mirror of
https://github.com/Noratrieb/portability.git
synced 2026-01-14 15:55:04 +01:00
stuff
This commit is contained in:
parent
a6de0298f2
commit
559186088f
2 changed files with 102 additions and 44 deletions
136
src/emulated.rs
136
src/emulated.rs
|
|
@ -2,7 +2,10 @@
|
||||||
#![allow(non_camel_case_types)]
|
#![allow(non_camel_case_types)]
|
||||||
|
|
||||||
mod base_defs {
|
mod base_defs {
|
||||||
use std::{ffi::CStr, fmt::Debug};
|
use std::{ffi::CStr, fmt::Debug, os::fd::RawFd, sync::atomic::Ordering};
|
||||||
|
|
||||||
|
pub(crate) type SIZE_T = usize;
|
||||||
|
pub(crate) type DWORD = i32;
|
||||||
|
|
||||||
pub(crate) type HANDLE = usize;
|
pub(crate) type HANDLE = usize;
|
||||||
|
|
||||||
|
|
@ -47,7 +50,21 @@ mod base_defs {
|
||||||
pub(super) mutex: std::sync::atomic::AtomicU64,
|
pub(super) mutex: std::sync::atomic::AtomicU64,
|
||||||
pub(super) pad: [u8; 40 - 8],
|
pub(super) pad: [u8; 40 - 8],
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) enum HandleImpl {
|
||||||
|
Fd(#[expect(dead_code)] RawFd),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl crate::GlobalStateWrapper {
|
||||||
|
pub(crate) fn crate_handle(&self, imp: HandleImpl) -> HANDLE {
|
||||||
|
let mut state = self.state.lock().unwrap();
|
||||||
|
let handle = state.next_handle_nr.fetch_add(1, Ordering::Relaxed);
|
||||||
|
assert!(state.handles.insert(handle, imp).is_none());
|
||||||
|
handle
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
pub(crate) use base_defs::HandleImpl;
|
||||||
|
|
||||||
macro_rules! define_emulation_entry {
|
macro_rules! define_emulation_entry {
|
||||||
($($name:ident,)*) => {
|
($($name:ident,)*) => {
|
||||||
|
|
@ -181,8 +198,8 @@ emulate!(
|
||||||
mod api_ms_win_core_synch_l1_2_0 {
|
mod api_ms_win_core_synch_l1_2_0 {
|
||||||
fn InitializeCriticalSectionEx(
|
fn InitializeCriticalSectionEx(
|
||||||
lpCriticalSection: *mut (),
|
lpCriticalSection: *mut (),
|
||||||
dwSpinCount: u32,
|
dwSpinCount: DWORD,
|
||||||
flags: u32,
|
flags: DWORD,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
delegate(kernel32)
|
delegate(kernel32)
|
||||||
}
|
}
|
||||||
|
|
@ -238,7 +255,7 @@ emulate!(
|
||||||
emulate!(
|
emulate!(
|
||||||
"api-ms-win-crt-runtime-l1-1-0.dll",
|
"api-ms-win-crt-runtime-l1-1-0.dll",
|
||||||
mod api_ms_win_crt_runtime_l1_1_0 {
|
mod api_ms_win_crt_runtime_l1_1_0 {
|
||||||
fn __p___argc() -> *const u32 {
|
fn __p___argc() -> *const DWORD {
|
||||||
static ARGC: i32 = 1;
|
static ARGC: i32 = 1;
|
||||||
(&raw const ARGC).cast()
|
(&raw const ARGC).cast()
|
||||||
}
|
}
|
||||||
|
|
@ -275,7 +292,7 @@ emulate!(
|
||||||
/// <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/initterm-initterm-e?view=msvc-170>
|
/// <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/initterm-initterm-e?view=msvc-170>
|
||||||
fn _initterm(_start: *const (), _end: *const ()) {}
|
fn _initterm(_start: *const (), _end: *const ()) {}
|
||||||
/// <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/initterm-initterm-e?view=msvc-170>
|
/// <https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/initterm-initterm-e?view=msvc-170>
|
||||||
fn _initterm_e(_start: *const (), _end: *const ()) -> u32 {
|
fn _initterm_e(_start: *const (), _end: *const ()) -> DWORD {
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
fn _register_onexit_function() {
|
fn _register_onexit_function() {
|
||||||
|
|
@ -339,9 +356,8 @@ emulate!(
|
||||||
fn AcquireSRWLockShared() {
|
fn AcquireSRWLockShared() {
|
||||||
todo!("AcquireSRWLockShared")
|
todo!("AcquireSRWLockShared")
|
||||||
}
|
}
|
||||||
fn AddVectoredExceptionHandler() {
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-addvectoredexceptionhandler>
|
||||||
todo!("AddVectoredExceptionHandler")
|
fn AddVectoredExceptionHandler(_first: u64, _handler: *const ()) {}
|
||||||
}
|
|
||||||
fn AssignProcessToJobObject() {
|
fn AssignProcessToJobObject() {
|
||||||
todo!("AssignProcessToJobObject")
|
todo!("AssignProcessToJobObject")
|
||||||
}
|
}
|
||||||
|
|
@ -473,8 +489,8 @@ emulate!(
|
||||||
todo!("FindNextFileW")
|
todo!("FindNextFileW")
|
||||||
}
|
}
|
||||||
/// <https://learn.microsoft.com/en-us/windows/win32/api/fibersapi/nf-fibersapi-flsalloc>
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/fibersapi/nf-fibersapi-flsalloc>
|
||||||
fn FlsAlloc(_callback: extern "win64" fn()) -> u32 {
|
fn FlsAlloc(_callback: extern "win64" fn()) -> DWORD {
|
||||||
const FLS_OUT_OF_INDEXES: u32 = -1_i32 as u32;
|
const FLS_OUT_OF_INDEXES: DWORD = -1_i32;
|
||||||
FLS_OUT_OF_INDEXES
|
FLS_OUT_OF_INDEXES
|
||||||
}
|
}
|
||||||
fn FlsFree() {
|
fn FlsFree() {
|
||||||
|
|
@ -519,8 +535,9 @@ emulate!(
|
||||||
fn GetComputerNameExW() {
|
fn GetComputerNameExW() {
|
||||||
todo!("GetComputerNameExW")
|
todo!("GetComputerNameExW")
|
||||||
}
|
}
|
||||||
fn GetConsoleMode() {
|
/// <https://learn.microsoft.com/en-us/windows/console/getconsolemode>
|
||||||
todo!("GetConsoleMode")
|
fn GetConsoleMode(_hConsoleHandle: HANDLE, _lpMode: *mut DWORD) -> bool {
|
||||||
|
true
|
||||||
}
|
}
|
||||||
fn GetConsoleOutputCP() {
|
fn GetConsoleOutputCP() {
|
||||||
todo!("GetConsoleOutputCP")
|
todo!("GetConsoleOutputCP")
|
||||||
|
|
@ -535,18 +552,19 @@ emulate!(
|
||||||
todo!("GetCurrentProcess")
|
todo!("GetCurrentProcess")
|
||||||
}
|
}
|
||||||
/// <https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocessid>
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentprocessid>
|
||||||
fn GetCurrentProcessId() -> u32 {
|
fn GetCurrentProcessId() -> DWORD {
|
||||||
std::process::id()
|
std::process::id() as DWORD
|
||||||
}
|
}
|
||||||
fn GetCurrentThread() {
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentthread>
|
||||||
todo!("GetCurrentThread")
|
fn GetCurrentThread() -> *mut () {
|
||||||
|
std::ptr::dangling_mut()
|
||||||
}
|
}
|
||||||
// <https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentthreadid>
|
// <https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-getcurrentthreadid>
|
||||||
fn GetCurrentThreadId() -> u32 {
|
fn GetCurrentThreadId() -> DWORD {
|
||||||
use std::sync::atomic;
|
use std::sync::atomic;
|
||||||
static THREAD_ID_COUNTER: atomic::AtomicU32 = atomic::AtomicU32::new(0);
|
static THREAD_ID_COUNTER: atomic::AtomicI32 = atomic::AtomicI32::new(0);
|
||||||
std::thread_local! {
|
std::thread_local! {
|
||||||
static THREAD_ID: u32 = THREAD_ID_COUNTER.fetch_add(1, atomic::Ordering::Relaxed);
|
static THREAD_ID: DWORD = THREAD_ID_COUNTER.fetch_add(1, atomic::Ordering::Relaxed);
|
||||||
}
|
}
|
||||||
|
|
||||||
THREAD_ID.with(|id| *id)
|
THREAD_ID.with(|id| *id)
|
||||||
|
|
@ -587,8 +605,8 @@ emulate!(
|
||||||
fn GetFullPathNameW() {
|
fn GetFullPathNameW() {
|
||||||
todo!("GetFullPathNameW")
|
todo!("GetFullPathNameW")
|
||||||
}
|
}
|
||||||
fn GetLastError() -> u32 {
|
fn GetLastError() -> DWORD {
|
||||||
1
|
crate::THREAD_STATE.with(|state| (*state.state.borrow().teb).last_error_number)
|
||||||
}
|
}
|
||||||
fn GetLocaleInfoEx() {
|
fn GetLocaleInfoEx() {
|
||||||
todo!("GetLocaleInfoEx")
|
todo!("GetLocaleInfoEx")
|
||||||
|
|
@ -602,13 +620,15 @@ emulate!(
|
||||||
fn GetModuleFileNameW() {
|
fn GetModuleFileNameW() {
|
||||||
todo!("GetModuleFileNameW")
|
todo!("GetModuleFileNameW")
|
||||||
}
|
}
|
||||||
fn GetModuleHandleA() {
|
fn GetModuleHandleA() -> HANDLE {
|
||||||
todo!("GetModuleHandleA")
|
tracing::error!("TODO GetModuleHandleW");
|
||||||
|
0
|
||||||
}
|
}
|
||||||
fn GetModuleHandleExW() {
|
fn GetModuleHandleExW() -> HANDLE {
|
||||||
todo!("GetModuleHandleExW")
|
tracing::error!("TODO GetModuleHandleW");
|
||||||
|
0
|
||||||
}
|
}
|
||||||
fn GetModuleHandleW() -> u64 {
|
fn GetModuleHandleW() -> HANDLE {
|
||||||
tracing::error!("TODO GetModuleHandleW");
|
tracing::error!("TODO GetModuleHandleW");
|
||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
@ -634,8 +654,9 @@ emulate!(
|
||||||
// TODO: error handling...
|
// TODO: error handling...
|
||||||
crate::va_for_dll_export_by_name(&dll, lpProcName.as_cstr(), 0)
|
crate::va_for_dll_export_by_name(&dll, lpProcName.as_cstr(), 0)
|
||||||
}
|
}
|
||||||
fn GetProcessHeap() {
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-getprocessheap>
|
||||||
todo!("GetProcessHeap")
|
fn GetProcessHeap() -> HANDLE {
|
||||||
|
1
|
||||||
}
|
}
|
||||||
fn GetProcessId() {
|
fn GetProcessId() {
|
||||||
todo!("GetProcessId")
|
todo!("GetProcessId")
|
||||||
|
|
@ -646,8 +667,20 @@ emulate!(
|
||||||
fn GetStartupInfoW() {
|
fn GetStartupInfoW() {
|
||||||
todo!("GetStartupInfoW")
|
todo!("GetStartupInfoW")
|
||||||
}
|
}
|
||||||
fn GetStdHandle() {
|
/// <https://learn.microsoft.com/en-us/windows/console/getstdhandle>
|
||||||
todo!("GetStdHandle")
|
fn GetStdHandle(nStdHandle: DWORD) -> HANDLE {
|
||||||
|
const STD_INPUT_HANDLE: DWORD = -10;
|
||||||
|
const STD_OUTPUT_HANDLE: DWORD = -11;
|
||||||
|
const STD_ERROR_HANDLE: DWORD = -12;
|
||||||
|
|
||||||
|
let fd = match nStdHandle {
|
||||||
|
STD_INPUT_HANDLE => 0,
|
||||||
|
STD_OUTPUT_HANDLE => 1,
|
||||||
|
STD_ERROR_HANDLE => 2,
|
||||||
|
_ => panic!("invalid std handle: {nStdHandle}"),
|
||||||
|
};
|
||||||
|
|
||||||
|
crate::GLOBAL_STATE.crate_handle(HandleImpl::Fd(fd))
|
||||||
}
|
}
|
||||||
fn GetStringTypeW() {
|
fn GetStringTypeW() {
|
||||||
todo!("GetStringTypeW")
|
todo!("GetStringTypeW")
|
||||||
|
|
@ -665,8 +698,8 @@ emulate!(
|
||||||
fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: *mut std::ffi::c_void) {
|
fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: *mut std::ffi::c_void) {
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
struct _FILETIME {
|
struct _FILETIME {
|
||||||
dwLowDateTime: u32,
|
dwLowDateTime: DWORD,
|
||||||
dwHighDateTime: u32,
|
dwHighDateTime: DWORD,
|
||||||
}
|
}
|
||||||
lpSystemTimeAsFileTime.cast::<_FILETIME>().write(_FILETIME {
|
lpSystemTimeAsFileTime.cast::<_FILETIME>().write(_FILETIME {
|
||||||
dwLowDateTime: 0,
|
dwLowDateTime: 0,
|
||||||
|
|
@ -694,8 +727,23 @@ emulate!(
|
||||||
fn GetWindowsDirectoryW() {
|
fn GetWindowsDirectoryW() {
|
||||||
todo!("GetWindowsDirectoryW")
|
todo!("GetWindowsDirectoryW")
|
||||||
}
|
}
|
||||||
fn HeapAlloc() {
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/heapapi/nf-heapapi-heapalloc>
|
||||||
todo!("HeapAlloc")
|
fn HeapAlloc(heap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> *mut u8 {
|
||||||
|
const HEAP_GENERATE_EXCEPTIONS: DWORD = 0x00000004;
|
||||||
|
const HEAP_ZERO_MEMORY: DWORD = 0x00000008;
|
||||||
|
assert_eq!(heap, 1);
|
||||||
|
|
||||||
|
let layout = std::alloc::Layout::from_size_align(dwBytes as usize, 8).unwrap();
|
||||||
|
|
||||||
|
let result = if (dwFlags & HEAP_ZERO_MEMORY) == 1 {
|
||||||
|
std::alloc::alloc_zeroed(layout)
|
||||||
|
} else {
|
||||||
|
std::alloc::alloc(layout)
|
||||||
|
};
|
||||||
|
if (dwFlags & HEAP_GENERATE_EXCEPTIONS) == 1 && result.is_null() {
|
||||||
|
panic!("throw exception lol");
|
||||||
|
}
|
||||||
|
result
|
||||||
}
|
}
|
||||||
fn HeapFree() {
|
fn HeapFree() {
|
||||||
todo!("HeapFree")
|
todo!("HeapFree")
|
||||||
|
|
@ -729,8 +777,8 @@ emulate!(
|
||||||
}
|
}
|
||||||
fn InitializeCriticalSectionEx(
|
fn InitializeCriticalSectionEx(
|
||||||
lpCriticalSection: *mut (),
|
lpCriticalSection: *mut (),
|
||||||
_dwSpinCount: u32,
|
_dwSpinCount: DWORD,
|
||||||
_flags: u32,
|
_flags: DWORD,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
lpCriticalSection
|
lpCriticalSection
|
||||||
.cast::<CRITICAL_SECTION>()
|
.cast::<CRITICAL_SECTION>()
|
||||||
|
|
@ -755,7 +803,7 @@ emulate!(
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
/// <https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent>
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-isprocessorfeaturepresent>
|
||||||
fn IsProcessorFeaturePresent(_ProcessorFeature: u32) -> bool {
|
fn IsProcessorFeaturePresent(_ProcessorFeature: DWORD) -> bool {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
fn IsThreadAFiber() {
|
fn IsThreadAFiber() {
|
||||||
|
|
@ -789,7 +837,7 @@ emulate!(
|
||||||
todo!("LoadLibraryExA")
|
todo!("LoadLibraryExA")
|
||||||
}
|
}
|
||||||
/// <https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw>
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/libloaderapi/nf-libloaderapi-loadlibraryexw>
|
||||||
fn LoadLibraryExW(lpLibFileName: LPCWSTR, _hFile: HANDLE, _dwFlags: u32) -> u64 {
|
fn LoadLibraryExW(lpLibFileName: LPCWSTR, _hFile: HANDLE, _dwFlags: DWORD) -> u64 {
|
||||||
let result = crate::load_dll(
|
let result = crate::load_dll(
|
||||||
&format!("{}.dll", &lpLibFileName.to_string()),
|
&format!("{}.dll", &lpLibFileName.to_string()),
|
||||||
&crate::GLOBAL_STATE.executable_path(),
|
&crate::GLOBAL_STATE.executable_path(),
|
||||||
|
|
@ -814,6 +862,7 @@ emulate!(
|
||||||
fn MoveFileExW() {
|
fn MoveFileExW() {
|
||||||
todo!("MoveFileExW")
|
todo!("MoveFileExW")
|
||||||
}
|
}
|
||||||
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar>
|
||||||
fn MultiByteToWideChar() {
|
fn MultiByteToWideChar() {
|
||||||
todo!("MultiByteToWideChar")
|
todo!("MultiByteToWideChar")
|
||||||
}
|
}
|
||||||
|
|
@ -924,8 +973,10 @@ emulate!(
|
||||||
fn SetInformationJobObject() {
|
fn SetInformationJobObject() {
|
||||||
todo!("SetInformationJobObject")
|
todo!("SetInformationJobObject")
|
||||||
}
|
}
|
||||||
fn SetLastError() {
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setlasterror>
|
||||||
todo!("SetLastError")
|
fn SetLastError(dw_err_code: DWORD) {
|
||||||
|
crate::THREAD_STATE
|
||||||
|
.with(|state| (*state.state.borrow_mut().teb).last_error_number = dw_err_code);
|
||||||
}
|
}
|
||||||
fn SetProcessAffinityMask() {
|
fn SetProcessAffinityMask() {
|
||||||
todo!("SetProcessAffinityMask")
|
todo!("SetProcessAffinityMask")
|
||||||
|
|
@ -936,9 +987,8 @@ emulate!(
|
||||||
fn SetThreadErrorMode() {
|
fn SetThreadErrorMode() {
|
||||||
todo!("SetThreadErrorMode")
|
todo!("SetThreadErrorMode")
|
||||||
}
|
}
|
||||||
fn SetThreadStackGuarantee() {
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreadstackguarantee>
|
||||||
todo!("SetThreadStackGuarantee")
|
fn SetThreadStackGuarantee(_stack_size_in_bytes: *mut u64) {}
|
||||||
}
|
|
||||||
/// <https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setunhandledexceptionfilter>
|
/// <https://learn.microsoft.com/en-us/windows/win32/api/errhandlingapi/nf-errhandlingapi-setunhandledexceptionfilter>
|
||||||
fn SetUnhandledExceptionFilter(_lpTopLevelExceptionFilter: *mut ()) -> *mut () {
|
fn SetUnhandledExceptionFilter(_lpTopLevelExceptionFilter: *mut ()) -> *mut () {
|
||||||
std::ptr::null_mut()
|
std::ptr::null_mut()
|
||||||
|
|
|
||||||
10
src/lib.rs
10
src/lib.rs
|
|
@ -10,7 +10,7 @@ use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
ptr,
|
ptr,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicU64, Ordering},
|
atomic::{AtomicU64, AtomicUsize, Ordering},
|
||||||
LazyLock, Mutex,
|
LazyLock, Mutex,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -293,6 +293,8 @@ pub fn execute(pe: &[u8], executable_path: &Path) {
|
||||||
client_id_unique_thread: 0,
|
client_id_unique_thread: 0,
|
||||||
active_rpc_handle: ptr::null(),
|
active_rpc_handle: ptr::null(),
|
||||||
thread_local_storage_pointer: &raw mut main_tls_slots,
|
thread_local_storage_pointer: &raw mut main_tls_slots,
|
||||||
|
peb: ptr::null(),
|
||||||
|
last_error_number: 0,
|
||||||
};
|
};
|
||||||
main_teb.tib.this = &raw const main_teb;
|
main_teb.tib.this = &raw const main_teb;
|
||||||
|
|
||||||
|
|
@ -386,6 +388,8 @@ struct TheGlobalState {
|
||||||
hmodule_to_dll: HashMap<u64, LoadedDll>,
|
hmodule_to_dll: HashMap<u64, LoadedDll>,
|
||||||
next_emulated_hmodule_idx: AtomicU64,
|
next_emulated_hmodule_idx: AtomicU64,
|
||||||
tls_slots: Vec<TlsSlot>,
|
tls_slots: Vec<TlsSlot>,
|
||||||
|
handles: HashMap<usize, emulated::HandleImpl>,
|
||||||
|
next_handle_nr: AtomicUsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum TlsSlot {
|
enum TlsSlot {
|
||||||
|
|
@ -436,6 +440,8 @@ static GLOBAL_STATE: GlobalStateWrapper = GlobalStateWrapper {
|
||||||
hmodule_to_dll: HashMap::new(),
|
hmodule_to_dll: HashMap::new(),
|
||||||
next_emulated_hmodule_idx: AtomicU64::new(1),
|
next_emulated_hmodule_idx: AtomicU64::new(1),
|
||||||
tls_slots: Vec::new(),
|
tls_slots: Vec::new(),
|
||||||
|
handles: HashMap::new(),
|
||||||
|
next_handle_nr: AtomicUsize::new(1),
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|
@ -460,6 +466,8 @@ struct ThreadEnvironmentBlock {
|
||||||
client_id_unique_thread: u64, // handle,
|
client_id_unique_thread: u64, // handle,
|
||||||
active_rpc_handle: *const (),
|
active_rpc_handle: *const (),
|
||||||
thread_local_storage_pointer: *mut [*mut (); 64],
|
thread_local_storage_pointer: *mut [*mut (); 64],
|
||||||
|
peb: *const (),
|
||||||
|
last_error_number: i32,
|
||||||
}
|
}
|
||||||
const _: [(); 88] =
|
const _: [(); 88] =
|
||||||
[(); std::mem::offset_of!(ThreadEnvironmentBlock, thread_local_storage_pointer)];
|
[(); std::mem::offset_of!(ThreadEnvironmentBlock, thread_local_storage_pointer)];
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue