ReactOS  0.4.15-dev-5452-g3c95c95
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 TAG_SHIM
Definition: tag.h:138
#define ExAllocatePoolWithTag(hernya, size, tag)
Definition: env_spec_w32.h:350
_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 {
604  if (ExGetPreviousMode() != KernelMode)
605  {
607  {
608  DPRINT1("SHIMS: ApphelpCacheAccessCheck failed\n");
609  return STATUS_ACCESS_DENIED;
610  }
611  }
612  return STATUS_SUCCESS;
613 }
KPROCESSOR_MODE NTAPI ExGetPreviousMode(VOID)
Definition: sysinfo.c:3062
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
const LUID SeTcbPrivilege
Definition: priv.c:26
#define DPRINT1
Definition: precomp.h:8
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

Referenced by NtApphelpCacheControl().

◆ ApphelpCacheAcquireLock()

VOID ApphelpCacheAcquireLock ( VOID  )

Definition at line 115 of file apphelp.c.

116 {
119 }
#define TRUE
Definition: types.h:120
BOOLEAN NTAPI ExAcquireResourceExclusiveLite(IN PERESOURCE Resource, IN BOOLEAN Wait)
Definition: resource.c:770
#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 }
VOID ApphelpCacheReleaseLock(VOID)
Definition: apphelp.c:134
struct _Entry Entry
Definition: kefuncs.h:629
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)
Definition: Messaging.c:560
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
static LIST_ENTRY ApphelpShimCacheAge
Definition: apphelp.c:32
Definition: apphelp.c:91
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
VOID ApphelpCacheAcquireLock(VOID)
Definition: apphelp.c:115
#define DPRINT1
Definition: precomp.h:8
#define STATUS_SUCCESS
Definition: shellext.h:65
base of all file and directory entries
Definition: entries.h:82

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 }
VOID ApphelpCacheReleaseLock(VOID)
Definition: apphelp.c:134
#define TRUE
Definition: types.h:120
static RTL_AVL_TABLE ApphelpShimCache
Definition: apphelp.c:31
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlEnumerateGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ BOOLEAN Restart)
Definition: apphelp.c:91
VOID ApphelpCacheAcquireLock(VOID)
Definition: apphelp.c:115
#define DPRINT1
Definition: precomp.h:8
NTSTATUS ApphelpCacheRemoveEntryNolock(_In_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:514
#define STATUS_SUCCESS
Definition: shellext.h:65
GLfloat GLfloat p
Definition: glext.h:8902

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 */
443  if (InitSafeBootMode)
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 }
PVOID NTAPI ApphelpShimCacheAllocateRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ CLONG ByteSize)
Definition: apphelp.c:234
static RTL_AVL_TABLE ApphelpShimCache
Definition: apphelp.c:31
NTSTATUS ExInitializeResourceLite(PULONG res)
Definition: env_spec_w32.h:641
BOOLEAN ApphelpCacheRead(VOID)
Definition: apphelp.c:306
#define FALSE
Definition: types.h:117
ULONG InitSafeBootMode
Definition: init.c:71
static BOOLEAN ApphelpCacheEnabled
Definition: apphelp.c:29
VOID NTAPI ApphelpShimCacheFreeRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID Buffer)
Definition: apphelp.c:243
static LIST_ENTRY ApphelpShimCacheAge
Definition: apphelp.c:32
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
RTL_GENERIC_COMPARE_RESULTS NTAPI ApphelpShimCacheCompareRoutine(_In_ struct _RTL_AVL_TABLE *Table, _In_ PVOID FirstStruct, _In_ PVOID SecondStruct)
Definition: apphelp.c:209
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
static ERESOURCE ApphelpCacheLock
Definition: apphelp.c:30
#define STATUS_SUCCESS
Definition: shellext.h:65
#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 
581 Cleanup:
583  return Status;
584 }
VOID ApphelpCacheReleaseLock(VOID)
Definition: apphelp.c:134
struct _Entry Entry
Definition: kefuncs.h:629
#define INVALID_HANDLE_VALUE
Definition: apphelp.c:44
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
static RTL_AVL_TABLE ApphelpShimCache
Definition: apphelp.c:31
#define EMPTY_SHIM_ENTRY
Definition: apphelp.c:40
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS ApphelpCacheQueryInfo(_In_ HANDLE ImageHandle, _Out_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:175
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
static void Lookup(RTF_Info *, char *)
Definition: reader.c:2228
Status
Definition: gdiplustypes.h:24
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static LIST_ENTRY ApphelpShimCacheAge
Definition: apphelp.c:32
Definition: apphelp.c:91
static const char * ImageName
Definition: image.c:34
static const WCHAR Cleanup[]
Definition: register.c:80
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
NTSTATUS ApphelpCacheRemoveEntryNolock(_In_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:514
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
BOOLEAN ApphelpCacheTryAcquireLock(VOID)
Definition: apphelp.c:122
base of all file and directory entries
Definition: entries.h:82

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;
261  PSHIM_PERSISTENT_CACHE_ENTRY Persistent;
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 }
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
static RTL_AVL_TABLE ApphelpShimCache
Definition: apphelp.c:31
#define EMPTY_SHIM_ENTRY
Definition: apphelp.c:40
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG _In_opt_ PVOID Data
Definition: wdfdevice.h:4527
uint16_t * PWCHAR
Definition: typedefs.h:56
#define InsertTailList(ListHead, Entry)
uint32_t ULONG_PTR
Definition: typedefs.h:65
VOID ApphelpFreeUnicodeString(_Inout_ PUNICODE_STRING String)
Definition: apphelp.c:161
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
#define SHIM_CACHE_HEADER_SIZE
Definition: apphelp.c:76
Definition: Header.h:8
NTSYSAPI PVOID NTAPI RtlInsertElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_reads_bytes_(BufferSize) PVOID Buffer, _In_ CLONG BufferSize, _Out_opt_ PBOOLEAN NewElement)
_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
#define PSHIM_PERSISTENT_CACHE_HEADER
Definition: apphelp.c:83
_In_ ULONG _In_opt_ WDFREQUEST _In_opt_ PVOID _In_ size_t _In_ PVOID _In_ size_t _Out_ size_t * DataLength
Definition: cdrom.h:1437
#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE
Definition: apphelp.c:80
static LIST_ENTRY ApphelpShimCacheAge
Definition: apphelp.c:32
Definition: apphelp.c:91
#define PSHIM_PERSISTENT_CACHE_ENTRY
Definition: apphelp.c:85
VOID ApphelpDuplicateUnicodeString(_Out_ PUNICODE_STRING Destination, _In_ PCUNICODE_STRING Source)
Definition: apphelp.c:141
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define SHIM_CACHE_MAGIC
Definition: apphelp.c:75
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
#define CACHE_HEADER_SIZE_NT_52
Definition: apphelp.c:66
base of all file and directory entries
Definition: entries.h:82

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,
185  &IoStatusBlock,
186  &FileBasic,
187  sizeof(FileBasic),
189  if (!NT_SUCCESS(Status))
190  {
191  return Status;
192  }
193 
194  Status = ZwQueryInformationFile(ImageHandle,
195  &IoStatusBlock,
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 }
LONG NTSTATUS
Definition: precomp.h:26
Status
Definition: gdiplustypes.h:24
LARGE_INTEGER LastWriteTime
Definition: nt_native.h:941
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
#define FileStandardInformation
Definition: propsheet.cpp:61
base of all file and directory entries
Definition: entries.h:82

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 }
NTSTATUS ApphelpCacheParse(_In_reads_(DataLength) PUCHAR Data, _In_ ULONG DataLength)
Definition: apphelp.c:251
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
static UNICODE_STRING AppCompatCacheValue
Definition: apphelp.c:38
#define REG_BINARY
Definition: nt_native.h:1496
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
LONG NTSTATUS
Definition: precomp.h:26
#define FALSE
Definition: types.h:117
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
#define KEY_QUERY_VALUE
Definition: nt_native.h:1016
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define NULL
Definition: types.h:112
#define DPRINT1
Definition: precomp.h:8
PVOID ApphelpAlloc(_In_ ULONG ByteSize)
Definition: apphelp.c:101
unsigned int ULONG
Definition: retypes.h:1
VOID ApphelpFree(_In_ PVOID Data)
Definition: apphelp.c:108
static OBJECT_ATTRIBUTES AppCompatKeyAttributes
Definition: apphelp.c:37

