ReBeacon_Src/include/Veil/Veil/Veil.System.RuntimeLibrary.h

10970 lines
230 KiB
C

/*
* PROJECT: Veil
* FILE: Veil.h
* PURPOSE: Definition for the Windows Internal API from ntdll.dll,
* samlib.dll and winsta.dll
*
* LICENSE: Relicensed under The MIT License from The CC BY 4.0 License
*
* DEVELOPER: MiroKaku (50670906+MiroKaku@users.noreply.github.com)
*/
/*
* PROJECT: Mouri's Internal NT API Collections (MINT)
* FILE: MINT.h
* PURPOSE: Definition for the Windows Internal API from ntdll.dll,
* samlib.dll and winsta.dll
*
* LICENSE: Relicensed under The MIT License from The CC BY 4.0 License
*
* DEVELOPER: Mouri_Naruto (Mouri_Naruto AT Outlook.com)
*/
/*
* This file is part of the Process Hacker project - https://processhacker.sf.io/
*
* You can redistribute this file and/or modify it under the terms of the
* Attribution 4.0 International (CC BY 4.0) license.
*
* You must give appropriate credit, provide a link to the license, and
* indicate if changes were made. You may do so in any reasonable manner, but
* not in any way that suggests the licensor endorses you or your use.
*/
#pragma once
// Warnings which disabled for compiling
#if _MSC_VER >= 1200
#pragma warning(push)
// nonstandard extension used : nameless struct/union
#pragma warning(disable:4201)
// 'struct_name' : structure was padded due to __declspec(align())
#pragma warning(disable:4324)
// 'enumeration': a forward declaration of an unscoped enumeration must have an
// underlying type (int assumed)
#pragma warning(disable:4471)
#endif
VEIL_BEGIN()
//
// Helper
//
#ifndef _KERNEL_MODE
//++
//
// PCHAR
// RtlOffsetToPointer (
// PVOID Base,
// ULONG Offset
// )
//
// Routine Description:
//
// This macro generates a pointer which points to the byte that is 'Offset'
// bytes beyond 'Base'. This is useful for referencing fields within
// self-relative data structures.
//
// Arguments:
//
// Base - The address of the base of the structure.
//
// Offset - An unsigned integer offset of the byte whose address is to
// be generated.
//
// Return Value:
//
// A PCHAR pointer to the byte that is 'Offset' bytes beyond 'Base'.
//
//
//--
#define RtlOffsetToPointer(B,O) ((PCHAR)( ((PCHAR)(B)) + ((ULONG_PTR)(O)) ))
//++
//
// ULONG
// RtlPointerToOffset (
// PVOID Base,
// PVOID Pointer
// )
//
// Routine Description:
//
// This macro calculates the offset from Base to Pointer. This is useful
// for producing self-relative offsets for structures.
//
// Arguments:
//
// Base - The address of the base of the structure.
//
// Pointer - A pointer to a field, presumably within the structure
// pointed to by Base. This value must be larger than that specified
// for Base.
//
// Return Value:
//
// A ULONG offset from Base to Pointer.
//
//
//--
#define RtlPointerToOffset(B,P) ((ULONG)( ((PCHAR)(P)) - ((PCHAR)(B)) ))
//++
//VOID
//RtlFailFast (
// _In_ ULONG Code
// );
//
// Routine Description:
//
// This routine brings down the caller immediately in the event that
// critical corruption has been detected. No exception handlers are
// invoked.
//
// The routine may be used in libraries 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.
//
// Arguments
//
// Code - Supplies the reason code describing what type of corruption
// was detected.
//
// Return Value:
//
// None. There is no return from this routine.
//
//--
DECLSPEC_NORETURN
FORCEINLINE
VOID
RtlFailFast(
_In_ ULONG Code
)
{
__fastfail(Code);
}
#endif // !_KERNEL_MODE
//
// Doubly-linked list manipulation routines.
//
#ifndef _KERNEL_MODE
//
// VOID
// InitializeListHead32(
// PLIST_ENTRY32 ListHead
// );
//
#define InitializeListHead32(ListHead) (\
(ListHead)->Flink = (ListHead)->Blink = PtrToUlong((ListHead)))
#define RTL_STATIC_LIST_HEAD(x) LIST_ENTRY x = { &x, &x }
FORCEINLINE
VOID
InitializeListHead(
_Out_ PLIST_ENTRY ListHead
)
{
ListHead->Flink = ListHead->Blink = ListHead;
return;
}
_Must_inspect_result_
BOOLEAN
FORCEINLINE
IsListEmpty(
_In_ const LIST_ENTRY* ListHead
)
{
return (BOOLEAN)(ListHead->Flink == ListHead);
}
//++
//VOID
//FatalListEntryError (
// _In_ PVOID p1,
// _In_ PVOID p2,
// _In_ PVOID p3
// );
//
// Routine Description:
//
// 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.
//
// Arguments:
//
// p1 - Supplies the first failure parameter.
//
// p2 - Supplies the second failure parameter.
//
// p3 - Supplies the third failure parameter.
//
//Return Value:
//
// None.
//--
FORCEINLINE
VOID
FatalListEntryError(
_In_ PVOID p1,
_In_ PVOID p2,
_In_ PVOID p3
)
{
UNREFERENCED_PARAMETER(p1);
UNREFERENCED_PARAMETER(p2);
UNREFERENCED_PARAMETER(p3);
RtlFailFast(FAST_FAIL_CORRUPT_LIST_ENTRY);
}
#if DBG
FORCEINLINE
VOID
RtlpCheckListEntry(
_In_ PLIST_ENTRY Entry
)
{
if ((((Entry->Flink)->Blink) != Entry) || (((Entry->Blink)->Flink) != Entry)) {
FatalListEntryError((PVOID)(Entry),
(PVOID)((Entry->Flink)->Blink),
(PVOID)((Entry->Blink)->Flink));
}
}
#else
#define RtlpCheckListEntry
#endif
FORCEINLINE
BOOLEAN
RemoveEntryList(
_In_ PLIST_ENTRY Entry
)
{
PLIST_ENTRY PrevEntry;
PLIST_ENTRY NextEntry;
NextEntry = Entry->Flink;
PrevEntry = Entry->Blink;
if ((NextEntry->Blink != Entry) || (PrevEntry->Flink != Entry)) {
FatalListEntryError((PVOID)PrevEntry,
(PVOID)Entry,
(PVOID)NextEntry);
}
PrevEntry->Flink = NextEntry;
NextEntry->Blink = PrevEntry;
return (BOOLEAN)(PrevEntry == NextEntry);
}
FORCEINLINE
PLIST_ENTRY
RemoveHeadList(
_Inout_ PLIST_ENTRY ListHead
)
{
PLIST_ENTRY Entry;
PLIST_ENTRY NextEntry;
Entry = ListHead->Flink;
#if DBG
RtlpCheckListEntry(ListHead);
#endif
NextEntry = Entry->Flink;
if ((Entry->Blink != ListHead) || (NextEntry->Blink != Entry)) {
FatalListEntryError((PVOID)ListHead,
(PVOID)Entry,
(PVOID)NextEntry);
}
ListHead->Flink = NextEntry;
NextEntry->Blink = ListHead;
return Entry;
}
FORCEINLINE
PLIST_ENTRY
RemoveTailList(
_Inout_ PLIST_ENTRY ListHead
)
{
PLIST_ENTRY Entry;
PLIST_ENTRY PrevEntry;
Entry = ListHead->Blink;
#if DBG
RtlpCheckListEntry(ListHead);
#endif
PrevEntry = Entry->Blink;
if ((Entry->Flink != ListHead) || (PrevEntry->Flink != Entry)) {
FatalListEntryError((PVOID)PrevEntry,
(PVOID)Entry,
(PVOID)ListHead);
}
ListHead->Blink = PrevEntry;
PrevEntry->Flink = ListHead;
return Entry;
}
FORCEINLINE
VOID
InsertTailList(
_Inout_ PLIST_ENTRY ListHead,
_Out_ __drv_aliasesMem PLIST_ENTRY Entry
)
{
PLIST_ENTRY PrevEntry;
#if DBG
RtlpCheckListEntry(ListHead);
#endif
PrevEntry = ListHead->Blink;
if (PrevEntry->Flink != ListHead) {
FatalListEntryError((PVOID)PrevEntry,
(PVOID)ListHead,
(PVOID)PrevEntry->Flink);
}
Entry->Flink = ListHead;
Entry->Blink = PrevEntry;
PrevEntry->Flink = Entry;
ListHead->Blink = Entry;
return;
}
FORCEINLINE
VOID
InsertHeadList(
_Inout_ PLIST_ENTRY ListHead,
_Out_ __drv_aliasesMem PLIST_ENTRY Entry
)
{
PLIST_ENTRY NextEntry;
#if DBG
RtlpCheckListEntry(ListHead);
#endif
NextEntry = ListHead->Flink;
if (NextEntry->Blink != ListHead) {
FatalListEntryError((PVOID)ListHead,
(PVOID)NextEntry,
(PVOID)NextEntry->Blink);
}
Entry->Flink = NextEntry;
Entry->Blink = ListHead;
NextEntry->Blink = Entry;
ListHead->Flink = Entry;
return;
}
FORCEINLINE
VOID
AppendTailList(
_Inout_ PLIST_ENTRY ListHead,
_Inout_ PLIST_ENTRY ListToAppend
)
{
PLIST_ENTRY ListEnd = ListHead->Blink;
RtlpCheckListEntry(ListHead);
RtlpCheckListEntry(ListToAppend);
ListHead->Blink->Flink = ListToAppend;
ListHead->Blink = ListToAppend->Blink;
ListToAppend->Blink->Flink = ListHead;
ListToAppend->Blink = ListEnd;
return;
}
FORCEINLINE
PSINGLE_LIST_ENTRY
PopEntryList(
_Inout_ PSINGLE_LIST_ENTRY ListHead
)
{
PSINGLE_LIST_ENTRY FirstEntry;
FirstEntry = ListHead->Next;
if (FirstEntry != NULL) {
ListHead->Next = FirstEntry->Next;
}
return FirstEntry;
}
FORCEINLINE
VOID
PushEntryList(
_Inout_ PSINGLE_LIST_ENTRY ListHead,
_Inout_ __drv_aliasesMem PSINGLE_LIST_ENTRY Entry
)
{
Entry->Next = ListHead->Next;
ListHead->Next = Entry;
return;
}
#if !defined(MIDL_PASS)
__inline
void
ListEntry32To64(
_In_ PLIST_ENTRY32 l32,
_Out_ PLIST_ENTRY64 l64
)
{
l64->Flink = (ULONGLONG)(ULONG)l32->Flink;
l64->Blink = (ULONGLONG)(ULONG)l32->Blink;
}
__inline
void
ListEntry64To32(
_In_ PLIST_ENTRY64 l64,
_Out_ PLIST_ENTRY32 l32
)
{
l32->Flink = (ULONG)l64->Flink;
l32->Blink = (ULONG)l64->Blink;
}
#endif
#endif // !_KERNEL_MODE
//
// Run once
//
#ifndef _KERNEL_MODE
#ifndef _RTL_RUN_ONCE_DEF
#define _RTL_RUN_ONCE_DEF
//
// Run once
//
#define RTL_RUN_ONCE_INIT {0} // Static initializer
//
// 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
typedef
_Function_class_(RTL_RUN_ONCE_INIT_FN)
_IRQL_requires_same_
ULONG /* 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;
#if (NTDDI_VERSION >= NTDDI_LONGHORN)
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlRunOnceInitialize(
_Out_ PRTL_RUN_ONCE RunOnce
);
_IRQL_requires_max_(APC_LEVEL)
_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
);
_IRQL_requires_max_(APC_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlRunOnceBeginInitialize(
_Inout_ PRTL_RUN_ONCE RunOnce,
_In_ ULONG Flags,
_Outptr_opt_result_maybenull_ PVOID* Context
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlRunOnceComplete(
_Inout_ PRTL_RUN_ONCE RunOnce,
_In_ ULONG Flags,
_In_opt_ PVOID Context
);
#endif // NTDDI_VERSION >= NTDDI_LONGHORN
#endif // !_KERNEL_MODE
//
// AVL Trees
//
#ifndef _KERNEL_MODE
//
// This enumerated type is used as the function return value of the function
// that is used to search the tree for a key. FoundNode indicates that the
// function found the key. Insert as left indicates that the key was not found
// and the node should be inserted as the left child of the parent. Insert as
// right indicates that the key was not found and the node should be inserted
// as the right child of the parent.
//
typedef enum _TABLE_SEARCH_RESULT {
TableEmptyTree,
TableFoundNode,
TableInsertAsLeft,
TableInsertAsRight
} TABLE_SEARCH_RESULT;
//
// The results of a compare can be less than, equal, or greater than.
//
typedef enum _RTL_GENERIC_COMPARE_RESULTS {
GenericLessThan,
GenericGreaterThan,
GenericEqual
} RTL_GENERIC_COMPARE_RESULTS;
//
// Define the Avl version of the generic table package. Note a generic table
// should really be an opaque type. We provide routines to manipulate the structure.
//
// A generic table is package for inserting, deleting, and looking up elements
// in a table (e.g., in a symbol table). To use this package the user
// defines the structure of the elements stored in the table, provides a
// comparison function, a memory allocation function, and a memory
// deallocation function.
//
// Note: the user compare function must impose a complete ordering among
// all of the elements, and the table does not allow for duplicate entries.
//
//
// Add an empty typedef so that functions can reference the
// a pointer to the generic table struct before it is declared.
//
struct _RTL_AVL_TABLE;
//
// The comparison function takes as input pointers to elements containing
// user defined structures and returns the results of comparing the two
// elements.
//
typedef
_IRQL_requires_same_
_Function_class_(RTL_AVL_COMPARE_ROUTINE)
RTL_GENERIC_COMPARE_RESULTS
NTAPI
RTL_AVL_COMPARE_ROUTINE(
_In_ struct _RTL_AVL_TABLE* Table,
_In_ PVOID FirstStruct,
_In_ PVOID SecondStruct
);
typedef RTL_AVL_COMPARE_ROUTINE* PRTL_AVL_COMPARE_ROUTINE;
//
// The allocation function is called by the generic table package whenever
// it needs to allocate memory for the table.
//
typedef
_IRQL_requires_same_
_Function_class_(RTL_AVL_ALLOCATE_ROUTINE)
__drv_allocatesMem(Mem)
PVOID
NTAPI
RTL_AVL_ALLOCATE_ROUTINE(
_In_ struct _RTL_AVL_TABLE* Table,
_In_ ULONG ByteSize
);
typedef RTL_AVL_ALLOCATE_ROUTINE* PRTL_AVL_ALLOCATE_ROUTINE;
//
// The deallocation function is called by the generic table package whenever
// it needs to deallocate memory from the table that was allocated by calling
// the user supplied allocation function.
//
typedef
_IRQL_requires_same_
_Function_class_(RTL_AVL_FREE_ROUTINE)
VOID
NTAPI
RTL_AVL_FREE_ROUTINE(
_In_ struct _RTL_AVL_TABLE* Table,
_In_ __drv_freesMem(Mem) _Post_invalid_ PVOID Buffer
);
typedef RTL_AVL_FREE_ROUTINE* PRTL_AVL_FREE_ROUTINE;
//
// The match function takes as input the user data to be matched and a pointer
// to some match data, which was passed along with the function pointer. It
// returns TRUE for a match and FALSE for no match.
//
// RTL_AVL_MATCH_FUNCTION returns
// STATUS_SUCCESS if the IndexRow matches
// STATUS_NO_MATCH if the IndexRow does not match, but the enumeration should
// continue
// STATUS_NO_MORE_MATCHES if the IndexRow does not match, and the enumeration
// should terminate
//
typedef
_IRQL_requires_same_
_Function_class_(RTL_AVL_MATCH_FUNCTION)
NTSTATUS
NTAPI
RTL_AVL_MATCH_FUNCTION(
_In_ struct _RTL_AVL_TABLE* Table,
_In_ PVOID UserData,
_In_ PVOID MatchData
);
typedef RTL_AVL_MATCH_FUNCTION* PRTL_AVL_MATCH_FUNCTION;
//
// Define the balanced tree links and Balance field. (No Rank field
// defined at this time.)
//
// Callers should treat this structure as opaque!
//
// The root of a balanced binary tree is not a real node in the tree
// but rather points to a real node which is the root. It is always
// in the table below, and its fields are used as follows:
//
// Parent Pointer to self, to allow for detection of the root.
// LeftChild NULL
// RightChild Pointer to real root
// Balance Undefined, however it is set to a convenient value
// (depending on the algorithm) prior to rebalancing
// in insert and delete routines.
//
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;
typedef RTL_BALANCED_LINKS* PRTL_BALANCED_LINKS;
//
// To use the generic table package the user declares a variable of type
// GENERIC_TABLE and then uses the routines described below to initialize
// the table and to manipulate the table. Note that the generic table
// should really be an opaque type.
//
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;
typedef RTL_AVL_TABLE* PRTL_AVL_TABLE;
//
// The procedure InitializeGenericTable takes as input an uninitialized
// generic table variable and pointers to the three user supplied routines.
// This must be called for every individual generic table variable before
// it can be used.
//
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 function InsertElementGenericTable will insert a new element
// in a table. It does this by allocating space for the new element
// (this includes AVL links), inserting the element in the table, and
// then returning to the user a pointer to the new element. If an element
// with the same key already exists in the table the return value is a pointer
// to the old element. The optional output parameter NewElement is used
// to indicate if the element previously existed in the table. Note: the user
// supplied Buffer is only used for searching the table, upon insertion its
// contents are copied to the newly created element. This means that
// pointer to the input buffer will not point to the new element.
//
NTSYSAPI
PVOID
NTAPI
RtlInsertElementGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_reads_bytes_(BufferSize) PVOID Buffer,
_In_ ULONG BufferSize,
_Out_opt_ PBOOLEAN NewElement
);
//
// The function InsertElementGenericTableFull will insert a new element
// in a table. It does this by allocating space for the new element
// (this includes AVL links), inserting the element in the table, and
// then returning to the user a pointer to the new element. If an element
// with the same key already exists in the table the return value is a pointer
// to the old element. The optional output parameter NewElement is used
// to indicate if the element previously existed in the table. Note: the user
// supplied Buffer is only used for searching the table, upon insertion its
// contents are copied to the newly created element. This means that
// pointer to the input buffer will not point to the new element.
// This routine is passed the NodeOrParent and SearchResult from a
// previous RtlLookupElementGenericTableFull.
//
NTSYSAPI
PVOID
NTAPI
RtlInsertElementGenericTableFullAvl(
_In_ PRTL_AVL_TABLE Table,
_In_reads_bytes_(BufferSize) PVOID Buffer,
_In_ ULONG BufferSize,
_Out_opt_ PBOOLEAN NewElement,
_In_ PVOID NodeOrParent,
_In_ TABLE_SEARCH_RESULT SearchResult
);
//
// The function DeleteElementGenericTable will find and delete an element
// from a generic table. If the element is located and deleted the return
// value is TRUE, otherwise if the element is not located the return value
// is FALSE. The user supplied input buffer is only used as a key in
// locating the element in the table.
//
NTSYSAPI
BOOLEAN
NTAPI
RtlDeleteElementGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID Buffer
);
//
// The function DeleteElementGenericTableAvxEx deletes the element specified
// by the NodeOrParent pointer. This element user data pointer must have first
// been obtained with RtlLookupElementGenericTableFull.
//
#if (NTDDI_VERSION >= NTDDI_WIN8)
NTSYSAPI
VOID
NTAPI
RtlDeleteElementGenericTableAvlEx(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID NodeOrParent
);
#endif // NTDDI_VERSION >= NTDDI_WIN8
//
// The function LookupElementGenericTable will find an element in a generic
// table. If the element is located the return value is a pointer to
// the user defined structure associated with the element, otherwise if
// the element is not located the return value is NULL. The user supplied
// input buffer is only used as a key in locating the element in the table.
//
_Must_inspect_result_
NTSYSAPI
PVOID
NTAPI
RtlLookupElementGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID Buffer
);
//
// The function LookupElementGenericTableFull will find an element in a generic
// table. If the element is located the return value is a pointer to
// the user defined structure associated with the element. If the element is not
// located then a pointer to the parent for the insert location is returned. The
// user must look at the SearchResult value to determine which is being returned.
// The user can use the SearchResult and parent for a subsequent FullInsertElement
// call to optimize the insert.
//
NTSYSAPI
PVOID
NTAPI
RtlLookupElementGenericTableFullAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID Buffer,
_Out_ PVOID* NodeOrParent,
_Out_ TABLE_SEARCH_RESULT* SearchResult
);
//
// The function EnumerateGenericTable will return to the caller one-by-one
// the elements of of a table. The return value is a pointer to the user
// defined structure associated with the element. The input parameter
// Restart indicates if the enumeration should start from the beginning
// or should return the next element. If the are no more new elements to
// return the return value is NULL. As an example of its use, to enumerate
// all of the elements in a table the user would write:
//
// for (ptr = EnumerateGenericTable(Table, TRUE);
// ptr != NULL;
// ptr = EnumerateGenericTable(Table, FALSE)) {
// :
// }
//
// NOTE: This routine does not modify the structure of the tree, but saves
// the last node returned in the generic table itself, and for this
// reason requires exclusive access to the table for the duration of
// the enumeration.
//
_Must_inspect_result_
NTSYSAPI
PVOID
NTAPI
RtlEnumerateGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ BOOLEAN Restart
);
//
// The function EnumerateGenericTableWithoutSplaying will return to the
// caller one-by-one the elements of of a table. The return value is a
// pointer to the user defined structure associated with the element.
// The input parameter RestartKey indicates if the enumeration should
// start from the beginning or should return the next element. If the
// are no more new elements to return the return value is NULL. As an
// example of its use, to enumerate all of the elements in a table the
// user would write:
//
// RestartKey = NULL;
// for (ptr = EnumerateGenericTableWithoutSplaying(Table, &RestartKey);
// ptr != NULL;
// ptr = EnumerateGenericTableWithoutSplaying(Table, &RestartKey)) {
// :
// }
//
// If RestartKey is NULL, the package will start from the least entry in the
// table, otherwise it will start from the last entry returned.
//
// NOTE: This routine does not modify either the structure of the tree
// or the generic table itself, but must insure that no deletes
// occur for the duration of the enumeration, typically by having
// at least shared access to the table for the duration.
//
_Must_inspect_result_
NTSYSAPI
PVOID
NTAPI
RtlEnumerateGenericTableWithoutSplayingAvl(
_In_ PRTL_AVL_TABLE Table,
_Inout_ PVOID* RestartKey
);
//
// RtlLookupFirstMatchingElementGenericTableAvl will return the left-most
// element in the tree matching the data in Buffer. If, for example, the tree
// contains filenames there may exist several that differ only in case. A case-
// blind searcher can use this routine to position himself in the tree at the
// first match, and use an enumeration routine (such as RtlEnumerateGenericTableWithoutSplayingAvl
// to return each subsequent match.
//
_Must_inspect_result_
NTSYSAPI
PVOID
NTAPI
RtlLookupFirstMatchingElementGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ PVOID Buffer,
_Out_ PVOID* RestartKey
);
//
// The function EnumerateGenericTableLikeADirectory will return to the
// caller one-by-one the elements of of a table. The return value is a
// pointer to the user defined structure associated with the element.
// The input parameter RestartKey indicates if the enumeration should
// start from the beginning or should return the next element. If the
// are no more new elements to return the return value is NULL. As an
// example of its use, to enumerate all of the elements in a table the
// user would write:
//
// RestartKey = NULL;
// for (ptr = EnumerateGenericTableLikeADirectory(Table, &RestartKey, ...);
// ptr != NULL;
// ptr = EnumerateGenericTableLikeADirectory(Table, &RestartKey, ...)) {
// :
// }
//
// If RestartKey is NULL, the package will start from the least entry in the
// table, otherwise it will start from the last entry returned.
//
// NOTE: This routine does not modify either the structure of the tree
// or the generic table itself. The table must only be acquired
// shared for the duration of this call, and all synchronization
// may optionally be dropped between calls. Enumeration is always
// correctly resumed in the most efficient manner possible via the
// IN OUT parameters provided.
//
// ****** Explain NextFlag. Directory enumeration resumes from a key
// requires more thought. Also need the match pattern and IgnoreCase.
// Should some structure be introduced to carry it all?
//
_Must_inspect_result_
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 function GetElementGenericTable will return the i'th element
// inserted in the generic table. I = 0 implies the first element,
// I = (RtlNumberGenericTableElements(Table)-1) will return the last element
// inserted into the generic table. The type of I is ULONG. Values
// of I > than (NumberGenericTableElements(Table)-1) will return NULL. If
// an arbitrary element is deleted from the generic table it will cause
// all elements inserted after the deleted element to "move up".
_Must_inspect_result_
NTSYSAPI
PVOID
NTAPI
RtlGetElementGenericTableAvl(
_In_ PRTL_AVL_TABLE Table,
_In_ ULONG I
);
//
// The function NumberGenericTableElements returns a ULONG value
// which is the number of generic table elements currently inserted
// in the generic table.
NTSYSAPI
ULONG
NTAPI
RtlNumberGenericTableElementsAvl(
_In_ PRTL_AVL_TABLE Table
);
//
// The function IsGenericTableEmpty will return to the caller TRUE if
// the input table is empty (i.e., does not contain any elements) and
// FALSE otherwise.
//
//
// Generic extensions for using generic structures with the avl libraries.
//
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlIsGenericTableEmptyAvl(
_In_ PRTL_AVL_TABLE Table
);
#endif // !_KERNEL_MODE
//
// SPlay linked
//
#ifndef _KERNEL_MODE
//
// Define the splay links and the associated manipuliation macros and
// routines. Note that the splay_links should be an opaque type.
// Routine are provided to traverse and manipulate the structure.
//
typedef struct _RTL_SPLAY_LINKS {
struct _RTL_SPLAY_LINKS* Parent;
struct _RTL_SPLAY_LINKS* LeftChild;
struct _RTL_SPLAY_LINKS* RightChild;
} RTL_SPLAY_LINKS;
typedef RTL_SPLAY_LINKS* PRTL_SPLAY_LINKS;
#if !defined(MIDL_PASS) && !defined(SORTPP_PASS)
FORCEINLINE
VOID
RtlInitializeSplayLinks(
_Out_ PRTL_SPLAY_LINKS Links
)
//++
//
// The procedure InitializeSplayLinks takes as input a pointer to
// splay link and initializes its substructure. All splay link nodes must
// be initialized before they are used in the different splay routines and
// macros.
//
//--
{
Links->Parent = Links;
Links->LeftChild = NULL;
Links->RightChild = NULL;
}
#endif // !defined(MIDL_PASS) && !defined(SORTPP_PASS)
//
// The macro function Parent takes as input a pointer to a splay link in a
// tree and returns a pointer to the splay link of the parent of the input
// node. If the input node is the root of the tree the return value is
// equal to the input value.
//
// PRTL_SPLAY_LINKS
// RtlParent (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlParent(Links) ( \
(PRTL_SPLAY_LINKS)(Links)->Parent \
)
//
// The macro function LeftChild takes as input a pointer to a splay link in
// a tree and returns a pointer to the splay link of the left child of the
// input node. If the left child does not exist, the return value is NULL.
//
// PRTL_SPLAY_LINKS
// RtlLeftChild (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlLeftChild(Links) ( \
(PRTL_SPLAY_LINKS)(Links)->LeftChild \
)
//
// The macro function RightChild takes as input a pointer to a splay link
// in a tree and returns a pointer to the splay link of the right child of
// the input node. If the right child does not exist, the return value is
// NULL.
//
// PRTL_SPLAY_LINKS
// RtlRightChild (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlRightChild(Links) ( \
(PRTL_SPLAY_LINKS)(Links)->RightChild \
)
//
// The macro function IsRoot takes as input a pointer to a splay link
// in a tree and returns TRUE if the input node is the root of the tree,
// otherwise it returns FALSE.
//
// BOOLEAN
// RtlIsRoot (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlIsRoot(Links) ( \
(RtlParent(Links) == (PRTL_SPLAY_LINKS)(Links)) \
)
//
// The macro function IsLeftChild takes as input a pointer to a splay link
// in a tree and returns TRUE if the input node is the left child of its
// parent, otherwise it returns FALSE.
//
// BOOLEAN
// RtlIsLeftChild (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlIsLeftChild(Links) ( \
(RtlLeftChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) \
)
//
// The macro function IsRightChild takes as input a pointer to a splay link
// in a tree and returns TRUE if the input node is the right child of its
// parent, otherwise it returns FALSE.
//
// BOOLEAN
// RtlIsRightChild (
// PRTL_SPLAY_LINKS Links
// );
//
#define RtlIsRightChild(Links) ( \
(RtlRightChild(RtlParent(Links)) == (PRTL_SPLAY_LINKS)(Links)) \
)
#if !defined(MIDL_PASS) && !defined(SORTPP_PASS)
FORCEINLINE
VOID
RtlInsertAsLeftChild(
_Inout_ PRTL_SPLAY_LINKS ParentLinks,
_Inout_ PRTL_SPLAY_LINKS ChildLinks
)
//++
//
// The procedure InsertAsLeftChild takes as input a pointer to a splay
// link in a tree and a pointer to a node not in a tree. It inserts the
// second node as the left child of the first node. The first node must not
// already have a left child, and the second node must not already have a
// parent.
//
//--
{
ParentLinks->LeftChild = ChildLinks;
ChildLinks->Parent = ParentLinks;
}
FORCEINLINE
VOID
RtlInsertAsRightChild(
_Inout_ PRTL_SPLAY_LINKS ParentLinks,
_Inout_ PRTL_SPLAY_LINKS ChildLinks
)
//++
//
// The procedure InsertAsRightChild takes as input a pointer to a splay
// link in a tree and a pointer to a node not in a tree. It inserts the
// second node as the right child of the first node. The first node must not
// already have a right child, and the second node must not already have a
// parent.
//
//--
{
ParentLinks->RightChild = ChildLinks;
ChildLinks->Parent = ParentLinks;
}
#endif // !defined(MIDL_PASS) && !defined(SORTPP_PASS)
//
// The Splay function takes as input a pointer to a splay link in a tree
// and splays the tree. Its function return value is a pointer to the
// root of the splayed tree.
//
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlSplay(
_Inout_ PRTL_SPLAY_LINKS Links
);
//
// The Delete function takes as input a pointer to a splay link in a tree
// and deletes that node from the tree. Its function return value is a
// pointer to the root of the tree. If the tree is now empty, the return
// value is NULL.
//
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlDelete(
_In_ PRTL_SPLAY_LINKS Links
);
//
// The DeleteNoSplay function takes as input a pointer to a splay link in a tree,
// the caller's pointer to the root of the tree and deletes that node from the
// tree. Upon return the caller's pointer to the root node will correctly point
// at the root of the tree.
//
// It operationally differs from RtlDelete only in that it will not splay the tree.
//
NTSYSAPI
VOID
NTAPI
RtlDeleteNoSplay(
_In_ PRTL_SPLAY_LINKS Links,
_Inout_ PRTL_SPLAY_LINKS* Root
);
//
// The SubtreeSuccessor function takes as input a pointer to a splay link
// in a tree and returns a pointer to the successor of the input node of
// the substree rooted at the input node. If there is not a successor, the
// return value is NULL.
//
_Must_inspect_result_
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlSubtreeSuccessor(
_In_ PRTL_SPLAY_LINKS Links
);
//
// The SubtreePredecessor function takes as input a pointer to a splay link
// in a tree and returns a pointer to the predecessor of the input node of
// the substree rooted at the input node. If there is not a predecessor,
// the return value is NULL.
//
_Must_inspect_result_
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlSubtreePredecessor(
_In_ PRTL_SPLAY_LINKS Links
);
//
// The RealSuccessor function takes as input a pointer to a splay link
// in a tree and returns a pointer to the successor of the input node within
// the entire tree. If there is not a successor, the return value is NULL.
//
_Must_inspect_result_
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlRealSuccessor(
_In_ PRTL_SPLAY_LINKS Links
);
//
// The RealPredecessor function takes as input a pointer to a splay link
// in a tree and returns a pointer to the predecessor of the input node
// within the entire tree. If there is not a predecessor, the return value
// is NULL.
//
_Must_inspect_result_
NTSYSAPI
PRTL_SPLAY_LINKS
NTAPI
RtlRealPredecessor(
_In_ PRTL_SPLAY_LINKS Links
);
#endif // !_KERNEL_MODE
//
// Generic table
//
#ifndef _KERNEL_MODE
//
// Define the generic table package. Note a generic table should really
// be an opaque type. We provide routines to manipulate the structure.
//
// A generic table is package for inserting, deleting, and looking up elements
// in a table (e.g., in a symbol table). To use this package the user
// defines the structure of the elements stored in the table, provides a
// comparison function, a memory allocation function, and a memory
// deallocation function.
//
// Note: the user compare function must impose a complete ordering among
// all of the elements, and the table does not allow for duplicate entries.
//
//
// Do not do the following defines if using Avl
//
#ifndef RTL_USE_AVL_TABLES
//
// Add an empty typedef so that functions can reference the
// a pointer to the generic table struct before it is declared.
//
struct _RTL_GENERIC_TABLE;
//
// The comparison function takes as input pointers to elements containing
// user defined structures and returns the results of comparing the two
// elements.
//
typedef
_IRQL_requires_same_
_Function_class_(RTL_GENERIC_COMPARE_ROUTINE)
RTL_GENERIC_COMPARE_RESULTS
NTAPI
RTL_GENERIC_COMPARE_ROUTINE(
_In_ struct _RTL_GENERIC_TABLE* Table,
_In_ PVOID FirstStruct,
_In_ PVOID SecondStruct
);
typedef RTL_GENERIC_COMPARE_ROUTINE* PRTL_GENERIC_COMPARE_ROUTINE;
//
// The allocation function is called by the generic table package whenever
// it needs to allocate memory for the table.
//
typedef
_IRQL_requires_same_
_Function_class_(RTL_GENERIC_ALLOCATE_ROUTINE)
__drv_allocatesMem(Mem)
PVOID
NTAPI
RTL_GENERIC_ALLOCATE_ROUTINE(
_In_ struct _RTL_GENERIC_TABLE* Table,
_In_ ULONG ByteSize
);
typedef RTL_GENERIC_ALLOCATE_ROUTINE* PRTL_GENERIC_ALLOCATE_ROUTINE;
//
// The deallocation function is called by the generic table package whenever
// it needs to deallocate memory from the table that was allocated by calling
// the user supplied allocation function.
//
typedef
_IRQL_requires_same_
_Function_class_(RTL_GENERIC_FREE_ROUTINE)
VOID
NTAPI
RTL_GENERIC_FREE_ROUTINE(
_In_ struct _RTL_GENERIC_TABLE* Table,
_In_ __drv_freesMem(Mem) _Post_invalid_ PVOID Buffer
);
typedef RTL_GENERIC_FREE_ROUTINE* PRTL_GENERIC_FREE_ROUTINE;
//
// To use the generic table package the user declares a variable of type
// GENERIC_TABLE and then uses the routines described below to initialize
// the table and to manipulate the table. Note that the generic table
// should really be an opaque type.
//
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;
typedef RTL_GENERIC_TABLE* PRTL_GENERIC_TABLE;
//
// The procedure InitializeGenericTable takes as input an uninitialized
// generic table variable and pointers to the three user supplied routines.
// This must be called for every individual generic table variable before
// it can be used.
//
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 function InsertElementGenericTable will insert a new element
// in a table. It does this by allocating space for the new element
// (this includes splay links), inserting the element in the table, and
// then returning to the user a pointer to the new element. If an element
// with the same key already exists in the table the return value is a pointer
// to the old element. The optional output parameter NewElement is used
// to indicate if the element previously existed in the table. Note: the user
// supplied Buffer is only used for searching the table, upon insertion its
// contents are copied to the newly created element. This means that
// pointer to the input buffer will not point to the new element.
//
NTSYSAPI
PVOID
NTAPI
RtlInsertElementGenericTable(
_In_ PRTL_GENERIC_TABLE Table,
_In_reads_bytes_(BufferSize) PVOID Buffer,
_In_ ULONG BufferSize,
_Out_opt_ PBOOLEAN NewElement
);
//
// The function InsertElementGenericTableFull will insert a new element
// in a table. It does this by allocating space for the new element
// (this includes splay links), inserting the element in the table, and
// then returning to the user a pointer to the new element. If an element
// with the same key already exists in the table the return value is a pointer
// to the old element. The optional output parameter NewElement is used
// to indicate if the element previously existed in the table. Note: the user
// supplied Buffer is only used for searching the table, upon insertion its
// contents are copied to the newly created element. This means that
// pointer to the input buffer will not point to the new element.
// This routine is passed the NodeOrParent and SearchResult from a
// previous RtlLookupElementGenericTableFull.
//
NTSYSAPI
PVOID
NTAPI
RtlInsertElementGenericTableFull(
_In_ PRTL_GENERIC_TABLE Table,
_In_reads_bytes_(BufferSize) PVOID Buffer,
_In_ ULONG BufferSize,
_Out_opt_ PBOOLEAN NewElement,
_In_ PVOID NodeOrParent,
_In_ TABLE_SEARCH_RESULT SearchResult
);
//
// The function DeleteElementGenericTable will find and delete an element
// from a generic table. If the element is located and deleted the return
// value is TRUE, otherwise if the element is not located the return value
// is FALSE. The user supplied input buffer is only used as a key in
// locating the element in the table.
//
NTSYSAPI
BOOLEAN
NTAPI
RtlDeleteElementGenericTable(
_In_ PRTL_GENERIC_TABLE Table,
_In_ PVOID Buffer
);
//
// The function LookupElementGenericTable will find an element in a generic
// table. If the element is located the return value is a pointer to
// the user defined structure associated with the element, otherwise if
// the element is not located the return value is NULL. The user supplied
// input buffer is only used as a key in locating the element in the table.
//
_Must_inspect_result_
NTSYSAPI
PVOID
NTAPI
RtlLookupElementGenericTable(
_In_ PRTL_GENERIC_TABLE Table,
_In_ PVOID Buffer
);
//
// The function LookupElementGenericTableFull will find an element in a generic
// table. If the element is located the return value is a pointer to
// the user defined structure associated with the element. If the element is not
// located then a pointer to the parent for the insert location is returned. The
// user must look at the SearchResult value to determine which is being returned.
// The user can use the SearchResult and parent for a subsequent FullInsertElement
// call to optimize the insert.
//
NTSYSAPI
PVOID
NTAPI
RtlLookupElementGenericTableFull(
_In_ PRTL_GENERIC_TABLE Table,
_In_ PVOID Buffer,
_Out_ PVOID* NodeOrParent,
_Out_ TABLE_SEARCH_RESULT* SearchResult
);
//
// The function EnumerateGenericTable will return to the caller one-by-one
// the elements of of a table. The return value is a pointer to the user
// defined structure associated with the element. The input parameter
// Restart indicates if the enumeration should start from the beginning
// or should return the next element. If the are no more new elements to
// return the return value is NULL. As an example of its use, to enumerate
// all of the elements in a table the user would write:
//
// for (ptr = EnumerateGenericTable(Table, TRUE);
// ptr != NULL;
// ptr = EnumerateGenericTable(Table, FALSE)) {
// :
// }
//
//
// PLEASE NOTE:
//
// If you enumerate a GenericTable using RtlEnumerateGenericTable, you
// will flatten the table, turning it into a sorted linked list.
// To enumerate the table without perturbing the splay links, use
// RtlEnumerateGenericTableWithoutSplaying
_Must_inspect_result_
NTSYSAPI
PVOID
NTAPI
RtlEnumerateGenericTable(
_In_ PRTL_GENERIC_TABLE Table,
_In_ BOOLEAN Restart
);
//
// The function EnumerateGenericTableWithoutSplaying will return to the
// caller one-by-one the elements of of a table. The return value is a
// pointer to the user defined structure associated with the element.
// The input parameter RestartKey indicates if the enumeration should
// start from the beginning or should return the next element. If the
// are no more new elements to return the return value is NULL. As an
// example of its use, to enumerate all of the elements in a table the
// user would write:
//
// RestartKey = NULL;
// for (ptr = EnumerateGenericTableWithoutSplaying(Table, &RestartKey);
// ptr != NULL;
// ptr = EnumerateGenericTableWithoutSplaying(Table, &RestartKey)) {
// :
// }
//
// If RestartKey is NULL, the package will start from the least entry in the
// table, otherwise it will start from the last entry returned.
//
//
// Note that unlike RtlEnumerateGenericTable, this routine will NOT perturb
// the splay order of the tree.
//
_Must_inspect_result_
NTSYSAPI
PVOID
NTAPI
RtlEnumerateGenericTableWithoutSplaying(
_In_ PRTL_GENERIC_TABLE Table,
_Inout_ PVOID* RestartKey
);
//
// The function GetElementGenericTable will return the i'th element
// inserted in the generic table. I = 0 implies the first element,
// I = (RtlNumberGenericTableElements(Table)-1) will return the last element
// inserted into the generic table. The type of I is ULONG. Values
// of I > than (NumberGenericTableElements(Table)-1) will return NULL. If
// an arbitrary element is deleted from the generic table it will cause
// all elements inserted after the deleted element to "move up".
_Must_inspect_result_
NTSYSAPI
PVOID
NTAPI
RtlGetElementGenericTable(
_In_ PRTL_GENERIC_TABLE Table,
_In_ ULONG I
);
//
// The function NumberGenericTableElements returns a ULONG value
// which is the number of generic table elements currently inserted
// in the generic table.
NTSYSAPI
ULONG
NTAPI
RtlNumberGenericTableElements(
_In_ PRTL_GENERIC_TABLE Table
);
//
// The function IsGenericTableEmpty will return to the caller TRUE if
// the input table is empty (i.e., does not contain any elements) and
// FALSE otherwise.
//
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlIsGenericTableEmpty(
_In_ PRTL_GENERIC_TABLE Table
);
#endif // RTL_USE_AVL_TABLES
#endif // !_KERNEL_MODE
//
// Hash Table
//
#ifndef _KERNEL_MODE
//
// The hash table header structure can either be allocated
// by the caller, or by the hash table creation function itself.
// This flag indicates what was done at creation time.
//
#define RTL_HASH_ALLOCATED_HEADER 0x00000001
//
// The RTL_HASH_RESERVED_SIGNATURE is the signature used internally for
// enumerators. A caller can never assign this signature to
// valid entries.
//
#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;
//
// Some components want to see the actual signature and can use
// this macro to encapsulate that operation.
//
#define HASH_ENTRY_KEY(x) ((x)->Signature)
//
// Brief background on each of the parameters and their
// justification:
// 1. ChainHead stores the pointer to a bucket. This is needed since
// our hash chains are doubly-linked circular lists, and there is
// is no way to determine whether we've reached the end of the
// chain unless we store the pointer to the bucket itself. This
// is particularly used in walking the sub-list of entries returned
// by a lookup. We need to know when the sub-list has been
// completely returned.
// 2. PrevLinkage stores a pointer to the entry before the entry
// under consideration. The reason for storing the previous entry
// instead of the entry itself is for cases where a lookup fails
// and PrevLinkage actually stores the entry that would have been
// the previous entry, had the looked up entry existed. This can
// then be used to actually insert the entry at that place.
// 3. Signature is used primarily as a safety check in insertion.
// This field must match the Signature of the entry being inserted.
//
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;
//
// Inline functions first.
//
#if !defined(MIDL_PASS) && !defined(SORTPP_PASS)
#if (NTDDI_VERSION >= NTDDI_WIN7)
FORCEINLINE
VOID
RtlInitHashTableContext(
_Inout_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context
)
{
Context->ChainHead = NULL;
Context->PrevLinkage = NULL;
}
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
FORCEINLINE
VOID
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;
}
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
FORCEINLINE
void
RtlReleaseHashTableContext(
_Inout_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context
)
{
UNREFERENCED_PARAMETER(Context);
return;
}
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
FORCEINLINE
ULONG
RtlTotalBucketsHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
)
{
return HashTable->TableSize;
}
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
FORCEINLINE
ULONG
RtlNonEmptyBucketsHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
)
{
return HashTable->NonEmptyBuckets;
}
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
FORCEINLINE
ULONG
RtlEmptyBucketsHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
)
{
return HashTable->TableSize - HashTable->NonEmptyBuckets;
}
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
FORCEINLINE
ULONG
RtlTotalEntriesHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
)
{
return HashTable->NumEntries;
}
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
FORCEINLINE
ULONG
RtlActiveEnumeratorsHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
)
{
return HashTable->NumEnumerators;
}
#endif
#endif // !defined(MIDL_PASS) && !defined(SORTPP_PASS)
//
// Almost all the hash functions take in a Context.
// If a valid context is passed in, it will be used
// in executing the operation if possible. If a
// blank context is passed in, it will be initialized
// appropriately.
//
#if (NTDDI_VERSION >= NTDDI_WIN7)
_Must_inspect_result_
_Success_(return != 0)
NTSYSAPI
BOOLEAN
NTAPI
RtlCreateHashTable(
_Inout_ _When_(NULL == *HashTable, _At_(*HashTable, __drv_allocatesMem(Mem)))
PRTL_DYNAMIC_HASH_TABLE * HashTable,
_In_ ULONG Shift,
_Reserved_ ULONG Flags
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN8)
_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
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
NTSYSAPI
VOID
NTAPI
RtlDeleteHashTable(
_In_ _When_((HashTable->Flags & RTL_HASH_ALLOCATED_HEADER), __drv_freesMem(Mem) _Post_invalid_)
PRTL_DYNAMIC_HASH_TABLE HashTable
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
NTSYSAPI
BOOLEAN
NTAPI
RtlInsertEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_In_ __drv_aliasesMem PRTL_DYNAMIC_HASH_TABLE_ENTRY Entry,
_In_ ULONG_PTR Signature,
_Inout_opt_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
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
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
_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
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
_Must_inspect_result_
NTSYSAPI
PRTL_DYNAMIC_HASH_TABLE_ENTRY
NTAPI
RtlGetNextEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_In_ PRTL_DYNAMIC_HASH_TABLE_CONTEXT Context
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
NTSYSAPI
BOOLEAN
NTAPI
RtlInitEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Out_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
_Must_inspect_result_
NTSYSAPI
PRTL_DYNAMIC_HASH_TABLE_ENTRY
NTAPI
RtlEnumerateEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
NTSYSAPI
VOID
NTAPI
RtlEndEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
NTSYSAPI
BOOLEAN
NTAPI
RtlInitWeakEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Out_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
_Must_inspect_result_
NTSYSAPI
PRTL_DYNAMIC_HASH_TABLE_ENTRY
NTAPI
RtlWeaklyEnumerateEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
NTSYSAPI
VOID
NTAPI
RtlEndWeakEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
#endif
#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
NTSYSAPI
BOOLEAN
NTAPI
RtlInitStrongEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Out_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
#endif
#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
_Must_inspect_result_
NTSYSAPI
PRTL_DYNAMIC_HASH_TABLE_ENTRY
NTAPI
RtlStronglyEnumerateEntryHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
#endif
#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
NTSYSAPI
VOID
NTAPI
RtlEndStrongEnumerationHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable,
_Inout_ PRTL_DYNAMIC_HASH_TABLE_ENUMERATOR Enumerator
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
NTSYSAPI
BOOLEAN
NTAPI
RtlExpandHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
NTSYSAPI
BOOLEAN
NTAPI
RtlContractHashTable(
_In_ PRTL_DYNAMIC_HASH_TABLE HashTable
);
#endif
#endif // !_KERNEL_MODE
//
// RB Trees
//
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN8)
NTSYSAPI
VOID
NTAPI
RtlRbInsertNodeEx(
_In_ PRTL_RB_TREE Tree,
_In_opt_ PRTL_BALANCED_NODE Parent,
_In_ BOOLEAN Right,
_Out_ PRTL_BALANCED_NODE Node
);
NTSYSAPI
VOID
NTAPI
RtlRbRemoveNode(
_In_ PRTL_RB_TREE Tree,
_In_ PRTL_BALANCED_NODE Node
);
#endif
#endif // !_KERNEL_MODE
//
// Critical sections
//
#ifndef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeCriticalSection(
_Out_ PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeCriticalSectionAndSpinCount(
_Inout_ PRTL_CRITICAL_SECTION CriticalSection,
_In_ ULONG SpinCount
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteCriticalSection(
_Inout_ PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
NTSTATUS
NTAPI
RtlEnterCriticalSection(
_Inout_ PRTL_CRITICAL_SECTION CriticalSection
);
NTSYSAPI
NTSTATUS
NTAPI
RtlLeaveCriticalSection(
_Inout_ PRTL_CRITICAL_SECTION 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
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
NTSYSAPI
HANDLE
NTAPI
RtlQueryCriticalSectionOwner(
_In_ HANDLE EventHandle
);
#endif
NTSYSAPI
VOID
NTAPI
RtlCheckForOrphanedCriticalSections(
_In_ HANDLE ThreadHandle
);
#endif // !_KERNEL_MODE
//
// Resources
//
#ifndef _KERNEL_MODE
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
);
#endif // !_KERNEL_MODE
//
// Slim reader-writer locks, condition variables, and barriers
//
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_VISTA)
// winbase:InitializeSRWLock
NTSYSAPI
VOID
NTAPI
RtlInitializeSRWLock(
_Out_ PRTL_SRWLOCK SRWLock
);
// winbase:AcquireSRWLockExclusive
NTSYSAPI
VOID
NTAPI
RtlAcquireSRWLockExclusive(
_Inout_ PRTL_SRWLOCK SRWLock
);
// winbase:AcquireSRWLockShared
NTSYSAPI
VOID
NTAPI
RtlAcquireSRWLockShared(
_Inout_ PRTL_SRWLOCK SRWLock
);
// winbase:ReleaseSRWLockExclusive
NTSYSAPI
VOID
NTAPI
RtlReleaseSRWLockExclusive(
_Inout_ PRTL_SRWLOCK SRWLock
);
// winbase:ReleaseSRWLockShared
NTSYSAPI
VOID
NTAPI
RtlReleaseSRWLockShared(
_Inout_ PRTL_SRWLOCK SRWLock
);
// winbase:TryAcquireSRWLockExclusive
NTSYSAPI
BOOLEAN
NTAPI
RtlTryAcquireSRWLockExclusive(
_Inout_ PRTL_SRWLOCK SRWLock
);
// winbase:TryAcquireSRWLockShared
NTSYSAPI
BOOLEAN
NTAPI
RtlTryAcquireSRWLockShared(
_Inout_ PRTL_SRWLOCK SRWLock
);
#if (NTDDI_VERSION >= NTDDI_WIN7)
// rev
NTSYSAPI
VOID
NTAPI
RtlAcquireReleaseSRWLockExclusive(
_Inout_ PRTL_SRWLOCK SRWLock
);
#endif //(NTDDI_VERSION >= NTDDI_WIN7)
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
#if (NTDDI_VERSION >= NTDDI_VISTA)
// 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
);
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
// 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
#if (NTDDI_VERSION >= NTDDI_VISTA)
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
);
#endif //(NTDDI_VERSION >= NTDDI_VISTA)
#endif // !_KERNEL_MODE
//
// Wait on address
//
#ifndef _KERNEL_MODE
// begin_rev
#if (NTDDI_VERSION >= NTDDI_WIN8)
NTSYSAPI
NTSTATUS
NTAPI
RtlWaitOnAddress(
_In_ volatile VOID* Address,
_In_ PVOID CompareAddress,
_In_ SIZE_T AddressSize,
_In_opt_ PLARGE_INTEGER Timeout
);
NTSYSAPI
VOID
NTAPI
RtlWakeAddressAll(
_In_ PVOID Address
);
NTSYSAPI
VOID
NTAPI
RtlWakeAddressSingle(
_In_ PVOID Address
);
#endif
// end_rev
#endif // !_KERNEL_MODE
//
// Strings
//
#ifndef ANSI_STRING_MAX_BYTES
#define ANSI_STRING_MAX_BYTES ((USHORT)65535)
#endif // ANSI_STRING_MAX_BYTES
#ifndef ANSI_STRING_MAX_CHARS
#define ANSI_STRING_MAX_CHARS ANSI_STRING_MAX_BYTES
#endif
#ifdef _KERNEL_MODE
#include <ntstrsafe.h>
#endif
#ifndef _KERNEL_MODE
_At_(AnsiString->Buffer, _Post_equal_to_(Buffer))
_At_(AnsiString->Length, _Post_equal_to_(0))
_At_(AnsiString->MaximumLength, _Post_equal_to_(BufferSize))
FORCEINLINE
VOID
RtlInitEmptyAnsiString(
_Out_ PANSI_STRING AnsiString,
_Pre_maybenull_ _Pre_readable_size_(BufferSize) __drv_aliasesMem PCHAR Buffer,
_In_ USHORT BufferSize
)
{
AnsiString->MaximumLength = BufferSize;
AnsiString->Buffer = Buffer;
AnsiString->Length = 0;
}
#endif // !_KERNEL_MODE
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlInitString(
_Out_ PSTRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCSZ SourceString
);
#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlInitStringEx(
_Out_ PSTRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCSZ SourceString
);
#endif
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlInitAnsiString(
_Out_ PANSI_STRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCSZ SourceString
);
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlInitAnsiStringEx(
_Out_ PANSI_STRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCSZ SourceString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlFreeAnsiString(
_Inout_ _At_(AnsiString->Buffer, _Frees_ptr_opt_)
PANSI_STRING AnsiString
);
#if (NTDDI_VERSION >= NTDDI_WIN10_VB)
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlInitUTF8String(
_Out_ PUTF8_STRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCSZ SourceString
);
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlInitUTF8StringEx(
_Out_ PUTF8_STRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCSZ SourceString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlFreeUTF8String(
_Inout_ _At_(utf8String->Buffer, _Frees_ptr_opt_)
PUTF8_STRING utf8String
);
#endif
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlFreeOemString(
_Inout_ _At_(OemString->Buffer, _Frees_ptr_opt_)
POEM_STRING OemString
);
NTSYSAPI
VOID
NTAPI
RtlCopyString(
_Out_ PSTRING DestinationString,
_In_opt_ const STRING* SourceString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
CHAR
NTAPI
RtlUpperChar(
_In_ CHAR Character
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
LONG
NTAPI
RtlCompareString(
_In_ const STRING* String1,
_In_ const STRING* String2,
_In_ BOOLEAN CaseInSensitive
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualString(
_In_ const STRING* String1,
_In_ const STRING* String2,
_In_ BOOLEAN CaseInSensitive
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlPrefixString(
_In_ const STRING* String1,
_In_ const STRING* String2,
_In_ BOOLEAN CaseInSensitive
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendStringToString(
_Inout_ PSTRING Destination,
_In_ const STRING* Source
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendAsciizToString(
_In_ PSTRING Destination,
_In_opt_ PCSTR Source
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlUpperString(
_Inout_ PSTRING DestinationString,
_In_ const STRING* SourceString
);
FORCEINLINE
BOOLEAN
RtlIsNullOrEmptyUnicodeString(
_In_opt_ PUNICODE_STRING String
)
{
return !String || String->Length == 0;
}
#ifndef _KERNEL_MODE
_At_(UnicodeString->Buffer, _Post_equal_to_(Buffer))
_At_(UnicodeString->Length, _Post_equal_to_(0))
_At_(UnicodeString->MaximumLength, _Post_equal_to_(BufferSize))
FORCEINLINE
VOID
RtlInitEmptyUnicodeString(
_Out_ PUNICODE_STRING UnicodeString,
_Writable_bytes_(BufferSize)
_When_(BufferSize != 0, _Notnull_)
__drv_aliasesMem PWCHAR Buffer,
_In_ USHORT BufferSize
)
{
UnicodeString->Buffer = Buffer;
UnicodeString->MaximumLength = BufferSize;
UnicodeString->Length = 0;
}
#endif // !_KERNEL_MODE
_IRQL_requires_max_(DISPATCH_LEVEL)
_At_(DestinationString->Buffer, _Post_equal_to_(SourceString))
_At_(DestinationString->Length, _Post_equal_to_(_String_length_(SourceString) * sizeof(WCHAR)))
_At_(DestinationString->MaximumLength, _Post_equal_to_((_String_length_(SourceString) + 1) * sizeof(WCHAR)))
NTSYSAPI
VOID
NTAPI
RtlInitUnicodeString(
_Out_ PUNICODE_STRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCWSTR SourceString
);
#ifndef RtlInitUnicodeStringEx
_IRQL_requires_max_(DISPATCH_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlInitUnicodeStringEx(
_Out_ PUNICODE_STRING DestinationString,
_In_opt_z_ __drv_aliasesMem PCWSTR SourceString
);
#endif
_IRQL_requires_max_(APC_LEVEL)
_Success_(return != 0)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlCreateUnicodeString(
_Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem))
PUNICODE_STRING DestinationString,
_In_z_ PCWSTR SourceString
);
NTSYSAPI
BOOLEAN
NTAPI
RtlCreateUnicodeStringFromAsciiz(
_Out_ PUNICODE_STRING DestinationString,
_In_ PCSTR SourceString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlFreeUnicodeString(
_Inout_ _At_(UnicodeString->Buffer, _Frees_ptr_opt_)
PUNICODE_STRING UnicodeString
);
#ifndef _KERNEL_MODE
#define RTL_DUPLICATE_UNICODE_STRING_NULL_TERMINATE (0x00000001)
#define RTL_DUPLICATE_UNICODE_STRING_ALLOCATE_NULL_STRING (0x00000002)
#endif // !_KERNEL_MODE
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlDuplicateUnicodeString(
_In_ ULONG Flags,
_In_ PCUNICODE_STRING StringIn,
_Out_ _At_(StringOut->Buffer, __drv_allocatesMem(Mem))
PUNICODE_STRING StringOut
);
_Unchanged_(DestinationString->Buffer)
_Unchanged_(DestinationString->MaximumLength)
_At_(DestinationString->Length,
_When_(SourceString->Length > DestinationString->MaximumLength,
_Post_equal_to_(DestinationString->MaximumLength))
_When_(SourceString->Length <= DestinationString->MaximumLength,
_Post_equal_to_(SourceString->Length)))
NTSYSAPI
VOID
NTAPI
RtlCopyUnicodeString(
_Inout_ PUNICODE_STRING DestinationString,
_In_opt_ PCUNICODE_STRING SourceString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
WCHAR
NTAPI
RtlUpcaseUnicodeChar(
_In_ WCHAR SourceCharacter
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
WCHAR
NTAPI
RtlDowncaseUnicodeChar(
_In_ WCHAR SourceCharacter
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
LONG
NTAPI
RtlCompareUnicodeString(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2,
_In_ BOOLEAN CaseInSensitive
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_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
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualUnicodeString(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2,
_In_ BOOLEAN CaseInSensitive
);
#ifndef _KERNEL_MODE
#define HASH_STRING_ALGORITHM_DEFAULT (0)
#define HASH_STRING_ALGORITHM_X65599 (1)
#define HASH_STRING_ALGORITHM_INVALID (0xffffffff)
#endif // !_KERNEL_MODE
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlHashUnicodeString(
_In_ PCUNICODE_STRING String,
_In_ BOOLEAN CaseInSensitive,
_In_ ULONG HashAlgorithm,
_Out_ PULONG HashValue
);
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlValidateUnicodeString(
_Reserved_ ULONG Flags,
_In_ PCUNICODE_STRING String
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlPrefixUnicodeString(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2,
_In_ BOOLEAN CaseInSensitive
);
#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlSuffixUnicodeString(
_In_ PCUNICODE_STRING String1,
_In_ PCUNICODE_STRING String2,
_In_ BOOLEAN CaseInSensitive
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10)
_Must_inspect_result_
NTSYSAPI
PWCHAR
NTAPI
RtlFindUnicodeSubstring(
_In_ PUNICODE_STRING FullString,
_In_ PUNICODE_STRING SearchString,
_In_ BOOLEAN CaseInSensitive
);
#endif
#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
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlFindCharInUnicodeString(
_In_ ULONG Flags,
_In_ PUNICODE_STRING StringToSearch,
_In_ PUNICODE_STRING CharSet,
_Out_ PUSHORT NonInclusivePrefixLength
);
_Success_(1)
_Unchanged_(Destination->MaximumLength)
_Unchanged_(Destination->Buffer)
_When_(_Old_(Destination->Length) + Source->Length <= Destination->MaximumLength,
_At_(Destination->Length,
_Post_equal_to_(_Old_(Destination->Length) + Source->Length))
_At_(return, _Out_range_(== , 0)))
_When_(_Old_(Destination->Length) + Source->Length > Destination->MaximumLength,
_Unchanged_(Destination->Length)
_At_(return, _Out_range_(< , 0)))
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendUnicodeStringToString(
_Inout_ PUNICODE_STRING Destination,
_In_ PCUNICODE_STRING Source
);
_Success_(1)
_Unchanged_(Destination->MaximumLength)
_Unchanged_(Destination->Buffer)
_When_(_Old_(Destination->Length) + _String_length_(Source) * sizeof(WCHAR) <= Destination->MaximumLength,
_At_(Destination->Length,
_Post_equal_to_(_Old_(Destination->Length) + _String_length_(Source) * sizeof(WCHAR)))
_At_(return, _Out_range_(== , 0)))
_When_(_Old_(Destination->Length) + _String_length_(Source) * sizeof(WCHAR) > Destination->MaximumLength,
_Unchanged_(Destination->Length)
_At_(return, _Out_range_(< , 0)))
NTSYSAPI
NTSTATUS
NTAPI
RtlAppendUnicodeToString(
_Inout_ PUNICODE_STRING Destination,
_In_opt_z_ PCWSTR Source
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_When_(AllocateDestinationString, _Must_inspect_result_)
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUNICODE_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_When_(AllocateDestinationString, _Must_inspect_result_)
NTSYSAPI
NTSTATUS
NTAPI
RtlDowncaseUnicodeString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUNICODE_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
NTSYSAPI
VOID
NTAPI
RtlEraseUnicodeString(
_Inout_ PUNICODE_STRING String
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlAnsiStringToUnicodeString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUNICODE_STRING DestinationString,
_In_ PCANSI_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
_When_(AllocateDestinationString,
_At_(DestinationString->MaximumLength,
_Out_range_(<= , (SourceString->MaximumLength / sizeof(WCHAR)))))
_When_(!AllocateDestinationString,
_At_(DestinationString->Buffer, _Const_)
_At_(DestinationString->MaximumLength, _Const_))
_IRQL_requires_max_(PASSIVE_LEVEL)
_When_(AllocateDestinationString, _Must_inspect_result_)
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToAnsiString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PANSI_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
#if (NTDDI_VERSION >= NTDDI_WIN7)
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlUTF8ToUnicodeN(
_Out_writes_bytes_to_(UnicodeStringMaxByteCount, *UnicodeStringActualByteCount) PWSTR UnicodeStringDestination,
_In_ ULONG UnicodeStringMaxByteCount,
_Out_ PULONG UnicodeStringActualByteCount,
_In_reads_bytes_(UTF8StringByteCount) PCCH UTF8StringSource,
_In_ ULONG UTF8StringByteCount
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeToUTF8N(
_Out_writes_bytes_to_(UTF8StringMaxByteCount, *UTF8StringActualByteCount) PCHAR UTF8StringDestination,
_In_ ULONG UTF8StringMaxByteCount,
_Out_ PULONG UTF8StringActualByteCount,
_In_reads_bytes_(UnicodeStringByteCount) PCWCH UnicodeStringSource,
_In_ ULONG UnicodeStringByteCount
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10_VB)
_When_(AllocateDestinationString,
_At_(DestinationString->MaximumLength, _Out_range_(<= , (SourceString->MaximumLength / sizeof(WCHAR)))))
_When_(!AllocateDestinationString,
_At_(DestinationString->Buffer, _Const_)
_At_(DestinationString->MaximumLength, _Const_))
_IRQL_requires_max_(PASSIVE_LEVEL)
_When_(AllocateDestinationString, _Must_inspect_result_)
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToUTF8String(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUTF8_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlUTF8StringToUnicodeString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUNICODE_STRING DestinationString,
_In_ PUTF8_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
#else // NTDDI_VERSION >= NTDDI_WIN10_VB
_When_(AllocateDestinationString,
_At_(DestinationString->MaximumLength, _Out_range_(<= , (SourceString->MaximumLength / sizeof(WCHAR)))))
_When_(!AllocateDestinationString,
_At_(DestinationString->Buffer, _Const_)
_At_(DestinationString->MaximumLength, _Const_))
_IRQL_requires_max_(PASSIVE_LEVEL)
_When_(AllocateDestinationString, _Must_inspect_result_)
FORCEINLINE
NTSTATUS
NTAPI
RtlUnicodeStringToUTF8String(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUTF8_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
)
{
NTSTATUS Status = STATUS_SUCCESS;
do
{
ULONG ActualByteCount = 0ul;
Status = RtlUnicodeToUTF8N(NULL, 0, &ActualByteCount, SourceString->Buffer, SourceString->Length);
if (ActualByteCount == 0ul)
{
break;
}
ActualByteCount += sizeof ANSI_NULL;
if (ActualByteCount >= ANSI_STRING_MAX_BYTES)
{
return STATUS_INVALID_PARAMETER_2;
}
if (AllocateDestinationString)
{
#ifdef _KERNEL_MODE
#pragma warning(suppress: 4996)
DestinationString->Buffer = (PSTR)ExAllocatePool(PagedPool, ActualByteCount);
#else
DestinationString->Buffer = (PSTR)LocalAlloc(LPTR, ActualByteCount);
#endif
if (DestinationString->Buffer == NULL)
{
Status = STATUS_NO_MEMORY;
break;
}
DestinationString->MaximumLength = (USHORT)ActualByteCount;
RtlSecureZeroMemory(DestinationString->Buffer, ActualByteCount);
}
else
{
if (DestinationString->MaximumLength < ActualByteCount)
{
Status = STATUS_BUFFER_OVERFLOW;
break;
}
}
Status = RtlUnicodeToUTF8N(DestinationString->Buffer, DestinationString->MaximumLength, &ActualByteCount, SourceString->Buffer, SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
{
RtlFreeAnsiString(DestinationString);
}
break;
}
if (ActualByteCount > DestinationString->MaximumLength)
{
Status = STATUS_BUFFER_OVERFLOW;
break;
}
DestinationString->Length = (USHORT)ActualByteCount;
DestinationString->Buffer[ActualByteCount / sizeof ANSI_NULL] = ANSI_NULL;
} while (false);
return Status;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
FORCEINLINE
NTSTATUS
NTAPI
RtlUTF8StringToUnicodeString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUNICODE_STRING DestinationString,
_In_ PUTF8_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
)
{
NTSTATUS Status = STATUS_SUCCESS;
do
{
ULONG ActualByteCount = 0ul;
Status = RtlUTF8ToUnicodeN(NULL, 0, &ActualByteCount, SourceString->Buffer, SourceString->Length);
if (ActualByteCount == 0ul)
{
break;
}
ActualByteCount += sizeof UNICODE_NULL;
if (ActualByteCount >= UNICODE_STRING_MAX_BYTES)
{
return STATUS_INVALID_PARAMETER_2;
}
if (AllocateDestinationString)
{
#ifdef _KERNEL_MODE
#pragma warning(suppress: 4996)
DestinationString->Buffer = (PWCH)ExAllocatePool(PagedPool, ActualByteCount);
#else
DestinationString->Buffer = (PWCH)LocalAlloc(LPTR, ActualByteCount);
#endif
if (DestinationString->Buffer == NULL)
{
Status = STATUS_NO_MEMORY;
break;
}
DestinationString->MaximumLength = (USHORT)ActualByteCount;
RtlSecureZeroMemory(DestinationString->Buffer, ActualByteCount);
}
else
{
if (DestinationString->MaximumLength < ActualByteCount)
{
Status = STATUS_BUFFER_OVERFLOW;
break;
}
}
Status = RtlUTF8ToUnicodeN(DestinationString->Buffer, DestinationString->MaximumLength, &ActualByteCount, SourceString->Buffer, SourceString->Length);
if (!NT_SUCCESS(Status))
{
if (AllocateDestinationString)
{
RtlFreeUnicodeString(DestinationString);
}
break;
}
if (ActualByteCount > DestinationString->MaximumLength)
{
Status = STATUS_BUFFER_OVERFLOW;
break;
}
DestinationString->Length = (USHORT)ActualByteCount;
DestinationString->Buffer[ActualByteCount / sizeof UNICODE_NULL] = UNICODE_NULL;
} while (false);
return Status;
}
#endif //NTDDI_VERSION < NTDDI_WIN10_VB
NTSYSAPI
WCHAR
NTAPI
RtlAnsiCharToUnicodeChar(
_Inout_ PUCHAR * SourceCharacter
);
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeStringToAnsiString(
_Inout_ PANSI_STRING DestinationString,
_In_ PUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlOemStringToUnicodeString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUNICODE_STRING DestinationString,
_In_ PCOEM_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
_When_(AllocateDestinationString, _At_(DestinationString->Buffer, _Post_notnull_ __drv_allocatesMem(Mem)))
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToOemString(
_When_(AllocateDestinationString, _Out_)
_When_(!AllocateDestinationString, _Inout_)
POEM_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeStringToOemString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
POEM_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlOemStringToCountedUnicodeString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
PUNICODE_STRING DestinationString,
_In_ PCOEM_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToCountedOemString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
POEM_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlUpcaseUnicodeStringToCountedOemString(
_When_(AllocateDestinationString, _Out_ _At_(DestinationString->Buffer, __drv_allocatesMem(Mem)))
_When_(!AllocateDestinationString, _Inout_)
POEM_STRING DestinationString,
_In_ PCUNICODE_STRING SourceString,
_In_ BOOLEAN AllocateDestinationString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
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
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlMultiByteToUnicodeSize(
_Out_ PULONG BytesInUnicodeString,
_In_reads_bytes_(BytesInMultiByteString) PCSTR MultiByteString,
_In_ ULONG BytesInMultiByteString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
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
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeToMultiByteSize(
_Out_ PULONG BytesInMultiByteString,
_In_reads_bytes_(BytesInUnicodeString) PCWCH UnicodeString,
_In_ ULONG BytesInUnicodeString
);
_IRQL_requires_max_(PASSIVE_LEVEL)
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
);
_IRQL_requires_max_(PASSIVE_LEVEL)
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
);
_IRQL_requires_max_(PASSIVE_LEVEL)
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
);
_IRQL_requires_max_(PASSIVE_LEVEL)
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
);
//
// String manipulation routines
//
_IRQL_requires_max_(PASSIVE_LEVEL)
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
);
_IRQL_requires_max_(PASSIVE_LEVEL)
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
);
_IRQL_requires_max_(PASSIVE_LEVEL)
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
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlInitCodePageTable(
_In_reads_opt_(2) PUSHORT TableBase,
_Inout_ PCPTABLEINFO CodePageTable
);
#ifndef _KERNEL_MODE
NTSYSAPI
VOID
NTAPI
RtlInitNlsTables(
_In_ PUSHORT AnsiNlsBase,
_In_ PUSHORT OemNlsBase,
_In_ PUSHORT LanguageNlsBase,
_Out_ PNLSTABLEINFO TableInfo // PCPTABLEINFO?
);
NTSYSAPI
VOID
NTAPI
RtlResetRtlTranslations(
_In_ PNLSTABLEINFO TableInfo
);
NTSYSAPI
BOOLEAN
NTAPI
RtlIsTextUnicode(
_In_ PVOID Buffer,
_In_ ULONG Size,
_Inout_opt_ PULONG Result
);
#endif // !_KERNEL_MODE
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;
#if (NTDDI_VERSION >= NTDDI_VISTA)
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
);
#endif
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN7)
// ntifs:FsRtlIsNameInExpression
NTSYSAPI
BOOLEAN
NTAPI
RtlIsNameInExpression(
_In_ PUNICODE_STRING Expression,
_In_ PUNICODE_STRING Name,
_In_ BOOLEAN IgnoreCase,
_In_opt_ PWCH UpcaseTable
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10_RS4)
// ntifs:FsRtlIsNameInUnUpcasedExpression
NTSYSAPI
BOOLEAN
NTAPI
RtlIsNameInUnUpcasedExpression(
_In_ PUNICODE_STRING Expression,
_In_ PUNICODE_STRING Name,
_In_ BOOLEAN IgnoreCase,
_In_opt_ PWCH UpcaseTable
);
#endif
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualDomainName(
_In_ PUNICODE_STRING String1,
_In_ PUNICODE_STRING String2
);
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualComputerName(
_In_ PUNICODE_STRING String1,
_In_ PUNICODE_STRING String2
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDnsHostNameToComputerName(
_Out_ PUNICODE_STRING ComputerNameString,
_In_ PUNICODE_STRING DnsHostNameString,
_In_ BOOLEAN AllocateComputerNameString
);
#endif // !_KERNEL_MODE
#ifndef _KERNEL_MODE
#define RTL_GUID_STRING_SIZE 38
#endif // !_KERNEL_MODE
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlStringFromGUID(
_In_ REFGUID Guid,
_Out_ _At_(GuidString->Buffer, __drv_allocatesMem(Mem))
PUNICODE_STRING GuidString
);
#if (NTDDI_VERSION >= NTDDI_WINBLUE)
// rev
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlStringFromGUIDEx(
_In_ PGUID Guid,
_Inout_ PUNICODE_STRING GuidString,
_In_ BOOLEAN AllocateGuidString
);
#endif
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlGUIDFromString(
_In_ PCUNICODE_STRING GuidString,
_Out_ GUID* Guid
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
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
);
#endif // NTDDI_VERSION >= NTDDI_VISTA
//
// Prefix
//
#ifndef _KERNEL_MODE
//
// Prefix package types and procedures.
//
// Note that the following two record structures should really be opaque
// to the user of this package. The only information about the two
// structures available for the user should be the size and alignment
// of the structures.
//
typedef struct _PREFIX_TABLE_ENTRY {
CSHORT NodeTypeCode;
CSHORT NameLength;
struct _PREFIX_TABLE_ENTRY* NextPrefixTree;
RTL_SPLAY_LINKS Links;
PSTRING Prefix;
} PREFIX_TABLE_ENTRY;
typedef PREFIX_TABLE_ENTRY* PPREFIX_TABLE_ENTRY;
typedef struct _PREFIX_TABLE {
CSHORT NodeTypeCode;
CSHORT NameLength;
PPREFIX_TABLE_ENTRY NextPrefixTree;
} PREFIX_TABLE;
typedef PREFIX_TABLE* PPREFIX_TABLE;
#endif // !_KERNEL_MODE
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
VOID
NTAPI
PfxInitialize(
_Out_ PPREFIX_TABLE PrefixTable
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
BOOLEAN
NTAPI
PfxInsertPrefix(
_In_ PPREFIX_TABLE PrefixTable,
_In_ __drv_aliasesMem PSTRING Prefix,
_Out_ PPREFIX_TABLE_ENTRY PrefixTableEntry
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
VOID
NTAPI
PfxRemovePrefix(
_In_ PPREFIX_TABLE PrefixTable,
_In_ PPREFIX_TABLE_ENTRY PrefixTableEntry
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
PPREFIX_TABLE_ENTRY
NTAPI
PfxFindPrefix(
_In_ PPREFIX_TABLE PrefixTable,
_In_ PSTRING FullName
);
#ifndef _KERNEL_MODE
//
// The following definitions are for the unicode version of the prefix
// package.
//
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;
typedef 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;
typedef UNICODE_PREFIX_TABLE* PUNICODE_PREFIX_TABLE;
#endif // !_KERNEL_MODE
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlInitializeUnicodePrefix(
_Out_ PUNICODE_PREFIX_TABLE PrefixTable
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
BOOLEAN
NTAPI
RtlInsertUnicodePrefix(
_In_ PUNICODE_PREFIX_TABLE PrefixTable,
_In_ __drv_aliasesMem PUNICODE_STRING Prefix,
_Out_ PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlRemoveUnicodePrefix(
_In_ PUNICODE_PREFIX_TABLE PrefixTable,
_In_ PUNICODE_PREFIX_TABLE_ENTRY PrefixTableEntry
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
PUNICODE_PREFIX_TABLE_ENTRY
NTAPI
RtlFindUnicodePrefix(
_In_ PUNICODE_PREFIX_TABLE PrefixTable,
_In_ PCUNICODE_STRING FullName,
_In_ ULONG CaseInsensitiveIndex
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
PUNICODE_PREFIX_TABLE_ENTRY
NTAPI
RtlNextUnicodePrefix(
_In_ PUNICODE_PREFIX_TABLE PrefixTable,
_In_ BOOLEAN Restart
);
//
// Compression
//
#ifndef _KERNEL_MODE
//
// Compression package types and procedures.
//
#define COMPRESSION_FORMAT_NONE (0x0000) // winnt
#define COMPRESSION_FORMAT_DEFAULT (0x0001) // winnt
#define COMPRESSION_FORMAT_LZNT1 (0x0002) // winnt
#define COMPRESSION_FORMAT_XPRESS (0x0003) // winnt
#define COMPRESSION_FORMAT_XPRESS_HUFF (0x0004) // winnt
#define COMPRESSION_FORMAT_XP10 (0x0005) // winnt
#define COMPRESSION_FORMAT_MAX (0x0005)
#define COMPRESSION_ENGINE_STANDARD (0x0000) // winnt
#define COMPRESSION_ENGINE_MAXIMUM (0x0100) // winnt
#define COMPRESSION_ENGINE_HIBER (0x0200) // winnt
#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)
//
// Compressed Data Information structure. This structure is
// used to describe the state of a compressed data buffer,
// whose uncompressed size is known. All compressed chunks
// described by this structure must be compressed with the
// same format. On compressed reads, this entire structure
// is an output, and on compressed writes the entire structure
// is an input.
//
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;
typedef COMPRESSED_DATA_INFO* PCOMPRESSED_DATA_INFO;
#endif // !_KERNEL_MODE
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
);
_IRQL_requires_max_(APC_LEVEL)
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 (NTDDI_VERSION >= NTDDI_WIN8)
_IRQL_requires_max_(APC_LEVEL)
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
#if (NTDDI_VERSION >= NTDDI_WINBLUE)
_IRQL_requires_max_(APC_LEVEL)
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
_IRQL_requires_max_(APC_LEVEL)
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 (NTDDI_VERSION >= NTDDI_WINBLUE)
_IRQL_requires_max_(APC_LEVEL)
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
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlDescribeChunk(
_In_ USHORT CompressionFormat,
_Inout_ PUCHAR* CompressedBuffer,
_In_ PUCHAR EndOfCompressedBufferPlus1,
_Out_ PUCHAR* ChunkBuffer,
_Out_ PULONG ChunkSize
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlReserveChunk(
_In_ USHORT CompressionFormat,
_Inout_ PUCHAR* CompressedBuffer,
_In_ PUCHAR EndOfCompressedBufferPlus1,
_Out_ PUCHAR* ChunkBuffer,
_In_ ULONG ChunkSize
);
_IRQL_requires_max_(APC_LEVEL)
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
);
_IRQL_requires_max_(APC_LEVEL)
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
//
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_VISTA)
// 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_ PUNICODE_STRING String,
_Out_ PLCID Lcid
);
// private
NTSYSAPI
VOID
NTAPI
RtlCleanUpTEBLangLists(
VOID
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetLocaleFileMappingAddress(
_Out_ PVOID* BaseAddress,
_Out_ PLCID DefaultLocaleId,
_Out_ PLARGE_INTEGER DefaultCasingTableSize
);
#endif
#endif // !_KERNEL_MODE
//
// PEB
//
#ifndef _KERNEL_MODE
NTSYSAPI
PPEB
NTAPI
RtlGetCurrentPeb(
VOID
);
NTSYSAPI
VOID
NTAPI
RtlAcquirePebLock(
VOID
);
NTSYSAPI
VOID
NTAPI
RtlReleasePebLock(
VOID
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
LOGICAL
NTAPI
RtlTryAcquirePebLock(
VOID
);
#endif
NTSYSAPI
NTSTATUS
NTAPI
RtlAllocateFromPeb(
_In_ ULONG Size,
_Out_ PVOID* Block
);
NTSYSAPI
NTSTATUS
NTAPI
RtlFreeToPeb(
_In_ PVOID Block,
_In_ ULONG Size
);
#endif // !_KERNEL_MODE
//
// Processes
//
#define DOS_MAX_COMPONENT_LENGTH 255
#define DOS_MAX_PATH_LENGTH (DOS_MAX_COMPONENT_LENGTH + 5)
typedef struct _CURDIR
{
UNICODE_STRING DosPath;
HANDLE Handle;
} CURDIR, * PCURDIR;
#define RTL_USER_PROC_CURDIR_CLOSE 0x00000002
#define RTL_USER_PROC_CURDIR_INHERIT 0x00000003
typedef struct _RTL_DRIVE_LETTER_CURDIR
{
USHORT Flags;
USHORT Length;
ULONG TimeStamp;
STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, * PRTL_DRIVE_LETTER_CURDIR;
#define RTL_MAX_DRIVE_LETTERS 32
#define RTL_DRIVE_LETTER_VALID (USHORT)0x0001
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;
UNICODE_STRING RedirectionDllName; // REDSTONE4
UNICODE_STRING HeapPartitionName; // 19H1
ULONG_PTR DefaultThreadpoolCpuSetMasks;
ULONG DefaultThreadpoolCpuSetMaskCount;
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
#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_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_OPTIN_PROCESS 0x00020000
#ifndef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateProcessParameters(
_Out_ PRTL_USER_PROCESS_PARAMETERS* pProcessParameters,
_In_ PUNICODE_STRING ImagePathName,
_In_opt_ PUNICODE_STRING DllPath,
_In_opt_ PUNICODE_STRING CurrentDirectory,
_In_opt_ PUNICODE_STRING CommandLine,
_In_opt_ PVOID Environment,
_In_opt_ PUNICODE_STRING WindowTitle,
_In_opt_ PUNICODE_STRING DesktopInfo,
_In_opt_ PUNICODE_STRING ShellInfo,
_In_opt_ PUNICODE_STRING RuntimeData
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateProcessParametersEx(
_Out_ PRTL_USER_PROCESS_PARAMETERS* pProcessParameters,
_In_ PUNICODE_STRING ImagePathName,
_In_opt_ PUNICODE_STRING DllPath,
_In_opt_ PUNICODE_STRING CurrentDirectory,
_In_opt_ PUNICODE_STRING CommandLine,
_In_opt_ PVOID Environment,
_In_opt_ PUNICODE_STRING WindowTitle,
_In_opt_ PUNICODE_STRING DesktopInfo,
_In_opt_ PUNICODE_STRING ShellInfo,
_In_opt_ PUNICODE_STRING RuntimeData,
_In_ ULONG Flags // pass RTL_USER_PROC_PARAMS_NORMALIZED to keep parameters normalized
);
#endif
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;
struct _SECTION_IMAGE_INFORMATION ImageInformation;
} RTL_USER_PROCESS_INFORMATION, * PRTL_USER_PROCESS_INFORMATION;
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserProcess(
_In_ PUNICODE_STRING NtImagePathName,
_In_ ULONG AttributesDeprecated,
_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
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserProcessEx(
_In_ PUNICODE_STRING NtImagePathName,
_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
_In_ BOOLEAN InheritHandles,
_Reserved_ ULONG Flags,
_Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
DECLSPEC_NORETURN
NTSYSAPI
VOID
NTAPI
RtlExitUserProcess(
_In_ NTSTATUS ExitStatus
);
#else
#define RtlExitUserProcess RtlExitUserProcess_R
DECLSPEC_NORETURN
FORCEINLINE VOID RtlExitUserProcess_R(
_In_ NTSTATUS ExitStatus
)
{
ExitProcess(ExitStatus);
}
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
// 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
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
);
// 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
);
#endif
// 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;
#if (NTDDI_VERSION >= NTDDI_WIN7)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateProcessReflection(
_In_ HANDLE ProcessHandle,
_In_ ULONG Flags, // RTL_CLONE_PROCESS_FLAGS
_In_opt_ PVOID StartRoutine,
_In_opt_ PVOID StartContext,
_In_opt_ HANDLE EventHandle,
_Out_opt_ PRTLP_PROCESS_REFLECTION_REFLECTION_INFORMATION ReflectionInformation
);
#endif
NTSYSAPI
NTSTATUS
STDAPIVCALLTYPE
RtlSetProcessIsCritical(
_In_ BOOLEAN NewValue,
_Out_opt_ PBOOLEAN OldValue,
_In_ BOOLEAN CheckFlag
);
NTSYSAPI
NTSTATUS
STDAPIVCALLTYPE
RtlSetThreadIsCritical(
_In_ BOOLEAN NewValue,
_Out_opt_ PBOOLEAN OldValue,
_In_ BOOLEAN CheckFlag
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlValidProcessProtection(
_In_ struct _PS_PROTECTION ProcessProtection
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlTestProtectedAccess(
_In_ struct _PS_PROTECTION Source,
_In_ struct _PS_PROTECTION Target
);
#if (NTDDI_VERSION >= NTDDI_WIN10_RS3)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsCurrentProcess( // NtCompareObjects(NtCurrentProcess(), ProcessHandle)
_In_ HANDLE ProcessHandle
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsCurrentThread( // NtCompareObjects(NtCurrentThread(), ThreadHandle)
_In_ HANDLE ThreadHandle
);
#endif
// KernelBase.dll
NTSYSAPI
BOOL
WINAPI
CreateProcessInternalA(
_In_opt_ HANDLE hUserToken,
_In_opt_ LPWSTR lpApplicationName,
_Inout_opt_ LPSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCSTR lpCurrentDirectory,
_In_ LPSTARTUPINFOA lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation,
_Out_opt_ PHANDLE hNewToken
);
NTSYSAPI
BOOL
WINAPI
CreateProcessInternalW(
_In_opt_ HANDLE hUserToken,
_In_opt_ LPCWSTR lpApplicationName,
_Inout_opt_ LPWSTR lpCommandLine,
_In_opt_ LPSECURITY_ATTRIBUTES lpProcessAttributes,
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ BOOL bInheritHandles,
_In_ DWORD dwCreationFlags,
_In_opt_ LPVOID lpEnvironment,
_In_opt_ LPCWSTR lpCurrentDirectory,
_In_ LPSTARTUPINFOW lpStartupInfo,
_Out_ LPPROCESS_INFORMATION lpProcessInformation,
_Out_opt_ PHANDLE hNewToken
);
#endif // !_KERNEL_MODE
//
// Threads
//
#ifndef _KERNEL_MODE
typedef NTSTATUS(NTAPI* PUSER_THREAD_START_ROUTINE)(
_In_ PVOID ThreadParameter
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserThread(
_In_ HANDLE Process,
_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 Thread,
_Out_opt_ PCLIENT_ID ClientId
);
#if (NTDDI_VERSION >= NTDDI_VISTA) // should be NTDDI_WINXP, but is NTDDI_VISTA for consistency with RtlExitUserProcess
DECLSPEC_NORETURN
NTSYSAPI
VOID
NTAPI
RtlExitUserThread(
_In_ NTSTATUS ExitStatus
);
#else
#define RtlExitUserThread RtlExitUserThread_R
DECLSPEC_NORETURN
FORCEINLINE VOID RtlExitUserThread_R(
_In_ NTSTATUS ExitStatus
)
{
ExitThread(ExitStatus);
}
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsCurrentThreadAttachExempt(
VOID
);
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
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_ struct _INITIAL_TEB* InitialTeb
);
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlFreeUserStack(
_In_ PVOID AllocationBase
);
#endif
#endif // !_KERNEL_MODE
//
// Extended thread context
//
#ifndef _KERNEL_MODE
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_EX, * PCONTEXT_EX;
#define CONTEXT_EX_LENGTH ALIGN_UP_BY(sizeof(CONTEXT_EX), PAGE_SIZE)
#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)((PCHAR)(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)
NTSYSAPI
VOID
NTAPI
RtlInitializeContext(
_In_ HANDLE Process,
_Out_ PCONTEXT Context,
_In_opt_ PVOID Parameter,
_In_opt_ PVOID InitialPc,
_In_opt_ PVOID InitialSp
);
NTSYSAPI
ULONG
NTAPI
RtlInitializeExtendedContext(
_Out_ PCONTEXT Context,
_In_ ULONG ContextFlags,
_Out_ PCONTEXT_EX* ContextEx
);
NTSYSAPI
ULONG
NTAPI
RtlCopyExtendedContext(
_Out_ PCONTEXT_EX Destination,
_In_ ULONG ContextFlags,
_In_ PCONTEXT_EX Source
);
NTSYSAPI
ULONG
NTAPI
RtlGetExtendedContextLength(
_In_ ULONG ContextFlags,
_Out_ PULONG ContextLength
);
NTSYSAPI
ULONG64
NTAPI
RtlGetExtendedFeaturesMask(
_In_ PCONTEXT_EX ContextEx
);
NTSYSAPI
PVOID
NTAPI
RtlLocateExtendedFeature(
_In_ PCONTEXT_EX ContextEx,
_In_ ULONG FeatureId,
_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
);
#ifdef _WIN64
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64GetThreadContext(
_In_ HANDLE ThreadHandle,
_Inout_ PWOW64_CONTEXT ThreadContext
);
#endif
#ifdef _WIN64
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64SetThreadContext(
_In_ HANDLE ThreadHandle,
_In_ PWOW64_CONTEXT ThreadContext
);
#endif
NTSYSAPI
NTSTATUS
NTAPI
RtlRemoteCall(
_In_ HANDLE Process,
_In_ HANDLE Thread,
_In_ PVOID CallSite,
_In_ ULONG ArgumentCount,
_In_opt_ PULONG_PTR Arguments,
_In_ BOOLEAN PassContext,
_In_ BOOLEAN AlreadySuspended
);
#endif // !_KERNEL_MODE
//
// Vectored exception handlers
//
#ifndef _KERNEL_MODE
NTSYSAPI
PVOID
NTAPI
RtlAddVectoredExceptionHandler(
_In_ ULONG First,
_In_ PVECTORED_EXCEPTION_HANDLER Handler
);
NTSYSAPI
ULONG
NTAPI
RtlRemoveVectoredExceptionHandler(
_In_ PVOID Handle
);
NTSYSAPI
PVOID
NTAPI
RtlAddVectoredContinueHandler(
_In_ ULONG First,
_In_ PVECTORED_EXCEPTION_HANDLER Handler
);
NTSYSAPI
ULONG
NTAPI
RtlRemoveVectoredContinueHandler(
_In_ PVOID Handle
);
#endif // !_KERNEL_MODE
//
// Runtime exception handling
//
#ifndef _KERNEL_MODE
typedef ULONG(NTAPI* PRTLP_UNHANDLED_EXCEPTION_FILTER)(
_In_ PEXCEPTION_POINTERS ExceptionInfo
);
NTSYSAPI
VOID
NTAPI
RtlSetUnhandledExceptionFilter(
_In_ 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
);
NTSYSAPI
BOOLEAN
NTAPI
RtlDispatchException(
_In_ PEXCEPTION_RECORD ExceptionRecord,
_In_ PCONTEXT ContextRecord
);
NTSYSAPI
DECLSPEC_NORETURN
VOID
NTAPI
RtlRaiseStatus(
_In_ NTSTATUS Status
);
NTSYSAPI
__analysis_noreturn
VOID
NTAPI
RtlAssert(
_In_ PVOID VoidFailedAssertion,
_In_ PVOID VoidFileName,
_In_ ULONG LineNumber,
_In_opt_ PSTR MutableMessage
);
#if DBG
#define ASSERT( exp ) \
((!(exp)) ? \
(RtlAssert( (PVOID)#exp, (PVOID)__FILE__, __LINE__, NULL ),FALSE) : \
TRUE)
#define ASSERTMSG( msg, exp ) \
((!(exp)) ? \
(RtlAssert( (PVOID)#exp, (PVOID)__FILE__, __LINE__, msg ),FALSE) : \
TRUE)
#define RTL_SOFT_ASSERT(_exp) \
((!(_exp)) ? \
(DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n", __FILE__, __LINE__, #_exp),FALSE) : \
TRUE)
#define RTL_SOFT_ASSERTMSG(_msg, _exp) \
((!(_exp)) ? \
(DbgPrint("%s(%d): Soft assertion failed\n Expression: %s\n Message: %s\n", __FILE__, __LINE__, #_exp, (_msg)),FALSE) : \
TRUE)
#define RTL_VERIFY ASSERT
#define RTL_VERIFYMSG ASSERTMSG
#define RTL_SOFT_VERIFY RTL_SOFT_ASSERT
#define RTL_SOFT_VERIFYMSG RTL_SOFT_ASSERTMSG
#else
#define ASSERT( exp ) ((void) 0)
#define ASSERTMSG( msg, exp ) ((void) 0)
#define RTL_SOFT_ASSERT(_exp) ((void) 0)
#define RTL_SOFT_ASSERTMSG(_msg, _exp) ((void) 0)
#define RTL_VERIFY( exp ) ((exp) ? TRUE : FALSE)
#define RTL_VERIFYMSG( msg, exp ) ((exp) ? TRUE : FALSE)
#define RTL_SOFT_VERIFY(_exp) ((_exp) ? TRUE : FALSE)
#define RTL_SOFT_VERIFYMSG(msg, _exp) ((_exp) ? TRUE : FALSE)
#endif // DBG
#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 TreeNode;
} DYNAMIC_FUNCTION_TABLE, * PDYNAMIC_FUNCTION_TABLE;
// rev
NTSYSAPI
PLIST_ENTRY
NTAPI
RtlGetFunctionTableListHead(
VOID
);
#endif
#endif // !_KERNEL_MODE
//
// Images
//
NTSYSAPI
PIMAGE_NT_HEADERS
NTAPI
RtlImageNtHeader(
_In_ PVOID BaseOfImage
);
#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
);
#ifndef _KERNEL_MODE
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
);
#endif // !_KERNEL_MODE
NTSYSAPI
PVOID
NTAPI
RtlImageDirectoryEntryToData(
_In_ PVOID BaseOfImage,
_In_ BOOLEAN MappedAsImage,
_In_ USHORT DirectoryEntry,
_Out_ PULONG Size
);
#ifndef _KERNEL_MODE
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
);
#endif // !_KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN10)
// rev
NTSYSAPI
PVOID
NTAPI
RtlFindExportedRoutineByName(
_In_ PVOID BaseOfImage,
_In_ PCSTR RoutineName
);
#endif
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGuardCheckLongJumpTarget(
_In_ PVOID PcValue,
_In_ BOOL IsFastFail,
_Out_ PBOOL IsLongJumpTarget
);
#endif
#endif // !_KERNEL_MODE
#ifdef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlPcToFileName(
_In_ PVOID PcValue,
_Out_ PUNICODE_STRING FileName
);
NTSYSAPI
NTSTATUS
NTAPI
RtlPcToFilePath(
_In_ PVOID PcValue,
_Out_ PUNICODE_STRING FilePath
);
NTSYSAPI
PVOID
NTAPI
RtlPcToFileHeader(
_In_ PVOID PcValue,
_Out_ PVOID* BaseOfImage
);
NTSYSAPI
VOID
NTAPI
RtlRaiseException(
_In_ PEXCEPTION_RECORD ExceptionRecord
);
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_ARM64) || defined(_M_ARM)
//
// Define unwind history table structure.
//
#define UNWIND_HISTORY_TABLE_SIZE 12
typedef struct _UNWIND_HISTORY_TABLE_ENTRY
{
ULONG_PTR ImageBase;
PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry;
} UNWIND_HISTORY_TABLE_ENTRY, * PUNWIND_HISTORY_TABLE_ENTRY;
typedef struct _UNWIND_HISTORY_TABLE
{
UINT32 Count;
UINT8 LocalHint;
UINT8 GlobalHint;
UINT8 Search;
UINT8 Once;
ULONG_PTR LowAddress;
ULONG_PTR HighAddress;
UNWIND_HISTORY_TABLE_ENTRY Entry[UNWIND_HISTORY_TABLE_SIZE];
} UNWIND_HISTORY_TABLE, * PUNWIND_HISTORY_TABLE;
NTSYSAPI
PIMAGE_RUNTIME_FUNCTION_ENTRY
NTAPI
RtlLookupFunctionEntry(
_In_ DWORD64 ControlPc,
_Out_ PDWORD64 ImageBase,
_Inout_opt_ PUNWIND_HISTORY_TABLE HistoryTable
);
NTSYSAPI
VOID
__cdecl
RtlRestoreContext(
_In_ PCONTEXT ContextRecord,
_In_opt_ struct _EXCEPTION_RECORD* ExceptionRecord
);
NTSYSAPI
VOID
NTAPI
RtlUnwindEx(
_In_opt_ PVOID TargetFrame,
_In_opt_ PVOID TargetIp,
_In_opt_ PEXCEPTION_RECORD ExceptionRecord,
_In_ PVOID ReturnValue,
_In_ PCONTEXT ContextRecord,
_In_opt_ PUNWIND_HISTORY_TABLE HistoryTable
);
NTSYSAPI
PEXCEPTION_ROUTINE
NTAPI
RtlVirtualUnwind(
_In_ UINT32 HandlerType,
_In_ SIZE_T ImageBase,
_In_ SIZE_T ControlPc,
_In_ PIMAGE_RUNTIME_FUNCTION_ENTRY FunctionEntry,
_Inout_ PCONTEXT ContextRecord,
_Out_ PVOID* HandlerData,
_Out_ PSIZE_T EstablisherFrame,
_Inout_opt_ /*PKNONVOLATILE_CONTEXT_POINTERS*/ PVOID ContextPointers
);
#endif // _M_AMD64 | _M_ARM64 | _M_ARM
#endif // _KERNEL_MODE
typedef struct _RTL_MODULE_BASIC_INFO {
PVOID ImageBase;
} RTL_MODULE_BASIC_INFO, * PRTL_MODULE_BASIC_INFO;
typedef struct _RTL_MODULE_EXTENDED_INFO {
RTL_MODULE_BASIC_INFO BasicInfo;
ULONG ImageSize;
USHORT FileNameOffset;
UCHAR FullPathName[256];
} RTL_MODULE_EXTENDED_INFO, * PRTL_MODULE_EXTENDED_INFO;
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryModuleInformation( // ZwQuerySystemInformation(SystemModuleInformation)
_Out_ PULONG ReturnLength,
_In_ ULONG BufferSize, // sizeof RTL_MODULE_EXTENDED_INFO or RTL_MODULE_BASIC_INFO
_In_ PVOID Buffer // PRTL_MODULE_EXTENDED_INFO or PRTL_MODULE_BASIC_INFO
);
//
// Memory
//
_Must_inspect_result_
NTSYSAPI
SIZE_T
NTAPI
RtlCompareMemoryUlong(
_In_reads_bytes_(Length) PVOID Source,
_In_ SIZE_T Length,
_In_ ULONG Pattern
);
#ifndef _KERNEL_MODE
#if defined(_M_AMD64)
FORCEINLINE
VOID
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
#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
#endif // !_KERNEL_MODE
//
// Environment
//
#ifndef _KERNEL_MODE
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
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateEnvironmentEx(
_In_ PVOID SourceEnv,
_Out_ PVOID* Environment,
_In_ ULONG Flags
);
#endif
NTSYSAPI
NTSTATUS
NTAPI
RtlDestroyEnvironment(
_In_ PVOID Environment
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetCurrentEnvironment(
_In_ PVOID Environment,
_Out_opt_ PVOID* PreviousEnvironment
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSetEnvironmentVar(
_Inout_opt_ PVOID* Environment,
_In_reads_(NameLength) PCWSTR Name,
_In_ SIZE_T NameLength,
_In_reads_(ValueLength) PCWSTR Value,
_In_ SIZE_T ValueLength
);
#endif
NTSYSAPI
NTSTATUS
NTAPI
RtlSetEnvironmentVariable(
_Inout_opt_ PVOID* Environment,
_In_ PUNICODE_STRING Name,
_In_opt_ PUNICODE_STRING Value
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryEnvironmentVariable(
_In_opt_ PVOID Environment,
_In_reads_(NameLength) PCWSTR Name,
_In_ SIZE_T NameLength,
_Out_writes_(ValueLength) PWSTR Value,
_In_ SIZE_T ValueLength,
_Out_ PSIZE_T ReturnLength
);
#endif
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryEnvironmentVariable_U(
_In_opt_ PVOID Environment,
_In_ PUNICODE_STRING Name,
_Inout_ PUNICODE_STRING Value
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlExpandEnvironmentStrings(
_In_opt_ PVOID Environment,
_In_reads_(SrcLength) PCWSTR Src,
_In_ SIZE_T SrcLength,
_Out_writes_(DstLength) PWSTR Dst,
_In_ SIZE_T DstLength,
_Out_opt_ PSIZE_T ReturnLength
);
#endif
NTSYSAPI
NTSTATUS
NTAPI
RtlExpandEnvironmentStrings_U(
_In_opt_ PVOID Environment,
_In_ PUNICODE_STRING Source,
_Inout_ PUNICODE_STRING Destination,
_Out_opt_ PULONG ReturnedLength
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetEnvironmentStrings(
_In_ PCWCHAR NewEnvironment,
_In_ SIZE_T NewEnvironmentSize
);
#endif // !_KERNEL_MODE
//
// Directory and path support
//
#ifndef _KERNEL_MODE
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,
RtlPathTypeDriveAbsolute,
RtlPathTypeDriveRelative,
RtlPathTypeRooted,
RtlPathTypeRelative,
RtlPathTypeLocalDevice,
RtlPathTypeRootLocalDevice
} RTL_PATH_TYPE;
// Data exports (ntdll.lib/ntdllp.lib)
NTSYSAPI PWSTR RtlNtdllName;
NTSYSAPI UNICODE_STRING RtlDosPathSeperatorsString;
NTSYSAPI UNICODE_STRING RtlAlternateDosPathSeperatorString;
NTSYSAPI UNICODE_STRING RtlNtPathSeperatorString;
// Path functions
NTSYSAPI
RTL_PATH_TYPE
NTAPI
RtlDetermineDosPathNameType_U(
_In_ PCWSTR DosFileName
);
NTSYSAPI
RTL_PATH_TYPE
NTAPI
RtlDetermineDosPathNameType_Ustr(
_In_ PCUNICODE_STRING DosFileName
);
NTSYSAPI
ULONG
NTAPI
RtlIsDosDeviceName_U(
_In_ PCWSTR DosFileName
);
NTSYSAPI
ULONG
NTAPI
RtlIsDosDeviceName_Ustr(
_In_ PUNICODE_STRING DosFileName
);
NTSYSAPI
ULONG
NTAPI
RtlGetFullPathName_U(
_In_ PCWSTR FileName,
_In_ ULONG BufferLength,
_Out_writes_bytes_(BufferLength) PWSTR Buffer,
_Out_opt_ PWSTR* FilePart
);
#if (NTDDI_VERSION >= NTDDI_WIN7)
// rev
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
);
#endif
#if (NTDDI_VERSION >= NTDDI_WS03)
NTSYSAPI
NTSTATUS
NTAPI
RtlGetFullPathName_UstrEx(
_In_ PUNICODE_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
);
#endif
NTSYSAPI
ULONG
NTAPI
RtlGetCurrentDirectory_U(
_In_ ULONG BufferLength,
_Out_writes_bytes_(BufferLength) PWSTR Buffer
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetCurrentDirectory_U(
_In_ PUNICODE_STRING PathName
);
NTSYSAPI
ULONG
NTAPI
RtlGetLongestNtPathLength(
VOID
);
NTSYSAPI
BOOLEAN
NTAPI
RtlDosPathNameToNtPathName_U(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR* FilePart,
_Out_opt_ PRTL_RELATIVE_NAME_U RelativeName
);
#if (NTDDI_VERSION >= NTDDI_WS03)
NTSYSAPI
NTSTATUS
NTAPI
RtlDosPathNameToNtPathName_U_WithStatus(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR* FilePart,
_Out_opt_ PRTL_RELATIVE_NAME_U RelativeName
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10_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
#if (NTDDI_VERSION >= NTDDI_WS03)
NTSYSAPI
BOOLEAN
NTAPI
RtlDosPathNameToRelativeNtPathName_U(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR* FilePart,
_Out_opt_ PRTL_RELATIVE_NAME_U RelativeName
);
#endif
#if (NTDDI_VERSION >= NTDDI_WS03)
NTSYSAPI
NTSTATUS
NTAPI
RtlDosPathNameToRelativeNtPathName_U_WithStatus(
_In_ PCWSTR DosFileName,
_Out_ PUNICODE_STRING NtFileName,
_Out_opt_ PWSTR* FilePart,
_Out_opt_ PRTL_RELATIVE_NAME_U RelativeName
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10_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
#if (NTDDI_VERSION >= NTDDI_WS03)
NTSYSAPI
VOID
NTAPI
RtlReleaseRelativeName(
_Inout_ PRTL_RELATIVE_NAME_U RelativeName
);
#endif
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_ PUNICODE_STRING Path,
_In_ PUNICODE_STRING FileName,
_In_opt_ PUNICODE_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
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetLengthWithoutLastFullDosOrNtPathElement(
_Reserved_ ULONG Flags,
_In_ PUNICODE_STRING PathString,
_Out_ PULONG Length
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetLengthWithoutTrailingPathSeperators(
_Reserved_ ULONG Flags,
_In_ PUNICODE_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_ PUNICODE_STRING Name,
_In_ BOOLEAN AllowExtendedCharacters,
_Inout_ PGENERATE_NAME_CONTEXT Context,
_Inout_ PUNICODE_STRING Name8dot3
);
#if (NTDDI_VERSION >= NTDDI_WIN8)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlComputePrivatizedDllName_U(
_In_ PUNICODE_STRING DllName,
_Out_ PUNICODE_STRING RealName,
_Out_ PUNICODE_STRING LocalName
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetSearchPath(
_Out_ PWSTR* SearchPath
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSetSearchPathMode(
_In_ ULONG Flags
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetExePath(
_In_ PCWSTR DosPathName,
_Out_ PWSTR* SearchPath
);
// rev
NTSYSAPI
VOID
NTAPI
RtlReleasePath(
_In_ PWSTR Path
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10_RS2)
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
PCWSTR
NTAPI
RtlGetNtSystemRoot(
VOID
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlAreLongPathsEnabled(
VOID
);
#endif // NTDDI_VERSION >= NTDDI_WIN10_RS2
NTSYSAPI
BOOLEAN
NTAPI
RtlIsThreadWithinLoaderCallout(
VOID
);
NTSYSAPI
BOOLEAN
NTAPI
RtlDllShutdownInProgress(
VOID
);
#endif // !_KERNEL_MODE
//
// Heaps
//
#ifndef _KERNEL_MODE
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)0x0100
#define RTL_HEAP_PROTECTED_ENTRY (USHORT)0x0200
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;
typedef struct _RTL_HEAP_INFORMATION
{
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; // Windows 11 > 22000
} RTL_HEAP_INFORMATION, * PRTL_HEAP_INFORMATION;
#define RTL_HEAP_SIGNATURE 0xFFEEFFEEUL
#define RTL_HEAP_SEGMENT_SIGNATURE 0xDDEEDDEEUL
typedef struct _RTL_PROCESS_HEAPS
{
ULONG NumberOfHeaps;
RTL_HEAP_INFORMATION Heaps[1];
} RTL_PROCESS_HEAPS, * PRTL_PROCESS_HEAPS;
typedef
_Function_class_(RTL_HEAP_COMMIT_ROUTINE)
_IRQL_requires_same_
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
_Must_inspect_result_
NTSYSAPI
PVOID
NTAPI
RtlCreateHeap(
_In_ ULONG Flags,
_In_opt_ PVOID HeapBase,
_In_opt_ SIZE_T ReserveSize,
_In_opt_ SIZE_T CommitSize,
_In_opt_ PVOID Lock,
_In_opt_ PRTL_HEAP_PARAMETERS Parameters
);
NTSYSAPI
PVOID
NTAPI
RtlDestroyHeap(
_In_ _Post_invalid_ PVOID HeapHandle
);
_Must_inspect_result_
_Ret_maybenull_
_Post_writable_byte_size_(Size)
NTSYSAPI
PVOID
NTAPI
RtlAllocateHeap(
_In_ PVOID HeapHandle,
_In_opt_ ULONG Flags,
_In_ SIZE_T Size
);
#if (NTDDI_VERSION >= NTDDI_WIN8)
_Success_(return != 0)
NTSYSAPI
LOGICAL
NTAPI
RtlFreeHeap(
_In_ PVOID HeapHandle,
_In_opt_ ULONG Flags,
_Frees_ptr_opt_ PVOID BaseAddress
);
#else
_Success_(return)
NTSYSAPI
BOOLEAN
NTAPI
RtlFreeHeap(
_In_ PVOID HeapHandle,
_In_opt_ ULONG Flags,
_Frees_ptr_opt_ PVOID BaseAddress
);
#endif
#endif // !_KERNEL_MODE
NTSYSAPI
SIZE_T
NTAPI
RtlSizeHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags,
_In_ PVOID BaseAddress
);
NTSYSAPI
NTSTATUS
NTAPI
RtlZeroHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags
);
#ifndef _KERNEL_MODE
NTSYSAPI
VOID
NTAPI
RtlProtectHeap(
_In_ PVOID HeapHandle,
_In_ BOOLEAN MakeReadOnly
);
#endif // !_KERNEL_MODE
#define RtlProcessHeap() (NtCurrentPeb()->ProcessHeap)
#ifndef _KERNEL_MODE
NTSYSAPI
BOOLEAN
NTAPI
RtlLockHeap(
_In_ PVOID HeapHandle
);
NTSYSAPI
BOOLEAN
NTAPI
RtlUnlockHeap(
_In_ PVOID HeapHandle
);
NTSYSAPI
PVOID
NTAPI
RtlReAllocateHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags,
_Frees_ptr_opt_ PVOID BaseAddress,
_In_ SIZE_T Size
);
NTSYSAPI
BOOLEAN
NTAPI
RtlGetUserInfoHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags,
_In_ PVOID BaseAddress,
_Out_opt_ PVOID * UserValue,
_Out_opt_ PULONG UserFlags
);
NTSYSAPI
BOOLEAN
NTAPI
RtlSetUserValueHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags,
_In_ PVOID BaseAddress,
_In_ PVOID UserValue
);
NTSYSAPI
BOOLEAN
NTAPI
RtlSetUserFlagsHeap(
_In_ PVOID 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_ PVOID HeapHandle,
_In_ ULONG Flags,
_In_opt_ PWSTR TagPrefix,
_In_ PWSTR TagNames
);
NTSYSAPI
PWSTR
NTAPI
RtlQueryTagHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags,
_In_ USHORT TagIndex,
_In_ BOOLEAN ResetCounters,
_Out_opt_ PRTL_HEAP_TAG_INFO TagInfo
);
NTSYSAPI
NTSTATUS
NTAPI
RtlExtendHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags,
_In_ PVOID Base,
_In_ SIZE_T Size
);
NTSYSAPI
SIZE_T
NTAPI
RtlCompactHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags
);
NTSYSAPI
BOOLEAN
NTAPI
RtlValidateHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags,
_In_ PVOID BaseAddress
);
NTSYSAPI
BOOLEAN
NTAPI
RtlValidateProcessHeaps(
VOID
);
NTSYSAPI
ULONG
NTAPI
RtlGetProcessHeaps(
_In_ ULONG NumberOfHeaps,
_Out_ PVOID * ProcessHeaps
);
typedef NTSTATUS(NTAPI* PRTL_ENUM_HEAPS_ROUTINE)(
_In_ PVOID HeapHandle,
_In_ PVOID Parameter
);
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_ PVOID 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_ PVOID HeapHandle,
_Inout_ PRTL_HEAP_WALK_ENTRY Entry
);
// HEAP_INFORMATION_CLASS
#define HeapCompatibilityInformation ((HEAP_INFORMATION_CLASS)0x0 ) // q; s: ULONG
#define HeapEnableTerminationOnCorruption ((HEAP_INFORMATION_CLASS)0x1 ) // q; s: NULL
#define HeapExtendedInformation ((HEAP_INFORMATION_CLASS)0x2 ) // q; s: HEAP_EXTENDED_INFORMATION
#define HeapOptimizeResources ((HEAP_INFORMATION_CLASS)0x3 ) // q; s: HEAP_OPTIMIZE_RESOURCES_INFORMATION
#define HeapTaggingInformation ((HEAP_INFORMATION_CLASS)0x4 )
#define HeapStackDatabase ((HEAP_INFORMATION_CLASS)0x5 )
#define HeapMemoryLimit ((HEAP_INFORMATION_CLASS)0x6 ) // 19H2
#define HeapDetailedFailureInformation ((HEAP_INFORMATION_CLASS)0x80000001)
#define HeapSetDebuggingInformation ((HEAP_INFORMATION_CLASS)0x80000002) // q; s: HEAP_DEBUGGING_INFORMATION
typedef enum _HEAP_COMPATIBILITY_MODE
{
HEAP_COMPATIBILITY_STANDARD = 0UL,
HEAP_COMPATIBILITY_LAL = 1UL,
HEAP_COMPATIBILITY_LFH = 2UL,
} HEAP_COMPATIBILITY_MODE;
typedef struct _PROCESS_HEAP_INFORMATION
{
ULONG_PTR ReserveSize;
ULONG_PTR CommitSize;
ULONG NumberOfHeaps;
ULONG_PTR FirstHeapInformationOffset;
} PROCESS_HEAP_INFORMATION, * PPROCESS_HEAP_INFORMATION;
typedef struct _HEAP_INFORMATION
{
ULONG_PTR Address;
ULONG Mode;
ULONG_PTR ReserveSize;
ULONG_PTR CommitSize;
ULONG_PTR FirstRegionInformationOffset;
ULONG_PTR NextHeapInformationOffset;
} HEAP_INFORMATION, * PHEAP_INFORMATION;
typedef struct _HEAP_EXTENDED_INFORMATION
{
HANDLE Process;
ULONG_PTR Heap;
ULONG Level;
PVOID CallbackRoutine;
PVOID CallbackContext;
union
{
PROCESS_HEAP_INFORMATION ProcessHeapInformation;
HEAP_INFORMATION HeapInformation;
};
} HEAP_EXTENDED_INFORMATION, * PHEAP_EXTENDED_INFORMATION;
// rev
typedef NTSTATUS(NTAPI* PRTL_HEAP_LEAK_ENUMERATION_ROUTINE)(
_In_ LONG Reserved,
_In_ PVOID HeapHandle,
_In_ PVOID BaseAddress,
_In_ SIZE_T BlockSize,
_In_ ULONG StackTraceDepth,
_In_ PVOID* StackTrace
);
// symbols
typedef struct _HEAP_DEBUGGING_INFORMATION
{
PVOID 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_ PVOID 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_ PVOID HeapHandle,
_In_ HEAP_INFORMATION_CLASS HeapInformationClass,
_In_opt_ PVOID HeapInformation,
_In_opt_ SIZE_T HeapInformationLength
);
NTSYSAPI
ULONG
NTAPI
RtlMultipleAllocateHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags,
_In_ SIZE_T Size,
_In_ ULONG Count,
_Out_ PVOID * Array
);
NTSYSAPI
ULONG
NTAPI
RtlMultipleFreeHeap(
_In_ PVOID HeapHandle,
_In_ ULONG Flags,
_In_ ULONG Count,
_In_ PVOID * Array
);
#if (NTDDI_VERSION >= NTDDI_WIN7)
NTSYSAPI
VOID
NTAPI
RtlDetectHeapLeaks(
VOID
);
#endif
NTSYSAPI
VOID
NTAPI
RtlFlushHeaps(
VOID
);
#endif // !_KERNEL_MODE
//
// Memory zones
//
#ifndef _KERNEL_MODE
// 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;
#if (NTDDI_VERSION >= NTDDI_VISTA)
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
);
#endif
// end_private
#endif // !_KERNEL_MODE
//
// Memory block lookaside lists
//
#ifndef _KERNEL_MODE
// begin_private
#if (NTDDI_VERSION >= NTDDI_VISTA)
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
);
#endif
// end_private
#endif // !_KERNEL_MODE
//
// Transactions
//
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
HANDLE
NTAPI
RtlGetCurrentTransaction(
VOID
);
// private
NTSYSAPI
LOGICAL
NTAPI
RtlSetCurrentTransaction(
_In_ HANDLE TransactionHandle
);
#endif
#endif // _KERNEL_MODE
//
// LUIDs
//
#ifndef _KERNEL_MODE
FORCEINLINE BOOLEAN RtlIsEqualLuid( // RtlEqualLuid
_In_ PLUID L1,
_In_ PLUID L2
)
{
return L1->LowPart == L2->LowPart &&
L1->HighPart == L2->HighPart;
}
#define RtlEqualLuid RtlIsEqualLuid
FORCEINLINE BOOLEAN RtlIsZeroLuid(
_In_ PLUID L1
)
{
return (L1->LowPart | L1->HighPart) == 0;
}
FORCEINLINE LUID RtlConvertLongToLuid(
_In_ LONG Long
)
{
LUID tempLuid;
LARGE_INTEGER tempLi;
tempLi.QuadPart = Long;
tempLuid.LowPart = tempLi.LowPart;
tempLuid.HighPart = tempLi.HighPart;
return tempLuid;
}
FORCEINLINE LUID RtlConvertUlongToLuid(
_In_ ULONG Ulong
)
{
LUID tempLuid;
tempLuid.LowPart = Ulong;
tempLuid.HighPart = 0;
return tempLuid;
}
NTSYSAPI
VOID
NTAPI
RtlCopyLuid(
_Out_ PLUID DestinationLuid,
_In_ PLUID SourceLuid
);
#endif // !_KERNEL_MODE
// ros
NTSYSAPI
VOID
NTAPI
RtlCopyLuidAndAttributesArray(
_In_ ULONG Count,
_In_ PLUID_AND_ATTRIBUTES Src,
_In_ PLUID_AND_ATTRIBUTES Dest
);
//
// Byte swap routines.
//
#ifndef _KERNEL_MODE
//
// Byte swap routines. These are used to convert from little-endian to
// big-endian and vice-versa.
//
#if (defined(_M_IX86) && (_MSC_FULL_VER > 13009037)) || ((defined(_M_AMD64) || defined(_M_IA64)) && (_MSC_FULL_VER > 13009175)) || defined(_M_ARM) || defined(_M_ARM64)
#ifdef __cplusplus
extern "C" {
#endif
_Check_return_ unsigned short __cdecl _byteswap_ushort(_In_ unsigned short);
_Check_return_ unsigned long __cdecl _byteswap_ulong(_In_ unsigned long);
_Check_return_ unsigned __int64 __cdecl _byteswap_uint64(_In_ unsigned __int64);
#ifdef __cplusplus
}
#endif
#pragma intrinsic(_byteswap_ushort)
#pragma intrinsic(_byteswap_ulong)
#pragma intrinsic(_byteswap_uint64)
#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
#endif // !_KERNEL_MODE
//
// Debugging
//
#ifndef _KERNEL_MODE
// private
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
{
struct _RTL_PROCESS_MODULES* Modules;
struct _RTL_PROCESS_MODULE_INFORMATION_EX* ModulesEx;
};
struct _RTL_PROCESS_BACKTRACES* BackTraces;
struct _RTL_PROCESS_HEAPS* Heaps;
struct _RTL_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
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
// 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
);
#endif
#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
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
);
#endif // !_KERNEL_MODE
//
// Messages
//
#ifdef _KERNEL_MODE
typedef struct _MESSAGE_RESOURCE_ENTRY {
USHORT Length;
USHORT Flags;
UINT8 Text[1];
} MESSAGE_RESOURCE_ENTRY, * PMESSAGE_RESOURCE_ENTRY;
#define MESSAGE_RESOURCE_UNICODE 0x0001
#define MESSAGE_RESOURCE_UTF8 0x0002
typedef struct _MESSAGE_RESOURCE_BLOCK {
UINT32 LowId;
UINT32 HighId;
UINT32 OffsetToEntries;
} MESSAGE_RESOURCE_BLOCK, * PMESSAGE_RESOURCE_BLOCK;
typedef struct _MESSAGE_RESOURCE_DATA {
UINT32 NumberOfBlocks;
MESSAGE_RESOURCE_BLOCK Blocks[1];
} MESSAGE_RESOURCE_DATA, * PMESSAGE_RESOURCE_DATA;
#endif // _KERNEL_MODE
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_ PWSTR 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_ PWSTR 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
);
#ifndef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlGetFileMUIPath(
_In_ ULONG Flags,
_In_ PCWSTR FilePath,
_Inout_opt_ PWSTR Language,
_Inout_ PULONG LanguageLength,
_Out_opt_ PWSTR FileMUIPath,
_Inout_ PULONG FileMUIPathLength,
_Inout_ PULONGLONG Enumerator
);
#endif // !_KERNEL_MODE
//
// Errors
//
_IRQL_requires_max_(APC_LEVEL)
_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
);
#ifndef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlGetLastNtStatus(
VOID
);
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
);
#endif // !_KERNEL_MODE
//
// Windows Error Reporting
//
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlReportException(
_In_ PEXCEPTION_RECORD ExceptionRecord,
_In_ PCONTEXT ContextRecord,
_In_ ULONG Flags
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlReportExceptionEx(
_In_ PEXCEPTION_RECORD ExceptionRecord,
_In_ PCONTEXT ContextRecord,
_In_ ULONG Flags,
_In_ PLARGE_INTEGER Timeout
);
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlWerpReportException(
_In_ ULONG ProcessId,
_In_ HANDLE CrashReportSharedMem,
_In_ ULONG Flags,
_Out_ PHANDLE CrashVerticalProcessHandle
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlReportSilentProcessExit(
_In_ HANDLE ProcessHandle,
_In_ NTSTATUS ExitStatus
);
#endif
#endif // !_KERNEL_MODE
//
// Random
//
_IRQL_requires_max_(APC_LEVEL)
_Ret_range_(<= , MAXLONG)
NTSYSAPI
ULONG
NTAPI
RtlRandom(
_Inout_ PULONG Seed
);
_IRQL_requires_max_(APC_LEVEL)
_Ret_range_(<= , MAXLONG)
NTSYSAPI
ULONG
NTAPI
RtlRandomEx(
_Inout_ PULONG Seed
);
#ifndef _KERNEL_MODE
NTSYSAPI
ULONG
NTAPI
RtlUniform(
_Inout_ PULONG Seed
);
#define RTL_IMPORT_TABLE_HASH_REVISION 1
NTSYSAPI
NTSTATUS
NTAPI
RtlComputeImportTableHash(
_In_ HANDLE FileHandle,
_Out_writes_bytes_(16) PCHAR Hash,
_In_ ULONG ImportTableHashRevision // must be 1
);
#endif // !_KERNEL_MODE
//
// Integer conversion
//
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlIntegerToChar(
_In_ ULONG Value,
_In_opt_ ULONG Base,
_In_ LONG OutputLength, // negative to pad to width
_Out_ PSTR String
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlCharToInteger(
_In_z_ PCSZ String,
_In_opt_ ULONG Base,
_Out_ PULONG Value
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlLargeIntegerToChar(
_In_ PLARGE_INTEGER Value,
_In_opt_ ULONG Base,
_In_ LONG OutputLength,
_Out_ PSTR String
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_At_(String->MaximumLength, _Const_)
NTSYSAPI
NTSTATUS
NTAPI
RtlIntegerToUnicodeString(
_In_ ULONG Value,
_In_opt_ ULONG Base,
_Inout_ PUNICODE_STRING String
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_At_(String->MaximumLength, _Const_)
NTSYSAPI
NTSTATUS
NTAPI
RtlInt64ToUnicodeString(
_In_ ULONGLONG Value,
_In_opt_ ULONG Base,
_Inout_ PUNICODE_STRING String
);
#ifndef _KERNEL_MODE
#ifdef _WIN64
#define RtlIntPtrToUnicodeString(Value, Base, String) RtlInt64ToUnicodeString(Value, Base, String)
#else
#define RtlIntPtrToUnicodeString(Value, Base, String) RtlIntegerToUnicodeString(Value, Base, String)
#endif
#endif // !_KERNEL_MODE
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlUnicodeStringToInteger(
_In_ PCUNICODE_STRING String,
_In_opt_ ULONG Base,
_Out_ PULONG Value
);
NTSTATUS
RtlUnicodeStringToInt64(
_In_ PCUNICODE_STRING String,
_In_opt_ ULONG Base,
_Out_ PLONG64 Number,
_Out_opt_ PWSTR* EndPointer
);
//
// IPv4/6 conversion
//
#include <ip2string.h>
//
// Time
//
#ifndef _KERNEL_MODE
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
);
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 (NTDDI_VERSION >= NTDDI_WIN8)
NTSYSAPI
ULONGLONG
NTAPI
RtlGetSystemTimePrecise(
VOID
);
#endif
#endif // !_KERNEL_MODE
//
// 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
);
//
// Bitmaps
//
//
// BitMap routines. The following structure, routines, and macros are
// for manipulating bitmaps. The user is responsible for allocating a bitmap
// structure (which is really a header) and a buffer (which must be longword
// aligned and multiple longwords in size).
//
#ifndef _KERNEL_MODE
typedef struct _RTL_BITMAP {
ULONG SizeOfBitMap; // Number of bits in bit map
PULONG Buffer; // Pointer to the bit map itself
} RTL_BITMAP;
typedef RTL_BITMAP* PRTL_BITMAP;
#endif // !_KERNEL_MODE
NTSYSAPI
VOID
NTAPI
RtlInitializeBitMap(
_Out_ PRTL_BITMAP BitMapHeader,
_In_opt_ __drv_aliasesMem PULONG BitMapBuffer,
_In_opt_ ULONG SizeOfBitMap
);
NTSYSAPI
VOID
NTAPI
RtlClearBit(
_In_ PRTL_BITMAP BitMapHeader,
_In_range_(< , BitMapHeader->SizeOfBitMap) ULONG BitNumber
);
NTSYSAPI
VOID
NTAPI
RtlSetBit(
_In_ PRTL_BITMAP BitMapHeader,
_In_range_(< , BitMapHeader->SizeOfBitMap) ULONG BitNumber
);
_Must_inspect_result_
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
);
//
// The following two routines locate a contiguous region of either
// clear or set bits within the bitmap. The region will be at least
// as large as the number specified, and the search of the bitmap will
// begin at the specified hint index (which is a bit index within the
// bitmap, zero based). The return value is the bit index of the located
// region (zero based) or -1 (i.e., 0xffffffff) if such a region cannot
// be located
//
_Success_(return != -1)
_Ret_range_(<= , BitMapHeader->SizeOfBitMap - NumberToFind)
_Must_inspect_result_
NTSYSAPI
ULONG
NTAPI
RtlFindClearBits(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG NumberToFind,
_In_ ULONG HintIndex
);
_Success_(return != -1)
_Ret_range_(<= , BitMapHeader->SizeOfBitMap - NumberToFind)
_Must_inspect_result_
NTSYSAPI
ULONG
NTAPI
RtlFindSetBits(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG NumberToFind,
_In_ ULONG HintIndex
);
//
// The following two routines locate a contiguous region of either
// clear or set bits within the bitmap and either set or clear the bits
// within the located region. The region will be as large as the number
// specified, and the search for the region will begin at the specified
// hint index (which is a bit index within the bitmap, zero based). The
// return value is the bit index of the located region (zero based) or
// -1 (i.e., 0xffffffff) if such a region cannot be located. If a region
// cannot be located then the setting/clearing of the bitmap is not performed.
//
_Success_(return != -1)
_Ret_range_(<= , BitMapHeader->SizeOfBitMap - NumberToFind)
NTSYSAPI
ULONG
NTAPI
RtlFindClearBitsAndSet(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG NumberToFind,
_In_ ULONG HintIndex
);
_Success_(return != -1)
_Ret_range_(<= , BitMapHeader->SizeOfBitMap - NumberToFind)
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
);
//
// The following routine locates a set of contiguous regions of clear
// bits within the bitmap. The caller specifies whether to return the
// longest runs or just the first found lcoated. The following structure is
// used to denote a contiguous run of bits. The two routines return an array
// of this structure, one for each run located.
//
#ifndef _KERNEL_MODE
typedef struct _RTL_BITMAP_RUN {
ULONG StartingIndex;
ULONG NumberOfBits;
} RTL_BITMAP_RUN;
typedef RTL_BITMAP_RUN* PRTL_BITMAP_RUN;
#endif // !_KERNEL_MODE
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
);
#ifndef _KERNEL_MODE
_Must_inspect_result_
FORCEINLINE
BOOLEAN
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
}
#endif // !_KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN8)
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
NTSYSAPI
ULONG
NTAPI
RtlNumberOfClearBits(
_In_ PRTL_BITMAP BitMapHeader
);
NTSYSAPI
ULONG
NTAPI
RtlNumberOfSetBits(
_In_ PRTL_BITMAP BitMapHeader
);
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlAreBitsClear(
_In_ PRTL_BITMAP BitMapHeader,
_In_ ULONG StartingIndex,
_In_ ULONG Length
);
_Must_inspect_result_
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
);
_Success_(return != -1)
_Must_inspect_result_
NTSYSAPI
CCHAR
NTAPI
RtlFindLeastSignificantBit(
_In_ ULONGLONG Set
);
_Success_(return != -1)
_Must_inspect_result_
NTSYSAPI
CCHAR
NTAPI
RtlFindMostSignificantBit(
_In_ ULONGLONG Set
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
NTSYSAPI
ULONG
NTAPI
RtlNumberOfSetBitsUlongPtr(
_In_ ULONG_PTR Target
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN8)
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
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
// 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
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10)
// 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
);
#endif
//
// Handle tables
//
#ifndef _KERNEL_MODE
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
);
#endif // !_KERNEL_MODE
//
// 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,
_Out_ 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_ PWSTR AtomName,
_Inout_opt_ PRTL_ATOM Atom
);
NTSYSAPI
NTSTATUS
NTAPI
RtlLookupAtomInAtomTable(
_In_ PVOID AtomTableHandle,
_In_ PWSTR 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
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlGetIntegerAtom(
_In_ PWSTR AtomName,
_Out_opt_ PUSHORT IntegerAtom
);
#endif
//
// SIDs
//
_IRQL_requires_max_(APC_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlValidSid(
_In_ PSID Sid
);
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualSid(
_In_ PSID Sid1,
_In_ PSID Sid2
);
_IRQL_requires_max_(APC_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlEqualPrefixSid(
_In_ PSID Sid1,
_In_ PSID Sid2
);
_IRQL_requires_max_(APC_LEVEL)
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 (NTDDI_VERSION >= NTDDI_WIN8)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlAllocateAndInitializeSidEx(
_In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
_In_ UCHAR SubAuthorityCount,
_In_reads_(SubAuthorityCount) PULONG SubAuthorities,
_Outptr_ PSID* Sid
);
#endif // NTDDI_VERSION >= NTDDI_WIN8
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeSid(
_Out_ PSID Sid,
_In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
_In_ UCHAR SubAuthorityCount
);
#if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlInitializeSidEx(
_Out_writes_bytes_(SECURITY_SID_SIZE(SubAuthorityCount)) PSID Sid,
_In_ PSID_IDENTIFIER_AUTHORITY IdentifierAuthority,
_In_ UCHAR SubAuthorityCount,
...
);
#endif
_IRQL_requires_max_(APC_LEVEL)
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
_Post_satisfies_(return >= 8 && return <= SECURITY_MAX_SID_SIZE)
ULONG
NTAPI
RtlLengthSid(
_In_ PSID Sid
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlCopySid(
_In_ ULONG DestinationSidLength,
_Out_writes_bytes_(DestinationSidLength) PSID DestinationSid,
_In_ PSID SourceSid
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateServiceSid(
_In_ PUNICODE_STRING ServiceName,
_Out_writes_bytes_opt_(*ServiceSidLength) PSID ServiceSid,
_Inout_ PULONG ServiceSidLength
);
#endif
// 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
);
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSidDominates(
_In_ PSID Sid1,
_In_ PSID Sid2,
_Out_ PBOOLEAN Dominates
);
#endif
#if (NTDDI_VERSION >= NTDDI_WINBLUE)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSidDominatesForTrust(
_In_ PSID Sid1,
_In_ PSID Sid2,
_Out_ PBOOLEAN DominatesTrust // TokenProcessTrustLevel
);
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
// 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
);
#endif
#endif // !_KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN7)
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlReplaceSidInSd(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ PSID OldSid,
_In_ PSID NewSid,
_Out_ ULONG * NumChanges
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateVirtualAccountSid(
_In_ PCUNICODE_STRING Name,
_In_ ULONG BaseSubAuthority,
_Out_writes_bytes_(*SidLength) PSID Sid,
_Inout_ PULONG SidLength
);
#endif
//
// MAX_UNICODE_STACK_BUFFER_LENGTH is the maximum stack buffer
// that RtlConvertSidToUnicodeString can fill if the caller
// specifies AllocateDestinationString = FALSE.
//
#ifndef _KERNEL_MODE
#define MAX_UNICODE_STACK_BUFFER_LENGTH 256
#endif // !_KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlConvertSidToUnicodeString(
_Inout_ PUNICODE_STRING UnicodeString,
_In_ PSID Sid,
_In_ BOOLEAN AllocateDestinationString
);
#ifndef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlLengthSidAsUnicodeString(
_In_ PSID Sid,
_Out_ PULONG StringLength
);
#endif // !_KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlSidHashInitialize(
_In_reads_(SidCount) PSID_AND_ATTRIBUTES SidAttr,
_In_ ULONG SidCount,
_Out_ PSID_AND_ATTRIBUTES_HASH SidAttrHash
);
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
PSID_AND_ATTRIBUTES
NTAPI
RtlSidHashLookup(
_In_ PSID_AND_ATTRIBUTES_HASH SidAttrHash,
_In_ PSID Sid
);
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsElevatedRid(
_In_ PSID_AND_ATTRIBUTES SidAttr
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10_RS2)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlDeriveCapabilitySidsFromName(
_Inout_ PUNICODE_STRING UnicodeString,
_Out_ PSID CapabilityGroupSid,
_Out_ PSID CapabilitySid
);
#endif
//
// Security Descriptors
//
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateSecurityDescriptor(
_Out_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ ULONG Revision
);
_IRQL_requires_max_(APC_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlValidSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
ULONG
NTAPI
RtlLengthSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor
);
_IRQL_requires_max_(APC_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlValidRelativeSecurityDescriptor(
_In_reads_bytes_(SecurityDescriptorLength) PSECURITY_DESCRIPTOR SecurityDescriptorInput,
_In_ ULONG SecurityDescriptorLength,
_In_ SECURITY_INFORMATION RequiredInformation
);
_IRQL_requires_max_(APC_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlGetControlSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_Out_ PSECURITY_DESCRIPTOR_CONTROL Control,
_Out_ PULONG Revision
);
_IRQL_requires_max_(APC_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlSetControlSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ SECURITY_DESCRIPTOR_CONTROL ControlBitsOfInterest,
_In_ SECURITY_DESCRIPTOR_CONTROL ControlBitsToSet
);
#ifndef _KERNEL_MODE
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
);
#endif // !_KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
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,
_Pre_ _Writable_elements_(1)
_When_(!(*DaclPresent), _Post_invalid_)
_When_((*DaclPresent), _Post_valid_)
PBOOLEAN DaclDefaulted
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlSetSaclSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_ BOOLEAN SaclPresent,
_In_opt_ PACL Sacl,
_In_opt_ BOOLEAN SaclDefaulted
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlGetSaclSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_Out_ PBOOLEAN SaclPresent,
_Out_ PACL* Sacl,
_Out_ PBOOLEAN SaclDefaulted
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlSetOwnerSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_opt_ PSID Owner,
_In_ BOOLEAN OwnerDefaulted
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlGetOwnerSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_Outptr_result_maybenull_ PSID* Owner,
_When_(*Owner == NULL, _Post_invalid_)
_When_(*Owner != NULL, _Post_valid_)
_Pre_ _Notnull_ _Pre_ _Writable_elements_(1) PBOOLEAN OwnerDefaulted
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlSetGroupSecurityDescriptor(
_Inout_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_In_opt_ PSID Group,
_In_ BOOLEAN GroupDefaulted
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlGetGroupSecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR SecurityDescriptor,
_Outptr_result_maybenull_ PSID* Group,
_Pre_ _Notnull_ _Pre_ _Writable_elements_(1)
_When_(*Group == NULL, _Post_invalid_)
_When_(*Group != NULL, _Post_valid_)
PBOOLEAN GroupDefaulted
);
#ifndef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlMakeSelfRelativeSD(
_In_ PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
_Out_writes_bytes_(*BufferLength) PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
_Inout_ PULONG BufferLength
);
#endif // !_KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAbsoluteToSelfRelativeSD(
_In_ PSECURITY_DESCRIPTOR AbsoluteSecurityDescriptor,
_Out_writes_bytes_to_opt_(*BufferLength, *BufferLength) PSECURITY_DESCRIPTOR SelfRelativeSecurityDescriptor,
_Inout_ PULONG BufferLength
);
_IRQL_requires_max_(APC_LEVEL)
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 pSelfRelativeSecurityDescriptor,
_Inout_ PULONG pBufferSize
);
//
// Access masks
//
NTSYSAPI
BOOLEAN
NTAPI
RtlAreAllAccessesGranted(
_In_ ACCESS_MASK GrantedAccess,
_In_ ACCESS_MASK DesiredAccess
);
NTSYSAPI
BOOLEAN
NTAPI
RtlAreAnyAccessesGranted(
_In_ ACCESS_MASK GrantedAccess,
_In_ ACCESS_MASK DesiredAccess
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
VOID
NTAPI
RtlMapGenericMask(
_Inout_ PACCESS_MASK AccessMask,
_In_ PGENERIC_MAPPING GenericMapping
);
//
// ACLs
//
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateAcl(
_Out_writes_bytes_(AclLength) PACL Acl,
_In_ ULONG AclLength,
_In_ ULONG AclRevision
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG StartingAceIndex,
_In_reads_bytes_(AceListLength) PVOID AceList,
_In_ ULONG AceListLength
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteAce(
_Inout_ PACL Acl,
_In_ ULONG AceIndex
);
NTSYSAPI
NTSTATUS
NTAPI
RtlGetAce(
_In_ PACL Acl,
_In_ ULONG AceIndex,
_Outptr_ PVOID* Ace
);
NTSYSAPI
BOOLEAN
NTAPI
RtlValidAcl(
_In_ PACL Acl
);
#ifdef _KERNEL_MODE
//
// Currently define Flags for "OBJECT" ACE types.
//
#define ACE_OBJECT_TYPE_PRESENT 0x1
#define ACE_INHERITED_OBJECT_TYPE_PRESENT 0x2
//
// The following declarations are used for setting and querying information
// about and ACL. First are the various information classes available to
// the user.
//
typedef enum _ACL_INFORMATION_CLASS {
AclRevisionInformation = 1,
AclSizeInformation
} ACL_INFORMATION_CLASS;
//
// This record is returned/sent if the user is requesting/setting the
// AclRevisionInformation
//
typedef struct _ACL_REVISION_INFORMATION {
UINT32 AclRevision;
} ACL_REVISION_INFORMATION;
typedef ACL_REVISION_INFORMATION* PACL_REVISION_INFORMATION;
//
// This record is returned if the user is requesting AclSizeInformation
//
typedef struct _ACL_SIZE_INFORMATION {
UINT32 AceCount;
UINT32 AclBytesInUse;
UINT32 AclBytesFree;
} ACL_SIZE_INFORMATION;
typedef ACL_SIZE_INFORMATION* PACL_SIZE_INFORMATION;
#endif // !_KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryInformationAcl(
_In_ PACL Acl,
_Out_writes_bytes_(AclInformationLength) PVOID AclInformation,
_In_ ULONG AclInformationLength,
_In_ ACL_INFORMATION_CLASS AclInformationClass
);
#ifndef _KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlSetInformationAcl(
_Inout_ PACL Acl,
_In_reads_bytes_(AclInformationLength) PVOID AclInformation,
_In_ ULONG AclInformationLength,
_In_ ACL_INFORMATION_CLASS AclInformationClass
);
#endif // !_KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
BOOLEAN
NTAPI
RtlFirstFreeAce(
_In_ PACL Acl,
_Out_ PVOID* FirstFree
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
PVOID
NTAPI
RtlFindAceByType(
_In_ PACL pAcl,
_In_ UCHAR AceType,
_Out_opt_ PULONG pIndex
);
#endif
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
BOOLEAN
NTAPI
RtlOwnerAcesPresent(
_In_ PACL pAcl
);
#endif
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessAllowedAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid
);
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessAllowedAceEx(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid
);
#ifndef _KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessDeniedAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid
);
#endif // !_KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAccessDeniedAceEx(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid
);
#ifndef _KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAddAuditAccessAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ACCESS_MASK AccessMask,
_In_ PSID Sid,
_In_ BOOLEAN AuditSuccess,
_In_ BOOLEAN AuditFailure
);
#endif // !_KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
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
);
_IRQL_requires_max_(APC_LEVEL)
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
);
_IRQL_requires_max_(APC_LEVEL)
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
);
_IRQL_requires_max_(APC_LEVEL)
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
);
#ifndef _KERNEL_MODE
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAddCompoundAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ UCHAR AceType,
_In_ ACCESS_MASK AccessMask,
_In_ PSID ServerSid,
_In_ PSID ClientSid
);
#endif // !_KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAddMandatoryAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ PSID Sid,
_In_ UCHAR AceType,
_In_ ACCESS_MASK AccessMask
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN8)
_IRQL_requires_max_(APC_LEVEL)
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
);
#endif //NTDDI_VERSION >= NTDDI_WIN8
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN8)
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlAddScopedPolicyIDAce(
_Inout_ PACL Acl,
_In_ ULONG AceRevision,
_In_ ULONG AceFlags,
_In_ ULONG AccessMask,
_In_ PSID Sid
);
#endif //NTDDI_VERSION >= NTDDI_WIN8
// Named pipes
NTSYSAPI
NTSTATUS
NTAPI
RtlDefaultNpAcl(
_Out_ PACL* Acl
);
#endif // !_KERNEL_MODE
//
// Security objects
//
#ifndef _KERNEL_MODE
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 Token
);
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 Token
);
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 Token,
_In_ PGENERIC_MAPPING GenericMapping
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCopySecurityDescriptor(
_In_ PSECURITY_DESCRIPTOR InputSecurityDescriptor,
_Out_ PSECURITY_DESCRIPTOR* OutputSecurityDescriptor
);
#endif // !_KERNEL_MODE
//
// Misc. security
//
#ifndef _KERNEL_MODE
NTSYSAPI
VOID
NTAPI
RtlRunEncodeUnicodeString(
_Inout_ PUCHAR Seed,
_In_ PUNICODE_STRING String
);
NTSYSAPI
VOID
NTAPI
RtlRunDecodeUnicodeString(
_In_ UCHAR Seed,
_In_ PUNICODE_STRING String
);
NTSYSAPI
NTSTATUS
NTAPI
RtlImpersonateSelf(
_In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlImpersonateSelfEx(
_In_ SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
_In_opt_ ACCESS_MASK AdditionalAccess,
_Out_opt_ PHANDLE ThreadToken
);
#endif
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
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlRemovePrivileges(
_In_ HANDLE TokenHandle,
_In_ PULONG PrivilegesToKeep,
_In_ ULONG PrivilegeCount
);
#endif
#endif // !_KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN8)
NTSYSAPI
NTSTATUS
NTAPI
RtlIsUntrustedObject(
_In_opt_ HANDLE Handle,
_In_opt_ PVOID Object,
_Out_ PBOOLEAN UntrustedObject
);
NTSYSAPI
ULONG
NTAPI
RtlQueryValidationRunlevel(
_In_opt_ PCUNICODE_STRING ComponentName
);
#endif
//
// Private namespaces
//
#ifndef _KERNEL_MODE
// begin_private
#if (NTDDI_VERSION >= NTDDI_VISTA)
NTSYSAPI
HANDLE
NTAPI
RtlCreateBoundaryDescriptor(
_In_ PUNICODE_STRING Name,
_In_ ULONG Flags
);
NTSYSAPI
VOID
NTAPI
RtlDeleteBoundaryDescriptor(
_In_ HANDLE BoundaryDescriptor
);
NTSYSAPI
NTSTATUS
NTAPI
RtlAddSIDToBoundaryDescriptor(
_Inout_ PHANDLE BoundaryDescriptor,
_In_ PSID RequiredSid
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN7)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlAddIntegrityLabelToBoundaryDescriptor(
_Inout_ PHANDLE BoundaryDescriptor,
_In_ PSID IntegrityLabel
);
#endif
// end_private
#endif // !_KERNEL_MODE
//
// Version
//
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlGetVersion(
_Out_
_At_(lpVersionInformation->dwOSVersionInfoSize, _Pre_ _Valid_)
_When_(lpVersionInformation->dwOSVersionInfoSize == sizeof(RTL_OSVERSIONINFOEXW),
_At_((PRTL_OSVERSIONINFOEXW)lpVersionInformation, _Out_))
PRTL_OSVERSIONINFOW lpVersionInformation
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlVerifyVersionInfo(
_In_ PRTL_OSVERSIONINFOEXW VersionInfo,
_In_ ULONG TypeMask,
_In_ ULONGLONG ConditionMask
);
#ifndef _KERNEL_MODE
// rev
NTSYSAPI
VOID
NTAPI
RtlGetNtVersionNumbers(
_Out_opt_ PULONG NtMajorVersion,
_Out_opt_ PULONG NtMinorVersion,
_Out_opt_ PULONG NtBuildNumber
);
#endif // !_KERNEL_MODE
//
// System information
//
// rev
NTSYSAPI
ULONG
NTAPI
RtlGetNtGlobalFlags(
VOID
);
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
NTSYSAPI
BOOLEAN
NTAPI
RtlGetNtProductType(
_Out_ PNT_PRODUCT_TYPE NtProductType
);
NTSYSAPI
ULONG
NTAPI
RtlGetSuiteMask(
VOID
);
#endif
//
// Thread pool (old)
//
#ifndef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlRegisterWait(
_Out_ PHANDLE WaitHandle,
_In_ HANDLE Handle,
_In_ WAITORTIMERCALLBACKFUNC Function,
_In_ PVOID Context,
_In_ ULONG Milliseconds,
_In_ ULONG Flags
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeregisterWait(
_In_ HANDLE WaitHandle
);
NTSYSAPI
NTSTATUS
NTAPI
RtlDeregisterWaitEx(
_In_ HANDLE WaitHandle,
_In_opt_ HANDLE Event // optional: RTL_WAITER_DEREGISTER_WAIT_FOR_COMPLETION
);
NTSYSAPI
NTSTATUS
NTAPI
RtlQueueWorkItem(
_In_ WORKERCALLBACKFUNC Function,
_In_ PVOID Context,
_In_ ULONG Flags
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetIoCompletionCallback(
_In_ HANDLE FileHandle,
_In_ APC_CALLBACK_FUNCTION CompletionProc,
_In_ ULONG Flags
);
typedef NTSTATUS(NTAPI* PRTL_START_POOL_THREAD)(
_In_ PTHREAD_START_ROUTINE Function,
_In_ PVOID Parameter,
_Out_ PHANDLE ThreadHandle
);
typedef NTSTATUS(NTAPI* PRTL_EXIT_POOL_THREAD)(
_In_ NTSTATUS ExitStatus
);
NTSYSAPI
NTSTATUS
NTAPI
RtlSetThreadPoolStartFunc(
_In_ PRTL_START_POOL_THREAD StartPoolThread,
_In_ PRTL_EXIT_POOL_THREAD ExitPoolThread
);
NTSYSAPI
VOID
NTAPI
RtlUserThreadStart(
_In_ PTHREAD_START_ROUTINE Function,
_In_ PVOID Parameter
);
#endif // !_KERNEL_MODE
//
// Timer support
//
#ifndef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateTimerQueue(
_Out_ PHANDLE TimerQueueHandle
);
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateTimer(
_In_ HANDLE TimerQueueHandle,
_Out_ PHANDLE Handle,
_In_ WAITORTIMERCALLBACKFUNC 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
);
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_ HANDLE Event
);
#endif // !_KERNEL_MODE
//
// Registry access
//
NTSYSAPI
NTSTATUS
NTAPI
RtlFormatCurrentUserKeyPath(
_Out_ PUNICODE_STRING CurrentUserKeyPath
);
NTSYSAPI
NTSTATUS
NTAPI
RtlOpenCurrentUser(
_In_ ACCESS_MASK DesiredAccess,
_Out_ PHANDLE CurrentUserKey
);
#ifndef _KERNEL_MODE
//
// The following values for the RelativeTo parameter determine what the
// Path parameter to RtlQueryRegistryValues is relative to.
//
#define RTL_REGISTRY_ABSOLUTE 0 // Path is a full path
#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 // Low order bits are registry handle
#define RTL_REGISTRY_OPTIONAL 0x80000000 // Indicates the key node is optional
#endif // !_KERNEL_MODE
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateRegistryKey(
_In_ ULONG RelativeTo,
_In_ PWSTR Path
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckRegistryKey(
_In_ ULONG RelativeTo,
_In_ PWSTR Path
);
#ifndef _KERNEL_MODE
typedef
_Function_class_(RTL_QUERY_REGISTRY_ROUTINE)
_IRQL_requires_max_(PASSIVE_LEVEL)
_IRQL_requires_same_
NTSTATUS
NTAPI
RTL_QUERY_REGISTRY_ROUTINE(
_In_z_ PWSTR ValueName,
_In_ ULONG ValueType,
_In_reads_bytes_opt_(ValueLength) 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;
//
// The following flags specify how the Name field of a RTL_QUERY_REGISTRY_TABLE
// entry is interpreted. A NULL name indicates the end of the table.
//
#define RTL_QUERY_REGISTRY_SUBKEY 0x00000001 // Name is a subkey and remainder of
// table or until next subkey are value
// names for that subkey to look at.
#define RTL_QUERY_REGISTRY_TOPKEY 0x00000002 // Reset current key to original key for
// this and all following table entries.
#define RTL_QUERY_REGISTRY_REQUIRED 0x00000004 // Fail if no match found for this table
// entry.
#define RTL_QUERY_REGISTRY_NOVALUE 0x00000008 // Used to mark a table entry that has no
// value name, just wants a call out, not
// an enumeration of all values.
#define RTL_QUERY_REGISTRY_NOEXPAND 0x00000010 // Used to suppress the expansion of
// REG_MULTI_SZ into multiple callouts or
// to prevent the expansion of environment
// variable values in REG_EXPAND_SZ
#define RTL_QUERY_REGISTRY_DIRECT 0x00000020 // QueryRoutine field ignored. EntryContext
// field points to location to store value.
// For null terminated strings, EntryContext
// points to UNICODE_STRING structure that
// that describes maximum size of buffer.
// If .Buffer field is NULL then a buffer is
// allocated.
//
#define RTL_QUERY_REGISTRY_DELETE 0x00000040 // Used to delete value keys after they
// are queried.
#define RTL_QUERY_REGISTRY_NOSTRING 0x00000080 // THIS IS DEPRECATED - use RTL_QUERY_REGISTRY_TYPECHECK
//
// Used with RTL_QUERY_REGISTRY_DIRECT in
// cases where the caller expects a
// non-string value. Otherwise, the
// assumption that EntryContext points to
// a UNICODE_STRING structure can overrun
// the caller's buffer.
//
#define RTL_QUERY_REGISTRY_TYPECHECK 0x00000100 // Used with RTL_QUERY_REGISTRY_DIRECT to
// validate the registry value type
// expected by caller with actual type thats
// read from the registry.
//
// Use the most significant byte of DefaultType from QueryTable, as the
// caller's expected REG_TYPE
//
#define RTL_QUERY_REGISTRY_TYPECHECK_SHIFT 24
#define RTL_QUERY_REGISTRY_TYPECHECK_MASK (0xff << RTL_QUERY_REGISTRY_TYPECHECK_SHIFT)
#endif // !_KERNEL_MODE
#ifndef RtlQueryRegistryValues
_IRQL_requires_max_(PASSIVE_LEVEL)
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
);
#endif
// rev
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryRegistryValuesEx(
_In_ ULONG RelativeTo,
_In_ PCWSTR Path,
_In_ PRTL_QUERY_REGISTRY_TABLE QueryTable,
_In_ PVOID Context,
_In_opt_ PVOID Environment
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlWriteRegistryValue(
_In_ ULONG RelativeTo,
_In_ PCWSTR Path,
_In_z_ PCWSTR ValueName,
_In_ ULONG ValueType,
_In_reads_bytes_opt_(ValueLength) PVOID ValueData,
_In_ ULONG ValueLength
);
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
RtlDeleteRegistryValue(
_In_ ULONG RelativeTo,
_In_ PCWSTR Path,
_In_z_ PCWSTR ValueName
);
//
// Thread profiling
//
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN7)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlEnableThreadProfiling(
_In_ HANDLE ThreadHandle,
_In_ ULONG Flags,
_In_ ULONG64 HardwareCounters,
_Out_ PVOID* PerformanceDataHandle
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlDisableThreadProfiling(
_In_ PVOID PerformanceDataHandle
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryThreadProfiling(
_In_ HANDLE ThreadHandle,
_Out_ PBOOLEAN Enabled
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlReadThreadProfilingData(
_In_ HANDLE PerformanceDataHandle,
_In_ ULONG Flags,
_Out_ PPERFORMANCE_DATA PerformanceData
);
#endif
#endif // !_KERNEL_MODE
//
// WOW64
//
#ifndef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlGetNativeSystemInformation(
_In_ ULONG 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
);
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64EnableFsRedirection(
_In_ BOOLEAN Wow64FsEnableRedirection
);
NTSYSAPI
NTSTATUS
NTAPI
RtlWow64EnableFsRedirectionEx(
_In_ PVOID Wow64FsEnableRedirection,
_Out_ PVOID* OldFsRedirectionLevel
);
#endif // !_KERNEL_MODE
//
// Misc
//
NTSYSAPI
ULONG32
NTAPI
RtlComputeCrc32(
_In_ ULONG32 PartialCrc,
_In_ PVOID Buffer,
_In_ ULONG Length
);
#ifndef _KERNEL_MODE
NTSYSAPI
PVOID
NTAPI
RtlEncodePointer(
_In_ PVOID Ptr
);
NTSYSAPI
PVOID
NTAPI
RtlDecodePointer(
_In_ PVOID Ptr
);
NTSYSAPI
PVOID
NTAPI
RtlEncodeSystemPointer(
_In_ PVOID Ptr
);
NTSYSAPI
PVOID
NTAPI
RtlDecodeSystemPointer(
_In_ PVOID Ptr
);
#if (NTDDI_VERSION >= NTDDI_WIN10)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlEncodeRemotePointer(
_In_ HANDLE ProcessHandle,
_In_ PVOID Pointer,
_Out_ PVOID* EncodedPointer
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlDecodeRemotePointer(
_In_ HANDLE ProcessHandle,
_In_ PVOID Pointer,
_Out_ PVOID* DecodedPointer
);
#endif
#endif // !_KERNEL_MODE
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsProcessorFeaturePresent(
_In_ ULONG ProcessorFeature
);
#ifndef _KERNEL_MODE
// rev
NTSYSAPI
ULONG
NTAPI
RtlGetCurrentProcessorNumber(
VOID
);
#if (NTDDI_VERSION >= NTDDI_WIN10)
// rev
NTSYSAPI
VOID
NTAPI
RtlGetCurrentProcessorNumberEx(
_Out_ PPROCESSOR_NUMBER ProcessorNumber
);
#endif
#endif // !_KERNEL_MODE
//
// Stack support
//
#ifndef _KERNEL_MODE
NTSYSAPI
VOID
NTAPI
RtlPushFrame(
_In_ struct _TEB_ACTIVE_FRAME* Frame
);
NTSYSAPI
VOID
NTAPI
RtlPopFrame(
_In_ struct _TEB_ACTIVE_FRAME* Frame
);
NTSYSAPI
struct _TEB_ACTIVE_FRAME*
NTAPI
RtlGetFrame(
VOID
);
#endif // !_KERNEL_MODE
#define RTL_WALK_USER_MODE_STACK 0x00000001
#define RTL_WALK_VALID_FLAGS 0x00000001
#ifndef _KERNEL_MODE
#define RTL_STACK_WALKING_MODE_FRAMES_TO_SKIP_SHIFT 0x00000008
#endif // !_KERNEL_MODE
// 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
);
#ifndef _KERNEL_MODE
#if (defined(_M_AMD64) || defined(_M_IA64)) && !defined(_REALLY_GET_CALLERS_CALLER_)
#define RtlGetCallersAddress(CallersAddress, CallersCaller) \
*CallersAddress = (PVOID)_ReturnAddress(); \
*CallersCaller = NULL;
#else
NTSYSAPI
VOID
NTAPI
RtlGetCallersAddress(
_Out_ PVOID* CallersAddress,
_Out_ PVOID* CallersCaller
);
#endif
#endif // !_KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN7)
_IRQL_requires_max_(PASSIVE_LEVEL)
NTSYSAPI
ULONG64
NTAPI
RtlGetEnabledExtendedFeatures(
_In_ ULONG64 FeatureMask
);
#endif
#if (NTDDI_VERSION >= NTDDI_WIN10_RS4)
// msdn
_IRQL_requires_max_(PASSIVE_LEVEL)
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
// private
typedef union _RTL_ELEVATION_FLAGS
{
ULONG Flags;
struct
{
ULONG ElevationEnabled : 1;
ULONG VirtualizationEnabled : 1;
ULONG InstallerDetectEnabled : 1;
ULONG ReservedBits : 29;
};
} RTL_ELEVATION_FLAGS, * PRTL_ELEVATION_FLAGS;
#if (NTDDI_VERSION >= NTDDI_VISTA)
// private
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryElevationFlags(
_Out_ PRTL_ELEVATION_FLAGS Flags
);
#endif
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_VISTA)
// 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
);
#endif
#endif // !_KERNEL_MODE
//
// Event Trace
//
#ifndef _KERNEL_MODE
// begin_msdn:"Winternl"
#define RTL_UNLOAD_EVENT_TRACE_NUMBER 64
// private
typedef struct _RTL_UNLOAD_EVENT_TRACE
{
PVOID BaseAddress;
SIZE_T SizeOfImage;
ULONG Sequence;
ULONG TimeDateStamp;
ULONG CheckSum;
WCHAR ImageName[32];
ULONG Version[2];
} RTL_UNLOAD_EVENT_TRACE, * PRTL_UNLOAD_EVENT_TRACE;
typedef struct _RTL_UNLOAD_EVENT_TRACE32
{
ULONG BaseAddress;
ULONG SizeOfImage;
ULONG Sequence;
ULONG TimeDateStamp;
ULONG CheckSum;
WCHAR ImageName[32];
ULONG Version[2];
} RTL_UNLOAD_EVENT_TRACE32, * PRTL_UNLOAD_EVENT_TRACE32;
NTSYSAPI
PRTL_UNLOAD_EVENT_TRACE
NTAPI
RtlGetUnloadEventTrace(
VOID
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
NTSYSAPI
VOID
NTAPI
RtlGetUnloadEventTraceEx(
_Out_ PULONG * ElementSize,
_Out_ PULONG * ElementCount,
_Out_ PVOID * EventTrace // works across all processes
);
#endif
// end_msdn
#endif // !_KERNEL_MODE
//
// Performance Counter
//
#ifndef _KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN7)
// rev
NTSYSAPI
LOGICAL
NTAPI
RtlQueryPerformanceCounter(
_Out_ PLARGE_INTEGER PerformanceCounter
);
// rev
NTSYSAPI
LOGICAL
NTAPI
RtlQueryPerformanceFrequency(
_Out_ PLARGE_INTEGER PerformanceFrequency
);
#endif
#endif // !_KERNEL_MODE
//
// Image Mitigation
//
#ifndef _KERNEL_MODE
// 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
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;
typedef enum _RTL_IMAGE_MITIGATION_OPTION_STATE
{
RtlMitigationOptionStateNotConfigured,
RtlMitigationOptionStateOn,
RtlMitigationOptionStateOff
} RTL_IMAGE_MITIGATION_OPTION_STATE;
// 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 (NTDDI_VERSION >= NTDDI_WIN10_RS3)
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryImageMitigationPolicy(
_In_opt_ PWSTR 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_ PWSTR ImagePath, // NULL for system-wide defaults
_In_ IMAGE_MITIGATION_POLICY Policy,
_In_ ULONG Flags,
_Inout_ PVOID Buffer,
_In_ ULONG BufferSize
);
#endif
#endif // !_KERNEL_MODE
//
// session
//
// rev
NTSYSAPI
ULONG
NTAPI
RtlGetCurrentServiceSessionId(
VOID
);
#if (NTDDI_VERSION >= NTDDI_WIN10_RS1)
NTSYSAPI
ULONG
NTAPI
RtlGetActiveConsoleId(
VOID
);
NTSYSAPI
ULONGLONG
NTAPI
RtlGetConsoleSessionForegroundProcessId(
VOID
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlIsMultiSessionSku(
VOID
);
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlIsMultiUsersInSessionSku(
VOID
);
#else // NTDDI_VERSION >= NTDDI_WIN10_RS1
FORCEINLINE
ULONG
NTAPI
RtlGetActiveConsoleId(
VOID
)
{
return SharedUserData->ActiveConsoleId;
}
FORCEINLINE
ULONGLONG
NTAPI
RtlGetConsoleSessionForegroundProcessId(
VOID
)
{
return SharedUserData->ConsoleSessionForegroundProcessId;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
FORCEINLINE
BOOLEAN
NTAPI
RtlIsMultiSessionSku(
VOID
)
{
return SharedUserData->DbgMultiSessionSku;
}
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
FORCEINLINE
BOOLEAN
NTAPI
RtlIsMultiUsersInSessionSku(
VOID
)
{
return SharedUserData->DbgMultiUsersInSessionSku;
}
#endif // NTDDI_VERSION < NTDDI_WIN10_RS1
//
// Appcontainer
//
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetTokenNamedObjectPath(
_In_ HANDLE Token,
_In_opt_ PSID Sid,
_Out_ PUNICODE_STRING ObjectPath // RtlFreeUnicodeString
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetAppContainerNamedObjectPath(
_In_opt_ HANDLE Token,
_In_opt_ PSID AppContainerSid,
_In_ BOOLEAN RelativePath,
_Out_ PUNICODE_STRING ObjectPath // RtlFreeUnicodeString
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetAppContainerParent(
_In_ PSID AppContainerSid,
_Out_ PSID* AppContainerSidParent // RtlFreeSid
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckSandboxedToken(
_In_opt_ HANDLE TokenHandle,
_Out_ PBOOLEAN IsSandboxed
);
#ifdef _KERNEL_MODE
NTSYSAPI
BOOLEAN
NTAPI
RtlIsSandboxedToken(
_In_opt_ PSECURITY_SUBJECT_CONTEXT Context,
_In_ KPROCESSOR_MODE PreviousMode
);
#endif // _KERNEL_MODE
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckTokenCapability(
_In_opt_ HANDLE TokenHandle,
_In_ PSID CapabilitySidToCheck,
_Out_ PBOOLEAN HasCapability
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCapabilityCheck(
_In_opt_ HANDLE TokenHandle,
_In_ PUNICODE_STRING CapabilityName,
_Out_ PBOOLEAN HasCapability
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckTokenMembership(
_In_opt_ HANDLE TokenHandle,
_In_ PSID SidToCheck,
_Out_ PBOOLEAN IsMember
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckTokenMembershipEx(
_In_opt_ HANDLE TokenHandle,
_In_ PSID SidToCheck,
_In_ ULONG Flags, // CTMF_VALID_FLAGS
_Out_ PBOOLEAN IsMember
);
#ifndef _KERNEL_MODE
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryTokenHostIdAsUlong64(
_In_ HANDLE TokenHandle,
_Out_ PULONG64 HostId // (WIN://PKGHOSTID)
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsParentOfChildAppContainer(
_In_ PSID ParentAppContainerSid,
_In_ PSID ChildAppContainerSid
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsCapabilitySid(
_In_ PSID Sid
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsPackageSid(
_In_ PSID Sid
);
// rev
NTSYSAPI
BOOLEAN
NTAPI
RtlIsValidProcessTrustLabelSid(
_In_ PSID Sid
);
#endif // !_KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN10_RS4)
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
NTSYSAPI
BOOLEAN
NTAPI
RtlIsStateSeparationEnabled(
VOID
);
#endif // NTDDI_VERSION >= NTDDI_WIN10_RS4
typedef enum _APPCONTAINER_SID_TYPE
{
NotAppContainerSidType,
ChildAppContainerSidType,
ParentAppContainerSidType,
InvalidAppContainerSidType,
MaxAppContainerSidType
} APPCONTAINER_SID_TYPE, * PAPPCONTAINER_SID_TYPE;
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlGetAppContainerSidType(
_In_ PSID AppContainerSid,
_Out_ PAPPCONTAINER_SID_TYPE AppContainerSidType
);
//
// Fls
//
#ifndef _KERNEL_MODE
NTSYSAPI
NTSTATUS
NTAPI
RtlFlsAlloc(
_In_ PFLS_CALLBACK_FUNCTION Callback,
_Out_ PULONG FlsIndex
);
NTSYSAPI
NTSTATUS
NTAPI
RtlFlsFree(
_In_ ULONG FlsIndex
);
#endif // !_KERNEL_MODE
//
// File System
//
#ifndef _KERNEL_MODE
typedef enum _STATE_LOCATION_TYPE
{
LocationTypeRegistry = 0,
LocationTypeFileSystem = 1,
LocationTypeMaximum = 2
} STATE_LOCATION_TYPE;
_IRQL_requires_max_(PASSIVE_LEVEL)
_Must_inspect_result_
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 // !_KERNEL_MODE
//
// Placeholder file routines.
//
#if (NTDDI_VERSION >= NTDDI_WIN10_RS2)
NTSYSAPI
BOOLEAN
NTAPI
RtlIsCloudFilesPlaceholder(
_In_ ULONG FileAttributes,
_In_ ULONG ReparseTag
);
NTSYSAPI
BOOLEAN
NTAPI
RtlIsPartialPlaceholder(
_In_ ULONG FileAttributes,
_In_ ULONG ReparseTag
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIsPartialPlaceholderFileHandle(
_In_ HANDLE FileHandle,
_Out_ PBOOLEAN IsPartialPlaceholder
);
NTSYSAPI
NTSTATUS
NTAPI
RtlIsPartialPlaceholderFileInfo(
_In_ CONST VOID* InfoBuffer,
_In_ FILE_INFORMATION_CLASS InfoClass,
_Out_ PBOOLEAN IsPartialPlaceholder
);
#endif // NTDDI_VERSION >= NTDDI_WIN10_RS2
#if (NTDDI_VERSION >= NTDDI_WIN10_RS2)
NTSYSAPI
BOOLEAN
NTAPI
RtlIsNonEmptyDirectoryReparsePointAllowed(
_In_ ULONG ReparseTag
);
#endif // NTDDI_VERSION >= NTDDI_WIN10_RS2
#ifndef _KERNEL_MODE
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlAppxIsFileOwnedByTrustedInstaller(
_In_ HANDLE FileHandle,
_Out_ PBOOLEAN IsFileOwnedByTrustedInstaller
);
#endif // !_KERNEL_MODE
// rev
typedef struct _PS_PKG_CLAIM
{
ULONGLONG Flags;
ULONGLONG Origin;
} PS_PKG_CLAIM, * PPS_PKG_CLAIM;
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
);
//
// Process & Thread Placeholder
//
#if (NTDDI_VERSION >= NTDDI_WIN10_RS3)
#ifndef _KERNEL_MODE
#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)
#endif // !_KERNEL_MODE
NTSYSAPI
CHAR
NTAPI
RtlQueryThreadPlaceholderCompatibilityMode(
VOID
);
NTSYSAPI
CHAR
NTAPI
RtlSetThreadPlaceholderCompatibilityMode(
_In_ CHAR Mode
);
#endif // NTDDI_VERSION >= NTDDI_WIN10_RS3
#if (NTDDI_VERSION >= NTDDI_WIN10_RS4)
#ifndef _KERNEL_MODE
#undef PHCM_MAX
#define PHCM_DISGUISE_FULL_PLACEHOLDERS ((CHAR)3)
#define PHCM_MAX ((CHAR)3)
#define PHCM_ERROR_NO_PEB ((CHAR)-3)
#endif // !_KERNEL_MODE
NTSYSAPI
CHAR
NTAPI
RtlQueryProcessPlaceholderCompatibilityMode(
VOID
);
NTSYSAPI
CHAR
NTAPI
RtlSetProcessPlaceholderCompatibilityMode(
_In_ CHAR Mode
);
#endif // NTDDI_VERSION >= NTDDI_WIN10_RS4
//
// Protected policies
//
#ifndef _KERNEL_MODE
// 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 // !_KERNEL_MODE
//
// Boot Status Data
//
// private
typedef enum _RTL_BSD_ITEM_TYPE
{
RtlBsdItemVersionNumber, // q; s: ULONG
RtlBsdItemProductType, // q; s: NT_PRODUCT_TYPE (ULONG)
RtlBsdItemAabEnabled, // q: s: BOOLEAN
RtlBsdItemAabTimeout, // q: s: UCHAR
RtlBsdItemBootGood, // q: s: BOOLEAN
RtlBsdItemBootShutdown, // q: s: BOOLEAN
RtlBsdSleepInProgress, // q: s: BOOLEAN
RtlBsdPowerTransition,
RtlBsdItemBootAttemptCount, // q: s: UCHAR
RtlBsdItemBootCheckpoint, // q: s: UCHAR
RtlBsdItemBootId, // q; s: ULONG (USER_SHARED_DATA->BootId)
RtlBsdItemShutdownBootId, // q; s: ULONG
RtlBsdItemReportedAbnormalShutdownBootId, // q; s: ULONG
RtlBsdItemErrorInfo,
RtlBsdItemPowerButtonPressInfo,
RtlBsdItemChecksum, // q: s: UCHAR
RtlBsdPowerTransitionExtension,
RtlBsdItemFeatureConfigurationState, // q; s: ULONG
RtlBsdItemMax
} RTL_BSD_ITEM_TYPE;
// private
typedef struct _RTL_BSD_ITEM
{
RTL_BSD_ITEM_TYPE Type;
PVOID DataBuffer;
ULONG DataLength;
} RTL_BSD_ITEM, * PRTL_BSD_ITEM;
#ifndef _KERNEL_MODE
// ros
NTSYSAPI
NTSTATUS
NTAPI
RtlCreateBootStatusDataFile(
VOID
);
#endif // !_KERNEL_MODE
// 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
);
#ifndef _KERNEL_MODE
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckBootStatusIntegrity(
_In_ HANDLE FileHandle,
_Out_ PBOOLEAN Verified
);
#endif // !_KERNEL_MODE
#if (NTDDI_VERSION >= NTDDI_WIN10_RS3)
// 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
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlCheckPortableOperatingSystem(
_Out_ PBOOLEAN IsPortable // VOID
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSetPortableOperatingSystem(
_In_ BOOLEAN IsPortable
);
#if (NTDDI_VERSION >= NTDDI_VISTA)
NTSYSAPI
NTSTATUS
NTAPI
RtlFindClosestEncodableLength(
_In_ ULONGLONG SourceLength,
_Out_ PULONGLONG TargetLength
);
#endif
//
// Memory cache
//
#ifndef _KERNEL_MODE
typedef NTSTATUS(NTAPI* PRTL_SECURE_MEMORY_CACHE_CALLBACK)(
_In_ PVOID Address,
_In_ SIZE_T Length
);
// 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
);
#endif // !_KERNEL_MODE
//
// Feature configuration
//
#if (NTDDI_VERSION >= NTDDI_WIN10_RS3)
typedef struct _RTL_FEATURE_USAGE_REPORT
{
ULONG FeatureId;
USHORT ReportingKind;
USHORT ReportingOptions;
} RTL_FEATURE_USAGE_REPORT, * PRTL_FEATURE_USAGE_REPORT;
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlNotifyFeatureUsage(
_In_ PRTL_FEATURE_USAGE_REPORT FeatureUsageReport
);
typedef enum _RTL_FEATURE_CONFIGURATION_TYPE
{
RtlFeatureConfigurationBoot,
RtlFeatureConfigurationRuntime,
RtlFeatureConfigurationCount
} RTL_FEATURE_CONFIGURATION_TYPE;
// rev
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;
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryFeatureConfiguration(
_In_ ULONG FeatureId,
_In_ RTL_FEATURE_CONFIGURATION_TYPE FeatureType,
_Inout_ PULONGLONG ChangeStamp,
_In_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration
);
#ifndef _KERNEL_MODE
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSetFeatureConfigurations(
_Inout_ PULONGLONG ChangeStamp,
_In_ RTL_FEATURE_CONFIGURATION_TYPE FeatureType,
_In_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration,
_In_ ULONG FeatureConfigurationCount
);
#endif // !_KERNEL_MODE
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryAllFeatureConfigurations(
_In_ RTL_FEATURE_CONFIGURATION_TYPE FeatureType,
_Inout_ PULONGLONG ChangeStamp,
_Out_ PRTL_FEATURE_CONFIGURATION FeatureConfigurations,
_Inout_ PULONG FeatureConfigurationCount
);
// rev
NTSYSAPI
ULONGLONG
NTAPI
RtlQueryFeatureConfigurationChangeStamp(
VOID
);
#ifndef _KERNEL_MODE
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlQueryFeatureUsageNotificationSubscriptions(
_Out_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration,
_Inout_ PULONG FeatureConfigurationCount
);
#endif // !_KERNEL_MODE
typedef VOID(NTAPI* PRTL_FEATURE_CONFIGURATION_CHANGE_NOTIFICAION)(
_In_opt_ PVOID Context
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlRegisterFeatureConfigurationChangeNotification(
_In_ PRTL_FEATURE_CONFIGURATION_CHANGE_NOTIFICAION Callback,
_In_opt_ PVOID Context,
_Inout_opt_ PULONGLONG ChangeStamp,
_Out_ PHANDLE NotificationHandle
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlUnregisterFeatureConfigurationChangeNotification(
_In_ HANDLE NotificationHandle
);
#ifndef _KERNEL_MODE
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlSubscribeForFeatureUsageNotification(
_In_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration,
_In_ ULONG FeatureConfigurationCount
);
// rev
NTSYSAPI
NTSTATUS
NTAPI
RtlUnsubscribeFromFeatureUsageNotifications(
_In_ PRTL_FEATURE_CONFIGURATION FeatureConfiguration,
_In_ ULONG FeatureConfigurationCount
);
#endif // !_KERNEL_MODE
#endif // NTDDI_VERSION >= NTDDI_WIN10_RS3
//
// Only Kernel RTL
//
#ifdef _KERNEL_MODE
// FsRtl
FORCEINLINE
VOID
NTAPI
FsRtlSetTopLevelIrpForModWriter()
{
IoSetTopLevelIrp((PIRP)FSRTL_MOD_WRITE_TOP_LEVEL_IRP);
}
_Must_inspect_result_
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
NTSTATUS
NTAPI
FsRtlGetFileNameInformation( // -> FltMgr!FsRtlGetFileNameInformation
_In_ PFILE_OBJECT FileObject,
_In_ ULONG NameOptions, // FLT_FILE_NAME_OPTIONS
_Out_ PUNICODE_STRING FileName,
_Outptr_ PVOID* FileNameInformation // PFLT_FILE_NAME_INFORMATION
);
_IRQL_requires_max_(APC_LEVEL)
FORCEINLINE
NTSTATUS
NTAPI
FsRtlParseFileNameInformation(
_Inout_ PFLT_FILE_NAME_INFORMATION FileNameInformation
)
{
return FltParseFileNameInformation(FileNameInformation);
}
_IRQL_requires_max_(APC_LEVEL)
NTSYSAPI
VOID
NTAPI
FsRtlReleaseFileNameInformation(
_In_ PVOID FileNameInformation
);
#endif // _KERNEL_MODE
VEIL_END()
#if _MSC_VER >= 1200
#pragma warning(pop)
#endif