aboutsummaryrefslogtreecommitdiff
path: root/std/os/windows/util.zig
diff options
context:
space:
mode:
authorAndrea Orru <andrea@orru.io>2018-08-06 01:43:19 -0400
committerAndrea Orru <andrea@orru.io>2018-08-06 01:43:19 -0400
commitd2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d (patch)
treee9fa3caec533a0d1e2b434868b2fde1f9240e5c8 /std/os/windows/util.zig
parent06614b3fa09954464c2e2f32756cacedc178a282 (diff)
parent63a23e848a62d5f167f8d5478de9766cb24aa6eb (diff)
downloadzig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.tar.gz
zig-d2f5e57b68da0b16e5789ca19045ccbcb4ecfa8d.zip
Merge branch 'master' into zen_stdlib
Diffstat (limited to 'std/os/windows/util.zig')
-rw-r--r--std/os/windows/util.zig135
1 files changed, 110 insertions, 25 deletions
diff --git a/std/os/windows/util.zig b/std/os/windows/util.zig
index 5af318b7b0..c9d2c3c3e6 100644
--- a/std/os/windows/util.zig
+++ b/std/os/windows/util.zig
@@ -7,7 +7,7 @@ const mem = std.mem;
const BufMap = std.BufMap;
const cstr = std.cstr;
-pub const WaitError = error {
+pub const WaitError = error{
WaitAbandoned,
WaitTimeOut,
Unexpected,
@@ -33,7 +33,7 @@ pub fn windowsClose(handle: windows.HANDLE) void {
assert(windows.CloseHandle(handle) != 0);
}
-pub const WriteError = error {
+pub const WriteError = error{
SystemResources,
OperationAborted,
IoPending,
@@ -42,7 +42,7 @@ pub const WriteError = error {
};
pub fn windowsWrite(handle: windows.HANDLE, bytes: []const u8) WriteError!void {
- if (windows.WriteFile(handle, @ptrCast(&const c_void, bytes.ptr), u32(bytes.len), null, null) == 0) {
+ if (windows.WriteFile(handle, @ptrCast(*const c_void, bytes.ptr), @intCast(u32, bytes.len), null, null) == 0) {
const err = windows.GetLastError();
return switch (err) {
windows.ERROR.INVALID_USER_BUFFER => WriteError.SystemResources,
@@ -68,20 +68,23 @@ pub fn windowsIsCygwinPty(handle: windows.HANDLE) bool {
const size = @sizeOf(windows.FILE_NAME_INFO);
var name_info_bytes align(@alignOf(windows.FILE_NAME_INFO)) = []u8{0} ** (size + windows.MAX_PATH);
- if (windows.GetFileInformationByHandleEx(handle, windows.FileNameInfo,
- @ptrCast(&c_void, &name_info_bytes[0]), u32(name_info_bytes.len)) == 0)
- {
+ if (windows.GetFileInformationByHandleEx(
+ handle,
+ windows.FileNameInfo,
+ @ptrCast(*c_void, &name_info_bytes[0]),
+ @intCast(u32, name_info_bytes.len),
+ ) == 0) {
return true;
}
- const name_info = @ptrCast(&const windows.FILE_NAME_INFO, &name_info_bytes[0]);
- const name_bytes = name_info_bytes[size..size + usize(name_info.FileNameLength)];
- const name_wide = ([]u16)(name_bytes);
- return mem.indexOf(u16, name_wide, []u16{'m','s','y','s','-'}) != null or
- mem.indexOf(u16, name_wide, []u16{'-','p','t','y'}) != null;
+ const name_info = @ptrCast(*const windows.FILE_NAME_INFO, &name_info_bytes[0]);
+ const name_bytes = name_info_bytes[size .. size + usize(name_info.FileNameLength)];
+ const name_wide = @bytesToSlice(u16, name_bytes);
+ return mem.indexOf(u16, name_wide, []u16{ 'm', 's', 'y', 's', '-' }) != null or
+ mem.indexOf(u16, name_wide, []u16{ '-', 'p', 't', 'y' }) != null;
}
-pub const OpenError = error {
+pub const OpenError = error{
SharingViolation,
PathAlreadyExists,
FileNotFound,
@@ -92,15 +95,18 @@ pub const OpenError = error {
};
/// `file_path` needs to be copied in memory to add a null terminating byte, hence the allocator.
-pub fn windowsOpen(allocator: &mem.Allocator, file_path: []const u8, desired_access: windows.DWORD, share_mode: windows.DWORD,
- creation_disposition: windows.DWORD, flags_and_attrs: windows.DWORD)
- OpenError!windows.HANDLE
-{
+pub fn windowsOpen(
+ allocator: *mem.Allocator,
+ file_path: []const u8,
+ desired_access: windows.DWORD,
+ share_mode: windows.DWORD,
+ creation_disposition: windows.DWORD,
+ flags_and_attrs: windows.DWORD,
+) OpenError!windows.HANDLE {
const path_with_null = try cstr.addNullByte(allocator, file_path);
defer allocator.free(path_with_null);
- const result = windows.CreateFileA(path_with_null.ptr, desired_access, share_mode, null, creation_disposition,
- flags_and_attrs, null);
+ const result = windows.CreateFileA(path_with_null.ptr, desired_access, share_mode, null, creation_disposition, flags_and_attrs, null);
if (result == windows.INVALID_HANDLE_VALUE) {
const err = windows.GetLastError();
@@ -118,7 +124,7 @@ pub fn windowsOpen(allocator: &mem.Allocator, file_path: []const u8, desired_acc
}
/// Caller must free result.
-pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap) ![]u8 {
+pub fn createWindowsEnvBlock(allocator: *mem.Allocator, env_map: *const BufMap) ![]u8 {
// count bytes needed
const bytes_needed = x: {
var bytes_needed: usize = 1; // 1 for the final null byte
@@ -149,25 +155,104 @@ pub fn createWindowsEnvBlock(allocator: &mem.Allocator, env_map: &const BufMap)
return result;
}
-pub fn windowsLoadDll(allocator: &mem.Allocator, dll_path: []const u8) !windows.HMODULE {
+pub fn windowsLoadDll(allocator: *mem.Allocator, dll_path: []const u8) !windows.HMODULE {
const padded_buff = try cstr.addNullByte(allocator, dll_path);
defer allocator.free(padded_buff);
- return windows.LoadLibraryA(padded_buff.ptr) ?? error.DllNotFound;
+ return windows.LoadLibraryA(padded_buff.ptr) orelse error.DllNotFound;
}
pub fn windowsUnloadDll(hModule: windows.HMODULE) void {
- assert(windows.FreeLibrary(hModule)!= 0);
+ assert(windows.FreeLibrary(hModule) != 0);
}
-
test "InvalidDll" {
- if (builtin.os != builtin.Os.windows) return;
+ if (builtin.os != builtin.Os.windows) return error.SkipZigTest;
const DllName = "asdf.dll";
const allocator = std.debug.global_allocator;
- const handle = os.windowsLoadDll(allocator, DllName) catch |err| {
+ const handle = os.windowsLoadDll(allocator, DllName) catch |err| {
assert(err == error.DllNotFound);
return;
};
}
+pub fn windowsFindFirstFile(
+ allocator: *mem.Allocator,
+ dir_path: []const u8,
+ find_file_data: *windows.WIN32_FIND_DATAA,
+) !windows.HANDLE {
+ const wild_and_null = []u8{ '\\', '*', 0 };
+ const path_with_wild_and_null = try allocator.alloc(u8, dir_path.len + wild_and_null.len);
+ defer allocator.free(path_with_wild_and_null);
+
+ mem.copy(u8, path_with_wild_and_null, dir_path);
+ mem.copy(u8, path_with_wild_and_null[dir_path.len..], wild_and_null);
+
+ const handle = windows.FindFirstFileA(path_with_wild_and_null.ptr, find_file_data);
+
+ if (handle == windows.INVALID_HANDLE_VALUE) {
+ const err = windows.GetLastError();
+ switch (err) {
+ windows.ERROR.FILE_NOT_FOUND,
+ windows.ERROR.PATH_NOT_FOUND,
+ => return error.PathNotFound,
+ else => return os.unexpectedErrorWindows(err),
+ }
+ }
+
+ return handle;
+}
+
+/// Returns `true` if there was another file, `false` otherwise.
+pub fn windowsFindNextFile(handle: windows.HANDLE, find_file_data: *windows.WIN32_FIND_DATAA) !bool {
+ if (windows.FindNextFileA(handle, find_file_data) == 0) {
+ const err = windows.GetLastError();
+ return switch (err) {
+ windows.ERROR.NO_MORE_FILES => false,
+ else => os.unexpectedErrorWindows(err),
+ };
+ }
+ return true;
+}
+
+pub const WindowsCreateIoCompletionPortError = error{Unexpected};
+
+pub fn windowsCreateIoCompletionPort(file_handle: windows.HANDLE, existing_completion_port: ?windows.HANDLE, completion_key: usize, concurrent_thread_count: windows.DWORD) !windows.HANDLE {
+ const handle = windows.CreateIoCompletionPort(file_handle, existing_completion_port, completion_key, concurrent_thread_count) orelse {
+ const err = windows.GetLastError();
+ switch (err) {
+ else => return os.unexpectedErrorWindows(err),
+ }
+ };
+ return handle;
+}
+
+pub const WindowsPostQueuedCompletionStatusError = error{Unexpected};
+
+pub fn windowsPostQueuedCompletionStatus(completion_port: windows.HANDLE, bytes_transferred_count: windows.DWORD, completion_key: usize, lpOverlapped: ?*windows.OVERLAPPED) WindowsPostQueuedCompletionStatusError!void {
+ if (windows.PostQueuedCompletionStatus(completion_port, bytes_transferred_count, completion_key, lpOverlapped) == 0) {
+ const err = windows.GetLastError();
+ switch (err) {
+ else => return os.unexpectedErrorWindows(err),
+ }
+ }
+}
+
+pub const WindowsWaitResult = error{
+ Normal,
+ Aborted,
+};
+
+pub fn windowsGetQueuedCompletionStatus(completion_port: windows.HANDLE, bytes_transferred_count: *windows.DWORD, lpCompletionKey: *usize, lpOverlapped: *?*windows.OVERLAPPED, dwMilliseconds: windows.DWORD) WindowsWaitResult {
+ if (windows.GetQueuedCompletionStatus(completion_port, bytes_transferred_count, lpCompletionKey, lpOverlapped, dwMilliseconds) == windows.FALSE) {
+ if (std.debug.runtime_safety) {
+ const err = windows.GetLastError();
+ if (err != windows.ERROR.ABANDONED_WAIT_0) {
+ std.debug.warn("err: {}\n", err);
+ }
+ assert(err == windows.ERROR.ABANDONED_WAIT_0);
+ }
+ return WindowsWaitResult.Aborted;
+ }
+ return WindowsWaitResult.Normal;
+}