📄 cmds.cpp
字号:
//
// skip this
//
return EXIT_OK;
}
rmdParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
rmdParams.ClassInstallHeader.InstallFunction = DIF_REMOVE;
rmdParams.Scope = DI_REMOVEDEVICE_GLOBAL;
rmdParams.HwProfile = 0;
if(!SetupDiSetClassInstallParams(Devs,DevInfo,&rmdParams.ClassInstallHeader,sizeof(rmdParams)) ||
!SetupDiCallClassInstaller(DIF_REMOVE,Devs,DevInfo)) {
//
// failed to invoke DIF_REMOVE
//
action = pControlContext->strFail;
} else {
//
// see if device needs reboot
//
devParams.cbSize = sizeof(devParams);
if(SetupDiGetDeviceInstallParams(Devs,DevInfo,&devParams) && (devParams.Flags & (DI_NEEDRESTART|DI_NEEDREBOOT))) {
//
// reboot required
//
action = pControlContext->strReboot;
pControlContext->reboot = TRUE;
} else {
//
// appears to have succeeded
//
action = pControlContext->strSuccess;
}
pControlContext->count++;
}
_tprintf(TEXT("%-60s: %s\n"),devID,action);
return EXIT_OK;
}
int cmdRemove(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in_ecount(argc) TCHAR* argv[])
/*++
Routine Description:
REMOVE
remove devices
Arguments:
BaseName - name of executable
Machine - machine name, must be NULL
argc/argv - remaining parameters
Return Value:
EXIT_xxxx
--*/
{
GenericContext context;
TCHAR strRemove[80];
TCHAR strReboot[80];
TCHAR strFail[80];
int failcode = EXIT_FAIL;
if(!argc) {
//
// arguments required
//
return EXIT_USAGE;
}
if(Machine) {
//
// must be local machine as we need to involve class/co installers
//
return EXIT_USAGE;
}
if(!LoadString(NULL,IDS_REMOVED,strRemove,ARRAYSIZE(strRemove))) {
return EXIT_FAIL;
}
if(!LoadString(NULL,IDS_REMOVED_REBOOT,strReboot,ARRAYSIZE(strReboot))) {
return EXIT_FAIL;
}
if(!LoadString(NULL,IDS_REMOVE_FAILED,strFail,ARRAYSIZE(strFail))) {
return EXIT_FAIL;
}
context.reboot = FALSE;
context.count = 0;
context.strReboot = strReboot;
context.strSuccess = strRemove;
context.strFail = strFail;
failcode = EnumerateDevices(BaseName,Machine,DIGCF_PRESENT,argc,argv,RemoveCallback,&context);
if(failcode == EXIT_OK) {
if(!context.count) {
FormatToStream(stdout,MSG_REMOVE_TAIL_NONE);
} else if(!context.reboot) {
FormatToStream(stdout,MSG_REMOVE_TAIL,context.count);
} else {
FormatToStream(stdout,MSG_REMOVE_TAIL_REBOOT,context.count);
failcode = EXIT_REBOOT;
}
}
return failcode;
}
int cmdRescan(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in_ecount(argc) TCHAR* argv[])
/*++
Routine Description:
RESCAN
rescan for new devices
Arguments:
BaseName - name of executable
Machine - machine name, must be NULL
argc/argv - remaining parameters
Return Value:
EXIT_xxxx
--*/
{
//
// reenumerate from the root of the devnode tree
// totally CM based
//
int failcode = EXIT_FAIL;
HMACHINE machineHandle = NULL;
DEVINST devRoot;
if(Machine) {
if(CM_Connect_Machine(Machine,&machineHandle) != CR_SUCCESS) {
return failcode;
}
}
if(CM_Locate_DevNode_Ex(&devRoot,NULL,CM_LOCATE_DEVNODE_NORMAL,machineHandle) != CR_SUCCESS) {
goto final;
}
FormatToStream(stdout,Machine ? MSG_RESCAN : MSG_RESCAN_LOCAL);
if(CM_Reenumerate_DevNode_Ex(devRoot, 0, machineHandle) != CR_SUCCESS) {
goto final;
}
FormatToStream(stdout,MSG_RESCAN_OK);
failcode = EXIT_OK;
final:
if(machineHandle) {
CM_Disconnect_Machine(machineHandle);
}
return failcode;
}
int cmdClassFilter(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in_ecount(argc) TCHAR* argv[])
/*++
Routine Description:
CLASSFILTER <name> <type> <subcmds>
Allows tweaking of class filters
Useful for filter driver development and for Product Support
<subcmds> is a list of the following:
@service - sets 'after' to the first match of service after 'after'
(reset to -1 after any other command)
!service - deletes first match of 'service' after 'after'
-service - insert new service directly prior to 'after', or at start
+service - insert new service directly after 'after', or at end
if no <subcmds> given, list the services
Arguments:
BaseName - name of executable
Machine - if non-NULL, remote machine
argc/argv - remaining parameters - list of class names
Return Value:
EXIT_xxxx
--*/
{
int failcode = EXIT_FAIL;
int argIndex;
DWORD numGuids = 0;
GUID guid;
LPTSTR regval = NULL;
HKEY hk = (HKEY)INVALID_HANDLE_VALUE;
LPTSTR * multiVal = NULL;
int after;
bool modified = false;
int span;
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(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo, __in DWORD Index, __in 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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -