c++ 安裝usb驅動

#include <windows.h>
#include <fileapi.h>
#include <minwindef.h>
#include <stdio.h>
#include <cfgmgr32.h>
#pragma comment(lib,"Setupapi.lib")
#pragma comment(lib,"newdev.lib")

#include <tchar.h> // Make all functions UNICODE safe.
#include <newdev.h> // for the API UpdateDriverForPlugAndPlayDevices().
#include <SetupAPI.h> // for SetupDiXxx functions.


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 *)lpMessag	eBuffer);
	else
		NULL;  //_tprintf(TEXT("%s FAILURE: (0xx)/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 = ( LPTSTR )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.
	//
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.
	//
cleanup_DeviceInfo:
	err = GetLastError();
	SetupDiDestroyDeviceInfoList( DeviceInfoSet );
	SetLastError( err );
	return err == NO_ERROR;
}
int InstallDriver( char *InfName, char *HardwareID )
{

	WIN32_FIND_DATA FindFileData;
	BOOL RebootRequired = 0; // Must be cleared.
	char *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( (LPTSTR)HWID ) )
	{
		//
		// No Need to Create a Device Node, just call our API.
		//
		BOOL Nb = UpdateDriverForPlugAndPlayDevices( 0, // No Window Handle
			( LPTSTR )HWID, // Hardware ID
			FName, // FileName
			INSTALLFLAG_FORCE,
			&RebootRequired );
		if ( !Nb )
		{
			int nErr = GetLastError();
			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( ( LPTSTR )HWID, // HardwareID
			FName, // FileName
			&RebootRequired ) )
		{
			int n = GetLastError();
			//_tprintf(TEXT("(InstallRootEnumeratedDriver Failure! Code = 2)/n			"));
				return 2; // Install Failure
		}
	}
	//_tprintf(TEXT("Driver Installed successfully./n"));
	if ( RebootRequired )
	{
		//_tprintf(TEXT("(Reboot Required)/n"));
		return 1; // Install Success, reboot required.
	}
	return 0; // Install Success, no reboot required.
}
// int resDriver( _TCHAR *HardwareID, bool bEnable )
// {
// 	SP_PROPCHANGE_PARAMS param;
// 	param.ClassInstallHeader.cbSize = sizeof( SP_CLASSINSTALL_HEADER );
// 	param.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
// 
// 	if ( bEnable == TRUE )
// 	{
// 		param.StateChange = DICS_ENABLE;;
// 	}
// 	else
// 	{
// 		param.StateChange = DICS_DISABLE;
// 	}
// 	param.Scope = DICS_FLAG_CONFIGSPECIFIC;
// 	param.HwProfile = 0;
// 
// 	//do disable/enable action
// 	SetupDiSetClassInstallParams( hDevInfo, &objDevInfoData, ¶m.ClassInstallHeader, sizeof( param ) );
// 	SetupDiCallClassInstaller( DIF_PROPERTYCHANGE, hDevInfo, &objDevInfoData );
// }
BOOL ChangeStatus( DWORD NewStatus, DWORD SelectedItem, HDEVINFO hDevInfo )
{


	LPTSTR lpszMsg = NULL;
	HCURSOR hCursor = NULL;
	try
	{
		SP_PROPCHANGE_PARAMS PropChangeParams = { sizeof( SP_CLASSINSTALL_HEADER ) };
		SP_DEVINFO_DATA DeviceInfoData = { sizeof( SP_DEVINFO_DATA ) };
		hCursor = SetCursor( LoadCursor( NULL, IDC_WAIT ) );

		// Get a handle to the Selected Item.
		if ( !SetupDiEnumDeviceInfo( hDevInfo, SelectedItem, &DeviceInfoData ) )
		{
			throw lpszMsg;
		}

		// Set the PropChangeParams structure.
		PropChangeParams.ClassInstallHeader.InstallFunction = DIF_PROPERTYCHANGE;
		PropChangeParams.Scope = DICS_FLAG_GLOBAL;
		PropChangeParams.StateChange = NewStatus;

		if ( !SetupDiSetClassInstallParams( hDevInfo, &DeviceInfoData,
			( SP_CLASSINSTALL_HEADER * )&PropChangeParams, sizeof( PropChangeParams ) ) )
		{
			throw lpszMsg;
		}

		// Call the ClassInstaller and perform the change.
		if ( !SetupDiCallClassInstaller( DIF_PROPERTYCHANGE, hDevInfo, &DeviceInfoData ) )
		{
			DWORD la = GetLastError();
			throw lpszMsg;
		}

		SetCursor( hCursor );
		return TRUE;
	}
	catch ( TCHAR * pszError )
	{
		SetCursor( hCursor );
		::MessageBox( NULL, pszError, _T( "提示" ), MB_OK );
		if ( NULL != lpszMsg )
		{
			LocalFree( ( HLOCAL )lpszMsg );
		}
		return FALSE;
	}
}
int resstartDevice( _TCHAR *HardwareID )
{

	HDEVINFO DeviceInfoSet;
	HDEVINFO Hdeinfo;
	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 = ( LPTSTR )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.
				//
				BOOL nDis = ChangeStatus( DICS_DISABLE, i, DeviceInfoSet );
				BOOL nEn = ChangeStatus( DICS_ENABLE, i, DeviceInfoSet );
				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;
	
}
int RemoveDriver( _TCHAR *HardwareID )
{
	HDEVINFO DeviceInfoSet;
	HDEVINFO Hdeinfo;
	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 = ( LPTSTR)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;
}
void main( int argc, char* argv[] )
{
	char* infPath = "H:\\cz\\xlyp2p\\demo2Install\\PL2701.inf";
//	char* hardwareId = "USB\\VID_0EA0&PID_7301&MI_00";
	
	char* hardwareId = "USB\\VID_0EA0&PID_7301&MI_05";
	


	int nInt = -1;
	nInt = InstallDriver( infPath, hardwareId );
// 	nInt = resstartDevice( hardwareId );
// 	RemoveDriver( hardwareId );
// 

// 	cout << "nInt = " << nInt << endl;
// 	char* remove2 = "USB\\VID_0EA0&PID_7301&&MI_00";
// 	resstartDevice( remove2 );
//  	 RemoveDriver( remove2 );
// 	cout << "nInt = " << nInt << endl;
	getchar();
}

注:工程配置屬性爲x64, 另使用多字符字符集  

安裝後  如需獲取 

http://blog.csdn.net/d2262272d/article/details/72781743


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章