Files
Johnny Shaw 53fbbdc5b5 sync latest
2026-03-25 18:14:46 -06:00

13282 lines
332 KiB
C++

/*
* RTL support functions
*
* This file is part of System Informer.
*/
#ifndef _NTRTL_H
#define _NTRTL_H
typedef struct _CPTABLEINFO CPTABLEINFO, *PCPTABLEINFO;
typedef enum _FILE_INFORMATION_CLASS FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
//
// Pointer arithmetic macros (type safe)
//
#define RtlOffsetToPointer(Base, Offset) ((PUCHAR)(((PUCHAR)(Base)) + ((ULONG_PTR)(Offset))))
#define RtlPointerToOffset(Base, Pointer) ((ULONG)(((PUCHAR)(Pointer)) - ((PUCHAR)(Base))))
#if defined(__cplusplus)
EXTERN_C_END
template <typename T>
FORCEINLINE
T*
RTL_PTR_ADD(T* Pointer, ULONG_PTR Value) noexcept {
return reinterpret_cast<T*>(reinterpret_cast<PBYTE>(Pointer) + Value);
}
template <typename T>
FORCEINLINE
T*
RTL_PTR_SUBTRACT(T* Pointer, ULONG_PTR Value) noexcept {
return reinterpret_cast<T*>(reinterpret_cast<PBYTE>(Pointer) - Value);
}
EXTERN_C_START
#else
#ifndef RTL_PTR_ADD
#define RTL_PTR_ADD(Pointer, Value) ((PVOID)(((PUCHAR)(Pointer)) + ((ULONG_PTR)(Value))))
#endif
#ifndef RTL_PTR_SUBTRACT
#define RTL_PTR_SUBTRACT(Pointer, Value) ((PVOID)(((PUCHAR)(Pointer)) - ((ULONG_PTR)(Value))))
#endif
#endif
#ifndef RTL_IS_POWER_OF_TWO
#define RTL_IS_POWER_OF_TWO(Value) ((Value != 0) && !((Value) & ((Value) - 1)))
#endif
#ifndef RTL_IS_CLEAR_OR_SINGLE_FLAG
#define RTL_IS_CLEAR_OR_SINGLE_FLAG(Flags, Mask) (((Flags) & (Mask)) == 0 || !(((Flags) & (Mask)) & (((Flags) & (Mask)) - 1)))
#endif
#ifndef RTL_NUM_ALIGN_DOWN
#define RTL_NUM_ALIGN_DOWN(Number, Alignment) ((Number) - ((Number) & ((Alignment) - 1)))
#endif
#ifndef RTL_NUM_ALIGN_UP
#define RTL_NUM_ALIGN_UP(Number, Alignment) RTL_NUM_ALIGN_DOWN((Number) + (Alignment) - 1, (Alignment))
#endif
//
// Time unit constants (ordered by magnitude)
//
#define RTL_NANOSEC_PER_TICK 100
#define RTL_TICKS_PER_MICROSEC 10
#define RTL_TICKS_PER_MILLISEC (RTL_TICKS_PER_MICROSEC * 1000) // 10,000
#define RTL_TICKS_PER_SEC (RTL_TICKS_PER_MILLISEC * 1000) // 10,000,000
#define RTL_TICKS_PER_MIN (RTL_TICKS_PER_SEC * 60) // 600,000,000
#define RTL_TICKS_PER_HOUR (RTL_TICKS_PER_MIN * 60) // 36,000,000,000
#define RTL_TICKS_PER_DAY (RTL_TICKS_PER_HOUR * 24) // 864,000,000,000
#define RTL_TICKS_PER_WEEK (RTL_TICKS_PER_DAY * 7) // 6,048,000,000,000
#define RTL_TICKS_PER_MONTH (RTL_TICKS_PER_DAY * 30) // 25,920,000,000,000
#define RTL_TICKS_PER_YEAR (RTL_TICKS_PER_DAY * 365) // 31,536,000,000,000
#define RTL_TICKS_PER_LEAP_YEAR (RTL_TICKS_PER_DAY * 366) // 31,622,400,000,000
#define RTL_NANOSEC_PER_SEC 1000000000ull
#define RTL_NANOSEC_PER_MILLISEC 1000000ull
#define RTL_100NANOSEC_PER_SEC 10000000ull
#define RTL_100NANOSEC_PER_MILLISEC 10000ull
#define RTL_MILLISEC_PER_SEC 1000ull
#define RTL_SEC_PER_HOUR 3600ull // 1 hour // 3,600 seconds
#define RTL_SEC_PER_DAY 86400ull // 1 day // 86,400 seconds
#define RTL_SEC_PER_WEEK 604800ull // 1 week // 604,800 seconds
#define RTL_SEC_PER_MONTH 2592000ull // 1 month // 2,592,000 seconds (30 days)
#define RTL_SEC_PER_YEAR 31536000ull // 1 year // 31,536,000 seconds (365 days)
//
// Time conversion macros (ordered by unit)
//
// Nanoseconds
#define RTL_SEC_TO_NANOSEC(s) ((s) * RTL_NANOSEC_PER_SEC)
#define RTL_NANOSEC_TO_SEC(ns) ((ns) / RTL_NANOSEC_PER_SEC)
#define RTL_MILLISEC_TO_NANOSEC(m) ((m) * RTL_NANOSEC_PER_MILLISEC)
#define RTL_NANOSEC_TO_MILLISEC(ns) ((ns) / RTL_NANOSEC_PER_MILLISEC)
#define RTL_NANOSEC_TO_100NANOSEC(ns) ((ns) / 100)
#define RTL_100NANOSEC_TO_NANOSEC(ns) ((ns) * 100)
// 100-Nanoseconds
#define RTL_SEC_TO_100NANOSEC(s) ((s) * RTL_100NANOSEC_PER_SEC)
#define RTL_100NANOSEC_TO_SEC(ns) ((ns) / RTL_100NANOSEC_PER_SEC)
#define RTL_MILLISEC_TO_100NANOSEC(m) ((m) * RTL_100NANOSEC_PER_MILLISEC)
#define RTL_100NANOSEC_TO_MILLISEC(ns) ((ns) / RTL_100NANOSEC_PER_MILLISEC)
// Milliseconds
#define RTL_SEC_TO_MILLISEC(s) ((s) * RTL_MILLISEC_PER_SEC)
#define RTL_MILLISEC_TO_SEC(m) ((m) / RTL_MILLISEC_PER_SEC)
/**
* The maximum value of the e_lfanew field in the IMAGE_DOS_HEADER structure for validation.
*/
#define RTL_IMAGE_MAX_DOS_HEADER (256UL * (1024UL * 1024UL)) // 256 MB
/**
* Meta characters for wildcard processing.
* \remarks NtQueryDirectoryFile(Ex), RtlDoesNameContainWildCards and file system drivers (FAT, NTFS, REFS).
*/
#define ANSI_DOS_STAR ((CHAR)'<')
#define ANSI_DOS_STAR_W ((WCHAR)L'<')
#define ANSI_DOS_QM ((CHAR)'>')
#define ANSI_DOS_QM_W ((WCHAR)L'>')
#define ANSI_DOS_DOT ((CHAR)'"')
#define ANSI_DOS_DOT_W ((WCHAR)L'"')
//
// Errors
//
/**
* The RtlFailFast routine brings down the caller immediately in the event that critical corruption has been detected. No exception handlers are invoked.
*
* \param Code A FAST_FAIL_<description> symbolic constant from winnt.h or wdm.h that indicates the reason for process termination.
* \return None. There is no return from this routine.
* \remarks The routine is shared with user mode and kernel mode. In user mode, the process is terminated, whereas in kernel mode, a KERNEL_SECURITY_CHECK_FAILURE bug check is raised.
*/
DECLSPEC_NORETURN
FORCEINLINE
VOID
NTAPI_INLINE
RtlFailFast(
_In_ ULONG Code
)
{
__fastfail(Code);
}
/**
* The RtlFatalListEntryError routine reports a fatal list entry error.
*
* \param p1 The first parameter passed to `RtlFailFast`.
* \param p2 The second parameter passed to `RtlFailFast`.
* \param p3 The third parameter passed to `RtlFailFast`.
* \remarks This routine is a wrapper around `RtlFailFast` that can be used to provide alternative reporting mechanisms, such as logging and trying to continue.
*/
DECLSPEC_NORETURN
FORCEINLINE
VOID
NTAPI_INLINE
RtlFatalListEntryError(
_In_ PVOID p1,
_In_ PVOID p2,
_In_ PVOID p3
)
{
//++
// This routine reports a fatal list entry error. It is implemented here as a
// wrapper around RtlFailFast so that alternative reporting mechanisms (such
// as simply logging and trying to continue) can be easily switched in.
//--
UNREFERENCED_PARAMETER(p1);
UNREFERENCED_PARAMETER(p2);
UNREFERENCED_PARAMETER(p3);
RtlFailFast(FAST_FAIL_CORRUPT_LIST_ENTRY);
}
//
// Linked lists
//
typedef struct _LIST_ENTRY LIST_ENTRY, *PLIST_ENTRY;
#define RTL_STATIC_LIST_HEAD(x) \
LIST_ENTRY (x) = { &(x), &(x) }
#define RTL_LIST_FOREACH(Entry, ListHead) \
for ((Entry) = (&(ListHead))->Flink; (Entry) != &(ListHead); (Entry) = (Entry)->Flink)
// #ifndef NO_LIST_ENTRY_CHECKS
// #define NO_LIST_ENTRY_CHECKS
// #endif
/**
* The RtlCheckListEntry routine checks the integrity of a doubly linked list entry.
*
* \param Entry A pointer to the list entry to check.
* \remarks This function calls `RtlFatalListEntryError` if the list entry is corrupted.
*/
FORCEINLINE
VOID
NTAPI_INLINE
RtlCheckListEntry(
_In_ PLIST_ENTRY Entry
)
{
if ((((Entry->Flink)->Blink) != Entry) || (((Entry->Blink)->Flink) != Entry))
{
RtlFatalListEntryError(
(PVOID)(Entry),
(PVOID)((Entry->Flink)->Blink),
(PVOID)((Entry->Blink)->Flink)
);
}
}
/**
* The InitializeListHead routine initializes a doubly linked list head.
*
* \param ListHead A pointer to the `LIST_ENTRY` structure to be initialized as a list head.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-initializelisthead
*/
FORCEINLINE
VOID
NTAPI_INLINE
InitializeListHead(
_Out_ PLIST_ENTRY ListHead
)
{
ListHead->Flink = ListHead->Blink = ListHead;
}
/**
* The InitializeListHead32 routine initializes a 32-bit doubly linked list head.
*
* \param ListHead A pointer to the `LIST_ENTRY32` structure to be initialized as a list head.
*/
FORCEINLINE
VOID
NTAPI_INLINE
InitializeListHead32(
_Out_ PLIST_ENTRY32 ListHead
)
{
ListHead->Flink = ListHead->Blink = PtrToUlong(ListHead);
}
/**
* The IsListEmpty routine determines whether a doubly linked list is empty.
*
* \param ListHead A pointer to the list head.
*
* \return `TRUE` if the list is empty, otherwise `FALSE`.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-islistempty
*/
_Must_inspect_result_
FORCEINLINE
BOOLEAN
NTAPI_INLINE
IsListEmpty(
_In_ PLIST_ENTRY ListHead
)
{
return ListHead->Flink == ListHead;
}
/**
* The RemoveEntryListUnsafe routine removes an entry from a doubly linked list without checking for integrity.
*
* \param Entry A pointer to the list entry to be removed.
* \return `TRUE` if the list becomes empty after the entry is removed, otherwise `FALSE`.
*/
FORCEINLINE
BOOLEAN
NTAPI_INLINE
RemoveEntryListUnsafe(
_In_ PLIST_ENTRY Entry
)
{
PLIST_ENTRY Blink;
PLIST_ENTRY Flink;
Flink = Entry->Flink;
Blink = Entry->Blink;
Blink->Flink = Flink;
Flink->Blink = Blink;
return (BOOLEAN)(Flink == Blink);
}
/**
* The RemoveEntryList routine removes an entry from a doubly linked list.
*
* \param Entry A pointer to the list entry to be removed.
* \return `TRUE` if the list becomes empty after the entry is removed, otherwise `FALSE`.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-removeentrylist
*/
FORCEINLINE
BOOLEAN
NTAPI_INLINE
RemoveEntryList(
_In_ PLIST_ENTRY Entry
)
{
PLIST_ENTRY PrevEntry;
PLIST_ENTRY NextEntry;
NextEntry = Entry->Flink;
PrevEntry = Entry->Blink;
#if !defined(NO_LIST_ENTRY_CHECKS)
if ((NextEntry->Blink != Entry) || (PrevEntry->Flink != Entry))
{
RtlFatalListEntryError((PVOID)PrevEntry, (PVOID)Entry, (PVOID)NextEntry);
}
#endif
PrevEntry->Flink = NextEntry;
NextEntry->Blink = PrevEntry;
return NextEntry == PrevEntry;
}
/**
* The RemoveHeadList routine removes the entry from the head of a doubly linked list.
*
* \param ListHead A pointer to the list head.
* \return A pointer to the entry removed from the head of the list.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-removeheadlist
*/
FORCEINLINE
PLIST_ENTRY
NTAPI_INLINE
RemoveHeadList(
_Inout_ PLIST_ENTRY ListHead
)
{
PLIST_ENTRY Entry;
PLIST_ENTRY NextEntry;
Entry = ListHead->Flink;
NextEntry = Entry->Flink;
#if !defined(NO_LIST_ENTRY_CHECKS)
if ((Entry->Blink != ListHead) || (NextEntry->Blink != Entry))
{
RtlFatalListEntryError((PVOID)ListHead, (PVOID)Entry, (PVOID)NextEntry);
}
#endif
ListHead->Flink = NextEntry;
NextEntry->Blink = ListHead;
return Entry;
}
/**
* The RemoveTailList routine removes the entry from the tail of a doubly linked list.
*
* \param ListHead A pointer to the list head.
* \return A pointer to the entry removed from the tail of the list.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-removetaillist
*/
FORCEINLINE
PLIST_ENTRY
NTAPI_INLINE
RemoveTailList(
_Inout_ PLIST_ENTRY ListHead
)
{
PLIST_ENTRY Entry;
PLIST_ENTRY PrevEntry;
Entry = ListHead->Blink;
PrevEntry = Entry->Blink;
#if !defined(NO_LIST_ENTRY_CHECKS)
if ((Entry->Flink != ListHead) || (PrevEntry->Flink != Entry))
{
RtlFatalListEntryError((PVOID)PrevEntry, (PVOID)Entry, (PVOID)ListHead);
}
#endif
ListHead->Blink = PrevEntry;
PrevEntry->Flink = ListHead;
return Entry;
}
/**
* The InsertTailList routine inserts an entry at the tail of a doubly linked list.
*
* \param ListHead A pointer to the list head.
* \param Entry A pointer to the list entry to be inserted.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-inserttaillist
*/
FORCEINLINE
VOID
NTAPI_INLINE
InsertTailList(
_Inout_ PLIST_ENTRY ListHead,
_Inout_ __drv_aliasesMem PLIST_ENTRY Entry
)
{
PLIST_ENTRY PrevEntry;
PrevEntry = ListHead->Blink;
#if !defined(NO_LIST_ENTRY_CHECKS)
if (PrevEntry->Flink != ListHead)
{
RtlFatalListEntryError((PVOID)PrevEntry, (PVOID)ListHead, (PVOID)PrevEntry->Flink);
}
#endif
Entry->Flink = ListHead;
Entry->Blink = PrevEntry;
PrevEntry->Flink = Entry;
ListHead->Blink = Entry;
}
/**
* The InsertHeadList routine inserts an entry at the head of a doubly linked list.
*
* \param ListHead A pointer to the list head.
* \param Entry A pointer to the list entry to be inserted.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-insertheadlist
*/
FORCEINLINE
VOID
NTAPI_INLINE
InsertHeadList(
_Inout_ PLIST_ENTRY ListHead,
_Inout_ __drv_aliasesMem PLIST_ENTRY Entry
)
{
PLIST_ENTRY NextEntry;
NextEntry = ListHead->Flink;
#if !defined(NO_LIST_ENTRY_CHECKS)
RtlCheckListEntry(ListHead);
if (NextEntry->Blink != ListHead)
{
RtlFatalListEntryError((PVOID)ListHead, (PVOID)NextEntry, (PVOID)NextEntry->Blink);
}
#endif
Entry->Flink = NextEntry;
Entry->Blink = ListHead;
NextEntry->Blink = Entry;
ListHead->Flink = Entry;
}
/**
* The AppendTailList routine appends a doubly linked list to the tail of another doubly linked list.
*
* \param ListHead A pointer to the head of the list to which to append.
* \param ListToAppend A pointer to the list to be appended.
*/
FORCEINLINE
VOID
NTAPI_INLINE
AppendTailList(
_Inout_ PLIST_ENTRY ListHead,
_Inout_ PLIST_ENTRY ListToAppend
)
{
PLIST_ENTRY ListEnd = ListHead->Blink;
#if !defined(NO_LIST_ENTRY_CHECKS)
RtlCheckListEntry(ListHead);
RtlCheckListEntry(ListToAppend);
#endif
ListHead->Blink->Flink = ListToAppend;
ListHead->Blink = ListToAppend->Blink;
ListToAppend->Blink->Flink = ListHead;
ListToAppend->Blink = ListEnd;
}
/**
* The PopEntryList routine removes the first entry from a singly linked list.
*
* \param ListHead A pointer to the list head.
* \return A pointer to the entry removed from the head of the list, or `NULL` if the list is empty.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-popentrylist
*/
FORCEINLINE
PSINGLE_LIST_ENTRY
NTAPI_INLINE
PopEntryList(
_Inout_ PSINGLE_LIST_ENTRY ListHead
)
{
PSINGLE_LIST_ENTRY FirstEntry;
FirstEntry = ListHead->Next;
if (FirstEntry)
ListHead->Next = FirstEntry->Next;
return FirstEntry;
}
/**
* The PushEntryList routine inserts an entry at the head of a singly linked list.
*
* \param ListHead A pointer to the list head.
* \param Entry A pointer to the list entry to be inserted.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-pushentrylist
*/
FORCEINLINE
VOID
NTAPI_INLINE
PushEntryList(
_Inout_ PSINGLE_LIST_ENTRY ListHead,
_Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry
)
{
Entry->Next = ListHead->Next;
ListHead->Next = Entry;
}
//
// AVL and splay trees
//
typedef enum _TABLE_SEARCH_RESULT
{
TableEmptyTree,
TableFoundNode,
TableInsertAsLeft,
TableInsertAsRight
} TABLE_SEARCH_RESULT;
typedef enum _RTL_GENERIC_COMPARE_RESULTS
{
GenericLessThan,
GenericGreaterThan,
GenericEqual
} RTL_GENERIC_COMPARE_RESULTS;
typedef struct _RTL_AVL_TABLE RTL_AVL_TABLE, *PRTL_AVL_TABLE;
typedef _Function_class_(RTL_AVL_COMPARE_ROUTINE)
RTL_GENERIC_COMPARE_RESULTS NTAPI RTL_AVL_COMPARE_ROUTINE(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID FirstStruct,
_In_ PVOID SecondStruct
);
typedef RTL_AVL_COMPARE_ROUTINE* PRTL_AVL_COMPARE_ROUTINE;
typedef _Function_class_(RTL_AVL_ALLOCATE_ROUTINE)
PVOID NTAPI RTL_AVL_ALLOCATE_ROUTINE(
_In_ PRTL_AVL_TABLE Table,
_In_ CLONG ByteSize
);
typedef RTL_AVL_ALLOCATE_ROUTINE* PRTL_AVL_ALLOCATE_ROUTINE;
typedef _Function_class_(RTL_AVL_FREE_ROUTINE)
VOID NTAPI RTL_AVL_FREE_ROUTINE(
_In_ PRTL_AVL_TABLE Table,
_In_ _Post_invalid_ PVOID Buffer
);
typedef RTL_AVL_FREE_ROUTINE* PRTL_AVL_FREE_ROUTINE;
typedef _Function_class_(RTL_AVL_MATCH_FUNCTION)
NTSTATUS NTAPI RTL_AVL_MATCH_FUNCTION(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID UserData,
_In_ PVOID MatchData
);
typedef RTL_AVL_MATCH_FUNCTION* PRTL_AVL_MATCH_FUNCTION;
typedef struct _RTL_BALANCED_LINKS
{
struct _RTL_BALANCED_LINKS *Parent;
struct _RTL_BALANCED_LINKS *LeftChild;
struct _RTL_BALANCED_LINKS *RightChild;
CHAR Balance;
UCHAR Reserved[3];
} RTL_BALANCED_LINKS, *PRTL_BALANCED_LINKS;
typedef struct _RTL_AVL_TABLE
{
RTL_BALANCED_LINKS BalancedRoot;
PVOID OrderedPointer;
ULONG WhichOrderedElement;
ULONG NumberGenericTableElements;
ULONG DepthOfTree;
PRTL_BALANCED_LINKS RestartKey;
ULONG DeleteCount;
PRTL_AVL_COMPARE_ROUTINE CompareRoutine;
PRTL_AVL_ALLOCATE_ROUTINE AllocateRoutine;
PRTL_AVL_FREE_ROUTINE FreeRoutine;
PVOID TableContext;
} RTL_AVL_TABLE, *PRTL_AVL_TABLE;
/**
* The RtlInitializeGenericTableAvl routine initializes a generic AVL table.
*
* \param Table A pointer to the `RTL_AVL_TABLE` structure to be initialized.
* \param CompareRoutine A comparison routine to be used for comparing elements.
* \param AllocateRoutine An allocation routine to be used for allocating memory for the table.
* \param FreeRoutine A free routine to be used for freeing memory allocated for the table.
* \param TableContext A context to be passed to the comparison, allocation, and free routines.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlinitializegenerictableavl
*/
NTSYSAPI
VOID
NTAPI
RtlInitializeGenericTableAvl(
_Out_ PRTL_AVL_TABLE Table,
_In_ PRTL_AVL_COMPARE_ROUTINE CompareRoutine,
_In_ PRTL_AVL_ALLOCATE_ROUTINE AllocateRoutine,
_In_ PRTL_AVL_FREE_ROUTINE FreeRoutine,
_In_opt_ PVOID TableContext
);
/**
* The RtlInsertElementGenericTableAvl routine inserts an element into a generic AVL table.
*
* \param Table A pointer to the generic table.
* \param Buffer A pointer to the buffer containing the element to be inserted.
* \param BufferSize The size of the buffer.
* \param NewElement A pointer to a boolean that receives `TRUE` if the element was newly inserted, or `FALSE` if the element already existed.
* \return A pointer to the newly inserted or existing element.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlinsertelementgenerictableavl
*/
NTSYSAPI
PVOID
NTAPI
RtlInsertElementGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_reads_bytes_(BufferSize) PVOID Buffer,
_In_ CLONG BufferSize,
_Out_opt_ PBOOLEAN NewElement
);
/**
* The RtlInsertElementGenericTableFullAvl routine inserts an element into a generic AVL table.
*
* \param Table A pointer to the generic table.
* \param Buffer A pointer to the buffer containing the element to be inserted.
* \param BufferSize The size of the buffer.
* \param NewElement A pointer to a boolean that receives `TRUE` if the element was newly inserted, or `FALSE` if the element already existed.
* \param NodeOrParent A pointer to the node or parent for the insertion.
* \param SearchResult The result of the search for the insertion point.
* \return A pointer to the newly inserted or existing element.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlinsertelementgenerictablefullavl
*/
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
);
/**
* The RtlDeleteElementGenericTableAvl routine deletes an element from a generic AVL table.
*
* \param Table A pointer to the generic table.
* \param Buffer A pointer to the buffer containing the element to be deleted.
* \return `TRUE` if the element was deleted, otherwise `FALSE`.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtldeleteelementgenerictableavl
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlDeleteElementGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID Buffer
);
/**
* The RtlLookupElementGenericTableAvl routine looks up an element in a generic AVL table.
*
* \param Table A pointer to the generic table.
* \param Buffer A pointer to the buffer containing the element to look up.
* \return A pointer to the found element, or `NULL` if the element was not found.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtllookupelementgenerictableavl
*/
_Check_return_
NTSYSAPI
PVOID
NTAPI
RtlLookupElementGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID Buffer
);
/**
* The RtlLookupElementGenericTableFullAvl routine looks up an element in a generic AVL table.
*
* \param Table A pointer to the generic table.
* \param Buffer A pointer to the buffer containing the element to look up.
* \param NodeOrParent A pointer that receives the node or parent of the element.
* \param SearchResult A pointer that receives the result of the search.
* \return A pointer to the found element, or `NULL` if the element was not found.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtllookupelementgenerictablefullavl
*/
NTSYSAPI
PVOID
NTAPI
RtlLookupElementGenericTableFullAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID Buffer,
_Out_ PVOID *NodeOrParent,
_Out_ TABLE_SEARCH_RESULT *SearchResult
);
/**
* The RtlEnumerateGenericTableAvl routine enumerates the elements in a generic AVL table.
*
* \param Table A pointer to the generic table.
* \param Restart `TRUE` to restart the enumeration, `FALSE` to continue.
* \return A pointer to the next element in the table, or `NULL` if there are no more elements.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlenumerategenerictableavl
*/
_Check_return_
NTSYSAPI
PVOID
NTAPI
RtlEnumerateGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ BOOLEAN Restart
);
/**
* The RtlEnumerateGenericTableWithoutSplayingAvl routine enumerates the elements in a generic AVL table without splaying.
*
* \param Table A pointer to the generic table.
* \param RestartKey A pointer to a restart key.
* \return A pointer to the next element in the table, or `NULL` if there are no more elements.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlenumerategenerictablewithoutsplayingavl
*/
_Check_return_
NTSYSAPI
PVOID
NTAPI
RtlEnumerateGenericTableWithoutSplayingAvl(
_In_ PRTL_AVL_TABLE Table,
_Inout_ PVOID *RestartKey
);
/**
* The RtlLookupFirstMatchingElementGenericTableAvl routine looks up the first matching element in a generic AVL table.
*
* \param Table A pointer to the generic table.
* \param Buffer A pointer to the buffer containing the element to look up.
* \param RestartKey A pointer to a restart key.
* \return A pointer to the first matching element, or `NULL` if no matching element was found.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtllookupfirstmatchingelementgenerictableavl
*/
_Check_return_
NTSYSAPI
PVOID
NTAPI
RtlLookupFirstMatchingElementGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID Buffer,
_Out_ PVOID *RestartKey
);
/**
* The RtlEnumerateGenericTableLikeADirectory routine enumerates the elements in a generic AVL table like a directory.
*
* \param Table A pointer to the generic table.
* \param MatchFunction A match function to be used for comparing elements.
* \param MatchData A context to be passed to the match function.
* \param NextFlag A flag indicating whether to move to the next element.
* \param RestartKey A pointer to a restart key.
* \param DeleteCount A pointer to a counter for deleted elements.
* \param Buffer A pointer to the buffer containing the element to look up.
* \return A pointer to the next element in the table, or `NULL` if there are no more elements.
*/
_Check_return_
NTSYSAPI
PVOID
NTAPI
RtlEnumerateGenericTableLikeADirectory(
_In_ PRTL_AVL_TABLE Table,
_In_opt_ PRTL_AVL_MATCH_FUNCTION MatchFunction,
_In_opt_ PVOID MatchData,
_In_ ULONG NextFlag,
_Inout_ PVOID *RestartKey,
_Inout_ PULONG DeleteCount,
_In_ PVOID Buffer
);
/**
* The RtlGetElementGenericTableAvl routine gets an element from a generic AVL table by its index.
*
* \param Table A pointer to the generic table.
* \param I The index of the element to get.
* \return A pointer to the element, or `NULL` if the index is out of range.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlgetelementgenerictableavl
*/
_Check_return_
NTSYSAPI
PVOID
NTAPI
RtlGetElementGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ ULONG I
);
/**
* The RtlNumberGenericTableElementsAvl routine gets the number of elements in a generic AVL table.
*
* \param Table A pointer to the generic table.
* \return The number of elements in the table.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlnumbergenerictableelementsavl
*/
NTSYSAPI
ULONG
NTAPI
RtlNumberGenericTableElementsAvl(
_In_ PRTL_AVL_TABLE Table
);
/**
* The RtlIsGenericTableEmptyAvl routine determines whether a generic AVL table is empty.
*
* \param Table A pointer to the generic table.
* \return `TRUE` if the table is empty, otherwise `FALSE`.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlisgenerictableemptyavl
*/
_Check_return_
NTSYSAPI
BOOLEAN
NTAPI
RtlIsGenericTableEmptyAvl(
_In_ PRTL_AVL_TABLE Table
);
typedef struct _RTL_SPLAY_LINKS
{
struct _RTL_SPLAY_LINKS *Parent;
struct _RTL_SPLAY_LINKS *LeftChild;
struct _RTL_SPLAY_LINKS *RightChild;
} RTL_SPLAY_LINKS, *PRTL_SPLAY_LINKS;
#define RtlInitializeSplayLinks(Links) \
{ \
PRTL_SPLAY_LINKS _SplayLinks; \
_SplayLinks = (PRTL_SPLAY_LINKS)(Links); \
_SplayLinks->Parent = _SplayLinks; \
_SplayLinks->LeftChild = NULL; \
_SplayLinks->RightChild = NULL; \
}
#define RtlParent(Links) ((PRTL_SPLAY_LINKS)(Links)->Parent)
#define RtlLeftChild(Links) ((PRTL_SPLAY_LINKS)(Links)->LeftChild)
#define RtlRightChild(Links) ((PRTL_SPLAY_LINKS)(Links)->RightChild)
#define RtlIsRoot(Links) ((RtlParent(Links) == (PRTL_SPLAY_LINKS)(Links)))
#define RtlIsLeftChild(Links) ((RtlLeftChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)))
#define RtlIsRightChild(Links) ((RtlRightChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)))
#define RtlInsertAsLeftChild(ParentLinks, ChildLinks) \
{ \
PRTL_SPLAY_LINKS _SplayParent; \
PRTL_SPLAY_LINKS _SplayChild; \
_SplayParent = (PRTL_SPLAY_LINKS)(ParentLinks); \
_SplayChild = (PRTL_SPLAY_LINKS)(ChildLinks); \
_SplayParent->LeftChild = _SplayChild; \
_SplayChild->Parent = _SplayParent; \
}
#define RtlInsertAsRightChild(ParentLinks, ChildLinks) \
{ \
PRTL_SPLAY_LINKS _SplayParent; \
PRTL_SPLAY_LINKS _SplayChild; \
_SplayParent = (PRTL_SPLAY_LINKS)(ParentLinks); \
_SplayChild = (PRTL_SPLAY_LINKS)(ChildLinks); \
_SplayParent->RightChild = _SplayChild; \
_SplayChild->Parent = _SplayParent; \
}
/**
* The RtlSplay routine performs a splay operation on a splay tree.
*
* \param Links A pointer to the splay links of the node to splay.
* \return A pointer to the new root of the splay tree.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlsplay
*/
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlSplay(
_Inout_ PRTL_SPLAY_LINKS Links
);
/**
* The RtlDelete routine deletes a node from a splay tree.
*
* \param Links A pointer to the splay links of the node to delete.
* \return A pointer to the new root of the splay tree.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtldelete
*/
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlDelete(
_In_ PRTL_SPLAY_LINKS Links
);
/**
* The RtlDeleteNoSplay routine deletes a node from a splay tree without splaying.
*
* \param Links A pointer to the splay links of the node to delete.
* \param Root A pointer to the root of the splay tree.
*/
NTSYSAPI
VOID
NTAPI
RtlDeleteNoSplay(
_In_ PRTL_SPLAY_LINKS Links,
_Inout_ PRTL_SPLAY_LINKS *Root
);
/**
* The RtlSubtreeSuccessor routine finds the successor of a node in a splay tree.
*
* \param Links A pointer to the splay links of the node.
* \return A pointer to the splay links of the successor node.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlsubtreesuccessor
*/
_Check_return_
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlSubtreeSuccessor(
_In_ PRTL_SPLAY_LINKS Links
);
/**
* The RtlSubtreePredecessor routine finds the predecessor of a node in a splay tree.
*
* \param Links A pointer to the splay links of the node.
* \return A pointer to the splay links of the predecessor node.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlsubtreepredecessor
*/
_Check_return_
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlSubtreePredecessor(
_In_ PRTL_SPLAY_LINKS Links
);
/**
* The RtlRealSuccessor routine finds the real successor of a node in a splay tree.
*
* \param Links A pointer to the splay links of the node.
* \return A pointer to the splay links of the real successor node.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlrealsuccessor
*/
_Check_return_
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlRealSuccessor(
_In_ PRTL_SPLAY_LINKS Links
);
/**
* The RtlRealPredecessor routine finds the real predecessor of a node in a splay tree.
*
* \param Links A pointer to the splay links of the node.
* \return A pointer to the splay links of the real predecessor node.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlrealpredecessor
*/
_Check_return_
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlRealPredecessor(
_In_ PRTL_SPLAY_LINKS Links
);
typedef struct _RTL_GENERIC_TABLE RTL_GENERIC_TABLE, *PRTL_GENERIC_TABLE;
typedef _Function_class_(RTL_GENERIC_COMPARE_ROUTINE)
RTL_GENERIC_COMPARE_RESULTS NTAPI RTL_GENERIC_COMPARE_ROUTINE(
_In_ PRTL_GENERIC_TABLE Table,
_In_ PVOID FirstStruct,
_In_ PVOID SecondStruct
);
typedef RTL_GENERIC_COMPARE_ROUTINE* PRTL_GENERIC_COMPARE_ROUTINE;
typedef _Function_class_(RTL_GENERIC_FREE_ROUTINE)
VOID NTAPI RTL_GENERIC_FREE_ROUTINE(
_In_ PRTL_GENERIC_TABLE Table,
_In_ _Post_invalid_ PVOID Buffer
);
typedef RTL_GENERIC_FREE_ROUTINE* PRTL_GENERIC_FREE_ROUTINE;
typedef _Function_class_(RTL_GENERIC_ALLOCATE_ROUTINE)
PVOID NTAPI RTL_GENERIC_ALLOCATE_ROUTINE(
_In_ PRTL_GENERIC_TABLE Table,
_In_ CLONG ByteSize
);
typedef RTL_GENERIC_ALLOCATE_ROUTINE* PRTL_GENERIC_ALLOCATE_ROUTINE;
typedef struct _RTL_GENERIC_TABLE
{
PRTL_SPLAY_LINKS TableRoot;
LIST_ENTRY InsertOrderList;
PLIST_ENTRY OrderedPointer;
ULONG WhichOrderedElement;
ULONG NumberGenericTableElements;
PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine;
PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine;
PRTL_GENERIC_FREE_ROUTINE FreeRoutine;
PVOID TableContext;
} RTL_GENERIC_TABLE, *PRTL_GENERIC_TABLE;
/**
* The RtlInitializeGenericTable routine initializes a generic table.
*
* \param Table A pointer to the `RTL_GENERIC_TABLE` structure to be initialized.
* \param CompareRoutine A comparison routine to be used for comparing elements.
* \param AllocateRoutine An allocation routine to be used for allocating memory for the table.
* \param FreeRoutine A free routine to be used for freeing memory allocated for the table.
* \param TableContext A context to be passed to the comparison, allocation, and free routines.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlinitializegenerictable
*/
NTSYSAPI
VOID
NTAPI
RtlInitializeGenericTable(
_Out_ PRTL_GENERIC_TABLE Table,
_In_ PRTL_GENERIC_COMPARE_ROUTINE CompareRoutine,
_In_ PRTL_GENERIC_ALLOCATE_ROUTINE AllocateRoutine,
_In_ PRTL_GENERIC_FREE_ROUTINE FreeRoutine,
_In_opt_ PVOID TableContext
);
/**
* The RtlInsertElementGenericTable routine inserts an element into a generic table.
*
* \param Table A pointer to the generic table.
* \param Buffer A pointer to the buffer containing the element to be inserted.
* \param BufferSize The size of the buffer.
* \param NewElement A pointer to a boolean that receives `TRUE` if the element was newly inserted, or `FALSE` if the element already existed.
* \return A pointer to the newly inserted or existing element.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlinsertelementgenerictable
*/
NTSYSAPI
PVOID
NTAPI
RtlInsertElementGenericTable(
_In_ PRTL_GENERIC_TABLE Table,
_In_reads_bytes_(BufferSize) PVOID Buffer,
_In_ CLONG BufferSize,
_Out_opt_ PBOOLEAN NewElement
);
/**
* The RtlInsertElementGenericTableFull routine inserts an element into a generic table.
*
* \param Table A pointer to the generic table.
* \param Buffer A pointer to the buffer containing the element to be inserted.
* \param BufferSize The size of the buffer.
* \param NewElement A pointer to a boolean that receives `TRUE` if the element was newly inserted, or `FALSE` if the element already existed.
* \param NodeOrParent A pointer to the node or parent for the insertion.
* \param SearchResult The result of the search for the insertion point.
* \return A pointer to the newly inserted or existing element.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlinsertelementgenerictablefull
*/
NTSYSAPI
PVOID
NTAPI
RtlInsertElementGenericTableFull(
_In_ PRTL_GENERIC_TABLE Table,
_In_reads_bytes_(BufferSize) PVOID Buffer,
_In_ CLONG BufferSize,
_Out_opt_ PBOOLEAN NewElement,
_In_ PVOID NodeOrParent,
_In_ TABLE_SEARCH_RESULT SearchResult
);
NTSYSAPI
BOOLEAN
NTAPI
RtlDeleteElementGenericTable(
_In_ PRTL_GENERIC_TABLE Table,
_In_ PVOID Buffer
);
_Check_return_
NTSYSAPI
PVOID
NTAPI
RtlLookupElementGenericTable(
_In_ PRTL_GENERIC_TABLE Table,
_In_ PVOID Buffer
);
NTSYSAPI
PVOID
NTAPI
RtlLookupElementGenericTableFull(
_In_ PRTL_GENERIC_TABLE Table,
_In_ PVOID Buffer,
_Out_ PVOID *NodeOrParent,
_Out_ TABLE_SEARCH_RESULT *SearchResult
);
_Check_return_
NTSYSAPI
PVOID
NTAPI
RtlEnumerateGenericTable(
_In_ PRTL_GENERIC_TABLE Table,
_In_ BOOLEAN Restart
);
_Check_return_
NTSYSAPI
PVOID
NTAPI
RtlEnumerateGenericTableWithoutSplaying(
_In_ PRTL_GENERIC_TABLE Table,
_Inout_ PVOID *RestartKey
);
_Check_return_
NTSYSAPI
PVOID
NTAPI
RtlGetElementGenericTable(
_In_ PRTL_GENERIC_TABLE Table,
_In_ ULONG I
);
NTSYSAPI
ULONG
NTAPI
RtlNumberGenericTableElements(
_In_ PRTL_GENERIC_TABLE Table
);
_Check_return_
NTSYSAPI
BOOLEAN
NTAPI
RtlIsGenericTableEmpty(
_In_ PRTL_GENERIC_TABLE Table
);
//
// RB trees
//
typedef struct _RTL_RB_TREE
{
PRTL_BALANCED_NODE Root;
union
{
UCHAR Encoded : 1;
PRTL_BALANCED_NODE Min;
};
} RTL_RB_TREE, *PRTL_RB_TREE;
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlRbInsertNodeEx(
_In_ PRTL_RB_TREE Tree,
_In_opt_ PRTL_BALANCED_NODE Parent,
_In_ BOOLEAN Right,
_Out_ PRTL_BALANCED_NODE Node
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlRbRemoveNode(
_In_ PRTL_RB_TREE Tree,
_In_ PRTL_BALANCED_NODE Node
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCompareExchangePointerMapping(
_In_ PRTL_BALANCED_NODE Node1,
_In_ PRTL_BALANCED_NODE Node2,
_Out_ PRTL_BALANCED_NODE *Node3,
_Out_ PRTL_BALANCED_NODE *Node4
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryPointerMapping(
_In_ PRTL_RB_TREE Tree,
_Inout_ PRTL_BALANCED_NODE Children
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlRemovePointerMapping(
_In_ PRTL_RB_TREE Tree,
_Inout_ PRTL_BALANCED_NODE Children
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
//
// Hash tables
//
// begin_ntddk
#define RTL_HASH_ALLOCATED_HEADER 0x00000001
#define RTL_HASH_RESERVED_SIGNATURE 0
typedef struct _RTL_DYNAMIC_HASH_TABLE_ENTRY
{
LIST_ENTRY Linkage;
ULONG_PTR Signature;
} RTL_DYNAMIC_HASH_TABLE_ENTRY, *PRTL_DYNAMIC_HASH_TABLE_ENTRY;
#define HASH_ENTRY_KEY(x) ((x)->Signature)
typedef struct _RTL_DYNAMIC_HASH_TABLE_CONTEXT
{
PLIST_ENTRY ChainHead;
PLIST_ENTRY PrevLinkage;
ULONG_PTR Signature;
} RTL_DYNAMIC_HASH_TABLE_CONTEXT, *PRTL_DYNAMIC_HASH_TABLE_CONTEXT;
typedef struct _RTL_DYNAMIC_HASH_TABLE_ENUMERATOR
{
union
{
RTL_DYNAMIC_HASH_TABLE_ENTRY HashEntry;
PLIST_ENTRY CurEntry;
};
PLIST_ENTRY ChainHead;
ULONG BucketIndex;
} RTL_DYNAMIC_HASH_TABLE_ENUMERATOR, *PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR;
typedef struct _RTL_DYNAMIC_HASH_TABLE
{
// Entries initialized at creation.
ULONG Flags;
ULONG Shift;
// Entries used in bucket computation.
ULONG TableSize;
ULONG Pivot;
ULONG DivisorMask;
// Counters.
ULONG NumEntries;
ULONG NonEmptyBuckets;
ULONG NumEnumerators;
// The directory. This field is for internal use only.
PVOID Directory;
} RTL_DYNAMIC_HASH_TABLE, *PRTL_DYNAMIC_HASH_TABLE;
FORCEINLINE
VOID
NTAPI_INLINE
RtlInitHashTableContext(
_Inout_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context
)
{
Context->ChainHead = NULL;
Context->PrevLinkage = NULL;
}
FORCEINLINE
VOID
NTAPI_INLINE
RtlInitHashTableContextFromEnumerator(
_Inout_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context,
_In_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
)
{
Context->ChainHead = Enumerator->ChainHead;
Context->PrevLinkage = Enumerator->HashEntry.Linkage.Blink;
}
FORCEINLINE
VOID
NTAPI_INLINE
RtlReleaseHashTableContext(
_Inout_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context
)
{
UNREFERENCED_PARAMETER(Context);
return;
}
FORCEINLINE
ULONG
NTAPI_INLINE
RtlTotalBucketsHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
)
{
return HashTable->TableSize;
}
FORCEINLINE
ULONG
NTAPI_INLINE
RtlNonEmptyBucketsHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
)
{
return HashTable->NonEmptyBuckets;
}
FORCEINLINE
ULONG
NTAPI_INLINE
RtlEmptyBucketsHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
)
{
return HashTable->TableSize - HashTable->NonEmptyBuckets;
}
FORCEINLINE
ULONG
NTAPI_INLINE
RtlTotalEntriesHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
)
{
return HashTable->NumEntries;
}
FORCEINLINE
ULONG
NTAPI_INLINE
RtlActiveEnumeratorsHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
)
{
return HashTable->NumEnumerators;
}
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlCreateHashTable(
_Inout_ _When_(*HashTable == NULL, __drv_allocatesMem(Mem)) PRTL_DYNAMIC_HASH_TABLE *HashTable,
_In_ ULONG Shift,
_In_ _Reserved_ ULONG Flags
);
_Must_inspect_result_
_Success_(return != 0)
NTSYSAPI
BOOLEAN
NTAPI
RtlCreateHashTableEx(
_Inout_ _When_(NULL == *HashTable, _At_(*HashTable, __drv_allocatesMem(Mem))) PRTL_DYNAMIC_HASH_TABLE *HashTable,
_In_ ULONG InitialSize,
_In_ ULONG Shift,
_Reserved_ ULONG Flags
);
NTSYSAPI
LOGICAL
NTAPI
RtlDeleteHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
);
NTSYSAPI
BOOLEAN
NTAPI
RtlInsertEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_In_ PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry,
_In_ ULONG_PTR Signature,
_Inout_opt_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context
);
NTSYSAPI
BOOLEAN
NTAPI
RtlRemoveEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_In_ PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry,
_Inout_opt_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context
);
_Must_inspect_result_
NTSYSAPI
PRTL_DYNAMIC_HASH_TABLE_ENTRY
NTAPI
RtlLookupEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_In_ ULONG_PTR Signature,
_Out_opt_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context
);
_Must_inspect_result_
NTSYSAPI
PRTL_DYNAMIC_HASH_TABLE_ENTRY
NTAPI
RtlGetNextEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_In_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context
);
NTSYSAPI
BOOLEAN
NTAPI
RtlInitEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Out_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
_Must_inspect_result_
NTSYSAPI
PRTL_DYNAMIC_HASH_TABLE_ENTRY
NTAPI
RtlEnumerateEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
NTSYSAPI
VOID
NTAPI
RtlEndEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
NTSYSAPI
BOOLEAN
NTAPI
RtlInitWeakEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Out_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
_Must_inspect_result_
NTSYSAPI
PRTL_DYNAMIC_HASH_TABLE_ENTRY
NTAPI
RtlWeaklyEnumerateEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
NTSYSAPI
VOID
NTAPI
RtlEndWeakEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
NTSYSAPI
BOOLEAN
NTAPI
RtlExpandHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
);
NTSYSAPI
BOOLEAN
NTAPI
RtlContractHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
NTSYSAPI
BOOLEAN
NTAPI
RtlInitStrongEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Out_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
_Must_inspect_result_
NTSYSAPI
PRTL_DYNAMIC_HASH_TABLE_ENTRY
NTAPI
RtlStronglyEnumerateEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
NTSYSAPI
VOID
NTAPI
RtlEndStrongEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
// end_ntddk
//
// Critical sections
//
// These flags define the upper byte of the critical section SpinCount field
#define RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO 0x01000000
#define RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN 0x02000000
#define RTL_CRITICAL_SECTION_FLAG_STATIC_INIT 0x04000000
#define RTL_CRITICAL_SECTION_FLAG_RESOURCE_TYPE 0x08000000
#define RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO 0x10000000
#define RTL_CRITICAL_SECTION_ALL_FLAG_BITS 0xFF000000
#define RTL_CRITICAL_SECTION_FLAG_RESERVED (RTL_CRITICAL_SECTION_ALL_FLAG_BITS & (~(RTL_CRITICAL_SECTION_FLAG_NO_DEBUG_INFO | RTL_CRITICAL_SECTION_FLAG_DYNAMIC_SPIN | RTL_CRITICAL_SECTION_FLAG_STATIC_INIT | RTL_CRITICAL_SECTION_FLAG_RESOURCE_TYPE | RTL_CRITICAL_SECTION_FLAG_FORCE_DEBUG_INFO)))
// These flags define possible values stored in the Flags field of a critsec debuginfo.
#define RTL_CRITICAL_SECTION_DEBUG_FLAG_STATIC_INIT 0x00000001
// typedef struct _RTL_CRITICAL_SECTION_DEBUG
// {
// USHORT Type;
// USHORT CreatorBackTraceIndex;
// struct _RTL_CRITICAL_SECTION *CriticalSection;
// LIST_ENTRY ProcessLocksList;
// ULONG EntryCount;
// ULONG ContentionCount;
// ULONG Flags;
// USHORT CreatorBackTraceIndexHigh;
// USHORT Identifier;
// } RTL_CRITICAL_SECTION_DEBUG, *PRTL_CRITICAL_SECTION_DEBUG, RTL_RESOURCE_DEBUG, *PRTL_RESOURCE_DEBUG;
//
// #pragma pack(push, 8)
// typedef struct _RTL_CRITICAL_SECTION
// {
// PRTL_CRITICAL_SECTION_DEBUG DebugInfo;
// LONG LockCount;
// LONG RecursionCount;
// HANDLE OwningThread;
// HANDLE LockSemaphore;
// SIZE_T SpinCount;
// } RTL_CRITICAL_SECTION, *PRTL_CRITICAL_SECTION;
// #pragma pack(pop)
/**
* The RtlInitializeCriticalSection routine initializes a critical section object.
*
* \param CriticalSection A pointer to the critical section object.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initializecriticalsection
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeCriticalSection(
_Out_ PRTL_CRITICAL_SECTION CriticalSection
);
/**
* The RtlInitializeCriticalSectionAndSpinCount routine initializes a critical section object and sets the spin count for the critical section.
*
* \param CriticalSection A pointer to the critical section object.
* \param SpinCount The spin count for the critical section object. On single-processor systems, the spin count is ignored.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initializecriticalsectionandspincount
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeCriticalSectionAndSpinCount(
_Out_ PRTL_CRITICAL_SECTION CriticalSection,
_In_ ULONG SpinCount
);
/**
* The RtlInitializeCriticalSectionEx routine initializes a critical section object and sets the spin count for the critical section with flags.
*
* \param CriticalSection A pointer to the critical section object.
* \param SpinCount The spin count for the critical section object. On single-processor systems, the spin count is ignored.
* \param Flags This parameter can be 0 or the CRITICAL_SECTION_NO_DEBUG_INFO flag.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initializecriticalsectionex
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeCriticalSectionEx(
_Out_ PRTL_CRITICAL_SECTION CriticalSection,
_In_ ULONG SpinCount,
_In_ ULONG Flags
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteCriticalSection(
_Inout_ PRTL_CRITICAL_SECTION CriticalSection
);
_Acquires_exclusive_lock_(*CriticalSection)
NTSYSAPI
NTSTATUS
NTAPI
RtlEnterCriticalSection(
_Inout_ PRTL_CRITICAL_SECTION CriticalSection
);
_Releases_exclusive_lock_(*CriticalSection)
NTSYSAPI
NTSTATUS
NTAPI
RtlLeaveCriticalSection(
_Inout_ PRTL_CRITICAL_SECTION CriticalSection
);
_When_(return != 0, _Acquires_exclusive_lock_(*CriticalSection))
NTSYSAPI
LOGICAL
NTAPI
RtlTryEnterCriticalSection(
_Inout_ PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
LOGICAL
NTAPI
RtlIsCriticalSectionLocked(
_In_ PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
LOGICAL
NTAPI
RtlIsCriticalSectionLockedByThread(
_In_ PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
ULONG
NTAPI
RtlGetCriticalSectionRecursionCount(
_In_ PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
ULONG
NTAPI
RtlSetCriticalSectionSpinCount(
_Inout_ PRTL_CRITICAL_SECTION CriticalSection,
_In_ ULONG SpinCount
);
NTSYSAPI
HANDLE
NTAPI
RtlQueryCriticalSectionOwner(
_In_ HANDLE EventHandle,
_In_ BOOLEAN ExactMatchOwnerAddress
);
NTSYSAPI
VOID
NTAPI
RtlCheckForOrphanedCriticalSections(
_In_ HANDLE ThreadHandle
);
/**
* Enables the creation of early critical section events.
*
* This function allows the system to create critical section events early in the process
* initialization. It is typically used to ensure that critical sections are properly
* initialized and can be used safely during the early stages of process startup.
* \remarks This function sets the FLG_CRITSEC_EVENT_CREATION flag in the PEB flags field.
* \return A pointer to the Process Environment Block (PEB).
*/
NTSYSAPI
PPEB
NTAPI
RtlEnableEarlyCriticalSectionEventCreation(
VOID
);
//
// Resources
//
typedef struct _RTL_RESOURCE
{
RTL_CRITICAL_SECTION CriticalSection;
HANDLE SharedSemaphore;
volatile ULONG NumberOfWaitingShared;
HANDLE ExclusiveSemaphore;
volatile ULONG NumberOfWaitingExclusive;
volatile LONG NumberOfActive; // negative: exclusive acquire; zero: not acquired; positive: shared acquire(s)
HANDLE ExclusiveOwnerThread;
ULONG Flags; // RTL_RESOURCE_FLAG_*
PRTL_RESOURCE_DEBUG DebugInfo;
} RTL_RESOURCE, *PRTL_RESOURCE;
#define RTL_RESOURCE_FLAG_LONG_TERM ((ULONG)0x00000001)
NTSYSAPI
VOID
NTAPI
RtlInitializeResource(
_Out_ PRTL_RESOURCE Resource
);
NTSYSAPI
VOID
NTAPI
RtlDeleteResource(
_Inout_ PRTL_RESOURCE Resource
);
NTSYSAPI
BOOLEAN
NTAPI
RtlAcquireResourceShared(
_Inout_ PRTL_RESOURCE Resource,
_In_ BOOLEAN Wait
);
NTSYSAPI
BOOLEAN
NTAPI
RtlAcquireResourceExclusive(
_Inout_ PRTL_RESOURCE Resource,
_In_ BOOLEAN Wait
);
NTSYSAPI
VOID
NTAPI
RtlReleaseResource(
_Inout_ PRTL_RESOURCE Resource
);
NTSYSAPI
VOID
NTAPI
RtlConvertSharedToExclusive(
_Inout_ PRTL_RESOURCE Resource
);
NTSYSAPI
VOID
NTAPI
RtlConvertExclusiveToShared(
_Inout_ PRTL_RESOURCE Resource
);
NTSYSAPI
ULONG
NTAPI
RtlDumpResource(
_Inout_ PRTL_RESOURCE Resource
);
//
// Slim reader-writer locks, condition variables, and barriers
//
#ifndef RTL_SRWLOCK_INIT
#define RTL_SRWLOCK_INIT {0}
#endif
// winbase:InitializeSRWLock
/**
* The RtlInitializeSRWLock routine initializes a slim reader/writer (SRW) lock.
*
* \param SRWLock A pointer to the SRW lock.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-initializesrwlock
*/
NTSYSAPI
VOID
NTAPI
RtlInitializeSRWLock(
_Out_ PRTL_SRWLOCK SRWLock
);
// winbase:AcquireSRWLockExclusive
_Acquires_exclusive_lock_(*SRWLock)
NTSYSAPI
VOID
NTAPI
RtlAcquireSRWLockExclusive(
_Inout_ PRTL_SRWLOCK SRWLock
);
// winbase:AcquireSRWLockShared
_Acquires_shared_lock_(*SRWLock)
NTSYSAPI
VOID
NTAPI
RtlAcquireSRWLockShared(
_Inout_ PRTL_SRWLOCK SRWLock
);
// winbase:ReleaseSRWLockExclusive
_Releases_exclusive_lock_(*SRWLock)
NTSYSAPI
VOID
NTAPI
RtlReleaseSRWLockExclusive(
_Inout_ PRTL_SRWLOCK SRWLock
);
// winbase:ReleaseSRWLockShared
_Releases_shared_lock_(*SRWLock)
NTSYSAPI
VOID
NTAPI
RtlReleaseSRWLockShared(
_Inout_ PRTL_SRWLOCK SRWLock
);
// winbase:TryAcquireSRWLockExclusive
_When_(return != 0, _Acquires_exclusive_lock_(*SRWLock))
NTSYSAPI
BOOLEAN
NTAPI
RtlTryAcquireSRWLockExclusive(
_Inout_ PRTL_SRWLOCK SRWLock
);
// winbase:TryAcquireSRWLockShared
_When_(return != 0, _Acquires_shared_lock_(*SRWLock))
NTSYSAPI
BOOLEAN
NTAPI
RtlTryAcquireSRWLockShared(
_Inout_ PRTL_SRWLOCK SRWLock
);
// rev
NTSYSAPI
VOID
NTAPI
RtlAcquireReleaseSRWLockExclusive(
_Inout_ PRTL_SRWLOCK SRWLock
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlConvertSRWLockExclusiveToShared(
_Inout_ PRTL_SRWLOCK SRWLock
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
//
// Read-Copy-Update (RCU).
//
// RCU synchronization allows concurrent access to shared data structures,
// such as linked lists, trees, or hash tables, without using traditional locking methods
// in scenarios where read operations are frequent and need to be fast.
// It is particularly useful in multi-threaded environments where multiple threads
// may read from the same data structure while one or more threads may modify it.
// @remarks RCU synchronization is not for general-purpose synchronization.
// Teb->Rcu is used to store the RCU state.
#if defined(PHNT_NATIVE_RCU)
// rev
typedef struct _RTL_RCU_SEGMENT
{
ULONG Count;
ULONG Reserved; // padding/unused
PVOID Slots[ANYSIZE_ARRAY];
//
// Interpretation (x64):
// Slots[0 .. Count-1] = RTL_RCU_THREAD_ENTRY* (or NULL)
// Slots[Count] = RTL_RCU_SEGMENT* link to next segment (or NULL)
//
} RTL_RCU_SEGMENT, *PRTL_RCU_SEGMENT;
// Helper for the address of link slot (the "next segment pointer")
#define RTL_RCU_SEGMENT_NEXT_PTR(S) ((PRTL_RCU_SEGMENT*)&((S)->Slots[(S)->Count]))
// rev
typedef struct _RTL_RCU_THREAD_ENTRY
{
volatile ULONGLONG ReadDepth;
ULONG ThreadCookie; // compared with TEB cached cookie
ULONG ThreadIdLike; // compared with TEB cached id
volatile ULONGLONG SeenEpoch; // WaitOnAddress/WakeAddressAll target
struct _RTL_RCU_THREAD_ENTRY* Next; // linked via State->ThreadList
} RTL_RCU_THREAD_ENTRY, *PRTL_RCU_THREAD_ENTRY;
C_ASSERT(sizeof(RTL_RCU_THREAD_ENTRY) == 0x20);
C_ASSERT(FIELD_OFFSET(RTL_RCU_THREAD_ENTRY, SeenEpoch) == 0x10);
//typedef struct _RTL_RCU_THREAD_ENTRY RTL_RCU_THREAD_ENTRY, *PRTL_RCU_THREAD_ENTRY;
//typedef struct _RTL_RCU_SEGMENT RTL_RCU_SEGMENT, *PRTL_RCU_SEGMENT;
// rev
typedef struct _RTL_RCU_STATE
{
//
// Global list links (inserted by RtlRcuAllocate under a global SRW lock).
//
struct _RTL_RCU_STATE *GlobalNext;
struct _RTL_RCU_STATE *GlobalPrev;
//
// Global epoch/state.
//
volatile ULONGLONG Epoch;
//
// Segmented array root used by RtlpRcuCurrentThreadData()
// to map "thread-id-like" (ebx) -> RTL_RCU_THREAD_ENTRY*.
//
PRTL_RCU_SEGMENT SegmentRoot;
//
// Singly-linked list of all per-thread entries for this state.
// synchronize walks this list and waits on each entry->SeenEpoch.
//
PRTL_RCU_THREAD_ENTRY ThreadList;
//
// Small cache indexed by (ebx % 10) (the 0xCCCCCCCD multiply trick).
//
PRTL_RCU_THREAD_ENTRY Cache[10];
//
// Slow-path SRW lock used when RtlpRcuCurrentThreadData() returns NULL.
// - ReadLock uses AcquireSRWLockShared(&state+0x78)
// - Synchronize uses Acquire/Release Exclusive on &state+0x78 (via helper)
//
RTL_SRWLOCK SlowPathLock;
//
// Stored from RtlRcuAllocate(ecx)
//
ULONG TagOrFlags;
ULONG Padding; // (to make sizeof == 0x88 on x64)
} RTL_RCU_STATE, *PRTL_RCU_STATE;
// Sanity checks (x64)
C_ASSERT(sizeof(RTL_RCU_STATE) == 0x88);
typedef struct _RTL_RCU_COOKIE
{
ULONG_PTR ThreadEntryOrNull; // NULL => slow-path SRW shared lock was used
} RTL_RCU_COOKIE, *PRTL_RCU_COOKIE;
#else
typedef struct _RTL_RCU_STATE RTL_RCU_STATE, *PRTL_RCU_STATE;
typedef ULONG_PTR RTL_RCU_COOKIE, *PRTL_RCU_COOKIE;
#endif // #if defined(PHNT_NATIVE_RCU)
NTSYSAPI
PRTL_RCU_STATE
NTAPI
RtlRcuAllocate(
_In_ ULONG Flags
);
NTSYSAPI
LOGICAL
NTAPI
RtlRcuFree(
_In_ PRTL_RCU_STATE State
);
NTSYSAPI
VOID
NTAPI
RtlRcuReadLock(
_Inout_ PRTL_RCU_STATE State,
_Out_ PRTL_RCU_COOKIE Cookie
);
NTSYSAPI
VOID
NTAPI
RtlRcuReadUnlock(
_Inout_ PRTL_RCU_STATE State,
_Inout_ PRTL_RCU_COOKIE Cookie
);
NTSYSAPI
LONG
NTAPI
RtlRcuSynchronize(
_Inout_ PRTL_RCU_STATE State
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
#define RTL_CONDITION_VARIABLE_INIT {0}
#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 0x1
// winbase:InitializeConditionVariable
NTSYSAPI
VOID
NTAPI
RtlInitializeConditionVariable(
_Out_ PRTL_CONDITION_VARIABLE ConditionVariable
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSleepConditionVariableCS(
_Inout_ PRTL_CONDITION_VARIABLE ConditionVariable,
_Inout_ PRTL_CRITICAL_SECTION CriticalSection,
_In_opt_ PLARGE_INTEGER Timeout
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSleepConditionVariableSRW(
_Inout_ PRTL_CONDITION_VARIABLE ConditionVariable,
_Inout_ PRTL_SRWLOCK SRWLock,
_In_opt_ PLARGE_INTEGER Timeout,
_In_ ULONG Flags
);
// winbase:WakeConditionVariable
NTSYSAPI
VOID
NTAPI
RtlWakeConditionVariable(
_Inout_ PRTL_CONDITION_VARIABLE ConditionVariable
);
// winbase:WakeAllConditionVariable
NTSYSAPI
VOID
NTAPI
RtlWakeAllConditionVariable(
_Inout_ PRTL_CONDITION_VARIABLE ConditionVariable
);
// begin_rev
#define RTL_BARRIER_FLAGS_SPIN_ONLY 0x00000001 // never block on event - always spin
#define RTL_BARRIER_FLAGS_BLOCK_ONLY 0x00000002 // always block on event - never spin
#define RTL_BARRIER_FLAGS_NO_DELETE 0x00000004 // use if barrier will never be deleted
// end_rev
// begin_private
NTSYSAPI
NTSTATUS
NTAPI
RtlInitBarrier(
_Out_ PRTL_BARRIER Barrier,
_In_ ULONG TotalThreads,
_In_ ULONG SpinCount
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteBarrier(
_In_ PRTL_BARRIER Barrier
);
NTSYSAPI
BOOLEAN
NTAPI
RtlBarrier(
_Inout_ PRTL_BARRIER Barrier,
_In_ ULONG Flags
);
NTSYSAPI
BOOLEAN
NTAPI
RtlBarrierForDelete(
_Inout_ PRTL_BARRIER Barrier,
_In_ ULONG Flags
);
// end_private
//
// Wait on address
//
// begin_rev
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
/**
* The RtlWaitOnAddress routine waits for the value at the specified address to change.
*
* \param Address The address on which to wait.
* \param CompareAddress A pointer to the location of the previously observed value at Address.
* \param AddressSize The size of the value, in bytes. This parameter can be 1, 2, 4, or 8.
* \param Timeout The number of milliseconds to wait before the operation times out. If this parameter is NULL (INFINITE), the thread waits indefinitely.
* \remarks WaitOnAddress is guaranteed to return when the address is signaled, but it is also allowed to return for other reasons.
* For this reason, the caller should compare the new value with the original undesired value to confirm that the value has actually changed.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitonaddress
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlWaitOnAddress(
_In_reads_bytes_(AddressSize) volatile VOID *Address,
_In_reads_bytes_(AddressSize) PVOID CompareAddress,
_In_ SIZE_T AddressSize,
_In_opt_ PLARGE_INTEGER Timeout
);
/**
* The RtlWakeAddressAll routine wakes all threads that are waiting for the value of an address to change.
*
* \param Address The address to signal. If any threads have previously called RtlWaitOnAddress for this address, the system wakes all of the waiting threads.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-wakebyaddressall
*/
NTSYSAPI
VOID
NTAPI
RtlWakeAddressAll(
_In_ PVOID Address
);
/**
* The RtlWakeAddressAllNoFence routine wakes all threads that are waiting for the value of an address to change.
*
* \param Address The address to signal. If any threads have previously called RtlWaitOnAddress for this address, the system wakes all of the waiting threads.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-wakebyaddressall
*/
NTSYSAPI
VOID
NTAPI
RtlWakeAddressAllNoFence(
_In_ PVOID Address
);
/**
* The RtlWakeAddressSingle routine wakes one thread that is waiting for the value of an address to change.
*
* \param Address The address to signal.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-wakebyaddresssingle
*/
NTSYSAPI
VOID
NTAPI
RtlWakeAddressSingle(
_In_ PVOID Address
);
/**
* The RtlWakeAddressSingleNoFence routine wakes one thread that is waiting for the value of an address to change.
*
* \param Address The address to signal.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-wakebyaddresssingle
*/
NTSYSAPI
VOID
NTAPI
RtlWakeAddressSingleNoFence(
_In_ PVOID Address
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
// end_rev
//
// Strings
//
_At_(AnsiString->Buffer, _Post_equal_to_(Buffer))
_At_(AnsiString->Length, _Post_equal_to_(0))
_At_(AnsiString->MaximumLength, _Post_equal_to_(MaximumLength))
FORCEINLINE
VOID
NTAPI_INLINE
RtlInitEmptyAnsiString(
_Out_ PANSI_STRING AnsiString,
_Pre_maybenull_ _Pre_readable_size_(MaximumLength) __drv_aliasesMem PCHAR Buffer,
_In_ USHORT MaximumLength
)
{
memset(AnsiString, 0, sizeof(ANSI_STRING));
AnsiString->MaximumLength = MaximumLength;
AnsiString->Buffer = Buffer;
}
#ifndef PHNT_NO_INLINE_INIT_STRING
FORCEINLINE
VOID
NTAPI_INLINE
RtlInitString(
_Out_ PSTRING DestinationString,
_In_opt_z_ PCSTR SourceString
)
{
if (SourceString)
DestinationString->MaximumLength = (DestinationString->Length = (USHORT)strlen(SourceString)) + sizeof(ANSI_NULL);
else
DestinationString->MaximumLength = DestinationString->Length = 0;
DestinationString->Buffer = (PCHAR)SourceString;
}
#else
NTSYSAPI
VOID
NTAPI
RtlInitString(
_Out_ PSTRING DestinationString,
_In_opt_z_ PCSTR SourceString
);
#endif // PHNT_NO_INLINE_INIT_STRING
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
NTSYSAPI
NTSTATUS
NTAPI
RtlInitStringEx(
_Out_ PSTRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCSZ SourceString
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
#ifndef PHNT_NO_INLINE_INIT_STRING
FORCEINLINE
VOID
NTAPI_INLINE
RtlInitAnsiString(
_Out_ PANSI_STRING DestinationString,
_In_opt_z_ PCSTR SourceString
)
{
if (SourceString)
DestinationString->MaximumLength = (DestinationString->Length = (USHORT)strlen(SourceString)) + sizeof(ANSI_NULL);
else
DestinationString->MaximumLength = DestinationString->Length = 0;
DestinationString->Buffer = (PCHAR)SourceString;
}
#else
NTSYSAPI
VOID
NTAPI
RtlInitAnsiString(
_Out_ PANSI_STRING DestinationString,
_In_opt_z_ PCSTR SourceString
);
#endif // PHNT_NO_INLINE_INIT_STRING
NTSYSAPI
NTSTATUS
NTAPI
RtlInitAnsiStringEx(
_Out_ PANSI_STRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCSZ SourceString
);
NTSYSAPI
VOID
NTAPI
RtlFreeAnsiString(
_Inout_ _At_(AnsiString->Buffer, _Frees_ptr_opt_) PANSI_STRING AnsiString
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_20H1)
NTSYSAPI
VOID
NTAPI
RtlInitUTF8String(
_Out_ PUTF8_STRING DestinationString,
_In_opt_z_ PCSZ SourceString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlInitUTF8StringEx(
_Out_ PUTF8_STRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCSZ SourceString
);
NTSYSAPI
VOID
NTAPI
RtlFreeUTF8String(
_Inout_ _At_(Utf8String->Buffer, _Frees_ptr_opt_) PUTF8_STRING Utf8String
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_20H1
NTSYSAPI
VOID
NTAPI
RtlFreeOemString(
_Inout_ POEM_STRING OemString
);
NTSYSAPI
VOID
NTAPI
RtlCopyString(
_In_ PSTRING DestinationString,
_In_opt_ PSTRING SourceString
);
NTSYSAPI
CHAR
NTAPI
RtlUpperChar(
_In_ CHAR Character
);
_Must_inspect_result_
NTSYSAPI
LONG
NTAPI
RtlCompareString(
_In_ PSTRING String1,
_In_ PSTRING String2,
_In_ BOOLEAN CaseInSensitive
);
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualString(
_In_ PSTRING String1,
_In_ PSTRING String2,
_In_ BOOLEAN CaseInSensitive
);
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlPrefixString(
_In_ PSTRING String1,
_In_ PSTRING String2,
_In_ BOOLEAN CaseInSensitive
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendStringToString(
_Inout_ PSTRING Destination,
_In_ PSTRING Source
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendAsciizToString(
_Inout_ PSTRING Destination,
_In_opt_z_ PCSTR Source
);
NTSYSAPI
VOID
NTAPI
RtlUpperString(
_Inout_ PSTRING DestinationString,
_In_ const STRING* SourceString
);
FORCEINLINE
BOOLEAN
NTAPI_INLINE
RtlIsNullOrEmptyUnicodeString(
_In_opt_ PCUNICODE_STRING String
)
{
return !String || String->Length == 0;
}
_At_(DestinationString->Buffer, _Post_equal_to_(Buffer))
_At_(DestinationString->Length, _Post_equal_to_(0))
_At_(DestinationString->MaximumLength, _Post_equal_to_(MaximumLength))
FORCEINLINE
VOID
NTAPI_INLINE
RtlInitEmptyUnicodeString(
_Out_ PUNICODE_STRING DestinationString,
_Writable_bytes_(MaximumLength) _When_(MaximumLength != 0, _Notnull_) __drv_aliasesMem PWCHAR Buffer,
_In_ USHORT MaximumLength
)
{
memset(DestinationString, 0, sizeof(UNICODE_STRING));
DestinationString->MaximumLength = MaximumLength;
DestinationString->Buffer = Buffer;
}
#ifndef PHNT_NO_INLINE_INIT_STRING
FORCEINLINE
VOID
NTAPI_INLINE
RtlInitUnicodeString(
_Out_ PUNICODE_STRING DestinationString,
_In_opt_z_ PCWSTR SourceString
)
{
if (SourceString)
DestinationString->MaximumLength = (DestinationString->Length = (USHORT)(wcslen(SourceString) * sizeof(WCHAR))) + sizeof(UNICODE_NULL);
else
DestinationString->MaximumLength = DestinationString->Length = 0;
DestinationString->Buffer = (PWCH)SourceString;
}
#else
NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString(
_Out_ PUNICODE_STRING DestinationString,
_In_opt_z_ PCWSTR SourceString
);
#endif // PHNT_NO_INLINE_INIT_STRING
#ifndef PHNT_NO_INLINE_INIT_STRING
FORCEINLINE
NTSTATUS
NTAPI_INLINE
RtlInitUnicodeStringEx(
_Out_ PUNICODE_STRING DestinationString,
_In_opt_z_ PCWSTR SourceString
)
{
size_t stringLength;
DestinationString->Length = 0;
DestinationString->Buffer = (PWCH)SourceString;
if (!SourceString)
return STATUS_SUCCESS;
stringLength = wcslen(SourceString);
if (stringLength <= UNICODE_STRING_MAX_CHARS - 1)
{
DestinationString->Length = (USHORT)stringLength * sizeof(WCHAR);
DestinationString->MaximumLength = DestinationString->Length + sizeof(UNICODE_NULL);
return STATUS_SUCCESS;
}
return STATUS_NAME_TOO_LONG;
}
#else
NTSYSAPI
NTSTATUS
NTAPI
RtlInitUnicodeStringEx(
_Out_ PUNICODE_STRING DestinationString,
_In_opt_z_ PCWSTR SourceString
);
#endif // PHNT_NO_INLINE_INIT_STRING
/**
* The RtlCreateUnicodeString routine creates a new counted Unicode string.
*
* \param DestinationString Pointer to the newly allocated and initialized Unicode string.
* \param SourceString Pointer to a null-terminated Unicode string with which to initialize the new string.
* \return TRUE if the Unicode string was successfully created, FALSE otherwise.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlcreateunicodestring
*/
_Success_(return != 0)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlCreateUnicodeString(
_Out_ PUNICODE_STRING DestinationString,
_In_z_ PCWSTR SourceString
);
NTSYSAPI
BOOLEAN
NTAPI
RtlCreateUnicodeStringFromAsciiz(
_Out_ PUNICODE_STRING DestinationString,
_In_z_ PCSTR SourceString
);
/**
* The RtlFreeUnicodeString routine releases storage that was allocated by RtlAnsiStringToUnicodeString or RtlUpcaseUnicodeString.
*
* \param UnicodeString A pointer to the string buffer.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlfreeunicodestring
*/
NTSYSAPI
VOID
NTAPI
RtlFreeUnicodeString(
_Inout_ _At_(UnicodeString->Buffer, _Frees_ptr_opt_) PUNICODE_STRING UnicodeString
);
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE (0x00000001)
#define RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING (0x00000002)
NTSYSAPI
NTSTATUS
NTAPI
RtlDuplicateUnicodeString(
_In_ ULONG Flags,
_In_ PCUNICODE_STRING StringIn,
_Out_ PUNICODE_STRING StringOut
);
/**
* The RtlCopyUnicodeString routine copies a source string to a destination string.
*
* \param[in] DestinationString A pointer to the destination string buffer.
* \param[in] SourceString A pointer to the source string buffer.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlcopyunicodestring
*/
NTSYSAPI
VOID
NTAPI
RtlCopyUnicodeString(
_In_ PCUNICODE_STRING DestinationString,
_In_opt_ PCUNICODE_STRING SourceString
);
/**
* The RtlUpcaseUnicodeChar routine converts the specified Unicode character to uppercase.
*
* \param[in] SourceCharacter Specifies the character to convert.
* \return The uppercase version of the specified Unicode character.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlupcaseunicodechar
*/
NTSYSAPI
WCHAR
NTAPI
RtlUpcaseUnicodeChar(
_In_ WCHAR SourceCharacter
);
/**
* The RtlDowncaseUnicodeChar routine converts the specified Unicode character to lowercase.
*
* \param[in] SourceCharacter Specifies the character to convert.
* \return The lowercase version of the specified Unicode character.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtldowncaseunicodechar
*/
NTSYSAPI
WCHAR
NTAPI
RtlDowncaseUnicodeChar(
_In_ WCHAR SourceCharacter
);
/**
* The RtlCompareUnicodeString routine compares two Unicode strings.
*
* \param[in] String1 Pointer to the first string.
* \param[in] String2 Pointer to the second string.
* \param[in] CaseInSensitive If TRUE, case should be ignored when doing the comparison.
* \return A signed value that gives the results of the comparison.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlcompareunicodestring
*/
_Must_inspect_result_
NTSYSAPI
LONG
NTAPI
RtlCompareUnicodeString(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2,
_In_ BOOLEAN CaseInSensitive
);
/**
* The RtlCompareUnicodeStrings routine compares two Unicode strings.
*
* \param[in] String1 Pointer to the first string.
* \param[in] String1Length The length, in bytes, of the first string.
* \param[in] String2 Pointer to the second string.
* \param[in] String2Length The length, in bytes, of the second string.
* \param[in] CaseInSensitive If TRUE, case should be ignored when doing the comparison.
* \return A signed value that gives the results of the comparison.
*/
_Must_inspect_result_
NTSYSAPI
LONG
NTAPI
RtlCompareUnicodeStrings(
_In_reads_(String1Length) PCWCH String1,
_In_ SIZE_T String1Length,
_In_reads_(String2Length) PCWCH String2,
_In_ SIZE_T String2Length,
_In_ BOOLEAN CaseInSensitive
);
/**
* The RtlEqualUnicodeString routine compares two Unicode strings to determine whether they are equal.
*
* \param[in] String1 Pointer to the first Unicode string.
* \param[in] String2 Pointer to the second Unicode string.
* \param[in] CaseInSensitive If TRUE, case should be ignored when doing the comparison.
* \return TRUE if the two Unicode strings are equal; otherwise, it returns FALSE.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlequalunicodestring
*/
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualUnicodeString(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2,
_In_ BOOLEAN CaseInSensitive
);
#define HASH_STRING_ALGORITHM_DEFAULT 0
#define HASH_STRING_ALGORITHM_X65599 1
#define HASH_STRING_ALGORITHM_INVALID 0xffffffff
/**
* The RtlHashUnicodeString routine creates a hash value from a given Unicode string and hash algorithm.
*
* \param[in] String A pointer to a UNICODE_STRING structure that contains the Unicode string to be converted to a hash value.
* \param[in] CaseInSensitive Specifies whether to treat the Unicode string as case sensitive when computing the hash value. If CaseInSensitive is TRUE, a lowercase and uppercase string hash to the same value.
* \param[in] HashAlgorithm The hash algorithm to use.
* \param[out] HashValue A pointer to a ULONG variable that receives the hash value.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlhashunicodestring
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlHashUnicodeString(
_In_ PCUNICODE_STRING String,
_In_ BOOLEAN CaseInSensitive,
_In_ ULONG HashAlgorithm,
_Out_ PULONG HashValue
);
NTSYSAPI
NTSTATUS
NTAPI
RtlValidateUnicodeString(
_In_ ULONG Flags,
_In_ PCUNICODE_STRING String
);
/**
* The RtlPrefixUnicodeString routine compares two Unicode strings to determine whether one string is a prefix of the other.
*
* \param[in] String1 Pointer to the first string, which might be a prefix of the buffered Unicode string at String2.
* \param[in] String2 Pointer to the second string.
* \param[in] CaseInSensitive TRUE, case should be ignored when doing the comparison.
* \return TRUE if String1 is a prefix of String2.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlprefixunicodestring
*/
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlPrefixUnicodeString(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2,
_In_ BOOLEAN CaseInSensitive
);
#if (PHNT_MODE == PHNT_MODE_KERNEL && PHNT_VERSION >= PHNT_WINDOWS_10)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlSuffixUnicodeString(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2,
_In_ BOOLEAN CaseInSensitive
);
#endif // PHNT_MODE == PHNT_MODE_KERNEL && PHNT_VERSION >= PHNT_WINDOWS_10
#pragma prefast(push)
#pragma prefast(disable : 6101, "Out parameter is not written fully or at all.")
FORCEINLINE
VOID
NTAPI_INLINE
RtlSanitizeUnicodeStringPadding(
_Out_ PUNICODE_STRING String
)
{
#if defined(_WIN64)
ULONG PaddingSize;
ULONG PaddingStart;
PaddingStart = FIELD_OFFSET(UNICODE_STRING, MaximumLength) + sizeof(String->MaximumLength);
PaddingSize = FIELD_OFFSET(UNICODE_STRING, Buffer) - PaddingStart;
memset((PCH)String + PaddingStart, 0, PaddingSize);
#else
UNREFERENCED_PARAMETER(String);
#endif
}
#pragma prefast(pop)
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
_Must_inspect_result_
NTSYSAPI
PWCHAR
NTAPI
RtlFindUnicodeSubstring(
_In_ PCUNICODE_STRING FullString,
_In_ PCUNICODE_STRING SearchString,
_In_ BOOLEAN CaseInSensitive
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
#define RTL_FIND_CHAR_IN_UNICODE_STRING_START_AT_END 0x00000001
#define RTL_FIND_CHAR_IN_UNICODE_STRING_COMPLEMENT_CHAR_SET 0x00000002
#define RTL_FIND_CHAR_IN_UNICODE_STRING_CASE_INSENSITIVE 0x00000004
NTSYSAPI
NTSTATUS
NTAPI
RtlFindCharInUnicodeString(
_In_ ULONG Flags,
_In_ PCUNICODE_STRING StringToSearch,
_In_ PCUNICODE_STRING CharSet,
_Out_ PUSHORT NonInclusivePrefixLength
);
typedef struct _RTL_UNICODE_STRING_BUFFER RTL_UNICODE_STRING_BUFFER, *PRTL_UNICODE_STRING_BUFFER;
NTSYSAPI
NTSTATUS
NTAPI
RtlMultiAppendUnicodeStringBuffer(
_Inout_ PRTL_UNICODE_STRING_BUFFER Buffer,
_In_ ULONG BufferCount,
_In_ PCUNICODE_STRING Source
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendPathElement(
_In_ ULONG Flags,
_Inout_ PRTL_UNICODE_STRING_BUFFER Buffer,
_In_ PCUNICODE_STRING Source
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendUnicodeStringToString(
_Inout_ PUNICODE_STRING Destination,
_In_ PCUNICODE_STRING Source
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendUnicodeToString(
_Inout_ PUNICODE_STRING Destination,
_In_opt_z_ PCWSTR Source
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeString(
_Inout_ PUNICODE_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDowncaseUnicodeString(
_Inout_ PUNICODE_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
VOID
NTAPI
RtlEraseUnicodeString(
_Inout_ PUNICODE_STRING String
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAnsiStringToUnicodeString(
_Inout_ PUNICODE_STRING DestinationString,
_In_ PCANSI_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
ULONG
NTAPI
RtlxAnsiStringToUnicodeSize(
_In_ PCANSI_STRING AnsiString
);
// NTSYSAPI
// ULONG
// NTAPI
// RtlAnsiStringToUnicodeSize(
// _In_ PCANSI_STRING AnsiString
// );
#define RtlAnsiStringToUnicodeSize(STRING) \
RtlxAnsiStringToUnicodeSize(STRING)
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToAnsiString(
_Inout_ PANSI_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
// rev
NTSYSAPI
ULONG
NTAPI
RtlUnicodeStringToAnsiSize(
_In_ PCUNICODE_STRING SourceString
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_20H1)
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToUTF8String(
_Inout_ PUTF8_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUTF8StringToUnicodeString(
_Inout_ PUNICODE_STRING DestinationString,
_In_ PCUTF8_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_20H1
NTSYSAPI
WCHAR
NTAPI
RtlAnsiCharToUnicodeChar(
_Inout_ PUCHAR *SourceCharacter
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeStringToAnsiString(
_Inout_ PANSI_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlOemStringToUnicodeString(
_Inout_ PUNICODE_STRING DestinationString,
_In_ POEM_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToOemString(
_Inout_ POEM_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeStringToOemString(
_Inout_ POEM_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlOemStringToCountedUnicodeString(
_Inout_ PUNICODE_STRING DestinationString,
_In_ PCOEM_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToCountedOemString(
_Inout_ POEM_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeStringToCountedOemString(
_Inout_ POEM_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
/**
* The RtlMultiByteToUnicodeN routine translates the specified source string into a Unicode string, using the current system ANSI code page (ACP).
* The source string is not necessarily from a multibyte character set.
*
* \param UnicodeString Pointer to a caller-allocated buffer that receives the translated string. UnicodeString buffer must not overlap with MultiByteString buffer.
* \param MaxBytesInUnicodeString Maximum number of bytes to be written at UnicodeString. If this value causes the translated string to be truncated, RtlMultiByteToUnicodeN does not return an error status.
* \param BytesInUnicodeString Pointer to a caller-allocated variable that receives the length, in bytes, of the translated string. This parameter can be NULL.
* \param MultiByteString Pointer to the string to be translated.
* \param BytesInMultiByteString Size, in bytes, of the string at MultiByteString.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlmultibytetounicoden
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlMultiByteToUnicodeN(
_Out_writes_bytes_to_(MaxBytesInUnicodeString, *BytesInUnicodeString) PWCH UnicodeString,
_In_ ULONG MaxBytesInUnicodeString,
_Out_opt_ PULONG BytesInUnicodeString,
_In_reads_bytes_(BytesInMultiByteString) PCSTR MultiByteString,
_In_ ULONG BytesInMultiByteString
);
/**
* The RtlMultiByteToUnicodeSize routine determines the number of bytes that are required to store the Unicode translation for the specified source string.
* The translation is assumed to use the current system ANSI code page (ACP). The source string is not necessarily from a multibyte character set.
*
* \param BytesInUnicodeString Pointer to a caller-allocated variable that receives the number of bytes that are required to store the translated string.
* \param MultiByteString Pointer to the source string for which the Unicode length is to be calculated.
* \param BytesInMultiByteString Length, in bytes, of the source string.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlmultibytetounicodesize
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlMultiByteToUnicodeSize(
_Out_ PULONG BytesInUnicodeString,
_In_reads_bytes_(BytesInMultiByteString) PCSTR MultiByteString,
_In_ ULONG BytesInMultiByteString
);
/**
* The RtlUnicodeToMultiByteN routine translates the specified Unicode string into a new character string, using the current system ANSI code page (ACP).
* The source string is not necessarily from a multibyte character set.
*
* \param MultiByteString Pointer to a caller-allocated buffer to receive the translated string. MultiByteString buffer must not overlap with UnicodeString buffer.
* \param MaxBytesInMultiByteString Maximum number of bytes to be written to MultiByteString. If this value causes the translated string to be truncated, RtlUnicodeToMultiByteN does not return an error status.
* \param BytesInMultiByteString Pointer to a caller-allocated variable that receives the length, in bytes, of the translated string. This parameter is optional and can be NULL.
* \param UnicodeString Pointer to the Unicode source string to be translated.
* \param BytesInUnicodeString Size, in bytes, of the string at UnicodeString.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlunicodetomultibyten
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeToMultiByteN(
_Out_writes_bytes_to_(MaxBytesInMultiByteString, *BytesInMultiByteString) PCHAR MultiByteString,
_In_ ULONG MaxBytesInMultiByteString,
_Out_opt_ PULONG BytesInMultiByteString,
_In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString,
_In_ ULONG BytesInUnicodeString
);
/**
* The RtlUnicodeToMultiByteSize routine determines the number of bytes that are required to store the multibyte translation for the specified Unicode string.
* The translation is assumed to use the current system ANSI code page (ACP). The source string is not necessarily from a multibyte character set.
*
* \param BytesInMultiByteString Pointer to a caller-allocated variable that receives the number of bytes required to store the translated string.
* \param UnicodeString Pointer to the Unicode string for which the multibyte length is to be calculated.
* \param BytesInUnicodeString Length, in bytes, of the source string.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlunicodetomultibytesize
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeToMultiByteSize(
_Out_ PULONG BytesInMultiByteString,
_In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString,
_In_ ULONG BytesInUnicodeString
);
/**
* The RtlUpcaseUnicodeToMultiByteN routine translates the specified Unicode string into a new uppercase character string, using the current system ANSI code page (ACP).
* The translated string is not necessarily from a multibyte character set.
*
* \param MultiByteString Pointer to a caller-allocated buffer to receive the translated string.
* \param MaxBytesInMultiByteString Maximum number of bytes to be written at MultiByteString. If this value causes the translated string to be truncated, RtlUpcaseUnicodeToMultiByteN does not return an error status.
* \param BytesInMultiByteString Pointer to a caller-allocated variable that receives the length, in bytes, of the translated string. This parameter can be NULL.
* \param UnicodeString Pointer to the Unicode source string to be translated.
* \param BytesInUnicodeString Size, in bytes, of the string at UnicodeString.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlupcaseunicodetomultibyten
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeToMultiByteN(
_Out_writes_bytes_to_(MaxBytesInMultiByteString, *BytesInMultiByteString) PCHAR MultiByteString,
_In_ ULONG MaxBytesInMultiByteString,
_Out_opt_ PULONG BytesInMultiByteString,
_In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString,
_In_ ULONG BytesInUnicodeString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlOemToUnicodeN(
_Out_writes_bytes_to_(MaxBytesInUnicodeString, *BytesInUnicodeString) PWSTR UnicodeString,
_In_ ULONG MaxBytesInUnicodeString,
_Out_opt_ PULONG BytesInUnicodeString,
_In_reads_bytes_(BytesInOemString) PCCH OemString,
_In_ ULONG BytesInOemString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeToOemN(
_Out_writes_bytes_to_(MaxBytesInOemString, *BytesInOemString) PCHAR OemString,
_In_ ULONG MaxBytesInOemString,
_Out_opt_ PULONG BytesInOemString,
_In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString,
_In_ ULONG BytesInUnicodeString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeToOemN(
_Out_writes_bytes_to_(MaxBytesInOemString, *BytesInOemString) PCHAR OemString,
_In_ ULONG MaxBytesInOemString,
_Out_opt_ PULONG BytesInOemString,
_In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString,
_In_ ULONG BytesInUnicodeString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlConsoleMultiByteToUnicodeN(
_Out_writes_bytes_to_(MaxBytesInUnicodeString, *BytesInUnicodeString) PWCH UnicodeString,
_In_ ULONG MaxBytesInUnicodeString,
_Out_opt_ PULONG BytesInUnicodeString,
_In_reads_bytes_(BytesInMultiByteString) PCCH MultiByteString,
_In_ ULONG BytesInMultiByteString,
_Out_ PULONG pdwSpecialChar
);
/**
* The RtlUTF8ToUnicodeN routine translates the specified source string into a Unicode string, using the 8-bit Unicode Transformation Format (UTF-8) code page.
*
* \param UnicodeStringDestination Pointer to a caller-allocated buffer to receive the translated string.
* \param UnicodeStringMaxByteCount Maximum number of bytes to be written at MultiByteString. If this value causes the translated string to be truncated, RtlUpcaseUnicodeToMultiByteN does not return an error status.
* \param UnicodeStringActualByteCount Pointer to a caller-allocated variable that receives the length, in bytes, of the translated string. This parameter can be NULL.
* \param UTF8StringSource Pointer to the Unicode source string to be translated.
* \param UTF8StringByteCount Size, in bytes, of the string at UnicodeString.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/devnotes/rtlutf8tounicoden
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlUTF8ToUnicodeN(
_Out_writes_bytes_to_(UnicodeStringMaxByteCount, *UnicodeStringActualByteCount) PWSTR UnicodeStringDestination,
_In_ ULONG UnicodeStringMaxByteCount,
_Out_opt_ PULONG UnicodeStringActualByteCount,
_In_reads_bytes_(UTF8StringByteCount) PCCH UTF8StringSource,
_In_ ULONG UTF8StringByteCount
);
/**
* The RtlUnicodeToUTF8N routine translates the specified Unicode string into a new character string, using the 8-bit Unicode Transformation Format (UTF-8) code page.
*
* \param UTF8StringDestination Pointer to a caller-allocated buffer to receive the translated string.
* \param UTF8StringMaxByteCount Maximum number of bytes to be written to UTF8StringDestination. If this value causes the translated string to be truncated, RtlUnicodeToUTF8N returns an error status.
* \param UTF8StringActualByteCount A pointer to a caller-allocated variable that receives the length, in bytes, of the translated string. This parameter is optional and can be NULL. If the string is truncated then the returned number counts the actual truncated string count.
* \param UnicodeStringSource A pointer to the Unicode source string to be translated.
* \param UnicodeStringByteCount Specifies the number of bytes in the Unicode source string that the UnicodeStringSource parameter points to.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/devnotes/rtlunicodetoutf8n
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeToUTF8N(
_Out_writes_bytes_to_(UTF8StringMaxByteCount, *UTF8StringActualByteCount) PCHAR UTF8StringDestination,
_In_ ULONG UTF8StringMaxByteCount,
_Out_opt_ PULONG UTF8StringActualByteCount,
_In_reads_bytes_(UnicodeStringByteCount) PCWCH UnicodeStringSource,
_In_ ULONG UnicodeStringByteCount
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCustomCPToUnicodeN(
_In_ PCPTABLEINFO CustomCP,
_Out_writes_bytes_to_(MaxBytesInUnicodeString, *BytesInUnicodeString) PWCH UnicodeString,
_In_ ULONG MaxBytesInUnicodeString,
_Out_opt_ PULONG BytesInUnicodeString,
_In_reads_bytes_(BytesInCustomCPString) PCH CustomCPString,
_In_ ULONG BytesInCustomCPString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeToCustomCPN(
_In_ PCPTABLEINFO CustomCP,
_Out_writes_bytes_to_(MaxBytesInCustomCPString, *BytesInCustomCPString) PCH CustomCPString,
_In_ ULONG MaxBytesInCustomCPString,
_Out_opt_ PULONG BytesInCustomCPString,
_In_reads_bytes_(BytesInUnicodeString) PWCH UnicodeString,
_In_ ULONG BytesInUnicodeString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeToCustomCPN(
_In_ PCPTABLEINFO CustomCP,
_Out_writes_bytes_to_(MaxBytesInCustomCPString, *BytesInCustomCPString) PCH CustomCPString,
_In_ ULONG MaxBytesInCustomCPString,
_Out_opt_ PULONG BytesInCustomCPString,
_In_reads_bytes_(BytesInUnicodeString) PWCH UnicodeString,
_In_ ULONG BytesInUnicodeString
);
NTSYSAPI
VOID
NTAPI
RtlInitCodePageTable(
_In_reads_opt_(2) PUSHORT TableBase,
_Inout_ PCPTABLEINFO CodePageTable
);
#if (PHNT_VERSION < PHNT_WINDOWS_11)
NTSYSAPI
VOID
NTAPI
RtlInitNlsTables(
_In_ PUSHORT AnsiNlsBase,
_In_ PUSHORT OemNlsBase,
_In_ PUSHORT LanguageNlsBase,
_Out_ PNLSTABLEINFO TableInfo // PCPTABLEINFO?
);
#endif
NTSYSAPI
VOID
NTAPI
RtlResetRtlTranslations(
_In_ PNLSTABLEINFO TableInfo
);
NTSYSAPI
BOOLEAN
NTAPI
RtlIsTextUnicode(
_In_ PVOID Buffer,
_In_ ULONG Size,
_Inout_opt_ PULONG Result
);
typedef enum _RTL_NORM_FORM
{
NormOther = 0x0,
NormC = 0x1,
NormD = 0x2,
NormKC = 0x5,
NormKD = 0x6,
NormIdna = 0xd,
DisallowUnassigned = 0x100,
NormCDisallowUnassigned = 0x101,
NormDDisallowUnassigned = 0x102,
NormKCDisallowUnassigned = 0x105,
NormKDDisallowUnassigned = 0x106,
NormIdnaDisallowUnassigned = 0x10d
} RTL_NORM_FORM;
NTSYSAPI
NTSTATUS
NTAPI
RtlNormalizeString(
_In_ ULONG NormForm, // RTL_NORM_FORM
_In_ PCWSTR SourceString,
_In_ LONG SourceStringLength,
_Out_writes_to_(*DestinationStringLength, *DestinationStringLength) PWSTR DestinationString,
_Inout_ PLONG DestinationStringLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIsNormalizedString(
_In_ ULONG NormForm, // RTL_NORM_FORM
_In_ PCWSTR SourceString,
_In_ LONG SourceStringLength,
_Out_ PBOOLEAN Normalized
);
// ntifs:FsRtlIsNameInExpression
/**
* The RtlIsNameInExpression routine determines whether a Unicode string matches the specified pattern.
*
* \param Expression A pointer to the pattern string. This string can contain wildcard characters. If the IgnoreCase parameter is TRUE, the string must contain only uppercase characters.
* \param Name Maximum number of bytes to be written to UTF8StringDestination. If this value causes the translated string to be truncated, RtlUnicodeToUTF8N returns an error status.
* \param IgnoreCase TRUE for case-insensitive matching, or FALSE for case-sensitive matching.
* \param UpcaseTable An optional pointer to an uppercase character table to use for case-insensitive matching. If this parameter is NULL, the default system uppercase character table is used.
* \return TRUE if the string matches the pattern. If the string does not match the pattern, this function returns FALSE.
* \sa https://learn.microsoft.com/en-us/windows/win32/devnotes/rtlisnameinexpression
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlIsNameInExpression(
_In_ PCUNICODE_STRING Expression,
_In_ PCUNICODE_STRING Name,
_In_ BOOLEAN IgnoreCase,
_In_opt_ PWCH UpcaseTable
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS4)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsNameInUnUpcasedExpression(
_In_ PCUNICODE_STRING Expression,
_In_ PCUNICODE_STRING Name,
_In_ BOOLEAN IgnoreCase,
_In_opt_ PWCH UpcaseTable
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS4
#if (PHNT_VERSION >= PHNT_WINDOWS_10_19H1)
/**
* The RtlDoesNameContainWildCards routine determines whether a Unicode string contains wildcard characters.
*
* \param Name A pointer to the string to be checked.
* \return TRUE if one or more wildcard characters were found, FALSE otherwise.
* \remarks The following are wildcard characters: *, ?, ANSI_DOS_STAR, ANSI_DOS_DOT, and ANSI_DOS_QM.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-_fsrtl_advanced_fcb_header-fsrtldoesnamecontainwildcards
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlDoesNameContainWildCards(
_In_ PCUNICODE_STRING Expression
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_19H1
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualDomainName(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2
);
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualComputerName(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDnsHostNameToComputerName(
_Out_ PUNICODE_STRING ComputerNameString,
_In_ PCUNICODE_STRING DnsHostNameString,
_In_ BOOLEAN AllocateComputerNameString
);
/**
* The RtlStringFromGUID routine converts a given GUID from binary format into a Unicode string.
*
* \param[in] Guid Specifies the binary-format GUID to convert.
* \param[out] GuidString Pointer to a caller-supplied variable in which a pointer to the converted GUID string is returned and must free by calling RtlFreeUnicodeString.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlstringfromguid
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlStringFromGUID(
_In_ PGUID Guid,
_Out_ PUNICODE_STRING GuidString
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
#define RTL_GUID_STRING_SIZE 38
#define MAX_UNICODE_GUID_STRING_LENGTH (36 + sizeof(UNICODE_NULL))
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlStringFromGUIDEx(
_In_ PGUID Guid,
_Inout_ PUNICODE_STRING GuidString,
_In_ BOOLEAN AllocateGuidString
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
NTSYSAPI
NTSTATUS
NTAPI
RtlGUIDFromString(
_In_ PCUNICODE_STRING GuidString,
_Out_ PGUID Guid
);
NTSYSAPI
LONG
NTAPI
RtlCompareAltitudes(
_In_ PCUNICODE_STRING Altitude1,
_In_ PCUNICODE_STRING Altitude2
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIdnToAscii(
_In_ ULONG Flags,
_In_ PCWSTR SourceString,
_In_ LONG SourceStringLength,
_Out_writes_to_(*DestinationStringLength, *DestinationStringLength) PWSTR DestinationString,
_Inout_ PLONG DestinationStringLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIdnToUnicode(
_In_ ULONG Flags,
_In_ PCWSTR SourceString,
_In_ LONG SourceStringLength,
_Out_writes_to_(*DestinationStringLength, *DestinationStringLength) PWSTR DestinationString,
_Inout_ PLONG DestinationStringLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIdnToNameprepUnicode(
_In_ ULONG Flags,
_In_ PCWSTR SourceString,
_In_ LONG SourceStringLength,
_Out_writes_to_(*DestinationStringLength, *DestinationStringLength) PWSTR DestinationString,
_Inout_ PLONG DestinationStringLength
);
//
// Prefix
//
typedef struct _PREFIX_TABLE_ENTRY
{
CSHORT NodeTypeCode;
CSHORT NameLength;
struct _PREFIX_TABLE_ENTRY *NextPrefixTree;
RTL_SPLAY_LINKS Links;
PSTRING Prefix;
} PREFIX_TABLE_ENTRY, *PPREFIX_TABLE_ENTRY;
typedef struct _PREFIX_TABLE
{
CSHORT NodeTypeCode;
CSHORT NameLength;
PPREFIX_TABLE_ENTRY NextPrefixTree;
} PREFIX_TABLE, *PPREFIX_TABLE;
NTSYSAPI
VOID
NTAPI
PfxInitialize(
_Out_ PPREFIX_TABLE PrefixTable
);
NTSYSAPI
BOOLEAN
NTAPI
PfxInsertPrefix(
_In_ PPREFIX_TABLE PrefixTable,
_In_ __drv_aliasesMem PSTRING Prefix,
_Out_ PPREFIX_TABLE_ENTRY PrefixTableEntry
);
NTSYSAPI
VOID
NTAPI
PfxRemovePrefix(
_In_ PPREFIX_TABLE PrefixTable,
_In_ PPREFIX_TABLE_ENTRY PrefixTableEntry
);
NTSYSAPI
PPREFIX_TABLE_ENTRY
NTAPI
PfxFindPrefix(
_In_ PPREFIX_TABLE PrefixTable,
_In_ PSTRING FullName
);
typedef struct _UNICODE_PREFIX_TABLE_ENTRY
{
CSHORT NodeTypeCode;
CSHORT NameLength;
struct _UNICODE_PREFIX_TABLE_ENTRY *NextPrefixTree;
struct _UNICODE_PREFIX_TABLE_ENTRY *CaseMatch;
RTL_SPLAY_LINKS Links;
PUNICODE_STRING Prefix;
} UNICODE_PREFIX_TABLE_ENTRY, *PUNICODE_PREFIX_TABLE_ENTRY;
typedef struct _UNICODE_PREFIX_TABLE
{
CSHORT NodeTypeCode;
CSHORT NameLength;
PUNICODE_PREFIX_TABLE_ENTRY NextPrefixTree;
PUNICODE_PREFIX_TABLE_ENTRY LastNextEntry;
} UNICODE_PREFIX_TABLE, *PUNICODE_PREFIX_TABLE;
NTSYSAPI
VOID
NTAPI
RtlInitializeUnicodePrefix(
_Out_ PUNICODE_PREFIX_TABLE PrefixTable
);
NTSYSAPI
BOOLEAN
NTAPI
RtlInsertUnicodePrefix(
_In_ PUNICODE_PREFIX_TABLE PrefixTable,
_In_ __drv_aliasesMem PCUNICODE_STRING Prefix,
_Out_ PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry
);
NTSYSAPI
VOID
NTAPI
RtlRemoveUnicodePrefix(
_In_ PUNICODE_PREFIX_TABLE PrefixTable,
_In_ PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry
);
NTSYSAPI
PUNICODE_PREFIX_TABLE_ENTRY
NTAPI
RtlFindUnicodePrefix(
_In_ PUNICODE_PREFIX_TABLE PrefixTable,
_In_ PCUNICODE_STRING FullName,
_In_ ULONG CaseInsensitiveIndex
);
NTSYSAPI
PUNICODE_PREFIX_TABLE_ENTRY
NTAPI
RtlNextUnicodePrefix(
_In_ PUNICODE_PREFIX_TABLE PrefixTable,
_In_ BOOLEAN Restart
);
//
// Compression
//
#define COMPRESSION_FORMAT_NONE (0x0000)
#define COMPRESSION_FORMAT_DEFAULT (0x0001)
#define COMPRESSION_FORMAT_LZNT1 (0x0002)
#define COMPRESSION_FORMAT_XPRESS (0x0003)
#define COMPRESSION_FORMAT_XPRESS_HUFF (0x0004)
#define COMPRESSION_FORMAT_XP10 (0x0005)
#define COMPRESSION_FORMAT_LZ4 (0x0006)
#define COMPRESSION_FORMAT_DEFLATE (0x0007)
#define COMPRESSION_FORMAT_ZLIB (0x0008)
#define COMPRESSION_FORMAT_MAX (0x0008)
#define COMPRESSION_ENGINE_STANDARD (0x0000)
#define COMPRESSION_ENGINE_MAXIMUM (0x0100)
#define COMPRESSION_ENGINE_HIBER (0x0200)
#define COMPRESSION_ENGINE_MAX (0x0200)
#define COMPRESSION_FORMAT_MASK (0x00FF)
#define COMPRESSION_ENGINE_MASK (0xFF00)
#define COMPRESSION_FORMAT_ENGINE_MASK (COMPRESSION_FORMAT_MASK | COMPRESSION_ENGINE_MASK)
typedef struct _COMPRESSED_DATA_INFO
{
//
// Code for the compression format (and engine) as
// defined in ntrtl.h. Note that COMPRESSION_FORMAT_NONE
// and COMPRESSION_FORMAT_DEFAULT are invalid if
// any of the described chunks are compressed.
//
USHORT CompressionFormatAndEngine;
//
// Since chunks and compression units are expected to be
// powers of 2 in size, we express then log2. So, for
// example (1 << ChunkShift) == ChunkSizeInBytes. The
// ClusterShift indicates how much space must be saved
// to successfully compress a compression unit - each
// successfully compressed compression unit must occupy
// at least one cluster less in bytes than an uncompressed
// compression unit.
//
UCHAR CompressionUnitShift;
UCHAR ChunkShift;
UCHAR ClusterShift;
UCHAR Reserved;
//
// This is the number of entries in the CompressedChunkSizes
// array.
//
USHORT NumberOfChunks;
//
// This is an array of the sizes of all chunks resident
// in the compressed data buffer. There must be one entry
// in this array for each chunk possible in the uncompressed
// buffer size. A size of FSRTL_CHUNK_SIZE indicates the
// corresponding chunk is uncompressed and occupies exactly
// that size. A size of 0 indicates that the corresponding
// chunk contains nothing but binary 0's, and occupies no
// space in the compressed data. All other sizes must be
// less than FSRTL_CHUNK_SIZE, and indicate the exact size
// of the compressed data in bytes.
//
ULONG CompressedChunkSizes[ANYSIZE_ARRAY];
} COMPRESSED_DATA_INFO, *PCOMPRESSED_DATA_INFO;
NTSYSAPI
NTSTATUS
NTAPI
RtlGetCompressionWorkSpaceSize(
_In_ USHORT CompressionFormatAndEngine,
_Out_ PULONG CompressBufferWorkSpaceSize,
_Out_ PULONG CompressFragmentWorkSpaceSize
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCompressBuffer(
_In_ USHORT CompressionFormatAndEngine,
_In_reads_bytes_(UncompressedBufferSize) PUCHAR UncompressedBuffer,
_In_ ULONG UncompressedBufferSize,
_Out_writes_bytes_to_(CompressedBufferSize, *FinalCompressedSize) PUCHAR CompressedBuffer,
_In_ ULONG CompressedBufferSize,
_In_ ULONG UncompressedChunkSize,
_Out_ PULONG FinalCompressedSize,
_In_ PVOID WorkSpace
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDecompressBuffer(
_In_ USHORT CompressionFormat,
_Out_writes_bytes_to_(UncompressedBufferSize, *FinalUncompressedSize) PUCHAR UncompressedBuffer,
_In_ ULONG UncompressedBufferSize,
_In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer,
_In_ ULONG CompressedBufferSize,
_Out_ PULONG FinalUncompressedSize
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
NTSYSAPI
NTSTATUS
NTAPI
RtlDecompressBufferEx(
_In_ USHORT CompressionFormat,
_Out_writes_bytes_to_(UncompressedBufferSize, *FinalUncompressedSize) PUCHAR UncompressedBuffer,
_In_ ULONG UncompressedBufferSize,
_In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer,
_In_ ULONG CompressedBufferSize,
_Out_ PULONG FinalUncompressedSize,
_In_opt_ PVOID WorkSpace
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
NTSYSAPI
NTSTATUS
NTAPI
RtlDecompressBufferEx2(
_In_ USHORT CompressionFormat,
_Out_writes_bytes_to_(UncompressedBufferSize, *FinalUncompressedSize) PUCHAR UncompressedBuffer,
_In_ ULONG UncompressedBufferSize,
_In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer,
_In_ ULONG CompressedBufferSize,
_In_ ULONG UncompressedChunkSize,
_Out_ PULONG FinalUncompressedSize,
_In_opt_ PVOID WorkSpace
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
NTSYSAPI
NTSTATUS
NTAPI
RtlDecompressFragment(
_In_ USHORT CompressionFormat,
_Out_writes_bytes_to_(UncompressedFragmentSize, *FinalUncompressedSize) PUCHAR UncompressedFragment,
_In_ ULONG UncompressedFragmentSize,
_In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer,
_In_ ULONG CompressedBufferSize,
_In_range_(<, CompressedBufferSize) ULONG FragmentOffset,
_Out_ PULONG FinalUncompressedSize,
_In_ PVOID WorkSpace
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
NTSYSAPI
NTSTATUS
NTAPI
RtlDecompressFragmentEx(
_In_ USHORT CompressionFormat,
_Out_writes_bytes_to_(UncompressedFragmentSize, *FinalUncompressedSize) PUCHAR UncompressedFragment,
_In_ ULONG UncompressedFragmentSize,
_In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer,
_In_ ULONG CompressedBufferSize,
_In_range_(<, CompressedBufferSize) ULONG FragmentOffset,
_In_ ULONG UncompressedChunkSize,
_Out_ PULONG FinalUncompressedSize,
_In_ PVOID WorkSpace
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
NTSYSAPI
NTSTATUS
NTAPI
RtlDescribeChunk(
_In_ USHORT CompressionFormat,
_Inout_ PUCHAR *CompressedBuffer,
_In_ PUCHAR EndOfCompressedBufferPlus1,
_Out_ PUCHAR *ChunkBuffer,
_Out_ PULONG ChunkSize
);
NTSYSAPI
NTSTATUS
NTAPI
RtlReserveChunk(
_In_ USHORT CompressionFormat,
_Inout_ PUCHAR *CompressedBuffer,
_In_ PUCHAR EndOfCompressedBufferPlus1,
_Out_ PUCHAR *ChunkBuffer,
_In_ ULONG ChunkSize
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDecompressChunks(
_Out_writes_bytes_(UncompressedBufferSize) PUCHAR UncompressedBuffer,
_In_ ULONG UncompressedBufferSize,
_In_reads_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer,
_In_ ULONG CompressedBufferSize,
_In_reads_bytes_(CompressedTailSize) PUCHAR CompressedTail,
_In_ ULONG CompressedTailSize,
_In_ PCOMPRESSED_DATA_INFO CompressedDataInfo
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCompressChunks(
_In_reads_bytes_(UncompressedBufferSize) PUCHAR UncompressedBuffer,
_In_ ULONG UncompressedBufferSize,
_Out_writes_bytes_(CompressedBufferSize) PUCHAR CompressedBuffer,
_In_range_(>=, (UncompressedBufferSize - (UncompressedBufferSize / 16))) ULONG CompressedBufferSize,
_Inout_updates_bytes_(CompressedDataInfoLength) PCOMPRESSED_DATA_INFO CompressedDataInfo,
_In_range_(>, sizeof(COMPRESSED_DATA_INFO)) ULONG CompressedDataInfoLength,
_In_ PVOID WorkSpace
);
//
// Locale
//
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlConvertLCIDToString(
_In_ LCID LcidValue,
_In_ ULONG Base,
_In_ ULONG Padding, // string is padded to this width
_Out_writes_(Size) PWSTR pResultBuf,
_In_ ULONG Size
);
// private
NTSYSAPI
BOOLEAN
NTAPI
RtlIsValidLocaleName(
_In_ PCWSTR LocaleName,
_In_ ULONG Flags
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlGetParentLocaleName(
_In_ PCWSTR LocaleName,
_Inout_ PUNICODE_STRING ParentLocaleName,
_In_ ULONG Flags,
_In_ BOOLEAN AllocateDestinationString
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlLcidToLocaleName(
_In_ LCID lcid, // sic
_Inout_ PUNICODE_STRING LocaleName,
_In_ ULONG Flags,
_In_ BOOLEAN AllocateDestinationString
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlLocaleNameToLcid(
_In_ PCWSTR LocaleName,
_Out_ PLCID lcid,
_In_ ULONG Flags
);
// private
NTSYSAPI
BOOLEAN
NTAPI
RtlLCIDToCultureName(
_In_ LCID Lcid,
_Inout_ PUNICODE_STRING String
);
// private
NTSYSAPI
BOOLEAN
NTAPI
RtlCultureNameToLCID(
_In_ PCUNICODE_STRING String,
_Out_ PLCID Lcid
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlpConvertLCIDsToCultureNames(
_In_ PCWSTR Lcids, // array
_Out_ PCWSTR* CultureNames
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlpConvertCultureNamesToLCIDs(
_In_ PCWSTR CultureNames, // array
_Out_ PCWSTR* Lcids
);
// private
NTSYSAPI
VOID
NTAPI
RtlCleanUpTEBLangLists(
VOID
);
// rev from GetThreadPreferredUILanguages
NTSYSAPI
NTSTATUS
NTAPI
RtlGetThreadPreferredUILanguages(
_In_ ULONG Flags, // MUI_LANGUAGE_NAME
_Out_ PULONG NumberOfLanguages,
_Out_writes_opt_(*ReturnLength) PZZWSTR Languages,
_Inout_ PULONG ReturnLength
);
// rev from GetProcessPreferredUILanguages
NTSYSAPI
NTSTATUS
NTAPI
RtlGetProcessPreferredUILanguages(
_In_ ULONG Flags, // MUI_LANGUAGE_NAME
_Out_ PULONG NumberOfLanguages,
_Out_writes_opt_(*ReturnLength) PZZWSTR Languages,
_Inout_ PULONG ReturnLength
);
// rev from GetSystemPreferredUILanguages
NTSYSAPI
NTSTATUS
NTAPI
RtlGetSystemPreferredUILanguages(
_In_ ULONG Flags, // MUI_LANGUAGE_NAME
_In_opt_ PCWSTR LocaleName,
_Out_ PULONG NumberOfLanguages,
_Out_writes_opt_(*ReturnLength) PZZWSTR Languages,
_Inout_ PULONG ReturnLength
);
// rev from GetSystemDefaultUILanguage
NTSYSAPI
NTSTATUS
NTAPI
RtlpGetSystemDefaultUILanguage(
_Out_ LANGID DefaultUILanguageId,
_Inout_ PLCID Lcid
);
// rev from GetUserPreferredUILanguages
NTSYSAPI
NTSTATUS
NTAPI
RtlGetUserPreferredUILanguages(
_In_ ULONG Flags, // MUI_LANGUAGE_NAME
_In_opt_ PCWSTR LocaleName,
_Out_ PULONG NumberOfLanguages,
_Out_writes_opt_(*ReturnLength) PZZWSTR Languages,
_Inout_ PULONG ReturnLength
);
// rev from GetUILanguageInfo
NTSYSAPI
NTSTATUS
NTAPI
RtlGetUILanguageInfo(
_In_ ULONG Flags,
_In_ PCZZWSTR Languages,
_Out_writes_opt_(*NumberOfFallbackLanguages) PZZWSTR FallbackLanguages,
_Inout_opt_ PULONG NumberOfFallbackLanguages,
_Out_ PULONG Attributes
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetLocaleFileMappingAddress(
_Out_ PVOID *BaseAddress,
_Out_ PLCID DefaultLocaleId,
_Out_ PLARGE_INTEGER DefaultCasingTableSize,
_Out_opt_ PULONG CurrentNLSVersion
);
//
// PEB
//
NTSYSAPI
PPEB
NTAPI
RtlGetCurrentPeb(
VOID
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAcquirePebLock(
VOID
);
NTSYSAPI
NTSTATUS
NTAPI
RtlReleasePebLock(
VOID
);
// private
NTSYSAPI
LOGICAL
NTAPI
RtlTryAcquirePebLock(
VOID
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAllocateFromPeb(
_In_ ULONG Size,
_Out_ PVOID *Block
);
NTSYSAPI
NTSTATUS
NTAPI
RtlFreeToPeb(
_In_ PVOID Block,
_In_ ULONG Size
);
//
// Processes
//
// CURDIR Handle | Flags
#define RTL_USER_PROC_CURDIR_CLOSE 0x00000002
#define RTL_USER_PROC_CURDIR_INHERIT 0x00000003
typedef struct _CURDIR
{
UNICODE_STRING DosPath;
HANDLE Handle;
} CURDIR, *PCURDIR;
// RTL_DRIVE_LETTER_CURDIR Flags
#define RTL_MAX_DRIVE_LETTERS 32
#define RTL_DRIVE_LETTER_VALID (USHORT)0x0001
typedef struct _RTL_DRIVE_LETTER_CURDIR
{
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;
#define RTL_USER_PROC_DETACHED_PROCESS ((HANDLE)(LONG_PTR)-1)
#define RTL_USER_PROC_CREATE_NEW_CONSOLE ((HANDLE)(LONG_PTR)-2)
#define RTL_USER_PROC_CREATE_NO_WINDOW ((HANDLE)(LONG_PTR)-3)
typedef struct _RTL_USER_PROCESS_PARAMETERS
{
ULONG MaximumLength;
ULONG Length;
ULONG Flags;
ULONG DebugFlags;
HANDLE ConsoleHandle;
ULONG ConsoleFlags;
HANDLE StandardInput;
HANDLE StandardOutput;
HANDLE StandardError;
CURDIR CurrentDirectory;
UNICODE_STRING DllPath;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
PVOID Environment;
ULONG StartingX;
ULONG StartingY;
ULONG CountX;
ULONG CountY;
ULONG CountCharsX;
ULONG CountCharsY;
ULONG FillAttribute;
ULONG WindowFlags;
ULONG ShowWindowFlags;
UNICODE_STRING WindowTitle;
UNICODE_STRING DesktopInfo;
UNICODE_STRING ShellInfo;
UNICODE_STRING RuntimeData;
RTL_DRIVE_LETTER_CURDIR CurrentDirectories[RTL_MAX_DRIVE_LETTERS];
ULONG_PTR EnvironmentSize;
ULONG_PTR EnvironmentVersion;
PVOID PackageDependencyData;
ULONG ProcessGroupId;
ULONG LoaderThreads; // THRESHOLD
UNICODE_STRING RedirectionDllName; // REDSTONE5
UNICODE_STRING HeapPartitionName; // 19H1
PULONGLONG DefaultThreadpoolCpuSetMasks;
ULONG DefaultThreadpoolCpuSetMaskCount;
ULONG DefaultThreadpoolThreadMaximum; // 20H1
ULONG HeapMemoryTypeMask; // WIN11 22H2
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
// RTL_USER_PROCESS_PARAMETERS Flags
#define RTL_USER_PROC_PARAMS_NORMALIZED 0x00000001
#define RTL_USER_PROC_PROFILE_USER 0x00000002
#define RTL_USER_PROC_PROFILE_KERNEL 0x00000004
#define RTL_USER_PROC_PROFILE_SERVER 0x00000008
//#define RTL_USER_PROC_RESERVE_64K 0x00000010
#define RTL_USER_PROC_RESERVE_1MB 0x00000020
#define RTL_USER_PROC_RESERVE_16MB 0x00000040
#define RTL_USER_PROC_CASE_SENSITIVE 0x00000080
#define RTL_USER_PROC_DISABLE_HEAP_DECOMMIT 0x00000100
#define RTL_USER_PROC_DLL_REDIRECTION_LOCAL 0x00001000
#define RTL_USER_PROC_APP_MANIFEST_PRESENT 0x00002000
#define RTL_USER_PROC_IMAGE_KEY_MISSING 0x00004000
#define RTL_USER_PROC_DEV_OVERRIDE_ENABLED 0x00008000
#define RTL_USER_PROC_OPTIN_PROCESS 0x00020000
#define RTL_USER_PROC_SESSION_OWNER 0x00040000
#define RTL_USER_PROC_HANDLE_USER_CALLBACK_EXCEPTIONS 0x00080000
#define RTL_USER_PROC_PROTECTED_PROCESS 0x00400000
#define RTL_USER_PROC_SECURE_PROCESS 0x80000000
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateProcessParameters(
_Out_ PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
_In_ PCUNICODE_STRING ImagePathName,
_In_opt_ PCUNICODE_STRING DllPath,
_In_opt_ PCUNICODE_STRING CurrentDirectory,
_In_opt_ PCUNICODE_STRING CommandLine,
_In_opt_ PVOID Environment,
_In_opt_ PCUNICODE_STRING WindowTitle,
_In_opt_ PCUNICODE_STRING DesktopInfo,
_In_opt_ PCUNICODE_STRING ShellInfo,
_In_opt_ PCUNICODE_STRING RuntimeData
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateProcessParametersEx(
_Out_ PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
_In_ PCUNICODE_STRING ImagePathName,
_In_opt_ PCUNICODE_STRING DllPath,
_In_opt_ PCUNICODE_STRING CurrentDirectory,
_In_opt_ PCUNICODE_STRING CommandLine,
_In_opt_ PVOID Environment,
_In_opt_ PCUNICODE_STRING WindowTitle,
_In_opt_ PCUNICODE_STRING DesktopInfo,
_In_opt_ PCUNICODE_STRING ShellInfo,
_In_opt_ PCUNICODE_STRING RuntimeData,
_In_ ULONG Flags // pass RTL_USER_PROC_PARAMS_NORMALIZED to keep parameters normalized
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS4)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateProcessParametersWithTemplate(
_Out_ PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
_In_ PCUNICODE_STRING ImagePathName,
_In_opt_ PCUNICODE_STRING DllPath,
_In_opt_ PCUNICODE_STRING CurrentDirectory,
_In_opt_ PCUNICODE_STRING CommandLine,
_In_opt_ PVOID Environment,
_In_opt_ PCUNICODE_STRING WindowTitle,
_In_opt_ PCUNICODE_STRING DesktopInfo,
_In_opt_ PCUNICODE_STRING ShellInfo,
_In_opt_ PCUNICODE_STRING RuntimeData,
_In_opt_ PCUNICODE_STRING RedirectionDllName,
_In_ ULONG Flags // pass RTL_USER_PROC_PARAMS_NORMALIZED to keep parameters normalized
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS4
NTSYSAPI
NTSTATUS
NTAPI
RtlDestroyProcessParameters(
_In_ _Post_invalid_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters
);
NTSYSAPI
PRTL_USER_PROCESS_PARAMETERS
NTAPI
RtlNormalizeProcessParams(
_Inout_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters
);
NTSYSAPI
PRTL_USER_PROCESS_PARAMETERS
NTAPI
RtlDeNormalizeProcessParams(
_Inout_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters
);
typedef struct _RTL_USER_PROCESS_INFORMATION
{
ULONG Length;
HANDLE ProcessHandle;
HANDLE ThreadHandle;
CLIENT_ID ClientId;
SECTION_IMAGE_INFORMATION ImageInformation;
} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;
// private
/**
* Creates a new process and its primary thread. The new process runs in the security context of the calling process.
*
* \param NtImagePathName The path of the image to be executed.
* \param ExtendedParameters Reserved
* \param ProcessParameters The process parameter information.
* \param ProcessSecurityDescriptor The security descriptor for the new process. If NULL, the process gets a default security descriptor.
* \param ThreadSecurityDescriptor The security descriptor for the initial thread. If NULL, the thread gets a default security descriptor.
* \param ParentProcess The handle of a process to use (instead of the calling process) as the parent for the process being created.
* \param InheritHandles If this parameter is TRUE, each inheritable handle in the calling process is inherited by the new process.
* \param DebugPort The handle of an ALPC port for debug messages. If NULL, the process gets a default port. (WindowsErrorReportingServicePort)
* \param TokenHandle The handle of a Token to use as the security context.
* \param ProcessInformation The user process information.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserProcess(
_In_ PCUNICODE_STRING NtImagePathName,
_In_ ULONG ExtendedParameters, // HIWORD(NumaNodeNumber), LOWORD(Reserved)
_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
_In_opt_ PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,
_In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
_In_opt_ HANDLE ParentProcess,
_In_ BOOLEAN InheritHandles,
_In_opt_ HANDLE DebugPort,
_In_opt_ HANDLE TokenHandle, // used to be ExceptionPort
_Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation
);
#define RTL_USER_PROCESS_EXTENDED_PARAMETERS_VERSION 1
// private
typedef struct _RTL_USER_PROCESS_EXTENDED_PARAMETERS
{
USHORT Version;
USHORT NodeNumber;
PSECURITY_DESCRIPTOR ProcessSecurityDescriptor;
PSECURITY_DESCRIPTOR ThreadSecurityDescriptor;
HANDLE ParentProcess;
HANDLE DebugPort;
HANDLE TokenHandle;
HANDLE JobHandle;
} RTL_USER_PROCESS_EXTENDED_PARAMETERS, *PRTL_USER_PROCESS_EXTENDED_PARAMETERS;
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS2)
/**
* The RtlCreateUserProcessEx routine creates a new process and its primary thread, with extended parameters.
*
* \param NtImagePathName Pointer to a UNICODE_STRING that specifies the path of the image to be executed.
* \param ProcessParameters Pointer to a RTL_USER_PROCESS_PARAMETERS structure that contains process parameter information.
* \param InheritHandles If TRUE, each inheritable handle in the calling process is inherited by the new process.
* \param ProcessExtendedParameters Optional pointer to a RTL_USER_PROCESS_EXTENDED_PARAMETERS structure for additional process creation options. Can be NULL.
* \param ProcessInformation Pointer to a RTL_USER_PROCESS_INFORMATION structure that receives information about the new process and its primary thread.
* \return NTSTATUS Successful or errant status.
* \remarks This function is available on Windows 10 RS2 and later. It allows for more advanced process creation scenarios than RtlCreateUserProcess.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-createprocessw
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserProcessEx(
_In_ PCUNICODE_STRING NtImagePathName,
_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
_In_ BOOLEAN InheritHandles,
_In_opt_ PRTL_USER_PROCESS_EXTENDED_PARAMETERS ProcessExtendedParameters,
_Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS2
/**
* The RtlExitUserProcess routine ends the calling process and all its threads.
*
* \param ExitStatus The exit status for the process and all threads.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-exitprocess
* \remarks This function does not return to the caller. It terminates the process and all threads immediately.
*/
_Analysis_noreturn_
DECLSPEC_NORETURN
NTSYSAPI
VOID
NTAPI
RtlExitUserProcess(
_In_ NTSTATUS ExitStatus
);
// begin_rev
#define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED 0x00000001
#define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES 0x00000002
#define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE 0x00000004 // don't update synchronization objects
// end_rev
// private
/**
* The RtlCloneUserProcess routine creates a new process from the current process.
*
* \param ProcessFlags The path of the image to be executed.
* \param ProcessSecurityDescriptor The security descriptor for the new process. If NULL, the process gets a default security descriptor.
* \param ThreadSecurityDescriptor The security descriptor for the initial thread. If NULL, the thread gets a default security descriptor.
* \param DebugPort The handle of an ALPC port for debug messages. If NULL, the process gets a default port. (WindowsErrorReportingServicePort)
* \param ProcessInformation The new process information.
* \return NTSTATUS Successful or errant status.
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlCloneUserProcess(
_In_ ULONG ProcessFlags,
_In_opt_ PSECURITY_DESCRIPTOR ProcessSecurityDescriptor,
_In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
_In_opt_ HANDLE DebugPort,
_Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlPrepareForProcessCloning(
VOID
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCompleteProcessCloning(
_In_ LOGICAL Completed
);
// private
NTSYSAPI
VOID
NTAPI
RtlUpdateClonedCriticalSection(
_Inout_ PRTL_CRITICAL_SECTION CriticalSection
);
// private
NTSYSAPI
VOID
NTAPI
RtlUpdateClonedSRWLock(
_Inout_ PRTL_SRWLOCK SRWLock,
_In_ LOGICAL Shared // TRUE to set to shared acquire
);
// rev RtlCloneUserProcess Flags
#define RTL_PROCESS_REFLECTION_FLAGS_CREATE_SUSPENDED 0x00000001
#define RTL_PROCESS_REFLECTION_FLAGS_INHERIT_HANDLES 0x00000002
#define RTL_PROCESS_REFLECTION_FLAGS_NO_SUSPEND 0x00000004
#define RTL_PROCESS_REFLECTION_FLAGS_NO_SYNCHRONIZE 0x00000008
#define RTL_PROCESS_REFLECTION_FLAGS_NO_CLOSE_EVENT 0x00000010
// private
typedef struct _RTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION
{
HANDLE ReflectionProcessHandle;
HANDLE ReflectionThreadHandle;
CLIENT_ID ReflectionClientId;
} RTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION, *PRTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION;
typedef RTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION PROCESS_REFLECTION_INFORMATION, *PPROCESS_REFLECTION_INFORMATION;
// rev
/**
* The RtlCreateProcessReflection function creates a lightweight copy of a process for debugging or snapshot purposes.
*
* \param ProcessHandle Handle to the process to reflect.
* \param Flags Flags that control the behavior of the reflection. See RTL_PROCESS_REFLECTION_FLAGS_*.
* \param StartRoutine Optional pointer to a routine to execute in the reflected process.
* \param StartContext Optional pointer to context to pass to the start routine.
* \param EventHandle Optional handle to an event to signal when the reflection is complete.
* \param ReflectionInformation Optional pointer to a structure that receives information about the reflected process.
* \return NTSTATUS Successful or errant status.
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateProcessReflection(
_In_ HANDLE ProcessHandle,
_In_ ULONG Flags, // RTL_PROCESS_REFLECTION_FLAGS_*
_In_opt_ PVOID StartRoutine,
_In_opt_ PVOID StartContext,
_In_opt_ HANDLE EventHandle,
_Out_opt_ PPROCESS_REFLECTION_INFORMATION ReflectionInformation
);
/**
* The RtlSetProcessIsCritical function sets or clears the critical status of the current process.
*
* \param NewValue TRUE to mark the process as critical, FALSE to clear.
* \param OldValue Optional pointer to receive the previous critical status.
* \param CheckFlag If TRUE, checks for certain conditions before setting.
* \return NTSTATUS Successful or errant status.
* \remarks A critical process will cause a system bugcheck if terminated.
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlSetProcessIsCritical(
_In_ BOOLEAN NewValue,
_Out_opt_ PBOOLEAN OldValue,
_In_ BOOLEAN CheckFlag
);
/**
* The RtlSetThreadIsCritical function sets or clears the critical status of the current thread.
*
* \param NewValue TRUE to mark the thread as critical, FALSE to clear.
* \param OldValue Optional pointer to receive the previous critical status.
* \param CheckFlag If TRUE, checks for certain conditions before setting.
* \return NTSTATUS Successful or errant status.
* \remarks A critical thread will cause a system bugcheck if terminated.
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlSetThreadIsCritical(
_In_ BOOLEAN NewValue,
_Out_opt_ PBOOLEAN OldValue,
_In_ BOOLEAN CheckFlag
);
// rev
/**
* The RtlSetThreadSubProcessTag function sets the sub-process tag for the current thread.
*
* \param SubProcessTag Pointer to the tag value to set.
* \return The previous sub-process tag value.
*/
NTSYSAPI
PVOID
NTAPI
RtlSetThreadSubProcessTag(
_In_ PVOID SubProcessTag
);
// rev
/**
* The RtlValidProcessProtection function validates the process protection level.
*
* \param ProcessProtection Pointer to a PS_PROTECTION structure describing the protection.
* \return TRUE if the protection level is valid, FALSE otherwise.
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlValidProcessProtection(
_In_ PS_PROTECTION ProcessProtection
);
// rev
/**
* The RtlTestProtectedAccess function tests whether a source protection level can access a target protection level.
*
* \param Source Pointer to a PS_PROTECTION structure for the source.
* \param Target Pointer to a PS_PROTECTION structure for the target.
* \return TRUE if access is allowed, FALSE otherwise.
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlTestProtectedAccess(
_In_ PS_PROTECTION Source,
_In_ PS_PROTECTION Target
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS3)
/**
* The RtlIsCurrentProcess function determines whether the specified process handle refers to the current process.
*
* \param ProcessHandle Handle to the process to compare with the current process.
* \return TRUE if the handle refers to the current process; otherwise, FALSE.
* \remarks Internally compares the specified handle with the current process handle using NtCompareObjects.
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlIsCurrentProcess( // NtCompareObjects(NtCurrentProcess(), ProcessHandle)
_In_ HANDLE ProcessHandle
);
/**
* The RtlIsCurrentThread function determines whether the specified thread handle refers to the current thread.
*
* \param ThreadHandle Handle to the thread to compare with the current thread.
* \return TRUE if the handle refers to the current thread; otherwise, FALSE.
* \remarks Internally compares the specified handle with the current thread handle using NtCompareObjects.
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlIsCurrentThread( // NtCompareObjects(NtCurrentThread(), ThreadHandle)
_In_ HANDLE ThreadHandle
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS3
//
// Threads
//
typedef _Function_class_(USER_THREAD_START_ROUTINE)
NTSTATUS NTAPI USER_THREAD_START_ROUTINE(
_In_ PVOID ThreadParameter
);
typedef USER_THREAD_START_ROUTINE* PUSER_THREAD_START_ROUTINE;
/**
* The RtlCreateUserThread routine creates a thread in the specified process.
*
* \param ProcessHandle Handle to the process in which the thread is to be created.
* \param ThreadSecurityDescriptor Optional pointer to a security descriptor for the new thread. If NULL, the thread gets a default security descriptor.
* \param CreateSuspended If TRUE, the thread is created in a suspended state and must be resumed explicitly. If FALSE, the thread starts running immediately.
* \param ZeroBits Optional number of high-order address bits that must be zero in the stack's base address. Usually set to 0.
* \param MaximumStackSize Optional maximum size, in bytes, of the stack for the new thread. If 0, the default size is used.
* \param CommittedStackSize Optional initial size, in bytes, of committed stack for the new thread. If 0, the default size is used.
* \param StartAddress Pointer to the application-defined function to be executed by the thread.
* \param Parameter Optional pointer to a variable to be passed to the thread function.
* \param ThreadHandle Optional pointer to a variable that receives the handle of the new thread.
* \param ClientId Optional pointer to a CLIENT_ID structure that receives the thread and process identifiers.
* \return NTSTATUS Successful or errant status.
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserThread(
_In_ HANDLE ProcessHandle,
_In_opt_ PSECURITY_DESCRIPTOR ThreadSecurityDescriptor,
_In_ BOOLEAN CreateSuspended,
_In_opt_ ULONG ZeroBits,
_In_opt_ SIZE_T MaximumStackSize,
_In_opt_ SIZE_T CommittedStackSize,
_In_ PUSER_THREAD_START_ROUTINE StartAddress,
_In_opt_ PVOID Parameter,
_Out_opt_ PHANDLE ThreadHandle,
_Out_opt_ PCLIENT_ID ClientId
);
/**
* The RtlExitUserThread routine ends the calling thread and returns the specified exit status.
*
* \param ExitStatus The exit status for the thread.
* \remarks This function does not return to the caller. It terminates the thread immediately.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-exitthread
*/
_Analysis_noreturn_
DECLSPEC_NORETURN
NTSYSAPI
VOID
NTAPI
RtlExitUserThread(
_In_ NTSTATUS ExitStatus
);
// rev
/**
* The RtlIsCurrentThreadAttachExempt routine determines whether the current thread is exempt from attach notifications.
*
* \return TRUE if the current thread is attach-exempt; otherwise, FALSE.
* \remarks Attach-exempt threads do not receive DLL_THREAD_ATTACH and DLL_THREAD_DETACH notifications.
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlIsCurrentThreadAttachExempt(
VOID
);
/**
* The RtlCreateUserStack routine allocates and initializes a user-mode stack for a new thread.
*
* \param CommittedStackSize The initial size, in bytes, of committed stack. If 0, the default is used.
* \param MaximumStackSize The maximum size, in bytes, of the stack. If 0, the default is used.
* \param ZeroBits The number of high-order address bits that must be zero in the stack's base address. Usually set to 0.
* \param PageSize The system page size, in bytes.
* \param ReserveAlignment The alignment for the reserved stack region.
* \param InitialTeb Pointer to an INITIAL_TEB structure that receives the stack information.
* \return NTSTATUS Successful or errant status.
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserStack(
_In_opt_ SIZE_T CommittedStackSize,
_In_opt_ SIZE_T MaximumStackSize,
_In_opt_ ULONG_PTR ZeroBits,
_In_ SIZE_T PageSize,
_In_ ULONG_PTR ReserveAlignment,
_Out_ PINITIAL_TEB InitialTeb
);
/**
* The RtlFreeUserStack routine frees a user-mode stack previously allocated for a thread.
*
* \param AllocationBase The base address of the stack allocation to free.
* \return NTSTATUS Successful or errant status.
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlFreeUserStack(
_In_ PVOID AllocationBase
);
//
// Extended thread context
//
typedef struct _CONTEXT_CHUNK
{
LONG Offset; // Offset may be negative.
ULONG Length;
} CONTEXT_CHUNK, *PCONTEXT_CHUNK;
typedef struct _CONTEXT_EX
{
CONTEXT_CHUNK All;
CONTEXT_CHUNK Legacy;
CONTEXT_CHUNK XState;
CONTEXT_CHUNK KernelCet;
} CONTEXT_EX, *PCONTEXT_EX;
#if defined(_AMD64_) || defined(_ARM64_) || defined(_ARM64EC_)
#define CONTEXT_ALIGN 0x10
#else
#define CONTEXT_ALIGN 0x8
#endif // _AMD64_ || _ARM64_ || _ARM64EC_
#if defined(_AMD64_)
#define CONTEXT_FRAME_LENGTH 0x4D0
#define CONTEXT_EX_PADDING 0x10
#elif defined(_ARM64_) || defined(_ARM64EC_)
#define CONTEXT_FRAME_LENGTH 0x390
#define CONTEXT_EX_PADDING 0x10
#elif defined(_M_ARM)
#define CONTEXT_FRAME_LENGTH 0x1a0
#define CONTEXT_EX_PADDING 0x8
#else
#define CONTEXT_FRAME_LENGTH 0x2CC
#define CONTEXT_EX_PADDING 0x4
#endif // _AMD64_
#define CONTEXT_ALIGNMENT(Size, Align) \
(((ULONG_PTR)(Size) + (Align) - 1) & ~((Align) - 1))
#define CONTEXT_EX_LENGTH \
CONTEXT_ALIGNMENT(sizeof(CONTEXT_EX), CONTEXT_ALIGN)
static_assert(CONTEXT_FRAME_LENGTH == sizeof(CONTEXT));
static_assert(CONTEXT_EX_LENGTH == 0x20);
#define RTL_CONTEXT_EX_OFFSET(ContextEx, Chunk) ((ContextEx)->Chunk.Offset)
#define RTL_CONTEXT_EX_LENGTH(ContextEx, Chunk) ((ContextEx)->Chunk.Length)
#define RTL_CONTEXT_EX_CHUNK(Base, Layout, Chunk) ((PVOID)((PUCHAR)(Base) + RTL_CONTEXT_EX_OFFSET(Layout, Chunk)))
#define RTL_CONTEXT_OFFSET(Context, Chunk) RTL_CONTEXT_EX_OFFSET((PCONTEXT_EX)((Context) + 1), Chunk)
#define RTL_CONTEXT_LENGTH(Context, Chunk) RTL_CONTEXT_EX_LENGTH((PCONTEXT_EX)((Context) + 1), Chunk)
#define RTL_CONTEXT_CHUNK(Context, Chunk) RTL_CONTEXT_EX_CHUNK((PCONTEXT_EX)((Context) + 1), (PCONTEXT_EX)((Context) + 1), Chunk)
/**
* The RtlInitializeContext function initializes a CONTEXT structure.
*
* \param ProcessHandle Handle to the process to write the CONTEXT. (32bit only)
* \param Context A pointer to a buffer within which to initialize a CONTEXT structure.
* \param Parameter Optional parameter passed to the thread start routine.
* \param InitialPc Initial instruction pointer (thread start routine).
* \param InitialSp Initial stack pointer.
* \return On 32bit, returns the status of NtWriteVirtualMemory. On 64bit, returns a constant value (0xf0e0d0c0a0908070).
* \remarks The return value on 64bit systems is not an NTSTATUS; callers should ignore it.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-initializecontext
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeContext(
_In_ HANDLE ProcessHandle,
_Out_ PCONTEXT Context,
_In_opt_ PVOID Parameter,
_In_opt_ PVOID InitialPc,
_In_opt_ PVOID InitialSp
);
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeExtendedContext(
_Out_ PCONTEXT Context,
_In_ ULONG ContextFlags,
_Out_ PCONTEXT_EX* ContextEx
);
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeExtendedContext2(
_Out_ PCONTEXT Context,
_In_ ULONG ContextFlags,
_Out_ PCONTEXT_EX* ContextEx,
_In_ ULONG64 EnabledExtendedFeatures // RtlGetEnabledExtendedFeatures(-1)
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCopyContext(
_Inout_ PCONTEXT Context,
_In_ ULONG ContextFlags,
_Out_ PCONTEXT Source
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCopyExtendedContext(
_Out_ PCONTEXT_EX Destination,
_In_ ULONG ContextFlags,
_In_ PCONTEXT_EX Source
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetExtendedContextLength(
_In_ ULONG ContextFlags,
_Out_ PULONG ContextLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetExtendedContextLength2(
_In_ ULONG ContextFlags,
_Out_ PULONG ContextLength,
_In_ ULONG64 EnabledExtendedFeatures // RtlGetEnabledExtendedFeatures(-1)
);
NTSYSAPI
ULONG64
NTAPI
RtlGetExtendedFeaturesMask(
_In_ PCONTEXT_EX ContextEx
);
NTSYSAPI
PVOID
NTAPI
RtlLocateExtendedFeature(
_In_ PCONTEXT_EX ContextEx,
_In_ ULONG FeatureId,
_Out_opt_ PULONG Length
);
NTSYSAPI
PVOID
NTAPI
RtlLocateExtendedFeature2(
_In_ PCONTEXT_EX ContextEx,
_In_ ULONG FeatureId,
_In_ XSTATE_CONFIGURATION XState,
_Out_opt_ PULONG Length
);
NTSYSAPI
PCONTEXT
NTAPI
RtlLocateLegacyContext(
_In_ PCONTEXT_EX ContextEx,
_Out_opt_ PULONG Length
);
NTSYSAPI
VOID
NTAPI
RtlSetExtendedFeaturesMask(
_In_ PCONTEXT_EX ContextEx,
_In_ ULONG64 FeatureMask
);
#if defined(_WIN64)
#if defined(_PHLIB_)
FORCEINLINE
NTSTATUS
NTAPI_INLINE
RtlWow64GetThreadContext(
_In_ HANDLE ThreadHandle,
_Inout_ PWOW64_CONTEXT ThreadContext
)
{
return NtQueryInformationThread(
ThreadHandle,
ThreadWow64Context,
ThreadContext,
sizeof(WOW64_CONTEXT),
NULL
);
}
#else
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64GetThreadContext(
_In_ HANDLE ThreadHandle,
_Inout_ PWOW64_CONTEXT ThreadContext
);
#endif // _PHLIB_
#endif // _WIN64
#if defined(_WIN64)
#if defined(_PHLIB_)
FORCEINLINE
NTSTATUS
NTAPI_INLINE
RtlWow64SetThreadContext(
_In_ HANDLE ThreadHandle,
_In_ PWOW64_CONTEXT ThreadContext
)
{
return NtSetInformationThread(
ThreadHandle,
ThreadWow64Context,
ThreadContext,
sizeof(WOW64_CONTEXT)
);
}
#else
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64SetThreadContext(
_In_ HANDLE ThreadHandle,
_In_ PWOW64_CONTEXT ThreadContext
);
#endif // _PHLIB_
#endif // _WIN64
/**
* The RtlRemoteCall routine calls a function in the context of a specified thread in a remote process.
*
* \param ProcessHandle Handle to the process in which the thread resides.
* \param ThreadHandle Handle to the thread in which the function is to be called.
* \param CallSite Address of the function to call in the remote process.
* \param ArgumentCount Number of arguments to pass to the function.
* \param Arguments Pointer to an array of arguments to pass to the function. Can be NULL if no arguments are needed.
* \param PassContext If TRUE, the thread context is passed to the function.
* \param AlreadySuspended If TRUE, the thread is already suspended and does not need to be suspended by this routine.
* \return NTSTATUS Successful or errant status.
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlRemoteCall(
_In_ HANDLE ProcessHandle,
_In_ HANDLE ThreadHandle,
_In_ PVOID CallSite,
_In_ ULONG ArgumentCount,
_In_opt_ PULONG_PTR Arguments,
_In_ BOOLEAN PassContext,
_In_ BOOLEAN AlreadySuspended
);
//
// Vectored Exception Handlers
//
/**
* Registers a vectored exception handler.
*
* \param First If this parameter is TRUE, the handler is the first handler in the list.
* \param Handler A pointer to the vectored exception handler to be called.
* \return A handle to the vectored exception handler.
* \see https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-addvectoredexceptionhandler
*/
NTSYSAPI
PVOID
NTAPI
RtlAddVectoredExceptionHandler(
_In_ ULONG First,
_In_ PVECTORED_EXCEPTION_HANDLER Handler
);
/**
* Removes a vectored exception handler.
*
* \param Handle A handle to the vectored exception handler to remove.
* \return The function returns 0 if the handler is removed, or -1 if the handler is not found.
* \see https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-removevectoredexceptionhandler
*/
NTSYSAPI
ULONG
NTAPI
RtlRemoveVectoredExceptionHandler(
_In_ PVOID Handle
);
/**
* Registers a vectored continue handler.
*
* \param First If this parameter is TRUE, the handler is the first handler in the list.
* \param Handler A pointer to the vectored exception handler to be called.
* \return A handle to the vectored continue handler.
* \see https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-addvectoredcontinuehandler
*/
NTSYSAPI
PVOID
NTAPI
RtlAddVectoredContinueHandler(
_In_ ULONG First,
_In_ PVECTORED_EXCEPTION_HANDLER Handler
);
/**
* Removes a vectored continue handler.
*
* \param Handle A handle to the vectored continue handler to remove.
* \return The function returns 0 if the handler is removed, or -1 if the handler is not found.
* \see https://docs.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-removevectoredcontinuehandler
*/
NTSYSAPI
ULONG
NTAPI
RtlRemoveVectoredContinueHandler(
_In_ PVOID Handle
);
//
// Runtime exception handling
//
typedef _Function_class_(RTLP_UNHANDLED_EXCEPTION_FILTER)
LONG NTAPI RTLP_UNHANDLED_EXCEPTION_FILTER(
_In_ PEXCEPTION_POINTERS ExceptionInfo
);
typedef RTLP_UNHANDLED_EXCEPTION_FILTER* PRTLP_UNHANDLED_EXCEPTION_FILTER;
NTSYSAPI
VOID
NTAPI
RtlSetUnhandledExceptionFilter(
_In_opt_ PRTLP_UNHANDLED_EXCEPTION_FILTER UnhandledExceptionFilter
);
// rev
NTSYSAPI
LONG
NTAPI
RtlUnhandledExceptionFilter(
_In_ PEXCEPTION_POINTERS ExceptionPointers
);
// rev
NTSYSAPI
LONG
NTAPI
RtlUnhandledExceptionFilter2(
_In_ PEXCEPTION_POINTERS ExceptionPointers,
_In_ ULONG Flags
);
// rev
NTSYSAPI
LONG
NTAPI
RtlKnownExceptionFilter(
_In_ PEXCEPTION_POINTERS ExceptionPointers
);
#ifdef _WIN64
// private
typedef enum _FUNCTION_TABLE_TYPE
{
RF_SORTED,
RF_UNSORTED,
RF_CALLBACK,
RF_KERNEL_DYNAMIC
} FUNCTION_TABLE_TYPE;
// private
typedef struct _DYNAMIC_FUNCTION_TABLE
{
LIST_ENTRY ListEntry;
PRUNTIME_FUNCTION FunctionTable;
LARGE_INTEGER TimeStamp;
ULONG64 MinimumAddress;
ULONG64 MaximumAddress;
ULONG64 BaseAddress;
PGET_RUNTIME_FUNCTION_CALLBACK Callback;
PVOID Context;
PWSTR OutOfProcessCallbackDll;
FUNCTION_TABLE_TYPE Type;
ULONG EntryCount;
RTL_BALANCED_NODE TreeNodeMin;
RTL_BALANCED_NODE TreeNodeMax;
} DYNAMIC_FUNCTION_TABLE, *PDYNAMIC_FUNCTION_TABLE;
// rev
NTSYSAPI
PLIST_ENTRY
NTAPI
RtlGetFunctionTableListHead(
VOID
);
#endif // _WIN64
//
// Linked lists
//
NTSYSAPI
VOID
NTAPI
RtlInitializeSListHead(
_Out_ PSLIST_HEADER ListHead
);
_Must_inspect_result_
NTSYSAPI
PSLIST_ENTRY
NTAPI
RtlFirstEntrySList(
_In_ const SLIST_HEADER *ListHead
);
NTSYSAPI
PSLIST_ENTRY
NTAPI
RtlInterlockedPopEntrySList(
_Inout_ PSLIST_HEADER ListHead
);
NTSYSAPI
PSLIST_ENTRY
NTAPI
RtlInterlockedPushEntrySList(
_Inout_ PSLIST_HEADER ListHead,
_Inout_ __drv_aliasesMem PSLIST_ENTRY ListEntry
);
NTSYSAPI
PSLIST_ENTRY
NTAPI
RtlInterlockedPushListSListEx(
_Inout_ PSLIST_HEADER ListHead,
_Inout_ __drv_aliasesMem PSLIST_ENTRY List,
_Inout_ PSLIST_ENTRY ListEnd,
_In_ ULONG Count
);
NTSYSAPI
PSLIST_ENTRY
NTAPI
RtlInterlockedFlushSList(
_Inout_ PSLIST_HEADER ListHead
);
NTSYSAPI
USHORT
NTAPI
RtlQueryDepthSList(
_In_ PSLIST_HEADER ListHead
);
//
// Activation Contexts
//
#define INVALID_ACTIVATION_CONTEXT ((HANDLE)(LONG_PTR)-1)
#define ACTCTX_PROCESS_DEFAULT ((HANDLE)(LONG_PTR)0)
#define ACTCTX_EMPTY ((HANDLE)(LONG_PTR)-3)
#define ACTCTX_SYSTEM_DEFAULT ((HANDLE)(LONG_PTR)-4)
#define IS_SPECIAL_ACTCTX(x) (((((LONG_PTR)(x)) - 1) | 7) == -1)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlGetActiveActivationContext(
_Out_ PACTIVATION_CONTEXT ActivationContext
);
// private
NTSYSAPI
VOID
NTAPI
RtlAddRefActivationContext(
_In_ PACTIVATION_CONTEXT ActivationContext
);
// private
NTSYSAPI
VOID
NTAPI
RtlReleaseActivationContext(
_In_ PACTIVATION_CONTEXT ActivationContext
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlZombifyActivationContext(
_In_ PACTIVATION_CONTEXT ActivationContext
);
// private
NTSYSAPI
BOOLEAN
NTAPI
RtlIsActivationContextActive(
_In_ PACTIVATION_CONTEXT ActivationContext
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlActivateActivationContext(
_Reserved_ ULONG Flags,
_In_ PACTIVATION_CONTEXT ActivationContext,
_Out_ PULONG_PTR Cookie
);
#define RTL_ACTIVATE_ACTIVATION_CONTEXT_EX_FLAG_RELEASE_ON_STACK_DEALLOCATION 0x00000001
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlActivateActivationContextEx(
_In_ ULONG Flags,
_In_ PTEB Teb,
_In_ PACTIVATION_CONTEXT ActivationContext,
_Out_ PULONG_PTR Cookie
);
#define RTL_DEACTIVATE_ACTIVATION_CONTEXT_FLAG_FORCE_EARLY_DEACTIVATION 0x00000001
// private
NTSYSAPI
VOID
NTAPI
RtlDeactivateActivationContext(
_In_ ULONG Flags,
_In_ ULONG_PTR Cookie
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateActivationContext(
_Reserved_ ULONG Flags,
_In_ PACTIVATION_CONTEXT_DATA ActivationContextData,
_In_opt_ ULONG ExtraBytes,
_In_opt_ PACTIVATION_CONTEXT_NOTIFY_ROUTINE NotificationRoutine,
_In_opt_ PVOID NotificationContext,
_Out_ PACTIVATION_CONTEXT *ActivationContext
);
#define FIND_ACTIVATION_CONTEXT_SECTION_KEY_RETURN_ACTIVATION_CONTEXT 0x00000001
#define FIND_ACTIVATION_CONTEXT_SECTION_KEY_RETURN_FLAGS 0x00000002
#define FIND_ACTIVATION_CONTEXT_SECTION_KEY_RETURN_ASSEMBLY_METADATA 0x00000004
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlFindActivationContextSectionString(
_In_ ULONG Flags,
_In_opt_ PGUID ExtensionGuid,
_In_ ULONG SectionId, // ACTIVATION_CONTEXT_SECTION_*
_In_ PCUNICODE_STRING StringToFind,
_Inout_ PACTCTX_SECTION_KEYED_DATA ReturnedData
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlFindActivationContextSectionGuid(
_In_ ULONG Flags,
_In_opt_ PGUID ExtensionGuid,
_In_ ULONG SectionId, // ACTIVATION_CONTEXT_SECTION_*
_In_ PGUID GuidToFind,
_Inout_ PACTCTX_SECTION_KEYED_DATA ReturnedData
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryActivationContextApplicationSettings(
_Reserved_ ULONG Flags,
_In_ PACTIVATION_CONTEXT ActivationContext,
_In_ PCWSTR SettingsNameSpace,
_In_ PCWSTR SettingName,
_Out_writes_bytes_(BufferLength) PWSTR Buffer,
_In_ SIZE_T BufferLength,
_Out_opt_ PSIZE_T RequiredLength
);
// ACTIVATION_CONTEXT_INFO_CLASS
// ActivationContextBasicInformation // q: ACTIVATION_CONTEXT_BASIC_INFORMATION
// ActivationContextDetailedInformation // q: ACTIVATION_CONTEXT_DETAILED_INFORMATION
// AssemblyDetailedInformationInActivationContext // q: ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION
// FileInformationInAssemblyOfAssemblyInActivationContext // q: ASSEMBLY_FILE_DETAILED_INFORMATION
// RunlevelInformationInActivationContext // q: ACTIVATION_CONTEXT_RUN_LEVEL_INFORMATION
// CompatibilityInformationInActivationContext // q: ACTIVATION_CONTEXT_COMPATIBILITY_INFORMATION[_LEGACY]
// ActivationContextManifestResourceName // q: ULONG
#define RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT 0x00000001
#define RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_ACTIVATION_CONTEXT_IS_MODULE 0x00000002
#define RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_ACTIVATION_CONTEXT_IS_ADDRESS 0x00000004
#define RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_NO_ADDREF 0x80000000
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryInformationActivationContext(
_In_ ULONG Flags,
_In_opt_ PACTIVATION_CONTEXT ActivationContext,
_In_opt_ PACTIVATION_CONTEXT_QUERY_INDEX SubInstanceIndex,
_In_ ACTIVATION_CONTEXT_INFO_CLASS ActivationContextInformationClass,
_Out_writes_bytes_(ActivationContextInformationLength) PVOID ActivationContextInformation,
_In_ SIZE_T ActivationContextInformationLength,
_Out_opt_ PSIZE_T ReturnLength
);
#if defined(_PHLIB_)
// private
FORCEINLINE
NTSTATUS
NTAPI_INLINE
RtlQueryInformationActiveActivationContext(
_In_ ACTIVATION_CONTEXT_INFO_CLASS ActivationContextInformationClass,
_Out_writes_bytes_(ActivationContextInformationLength) PVOID ActivationContextInformation,
_In_ SIZE_T ActivationContextInformationLength,
_Out_opt_ PSIZE_T ReturnLength
)
{
return RtlQueryInformationActivationContext(
RTL_QUERY_INFORMATION_ACTIVATION_CONTEXT_FLAG_USE_ACTIVE_ACTIVATION_CONTEXT,
NULL,
NULL,
ActivationContextInformationClass,
ActivationContextInformation,
ActivationContextInformationLength,
ReturnLength
);
}
#else
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryInformationActiveActivationContext(
_In_ ACTIVATION_CONTEXT_INFO_CLASS ActivationContextInformationClass,
_Out_writes_bytes_(ActivationContextInformationLength) PVOID ActivationContextInformation,
_In_ SIZE_T ActivationContextInformationLength,
_Out_opt_ PSIZE_T ReturnLength
);
#endif // _PHLIB_
//
// Images
//
NTSYSAPI
PIMAGE_NT_HEADERS
NTAPI
RtlImageNtHeader(
_In_ PVOID BaseOfImage
);
/**
* Flag to disable range checking in RtlImageNtHeaderEx.
*/
#define RTL_IMAGE_NT_HEADER_EX_FLAG_NO_RANGE_CHECK 0x00000001
NTSYSAPI
NTSTATUS
NTAPI
RtlImageNtHeaderEx(
_In_ ULONG Flags,
_In_ PVOID BaseOfImage,
_In_ ULONG64 Size,
_Out_ PIMAGE_NT_HEADERS *OutHeaders
);
NTSYSAPI
PVOID
NTAPI
RtlAddressInSectionTable(
_In_ PIMAGE_NT_HEADERS NtHeaders,
_In_ PVOID BaseOfImage,
_In_ ULONG VirtualAddress
);
NTSYSAPI
PIMAGE_SECTION_HEADER
NTAPI
RtlSectionTableFromVirtualAddress(
_In_ PIMAGE_NT_HEADERS NtHeaders,
_In_ PVOID BaseOfImage,
_In_ ULONG VirtualAddress
);
NTSYSAPI
PVOID
NTAPI
RtlImageDirectoryEntryToData(
_In_ PVOID BaseOfImage,
_In_ BOOLEAN MappedAsImage,
_In_ USHORT DirectoryEntry,
_Out_ PULONG Size
);
NTSYSAPI
PIMAGE_SECTION_HEADER
NTAPI
RtlImageRvaToSection(
_In_ PIMAGE_NT_HEADERS NtHeaders,
_In_ PVOID BaseOfImage,
_In_ ULONG Rva
);
NTSYSAPI
PVOID
NTAPI
RtlImageRvaToVa(
_In_ PIMAGE_NT_HEADERS NtHeaders,
_In_ PVOID BaseOfImage,
_In_ ULONG Rva,
_Out_opt_ PIMAGE_SECTION_HEADER *LastRvaSection
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS1)
// rev
NTSYSAPI
PVOID
NTAPI
RtlFindExportedRoutineByName(
_In_ PVOID BaseOfImage,
_In_z_ PCSTR RoutineName
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGuardCheckLongJumpTarget(
_In_ PVOID PcValue,
_In_ BOOL IsFastFail,
_Out_ PBOOL IsLongJumpTarget
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS1
#if (PHNT_VERSION >= PHNT_WINDOWS_11_22H2)
NTSYSAPI
VOID
NTAPI
RtlValidateUserCallTarget(
_In_ PVOID Address,
_Out_ PULONG Flags
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11_22H2
//
// Memory
//
_Check_return_
NTSYSAPI
SIZE_T
NTAPI
RtlCompareMemory(
_In_ const VOID* Source1,
_In_ const VOID* Source2,
_In_ SIZE_T Length
);
_Must_inspect_result_
NTSYSAPI
SIZE_T
NTAPI
RtlCompareMemoryUlong(
_In_reads_bytes_(Length) PVOID Source,
_In_ SIZE_T Length,
_In_ ULONG Pattern
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCopyMappedMemory(
_Out_writes_bytes_all_(Length) PVOID Destination,
_In_reads_bytes_(Length) PVOID Source,
_In_ SIZE_T Length
);
#if defined(_M_AMD64) || defined(_M_ARM64)
NTSYSAPI
VOID
NTAPI
RtlCopyMemoryNonTemporal(
_Out_writes_bytes_all_(Length) VOID UNALIGNED *Destination,
_In_reads_bytes_(Length) CONST VOID UNALIGNED *Source,
_In_ SIZE_T Length
);
NTSYSAPI
VOID
NTAPI
RtlFillMemoryNonTemporal(
_Out_writes_bytes_all_(Length) VOID UNALIGNED *Destination,
_In_ SIZE_T Length,
_In_ CONST UCHAR Value
);
#else
#define RtlCopyMemoryNonTemporal RtlCopyMemory
#define RtlFillMemoryNonTemporal RtlFillMemory
#endif
#if defined(_M_AMD64)
FORCEINLINE
VOID
NTAPI_INLINE
RtlFillMemoryUlong(
_Out_writes_bytes_all_(Length) PVOID Destination,
_In_ SIZE_T Length,
_In_ ULONG Pattern
)
{
PULONG Address = (PULONG)Destination;
//
// If the number of DWORDs is not zero, then fill the specified buffer
// with the specified pattern.
//
if ((Length /= 4) != 0) {
//
// If the destination is not quadword aligned (ignoring low bits),
// then align the destination by storing one DWORD.
//
if (((ULONG64)Address & 4) != 0) {
*Address = Pattern;
if ((Length -= 1) == 0) {
return;
}
Address += 1;
}
//
// If the number of QWORDs is not zero, then fill the destination
// buffer a QWORD at a time.
//
__stosq((PULONG64)(Address),
Pattern | ((ULONG64)Pattern << 32),
Length / 2);
if ((Length & 1) != 0) {
Address[Length - 1] = Pattern;
}
}
return;
}
#else
NTSYSAPI
VOID
NTAPI
RtlFillMemoryUlong(
_Out_writes_bytes_all_(Length) PVOID Destination,
_In_ SIZE_T Length,
_In_ ULONG Pattern
);
#endif // _M_AMD64
#if defined(_M_AMD64)
#define RtlFillMemoryUlonglong(Destination, Length, Pattern) \
__stosq((PULONG64)(Destination), Pattern, (Length) / 8)
#else
NTSYSAPI
VOID
NTAPI
RtlFillMemoryUlonglong(
_Out_writes_bytes_all_(Length) PVOID Destination,
_In_ SIZE_T Length,
_In_ ULONGLONG Pattern
);
#endif // _M_AMD64
#if (PHNT_VERSION >= PHNT_WINDOWS_10_19H2)
NTSYSAPI
BOOLEAN
NTAPI
RtlIsZeroMemory(
_In_ PVOID Buffer,
_In_ SIZE_T Length
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_19H2
NTSYSAPI
ULONG
NTAPI
RtlCrc32(
_In_reads_bytes_(Size) const void *Buffer,
_In_ size_t Size,
_In_ ULONG InitialCrc
);
NTSYSAPI
ULONGLONG
NTAPI
RtlCrc64(
_In_reads_bytes_(Size) const void *Buffer,
_In_ size_t Size,
_In_ ULONGLONG InitialCrc
);
// RTL_SYSTEM_GLOBAL_DATA_ID
#define GlobalDataIdUnknown 0
#define GlobalDataIdRngSeedVersion 1 // KUSER_SHARED_DATA->RngSeedVersion
#define GlobalDataIdInterruptTime 2 // KUSER_SHARED_DATA->InterruptTime
#define GlobalDataIdTimeZoneBias 3 // KUSER_SHARED_DATA->TimeZoneBias
#define GlobalDataIdImageNumberLow 4 // KUSER_SHARED_DATA->ImageNumberLow
#define GlobalDataIdImageNumberHigh 5 // KUSER_SHARED_DATA->ImageNumberHigh
#define GlobalDataIdTimeZoneId 6 // KUSER_SHARED_DATA->TimeZoneId
#define GlobalDataIdNtMajorVersion 7 // KUSER_SHARED_DATA->NtMajorVersion
#define GlobalDataIdNtMinorVersion 8 // KUSER_SHARED_DATA->NtMinorVersion
#define GlobalDataIdSystemExpirationDate 9 // KUSER_SHARED_DATA->SystemExpirationDate
#define GlobalDataIdKdDebuggerEnabled 10 // KUSER_SHARED_DATA->KdDebuggerEnabled
#define GlobalDataIdCyclesPerYield 11 // KUSER_SHARED_DATA->CyclesPerYield
#define GlobalDataIdSafeBootMode 12 // KUSER_SHARED_DATA->SafeBootMode
#define GlobalDataIdLastSystemRITEventTickCount 13 // KUSER_SHARED_DATA->LastSystemRITEventTickCount
#define GlobalDataIdConsoleSharedDataFlags 14 // KUSER_SHARED_DATA->ConsoleSharedDataFlags
#define GlobalDataIdNtSystemRootDrive 15 // KUSER_SHARED_DATA->NtSystemRoot // RtlGetNtSystemRoot
#define GlobalDataIdQpcBypassEnabled 16 // KUSER_SHARED_DATA->QpcBypassEnabled
#define GlobalDataIdQpcData 17 // KUSER_SHARED_DATA->QpcData
#define GlobalDataIdQpcBias 18 // KUSER_SHARED_DATA->QpcBias
#if !defined(NTDDI_WIN10_FE) || (NTDDI_VERSION < NTDDI_WIN10_FE)
typedef ULONG RTL_SYSTEM_GLOBAL_DATA_ID;
#endif // !defined(NTDDI_WIN10_FE) || (NTDDI_VERSION < NTDDI_WIN10_FE)
NTSYSAPI
ULONG
NTAPI
RtlGetSystemGlobalData(
_In_ RTL_SYSTEM_GLOBAL_DATA_ID DataId,
_Inout_ PVOID Buffer,
_In_ ULONG Size
);
NTSYSAPI
ULONG
NTAPI
RtlSetSystemGlobalData(
_In_ RTL_SYSTEM_GLOBAL_DATA_ID DataId,
_In_ PVOID Buffer,
_In_ ULONG Size
);
//
// Environment
//
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateEnvironment(
_In_ BOOLEAN CloneCurrentEnvironment,
_Out_ PVOID *Environment
);
// begin_rev
#define RTL_CREATE_ENVIRONMENT_TRANSLATE 0x1 // translate from multi-byte to Unicode
#define RTL_CREATE_ENVIRONMENT_TRANSLATE_FROM_OEM 0x2 // translate from OEM to Unicode (Translate flag must also be set)
#define RTL_CREATE_ENVIRONMENT_EMPTY 0x4 // create empty environment block
// end_rev
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateEnvironmentEx(
_In_opt_ PVOID SourceEnvironment,
_Out_ PVOID *Environment,
_In_ ULONG Flags
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDestroyEnvironment(
_In_ _Post_invalid_ PVOID Environment
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetCurrentEnvironment(
_In_ PVOID Environment,
_Out_opt_ PVOID *PreviousEnvironment
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSetEnvironmentVar(
_Inout_opt_ PVOID *Environment,
_In_reads_(NameLength) PCWSTR Name,
_In_ SIZE_T NameLength,
_In_reads_(ValueLength) PCWSTR Value,
_In_opt_ SIZE_T ValueLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetEnvironmentVariable(
_Inout_opt_ PVOID *Environment,
_In_ PCUNICODE_STRING Name,
_In_opt_ PCUNICODE_STRING Value
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryEnvironmentVariable(
_In_opt_ PVOID Environment,
_In_reads_(NameLength) PCWSTR Name,
_In_ SIZE_T NameLength,
_Out_writes_opt_(ValueLength) PWSTR Value,
_In_opt_ SIZE_T ValueLength,
_Out_ PSIZE_T ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryEnvironmentVariable_U(
_In_opt_ PVOID Environment,
_In_ PCUNICODE_STRING Name,
_Inout_ PUNICODE_STRING Value
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlExpandEnvironmentStrings(
_In_opt_ PVOID Environment,
_In_reads_(SourceLength) PCWSTR Source,
_In_ SIZE_T SourceLength,
_Out_writes_(DestinationLength) PWSTR Destination,
_In_ SIZE_T DestinationLength,
_Out_opt_ PSIZE_T ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlExpandEnvironmentStrings_U(
_In_opt_ PVOID Environment,
_In_ PCUNICODE_STRING Source,
_Inout_ PUNICODE_STRING Destination,
_Out_opt_ PULONG ReturnedLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetEnvironmentStrings(
_In_ PCWSTR NewEnvironment,
_In_ SIZE_T NewEnvironmentSize
);
//
// Directory and path support
//
typedef struct _RTLP_CURDIR_REF
{
LONG ReferenceCount;
HANDLE DirectoryHandle;
} RTLP_CURDIR_REF, *PRTLP_CURDIR_REF;
typedef struct _RTL_RELATIVE_NAME_U
{
UNICODE_STRING RelativeName;
HANDLE ContainingDirectory;
PRTLP_CURDIR_REF CurDirRef;
} RTL_RELATIVE_NAME_U, *PRTL_RELATIVE_NAME_U;
typedef enum _RTL_PATH_TYPE
{
RtlPathTypeUnknown,
RtlPathTypeUncAbsolute, // "\\\\server\\share\\folder\\file.txt
RtlPathTypeDriveAbsolute, // "C:\\folder\\file.txt"
RtlPathTypeDriveRelative, // "C:folder\\file.txt"
RtlPathTypeRooted, // "\\folder\\file.txt"
RtlPathTypeRelative, // "folder\\file.txt"
RtlPathTypeLocalDevice, // "\\\\.\\PhysicalDrive0"
RtlPathTypeRootLocalDevice // "\\\\?\\C:\\folder\\file.txt"
} RTL_PATH_TYPE;
#if !defined(PHNT_INLINE_SEPERATOR_STRINGS)
#define RtlNtdllName L"ntdll.dll"
#define RtlDosPathSeperatorsString ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L"\\/"))
#define RtlAlternateDosPathSeperatorString ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L"/"))
#define RtlNtPathSeperatorString ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L"\\"))
#define RtlDosDevicesPrefix ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L"\\??\\"))
#define RtlDosDevicesUncPrefix ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L"\\??\\UNC\\"))
#define RtlSlashSlashDot ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L"\\\\.\\"))
#define RtlNullString ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L""))
#define RtlWin32NtRootSlash ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L"\\\\?\\"))
#define RtlWin32NtRoot ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L"\\\\?"))
#define RtlWin32NtUncRoot ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L"\\\\?\\UNC"))
#define RtlWin32NtUncRootSlash ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L"\\\\?\\UNC\\"))
#define RtlDefaultExtension ((CONST UNICODE_STRING)RTL_CONSTANT_STRING(L".DLL"))
#else
// Data exports (ntdll.lib/ntdllp.lib)
NTSYSAPI PCWSTR RtlNtdllName;
NTSYSAPI UNICODE_STRING RtlDosPathSeperatorsString;
NTSYSAPI UNICODE_STRING RtlAlternateDosPathSeperatorString;
NTSYSAPI UNICODE_STRING RtlNtPathSeperatorString;
#endif // PHNT_INLINE_SEPERATOR_STRINGS
//
// Path functions
//
/**
* The RtlDetermineDosPathNameType_U routine determines the type of Dos or Win32 path type for the specified filename.
*
* \param DosFileName A pointer to the buffer that contains the Dos or Win32 filename.
* \return The return value specifies the path type for the specified file.
*/
NTSYSAPI
RTL_PATH_TYPE
NTAPI
RtlDetermineDosPathNameType_U(
_In_ PCWSTR DosFileName
);
/**
* The RtlIsDosDeviceName_U routine examines the Dos format file name and determines if it is a Dos device name.
*
* \param DosFileName A pointer to the buffer that contains the DOS or Win32 filename.
* \return A nonzero value when the Dos file name is the name of a Dos device. The high order 16 bits is the offset
* in the input buffer where the dos device name beings and the low order 16 bits is the length of the device name (excluding any optional trailing colon).
* Otherwise, A zero value when the Dos file name is not the name of a Dos device.
* \sa https://learn.microsoft.com/en-us/windows/win32/devnotes/rtlisdosdevicename_u
*/
NTSYSAPI
ULONG
NTAPI
RtlIsDosDeviceName_U(
_In_ PCWSTR DosFileName
);
/**
* The RtlGetFullPathName_U routine retrieves the full path and file name of the specified file.
*
* \param FileName A pointer to the buffer that contains the relative filename.
* \param BufferLength The length of the buffer for the file path string, in WCHARs. The buffer length must include room for a terminating null character.
* \param Buffer A pointer to the buffer that receives the file path string.
* \param FilePart A pointer to a buffer that receives the address (within Buffer) of the final file name component in the path.
* \return If the function succeeds, the return value specifies the number of characters that are written to the buffer, not including the terminating null character.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamea
*/
NTSYSAPI
ULONG
NTAPI
RtlGetFullPathName_U(
_In_ PCWSTR FileName,
_In_ ULONG BufferLength,
_Out_writes_bytes_(BufferLength) PWSTR Buffer,
_Out_opt_ PWSTR *FilePart
);
// rev
/**
* The RtlGetFullPathName_UEx routine retrieves the full path and file name of the specified file.
*
* \param FileName A pointer to the buffer that contains the relative filename.
* \param BufferLength The length of the buffer for the file path string, in WCHARs. The buffer length must include room for a terminating null character.
* \param Buffer A pointer to the buffer that receives the file path string.
* \param FilePart A pointer to a buffer that receives the address (within Buffer) of the final file name component in the path.
* \param BytesRequired If the function succeeds, the return value specifies the number of characters that are written to the buffer, not including the terminating null character.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamea
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlGetFullPathName_UEx(
_In_ PCWSTR FileName,
_In_ ULONG BufferLength,
_Out_writes_bytes_(BufferLength) PWSTR Buffer,
_Out_opt_ PWSTR *FilePart,
_Out_opt_ ULONG *BytesRequired
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetFullPathName_UstrEx(
_In_ PCUNICODE_STRING FileName,
_Inout_ PUNICODE_STRING StaticString,
_Out_opt_ PUNICODE_STRING DynamicString,
_Out_opt_ PUNICODE_STRING *StringUsed,
_Out_opt_ SIZE_T *FilePartPrefixCch,
_Out_opt_ PBOOLEAN NameInvalid,
_Out_ RTL_PATH_TYPE *InputPathType,
_Out_opt_ SIZE_T *BytesRequired
);
/**
* The RtlGetCurrentDirectory_U routine retrieves the current directory for the current process.
*
* \param BufferLength The length of the buffer for the current directory string, in WCHARs. The buffer length must include room for a terminating null character.
* \param Buffer A pointer to the buffer that receives the current directory string.
* \return If the function succeeds, the return value specifies the number of characters that are written to the buffer, not including the terminating null character.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcurrentdirectory
*/
NTSYSAPI
ULONG
NTAPI
RtlGetCurrentDirectory_U(
_In_ ULONG BufferLength,
_Out_writes_bytes_(BufferLength) PWSTR Buffer
);
/**
* The RtlSetCurrentDirectory_U routine changes the current directory for the current process.
*
* \param PathName The path to the new current directory.
* This parameter may specify a relative path or a full path. In either case, the full path of the specified directory is calculated and stored as the current directory.
* \return If the function succeeds, the return value specifies the number of characters that are written to the buffer, not including the terminating null character.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-getcurrentdirectory
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlSetCurrentDirectory_U(
_In_ PCUNICODE_STRING PathName
);
NTSYSAPI
ULONG
NTAPI
RtlGetLongestNtPathLength(
VOID
);
// rev
typedef struct _RTL_BUFFER
{
PUCHAR Buffer;
PUCHAR StaticBuffer;
SIZE_T Size;
SIZE_T StaticSize;
} RTL_BUFFER, *PRTL_BUFFER;
//FORCEINLINE
//VOID
//RtlInitBuffer(
// _Inout_ PRTL_BUFFER Buffer,
// _In_ PUCHAR Data,
// _In_ ULONG DataSize
// )
//{
// Buffer->Buffer = Buffer->StaticBuffer = Data;
// Buffer->Size = Buffer->StaticSize = DataSize;
//}
//
//FORCEINLINE
//VOID
//RtlFreeBuffer(
// _Inout_ PRTL_BUFFER Buffer
// )
//{
// if (Buffer->Buffer != Buffer->StaticBuffer && Buffer->Buffer)
// RtlFreeHeap(RtlProcessHeap(), 0, Buffer->Buffer);
// Buffer->Buffer = Buffer->StaticBuffer;
// Buffer->Size = Buffer->StaticSize;
//}
// rev
typedef struct _RTL_UNICODE_STRING_BUFFER
{
UNICODE_STRING String;
RTL_BUFFER ByteBuffer;
UCHAR MinimumStaticBufferForTerminalNul[2];
} RTL_UNICODE_STRING_BUFFER, *PRTL_UNICODE_STRING_BUFFER;
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlNtPathNameToDosPathName(
_Reserved_ ULONG Flags,
_Inout_ PRTL_UNICODE_STRING_BUFFER Path,
_Out_opt_ PULONG Disposition, // RtlDetermineDosPathNameType_U
_Inout_opt_ PWSTR* FilePart
);
NTSYSAPI
BOOLEAN
NTAPI
RtlDosPathNameToNtPathName_U(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR *FilePart,
_Out_opt_ PRTL_RELATIVE_NAME_U RelativeName
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDosPathNameToNtPathName_U_WithStatus(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR *FilePart,
_Out_opt_ PRTL_RELATIVE_NAME_U RelativeName
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS3)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlDosLongPathNameToNtPathName_U_WithStatus(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR *FilePart,
_Out_opt_ PRTL_RELATIVE_NAME_U RelativeName
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS3
NTSYSAPI
BOOLEAN
NTAPI
RtlDosPathNameToRelativeNtPathName_U(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR *FilePart,
_Out_opt_ PRTL_RELATIVE_NAME_U RelativeName
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDosPathNameToRelativeNtPathName_U_WithStatus(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR *FilePart,
_Out_opt_ PRTL_RELATIVE_NAME_U RelativeName
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS3)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlDosLongPathNameToRelativeNtPathName_U_WithStatus(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR *FilePart,
_Out_opt_ PRTL_RELATIVE_NAME_U RelativeName
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS3
NTSYSAPI
VOID
NTAPI
RtlReleaseRelativeName(
_Inout_ PRTL_RELATIVE_NAME_U RelativeName
);
NTSYSAPI
ULONG
NTAPI
RtlDosSearchPath_U(
_In_ PCWSTR Path,
_In_ PCWSTR FileName,
_In_opt_ PCWSTR Extension,
_In_ ULONG BufferLength,
_Out_writes_bytes_(BufferLength) PWSTR Buffer,
_Out_opt_ PWSTR *FilePart
);
#define RTL_DOS_SEARCH_PATH_FLAG_APPLY_ISOLATION_REDIRECTION 0x00000001
#define RTL_DOS_SEARCH_PATH_FLAG_DISALLOW_DOT_RELATIVE_PATH_SEARCH 0x00000002
#define RTL_DOS_SEARCH_PATH_FLAG_APPLY_DEFAULT_EXTENSION_WHEN_NOT_RELATIVE_PATH_EVEN_IF_FILE_HAS_EXTENSION 0x00000004
NTSYSAPI
NTSTATUS
NTAPI
RtlDosSearchPath_Ustr(
_In_ ULONG Flags,
_In_ PCUNICODE_STRING Path,
_In_ PCUNICODE_STRING FileName,
_In_opt_ PCUNICODE_STRING DefaultExtension,
_Out_opt_ PUNICODE_STRING StaticString,
_Out_opt_ PUNICODE_STRING DynamicString,
_Out_opt_ PCUNICODE_STRING *FullFileNameOut,
_Out_opt_ SIZE_T *FilePartPrefixCch,
_Out_opt_ SIZE_T *BytesRequired
);
NTSYSAPI
BOOLEAN
NTAPI
RtlDoesFileExists_U(
_In_ PCWSTR FileName
);
// ros
NTSYSAPI
NTSTATUS
NTAPI
RtlDosApplyFileIsolationRedirection_Ustr(
_In_ ULONG Flags,
_In_ PCUNICODE_STRING OriginalName,
_In_ PCUNICODE_STRING Extension,
_In_opt_ PCUNICODE_STRING StaticString,
_In_opt_ PCUNICODE_STRING DynamicString,
_In_opt_ PCUNICODE_STRING* NewName,
_In_ PULONG NewFlags,
_In_ PSIZE_T FileNameSize,
_In_ PSIZE_T RequiredLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetLengthWithoutLastFullDosOrNtPathElement(
_Reserved_ ULONG Flags,
_In_ PCUNICODE_STRING PathString,
_Out_ PULONG Length
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetLengthWithoutTrailingPathSeperators(
_Reserved_ ULONG Flags,
_In_ PCUNICODE_STRING PathString,
_Out_ PULONG Length
);
typedef struct _GENERATE_NAME_CONTEXT
{
USHORT Checksum;
BOOLEAN CheckSumInserted;
UCHAR NameLength;
WCHAR NameBuffer[8];
ULONG ExtensionLength;
WCHAR ExtensionBuffer[4];
ULONG LastIndexValue;
} GENERATE_NAME_CONTEXT, *PGENERATE_NAME_CONTEXT;
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlGenerate8dot3Name(
_In_ PCUNICODE_STRING Name,
_In_ BOOLEAN AllowExtendedCharacters,
_Inout_ PGENERATE_NAME_CONTEXT Context,
_Inout_ PUNICODE_STRING Name8dot3
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlComputePrivatizedDllName_U(
_In_ PCUNICODE_STRING DllName,
_Out_ PUNICODE_STRING RealName,
_Out_ PUNICODE_STRING LocalName
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetSearchPath(
_Out_ PCWSTR* Path // RtlReleasePath
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSetSearchPathMode(
_In_ ULONG Flags
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetExePath(
_In_ PCWSTR DosPathName,
_Out_ PCWSTR* Path
);
// rev
NTSYSAPI
VOID
NTAPI
RtlReleasePath(
_In_ PCWSTR Path
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS1)
// rev
NTSYSAPI
ULONG
NTAPI
RtlReplaceSystemDirectoryInPath(
_Inout_ PUNICODE_STRING Destination,
_In_ USHORT Machine, // IMAGE_FILE_MACHINE_I386
_In_ USHORT TargetMachine, // IMAGE_FILE_MACHINE_TARGET_HOST
_In_ BOOLEAN IncludePathSeperator
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS1
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS1)
// rev from Wow64DetermineEnvironment
NTSYSAPI
USHORT
NTAPI
RtlWow64GetCurrentMachine(
VOID
);
// rev from Wow64DetermineEnvironment
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64IsWowGuestMachineSupported(
_In_ USHORT NativeMachine,
_Out_ PBOOLEAN IsWowGuestMachineSupported
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS1
#if (PHNT_VERSION >= PHNT_WINDOWS_10_21H2)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64GetProcessMachines(
_In_ HANDLE ProcessHandle,
_Out_ PUSHORT ProcessMachine,
_Out_opt_ PUSHORT NativeMachine
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_21H2
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
// rev
#define IMAGE_FILE_NATIVE_MACHINE_I386 0x1
#define IMAGE_FILE_NATIVE_MACHINE_AMD64 0x2
#define IMAGE_FILE_NATIVE_MACHINE_ARMNT 0x4
#define IMAGE_FILE_NATIVE_MACHINE_ARM64 0x8
#define IMAGE_FILE_NATIVE_MACHINE_ARM64EC 0x10
#if !defined(NTDDI_WIN11_BR) || (NTDDI_VERSION < NTDDI_WIN11_BR)
// private
typedef struct _IMAGE_FILE_MACHINES
{
union
{
ULONG Value;
struct
{
ULONG MachineX86 : 1;
ULONG MachineAmd64 : 1;
ULONG MachineArm : 1;
ULONG MachineArm64 : 1;
ULONG MachineArm64EC : 1;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
} IMAGE_FILE_MACHINES;
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetImageFileMachines(
_In_ PCWSTR FileName,
_Out_ IMAGE_FILE_MACHINES *MachineTypeFlags
);
#endif // #if !defined(NTDDI_WIN11_BR) || (NTDDI_VERSION < NTDDI_WIN11_BR)
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS2)
// rev
NTSYSAPI
PWSTR
NTAPI
RtlGetNtSystemRoot(
VOID
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlAreLongPathsEnabled(
VOID
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS2
NTSYSAPI
BOOLEAN
NTAPI
RtlIsThreadWithinLoaderCallout(
VOID
);
/**
* Gets a value indicating whether the process is currently in the shutdown phase.
*
* \return TRUE if a shutdown of the current dll process is in progress; otherwise, FALSE.
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlDllShutdownInProgress(
VOID
);
//
// Heaps
//
typedef struct _RTL_HEAP_ENTRY
{
SIZE_T Size;
USHORT Flags;
USHORT AllocatorBackTraceIndex;
union
{
struct
{
SIZE_T Settable;
ULONG Tag;
} s1;
struct
{
SIZE_T CommittedSize;
PVOID FirstBlock;
} s2;
} u;
} RTL_HEAP_ENTRY, *PRTL_HEAP_ENTRY;
#define RTL_HEAP_BUSY (USHORT)0x0001
#define RTL_HEAP_SEGMENT (USHORT)0x0002
#define RTL_HEAP_SETTABLE_VALUE (USHORT)0x0010
#define RTL_HEAP_SETTABLE_FLAG1 (USHORT)0x0020
#define RTL_HEAP_SETTABLE_FLAG2 (USHORT)0x0040
#define RTL_HEAP_SETTABLE_FLAG3 (USHORT)0x0080
#define RTL_HEAP_SETTABLE_FLAGS (USHORT)0x00e0
#define RTL_HEAP_UNCOMMITTED_RANGE (USHORT)0x1000
#define RTL_HEAP_PROTECTED_ENTRY (USHORT)0x2000
#define RTL_HEAP_LARGE_ALLOC (USHORT)0x4000
#define RTL_HEAP_LFH_ALLOC (USHORT)0x8000
typedef struct _RTL_HEAP_TAG
{
ULONG NumberOfAllocations;
ULONG NumberOfFrees;
SIZE_T BytesAllocated;
USHORT TagIndex;
USHORT CreatorBackTraceIndex;
WCHAR TagName[24];
} RTL_HEAP_TAG, *PRTL_HEAP_TAG;
// Windows 7/8/10
typedef struct _RTL_HEAP_INFORMATION_V1
{
PVOID BaseAddress;
ULONG Flags;
USHORT EntryOverhead;
USHORT CreatorBackTraceIndex;
SIZE_T BytesAllocated;
SIZE_T BytesCommitted;
ULONG NumberOfTags;
ULONG NumberOfEntries;
ULONG NumberOfPseudoTags;
ULONG PseudoTagGranularity;
ULONG Reserved[5];
PRTL_HEAP_TAG Tags;
PRTL_HEAP_ENTRY Entries;
} RTL_HEAP_INFORMATION_V1, *PRTL_HEAP_INFORMATION_V1;
// Windows 11 > 22000
typedef struct _RTL_HEAP_INFORMATION_V2
{
PVOID BaseAddress;
ULONG Flags;
USHORT EntryOverhead;
USHORT CreatorBackTraceIndex;
SIZE_T BytesAllocated;
SIZE_T BytesCommitted;
ULONG NumberOfTags;
ULONG NumberOfEntries;
ULONG NumberOfPseudoTags;
ULONG PseudoTagGranularity;
ULONG Reserved[5];
PRTL_HEAP_TAG Tags;
PRTL_HEAP_ENTRY Entries;
ULONG64 HeapTag;
} RTL_HEAP_INFORMATION_V2, *PRTL_HEAP_INFORMATION_V2;
#define RTL_HEAP_SIGNATURE 0xFFEEFFEEUL
#define RTL_HEAP_SEGMENT_SIGNATURE 0xDDEEDDEEUL
typedef struct _RTL_PROCESS_HEAPS_V1
{
ULONG NumberOfHeaps;
_Field_size_(NumberOfHeaps) RTL_HEAP_INFORMATION_V1 Heaps[1];
} RTL_PROCESS_HEAPS_V1, *PRTL_PROCESS_HEAPS_V1;
typedef struct _RTL_PROCESS_HEAPS_V2
{
ULONG NumberOfHeaps;
_Field_size_(NumberOfHeaps) RTL_HEAP_INFORMATION_V2 Heaps[1];
} RTL_PROCESS_HEAPS_V2, *PRTL_PROCESS_HEAPS_V2;
//
// Segment heap parameters.
//
typedef enum _RTL_MEMORY_TYPE
{
MemoryTypePaged,
MemoryTypeNonPaged,
MemoryType64KPage,
MemoryTypeLargePage,
MemoryTypeHugePage,
MemoryTypeCustom,
MemoryTypeMax
} RTL_MEMORY_TYPE, *PRTL_MEMORY_TYPE;
typedef enum _HEAP_MEMORY_INFO_CLASS
{
HeapMemoryBasicInformation
} HEAP_MEMORY_INFO_CLASS;
typedef _Function_class_(ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK)
NTSTATUS NTAPI ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK(
_Inout_ HANDLE CallbackContext,
_In_ HANDLE ProcessHandle,
_Inout_ _At_ (*BaseAddress, _Readable_bytes_ (*RegionSize) _Writable_bytes_ (*RegionSize) _Post_readable_byte_size_ (*RegionSize)) PVOID* BaseAddress,
_Inout_ PSIZE_T RegionSize,
_In_ ULONG AllocationType,
_In_ ULONG PageProtection,
_Inout_updates_opt_(ExtendedParameterCount) PMEM_EXTENDED_PARAMETER ExtendedParameters,
_In_ ULONG ExtendedParameterCount
);
typedef ALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK *PALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK;
typedef _Function_class_(FREE_VIRTUAL_MEMORY_EX_CALLBACK)
NTSTATUS NTAPI FREE_VIRTUAL_MEMORY_EX_CALLBACK(
_Inout_ HANDLE CallbackContext,
_In_ HANDLE ProcessHandle,
_Inout_ __drv_freesMem(Mem) PVOID *BaseAddress,
_Inout_ PSIZE_T RegionSize,
_In_ ULONG FreeType
);
typedef FREE_VIRTUAL_MEMORY_EX_CALLBACK *PFREE_VIRTUAL_MEMORY_EX_CALLBACK;
typedef _Function_class_(QUERY_VIRTUAL_MEMORY_CALLBACK)
NTSTATUS NTAPI QUERY_VIRTUAL_MEMORY_CALLBACK(
_Inout_ HANDLE CallbackContext,
_In_ HANDLE ProcessHandle,
_In_opt_ PVOID BaseAddress,
_In_ HEAP_MEMORY_INFO_CLASS MemoryInformationClass,
_Out_writes_bytes_(MemoryInformationLength) PVOID MemoryInformation,
_In_ SIZE_T MemoryInformationLength,
_Out_opt_ PSIZE_T ReturnLength
);
typedef QUERY_VIRTUAL_MEMORY_CALLBACK *PQUERY_VIRTUAL_MEMORY_CALLBACK;
typedef struct _RTL_SEGMENT_HEAP_VA_CALLBACKS
{
HANDLE CallbackContext;
PALLOCATE_VIRTUAL_MEMORY_EX_CALLBACK AllocateVirtualMemory;
PFREE_VIRTUAL_MEMORY_EX_CALLBACK FreeVirtualMemory;
PQUERY_VIRTUAL_MEMORY_CALLBACK QueryVirtualMemory;
} RTL_SEGMENT_HEAP_VA_CALLBACKS, *PRTL_SEGMENT_HEAP_VA_CALLBACKS;
#define RTL_SEGHEAP_MEM_SOURCE_ANY_NODE ((ULONG)-1)
typedef struct _RTL_SEGMENT_HEAP_MEMORY_SOURCE
{
ULONG Flags;
ULONG MemoryTypeMask; // Mask of RTL_MEMORY_TYPE members.
ULONG NumaNode;
union
{
HANDLE PartitionHandle;
RTL_SEGMENT_HEAP_VA_CALLBACKS *Callbacks;
};
SIZE_T Reserved[2];
} RTL_SEGMENT_HEAP_MEMORY_SOURCE, *PRTL_SEGMENT_HEAP_MEMORY_SOURCE;
#define SEGMENT_HEAP_PARAMETERS_VERSION 3
#define SEGMENT_HEAP_FLG_USE_PAGE_HEAP 0x1
#define SEGMENT_HEAP_FLG_NO_LFH 0x2
#define SEGMENT_HEAP_PARAMS_VALID_FLAGS 0x3
typedef struct _RTL_SEGMENT_HEAP_PARAMETERS
{
USHORT Version;
USHORT Size;
ULONG Flags;
RTL_SEGMENT_HEAP_MEMORY_SOURCE MemorySource;
SIZE_T Reserved[4];
} RTL_SEGMENT_HEAP_PARAMETERS, *PRTL_SEGMENT_HEAP_PARAMETERS;
//
// Heap parameters.
//
typedef _Function_class_(RTL_HEAP_COMMIT_ROUTINE)
NTSTATUS NTAPI RTL_HEAP_COMMIT_ROUTINE(
_In_ PVOID Base,
_Inout_ PVOID* CommitAddress,
_Inout_ PSIZE_T CommitSize
);
typedef RTL_HEAP_COMMIT_ROUTINE* PRTL_HEAP_COMMIT_ROUTINE;
typedef struct _RTL_HEAP_PARAMETERS
{
ULONG Length;
SIZE_T SegmentReserve;
SIZE_T SegmentCommit;
SIZE_T DeCommitFreeBlockThreshold;
SIZE_T DeCommitTotalFreeThreshold;
SIZE_T MaximumAllocationSize;
SIZE_T VirtualMemoryThreshold;
SIZE_T InitialCommit;
SIZE_T InitialReserve;
PRTL_HEAP_COMMIT_ROUTINE CommitRoutine;
SIZE_T Reserved[2];
} RTL_HEAP_PARAMETERS, *PRTL_HEAP_PARAMETERS;
#define HEAP_SETTABLE_USER_VALUE 0x00000100
#define HEAP_SETTABLE_USER_FLAG1 0x00000200
#define HEAP_SETTABLE_USER_FLAG2 0x00000400
#define HEAP_SETTABLE_USER_FLAG3 0x00000800
#define HEAP_SETTABLE_USER_FLAGS 0x00000e00
#define HEAP_CLASS_0 0x00000000 // Process heap
#define HEAP_CLASS_1 0x00001000 // Private heap
#define HEAP_CLASS_2 0x00002000 // Kernel heap
#define HEAP_CLASS_3 0x00003000 // GDI heap
#define HEAP_CLASS_4 0x00004000 // User heap
#define HEAP_CLASS_5 0x00005000 // Console heap
#define HEAP_CLASS_6 0x00006000 // User desktop heap
#define HEAP_CLASS_7 0x00007000 // CSR shared heap
#define HEAP_CLASS_8 0x00008000 // CSR port heap
#define HEAP_CLASS_MASK 0x0000f000
#define HEAP_MAXIMUM_TAG 0x0FFF
#define HEAP_GLOBAL_TAG 0x0800
#define HEAP_PSEUDO_TAG_FLAG 0x8000
#define HEAP_TAG_SHIFT 18
#define HEAP_TAG_MASK (HEAP_MAXIMUM_TAG << HEAP_TAG_SHIFT)
#define HEAP_CREATE_SEGMENT_HEAP 0x00000100
//
// Only applies to segment heap. Applies pointer obfuscation which is
// generally excessive and unnecessary but is necessary for certain insecure
// heaps in win32k.
//
// Specifying HEAP_CREATE_HARDENED prevents the heap from using locks as
// pointers would potentially be exposed in heap metadata lock variables.
// Callers are therefore responsible for synchronizing access to hardened heaps.
//
#define HEAP_CREATE_HARDENED 0x00000200
/**
* The RtlCreateHeap routine creates a heap object that can be used by the calling process. This routine reserves
* space in the virtual address space of the process and allocates physical storage for a specified initial portion of this block.
*
* \param Flags Flags specifying optional attributes of the heap.
* \param HeapBase If HeapBase is a non-NULL value, it specifies the base address for a block of caller-allocated memory to use for the heap.
* \param ReserveSize If ReserveSize is a nonzero value, it specifies the initial amount of memory, in bytes, to reserve for the heap.
* \param CommitSize If CommitSize is a nonzero value, it specifies the initial amount of memory, in bytes, to commit for the heap.
* \param Lock Pointer to an opaque structure to be used as the heap lock.
* \param Parameters Pointer to a RTL_HEAP_PARAMETERS structure that contains parameters to be applied when creating the heap.
* \return RtlCreateHeap returns a handle to be used in accessing the created heap.
* \remarks https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlcreateheap
*/
_Success_(return != 0)
_Must_inspect_result_
_Ret_maybenull_
NTSYSAPI
HANDLE
NTAPI
RtlCreateHeap(
_In_ ULONG Flags,
_In_opt_ PVOID HeapBase,
_In_opt_ SIZE_T ReserveSize,
_In_opt_ SIZE_T CommitSize,
_In_opt_ PVOID Lock,
_When_((Flags & HEAP_CREATE_SEGMENT_HEAP) != 0, _In_reads_bytes_opt_(sizeof(RTL_SEGMENT_HEAP_PARAMETERS)))
_When_((Flags & HEAP_CREATE_SEGMENT_HEAP) == 0, _In_reads_bytes_opt_(sizeof(RTL_HEAP_PARAMETERS)))
_In_opt_ PVOID Parameters
);
/**
* The RtlDestroyHeap routine destroys the specified heap object. RtlDestroyHeap decommits and releases all the pages of a private heap object,
* and it invalidates the handle to the heap.
*
* \param HeapHandle Handle for the heap to be destroyed. This parameter is a heap handle returned by RtlCreateHeap.
* \return If the call to RtlDestroyHeap succeeds, the return value is a NULL pointer. If the call to RtlDestroyHeap fails, the return value is a handle for the heap.
* \remarks https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtldestroyheap
*/
_Success_(return == 0)
NTSYSAPI
PVOID
NTAPI
RtlDestroyHeap(
_In_ _Post_invalid_ HANDLE HeapHandle
);
/**
* The RtlAllocateHeap routine allocates a block of memory from a heap.
*
* \param HeapHandle Handle for a private heap from which the memory will be allocated.
* \param Flags Controllable aspects of heap allocation. Specifying any flags will override the corresponding value specified when the heap was created with RtlCreateHeap.
* \param Size Number of bytes to be allocated. If the heap, specified by the HeapHandle parameter, is a nongrowable heap, Size must be less than or equal to the heap's virtual memory threshold.
* \return If the call to RtlAllocateHeap succeeds, the return value is a pointer to the newly-allocated block. The return value is NULL if the allocation failed.
* \remarks https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlallocateheap
*/
_Success_(return != 0)
_Must_inspect_result_
_Ret_maybenull_
_Post_writable_byte_size_(Size)
__drv_allocatesMem(Mem)
NTSYSAPI
DECLSPEC_ALLOCATOR
DECLSPEC_NOALIAS
DECLSPEC_RESTRICT
PVOID
NTAPI
RtlAllocateHeap(
_In_ HANDLE HeapHandle,
_In_opt_ ULONG Flags,
_In_ SIZE_T Size
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
_Success_(return != 0)
NTSYSAPI
LOGICAL
NTAPI
RtlFreeHeap(
_In_ HANDLE HeapHandle,
_In_opt_ ULONG Flags,
_Frees_ptr_opt_ _Post_invalid_ PVOID BaseAddress
);
#else
_Success_(return)
NTSYSAPI
BOOLEAN
NTAPI
RtlFreeHeap(
_In_ HANDLE HeapHandle,
_In_opt_ ULONG Flags,
_Frees_ptr_opt_ PVOID BaseAddress
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
NTSYSAPI
SIZE_T
NTAPI
RtlSizeHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_In_ PCVOID BaseAddress
);
NTSYSAPI
NTSTATUS
NTAPI
RtlZeroHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags
);
NTSYSAPI
VOID
NTAPI
RtlProtectHeap(
_In_ HANDLE HeapHandle,
_In_ BOOLEAN MakeReadOnly
);
#define RtlProcessHeap() (NtCurrentPeb()->ProcessHeap)
NTSYSAPI
BOOLEAN
NTAPI
RtlLockHeap(
_In_ HANDLE HeapHandle
);
NTSYSAPI
BOOLEAN
NTAPI
RtlUnlockHeap(
_In_ HANDLE HeapHandle
);
_Success_(return != 0)
_Must_inspect_result_
_Ret_maybenull_
_Post_writable_byte_size_(Size)
_When_(Size > 0, __drv_allocatesMem(Mem))
NTSYSAPI
DECLSPEC_ALLOCATOR
DECLSPEC_NOALIAS
DECLSPEC_RESTRICT
PVOID
NTAPI
RtlReAllocateHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_Frees_ptr_opt_ PVOID BaseAddress,
_In_ SIZE_T Size
);
NTSYSAPI
BOOLEAN
NTAPI
RtlGetUserInfoHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_In_ PVOID BaseAddress,
_Out_opt_ PVOID *UserValue,
_Out_opt_ PULONG UserFlags
);
NTSYSAPI
BOOLEAN
NTAPI
RtlSetUserValueHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_In_ PVOID BaseAddress,
_In_ PVOID UserValue
);
NTSYSAPI
BOOLEAN
NTAPI
RtlSetUserFlagsHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_In_ PVOID BaseAddress,
_In_ ULONG UserFlagsReset,
_In_ ULONG UserFlagsSet
);
typedef struct _RTL_HEAP_TAG_INFO
{
ULONG NumberOfAllocations;
ULONG NumberOfFrees;
SIZE_T BytesAllocated;
} RTL_HEAP_TAG_INFO, *PRTL_HEAP_TAG_INFO;
#define RTL_HEAP_MAKE_TAG HEAP_MAKE_TAG_FLAGS
NTSYSAPI
ULONG
NTAPI
RtlCreateTagHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_In_opt_ PCWSTR TagPrefix,
_In_ PCWSTR TagNames
);
NTSYSAPI
PWSTR
NTAPI
RtlQueryTagHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_In_ USHORT TagIndex,
_In_ BOOLEAN ResetCounters,
_Out_opt_ PRTL_HEAP_TAG_INFO TagInfo
);
NTSYSAPI
NTSTATUS
NTAPI
RtlExtendHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_In_ PVOID Base,
_In_ SIZE_T Size
);
NTSYSAPI
SIZE_T
NTAPI
RtlCompactHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags
);
NTSYSAPI
BOOLEAN
NTAPI
RtlValidateHeap(
_In_opt_ HANDLE HeapHandle,
_In_ ULONG Flags,
_In_opt_ PVOID BaseAddress
);
NTSYSAPI
BOOLEAN
NTAPI
RtlValidateProcessHeaps(
VOID
);
NTSYSAPI
ULONG
NTAPI
RtlGetProcessHeaps(
_In_ ULONG NumberOfHeaps,
_Out_ PVOID *ProcessHeaps
);
typedef _Function_class_(RTL_ENUM_HEAPS_ROUTINE)
NTSTATUS NTAPI RTL_ENUM_HEAPS_ROUTINE(
_In_ HANDLE HeapHandle,
_In_ PVOID Parameter
);
typedef RTL_ENUM_HEAPS_ROUTINE *PRTL_ENUM_HEAPS_ROUTINE;
NTSYSAPI
NTSTATUS
NTAPI
RtlEnumProcessHeaps(
_In_ PRTL_ENUM_HEAPS_ROUTINE EnumRoutine,
_In_ PVOID Parameter
);
typedef struct _RTL_HEAP_USAGE_ENTRY
{
struct _RTL_HEAP_USAGE_ENTRY *Next;
PVOID Address;
SIZE_T Size;
USHORT AllocatorBackTraceIndex;
USHORT TagIndex;
} RTL_HEAP_USAGE_ENTRY, *PRTL_HEAP_USAGE_ENTRY;
typedef struct _RTL_HEAP_USAGE
{
ULONG Length;
SIZE_T BytesAllocated;
SIZE_T BytesCommitted;
SIZE_T BytesReserved;
SIZE_T BytesReservedMaximum;
PRTL_HEAP_USAGE_ENTRY Entries;
PRTL_HEAP_USAGE_ENTRY AddedEntries;
PRTL_HEAP_USAGE_ENTRY RemovedEntries;
ULONG_PTR Reserved[8];
} RTL_HEAP_USAGE, *PRTL_HEAP_USAGE;
#define HEAP_USAGE_ALLOCATED_BLOCKS HEAP_REALLOC_IN_PLACE_ONLY
#define HEAP_USAGE_FREE_BUFFER HEAP_ZERO_MEMORY
NTSYSAPI
NTSTATUS
NTAPI
RtlUsageHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_Inout_ PRTL_HEAP_USAGE Usage
);
typedef struct _RTL_HEAP_WALK_ENTRY
{
PVOID DataAddress;
SIZE_T DataSize;
UCHAR OverheadBytes;
UCHAR SegmentIndex;
USHORT Flags;
union
{
struct
{
SIZE_T Settable;
USHORT TagIndex;
USHORT AllocatorBackTraceIndex;
ULONG Reserved[2];
} Block;
struct
{
ULONG CommittedSize;
ULONG UnCommittedSize;
PVOID FirstEntry;
PVOID LastEntry;
} Segment;
};
} RTL_HEAP_WALK_ENTRY, *PRTL_HEAP_WALK_ENTRY;
NTSYSAPI
NTSTATUS
NTAPI
RtlWalkHeap(
_In_ HANDLE HeapHandle,
_Inout_ PRTL_HEAP_WALK_ENTRY Entry
);
// HEAP_INFORMATION_CLASS
#define HeapCompatibilityInformation 0x0 // q; s: ULONG
#define HeapEnableTerminationOnCorruption 0x1 // q; s: NULL
#define HeapExtendedInformation 0x2 // q; s: HEAP_EXTENDED_INFORMATION
#define HeapOptimizeResources 0x3 // q; s: HEAP_OPTIMIZE_RESOURCES_INFORMATION
#define HeapTaggingInformation 0x4 // q: RTLP_HEAP_TAGGING_INFO
#define HeapStackDatabase 0x5 // q: RTL_HEAP_STACK_QUERY; s: RTL_HEAP_STACK_CONTROL
#define HeapMemoryLimit 0x6 // since 19H2
#define HeapTag 0x7 // since 20H1
#define HeapDetailedFailureInformation 0x80000001
#define HeapSetDebuggingInformation 0x80000002 // q; s: HEAP_DEBUGGING_INFORMATION
typedef enum _HEAP_COMPATIBILITY_MODE
{
HEAP_COMPATIBILITY_MODE_STANDARD = 0UL,
HEAP_COMPATIBILITY_MODE_LAL = 1UL, // Lookaside list heap (LAL) compatibility mode.
HEAP_COMPATIBILITY_MODE_LFH = 2UL, // Low-fragmentation heap (LFH) compatibility mode.
} HEAP_COMPATIBILITY_MODE;
typedef struct _RTLP_TAG_INFO
{
GUID Id;
SIZE_T CurrentAllocatedBytes;
} RTLP_TAG_INFO, *PRTLP_TAG_INFO;
#define RTLP_HEAP_TAGGING_INFO_VERSION 0x1
typedef struct _RTLP_HEAP_TAGGING_INFO
{
USHORT Version;
USHORT Flags; // 1: Multiple Tags, 2: Single Tag + Hash
HANDLE ProcessHandle;
SIZE_T EntriesCount;
RTLP_TAG_INFO Entries[1];
} RTLP_HEAP_TAGGING_INFO, *PRTLP_HEAP_TAGGING_INFO;
typedef struct _PROCESS_HEAP_INFORMATION
{
SIZE_T ReserveSize;
SIZE_T CommitSize;
ULONG NumberOfHeaps;
ULONG_PTR FirstHeapInformationOffset;
} PROCESS_HEAP_INFORMATION, *PPROCESS_HEAP_INFORMATION;
typedef struct _HEAP_REGION_INFORMATION
{
PVOID Address;
SIZE_T ReserveSize;
SIZE_T CommitSize;
ULONG_PTR FirstRangeInformationOffset;
ULONG_PTR NextRegionInformationOffset;
} HEAP_REGION_INFORMATION, *PHEAP_REGION_INFORMATION;
typedef struct _HEAP_RANGE_INFORMATION
{
PVOID Address;
SIZE_T Size;
ULONG Type;
ULONG Protection;
ULONG_PTR FirstBlockInformationOffset;
ULONG_PTR NextRangeInformationOffset;
} HEAP_RANGE_INFORMATION, *PHEAP_RANGE_INFORMATION;
typedef struct _HEAP_BLOCK_INFORMATION
{
PVOID Address;
ULONG Flags;
SIZE_T DataSize;
ULONG_PTR OverheadSize;
ULONG_PTR NextBlockInformationOffset;
} HEAP_BLOCK_INFORMATION, *PHEAP_BLOCK_INFORMATION;
typedef struct _HEAP_INFORMATION
{
PVOID Address;
ULONG Mode;
SIZE_T ReserveSize;
SIZE_T CommitSize;
ULONG_PTR FirstRegionInformationOffset;
ULONG_PTR NextHeapInformationOffset;
} HEAP_INFORMATION, *PHEAP_INFORMATION;
typedef struct _SEGMENT_HEAP_PERFORMANCE_COUNTER_INFORMATION
{
SIZE_T SegmentReserveSize;
SIZE_T SegmentCommitSize;
SIZE_T SegmentCount;
SIZE_T AllocatedSize;
SIZE_T LargeAllocReserveSize;
SIZE_T LargeAllocCommitSize;
} SEGMENT_HEAP_PERFORMANCE_COUNTER_INFORMATION, *PSEGMENT_HEAP_PERFORMANCE_COUNTER_INFORMATION;
#define HeapPerformanceCountersInformationStandardHeapVersion 0x1
#define HeapPerformanceCountersInformationSegmentHeapVersion 0x2
typedef struct _HEAP_PERFORMANCE_COUNTERS_INFORMATION
{
ULONG Size;
ULONG Version;
ULONG HeapIndex;
ULONG LastHeapIndex;
PVOID BaseAddress;
SIZE_T ReserveSize;
SIZE_T CommitSize;
ULONG SegmentCount;
SIZE_T LargeUCRMemory;
ULONG UCRLength;
SIZE_T AllocatedSpace;
SIZE_T FreeSpace;
ULONG FreeListLength;
ULONG Contention;
ULONG VirtualBlocks;
ULONG CommitRate;
ULONG DecommitRate;
SEGMENT_HEAP_PERFORMANCE_COUNTER_INFORMATION SegmentHeapPerfInformation; // since WIN8
} HEAP_PERFORMANCE_COUNTERS_INFORMATION, *PHEAP_PERFORMANCE_COUNTERS_INFORMATION;
typedef struct _HEAP_INFORMATION_ITEM
{
ULONG Level;
SIZE_T Size;
union
{
PROCESS_HEAP_INFORMATION ProcessHeapInformation;
HEAP_INFORMATION HeapInformation;
HEAP_REGION_INFORMATION HeapRegionInformation;
HEAP_RANGE_INFORMATION HeapRangeInformation;
HEAP_BLOCK_INFORMATION HeapBlockInformation;
HEAP_PERFORMANCE_COUNTERS_INFORMATION HeapPerfInformation;
ULONG_PTR DynamicStart;
};
} HEAP_INFORMATION_ITEM, *PHEAP_INFORMATION_ITEM;
typedef _Function_class_(RTL_HEAP_EXTENDED_ENUMERATION_ROUTINE)
NTSTATUS NTAPI RTL_HEAP_EXTENDED_ENUMERATION_ROUTINE(
_In_ PHEAP_INFORMATION_ITEM Information,
_In_opt_ PVOID Context
);
typedef RTL_HEAP_EXTENDED_ENUMERATION_ROUTINE* PRTL_HEAP_EXTENDED_ENUMERATION_ROUTINE;
// HEAP_EXTENDED_INFORMATION Level
#define HeapExtendedProcessHeapInformationLevel 0x1
#define HeapExtendedHeapInformationLevel 0x2
#define HeapExtendedHeapRegionInformationLevel 0x3
#define HeapExtendedHeapRangeInformationLevel 0x4
#define HeapExtendedHeapBlockInformationLevel 0x5
#define HeapExtendedHeapHeapPerfInformationLevel 0x80000000
typedef struct _HEAP_EXTENDED_INFORMATION
{
HANDLE ProcessHandle;
HANDLE HeapHandle;
ULONG Level;
PRTL_HEAP_EXTENDED_ENUMERATION_ROUTINE CallbackRoutine;
PVOID CallbackContext;
union
{
PROCESS_HEAP_INFORMATION ProcessHeapInformation;
HEAP_INFORMATION HeapInformation;
};
} HEAP_EXTENDED_INFORMATION, *PHEAP_EXTENDED_INFORMATION;
// rev
typedef _Function_class_(RTL_HEAP_STACK_WRITE_ROUTINE)
NTSTATUS NTAPI RTL_HEAP_STACK_WRITE_ROUTINE(
_In_ PVOID Information, // TODO: 3 missing structures (dmex)
_In_ ULONG Size,
_In_opt_ PVOID Context
);
typedef RTL_HEAP_STACK_WRITE_ROUTINE* PRTL_HEAP_STACK_WRITE_ROUTINE;
// rev
typedef struct _RTLP_HEAP_STACK_TRACE_SERIALIZATION_INIT
{
ULONG Count;
ULONG Total;
ULONG Flags;
} RTLP_HEAP_STACK_TRACE_SERIALIZATION_INIT, *PRTLP_HEAP_STACK_TRACE_SERIALIZATION_INIT;
// rev
typedef struct _RTLP_HEAP_STACK_TRACE_SERIALIZATION_HEADER
{
USHORT Version;
USHORT PointerSize;
PVOID Heap;
SIZE_T TotalCommit;
SIZE_T TotalReserve;
} RTLP_HEAP_STACK_TRACE_SERIALIZATION_HEADER, *PRTLP_HEAP_STACK_TRACE_SERIALIZATION_HEADER;
// rev
typedef struct _RTLP_HEAP_STACK_TRACE_SERIALIZATION_ALLOCATION
{
PVOID Address;
ULONG Flags;
SIZE_T DataSize;
} RTLP_HEAP_STACK_TRACE_SERIALIZATION_ALLOCATION, *PRTLP_HEAP_STACK_TRACE_SERIALIZATION_ALLOCATION;
// rev
typedef struct _RTLP_HEAP_STACK_TRACE_SERIALIZATION_STACKFRAME
{
PVOID StackFrame[8];
} RTLP_HEAP_STACK_TRACE_SERIALIZATION_STACKFRAME, *PRTLP_HEAP_STACK_TRACE_SERIALIZATION_STACKFRAME;
#define HEAP_STACK_QUERY_VERSION 0x2
typedef struct _RTL_HEAP_STACK_QUERY
{
ULONG Version;
HANDLE ProcessHandle;
PRTL_HEAP_STACK_WRITE_ROUTINE WriteRoutine;
PVOID SerializationContext;
UCHAR QueryLevel;
UCHAR Flags;
} RTL_HEAP_STACK_QUERY, *PRTL_HEAP_STACK_QUERY;
#define HEAP_STACK_CONTROL_VERSION 0x1
#define HEAP_STACK_CONTROL_FLAGS_STACKTRACE_ENABLE 0x1
#define HEAP_STACK_CONTROL_FLAGS_STACKTRACE_DISABLE 0x2
typedef struct _RTL_HEAP_STACK_CONTROL
{
USHORT Version;
USHORT Flags;
HANDLE ProcessHandle;
} RTL_HEAP_STACK_CONTROL, *PRTL_HEAP_STACK_CONTROL;
// rev
typedef _Function_class_(RTL_HEAP_DEBUGGING_INTERCEPTOR_ROUTINE)
NTSTATUS NTAPI RTL_HEAP_DEBUGGING_INTERCEPTOR_ROUTINE(
_In_ HANDLE HeapHandle,
_In_ ULONG Action,
_In_ ULONG StackFramesToCapture,
_In_ PVOID *StackTrace
);
typedef RTL_HEAP_DEBUGGING_INTERCEPTOR_ROUTINE* PRTL_HEAP_DEBUGGING_INTERCEPTOR_ROUTINE;
// rev
typedef _Function_class_(RTL_HEAP_LEAK_ENUMERATION_ROUTINE)
NTSTATUS NTAPI RTL_HEAP_LEAK_ENUMERATION_ROUTINE(
_In_ LONG Reserved,
_In_ HANDLE HeapHandle,
_In_ PVOID BaseAddress,
_In_ SIZE_T BlockSize,
_In_ ULONG StackTraceDepth,
_In_ PVOID *StackTrace
);
typedef RTL_HEAP_LEAK_ENUMERATION_ROUTINE* PRTL_HEAP_LEAK_ENUMERATION_ROUTINE;
// symbols
typedef struct _HEAP_DEBUGGING_INFORMATION
{
PRTL_HEAP_DEBUGGING_INTERCEPTOR_ROUTINE InterceptorFunction;
USHORT InterceptorValue;
ULONG ExtendedOptions;
ULONG StackTraceDepth;
SIZE_T MinTotalBlockSize;
SIZE_T MaxTotalBlockSize;
PRTL_HEAP_LEAK_ENUMERATION_ROUTINE HeapLeakEnumerationRoutine;
} HEAP_DEBUGGING_INFORMATION, *PHEAP_DEBUGGING_INFORMATION;
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryHeapInformation(
_In_opt_ HANDLE HeapHandle,
_In_ HEAP_INFORMATION_CLASS HeapInformationClass,
_Out_opt_ PVOID HeapInformation,
_In_opt_ SIZE_T HeapInformationLength,
_Out_opt_ PSIZE_T ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetHeapInformation(
_In_opt_ HANDLE HeapHandle,
_In_ HEAP_INFORMATION_CLASS HeapInformationClass,
_In_opt_ PCVOID HeapInformation,
_In_opt_ SIZE_T HeapInformationLength
);
NTSYSAPI
ULONG
NTAPI
RtlMultipleAllocateHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_In_ SIZE_T Size,
_In_ ULONG Count,
_Out_ PVOID *Array
);
NTSYSAPI
ULONG
NTAPI
RtlMultipleFreeHeap(
_In_ HANDLE HeapHandle,
_In_ ULONG Flags,
_In_ ULONG Count,
_In_ PVOID *Array
);
NTSYSAPI
VOID
NTAPI
RtlDetectHeapLeaks(
VOID
);
NTSYSAPI
VOID
NTAPI
RtlFlushHeaps(
VOID
);
//
// Memory zones
//
// begin_private
typedef struct _RTL_MEMORY_ZONE_SEGMENT
{
struct _RTL_MEMORY_ZONE_SEGMENT *NextSegment;
SIZE_T Size;
PVOID Next;
PVOID Limit;
} RTL_MEMORY_ZONE_SEGMENT, *PRTL_MEMORY_ZONE_SEGMENT;
typedef struct _RTL_MEMORY_ZONE
{
RTL_MEMORY_ZONE_SEGMENT Segment;
RTL_SRWLOCK Lock;
ULONG LockCount;
PRTL_MEMORY_ZONE_SEGMENT FirstSegment;
} RTL_MEMORY_ZONE, *PRTL_MEMORY_ZONE;
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateMemoryZone(
_Out_ PVOID *MemoryZone,
_In_ SIZE_T InitialSize,
_Reserved_ ULONG Flags
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDestroyMemoryZone(
_In_ _Post_invalid_ PVOID MemoryZone
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAllocateMemoryZone(
_In_ PVOID MemoryZone,
_In_ SIZE_T BlockSize,
_Out_ PVOID *Block
);
NTSYSAPI
NTSTATUS
NTAPI
RtlResetMemoryZone(
_In_ PVOID MemoryZone
);
NTSYSAPI
NTSTATUS
NTAPI
RtlLockMemoryZone(
_In_ PVOID MemoryZone
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUnlockMemoryZone(
_In_ PVOID MemoryZone
);
//
// Memory block lookaside lists
//
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateMemoryBlockLookaside(
_Out_ PVOID *MemoryBlockLookaside,
_Reserved_ ULONG Flags,
_In_ ULONG InitialSize,
_In_ ULONG MinimumBlockSize,
_In_ ULONG MaximumBlockSize
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDestroyMemoryBlockLookaside(
_In_ PVOID MemoryBlockLookaside
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAllocateMemoryBlockLookaside(
_In_ PVOID MemoryBlockLookaside,
_In_ ULONG BlockSize,
_Out_ PVOID *Block
);
NTSYSAPI
NTSTATUS
NTAPI
RtlFreeMemoryBlockLookaside(
_In_ PVOID MemoryBlockLookaside,
_In_ PVOID Block
);
NTSYSAPI
NTSTATUS
NTAPI
RtlExtendMemoryBlockLookaside(
_In_ PVOID MemoryBlockLookaside,
_In_ ULONG Increment
);
NTSYSAPI
NTSTATUS
NTAPI
RtlResetMemoryBlockLookaside(
_In_ PVOID MemoryBlockLookaside
);
NTSYSAPI
NTSTATUS
NTAPI
RtlLockMemoryBlockLookaside(
_In_ PVOID MemoryBlockLookaside
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUnlockMemoryBlockLookaside(
_In_ PVOID MemoryBlockLookaside
);
// end_private
//
// Transactions
//
// private
NTSYSAPI
HANDLE
NTAPI
RtlGetCurrentTransaction(
_In_opt_ PCWSTR ExistingFileName,
_In_opt_ PCWSTR NewFileName
);
// private
NTSYSAPI
LOGICAL
NTAPI
RtlSetCurrentTransaction(
_In_opt_ HANDLE TransactionHandle
);
//
// LUIDs
//
FORCEINLINE
BOOLEAN
NTAPI_INLINE
RtlIsEqualLuid( // RtlEqualLuid
_In_ PLUID L1,
_In_ PLUID L2
)
{
return L1->LowPart == L2->LowPart &&
L1->HighPart == L2->HighPart;
}
FORCEINLINE
BOOLEAN
NTAPI_INLINE
RtlIsZeroLuid(
_In_ PLUID L1
)
{
return (L1->LowPart | L1->HighPart) == 0;
}
FORCEINLINE
LUID
NTAPI_INLINE
RtlConvertLongToLuid(
_In_ LONG Long
)
{
LUID tempLuid;
tempLuid.LowPart = Long;
tempLuid.HighPart = 0;
return tempLuid;
}
FORCEINLINE
LUID
NTAPI_INLINE
RtlConvertUlongToLuid(
_In_ ULONG Ulong
)
{
LUID tempLuid;
tempLuid.LowPart = Ulong;
tempLuid.HighPart = 0;
return tempLuid;
}
FORCEINLINE
LONGLONG
NTAPI_INLINE
RtlConvertLuidToLonglong(
_In_ LUID Luid
)
{
LARGE_INTEGER tempLi;
tempLi.LowPart = Luid.LowPart;
tempLi.HighPart = Luid.HighPart;
return tempLi.QuadPart;
}
FORCEINLINE
ULONGLONG
NTAPI_INLINE
RtlConvertLuidToUlonglong(
_In_ LUID Luid
)
{
ULARGE_INTEGER tempLi;
tempLi.LowPart = Luid.LowPart;
tempLi.HighPart = Luid.HighPart;
return tempLi.QuadPart;
}
NTSYSAPI
VOID
NTAPI
RtlCopyLuid(
_Out_ PLUID DestinationLuid,
_In_ PLUID SourceLuid
);
// ros
NTSYSAPI
VOID
NTAPI
RtlCopyLuidAndAttributesArray(
_In_ ULONG Count,
_In_ PLUID_AND_ATTRIBUTES Src,
_In_ PLUID_AND_ATTRIBUTES Dest
);
//
// Byte swap routines.
//
#ifndef PHNT_RTL_BYTESWAP
#define RtlUshortByteSwap(_x) _byteswap_ushort((USHORT)(_x))
#define RtlUlongByteSwap(_x) _byteswap_ulong((_x))
#define RtlUlonglongByteSwap(_x) _byteswap_uint64((_x))
#else
NTSYSAPI
USHORT
FASTCALL
RtlUshortByteSwap(
_In_ USHORT Source
);
NTSYSAPI
ULONG
FASTCALL
RtlUlongByteSwap(
_In_ ULONG Source
);
NTSYSAPI
ULONGLONG
FASTCALL
RtlUlonglongByteSwap(
_In_ ULONGLONG Source
);
#endif // PHNT_RTL_BYTESWAP
DECLSPEC_DEPRECATED
NTSYSAPI
LARGE_INTEGER
NTAPI
RtlConvertUlongToLargeInteger(
_In_ ULONG UnsignedInteger
);
DECLSPEC_DEPRECATED
NTSYSAPI
LARGE_INTEGER
NTAPI
RtlConvertLongToLargeInteger(
_In_ LONG SignedInteger
);
DECLSPEC_DEPRECATED
NTSYSAPI
LARGE_INTEGER
NTAPI
RtlEnlargedIntegerMultiply(
_In_ LONG Multiplicand,
_In_ LONG Multiplier
);
DECLSPEC_DEPRECATED
NTSYSAPI
LARGE_INTEGER
NTAPI_INLINE
RtlEnlargedUnsignedMultiply(
_In_ ULONG Multiplicand,
_In_ ULONG Multiplier
);
//
// Debugging
//
// private
typedef struct _RTL_PROCESS_MODULES *PRTL_PROCESS_MODULES;
typedef struct _RTL_PROCESS_MODULE_INFORMATION_EX *PRTL_PROCESS_MODULE_INFORMATION_EX;
typedef struct _RTL_PROCESS_BACKTRACES *PRTL_PROCESS_BACKTRACES;
typedef struct _RTL_PROCESS_LOCKS *PRTL_PROCESS_LOCKS;
typedef struct _RTL_PROCESS_VERIFIER_OPTIONS
{
ULONG SizeStruct;
ULONG Option;
UCHAR OptionData[1];
} RTL_PROCESS_VERIFIER_OPTIONS, *PRTL_PROCESS_VERIFIER_OPTIONS;
// private
typedef struct _RTL_DEBUG_INFORMATION
{
HANDLE SectionHandleClient;
PVOID ViewBaseClient;
PVOID ViewBaseTarget;
ULONG_PTR ViewBaseDelta;
HANDLE EventPairClient;
HANDLE EventPairTarget;
HANDLE TargetProcessId;
HANDLE TargetThreadHandle;
ULONG Flags;
SIZE_T OffsetFree;
SIZE_T CommitSize;
SIZE_T ViewSize;
union
{
PRTL_PROCESS_MODULES Modules;
PRTL_PROCESS_MODULE_INFORMATION_EX ModulesEx;
};
PRTL_PROCESS_BACKTRACES BackTraces;
PVOID Heaps;
PRTL_PROCESS_LOCKS Locks;
PVOID SpecificHeap;
HANDLE TargetProcessHandle;
PRTL_PROCESS_VERIFIER_OPTIONS VerifierOptions;
PVOID ProcessHeap;
HANDLE CriticalSectionHandle;
HANDLE CriticalSectionOwnerThread;
PVOID Reserved[4];
} RTL_DEBUG_INFORMATION, *PRTL_DEBUG_INFORMATION;
NTSYSAPI
PRTL_DEBUG_INFORMATION
NTAPI
RtlCreateQueryDebugBuffer(
_In_opt_ ULONG MaximumCommit,
_In_ BOOLEAN UseEventPair
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDestroyQueryDebugBuffer(
_In_ PRTL_DEBUG_INFORMATION Buffer
);
// private
NTSYSAPI
PVOID
NTAPI
RtlCommitDebugInfo(
_Inout_ PRTL_DEBUG_INFORMATION Buffer,
_In_ SIZE_T Size
);
// private
NTSYSAPI
VOID
NTAPI
RtlDeCommitDebugInfo(
_Inout_ PRTL_DEBUG_INFORMATION Buffer,
_In_ PVOID p,
_In_ SIZE_T Size
);
#define RTL_QUERY_PROCESS_MODULES 0x00000001
#define RTL_QUERY_PROCESS_BACKTRACES 0x00000002
#define RTL_QUERY_PROCESS_HEAP_SUMMARY 0x00000004
#define RTL_QUERY_PROCESS_HEAP_TAGS 0x00000008
#define RTL_QUERY_PROCESS_HEAP_ENTRIES 0x00000010
#define RTL_QUERY_PROCESS_LOCKS 0x00000020
#define RTL_QUERY_PROCESS_MODULES32 0x00000040
#define RTL_QUERY_PROCESS_VERIFIER_OPTIONS 0x00000080 // rev
#define RTL_QUERY_PROCESS_MODULESEX 0x00000100 // rev
#define RTL_QUERY_PROCESS_HEAP_SEGMENTS 0x00000200
#define RTL_QUERY_PROCESS_CS_OWNER 0x00000400 // rev
#define RTL_QUERY_PROCESS_NONINVASIVE 0x80000000
#define RTL_QUERY_PROCESS_NONINVASIVE_CS_OWNER 0x80000800 // WIN11
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryProcessDebugInformation(
_In_ HANDLE UniqueProcessId,
_In_ ULONG Flags,
_Inout_ PRTL_DEBUG_INFORMATION Buffer
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSetProcessDebugInformation(
_In_ HANDLE UniqueProcessId,
_In_ ULONG Flags,
_Inout_ PRTL_DEBUG_INFORMATION Buffer
);
// rev
FORCEINLINE
BOOLEAN
NTAPI_INLINE
RtlIsAnyDebuggerPresent(
VOID
)
{
BOOLEAN result;
result = NtCurrentPeb()->BeingDebugged;
if (!result)
return USER_SHARED_DATA->KdDebuggerEnabled;
return result;
}
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlDebugPrintTimes(
VOID
);
//
// Messages
//
NTSYSAPI
NTSTATUS
NTAPI
RtlFindMessage(
_In_ PVOID DllHandle,
_In_ ULONG MessageTableId,
_In_ ULONG MessageLanguageId,
_In_ ULONG MessageId,
_Out_ PMESSAGE_RESOURCE_ENTRY *MessageEntry
);
NTSYSAPI
NTSTATUS
NTAPI
RtlFormatMessage(
_In_ PCWSTR MessageFormat,
_In_ ULONG MaximumWidth,
_In_ BOOLEAN IgnoreInserts,
_In_ BOOLEAN ArgumentsAreAnsi,
_In_ BOOLEAN ArgumentsAreAnArray,
_In_ va_list *Arguments,
_Out_writes_bytes_to_(Length, *ReturnLength) PWSTR Buffer,
_In_ ULONG Length,
_Out_opt_ PULONG ReturnLength
);
typedef struct _PARSE_MESSAGE_CONTEXT
{
ULONG fFlags;
ULONG cwSavColumn;
SIZE_T iwSrc;
SIZE_T iwDst;
SIZE_T iwDstSpace;
va_list lpvArgStart;
} PARSE_MESSAGE_CONTEXT, *PPARSE_MESSAGE_CONTEXT;
#define INIT_PARSE_MESSAGE_CONTEXT(ctx) { (ctx)->fFlags = 0; }
#define TEST_PARSE_MESSAGE_CONTEXT_FLAG(ctx, flag) ((ctx)->fFlags & (flag))
#define SET_PARSE_MESSAGE_CONTEXT_FLAG(ctx, flag) ((ctx)->fFlags |= (flag))
#define CLEAR_PARSE_MESSAGE_CONTEXT_FLAG(ctx, flag) ((ctx)->fFlags &= ~(flag))
NTSYSAPI
NTSTATUS
NTAPI
RtlFormatMessageEx(
_In_ PCWSTR MessageFormat,
_In_ ULONG MaximumWidth,
_In_ BOOLEAN IgnoreInserts,
_In_ BOOLEAN ArgumentsAreAnsi,
_In_ BOOLEAN ArgumentsAreAnArray,
_In_ va_list *Arguments,
_Out_writes_bytes_to_(Length, *ReturnLength) PWSTR Buffer,
_In_ ULONG Length,
_Out_opt_ PULONG ReturnLength,
_Out_opt_ PPARSE_MESSAGE_CONTEXT ParseContext
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetFileMUIPath(
_In_ ULONG Flags,
_In_ PCWSTR FilePath,
_Inout_opt_ PCWSTR Language,
_Inout_ PULONG LanguageLength,
_Out_opt_ PWSTR FileMUIPath,
_Inout_ PULONG FileMUIPathLength,
_Inout_ PULONGLONG Enumerator
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlLoadString(
_In_ PVOID DllHandle,
_In_ ULONG StringId,
_In_opt_ PCWSTR StringLanguage,
_In_ ULONG Flags,
_Out_ PCWSTR *ReturnString,
_Out_opt_ PUSHORT ReturnStringLen,
_Out_writes_(ReturnLanguageLen) PWSTR ReturnLanguageName,
_Inout_opt_ PULONG ReturnLanguageLen
);
//
// Errors
//
_When_(Status < 0, _Out_range_(>, 0))
_When_(Status >= 0, _Out_range_(==, 0))
NTSYSAPI
ULONG
NTAPI
RtlNtStatusToDosError(
_In_ NTSTATUS Status
);
_When_(Status < 0, _Out_range_(>, 0))
_When_(Status >= 0, _Out_range_(==, 0))
NTSYSAPI
ULONG
NTAPI
RtlNtStatusToDosErrorNoTeb(
_In_ NTSTATUS Status
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetLastNtStatus(
VOID
);
_Check_return_
_Post_equals_last_error_
NTSYSAPI
LONG
NTAPI
RtlGetLastWin32Error(
VOID
);
NTSYSAPI
VOID
NTAPI
RtlSetLastWin32ErrorAndNtStatusFromNtStatus(
_In_ NTSTATUS Status
);
NTSYSAPI
VOID
NTAPI
RtlSetLastWin32Error(
_In_ LONG Win32Error
);
NTSYSAPI
VOID
NTAPI
RtlRestoreLastWin32Error(
_In_ LONG Win32Error
);
#define RTL_ERRORMODE_FAILCRITICALERRORS 0x0010
#define RTL_ERRORMODE_NOGPFAULTERRORBOX 0x0020
#define RTL_ERRORMODE_NOOPENFILEERRORBOX 0x0040
NTSYSAPI
ULONG
NTAPI
RtlGetThreadErrorMode(
VOID
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetThreadErrorMode(
_In_ ULONG NewMode,
_Out_opt_ PULONG OldMode
);
//
// Windows Error Reporting
//
NTSYSAPI
NTSTATUS
NTAPI
RtlReportException(
_In_ PEXCEPTION_RECORD ExceptionRecord,
_In_ PCONTEXT ContextRecord,
_In_ ULONG Flags
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS1)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlReportExceptionEx(
_In_ PEXCEPTION_RECORD ExceptionRecord,
_In_ PCONTEXT ContextRecord,
_In_ ULONG Flags,
_In_ PLARGE_INTEGER Timeout
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS1
NTSYSAPI
NTSTATUS
NTAPI
RtlWerpReportException(
_In_ ULONG ProcessId,
_In_ HANDLE CrashReportSharedMem,
_In_ ULONG Flags,
_Out_ PHANDLE CrashVerticalProcessHandle
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlReportSilentProcessExit(
_In_ HANDLE ProcessHandle,
_In_ NTSTATUS ExitStatus
);
//
// Random
//
NTSYSAPI
ULONG
NTAPI
RtlUniform(
_Inout_ PULONG Seed
);
_Ret_range_(<=, MAXLONG)
NTSYSAPI
ULONG
NTAPI
RtlRandom(
_Inout_ PULONG Seed
);
_Ret_range_(<=, MAXLONG)
NTSYSAPI
ULONG
NTAPI
RtlRandomEx(
_Inout_ PULONG Seed
);
#define RTL_IMPORT_TABLE_HASH_REVISION 1
NTSYSAPI
NTSTATUS
NTAPI
RtlComputeImportTableHash(
_In_ HANDLE FileHandle,
_Out_writes_bytes_(16) PUCHAR Hash,
_In_ ULONG ImportTableHashRevision // must be 1
);
//
// Integer conversion
//
NTSYSAPI
NTSTATUS
NTAPI
RtlIntegerToChar(
_In_ ULONG Value,
_In_opt_ ULONG Base,
_In_ LONG OutputLength, // negative to pad to width
_Out_ PSTR String
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCharToInteger(
_In_z_ PCSTR String,
_In_opt_ ULONG Base,
_Out_ PULONG Value
);
NTSYSAPI
NTSTATUS
NTAPI
RtlLargeIntegerToChar(
_In_ PLARGE_INTEGER Value,
_In_opt_ ULONG Base,
_In_ LONG OutputLength,
_Out_ PSTR String
);
#define RtlLargeIntegerGreaterThan(X,Y) ((((X).HighPart == (Y).HighPart) && ((X).LowPart > (Y).LowPart)) || ((X).HighPart > (Y).HighPart))
#define RtlLargeIntegerGreaterThanOrEqualTo(X,Y) ((((X).HighPart == (Y).HighPart) && ((X).LowPart >= (Y).LowPart)) || ((X).HighPart > (Y).HighPart)))
#define RtlLargeIntegerEqualTo(X,Y) (!(((X).LowPart ^ (Y).LowPart) | ((X).HighPart ^ (Y).HighPart)))
#define RtlLargeIntegerNotEqualTo(X,Y) ((((X).LowPart ^ (Y).LowPart) | ((X).HighPart ^ (Y).HighPart)))
#define RtlLargeIntegerLessThan(X,Y) ((((X).HighPart == (Y).HighPart) && ((X).LowPart < (Y).LowPart)) || ((X).HighPart < (Y).HighPart))
#define RtlLargeIntegerLessThanOrEqualTo(X,Y) ((((X).HighPart == (Y).HighPart) && ((X).LowPart <= (Y).LowPart)) || ((X).HighPart < (Y).HighPart))
#define RtlLargeIntegerGreaterThanZero(X) ((((X).HighPart == 0) && ((X).LowPart > 0)) || ((X).HighPart > 0 ))
#define RtlLargeIntegerGreaterOrEqualToZero(X) ((X).HighPart >= 0)
#define RtlLargeIntegerEqualToZero(X) (!((X).LowPart | (X).HighPart))
#define RtlLargeIntegerNotEqualToZero(X) (((X).LowPart | (X).HighPart))
#define RtlLargeIntegerLessThanZero(X) (((X).HighPart < 0))
#define RtlLargeIntegerLessOrEqualToZero(X) (((X).HighPart < 0) || !((X).LowPart | (X).HighPart))
NTSYSAPI
NTSTATUS
NTAPI
RtlIntegerToUnicodeString(
_In_ ULONG Value,
_In_opt_ ULONG Base,
_Inout_ PUNICODE_STRING String
);
NTSYSAPI
NTSTATUS
NTAPI
RtlInt64ToUnicodeString(
_In_ ULONGLONG Value,
_In_opt_ ULONG Base,
_Inout_ PUNICODE_STRING String
);
#ifdef _WIN64
#define RtlIntPtrToUnicodeString(Value, Base, String) RtlInt64ToUnicodeString(Value, Base, String)
#else
#define RtlIntPtrToUnicodeString(Value, Base, String) RtlIntegerToUnicodeString(Value, Base, String)
#endif // _WIN64
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToInteger(
_In_ PCUNICODE_STRING String,
_In_opt_ ULONG Base,
_Out_ PULONG Value
);
//
// IPv4/6 conversion
//
#ifndef s_addr
//
// IPv4 Internet address
// This is an 'on-wire' format structure.
//
typedef struct in_addr
{
union
{
struct { UCHAR s_b1, s_b2, s_b3, s_b4; } S_un_b;
struct { USHORT s_w1, s_w2; } S_un_w;
ULONG S_addr;
} S_un;
#define s_addr S_un.S_addr /* can be used for most tcp & ip code */
#define s_host S_un.S_un_b.s_b2 // host on imp
#define s_net S_un.S_un_b.s_b1 // network
#define s_imp S_un.S_un_w.s_w2 // imp
#define s_impno S_un.S_un_b.s_b4 // imp #
#define s_lh S_un.S_un_b.s_b3 // logical host
} IN_ADDR, * PIN_ADDR, FAR* LPIN_ADDR;
#endif // s_addr
#ifndef s6_addr
//
// IPv6 Internet address (RFC 2553)
// This is an 'on-wire' format structure.
//
typedef struct in6_addr
{
union
{
UCHAR Byte[16];
USHORT Word[8];
} u;
#define in_addr6 in6_addr
#define _S6_un u
#define _S6_u8 Byte
#define s6_addr _S6_un._S6_u8
#define s6_bytes u.Byte
#define s6_words u.Word
} IN6_ADDR, *PIN6_ADDR, FAR *LPIN6_ADDR;
#endif // s6_addr
typedef struct in_addr IN_ADDR, *PIN_ADDR;
typedef struct in6_addr IN6_ADDR, *PIN6_ADDR;
typedef IN_ADDR const *PCIN_ADDR;
typedef IN6_ADDR const *PCIN6_ADDR;
NTSYSAPI
PSTR
NTAPI
RtlIpv4AddressToStringA(
_In_ PCIN_ADDR Address,
_Out_writes_(16) PSTR AddressString
);
NTSYSAPI
PWSTR
NTAPI
RtlIpv4AddressToStringW(
_In_ PCIN_ADDR Address,
_Out_writes_(16) PWSTR AddressString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv4AddressToStringExA(
_In_ PCIN_ADDR Address,
_In_ USHORT Port,
_Out_writes_to_(*AddressStringLength, *AddressStringLength) PSTR AddressString,
_Inout_ PULONG AddressStringLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv4AddressToStringExW(
_In_ PCIN_ADDR Address,
_In_ USHORT Port,
_Out_writes_to_(*AddressStringLength, *AddressStringLength) PWSTR AddressString,
_Inout_ PULONG AddressStringLength
);
NTSYSAPI
PSTR
NTAPI
RtlIpv6AddressToStringA(
_In_ PCIN6_ADDR Address,
_Out_writes_(46) PSTR AddressString
);
NTSYSAPI
PWSTR
NTAPI
RtlIpv6AddressToStringW(
_In_ PCIN6_ADDR Address,
_Out_writes_(46) PWSTR AddressString
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv6AddressToStringExA(
_In_ PCIN6_ADDR Address,
_In_ ULONG ScopeId,
_In_ USHORT Port,
_Out_writes_to_(*AddressStringLength, *AddressStringLength) PSTR AddressString,
_Inout_ PULONG AddressStringLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv6AddressToStringExW(
_In_ PCIN6_ADDR Address,
_In_ ULONG ScopeId,
_In_ USHORT Port,
_Out_writes_to_(*AddressStringLength, *AddressStringLength) PWSTR AddressString,
_Inout_ PULONG AddressStringLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv4StringToAddressA(
_In_ PCSTR AddressString,
_In_ BOOLEAN Strict,
_Out_ PCSTR *Terminator,
_Out_ PIN_ADDR Address
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv4StringToAddressW(
_In_ PCWSTR AddressString,
_In_ BOOLEAN Strict,
_Out_ PCWSTR *Terminator,
_Out_ PIN_ADDR Address
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv4StringToAddressExA(
_In_ PCSTR AddressString,
_In_ BOOLEAN Strict,
_Out_ PIN_ADDR Address,
_Out_ PUSHORT Port
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv4StringToAddressExW(
_In_ PCWSTR AddressString,
_In_ BOOLEAN Strict,
_Out_ PIN_ADDR Address,
_Out_ PUSHORT Port
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv6StringToAddressA(
_In_ PCSTR AddressString,
_Out_ PCSTR *Terminator,
_Out_ PIN6_ADDR Address
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv6StringToAddressW(
_In_ PCWSTR AddressString,
_Out_ PCWSTR *Terminator,
_Out_ PIN6_ADDR Address
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv6StringToAddressExA(
_In_ PCSTR AddressString,
_Out_ PIN6_ADDR Address,
_Out_ PULONG ScopeId,
_Out_ PUSHORT Port
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIpv6StringToAddressExW(
_In_ PCWSTR AddressString,
_Out_ PIN6_ADDR Address,
_Out_ PULONG ScopeId,
_Out_ PUSHORT Port
);
#define RtlIpv4AddressToString RtlIpv4AddressToStringW
#define RtlIpv4AddressToStringEx RtlIpv4AddressToStringExW
#define RtlIpv6AddressToString RtlIpv6AddressToStringW
#define RtlIpv6AddressToStringEx RtlIpv6AddressToStringExW
#define RtlIpv4StringToAddress RtlIpv4StringToAddressW
#define RtlIpv4StringToAddressEx RtlIpv4StringToAddressExW
#define RtlIpv6StringToAddress RtlIpv6StringToAddressW
#define RtlIpv6StringToAddressEx RtlIpv6StringToAddressExW
//
// Time
//
typedef struct _TIME_FIELDS
{
CSHORT Year; // 1601...
CSHORT Month; // 1..12
CSHORT Day; // 1..31
CSHORT Hour; // 0..23
CSHORT Minute; // 0..59
CSHORT Second; // 0..59
CSHORT Milliseconds; // 0..999
CSHORT Weekday; // 0..6 = Sunday..Saturday
} TIME_FIELDS, *PTIME_FIELDS;
NTSYSAPI
BOOLEAN
NTAPI
RtlCutoverTimeToSystemTime(
_In_ PTIME_FIELDS CutoverTime,
_Out_ PLARGE_INTEGER SystemTime,
_In_ PLARGE_INTEGER CurrentSystemTime,
_In_ BOOLEAN ThisYear
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSystemTimeToLocalTime(
_In_ PLARGE_INTEGER SystemTime,
_Out_ PLARGE_INTEGER LocalTime
);
NTSYSAPI
NTSTATUS
NTAPI
RtlLocalTimeToSystemTime(
_In_ PLARGE_INTEGER LocalTime,
_Out_ PLARGE_INTEGER SystemTime
);
NTSYSAPI
VOID
NTAPI
RtlTimeToElapsedTimeFields(
_In_ PLARGE_INTEGER Time,
_Out_ PTIME_FIELDS TimeFields
);
NTSYSAPI
VOID
NTAPI
RtlTimeToTimeFields(
_In_ PLARGE_INTEGER Time,
_Out_ PTIME_FIELDS TimeFields
);
NTSYSAPI
BOOLEAN
NTAPI
RtlTimeFieldsToTime(
_In_ PTIME_FIELDS TimeFields, // Weekday is ignored
_Out_ PLARGE_INTEGER Time
);
#define SecondsToStartOf1980 11960006400
#define SecondsToStartOf1970 11644473600
NTSYSAPI
BOOLEAN
NTAPI
RtlTimeToSecondsSince1980(
_In_ PLARGE_INTEGER Time,
_Out_ PULONG ElapsedSeconds
);
NTSYSAPI
VOID
NTAPI
RtlSecondsSince1980ToTime(
_In_ ULONG ElapsedSeconds,
_Out_ PLARGE_INTEGER Time
);
NTSYSAPI
BOOLEAN
NTAPI
RtlTimeToSecondsSince1970(
_In_ PLARGE_INTEGER Time,
_Out_ PULONG ElapsedSeconds
);
NTSYSAPI
VOID
NTAPI
RtlSecondsSince1970ToTime(
_In_ ULONG ElapsedSeconds,
_Out_ PLARGE_INTEGER Time
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
NTSYSAPI
ULONGLONG
NTAPI
RtlGetSystemTimePrecise(
VOID
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_10_21H2)
NTSYSAPI
KSYSTEM_TIME
NTAPI
RtlGetSystemTimeAndBias(
_Out_ KSYSTEM_TIME TimeZoneBias,
_Out_opt_ PLARGE_INTEGER TimeZoneBiasEffectiveStart,
_Out_opt_ PLARGE_INTEGER TimeZoneBiasEffectiveEnd
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_21H2
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
NTSYSAPI
ULONGLONG
NTAPI
RtlGetInterruptTimePrecise(
_Out_ PLARGE_INTEGER PerformanceCounter
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
NTSYSAPI
ULONGLONG
NTAPI
RtlQueryUnbiasedInterruptTime(
_Out_ PLARGE_INTEGER InterruptTime
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_11_24H2)
// rev
NTSYSAPI
ULONGLONG
NTAPI
RtlQueryUnbiasedInterruptTimePrecise(
_Out_ PLARGE_INTEGER InterruptTime
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11_24H2
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
FORCEINLINE
ULONGLONG
NTAPI_INLINE
RtlBeginReadTickLock(
_In_ PULONGLONG TimeUpdateLock // USER_SHARED_DATA->TimeUpdateLock
)
{
ULONGLONG result;
for (result = *TimeUpdateLock; (*TimeUpdateLock & 1) != 0; result = *TimeUpdateLock)
{
YieldProcessor();
}
return result;
}
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
//
// Time zones
//
typedef struct _RTL_TIME_ZONE_INFORMATION
{
LONG Bias;
WCHAR StandardName[32];
TIME_FIELDS StandardStart;
LONG StandardBias;
WCHAR DaylightName[32];
TIME_FIELDS DaylightStart;
LONG DaylightBias;
} RTL_TIME_ZONE_INFORMATION, *PRTL_TIME_ZONE_INFORMATION;
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryTimeZoneInformation(
_Out_ PRTL_TIME_ZONE_INFORMATION TimeZoneInformation
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetTimeZoneInformation(
_In_ PRTL_TIME_ZONE_INFORMATION TimeZoneInformation
);
//
// Interlocked bit manipulation interfaces
//
#define RtlInterlockedSetBits(Flags, Flag) \
InterlockedOr((PLONG)(Flags), Flag)
#define RtlInterlockedAndBits(Flags, Flag) \
InterlockedAnd((PLONG)(Flags), Flag)
#define RtlInterlockedClearBits(Flags, Flag) \
RtlInterlockedAndBits(Flags, ~(Flag))
#define RtlInterlockedXorBits(Flags, Flag) \
InterlockedXor(Flags, Flag)
#define RtlInterlockedSetBitsDiscardReturn(Flags, Flag) \
(VOID) RtlInterlockedSetBits(Flags, Flag)
#define RtlInterlockedAndBitsDiscardReturn(Flags, Flag) \
(VOID) RtlInterlockedAndBits(Flags, Flag)
#define RtlInterlockedClearBitsDiscardReturn(Flags, Flag) \
RtlInterlockedAndBitsDiscardReturn(Flags, ~(Flag))
#define RtlInterlockedTestBits(Flags, Flag) \
((InterlockedOr((PLONG)(Flags), 0) & (Flag)) == (Flag)) // dmex
//
// Bitmaps
//
typedef struct _RTL_BITMAP
{
ULONG SizeOfBitMap;
PULONG Buffer;
} RTL_BITMAP, *PRTL_BITMAP;
NTSYSAPI
VOID
NTAPI
RtlInitializeBitMap(
_Out_ PRTL_BITMAP BitMapHeader,
_In_ PULONG BitMapBuffer,
_In_ ULONG SizeOfBitMap
);
#if (PHNT_MODE == PHNT_MODE_KERNEL || PHNT_VERSION >= PHNT_WINDOWS_8)
NTSYSAPI
VOID
NTAPI
RtlClearBit(
_In_ PRTL_BITMAP BitMapHeader,
_In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber
);
#endif // PHNT_MODE == PHNT_MODE_KERNEL || PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_MODE == PHNT_MODE_KERNEL || PHNT_VERSION >= PHNT_WINDOWS_8)
NTSYSAPI
VOID
NTAPI
RtlSetBit(
_In_ PRTL_BITMAP BitMapHeader,
_In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber
);
#endif // PHNT_MODE == PHNT_MODE_KERNEL || PHNT_VERSION >= PHNT_WINDOWS_8
_Check_return_
NTSYSAPI
BOOLEAN
NTAPI
RtlTestBit(
_In_ PRTL_BITMAP BitMapHeader,
_In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitNumber
);
NTSYSAPI
VOID
NTAPI
RtlClearAllBits(
_In_ PRTL_BITMAP BitMapHeader
);
NTSYSAPI
VOID
NTAPI
RtlSetAllBits(
_In_ PRTL_BITMAP BitMapHeader
);
_Success_(return != -1)
_Check_return_
NTSYSAPI
ULONG
NTAPI
RtlFindClearBits(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG NumberToFind,
_In_ ULONG HintIndex
);
_Success_(return != -1)
_Check_return_
NTSYSAPI
ULONG
NTAPI
RtlFindSetBits(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG NumberToFind,
_In_ ULONG HintIndex
);
_Success_(return != -1)
NTSYSAPI
ULONG
NTAPI
RtlFindClearBitsAndSet(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG NumberToFind,
_In_ ULONG HintIndex
);
_Success_(return != -1)
NTSYSAPI
ULONG
NTAPI
RtlFindSetBitsAndClear(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG NumberToFind,
_In_ ULONG HintIndex
);
NTSYSAPI
VOID
NTAPI
RtlClearBits(
_In_ PRTL_BITMAP BitMapHeader,
_In_range_(0, BitMapHeader->SizeOfBitMap - NumberToClear) ULONG StartingIndex,
_In_range_(0, BitMapHeader->SizeOfBitMap - StartingIndex) ULONG NumberToClear
);
NTSYSAPI
VOID
NTAPI
RtlSetBits(
_In_ PRTL_BITMAP BitMapHeader,
_In_range_(0, BitMapHeader->SizeOfBitMap - NumberToSet) ULONG StartingIndex,
_In_range_(0, BitMapHeader->SizeOfBitMap - StartingIndex) ULONG NumberToSet
);
NTSYSAPI
CCHAR
NTAPI
RtlFindMostSignificantBit(
_In_ ULONGLONG Set
);
NTSYSAPI
CCHAR
NTAPI
RtlFindLeastSignificantBit(
_In_ ULONGLONG Set
);
typedef struct _RTL_BITMAP_RUN
{
ULONG StartingIndex;
ULONG NumberOfBits;
} RTL_BITMAP_RUN, *PRTL_BITMAP_RUN;
NTSYSAPI
ULONG
NTAPI
RtlFindClearRuns(
_In_ PRTL_BITMAP BitMapHeader,
_Out_writes_to_(SizeOfRunArray, return) PRTL_BITMAP_RUN RunArray,
_In_range_(>, 0) ULONG SizeOfRunArray,
_In_ BOOLEAN LocateLongestRuns
);
NTSYSAPI
ULONG
NTAPI
RtlFindLongestRunClear(
_In_ PRTL_BITMAP BitMapHeader,
_Out_ PULONG StartingIndex
);
NTSYSAPI
ULONG
NTAPI
RtlFindFirstRunClear(
_In_ PRTL_BITMAP BitMapHeader,
_Out_ PULONG StartingIndex
);
_Check_return_
FORCEINLINE
BOOLEAN
NTAPI_INLINE
RtlCheckBit(
_In_ PRTL_BITMAP BitMapHeader,
_In_range_(<, BitMapHeader->SizeOfBitMap) ULONG BitPosition
)
{
#ifdef _WIN64
return BitTest64((LONG64 const *)BitMapHeader->Buffer, (LONG64)BitPosition);
#else
return (((PLONG)BitMapHeader->Buffer)[BitPosition / 32] >> (BitPosition % 32)) & 0x1;
#endif // _WIN64
}
NTSYSAPI
ULONG
NTAPI
RtlNumberOfClearBits(
_In_ PRTL_BITMAP BitMapHeader
);
NTSYSAPI
ULONG
NTAPI
RtlNumberOfSetBits(
_In_ PRTL_BITMAP BitMapHeader
);
_Check_return_
NTSYSAPI
BOOLEAN
NTAPI
RtlAreBitsClear(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG StartingIndex,
_In_ ULONG Length
);
_Check_return_
NTSYSAPI
BOOLEAN
NTAPI
RtlAreBitsSet(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG StartingIndex,
_In_ ULONG Length
);
NTSYSAPI
ULONG
NTAPI
RtlFindNextForwardRunClear(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG FromIndex,
_Out_ PULONG StartingRunIndex
);
NTSYSAPI
ULONG
NTAPI
RtlFindLastBackwardRunClear(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG FromIndex,
_Out_ PULONG StartingRunIndex
);
NTSYSAPI
ULONG
NTAPI
RtlNumberOfSetBitsUlongPtr(
_In_ ULONG_PTR Target
);
// rev
NTSYSAPI
VOID
NTAPI
RtlInterlockedClearBitRun(
_In_ PRTL_BITMAP BitMapHeader,
_In_range_(0, BitMapHeader->SizeOfBitMap - NumberToClear) ULONG StartingIndex,
_In_range_(0, BitMapHeader->SizeOfBitMap - StartingIndex) ULONG NumberToClear
);
// rev
NTSYSAPI
VOID
NTAPI
RtlInterlockedSetBitRun(
_In_ PRTL_BITMAP BitMapHeader,
_In_range_(0, BitMapHeader->SizeOfBitMap - NumberToSet) ULONG StartingIndex,
_In_range_(0, BitMapHeader->SizeOfBitMap - StartingIndex) ULONG NumberToSet
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
NTSYSAPI
VOID
NTAPI
RtlCopyBitMap(
_In_ PRTL_BITMAP Source,
_In_ PRTL_BITMAP Destination,
_In_range_(0, Destination->SizeOfBitMap - 1) ULONG TargetBit
);
NTSYSAPI
VOID
NTAPI
RtlExtractBitMap(
_In_ PRTL_BITMAP Source,
_In_ PRTL_BITMAP Destination,
_In_range_(0, Source->SizeOfBitMap - 1) ULONG TargetBit,
_In_range_(0, Source->SizeOfBitMap) ULONG NumberOfBits
);
NTSYSAPI
ULONG
NTAPI
RtlNumberOfClearBitsInRange(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG StartingIndex,
_In_ ULONG Length
);
NTSYSAPI
ULONG
NTAPI
RtlNumberOfSetBitsInRange(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG StartingIndex,
_In_ ULONG Length
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
// private
typedef struct _RTL_BITMAP_EX
{
ULONG64 SizeOfBitMap;
PULONG64 Buffer;
} RTL_BITMAP_EX, *PRTL_BITMAP_EX;
// rev
NTSYSAPI
VOID
NTAPI
RtlInitializeBitMapEx(
_Out_ PRTL_BITMAP_EX BitMapHeader,
_In_ PULONG64 BitMapBuffer,
_In_ ULONG64 SizeOfBitMap
);
// rev
_Check_return_
NTSYSAPI
BOOLEAN
NTAPI
RtlTestBitEx(
_In_ PRTL_BITMAP_EX BitMapHeader,
_In_range_(<, BitMapHeader->SizeOfBitMap) ULONG64 BitNumber
);
// rev
NTSYSAPI
VOID
NTAPI
RtlClearAllBitsEx(
_In_ PRTL_BITMAP_EX BitMapHeader
);
// rev
NTSYSAPI
VOID
NTAPI
RtlClearBitEx(
_In_ PRTL_BITMAP_EX BitMapHeader,
_In_range_(<, BitMapHeader->SizeOfBitMap) ULONG64 BitNumber
);
// rev
NTSYSAPI
VOID
NTAPI
RtlSetBitEx(
_In_ PRTL_BITMAP_EX BitMapHeader,
_In_range_(<, BitMapHeader->SizeOfBitMap) ULONG64 BitNumber
);
// rev
NTSYSAPI
ULONG64
NTAPI
RtlFindSetBitsEx(
_In_ PRTL_BITMAP_EX BitMapHeader,
_In_ ULONG64 NumberToFind,
_In_ ULONG64 HintIndex
);
NTSYSAPI
ULONG64
NTAPI
RtlFindSetBitsAndClearEx(
_In_ PRTL_BITMAP_EX BitMapHeader,
_In_ ULONG64 NumberToFind,
_In_ ULONG64 HintIndex
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
//
// Handle tables
//
typedef struct _RTL_HANDLE_TABLE_ENTRY
{
union
{
ULONG Flags; // allocated entries have the low bit set
struct _RTL_HANDLE_TABLE_ENTRY *NextFree;
};
} RTL_HANDLE_TABLE_ENTRY, *PRTL_HANDLE_TABLE_ENTRY;
#define RTL_HANDLE_ALLOCATED (USHORT)0x0001
typedef struct _RTL_HANDLE_TABLE
{
ULONG MaximumNumberOfHandles;
ULONG SizeOfHandleTableEntry;
ULONG Reserved[2];
PRTL_HANDLE_TABLE_ENTRY FreeHandles;
PRTL_HANDLE_TABLE_ENTRY CommittedHandles;
PRTL_HANDLE_TABLE_ENTRY UnCommittedHandles;
PRTL_HANDLE_TABLE_ENTRY MaxReservedHandles;
} RTL_HANDLE_TABLE, *PRTL_HANDLE_TABLE;
NTSYSAPI
VOID
NTAPI
RtlInitializeHandleTable(
_In_ ULONG MaximumNumberOfHandles,
_In_ ULONG SizeOfHandleTableEntry,
_Out_ PRTL_HANDLE_TABLE HandleTable
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDestroyHandleTable(
_Inout_ PRTL_HANDLE_TABLE HandleTable
);
NTSYSAPI
PRTL_HANDLE_TABLE_ENTRY
NTAPI
RtlAllocateHandle(
_In_ PRTL_HANDLE_TABLE HandleTable,
_Out_opt_ PULONG HandleIndex
);
NTSYSAPI
BOOLEAN
NTAPI
RtlFreeHandle(
_In_ PRTL_HANDLE_TABLE HandleTable,
_In_ PRTL_HANDLE_TABLE_ENTRY Handle
);
NTSYSAPI
BOOLEAN
NTAPI
RtlIsValidHandle(
_In_ PRTL_HANDLE_TABLE HandleTable,
_In_ PRTL_HANDLE_TABLE_ENTRY Handle
);
NTSYSAPI
BOOLEAN
NTAPI
RtlIsValidIndexHandle(
_In_ PRTL_HANDLE_TABLE HandleTable,
_In_ ULONG HandleIndex,
_Out_ PRTL_HANDLE_TABLE_ENTRY *Handle
);
//
// Atom tables
//
#define RTL_ATOM_MAXIMUM_INTEGER_ATOM (RTL_ATOM)0xc000
#define RTL_ATOM_INVALID_ATOM (RTL_ATOM)0x0000
#define RTL_ATOM_TABLE_DEFAULT_NUMBER_OF_BUCKETS 37
#define RTL_ATOM_MAXIMUM_NAME_LENGTH 255
#define RTL_ATOM_PINNED 0x01
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateAtomTable(
_In_ ULONG NumberOfBuckets,
_Inout_ PVOID *AtomTableHandle
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDestroyAtomTable(
_In_ _Post_invalid_ PVOID AtomTableHandle
);
NTSYSAPI
NTSTATUS
NTAPI
RtlEmptyAtomTable(
_In_ PVOID AtomTableHandle,
_In_ BOOLEAN IncludePinnedAtoms
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAtomToAtomTable(
_In_ PVOID AtomTableHandle,
_In_ PCWSTR AtomName,
_Inout_opt_ PRTL_ATOM Atom
);
NTSYSAPI
NTSTATUS
NTAPI
RtlLookupAtomInAtomTable(
_In_ PVOID AtomTableHandle,
_In_ PCWSTR AtomName,
_Out_opt_ PRTL_ATOM Atom
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteAtomFromAtomTable(
_In_ PVOID AtomTableHandle,
_In_ RTL_ATOM Atom
);
NTSYSAPI
NTSTATUS
NTAPI
RtlPinAtomInAtomTable(
_In_ PVOID AtomTableHandle,
_In_ RTL_ATOM Atom
);
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryAtomInAtomTable(
_In_ PVOID AtomTableHandle,
_In_ RTL_ATOM Atom,
_Out_opt_ PULONG AtomUsage,
_Out_opt_ PULONG AtomFlags,
_Inout_updates_bytes_to_opt_(*AtomNameLength, *AtomNameLength) PWSTR AtomName,
_Inout_opt_ PULONG AtomNameLength
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlGetIntegerAtom(
_In_ PCWSTR AtomName,
_Out_opt_ PUSHORT IntegerAtom
);
//
// SIDs
//
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlValidSid(
_In_ PSID Sid
);
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualSid(
_In_ PSID Sid1,
_In_ PSID Sid2
);
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualPrefixSid(
_In_ PSID Sid1,
_In_ PSID Sid2
);
NTSYSAPI
ULONG
NTAPI
RtlLengthRequiredSid(
_In_ ULONG SubAuthorityCount
);
NTSYSAPI
PVOID
NTAPI
RtlFreeSid(
_In_ _Post_invalid_ PSID Sid
);
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlAllocateAndInitializeSid(
_In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
_In_ UCHAR SubAuthorityCount,
_In_ ULONG SubAuthority0,
_In_ ULONG SubAuthority1,
_In_ ULONG SubAuthority2,
_In_ ULONG SubAuthority3,
_In_ ULONG SubAuthority4,
_In_ ULONG SubAuthority5,
_In_ ULONG SubAuthority6,
_In_ ULONG SubAuthority7,
_Outptr_ PSID *Sid
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlAllocateAndInitializeSidEx(
_In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
_In_ UCHAR SubAuthorityCount,
_In_reads_(SubAuthorityCount) PULONG SubAuthorities,
_Outptr_ PSID *Sid
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeSid(
_Out_ PSID Sid,
_In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
_In_ UCHAR SubAuthorityCount
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeSidEx(
_Out_writes_bytes_(SECURITY_SID_SIZE(SubAuthorityCount)) PSID Sid,
_In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
_In_ UCHAR SubAuthorityCount,
...
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
NTSYSAPI
PSID_IDENTIFIER_AUTHORITY
NTAPI
RtlIdentifierAuthoritySid(
_In_ PSID Sid
);
NTSYSAPI
PULONG
NTAPI
RtlSubAuthoritySid(
_In_ PSID Sid,
_In_ ULONG SubAuthority
);
NTSYSAPI
PUCHAR
NTAPI
RtlSubAuthorityCountSid(
_In_ PSID Sid
);
NTSYSAPI
ULONG
NTAPI
RtlLengthSid(
_In_ PSID Sid
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCopySid(
_In_ ULONG DestinationSidLength,
_Out_writes_bytes_(DestinationSidLength) PSID DestinationSid,
_In_ PSID SourceSid
);
// ros
NTSYSAPI
NTSTATUS
NTAPI
RtlCopySidAndAttributesArray(
_In_ ULONG Count,
_In_ PSID_AND_ATTRIBUTES Src,
_In_ ULONG SidAreaSize,
_In_ PSID_AND_ATTRIBUTES Dest,
_In_ PSID SidArea,
_Out_ PSID *RemainingSidArea,
_Out_ PULONG RemainingSidAreaSize
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateServiceSid(
_In_ PCUNICODE_STRING ServiceName,
_Out_writes_bytes_opt_(*ServiceSidLength) PSID ServiceSid,
_Inout_ PULONG ServiceSidLength
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSidDominates(
_In_ PSID Sid1,
_In_ PSID Sid2,
_Out_ PBOOLEAN Dominates
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSidDominatesForTrust(
_In_ PSID Sid1,
_In_ PSID Sid2,
_Out_ PBOOLEAN DominatesTrust // TokenProcessTrustLevel
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSidEqualLevel(
_In_ PSID Sid1,
_In_ PSID Sid2,
_Out_ PBOOLEAN EqualLevel
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSidIsHigherLevel(
_In_ PSID Sid1,
_In_ PSID Sid2,
_Out_ PBOOLEAN HigherLevel
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateVirtualAccountSid(
_In_ PCUNICODE_STRING Name,
_In_ ULONG BaseSubAuthority,
_Out_writes_bytes_(*SidLength) PSID Sid,
_Inout_ PULONG SidLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlReplaceSidInSd(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ PSID OldSid,
_In_ PSID NewSid,
_Out_ ULONG *NumChanges
);
#define MAX_UNICODE_STACK_BUFFER_LENGTH 256
NTSYSAPI
NTSTATUS
NTAPI
RtlLengthSidAsUnicodeString(
_In_ PSID Sid,
_Out_ PULONG StringLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlConvertSidToUnicodeString(
_Inout_ PUNICODE_STRING UnicodeString,
_In_ PSID Sid,
_In_ BOOLEAN AllocateDestinationString
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSidHashInitialize(
_In_reads_(SidCount) PSID_AND_ATTRIBUTES SidAttr,
_In_ ULONG SidCount,
_Out_ PSID_AND_ATTRIBUTES_HASH SidAttrHash
);
// private
NTSYSAPI
PSID_AND_ATTRIBUTES
NTAPI
RtlSidHashLookup(
_In_ PSID_AND_ATTRIBUTES_HASH SidAttrHash,
_In_ PSID Sid
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsElevatedRid(
_In_ PSID_AND_ATTRIBUTES SidAttr
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlDeriveCapabilitySidsFromName(
_Inout_ PUNICODE_STRING UnicodeString,
_Out_ PSID CapabilityGroupSid,
_Out_ PSID CapabilitySid
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
//
// Security Descriptors
//
/**
* The RtlCreateSecurityDescriptor routine initializes a new absolute-format security descriptor.
* On return, the security descriptor is initialized with no system ACL, no discretionary ACL, no owner, no primary group, and all control flags set to zero.
*
* \param SecurityDescriptor Pointer to the buffer for the \ref SECURITY_DESCRIPTOR to be initialized.
* \param Revision Specifies the revision level to assign to the security descriptor. Set this parameter to SECURITY_DESCRIPTOR_REVISION.
* \return NTSTATUS Successful or errant status.
* \see https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlcreatesecuritydescriptor
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateSecurityDescriptor(
_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ ULONG Revision
);
/**
* The RtlValidSecurityDescriptor routine checks a given security descriptor's validity.
*
* \param SecurityDescriptor Pointer to the \ref SECURITY_DESCRIPTOR to be checked.
* \return Returns TRUE if the security descriptor is valid, or FALSE otherwise.
* \remarks The routine checks the validity of an absolute-format security descriptor. To check the validity of a self-relative security descriptor, use the \ref RtlValidRelativeSecurityDescriptor routine instead.
* \see https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlvalidsecuritydescriptor
*/
_Check_return_
NTSYSAPI
BOOLEAN
NTAPI
RtlValidSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
);
/**
* The RtlLengthSecurityDescriptor routine returns the size of a given security descriptor.
*
* \param SecurityDescriptor A pointer to a \ref SECURITY_DESCRIPTOR structure whose length the function retrieves.
* \return Returns the length, in bytes, of the SECURITY_DESCRIPTOR structure.
* \see https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtllengthsecuritydescriptor
*/
NTSYSAPI
ULONG
NTAPI
RtlLengthSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
);
/**
* The RtlValidRelativeSecurityDescriptor routine checks the validity of a self-relative security descriptor.
*
* \param SecurityDescriptorInput A pointer to the buffer that contains the security descriptor in self-relative format.
* The buffer must begin with a SECURITY_DESCRIPTOR structure, which is followed by the rest of the security descriptor data.
* \param SecurityDescriptorLength The size of the SecurityDescriptorInput structure.
* \param RequiredInformation A SECURITY_INFORMATION value that specifies the information that is required to be contained in the security descriptor.
* \return RtlValidRelativeSecurityDescriptor returns TRUE if the security descriptor is valid and includes the information that the RequiredInformation parameter specifies. Otherwise, this routine returns FALSE.
* \see https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlvalidrelativesecuritydescriptor
*/
_Check_return_
NTSYSAPI
BOOLEAN
NTAPI
RtlValidRelativeSecurityDescriptor(
_In_reads_bytes_(SecurityDescriptorLength) PSECURITY_DESCRIPTOR SecurityDescriptorInput,
_In_ ULONG SecurityDescriptorLength,
_In_ SECURITY_INFORMATION RequiredInformation
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetControlSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_Out_ PSECURITY_DESCRIPTOR_CONTROL Control,
_Out_ PULONG Revision
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetControlSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
_In_ SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetAttributesSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ SECURITY_DESCRIPTOR_CONTROL Control,
_Out_ PULONG Revision
);
NTSYSAPI
BOOLEAN
NTAPI
RtlGetSecurityDescriptorRMControl(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_Out_ PUCHAR RMControl
);
NTSYSAPI
VOID
NTAPI
RtlSetSecurityDescriptorRMControl(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_opt_ PUCHAR RMControl
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetDaclSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ BOOLEAN DaclPresent,
_In_opt_ PACL Dacl,
_In_ BOOLEAN DaclDefaulted
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetDaclSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_Out_ PBOOLEAN DaclPresent,
_Outptr_result_maybenull_ PACL *Dacl,
_Out_ PBOOLEAN DaclDefaulted
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetSaclSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ BOOLEAN SaclPresent,
_In_opt_ PACL Sacl,
_In_ BOOLEAN SaclDefaulted
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetSaclSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_Out_ PBOOLEAN SaclPresent,
_Out_ PACL *Sacl,
_Out_ PBOOLEAN SaclDefaulted
);
/**
* The RtlSetOwnerSecurityDescriptor routine sets the owner information of an absolute-format security descriptor. It replaces any owner information that is already present in the security descriptor.
*
* \param SecurityDescriptor Pointer to the SECURITY_DESCRIPTOR structure whose owner is to be set. RtlSetOwnerSecurityDescriptor replaces any existing owner with the new owner.
* \param Owner Pointer to a security identifier (SID) structure for the security descriptor's new primary owner.
* \li \c This pointer, not the SID structure itself, is copied into the security descriptor.
* \li \c If this parameter is NULL, RtlSetOwnerSecurityDescriptor clears the security descriptor's owner information. This marks the security descriptor as having no owner.
* \param OwnerDefaulted Set to TRUE if the owner information is derived from a default mechanism.
* \li \c If this value is TRUE, it is default information. RtlSetOwnerSecurityDescriptor sets the SE_OWNER_DEFAULTED flag in the security descriptor's SECURITY_DESCRIPTOR_CONTROL field.
* \li \c If this parameter is FALSE, the SE_OWNER_DEFAULTED flag is cleared.
* \return NTSTATUS Successful or errant status.
* \see https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlsetownersecuritydescriptor
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlSetOwnerSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_opt_ PSID Owner,
_In_ BOOLEAN OwnerDefaulted
);
/**
* The RtlGetOwnerSecurityDescriptor routine returns the owner information for a given security descriptor.
*
* \param SecurityDescriptor Pointer to the SECURITY_DESCRIPTOR structure.
* \param Owner Pointer to an address to receive a pointer to the owner security identifier (SID). If the security descriptor does not currently contain an owner SID, Owner receives NULL.
* \param OwnerDefaulted Pointer to a Boolean variable that receives TRUE if the owner information is derived from a default mechanism, FALSE otherwise. Valid only if Owner receives a non-NULL value.
* \return NTSTATUS Successful or errant status.
* \see https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlgetownersecuritydescriptor
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlGetOwnerSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_Outptr_result_maybenull_ PSID *Owner,
_Out_ PBOOLEAN OwnerDefaulted
);
/**
* The RtlSetGroupSecurityDescriptor routine sets the primary group information of an absolute-format security descriptor. It replaces any primary group information that is already present in the security descriptor.
*
* \param SecurityDescriptor Pointer to the SECURITY_DESCRIPTOR structure whose primary group is to be set. RtlSetGroupSecurityDescriptor replaces any existing primary group with the new primary group.
* \param Group Pointer to a security identifier (SID) structure for the security descriptor's new primary owner.
* \li \c This pointer, not the SID structure itself, is copied into the security descriptor.
* \li \c If Group is NULL, RtlSetGroupSecurityDescriptor clears the security descriptor's primary group information. This marks the security descriptor as having no primary group.
* \param GroupDefaulted Set this Boolean variable to TRUE if the primary group information is derived from a default mechanism.
* \li \c If this parameter is TRUE, RtlSetGroupSecurityDescriptor sets the SE_GROUP_DEFAULTED flag in the security descriptor's SECURITY_DESCRIPTOR_CONTROL field.
* \li \c If this parameter is FALSE, RtlSetGroupSecurityDescriptor clears the SE_GROUP_DEFAULTED flag.
* \return NTSTATUS Successful or errant status.
* \see https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlsetgroupsecuritydescriptor
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlSetGroupSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_opt_ PSID Group,
_In_ BOOLEAN GroupDefaulted
);
/**
* The RtlGetGroupSecurityDescriptor routine returns the primary group information for a given security descriptor.
*
* \param SecurityDescriptor Pointer to the security descriptor whose primary group information is to be returned.
* \param Group Pointer to a variable that receives a pointer to the security identifier (SID) for the primary group.
* \param GroupDefaulted Pointer to a Boolean variable that receives the value of the SE_GROUP_DEFAULTED flag.
* \return NTSTATUS Successful or errant status.
* \see https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlgetgroupsecuritydescriptor
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlGetGroupSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_Outptr_result_maybenull_ PSID *Group,
_Out_ PBOOLEAN GroupDefaulted
);
NTSYSAPI
NTSTATUS
NTAPI
RtlMakeSelfRelativeSD(
_In_ PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
_Out_writes_bytes_(*BufferLength) PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
_Inout_ PULONG BufferLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAbsoluteToSelfRelativeSD(
_In_ PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
_Out_writes_bytes_to_opt_(*BufferLength, *BufferLength) PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
_Inout_ PULONG BufferLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSelfRelativeToAbsoluteSD(
_In_ PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
_Out_writes_bytes_to_opt_(*AbsoluteSecurityDescriptorSize, *AbsoluteSecurityDescriptorSize) PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
_Inout_ PULONG AbsoluteSecurityDescriptorSize,
_Out_writes_bytes_to_opt_(*DaclSize, *DaclSize) PACL Dacl,
_Inout_ PULONG DaclSize,
_Out_writes_bytes_to_opt_(*SaclSize, *SaclSize) PACL Sacl,
_Inout_ PULONG SaclSize,
_Out_writes_bytes_to_opt_(*OwnerSize, *OwnerSize) PSID Owner,
_Inout_ PULONG OwnerSize,
_Out_writes_bytes_to_opt_(*PrimaryGroupSize, *PrimaryGroupSize) PSID PrimaryGroup,
_Inout_ PULONG PrimaryGroupSize
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSelfRelativeToAbsoluteSD2(
_Inout_ PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
_Inout_ PULONG BufferSize
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_19H2)
__drv_maxIRQL(APC_LEVEL)
NTSYSAPI
BOOLEAN
NTAPI
RtlNormalizeSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR *SecurityDescriptor,
_In_ ULONG SecurityDescriptorLength,
_Out_opt_ PSECURITY_DESCRIPTOR *NewSecurityDescriptor,
_Out_opt_ PULONG NewSecurityDescriptorLength,
_In_ BOOLEAN CheckOnly
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_19H2
//
// Access masks
//
#ifndef PHNT_NO_INLINE_ACCESSES_GRANTED
/**
* Checks if all desired accesses are granted.
*
* This function determines whether all the accesses specified in the DesiredAccess
* mask are granted by the GrantedAccess mask.
*
* \param GrantedAccess The access mask that specifies the granted accesses.
* \param DesiredAccess The access mask that specifies the desired accesses.
* \return Returns TRUE if all desired accesses are granted, otherwise FALSE.
*/
FORCEINLINE
BOOLEAN
NTAPI_INLINE
RtlAreAllAccessesGranted(
_In_ ACCESS_MASK GrantedAccess,
_In_ ACCESS_MASK DesiredAccess
)
{
return (~GrantedAccess & DesiredAccess) == 0;
}
/**
* Checks if any of the desired accesses are granted.
*
* This function determines if any of the access rights specified in the DesiredAccess
* mask are present in the GrantedAccess mask.
*
* \param GrantedAccess The access mask that specifies the granted access rights.
* \param DesiredAccess The access mask that specifies the desired access rights.
* \return Returns TRUE if any of the desired access rights are granted, otherwise FALSE.
*/
FORCEINLINE
BOOLEAN
NTAPI_INLINE
RtlAreAnyAccessesGranted(
_In_ ACCESS_MASK GrantedAccess,
_In_ ACCESS_MASK DesiredAccess
)
{
return (GrantedAccess & DesiredAccess) != 0;
}
#else
/**
* Checks if all desired accesses are granted.
*
* This function determines whether all the accesses specified in the DesiredAccess
* mask are granted by the GrantedAccess mask.
*
* \param GrantedAccess The access mask that specifies the granted accesses.
* \param DesiredAccess The access mask that specifies the desired accesses.
* \return Returns TRUE if all desired accesses are granted, otherwise FALSE.
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlAreAllAccessesGranted(
_In_ ACCESS_MASK GrantedAccess,
_In_ ACCESS_MASK DesiredAccess
);
/**
* Checks if any of the desired accesses are granted.
*
* This function determines if any of the access rights specified in the DesiredAccess
* mask are present in the GrantedAccess mask.
*
* \param GrantedAccess The access mask that specifies the granted access rights.
* \param DesiredAccess The access mask that specifies the desired access rights.
* \return Returns TRUE if any of the desired access rights are granted, otherwise FALSE.
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlAreAnyAccessesGranted(
_In_ ACCESS_MASK GrantedAccess,
_In_ ACCESS_MASK DesiredAccess
);
#endif // PHNT_NO_INLINE_ACCESSES_GRANTED
NTSYSAPI
VOID
NTAPI
RtlMapGenericMask(
_Inout_ PACCESS_MASK AccessMask,
_In_ PGENERIC_MAPPING GenericMapping
);
//
// ACLs
//
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateAcl(
_Out_writes_bytes_(AclLength) PACL Acl,
_In_ ULONG AclLength,
_In_ ULONG AclRevision
);
NTSYSAPI
BOOLEAN
NTAPI
RtlValidAcl(
_In_ PACL Acl
);
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryInformationAcl(
_In_ PACL Acl,
_Out_writes_bytes_(AclInformationLength) PVOID AclInformation,
_In_ ULONG AclInformationLength,
_In_ ACL_INFORMATION_CLASS AclInformationClass
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetInformationAcl(
_Inout_ PACL Acl,
_In_reads_bytes_(AclInformationLength) PVOID AclInformation,
_In_ ULONG AclInformationLength,
_In_ ACL_INFORMATION_CLASS AclInformationClass
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG StartingAceIndex,
_In_reads_bytes_(AceListLength) PVOID AceList,
_In_ ULONG AceListLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteAce(
_Inout_ PACL Acl,
_In_ ULONG AceIndex
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetAce(
_In_ PACL Acl,
_In_ ULONG AceIndex,
_Outptr_ PVOID *Ace
);
#if (PHNT_VERSION >= PHNT_WINDOWS_11_24H2)
NTSYSAPI
NTSTATUS
NTAPI
RtlGetAcesBufferSize(
_In_ PACL Acl,
_Out_ PULONG AcesBufferSize
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11_24H2
NTSYSAPI
BOOLEAN
NTAPI
RtlFirstFreeAce(
_In_ PACL Acl,
_Out_ PVOID *FirstFree
);
// private
NTSYSAPI
PVOID
NTAPI
RtlFindAceByType(
_In_ PACL Acl,
_In_ UCHAR AceType,
_Out_opt_ PULONG Index
);
// private
NTSYSAPI
BOOLEAN
NTAPI
RtlOwnerAcesPresent(
_In_ PACL pAcl
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessAllowedAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessAllowedAceEx(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessDeniedAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessDeniedAceEx(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAuditAccessAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid,
_In_ BOOLEAN AuditSuccess,
_In_ BOOLEAN AuditFailure
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAuditAccessAceEx(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid,
_In_ BOOLEAN AuditSuccess,
_In_ BOOLEAN AuditFailure
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessAllowedObjectAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ACCESS_MASK AccessMask,
_In_opt_ PGUID ObjectTypeGuid,
_In_opt_ PGUID InheritedObjectTypeGuid,
_In_ PSID Sid
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessDeniedObjectAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ACCESS_MASK AccessMask,
_In_opt_ PGUID ObjectTypeGuid,
_In_opt_ PGUID InheritedObjectTypeGuid,
_In_ PSID Sid
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAuditAccessObjectAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ACCESS_MASK AccessMask,
_In_opt_ PGUID ObjectTypeGuid,
_In_opt_ PGUID InheritedObjectTypeGuid,
_In_ PSID Sid,
_In_ BOOLEAN AuditSuccess,
_In_ BOOLEAN AuditFailure
);
// private
#define COMPOUND_ACE_IMPERSONATION 1
// private
typedef struct _COMPOUND_ACCESS_ALLOWED_ACE
{
ACE_HEADER Header;
ACCESS_MASK Mask;
USHORT CompoundAceType; // COMPOUND_ACE_*
USHORT Reserved;
ULONG SidStart; // Server SID
// Client SID follows
} COMPOUND_ACCESS_ALLOWED_ACE, *PCOMPOUND_ACCESS_ALLOWED_ACE;
NTSYSAPI
NTSTATUS
NTAPI
RtlAddCompoundAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ UCHAR AceType, // COMPOUND_ACE_*
_In_ ACCESS_MASK AccessMask,
_In_ PSID ServerSid,
_In_ PSID ClientSid
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlAddMandatoryAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ PSID Sid,
_In_ UCHAR AceType,
_In_ ACCESS_MASK AccessMask
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
NTSYSAPI
NTSTATUS
NTAPI
RtlAddResourceAttributeAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ULONG AccessMask,
_In_ PSID Sid,
_In_ PCLAIM_SECURITY_ATTRIBUTES_INFORMATION AttributeInfo,
_Out_ PULONG ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddScopedPolicyIDAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ULONG AccessMask,
_In_ PSID Sid
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlAddProcessTrustLabelAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ PSID ProcessTrustLabelSid,
_In_ UCHAR AceType, // SYSTEM_PROCESS_TRUST_LABEL_ACE_TYPE
_In_ ACCESS_MASK AccessMask
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessFilterAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags, // TRUST_PROTECTED_FILTER_ACE_FLAG
_In_ PSID AccessFilterSid,
_In_ UCHAR AceType, // SYSTEM_FILTERING_ACE_TYPE
_In_ ACCESS_MASK AccessMask,
_In_ PVOID Buffer, // SYSTEM_ACCESS_FILTER_ACE
_In_ USHORT BufferLength
);
//
// Named pipes
//
NTSYSAPI
NTSTATUS
NTAPI
RtlDefaultNpAcl(
_Out_ PACL *Acl
);
//
// Security objects
//
NTSYSAPI
NTSTATUS
NTAPI
RtlNewSecurityObject(
_In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor,
_In_opt_ PSECURITY_DESCRIPTOR CreatorDescriptor,
_Out_ PSECURITY_DESCRIPTOR *NewDescriptor,
_In_ BOOLEAN IsDirectoryObject,
_In_opt_ HANDLE Token,
_In_ PGENERIC_MAPPING GenericMapping
);
NTSYSAPI
NTSTATUS
NTAPI
RtlNewSecurityObjectEx(
_In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor,
_In_opt_ PSECURITY_DESCRIPTOR CreatorDescriptor,
_Out_ PSECURITY_DESCRIPTOR *NewDescriptor,
_In_opt_ GUID *ObjectType,
_In_ BOOLEAN IsDirectoryObject,
_In_ ULONG AutoInheritFlags, // SEF_*
_In_opt_ HANDLE Token,
_In_ PGENERIC_MAPPING GenericMapping
);
NTSYSAPI
NTSTATUS
NTAPI
RtlNewSecurityObjectWithMultipleInheritance(
_In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor,
_In_opt_ PSECURITY_DESCRIPTOR CreatorDescriptor,
_Out_ PSECURITY_DESCRIPTOR *NewDescriptor,
_In_opt_ GUID **ObjectType,
_In_ ULONG GuidCount,
_In_ BOOLEAN IsDirectoryObject,
_In_ ULONG AutoInheritFlags, // SEF_*
_In_opt_ HANDLE Token,
_In_ PGENERIC_MAPPING GenericMapping
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteSecurityObject(
_Inout_ PSECURITY_DESCRIPTOR *ObjectDescriptor
);
NTSYSAPI
NTSTATUS
NTAPI
RtlQuerySecurityObject(
_In_ PSECURITY_DESCRIPTOR ObjectDescriptor,
_In_ SECURITY_INFORMATION SecurityInformation,
_Out_opt_ PSECURITY_DESCRIPTOR ResultantDescriptor,
_In_ ULONG DescriptorLength,
_Out_ PULONG ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetSecurityObject(
_In_ SECURITY_INFORMATION SecurityInformation,
_In_ PSECURITY_DESCRIPTOR ModificationDescriptor,
_Inout_ PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
_In_ PGENERIC_MAPPING GenericMapping,
_In_opt_ HANDLE TokenHandle
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetSecurityObjectEx(
_In_ SECURITY_INFORMATION SecurityInformation,
_In_ PSECURITY_DESCRIPTOR ModificationDescriptor,
_Inout_ PSECURITY_DESCRIPTOR *ObjectsSecurityDescriptor,
_In_ ULONG AutoInheritFlags, // SEF_*
_In_ PGENERIC_MAPPING GenericMapping,
_In_opt_ HANDLE TokenHandle
);
NTSYSAPI
NTSTATUS
NTAPI
RtlConvertToAutoInheritSecurityObject(
_In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor,
_In_ PSECURITY_DESCRIPTOR CurrentSecurityDescriptor,
_Out_ PSECURITY_DESCRIPTOR *NewSecurityDescriptor,
_In_opt_ GUID *ObjectType,
_In_ BOOLEAN IsDirectoryObject,
_In_ PGENERIC_MAPPING GenericMapping
);
NTSYSAPI
NTSTATUS
NTAPI
RtlNewInstanceSecurityObject(
_In_ BOOLEAN ParentDescriptorChanged,
_In_ BOOLEAN CreatorDescriptorChanged,
_In_ PLUID OldClientTokenModifiedId,
_Out_ PLUID NewClientTokenModifiedId,
_In_opt_ PSECURITY_DESCRIPTOR ParentDescriptor,
_In_opt_ PSECURITY_DESCRIPTOR CreatorDescriptor,
_Out_ PSECURITY_DESCRIPTOR *NewDescriptor,
_In_ BOOLEAN IsDirectoryObject,
_In_ HANDLE TokenHandle,
_In_ PGENERIC_MAPPING GenericMapping
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCopySecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR InputSecurityDescriptor,
_Out_ PSECURITY_DESCRIPTOR *OutputSecurityDescriptor
);
// private
typedef struct _RTL_ACE_DATA
{
UCHAR AceType;
UCHAR InheritFlags;
UCHAR AceFlags;
ACCESS_MASK AccessMask;
PSID* Sid;
} RTL_ACE_DATA, *PRTL_ACE_DATA;
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserSecurityObject(
_In_ PRTL_ACE_DATA AceData,
_In_ ULONG AceCount,
_In_ PSID OwnerSid,
_In_ PSID GroupSid,
_In_ BOOLEAN IsDirectoryObject,
_In_ PGENERIC_MAPPING GenericMapping,
_Out_ PSECURITY_DESCRIPTOR* NewSecurityDescriptor
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateAndSetSD(
_In_ PRTL_ACE_DATA AceData,
_In_ ULONG AceCount,
_In_opt_ PSID OwnerSid,
_In_opt_ PSID GroupSid,
_Out_ PSECURITY_DESCRIPTOR* NewSecurityDescriptor
);
//
// Misc. security
//
NTSYSAPI
VOID
NTAPI
RtlRunEncodeUnicodeString(
_Inout_ PUCHAR Seed,
_Inout_ PUNICODE_STRING String
);
NTSYSAPI
VOID
NTAPI
RtlRunDecodeUnicodeString(
_In_ UCHAR Seed,
_Inout_ PUNICODE_STRING String
);
NTSYSAPI
NTSTATUS
NTAPI
RtlImpersonateSelf(
_In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlImpersonateSelfEx(
_In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
_In_opt_ ACCESS_MASK AdditionalAccess,
_Out_opt_ PHANDLE ThreadToken
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAdjustPrivilege(
_In_ ULONG Privilege,
_In_ BOOLEAN Enable,
_In_ BOOLEAN Client,
_Out_ PBOOLEAN WasEnabled
);
#define RTL_ACQUIRE_PRIVILEGE_REVERT 0x00000001
#define RTL_ACQUIRE_PRIVILEGE_PROCESS 0x00000002
NTSYSAPI
NTSTATUS
NTAPI
RtlAcquirePrivilege(
_In_ PULONG Privilege,
_In_ ULONG NumPriv,
_In_ ULONG Flags,
_Out_ PVOID *ReturnedState
);
NTSYSAPI
VOID
NTAPI
RtlReleasePrivilege(
_In_ PVOID StatePointer
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlRemovePrivileges(
_In_ HANDLE TokenHandle,
_In_ PULONG PrivilegesToKeep,
_In_ ULONG PrivilegeCount
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlIsUntrustedObject(
_In_opt_ HANDLE Handle,
_In_opt_ PVOID Object,
_Out_ PBOOLEAN IsUntrustedObject
);
NTSYSAPI
ULONG
NTAPI
RtlQueryValidationRunlevel(
_In_opt_ PCUNICODE_STRING ComponentName
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
NTSYSAPI
NTSTATUS
NTAPI
RtlNewSecurityGrantedAccess(
_In_ ACCESS_MASK DesiredAccess,
_Out_ PPRIVILEGE_SET NewPrivileges,
_Inout_ PULONG Length,
_In_opt_ HANDLE TokenHandle,
_In_ PGENERIC_MAPPING GenericMapping,
_Out_ PACCESS_MASK RemainingDesiredAccess
);
//
// Private namespaces
//
// rev
#define BOUNDARY_DESCRIPTOR_FLAG_NONE 0x0
#define BOUNDARY_DESCRIPTOR_ADD_APPCONTAINER_SID 0x0001
_Ret_maybenull_
_Success_(return != NULL)
NTSYSAPI
POBJECT_BOUNDARY_DESCRIPTOR
NTAPI
RtlCreateBoundaryDescriptor(
_In_ PCUNICODE_STRING Name,
_In_ ULONG Flags
);
NTSYSAPI
VOID
NTAPI
RtlDeleteBoundaryDescriptor(
_In_ _Post_invalid_ POBJECT_BOUNDARY_DESCRIPTOR BoundaryDescriptor
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddSIDToBoundaryDescriptor(
_Inout_ POBJECT_BOUNDARY_DESCRIPTOR *BoundaryDescriptor,
_In_ PCSID RequiredSid
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlAddIntegrityLabelToBoundaryDescriptor(
_Inout_ POBJECT_BOUNDARY_DESCRIPTOR *BoundaryDescriptor,
_In_ PCSID IntegrityLabel
);
//
// Version
//
// rev
typedef struct _RTL_OSVERSIONINFO
{
ULONG OSVersionInfoSize;
ULONG MajorVersion;
ULONG MinorVersion;
ULONG BuildNumber;
ULONG PlatformId;
WCHAR CSDVersion[128];
} RTL_OSVERSIONINFO, *PRTL_OSVERSIONINFO;
// rev
typedef struct _RTL_OSVERSIONINFOEX
{
ULONG OSVersionInfoSize;
ULONG MajorVersion;
ULONG MinorVersion;
ULONG BuildNumber;
ULONG PlatformId;
WCHAR CSDVersion[128];
USHORT ServicePackMajor;
USHORT ServicePackMinor;
USHORT SuiteMask;
UCHAR ProductType;
UCHAR Reserved;
} RTL_OSVERSIONINFOEX, *PRTL_OSVERSIONINFOEX;
// rev
typedef struct _RTL_OSVERSIONINFOEX2
{
ULONG OSVersionInfoSize;
ULONG MajorVersion;
ULONG MinorVersion;
ULONG BuildNumber;
ULONG PlatformId;
WCHAR CSDVersion[128];
USHORT ServicePackMajor;
USHORT ServicePackMinor;
USHORT SuiteMask;
UCHAR ProductType;
UCHAR Reserved;
ULONG SuiteMaskEx;
ULONG Reserved2;
} RTL_OSVERSIONINFOEX2, *PRTL_OSVERSIONINFOEX2;
// rev
typedef struct _RTL_OSVERSIONINFOEX3
{
ULONG OSVersionInfoSize;
ULONG MajorVersion;
ULONG MinorVersion;
ULONG BuildNumber;
union
{
ULONG PlatformId;
ULONG QfeNumber;
};
union
{
WCHAR CSDVersion[128];
WCHAR LayerAttrib[128];
};
USHORT ServicePackMajor;
USHORT ServicePackMinor;
USHORT SuiteMask;
UCHAR ProductType;
UCHAR Reserved;
ULONG SuiteMaskEx;
ULONG Reserved2;
union
{
USHORT RawInput16;
USHORT LayerNumber : 12;
USHORT AttribSelector : 4;
} Input;
USHORT LayerCount;
ULONG LayerFlags;
} RTL_OSVERSIONINFOEX3, *PRTL_OSVERSIONINFOEX3;
NTSYSAPI
NTSTATUS
NTAPI
RtlGetVersion(
_Out_ PVOID VersionInformation
);
NTSYSAPI
NTSTATUS
NTAPI
RtlVerifyVersionInfo(
_In_ PVOID VersionInformation,
_In_ ULONG TypeMask,
_In_ ULONGLONG ConditionMask
);
// rev
NTSYSAPI
VOID
NTAPI
RtlGetNtVersionNumbers(
_Out_opt_ PULONG NtMajorVersion,
_Out_opt_ PULONG NtMinorVersion,
_Out_opt_ PULONG NtBuildNumber
);
//
// System information
//
// rev
NTSYSAPI
ULONG
NTAPI
RtlGetNtGlobalFlags(
VOID
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlGetNtProductType(
_Out_ PNT_PRODUCT_TYPE NtProductType
);
// private
NTSYSAPI
BOOLEAN
NTAPI
RtlGetProductInfo(
_In_ ULONG OSMajorVersion,
_In_ ULONG OSMinorVersion,
_In_ ULONG SpMajorVersion,
_In_ ULONG SpMinorVersion,
_Out_ PULONG ReturnedProductType
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS1)
// private
NTSYSAPI
ULONG
NTAPI
RtlGetSuiteMask(
VOID
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS1
//
// Thread pool (old)
//
typedef _Function_class_(WAIT_CALLBACK_ROUTINE)
VOID NTAPI WAIT_CALLBACK_ROUTINE(
_In_ PVOID Parameter,
_In_ BOOLEAN TimerOrWaitFired
);
typedef WAIT_CALLBACK_ROUTINE* PWAIT_CALLBACK_ROUTINE;
#define WT_EXECUTEDEFAULT 0x00000000
#define WT_EXECUTEINIOTHREAD 0x00000001
#define WT_EXECUTEINUITHREAD 0x00000002
#define WT_EXECUTEINWAITTHREAD 0x00000004
#define WT_EXECUTEONLYONCE 0x00000008
#define WT_EXECUTELONGFUNCTION 0x00000010
#define WT_EXECUTEINTIMERTHREAD 0x00000020
#define WT_EXECUTEINPERSISTENTIOTHREAD 0x00000040
#define WT_EXECUTEINPERSISTENTTHREAD 0x00000080
#define WT_TRANSFER_IMPERSONATION 0x00000100
NTSYSAPI
NTSTATUS
NTAPI
RtlRegisterWait(
_Out_ PHANDLE WaitHandle,
_In_ HANDLE Handle,
_In_ PWAIT_CALLBACK_ROUTINE Function,
_In_opt_ PVOID Context,
_In_ ULONG Milliseconds,
_In_ ULONG Flags
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeregisterWait(
_In_ HANDLE WaitHandle
);
#define RTL_WAITER_DEREGISTER_WAIT_FOR_COMPLETION ((HANDLE)(LONG_PTR)-1)
/**
* Releases all resources used by a wait object.
*
* \param WaitHandle The access mask that specifies the granted access rights.
* \param CompletionEvent Optional completion event for wait callback completion.
* \remarks RTL_WAITER_DEREGISTER_WAIT_FOR_COMPLETION: blocking wait for wait callback completion.
* NULL: non-blocking wait for wait callback completion.
* EventHandle: caller wait for wait callback completion.
* \return NTSTATUS Successful or errant status.
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlDeregisterWaitEx(
_In_ HANDLE WaitHandle,
_In_opt_ HANDLE CompletionEvent // optional: RTL_WAITER_DEREGISTER_WAIT_FOR_COMPLETION
);
typedef _Function_class_(RTL_WORK_CALLBACK)
VOID NTAPI RTL_WORK_CALLBACK(
_In_ PVOID ThreadParameter
);
typedef RTL_WORK_CALLBACK* PRTL_WORK_CALLBACK;
NTSYSAPI
NTSTATUS
NTAPI
RtlQueueWorkItem(
_In_ PRTL_WORK_CALLBACK Function,
_In_opt_ PVOID Context,
_In_ ULONG Flags
);
typedef _Function_class_(RTL_OVERLAPPED_COMPLETION_ROUTINE)
VOID NTAPI RTL_OVERLAPPED_COMPLETION_ROUTINE(
_In_ NTSTATUS StatusCode,
_In_ PVOID Context1,
_In_ PVOID Context2
);
typedef RTL_OVERLAPPED_COMPLETION_ROUTINE* PRTL_OVERLAPPED_COMPLETION_ROUTINE;
/**
* Associates the I/O completion port owned by the thread pool with the specified file handle.
* On completion of an I/O request involving this file, a non-I/O worker thread will execute the specified callback function.
*
* \param FileHandle A handle to the file or device for which to set the I/O completion callback.
* \param Function A pointer to the callback function to be executed when an I/O operation completes.
* \param Flags Reserved; must be zero.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-bindiocompletioncallback
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlSetIoCompletionCallback(
_In_ HANDLE FileHandle,
_In_ PRTL_OVERLAPPED_COMPLETION_ROUTINE Function,
_In_ ULONG Flags
);
typedef _Function_class_(RTL_START_POOL_THREAD)
NTSTATUS NTAPI RTL_START_POOL_THREAD(
_In_ PUSER_THREAD_START_ROUTINE Function,
_In_ PVOID Parameter,
_Out_ PHANDLE ThreadHandle
);
typedef RTL_START_POOL_THREAD *PRTL_START_POOL_THREAD;
typedef _Function_class_(RTL_EXIT_POOL_THREAD)
NTSTATUS NTAPI RTL_EXIT_POOL_THREAD(
_In_ NTSTATUS ExitStatus
);
typedef RTL_EXIT_POOL_THREAD *PRTL_EXIT_POOL_THREAD;
NTSYSAPI
NTSTATUS
NTAPI
RtlSetThreadPoolStartFunc(
_In_ PRTL_START_POOL_THREAD StartPoolThread,
_In_ PRTL_EXIT_POOL_THREAD ExitPoolThread
);
NTSYSAPI
VOID
NTAPI
RtlUserThreadStart(
_In_ PUSER_THREAD_START_ROUTINE Function,
_In_ PVOID Parameter
);
NTSYSAPI
VOID
NTAPI
LdrInitializeThunk(
_In_ PCONTEXT ContextRecord,
_In_ PVOID Parameter
);
NTSYSAPI
NTSTATUS
NTAPI
LdrProcessInitializationComplete(
VOID
);
//
// Thread execution
//
NTSYSAPI
NTSTATUS
NTAPI
RtlDelayExecution(
_In_ BOOLEAN Alertable,
_In_opt_ PLARGE_INTEGER DelayInterval
);
//
// Timer support
//
/**
* Creates a queue for timers.
*
* \param TimerQueueHandle A pointer to a variable that receives the handle to the newly created timer queue.
* \return NTSTATUS Successful or errant status.
* \remarks Timer-queue timers are lightweight objects that enable you to specify a callback function to be called at a specified time.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/threadpoollegacyapiset/nf-threadpoollegacyapiset-createtimerqueue
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateTimerQueue(
_Out_ PHANDLE TimerQueueHandle
);
typedef _Function_class_(RTL_TIMER_CALLBACK)
VOID NTAPI RTL_TIMER_CALLBACK(
_In_ PVOID Parameter,
_In_ BOOLEAN TimerOrWaitFired
);
typedef RTL_TIMER_CALLBACK *PRTL_TIMER_CALLBACK;
/**
* Creates a timer-queue timer.
*
* \param TimerQueueHandle A handle to the timer queue. This handle is returned by a previous call to RtlCreateTimerQueue.
* \param Handle A pointer to a variable that receives the handle to the newly created timer-queue timer.
* \param Function A pointer to the callback function to be executed when the timer expires.
* \param Context A pointer to a variable to be passed to the callback function.
* \param DueTime The amount of time in milliseconds relative to the current time that must elapse before the timer is signaled for the first time.
* \param Period The period of the timer in milliseconds. If this value is zero, the timer is signaled once; otherwise, it is signaled periodically.
* \param Flags The flags that control the behavior of the timer. This parameter can be zero or one of the following values:
* WT_EXECUTEDEFAULT, WT_EXECUTEONLYONCE, WT_EXECUTELONGFUNCTION, WT_EXECUTEINTIMERTHREAD, WT_EXECUTEINPERSISTENTTHREAD, WT_TRANSFER_IMPERSONATION.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/threadpoollegacyapiset/nf-threadpoollegacyapiset-createtimerqueuetimer
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateTimer(
_In_ HANDLE TimerQueueHandle,
_Out_ PHANDLE Handle,
_In_ PRTL_TIMER_CALLBACK Function,
_In_opt_ PVOID Context,
_In_ ULONG DueTime,
_In_ ULONG Period,
_In_ ULONG Flags
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetTimer(
_In_ HANDLE TimerQueueHandle,
_Out_ PHANDLE Handle,
_In_ PRTL_TIMER_CALLBACK Function,
_In_opt_ PVOID Context,
_In_ ULONG DueTime,
_In_ ULONG Period,
_In_ ULONG Flags
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUpdateTimer(
_In_ HANDLE TimerQueueHandle,
_In_ HANDLE TimerHandle,
_In_ ULONG DueTime,
_In_ ULONG Period
);
#define RTL_TIMER_DELETE_WAIT_FOR_COMPLETION ((HANDLE)(LONG_PTR)-1)
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteTimer(
_In_ HANDLE TimerQueueHandle,
_In_ HANDLE TimerToCancel,
_In_opt_ HANDLE Event // optional: RTL_TIMER_DELETE_WAIT_FOR_COMPLETION
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteTimerQueue(
_In_ HANDLE TimerQueueHandle
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteTimerQueueEx(
_In_ HANDLE TimerQueueHandle,
_In_opt_ HANDLE Event
);
//
// Registry access
//
NTSYSAPI
NTSTATUS
NTAPI
RtlFormatCurrentUserKeyPath(
_Out_ PUNICODE_STRING CurrentUserKeyPath
);
NTSYSAPI
NTSTATUS
NTAPI
RtlOpenCurrentUser(
_In_ ACCESS_MASK DesiredAccess,
_Out_ PHANDLE CurrentUserKey
);
#define RTL_REGISTRY_ABSOLUTE 0
#define RTL_REGISTRY_SERVICES 1 // \Registry\Machine\System\CurrentControlSet\Services
#define RTL_REGISTRY_CONTROL 2 // \Registry\Machine\System\CurrentControlSet\Control
#define RTL_REGISTRY_WINDOWS_NT 3 // \Registry\Machine\Software\Microsoft\Windows NT\CurrentVersion
#define RTL_REGISTRY_DEVICEMAP 4 // \Registry\Machine\Hardware\DeviceMap
#define RTL_REGISTRY_USER 5 // \Registry\User\CurrentUser
#define RTL_REGISTRY_MAXIMUM 6
#define RTL_REGISTRY_HANDLE 0x40000000
#define RTL_REGISTRY_OPTIONAL 0x80000000
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateRegistryKey(
_In_ ULONG RelativeTo,
_In_ PCWSTR Path
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckRegistryKey(
_In_ ULONG RelativeTo,
_In_ PCWSTR Path
);
typedef _Function_class_(RTL_QUERY_REGISTRY_ROUTINE)
NTSTATUS NTAPI RTL_QUERY_REGISTRY_ROUTINE(
_In_z_ PCWSTR ValueName,
_In_ ULONG ValueType,
_In_ PVOID ValueData,
_In_ ULONG ValueLength,
_In_opt_ PVOID Context,
_In_opt_ PVOID EntryContext
);
typedef RTL_QUERY_REGISTRY_ROUTINE *PRTL_QUERY_REGISTRY_ROUTINE;
typedef struct _RTL_QUERY_REGISTRY_TABLE
{
PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
ULONG Flags;
PWSTR Name;
PVOID EntryContext;
ULONG DefaultType;
PVOID DefaultData;
ULONG DefaultLength;
} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;
#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001
#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002
#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004
#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008
#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010
#define RTL_QUERY_REGISTRY_DIRECT 0x00000020
#define RTL_QUERY_REGISTRY_DELETE 0x00000040
#define RTL_QUERY_REGISTRY_NOSTRING 0x00000080 // deprecated
#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100
#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT 24
#define RTL_QUERY_REGISTRY_TYPECHECK_MASK (0xff << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT)
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryRegistryValues(
_In_ ULONG RelativeTo,
_In_ PCWSTR Path,
_Inout_ _At_(*(*QueryTable).EntryContext, _Pre_unknown_) PRTL_QUERY_REGISTRY_TABLE QueryTable,
_In_opt_ PVOID Context,
_In_opt_ PVOID Environment
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryRegistryValuesEx(
_In_ ULONG RelativeTo,
_In_ PCWSTR Path,
_Inout_ _At_(*(*QueryTable).EntryContext, _Pre_unknown_) PRTL_QUERY_REGISTRY_TABLE QueryTable,
_In_opt_ PVOID Context,
_In_opt_ PVOID Environment
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS4)
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryRegistryValueWithFallback(
_In_opt_ HANDLE PrimaryHandle,
_In_opt_ HANDLE FallbackHandle,
_In_ PCUNICODE_STRING ValueName,
_In_ ULONG ValueLength,
_Out_opt_ PULONG ValueType,
_Out_writes_bytes_to_(ValueLength, *ResultLength) PVOID ValueData,
_Out_range_(<= , ValueLength) PULONG ResultLength
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS4
NTSYSAPI
NTSTATUS
NTAPI
RtlWriteRegistryValue(
_In_ ULONG RelativeTo,
_In_ PCWSTR Path,
_In_z_ PCWSTR ValueName,
_In_ ULONG ValueType,
_In_ PVOID ValueData,
_In_ ULONG ValueLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteRegistryValue(
_In_ ULONG RelativeTo,
_In_ PCWSTR Path,
_In_z_ PCWSTR ValueName
);
//
// Thread profiling
//
// rev
/**
* The RtlEnableThreadProfiling routine enables thread profiling on the specified thread.
*
* \param ThreadHandle The handle to the thread on which you want to enable profiling. This must be the current thread.
* \param Flags To receive thread profiling data such as context switch count, set this parameter to THREAD_PROFILING_FLAG_DISPATCH; otherwise, set to 0.
* \param HardwareCounters To receive hardware performance counter data, set this parameter to a bitmask that identifies the hardware counters to collect.
* \param PerformanceDataHandle An opaque handle that you use when calling the RtlReadThreadProfilingData and RtlDisableThreadProfiling functions.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-enablethreadprofiling
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlEnableThreadProfiling(
_In_ HANDLE ThreadHandle,
_In_ ULONG Flags,
_In_ ULONG64 HardwareCounters,
_Out_ PVOID *PerformanceDataHandle
);
// rev
/**
* The RtlDisableThreadProfiling routine disables thread profiling.
*
* \param PerformanceDataHandle The handle that the RtlEnableThreadProfiling function returned.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-querythreadprofiling
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlDisableThreadProfiling(
_In_ PVOID PerformanceDataHandle
);
// rev
/**
* The RtlQueryThreadProfiling routine determines whether thread profiling is enabled for the specified thread.
*
* \param ThreadHandle The handle to the thread on which you want to enable profiling. This must be the current thread.
* \param Enabled Is TRUE if thread profiling is enabled for the specified thread; otherwise, FALSE.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-querythreadprofiling
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryThreadProfiling(
_In_ HANDLE ThreadHandle,
_Out_ PBOOLEAN Enabled
);
// rev
/**
* The RtlReadThreadProfilingData routine reads the specified profiling data associated with the thread.
*
* \param PerformanceDataHandle The handle that the RtlEnableThreadProfiling function returned.
* \param Flags One or more flags set when you called the RtlEnableThreadProfiling function that specify the counter data to read.
* \param PerformanceData A PERFORMANCE_DATA structure that contains the thread profiling and hardware counter data.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-readthreadprofilingdata
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlReadThreadProfilingData(
_In_ HANDLE PerformanceDataHandle,
_In_ ULONG Flags,
_Out_ PPERFORMANCE_DATA PerformanceData
);
//
// WOW64
//
NTSYSAPI
NTSTATUS
NTAPI
RtlGetNativeSystemInformation(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_In_ PVOID NativeSystemInformation,
_In_ ULONG InformationLength,
_Out_opt_ PULONG ReturnLength
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
NtWow64GetNativeSystemInformation(
_In_ SYSTEM_INFORMATION_CLASS SystemInformationClass,
_In_ PVOID NativeSystemInformation,
_In_ ULONG InformationLength,
_Out_opt_ PULONG ReturnLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlQueueApcWow64Thread(
_In_ HANDLE ThreadHandle,
_In_ PPS_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcArgument1,
_In_opt_ PVOID ApcArgument2,
_In_opt_ PVOID ApcArgument3
);
/**
* The RtlWow64EnableFsRedirection routine enables or disables file system redirection for the calling thread.
*
* \param Wow64FsEnableRedirection If TRUE, requests redirection be enabled; if FALSE, requests redirection be disabled.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/wow64apiset/nf-wow64apiset-wow64enablewow64fsredirection
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64EnableFsRedirection(
_In_ BOOLEAN Wow64FsEnableRedirection
);
/**
* The RtlWow64EnableFsRedirectionEx routine enables or disables file system redirection for the calling thread.
*
* \param Wow64FsEnableRedirection If TRUE, requests redirection be enabled; if FALSE, requests redirection be disabled.
* \param OldFsRedirectionLevel The WOW64 file system redirection value. The system uses this parameter to store information
* necessary to revert (re-enable) file system redirection.
* \return NTSTATUS Successful or errant status.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/wow64apiset/nf-wow64apiset-wow64disablewow64fsredirection
*/
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64EnableFsRedirectionEx(
_In_ PVOID Wow64FsEnableRedirection,
_Out_ PVOID *OldFsRedirectionLevel
);
//
// Misc.
//
/**
* The RtlComputeCrc32 routine computes the CRC32 checksum for a buffer, allowing for incremental computation by providing a partial CRC value.
*
* \param PartialCrc The initial CRC32 value. Use 0 for a new computation, or the result of a previous call to continue CRC calculation over additional data.
* \param Buffer Pointer to the buffer containing the data to compute the CRC32 for.
* \param Length The length, in bytes, of the buffer.
* \return The computed CRC32 value.
*/
NTSYSAPI
ULONG32
NTAPI
RtlComputeCrc32(
_In_ ULONG32 PartialCrc,
_In_ PVOID Buffer,
_In_ ULONG Length
);
/**
* The RtlEncodePointer routine encodes the specified pointer. Encoded pointers can be used to provide another layer of protection for pointer values.
*
* \param Ptr The system pointer to be encoded.
* \return The function returns the encoded pointer.
* \sa https://learn.microsoft.com/en-us/previous-versions/bb432254(v=vs.85)
*/
_Ret_maybenull_
NTSYSAPI
PVOID
NTAPI
RtlEncodePointer(
_In_opt_ PVOID Ptr
);
/**
* The RtlDecodePointer routine decodes a pointer that was previously encoded with RtlEncodePointer.
*
* \param Ptr The system pointer to be decoded.
* \return The function returns the decoded pointer.
* \sa https://learn.microsoft.com/en-us/previous-versions/bb432242(v=vs.85)
*/
_Ret_maybenull_
NTSYSAPI
PVOID
NTAPI
RtlDecodePointer(
_In_opt_ PVOID Ptr
);
/**
* The RtlEncodeSystemPointer routine encodes the specified pointer with a system-specific value.
* Encoded pointers can be used to provide another layer of protection for pointer values.
*
* \param Ptr The system pointer to be encoded.
* \return The function returns the encoded pointer.
* \sa https://learn.microsoft.com/en-us/previous-versions/bb432255(v=vs.85)
*/
_Ret_maybenull_
NTSYSAPI
PVOID
NTAPI
RtlEncodeSystemPointer(
_In_opt_ PVOID Ptr
);
/**
* The RtlDecodeSystemPointer routine decodes a pointer that was previously encoded with RtlEncodeSystemPointer.
*
* \param Ptr The pointer to be decoded.
* \return The function returns the decoded pointer.
* \sa https://learn.microsoft.com/en-us/previous-versions/bb432243(v=vs.85)
*/
_Ret_maybenull_
NTSYSAPI
PVOID
NTAPI
RtlDecodeSystemPointer(
_In_opt_ PVOID Ptr
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
// rev
/**
* The RtlEncodeRemotePointer routine encodes the specified pointer of the specified process.
* Encoded pointers can be used to provide another layer of protection for pointer values.
*
* \param ProcessHandle Handle to the remote process that owns the pointer.
* \param Pointer The pointer to be encoded.
* \param EncodedPointer The encoded pointer.
* \return HRESULT Successful or errant status.
* \sa https://learn.microsoft.com/en-us/previous-versions/dn877135(v=vs.85)
*/
NTSYSAPI
HRESULT
NTAPI
RtlEncodeRemotePointer(
_In_ HANDLE ProcessHandle,
_In_opt_ PVOID Pointer,
_Out_ PVOID *EncodedPointer
);
// rev
/**
* The RtlDecodeRemotePointer routine decodes a pointer in a specified process that was previously
* encoded with RtlEncodePointer or RtlEncodeRemotePointer.
*
* \param ProcessHandle Handle to the remote process that owns the pointer.
* \param Pointer The pointer to be decoded.
* \param DecodedPointer The decoded pointer.
* \return HRESULT Successful or errant status.
* \sa https://learn.microsoft.com/en-us/previous-versions/dn877133(v=vs.85)
*/
NTSYSAPI
HRESULT
NTAPI
RtlDecodeRemotePointer(
_In_ HANDLE ProcessHandle,
_In_opt_ PVOID Pointer,
_Out_ PVOID *DecodedPointer
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
// rev
/**
* The RtlIsProcessorFeaturePresent routine determines whether the specified processor feature is supported by the current computer.
*
* \param ProcessorFeature The processor feature to be tested.
* \return If the feature is supported, the return value is a nonzero value.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent
*/
NTSYSAPI
BOOLEAN
NTAPI
RtlIsProcessorFeaturePresent(
_In_ ULONG ProcessorFeature
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
// rev
/**
* The RtlGetCurrentProcessorNumber routine retrieves the number of the processor the current thread was running
* on during the call to this function.
*
* \return The function returns the current processor number.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocessornumber
*/
NTSYSAPI
ULONG
NTAPI
RtlGetCurrentProcessorNumber(
VOID
);
// rev
/**
* The RtlGetCurrentProcessorNumberEx routine retrieves the processor group and number of the logical processor
* in which the calling thread is running.
*
* \param ProcessorNumber A pointer to a PROCESSOR_NUMBER structure that receives the processor group and number
* of the logical processor the calling thread is running.
* \return This function does not return a value.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocessornumberex
*/
NTSYSAPI
VOID
NTAPI
RtlGetCurrentProcessorNumberEx(
_Out_ PPROCESSOR_NUMBER ProcessorNumber
);
//
// Stack support
//
NTSYSAPI
VOID
NTAPI
RtlPushFrame(
_In_ PTEB_ACTIVE_FRAME Frame
);
NTSYSAPI
VOID
NTAPI
RtlPopFrame(
_In_ PTEB_ACTIVE_FRAME Frame
);
NTSYSAPI
PTEB_ACTIVE_FRAME
NTAPI
RtlGetFrame(
VOID
);
#define RTL_WALK_USER_MODE_STACK 0x00000001
#define RTL_WALK_KERNEL_STACK 0x00000002
#define RTL_WALK_USER_KERNEL_STACK 0x00000003
#define RTL_WALK_VALID_FLAGS 0x00000006
#define RTL_STACK_WALKING_MODE_FRAMES_TO_SKIP_SHIFT 0x00000008
// private
NTSYSAPI
ULONG
NTAPI
RtlWalkFrameChain(
_Out_writes_(Count - (Flags >> RTL_STACK_WALKING_MODE_FRAMES_TO_SKIP_SHIFT)) PVOID *Callers,
_In_ ULONG Count,
_In_ ULONG Flags
);
// rev
DECLSPEC_DEPRECATED
NTSYSAPI
VOID
NTAPI
RtlGetCallersAddress( // Use the intrinsic _ReturnAddress instead.
_Out_ PVOID *CallersAddress,
_Out_ PVOID *CallersCaller
);
/**
* The RtlGetEnabledExtendedFeatures routine returns a mask of extended processor features that are enabled by the system.
*
* \param FeatureMask A 64-bit feature mask. This parameter indicates a set of extended processor features for which the caller
* requests information about whether the features are enabled.
* \return A 64-bitmask of enabled extended processor features. The routine calculates this mask as the intersection (bitwise AND)
* between all enabled features and the value of the FeatureMask parameter.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntddk/nf-ntddk-rtlgetenabledextendedfeatures
*/
NTSYSAPI
ULONG64
NTAPI
RtlGetEnabledExtendedFeatures(
_In_ ULONG64 FeatureMask
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS4)
// msdn
NTSYSAPI
ULONG64
NTAPI
RtlGetEnabledExtendedAndSupervisorFeatures(
_In_ ULONG64 FeatureMask
);
// msdn
_Ret_maybenull_
_Success_(return != NULL)
NTSYSAPI
PVOID
NTAPI
RtlLocateSupervisorFeature(
_In_ PXSAVE_AREA_HEADER XStateHeader,
_In_range_(XSTATE_AVX, MAXIMUM_XSTATE_FEATURES - 1) ULONG FeatureId,
_Out_opt_ PULONG Length
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS4
#define ELEVATION_FLAG_TOKEN_CHECKS 0x00000001
#define ELEVATION_FLAG_VIRTUALIZATION 0x00000002
#define ELEVATION_FLAG_SHORTCUT_REDIR 0x00000004
#define ELEVATION_FLAG_NO_SIGNATURE_CHECK 0x00000008
// private
typedef struct _RTL_ELEVATION_FLAGS
{
union
{
ULONG Flags;
struct
{
ULONG ElevationEnabled : 1;
ULONG VirtualizationEnabled : 1;
ULONG InstallerDetectEnabled : 1;
ULONG AdminApprovalModeType : 2;
ULONG ReservedBits : 27;
};
};
} RTL_ELEVATION_FLAGS, *PRTL_ELEVATION_FLAGS;
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryElevationFlags(
_Out_ PRTL_ELEVATION_FLAGS Flags
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlRegisterThreadWithCsrss(
VOID
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlLockCurrentThread(
VOID
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlUnlockCurrentThread(
VOID
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlLockModuleSection(
_In_ PVOID Address
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlUnlockModuleSection(
_In_ PVOID Address
);
#define RTL_UNLOAD_EVENT_TRACE_NUMBER 64
// private
/**
* The RTL_UNLOAD_EVENT_TRACE structure contains information about modules unloaded by the current process.
*
* \sa https://learn.microsoft.com/en-us/windows/win32/devnotes/rtlgetunloadeventtrace
*/
typedef struct _RTL_UNLOAD_EVENT_TRACE
{
PVOID BaseAddress; // Base address of dll
SIZE_T SizeOfImage; // Size of image
ULONG Sequence; // Sequence number for this event
ULONG TimeDateStamp; // Time and date of image
ULONG CheckSum; // Image checksum
WCHAR ImageName[32]; // Image name
ULONG Version[2];
} RTL_UNLOAD_EVENT_TRACE, *PRTL_UNLOAD_EVENT_TRACE;
typedef struct _RTL_UNLOAD_EVENT_TRACE32
{
ULONG BaseAddress; // Base address of dll
ULONG SizeOfImage; // Size of image
ULONG Sequence; // Sequence number for this event
ULONG TimeDateStamp; // Time and date of image
ULONG CheckSum; // Image checksum
WCHAR ImageName[32]; // Image name
ULONG Version[2];
} RTL_UNLOAD_EVENT_TRACE32, *PRTL_UNLOAD_EVENT_TRACE32;
/**
* The RtlGetUnloadEventTrace routine enables the dump code to get the unloaded module information from Ntdll.dll for storage in the minidump.
*
* \return A pointer to an array of unload events.
* \sa https://learn.microsoft.com/en-us/windows/win32/devnotes/rtlgetunloadeventtrace
*/
NTSYSAPI
PRTL_UNLOAD_EVENT_TRACE
NTAPI
RtlGetUnloadEventTrace(
VOID
);
/**
* The RtlGetUnloadEventTraceEx routine retrieves the size and location of the dynamically unloaded module list for the current process.
*
* \param ElementSize A pointer to a variable that contains the size of an element in the list.
* \param ElementCount A pointer to a variable that contains the number of elements in the list.
* \param EventTrace A pointer to an array of RTL_UNLOAD_EVENT_TRACE structures.
* \return A pointer to an array of unload events.
* \sa https://learn.microsoft.com/en-us/windows/win32/devnotes/rtlgetunloadeventtraceex
*/
NTSYSAPI
PRTL_UNLOAD_EVENT_TRACE
NTAPI
RtlGetUnloadEventTraceEx(
_Out_ PULONG *ElementSize,
_Out_ PULONG *ElementCount,
_Out_ PVOID *EventTrace // works across all processes
);
/**
* The RtlCaptureStackBackTrace routine captures a stack trace by walking the stack and recording the information for each frame.
*
* \param FramesToSkip Number of frames to skip from the start (current call point) of the back trace.
* \param FramesToCapture Number of frames to be captured.
* \param BackTrace Caller-allocated array in which pointers to the return addresses captured from the current stack trace are returned.
* \param BackTraceHash Optional value that can be used to organize hash tables. This hash value is calculated based on the values of the pointers returned in the BackTrace array. Two identical stack traces will generate identical hash values.
* \return The number of captured frames.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlcapturestackbacktrace
*/
_Success_(return != 0)
NTSYSAPI
USHORT
NTAPI
RtlCaptureStackBackTrace(
_In_ ULONG FramesToSkip,
_In_ ULONG FramesToCapture,
_Out_writes_to_(FramesToCapture,return) PVOID* BackTrace,
_Out_opt_ PULONG BackTraceHash
);
/**
* The RtlCaptureContext routine retrieves a context record in the context of the caller.
*
* \param ContextRecord A pointer to a CONTEXT structure.
* \return This function does not return a value.
* \sa https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/ntifs/nf-ntifs-rtlcapturecontext
*/
NTSYSAPI
VOID
NTAPI
RtlCaptureContext(
_Out_ PCONTEXT ContextRecord
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_20H1)
NTSYSAPI
VOID
NTAPI
RtlCaptureContext2(
_Inout_ PCONTEXT ContextRecord
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_20H1
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
NTSYSAPI
VOID
STDAPIVCALLTYPE
RtlRestoreContext(
_In_ PCONTEXT ContextRecord,
_In_opt_ struct _EXCEPTION_RECORD* ExceptionRecord
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
NTSYSAPI
VOID
NTAPI
RtlUnwind(
_In_opt_ PVOID TargetFrame,
_In_opt_ PVOID TargetIp,
_In_opt_ PEXCEPTION_RECORD ExceptionRecord,
_In_ PVOID ReturnValue
);
#if defined(_M_AMD64) && defined(_M_ARM64EC)
NTSYSAPI
BOOLEAN
STDAPIVCALLTYPE
RtlAddFunctionTable(
_In_reads_(EntryCount) PRUNTIME_FUNCTION FunctionTable,
_In_ ULONG EntryCount,
_In_ ULONG64 BaseAddress
);
NTSYSAPI
BOOLEAN
STDAPIVCALLTYPE
RtlDeleteFunctionTable(
_In_ PRUNTIME_FUNCTION FunctionTable
);
NTSYSAPI
BOOLEAN
STDAPIVCALLTYPE
RtlInstallFunctionTableCallback(
_In_ ULONG64 TableIdentifier,
_In_ ULONG64 BaseAddress,
_In_ ULONG Length,
_In_ PGET_RUNTIME_FUNCTION_CALLBACK Callback,
_In_opt_ PVOID Context,
_In_opt_ PCWSTR OutOfProcessCallbackDll
);
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
NTSYSAPI
ULONG
NTAPI
RtlAddGrowableFunctionTable(
_Out_ PVOID* DynamicTable,
_In_reads_(MaximumEntryCount) PRUNTIME_FUNCTION FunctionTable,
_In_ ULONG EntryCount,
_In_ ULONG MaximumEntryCount,
_In_ ULONG_PTR RangeBase,
_In_ ULONG_PTR RangeEnd
);
NTSYSAPI
VOID
NTAPI
RtlGrowFunctionTable(
_Inout_ PVOID DynamicTable,
_In_ ULONG NewEntryCount
);
NTSYSAPI
VOID
NTAPI
RtlDeleteGrowableFunctionTable(
_In_ PVOID DynamicTable
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#endif // _M_AMD64 && _M_ARM64EC
#if defined(_M_ARM64EC)
NTSYSAPI
BOOLEAN
NTAPI
RtlIsEcCode(
_In_ ULONG64 CodePointer
);
#endif // _M_ARM64EC
/**
* The RtlLookupFunctionEntry routine searches the active function tables for an entry that corresponds to the specified PC value.
*
* \param ControlPc The virtual address of an instruction bundle within the function.
* \param ImageBase The base address of module to which the function belongs.
* \return The entry in the function table for the specified PC.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtllookupfunctionentry
*/
// NTSYSAPI
// PRUNTIME_FUNCTION
// NTAPI
// RtlLookupFunctionEntry(
// _In_ ULONG_PTR ControlPc,
// _Out_ PULONG_PTR ImageBase,
// _Inout_opt_ PUNWIND_HISTORY_TABLE HistoryTable
// );
/**
* The RtlPcToFileHeader routine retrieves the base address of the image that contains the specified PC value.
*
* \param PcValue The PC value. The function searches all modules mapped into the address space of the calling process for a module that contains this value.
* \param BaseOfImage The base address of the image containing the PC value. This value must be added to any relative addresses in the headers to locate the image.
* \return If the PC value is found, returns the base address of the image that contains the PC value. If no image contains the PC value, the function returns NULL.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-rtlpctofileheader
*/
NTSYSAPI
PVOID
NTAPI
RtlPcToFileHeader(
_In_ PVOID PcValue,
_Out_ PVOID* BaseOfImage
);
// rev
/**
* The RtlQueryPerformanceCounter routine retrieves the current value of the performance counter, which is a high resolution (<1us) time stamp that can be used for time-interval measurements.
*
* \param PerformanceCounter A pointer to a variable that receives the current performance-counter value, in counts.
* \return Returns TRUE if the function succeeds, otherwise FALSE. On systems that run Windows XP or later, the function will always succeed and will thus never return zero.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancecounter
*/
NTSYSAPI
LOGICAL
NTAPI
RtlQueryPerformanceCounter(
_Out_ PLARGE_INTEGER PerformanceCounter
);
// rev
/**
* The RtlQueryPerformanceFrequency routine retrieves the frequency of the performance counter. The frequency of the performance counter is fixed at system boot and is consistent across all processors.
* Therefore, the frequency need only be queried upon application initialization, and the result can be cached.
*
* \param PerformanceFrequency A pointer to a variable that receives the current performance-counter frequency, in counts per second.
* \return Returns TRUE if the function succeeds, otherwise FALSE. On systems that run Windows XP or later, the function will always succeed and will thus never return zero.
* \sa https://learn.microsoft.com/en-us/windows/win32/api/profileapi/nf-profileapi-queryperformancefrequency
*/
NTSYSAPI
LOGICAL
NTAPI
RtlQueryPerformanceFrequency(
_Out_ PLARGE_INTEGER PerformanceFrequency
);
//
// Image Mitigation
//
// rev
typedef enum _IMAGE_MITIGATION_POLICY
{
ImageDepPolicy, // RTL_IMAGE_MITIGATION_DEP_POLICY
ImageAslrPolicy, // RTL_IMAGE_MITIGATION_ASLR_POLICY
ImageDynamicCodePolicy, // RTL_IMAGE_MITIGATION_DYNAMIC_CODE_POLICY
ImageStrictHandleCheckPolicy, // RTL_IMAGE_MITIGATION_STRICT_HANDLE_CHECK_POLICY
ImageSystemCallDisablePolicy, // RTL_IMAGE_MITIGATION_SYSTEM_CALL_DISABLE_POLICY
ImageMitigationOptionsMask,
ImageExtensionPointDisablePolicy, // RTL_IMAGE_MITIGATION_EXTENSION_POINT_DISABLE_POLICY
ImageControlFlowGuardPolicy, // RTL_IMAGE_MITIGATION_CONTROL_FLOW_GUARD_POLICY
ImageSignaturePolicy, // RTL_IMAGE_MITIGATION_BINARY_SIGNATURE_POLICY
ImageFontDisablePolicy, // RTL_IMAGE_MITIGATION_FONT_DISABLE_POLICY
ImageImageLoadPolicy, // RTL_IMAGE_MITIGATION_IMAGE_LOAD_POLICY
ImagePayloadRestrictionPolicy, // RTL_IMAGE_MITIGATION_PAYLOAD_RESTRICTION_POLICY
ImageChildProcessPolicy, // RTL_IMAGE_MITIGATION_CHILD_PROCESS_POLICY
ImageSehopPolicy, // RTL_IMAGE_MITIGATION_SEHOP_POLICY
ImageHeapPolicy, // RTL_IMAGE_MITIGATION_HEAP_POLICY
ImageUserShadowStackPolicy, // RTL_IMAGE_MITIGATION_USER_SHADOW_STACK_POLICY
ImageRedirectionTrustPolicy, // RTL_IMAGE_MITIGATION_REDIRECTION_TRUST_POLICY
ImageUserPointerAuthPolicy, // RTL_IMAGE_MITIGATION_USER_POINTER_AUTH_POLICY
MaxImageMitigationPolicy
} IMAGE_MITIGATION_POLICY;
// rev
typedef union _RTL_IMAGE_MITIGATION_POLICY
{
struct
{
ULONG64 AuditState : 2;
ULONG64 AuditFlag : 1;
ULONG64 EnableAdditionalAuditingOption : 1;
ULONG64 Reserved : 60;
};
struct
{
ULONG64 PolicyState : 2;
ULONG64 AlwaysInherit : 1;
ULONG64 EnableAdditionalPolicyOption : 1;
ULONG64 AuditReserved : 60;
};
} RTL_IMAGE_MITIGATION_POLICY, *PRTL_IMAGE_MITIGATION_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_DEP_POLICY
{
RTL_IMAGE_MITIGATION_POLICY Dep;
} RTL_IMAGE_MITIGATION_DEP_POLICY, *PRTL_IMAGE_MITIGATION_DEP_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_ASLR_POLICY
{
RTL_IMAGE_MITIGATION_POLICY ForceRelocateImages;
RTL_IMAGE_MITIGATION_POLICY BottomUpRandomization;
RTL_IMAGE_MITIGATION_POLICY HighEntropyRandomization;
} RTL_IMAGE_MITIGATION_ASLR_POLICY, *PRTL_IMAGE_MITIGATION_ASLR_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_DYNAMIC_CODE_POLICY
{
RTL_IMAGE_MITIGATION_POLICY BlockDynamicCode;
} RTL_IMAGE_MITIGATION_DYNAMIC_CODE_POLICY, *PRTL_IMAGE_MITIGATION_DYNAMIC_CODE_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_STRICT_HANDLE_CHECK_POLICY
{
RTL_IMAGE_MITIGATION_POLICY StrictHandleChecks;
} RTL_IMAGE_MITIGATION_STRICT_HANDLE_CHECK_POLICY, *PRTL_IMAGE_MITIGATION_STRICT_HANDLE_CHECK_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_SYSTEM_CALL_DISABLE_POLICY
{
RTL_IMAGE_MITIGATION_POLICY BlockWin32kSystemCalls;
} RTL_IMAGE_MITIGATION_SYSTEM_CALL_DISABLE_POLICY, *PRTL_IMAGE_MITIGATION_SYSTEM_CALL_DISABLE_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_EXTENSION_POINT_DISABLE_POLICY
{
RTL_IMAGE_MITIGATION_POLICY DisableExtensionPoints;
} RTL_IMAGE_MITIGATION_EXTENSION_POINT_DISABLE_POLICY, *PRTL_IMAGE_MITIGATION_EXTENSION_POINT_DISABLE_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_CONTROL_FLOW_GUARD_POLICY
{
RTL_IMAGE_MITIGATION_POLICY ControlFlowGuard;
RTL_IMAGE_MITIGATION_POLICY StrictControlFlowGuard;
} RTL_IMAGE_MITIGATION_CONTROL_FLOW_GUARD_POLICY, *PRTL_IMAGE_MITIGATION_CONTROL_FLOW_GUARD_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_BINARY_SIGNATURE_POLICY
{
RTL_IMAGE_MITIGATION_POLICY BlockNonMicrosoftSignedBinaries;
RTL_IMAGE_MITIGATION_POLICY EnforceSigningOnModuleDependencies;
} RTL_IMAGE_MITIGATION_BINARY_SIGNATURE_POLICY, *PRTL_IMAGE_MITIGATION_BINARY_SIGNATURE_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_FONT_DISABLE_POLICY
{
RTL_IMAGE_MITIGATION_POLICY DisableNonSystemFonts;
} RTL_IMAGE_MITIGATION_FONT_DISABLE_POLICY, *PRTL_IMAGE_MITIGATION_FONT_DISABLE_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_IMAGE_LOAD_POLICY
{
RTL_IMAGE_MITIGATION_POLICY BlockRemoteImageLoads;
RTL_IMAGE_MITIGATION_POLICY BlockLowLabelImageLoads;
RTL_IMAGE_MITIGATION_POLICY PreferSystem32;
} RTL_IMAGE_MITIGATION_IMAGE_LOAD_POLICY, *PRTL_IMAGE_MITIGATION_IMAGE_LOAD_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_PAYLOAD_RESTRICTION_POLICY
{
RTL_IMAGE_MITIGATION_POLICY EnableExportAddressFilter;
RTL_IMAGE_MITIGATION_POLICY EnableExportAddressFilterPlus;
RTL_IMAGE_MITIGATION_POLICY EnableImportAddressFilter;
RTL_IMAGE_MITIGATION_POLICY EnableRopStackPivot;
RTL_IMAGE_MITIGATION_POLICY EnableRopCallerCheck;
RTL_IMAGE_MITIGATION_POLICY EnableRopSimExec;
WCHAR EafPlusModuleList[512]; // 19H1
} RTL_IMAGE_MITIGATION_PAYLOAD_RESTRICTION_POLICY, *PRTL_IMAGE_MITIGATION_PAYLOAD_RESTRICTION_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_CHILD_PROCESS_POLICY
{
RTL_IMAGE_MITIGATION_POLICY DisallowChildProcessCreation;
} RTL_IMAGE_MITIGATION_CHILD_PROCESS_POLICY, *PRTL_IMAGE_MITIGATION_CHILD_PROCESS_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_SEHOP_POLICY
{
RTL_IMAGE_MITIGATION_POLICY Sehop;
} RTL_IMAGE_MITIGATION_SEHOP_POLICY, *PRTL_IMAGE_MITIGATION_SEHOP_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_HEAP_POLICY
{
RTL_IMAGE_MITIGATION_POLICY TerminateOnHeapErrors;
} RTL_IMAGE_MITIGATION_HEAP_POLICY, *PRTL_IMAGE_MITIGATION_HEAP_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_USER_SHADOW_STACK_POLICY
{
RTL_IMAGE_MITIGATION_POLICY UserShadowStack;
RTL_IMAGE_MITIGATION_POLICY SetContextIpValidation;
RTL_IMAGE_MITIGATION_POLICY BlockNonCetBinaries;
} RTL_IMAGE_MITIGATION_USER_SHADOW_STACK_POLICY, *PRTL_IMAGE_MITIGATION_USER_SHADOW_STACK_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_REDIRECTION_TRUST_POLICY
{
RTL_IMAGE_MITIGATION_POLICY BlockUntrustedRedirections;
} RTL_IMAGE_MITIGATION_REDIRECTION_TRUST_POLICY, *PRTL_IMAGE_MITIGATION_REDIRECTION_TRUST_POLICY;
// rev
typedef struct _RTL_IMAGE_MITIGATION_USER_POINTER_AUTH_POLICY
{
RTL_IMAGE_MITIGATION_POLICY PointerAuthUserIp;
} RTL_IMAGE_MITIGATION_USER_POINTER_AUTH_POLICY, *PRTL_IMAGE_MITIGATION_USER_POINTER_AUTH_POLICY;
// rev
typedef enum _RTL_IMAGE_MITIGATION_OPTION_STATE
{
RtlMitigationOptionStateNotConfigured,
RtlMitigationOptionStateOn,
RtlMitigationOptionStateOff,
RtlMitigationOptionStateForce,
RtlMitigationOptionStateOption
} RTL_IMAGE_MITIGATION_OPTION_STATE;
#define RTL_IMAGE_MITIGATION_OPTION_STATEMASK 3UL
#define RTL_IMAGE_MITIGATION_OPTION_FORCEMASK 4UL
#define RTL_IMAGE_MITIGATION_OPTION_OPTIONMASK 8UL
// rev from PROCESS_MITIGATION_FLAGS
#define RTL_IMAGE_MITIGATION_FLAG_RESET 0x1
#define RTL_IMAGE_MITIGATION_FLAG_REMOVE 0x2
#define RTL_IMAGE_MITIGATION_FLAG_OSDEFAULT 0x4
#define RTL_IMAGE_MITIGATION_FLAG_AUDIT 0x8
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS3)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryImageMitigationPolicy(
_In_opt_ PCWSTR ImagePath, // NULL for system-wide defaults
_In_ IMAGE_MITIGATION_POLICY Policy,
_In_ ULONG Flags,
_Inout_ PVOID Buffer,
_In_ ULONG BufferSize
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSetImageMitigationPolicy(
_In_opt_ PCWSTR ImagePath, // NULL for system-wide defaults
_In_ IMAGE_MITIGATION_POLICY Policy,
_In_ ULONG Flags,
_Inout_ PVOID Buffer,
_In_ ULONG BufferSize
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS3
//
// Session
//
// rev
NTSYSAPI
ULONG
NTAPI
RtlGetCurrentServiceSessionId(
VOID
);
// private
NTSYSAPI
ULONG
NTAPI
RtlGetActiveConsoleId(
VOID
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS1)
// private
NTSYSAPI
LONGLONG
NTAPI
RtlGetConsoleSessionForegroundProcessId(
VOID
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS1
//
// Appcontainer
//
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS2)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetTokenNamedObjectPath(
_In_ HANDLE TokenHandle,
_In_opt_ PSID Sid,
_Out_ PUNICODE_STRING ObjectPath // RtlFreeUnicodeString
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS2
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetAppContainerNamedObjectPath(
_In_opt_ HANDLE TokenHandle,
_In_opt_ PSID AppContainerSid,
_In_ BOOLEAN RelativePath,
_Out_ PUNICODE_STRING ObjectPath // RtlFreeUnicodeString
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetAppContainerParent(
_In_ PSID AppContainerSid,
_Out_ PSID* AppContainerSidParent // RtlFreeSid
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckSandboxedToken(
_In_opt_ HANDLE TokenHandle,
_Out_ PBOOLEAN IsSandboxed
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckTokenCapability(
_In_opt_ HANDLE TokenHandle,
_In_ PSID CapabilitySidToCheck,
_Out_ PBOOLEAN HasCapability
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCapabilityCheck(
_In_opt_ HANDLE TokenHandle,
_In_ PCUNICODE_STRING CapabilityName,
_Out_ PBOOLEAN HasCapability
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckTokenMembership(
_In_opt_ HANDLE TokenHandle,
_In_ PSID SidToCheck,
_Out_ PBOOLEAN IsMember
);
// RtlCheckTokenMembershipEx Flags
#define CTMF_INCLUDE_APPCONTAINER 0x00000001UL
#define CTMF_INCLUDE_LPAC 0x00000002UL
#define CTMF_VALID_FLAGS (CTMF_INCLUDE_APPCONTAINER | CTMF_INCLUDE_LPAC)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckTokenMembershipEx(
_In_opt_ HANDLE TokenHandle,
_In_ PSID SidToCheck,
_In_ ULONG Flags, // CTMF_VALID_FLAGS
_Out_ PBOOLEAN IsMember
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS4)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryTokenHostIdAsUlong64(
_In_ HANDLE TokenHandle,
_Out_ PULONG64 HostId // (WIN://PKGHOSTID)
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS4
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsParentOfChildAppContainer(
_In_ PSID ParentAppContainerSid,
_In_ PSID ChildAppContainerSid
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlIsApiSetImplemented(
_In_z_ PCSTR ApiSetName
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsCapabilitySid(
_In_ PSID Sid
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsPackageSid(
_In_ PSID Sid
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsValidProcessTrustLabelSid(
_In_ PSID Sid
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
typedef enum _APPCONTAINER_SID_TYPE
{
NotAppContainerSidType,
ChildAppContainerSidType,
ParentAppContainerSidType,
InvalidAppContainerSidType,
MaxAppContainerSidType
} APPCONTAINER_SID_TYPE, *PAPPCONTAINER_SID_TYPE;
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetAppContainerSidType(
_In_ PSID AppContainerSid,
_Out_ PAPPCONTAINER_SID_TYPE AppContainerSidType
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
NTSYSAPI
NTSTATUS
NTAPI
RtlFlsAlloc(
_In_opt_ PFLS_CALLBACK_FUNCTION Callback,
_Out_ PULONG FlsIndex
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlFlsAllocEx(
_In_opt_ PFLS_CALLBACK_FUNCTION Callback,
_Out_ PULONG,
_Out_ PULONG FlsIndex
);
NTSYSAPI
NTSTATUS
NTAPI
RtlFlsFree(
_In_ ULONG FlsIndex
);
NTSYSAPI
NTSTATUS
NTAPI
RtlFlsGetValue(
_In_ ULONG FlsIndex,
_Out_ PVOID* FlsData
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_20H1)
NTSYSAPI
PVOID
NTAPI
RtlFlsGetValue2(
_In_ ULONG FlsIndex
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_20H1
NTSYSAPI
NTSTATUS
NTAPI
RtlFlsSetValue(
_In_ ULONG FlsIndex,
_In_opt_ PVOID FlsData
);
#define RTL_FLS_DATA_CLEANUP_PER_SLOT 1
#define RTL_FLS_DATA_CLEANUP_DEALLOCATE 2
NTSYSAPI
VOID
NTAPI
RtlProcessFlsData(
_In_ PVOID FlsData,
_In_ ULONG Flags
);
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlTlsAlloc(
_Out_ PULONG TlsIndex
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlTlsFree(
_In_ ULONG TlsIndex
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlTlsSetValue(
_In_ ULONG TlsIndex,
_In_opt_ PVOID TlsData
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
//
// State isolation
//
typedef enum _STATE_LOCATION_TYPE
{
LocationTypeRegistry,
LocationTypeFileSystem,
LocationTypeMaximum
} STATE_LOCATION_TYPE;
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS3)
// private
NTSYSAPI
BOOLEAN
NTAPI
RtlIsStateSeparationEnabled(
VOID
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlGetPersistedStateLocation(
_In_ PCWSTR SourceID,
_In_opt_ PCWSTR CustomValue,
_In_opt_ PCWSTR DefaultPath,
_In_ STATE_LOCATION_TYPE StateLocationType,
_Out_writes_bytes_to_opt_(BufferLengthIn, *BufferLengthOut) PWCHAR TargetPath,
_In_ ULONG BufferLengthIn,
_Out_opt_ PULONG BufferLengthOut
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS3
//
// Cloud Filters
//
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS3)
// msdn
NTSYSAPI
BOOLEAN
NTAPI
RtlIsCloudFilesPlaceholder(
_In_ ULONG FileAttributes,
_In_ ULONG ReparseTag
);
// msdn
NTSYSAPI
BOOLEAN
NTAPI
RtlIsPartialPlaceholder(
_In_ ULONG FileAttributes,
_In_ ULONG ReparseTag
);
// msdn
NTSYSAPI
NTSTATUS
NTAPI
RtlIsPartialPlaceholderFileHandle(
_In_ HANDLE FileHandle,
_Out_ PBOOLEAN IsPartialPlaceholder
);
// msdn
NTSYSAPI
NTSTATUS
NTAPI
RtlIsPartialPlaceholderFileInfo(
_In_ PVOID InfoBuffer,
_In_ FILE_INFORMATION_CLASS InfoClass,
_Out_ PBOOLEAN IsPartialPlaceholder
);
#undef PHCM_MAX
#define PHCM_APPLICATION_DEFAULT ((CHAR)0)
#define PHCM_DISGUISE_PLACEHOLDERS ((CHAR)1)
#define PHCM_EXPOSE_PLACEHOLDERS ((CHAR)2)
#define PHCM_MAX ((CHAR)2)
#define PHCM_ERROR_INVALID_PARAMETER ((CHAR)-1)
#define PHCM_ERROR_NO_TEB ((CHAR)-2)
NTSYSAPI
CHAR
NTAPI
RtlQueryThreadPlaceholderCompatibilityMode(
VOID
);
NTSYSAPI
CHAR
NTAPI
RtlSetThreadPlaceholderCompatibilityMode(
_In_ CHAR Mode
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS3
#undef PHCM_MAX
#define PHCM_DISGUISE_FULL_PLACEHOLDERS ((CHAR)3)
#define PHCM_MAX ((CHAR)3)
#define PHCM_ERROR_NO_PEB ((CHAR)-3)
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS4)
NTSYSAPI
CHAR
NTAPI
RtlQueryProcessPlaceholderCompatibilityMode(
VOID
);
NTSYSAPI
CHAR
NTAPI
RtlSetProcessPlaceholderCompatibilityMode(
_In_ CHAR Mode
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS4
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS2)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsNonEmptyDirectoryReparsePointAllowed(
_In_ ULONG ReparseTag
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS2
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlAppxIsFileOwnedByTrustedInstaller(
_In_ HANDLE FileHandle,
_Out_ PBOOLEAN IsFileOwnedByTrustedInstaller
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
// Windows Internals book
#define PSM_ACTIVATION_TOKEN_PACKAGED_APPLICATION 0x00000001UL // AppX package format
#define PSM_ACTIVATION_TOKEN_SHARED_ENTITY 0x00000002UL // Shared token, multiple binaries in the same package
#define PSM_ACTIVATION_TOKEN_FULL_TRUST 0x00000004UL // Trusted (Centennial), converted Win32 application
#define PSM_ACTIVATION_TOKEN_NATIVE_SERVICE 0x00000008UL // Packaged service created by SCM
//#define PSM_ACTIVATION_TOKEN_DEVELOPMENT_APP 0x00000010UL
#define PSM_ACTIVATION_TOKEN_MULTIPLE_INSTANCES_ALLOWED 0x00000010UL
#define PSM_ACTIVATION_TOKEN_BREAKAWAY_INHIBITED 0x00000020UL // Cannot create non-packaged child processes
#define PSM_ACTIVATION_TOKEN_RUNTIME_BROKER 0x00000040UL // rev
#define PSM_ACTIVATION_TOKEN_UNIVERSAL_CONSOLE 0x00000200UL // rev
#define PSM_ACTIVATION_TOKEN_WIN32ALACARTE_PROCESS 0x00010000UL // rev
// PackageOrigin appmodel.h
//#define PackageOrigin_Unknown 0
//#define PackageOrigin_Unsigned 1
//#define PackageOrigin_Inbox 2
//#define PackageOrigin_Store 3
//#define PackageOrigin_DeveloperUnsigned 4
//#define PackageOrigin_DeveloperSigned 5
//#define PackageOrigin_LineOfBusiness 6
#define PSMP_MINIMUM_SYSAPP_CLAIM_VALUES 2
#define PSMP_MAXIMUM_SYSAPP_CLAIM_VALUES 4
// private
typedef struct _PS_PKG_CLAIM
{
ULONG Flags; // PSM_ACTIVATION_TOKEN_*
ULONG Origin; // PackageOrigin
} PS_PKG_CLAIM, *PPS_PKG_CLAIM;
// private // WIN://BGKD
typedef enum _PSM_ACTIVATE_BACKGROUND_TYPE
{
PsmActNotBackground = 0,
PsmActMixedHost = 1,
PsmActPureHost = 2,
PsmActSystemHost = 3,
PsmActInvalidType = 4,
} PSM_ACTIVATE_BACKGROUND_TYPE;
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryPackageClaims(
_In_ HANDLE TokenHandle,
_Out_writes_bytes_to_opt_(*PackageSize, *PackageSize) PWSTR PackageFullName,
_Inout_opt_ PSIZE_T PackageSize,
_Out_writes_bytes_to_opt_(*AppIdSize, *AppIdSize) PWSTR AppId,
_Inout_opt_ PSIZE_T AppIdSize,
_Out_opt_ PGUID DynamicId,
_Out_opt_ PPS_PKG_CLAIM PkgClaim,
_Out_opt_ PULONG64 AttributesPresent
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryPackageIdentity(
_In_ HANDLE TokenHandle,
_Out_writes_bytes_to_(*PackageSize, *PackageSize) PWSTR PackageFullName,
_Inout_ PSIZE_T PackageSize,
_Out_writes_bytes_to_opt_(*AppIdSize, *AppIdSize) PWSTR AppId,
_Inout_opt_ PSIZE_T AppIdSize,
_Out_opt_ PBOOLEAN Packaged
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryPackageIdentityEx(
_In_ HANDLE TokenHandle,
_Out_writes_bytes_to_(*PackageSize, *PackageSize) PWSTR PackageFullName,
_Inout_ PSIZE_T PackageSize,
_Out_writes_bytes_to_opt_(*AppIdSize, *AppIdSize) PWSTR AppId,
_Inout_opt_ PSIZE_T AppIdSize,
_Out_opt_ PGUID DynamicId,
_Out_opt_ PULONG64 Flags
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
//
// Protected policies
//
#if (PHNT_VERSION >= PHNT_WINDOWS_8_1)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryProtectedPolicy(
_In_ PGUID PolicyGuid,
_Out_ PULONG_PTR PolicyValue
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSetProtectedPolicy(
_In_ PGUID PolicyGuid,
_In_ ULONG_PTR PolicyValue,
_Out_ PULONG_PTR OldPolicyValue
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8_1
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS1)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsEnclaveFeaturePresent(
_In_ ULONG FeatureMask
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS1
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
// private
NTSYSAPI
BOOLEAN
NTAPI
RtlIsMultiSessionSku(
VOID
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS1)
// private
NTSYSAPI
BOOLEAN
NTAPI
RtlIsMultiUsersInSessionSku(
VOID
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS1
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetSessionProperties(
_In_ ULONG SessionId,
_Out_ PULONG SharedUserSessionId
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
// private
typedef enum _RTL_BSD_ITEM_TYPE
{
RtlBsdItemVersionNumber, // qs: ULONG
RtlBsdItemProductType, // qs: NT_PRODUCT_TYPE (ULONG)
RtlBsdItemAabEnabled, // qs: BOOLEAN // AutoAdvancedBoot
RtlBsdItemAabTimeout, // qs: UCHAR // AdvancedBootMenuTimeout
RtlBsdItemBootGood, // qs: BOOLEAN // LastBootSucceeded
RtlBsdItemBootShutdown, // qs: BOOLEAN // LastBootShutdown
RtlBsdSleepInProgress, // qs: BOOLEAN // SleepInProgress
RtlBsdPowerTransition, // qs: RTL_BSD_DATA_POWER_TRANSITION
RtlBsdItemBootAttemptCount, // qs: UCHAR // BootAttemptCount
RtlBsdItemBootCheckpoint, // qs: UCHAR // LastBootCheckpoint
RtlBsdItemBootId, // qs: ULONG (USER_SHARED_DATA->BootId) // 10
RtlBsdItemShutdownBootId, // qs: ULONG
RtlBsdItemReportedAbnormalShutdownBootId, // qs: ULONG
RtlBsdItemErrorInfo, // qs: RTL_BSD_DATA_ERROR_INFO
RtlBsdItemPowerButtonPressInfo, // qs: RTL_BSD_POWER_BUTTON_PRESS_INFO
RtlBsdItemChecksum, // q: UCHAR
RtlBsdPowerTransitionExtension, // qs: RTL_BSD_DATA_POWER_TRANSITION_EXTENSION
RtlBsdItemFeatureConfigurationState, // qs: ULONG
RtlBsdItemRevocationListInfo, // qs: RTL_BSD_ITEM_REVOCATION_LIST // 24H2
RtlBsdItemMax
} RTL_BSD_ITEM_TYPE;
typedef struct _RTL_BSD_DATA_POWER_TRANSITION
{
UCHAR PowerButton : 1;
UCHAR SleepButton : 1;
UCHAR LidClose : 1;
UCHAR SystemIdle : 1;
UCHAR UserPresent : 1; // Power setting "Keep Alive"
UCHAR ApmBattery : 1;
UCHAR Reserved : 2;
} RTL_BSD_DATA_POWER_TRANSITION, *PRTL_BSD_DATA_POWER_TRANSITION;
typedef struct _RTL_BSD_DATA_ERROR_INFO
{
ULONG BootId; // The Boot ID where the error occurred
ULONG RepeatCount; // How many times this specific error happened
ULONG OtherErrorCount; // Count of other errors
} RTL_BSD_DATA_ERROR_INFO, *PRTL_BSD_DATA_ERROR_INFO;
typedef struct _RTL_BSD_POWER_BUTTON_PRESS_INFO
{
ULONG LastPressBootId;
ULONG LastPressTime; // Time in seconds since boot
ULONG LastReleaseTime;
ULONG ButtonPressCount;
ULONG CoalescedPressTime; // Total time pressed across recent boots
ULONG CoalescedPressCount;
} RTL_BSD_POWER_BUTTON_PRESS_INFO, *PRTL_BSD_POWER_BUTTON_PRESS_INFO;
typedef struct _RTL_BSD_DATA_POWER_TRANSITION_EXTENSION
{
UCHAR SystemIdleTransition : 1;
UCHAR FanError : 1;
UCHAR ThermalShutdown : 1;
UCHAR Reserved : 5;
} RTL_BSD_DATA_POWER_TRANSITION_EXTENSION, *PRTL_BSD_DATA_POWER_TRANSITION_EXTENSION;
// private
typedef struct _RTL_BSD_ITEM
{
RTL_BSD_ITEM_TYPE Type;
PVOID DataBuffer;
ULONG DataLength;
} RTL_BSD_ITEM, *PRTL_BSD_ITEM;
// ros
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateBootStatusDataFile(
VOID
);
// ros
NTSYSAPI
NTSTATUS
NTAPI
RtlLockBootStatusData(
_Out_ PHANDLE FileHandle
);
// ros
NTSYSAPI
NTSTATUS
NTAPI
RtlUnlockBootStatusData(
_In_ HANDLE FileHandle
);
// ros
NTSYSAPI
NTSTATUS
NTAPI
RtlGetSetBootStatusData(
_In_ HANDLE FileHandle,
_In_ BOOLEAN Read,
_In_ RTL_BSD_ITEM_TYPE DataClass,
_In_ PVOID Buffer,
_In_ ULONG BufferSize,
_Out_opt_ PULONG ReturnLength
);
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS1)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckBootStatusIntegrity(
_In_ HANDLE FileHandle,
_Out_ PBOOLEAN Verified
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlRestoreBootStatusDefaults(
_In_ HANDLE FileHandle
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS1
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS3)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlRestoreSystemBootStatusDefaults(
VOID
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetSystemBootStatus(
_In_ RTL_BSD_ITEM_TYPE BootStatusInformationClass,
_Out_ PVOID DataBuffer,
_In_ ULONG DataLength
//_Out_opt_ PULONG ReturnLength
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSetSystemBootStatus(
_In_ RTL_BSD_ITEM_TYPE BootStatusInformationClass,
_In_ PVOID DataBuffer,
_In_ ULONG DataLength
//_Out_opt_ PULONG ReturnLength
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS3
#if (PHNT_VERSION >= PHNT_WINDOWS_8)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckPortableOperatingSystem(
_Out_ PBOOLEAN IsPortable // VOID
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSetPortableOperatingSystem(
_In_ BOOLEAN IsPortable
);
// rev
NTSYSAPI
ULONG
NTAPI
RtlSetProxiedProcessId(
_In_ ULONG ProxiedProcessId
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_8
NTSYSAPI
NTSTATUS
NTAPI
RtlFindClosestEncodableLength(
_In_ ULONGLONG SourceLength,
_Out_ PULONGLONG TargetLength
);
//
// Memory cache
//
typedef _Function_class_(RTL_SECURE_MEMORY_CACHE_CALLBACK)
NTSTATUS NTAPI RTL_SECURE_MEMORY_CACHE_CALLBACK(
_In_ PVOID Address,
_In_ SIZE_T Length
);
typedef RTL_SECURE_MEMORY_CACHE_CALLBACK *PRTL_SECURE_MEMORY_CACHE_CALLBACK;
// ros
NTSYSAPI
NTSTATUS
NTAPI
RtlRegisterSecureMemoryCacheCallback(
_In_ PRTL_SECURE_MEMORY_CACHE_CALLBACK Callback
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeregisterSecureMemoryCacheCallback(
_In_ PRTL_SECURE_MEMORY_CACHE_CALLBACK Callback
);
// ros
NTSYSAPI
BOOLEAN
NTAPI
RtlFlushSecureMemoryCache(
_In_ PVOID MemoryCache,
_In_opt_ SIZE_T MemoryLength
);
//
// Feature configuration
//
// private
typedef ULONG RTL_FEATURE_ID;
typedef ULONGLONG RTL_FEATURE_CHANGE_STAMP, *PRTL_FEATURE_CHANGE_STAMP;
typedef UCHAR RTL_FEATURE_VARIANT;
typedef ULONG RTL_FEATURE_VARIANT_PAYLOAD;
typedef PVOID RTL_FEATURE_CONFIGURATION_CHANGE_REGISTRATION, *PRTL_FEATURE_CONFIGURATION_CHANGE_REGISTRATION;
// private
typedef struct _RTL_FEATURE_USAGE_REPORT
{
ULONG FeatureId;
USHORT ReportingKind;
USHORT ReportingOptions;
} RTL_FEATURE_USAGE_REPORT, *PRTL_FEATURE_USAGE_REPORT;
// private
typedef enum _RTL_FEATURE_CONFIGURATION_TYPE
{
RtlFeatureConfigurationBoot,
RtlFeatureConfigurationRuntime,
RtlFeatureConfigurationCount
} RTL_FEATURE_CONFIGURATION_TYPE;
// private
typedef struct _RTL_FEATURE_CONFIGURATION
{
ULONG FeatureId;
union
{
ULONG Flags;
struct
{
ULONG Priority : 4;
ULONG EnabledState : 2;
ULONG IsWexpConfiguration : 1;
ULONG HasSubscriptions : 1;
ULONG Variant : 6;
ULONG VariantPayloadKind : 2;
ULONG Reserved : 16;
};
};
ULONG VariantPayload;
} RTL_FEATURE_CONFIGURATION, *PRTL_FEATURE_CONFIGURATION;
// private
typedef struct _RTL_FEATURE_CONFIGURATION_INTERNAL
{
ULONG FeatureId;
union
{
struct
{
ULONG Priority : 4;
ULONG EnabledState : 2;
ULONG IsWexpConfiguration : 1;
ULONG HasSubscriptions : 1;
ULONG Variant : 6;
ULONG VariantPayloadKind : 2;
ULONG Reserved : 16;
};
ULONG Flags;
};
ULONG VariantPayload;
union
{
struct
{
ULONG ChangeTimeUpgrade : 1;
ULONG HasGroupBypass : 1;
ULONG Reserved2 : 30;
};
ULONG Flags2;
};
} RTL_FEATURE_CONFIGURATION_INTERNAL, *PRTL_FEATURE_CONFIGURATION_INTERNAL;
// private
typedef struct _SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION_ENTRY
{
RTL_FEATURE_CHANGE_STAMP ChangeStamp;
HANDLE SectionHandle;
SIZE_T Size;
} SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION_ENTRY, *PSYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION_ENTRY;
// private
typedef enum _SYSTEM_FEATURE_CONFIGURATION_SECTION_TYPE
{
SystemFeatureConfigurationSectionTypeBoot = 0,
SystemFeatureConfigurationSectionTypeRuntime = 1,
SystemFeatureConfigurationSectionTypeUsageTriggers = 2,
SystemFeatureConfigurationSectionTypeGoverned = 3,
SystemFeatureConfigurationSectionTypeCount
} SYSTEM_FEATURE_CONFIGURATION_SECTION_TYPE;
// private
typedef struct _SYSTEM_FEATURE_CONFIGURATION_SECTIONS_REQUEST
{
RTL_FEATURE_CHANGE_STAMP PreviousChangeStamps[SystemFeatureConfigurationSectionTypeCount];
} SYSTEM_FEATURE_CONFIGURATION_SECTIONS_REQUEST, *PSYSTEM_FEATURE_CONFIGURATION_SECTIONS_REQUEST;
// private
typedef struct _SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION
{
RTL_FEATURE_CHANGE_STAMP OverallChangeStamp;
SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION_ENTRY Descriptors[SystemFeatureConfigurationSectionTypeCount];
} SYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION, *PSYSTEM_FEATURE_CONFIGURATION_SECTIONS_INFORMATION;
//typedef struct _SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE
//{
// ULONG UpdateCount;
// _Field_size_(UpdateCount) SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE_ENTRY Updates[ANYSIZE_ARRAY];
//} SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE, *PSYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE;
// private
typedef struct _RTL_FEATURE_CONFIGURATION_TABLE
{
ULONG FeatureCount;
_Field_size_(FeatureCount) RTL_FEATURE_CONFIGURATION_INTERNAL Features[ANYSIZE_ARRAY];
} RTL_FEATURE_CONFIGURATION_TABLE, *PRTL_FEATURE_CONFIGURATION_TABLE;
// private
typedef enum _RTL_FEATURE_CONFIGURATION_PRIORITY
{
FeatureConfigurationPriorityImageDefault = 0,
FeatureConfigurationPriorityEKB = 1,
FeatureConfigurationPrioritySafeguard = 2,
FeatureConfigurationPriorityPersistent = FeatureConfigurationPrioritySafeguard,
FeatureConfigurationPriorityReserved3 = 3,
FeatureConfigurationPriorityService = 4,
FeatureConfigurationPriorityReserved5 = 5,
FeatureConfigurationPriorityDynamic = 6,
FeatureConfigurationPriorityReserved7 = 7,
FeatureConfigurationPriorityUser = 8,
FeatureConfigurationPrioritySecurity = 9,
FeatureConfigurationPriorityUserPolicy = 10,
FeatureConfigurationPriorityReserved11 = 11,
FeatureConfigurationPriorityTest = 12,
FeatureConfigurationPriorityReserved13 = 13,
FeatureConfigurationPriorityReserved14 = 14,
FeatureConfigurationPriorityImageOverride = 15,
FeatureConfigurationPriorityMax = FeatureConfigurationPriorityImageOverride
} RTL_FEATURE_CONFIGURATION_PRIORITY, *PRTL_FEATURE_CONFIGURATION_PRIORITY;
// private
typedef enum _RTL_FEATURE_ENABLED_STATE
{
FeatureEnabledStateDefault,
FeatureEnabledStateDisabled,
FeatureEnabledStateEnabled
} RTL_FEATURE_ENABLED_STATE;
// private
typedef enum _RTL_FEATURE_ENABLED_STATE_OPTIONS
{
FeatureEnabledStateOptionsNone,
FeatureEnabledStateOptionsWexpConfig
} RTL_FEATURE_ENABLED_STATE_OPTIONS, *PRTL_FEATURE_ENABLED_STATE_OPTIONS;
// private
typedef enum _RTL_FEATURE_VARIANT_PAYLOAD_KIND
{
FeatureVariantPayloadKindNone,
FeatureVariantPayloadKindResident,
FeatureVariantPayloadKindExternal
} RTL_FEATURE_VARIANT_PAYLOAD_KIND, *PRTL_FEATURE_VARIANT_PAYLOAD_KIND;
// private
typedef enum _RTL_FEATURE_CONFIGURATION_OPERATION
{
FeatureConfigurationOperationNone = 0,
FeatureConfigurationOperationFeatureState = 1,
FeatureConfigurationOperationVariantState = 2,
FeatureConfigurationOperationResetState = 4
} RTL_FEATURE_CONFIGURATION_OPERATION, *PRTL_FEATURE_CONFIGURATION_OPERATION;
// private
typedef struct _RTL_FEATURE_CONFIGURATION_UPDATE
{
RTL_FEATURE_ID FeatureId;
RTL_FEATURE_CONFIGURATION_PRIORITY Priority;
RTL_FEATURE_ENABLED_STATE EnabledState;
RTL_FEATURE_ENABLED_STATE_OPTIONS EnabledStateOptions;
union
{
ULONG VariantFlags;
struct
{
ULONG Variant : 8;
ULONG ChangeTimeUpgrade : 1;
ULONG HasGroupBypass : 1;
ULONG ReservedFlags : 22;
} DUMMYSTRUCTNAME;
} DUMMYUNIONNAME;
UCHAR Reserved[3];
RTL_FEATURE_VARIANT_PAYLOAD_KIND VariantPayloadKind;
RTL_FEATURE_VARIANT_PAYLOAD VariantPayload;
RTL_FEATURE_CONFIGURATION_OPERATION Operation;
} RTL_FEATURE_CONFIGURATION_UPDATE, *PRTL_FEATURE_CONFIGURATION_UPDATE;
// private
typedef struct _RTL_FEATURE_USAGE_SUBSCRIPTION_TARGET
{
ULONG Data[2];
} RTL_FEATURE_USAGE_SUBSCRIPTION_TARGET, *PRTL_FEATURE_USAGE_SUBSCRIPTION_TARGET;
// private
typedef struct _SYSTEM_FEATURE_USAGE_SUBSCRIPTION_DETAILS
{
RTL_FEATURE_ID FeatureId;
USHORT ReportingKind;
USHORT ReportingOptions;
RTL_FEATURE_USAGE_SUBSCRIPTION_TARGET ReportingTarget;
} SYSTEM_FEATURE_USAGE_SUBSCRIPTION_DETAILS, *PSYSTEM_FEATURE_USAGE_SUBSCRIPTION_DETAILS;
// private
typedef struct _RTL_FEATURE_USAGE_DATA
{
RTL_FEATURE_ID FeatureId;
USHORT ReportingKind;
USHORT UsageCount;
} RTL_FEATURE_USAGE_DATA, *PRTL_FEATURE_USAGE_DATA;
// private
typedef struct _RTL_FEATURE_USAGE_SUBSCRIPTION_DETAILS
{
RTL_FEATURE_ID FeatureId;
USHORT ReportingKind;
USHORT ReportingOptions;
RTL_FEATURE_USAGE_SUBSCRIPTION_TARGET ReportingTarget;
} RTL_FEATURE_USAGE_SUBSCRIPTION_DETAILS, *PRTL_FEATURE_USAGE_SUBSCRIPTION_DETAILS;
// private
typedef struct _RTL_FEATURE_USAGE_SUBSCRIPTION_TABLE
{
ULONG SubscriptionCount;
_Field_size_(SubscriptionCount) RTL_FEATURE_USAGE_SUBSCRIPTION_DETAILS Subscriptions[ANYSIZE_ARRAY];
} RTL_FEATURE_USAGE_SUBSCRIPTION_TABLE, *PRTL_FEATURE_USAGE_SUBSCRIPTION_TABLE;
// private
typedef struct _SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE_ENTRY
{
ULONG Remove;
RTL_FEATURE_USAGE_SUBSCRIPTION_DETAILS Details;
} SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE_ENTRY, *PSYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE_ENTRY;
// private
typedef _Function_class_(RTL_FEATURE_CONFIGURATION_CHANGE_CALLBACK)
VOID NTAPI RTL_FEATURE_CONFIGURATION_CHANGE_CALLBACK(
_In_opt_ PVOID Context
);
typedef RTL_FEATURE_CONFIGURATION_CHANGE_CALLBACK *PRTL_FEATURE_CONFIGURATION_CHANGE_CALLBACK;
// private
typedef struct _SYSTEM_FEATURE_CONFIGURATION_QUERY
{
RTL_FEATURE_CONFIGURATION_TYPE ConfigurationType;
RTL_FEATURE_ID FeatureId;
} SYSTEM_FEATURE_CONFIGURATION_QUERY, *PSYSTEM_FEATURE_CONFIGURATION_QUERY;
// private
typedef struct _SYSTEM_FEATURE_CONFIGURATION_INFORMATION
{
RTL_FEATURE_CHANGE_STAMP ChangeStamp;
RTL_FEATURE_CONFIGURATION Configuration;
} SYSTEM_FEATURE_CONFIGURATION_INFORMATION, *PSYSTEM_FEATURE_CONFIGURATION_INFORMATION;
// private
typedef enum _SYSTEM_FEATURE_CONFIGURATION_UPDATE_TYPE
{
SystemFeatureConfigurationUpdateTypeUpdate = 0,
SystemFeatureConfigurationUpdateTypeOverwrite = 1,
SystemFeatureConfigurationUpdateTypeCount = 2,
} SYSTEM_FEATURE_CONFIGURATION_UPDATE_TYPE, *PSYSTEM_FEATURE_CONFIGURATION_UPDATE_TYPE;
// private
typedef struct _SYSTEM_FEATURE_CONFIGURATION_UPDATE
{
SYSTEM_FEATURE_CONFIGURATION_UPDATE_TYPE UpdateType;
union
{
struct
{
RTL_FEATURE_CHANGE_STAMP PreviousChangeStamp;
RTL_FEATURE_CONFIGURATION_TYPE ConfigurationType;
ULONG UpdateCount;
_Field_size_(UpdateCount) RTL_FEATURE_CONFIGURATION_UPDATE Updates[ANYSIZE_ARRAY];
} Update;
struct
{
RTL_FEATURE_CHANGE_STAMP PreviousChangeStamp;
RTL_FEATURE_CONFIGURATION_TYPE ConfigurationType;
SIZE_T BufferSize;
PVOID Buffer;
} Overwrite;
};
} SYSTEM_FEATURE_CONFIGURATION_UPDATE, *PSYSTEM_FEATURE_CONFIGURATION_UPDATE;
// private
//typedef struct _SYSTEM_FEATURE_USAGE_SUBSCRIPTION_DETAILS
//{
// RTL_FEATURE_ID FeatureId;
// USHORT ReportingKind;
// USHORT ReportingOptions;
// RTL_FEATURE_USAGE_SUBSCRIPTION_TARGET ReportingTarget;
//} SYSTEM_FEATURE_USAGE_SUBSCRIPTION_DETAILS, *PSYSTEM_FEATURE_USAGE_SUBSCRIPTION_DETAILS;
//typedef struct _SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE_ENTRY
//{
// ULONG Remove;
// RTL_FEATURE_USAGE_SUBSCRIPTION_DETAILS Details;
//} SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE_ENTRY, *PSYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE_ENTRY;
//
//typedef struct _SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE
//{
// ULONG UpdateCount;
// _Field_size_(UpdateCount) SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE_ENTRY Updates[ANYSIZE_ARRAY];
//} SYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE, *PSYSTEM_FEATURE_USAGE_SUBSCRIPTION_UPDATE;
#if (PHNT_VERSION >= PHNT_WINDOWS_10_20H1)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlNotifyFeatureUsage(
_In_ PRTL_FEATURE_USAGE_REPORT FeatureUsageReport
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryFeatureConfiguration(
_In_ RTL_FEATURE_ID FeatureId,
_In_ RTL_FEATURE_CONFIGURATION_TYPE ConfigurationType,
_Out_ PRTL_FEATURE_CHANGE_STAMP ChangeStamp,
_Out_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSetFeatureConfigurations(
_In_opt_ PRTL_FEATURE_CHANGE_STAMP PreviousChangeStamp,
_In_ RTL_FEATURE_CONFIGURATION_TYPE ConfigurationType,
_In_reads_(ConfigurationUpdateCount) PRTL_FEATURE_CONFIGURATION_UPDATE ConfigurationUpdates,
_In_ SIZE_T ConfigurationUpdateCount
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryAllFeatureConfigurations(
_In_ RTL_FEATURE_CONFIGURATION_TYPE ConfigurationType,
_Out_opt_ PRTL_FEATURE_CHANGE_STAMP ChangeStamp,
_Out_writes_(*ConfigurationCount) PRTL_FEATURE_CONFIGURATION Configurations,
_Inout_ PSIZE_T ConfigurationCount
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryAllInternalFeatureConfigurations(
_In_ RTL_FEATURE_CONFIGURATION_TYPE ConfigurationType,
_Out_opt_ PRTL_FEATURE_CHANGE_STAMP ChangeStamp,
_Out_writes_(*ConfigurationCount) PRTL_FEATURE_CONFIGURATION Configurations,
_Inout_ PSIZE_T ConfigurationCount
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryAllInternalRuntimeFeatureConfigurations(
_In_ RTL_FEATURE_ID FeatureId,
_In_ RTL_FEATURE_CONFIGURATION_TYPE ConfigurationType,
_Out_opt_ PRTL_FEATURE_CHANGE_STAMP ChangeStamp,
_Out_writes_(*ConfigurationCount) PRTL_FEATURE_CONFIGURATION Configurations,
_Inout_ PSIZE_T ConfigurationCount
);
// private
NTSYSAPI
RTL_FEATURE_CHANGE_STAMP
NTAPI
RtlQueryFeatureConfigurationChangeStamp(
VOID
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryFeatureUsageNotificationSubscriptions(
_Out_writes_(*SubscriptionCount) PRTL_FEATURE_USAGE_SUBSCRIPTION_DETAILS Subscriptions,
_Inout_ PSIZE_T SubscriptionCount
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlRegisterFeatureConfigurationChangeNotification(
_In_ PRTL_FEATURE_CONFIGURATION_CHANGE_CALLBACK Callback,
_In_opt_ PVOID Context,
_In_opt_ PRTL_FEATURE_CHANGE_STAMP ObservedChangeStamp,
_Out_ PRTL_FEATURE_CONFIGURATION_CHANGE_REGISTRATION RegistrationHandle
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlUnregisterFeatureConfigurationChangeNotification(
_In_ RTL_FEATURE_CONFIGURATION_CHANGE_REGISTRATION RegistrationHandle
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSubscribeForFeatureUsageNotification(
_In_reads_(SubscriptionCount) PRTL_FEATURE_USAGE_SUBSCRIPTION_DETAILS SubscriptionDetails,
_In_ SIZE_T SubscriptionCount
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlUnsubscribeFromFeatureUsageNotifications(
_In_reads_(SubscriptionCount) PRTL_FEATURE_USAGE_SUBSCRIPTION_DETAILS SubscriptionDetails,
_In_ SIZE_T SubscriptionCount
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_20H1
// private
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
NTSYSAPI
NTSTATUS
NTAPI
RtlOverwriteFeatureConfigurationBuffer(
_In_opt_ PRTL_FEATURE_CHANGE_STAMP PreviousChangeStamp,
_In_ RTL_FEATURE_CONFIGURATION_TYPE ConfigurationType,
_In_reads_bytes_opt_(ConfigurationBufferSize) PVOID ConfigurationBuffer,
_In_ ULONG ConfigurationBufferSize
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlNotifyFeatureToggleUsage(
_In_ PRTL_FEATURE_USAGE_REPORT FeatureUsageReport,
_In_ RTL_FEATURE_ID FeatureId,
_In_ ULONG Flags
);
// rev
NTSYSAPI
ULONG
NTAPI
RtlGetFeatureTogglesChangeToken(
VOID
);
//
// Run Once
//
#ifndef _RTL_RUN_ONCE_DEF
#define _RTL_RUN_ONCE_DEF
//
// Run once initializer
//
#define RTL_RUN_ONCE_INIT {0}
//
// Run once flags
//
#define RTL_RUN_ONCE_CHECK_ONLY 0x00000001UL
#define RTL_RUN_ONCE_ASYNC 0x00000002UL
#define RTL_RUN_ONCE_INIT_FAILED 0x00000004UL
//
// The context stored in the run once structure must
// leave the following number of low order bits unused.
//
#define RTL_RUN_ONCE_CTX_RESERVED_BITS 2
typedef union _RTL_RUN_ONCE
{
PVOID Ptr;
} RTL_RUN_ONCE, *PRTL_RUN_ONCE;
#endif // _RTL_RUN_ONCE_DEF
NTSYSAPI
VOID
NTAPI
RtlRunOnceInitialize(
_Out_ PRTL_RUN_ONCE RunOnce
);
typedef _Function_class_(RTL_RUN_ONCE_INIT_FN)
LOGICAL NTAPI RTL_RUN_ONCE_INIT_FN(
_Inout_ PRTL_RUN_ONCE RunOnce,
_Inout_opt_ PVOID Parameter,
_Inout_opt_ PVOID *Context
);
typedef RTL_RUN_ONCE_INIT_FN *PRTL_RUN_ONCE_INIT_FN;
_Maybe_raises_SEH_exception_
NTSYSAPI
NTSTATUS
NTAPI
RtlRunOnceExecuteOnce(
_Inout_ PRTL_RUN_ONCE RunOnce,
_In_ __callback PRTL_RUN_ONCE_INIT_FN InitFn,
_Inout_opt_ PVOID Parameter,
_Outptr_opt_result_maybenull_ PVOID *Context
);
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlRunOnceBeginInitialize(
_Inout_ PRTL_RUN_ONCE RunOnce,
_In_ ULONG Flags,
_Outptr_opt_result_maybenull_ PVOID *Context
);
NTSYSAPI
NTSTATUS
NTAPI
RtlRunOnceComplete(
_Inout_ PRTL_RUN_ONCE RunOnce,
_In_ ULONG Flags,
_In_opt_ PVOID Context
);
//
// WNF (Windows Notification Facility)
//
#if (PHNT_VERSION >= PHNT_WINDOWS_10)
#define WNF_STATE_KEY 0x41C64E6DA3BC0074
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualWnfChangeStamps(
_In_ WNF_CHANGE_STAMP ChangeStamp1,
_In_ WNF_CHANGE_STAMP ChangeStamp2
);
_Always_(_Post_satisfies_(return == STATUS_NO_MEMORY || return == STATUS_RETRY || return == STATUS_SUCCESS))
typedef _Function_class_(WNF_USER_CALLBACK)
NTSTATUS NTAPI WNF_USER_CALLBACK(
_In_ WNF_STATE_NAME StateName,
_In_ WNF_CHANGE_STAMP ChangeStamp,
_In_opt_ PWNF_TYPE_ID TypeId,
_In_opt_ PVOID CallbackContext,
_In_reads_bytes_opt_(Length) const VOID* Buffer,
_In_ ULONG Length
);
typedef WNF_USER_CALLBACK *PWNF_USER_CALLBACK;
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryWnfStateData(
_Out_ PWNF_CHANGE_STAMP ChangeStamp,
_In_ WNF_STATE_NAME StateName,
_In_ PWNF_USER_CALLBACK Callback,
_In_opt_ PVOID CallbackContext,
_In_opt_ PWNF_TYPE_ID TypeId
);
NTSYSAPI
NTSTATUS
NTAPI
RtlPublishWnfStateData(
_In_ WNF_STATE_NAME StateName,
_In_opt_ PCWNF_TYPE_ID TypeId,
_In_reads_bytes_opt_(Length) const VOID* Buffer,
_In_opt_ ULONG Length,
_In_opt_ const VOID* ExplicitScope
);
typedef struct WNF_USER_SUBSCRIPTION *PWNF_USER_SUBSCRIPTION;
#define WNF_CREATE_SERIALIZATION_GROUP_FLAG 0x00000001L
NTSYSAPI
NTSTATUS
NTAPI
RtlSubscribeWnfStateChangeNotification(
_Out_ PWNF_USER_SUBSCRIPTION* SubscriptionHandle,
_In_ WNF_STATE_NAME StateName,
_In_ WNF_CHANGE_STAMP ChangeStamp,
_In_ PWNF_USER_CALLBACK Callback,
_In_opt_ PVOID CallbackContext,
_In_opt_ PCWNF_TYPE_ID TypeId,
_In_opt_ ULONG SerializationGroup,
_In_ ULONG Flags
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUnsubscribeWnfStateChangeNotification(
_In_ PWNF_USER_SUBSCRIPTION SubscriptionHandle
);
NTSYSAPI
NTSTATUS
NTAPI
RtlWnfDllUnloadCallback(
_In_ PVOID DllBase
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10
#if (PHNT_VERSION >= PHNT_WINDOWS_10_20H1)
NTSYSAPI
ULONG_PTR
NTAPI
RtlGetReturnAddressHijackTarget(
VOID
);
#endif
#define COPY_FILE_CHUNK_DUPLICATE_EXTENTS 0x00000001L // 24H2
#define VALID_COPY_FILE_CHUNK_FLAGS (COPY_FILE_CHUNK_DUPLICATE_EXTENTS)
//
// Property Store
//
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryPropertyStore(
_In_ ULONG_PTR Key,
_Out_ PULONG_PTR Context
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlRemovePropertyStore(
_In_ ULONG_PTR Key,
_Out_ PULONG_PTR Context
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCompareExchangePropertyStore(
_In_ ULONG_PTR Key,
_In_ PULONG_PTR Comperand,
_In_opt_ PULONG_PTR Exchange,
_Out_ PULONG_PTR Context
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
#if (PHNT_VERSION >= PHNT_WINDOWS_11)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64ChangeProcessState(
_In_ HANDLE ProcessStateChangeHandle,
_In_ HANDLE ProcessHandle,
_In_ PROCESS_STATE_CHANGE_TYPE StateChangeType
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64ChangeThreadState(
_In_ HANDLE ThreadStateChangeHandle,
_In_ HANDLE ThreadHandle,
_In_ THREAD_STATE_CHANGE_TYPE StateChangeType
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11
#if (PHNT_VERSION >= PHNT_WINDOWS_10_RS1)
// rev
NTSYSAPI
USHORT
NTAPI
RtlGetCurrentThreadPrimaryGroup(
VOID
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_10_RS1
#if (PHNT_VERSION >= PHNT_WINDOWS_11_24H2)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryProcessAvailableCpus(
_In_ HANDLE ProcessHandle,
_In_ PKAFFINITY_EX Affinity,
_In_ ULONG64 ObservedSequenceNumber,
_Out_opt_ PULONG64 SequenceNumber
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryProcessAvailableCpusCount(
_In_ HANDLE ProcessHandle,
_Out_ PULONG AvailableCpusCount,
_Out_opt_ PULONG64 SequenceNumber
);
#endif // PHNT_VERSION >= PHNT_WINDOWS_11_24H2
#endif // _NTRTL_H
/*
* RTL forward symbol typedefs
*
* This file is part of System Informer.
*/
#ifndef _NTRTL_FWD_H
#define _NTRTL_FWD_H
// Note: ntdll symbols and exports define these forwarders:
// begin_forwarders
#ifndef PHNT_INLINE_NAME_FORWARDERS
#define RtlGetNativeSystemInformation NtQuerySystemInformation
#define RtlGetTickCount NtGetTickCount
#define RtlGuardRestoreContext RtlRestoreContext
#define RtlRandom RtlRandomEx
#define RtlOpenImageFileOptionsKey LdrOpenImageFileOptionsKey
#define RtlQueryImageFileExecutionOptions LdrQueryImageFileExecutionOptionsEx
#define RtlQueryImageFileKeyOption LdrQueryImageFileKeyOption
#define RtlSetTimer RtlCreateTimer
#define RtlRestoreLastWin32Error RtlSetLastWin32Error
#endif // PHNT_INLINE_NAME_FORWARDERS
// end_forwarders
#endif // _NTRTL_FWD_H