Obtaining a CreateFile()device path (MS DOS Path) using SetupDi* for a device

lkd> !error -0n2147024637
Error code: (HRESULT) 0x80070103 (2147942659) - No more data is available.

On 8/27/11, xxxxx@jmr.com wrote:
> I thought that OSR was founded by Mark Rassinovich, who owned / was involved
> with SysInternals, which Microsoft bought not too long ago. I might have
> his last name mispelled. I took a class with him a few years back.
>
> Back to topic.
>
> 1. I rebooted my computer and unplugged the expander across the reboot.
>
> 2. I rewrote / restructured the code thanks to the help here.
>
> What I found out is that eliminating the SetupDiCreateInterface() call,
> rebooting, and reworking the code yields the following facts.
>
> * I am now able to get a single Device Path from the ATTO HBA controller and
> that path is the right one, which is CreateFile() friendly.
>
> * I found out that there is no interface for my expander, which means that I
> need to create a driver for it or find some other solution.
>
> Code Changes Made:
>
> // We start at the “root” of the device tree and look for all
> // devices that match the interface GUID of a disk
> DiGetClassFlags iFlags = DiGetClassFlags.DIGCF_PRESENT |
> DiGetClassFlags.DIGCF_ALLCLASSES | DiGetClassFlags.DIGCF_PROFILE |
> DiGetClassFlags.DIGCF_DEVICEINTERFACE;
> int iArgFlags = (int)iFlags;
> hDevInfo = SetupDiGetClassDevs(IntPtr.Zero, IntPtr.Zero, IntPtr.Zero,
> iArgFlags);
> if (INVALID_HANDLE_VALUE == hDevInfo.ToInt32())
> {
> Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
> return false;
> }
>
> // Boolean bResult;
> bool bSuccess = true;
> int iDevice = 0;
> while (bSuccess)
> {
> String strDevDevicePath, strDevClassName, strDevDriver,
> strDevDescription, strDevName, strDevInstanceId;
> Guid guidDevInterfaceLocal;
>
>
> // Initialize the required variables.
> strDevDevicePath = “”;
> guidDevInterfaceLocal = new Guid(0x0, 0x0000, 0x0000, 0x00, 0x00, 0x00,
> 0x00, 0x00, 0x00, 0x00, 0x00);
>
> // Create a Device Interface Data structure.
> SP_DEVINFO_DATA sDevInfoData = new SP_DEVINFO_DATA();
> sDevInfoData.cbSize = (uint)Marshal.SizeOf(sDevInfoData);
>
> // Enumerate the next devices or the first device, if the first pass.
> bSuccess = SetupDiEnumDeviceInfo(hDevInfo, (UInt32)iDevice,
> sDevInfoData);
> if (false == bSuccess)
> {
> iErrorCode = Marshal.GetHRForLastWin32Error();
> Marshal.ThrowExceptionForHR(iErrorCode);
> }
>
> // Get Device: Name
> strDevName = GetDeviceName(hDevInfo, ref sDevInfoData);
>
> // See if we have the board in question.
> if (strDevName == strDevNameToFind)
> {
> // Get Device: Interface Class GUID
> GetDeviceInterface(hDevInfo, ref sDevInfoData, ref
> guidDevInterfaceLocal, ref strDevDevicePath);
> break;
> }
>
> // Increment the device enumeration index.
> iDevice++;
> }
> }
>
> catch (Exception ex)
> {
> MessageBox.Show(ex.ToString(), Application.ProductName,
> MessageBoxButtons.OK);
> }
>
> finally
> {
> SetupDiDestroyDeviceInfoList(hDevInfo);
> }
>
> return true;
>
> The call to GetDeviceInterface() uses hDevInfo and sDevInfoData in the call
> to SetupDiEnumDeviceInterfaces(). That yields one entry and returns a
> SP_DEVICE_INTERFACE_DATA, which I can then pass to
> SetupDiGetDeviceInterfaceDetail, which gives the right path name.
>
> When calling this new code, I do not even see the expander, even though it
> shows nicely in the Windows Device Manager. I can plug in and unplug the
> expander and see the entry in Device Manager disappear and appear depending
> on if I plug the expander in or not, but no hit on the expander, hence I
> need another solution or just write a device driver.
>
> QUESTION:
> When completes and has no more matches, I get an error code of, -2147024637.
> The size of the container variable is an ‘int’, which is the size
> requested. According to
>
> http://msdn.microsoft.com/en-us/library/ms681382(v=VS.85).aspx
>
> there is no code that low / high. Is there a nice C/C++ define for this
> value? Should I be casting to something?
>
> —
> NTDEV is sponsored by OSR
>
> For our schedule of WDF, WDM, debugging and other seminars visit:
> http://www.osr.com/seminars
>
> To unsubscribe, visit the List Server section of OSR Online at
> http://www.osronline.com/page.cfm?name=ListServer
>


