mirror of
https://github.com/reactos/reactos.git
synced 2025-08-05 06:33:01 +00:00
Rework apisets to use a table
This removes all fake apiset forwarders, and handles apisets inside ntdll. This is not 100% compatible with how windows does it, but it should be good enough for us.
This commit is contained in:
parent
116c0cd9a5
commit
24a56f89ab
246 changed files with 1910 additions and 9091 deletions
92
sdk/lib/apisets/apisets.c
Normal file
92
sdk/lib/apisets/apisets.c
Normal file
|
@ -0,0 +1,92 @@
|
|||
/*
|
||||
* PROJECT: ReactOS apisets
|
||||
* LICENSE: LGPL-2.1-or-later (https://spdx.org/licenses/LGPL-2.1-or-later)
|
||||
* PURPOSE: Resolving the apiset to a ReactOS system dll
|
||||
* COPYRIGHT: Copyright 2024 Mark Jansen <mark.jansen@reactos.org>
|
||||
*/
|
||||
|
||||
#include <ndk/umtypes.h>
|
||||
#include <ndk/rtlfuncs.h>
|
||||
#include "apisetsp.h"
|
||||
|
||||
|
||||
const ULONGLONG API_ = (ULONGLONG)0x2D004900500041; /// L"API-"
|
||||
const ULONGLONG EXT_ = (ULONGLONG)0x2D005400580045; /// L"EXT-";
|
||||
|
||||
WORD PrefixSize = sizeof(L"api-") - sizeof(WCHAR);
|
||||
WORD ExtensionSize = sizeof(L".dll") - sizeof(WCHAR);
|
||||
|
||||
|
||||
// The official prototype according to the Windows kit 8.1 is:
|
||||
//NTSTATUS
|
||||
//ApiSetResolveToHost (
|
||||
// _In_ PCAPI_SET_NAMESPACE_ARRAY Schema,
|
||||
// _In_ PCUNICODE_STRING FileNameIn,
|
||||
// _In_opt_ PCUNICODE_STRING ParentName,
|
||||
// _Out_ PBOOLEAN Resolved,
|
||||
// _Out_ PUNICODE_STRING HostBinary
|
||||
// );
|
||||
|
||||
|
||||
NTSTATUS
|
||||
ApiSetResolveToHost(
|
||||
_In_ DWORD ApisetVersion,
|
||||
_In_ PCUNICODE_STRING ApiToResolve,
|
||||
_Out_ PBOOLEAN Resolved,
|
||||
_Out_ PUNICODE_STRING Output
|
||||
)
|
||||
{
|
||||
if (ApiToResolve->Length < PrefixSize)
|
||||
{
|
||||
*Resolved = FALSE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// Grab the first four chars from the string, converting the first 3 to uppercase
|
||||
PWSTR ApiSetNameBuffer = ApiToResolve->Buffer;
|
||||
ULONGLONG ApiSetNameBufferPrefix = ((ULONGLONG *)ApiSetNameBuffer)[0] & 0xFFFFFFDFFFDFFFDF;
|
||||
// Check if it matches either 'api-' or 'ext-'
|
||||
if (!(ApiSetNameBufferPrefix == API_ || ApiSetNameBufferPrefix == EXT_))
|
||||
{
|
||||
*Resolved = FALSE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
// If there is an extension, cut it off (we store apisets without extension)
|
||||
UNICODE_STRING Tmp = *ApiToResolve;
|
||||
const WCHAR *Extension = Tmp.Buffer + (Tmp.Length - ExtensionSize) / sizeof(WCHAR);
|
||||
if (!_wcsnicmp(Extension, L".dll", ExtensionSize / sizeof(WCHAR)))
|
||||
Tmp.Length -= ExtensionSize;
|
||||
|
||||
// Binary search the apisets
|
||||
// Ideally we should use bsearch here, but that drags in another dependency and we do not want that here.
|
||||
LONG UBnd = g_ApisetsCount - 1;
|
||||
LONG LBnd = 0;
|
||||
while (LBnd <= UBnd)
|
||||
{
|
||||
LONG Index = (UBnd - LBnd) / 2 + LBnd;
|
||||
|
||||
LONG result = RtlCompareUnicodeString(&Tmp, &g_Apisets[Index].Name, TRUE);
|
||||
if (result == 0)
|
||||
{
|
||||
// Check if this version is included
|
||||
if (g_Apisets[Index].dwOsVersions & ApisetVersion)
|
||||
{
|
||||
// Return a static string (does not have to be freed)
|
||||
*Resolved = TRUE;
|
||||
*Output = g_Apisets[Index].Target;
|
||||
}
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
else if (result < 0)
|
||||
{
|
||||
UBnd = Index - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
LBnd = Index + 1;
|
||||
}
|
||||
}
|
||||
*Resolved = FALSE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue