ReactOS 0.4.15-dev-5836-g942b022
apphelp.c File Reference
#include <ntoskrnl.h>
#include <debug.h>
#include <pshpack1.h>
#include <poppack.h>
Include dependency graph for apphelp.c:

Go to the source code of this file.

Classes

struct  SHIM_PERSISTENT_CACHE_HEADER_52
 
struct  SHIM_PERSISTENT_CACHE_ENTRY_52
 
struct  SHIM_CACHE_ENTRY
 

Macros

#define NDEBUG
 
#define EMPTY_SHIM_ENTRY   { { 0 }, { { 0 } }, 0 }
 
#define MAX_SHIM_ENTRIES   0x200
 
#define INVALID_HANDLE_VALUE   (HANDLE)(-1)
 
#define CACHE_MAGIC_NT_52   0xbadc0ffe
 
#define CACHE_HEADER_SIZE_NT_52   0x8
 
#define NT52_PERSISTENT_ENTRY_SIZE32   0x18
 
#define NT52_PERSISTENT_ENTRY_SIZE64   0x20
 
#define SHIM_CACHE_MAGIC   CACHE_MAGIC_NT_52
 
#define SHIM_CACHE_HEADER_SIZE   CACHE_HEADER_SIZE_NT_52
 
#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE   NT52_PERSISTENT_ENTRY_SIZE32
 
#define SHIM_PERSISTENT_CACHE_HEADER   SHIM_PERSISTENT_CACHE_HEADER_52
 
#define PSHIM_PERSISTENT_CACHE_HEADER   PSHIM_PERSISTENT_CACHE_HEADER_52
 
#define SHIM_PERSISTENT_CACHE_ENTRY   SHIM_PERSISTENT_CACHE_ENTRY_52
 
#define PSHIM_PERSISTENT_CACHE_ENTRY   PSHIM_PERSISTENT_CACHE_ENTRY_52
 

Typedefs

typedef struct SHIM_PERSISTENT_CACHE_HEADER_52 SHIM_PERSISTENT_CACHE_HEADER_52
 
typedef struct SHIM_PERSISTENT_CACHE_HEADER_52PSHIM_PERSISTENT_CACHE_HEADER_52
 
typedef struct SHIM_PERSISTENT_CACHE_ENTRY_52 SHIM_PERSISTENT_CACHE_ENTRY_52
 
typedef struct SHIM_PERSISTENT_CACHE_ENTRY_52PSHIM_PERSISTENT_CACHE_ENTRY_52
 
typedef struct SHIM_CACHE_ENTRY SHIM_CACHE_ENTRY
 
typedef struct SHIM_CACHE_ENTRYPSHIM_CACHE_ENTRY
 

Functions

 C_ASSERT (sizeof(SHIM_PERSISTENT_CACHE_ENTRY)==SHIM_PERSISTENT_CACHE_ENTRY_SIZE)
 
 C_ASSERT (sizeof(SHIM_PERSISTENT_CACHE_HEADER)==SHIM_CACHE_HEADER_SIZE)
 
PVOID ApphelpAlloc (_In_ ULONG ByteSize)
 
VOID ApphelpFree (_In_ PVOID Data)
 
VOID ApphelpCacheAcquireLock (VOID)
 
BOOLEAN ApphelpCacheTryAcquireLock (VOID)
 
VOID ApphelpCacheReleaseLock (VOID)
 
VOID ApphelpDuplicateUnicodeString (_Out_ PUNICODE_STRING Destination, _In_ PCUNICODE_STRING Source)
 
VOID ApphelpFreeUnicodeString (_Inout_ PUNICODE_STRING String)
 
NTSTATUS ApphelpCacheQueryInfo (_In_ HANDLE ImageHandle, _Out_ PSHIM_CACHE_ENTRY Entry)
 
RTL_GENERIC_COMPARE_RESULTS NTAPI ApphelpShimCacheCompareRoutine (_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct)
 
PVOID NTAPI ApphelpShimCacheAllocateRoutine (_In_ struct _RTL_AVL_TABLE *Table, _In_ CLONG ByteSize)
 
VOID NTAPI ApphelpShimCacheFreeRoutine (_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID Buffer)
 
NTSTATUS ApphelpCacheParse (_In_reads_(DataLength) PUCHAR Data, _In_ ULONG DataLength)
 
BOOLEAN ApphelpCacheRead (VOID)
 
