Created
December 7, 2024 05:56
-
-
Save hfiref0x/ab55c3983e195b8a4ad3b736ec6e6d31 to your computer and use it in GitHub Desktop.
ApiSet resolve Win7-Win11 (all versions)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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