40#define EMPTY_SHIM_ENTRY { { 0 }, { { 0 } }, 0 }
41#define MAX_SHIM_ENTRIES 0x200
43#ifndef INVALID_HANDLE_VALUE
44#define INVALID_HANDLE_VALUE (HANDLE)(-1)
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
75#define SHIM_CACHE_MAGIC CACHE_MAGIC_NT_52
76#define SHIM_CACHE_HEADER_SIZE CACHE_HEADER_SIZE_NT_52
78#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE NT52_PERSISTENT_ENTRY_SIZE64
80#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE NT52_PERSISTENT_ENTRY_SIZE32
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
169 String->MaximumLength = 0;
184 Status = ZwQueryInformationFile(ImageHandle,
194 Status = ZwQueryInformationFile(ImageHandle,
197 sizeof(FileStandard),
265 DPRINT1(
"SHIMS: ApphelpCacheParse not enough data for a minimal header (0x%x)\n",
DataLength);
271 DPRINT1(
"SHIMS: ApphelpCacheParse found invalid magic (0x%x)\n",
Header->Magic);
275 NumEntries =
Header->NumEntries;
276 DPRINT(
"SHIMS: ApphelpCacheParse walking %d entries\n", NumEntries);
277 for (Cur = 0; Cur < NumEntries; ++Cur)
283 String.Length = Persistent->ImageName.Length;
284 String.MaximumLength = Persistent->ImageName.MaximumLength;
288 Entry.Persistent = *Persistent;
296 DPRINT1(
"SHIMS: ApphelpCacheParse insert failed\n");
312 ULONG KeyInfoSize, ResultSize;
317 DPRINT1(
"SHIMS: ApphelpCacheRead could not even open Session Manager\\AppCompatCache (0x%x)\n",
Status);
325 sizeof(KeyValueObject),
331 if (KeyValueInformation !=
NULL)
349 DPRINT1(
"SHIMS: ApphelpCacheRead not loaded from registry (0x%x)\n",
Status);
352 if (KeyValueInformation != &KeyValueObject && KeyValueInformation !=
NULL)
365 ULONG NumEntries = 0;
380 Length +=
Entry->Persistent.ImageName.MaximumLength;
382 ListEntry = ListEntry->
Flink;
384 DPRINT(
"SHIMS: ApphelpCacheWrite, %d Entries, total size: %d\n", NumEntries,
Length);
386 DPRINT(
"SHIMS: ApphelpCacheWrite, Rounded to: %d\n",
Length);
395 Header->NumEntries = NumEntries;
401 USHORT ImageNameLen =
Entry->Persistent.ImageName.MaximumLength;
403 *WriteEntry =
Entry->Persistent;
404 BufferNamePos -= ImageNameLen;
408 WriteEntry->ImageName.Buffer = (
PWCH)(BufferNamePos -
Buffer);
411 ListEntry = ListEntry->
Flink;
428 DPRINT1(
"SHIMS: ApphelpCacheWrite could not even open Session Manager\\AppCompatCache (0x%x)\n",
Status);
441 DPRINT(
"SHIMS: ApphelpCacheInitialize\n");
445 DPRINT1(
"SHIMS: Safe mode detected, disabling cache.\n");
489 LocalImageName = ServiceData->ImageName;
490 *ImageHandle = ServiceData->ImageHandle;
508 DPRINT1(
"SHIMS: ApphelpValidateData: invalid data passed\n");
548 DPRINT(
"SHIMS: ApphelpCacheLookupEntry: could not find %wZ\n",
ImageName);
555 DPRINT(
"SHIMS: ApphelpCacheLookupEntry: ok\n");
563 Lookup.Persistent.DateTime.QuadPart ==
Entry->Persistent.DateTime.QuadPart &&
564 Lookup.Persistent.FileSize.QuadPart ==
Entry->Persistent.FileSize.QuadPart)
566 DPRINT(
"SHIMS: ApphelpCacheLookupEntry: found & validated\n");
574 DPRINT1(
"SHIMS: ApphelpCacheLookupEntry: file info mismatch (%lx)\n",
Status);
608 DPRINT1(
"SHIMS: ApphelpCacheAccessCheck failed\n");
642 &NodeOrParent, &SearchResult);
645 DPRINT(
"SHIMS: ApphelpCacheUpdateEntry: Entry already exists, reusing it\n");
649 Lookup->Persistent.DateTime =
Entry.Persistent.DateTime;
650 Lookup->Persistent.FileSize =
Entry.Persistent.FileSize;
654 DPRINT(
"SHIMS: ApphelpCacheUpdateEntry: Inserting new Entry\n");
676 DPRINT1(
"SHIMS: ApphelpCacheUpdateEntry: Cache growing too big, dropping oldest item\n");
692 DPRINT1(
"SHIMS: ApphelpCacheFlush\n");
708 DPRINT1(
"SHIMS: NtApphelpCacheControl( Dumping entries, newest to oldest )\n");
715 DPRINT1(
"DateTime: 0x%I64x\n",
Entry->Persistent.DateTime.QuadPart);
716 DPRINT1(
"FileSize: 0x%I64x\n",
Entry->Persistent.FileSize.QuadPart);
718 ListEntry = ListEntry->
Flink;
738 DPRINT1(
"NtApphelpCacheControl: ApphelpCacheEnabled == 0\n");
744 DPRINT(
"SHIMS: NtApphelpCacheControl( ApphelpCacheServiceLookup )\n");
750 DPRINT(
"SHIMS: NtApphelpCacheControl( ApphelpCacheServiceRemove )\n");
756 DPRINT(
"SHIMS: NtApphelpCacheControl( ApphelpCacheServiceUpdate )\n");
773 DPRINT1(
"SHIMS: NtApphelpCacheControl( ApphelpDBGReadRegistry ): flushing cache.\n");
775 DPRINT1(
"SHIMS: NtApphelpCacheControl( ApphelpDBGReadRegistry ): reading cache.\n");
779 DPRINT1(
"SHIMS: NtApphelpCacheControl( ApphelpDBGWriteRegistry ): writing cache.\n");
783 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_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
#define NT_SUCCESS(StatCode)
#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 OBJ_KERNEL_HANDLE
#define OBJ_CASE_INSENSITIVE
#define EXCEPTION_EXECUTE_HANDLER
#define KeLeaveCriticalRegion()
#define KeEnterCriticalRegion()
#define ExFreePoolWithTag(_P, _T)
static PWSTR SIZE_T Length
static const char * ImageName
static OUT PIO_STATUS_BLOCK IoStatusBlock
_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 _SEH2_GetExceptionCode()
#define _SEH2_EXCEPT(...)
#define _SEH2_YIELD(__stmt)
#define FileStandardInformation
#define STATUS_BUFFER_OVERFLOW
base of all file and directory entries
SHIM_PERSISTENT_CACHE_ENTRY Persistent
struct _LIST_ENTRY * Blink
struct _LIST_ENTRY * Flink
#define RTL_CONSTANT_STRING(s)
#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