BOOLEAN ApphelpCacheWrite (VOID)
 
NTSTATUS NTAPI ApphelpCacheInitialize (VOID)
 
VOID NTAPI ApphelpCacheShutdown (VOID)
 
NTSTATUS ApphelpValidateData (_In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData, _Out_ PUNICODE_STRING ImageName, _Out_ PHANDLE ImageHandle)
 
NTSTATUS ApphelpCacheRemoveEntryNolock (_In_ PSHIM_CACHE_ENTRY Entry)
 
NTSTATUS ApphelpCacheLookupEntry (_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
 
NTSTATUS ApphelpCacheRemoveEntry (_In_ PUNICODE_STRING ImageName)
 
NTSTATUS ApphelpCacheAccessCheck (VOID)
 
NTSTATUS ApphelpCacheUpdateEntry (_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
 
NTSTATUS ApphelpCacheFlush (VOID)
 
NTSTATUS ApphelpCacheDump (VOID)
 
NTSTATUS NTAPI NtApphelpCacheControl (_In_ APPHELPCACHESERVICECLASS Service, _In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData)
 

Variables

static BOOLEAN ApphelpCacheEnabled = FALSE
 
static ERESOURCE ApphelpCacheLock
 
static RTL_AVL_TABLE ApphelpShimCache
 
static LIST_ENTRY ApphelpShimCacheAge
 
ULONG InitSafeBootMode
 
static UNICODE_STRING AppCompatCacheKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\AppCompatCache")
 
static OBJECT_ATTRIBUTES AppCompatKeyAttributes = RTL_CONSTANT_OBJECT_ATTRIBUTES(&AppCompatCacheKey, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE)
 
static UNICODE_STRING AppCompatCacheValue = RTL_CONSTANT_STRING(L"AppCompatCache")
 

Macro Definition Documentation

◆ CACHE_HEADER_SIZE_NT_52

#define CACHE_HEADER_SIZE_NT_52   0x8

Definition at line 66 of file apphelp.c.

◆ CACHE_MAGIC_NT_52

#define CACHE_MAGIC_NT_52   0xbadc0ffe

Definition at line 65 of file apphelp.c.

◆ EMPTY_SHIM_ENTRY

#define EMPTY_SHIM_ENTRY   { { 0 }, { { 0 } }, 0 }

Definition at line 40 of file apphelp.c.

◆ INVALID_HANDLE_VALUE

#define INVALID_HANDLE_VALUE   (HANDLE)(-1)

Definition at line 44 of file apphelp.c.

◆ MAX_SHIM_ENTRIES

#define MAX_SHIM_ENTRIES   0x200

Definition at line 41 of file apphelp.c.

◆ NDEBUG

#define NDEBUG

Definition at line 24 of file apphelp.c.

◆ NT52_PERSISTENT_ENTRY_SIZE32

#define NT52_PERSISTENT_ENTRY_SIZE32   0x18

Definition at line 67 of file apphelp.c.

◆ NT52_PERSISTENT_ENTRY_SIZE64

#define NT52_PERSISTENT_ENTRY_SIZE64   0x20

Definition at line 68 of file apphelp.c.

◆ PSHIM_PERSISTENT_CACHE_ENTRY

#define PSHIM_PERSISTENT_CACHE_ENTRY   PSHIM_PERSISTENT_CACHE_ENTRY_52

Definition at line 85 of file apphelp.c.

◆ PSHIM_PERSISTENT_CACHE_HEADER

#define PSHIM_PERSISTENT_CACHE_HEADER   PSHIM_PERSISTENT_CACHE_HEADER_52

Definition at line 83 of file apphelp.c.

◆ SHIM_CACHE_HEADER_SIZE

#define SHIM_CACHE_HEADER_SIZE   CACHE_HEADER_SIZE_NT_52

Definition at line 76 of file apphelp.c.

◆ SHIM_CACHE_MAGIC

#define SHIM_CACHE_MAGIC   CACHE_MAGIC_NT_52

Definition at line 75 of file apphelp.c.

◆ SHIM_PERSISTENT_CACHE_ENTRY

#define SHIM_PERSISTENT_CACHE_ENTRY   SHIM_PERSISTENT_CACHE_ENTRY_52

Definition at line 84 of file apphelp.c.

◆ SHIM_PERSISTENT_CACHE_ENTRY_SIZE

#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE   NT52_PERSISTENT_ENTRY_SIZE32

Definition at line 80 of file apphelp.c.

◆ SHIM_PERSISTENT_CACHE_HEADER

#define SHIM_PERSISTENT_CACHE_HEADER   SHIM_PERSISTENT_CACHE_HEADER_52

Definition at line 82 of file apphelp.c.

Typedef Documentation

◆ PSHIM_CACHE_ENTRY

◆ PSHIM_PERSISTENT_CACHE_ENTRY_52

◆ PSHIM_PERSISTENT_CACHE_HEADER_52

◆ SHIM_CACHE_ENTRY

◆ SHIM_PERSISTENT_CACHE_ENTRY_52

◆ SHIM_PERSISTENT_CACHE_HEADER_52

Function Documentation

◆ ApphelpAlloc()

PVOID ApphelpAlloc ( _In_ ULONG  ByteSize)

Definition at line 101 of file apphelp.c.

103{
105}
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
#define PagedPool
Definition: env_spec_w32.h:308
#define TAG_SHIM
Definition: tag.h:138
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:393

Referenced by ApphelpCacheRead(), ApphelpCacheWrite(), ApphelpDuplicateUnicodeString(), and ApphelpShimCacheAllocateRoutine().

◆ ApphelpCacheAccessCheck()

NTSTATUS ApphelpCacheAccessCheck ( VOID  )

Definition at line 602 of file apphelp.c.

603{
605 {
607 {
608 DPRINT1("SHIMS: ApphelpCacheAccessCheck failed\n");
610 }
611 }
612 return STATUS_SUCCESS;
613}
#define DPRINT1
Definition: precomp.h:8
#define ExGetPreviousMode
Definition: ex.h:139
#define KernelMode
Definition: asm.h:34
#define UserMode
Definition: asm.h:35
const LUID SeTcbPrivilege
Definition: priv.c:26
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
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145

Referenced by NtApphelpCacheControl().

◆ ApphelpCacheAcquireLock()

VOID ApphelpCacheAcquireLock ( VOID  )

Definition at line 115 of file apphelp.c.

116{
119}
#define TRUE
Definition: types.h:120
#define ExAcquireResourceExclusiveLite(res, wait)
Definition: env_spec_w32.h:615
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
static ERESOURCE ApphelpCacheLock
Definition: apphelp.c:30

Referenced by ApphelpCacheDump(), ApphelpCacheFlush(), ApphelpCacheRemoveEntry(), ApphelpCacheUpdateEntry(), and ApphelpCacheWrite().

◆ ApphelpCacheDump()

NTSTATUS ApphelpCacheDump ( VOID  )

Definition at line 703 of file apphelp.c.

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}
static LIST_ENTRY ApphelpShimCacheAge
Definition: apphelp.c:32
VOID ApphelpCacheAcquireLock(VOID)
Definition: apphelp.c:115
VOID ApphelpCacheReleaseLock(VOID)
Definition: apphelp.c:134
base of all file and directory entries
Definition: entries.h:83
Definition: apphelp.c:92
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550

Referenced by NtApphelpCacheControl().

◆ ApphelpCacheFlush()

NTSTATUS ApphelpCacheFlush ( VOID  )

Definition at line 688 of file apphelp.c.

689{
690 PVOID p;
691
692 DPRINT1("SHIMS: ApphelpCacheFlush\n");
695 {
697 }
699 return STATUS_SUCCESS;
700}
GLfloat GLfloat p
Definition: glext.h:8902
NTSTATUS ApphelpCacheRemoveEntryNolock(_In_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:514
static RTL_AVL_TABLE ApphelpShimCache
Definition: apphelp.c:31
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlEnumerateGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ BOOLEAN Restart)

Referenced by NtApphelpCacheControl().

◆ ApphelpCacheInitialize()

NTSTATUS NTAPI ApphelpCacheInitialize ( VOID  )

Definition at line 439 of file apphelp.c.

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}
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
#define NULL
Definition: types.h:112
#define FALSE
Definition: types.h:117
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
RTL_GENERIC_COMPARE_RESULTS NTAPI ApphelpShimCacheCompareRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct)
Definition: apphelp.c:209
static BOOLEAN ApphelpCacheEnabled
Definition: apphelp.c:29
PVOID NTAPI ApphelpShimCacheAllocateRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ CLONG ByteSize)
Definition: apphelp.c:234
BOOLEAN ApphelpCacheRead(VOID)
Definition: apphelp.c:306
ULONG InitSafeBootMode
Definition: init.c:71
VOID NTAPI ApphelpShimCacheFreeRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID Buffer)
Definition: apphelp.c:243
#define DPRINT
Definition: sndvol32.h:71

