From 4a2bfec150ac8b78185d98324782da7841eddb9b Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 15 Apr 2018 12:57:45 -0400 Subject: fix linux implementation of self exe path closes #894 --- src/os.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/os.cpp') diff --git a/src/os.cpp b/src/os.cpp index e0491b21de..97462bd658 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -1007,6 +1007,7 @@ int os_self_exe_path(Buf *out_path) { buf_resize(out_path, buf_len(out_path) * 2); continue; } + buf_resize(out_path, amt); return 0; } #endif -- cgit v1.2.3 From 1c41f1ca6252faaa7750936c67562f1866a48075 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Apr 2018 20:54:52 -0400 Subject: better error reporting for missing libc on windows closes #931 --- src/analyze.cpp | 9 ++++++--- src/os.cpp | 3 +++ 2 files changed, 9 insertions(+), 3 deletions(-) (limited to 'src/os.cpp') diff --git a/src/analyze.cpp b/src/analyze.cpp index d142b86326..5dd7b0d18c 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -4433,7 +4433,8 @@ void find_libc_lib_path(CodeGen *g) { if (g->msvc_lib_dir == nullptr) { Buf* vc_lib_dir = buf_alloc(); if (os_get_win32_vcruntime_path(vc_lib_dir, g->zig_target.arch.arch)) { - zig_panic("Unable to determine vcruntime path."); + fprintf(stderr, "Unable to determine vcruntime path. --msvc-lib-dir"); + exit(1); } g->msvc_lib_dir = vc_lib_dir; } @@ -4441,7 +4442,8 @@ void find_libc_lib_path(CodeGen *g) { if (g->libc_lib_dir == nullptr) { Buf* ucrt_lib_path = buf_alloc(); if (os_get_win32_ucrt_lib_path(sdk, ucrt_lib_path, g->zig_target.arch.arch)) { - zig_panic("Unable to determine ucrt path."); + fprintf(stderr, "Unable to determine ucrt path. --libc-lib-dir"); + exit(1); } g->libc_lib_dir = ucrt_lib_path; } @@ -4449,7 +4451,8 @@ void find_libc_lib_path(CodeGen *g) { if (g->kernel32_lib_dir == nullptr) { Buf* kern_lib_path = buf_alloc(); if (os_get_win32_kern32_path(sdk, kern_lib_path, g->zig_target.arch.arch)) { - zig_panic("Unable to determine kernel32 path."); + fprintf(stderr, "Unable to determine kernel32 path. --kernel32-lib-dir"); + exit(1); } g->kernel32_lib_dir = kern_lib_path; } diff --git a/src/os.cpp b/src/os.cpp index 97462bd658..d335d8d218 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -1334,6 +1334,9 @@ com_done:; int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) { #if defined(ZIG_OS_WINDOWS) + if (buf_len(sdk->path10) == 0 || buf_len(sdk->version10) == 0) { + return ErrorFileNotFound; + } buf_resize(output_buf, 0); buf_appendf(output_buf, "%s\\Lib\\%s\\ucrt\\", buf_ptr(&sdk->path10), buf_ptr(&sdk->version10)); switch (platform_type) { -- cgit v1.2.3 From 25dff91fa099489858428a7071b8c76acf1f943d Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Apr 2018 21:08:52 -0400 Subject: fix windows build broken by previous commit fixes build failure from 1c41f1ca6252faaa7750936c67562f1866a48075 --- src/os.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/os.cpp') diff --git a/src/os.cpp b/src/os.cpp index d335d8d218..c93e2887b7 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -1334,7 +1334,7 @@ com_done:; int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) { #if defined(ZIG_OS_WINDOWS) - if (buf_len(sdk->path10) == 0 || buf_len(sdk->version10) == 0) { + if (buf_len(&sdk->path10) == 0 || buf_len(&sdk->version10) == 0) { return ErrorFileNotFound; } buf_resize(output_buf, 0); -- cgit v1.2.3 From 75328e32045d1275c03f1f37058ee0a3b775c632 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sun, 22 Apr 2018 21:47:25 -0400 Subject: exit(1) instead of abort() for file not found --- src/analyze.cpp | 6 ++++-- src/codegen.cpp | 6 ++++-- src/os.cpp | 3 --- 3 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/os.cpp') diff --git a/src/analyze.cpp b/src/analyze.cpp index 5dd7b0d18c..a598d7676e 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -4306,7 +4306,8 @@ bool handle_is_ptr(TypeTableEntry *type_entry) { static ZigWindowsSDK *get_windows_sdk(CodeGen *g) { if (g->win_sdk == nullptr) { if (os_find_windows_sdk(&g->win_sdk)) { - zig_panic("Unable to determine Windows SDK path."); + fprintf(stderr, "unable to determine windows sdk path\n"); + exit(1); } } assert(g->win_sdk != nullptr); @@ -4408,7 +4409,8 @@ void find_libc_include_path(CodeGen *g) { ZigWindowsSDK *sdk = get_windows_sdk(g); g->libc_include_dir = buf_alloc(); if (os_get_win32_ucrt_include_path(sdk, g->libc_include_dir)) { - zig_panic("Unable to determine libc include path."); + fprintf(stderr, "Unable to determine libc include path. --libc-include-dir"); + exit(1); } } else if (g->zig_target.os == OsLinux) { g->libc_include_dir = get_linux_libc_include_path(); diff --git a/src/codegen.cpp b/src/codegen.cpp index 4581c3e2b3..2d8c385f44 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -6638,12 +6638,14 @@ static void gen_root_source(CodeGen *g) { Buf *abs_full_path = buf_alloc(); int err; if ((err = os_path_real(rel_full_path, abs_full_path))) { - zig_panic("unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err)); + fprintf(stderr, "unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err)); + exit(1); } Buf *source_code = buf_alloc(); if ((err = os_fetch_file_path(rel_full_path, source_code, true))) { - zig_panic("unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err)); + fprintf(stderr, "unable to open '%s': %s", buf_ptr(rel_full_path), err_str(err)); + exit(1); } g->root_import = add_source_file(g, g->root_package, abs_full_path, source_code); diff --git a/src/os.cpp b/src/os.cpp index c93e2887b7..97462bd658 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -1334,9 +1334,6 @@ com_done:; int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) { #if defined(ZIG_OS_WINDOWS) - if (buf_len(&sdk->path10) == 0 || buf_len(&sdk->version10) == 0) { - return ErrorFileNotFound; - } buf_resize(output_buf, 0); buf_appendf(output_buf, "%s\\Lib\\%s\\ucrt\\", buf_ptr(&sdk->path10), buf_ptr(&sdk->version10)); switch (platform_type) { -- cgit v1.2.3 From e6b69151c0d30d2df95d1f92b65784eac7d186d9 Mon Sep 17 00:00:00 2001 From: Bodie Solomon Date: Sun, 17 Jun 2018 14:35:00 -0400 Subject: Fix 1117: Use realpath in stage1 Darwin os_self_exe_path Issue: https://github.com/ziglang/zig/issues/1117 The macOS stage1 Zig compiler should look in Zig's real absolute path for the Zig stdlib, but os_self_exe_path looks in its path as returned by _NSGetExecutablePath, which may be a symlink. This means that a symlinked Zig cannot find the Zig stdlib. This patch fixes the issue by resolving the _NSGetExecutablePath result to the real path using realpath() before copying the result to the output path. --- src/os.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) (limited to 'src/os.cpp') diff --git a/src/os.cpp b/src/os.cpp index 97462bd658..75e6dd8658 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -989,12 +989,28 @@ int os_self_exe_path(Buf *out_path) { } #elif defined(ZIG_OS_DARWIN) + // How long is the executable's path? uint32_t u32_len = 0; int ret1 = _NSGetExecutablePath(nullptr, &u32_len); assert(ret1 != 0); - buf_resize(out_path, u32_len); - int ret2 = _NSGetExecutablePath(buf_ptr(out_path), &u32_len); + + // Allocate a buffer for this path. + Buf *path_tmp = buf_alloc_fixed(u32_len); + // Fill the buffer with the path, which may be a symlink. + int ret2 = _NSGetExecutablePath(buf_ptr(path_tmp), &u32_len); assert(ret2 == 0); + + // Make a buffer with room for the real path. + Buf *resolve_tmp = buf_alloc_fixed(PATH_MAX); + + // Fill it with the real resolved path. + char *real_path = realpath(buf_ptr(path_tmp), buf_ptr(resolve_tmp)); + // IEEE Std 1003.1-2017: realpath() shall return a pointer to the + // buffer containing the resolved name. + assert(real_path == buf_ptr(resolve_tmp)); + + // Resize out_path and copy the resulting resolved absolute path. + buf_init_from_buf(out_path, resolve_tmp); return 0; #elif defined(ZIG_OS_LINUX) buf_resize(out_path, 256); -- cgit v1.2.3 From 045682289243c6186363e984babc706c3ed93152 Mon Sep 17 00:00:00 2001 From: Bodie Solomon Date: Mon, 18 Jun 2018 07:01:59 -0400 Subject: Fix 1117: Tweak realpath logic to use out_path as scratch space --- src/os.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/os.cpp') diff --git a/src/os.cpp b/src/os.cpp index 75e6dd8658..0e3c3f9a60 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -994,23 +994,23 @@ int os_self_exe_path(Buf *out_path) { int ret1 = _NSGetExecutablePath(nullptr, &u32_len); assert(ret1 != 0); - // Allocate a buffer for this path. - Buf *path_tmp = buf_alloc_fixed(u32_len); - // Fill the buffer with the path, which may be a symlink. - int ret2 = _NSGetExecutablePath(buf_ptr(path_tmp), &u32_len); + // Make room for the executable path and resolved path in out_path, + // then subslice it for convenience. + buf_resize(out_path, u32_len + PATH_MAX); + Buf *tmp = buf_slice(out_path, 0, u32_len); + Buf *resolved = buf_slice(out_path, u32_len, u32_len + PATH_MAX); + + // Fill the executable path. + int ret2 = _NSGetExecutablePath(buf_ptr(tmp), &u32_len); assert(ret2 == 0); - // Make a buffer with room for the real path. - Buf *resolve_tmp = buf_alloc_fixed(PATH_MAX); + // Resolve the real path from that. + char *real_path = realpath(buf_ptr(tmp), buf_ptr(resolved)); + assert(real_path == buf_ptr(resolved)); - // Fill it with the real resolved path. - char *real_path = realpath(buf_ptr(path_tmp), buf_ptr(resolve_tmp)); - // IEEE Std 1003.1-2017: realpath() shall return a pointer to the - // buffer containing the resolved name. - assert(real_path == buf_ptr(resolve_tmp)); - - // Resize out_path and copy the resulting resolved absolute path. - buf_init_from_buf(out_path, resolve_tmp); + // Write the real path back into the beginning of out_path, resize. + buf_init_from_buf(out_path, resolved); + assert(buf_len(out_path) == buf_len(resolved)); return 0; #elif defined(ZIG_OS_LINUX) buf_resize(out_path, 256); -- cgit v1.2.3 From c7057bd25b2a99e5ac61963efd588f5fe4ba93c6 Mon Sep 17 00:00:00 2001 From: Bodie Solomon Date: Mon, 18 Jun 2018 07:37:26 -0400 Subject: Fix 1117: Revise realpath scratch logic --- src/os.cpp | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) (limited to 'src/os.cpp') diff --git a/src/os.cpp b/src/os.cpp index 0e3c3f9a60..75f748e2f0 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -994,23 +994,24 @@ int os_self_exe_path(Buf *out_path) { int ret1 = _NSGetExecutablePath(nullptr, &u32_len); assert(ret1 != 0); - // Make room for the executable path and resolved path in out_path, - // then subslice it for convenience. - buf_resize(out_path, u32_len + PATH_MAX); - Buf *tmp = buf_slice(out_path, 0, u32_len); - Buf *resolved = buf_slice(out_path, u32_len, u32_len + PATH_MAX); + // Make a buffer having room for the temp path. + Buf *tmp = buf_alloc_fixed(u32_len); // Fill the executable path. int ret2 = _NSGetExecutablePath(buf_ptr(tmp), &u32_len); assert(ret2 == 0); // Resolve the real path from that. - char *real_path = realpath(buf_ptr(tmp), buf_ptr(resolved)); - assert(real_path == buf_ptr(resolved)); + buf_resize(out_path, PATH_MAX); + char *real_path = realpath(buf_ptr(tmp), buf_ptr(out_path)); + assert(real_path == buf_ptr(out_path)); + + // Deallocate our scratch space. + buf_deinit(tmp); + + // Resize out_path for the correct length. + buf_resize(out_path, strlen(buf_ptr(out_path))); - // Write the real path back into the beginning of out_path, resize. - buf_init_from_buf(out_path, resolved); - assert(buf_len(out_path) == buf_len(resolved)); return 0; #elif defined(ZIG_OS_LINUX) buf_resize(out_path, 256); -- cgit v1.2.3 From 4ce36a64755b4b2ca8bb28e3ac91b23dfe90ade8 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 18 Jun 2018 12:18:39 -0400 Subject: adjust logic for finding the path to zig executable on darwin --- src/os.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/os.cpp') diff --git a/src/os.cpp b/src/os.cpp index 75f748e2f0..14e9effb1e 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -1004,10 +1004,10 @@ int os_self_exe_path(Buf *out_path) { // Resolve the real path from that. buf_resize(out_path, PATH_MAX); char *real_path = realpath(buf_ptr(tmp), buf_ptr(out_path)); - assert(real_path == buf_ptr(out_path)); - - // Deallocate our scratch space. - buf_deinit(tmp); + if (!real_path) { + buf_init_from_buf(out_path, tmp); + return 0; + } // Resize out_path for the correct length. buf_resize(out_path, strlen(buf_ptr(out_path))); -- cgit v1.2.3 From cd4676a2338430d9e424f297b8b576143c5be180 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 18 Jun 2018 12:54:03 -0400 Subject: stage1: update darwin code to workaround old libc bug See #1128 --- src/os.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/os.cpp') diff --git a/src/os.cpp b/src/os.cpp index 14e9effb1e..b7d2fd1de0 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -994,15 +994,15 @@ int os_self_exe_path(Buf *out_path) { int ret1 = _NSGetExecutablePath(nullptr, &u32_len); assert(ret1 != 0); - // Make a buffer having room for the temp path. Buf *tmp = buf_alloc_fixed(u32_len); // Fill the executable path. int ret2 = _NSGetExecutablePath(buf_ptr(tmp), &u32_len); assert(ret2 == 0); - // Resolve the real path from that. - buf_resize(out_path, PATH_MAX); + // According to libuv project, PATH_MAX*2 works around a libc bug where + // the resolved path is sometimes bigger than PATH_MAX. + buf_resize(out_path, PATH_MAX*2); char *real_path = realpath(buf_ptr(tmp), buf_ptr(out_path)); if (!real_path) { buf_init_from_buf(out_path, tmp); -- cgit v1.2.3 From 8e714289cac55fd6f793cf21cea5fa1930edb985 Mon Sep 17 00:00:00 2001 From: Isaac Hier Date: Sun, 24 Jun 2018 20:27:18 -0400 Subject: Fix os_path_join for case where dirname is empty --- src/os.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/os.cpp') diff --git a/src/os.cpp b/src/os.cpp index b7d2fd1de0..d52295950d 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -225,6 +225,11 @@ void os_path_extname(Buf *full_path, Buf *out_basename, Buf *out_extname) { } void os_path_join(Buf *dirname, Buf *basename, Buf *out_full_path) { + if (buf_len(dirname) == 0) { + buf_init_from_buf(out_full_path, basename); + return; + } + buf_init_from_buf(out_full_path, dirname); uint8_t c = *(buf_ptr(out_full_path) + buf_len(out_full_path) - 1); if (!os_is_sep(c)) -- cgit v1.2.3 From 58c5f94a99a78346286065bbf390e4c30be1b707 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Fri, 20 Jul 2018 23:37:37 -0400 Subject: self-hosted: share C++ code for finding libc on windows --- CMakeLists.txt | 7 + src-self-hosted/c.zig | 1 + src-self-hosted/libc_installation.zig | 25 ++- src/analyze.cpp | 7 +- src/os.cpp | 248 +----------------------- src/os.hpp | 10 +- src/windows_sdk.cpp | 346 ++++++++++++++++++++++++++++++++++ src/windows_sdk.h | 45 +++++ std/os/windows/advapi32.zig | 30 +++ std/os/windows/index.zig | 192 +------------------ std/os/windows/kernel32.zig | 162 ++++++++++++++++ std/os/windows/ole32.zig | 18 ++ std/os/windows/shell32.zig | 4 + std/os/windows/shlwapi.zig | 4 + std/os/windows/user32.zig | 4 + 15 files changed, 658 insertions(+), 445 deletions(-) create mode 100644 src/windows_sdk.cpp create mode 100644 src/windows_sdk.h create mode 100644 std/os/windows/advapi32.zig create mode 100644 std/os/windows/kernel32.zig create mode 100644 std/os/windows/ole32.zig create mode 100644 std/os/windows/shell32.zig create mode 100644 std/os/windows/shlwapi.zig create mode 100644 std/os/windows/user32.zig (limited to 'src/os.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index 30d7bb4856..20755cfc1b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -426,6 +426,7 @@ set(ZIG_SOURCES ) set(ZIG_CPP_SOURCES "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp" + "${CMAKE_SOURCE_DIR}/src/windows_sdk.cpp" ) set(ZIG_STD_FILES @@ -567,8 +568,14 @@ set(ZIG_STD_FILES "os/linux/x86_64.zig" "os/path.zig" "os/time.zig" + "os/windows/advapi32.zig" "os/windows/error.zig" "os/windows/index.zig" + "os/windows/kernel32.zig" + "os/windows/ole32.zig" + "os/windows/shell32.zig" + "os/windows/shlwapi.zig" + "os/windows/user32.zig" "os/windows/util.zig" "os/zen.zig" "rand/index.zig" diff --git a/src-self-hosted/c.zig b/src-self-hosted/c.zig index 3912462985..778d851240 100644 --- a/src-self-hosted/c.zig +++ b/src-self-hosted/c.zig @@ -4,4 +4,5 @@ pub use @cImport({ @cInclude("inttypes.h"); @cInclude("config.h"); @cInclude("zig_llvm.h"); + @cInclude("windows_sdk.h"); }); diff --git a/src-self-hosted/libc_installation.zig b/src-self-hosted/libc_installation.zig index 8444c47310..5a9b7561fa 100644 --- a/src-self-hosted/libc_installation.zig +++ b/src-self-hosted/libc_installation.zig @@ -2,6 +2,7 @@ const std = @import("std"); const builtin = @import("builtin"); const event = std.event; const Target = @import("target.zig").Target; +const c = @import("c.zig"); /// See the render function implementation for documentation of the fields. pub const LibCInstallation = struct { @@ -122,7 +123,7 @@ pub const LibCInstallation = struct { \\# Only needed when targeting Windows. \\kernel32_lib_dir={} \\ - \\# The full path to the dynamic linker. + \\# The full path to the dynamic linker, on the target system. \\# Only needed when targeting Linux. \\dynamic_linker_path={} \\ @@ -143,10 +144,24 @@ pub const LibCInstallation = struct { errdefer group.cancelAll(); switch (builtin.os) { builtin.Os.windows => { - try group.call(findNativeIncludeDirWindows, self, loop); - try group.call(findNativeLibDirWindows, self, loop); - try group.call(findNativeMsvcLibDir, self, loop); - try group.call(findNativeKernel32LibDir, self, loop); + var sdk: *c.ZigWindowsSDK = undefined; + switch (c.zig_find_windows_sdk(@ptrCast(?[*]?[*]c.ZigWindowsSDK, &sdk))) { + c.ZigFindWindowsSdkError.None => { + defer c.zig_free_windows_sdk(@ptrCast(?[*]c.ZigWindowsSDK, sdk)); + + errdefer if (self.msvc_lib_dir) |s| loop.allocator.free(s); + if (sdk.msvc_lib_dir_ptr) |ptr| { + self.msvc_lib_dir = try std.mem.dupe(loop.allocator, u8, ptr[0..sdk.msvc_lib_dir_len]); + } + //try group.call(findNativeIncludeDirWindows, self, loop); + //try group.call(findNativeLibDirWindows, self, loop); + //try group.call(findNativeMsvcLibDir, self, loop); + //try group.call(findNativeKernel32LibDir, self, loop); + }, + c.ZigFindWindowsSdkError.OutOfMemory => return error.OutOfMemory, + c.ZigFindWindowsSdkError.NotFound => return error.NotFound, + c.ZigFindWindowsSdkError.PathTooLong => return error.NotFound, + } }, builtin.Os.linux => { try group.call(findNativeIncludeDirLinux, self, loop); diff --git a/src/analyze.cpp b/src/analyze.cpp index 06d611f80d..6bbe5f6037 100644 --- a/src/analyze.cpp +++ b/src/analyze.cpp @@ -4379,7 +4379,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) { static ZigWindowsSDK *get_windows_sdk(CodeGen *g) { if (g->win_sdk == nullptr) { - if (os_find_windows_sdk(&g->win_sdk)) { + if (zig_find_windows_sdk(&g->win_sdk)) { fprintf(stderr, "unable to determine windows sdk path\n"); exit(1); } @@ -4499,12 +4499,11 @@ void find_libc_lib_path(CodeGen *g) { ZigWindowsSDK *sdk = get_windows_sdk(g); if (g->msvc_lib_dir == nullptr) { - Buf* vc_lib_dir = buf_alloc(); - if (os_get_win32_vcruntime_path(vc_lib_dir, g->zig_target.arch.arch)) { + if (sdk->msvc_lib_dir_ptr == nullptr) { fprintf(stderr, "Unable to determine vcruntime path. --msvc-lib-dir"); exit(1); } - g->msvc_lib_dir = vc_lib_dir; + g->msvc_lib_dir = buf_create_from_mem(sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len); } if (g->libc_lib_dir == nullptr) { diff --git a/src/os.cpp b/src/os.cpp index d52295950d..91a591a7b6 100644 --- a/src/os.cpp +++ b/src/os.cpp @@ -26,7 +26,6 @@ #include #include #include -#include "windows_com.hpp" typedef SSIZE_T ssize_t; #else @@ -1115,249 +1114,10 @@ void os_stderr_set_color(TermColor color) { #endif } -int os_find_windows_sdk(ZigWindowsSDK **out_sdk) { -#if defined(ZIG_OS_WINDOWS) - ZigWindowsSDK *result_sdk = allocate(1); - buf_resize(&result_sdk->path10, 0); - buf_resize(&result_sdk->path81, 0); - - HKEY key; - HRESULT rc; - rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY | KEY_ENUMERATE_SUB_KEYS, &key); - if (rc != ERROR_SUCCESS) { - return ErrorFileNotFound; - } - - { - DWORD tmp_buf_len = MAX_PATH; - buf_resize(&result_sdk->path10, tmp_buf_len); - rc = RegQueryValueEx(key, "KitsRoot10", NULL, NULL, (LPBYTE)buf_ptr(&result_sdk->path10), &tmp_buf_len); - if (rc == ERROR_FILE_NOT_FOUND) { - buf_resize(&result_sdk->path10, 0); - } else { - buf_resize(&result_sdk->path10, tmp_buf_len); - } - } - { - DWORD tmp_buf_len = MAX_PATH; - buf_resize(&result_sdk->path81, tmp_buf_len); - rc = RegQueryValueEx(key, "KitsRoot81", NULL, NULL, (LPBYTE)buf_ptr(&result_sdk->path81), &tmp_buf_len); - if (rc == ERROR_FILE_NOT_FOUND) { - buf_resize(&result_sdk->path81, 0); - } else { - buf_resize(&result_sdk->path81, tmp_buf_len); - } - } - - if (buf_len(&result_sdk->path10) != 0) { - Buf *sdk_lib_dir = buf_sprintf("%s\\Lib\\*", buf_ptr(&result_sdk->path10)); - - // enumerate files in sdk path looking for latest version - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFileA(buf_ptr(sdk_lib_dir), &ffd); - if (hFind == INVALID_HANDLE_VALUE) { - return ErrorFileNotFound; - } - int v0 = 0, v1 = 0, v2 = 0, v3 = 0; - bool found_version_dir = false; - for (;;) { - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - int c0 = 0, c1 = 0, c2 = 0, c3 = 0; - sscanf(ffd.cFileName, "%d.%d.%d.%d", &c0, &c1, &c2, &c3); - if (c0 == 10 && c1 == 0 && c2 == 10240 && c3 == 0) { - // Microsoft released 26624 as 10240 accidentally. - // https://developer.microsoft.com/en-us/windows/downloads/sdk-archive - c2 = 26624; - } - if ((c0 > v0) || (c1 > v1) || (c2 > v2) || (c3 > v3)) { - v0 = c0, v1 = c1, v2 = c2, v3 = c3; - buf_init_from_str(&result_sdk->version10, ffd.cFileName); - found_version_dir = true; - } - } - if (FindNextFile(hFind, &ffd) == 0) { - FindClose(hFind); - break; - } - } - if (!found_version_dir) { - buf_resize(&result_sdk->path10, 0); - } - } - - if (buf_len(&result_sdk->path81) != 0) { - Buf *sdk_lib_dir = buf_sprintf("%s\\Lib\\winv*", buf_ptr(&result_sdk->path81)); - - // enumerate files in sdk path looking for latest version - WIN32_FIND_DATA ffd; - HANDLE hFind = FindFirstFileA(buf_ptr(sdk_lib_dir), &ffd); - if (hFind == INVALID_HANDLE_VALUE) { - return ErrorFileNotFound; - } - int v0 = 0, v1 = 0; - bool found_version_dir = false; - for (;;) { - if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - int c0 = 0, c1 = 0; - sscanf(ffd.cFileName, "winv%d.%d", &c0, &c1); - if ((c0 > v0) || (c1 > v1)) { - v0 = c0, v1 = c1; - buf_init_from_str(&result_sdk->version81, ffd.cFileName); - found_version_dir = true; - } - } - if (FindNextFile(hFind, &ffd) == 0) { - FindClose(hFind); - break; - } - } - if (!found_version_dir) { - buf_resize(&result_sdk->path81, 0); - } - } - - *out_sdk = result_sdk; - return 0; -#else - return ErrorFileNotFound; -#endif -} - -int os_get_win32_vcruntime_path(Buf* output_buf, ZigLLVM_ArchType platform_type) { -#if defined(ZIG_OS_WINDOWS) - buf_resize(output_buf, 0); - //COM Smart Pointerse requires explicit scope - { - HRESULT rc; - rc = CoInitializeEx(NULL, COINIT_MULTITHREADED); - if (rc != S_OK) { - goto com_done; - } - - //This COM class is installed when a VS2017 - ISetupConfigurationPtr setup_config; - rc = setup_config.CreateInstance(__uuidof(SetupConfiguration)); - if (rc != S_OK) { - goto com_done; - } - - IEnumSetupInstancesPtr all_instances; - rc = setup_config->EnumInstances(&all_instances); - if (rc != S_OK) { - goto com_done; - } - - ISetupInstance* curr_instance; - ULONG found_inst; - while ((rc = all_instances->Next(1, &curr_instance, &found_inst) == S_OK)) { - BSTR bstr_inst_path; - rc = curr_instance->GetInstallationPath(&bstr_inst_path); - if (rc != S_OK) { - goto com_done; - } - //BSTRs are UTF-16 encoded, so we need to convert the string & adjust the length - UINT bstr_path_len = *((UINT*)bstr_inst_path - 1); - ULONG tmp_path_len = bstr_path_len / 2 + 1; - char* conv_path = (char*)bstr_inst_path; - char *tmp_path = (char*)alloca(tmp_path_len); - memset(tmp_path, 0, tmp_path_len); - uint32_t c = 0; - for (uint32_t i = 0; i < bstr_path_len; i += 2) { - tmp_path[c] = conv_path[i]; - ++c; - assert(c != tmp_path_len); - } - - buf_append_str(output_buf, tmp_path); - buf_append_char(output_buf, '\\'); - - Buf* tmp_buf = buf_alloc(); - buf_append_buf(tmp_buf, output_buf); - buf_append_str(tmp_buf, "VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt"); - FILE* tools_file = fopen(buf_ptr(tmp_buf), "r"); - if (!tools_file) { - goto com_done; - } - memset(tmp_path, 0, tmp_path_len); - fgets(tmp_path, tmp_path_len, tools_file); - strtok(tmp_path, " \r\n"); - fclose(tools_file); - buf_appendf(output_buf, "VC\\Tools\\MSVC\\%s\\lib\\", tmp_path); - switch (platform_type) { - case ZigLLVM_x86: - buf_append_str(output_buf, "x86\\"); - break; - case ZigLLVM_x86_64: - buf_append_str(output_buf, "x64\\"); - break; - case ZigLLVM_arm: - buf_append_str(output_buf, "arm\\"); - break; - default: - zig_panic("Attemped to use vcruntime for non-supported platform."); - } - buf_resize(tmp_buf, 0); - buf_append_buf(tmp_buf, output_buf); - buf_append_str(tmp_buf, "vcruntime.lib"); - - if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) { - return 0; - } - } - } - -com_done:; - HKEY key; - HRESULT rc; - rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key); - if (rc != ERROR_SUCCESS) { - return ErrorFileNotFound; - } - - DWORD dw_type = 0; - DWORD cb_data = 0; - rc = RegQueryValueEx(key, "14.0", NULL, &dw_type, NULL, &cb_data); - if ((rc == ERROR_FILE_NOT_FOUND) || (REG_SZ != dw_type)) { - return ErrorFileNotFound; - } - - Buf* tmp_buf = buf_alloc_fixed(cb_data); - RegQueryValueExA(key, "14.0", NULL, NULL, (LPBYTE)buf_ptr(tmp_buf), &cb_data); - //RegQueryValueExA returns the length of the string INCLUDING the null terminator - buf_resize(tmp_buf, cb_data-1); - buf_append_str(tmp_buf, "VC\\Lib\\"); - switch (platform_type) { - case ZigLLVM_x86: - //x86 is in the root of the Lib folder - break; - case ZigLLVM_x86_64: - buf_append_str(tmp_buf, "amd64\\"); - break; - case ZigLLVM_arm: - buf_append_str(tmp_buf, "arm\\"); - break; - default: - zig_panic("Attemped to use vcruntime for non-supported platform."); - } - - buf_append_buf(output_buf, tmp_buf); - buf_append_str(tmp_buf, "vcruntime.lib"); - - if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) { - return 0; - } else { - buf_resize(output_buf, 0); - return ErrorFileNotFound; - } -#else - return ErrorFileNotFound; -#endif -} - int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) { #if defined(ZIG_OS_WINDOWS) buf_resize(output_buf, 0); - buf_appendf(output_buf, "%s\\Lib\\%s\\ucrt\\", buf_ptr(&sdk->path10), buf_ptr(&sdk->version10)); + buf_appendf(output_buf, "%s\\Lib\\%s\\ucrt\\", sdk->path10_ptr, sdk->version10_ptr); switch (platform_type) { case ZigLLVM_x86: buf_append_str(output_buf, "x86\\"); @@ -1389,7 +1149,7 @@ int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Arch int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) { #if defined(ZIG_OS_WINDOWS) buf_resize(output_buf, 0); - buf_appendf(output_buf, "%s\\Include\\%s\\ucrt", buf_ptr(&sdk->path10), buf_ptr(&sdk->version10)); + buf_appendf(output_buf, "%s\\Include\\%s\\ucrt", sdk->path10_ptr, sdk->version10_ptr); if (GetFileAttributesA(buf_ptr(output_buf)) != INVALID_FILE_ATTRIBUTES) { return 0; } @@ -1406,7 +1166,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy #if defined(ZIG_OS_WINDOWS) { buf_resize(output_buf, 0); - buf_appendf(output_buf, "%s\\Lib\\%s\\um\\", buf_ptr(&sdk->path10), buf_ptr(&sdk->version10)); + buf_appendf(output_buf, "%s\\Lib\\%s\\um\\", sdk->path10_ptr, sdk->version10_ptr); switch (platform_type) { case ZigLLVM_x86: buf_append_str(output_buf, "x86\\"); @@ -1429,7 +1189,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy } { buf_resize(output_buf, 0); - buf_appendf(output_buf, "%s\\Lib\\%s\\um\\", buf_ptr(&sdk->path81), buf_ptr(&sdk->version81)); + buf_appendf(output_buf, "%s\\Lib\\%s\\um\\", sdk->path81_ptr, sdk->version81_ptr); switch (platform_type) { case ZigLLVM_x86: buf_append_str(output_buf, "x86\\"); diff --git a/src/os.hpp b/src/os.hpp index b94e98ec3d..cfe4e8f3a2 100644 --- a/src/os.hpp +++ b/src/os.hpp @@ -12,6 +12,7 @@ #include "buffer.hpp" #include "error.hpp" #include "zig_llvm.h" +#include "windows_sdk.h" #include #include @@ -79,15 +80,6 @@ bool os_is_sep(uint8_t c); int os_self_exe_path(Buf *out_path); -struct ZigWindowsSDK { - Buf path10; - Buf version10; - Buf path81; - Buf version81; -}; - -int os_find_windows_sdk(ZigWindowsSDK **out_sdk); -int os_get_win32_vcruntime_path(Buf *output_buf, ZigLLVM_ArchType platform_type); int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf *output_buf); int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type); int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type); diff --git a/src/windows_sdk.cpp b/src/windows_sdk.cpp new file mode 100644 index 0000000000..059bdee4e9 --- /dev/null +++ b/src/windows_sdk.cpp @@ -0,0 +1,346 @@ +/* + * Copyright (c) 2018 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#include "windows_sdk.h" + +#if defined(_WIN32) + +#include "windows_com.hpp" +#include +#include + +struct ZigWindowsSDKPrivate { + ZigWindowsSDK base; +}; + +enum NativeArch { + NativeArchArm, + NativeArchi386, + NativeArchx86_64, +}; + +#if defined(_M_ARM) || defined(__arm_) +static const NativeArch native_arch = NativeArchArm; +#endif +#if defined(_M_IX86) || defined(__i386__) +static const NativeArch native_arch = NativeArchi386; +#endif +#if defined(_M_X64) || defined(__x86_64__) +static const NativeArch native_arch = NativeArchx86_64; +#endif + +void zig_free_windows_sdk(struct ZigWindowsSDK *sdk) { + if (sdk == nullptr) { + return; + } + free((void*)sdk->path10_ptr); + free((void*)sdk->version10_ptr); + free((void*)sdk->path81_ptr); + free((void*)sdk->version81_ptr); + free((void*)sdk->msvc_lib_dir_ptr); +} + +static ZigFindWindowsSdkError find_msvc_lib_dir(ZigWindowsSDKPrivate *priv) { + //COM Smart Pointers requires explicit scope + { + HRESULT rc = CoInitializeEx(NULL, COINIT_MULTITHREADED); + if (rc != S_OK && rc != S_FALSE) { + goto com_done; + } + + //This COM class is installed when a VS2017 + ISetupConfigurationPtr setup_config; + rc = setup_config.CreateInstance(__uuidof(SetupConfiguration)); + if (rc != S_OK) { + goto com_done; + } + + IEnumSetupInstancesPtr all_instances; + rc = setup_config->EnumInstances(&all_instances); + if (rc != S_OK) { + goto com_done; + } + + ISetupInstance* curr_instance; + ULONG found_inst; + while ((rc = all_instances->Next(1, &curr_instance, &found_inst) == S_OK)) { + BSTR bstr_inst_path; + rc = curr_instance->GetInstallationPath(&bstr_inst_path); + if (rc != S_OK) { + goto com_done; + } + //BSTRs are UTF-16 encoded, so we need to convert the string & adjust the length + //TODO call an actual function to do this + UINT bstr_path_len = *((UINT*)bstr_inst_path - 1); + ULONG tmp_path_len = bstr_path_len / 2 + 1; + char* conv_path = (char*)bstr_inst_path; + // TODO don't use alloca + char *tmp_path = (char*)alloca(tmp_path_len); + memset(tmp_path, 0, tmp_path_len); + uint32_t c = 0; + for (uint32_t i = 0; i < bstr_path_len; i += 2) { + tmp_path[c] = conv_path[i]; + ++c; + assert(c != tmp_path_len); + } + char output_path[4096]; + output_path[0] = 0; + char *out_append_ptr = output_path; + + out_append_ptr += sprintf(out_append_ptr, "%s\\", tmp_path); + + char tmp_buf[4096]; + sprintf(tmp_buf, "%s%s", output_path, "VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt"); + FILE* tools_file = fopen(tmp_buf, "rb"); + if (!tools_file) { + goto com_done; + } + memset(tmp_path, 0, tmp_path_len); + fgets(tmp_path, tmp_path_len, tools_file); + strtok(tmp_path, " \r\n"); + fclose(tools_file); + out_append_ptr += sprintf(out_append_ptr, "VC\\Tools\\MSVC\\%s\\lib\\", tmp_path); + switch (native_arch) { + case NativeArchi386: + out_append_ptr += sprintf(out_append_ptr, "x86\\"); + break; + case NativeArchx86_64: + out_append_ptr += sprintf(out_append_ptr, "x64\\"); + break; + case NativeArchArm: + out_append_ptr += sprintf(out_append_ptr, "arm\\"); + break; + } + sprintf(tmp_buf, "%s%s", output_path, "vcruntime.lib"); + + if (GetFileAttributesA(tmp_buf) != INVALID_FILE_ATTRIBUTES) { + priv->base.msvc_lib_dir_ptr = strdup(output_path); + if (priv->base.msvc_lib_dir_ptr == nullptr) { + return ZigFindWindowsSdkErrorOutOfMemory; + } + priv->base.msvc_lib_dir_len = strlen(priv->base.msvc_lib_dir_ptr); + return ZigFindWindowsSdkErrorNone; + } + } + } + +com_done:; + HKEY key; + HRESULT rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", 0, + KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key); + if (rc != ERROR_SUCCESS) { + return ZigFindWindowsSdkErrorNotFound; + } + + DWORD dw_type = 0; + DWORD cb_data = 0; + rc = RegQueryValueEx(key, "14.0", NULL, &dw_type, NULL, &cb_data); + if ((rc == ERROR_FILE_NOT_FOUND) || (REG_SZ != dw_type)) { + return ZigFindWindowsSdkErrorNotFound; + } + + char tmp_buf[4096]; + + RegQueryValueExA(key, "14.0", NULL, NULL, (LPBYTE)tmp_buf, &cb_data); + // RegQueryValueExA returns the length of the string INCLUDING the null terminator + char *tmp_buf_append_ptr = tmp_buf + (cb_data - 1); + tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "VC\\Lib\\"); + switch (native_arch) { + case NativeArchi386: + //x86 is in the root of the Lib folder + break; + case NativeArchx86_64: + tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "amd64\\"); + break; + case NativeArchArm: + tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "arm\\"); + break; + } + + char *output_path = strdup(tmp_buf); + if (output_path == nullptr) { + return ZigFindWindowsSdkErrorOutOfMemory; + } + + tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "vcruntime.lib"); + + if (GetFileAttributesA(tmp_buf) != INVALID_FILE_ATTRIBUTES) { + priv->base.msvc_lib_dir_ptr = output_path; + priv->base.msvc_lib_dir_len = strlen(output_path); + return ZigFindWindowsSdkErrorNone; + } else { + free(output_path); + return ZigFindWindowsSdkErrorNotFound; + } +} + +static ZigFindWindowsSdkError find_10_version(ZigWindowsSDKPrivate *priv) { + if (priv->base.path10_ptr == nullptr) + return ZigFindWindowsSdkErrorNone; + + char sdk_lib_dir[4096]; + int n = snprintf(sdk_lib_dir, 4096, "%s\\Lib\\*", priv->base.path10_ptr); + if (n < 0 || n >= 4096) { + return ZigFindWindowsSdkErrorPathTooLong; + } + + // enumerate files in sdk path looking for latest version + WIN32_FIND_DATA ffd; + HANDLE hFind = FindFirstFileA(sdk_lib_dir, &ffd); + if (hFind == INVALID_HANDLE_VALUE) { + return ZigFindWindowsSdkErrorNotFound; + } + int v0 = 0, v1 = 0, v2 = 0, v3 = 0; + for (;;) { + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + int c0 = 0, c1 = 0, c2 = 0, c3 = 0; + sscanf(ffd.cFileName, "%d.%d.%d.%d", &c0, &c1, &c2, &c3); + if (c0 == 10 && c1 == 0 && c2 == 10240 && c3 == 0) { + // Microsoft released 26624 as 10240 accidentally. + // https://developer.microsoft.com/en-us/windows/downloads/sdk-archive + c2 = 26624; + } + if ((c0 > v0) || (c1 > v1) || (c2 > v2) || (c3 > v3)) { + v0 = c0, v1 = c1, v2 = c2, v3 = c3; + free((void*)priv->base.version10_ptr); + priv->base.version10_ptr = strdup(ffd.cFileName); + if (priv->base.version10_ptr == nullptr) { + FindClose(hFind); + return ZigFindWindowsSdkErrorOutOfMemory; + } + } + } + if (FindNextFile(hFind, &ffd) == 0) { + FindClose(hFind); + break; + } + } + priv->base.version10_len = strlen(priv->base.version10_ptr); + return ZigFindWindowsSdkErrorNone; +} + +static ZigFindWindowsSdkError find_81_version(ZigWindowsSDKPrivate *priv) { + if (priv->base.path81_ptr == nullptr) + return ZigFindWindowsSdkErrorNone; + + char sdk_lib_dir[4096]; + int n = snprintf(sdk_lib_dir, 4096, "%s\\Lib\\winv*", priv->base.path81_ptr); + if (n < 0 || n >= 4096) { + return ZigFindWindowsSdkErrorPathTooLong; + } + + // enumerate files in sdk path looking for latest version + WIN32_FIND_DATA ffd; + HANDLE hFind = FindFirstFileA(sdk_lib_dir, &ffd); + if (hFind == INVALID_HANDLE_VALUE) { + return ZigFindWindowsSdkErrorNotFound; + } + int v0 = 0, v1 = 0; + for (;;) { + if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { + int c0 = 0, c1 = 0; + sscanf(ffd.cFileName, "winv%d.%d", &c0, &c1); + if ((c0 > v0) || (c1 > v1)) { + v0 = c0, v1 = c1; + free((void*)priv->base.version81_ptr); + priv->base.version81_ptr = strdup(ffd.cFileName); + if (priv->base.version81_ptr == nullptr) { + FindClose(hFind); + return ZigFindWindowsSdkErrorOutOfMemory; + } + } + } + if (FindNextFile(hFind, &ffd) == 0) { + FindClose(hFind); + break; + } + } + priv->base.version81_len = strlen(priv->base.version81_ptr); + return ZigFindWindowsSdkErrorNone; +} + +ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk) { + ZigWindowsSDKPrivate *priv = (ZigWindowsSDKPrivate*)calloc(1, sizeof(ZigWindowsSDKPrivate)); + if (priv == nullptr) { + return ZigFindWindowsSdkErrorOutOfMemory; + } + + HKEY key; + HRESULT rc; + rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", 0, + KEY_QUERY_VALUE | KEY_WOW64_32KEY | KEY_ENUMERATE_SUB_KEYS, &key); + if (rc != ERROR_SUCCESS) { + zig_free_windows_sdk(&priv->base); + return ZigFindWindowsSdkErrorNotFound; + } + + { + DWORD tmp_buf_len = MAX_PATH; + priv->base.path10_ptr = (const char *)calloc(tmp_buf_len, 1); + if (priv->base.path10_ptr == nullptr) { + zig_free_windows_sdk(&priv->base); + return ZigFindWindowsSdkErrorOutOfMemory; + } + rc = RegQueryValueEx(key, "KitsRoot10", NULL, NULL, (LPBYTE)priv->base.path10_ptr, &tmp_buf_len); + if (rc == ERROR_SUCCESS) { + priv->base.path10_len = tmp_buf_len; + } else { + free((void*)priv->base.path10_ptr); + priv->base.path10_ptr = nullptr; + } + } + { + DWORD tmp_buf_len = MAX_PATH; + priv->base.path81_ptr = (const char *)calloc(tmp_buf_len, 1); + if (priv->base.path81_ptr == nullptr) { + zig_free_windows_sdk(&priv->base); + return ZigFindWindowsSdkErrorOutOfMemory; + } + rc = RegQueryValueEx(key, "KitsRoot81", NULL, NULL, (LPBYTE)priv->base.path81_ptr, &tmp_buf_len); + if (rc == ERROR_SUCCESS) { + priv->base.path81_len = tmp_buf_len; + } else { + free((void*)priv->base.path81_ptr); + priv->base.path81_ptr = nullptr; + } + } + + { + ZigFindWindowsSdkError err = find_10_version(priv); + if (err == ZigFindWindowsSdkErrorOutOfMemory) { + zig_free_windows_sdk(&priv->base); + return err; + } + } + { + ZigFindWindowsSdkError err = find_81_version(priv); + if (err == ZigFindWindowsSdkErrorOutOfMemory) { + zig_free_windows_sdk(&priv->base); + return err; + } + } + + { + ZigFindWindowsSdkError err = find_msvc_lib_dir(priv); + if (err == ZigFindWindowsSdkErrorOutOfMemory) { + zig_free_windows_sdk(&priv->base); + return err; + } + } + + *out_sdk = &priv->base; + return ZigFindWindowsSdkErrorNone; +} + +#else + +void zig_free_windows_sdk(struct ZigWindowsSDK *sdk) {} +ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk) { + return ZigFindWindowsSdkErrorNotFound; +} + +#endif diff --git a/src/windows_sdk.h b/src/windows_sdk.h new file mode 100644 index 0000000000..080ed55bed --- /dev/null +++ b/src/windows_sdk.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2018 Andrew Kelley + * + * This file is part of zig, which is MIT licensed. + * See http://opensource.org/licenses/MIT + */ + +#ifndef ZIG_WINDOWS_SDK_H +#define ZIG_WINDOWS_SDK_H + +#ifdef __cplusplus +#define ZIG_EXTERN_C extern "C" +#else +#define ZIG_EXTERN_C +#endif + +struct ZigWindowsSDK { + const char *path10_ptr; + size_t path10_len; + + const char *version10_ptr; + size_t version10_len; + + const char *path81_ptr; + size_t path81_len; + + const char *version81_ptr; + size_t version81_len; + + const char *msvc_lib_dir_ptr; + size_t msvc_lib_dir_len; +}; + +enum ZigFindWindowsSdkError { + ZigFindWindowsSdkErrorNone, + ZigFindWindowsSdkErrorOutOfMemory, + ZigFindWindowsSdkErrorNotFound, + ZigFindWindowsSdkErrorPathTooLong, +}; + +ZIG_EXTERN_C enum ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk); + +ZIG_EXTERN_C void zig_free_windows_sdk(struct ZigWindowsSDK *sdk); + +#endif diff --git a/std/os/windows/advapi32.zig b/std/os/windows/advapi32.zig new file mode 100644 index 0000000000..dcb5a636ea --- /dev/null +++ b/std/os/windows/advapi32.zig @@ -0,0 +1,30 @@ +use @import("index.zig"); + +pub const PROV_RSA_FULL = 1; + +pub const REGSAM = ACCESS_MASK; +pub const ACCESS_MASK = DWORD; +pub const PHKEY = &HKEY; +pub const HKEY = &HKEY__; +pub const HKEY__ = extern struct { + unused: c_int, +}; +pub const LSTATUS = LONG; + +pub extern "advapi32" stdcallcc fn CryptAcquireContextA( + phProv: *HCRYPTPROV, + pszContainer: ?LPCSTR, + pszProvider: ?LPCSTR, + dwProvType: DWORD, + dwFlags: DWORD, +) BOOL; + +pub extern "advapi32" stdcallcc fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) BOOL; + +pub extern "advapi32" stdcallcc fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: [*]BYTE) BOOL; + +pub extern "advapi32" stdcallcc fn RegOpenKeyExW(hKey: HKEY, lpSubKey: LPCWSTR, ulOptions: DWORD, samDesired: REGSAM, + phkResult: &HKEY,) LSTATUS; + +pub extern "advapi32" stdcallcc fn RegQueryValueExW(hKey: HKEY, lpValueName: LPCWSTR, lpReserved: LPDWORD, + lpType: LPDWORD, lpData: LPBYTE, lpcbData: LPDWORD,) LSTATUS; diff --git a/std/os/windows/index.zig b/std/os/windows/index.zig index 96c4d3861c..90ccfaf6c5 100644 --- a/std/os/windows/index.zig +++ b/std/os/windows/index.zig @@ -1,190 +1,19 @@ const std = @import("../../index.zig"); const assert = std.debug.assert; + +pub use @import("advapi32.zig"); +pub use @import("kernel32.zig"); +pub use @import("ole32.zig"); +pub use @import("shell32.zig"); +pub use @import("shlwapi.zig"); +pub use @import("user32.zig"); + test "import" { _ = @import("util.zig"); } pub const ERROR = @import("error.zig"); -pub extern "advapi32" stdcallcc fn CryptAcquireContextA( - phProv: *HCRYPTPROV, - pszContainer: ?LPCSTR, - pszProvider: ?LPCSTR, - dwProvType: DWORD, - dwFlags: DWORD, -) BOOL; - -pub extern "advapi32" stdcallcc fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) BOOL; - -pub extern "advapi32" stdcallcc fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: [*]BYTE) BOOL; - -pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL; - -pub extern "kernel32" stdcallcc fn CreateDirectoryA( - lpPathName: LPCSTR, - lpSecurityAttributes: ?*SECURITY_ATTRIBUTES, -) BOOL; - -pub extern "kernel32" stdcallcc fn CreateFileA( - lpFileName: LPCSTR, - dwDesiredAccess: DWORD, - dwShareMode: DWORD, - lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES, - dwCreationDisposition: DWORD, - dwFlagsAndAttributes: DWORD, - hTemplateFile: ?HANDLE, -) HANDLE; - -pub extern "kernel32" stdcallcc fn CreatePipe( - hReadPipe: *HANDLE, - hWritePipe: *HANDLE, - lpPipeAttributes: *const SECURITY_ATTRIBUTES, - nSize: DWORD, -) BOOL; - -pub extern "kernel32" stdcallcc fn CreateProcessA( - lpApplicationName: ?LPCSTR, - lpCommandLine: LPSTR, - lpProcessAttributes: ?*SECURITY_ATTRIBUTES, - lpThreadAttributes: ?*SECURITY_ATTRIBUTES, - bInheritHandles: BOOL, - dwCreationFlags: DWORD, - lpEnvironment: ?*c_void, - lpCurrentDirectory: ?LPCSTR, - lpStartupInfo: *STARTUPINFOA, - lpProcessInformation: *PROCESS_INFORMATION, -) BOOL; - -pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA( - lpSymlinkFileName: LPCSTR, - lpTargetFileName: LPCSTR, - dwFlags: DWORD, -) BOOLEAN; - -pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) ?HANDLE; - -pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE; - -pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) BOOL; - -pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn; - -pub extern "kernel32" stdcallcc fn FindFirstFileA(lpFileName: LPCSTR, lpFindFileData: *WIN32_FIND_DATAA) HANDLE; -pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL; -pub extern "kernel32" stdcallcc fn FindNextFileA(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAA) BOOL; - -pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsA(penv: [*]u8) BOOL; - -pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR; - -pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) BOOL; - -pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD; - -pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8; - -pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD; - -pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL; - -pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) BOOL; - -pub extern "kernel32" stdcallcc fn GetFileAttributesA(lpFileName: LPCSTR) DWORD; - -pub extern "kernel32" stdcallcc fn GetModuleFileNameA(hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) DWORD; - -pub extern "kernel32" stdcallcc fn GetLastError() DWORD; - -pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx( - in_hFile: HANDLE, - in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, - out_lpFileInformation: *c_void, - in_dwBufferSize: DWORD, -) BOOL; - -pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleA( - hFile: HANDLE, - lpszFilePath: LPSTR, - cchFilePath: DWORD, - dwFlags: DWORD, -) DWORD; - -pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE; -pub extern "kernel32" stdcallcc fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) BOOL; - -pub extern "kernel32" stdcallcc fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) void; -pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(*FILETIME) void; - -pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE; -pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL; -pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) ?*c_void; -pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) SIZE_T; -pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) BOOL; -pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T; -pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL; - -pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE; - -pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?*c_void; - -pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) BOOL; - -pub extern "kernel32" stdcallcc fn MoveFileExA( - lpExistingFileName: LPCSTR, - lpNewFileName: LPCSTR, - dwFlags: DWORD, -) BOOL; - -pub extern "kernel32" stdcallcc fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) BOOL; - -pub extern "kernel32" stdcallcc fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) BOOL; - -pub extern "kernel32" stdcallcc fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) BOOL; - -pub extern "kernel32" stdcallcc fn ReadFile( - in_hFile: HANDLE, - out_lpBuffer: *c_void, - in_nNumberOfBytesToRead: DWORD, - out_lpNumberOfBytesRead: *DWORD, - in_out_lpOverlapped: ?*OVERLAPPED, -) BOOL; - -pub extern "kernel32" stdcallcc fn RemoveDirectoryA(lpPathName: LPCSTR) BOOL; - -pub extern "kernel32" stdcallcc fn SetFilePointerEx( - in_fFile: HANDLE, - in_liDistanceToMove: LARGE_INTEGER, - out_opt_ldNewFilePointer: ?*LARGE_INTEGER, - in_dwMoveMethod: DWORD, -) BOOL; - -pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL; - -pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void; - -pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL; - -pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD; - -pub extern "kernel32" stdcallcc fn WriteFile( - in_hFile: HANDLE, - in_lpBuffer: *const c_void, - in_nNumberOfBytesToWrite: DWORD, - out_lpNumberOfBytesWritten: ?*DWORD, - in_out_lpOverlapped: ?*OVERLAPPED, -) BOOL; - -//TODO: call unicode versions instead of relying on ANSI code page -pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: LPCSTR) ?HMODULE; - -pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL; - -pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) c_int; - -pub extern "shlwapi" stdcallcc fn PathFileExistsA(pszPath: ?LPCTSTR) BOOL; - -pub const PROV_RSA_FULL = 1; - pub const BOOL = c_int; pub const BOOLEAN = BYTE; pub const BYTE = u8; @@ -206,6 +35,7 @@ pub const LPSTR = [*]CHAR; pub const LPTSTR = if (UNICODE) LPWSTR else LPSTR; pub const LPVOID = *c_void; pub const LPWSTR = [*]WCHAR; +pub const LPCWSTR = [*]const WCHAR; pub const PVOID = *c_void; pub const PWSTR = [*]WCHAR; pub const SIZE_T = usize; @@ -442,10 +272,6 @@ pub const SYSTEM_INFO = extern struct { wProcessorRevision: WORD, }; -pub extern "ole32.dll" stdcallcc fn CoTaskMemFree(pv: LPVOID) void; - -pub extern "shell32.dll" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT; - pub const HRESULT = c_long; pub const KNOWNFOLDERID = GUID; diff --git a/std/os/windows/kernel32.zig b/std/os/windows/kernel32.zig new file mode 100644 index 0000000000..fa3473ad05 --- /dev/null +++ b/std/os/windows/kernel32.zig @@ -0,0 +1,162 @@ +use @import("index.zig"); + +pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL; + +pub extern "kernel32" stdcallcc fn CreateDirectoryA( + lpPathName: LPCSTR, + lpSecurityAttributes: ?*SECURITY_ATTRIBUTES, +) BOOL; + +pub extern "kernel32" stdcallcc fn CreateFileA( + lpFileName: LPCSTR, + dwDesiredAccess: DWORD, + dwShareMode: DWORD, + lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES, + dwCreationDisposition: DWORD, + dwFlagsAndAttributes: DWORD, + hTemplateFile: ?HANDLE, +) HANDLE; + +pub extern "kernel32" stdcallcc fn CreatePipe( + hReadPipe: *HANDLE, + hWritePipe: *HANDLE, + lpPipeAttributes: *const SECURITY_ATTRIBUTES, + nSize: DWORD, +) BOOL; + +pub extern "kernel32" stdcallcc fn CreateProcessA( + lpApplicationName: ?LPCSTR, + lpCommandLine: LPSTR, + lpProcessAttributes: ?*SECURITY_ATTRIBUTES, + lpThreadAttributes: ?*SECURITY_ATTRIBUTES, + bInheritHandles: BOOL, + dwCreationFlags: DWORD, + lpEnvironment: ?*c_void, + lpCurrentDirectory: ?LPCSTR, + lpStartupInfo: *STARTUPINFOA, + lpProcessInformation: *PROCESS_INFORMATION, +) BOOL; + +pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA( + lpSymlinkFileName: LPCSTR, + lpTargetFileName: LPCSTR, + dwFlags: DWORD, +) BOOLEAN; + +pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) ?HANDLE; + +pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE; + +pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) BOOL; + +pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn; + +pub extern "kernel32" stdcallcc fn FindFirstFileA(lpFileName: LPCSTR, lpFindFileData: *WIN32_FIND_DATAA) HANDLE; +pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL; +pub extern "kernel32" stdcallcc fn FindNextFileA(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAA) BOOL; + +pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsA(penv: [*]u8) BOOL; + +pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR; + +pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) BOOL; + +pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD; + +pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8; + +pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD; + +pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL; + +pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) BOOL; + +pub extern "kernel32" stdcallcc fn GetFileAttributesA(lpFileName: LPCSTR) DWORD; + +pub extern "kernel32" stdcallcc fn GetModuleFileNameA(hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) DWORD; + +pub extern "kernel32" stdcallcc fn GetLastError() DWORD; + +pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx( + in_hFile: HANDLE, + in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS, + out_lpFileInformation: *c_void, + in_dwBufferSize: DWORD, +) BOOL; + +pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleA( + hFile: HANDLE, + lpszFilePath: LPSTR, + cchFilePath: DWORD, + dwFlags: DWORD, +) DWORD; + +pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE; +pub extern "kernel32" stdcallcc fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) BOOL; + +pub extern "kernel32" stdcallcc fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) void; +pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(*FILETIME) void; + +pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE; +pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL; +pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) ?*c_void; +pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) SIZE_T; +pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) BOOL; +pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T; +pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL; + +pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE; + +pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?*c_void; + +pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) BOOL; + +pub extern "kernel32" stdcallcc fn MoveFileExA( + lpExistingFileName: LPCSTR, + lpNewFileName: LPCSTR, + dwFlags: DWORD, +) BOOL; + +pub extern "kernel32" stdcallcc fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) BOOL; + +pub extern "kernel32" stdcallcc fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) BOOL; + +pub extern "kernel32" stdcallcc fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) BOOL; + +pub extern "kernel32" stdcallcc fn ReadFile( + in_hFile: HANDLE, + out_lpBuffer: *c_void, + in_nNumberOfBytesToRead: DWORD, + out_lpNumberOfBytesRead: *DWORD, + in_out_lpOverlapped: ?*OVERLAPPED, +) BOOL; + +pub extern "kernel32" stdcallcc fn RemoveDirectoryA(lpPathName: LPCSTR) BOOL; + +pub extern "kernel32" stdcallcc fn SetFilePointerEx( + in_fFile: HANDLE, + in_liDistanceToMove: LARGE_INTEGER, + out_opt_ldNewFilePointer: ?*LARGE_INTEGER, + in_dwMoveMethod: DWORD, +) BOOL; + +pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL; + +pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void; + +pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL; + +pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD; + +pub extern "kernel32" stdcallcc fn WriteFile( + in_hFile: HANDLE, + in_lpBuffer: *const c_void, + in_nNumberOfBytesToWrite: DWORD, + out_lpNumberOfBytesWritten: ?*DWORD, + in_out_lpOverlapped: ?*OVERLAPPED, +) BOOL; + +//TODO: call unicode versions instead of relying on ANSI code page +pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: LPCSTR) ?HMODULE; + +pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL; diff --git a/std/os/windows/ole32.zig b/std/os/windows/ole32.zig new file mode 100644 index 0000000000..84d8089d07 --- /dev/null +++ b/std/os/windows/ole32.zig @@ -0,0 +1,18 @@ +use @import("index.zig"); + +pub extern "ole32.dll" stdcallcc fn CoTaskMemFree(pv: LPVOID) void; +pub extern "ole32.dll" stdcallcc fn CoUninitialize() void; +pub extern "ole32.dll" stdcallcc fn CoGetCurrentProcess() DWORD; +pub extern "ole32.dll" stdcallcc fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) HRESULT; + + +pub const COINIT_APARTMENTTHREADED = COINIT.COINIT_APARTMENTTHREADED; +pub const COINIT_MULTITHREADED = COINIT.COINIT_MULTITHREADED; +pub const COINIT_DISABLE_OLE1DDE = COINIT.COINIT_DISABLE_OLE1DDE; +pub const COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY; +pub const COINIT = extern enum { + COINIT_APARTMENTTHREADED = 2, + COINIT_MULTITHREADED = 0, + COINIT_DISABLE_OLE1DDE = 4, + COINIT_SPEED_OVER_MEMORY = 8, +}; diff --git a/std/os/windows/shell32.zig b/std/os/windows/shell32.zig new file mode 100644 index 0000000000..f10466add3 --- /dev/null +++ b/std/os/windows/shell32.zig @@ -0,0 +1,4 @@ +use @import("index.zig"); + +pub extern "shell32.dll" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT; + diff --git a/std/os/windows/shlwapi.zig b/std/os/windows/shlwapi.zig new file mode 100644 index 0000000000..6bccefaf98 --- /dev/null +++ b/std/os/windows/shlwapi.zig @@ -0,0 +1,4 @@ +use @import("index.zig"); + +pub extern "shlwapi" stdcallcc fn PathFileExistsA(pszPath: ?LPCTSTR) BOOL; + diff --git a/std/os/windows/user32.zig b/std/os/windows/user32.zig new file mode 100644 index 0000000000..37f9f6f3b8 --- /dev/null +++ b/std/os/windows/user32.zig @@ -0,0 +1,4 @@ +use @import("index.zig"); + +pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) c_int; + -- cgit v1.2.3