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

1307 lines
33 KiB

  1. #include "precomp.h"
  2. #include "ntexapi.h"
  3. extern BOOL g_bClearSessionLogBeforeRun;
  4. extern BOOL g_bUseAVDebugger;
  5. TCHAR g_szXML[32768];
  6. TCHAR g_szCmd[1024];
  7. /////////////////////////////////////////////////////////////////////////////
  8. //
  9. // Registry keys/values names
  10. //
  11. const TCHAR g_szImageOptionsKeyName[] = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options");
  12. const TCHAR g_szGlobalFlagValueName[] = _T("GlobalFlag");
  13. const TCHAR g_szVerifierFlagsValueName[] = _T("VerifierFlags");
  14. const TCHAR g_szVerifierPathValueName[] = _T("VerifierPath");
  15. const TCHAR g_szDebugger[] = _T("Debugger");
  16. CAVAppInfoArray g_aAppInfo;
  17. CTestInfoArray g_aTestInfo;
  18. BOOL
  19. SetAppVerifierFlagsForKey(
  20. HKEY hKey,
  21. DWORD dwDesiredFlags
  22. )
  23. {
  24. BOOL bRet = FALSE;
  25. DWORD dwValueType = 0;
  26. DWORD dwDataSize = 0;
  27. TCHAR szOldGlobalFlagValue[32];
  28. BOOL bSuccesfullyConverted;
  29. BOOL bDesireEnabled = (dwDesiredFlags != 0);
  30. LONG lResult;
  31. DWORD dwFlags = 0;
  32. //
  33. // Read the GlobalFlag value
  34. //
  35. dwDataSize = sizeof(szOldGlobalFlagValue);
  36. lResult = RegQueryValueEx(hKey,
  37. g_szGlobalFlagValueName,
  38. NULL,
  39. &dwValueType,
  40. (LPBYTE) &szOldGlobalFlagValue[0],
  41. &dwDataSize);
  42. if (ERROR_SUCCESS == lResult) {
  43. bSuccesfullyConverted = AVRtlCharToInteger(szOldGlobalFlagValue,
  44. 0,
  45. &dwFlags);
  46. if (!bSuccesfullyConverted) {
  47. dwFlags = 0;
  48. }
  49. }
  50. BOOL bEnabled = (dwFlags & FLG_APPLICATION_VERIFIER) != 0;
  51. //
  52. // write the new global flags, if necessary
  53. //
  54. if (bDesireEnabled != bEnabled) {
  55. if (bDesireEnabled) {
  56. dwFlags |= FLG_APPLICATION_VERIFIER;
  57. } else {
  58. dwFlags &= ~FLG_APPLICATION_VERIFIER;
  59. }
  60. BOOL bSuccess = AVWriteStringHexValueToRegistry(hKey,
  61. g_szGlobalFlagValueName,
  62. dwFlags);
  63. if (!bSuccess) {
  64. goto out;
  65. }
  66. }
  67. //
  68. // now write the app verifier settings
  69. //
  70. if (bDesireEnabled) {
  71. lResult = RegSetValueEx(hKey,
  72. g_szVerifierFlagsValueName,
  73. 0,
  74. REG_DWORD,
  75. (PBYTE) &dwDesiredFlags,
  76. sizeof(dwDesiredFlags));
  77. if (lResult != ERROR_SUCCESS) {
  78. goto out;
  79. }
  80. } else {
  81. lResult = RegDeleteValue(hKey, g_szVerifierFlagsValueName);
  82. if (lResult != ERROR_SUCCESS) {
  83. goto out;
  84. }
  85. }
  86. bRet = TRUE;
  87. out:
  88. return bRet;
  89. }
  90. DWORD
  91. GetAppVerifierFlagsFromKey(
  92. HKEY hKey
  93. )
  94. {
  95. DWORD dwRet = 0;
  96. DWORD dwValueType = 0;
  97. DWORD dwDataSize = 0;
  98. TCHAR szOldGlobalFlagValue[32];
  99. BOOL bSuccesfullyConverted;
  100. LONG lResult;
  101. DWORD dwFlags = 0;
  102. //
  103. // Read the GlobalFlag value
  104. //
  105. dwDataSize = sizeof(szOldGlobalFlagValue);
  106. lResult = RegQueryValueEx(hKey,
  107. g_szGlobalFlagValueName,
  108. NULL,
  109. &dwValueType,
  110. (LPBYTE)&szOldGlobalFlagValue[0],
  111. &dwDataSize);
  112. if (ERROR_SUCCESS == lResult) {
  113. bSuccesfullyConverted = AVRtlCharToInteger(szOldGlobalFlagValue,
  114. 0,
  115. &dwFlags);
  116. if ((FALSE != bSuccesfullyConverted) &&
  117. ((dwFlags & FLG_APPLICATION_VERIFIER) != 0)) {
  118. //
  119. // App verifier is enabled for this app - read the verifier flags
  120. //
  121. dwDataSize = sizeof(dwRet);
  122. lResult = RegQueryValueEx(hKey,
  123. g_szVerifierFlagsValueName,
  124. NULL,
  125. &dwValueType,
  126. (LPBYTE)&dwRet,
  127. &dwDataSize);
  128. if (ERROR_SUCCESS != lResult || REG_DWORD != dwValueType) {
  129. //
  130. // couldn't get them, for one reason or another
  131. //
  132. dwRet = 0;
  133. }
  134. }
  135. }
  136. return dwRet;
  137. }
  138. void
  139. SetAppVerifierFullPathForKey(
  140. HKEY hKey,
  141. wstring& strPath
  142. )
  143. {
  144. if (strPath.size() == 0) {
  145. RegDeleteValue(hKey, g_szVerifierPathValueName);
  146. } else {
  147. RegSetValueEx(hKey,
  148. g_szVerifierPathValueName,
  149. 0,
  150. REG_SZ,
  151. (PBYTE) strPath.c_str(),
  152. strPath.size() * sizeof(WCHAR));
  153. }
  154. }
  155. void
  156. SetDebuggerOptionsForKey(
  157. HKEY hKey,
  158. BOOL bUseAVDebugger
  159. )
  160. {
  161. WCHAR szName[MAX_PATH];
  162. szName[0] = 0;
  163. GetModuleFileName(NULL, szName, MAX_PATH);
  164. wcscat(szName, L" /debug");
  165. if (bUseAVDebugger) {
  166. RegSetValueEx(hKey,
  167. g_szDebugger,
  168. 0,
  169. REG_SZ,
  170. (PBYTE)szName,
  171. wcslen(szName) * sizeof(WCHAR));
  172. } else {
  173. WCHAR szDbgName[MAX_PATH];
  174. DWORD cbSize;
  175. cbSize = MAX_PATH * sizeof(WCHAR);
  176. szDbgName[0] = 0;
  177. RegQueryValueEx(hKey,
  178. g_szDebugger,
  179. 0,
  180. NULL,
  181. (PBYTE)szDbgName,
  182. &cbSize);
  183. if (_wcsicmp(szName, szDbgName) == 0) {
  184. RegDeleteValue(hKey, g_szDebugger);
  185. }
  186. }
  187. }
  188. void
  189. GetAppVerifierFullPathFromKey(
  190. HKEY hKey,
  191. wstring& strPath
  192. )
  193. {
  194. DWORD dwValueType = 0;
  195. DWORD dwDataSize = 0;
  196. TCHAR szVerifierPath[MAX_PATH];
  197. LONG lResult;
  198. //
  199. // Read the GlobalFlag value
  200. //
  201. dwDataSize = sizeof(szVerifierPath);
  202. szVerifierPath[0] = 0;
  203. lResult = RegQueryValueEx(hKey,
  204. g_szVerifierPathValueName,
  205. NULL,
  206. &dwValueType,
  207. (LPBYTE)szVerifierPath,
  208. &dwDataSize);
  209. if (ERROR_SUCCESS == lResult && dwValueType == REG_SZ) {
  210. strPath = szVerifierPath;
  211. }
  212. }
  213. void
  214. GetCurrentAppSettingsFromRegistry(
  215. void
  216. )
  217. {
  218. HKEY hImageOptionsKey;
  219. HKEY hSubKey;
  220. DWORD dwSubkeyIndex;
  221. DWORD dwDataSize;
  222. DWORD dwValueType;
  223. DWORD dwFlags;
  224. LONG lResult;
  225. FILETIME LastWriteTime;
  226. TCHAR szOldGlobalFlagValue[32];
  227. TCHAR szKeyNameBuffer[256];
  228. //
  229. // Open the Image File Execution Options regkey
  230. //
  231. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  232. g_szImageOptionsKeyName,
  233. 0,
  234. KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
  235. &hImageOptionsKey);
  236. if (lResult != ERROR_SUCCESS) {
  237. if (lResult == ERROR_ACCESS_DENIED) {
  238. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  239. } else {
  240. AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED,
  241. g_szImageOptionsKeyName,
  242. (DWORD)lResult);
  243. }
  244. return;
  245. }
  246. //
  247. // Enumerate all the existing subkeys for app execution options
  248. //
  249. for (dwSubkeyIndex = 0; TRUE; dwSubkeyIndex += 1) {
  250. wstring wstrPath;
  251. dwDataSize = ARRAY_LENGTH(szKeyNameBuffer);
  252. lResult = RegEnumKeyEx(hImageOptionsKey,
  253. dwSubkeyIndex,
  254. szKeyNameBuffer,
  255. &dwDataSize,
  256. NULL,
  257. NULL,
  258. NULL,
  259. &LastWriteTime);
  260. if (lResult != ERROR_SUCCESS) {
  261. if (lResult == ERROR_NO_MORE_ITEMS) {
  262. //
  263. // We finished looking at all the existing subkeys
  264. //
  265. break;
  266. } else {
  267. if (lResult == ERROR_ACCESS_DENIED) {
  268. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  269. } else {
  270. AVErrorResourceFormat(IDS_REGENUMKEYEX_FAILED,
  271. g_szImageOptionsKeyName,
  272. (DWORD)lResult);
  273. }
  274. goto CleanUpAndDone;
  275. }
  276. }
  277. //
  278. // Open the subkey
  279. //
  280. lResult = RegOpenKeyEx(hImageOptionsKey,
  281. szKeyNameBuffer,
  282. 0,
  283. KEY_QUERY_VALUE | KEY_SET_VALUE,
  284. &hSubKey);
  285. if (lResult != ERROR_SUCCESS) {
  286. if (lResult == ERROR_ACCESS_DENIED) {
  287. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  288. } else {
  289. AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED,
  290. szKeyNameBuffer,
  291. (DWORD)lResult);
  292. }
  293. goto CleanUpAndDone;
  294. }
  295. dwFlags = GetAppVerifierFlagsFromKey(hSubKey);
  296. GetAppVerifierFullPathFromKey(hSubKey, wstrPath);
  297. if (dwFlags || wstrPath.size()) {
  298. //
  299. // Update the info in the array, or add it if necessary
  300. //
  301. CAVAppInfo* pApp;
  302. BOOL bFound = FALSE;
  303. for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) {
  304. if (_wcsicmp(pApp->wstrExeName.c_str(), szKeyNameBuffer) == 0) {
  305. bFound = TRUE;
  306. pApp->dwRegFlags = dwFlags;
  307. pApp->wstrExePath = wstrPath;
  308. break;
  309. }
  310. }
  311. if (!bFound) {
  312. CAVAppInfo AppInfo;
  313. AppInfo.wstrExeName = szKeyNameBuffer;
  314. AppInfo.dwRegFlags = dwFlags;
  315. AppInfo.wstrExePath = wstrPath;
  316. g_aAppInfo.push_back(AppInfo);
  317. }
  318. }
  319. VERIFY(ERROR_SUCCESS == RegCloseKey(hSubKey));
  320. }
  321. CleanUpAndDone:
  322. VERIFY(ERROR_SUCCESS == RegCloseKey(hImageOptionsKey));
  323. }
  324. void
  325. GetCurrentAppSettingsFromSDB(
  326. void
  327. )
  328. {
  329. CAVAppInfo AppInfo;
  330. TCHAR szPath[MAX_PATH];
  331. PDB pdb = NULL;
  332. TAGID tiDB = TAGID_NULL;
  333. TAGID tiExe = TAGID_NULL;
  334. //
  335. // go find the SDB
  336. //
  337. szPath[0] = 0;
  338. GetSystemWindowsDirectory(szPath, MAX_PATH);
  339. _tcscat(szPath, _T("\\AppPatch\\Custom\\{448850f4-a5ea-4dd1-bf1b-d5fa285dc64b}.sdb"));
  340. pdb = SdbOpenDatabase(szPath, DOS_PATH);
  341. if (!pdb) {
  342. //
  343. // no current DB
  344. //
  345. goto out;
  346. }
  347. //
  348. // enumerate all the apps and the shims applied to them
  349. //
  350. tiDB = SdbFindFirstTag(pdb, TAGID_ROOT, TAG_DATABASE);
  351. if (!tiDB) {
  352. goto out;
  353. }
  354. tiExe = SdbFindFirstTag(pdb, tiDB, TAG_EXE);
  355. while (tiExe) {
  356. WCHAR* wszName = NULL;
  357. TAGID tiShim = TAGID_NULL;
  358. TAGID tiName = SdbFindFirstTag(pdb, tiExe, TAG_NAME);
  359. if (!tiName) {
  360. goto nextExe;
  361. }
  362. wszName = SdbGetStringTagPtr(pdb, tiName);
  363. CAVAppInfoArray::iterator it;
  364. BOOL bFound = FALSE;
  365. for (it = g_aAppInfo.begin(); it != g_aAppInfo.end(); it++) {
  366. if (_wcsicmp(it->wstrExeName.c_str(), wszName) == 0) {
  367. bFound = TRUE;
  368. break;
  369. }
  370. }
  371. if (!bFound) {
  372. AppInfo.wstrExeName = wszName;
  373. g_aAppInfo.push_back(AppInfo);
  374. it = g_aAppInfo.end() - 1;
  375. }
  376. tiShim = SdbFindFirstTag(pdb, tiExe, TAG_SHIM_REF);
  377. while (tiShim) {
  378. WCHAR* wszShimName = NULL;
  379. TAGID tiShimName = SdbFindFirstTag(pdb, tiShim, TAG_NAME);
  380. if (!tiShimName) {
  381. goto nextShim;
  382. }
  383. wszShimName = SdbGetStringTagPtr(pdb, tiShimName);
  384. it->awstrShims.push_back(wstring(wszShimName));
  385. nextShim:
  386. tiShim = SdbFindNextTag(pdb, tiExe, tiShim);
  387. }
  388. nextExe:
  389. tiExe = SdbFindNextTag(pdb, tiDB, tiExe);
  390. }
  391. out:
  392. if (pdb) {
  393. SdbCloseDatabase(pdb);
  394. pdb = NULL;
  395. }
  396. return;
  397. }
  398. void
  399. GetCurrentAppSettings(
  400. void
  401. )
  402. {
  403. g_aAppInfo.clear();
  404. GetCurrentAppSettingsFromRegistry();
  405. GetCurrentAppSettingsFromSDB();
  406. }
  407. void
  408. SetCurrentRegistrySettings(
  409. void
  410. )
  411. {
  412. HKEY hImageOptionsKey;
  413. HKEY hSubKey = NULL;
  414. DWORD dwSubkeyIndex;
  415. DWORD dwDataSize;
  416. DWORD dwValueType;
  417. DWORD dwFlags;
  418. LONG lResult;
  419. FILETIME LastWriteTime;
  420. TCHAR szKeyNameBuffer[ 256 ];
  421. CAVAppInfo* pApp;
  422. wstring wstrEmpty = L"";
  423. //
  424. // Open the Image File Execution Options regkey
  425. //
  426. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  427. g_szImageOptionsKeyName,
  428. 0,
  429. KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
  430. &hImageOptionsKey);
  431. if (lResult != ERROR_SUCCESS) {
  432. if (lResult == ERROR_ACCESS_DENIED) {
  433. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  434. } else {
  435. AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED,
  436. g_szImageOptionsKeyName,
  437. (DWORD)lResult);
  438. }
  439. return;
  440. }
  441. //
  442. // Enumerate all the existing subkeys for app execution options
  443. //
  444. for (dwSubkeyIndex = 0; TRUE; dwSubkeyIndex += 1) {
  445. dwDataSize = ARRAY_LENGTH(szKeyNameBuffer);
  446. lResult = RegEnumKeyEx(hImageOptionsKey,
  447. dwSubkeyIndex,
  448. szKeyNameBuffer,
  449. &dwDataSize,
  450. NULL,
  451. NULL,
  452. NULL,
  453. &LastWriteTime);
  454. if (lResult != ERROR_SUCCESS) {
  455. if (lResult == ERROR_NO_MORE_ITEMS) {
  456. //
  457. // We finished looking at all the existing subkeys
  458. //
  459. break;
  460. } else {
  461. if (lResult == ERROR_ACCESS_DENIED) {
  462. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  463. } else {
  464. AVErrorResourceFormat(IDS_REGENUMKEYEX_FAILED,
  465. g_szImageOptionsKeyName,
  466. (DWORD)lResult);
  467. }
  468. goto CleanUpAndDone;
  469. }
  470. }
  471. //
  472. // Open the subkey
  473. //
  474. lResult = RegOpenKeyEx(hImageOptionsKey,
  475. szKeyNameBuffer,
  476. 0,
  477. KEY_QUERY_VALUE | KEY_SET_VALUE,
  478. &hSubKey);
  479. if (lResult != ERROR_SUCCESS) {
  480. if (lResult == ERROR_ACCESS_DENIED) {
  481. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  482. } else {
  483. AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED,
  484. szKeyNameBuffer,
  485. (DWORD)lResult);
  486. }
  487. goto CleanUpAndDone;
  488. }
  489. dwFlags = GetAppVerifierFlagsFromKey(hSubKey);
  490. DWORD dwDesiredFlags = 0;
  491. BOOL bFound = FALSE;
  492. for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) {
  493. if (_wcsicmp(pApp->wstrExeName.c_str(), szKeyNameBuffer) == 0) {
  494. dwDesiredFlags = pApp->dwRegFlags;
  495. bFound = TRUE;
  496. //
  497. // we found it, so update the full path
  498. //
  499. SetAppVerifierFullPathForKey(hSubKey, pApp->wstrExePath);
  500. //
  501. // and add the debugger as well
  502. //
  503. SetDebuggerOptionsForKey(hSubKey, g_bUseAVDebugger);
  504. break;
  505. }
  506. }
  507. if (!bFound) {
  508. //
  509. // if this one isn't in our list, make sure it doesn't
  510. // have a full path or our debugger set
  511. //
  512. SetAppVerifierFullPathForKey(hSubKey, wstrEmpty);
  513. SetDebuggerOptionsForKey(hSubKey, FALSE);
  514. }
  515. if (dwFlags != dwDesiredFlags) {
  516. SetAppVerifierFlagsForKey(hSubKey, dwDesiredFlags);
  517. }
  518. VERIFY(ERROR_SUCCESS == RegCloseKey(hSubKey));
  519. hSubKey = NULL;
  520. }
  521. //
  522. // and now go through the list the other way, looking for new ones to add
  523. //
  524. for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) {
  525. lResult = RegOpenKeyEx(hImageOptionsKey,
  526. pApp->wstrExeName.c_str(),
  527. 0,
  528. KEY_QUERY_VALUE | KEY_SET_VALUE,
  529. &hSubKey);
  530. //
  531. // if it exists, we've already dealt with it above
  532. //
  533. if (lResult != ERROR_SUCCESS) {
  534. //
  535. // it doesn't exist. Try to create it.
  536. //
  537. lResult = RegCreateKeyEx(hImageOptionsKey,
  538. pApp->wstrExeName.c_str(),
  539. 0,
  540. NULL,
  541. REG_OPTION_NON_VOLATILE,
  542. KEY_QUERY_VALUE | KEY_SET_VALUE,
  543. NULL,
  544. &hSubKey,
  545. NULL);
  546. if (lResult == ERROR_SUCCESS) {
  547. SetAppVerifierFlagsForKey(hSubKey, pApp->dwRegFlags);
  548. SetAppVerifierFullPathForKey(hSubKey, pApp->wstrExePath);
  549. SetDebuggerOptionsForKey(hSubKey, g_bUseAVDebugger);
  550. }
  551. }
  552. if (hSubKey) {
  553. RegCloseKey(hSubKey);
  554. hSubKey = NULL;
  555. }
  556. }
  557. CleanUpAndDone:
  558. VERIFY(ERROR_SUCCESS == RegCloseKey(hImageOptionsKey));
  559. }
  560. void
  561. SetCurrentAppSettings(
  562. void
  563. )
  564. {
  565. SetCurrentRegistrySettings();
  566. AppCompatWriteShimSettings(g_aAppInfo);
  567. }
  568. KERNEL_TEST_INFO g_KernelTests[] =
  569. {
  570. {
  571. IDS_PAGE_HEAP,
  572. IDS_PAGE_HEAP_DESC,
  573. RTL_VRF_FLG_FULL_PAGE_HEAP,
  574. TRUE,
  575. L"PageHeap"
  576. },
  577. {
  578. IDS_VERIFY_LOCKS_CHECKS,
  579. IDS_VERIFY_LOCKS_CHECKS_DESC,
  580. RTL_VRF_FLG_LOCK_CHECKS,
  581. TRUE,
  582. L"Locks"
  583. },
  584. {
  585. IDS_VERIFY_HANDLE_CHECKS,
  586. IDS_VERIFY_HANDLE_CHECKS_DESC,
  587. RTL_VRF_FLG_HANDLE_CHECKS,
  588. TRUE,
  589. L"Handles"
  590. },
  591. {
  592. IDS_VERIFY_STACK_CHECKS,
  593. IDS_VERIFY_STACK_CHECKS_DESC,
  594. RTL_VRF_FLG_STACK_CHECKS,
  595. FALSE,
  596. L"Stacks"
  597. }
  598. };
  599. BOOL
  600. GetKernelTestInfo(
  601. CTestInfoArray& TestArray
  602. )
  603. {
  604. CTestInfo ti;
  605. TCHAR szTemp[256];
  606. int i;
  607. ti.eTestType = TEST_KERNEL;
  608. for (int i = 0; i < ARRAY_LENGTH(g_KernelTests); ++i) {
  609. if (!AVLoadString(g_KernelTests[i].m_uNameStringId, szTemp, ARRAY_LENGTH(szTemp))) {
  610. continue;
  611. }
  612. ti.strTestName = szTemp;
  613. if (AVLoadString(g_KernelTests[i].m_uDescriptionStringId, szTemp, ARRAY_LENGTH(szTemp))) {
  614. ti.strTestDescription = szTemp;
  615. } else {
  616. ti.strTestDescription = L"";
  617. }
  618. ti.dwKernelFlag = g_KernelTests[i].m_dwBit;
  619. ti.bDefault = g_KernelTests[i].m_bDefault;
  620. ti.strTestCommandLine = g_KernelTests[i].m_szCommandLine;
  621. TestArray.push_back(ti);
  622. }
  623. return TRUE;
  624. }
  625. void
  626. ParseIncludeList(
  627. WCHAR* szList,
  628. CWStringArray& astrArray
  629. )
  630. {
  631. if (!szList) {
  632. return;
  633. }
  634. WCHAR *szComma = NULL;
  635. WCHAR *szBegin = szList;
  636. WCHAR szTemp[128];
  637. int nLen = wcslen(szList);
  638. WCHAR *szEnd = szList + nLen;
  639. do {
  640. szComma = wcschr(szBegin, L',');
  641. if (!szComma) {
  642. szComma = szEnd;
  643. }
  644. while (*szComma && iswspace(*szComma)) {
  645. szComma++;
  646. }
  647. nLen = (int)(szComma - szBegin);
  648. if (nLen > 0) {
  649. memcpy(szTemp, szBegin, nLen * sizeof(WCHAR));
  650. szTemp[nLen] = 0;
  651. astrArray.push_back(szTemp);
  652. }
  653. if (!*szComma) {
  654. break;
  655. }
  656. szBegin = szComma + 1;
  657. } while (TRUE);
  658. }
  659. BOOL
  660. GetShimInfo(
  661. CTestInfoArray& TestInfoArray
  662. )
  663. {
  664. HKEY hKey = NULL;
  665. BOOL bRet = FALSE;
  666. int nWhich = 0;
  667. TCHAR szAppPatch[MAX_PATH];
  668. TCHAR szShimFullPath[MAX_PATH];
  669. HMODULE hMod;
  670. _pfnEnumShims pEnumShims = NULL;
  671. _pfnIsVerifierDLL pIsVerifer = NULL;
  672. PSHIM_DESCRIPTION pShims = NULL;
  673. DWORD dwShims = 0;
  674. WIN32_FIND_DATA FindData;
  675. HANDLE hFind = INVALID_HANDLE_VALUE;
  676. TCHAR szDllSearch[MAX_PATH];
  677. GetSystemWindowsDirectory(szAppPatch, MAX_PATH);
  678. _tcscat(szAppPatch, _T("\\AppPatch\\"));
  679. _tcscpy(szDllSearch, szAppPatch);
  680. _tcscat(szDllSearch, _T("*.dll"));
  681. //
  682. // enumerate all the DLLs and look for ones that have Verification
  683. // shims in them
  684. //
  685. hFind = FindFirstFile(szDllSearch, &FindData);
  686. while (hFind != INVALID_HANDLE_VALUE) {
  687. _tcscpy(szShimFullPath, szAppPatch);
  688. _tcscat(szShimFullPath, FindData.cFileName);
  689. hMod = LoadLibrary(szShimFullPath);
  690. if (!hMod) {
  691. goto nextKey;
  692. }
  693. pIsVerifer = (_pfnIsVerifierDLL)GetProcAddress(hMod, "IsVerifierDLL");
  694. if (!pIsVerifer) {
  695. //
  696. // not a real verifier shim
  697. //
  698. goto nextKey;
  699. }
  700. if (!pIsVerifer()) {
  701. //
  702. // not a real verifier shim
  703. //
  704. goto nextKey;
  705. }
  706. pEnumShims = (_pfnEnumShims)GetProcAddress(hMod, "EnumShims");
  707. if (!pEnumShims) {
  708. //
  709. // not a real verifier shim
  710. //
  711. goto nextKey;
  712. }
  713. dwShims = pEnumShims(NULL, ENUM_SHIMS_MAGIC);
  714. if (!dwShims) {
  715. goto nextKey;
  716. }
  717. pShims = new SHIM_DESCRIPTION[dwShims];
  718. if (!pShims) {
  719. goto out;
  720. }
  721. pEnumShims(pShims, ENUM_SHIMS_MAGIC);
  722. for (DWORD i = 0; i < dwShims; ++i) {
  723. CTestInfo ti;
  724. ti.eTestType = TEST_SHIM;
  725. ti.strDllName = FindData.cFileName;
  726. ti.strTestName = pShims[i].szName;
  727. ti.strTestCommandLine = pShims[i].szName;
  728. ti.strTestDescription = pShims[i].szDescription;
  729. ti.bDefault = TRUE;
  730. ParseIncludeList(pShims[i].szIncludes, ti.astrIncludes);
  731. ParseIncludeList(pShims[i].szExcludes, ti.astrExcludes);
  732. //
  733. // add it to the end
  734. //
  735. TestInfoArray.push_back(ti);
  736. }
  737. delete [] pShims;
  738. pShims = NULL;
  739. nextKey:
  740. if (hMod) {
  741. FreeLibrary(hMod);
  742. hMod = NULL;
  743. }
  744. if (!FindNextFile(hFind, &FindData)) {
  745. FindClose(hFind);
  746. hFind = INVALID_HANDLE_VALUE;
  747. }
  748. }
  749. bRet = TRUE;
  750. out:
  751. if (hMod) {
  752. FreeLibrary(hMod);
  753. hMod = NULL;
  754. }
  755. if (hFind != INVALID_HANDLE_VALUE) {
  756. FindClose(hFind);
  757. hFind = INVALID_HANDLE_VALUE;
  758. }
  759. return bRet;
  760. }
  761. BOOL
  762. InitTestInfo(
  763. void
  764. )
  765. {
  766. g_aTestInfo.clear();
  767. if (!GetKernelTestInfo(g_aTestInfo)) {
  768. return FALSE;
  769. }
  770. if (!GetShimInfo(g_aTestInfo)) {
  771. return FALSE;
  772. }
  773. return TRUE;
  774. }
  775. void
  776. ResetVerifierLog(
  777. void
  778. )
  779. {
  780. WIN32_FIND_DATA FindData;
  781. HANDLE hFind = INVALID_HANDLE_VALUE;
  782. BOOL bFound;
  783. TCHAR szVLogPath[MAX_PATH];
  784. TCHAR szVLogSearch[MAX_PATH];
  785. TCHAR szPath[MAX_PATH];
  786. HANDLE hFile;
  787. GetSystemWindowsDirectory(szVLogPath, MAX_PATH);
  788. _tcscat(szVLogPath, _T("\\AppPatch\\VLog\\"));
  789. _tcscpy(szVLogSearch, szVLogPath);
  790. _tcscat(szVLogSearch, _T("*.log"));
  791. //
  792. // kill all the .log files
  793. //
  794. hFind = FindFirstFile(szVLogSearch, &FindData);
  795. while (hFind != INVALID_HANDLE_VALUE) {
  796. _tcscpy(szPath, szVLogPath);
  797. _tcscat(szPath, FindData.cFileName);
  798. DeleteFile(szPath);
  799. if (!FindNextFile(hFind, &FindData)) {
  800. FindClose(hFind);
  801. hFind = INVALID_HANDLE_VALUE;
  802. }
  803. }
  804. //
  805. // recreate session.log
  806. //
  807. CreateDirectory(szVLogPath, NULL);
  808. _tcscpy(szPath, szVLogPath);
  809. _tcscat(szPath, _T("session.log"));
  810. hFile = CreateFile(szPath,
  811. GENERIC_WRITE,
  812. 0,
  813. NULL,
  814. CREATE_ALWAYS,
  815. FILE_ATTRIBUTE_NORMAL,
  816. NULL);
  817. if (hFile != INVALID_HANDLE_VALUE) {
  818. CloseHandle(hFile);
  819. }
  820. return;
  821. }
  822. void EnableVerifierLog(void)
  823. {
  824. HANDLE hFile;
  825. TCHAR szPath[MAX_PATH];
  826. TCHAR szVLogPath[MAX_PATH];
  827. GetSystemWindowsDirectory(szVLogPath, MAX_PATH);
  828. _tcscat(szVLogPath, _T("\\AppPatch\\VLog\\"));
  829. //
  830. // make sure VLog dir and session.log exists
  831. //
  832. CreateDirectory(szVLogPath, NULL);
  833. _tcscpy(szPath, szVLogPath);
  834. _tcscat(szPath, _T("session.log"));
  835. hFile = CreateFile(szPath,
  836. GENERIC_WRITE,
  837. 0,
  838. NULL,
  839. CREATE_ALWAYS,
  840. FILE_ATTRIBUTE_NORMAL,
  841. NULL);
  842. if (hFile != INVALID_HANDLE_VALUE) {
  843. CloseHandle(hFile);
  844. }
  845. }
  846. CTestInfo*
  847. FindShim(
  848. wstring& wstrName
  849. )
  850. {
  851. CTestInfoArray::iterator it;
  852. for (it = g_aTestInfo.begin(); it != g_aTestInfo.end(); it++) {
  853. if (it->strTestName == wstrName) {
  854. return &(*it);
  855. }
  856. }
  857. return NULL;
  858. }
  859. extern "C" BOOL
  860. ShimdbcExecute(
  861. LPCWSTR lpszCmdLine
  862. );
  863. TCHAR g_szBuff[2048] = _T("");
  864. BOOL
  865. AppCompatWriteShimSettings(
  866. CAVAppInfoArray& arrAppInfo
  867. )
  868. {
  869. TCHAR szTempPath[MAX_PATH] = _T("");
  870. TCHAR szXmlFile[MAX_PATH] = _T("");
  871. TCHAR szSdbFile[MAX_PATH] = _T("");
  872. HANDLE hFile = INVALID_HANDLE_VALUE;
  873. DWORD bytesWritten;
  874. STARTUPINFO si;
  875. PROCESS_INFORMATION pi;
  876. BOOL bReturn = FALSE;
  877. TCHAR szUnicodeHdr[2] = { 0xFEFF, 0};
  878. if (0 == arrAppInfo.size()) {
  879. return AppCompatDeleteSettings();
  880. }
  881. //
  882. // Construct the XML...
  883. //
  884. wsprintf(g_szXML,
  885. _T("%s<?xml version=\"1.0\"?>\r\n")
  886. _T("<DATABASE NAME=\"Application Verifier Database\" ID=\"{448850f4-a5ea-4dd1-bf1b-d5fa285dc64b}\">\r\n")
  887. _T(" <LIBRARY>\r\n"),
  888. szUnicodeHdr);
  889. CTestInfoArray::iterator it;
  890. for (it = g_aTestInfo.begin(); it != g_aTestInfo.end(); it++) {
  891. if (it->eTestType != TEST_SHIM) {
  892. continue;
  893. }
  894. wsprintf(g_szBuff,
  895. _T(" <SHIM NAME=\"%s\" FILE=\"%s\">\r\n")
  896. _T(" <DESCRIPTION>\r\n")
  897. _T(" %s\r\n")
  898. _T(" </DESCRIPTION>\r\n"),
  899. it->strTestName.c_str(),
  900. it->strDllName.c_str(),
  901. it->strTestDescription.c_str());
  902. lstrcat(g_szXML, g_szBuff);
  903. CWStringArray::iterator wsit;
  904. for (wsit = it->astrIncludes.begin(); wsit != it->astrIncludes.end(); ++wsit) {
  905. wsprintf(g_szBuff,
  906. _T(" <INCLUDE MODULE=\"%s\"/>\r\n"),
  907. wsit->c_str());
  908. lstrcat(g_szXML, g_szBuff);
  909. }
  910. for (wsit = it->astrExcludes.begin(); wsit != it->astrExcludes.end(); ++wsit) {
  911. wsprintf(g_szBuff,
  912. _T(" <EXCLUDE MODULE=\"%s\"/>\r\n"),
  913. wsit->c_str());
  914. lstrcat(g_szXML, g_szBuff);
  915. }
  916. lstrcat(g_szXML, _T(" </SHIM>\r\n"));
  917. }
  918. lstrcat(g_szXML, _T(" </LIBRARY>\r\n\r\n"));
  919. lstrcat(g_szXML, _T(" <APP NAME=\"All EXEs to be verified\" VENDOR=\"Various\">\r\n"));
  920. CAVAppInfo* aiit;
  921. for (aiit = arrAppInfo.begin(); aiit != arrAppInfo.end(); aiit++) {
  922. //
  923. // if there're no shims, we're done
  924. //
  925. if (aiit->awstrShims.size() == 0) {
  926. continue;
  927. }
  928. wsprintf(g_szBuff, _T(" <EXE NAME=\"%s\">\r\n"),
  929. aiit->wstrExeName.c_str());
  930. lstrcat(g_szXML, g_szBuff);
  931. CWStringArray::iterator wsit;
  932. for (wsit = aiit->awstrShims.begin();
  933. wsit != aiit->awstrShims.end();
  934. wsit++) {
  935. CTestInfo* pTestInfo = FindShim(*wsit);
  936. if (pTestInfo) {
  937. wsprintf(g_szBuff,
  938. _T(" <SHIM NAME=\"%s\"/>\r\n"),
  939. pTestInfo->strTestName.c_str());
  940. lstrcat(g_szXML, g_szBuff);
  941. }
  942. }
  943. lstrcat(g_szXML, _T(" </EXE>\r\n"));
  944. }
  945. lstrcat(g_szXML,
  946. _T(" </APP>\r\n")
  947. _T("</DATABASE>"));
  948. if (GetTempPath(MAX_PATH, szTempPath) == 0) {
  949. DPF("[AppCompatSaveSettings] GetTempPath failed.");
  950. goto cleanup;
  951. }
  952. //
  953. // Obtain a temp name for the XML file
  954. //
  955. if (GetTempFileName(szTempPath, _T("XML"), NULL, szXmlFile) == 0) {
  956. DPF("[AppCompatSaveSettings] GetTempFilePath for XML failed.");
  957. goto cleanup;
  958. }
  959. hFile = CreateFile(szXmlFile,
  960. GENERIC_WRITE,
  961. 0,
  962. NULL,
  963. CREATE_ALWAYS,
  964. FILE_ATTRIBUTE_NORMAL,
  965. NULL);
  966. if (hFile == INVALID_HANDLE_VALUE) {
  967. DPF("[AppCompatSaveSettings] CreateFile '%s' failed 0x%X.",
  968. szXmlFile, GetLastError());
  969. goto cleanup;
  970. }
  971. if (WriteFile(hFile, g_szXML, lstrlen(g_szXML) * sizeof(TCHAR), &bytesWritten, NULL) == 0) {
  972. DPF("[AppCompatSaveSettings] WriteFile \"%s\" failed 0x%X.",
  973. szXmlFile, GetLastError());
  974. goto cleanup;
  975. }
  976. CloseHandle(hFile);
  977. hFile = INVALID_HANDLE_VALUE;
  978. //
  979. // Obtain a temp name for the SDB file
  980. //
  981. wsprintf(szSdbFile, _T("%stempdb.sdb"), szTempPath);
  982. DeleteFile(szSdbFile);
  983. //
  984. // Invoke the compiler to generate the SDB file
  985. //
  986. ZeroMemory(&si, sizeof(si));
  987. si.cb = sizeof(si);
  988. wsprintf(g_szCmd, _T("shimdbc.exe fix -q \"%s\" \"%s\""), szXmlFile, szSdbFile);
  989. if (!ShimdbcExecute(g_szCmd)) {
  990. DPF("[AppCompatSaveSettings] CreateProcess \"%s\" failed 0x%X.",
  991. g_szCmd, GetLastError());
  992. goto cleanup;
  993. }
  994. //
  995. // The SDB file is generated. Install the database now.
  996. //
  997. ZeroMemory(&si, sizeof(si));
  998. si.cb = sizeof(si);
  999. wsprintf(g_szCmd, _T("sdbinst.exe -q \"%s\""), szSdbFile);
  1000. if (!CreateProcess(NULL,
  1001. g_szCmd,
  1002. NULL,
  1003. NULL,
  1004. FALSE,
  1005. NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
  1006. NULL,
  1007. NULL,
  1008. &si,
  1009. &pi)) {
  1010. DPF("[AppCompatSaveSettings] CreateProcess \"%s\" failed 0x%X.",
  1011. g_szCmd, GetLastError());
  1012. goto cleanup;
  1013. }
  1014. CloseHandle(pi.hThread);
  1015. WaitForSingleObject(pi.hProcess, INFINITE);
  1016. CloseHandle(pi.hProcess);
  1017. //
  1018. // ensure we've got a fresh log session started
  1019. //
  1020. EnableVerifierLog();
  1021. if (g_bClearSessionLogBeforeRun) {
  1022. ResetVerifierLog();
  1023. }
  1024. bReturn = TRUE;
  1025. cleanup:
  1026. if (hFile != INVALID_HANDLE_VALUE) {
  1027. CloseHandle(hFile);
  1028. }
  1029. DeleteFile(szXmlFile);
  1030. DeleteFile(szSdbFile);
  1031. return bReturn;
  1032. }
  1033. BOOL
  1034. AppCompatDeleteSettings(
  1035. void
  1036. )
  1037. {
  1038. STARTUPINFO si;
  1039. PROCESS_INFORMATION pi;
  1040. TCHAR szCmd[MAX_PATH];
  1041. ZeroMemory(&si, sizeof(si));
  1042. si.cb = sizeof(si);
  1043. lstrcpy(szCmd, _T("sdbinst.exe -q -u -g {448850f4-a5ea-4dd1-bf1b-d5fa285dc64b}"));
  1044. if (!CreateProcess(NULL,
  1045. szCmd,
  1046. NULL,
  1047. NULL,
  1048. FALSE,
  1049. NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
  1050. NULL,
  1051. NULL,
  1052. &si,
  1053. &pi)) {
  1054. DPF("[AppCompatDeleteSettings] CreateProcess \"%s\" failed 0x%X.",
  1055. szCmd, GetLastError());
  1056. return FALSE;
  1057. }
  1058. CloseHandle(pi.hThread);
  1059. WaitForSingleObject(pi.hProcess, INFINITE);
  1060. CloseHandle(pi.hProcess);
  1061. return TRUE;
  1062. }