Referenced by IoInitSystem().

◆ ApphelpCacheLookupEntry()

NTSTATUS ApphelpCacheLookupEntry ( _In_ PUNICODE_STRING  ImageName,
_In_ HANDLE  ImageHandle 
)

Definition at line 531 of file apphelp.c.

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}
LONG NTSTATUS
Definition: precomp.h:26
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#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 InsertHeadList(ListHead, Entry)
Status
Definition: gdiplustypes.h:25
static const char * ImageName
Definition: image.c:34
NTSTATUS ApphelpCacheQueryInfo(_In_ HANDLE ImageHandle, _Out_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:175
#define EMPTY_SHIM_ENTRY
Definition: apphelp.c:40
BOOLEAN ApphelpCacheTryAcquireLock(VOID)
Definition: apphelp.c:122
#define STATUS_NOT_FOUND
Definition: shellext.h:72
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)

Referenced by NtApphelpCacheControl().

◆ ApphelpCacheParse()

NTSTATUS ApphelpCacheParse ( _In_reads_(DataLength) PUCHAR  Data,
_In_ ULONG  DataLength 
)

Definition at line 251 of file apphelp.c.

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}
_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: Header.h:9
#define InsertTailList(ListHead, Entry)
#define SHIM_CACHE_HEADER_SIZE
Definition: apphelp.c:76
VOID ApphelpDuplicateUnicodeString(_Out_ PUNICODE_STRING Destination, _In_ PCUNICODE_STRING Source)
Definition: apphelp.c:141
#define SHIM_CACHE_MAGIC
Definition: apphelp.c:75
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
#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE
Definition: apphelp.c:80
#define PSHIM_PERSISTENT_CACHE_ENTRY
Definition: apphelp.c:85
uint32_t ULONG_PTR
Definition: typedefs.h:65
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
_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
NTSYSAPI PVOID NTAPI RtlInsertElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_reads_bytes_(BufferSize) PVOID Buffer, _In_ CLONG BufferSize, _Out_opt_ PBOOLEAN NewElement)

