ReactOS  0.4.15-dev-5446-g3f3714b
apphelp.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Kernel
3  * LICENSE: BSD - See COPYING.ARM in the top level directory
4  * FILE: ntoskrnl/ps/apphelp.c
5  * PURPOSE: SHIM engine caching.
6  * This caching speeds up checks for the apphelp compatibility layer.
7  * PROGRAMMERS: Mark Jansen
8  */
9 
10 /*
11 Useful references:
12 https://github.com/mandiant/ShimCacheParser/blob/master/ShimCacheParser.py
13 http://technet.microsoft.com/en-us/library/dd837644(v=ws.10).aspx
14 http://msdn.microsoft.com/en-us/library/bb432182(v=vs.85).aspx
15 http://www.alex-ionescu.com/?p=43
16 http://recxltd.blogspot.nl/2012/04/windows-appcompat-research-notes-part-1.html
17 http://journeyintoir.blogspot.ch/2013/12/revealing-recentfilecachebcf-file.html
18 https://dl.mandiant.com/EE/library/Whitepaper_ShimCacheParser.pdf
19 */
20 
21 /* INCLUDES ******************************************************************/
22 
23 #include <ntoskrnl.h>
24 #define NDEBUG
25 #include <debug.h>
26 
27 /* GLOBALS *******************************************************************/
28 
33 
34 extern ULONG InitSafeBootMode;
35 
36 static UNICODE_STRING AppCompatCacheKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\AppCompatCache");
39 
40 #define EMPTY_SHIM_ENTRY { { 0 }, { { 0 } }, 0 }
41 #define MAX_SHIM_ENTRIES 0x200
42 
43 #ifndef INVALID_HANDLE_VALUE
44 #define INVALID_HANDLE_VALUE (HANDLE)(-1)
45 #endif
46 
47 #include <pshpack1.h>
48 
50 {
54 
55 /* The data that is present in the registry (Win2k3 version) */
57 {
62 
63 #include <poppack.h>
64 
65 #define CACHE_MAGIC_NT_52 0xbadc0ffe
66 #define CACHE_HEADER_SIZE_NT_52 0x8
67 #define NT52_PERSISTENT_ENTRY_SIZE32 0x18
68 #define NT52_PERSISTENT_ENTRY_SIZE64 0x20
69 
70 //#define CACHE_MAGIC_NT_61 0xbadc0fee
71 //#define CACHE_HEADER_SIZE_NT_61 0x80
72 //#define NT61_PERSISTENT_ENTRY_SIZE32 0x20
73 //#define NT61_PERSISTENT_ENTRY_SIZE64 0x30
74 
75 #define SHIM_CACHE_MAGIC CACHE_MAGIC_NT_52
76 #define SHIM_CACHE_HEADER_SIZE CACHE_HEADER_SIZE_NT_52
77 #ifdef _WIN64
78 #define SHIM_PERSISTENT_CACHE_ENTRY_SIZE NT52_PERSISTENT_ENTRY_SIZE64
79 #else
80 #define SHIM_PERSISTENT_CACHE_ENTRY_SIZE NT52_PERSISTENT_ENTRY_SIZE32
81 #endif
82 #define SHIM_PERSISTENT_CACHE_HEADER SHIM_PERSISTENT_CACHE_HEADER_52
83 #define PSHIM_PERSISTENT_CACHE_HEADER PSHIM_PERSISTENT_CACHE_HEADER_52
84 #define SHIM_PERSISTENT_CACHE_ENTRY SHIM_PERSISTENT_CACHE_ENTRY_52
85 #define PSHIM_PERSISTENT_CACHE_ENTRY PSHIM_PERSISTENT_CACHE_ENTRY_52
86 
89 
90 /* The struct we keep in memory */
91 typedef struct SHIM_CACHE_ENTRY
92 {
97 
98 /* PRIVATE FUNCTIONS *********************************************************/
99 
100 PVOID
103 {
105 }
106 
107 VOID
109  _In_ PVOID Data)
110 {
112 }
113 
114 VOID
116 {
119 }
120 
121 BOOLEAN
123 {
126  {
128  return FALSE;
129  }
130  return TRUE;
131 }
132 
133 VOID
135 {
138 }
139 
140 VOID
144 {
145  Destination->Length = Source->Length;
146  if (Destination->Length)
147  {
152  }
153  else
154  {
157  }
158 }
159 
160 VOID
163 {
164  if (String->Buffer)
165  {
166  ApphelpFree(String->Buffer);
167  }
168  String->Length = 0;
169  String->MaximumLength = 0;
170  String->Buffer = NULL;
171 }
172 
173 /* Query file info from a handle, storing it in Entry */
174 NTSTATUS
176  _In_ HANDLE ImageHandle,
178 {
180  FILE_BASIC_INFORMATION FileBasic;
181  FILE_STANDARD_INFORMATION FileStandard;
183 
184  Status = ZwQueryInformationFile(ImageHandle,
185  &IoStatusBlock,
186  &FileBasic,
187  sizeof(FileBasic),
189  if (!NT_SUCCESS(Status))
190  {
191  return Status;
192  }
193 
194  Status = ZwQueryInformationFile(ImageHandle,
195  &IoStatusBlock,
196  &FileStandard,
197  sizeof(FileStandard),
199  if (NT_SUCCESS(Status))
200  {
201  Entry->Persistent.DateTime = FileBasic.LastWriteTime;
202  Entry->Persistent.FileSize = FileStandard.EndOfFile;
203  }
204  return Status;
205 }
206 
208 NTAPI
210  _In_ struct _RTL_AVL_TABLE *Table,
213 {
214  PSHIM_CACHE_ENTRY FirstEntry = FirstStruct;
215  PSHIM_CACHE_ENTRY SecondEntry = SecondStruct;
216  LONG Result;
217 
218  Result = RtlCompareUnicodeString(&FirstEntry->Persistent.ImageName,
219  &SecondEntry->Persistent.ImageName,
220  TRUE);
221  if (Result < 0)
222  {
223  return GenericLessThan;
224  }
225  else if (Result == 0)
226  {
227  return GenericEqual;
228  }
229  return GenericGreaterThan;
230 }
231 
232 PVOID
233 NTAPI
235  _In_ struct _RTL_AVL_TABLE *Table,
237 {
238  return ApphelpAlloc(ByteSize);
239 }
240 
241 VOID
242 NTAPI
244  _In_ struct _RTL_AVL_TABLE *Table,
245  _In_ PVOID Buffer)
246 {
248 }
249 
250 NTSTATUS
254 {
256  ULONG Cur;
257  ULONG NumEntries;
261  PSHIM_PERSISTENT_CACHE_ENTRY Persistent;
262 
264  {
265  DPRINT1("SHIMS: ApphelpCacheParse not enough data for a minimal header (0x%x)\n", DataLength);
267  }
268 
269  if (Header->Magic != SHIM_CACHE_MAGIC)
270  {
271  DPRINT1("SHIMS: ApphelpCacheParse found invalid magic (0x%x)\n", Header->Magic);
273  }
274 
275  NumEntries = Header->NumEntries;
276  DPRINT("SHIMS: ApphelpCacheParse walking %d entries\n", NumEntries);
277  for (Cur = 0; Cur < NumEntries; ++Cur)
278  {
281  /* The entry in the Persistent storage is not really a UNICODE_STRING,
282  so we have to convert the offset into a real pointer before using it. */
283  String.Length = Persistent->ImageName.Length;
284  String.MaximumLength = Persistent->ImageName.MaximumLength;
285  String.Buffer = (PWCHAR)((ULONG_PTR)Persistent->ImageName.Buffer + Data);
286 
287  /* Now we copy all data to a local buffer, that can be safely duplicated by RtlInsert */
288  Entry.Persistent = *Persistent;
289  ApphelpDuplicateUnicodeString(&Entry.Persistent.ImageName, &String);
291  &Entry,
292  sizeof(Entry),
293  NULL);
294  if (!Result)
295  {
296  DPRINT1("SHIMS: ApphelpCacheParse insert failed\n");
297  ApphelpFreeUnicodeString(&Entry.Persistent.ImageName);
299  }
301  }
302  return STATUS_SUCCESS;
303 }
304 
305 BOOLEAN
307 {
310  KEY_VALUE_PARTIAL_INFORMATION KeyValueObject;
311  PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation = &KeyValueObject;
312  ULONG KeyInfoSize, ResultSize;
313 
315  if (!NT_SUCCESS(Status))
316  {
317  DPRINT1("SHIMS: ApphelpCacheRead could not even open Session Manager\\AppCompatCache (0x%x)\n", Status);
318  return FALSE;
319  }
320 
321  Status = ZwQueryValueKey(KeyHandle,
324  KeyValueInformation,
325  sizeof(KeyValueObject),
326  &ResultSize);
328  {
329  KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + KeyValueInformation->DataLength;
330  KeyValueInformation = ApphelpAlloc(KeyInfoSize);
331  if (KeyValueInformation != NULL)
332  {
333  Status = ZwQueryValueKey(KeyHandle,
336  KeyValueInformation,
337  KeyInfoSize,
338  &ResultSize);
339  }
340  }
341 
342  if (NT_SUCCESS(Status) && KeyValueInformation->Type == REG_BINARY)
343  {
344  Status = ApphelpCacheParse(KeyValueInformation->Data,
345  KeyValueInformation->DataLength);
346  }
347  else
348  {
349  DPRINT1("SHIMS: ApphelpCacheRead not loaded from registry (0x%x)\n", Status);
350  }
351 
352  if (KeyValueInformation != &KeyValueObject && KeyValueInformation != NULL)
353  {
354  ApphelpFree(KeyValueInformation);
355  }
356 
358  return NT_SUCCESS(Status);
359 }
360 
361 BOOLEAN
363 {
365  ULONG NumEntries = 0;
366  PLIST_ENTRY ListEntry;
367  PUCHAR Buffer, BufferNamePos;
369  PSHIM_PERSISTENT_CACHE_ENTRY WriteEntry;
372 
373  /* First we have to calculate the required size. */
375  ListEntry = ApphelpShimCacheAge.Flink;
376  while (ListEntry != &ApphelpShimCacheAge)
377  {
380  Length += Entry->Persistent.ImageName.MaximumLength;
381  ++NumEntries;
382  ListEntry = ListEntry->Flink;
383  }
384  DPRINT("SHIMS: ApphelpCacheWrite, %d Entries, total size: %d\n", NumEntries, Length);
385  Length = ROUND_UP(Length, sizeof(ULONGLONG));
386  DPRINT("SHIMS: ApphelpCacheWrite, Rounded to: %d\n", Length);
387 
388  /* Now we allocate and prepare some helpers */
390  BufferNamePos = Buffer + Length;
393 
394  Header->Magic = SHIM_CACHE_MAGIC;
395  Header->NumEntries = NumEntries;
396 
397  ListEntry = ApphelpShimCacheAge.Flink;
398  while (ListEntry != &ApphelpShimCacheAge)
399  {
401  USHORT ImageNameLen = Entry->Persistent.ImageName.MaximumLength;
402  /* Copy the Persistent structure over */
403  *WriteEntry = Entry->Persistent;
404  BufferNamePos -= ImageNameLen;
405  /* Copy the image name over */
406  RtlCopyMemory(BufferNamePos, Entry->Persistent.ImageName.Buffer, ImageNameLen);
407  /* Fix the Persistent structure, so that Buffer is once again an offset */
408  WriteEntry->ImageName.Buffer = (PWCH)(BufferNamePos - Buffer);
409 
410  ++WriteEntry;
411  ListEntry = ListEntry->Flink;
412  }
414 
416  if (NT_SUCCESS(Status))
417  {
418  Status = ZwSetValueKey(KeyHandle,
420  0,
421  REG_BINARY,
422  Buffer,
423  Length);
425  }
426  else
427  {
428  DPRINT1("SHIMS: ApphelpCacheWrite could not even open Session Manager\\AppCompatCache (0x%x)\n", Status);
429  }
430 
432  return NT_SUCCESS(Status);
433 }
434 
435 
436 CODE_SEG("INIT")
437 NTSTATUS
438 NTAPI
440 {
441  DPRINT("SHIMS: ApphelpCacheInitialize\n");
442  /* If we are booting in safemode we do not want to use the apphelp cache */
443  if (InitSafeBootMode)
444  {
445  DPRINT1("SHIMS: Safe mode detected, disabling cache.\n");
447  }
448  else
449  {
455  NULL);
458  }
459  DPRINT("SHIMS: ApphelpCacheInitialize: %d\n", ApphelpCacheEnabled);
460  return STATUS_SUCCESS;
461 }
462 
463 VOID
464 NTAPI
466 {
468  {
470  }
471 }
472 
473 NTSTATUS
477  _Out_ PHANDLE ImageHandle)
478 {
480 
481  if (ServiceData)
482  {
483  UNICODE_STRING LocalImageName;
484  _SEH2_TRY
485  {
486  ProbeForRead(ServiceData,
488  sizeof(ULONG));
489  LocalImageName = ServiceData->ImageName;
490  *ImageHandle = ServiceData->ImageHandle;
491  if (LocalImageName.Length && LocalImageName.Buffer)
492  {
493  ProbeForRead(LocalImageName.Buffer,
494  LocalImageName.Length * sizeof(WCHAR),
495  1);
496  ApphelpDuplicateUnicodeString(ImageName, &LocalImageName);
498  }
499  }
501  {
503  }
504  _SEH2_END;
505  }
506  if (!NT_SUCCESS(Status))
507  {
508  DPRINT1("SHIMS: ApphelpValidateData: invalid data passed\n");
509  }
510  return Status;
511 }
512 
513 NTSTATUS
516 {
517  if (Entry)
518  {
519  PWSTR Buffer = Entry->Persistent.ImageName.Buffer;
520  RemoveEntryList(&Entry->List);
522  {
524  }
525  return STATUS_SUCCESS;
526  }
527  return STATUS_NOT_FOUND;
528 }
529 
530 NTSTATUS
533  _In_ HANDLE ImageHandle)
534 {
538 
540  {
541  return Status;
542  }
543 
544  Lookup.Persistent.ImageName = *ImageName;
546  if (Entry == NULL)
547  {
548  DPRINT("SHIMS: ApphelpCacheLookupEntry: could not find %wZ\n", ImageName);
549  goto Cleanup;
550  }
551 
552  DPRINT("SHIMS: ApphelpCacheLookupEntry: found %wZ\n", ImageName);
553  if (ImageHandle == INVALID_HANDLE_VALUE)
554  {
555  DPRINT("SHIMS: ApphelpCacheLookupEntry: ok\n");
556  /* just return if we know it, do not query file info */
558  }
559  else
560  {
561  Status = ApphelpCacheQueryInfo(ImageHandle, &Lookup);
562  if (NT_SUCCESS(Status) &&
563  Lookup.Persistent.DateTime.QuadPart == Entry->Persistent.DateTime.QuadPart &&
564  Lookup.Persistent.FileSize.QuadPart == Entry->Persistent.FileSize.QuadPart)
565  {
566  DPRINT("SHIMS: ApphelpCacheLookupEntry: found & validated\n");
568  /* move it to the front to keep it alive */
569  RemoveEntryList(&Entry->List);
571  }
572  else
573  {
574  DPRINT1("SHIMS: ApphelpCacheLookupEntry: file info mismatch (%lx)\n", Status);
576  /* Could not read file info, or it did not match, drop it from the cache */
578  }
579  }
580 
581 Cleanup:
583  return Status;
584 }
585 
586 NTSTATUS
589 {
592 
597  return Status;
598 }
599 
600 /* Validate that we are either called from r0, or from a service-like context */
601 NTSTATUS
603 {
604  if (ExGetPreviousMode() != KernelMode)
605  {
607  {
608  DPRINT1("SHIMS: ApphelpCacheAccessCheck failed\n");
609  return STATUS_ACCESS_DENIED;
610  }
611  }
612  return STATUS_SUCCESS;
613 }
614 
615 NTSTATUS
618  _In_ HANDLE ImageHandle)
619 {
623  PVOID NodeOrParent;
624  TABLE_SEARCH_RESULT SearchResult;
625 
627 
628  /* If we got a file handle, query it for info */
629  if (ImageHandle != INVALID_HANDLE_VALUE)
630  {
631  Status = ApphelpCacheQueryInfo(ImageHandle, &Entry);
632  if (!NT_SUCCESS(Status))
633  {
634  goto Cleanup;
635  }
636  }
637 
638  /* Use ImageName for the lookup, don't actually duplicate it */
639  Entry.Persistent.ImageName = *ImageName;
641  &Entry,
642  &NodeOrParent, &SearchResult);
643  if (Lookup)
644  {
645  DPRINT("SHIMS: ApphelpCacheUpdateEntry: Entry already exists, reusing it\n");
646  /* Unlink the found item, so we can put it back at the front,
647  and copy the earlier obtained file info*/
648  RemoveEntryList(&Lookup->List);
649  Lookup->Persistent.DateTime = Entry.Persistent.DateTime;
650  Lookup->Persistent.FileSize = Entry.Persistent.FileSize;
651  }
652  else
653  {
654  DPRINT("SHIMS: ApphelpCacheUpdateEntry: Inserting new Entry\n");
655  /* Insert a new entry, with its own copy of the ImageName */
656  ApphelpDuplicateUnicodeString(&Entry.Persistent.ImageName, ImageName);
658  &Entry,
659  sizeof(Entry),
660  0,
661  NodeOrParent,
662  SearchResult);
663  if (!Lookup)
664  {
665  ApphelpFreeUnicodeString(&Entry.Persistent.ImageName);
667  }
668  }
669  if (Lookup)
670  {
671  /* Either we re-used an existing item, or we inserted a new one, keep it alive */
674  {
676  DPRINT1("SHIMS: ApphelpCacheUpdateEntry: Cache growing too big, dropping oldest item\n");
679  }
680  }
681 
682 Cleanup:
684  return Status;
685 }
686 
687 NTSTATUS
689 {
690  PVOID p;
691 
692  DPRINT1("SHIMS: ApphelpCacheFlush\n");
695  {
697  }
699  return STATUS_SUCCESS;
700 }
701 
702 NTSTATUS
704 {
705  PLIST_ENTRY ListEntry;
707 
708  DPRINT1("SHIMS: NtApphelpCacheControl( Dumping entries, newest to oldest )\n");
710  ListEntry = ApphelpShimCacheAge.Flink;
711  while (ListEntry != &ApphelpShimCacheAge)
712  {
714  DPRINT1("Entry: %wZ\n", &Entry->Persistent.ImageName);
715  DPRINT1("DateTime: 0x%I64x\n", Entry->Persistent.DateTime.QuadPart);
716  DPRINT1("FileSize: 0x%I64x\n", Entry->Persistent.FileSize.QuadPart);
717  DPRINT1("Flags: 0x%x\n", Entry->CompatFlags);
718  ListEntry = ListEntry->Flink;
719  }
721  return STATUS_SUCCESS;
722 }
723 
724 /* PUBLIC FUNCTIONS **********************************************************/
725 
726 NTSTATUS
727 NTAPI
731 {
733  UNICODE_STRING ImageName = { 0 };
735 
736  if (!ApphelpCacheEnabled)
737  {
738  DPRINT1("NtApphelpCacheControl: ApphelpCacheEnabled == 0\n");
739  return Status;
740  }
741  switch (Service)
742  {
744  DPRINT("SHIMS: NtApphelpCacheControl( ApphelpCacheServiceLookup )\n");
745  Status = ApphelpValidateData(ServiceData, &ImageName, &Handle);
746  if (NT_SUCCESS(Status))
748  break;
750  DPRINT("SHIMS: NtApphelpCacheControl( ApphelpCacheServiceRemove )\n");
751  Status = ApphelpValidateData(ServiceData, &ImageName, &Handle);
752  if (NT_SUCCESS(Status))
754  break;
756  DPRINT("SHIMS: NtApphelpCacheControl( ApphelpCacheServiceUpdate )\n");
758  if (NT_SUCCESS(Status))
759  {
760  Status = ApphelpValidateData(ServiceData, &ImageName, &Handle);
761  if (NT_SUCCESS(Status))
763  }
764  break;
766  /* FIXME: Check for admin or system here. */
768  break;
771  break;
773  DPRINT1("SHIMS: NtApphelpCacheControl( ApphelpDBGReadRegistry ): flushing cache.\n");
775  DPRINT1("SHIMS: NtApphelpCacheControl( ApphelpDBGReadRegistry ): reading cache.\n");
777  break;
779  DPRINT1("SHIMS: NtApphelpCacheControl( ApphelpDBGWriteRegistry ): writing cache.\n");
781  break;
782  default:
783  DPRINT1("SHIMS: NtApphelpCacheControl( Invalid service requested )\n");
784  break;
785  }
786  if (ImageName.Buffer)
787  {
789  }
790  return Status;
791 }
792 
_SEH2_TRY
Definition: create.c:4226
VOID ApphelpCacheReleaseLock(VOID)
Definition: apphelp.c:134
NTSTATUS ApphelpCacheParse(_In_reads_(DataLength) PUCHAR Data, _In_ ULONG DataLength)
Definition: apphelp.c:251
LARGE_INTEGER DateTime
Definition: apphelp.c:59
PVOID NTAPI ApphelpShimCacheAllocateRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ CLONG ByteSize)
Definition: apphelp.c:234
ASMGENDATA Table[]
Definition: genincdata.c:61
#define SHIM_PERSISTENT_CACHE_HEADER
Definition: apphelp.c:82
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define _In_opt_
Definition: ms_sal.h:309
NTSTATUS ApphelpCacheDump(VOID)
Definition: apphelp.c:703
#define _Inout_
Definition: ms_sal.h:378
struct _Entry Entry
Definition: kefuncs.h:629
#define KEY_SET_VALUE
Definition: nt_native.h:1017
#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
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define _Out_
Definition: ms_sal.h:345
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
static UNICODE_STRING AppCompatCacheValue
Definition: apphelp.c:38
#define INVALID_HANDLE_VALUE
Definition: apphelp.c:44
#define REG_BINARY
Definition: nt_native.h:1496
#define TRUE
Definition: types.h:120
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:56
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
static RTL_AVL_TABLE ApphelpShimCache
Definition: apphelp.c:31
NTSYSAPI BOOLEAN NTAPI RtlDeleteElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
#define EMPTY_SHIM_ENTRY
Definition: apphelp.c:40
unsigned char * PUCHAR
Definition: retypes.h:3
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG _In_opt_ PVOID Data
Definition: wdfdevice.h:4527
enum _TABLE_SEARCH_RESULT TABLE_SEARCH_RESULT
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS ApphelpCacheUpdateEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
Definition: apphelp.c:616
NTSYSAPI PVOID NTAPI RtlLookupElementGenericTableFullAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer, _Out_ PVOID *NodeOrParent, _Out_ TABLE_SEARCH_RESULT *SearchResult)
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
NTSYSAPI PVOID NTAPI RtlInsertElementGenericTableFullAvl(_In_ PRTL_AVL_TABLE Table, _In_reads_bytes_(BufferSize) PVOID Buffer, _In_ CLONG BufferSize, _Out_opt_ PBOOLEAN NewElement, _In_ PVOID NodeOrParent, _In_ TABLE_SEARCH_RESULT SearchResult)
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3062
uint16_t * PWCHAR
Definition: typedefs.h:56
_SEH2_END
Definition: create.c:4400
#define InsertTailList(ListHead, Entry)
NTSTATUS ApphelpCacheQueryInfo(_In_ HANDLE ImageHandle, _Out_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:175
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define TAG_SHIM
Definition: tag.h:138
BOOLEAN ApphelpCacheRead(VOID)
Definition: apphelp.c:306
C_ASSERT(sizeof(SHIM_PERSISTENT_CACHE_ENTRY)==SHIM_PERSISTENT_CACHE_ENTRY_SIZE)
uint32_t ULONG_PTR
Definition: typedefs.h:65
VOID ApphelpFreeUnicodeString(_Inout_ PUNICODE_STRING String)
Definition: apphelp.c:161
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
static void Lookup(RTF_Info *, char *)
Definition: reader.c:2228
ULONG CLONG
Definition: umtypes.h:126
struct SHIM_PERSISTENT_CACHE_HEADER_52 SHIM_PERSISTENT_CACHE_HEADER_52
#define L(x)
Definition: ntvdm.h:50
Definition: apphelp.c:56
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define FALSE
Definition: types.h:117
#define UNICODE_NULL
#define SHIM_CACHE_HEADER_SIZE
Definition: apphelp.c:76
Definition: Header.h:8
long LONG
Definition: pedump.c:60
struct SHIM_PERSISTENT_CACHE_ENTRY_52 * PSHIM_PERSISTENT_CACHE_ENTRY_52
struct SHIM_CACHE_ENTRY * PSHIM_CACHE_ENTRY
NTSYSAPI PVOID NTAPI RtlInsertElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_reads_bytes_(BufferSize) PVOID Buffer, _In_ CLONG BufferSize, _Out_opt_ PBOOLEAN NewElement)
SHIM_PERSISTENT_CACHE_ENTRY Persistent
Definition: apphelp.c:94
unsigned char BOOLEAN
BOOLEAN ApphelpCacheWrite(VOID)
Definition: apphelp.c:362
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:426
#define _In_
Definition: ms_sal.h:308
#define PSHIM_PERSISTENT_CACHE_HEADER
Definition: apphelp.c:83
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1437
Definition: bufpool.h:45
#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE
Definition: apphelp.c:80
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
ULONG CompatFlags
Definition: apphelp.c:95
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define STATUS_NOT_FOUND
Definition: shellext.h:72
ULONG InitSafeBootMode
Definition: init.c:71
NTSTATUS ApphelpCacheAccessCheck(VOID)
Definition: apphelp.c:602
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
Definition: rtltypes.h:383
static BOOLEAN ApphelpCacheEnabled
Definition: apphelp.c:29
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlEnumerateGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ BOOLEAN Restart)
struct SHIM_PERSISTENT_CACHE_HEADER_52 * PSHIM_PERSISTENT_CACHE_HEADER_52
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
uint64_t ULONGLONG
Definition: typedefs.h:67
VOID NTAPI ApphelpShimCacheFreeRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID Buffer)
Definition: apphelp.c:243
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElementsAvl(_In_ PRTL_AVL_TABLE Table)
NTSTATUS NTAPI NtApphelpCacheControl(_In_ APPHELPCACHESERVICECLASS Service, _In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData)
Definition: apphelp.c:728
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2991
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
static LIST_ENTRY ApphelpShimCacheAge
Definition: apphelp.c:32
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
WCHAR * PWCH
Definition: ntbasedef.h:410
Definition: apphelp.c:91
#define MAX_SHIM_ENTRIES
Definition: apphelp.c:41
static const char * ImageName
Definition: image.c:34
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define PSHIM_PERSISTENT_CACHE_ENTRY
Definition: apphelp.c:85
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:454
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
_IRQL_requires_same_ _In_ PVOID FirstStruct
Definition: rtltypes.h:383
VOID NTAPI RtlInitializeGenericTableAvl(IN OUT PRTL_AVL_TABLE Table, IN PRTL_AVL_COMPARE_ROUTINE CompareRoutine, IN PRTL_AVL_ALLOCATE_ROUTINE AllocateRoutine, IN PRTL_AVL_FREE_ROUTINE FreeRoutine, IN PVOID TableContext)
Definition: avltable.c:26
VOID NTAPI ApphelpCacheShutdown(VOID)
Definition: apphelp.c:465
Definition: typedefs.h:119
static const WCHAR Cleanup[]
Definition: register.c:80
LARGE_INTEGER FileSize
Definition: apphelp.c:60
LIST_ENTRY List
Definition: apphelp.c:93
RTL_GENERIC_COMPARE_RESULTS NTAPI ApphelpShimCacheCompareRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct)
Definition: apphelp.c:209
#define _In_reads_(size)
Definition: ms_sal.h:319
static PWSTR SIZE_T Length
Definition: apphelp.c:93
static UNICODE_STRING AppCompatCacheKey
Definition: apphelp.c:36
VOID ApphelpCacheAcquireLock(VOID)
Definition: apphelp.c:115
const LUID SeTcbPrivilege
Definition: priv.c:26
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
#define SHIM_PERSISTENT_CACHE_ENTRY
Definition: apphelp.c:84
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
unsigned short USHORT
Definition: pedump.c:61
VOID ApphelpDuplicateUnicodeString(_Out_ PUNICODE_STRING Destination, _In_ PCUNICODE_STRING Source)
Definition: apphelp.c:141
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
BOOLEAN NTAPI ExTryToAcquireResourceExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:2129
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSTATUS ApphelpValidateData(_In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData, _Out_ PUNICODE_STRING ImageName, _Out_ PHANDLE ImageHandle)
Definition: apphelp.c:474
enum _APPHELPCACHESERVICECLASS APPHELPCACHESERVICECLASS
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define NULL
Definition: types.h:112
enum _RTL_GENERIC_COMPARE_RESULTS RTL_GENERIC_COMPARE_RESULTS
#define DPRINT1
Definition: precomp.h:8
#define FileStandardInformation
Definition: propsheet.cpp:61
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
Definition: priv.c:744
PVOID ApphelpAlloc(_In_ ULONG ByteSize)
Definition: apphelp.c:101
_In_ HANDLE Handle
Definition: extypes.h:390
NTSTATUS ApphelpCacheRemoveEntryNolock(_In_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:514
ULONG ERESOURCE
Definition: env_spec_w32.h:594
unsigned int ULONG
Definition: retypes.h:1
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
UNICODE_STRING ImageName
Definition: apphelp.c:58
static ERESOURCE ApphelpCacheLock
Definition: apphelp.c:30
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define SHIM_CACHE_MAGIC
Definition: apphelp.c:75
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167
VOID ApphelpFree(_In_ PVOID Data)
Definition: apphelp.c:108
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
static OBJECT_ATTRIBUTES AppCompatKeyAttributes
Definition: apphelp.c:37
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
GLfloat GLfloat p
Definition: glext.h:8902
#define DPRINT
Definition: sndvol32.h:71
BOOLEAN ApphelpCacheTryAcquireLock(VOID)
Definition: apphelp.c:122
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:393
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
static CODE_SEG("PAGE")
Definition: isapnp.c:1482
#define CACHE_HEADER_SIZE_NT_52
Definition: apphelp.c:66
struct SHIM_CACHE_ENTRY SHIM_CACHE_ENTRY
base of all file and directory entries
Definition: entries.h:82
NTSTATUS ApphelpCacheRemoveEntry(_In_ PUNICODE_STRING ImageName)
Definition: apphelp.c:587
NTSTATUS NTAPI ApphelpCacheInitialize(VOID)
Definition: apphelp.c:439
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
NTSTATUS ApphelpCacheFlush(VOID)
Definition: apphelp.c:688
struct SHIM_PERSISTENT_CACHE_ENTRY_52 SHIM_PERSISTENT_CACHE_ENTRY_52
NTSTATUS ApphelpCacheLookupEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
Definition: apphelp.c:531