diff options
| -rw-r--r-- | src/os/os_wine.c | 23 | ||||
| -rw-r--r-- | wine/common/wrt.c | 236 | ||||
| -rw-r--r-- | wine/include/wine/compiler.h | 32 | ||||
| -rw-r--r-- | wine/toolchain_mingw.cmake | 2 | ||||
| -rw-r--r-- | wine/wow64/CMakeLists.txt | 8 | ||||
| -rw-r--r-- | wine/wow64/wowbox64.c | 2 |
6 files changed, 284 insertions, 19 deletions
diff --git a/src/os/os_wine.c b/src/os/os_wine.c index 19955274..f2dd64c1 100644 --- a/src/os/os_wine.c +++ b/src/os/os_wine.c @@ -6,17 +6,13 @@ #include "os.h" #include "debug.h" +#include "wine/compiler.h" #include "wine/debug.h" #define HandleToULong(h) ((ULONG)(ULONG_PTR)(h)) NTSTATUS WINAPI NtYieldExecution(void); -static HANDLE myGetProcessHeap(void) -{ - return ((HANDLE**)NtCurrentTeb())[12][6]; -} - int GetTID(void) { @@ -105,13 +101,6 @@ static uint32_t prot_unix_to_win32(uint32_t unx) return 0; } -#define NtCurrentProcess() ((HANDLE) ~(ULONG_PTR)0) - -NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG*); -NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE, PVOID*, ULONG_PTR, SIZE_T*, ULONG, ULONG); -PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T); -NTSTATUS WINAPI NtFreeVirtualMemory(HANDLE, PVOID*, SIZE_T*, ULONG); - int mprotect(void* addr, size_t len, int prot) { NTSTATUS ntstatus; @@ -171,7 +160,7 @@ int InternalMunmap(void* addr, unsigned long length) void* WinMalloc(size_t size) { void* ret; - ret = RtlAllocateHeap(myGetProcessHeap(), 0, size); + ret = RtlAllocateHeap(GetProcessHeap(), 0, size); return ret; } @@ -180,25 +169,25 @@ void* WinRealloc(void* ptr, size_t size) void* ret; if (!ptr) return WinMalloc(size); - ret = RtlReAllocateHeap(myGetProcessHeap(), HEAP_ZERO_MEMORY, ptr, size); + ret = RtlReAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, ptr, size); return ret; } void* WinCalloc(size_t nmemb, size_t size) { void* ret; - ret = RtlAllocateHeap(myGetProcessHeap(), HEAP_ZERO_MEMORY, nmemb * size); + ret = RtlAllocateHeap(GetProcessHeap(), HEAP_ZERO_MEMORY, nmemb * size); return ret; } void WinFree(void* ptr) { - RtlFreeHeap(myGetProcessHeap(), 0, ptr); + RtlFreeHeap(GetProcessHeap(), 0, ptr); } void free(void* ptr) { - RtlFreeHeap(myGetProcessHeap(), 0, ptr); + RtlFreeHeap(GetProcessHeap(), 0, ptr); } int VolatileRangesContains(uintptr_t addr) diff --git a/wine/common/wrt.c b/wine/common/wrt.c new file mode 100644 index 00000000..d9725e4b --- /dev/null +++ b/wine/common/wrt.c @@ -0,0 +1,236 @@ +#include <windows.h> +#include <ntstatus.h> +#include <winternl.h> + +#include "debug.h" +#include "wine/compiler.h" +#include "wine/debug.h" + + +#define FILE_ATTRIBUTE_VALID_FLAGS 0x00007fb7 + +static UINT get_nt_file_options(DWORD attributes) +{ + UINT options = 0; + + if (attributes & FILE_FLAG_BACKUP_SEMANTICS) + options |= FILE_OPEN_FOR_BACKUP_INTENT; + else + options |= FILE_NON_DIRECTORY_FILE; + if (attributes & FILE_FLAG_DELETE_ON_CLOSE) + options |= FILE_DELETE_ON_CLOSE; + if (attributes & FILE_FLAG_NO_BUFFERING) + options |= FILE_NO_INTERMEDIATE_BUFFERING; + if (!(attributes & FILE_FLAG_OVERLAPPED)) + options |= FILE_SYNCHRONOUS_IO_NONALERT; + if (attributes & FILE_FLAG_RANDOM_ACCESS) + options |= FILE_RANDOM_ACCESS; + if (attributes & FILE_FLAG_SEQUENTIAL_SCAN) + options |= FILE_SEQUENTIAL_ONLY; + if (attributes & FILE_FLAG_WRITE_THROUGH) + options |= FILE_WRITE_THROUGH; + return options; +} + +HANDLE WINAPI CreateFileW(LPCWSTR filename, DWORD access, DWORD sharing, LPSECURITY_ATTRIBUTES sa, DWORD creation, DWORD attributes, HANDLE template) +{ + UNICODE_STRING filenameU; + OBJECT_ATTRIBUTES attr; + IO_STATUS_BLOCK io; + HANDLE ret; + + static const UINT nt_disposition[5] = { FILE_CREATE, FILE_OVERWRITE_IF, FILE_OPEN, FILE_OPEN_IF, FILE_OVERWRITE }; + if (!RtlDosPathNameToNtPathName_U(filename, &filenameU, NULL, NULL)) { + return INVALID_HANDLE_VALUE; + } + if (attributes & FILE_FLAG_DELETE_ON_CLOSE) access |= DELETE; + InitializeObjectAttributes(&attr, &filenameU, OBJ_CASE_INSENSITIVE, 0, NULL); + NTSTATUS status = NtCreateFile(&ret, access | GENERIC_READ | SYNCHRONIZE, &attr, &io, NULL, attributes & FILE_ATTRIBUTE_VALID_FLAGS, sharing, + nt_disposition[creation - CREATE_NEW], get_nt_file_options(attributes), NULL, 0); + RtlFreeUnicodeString(&filenameU); + return status ? INVALID_HANDLE_VALUE : ret; +} + +HANDLE WINAPI CreateFileA(LPCSTR name, DWORD access, DWORD sharing, LPSECURITY_ATTRIBUTES sa, DWORD creation, DWORD attributes, HANDLE template) +{ + UNICODE_STRING nameU; + RtlCreateUnicodeStringFromAsciiz(&nameU, name); + HANDLE handle = CreateFileW(nameU.Buffer, access, sharing, sa, creation, attributes, template); + RtlFreeUnicodeString(&nameU); + return handle; +} + + +BOOL WINAPI CloseHandle(HANDLE handle) +{ + return !NtClose(handle); +} + +DWORD WINAPI GetEnvironmentVariableA(LPCSTR name, LPSTR value, DWORD size) +{ + UNICODE_STRING nameU, valueU; + PWSTR valueW; + NTSTATUS status; + DWORD len, ret; + + if (!(valueW = RtlAllocateHeap(GetProcessHeap(), 0, size * sizeof(WCHAR)))) return 0; + + RtlCreateUnicodeStringFromAsciiz(&nameU, name); + valueU.Length = 0; + valueU.MaximumLength = (size ? size - 1 : 0) * sizeof(WCHAR); + valueU.Buffer = valueW; + + status = RtlQueryEnvironmentVariable_U(NULL, &nameU, &valueU); + len = valueU.Length / sizeof(WCHAR); + if (status == STATUS_BUFFER_TOO_SMALL) + ret = len + 1; + else if (status) + ret = 0; + else if (!size) + ret = len + 1; + else { + if (len) RtlUnicodeToMultiByteN(value, size, &ret, valueW, len * sizeof(WCHAR)); + } + + RtlFreeUnicodeString(&nameU); + RtlFreeHeap(GetProcessHeap(), 0, valueW); + return ret; +} + +DWORD WINAPI GetFileAttributesW(LPCWSTR name) +{ + FILE_BASIC_INFORMATION info; + UNICODE_STRING nameU; + OBJECT_ATTRIBUTES attr; + NTSTATUS status; + + if (!RtlDosPathNameToNtPathName_U(name, &nameU, NULL, NULL)) { + return INVALID_FILE_ATTRIBUTES; + } + + InitializeObjectAttributes(&attr, &nameU, OBJ_CASE_INSENSITIVE, 0, NULL); + status = NtQueryAttributesFile(&attr, &info); + RtlFreeUnicodeString(&nameU); + + if (status == STATUS_SUCCESS) return info.FileAttributes; + if (RtlIsDosDeviceName_U(name)) return FILE_ATTRIBUTE_ARCHIVE; + return INVALID_FILE_ATTRIBUTES; +} + +DWORD WINAPI GetFileAttributesA(LPCSTR name) +{ + UNICODE_STRING nameU; + RtlCreateUnicodeStringFromAsciiz(&nameU, name); + DWORD ret = GetFileAttributesW(nameU.Buffer); + RtlFreeUnicodeString(&nameU); + return ret; +} + +HANDLE WINAPI GetProcessHeap(void) +{ + return ((HANDLE**)NtCurrentTeb())[12][6]; +} + + +DWORD WINAPI GetModuleFileNameW(HMODULE module, LPWSTR filename, DWORD size) +{ + ULONG len = 0; + UNICODE_STRING filenameU; + NTSTATUS status; + + filenameU.Buffer = filename; + filenameU.MaximumLength = min(size, UNICODE_STRING_MAX_CHARS) * sizeof(WCHAR); + status = LdrGetDllFullName(module, &filenameU); + if (!status || status == STATUS_BUFFER_TOO_SMALL) len = filenameU.Length / sizeof(WCHAR); + return len; +} + + +DWORD WINAPI GetModuleFileNameA(HMODULE module, LPSTR filename, DWORD size) +{ + LPWSTR filenameW = RtlAllocateHeap(GetProcessHeap(), 0, size * sizeof(WCHAR)); + DWORD len, ret = 0; + + if (!filenameW) return 0; + + if ((len = GetModuleFileNameW(module, filenameW, size))) { + RtlUnicodeToMultiByteN(filename, size, &ret, filenameW, len * sizeof(WCHAR)); + if (ret < size) filename[ret] = 0; + } + RtlFreeHeap(GetProcessHeap(), 0, filenameW); + return ret; +} + +BOOL WINAPI ReadFile(HANDLE file, LPVOID buffer, DWORD count, LPDWORD result, LPOVERLAPPED overlapped) +{ + LARGE_INTEGER offset; + PLARGE_INTEGER poffset = NULL; + IO_STATUS_BLOCK iosb; + PIO_STATUS_BLOCK io_status = &iosb; + HANDLE event = 0; + NTSTATUS status; + LPVOID cvalue = NULL; + + if (result) *result = 0; + + if (overlapped) { + printf_log(LOG_NONE, "unimplemented overlapped in ReadFile\n"); + return FALSE; + } else + io_status->Information = 0; + io_status->Status = STATUS_PENDING; + + status = NtReadFile(file, event, NULL, cvalue, io_status, buffer, count, poffset, NULL); + + if (status == STATUS_PENDING && !overlapped) { + printf_log(LOG_NONE, "unimplemented pending in ReadFile\n"); + } + + if (result) *result = overlapped && status ? 0 : io_status->Information; + + if (status == STATUS_END_OF_FILE) { + if (overlapped != NULL) { + return FALSE; + } + } else if (status && status != STATUS_TIMEOUT) { + return FALSE; + } + return TRUE; +} + + +static void fillSystemInfo(SYSTEM_INFO* si, const SYSTEM_BASIC_INFORMATION__* basic_info, const SYSTEM_CPU_INFORMATION* cpu_info) +{ + si->wProcessorArchitecture = cpu_info->ProcessorArchitecture; + si->wReserved = 0; + si->dwPageSize = basic_info->PageSize; + si->lpMinimumApplicationAddress = basic_info->LowestUserAddress; + si->lpMaximumApplicationAddress = basic_info->HighestUserAddress; + si->dwActiveProcessorMask = basic_info->ActiveProcessorsAffinityMask; + si->dwNumberOfProcessors = basic_info->NumberOfProcessors; + si->dwAllocationGranularity = basic_info->AllocationGranularity; + si->wProcessorLevel = cpu_info->ProcessorLevel; + si->wProcessorRevision = cpu_info->ProcessorRevision; + + switch (cpu_info->ProcessorArchitecture) { + case PROCESSOR_ARCHITECTURE_ARM64: + si->dwProcessorType = 0; + break; + default: + printf_log(LOG_NONE, "Unknown processor architecture %x\n", cpu_info->ProcessorArchitecture); + si->dwProcessorType = 0; + break; + } +} + +void WINAPI GetSystemInfo(SYSTEM_INFO* si) +{ + SYSTEM_BASIC_INFORMATION__ basic_info; + SYSTEM_CPU_INFORMATION cpu_info; + + if (NtQuerySystemInformation(0 /* SystemBasicInformation */, &basic_info, sizeof(basic_info), NULL) + || NtQuerySystemInformation(1 /* SystemCpuInformation */, &cpu_info, sizeof(cpu_info), NULL)) + return; + + fillSystemInfo(si, &basic_info, &cpu_info); +} diff --git a/wine/include/wine/compiler.h b/wine/include/wine/compiler.h index f206c40d..a38f624b 100644 --- a/wine/include/wine/compiler.h +++ b/wine/include/wine/compiler.h @@ -50,16 +50,48 @@ typedef struct _XMM_SAVE_AREA32 { BYTE Reserved4[96]; } XMM_SAVE_AREA32; +typedef struct _SYSTEM_CPU_INFORMATION { + USHORT ProcessorArchitecture; + USHORT ProcessorLevel; + USHORT ProcessorRevision; + USHORT MaximumProcessors; + ULONG ProcessorFeatureBits; +} SYSTEM_CPU_INFORMATION, *PSYSTEM_CPU_INFORMATION; + +typedef struct _SYSTEM_BASIC_INFORMATION__ { + DWORD unknown; + ULONG KeMaximumIncrement; + ULONG PageSize; + ULONG MmNumberOfPhysicalPages; + ULONG MmLowestPhysicalPage; + ULONG MmHighestPhysicalPage; + ULONG_PTR AllocationGranularity; + PVOID LowestUserAddress; + PVOID HighestUserAddress; + ULONG_PTR ActiveProcessorsAffinityMask; + BYTE NumberOfProcessors; +} SYSTEM_BASIC_INFORMATION__, *PSYSTEM_BASIC_INFORMATION__; + #define NtCurrentProcess() ((HANDLE)(LONG_PTR) - 1) NTSTATUS WINAPI RtlWow64GetCurrentCpuArea(USHORT*, void**, void**); NTSTATUS WINAPI Wow64SystemServiceEx(UINT, UINT*); NTSYSAPI NTSTATUS WINAPI LdrGetDllHandle(LPCWSTR, ULONG, const UNICODE_STRING*, HMODULE*); +NTSYSAPI NTSTATUS WINAPI LdrGetDllFullName(HMODULE, UNICODE_STRING*); NTSYSAPI NTSTATUS WINAPI NtContinue(PCONTEXT, BOOLEAN); NTSYSAPI NTSTATUS WINAPI NtQueryVirtualMemory(HANDLE, LPCVOID, MEMORY_INFORMATION_CLASS, PVOID, SIZE_T, SIZE_T*); +NTSYSAPI NTSTATUS WINAPI NtReadFile(HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID, PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER, PULONG); NTSYSAPI void* WINAPI RtlFindExportedRoutineByName(HMODULE, const char*); NTSYSAPI void DECLSPEC_NORETURN WINAPI RtlRaiseStatus(NTSTATUS); NTSYSAPI void WINAPI RtlRaiseException(EXCEPTION_RECORD*); +NTSYSAPI NTSTATUS WINAPI RtlQueryEnvironmentVariable_U(PWSTR, PUNICODE_STRING, PUNICODE_STRING); +NTSYSAPI NTSTATUS WINAPI NtQueryAttributesFile(const OBJECT_ATTRIBUTES*, FILE_BASIC_INFORMATION*); +NTSYSAPI ULONG WINAPI RtlIsDosDeviceName_U(PCWSTR); +NTSYSAPI NTSTATUS WINAPI RtlUnicodeToMultiByteN(LPSTR, DWORD, LPDWORD, LPCWSTR, DWORD); +NTSTATUS WINAPI NtProtectVirtualMemory(HANDLE, PVOID*, SIZE_T*, ULONG, ULONG*); +NTSTATUS WINAPI NtAllocateVirtualMemory(HANDLE, PVOID*, ULONG_PTR, SIZE_T*, ULONG, ULONG); +PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T); +NTSTATUS WINAPI NtFreeVirtualMemory(HANDLE, PVOID*, SIZE_T*, ULONG); static inline uintptr_t calculate_fs(void) { diff --git a/wine/toolchain_mingw.cmake b/wine/toolchain_mingw.cmake index 0df2c964..46bfd07f 100644 --- a/wine/toolchain_mingw.cmake +++ b/wine/toolchain_mingw.cmake @@ -1,5 +1,7 @@ set(CMAKE_SYSTEM_NAME Windows) set(CMAKE_SYSTEM_PROCESSOR aarch64) +set(CMAKE_C_STANDARD_LIBRARIES "" CACHE STRING "" FORCE) + set(CMAKE_C_COMPILER aarch64-w64-mingw32-clang) set(CMAKE_ASM_COMPILER aarch64-w64-mingw32-as) \ No newline at end of file diff --git a/wine/wow64/CMakeLists.txt b/wine/wow64/CMakeLists.txt index 86da91c5..1ae1728b 100644 --- a/wine/wow64/CMakeLists.txt +++ b/wine/wow64/CMakeLists.txt @@ -25,6 +25,7 @@ string(REPLACE "," ";" INTERPRETER "${INTERPRETER_STR}") set(WOW64_MAIN_SRC "${BOX64_ROOT}/wine/common/crt.c" + "${BOX64_ROOT}/wine/common/wrt.c" "${BOX64_ROOT}/wine/wow64/wowbox64.c" ) @@ -136,7 +137,12 @@ import_dll(wow64) # always enable DynaRec, only supports ARM64 for now. add_compile_definitions(DYNAREC ARM64) -target_link_options(wowbox64 PRIVATE -nostdlib -nodefaultlibs -lclang_rt.builtins-aarch64 -Wl,--image-base,0x004c0000) +target_compile_options(wowbox64 PRIVATE -Wno-inconsistent-dllimport) +target_link_options(wowbox64 PRIVATE -nostdlib -nodefaultlibs + -lclang_rt.builtins-aarch64 + -Wl,--image-base,0x004c0000 + -Wl,/ignore:4217 # LNK4217: locally defined symbol imported +) set_target_properties(wowbox64 PROPERTIES PREFIX "" SUFFIX ".dll" diff --git a/wine/wow64/wowbox64.c b/wine/wow64/wowbox64.c index 141b534f..d1e74243 100644 --- a/wine/wow64/wowbox64.c +++ b/wine/wow64/wowbox64.c @@ -226,7 +226,7 @@ NTSTATUS WINAPI BTCpuProcessInit(void) InitializeEnvFiles(); TCHAR filename[MAX_PATH]; - if (GetModuleFileName(NULL, filename, MAX_PATH)) { + if (GetModuleFileNameA(NULL, filename, MAX_PATH)) { char* shortname = strrchr(filename, '\\'); if (shortname) { shortname++; |