我是靠谱客的博主 粗心鞋垫,最近开发中收集的这篇文章主要介绍代码实现利用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 1024

int 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);
	else
		NULL;  //_tprintf(TEXT("%s FAILURE: (0x%08x)/n"),ErrorName,Err);

	if (lpMessageBuffer) LocalFree( lpMessageBuffer ); // Free system buffer

	SetLastError(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 Classes
		0,
		0,
		DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system

	if (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 Handle
			HWID, // Hardware ID
			FName, // FileName
			INSTALLFLAG_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, // HardwareID
			FName, // 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 Classes
		0,
		0,
		DIGCF_ALLCLASSES | DIGCF_PRESENT ); // All devices present on system

	if (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文件安装硬件驱动的全部内容,希望文章能够帮你解决代码实现利用inf文件安装硬件驱动所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(52)

评论列表共有 0 条评论

立即
投稿
返回
顶部