Referenced by ApphelpCacheRead().

◆ ApphelpCacheQueryInfo()

NTSTATUS ApphelpCacheQueryInfo ( _In_ HANDLE  ImageHandle,
_Out_ PSHIM_CACHE_ENTRY  Entry 
)

Definition at line 175 of file apphelp.c.

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}
@ FileBasicInformation
Definition: from_kernel.h:65
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FileStandardInformation
Definition: propsheet.cpp:61
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941

Referenced by ApphelpCacheLookupEntry(), and ApphelpCacheUpdateEntry().

◆ ApphelpCacheRead()

BOOLEAN ApphelpCacheRead ( VOID  )

Definition at line 306 of file apphelp.c.

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}
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
#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
static UNICODE_STRING AppCompatCacheValue
Definition: apphelp.c:38
PVOID ApphelpAlloc(_In_ ULONG ByteSize)
Definition: apphelp.c:101
static OBJECT_ATTRIBUTES AppCompatKeyAttributes
Definition: apphelp.c:37
VOID ApphelpFree(_In_ PVOID Data)
Definition: apphelp.c:108
NTSTATUS ApphelpCacheParse(_In_reads_(DataLength) PUCHAR Data, _In_ ULONG DataLength)
Definition: apphelp.c:251
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66

Referenced by ApphelpCacheInitialize(), and NtApphelpCacheControl().

◆ ApphelpCacheReleaseLock()

VOID ApphelpCacheReleaseLock ( VOID  )

Definition at line 134 of file apphelp.c.

135{
138}
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
VOID FASTCALL ExReleaseResourceLite(IN PERESOURCE Resource)
Definition: resource.c:1817

Referenced by ApphelpCacheDump(), ApphelpCacheFlush(), ApphelpCacheLookupEntry(), ApphelpCacheRemoveEntry(), ApphelpCacheUpdateEntry(), and ApphelpCacheWrite().

◆ ApphelpCacheRemoveEntry()

