beiujm
驱动小牛
驱动小牛
  • 注册日期2005-11-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分983分
  • 威望129点
  • 贡献值0点
  • 好评度98点
  • 原创分0分
  • 专家分0分
阅读:1571回复:1

关于驱动中通过DEVICE_OBJECT得到设备类型等信息请教

楼主#
更多 发布于:2008-01-11 10:49
如题,希望高人能够帮下忙。

参考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盘插入实在驱动加载之后,怎么判断设备的类型)。



http://beiyu.bokee.com
fazwh
驱动牛犊
驱动牛犊
  • 注册日期2005-09-11
  • 最后登录2020-11-18
  • 粉丝0
  • 关注0
  • 积分32分
  • 威望303点
  • 贡献值0点
  • 好评度48点
  • 原创分0分
  • 专家分0分
  • 社区居民
沙发#
发布于:2008-04-22 17:09
关注。
游客

返回顶部