[OSR-DETECTED-SPAM] Re: SetupDiGetDeviceInterfaceDetail Function & DevicePath

Does intel have sample applications that work? All signs point to the driver refusing the file create though. Have you set a bp on the driver’s MJ_CREATE handler to see if it is invoked and what it is returning?

Bent from my phone


From: xxxxx@lists.osr.com on behalf of xxxxx@winsystems.com xxxxx@lists.osr.com
Sent: Wednesday, August 9, 2017 8:37:36 AM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] SetupDiGetDeviceInterfaceDetail Function & DevicePath

I am running the application in an administrator console window.


NTDEV is sponsored by OSR

Visit the list online at: https:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at https:

To unsubscribe, visit the List Server section of OSR Online at https:</https:></https:></https:>

I cannot do a printf since I am in a DLL, but I used the MessageBoxW to confirm that the \?\ is indeed present.

The CreateFile returns a -1 and the GetLastError returns a 2.

I have hard coded these strings and tied to open the device with no luck.

I see the I2C devices in Device Manager with a loaded driver (iaioi2c.sys). The I2Cpublic.h include file from Intel has this:

DEFINE_GUID(I2C_LPSS_INTERFACE_GUID,
0x4fd00181, 0xf807, 0x41aa, 0x8d, 0x33, 0xf2, 0x2c, 0x5d, 0x7c, 0xae, 0xbd);

I am including the entire function here so all is visible. Thanks for the help Tim.

DECLDIR int InitializeSession()
{
HDEVINFO DeviceInfoSet;
SP_DEVINFO_DATA DeviceInfoData;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL;
ULONG requiredSize = 0, Length;
DWORD Index = 0;
HANDLE tempHandle;
WCHAR *i2cDevice = I2C_CONTROLLER_NUM; // L"0f41"
DWORD LastError;
DWORD status = SUCCESS;

DeviceInfoSet = SetupDiGetClassDevs((GUID*)&I2C_LPSS_INTERFACE_GUID, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

if (DeviceInfoSet == INVALID_HANDLE_VALUE)
return status = INVALID_HANDLE;

SetupDiEnumDeviceInfo(DeviceInfoSet, Index, &DeviceInfoData);

DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

while (SetupDiEnumDeviceInfo(DeviceInfoSet, Index, &DeviceInfoData))
{
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
SetupDiCreateDeviceInterface(DeviceInfoSet, &DeviceInfoData, &DeviceInfoData.ClassGuid, NULL, 0, &DeviceInterfaceData);

// call the first time to get required buffer size
status = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &DeviceInterfaceData, NULL, 0, &requiredSize, NULL);
LastError = GetLastError();

if (status == FALSE && LastError != ERROR_INSUFFICIENT_BUFFER)
{
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return LastError;
}

// allocate required buffer
if (requiredSize)
DeviceInterfaceDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)LocalAlloc(LMEM_FIXED, requiredSize);

if (DeviceInterfaceDetailData == NULL)
{
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return status = INSUFFICIENT_MEMORY;
}

// call the second time to get detailed info
DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
Length = requiredSize;
status = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &DeviceInterfaceData, DeviceInterfaceDetailData, Length, &requiredSize, NULL);

if (status == FALSE)
{
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
LocalFree(DeviceInterfaceDetailData);
return GetLastError();
}

// check for i2c controller #1 and break
if (wcsstr(DeviceInterfaceDetailData->DevicePath, i2cDevice) != NULL)
break;

Index++;
}

if (DeviceInterfaceDetailData)
{
tempHandle = CreateFileW(DeviceInterfaceDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);

LastError = GetLastError();

if (tempHandle == INVALID_HANDLE_VALUE)
status = INVALID_HANDLE;
else
lvdsControllerHandle = tempHandle;
}

LocalFree(DeviceInterfaceDetailData);
SetupDiDestroyDeviceInfoList(DeviceInfoSet);

return status;
}

Intel does not provide any code samples but they would be very helpful. I am in contact with them also but they aren’t much help. Agreed that the driver does not like what I am trying. Don’t believe I have visibility to set bp’s in the driver.

As a side note, you are leaking DeviceInterfaceDetailData when if you go through the loop more than once

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@winsystems.com xxxxx@lists.osr.com
Sent: Wednesday, August 9, 2017 2:22 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] SetupDiGetDeviceInterfaceDetail Function & DevicePath

I cannot do a printf since I am in a DLL, but I used the MessageBoxW to confirm that the \?\ is indeed present.

The CreateFile returns a -1 and the GetLastError returns a 2.

I have hard coded these strings and tied to open the device with no luck.

I see the I2C devices in Device Manager with a loaded driver (iaioi2c.sys). The I2Cpublic.h include file from Intel has this:

DEFINE_GUID(I2C_LPSS_INTERFACE_GUID,
0x4fd00181, 0xf807, 0x41aa, 0x8d, 0x33, 0xf2, 0x2c, 0x5d, 0x7c, 0xae, 0xbd);

I am including the entire function here so all is visible. Thanks for the help Tim.

DECLDIR int InitializeSession()
{
HDEVINFO DeviceInfoSet;
SP_DEVINFO_DATA DeviceInfoData;
SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
PSP_DEVICE_INTERFACE_DETAIL_DATA DeviceInterfaceDetailData = NULL;
ULONG requiredSize = 0, Length;
DWORD Index = 0;
HANDLE tempHandle;
WCHAR i2cDevice = I2C_CONTROLLER_NUM; // L"0f41"
DWORD LastError;
DWORD status = SUCCESS;

DeviceInfoSet = SetupDiGetClassDevs((GUID
)&I2C_LPSS_INTERFACE_GUID, NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE);

if (DeviceInfoSet == INVALID_HANDLE_VALUE)
return status = INVALID_HANDLE;

SetupDiEnumDeviceInfo(DeviceInfoSet, Index, &DeviceInfoData);

DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);

