📄 dump.cpp
字号:
UINT DumpDeviceDriversCallback(PVOID Context,UINT Notification,UINT_PTR Param1,UINT_PTR Param2)
/*++
Routine Description:
if Context provided, Simply count
otherwise dump files indented 2
Arguments:
Context - DWORD Count
Notification - SPFILENOTIFY_QUEUESCAN
Param1 - scan
Return Value:
none
--*/
{
LPDWORD count = (LPDWORD)Context;
LPTSTR file = (LPTSTR)Param1;
if(count) {
count[0]++;
} else {
Padding(2);
_tprintf(TEXT("%s\n"),file);
}
return NO_ERROR;
}
BOOL FindCurrentDriver(HDEVINFO Devs,PSP_DEVINFO_DATA DevInfo,PSP_DRVINFO_DATA DriverInfoData)
/*++
Routine Description:
Find the driver that is associated with the current device
We can do this either the quick way (available in WinXP)
or the long way that works in Win2k.
Arguments:
Devs )_ uniquely identify device
DevInfo )
Return Value:
TRUE if we managed to determine and select current driver
--*/
{
SP_DEVINSTALL_PARAMS deviceInstallParams;
WCHAR SectionName[LINE_LEN];
WCHAR DrvDescription[LINE_LEN];
WCHAR MfgName[LINE_LEN];
WCHAR ProviderName[LINE_LEN];
HKEY hKey = NULL;
DWORD RegDataLength;
DWORD RegDataType;
DWORD c;
BOOL match = FALSE;
long regerr;
ZeroMemory(&deviceInstallParams, sizeof(deviceInstallParams));
deviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
if(!SetupDiGetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams)) {
return FALSE;
}
#ifdef DI_FLAGSEX_INSTALLEDDRIVER
//
// Set the flags that tell SetupDiBuildDriverInfoList to just put the
// currently installed driver node in the list, and that it should allow
// excluded drivers. This flag introduced in WinXP.
//
deviceInstallParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
if(SetupDiSetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams)) {
//
// we were able to specify this flag, so proceed the easy way
// we should get a list of no more than 1 driver
//
if(!SetupDiBuildDriverInfoList(Devs, DevInfo, SPDIT_CLASSDRIVER)) {
return FALSE;
}
if (!SetupDiEnumDriverInfo(Devs, DevInfo, SPDIT_CLASSDRIVER,
0, DriverInfoData)) {
return FALSE;
}
//
// we've selected the current driver
//
return TRUE;
}
deviceInstallParams.FlagsEx &= ~(DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
#endif
//
// The following method works in Win2k, but it's slow and painful.
//
// First, get driver key - if it doesn't exist, no driver
//
hKey = SetupDiOpenDevRegKey(Devs,
DevInfo,
DICS_FLAG_GLOBAL,
0,
DIREG_DRV,
KEY_READ
);
if(hKey == INVALID_HANDLE_VALUE) {
//
// no such value exists, so there can't be an associated driver
//
RegCloseKey(hKey);
return FALSE;
}
//
// obtain path of INF - we'll do a search on this specific INF
//
RegDataLength = sizeof(deviceInstallParams.DriverPath); // bytes!!!
regerr = RegQueryValueEx(hKey,
REGSTR_VAL_INFPATH,
NULL,
&RegDataType,
(PBYTE)deviceInstallParams.DriverPath,
&RegDataLength
);
if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) {
//
// no such value exists, so no associated driver
//
RegCloseKey(hKey);
return FALSE;
}
//
// obtain name of Provider to fill into DriverInfoData
//
RegDataLength = sizeof(ProviderName); // bytes!!!
regerr = RegQueryValueEx(hKey,
REGSTR_VAL_PROVIDER_NAME,
NULL,
&RegDataType,
(PBYTE)ProviderName,
&RegDataLength
);
if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) {
//
// no such value exists, so we don't have a valid associated driver
//
RegCloseKey(hKey);
return FALSE;
}
//
// obtain name of section - for final verification
//
RegDataLength = sizeof(SectionName); // bytes!!!
regerr = RegQueryValueEx(hKey,
REGSTR_VAL_INFSECTION,
NULL,
&RegDataType,
(PBYTE)SectionName,
&RegDataLength
);
if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) {
//
// no such value exists, so we don't have a valid associated driver
//
RegCloseKey(hKey);
return FALSE;
}
//
// driver description (need not be same as device description)
// - for final verification
//
RegDataLength = sizeof(DrvDescription); // bytes!!!
regerr = RegQueryValueEx(hKey,
REGSTR_VAL_DRVDESC,
NULL,
&RegDataType,
(PBYTE)DrvDescription,
&RegDataLength
);
RegCloseKey(hKey);
if((regerr != ERROR_SUCCESS) || (RegDataType != REG_SZ)) {
//
// no such value exists, so we don't have a valid associated driver
//
return FALSE;
}
//
// Manufacturer (via SPDRP_MFG, don't access registry directly!)
//
if(!SetupDiGetDeviceRegistryProperty(Devs,
DevInfo,
SPDRP_MFG,
NULL, // datatype is guaranteed to always be REG_SZ.
(PBYTE)MfgName,
sizeof(MfgName), // bytes!!!
NULL)) {
//
// no such value exists, so we don't have a valid associated driver
//
return FALSE;
}
//
// now search for drivers listed in the INF
//
//
deviceInstallParams.Flags |= DI_ENUMSINGLEINF;
deviceInstallParams.FlagsEx |= DI_FLAGSEX_ALLOWEXCLUDEDDRVS;
if(!SetupDiSetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams)) {
return FALSE;
}
if(!SetupDiBuildDriverInfoList(Devs, DevInfo, SPDIT_CLASSDRIVER)) {
return FALSE;
}
//
// find the entry in the INF that was used to install the driver for
// this device
//
for(c=0;SetupDiEnumDriverInfo(Devs,DevInfo,SPDIT_CLASSDRIVER,c,DriverInfoData);c++) {
if((_tcscmp(DriverInfoData->MfgName,MfgName)==0)
&&(_tcscmp(DriverInfoData->ProviderName,ProviderName)==0)) {
//
// these two fields match, try more detailed info
// to ensure we have the exact driver entry used
//
SP_DRVINFO_DETAIL_DATA detail;
detail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
if(!SetupDiGetDriverInfoDetail(Devs,DevInfo,DriverInfoData,&detail,sizeof(detail),NULL)
&& (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) {
continue;
}
if((_tcscmp(detail.SectionName,SectionName)==0) &&
(_tcscmp(detail.DrvDescription,DrvDescription)==0)) {
match = TRUE;
break;
}
}
}
if(!match) {
SetupDiDestroyDriverInfoList(Devs,DevInfo,SPDIT_CLASSDRIVER);
}
return match;
}
BOOL DumpDeviceDriverFiles(HDEVINFO Devs,PSP_DEVINFO_DATA DevInfo)
/*++
Routine Description:
Dump information about what files were installed for driver package
<tab>Installed using OEM123.INF section [abc.NT]
<tab><tab>file...
Arguments:
Devs )_ uniquely identify device
DevInfo )
Return Value:
none
--*/
{
//
// do this by 'searching' for the current driver
// mimmicing a copy-only install to our own file queue
// and then parsing that file queue
//
SP_DEVINSTALL_PARAMS deviceInstallParams;
SP_DRVINFO_DATA driverInfoData;
SP_DRVINFO_DETAIL_DATA driverInfoDetail;
HSPFILEQ queueHandle = INVALID_HANDLE_VALUE;
DWORD count;
DWORD scanResult;
BOOL success = FALSE;
ZeroMemory(&driverInfoData,sizeof(driverInfoData));
driverInfoData.cbSize = sizeof(driverInfoData);
if(!FindCurrentDriver(Devs,DevInfo,&driverInfoData)) {
Padding(1);
FormatToStream(stdout, MSG_DUMP_NO_DRIVER);
return FALSE;
}
//
// get useful driver information
//
driverInfoDetail.cbSize = sizeof(SP_DRVINFO_DETAIL_DATA);
if(!SetupDiGetDriverInfoDetail(Devs,DevInfo,&driverInfoData,&driverInfoDetail,sizeof(SP_DRVINFO_DETAIL_DATA),NULL) &&
GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
//
// no information about driver or section
//
goto final;
}
if(!driverInfoDetail.InfFileName[0] || !driverInfoDetail.SectionName[0]) {
goto final;
}
//
// pretend to do the file-copy part of a driver install
// to determine what files are used
// the specified driver must be selected as the active driver
//
if(!SetupDiSetSelectedDriver(Devs, DevInfo, &driverInfoData)) {
goto final;
}
//
// create a file queue so we can look at this queue later
//
queueHandle = SetupOpenFileQueue();
if ( queueHandle == (HSPFILEQ)INVALID_HANDLE_VALUE ) {
goto final;
}
//
// modify flags to indicate we're providing our own queue
//
ZeroMemory(&deviceInstallParams, sizeof(deviceInstallParams));
deviceInstallParams.cbSize = sizeof(SP_DEVINSTALL_PARAMS);
if ( !SetupDiGetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams) ) {
goto final;
}
//
// we want to add the files to the file queue, not install them!
//
deviceInstallParams.FileQueue = queueHandle;
deviceInstallParams.Flags |= DI_NOVCP;
if ( !SetupDiSetDeviceInstallParams(Devs, DevInfo, &deviceInstallParams) ) {
goto final;
}
//
// now fill queue with files that are to be installed
// this involves all class/co-installers
//
if ( !SetupDiCallClassInstaller(DIF_INSTALLDEVICEFILES, Devs, DevInfo) ) {
goto final;
}
//
// we now have a list of delete/rename/copy files
// iterate the copy queue twice - 1st time to get # of files
// 2nd time to get files
// (WinXP has API to get # of files, but we want this to work
// on Win2k too)
//
count = 0;
scanResult = 0;
//
// call once to count
//
SetupScanFileQueue(queueHandle,SPQ_SCAN_USE_CALLBACK,NULL,DumpDeviceDriversCallback,&count,&scanResult);
Padding(1);
FormatToStream(stdout, count ? MSG_DUMP_DRIVER_FILES : MSG_DUMP_NO_DRIVER_FILES, count, driverInfoDetail.InfFileName, driverInfoDetail.SectionName);
//
// call again to dump the files
//
SetupScanFileQueue(queueHandle,SPQ_SCAN_USE_CALLBACK,NULL,DumpDeviceDriversCallback,NULL,&scanResult);
success = TRUE;
final:
SetupDiDestroyDriverInfoList(Devs,DevInfo,SPDIT_CLASSDRIVER);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -