Windows System Software -- Consulting, Training, Development -- Unique Expertise, Guaranteed Results

Home NTDEV
Before Posting...
Please check out the Community Guidelines in the Announcements and Administration Category.

More Info on Driver Writing and Debugging


The free OSR Learning Library has more than 50 articles on a wide variety of topics about writing and debugging device drivers and Minifilters. From introductory level to advanced. All the articles have been recently reviewed and updated, and are written using the clear and definitive style you've come to expect from OSR over the years.


Check out The OSR Learning Library at: https://www.osr.com/osr-learning-library/


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

Doron_HolanDoron_Holan Member - All Emails Posts: 10,499
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: [email protected] on behalf of [email protected]stems.com [email protected]
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:

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

To unsubscribe, visit the List Server section of OSR Online at
d

Comments

  • PBDPBD Member Posts: 71
    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;
    }
  • PBDPBD Member Posts: 71
    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.
  • Doron_HolanDoron_Holan Member - All Emails Posts: 10,499
    As a side note, you are leaking DeviceInterfaceDetailData when if you go through the loop more than once

    d

    -----Original Message-----
    From: [email protected] [mailto:[email protected]] On Behalf Of [email protected] [email protected]
    Sent: Wednesday, August 9, 2017 2:22 PM
    To: Windows System Software Devs Interest List <[email protected]>
    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://na01.safelinks.protection.outlook.com/?url=http://www.osronline.com/showlists.cfm?list=ntdev&amp;data=02|01|[email protected]|71e5cf79a12244d157b108d4df6cc507|72f988bf86f141af91ab2d7cd011db47|1|0|636379105638066297&amp;sdata=zlZ1ixdaEk2HuUw+rqmhL4Hwl67XHWFrlDxGRCPRQTU=&amp;reserved=0&gt;

    MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
    Details at <https://na01.safelinks.protection.outlook.com/?url=http://www.osr.com/seminars&amp;data=02|01|[email protected]|71e5cf79a12244d157b108d4df6cc507|72f988bf86f141af91ab2d7cd011db47|1|0|636379105638066297&amp;sdata=ByugIsaoTrggRuQx/v4dAUPJv9uBzNKkTySKjJUzRoU=&amp;reserved=0&gt;

    To unsubscribe, visit the List Server section of OSR Online at <https://na01.safelinks.protection.outlook.com/?url=http://www.osronline.com/page.cfm?name=ListServer&amp;data=02|01|[email protected]|71e5cf79a12244d157b108d4df6cc507|72f988bf86f141af91ab2d7cd011db47|1|0|636379105638066297&amp;sdata=RjdsDPFPV4VDEv+aFpGB7ZRoSFxvDGsmjb2/A6mqvpo=&amp;reserved=0&gt;
    d
  • Doron_HolanDoron_Holan Member - All Emails Posts: 10,499
    For the breakpoint, sure you do and you don't need symbols. !drvobj <driver object> 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: [email protected] [mailto:[email protected]] On Behalf Of [email protected] [email protected]
    Sent: Wednesday, August 9, 2017 2:33 PM
    To: Windows System Software Devs Interest List <[email protected]>
    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://na01.safelinks.protection.outlook.com/?url=http://www.osronline.com/showlists.cfm?list=ntdev&amp;data=02|01|[email protected]|1a0d4b69b2ea4588801c08d4df6e5e4a|72f988bf86f141af91ab2d7cd011db47|1|0|636379112588684000&amp;sdata=64aO+4WE8hZ9FI4+heoEDUGZyx53swO6XW6ajlap7xw=&amp;reserved=0&gt;

    MONTHLY seminars on crash dump analysis, WDF, Windows internals and software drivers!
    Details at <https://na01.safelinks.protection.outlook.com/?url=http://www.osr.com/seminars&amp;data=02|01|[email protected]|1a0d4b69b2ea4588801c08d4df6e5e4a|72f988bf86f141af91ab2d7cd011db47|1|0|636379112588684000&amp;sdata=XDsvy6B19MQzkQUHKk6xw5w54DRSe+/YdvVXxeqfMT8=&amp;reserved=0&gt;

    To unsubscribe, visit the List Server section of OSR Online at <https://na01.safelinks.protection.outlook.com/?url=http://www.osronline.com/page.cfm?name=ListServer&amp;data=02|01|[email protected]|1a0d4b69b2ea4588801c08d4df6e5e4a|72f988bf86f141af91ab2d7cd011db47|1|0|636379112588684000&amp;sdata=aOsh5V2ct/9dkRCrkK6dcMl4/s+eAA2TMBWYuakbqZk=&amp;reserved=0&gt;
    d
  • PBDPBD Member Posts: 71
    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.
  • OSR_Community_UserOSR_Community_User Member Posts: 110,217
    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.
  • Tim_RobertsTim_Roberts Member - All Emails Posts: 13,451
    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.


    [email protected] [email protected] 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, [email protected]
    Providenza & Boekelheide, Inc.

    Tim Roberts, [email protected]
    Providenza & Boekelheide, Inc.

  • PBDPBD Member Posts: 71
    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!
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Upcoming OSR Seminars
OSR has suspended in-person seminars due to the Covid-19 outbreak. But, don't miss your training! Attend via the internet instead!
Kernel Debugging 30 Mar 2020 OSR Seminar Space
Developing Minifilters 15 Jun 2020 LIVE ONLINE
Writing WDF Drivers 22 June 2020 LIVE ONLINE
Internals & Software Drivers 28 Sept 2020 Dulles, VA