40 #define EMPTY_SHIM_ENTRY { { 0 }, { { 0 } }, 0 } 41 #define MAX_SHIM_ENTRIES 0x200 42 #define TAG_SHIM 'MIHS' 44 #ifndef INVALID_HANDLE_VALUE 45 #define INVALID_HANDLE_VALUE (HANDLE)(-1) 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 76 #define SHIM_CACHE_MAGIC CACHE_MAGIC_NT_52 77 #define SHIM_CACHE_HEADER_SIZE CACHE_HEADER_SIZE_NT_52 79 #define SHIM_PERSISTENT_CACHE_ENTRY_SIZE NT52_PERSISTENT_ENTRY_SIZE64 81 #define SHIM_PERSISTENT_CACHE_ENTRY_SIZE NT52_PERSISTENT_ENTRY_SIZE32 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 170 String->MaximumLength = 0;
185 Status = ZwQueryInformationFile(ImageHandle,
195 Status = ZwQueryInformationFile(ImageHandle,
198 sizeof(FileStandard),
266 DPRINT1(
"SHIMS: ApphelpCacheParse not enough data for a minimal header (0x%x)\n",
DataLength);
272 DPRINT1(
"SHIMS: ApphelpCacheParse found invalid magic (0x%x)\n",
Header->Magic);
276 NumEntries =
Header->NumEntries;
277 DPRINT(
"SHIMS: ApphelpCacheParse walking %d entries\n", NumEntries);
278 for (Cur = 0; Cur < NumEntries; ++Cur)
284 String.Length = Persistent->ImageName.Length;
285 String.MaximumLength = Persistent->ImageName.MaximumLength;
289 Entry.Persistent = *Persistent;
297 DPRINT1(
"SHIMS: ApphelpCacheParse insert failed\n");
313 ULONG KeyInfoSize, ResultSize;
318 DPRINT1(
"SHIMS: ApphelpCacheRead could not even open Session Manager\\AppCompatCache (0x%x)\n",
Status);
326 sizeof(KeyValueObject),
332 if (KeyValueInformation !=
NULL)
350 DPRINT1(
"SHIMS: ApphelpCacheRead not loaded from registry (0x%x)\n",
Status);
353 if (KeyValueInformation != &KeyValueObject && KeyValueInformation !=
NULL)
366 ULONG NumEntries = 0;
381 Length +=
Entry->Persistent.ImageName.MaximumLength;
383 ListEntry = ListEntry->
Flink;
385 DPRINT(
"SHIMS: ApphelpCacheWrite, %d Entries, total size: %d\n", NumEntries,
Length);
387 DPRINT(
"SHIMS: ApphelpCacheWrite, Rounded to: %d\n",
Length);
396 Header->NumEntries = NumEntries;
402 USHORT ImageNameLen =
Entry->Persistent.ImageName.MaximumLength;
404 *WriteEntry =
Entry->Persistent;
405 BufferNamePos -= ImageNameLen;
409 WriteEntry->ImageName.Buffer = (
PWCH)(BufferNamePos -
Buffer);
412 ListEntry = ListEntry->
Flink;
429 DPRINT1(
"SHIMS: ApphelpCacheWrite could not even open Session Manager\\AppCompatCache (0x%x)\n",
Status);
442 DPRINT(
"SHIMS: ApphelpCacheInitialize\n");
446 DPRINT1(
"SHIMS: Safe mode detected, disabling cache.\n");
490 LocalImageName = ServiceData->ImageName;
491 *ImageHandle = ServiceData->ImageHandle;
509 DPRINT1(
"SHIMS: ApphelpValidateData: invalid data passed\n");
549 DPRINT(
"SHIMS: ApphelpCacheLookupEntry: could not find %wZ\n",
ImageName);
556 DPRINT(
"SHIMS: ApphelpCacheLookupEntry: ok\n");
564 Lookup.Persistent.DateTime.QuadPart ==
Entry->Persistent.DateTime.QuadPart &&
565 Lookup.Persistent.FileSize.QuadPart ==
Entry->Persistent.FileSize.QuadPart)
567 DPRINT(
"SHIMS: ApphelpCacheLookupEntry: found & validated\n");
575 DPRINT1(
"SHIMS: ApphelpCacheLookupEntry: file info mismatch (%lx)\n",
Status);
609 DPRINT1(
"SHIMS: ApphelpCacheAccessCheck failed\n");
643 &NodeOrParent, &SearchResult);
646 DPRINT(
"SHIMS: ApphelpCacheUpdateEntry: Entry already exists, reusing it\n");
650 Lookup->Persistent.DateTime =
Entry.Persistent.DateTime;
651 Lookup->Persistent.FileSize =
Entry.Persistent.FileSize;
655 DPRINT(
"SHIMS: ApphelpCacheUpdateEntry: Inserting new Entry\n");
677 DPRINT1(
"SHIMS: ApphelpCacheUpdateEntry: Cache growing too big, dropping oldest item\n");
693 DPRINT1(
"SHIMS: ApphelpCacheFlush\n");
709 DPRINT1(
"SHIMS: NtApphelpCacheControl( Dumping entries, newest to oldest )\n");
716 DPRINT1(
"DateTime: 0x%I64x\n",
Entry->Persistent.DateTime.QuadPart);
717 DPRINT1(
"FileSize: 0x%I64x\n",
Entry->Persistent.FileSize.QuadPart);
719 ListEntry = ListEntry->
Flink;
739 DPRINT1(
"NtApphelpCacheControl: ApphelpCacheEnabled == 0\n");
745 DPRINT(
"SHIMS: NtApphelpCacheControl( ApphelpCacheServiceLookup )\n");
751 DPRINT(
"SHIMS: NtApphelpCacheControl( ApphelpCacheServiceRemove )\n");
757 DPRINT(
"SHIMS: NtApphelpCacheControl( ApphelpCacheServiceUpdate )\n");
774 DPRINT1(
"SHIMS: NtApphelpCacheControl( ApphelpDBGReadRegistry ): flushing cache.\n");
776 DPRINT1(
"SHIMS: NtApphelpCacheControl( ApphelpDBGReadRegistry ): reading cache.\n");
780 DPRINT1(
"SHIMS: NtApphelpCacheControl( ApphelpDBGWriteRegistry ): writing cache.\n");
784 DPRINT1(
"SHIMS: NtApphelpCacheControl( Invalid service requested )\n");
VOID ApphelpCacheReleaseLock(VOID)
NTSTATUS ApphelpCacheParse(_In_reads_(DataLength) PUCHAR Data, _In_ ULONG DataLength)
PVOID NTAPI ApphelpShimCacheAllocateRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ CLONG ByteSize)
#define SHIM_PERSISTENT_CACHE_HEADER
_In_ ULONG _In_ ULONG _In_ ULONG Length
#define ROUND_UP(n, align)
NTSTATUS ApphelpCacheDump(VOID)
#define OBJ_CASE_INSENSITIVE
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
IN BOOLEAN OUT PSTR Buffer
static UNICODE_STRING AppCompatCacheValue
#define INVALID_HANDLE_VALUE
#define STATUS_INVALID_PARAMETER
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
struct _LIST_ENTRY * Blink
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
static RTL_AVL_TABLE ApphelpShimCache
NTSYSAPI BOOLEAN NTAPI RtlDeleteElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG _In_opt_ PVOID Data
enum _TABLE_SEARCH_RESULT TABLE_SEARCH_RESULT
NTSTATUS ApphelpCacheUpdateEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
NTSYSAPI PVOID NTAPI RtlLookupElementGenericTableFullAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer, _Out_ PVOID *NodeOrParent, _Out_ TABLE_SEARCH_RESULT *SearchResult)
NTSTATUS ExInitializeResourceLite(PULONG res)
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)
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
#define InsertTailList(ListHead, Entry)
NTSTATUS ApphelpCacheQueryInfo(_In_ HANDLE ImageHandle, _Out_ PSHIM_CACHE_ENTRY Entry)
#define OBJ_KERNEL_HANDLE
BOOLEAN ApphelpCacheRead(VOID)
C_ASSERT(sizeof(SHIM_PERSISTENT_CACHE_ENTRY)==SHIM_PERSISTENT_CACHE_ENTRY_SIZE)
VOID ApphelpFreeUnicodeString(_Inout_ PUNICODE_STRING String)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
static void Lookup(RTF_Info *, char *)
struct SHIM_PERSISTENT_CACHE_HEADER_52 SHIM_PERSISTENT_CACHE_HEADER_52
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
#define SHIM_CACHE_HEADER_SIZE
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
SHIM_PERSISTENT_CACHE_ENTRY Persistent
BOOLEAN ApphelpCacheWrite(VOID)
_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
#define PSHIM_PERSISTENT_CACHE_HEADER
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE
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)
struct _LIST_ENTRY * Flink
NTSTATUS ApphelpCacheAccessCheck(VOID)
#define _SEH2_YIELD(STMT_)
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
static BOOLEAN ApphelpCacheEnabled
#define NT_SUCCESS(StatCode)
_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
VOID NTAPI ApphelpShimCacheFreeRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID Buffer)
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElementsAvl(_In_ PRTL_AVL_TABLE Table)
NTSTATUS NTAPI NtApphelpCacheControl(_In_ APPHELPCACHESERVICECLASS Service, _In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData)
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
#define STATUS_ACCESS_DENIED
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
static LIST_ENTRY ApphelpShimCacheAge
#define ExAllocatePoolWithTag(hernya, size, tag)
static const char * ImageName
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
#define PSHIM_PERSISTENT_CACHE_ENTRY
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
_Must_inspect_result_ _In_ WDFCMRESLIST List
#define KeEnterCriticalRegion()
_IRQL_requires_same_ _In_ PVOID FirstStruct
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)
VOID NTAPI ApphelpCacheShutdown(VOID)
static const WCHAR Cleanup[]
RTL_GENERIC_COMPARE_RESULTS NTAPI ApphelpShimCacheCompareRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct)
static PWSTR SIZE_T Length
static UNICODE_STRING AppCompatCacheKey
VOID ApphelpCacheAcquireLock(VOID)
const LUID SeTcbPrivilege
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
#define SHIM_PERSISTENT_CACHE_ENTRY
#define KeLeaveCriticalRegion()
#define STATUS_BUFFER_OVERFLOW
VOID ApphelpDuplicateUnicodeString(_Out_ PUNICODE_STRING Destination, _In_ PCUNICODE_STRING Source)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define InitializeListHead(ListHead)
BOOLEAN NTAPI ExTryToAcquireResourceExclusiveLite(IN PERESOURCE Resource)
NTSTATUS ApphelpValidateData(_In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData, _Out_ PUNICODE_STRING ImageName, _Out_ PHANDLE ImageHandle)
enum _APPHELPCACHESERVICECLASS APPHELPCACHESERVICECLASS
static OUT PIO_STATUS_BLOCK IoStatusBlock
enum _RTL_GENERIC_COMPARE_RESULTS RTL_GENERIC_COMPARE_RESULTS
#define FileStandardInformation
PVOID ApphelpAlloc(_In_ ULONG ByteSize)
NTSTATUS ApphelpCacheRemoveEntryNolock(_In_ PSHIM_CACHE_ENTRY Entry)
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
static ERESOURCE ApphelpCacheLock
#define RtlCopyMemory(Destination, Source, Length)
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
VOID ApphelpFree(_In_ PVOID Data)
#define _SEH2_EXCEPT(...)
static OBJECT_ATTRIBUTES AppCompatKeyAttributes
#define ExFreePoolWithTag(_P, _T)
#define _SEH2_GetExceptionCode()
BOOLEAN ApphelpCacheTryAcquireLock(VOID)
_IRQL_requires_same_ _In_ CLONG ByteSize
#define CACHE_HEADER_SIZE_NT_52
struct SHIM_CACHE_ENTRY SHIM_CACHE_ENTRY
base of all file and directory entries
NTSTATUS ApphelpCacheRemoveEntry(_In_ PUNICODE_STRING ImageName)
NTSTATUS NTAPI ApphelpCacheInitialize(VOID)
#define RTL_CONSTANT_STRING(s)
NTSTATUS ApphelpCacheFlush(VOID)
struct SHIM_PERSISTENT_CACHE_ENTRY_52 SHIM_PERSISTENT_CACHE_ENTRY_52
NTSTATUS ApphelpCacheLookupEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)