|
|
#include "precomp.h"
#include "ntexapi.h"
extern BOOL g_bClearSessionLogBeforeRun; extern BOOL g_bUseAVDebugger;
TCHAR g_szXML[32768];
TCHAR g_szCmd[1024];
/////////////////////////////////////////////////////////////////////////////
//
// Registry keys/values names
//
const TCHAR g_szImageOptionsKeyName[] = _T("Software\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options"); const TCHAR g_szGlobalFlagValueName[] = _T("GlobalFlag"); const TCHAR g_szVerifierFlagsValueName[] = _T("VerifierFlags"); const TCHAR g_szVerifierPathValueName[] = _T("VerifierPath"); const TCHAR g_szDebugger[] = _T("Debugger");
CAVAppInfoArray g_aAppInfo;
CTestInfoArray g_aTestInfo;
BOOL SetAppVerifierFlagsForKey( HKEY hKey, DWORD dwDesiredFlags ) { BOOL bRet = FALSE; DWORD dwValueType = 0; DWORD dwDataSize = 0; TCHAR szOldGlobalFlagValue[32]; BOOL bSuccesfullyConverted; BOOL bDesireEnabled = (dwDesiredFlags != 0); LONG lResult; DWORD dwFlags = 0;
//
// Read the GlobalFlag value
//
dwDataSize = sizeof(szOldGlobalFlagValue);
lResult = RegQueryValueEx(hKey, g_szGlobalFlagValueName, NULL, &dwValueType, (LPBYTE) &szOldGlobalFlagValue[0], &dwDataSize);
if (ERROR_SUCCESS == lResult) { bSuccesfullyConverted = AVRtlCharToInteger(szOldGlobalFlagValue, 0, &dwFlags); if (!bSuccesfullyConverted) { dwFlags = 0; } }
BOOL bEnabled = (dwFlags & FLG_APPLICATION_VERIFIER) != 0;
//
// write the new global flags, if necessary
//
if (bDesireEnabled != bEnabled) { if (bDesireEnabled) { dwFlags |= FLG_APPLICATION_VERIFIER; } else { dwFlags &= ~FLG_APPLICATION_VERIFIER; }
BOOL bSuccess = AVWriteStringHexValueToRegistry(hKey, g_szGlobalFlagValueName, dwFlags); if (!bSuccess) { goto out; } }
//
// now write the app verifier settings
//
if (bDesireEnabled) { lResult = RegSetValueEx(hKey, g_szVerifierFlagsValueName, 0, REG_DWORD, (PBYTE) &dwDesiredFlags, sizeof(dwDesiredFlags)); if (lResult != ERROR_SUCCESS) { goto out; } } else { lResult = RegDeleteValue(hKey, g_szVerifierFlagsValueName); if (lResult != ERROR_SUCCESS) { goto out; } }
bRet = TRUE;
out: return bRet; }
DWORD GetAppVerifierFlagsFromKey( HKEY hKey ) { DWORD dwRet = 0; DWORD dwValueType = 0; DWORD dwDataSize = 0; TCHAR szOldGlobalFlagValue[32]; BOOL bSuccesfullyConverted; LONG lResult; DWORD dwFlags = 0;
//
// Read the GlobalFlag value
//
dwDataSize = sizeof(szOldGlobalFlagValue);
lResult = RegQueryValueEx(hKey, g_szGlobalFlagValueName, NULL, &dwValueType, (LPBYTE)&szOldGlobalFlagValue[0], &dwDataSize);
if (ERROR_SUCCESS == lResult) { bSuccesfullyConverted = AVRtlCharToInteger(szOldGlobalFlagValue, 0, &dwFlags);
if ((FALSE != bSuccesfullyConverted) && ((dwFlags & FLG_APPLICATION_VERIFIER) != 0)) { //
// App verifier is enabled for this app - read the verifier flags
//
dwDataSize = sizeof(dwRet);
lResult = RegQueryValueEx(hKey, g_szVerifierFlagsValueName, NULL, &dwValueType, (LPBYTE)&dwRet, &dwDataSize);
if (ERROR_SUCCESS != lResult || REG_DWORD != dwValueType) { //
// couldn't get them, for one reason or another
//
dwRet = 0; } } }
return dwRet; }
void SetAppVerifierFullPathForKey( HKEY hKey, wstring& strPath ) { if (strPath.size() == 0) { RegDeleteValue(hKey, g_szVerifierPathValueName); } else { RegSetValueEx(hKey, g_szVerifierPathValueName, 0, REG_SZ, (PBYTE) strPath.c_str(), strPath.size() * sizeof(WCHAR)); } }
void SetDebuggerOptionsForKey( HKEY hKey, BOOL bUseAVDebugger ) { WCHAR szName[MAX_PATH]; szName[0] = 0;
GetModuleFileName(NULL, szName, MAX_PATH);
wcscat(szName, L" /debug"); if (bUseAVDebugger) { RegSetValueEx(hKey, g_szDebugger, 0, REG_SZ, (PBYTE)szName, wcslen(szName) * sizeof(WCHAR)); } else { WCHAR szDbgName[MAX_PATH]; DWORD cbSize; cbSize = MAX_PATH * sizeof(WCHAR);
szDbgName[0] = 0;
RegQueryValueEx(hKey, g_szDebugger, 0, NULL, (PBYTE)szDbgName, &cbSize);
if (_wcsicmp(szName, szDbgName) == 0) { RegDeleteValue(hKey, g_szDebugger); } } }
void GetAppVerifierFullPathFromKey( HKEY hKey, wstring& strPath ) { DWORD dwValueType = 0; DWORD dwDataSize = 0; TCHAR szVerifierPath[MAX_PATH]; LONG lResult;
//
// Read the GlobalFlag value
//
dwDataSize = sizeof(szVerifierPath);
szVerifierPath[0] = 0;
lResult = RegQueryValueEx(hKey, g_szVerifierPathValueName, NULL, &dwValueType, (LPBYTE)szVerifierPath, &dwDataSize);
if (ERROR_SUCCESS == lResult && dwValueType == REG_SZ) { strPath = szVerifierPath; } }
void GetCurrentAppSettingsFromRegistry( void ) { HKEY hImageOptionsKey; HKEY hSubKey; DWORD dwSubkeyIndex; DWORD dwDataSize; DWORD dwValueType; DWORD dwFlags; LONG lResult; FILETIME LastWriteTime; TCHAR szOldGlobalFlagValue[32]; TCHAR szKeyNameBuffer[256];
//
// Open the Image File Execution Options regkey
//
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szImageOptionsKeyName, 0, KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, &hImageOptionsKey);
if (lResult != ERROR_SUCCESS) { if (lResult == ERROR_ACCESS_DENIED) { AVErrorResourceFormat(IDS_ACCESS_IS_DENIED); } else { AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED, g_szImageOptionsKeyName, (DWORD)lResult); }
return; }
//
// Enumerate all the existing subkeys for app execution options
//
for (dwSubkeyIndex = 0; TRUE; dwSubkeyIndex += 1) { wstring wstrPath;
dwDataSize = ARRAY_LENGTH(szKeyNameBuffer);
lResult = RegEnumKeyEx(hImageOptionsKey, dwSubkeyIndex, szKeyNameBuffer, &dwDataSize, NULL, NULL, NULL, &LastWriteTime);
if (lResult != ERROR_SUCCESS) { if (lResult == ERROR_NO_MORE_ITEMS) { //
// We finished looking at all the existing subkeys
//
break; } else { if (lResult == ERROR_ACCESS_DENIED) { AVErrorResourceFormat(IDS_ACCESS_IS_DENIED); } else { AVErrorResourceFormat(IDS_REGENUMKEYEX_FAILED, g_szImageOptionsKeyName, (DWORD)lResult); }
goto CleanUpAndDone; } }
//
// Open the subkey
//
lResult = RegOpenKeyEx(hImageOptionsKey, szKeyNameBuffer, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hSubKey);
if (lResult != ERROR_SUCCESS) { if (lResult == ERROR_ACCESS_DENIED) { AVErrorResourceFormat(IDS_ACCESS_IS_DENIED); } else { AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED, szKeyNameBuffer, (DWORD)lResult); }
goto CleanUpAndDone; }
dwFlags = GetAppVerifierFlagsFromKey(hSubKey); GetAppVerifierFullPathFromKey(hSubKey, wstrPath); if (dwFlags || wstrPath.size()) { //
// Update the info in the array, or add it if necessary
//
CAVAppInfo* pApp; BOOL bFound = FALSE;
for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) { if (_wcsicmp(pApp->wstrExeName.c_str(), szKeyNameBuffer) == 0) { bFound = TRUE; pApp->dwRegFlags = dwFlags; pApp->wstrExePath = wstrPath; break; } }
if (!bFound) { CAVAppInfo AppInfo; AppInfo.wstrExeName = szKeyNameBuffer; AppInfo.dwRegFlags = dwFlags; AppInfo.wstrExePath = wstrPath;
g_aAppInfo.push_back(AppInfo); } }
VERIFY(ERROR_SUCCESS == RegCloseKey(hSubKey)); }
CleanUpAndDone:
VERIFY(ERROR_SUCCESS == RegCloseKey(hImageOptionsKey)); }
void GetCurrentAppSettingsFromSDB( void ) { CAVAppInfo AppInfo; TCHAR szPath[MAX_PATH]; PDB pdb = NULL; TAGID tiDB = TAGID_NULL; TAGID tiExe = TAGID_NULL;
//
// go find the SDB
//
szPath[0] = 0; GetSystemWindowsDirectory(szPath, MAX_PATH); _tcscat(szPath, _T("\\AppPatch\\Custom\\{448850f4-a5ea-4dd1-bf1b-d5fa285dc64b}.sdb"));
pdb = SdbOpenDatabase(szPath, DOS_PATH); if (!pdb) { //
// no current DB
//
goto out; }
//
// enumerate all the apps and the shims applied to them
//
tiDB = SdbFindFirstTag(pdb, TAGID_ROOT, TAG_DATABASE); if (!tiDB) { goto out; }
tiExe = SdbFindFirstTag(pdb, tiDB, TAG_EXE); while (tiExe) { WCHAR* wszName = NULL; TAGID tiShim = TAGID_NULL; TAGID tiName = SdbFindFirstTag(pdb, tiExe, TAG_NAME);
if (!tiName) { goto nextExe; } wszName = SdbGetStringTagPtr(pdb, tiName);
CAVAppInfoArray::iterator it; BOOL bFound = FALSE;
for (it = g_aAppInfo.begin(); it != g_aAppInfo.end(); it++) { if (_wcsicmp(it->wstrExeName.c_str(), wszName) == 0) { bFound = TRUE; break; } }
if (!bFound) { AppInfo.wstrExeName = wszName; g_aAppInfo.push_back(AppInfo); it = g_aAppInfo.end() - 1; }
tiShim = SdbFindFirstTag(pdb, tiExe, TAG_SHIM_REF); while (tiShim) { WCHAR* wszShimName = NULL; TAGID tiShimName = SdbFindFirstTag(pdb, tiShim, TAG_NAME); if (!tiShimName) { goto nextShim; } wszShimName = SdbGetStringTagPtr(pdb, tiShimName);
it->awstrShims.push_back(wstring(wszShimName));
nextShim: tiShim = SdbFindNextTag(pdb, tiExe, tiShim); }
nextExe:
tiExe = SdbFindNextTag(pdb, tiDB, tiExe); }
out:
if (pdb) { SdbCloseDatabase(pdb); pdb = NULL; }
return; }
void GetCurrentAppSettings( void ) { g_aAppInfo.clear();
GetCurrentAppSettingsFromRegistry(); GetCurrentAppSettingsFromSDB(); }
void SetCurrentRegistrySettings( void ) { HKEY hImageOptionsKey; HKEY hSubKey = NULL; DWORD dwSubkeyIndex; DWORD dwDataSize; DWORD dwValueType; DWORD dwFlags; LONG lResult; FILETIME LastWriteTime; TCHAR szKeyNameBuffer[ 256 ]; CAVAppInfo* pApp; wstring wstrEmpty = L"";
//
// Open the Image File Execution Options regkey
//
lResult = RegOpenKeyEx(HKEY_LOCAL_MACHINE, g_szImageOptionsKeyName, 0, KEY_CREATE_SUB_KEY | KEY_ENUMERATE_SUB_KEYS, &hImageOptionsKey);
if (lResult != ERROR_SUCCESS) { if (lResult == ERROR_ACCESS_DENIED) { AVErrorResourceFormat(IDS_ACCESS_IS_DENIED); } else { AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED, g_szImageOptionsKeyName, (DWORD)lResult); }
return; }
//
// Enumerate all the existing subkeys for app execution options
//
for (dwSubkeyIndex = 0; TRUE; dwSubkeyIndex += 1) { dwDataSize = ARRAY_LENGTH(szKeyNameBuffer);
lResult = RegEnumKeyEx(hImageOptionsKey, dwSubkeyIndex, szKeyNameBuffer, &dwDataSize, NULL, NULL, NULL, &LastWriteTime);
if (lResult != ERROR_SUCCESS) { if (lResult == ERROR_NO_MORE_ITEMS) { //
// We finished looking at all the existing subkeys
//
break; } else { if (lResult == ERROR_ACCESS_DENIED) { AVErrorResourceFormat(IDS_ACCESS_IS_DENIED); } else { AVErrorResourceFormat(IDS_REGENUMKEYEX_FAILED, g_szImageOptionsKeyName, (DWORD)lResult); }
goto CleanUpAndDone; } }
//
// Open the subkey
//
lResult = RegOpenKeyEx(hImageOptionsKey, szKeyNameBuffer, 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hSubKey);
if (lResult != ERROR_SUCCESS) { if (lResult == ERROR_ACCESS_DENIED) { AVErrorResourceFormat(IDS_ACCESS_IS_DENIED); } else { AVErrorResourceFormat(IDS_REGOPENKEYEX_FAILED, szKeyNameBuffer, (DWORD)lResult); }
goto CleanUpAndDone; }
dwFlags = GetAppVerifierFlagsFromKey(hSubKey); DWORD dwDesiredFlags = 0; BOOL bFound = FALSE;
for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) { if (_wcsicmp(pApp->wstrExeName.c_str(), szKeyNameBuffer) == 0) { dwDesiredFlags = pApp->dwRegFlags; bFound = TRUE;
//
// we found it, so update the full path
//
SetAppVerifierFullPathForKey(hSubKey, pApp->wstrExePath);
//
// and add the debugger as well
//
SetDebuggerOptionsForKey(hSubKey, g_bUseAVDebugger);
break; } }
if (!bFound) { //
// if this one isn't in our list, make sure it doesn't
// have a full path or our debugger set
//
SetAppVerifierFullPathForKey(hSubKey, wstrEmpty); SetDebuggerOptionsForKey(hSubKey, FALSE); }
if (dwFlags != dwDesiredFlags) { SetAppVerifierFlagsForKey(hSubKey, dwDesiredFlags); }
VERIFY(ERROR_SUCCESS == RegCloseKey(hSubKey)); hSubKey = NULL; }
//
// and now go through the list the other way, looking for new ones to add
//
for (pApp = g_aAppInfo.begin(); pApp != g_aAppInfo.end(); pApp++) { lResult = RegOpenKeyEx(hImageOptionsKey, pApp->wstrExeName.c_str(), 0, KEY_QUERY_VALUE | KEY_SET_VALUE, &hSubKey);
//
// if it exists, we've already dealt with it above
//
if (lResult != ERROR_SUCCESS) { //
// it doesn't exist. Try to create it.
//
lResult = RegCreateKeyEx(hImageOptionsKey, pApp->wstrExeName.c_str(), 0, NULL, REG_OPTION_NON_VOLATILE, KEY_QUERY_VALUE | KEY_SET_VALUE, NULL, &hSubKey, NULL);
if (lResult == ERROR_SUCCESS) { SetAppVerifierFlagsForKey(hSubKey, pApp->dwRegFlags); SetAppVerifierFullPathForKey(hSubKey, pApp->wstrExePath); SetDebuggerOptionsForKey(hSubKey, g_bUseAVDebugger); } } if (hSubKey) { RegCloseKey(hSubKey); hSubKey = NULL; } }
CleanUpAndDone:
VERIFY(ERROR_SUCCESS == RegCloseKey(hImageOptionsKey)); }
void SetCurrentAppSettings( void ) { SetCurrentRegistrySettings(); AppCompatWriteShimSettings(g_aAppInfo); }
KERNEL_TEST_INFO g_KernelTests[] = { { IDS_PAGE_HEAP, IDS_PAGE_HEAP_DESC, RTL_VRF_FLG_FULL_PAGE_HEAP, TRUE, L"PageHeap" }, { IDS_VERIFY_LOCKS_CHECKS, IDS_VERIFY_LOCKS_CHECKS_DESC, RTL_VRF_FLG_LOCK_CHECKS, TRUE, L"Locks" }, { IDS_VERIFY_HANDLE_CHECKS, IDS_VERIFY_HANDLE_CHECKS_DESC, RTL_VRF_FLG_HANDLE_CHECKS, TRUE, L"Handles" }, { IDS_VERIFY_STACK_CHECKS, IDS_VERIFY_STACK_CHECKS_DESC, RTL_VRF_FLG_STACK_CHECKS, FALSE, L"Stacks" } };
BOOL GetKernelTestInfo( CTestInfoArray& TestArray ) { CTestInfo ti; TCHAR szTemp[256]; int i;
ti.eTestType = TEST_KERNEL;
for (int i = 0; i < ARRAY_LENGTH(g_KernelTests); ++i) { if (!AVLoadString(g_KernelTests[i].m_uNameStringId, szTemp, ARRAY_LENGTH(szTemp))) { continue; } ti.strTestName = szTemp;
if (AVLoadString(g_KernelTests[i].m_uDescriptionStringId, szTemp, ARRAY_LENGTH(szTemp))) { ti.strTestDescription = szTemp; } else { ti.strTestDescription = L""; }
ti.dwKernelFlag = g_KernelTests[i].m_dwBit; ti.bDefault = g_KernelTests[i].m_bDefault; ti.strTestCommandLine = g_KernelTests[i].m_szCommandLine;
TestArray.push_back(ti); }
return TRUE; }
void ParseIncludeList( WCHAR* szList, CWStringArray& astrArray ) { if (!szList) { return; }
WCHAR *szComma = NULL; WCHAR *szBegin = szList; WCHAR szTemp[128]; int nLen = wcslen(szList); WCHAR *szEnd = szList + nLen;
do { szComma = wcschr(szBegin, L','); if (!szComma) { szComma = szEnd; } while (*szComma && iswspace(*szComma)) { szComma++; }
nLen = (int)(szComma - szBegin);
if (nLen > 0) { memcpy(szTemp, szBegin, nLen * sizeof(WCHAR)); szTemp[nLen] = 0;
astrArray.push_back(szTemp); }
if (!*szComma) { break; } szBegin = szComma + 1;
} while (TRUE);
}
BOOL GetShimInfo( CTestInfoArray& TestInfoArray ) { HKEY hKey = NULL; BOOL bRet = FALSE; int nWhich = 0; TCHAR szAppPatch[MAX_PATH]; TCHAR szShimFullPath[MAX_PATH]; HMODULE hMod; _pfnEnumShims pEnumShims = NULL; _pfnIsVerifierDLL pIsVerifer = NULL; PSHIM_DESCRIPTION pShims = NULL; DWORD dwShims = 0;
WIN32_FIND_DATA FindData; HANDLE hFind = INVALID_HANDLE_VALUE; TCHAR szDllSearch[MAX_PATH];
GetSystemWindowsDirectory(szAppPatch, MAX_PATH); _tcscat(szAppPatch, _T("\\AppPatch\\")); _tcscpy(szDllSearch, szAppPatch); _tcscat(szDllSearch, _T("*.dll"));
//
// enumerate all the DLLs and look for ones that have Verification
// shims in them
//
hFind = FindFirstFile(szDllSearch, &FindData); while (hFind != INVALID_HANDLE_VALUE) {
_tcscpy(szShimFullPath, szAppPatch); _tcscat(szShimFullPath, FindData.cFileName);
hMod = LoadLibrary(szShimFullPath); if (!hMod) { goto nextKey; }
pIsVerifer = (_pfnIsVerifierDLL)GetProcAddress(hMod, "IsVerifierDLL"); if (!pIsVerifer) { //
// not a real verifier shim
//
goto nextKey; }
if (!pIsVerifer()) { //
// not a real verifier shim
//
goto nextKey; }
pEnumShims = (_pfnEnumShims)GetProcAddress(hMod, "EnumShims"); if (!pEnumShims) { //
// not a real verifier shim
//
goto nextKey; }
dwShims = pEnumShims(NULL, ENUM_SHIMS_MAGIC); if (!dwShims) { goto nextKey; }
pShims = new SHIM_DESCRIPTION[dwShims]; if (!pShims) { goto out; }
pEnumShims(pShims, ENUM_SHIMS_MAGIC);
for (DWORD i = 0; i < dwShims; ++i) { CTestInfo ti;
ti.eTestType = TEST_SHIM; ti.strDllName = FindData.cFileName; ti.strTestName = pShims[i].szName; ti.strTestCommandLine = pShims[i].szName; ti.strTestDescription = pShims[i].szDescription; ti.bDefault = TRUE;
ParseIncludeList(pShims[i].szIncludes, ti.astrIncludes); ParseIncludeList(pShims[i].szExcludes, ti.astrExcludes);
//
// add it to the end
//
TestInfoArray.push_back(ti); }
delete [] pShims; pShims = NULL;
nextKey: if (hMod) { FreeLibrary(hMod); hMod = NULL; } if (!FindNextFile(hFind, &FindData)) { FindClose(hFind); hFind = INVALID_HANDLE_VALUE; } }
bRet = TRUE;
out:
if (hMod) { FreeLibrary(hMod); hMod = NULL; } if (hFind != INVALID_HANDLE_VALUE) { FindClose(hFind); hFind = INVALID_HANDLE_VALUE; } return bRet; }
BOOL InitTestInfo( void ) { g_aTestInfo.clear();
if (!GetKernelTestInfo(g_aTestInfo)) { return FALSE; } if (!GetShimInfo(g_aTestInfo)) { return FALSE; }
return TRUE; }
void ResetVerifierLog( void ) { WIN32_FIND_DATA FindData; HANDLE hFind = INVALID_HANDLE_VALUE; BOOL bFound; TCHAR szVLogPath[MAX_PATH]; TCHAR szVLogSearch[MAX_PATH]; TCHAR szPath[MAX_PATH]; HANDLE hFile;
GetSystemWindowsDirectory(szVLogPath, MAX_PATH); _tcscat(szVLogPath, _T("\\AppPatch\\VLog\\")); _tcscpy(szVLogSearch, szVLogPath); _tcscat(szVLogSearch, _T("*.log"));
//
// kill all the .log files
//
hFind = FindFirstFile(szVLogSearch, &FindData); while (hFind != INVALID_HANDLE_VALUE) {
_tcscpy(szPath, szVLogPath); _tcscat(szPath, FindData.cFileName);
DeleteFile(szPath);
if (!FindNextFile(hFind, &FindData)) { FindClose(hFind); hFind = INVALID_HANDLE_VALUE; } }
//
// recreate session.log
//
CreateDirectory(szVLogPath, NULL);
_tcscpy(szPath, szVLogPath); _tcscat(szPath, _T("session.log"));
hFile = CreateFile(szPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); }
return; }
void EnableVerifierLog(void) { HANDLE hFile; TCHAR szPath[MAX_PATH]; TCHAR szVLogPath[MAX_PATH];
GetSystemWindowsDirectory(szVLogPath, MAX_PATH); _tcscat(szVLogPath, _T("\\AppPatch\\VLog\\")); //
// make sure VLog dir and session.log exists
//
CreateDirectory(szVLogPath, NULL);
_tcscpy(szPath, szVLogPath); _tcscat(szPath, _T("session.log"));
hFile = CreateFile(szPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); } }
CTestInfo* FindShim( wstring& wstrName ) { CTestInfoArray::iterator it;
for (it = g_aTestInfo.begin(); it != g_aTestInfo.end(); it++) { if (it->strTestName == wstrName) { return &(*it); } }
return NULL; }
extern "C" BOOL ShimdbcExecute( LPCWSTR lpszCmdLine );
TCHAR g_szBuff[2048] = _T("");
BOOL AppCompatWriteShimSettings( CAVAppInfoArray& arrAppInfo ) { TCHAR szTempPath[MAX_PATH] = _T(""); TCHAR szXmlFile[MAX_PATH] = _T(""); TCHAR szSdbFile[MAX_PATH] = _T(""); HANDLE hFile = INVALID_HANDLE_VALUE; DWORD bytesWritten; STARTUPINFO si; PROCESS_INFORMATION pi; BOOL bReturn = FALSE; TCHAR szUnicodeHdr[2] = { 0xFEFF, 0};
if (0 == arrAppInfo.size()) { return AppCompatDeleteSettings(); }
//
// Construct the XML...
//
wsprintf(g_szXML, _T("%s<?xml version=\"1.0\"?>\r\n") _T("<DATABASE NAME=\"Application Verifier Database\" ID=\"{448850f4-a5ea-4dd1-bf1b-d5fa285dc64b}\">\r\n") _T(" <LIBRARY>\r\n"), szUnicodeHdr);
CTestInfoArray::iterator it;
for (it = g_aTestInfo.begin(); it != g_aTestInfo.end(); it++) { if (it->eTestType != TEST_SHIM) { continue; } wsprintf(g_szBuff, _T(" <SHIM NAME=\"%s\" FILE=\"%s\">\r\n") _T(" <DESCRIPTION>\r\n") _T(" %s\r\n") _T(" </DESCRIPTION>\r\n"), it->strTestName.c_str(), it->strDllName.c_str(), it->strTestDescription.c_str());
lstrcat(g_szXML, g_szBuff);
CWStringArray::iterator wsit;
for (wsit = it->astrIncludes.begin(); wsit != it->astrIncludes.end(); ++wsit) { wsprintf(g_szBuff, _T(" <INCLUDE MODULE=\"%s\"/>\r\n"), wsit->c_str());
lstrcat(g_szXML, g_szBuff); } for (wsit = it->astrExcludes.begin(); wsit != it->astrExcludes.end(); ++wsit) { wsprintf(g_szBuff, _T(" <EXCLUDE MODULE=\"%s\"/>\r\n"), wsit->c_str());
lstrcat(g_szXML, g_szBuff); }
lstrcat(g_szXML, _T(" </SHIM>\r\n"));
}
lstrcat(g_szXML, _T(" </LIBRARY>\r\n\r\n")); lstrcat(g_szXML, _T(" <APP NAME=\"All EXEs to be verified\" VENDOR=\"Various\">\r\n"));
CAVAppInfo* aiit;
for (aiit = arrAppInfo.begin(); aiit != arrAppInfo.end(); aiit++) {
//
// if there're no shims, we're done
//
if (aiit->awstrShims.size() == 0) { continue; }
wsprintf(g_szBuff, _T(" <EXE NAME=\"%s\">\r\n"), aiit->wstrExeName.c_str()); lstrcat(g_szXML, g_szBuff);
CWStringArray::iterator wsit;
for (wsit = aiit->awstrShims.begin(); wsit != aiit->awstrShims.end(); wsit++) {
CTestInfo* pTestInfo = FindShim(*wsit);
if (pTestInfo) { wsprintf(g_szBuff, _T(" <SHIM NAME=\"%s\"/>\r\n"), pTestInfo->strTestName.c_str());
lstrcat(g_szXML, g_szBuff); } }
lstrcat(g_szXML, _T(" </EXE>\r\n")); }
lstrcat(g_szXML, _T(" </APP>\r\n") _T("</DATABASE>"));
if (GetTempPath(MAX_PATH, szTempPath) == 0) { DPF("[AppCompatSaveSettings] GetTempPath failed."); goto cleanup; }
//
// Obtain a temp name for the XML file
//
if (GetTempFileName(szTempPath, _T("XML"), NULL, szXmlFile) == 0) { DPF("[AppCompatSaveSettings] GetTempFilePath for XML failed."); goto cleanup; }
hFile = CreateFile(szXmlFile, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (hFile == INVALID_HANDLE_VALUE) { DPF("[AppCompatSaveSettings] CreateFile '%s' failed 0x%X.", szXmlFile, GetLastError()); goto cleanup; }
if (WriteFile(hFile, g_szXML, lstrlen(g_szXML) * sizeof(TCHAR), &bytesWritten, NULL) == 0) { DPF("[AppCompatSaveSettings] WriteFile \"%s\" failed 0x%X.", szXmlFile, GetLastError()); goto cleanup; }
CloseHandle(hFile); hFile = INVALID_HANDLE_VALUE;
//
// Obtain a temp name for the SDB file
//
wsprintf(szSdbFile, _T("%stempdb.sdb"), szTempPath);
DeleteFile(szSdbFile);
//
// Invoke the compiler to generate the SDB file
//
ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si);
wsprintf(g_szCmd, _T("shimdbc.exe fix -q \"%s\" \"%s\""), szXmlFile, szSdbFile);
if (!ShimdbcExecute(g_szCmd)) { DPF("[AppCompatSaveSettings] CreateProcess \"%s\" failed 0x%X.", g_szCmd, GetLastError()); goto cleanup; }
//
// The SDB file is generated. Install the database now.
//
ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si);
wsprintf(g_szCmd, _T("sdbinst.exe -q \"%s\""), szSdbFile);
if (!CreateProcess(NULL, g_szCmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
DPF("[AppCompatSaveSettings] CreateProcess \"%s\" failed 0x%X.", g_szCmd, GetLastError()); goto cleanup; }
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
//
// ensure we've got a fresh log session started
//
EnableVerifierLog();
if (g_bClearSessionLogBeforeRun) { ResetVerifierLog(); }
bReturn = TRUE;
cleanup:
if (hFile != INVALID_HANDLE_VALUE) { CloseHandle(hFile); }
DeleteFile(szXmlFile); DeleteFile(szSdbFile);
return bReturn; }
BOOL AppCompatDeleteSettings( void ) { STARTUPINFO si; PROCESS_INFORMATION pi; TCHAR szCmd[MAX_PATH];
ZeroMemory(&si, sizeof(si)); si.cb = sizeof(si);
lstrcpy(szCmd, _T("sdbinst.exe -q -u -g {448850f4-a5ea-4dd1-bf1b-d5fa285dc64b}"));
if (!CreateProcess(NULL, szCmd, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS | CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) {
DPF("[AppCompatDeleteSettings] CreateProcess \"%s\" failed 0x%X.", szCmd, GetLastError()); return FALSE; }
CloseHandle(pi.hThread);
WaitForSingleObject(pi.hProcess, INFINITE);
CloseHandle(pi.hProcess);
return TRUE; }
|