ReactOS 0.4.16-dev-336-gb667d82
apisets.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS apisets
3 * LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
4 * PURPOSE: Resolving the apiset to a ReactOS system dll
5 * COPYRIGHT: Copyright 2024 Mark Jansen <mark.jansen@reactos.org>
6 */
7
8#include <ndk/umtypes.h>
9#include <ndk/rtlfuncs.h>
10#include "apisetsp.h"
11
12
13const ULONGLONG API_ = (ULONGLONG)0x2D004900500041;
14const ULONGLONG EXT_ = (ULONGLONG)0x2D005400580045;
15
16WORD PrefixSize = sizeof(L"api-") - sizeof(WCHAR);
17WORD ExtensionSize = sizeof(L".dll") - sizeof(WCHAR);
18
19
20// The official prototype according to the Windows kit 8.1 is:
21//NTSTATUS
22//ApiSetResolveToHost (
23// _In_ PCAPI_SET_NAMESPACE_ARRAY Schema,
24// _In_ PCUNICODE_STRING FileNameIn,
25// _In_opt_ PCUNICODE_STRING ParentName,
26// _Out_ PBOOLEAN Resolved,
27// _Out_ PUNICODE_STRING HostBinary
28// );
29
30
33 _In_ DWORD ApisetVersion,
34 _In_ PCUNICODE_STRING ApiToResolve,
35 _Out_ PBOOLEAN Resolved,
37)
38{
39 if (ApiToResolve->Length < PrefixSize)
40 {
41 *Resolved = FALSE;
42 return STATUS_SUCCESS;
43 }
44
45 // Grab the first four chars from the string, converting the first 3 to uppercase
46 PWSTR ApiSetNameBuffer = ApiToResolve->Buffer;
47 ULONGLONG ApiSetNameBufferPrefix = ((ULONGLONG *)ApiSetNameBuffer)[0] & 0xFFFFFFDFFFDFFFDF;
48 // Check if it matches either 'api-' or 'ext-'
49 if (!(ApiSetNameBufferPrefix == API_ || ApiSetNameBufferPrefix == EXT_))
50 {
51 *Resolved = FALSE;
52 return STATUS_SUCCESS;
53 }
54
55 // If there is an extension, cut it off (we store apisets without extension)
56 UNICODE_STRING Tmp = *ApiToResolve;
57 const WCHAR *Extension = Tmp.Buffer + (Tmp.Length - ExtensionSize) / sizeof(WCHAR);
58 if (!_wcsnicmp(Extension, L".dll", ExtensionSize / sizeof(WCHAR)))
59 Tmp.Length -= ExtensionSize;
60
61 // Binary search the apisets
62 // Ideally we should use bsearch here, but that drags in another dependency and we do not want that here.
63 LONG UBnd = g_ApisetsCount - 1;
64 LONG LBnd = 0;
65 while (LBnd <= UBnd)
66 {
67 LONG Index = (UBnd - LBnd) / 2 + LBnd;
68
70 if (result == 0)
71 {
72 // Check if this version is included
73 if (g_Apisets[Index].dwOsVersions & ApisetVersion)
74 {
75 // Return a static string (does not have to be freed)
76 *Resolved = TRUE;
78 }
79 return STATUS_SUCCESS;
80 }
81 else if (result < 0)
82 {
83 UBnd = Index - 1;
84 }
85 else
86 {
87 LBnd = Index + 1;
88 }
89 }
90 *Resolved = FALSE;
91 return STATUS_SUCCESS;
92}
const LONG g_ApisetsCount
const ROS_APISET g_Apisets[]
Definition: apisets.table.c:12
LONG NTSTATUS
Definition: precomp.h:26
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
ULONG RtlCompareUnicodeString(PUNICODE_STRING s1, PUNICODE_STRING s2, BOOLEAN UpCase)
Definition: string_lib.cpp:31
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
_Inout_opt_ PUNICODE_STRING Extension
Definition: fltkernel.h:1092
GLuint64EXT * result
Definition: glext.h:11304
#define _Out_
Definition: no_sal2.h:160
#define _In_
Definition: no_sal2.h:158
#define L(x)
Definition: ntvdm.h:50
long LONG
Definition: pedump.c:60
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
@ Output
Definition: arc.h:85
WORD ExtensionSize
Definition: apisets.c:17
const ULONGLONG API_
Definition: apisets.c:13
WORD PrefixSize
L"EXT-";.
Definition: apisets.c:16
const ULONGLONG EXT_
L"API-".
Definition: apisets.c:14
NTSTATUS ApiSetResolveToHost(_In_ DWORD ApisetVersion, _In_ PCUNICODE_STRING ApiToResolve, _Out_ PBOOLEAN Resolved, _Out_ PUNICODE_STRING Output)
Definition: apisets.c:32
#define STATUS_SUCCESS
Definition: shellext.h:65
const UNICODE_STRING Target
Definition: apisetsp.h:14
uint16_t * PWSTR
Definition: typedefs.h:56
unsigned char * PBOOLEAN
Definition: typedefs.h:53
uint64_t ULONGLONG
Definition: typedefs.h:67
_In_ WDFCOLLECTION _In_ ULONG Index
__wchar_t WCHAR
Definition: xmlstorage.h:180