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.

412 lines
11 KiB

  1. #include "acBrowser.h"
  2. #include "..\acFileAttr\acFileAttr.h"
  3. typedef struct tagKEYHEADER{
  4. DWORD Size;
  5. DWORD MsgId;
  6. DWORD AppType;
  7. } KEYHEADER, *PKEYHEADER;
  8. char g_szData[2048];
  9. VOID
  10. PrintHeader(
  11. KEYHEADER* pheader,
  12. char* pszAppName,
  13. char* pszShimData)
  14. {
  15. char* pszOut = g_szData;
  16. lstrcpy(pszOut, "Application state: ");
  17. switch (pheader->AppType & APPTYPE_TYPE_MASK) {
  18. case APPTYPE_INC_NOBLOCK:
  19. lstrcat(pszOut, "Incompatible - no hard block\r\n");
  20. break;
  21. case APPTYPE_INC_HARDBLOCK:
  22. lstrcat(pszOut, "Incompatible - hard block\r\n");
  23. break;
  24. case APPTYPE_MINORPROBLEM:
  25. lstrcat(pszOut, "Minor problems\r\n");
  26. break;
  27. case APPTYPE_REINSTALL:
  28. lstrcat(pszOut, "Reinstall\r\n");
  29. break;
  30. case APPTYPE_VERSION:
  31. lstrcat(pszOut, "Version substitute\r\n");
  32. break;
  33. case APPTYPE_SHIM:
  34. lstrcat(pszOut, "Shim\r\n");
  35. break;
  36. default:
  37. lstrcat(pszOut, "AppsHelp\r\n");
  38. break;
  39. }
  40. pszOut = g_szData + lstrlen(g_szData);
  41. if (pszShimData == NULL) {
  42. wsprintf(pszOut, "Message ID: %d\r\n\r\n", pheader->MsgId);
  43. } else {
  44. wsprintf(pszOut, "Shim fix: %s\r\n\r\n", pszShimData);
  45. }
  46. pszOut = g_szData + lstrlen(g_szData);
  47. wsprintf(pszOut, "Attributes for %s:\r\n", pszAppName);
  48. }
  49. #define MAX_EXE_NAME 64
  50. #define MAX_VALUE_LENGTH 64 // in most cases this is a number but
  51. // it can be a string as well
  52. #define MAX_BLOB_SIZE 2048
  53. BYTE g_data[MAX_BLOB_SIZE];
  54. BOOL
  55. EnumShimmedApps_Win2000(
  56. PFNADDSHIM pfnAddShim,
  57. BOOL bOnlyShims)
  58. {
  59. LONG status;
  60. HKEY hkey, hkeyApp;
  61. DWORD cbSize;
  62. DWORD cbData;
  63. DWORD cbShimData;
  64. FILETIME ft;
  65. DWORD dwType;
  66. char szAppName[MAX_EXE_NAME];
  67. char szValueName[MAX_VALUE_LENGTH];
  68. char szShimValueName[128];
  69. char szShimData[256];
  70. BOOL bEnabled;
  71. DWORD dwValue;
  72. KEYHEADER header;
  73. status = RegOpenKey(HKEY_LOCAL_MACHINE,
  74. "System\\CurrentControlSet\\Control\\Session Manager\\AppCompatibility",
  75. &hkey);
  76. if (status != ERROR_SUCCESS) {
  77. LogMsg("Failed to open AppCompatibility registry key\n");
  78. return FALSE;
  79. }
  80. // loop through all the binaries listed under the AppCompatibility key
  81. for (dwValue = 0; ; dwValue++) {
  82. DWORD dwV;
  83. // we'll only read binary names that are less then MAX_EXE_NAME
  84. // in size.
  85. cbSize = MAX_EXE_NAME;
  86. status = RegEnumKeyEx(
  87. hkey,
  88. dwValue,
  89. szAppName,
  90. &cbSize,
  91. NULL,
  92. NULL,
  93. NULL,
  94. &ft);
  95. // get out if no more entries
  96. if (status != ERROR_SUCCESS) {
  97. break;
  98. }
  99. // get the handle to the registry key for this app
  100. status = RegOpenKey(hkey,
  101. szAppName,
  102. &hkeyApp);
  103. // this should not fail but let's be cautious
  104. if (status != ERROR_SUCCESS) {
  105. LogMsg("Failed to open reg key for '%s'\n", szAppName);
  106. continue;
  107. }
  108. // loop through all the shims and AppsHelp entries for the
  109. // current app.
  110. for (dwV = 0; ; dwV++) {
  111. char* pszData;
  112. cbSize = MAX_VALUE_LENGTH;
  113. cbData = MAX_BLOB_SIZE;
  114. cbShimData = 256;
  115. status = RegEnumValue(
  116. hkeyApp,
  117. dwV,
  118. szValueName,
  119. &cbSize,
  120. NULL,
  121. &dwType,
  122. (LPBYTE)&g_data,
  123. &cbData);
  124. if (status != ERROR_SUCCESS) {
  125. break;
  126. }
  127. // we're only interested in the binary values
  128. if (dwType != REG_BINARY) {
  129. continue;
  130. }
  131. CopyMemory(&header, g_data, sizeof(KEYHEADER));
  132. // it must me a valid blob
  133. if (header.Size != sizeof(KEYHEADER)) {
  134. LogMsg("Invalid blob\n");
  135. continue;
  136. }
  137. bEnabled = TRUE;
  138. // now let's look for an enabled shim entry
  139. wsprintf(szShimValueName, "DllPatch-%s", szValueName);
  140. status = RegQueryValueEx(
  141. hkeyApp,
  142. szShimValueName,
  143. NULL,
  144. &dwType,
  145. (LPBYTE)szShimData,
  146. &cbShimData);
  147. if (status != ERROR_SUCCESS) {
  148. // how about a disabled shim entry
  149. wsprintf(szShimValueName, "-DllPatch-%s", szValueName);
  150. status = RegQueryValueEx(
  151. hkeyApp,
  152. szShimValueName,
  153. NULL,
  154. &dwType,
  155. (LPBYTE)szShimData,
  156. &cbShimData);
  157. if (status != ERROR_SUCCESS) {
  158. // this is not a shim. If only shim entries are
  159. // requested go to the next entry.
  160. if (bOnlyShims) {
  161. continue;
  162. }
  163. // This is an AppsHelp entry.
  164. PrintHeader(&header, szAppName, NULL);
  165. pszData = g_szData + lstrlen(g_szData);
  166. if (BlobToString(g_data + sizeof(KEYHEADER),
  167. cbData - sizeof(KEYHEADER) - sizeof(DWORD),
  168. pszData)) {
  169. (*pfnAddShim)(szAppName, szValueName, g_szData, TRUE, FALSE);
  170. } else {
  171. LogMsg("Failed to dump blob for AppsHelp entry: app '%s' entry '%s'\n",
  172. szAppName, szValueName);
  173. }
  174. continue;
  175. }
  176. bEnabled = FALSE;
  177. }
  178. // This is a shim.
  179. PrintHeader(&header, szAppName, szShimData);
  180. pszData = g_szData + lstrlen(g_szData);
  181. if (BlobToString(g_data + sizeof(KEYHEADER),
  182. cbData - sizeof(KEYHEADER) - sizeof(DWORD),
  183. pszData)) {
  184. (*pfnAddShim)(szAppName, szValueName, g_szData, bEnabled, TRUE);
  185. } else {
  186. LogMsg("Failed to dump blob for shim entry: app '%s' entry '%s'\n",
  187. szAppName, szValueName);
  188. }
  189. }
  190. RegCloseKey(hkeyApp);
  191. }
  192. RegCloseKey(hkey);
  193. return TRUE;
  194. }
  195. BOOL
  196. EnableShim_Win2000(
  197. char* pszApp,
  198. char* pszShim)
  199. {
  200. LONG status;
  201. HKEY hkey;
  202. char szAppKey[128];
  203. char szShimValueName[128];
  204. char szData[256];
  205. DWORD cbSize, dwType;
  206. BOOL bRet = FALSE;
  207. wsprintf(szAppKey, "%s\\%s",
  208. "System\\CurrentControlSet\\Control\\Session Manager\\AppCompatibility",
  209. pszApp);
  210. status = RegOpenKey(HKEY_LOCAL_MACHINE,
  211. szAppKey,
  212. &hkey);
  213. if (status != ERROR_SUCCESS) {
  214. LogMsg("Failed to open registry key %s\n", szAppKey);
  215. return FALSE;
  216. }
  217. wsprintf(szShimValueName, "-DllPatch-%s", pszShim);
  218. cbSize = 256;
  219. status = RegQueryValueEx(hkey,
  220. szShimValueName,
  221. NULL,
  222. &dwType,
  223. (LPBYTE)szData,
  224. &cbSize);
  225. if (status != ERROR_SUCCESS || dwType != REG_SZ || cbSize >= 256) {
  226. LogMsg("Error reading key %s\n", szShimValueName);
  227. goto Cleanup;
  228. }
  229. status = RegDeleteValue(hkey, szShimValueName);
  230. if (status != ERROR_SUCCESS) {
  231. LogMsg("Couldn't delete key %s\n", szShimValueName);
  232. goto Cleanup;
  233. }
  234. wsprintf(szShimValueName, "DllPatch-%s", pszShim);
  235. status = RegSetValueEx(hkey,
  236. szShimValueName,
  237. 0,
  238. REG_SZ,
  239. (LPBYTE)szData,
  240. cbSize);
  241. if (status != ERROR_SUCCESS) {
  242. LogMsg("Couldn't set value key %s\n", szShimValueName);
  243. goto Cleanup;
  244. }
  245. bRet = TRUE;
  246. Cleanup:
  247. RegCloseKey(hkey);
  248. return bRet;
  249. }
  250. BOOL
  251. DisableShim_Win2000(
  252. char* pszApp,
  253. char* pszShim)
  254. {
  255. LONG status;
  256. HKEY hkey;
  257. char szAppKey[128];
  258. char szShimValueName[128];
  259. char szData[256];
  260. DWORD cbSize, dwType;
  261. BOOL bRet = FALSE;
  262. wsprintf(szAppKey, "%s\\%s",
  263. "System\\CurrentControlSet\\Control\\Session Manager\\AppCompatibility",
  264. pszApp);
  265. status = RegOpenKey(HKEY_LOCAL_MACHINE,
  266. szAppKey,
  267. &hkey);
  268. if (status != ERROR_SUCCESS) {
  269. LogMsg("Failed to open registry key %s\n", szAppKey);
  270. return FALSE;
  271. }
  272. wsprintf(szShimValueName, "DllPatch-%s", pszShim);
  273. cbSize = 256;
  274. status = RegQueryValueEx(hkey,
  275. szShimValueName,
  276. NULL,
  277. &dwType,
  278. (LPBYTE)szData,
  279. &cbSize);
  280. if (status != ERROR_SUCCESS || dwType != REG_SZ || cbSize >= 256) {
  281. LogMsg("Error reading key %s\n", szShimValueName);
  282. goto Cleanup;
  283. }
  284. status = RegDeleteValue(hkey, szShimValueName);
  285. if (status != ERROR_SUCCESS) {
  286. LogMsg("Couldn't delete key %s\n", szShimValueName);
  287. goto Cleanup;
  288. }
  289. wsprintf(szShimValueName, "-DllPatch-%s", pszShim);
  290. status = RegSetValueEx(hkey,
  291. szShimValueName,
  292. 0,
  293. REG_SZ,
  294. (LPBYTE)szData,
  295. cbSize);
  296. if (status != ERROR_SUCCESS) {
  297. LogMsg("Couldn't set value key %s\n", szShimValueName);
  298. goto Cleanup;
  299. }
  300. bRet = TRUE;
  301. Cleanup:
  302. RegCloseKey(hkey);
  303. return bRet;
  304. }
  305. BOOL
  306. DeleteShim_Win2000(
  307. char* pszApp,
  308. char* pszShim)
  309. {
  310. LONG status;
  311. HKEY hkey;
  312. char szAppKey[128];
  313. char szShimValueName[128];
  314. wsprintf(szAppKey, "%s\\%s",
  315. "System\\CurrentControlSet\\Control\\Session Manager\\AppCompatibility",
  316. pszApp);
  317. status = RegOpenKey(HKEY_LOCAL_MACHINE,
  318. szAppKey,
  319. &hkey);
  320. if (status != ERROR_SUCCESS) {
  321. LogMsg("Failed to open registry key %s\n", szAppKey);
  322. return FALSE;
  323. }
  324. wsprintf(szShimValueName, "DllPatch-%s", pszShim);
  325. status = RegDeleteValue(hkey, szShimValueName);
  326. wsprintf(szShimValueName, "-DllPatch-%s", pszShim);
  327. status = RegDeleteValue(hkey, szShimValueName);
  328. RegCloseKey(hkey);
  329. return TRUE;
  330. }