while (SetupDiEnumDeviceInfo(DeviceInfoSet, Index, &DeviceInfoData))
{
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
SetupDiCreateDeviceInterface(DeviceInfoSet, &DeviceInfoData, &DeviceInfoData.ClassGuid, NULL, 0, &DeviceInterfaceData);

// call the first time to get required buffer size
status = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &DeviceInterfaceData, NULL, 0, &requiredSize, NULL);
LastError = GetLastError();

if (status == FALSE && LastError != ERROR_INSUFFICIENT_BUFFER)
{
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return LastError;
}

// allocate required buffer
if (requiredSize)
DeviceInterfaceDetailData = (PSP_INTERFACE_DEVICE_DETAIL_DATA)LocalAlloc(LMEM_FIXED, requiredSize);

if (DeviceInterfaceDetailData == NULL)
{
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
return status = INSUFFICIENT_MEMORY;
}

// call the second time to get detailed info
DeviceInterfaceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
Length = requiredSize;
status = SetupDiGetDeviceInterfaceDetail(DeviceInfoSet, &DeviceInterfaceData, DeviceInterfaceDetailData, Length, &requiredSize, NULL);

if (status == FALSE)
{
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
LocalFree(DeviceInterfaceDetailData);
return GetLastError();
}

// check for i2c controller #1 and break
if (wcsstr(DeviceInterfaceDetailData->DevicePath, i2cDevice) != NULL)
break;

Index++;
}

if (DeviceInterfaceDetailData)
{
tempHandle = CreateFileW(DeviceInterfaceDetailData->DevicePath,
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
NULL);

LastError = GetLastError();

if (tempHandle == INVALID_HANDLE_VALUE)
status = INVALID_HANDLE;
else
lvdsControllerHandle = tempHandle;
}

LocalFree(DeviceInterfaceDetailData);
SetupDiDestroyDeviceInfoList(DeviceInfoSet);

return status;
}


NTDEV is sponsored by OSR

Visit the list online at: https:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at https:

To unsubscribe, visit the List Server section of OSR Online at https:</https:></https:></https:>

For the breakpoint, sure you do and you don’t need symbols. !drvobj 2 will show you the entry points, including the one for IRP_MJ_CREATE. You can get the driver object from the device object or !object \Driver

d

-----Original Message-----
From: xxxxx@lists.osr.com [mailto:xxxxx@lists.osr.com] On Behalf Of xxxxx@winsystems.com xxxxx@lists.osr.com
Sent: Wednesday, August 9, 2017 2:33 PM
To: Windows System Software Devs Interest List
Subject: RE:[ntdev] [OSR-DETECTED-SPAM] Re: SetupDiGetDeviceInterfaceDetail Function & DevicePath

Intel does not provide any code samples but they would be very helpful. I am in contact with them also but they aren’t much help. Agreed that the driver does not like what I am trying. Don’t believe I have visibility to set bp’s in the driver.


NTDEV is sponsored by OSR

Visit the list online at: https:

MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
Details at https:

To unsubscribe, visit the List Server section of OSR Online at https:</https:></https:></https:>

These look like windbg commands. I am launching the application remotely from Visual Studio 2013. I tried to step into CreateFile but am obviously missing the necessary data. This is something I have never done before. Sorry for my ignorance.

Sorry about my last post. I looked back at the headers and the strings used are TCHAR strings.

I wonder if SetupDiCreateDeviceInterface is the right choice. The doc states that the interface created by the app must be enabled by the driver. Typically, to open a device handle with a device interface, you do the following:

  1. Open the device info list with SetupDiGetClassDevs like you did.
  2. Loop through the list of device interfaces with SetupDiEnumDeviceInterfaces.
  3. For each device interface, get the detailed data (device path) with SetupDiGetDeviceInterfaceDetail.

You should give it a try.

windev234 wrote:

I wonder if SetupDiCreateDeviceInterface is the right choice. The doc states that the interface created by the app must be enabled by the driver. Typically, to open a device handle with a device interface, you do the following:

Hmmm – I never even noticed that.

xxxxx@winsystems.com xxxxx@lists.osr.com wrote:

while (SetupDiEnumDeviceInfo(DeviceInfoSet, Index, &DeviceInfoData))
{
DeviceInterfaceData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
SetupDiCreateDeviceInterface(DeviceInfoSet, &DeviceInfoData, &DeviceInfoData.ClassGuid, NULL, 0, &DeviceInterfaceData);

Yes, this is totally wrong. You want to enumerate the interfaces that
have already been exposed by existing drivers. You cannot add
additional interfaces to existing drivers, because you don’t know what
interfaces they support. Plus, you are adding the ClassGuid, which is
the Device Manager install class, not a device interface. You need to
rip this line right out.


Tim Roberts, xxxxx@probo.com
Providenza & Boekelheide, Inc.

I actually discovered last night that the GUID of the Device Class was being appended to the path instead of the GUID of the device itself. In the registry, it showed the proper name in the SymbolicLink property. After I hard coded the device name with the right GUID, I was able to open the device.

I was going to research how to fix the code this morning but the answer was waiting for me here. I added your code fixes and it works! Thanks to all who helped. This is a great resource!