Hi,
I'm trying to write an application which returns me a handle to a
device in C#. I already got most of the information needed for this
purpose, like the DeviceInfoSet (as IntPtr), the SP_DEVINFO_DATA
struct, the device name, ... But the final step, calling
SetupDiEnumDeviceInterfaces() to retrieve the SP_DEVICE_INTERFACE_DATA
struct fails. Extraction from my code:


//get device info set for the device class
_deviceInfoSet = SetupDiGetClassDevs(ref _guids[0], 0,
IntPtr.Zero, DIGCF_PRESENT);
if (_deviceInfoSet.ToInt32() == -1)
if (!res) { //device information is unavailable:
_deviceName = new StringBuilder("");
_errorcode = -3; return;
}

//_deviceInfoData.cbSize = (uint)
Marshal.SizeOf(_deviceInfoData);
_deviceInfoData.cbSize = 28;
_deviceInfoData.DevInst = 0;
_deviceInfoData.ClassGuid = System.Guid.Empty;
_deviceInfoData.Reserved = 0;

res = SetupDiEnumDeviceInfo(_deviceInfoSet, _deviceIndex,
_deviceInfoData);
if (!res) { //no such device:
SetupDiDestroyDeviceInfoList(_deviceInfoSet);
_deviceName = new StringBuilder("");
_errorcode = -1; return;
}

// code for get the device name by calling
SetupDiGetDeviceRegistryProperty() ....


/* ok till here */


SP_DEVICE_INTERFACE_DETAIL_DATA diDetail = new
SP_DEVICE_INTERFACE_DETAIL_DATA();
//diDetail.cbSize = (uint) Marshal.SizeOf(diDetail);
if (IntPtr.Size == 8)
diDetail.cbSize = 8;
else
diDetail.cbSize = 5;
uint size1 = 0;

// get Buffer Size
bool check =
SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, ref _deviceInfoData,
IntPtr.Zero, 0, out size1, IntPtr.Zero);
check =
SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, ref _deviceInfoData,
ref diDetail, size1, out size1, IntPtr.Zero);


SetupDiGetDeviceInterfaceDetail() always returns false, and size1
stays '0'. What am I doing wrong?
Or is there an other way in getting the device path? Maybe there is a
function returning the device path when passing the DevInst or
Reserved field from SP_DEVINFO_DATA?

Other ways I tried:
retrieving the device ID by calling CM_Get_Device_ID(); but till now I
haven't a way how to get the device path by device ID.
IoGetDeviceProperty(); but I don't know how to get PDEVICE_OBJECT
(marshalled as IntPtr) as I don't know in which .dll
IoGetDeviceObjectPointer() can be found (WineHQ tells me something
about 'ntoskrnl.dll' which cannot be found on my WinXP system; so I
tried 'ntoskrnl.exe' but got an AccessViolationException with the
explanation "Attempted to read or write protected memory. This is
often an indication that other memory is corrupt.")

As you see, I tried a lot of different ways, but couldn't find the
proper solution. Can you help me?
Thanks a lot
Christian Dankl

Re: getting the device path / device handle of a specific device by Doron

Doron
Thu Mar 13 16:14:43 CDT 2008

both IoXxxx calls are kernel mode APIs, not user mode APIs. what does
GetLastError (Marshal.Interop.GetLastError ?) return?

d

--
Please do not send e-mail directly to this alias. this alias is for
newsgroup purposes only.
This posting is provided "AS IS" with no warranties, and confers no rights.


<trebanloasn@googlemail.com> wrote in message
news:0c20ea9d-b7e2-46b0-bbc3-8827be39dddc@n75g2000hsh.googlegroups.com...
> Hi,
> I'm trying to write an application which returns me a handle to a
> device in C#. I already got most of the information needed for this
> purpose, like the DeviceInfoSet (as IntPtr), the SP_DEVINFO_DATA
> struct, the device name, ... But the final step, calling
> SetupDiEnumDeviceInterfaces() to retrieve the SP_DEVICE_INTERFACE_DATA
> struct fails. Extraction from my code:
>
>
> //get device info set for the device class
> _deviceInfoSet = SetupDiGetClassDevs(ref _guids[0], 0,
> IntPtr.Zero, DIGCF_PRESENT);
> if (_deviceInfoSet.ToInt32() == -1)
> if (!res) { //device information is unavailable:
> _deviceName = new StringBuilder("");
> _errorcode = -3; return;
> }
>
> //_deviceInfoData.cbSize = (uint)
> Marshal.SizeOf(_deviceInfoData);
> _deviceInfoData.cbSize = 28;
> _deviceInfoData.DevInst = 0;
> _deviceInfoData.ClassGuid = System.Guid.Empty;
> _deviceInfoData.Reserved = 0;
>
> res = SetupDiEnumDeviceInfo(_deviceInfoSet, _deviceIndex,
> _deviceInfoData);
> if (!res) { //no such device:
> SetupDiDestroyDeviceInfoList(_deviceInfoSet);
> _deviceName = new StringBuilder("");
> _errorcode = -1; return;
> }
>
> // code for get the device name by calling
> SetupDiGetDeviceRegistryProperty() ....
>
>
> /* ok till here */
>
>
> SP_DEVICE_INTERFACE_DETAIL_DATA diDetail = new
> SP_DEVICE_INTERFACE_DETAIL_DATA();
> //diDetail.cbSize = (uint) Marshal.SizeOf(diDetail);
> if (IntPtr.Size == 8)
> diDetail.cbSize = 8;
> else
> diDetail.cbSize = 5;
> uint size1 = 0;
>
> // get Buffer Size
> bool check =
> SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, ref _deviceInfoData,
> IntPtr.Zero, 0, out size1, IntPtr.Zero);
> check =
> SetupDiGetDeviceInterfaceDetail(_deviceInfoSet, ref _deviceInfoData,
> ref diDetail, size1, out size1, IntPtr.Zero);
>
>
> SetupDiGetDeviceInterfaceDetail() always returns false, and size1
> stays '0'. What am I doing wrong?
> Or is there an other way in getting the device path? Maybe there is a
> function returning the device path when passing the DevInst or
> Reserved field from SP_DEVINFO_DATA?
>
> Other ways I tried:
> retrieving the device ID by calling CM_Get_Device_ID(); but till now I
> haven't a way how to get the device path by device ID.
> IoGetDeviceProperty(); but I don't know how to get PDEVICE_OBJECT
> (marshalled as IntPtr) as I don't know in which .dll
> IoGetDeviceObjectPointer() can be found (WineHQ tells me something
> about 'ntoskrnl.dll' which cannot be found on my WinXP system; so I
> tried 'ntoskrnl.exe' but got an AccessViolationException with the
> explanation "Attempted to read or write protected memory. This is
> often an indication that other memory is corrupt.")
>
> As you see, I tried a lot of different ways, but couldn't find the
> proper solution. Can you help me?
> Thanks a lot
> Christian Dankl