📄 cmds.cpp
字号:
/*++
Copyright (c) Microsoft Corporation. All rights reserved.
Module Name:
devcon.cpp
Abstract:
Device Console
command-line interface for managing devices
--*/
#include "devcon.h"
struct GenericContext {
DWORD count;
DWORD control;
BOOL reboot;
LPCTSTR strSuccess;
LPCTSTR strReboot;
LPCTSTR strFail;
};
#define FIND_DEVICE 0x00000001 // display device
#define FIND_STATUS 0x00000002 // display status of device
#define FIND_RESOURCES 0x00000004 // display resources of device
#define FIND_DRIVERFILES 0x00000008 // display drivers used by device
#define FIND_HWIDS 0x00000010 // display hw/compat id's used by device
#define FIND_DRIVERNODES 0x00000020 // display driver nodes for a device.
#define FIND_CLASS 0x00000040 // display device's setup class
#define FIND_STACK 0x00000080 // display device's driver-stack
struct SetHwidContext {
int argc_right;
LPTSTR * argv_right;
DWORD prop;
int skipped;
int modified;
};
int cmdHelp(LPCTSTR BaseName,LPCTSTR Machine,int argc,TCHAR* argv[])
/*++
Routine Description:
HELP command
allow HELP or HELP <command>
Arguments:
BaseName - name of executable
Machine - if non-NULL, remote machine (ignored)
argc/argv - remaining parameters
Return Value:
EXIT_xxxx
--*/
{
DWORD helptext = 0;
int dispIndex;
LPCTSTR cmd = NULL;
BOOL unknown = FALSE;
if(argc) {
//
// user passed in a command for help on... long help
//
for(dispIndex = 0;DispatchTable[dispIndex].cmd;dispIndex++) {
if(_tcsicmp(argv[0],DispatchTable[dispIndex].cmd)==0) {
cmd = DispatchTable[dispIndex].cmd;
helptext = DispatchTable[dispIndex].longHelp;
break;
}
}
if(!cmd) {
unknown = TRUE;
cmd = argv[0];
}
}
if(helptext) {
//
// long help
//
FormatToStream(stdout,helptext,BaseName,cmd);
} else {
//
// help help
//
FormatToStream(stdout,unknown ? MSG_HELP_OTHER : MSG_HELP_LONG,BaseName,cmd);
//
// enumerate through each command and display short help for each
//
for(dispIndex = 0;DispatchTable[dispIndex].cmd;dispIndex++) {
if(DispatchTable[dispIndex].shortHelp) {
FormatToStream(stdout,DispatchTable[dispIndex].shortHelp,DispatchTable[dispIndex].cmd);
}
}
}
return EXIT_OK;
}
int cmdClasses(LPCTSTR BaseName,LPCTSTR Machine,int argc,TCHAR* argv[])
/*++
Routine Description:
CLASSES command
lists classes on (optionally) specified machine
format as <name>: <destination>
Arguments:
BaseName - name of executable
Machine - if non-NULL, remote machine
argc/argv - remaining parameters - ignored
Return Value:
EXIT_xxxx
--*/
{
DWORD reqGuids = 128;
DWORD numGuids;
LPGUID guids = NULL;
DWORD index;
int failcode = EXIT_FAIL;
guids = new GUID[reqGuids];
if(!guids) {
goto final;
}
if(!SetupDiBuildClassInfoListEx(0,guids,reqGuids,&numGuids,Machine,NULL)) {
do {
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto final;
}
delete [] guids;
reqGuids = numGuids;
guids = new GUID[reqGuids];
if(!guids) {
goto final;
}
} while(!SetupDiBuildClassInfoListEx(0,guids,reqGuids,&numGuids,Machine,NULL));
}
FormatToStream(stdout,Machine?MSG_CLASSES_HEADER:MSG_CLASSES_HEADER_LOCAL,numGuids,Machine);
for(index=0;index<numGuids;index++) {
TCHAR className[MAX_CLASS_NAME_LEN];
TCHAR classDesc[LINE_LEN];
if(!SetupDiClassNameFromGuidEx(&guids[index],className,MAX_CLASS_NAME_LEN,NULL,Machine,NULL)) {
lstrcpyn(className,TEXT("?"),MAX_CLASS_NAME_LEN);
}
if(!SetupDiGetClassDescriptionEx(&guids[index],classDesc,LINE_LEN,NULL,Machine,NULL)) {
lstrcpyn(classDesc,className,LINE_LEN);
}
_tprintf(TEXT("%-20s: %s\n"),className,classDesc);
}
failcode = EXIT_OK;
final:
if(guids) {
delete [] guids;
}
return failcode;
}
int cmdListClass(LPCTSTR BaseName,LPCTSTR Machine,int argc,TCHAR* argv[])
/*++
Routine Description:
LISTCLASS <name>....
lists all devices for each specified class
there can be more than one physical class for a class name (shouldn't be
though) in such cases, list each class
if machine given, list devices for that machine
Arguments:
BaseName - name of executable
Machine - if non-NULL, remote machine
argc/argv - remaining parameters - list of class names
Return Value:
EXIT_xxxx
--*/
{
BOOL classListed = FALSE;
BOOL devListed = FALSE;
DWORD reqGuids = 16;
int argIndex;
int failcode = EXIT_FAIL;
LPGUID guids = NULL;
HDEVINFO devs = INVALID_HANDLE_VALUE;
if(!argc) {
return EXIT_USAGE;
}
guids = new GUID[reqGuids];
if(!guids) {
goto final;
}
for(argIndex = 0;argIndex<argc;argIndex++) {
DWORD numGuids;
DWORD index;
if(!(argv[argIndex] && argv[argIndex][0])) {
continue;
}
//
// there could be one to many name to GUID mapping
//
while(!SetupDiClassGuidsFromNameEx(argv[argIndex],guids,reqGuids,&numGuids,Machine,NULL)) {
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto final;
}
delete [] guids;
reqGuids = numGuids;
guids = new GUID[reqGuids];
if(!guids) {
goto final;
}
}
if(numGuids == 0) {
FormatToStream(stdout,Machine?MSG_LISTCLASS_NOCLASS:MSG_LISTCLASS_NOCLASS_LOCAL,argv[argIndex],Machine);
continue;
}
for(index = 0;index<numGuids;index++) {
TCHAR className[MAX_CLASS_NAME_LEN];
TCHAR classDesc[LINE_LEN];
DWORD devCount = 0;
SP_DEVINFO_DATA devInfo;
DWORD devIndex;
devs = SetupDiGetClassDevsEx(&guids[index],NULL,NULL,DIGCF_PRESENT,NULL,Machine,NULL);
if(devs != INVALID_HANDLE_VALUE) {
//
// count number of devices
//
devInfo.cbSize = sizeof(devInfo);
while(SetupDiEnumDeviceInfo(devs,devCount,&devInfo)) {
devCount++;
}
}
if(!SetupDiClassNameFromGuidEx(&guids[index],className,MAX_CLASS_NAME_LEN,NULL,Machine,NULL)) {
lstrcpyn(className,TEXT("?"),MAX_CLASS_NAME_LEN);
}
if(!SetupDiGetClassDescriptionEx(&guids[index],classDesc,LINE_LEN,NULL,Machine,NULL)) {
lstrcpyn(classDesc,className,LINE_LEN);
}
//
// how many devices?
//
if (!devCount) {
FormatToStream(stdout,Machine?MSG_LISTCLASS_HEADER_NONE:MSG_LISTCLASS_HEADER_NONE_LOCAL,className,classDesc,Machine);
} else {
FormatToStream(stdout,Machine?MSG_LISTCLASS_HEADER:MSG_LISTCLASS_HEADER_LOCAL,devCount,className,classDesc,Machine);
for(devIndex=0;SetupDiEnumDeviceInfo(devs,devIndex,&devInfo);devIndex++) {
DumpDevice(devs,&devInfo);
}
}
if(devs != INVALID_HANDLE_VALUE) {
SetupDiDestroyDeviceInfoList(devs);
devs = INVALID_HANDLE_VALUE;
}
}
}
failcode = 0;
final:
if(guids) {
delete [] guids;
}
if(devs != INVALID_HANDLE_VALUE) {
SetupDiDestroyDeviceInfoList(devs);
}
return failcode;
}
int FindCallback(HDEVINFO Devs,PSP_DEVINFO_DATA DevInfo,DWORD Index,LPVOID Context)
/*++
Routine Description:
Callback for use by Find/FindAll
just simply display the device
Arguments:
Devs )_ uniquely identify the device
DevInfo )
Index - index of device
Context - GenericContext
Return Value:
EXIT_xxxx
--*/
{
GenericContext *pFindContext = (GenericContext*)Context;
if(!pFindContext->control) {
DumpDevice(Devs,DevInfo);
pFindContext->count++;
return EXIT_OK;
}
if(!DumpDeviceWithInfo(Devs,DevInfo,NULL)) {
return EXIT_OK;
}
if(pFindContext->control&FIND_DEVICE) {
DumpDeviceDescr(Devs,DevInfo);
}
if(pFindContext->control&FIND_CLASS) {
DumpDeviceClass(Devs,DevInfo);
}
if(pFindContext->control&FIND_STATUS) {
DumpDeviceStatus(Devs,DevInfo);
}
if(pFindContext->control&FIND_RESOURCES) {
DumpDeviceResources(Devs,DevInfo);
}
if(pFindContext->control&FIND_DRIVERFILES) {
DumpDeviceDriverFiles(Devs,DevInfo);
}
if(pFindContext->control&FIND_STACK) {
DumpDeviceStack(Devs,DevInfo);
}
if(pFindContext->control&FIND_HWIDS) {
DumpDeviceHwIds(Devs,DevInfo);
}
if (pFindContext->control&FIND_DRIVERNODES) {
DumpDeviceDriverNodes(Devs,DevInfo);
}
pFindContext->count++;
return EXIT_OK;
}
int cmdFind(LPCTSTR BaseName,LPCTSTR Machine,int argc,TCHAR* argv[])
/*++
Routine Description:
FIND <id> ...
use EnumerateDevices to do hardwareID matching
for each match, dump to stdout
note that we only enumerate present devices
Arguments:
BaseName - name of executable
Machine - if non-NULL, remote machine
argc/argv - remaining parameters - passed into EnumerateDevices
Return Value:
EXIT_xxxx
--*/
{
GenericContext context;
int failcode;
if(!argc) {
return EXIT_USAGE;
}
context.count = 0;
context.control = 0;
failcode = EnumerateDevices(BaseName,Machine,DIGCF_PRESENT,argc,argv,FindCallback,&context);
if(failcode == EXIT_OK) {
if(!context.count) {
FormatToStream(stdout,Machine?MSG_FIND_TAIL_NONE:MSG_FIND_TAIL_NONE_LOCAL,Machine);
} else {
FormatToStream(stdout,Machine?MSG_FIND_TAIL:MSG_FIND_TAIL_LOCAL,context.count,Machine);
}
}
return failcode;
}
int cmdFindAll(LPCTSTR BaseName,LPCTSTR Machine,int argc,TCHAR* argv[])
/*++
Routine Description:
FINDALL <id> ...
use EnumerateDevices to do hardwareID matching
for each match, dump to stdout
like find, but also show not-present devices
Arguments:
BaseName - name of executable
Machine - if non-NULL, remote machine
argc/argv - remaining parameters - passed into EnumerateDevices
Return Value:
EXIT_xxxx
--*/
{
GenericContext context;
int failcode;
if(!argc) {
return EXIT_USAGE;
}
context.count = 0;
context.control = 0;
failcode = EnumerateDevices(BaseName,Machine,0,argc,argv,FindCallback,&context);
if(failcode == EXIT_OK) {
if(!context.count) {
FormatToStream(stdout,Machine?MSG_FIND_TAIL_NONE:MSG_FIND_TAIL_NONE_LOCAL,Machine);
} else {
FormatToStream(stdout,Machine?MSG_FIND_TAIL:MSG_FIND_TAIL_LOCAL,context.count,Machine);
}
}
return failcode;
}
int cmdStatus(LPCTSTR BaseName,LPCTSTR Machine,int argc,TCHAR* argv[])
/*++
Routine Description:
STATUS <id> ...
use EnumerateDevices to do hardwareID matching
for each match, dump status to stdout
note that we only enumerate present devices
Arguments:
BaseName - name of executable
Machine - if non-NULL, remote machine
argc/argv - remaining parameters - passed into EnumerateDevices
Return Value:
EXIT_xxxx
--*/
{
GenericContext context;
int failcode;
if(!argc) {
return EXIT_USAGE;
}
context.count = 0;
context.control = FIND_DEVICE | FIND_STATUS;
failcode = EnumerateDevices(BaseName,Machine,DIGCF_PRESENT,argc,argv,FindCallback,&context);
if(failcode == EXIT_OK) {
if(!context.count) {
FormatToStream(stdout,Machine?MSG_FIND_TAIL_NONE:MSG_FIND_TAIL_NONE_LOCAL,Machine);
} else {
FormatToStream(stdout,Machine?MSG_FIND_TAIL:MSG_FIND_TAIL_LOCAL,context.count,Machine);
}
}
return failcode;
}
int cmdResources(LPCTSTR BaseName,LPCTSTR Machine,int argc,TCHAR* argv[])
/*++
Routine Description:
RESOURCES <id> ...
use EnumerateDevices to do hardwareID matching
for each match, dump resources to stdout
note that we only enumerate present devices
Arguments:
BaseName - name of executable
Machine - if non-NULL, remote machine
argc/argv - remaining parameters - passed into EnumerateDevices
Return Value:
EXIT_xxxx
--*/
{
GenericContext context;
int failcode;
if(!argc) {
return EXIT_USAGE;
}
context.count = 0;
context.control = FIND_DEVICE | FIND_RESOURCES;
failcode = EnumerateDevices(BaseName,Machine,DIGCF_PRESENT,argc,argv,FindCallback,&context);
if(failcode == EXIT_OK) {
if(!context.count) {
FormatToStream(stdout,Machine?MSG_FIND_TAIL_NONE:MSG_FIND_TAIL_NONE_LOCAL,Machine);
} else {
FormatToStream(stdout,Machine?MSG_FIND_TAIL:MSG_FIND_TAIL_LOCAL,context.count,Machine);
}
}
return failcode;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -