znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
阅读:3200回复:4

sfilter之目录隐藏代码,关键函数

楼主#
更多 发布于:2010-02-18 21:30
如果你没有能力把这些函数用上,那说明:你还需要看基础教程,然后再回头看这个吧。
NTSTATUS ProcessHideDir(PDEVICE_OBJECT DeviceObject,PIRP Irp,PUNICODE_STRING Filename)
{
 KEVENT event;
 PFILE_BOTH_DIR_INFORMATION QueryBuffer = NULL;
 PFILE_BOTH_DIR_INFORMATION PreQueryBuffer = NULL; 
 ULONG      NextOffset = 0;
 ULONG      CurNoHideBufPos = 0;  //当前项之前不需要隐藏的缓冲区长度.
 ULONG      DirBufLen = 0; //用户缓冲区冲长度
 ULONG      AfterHideBufLen = 0;
 ULONG      ulCurItemLen=0;
 //new func use
 BOOLEAN      bIsHideFile =FALSE;
 BOOLEAN      bLastOne=FALSE;
 PSGFILTER_DEVICE_EXTENSION devExt=(PSGFILTER_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
 PNAME_CONTROL    pFullFileName;
 NTSTATUS     Status;
 UNICODE_STRING    ustrOnlyFileName;// no dirpath
 UNICODE_STRING    ustrCurrentDir;
 UNICODE_STRING    ustrParentDir;
 UNICODE_STRING    ustrFolderCtlFile;
 UNICODE_STRING    ustrUpperPath;
    
 PIO_STACK_LOCATION IrpSp=IoGetCurrentIrpStackLocation(Irp);
 RtlInitUnicodeString(&ustrCurrentDir,L".");
 RtlInitUnicodeString(&ustrParentDir,L"..");
 RtlInitUnicodeString(&ustrFolderCtlFile,DRVDIRHIDESETFILE);
 Status =NLAllocateNameControl(&pFullFileName,&gSfNameBufferLookasideList);
 if(!NT_SUCCESS(Status))
 {
  IoCompleteRequest(Irp, IO_NO_INCREMENT);
  return Status;
 }
 Status=NLReallocNameControl(pFullFileName,SG_MAX_PATH,NULL);
 if(!NT_SUCCESS(Status))
 {
  IoCompleteRequest(Irp, IO_NO_INCREMENT);
  return Status;
 }
 while (TRUE)
 {

  KeInitializeEvent(&event, NotificationEvent, FALSE);
  IoCopyCurrentIrpStackLocationToNext(Irp);
  IoSetCompletionRoutine(Irp, ProcessHideDirCompletion, &event, TRUE, TRUE, TRUE);
  IoCallDriver(devExt->NLExtHeader.AttachedToDeviceObject, Irp);
  KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
  KeClearEvent(&event);

  if(!NT_SUCCESS(Irp->IoStatus.Status))// == STATUS_NO_SUCH_FILE)
  {
   IoCompleteRequest(Irp, IO_NO_INCREMENT);
   return Irp->IoStatus.Status;
  }

  DirBufLen = IrpSp->Parameters.QueryDirectory.Length;  //从底层传入的目录信息缓冲区长度
  AfterHideBufLen = DirBufLen; 
  //Get the directory information link
  if (Irp->MdlAddress) {
   QueryBuffer = (PFILE_BOTH_DIR_INFORMATION)MmGetSystemAddressForMdl(Irp->MdlAddress);
  } else{
   //
   QueryBuffer = (PFILE_BOTH_DIR_INFORMATION)Irp->UserBuffer;
  }

  //backup the querybuffer
  PreQueryBuffer = QueryBuffer;
  if ((!QueryBuffer) || (QueryBuffer->NextEntryOffset > DirBufLen) || QueryBuffer->FileNameLength == 0 )// 缓冲区为空 或 用户传入的缓冲区长度不够,或文件名为空
  {
   IoSkipCurrentIrpStackLocation(Irp);
   return IoCallDriver( devExt->NLExtHeader.AttachedToDeviceObject, Irp );
  }

  bLastOne = FALSE;

  do  //循环读取目录项
  {
   bIsHideFile = FALSE;

   RtlCopyUnicodeString(&pFullFileName->Name,Filename);
   if( pFullFileName->Name.Buffer[pFullFileName->Name.Length/2-1] != L'\\')//处理盘符后的\符号
    RtlAppendUnicodeToString(&pFullFileName->Name,L"\\"); 
   ustrOnlyFileName.Buffer = QueryBuffer->FileName;
   ustrOnlyFileName.Length=(USHORT) QueryBuffer->FileNameLength;
   ustrOnlyFileName.MaximumLength = ustrOnlyFileName.Length;
   if( ustrOnlyFileName.Length>1)
   {
    if( ustrOnlyFileName.Buffer[0] == L'\\')
    {
     ustrOnlyFileName.Buffer+=1;
     ustrOnlyFileName.Length-=2;
    }
   }
            Status=RtlAppendUnicodeStringToString(&pFullFileName->Name,&ustrOnlyFileName);
   if( NT_SUCCESS(Status))
   {

    RtlUpcaseUnicodeString(&ustrUpperPath,&pFullFileName->Name,TRUE);
     if((QueryBuffer->FileAttributes & FILE_ATTRIBUTE_ARCHIVE) == FILE_ATTRIBUTE_ARCHIVE) // 是文件
     {
      if( RtlCompareUnicodeString(&ustrFolderCtlFile,&ustrOnlyFileName,TRUE) == 0)
      {
       bIsHideFile = TRUE;  // 如果是目录控制文件,直接隐藏
      }
      else
   
       if( SgFindFile(&ustrUpperPath,&bIsHideFile))
        bIsHideFile  = TRUE;
       else
        bIsHideFile = FALSE;
     
    
     
       
     }
     else if((QueryBuffer->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) == FILE_ATTRIBUTE_DIRECTORY)
     {
  
      if((RtlCompareUnicodeString(&ustrCurrentDir,&ustrOnlyFileName,TRUE) != 0)  &&  (RtlCompareUnicodeString(&ustrOnlyFileName,&ustrParentDir,TRUE) != 0))
      {

       
       //if( !SgFindFile(&ustrUpperPath,&bIsHideFile))
       // bIsHideFile =   FALSE;
       //{
        bIsHideFile=IsHideDirectory(&pFullFileName->Name,devExt);
       // SgAddFile(&pFullFileName->Name,bIsHideFile);
       //}
      }
     
     }
    RtlFreeUnicodeString(&ustrUpperPath);
   }

   NextOffset = QueryBuffer->NextEntryOffset; //下一个目录内容项(目录或文件)的偏移,也是当前项的长度

   if ( bIsHideFile == TRUE)// 隐藏的目录
   {

   
    if (0 == NextOffset)   //没有下一个了
    {
     PreQueryBuffer->NextEntryOffset = 0;
     AfterHideBufLen =CurNoHideBufPos; //设置新的长度等于前面没隐藏的长度
 
    }
    else
    {
     RtlMoveMemory((PUCHAR) QueryBuffer, (PUCHAR) QueryBuffer + NextOffset, (DirBufLen - CurNoHideBufPos - NextOffset)); 
     //old use block********
     AfterHideBufLen -= NextOffset;  //最终的长度要减去当前项的长度
 
 
    }
    //end of "first if" of DO
   } 
   else
   {
    //当前项不需要隐藏,那就算长度吧
    CurNoHideBufPos += NextOffset;  //计算前面没有隐藏的长度
    
    if(NextOffset > 0)//有下一项,那就要修正 前一项
    {
 
     PreQueryBuffer = QueryBuffer;
     QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR) QueryBuffer + NextOffset);
    }


   }

  } while (0 != NextOffset );//(0 != offset);

  Irp->IoStatus.Information = AfterHideBufLen;
  if( AfterHideBufLen >  0 ) // 非: 只有一项,且是隐藏的....
  {
 
   break;
  }
  else
   Irp->IoStatus.Information = DirBufLen;
 } // end of while(TRUE)

 IoCompleteRequest(Irp, IO_NO_INCREMENT);
 Status=Irp->IoStatus.Status;
 NLFreeNameControl(pFullFileName,&gSfNameBufferLookasideList);

 return Status;

 

}
//
// 目录内容隐藏处理的完成例程
//
//
NTSTATUS
ProcessHideDirCompletion(
       PDEVICE_OBJECT DeviceObject,
       PIRP Irp,
       PVOID Context
       )
{
 UNREFERENCED_PARAMETER(DeviceObject);
 UNREFERENCED_PARAMETER(Irp);
 KeSetEvent((PRKEVENT) Context, IO_NO_INCREMENT, FALSE);
 return STATUS_MORE_PROCESSING_REQUIRED;
}