Referenced by ApphelpCacheInitialize(), and NtApphelpCacheControl().

◆ ApphelpCacheReleaseLock()

VOID ApphelpCacheReleaseLock ( VOID  )

Definition at line 134 of file apphelp.c.

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

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

◆ ApphelpCacheRemoveEntry()

NTSTATUS ApphelpCacheRemoveEntry ( _In_ PUNICODE_STRING  ImageName)

Definition at line 587 of file apphelp.c.

589 {
592 
597  return Status;
598 }
VOID ApphelpCacheReleaseLock(VOID)
Definition: apphelp.c:134
struct _Entry Entry
Definition: kefuncs.h:629
static RTL_AVL_TABLE ApphelpShimCache
Definition: apphelp.c:31
LONG NTSTATUS
Definition: precomp.h:26
Status
Definition: gdiplustypes.h:24
Definition: apphelp.c:91
static const char * ImageName
Definition: image.c:34
VOID ApphelpCacheAcquireLock(VOID)
Definition: apphelp.c:115
NTSTATUS ApphelpCacheRemoveEntryNolock(_In_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:514
_Must_inspect_result_ NTSYSAPI PVOID NTAPI RtlLookupElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
base of all file and directory entries
Definition: entries.h:82

Referenced by NtApphelpCacheControl().

◆ 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 }
uint16_t * PWSTR
Definition: typedefs.h:56
static RTL_AVL_TABLE ApphelpShimCache
Definition: apphelp.c:31
NTSYSAPI BOOLEAN NTAPI RtlDeleteElementGenericTableAvl(_In_ PRTL_AVL_TABLE Table, _In_ PVOID Buffer)
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
Definition: bufpool.h:45
#define STATUS_NOT_FOUND
Definition: shellext.h:72
VOID ApphelpFree(_In_ PVOID Data)
Definition: apphelp.c:108
#define STATUS_SUCCESS
Definition: shellext.h:65
base of all file and directory entries
Definition: entries.h:82

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
static BOOLEAN ApphelpCacheEnabled
Definition: apphelp.c:29

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 }
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define KeEnterCriticalRegion()
Definition: ke_x.h:88
#define KeLeaveCriticalRegion()
Definition: ke_x.h:119
BOOLEAN NTAPI ExTryToAcquireResourceExclusiveLite(IN PERESOURCE Resource)
Definition: resource.c:2129
static ERESOURCE ApphelpCacheLock
Definition: apphelp.c:30

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 
682 Cleanup:
684  return Status;
685 }
VOID ApphelpCacheReleaseLock(VOID)
Definition: apphelp.c:134
#define INVALID_HANDLE_VALUE
Definition: apphelp.c:44
struct _LIST_ENTRY * Blink
Definition: typedefs.h:122
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
static RTL_AVL_TABLE ApphelpShimCache
Definition: apphelp.c:31
#define EMPTY_SHIM_ENTRY
Definition: apphelp.c:40
enum _TABLE_SEARCH_RESULT TABLE_SEARCH_RESULT
LONG NTSTATUS
Definition: precomp.h:26
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)
NTSTATUS ApphelpCacheQueryInfo(_In_ HANDLE ImageHandle, _Out_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:175
VOID ApphelpFreeUnicodeString(_Inout_ PUNICODE_STRING String)
Definition: apphelp.c:161
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
static void Lookup(RTF_Info *, char *)
Definition: reader.c:2228
_In_ BOOLEAN Remove
Definition: psfuncs.h:110
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)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
NTSYSAPI ULONG NTAPI RtlNumberGenericTableElementsAvl(_In_ PRTL_AVL_TABLE Table)
static LIST_ENTRY ApphelpShimCacheAge
Definition: apphelp.c:32
Definition: apphelp.c:91
#define MAX_SHIM_ENTRIES
Definition: apphelp.c:41
static const char * ImageName
Definition: image.c:34
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
static const WCHAR Cleanup[]
Definition: register.c:80
VOID ApphelpCacheAcquireLock(VOID)
Definition: apphelp.c:115
VOID ApphelpDuplicateUnicodeString(_Out_ PUNICODE_STRING Destination, _In_ PCUNICODE_STRING Source)
Definition: apphelp.c:141
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define DPRINT1
Definition: precomp.h:8
NTSTATUS ApphelpCacheRemoveEntryNolock(_In_ PSHIM_CACHE_ENTRY Entry)
Definition: apphelp.c:514
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
base of all file and directory entries
Definition: entries.h:82

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;
369  PSHIM_PERSISTENT_CACHE_ENTRY WriteEntry;
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,
421  REG_BINARY,
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 }
VOID ApphelpCacheReleaseLock(VOID)
Definition: apphelp.c:134
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:101
#define ROUND_UP(n, align)
Definition: eventvwr.h:34
#define KEY_SET_VALUE
Definition: nt_native.h:1017
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
static UNICODE_STRING AppCompatCacheValue
Definition: apphelp.c:38
#define REG_BINARY
Definition: nt_native.h:1496
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
unsigned char * PUCHAR
Definition: retypes.h:3
LONG NTSTATUS
Definition: precomp.h:26
#define SHIM_CACHE_HEADER_SIZE
Definition: apphelp.c:76
Definition: Header.h:8
#define PSHIM_PERSISTENT_CACHE_HEADER
Definition: apphelp.c:83
Definition: bufpool.h:45
#define SHIM_PERSISTENT_CACHE_ENTRY_SIZE
Definition: apphelp.c:80
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)
Definition: Messaging.c:560
Status
Definition: gdiplustypes.h:24
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
uint64_t ULONGLONG
Definition: typedefs.h:67
static LIST_ENTRY ApphelpShimCacheAge
Definition: apphelp.c:32
WCHAR * PWCH
Definition: ntbasedef.h:410
Definition: apphelp.c:91
#define PSHIM_PERSISTENT_CACHE_ENTRY
Definition: apphelp.c:85
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
Definition: typedefs.h:119
static PWSTR SIZE_T Length
Definition: apphelp.c:93
VOID ApphelpCacheAcquireLock(VOID)
Definition: apphelp.c:115
unsigned short USHORT
Definition: pedump.c:61
#define DPRINT1
Definition: precomp.h:8
PVOID ApphelpAlloc(_In_ ULONG ByteSize)
Definition: apphelp.c:101
unsigned int ULONG
Definition: retypes.h:1
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define SHIM_CACHE_MAGIC
Definition: apphelp.c:75
VOID ApphelpFree(_In_ PVOID Data)
Definition: apphelp.c:108
static OBJECT_ATTRIBUTES AppCompatKeyAttributes
Definition: apphelp.c:37
#define DPRINT
Definition: sndvol32.h:71
base of all file and directory entries
Definition: entries.h:82

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 }
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define UNICODE_NULL
__wchar_t WCHAR
Definition: xmlstorage.h:180
_In_ PUNICODE_STRING _Inout_ PUNICODE_STRING Destination
Definition: rtlfuncs.h:2991
#define NULL
Definition: types.h:112
PVOID ApphelpAlloc(_In_ ULONG ByteSize)
Definition: apphelp.c:101
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
_In_ UINT _In_ UINT _In_ PNDIS_PACKET Source
Definition: ndis.h:3167

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

