代码实现利用inf文件安装硬件驱动
生活随笔
收集整理的這篇文章主要介紹了
代码实现利用inf文件安装硬件驱动
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
代碼參考了網上資料并進行了整理:
#include "stdafx.h" #include <tchar.h> // Make all functions UNICODE safe. #include <newdev.h> // for the API UpdateDriverForPlugAndPlayDevices(). #include <setupapi.h> // for SetupDiXxx functions. #include "DirAndFile .h" #include <string>using namespace std;#pragma comment(lib, "setupapi.lib") #pragma comment(lib, "Newdev.lib")#define MAX_CLASS_NAME_LEN 1024int DisplayError(TCHAR * ErrorName) {DWORD Err = GetLastError();LPVOID lpMessageBuffer = NULL;if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL,Err,MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),(LPTSTR) &lpMessageBuffer,0,NULL ))NULL; //_tprintf(TEXT("%s FAILURE: %s/n"),ErrorName,(TCHAR *)lpMessageBuffer);elseNULL; //_tprintf(TEXT("%s FAILURE: (0x%08x)/n"),ErrorName,Err);if (lpMessageBuffer) LocalFree( lpMessageBuffer ); // Free system bufferSetLastError(Err);return FALSE; }BOOL FindExistingDevice(IN LPTSTR HardwareId) {HDEVINFO DeviceInfoSet;SP_DEVINFO_DATA DeviceInfoData;DWORD i,err;BOOL Found;// Create a Device Information Set with all present devices.DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes0,0,DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on systemif (DeviceInfoSet == INVALID_HANDLE_VALUE){return DisplayError(TEXT("GetClassDevs(All Present Devices)"));}//_tprintf(TEXT("Search for Device ID: [%s]/n"),HardwareId);// 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 HardwareID 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 HardwareID. 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.DisplayError(TEXT("GetDeviceRegistryProperty"));goto cleanup_DeviceInfo;}}if (GetLastError() == ERROR_INVALID_DATA)continue;// Compare each entry in the buffer multi-sz list with our HardwareID.for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen(p)+sizeof(TCHAR)){//_tprintf(TEXT("Compare device ID: [%s]/n"),p);if (!_tcscmp(HardwareId,p)){//_tprintf(TEXT("Found! [%s]/n"),p);Found = TRUE;break;}}if (buffer) LocalFree(buffer);if (Found) break;}if (GetLastError() != NO_ERROR){DisplayError(TEXT("EnumDeviceInfo"));}cleanup_DeviceInfo:err = GetLastError();SetupDiDestroyDeviceInfoList(DeviceInfoSet);SetLastError(err);return err == NO_ERROR; //??? }BOOL InstallRootEnumeratedDriver(IN LPTSTR HardwareId,IN LPTSTR INFFile,OUT PBOOL RebootRequired OPTIONAL) {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(INFFile,&ClassGUID,ClassName,sizeof(ClassName),0)){return DisplayError(TEXT("GetINFClass"));}// Create the container for the to-be-created Device Information Element.DeviceInfoSet = SetupDiCreateDeviceInfoList(&ClassGUID,0);if(DeviceInfoSet == INVALID_HANDLE_VALUE){return DisplayError(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)){DisplayError(TEXT("CreateDeviceInfo"));goto cleanup_DeviceInfo;}// Add the HardwareID to the Device's HardwareID property.if(!SetupDiSetDeviceRegistryProperty(DeviceInfoSet,&DeviceInfoData,SPDRP_HARDWAREID,(LPBYTE)HardwareId,(lstrlen(HardwareId)+1+1)*sizeof(TCHAR))){DisplayError(TEXT("SetDeviceRegistryProperty"));goto cleanup_DeviceInfo;}// Transform the registry element into an actual devnode// in the PnP HW tree.if (!SetupDiCallClassInstaller(DIF_REGISTERDEVICE,DeviceInfoSet,&DeviceInfoData)){DisplayError(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,HardwareId,INFFile,INSTALLFLAG_FORCE,RebootRequired)){DWORD err = GetLastError();DisplayError(TEXT("UpdateDriverForPlugAndPlayDevices"));if (!SetupDiCallClassInstaller(DIF_REMOVE,DeviceInfoSet,&DeviceInfoData)){DisplayError(TEXT("CallClassInstaller(REMOVE)"));}SetLastError(err);}cleanup_DeviceInfo:err = GetLastError();SetupDiDestroyDeviceInfoList(DeviceInfoSet);SetLastError(err);return err == NO_ERROR; }/************************************************************************** * 函數名:InstallDriver * 功 能:安裝驅動 * 參 數:_TCHAR *InfName,inf文件的文件路徑 * _TCHAR *HardwareID,硬件設備ID * 返回值:int ,0為成功 **************************************************************************/ int InstallDriver(_TCHAR *InfName, _TCHAR *HardwareID) {WIN32_FIND_DATA FindFileData;BOOL RebootRequired = 0; // Must be cleared._TCHAR *FName, *HWID;FName = InfName;HWID = HardwareID;if (FindFirstFile(FName,&FindFileData) == INVALID_HANDLE_VALUE){//_tprintf(TEXT(" File not found./n"));//_tprintf(TEXT("usage: install <INF_File> <Hardware_ID>/n"));return 2; // Install Failure}//// Look to see if this device allready exists.//if (FindExistingDevice(HWID)){//// No Need to Create a Device Node, just call our API.//if (!UpdateDriverForPlugAndPlayDevices(0, // No Window HandleHWID, // Hardware IDFName, // FileNameINSTALLFLAG_FORCE,&RebootRequired)){DisplayError(TEXT("UpdateDriverForPlugAndPlayDevices"));return 2; // Install Failure}}else{if (GetLastError()!= ERROR_NO_MORE_ITEMS){//// An unknown failure from FindExistingDevice()////_tprintf(TEXT("(IERROR_NO_MORE_ITEMS)/n"));//_tprintf(TEXT("(Install Failure! Code = 2)/n"));return 2; // Install Failure}//// Driver Does not exist, Create and call the API.// HardwareID must be a multi-sz string, which argv[2] is.//if (!InstallRootEnumeratedDriver(HWID, // HardwareIDFName, // FileName&RebootRequired)){//_tprintf(TEXT("(InstallRootEnumeratedDriver Failure! Code = 2)/n"));return 2; // Install Failure}}//_tprintf(TEXT("Driver Installed successfully./n"));if (RebootRequired){return 1; // Install Success, reboot required.}return 0; // Install Success, no reboot required. }/************************************************************************** * 函數名:RemoveDriver * 功 能:卸載驅動 * 參 數:_TCHAR *HardwareID,硬件設備ID * 返回值:int ,0為成功 **************************************************************************/ int RemoveDriver(_TCHAR *HardwareID) {HDEVINFO DeviceInfoSet;SP_DEVINFO_DATA DeviceInfoData;DWORD i,err;DeviceInfoSet = SetupDiGetClassDevs(NULL, // All Classes0,0,DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on systemif (DeviceInfoSet == INVALID_HANDLE_VALUE){DisplayError(TEXT("GetClassDevs(All Present Devices)"));return 1;}// Enumerate through all Devices.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 HardwareID 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 HardwareID. 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.DisplayError(TEXT("GetDeviceRegistryProperty"));goto cleanup_DeviceInfo;}}if (GetLastError() == ERROR_INVALID_DATA)continue;// Compare each entry in the buffer multi-sz list with our HardwareID.for (p=buffer;*p&&(p<&buffer[buffersize]);p+=lstrlen(p)+sizeof(TCHAR)){//_tprintf(TEXT("Compare device ID: [%s]/n"),p);if (!_tcscmp(HardwareID,p)){//_tprintf(TEXT("Found! [%s]/n"),p);// Worker function to remove device.if (!SetupDiCallClassInstaller(DIF_REMOVE,DeviceInfoSet,&DeviceInfoData)){DisplayError(TEXT("CallClassInstaller(REMOVE)"));}break;}}if (buffer) LocalFree(buffer);}if ((GetLastError()!=NO_ERROR)&&(GetLastError()!=ERROR_NO_MORE_ITEMS)){DisplayError(TEXT("EnumDeviceInfo"));}//// Cleanup.// cleanup_DeviceInfo:err = GetLastError();SetupDiDestroyDeviceInfoList(DeviceInfoSet);return err; } 調用方法:
//注意安裝64位驅動的時候需要編譯成64位應用程序才能安裝成功 int _tmain(int argc, _TCHAR* argv[]) {string infPath = "D:\\systest\\siusbxp.inf";string hardwareId = "USB\\VID_xxxx&PID_xxxx";InstallDriver((_TCHAR *)infPath.c_str(), (_TCHAR *)hardwareId.c_str());return 0; }
注意在安裝64位驅動的時候需要編譯成64位應用程序才能安裝成功。
總結
以上是生活随笔為你收集整理的代码实现利用inf文件安装硬件驱动的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用Pytorch来拟合函数
- 下一篇: 塞班S60v3版平台手机证书权限内容大解