Skip to content

Instantly share code, notes, and snippets.

@hfiref0x
Created December 7, 2024 05:56
Show Gist options
  • Save hfiref0x/ab55c3983e195b8a4ad3b736ec6e6d31 to your computer and use it in GitHub Desktop.
Save hfiref0x/ab55c3983e195b8a4ad3b736ec6e6d31 to your computer and use it in GitHub Desktop.
ApiSet resolve Win7-Win11 (all versions)
/*
* File: apiset.c
*
* Created on: Dec 06, 2024
*
* Modified on: Dec 06, 2024
*
* Project: WinDepends.Core
*
* Author: WinDepends dev team
*/
#include "core.h"
__forceinline wchar_t locase_w(wchar_t c)
{
if ((c >= 'A') && (c <= 'Z'))
return c + 0x20;
else
return c;
}
BOOL
NTAPI
ApiSetpValidateNameToResolve(
_In_ PCUNICODE_STRING ApiSetNameToResolve
)
{
WCHAR* ApiSetNameBuffer;
ULONGLONG ApiSetNameBufferPrefix;
if (ApiSetNameToResolve->Length < API_SET_PREFIX_NAME_U_LENGTH) {
return FALSE;
}
ApiSetNameBuffer = ApiSetNameToResolve->Buffer;
ApiSetNameBufferPrefix = API_SET_TO_UPPER_PREFIX(((ULONG64*)ApiSetNameBuffer)[0]);
if (ApiSetNameBufferPrefix != API_SET_PREFIX_API && ApiSetNameBufferPrefix != API_SET_PREFIX_EXT) {
return FALSE;
}
return TRUE;
}
PAPI_SET_NAMESPACE_ENTRY_V6
NTAPI
ApiSetpSearchForApiSetV6(
_In_ PAPI_SET_NAMESPACE_V6 ApiSetNamespace,
_In_ PWCHAR ApiSetNameToResolve,
_In_ USHORT ApiSetNameToResolveLength
)
{
WCHAR wch;
USHORT i;
ULONG entryHash;
LONG low, middle, high;
PAPI_SET_HASH_ENTRY_V6 HashEntry;
PAPI_SET_NAMESPACE_ENTRY_V6 FoundEntry;
if (!ApiSetNameToResolveLength) {
return NULL;
}
entryHash = 0;
for (i = 0; i < ApiSetNameToResolveLength; i++) {
wch = locase_w(ApiSetNameToResolve[i]);
entryHash = entryHash * ApiSetNamespace->HashMultiplier + wch;
}
FoundEntry = NULL;
low = 0;
middle = 0;
high = (LONG)ApiSetNamespace->Count - 1;
while (high >= low) {
middle = (low + high) >> 1;
HashEntry = API_SET_HASH_ENTRY_V6(ApiSetNamespace, middle);
if (entryHash < HashEntry->Hash) {
high = middle - 1;
}
else if (entryHash > HashEntry->Hash) {
low = middle + 1;
}
else {
FoundEntry = API_SET_NAMESPACE_ENTRY_V6(ApiSetNamespace, HashEntry);
break;
}
}
if (high < low) {
return NULL;
}
if (0 == gsup.RtlCompareUnicodeStrings(ApiSetNameToResolve,
ApiSetNameToResolveLength,
API_SET_NAMESPACE_ENTRY_NAME_V6(ApiSetNamespace, FoundEntry),
FoundEntry->HashNameLength / sizeof(WCHAR),
TRUE))
{
return FoundEntry;
}
return NULL;
}
PAPI_SET_VALUE_ENTRY_V6
NTAPI
ApiSetpSearchForApiSetHostV6(
_In_ PAPI_SET_NAMESPACE_ENTRY_V6 Entry,
_In_ WCHAR* ApiSetNameToResolve,
_In_ USHORT ApiSetNameToResolveLength,
_In_ PAPI_SET_NAMESPACE_V6 ApiSetNamespace
)
{
LONG result, low, middle, high;
PAPI_SET_VALUE_ENTRY_V6 FoundEntry;
PAPI_SET_VALUE_ENTRY_V6 ApiSetHostEntry;
FoundEntry = API_SET_VALUE_ENTRY_V6(ApiSetNamespace, Entry, 0);
high = (LONG)(Entry->Count - 1);
if (!high) {
return FoundEntry;
}
low = 1;
while (low <= high) {
middle = (low + high) >> 1;
ApiSetHostEntry = API_SET_VALUE_ENTRY_V6(ApiSetNamespace, Entry, middle);
result = gsup.RtlCompareUnicodeStrings(ApiSetNameToResolve,
ApiSetNameToResolveLength,
API_SET_VALUE_NAME_V6(ApiSetNamespace, ApiSetHostEntry),
ApiSetHostEntry->NameLength / sizeof(WCHAR),
TRUE);
if (result < 0) {
high = middle - 1;
}
else if (result > 0) {
low = middle + 1;
}
else {
FoundEntry = API_SET_VALUE_ENTRY_V6(ApiSetNamespace, Entry, middle);
break;
}
}
return FoundEntry;
}
NTSTATUS
NTAPI
ApiSetResolveToHostV6(
_In_ PAPI_SET_NAMESPACE ApiSetNamespace,
_In_ PCUNICODE_STRING ApiSetNameToResolve,
_In_opt_ PCUNICODE_STRING ParentName,
_Out_ PUNICODE_STRING Output
)
{
BOOLEAN Resolved = FALSE;
USHORT ApiSetEffectiveLength;
WCHAR* ApiSetNameBuffer, * pwch;
ULONG ApiSetNameBufferLength;
PAPI_SET_NAMESPACE_ENTRY_V6 ResolvedNamespaceEntry;
PAPI_SET_VALUE_ENTRY_V6 HostLibraryEntry;
do {
if (!ApiSetpValidateNameToResolve(ApiSetNameToResolve))
break;
ApiSetNameBuffer = ApiSetNameToResolve->Buffer;
ApiSetNameBufferLength = (ULONG)ApiSetNameToResolve->Length;
pwch = (WCHAR*)((ULONG_PTR)ApiSetNameBuffer + ApiSetNameBufferLength);
do {
if (ApiSetNameBufferLength <= 1)
break;
ApiSetNameBufferLength -= sizeof(WCHAR);
--pwch;
} while (*pwch != L'-');
ApiSetEffectiveLength = (USHORT)(ApiSetNameBufferLength / sizeof(WCHAR));
if (!ApiSetEffectiveLength) {
break;
}
ResolvedNamespaceEntry = ApiSetpSearchForApiSetV6((PAPI_SET_NAMESPACE_V6)ApiSetNamespace,
ApiSetNameBuffer,
ApiSetEffectiveLength);
if (!ResolvedNamespaceEntry) {
break;
}
if (ResolvedNamespaceEntry->Count > 1 && ParentName) {
HostLibraryEntry = ApiSetpSearchForApiSetHostV6(ResolvedNamespaceEntry,
ParentName->Buffer,
ParentName->Length / sizeof(WCHAR),
(PAPI_SET_NAMESPACE_V6)ApiSetNamespace);
}
else if (ResolvedNamespaceEntry->Count > 0) {
HostLibraryEntry = API_SET_VALUE_ENTRY_V6(ApiSetNamespace,
ResolvedNamespaceEntry,
0);
}
else {
break;
}
if (IS_API_SET_EMPTY_VALUE_ENTRY_V6(HostLibraryEntry)) {
return STATUS_APISET_NOT_HOSTED;
}
Output->Length = (USHORT)HostLibraryEntry->ValueLength;
Output->MaximumLength = Output->Length;
Output->Buffer = API_SET_VALUE_ENTRY_VALUE_V6(ApiSetNamespace, HostLibraryEntry);
Resolved = TRUE;
} while (FALSE);
return Resolved ? STATUS_SUCCESS : STATUS_APISET_NOT_PRESENT;
}
PAPI_SET_NAMESPACE_ENTRY_V4
NTAPI
ApiSetpSearchForApiSetV4(
_In_ PVOID Namespace,
_In_ PCUNICODE_STRING ApiSetNameToResolve
)
{
LONG result, low, middle, high;
PAPI_SET_NAMESPACE_ARRAY_V4 ApiSetNamespace;
PAPI_SET_NAMESPACE_ENTRY_V4 ApiSetNamespaceEntry;
UNICODE_STRING NamespaceEntry;
ApiSetNamespace = (PAPI_SET_NAMESPACE_ARRAY_V4)Namespace;
low = 0;
high = (LONG)(ApiSetNamespace->Count - 1);
while (high >= low) {
middle = (high + low) >> 1;
ApiSetNamespaceEntry = API_SET_NAMESPACE_ENTRY_V4(ApiSetNamespace, middle);
NamespaceEntry.Length = NamespaceEntry.MaximumLength = (USHORT)ApiSetNamespaceEntry->NameLength;
NamespaceEntry.Buffer = API_SET_NAMESPACE_ENTRY_NAME_V4(ApiSetNamespace, ApiSetNamespaceEntry);
result = gsup.RtlCompareUnicodeString(ApiSetNameToResolve, &NamespaceEntry, TRUE);
if (result < 0) {
high = middle - 1;
}
else if (result > 0) {
low = middle + 1;
}
else {
return ApiSetNamespaceEntry;
}
}
return NULL;
}
PAPI_SET_VALUE_ENTRY_V4
NTAPI
ApiSetpSearchForApiSetHostV4(
_In_ PAPI_SET_VALUE_ARRAY_V4 ApiSetValueArray,
_In_ PCUNICODE_STRING ApiSetNameToResolve,
_In_ PAPI_SET_NAMESPACE_ARRAY_V4 ApiSetNamespace
)
{
LONG result, low, middle, high;
PAPI_SET_VALUE_ENTRY_V4 ApiSetHostEntry;
UNICODE_STRING NamespaceEntry;
low = 1;
high = (LONG)(ApiSetValueArray->Count - 1);
while (high >= low) {
middle = (high + low) >> 1;
ApiSetHostEntry = API_SET_VALUE_ENTRY_V4(ApiSetNamespace, ApiSetValueArray, middle);
NamespaceEntry.Length = NamespaceEntry.MaximumLength = (USHORT)ApiSetHostEntry->NameLength;
NamespaceEntry.Buffer = API_SET_VALUE_ENTRY_NAME_V4(ApiSetNamespace, ApiSetHostEntry);
result = gsup.RtlCompareUnicodeString(ApiSetNameToResolve, &NamespaceEntry, TRUE);
if (result < 0) {
high = middle - 1;
}
else if (result > 0) {
low = middle + 1;
}
else {
return ApiSetHostEntry;
}
}
return NULL;
}
NTSTATUS
NTAPI
ApiSetResolveToHostV4(
_In_ PAPI_SET_NAMESPACE ApiSetNamespace,
_In_ PCUNICODE_STRING ApiSetNameToResolve,
_In_opt_ PCUNICODE_STRING ParentName,
_Out_ PUNICODE_STRING Output
)
{
BOOLEAN Resolved = FALSE;
PAPI_SET_NAMESPACE_ENTRY_V4 ResolvedNamespaceEntry;
PAPI_SET_VALUE_ARRAY_V4 ResolvedValueArray;
PAPI_SET_VALUE_ENTRY_V4 HostLibraryEntry;
UNICODE_STRING ApiSetNameNoExtString;
USHORT PrefixLength = sizeof(ULONGLONG);
do {
if (!ApiSetpValidateNameToResolve(ApiSetNameToResolve))
break;
ApiSetNameNoExtString.Length = ApiSetNameToResolve->Length - PrefixLength;
ApiSetNameNoExtString.MaximumLength = ApiSetNameNoExtString.Length;
ApiSetNameNoExtString.Buffer = (WCHAR*)((ULONG_PTR)ApiSetNameToResolve->Buffer +
PrefixLength);
if (ApiSetNameNoExtString.Length >= PrefixLength &&
ApiSetNameNoExtString.Buffer[(USHORT)(ApiSetNameNoExtString.Length - PrefixLength) / sizeof(WCHAR)] == L'.')
{
ApiSetNameNoExtString.Length -= PrefixLength;
}
ResolvedNamespaceEntry = ApiSetpSearchForApiSetV4(ApiSetNamespace,
&ApiSetNameNoExtString);
if (!ResolvedNamespaceEntry) {
break;
}
ResolvedValueArray = API_SET_NAMESPACE_ENTRY_DATA_V4(ApiSetNamespace,
ResolvedNamespaceEntry);
if (ResolvedValueArray->Count > 1 && ParentName) {
HostLibraryEntry = ApiSetpSearchForApiSetHostV4(ResolvedValueArray,
ParentName,
(PAPI_SET_NAMESPACE_ARRAY_V4)ApiSetNamespace);
}
else if (ResolvedValueArray->Count > 0) {
HostLibraryEntry = API_SET_VALUE_ENTRY_V4(ApiSetNamespace, ResolvedValueArray, 0);
}
else {
break;
}
if (IS_API_SET_EMPTY_VALUE_ENTRY_V4(HostLibraryEntry)) {
return STATUS_APISET_NOT_HOSTED;
}
Output->Length = (USHORT)HostLibraryEntry->ValueLength;
Output->MaximumLength = Output->Length;
Output->Buffer = API_SET_VALUE_ENTRY_VALUE_V4(ApiSetNamespace, HostLibraryEntry);
Resolved = TRUE;
} while (FALSE);
return Resolved ? STATUS_SUCCESS : STATUS_APISET_NOT_PRESENT;
}
PAPI_SET_VALUE_ENTRY_V2
NTAPI
ApiSetpSearchForApiSetHostV2(
_In_ PAPI_SET_VALUE_ARRAY_V2 ApiSetValueArray,
_In_ PCUNICODE_STRING ApiToResolve,
_In_ PAPI_SET_NAMESPACE ApiSetNamespace
)
{
LONG low, middle, high, result;
UNICODE_STRING ApiSetHostName;
PAPI_SET_VALUE_ENTRY_V2 ApiSetValueEntry;
low = 1;
high = ApiSetValueArray->Count - 1;
while (high >= low) {
middle = (high + low) >> 1;
ApiSetValueEntry = &ApiSetValueArray->Array[middle];
ApiSetHostName.Length = (USHORT)ApiSetValueEntry->NameLength;
ApiSetHostName.MaximumLength = ApiSetHostName.Length;
ApiSetHostName.Buffer = (WCHAR*)((ULONG_PTR)ApiSetNamespace + ApiSetValueEntry->NameOffset);
result = gsup.RtlCompareUnicodeString(ApiToResolve, &ApiSetHostName, TRUE);
if (result < 0) {
high = middle - 1;
}
else if (result > 0) {
low = middle + 1;
}
else {
return ApiSetValueEntry;
}
}
return NULL;
}
NTSTATUS
NTAPI
ApiSetResolveToHostV2(
_In_ PAPI_SET_NAMESPACE ApiSetNamespace,
_In_ PCUNICODE_STRING ApiSetNameToResolve,
_In_opt_ PCUNICODE_STRING ParentName,
_Out_ PUNICODE_STRING Output
)
{
BOOLEAN Resolved = FALSE;
LONG Low, Middle, High, Result;
PAPI_SET_NAMESPACE_ARRAY_V2 ApiSetNamespaceArray;
PAPI_SET_NAMESPACE_ENTRY_V2 ApiSetNamespaceEntry;
PAPI_SET_VALUE_ARRAY_V2 ApiSetValueArray;
PAPI_SET_VALUE_ENTRY_V2 HostLibraryEntry;
UNICODE_STRING ApiSetNamespaceString;
UNICODE_STRING ApiSetNameNoExtString;
USHORT PrefixLength = sizeof(ULONGLONG);
do {
if (!ApiSetpValidateNameToResolve(ApiSetNameToResolve))
break;
ApiSetNameNoExtString.Length = ApiSetNameToResolve->Length - PrefixLength;
ApiSetNameNoExtString.MaximumLength = ApiSetNameNoExtString.Length;
ApiSetNameNoExtString.Buffer = (WCHAR*)((ULONG_PTR)ApiSetNameToResolve->Buffer +
PrefixLength);
if (ApiSetNameNoExtString.Length >= PrefixLength &&
ApiSetNameNoExtString.Buffer[(USHORT)(ApiSetNameNoExtString.Length - PrefixLength) / sizeof(WCHAR)] == L'.')
{
ApiSetNameNoExtString.Length -= PrefixLength;
}
ApiSetNamespaceArray = (PAPI_SET_NAMESPACE_ARRAY_V2)ApiSetNamespace;
ApiSetNamespaceEntry = NULL;
Low = 0;
High = (LONG)(ApiSetNamespaceArray->Count - 1);
while (High >= Low) {
Middle = (Low + High) >> 1;
ApiSetNamespaceEntry = API_SET_NAMESPACE_ENTRY_V2(ApiSetNamespace, Middle);
ApiSetNamespaceString.Length = (USHORT)ApiSetNamespaceEntry->NameLength;
ApiSetNamespaceString.MaximumLength = ApiSetNamespaceString.Length;
ApiSetNamespaceString.Buffer = (WCHAR*)((ULONG_PTR)ApiSetNamespace + ApiSetNamespaceEntry->NameOffset);
Result = gsup.RtlCompareUnicodeString(&ApiSetNameNoExtString, &ApiSetNamespaceString, TRUE);
if (Result < 0) {
High = Middle - 1;
}
else if (Result > 0) {
Low = Middle + 1;
}
else {
break;
}
}
if (High < Low) {
break;
}
ApiSetValueArray = (PAPI_SET_VALUE_ARRAY_V2)((ULONG_PTR)ApiSetNamespace +
ApiSetNamespaceEntry->DataOffset);
if (ApiSetValueArray->Count > 1 && ParentName) {
HostLibraryEntry = ApiSetpSearchForApiSetHostV2(ApiSetValueArray,
ParentName,
ApiSetNamespace);
}
else {
HostLibraryEntry = NULL;
}
if (HostLibraryEntry == NULL) {
HostLibraryEntry = ApiSetValueArray->Array;
}
Output->Length = (USHORT)HostLibraryEntry->ValueLength;
Output->MaximumLength = Output->Length;
Output->Buffer = (WCHAR*)((ULONG_PTR)ApiSetNamespace + HostLibraryEntry->ValueOffset);
Resolved = TRUE;
} while (FALSE);
return Resolved ? STATUS_SUCCESS : STATUS_APISET_NOT_PRESENT;
}
/*
* File: apisetx.h
*
* Created on: Aug 27, 2024
*
* Modified on: Dec 06, 2024
*
* Project: WinDepends.Core
*
*/
#pragma once
#pragma once
#ifndef _APISETX_H_
#define _APISETX_H_
//
// Copy-pasted from MS headers from the pre nerfed state.
//
#ifndef API_SET_SECTION_NAME
#define API_SET_SECTION_NAME ".apiset"
#endif
#ifndef API_SET_SCHEMA_SUFFIX
#define API_SET_SCHEMA_SUFFIX L".sys"
#endif
#define API_SET_PREFIX_API (ULONGLONG)0x002D004900500041 /* L"API-" */
#define API_SET_PREFIX_EXT (ULONGLONG)0x002D005400580045 /* L"EXT-" */
#define API_SET_PREFIX_NAME_A "API-"
#define API_SET_PREFIX_NAME_A_SIZE (sizeof(API_SET_PREFIX_NAME_A) - sizeof(CHAR))
#define API_SET_PREFIX_NAME_A_LENGTH (RTL_NUMBER_OF(API_SET_PREFIX_NAME_A) - 1)
#define API_SET_PREFIX_NAME_U TEXT(API_SET_PREFIX_NAME_A)
#define API_SET_PREFIX_NAME_U_SIZE (sizeof(API_SET_PREFIX_NAME_U) - sizeof(WCHAR))
#define API_SET_PREFIX_NAME_U_LENGTH (RTL_NUMBER_OF(API_SET_PREFIX_NAME_U) - 1)
#define API_SET_EXTENSION_NAME_A "EXT-"
#define API_SET_EXTENSION_NAME_A_SIZE (sizeof(API_SET_EXTENSION_NAME_A) - sizeof(CHAR))
#define API_SET_EXTENSION_NAME_A_LENGTH (RTL_NUMBER_OF(API_SET_EXTENSION_NAME_A) - 1)
#define API_SET_EXTENSION_NAME_U TEXT(API_SET_EXTENSION_NAME_A)
#define API_SET_EXTENSION_NAME_U_SIZE (sizeof(API_SET_EXTENSION_NAME_U) - sizeof(WCHAR))
#define API_SET_EXTENSION_NAME_U_LENGTH (RTL_NUMBER_OF(API_SET_EXTENSION_NAME_U) - 1)
#define API_SET_DLL_EXT_A ".DLL"
#define API_SET_DLL_EXT_A_SIZE (sizeof(API_SET_DLL_EXT_A) - sizeof(CHAR))
#define API_SET_DLL_EXT_A_NAME_LENGTH (RTL_NUMBER_OF(API_SET_DLL_EXT_A) - 1)
#define API_SET_DLL_EXT_U TEXT(API_SET_DLL_EXT_A)
#define API_SET_DLL_EXT_U_SIZE (sizeof(API_SET_DLL_EXT_U) - sizeof(WCHAR))
#define API_SET_DLL_EXT_U_NAME_LENGTH (RTL_NUMBER_OF(API_SET_DLL_EXT_U) - 1)
#define API_SET_SCHEMA_FLAGS_SEALED 0x00000001UL
#define API_SET_SCHEMA_FLAGS_HOST_EXTENSION 0x00000002UL
#define API_SET_SCHEMA_ENTRY_FLAGS_SEALED 0x00000001UL
#define API_SET_SCHEMA_ENTRY_FLAGS_EXTENSION 0x00000002UL
#ifndef API_SET_SCHEMA_VERSION_V2
#define API_SET_SCHEMA_VERSION_V2 2
#endif
#ifndef API_SET_SCHEMA_VERSION_V3
#define API_SET_SCHEMA_VERSION_V3 3 //private
#endif
#ifndef API_SET_SCHEMA_VERSION_V4
#define API_SET_SCHEMA_VERSION_V4 4
#endif
#ifndef API_SET_SCHEMA_VERSION_V6
#define API_SET_SCHEMA_VERSION_V6 6
#endif
#define API_SET_TO_UPPER_PREFIX(x) ((x) & 0xFFFFFFDFFFDFFFDFULL)
//
// API Set Schema Version 2
//
typedef struct _API_SET_VALUE_ENTRY_V2 {
ULONG NameOffset;
ULONG NameLength;
ULONG ValueOffset;
ULONG ValueLength;
} API_SET_VALUE_ENTRY_V2, * PAPI_SET_VALUE_ENTRY_V2;
typedef struct _API_SET_VALUE_ARRAY_V2 {
ULONG Count;
API_SET_VALUE_ENTRY_V2 Array[ANYSIZE_ARRAY];
} API_SET_VALUE_ARRAY_V2, * PAPI_SET_VALUE_ARRAY_V2;
typedef struct _API_SET_NAMESPACE_ENTRY_V2 {
ULONG NameOffset;
ULONG NameLength;
ULONG DataOffset; // API_SET_VALUE_ARRAY
} API_SET_NAMESPACE_ENTRY_V2, * PAPI_SET_NAMESPACE_ENTRY_V2;
typedef struct _API_SET_NAMESPACE_ARRAY_V2 {
ULONG Version;
ULONG Count;
_Field_size_full_(Count) API_SET_NAMESPACE_ENTRY_V2 Array[ANYSIZE_ARRAY];
} API_SET_NAMESPACE_ARRAY_V2, * PAPI_SET_NAMESPACE_ARRAY_V2;
#define API_SET_NAMESPACE_ENTRY_V2(ApiSetNamespace, Index) \
(((PAPI_SET_NAMESPACE_ARRAY_V2)(ApiSetNamespace))->Array + Index)
//
// API Set Schema Version 4
//
typedef struct _API_SET_VALUE_ENTRY_V4 {
ULONG Flags;
ULONG NameOffset;
_Field_range_(0, UNICODE_STRING_MAX_BYTES) ULONG NameLength;
ULONG ValueOffset;
_Field_range_(0, UNICODE_STRING_MAX_BYTES) ULONG ValueLength;
} API_SET_VALUE_ENTRY_V4, * PAPI_SET_VALUE_ENTRY_V4;
_Struct_size_bytes_(FIELD_OFFSET(API_SET_VALUE_ARRAY_V4, Array) + (sizeof(API_SET_VALUE_ENTRY_V4) * Count))
typedef struct _API_SET_VALUE_ARRAY_V4 {
ULONG Flags;
ULONG Count;
_Field_size_full_(Count) API_SET_VALUE_ENTRY_V4 Array[ANYSIZE_ARRAY];
} API_SET_VALUE_ARRAY_V4, * PAPI_SET_VALUE_ARRAY_V4;
typedef struct _API_SET_NAMESPACE_ENTRY_V4 {
ULONG Flags;
ULONG NameOffset;
_Field_range_(0, UNICODE_STRING_MAX_BYTES) ULONG NameLength;
ULONG AliasOffset;
_Field_range_(0, UNICODE_STRING_MAX_BYTES) ULONG AliasLength;
ULONG DataOffset; // API_SET_VALUE_ARRAY_V4
} API_SET_NAMESPACE_ENTRY_V4, * PAPI_SET_NAMESPACE_ENTRY_V4;
_Struct_size_bytes_(Size)
typedef struct _API_SET_NAMESPACE_ARRAY_V4 {
ULONG Version;
ULONG Size;
ULONG Flags;
ULONG Count;
_Field_size_full_(Count) API_SET_NAMESPACE_ENTRY_V4 Array[ANYSIZE_ARRAY];
} API_SET_NAMESPACE_ARRAY_V4, * PAPI_SET_NAMESPACE_ARRAY_V4;
#define IS_API_SET_EMPTY_VALUE_ENTRY_V4(ValueEntry) \
((ValueEntry->ValueOffset == 0) && (ValueEntry->ValueLength == 0) && \
(ValueEntry->NameOffset == 0) && (ValueEntry->NameLength == 0))
#define API_SET_NAMESPACE_ENTRY_V4(ApiSetNamespace, Index) \
((PAPI_SET_NAMESPACE_ENTRY_V4)(((PAPI_SET_NAMESPACE_ARRAY_V4)(ApiSetNamespace))->Array + Index))
#define API_SET_NAMESPACE_ENTRY_NAME_V4(ApiSetNamespace, NamespaceEntry) \
((PWCHAR)((ULONG_PTR)(ApiSetNamespace) + ((PAPI_SET_NAMESPACE_ENTRY_V4)(NamespaceEntry))->NameOffset))
#define API_SET_NAMESPACE_ENTRY_DATA_V4(ApiSetNamespace, NamespaceEntry) \
((PAPI_SET_VALUE_ARRAY_V4)((ULONG_PTR)(ApiSetNamespace) + ((PAPI_SET_NAMESPACE_ENTRY_V4)(NamespaceEntry))->DataOffset))
#define API_SET_VALUE_ENTRY_V4(ApiSetNamespace, ResolvedValueArray, Index) \
((PAPI_SET_VALUE_ENTRY_V4)(((PAPI_SET_VALUE_ARRAY_V4)(ResolvedValueArray))->Array + Index))
#define API_SET_VALUE_ENTRY_NAME_V4(ApiSetNamespace, ApiSetValueEntry) \
((WCHAR*)((ULONG_PTR)(ApiSetNamespace) + ((PAPI_SET_VALUE_ENTRY_V4)(ApiSetValueEntry))->NameOffset))
#define API_SET_VALUE_ENTRY_VALUE_V4(ApiSetNamespace, ApiSetValueEntry) \
((WCHAR*)((ULONG_PTR)(ApiSetNamespace) + ((PAPI_SET_VALUE_ENTRY_V4)(ApiSetValueEntry))->ValueOffset))
//
// API Set Schema Version 6
//
typedef struct _API_SET_HASH_ENTRY_V6 {
ULONG Hash;
ULONG NamespaceIndex;
} API_SET_HASH_ENTRY_V6, * PAPI_SET_HASH_ENTRY_V6;
typedef struct _API_SET_NAMESPACE_ENTRY_V6 {
ULONG Flags;
ULONG NameOffset;
ULONG NameLength;
ULONG HashNameLength; //size of name up to the last hyphen
ULONG DataOffset; //API_SET_VALUE_ENTRY_V6
ULONG Count; //number of API_SET_VALUE_ENTRY_V6 at DataOffset
} API_SET_NAMESPACE_ENTRY_V6, * PAPI_SET_NAMESPACE_ENTRY_V6;
typedef struct _API_SET_VALUE_ENTRY_V6 {
ULONG Flags;
ULONG NameOffset;
ULONG NameLength;
ULONG ValueOffset;
ULONG ValueLength;
} API_SET_VALUE_ENTRY_V6, * PAPI_SET_VALUE_ENTRY_V6;
_Struct_size_bytes_(Size)
typedef struct _API_SET_NAMESPACE_V6 {
ULONG Version;
ULONG Size;
ULONG Flags;
ULONG Count;
ULONG NamespaceEntryOffset; //API_SET_NAMESPACE_ENTRY_V6
ULONG NamespaceHashesOffset; //_API_SET_HASH_ENTRY_V6
ULONG HashMultiplier;
} API_SET_NAMESPACE_V6, * PAPI_SET_NAMESPACE_V6;
#define IS_API_SET_EMPTY_VALUE_ENTRY_V6(ValueEntry) \
((ValueEntry->ValueOffset == 0) && (ValueEntry->ValueLength == 0) && \
(ValueEntry->NameOffset == 0) && (ValueEntry->NameLength == 0))
#define API_SET_VALUE_ENTRY_V6(Namespace, Entry, Index) \
((API_SET_VALUE_ENTRY_V6 *)RtlOffsetToPointer(Namespace, (Index) * sizeof(API_SET_VALUE_ENTRY_V6) + Entry->DataOffset))
#define API_SET_VALUE_NAME_V6(Namespace, Entry) \
((PWCHAR)RtlOffsetToPointer(Namespace, Entry->NameOffset))
#define API_SET_VALUE_ENTRY_VALUE_V6(ApiSetNamespace, Entry) \
((PWCHAR)((ULONG_PTR)(ApiSetNamespace) + ((PAPI_SET_VALUE_ENTRY_V6)(Entry))->ValueOffset))
#define API_SET_HASH_ENTRY_V6(Namespace, HashIndex) \
((API_SET_HASH_ENTRY_V6*)RtlOffsetToPointer(Namespace, Namespace->NamespaceHashesOffset + sizeof(ULONG64) * (HashIndex)))
#define API_SET_NAMESPACE_ENTRY_V6(Namespace, LookupHashEntry) \
((PAPI_SET_NAMESPACE_ENTRY_V6)RtlOffsetToPointer(Namespace, LookupHashEntry->NamespaceIndex * sizeof(API_SET_NAMESPACE_ENTRY_V6) + \
Namespace->NamespaceEntryOffset))
#define API_SET_NAMESPACE_ENTRY_NAME_V6(Namespace, NamespaceEntry) \
((PWCHAR)RtlOffsetToPointer(Namespace, NamespaceEntry->NameOffset))
typedef struct _API_SET_NAMESPACE {
ULONG Version;
} API_SET_NAMESPACE, * PAPI_SET_NAMESPACE;
NTSTATUS
NTAPI
ApiSetResolveToHostV6(
_In_ PAPI_SET_NAMESPACE ApiSetNamespace,
_In_ PCUNICODE_STRING ApiSetNameToResolve,
_In_opt_ PCUNICODE_STRING ParentName,
_Out_ PUNICODE_STRING Output);
NTSTATUS
NTAPI
ApiSetResolveToHostV4(
_In_ PAPI_SET_NAMESPACE ApiSetNamespace,
_In_ PCUNICODE_STRING ResolveName,
_In_opt_ PCUNICODE_STRING ParentName,
_Out_ PUNICODE_STRING Output);
NTSTATUS
NTAPI
ApiSetResolveToHostV2(
_In_ PAPI_SET_NAMESPACE ApiSetNamespace,
_In_ PCUNICODE_STRING ApiSetNameToResolve,
_In_opt_ PCUNICODE_STRING ParentName,
_Out_ PUNICODE_STRING Output);
#endif /* _APISETX_H_ */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment