⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 关于文件夹地隐藏.txt

📁 文件系统驱动开发的文档资料(IFS DDK)
💻 TXT
字号:
总结:关于文件夹地隐藏。

1、返回的列表中只有一项并且这一项就是需要隐藏的项同时ReturnSingleEntry又为TRUE时怎么办? 

  1)、Coolice采用重新调用ZwQueryDirectoryFile()的方法,不过这种方法需要考虑重入问题。 
  2)、VCMFC通过对根目录进行特别处理来实现隐藏,不过他没有给出代码,具体方法我也不清楚。 

  还有另外一种的方法,那就是重新构造IRP查询。Coolice也提到了这种方法,不过他也没有代码。OK,下面就是这种方法的代码: 

  // 
  // 执行隐藏操作 
  // 
  bool bNeedReQuery; 
  bool bReturnSingleEntry; 

  bReturnSingleEntry = ((IrpStack->Flags & SL_RETURN_SINGLE_ENTRY) 
              == SL_RETURN_SINGLE_ENTRY 
              ); 

  while(true) 
  {   
    // 
    // 在SfHideFile()中判断是否符合上述条件,如果符合则设置bNeedReQuery为TRUE然后直接返回。 
    // 
    Status = SfHideFile( 
          &FullDirName, 
          Irp->UserBuffer, 
          IrpStack->Parameters.QueryFile.Length, 
          bReturnSingleEntry, 
          &bNeedReQuery 
          ); 
    if(!bNeedReQuery) 
    { 
      break; 
    } 

    // 
    // 如果欲隐藏的文件恰好是第一项,这时候只能通过重新查询来实现隐藏。 
    // 
    Status = SfReissueIrp(Irp,DeviceObject->StackSize + 2,DevExt); 
    if(Status != STATUS_SUCCESS) 
    { 
      break; 
    } 
  } 


  //--------------------------------------------------------------------------- 
  // 
  // 构造新的IRP来继续查询 
  // 
  NTSTATUS 
  SfReissueIrp( 
    IN PIRP Irp, 
    IN int StackSize, 
    IN PSFILTER_DEVICE_EXTENSION DevExt 
    ) 
  { 
    NTSTATUS Status; 
    PIO_STACK_LOCATION IrpStack; 
    PIRP NewIrp; 
    PIO_STACK_LOCATION NextIrpStack; 

    NewIrp = IoAllocateIrp(StackSize,false); 
    if(NewIrp != NULL) 
    { 
      // 
      // 设置同步事件 
      // 
      KEVENT WaitEvent; 

      KeInitializeEvent(&WaitEvent,SynchronizationEvent,false); 
   
      // 
      // 设置IRP 
      // 
      NewIrp->UserEvent = NULL; 
   
      NewIrp->AssociatedIrp.SystemBuffer = Irp->AssociatedIrp.SystemBuffer; 
      NewIrp->UserBuffer = Irp->UserBuffer; 

      NewIrp->Tail.Overlay.Thread = PsGetCurrentThread(); 
      NewIrp->RequestorMode = Irp->RequestorMode; 
      NewIrp->Flags = Irp->Flags & (~IRP_ASSOCIATED_IRP); 
   
      // 
      // 设置IO堆栈 
      // 
      IrpStack = IoGetCurrentIrpStackLocation(Irp); 
      NextIrpStack = IoGetNextIrpStackLocation(NewIrp); 
   
      *NextIrpStack = *IrpStack; 
   
      NextIrpStack->CompletionRoutine = SfDirectoryControlCompletion; 
      NextIrpStack->Context = &WaitEvent; 
   
      // 
      // 发送新的IRP到下层FSD 
      // 
      Status = IoCallDriver(DevExt->AttachedToDeviceObject,NewIrp); 
      if(Status == STATUS_PENDING) 
      { 
        KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL); 
   
        Status = NewIrp->IoStatus.Status; 
      } 

      // 
      // 释放IRP 
      // 
      IoFreeIrp(NewIrp); 
    } 
    else 
    { 
      Status = STATUS_INSUFFICIENT_RESOURCES; 
    } 

    return Status; 
  } 


2、那就是要隐藏的文件在返回缓冲中不是第一项时怎么隐藏? 

  我使用“隐藏”来搜索了本分论坛的贴子,在有关隐藏文件夹地讨论中,发现几乎99.9999%的FSFD Writer都使用与VCMFC相同的方法,那就是不停的Move Memory …:),实际上除了第一项需要Move以外,后面所有项地隐藏都是不需要Move的,直接更改一个ULONG值就可以了,一律Move只会对系统性能产生影响。虽然现在CPU已经是2、3、4G了(Sorry,具体是多少不清楚),不过追求最好的性能应该是一个程序员最基本的追求吧? 

  // 
  // 1、第一项匹配 
  // 
  if(...) 
  { 
  } 

  // 
  // 2:最后一项匹配 
  // 
  else if(pDirInfo->NextEntryOffset == 0) 
  { 
    pPrevDirInfo->NextEntryOffset = 0; 
  } 

  // 
  // 3:中间项匹配 
  // 
  else 
  { 
    // 
    // 隐藏中间项目时不需要调整pPrevDirInfo的值 
    // 
    bMustAdjustPrevDirInfo = false; 

    pPrevDirInfo->NextEntryOffset += pDirInfo->NextEntryOffset; 
  } 

  // 
  // ........ // Do something here 
  // 

  // 
  // 是否需要调整pPrevDirInfo的值?(隐藏中间项目时不需要) 
  // 
  if(bMustAdjustPrevDirInfo) 
  { 
    pPrevDirInfo = pDirInfo; 
  } 

  pDirInfo = (PFILE_BOTH_DIR_INFORMATION)((PUCHAR)pDirInfo + pDirInfo->NextEntryOffset); 


3、最最重要的一点,那就是我上面的贴出的代码是不能直接Copy & Paste & Compile的,其中道理我想你自己应该明白。 


2004-1-30开始学习文件系统驱动开发,直接着手的第一个问题就是把以前通过Hook ZwQueryDirectoryFile()来实现文件夹隐藏的驱动重新使用FSFD来实现。说来惭愧,使用了8天时间才彻底搞定。 

题外话:SFilter在2K上面也是可以动态加载的,使用一些Trick就可以了。如果老是只听MS的那些工程师的话,那玩驱动编程岂不是少了许多乐趣? 

最后,如果你认为我的总结对你还有一个点帮助,就请up一个这个贴子 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -