USBCCGP 获取USB设备特性

设备特性在windows下所有设备的通用,其主要包括一些电源特性和热插拨特性。
结构定义如下:

typedef _Struct_size_bytes_(Size) struct _DEVICE_CAPABILITIES {
    _Field_range_(==, sizeof(struct _DEVICE_CAPABILITIES)) USHORT Size;
    USHORT Version;  // the version documented here is version 1
    ULONG DeviceD1:1;
    ULONG DeviceD2:1;
    ULONG LockSupported:1;
    ULONG EjectSupported:1; // Ejectable in S0
    ULONG Removable:1;
    ULONG DockDevice:1;
    ULONG UniqueID:1;
    ULONG SilentInstall:1;
    ULONG RawDeviceOK:1;
    ULONG SurpriseRemovalOK:1;
    ULONG WakeFromD0:1;
    ULONG WakeFromD1:1;
    ULONG WakeFromD2:1;
    ULONG WakeFromD3:1;
    ULONG HardwareDisabled:1;
    ULONG NonDynamic:1;
    ULONG WarmEjectSupported:1;
    ULONG NoDisplayInUI:1;


    ULONG Reserved1:1; // See note
    ULONG WakeFromInterrupt:1;
    ULONG SecureDevice:1;
    ULONG ChildOfVgaEnabledBridge:1;
    ULONG DecodeIoOnBoot:1;

    ULONG Reserved:9; // See note

    ULONG Address;
    ULONG UINumber;

    DEVICE_POWER_STATE DeviceState[POWER_SYSTEM_MAXIMUM];
    _Field_range_(PowerSystemUnspecified, PowerSystemHibernate) SYSTEM_POWER_STATE SystemWake;
    _Field_range_(PowerDeviceUnspecified, PowerDeviceD3) DEVICE_POWER_STATE DeviceWake;
    ULONG D1Latency;
    ULONG D2Latency;
    ULONG D3Latency;
} DEVICE_CAPABILITIES, *PDEVICE_CAPABILITIES;

设备特性的获取比较简单,其有专门的IRP,只需要按要要求创建存储单元,并初始化部分成员,然且IoCallDriver到下层设备,然后就等返回就行。
完整的代码:

fdo.c


NTSTATUS
FDO_QueryCapabilities(
    IN PDEVICE_OBJECT DeviceObject,
    IN OUT PDEVICE_CAPABILITIES Capabilities)
{
    PIRP Irp;
    KEVENT Event;
    NTSTATUS Status;
    PIO_STACK_LOCATION IoStack;
    PFDO_DEVICE_EXTENSION FDODeviceExtension;

    /* Get device extension */
    FDODeviceExtension = (PFDO_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
    ASSERT(FDODeviceExtension->Common.IsFDO);

    /* Init event */
    KeInitializeEvent(&Event, NotificationEvent, FALSE);

    /* Now allocte the irp */
    Irp = IoAllocateIrp(DeviceObject->StackSize, FALSE);
    if (!Irp)
    {
        /* No memory */
        return STATUS_INSUFFICIENT_RESOURCES;
    }

    /* Get next stack location */
    IoStack = IoGetNextIrpStackLocation(Irp);

    /* Init stack location */
    IoStack->MajorFunction = IRP_MJ_PNP;
    IoStack->MinorFunction = IRP_MN_QUERY_CAPABILITIES;
    IoStack->Parameters.DeviceCapabilities.Capabilities = Capabilities;

    /* Set completion routine */
    IoSetCompletionRoutine(Irp,
                           FDO_QueryCapabilitiesCompletionRoutine,
                           (PVOID)&Event,
                           TRUE,
                           TRUE,
                           TRUE);

    /* Init capabilities */
    RtlZeroMemory(Capabilities, sizeof(DEVICE_CAPABILITIES));
    Capabilities->Size = sizeof(DEVICE_CAPABILITIES);
    Capabilities->Version = 1; // FIXME hardcoded constant
    Capabilities->Address = MAXULONG;
    Capabilities->UINumber = MAXULONG;

    /* Pnp irps have default completion code */
    Irp->IoStatus.Status = STATUS_NOT_SUPPORTED;

    /* Call lower device */
    Status = IoCallDriver(FDODeviceExtension->NextDeviceObject, Irp);
    if (Status == STATUS_PENDING)
    {
        /* Wait for completion */
        KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
    }

    /* Get status */
    Status = Irp->IoStatus.Status;

    /* Complete request */
    IoFreeIrp(Irp);

    /* Done */
    return Status;
}
取消
感谢您的支持,我会继续努力的!
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦

Powered by bytekits.com,汇天下文字,成非凡梦想!!!