432 lines
15 KiB
C
432 lines
15 KiB
C
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
sxsp.h
|
|
|
|
Abstract:
|
|
|
|
Include file for ntdll-private definitions of Side-By-Side data structures.
|
|
|
|
Author:
|
|
|
|
Michael J. Grier (mgrier) October 26, 2000
|
|
|
|
Environment:
|
|
|
|
|
|
Revision History:
|
|
|
|
--*/
|
|
|
|
#if !defined(_NTDLL_SXSP_H_INCLUDED_)
|
|
#define _NTDLL_SXSP_H_INCLUDED_
|
|
|
|
#include <nturtl.h>
|
|
#include <sxstypes.h>
|
|
|
|
typedef const void *PCVOID;
|
|
|
|
//
|
|
// Private definitions for activation context management stuff
|
|
//
|
|
|
|
#define NUMBER_OF(x) (sizeof(x) / sizeof((x)[0]))
|
|
|
|
//
|
|
// Codes for the STATUS_SXS_CORRUPTION exception
|
|
//
|
|
|
|
#define SXS_CORRUPTION_CODE_FRAMELIST (1)
|
|
#define SXS_CORRUPTION_CODE_FRAMELIST_SUBCODE_BAD_MAGIC (1)
|
|
#define SXS_CORRUPTION_CODE_FRAMELIST_SUBCODE_BAD_INUSECOUNT (2)
|
|
|
|
// SXS_CORRUPTION_CODE_FRAMELIST:
|
|
//
|
|
// ExceptionInformation[0] == SXS_CORRUPTION_CODE_FRAMELIST
|
|
// ExceptionInformation[1] == one of: SXS_CORRUPTION_CODE_FRAMELIST_SUBCODE_BAD_MAGIC, SXS_CORRUPTION_CODE_FRAMELIST_SUBCODE_BAD_INUSECOUNT
|
|
// ExceptionInformation[2] == Framelist list head in TEB
|
|
// ExceptionInformation[3] == Framelist found to be corrupt
|
|
|
|
#define SXS_CORRUPTION_ACTCTX_LIST (2)
|
|
#define SXS_CORRUPTION_ACTCTX_LIST_RELEASING_NOT_IN_LIVE_LIST (1)
|
|
|
|
// SXS_CORRUPTION_ACTCTX_LIST
|
|
//
|
|
// ExceptionInformation[0] = SXS_CORRUPTION_ACTCTX_LIST
|
|
// ExceptionInformation[1] = One of SXS_CORRUPTION_ACTCTX_LIST_*
|
|
// ExceptionInformation[2] = Pointer to the list of live activation contexts
|
|
// ExceptionInformation[3] = Activation context not found in live list
|
|
|
|
#define SXS_CORRUPTION_ACTCTX_MAGIC (1)
|
|
#define SXS_CORRUPTION_ACTCTX_MAGIC_NOT_MATCHED (1)
|
|
#define SXS_CORRUPTION_ACTCTX_MAGIC_NOT_ALIGNED (2)
|
|
|
|
// SXS_CORRUPTION_ACTCTX_MAGIC
|
|
//
|
|
// ExceptionInformation[0] = SXS_CORRUPTION_ACTCTX_MAGIC
|
|
// ExceptionInformation[1] = SXS_CORRUPTION_MAGIC_NOT_MATCHED or SXS_CORRUPTION_ACTCTX_MAGIC_NOT_ALIGNED
|
|
// ExceptionInformation[2] = Pointer to the activation context that fails
|
|
|
|
|
|
typedef struct _RTL_HEAP_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME {
|
|
RTL_ACTIVATION_CONTEXT_STACK_FRAME Frame;
|
|
ULONG_PTR Cookie;
|
|
PVOID ActivationStackBackTrace[8];
|
|
} RTL_HEAP_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME, *PRTL_HEAP_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME;
|
|
|
|
NTSYSAPI
|
|
VOID
|
|
NTAPI
|
|
RtlpAssemblyStorageMapResolutionDefaultCallback(
|
|
IN ULONG CallbackReason,
|
|
IN OUT ASSEMBLY_STORAGE_MAP_RESOLUTION_CALLBACK_DATA *CallbackData,
|
|
IN PVOID CallbackContext
|
|
);
|
|
|
|
typedef struct _ASSEMBLY_STORAGE_MAP_ENTRY {
|
|
ULONG Flags;
|
|
UNICODE_STRING DosPath; // stored with a trailing unicode null
|
|
HANDLE Handle; // open file handle on the directory to lock it down
|
|
} ASSEMBLY_STORAGE_MAP_ENTRY, *PASSEMBLY_STORAGE_MAP_ENTRY;
|
|
|
|
#define ASSEMBLY_STORAGE_MAP_ASSEMBLY_ARRAY_IS_HEAP_ALLOCATED (0x00000001)
|
|
|
|
typedef struct _ASSEMBLY_STORAGE_MAP {
|
|
ULONG Flags;
|
|
ULONG AssemblyCount;
|
|
PASSEMBLY_STORAGE_MAP_ENTRY *AssemblyArray;
|
|
} ASSEMBLY_STORAGE_MAP, *PASSEMBLY_STORAGE_MAP;
|
|
|
|
#define ACTCTX_RELEASE_STACK_DEPTH (4)
|
|
#define ACTCTX_RELEASE_STACK_SLOTS (4)
|
|
|
|
typedef struct _ACTIVATION_CONTEXT {
|
|
LONG RefCount;
|
|
ULONG Flags;
|
|
LIST_ENTRY Links;
|
|
PCACTIVATION_CONTEXT_DATA ActivationContextData;
|
|
PACTIVATION_CONTEXT_NOTIFY_ROUTINE NotificationRoutine;
|
|
PVOID NotificationContext;
|
|
ULONG SentNotifications[8];
|
|
ULONG DisabledNotifications[8];
|
|
ASSEMBLY_STORAGE_MAP StorageMap;
|
|
PASSEMBLY_STORAGE_MAP_ENTRY InlineStorageMapEntries[32];
|
|
ULONG StackTraceIndex;
|
|
PVOID StackTraces[ACTCTX_RELEASE_STACK_SLOTS][ACTCTX_RELEASE_STACK_DEPTH];
|
|
} ACTIVATION_CONTEXT;
|
|
|
|
#define ACTIVATION_CONTEXT_NOTIFICATION_DESTROY_INDEX (ACTIVATION_CONTEXT_NOTIFICATION_DESTROY >> 5)
|
|
#define ACTIVATION_CONTEXT_NOTIFICATION_DESTROY_MASK ((ULONG) (1 << (ACTIVATION_CONTEXT_NOTIFICATION_DESTROY & 0x1f)))
|
|
|
|
#define ACTIVATION_CONTEXT_NOTIFICATION_ZOMBIFY_INDEX (ACTIVATION_CONTEXT_NOTIFICATION_ZOMBIFY >> 5)
|
|
#define ACTIVATION_CONTEXT_NOTIFICATION_ZOMBIFY_MASK ((ULONG) (1 << (ACTIVATION_CONTEXT_NOTIFICATION_ZOMBIFY & 0x1f)))
|
|
|
|
#define ACTIVATION_CONTEXT_NOTIFICATION_USED_INDEX (ACTIVATION_CONTEXT_NOTIFICATION_USED >> 5)
|
|
#define ACTIVATION_CONTEXT_NOTIFICATION_USED_MASK ((ULONG) (1 << (ACTIVATION_CONTEXT_NOTIFICATION_USED & 0x1f)))
|
|
|
|
#define HAS_ACTIVATION_CONTEXT_NOTIFICATION_BEEN_SENT(_pac, _nt) (((_pac)->SentNotifications[ACTIVATION_CONTEXT_NOTIFICATION_ ## _nt ## _INDEX] & ACTIVATION_CONTEXT_NOTIFICATION_ ## _nt ## _MASK) != 0)
|
|
#define HAS_ACTIVATION_CONTEXT_NOTIFICATION_BEEN_DISABLED(_pac, _nt) (((_pac)->DisabledNotifications[ACTIVATION_CONTEXT_NOTIFICATION_ ## _nt ## _INDEX] & ACTIVATION_CONTEXT_NOTIFICATION_ ## _nt ## _MASK) != 0)
|
|
|
|
#define ACTIVATION_CONTEXT_SHOULD_SEND_NOTIFICATION(_pac, _nt) \
|
|
((!IS_SPECIAL_ACTCTX(_pac)) && ((_pac)->NotificationRoutine != NULL) && ((!HAS_ACTIVATION_CONTEXT_NOTIFICATION_BEEN_SENT((_pac), _nt)) || (!HAS_ACTIVATION_CONTEXT_NOTIFICATION_BEEN_DISABLED((_pac), _nt))))
|
|
|
|
#define RECORD_ACTIVATION_CONTEXT_NOTIFICATION_SENT(_pac, _nt) { (_pac)->SentNotifications[ACTIVATION_CONTEXT_NOTIFICATION_ ## _nt ## _INDEX] |= ACTIVATION_CONTEXT_NOTIFICATION_ ## _nt ## _MASK; }
|
|
#define RECORD_ACTIVATION_CONTEXT_NOTIFICATION_DISABLED(_pac, _nt) { (_pac)->DisabledNotifications[ACTIVATION_CONTEXT_NOTIFICATION_ ## _nt ## _INDEX] |= ACTIVATION_CONTEXT_NOTIFICATION_ ## _nt ## _MASK; }
|
|
|
|
#define SEND_ACTIVATION_CONTEXT_NOTIFICATION(_pac, _nt, _data) \
|
|
{ \
|
|
if (ACTIVATION_CONTEXT_SHOULD_SEND_NOTIFICATION((_pac), _nt)) { \
|
|
BOOLEAN __DisableNotification = FALSE; \
|
|
(*((_pac)->NotificationRoutine))( \
|
|
ACTIVATION_CONTEXT_NOTIFICATION_ ## _nt, \
|
|
(_pac), \
|
|
(_pac)->ActivationContextData, \
|
|
(_pac)->NotificationContext, \
|
|
(_data), \
|
|
&__DisableNotification); \
|
|
RECORD_ACTIVATION_CONTEXT_NOTIFICATION_SENT((_pac), _nt); \
|
|
if (__DisableNotification) \
|
|
RECORD_ACTIVATION_CONTEXT_NOTIFICATION_DISABLED((_pac), _nt); \
|
|
} \
|
|
}
|
|
|
|
//
|
|
// Flags for ACTIVATION_CONTEXT
|
|
//
|
|
|
|
#define ACTIVATION_CONTEXT_ZOMBIFIED (0x00000001)
|
|
#define ACTIVATION_CONTEXT_NOT_HEAP_ALLOCATED (0x00000002)
|
|
|
|
//
|
|
// Because activating an activation context may require a heap allocation
|
|
// which may fail, sometimes (e.g. dispatching an APC) we must still
|
|
// go forward with the operation. If there is an opportunity to
|
|
// report the failure to activate back to the user, that should be done.
|
|
// However, as in activating the necessary context prior to dispatching
|
|
// an APC back to the user mode code, if the allocation fails, there is
|
|
// no caller to whom to report the error.
|
|
//
|
|
// To alleviate this problem, failure paths should disable lookups on
|
|
// the current stack frame via the RtlSetActivationContextSearchState()
|
|
// API. Calling RtlSetActivationContextSearchState(FALSE) marks
|
|
// the active frame as having lookups disabled. Attempts to query
|
|
// the activation context stack will fail with the
|
|
// STATUS_SXS_THREAD_QUERIES_DISABLED.
|
|
//
|
|
// This means that attempts to load libraries from within APCs where this
|
|
// is true will fail, but it's surely better than either silently not
|
|
// calling the APC or calling the APC with the wrong activation context
|
|
// active.
|
|
//
|
|
|
|
#define ACTIVATION_CONTEXT_STACK_FRAMELIST_MAGIC 'tslF'
|
|
|
|
typedef struct _ACTIVATION_CONTEXT_STACK_FRAMELIST {
|
|
ULONG Magic; // Bit pattern to recognize a framelist
|
|
ULONG FramesInUse;
|
|
LIST_ENTRY Links;
|
|
ULONG Flags;
|
|
ULONG NotFramesInUse; // Inverted bits of FramesInUse. Useful for debugging.
|
|
RTL_HEAP_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME Frames[32];
|
|
} ACTIVATION_CONTEXT_STACK_FRAMELIST, *PACTIVATION_CONTEXT_STACK_FRAMELIST;
|
|
|
|
#define RTLP_VALIDATE_ACTIVATION_CONTEXT_DATA_FLAG_VALIDATE_SIZE (0x00000001)
|
|
#define RTLP_VALIDATE_ACTIVATION_CONTEXT_DATA_FLAG_VALIDATE_OFFSETS (0x00000002)
|
|
#define RTLP_VALIDATE_ACTIVATION_CONTEXT_DATA_FLAG_VALIDATE_READONLY (0x00000004)
|
|
|
|
NTSTATUS
|
|
RtlpValidateActivationContextData(
|
|
IN ULONG Flags OPTIONAL,
|
|
IN PCACTIVATION_CONTEXT_DATA Data,
|
|
IN SIZE_T BufferSize OPTIONAL
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpFindUnicodeStringInSection(
|
|
IN const ACTIVATION_CONTEXT_STRING_SECTION_HEADER UNALIGNED * Header,
|
|
IN SIZE_T SectionSize,
|
|
IN PCUNICODE_STRING StringToFind,
|
|
OUT PACTIVATION_CONTEXT_SECTION_KEYED_DATA DataOut OPTIONAL,
|
|
IN OUT PULONG HashAlgorithm,
|
|
IN OUT PULONG PseudoKey,
|
|
OUT PULONG UserDataSize OPTIONAL,
|
|
OUT VOID CONST ** UserData OPTIONAL
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpFindGuidInSection(
|
|
IN const ACTIVATION_CONTEXT_GUID_SECTION_HEADER UNALIGNED * Header,
|
|
IN const GUID *GuidToFind,
|
|
OUT PACTIVATION_CONTEXT_SECTION_KEYED_DATA DataOut OPTIONAL
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpLocateActivationContextSection(
|
|
IN PCACTIVATION_CONTEXT_DATA ActivationContextData,
|
|
IN const GUID *ExtensionGuid,
|
|
IN ULONG Id,
|
|
OUT PCVOID *SectionData,
|
|
OUT ULONG *SectionLength
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpCrackActivationContextStringSectionHeader(
|
|
IN CONST VOID *SectionBase,
|
|
IN SIZE_T SectionLength,
|
|
OUT ULONG *FormatVersion OPTIONAL,
|
|
OUT ULONG *DataFormatVersion OPTIONAL,
|
|
OUT ULONG *SectionFlags OPTIONAL,
|
|
OUT ULONG *ElementCount OPTIONAL,
|
|
OUT PCACTIVATION_CONTEXT_STRING_SECTION_ENTRY *Elements OPTIONAL,
|
|
OUT ULONG *HashAlgorithm OPTIONAL,
|
|
OUT VOID CONST **SearchStructure OPTIONAL,
|
|
OUT ULONG *UserDataSize OPTIONAL,
|
|
OUT VOID CONST **UserData OPTIONAL
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpGetActiveActivationContextApplicationDirectory(
|
|
IN SIZE_T InLength,
|
|
OUT PVOID OutBuffer,
|
|
OUT SIZE_T *OutLength
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpFindNextActivationContextSection(
|
|
PFINDFIRSTACTIVATIONCONTEXTSECTION Context,
|
|
OUT PCVOID *SectionData,
|
|
ULONG *SectionLength,
|
|
PACTIVATION_CONTEXT *ActivationContextOut
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpAllocateActivationContextStackFrame(
|
|
ULONG Flags,
|
|
PTEB Teb,
|
|
PRTL_HEAP_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME *Frame
|
|
);
|
|
|
|
VOID
|
|
RtlpFreeActivationContextStackFrame(
|
|
PRTL_HEAP_ALLOCATED_ACTIVATION_CONTEXT_STACK_FRAME Frame
|
|
);
|
|
|
|
PSTR
|
|
RtlpFormatGuidANSI(
|
|
const GUID *Guid,
|
|
PSTR Buffer,
|
|
SIZE_T BufferLength
|
|
);
|
|
|
|
#define RTLP_DISALLOW_THE_EMPTY_ACTIVATION_CONTEXT(ActCtx) \
|
|
{ \
|
|
ASSERT((ActCtx) != &RtlpTheEmptyActivationContext); \
|
|
if ((ActCtx) == &RtlpTheEmptyActivationContext) { \
|
|
DbgPrintEx( \
|
|
DPFLTR_SXS_ID, \
|
|
DPFLTR_ERROR_LEVEL, \
|
|
"SXS: %s() passed the empty activation context\n", __FUNCTION__); \
|
|
Status = STATUS_INVALID_PARAMETER; \
|
|
goto Exit; \
|
|
} \
|
|
}
|
|
|
|
#define RTLP_DISALLOW_THE_EMPTY_ACTIVATION_CONTEXT_DATA(ActCtxData) \
|
|
{ \
|
|
ASSERT((ActCtxData) != &RtlpTheEmptyActivationContextData); \
|
|
if ((ActCtxData) == &RtlpTheEmptyActivationContextData) { \
|
|
DbgPrintEx( \
|
|
DPFLTR_SXS_ID, \
|
|
DPFLTR_ERROR_LEVEL, \
|
|
"SXS: %s() passed the empty activation context data\n", __FUNCTION__); \
|
|
Status = STATUS_INVALID_PARAMETER; \
|
|
goto Exit; \
|
|
} \
|
|
}
|
|
|
|
PACTIVATION_CONTEXT
|
|
RtlpMapSpecialValuesToBuiltInActivationContexts(
|
|
PACTIVATION_CONTEXT ActivationContext
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpThreadPoolGetActiveActivationContext(
|
|
PACTIVATION_CONTEXT* ActivationContext
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpInitializeAssemblyStorageMap(
|
|
PASSEMBLY_STORAGE_MAP Map,
|
|
ULONG EntryCount,
|
|
PASSEMBLY_STORAGE_MAP_ENTRY *EntryArray
|
|
);
|
|
|
|
VOID
|
|
RtlpUninitializeAssemblyStorageMap(
|
|
PASSEMBLY_STORAGE_MAP Map
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpResolveAssemblyStorageMapEntry(
|
|
IN OUT PASSEMBLY_STORAGE_MAP Map,
|
|
IN PCACTIVATION_CONTEXT_DATA Data,
|
|
IN ULONG AssemblyRosterIndex,
|
|
IN PASSEMBLY_STORAGE_MAP_RESOLUTION_CALLBACK_ROUTINE Callback,
|
|
IN PVOID CallbackContext
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpInsertAssemblyStorageMapEntry(
|
|
IN PASSEMBLY_STORAGE_MAP Map,
|
|
IN ULONG AssemblyRosterIndex,
|
|
IN PCUNICODE_STRING StorageLocation,
|
|
IN OUT HANDLE *OpenDirectoryHandle
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpProbeAssemblyStorageRootForAssembly(
|
|
IN ULONG Flags,
|
|
IN PCUNICODE_STRING Root,
|
|
IN PCUNICODE_STRING AssemblyDirectory,
|
|
OUT PUNICODE_STRING PreAllocatedString,
|
|
OUT PUNICODE_STRING DynamicString,
|
|
OUT PUNICODE_STRING *StringUsed,
|
|
IN OUT HANDLE *OpenDirectoryHandle
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpGetAssemblyStorageMapRootLocation(
|
|
IN HANDLE KeyHandle,
|
|
IN PCUNICODE_STRING SubKeyName,
|
|
OUT PUNICODE_STRING Root
|
|
);
|
|
|
|
#define RTLP_GET_ACTIVATION_CONTEXT_DATA_STORAGE_MAP_AND_ROSTER_HEADER_USE_PROCESS_DEFAULT (0x00000001)
|
|
#define RTLP_GET_ACTIVATION_CONTEXT_DATA_STORAGE_MAP_AND_ROSTER_HEADER_USE_SYSTEM_DEFAULT (0x00000002)
|
|
|
|
NTSTATUS
|
|
RtlpGetActivationContextDataRosterHeader(
|
|
IN ULONG Flags,
|
|
IN PCACTIVATION_CONTEXT_DATA ActivationContextData,
|
|
OUT PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER *AssemblyRosterHeader
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpGetActivationContextDataStorageMapAndRosterHeader(
|
|
IN ULONG Flags,
|
|
IN PPEB Peb,
|
|
IN PACTIVATION_CONTEXT ActivationContext,
|
|
OUT PCACTIVATION_CONTEXT_DATA *ActivationContextData,
|
|
OUT PASSEMBLY_STORAGE_MAP *AssemblyStorageMap,
|
|
OUT PCACTIVATION_CONTEXT_DATA_ASSEMBLY_ROSTER_HEADER *AssemblyRosterHeader
|
|
);
|
|
|
|
#define RTLP_GET_ACTIVATION_CONTEXT_DATA_MAP_NULL_TO_EMPTY (0x00000001)
|
|
NTSTATUS
|
|
RtlpGetActivationContextData(
|
|
IN ULONG Flags,
|
|
IN PCACTIVATION_CONTEXT ActivationContext,
|
|
IN PCFINDFIRSTACTIVATIONCONTEXTSECTION FindContext, OPTIONAL /* This is used for its flags. */
|
|
OUT PCACTIVATION_CONTEXT_DATA * ActivationContextData
|
|
);
|
|
|
|
NTSTATUS
|
|
RtlpFindActivationContextSection_FillOutReturnedData(
|
|
IN ULONG Flags,
|
|
OUT PACTIVATION_CONTEXT_SECTION_KEYED_DATA ReturnedData,
|
|
IN OUT PACTIVATION_CONTEXT ActivationContext,
|
|
IN PCFINDFIRSTACTIVATIONCONTEXTSECTION FindContext,
|
|
IN const VOID * UNALIGNED Header,
|
|
IN ULONG Header_UserDataOffset,
|
|
IN ULONG Header_UserDataSize,
|
|
IN ULONG SectionLength
|
|
);
|
|
|
|
VOID
|
|
FASTCALL
|
|
RtlpFreeCachedActivationContexts(
|
|
VOID
|
|
);
|
|
|
|
|
|
|
|
#define ACTCTX_MAGIC_MARKER ((PVOID)(ULONG_PTR)('gMcA'))
|
|
|
|
typedef struct _ACTIVATION_CONTEXT_WRAPPED {
|
|
PVOID MagicMarker;
|
|
ACTIVATION_CONTEXT ActivationContext;
|
|
} ACTIVATION_CONTEXT_WRAPPED, *PACTIVATION_CONTEXT_WRAPPED;
|
|
|
|
typedef const ACTIVATION_CONTEXT_WRAPPED *PCACTIVATION_CONTEXT_WRAPPED;
|
|
|
|
extern const ACTIVATION_CONTEXT_DATA RtlpTheEmptyActivationContextData;
|
|
extern const ACTIVATION_CONTEXT_WRAPPED RtlpTheEmptyActivationContextWrapped;
|
|
#define RtlpTheEmptyActivationContext (RtlpTheEmptyActivationContextWrapped.ActivationContext)
|
|
|
|
EXTERN_C BOOLEAN g_SxsKeepActivationContextsAlive;
|
|
|
|
#endif // !defined(_NTDLL_SXSP_H_INCLUDED_)
|