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.

1181 lines
38 KiB

  1. /*==========================================================================;
  2. *
  3. * Copyright (C) 1994-1997 Microsoft Corporation. All Rights Reserved.
  4. *
  5. * File: drvinfo.c
  6. * Content: DirectDraw driver info implementation
  7. *@@BEGIN_MSINTERNAL
  8. * History:
  9. * Date By Reason
  10. * ==== == ======
  11. * 17-jun-98 jeffno initial implementation, after michael lyons and toddla
  12. * 14-jun-99 mregen return WHQL certification level -- postponed
  13. *@@END_MSINTERNAL
  14. *
  15. ***************************************************************************/
  16. #include "ddrawpr.h"
  17. #include <tchar.h>
  18. #include <stdio.h>
  19. #include <wincrypt.h>
  20. #include <wintrust.h>
  21. #include <softpub.h>
  22. #include <mscat.h>
  23. //========================================================================
  24. //
  25. // just some handy forward declarations
  26. //
  27. DWORD GetWHQLLevel(LPTSTR lpszDriver, LPSTR lpszWin9xDriver);
  28. DWORD IsFileDigitallySigned(LPTSTR lpszDriver);
  29. BOOL FileIsSignedOld(LPTSTR lpszFile);
  30. //
  31. // These functions are defined in mscat.h. They are not available on win95,
  32. // so we have to use LoadLibrary to load mscat32.dll and wincrypt.dll
  33. //
  34. typedef HCATINFO WINAPI funcCryptCATAdminEnumCatalogFromHash(HCATADMIN hCatAdmin,
  35. BYTE *pbHash,
  36. DWORD cbHash,
  37. DWORD dwFlags,
  38. HCATINFO *phPrevCatInfo);
  39. typedef BOOL WINAPI funcCryptCATAdminCalcHashFromFileHandle(HANDLE hFile,
  40. DWORD *pcbHash,
  41. BYTE *pbHash,
  42. DWORD dwFlags);
  43. typedef HANDLE WINAPI funcCryptCATOpen(LPWSTR pwszFileName,
  44. DWORD fdwOpenFlags,
  45. HCRYPTPROV hProv,
  46. DWORD dwPublicVersion,
  47. DWORD dwEncodingType);
  48. typedef BOOL WINAPI funcCryptCATClose(IN HANDLE hCatalog);
  49. typedef CRYPTCATATTRIBUTE * WINAPI funcCryptCATGetCatAttrInfo(HANDLE hCatalog,
  50. LPWSTR pwszReferenceTag);
  51. typedef BOOL WINAPI funcCryptCATAdminAcquireContext(HCATADMIN *phCatAdmin,
  52. GUID *pgSubsystem,
  53. DWORD dwFlags);
  54. typedef BOOL WINAPI funcCryptCATAdminReleaseContext(HCATADMIN hCatAdmin,
  55. DWORD dwFlags);
  56. typedef BOOL WINAPI funcCryptCATAdminReleaseCatalogContext(HCATADMIN hCatAdmin,
  57. HCATINFO hCatInfo,
  58. DWORD dwFlags);
  59. typedef BOOL WINAPI funcCryptCATCatalogInfoFromContext(HCATINFO hCatInfo,
  60. CATALOG_INFO *psCatInfo,
  61. DWORD dwFlags);
  62. typedef CRYPTCATATTRIBUTE * WINAPI funcCryptCATEnumerateCatAttr(HCATINFO hCatalog,
  63. CRYPTCATATTRIBUTE *lpCat);
  64. //
  65. // function defined in wincrypt.dll
  66. //
  67. typedef LONG WINAPI funcWinVerifyTrust(HWND hwnd, GUID *pgActionID,
  68. LPVOID pWVTData);
  69. //
  70. // our storage for the mscat32/wincrypt dll loader
  71. //
  72. typedef struct tagCatApi {
  73. BOOL bInitialized;
  74. HINSTANCE hLibMSCat;
  75. HINSTANCE hLibWinTrust;
  76. HCATADMIN hCatAdmin;
  77. funcCryptCATClose *pCryptCATClose;
  78. funcCryptCATGetCatAttrInfo *pCryptCATGetCatAttrInfo;
  79. funcCryptCATOpen *pCryptCATOpen;
  80. funcCryptCATAdminEnumCatalogFromHash *pCryptCATAdminEnumCatalogFromHash;
  81. funcCryptCATAdminCalcHashFromFileHandle *pCryptCATAdminCalcHashFromFileHandle;
  82. funcCryptCATAdminAcquireContext *pCryptCATAdminAcquireContext;
  83. funcCryptCATAdminReleaseContext *pCryptCATAdminReleaseContext;
  84. funcCryptCATAdminReleaseCatalogContext *pCryptCATAdminReleaseCatalogContext;
  85. funcCryptCATCatalogInfoFromContext *pCryptCATCatalogInfoFromContext;
  86. funcCryptCATEnumerateCatAttr *pCryptCATEnumerateCatAttr;
  87. funcWinVerifyTrust *pWinVerifyTrust;
  88. } CATAPI,* LPCATAPI;
  89. //========================================================================
  90. //
  91. // some helper functions to open/close crypt API
  92. //
  93. #undef DPF_MODNAME
  94. #define DPF_MODNAME "InitCATAPI"
  95. BOOL InitCATAPI(LPCATAPI lpCatApi)
  96. {
  97. UINT uiOldErrorMode;
  98. HINSTANCE hLibMSCat;
  99. HINSTANCE hLibWinTrust;
  100. DDASSERT(lpCatApi!=NULL);
  101. ZeroMemory(lpCatApi, sizeof(CATAPI));
  102. // already initialized by ZeroMemory
  103. // lpCatApi->bInitialized=FALSE:
  104. uiOldErrorMode=SetErrorMode(SEM_NOOPENFILEERRORBOX);
  105. hLibMSCat=LoadLibrary("mscat32.dll");
  106. hLibWinTrust=LoadLibrary("wintrust.dll");
  107. if (hLibMSCat!=NULL &&
  108. hLibWinTrust!=NULL)
  109. {
  110. lpCatApi->pCryptCATOpen=(funcCryptCATOpen *)
  111. GetProcAddress (hLibMSCat, "CryptCATOpen");
  112. lpCatApi->pCryptCATClose=(funcCryptCATClose *)
  113. GetProcAddress (hLibMSCat, "CryptCATClose");
  114. lpCatApi->pCryptCATGetCatAttrInfo=(funcCryptCATGetCatAttrInfo *)
  115. GetProcAddress (hLibMSCat, "CryptCATGetCatAttrInfo");
  116. lpCatApi->pCryptCATAdminCalcHashFromFileHandle=(funcCryptCATAdminCalcHashFromFileHandle*)
  117. GetProcAddress (hLibMSCat, "CryptCATAdminCalcHashFromFileHandle");
  118. lpCatApi->pCryptCATAdminEnumCatalogFromHash=(funcCryptCATAdminEnumCatalogFromHash*)
  119. GetProcAddress (hLibMSCat, "CryptCATAdminEnumCatalogFromHash");
  120. lpCatApi->pCryptCATAdminAcquireContext=(funcCryptCATAdminAcquireContext*)
  121. GetProcAddress (hLibMSCat, "CryptCATAdminAcquireContext");
  122. lpCatApi->pCryptCATAdminReleaseContext=(funcCryptCATAdminReleaseContext*)
  123. GetProcAddress (hLibMSCat, "CryptCATAdminReleaseContext");
  124. lpCatApi->pCryptCATAdminReleaseCatalogContext=(funcCryptCATAdminReleaseCatalogContext*)
  125. GetProcAddress (hLibMSCat, "CryptCATAdminReleaseCatalogContext");
  126. lpCatApi->pCryptCATCatalogInfoFromContext=(funcCryptCATCatalogInfoFromContext*)
  127. GetProcAddress (hLibMSCat, "CryptCATCatalogInfoFromContext");
  128. lpCatApi->pCryptCATEnumerateCatAttr=(funcCryptCATEnumerateCatAttr*)
  129. GetProcAddress (hLibMSCat, "CryptCATEnumerateCatAttr");
  130. lpCatApi->pWinVerifyTrust=(funcWinVerifyTrust*)
  131. GetProcAddress (hLibWinTrust,"WinVerifyTrust");
  132. if (lpCatApi->pCryptCATOpen!=NULL &&
  133. lpCatApi->pCryptCATClose!=NULL &&
  134. lpCatApi->pCryptCATGetCatAttrInfo!=NULL &&
  135. lpCatApi->pCryptCATAdminCalcHashFromFileHandle!=NULL &&
  136. lpCatApi->pCryptCATAdminEnumCatalogFromHash!=NULL &&
  137. lpCatApi->pCryptCATAdminAcquireContext!=NULL &&
  138. lpCatApi->pCryptCATAdminReleaseContext!=NULL &&
  139. lpCatApi->pCryptCATAdminReleaseCatalogContext!=NULL &&
  140. lpCatApi->pCryptCATCatalogInfoFromContext!=NULL &&
  141. lpCatApi->pCryptCATEnumerateCatAttr !=NULL &&
  142. lpCatApi->pWinVerifyTrust!=NULL
  143. )
  144. {
  145. if ((*lpCatApi->pCryptCATAdminAcquireContext)(&lpCatApi->hCatAdmin,NULL,0))
  146. {
  147. lpCatApi->hLibMSCat=hLibMSCat;
  148. lpCatApi->hLibWinTrust=hLibWinTrust;
  149. lpCatApi->bInitialized=TRUE;
  150. }
  151. }
  152. }
  153. if (!lpCatApi->bInitialized)
  154. {
  155. FreeLibrary(hLibMSCat);
  156. FreeLibrary(hLibWinTrust);
  157. }
  158. SetErrorMode(uiOldErrorMode);
  159. return lpCatApi->bInitialized;
  160. }
  161. BOOL ReleaseCATAPI(LPCATAPI lpCatApi)
  162. {
  163. DDASSERT(lpCatApi!=NULL);
  164. if (lpCatApi->bInitialized)
  165. {
  166. (*lpCatApi->pCryptCATAdminReleaseContext)(lpCatApi->hCatAdmin, 0);
  167. FreeLibrary(lpCatApi->hLibMSCat);
  168. FreeLibrary(lpCatApi->hLibWinTrust);
  169. ZeroMemory(lpCatApi, sizeof(CATAPI));
  170. return TRUE;
  171. }
  172. return FALSE;
  173. }
  174. //========================================================================
  175. //
  176. // _strstr
  177. //
  178. // String-in-string function, written to avoid RTL inclusion necessity.
  179. //
  180. //========================================================================
  181. char *_strstr(char *s1, char *s2)
  182. {
  183. if (s1 && s2)
  184. {
  185. while (*s1)
  186. {
  187. char *p1=s1;
  188. char *p2=s2;
  189. while (*p2 && (*p1==*p2))
  190. {
  191. p1++;
  192. p2++;
  193. }
  194. if (*p2==0)
  195. return s1;
  196. s1++;
  197. }
  198. }
  199. return NULL;
  200. }
  201. //***&&*%**!!ing c runtime
  202. DWORD _atoi(char * p)
  203. {
  204. DWORD dw=0;
  205. while ((*p >= '0' && *p <= '9') || (*p >= 'A' && *p <= 'F') || (*p >= 'A' && *p <= 'F'))
  206. {
  207. dw = dw*16;
  208. if (*p >= 'a')
  209. dw += *p-'a' + 10;
  210. else if (*p >= 'A')
  211. dw += *p-'A' + 10;
  212. else
  213. dw += *p-'0';
  214. p++;
  215. }
  216. return dw;
  217. }
  218. char *FindLast(char * s, char c)
  219. {
  220. char * pFound=0;
  221. if (s)
  222. {
  223. while (*s)
  224. {
  225. if (*s == c)
  226. pFound = s;
  227. s++;
  228. }
  229. }
  230. return pFound;
  231. }
  232. //========================================================================
  233. // hard-coded vendor IDs
  234. //========================================================================
  235. #define VEN_3DFX "VEN_121A"
  236. #define VEN_3DFXVOODOO1 "VEN_121A&DEV_0001"
  237. #define VEN_POWERVR "VEN_1033"
  238. #ifdef WIN95
  239. void GetFileVersionData (D3DADAPTER_IDENTIFIER8* pDI)
  240. {
  241. void * buffer;
  242. VS_FIXEDFILEINFO * verinfo;
  243. DWORD dwSize;
  244. DWORD dwHi,dwLo;
  245. //Failure means 0 returned
  246. pDI->DriverVersion.HighPart = 0;
  247. pDI->DriverVersion.LowPart = 0;
  248. dwSize = GetFileVersionInfoSize (pDI->Driver, 0);
  249. if (!dwSize)
  250. {
  251. return;
  252. }
  253. buffer=MemAlloc(dwSize);
  254. if (!buffer)
  255. {
  256. return;
  257. }
  258. if (!GetFileVersionInfo(pDI->Driver, 0, dwSize, buffer))
  259. {
  260. MemFree(buffer);
  261. return;
  262. }
  263. if (!VerQueryValue(buffer, "\\", (void **)&verinfo, (UINT *)&dwSize))
  264. {
  265. MemFree(buffer);
  266. return;
  267. }
  268. pDI->DriverVersion.HighPart = verinfo->dwFileVersionMS;
  269. pDI->DriverVersion.LowPart = verinfo->dwFileVersionLS;
  270. MemFree(buffer);
  271. }
  272. extern HRESULT _GetDriverInfoFromRegistry(char *szClass, char *szClassNot, char *szVendor, D3DADAPTER_IDENTIFIER8* pDI, char *szDeviceID);
  273. /*
  274. * following are all the 9x-specific version functions
  275. */
  276. void GetHALName(char* pDriverName, D3DADAPTER_IDENTIFIER8* pDI)
  277. {
  278. pDI->Driver[0] = '\0';
  279. D3D8GetHALName(pDriverName, pDI->Driver);
  280. }
  281. BOOL CheckPowerVR(D3DADAPTER_IDENTIFIER8* pDI)
  282. {
  283. #if 0
  284. BOOL bFound=FALSE;
  285. HKEY hKey;
  286. DWORD dwSize;
  287. DWORD dwType;
  288. if (pdrv->dwFlags & DDRAWI_SECONDARYDRIVERLOADED)
  289. {
  290. /*
  291. * Any secondary driver information in the registry at all? (assert this is true)
  292. */
  293. if (ERROR_SUCCESS == RegOpenKey(HKEY_LOCAL_MACHINE,
  294. REGSTR_PATH_SECONDARY,
  295. &hKey))
  296. {
  297. /*
  298. * Extract the name of the secondary driver's DLL. (assert this works)
  299. */
  300. dwSize = sizeof(pDI->di.szDriver) - 1;
  301. if (ERROR_SUCCESS == RegQueryValueEx(hKey,
  302. REGSTR_VALUE_SECONDARY_DRIVERNAME,
  303. NULL,
  304. &dwType,
  305. pDI->di.szDriver,
  306. &dwSize))
  307. {
  308. if (REG_SZ == dwType)
  309. {
  310. GetFileVersionData(pDI);
  311. }
  312. }
  313. RegCloseKey(hKey);
  314. }
  315. if (SUCCEEDED(_GetDriverInfoFromRegistry(NULL, "Display", VEN_POWERVR, pDI)))
  316. {
  317. //got PVR data...
  318. bFound = TRUE;
  319. }
  320. }
  321. return bFound;
  322. #endif
  323. return TRUE;
  324. }
  325. HRESULT Check3Dfx (D3DADAPTER_IDENTIFIER8* pDI)
  326. {
  327. HRESULT hr = S_OK;
  328. char szDeviceID[MAX_DDDEVICEID_STRING];
  329. if (FAILED(_GetDriverInfoFromRegistry(NULL, "Display", VEN_3DFX, pDI, szDeviceID)))
  330. {
  331. DPF_ERR("Couldn't get registry data for this device");
  332. hr = E_FAIL;
  333. }
  334. return hr;
  335. }
  336. HRESULT GetDriverInfoFromRegistry(char *szClass, char *szClassNot, char *szVendor, D3DADAPTER_IDENTIFIER8* pDI, char *szDeviceID)
  337. {
  338. return _GetDriverInfoFromRegistry(szClass, szClassNot, szVendor, pDI, szDeviceID);
  339. }
  340. /*
  341. * Given a DISPLAY_DEVICE, get driver name
  342. * NOTE::: THIS FUNCTION NUKES THE DISPLAY_DEVICE.DeviceKey STRING!!!!
  343. */
  344. void GetWin9XDriverName(DISPLAY_DEVICEA * pdd, LPSTR pDrvName)
  345. {
  346. HKEY hKey;
  347. lstrcat(pdd->DeviceKey, "\\DEFAULT");
  348. if (ERROR_SUCCESS == RegOpenKeyEx(
  349. HKEY_LOCAL_MACHINE,
  350. pdd->DeviceKey,
  351. 0,
  352. KEY_QUERY_VALUE ,
  353. &hKey))
  354. {
  355. DWORD dwSize = MAX_DDDEVICEID_STRING;
  356. DWORD dwType = 0;
  357. RegQueryValueEx(hKey,
  358. TEXT("drv"),
  359. NULL,
  360. &dwType,
  361. pDrvName,
  362. &dwSize);
  363. RegCloseKey(hKey);
  364. }
  365. }
  366. #else //win95
  367. HRESULT Check3Dfx(D3DADAPTER_IDENTIFIER8* pDI)
  368. {
  369. return E_FAIL;
  370. }
  371. HRESULT GetDriverInfoFromRegistry(char *szClass, char *szClassNot, char *szVendor, D3DADAPTER_IDENTIFIER8* pDI, char *szDeviceID)
  372. {
  373. return E_FAIL;
  374. }
  375. /*
  376. * Given a DISPLAY_DEVICE, get driver name, assuming winnt5
  377. * NOTE::: THIS FUNCTION NUKES THE DISPLAY_DEVICE.DeviceKey STRING!!!!
  378. */
  379. void GetNTDriverNameAndVersion(DISPLAY_DEVICEA * pdd, D3DADAPTER_IDENTIFIER8* pDI)
  380. {
  381. HKEY hKey;
  382. void* buffer;
  383. DWORD dwSize;
  384. VS_FIXEDFILEINFO* verinfo;
  385. //
  386. // old style to determine display driver...returns name of miniport!
  387. //
  388. char * pTemp;
  389. // The device key has the form blah\blah\services\<devicekey>\DeviceN
  390. // So we back up one node:
  391. if ((pTemp = FindLast(pdd->DeviceKey,'\\')))
  392. {
  393. char * pTempX;
  394. char cOld=*pTemp;
  395. *pTemp = 0;
  396. //If we back up one node, we'll have the registry key under which the driver is stored. Let's use that!
  397. if ((pTempX = FindLast(pdd->DeviceKey,'\\')))
  398. {
  399. lstrcpyn(pDI->Driver, pTemp+1, sizeof(pDI->Driver));
  400. //ATTENTION No point getting version data without a filname:
  401. //We need a new service or something to get the used display driver name
  402. //GetFileVersionData(pDI);
  403. }
  404. *pTemp=cOld;
  405. }
  406. //
  407. // we can find the display driver in a registry key
  408. //
  409. // note: InstalledDisplayDrivers can contain several entries
  410. // to display drivers Since there is no way to find out which
  411. // one is the active one, we always return the first as being
  412. // the display driver!
  413. //
  414. if (ERROR_SUCCESS == RegOpenKeyEx(
  415. HKEY_LOCAL_MACHINE,
  416. pdd->DeviceKey+18,
  417. 0,
  418. KEY_QUERY_VALUE ,
  419. &hKey))
  420. {
  421. DWORD dwSize = sizeof(pDI->Driver);
  422. DWORD dwType = 0;
  423. if (ERROR_SUCCESS == RegQueryValueEx(hKey,
  424. TEXT("InstalledDisplayDrivers"),
  425. NULL,
  426. &dwType,
  427. pDI->Driver,
  428. &dwSize))
  429. {
  430. lstrcat(pDI->Driver, TEXT(".dll"));
  431. }
  432. RegCloseKey(hKey);
  433. }
  434. // We have the name, now get the version
  435. pDI->DriverVersion.HighPart = 0;
  436. pDI->DriverVersion.LowPart = 0;
  437. dwSize=GetFileVersionInfoSize(pDI->Driver, 0);
  438. if (dwSize == 0)
  439. return;
  440. buffer = MemAlloc(dwSize);
  441. if (buffer == NULL)
  442. return;
  443. if (!GetFileVersionInfo(pDI->Driver, 0, dwSize, buffer))
  444. {
  445. MemFree(buffer);
  446. return;
  447. }
  448. if (!VerQueryValue(buffer, "\\", (void **)&verinfo, (UINT *)&dwSize))
  449. {
  450. MemFree(buffer);
  451. return;
  452. }
  453. pDI->DriverVersion.HighPart = verinfo->dwFileVersionMS;
  454. pDI->DriverVersion.LowPart = verinfo->dwFileVersionLS;
  455. MemFree(buffer);
  456. }
  457. #endif //win95
  458. void GenerateIdentifier(D3DADAPTER_IDENTIFIER8* pDI)
  459. {
  460. LPDWORD pdw;
  461. CopyMemory(&pDI->DeviceIdentifier, &CLSID_DirectDraw, sizeof(pDI->DeviceIdentifier));
  462. //The device IDs get XORed into the whole GUID with the vendor and device ID in the
  463. //first two DWORDs so they don't get XORed with anything else. This makes it
  464. DDASSERT(sizeof(GUID) >= 4*sizeof(DWORD));
  465. pdw = (LPDWORD) &pDI->DeviceIdentifier;
  466. pdw[0] ^= pDI->VendorId;
  467. pdw[1] ^= pDI->DeviceId;
  468. pdw[2] ^= pDI->SubSysId;
  469. pdw[3] ^= pDI->Revision;
  470. // The driver version gets XORed into the last two DWORDs of the GUID:
  471. pdw[2] ^= pDI->DriverVersion.LowPart;
  472. pdw[3] ^= pDI->DriverVersion.HighPart;
  473. }
  474. void ParseDeviceId(D3DADAPTER_IDENTIFIER8* pDI, char *szDeviceID)
  475. {
  476. char * p;
  477. DPF(5,"Parsing %s",szDeviceID);
  478. pDI->VendorId = 0;
  479. pDI->DeviceId = 0;
  480. pDI->SubSysId = 0;
  481. pDI->Revision = 0;
  482. if (p =_strstr(szDeviceID, "VEN_"))
  483. pDI->VendorId = _atoi(p + 4);
  484. if (p = _strstr(szDeviceID, "DEV_"))
  485. pDI->DeviceId = _atoi(p + 4);
  486. if (p = _strstr(szDeviceID, "SUBSYS_"))
  487. pDI->SubSysId = _atoi(p + 7);
  488. if (p = _strstr(szDeviceID, "REV_"))
  489. pDI->Revision = _atoi(p + 4);
  490. }
  491. void GetAdapterInfo(char* pDriverName, D3DADAPTER_IDENTIFIER8* pDI, BOOL bDisplayDriver, BOOL bGuidOnly, BOOL bDriverName)
  492. {
  493. HRESULT hr = S_OK;
  494. int n;
  495. DISPLAY_DEVICEA dd;
  496. BOOL bFound;
  497. char szDeviceID[MAX_DDDEVICEID_STRING];
  498. #ifndef WINNT
  499. static char szWin9xName[MAX_DDDEVICEID_STRING];
  500. #endif
  501. memset(pDI, 0, sizeof(*pDI));
  502. szDeviceID[0] = 0;
  503. #ifndef WINNT
  504. // On Win9X, it's pretty expensive to get the driver name, so we
  505. // only want to get it when we really need it
  506. szWin9xName[0] = '\0';
  507. if (bDriverName)
  508. {
  509. GetHALName(pDriverName, pDI);
  510. GetFileVersionData(pDI);
  511. }
  512. #endif
  513. // If it's a 3dfx, it's easy
  514. if (!bDisplayDriver)
  515. {
  516. hr = Check3Dfx(pDI);
  517. }
  518. else
  519. {
  520. // Not a 3dfx. Next step: Figure out which display device we
  521. // really are and get description string for it
  522. ZeroMemory(&dd, sizeof(dd));
  523. dd.cb = sizeof(dd);
  524. bFound=FALSE;
  525. for(n=0; xxxEnumDisplayDevicesA(NULL, n, &dd, 0); n++)
  526. {
  527. if (0 == _stricmp(dd.DeviceName, pDriverName))
  528. {
  529. // Found the device. Now we can get some data for it.
  530. lstrcpyn(pDI->Description, dd.DeviceString, sizeof(pDI->Description));
  531. lstrcpyn(szDeviceID, dd.DeviceID, sizeof(szDeviceID));
  532. bFound = TRUE;
  533. #ifdef WINNT
  534. GetNTDriverNameAndVersion(&dd,pDI);
  535. #else
  536. GetWin9XDriverName(&dd, szWin9xName);
  537. if (pDI->Driver[0] == '\0')
  538. {
  539. lstrcpyn(pDI->Driver, szWin9xName, sizeof(pDI->Driver));
  540. }
  541. #endif
  542. break;
  543. }
  544. ZeroMemory(&dd, sizeof(dd));
  545. dd.cb = sizeof(dd);
  546. }
  547. if (!bFound)
  548. {
  549. // Didn't find it: xxxEnumDisplayDevices failed, i.e. we're on 9x or NT4,
  550. if (FAILED(GetDriverInfoFromRegistry("Display", NULL, NULL, pDI, szDeviceID)))
  551. {
  552. return;
  553. }
  554. }
  555. }
  556. if (SUCCEEDED(hr))
  557. {
  558. ParseDeviceId(pDI, szDeviceID);
  559. // Finally, for the primary only, check if a PowerVR is in and functioning
  560. #if 0
  561. if (0 == (dwFlags & DDGDI_GETHOSTIDENTIFIER))
  562. {
  563. if (IsVGADevice(pdrv->cDriverName) && CheckPowerVR(pDI))
  564. {
  565. ParseDeviceId(pDI, szDeviceID);
  566. }
  567. }
  568. #endif
  569. // Munge driver version and ID into the identifier GUID.
  570. GenerateIdentifier(pDI);
  571. // Now get the WHQL level
  572. if (!bGuidOnly)
  573. {
  574. #ifdef WINNT
  575. pDI->WHQLLevel = GetWHQLLevel((LPTSTR)pDI->Driver, NULL);
  576. #else
  577. pDI->WHQLLevel = GetWHQLLevel((LPTSTR)pDI->Driver, szWin9xName);
  578. #endif
  579. }
  580. else
  581. {
  582. pDI->WHQLLevel = 0;
  583. }
  584. }
  585. }
  586. /*
  587. * Voodoo1GoodToGo
  588. *
  589. * The Voodoo 1 driver will succeed the CreateDC call on Voodoo 2, Voodoo 3,
  590. * or Banshee hardware, but if we use the driver beyond that it will hang
  591. * the hardware. This is a work around to not enumerate a Voodoo 1
  592. * driver if the hardware isn't there.
  593. *
  594. * To our knowledge, only two guids were ever used to enumerate Voodoo1
  595. * hardware, so we will look for those guids and assume that anything else
  596. * doesn't need to be checked.
  597. */
  598. BOOL Voodoo1GoodToGo(GUID * pGuid)
  599. {
  600. D3DADAPTER_IDENTIFIER8 DI;
  601. if (IsEqualIID(pGuid, &guidVoodoo1A) || IsEqualIID(pGuid, &guidVoodoo1B))
  602. {
  603. #ifdef WIN95
  604. char szDeviceID[MAX_DDDEVICEID_STRING];
  605. /*
  606. * Now search the hardware enum key to see if Voodoo 1 hardware exists
  607. */
  608. if (FAILED(_GetDriverInfoFromRegistry(NULL, "Display", VEN_3DFXVOODOO1, &DI, szDeviceID)))
  609. {
  610. return FALSE;
  611. }
  612. #else
  613. return FALSE;
  614. #endif
  615. }
  616. return TRUE;
  617. }
  618. #ifndef WINNT
  619. /****************************************************************************
  620. *
  621. * FileIsSignedOld
  622. *
  623. * find win95 style of signature
  624. *
  625. ****************************************************************************/
  626. BOOL FileIsSignedOld(LPTSTR lpszFile)
  627. {
  628. typedef struct tagIMAGE_DOS_HEADER // DOS .EXE header
  629. {
  630. WORD e_magic; // Magic number
  631. WORD e_cblp; // Bytes on last page of file
  632. WORD e_cp; // Pages in file
  633. WORD e_crlc; // Relocations
  634. WORD e_cparhdr; // Size of header in paragraphs
  635. WORD e_minalloc; // Minimum extra paragraphs needed
  636. WORD e_maxalloc; // Maximum extra paragraphs needed
  637. WORD e_ss; // Initial (relative) SS value
  638. WORD e_sp; // Initial SP value
  639. WORD e_csum; // Checksum
  640. WORD e_ip; // Initial IP value
  641. WORD e_cs; // Initial (relative) CS value
  642. WORD e_lfarlc; // File address of relocation table
  643. WORD e_ovno; // Overlay number
  644. WORD e_res[4]; // Reserved words
  645. WORD e_oemid; // OEM identifier (for e_oeminfo)
  646. WORD e_oeminfo; // OEM information; e_oemid specific
  647. WORD e_res2[10]; // Reserved words
  648. LONG e_lfanew; // File address of new exe header
  649. } IMAGE_DOS_HEADER, * PIMAGE_DOS_HEADER, FAR* LPIMAGE_DOS_HEADER;
  650. typedef struct tagIMAGE_OS2_HEADER // OS/2 .EXE header
  651. {
  652. WORD ne_magic; // Magic number
  653. CHAR ne_ver; // Version number
  654. CHAR ne_rev; // Revision number
  655. WORD ne_enttab; // Offset of Entry Table
  656. WORD ne_cbenttab; // Number of bytes in Entry Table
  657. LONG ne_crc; // Checksum of whole file
  658. WORD ne_flags; // Flag word
  659. WORD ne_autodata; // Automatic data segment number
  660. WORD ne_heap; // Initial heap allocation
  661. WORD ne_stack; // Initial stack allocation
  662. LONG ne_csip; // Initial CS:IP setting
  663. LONG ne_sssp; // Initial SS:SP setting
  664. WORD ne_cseg; // Count of file segments
  665. WORD ne_cmod; // Entries in Module Reference Table
  666. WORD ne_cbnrestab; // Size of non-resident name table
  667. WORD ne_segtab; // Offset of Segment Table
  668. WORD ne_rsrctab; // Offset of Resource Table
  669. WORD ne_restab; // Offset of resident name table
  670. WORD ne_modtab; // Offset of Module Reference Table
  671. WORD ne_imptab; // Offset of Imported Names Table
  672. LONG ne_nrestab; // Offset of Non-resident Names Table
  673. WORD ne_cmovent; // Count of movable entries
  674. WORD ne_align; // Segment alignment shift count
  675. WORD ne_cres; // Count of resource segments
  676. BYTE ne_exetyp; // Target Operating system
  677. BYTE ne_flagsothers; // Other .EXE flags
  678. WORD ne_pretthunks; // offset to return thunks
  679. WORD ne_psegrefbytes; // offset to segment ref. bytes
  680. WORD ne_swaparea; // Minimum code swap area size
  681. WORD ne_expver; // Expected Windows version number
  682. } IMAGE_OS2_HEADER, * PIMAGE_OS2_HEADER, FAR* LPIMAGE_OS2_HEADER;
  683. typedef struct tagWINSTUB
  684. {
  685. IMAGE_DOS_HEADER idh;
  686. BYTE rgb[14];
  687. } WINSTUB, * PWINSTUB, FAR* LPWINSTUB;
  688. typedef struct tagFILEINFO
  689. {
  690. BYTE cbInfo[0x120];
  691. } FILEINFO, * PFILEINFO, FAR* LPFILEINFO;
  692. FILEINFO fi;
  693. int nRC;
  694. LPIMAGE_DOS_HEADER lpmz;
  695. LPIMAGE_OS2_HEADER lpne;
  696. BYTE cbInfo[9+32+2];
  697. BOOL IsSigned = FALSE;
  698. OFSTRUCT OpenStruct;
  699. HFILE hFile;
  700. static WINSTUB winstub = {
  701. {
  702. IMAGE_DOS_SIGNATURE, /* magic */
  703. 0, /* bytes on last page - varies */
  704. 0, /* pages in file - varies */
  705. 0, /* relocations */
  706. 4, /* paragraphs in header */
  707. 1, /* min allocation */
  708. 0xFFFF, /* max allocation */
  709. 0, /* initial SS */
  710. 0xB8, /* initial SP */
  711. 0, /* checksum (ha!) */
  712. 0, /* initial IP */
  713. 0, /* initial CS */
  714. 0x40, /* lfarlc */
  715. 0, /* overlay number */
  716. { 0, 0, 0, 0}, /* reserved */
  717. 0, /* oem id */
  718. 0, /* oem info */
  719. 0, /* compiler bug */
  720. { 0}, /* reserved */
  721. 0x80, /* lfanew */
  722. },
  723. {
  724. 0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD,
  725. 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21,
  726. }
  727. };
  728. OpenStruct.cBytes = sizeof(OpenStruct);
  729. lstrcpyn(OpenStruct.szPathName, lpszFile, OFS_MAXPATHNAME);
  730. hFile = OpenFile(lpszFile, &OpenStruct, OF_READ);
  731. if (hFile == HFILE_ERROR)
  732. {
  733. return FALSE;
  734. }
  735. nRC = 0;
  736. ReadFile((HANDLE) hFile, (LPVOID)&fi, sizeof(FILEINFO), &nRC, NULL);
  737. if (nRC != sizeof(FILEINFO))
  738. {
  739. goto FileIsSigned_exit;
  740. }
  741. lpmz = (LPIMAGE_DOS_HEADER)(&fi);
  742. lpne = (LPIMAGE_OS2_HEADER)((WORD)&fi + 0x80);
  743. winstub.idh.e_cblp = lpmz->e_cblp;
  744. winstub.idh.e_cp = lpmz->e_cp;
  745. if (memcmp(&fi, &winstub, sizeof(winstub)) == 0)
  746. {
  747. goto FileIsSigned_exit;
  748. }
  749. memcpy(cbInfo, &((PWINSTUB)(&fi)->cbInfo)->rgb[14], sizeof(cbInfo));
  750. if ((cbInfo[4] != ' ') || // space
  751. (cbInfo[8] != ' ') || // space
  752. (cbInfo[9+32] != '\n') || // return
  753. (cbInfo[9+32+1] != '$')) // Dollar Sign
  754. {
  755. goto FileIsSigned_exit;
  756. }
  757. cbInfo[4] = 0;
  758. cbInfo[8] = 0;
  759. if ((strcmp((const char*)&cbInfo[0], "Cert") != 0) ||
  760. (strcmp((const char*)&cbInfo[5], "DX2") != 0))
  761. {
  762. goto FileIsSigned_exit;
  763. }
  764. IsSigned=TRUE;
  765. FileIsSigned_exit:
  766. _lclose(hFile);
  767. return IsSigned;
  768. }
  769. #endif
  770. /*
  771. * GetWHQLLevel - On Win95, look for old stamp only. On Win2000, use digital
  772. * signature only. On Win98, look for old stamp first, then digital signature
  773. * if no old stamp.
  774. *
  775. * return 0 -- unsigned or uncertified
  776. * return 1 -- driver certified
  777. * return 1997 -- driver certified, PC97 compliant...
  778. * return 1998...
  779. *
  780. *
  781. * arguments:
  782. *
  783. * lpszDriver----Path of driver file
  784. *
  785. */
  786. DWORD GetWHQLLevel(LPTSTR lpszDriver, LPSTR lpszWin9xDriver)
  787. {
  788. TCHAR szTmp[MAX_PATH];
  789. DWORD dwWhqlLevel = 0;
  790. // here we should rather call
  791. if (GetSystemDirectory(szTmp, MAX_PATH-lstrlen(lpszDriver)-2)==0)
  792. return 0;
  793. lstrcat(szTmp, TEXT("\\"));
  794. lstrcat(szTmp, lpszDriver);
  795. _tcslwr(szTmp);
  796. //
  797. // Look for a digital signature
  798. //
  799. dwWhqlLevel = IsFileDigitallySigned(szTmp);
  800. if (dwWhqlLevel != 0)
  801. {
  802. return dwWhqlLevel;
  803. }
  804. #ifndef WINNT
  805. // It wasn't digitally signed, but it may still have been signed
  806. // the old way. On Win9X, however, lpszDriver actually contains the
  807. // 32 bit HAL name rather than the display driver, but we typically only
  808. // signed the display driver, so we should use lpszWin9xDriver.
  809. if (lpszWin9xDriver[0] != '\0')
  810. {
  811. GetSystemDirectory(szTmp, MAX_PATH-lstrlen(lpszWin9xDriver)-2);
  812. lstrcat(szTmp, TEXT("\\"));
  813. lstrcat(szTmp, lpszWin9xDriver);
  814. }
  815. else
  816. {
  817. GetSystemDirectory(szTmp, MAX_PATH-lstrlen(lpszDriver)-2);
  818. lstrcat(szTmp, TEXT("\\"));
  819. lstrcat(szTmp, lpszDriver);
  820. }
  821. if (FileIsSignedOld(szTmp))
  822. {
  823. return 1;
  824. }
  825. #endif
  826. return 0;
  827. }
  828. DWORD IsFileDigitallySigned(LPTSTR lpszDriver)
  829. {
  830. DWORD dwWHQLLevel=0; // default, driver not certified
  831. CATAPI catapi;
  832. WCHAR *lpFileName;
  833. DRIVER_VER_INFO VerInfo;
  834. TCHAR szBuffer[50];
  835. LPSTR lpAttr;
  836. #ifndef UNICODE
  837. WCHAR wszDriver[MAX_PATH];
  838. MultiByteToWideChar(CP_ACP, 0, lpszDriver, -1, wszDriver, MAX_PATH);
  839. lpFileName = wcsrchr(wszDriver, TEXT('\\'));
  840. if (lpFileName==NULL)
  841. {
  842. lpFileName = wszDriver;
  843. }
  844. else
  845. {
  846. lpFileName++;
  847. }
  848. #else
  849. lpFileName = _tcsrchr(lpszDriver, TEXT('\\'));
  850. if (lpFileName==NULL) lpFileName = lpszDriver;
  851. #endif
  852. //
  853. // try to load and initialize the mscat32.dll and wintrust.dll
  854. // these dlls are not available on win95
  855. //
  856. if (InitCATAPI(&catapi))
  857. {
  858. HANDLE hFile;
  859. DWORD cbHashSize=0;
  860. BYTE *pbHash;
  861. BOOL bResult;
  862. //
  863. // create a handle to our driver, because cat api wants handle to file
  864. //
  865. hFile = CreateFile(lpszDriver,
  866. GENERIC_READ,
  867. FILE_SHARE_READ | FILE_SHARE_WRITE,
  868. 0,
  869. OPEN_EXISTING,
  870. FILE_ATTRIBUTE_NORMAL,
  871. 0
  872. );
  873. if (hFile!=INVALID_HANDLE_VALUE)
  874. {
  875. // first query hash size...
  876. bResult=(*catapi.pCryptCATAdminCalcHashFromFileHandle)(hFile,
  877. &cbHashSize,
  878. NULL,
  879. 0);
  880. pbHash=NULL;
  881. if (bResult)
  882. {
  883. // allocate hash
  884. pbHash = MemAlloc(cbHashSize);
  885. }
  886. if (pbHash!=NULL)
  887. {
  888. HCATINFO hPrevCat=NULL;
  889. HANDLE hCatalog=NULL;
  890. WINTRUST_DATA WinTrustData;
  891. WINTRUST_CATALOG_INFO WinTrustCatalogInfo;
  892. GUID guidSubSystemDriver = DRIVER_ACTION_VERIFY;
  893. CRYPTCATATTRIBUTE *lpCat = NULL;
  894. //
  895. // Now get the hash for our file
  896. //
  897. bResult=(*catapi.pCryptCATAdminCalcHashFromFileHandle)(hFile,
  898. &cbHashSize,
  899. pbHash,
  900. 0);
  901. if (bResult)
  902. {
  903. hCatalog=(*catapi.pCryptCATAdminEnumCatalogFromHash)(
  904. catapi.hCatAdmin,
  905. pbHash,
  906. cbHashSize,
  907. 0,
  908. &hPrevCat);
  909. }
  910. //
  911. // Initialize the structures that
  912. // will be used later on in calls to WinVerifyTrust.
  913. //
  914. ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA));
  915. WinTrustData.cbStruct = sizeof(WINTRUST_DATA);
  916. WinTrustData.dwUIChoice = WTD_UI_NONE;
  917. WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
  918. WinTrustData.dwUnionChoice = WTD_CHOICE_CATALOG;
  919. WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE;
  920. WinTrustData.pPolicyCallbackData = (LPVOID)&VerInfo;
  921. ZeroMemory(&VerInfo, sizeof(DRIVER_VER_INFO));
  922. VerInfo.cbStruct = sizeof(DRIVER_VER_INFO);
  923. WinTrustData.pCatalog = &WinTrustCatalogInfo;
  924. ZeroMemory(&WinTrustCatalogInfo, sizeof(WINTRUST_CATALOG_INFO));
  925. WinTrustCatalogInfo.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
  926. WinTrustCatalogInfo.pbCalculatedFileHash = pbHash;
  927. WinTrustCatalogInfo.cbCalculatedFileHash = cbHashSize;
  928. WinTrustCatalogInfo.pcwszMemberTag = lpFileName;
  929. while (hCatalog)
  930. {
  931. CATALOG_INFO CatInfo;
  932. ZeroMemory(&CatInfo, sizeof(CATALOG_INFO));
  933. CatInfo.cbStruct = sizeof(CATALOG_INFO);
  934. if ((*catapi.pCryptCATCatalogInfoFromContext)(hCatalog, &CatInfo, 0))
  935. {
  936. HRESULT hRes;
  937. WinTrustCatalogInfo.pcwszCatalogFilePath = CatInfo.wszCatalogFile;
  938. // Now verify that the file is an actual member of the catalog.
  939. hRes = (*catapi.pWinVerifyTrust)
  940. (NULL, &guidSubSystemDriver, &WinTrustData);
  941. if (hRes == ERROR_SUCCESS)
  942. {
  943. //
  944. // Our driver is certified! Now see if the cat
  945. // info contains the WHQL level
  946. //
  947. CRYPTCATATTRIBUTE *lpCat = NULL;
  948. HANDLE hCat;
  949. dwWHQLLevel=1; // return "certified"
  950. hCat = (*catapi.pCryptCATOpen)(CatInfo.wszCatalogFile, (DWORD)CRYPTCAT_OPEN_EXISTING, (HCRYPTPROV)NULL, 0, 0);
  951. lpCat = (*catapi.pCryptCATGetCatAttrInfo) (hCat, L"KV_DISPLAY");
  952. if (lpCat != NULL)
  953. {
  954. WideCharToMultiByte(CP_ACP, 0, (PUSHORT)lpCat->pbValue, -1, szBuffer, 50, NULL, NULL);
  955. // The value looks like "1:yyyy-mm-dd".
  956. lpAttr = _strstr(szBuffer, ":");
  957. lpAttr++;
  958. lpAttr[4] = '\0';
  959. dwWHQLLevel = atoi(lpAttr) * 0x10000;
  960. lpAttr[7] = '\0';
  961. dwWHQLLevel |= atoi(&lpAttr[5]) * 0x100;
  962. dwWHQLLevel |= atoi(&lpAttr[8]);
  963. }
  964. (*catapi.pCryptCATClose)(hCat);
  965. break;
  966. }
  967. }
  968. //
  969. // iterate through catalogs...
  970. //
  971. hPrevCat=hCatalog;
  972. hCatalog=(*catapi.pCryptCATAdminEnumCatalogFromHash)(
  973. catapi.hCatAdmin,
  974. pbHash,
  975. cbHashSize,
  976. 0,
  977. &hPrevCat);
  978. }
  979. //
  980. // we might have to free a catalog context!
  981. //
  982. if (hCatalog)
  983. {
  984. (*catapi.pCryptCATAdminReleaseCatalogContext)
  985. (catapi.hCatAdmin, hCatalog, 0);
  986. }
  987. //
  988. // free hash
  989. //
  990. MemFree(pbHash);
  991. }
  992. CloseHandle(hFile);
  993. }
  994. }
  995. ReleaseCATAPI(&catapi);
  996. return dwWHQLLevel;
  997. }