Leaked source code of windows server 2003
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.

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