10970 lines
230 KiB
C
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
|