authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-20 23:37:37-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-07-20 23:38:13-04:00
log58c5f94a99a78346286065bbf390e4c30be1b707
tree4ea22febe640c11a994092f928ef589df27e5eb3
parentf5a67dba08b81c7109c52f6ad957aefdd646b56e

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


15 files changed, 658 insertions(+), 445 deletions(-)

CMakeLists.txt+7
...@@ -426,6 +426,7 @@ set(ZIG_SOURCES...@@ -426,6 +426,7 @@ set(ZIG_SOURCES
426)426)
427set(ZIG_CPP_SOURCES427set(ZIG_CPP_SOURCES
428 "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"428 "${CMAKE_SOURCE_DIR}/src/zig_llvm.cpp"
429 "${CMAKE_SOURCE_DIR}/src/windows_sdk.cpp"
429)430)
430431
431set(ZIG_STD_FILES432set(ZIG_STD_FILES
...@@ -567,8 +568,14 @@ set(ZIG_STD_FILES...@@ -567,8 +568,14 @@ set(ZIG_STD_FILES
567 "os/linux/x86_64.zig"568 "os/linux/x86_64.zig"
568 "os/path.zig"569 "os/path.zig"
569 "os/time.zig"570 "os/time.zig"
571 "os/windows/advapi32.zig"
570 "os/windows/error.zig"572 "os/windows/error.zig"
571 "os/windows/index.zig"573 "os/windows/index.zig"
574 "os/windows/kernel32.zig"
575 "os/windows/ole32.zig"
576 "os/windows/shell32.zig"
577 "os/windows/shlwapi.zig"
578 "os/windows/user32.zig"
572 "os/windows/util.zig"579 "os/windows/util.zig"
573 "os/zen.zig"580 "os/zen.zig"
574 "rand/index.zig"581 "rand/index.zig"
src-self-hosted/c.zig+1
...@@ -4,4 +4,5 @@ pub use @cImport({...@@ -4,4 +4,5 @@ pub use @cImport({
4 @cInclude("inttypes.h");4 @cInclude("inttypes.h");
5 @cInclude("config.h");5 @cInclude("config.h");
6 @cInclude("zig_llvm.h");6 @cInclude("zig_llvm.h");
7 @cInclude("windows_sdk.h");
7});8});
src-self-hosted/libc_installation.zig+20-5
...@@ -2,6 +2,7 @@ const std = @import("std");...@@ -2,6 +2,7 @@ const std = @import("std");
2const builtin = @import("builtin");2const builtin = @import("builtin");
3const event = std.event;3const event = std.event;
4const Target = @import("target.zig").Target;4const Target = @import("target.zig").Target;
5const c = @import("c.zig");
56
6/// See the render function implementation for documentation of the fields.7/// See the render function implementation for documentation of the fields.
7pub const LibCInstallation = struct {8pub const LibCInstallation = struct {
...@@ -122,7 +123,7 @@ pub const LibCInstallation = struct {...@@ -122,7 +123,7 @@ pub const LibCInstallation = struct {
122 \\# Only needed when targeting Windows.123 \\# Only needed when targeting Windows.
123 \\kernel32_lib_dir={}124 \\kernel32_lib_dir={}
124 \\125 \\
125 \\# The full path to the dynamic linker.126 \\# The full path to the dynamic linker, on the target system.
126 \\# Only needed when targeting Linux.127 \\# Only needed when targeting Linux.
127 \\dynamic_linker_path={}128 \\dynamic_linker_path={}
128 \\129 \\
...@@ -143,10 +144,24 @@ pub const LibCInstallation = struct {...@@ -143,10 +144,24 @@ pub const LibCInstallation = struct {
143 errdefer group.cancelAll();144 errdefer group.cancelAll();
144 switch (builtin.os) {145 switch (builtin.os) {
145 builtin.Os.windows => {146 builtin.Os.windows => {
146 try group.call(findNativeIncludeDirWindows, self, loop);147 var sdk: *c.ZigWindowsSDK = undefined;
147 try group.call(findNativeLibDirWindows, self, loop);148 switch (c.zig_find_windows_sdk(@ptrCast(?[*]?[*]c.ZigWindowsSDK, &sdk))) {
148 try group.call(findNativeMsvcLibDir, self, loop);149 c.ZigFindWindowsSdkError.None => {
149 try group.call(findNativeKernel32LibDir, self, loop);150 defer c.zig_free_windows_sdk(@ptrCast(?[*]c.ZigWindowsSDK, sdk));
151
152 errdefer if (self.msvc_lib_dir) |s| loop.allocator.free(s);
153 if (sdk.msvc_lib_dir_ptr) |ptr| {
154 self.msvc_lib_dir = try std.mem.dupe(loop.allocator, u8, ptr[0..sdk.msvc_lib_dir_len]);
155 }
156 //try group.call(findNativeIncludeDirWindows, self, loop);
157 //try group.call(findNativeLibDirWindows, self, loop);
158 //try group.call(findNativeMsvcLibDir, self, loop);
159 //try group.call(findNativeKernel32LibDir, self, loop);
160 },
161 c.ZigFindWindowsSdkError.OutOfMemory => return error.OutOfMemory,
162 c.ZigFindWindowsSdkError.NotFound => return error.NotFound,
163 c.ZigFindWindowsSdkError.PathTooLong => return error.NotFound,
164 }
150 },165 },
151 builtin.Os.linux => {166 builtin.Os.linux => {
152 try group.call(findNativeIncludeDirLinux, self, loop);167 try group.call(findNativeIncludeDirLinux, self, loop);
src/analyze.cpp+3-4
...@@ -4379,7 +4379,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {...@@ -4379,7 +4379,7 @@ bool handle_is_ptr(TypeTableEntry *type_entry) {
43794379
4380static ZigWindowsSDK *get_windows_sdk(CodeGen *g) {4380static ZigWindowsSDK *get_windows_sdk(CodeGen *g) {
4381 if (g->win_sdk == nullptr) {4381 if (g->win_sdk == nullptr) {
4382 if (os_find_windows_sdk(&g->win_sdk)) {4382 if (zig_find_windows_sdk(&g->win_sdk)) {
4383 fprintf(stderr, "unable to determine windows sdk path\n");4383 fprintf(stderr, "unable to determine windows sdk path\n");
4384 exit(1);4384 exit(1);
4385 }4385 }
...@@ -4499,12 +4499,11 @@ void find_libc_lib_path(CodeGen *g) {...@@ -4499,12 +4499,11 @@ void find_libc_lib_path(CodeGen *g) {
4499 ZigWindowsSDK *sdk = get_windows_sdk(g);4499 ZigWindowsSDK *sdk = get_windows_sdk(g);
45004500
4501 if (g->msvc_lib_dir == nullptr) {4501 if (g->msvc_lib_dir == nullptr) {
4502 Buf* vc_lib_dir = buf_alloc();4502 if (sdk->msvc_lib_dir_ptr == nullptr) {
4503 if (os_get_win32_vcruntime_path(vc_lib_dir, g->zig_target.arch.arch)) {
4504 fprintf(stderr, "Unable to determine vcruntime path. --msvc-lib-dir");4503 fprintf(stderr, "Unable to determine vcruntime path. --msvc-lib-dir");
4505 exit(1);4504 exit(1);
4506 }4505 }
4507 g->msvc_lib_dir = vc_lib_dir;4506 g->msvc_lib_dir = buf_create_from_mem(sdk->msvc_lib_dir_ptr, sdk->msvc_lib_dir_len);
4508 }4507 }
45094508
4510 if (g->libc_lib_dir == nullptr) {4509 if (g->libc_lib_dir == nullptr) {
src/os.cpp+4-244
...@@ -26,7 +26,6 @@...@@ -26,7 +26,6 @@
26#include <windows.h>26#include <windows.h>
27#include <io.h>27#include <io.h>
28#include <fcntl.h>28#include <fcntl.h>
29#include "windows_com.hpp"
3029
31typedef SSIZE_T ssize_t;30typedef SSIZE_T ssize_t;
32#else31#else
...@@ -1115,249 +1114,10 @@ void os_stderr_set_color(TermColor color) {...@@ -1115,249 +1114,10 @@ void os_stderr_set_color(TermColor color) {
1115#endif1114#endif
1116}1115}
11171116
1118int os_find_windows_sdk(ZigWindowsSDK **out_sdk) {
1119#if defined(ZIG_OS_WINDOWS)
1120 ZigWindowsSDK *result_sdk = allocate<ZigWindowsSDK>(1);
1121 buf_resize(&result_sdk->path10, 0);
1122 buf_resize(&result_sdk->path81, 0);
1123
1124 HKEY key;
1125 HRESULT rc;
1126 rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY | KEY_ENUMERATE_SUB_KEYS, &key);
1127 if (rc != ERROR_SUCCESS) {
1128 return ErrorFileNotFound;
1129 }
1130
1131 {
1132 DWORD tmp_buf_len = MAX_PATH;
1133 buf_resize(&result_sdk->path10, tmp_buf_len);
1134 rc = RegQueryValueEx(key, "KitsRoot10", NULL, NULL, (LPBYTE)buf_ptr(&result_sdk->path10), &tmp_buf_len);
1135 if (rc == ERROR_FILE_NOT_FOUND) {
1136 buf_resize(&result_sdk->path10, 0);
1137 } else {
1138 buf_resize(&result_sdk->path10, tmp_buf_len);
1139 }
1140 }
1141 {
1142 DWORD tmp_buf_len = MAX_PATH;
1143 buf_resize(&result_sdk->path81, tmp_buf_len);
1144 rc = RegQueryValueEx(key, "KitsRoot81", NULL, NULL, (LPBYTE)buf_ptr(&result_sdk->path81), &tmp_buf_len);
1145 if (rc == ERROR_FILE_NOT_FOUND) {
1146 buf_resize(&result_sdk->path81, 0);
1147 } else {
1148 buf_resize(&result_sdk->path81, tmp_buf_len);
1149 }
1150 }
1151
1152 if (buf_len(&result_sdk->path10) != 0) {
1153 Buf *sdk_lib_dir = buf_sprintf("%s\\Lib\\*", buf_ptr(&result_sdk->path10));
1154
1155 // enumerate files in sdk path looking for latest version
1156 WIN32_FIND_DATA ffd;
1157 HANDLE hFind = FindFirstFileA(buf_ptr(sdk_lib_dir), &ffd);
1158 if (hFind == INVALID_HANDLE_VALUE) {
1159 return ErrorFileNotFound;
1160 }
1161 int v0 = 0, v1 = 0, v2 = 0, v3 = 0;
1162 bool found_version_dir = false;
1163 for (;;) {
1164 if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1165 int c0 = 0, c1 = 0, c2 = 0, c3 = 0;
1166 sscanf(ffd.cFileName, "%d.%d.%d.%d", &c0, &c1, &c2, &c3);
1167 if (c0 == 10 && c1 == 0 && c2 == 10240 && c3 == 0) {
1168 // Microsoft released 26624 as 10240 accidentally.
1169 // https://developer.microsoft.com/en-us/windows/downloads/sdk-archive
1170 c2 = 26624;
1171 }
1172 if ((c0 > v0) || (c1 > v1) || (c2 > v2) || (c3 > v3)) {
1173 v0 = c0, v1 = c1, v2 = c2, v3 = c3;
1174 buf_init_from_str(&result_sdk->version10, ffd.cFileName);
1175 found_version_dir = true;
1176 }
1177 }
1178 if (FindNextFile(hFind, &ffd) == 0) {
1179 FindClose(hFind);
1180 break;
1181 }
1182 }
1183 if (!found_version_dir) {
1184 buf_resize(&result_sdk->path10, 0);
1185 }
1186 }
1187
1188 if (buf_len(&result_sdk->path81) != 0) {
1189 Buf *sdk_lib_dir = buf_sprintf("%s\\Lib\\winv*", buf_ptr(&result_sdk->path81));
1190
1191 // enumerate files in sdk path looking for latest version
1192 WIN32_FIND_DATA ffd;
1193 HANDLE hFind = FindFirstFileA(buf_ptr(sdk_lib_dir), &ffd);
1194 if (hFind == INVALID_HANDLE_VALUE) {
1195 return ErrorFileNotFound;
1196 }
1197 int v0 = 0, v1 = 0;
1198 bool found_version_dir = false;
1199 for (;;) {
1200 if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
1201 int c0 = 0, c1 = 0;
1202 sscanf(ffd.cFileName, "winv%d.%d", &c0, &c1);
1203 if ((c0 > v0) || (c1 > v1)) {
1204 v0 = c0, v1 = c1;
1205 buf_init_from_str(&result_sdk->version81, ffd.cFileName);
1206 found_version_dir = true;
1207 }
1208 }
1209 if (FindNextFile(hFind, &ffd) == 0) {
1210 FindClose(hFind);
1211 break;
1212 }
1213 }
1214 if (!found_version_dir) {
1215 buf_resize(&result_sdk->path81, 0);
1216 }
1217 }
1218
1219 *out_sdk = result_sdk;
1220 return 0;
1221#else
1222 return ErrorFileNotFound;
1223#endif
1224}
1225
1226int os_get_win32_vcruntime_path(Buf* output_buf, ZigLLVM_ArchType platform_type) {
1227#if defined(ZIG_OS_WINDOWS)
1228 buf_resize(output_buf, 0);
1229 //COM Smart Pointerse requires explicit scope
1230 {
1231 HRESULT rc;
1232 rc = CoInitializeEx(NULL, COINIT_MULTITHREADED);
1233 if (rc != S_OK) {
1234 goto com_done;
1235 }
1236
1237 //This COM class is installed when a VS2017
1238 ISetupConfigurationPtr setup_config;
1239 rc = setup_config.CreateInstance(__uuidof(SetupConfiguration));
1240 if (rc != S_OK) {
1241 goto com_done;
1242 }
1243
1244 IEnumSetupInstancesPtr all_instances;
1245 rc = setup_config->EnumInstances(&all_instances);
1246 if (rc != S_OK) {
1247 goto com_done;
1248 }
1249
1250 ISetupInstance* curr_instance;
1251 ULONG found_inst;
1252 while ((rc = all_instances->Next(1, &curr_instance, &found_inst) == S_OK)) {
1253 BSTR bstr_inst_path;
1254 rc = curr_instance->GetInstallationPath(&bstr_inst_path);
1255 if (rc != S_OK) {
1256 goto com_done;
1257 }
1258 //BSTRs are UTF-16 encoded, so we need to convert the string & adjust the length
1259 UINT bstr_path_len = *((UINT*)bstr_inst_path - 1);
1260 ULONG tmp_path_len = bstr_path_len / 2 + 1;
1261 char* conv_path = (char*)bstr_inst_path;
1262 char *tmp_path = (char*)alloca(tmp_path_len);
1263 memset(tmp_path, 0, tmp_path_len);
1264 uint32_t c = 0;
1265 for (uint32_t i = 0; i < bstr_path_len; i += 2) {
1266 tmp_path[c] = conv_path[i];
1267 ++c;
1268 assert(c != tmp_path_len);
1269 }
1270
1271 buf_append_str(output_buf, tmp_path);
1272 buf_append_char(output_buf, '\\');
1273
1274 Buf* tmp_buf = buf_alloc();
1275 buf_append_buf(tmp_buf, output_buf);
1276 buf_append_str(tmp_buf, "VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt");
1277 FILE* tools_file = fopen(buf_ptr(tmp_buf), "r");
1278 if (!tools_file) {
1279 goto com_done;
1280 }
1281 memset(tmp_path, 0, tmp_path_len);
1282 fgets(tmp_path, tmp_path_len, tools_file);
1283 strtok(tmp_path, " \r\n");
1284 fclose(tools_file);
1285 buf_appendf(output_buf, "VC\\Tools\\MSVC\\%s\\lib\\", tmp_path);
1286 switch (platform_type) {
1287 case ZigLLVM_x86:
1288 buf_append_str(output_buf, "x86\\");
1289 break;
1290 case ZigLLVM_x86_64:
1291 buf_append_str(output_buf, "x64\\");
1292 break;
1293 case ZigLLVM_arm:
1294 buf_append_str(output_buf, "arm\\");
1295 break;
1296 default:
1297 zig_panic("Attemped to use vcruntime for non-supported platform.");
1298 }
1299 buf_resize(tmp_buf, 0);
1300 buf_append_buf(tmp_buf, output_buf);
1301 buf_append_str(tmp_buf, "vcruntime.lib");
1302
1303 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1304 return 0;
1305 }
1306 }
1307 }
1308
1309com_done:;
1310 HKEY key;
1311 HRESULT rc;
1312 rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", 0, KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key);
1313 if (rc != ERROR_SUCCESS) {
1314 return ErrorFileNotFound;
1315 }
1316
1317 DWORD dw_type = 0;
1318 DWORD cb_data = 0;
1319 rc = RegQueryValueEx(key, "14.0", NULL, &dw_type, NULL, &cb_data);
1320 if ((rc == ERROR_FILE_NOT_FOUND) || (REG_SZ != dw_type)) {
1321 return ErrorFileNotFound;
1322 }
1323
1324 Buf* tmp_buf = buf_alloc_fixed(cb_data);
1325 RegQueryValueExA(key, "14.0", NULL, NULL, (LPBYTE)buf_ptr(tmp_buf), &cb_data);
1326 //RegQueryValueExA returns the length of the string INCLUDING the null terminator
1327 buf_resize(tmp_buf, cb_data-1);
1328 buf_append_str(tmp_buf, "VC\\Lib\\");
1329 switch (platform_type) {
1330 case ZigLLVM_x86:
1331 //x86 is in the root of the Lib folder
1332 break;
1333 case ZigLLVM_x86_64:
1334 buf_append_str(tmp_buf, "amd64\\");
1335 break;
1336 case ZigLLVM_arm:
1337 buf_append_str(tmp_buf, "arm\\");
1338 break;
1339 default:
1340 zig_panic("Attemped to use vcruntime for non-supported platform.");
1341 }
1342
1343 buf_append_buf(output_buf, tmp_buf);
1344 buf_append_str(tmp_buf, "vcruntime.lib");
1345
1346 if (GetFileAttributesA(buf_ptr(tmp_buf)) != INVALID_FILE_ATTRIBUTES) {
1347 return 0;
1348 } else {
1349 buf_resize(output_buf, 0);
1350 return ErrorFileNotFound;
1351 }
1352#else
1353 return ErrorFileNotFound;
1354#endif
1355}
1356
1357int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {1117int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchType platform_type) {
1358#if defined(ZIG_OS_WINDOWS)1118#if defined(ZIG_OS_WINDOWS)
1359 buf_resize(output_buf, 0);1119 buf_resize(output_buf, 0);
1360 buf_appendf(output_buf, "%s\\Lib\\%s\\ucrt\\", buf_ptr(&sdk->path10), buf_ptr(&sdk->version10));1120 buf_appendf(output_buf, "%s\\Lib\\%s\\ucrt\\", sdk->path10_ptr, sdk->version10_ptr);
1361 switch (platform_type) {1121 switch (platform_type) {
1362 case ZigLLVM_x86:1122 case ZigLLVM_x86:
1363 buf_append_str(output_buf, "x86\\");1123 buf_append_str(output_buf, "x86\\");
...@@ -1389,7 +1149,7 @@ int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Arch...@@ -1389,7 +1149,7 @@ int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_Arch
1389int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {1149int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf* output_buf) {
1390#if defined(ZIG_OS_WINDOWS)1150#if defined(ZIG_OS_WINDOWS)
1391 buf_resize(output_buf, 0);1151 buf_resize(output_buf, 0);
1392 buf_appendf(output_buf, "%s\\Include\\%s\\ucrt", buf_ptr(&sdk->path10), buf_ptr(&sdk->version10));1152 buf_appendf(output_buf, "%s\\Include\\%s\\ucrt", sdk->path10_ptr, sdk->version10_ptr);
1393 if (GetFileAttributesA(buf_ptr(output_buf)) != INVALID_FILE_ATTRIBUTES) {1153 if (GetFileAttributesA(buf_ptr(output_buf)) != INVALID_FILE_ATTRIBUTES) {
1394 return 0;1154 return 0;
1395 }1155 }
...@@ -1406,7 +1166,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy...@@ -1406,7 +1166,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy
1406#if defined(ZIG_OS_WINDOWS)1166#if defined(ZIG_OS_WINDOWS)
1407 {1167 {
1408 buf_resize(output_buf, 0);1168 buf_resize(output_buf, 0);
1409 buf_appendf(output_buf, "%s\\Lib\\%s\\um\\", buf_ptr(&sdk->path10), buf_ptr(&sdk->version10));1169 buf_appendf(output_buf, "%s\\Lib\\%s\\um\\", sdk->path10_ptr, sdk->version10_ptr);
1410 switch (platform_type) {1170 switch (platform_type) {
1411 case ZigLLVM_x86:1171 case ZigLLVM_x86:
1412 buf_append_str(output_buf, "x86\\");1172 buf_append_str(output_buf, "x86\\");
...@@ -1429,7 +1189,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy...@@ -1429,7 +1189,7 @@ int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf* output_buf, ZigLLVM_ArchTy
1429 }1189 }
1430 {1190 {
1431 buf_resize(output_buf, 0);1191 buf_resize(output_buf, 0);
1432 buf_appendf(output_buf, "%s\\Lib\\%s\\um\\", buf_ptr(&sdk->path81), buf_ptr(&sdk->version81));1192 buf_appendf(output_buf, "%s\\Lib\\%s\\um\\", sdk->path81_ptr, sdk->version81_ptr);
1433 switch (platform_type) {1193 switch (platform_type) {
1434 case ZigLLVM_x86:1194 case ZigLLVM_x86:
1435 buf_append_str(output_buf, "x86\\");1195 buf_append_str(output_buf, "x86\\");
src/os.hpp+1-9
...@@ -12,6 +12,7 @@...@@ -12,6 +12,7 @@
12#include "buffer.hpp"12#include "buffer.hpp"
13#include "error.hpp"13#include "error.hpp"
14#include "zig_llvm.h"14#include "zig_llvm.h"
15#include "windows_sdk.h"
1516
16#include <stdio.h>17#include <stdio.h>
17#include <inttypes.h>18#include <inttypes.h>
...@@ -79,15 +80,6 @@ bool os_is_sep(uint8_t c);...@@ -79,15 +80,6 @@ bool os_is_sep(uint8_t c);
7980
80int os_self_exe_path(Buf *out_path);81int os_self_exe_path(Buf *out_path);
8182
82struct ZigWindowsSDK {
83 Buf path10;
84 Buf version10;
85 Buf path81;
86 Buf version81;
87};
88
89int os_find_windows_sdk(ZigWindowsSDK **out_sdk);
90int os_get_win32_vcruntime_path(Buf *output_buf, ZigLLVM_ArchType platform_type);
91int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf *output_buf);83int os_get_win32_ucrt_include_path(ZigWindowsSDK *sdk, Buf *output_buf);
92int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);84int os_get_win32_ucrt_lib_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
93int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);85int os_get_win32_kern32_path(ZigWindowsSDK *sdk, Buf *output_buf, ZigLLVM_ArchType platform_type);
src/windows_sdk.cpp created+346
...@@ -0,0 +1,346 @@
1/*
2 * Copyright (c) 2018 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#include "windows_sdk.h"
9
10#if defined(_WIN32)
11
12#include "windows_com.hpp"
13#include <inttypes.h>
14#include <assert.h>
15
16struct ZigWindowsSDKPrivate {
17 ZigWindowsSDK base;
18};
19
20enum NativeArch {
21 NativeArchArm,
22 NativeArchi386,
23 NativeArchx86_64,
24};
25
26#if defined(_M_ARM) || defined(__arm_)
27static const NativeArch native_arch = NativeArchArm;
28#endif
29#if defined(_M_IX86) || defined(__i386__)
30static const NativeArch native_arch = NativeArchi386;
31#endif
32#if defined(_M_X64) || defined(__x86_64__)
33static const NativeArch native_arch = NativeArchx86_64;
34#endif
35
36void zig_free_windows_sdk(struct ZigWindowsSDK *sdk) {
37 if (sdk == nullptr) {
38 return;
39 }
40 free((void*)sdk->path10_ptr);
41 free((void*)sdk->version10_ptr);
42 free((void*)sdk->path81_ptr);
43 free((void*)sdk->version81_ptr);
44 free((void*)sdk->msvc_lib_dir_ptr);
45}
46
47static ZigFindWindowsSdkError find_msvc_lib_dir(ZigWindowsSDKPrivate *priv) {
48 //COM Smart Pointers requires explicit scope
49 {
50 HRESULT rc = CoInitializeEx(NULL, COINIT_MULTITHREADED);
51 if (rc != S_OK && rc != S_FALSE) {
52 goto com_done;
53 }
54
55 //This COM class is installed when a VS2017
56 ISetupConfigurationPtr setup_config;
57 rc = setup_config.CreateInstance(__uuidof(SetupConfiguration));
58 if (rc != S_OK) {
59 goto com_done;
60 }
61
62 IEnumSetupInstancesPtr all_instances;
63 rc = setup_config->EnumInstances(&all_instances);
64 if (rc != S_OK) {
65 goto com_done;
66 }
67
68 ISetupInstance* curr_instance;
69 ULONG found_inst;
70 while ((rc = all_instances->Next(1, &curr_instance, &found_inst) == S_OK)) {
71 BSTR bstr_inst_path;
72 rc = curr_instance->GetInstallationPath(&bstr_inst_path);
73 if (rc != S_OK) {
74 goto com_done;
75 }
76 //BSTRs are UTF-16 encoded, so we need to convert the string & adjust the length
77 //TODO call an actual function to do this
78 UINT bstr_path_len = *((UINT*)bstr_inst_path - 1);
79 ULONG tmp_path_len = bstr_path_len / 2 + 1;
80 char* conv_path = (char*)bstr_inst_path;
81 // TODO don't use alloca
82 char *tmp_path = (char*)alloca(tmp_path_len);
83 memset(tmp_path, 0, tmp_path_len);
84 uint32_t c = 0;
85 for (uint32_t i = 0; i < bstr_path_len; i += 2) {
86 tmp_path[c] = conv_path[i];
87 ++c;
88 assert(c != tmp_path_len);
89 }
90 char output_path[4096];
91 output_path[0] = 0;
92 char *out_append_ptr = output_path;
93
94 out_append_ptr += sprintf(out_append_ptr, "%s\\", tmp_path);
95
96 char tmp_buf[4096];
97 sprintf(tmp_buf, "%s%s", output_path, "VC\\Auxiliary\\Build\\Microsoft.VCToolsVersion.default.txt");
98 FILE* tools_file = fopen(tmp_buf, "rb");
99 if (!tools_file) {
100 goto com_done;
101 }
102 memset(tmp_path, 0, tmp_path_len);
103 fgets(tmp_path, tmp_path_len, tools_file);
104 strtok(tmp_path, " \r\n");
105 fclose(tools_file);
106 out_append_ptr += sprintf(out_append_ptr, "VC\\Tools\\MSVC\\%s\\lib\\", tmp_path);
107 switch (native_arch) {
108 case NativeArchi386:
109 out_append_ptr += sprintf(out_append_ptr, "x86\\");
110 break;
111 case NativeArchx86_64:
112 out_append_ptr += sprintf(out_append_ptr, "x64\\");
113 break;
114 case NativeArchArm:
115 out_append_ptr += sprintf(out_append_ptr, "arm\\");
116 break;
117 }
118 sprintf(tmp_buf, "%s%s", output_path, "vcruntime.lib");
119
120 if (GetFileAttributesA(tmp_buf) != INVALID_FILE_ATTRIBUTES) {
121 priv->base.msvc_lib_dir_ptr = strdup(output_path);
122 if (priv->base.msvc_lib_dir_ptr == nullptr) {
123 return ZigFindWindowsSdkErrorOutOfMemory;
124 }
125 priv->base.msvc_lib_dir_len = strlen(priv->base.msvc_lib_dir_ptr);
126 return ZigFindWindowsSdkErrorNone;
127 }
128 }
129 }
130
131com_done:;
132 HKEY key;
133 HRESULT rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\VisualStudio\\SxS\\VS7", 0,
134 KEY_QUERY_VALUE | KEY_WOW64_32KEY, &key);
135 if (rc != ERROR_SUCCESS) {
136 return ZigFindWindowsSdkErrorNotFound;
137 }
138
139 DWORD dw_type = 0;
140 DWORD cb_data = 0;
141 rc = RegQueryValueEx(key, "14.0", NULL, &dw_type, NULL, &cb_data);
142 if ((rc == ERROR_FILE_NOT_FOUND) || (REG_SZ != dw_type)) {
143 return ZigFindWindowsSdkErrorNotFound;
144 }
145
146 char tmp_buf[4096];
147
148 RegQueryValueExA(key, "14.0", NULL, NULL, (LPBYTE)tmp_buf, &cb_data);
149 // RegQueryValueExA returns the length of the string INCLUDING the null terminator
150 char *tmp_buf_append_ptr = tmp_buf + (cb_data - 1);
151 tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "VC\\Lib\\");
152 switch (native_arch) {
153 case NativeArchi386:
154 //x86 is in the root of the Lib folder
155 break;
156 case NativeArchx86_64:
157 tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "amd64\\");
158 break;
159 case NativeArchArm:
160 tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "arm\\");
161 break;
162 }
163
164 char *output_path = strdup(tmp_buf);
165 if (output_path == nullptr) {
166 return ZigFindWindowsSdkErrorOutOfMemory;
167 }
168
169 tmp_buf_append_ptr += sprintf(tmp_buf_append_ptr, "vcruntime.lib");
170
171 if (GetFileAttributesA(tmp_buf) != INVALID_FILE_ATTRIBUTES) {
172 priv->base.msvc_lib_dir_ptr = output_path;
173 priv->base.msvc_lib_dir_len = strlen(output_path);
174 return ZigFindWindowsSdkErrorNone;
175 } else {
176 free(output_path);
177 return ZigFindWindowsSdkErrorNotFound;
178 }
179}
180
181static ZigFindWindowsSdkError find_10_version(ZigWindowsSDKPrivate *priv) {
182 if (priv->base.path10_ptr == nullptr)
183 return ZigFindWindowsSdkErrorNone;
184
185 char sdk_lib_dir[4096];
186 int n = snprintf(sdk_lib_dir, 4096, "%s\\Lib\\*", priv->base.path10_ptr);
187 if (n < 0 || n >= 4096) {
188 return ZigFindWindowsSdkErrorPathTooLong;
189 }
190
191 // enumerate files in sdk path looking for latest version
192 WIN32_FIND_DATA ffd;
193 HANDLE hFind = FindFirstFileA(sdk_lib_dir, &ffd);
194 if (hFind == INVALID_HANDLE_VALUE) {
195 return ZigFindWindowsSdkErrorNotFound;
196 }
197 int v0 = 0, v1 = 0, v2 = 0, v3 = 0;
198 for (;;) {
199 if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
200 int c0 = 0, c1 = 0, c2 = 0, c3 = 0;
201 sscanf(ffd.cFileName, "%d.%d.%d.%d", &c0, &c1, &c2, &c3);
202 if (c0 == 10 && c1 == 0 && c2 == 10240 && c3 == 0) {
203 // Microsoft released 26624 as 10240 accidentally.
204 // https://developer.microsoft.com/en-us/windows/downloads/sdk-archive
205 c2 = 26624;
206 }
207 if ((c0 > v0) || (c1 > v1) || (c2 > v2) || (c3 > v3)) {
208 v0 = c0, v1 = c1, v2 = c2, v3 = c3;
209 free((void*)priv->base.version10_ptr);
210 priv->base.version10_ptr = strdup(ffd.cFileName);
211 if (priv->base.version10_ptr == nullptr) {
212 FindClose(hFind);
213 return ZigFindWindowsSdkErrorOutOfMemory;
214 }
215 }
216 }
217 if (FindNextFile(hFind, &ffd) == 0) {
218 FindClose(hFind);
219 break;
220 }
221 }
222 priv->base.version10_len = strlen(priv->base.version10_ptr);
223 return ZigFindWindowsSdkErrorNone;
224}
225
226static ZigFindWindowsSdkError find_81_version(ZigWindowsSDKPrivate *priv) {
227 if (priv->base.path81_ptr == nullptr)
228 return ZigFindWindowsSdkErrorNone;
229
230 char sdk_lib_dir[4096];
231 int n = snprintf(sdk_lib_dir, 4096, "%s\\Lib\\winv*", priv->base.path81_ptr);
232 if (n < 0 || n >= 4096) {
233 return ZigFindWindowsSdkErrorPathTooLong;
234 }
235
236 // enumerate files in sdk path looking for latest version
237 WIN32_FIND_DATA ffd;
238 HANDLE hFind = FindFirstFileA(sdk_lib_dir, &ffd);
239 if (hFind == INVALID_HANDLE_VALUE) {
240 return ZigFindWindowsSdkErrorNotFound;
241 }
242 int v0 = 0, v1 = 0;
243 for (;;) {
244 if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
245 int c0 = 0, c1 = 0;
246 sscanf(ffd.cFileName, "winv%d.%d", &c0, &c1);
247 if ((c0 > v0) || (c1 > v1)) {
248 v0 = c0, v1 = c1;
249 free((void*)priv->base.version81_ptr);
250 priv->base.version81_ptr = strdup(ffd.cFileName);
251 if (priv->base.version81_ptr == nullptr) {
252 FindClose(hFind);
253 return ZigFindWindowsSdkErrorOutOfMemory;
254 }
255 }
256 }
257 if (FindNextFile(hFind, &ffd) == 0) {
258 FindClose(hFind);
259 break;
260 }
261 }
262 priv->base.version81_len = strlen(priv->base.version81_ptr);
263 return ZigFindWindowsSdkErrorNone;
264}
265
266ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk) {
267 ZigWindowsSDKPrivate *priv = (ZigWindowsSDKPrivate*)calloc(1, sizeof(ZigWindowsSDKPrivate));
268 if (priv == nullptr) {
269 return ZigFindWindowsSdkErrorOutOfMemory;
270 }
271
272 HKEY key;
273 HRESULT rc;
274 rc = RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SOFTWARE\\Microsoft\\Windows Kits\\Installed Roots", 0,
275 KEY_QUERY_VALUE | KEY_WOW64_32KEY | KEY_ENUMERATE_SUB_KEYS, &key);
276 if (rc != ERROR_SUCCESS) {
277 zig_free_windows_sdk(&priv->base);
278 return ZigFindWindowsSdkErrorNotFound;
279 }
280
281 {
282 DWORD tmp_buf_len = MAX_PATH;
283 priv->base.path10_ptr = (const char *)calloc(tmp_buf_len, 1);
284 if (priv->base.path10_ptr == nullptr) {
285 zig_free_windows_sdk(&priv->base);
286 return ZigFindWindowsSdkErrorOutOfMemory;
287 }
288 rc = RegQueryValueEx(key, "KitsRoot10", NULL, NULL, (LPBYTE)priv->base.path10_ptr, &tmp_buf_len);
289 if (rc == ERROR_SUCCESS) {
290 priv->base.path10_len = tmp_buf_len;
291 } else {
292 free((void*)priv->base.path10_ptr);
293 priv->base.path10_ptr = nullptr;
294 }
295 }
296 {
297 DWORD tmp_buf_len = MAX_PATH;
298 priv->base.path81_ptr = (const char *)calloc(tmp_buf_len, 1);
299 if (priv->base.path81_ptr == nullptr) {
300 zig_free_windows_sdk(&priv->base);
301 return ZigFindWindowsSdkErrorOutOfMemory;
302 }
303 rc = RegQueryValueEx(key, "KitsRoot81", NULL, NULL, (LPBYTE)priv->base.path81_ptr, &tmp_buf_len);
304 if (rc == ERROR_SUCCESS) {
305 priv->base.path81_len = tmp_buf_len;
306 } else {
307 free((void*)priv->base.path81_ptr);
308 priv->base.path81_ptr = nullptr;
309 }
310 }
311
312 {
313 ZigFindWindowsSdkError err = find_10_version(priv);
314 if (err == ZigFindWindowsSdkErrorOutOfMemory) {
315 zig_free_windows_sdk(&priv->base);
316 return err;
317 }
318 }
319 {
320 ZigFindWindowsSdkError err = find_81_version(priv);
321 if (err == ZigFindWindowsSdkErrorOutOfMemory) {
322 zig_free_windows_sdk(&priv->base);
323 return err;
324 }
325 }
326
327 {
328 ZigFindWindowsSdkError err = find_msvc_lib_dir(priv);
329 if (err == ZigFindWindowsSdkErrorOutOfMemory) {
330 zig_free_windows_sdk(&priv->base);
331 return err;
332 }
333 }
334
335 *out_sdk = &priv->base;
336 return ZigFindWindowsSdkErrorNone;
337}
338
339#else
340
341void zig_free_windows_sdk(struct ZigWindowsSDK *sdk) {}
342ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk) {
343 return ZigFindWindowsSdkErrorNotFound;
344}
345
346#endif
src/windows_sdk.h created+45
...@@ -0,0 +1,45 @@
1/*
2 * Copyright (c) 2018 Andrew Kelley
3 *
4 * This file is part of zig, which is MIT licensed.
5 * See http://opensource.org/licenses/MIT
6 */
7
8#ifndef ZIG_WINDOWS_SDK_H
9#define ZIG_WINDOWS_SDK_H
10
11#ifdef __cplusplus
12#define ZIG_EXTERN_C extern "C"
13#else
14#define ZIG_EXTERN_C
15#endif
16
17struct ZigWindowsSDK {
18 const char *path10_ptr;
19 size_t path10_len;
20
21 const char *version10_ptr;
22 size_t version10_len;
23
24 const char *path81_ptr;
25 size_t path81_len;
26
27 const char *version81_ptr;
28 size_t version81_len;
29
30 const char *msvc_lib_dir_ptr;
31 size_t msvc_lib_dir_len;
32};
33
34enum ZigFindWindowsSdkError {
35 ZigFindWindowsSdkErrorNone,
36 ZigFindWindowsSdkErrorOutOfMemory,
37 ZigFindWindowsSdkErrorNotFound,
38 ZigFindWindowsSdkErrorPathTooLong,
39};
40
41ZIG_EXTERN_C enum ZigFindWindowsSdkError zig_find_windows_sdk(struct ZigWindowsSDK **out_sdk);
42
43ZIG_EXTERN_C void zig_free_windows_sdk(struct ZigWindowsSDK *sdk);
44
45#endif
std/os/windows/advapi32.zig created+30
...@@ -0,0 +1,30 @@
1use @import("index.zig");
2
3pub const PROV_RSA_FULL = 1;
4
5pub const REGSAM = ACCESS_MASK;
6pub const ACCESS_MASK = DWORD;
7pub const PHKEY = &HKEY;
8pub const HKEY = &HKEY__;
9pub const HKEY__ = extern struct {
10 unused: c_int,
11};
12pub const LSTATUS = LONG;
13
14pub extern "advapi32" stdcallcc fn CryptAcquireContextA(
15 phProv: *HCRYPTPROV,
16 pszContainer: ?LPCSTR,
17 pszProvider: ?LPCSTR,
18 dwProvType: DWORD,
19 dwFlags: DWORD,
20) BOOL;
21
22pub extern "advapi32" stdcallcc fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) BOOL;
23
24pub extern "advapi32" stdcallcc fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: [*]BYTE) BOOL;
25
26pub extern "advapi32" stdcallcc fn RegOpenKeyExW(hKey: HKEY, lpSubKey: LPCWSTR, ulOptions: DWORD, samDesired: REGSAM,
27 phkResult: &HKEY,) LSTATUS;
28
29pub extern "advapi32" stdcallcc fn RegQueryValueExW(hKey: HKEY, lpValueName: LPCWSTR, lpReserved: LPDWORD,
30 lpType: LPDWORD, lpData: LPBYTE, lpcbData: LPDWORD,) LSTATUS;
std/os/windows/index.zig+9-183
...@@ -1,190 +1,19 @@...@@ -1,190 +1,19 @@
1const std = @import("../../index.zig");1const std = @import("../../index.zig");
2const assert = std.debug.assert;2const assert = std.debug.assert;
3
4pub use @import("advapi32.zig");
5pub use @import("kernel32.zig");
6pub use @import("ole32.zig");
7pub use @import("shell32.zig");
8pub use @import("shlwapi.zig");
9pub use @import("user32.zig");
10
3test "import" {11test "import" {
4 _ = @import("util.zig");12 _ = @import("util.zig");
5}13}
614
7pub const ERROR = @import("error.zig");15pub const ERROR = @import("error.zig");
816
9pub extern "advapi32" stdcallcc fn CryptAcquireContextA(
10 phProv: *HCRYPTPROV,
11 pszContainer: ?LPCSTR,
12 pszProvider: ?LPCSTR,
13 dwProvType: DWORD,
14 dwFlags: DWORD,
15) BOOL;
16
17pub extern "advapi32" stdcallcc fn CryptReleaseContext(hProv: HCRYPTPROV, dwFlags: DWORD) BOOL;
18
19pub extern "advapi32" stdcallcc fn CryptGenRandom(hProv: HCRYPTPROV, dwLen: DWORD, pbBuffer: [*]BYTE) BOOL;
20
21pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL;
22
23pub extern "kernel32" stdcallcc fn CreateDirectoryA(
24 lpPathName: LPCSTR,
25 lpSecurityAttributes: ?*SECURITY_ATTRIBUTES,
26) BOOL;
27
28pub extern "kernel32" stdcallcc fn CreateFileA(
29 lpFileName: LPCSTR,
30 dwDesiredAccess: DWORD,
31 dwShareMode: DWORD,
32 lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES,
33 dwCreationDisposition: DWORD,
34 dwFlagsAndAttributes: DWORD,
35 hTemplateFile: ?HANDLE,
36) HANDLE;
37
38pub extern "kernel32" stdcallcc fn CreatePipe(
39 hReadPipe: *HANDLE,
40 hWritePipe: *HANDLE,
41 lpPipeAttributes: *const SECURITY_ATTRIBUTES,
42 nSize: DWORD,
43) BOOL;
44
45pub extern "kernel32" stdcallcc fn CreateProcessA(
46 lpApplicationName: ?LPCSTR,
47 lpCommandLine: LPSTR,
48 lpProcessAttributes: ?*SECURITY_ATTRIBUTES,
49 lpThreadAttributes: ?*SECURITY_ATTRIBUTES,
50 bInheritHandles: BOOL,
51 dwCreationFlags: DWORD,
52 lpEnvironment: ?*c_void,
53 lpCurrentDirectory: ?LPCSTR,
54 lpStartupInfo: *STARTUPINFOA,
55 lpProcessInformation: *PROCESS_INFORMATION,
56) BOOL;
57
58pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA(
59 lpSymlinkFileName: LPCSTR,
60 lpTargetFileName: LPCSTR,
61 dwFlags: DWORD,
62) BOOLEAN;
63
64pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) ?HANDLE;
65
66pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE;
67
68pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) BOOL;
69
70pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn;
71
72pub extern "kernel32" stdcallcc fn FindFirstFileA(lpFileName: LPCSTR, lpFindFileData: *WIN32_FIND_DATAA) HANDLE;
73pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;
74pub extern "kernel32" stdcallcc fn FindNextFileA(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAA) BOOL;
75
76pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsA(penv: [*]u8) BOOL;
77
78pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;
79
80pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) BOOL;
81
82pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD;
83
84pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8;
85
86pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD;
87
88pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL;
89
90pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) BOOL;
91
92pub extern "kernel32" stdcallcc fn GetFileAttributesA(lpFileName: LPCSTR) DWORD;
93
94pub extern "kernel32" stdcallcc fn GetModuleFileNameA(hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) DWORD;
95
96pub extern "kernel32" stdcallcc fn GetLastError() DWORD;
97
98pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(
99 in_hFile: HANDLE,
100 in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
101 out_lpFileInformation: *c_void,
102 in_dwBufferSize: DWORD,
103) BOOL;
104
105pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleA(
106 hFile: HANDLE,
107 lpszFilePath: LPSTR,
108 cchFilePath: DWORD,
109 dwFlags: DWORD,
110) DWORD;
111
112pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE;
113pub extern "kernel32" stdcallcc fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) BOOL;
114
115pub extern "kernel32" stdcallcc fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) void;
116pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(*FILETIME) void;
117
118pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE;
119pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL;
120pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) ?*c_void;
121pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) SIZE_T;
122pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) BOOL;
123pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T;
124pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL;
125
126pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE;
127
128pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?*c_void;
129
130pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) BOOL;
131
132pub extern "kernel32" stdcallcc fn MoveFileExA(
133 lpExistingFileName: LPCSTR,
134 lpNewFileName: LPCSTR,
135 dwFlags: DWORD,
136) BOOL;
137
138pub extern "kernel32" stdcallcc fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) BOOL;
139
140pub extern "kernel32" stdcallcc fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) BOOL;
141
142pub extern "kernel32" stdcallcc fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) BOOL;
143
144pub extern "kernel32" stdcallcc fn ReadFile(
145 in_hFile: HANDLE,
146 out_lpBuffer: *c_void,
147 in_nNumberOfBytesToRead: DWORD,
148 out_lpNumberOfBytesRead: *DWORD,
149 in_out_lpOverlapped: ?*OVERLAPPED,
150) BOOL;
151
152pub extern "kernel32" stdcallcc fn RemoveDirectoryA(lpPathName: LPCSTR) BOOL;
153
154pub extern "kernel32" stdcallcc fn SetFilePointerEx(
155 in_fFile: HANDLE,
156 in_liDistanceToMove: LARGE_INTEGER,
157 out_opt_ldNewFilePointer: ?*LARGE_INTEGER,
158 in_dwMoveMethod: DWORD,
159) BOOL;
160
161pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL;
162
163pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void;
164
165pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL;
166
167pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD;
168
169pub extern "kernel32" stdcallcc fn WriteFile(
170 in_hFile: HANDLE,
171 in_lpBuffer: *const c_void,
172 in_nNumberOfBytesToWrite: DWORD,
173 out_lpNumberOfBytesWritten: ?*DWORD,
174 in_out_lpOverlapped: ?*OVERLAPPED,
175) BOOL;
176
177//TODO: call unicode versions instead of relying on ANSI code page
178pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: LPCSTR) ?HMODULE;
179
180pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL;
181
182pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) c_int;
183
184pub extern "shlwapi" stdcallcc fn PathFileExistsA(pszPath: ?LPCTSTR) BOOL;
185
186pub const PROV_RSA_FULL = 1;
187
188pub const BOOL = c_int;17pub const BOOL = c_int;
189pub const BOOLEAN = BYTE;18pub const BOOLEAN = BYTE;
190pub const BYTE = u8;19pub const BYTE = u8;
...@@ -206,6 +35,7 @@ pub const LPSTR = [*]CHAR;...@@ -206,6 +35,7 @@ pub const LPSTR = [*]CHAR;
206pub const LPTSTR = if (UNICODE) LPWSTR else LPSTR;35pub const LPTSTR = if (UNICODE) LPWSTR else LPSTR;
207pub const LPVOID = *c_void;36pub const LPVOID = *c_void;
208pub const LPWSTR = [*]WCHAR;37pub const LPWSTR = [*]WCHAR;
38pub const LPCWSTR = [*]const WCHAR;
209pub const PVOID = *c_void;39pub const PVOID = *c_void;
210pub const PWSTR = [*]WCHAR;40pub const PWSTR = [*]WCHAR;
211pub const SIZE_T = usize;41pub const SIZE_T = usize;
...@@ -442,10 +272,6 @@ pub const SYSTEM_INFO = extern struct {...@@ -442,10 +272,6 @@ pub const SYSTEM_INFO = extern struct {
442 wProcessorRevision: WORD,272 wProcessorRevision: WORD,
443};273};
444274
445pub extern "ole32.dll" stdcallcc fn CoTaskMemFree(pv: LPVOID) void;
446
447pub extern "shell32.dll" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT;
448
449pub const HRESULT = c_long;275pub const HRESULT = c_long;
450276
451pub const KNOWNFOLDERID = GUID;277pub const KNOWNFOLDERID = GUID;
std/os/windows/kernel32.zig created+162
...@@ -0,0 +1,162 @@
1use @import("index.zig");
2
3pub extern "kernel32" stdcallcc fn CloseHandle(hObject: HANDLE) BOOL;
4
5pub extern "kernel32" stdcallcc fn CreateDirectoryA(
6 lpPathName: LPCSTR,
7 lpSecurityAttributes: ?*SECURITY_ATTRIBUTES,
8) BOOL;
9
10pub extern "kernel32" stdcallcc fn CreateFileA(
11 lpFileName: LPCSTR,
12 dwDesiredAccess: DWORD,
13 dwShareMode: DWORD,
14 lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES,
15 dwCreationDisposition: DWORD,
16 dwFlagsAndAttributes: DWORD,
17 hTemplateFile: ?HANDLE,
18) HANDLE;
19
20pub extern "kernel32" stdcallcc fn CreatePipe(
21 hReadPipe: *HANDLE,
22 hWritePipe: *HANDLE,
23 lpPipeAttributes: *const SECURITY_ATTRIBUTES,
24 nSize: DWORD,
25) BOOL;
26
27pub extern "kernel32" stdcallcc fn CreateProcessA(
28 lpApplicationName: ?LPCSTR,
29 lpCommandLine: LPSTR,
30 lpProcessAttributes: ?*SECURITY_ATTRIBUTES,
31 lpThreadAttributes: ?*SECURITY_ATTRIBUTES,
32 bInheritHandles: BOOL,
33 dwCreationFlags: DWORD,
34 lpEnvironment: ?*c_void,
35 lpCurrentDirectory: ?LPCSTR,
36 lpStartupInfo: *STARTUPINFOA,
37 lpProcessInformation: *PROCESS_INFORMATION,
38) BOOL;
39
40pub extern "kernel32" stdcallcc fn CreateSymbolicLinkA(
41 lpSymlinkFileName: LPCSTR,
42 lpTargetFileName: LPCSTR,
43 dwFlags: DWORD,
44) BOOLEAN;
45
46pub extern "kernel32" stdcallcc fn CreateIoCompletionPort(FileHandle: HANDLE, ExistingCompletionPort: ?HANDLE, CompletionKey: ULONG_PTR, NumberOfConcurrentThreads: DWORD) ?HANDLE;
47
48pub extern "kernel32" stdcallcc fn CreateThread(lpThreadAttributes: ?LPSECURITY_ATTRIBUTES, dwStackSize: SIZE_T, lpStartAddress: LPTHREAD_START_ROUTINE, lpParameter: ?LPVOID, dwCreationFlags: DWORD, lpThreadId: ?LPDWORD) ?HANDLE;
49
50pub extern "kernel32" stdcallcc fn DeleteFileA(lpFileName: LPCSTR) BOOL;
51
52pub extern "kernel32" stdcallcc fn ExitProcess(exit_code: UINT) noreturn;
53
54pub extern "kernel32" stdcallcc fn FindFirstFileA(lpFileName: LPCSTR, lpFindFileData: *WIN32_FIND_DATAA) HANDLE;
55pub extern "kernel32" stdcallcc fn FindClose(hFindFile: HANDLE) BOOL;
56pub extern "kernel32" stdcallcc fn FindNextFileA(hFindFile: HANDLE, lpFindFileData: *WIN32_FIND_DATAA) BOOL;
57
58pub extern "kernel32" stdcallcc fn FreeEnvironmentStringsA(penv: [*]u8) BOOL;
59
60pub extern "kernel32" stdcallcc fn GetCommandLineA() LPSTR;
61
62pub extern "kernel32" stdcallcc fn GetConsoleMode(in_hConsoleHandle: HANDLE, out_lpMode: *DWORD) BOOL;
63
64pub extern "kernel32" stdcallcc fn GetCurrentDirectoryA(nBufferLength: WORD, lpBuffer: ?LPSTR) DWORD;
65
66pub extern "kernel32" stdcallcc fn GetEnvironmentStringsA() ?[*]u8;
67
68pub extern "kernel32" stdcallcc fn GetEnvironmentVariableA(lpName: LPCSTR, lpBuffer: LPSTR, nSize: DWORD) DWORD;
69
70pub extern "kernel32" stdcallcc fn GetExitCodeProcess(hProcess: HANDLE, lpExitCode: *DWORD) BOOL;
71
72pub extern "kernel32" stdcallcc fn GetFileSizeEx(hFile: HANDLE, lpFileSize: *LARGE_INTEGER) BOOL;
73
74pub extern "kernel32" stdcallcc fn GetFileAttributesA(lpFileName: LPCSTR) DWORD;
75
76pub extern "kernel32" stdcallcc fn GetModuleFileNameA(hModule: ?HMODULE, lpFilename: LPSTR, nSize: DWORD) DWORD;
77
78pub extern "kernel32" stdcallcc fn GetLastError() DWORD;
79
80pub extern "kernel32" stdcallcc fn GetFileInformationByHandleEx(
81 in_hFile: HANDLE,
82 in_FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
83 out_lpFileInformation: *c_void,
84 in_dwBufferSize: DWORD,
85) BOOL;
86
87pub extern "kernel32" stdcallcc fn GetFinalPathNameByHandleA(
88 hFile: HANDLE,
89 lpszFilePath: LPSTR,
90 cchFilePath: DWORD,
91 dwFlags: DWORD,
92) DWORD;
93
94pub extern "kernel32" stdcallcc fn GetProcessHeap() ?HANDLE;
95pub extern "kernel32" stdcallcc fn GetQueuedCompletionStatus(CompletionPort: HANDLE, lpNumberOfBytesTransferred: LPDWORD, lpCompletionKey: *ULONG_PTR, lpOverlapped: *?*OVERLAPPED, dwMilliseconds: DWORD) BOOL;
96
97pub extern "kernel32" stdcallcc fn GetSystemInfo(lpSystemInfo: *SYSTEM_INFO) void;
98pub extern "kernel32" stdcallcc fn GetSystemTimeAsFileTime(*FILETIME) void;
99
100pub extern "kernel32" stdcallcc fn HeapCreate(flOptions: DWORD, dwInitialSize: SIZE_T, dwMaximumSize: SIZE_T) ?HANDLE;
101pub extern "kernel32" stdcallcc fn HeapDestroy(hHeap: HANDLE) BOOL;
102pub extern "kernel32" stdcallcc fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void, dwBytes: SIZE_T) ?*c_void;
103pub extern "kernel32" stdcallcc fn HeapSize(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) SIZE_T;
104pub extern "kernel32" stdcallcc fn HeapValidate(hHeap: HANDLE, dwFlags: DWORD, lpMem: *const c_void) BOOL;
105pub extern "kernel32" stdcallcc fn HeapCompact(hHeap: HANDLE, dwFlags: DWORD) SIZE_T;
106pub extern "kernel32" stdcallcc fn HeapSummary(hHeap: HANDLE, dwFlags: DWORD, lpSummary: LPHEAP_SUMMARY) BOOL;
107
108pub extern "kernel32" stdcallcc fn GetStdHandle(in_nStdHandle: DWORD) ?HANDLE;
109
110pub extern "kernel32" stdcallcc fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) ?*c_void;
111
112pub extern "kernel32" stdcallcc fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: *c_void) BOOL;
113
114pub extern "kernel32" stdcallcc fn MoveFileExA(
115 lpExistingFileName: LPCSTR,
116 lpNewFileName: LPCSTR,
117 dwFlags: DWORD,
118) BOOL;
119
120pub extern "kernel32" stdcallcc fn PostQueuedCompletionStatus(CompletionPort: HANDLE, dwNumberOfBytesTransferred: DWORD, dwCompletionKey: ULONG_PTR, lpOverlapped: ?*OVERLAPPED) BOOL;
121
122pub extern "kernel32" stdcallcc fn QueryPerformanceCounter(lpPerformanceCount: *LARGE_INTEGER) BOOL;
123
124pub extern "kernel32" stdcallcc fn QueryPerformanceFrequency(lpFrequency: *LARGE_INTEGER) BOOL;
125
126pub extern "kernel32" stdcallcc fn ReadFile(
127 in_hFile: HANDLE,
128 out_lpBuffer: *c_void,
129 in_nNumberOfBytesToRead: DWORD,
130 out_lpNumberOfBytesRead: *DWORD,
131 in_out_lpOverlapped: ?*OVERLAPPED,
132) BOOL;
133
134pub extern "kernel32" stdcallcc fn RemoveDirectoryA(lpPathName: LPCSTR) BOOL;
135
136pub extern "kernel32" stdcallcc fn SetFilePointerEx(
137 in_fFile: HANDLE,
138 in_liDistanceToMove: LARGE_INTEGER,
139 out_opt_ldNewFilePointer: ?*LARGE_INTEGER,
140 in_dwMoveMethod: DWORD,
141) BOOL;
142
143pub extern "kernel32" stdcallcc fn SetHandleInformation(hObject: HANDLE, dwMask: DWORD, dwFlags: DWORD) BOOL;
144
145pub extern "kernel32" stdcallcc fn Sleep(dwMilliseconds: DWORD) void;
146
147pub extern "kernel32" stdcallcc fn TerminateProcess(hProcess: HANDLE, uExitCode: UINT) BOOL;
148
149pub extern "kernel32" stdcallcc fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) DWORD;
150
151pub extern "kernel32" stdcallcc fn WriteFile(
152 in_hFile: HANDLE,
153 in_lpBuffer: *const c_void,
154 in_nNumberOfBytesToWrite: DWORD,
155 out_lpNumberOfBytesWritten: ?*DWORD,
156 in_out_lpOverlapped: ?*OVERLAPPED,
157) BOOL;
158
159//TODO: call unicode versions instead of relying on ANSI code page
160pub extern "kernel32" stdcallcc fn LoadLibraryA(lpLibFileName: LPCSTR) ?HMODULE;
161
162pub extern "kernel32" stdcallcc fn FreeLibrary(hModule: HMODULE) BOOL;
std/os/windows/ole32.zig created+18
...@@ -0,0 +1,18 @@
1use @import("index.zig");
2
3pub extern "ole32.dll" stdcallcc fn CoTaskMemFree(pv: LPVOID) void;
4pub extern "ole32.dll" stdcallcc fn CoUninitialize() void;
5pub extern "ole32.dll" stdcallcc fn CoGetCurrentProcess() DWORD;
6pub extern "ole32.dll" stdcallcc fn CoInitializeEx(pvReserved: LPVOID, dwCoInit: DWORD) HRESULT;
7
8
9pub const COINIT_APARTMENTTHREADED = COINIT.COINIT_APARTMENTTHREADED;
10pub const COINIT_MULTITHREADED = COINIT.COINIT_MULTITHREADED;
11pub const COINIT_DISABLE_OLE1DDE = COINIT.COINIT_DISABLE_OLE1DDE;
12pub const COINIT_SPEED_OVER_MEMORY = COINIT.COINIT_SPEED_OVER_MEMORY;
13pub const COINIT = extern enum {
14 COINIT_APARTMENTTHREADED = 2,
15 COINIT_MULTITHREADED = 0,
16 COINIT_DISABLE_OLE1DDE = 4,
17 COINIT_SPEED_OVER_MEMORY = 8,
18};
std/os/windows/shell32.zig created+4
...@@ -0,0 +1,4 @@
1use @import("index.zig");
2
3pub extern "shell32.dll" stdcallcc fn SHGetKnownFolderPath(rfid: *const KNOWNFOLDERID, dwFlags: DWORD, hToken: ?HANDLE, ppszPath: *[*]WCHAR) HRESULT;
4
std/os/windows/shlwapi.zig created+4
...@@ -0,0 +1,4 @@
1use @import("index.zig");
2
3pub extern "shlwapi" stdcallcc fn PathFileExistsA(pszPath: ?LPCTSTR) BOOL;
4
std/os/windows/user32.zig created+4
...@@ -0,0 +1,4 @@
1use @import("index.zig");
2
3pub extern "user32" stdcallcc fn MessageBoxA(hWnd: ?HANDLE, lpText: ?LPCTSTR, lpCaption: ?LPCTSTR, uType: UINT) c_int;
4