ReactOS 0.4.16-dev-336-gb667d82
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/*
11Useful references:
12https://github.com/mandiant/ShimCacheParser/blob/master/ShimCacheParser.py
13http://technet.microsoft.com/en-us/library/dd837644(v=ws.10).aspx
14http://msdn.microsoft.com/en-us/library/bb432182(v=vs.85).aspx
15http://www.alex-ionescu.com/?p=43
16http://recxltd.blogspot.nl/2012/04/windows-appcompat-research-notes-part-1.html
17http://journeyintoir.blogspot.ch/2013/12/revealing-recentfilecachebcf-file.html
18https://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
35
36static 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 */
91typedef struct SHIM_CACHE_ENTRY
92{
97
98/* PRIVATE FUNCTIONS *********************************************************/
99
100PVOID
103{
105}
106
107VOID
110{
112}
113
114VOID
116{
119}
120
123{
126 {
128 return FALSE;
129 }
130 return TRUE;
131}
132
133VOID
135{
138}
139
140VOID
144{
145 Destination->Length = Source->Length;
146 if (Destination->Length)
147 {
152 }
153 else
154 {
157 }
158}
159
160VOID
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 */
176 _In_ HANDLE ImageHandle,
178{
180 FILE_BASIC_INFORMATION FileBasic;
181 FILE_STANDARD_INFORMATION FileStandard;
183
184 Status = ZwQueryInformationFile(ImageHandle,
186 &FileBasic,
187 sizeof(FileBasic),
189 if (!NT_SUCCESS(Status))
190 {
191 return Status;
192 }
193
194 Status = ZwQueryInformationFile(ImageHandle,
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
208NTAPI
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
232PVOID
233NTAPI
235 _In_ struct _RTL_AVL_TABLE *Table,
237{
238 return ApphelpAlloc(ByteSize);
239}
240
241VOID
242NTAPI
244 _In_ struct _RTL_AVL_TABLE *Table,
246{
248}
249
254{
256 ULONG Cur;
257 ULONG NumEntries;
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
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
363{
365 ULONG NumEntries = 0;
366 PLIST_ENTRY ListEntry;
367 PUCHAR Buffer, BufferNamePos;
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,
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
436CODE_SEG("INIT")
438NTAPI
440{
441 DPRINT("SHIMS: ApphelpCacheInitialize\n");
442 /* If we are booting in safemode we do not want to use the apphelp cache */
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
463VOID
464NTAPI
466{
468 {
470 }
471}
472
477 _Out_ PHANDLE ImageHandle)
478{
480
481 if (ServiceData)
482 {
483 UNICODE_STRING LocalImageName;
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);
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
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
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
581Cleanup:
583 return Status;
584}
585
589{
592
597 return Status;
598}
599
600/* Validate that we are either called from r0, or from a service-like context */
603{
605 {
607 {
608 DPRINT1("SHIMS: ApphelpCacheAccessCheck failed\n");
610 }
611 }
612 return STATUS_SUCCESS;
613}
614
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
682Cleanup:
684 return Status;
685}
686
689{
690 PVOID p;
691
692 DPRINT1("SHIMS: ApphelpCacheFlush\n");
695 {
697 }
699 return STATUS_SUCCESS;
700}
701
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
727NTAPI
731{
735
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
#define CODE_SEG(...)
unsigned char BOOLEAN
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
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1444
Definition: bufpool.h:45
Definition: Header.h:9
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
static void Lookup(RTF_Info *, char *)
Definition: reader.c:2228
static const WCHAR Cleanup[]
Definition: register.c:80
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
ULONG ERESOURCE
Definition: env_spec_w32.h:594
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define PagedPool
Definition: env_spec_w32.h:308
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define ExGetPreviousMode
Definition: ex.h:140
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
@ FileBasicInformation
Definition: from_kernel.h:65
ULONG Handle
Definition: gdb_input.c:15
Status
Definition: gdiplustypes.h:25
ASMGENDATA Table[]
Definition: genincdata.c:61
GLfloat GLfloat p
Definition: glext.h:8902
enum _APPHELPCACHESERVICECLASS APPHELPCACHESERVICECLASS
@ ApphelpDBGReadRegistry
Definition: pstypes.h:980
@ ApphelpCacheServiceLookup
Definition: pstypes.h:974
@ ApphelpCacheServiceRemove
Definition: pstypes.h:975
@ ApphelpCacheServiceUpdate
Definition: pstypes.h:976
@ ApphelpCacheServiceDump
Definition: pstypes.h:978
@ ApphelpDBGWriteRegistry
Definition: pstypes.h:981
@ ApphelpCacheServiceFlush
Definition: pstypes.h:977
#define OBJ_KERNEL_HANDLE
Definition: winternl.h:231
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:90
#define C_ASSERT(e)
Definition: intsafe.h:73
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1109
static PWSTR SIZE_T Length
Definition: apphelp.c:93
static const char * ImageName
Definition: image.c:34
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:3016
#define _In_reads_(s)
Definition: no_sal2.h:168
#define _Inout_
Definition: no_sal2.h:162
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define _In_opt_
Definition: no_sal2.h:212
#define REG_BINARY
Definition: nt_native.h:1496
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define KEY_SET_VALUE
Definition: nt_native.h:1017
WCHAR * PWCH
Definition: ntbasedef.h:418
#define UNICODE_NULL
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
BOOLEAN NTAPI ExTryToAcquireResourceExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:2134
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1822
const LUID SeTcbPrivilege
Definition: priv.c:26
NTSTATUS ApphelpCacheDump(VOID)
Definition: apphelp.c:703
static UNICODE_STRING AppCompatCacheValue
Definition: apphelp.c:38
RTL_GENERIC_COMPARE_RESULTS NTAPI ApphelpShimCacheCompareRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct)
Definition: apphelp.c:209
PVOID ApphelpAlloc(_In_ ULONG ByteSize)
Definition: apphelp.c:101
NTSTATUS ApphelpCacheQueryInfo(_In_ HANDLE ImageHandle, _Out_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:175
struct SHIM_PERSISTENT_CACHE_HEADER_52 * PSHIM_PERSISTENT_CACHE_HEADER_52
BOOLEAN ApphelpCacheWrite(VOID)
Definition: apphelp.c:362
static BOOLEAN ApphelpCacheEnabled
Definition: apphelp.c:29
PVOID NTAPI ApphelpShimCacheAllocateRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ CLONG ByteSize)
Definition: apphelp.c:234
static OBJECT_ATTRIBUTES AppCompatKeyAttributes
Definition: apphelp.c:37
static UNICODE_STRING AppCompatCacheKey
Definition: apphelp.c:36
VOID NTAPI ApphelpCacheShutdown(VOID)
Definition: apphelp.c:465
#define SHIM_CACHE_HEADER_SIZE
Definition: apphelp.c:76
NTSTATUS ApphelpCacheFlush(VOID)
Definition: apphelp.c:688
VOID ApphelpDuplicateUnicodeString(_Out_ PUNICODE_STRING Destination, _In_ PCUNICODE_STRING Source)
Definition: apphelp.c:141
struct SHIM_CACHE_ENTRY * PSHIM_CACHE_ENTRY
#define SHIM_PERSISTENT_CACHE_HEADER
Definition: apphelp.c:82
#define SHIM_PERSISTENT_CACHE_ENTRY
Definition: apphelp.c:84
#define SHIM_CACHE_MAGIC
Definition: apphelp.c:75
BOOLEAN ApphelpCacheRead(VOID)
Definition: apphelp.c:306
static LIST_ENTRY ApphelpShimCacheAge
Definition: apphelp.c:32
VOID ApphelpCacheAcquireLock(VOID)
Definition: apphelp.c:115
NTSTATUS ApphelpCacheRemoveEntry(_In_ PUNICODE_STRING ImageName)
Definition: apphelp.c:587
VOID ApphelpFree(_In_ PVOID Data)
Definition: apphelp.c:108
VOID ApphelpFreeUnicodeString(_Inout_ PUNICODE_STRING String)
Definition: apphelp.c:161
#define PSHIM_PERSISTENT_CACHE_HEADER
Definition: apphelp.c:83
#define CACHE_HEADER_SIZE_NT_52
Definition: apphelp.c:66
NTSTATUS ApphelpCacheUpdateEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
Definition: apphelp.c:616
struct SHIM_PERSISTENT_CACHE_ENTRY_52 * PSHIM_PERSISTENT_CACHE_ENTRY_52
NTSTATUS NTAPI ApphelpCacheInitialize(VOID)
Definition: apphelp.c:439
NTSTATUS ApphelpValidateData(_In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData, _Out_ PUNICODE_STRING ImageName, _Out_ PHANDLE ImageHandle)
Definition: apphelp.c:474
NTSTATUS ApphelpCacheRemoveEntryNolock(_In_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:514
VOID ApphelpCacheReleaseLock(VOID)
Definition: apphelp.c:134
NTSTATUS ApphelpCacheAccessCheck(VOID)
Definition: apphelp.c:602
NTSTATUS ApphelpCacheLookupEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
Definition: apphelp.c:531
#define EMPTY_SHIM_ENTRY
Definition: apphelp.c:40
NTSTATUS ApphelpCacheParse(_In_reads_(DataLength) PUCHAR Data, _In_ ULONG DataLength)
Definition: apphelp.c:251
static RTL_AVL_TABLE ApphelpShimCache
Definition: apphelp.c:31
ULONG InitSafeBootMode
Definition: init.c:71
#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE
Definition: apphelp.c:80
#define MAX_SHIM_ENTRIES
Definition: apphelp.c:41
NTSTATUS NTAPI NtApphelpCacheControl(_In_ APPHELPCACHESERVICECLASS Service, _In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData)
Definition: apphelp.c:728
BOOLEAN ApphelpCacheTryAcquireLock(VOID)
Definition: apphelp.c:122
static ERESOURCE ApphelpCacheLock
Definition: apphelp.c:30
VOID NTAPI ApphelpShimCacheFreeRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID Buffer)
Definition: apphelp.c:243
#define PSHIM_PERSISTENT_CACHE_ENTRY
Definition: apphelp.c:85
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
@ Service
Definition: ntsecapi.h:292
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
unsigned short USHORT
Definition: pedump.c:61
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
#define _SEH2_END
Definition: pseh2_64.h:155
#define _SEH2_TRY
Definition: pseh2_64.h:55
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168
#define FileStandardInformation
Definition: propsheet.cpp:61
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define DPRINT
Definition: sndvol32.h:73
base of all file and directory entries
Definition: entries.h:83
Definition: apphelp.c:92
ULONG CompatFlags
Definition: apphelp.c:95
LIST_ENTRY List
Definition: apphelp.c:93
SHIM_PERSISTENT_CACHE_ENTRY Persistent
Definition: apphelp.c:94
Definition: apphelp.c:57
UNICODE_STRING ImageName
Definition: apphelp.c:58
LARGE_INTEGER DateTime
Definition: apphelp.c:59
LARGE_INTEGER FileSize
Definition: apphelp.c:60
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941
Definition: typedefs.h:120
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define TAG_SHIM
Definition: tag.h:138
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint16_t * PWSTR
Definition: typedefs.h:56
#define NTAPI
Definition: typedefs.h:36
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
unsigned char * PUCHAR
Definition: typedefs.h:53
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
ULONG CLONG
Definition: umtypes.h:126
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
_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:409
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
NTSYSAPI PVOID NTAPI RtlLookupElementGenericTableFullAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer, _Out_ PVOID *NodeOrParent, _Out_ TABLE_SEARCH_RESULT *SearchResult)
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)
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
NTSYSAPI BOOLEAN NTAPI RtlDeleteElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
NTSYSAPI PVOID NTAPI RtlInsertElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_reads_bytes_(BufferSize) PVOID Buffer, _In_ CLONG BufferSize, _Out_opt_ PBOOLEAN NewElement)
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlEnumerateGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ BOOLEAN Restart)
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElementsAvl(_In_ PRTL_AVL_TABLE Table)
TABLE_SEARCH_RESULT
Definition: rtltypes.h:386
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
Definition: rtltypes.h:403
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:412
_IRQL_requires_same_ _In_ PVOID FirstStruct
Definition: rtltypes.h:402
@ GenericLessThan
Definition: rtltypes.h:389
@ GenericEqual
Definition: rtltypes.h:391
@ GenericGreaterThan
Definition: rtltypes.h:390
enum _RTL_GENERIC_COMPARE_RESULTS RTL_GENERIC_COMPARE_RESULTS
__wchar_t WCHAR
Definition: xmlstorage.h:180