|
|
#include "acBrowser.h"
#include "..\acFileAttr\acFileAttr.h"
typedef struct tagKEYHEADER{ DWORD Size; DWORD MsgId; DWORD AppType; } KEYHEADER, *PKEYHEADER;
char g_szData[2048];
VOID PrintHeader( KEYHEADER* pheader, char* pszAppName, char* pszShimData) { char* pszOut = g_szData;
lstrcpy(pszOut, "Application state: "); switch (pheader->AppType & APPTYPE_TYPE_MASK) { case APPTYPE_INC_NOBLOCK: lstrcat(pszOut, "Incompatible - no hard block\r\n"); break; case APPTYPE_INC_HARDBLOCK: lstrcat(pszOut, "Incompatible - hard block\r\n"); break; case APPTYPE_MINORPROBLEM: lstrcat(pszOut, "Minor problems\r\n"); break; case APPTYPE_REINSTALL: lstrcat(pszOut, "Reinstall\r\n"); break; case APPTYPE_VERSION: lstrcat(pszOut, "Version substitute\r\n"); break; case APPTYPE_SHIM: lstrcat(pszOut, "Shim\r\n"); break; default: lstrcat(pszOut, "AppsHelp\r\n"); break; } pszOut = g_szData + lstrlen(g_szData); if (pszShimData == NULL) { wsprintf(pszOut, "Message ID: %d\r\n\r\n", pheader->MsgId); } else { wsprintf(pszOut, "Shim fix: %s\r\n\r\n", pszShimData); }
pszOut = g_szData + lstrlen(g_szData); wsprintf(pszOut, "Attributes for %s:\r\n", pszAppName); }
#define MAX_EXE_NAME 64
#define MAX_VALUE_LENGTH 64 // in most cases this is a number but
// it can be a string as well
#define MAX_BLOB_SIZE 2048
BYTE g_data[MAX_BLOB_SIZE];
BOOL EnumShimmedApps_Win2000( PFNADDSHIM pfnAddShim, BOOL bOnlyShims) { LONG status; HKEY hkey, hkeyApp; DWORD cbSize; DWORD cbData; DWORD cbShimData; FILETIME ft; DWORD dwType; char szAppName[MAX_EXE_NAME]; char szValueName[MAX_VALUE_LENGTH]; char szShimValueName[128]; char szShimData[256]; BOOL bEnabled; DWORD dwValue; KEYHEADER header; status = RegOpenKey(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Control\\Session Manager\\AppCompatibility", &hkey);
if (status != ERROR_SUCCESS) { LogMsg("Failed to open AppCompatibility registry key\n"); return FALSE; } // loop through all the binaries listed under the AppCompatibility key
for (dwValue = 0; ; dwValue++) { DWORD dwV;
// we'll only read binary names that are less then MAX_EXE_NAME
// in size.
cbSize = MAX_EXE_NAME; status = RegEnumKeyEx( hkey, dwValue, szAppName, &cbSize, NULL, NULL, NULL, &ft);
// get out if no more entries
if (status != ERROR_SUCCESS) { break; } // get the handle to the registry key for this app
status = RegOpenKey(hkey, szAppName, &hkeyApp); // this should not fail but let's be cautious
if (status != ERROR_SUCCESS) { LogMsg("Failed to open reg key for '%s'\n", szAppName); continue; }
// loop through all the shims and AppsHelp entries for the
// current app.
for (dwV = 0; ; dwV++) { char* pszData; cbSize = MAX_VALUE_LENGTH; cbData = MAX_BLOB_SIZE; cbShimData = 256;
status = RegEnumValue( hkeyApp, dwV, szValueName, &cbSize, NULL, &dwType, (LPBYTE)&g_data, &cbData); if (status != ERROR_SUCCESS) { break; }
// we're only interested in the binary values
if (dwType != REG_BINARY) { continue; }
CopyMemory(&header, g_data, sizeof(KEYHEADER));
// it must me a valid blob
if (header.Size != sizeof(KEYHEADER)) { LogMsg("Invalid blob\n"); continue; } bEnabled = TRUE;
// now let's look for an enabled shim entry
wsprintf(szShimValueName, "DllPatch-%s", szValueName);
status = RegQueryValueEx( hkeyApp, szShimValueName, NULL, &dwType, (LPBYTE)szShimData, &cbShimData); if (status != ERROR_SUCCESS) { // how about a disabled shim entry
wsprintf(szShimValueName, "-DllPatch-%s", szValueName);
status = RegQueryValueEx( hkeyApp, szShimValueName, NULL, &dwType, (LPBYTE)szShimData, &cbShimData); if (status != ERROR_SUCCESS) { // this is not a shim. If only shim entries are
// requested go to the next entry.
if (bOnlyShims) { continue; } // This is an AppsHelp entry.
PrintHeader(&header, szAppName, NULL); pszData = g_szData + lstrlen(g_szData); if (BlobToString(g_data + sizeof(KEYHEADER), cbData - sizeof(KEYHEADER) - sizeof(DWORD), pszData)) { (*pfnAddShim)(szAppName, szValueName, g_szData, TRUE, FALSE); } else { LogMsg("Failed to dump blob for AppsHelp entry: app '%s' entry '%s'\n", szAppName, szValueName); } continue; } bEnabled = FALSE; } // This is a shim.
PrintHeader(&header, szAppName, szShimData); pszData = g_szData + lstrlen(g_szData); if (BlobToString(g_data + sizeof(KEYHEADER), cbData - sizeof(KEYHEADER) - sizeof(DWORD), pszData)) { (*pfnAddShim)(szAppName, szValueName, g_szData, bEnabled, TRUE); } else { LogMsg("Failed to dump blob for shim entry: app '%s' entry '%s'\n", szAppName, szValueName); } } RegCloseKey(hkeyApp); }
RegCloseKey(hkey);
return TRUE; }
BOOL EnableShim_Win2000( char* pszApp, char* pszShim) { LONG status; HKEY hkey; char szAppKey[128]; char szShimValueName[128]; char szData[256]; DWORD cbSize, dwType; BOOL bRet = FALSE; wsprintf(szAppKey, "%s\\%s", "System\\CurrentControlSet\\Control\\Session Manager\\AppCompatibility", pszApp); status = RegOpenKey(HKEY_LOCAL_MACHINE, szAppKey, &hkey);
if (status != ERROR_SUCCESS) { LogMsg("Failed to open registry key %s\n", szAppKey); return FALSE; } wsprintf(szShimValueName, "-DllPatch-%s", pszShim); cbSize = 256; status = RegQueryValueEx(hkey, szShimValueName, NULL, &dwType, (LPBYTE)szData, &cbSize); if (status != ERROR_SUCCESS || dwType != REG_SZ || cbSize >= 256) { LogMsg("Error reading key %s\n", szShimValueName); goto Cleanup; } status = RegDeleteValue(hkey, szShimValueName); if (status != ERROR_SUCCESS) { LogMsg("Couldn't delete key %s\n", szShimValueName); goto Cleanup; } wsprintf(szShimValueName, "DllPatch-%s", pszShim);
status = RegSetValueEx(hkey, szShimValueName, 0, REG_SZ, (LPBYTE)szData, cbSize); if (status != ERROR_SUCCESS) { LogMsg("Couldn't set value key %s\n", szShimValueName); goto Cleanup; } bRet = TRUE;
Cleanup: RegCloseKey(hkey); return bRet; }
BOOL DisableShim_Win2000( char* pszApp, char* pszShim) { LONG status; HKEY hkey; char szAppKey[128]; char szShimValueName[128]; char szData[256]; DWORD cbSize, dwType; BOOL bRet = FALSE; wsprintf(szAppKey, "%s\\%s", "System\\CurrentControlSet\\Control\\Session Manager\\AppCompatibility", pszApp); status = RegOpenKey(HKEY_LOCAL_MACHINE, szAppKey, &hkey);
if (status != ERROR_SUCCESS) { LogMsg("Failed to open registry key %s\n", szAppKey); return FALSE; } wsprintf(szShimValueName, "DllPatch-%s", pszShim); cbSize = 256; status = RegQueryValueEx(hkey, szShimValueName, NULL, &dwType, (LPBYTE)szData, &cbSize); if (status != ERROR_SUCCESS || dwType != REG_SZ || cbSize >= 256) { LogMsg("Error reading key %s\n", szShimValueName); goto Cleanup; } status = RegDeleteValue(hkey, szShimValueName); if (status != ERROR_SUCCESS) { LogMsg("Couldn't delete key %s\n", szShimValueName); goto Cleanup; } wsprintf(szShimValueName, "-DllPatch-%s", pszShim);
status = RegSetValueEx(hkey, szShimValueName, 0, REG_SZ, (LPBYTE)szData, cbSize); if (status != ERROR_SUCCESS) { LogMsg("Couldn't set value key %s\n", szShimValueName); goto Cleanup; } bRet = TRUE;
Cleanup: RegCloseKey(hkey); return bRet; }
BOOL DeleteShim_Win2000( char* pszApp, char* pszShim) { LONG status; HKEY hkey; char szAppKey[128]; char szShimValueName[128]; wsprintf(szAppKey, "%s\\%s", "System\\CurrentControlSet\\Control\\Session Manager\\AppCompatibility", pszApp); status = RegOpenKey(HKEY_LOCAL_MACHINE, szAppKey, &hkey);
if (status != ERROR_SUCCESS) { LogMsg("Failed to open registry key %s\n", szAppKey); return FALSE; } wsprintf(szShimValueName, "DllPatch-%s", pszShim); status = RegDeleteValue(hkey, szShimValueName); wsprintf(szShimValueName, "-DllPatch-%s", pszShim); status = RegDeleteValue(hkey, szShimValueName); RegCloseKey(hkey); return TRUE; }
|