📄 cmds.cpp
字号:
SC_HANDLE SCMHandle = NULL;
SC_HANDLE ServHandle = NULL;
if((argc<2) || !argv[0][0]) {
return EXIT_USAGE;
}
//
// just take the first guid for the name
//
if(!SetupDiClassGuidsFromNameEx(argv[0],&guid,1,&numGuids,Machine,NULL)) {
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto final;
}
}
if(numGuids == 0) {
goto final;
}
if(_tcsicmp(argv[1],TEXT("upper"))==0) {
regval = REGSTR_VAL_UPPERFILTERS;
} else if(_tcsicmp(argv[1],TEXT("lower"))==0) {
regval = REGSTR_VAL_LOWERFILTERS;
} else {
failcode = EXIT_USAGE;
goto final;
}
hk = SetupDiOpenClassRegKeyEx(&guid,
KEY_READ | (argc>2 ? KEY_WRITE : 0),
DIOCR_INSTALLER,
Machine,
NULL
);
if(hk == INVALID_HANDLE_VALUE) {
goto final;
}
multiVal = GetRegMultiSz(hk,regval);
if(argc<=2) {
//
// just display
//
FormatToStream(stdout,MSG_CLASSFILTER_UNCHANGED);
DumpArray(1,multiVal);
failcode = EXIT_OK;
goto final;
}
after = -1; // for the @service expressions
span = 1;
if(!multiVal) {
multiVal = CopyMultiSz(NULL);
if(!multiVal) {
goto final;
}
}
for(argIndex=2;argIndex<argc;argIndex++) {
if((argv[argIndex] == NULL) ||
(!argv[argIndex])) {
failcode = EXIT_USAGE;
break;
}
int op = argv[argIndex][0];
LPTSTR serv = argv[argIndex]+1;
int mark = 0;
int cnt;
int ent;
LPTSTR * tmpArray;
if(op == TEXT('=')) {
after = -1;
span = 1;
op = serv[0];
if(!op) {
continue;
}
serv++;
}
if(!serv[0]) {
failcode = EXIT_USAGE;
goto final;
}
if((op == TEXT('@')) || (op == TEXT('!'))) {
//
// need to find specified service in list
//
for(after+=span;multiVal[after];after++) {
if(_tcsicmp(multiVal[after],serv)==0) {
break;
}
}
if(!multiVal[after]) {
goto final;
}
if(op == TEXT('@')) {
//
// all we needed to do for '@'
//
span = 1; // span of 1
continue;
}
//
// we're modifying
//
int c;
for(c = after;multiVal[c];c++) {
multiVal[c] = multiVal[c+1];
}
LPTSTR * newArray = CopyMultiSz(multiVal);
if(!newArray) {
goto final;
}
DelMultiSz(multiVal);
multiVal = newArray;
span = 0; // span of 0 (deleted)
modified = true;
continue;
}
if(op == '+') {
//
// insert after
//
if(after<0) {
int c;
for(c = 0;multiVal[c];c++) {
// nothing
}
mark = c;
}
else {
mark = after+span;
}
} else if(op == '-') {
//
// insert before
//
if(after<0) {
mark = 0;
} else {
mark = after;
}
} else {
//
// not valid
//
failcode = EXIT_USAGE;
goto final;
}
//
// sanity - see if service exists
//
if(!(SCMHandle = OpenSCManager(Machine, NULL, GENERIC_READ))) {
goto final;
}
ServHandle = OpenService(SCMHandle,serv,GENERIC_READ);
if(ServHandle) {
CloseServiceHandle(ServHandle);
}
CloseServiceHandle(SCMHandle);
if(!ServHandle) {
goto final;
}
//
// need an array a little bigger
//
for(cnt = 0;multiVal[cnt];cnt++) {
// nothing
}
tmpArray = new LPTSTR[cnt+2];
if(!tmpArray) {
goto final;
}
for(ent=0;ent<mark;ent++) {
tmpArray[ent] = multiVal[ent];
}
tmpArray[ent] = serv;
for(;ent<cnt;ent++) {
tmpArray[ent+1] = multiVal[ent];
}
tmpArray[ent+1] = NULL;
LPTSTR * newArray = CopyMultiSz(tmpArray);
delete [] tmpArray;
if(!newArray) {
goto final;
}
DelMultiSz(multiVal);
multiVal = newArray;
modified = true;
span = 1;
after = mark;
}
if(modified) {
if(multiVal[0]) {
int len = 0;
LPTSTR multiSz = multiVal[-1];
LPTSTR p = multiSz;
while(*p) {
p+=lstrlen(p)+1;
}
p++; // skip past null
len = (p-multiSz)*sizeof(TCHAR);
LONG err = RegSetValueEx(hk,regval,0,REG_MULTI_SZ,(LPBYTE)multiSz,len);
if(err==NO_ERROR) {
FormatToStream(stdout,MSG_CLASSFILTER_CHANGED);
DumpArray(1,multiVal);
failcode = EXIT_REBOOT;
}
} else {
LONG err = RegDeleteValue(hk,regval);
if((err == NO_ERROR) || (err == ERROR_FILE_NOT_FOUND)) {
FormatToStream(stdout,MSG_CLASSFILTER_CHANGED);
failcode = EXIT_REBOOT;
}
}
} else {
FormatToStream(stdout,MSG_CLASSFILTER_UNCHANGED);
DumpArray(1,multiVal);
failcode = EXIT_OK;
}
final:
if(multiVal) {
DelMultiSz(multiVal);
}
if(hk != (HKEY)INVALID_HANDLE_VALUE) {
RegCloseKey(hk);
}
return failcode;
}
int SetHwidCallback(HDEVINFO Devs,PSP_DEVINFO_DATA DevInfo,DWORD Index,LPVOID Context)
/*++
Routine Description:
Callback for use by SetHwid
Arguments:
Devs )_ uniquely identify the device
DevInfo )
Index - index of device
Context - SetHwidContext
Return Value:
EXIT_xxxx
--*/
{
SP_REMOVEDEVICE_PARAMS rmdParams;
SetHwidContext *pControlContext = (SetHwidContext*)Context;
SP_DEVINSTALL_PARAMS devParams;
ULONG status;
ULONG problem;
LPTSTR * hwlist = NULL;
bool modified = false;
int result = EXIT_FAIL;
//
// processes the sub-commands on each callback
// not most efficient way of doing things, but perf isn't important
//
TCHAR devID[MAX_DEVICE_ID_LEN];
BOOL b = TRUE;
SP_DEVINFO_LIST_DETAIL_DATA devInfoListDetail;
devInfoListDetail.cbSize = sizeof(devInfoListDetail);
if((!SetupDiGetDeviceInfoListDetail(Devs,&devInfoListDetail)) ||
(CM_Get_Device_ID_Ex(DevInfo->DevInst,devID,MAX_DEVICE_ID_LEN,0,devInfoListDetail.RemoteMachineHandle)!=CR_SUCCESS) ||
(CM_Get_DevNode_Status_Ex(&status,&problem,DevInfo->DevInst,0,devInfoListDetail.RemoteMachineHandle)!=CR_SUCCESS)) {
//
// skip this
//
return EXIT_OK;
}
//
// this is how to verify it's root enumerated
//
if(!(status & DN_ROOT_ENUMERATED)) {
_tprintf(TEXT("%-60s: "),devID);
FormatToStream(stdout,MSG_SETHWID_NOTROOT);
pControlContext->skipped++;
return EXIT_OK;
}
hwlist = GetDevMultiSz(Devs,DevInfo,pControlContext->prop);
if(hwlist == NULL) {
hwlist = CopyMultiSz(NULL);
if(hwlist == NULL) {
return EXIT_FAIL;
}
}
//
// modify hwid list (only relevent for root-enumerated devices)
//
int i;
int mark = -1;
for(i=0;i<pControlContext->argc_right;i++) {
LPTSTR op = pControlContext->argv_right[i];
if(op[0] == TEXT('=')) {
//
// clear the hwid list first
//
hwlist[0] = NULL;
mark = 0;
op++;
} else if(op[0] == TEXT('+')) {
//
// insert as better match
//
mark = 0;
op++;
} else if(op[0] == TEXT('-')) {
//
// insert as worse match
//
mark = -1;
op++;
} else if(op[0] == TEXT('!')) {
//
// delete
//
mark = -2;
op++;
} else {
//
// treat as a hardware id
//
}
if(!*op) {
result = EXIT_USAGE;
goto final;
}
int cnt;
for(cnt = 0;hwlist[cnt];cnt++) {
// nothing
}
if((mark == -1) || (mark>cnt)) {
mark = cnt;
}
LPTSTR * tmpArray = new LPTSTR[cnt+2];
if(!tmpArray) {
goto final;
}
int dst = 0;
int ent;
for(ent=0;ent<mark;ent++) {
if(_tcsicmp(hwlist[ent],op)==0) {
continue;
}
tmpArray[dst++] = hwlist[ent];
}
if(mark>=0) {
tmpArray[dst++] = op;
}
for(;ent<cnt;ent++) {
if(_tcsicmp(hwlist[ent],op)==0) {
continue;
}
tmpArray[dst++] = hwlist[ent];
}
tmpArray[dst] = NULL;
LPTSTR * newArray = CopyMultiSz(tmpArray);
delete [] tmpArray;
if(!newArray) {
goto final;
}
DelMultiSz(hwlist);
hwlist = newArray;
modified = true;
mark++;
}
//
// re-set the hwid list
//
if(modified) {
if(hwlist[0]) {
int len = 0;
LPTSTR multiSz = hwlist[-1];
LPTSTR p = multiSz;
while(*p) {
p+=lstrlen(p)+1;
}
p++; // skip past final null
len = (p-multiSz)*sizeof(TCHAR);
if(!SetupDiSetDeviceRegistryProperty(Devs,
DevInfo,
pControlContext->prop,
(LPBYTE)multiSz,
len)) {
result = EXIT_FAIL;
goto final;
}
} else {
//
// delete list
//
if(!SetupDiSetDeviceRegistryProperty(Devs,
DevInfo,
pControlContext->prop,
NULL,
0)) {
result = EXIT_FAIL;
goto final;
}
}
}
result = EXIT_OK;
pControlContext->modified++;
_tprintf(TEXT("%-60s: "),devID);
for(mark=0;hwlist[mark];mark++) {
if(mark > 0) {
_tprintf(TEXT(","));
}
_tprintf(TEXT("%s"),hwlist[mark]);
}
_tprintf(TEXT("\n"));
//
// cleanup
//
final:
if(hwlist) {
DelMultiSz(hwlist);
}
return result;
}
int cmdSetHwid(LPCTSTR BaseName,LPCTSTR Machine,int argc,TCHAR* argv[])
/*++
Routine Description:
SETHWID
changes the hardware ID's of the listed root-enumerated devices
This demonstrates how to differentiate between root-enumerated and
non root-enumerated devices.
It also demonstrates how to get/set hardware ID's of root-enumerated
devices.
Arguments:
BaseName - name of executable
Machine - machine name, must be NULL
argc/argv - remaining parameters
Return Value:
EXIT_xxxx
--*/
{
SetHwidContext context;
int failcode = EXIT_FAIL;
if(!SplitCommandLine(argc,argv,context.argc_right,context.argv_right)
|| (argc == 0)
|| (context.argc_right == 0)) {
//
// arguments required both left and right of ':='
//
return EXIT_USAGE;
}
context.skipped = 0;
context.modified = 0;
context.prop = SPDRP_HARDWAREID;
failcode = EnumerateDevices(BaseName,Machine,DIGCF_PRESENT,argc,argv,SetHwidCallback,&context);
if(failcode == EXIT_OK) {
if(context.skipped) {
FormatToStream(stdout,MSG_SETHWID_TAIL_SKIPPED,context.skipped,context.modified);
} else if(context.modified) {
FormatToStream(stdout,MSG_SETHWID_TAIL_MODIFIED,context.modified);
} else {
FormatToStream(stdout,MSG_SETHWID_TAIL_NONE);
}
}
return failcode;
}
DispatchEntry DispatchTable[] = {
{ TEXT("classfilter"), cmdClassFilter, MSG_CLASSFILTER_SHORT, MSG_CLASSFILTER_LONG },
{ TEXT("classes"), cmdClasses, MSG_CLASSES_SHORT, MSG_CLASSES_LONG },
{ TEXT("disable"), cmdDisable, MSG_DISABLE_SHORT, MSG_DISABLE_LONG },
{ TEXT("driverfiles"), cmdDriverFiles, MSG_DRIVERFILES_SHORT, MSG_DRIVERFILES_LONG },
{ TEXT("drivernodes"), cmdDriverNodes, MSG_DRIVERNODES_SHORT, MSG_DRIVERNODES_LONG },
{ TEXT("enable"), cmdEnable, MSG_ENABLE_SHORT, MSG_ENABLE_LONG },
{ TEXT("find"), cmdFind, MSG_FIND_SHORT, MSG_FIND_LONG },
{ TEXT("findall"), cmdFindAll, MSG_FINDALL_SHORT, MSG_FINDALL_LONG },
{ TEXT("help"), cmdHelp, MSG_HELP_SHORT, 0 },
{ TEXT("hwids"), cmdHwIds, MSG_HWIDS_SHORT, MSG_HWIDS_LONG },
{ TEXT("install"), cmdInstall, MSG_INSTALL_SHORT, MSG_INSTALL_LONG },
{ TEXT("listclass"), cmdListClass, MSG_LISTCLASS_SHORT, MSG_LISTCLASS_LONG },
{ TEXT("reboot"), cmdReboot, MSG_REBOOT_SHORT, MSG_REBOOT_LONG },
{ TEXT("remove"), cmdRemove, MSG_REMOVE_SHORT, MSG_REMOVE_LONG },
{ TEXT("rescan"), cmdRescan, MSG_RESCAN_SHORT, MSG_RESCAN_LONG },
{ TEXT("resources"), cmdResources, MSG_RESOURCES_SHORT, MSG_RESOURCES_LONG },
{ TEXT("restart"), cmdRestart, MSG_RESTART_SHORT, MSG_RESTART_LONG },
{ TEXT("sethwid"), cmdSetHwid, MSG_SETHWID_SHORT, MSG_SETHWID_LONG },
{ TEXT("stack"), cmdStack, MSG_STACK_SHORT, MSG_STACK_LONG },
{ TEXT("status"), cmdStatus, MSG_STATUS_SHORT, MSG_STATUS_LONG },
{ TEXT("update"), cmdUpdate, MSG_UPDATE_SHORT, MSG_UPDATE_LONG },
{ TEXT("updateni"), cmdUpdateNI, MSG_UPDATENI_SHORT, MSG_UPDATENI_LONG },
{ TEXT("?"), cmdHelp, 0, 0 },
{ NULL,NULL }
};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -