ReactOS  0.4.13-dev-100-gc8611ae
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 #define TAG_SHIM 'MIHS'
43 
44 #ifndef INVALID_HANDLE_VALUE
45 #define INVALID_HANDLE_VALUE (HANDLE)(-1)
46 #endif
47 
48 #include <pshpack1.h>
49 
51 {
55 
56 /* The data that is present in the registry (Win2k3 version) */
58 {
63 
64 #include <poppack.h>
65 
66 #define CACHE_MAGIC_NT_52 0xbadc0ffe
67 #define CACHE_HEADER_SIZE_NT_52 0x8
68 #define NT52_PERSISTENT_ENTRY_SIZE32 0x18
69 #define NT52_PERSISTENT_ENTRY_SIZE64 0x20
70 
71 //#define CACHE_MAGIC_NT_61 0xbadc0fee
72 //#define CACHE_HEADER_SIZE_NT_61 0x80
73 //#define NT61_PERSISTENT_ENTRY_SIZE32 0x20
74 //#define NT61_PERSISTENT_ENTRY_SIZE64 0x30
75 
76 #define SHIM_CACHE_MAGIC CACHE_MAGIC_NT_52
77 #define SHIM_CACHE_HEADER_SIZE CACHE_HEADER_SIZE_NT_52
78 #ifdef _WIN64
79 #define SHIM_PERSISTENT_CACHE_ENTRY_SIZE NT52_PERSISTENT_ENTRY_SIZE64
80 #else
81 #define SHIM_PERSISTENT_CACHE_ENTRY_SIZE NT52_PERSISTENT_ENTRY_SIZE32
82 #endif
83 #define SHIM_PERSISTENT_CACHE_HEADER SHIM_PERSISTENT_CACHE_HEADER_52
84 #define PSHIM_PERSISTENT_CACHE_HEADER PSHIM_PERSISTENT_CACHE_HEADER_52
85 #define SHIM_PERSISTENT_CACHE_ENTRY SHIM_PERSISTENT_CACHE_ENTRY_52
86 #define PSHIM_PERSISTENT_CACHE_ENTRY PSHIM_PERSISTENT_CACHE_ENTRY_52
87 
90 
91 /* The struct we keep in memory */
92 typedef struct SHIM_CACHE_ENTRY
93 {
98 
99 /* PRIVATE FUNCTIONS *********************************************************/
100 
101 PVOID
104 {
106 }
107 
108 VOID
110  _In_ PVOID Data)
111 {
113 }
114 
115 VOID
117 {
120 }
121 
122 BOOLEAN
124 {
127  {
129  return FALSE;
130  }
131  return TRUE;
132 }
133 
134 VOID
136 {
139 }
140 
141 VOID
145 {
146  Destination->Length = Source->Length;
147  if (Destination->Length)
148  {
153  }
154  else
155  {
158  }
159 }
160 
161 VOID
164 {
165  if (String->Buffer)
166  {
167  ApphelpFree(String->Buffer);
168  }
169  String->Length = 0;
170  String->MaximumLength = 0;
171  String->Buffer = NULL;
172 }
173 
174 /* Query file info from a handle, storing it in Entry */
175 NTSTATUS
177  _In_ HANDLE ImageHandle,
179 {
181  FILE_BASIC_INFORMATION FileBasic;
182  FILE_STANDARD_INFORMATION FileStandard;
184 
185  Status = ZwQueryInformationFile(ImageHandle,
186  &IoStatusBlock,
187  &FileBasic,
188  sizeof(FileBasic),
190  if (!NT_SUCCESS(Status))
191  {
192  return Status;
193  }
194 
195  Status = ZwQueryInformationFile(ImageHandle,
196  &IoStatusBlock,
197  &FileStandard,
198  sizeof(FileStandard),
200  if (NT_SUCCESS(Status))
201  {
202  Entry->Persistent.DateTime = FileBasic.LastWriteTime;
203  Entry->Persistent.FileSize = FileStandard.EndOfFile;
204  }
205  return Status;
206 }
207 
209 NTAPI
211  _In_ struct _RTL_AVL_TABLE *Table,
214 {
215  PSHIM_CACHE_ENTRY FirstEntry = FirstStruct;
216  PSHIM_CACHE_ENTRY SecondEntry = SecondStruct;
217  LONG Result;
218 
219  Result = RtlCompareUnicodeString(&FirstEntry->Persistent.ImageName,
220  &SecondEntry->Persistent.ImageName,
221  TRUE);
222  if (Result < 0)
223  {
224  return GenericLessThan;
225  }
226  else if (Result == 0)
227  {
228  return GenericEqual;
229  }
230  return GenericGreaterThan;
231 }
232 
233 PVOID
234 NTAPI
236  _In_ struct _RTL_AVL_TABLE *Table,
238 {
239  return ApphelpAlloc(ByteSize);
240 }
241 
242 VOID
243 NTAPI
245  _In_ struct _RTL_AVL_TABLE *Table,
246  _In_ PVOID Buffer)
247 {
249 }
250 
251 NTSTATUS
255 {
257  ULONG Cur;
258  ULONG NumEntries;
262  PSHIM_PERSISTENT_CACHE_ENTRY Persistent;
263 
265  {
266  DPRINT1("SHIMS: ApphelpCacheParse not enough data for a minimal header (0x%x)\n", DataLength);
268  }
269 
270  if (Header->Magic != SHIM_CACHE_MAGIC)
271  {
272  DPRINT1("SHIMS: ApphelpCacheParse found invalid magic (0x%x)\n", Header->Magic);
274  }
275 
276  NumEntries = Header->NumEntries;
277  DPRINT("SHIMS: ApphelpCacheParse walking %d entries\n", NumEntries);
278  for (Cur = 0; Cur < NumEntries; ++Cur)
279  {
282  /* The entry in the Persistent storage is not really a UNICODE_STRING,
283  so we have to convert the offset into a real pointer before using it. */
284  String.Length = Persistent->ImageName.Length;
285  String.MaximumLength = Persistent->ImageName.MaximumLength;
286  String.Buffer = (PWCHAR)((ULONG_PTR)Persistent->ImageName.Buffer + Data);
287 
288  /* Now we copy all data to a local buffer, that can be safely duplicated by RtlInsert */
289  Entry.Persistent = *Persistent;
290  ApphelpDuplicateUnicodeString(&Entry.Persistent.ImageName, &String);
292  &Entry,
293  sizeof(Entry),
294  NULL);
295  if (!Result)
296  {
297  DPRINT1("SHIMS: ApphelpCacheParse insert failed\n");
298  ApphelpFreeUnicodeString(&Entry.Persistent.ImageName);
300  }
302  }
303  return STATUS_SUCCESS;
304 }
305 
306 BOOLEAN
308 {
311  KEY_VALUE_PARTIAL_INFORMATION KeyValueObject;
312  PKEY_VALUE_PARTIAL_INFORMATION KeyValueInformation = &KeyValueObject;
313  ULONG KeyInfoSize, ResultSize;
314 
316  if (!NT_SUCCESS(Status))
317  {
318  DPRINT1("SHIMS: ApphelpCacheRead could not even open Session Manager\\AppCompatCache (0x%x)\n", Status);
319  return FALSE;
320  }
321 
322  Status = ZwQueryValueKey(KeyHandle,
325  KeyValueInformation,
326  sizeof(KeyValueObject),
327  &ResultSize);
329  {
330  KeyInfoSize = sizeof(KEY_VALUE_PARTIAL_INFORMATION) + KeyValueInformation->DataLength;
331  KeyValueInformation = ApphelpAlloc(KeyInfoSize);
332  if (KeyValueInformation != NULL)
333  {
334  Status = ZwQueryValueKey(KeyHandle,
337  KeyValueInformation,
338  KeyInfoSize,
339  &ResultSize);
340  }
341  }
342 
343  if (NT_SUCCESS(Status) && KeyValueInformation->Type == REG_BINARY)
344  {
345  Status = ApphelpCacheParse(KeyValueInformation->Data,
346  KeyValueInformation->DataLength);
347  }
348  else
349  {
350  DPRINT1("SHIMS: ApphelpCacheRead not loaded from registry (0x%x)\n", Status);
351  }
352 
353  if (KeyValueInformation != &KeyValueObject && KeyValueInformation != NULL)
354  {
355  ApphelpFree(KeyValueInformation);
356  }
357 
359  return NT_SUCCESS(Status);
360 }
361 
362 BOOLEAN
364 {
366  ULONG NumEntries = 0;
367  PLIST_ENTRY ListEntry;
368  PUCHAR Buffer, BufferNamePos;
370  PSHIM_PERSISTENT_CACHE_ENTRY WriteEntry;
373 
374  /* First we have to calculate the required size. */
376  ListEntry = ApphelpShimCacheAge.Flink;
377  while (ListEntry != &ApphelpShimCacheAge)
378  {
381  Length += Entry->Persistent.ImageName.MaximumLength;
382  ++NumEntries;
383  ListEntry = ListEntry->Flink;
384  }
385  DPRINT("SHIMS: ApphelpCacheWrite, %d Entries, total size: %d\n", NumEntries, Length);
386  Length = ROUND_UP(Length, sizeof(ULONGLONG));
387  DPRINT("SHIMS: ApphelpCacheWrite, Rounded to: %d\n", Length);
388 
389  /* Now we allocate and prepare some helpers */
391  BufferNamePos = Buffer + Length;
394 
395  Header->Magic = SHIM_CACHE_MAGIC;
396  Header->NumEntries = NumEntries;
397 
398  ListEntry = ApphelpShimCacheAge.Flink;
399  while (ListEntry != &ApphelpShimCacheAge)
400  {
402  USHORT ImageNameLen = Entry->Persistent.ImageName.MaximumLength;
403  /* Copy the Persistent structure over */
404  *WriteEntry = Entry->Persistent;
405  BufferNamePos -= ImageNameLen;
406  /* Copy the image name over */
407  RtlCopyMemory(BufferNamePos, Entry->Persistent.ImageName.Buffer, ImageNameLen);
408  /* Fix the Persistent structure, so that Buffer is once again an offset */
409  WriteEntry->ImageName.Buffer = (PWCH)(BufferNamePos - Buffer);
410 
411  ++WriteEntry;
412  ListEntry = ListEntry->Flink;
413  }
415 
417  if (NT_SUCCESS(Status))
418  {
419  Status = ZwSetValueKey(KeyHandle,
421  0,
422  REG_BINARY,
423  Buffer,
424  Length);
426  }
427  else
428  {
429  DPRINT1("SHIMS: ApphelpCacheWrite could not even open Session Manager\\AppCompatCache (0x%x)\n", Status);
430  }
431 
433  return NT_SUCCESS(Status);
434 }
435 
436 
437 INIT_FUNCTION
438 NTSTATUS
439 NTAPI
441 {
442  DPRINT("SHIMS: ApphelpCacheInitialize\n");
443  /* If we are booting in safemode we do not want to use the apphelp cache */
444  if (InitSafeBootMode)
445  {
446  DPRINT1("SHIMS: Safe mode detected, disabling cache.\n");
448  }
449  else
450  {
456  NULL);
459  }
460  DPRINT("SHIMS: ApphelpCacheInitialize: %d\n", ApphelpCacheEnabled);
461  return STATUS_SUCCESS;
462 }
463 
464 VOID
465 NTAPI
467 {
469  {
471  }
472 }
473 
474 NTSTATUS
478  _Out_ PHANDLE ImageHandle)
479 {
481 
482  if (ServiceData)
483  {
484  UNICODE_STRING LocalImageName;
485  _SEH2_TRY
486  {
487  ProbeForRead(ServiceData,
489  sizeof(ULONG));
490  LocalImageName = ServiceData->ImageName;
491  *ImageHandle = ServiceData->ImageHandle;
492  if (LocalImageName.Length && LocalImageName.Buffer)
493  {
494  ProbeForRead(LocalImageName.Buffer,
495  LocalImageName.Length * sizeof(WCHAR),
496  1);
497  ApphelpDuplicateUnicodeString(ImageName, &LocalImageName);
499  }
500  }
502  {
504  }
505  _SEH2_END;
506  }
507  if (!NT_SUCCESS(Status))
508  {
509  DPRINT1("SHIMS: ApphelpValidateData: invalid data passed\n");
510  }
511  return Status;
512 }
513 
514 NTSTATUS
517 {
518  if (Entry)
519  {
520  PWSTR Buffer = Entry->Persistent.ImageName.Buffer;
521  RemoveEntryList(&Entry->List);
523  {
525  }
526  return STATUS_SUCCESS;
527  }
528  return STATUS_NOT_FOUND;
529 }
530 
531 NTSTATUS
534  _In_ HANDLE ImageHandle)
535 {
539 
541  {
542  return Status;
543  }
544 
545  Lookup.Persistent.ImageName = *ImageName;
547  if (Entry == NULL)
548  {
549  DPRINT("SHIMS: ApphelpCacheLookupEntry: could not find %wZ\n", ImageName);
550  goto Cleanup;
551  }
552 
553  DPRINT("SHIMS: ApphelpCacheLookupEntry: found %wZ\n", ImageName);
554  if (ImageHandle == INVALID_HANDLE_VALUE)
555  {
556  DPRINT("SHIMS: ApphelpCacheLookupEntry: ok\n");
557  /* just return if we know it, do not query file info */
559  }
560  else
561  {
562  Status = ApphelpCacheQueryInfo(ImageHandle, &Lookup);
563  if (NT_SUCCESS(Status) &&
564  Lookup.Persistent.DateTime.QuadPart == Entry->Persistent.DateTime.QuadPart &&
565  Lookup.Persistent.FileSize.QuadPart == Entry->Persistent.FileSize.QuadPart)
566  {
567  DPRINT("SHIMS: ApphelpCacheLookupEntry: found & validated\n");
569  /* move it to the front to keep it alive */
570  RemoveEntryList(&Entry->List);
572  }
573  else
574  {
575  DPRINT1("SHIMS: ApphelpCacheLookupEntry: file info mismatch (%lx)\n", Status);
577  /* Could not read file info, or it did not match, drop it from the cache */
579  }
580  }
581 
582 Cleanup:
584  return Status;
585 }
586 
587 NTSTATUS
590 {
593 
598  return Status;
599 }
600 
601 /* Validate that we are either called from r0, or from a service-like context */
602 NTSTATUS
604 {
605  if (ExGetPreviousMode() != KernelMode)
606  {
608  {
609  DPRINT1("SHIMS: ApphelpCacheAccessCheck failed\n");
610  return STATUS_ACCESS_DENIED;
611  }
612  }
613  return STATUS_SUCCESS;
614 }
615 
616 NTSTATUS
619  _In_ HANDLE ImageHandle)
620 {
624  PVOID NodeOrParent;
625  TABLE_SEARCH_RESULT SearchResult;
626 
628 
629  /* If we got a file handle, query it for info */
630  if (ImageHandle != INVALID_HANDLE_VALUE)
631  {
632  Status = ApphelpCacheQueryInfo(ImageHandle, &Entry);
633  if (!NT_SUCCESS(Status))
634  {
635  goto Cleanup;
636  }
637  }
638 
639  /* Use ImageName for the lookup, don't actually duplicate it */
640  Entry.Persistent.ImageName = *ImageName;
642  &Entry,
643  &NodeOrParent, &SearchResult);
644  if (Lookup)
645  {
646  DPRINT("SHIMS: ApphelpCacheUpdateEntry: Entry already exists, reusing it\n");
647  /* Unlink the found item, so we can put it back at the front,
648  and copy the earlier obtained file info*/
649  RemoveEntryList(&Lookup->List);
650  Lookup->Persistent.DateTime = Entry.Persistent.DateTime;
651  Lookup->Persistent.FileSize = Entry.Persistent.FileSize;
652  }
653  else
654  {
655  DPRINT("SHIMS: ApphelpCacheUpdateEntry: Inserting new Entry\n");
656  /* Insert a new entry, with its own copy of the ImageName */
657  ApphelpDuplicateUnicodeString(&Entry.Persistent.ImageName, ImageName);
659  &Entry,
660  sizeof(Entry),
661  0,
662  NodeOrParent,
663  SearchResult);
664  if (!Lookup)
665  {
666  ApphelpFreeUnicodeString(&Entry.Persistent.ImageName);
668  }
669  }
670  if (Lookup)
671  {
672  /* Either we re-used an existing item, or we inserted a new one, keep it alive */
675  {
677  DPRINT1("SHIMS: ApphelpCacheUpdateEntry: Cache growing too big, dropping oldest item\n");
680  }
681  }
682 
683 Cleanup:
685  return Status;
686 }
687 
688 NTSTATUS
690 {
691  PVOID p;
692 
693  DPRINT1("SHIMS: ApphelpCacheFlush\n");
696  {
698  }
700  return STATUS_SUCCESS;
701 }
702 
703 NTSTATUS
705 {
706  PLIST_ENTRY ListEntry;
708 
709  DPRINT1("SHIMS: NtApphelpCacheControl( Dumping entries, newest to oldest )\n");
711  ListEntry = ApphelpShimCacheAge.Flink;
712  while (ListEntry != &ApphelpShimCacheAge)
713  {
715  DPRINT1("Entry: %wZ\n", &Entry->Persistent.ImageName);
716  DPRINT1("DateTime: 0x%I64x\n", Entry->Persistent.DateTime.QuadPart);
717  DPRINT1("FileSize: 0x%I64x\n", Entry->Persistent.FileSize.QuadPart);
718  DPRINT1("Flags: 0x%x\n", Entry->CompatFlags);
719  ListEntry = ListEntry->Flink;
720  }
722  return STATUS_SUCCESS;
723 }
724 
725 /* PUBLIC FUNCTIONS **********************************************************/
726 
727 NTSTATUS
728 NTAPI
732 {
734  UNICODE_STRING ImageName = { 0 };
736 
737  if (!ApphelpCacheEnabled)
738  {
739  DPRINT1("NtApphelpCacheControl: ApphelpCacheEnabled == 0\n");
740  return Status;
741  }
742  switch (Service)
743  {
745  DPRINT("SHIMS: NtApphelpCacheControl( ApphelpCacheServiceLookup )\n");
746  Status = ApphelpValidateData(ServiceData, &ImageName, &Handle);
747  if (NT_SUCCESS(Status))
749  break;
751  DPRINT("SHIMS: NtApphelpCacheControl( ApphelpCacheServiceRemove )\n");
752  Status = ApphelpValidateData(ServiceData, &ImageName, &Handle);
753  if (NT_SUCCESS(Status))
755  break;
757  DPRINT("SHIMS: NtApphelpCacheControl( ApphelpCacheServiceUpdate )\n");
759  if (NT_SUCCESS(Status))
760  {
761  Status = ApphelpValidateData(ServiceData, &ImageName, &Handle);
762  if (NT_SUCCESS(Status))
764  }
765  break;
767  /* FIXME: Check for admin or system here. */
769  break;
772  break;
774  DPRINT1("SHIMS: NtApphelpCacheControl( ApphelpDBGReadRegistry ): flushing cache.\n");
776  DPRINT1("SHIMS: NtApphelpCacheControl( ApphelpDBGReadRegistry ): reading cache.\n");
778  break;
780  DPRINT1("SHIMS: NtApphelpCacheControl( ApphelpDBGWriteRegistry ): writing cache.\n");
782  break;
783  default:
784  DPRINT1("SHIMS: NtApphelpCacheControl( Invalid service requested )\n");
785  break;
786  }
787  if (ImageName.Buffer)
788  {
790  }
791  return Status;
792 }
793 
VOID ApphelpCacheReleaseLock(VOID)
Definition: apphelp.c:135
NTSTATUS ApphelpCacheParse(_In_reads_(DataLength) PUCHAR Data, _In_ ULONG DataLength)
Definition: apphelp.c:252
LARGE_INTEGER DateTime
Definition: apphelp.c:60
PVOID NTAPI ApphelpShimCacheAllocateRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ CLONG ByteSize)
Definition: apphelp.c:235
INIT_FUNCTION NTSTATUS NTAPI ApphelpCacheInitialize(VOID)
Definition: apphelp.c:440
ASMGENDATA Table[]
Definition: genincdata.c:61
#define TRUE
Definition: types.h:120
NTSYSAPI VOID NTAPI RtlCopyMemory(VOID UNALIGNED *Destination, CONST VOID UNALIGNED *Source, ULONG Length)
#define SHIM_PERSISTENT_CACHE_HEADER
Definition: apphelp.c:83
#define ROUND_UP(n, align)
Definition: eventvwr.h:31
NTSTATUS ApphelpCacheDump(VOID)
Definition: apphelp.c:704
#define TAG_SHIM
Definition: apphelp.c:42
struct _Entry Entry
Definition: kefuncs.h:640
#define KEY_SET_VALUE
Definition: nt_native.h:1017
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4693
USHORT MaximumLength
Definition: env_spec_w32.h:370
static UNICODE_STRING AppCompatCacheValue
Definition: apphelp.c:38
#define INVALID_HANDLE_VALUE
Definition: apphelp.c:45
#define REG_BINARY
Definition: nt_native.h:1496
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
uint16_t * PWSTR
Definition: typedefs.h:54
struct _LIST_ENTRY * Blink
Definition: typedefs.h:120
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
#define _In_reads_(size)
Definition: no_sal2.h:228
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:617
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)
BOOLEAN NTAPI SeSinglePrivilegeCheck(IN LUID PrivilegeValue, IN KPROCESSOR_MODE PreviousMode)
Definition: priv.c:524
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:2966
static WCHAR String[]
Definition: stringtable.c:55
uint16_t * PWCHAR
Definition: typedefs.h:54
#define InsertTailList(ListHead, Entry)
NTSTATUS ApphelpCacheQueryInfo(_In_ HANDLE ImageHandle, _Out_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:176
#define _In_opt_
Definition: no_sal2.h:213
BOOLEAN ApphelpCacheRead(VOID)
Definition: apphelp.c:307
C_ASSERT(sizeof(SHIM_PERSISTENT_CACHE_ENTRY)==SHIM_PERSISTENT_CACHE_ENTRY_SIZE)
_SEH2_TRY
Definition: create.c:4250
uint32_t ULONG_PTR
Definition: typedefs.h:63
VOID ApphelpFreeUnicodeString(_Inout_ PUNICODE_STRING String)
Definition: apphelp.c:162
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
Definition: apphelp.c:57
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
#define UNICODE_NULL
#define SHIM_CACHE_HEADER_SIZE
Definition: apphelp.c:77
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)
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
SHIM_PERSISTENT_CACHE_ENTRY Persistent
Definition: apphelp.c:95
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
BOOLEAN ApphelpCacheWrite(VOID)
Definition: apphelp.c:363
_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 _Out_
Definition: no_sal2.h:323
_In_ LPGUID _In_ PVOID Data
Definition: classpnp.h:778
#define PSHIM_PERSISTENT_CACHE_HEADER
Definition: apphelp.c:84
void DPRINT(...)
Definition: polytest.cpp:61
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
Definition: bufpool.h:45
#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE
Definition: apphelp.c:81
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:96
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
_In_ HANDLE Handle
Definition: extypes.h:390
#define STATUS_NOT_FOUND
Definition: shellext.h:67
ULONG InitSafeBootMode
Definition: init.c:68
NTSTATUS ApphelpCacheAccessCheck(VOID)
Definition: apphelp.c:603
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941
#define _SEH2_YIELD(STMT_)
Definition: pseh2_64.h:8
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
Definition: rtltypes.h:379
LIST_ENTRY List
Definition: psmgr.c:57
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
uint64_t ULONGLONG
Definition: typedefs.h:65
VOID NTAPI ApphelpShimCacheFreeRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID Buffer)
Definition: apphelp.c:244
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:729
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2875
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define _Inout_
Definition: no_sal2.h:244
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817
static LIST_ENTRY ApphelpShimCacheAge
Definition: apphelp.c:32
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
WCHAR * PWCH
Definition: ntbasedef.h:417
Definition: apphelp.c:92
#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
static const WCHAR L[]
Definition: oid.c:1250
#define PSHIM_PERSISTENT_CACHE_ENTRY
Definition: apphelp.c:86
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
#define KeEnterCriticalRegion()
Definition: ke_x.h:83
_IRQL_requires_same_ _In_ PVOID FirstStruct
Definition: rtltypes.h:379
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:466
Definition: typedefs.h:117
static const WCHAR Cleanup[]
Definition: register.c:80
LARGE_INTEGER FileSize
Definition: apphelp.c:61
LIST_ENTRY List
Definition: apphelp.c:94
RTL_GENERIC_COMPARE_RESULTS NTAPI ApphelpShimCacheCompareRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct)
Definition: apphelp.c:210
static PWSTR SIZE_T Length
Definition: apphelp.c:91
static UNICODE_STRING AppCompatCacheKey
Definition: apphelp.c:36
VOID ApphelpCacheAcquireLock(VOID)
Definition: apphelp.c:116
Status
Definition: gdiplustypes.h:24
const LUID SeTcbPrivilege
Definition: priv.c:28
#define _In_
Definition: no_sal2.h:204
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
_SEH2_END
Definition: create.c:4424
#define SHIM_PERSISTENT_CACHE_ENTRY
Definition: apphelp.c:85
#define KeLeaveCriticalRegion()
Definition: ke_x.h:114
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
unsigned short USHORT
Definition: pedump.c:61
VOID ApphelpDuplicateUnicodeString(_Out_ PUNICODE_STRING Destination, _In_ PCUNICODE_STRING Source)
Definition: apphelp.c:142
#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:246
NTSTATUS ApphelpValidateData(_In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData, _Out_ PUNICODE_STRING ImageName, _Out_ PHANDLE ImageHandle)
Definition: apphelp.c:475
enum _APPHELPCACHESERVICECLASS APPHELPCACHESERVICECLASS
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
enum _RTL_GENERIC_COMPARE_RESULTS RTL_GENERIC_COMPARE_RESULTS
#define DPRINT1
Definition: precomp.h:8
#define FileStandardInformation
Definition: propsheet.cpp:61
PVOID ApphelpAlloc(_In_ ULONG ByteSize)
Definition: apphelp.c:102
NTSTATUS ApphelpCacheRemoveEntryNolock(_In_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:515
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:59
static ERESOURCE ApphelpCacheLock
Definition: apphelp.c:30
#define SHIM_CACHE_MAGIC
Definition: apphelp.c:76
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3149
VOID ApphelpFree(_In_ PVOID Data)
Definition: apphelp.c:109
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:6
static OBJECT_ATTRIBUTES AppCompatKeyAttributes
Definition: apphelp.c:37
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:12
GLfloat GLfloat p
Definition: glext.h:8902
BOOLEAN ApphelpCacheTryAcquireLock(VOID)
Definition: apphelp.c:123
_Must_inspect_result_ _Out_writes_to_ DataLength PHIDP_DATA _Inout_ PULONG DataLength
Definition: hidpi.h:333
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
return STATUS_SUCCESS
Definition: btrfs.c:2725
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:389
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define CACHE_HEADER_SIZE_NT_52
Definition: apphelp.c:67
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:588
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
NTSTATUS ApphelpCacheFlush(VOID)
Definition: apphelp.c:689
struct SHIM_PERSISTENT_CACHE_ENTRY_52 SHIM_PERSISTENT_CACHE_ENTRY_52
NTSTATUS ApphelpCacheLookupEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
Definition: apphelp.c:532