📄 driversetuphelper.cpp
字号:
// DriverSetupHelper.cpp: implementation of the CDriverSetupHelper class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "DriverSetupHelper.h"
#ifndef DT
#define DT DebugTrace
extern BOOL DebugTrace(const char * lpszFormat,...);
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CDriverSetupHelper::CDriverSetupHelper()
{
}
CDriverSetupHelper::~CDriverSetupHelper()
{
}
//install a device by a inf file and a szHardwareID
//set bMultiInstance to TURE to permit multiple device instance.
BOOL CDriverSetupHelper::Install(IN CString szInfFile,IN CString szHardwareID,IN BOOL bMultiInstance OPTIONAL,OUT PBOOL pbRebootRequired OPTIONAL)
{
WIN32_FIND_DATA FindFileData;
BOOL RebootRequired = 0; // Must be cleared.
if (FindFirstFile(szInfFile,&FindFileData)==INVALID_HANDLE_VALUE)
{
DT("File not found:"+szInfFile);
return FALSE;
}
//
// Look to see if this device allready exists.
//
if (!bMultiInstance && FindExistingDevice(szHardwareID))
{
//
// No Need to Create a Device Node, just call our API.
//
if (!UpdateDriverForPlugAndPlayDevices(0, // No Window Handle
szHardwareID, // Hardware ID
szInfFile, // FileName
INSTALLFLAG_FORCE,
&RebootRequired))
{
DT(TEXT("UpdateDriverForPlugAndPlayDevices"));
return FALSE; // Install Failure
}
}
else
{
//
// Driver Does not exist, Create and call the API.
// HardwareID must be a multi-sz string, which szHardwareID is.
//
if (!InstallRootEnumeratedDriver(szInfFile,szHardwareID,
&RebootRequired))
{
return FALSE; // Install Failure
}
}
DT(TEXT("Driver Installed successfully.\n"));
if(pbRebootRequired)
*pbRebootRequired = RebootRequired;
if (RebootRequired)
{
DT(TEXT("(Reboot Required)\n"));
return TRUE; // Install Success, reboot required.
}
return TRUE; // Install Success, no reboot required.
}
//是否存在szHardwareID为szszHardwareID的设备
BOOL CDriverSetupHelper::FindExistingDevice(CString szHardwareID)
{
HDEVINFO DeviceInfoSet;
SP_DEVINFO_DATA DeviceInfoData;
DWORD i,err;
BOOL Found;
//
// Create a Device Information Set with all present devices.
//
DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes
0,
0,
DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system
if (DeviceInfoSet == INVALID_HANDLE_VALUE)
{
return DT(TEXT("GetClassDevs(All Present Devices)"));
}
DT(TEXT("Search for Device ID: [%s]\n"),szHardwareID);
//
// Enumerate through all Devices.
//
Found = FALSE;
DeviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
for (i=0;SetupDiEnumDeviceInfo(DeviceInfoSet,i,&DeviceInfoData);i++)
{
DWORD DataT;
LPTSTR p,buffer = NULL;
DWORD buffersize = 0;
//
// We won't know the size of the szHardwareID buffer until we call
// this function. So call it with a null to begin with, and then
// use the required buffer size to Alloc the nessicary space.
// Keep calling we have success or an unknown failure.
//
while (!SetupDiGetDeviceRegistryProperty(
DeviceInfoSet,
&DeviceInfoData,
SPDRP_HARDWAREID,
&DataT,
(PBYTE)buffer,
buffersize,
&buffersize))
{
if (GetLastError() == ERROR_INVALID_DATA)
{
//
// May be a Legacy Device with no szHardwareID. Continue.
//
break;
}
else if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
{
//
// We need to change the buffer size.
//
if (buffer)
LocalFree(buffer);
buffer = (char*)LocalAlloc(LPTR,buffersize);
}
else
{
//
// Unknown Failure.
//
DT(TEXT("GetDeviceRegistryProperty"));
goto cleanup_DeviceInfo;
}
}
if (GetLastError() == ERROR_INVALID_DATA)
continue;
//
// Compare each entry in the buffer multi-sz list with our szHardwareID.
//
for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen(p)+sizeof(TCHAR))
{
DT(TEXT("Compare device ID: [%s]\n"),p);
if (!_tcscmp(szHardwareID,p))
{
DT(TEXT("Found! [%s]\n"),p);
Found = TRUE;
break;
}
}
if (buffer) LocalFree(buffer);
if (Found) break;
}
if (GetLastError() != NO_ERROR)
{
DT(TEXT("EnumDeviceInfo"));
}
//
// Cleanup.
//
cleanup_DeviceInfo:
err = GetLastError();
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
SetLastError(err);
return err == NO_ERROR; //???
}
BOOL CDriverSetupHelper::InstallRootEnumeratedDriver(CString szInfFile, CString szHardwareID, PBOOL pbRebootRequired)
{
HDEVINFO DeviceInfoSet = 0;
SP_DEVINFO_DATA DeviceInfoData;
GUID ClassGUID;
TCHAR ClassName[MAX_CLASS_NAME_LEN];
DWORD err;
//
// Use the INF File to extract the Class GUID.
//
if (!SetupDiGetINFClass(szInfFile,&ClassGUID,ClassName,sizeof(ClassName),0))
{
return DT(TEXT("GetINFClass fail"));
}
//
// Create the container for the to-be-created Device Information Element.
//
DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0);
if(DeviceInfoSet == INVALID_HANDLE_VALUE)
{
return DT(TEXT("CreateDeviceInfoList"));
}
//
// 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))
{
DT(TEXT("CreateDeviceInfo"));
goto cleanup_DeviceInfo;
}
char szBufferHwID[2000];
memset(szBufferHwID,0,sizeof(szBufferHwID));
strcpy(szBufferHwID,szHardwareID);
//strcat(szBufferHwID,'\0');
//
// Add the HardwareID to the Device's HardwareID property.
//
if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,
&DeviceInfoData,
SPDRP_HARDWAREID,
(LPBYTE)szBufferHwID,
(lstrlen(szBufferHwID)+1+1)*sizeof(TCHAR)))
{
DT(TEXT("SetDeviceRegistryProperty"));
goto cleanup_DeviceInfo;
}
//
// Transform the registry element into an actual devnode
// in the PnP HW tree.
//
if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,
DeviceInfoSet,
&DeviceInfoData))
{
DT(TEXT("CallClassInstaller(REGISTERDEVICE)"));
goto cleanup_DeviceInfo;
}
//
// The element is now registered. We must explicitly remove the
// device using DIF_REMOVE, if we encounter any failure from now on.
//
//
// Install the Driver.
//
if (!UpdateDriverForPlugAndPlayDevices(0,
szHardwareID,
szInfFile,
INSTALLFLAG_FORCE,
pbRebootRequired))
{
DWORD err = GetLastError();
DT(TEXT("UpdateDriverForPlugAndPlayDevices"));
if (!SetupDiCallClassInstaller(
DIF_REMOVE,
DeviceInfoSet,
&DeviceInfoData))
{
DT(TEXT("CallClassInstaller(REMOVE)"));
}
SetLastError(err);
}
//
// Cleanup.
//
cleanup_DeviceInfo:
err = GetLastError();
SetupDiDestroyDeviceInfoList(DeviceInfoSet);
SetLastError(err);
return err == NO_ERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -