237 lines
8.1 KiB
C
237 lines
8.1 KiB
C
#include "precomp.h"
|
|
#pragma hdrstop
|
|
|
|
//
|
|
// Format: devprop <Enumerator | DeviceId | *> [-m <MachineName>]
|
|
//
|
|
|
|
TCHAR DevPropTable[][34] = {
|
|
TEXT("SPDRP_DEVICEDESC"),
|
|
TEXT("SPDRP_HARDWAREID"),
|
|
TEXT("SPDRP_COMPATIBLEIDS"),
|
|
TEXT("SPDRP_UNUSED0"),
|
|
TEXT("SPDRP_SERVICE"),
|
|
TEXT("SPDRP_UNUSED1"),
|
|
TEXT("SPDRP_UNUSED2"),
|
|
TEXT("SPDRP_CLASS"),
|
|
TEXT("SPDRP_CLASSGUID"),
|
|
TEXT("SPDRP_DRIVER"),
|
|
TEXT("SPDRP_CONFIGFLAGS"),
|
|
TEXT("SPDRP_MFG"),
|
|
TEXT("SPDRP_FRIENDLYNAME"),
|
|
TEXT("SPDRP_LOCATION_INFORMATION"),
|
|
TEXT("SPDRP_PHYSICAL_DEVICE_OBJECT_NAME"),
|
|
TEXT("SPDRP_CAPABILITIES"),
|
|
TEXT("SPDRP_UI_NUMBER"),
|
|
TEXT("SPDRP_UPPERFILTERS"),
|
|
TEXT("SPDRP_LOWERFILTERS"),
|
|
TEXT("SPDRP_BUSTYPEGUID"),
|
|
TEXT("SPDRP_LEGACYBUSTYPE"),
|
|
TEXT("SPDRP_BUSNUMBER"),
|
|
TEXT("SPDRP_ENUMERATOR_NAME"),
|
|
TEXT("SPDPR_SECURITY"),
|
|
TEXT("SPDRP_SECURITY_SDS"),
|
|
TEXT("SPDRP_DEVTYPE"),
|
|
TEXT("SPDRP_EXCLUSIVE"),
|
|
TEXT("SPDRP_CHARACTERISTICS"),
|
|
TEXT("SPDRP_ADDRESS"),
|
|
TEXT("SPDRP_UI_NUMBER_DESC_FORMAT")
|
|
};
|
|
|
|
int
|
|
__cdecl
|
|
_tmain(
|
|
IN int argc,
|
|
IN PTCHAR argv[]
|
|
)
|
|
{
|
|
TCHAR DeviceId[MAX_DEVICE_ID_LEN];
|
|
TCHAR MachineName[SP_MAX_MACHINENAME_LENGTH];
|
|
int CharsInUnicodeString;
|
|
HDEVINFO DeviceInfoSet;
|
|
SP_DEVINFO_DATA DeviceInfoData;
|
|
DWORD Err;
|
|
DWORD i, j, k, RegDataType, BufferSize;
|
|
BYTE Buffer[1024];
|
|
LPCTSTR CurString;
|
|
LPCTSTR MachineNameString = NULL;
|
|
BOOL OpenSpecificDevice = FALSE;
|
|
|
|
if((argc < 2) || !lstrcmp(argv[1], TEXT("-?")) || !lstrcmp(argv[1], TEXT("/?"))) {
|
|
_tprintf(TEXT("Usage: devprop <Enumerator | DeviceId | *> [-m <MachineName>]\n"));
|
|
return -1;
|
|
}
|
|
|
|
//
|
|
// The user specified either an enumerator name, a specific device ID, or a
|
|
// wildcard ('*'). We can tell the difference between the first two based
|
|
// on whether or not there's a path separator character in the string.
|
|
//
|
|
|
|
if(lstrlen(argv[1]) >= MAX_DEVICE_ID_LEN) {
|
|
_tprintf(TEXT("DeviceId must be less than %d characters.\n"), MAX_DEVICE_ID_LEN);
|
|
return -1;
|
|
}
|
|
lstrcpyn(DeviceId, argv[1], MAX_DEVICE_ID_LEN);
|
|
|
|
if((lstrlen(DeviceId) == 1) && (*DeviceId == TEXT('*'))) {
|
|
//
|
|
// The wildcard character ('*') was specified--process all devices
|
|
//
|
|
CurString = NULL;
|
|
|
|
} else if(_tcschr(DeviceId, TEXT('\\'))) {
|
|
//
|
|
// This device has a path separator character--assume it's a valid
|
|
// device id.
|
|
//
|
|
OpenSpecificDevice = TRUE;
|
|
|
|
} else {
|
|
//
|
|
// Assume this string is an enumerator name.
|
|
//
|
|
CurString = DeviceId;
|
|
}
|
|
|
|
//
|
|
// See if the user pointed us at a remote machine via the "-m" option.
|
|
//
|
|
if((argc > 3) && !_tcsicmp(argv[2], TEXT("-m"))) {
|
|
|
|
if(lstrlen(argv[3]) >= SP_MAX_MACHINENAME_LENGTH) {
|
|
_tprintf(TEXT("Machine name must be less than %d characters.\n"), SP_MAX_MACHINENAME_LENGTH);
|
|
return -1;
|
|
}
|
|
lstrcpy(MachineName, argv[3]);
|
|
|
|
MachineNameString = MachineName;
|
|
}
|
|
|
|
if(OpenSpecificDevice) {
|
|
//
|
|
// Create an HDEVINFO set, and open up a device information element for the specified
|
|
// device within that set.
|
|
//
|
|
DeviceInfoSet = SetupDiCreateDeviceInfoListEx(NULL, NULL, MachineNameString, NULL);
|
|
if(DeviceInfoSet == INVALID_HANDLE_VALUE) {
|
|
_tprintf(TEXT("SetupDiCreateDeviceInfoList failed with %lx\n"), GetLastError());
|
|
return -1;
|
|
}
|
|
|
|
if(!SetupDiOpenDeviceInfo(DeviceInfoSet,
|
|
DeviceId,
|
|
NULL,
|
|
0,
|
|
NULL)) {
|
|
|
|
Err = GetLastError();
|
|
_tprintf(TEXT("SetupDiOpenDeviceInfo failed with %lx\n"), Err);
|
|
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
|
|
return -1;
|
|
}
|
|
|
|
} else {
|
|
DeviceInfoSet = SetupDiGetClassDevsEx(NULL,
|
|
CurString,
|
|
NULL,
|
|
DIGCF_ALLCLASSES,
|
|
NULL,
|
|
MachineNameString,
|
|
NULL
|
|
);
|
|
|
|
if(DeviceInfoSet == INVALID_HANDLE_VALUE) {
|
|
_tprintf(TEXT("SetupDiGetClassDevs failed with %lx\n"), GetLastError());
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
|
|
for(i = 0;
|
|
SetupDiEnumDeviceInfo(DeviceInfoSet, i, &DeviceInfoData);
|
|
i++)
|
|
{
|
|
SetupDiGetDeviceInstanceId(DeviceInfoSet,
|
|
&DeviceInfoData,
|
|
DeviceId,
|
|
MAX_DEVICE_ID_LEN,
|
|
NULL
|
|
);
|
|
|
|
_tprintf(TEXT("For device \"%s\"\n"), DeviceId);
|
|
|
|
for(j = 0; j < (sizeof(DevPropTable) / sizeof(DevPropTable[0])); j++) {
|
|
|
|
_tprintf(TEXT(" %s : ("), DevPropTable[j]);
|
|
|
|
if(SetupDiGetDeviceRegistryProperty(DeviceInfoSet,
|
|
&DeviceInfoData,
|
|
j,
|
|
&RegDataType,
|
|
Buffer,
|
|
sizeof(Buffer),
|
|
&BufferSize)) {
|
|
Err = NO_ERROR;
|
|
} else {
|
|
Err = GetLastError();
|
|
}
|
|
|
|
if(Err == NO_ERROR) {
|
|
|
|
switch(RegDataType) {
|
|
|
|
case REG_SZ :
|
|
_tprintf(TEXT("REG_SZ:%d) \"%s\"\n"),
|
|
BufferSize,
|
|
(LPCTSTR)Buffer
|
|
);
|
|
break;
|
|
|
|
case REG_MULTI_SZ :
|
|
_tprintf(TEXT("REG_MULTI_SZ:%d)"), BufferSize);
|
|
for(CurString = (LPCTSTR)Buffer;
|
|
*CurString;
|
|
CurString += lstrlen(CurString) + 1) {
|
|
|
|
_tprintf(TEXT(" \"%s\""), CurString);
|
|
}
|
|
_tprintf(TEXT("\n"));
|
|
break;
|
|
|
|
case REG_DWORD :
|
|
_tprintf(TEXT("REG_DWORD:%d) %lx\n"),
|
|
BufferSize,
|
|
*((PDWORD)Buffer)
|
|
);
|
|
break;
|
|
|
|
case REG_BINARY :
|
|
_tprintf(TEXT("REG_BINARY:%d)"), BufferSize);
|
|
for(k = 0; k < BufferSize; k++) {
|
|
_tprintf(TEXT(" %lx"), Buffer[k]);
|
|
}
|
|
_tprintf(TEXT("\n"));
|
|
break;
|
|
|
|
default :
|
|
_tprintf(TEXT("Registry data type %lx:%d)\n"),
|
|
RegDataType,
|
|
BufferSize
|
|
);
|
|
}
|
|
|
|
} else {
|
|
_tprintf(TEXT("Error %lx)\n"), Err);
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
|
|
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
|
|
|
|
return 0;
|
|
}
|
|
|