NTSTATUS ApphelpCacheRemoveEntry ( _In_ PUNICODE_STRING  ImageName)

◆ ApphelpCacheRemoveEntryNolock()

NTSTATUS ApphelpCacheRemoveEntryNolock ( _In_ PSHIM_CACHE_ENTRY  Entry)

Definition at line 514 of file apphelp.c.

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}
Definition: bufpool.h:45
uint16_t * PWSTR
Definition: typedefs.h:56
NTSYSAPI BOOLEAN NTAPI RtlDeleteElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)

Referenced by ApphelpCacheFlush(), ApphelpCacheLookupEntry(), ApphelpCacheRemoveEntry(), and ApphelpCacheUpdateEntry().

◆ ApphelpCacheShutdown()

VOID NTAPI ApphelpCacheShutdown ( VOID  )

Definition at line 465 of file apphelp.c.

466{
468 {
470 }
471}
BOOLEAN ApphelpCacheWrite(VOID)
Definition: apphelp.c:362

Referenced by PopGracefulShutdown().

◆ ApphelpCacheTryAcquireLock()

BOOLEAN ApphelpCacheTryAcquireLock ( VOID  )

Definition at line 122 of file apphelp.c.

123{
126 {
128 return FALSE;
129 }
130 return TRUE;
131}
BOOLEAN NTAPI ExTryToAcquireResourceExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:2129

Referenced by ApphelpCacheLookupEntry().

◆ ApphelpCacheUpdateEntry()

NTSTATUS ApphelpCacheUpdateEntry ( _In_ PUNICODE_STRING  ImageName,
_In_ HANDLE  ImageHandle 
)

Definition at line 616 of file apphelp.c.

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}
#define MAX_SHIM_ENTRIES
Definition: apphelp.c:41
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
_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)
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElementsAvl(_In_ PRTL_AVL_TABLE Table)
enum _TABLE_SEARCH_RESULT TABLE_SEARCH_RESULT

Referenced by NtApphelpCacheControl().

◆ ApphelpCacheWrite()

BOOLEAN ApphelpCacheWrite ( VOID  )

Definition at line 362 of file apphelp.c.

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}
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define KEY_SET_VALUE
Definition: nt_native.h:1017
WCHAR * PWCH
Definition: ntbasedef.h:410
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
unsigned short USHORT
Definition: pedump.c:61
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
unsigned char * PUCHAR
Definition: typedefs.h:53
uint64_t ULONGLONG
Definition: typedefs.h:67

Referenced by ApphelpCacheShutdown(), and NtApphelpCacheControl().

◆ ApphelpDuplicateUnicodeString()

VOID ApphelpDuplicateUnicodeString ( _Out_ PUNICODE_STRING  Destination,
_In_ PCUNICODE_STRING  Source 
)

Definition at line 141 of file apphelp.c.

144{
145 Destination->Length = Source->Length;
146 if (Destination->Length)
147 {
152 }
153 else
154 {
157 }
158}
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3169
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2992
#define UNICODE_NULL
USHORT MaximumLength
Definition: env_spec_w32.h:370
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by ApphelpCacheParse(), ApphelpCacheUpdateEntry(), and ApphelpValidateData().

◆ ApphelpFree()

VOID ApphelpFree ( _In_ PVOID  Data)

◆ ApphelpFreeUnicodeString()

VOID ApphelpFreeUnicodeString ( _Inout_ PUNICODE_STRING  String)

Definition at line 161 of file apphelp.c.

163{
164 if (String->Buffer)
165 {
166 ApphelpFree(String->Buffer);
167 }
168 String->Length = 0;
169 String->MaximumLength = 0;
170 String->Buffer = NULL;
171}

Referenced by ApphelpCacheParse(), ApphelpCacheUpdateEntry(), and NtApphelpCacheControl().

◆ ApphelpShimCacheAllocateRoutine()

PVOID NTAPI ApphelpShimCacheAllocateRoutine ( _In_ struct _RTL_AVL_TABLE Table,
_In_ CLONG  ByteSize 
)

Definition at line 234 of file apphelp.c.

237{
238 return ApphelpAlloc(ByteSize);
239}

Referenced by ApphelpCacheInitialize().

◆ ApphelpShimCacheCompareRoutine()

RTL_GENERIC_COMPARE_RESULTS NTAPI ApphelpShimCacheCompareRoutine ( _In_ struct _RTL_AVL_TABLE Table,
_In_ PVOID  FirstStruct,
_In_ PVOID  SecondStruct 
)

Definition at line 209 of file apphelp.c.

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}
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
long LONG
Definition: pedump.c:60
SHIM_PERSISTENT_CACHE_ENTRY Persistent
Definition: apphelp.c:94
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
Definition: rtltypes.h:384
_IRQL_requires_same_ _In_ PVOID FirstStruct
Definition: rtltypes.h:383
@ GenericLessThan
Definition: rtltypes.h:370
@ GenericEqual
Definition: rtltypes.h:372
@ GenericGreaterThan
Definition: rtltypes.h:371

Referenced by ApphelpCacheInitialize().

◆ ApphelpShimCacheFreeRoutine()

VOID NTAPI ApphelpShimCacheFreeRoutine ( _In_ struct _RTL_AVL_TABLE Table,
_In_ PVOID  Buffer 
)

Definition at line 243 of file apphelp.c.

246{
248}

Referenced by ApphelpCacheInitialize().

◆ ApphelpValidateData()

NTSTATUS ApphelpValidateData ( _In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP  ServiceData,
_Out_ PUNICODE_STRING  ImageName,
_Out_ PHANDLE  ImageHandle 
)

Definition at line 474 of file apphelp.c.

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}
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:159
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:34
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:162

Referenced by NtApphelpCacheControl().

◆ C_ASSERT() [1/2]

◆ C_ASSERT() [2/2]

◆ NtApphelpCacheControl()

NTSTATUS NTAPI NtApphelpCacheControl ( _In_ APPHELPCACHESERVICECLASS  Service,
_In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP  ServiceData 
)

Definition at line 728 of file apphelp.c.

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}
ULONG Handle
Definition: gdb_input.c:15
@ ApphelpDBGReadRegistry
Definition: pstypes.h:979
@ ApphelpCacheServiceLookup
Definition: pstypes.h:973
@ ApphelpCacheServiceRemove
Definition: pstypes.h:974
@ ApphelpCacheServiceUpdate
Definition: pstypes.h:975
@ ApphelpCacheServiceDump
Definition: pstypes.h:977
@ ApphelpDBGWriteRegistry
Definition: pstypes.h:980
@ ApphelpCacheServiceFlush
Definition: pstypes.h:976
NTSTATUS ApphelpCacheDump(VOID)
Definition: apphelp.c:703
NTSTATUS ApphelpCacheFlush(VOID)
Definition: apphelp.c:688
NTSTATUS ApphelpCacheRemoveEntry(_In_ PUNICODE_STRING ImageName)
Definition: apphelp.c:587
NTSTATUS ApphelpCacheUpdateEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
Definition: apphelp.c:616
NTSTATUS ApphelpValidateData(_In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData, _Out_ PUNICODE_STRING ImageName, _Out_ PHANDLE ImageHandle)
Definition: apphelp.c:474
NTSTATUS ApphelpCacheAccessCheck(VOID)
Definition: apphelp.c:602
NTSTATUS ApphelpCacheLookupEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
Definition: apphelp.c:531
@ Service
Definition: ntsecapi.h:292

Referenced by BaseDumpAppcompatCache(), BaseFlushAppcompatCache(), and CallApphelp().

Variable Documentation

◆ AppCompatCacheKey

UNICODE_STRING AppCompatCacheKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\AppCompatCache")
static

Definition at line 36 of file apphelp.c.

◆ AppCompatCacheValue

UNICODE_STRING AppCompatCacheValue = RTL_CONSTANT_STRING(L"AppCompatCache")
static

Definition at line 38 of file apphelp.c.

Referenced by ApphelpCacheRead(), and ApphelpCacheWrite().

◆ AppCompatKeyAttributes

◆ ApphelpCacheEnabled

BOOLEAN ApphelpCacheEnabled = FALSE
static

Definition at line 29 of file apphelp.c.

Referenced by ApphelpCacheInitialize(), ApphelpCacheShutdown(), and NtApphelpCacheControl().

◆ ApphelpCacheLock

ERESOURCE ApphelpCacheLock
static

◆ ApphelpShimCache

◆ ApphelpShimCacheAge

◆ InitSafeBootMode

ULONG InitSafeBootMode
extern

Definition at line 71 of file init.c.

Referenced by ApphelpCacheInitialize(), and Phase1InitializationDiscard().