hill9932
驱动牛犊
驱动牛犊
  • 注册日期2004-03-04
  • 最后登录2008-03-17
  • 粉丝0
  • 关注0
  • 积分335分
  • 威望35点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
阅读:1713回复:2

请教"为何无法更改文件名"

楼主#
更多 发布于:2007-12-19 18:02
我用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;
}
hill9932
驱动牛犊
驱动牛犊
  • 注册日期2004-03-04
  • 最后登录2008-03-17
  • 粉丝0
  • 关注0
  • 积分335分
  • 威望35点
  • 贡献值0点
  • 好评度32点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-12-27 19:05
谢谢你的答复,经过调试我发现我的代码中把
IrpSp->DeviceObject = DeviceObject;去掉就可以了。
yaolixing
驱动小牛
驱动小牛
  • 注册日期2006-06-27
  • 最后登录2010-07-15
  • 粉丝1
  • 关注0
  • 积分991分
  • 威望135点
  • 贡献值0点
  • 好评度124点
  • 原创分0分
  • 专家分0分
板凳#
发布于: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);              
}
游客

返回顶部