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.

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