self-hosted: share C++ code for finding libc on windows

master
Andrew Kelley 2018-07-20 23:37:37 -04:00
parent f5a67dba08
commit 58c5f94a99
15 changed files with 658 additions and 445 deletions

View File

@ -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"

View File

@ -4,4 +4,5 @@ pub use @cImport({
@cInclude("inttypes.h");
@cInclude("config.h");
@cInclude("zig_llvm.h");
@cInclude("windows_sdk.h");
});

View File

@ -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);

View File

@ -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) {

View File

@ -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\\");

View File

@ -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);

346
src/windows_sdk.cpp Normal file
View File

@ -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

45
src/windows_sdk.h Normal file
View File

@ -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

View File

@ -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;

View File

@ -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;

162
std/os/windows/kernel32.zig Normal file
View File

@ -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;

18
std/os/windows/ole32.zig Normal file
View File

@ -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,
};

View File

@ -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;

View File

@ -0,0 +1,4 @@
use @import("index.zig");
pub extern "shlwapi" stdcallcc fn PathFileExistsA(pszPath: ?LPCTSTR) BOOL;

View File

@ -0,0 +1,4 @@
use @import("index.zig");
pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) c_int;