lhzh114
驱动牛犊
驱动牛犊
  • 注册日期2004-02-20
  • 最后登录2008-12-27
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望37点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
阅读:2008回复:10

讨论 tooflat 的代码,100 分伺候

楼主#
更多 发布于:2004-12-24 09:21
NTSTATUS
ProcessHiddenFile(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp,
    IN PIO_STACK_LOCATION IrpSp
)
{
NTSTATUS status;
    PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
    KEVENT event;
    PFILE_BOTH_DIR_INFORMATION QueryBuffer = NULL;
    PFILE_BOTH_DIR_INFORMATION PreQueryBuffer = NULL;
    ULONG offset = 0;
    ULONG pos = 0;
    ULONG len = 0;
    ULONG newlen = 1;
    WCHAR file[] = L"TEST.TXT";

KeInitializeEvent(&event, NotificationEvent, FALSE);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, HiddenFileCompletion, &event, TRUE, TRUE, TRUE);
status = IoCallDriver(pdx->NextDeviceObject, Irp);
 
if (STATUS_PENDING == status)
{
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
}


   while (1)
   {
    len = IrpSp->Parameters.QueryFile.Length;    //ifs kit 2000说明应该用QueryDirectory吧,文档里没有QueryFile?
    newlen = len;
    QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;
    PreQueryBuffer = QueryBuffer;

    if ((!QueryBuffer) || (QueryBuffer->NextEntryOffset > len))  //什么时候QueryBuffer->NextEntryOffset > len ?
    {
        IoSkipCurrentIrpStackLocation(Irp);
        return IoCallDriver(pdx->NextDeviceObject, Irp);
    }

    do
    {
        offset = QueryBuffer->NextEntryOffset;
// 过滤规则
if ((QueryBuffer->FileNameLength > 0) && (_wcsicmp(QueryBuffer->FileName, file) == 0))
  {
          if (0 == offset) // the last one
 {
             PreQueryBuffer->NextEntryOffset = 0;
             newlen = pos;
 }
          else
 {
             if (PreQueryBuffer != QueryBuffer)
             {
                PreQueryBuffer->NextEntryOffset += offset;
             }
             else // the first one
             {
                RtlMoveMemory((PUCHAR) QueryBuffer, (PUCHAR) QueryBuffer + offset, len - pos - offset);
             }
             newlen -= offset;
 }
          break;
  }
       pos += offset;
       PreQueryBuffer = QueryBuffer;
       QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ((PUCHAR) QueryBuffer + offset);
    } while (0 != offset);

  

    if (0 == newlen)
    {
        KeResetEvent(&event);
IoCopyCurrentIrpStackLocationToNext(Irp);
IoSetCompletionRoutine(Irp, HiddenFileCompletion, &event, TRUE, TRUE, TRUE);
status = IoCallDriver(pdx->NextDeviceObject, Irp);
 
if (STATUS_PENDING == status)                               //为何再次把irp发送到下层后等待?
{
KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, NULL);
}

       if (0 == Irp->IoStatus.Information)
       {
        break;
       }
    }
    else
    {
       Irp->IoStatus.Information = newlen;
       break;
    }
   } //while(1)

   IoCompleteRequest(Irp, IO_NO_INCREMENT);
   return Irp->IoStatus.Status;                              //完成irp后还可以用 Irp->IoStatus.Status ?
}

NTSTATUS
HiddenFileCompletion(
    PDEVICE_OBJECT DeviceObject,
    PIRP Irp,
    PVOID Context
)
{
  
   UNREFERENCED_PARAMETER(DeviceObject);
   UNREFERENCED_PARAMETER(Irp);                             //此调用起什么作用?

   if (Irp->PendingReturned)
   {
      KeSetEvent((PRKEVENT) Context, IO_NO_INCREMENT, FALSE);
   }
   return STATUS_MORE_PROCESSING_REQUIRED;  
  
}

//我是新手,请各路高手指点迷津
lhzh114
驱动牛犊
驱动牛犊
  • 注册日期2004-02-20
  • 最后登录2008-12-27
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望37点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-12-27 11:38
tooflat大侠:

您这段代码别处还有问题吗?请指教!
我用上后加载总是 重新启动

能QQ交流吗?50994497
lhzh114
驱动牛犊
驱动牛犊
  • 注册日期2004-02-20
  • 最后登录2008-12-27
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望37点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2005-01-12 17:31
这样调用的:
NTSTATUS status;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) DeviceObject->DeviceExtension;
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation( Irp );

if ((irpsp->MinorFunction) == IRP_MN_QUERY_DIRECTORY )
{
       return ProcessHiddenFile(DeviceObject,Irp,irpsp);
}
else
{
  IoSkipCurrentIrpStackLocation(Irp);
  return IoCallDriver(pdx->NextDeviceObject, Irp);
}


调用QueryBuffer->NextEntryOffset,跟踪发现处理一些个IRP时访问QueryBuffer->NextEntryOffset提示Access Violation,然后蓝屏→重启
不知什么原因?
win2000 + ifs kit 2k
lhzh114
驱动牛犊
驱动牛犊
  • 注册日期2004-02-20
  • 最后登录2008-12-27
  • 粉丝0
  • 关注0
  • 积分9分
  • 威望37点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
地板#
发布于:2005-01-13 15:46
这是源代码,2000下的sFilter,帮忙看一下,先谢谢了!
附件名称/大小 下载次数 最后更新
2005-01-13_sfilter.c (93KB)  43
游客

返回顶部