最新喜欢:

rhpengrhpeng
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
evergreen7
驱动牛犊
驱动牛犊
  • 注册日期2009-03-22
  • 最后登录2010-04-02
  • 粉丝1
  • 关注0
  • 积分43分
  • 威望431点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2010-02-18 21:35
顶起~~ O(∩_∩)O谢谢~~~您知道我在找
BuShiXiaoHaiZi
驱动牛犊
驱动牛犊
  • 注册日期2008-12-20
  • 最后登录2012-04-22
  • 粉丝0
  • 关注0
  • 积分57分
  • 威望531点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2010-02-19 13:26
嘿嘿,谢谢先
nth2say
驱动牛犊
驱动牛犊
  • 注册日期2009-10-09
  • 最后登录2014-03-17
  • 粉丝1
  • 关注0
  • 积分28分
  • 威望281点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2010-02-25 11:15
谢谢马哥分享。看起来比原来那个简单点~~
fjcy918628
驱动牛犊
驱动牛犊
  • 注册日期2009-05-11
  • 最后登录2011-11-29
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望91点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2010-03-16 16:47
znsoft  老大,为什么这几句
   ustrOnlyFileName.Buffer = QueryBuffer->FileName;
   ustrOnlyFileName.Length=(USHORT) QueryBuffer->FileNameLength;
   ustrOnlyFileName.MaximumLength = ustrOnlyFileName.Length;

可以直接RtlInitUnicodeString(&ustrOnlyFileName,QueryBuffer->FileName);
ustrOnlyFileName.Length = (USHORT) QueryBuffer->FileNameLength;

这两种有区别么
游客

返回顶部