阅读:2658回复:3
同一个设备,在不同派遣函数中有的可以挂接有的却不可以,奇怪!
我机器上有一个叫Winachsf0的设备,我在DriverEntry中可以通过IoAttachDevice把我的设备挂接到设备栈上,而在我自定义的IoControl中却无法将我的设备挂接到设备栈上,返回的状态是STATUS_OBJECT_NAME_NOT_FOUND,不知道有没有碰到过?
|
|
沙发#
发布于:2010-01-18 09:14
贴代码看看?
|
|
板凳#
发布于:2010-01-18 10:06
代码如下
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath){ KdPrint(("Enter DriverEntry!\n")); for(int i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) DriverObject->MajorFunction = DispatchPassthrough; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoCtlPassthrough; DriverObject->MajorFunction[IRP_MJ_READ] = Read; DriverObject->DriverUnload = DriverUnload; KdPrint(("Leave DriverEntry!\n")); return CreateDevice(DriverObject); } NTSTATUS CreateDevice(IN PDRIVER_OBJECT DriverObject) { NTSTATUS status = STATUS_SUCCESS; KdPrint(("Enter CreateDevice!\n")); UNICODE_STRING DevName; RtlInitUnicodeString(&DevName, L"\\Device\\MyDevice"); PDEVICE_OBJECT fdo = NULL; status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), &DevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo); if(!NT_SUCCESS(status)) return status; PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)fdo->DeviceExtension; RtlZeroMemory(DevExt, sizeof(DEVICE_EXTENSION)); DevExt->FiltDeviceObject = fdo; UNICODE_STRING SymbolicLinkName; RtlInitUnicodeString(&SymbolicLinkName, L"\\??\\COMMFILT"); status = IoCreateSymbolicLink(&SymbolicLinkName, &DevName); if(!NT_SUCCESS(status)) { IoDeleteDevice(fdo); return status; } DevExt->SymbolicLink = SymbolicLinkName; /*UNICODE_STRING TargetDeviceName; RtlInitUnicodeString(&TargetDeviceName, L"\\Device\\Winachsf0"); status = IoAttachDevice(fdo, &TargetDeviceName, &DevExt->LowerLevelDeviceObject); if(!NT_SUCCESS(status)) { IoDeleteSymbolicLink(&SymbolicLinkName); IoDeleteDevice(fdo); return status; } fdo->DeviceType = DevExt->LowerLevelDeviceObject->DeviceType; fdo->Characteristics = DevExt->LowerLevelDeviceObject->Characteristics; fdo->Flags |= (DevExt->LowerLevelDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO)); */ fdo->Flags &= ~DO_DEVICE_INITIALIZING; KdPrint(("Leave CreateDevice!\n")); return status; } NTSTATUS IoCtlPassthrough(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { KdPrint(("Enter IoCtlPassthrough!\n")); NTSTATUS status; PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp); PDEVICE_EXTENSION DevExt = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension; switch(stack->Parameters.DeviceIoControl.IoControlCode) { case ATTACH_CTL_CODE: { ULONG lInputBufferLen = stack->Parameters.DeviceIoControl.InputBufferLength; ANSI_STRING strDriver; strDriver.Buffer = (PCHAR)ExAllocatePool(PagedPool, lInputBufferLen); if(NULL == strDriver.Buffer) { status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; break; } RtlCopyMemory(strDriver.Buffer, Irp->AssociatedIrp.SystemBuffer, lInputBufferLen); strDriver.Length = (USHORT)lInputBufferLen; KdPrint(("strDriver is %Z!\n", &strDriver)); UNICODE_STRING TargetDeviceName; if(!NT_SUCCESS(status = RtlAnsiStringToUnicodeString(&TargetDeviceName, &strDriver, TRUE))) { RtlFreeAnsiString(&strDriver); Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; break; } KdPrint(("TargetDeviceName is %wZ!\n", &TargetDeviceName)); if(NULL != DevExt->LowerLevelDeviceObject) { IoDetachDevice(DevExt->LowerLevelDeviceObject); DevExt->LowerLevelDeviceObject = NULL; } /***********该部分代码和CreateDevice中注释部分功能相同,此处IoAttachDevice失败,而CreateDevice中可以成功************/ status = IoAttachDevice(DeviceObject, &TargetDeviceName, &DevExt->LowerLevelDeviceObject); if(!NT_SUCCESS(status)) { KdPrint(("IoAttachDevice failed and status = %s!\n", OsrNTStatusToString(status))); RtlFreeAnsiString(&strDriver); RtlFreeUnicodeString(&TargetDeviceName); Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; break; } /****************************************End********************************************/ RtlFreeAnsiString(&strDriver); RtlFreeUnicodeString(&TargetDeviceName); DevExt->LowerLevelDeviceObject->DeviceType = DevExt->LowerLevelDeviceObject->DeviceType; DevExt->LowerLevelDeviceObject->Characteristics = DevExt->LowerLevelDeviceObject->Characteristics; DevExt->LowerLevelDeviceObject->Flags |= (DevExt->LowerLevelDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO)); Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; break; } case DETACH_CTL_CODE: if(NULL != DevExt->LowerLevelDeviceObject) { status = STATUS_SUCCESS; IoDetachDevice(DevExt->LowerLevelDeviceObject); Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } break; } if(NULL == DevExt->LowerLevelDeviceObject) { status = STATUS_SUCCESS; Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); } else { IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(DevExt->LowerLevelDeviceObject, Irp); } KdPrint(("Leave IoCtlPassthrough!\n")); return status; } |
|
地板#
发布于:2010-01-19 21:16
找到问题了
问题出在IoControl派遣例程中ULONG lInputBufferLen = stack->Parameters.DeviceIoControl.InputBufferLength; ANSI_STRING strDriver; strDriver.Buffer = (PCHAR)ExAllocatePool(PagedPool, lInputBufferLen); if(NULL == strDriver.Buffer) { status = STATUS_INSUFFICIENT_RESOURCES; Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; break; } RtlCopyMemory(strDriver.Buffer, Irp->AssociatedIrp.SystemBuffer, lInputBufferLen); strDriver.Length = (USHORT)lInputBufferLen; KdPrint(("strDriver is %Z!\n", &strDriver)); 这里strDriver.Length是不正确的,其值应该是实际字符串的长度,strDriver.MaximumLength才应该是lInputBufferLen。strDriver错了就导致其对应的UNICODE_STRING也不正确,由此我的体会是ANSI_STRING和UNICODE_STRING的Length也很重要,大家不要只将注意力放在它们的值上而忽视大小,这个问题困扰了我好几天。 |
|