self-hosted: share C++ code for finding libc on windows
parent
f5a67dba08
commit
58c5f94a99
|
@ -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"
|
||||
|
|
|
@ -4,4 +4,5 @@ pub use @cImport({
|
|||
@cInclude("inttypes.h");
|
||||
@cInclude("config.h");
|
||||
@cInclude("zig_llvm.h");
|
||||
@cInclude("windows_sdk.h");
|
||||
});
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
248
src/os.cpp
248
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\\");
|
||||
|
|
10
src/os.hpp
10
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);
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
|
@ -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,
|
||||
};
|
|
@ -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;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
use @import("index.zig");
|
||||
|
||||
pub extern "shlwapi" stdcallcc fn PathFileExistsA(pszPath: ?LPCTSTR) BOOL;
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
use @import("index.zig");
|
||||
|
||||
pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) c_int;
|
||||
|
Loading…
Reference in New Issue