about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--src/os/os_wine.c23
-rw-r--r--wine/common/wrt.c236
-rw-r--r--wine/include/wine/compiler.h32
-rw-r--r--wine/toolchain_mingw.cmake2
-rw-r--r--wine/wow64/CMakeLists.txt8
-rw-r--r--wine/wow64/wowbox64.c2
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++;