More on WDM Device Interfaces

0 Likes

Problem:

Ok, I think I basically understand WDM Device Interfaces but how do applications get a path to a device that exports a device interface?

Resolution:

More on WDM Device Interfaces

If you read the previous tip on WDM Device Interfaces (325), you may have been left wondering how applications actually obtain a path to a device that exports a device interface. This tip shows how to do just that.

First of all, you must know the class GUID for the device interface that was registered by a device that you want to open. For example:

static GUID MyDevInterfaceClassGuid =

{ 0x5de30cc0, 0xfef7, 0x11d1, { 0xb3, 0x14, 0x0, 0xc0, 0xd1, 0x57, 0x49, 0x7d } };

Next, call SetupDiGetClassDevs, which returns a handle to a device information set. The device information set contains information about all device interfaces of the class specified by the GUID. For example:

#include

HDEVINFO hInfo;

DWORD flags = DIGCF_DEVICEINTERFACE | DIGCF_PRESENT;

hInfo = SetupDiGetClassDevs(&MyDevInterfaceClassGuid, NULL, NULL, flags);

The next step is to enumerate each of the device interfaces in the device information set. The routine that does this is SetupDiEnumDeviceInterfaces. You can call this routine repeatedly, incrementing parameter index each timem, until it returns FALSE and GetLastError returns ERROR_NO_MORE_ITEMS.

SP_DEVICE_INTERFACE_DATA DevData;

DevData.cbSize = sizeof( SP_DEVICE_INTERFACE_DATA );

DWORD index = 0;

status = SetupDiEnumDeviceInterfaces(

hInfo,

NULL,

&MyDevInterfaceClassGuid,

index,

&DevData

);

Once you have successfully enumerated a device interface, you can then get detailed information about it. The information is bus or device specific, but always includes at least the pathname for opening the device with CreateFile. To get the detailed information, you call SetupDiGetInterfaceDeviceDetail. You must call this once to get the memory requirement for the buffer, and then a second time to actually get the data. For example:

DWORD ReqLen;

// first call to get buffer size

SetupDiGetInterfaceDeviceDetail (

hInfo,

&DevData,

NULL,

0,

&ReqLen,

NULL

);

PSP_INTERFACE_DEVICE_DETAIL_DATA DevDetail;

DevDetail = PSP_INTERFACE_DEVICE_DETAIL_DATA(new char[ReqLen]);

if ( ! DevDetail )

{

// error

}

DevDetail->cbSize = sizeof SP_INTERFACE_DEVICE_DETAIL_DATA;

// second call to actually get the data

status = SetupDiGetInterfaceDeviceDetail (

hInfo,

&DevData,

DevDetail,

ReqLen,

&ReqLen,

NULL

);

Finally, you can call CreateFile with the path returned from SetupDiGetInterfaceDeviceDetail:

if (status)

{

HANDLE hDev = CreateFile(

DevDetail->DevicePath,

GENERIC_READ | GENERIC_WRITE,

FILE_SHARE_READ | FILE_SHARE_WRITE,

NULL,

OPEN_EXISTING,

FILE_ATTRIBUTE_NORMAL,

NULL

);

}

If you are using DriverWorks™, there are two new classes in version 2.0, CDeviceInterfaceClass and CDeviceInterface, which simplify these operations for applications.

Old KB# 11304
Comment List
Anonymous
Related Discussions
Recommended