◆ ApphelpFree()

VOID ApphelpFree ( _In_ PVOID  Data)

Definition at line 108 of file apphelp.c.

110 {
112 }
#define TAG_SHIM
Definition: tag.h:138
#define ExFreePoolWithTag(_P, _T)
Definition: module.h:1099

Referenced by ApphelpCacheRead(), ApphelpCacheRemoveEntryNolock(), ApphelpCacheWrite(), ApphelpFreeUnicodeString(), and ApphelpShimCacheFreeRoutine().

◆ 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 }
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2430
#define NULL
Definition: types.h:112
VOID ApphelpFree(_In_ PVOID Data)
Definition: apphelp.c:108

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 }
PVOID ApphelpAlloc(_In_ ULONG ByteSize)
Definition: apphelp.c:101
_IRQL_requires_same_ _In_ CLONG ByteSize
Definition: rtltypes.h:393

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 }
#define TRUE
Definition: types.h:120
long LONG
Definition: pedump.c:60
SHIM_PERSISTENT_CACHE_ENTRY Persistent
Definition: apphelp.c:94
_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
_IRQL_requires_same_ _In_ PVOID _In_ PVOID SecondStruct
Definition: rtltypes.h:383
Definition: apphelp.c:91
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
_IRQL_requires_same_ _In_ PVOID FirstStruct
Definition: rtltypes.h:383

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 }
Definition: bufpool.h:45
VOID ApphelpFree(_In_ PVOID Data)
Definition: apphelp.c:108

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;
484  _SEH2_TRY
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);
496  ApphelpDuplicateUnicodeString(ImageName, &LocalImageName);
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 }
_SEH2_TRY
Definition: create.c:4226
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
_SEH2_END
Definition: create.c:4400
Status
Definition: gdiplustypes.h:24
__wchar_t WCHAR
Definition: xmlstorage.h:180
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
static const char * ImageName
Definition: image.c:34
VOID NTAPI ProbeForRead(IN CONST VOID *Address, IN SIZE_T Length, IN ULONG Alignment)
Definition: exintrin.c:102
VOID ApphelpDuplicateUnicodeString(_Out_ PUNICODE_STRING Destination, _In_ PCUNICODE_STRING Source)
Definition: apphelp.c:141
#define DPRINT1
Definition: precomp.h:8
unsigned int ULONG
Definition: retypes.h:1
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:40
#define STATUS_SUCCESS
Definition: shellext.h:65
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:165
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:168

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 {
733  UNICODE_STRING ImageName = { 0 };
735 
736  if (!ApphelpCacheEnabled)
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 }
NTSTATUS ApphelpCacheDump(VOID)
Definition: apphelp.c:703
#define INVALID_HANDLE_VALUE
Definition: apphelp.c:44
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
LONG NTSTATUS
Definition: precomp.h:26
NTSTATUS ApphelpCacheUpdateEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
Definition: apphelp.c:616
BOOLEAN ApphelpCacheRead(VOID)
Definition: apphelp.c:306
VOID ApphelpFreeUnicodeString(_Inout_ PUNICODE_STRING String)
Definition: apphelp.c:161
BOOLEAN ApphelpCacheWrite(VOID)
Definition: apphelp.c:362
Status
Definition: gdiplustypes.h:24
#define STATUS_NOT_FOUND
Definition: shellext.h:72
NTSTATUS ApphelpCacheAccessCheck(VOID)
Definition: apphelp.c:602
static BOOLEAN ApphelpCacheEnabled
Definition: apphelp.c:29
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static const char * ImageName
Definition: image.c:34
NTSTATUS ApphelpValidateData(_In_opt_ PAPPHELP_CACHE_SERVICE_LOOKUP ServiceData, _Out_ PUNICODE_STRING ImageName, _Out_ PHANDLE ImageHandle)
Definition: apphelp.c:474
#define DPRINT1
Definition: precomp.h:8
_In_ HANDLE Handle
Definition: extypes.h:390
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
NTSTATUS ApphelpCacheRemoveEntry(_In_ PUNICODE_STRING ImageName)
Definition: apphelp.c:587
NTSTATUS ApphelpCacheFlush(VOID)
Definition: apphelp.c:688
NTSTATUS ApphelpCacheLookupEntry(_In_ PUNICODE_STRING ImageName, _In_ HANDLE ImageHandle)
Definition: apphelp.c:531

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

Definition at line 71 of file init.c.

Referenced by ApphelpCacheInitialize(), and Phase1InitializationDiscard().