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.

272 lines
9.2 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. apcompat.c
  5. Abstract:
  6. This source implements checking AppCompatibility key that will come with NT
  7. Author:
  8. Calin Negreanu (calinn) 18-May-1999
  9. Revision History:
  10. --*/
  11. #include "pch.h"
  12. #include "badapps.h"
  13. // #define _OLDAPPDB
  14. #define DBG_APPCOMPAT "AppCompat"
  15. //
  16. // Globals
  17. //
  18. POOLHANDLE g_AppCompatPool = NULL;
  19. HASHTABLE g_AppCompatTable = NULL;
  20. HINF g_AppCompatInf = INVALID_HANDLE_VALUE;
  21. //
  22. // ISSUE - this will change to appmig.inf - leave it the old way until
  23. // AppCompat team checks in the new file
  24. //
  25. #define S_APP_COMPAT_FILE1 TEXT("APPMIG.INF")
  26. #define S_APP_COMPAT_FILE2 TEXT("APPMIG.IN_")
  27. #define S_BASE_WIN_OPTIONS TEXT("BaseWinOptions")
  28. #define S_ADD_REG TEXT("AddReg")
  29. typedef struct _APPCOMPAT_FILE {
  30. PBYTE Info;
  31. DWORD InfoSize;
  32. struct _APPCOMPAT_FILE *Next;
  33. } APPCOMPAT_FILE, *PAPPCOMPAT_FILE;
  34. BOOL
  35. pInitAppCompat (
  36. VOID
  37. )
  38. {
  39. PCSTR AppCompatFile = NULL;
  40. PCSTR AppCompatCompFile = NULL;
  41. DWORD decompResult;
  42. BOOL result = TRUE;
  43. INFCONTEXT baseContext, addContext, regContext;
  44. TCHAR baseSection [MEMDB_MAX];
  45. TCHAR addSection [MEMDB_MAX];
  46. TCHAR regValue [MEMDB_MAX];
  47. TCHAR fieldStr [MEMDB_MAX];
  48. INT fieldVal;
  49. PCTSTR regFile;
  50. PAPPCOMPAT_FILE appCompatFile;
  51. DWORD index;
  52. HASHITEM stringId;
  53. if (CANCELLED()) {
  54. SetLastError (ERROR_CANCELLED);
  55. return FALSE;
  56. }
  57. __try {
  58. AppCompatFile = JoinPaths (SOURCEDIRECTORY(0), S_APP_COMPAT_FILE1);
  59. g_AppCompatInf = InfOpenInfFile (AppCompatFile);
  60. if (g_AppCompatInf == INVALID_HANDLE_VALUE) {
  61. FreePathString (AppCompatFile);
  62. AppCompatFile = JoinPaths (g_TempDir, S_APP_COMPAT_FILE1);
  63. AppCompatCompFile = JoinPaths (SOURCEDIRECTORY(0), S_APP_COMPAT_FILE2);
  64. decompResult = SetupDecompressOrCopyFile (AppCompatCompFile, AppCompatFile, 0);
  65. if ((decompResult != ERROR_SUCCESS) && (decompResult != ERROR_ALREADY_EXISTS)) {
  66. LOG((LOG_ERROR, "Cannot open Application compatibility database : %s", AppCompatCompFile));
  67. result = FALSE;
  68. __leave;
  69. }
  70. g_AppCompatInf = InfOpenInfFile (AppCompatFile);
  71. if (g_AppCompatInf == INVALID_HANDLE_VALUE) {
  72. LOG((LOG_ERROR, "Cannot open Application compatibility database : %s", AppCompatCompFile));
  73. result = FALSE;
  74. __leave;
  75. }
  76. }
  77. g_AppCompatPool = PoolMemInitNamedPool ("AppCompat Pool");
  78. g_AppCompatTable = HtAllocWithData (sizeof (PAPPCOMPAT_FILE));
  79. if (g_AppCompatTable == NULL) {
  80. LOG((LOG_ERROR, "Cannot initialize memory for Application compatibility operations"));
  81. result = FALSE;
  82. __leave;
  83. }
  84. //
  85. // finally load the data from ApCompat.inf
  86. //
  87. if (SetupFindFirstLine (g_AppCompatInf, S_BASE_WIN_OPTIONS, NULL, &baseContext)) {
  88. do {
  89. if (SetupGetStringField (&baseContext, 1, baseSection, MEMDB_MAX, NULL)) {
  90. if (SetupFindFirstLine (g_AppCompatInf, baseSection, S_ADD_REG, &addContext)) {
  91. do {
  92. if (SetupGetStringField (&addContext, 1, addSection, MEMDB_MAX, NULL)) {
  93. if (SetupFindFirstLine (g_AppCompatInf, addSection, NULL, &regContext)) {
  94. do {
  95. if (SetupGetStringField (&regContext, 2, regValue, MEMDB_MAX, NULL)) {
  96. regFile = GetFileNameFromPath (regValue);
  97. appCompatFile = (PAPPCOMPAT_FILE) PoolMemGetMemory (g_AppCompatPool, sizeof (APPCOMPAT_FILE));
  98. ZeroMemory (appCompatFile, sizeof (APPCOMPAT_FILE));
  99. index = SetupGetFieldCount (&regContext);
  100. if (index > 4) {
  101. appCompatFile->Info = (PBYTE) PoolMemGetMemory (g_AppCompatPool, index - 4);
  102. appCompatFile->InfoSize = index - 4;
  103. index = 0;
  104. while (SetupGetStringField (&regContext, index+5, fieldStr, MEMDB_MAX, NULL)) {
  105. sscanf (fieldStr, TEXT("%x"), &fieldVal);
  106. appCompatFile->Info [index] = (BYTE) fieldVal;
  107. index ++;
  108. }
  109. if (index) {
  110. stringId = HtFindString (g_AppCompatTable, regFile);
  111. if (stringId) {
  112. HtCopyStringData (g_AppCompatTable, stringId, &(appCompatFile->Next));
  113. HtSetStringData (g_AppCompatTable, stringId, &appCompatFile);
  114. } else {
  115. HtAddStringAndData (g_AppCompatTable, regFile, &appCompatFile);
  116. }
  117. }
  118. }
  119. }
  120. } while (SetupFindNextLine (&regContext, &regContext));
  121. }
  122. }
  123. } while (SetupFindNextLine (&addContext, &addContext));
  124. }
  125. }
  126. } while (SetupFindNextLine (&baseContext, &baseContext));
  127. }
  128. }
  129. __finally {
  130. if (AppCompatFile) {
  131. FreePathString (AppCompatFile);
  132. AppCompatFile = NULL;
  133. }
  134. if (AppCompatCompFile) {
  135. FreePathString (AppCompatCompFile);
  136. AppCompatCompFile = NULL;
  137. }
  138. }
  139. return result;
  140. }
  141. DWORD
  142. InitAppCompat (
  143. IN DWORD Request
  144. )
  145. {
  146. switch (Request) {
  147. case REQUEST_QUERYTICKS:
  148. return TICKS_INIT_APP_COMPAT;
  149. case REQUEST_RUN:
  150. if (!pInitAppCompat ()) {
  151. return GetLastError ();
  152. }
  153. else {
  154. return ERROR_SUCCESS;
  155. }
  156. default:
  157. DEBUGMSG ((DBG_ERROR, "Bad parameter in InitAppCompat"));
  158. }
  159. return 0;
  160. }
  161. BOOL
  162. pDoneAppCompat (
  163. VOID
  164. )
  165. {
  166. if (g_AppCompatTable) {
  167. HtFree (g_AppCompatTable);
  168. g_AppCompatTable = NULL;
  169. }
  170. if (g_AppCompatPool) {
  171. PoolMemDestroyPool (g_AppCompatPool);
  172. g_AppCompatPool = NULL;
  173. }
  174. if (g_AppCompatInf != INVALID_HANDLE_VALUE) {
  175. InfCloseInfFile (g_AppCompatInf);
  176. g_AppCompatInf = INVALID_HANDLE_VALUE;
  177. }
  178. return TRUE;
  179. }
  180. DWORD
  181. DoneAppCompat (
  182. IN DWORD Request
  183. )
  184. {
  185. switch (Request) {
  186. case REQUEST_QUERYTICKS:
  187. return TICKS_DONE_APP_COMPAT;
  188. case REQUEST_RUN:
  189. if (!pDoneAppCompat ()) {
  190. return GetLastError ();
  191. }
  192. else {
  193. return ERROR_SUCCESS;
  194. }
  195. default:
  196. DEBUGMSG ((DBG_ERROR, "Bad parameter in DoneAppCompat"));
  197. }
  198. return 0;
  199. }
  200. BOOL
  201. AppCompatTestFile (
  202. IN OUT PFILE_HELPER_PARAMS Params
  203. )
  204. {
  205. PCTSTR filePtr;
  206. HASHITEM stringId;
  207. PAPPCOMPAT_FILE appCompatFile;
  208. BOOL found = FALSE;
  209. BADAPP_DATA badAppData;
  210. BADAPP_PROP badAppProp;
  211. if (Params->Handled == 0) {
  212. filePtr = GetFileNameFromPath (Params->FullFileSpec);
  213. if (filePtr) {
  214. stringId = HtFindString (g_AppCompatTable, filePtr);
  215. if (stringId) {
  216. HtCopyStringData (g_AppCompatTable, stringId, &appCompatFile);
  217. while (!found && appCompatFile) {
  218. if (appCompatFile->Info) {
  219. badAppProp.Size = sizeof(BADAPP_PROP);
  220. badAppData.Size = sizeof(BADAPP_DATA);
  221. badAppData.FilePath = Params->FullFileSpec;
  222. badAppData.Blob = appCompatFile->Info;
  223. badAppData.BlobSize = appCompatFile->InfoSize;
  224. if (SHIsBadApp(&badAppData, &badAppProp)) {
  225. switch (badAppProp.AppType & APPTYPE_TYPE_MASK)
  226. {
  227. case APPTYPE_INC_HARDBLOCK:
  228. case APPTYPE_INC_NOBLOCK:
  229. found = TRUE;
  230. MarkFileForExternalDelete (Params->FullFileSpec);
  231. if (!IsFileMarkedForAnnounce (Params->FullFileSpec)) {
  232. AnnounceFileInReport (Params->FullFileSpec, 0, ACT_INCOMPATIBLE);
  233. }
  234. Params->Handled = TRUE;
  235. }
  236. }
  237. }
  238. appCompatFile = appCompatFile->Next;
  239. }
  240. }
  241. }
  242. }
  243. return TRUE;
  244. }