Discussion:
Why SetupDiEnumDeviceInterfaces fails after SetupDiGetClassDevs success?
(too old to reply)
Pavel A.
2010-08-10 21:29:32 UTC
Permalink
I have a strange problem with the "classic" device interface
enumeration code (see below).
It works on all WinXP machines we tried it on, except one.
Unfortunately that is a customer's machine so I can't hack it freely,
need some concrete ideas to act upon.

In short, I call SetupDiGetClassDevs(&MY_GUID,... DIGCF_INTERFACEDEVICE)
to get devices with my interface. There is exactly one such device,
created by my driver. This call returns success.
Then I call SetupDiEnumDeviceInterfaces again for my interface GUID -
and it fails with GetLastError=ERROR_NO_MORE_ITEMS ???
I know that the driver successfully enabled this interface, it
shows up in the registry, with correct reference count and so on.

What can be wrong here? Why SetupDiEnumDeviceInterfaces can fail?
This machine is loaded with lots of various software, but generally behaves
well.

The function below is in a DLL, loaded by a console app, both compiled wih
VC2005 .

Regards,
Pavel

---------- code -------
#include <windows.h>
#include <stdio.h>
#include <initguid.h>
#include <setupapi.h>
#pragma comment(lib, "setupapi")

#define _MAX_DEVINTERFACE_NAME_CCH 512

int openDriver( HANDLE *hnd )
{
// Get list of devices with our class GUID:
HDEVINFO classDevs = SetupDiGetClassDevs( &MY_GUID,
NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );

if ( (INVALID_HANDLE_VALUE == classDevs) || (NULL == classDevs) )
{
dprintWarn("No supported devices found\n");
return -1;
}

SP_DEVICE_INTERFACE_DATA ifdata;
ifdata.cbSize = sizeof(ifdata);
if( !SetupDiEnumDeviceInterfaces(classDevs, NULL, &MY_GUID, 0,
&ifdata) )
{
//<<< HERE IT FAILS GetLastError=ERROR_NO_MORE_ITEMS
dprintWarn("OpenDriver: No supported devices found\n");
SetupDiDestroyDeviceInfoList(classDevs);
return -2;
}

// Get the name for CreateFile
..............................
}
Thomas F. Divine
2010-08-10 22:25:07 UTC
Permalink
Looks OK to me.

Have you tried fetching DeviceInfoData first? Don't know how it could make
any difference, but...

Thomas F. Divine
Post by Pavel A.
I have a strange problem with the "classic" device interface
enumeration code (see below).
It works on all WinXP machines we tried it on, except one.
Unfortunately that is a customer's machine so I can't hack it freely,
need some concrete ideas to act upon.
In short, I call SetupDiGetClassDevs(&MY_GUID,... DIGCF_INTERFACEDEVICE)
to get devices with my interface. There is exactly one such device,
created by my driver. This call returns success.
Then I call SetupDiEnumDeviceInterfaces again for my interface GUID -
and it fails with GetLastError=ERROR_NO_MORE_ITEMS ???
I know that the driver successfully enabled this interface, it
shows up in the registry, with correct reference count and so on.
What can be wrong here? Why SetupDiEnumDeviceInterfaces can fail?
This machine is loaded with lots of various software, but generally
behaves well.
The function below is in a DLL, loaded by a console app, both compiled wih
VC2005 .
Regards,
Pavel
---------- code -------
#include <windows.h>
#include <stdio.h>
#include <initguid.h>
#include <setupapi.h>
#pragma comment(lib, "setupapi")
#define _MAX_DEVINTERFACE_NAME_CCH 512
int openDriver( HANDLE *hnd )
{
HDEVINFO classDevs = SetupDiGetClassDevs( &MY_GUID,
NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
if ( (INVALID_HANDLE_VALUE == classDevs) || (NULL == classDevs) )
{
dprintWarn("No supported devices found\n");
return -1;
}
SP_DEVICE_INTERFACE_DATA ifdata;
ifdata.cbSize = sizeof(ifdata);
if( !SetupDiEnumDeviceInterfaces(classDevs, NULL, &MY_GUID, 0,
&ifdata) )
{
//<<< HERE IT FAILS GetLastError=ERROR_NO_MORE_ITEMS
dprintWarn("OpenDriver: No supported devices found\n");
SetupDiDestroyDeviceInfoList(classDevs);
return -2;
}
// Get the name for CreateFile
..............................
}
Pavel A.
2010-08-10 22:58:44 UTC
Permalink
Post by Thomas F. Divine
Looks OK to me.
For me too... and it even works on many machines...
Post by Thomas F. Divine
Have you tried fetching DeviceInfoData first? Don't know how it could make
any difference, but...
Thanks, Thomas, will try.
By the way, when I looked for the GetLastError symbolic name,
103 is ERROR_NO_MORE_ITEMS, but it is also STATUS_PENDING
as NTSTATUS... does this make any sense?

Thanks.
-- pa
Post by Thomas F. Divine
Thomas F. Divine
Post by Pavel A.
I have a strange problem with the "classic" device interface
enumeration code (see below).
It works on all WinXP machines we tried it on, except one.
Unfortunately that is a customer's machine so I can't hack it freely,
need some concrete ideas to act upon.
In short, I call SetupDiGetClassDevs(&MY_GUID,... DIGCF_INTERFACEDEVICE)
to get devices with my interface. There is exactly one such device,
created by my driver. This call returns success.
Then I call SetupDiEnumDeviceInterfaces again for my interface GUID -
and it fails with GetLastError=ERROR_NO_MORE_ITEMS ???
I know that the driver successfully enabled this interface, it
shows up in the registry, with correct reference count and so on.
What can be wrong here? Why SetupDiEnumDeviceInterfaces can fail?
This machine is loaded with lots of various software, but generally
behaves well.
The function below is in a DLL, loaded by a console app, both compiled
wih VC2005 .
Regards,
Pavel
---------- code -------
#include <windows.h>
#include <stdio.h>
#include <initguid.h>
#include <setupapi.h>
#pragma comment(lib, "setupapi")
#define _MAX_DEVINTERFACE_NAME_CCH 512
int openDriver( HANDLE *hnd )
{
HDEVINFO classDevs = SetupDiGetClassDevs( &MY_GUID,
NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
if ( (INVALID_HANDLE_VALUE == classDevs) || (NULL == classDevs) )
{
dprintWarn("No supported devices found\n");
return -1;
}
SP_DEVICE_INTERFACE_DATA ifdata;
ifdata.cbSize = sizeof(ifdata);
if( !SetupDiEnumDeviceInterfaces(classDevs, NULL, &MY_GUID, 0,
&ifdata) )
{
//<<< HERE IT FAILS GetLastError=ERROR_NO_MORE_ITEMS
dprintWarn("OpenDriver: No supported devices found\n");
SetupDiDestroyDeviceInfoList(classDevs);
return -2;
}
// Get the name for CreateFile
..............................
}
Thomas F. Divine
2010-08-11 13:22:26 UTC
Permalink
Maybe there is confusion between Win32 error codes (WinError.h) and NT
status codes (NTStatus.h).

Perhaps pending is correct in this case because of some delay...

Thos
Post by Pavel A.
Post by Thomas F. Divine
Looks OK to me.
For me too... and it even works on many machines...
Post by Thomas F. Divine
Have you tried fetching DeviceInfoData first? Don't know how it could
make any difference, but...
Thanks, Thomas, will try.
By the way, when I looked for the GetLastError symbolic name,
103 is ERROR_NO_MORE_ITEMS, but it is also STATUS_PENDING
as NTSTATUS... does this make any sense?
Thanks.
-- pa
Post by Thomas F. Divine
Thomas F. Divine
Post by Pavel A.
I have a strange problem with the "classic" device interface
enumeration code (see below).
It works on all WinXP machines we tried it on, except one.
Unfortunately that is a customer's machine so I can't hack it freely,
need some concrete ideas to act upon.
In short, I call SetupDiGetClassDevs(&MY_GUID,... DIGCF_INTERFACEDEVICE)
to get devices with my interface. There is exactly one such device,
created by my driver. This call returns success.
Then I call SetupDiEnumDeviceInterfaces again for my interface GUID -
and it fails with GetLastError=ERROR_NO_MORE_ITEMS ???
I know that the driver successfully enabled this interface, it
shows up in the registry, with correct reference count and so on.
What can be wrong here? Why SetupDiEnumDeviceInterfaces can fail?
This machine is loaded with lots of various software, but generally
behaves well.
The function below is in a DLL, loaded by a console app, both compiled
wih VC2005 .
Regards,
Pavel
---------- code -------
#include <windows.h>
#include <stdio.h>
#include <initguid.h>
#include <setupapi.h>
#pragma comment(lib, "setupapi")
#define _MAX_DEVINTERFACE_NAME_CCH 512
int openDriver( HANDLE *hnd )
{
HDEVINFO classDevs = SetupDiGetClassDevs( &MY_GUID,
NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
if ( (INVALID_HANDLE_VALUE == classDevs) || (NULL == classDevs) )
{
dprintWarn("No supported devices found\n");
return -1;
}
SP_DEVICE_INTERFACE_DATA ifdata;
ifdata.cbSize = sizeof(ifdata);
if( !SetupDiEnumDeviceInterfaces(classDevs, NULL, &MY_GUID, 0,
&ifdata) )
{
//<<< HERE IT FAILS GetLastError=ERROR_NO_MORE_ITEMS
dprintWarn("OpenDriver: No supported devices found\n");
SetupDiDestroyDeviceInfoList(classDevs);
return -2;
}
// Get the name for CreateFile
..............................
}
Pavel A.
2010-08-12 01:27:44 UTC
Permalink
Catched the culprit: Logitech USB camera driver LVUSBsta.sys.
It changed the security for built-in class Unknown ("Other devices") so that
only Local system can access it.
No idea why they did this.
Since my driver is in Unknown class, it was affected.

I've deleted the Unknown class from registry, rebooted and noticed that
somebody created it again.
The rest was simple, thanks to Sysinternals procmon: I've set it to log
registry writes on the class key during boot,
restarted again and the Logitech driver was catched with red hands.

The fix was to specify security for my device in the INF, so it won't
inherit it from the (hacked) class.
Back to basics, every day :(

Regards,
-- pa
Post by Thomas F. Divine
Maybe there is confusion between Win32 error codes (WinError.h) and NT
status codes (NTStatus.h).
Perhaps pending is correct in this case because of some delay...
Thos
Post by Pavel A.
Post by Thomas F. Divine
Looks OK to me.
For me too... and it even works on many machines...
Post by Thomas F. Divine
Have you tried fetching DeviceInfoData first? Don't know how it could
make any difference, but...
Thanks, Thomas, will try.
By the way, when I looked for the GetLastError symbolic name,
103 is ERROR_NO_MORE_ITEMS, but it is also STATUS_PENDING
as NTSTATUS... does this make any sense?
Thanks.
-- pa
Post by Thomas F. Divine
Thomas F. Divine
Post by Pavel A.
I have a strange problem with the "classic" device interface
enumeration code (see below).
It works on all WinXP machines we tried it on, except one.
Unfortunately that is a customer's machine so I can't hack it freely,
need some concrete ideas to act upon.
In short, I call SetupDiGetClassDevs(&MY_GUID,...
DIGCF_INTERFACEDEVICE)
to get devices with my interface. There is exactly one such device,
created by my driver. This call returns success.
Then I call SetupDiEnumDeviceInterfaces again for my interface GUID -
and it fails with GetLastError=ERROR_NO_MORE_ITEMS ???
I know that the driver successfully enabled this interface, it
shows up in the registry, with correct reference count and so on.
What can be wrong here? Why SetupDiEnumDeviceInterfaces can fail?
This machine is loaded with lots of various software, but generally
behaves well.
The function below is in a DLL, loaded by a console app, both compiled
wih VC2005 .
Regards,
Pavel
---------- code -------
#include <windows.h>
#include <stdio.h>
#include <initguid.h>
#include <setupapi.h>
#pragma comment(lib, "setupapi")
#define _MAX_DEVINTERFACE_NAME_CCH 512
int openDriver( HANDLE *hnd )
{
HDEVINFO classDevs = SetupDiGetClassDevs( &MY_GUID,
NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
if ( (INVALID_HANDLE_VALUE == classDevs) || (NULL == classDevs) )
{
dprintWarn("No supported devices found\n");
return -1;
}
SP_DEVICE_INTERFACE_DATA ifdata;
ifdata.cbSize = sizeof(ifdata);
if( !SetupDiEnumDeviceInterfaces(classDevs, NULL, &MY_GUID, 0,
&ifdata) )
{
//<<< HERE IT FAILS GetLastError=ERROR_NO_MORE_ITEMS
dprintWarn("OpenDriver: No supported devices found\n");
SetupDiDestroyDeviceInfoList(classDevs);
return -2;
}
// Get the name for CreateFile
..............................
}
Thomas F. Divine
2010-08-12 12:53:15 UTC
Permalink
Good sleuthing, Pavel. I'll remember that one.

Thomas
Post by Pavel A.
Catched the culprit: Logitech USB camera driver LVUSBsta.sys.
It changed the security for built-in class Unknown ("Other devices") so
that only Local system can access it.
No idea why they did this.
Since my driver is in Unknown class, it was affected.
I've deleted the Unknown class from registry, rebooted and noticed that
somebody created it again.
The rest was simple, thanks to Sysinternals procmon: I've set it to log
registry writes on the class key during boot,
restarted again and the Logitech driver was catched with red hands.
The fix was to specify security for my device in the INF, so it won't
inherit it from the (hacked) class.
Back to basics, every day :(
Regards,
-- pa
Post by Thomas F. Divine
Maybe there is confusion between Win32 error codes (WinError.h) and NT
status codes (NTStatus.h).
Perhaps pending is correct in this case because of some delay...
Thos
Post by Pavel A.
Post by Thomas F. Divine
Looks OK to me.
For me too... and it even works on many machines...
Post by Thomas F. Divine
Have you tried fetching DeviceInfoData first? Don't know how it could
make any difference, but...
Thanks, Thomas, will try.
By the way, when I looked for the GetLastError symbolic name,
103 is ERROR_NO_MORE_ITEMS, but it is also STATUS_PENDING
as NTSTATUS... does this make any sense?
Thanks.
-- pa
Post by Thomas F. Divine
Thomas F. Divine
Post by Pavel A.
I have a strange problem with the "classic" device interface
enumeration code (see below).
It works on all WinXP machines we tried it on, except one.
Unfortunately that is a customer's machine so I can't hack it freely,
need some concrete ideas to act upon.
In short, I call SetupDiGetClassDevs(&MY_GUID,...
DIGCF_INTERFACEDEVICE)
to get devices with my interface. There is exactly one such device,
created by my driver. This call returns success.
Then I call SetupDiEnumDeviceInterfaces again for my interface GUID -
and it fails with GetLastError=ERROR_NO_MORE_ITEMS ???
I know that the driver successfully enabled this interface, it
shows up in the registry, with correct reference count and so on.
What can be wrong here? Why SetupDiEnumDeviceInterfaces can fail?
This machine is loaded with lots of various software, but generally
behaves well.
The function below is in a DLL, loaded by a console app, both compiled
wih VC2005 .
Regards,
Pavel
---------- code -------
#include <windows.h>
#include <stdio.h>
#include <initguid.h>
#include <setupapi.h>
#pragma comment(lib, "setupapi")
#define _MAX_DEVINTERFACE_NAME_CCH 512
int openDriver( HANDLE *hnd )
{
HDEVINFO classDevs = SetupDiGetClassDevs( &MY_GUID,
NULL, NULL, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE );
if ( (INVALID_HANDLE_VALUE == classDevs) || (NULL == classDevs) )
{
dprintWarn("No supported devices found\n");
return -1;
}
SP_DEVICE_INTERFACE_DATA ifdata;
ifdata.cbSize = sizeof(ifdata);
if( !SetupDiEnumDeviceInterfaces(classDevs, NULL, &MY_GUID, 0,
&ifdata) )
{
//<<< HERE IT FAILS GetLastError=ERROR_NO_MORE_ITEMS
dprintWarn("OpenDriver: No supported devices found\n");
SetupDiDestroyDeviceInfoList(classDevs);
return -2;
}
// Get the name for CreateFile
..............................
}
Loading...