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.

1852 lines
68 KiB

  1. /****************************************************************************
  2. *
  3. * File: fileinfo.cpp
  4. * Project: DxDiag (DirectX Diagnostic Tool)
  5. * Author: Mike Anderson (manders@microsoft.com)
  6. * Purpose: Gather information about files on this machine
  7. *
  8. * (C) Copyright 1998 Microsoft Corp. All rights reserved.
  9. *
  10. ****************************************************************************/
  11. #include <tchar.h>
  12. #include <Windows.h>
  13. #include <mmsystem.h>
  14. #include <stdio.h>
  15. #include <capi.h>
  16. #include <softpub.h>
  17. #include <winsock.h>
  18. #include "sysinfo.h" // for BIsPlatformNT
  19. #include "fileinfo.h"
  20. #include "resource.h"
  21. // MsCat32.dll function prototypes
  22. typedef BOOL (WINAPI* PfnCryptCATAdminAcquireContext)(OUT HCATADMIN *phCatAdmin,
  23. IN const GUID *pgSubsystem,
  24. IN DWORD dwFlags);
  25. typedef BOOL (WINAPI* PfnCryptCATAdminReleaseContext)(IN HCATADMIN hCatAdmin,
  26. IN DWORD dwFlags);
  27. typedef BOOL (WINAPI* PfnCryptCATAdminReleaseCatalogContext)(IN HCATADMIN hCatAdmin,
  28. IN HCATINFO hCatInfo,
  29. IN DWORD dwFlags);
  30. typedef BOOL (WINAPI* PfnCryptCATCatalogInfoFromContext)(IN HCATINFO hCatInfo,
  31. IN OUT CATALOG_INFO *psCatInfo,
  32. IN DWORD dwFlags);
  33. typedef HCATINFO (WINAPI* PfnCryptCATAdminEnumCatalogFromHash)(IN HCATADMIN hCatAdmin,
  34. IN BYTE *pbHash,
  35. IN DWORD cbHash,
  36. IN DWORD dwFlags,
  37. IN OUT HCATINFO *phPrevCatInfo);
  38. typedef BOOL (WINAPI* PfnIsCatalogFile)(IN OPTIONAL HANDLE hFile,
  39. IN OPTIONAL WCHAR *pwszFileName);
  40. typedef BOOL (WINAPI* PfnCryptCATAdminCalcHashFromFileHandle)(IN HANDLE hFile,
  41. IN OUT DWORD *pcbHash,
  42. OUT OPTIONAL BYTE *pbHash,
  43. IN DWORD dwFlags);
  44. // WinTrust.dll function prototypes
  45. typedef HRESULT (WINAPI* PfnWinVerifyTrust)(HWND hWnd,
  46. GUID *pgActionID,
  47. WINTRUST_DATA *pWinTrustData);
  48. // Crypt32.dll function prototypes
  49. typedef BOOL (WINAPI* PfnCertFreeCertificateContext)(IN PCCERT_CONTEXT pCertContext);
  50. struct DigiSignData
  51. {
  52. BOOL bInitialized;
  53. BOOL bFailed;
  54. // Need to LoadLibrary/GetProcAddress for mscat32 APIs since they
  55. // don't exist on Win95
  56. HINSTANCE hInstMsCat32;
  57. PfnCryptCATAdminAcquireContext CryptCATAdminAcquireContext;
  58. PfnCryptCATAdminReleaseContext CryptCATAdminReleaseContext;
  59. PfnCryptCATAdminReleaseCatalogContext CryptCATAdminReleaseCatalogContext;
  60. PfnCryptCATCatalogInfoFromContext CryptCATCatalogInfoFromContext;
  61. PfnCryptCATAdminEnumCatalogFromHash CryptCATAdminEnumCatalogFromHash;
  62. PfnIsCatalogFile IsCatalogFile;
  63. PfnCryptCATAdminCalcHashFromFileHandle CryptCATAdminCalcHashFromFileHandle;
  64. // Ditto for wintrust.dll APIs
  65. HINSTANCE hInstWinTrust;
  66. PfnWinVerifyTrust WinVerifyTrust;
  67. // Ditto for cypt32.dll APIs
  68. HINSTANCE hInstCrypt32;
  69. PfnCertFreeCertificateContext CertFreeCertificateContext;
  70. HCATADMIN hCatAdmin;
  71. };
  72. static DigiSignData s_dsd;
  73. static BOOL GetMediaPlayerFolder(TCHAR* pszPath);
  74. static BOOL VerifyFileNode(TCHAR* lpFileName, TCHAR* lpDirName);
  75. static BOOL VerifyIsFileSigned(LPTSTR pcszMatchFile, PDRIVER_VER_INFO lpVerInfo);
  76. static BOOL InitDigiSignData(VOID);
  77. static BOOL IsFileDigitallySigned(TCHAR* pszFile);
  78. static BOOL IsBadWin95Winsock( FileInfo* pFileInfo );
  79. /****************************************************************************
  80. *
  81. * GetProgramFilesFolder
  82. *
  83. ****************************************************************************/
  84. VOID InitFileInfo()
  85. {
  86. ZeroMemory(&s_dsd, sizeof(s_dsd));
  87. s_dsd.bFailed = FALSE;
  88. s_dsd.bInitialized = FALSE;
  89. }
  90. /****************************************************************************
  91. *
  92. * GetProgramFilesFolder
  93. *
  94. ****************************************************************************/
  95. BOOL GetProgramFilesFolder(TCHAR* pszPath)
  96. {
  97. HKEY hkey;
  98. DWORD dwType;
  99. DWORD cb;
  100. if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  101. TEXT("Software\\Microsoft\\Windows\\CurrentVersion"), 0, KEY_READ, &hkey))
  102. {
  103. return FALSE;
  104. }
  105. cb = MAX_PATH;
  106. RegQueryValueEx(hkey, TEXT("ProgramFilesDir"), NULL, &dwType, (LPBYTE)pszPath, &cb);
  107. RegCloseKey(hkey);
  108. if (cb == 0)
  109. return FALSE;
  110. return TRUE;
  111. }
  112. /****************************************************************************
  113. *
  114. * FormatFileTime
  115. *
  116. ****************************************************************************/
  117. VOID FormatFileTime(FILETIME* pUTCFileTime, TCHAR* pszDateLocal, TCHAR* pszDateEnglish)
  118. {
  119. FILETIME fileTimeLocal;
  120. SYSTEMTIME systemTime;
  121. TCHAR szTime[100];
  122. FileTimeToLocalFileTime(pUTCFileTime, &fileTimeLocal);
  123. FileTimeToSystemTime(&fileTimeLocal, &systemTime);
  124. wsprintf(pszDateEnglish, TEXT("%d/%d/%04d %02d:%02d:%02d"),
  125. systemTime.wMonth, systemTime.wDay, systemTime.wYear,
  126. systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
  127. GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &systemTime, NULL, pszDateLocal, 30);
  128. wsprintf(szTime, TEXT(" %02d:%02d:%02d"), systemTime.wHour,
  129. systemTime.wMinute, systemTime.wSecond);
  130. lstrcat(pszDateLocal, szTime);
  131. }
  132. /****************************************************************************
  133. *
  134. * GetMediaPlayerFolder
  135. *
  136. ****************************************************************************/
  137. BOOL GetMediaPlayerFolder(TCHAR* pszPath)
  138. {
  139. HKEY hkey;
  140. DWORD dwType;
  141. DWORD cb;
  142. if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  143. TEXT("Software\\Microsoft\\MediaPlayer"), 0, KEY_READ, &hkey))
  144. {
  145. return FALSE;
  146. }
  147. cb = MAX_PATH;
  148. RegQueryValueEx(hkey, TEXT("Installation Directory"), NULL, &dwType, (LPBYTE)pszPath, &cb);
  149. RegCloseKey(hkey);
  150. if (cb == 0)
  151. return FALSE;
  152. return TRUE;
  153. }
  154. /****************************************************************************
  155. *
  156. * GetDxSetupFolder
  157. *
  158. ****************************************************************************/
  159. BOOL GetDxSetupFolder(TCHAR* pszPath)
  160. {
  161. if (!GetProgramFilesFolder(pszPath))
  162. return FALSE;
  163. lstrcat(pszPath, TEXT("\\DirectX\\Setup"));
  164. return TRUE;
  165. }
  166. /****************************************************************************
  167. *
  168. * GetComponentFiles
  169. *
  170. ****************************************************************************/
  171. HRESULT GetComponentFiles(TCHAR* pszFolder, FileInfo** ppFileInfoFirst,
  172. BOOL bSkipMissingFiles, LONG ids)
  173. {
  174. LONG cch;
  175. FileInfo* pFileInfo;
  176. FileInfo* pFileInfoNew;
  177. LONG iFile;
  178. TCHAR szFile[50];
  179. TCHAR szPath[MAX_PATH];
  180. TCHAR szComponentFiles[2048];
  181. TCHAR* pszFilePos;
  182. TCHAR* pszFilePos2;
  183. TCHAR* pszFirstParen;
  184. FLOAT fStartShipAt;
  185. FLOAT fStopShipAt;
  186. BOOL bDriversDir;
  187. BOOL bNTDriversDir;
  188. BOOL bIgnoreVersionInfo;
  189. BOOL bIgnoreDebug;
  190. BOOL bIgnoreBeta;
  191. BOOL bBDA;
  192. BOOL bNotIA64;
  193. BOOL bOptional;
  194. BOOL bOptionalOnNT;
  195. BOOL bOptionalOnWOW64;
  196. BOOL bIsNT = BIsPlatformNT();
  197. BOOL bIs95 = BIsWin95();
  198. cch = LoadString(NULL, ids, szComponentFiles, 2048);
  199. if (cch == 0 || cch >= 2047)
  200. return E_FAIL;
  201. pszFilePos = szComponentFiles;
  202. for (iFile = 0; ; iFile++)
  203. {
  204. // Stop if we've gone through the whole list
  205. if (pszFilePos == NULL)
  206. break;
  207. // Pull the next file out of the list
  208. pszFilePos2 = _tcsstr(pszFilePos, TEXT(","));
  209. if (pszFilePos2 == NULL)
  210. {
  211. _tcsncpy(szFile, pszFilePos, 50);
  212. szFile[49]=0;
  213. pszFilePos = NULL;
  214. }
  215. else
  216. {
  217. _tcsncpy(szFile, pszFilePos, (DWORD)(pszFilePos2 - pszFilePos));
  218. szFile[pszFilePos2 - pszFilePos] = '\0';
  219. pszFilePos = pszFilePos2 + 1;
  220. }
  221. // Clear file flags
  222. fStartShipAt = 0.0f;
  223. fStopShipAt = 10000.0f;
  224. bDriversDir = FALSE;
  225. bNTDriversDir = FALSE;
  226. bIgnoreVersionInfo = FALSE;
  227. bIgnoreDebug = FALSE;
  228. bIgnoreBeta = FALSE;
  229. bBDA = FALSE;
  230. bNotIA64 = FALSE;
  231. bOptional = FALSE;
  232. bOptionalOnNT = FALSE;
  233. bOptionalOnWOW64 = FALSE;
  234. // Look at file flags, if any
  235. pszFirstParen = _tcsstr(szFile, TEXT("("));
  236. if (pszFirstParen != NULL)
  237. {
  238. // If this file does not exist on NT, and we are running NT, skip it.
  239. if (_tcsstr(pszFirstParen, TEXT("notNT")) != NULL && bIsNT)
  240. continue;
  241. // If this file does not exist on W95, and we are running W95, skip it.
  242. if (_tcsstr(pszFirstParen, TEXT("not95")) != NULL && bIs95)
  243. continue;
  244. // If this file only exists on W95, and we are not running W95, skip it.
  245. // Note: files like vjoyd.vxd may exist on Win98, but DX setup does not
  246. // install them or update them, so we ignore them.
  247. // Note: can't call this "95only" because it would clash with "5only"
  248. if (_tcsstr(pszFirstParen, TEXT("9fiveonly")) != NULL && !bIs95)
  249. continue;
  250. // Check for other flags
  251. if (_tcsstr(pszFirstParen, TEXT("+")) != NULL)
  252. {
  253. if (_tcsstr(pszFirstParen, TEXT("+5")) != NULL)
  254. fStartShipAt = 5.0f;
  255. else if (_tcsstr(pszFirstParen, TEXT("+61")) != NULL)
  256. fStartShipAt = 6.1f;
  257. else if (_tcsstr(pszFirstParen, TEXT("+6")) != NULL)
  258. fStartShipAt = 6.0f;
  259. else if (_tcsstr(pszFirstParen, TEXT("+71")) != NULL)
  260. fStartShipAt = 7.1f;
  261. else if (_tcsstr(pszFirstParen, TEXT("+7")) != NULL)
  262. fStartShipAt = 7.0f;
  263. else if (_tcsstr(pszFirstParen, TEXT("+81")) != NULL)
  264. fStartShipAt = 8.1f;
  265. else if (_tcsstr(pszFirstParen, TEXT("+8")) != NULL)
  266. fStartShipAt = 8.0f;
  267. }
  268. if (_tcsstr(pszFirstParen, TEXT("-")) != NULL)
  269. {
  270. if (_tcsstr(pszFirstParen, TEXT("-5")) != NULL)
  271. fStopShipAt = 5.0f;
  272. else if (_tcsstr(pszFirstParen, TEXT("-61")) != NULL)
  273. fStopShipAt = 6.1f;
  274. else if (_tcsstr(pszFirstParen, TEXT("-6")) != NULL)
  275. fStopShipAt = 6.0f;
  276. else if (_tcsstr(pszFirstParen, TEXT("-71")) != NULL)
  277. fStopShipAt = 7.1f;
  278. else if (_tcsstr(pszFirstParen, TEXT("-7")) != NULL)
  279. fStopShipAt = 7.0f;
  280. else if (_tcsstr(pszFirstParen, TEXT("-81")) != NULL)
  281. fStopShipAt = 8.1f;
  282. else if (_tcsstr(pszFirstParen, TEXT("-8")) != NULL)
  283. fStopShipAt = 8.0f;
  284. }
  285. // Note: can't call this "DriversDir" because it would clash with "NTDriversDir"
  286. if (_tcsstr(pszFirstParen, TEXT("DrivDir")) != NULL)
  287. bDriversDir = TRUE;
  288. if (_tcsstr(pszFirstParen, TEXT("NTDriversDir")) != NULL)
  289. bNTDriversDir = TRUE;
  290. if (_tcsstr(pszFirstParen, TEXT("SkipVer")) != NULL)
  291. bIgnoreVersionInfo = TRUE;
  292. if (_tcsstr(pszFirstParen, TEXT("SkipDebug")) != NULL)
  293. bIgnoreDebug = TRUE;
  294. if (_tcsstr(pszFirstParen, TEXT("SkipBeta")) != NULL)
  295. bIgnoreBeta = TRUE;
  296. if (_tcsstr(pszFirstParen, TEXT("notia64")) != NULL)
  297. bNotIA64 = TRUE;
  298. if (_tcsstr(pszFirstParen, TEXT("optnt")) != NULL)
  299. bOptionalOnNT = TRUE;
  300. else if (_tcsstr(pszFirstParen, TEXT("optwow")) != NULL)
  301. bOptionalOnWOW64 = TRUE;
  302. else if (_tcsstr(pszFirstParen, TEXT("opt")) != NULL)
  303. bOptional = TRUE;
  304. if (_tcsstr(pszFirstParen, TEXT("bda")) != NULL)
  305. {
  306. bBDA = TRUE;
  307. bOptional = TRUE;
  308. bIgnoreVersionInfo = TRUE;
  309. }
  310. // End file name at open parenthesis, if any:
  311. *pszFirstParen = TEXT('\0');
  312. }
  313. pFileInfoNew = new FileInfo;
  314. if (pFileInfoNew == NULL)
  315. return E_OUTOFMEMORY;
  316. ZeroMemory(pFileInfoNew, sizeof(FileInfo));
  317. pFileInfoNew->m_fStartShipAt = fStartShipAt;
  318. pFileInfoNew->m_fStopShipAt = fStopShipAt;
  319. pFileInfoNew->m_bIgnoreVersionInfo = bIgnoreVersionInfo;
  320. pFileInfoNew->m_bIgnoreDebug = bIgnoreDebug;
  321. pFileInfoNew->m_bIgnoreBeta = bIgnoreBeta;
  322. pFileInfoNew->m_bBDA = bBDA;
  323. pFileInfoNew->m_bNotIA64 = bNotIA64;
  324. pFileInfoNew->m_bOptional = bOptional;
  325. pFileInfoNew->m_bOptionalOnNT = bOptionalOnNT;
  326. pFileInfoNew->m_bOptionalOnWOW64 = bOptionalOnWOW64;
  327. lstrcpy(pFileInfoNew->m_szName, szFile);
  328. _tcsncpy(szPath, pszFolder,MAX_PATH);
  329. szPath[MAX_PATH-1]=0;
  330. lstrcat(szPath, TEXT("\\"));
  331. if (bNTDriversDir && bIsNT)
  332. lstrcat(szPath, TEXT("Drivers\\"));
  333. else if (bDriversDir)
  334. lstrcat(szPath, TEXT("..\\System32\\Drivers\\"));
  335. lstrcat(szPath, szFile);
  336. WIN32_FIND_DATA findFileData;
  337. HANDLE hFind = FindFirstFile(szPath, &findFileData);
  338. if (hFind == INVALID_HANDLE_VALUE)
  339. {
  340. if (bSkipMissingFiles)
  341. {
  342. delete pFileInfoNew;
  343. continue;
  344. }
  345. }
  346. else
  347. {
  348. pFileInfoNew->m_bExists = TRUE;
  349. FindClose(hFind);
  350. }
  351. if (pFileInfoNew->m_bExists)
  352. {
  353. pFileInfoNew->m_numBytes = findFileData.nFileSizeLow;
  354. pFileInfoNew->m_FileTime = findFileData.ftLastWriteTime;
  355. FormatFileTime(&findFileData.ftLastWriteTime, pFileInfoNew->m_szDatestampLocal,
  356. pFileInfoNew->m_szDatestamp);
  357. GetFileVersion(szPath, pFileInfoNew->m_szVersion, pFileInfoNew->m_szAttributes,
  358. pFileInfoNew->m_szLanguageLocal, pFileInfoNew->m_szLanguage, &pFileInfoNew->m_bBeta, &pFileInfoNew->m_bDebug);
  359. }
  360. if (*ppFileInfoFirst == NULL)
  361. *ppFileInfoFirst = pFileInfoNew;
  362. else
  363. {
  364. for (pFileInfo = *ppFileInfoFirst;
  365. pFileInfo->m_pFileInfoNext != NULL;
  366. pFileInfo = pFileInfo->m_pFileInfoNext)
  367. {
  368. }
  369. pFileInfo->m_pFileInfoNext = pFileInfoNew;
  370. }
  371. }
  372. return S_OK;
  373. }
  374. /****************************************************************************
  375. *
  376. * DestroyFileList
  377. *
  378. ****************************************************************************/
  379. VOID DestroyFileList(FileInfo* pFileInfoFirst)
  380. {
  381. FileInfo* pFileInfo;
  382. FileInfo* pFileInfoNext;
  383. for (pFileInfo = pFileInfoFirst; pFileInfo != NULL; pFileInfo = pFileInfoNext)
  384. {
  385. pFileInfoNext = pFileInfo->m_pFileInfoNext;
  386. delete pFileInfo;
  387. }
  388. }
  389. /****************************************************************************
  390. *
  391. * GetFileDateAndSize
  392. *
  393. ****************************************************************************/
  394. BOOL GetFileDateAndSize(TCHAR* pszFile, TCHAR* pszDateLocal, TCHAR* pszDateEnglish,
  395. LONG* pnumBytes)
  396. {
  397. WIN32_FIND_DATA findFileData;
  398. HANDLE hFind;
  399. pszDateLocal[0] = '\0';
  400. pszDateEnglish[0] = '\0';
  401. *pnumBytes = 0;
  402. hFind = FindFirstFile(pszFile, &findFileData);
  403. if (hFind == INVALID_HANDLE_VALUE)
  404. return FALSE; // file not found
  405. FindClose(hFind);
  406. *pnumBytes = findFileData.nFileSizeLow;
  407. FormatFileTime(&findFileData.ftLastWriteTime, pszDateLocal, pszDateEnglish);
  408. return TRUE;
  409. }
  410. /****************************************************************************
  411. *
  412. * GetFileVersion
  413. *
  414. ****************************************************************************/
  415. HRESULT GetFileVersion(TCHAR* pszFile, TCHAR* pszVersion, TCHAR* pszAttributes,
  416. TCHAR* pszLanguageLocal, TCHAR* pszLanguage, BOOL* pbBeta, BOOL* pbDebug)
  417. {
  418. UINT cb;
  419. DWORD dwHandle;
  420. BYTE FileVersionBuffer[4096];
  421. VS_FIXEDFILEINFO* pVersion = NULL;
  422. DWORD dwVersionAttribs = 0; // DEBUG, RETAIL, etc.
  423. DWORD* pdwCharSet = NULL;
  424. WORD wLanguage;
  425. LCID lcid;
  426. TCHAR szDebug[100];
  427. TCHAR szRetail[100];
  428. TCHAR szBeta[100];
  429. TCHAR szFinal[100];
  430. TCHAR szCombineFmt[100];
  431. LoadString(NULL, IDS_DEBUG, szDebug, 100);
  432. LoadString(NULL, IDS_RETAIL, szRetail, 100);
  433. LoadString(NULL, IDS_BETA, szBeta, 100);
  434. LoadString(NULL, IDS_FINAL, szFinal, 100);
  435. LoadString(NULL, IDS_ATTRIBCOMBINE, szCombineFmt, 100);
  436. cb = GetFileVersionInfoSize(pszFile, &dwHandle/*ignored*/);
  437. if (cb > 0)
  438. {
  439. if (cb > sizeof(FileVersionBuffer))
  440. cb = sizeof(FileVersionBuffer);
  441. if (GetFileVersionInfo(pszFile, 0, cb, FileVersionBuffer))
  442. {
  443. pVersion = NULL;
  444. if (VerQueryValue(FileVersionBuffer, TEXT("\\"), (VOID**)&pVersion, &cb)
  445. && pVersion != NULL)
  446. {
  447. if (pszVersion != NULL)
  448. {
  449. wsprintf(pszVersion, TEXT("%d.%02d.%02d.%04d"),
  450. HIWORD(pVersion->dwFileVersionMS),
  451. LOWORD(pVersion->dwFileVersionMS),
  452. HIWORD(pVersion->dwFileVersionLS),
  453. LOWORD(pVersion->dwFileVersionLS));
  454. }
  455. if (pszAttributes != NULL)
  456. {
  457. dwVersionAttribs = pVersion->dwFileFlags;
  458. // Bug 18892: work around DPlay 6.0a
  459. if (pVersion->dwFileVersionMS == 0x00040006 &&
  460. (pVersion->dwFileVersionLS == 0x0002016b || // 4.06.02.0363
  461. pVersion->dwFileVersionLS == 0x00020164)) // 4.06.02.0356
  462. {
  463. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  464. }
  465. if (pszVersion != NULL)
  466. {
  467. TCHAR* pszLeaf = _tcsrchr(pszFile, TEXT('\\'));
  468. if( pszLeaf )
  469. {
  470. pszLeaf++;
  471. // Work around several DXMedia files which are incorrectly marked as beta
  472. if (lstrcmp(pszLeaf, TEXT("oleaut32.dll")) == 0)
  473. {
  474. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  475. }
  476. else if (lstrcmp(pszLeaf, TEXT("quartz.dll")) == 0 &&
  477. lstrcmp(pszVersion, TEXT("4.00.96.0729")) == 0)
  478. {
  479. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  480. }
  481. else if (lstrcmp(pszLeaf, TEXT("quartz.vxd")) == 0 &&
  482. lstrcmp(pszVersion, TEXT("4.00.96.0729")) == 0)
  483. {
  484. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  485. }
  486. else if (lstrcmp(pszLeaf, TEXT("mciqtz.drv")) == 0 &&
  487. lstrcmp(pszVersion, TEXT("4.00.96.0729")) == 0)
  488. {
  489. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  490. }
  491. else if (lstrcmp(pszLeaf, TEXT("mciqtz32.dll")) == 0 &&
  492. lstrcmp(pszVersion, TEXT("4.00.96.0729")) == 0)
  493. {
  494. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  495. }
  496. else if (lstrcmp(pszLeaf, TEXT("actmovie.exe")) == 0)
  497. {
  498. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  499. }
  500. else if (lstrcmp(pszLeaf, TEXT("strmdll.dll")) == 0)
  501. {
  502. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  503. }
  504. else if (lstrcmp(pszLeaf, TEXT("unam4ie.exe")) == 0 &&
  505. lstrcmp(pszVersion, TEXT("6.00.02.0902")) == 0)
  506. {
  507. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  508. }
  509. else if (lstrcmp(pszLeaf, TEXT("unam4ie.exe")) == 0 &&
  510. lstrcmp(pszVersion, TEXT("5.01.18.1024")) == 0)
  511. {
  512. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  513. }
  514. else if (lstrcmp(pszLeaf, TEXT("iac25_32.ax")) == 0 &&
  515. lstrcmp(pszVersion, TEXT("2.00.05.0050")) == 0)
  516. {
  517. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  518. }
  519. else if (lstrcmp(pszLeaf, TEXT("iac25_32.ax")) == 0 &&
  520. lstrcmp(pszVersion, TEXT("2.00.05.0052")) == 0)
  521. {
  522. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  523. }
  524. else if (lstrcmp(pszLeaf, TEXT("tm20dec.ax")) == 0)
  525. {
  526. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  527. }
  528. else if (lstrcmp(pszLeaf, TEXT("tm20dec.ax")) == 0 &&
  529. lstrcmp(pszVersion, TEXT("1.00.00.0000")) == 0)
  530. {
  531. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  532. }
  533. else if (lstrcmp(pszLeaf, TEXT("msdxm.ocx")) == 0)
  534. {
  535. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  536. }
  537. else if (lstrcmp(pszLeaf, TEXT("dxmasf.dll")) == 0)
  538. {
  539. dwVersionAttribs &= ~VS_FF_PRERELEASE;
  540. }
  541. else if (lstrcmp(pszLeaf, TEXT("iac25_32.ax")) == 0 &&
  542. lstrcmp(pszVersion, TEXT("2.00.05.0053")) == 0)
  543. {
  544. dwVersionAttribs &= ~VS_FF_PRERELEASE; // Since 350883 got punted
  545. }
  546. }
  547. }
  548. wsprintf(pszAttributes, szCombineFmt,
  549. (dwVersionAttribs & VS_FF_PRERELEASE ? szBeta : szFinal),
  550. (dwVersionAttribs & VS_FF_DEBUG ? szDebug : szRetail));
  551. if (pbBeta != NULL)
  552. *pbBeta = (dwVersionAttribs & VS_FF_PRERELEASE) ? TRUE : FALSE;
  553. if (pbDebug != NULL)
  554. *pbDebug = (dwVersionAttribs & VS_FF_DEBUG) ? TRUE : FALSE;
  555. }
  556. }
  557. if (pszLanguage != NULL)
  558. {
  559. if (VerQueryValue(FileVersionBuffer, TEXT("\\VarFileInfo\\Translation"), (VOID**)&pdwCharSet, &cb)
  560. && pdwCharSet && cb)
  561. {
  562. wLanguage = LOWORD(*pdwCharSet);
  563. lcid = MAKELCID(wLanguage, SORT_DEFAULT);
  564. GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, pszLanguage, 100);
  565. if (pszLanguageLocal != NULL)
  566. {
  567. GetLocaleInfo(lcid, LOCALE_SLANGUAGE, pszLanguageLocal, 100);
  568. // Show "English", not "English (United States)". I can't
  569. // find a better way to do this (such that it localizes properly)
  570. TCHAR* pszSublanguage;
  571. pszSublanguage = _tcsstr(pszLanguageLocal, TEXT(" ("));
  572. if (pszSublanguage != NULL)
  573. *pszSublanguage = '\0';
  574. }
  575. }
  576. }
  577. }
  578. }
  579. else
  580. {
  581. TCHAR* pszLeaf = _tcsrchr(pszFile, TEXT('\\'));
  582. if( pszLeaf )
  583. {
  584. pszLeaf++;
  585. if (DXUtil_strcmpi(pszLeaf, TEXT("vidx16.dll")) == 0)
  586. {
  587. if (pszVersion != NULL)
  588. lstrcpy(pszVersion, TEXT("0.00.00.0000"));
  589. if (pszAttributes != NULL)
  590. {
  591. _sntprintf(pszAttributes, 50, TEXT("%s %s"), szFinal, szRetail);
  592. pszAttributes[49] = 0;
  593. }
  594. if (pszLanguage != NULL)
  595. {
  596. wLanguage = MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US);
  597. lcid = MAKELCID(wLanguage, SORT_DEFAULT);
  598. GetLocaleInfo(lcid, LOCALE_SENGLANGUAGE, pszLanguage, 100);
  599. if (pszLanguageLocal != NULL)
  600. {
  601. GetLocaleInfo(lcid, LOCALE_SLANGUAGE, pszLanguageLocal, 100);
  602. // Show "English", not "English (United States)". I can't
  603. // find a better way to do this (such that it localizes properly)
  604. TCHAR* pszSublanguage;
  605. pszSublanguage = _tcsstr(pszLanguageLocal, TEXT(" ("));
  606. if (pszSublanguage != NULL)
  607. *pszSublanguage = '\0';
  608. }
  609. }
  610. }
  611. }
  612. }
  613. return S_OK;
  614. }
  615. /****************************************************************************
  616. *
  617. * GetLanguageFromFile
  618. *
  619. ****************************************************************************/
  620. WORD GetLanguageFromFile(const TCHAR* pszFileName, const TCHAR* pszPath)
  621. {
  622. BYTE FileVersionBuffer[4096];
  623. DWORD *pdwCharSet;
  624. UINT cb;
  625. DWORD dwHandle;
  626. TCHAR szFileAndPath[MAX_PATH];
  627. WORD wLanguage;
  628. _tcsncpy(szFileAndPath, pszPath, MAX_PATH);
  629. szFileAndPath[MAX_PATH-1] = 0;
  630. lstrcat(szFileAndPath, TEXT("\\"));
  631. if( lstrlen(szFileAndPath) + lstrlen(pszFileName) < MAX_PATH )
  632. lstrcat(szFileAndPath, pszFileName);
  633. memset(FileVersionBuffer, 0, sizeof FileVersionBuffer);
  634. wLanguage = 0;
  635. if (cb = GetFileVersionInfoSize(szFileAndPath, &dwHandle/*ignored*/))
  636. {
  637. cb = (cb <= sizeof FileVersionBuffer ? cb : sizeof FileVersionBuffer);
  638. if (GetFileVersionInfo(szFileAndPath, 0, cb, FileVersionBuffer))
  639. {
  640. pdwCharSet = 0;
  641. if (VerQueryValue(FileVersionBuffer, TEXT("\\VarFileInfo\\Translation"), (void**)&pdwCharSet, &cb)
  642. && pdwCharSet && cb)
  643. {
  644. wLanguage = LOWORD(*pdwCharSet);
  645. }
  646. }
  647. }
  648. return wLanguage;
  649. }
  650. struct DLSVERSION
  651. {
  652. DWORD dwVersionMS;
  653. DWORD dwVersionLS;
  654. };
  655. #define FOURCC_VERS mmioFOURCC('v','e','r','s')
  656. /****************************************************************************
  657. *
  658. * GetRiffFileVersion
  659. *
  660. ****************************************************************************/
  661. HRESULT GetRiffFileVersion(TCHAR* pszFile, TCHAR* pszVersion)
  662. {
  663. MMIOINFO mmio;
  664. MMCKINFO mmck1;
  665. MMCKINFO mmck2;
  666. DLSVERSION dlsver;
  667. HMMIO hDLS;
  668. // DLS file has different version scheme since it's a riff file.
  669. // So retrieve version info from 'vers' chunk.
  670. ZeroMemory(&mmio, sizeof(MMIOINFO));
  671. hDLS = mmioOpen(pszFile,&mmio,MMIO_READ);
  672. if (hDLS == NULL)
  673. {
  674. return E_FAIL;
  675. }
  676. // read riff chunk
  677. ZeroMemory(&mmck1,sizeof(MMCKINFO));
  678. if (mmioDescend(hDLS,
  679. &mmck1,
  680. NULL,
  681. MMIO_FINDRIFF) != MMSYSERR_NOERROR)
  682. {
  683. mmioClose(hDLS,0);
  684. return E_FAIL;
  685. }
  686. ZeroMemory(&mmck2,sizeof(MMCKINFO));
  687. mmck2.ckid = FOURCC_VERS;
  688. if (mmioDescend(hDLS,
  689. &mmck2,
  690. &mmck1,
  691. MMIO_FINDCHUNK) != MMSYSERR_NOERROR)
  692. {
  693. mmioClose(hDLS,0);
  694. return E_FAIL;
  695. }
  696. if (mmioRead(hDLS,
  697. (HPSTR)&dlsver,
  698. sizeof(DLSVERSION)) != sizeof(DLSVERSION))
  699. {
  700. mmioClose(hDLS,0);
  701. return E_FAIL;
  702. }
  703. wsprintf(pszVersion, TEXT("%d.%02d.%02d.%04d"),
  704. HIWORD(dlsver.dwVersionMS),
  705. LOWORD(dlsver.dwVersionMS),
  706. HIWORD(dlsver.dwVersionLS),
  707. LOWORD(dlsver.dwVersionLS));
  708. mmioClose(hDLS,0);
  709. return S_OK;
  710. }
  711. /****************************************************************************
  712. *
  713. * FileIsSigned - use digital signature on all OSs
  714. *
  715. ****************************************************************************/
  716. VOID FileIsSigned(LPTSTR lpszFile, BOOL* pbSigned, BOOL* pbIsValid)
  717. {
  718. // Look for digital sig
  719. if( !InitDigiSignData() )
  720. {
  721. if( pbSigned )
  722. *pbSigned = FALSE;
  723. if( pbIsValid )
  724. *pbIsValid = FALSE;
  725. return;
  726. }
  727. if( pbSigned )
  728. *pbSigned = IsFileDigitallySigned(lpszFile);
  729. if( pbIsValid )
  730. *pbIsValid = TRUE;
  731. }
  732. /****************************************************************************
  733. *
  734. * InitDigiSignData
  735. *
  736. ****************************************************************************/
  737. BOOL InitDigiSignData(VOID)
  738. {
  739. TCHAR szPath[MAX_PATH];
  740. if( s_dsd.bInitialized )
  741. return TRUE;
  742. if( s_dsd.bFailed )
  743. return FALSE;
  744. ZeroMemory(&s_dsd, sizeof(s_dsd));
  745. GetSystemDirectory(szPath, MAX_PATH);
  746. lstrcat(szPath, TEXT("\\mscat32.dll"));
  747. s_dsd.hInstMsCat32 = LoadLibrary(szPath);
  748. if (s_dsd.hInstMsCat32 == NULL)
  749. {
  750. s_dsd.bFailed = TRUE;
  751. return FALSE;
  752. }
  753. s_dsd.CryptCATAdminAcquireContext = (PfnCryptCATAdminAcquireContext)GetProcAddress(s_dsd.hInstMsCat32, "CryptCATAdminAcquireContext");
  754. if (s_dsd.CryptCATAdminAcquireContext == NULL)
  755. {
  756. s_dsd.bFailed = TRUE;
  757. return FALSE;
  758. }
  759. s_dsd.CryptCATAdminReleaseContext = (PfnCryptCATAdminReleaseContext)GetProcAddress(s_dsd.hInstMsCat32, "CryptCATAdminReleaseContext");
  760. if (s_dsd.CryptCATAdminReleaseContext == NULL)
  761. {
  762. s_dsd.bFailed = TRUE;
  763. return FALSE;
  764. }
  765. s_dsd.CryptCATAdminReleaseCatalogContext = (PfnCryptCATAdminReleaseCatalogContext)GetProcAddress(s_dsd.hInstMsCat32, "CryptCATAdminReleaseCatalogContext");
  766. if (s_dsd.CryptCATAdminReleaseCatalogContext == NULL)
  767. {
  768. s_dsd.bFailed = TRUE;
  769. return FALSE;
  770. }
  771. s_dsd.CryptCATCatalogInfoFromContext = (PfnCryptCATCatalogInfoFromContext)GetProcAddress(s_dsd.hInstMsCat32, "CryptCATCatalogInfoFromContext");
  772. if (s_dsd.CryptCATCatalogInfoFromContext == NULL)
  773. {
  774. s_dsd.bFailed = TRUE;
  775. return FALSE;
  776. }
  777. s_dsd.CryptCATAdminEnumCatalogFromHash = (PfnCryptCATAdminEnumCatalogFromHash)GetProcAddress(s_dsd.hInstMsCat32, "CryptCATAdminEnumCatalogFromHash");
  778. if (s_dsd.CryptCATAdminEnumCatalogFromHash == NULL)
  779. {
  780. s_dsd.bFailed = TRUE;
  781. return FALSE;
  782. }
  783. s_dsd.IsCatalogFile = (PfnIsCatalogFile)GetProcAddress(s_dsd.hInstMsCat32, "IsCatalogFile");
  784. if (s_dsd.IsCatalogFile == NULL)
  785. {
  786. s_dsd.bFailed = TRUE;
  787. return FALSE;
  788. }
  789. s_dsd.CryptCATAdminCalcHashFromFileHandle = (PfnCryptCATAdminCalcHashFromFileHandle)GetProcAddress(s_dsd.hInstMsCat32, "CryptCATAdminCalcHashFromFileHandle");
  790. if (s_dsd.CryptCATAdminCalcHashFromFileHandle == NULL)
  791. {
  792. s_dsd.bFailed = TRUE;
  793. return FALSE;
  794. }
  795. if (!s_dsd.CryptCATAdminAcquireContext(&s_dsd.hCatAdmin, NULL, 0))
  796. {
  797. s_dsd.bFailed = TRUE;
  798. return FALSE;
  799. }
  800. GetSystemDirectory(szPath, MAX_PATH);
  801. lstrcat(szPath, TEXT("\\wintrust.dll"));
  802. s_dsd.hInstWinTrust = LoadLibrary(szPath);
  803. if (s_dsd.hInstWinTrust == NULL)
  804. {
  805. s_dsd.bFailed = TRUE;
  806. return FALSE;
  807. }
  808. s_dsd.WinVerifyTrust = (PfnWinVerifyTrust)GetProcAddress(s_dsd.hInstWinTrust, "WinVerifyTrust");
  809. if (s_dsd.WinVerifyTrust == NULL)
  810. {
  811. s_dsd.bFailed = TRUE;
  812. return FALSE;
  813. }
  814. GetSystemDirectory(szPath, MAX_PATH);
  815. lstrcat(szPath, TEXT("\\crypt32.dll"));
  816. s_dsd.hInstCrypt32 = LoadLibrary(szPath);
  817. if (s_dsd.hInstCrypt32 == NULL)
  818. {
  819. s_dsd.bFailed = TRUE;
  820. return FALSE;
  821. }
  822. s_dsd.CertFreeCertificateContext = (PfnCertFreeCertificateContext)GetProcAddress(s_dsd.hInstCrypt32, "CertFreeCertificateContext");
  823. if (s_dsd.CertFreeCertificateContext == NULL)
  824. {
  825. s_dsd.bFailed = TRUE;
  826. return FALSE;
  827. }
  828. s_dsd.bFailed = FALSE;
  829. s_dsd.bInitialized = TRUE;
  830. return TRUE;
  831. }
  832. /****************************************************************************
  833. *
  834. * ReleaseDigiSignData
  835. *
  836. ****************************************************************************/
  837. VOID ReleaseDigiSignData(VOID)
  838. {
  839. if( s_dsd.CryptCATAdminReleaseContext && s_dsd.hCatAdmin )
  840. s_dsd.CryptCATAdminReleaseContext(s_dsd.hCatAdmin,0);
  841. if (s_dsd.hInstMsCat32 != NULL)
  842. FreeLibrary(s_dsd.hInstMsCat32);
  843. if (s_dsd.hInstWinTrust != NULL)
  844. FreeLibrary(s_dsd.hInstWinTrust);
  845. if (s_dsd.hInstCrypt32 != NULL)
  846. FreeLibrary(s_dsd.hInstCrypt32);
  847. ZeroMemory(&s_dsd, sizeof(s_dsd));
  848. }
  849. /****************************************************************************
  850. *
  851. * IsFileDigitallySigned
  852. *
  853. ****************************************************************************/
  854. BOOL IsFileDigitallySigned(TCHAR* pszFile)
  855. {
  856. if (!s_dsd.bInitialized)
  857. return FALSE;
  858. TCHAR lpFileName[MAX_PATH];
  859. TCHAR lpDirName[MAX_PATH];
  860. TCHAR* pch;
  861. if( lstrlen(lpDirName) + lstrlen(pszFile) < MAX_PATH )
  862. lstrcpy(lpDirName, pszFile);
  863. CharLowerBuff(lpDirName, lstrlen(lpDirName));
  864. pch = _tcsrchr(lpDirName, TEXT('\\'));
  865. // 22670: There *should* be a backslash in pszFile, but cope if it isn't
  866. if (pch == NULL)
  867. {
  868. lstrcpyn(lpFileName, pszFile,MAX_PATH);
  869. GetCurrentDirectory(MAX_PATH, lpDirName);
  870. }
  871. else
  872. {
  873. lstrcpy(lpFileName, pch + 1);
  874. *pch = TEXT('\0');
  875. }
  876. if (_tcsstr(lpDirName, TEXT("\\")) == NULL)
  877. lstrcat(lpDirName, TEXT("\\"));
  878. return VerifyFileNode(lpFileName, lpDirName);
  879. }
  880. /****************************************************************************
  881. *
  882. * VerifyFileNode
  883. *
  884. ****************************************************************************/
  885. BOOL VerifyFileNode(TCHAR* lpFileName, TCHAR* lpDirName)
  886. {
  887. const DWORD HASH_SIZE = 100;
  888. HANDLE hFile;
  889. BOOL bRet;
  890. HCATINFO hCatInfo = NULL;
  891. HCATINFO PrevCat;
  892. WINTRUST_DATA WinTrustData;
  893. WINTRUST_CATALOG_INFO WinTrustCatalogInfo;
  894. DRIVER_VER_INFO VerInfo;
  895. GUID guidSubSystemDriver = DRIVER_ACTION_VERIFY;
  896. HRESULT hRes;
  897. DWORD cbHash = HASH_SIZE;
  898. BYTE szHash[HASH_SIZE];
  899. LPBYTE lpHash = szHash;
  900. CATALOG_INFO CatInfo;
  901. #ifndef UNICODE
  902. WCHAR UnicodeKey[MAX_PATH];
  903. #endif
  904. BOOL bSigned = FALSE;
  905. TCHAR szFullPath[MAX_PATH];
  906. wsprintf(szFullPath, TEXT("%s\\%s"), lpDirName, lpFileName);
  907. //
  908. // Get the handle to the file, so we can call CryptCATAdminCalcHashFromFileHandle
  909. //
  910. hFile = CreateFile( szFullPath,
  911. GENERIC_READ,
  912. FILE_SHARE_READ | FILE_SHARE_WRITE,
  913. NULL,
  914. OPEN_EXISTING,
  915. FILE_ATTRIBUTE_NORMAL,
  916. NULL);
  917. if (hFile == INVALID_HANDLE_VALUE)
  918. {
  919. return FALSE;
  920. }
  921. // Initialize the hash buffer
  922. ZeroMemory(lpHash, HASH_SIZE);
  923. // Generate the hash from the file handle and store it in lpHash
  924. if (!s_dsd.CryptCATAdminCalcHashFromFileHandle(hFile, &cbHash, lpHash, 0))
  925. {
  926. //
  927. // If we couldn't generate a hash, it might be an individually signed catalog.
  928. // If it's a catalog, zero out lpHash and cbHash so we know there's no hash to check.
  929. //
  930. if (s_dsd.IsCatalogFile(hFile, NULL))
  931. {
  932. lpHash = NULL;
  933. cbHash = 0;
  934. }
  935. else // If it wasn't a catalog, we'll bail and this file will show up as unscanned.
  936. {
  937. CloseHandle(hFile);
  938. return FALSE;
  939. }
  940. }
  941. // Close the file handle
  942. CloseHandle(hFile);
  943. //
  944. // Now we have the file's hash. Initialize the structures that
  945. // will be used later on in calls to WinVerifyTrust.
  946. //
  947. ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA));
  948. WinTrustData.cbStruct = sizeof(WINTRUST_DATA);
  949. WinTrustData.dwUIChoice = WTD_UI_NONE;
  950. WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
  951. WinTrustData.dwUnionChoice = WTD_CHOICE_CATALOG;
  952. WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE;
  953. WinTrustData.pPolicyCallbackData = (LPVOID)&VerInfo;
  954. ZeroMemory(&VerInfo, sizeof(DRIVER_VER_INFO));
  955. VerInfo.cbStruct = sizeof(DRIVER_VER_INFO);
  956. OSVERSIONINFO osvi;
  957. ZeroMemory(&osvi, sizeof(osvi));
  958. osvi.dwOSVersionInfoSize = sizeof(osvi);
  959. if (GetVersionEx(&osvi))
  960. {
  961. VerInfo.dwPlatform = osvi.dwPlatformId;
  962. VerInfo.dwVersion = osvi.dwMajorVersion;
  963. VerInfo.sOSVersionLow.dwMajor = osvi.dwMajorVersion;
  964. VerInfo.sOSVersionLow.dwMinor = osvi.dwMinorVersion;
  965. VerInfo.sOSVersionHigh.dwMajor = osvi.dwMajorVersion;
  966. VerInfo.sOSVersionHigh.dwMinor = osvi.dwMinorVersion;
  967. }
  968. WinTrustData.pCatalog = &WinTrustCatalogInfo;
  969. ZeroMemory(&WinTrustCatalogInfo, sizeof(WINTRUST_CATALOG_INFO));
  970. WinTrustCatalogInfo.cbStruct = sizeof(WINTRUST_CATALOG_INFO);
  971. WinTrustCatalogInfo.pbCalculatedFileHash = lpHash;
  972. WinTrustCatalogInfo.cbCalculatedFileHash = cbHash;
  973. #ifdef UNICODE
  974. WinTrustCatalogInfo.pcwszMemberTag = lpFileName;
  975. #else
  976. MultiByteToWideChar(CP_ACP, 0, lpFileName, -1, UnicodeKey, MAX_PATH);
  977. WinTrustCatalogInfo.pcwszMemberTag = UnicodeKey;
  978. #endif
  979. //
  980. // Now we try to find the file hash in the catalog list, via CryptCATAdminEnumCatalogFromHash
  981. //
  982. PrevCat = NULL;
  983. hCatInfo = s_dsd.CryptCATAdminEnumCatalogFromHash(s_dsd.hCatAdmin, lpHash, cbHash, 0, &PrevCat);
  984. //
  985. // We want to cycle through the matching catalogs until we find one that matches both hash and member tag
  986. //
  987. bRet = FALSE;
  988. while(hCatInfo && !bRet)
  989. {
  990. ZeroMemory(&CatInfo, sizeof(CATALOG_INFO));
  991. CatInfo.cbStruct = sizeof(CATALOG_INFO);
  992. if(s_dsd.CryptCATCatalogInfoFromContext(hCatInfo, &CatInfo, 0))
  993. {
  994. WinTrustCatalogInfo.pcwszCatalogFilePath = CatInfo.wszCatalogFile;
  995. // Now verify that the file is an actual member of the catalog.
  996. hRes = s_dsd.WinVerifyTrust(NULL, &guidSubSystemDriver, &WinTrustData);
  997. if (hRes == ERROR_SUCCESS)
  998. {
  999. /*
  1000. #ifdef UNICODE
  1001. GetFullPathName(CatInfo.wszCatalogFile, MAX_PATH, szBuffer, &lpFilePart);
  1002. #else
  1003. WideCharToMultiByte(CP_ACP, 0, CatInfo.wszCatalogFile, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
  1004. GetFullPathName(szBuffer, MAX_PATH, szBuffer, &lpFilePart);
  1005. #endif
  1006. lpFileNode->lpCatalog = (LPTSTR)MALLOC((lstrlen(lpFilePart) + 1) * sizeof(TCHAR));
  1007. lstrcpy(lpFileNode->lpCatalog, lpFilePart);
  1008. */
  1009. if (VerInfo.pcSignerCertContext != NULL)
  1010. {
  1011. s_dsd.CertFreeCertificateContext(VerInfo.pcSignerCertContext);
  1012. VerInfo.pcSignerCertContext = NULL;
  1013. }
  1014. bRet = TRUE;
  1015. }
  1016. }
  1017. if (!bRet)
  1018. {
  1019. // The hash was in this catalog, but the file wasn't a member... so off to the next catalog
  1020. PrevCat = hCatInfo;
  1021. hCatInfo = s_dsd.CryptCATAdminEnumCatalogFromHash(s_dsd.hCatAdmin, lpHash, cbHash, 0, &PrevCat);
  1022. }
  1023. }
  1024. if (!hCatInfo)
  1025. {
  1026. //
  1027. // If it wasn't found in the catalogs, check if the file is individually signed.
  1028. //
  1029. bRet = VerifyIsFileSigned(lpFileName, (PDRIVER_VER_INFO) &VerInfo);
  1030. if (bRet)
  1031. {
  1032. // If so, mark the file as being signed.
  1033. bSigned = TRUE;
  1034. }
  1035. }
  1036. else
  1037. {
  1038. // The file was verified in the catalogs, so mark it as signed and free the catalog context.
  1039. bSigned = TRUE;
  1040. s_dsd.CryptCATAdminReleaseCatalogContext(s_dsd.hCatAdmin, hCatInfo, 0);
  1041. }
  1042. /*
  1043. if (lpFileNode->bSigned)
  1044. {
  1045. #ifdef UNICODE
  1046. lpFileNode->lpVersion = MALLOC((lstrlen(VerInfo.wszVersion) + 1) * sizeof(TCHAR));
  1047. lstrcpy(lpFileNode->lpVersion, VerInfo.wszVersion);
  1048. lpFileNode->lpSignedBy = MALLOC((lstrlen(VerInfo.wszSignedBy) + 1) * sizeof(TCHAR));
  1049. lstrcpy(lpFileNode->lpSignedBy, VerInfo.wszSignedBy);
  1050. #else
  1051. WideCharToMultiByte(CP_ACP, 0, VerInfo.wszVersion, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
  1052. lpFileNode->lpVersion = (LPTSTR)MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR));
  1053. lstrcpy(lpFileNode->lpVersion, szBuffer);
  1054. WideCharToMultiByte(CP_ACP, 0, VerInfo.wszSignedBy, -1, szBuffer, sizeof(szBuffer), NULL, NULL);
  1055. lpFileNode->lpSignedBy = (LPTSTR)MALLOC((lstrlen(szBuffer) + 1) * sizeof(TCHAR));
  1056. lstrcpy(lpFileNode->lpSignedBy, szBuffer);
  1057. #endif
  1058. }
  1059. */
  1060. return bSigned;
  1061. }
  1062. /****************************************************************************
  1063. *
  1064. * VerifyIsFileSigned
  1065. *
  1066. ****************************************************************************/
  1067. BOOL VerifyIsFileSigned(LPTSTR pcszMatchFile, PDRIVER_VER_INFO lpVerInfo)
  1068. {
  1069. HRESULT hRes;
  1070. WINTRUST_DATA WinTrustData;
  1071. WINTRUST_FILE_INFO WinTrustFile;
  1072. GUID guidOSVerCheck = DRIVER_ACTION_VERIFY;
  1073. GUID guidPublishedSoftware = WINTRUST_ACTION_GENERIC_VERIFY_V2;
  1074. ZeroMemory(&WinTrustData, sizeof(WINTRUST_DATA));
  1075. WinTrustData.cbStruct = sizeof(WINTRUST_DATA);
  1076. WinTrustData.dwUIChoice = WTD_UI_NONE;
  1077. WinTrustData.fdwRevocationChecks = WTD_REVOKE_NONE;
  1078. WinTrustData.dwUnionChoice = WTD_CHOICE_FILE;
  1079. WinTrustData.dwStateAction = WTD_STATEACTION_AUTO_CACHE;
  1080. WinTrustData.pFile = &WinTrustFile;
  1081. WinTrustData.pPolicyCallbackData = (LPVOID)lpVerInfo;
  1082. ZeroMemory(lpVerInfo, sizeof(DRIVER_VER_INFO));
  1083. lpVerInfo->cbStruct = sizeof(DRIVER_VER_INFO);
  1084. ZeroMemory(&WinTrustFile, sizeof(WINTRUST_FILE_INFO));
  1085. WinTrustFile.cbStruct = sizeof(WINTRUST_FILE_INFO);
  1086. #ifndef UNICODE
  1087. WCHAR wszFileName[MAX_PATH];
  1088. MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, pcszMatchFile, -1, (LPWSTR)wszFileName, MAX_PATH);
  1089. wszFileName[MAX_PATH-1] = 0;
  1090. WinTrustFile.pcwszFilePath = wszFileName;
  1091. #else
  1092. WinTrustFile.pcwszFilePath = pcszMatchFile;
  1093. #endif
  1094. hRes = s_dsd.WinVerifyTrust(NULL, &guidOSVerCheck, &WinTrustData);
  1095. if (hRes != ERROR_SUCCESS)
  1096. hRes = s_dsd.WinVerifyTrust(NULL, &guidPublishedSoftware, &WinTrustData);
  1097. if (lpVerInfo->pcSignerCertContext != NULL)
  1098. {
  1099. s_dsd.CertFreeCertificateContext(lpVerInfo->pcSignerCertContext);
  1100. lpVerInfo->pcSignerCertContext = NULL;
  1101. }
  1102. return (hRes == ERROR_SUCCESS);
  1103. }
  1104. /****************************************************************************
  1105. *
  1106. * DiagnoseDxFiles
  1107. *
  1108. ****************************************************************************/
  1109. VOID DiagnoseDxFiles(SysInfo* pSysInfo, FileInfo* pDxComponentsFileInfoFirst,
  1110. FileInfo* pDxWinComponentsFileInfoFirst)
  1111. {
  1112. FileInfo* pFileInfo;
  1113. TCHAR szHighest[100];
  1114. TCHAR szDXVersion[100];
  1115. BOOL bNT = BIsPlatformNT();
  1116. BOOL bWin2k = BIsWin2k();
  1117. BOOL bIA64 = BIsIA64();
  1118. FLOAT fDXVersion = 0.0f;
  1119. BOOL bDX5 = FALSE;
  1120. BOOL bDX6 = FALSE; // 6.x
  1121. BOOL bDX60 = FALSE; // 6.0
  1122. BOOL bDX61 = FALSE; // 6.1
  1123. BOOL bDX7 = FALSE; // 7.x
  1124. BOOL bDX70 = FALSE; // 7.0
  1125. BOOL bDX71 = FALSE; // 7.1
  1126. BOOL bDX8 = FALSE; // 8.x
  1127. BOOL bDX80 = FALSE; // 8.0
  1128. BOOL bDX81 = FALSE; // 8.1
  1129. BOOL b64BitDxDiag = BIsDxDiag64Bit();
  1130. TCHAR szMissing[200];
  1131. TCHAR szInWindows[200];
  1132. TCHAR szOld[200];
  1133. TCHAR szDebug[200];
  1134. TCHAR szBeta[200];
  1135. TCHAR szFmt[300];
  1136. TCHAR szMessage[300];
  1137. LONG lwNumInWindows;
  1138. LONG lwNumMissing;
  1139. LONG lwNumOld;
  1140. LONG lwNumDebug;
  1141. LONG lwNumBeta;
  1142. TCHAR szListContinuer[30];
  1143. TCHAR szListEtc[30];
  1144. BOOL bVersionWarnings = TRUE;
  1145. BOOL bWinsockWarning = FALSE;
  1146. // Find highest version number in list
  1147. szHighest[0] = '\0';
  1148. for (pFileInfo = pDxComponentsFileInfoFirst; pFileInfo != NULL;
  1149. pFileInfo = pFileInfo->m_pFileInfoNext)
  1150. {
  1151. if (pFileInfo->m_bIgnoreVersionInfo)
  1152. continue;
  1153. // ddrawex.dll and dxapi.sys have wacky version numbers, so ignore them
  1154. if (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("ddrawex.dll")) == 0 ||
  1155. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dxapi.sys")) == 0)
  1156. {
  1157. continue;
  1158. }
  1159. // Bug 18892: dplayx.dll and dpmodemx.dll can have wacky version numbers if
  1160. // DPlay 6.0a is installed over DX 6.0
  1161. if (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dplayx.dll")) == 0 &&
  1162. DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("4.06.02.0363")) == 0)
  1163. {
  1164. continue;
  1165. }
  1166. if (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dpmodemx.dll")) == 0 &&
  1167. DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("4.06.02.0356")) == 0)
  1168. {
  1169. continue;
  1170. }
  1171. // DPlay 6.1a: dplay files can have higher version numbers if
  1172. // DPlay 6.1a is installed over DX 6.0 (or DX 6.1)
  1173. if (DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("4.06.03.0518")) == 0 &&
  1174. (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dplayx.dll")) == 0 ||
  1175. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dpmodemx.dll")) == 0 ||
  1176. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dpwsockx.dll")) == 0 ||
  1177. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dplaysvr.exe")) == 0))
  1178. {
  1179. continue;
  1180. }
  1181. if (lstrcmp(pFileInfo->m_szVersion, pSysInfo->m_szDxDiagVersion) > 0)
  1182. {
  1183. // Bug 21291: Do not complain about file version newer than DxDiag itself
  1184. continue;
  1185. }
  1186. if (lstrcmp(szHighest, pFileInfo->m_szVersion) < 0)
  1187. lstrcpy(szHighest, pFileInfo->m_szVersion);
  1188. }
  1189. if (bNT)
  1190. lstrcpy(szDXVersion, pSysInfo->m_szDirectXVersion);
  1191. else
  1192. lstrcpy(szDXVersion, szHighest);
  1193. // Determine DX version
  1194. DWORD dwMajor;
  1195. DWORD dwMinor;
  1196. DWORD dwRevision;
  1197. DWORD dwBuild;
  1198. if( _stscanf(szDXVersion, TEXT("%d.%d.%d.%d"), &dwMajor, &dwMinor, &dwRevision, &dwBuild) != 4 )
  1199. {
  1200. dwMajor = 0;
  1201. dwMinor = 0;
  1202. dwRevision = 0;
  1203. dwBuild = 0;
  1204. }
  1205. if (dwMinor < 6)
  1206. bDX5 = TRUE;
  1207. else if (dwMinor < 7 && dwRevision < 2)
  1208. bDX60 = TRUE;
  1209. else if (dwMinor < 7)
  1210. bDX61 = TRUE;
  1211. else if (dwMinor < 8 && dwRevision < 1)
  1212. bDX70 = TRUE;
  1213. else if (dwMinor < 8)
  1214. bDX71 = TRUE;
  1215. else if (dwMinor == 8 && dwRevision < 1)
  1216. bDX80 = TRUE;
  1217. else if (dwMinor >= 8)
  1218. bDX81 = TRUE;
  1219. // Calc DX ver
  1220. fDXVersion = (float) dwMinor + (float) (dwRevision/10.0f);
  1221. // Is this DX6?
  1222. bDX6 = bDX60 || bDX61;
  1223. // Is this DX7?
  1224. bDX7 = bDX70 || bDX71;
  1225. // Is this DX8?
  1226. bDX8 = bDX80 || bDX81;
  1227. lwNumInWindows = 0;
  1228. lwNumMissing = 0;
  1229. lwNumOld = 0;
  1230. lwNumDebug = 0;
  1231. lwNumBeta = 0;
  1232. LoadString(NULL, IDS_LISTCONTINUER, szListContinuer, 30);
  1233. LoadString(NULL, IDS_LISTETC, szListEtc, 30);
  1234. for (pFileInfo = pDxWinComponentsFileInfoFirst; pFileInfo != NULL;
  1235. pFileInfo = pFileInfo->m_pFileInfoNext)
  1236. {
  1237. pFileInfo->m_bProblem = TRUE;
  1238. lwNumInWindows++;
  1239. if (lwNumInWindows == 1)
  1240. {
  1241. lstrcpy(szInWindows, pFileInfo->m_szName);
  1242. }
  1243. else if (lwNumInWindows < 4)
  1244. {
  1245. lstrcat(szInWindows, szListContinuer);
  1246. lstrcat(szInWindows, pFileInfo->m_szName);
  1247. }
  1248. else if (lwNumInWindows < 5)
  1249. {
  1250. lstrcat(szInWindows, szListEtc);
  1251. }
  1252. }
  1253. for (pFileInfo = pDxComponentsFileInfoFirst; pFileInfo != NULL;
  1254. pFileInfo = pFileInfo->m_pFileInfoNext)
  1255. {
  1256. if (!pFileInfo->m_bExists && !pFileInfo->m_bOptional)
  1257. {
  1258. // A missing file is a problem unless it's optional, OR...
  1259. // (on NT): it's optional on NT
  1260. // (on IA64): it's not on IA64
  1261. // (on IA64): we're running 32-bit dxdiag and its optional on WOW
  1262. // if file hasn't shipped yet on this DX version
  1263. // if file stopped shipping on or after this DX version
  1264. if (bNT && pFileInfo->m_bOptionalOnNT)
  1265. {
  1266. }
  1267. else if (bIA64 && pFileInfo->m_bNotIA64)
  1268. {
  1269. }
  1270. else if (bIA64 && !b64BitDxDiag && pFileInfo->m_bOptionalOnWOW64)
  1271. {
  1272. }
  1273. else if (fDXVersion+0.05f < pFileInfo->m_fStartShipAt)
  1274. {
  1275. }
  1276. else if (fDXVersion+0.05f >= pFileInfo->m_fStopShipAt)
  1277. {
  1278. }
  1279. else
  1280. {
  1281. pFileInfo->m_bProblem = TRUE;
  1282. LoadString(NULL, IDS_FILEMISSING, pFileInfo->m_szVersion, 50);
  1283. lwNumMissing++;
  1284. if (lwNumMissing == 1)
  1285. {
  1286. lstrcpy(szMissing, pFileInfo->m_szName);
  1287. }
  1288. else if (lwNumMissing < 4)
  1289. {
  1290. lstrcat(szMissing, szListContinuer);
  1291. lstrcat(szMissing, pFileInfo->m_szName);
  1292. }
  1293. else if (lwNumMissing < 5)
  1294. {
  1295. lstrcat(szMissing, szListEtc);
  1296. }
  1297. }
  1298. }
  1299. if (!pFileInfo->m_bExists)
  1300. continue;
  1301. if( BIsWin95() )
  1302. {
  1303. if( DXUtil_strcmpi(pFileInfo->m_szName, TEXT("wsock32.dll")) )
  1304. {
  1305. if( IsBadWin95Winsock( pFileInfo ) )
  1306. bWinsockWarning = TRUE;
  1307. }
  1308. }
  1309. // If DX6 or later, flag any dx5 only files as
  1310. // obsolete (needing to be deleted)
  1311. // manbugs 16765: don't complain about these files, just don't list them
  1312. if (!bDX5 && (pFileInfo->m_fStopShipAt == 6.0f))
  1313. {
  1314. pFileInfo->m_bProblem = TRUE;
  1315. pFileInfo->m_bObsolete = TRUE;
  1316. continue; // don't complain about these files for any other reason
  1317. }
  1318. if (bVersionWarnings && lstrcmp(szHighest, pFileInfo->m_szVersion) != 0)
  1319. {
  1320. if( pFileInfo->m_bIgnoreVersionInfo )
  1321. {
  1322. // Don't warn on files that have m_bIgnoreVersionInfo set
  1323. }
  1324. else if( bDX81 && ( _tcsstr(pFileInfo->m_szVersion, TEXT("4.08.00.0400")) != NULL ||
  1325. _tcsstr(pFileInfo->m_szVersion, TEXT("5.01.2258.0400")) != NULL ) )
  1326. {
  1327. // Bug 48732: If szHighest is 4.08.00.05xx and
  1328. // pFileInfo->m_szVersion is 4.08.00.0400 its OK
  1329. }
  1330. else if( bWin2k && (
  1331. (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("d3drm.dll")) == 0 && DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("5.00.2134.0001")) == 0) ||
  1332. (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("d3dxof.dll")) == 0 && DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("5.00.2135.0001")) == 0) ||
  1333. (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("d3dpmesh.dll")) == 0 && DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("5.00.2134.0001")) == 0)
  1334. )
  1335. )
  1336. {
  1337. }
  1338. else if( bDX71 && _tcsstr(pFileInfo->m_szVersion, TEXT("4.07.00.07")) != NULL )
  1339. {
  1340. // Bug 114753: If szHighest is 4.07.01.xxxx and
  1341. // pFileInfo->m_szVersion is 4.07.00.0700 its OK (for now).
  1342. }
  1343. else if (!bNT && (bDX60 || bDX61) && CompareString(LOCALE_SYSTEM_DEFAULT, 0,
  1344. pFileInfo->m_szVersion, 4, TEXT("4.05"), 4) == CSTR_EQUAL &&
  1345. ( DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dsound.dll")) == 0 ||
  1346. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dsound.vxd")) == 0 ||
  1347. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dinput.dll")) == 0 ||
  1348. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dinput.vxd")) == 0 ||
  1349. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("vjoyd.vxd")) == 0 ||
  1350. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("msanalog.vxd")) == 0 ||
  1351. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("joy.cpl")) == 0 ||
  1352. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("gcdef.dll")) == 0 ||
  1353. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("gchand.dll")) == 0))
  1354. {
  1355. // If Win9x DX6.x, dsound and dinput are allowed to be 4.05.xx.xxxx
  1356. // CompareString is used rather than lstrcmp only because we
  1357. // only want to look at the first four characters of the string
  1358. // Don't report these as version problems
  1359. }
  1360. else if (!bNT && bDX7 && CompareString(LOCALE_SYSTEM_DEFAULT, 0,
  1361. pFileInfo->m_szVersion, 4, TEXT("4.05"), 4) == CSTR_EQUAL &&
  1362. (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dinput.dll")) == 0 ||
  1363. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dinput.vxd")) == 0 ||
  1364. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("joy.cpl")) == 0 ||
  1365. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("gchand.dll")) == 0 ||
  1366. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("gcdef.dll")) == 0 ||
  1367. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("vjoyd.vxd")) == 0 ||
  1368. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("msanalog.vxd")) == 0))
  1369. {
  1370. // 21470: On DX7, these input files still exist on Win95,
  1371. // and they stay at DX5 level.
  1372. }
  1373. else if ( !bNT &&
  1374. (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("msjstick.drv")) == 0 && DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("4.00.00.0950")) == 0) ||
  1375. (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("vjoyd.vxd")) == 0 && DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("4.05.00.0155")) == 0)
  1376. )
  1377. {
  1378. // 34687: These stays at the dx5 level.
  1379. }
  1380. else if (!bNT && (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("ddrawex.dll")) == 0 ||
  1381. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dxapi.sys")) == 0))
  1382. {
  1383. // Ignore ddrawex.dll and dxapi.sys on Win9x because they have weird version numbers:
  1384. }
  1385. else if (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dplayx.dll")) == 0 &&
  1386. DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("4.06.02.0363")) == 0)
  1387. {
  1388. // Bug 18892: work around DPlay 6.0a
  1389. }
  1390. else if (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dpmodemx.dll")) == 0 &&
  1391. DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("4.06.02.0356")) == 0)
  1392. {
  1393. // Bug 18892: work around DPlay 6.0a
  1394. }
  1395. else if (DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("4.06.03.0518")) == 0 &&
  1396. (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dplayx.dll")) == 0 ||
  1397. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dpmodemx.dll")) == 0 ||
  1398. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dpwsockx.dll")) == 0 ||
  1399. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dplaysvr.exe")) == 0))
  1400. {
  1401. // DPlay 6.1a: dplay files can have higher version numbers if
  1402. // DPlay 6.1a is installed over DX 6.0 (or DX 6.1)
  1403. }
  1404. else if (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dxsetup.exe")) == 0 ||
  1405. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dsetup.dll")) == 0 ||
  1406. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dsetup16.dll")) == 0 ||
  1407. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dsetup32.dll")) == 0 ||
  1408. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("directx.cpl")) == 0)
  1409. {
  1410. // Bug 18540: Don't complain if dsetup/cpl files are out of date because
  1411. // some updates (OSR) don't update the setup/cpl files which may exist from
  1412. // another (SDK) installation
  1413. }
  1414. else if (!bNT && DXUtil_strcmpi(pFileInfo->m_szVersion, TEXT("4.06.02.0436")) == 0 &&
  1415. (DXUtil_strcmpi(pFileInfo->m_szName, TEXT("d3drm.dll")) == 0 ||
  1416. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("d3dxof.dll")) == 0 ||
  1417. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("d3dpmesh.dll")) == 0 ||
  1418. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dplayx.dll")) == 0 ||
  1419. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dpmodemx.dll")) == 0 ||
  1420. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dpwsockx.dll")) == 0 ||
  1421. DXUtil_strcmpi(pFileInfo->m_szName, TEXT("dplaysvr.exe")) == 0))
  1422. {
  1423. // On DX 6.1a, the RM and DPlay files stay at 4.06.02.0436. No problemo.
  1424. }
  1425. else if (lstrcmp(pFileInfo->m_szVersion, pSysInfo->m_szDxDiagVersion) > 0)
  1426. {
  1427. // Bug 21291: Do not complain about file version newer than DxDiag itself
  1428. }
  1429. else
  1430. {
  1431. pFileInfo->m_bProblem = TRUE;
  1432. lwNumOld++;
  1433. if (lwNumOld == 1)
  1434. {
  1435. lstrcpy(szOld, pFileInfo->m_szName);
  1436. }
  1437. else if (lwNumOld < 4)
  1438. {
  1439. lstrcat(szOld, szListContinuer);
  1440. lstrcat(szOld, pFileInfo->m_szName);
  1441. }
  1442. else if (lwNumOld < 5)
  1443. {
  1444. lstrcat(szOld, szListEtc);
  1445. }
  1446. }
  1447. } // end if (bVersionWarnings && lstrcmp(szHighest, pFileInfo->m_szVersion) != 0)
  1448. if (pFileInfo->m_bBeta && !pFileInfo->m_bIgnoreBeta)
  1449. {
  1450. pFileInfo->m_bProblem = TRUE;
  1451. lwNumBeta++;
  1452. if (lwNumBeta == 1)
  1453. {
  1454. lstrcpy(szBeta, pFileInfo->m_szName);
  1455. }
  1456. else if (lwNumBeta < 4)
  1457. {
  1458. lstrcat(szBeta, szListContinuer);
  1459. lstrcat(szBeta, pFileInfo->m_szName);
  1460. }
  1461. else if (lwNumBeta < 5)
  1462. {
  1463. lstrcat(szBeta, szListEtc);
  1464. }
  1465. }
  1466. if (pFileInfo->m_bDebug && !pFileInfo->m_bIgnoreDebug)
  1467. {
  1468. pFileInfo->m_bProblem = TRUE;
  1469. lwNumDebug++;
  1470. if (lwNumDebug == 1)
  1471. {
  1472. lstrcpy(szDebug, pFileInfo->m_szName);
  1473. }
  1474. else if (lwNumDebug < 4)
  1475. {
  1476. lstrcat(szDebug, szListContinuer);
  1477. lstrcat(szDebug, pFileInfo->m_szName);
  1478. }
  1479. else if (lwNumDebug < 5)
  1480. {
  1481. lstrcat(szDebug, szListEtc);
  1482. }
  1483. }
  1484. }
  1485. BOOL bShouldReinstall = FALSE;
  1486. _tcscpy(pSysInfo->m_szDXFileNotes, TEXT("") );
  1487. _tcscpy(pSysInfo->m_szDXFileNotesEnglish, TEXT("") );
  1488. if (lwNumInWindows > 0)
  1489. {
  1490. if (lwNumInWindows == 1)
  1491. LoadString(NULL, IDS_INWINDOWSFMT1, szFmt, 300);
  1492. else
  1493. LoadString(NULL, IDS_INWINDOWSFMT2, szFmt, 300);
  1494. wsprintf(szMessage, szFmt, szInWindows);
  1495. _tcscat(pSysInfo->m_szDXFileNotes, szMessage);
  1496. if (lwNumInWindows == 1)
  1497. LoadString(NULL, IDS_INWINDOWSFMT1_ENGLISH, szFmt, 300);
  1498. else
  1499. LoadString(NULL, IDS_INWINDOWSFMT2_ENGLISH, szFmt, 300);
  1500. wsprintf(szMessage, szFmt, szInWindows);
  1501. _tcscat(pSysInfo->m_szDXFileNotesEnglish, szMessage);
  1502. }
  1503. if (lwNumMissing > 0)
  1504. {
  1505. if (lwNumMissing == 1)
  1506. LoadString(NULL, IDS_MISSINGFMT1, szFmt, 300);
  1507. else
  1508. LoadString(NULL, IDS_MISSINGFMT2, szFmt, 300);
  1509. wsprintf(szMessage, szFmt, szMissing);
  1510. _tcscat(pSysInfo->m_szDXFileNotes, szMessage);
  1511. if (lwNumMissing == 1)
  1512. LoadString(NULL, IDS_MISSINGFMT1_ENGLISH, szFmt, 300);
  1513. else
  1514. LoadString(NULL, IDS_MISSINGFMT2_ENGLISH, szFmt, 300);
  1515. wsprintf(szMessage, szFmt, szMissing);
  1516. _tcscat(pSysInfo->m_szDXFileNotesEnglish, szMessage);
  1517. bShouldReinstall = TRUE;
  1518. }
  1519. if (lwNumOld > 0)
  1520. {
  1521. if (lwNumOld == 1)
  1522. LoadString(NULL, IDS_OLDFMT1, szFmt, 300);
  1523. else
  1524. LoadString(NULL, IDS_OLDFMT2, szFmt, 300);
  1525. wsprintf(szMessage, szFmt, szOld);
  1526. _tcscat(pSysInfo->m_szDXFileNotes, szMessage);
  1527. if (lwNumOld == 1)
  1528. LoadString(NULL, IDS_OLDFMT1_ENGLISH, szFmt, 300);
  1529. else
  1530. LoadString(NULL, IDS_OLDFMT2_ENGLISH, szFmt, 300);
  1531. wsprintf(szMessage, szFmt, szOld);
  1532. _tcscat(pSysInfo->m_szDXFileNotesEnglish, szMessage);
  1533. bShouldReinstall = TRUE;
  1534. }
  1535. if (lwNumBeta > 0)
  1536. {
  1537. if (lwNumBeta == 1)
  1538. LoadString(NULL, IDS_BETAFMT1, szFmt, 300);
  1539. else
  1540. LoadString(NULL, IDS_BETAFMT2, szFmt, 300);
  1541. wsprintf(szMessage, szFmt, szBeta);
  1542. _tcscat(pSysInfo->m_szDXFileNotes, szMessage);
  1543. if (lwNumBeta == 1)
  1544. LoadString(NULL, IDS_BETAFMT1_ENGLISH, szFmt, 300);
  1545. else
  1546. LoadString(NULL, IDS_BETAFMT2_ENGLISH, szFmt, 300);
  1547. wsprintf(szMessage, szFmt, szBeta);
  1548. _tcscat(pSysInfo->m_szDXFileNotesEnglish, szMessage);
  1549. bShouldReinstall = TRUE;
  1550. }
  1551. if (lwNumDebug > 0)
  1552. {
  1553. if (lwNumDebug == 1)
  1554. LoadString(NULL, IDS_DEBUGFMT1, szFmt, 300);
  1555. else
  1556. LoadString(NULL, IDS_DEBUGFMT2, szFmt, 300);
  1557. wsprintf(szMessage, szFmt, szDebug);
  1558. _tcscat( pSysInfo->m_szDXFileNotes, szMessage);
  1559. if (lwNumDebug == 1)
  1560. LoadString(NULL, IDS_DEBUGFMT1_ENGLISH, szFmt, 300);
  1561. else
  1562. LoadString(NULL, IDS_DEBUGFMT2_ENGLISH, szFmt, 300);
  1563. wsprintf(szMessage, szFmt, szDebug);
  1564. _tcscat( pSysInfo->m_szDXFileNotesEnglish, szMessage);
  1565. //bShouldReinstall = TRUE;
  1566. }
  1567. if( bWinsockWarning )
  1568. {
  1569. LoadString(NULL, IDS_WINSOCK_WARN, szMessage, 300);
  1570. _tcscat( pSysInfo->m_szDXFileNotes, szMessage);
  1571. LoadString(NULL, IDS_WINSOCK_WARN_ENGLISH, szMessage, 300);
  1572. _tcscat( pSysInfo->m_szDXFileNotesEnglish, szMessage);
  1573. }
  1574. if( bShouldReinstall )
  1575. {
  1576. BOOL bTellUser = FALSE;
  1577. // Figure out if the user can install DirectX
  1578. if( BIsPlatform9x() )
  1579. bTellUser = TRUE;
  1580. else if( BIsWin2k() && bDX8 )
  1581. bTellUser = TRUE;
  1582. if( bTellUser )
  1583. {
  1584. LoadString(NULL, IDS_REINSTALL_DX, szMessage, 300);
  1585. _tcscat( pSysInfo->m_szDXFileNotes, szMessage);
  1586. LoadString(NULL, IDS_REINSTALL_DX_ENGLISH, szMessage, 300);
  1587. _tcscat( pSysInfo->m_szDXFileNotesEnglish, szMessage);
  1588. }
  1589. }
  1590. if (lwNumMissing == 0 && lwNumOld == 0 &&
  1591. lwNumBeta == 0 && lwNumDebug == 0 && lwNumInWindows == 0)
  1592. {
  1593. LoadString(NULL, IDS_NOPROBLEM, szMessage, 300);
  1594. _tcscat(pSysInfo->m_szDXFileNotes, szMessage);
  1595. LoadString(NULL, IDS_NOPROBLEM_ENGLISH, szMessage, 300);
  1596. _tcscat(pSysInfo->m_szDXFileNotesEnglish, szMessage);
  1597. }
  1598. }
  1599. /****************************************************************************
  1600. *
  1601. * IsBadWin95Winsock
  1602. *
  1603. ****************************************************************************/
  1604. BOOL IsBadWin95Winsock( FileInfo* pFileInfo )
  1605. {
  1606. typedef int (PASCAL* LPWSASTARTUP)(IN WORD wVersionRequired, OUT LPWSADATA lpWSAData);
  1607. typedef int (PASCAL* LPWSACLEANUP)(void);
  1608. BOOL bReturn = FALSE;
  1609. TCHAR szPath[MAX_PATH];
  1610. HINSTANCE hInstWSock;
  1611. LPWSASTARTUP pWSAStartup = NULL;
  1612. LPWSACLEANUP pWSACleanup = NULL;
  1613. GetSystemDirectory(szPath, MAX_PATH);
  1614. lstrcat(szPath, TEXT("\\wsock32.dll"));
  1615. hInstWSock = LoadLibrary(szPath);
  1616. if (hInstWSock != NULL)
  1617. {
  1618. pWSAStartup = (LPWSASTARTUP)GetProcAddress(hInstWSock, "WSAStartup");
  1619. pWSACleanup = (LPWSACLEANUP)GetProcAddress(hInstWSock, "WSACleanup");
  1620. if (pWSAStartup != NULL && pWSACleanup != NULL)
  1621. {
  1622. WORD wVersionRequested;
  1623. WSADATA wsaData;
  1624. int err;
  1625. wVersionRequested = MAKEWORD( 2, 2 );
  1626. err = pWSAStartup( wVersionRequested, &wsaData );
  1627. if ( err == 0 )
  1628. {
  1629. if ( LOBYTE( wsaData.wVersion ) == 2 &&
  1630. HIBYTE( wsaData.wVersion ) == 2 )
  1631. {
  1632. FILETIME fileTimeGoodWinsock;
  1633. SYSTEMTIME systemTimeGoodWinsock;
  1634. ULARGE_INTEGER ulGoodWinsock;
  1635. ULARGE_INTEGER ulCurrentWinsock;
  1636. ZeroMemory( &systemTimeGoodWinsock, sizeof(SYSTEMTIME) );
  1637. systemTimeGoodWinsock.wYear = 1998;
  1638. systemTimeGoodWinsock.wMonth = 2;
  1639. systemTimeGoodWinsock.wDay = 6;
  1640. systemTimeGoodWinsock.wHour = 14;
  1641. systemTimeGoodWinsock.wMinute = 18;
  1642. systemTimeGoodWinsock.wSecond = 00;
  1643. SystemTimeToFileTime( &systemTimeGoodWinsock, &fileTimeGoodWinsock );
  1644. ulCurrentWinsock.LowPart = pFileInfo->m_FileTime.dwLowDateTime;
  1645. ulCurrentWinsock.HighPart = pFileInfo->m_FileTime.dwHighDateTime;
  1646. ulGoodWinsock.LowPart = fileTimeGoodWinsock.dwLowDateTime;
  1647. ulGoodWinsock.HighPart = fileTimeGoodWinsock.dwHighDateTime;
  1648. if( ulCurrentWinsock.QuadPart < ulGoodWinsock.QuadPart )
  1649. {
  1650. bReturn = TRUE;
  1651. }
  1652. }
  1653. pWSACleanup();
  1654. }
  1655. }
  1656. }
  1657. FreeLibrary(hInstWSock);
  1658. return bReturn;
  1659. }