2024-12-01 06:43:10 -03:00
/*
* Copyright ( c ) 2024 , stasoid < stasoid @ yahoo . com >
2025-08-29 13:27:41 -03:00
* Copyright ( c ) 2025 , ayeteadoe < ayeteadoe @ gmail . com >
2025-09-02 12:14:30 -03:00
* Copyright ( c ) 2025 , Ryszard Goc < ryszardgoc @ gmail . com >
2024-12-01 06:43:10 -03:00
*
* SPDX - License - Identifier : BSD - 2 - Clause
*/
// This header should be included only in cpp files.
// It should be included after all other files and should be separated from them by a non-#include line to prevent clang-format from changing header order.
# pragma once
2025-08-29 13:27:41 -03:00
# include <AK/Assertions.h>
2025-09-02 12:14:30 -03:00
# include <AK/Diagnostics.h>
2024-12-01 06:43:10 -03:00
# include <AK/Platform.h>
2026-02-17 10:23:39 -03:00
# ifdef AK_OS_WINDOWS
2024-12-01 06:43:10 -03:00
# define timeval dummy_timeval
2025-09-02 12:14:30 -03:00
# include <ntstatus.h>
2024-12-01 06:43:10 -03:00
# include <winsock2.h>
2025-09-02 12:14:30 -03:00
# include <winternl.h>
extern " C " {
// NOTE: These are documented here: https://learn.microsoft.com/en-us/windows/win32/devnotes/-win32-misclowlevelclientsupport
// If the function signature changes, we should catch it with GetProcAddress failing in most cases.
// None of these are marked deprecated and they seem to be used internally in the kernel.
NTAPI NTSTATUS NtAssociateWaitCompletionPacket (
_In_ HANDLE WaitCompletionPacketHandle ,
_In_ HANDLE IoCompletionHandle ,
_In_ HANDLE TargetObjectHandle ,
_In_opt_ PVOID KeyContext ,
_In_opt_ PVOID ApcContext ,
_In_ NTSTATUS IoStatus ,
_In_ ULONG_PTR IoStatusInformation ,
_Out_opt_ PBOOLEAN AlreadySignaled ) ;
NTAPI NTSTATUS NtCancelWaitCompletionPacket (
_In_ HANDLE WaitCompletionPacketHandle ,
_In_ BOOLEAN RemoveSignaledPacket ) ;
NTAPI NTSTATUS NtCreateWaitCompletionPacket (
_Out_ PHANDLE WaitCompletionPacketHandle ,
_In_ ACCESS_MASK DesiredAccess ,
_In_opt_ POBJECT_ATTRIBUTES ObjectAttributes ) ;
2026-01-02 21:48:45 -03:00
// https://learn.microsoft.com/en-us/windows/win32/seccng/processprng
BOOL WINAPI ProcessPrng ( PBYTE pbData , SIZE_T cbData ) ;
2025-09-02 12:14:30 -03:00
}
using PFN_NtCreateWaitCompletionPacket = decltype ( & NtCreateWaitCompletionPacket ) ;
using PFN_NtCancelWaitCompletionPacket = decltype ( & NtCancelWaitCompletionPacket ) ;
using PFN_NtAssociateWaitCompletionPacket = decltype ( & NtAssociateWaitCompletionPacket ) ;
2026-01-02 21:48:45 -03:00
using PFN_ProcessPrng = decltype ( & ProcessPrng ) ;
2025-09-02 12:14:30 -03:00
inline struct SystemApi {
PFN_NtAssociateWaitCompletionPacket NtAssociateWaitCompletionPacket = NULL ;
PFN_NtCancelWaitCompletionPacket NtCancelWaitCompletionPacket = NULL ;
PFN_NtCreateWaitCompletionPacket NtCreateWaitCompletionPacket = NULL ;
2026-01-02 21:48:45 -03:00
PFN_ProcessPrng ProcessPrng = NULL ;
2025-09-02 12:14:30 -03:00
SystemApi ( )
{
2026-01-02 21:48:45 -03:00
HMODULE hBcryptprimitives = LoadLibraryW ( L " bcryptprimitives.dll " ) ;
2025-09-02 12:14:30 -03:00
HMODULE hNtdll = GetModuleHandleW ( L " ntdll.dll " ) ;
2026-01-02 21:48:45 -03:00
VERIFY ( hBcryptprimitives ) ;
2025-09-02 12:14:30 -03:00
VERIFY ( hNtdll ) ;
AK_IGNORE_DIAGNOSTIC ( " -Wcast-function-type-mismatch " ,
NtAssociateWaitCompletionPacket = ( PFN_NtAssociateWaitCompletionPacket ) GetProcAddress ( hNtdll , " NtAssociateWaitCompletionPacket " ) ;
NtCancelWaitCompletionPacket = ( PFN_NtCancelWaitCompletionPacket ) GetProcAddress ( hNtdll , " NtCancelWaitCompletionPacket " ) ;
2026-01-02 21:48:45 -03:00
NtCreateWaitCompletionPacket = ( PFN_NtCreateWaitCompletionPacket ) GetProcAddress ( hNtdll , " NtCreateWaitCompletionPacket " ) ;
ProcessPrng = ( PFN_ProcessPrng ) GetProcAddress ( hBcryptprimitives , " ProcessPrng " ) ; )
2025-09-02 12:14:30 -03:00
VERIFY ( NtAssociateWaitCompletionPacket ) ;
VERIFY ( NtCancelWaitCompletionPacket ) ;
VERIFY ( NtCreateWaitCompletionPacket ) ;
2026-01-02 21:48:45 -03:00
VERIFY ( ProcessPrng ) ;
2025-09-02 12:14:30 -03:00
}
} g_system ;
2024-12-01 06:43:10 -03:00
# undef timeval
# undef IN
# pragma comment(lib, "ws2_32.lib")
# include <io.h>
2025-08-29 13:27:41 -03:00
# include <stdlib.h>
inline void initiate_wsa ( )
{
WSADATA wsa ;
WORD version = MAKEWORD ( 2 , 2 ) ;
int rc = WSAStartup ( version , & wsa ) ;
VERIFY ( rc = = 0 & & wsa . wVersion = = version ) ;
}
inline void terminate_wsa ( )
{
int rc = WSACleanup ( ) ;
VERIFY ( rc = = 0 ) ;
}
static void invalid_parameter_handler ( wchar_t const * , wchar_t const * , wchar_t const * , unsigned int , uintptr_t )
{
}
inline void override_crt_invalid_parameter_handler ( )
{
// Make _get_osfhandle return -1 instead of crashing on invalid fd in release (debug still __debugbreak's)
_set_invalid_parameter_handler ( invalid_parameter_handler ) ;
}
inline void windows_init ( )
{
initiate_wsa ( ) ;
override_crt_invalid_parameter_handler ( ) ;
}
inline void windows_shutdown ( )
{
terminate_wsa ( ) ;
}
2024-12-01 06:43:10 -03:00
# endif