阅读:2008回复: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-27 11:38
tooflat大侠:
您这段代码别处还有问题吗?请指教! 我用上后加载总是 重新启动 能QQ交流吗?50994497 |
|
板凳#
发布于: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 |
|
地板#
发布于:2005-01-13 15:46
这是源代码,2000下的sFilter,帮忙看一下,先谢谢了!
|
|
|