[Post] source code for automatically installing and uninstalling the driver

Source: Internet
Author: User

[Post] source code for automatically installing and uninstalling the driver

# 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 "Install. H"
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: (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.
//
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
// 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 (_ 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> 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)
{
// _ Tprintf (text ("(reboot required) \ n "));
Return 1; // install success, reboot required.
}
Return 0; // install success, no reboot required.
}
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;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.