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.

1676 lines
46 KiB

  1. #include "precomp.h"
  2. #include "ntexapi.h"
  3. using namespace ShimLib;
  4. extern BOOL g_bClearSessionLogBeforeRun;
  5. extern BOOL g_bUseAVDebugger;
  6. #define AVDB_ID_32 _T("{448850f4-a5ea-4dd1-bf1b-d5fa285dc64b}")
  7. #define AVDB_ID_64 _T("{64646464-a5ea-4dd1-bf1b-d5fa285dc64b}")
  8. /////////////////////////////////////////////////////////////////////////////
  9. //
  10. // Registry keys/values names
  11. //
  12. const TCHAR g_szImageOptionsKeyName[] = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options");
  13. const TCHAR g_szGlobalFlagValueName[] = _T("GlobalFlag");
  14. const TCHAR g_szVerifierFlagsValueName[] = _T("VerifierFlags");
  15. const TCHAR g_szVerifierPathValueName[] = _T("VerifierPath");
  16. const TCHAR g_szDebuggerKeyName[] = _T("Debugger");
  17. CAVAppInfoArray g_aAppInfo;
  18. CTestInfoArray g_aTestInfo;
  19. BOOL
  20. SetAppVerifierFlagsForKey(
  21. HKEY hKey,
  22. DWORD dwDesiredFlags
  23. )
  24. {
  25. BOOL bRet = FALSE;
  26. DWORD dwValueType = 0;
  27. DWORD dwDataSize = 0;
  28. TCHAR szOldGlobalFlagValue[32];
  29. BOOL bSuccesfullyConverted;
  30. BOOL bDesireEnabled = (dwDesiredFlags != 0);
  31. LONG lResult;
  32. DWORD dwFlags = 0;
  33. DWORD dwEnableFlag;
  34. //
  35. // Read the GlobalFlag value
  36. //
  37. dwDataSize = sizeof(szOldGlobalFlagValue);
  38. lResult = RegQueryValueEx(hKey,
  39. g_szGlobalFlagValueName,
  40. NULL,
  41. &dwValueType,
  42. (LPBYTE) &szOldGlobalFlagValue[0],
  43. &dwDataSize);
  44. if (ERROR_SUCCESS == lResult) {
  45. bSuccesfullyConverted = AVRtlCharToInteger(szOldGlobalFlagValue,
  46. 0,
  47. &dwFlags);
  48. if (!bSuccesfullyConverted) {
  49. dwFlags = 0;
  50. }
  51. }
  52. //
  53. // handle Win2K differently.
  54. //
  55. if (g_bWin2KMode) {
  56. //
  57. // we can only do PageHeap on Win2K, so just check that flag
  58. //
  59. bDesireEnabled = ((dwDesiredFlags & RTL_VRF_FLG_FULL_PAGE_HEAP) != 0);
  60. dwEnableFlag = FLG_HEAP_PAGE_ALLOCS;
  61. } else {
  62. dwEnableFlag = FLG_APPLICATION_VERIFIER;
  63. }
  64. BOOL bEnabled = (dwFlags & dwEnableFlag) != 0;
  65. //
  66. // write the new global flags, if necessary
  67. //
  68. if (bDesireEnabled != bEnabled) {
  69. if (bDesireEnabled) {
  70. dwFlags |= dwEnableFlag;
  71. } else {
  72. dwFlags &= ~dwEnableFlag;
  73. }
  74. BOOL bSuccess = AVWriteStringHexValueToRegistry(hKey,
  75. g_szGlobalFlagValueName,
  76. dwFlags);
  77. if (!bSuccess) {
  78. goto out;
  79. }
  80. }
  81. //
  82. // we only write the special app verifier settings if we're not in Win2K mode
  83. //
  84. if (!g_bWin2KMode) {
  85. //
  86. // now write the app verifier settings
  87. //
  88. if (bDesireEnabled) {
  89. lResult = RegSetValueEx(hKey,
  90. g_szVerifierFlagsValueName,
  91. 0,
  92. REG_DWORD,
  93. (PBYTE) &dwDesiredFlags,
  94. sizeof(dwDesiredFlags));
  95. if (lResult != ERROR_SUCCESS) {
  96. goto out;
  97. }
  98. } else {
  99. lResult = RegDeleteValue(hKey, g_szVerifierFlagsValueName);
  100. if (lResult != ERROR_SUCCESS) {
  101. goto out;
  102. }
  103. }
  104. }
  105. bRet = TRUE;
  106. out:
  107. return bRet;
  108. }
  109. DWORD
  110. GetAppVerifierFlagsFromKey(
  111. HKEY hKey
  112. )
  113. {
  114. DWORD dwRet = 0;
  115. DWORD dwValueType = 0;
  116. DWORD dwDataSize = 0;
  117. TCHAR szOldGlobalFlagValue[32];
  118. BOOL bSuccesfullyConverted;
  119. LONG lResult;
  120. DWORD dwFlags = 0;
  121. //
  122. // Read the GlobalFlag value
  123. //
  124. dwDataSize = sizeof(szOldGlobalFlagValue);
  125. lResult = RegQueryValueEx(hKey,
  126. g_szGlobalFlagValueName,
  127. NULL,
  128. &dwValueType,
  129. (LPBYTE)&szOldGlobalFlagValue[0],
  130. &dwDataSize);
  131. if (ERROR_SUCCESS == lResult) {
  132. bSuccesfullyConverted = AVRtlCharToInteger(szOldGlobalFlagValue,
  133. 0,
  134. &dwFlags);
  135. if (g_bWin2KMode) {
  136. //
  137. // special check for Win2K
  138. //
  139. if ((FALSE != bSuccesfullyConverted) &&
  140. ((dwFlags & FLG_HEAP_PAGE_ALLOCS) != 0)) {
  141. dwRet = RTL_VRF_FLG_FULL_PAGE_HEAP;
  142. }
  143. } else {
  144. if ((FALSE != bSuccesfullyConverted) &&
  145. ((dwFlags & FLG_APPLICATION_VERIFIER) != 0)) {
  146. //
  147. // App verifier is enabled for this app - read the verifier flags
  148. //
  149. dwDataSize = sizeof(dwRet);
  150. lResult = RegQueryValueEx(hKey,
  151. g_szVerifierFlagsValueName,
  152. NULL,
  153. &dwValueType,
  154. (LPBYTE)&dwRet,
  155. &dwDataSize);
  156. if (ERROR_SUCCESS != lResult || REG_DWORD != dwValueType) {
  157. //
  158. // couldn't get them, for one reason or another
  159. //
  160. dwRet = 0;
  161. }
  162. }
  163. }
  164. }
  165. return dwRet;
  166. }
  167. void
  168. SetAppVerifierFullPathForKey(
  169. HKEY hKey,
  170. wstring& strPath
  171. )
  172. {
  173. if (strPath.size() == 0) {
  174. RegDeleteValue(hKey, g_szVerifierPathValueName);
  175. } else {
  176. RegSetValueEx(hKey,
  177. g_szVerifierPathValueName,
  178. 0,
  179. REG_SZ,
  180. (PBYTE) strPath.c_str(),
  181. (strPath.size() + 1) * sizeof(WCHAR));
  182. }
  183. }
  184. void
  185. SetDebuggerOptionsForKey(
  186. HKEY hKey,
  187. CAVAppInfo *pApp
  188. )
  189. {
  190. WCHAR szName[MAX_PATH];
  191. StringCchCopyW(szName, ARRAY_LENGTH(szName), L"\"");
  192. GetModuleFileName(NULL, szName + 1, MAX_PATH - 10);
  193. StringCchCatW(szName, ARRAY_LENGTH(szName), L"\" /debug");
  194. if (pApp && pApp->bBreakOnLog && pApp->wstrDebugger.size()) {
  195. RegSetValueEx(hKey,
  196. g_szDebuggerKeyName,
  197. 0,
  198. REG_SZ,
  199. (PBYTE)pApp->wstrDebugger.c_str(),
  200. (pApp->wstrDebugger.size() + 1) * sizeof(WCHAR));
  201. } else {
  202. WCHAR szDbgName[MAX_PATH];
  203. DWORD cbSize;
  204. cbSize = sizeof(szDbgName);
  205. szDbgName[0] = 0;
  206. RegQueryValueEx(hKey,
  207. g_szDebuggerKeyName,
  208. 0,
  209. NULL,
  210. (PBYTE)szDbgName,
  211. &cbSize);
  212. //
  213. // if the current debugger matches either our own debugger or the user selected one,
  214. // delete it, but leave alone any other debugger
  215. //
  216. if ((_wcsicmp(szName, szDbgName) == 0) || (pApp && (_wcsicmp(pApp->wstrDebugger.c_str(), szDbgName) == 0))) {
  217. RegDeleteValue(hKey, g_szDebuggerKeyName);
  218. }
  219. }
  220. }
  221. void
  222. GetAppVerifierFullPathFromKey(
  223. HKEY hKey,
  224. wstring& strPath
  225. )
  226. {
  227. DWORD dwValueType = 0;
  228. DWORD dwDataSize = 0;
  229. TCHAR szVerifierPath[MAX_PATH];
  230. LONG lResult;
  231. //
  232. // Read the GlobalFlag value
  233. //
  234. dwDataSize = sizeof(szVerifierPath);
  235. szVerifierPath[0] = 0;
  236. lResult = RegQueryValueEx(hKey,
  237. g_szVerifierPathValueName,
  238. NULL,
  239. &dwValueType,
  240. (LPBYTE)szVerifierPath,
  241. &dwDataSize);
  242. if (ERROR_SUCCESS == lResult && dwValueType == REG_SZ) {
  243. strPath = szVerifierPath;
  244. }
  245. }
  246. void
  247. GetCurrentAppSettingsFromRegistry(
  248. void
  249. )
  250. {
  251. HKEY hImageOptionsKey;
  252. HKEY hSubKey;
  253. DWORD dwSubkeyIndex;
  254. DWORD dwDataSize;
  255. DWORD dwValueType;
  256. DWORD dwFlags;
  257. LONG lResult;
  258. FILETIME LastWriteTime;
  259. TCHAR szOldGlobalFlagValue[32];
  260. TCHAR szKeyNameBuffer[256];
  261. //
  262. // Open the Image File Execution Options regkey
  263. //
  264. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  265. g_szImageOptionsKeyName,
  266. 0,
  267. KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
  268. &hImageOptionsKey);
  269. if (lResult != ERROR_SUCCESS) {
  270. if (lResult == ERROR_ACCESS_DENIED) {
  271. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  272. } else {
  273. AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED,
  274. g_szImageOptionsKeyName,
  275. (DWORD)lResult);
  276. }
  277. return;
  278. }
  279. //
  280. // Enumerate all the existing subkeys for app execution options
  281. //
  282. for (dwSubkeyIndex = 0; TRUE; dwSubkeyIndex += 1) {
  283. wstring wstrPath;
  284. dwDataSize = ARRAY_LENGTH(szKeyNameBuffer);
  285. lResult = RegEnumKeyEx(hImageOptionsKey,
  286. dwSubkeyIndex,
  287. szKeyNameBuffer,
  288. &dwDataSize,
  289. NULL,
  290. NULL,
  291. NULL,
  292. &LastWriteTime);
  293. if (lResult != ERROR_SUCCESS) {
  294. if (lResult == ERROR_NO_MORE_ITEMS) {
  295. //
  296. // We finished looking at all the existing subkeys
  297. //
  298. break;
  299. } else {
  300. if (lResult == ERROR_ACCESS_DENIED) {
  301. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  302. } else {
  303. AVErrorResourceFormat(IDS_REGENUMKEYEX_FAILED,
  304. g_szImageOptionsKeyName,
  305. (DWORD)lResult);
  306. }
  307. goto CleanUpAndDone;
  308. }
  309. }
  310. //
  311. // Open the subkey
  312. //
  313. lResult = RegOpenKeyEx(hImageOptionsKey,
  314. szKeyNameBuffer,
  315. 0,
  316. KEY_QUERY_VALUE | KEY_SET_VALUE,
  317. &hSubKey);
  318. if (lResult != ERROR_SUCCESS) {
  319. if (lResult == ERROR_ACCESS_DENIED) {
  320. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  321. } else {
  322. AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED,
  323. szKeyNameBuffer,
  324. (DWORD)lResult);
  325. }
  326. goto CleanUpAndDone;
  327. }
  328. dwFlags = GetAppVerifierFlagsFromKey(hSubKey);
  329. GetAppVerifierFullPathFromKey(hSubKey, wstrPath);
  330. if (dwFlags || wstrPath.size()) {
  331. //
  332. // Update the info in the array, or add it if necessary
  333. //
  334. CAVAppInfo* pApp;
  335. BOOL bFound = FALSE;
  336. for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) {
  337. if (_wcsicmp(pApp->wstrExeName.c_str(), szKeyNameBuffer) == 0) {
  338. bFound = TRUE;
  339. pApp->dwRegFlags = dwFlags;
  340. pApp->wstrExePath = wstrPath;
  341. break;
  342. }
  343. }
  344. if (!bFound) {
  345. CAVAppInfo AppInfo;
  346. AppInfo.wstrExeName = szKeyNameBuffer;
  347. AppInfo.dwRegFlags = dwFlags;
  348. AppInfo.wstrExePath = wstrPath;
  349. g_aAppInfo.push_back(AppInfo);
  350. }
  351. }
  352. VERIFY(ERROR_SUCCESS == RegCloseKey(hSubKey));
  353. }
  354. CleanUpAndDone:
  355. VERIFY(ERROR_SUCCESS == RegCloseKey(hImageOptionsKey));
  356. }
  357. void
  358. GetCurrentAppSettingsFromSDB(
  359. void
  360. )
  361. {
  362. CAVAppInfo AppInfo;
  363. TCHAR szPath[MAX_PATH];
  364. PDB pdb = NULL;
  365. TAGID tiDB = TAGID_NULL;
  366. TAGID tiExe = TAGID_NULL;
  367. //
  368. // go find the SDB
  369. //
  370. szPath[0] = 0;
  371. GetSystemWindowsDirectory(szPath, MAX_PATH);
  372. #if defined(_WIN64)
  373. StringCchCatW(szPath, ARRAY_LENGTH(szPath), _T("\\AppPatch\\Custom\\IA64\\") AVDB_ID_64 _T(".sdb"));
  374. #else
  375. StringCchCatW(szPath, ARRAY_LENGTH(szPath), _T("\\AppPatch\\Custom\\") AVDB_ID_32 _T(".sdb"));
  376. #endif // _WIN64
  377. pdb = SdbOpenDatabase(szPath, DOS_PATH);
  378. if (!pdb) {
  379. //
  380. // no current DB
  381. //
  382. goto out;
  383. }
  384. //
  385. // enumerate all the apps and the shims applied to them
  386. //
  387. tiDB = SdbFindFirstTag(pdb, TAGID_ROOT, TAG_DATABASE);
  388. if (!tiDB) {
  389. goto out;
  390. }
  391. tiExe = SdbFindFirstTag(pdb, tiDB, TAG_EXE);
  392. while (tiExe) {
  393. WCHAR* wszName = NULL;
  394. TAGID tiShim = TAGID_NULL;
  395. TAGID tiName = SdbFindFirstTag(pdb, tiExe, TAG_NAME);
  396. if (!tiName) {
  397. goto nextExe;
  398. }
  399. wszName = SdbGetStringTagPtr(pdb, tiName);
  400. if (!wszName) {
  401. goto nextExe;
  402. }
  403. CAVAppInfoArray::iterator it;
  404. BOOL bFound = FALSE;
  405. for (it = g_aAppInfo.begin(); it != g_aAppInfo.end(); it++) {
  406. if (_wcsicmp(it->wstrExeName.c_str(), wszName) == 0) {
  407. bFound = TRUE;
  408. break;
  409. }
  410. }
  411. if (!bFound) {
  412. AppInfo.wstrExeName = wszName;
  413. g_aAppInfo.push_back(AppInfo);
  414. it = g_aAppInfo.end() - 1;
  415. }
  416. tiShim = SdbFindFirstTag(pdb, tiExe, TAG_SHIM_REF);
  417. while (tiShim) {
  418. WCHAR* wszShimName = NULL;
  419. TAGID tiShimName = SdbFindFirstTag(pdb, tiShim, TAG_NAME);
  420. if (!tiShimName) {
  421. goto nextShim;
  422. }
  423. wszShimName = SdbGetStringTagPtr(pdb, tiShimName);
  424. it->awstrShims.push_back(wstring(wszShimName));
  425. nextShim:
  426. tiShim = SdbFindNextTag(pdb, tiExe, tiShim);
  427. }
  428. nextExe:
  429. tiExe = SdbFindNextTag(pdb, tiDB, tiExe);
  430. }
  431. out:
  432. if (pdb) {
  433. SdbCloseDatabase(pdb);
  434. pdb = NULL;
  435. }
  436. return;
  437. }
  438. void
  439. InitDefaultAppSettings(
  440. void
  441. )
  442. {
  443. BOOL bFound = FALSE;
  444. //
  445. // see if it's already in the list
  446. //
  447. for (CAVAppInfo *pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) {
  448. if (pApp->wstrExeName == AVRF_DEFAULT_SETTINGS_NAME_W) {
  449. if (pApp != g_aAppInfo.begin()) {
  450. //
  451. // it's not at the beginning, so move it to the beginning
  452. //
  453. CAVAppInfo AppTemp;
  454. AppTemp = *pApp;
  455. g_aAppInfo.erase(pApp);
  456. g_aAppInfo.insert(g_aAppInfo.begin(), AppTemp);
  457. }
  458. bFound = TRUE;
  459. break;
  460. }
  461. }
  462. //
  463. // it's not, so add it to the beginning
  464. //
  465. if (!bFound) {
  466. CAVAppInfo AppInfo;
  467. AppInfo.wstrExeName = AVRF_DEFAULT_SETTINGS_NAME_W;
  468. CTestInfo *pTest;
  469. for (pTest = g_aTestInfo.begin(); pTest != g_aTestInfo.end(); pTest++) {
  470. if (pTest->bDefault) {
  471. AppInfo.AddTest(*pTest);
  472. }
  473. }
  474. g_aAppInfo.insert(g_aAppInfo.begin(), AppInfo);
  475. }
  476. }
  477. void
  478. GetCurrentAppSettings(
  479. void
  480. )
  481. {
  482. g_aAppInfo.clear();
  483. //
  484. // make sure default is in the first position
  485. //
  486. CAVAppInfo AppInfo;
  487. AppInfo.wstrExeName = AVRF_DEFAULT_SETTINGS_NAME_W;
  488. g_aAppInfo.push_back(AppInfo);
  489. GetCurrentAppSettingsFromRegistry();
  490. GetCurrentAppSettingsFromSDB();
  491. InitDefaultAppSettings();
  492. }
  493. void
  494. SetCurrentRegistrySettings(
  495. void
  496. )
  497. {
  498. HKEY hImageOptionsKey;
  499. HKEY hSubKey = NULL;
  500. DWORD dwSubkeyIndex;
  501. DWORD dwDataSize;
  502. DWORD dwValueType;
  503. DWORD dwFlags;
  504. LONG lResult;
  505. FILETIME LastWriteTime;
  506. TCHAR szKeyNameBuffer[ 256 ];
  507. CAVAppInfo* pApp;
  508. wstring wstrEmpty = L"";
  509. //
  510. // Open the Image File Execution Options regkey
  511. //
  512. lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  513. g_szImageOptionsKeyName,
  514. 0,
  515. KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS,
  516. &hImageOptionsKey);
  517. if (lResult != ERROR_SUCCESS) {
  518. if (lResult == ERROR_ACCESS_DENIED) {
  519. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  520. } else {
  521. AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED,
  522. g_szImageOptionsKeyName,
  523. (DWORD)lResult);
  524. }
  525. return;
  526. }
  527. //
  528. // Enumerate all the existing subkeys for app execution options
  529. //
  530. for (dwSubkeyIndex = 0; TRUE; dwSubkeyIndex += 1) {
  531. dwDataSize = ARRAY_LENGTH(szKeyNameBuffer);
  532. lResult = RegEnumKeyEx(hImageOptionsKey,
  533. dwSubkeyIndex,
  534. szKeyNameBuffer,
  535. &dwDataSize,
  536. NULL,
  537. NULL,
  538. NULL,
  539. &LastWriteTime);
  540. if (lResult != ERROR_SUCCESS) {
  541. if (lResult == ERROR_NO_MORE_ITEMS) {
  542. //
  543. // We finished looking at all the existing subkeys
  544. //
  545. break;
  546. } else {
  547. if (lResult == ERROR_ACCESS_DENIED) {
  548. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  549. } else {
  550. AVErrorResourceFormat(IDS_REGENUMKEYEX_FAILED,
  551. g_szImageOptionsKeyName,
  552. (DWORD)lResult);
  553. }
  554. goto CleanUpAndDone;
  555. }
  556. }
  557. //
  558. // Open the subkey
  559. //
  560. lResult = RegOpenKeyEx(hImageOptionsKey,
  561. szKeyNameBuffer,
  562. 0,
  563. KEY_QUERY_VALUE | KEY_SET_VALUE,
  564. &hSubKey);
  565. if (lResult != ERROR_SUCCESS) {
  566. if (lResult == ERROR_ACCESS_DENIED) {
  567. AVErrorResourceFormat(IDS_ACCESS_IS_DENIED);
  568. } else {
  569. AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED,
  570. szKeyNameBuffer,
  571. (DWORD)lResult);
  572. }
  573. goto CleanUpAndDone;
  574. }
  575. dwFlags = GetAppVerifierFlagsFromKey(hSubKey);
  576. DWORD dwDesiredFlags = 0;
  577. BOOL bFound = FALSE;
  578. for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) {
  579. if (_wcsicmp(pApp->wstrExeName.c_str(), szKeyNameBuffer) == 0) {
  580. dwDesiredFlags = pApp->dwRegFlags;
  581. bFound = TRUE;
  582. //
  583. // we found it, so update the full path
  584. //
  585. SetAppVerifierFullPathForKey(hSubKey, pApp->wstrExePath);
  586. //
  587. // and add the debugger as well
  588. //
  589. SetDebuggerOptionsForKey(hSubKey, pApp);
  590. break;
  591. }
  592. }
  593. if (!bFound) {
  594. //
  595. // if this one isn't in our list, make sure it doesn't
  596. // have a full path or our debugger set
  597. //
  598. SetAppVerifierFullPathForKey(hSubKey, wstrEmpty);
  599. SetDebuggerOptionsForKey(hSubKey, NULL);
  600. }
  601. if (dwFlags != dwDesiredFlags) {
  602. SetAppVerifierFlagsForKey(hSubKey, dwDesiredFlags);
  603. }
  604. VERIFY(ERROR_SUCCESS == RegCloseKey(hSubKey));
  605. hSubKey = NULL;
  606. }
  607. //
  608. // and now go through the list the other way, looking for new ones to add
  609. //
  610. for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) {
  611. lResult = RegOpenKeyEx(hImageOptionsKey,
  612. pApp->wstrExeName.c_str(),
  613. 0,
  614. KEY_QUERY_VALUE | KEY_SET_VALUE,
  615. &hSubKey);
  616. //
  617. // if it exists, we've already dealt with it above
  618. //
  619. if (lResult != ERROR_SUCCESS) {
  620. //
  621. // it doesn't exist. Try to create it.
  622. //
  623. lResult = RegCreateKeyEx(hImageOptionsKey,
  624. pApp->wstrExeName.c_str(),
  625. 0,
  626. NULL,
  627. REG_OPTION_NON_VOLATILE,
  628. KEY_QUERY_VALUE | KEY_SET_VALUE,
  629. NULL,
  630. &hSubKey,
  631. NULL);
  632. if (lResult == ERROR_SUCCESS) {
  633. SetAppVerifierFlagsForKey(hSubKey, pApp->dwRegFlags);
  634. SetAppVerifierFullPathForKey(hSubKey, pApp->wstrExePath);
  635. SetDebuggerOptionsForKey(hSubKey, pApp);
  636. }
  637. }
  638. if (hSubKey) {
  639. RegCloseKey(hSubKey);
  640. hSubKey = NULL;
  641. }
  642. }
  643. CleanUpAndDone:
  644. VERIFY(ERROR_SUCCESS == RegCloseKey(hImageOptionsKey));
  645. }
  646. void
  647. SetCurrentAppSettings(
  648. void
  649. )
  650. {
  651. SetCurrentRegistrySettings();
  652. AppCompatWriteShimSettings(g_aAppInfo, TRUE);
  653. #if defined(_WIN64)
  654. AppCompatWriteShimSettings(g_aAppInfo, FALSE);
  655. #endif
  656. }
  657. KERNEL_TEST_INFO g_KernelTests[] =
  658. {
  659. {
  660. IDS_PAGE_HEAP,
  661. IDS_PAGE_HEAP_DESC,
  662. RTL_VRF_FLG_FULL_PAGE_HEAP,
  663. TRUE,
  664. L"PageHeap",
  665. TRUE
  666. },
  667. {
  668. IDS_VERIFY_LOCKS_CHECKS,
  669. IDS_VERIFY_LOCKS_CHECKS_DESC,
  670. RTL_VRF_FLG_LOCK_CHECKS,
  671. TRUE,
  672. L"Locks",
  673. FALSE
  674. },
  675. {
  676. IDS_VERIFY_HANDLE_CHECKS,
  677. IDS_VERIFY_HANDLE_CHECKS_DESC,
  678. RTL_VRF_FLG_HANDLE_CHECKS,
  679. TRUE,
  680. L"Handles",
  681. FALSE
  682. },
  683. {
  684. IDS_VERIFY_STACK_CHECKS,
  685. IDS_VERIFY_STACK_CHECKS_DESC,
  686. RTL_VRF_FLG_STACK_CHECKS,
  687. FALSE,
  688. L"Stacks",
  689. FALSE
  690. },
  691. {
  692. IDS_VERIFY_RPC_CHECKS,
  693. IDS_VERIFY_RPC_CHECKS_DESC,
  694. RTL_VRF_FLG_RPC_CHECKS,
  695. FALSE,
  696. L"RPC Checks",
  697. FALSE
  698. }
  699. };
  700. BOOL
  701. GetKernelTestInfo(
  702. CTestInfoArray& TestArray
  703. )
  704. {
  705. CTestInfo ti;
  706. TCHAR szTemp[256];
  707. int i;
  708. ti.eTestType = TEST_KERNEL;
  709. for (i = 0; i < ARRAY_LENGTH(g_KernelTests); ++i) {
  710. ti.strTestName = g_KernelTests[i].m_szCommandLine;
  711. if (AVLoadString(g_KernelTests[i].m_uFriendlyNameStringId, szTemp, ARRAY_LENGTH(szTemp))) {
  712. ti.strTestFriendlyName = szTemp;
  713. } else {
  714. ti.strTestFriendlyName = ti.strTestName;
  715. }
  716. if (AVLoadString(g_KernelTests[i].m_uDescriptionStringId, szTemp, ARRAY_LENGTH(szTemp))) {
  717. ti.strTestDescription = szTemp;
  718. } else {
  719. ti.strTestDescription = L"";
  720. }
  721. ti.dwKernelFlag = g_KernelTests[i].m_dwBit;
  722. ti.bDefault = g_KernelTests[i].m_bDefault;
  723. ti.bWin2KCompatible = g_KernelTests[i].m_bWin2KCompatible;
  724. TestArray.push_back(ti);
  725. }
  726. return TRUE;
  727. }
  728. void
  729. ParseIncludeList(
  730. WCHAR* szList,
  731. CIncludeArray& aArray
  732. )
  733. {
  734. if (!szList) {
  735. return;
  736. }
  737. BOOL bInclude = TRUE;
  738. WCHAR *szBegin = szList;
  739. WCHAR *szEnd = NULL;
  740. DWORD dwLen = 0;
  741. while (1) {
  742. //
  743. // skip space
  744. //
  745. while (*szBegin == L' ') {
  746. szBegin++;
  747. }
  748. //
  749. // check for end
  750. //
  751. if (*szBegin == 0) {
  752. break;
  753. }
  754. //
  755. // check for E: or I:
  756. //
  757. if (_wcsnicmp(szBegin, L"E:", 2) == 0) {
  758. bInclude = FALSE;
  759. szBegin += 2;
  760. continue;
  761. }
  762. if (_wcsnicmp(szBegin, L"I:", 2) == 0) {
  763. bInclude = TRUE;
  764. szBegin += 2;
  765. continue;
  766. }
  767. szEnd = wcschr(szBegin, L' ');
  768. if (szEnd) {
  769. dwLen = szEnd - szBegin;
  770. } else {
  771. dwLen = wcslen(szBegin);
  772. }
  773. if (dwLen) {
  774. WCHAR szTemp[MAX_PATH];
  775. CIncludeInfo Include;
  776. memcpy(szTemp, szBegin, dwLen * sizeof(WCHAR));
  777. szTemp[dwLen] = 0;
  778. Include.bInclude = bInclude;
  779. Include.strModule = szTemp;
  780. aArray.push_back(Include);
  781. szBegin += dwLen;
  782. } else {
  783. //
  784. // just in case
  785. //
  786. break;
  787. }
  788. }
  789. }
  790. BOOL
  791. GetShimInfo(
  792. CTestInfoArray& TestInfoArray
  793. )
  794. {
  795. HKEY hKey = NULL;
  796. BOOL bRet = FALSE;
  797. int nWhich = 0;
  798. TCHAR szAppPatch[MAX_PATH];
  799. TCHAR szShimFullPath[MAX_PATH];
  800. HMODULE hMod = NULL;
  801. _pfnGetVerifierMagic pGetVerifierMagic = NULL;
  802. _pfnQueryShimInfo pQueryShimInfo = NULL;
  803. LPWSTR *pShimNames = NULL;
  804. DWORD dwShims = 0;
  805. WIN32_FIND_DATA FindData;
  806. HANDLE hFind = INVALID_HANDLE_VALUE;
  807. TCHAR szDllSearch[MAX_PATH];
  808. szAppPatch[0] = 0;
  809. GetSystemWindowsDirectory(szAppPatch, MAX_PATH);
  810. #if defined(_WIN64)
  811. StringCchCatW(szAppPatch, ARRAY_LENGTH(szAppPatch), _T("\\AppPatch\\IA64\\"));
  812. #else
  813. StringCchCatW(szAppPatch, ARRAY_LENGTH(szAppPatch), _T("\\AppPatch\\"));
  814. #endif // defined(_WIN64)
  815. StringCchCopyW(szDllSearch, ARRAY_LENGTH(szDllSearch), szAppPatch);
  816. StringCchCatW(szDllSearch, ARRAY_LENGTH(szDllSearch), _T("*.dll"));
  817. //
  818. // enumerate all the DLLs and look for ones that have Verification
  819. // shims in them
  820. //
  821. hFind = FindFirstFile(szDllSearch, &FindData);
  822. while (hFind != INVALID_HANDLE_VALUE) {
  823. BOOL bVerifierShim = FALSE;
  824. StringCchCopyW(szShimFullPath, ARRAY_LENGTH(szShimFullPath), szAppPatch);
  825. StringCchCatW(szShimFullPath, ARRAY_LENGTH(szShimFullPath), FindData.cFileName);
  826. hMod = LoadLibrary(szShimFullPath);
  827. if (!hMod) {
  828. goto nextKey;
  829. }
  830. pGetVerifierMagic = (_pfnGetVerifierMagic)GetProcAddress(hMod, "GetVerifierMagic");
  831. if (!pGetVerifierMagic) {
  832. //
  833. // not a real verifier shim
  834. //
  835. goto nextKey;
  836. }
  837. if (pGetVerifierMagic() != VERIFIER_SHIMS_MAGIC) {
  838. //
  839. // not a real verifier shim
  840. //
  841. goto nextKey;
  842. }
  843. pQueryShimInfo = (_pfnQueryShimInfo)GetProcAddress(hMod, "QueryShimInfo");
  844. if (!pQueryShimInfo) {
  845. //
  846. // not a real verifier shim
  847. //
  848. goto nextKey;
  849. }
  850. dwShims = 0;
  851. if (!pQueryShimInfo(NULL, AVRF_INFO_NUM_SHIMS, (PVOID)&dwShims) || dwShims == 0) {
  852. //
  853. // no shims available
  854. //
  855. goto nextKey;
  856. }
  857. bVerifierShim = TRUE;
  858. pShimNames = new LPWSTR[dwShims];
  859. if (!pShimNames) {
  860. goto out;
  861. }
  862. if (!pQueryShimInfo(NULL, AVRF_INFO_SHIM_NAMES, (PVOID)pShimNames)) {
  863. goto nextKey;
  864. }
  865. for (DWORD i = 0; i < dwShims; ++i) {
  866. CTestInfo ti;
  867. LPWSTR szTemp = NULL;
  868. DWORD dwFlags = 0;
  869. DWORD dwVersion = 0;
  870. ti.eTestType = TEST_SHIM;
  871. ti.strDllName = FindData.cFileName;
  872. ti.strTestName = pShimNames[i];
  873. szTemp = NULL;
  874. if (pQueryShimInfo(pShimNames[i], AVRF_INFO_FRIENDLY_NAME, (PVOID)&szTemp) && szTemp) {
  875. ti.strTestFriendlyName = szTemp;
  876. } else {
  877. //
  878. // default to the shim name
  879. //
  880. ti.strTestFriendlyName = pShimNames[i];
  881. }
  882. if (pQueryShimInfo(pShimNames[i], AVRF_INFO_VERSION, (PVOID)&dwVersion)) {
  883. WCHAR szVersion[40];
  884. ti.wVersionHigh = HIWORD(dwVersion);
  885. ti.wVersionLow = LOWORD(dwVersion);
  886. StringCchPrintfW(szVersion, ARRAY_LENGTH(szVersion), L" (%d.%d)", ti.wVersionHigh, ti.wVersionLow);
  887. ti.strTestFriendlyName += szVersion;
  888. }
  889. szTemp = NULL;
  890. if (pQueryShimInfo(pShimNames[i], AVRF_INFO_DESCRIPTION, (PVOID)&szTemp) && szTemp) {
  891. ti.strTestDescription = szTemp;
  892. }
  893. if (pQueryShimInfo(pShimNames[i], AVRF_INFO_FLAGS, (PVOID)&dwFlags)) {
  894. ti.bDefault = !(dwFlags & AVRF_FLAG_NO_DEFAULT) && !(dwFlags & AVRF_FLAG_RUN_ALONE);
  895. ti.bWin2KCompatible = !(dwFlags & AVRF_FLAG_NO_WIN2K);
  896. ti.bSetupOK = !(dwFlags & AVRF_FLAG_NOT_SETUP);
  897. ti.bNonSetupOK = !(dwFlags & AVRF_FLAG_ONLY_SETUP);
  898. ti.bRunAlone = !!(dwFlags & AVRF_FLAG_RUN_ALONE);
  899. ti.bPseudoShim = !!(dwFlags & AVRF_FLAG_NO_SHIM);
  900. ti.bNonTest = !!(dwFlags & AVRF_FLAG_NO_TEST);
  901. ti.bInternal = !(dwFlags & AVRF_FLAG_EXTERNAL_ONLY);
  902. ti.bExternal = !(dwFlags & AVRF_FLAG_INTERNAL_ONLY);
  903. } else {
  904. ti.bDefault = TRUE;
  905. ti.bWin2KCompatible = TRUE;
  906. ti.bSetupOK = TRUE;
  907. ti.bNonSetupOK = TRUE;
  908. ti.bRunAlone = FALSE;
  909. ti.bPseudoShim = FALSE;
  910. ti.bNonTest = FALSE;
  911. ti.bInternal = TRUE;
  912. ti.bExternal = TRUE;
  913. }
  914. szTemp = NULL;
  915. if (pQueryShimInfo(pShimNames[i], AVRF_INFO_INCLUDE_EXCLUDE, (PVOID)&szTemp) && szTemp) {
  916. ParseIncludeList(szTemp, ti.aIncludes);
  917. }
  918. //
  919. // now get the PropSheetPage
  920. //
  921. if (pQueryShimInfo(pShimNames[i], AVRF_INFO_OPTIONS_PAGE, (PVOID)&(ti.PropSheetPage))) {
  922. ti.PropSheetPage.dwFlags |= PSP_USETITLE;
  923. ti.PropSheetPage.pszTitle = ti.strTestName.c_str();
  924. } else {
  925. ZeroMemory(&(ti.PropSheetPage), sizeof(PROPSHEETPAGE));
  926. }
  927. //
  928. // add it to the end
  929. //
  930. TestInfoArray.push_back(ti);
  931. }
  932. nextKey:
  933. if (pShimNames) {
  934. delete [] pShimNames;
  935. pShimNames = NULL;
  936. }
  937. if (hMod) {
  938. //
  939. // if it's a verifier shim, we need to keep it around
  940. //
  941. if (!bVerifierShim) {
  942. FreeLibrary(hMod);
  943. }
  944. hMod = NULL;
  945. }
  946. if (!FindNextFile(hFind, &FindData)) {
  947. FindClose(hFind);
  948. hFind = INVALID_HANDLE_VALUE;
  949. }
  950. }
  951. bRet = TRUE;
  952. out:
  953. if (hMod) {
  954. FreeLibrary(hMod);
  955. hMod = NULL;
  956. }
  957. if (hFind != INVALID_HANDLE_VALUE) {
  958. FindClose(hFind);
  959. hFind = INVALID_HANDLE_VALUE;
  960. }
  961. return bRet;
  962. }
  963. BOOL
  964. InitTestInfo(
  965. void
  966. )
  967. {
  968. g_aTestInfo.clear();
  969. if (!GetKernelTestInfo(g_aTestInfo)) {
  970. return FALSE;
  971. }
  972. if (!GetShimInfo(g_aTestInfo)) {
  973. return FALSE;
  974. }
  975. return TRUE;
  976. }
  977. void
  978. ResetVerifierLog(
  979. void
  980. )
  981. {
  982. WIN32_FIND_DATA FindData;
  983. HANDLE hFind = INVALID_HANDLE_VALUE;
  984. BOOL bFound;
  985. DWORD cchSize;
  986. TCHAR szVLogPath[MAX_PATH];
  987. TCHAR szVLogSearch[MAX_PATH];
  988. TCHAR szPath[MAX_PATH];
  989. HANDLE hFile;
  990. cchSize = GetAppVerifierLogPath(szVLogPath, ARRAY_LENGTH(szVLogPath));
  991. if (cchSize > ARRAY_LENGTH(szVLogPath) || cchSize == 0) {
  992. return;
  993. }
  994. StringCchCopyW(szVLogSearch, ARRAY_LENGTH(szVLogSearch), szVLogPath);
  995. StringCchCatW(szVLogSearch, ARRAY_LENGTH(szVLogSearch), _T("\\"));
  996. StringCchCatW(szVLogSearch, ARRAY_LENGTH(szVLogSearch), _T("*.log"));
  997. //
  998. // kill all the .log files
  999. //
  1000. hFind = FindFirstFile(szVLogSearch, &FindData);
  1001. while (hFind != INVALID_HANDLE_VALUE) {
  1002. StringCchCopyW(szPath, ARRAY_LENGTH(szPath), szVLogPath);
  1003. StringCchCatW(szPath, ARRAY_LENGTH(szPath), _T("\\"));
  1004. StringCchCatW(szPath, ARRAY_LENGTH(szPath), FindData.cFileName);
  1005. DeleteFile(szPath);
  1006. if (!FindNextFile(hFind, &FindData)) {
  1007. FindClose(hFind);
  1008. hFind = INVALID_HANDLE_VALUE;
  1009. }
  1010. }
  1011. //
  1012. // recreate session.log
  1013. //
  1014. CreateDirectory(szVLogPath, NULL);
  1015. StringCchCopyW(szPath, ARRAY_LENGTH(szPath), szVLogPath);
  1016. StringCchCatW(szPath, ARRAY_LENGTH(szPath), _T("\\"));
  1017. StringCchCatW(szPath, ARRAY_LENGTH(szPath), _T("session.log"));
  1018. hFile = CreateFile(szPath,
  1019. GENERIC_WRITE,
  1020. 0,
  1021. NULL,
  1022. CREATE_ALWAYS,
  1023. FILE_ATTRIBUTE_NORMAL,
  1024. NULL);
  1025. if (hFile != INVALID_HANDLE_VALUE) {
  1026. CloseHandle(hFile);
  1027. }
  1028. return;
  1029. }
  1030. void EnableVerifierLog(void)
  1031. {
  1032. HANDLE hFile;
  1033. TCHAR szPath[MAX_PATH];
  1034. TCHAR szVLogPath[MAX_PATH];
  1035. DWORD cchSize;
  1036. cchSize = GetAppVerifierLogPath(szVLogPath, ARRAY_LENGTH(szVLogPath));
  1037. if (cchSize > ARRAY_LENGTH(szVLogPath) || cchSize == 0) {
  1038. return;
  1039. }
  1040. //
  1041. // make sure log dir and session.log exists
  1042. //
  1043. CreateDirectory(szVLogPath, NULL);
  1044. StringCchCopyW(szPath, ARRAY_LENGTH(szPath), szVLogPath);
  1045. StringCchCatW(szPath, ARRAY_LENGTH(szPath), _T("\\"));
  1046. StringCchCatW(szPath, ARRAY_LENGTH(szPath), _T("session.log"));
  1047. hFile = CreateFile(szPath,
  1048. GENERIC_WRITE,
  1049. 0,
  1050. NULL,
  1051. CREATE_ALWAYS,
  1052. FILE_ATTRIBUTE_NORMAL,
  1053. NULL);
  1054. if (hFile != INVALID_HANDLE_VALUE) {
  1055. CloseHandle(hFile);
  1056. }
  1057. }
  1058. CTestInfo*
  1059. FindShim(
  1060. wstring& wstrName
  1061. )
  1062. {
  1063. CTestInfoArray::iterator it;
  1064. for (it = g_aTestInfo.begin(); it != g_aTestInfo.end(); it++) {
  1065. if (it->strTestName == wstrName) {
  1066. return &(*it);
  1067. }
  1068. }
  1069. return NULL;
  1070. }
  1071. extern "C" BOOL
  1072. ShimdbcExecute(
  1073. LPCWSTR lpszCmdLine
  1074. );
  1075. BOOL
  1076. AppCompatWriteShimSettings(
  1077. CAVAppInfoArray& arrAppInfo,
  1078. BOOL b32bitOnly
  1079. )
  1080. {
  1081. TCHAR szTempPath[MAX_PATH] = _T("");
  1082. TCHAR szXmlFile[MAX_PATH] = _T("");
  1083. TCHAR szSdbFile[MAX_PATH] = _T("");
  1084. HANDLE hFile = INVALID_HANDLE_VALUE;
  1085. DWORD bytesWritten;
  1086. STARTUPINFO si;
  1087. PROCESS_INFORMATION pi;
  1088. BOOL bReturn = FALSE;
  1089. TCHAR szUnicodeHdr[2] = { 0xFEFF, 0};
  1090. wstring wstrXML;
  1091. static WCHAR wszTemp[2048];
  1092. static WCHAR wszCmd[1024];
  1093. if (0 == arrAppInfo.size()) {
  1094. return AppCompatDeleteSettings();
  1095. }
  1096. wszTemp[0] = 0;
  1097. //
  1098. // Construct the XML...
  1099. //
  1100. #if defined(_WIN64)
  1101. if (!b32bitOnly) {
  1102. StringCchPrintfW(wszTemp,
  1103. ARRAYSIZE(wszTemp),
  1104. _T("%s<?xml version=\"1.0\"?>\r\n")
  1105. _T("<DATABASE NAME=\"Application Verifier Database (64 bit)\" ID=\"%s\">\r\n")
  1106. _T(" <LIBRARY>\r\n"),
  1107. szUnicodeHdr,
  1108. AVDB_ID_64);
  1109. } else
  1110. #endif
  1111. {
  1112. StringCchPrintfW(wszTemp,
  1113. ARRAYSIZE(wszTemp),
  1114. _T("%s<?xml version=\"1.0\"?>\r\n")
  1115. _T("<DATABASE NAME=\"Application Verifier Database\" ID=\"%s\">\r\n")
  1116. _T(" <LIBRARY>\r\n"),
  1117. szUnicodeHdr,
  1118. AVDB_ID_32);
  1119. }
  1120. wstrXML += wszTemp;
  1121. CTestInfoArray::iterator it;
  1122. for (it = g_aTestInfo.begin(); it != g_aTestInfo.end(); it++) {
  1123. if (it->eTestType != TEST_SHIM) {
  1124. continue;
  1125. }
  1126. StringCchPrintfW(wszTemp,
  1127. ARRAYSIZE(wszTemp),
  1128. _T(" <SHIM NAME=\"%s\" FILE=\"%s\">\r\n")
  1129. _T(" <DESCRIPTION>\r\n")
  1130. _T(" %s\r\n")
  1131. _T(" </DESCRIPTION>\r\n"),
  1132. it->strTestName.c_str(),
  1133. it->strDllName.c_str(),
  1134. it->strTestDescription.c_str());
  1135. wstrXML += wszTemp;
  1136. CIncludeArray::iterator iait;
  1137. for (iait = it->aIncludes.begin(); iait != it->aIncludes.end(); ++iait) {
  1138. if (iait->bInclude) {
  1139. StringCchPrintfW(wszTemp,
  1140. ARRAYSIZE(wszTemp),
  1141. _T(" <INCLUDE MODULE=\"%s\"/>\r\n"),
  1142. iait->strModule.c_str());
  1143. } else {
  1144. StringCchPrintfW(wszTemp,
  1145. ARRAYSIZE(wszTemp),
  1146. _T(" <EXCLUDE MODULE=\"%s\"/>\r\n"),
  1147. iait->strModule.c_str());
  1148. }
  1149. wstrXML += wszTemp;
  1150. }
  1151. //
  1152. // make sure the EXE is included
  1153. //
  1154. wstrXML += _T(" <INCLUDE MODULE=\"%EXE%\"/>\r\n");
  1155. wstrXML += _T(" </SHIM>\r\n");
  1156. }
  1157. //
  1158. // put in layers for handling propagation of shims -- one layer per EXE
  1159. //
  1160. CAVAppInfo* aiit;
  1161. for (aiit = arrAppInfo.begin(); aiit != arrAppInfo.end(); aiit++) {
  1162. //
  1163. // if there are no shims, we're done
  1164. //
  1165. if (aiit->awstrShims.size() == 0) {
  1166. continue;
  1167. }
  1168. if (aiit->bPropagateTests) {
  1169. StringCchPrintfW(wszTemp,
  1170. ARRAYSIZE(wszTemp),
  1171. _T(" <LAYER NAME=\"LAYER_%s\">\r\n"),
  1172. aiit->wstrExeName.c_str());
  1173. wstrXML += wszTemp;
  1174. CWStringArray::iterator wsit;
  1175. for (wsit = aiit->awstrShims.begin();
  1176. wsit != aiit->awstrShims.end();
  1177. wsit++) {
  1178. CTestInfo* pTestInfo = FindShim(*wsit);
  1179. if (pTestInfo) {
  1180. StringCchPrintfW(wszTemp,
  1181. ARRAYSIZE(wszTemp),
  1182. _T(" <SHIM NAME=\"%s\"/>\r\n"),
  1183. pTestInfo->strTestName.c_str());
  1184. wstrXML += wszTemp;
  1185. }
  1186. }
  1187. wstrXML += _T(" </LAYER>\r\n");
  1188. }
  1189. }
  1190. wstrXML += _T(" </LIBRARY>\r\n\r\n");
  1191. wstrXML += _T(" <APP NAME=\"All EXEs to be verified\" VENDOR=\"Various\">\r\n");
  1192. for (aiit = arrAppInfo.begin(); aiit != arrAppInfo.end(); aiit++) {
  1193. //
  1194. // if there are no shims, we're done
  1195. //
  1196. if (aiit->awstrShims.size() == 0) {
  1197. continue;
  1198. }
  1199. StringCchPrintfW(wszTemp,
  1200. ARRAYSIZE(wszTemp),
  1201. _T(" <EXE NAME=\"%s\">\r\n"),
  1202. aiit->wstrExeName.c_str());
  1203. wstrXML += wszTemp;
  1204. if (aiit->bPropagateTests) {
  1205. //
  1206. // we need to fill in the layer name
  1207. //
  1208. StringCchPrintfW(wszTemp,
  1209. ARRAYSIZE(wszTemp),
  1210. _T(" <LAYER NAME=\"LAYER_%s\"/>\r\n"),
  1211. aiit->wstrExeName.c_str());
  1212. wstrXML += wszTemp;
  1213. }
  1214. //
  1215. // we still need to save the shim names, so they won't be lost when we
  1216. // load appverifier again. It's redundant, but doesn't hurt anything.
  1217. //
  1218. CWStringArray::iterator wsit;
  1219. for (wsit = aiit->awstrShims.begin();
  1220. wsit != aiit->awstrShims.end();
  1221. wsit++) {
  1222. CTestInfo* pTestInfo = FindShim(*wsit);
  1223. if (pTestInfo) {
  1224. StringCchPrintfW(wszTemp,
  1225. ARRAYSIZE(wszTemp),
  1226. _T(" <SHIM NAME=\"%s\"/>\r\n"),
  1227. pTestInfo->strTestName.c_str());
  1228. wstrXML += wszTemp;
  1229. }
  1230. }
  1231. wstrXML += _T(" </EXE>\r\n");
  1232. }
  1233. wstrXML +=
  1234. _T(" </APP>\r\n")
  1235. _T("</DATABASE>");
  1236. if (GetTempPath(MAX_PATH, szTempPath) == 0) {
  1237. DPF("[AppCompatSaveSettings] GetTempPath failed.");
  1238. goto cleanup;
  1239. }
  1240. //
  1241. // Obtain a temp name for the XML file
  1242. //
  1243. if (GetTempFileName(szTempPath, _T("XML"), NULL, szXmlFile) == 0) {
  1244. DPF("[AppCompatSaveSettings] GetTempFilePath for XML failed.");
  1245. goto cleanup;
  1246. }
  1247. hFile = CreateFile(szXmlFile,
  1248. GENERIC_WRITE,
  1249. 0,
  1250. NULL,
  1251. CREATE_ALWAYS,
  1252. FILE_ATTRIBUTE_NORMAL,
  1253. NULL);
  1254. if (hFile == INVALID_HANDLE_VALUE) {
  1255. DPF("[AppCompatSaveSettings] CreateFile '%s' failed 0x%X.",
  1256. szXmlFile, GetLastError());
  1257. goto cleanup;
  1258. }
  1259. if (WriteFile(hFile, wstrXML.c_str(), wstrXML.length() * sizeof(TCHAR), &bytesWritten, NULL) == 0) {
  1260. DPF("[AppCompatSaveSettings] WriteFile \"%s\" failed 0x%X.",
  1261. szXmlFile, GetLastError());
  1262. goto cleanup;
  1263. }
  1264. CloseHandle(hFile);
  1265. hFile = INVALID_HANDLE_VALUE;
  1266. //
  1267. // Obtain a temp name for the SDB file
  1268. //
  1269. StringCchPrintfW(szSdbFile, ARRAY_LENGTH(szSdbFile), _T("%stempdb.sdb"), szTempPath);
  1270. DeleteFile(szSdbFile);
  1271. //
  1272. // Invoke the compiler to generate the SDB file
  1273. //
  1274. ZeroMemory(&si, sizeof(si));
  1275. si.cb = sizeof(si);
  1276. StringCchPrintfW(wszCmd, ARRAY_LENGTH(wszCmd), _T("shimdbc.exe fix -q \"%s\" \"%s\""), szXmlFile, szSdbFile);
  1277. if (!ShimdbcExecute(wszCmd)) {
  1278. DPF("[AppCompatSaveSettings] CreateProcess \"%s\" failed 0x%X.",
  1279. wszCmd, GetLastError());
  1280. goto cleanup;
  1281. }
  1282. //
  1283. // The SDB file is generated. Install the database now.
  1284. //
  1285. ZeroMemory(&si, sizeof(si));
  1286. si.cb = sizeof(si);
  1287. #if defined(_WIN64)
  1288. if (b32bitOnly) {
  1289. WCHAR wszSys[MAX_PATH] = L"";
  1290. int nLen;
  1291. GetSystemWindowsDirectory(wszSys, MAX_PATH);
  1292. nLen = wcslen(wszSys);
  1293. if (wszSys[nLen - 1] == L'\\') {
  1294. wszSys[nLen - 1] = 0;
  1295. }
  1296. StringCchPrintfW(wszCmd,
  1297. ARRAY_LENGTH(wszCmd),
  1298. _T("%s\\syswow64\\sdbinst.exe -q \"%s\""),
  1299. wszSys,
  1300. szSdbFile);
  1301. }
  1302. #endif
  1303. {
  1304. StringCchPrintfW(wszCmd, ARRAY_LENGTH(wszCmd), _T("sdbinst.exe -q \"%s\""), szSdbFile);
  1305. }
  1306. if (!CreateProcess(NULL,
  1307. wszCmd,
  1308. NULL,
  1309. NULL,
  1310. FALSE,
  1311. NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
  1312. NULL,
  1313. NULL,
  1314. &si,
  1315. &pi)) {
  1316. DPF("[AppCompatSaveSettings] CreateProcess \"%s\" failed 0x%X.",
  1317. wszCmd, GetLastError());
  1318. goto cleanup;
  1319. }
  1320. CloseHandle(pi.hThread);
  1321. WaitForSingleObject(pi.hProcess, INFINITE);
  1322. CloseHandle(pi.hProcess);
  1323. //
  1324. // ensure we've got a fresh log session started
  1325. //
  1326. EnableVerifierLog();
  1327. bReturn = TRUE;
  1328. cleanup:
  1329. if (hFile != INVALID_HANDLE_VALUE) {
  1330. CloseHandle(hFile);
  1331. }
  1332. DeleteFile(szXmlFile);
  1333. DeleteFile(szSdbFile);
  1334. return bReturn;
  1335. }
  1336. BOOL
  1337. AppCompatDeleteSettings(
  1338. void
  1339. )
  1340. {
  1341. STARTUPINFO si;
  1342. PROCESS_INFORMATION pi;
  1343. WCHAR wszCmd[MAX_PATH];
  1344. ZeroMemory(&si, sizeof(si));
  1345. si.cb = sizeof(si);
  1346. #if defined(_WIN64)
  1347. StringCchPrintfW(wszCmd, ARRAY_LENGTH(wszCmd), _T("sdbinst.exe -q -u -g ") AVDB_ID_64);
  1348. #else
  1349. StringCchPrintfW(wszCmd, ARRAY_LENGTH(wszCmd), _T("sdbinst.exe -q -u -g ") AVDB_ID_32);
  1350. #endif
  1351. if (!CreateProcess(NULL,
  1352. wszCmd,
  1353. NULL,
  1354. NULL,
  1355. FALSE,
  1356. NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW,
  1357. NULL,
  1358. NULL,
  1359. &si,
  1360. &pi)) {
  1361. DPF("[AppCompatDeleteSettings] CreateProcess \"%s\" failed 0x%X.",
  1362. wszCmd, GetLastError());
  1363. return FALSE;
  1364. }
  1365. CloseHandle(pi.hThread);
  1366. WaitForSingleObject(pi.hProcess, INFINITE);
  1367. CloseHandle(pi.hProcess);
  1368. return TRUE;
  1369. }