📄 devutils.cpp
字号:
/*
* $Id: devutils.cpp,v 1.4 2006/11/10 14:07:40 vfrolov Exp $
*
* Copyright (c) 2006 Vyacheslav Frolov
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*
* $Log: devutils.cpp,v $
* Revision 1.4 2006/11/10 14:07:40 vfrolov
* Implemented remove command
*
* Revision 1.3 2006/11/02 16:20:44 vfrolov
* Added usage the fixed port numbers
*
* Revision 1.2 2006/10/13 10:26:35 vfrolov
* Some defines moved to ../include/com0com.h
* Changed name of device object (for WMI)
*
* Revision 1.1 2006/07/28 12:16:42 vfrolov
* Initial revision
*
*/
#include "precomp.h"
#include "inffile.h"
#include "msg.h"
#include "devutils.h"
#include "utils.h"
///////////////////////////////////////////////////////////////
struct EnumParams {
EnumParams() {
pParam1 = NULL;
pParam2 = NULL;
count = 0;
pRebootRequired = NULL;
}
DevProperties devProperties;
void *pParam1;
void *pParam2;
int count;
BOOL *pRebootRequired;
};
typedef EnumParams *PEnumParams;
struct DevParams {
DevParams(PEnumParams _pEnumParams) {
pEnumParams = _pEnumParams;
}
PEnumParams pEnumParams;
DevProperties devProperties;
};
typedef DevParams *PDevParams;
///////////////////////////////////////////////////////////////
static int EnumDevices(
InfFile &infFile,
DWORD flags,
BOOL (* pFunk)(HDEVINFO, PSP_DEVINFO_DATA, PDevParams),
PEnumParams pEnumParams)
{
HDEVINFO hDevInfo;
hDevInfo = SetupDiGetClassDevs(NULL, NULL, NULL, DIGCF_ALLCLASSES|flags);
if (hDevInfo == INVALID_HANDLE_VALUE) {
ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiGetClassDevs()");
return IDCANCEL;
}
SP_DEVINFO_DATA devInfoData;
devInfoData.cbSize = sizeof(devInfoData);
int res = IDCONTINUE;
for (int i = 0 ; SetupDiEnumDeviceInfo(hDevInfo, i, &devInfoData) ; i++) {
char classGUID[100];
if (!SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_CLASSGUID, NULL, (PBYTE)classGUID, sizeof(classGUID), NULL))
continue;
if (lstrcmpi(classGUID, infFile.ClassGUID()))
continue;
char provider[100];
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_MFG, NULL, (PBYTE)provider, sizeof(provider), NULL)) {
// check provider if exists
if (lstrcmpi(provider, infFile.Provider()))
continue;
}
DevParams devParams(pEnumParams);
char hwid[40];
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_HARDWAREID, NULL, (PBYTE)hwid, sizeof(hwid), NULL))
devParams.devProperties.pDevId = hwid;
if (pEnumParams->devProperties.pDevId && (!devParams.devProperties.pDevId ||
lstrcmpi(devParams.devProperties.pDevId, pEnumParams->devProperties.pDevId)))
{
continue;
}
char location[40];
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_LOCATION_INFORMATION, NULL, (PBYTE)location, sizeof(location), NULL))
devParams.devProperties.pLocation = location;
if (pEnumParams->devProperties.pLocation && (!devParams.devProperties.pLocation ||
lstrcmpi(devParams.devProperties.pLocation, pEnumParams->devProperties.pLocation)))
{
continue;
}
char name[40];
if (SetupDiGetDeviceRegistryProperty(hDevInfo, &devInfoData, SPDRP_PHYSICAL_DEVICE_OBJECT_NAME, NULL, (PBYTE)name, sizeof(name), NULL))
devParams.devProperties.pPhObjName = name;
if (pEnumParams->devProperties.pPhObjName && (!devParams.devProperties.pPhObjName ||
lstrcmpi(devParams.devProperties.pPhObjName, pEnumParams->devProperties.pPhObjName)))
{
continue;
}
res = pFunk(hDevInfo, &devInfoData, &devParams);
if (res != IDCONTINUE)
break;
}
DWORD err = GetLastError();
SetupDiDestroyDeviceInfoList(hDevInfo);
SetLastError(err);
return res;
}
///////////////////////////////////////////////////////////////
static BOOL UpdateRebootRequired(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData, BOOL *pRebootRequired)
{
if (!pRebootRequired)
return TRUE;
if (*pRebootRequired)
return TRUE;
SP_DEVINSTALL_PARAMS installParams;
memset(&installParams, 0, sizeof(installParams));
installParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
if (!SetupDiGetDeviceInstallParams(hDevInfo, pDevInfoData, &installParams)) {
ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiGetDeviceInstallParams()");
return FALSE;
}
*pRebootRequired = (installParams.Flags & DI_NEEDREBOOT) ? TRUE : FALSE;
return TRUE;
}
///////////////////////////////////////////////////////////////
static BOOL ChangeState(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData, DWORD stateChange)
{
SP_PROPCHANGE_PARAMS propChangeParams;
memset(&propChangeParams, 0, sizeof(propChangeParams));
propChangeParams.ClassInstallHeader.cbSize = sizeof(SP_CLASSINSTALL_HEADER);
propChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
propChangeParams.StateChange = stateChange;
propChangeParams.Scope = DICS_FLAG_CONFIGSPECIFIC;
propChangeParams.HwProfile = 0;
if (!SetupDiSetClassInstallParams(hDevInfo, pDevInfoData, (SP_CLASSINSTALL_HEADER *)&propChangeParams, sizeof(propChangeParams))) {
ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiSetClassInstallParams()");
return FALSE;
}
if (!SetupDiCallClassInstaller(DIF_PROPERTYCHANGE, hDevInfo, pDevInfoData)) {
ShowLastError(MB_OK|MB_ICONSTOP, "SetupDiCallClassInstaller(DIF_PROPERTYCHANGE)");
return FALSE;
}
return TRUE;
}
///////////////////////////////////////////////////////////////
static int EnumDevice(HDEVINFO hDevInfo, PSP_DEVINFO_DATA pDevInfoData, PDevParams pDevParams)
{
/*
Trace("Enumerated %s %s %s\n",
pDevParams->devProperties.pLocation,
pDevParams->devProperties.pDevId,
pDevParams->devProperties.pPhObjName);
*/
int res = IDCONTINUE;
if (pDevParams->pEnumParams->pParam1) {
if (!PDEVCALLBACK(pDevParams->pEnumParams->pParam1)(hDevInfo,
pDevInfoData,
&pDevParams->devProperties,
pDevParams->pEnumParams->pRebootRequired,
pDevParams->pEnumParams->pParam2))
{
res = IDCANCEL;
}
}
pDevParams->pEnumParams->count++;
return res;
}
int EnumDevices(
InfFile &infFile,
PCDevProperties pDevProperties,
BOOL *pRebootRequired,
PDEVCALLBACK pDevCallBack,
void *pCallBackParam)
{
EnumParams enumParams;
if (pDevProperties)
enumParams.devProperties = *pDevProperties;
enumParams.pRebootRequired = pRebootRequired;
enumParams.pParam1 = pDevCallBack;
enumParams.pParam2 = pCallBackParam;
if (EnumDevices(infFile, DIGCF_PRESENT, EnumDevice, &enumParams) != IDCONTINUE)
return -1;
return enumParams.count;
}
///////////////////////////////////////////////////////////////
int DisableDevice(
HDEVINFO hDevInfo,
PSP_DEVINFO_DATA pDevInfoData,
PCDevProperties pDevProperties,
BOOL *pRebootRequired)
{
if (!ChangeState(hDevInfo, pDevInfoData, DICS_DISABLE))
return IDCANCEL;
Trace("Disabled %s %s %s\n",
pDevProperties->pLocation,
pDevProperties->pDevId,
pDevProperties->pPhObjName);
if (pRebootRequired && !*pRebootRequired) {
BOOL rebootRequired = FALSE;
if (!UpdateRebootRequired(hDevInfo, pDevInfoData, &rebootRequired))
return IDCANCEL;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -