阅读:1996回复:10
讨论 tooflat 的代码,100 分伺候
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; } //我是新手,请各路高手指点迷津 |
|
沙发#
发布于:2004-12-24 09:57
这个代码好像是参考SFILTER的吧
1“为何再次把irp发送到下层后等待?” 应该是利用事件同步完成例程吧,也就是在IoCompleteRequest(Irp, IO_NO_INCREMENT)前保证完成例程已经OK了。 2“完成irp后还可以用 Irp->IoStatus.Status ?” 我也觉得有点问题。 |
|
|
板凳#
发布于:2004-12-24 13:13
关注学习中...
|
|
|
地板#
发布于:2004-12-27 10:21
这个代码好像是参考SFILTER的吧 ================================================ 是有问题 什么时候QueryBuffer->NextEntryOffset > len ? ================================================ 容错性处理而已,应该不会有这种情况发生 UNREFERENCED_PARAMETER(Irp); //此调用起什么作用? ================================================ 原来的目的是不让编译器发生警告,这里不需要 [编辑 - 12/27/04 by tooflat] |
|
地下室#
发布于:2004-12-27 11:38
tooflat大侠:
您这段代码别处还有问题吗?请指教! 我用上后加载总是 重新启动 能QQ交流吗?50994497 |
|
5楼#
发布于:2004-12-27 17:47
tooflat大侠: 还没有发现其他问题,你可以跟踪一下是什么地方蓝屏, 我不用QQ |
|
6楼#
发布于: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 |
|
7楼#
发布于:2005-01-12 23:01
是不是QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer;
这句代码有问题,我原来的代码前面对RequestMode有判断,如果是KernelMode,就直接下发了,如果是KernelMode,那么buffer就不在Irp->UserBuffer,应该在Irp->MdlAddress |
|
8楼#
发布于:2005-01-13 08:56
是不是QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer; 看了一下DDK,缓冲区就应该在UserBuffer中,不清楚为什么你那边为出现这个问题 |
|
9楼#
发布于:2005-01-13 15:46
这是源代码,2000下的sFilter,帮忙看一下,先谢谢了!
|
|
|
10楼#
发布于:2005-01-14 21:15
while (1)
{ //增加这句代码试试 pos = 0; len = IrpSp->Parameters.QueryFile.Length; newlen = len; QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer; PreQueryBuffer = QueryBuffer; |
|