tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
阅读:14832回复:49

终于搞定隐藏文件、目录了,好高兴啊!!!!!哈哈

楼主#
更多 发布于:2004-01-09 16:48
可以过滤掉目录下的所有entry,不需要重新构造irp
NTSTATUS
DispatchDirectoryControl(
       IN PDEVICE_OBJECT DeviceObject,
       IN PIRP Irp
       )
{
       PDEVICE_EXTENSION devExt = DeviceObject->DeviceExtension;
       PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
       KEVENT waitEvent;
       NTSTATUS status;
       PWSTR fileNameBuffer;
       ULONG bufferLength;
       ULONG newLength;
       ULONG offset;
       ULONG currentPosition;
       PFILE_BOTH_DIR_INFORMATION dirInfo = NULL;
       PFILE_BOTH_DIR_INFORMATION preDirInfo = NULL;

       PAGED_CODE();

       if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) {

              Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
              Irp->IoStatus.Information = 0;
              IoCompleteRequest(Irp, IO_NO_INCREMENT);
              return STATUS_INVALID_DEVICE_REQUEST;
       }

       if (Irp->RequestorMode == KernelMode) {

              IoSkipCurrentIrpStackLocation(Irp);
              return IoCallDriver(((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp);
       }

       if (FileBothDirectoryInformation != irpSp->Parameters.QueryDirectory.FileInformationClass) {

              IoSkipCurrentIrpStackLocation(Irp);
              return IoCallDriver(((PDEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp);
       }

       KeInitializeEvent(&waitEvent, NotificationEvent, FALSE);
      
       IoCopyCurrentIrpStackLocationToNext(Irp);

       IoSetCompletionRoutine(Irp,
              DirectoryControlCompletion,
              &waitEvent,        //context parameter
              TRUE,
              TRUE,
              TRUE
              );
      
       status = IoCallDriver(devExt->AttachedToDeviceObject, Irp);
      
       //
       //  Wait for the operation to complete
       //
       if (STATUS_PENDING == status) {
      
              status = KeWaitForSingleObject(&waitEvent,
                     Executive,
                     KernelMode,
                     FALSE,
                     NULL
                     );
              ASSERT(STATUS_SUCCESS == status);
       }

       if (!NT_SUCCESS(status) ||(0 == irpSp->Parameters.QueryFile.Length)) {

              IoCompleteRequest(Irp, IO_NO_INCREMENT);
              return status;
       }

       fileNameBuffer =(PWSTR) ExAllocatePoolWithTag(NonPagedPool, MAX_PATH * sizeof(WCHAR), POOL_TAG);
       if (!fileNameBuffer)
       {
              IoCompleteRequest(Irp, IO_NO_INCREMENT);
              return status;
       }

       RtlZeroMemory(fileNameBuffer, MAX_PATH * sizeof(WCHAR));

       if (!NT_SUCCESS(GetFileName(DeviceObject, irpSp->FileObject, fileNameBuffer))) {

              ExFreePoolWithTag(fileNameBuffer, POOL_TAG);
              IoCompleteRequest(Irp, IO_NO_INCREMENT);
              return status;
       }
      
       if (0 != _wcsicmp(fileNameBuffer, L"\\")) {

              ExFreePoolWithTag(fileNameBuffer, POOL_TAG);
              IoCompleteRequest(Irp, IO_NO_INCREMENT);
              return status;
       }
      
       while (TRUE) {

              bufferLength = irpSp->Parameters.QueryDirectory.Length;
              newLength = bufferLength;
              currentPosition = 0;
              dirInfo =(PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;
              preDirInfo = dirInfo;

              if ((!dirInfo) ||(dirInfo->NextEntryOffset > bufferLength)) {

                     IoCompleteRequest(Irp, IO_NO_INCREMENT);
                     return status;
              }
              
              do {

                     offset = dirInfo->NextEntryOffset;
                     if ((dirInfo->FileNameLength > 0) &&
                            (_wcsnicmp(HIDDEN_DIRECTORY, dirInfo->FileName, dirInfo->FileNameLength / sizeof(WCHAR)) == 0)) {

                            if (0 == offset) { // the last one

                                   preDirInfo->NextEntryOffset = 0;
                                   newLength = currentPosition;

                            } else {

                                   if (preDirInfo != dirInfo) {

                                          preDirInfo->NextEntryOffset += dirInfo->NextEntryOffset;
                                          dirInfo = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR) dirInfo + offset);
                                          
                                   } else {

                                          RtlMoveMemory((PUCHAR) dirInfo,(PUCHAR) dirInfo + offset, bufferLength - currentPosition - offset);
                                          newLength -= offset;

                                   }
                            }
                            
//                            break;
                     }
                     else
                     {
                            currentPosition += offset;
                            preDirInfo = dirInfo;
                            dirInfo =(PFILE_BOTH_DIR_INFORMATION)((PUCHAR) dirInfo + offset);
                     }

              } while(0 != offset);

              if (0 == newLength) {
                    
                     KeResetEvent(&waitEvent);
                    
                     IoCopyCurrentIrpStackLocationToNext(Irp);
                    
                     IoSetCompletionRoutine(Irp,
                            DirectoryControlCompletion,
                            &waitEvent,        //context parameter
                            TRUE,
                            TRUE,
                            TRUE
                            );
                    
                     status = IoCallDriver(devExt->AttachedToDeviceObject, Irp);
                    
                     //
                     //       Wait for the operation to complete
                     //
                     if (STATUS_PENDING == status) {
                    
                            status = KeWaitForSingleObject(&waitEvent,
                                   Executive,
                                   KernelMode,
                                   FALSE,
                                   NULL
                                   );
                            ASSERT(STATUS_SUCCESS == status);
                     }

                     if (!NT_SUCCESS(status) ||(0 == Irp->IoStatus.Information)) {
                            
                            break;
                     }

              } else {

                     Irp->IoStatus.Information = newLength;
                     break;
              }
       }

       ExFreePoolWithTag(fileNameBuffer, POOL_TAG);
      
       Irp->IoStatus.Information = newLength;
       IoCompleteRequest(Irp, IO_NO_INCREMENT);
       return status;
}

NTSTATUS
DirectoryControlCompletion(
       IN PDEVICE_OBJECT DeviceObject,
       IN PIRP Irp,
       IN PVOID Context
       )
{
       UNREFERENCED_PARAMETER(DeviceObject);
       UNREFERENCED_PARAMETER(Irp);

       KeSetEvent((PKEVENT) Context, IO_NO_INCREMENT, FALSE);

       return STATUS_MORE_PROCESSING_REQUIRED;
}

最新喜欢:

SamSunSamSun sijinsijin linshierlinshi... zhuwgzhuwg
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-01-13 14:45
过滤掉目录中所有的entry也可以
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-07-11 16:07
我一直都用这种方法,没有发现任何问题
tooflat
论坛版主
论坛版主
  • 注册日期2002-07-08
  • 最后登录2014-03-11
  • 粉丝2
  • 关注0
  • 积分1007分
  • 威望551点
  • 贡献值3点
  • 好评度476点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-07-18 09:48
下面是引用cardmagic于2005-07-16 00:38发表的:

过滤一个文件就break问题不大,但是如果利用这个隐藏一次查询中得若干文件得话,就有麻烦.

pos += offset;
PreQueryBuffer = QueryBuffer;
.......


兄台所言极是
游客

返回顶部