#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