ReactOS  0.4.14-dev-1256-g2125fec
appcache.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Win32 Base API
3  * LICENSE: GPL - See COPYING in the top level directory
4  * FILE: dll/win32/kernel32/client/appcache.c
5  * PURPOSE: Application Compatibility Cache
6  * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7  */
8 
9 /* INCLUDES *******************************************************************/
10 
11 #include <k32.h>
12 
13 #define NDEBUG
14 #include <debug.h>
15 
16 /* GLOBALS ********************************************************************/
17 
22 
27 
28 #define APPHELP_VALID_RESULT 0x10000
29 #define APPHELP_RESULT_NOTFOUND 0x20000
30 #define APPHELP_RESULT_FOUND 0x40000
31 
32 
33 /* FUNCTIONS ******************************************************************/
34 
35 BOOLEAN
36 WINAPI
38 {
43  UNICODE_STRING OptionKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\SafeBoot\\Option");
44  UNICODE_STRING AppCompatKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\AppCompatibility");
45  UNICODE_STRING PolicyKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\Software\\Policies\\Microsoft\\Windows\\AppCompat");
46  UNICODE_STRING OptionValue = RTL_CONSTANT_STRING(L"OptionValue");
47  UNICODE_STRING DisableAppCompat = RTL_CONSTANT_STRING(L"DisableAppCompat");
48  UNICODE_STRING DisableEngine = RTL_CONSTANT_STRING(L"DisableEngine");
52 
53  /*
54  * This is a TROOLEAN, -1 means we haven't yet figured it out.
55  * 0 means shims are enabled, and 1 means shims are disabled!
56  */
57  if (g_ShimsDisabled == -1)
58  {
59  ULONG DisableShims = FALSE;
60 
61  /* Open the safe mode key */
62  Status = NtOpenKey(&KeyHandle, KEY_QUERY_VALUE, &OptionKeyAttributes);
63  if (NT_SUCCESS(Status))
64  {
65  /* Check if this is safemode */
67  &OptionValue,
69  &KeyInfo,
70  sizeof(KeyInfo),
71  &ResultLength);
73  if ((NT_SUCCESS(Status)) &&
74  (KeyInfo.Type == REG_DWORD) &&
75  (KeyInfo.DataLength == sizeof(ULONG)) &&
76  (KeyInfo.Data[0] != FALSE))
77  {
78  /* It is, so disable shims! */
79  DisableShims = TRUE;
80  }
81  }
82 
83  if (!DisableShims)
84  {
85  /* Open the app compatibility engine settings key */
87  if (NT_SUCCESS(Status))
88  {
89  /* Check if the app compat engine is turned off */
91  &DisableAppCompat,
93  &KeyInfo,
94  sizeof(KeyInfo),
95  &ResultLength);
97  if ((NT_SUCCESS(Status)) &&
98  (KeyInfo.Type == REG_DWORD) &&
99  (KeyInfo.DataLength == sizeof(ULONG)) &&
100  (KeyInfo.Data[0] == TRUE))
101  {
102  /* It is, so disable shims! */
103  DisableShims = TRUE;
104  }
105  }
106  }
107  if (!DisableShims)
108  {
109  /* Finally, open the app compatibility policy key */
110  Status = NtOpenKey(&KeyHandle, KEY_QUERY_VALUE, &PolicyKeyAttributes);
111  if (NT_SUCCESS(Status))
112  {
113  /* Check if the system policy disables app compat */
115  &DisableEngine,
117  &KeyInfo,
118  sizeof(KeyInfo),
119  &ResultLength);
121  if ((NT_SUCCESS(Status)) &&
122  (KeyInfo.Type == REG_DWORD) &&
123  (KeyInfo.DataLength == sizeof(ULONG)) &&
124  (KeyInfo.Data[0] == TRUE))
125  {
126  /* It does, so disable shims! */
127  DisableShims = TRUE;
128  }
129  }
130  }
131  g_ShimsDisabled = DisableShims;
132  }
133 
134  /* Return if shims are disabled or not ("Enabled == 1" means disabled!) */
135  return g_ShimsDisabled ? TRUE : FALSE;
136 }
137 
138 /*
139  * @unimplemented
140  */
141 BOOL
142 WINAPI
146  OUT PULONG Reason)
147 {
148  DPRINT("BaseCheckAppcompatCache is UNIMPLEMENTED\n");
149 
150  if (Reason) *Reason = 0;
151 
152  // We don't know this app.
153  return FALSE;
154 }
155 
156 static
157 VOID
159 {
160  WCHAR Buffer[MAX_PATH*2];
161  UNICODE_STRING DllPath = {0};
162  PVOID ApphelpAddress;
163  PVOID pApphelpCheckRunAppEx = NULL, pSdbPackAppCompatData = NULL;
164 
165  RtlInitEmptyUnicodeString(&DllPath, Buffer, sizeof(Buffer));
167  RtlAppendUnicodeToString(&DllPath, L"\\system32\\apphelp.dll");
168 
169  if (NT_SUCCESS(LdrLoadDll(NULL, NULL, &DllPath, &ApphelpAddress)))
170  {
171  ANSI_STRING ProcName;
172 
173  RtlInitAnsiString(&ProcName, "ApphelpCheckRunAppEx");
174  if (!NT_SUCCESS(LdrGetProcedureAddress(ApphelpAddress, &ProcName, 0, &pApphelpCheckRunAppEx)))
175  pApphelpCheckRunAppEx = NULL;
176 
177  RtlInitAnsiString(&ProcName, "SdbPackAppCompatData");
178  if (!NT_SUCCESS(LdrGetProcedureAddress(ApphelpAddress, &ProcName, 0, &pSdbPackAppCompatData)))
179  pSdbPackAppCompatData = NULL;
180  }
181 
183  {
184  g_pSdbPackAppCompatData = RtlEncodeSystemPointer(pSdbPackAppCompatData);
185  }
186 }
187 
188 /*
189  *
190  */
191 BOOL
192 WINAPI
196  IN USHORT ExeType,
197  IN PULONG pReason,
200  IN PVOID* SxsData,
203 {
204  ULONG Reason = 0;
205  ULONG64 Flags1 = 0;
206  ULONG Flags2 = 0;
207  BOOL Continue, NeedCleanup = FALSE;
208  tApphelpCheckRunAppEx pApphelpCheckRunAppEx;
209  tSdbPackAppCompatData pSdbPackAppCompatData;
210  PVOID QueryResult = NULL;
211  ULONG QueryResultSize = 0;
212 
214  {
215  BaseInitApphelp();
217  }
218 
219  pApphelpCheckRunAppEx = RtlDecodeSystemPointer(g_pApphelpCheckRunAppEx);
220  pSdbPackAppCompatData = RtlDecodeSystemPointer(g_pSdbPackAppCompatData);
221 
222  if (!pApphelpCheckRunAppEx || !pSdbPackAppCompatData)
223  return TRUE;
224 
225  if (pReason)
226  Reason = *pReason;
227 
228  Continue = pApphelpCheckRunAppEx(FileHandle, NULL, NULL, ApplicationName, Environment, ExeType, &Reason,
229  &QueryResult, &QueryResultSize, SxsData, SxsDataSize, FusionFlags, &Flags1, &Flags2);
230 
231  if (pReason)
232  *pReason = Reason;
233 
234  if (Continue)
235  {
237  {
238  if (!pSdbPackAppCompatData(NULL, QueryResult, SdbQueryAppCompatData, SdbQueryAppCompatDataSize))
239  {
240  DPRINT1("SdbPackAppCompatData returned a failure!\n");
241  NeedCleanup = TRUE;
242  }
243  }
244  else
245  {
246  NeedCleanup = TRUE;
247  }
248  }
249 
250  if (QueryResult)
251  RtlFreeHeap(RtlGetProcessHeap(), 0, QueryResult);
252 
253  if (NeedCleanup)
254  {
259  *SxsData = NULL;
260  if (SxsDataSize)
261  *SxsDataSize = 0;
262  }
263 
264  return Continue;
265 }
266 
267 /*
268  * @implemented
269  */
270 NTSTATUS
271 WINAPI
275  IN USHORT ExeType,
278  IN PVOID* SxsData,
281 {
283  ULONG Reason = 0;
284 
285  /* Is shimming enabled by group policy? */
287  {
288  /* Nothing to worry about */
290  }
291  else
292  {
293  /* It is, check if we know about this app */
295  FileHandle,
296  Environment,
297  &Reason))
298  {
301  {
303  }
304  }
305  }
306 
307  /* Return caller the status */
308  return Status;
309 }
310 
311 /*
312  * @implemented
313  */
314 BOOL
315 WINAPI
317 {
319 
321  return NT_SUCCESS(Status);
322 }
323 
324 /*
325  * @implemented
326  */
327 BOOL
328 WINAPI
330 {
332 
334  return NT_SUCCESS(Status);
335 }
336 
337 /*
338  * @implemented
339  */
340 VOID
341 WINAPI
343  IN PVOID AppCompatSxsData)
344 {
345  /* Free the input pointers if present */
346  if (AppCompatData) RtlFreeHeap(RtlGetProcessHeap(), 0, AppCompatData);
347  if (AppCompatSxsData) RtlFreeHeap(RtlGetProcessHeap(), 0, AppCompatSxsData);
348 }
349 
350 /*
351  * @unimplemented
352  */
353 VOID
354 WINAPI
356  ULONG Unknown2,
357  ULONG Unknown3)
358 {
359  STUB;
360 }
361 
362 /*
363  * @unimplemented
364  */
365 NTSTATUS
366 WINAPI
368 {
369  STUB;
370  return STATUS_NOT_IMPLEMENTED;
371 }
372 
373 /*
374  * @unimplemented
375  */
376 NTSTATUS
377 WINAPI
379 {
380  STUB;
381  return STATUS_NOT_IMPLEMENTED;
382 }
383 
384 /*
385  * @unimplemented
386  */
387 BOOL
388 WINAPI
390 {
391  STUB;
392  return FALSE;
393 }
394 
395 /*
396  * @unimplemented
397  */
398 BOOL
399 WINAPI
401 {
402  STUB;
403  return FALSE;
404 }
405 
406 /*
407  * @unimplemented
408  */
409 PVOID
410 WINAPI
412 {
413  STUB;
414  return NULL;
415 }
416 
417 /*
418  * @unimplemented
419  */
420 BOOL
421 WINAPI
423 {
424  STUB;
425  return FALSE;
426 }
427 
428 /*
429  * @unimplemented
430  */
431 VOID
432 WINAPI
434 {
435  STUB;
436 }
437 
438 /*
439  * @unimplemented
440  */
441 BOOL
442 WINAPI
444 {
445  STUB;
446  return FALSE;
447 }
IN CINT OUT PVOID IN ULONG OUT PULONG ResultLength
Definition: conport.c:47
PVOID NTAPI RtlEncodeSystemPointer(IN PVOID Pointer)
Definition: process.c:429
VOID WINAPI BasepFreeAppCompatData(IN PVOID AppCompatData, IN PVOID AppCompatSxsData)
Definition: appcache.c:342
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:45
#define IN
Definition: typedefs.h:39
BOOL WINAPI BaseCheckRunApp(IN HANDLE FileHandle, IN PWCHAR ApplicationName, IN PWCHAR Environment, IN USHORT ExeType, IN PULONG pReason, IN PVOID *SdbQueryAppCompatData, IN PULONG SdbQueryAppCompatDataSize, IN PVOID *SxsData, IN PULONG SxsDataSize, OUT PULONG FusionFlags)
Definition: appcache.c:193
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID PULONG PULONG FusionFlags
Definition: env.c:45
#define TRUE
Definition: types.h:120
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES IN DWORD Unknown3
Definition: conport.c:35
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
static BOOL g_ApphelpInitialized
Definition: appcache.c:19
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
OBJECT_ATTRIBUTES AppCompatKeyAttributes
Definition: shimdbg.c:228
static IN LPSTR IN PVOID Unk2
Definition: ldrinit.c:47
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
uint16_t * PWCHAR
Definition: typedefs.h:55
VOID WINAPI BaseUpdateAppcompatCache(ULONG Unknown1, ULONG Unknown2, ULONG Unknown3)
Definition: appcache.c:355
LPCWSTR LPCWSTR LPCWSTR DWORD PSDBQUERYRESULT_VISTA pQueryResult
Definition: env.c:35
#define BOOL
Definition: nt_native.h:43
VOID WINAPI SetTermsrvAppInstallMode(IN BOOL bInstallMode)
Definition: appcache.c:433
static VOID BaseInitApphelp(VOID)
Definition: appcache.c:158
NTSYSAPI VOID NTAPI RtlCopyUnicodeString(PUNICODE_STRING DestinationString, PUNICODE_STRING SourceString)
BOOL WINAPI BaseInitAppcompatCache(VOID)
Definition: appcache.c:389
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
BOOLEAN WINAPI IsShimInfrastructureDisabled(VOID)
Definition: appcache.c:37
HANDLE FileHandle
Definition: stats.c:38
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID PULONG PULONG PULONG64 SomeFlag1
Definition: env.c:45
unsigned int BOOL
Definition: ntddk_ex.h:94
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
NTSTATUS WINAPI BaseCleanupAppcompatCacheSupport(PVOID pUnknown)
Definition: appcache.c:378
static PVOID g_pApphelpCheckRunAppEx
Definition: appcache.c:20
NTSTATUS NTAPI LdrGetProcedureAddress(IN PVOID BaseAddress, IN PANSI_STRING Name, IN ULONG Ordinal, OUT PVOID *ProcedureAddress)
Definition: ldrapi.c:823
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
PVOID NTAPI RtlDecodeSystemPointer(IN PVOID Pointer)
Definition: process.c:439
void DPRINT(...)
Definition: polytest.cpp:61
Definition: bufpool.h:45
BOOL WINAPI BaseCheckAppcompatCache(IN PWCHAR ApplicationName, IN HANDLE FileHandle, IN PWCHAR Environment, OUT PULONG Reason)
Definition: appcache.c:143
#define APPHELP_RESULT_FOUND
Definition: appcache.c:30
_In_ PUNKNOWN pUnknown
Definition: drmk.h:76
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
UNICODE_STRING BaseWindowsDirectory
Definition: path.c:20
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define MAX_PATH
Definition: compat.h:26
#define WINAPI
Definition: msvc.h:6
NTSTATUS NTAPI NtApphelpCacheControl(_In_ APPHELPCACHESERVICECLASS Service, _In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData)
Definition: apphelp.c:729
unsigned long DWORD
Definition: ntddk_ex.h:95
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
static IN LPSTR Unk1
Definition: ldrinit.c:47
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
PSDBQUERYRESULT_VISTA PVOID * ppData
Definition: env.c:54
unsigned __int64 ULONG64
Definition: imports.h:198
volatile int Continue
Definition: gdblib.c:102
static const WCHAR L[]
Definition: oid.c:1250
static PVOID g_pSdbPackAppCompatData
Definition: appcache.c:21
NTSTATUS NTAPI DECLSPEC_HOTPATCH LdrLoadDll(IN PWSTR SearchPath OPTIONAL, IN PULONG DllCharacteristics OPTIONAL, IN PUNICODE_STRING DllName, OUT PVOID *BaseAddress)
Definition: ldrapi.c:310
BOOL(WINAPI * tSdbPackAppCompatData)(PVOID hsdb, PVOID pQueryResult, PVOID *ppData, DWORD *dwSize)
Definition: appcache.c:26
ULONG g_ShimsDisabled
Definition: appcache.c:18
NTSTATUS WINAPI BaseCleanupAppcompatCache(VOID)
Definition: appcache.c:367
Status
Definition: gdiplustypes.h:24
BOOL WINAPI BaseFlushAppcompatCache(VOID)
Definition: appcache.c:329
PVOID WINAPI GetComPlusPackageInstallStatus(VOID)
Definition: appcache.c:411
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
PVOID PVOID PWCHAR ApplicationName
Definition: env.c:45
PVOID PVOID PWCHAR PVOID USHORT ExeType
Definition: env.c:45
#define STUB
Definition: kernel32.h:27
unsigned short USHORT
Definition: pedump.c:61
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID PULONG SxsDataSize
Definition: env.c:45
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
static const char const char * DllPath
Definition: image.c:34
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID PULONG PULONG PULONG64 PULONG SomeFlag2
Definition: env.c:45
unsigned int * PULONG
Definition: retypes.h:1
BOOL WINAPI BaseInitAppcompatCacheSupport(VOID)
Definition: appcache.c:400
#define DPRINT1
Definition: precomp.h:8
#define APPHELP_VALID_RESULT
Definition: appcache.c:28
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
BOOL WINAPI BaseDumpAppcompatCache(VOID)
Definition: appcache.c:316
BOOL WINAPI TermsrvAppInstallMode(VOID)
Definition: appcache.c:443
#define OUT
Definition: typedefs.h:40
unsigned int ULONG
Definition: retypes.h:1
BOOL WINAPI SetComPlusPackageInstallStatus(LPVOID lpInfo)
Definition: appcache.c:422
unsigned __int64 * PULONG64
Definition: imports.h:198
BOOL(WINAPI * tApphelpCheckRunAppEx)(HANDLE FileHandle, PVOID Unk1, PVOID Unk2, PWCHAR ApplicationName, PVOID Environment, USHORT ExeType, PULONG Reason, PVOID *SdbQueryAppCompatData, PULONG SdbQueryAppCompatDataSize, PVOID *SxsData, PULONG SxsDataSize, PULONG FusionFlags, PULONG64 SomeFlag1, PULONG SomeFlag2)
Definition: appcache.c:23
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID * SxsData
Definition: env.c:45
localAdvHdr Flags2
Definition: fsrtlfuncs.h:1692
return STATUS_SUCCESS
Definition: btrfs.c:2938
PVOID PVOID PWCHAR PVOID USHORT PULONG Reason
Definition: env.c:45
#define REG_DWORD
Definition: sdbapi.c:596
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID * SdbQueryAppCompatData
Definition: env.c:45
PSDBQUERYRESULT_VISTA PVOID DWORD * dwSize
Definition: env.c:54
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG SdbQueryAppCompatDataSize
Definition: env.c:45
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
NTSTATUS WINAPI BasepCheckBadapp(IN HANDLE FileHandle, IN PWCHAR ApplicationName, IN PWCHAR Environment, IN USHORT ExeType, IN PVOID *SdbQueryAppCompatData, IN PULONG SdbQueryAppCompatDataSize, IN PVOID *SxsData, IN PULONG SxsDataSize, OUT PULONG FusionFlags)
Definition: appcache.c:272