Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1006 lines
28 KiB

  1. ///////////////////////////////////////////////////////////////////////////////
  2. //This file has the implementation for the WMI Provider for WHQL.
  3. //Uses MFC
  4. ///////////////////////////////////////////////////////////////////////////////
  5. // WhqlObj.cpp : Implementation of CWhqlObj
  6. #include "stdafx.h"
  7. #include "msinfo32.h"
  8. #include "WhqlObj.h"
  9. #include "chkdrv.h"
  10. HCATADMIN g_hCatAdmin;
  11. Classes_Provided eClasses;
  12. /////////////////////////////////////////////////////////////////////////////
  13. // CWhqlObj
  14. //v-stlowe 5-7-2001
  15. SCODE CWhqlObj::PutPropertyDTMFValue(IWbemClassObject* pInstance, LPCTSTR szName, LPCTSTR szValue)
  16. {
  17. HRESULT hr = S_FALSE;
  18. if (pInstance)
  19. {
  20. CComVariant ovValue(szValue);
  21. hr = ovValue.ChangeType(VT_DATE);
  22. COleDateTime dateTime = ovValue;
  23. CString strDateTime = dateTime.Format(_T("%Y%m%d%H%M%S.******+***"));
  24. ovValue = strDateTime.AllocSysString();
  25. if(SUCCEEDED(hr))
  26. {
  27. hr = pInstance->Put(CComBSTR(szName), 0, &ovValue, 0);
  28. }
  29. }
  30. return hr;
  31. }
  32. SCODE CWhqlObj::PutPropertyValue(IWbemClassObject* pInstance, LPCTSTR szName, LPCTSTR szValue)
  33. {
  34. HRESULT hr = S_FALSE;
  35. if(pInstance)
  36. {
  37. hr = pInstance->Put(CComBSTR(szName), 0, &CComVariant(szValue), 0);
  38. }
  39. return hr;
  40. }
  41. int WalkTreeHelper(DEVNODE hDevnode, DEVNODE hParent)
  42. {
  43. CheckDevice *pCurrentDevice;
  44. DEVNODE hSibling;
  45. DEVNODE hChild;
  46. CONFIGRET retval;
  47. pCurrentDevice = new CheckDevice(hDevnode, hParent);
  48. if(pCurrentDevice)
  49. {
  50. retval = pCurrentDevice->GetChild(&hChild);
  51. if(!retval)
  52. {
  53. WalkTreeHelper(hChild, hDevnode);
  54. }
  55. retval = pCurrentDevice->GetSibling(&hSibling);
  56. if(!retval)
  57. {
  58. WalkTreeHelper(hSibling, hParent);
  59. }
  60. }
  61. return TRUE;
  62. }
  63. int CWhqlObj::WalkTree(void)
  64. {
  65. CONFIGRET retval;
  66. DEVNODE hDevnode;
  67. //v-stlowe
  68. CheckDevice * pCurrentDevice = (CheckDevice *) DevnodeClass::GetHead();
  69. if (pCurrentDevice)
  70. {
  71. return TRUE;
  72. }
  73. //end v-stlowe
  74. // create devnode list
  75. retval = CM_Locate_DevNode(&hDevnode, NULL, CM_LOCATE_DEVNODE_NORMAL);
  76. if(retval)
  77. {
  78. //logprintf("ERROR: Could not locate any PnP Devices\r\n");
  79. return FALSE;
  80. }
  81. else
  82. WalkTreeHelper(hDevnode, NULL);
  83. return(TRUE);
  84. }
  85. STDMETHODIMP CWhqlObj::Initialize(LPWSTR pszUser,
  86. LONG lFlags,
  87. LPWSTR pszNamespace,
  88. LPWSTR pszLocale,
  89. IWbemServices *pNamespace,
  90. IWbemContext *pCtx,
  91. IWbemProviderInitSink *pInitSink)
  92. {
  93. if(pNamespace)
  94. pNamespace->AddRef();
  95. //Standard Var Inits.
  96. m_pNamespace = pNamespace;
  97. //Let CIMOM know you are initialized
  98. pInitSink->SetStatus(WBEM_S_INITIALIZED, 0);
  99. return WBEM_S_NO_ERROR;
  100. }
  101. SCODE CWhqlObj::CreateInstanceEnumAsync(BSTR RefStr,
  102. long lFlags,
  103. IWbemContext *pCtx,
  104. IWbemObjectSink *pHandler)
  105. {
  106. HRESULT hr = S_OK;
  107. IWbemClassObject *pClass = NULL;
  108. IWbemClassObject **ppInstances = NULL;
  109. LONG cInstances, lIndex;
  110. cInstances = lIndex = 0L;
  111. // Do a check of arguments and make sure we have pointer to Namespace
  112. if(pHandler == NULL || m_pNamespace == NULL)
  113. return WBEM_E_INVALID_PARAMETER;
  114. // Get a class object from CIMOM
  115. hr = m_pNamespace->GetObject(RefStr, 0, pCtx, &pClass, NULL);
  116. if(FAILED(hr))
  117. return WBEM_E_FAILED;
  118. CString csRefStr = RefStr;
  119. if(_tcsicmp(csRefStr , _T("Win32_PnPSignedDriver")) == 0)
  120. {
  121. eClasses = Class_Win32_PnPSignedDriver;
  122. }
  123. else if(_tcsicmp(csRefStr , _T("Win32_PnPSignedDriverCIMDataFile")) == 0)
  124. {
  125. eClasses = Class_Win32_PnPSignedDriverCIMDataFile;
  126. }
  127. CPtrArray ptrArr;
  128. ptrArr.RemoveAll();
  129. CreateList(ptrArr, pClass, pCtx, eClasses); //regular devices
  130. BuildPrinterFileList(ptrArr, pClass, pCtx, eClasses); //installed printers
  131. hr = pClass->Release();
  132. cInstances = (LONG)ptrArr.GetSize();
  133. ppInstances = (IWbemClassObject**)new LPVOID[cInstances];
  134. for(int nIndex = 0 ;nIndex<cInstances ;nIndex++)
  135. ppInstances[nIndex] = (IWbemClassObject*)ptrArr[nIndex];
  136. if (SUCCEEDED(hr))
  137. {
  138. // Send the instances to the caller
  139. hr = pHandler->Indicate(cInstances, ppInstances);
  140. for (lIndex = 0; lIndex < cInstances; lIndex++)
  141. ppInstances[lIndex]->Release();
  142. }
  143. // Cleanup
  144. if (ppInstances)
  145. {
  146. delete []ppInstances;
  147. ppInstances = NULL;
  148. }
  149. ptrArr.RemoveAll();
  150. // End Cleanup
  151. // Set status
  152. hr = pHandler->SetStatus(0, hr, NULL, NULL);
  153. return hr;
  154. }
  155. typedef BOOL (WINAPI *pSetupVerifyInfFile)(
  156. IN PCWSTR InfName,
  157. IN PSP_ALTPLATFORM_INFO AltPlatformInfo, OPTIONAL
  158. OUT PSP_INF_SIGNER_INFO_W InfSignerInfo
  159. );
  160. int CWhqlObj::CreateList(CPtrArray& ptrArr, IWbemClassObject *& pClass, IWbemContext *pCtx ,Classes_Provided eClasses)
  161. {
  162. if(pCtx == NULL)
  163. return S_FALSE;
  164. TCHAR szName[MAX_PATH] ;
  165. TCHAR szDeviceID[MAX_PATH] , szClassGuid[MAX_PATH] , szDeviceDesc[MAX_PATH];
  166. LONG len = sizeof(szName);
  167. HRESULT hr = S_FALSE;
  168. ULONG lRet = 0L;
  169. LONG lIndex = 0L;
  170. CString cstring;
  171. IWbemClassObject *pInstance = NULL;
  172. CheckDevice *pCurrentDevice = NULL;
  173. CheckDevice *pToBeDeletedDevice = NULL;
  174. FileNode *file;
  175. CComBSTR bstr;
  176. BOOL bAddedInstance = FALSE;
  177. TCHAR szTemp[ MAX_PATH + 1 ];
  178. SP_INF_SIGNER_INFO infSignerInfo;
  179. HINSTANCE hinst = NULL;
  180. pSetupVerifyInfFile fpSetupVerifyInfFile = NULL;
  181. hinst = LoadLibrary(_T("SetupApi.dll"));
  182. #ifdef _UNICODE
  183. fpSetupVerifyInfFile = (pSetupVerifyInfFile)GetProcAddress(hinst, "SetupVerifyInfFileW");
  184. #else
  185. fpSetupVerifyInfFile = (pSetupVerifyInfFile)GetProcAddress(hinst, "SetupVerifyInfFileA");
  186. #endif
  187. ZeroMemory(&infSignerInfo , sizeof(SP_INF_SIGNER_INFO));
  188. infSignerInfo.cbSize = sizeof(SP_INF_SIGNER_INFO);
  189. WalkTree();
  190. CString csPathStr;
  191. GetServerAndNamespace(pCtx, csPathStr); //Get Server And Namespace.
  192. pCurrentDevice = (CheckDevice *) DevnodeClass::GetHead();
  193. while(pCurrentDevice)
  194. {
  195. if(eClasses == Class_Win32_PnPSignedDriver && !bAddedInstance)
  196. {
  197. bAddedInstance = TRUE;
  198. if(pClass)
  199. hr = pClass->SpawnInstance(0, &pInstance);
  200. if(SUCCEEDED(hr) && pInstance)
  201. {
  202. //m_ptrArr.Add(pInstance);
  203. ptrArr.Add(pInstance);
  204. PutPropertyValue( pInstance , _T("DeviceName") , pCurrentDevice->DeviceName());
  205. PutPropertyValue( pInstance , _T("DeviceClass") , pCurrentDevice->DeviceClass());
  206. PutPropertyValue( pInstance , _T("HardwareID") , pCurrentDevice->HardwareID());
  207. PutPropertyValue( pInstance , _T("CompatID") , pCurrentDevice->CompatID());
  208. PutPropertyValue( pInstance , _T("DeviceID") , pCurrentDevice->DeviceID());
  209. PutPropertyValue( pInstance , _T("ClassGuid") , pCurrentDevice->GUID());
  210. PutPropertyValue( pInstance , _T("Location") , pCurrentDevice->Location());
  211. PutPropertyValue( pInstance , _T("PDO") , pCurrentDevice->PDO());
  212. PutPropertyValue( pInstance , _T("Manufacturer") , pCurrentDevice->MFG());
  213. PutPropertyValue( pInstance , _T("FriendlyName") , pCurrentDevice->FriendlyName());
  214. PutPropertyValue( pInstance , _T("InfName") , pCurrentDevice->InfName());
  215. PutPropertyValue( pInstance , _T("DriverProviderName") , pCurrentDevice->InfProvider());
  216. PutPropertyValue( pInstance , _T("DevLoader") , pCurrentDevice->DevLoader());
  217. PutPropertyValue( pInstance , _T("DriverName") , pCurrentDevice->DriverName());
  218. PutPropertyDTMFValue( pInstance , _T("DriverDate") , pCurrentDevice->DriverDate());
  219. PutPropertyValue( pInstance , _T("Description") , pCurrentDevice->DriverDesc());
  220. PutPropertyValue( pInstance , _T("DriverVersion") , pCurrentDevice->DriverVersion());
  221. PutPropertyValue( pInstance , _T("InfSection") , pCurrentDevice->InfSection());
  222. if(pCurrentDevice->InfName())
  223. {
  224. //cstring.Format(_T("%%WINDIR%%\\inf\\%s"), pCurrentDevice->InfName());
  225. //ExpandEnvironmentStrings(cstring , szTemp , sizeof(szTemp) + 1 );
  226. TCHAR *pInfpath = NULL;
  227. DWORD dw = ExpandEnvironmentStrings(_T("%windir%"), NULL, 0);
  228. if(dw > 0)
  229. {
  230. pInfpath = new TCHAR[dw];
  231. if(pInfpath)
  232. {
  233. dw = ExpandEnvironmentStrings(_T("%windir%"), pInfpath, dw);
  234. CString szTemp(pInfpath);
  235. szTemp += _T("\\inf\\");
  236. szTemp += pCurrentDevice->InfName();
  237. BOOL bRet = FALSE;
  238. //Do only if SetupApi.dll loaded & we have got fpSetupVerifyInfFile
  239. if(fpSetupVerifyInfFile != NULL)
  240. {
  241. bRet = (*fpSetupVerifyInfFile)(
  242. /*IN PCSTR*/ szTemp,
  243. /*IN PSP_ALTPLATFORM_INFO*/NULL,
  244. /*OUT PSP_INF_SIGNER_INFO_A*/ &infSignerInfo
  245. );
  246. hr = pInstance->Put(L"IsSigned", 0, &CComVariant(bRet), 0 );
  247. if(bRet)
  248. PutPropertyValue( pInstance , _T("Signer") , infSignerInfo.DigitalSigner);
  249. }
  250. delete[] pInfpath;
  251. pInfpath = NULL;
  252. }//if(pInfpath)
  253. }//if(dw > 0)
  254. }//if(pCurrentDevice->InfName())
  255. }
  256. }
  257. if(eClasses == Class_Win32_PnPSignedDriverCIMDataFile)
  258. {
  259. CString szAntecedent(pCurrentDevice->DeviceID()); //Antecedent
  260. if(!szAntecedent.IsEmpty())
  261. {
  262. szAntecedent.Replace(_T("\\"), _T("\\\\"));
  263. file = pCurrentDevice->GetFileList();
  264. while(file)
  265. {
  266. CString szDependent(file->FilePath()); //Dependent
  267. if(!szDependent.IsEmpty())
  268. {
  269. szDependent.Replace(_T("\\"), _T("\\\\"));
  270. if(pClass)
  271. hr = pClass->SpawnInstance(0, &pInstance);
  272. if(SUCCEEDED(hr) && pInstance)
  273. {
  274. if(!csPathStr.IsEmpty())
  275. {
  276. CString szData(csPathStr);
  277. szData += _T(":Win32_PnPSignedDriver.DeviceID=\"");
  278. szData += szAntecedent;
  279. szData += _T("\"");
  280. hr = pInstance->Put(_T("Antecedent"), 0, &CComVariant(szData), 0);
  281. szData.Empty();
  282. szData = csPathStr;
  283. szData += _T(":CIM_DataFile.Name=\"");
  284. szData += szDependent;
  285. szData += _T("\"");
  286. hr = pInstance->Put(_T("Dependent"), 0, &CComVariant(szData), 0);
  287. ptrArr.Add(pInstance);
  288. }
  289. }
  290. }
  291. file = file->pNext;
  292. }
  293. }
  294. }
  295. //pToBeDeletedDevice = pCurrentDevice;
  296. pCurrentDevice = (CheckDevice *)pCurrentDevice->GetNext();
  297. //if(pToBeDeletedDevice)
  298. //delete pToBeDeletedDevice ;//delete pToBeDeletedDevice which will release it from CheckDevice Linked List.
  299. bAddedInstance = FALSE;
  300. }
  301. if(hinst)
  302. FreeLibrary(hinst);
  303. return hr;
  304. }
  305. SCODE CWhqlObj::GetServerAndNamespace(IWbemContext* pCtx, CString& csPathStr)
  306. {
  307. HRESULT hr = S_FALSE;
  308. ULONG lRet = 0L;
  309. CComBSTR language = _T("WQL");
  310. CComBSTR query = _T("select __NameSpace , __Server from Win32_PnpEntity");
  311. CComPtr<IEnumWbemClassObject> pEnum;
  312. CComPtr<IWbemClassObject> pObject;
  313. hr = m_pNamespace->ExecQuery(language , query ,
  314. WBEM_FLAG_RETURN_IMMEDIATELY|WBEM_FLAG_FORWARD_ONLY, pCtx , &pEnum);
  315. language.Empty();
  316. query.Empty();
  317. if(pEnum == NULL)
  318. return S_FALSE;
  319. CComVariant v;
  320. //Get Server And Namespace from the Enum.
  321. if( WBEM_S_NO_ERROR == pEnum->Next(WBEM_INFINITE , 1 , &pObject , &lRet ) )
  322. {
  323. //Fill csPathStr.Its value will be used in Antecedent & Dependent in assoc. class.
  324. //At the end of the condition we should have something like
  325. //csPathStr = "\\\\A-KJAW-RI1\\root\\CIMV2"
  326. if(csPathStr.IsEmpty())
  327. {
  328. hr = pObject->Get(L"__Server", 0, &v, NULL , NULL);
  329. if( SUCCEEDED(hr) )
  330. {
  331. csPathStr += _T("\\\\");
  332. csPathStr += V_BSTR(&v);
  333. hr = pObject->Get(L"__NameSpace", 0, &v, NULL , NULL);
  334. if( SUCCEEDED(hr) )
  335. {
  336. csPathStr += _T("\\");
  337. csPathStr += V_BSTR(&v);
  338. }
  339. ATLTRACE(_T("Server & Namespace Path = %s\n") , csPathStr);
  340. VariantClear(&v);
  341. }
  342. }
  343. }
  344. return hr;
  345. }
  346. /*************************************************************************
  347. * Function : VerifyIsFileSigned
  348. * Purpose : Calls WinVerifyTrust with Policy Provider GUID to
  349. * verify if an individual file is signed.
  350. **************************************************************************/
  351. BOOL VerifyIsFileSigned(LPTSTR pcszMatchFile, PDRIVER_VER_INFO lpVerInfo)
  352. {
  353. INT iRet;
  354. HRESULT hRes;
  355. WINTRUST_DATA WinTrustData;
  356. WINTRUST_FILE_INFO WinTrustFile;
  357. GUID gOSVerCheck = DRIVER_ACTION_VERIFY;
  358. GUID gPublishedSoftware = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  359. #ifndef UNICODE
  360. WCHAR wszFileName[MAX_PATH];
  361. #endif
  362. ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA));
  363. WinTrustData.cbStruct = sizeof(WINTRUST_DATA);
  364. WinTrustData.dwUIChoice = WTD_UI_NONE;
  365. WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
  366. WinTrustData.dwUnionChoice = WTD_CHOICE_FILE;
  367. WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE;
  368. WinTrustData.pFile = &WinTrustFile;
  369. WinTrustData.pPolicyCallbackData = (LPVOID)lpVerInfo;
  370. ZeroMemory(lpVerInfo, sizeof(DRIVER_VER_INFO));
  371. lpVerInfo->cbStruct = sizeof(DRIVER_VER_INFO);
  372. ZeroMemory(&WinTrustFile, sizeof(WINTRUST_FILE_INFO));
  373. WinTrustFile.cbStruct = sizeof(WINTRUST_FILE_INFO);
  374. #ifndef UNICODE
  375. iRet = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcszMatchFile, -1, (LPWSTR)&wszFileName, cA(wszFileName));
  376. WinTrustFile.pcwszFilePath = wszFileName;
  377. #else
  378. WinTrustFile.pcwszFilePath = pcszMatchFile;
  379. #endif
  380. hRes = WinVerifyTrust((HWND) INVALID_HANDLE_VALUE, &gOSVerCheck, &WinTrustData);
  381. if (hRes != ERROR_SUCCESS) {
  382. hRes = WinVerifyTrust((HWND) INVALID_HANDLE_VALUE, &gPublishedSoftware, &WinTrustData);
  383. }
  384. //
  385. // Free the pcSignerCertContext member of the DRIVER_VER_INFO struct
  386. // that was allocated in our call to WinVerifyTrust.
  387. //
  388. if (lpVerInfo && lpVerInfo->pcSignerCertContext) {
  389. CertFreeCertificateContext(lpVerInfo->pcSignerCertContext);
  390. lpVerInfo->pcSignerCertContext = NULL;
  391. }
  392. return(hRes == ERROR_SUCCESS);
  393. }
  394. //
  395. // Given a specific LPFILENODE, verify that the file is signed or unsigned.
  396. // Fill in all the necessary structures so the listview control can display properly.
  397. //
  398. BOOL VerifyFileNode(LPFILENODE lpFileNode)
  399. {
  400. HANDLE hFile;
  401. BOOL bRet;
  402. HCATINFO hCatInfo = NULL;
  403. HCATINFO PrevCat;
  404. WINTRUST_DATA WinTrustData;
  405. WINTRUST_CATALOG_INFO WinTrustCatalogInfo;
  406. DRIVER_VER_INFO VerInfo;
  407. GUID gSubSystemDriver = DRIVER_ACTION_VERIFY;
  408. HRESULT hRes;
  409. DWORD cbHash = HASH_SIZE;
  410. BYTE szHash[HASH_SIZE];
  411. LPBYTE lpHash = szHash;
  412. CATALOG_INFO CatInfo;
  413. LPTSTR lpFilePart;
  414. TCHAR szBuffer[MAX_PATH];
  415. static TCHAR szCurrentDirectory[MAX_PATH];
  416. OSVERSIONINFO OsVersionInfo;
  417. BOOL bTmp = FALSE;
  418. #ifndef UNICODE
  419. WCHAR UnicodeKey[MAX_PATH];
  420. #endif
  421. if (!SetCurrentDirectory(lpFileNode->lpDirName)) {
  422. return FALSE;
  423. }
  424. //
  425. // Get the handle to the file, so we can call CryptCATAdminCalcHashFromFileHandle
  426. //
  427. hFile = CreateFile( lpFileNode->lpFileName,
  428. GENERIC_READ,
  429. FILE_SHARE_READ | FILE_SHARE_WRITE,
  430. NULL,
  431. OPEN_EXISTING,
  432. FILE_ATTRIBUTE_NORMAL,
  433. NULL);
  434. if (hFile == INVALID_HANDLE_VALUE) {
  435. lpFileNode->LastError = GetLastError();
  436. return FALSE;
  437. }
  438. // Initialize the hash buffer
  439. ZeroMemory(lpHash, HASH_SIZE);
  440. // Generate the hash from the file handle and store it in lpHash
  441. if (!CryptCATAdminCalcHashFromFileHandle(hFile, &cbHash, lpHash, 0)) {
  442. //
  443. // If we couldn't generate a hash, it might be an individually signed catalog.
  444. // If it's a catalog, zero out lpHash and cbHash so we know there's no hash to check.
  445. //
  446. if (IsCatalogFile(hFile, NULL)) {
  447. lpHash = NULL;
  448. cbHash = 0;
  449. } else { // If it wasn't a catalog, we'll bail and this file will show up as unscanned.
  450. CloseHandle(hFile);
  451. return FALSE;
  452. }
  453. }
  454. // Close the file handle
  455. CloseHandle(hFile);
  456. //
  457. // Now we have the file's hash. Initialize the structures that
  458. // will be used later on in calls to WinVerifyTrust.
  459. //
  460. ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA));
  461. WinTrustData.cbStruct = sizeof(WINTRUST_DATA);
  462. WinTrustData.dwUIChoice = WTD_UI_NONE;
  463. WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
  464. WinTrustData.dwUnionChoice = WTD_CHOICE_CATALOG;
  465. WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE;
  466. WinTrustData.pPolicyCallbackData = (LPVOID)&VerInfo;
  467. ZeroMemory(&VerInfo, sizeof(DRIVER_VER_INFO));
  468. VerInfo.cbStruct = sizeof(DRIVER_VER_INFO);
  469. //
  470. // Only validate against the current OS Version, unless the bValidateAgainstAnyOs
  471. // parameter was TRUE. In that case we will just leave the sOSVersionXxx fields
  472. // 0 which tells WinVerifyTrust to validate against any OS.
  473. //
  474. if (!lpFileNode->bValidateAgainstAnyOs) {
  475. OsVersionInfo.dwOSVersionInfoSize = sizeof(OsVersionInfo);
  476. if (GetVersionEx(&OsVersionInfo)) {
  477. VerInfo.sOSVersionLow.dwMajor = OsVersionInfo.dwMajorVersion;
  478. VerInfo.sOSVersionLow.dwMinor = OsVersionInfo.dwMinorVersion;
  479. VerInfo.sOSVersionHigh.dwMajor = OsVersionInfo.dwMajorVersion;
  480. VerInfo.sOSVersionHigh.dwMinor = OsVersionInfo.dwMinorVersion;
  481. }
  482. }
  483. WinTrustData.pCatalog = &WinTrustCatalogInfo;
  484. ZeroMemory(&WinTrustCatalogInfo, sizeof(WINTRUST_CATALOG_INFO));
  485. WinTrustCatalogInfo.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
  486. WinTrustCatalogInfo.pbCalculatedFileHash = lpHash;
  487. WinTrustCatalogInfo.cbCalculatedFileHash = cbHash;
  488. #ifdef UNICODE
  489. WinTrustCatalogInfo.pcwszMemberTag = lpFileNode->lpFileName;
  490. #else
  491. MultiByteToWideChar(CP_ACP, 0, lpFileNode->lpFileName, -1, UnicodeKey, cA(UnicodeKey));
  492. WinTrustCatalogInfo.pcwszMemberTag = UnicodeKey;
  493. #endif
  494. //
  495. // Now we try to find the file hash in the catalog list, via CryptCATAdminEnumCatalogFromHash
  496. //
  497. PrevCat = NULL;
  498. hCatInfo = CryptCATAdminEnumCatalogFromHash(g_hCatAdmin, lpHash, cbHash, 0, &PrevCat);
  499. //
  500. // We want to cycle through the matching catalogs until we find one that matches both hash and member tag
  501. //
  502. bRet = FALSE;
  503. while (hCatInfo && !bRet) {
  504. ZeroMemory(&CatInfo, sizeof(CATALOG_INFO));
  505. CatInfo.cbStruct = sizeof(CATALOG_INFO);
  506. if (CryptCATCatalogInfoFromContext(hCatInfo, &CatInfo, 0)) {
  507. WinTrustCatalogInfo.pcwszCatalogFilePath = CatInfo.wszCatalogFile;
  508. // Now verify that the file is an actual member of the catalog.
  509. hRes = WinVerifyTrust((HWND) INVALID_HANDLE_VALUE, &gSubSystemDriver, &WinTrustData);
  510. if (hRes == ERROR_SUCCESS) {
  511. #ifdef UNICODE
  512. GetFullPathName(CatInfo.wszCatalogFile, MAX_PATH, szBuffer, &lpFilePart);
  513. #else
  514. WideCharToMultiByte(CP_ACP, 0, CatInfo.wszCatalogFile, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
  515. GetFullPathName(szBuffer, MAX_PATH, szBuffer, &lpFilePart);
  516. #endif
  517. lpFileNode->lpCatalog = (LPTSTR) MALLOC((lstrlen(lpFilePart) + 1) * sizeof(TCHAR));
  518. if (lpFileNode->lpCatalog) {
  519. lstrcpy(lpFileNode->lpCatalog, lpFilePart);
  520. }
  521. bRet = TRUE;
  522. }
  523. //
  524. // Free the pcSignerCertContext member of the DRIVER_VER_INFO struct
  525. // that was allocated in our call to WinVerifyTrust.
  526. //
  527. if (VerInfo.pcSignerCertContext != NULL) {
  528. CertFreeCertificateContext(VerInfo.pcSignerCertContext);
  529. VerInfo.pcSignerCertContext = NULL;
  530. }
  531. }
  532. if (!bRet) {
  533. // The hash was in this catalog, but the file wasn't a member... so off to the next catalog
  534. PrevCat = hCatInfo;
  535. hCatInfo = CryptCATAdminEnumCatalogFromHash(g_hCatAdmin, lpHash, cbHash, 0, &PrevCat);
  536. }
  537. }
  538. // Mark this file as having been scanned.
  539. lpFileNode->bScanned = TRUE;
  540. if (!hCatInfo) {
  541. //
  542. // If it wasn't found in the catalogs, check if the file is individually signed.
  543. //
  544. bRet = VerifyIsFileSigned(lpFileNode->lpFileName, (PDRIVER_VER_INFO)&VerInfo);
  545. if (bRet) {
  546. // If so, mark the file as being signed.
  547. lpFileNode->bSigned = TRUE;
  548. }
  549. } else {
  550. // The file was verified in the catalogs, so mark it as signed and free the catalog context.
  551. lpFileNode->bSigned = TRUE;
  552. CryptCATAdminReleaseCatalogContext(g_hCatAdmin, hCatInfo, 0);
  553. }
  554. if (lpFileNode->bSigned) {
  555. #ifdef UNICODE
  556. lpFileNode->lpVersion = (LPTSTR) MALLOC((lstrlen(VerInfo.wszVersion) + 1) * sizeof(TCHAR));
  557. if (lpFileNode->lpVersion) {
  558. lstrcpy(lpFileNode->lpVersion, VerInfo.wszVersion);
  559. }
  560. lpFileNode->lpSignedBy = (LPTSTR) MALLOC((lstrlen(VerInfo.wszSignedBy) + 1) * sizeof(TCHAR));
  561. if (lpFileNode->lpSignedBy) {
  562. lstrcpy(lpFileNode->lpSignedBy, VerInfo.wszSignedBy);
  563. }
  564. #else
  565. WideCharToMultiByte(CP_ACP, 0, VerInfo.wszVersion, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
  566. lpFileNode->lpVersion = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR));
  567. if (lpFileNode->lpVersion) {
  568. lstrcpy(lpFileNode->lpVersion, szBuffer);
  569. }
  570. WideCharToMultiByte(CP_ACP, 0, VerInfo.wszSignedBy, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
  571. lpFileNode->lpSignedBy = MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR));
  572. if (lpFileNode->lpSignedBy) {
  573. lstrcpy(lpFileNode->lpSignedBy, szBuffer);
  574. }
  575. #endif
  576. } else {
  577. //
  578. // Get the icon (if the file isn't signed) so we can display it in the listview faster.
  579. //
  580. //MyGetFileInfo(lpFileNode);
  581. }
  582. return lpFileNode->bSigned;
  583. }
  584. LPFILENODE CreateFileNode(LPTSTR lpDirectory, LPTSTR lpFileName)
  585. {
  586. LPFILENODE lpFileNode;
  587. TCHAR szDirName[MAX_PATH];
  588. FILETIME ftLocalTime;
  589. WIN32_FILE_ATTRIBUTE_DATA faData;
  590. BOOL bRet;
  591. GetCurrentDirectory(MAX_PATH, szDirName);
  592. CharLowerBuff(szDirName, lstrlen(szDirName));
  593. lpFileNode = (LPFILENODE) MALLOC(sizeof(FILENODE));
  594. if (lpFileNode)
  595. {
  596. lpFileNode->lpFileName = (LPTSTR) MALLOC((lstrlen(lpFileName) + 1) * sizeof(TCHAR));
  597. if (!lpFileNode->lpFileName)
  598. {
  599. goto clean0;
  600. }
  601. lstrcpy(lpFileNode->lpFileName, lpFileName);
  602. CharLowerBuff(lpFileNode->lpFileName, lstrlen(lpFileNode->lpFileName));
  603. if (lpDirectory)
  604. {
  605. lpFileNode->lpDirName = (LPTSTR) MALLOC((lstrlen(lpDirectory) + 1) * sizeof(TCHAR));
  606. if (!lpFileNode->lpDirName)
  607. {
  608. goto clean0;
  609. }
  610. lstrcpy(lpFileNode->lpDirName, lpDirectory);
  611. CharLowerBuff(lpFileNode->lpDirName, lstrlen(lpFileNode->lpDirName));
  612. }
  613. else
  614. {
  615. lpFileNode->lpDirName = (LPTSTR) MALLOC((lstrlen(szDirName) + 1) * sizeof(TCHAR));
  616. if (!lpFileNode->lpDirName)
  617. {
  618. goto clean0;
  619. }
  620. lstrcpy(lpFileNode->lpDirName, szDirName);
  621. CharLowerBuff(lpFileNode->lpDirName, lstrlen(lpFileNode->lpDirName));
  622. }
  623. if (lpDirectory)
  624. SetCurrentDirectory(lpDirectory);
  625. ZeroMemory(&faData, sizeof(WIN32_FILE_ATTRIBUTE_DATA));
  626. bRet = GetFileAttributesEx(lpFileName, GetFileExInfoStandard, &faData);
  627. if (bRet)
  628. {
  629. // Store away the last access time for logging purposes.
  630. FileTimeToLocalFileTime(&faData.ftLastWriteTime, &ftLocalTime);
  631. FileTimeToSystemTime(&ftLocalTime, &lpFileNode->LastModified);
  632. }
  633. }
  634. if (lpDirectory)
  635. SetCurrentDirectory(szDirName);
  636. return lpFileNode;
  637. clean0:
  638. //
  639. // If we get here then we weren't able to allocate all of the memory needed
  640. // for this structure, so free up any memory we were able to allocate and
  641. // reutnr NULL.
  642. //
  643. if (lpFileNode)
  644. {
  645. if (lpFileNode->lpFileName)
  646. {
  647. FREE(lpFileNode->lpFileName);
  648. }
  649. if (lpFileNode->lpDirName)
  650. {
  651. FREE(lpFileNode->lpDirName);
  652. }
  653. FREE(lpFileNode);
  654. }
  655. return NULL;
  656. }
  657. LPFILENODE Check_File(LPTSTR szFilePathName)
  658. {
  659. LPFILENODE lpFileNode = NULL;
  660. // If we don't already have a g_hCatAdmin handle, acquire one.
  661. if (!g_hCatAdmin) {
  662. CryptCATAdminAcquireContext(&g_hCatAdmin, NULL, 0);
  663. }
  664. TCHAR* szFileName = szFilePathName;
  665. if(szFilePathName)
  666. {
  667. szFileName = _tcsrchr(szFilePathName, _T('\\'));
  668. if(szFileName)
  669. {
  670. *szFileName++ = _T('\0');
  671. lpFileNode = CreateFileNode(szFilePathName, szFileName);
  672. if(lpFileNode)
  673. {
  674. VerifyFileNode(lpFileNode);
  675. }
  676. }
  677. }
  678. return lpFileNode;
  679. }
  680. // returns data between dbl quotes, unescapes slashes
  681. // "\\\\red-prn-23\\priv0124" -> \\red-prn-23\priv0124
  682. LPTSTR GetQuotedData(VARIANT& v, BOOL bUnescapeSlashs = TRUE)
  683. {
  684. CString szData;
  685. if(v.vt == VT_BSTR)
  686. {
  687. szData = v.bstrVal;
  688. if(!szData.IsEmpty())
  689. {
  690. int nPos = szData.Find(_T('"'));
  691. if(nPos >= 0 && (szData.GetLength() > 1))
  692. {
  693. szData = szData.Mid(nPos + 1);
  694. nPos = szData.Find(_T('"'));
  695. if(nPos >= 0)
  696. {
  697. szData = szData.Mid(0, nPos);
  698. if(bUnescapeSlashs)
  699. szData.Replace(_T("\\\\"), _T("\\"));
  700. }
  701. }
  702. }
  703. VariantClear(&v);
  704. v.vt = VT_BSTR;
  705. v.bstrVal = CComBSTR(szData);
  706. }
  707. return CComBSTR(szData);
  708. }
  709. void CWhqlObj::BuildPrinterFileList(CPtrArray& ptrArr, IWbemClassObject *& pClass, IWbemContext *pCtx , Classes_Provided eClasses)
  710. {
  711. IEnumWbemClassObject *pEnum = NULL;
  712. IWbemClassObject *pInstance = NULL;
  713. IWbemClassObject *pObject = NULL;
  714. ULONG uReturned = 0;
  715. HRESULT hr = WBEM_S_NO_ERROR;
  716. CComVariant val;
  717. LPFILENODE lpFileNode = NULL;
  718. if((eClasses == Class_Win32_PnPSignedDriver) ||
  719. (eClasses == Class_Win32_PnPSignedDriverCIMDataFile))
  720. {
  721. CoImpersonateClient(); //Impersonate the client. This is a must to be able to see network printers.
  722. CString csPathStr;
  723. GetServerAndNamespace(pCtx, csPathStr); //Get Server And Namespace.
  724. hr = m_pNamespace->CreateInstanceEnum(CComBSTR("Win32_PrinterDriverDll"),
  725. WBEM_FLAG_RETURN_IMMEDIATELY | WBEM_FLAG_FORWARD_ONLY,
  726. pCtx,
  727. &pEnum);
  728. while(WBEM_S_NO_ERROR == hr && pEnum)
  729. {
  730. hr = pEnum->Next(WBEM_INFINITE,
  731. 1,
  732. &pObject,
  733. &uReturned);
  734. if(SUCCEEDED(hr) && pObject)
  735. {
  736. hr = pObject->Get(_T("Antecedent"), 0, &val, NULL , NULL);
  737. if(SUCCEEDED(hr))
  738. {
  739. if(pClass)
  740. hr = pClass->SpawnInstance(0, &pInstance);
  741. if(SUCCEEDED(hr) && pInstance)
  742. {
  743. if(eClasses == Class_Win32_PnPSignedDriver)
  744. {
  745. LPTSTR szDriverPath = GetQuotedData(val);
  746. if(szDriverPath)
  747. {
  748. lpFileNode = Check_File(szDriverPath);
  749. if(lpFileNode)
  750. {
  751. val = lpFileNode->bSigned;
  752. hr = pInstance->Put(_T("IsSigned"), 0, &val, 0);
  753. val.Clear();
  754. val = lpFileNode->lpVersion;
  755. hr = pInstance->Put(_T("DriverVersion"), 0, &val, 0);
  756. val.Clear();
  757. val = lpFileNode->lpSignedBy;
  758. hr = pInstance->Put(_T("Signer"), 0, &val, 0);
  759. }
  760. }
  761. }
  762. else if(eClasses == Class_Win32_PnPSignedDriverCIMDataFile)
  763. {
  764. GetQuotedData(val, FALSE);
  765. CString szData(csPathStr);
  766. szData += _T(":CIM_DataFile.Name=\"");
  767. szData += val.bstrVal;
  768. szData += _T("\"");
  769. val = szData;
  770. hr = pInstance->Put(_T("Dependent"), 0, &val, 0);
  771. }
  772. val.Clear();
  773. hr = pObject->Get(_T("Dependent"), 0, &val, NULL , NULL);
  774. if(SUCCEEDED(hr))
  775. {
  776. if(eClasses == Class_Win32_PnPSignedDriver)
  777. {
  778. GetQuotedData(val);
  779. hr = pInstance->Put(_T("DeviceID"), 0, &val, 0);
  780. }
  781. else if(eClasses == Class_Win32_PnPSignedDriverCIMDataFile)
  782. {
  783. GetQuotedData(val, FALSE);
  784. CString szData(csPathStr);
  785. szData += _T(":Win32_PnPSignedDriver.DeviceID=\"");
  786. szData += val.bstrVal;
  787. szData += _T("\"");
  788. val = szData;
  789. hr = pInstance->Put(_T("Antecedent"), 0, &val, 0);
  790. }
  791. }
  792. ptrArr.Add(pInstance);
  793. }
  794. val.Clear();
  795. }
  796. if(pObject)
  797. {
  798. pObject->Release();
  799. pObject = NULL;
  800. }
  801. }
  802. val.Clear();
  803. }
  804. if(pEnum)
  805. {
  806. pEnum->Release();
  807. pEnum = NULL;
  808. }
  809. CoRevertToSelf(); //Revert back
  810. }
  811. }