38#define EMPTY_SHIM_ENTRY { { 0 }, { { 0 } }, 0 }
39#define MAX_SHIM_ENTRIES 0x200
41#ifndef INVALID_HANDLE_VALUE
42#define INVALID_HANDLE_VALUE (HANDLE)(-1)
63#define CACHE_MAGIC_NT_52 0xbadc0ffe
64#define CACHE_HEADER_SIZE_NT_52 0x8
65#define NT52_PERSISTENT_ENTRY_SIZE32 0x18
66#define NT52_PERSISTENT_ENTRY_SIZE64 0x20
73#define SHIM_CACHE_MAGIC CACHE_MAGIC_NT_52
74#define SHIM_CACHE_HEADER_SIZE CACHE_HEADER_SIZE_NT_52
76#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE NT52_PERSISTENT_ENTRY_SIZE64
78#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE NT52_PERSISTENT_ENTRY_SIZE32
80#define SHIM_PERSISTENT_CACHE_HEADER SHIM_PERSISTENT_CACHE_HEADER_52
81#define PSHIM_PERSISTENT_CACHE_HEADER PSHIM_PERSISTENT_CACHE_HEADER_52
82#define SHIM_PERSISTENT_CACHE_ENTRY SHIM_PERSISTENT_CACHE_ENTRY_52
83#define PSHIM_PERSISTENT_CACHE_ENTRY PSHIM_PERSISTENT_CACHE_ENTRY_52
167 String->MaximumLength = 0;
182 Status = ZwQueryInformationFile(ImageHandle,
192 Status = ZwQueryInformationFile(ImageHandle,
195 sizeof(FileStandard),
263 DPRINT1(
"SHIMS: ApphelpCacheParse not enough data for a minimal header (0x%x)\n",
DataLength);
269 DPRINT1(
"SHIMS: ApphelpCacheParse found invalid magic (0x%x)\n",
Header->Magic);
273 NumEntries =
Header->NumEntries;
274 DPRINT(
"SHIMS: ApphelpCacheParse walking %d entries\n", NumEntries);
275 for (Cur = 0; Cur < NumEntries; ++Cur)
281 String.Length = Persistent->ImageName.Length;
282 String.MaximumLength = Persistent->ImageName.MaximumLength;
286 Entry.Persistent = *Persistent;
294 DPRINT1(
"SHIMS: ApphelpCacheParse insert failed\n");
310 ULONG KeyInfoSize, ResultSize;
315 DPRINT1(
"SHIMS: ApphelpCacheRead could not even open Session Manager\\AppCompatCache (0x%x)\n",
Status);
323 sizeof(KeyValueObject),
329 if (KeyValueInformation !=
NULL)
347 DPRINT1(
"SHIMS: ApphelpCacheRead not loaded from registry (0x%x)\n",
Status);
350 if (KeyValueInformation != &KeyValueObject && KeyValueInformation !=
NULL)
363 ULONG NumEntries = 0;
378 Length +=
Entry->Persistent.ImageName.MaximumLength;
380 ListEntry = ListEntry->
Flink;
382 DPRINT(
"SHIMS: ApphelpCacheWrite, %d Entries, total size: %d\n", NumEntries,
Length);
384 DPRINT(
"SHIMS: ApphelpCacheWrite, Rounded to: %d\n",
Length);
393 Header->NumEntries = NumEntries;
399 USHORT ImageNameLen =
Entry->Persistent.ImageName.MaximumLength;
401 *WriteEntry =
Entry->Persistent;
402 BufferNamePos -= ImageNameLen;
406 WriteEntry->ImageName.Buffer = (
PWCH)(BufferNamePos -
Buffer);
409 ListEntry = ListEntry->
Flink;
426 DPRINT1(
"SHIMS: ApphelpCacheWrite could not even open Session Manager\\AppCompatCache (0x%x)\n",
Status);
439 DPRINT(
"SHIMS: ApphelpCacheInitialize\n");
443 DPRINT1(
"SHIMS: Safe mode detected, disabling cache.\n");
487 LocalImageName = ServiceData->ImageName;
488 *ImageHandle = ServiceData->ImageHandle;
506 DPRINT1(
"SHIMS: ApphelpValidateData: invalid data passed\n");
542 Lookup.Persistent.ImageName = *ImageName;
546 DPRINT(
"SHIMS: ApphelpCacheLookupEntry: could not find %wZ\n", ImageName);
550 DPRINT(
"SHIMS: ApphelpCacheLookupEntry: found %wZ\n", ImageName);
553 DPRINT(
"SHIMS: ApphelpCacheLookupEntry: ok\n");
561 Lookup.Persistent.DateTime.QuadPart ==
Entry->Persistent.DateTime.QuadPart &&
562 Lookup.Persistent.FileSize.QuadPart ==
Entry->Persistent.FileSize.QuadPart)
564 DPRINT(
"SHIMS: ApphelpCacheLookupEntry: found & validated\n");
572 DPRINT1(
"SHIMS: ApphelpCacheLookupEntry: file info mismatch (%lx)\n",
Status);
606 DPRINT1(
"SHIMS: ApphelpCacheAccessCheck failed\n");
637 Entry.Persistent.ImageName = *ImageName;
640 &NodeOrParent, &SearchResult);
643 DPRINT(
"SHIMS: ApphelpCacheUpdateEntry: Entry already exists, reusing it\n");
647 Lookup->Persistent.DateTime =
Entry.Persistent.DateTime;
648 Lookup->Persistent.FileSize =
Entry.Persistent.FileSize;
652 DPRINT(
"SHIMS: ApphelpCacheUpdateEntry: Inserting new Entry\n");
674 DPRINT1(
"SHIMS: ApphelpCacheUpdateEntry: Cache growing too big, dropping oldest item\n");
690 DPRINT1(
"SHIMS: ApphelpCacheFlush\n");
706 DPRINT1(
"SHIMS: NtApphelpCacheControl( Dumping entries, newest to oldest )\n");
713 DPRINT1(
"DateTime: 0x%I64x\n",
Entry->Persistent.DateTime.QuadPart);
714 DPRINT1(
"FileSize: 0x%I64x\n",
Entry->Persistent.FileSize.QuadPart);
716 ListEntry = ListEntry->
Flink;
736 DPRINT1(
"NtApphelpCacheControl: ApphelpCacheEnabled == 0\n");
742 DPRINT(
"SHIMS: NtApphelpCacheControl( ApphelpCacheServiceLookup )\n");
748 DPRINT(
"SHIMS: NtApphelpCacheControl( ApphelpCacheServiceRemove )\n");
754 DPRINT(
"SHIMS: NtApphelpCacheControl( ApphelpCacheServiceUpdate )\n");
771 DPRINT1(
"SHIMS: NtApphelpCacheControl( ApphelpDBGReadRegistry ): flushing cache.\n");
773 DPRINT1(
"SHIMS: NtApphelpCacheControl( ApphelpDBGReadRegistry ): reading cache.\n");
777 DPRINT1(
"SHIMS: NtApphelpCacheControl( ApphelpDBGWriteRegistry ): writing cache.\n");
781 DPRINT1(
"SHIMS: NtApphelpCacheControl( Invalid service requested )\n");
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)
_In_ PIO_STATUS_BLOCK IoStatusBlock
_In_ D3DDDI_VIDEO_PRESENT_TARGET_ID _In_ ULONG _In_ ULONG DataLength
#define NT_SUCCESS(StatCode)
#define RTL_CONSTANT_STRING(s)
#define INVALID_HANDLE_VALUE
static void Lookup(RTF_Info *, char *)
static const WCHAR Cleanup[]
#define RemoveEntryList(Entry)
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define ExAllocatePoolWithTag(hernya, size, tag)
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
NTSTATUS ExInitializeResourceLite(PULONG res)
#define ExAcquireResourceExclusiveLite(res, wait)
#define InitializeListHead(ListHead)
#define ROUND_UP(n, align)
#define ExGetPreviousMode
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
enum _APPHELPCACHESERVICECLASS APPHELPCACHESERVICECLASS
@ ApphelpCacheServiceLookup
@ ApphelpCacheServiceRemove
@ ApphelpCacheServiceUpdate
@ ApphelpCacheServiceDump
@ ApphelpDBGWriteRegistry
@ ApphelpCacheServiceFlush
#define EXCEPTION_EXECUTE_HANDLER
#define KeLeaveCriticalRegion()
#define KeEnterCriticalRegion()
#define ExFreePoolWithTag(_P, _T)
static PWSTR SIZE_T Length
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
@ KeyValuePartialInformation
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
_In_ ULONG _In_ ULONG _In_ ULONG Length
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
BOOLEAN NTAPI ExTryToAcquireResourceExclusiveLite(IN PERESOURCE Resource)
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
const LUID SeTcbPrivilege
NTSTATUS ApphelpCacheDump(VOID)
static UNICODE_STRING AppCompatCacheValue
RTL_GENERIC_COMPARE_RESULTS NTAPI ApphelpShimCacheCompareRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct)
PVOID ApphelpAlloc(_In_ ULONG ByteSize)
NTSTATUS ApphelpCacheQueryInfo(_In_ HANDLE ImageHandle, _Out_ PSHIM_CACHE_ENTRY Entry)
struct SHIM_PERSISTENT_CACHE_HEADER_52 * PSHIM_PERSISTENT_CACHE_HEADER_52
BOOLEAN ApphelpCacheWrite(VOID)
static BOOLEAN ApphelpCacheEnabled
PVOID NTAPI ApphelpShimCacheAllocateRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ CLONG ByteSize)
static OBJECT_ATTRIBUTES AppCompatKeyAttributes
static UNICODE_STRING AppCompatCacheKey
VOID NTAPI ApphelpCacheShutdown(VOID)
#define SHIM_CACHE_HEADER_SIZE
NTSTATUS ApphelpCacheFlush(VOID)
VOID ApphelpDuplicateUnicodeString(_Out_ PUNICODE_STRING Destination, _In_ PCUNICODE_STRING Source)
struct SHIM_CACHE_ENTRY * PSHIM_CACHE_ENTRY
#define SHIM_PERSISTENT_CACHE_HEADER
#define SHIM_PERSISTENT_CACHE_ENTRY
BOOLEAN ApphelpCacheRead(VOID)
static LIST_ENTRY ApphelpShimCacheAge
VOID ApphelpCacheAcquireLock(VOID)
NTSTATUS ApphelpCacheRemoveEntry(_In_ PUNICODE_STRING ImageName)
VOID ApphelpFree(_In_ PVOID Data)
VOID ApphelpFreeUnicodeString(_Inout_ PUNICODE_STRING String)
#define PSHIM_PERSISTENT_CACHE_HEADER
#define CACHE_HEADER_SIZE_NT_52
NTSTATUS ApphelpCacheUpdateEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
struct SHIM_PERSISTENT_CACHE_ENTRY_52 * PSHIM_PERSISTENT_CACHE_ENTRY_52
NTSTATUS NTAPI ApphelpCacheInitialize(VOID)
NTSTATUS ApphelpValidateData(_In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData, _Out_ PUNICODE_STRING ImageName, _Out_ PHANDLE ImageHandle)
NTSTATUS ApphelpCacheRemoveEntryNolock(_In_ PSHIM_CACHE_ENTRY Entry)
VOID ApphelpCacheReleaseLock(VOID)
NTSTATUS ApphelpCacheAccessCheck(VOID)
NTSTATUS ApphelpCacheLookupEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
NTSTATUS ApphelpCacheParse(_In_reads_(DataLength) PUCHAR Data, _In_ ULONG DataLength)
static RTL_AVL_TABLE ApphelpShimCache
#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE
NTSTATUS NTAPI NtApphelpCacheControl(_In_ APPHELPCACHESERVICECLASS Service, _In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData)
BOOLEAN ApphelpCacheTryAcquireLock(VOID)
static ERESOURCE ApphelpCacheLock
VOID NTAPI ApphelpShimCacheFreeRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID Buffer)
#define PSHIM_PERSISTENT_CACHE_ENTRY
BOOLEAN NTAPI SeSinglePrivilegeCheck(_In_ LUID PrivilegeValue, _In_ KPROCESSOR_MODE PreviousMode)
Checks if a single privilege is present in the context of the calling thread.
#define OBJ_KERNEL_HANDLE
#define OBJ_CASE_INSENSITIVE
#define _SEH2_GetExceptionCode()
#define _SEH2_EXCEPT(...)
#define _SEH2_YIELD(__stmt)
#define FileStandardInformation
#define STATUS_BUFFER_OVERFLOW
SHIM_PERSISTENT_CACHE_ENTRY Persistent
struct _LIST_ENTRY * Blink
struct _LIST_ENTRY * Flink
#define RtlCopyMemory(Destination, Source, Length)
#define CONTAINING_RECORD(address, type, field)
#define STATUS_ACCESS_DENIED
#define STATUS_INVALID_PARAMETER
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
_Must_inspect_result_ _In_ WDFCMRESLIST List
_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
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)
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
_IRQL_requires_same_ _In_ CLONG ByteSize
_IRQL_requires_same_ _In_ PVOID FirstStruct
enum _RTL_GENERIC_COMPARE_RESULTS RTL_GENERIC_COMPARE_RESULTS