📄 cmds.cpp
字号:
//
// must be local machine as we need to involve class/co installers
//
return EXIT_USAGE;
}
if(!LoadString(NULL,IDS_DISABLED,strDisable,ARRAYSIZE(strDisable))) {
return EXIT_FAIL;
}
if(!LoadString(NULL,IDS_DISABLED_REBOOT,strReboot,ARRAYSIZE(strReboot))) {
return EXIT_FAIL;
}
if(!LoadString(NULL,IDS_DISABLE_FAILED,strFail,ARRAYSIZE(strFail))) {
return EXIT_FAIL;
}
context.control = DICS_DISABLE; // DICS_PROPCHANGE DICS_ENABLE DICS_DISABLE
context.reboot = FALSE;
context.count = 0;
context.strReboot = strReboot;
context.strSuccess = strDisable;
context.strFail = strFail;
failcode = EnumerateDevices(BaseName,Machine,DIGCF_PRESENT,argc,argv,ControlCallback,&context);
if(failcode == EXIT_OK) {
if(!context.count) {
FormatToStream(stdout,MSG_FIND_TAIL_NONE_LOCAL);
} else if(!context.reboot) {
FormatToStream(stdout,MSG_DISABLE_TAIL,context.count);
} else {
FormatToStream(stdout,MSG_DISABLE_TAIL_REBOOT,context.count);
failcode = EXIT_REBOOT;
}
}
return failcode;
}
int cmdRestart(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in_ecount(argc) TCHAR* argv[])
/*++
Routine Description:
RESTART <id> ...
use EnumerateDevices to do hardwareID matching
for each match, attempt to restart by issueing a PROPCHANGE
Arguments:
BaseName - name of executable
Machine - must be NULL (local machine only)
argc/argv - remaining parameters - passed into EnumerateDevices
Return Value:
EXIT_xxxx (EXIT_REBOOT if reboot is required)
--*/
{
GenericContext context;
TCHAR strRestarted[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_RESTARTED,strRestarted,ARRAYSIZE(strRestarted))) {
return EXIT_FAIL;
}
if(!LoadString(NULL,IDS_REQUIRES_REBOOT,strReboot,ARRAYSIZE(strReboot))) {
return EXIT_FAIL;
}
if(!LoadString(NULL,IDS_RESTART_FAILED,strFail,ARRAYSIZE(strFail))) {
return EXIT_FAIL;
}
context.control = DICS_PROPCHANGE;
context.reboot = FALSE;
context.count = 0;
context.strReboot = strReboot;
context.strSuccess = strRestarted;
context.strFail = strFail;
failcode = EnumerateDevices(BaseName,Machine,DIGCF_PRESENT,argc,argv,ControlCallback,&context);
if(failcode == EXIT_OK) {
if(!context.count) {
FormatToStream(stdout,MSG_FIND_TAIL_NONE_LOCAL);
} else if(!context.reboot) {
FormatToStream(stdout,MSG_RESTART_TAIL,context.count);
} else {
FormatToStream(stdout,MSG_RESTART_TAIL_REBOOT,context.count);
failcode = EXIT_REBOOT;
}
}
return failcode;
}
int cmdReboot(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in_ecount(argc) TCHAR* argv[])
/*++
Routine Description:
REBOOT
reboot local machine
Arguments:
BaseName - name of executable
Machine - must be NULL (local machine only)
argc/argv - remaining parameters - ignored
Return Value:
EXIT_xxxx
--*/
{
if(Machine) {
//
// must be local machine
//
return EXIT_USAGE;
}
FormatToStream(stdout,MSG_REBOOT);
return Reboot() ? EXIT_OK : EXIT_FAIL;
}
int cmdUpdate(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in_ecount(argc) TCHAR* argv[])
/*++
Routine Description:
UPDATE
update driver for existing device(s)
Arguments:
BaseName - name of executable
Machine - machine name, must be NULL
argc/argv - remaining parameters
Return Value:
EXIT_xxxx
--*/
{
HMODULE newdevMod = NULL;
int failcode = EXIT_FAIL;
UpdateDriverForPlugAndPlayDevicesProto UpdateFn;
BOOL reboot = FALSE;
LPCTSTR hwid = NULL;
LPCTSTR inf = NULL;
DWORD flags = 0;
DWORD res;
TCHAR InfPath[MAX_PATH];
if(Machine) {
//
// must be local machine
//
return EXIT_USAGE;
}
if(argc<2) {
//
// at least HWID required
//
return EXIT_USAGE;
}
inf = argv[0];
if(!inf[0]) {
return EXIT_USAGE;
}
hwid = argv[1];
if(!hwid[0]) {
return EXIT_USAGE;
}
//
// Inf must be a full pathname
//
res = GetFullPathName(inf,MAX_PATH,InfPath,NULL);
if((res >= MAX_PATH) || (res == 0)) {
//
// inf pathname too long
//
return EXIT_FAIL;
}
if(GetFileAttributes(InfPath)==(DWORD)(-1)) {
//
// inf doesn't exist
//
return EXIT_FAIL;
}
inf = InfPath;
flags |= INSTALLFLAG_FORCE;
//
// make use of UpdateDriverForPlugAndPlayDevices
//
newdevMod = LoadLibrary(TEXT("newdev.dll"));
if(!newdevMod) {
goto final;
}
UpdateFn = (UpdateDriverForPlugAndPlayDevicesProto)GetProcAddress(newdevMod,UPDATEDRIVERFORPLUGANDPLAYDEVICES);
if(!UpdateFn)
{
goto final;
}
FormatToStream(stdout,inf ? MSG_UPDATE_INF : MSG_UPDATE,hwid,inf);
if(!UpdateFn(NULL,hwid,inf,flags,&reboot)) {
goto final;
}
FormatToStream(stdout,MSG_UPDATE_OK);
failcode = reboot ? EXIT_REBOOT : EXIT_OK;
final:
if(newdevMod) {
FreeLibrary(newdevMod);
}
return failcode;
}
int cmdInstall(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in_ecount(argc) TCHAR* argv[])
/*++
Routine Description:
CREATE
Creates a root enumerated devnode and installs drivers on it
Arguments:
BaseName - name of executable
Machine - machine name, must be NULL
argc/argv - remaining parameters
Return Value:
EXIT_xxxx
--*/
{
HDEVINFO DeviceInfoSet = INVALID_HANDLE_VALUE;
SP_DEVINFO_DATA DeviceInfoData;
GUID ClassGUID;
TCHAR ClassName[MAX_CLASS_NAME_LEN];
TCHAR hwIdList[LINE_LEN+4];
TCHAR InfPath[MAX_PATH];
DWORD err;
int failcode = EXIT_FAIL;
BOOL reboot = FALSE;
LPCTSTR hwid = NULL;
LPCTSTR inf = NULL;
DWORD flags = 0;
DWORD len;
if(Machine) {
//
// must be local machine
//
return EXIT_USAGE;
}
if(argc<2) {
//
// at least HWID required
//
return EXIT_USAGE;
}
inf = argv[0];
if(!inf[0]) {
return EXIT_USAGE;
}
hwid = argv[1];
if(!hwid[0]) {
return EXIT_USAGE;
}
//
// Inf must be a full pathname
//
if(GetFullPathName(inf,MAX_PATH,InfPath,NULL) >= MAX_PATH) {
//
// inf pathname too long
//
return EXIT_FAIL;
}
//
// List of hardware ID's must be double zero-terminated
//
ZeroMemory(hwIdList,sizeof(hwIdList));
if (FAILED(StringCchCopy(hwIdList,LINE_LEN,hwid))) {
goto final;
}
//
// Use the INF File to extract the Class GUID.
//
if (!SetupDiGetINFClass(InfPath,&ClassGUID,ClassName,sizeof(ClassName)/sizeof(ClassName[0]),0))
{
goto final;
}
//
// Create the container for the to-be-created Device Information Element.
//
DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0);
if(DeviceInfoSet == INVALID_HANDLE_VALUE)
{
goto final;
}
//
// Now create the element.
// Use the Class GUID and Name from the INF file.
//
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
if (!SetupDiCreateDeviceInfo(DeviceInfoSet,
ClassName,
&ClassGUID,
NULL,
0,
DICD_GENERATE_ID,
&DeviceInfoData))
{
goto final;
}
//
// Add the HardwareID to the Device's HardwareID property.
//
if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
&DeviceInfoData,
SPDRP_HARDWAREID,
(LPBYTE)hwIdList,
(lstrlen(hwIdList)+1+1)*sizeof(TCHAR)))
{
goto final;
}
//
// Transform the registry element into an actual devnode
// in the PnP HW tree.
//
if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
DeviceInfoSet,
&DeviceInfoData))
{
goto final;
}
FormatToStream(stdout,MSG_INSTALL_UPDATE);
//
// update the driver for the device we just created
//
failcode = cmdUpdate(BaseName,Machine,Flags,argc,argv);
final:
if (DeviceInfoSet != INVALID_HANDLE_VALUE) {
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
}
return failcode;
}
int cmdUpdateNI(__in LPCTSTR BaseName, __in LPCTSTR Machine, __in DWORD Flags, __in int argc, __in_ecount(argc) TCHAR* argv[])
/*++
Routine Description:
UPDATE (non interactive version)
update driver for existing device(s)
Arguments:
BaseName - name of executable
Machine - machine name, must be NULL
argc/argv - remaining parameters
Return Value:
EXIT_xxxx
--*/
{
//
// turn off interactive mode while doing the update
//
HMODULE setupapiMod = NULL;
SetupSetNonInteractiveModeProto SetNIFn;
int res;
BOOL prev;
setupapiMod = LoadLibrary(TEXT("setupapi.dll"));
if(!setupapiMod) {
return cmdUpdate(BaseName,Machine,Flags,argc,argv);
}
SetNIFn = (SetupSetNonInteractiveModeProto)GetProcAddress(setupapiMod,SETUPSETNONINTERACTIVEMODE);
if(!SetNIFn)
{
FreeLibrary(setupapiMod);
return cmdUpdate(BaseName,Machine,Flags,argc,argv);
}
prev = SetNIFn(TRUE);
res = cmdUpdate(BaseName,Machine,Flags,argc,argv);
SetNIFn(prev);
FreeLibrary(setupapiMod);
return res;
}
int RemoveCallback(__in HDEVINFO Devs, __in PSP_DEVINFO_DATA DevInfo, __in DWORD Index, __in LPVOID Context)
/*++
Routine Description:
Callback for use by Remove
Invokes DIF_REMOVE
uses SetupDiCallClassInstaller so cannot be done for remote devices
Don't use CM_xxx API's, they bypass class/co-installers and this is bad.
Arguments:
Devs )_ uniquely identify the device
DevInfo )
Index - index of device
Context - GenericContext
Return Value:
EXIT_xxxx
--*/
{
SP_REMOVEDEVICE_PARAMS rmdParams;
GenericContext *pControlContext = (GenericContext*)Context;
SP_DEVINSTALL_PARAMS devParams;
LPCTSTR action = NULL;
//
// need hardware ID before trying to remove, as we wont have it after
//
TCHAR devID[MAX_DEVICE_ID_LEN];
LPTSTR desc;
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)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -