阅读:1712回复:2
请教"为何无法更改文件名"
我用ZwCreateFile以DELETE权限获取一文件的FILE_OBJECT后,调用以下代码,结果总是返回0xC000000D,折腾了很久没解决,请大家帮忙看看.
传入的参数中,目标文件名以绝对路径表示,且前面已经加了 \??\ /************************************************************* 功能描述: 重命名文件 返回值: 无 其他说明: *************************************************************/ NTSTATUS RenameFile( IN PWSTR DstFileName, // 目的文件名 IN PFILE_OBJECT FileObject, PDEVICE_OBJECT DeviceObject ) { PIRP Irp = NULL; PIO_STACK_LOCATION IrpSp = NULL; KEVENT Event; IO_STATUS_BLOCK IoStatus; NTSTATUS ntStatus = STATUS_SUCCESS; PFILE_RENAME_INFORMATION FileNameInfo = NULL; PAGED_CODE(); ASSERT( NULL != DeviceObject ); ASSERT( NULL != FileObject ); KeInitializeEvent( &Event, NotificationEvent, FALSE ); FileNameInfo = ExAllocateFromNPagedLookasideList( &FullPathLookaside ); if( !FileNameInfo ) return STATUS_INSUFFICIENT_RESOURCES; FileNameInfo->ReplaceIfExists = FALSE; FileNameInfo->RootDirectory = NULL; wcscpy( FileNameInfo->FileName, DstFileName ); FileNameInfo->FileNameLength = wcslen( DstFileName ) * sizeof(WCHAR); IoStatus.Status = STATUS_SUCCESS; IoStatus.Information = 0; Irp = IoAllocateIrp( DeviceObject->StackSize, FALSE ); if( !Irp ) return STATUS_INSUFFICIENT_RESOURCES; // 设置IRP请求包参数 Irp->Tail.Overlay.Thread = PsGetCurrentThread();// 设置当前线程为IRP请求的线程环境 Irp->Tail.Overlay.OriginalFileObject = FileObject; Irp->RequestorMode = KernelMode; // 设置IRP请求为内核模式,这样I/O管理器不需要探测内存 Irp->UserIosb = &IoStatus; Irp->UserEvent = &Event; Irp->Flags |= IRP_BUFFERED_IO; Irp->AssociatedIrp.SystemBuffer = FileNameInfo; // 设置堆栈 IrpSp = IoGetNextIrpStackLocation(Irp); IrpSp->MajorFunction = IRP_MJ_SET_INFORMATION; IrpSp->FileObject = FileObject; IrpSp->DeviceObject = DeviceObject; IrpSp->Parameters.SetFile.FileInformationClass = FileRenameInformation; IrpSp->Parameters.SetFile.FileObject = FileObject; IrpSp->Parameters.SetFile.Length = FileNameInfo->FileNameLength + 16; IrpSp->Parameters.SetFile.ReplaceIfExists = FileNameInfo->ReplaceIfExists; IoSetCompletionRoutine( Irp, QueryCompletion, &Event, TRUE, TRUE, TRUE ); ntStatus = IoCallDriver( DeviceObject, Irp ); // 等待系统完成IRP if( STATUS_PENDING == ntStatus ) KeWaitForSingleObject(&Event, Executive, KernelMode, TRUE, 0); ExFreeToNPagedLookasideList( &FullPathLookaside, FileNameInfo ); return IoStatus.Status; } // 完成例程 // 由于是自己分配的IRP,因此必须在此释放 NTSTATUS QueryCompletion ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PKEVENT SynchronizingEvent ) { *Irp->UserIosb = Irp->IoStatus; if( SynchronizingEvent ) KeSetEvent( SynchronizingEvent, IO_NO_INCREMENT, FALSE ); IoFreeIrp( Irp ); return STATUS_MORE_PROCESSING_REQUIRED; } |
|
沙发#
发布于:2007-12-22 15:33
NTSTATUS
KfcIoCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { // PAGED_CODE(); KdPrint(("KfsIoCompletion\n")); UNREFERENCED_PARAMETER(Context); UNREFERENCED_PARAMETER(DeviceObject); *Irp->UserIosb=Irp->IoStatus; KeSetEvent(Irp->UserEvent,0,FALSE); IoFreeIrp(Irp); return STATUS_MORE_PROCESSING_REQUIRED; } BOOLEAN KfsSetRenameInformation( IN PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, IN OUT PFILE_RENAME_INFORMATION SomeInformation, IN ULONG SomeInformationSize,//sizeof(FILE_DISPOSITION_INFORMATION) IN UCHAR MajorFunction, IN FILE_INFORMATION_CLASS FileInformationClass, PIO_STATUS_BLOCK IoStatusBlock ) { PIRP irp; PDEVICE_OBJECT fsdDevice;//IoGetRelatedDeviceObject(FileObject); KEVENT event; PIO_STACK_LOCATION ioStackLocation; // PAGED_CODE(); // KeInitializeEvent(&event,SynchronizationEvent,FALSE); fsdDevice=IoGetRelatedDeviceObject(FileObject); UNREFERENCED_PARAMETER(IoStatusBlock); UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(MajorFunction); UNREFERENCED_PARAMETER(FileInformationClass); // IoStatusBlock=NULL; KdPrint(("KfsSetFileInformation\n")); irp=IoAllocateIrp(fsdDevice->StackSize,FALSE); if(!irp) { return FALSE; } irp->AssociatedIrp.SystemBuffer=SomeInformation; irp->UserEvent=&event; irp->UserIosb=IoStatusBlock; irp->Tail.Overlay.Thread=PsGetCurrentThread(); irp->Tail.Overlay.OriginalFileObject=FileObject; irp->RequestorMode=KernelMode; irp->Flags=0; //SetFlag(irp->Flags,FILE_NO_INTERMEDIATE_BUFFERING); //SetFlag(irp->Flags,IRP_NOCACHE|IRP_PAGING_IO|IRP_SYNCHRONOUS_PAGING_IO); //SetFlag(irp->Flags,IRP_NOCACHE); //SetFlag(FileObject->Flags,FO_FILE_MODIFIED); //SetFlag(FileObject->Flags,FO_FILE_SIZE_CHANGED); KeInitializeEvent(&event,SynchronizationEvent,FALSE); ioStackLocation=IoGetNextIrpStackLocation(irp); ioStackLocation->MajorFunction=MajorFunction; ioStackLocation->DeviceObject=fsdDevice;//DeviceObject; ioStackLocation->FileObject=FileObject; ioStackLocation->Parameters.SetFile.Length= SomeInformationSize; ioStackLocation->Parameters.SetFile.FileInformationClass=FileInformationClass; ioStackLocation->Parameters.SetFile.FileObject = 0; // not used for allocation ioStackLocation->Parameters.SetFile.AdvanceOnly=FALSE; if(FileInformationClass == FileDispositionInformation ) { ioStackLocation->Parameters.SetFile.ReplaceIfExists=TRUE; } IoSetCompletionRoutine(irp,KfcIoCompletion,0,TRUE,TRUE,TRUE); (void)IoCallDriver(fsdDevice,irp); KeWaitForSingleObject(&event,Executive,KernelMode,TRUE,0); return NT_SUCCESS(IoStatusBlock->Status); } |
|
板凳#
发布于:2007-12-27 19:05
谢谢你的答复,经过调试我发现我的代码中把
IrpSp->DeviceObject = DeviceObject;去掉就可以了。 |
|