|
|
/*++
Copyright (C) 1997-1999 Microsoft Corporation
Module Name:
CDriver.cpp
Abstract:
This module implements CDriver and CService classes
Author:
William Hsieh (williamh) created
Revision History:
--*/
#include "devmgr.h"
#include "cdriver.h"
const TCHAR* tszStringFileInfo = TEXT("StringFileInfo\\%04X%04X\\"); const TCHAR* tszFileVersion = TEXT("FileVersion"); const TCHAR* tszLegalCopyright = TEXT("LegalCopyright"); const TCHAR* tszCompanyName = TEXT("CompanyName"); const TCHAR* tszTranslation = TEXT("VarFileInfo\\Translation"); const TCHAR* tszStringFileInfoDefault = TEXT("StringFileInfo\\040904B0\\");
BOOL CDriver::Create( CDevice* pDevice, PSP_DRVINFO_DATA pDrvInfoData ) { HKEY hKey; TCHAR InfPath[MAX_PATH]; TCHAR InfName[MAX_PATH];
ASSERT(pDevice);
m_pDevice = pDevice; m_OnLocalMachine = pDevice->m_pMachine->IsLocal();
CMachine* pMachine = m_pDevice->m_pMachine;
ASSERT(pMachine);
//
// We can't get the digital signer on remote machines
//
if (!m_OnLocalMachine) { return TRUE; }
m_hSDBDrvMain = SdbInitDatabase(SDB_DATABASE_MAIN_DRIVERS, NULL);
//
// Open drvice's driver registry key to get the InfPath
//
hKey = pMachine->DiOpenDevRegKey(*m_pDevice, DICS_FLAG_GLOBAL, 0, DIREG_DRV, KEY_READ);
if (INVALID_HANDLE_VALUE != hKey) {
DWORD regType; DWORD Len = sizeof(InfName); CSafeRegistry regDrv(hKey);
//
// Get the inf path from the driver key
//
if (regDrv.GetValue(REGSTR_VAL_INFPATH, ®Type, (PBYTE)InfName, &Len)) {
if (GetSystemWindowsDirectory(InfPath, ARRAYLEN(InfPath))) {
if (lstrlen(InfPath)) { //
// Tack on an extra back slash if one is needed
//
if (_T('\\') != InfPath[lstrlen(InfPath) - 1]) { lstrcat(InfPath, TEXT("\\")); }
lstrcat(InfPath, TEXT("INF\\")); lstrcat(InfPath, InfName);
pMachine->GetDigitalSigner(InfPath, m_DigitalSigner); } } } }
return TRUE; }
BOOL CDriver::BuildDriverList( PSP_DRVINFO_DATA pDrvInfoData, BOOL bFunctionAndFiltersOnly ) { SP_DRVINFO_DATA DrvInfoData; HSPFILEQ hFileQueue = INVALID_HANDLE_VALUE; SP_DEVINSTALL_PARAMS DevInstParams;
//
// If we already built up the list of driver files then we don't need
// to do it again.
//
if (m_DriverListBuilt) { return m_listDriverFile.GetCount(); }
ASSERT(m_pDevice);
if (!m_OnLocalMachine) { AddFunctionAndFilterDrivers(m_pDevice); return m_listDriverFile.GetCount(); }
CMachine* pMachine = m_pDevice->m_pMachine; ASSERT(pMachine);
hFileQueue = SetupOpenFileQueue();
//
// Only build up the list of files from the INF if bFunctionAndFiltersOnly
// is not TRUE.
//
if (!bFunctionAndFiltersOnly) { DevInstParams.cbSize = sizeof(DevInstParams);
if (!pDrvInfoData) {
pMachine->DiGetDeviceInstallParams(*m_pDevice, &DevInstParams);
//
// Set the DI_FLAGSEX_INSTALLEDDRIVER flag before calling SetupDiBuildDriverInfoList.
// This will have it only put the installed driver into the list.
//
DevInstParams.FlagsEx |= (DI_FLAGSEX_INSTALLEDDRIVER | DI_FLAGSEX_ALLOWEXCLUDEDDRVS);
if (pMachine->DiSetDeviceInstallParams(*m_pDevice, &DevInstParams) && pMachine->DiBuildDriverInfoList(*m_pDevice, SPDIT_CLASSDRIVER)) {
DrvInfoData.cbSize = sizeof(DrvInfoData);
//
// There should only be one driver in this list. If there isn't any
// drivers in this list then there must not be a driver currently
// installed on this device.
//
if (pMachine->DiEnumDriverInfo(*m_pDevice, SPDIT_CLASSDRIVER, 0, &DrvInfoData)) {
//
// Set this as the selected driver
//
pMachine->DiSetSelectedDriver(*m_pDevice, &DrvInfoData);
pDrvInfoData = &DrvInfoData;
} else {
//
// We did not find a match...so just destroy it.
//
pMachine->DiDestroyDriverInfoList(*m_pDevice, SPDIT_CLASSDRIVER);
pDrvInfoData = NULL; } } }
if (pDrvInfoData) {
//
// Get a list of all the files installed for this device
//
if (INVALID_HANDLE_VALUE != hFileQueue) {
DevInstParams.FileQueue = hFileQueue; DevInstParams.Flags |= DI_NOVCP;
if (pMachine->DiSetDeviceInstallParams(*m_pDevice, &DevInstParams) && pMachine->DiCallClassInstaller(DIF_INSTALLDEVICEFILES, *m_pDevice)) { //
// Dereference the file queue so that we can close it
//
DevInstParams.FileQueue = NULL; DevInstParams.Flags &= ~DI_NOVCP; pMachine->DiSetDeviceInstallParams(*m_pDevice, &DevInstParams); } }
if (pDrvInfoData == &DrvInfoData) { pMachine->DiDestroyDriverInfoList(*m_pDevice, SPDIT_CLASSDRIVER); } } }
//
// Add the funtion and device and class upper and lower filters, sometimes
// these aren't added via the INF file directly so this makes sure they
// show up in the list.
//
AddFunctionAndFilterDrivers(m_pDevice, hFileQueue);
if (hFileQueue != INVALID_HANDLE_VALUE) { //
// Scan the file queue.
//
DWORD ScanResult; SetupScanFileQueue(hFileQueue, SPQ_SCAN_USE_CALLBACK_SIGNERINFO, NULL, ScanQueueCallback, (PVOID)this, &ScanResult );
//
// Close the file queue
//
SetupCloseFileQueue(hFileQueue); }
m_DriverListBuilt = TRUE;
return m_listDriverFile.GetCount(); }
void CDriver::AddDriverFile( CDriverFile* pNewDrvFile ) { //
// Check to see if this driver already exists in the list.
//
POSITION pos = m_listDriverFile.GetHeadPosition();
while (NULL != pos) { CDriverFile* pDrvFile = m_listDriverFile.GetNext(pos);
if (lstrcmpi(pDrvFile->GetFullPathName(), pNewDrvFile->GetFullPathName()) == 0) { //
// This file already exists in the list so just return without
// adding it.
//
return; } }
m_listDriverFile.AddTail(pNewDrvFile); }
void CDriver::AddFunctionAndFilterDrivers( CDevice* pDevice, HSPFILEQ hFileQueue ) { TCHAR ServiceName[MAX_PATH]; ULONG BufferLen; HKEY hKey; DWORD regType;
//
// Get the function driver
//
if (pDevice->m_pMachine->DiGetDeviceRegistryProperty(*pDevice, SPDRP_SERVICE, NULL, (PBYTE)ServiceName, sizeof(ServiceName), NULL )) { CreateFromService(pDevice, ServiceName, hFileQueue); }
//
// Add the upper and lower device filters
//
for (int i = 0; i<2; i++) { BufferLen = 0; pDevice->m_pMachine->DiGetDeviceRegistryProperty( *pDevice, i ? SPDRP_LOWERFILTERS : SPDRP_UPPERFILTERS, NULL, NULL, BufferLen, &BufferLen );
if (BufferLen != 0) { PTSTR Buffer = new TCHAR[BufferLen+2];
if (Buffer) { ZeroMemory(Buffer, BufferLen+2);
if (pDevice->m_pMachine->DiGetDeviceRegistryProperty( *pDevice, i ? SPDRP_LOWERFILTERS : SPDRP_UPPERFILTERS, NULL, (PBYTE)Buffer, BufferLen, &BufferLen )) { for (PTSTR SingleItem = Buffer; *SingleItem; SingleItem += (lstrlen(SingleItem) + 1)) { CreateFromService(pDevice, SingleItem, hFileQueue); } }
delete Buffer; } } }
//
// Add the upper and lower class filters
//
GUID ClassGuid; pDevice->ClassGuid(ClassGuid); hKey = m_pDevice->m_pMachine->DiOpenClassRegKey(&ClassGuid, KEY_READ, DIOCR_INSTALLER);
if (INVALID_HANDLE_VALUE != hKey) {
CSafeRegistry regClass(hKey);
for (int i = 0; i<2; i++) { BufferLen = 0; regClass.GetValue(i ? REGSTR_VAL_LOWERFILTERS : REGSTR_VAL_UPPERFILTERS, ®Type, NULL, &BufferLen ); if (BufferLen != 0) { PTSTR Buffer = new TCHAR[BufferLen+2];
if (Buffer) { ZeroMemory(Buffer, BufferLen+2);
if (regClass.GetValue(i ? REGSTR_VAL_LOWERFILTERS : REGSTR_VAL_UPPERFILTERS, ®Type, (PBYTE)Buffer, &BufferLen )) { for (PTSTR SingleItem = Buffer; *SingleItem; SingleItem += (lstrlen(SingleItem) + 1)) { CreateFromService(pDevice, SingleItem, hFileQueue); } }
delete Buffer; } } } }
}
void CDriver::CreateFromService( CDevice* pDevice, PCTSTR ServiceName, HSPFILEQ hFileQueue ) { SC_HANDLE hscManager = NULL; SC_HANDLE hscService = NULL;
if (!ServiceName) { return; }
try { BOOL ComposePathNameFromServiceName = TRUE;
// open default database on local machine for now
hscManager = OpenSCManager(m_OnLocalMachine ? NULL : pDevice->m_pMachine->GetMachineFullName(), NULL, GENERIC_READ);
if (NULL != hscManager) { hscService = OpenService(hscManager, ServiceName, GENERIC_READ); if (NULL != hscService) { QUERY_SERVICE_CONFIG qsc; DWORD BytesRequired;
// first, probe for buffer size
if (!QueryServiceConfig(hscService, NULL, 0, &BytesRequired) && ERROR_INSUFFICIENT_BUFFER == GetLastError()) { TCHAR FullPath[MAX_PATH]; BufferPtr<BYTE> BufPtr(BytesRequired); LPQUERY_SERVICE_CONFIG pqsc; pqsc = (LPQUERY_SERVICE_CONFIG)(PBYTE)BufPtr; DWORD Size;
if (QueryServiceConfig(hscService, pqsc, BytesRequired, &Size) && pqsc->lpBinaryPathName && (TEXT('\0') != pqsc->lpBinaryPathName[0])) { ComposePathNameFromServiceName = FALSE;
//
// Make sure we have a valid full path.
//
if (GetFullPathFromImagePath(pqsc->lpBinaryPathName, FullPath, ARRAYLEN(FullPath))) {
if (hFileQueue != INVALID_HANDLE_VALUE) { //
// Add the file to the queue.
//
TCHAR TargetPath[MAX_PATH]; lstrcpy(TargetPath, FullPath); PTSTR p = (PTSTR)StrRChr(TargetPath, NULL, TEXT('\\')); if (p) { *p = TEXT('\0'); }
SetupQueueCopy(hFileQueue, NULL, NULL, MyGetFileTitle(FullPath), NULL, NULL, TargetPath, NULL, 0 ); } else { //
// No file queue was passed in so just manually
// add this to our list of driver files.
//
SafePtr<CDriverFile> DrvFilePtr; CDriverFile* pDrvFile = new CDriverFile(); DrvFilePtr.Attach(pDrvFile);
//
// We will set the GetWin32Error to 0xFFFFFFFF which will
// cause the UI to say 'not available' for the
// signature.
//
if (pDrvFile->Create(FullPath, m_OnLocalMachine, 0xFFFFFFFF, NULL, m_hSDBDrvMain)) { AddDriverFile(pDrvFile); DrvFilePtr.Detach(); } } } } }
CloseServiceHandle(hscService); hscService = NULL; }
CloseServiceHandle(hscManager); hscManager = NULL; }
if (ComposePathNameFromServiceName) { TCHAR FullPathName[MAX_PATH]; TCHAR SysDir[MAX_PATH]; if ((GetSystemDirectory(SysDir, ARRAYLEN(SysDir)) != 0) && SUCCEEDED(StringCchCopy(FullPathName, ARRAYLEN(FullPathName), SysDir)) && SUCCEEDED(StringCchCat(FullPathName, ARRAYLEN(FullPathName), TEXT("\\drivers\\"))) && SUCCEEDED(StringCchCat(FullPathName, ARRAYLEN(FullPathName), ServiceName)) && SUCCEEDED(StringCchCat(FullPathName, ARRAYLEN(FullPathName), TEXT(".sys")))) { if (hFileQueue != INVALID_HANDLE_VALUE) { //
// Add the file to the queue.
//
TCHAR TargetPath[MAX_PATH]; lstrcpy(TargetPath, FullPathName); PTSTR p = (PTSTR)StrRChr(TargetPath, NULL, TEXT('\\')); if (p) { *p = TEXT('\0'); } SetupQueueCopy(hFileQueue, NULL, NULL, MyGetFileTitle(FullPathName), NULL, NULL, TargetPath, NULL, 0 ); } else { //
// No file queue was passed in so just manually
// add this to our list of driver files.
//
SafePtr<CDriverFile> DrvFilePtr; CDriverFile* pDrvFile = new CDriverFile(); DrvFilePtr.Attach(pDrvFile); //
// We will set the GetWin32Error to 0xFFFFFFFF which will
// cause the UI to say 'not available' for the
// signature.
//
if (pDrvFile->Create(FullPathName, m_OnLocalMachine, 0xFFFFFFFF, NULL, m_hSDBDrvMain)) { AddDriverFile(pDrvFile); DrvFilePtr.Detach(); } } } } }
catch (CMemoryException* e) { if (hscService) { CloseServiceHandle(hscService); }
if (hscManager) { CloseServiceHandle(hscManager); } throw; } }
CDriver::~CDriver() { if (!m_listDriverFile.IsEmpty()) { POSITION pos = m_listDriverFile.GetHeadPosition();
while (NULL != pos) { CDriverFile* pDrvFile = m_listDriverFile.GetNext(pos); delete pDrvFile; }
m_listDriverFile.RemoveAll(); }
if (m_hSDBDrvMain) { SdbReleaseDatabase(m_hSDBDrvMain); } }
BOOL CDriver::operator ==( CDriver& OtherDriver ) { CDriverFile* pThisDrvFile; CDriverFile* pOtherDrvFile; BOOL DrvFileFound = FALSE; PVOID ThisContext, OtherContext; if (GetFirstDriverFile(&pThisDrvFile, ThisContext)) { do {
DrvFileFound = FALSE;
if (OtherDriver.GetFirstDriverFile(&pOtherDrvFile, OtherContext)) { do { if (*pThisDrvFile == *pOtherDrvFile) { DrvFileFound = TRUE; break; }
} while (OtherDriver.GetNextDriverFile(&pOtherDrvFile, OtherContext)); }
} while (DrvFileFound && GetNextDriverFile(&pThisDrvFile, ThisContext));
return DrvFileFound; }
else { // if both do not have driver file, they are equal.
return !OtherDriver.GetFirstDriverFile(&pOtherDrvFile, OtherContext); } }
//
// Can not throw a exception from this function because it is a callback
//
UINT CDriver::ScanQueueCallback( PVOID Context, UINT Notification, UINT_PTR Param1, UINT_PTR Param2 ) { try { if (SPFILENOTIFY_QUEUESCAN_SIGNERINFO == Notification && Param1) { CDriver* pDriver = (CDriver*)Context;
if (pDriver) { SafePtr<CDriverFile> DrvFilePtr; CDriverFile* pDrvFile = new CDriverFile(); DrvFilePtr.Attach(pDrvFile);
//
// When creating the CDriver set the Win32Error to 0xFFFFFFFF
// if the user is loged in as a guest. This is because we
// cannot tell if a file is digitally signed if the user is
// a guest. If the user is not a guest then use the Win32Error
// returned from setupapi.
//
if (pDrvFile->Create((LPCTSTR)((PFILEPATHS_SIGNERINFO)Param1)->Target, pDriver->IsLocal(), pDriver->m_pDevice->m_pMachine->IsUserAGuest() ? 0xFFFFFFFF : ((PFILEPATHS_SIGNERINFO)Param1)->Win32Error, ((PFILEPATHS_SIGNERINFO)Param1)->DigitalSigner, pDriver->m_hSDBDrvMain )) { pDriver->AddDriverFile(pDrvFile); DrvFilePtr.Detach(); } } } }
catch (CMemoryException* e) { e->Delete(); return ERROR_NOT_ENOUGH_MEMORY; }
return NO_ERROR; }
BOOL CDriver::GetFirstDriverFile( CDriverFile** ppDrvFile, PVOID& Context ) { ASSERT(ppDrvFile);
if (!m_listDriverFile.IsEmpty()) { POSITION pos = m_listDriverFile.GetHeadPosition(); *ppDrvFile = m_listDriverFile.GetNext(pos); Context = pos; return TRUE; }
Context = NULL; *ppDrvFile = NULL;
return FALSE; }
BOOL CDriver::GetNextDriverFile( CDriverFile** ppDrvFile, PVOID& Context ) { ASSERT(ppDrvFile);
POSITION pos = (POSITION)Context;
if (NULL != pos) { *ppDrvFile = m_listDriverFile.GetNext(pos); Context = pos; return TRUE; }
*ppDrvFile = NULL; return FALSE; }
void CDriver::GetDriverSignerString( String& strDriverSigner ) { if (m_DigitalSigner.IsEmpty()) {
strDriverSigner.LoadString(g_hInstance, IDS_NO_DIGITALSIGNATURE);
} else {
strDriverSigner = m_DigitalSigner; } }
BOOL CDriver::GetFullPathFromImagePath( LPCTSTR ImagePath, LPTSTR FullPath, UINT FullPathLength ) { TCHAR OriginalCurrentDirectory[MAX_PATH]; LPTSTR pRelativeString; LPTSTR lpFilePart;
if (!ImagePath || (ImagePath[0] == TEXT('\0'))) { return FALSE; }
//
// If we aren't on a local machine then just return the file name and not
// the full path.
//
if (!m_OnLocalMachine) { lstrcpyn(FullPath, MyGetFileTitle(ImagePath), FullPathLength); return TRUE; }
//
// First check if the ImagePath happens to be a valid full path.
//
if (GetFileAttributes(ImagePath) != 0xFFFFFFFF) { ::GetFullPathName(ImagePath, FullPathLength, FullPath, &lpFilePart); return TRUE; }
pRelativeString = (LPTSTR)ImagePath;
//
// If the ImagePath starts with "\SystemRoot" or "%SystemRoot%" then
// remove those values.
//
if (StrCmpNI(ImagePath, TEXT("\\SystemRoot\\"), lstrlen(TEXT("\\SystemRoot\\"))) == 0) { pRelativeString += lstrlen(TEXT("\\SystemRoot\\")); } else if (StrCmpNI(ImagePath, TEXT("%SystemRoot%\\"), lstrlen(TEXT("%SystemRoot%\\"))) == 0) { pRelativeString += lstrlen(TEXT("%SystemRoot%\\")); }
//
// At this point pRelativeString should point to the image path relative to
// the windows directory.
//
if (!GetSystemWindowsDirectory(FullPath, FullPathLength)) { return FALSE; }
if (!GetCurrentDirectory(ARRAYLEN(OriginalCurrentDirectory), OriginalCurrentDirectory)) { OriginalCurrentDirectory[0] = TEXT('\0'); }
if (!SetCurrentDirectory(FullPath)) { return FALSE; }
::GetFullPathName(pRelativeString, FullPathLength, FullPath, &lpFilePart);
if (OriginalCurrentDirectory[0] != TEXT('\0')) { SetCurrentDirectory(OriginalCurrentDirectory); }
return TRUE; }
BOOL CDriverFile::Create( LPCTSTR ServiceName, BOOL LocalMachine, DWORD Win32Error, LPCTSTR DigitalSigner, HSDB hSDBDrvMain ) { if (!ServiceName || (TEXT('\0') == ServiceName[0])) { return FALSE; }
m_Win32Error = Win32Error;
if (DigitalSigner) { m_strDigitalSigner = DigitalSigner; }
//
// For remote machine, we can not verify if the driver file exits.
// we only show the driver name.
//
if (LocalMachine) { m_Attributes = GetFileAttributes(ServiceName);
if (0xFFFFFFFF != m_Attributes) { m_strFullPathName = ServiceName;
} else { //
// The driver is a service. Do not search for the current director --
// GetFullPathName is useless here.
// Search for Windows dir and System directory
//
TCHAR BaseDir[MAX_PATH];
BaseDir[0] = TEXT('\0');
if (GetSystemWindowsDirectory(BaseDir, ARRAYLEN(BaseDir))) {
int Len;
Len = lstrlen(BaseDir);
if (Len) { if (_T('\\') != BaseDir[Len - 1]) { lstrcat(BaseDir, TEXT("\\")); }
lstrcat(BaseDir, MyGetFileTitle(ServiceName)); m_Attributes = GetFileAttributes(BaseDir); }
if (0xFFFFFFFF == m_Attributes) { if (GetSystemDirectory(BaseDir, ARRAYLEN(BaseDir))) {
Len = lstrlen(BaseDir);
if (Len) { if (_T('\\') != BaseDir[Len - 1]) { lstrcat(BaseDir, TEXT("\\")); }
lstrcat(BaseDir, MyGetFileTitle(ServiceName)); m_Attributes = GetFileAttributes(BaseDir); } } }
//
// hopeless, we could find the path
//
if (0xFFFFFFFF == m_Attributes) { return FALSE; }
m_strFullPathName = BaseDir;
} else {
return FALSE; } }
m_HasVersionInfo = GetVersionInfo(); }
else { m_strFullPathName = ServiceName;
//
//we do not have version info
//
m_HasVersionInfo = FALSE; }
if (!m_strFullPathName.IsEmpty() && hSDBDrvMain != NULL) { TAGREF tagref = TAGREF_NULL; HAPPHELPINFOCONTEXT hAppHelpInfoContext = NULL; SDBENTRYINFO entryinfo; DWORD cbSize;
tagref = SdbGetDatabaseMatch(hSDBDrvMain, (LPTSTR)m_strFullPathName, INVALID_HANDLE_VALUE, NULL, 0 );
if (tagref != TAGREF_NULL) { //
// This driver is in the database.
//
m_IsDriverBlocked = TRUE;
//
// Call SdbReadDriverInformation to get the database GUID and the
// driver GUID for this entry.
//
ZeroMemory(&entryinfo, sizeof(entryinfo)); if (SdbReadDriverInformation(hSDBDrvMain, tagref, &entryinfo)) { //
// Open up the App help information database and query for the
// html link.
//
hAppHelpInfoContext = SdbOpenApphelpInformation(&(entryinfo.guidDB), &(entryinfo.guidID));
if (hAppHelpInfoContext) {
cbSize = 0; PBYTE pBuffer = NULL;
cbSize = SdbQueryApphelpInformation(hAppHelpInfoContext, ApphelpHelpCenterURL, NULL, 0);
if (cbSize && (pBuffer = new BYTE[cbSize])) {
cbSize = SdbQueryApphelpInformation(hAppHelpInfoContext, ApphelpHelpCenterURL, (LPVOID)pBuffer, cbSize);
if (cbSize) { m_strHtmlHelpID = (LPTSTR)pBuffer; }
delete pBuffer; }
SdbCloseApphelpInformation(hAppHelpInfoContext); } } } }
return TRUE; } BOOL CDriverFile::GetVersionInfo() { DWORD Size, dwHandle;
Size = GetFileVersionInfoSize((LPTSTR)(LPCTSTR)m_strFullPathName, &dwHandle);
if (!Size) { return FALSE; }
BufferPtr<BYTE> BufPtr(Size); PVOID pVerInfo = BufPtr;
if (GetFileVersionInfo((LPTSTR)(LPCTSTR)m_strFullPathName, dwHandle, Size, pVerInfo)) { // get VarFileInfo\Translation
PVOID pBuffer; UINT Len; String strStringFileInfo;
if (!VerQueryValue(pVerInfo, (LPTSTR)tszTranslation, &pBuffer, &Len)) { strStringFileInfo = tszStringFileInfoDefault; }
else { strStringFileInfo.Format(tszStringFileInfo, *((WORD*)pBuffer), *(((WORD*)pBuffer) + 1)); }
String str; str = strStringFileInfo + tszFileVersion;
if (VerQueryValue(pVerInfo, (LPTSTR)(LPCTSTR)str, &pBuffer, &Len)) { m_strVersion = (LPTSTR)pBuffer; str = strStringFileInfo + tszLegalCopyright;
if (VerQueryValue(pVerInfo, (LPTSTR)(LPCTSTR)str, &pBuffer, &Len)) { m_strCopyright = (LPTSTR)pBuffer; str = strStringFileInfo + tszCompanyName;
if (VerQueryValue(pVerInfo, (LPTSTR)(LPCTSTR)str, &pBuffer, &Len)) { m_strProvider = (LPTSTR)pBuffer; } } } }
return TRUE; }
BOOL CDriverFile::operator ==( CDriverFile& OtherDrvFile ) { return \ m_HasVersionInfo == OtherDrvFile.HasVersionInfo() && (GetFullPathName() == OtherDrvFile.GetFullPathName() || (GetFullPathName() && OtherDrvFile.GetFullPathName() && !lstrcmpi(GetFullPathName(), OtherDrvFile.GetFullPathName()) ) ) && (GetProvider() == OtherDrvFile.GetProvider() || (GetProvider() && OtherDrvFile.GetProvider() && !lstrcmpi(GetProvider(), OtherDrvFile.GetProvider()) ) ) && (GetCopyright() == OtherDrvFile.GetCopyright() || (GetCopyright() && OtherDrvFile.GetCopyright() && !lstrcmpi(GetCopyright(), OtherDrvFile.GetCopyright()) ) ) && (GetVersion() == OtherDrvFile.GetVersion() || (GetVersion() && OtherDrvFile.GetVersion() && !lstrcmpi(GetVersion(), OtherDrvFile.GetVersion()) ) ); }
|