阅读:1823回复:4
请版主和vcmfc两位大虾帮我看看,为什么会这样?
我在ifs kit的sfilter的例子中加入一段处理irp_mn_directory_control的代码,想隐藏文件夹,虽然成功了,但是只要打开 与该文件夹在同一个目录 的文件或者exe,系统就会出现蓝屏,提示:在非页区出现一个页面错误。
例如:我隐藏c:\\program files\\TestH后,当用浏览器打开c:\\program files之后,TestH被隐藏,但如果我打开program files目录下面的a.exe时,就会出现上面的情况 我的代码是这样的: NTSTATUS SfDtCtrl(//拦截directory control的例程 IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) { PAGED_CODE(); VALIDATE_IRQL(Irp); IN PDEVICE_OBJECT aa = DeviceObject; PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp); NTSTATUS status; ANSI_STRING directoryFilter; PCHAR queryFilter; PQUERY_DIRECTORY queryDirectory; if (currentIrpStack->MinorFunction == IRP_MN_QUERY_DIRECTORY) { //下面这段代码copy自sfilter的sfCreate例程 ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); // // If debugging is enabled, do the processing required to see the packet // upon its completion. Otherwise, let the request go with no further // processing. // if (!(SfDebug & SFDEBUG_DO_CREATE_COMPLETION| SFDEBUG_GET_CREATE_NAMES| SFDEBUG_DISPLAY_CREATE_NAMES)) { // // Don\'t put us on the stack then call the next driver // IoSkipCurrentIrpStackLocation( Irp ); return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); } else { KEVENT waitEvent; // // Initialize an event to wait for the completion routine to occur // KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); // // Copy the stack and set our Completion routine // IoCopyCurrentIrpStackLocationToNext( Irp ); IoSetCompletionRoutine( Irp, SfCreateCompletion,//在该例程中加入对隐藏文件夹的处理 &waitEvent, TRUE, TRUE, TRUE ); // // Call the next driver in the stack. // status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); // // Wait for the completion routine to be called // if (STATUS_PENDING == status) { NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL); ASSERT(STATUS_SUCCESS == localStatus); } // // Verify the IoCompleteRequest was called // ASSERT(KeReadStateEvent(&waitEvent) || !NT_SUCCESS(Irp->IoStatus.Status)); // // Retrieve and display the filename if requested // if (FlagOn(SfDebug,(SFDEBUG_GET_CREATE_NAMES|SFDEBUG_DISPLAY_CREATE_NAMES))) { SfDisplayCreateFileName( Irp ); } // // Save the status and continue processing the IRP // status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } } else { IoCopyCurrentIrpStackLocationToNext( Irp ); return IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); } } NTSTATUS SfCreateCompletion ( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) /*++ Routine Description: This function is the create/open completion routine for this filter file system driver. If debugging is enabled, then this function prints the name of the file that was successfully opened/created by the file system as a result of the specified I/O request. Arguments: DeviceObject - Pointer to the device on which the file was created. Irp - Pointer to the I/O Request Packet the represents the operation. Context - This driver\'s context parameter - unused; Return Value: The function value is STATUS_SUCCESS. --*/ { PKEVENT event = Context; PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp); ApcHookHideFile(Irp, currentIrpStack);//隐藏文件夹 UNREFERENCED_PARAMETER( DeviceObject ); UNREFERENCED_PARAMETER( Irp ); ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); KeSetEvent(event, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; } void ApcHookHideFile(IN PIRP Irp, PIO_STACK_LOCATION currentIrpStack ) { PFILE_BOTH_DIR_INFORMATION QueryBuffer = NULL; PFILE_BOTH_DIR_INFORMATION preQueryBuffer = NULL; ULONG offset = 0; ULONG currentPosition = 0; ULONG bufferLength = currentIrpStack->Parameters.QueryFile.Length; ULONG NewLength = 0; WCHAR fileNameToRemove[] = L\"TestH\"; PUCHAR startEntryToRemove = NULL; PUCHAR startNextEntry = NULL; NewLength = bufferLength; QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) Irp->UserBuffer; if (QueryBuffer->NextEntryOffset > bufferLength) return; do { offset = QueryBuffer->NextEntryOffset; // DebugPrint( ( \"HookRoutine : QUERY_DIR : TestH - ws 0xd\\n\", // QueryBuffer->FileName, QueryBuffer->NextEntryOffset ) ); if (wcsncmp(QueryBuffer->FileName, fileNameToRemove, 5) == 0) { //如果要隐藏的文件夹是链表中最后一项,则将其前驱节点的nextoffset改为零,置newLength为currentPosition if (0 == offset) { NewLength = currentPosition; preQueryBuffer->NextEntryOffset = 0; break; } startEntryToRemove = (PUCHAR) QueryBuffer; startNextEntry = (PUCHAR) QueryBuffer + offset; RtlMoveMemory( startEntryToRemove, startNextEntry, bufferLength - currentPosition - offset ); NewLength -= offset; break; } currentPosition += offset; preQueryBuffer = QueryBuffer; QueryBuffer = (PFILE_BOTH_DIR_INFORMATION) ( (PUCHAR) QueryBuffer + offset ); } while (offset != 0); Irp->IoStatus.Information = NewLength; } 请大家帮我看看啊。我将apchidefile()放到dtctrl例程中的setcompletionroutine()之后再处理也不行啊,问题是一样的 |
|
最新喜欢:![]() |
沙发#
发布于:2003-04-25 17:06
还有一点忘了说了,我如果不用浏览器打开c:\\program files运行a.exe,而是用桌面快捷方式运行a.exe时,就不会出现蓝屏啊
|
|
板凳#
发布于:2003-04-25 20:43
你有ifs kit 能上传给我吗?
或者告诉我哪里可以免费下载 thanks!very much |
|
地板#
发布于:2003-09-12 13:23
你要那个版本
|
|
|
地下室#
发布于:2003-09-12 17:33
你的
KEVENT waitEvent; KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); IoCopyCurrentIrpStackLocationToNext( Irp ); IoSetCompletionRoutine( Irp, SfCreateCompletion,//在该例程中加入对隐藏文件夹的处理 &waitEvent, TRUE, TRUE, TRUE ); // // Call the next driver in the stack. // status = IoCallDriver( ((PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension)->AttachedToDeviceObject, Irp ); // // Wait for the completion routine to be called // if (STATUS_PENDING == status) { NTSTATUS localStatus = KeWaitForSingleObject(&waitEvent, Executive, KernelMode, FALSE, NULL); ASSERT(STATUS_SUCCESS == localStatus); } // // Verify the IoCompleteRequest was called // ASSERT(KeReadStateEvent(&waitEvent) || !NT_SUCCESS(Irp->IoStatus.Status)); // // Retrieve and display the filename if requested // if (FlagOn(SfDebug,(SFDEBUG_GET_CREATE_NAMES|SFDEBUG_DISPLAY_CREATE_NAMES))) { SfDisplayCreateFileName( Irp ); } // // Save the status and continue processing the IRP // status = Irp->IoStatus.Status; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return status; } 对IRP进行了重复的处理,你把后面的IoCompleteRequest( Irp, IO_NO_INCREMENT );去掉 |
|