Commit 58c5f94a99
Changed files (15)
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) {
src/os.cpp
@@ -26,7 +26,6 @@
#include <windows.h>
#include <io.h>
#include <fcntl.h>
-#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<ZigWindowsSDK>(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\\");
src/os.hpp
@@ -12,6 +12,7 @@
#include "buffer.hpp"
#include "error.hpp"
#include "zig_llvm.h"
+#include "windows_sdk.h"
#include <stdio.h>
#include <inttypes.h>
@@ -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);
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 <inttypes.h>
+#include <assert.h>
+
+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
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
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");
});
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);
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;
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;
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;
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,
+};
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;
+
std/os/windows/shlwapi.zig
@@ -0,0 +1,4 @@
+use @import("index.zig");
+
+pub extern "shlwapi" stdcallcc fn PathFileExistsA(pszPath: ?LPCTSTR) BOOL;
+
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;
+
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"