阅读:1571回复:1
关于驱动中通过DEVICE_OBJECT得到设备类型等信息请教
如题,希望高人能够帮下忙。
参考Sfilter中的结构和历程。 例如在注册回调函数的时候,当U盘加载,FsNotification得到调用 IoRegisterFsRegistrationChange(DriverObject, FsNotification); VOID FsNotification( IN PDEVICE_OBJECT DeviceObject, IN BOOLEAN FsActive ) {。。。} 那么怎么在FsNotification调用中,通过DeviceObject得到设备的类型是USB盘。 在开发过程中,发现可以在派遣函数 DriverObject->MajorFunction[IRP_MJ_FILE_SYSTEM_CONTROL] = FsControl; NTSTATUS FsControl( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp ) {。。。} 通过Irp得到IRP栈, PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp) 然后再用IRP栈得到真正设备的类型。下面的代码参考驱网上例子,得到挂接设备真正的类型。 NTSTATUS GetStorageDeviceBusType( IN PDEVICE_OBJECT DeviceObject, ULONG* puType, IN PIRP Irp) { PIRP NewIrp; PSTORAGE_DEVICE_DESCRIPTOR Descriptor; PSTORAGE_PROPERTY_QUERY pQuery; PSTORAGE_PROPERTY_QUERY pBuffer; KEVENT WaitEvent; NTSTATUS Status = STATUS_SUCCESS; IO_STATUS_BLOCK IoStatus; KIRQL CurrentIRQL; PDEVICE_OBJECT StorageStackDeviceObject; PIO_STACK_LOCATION IrpSp; UNREFERENCED_PARAMETER(Irp); UNREFERENCED_PARAMETER(DeviceObject); *puType = BusTypeUnknown; if(Irp == NULL) { KdPrint(("USBFilter!GetStorageDeviceBusType Irp == NULL\n")); return Status; } //ASSERT(KeGetCurrentIrql() < DISPATCH_LEVEL); CurrentIRQL = KeGetCurrentIrql(); if(CurrentIRQL >= DISPATCH_LEVEL) { KdPrint(("USBFilter!GetStorageDeviceBusType CurrentIRQL != PASSIVE_LEVEL\n")); return Status; } //得到真正的设备对象 IrpSp = IoGetCurrentIrpStackLocation(Irp); StorageStackDeviceObject = IrpSp->Parameters.MountVolume.Vpb->RealDevice; pBuffer = (PSTORAGE_PROPERTY_QUERY)ExAllocatePool(NonPagedPool, sizeof(STORAGE_DEVICE_DESCRIPTOR) * 4); pQuery = (PSTORAGE_PROPERTY_QUERY)ExAllocatePool(NonPagedPool, sizeof(STORAGE_DEVICE_DESCRIPTOR)); // first set the query properties pQuery->PropertyId = StorageDeviceProperty; pQuery->QueryType = PropertyStandardQuery; // initialize the waitable event KeInitializeEvent(&WaitEvent, NotificationEvent, FALSE); // we should build the query irp ourselves //发送irp对象,这里需要是真正的设备 NewIrp = IoBuildDeviceIoControlRequest( IOCTL_STORAGE_QUERY_PROPERTY, StorageStackDeviceObject, (PVOID)pQuery, sizeof(STORAGE_DEVICE_DESCRIPTOR), (PVOID)pBuffer, sizeof(STORAGE_DEVICE_DESCRIPTOR) * 4, FALSE, &WaitEvent, &IoStatus); if (NULL == NewIrp) // can't create new irp { DbgPrint("[%s] [%u] I can't create a new irp to query the property of device (%p)!\n", __FILE__, __LINE__, StorageStackDeviceObject); return Status; } // send this irp to the storage device Status = IoCallDriver(StorageStackDeviceObject, NewIrp); if (Status == STATUS_PENDING) { Status = KeWaitForSingleObject(&WaitEvent, Executive, KernelMode, FALSE, NULL); Status = IoStatus.Status; } if (!NT_SUCCESS(Status)) { DbgPrint("[%s] [%u] Query IOCTL_STORAGE_QUERY_PROPERTY of device (%p) failed, Status=0x%08X!\n", __FILE__, __LINE__, StorageStackDeviceObject, Status); return Status; } Descriptor = (PSTORAGE_DEVICE_DESCRIPTOR)pBuffer; *puType = Descriptor->BusType; ExFreePool(pBuffer); ExFreePool(pQuery); return Status; } GetStorageDeviceBusType可以被FsControl调用成功。但是通过这个步骤只能在驱动加载好以后,判断其后插入的U盘,那么怎么判断系统中在驱动加载之前就已经加载好了的U盘呢?(也就是U盘插入实在驱动加载之后,怎么判断设备的类型)。 |
|
|
沙发#
发布于:2008-04-22 17:09
关注。
|
|