thanks and regards

raj_r

[OFF TOPIC]

wrote in message news:…
>The web interface for OSR has a lot to be desired. Microsoft laid an egg
>on this site. Mark sold out to Microsoft, so… Going to My Profile and
> >unchecking the two ‘spam me’ options yields on Windows 7 IE an error
>(blank really) screen. I did not know why I did not think of that for any
>website >that I ever created. Users must chose the annoyance option.

Funny, we never received an email to webmaster with this bug or the repro
steps. You DID report it, right? Because, you know, we can’t fix things on
our forums (that we run FOR FREE) if we don’t know about the bugs. Speaking
of that, if you have lots of web experience (because WE sure as hell don’t),
then we’d be more than happy for you to volunteer to help us fix any issues
that you find.

>I thought that OSR was founded by Mark Rassinovich, who owned / was
>involved with SysInternals, which Microsoft bought not too long ago. I
>might >have his last name mispelled. I took a class with him a few years
>back.

No, not at all. Mark did work here at one point, but was never a founder or
owner and we have no relationship with SysInternals (nor are we owned by
Microsoft).

>My preference would be a newsgroup reader, such as what comes with the
>Outlook Express replacement, but most companies do not support the >NMTP
>method anymore, which is sad. That leaves the web interface. Mail lists
>get to complicated to follow threads, at least for me.

Maybe you were so lost in the crappitude of the site that you didn’t read
the section on participating in the lists??

http://www.osronline.com/page.cfm?name=ListServer

Because I thought it was pretty clear from there that NNTP is supported.

-scott

Here is the sequence (simplified a bit, no error handling).

HDEVINFO DevInfo;
ULONG i;
SP_INTERFACE_DEVICE_DATA InterfaceInfo;
ULONG Length;
PSP_DEVICE_INTERFACE_DETAIL_DATA Data;
SP_DEVINFO_DATA DevData;
DevInfo = SetupDiGetClassDevs((LPGUID)InterfaceGuid, NULL, NULL, ( DIGCF_DEVICEINTERFACE | DIGCF_PRESENT ));
for( i = 0; ; i++ )
{
InterfaceInfo.cbSize = sizeof(SP_INTERFACE_DEVICE_DATA);
SetupDiEnumDeviceInterfaces(DevInfo, NULL, (LPGUID)InterfaceGuid, i, &InterfaceInfo);
Length = 0;
SetupDiGetDeviceInterfaceDetail(DevInfo, &InterfaceInfo, NULL, 0, &Length, NULL);
Data = (PSP_DEVICE_INTERFACE_DETAIL_DATA)malloc(Length);
SetupDiGetDeviceInterfaceDetail(DevInfo, &InterfaceInfo, Data, Length, NULL, &DevData);
// Here Data->DevicePath can be passed to CreateFile
// To get the friendly name of the device, use:
SetupDiGetDeviceRegistryProperty(DevInfo, &DevData, SPDRP_FRIENDLYNAME, !!! data reference);
// Then if the above fails
SetupDiGetDeviceRegistryProperty(DevInfo, &DevData, SPDRP_DEVICEDESC, !!! data reference);
}
SetupDiDestroyDeviceInfoList)(DevInfo);

BTW - note that HDEVINFO is a collection handle, and SP_DEVINFO_DATA is iterator in it.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> public class EnumerateInstall : Win32SetupDi, Win32General, cTools

This violates the Liskov’s principle (or do you want to say that your enumerator _can be used in interchangeable way with Win32SetupDi?), and thus is a sample of BAD use of inheritance.

No wonder both C# and Java prohibit multiple inheritance of implementations and not interfaces.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

> True. Multiple inheritance is a concept with some controversy.

…or just plain evil in most cases.

Alexandrescu is correct: DO NOT use inheritance just to reuse the code from the base class. Instead, make a field of the base class’s type. At least use private inheritance in C++.

Inheritance is only for cases where substitutability by Liskov is provided, not for code reuse.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com