mirror of
https://github.com/ziglang/zig.git
synced 2026-01-04 20:43:19 +00:00
fixes for windows to build self hosted compiler
This commit is contained in:
parent
5de07ab721
commit
86bb7e5984
@ -13,9 +13,9 @@ pub use switch (builtin.os) {
|
||||
else => struct {},
|
||||
};
|
||||
|
||||
pub fn getErrno(rc: var) u12 {
|
||||
pub fn getErrno(rc: var) u16 {
|
||||
if (rc == -1) {
|
||||
return @intCast(u12, _errno().*);
|
||||
return @intCast(u16, _errno().*);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -412,7 +412,7 @@ pub const ChildProcess = struct {
|
||||
const any_ignore = (self.stdin_behavior == StdIo.Ignore or self.stdout_behavior == StdIo.Ignore or self.stderr_behavior == StdIo.Ignore);
|
||||
|
||||
const nul_handle = if (any_ignore) blk: {
|
||||
break :blk try windows.CreateFile("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL);
|
||||
break :blk try windows.CreateFile("NUL", windows.GENERIC_READ, windows.FILE_SHARE_READ, null, windows.OPEN_EXISTING, windows.FILE_ATTRIBUTE_NORMAL, null);
|
||||
} else blk: {
|
||||
break :blk undefined;
|
||||
};
|
||||
|
||||
@ -147,14 +147,14 @@ pub async fn pwriteWindows(loop: *Loop, fd: fd_t, data: []const u8, offset: u64)
|
||||
errdefer loop.finishOneEvent();
|
||||
|
||||
errdefer {
|
||||
_ = windows.CancelIoEx(fd, &resume_node.base.overlapped);
|
||||
_ = windows.kernel32.CancelIoEx(fd, &resume_node.base.overlapped);
|
||||
}
|
||||
suspend {
|
||||
_ = windows.WriteFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &resume_node.base.overlapped);
|
||||
_ = windows.kernel32.WriteFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &resume_node.base.overlapped);
|
||||
}
|
||||
var bytes_transferred: windows.DWORD = undefined;
|
||||
if (windows.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
|
||||
switch (windows.GetLastError()) {
|
||||
if (windows.kernel32.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
|
||||
switch (windows.kernel32.GetLastError()) {
|
||||
windows.ERROR.IO_PENDING => unreachable,
|
||||
windows.ERROR.INVALID_USER_BUFFER => return error.SystemResources,
|
||||
windows.ERROR.NOT_ENOUGH_MEMORY => return error.SystemResources,
|
||||
@ -247,7 +247,7 @@ pub async fn preadv(loop: *Loop, fd: fd_t, data: []const []u8, offset: usize) PR
|
||||
}
|
||||
|
||||
/// data must outlive the returned promise
|
||||
pub async fn preadvWindows(loop: *Loop, fd: fd_t, data: []const []u8, offset: u64) os.WindowsReadError!usize {
|
||||
pub async fn preadvWindows(loop: *Loop, fd: fd_t, data: []const []u8, offset: u64) !usize {
|
||||
assert(data.len != 0);
|
||||
if (data.len == 1) return await (async preadWindows(loop, fd, data[0], offset) catch unreachable);
|
||||
|
||||
@ -291,19 +291,19 @@ pub async fn preadWindows(loop: *Loop, fd: fd_t, data: []u8, offset: u64) !usize
|
||||
},
|
||||
};
|
||||
// TODO only call create io completion port once per fd
|
||||
_ = windows.CreateIoCompletionPort(fd, loop.os_data.io_port, undefined, undefined);
|
||||
_ = windows.CreateIoCompletionPort(fd, loop.os_data.io_port, undefined, undefined) catch undefined;
|
||||
loop.beginOneEvent();
|
||||
errdefer loop.finishOneEvent();
|
||||
|
||||
errdefer {
|
||||
_ = windows.CancelIoEx(fd, &resume_node.base.overlapped);
|
||||
_ = windows.kernel32.CancelIoEx(fd, &resume_node.base.overlapped);
|
||||
}
|
||||
suspend {
|
||||
_ = windows.ReadFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &resume_node.base.overlapped);
|
||||
_ = windows.kernel32.ReadFile(fd, data.ptr, @intCast(windows.DWORD, data.len), null, &resume_node.base.overlapped);
|
||||
}
|
||||
var bytes_transferred: windows.DWORD = undefined;
|
||||
if (windows.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
|
||||
switch (windows.GetLastError()) {
|
||||
if (windows.kernel32.GetOverlappedResult(fd, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
|
||||
switch (windows.kernel32.GetLastError()) {
|
||||
windows.ERROR.IO_PENDING => unreachable,
|
||||
windows.ERROR.OPERATION_ABORTED => return error.OperationAborted,
|
||||
windows.ERROR.BROKEN_PIPE => return error.BrokenPipe,
|
||||
@ -408,12 +408,14 @@ pub async fn openRead(loop: *Loop, path: []const u8) File.OpenError!fd_t {
|
||||
return await (async openPosix(loop, path, flags, File.default_mode) catch unreachable);
|
||||
},
|
||||
|
||||
builtin.Os.windows => return os.windowsOpen(
|
||||
builtin.Os.windows => return windows.CreateFile(
|
||||
path,
|
||||
windows.GENERIC_READ,
|
||||
windows.FILE_SHARE_READ,
|
||||
null,
|
||||
windows.OPEN_EXISTING,
|
||||
windows.FILE_ATTRIBUTE_NORMAL | windows.FILE_FLAG_OVERLAPPED,
|
||||
null,
|
||||
),
|
||||
|
||||
else => @compileError("Unsupported OS"),
|
||||
@ -437,12 +439,14 @@ pub async fn openWriteMode(loop: *Loop, path: []const u8, mode: File.Mode) File.
|
||||
const flags = os.O_LARGEFILE | os.O_WRONLY | os.O_CREAT | os.O_CLOEXEC | os.O_TRUNC;
|
||||
return await (async openPosix(loop, path, flags, File.default_mode) catch unreachable);
|
||||
},
|
||||
builtin.Os.windows => return os.windowsOpen(
|
||||
builtin.Os.windows => return windows.CreateFile(
|
||||
path,
|
||||
windows.GENERIC_WRITE,
|
||||
windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
|
||||
null,
|
||||
windows.CREATE_ALWAYS,
|
||||
windows.FILE_ATTRIBUTE_NORMAL | windows.FILE_FLAG_OVERLAPPED,
|
||||
null,
|
||||
),
|
||||
else => @compileError("Unsupported OS"),
|
||||
}
|
||||
@ -460,12 +464,14 @@ pub async fn openReadWrite(
|
||||
return await (async openPosix(loop, path, flags, mode) catch unreachable);
|
||||
},
|
||||
|
||||
builtin.Os.windows => return os.windowsOpen(
|
||||
builtin.Os.windows => return windows.CreateFile(
|
||||
path,
|
||||
windows.GENERIC_WRITE | windows.GENERIC_READ,
|
||||
windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
|
||||
null,
|
||||
windows.OPEN_ALWAYS,
|
||||
windows.FILE_ATTRIBUTE_NORMAL | windows.FILE_FLAG_OVERLAPPED,
|
||||
null,
|
||||
),
|
||||
|
||||
else => @compileError("Unsupported OS"),
|
||||
@ -622,12 +628,14 @@ pub async fn writeFileMode(loop: *Loop, path: []const u8, contents: []const u8,
|
||||
}
|
||||
|
||||
async fn writeFileWindows(loop: *Loop, path: []const u8, contents: []const u8) !void {
|
||||
const handle = try os.windowsOpen(
|
||||
const handle = try windows.CreateFile(
|
||||
path,
|
||||
windows.GENERIC_WRITE,
|
||||
windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
|
||||
null,
|
||||
windows.CREATE_ALWAYS,
|
||||
windows.FILE_ATTRIBUTE_NORMAL | windows.FILE_FLAG_OVERLAPPED,
|
||||
null,
|
||||
);
|
||||
defer os.close(handle);
|
||||
|
||||
@ -1028,7 +1036,7 @@ pub fn Watch(comptime V: type) type {
|
||||
defer if (!basename_utf16le_null_consumed) self.channel.loop.allocator.free(basename_utf16le_null);
|
||||
const basename_utf16le_no_null = basename_utf16le_null[0 .. basename_utf16le_null.len - 1];
|
||||
|
||||
const dir_handle = windows.CreateFileW(
|
||||
const dir_handle = try windows.CreateFileW(
|
||||
dirname_utf16le.ptr,
|
||||
windows.FILE_LIST_DIRECTORY,
|
||||
windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE | windows.FILE_SHARE_WRITE,
|
||||
@ -1037,15 +1045,8 @@ pub fn Watch(comptime V: type) type {
|
||||
windows.FILE_FLAG_BACKUP_SEMANTICS | windows.FILE_FLAG_OVERLAPPED,
|
||||
null,
|
||||
);
|
||||
if (dir_handle == windows.INVALID_HANDLE_VALUE) {
|
||||
switch (windows.GetLastError()) {
|
||||
windows.ERROR.FILE_NOT_FOUND => return error.FileNotFound,
|
||||
windows.ERROR.PATH_NOT_FOUND => return error.FileNotFound,
|
||||
else => |err| return windows.unexpectedError(err),
|
||||
}
|
||||
}
|
||||
var dir_handle_consumed = false;
|
||||
defer if (!dir_handle_consumed) os.close(dir_handle);
|
||||
defer if (!dir_handle_consumed) windows.CloseHandle(dir_handle);
|
||||
|
||||
const held = await (async self.os_data.table_lock.acquire() catch unreachable);
|
||||
defer held.release();
|
||||
@ -1124,7 +1125,7 @@ pub fn Watch(comptime V: type) type {
|
||||
var event_buf: [4096]u8 align(@alignOf(windows.FILE_NOTIFY_INFORMATION)) = undefined;
|
||||
|
||||
// TODO handle this error not in the channel but in the setup
|
||||
_ = os.windowsCreateIoCompletionPort(
|
||||
_ = windows.CreateIoCompletionPort(
|
||||
dir_handle,
|
||||
self.channel.loop.os_data.io_port,
|
||||
undefined,
|
||||
@ -1140,10 +1141,10 @@ pub fn Watch(comptime V: type) type {
|
||||
self.channel.loop.beginOneEvent();
|
||||
errdefer self.channel.loop.finishOneEvent();
|
||||
errdefer {
|
||||
_ = windows.CancelIoEx(dir_handle, &resume_node.base.overlapped);
|
||||
_ = windows.kernel32.CancelIoEx(dir_handle, &resume_node.base.overlapped);
|
||||
}
|
||||
suspend {
|
||||
_ = windows.ReadDirectoryChangesW(
|
||||
_ = windows.kernel32.ReadDirectoryChangesW(
|
||||
dir_handle,
|
||||
&event_buf,
|
||||
@intCast(windows.DWORD, event_buf.len),
|
||||
@ -1159,8 +1160,8 @@ pub fn Watch(comptime V: type) type {
|
||||
}
|
||||
}
|
||||
var bytes_transferred: windows.DWORD = undefined;
|
||||
if (windows.GetOverlappedResult(dir_handle, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
|
||||
const err = switch (windows.GetLastError()) {
|
||||
if (windows.kernel32.GetOverlappedResult(dir_handle, &resume_node.base.overlapped, &bytes_transferred, windows.FALSE) == 0) {
|
||||
const err = switch (windows.kernel32.GetLastError()) {
|
||||
else => |err| windows.unexpectedError(err),
|
||||
};
|
||||
await (async self.channel.put(err) catch unreachable);
|
||||
|
||||
@ -27,7 +27,7 @@ pub const File = struct {
|
||||
|
||||
/// Call close to clean up.
|
||||
pub fn openRead(path: []const u8) OpenError!File {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
const path_w = try windows.sliceToPrefixedFileW(path);
|
||||
return openReadW(&path_w);
|
||||
}
|
||||
@ -37,7 +37,7 @@ pub const File = struct {
|
||||
|
||||
/// `openRead` except with a null terminated path
|
||||
pub fn openReadC(path: [*]const u8) OpenError!File {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
const path_w = try windows.cStrToPrefixedFileW(path);
|
||||
return openReadW(&path_w);
|
||||
}
|
||||
@ -52,8 +52,10 @@ pub const File = struct {
|
||||
path_w,
|
||||
windows.GENERIC_READ,
|
||||
windows.FILE_SHARE_READ,
|
||||
null,
|
||||
windows.OPEN_EXISTING,
|
||||
windows.FILE_ATTRIBUTE_NORMAL,
|
||||
null,
|
||||
);
|
||||
return openHandle(handle);
|
||||
}
|
||||
@ -67,7 +69,7 @@ pub const File = struct {
|
||||
/// If a file already exists in the destination it will be truncated.
|
||||
/// Call close to clean up.
|
||||
pub fn openWriteMode(path: []const u8, file_mode: Mode) OpenError!File {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
const path_w = try windows.sliceToPrefixedFileW(path);
|
||||
return openWriteModeW(&path_w, file_mode);
|
||||
}
|
||||
@ -77,7 +79,7 @@ pub const File = struct {
|
||||
|
||||
/// Same as `openWriteMode` except `path` is null-terminated.
|
||||
pub fn openWriteModeC(path: [*]const u8, file_mode: Mode) OpenError!File {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
const path_w = try windows.cStrToPrefixedFileW(path);
|
||||
return openWriteModeW(&path_w, file_mode);
|
||||
}
|
||||
@ -92,8 +94,10 @@ pub const File = struct {
|
||||
path_w,
|
||||
windows.GENERIC_WRITE,
|
||||
windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
|
||||
null,
|
||||
windows.CREATE_ALWAYS,
|
||||
windows.FILE_ATTRIBUTE_NORMAL,
|
||||
null,
|
||||
);
|
||||
return openHandle(handle);
|
||||
}
|
||||
@ -102,7 +106,7 @@ pub const File = struct {
|
||||
/// If a file already exists in the destination this returns OpenError.PathAlreadyExists
|
||||
/// Call close to clean up.
|
||||
pub fn openWriteNoClobber(path: []const u8, file_mode: Mode) OpenError!File {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
const path_w = try windows.sliceToPrefixedFileW(path);
|
||||
return openWriteNoClobberW(&path_w, file_mode);
|
||||
}
|
||||
@ -111,7 +115,7 @@ pub const File = struct {
|
||||
}
|
||||
|
||||
pub fn openWriteNoClobberC(path: [*]const u8, file_mode: Mode) OpenError!File {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
const path_w = try windows.cStrToPrefixedFileW(path);
|
||||
return openWriteNoClobberW(&path_w, file_mode);
|
||||
}
|
||||
@ -125,8 +129,10 @@ pub const File = struct {
|
||||
path_w,
|
||||
windows.GENERIC_WRITE,
|
||||
windows.FILE_SHARE_WRITE | windows.FILE_SHARE_READ | windows.FILE_SHARE_DELETE,
|
||||
null,
|
||||
windows.CREATE_NEW,
|
||||
windows.FILE_ATTRIBUTE_NORMAL,
|
||||
null,
|
||||
);
|
||||
return openHandle(handle);
|
||||
}
|
||||
@ -198,7 +204,7 @@ pub const File = struct {
|
||||
}
|
||||
|
||||
pub fn getEndPos(self: File) GetPosError!u64 {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
return windows.GetFileSizeEx(self.handle);
|
||||
}
|
||||
const stat = try os.fstat(self.handle);
|
||||
@ -208,7 +214,7 @@ pub const File = struct {
|
||||
pub const ModeError = os.FStatError;
|
||||
|
||||
pub fn mode(self: File) ModeError!Mode {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
return {};
|
||||
}
|
||||
const stat = try os.fstat(self.handle);
|
||||
|
||||
16
std/os.zig
16
std/os.zig
@ -70,7 +70,7 @@ pub const errno = system.getErrno;
|
||||
/// must call `fsync` before `close`.
|
||||
/// Note: The Zig standard library does not support POSIX thread cancellation.
|
||||
pub fn close(fd: fd_t) void {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
return windows.CloseHandle(fd);
|
||||
}
|
||||
if (wasi.is_the_target) {
|
||||
@ -236,7 +236,7 @@ pub const ReadError = error{
|
||||
/// This function is for blocking file descriptors only. For non-blocking, see
|
||||
/// `readAsync`.
|
||||
pub fn read(fd: fd_t, buf: []u8) ReadError!usize {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
return windows.ReadFile(fd, buf);
|
||||
}
|
||||
|
||||
@ -363,7 +363,7 @@ pub const WriteError = error{
|
||||
/// This function is for blocking file descriptors only. For non-blocking, see
|
||||
/// `writeAsync`.
|
||||
pub fn write(fd: fd_t, bytes: []const u8) WriteError!void {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
return windows.WriteFile(fd, bytes);
|
||||
}
|
||||
|
||||
@ -1736,7 +1736,7 @@ pub const FStatError = error{
|
||||
pub fn fstat(fd: fd_t) FStatError!Stat {
|
||||
var stat: Stat = undefined;
|
||||
if (darwin.is_the_target) {
|
||||
switch (errno(system.@"fstat$INODE64"(fd, &stat))) {
|
||||
switch (darwin.getErrno(darwin.@"fstat$INODE64"(fd, &stat))) {
|
||||
0 => return stat,
|
||||
EBADF => unreachable, // Always a race condition.
|
||||
ENOMEM => return error.SystemResources,
|
||||
@ -2265,7 +2265,7 @@ pub const RealPathError = error{
|
||||
/// The return value is a slice of `out_buffer`, but not necessarily from the beginning.
|
||||
/// See also `realpathC` and `realpathW`.
|
||||
pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
const pathname_w = try windows.sliceToPrefixedFileW(pathname);
|
||||
return realpathW(&pathname_w, out_buffer);
|
||||
}
|
||||
@ -2275,12 +2275,12 @@ pub fn realpath(pathname: []const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathE
|
||||
|
||||
/// Same as `realpath` except `pathname` is null-terminated.
|
||||
pub fn realpathC(pathname: [*]const u8, out_buffer: *[MAX_PATH_BYTES]u8) RealPathError![]u8 {
|
||||
if (windows.is_the_target and !builtin.link_libc) {
|
||||
if (windows.is_the_target) {
|
||||
const pathname_w = try windows.cStrToPrefixedFileW(pathname);
|
||||
return realpathW(&pathname_w, out_buffer);
|
||||
}
|
||||
if (linux.is_the_target and !builtin.link_libc) {
|
||||
const fd = try openC(pathname, O_PATH | O_NONBLOCK | O_CLOEXEC, 0);
|
||||
const fd = try openC(pathname, linux.O_PATH | linux.O_NONBLOCK | linux.O_CLOEXEC, 0);
|
||||
defer close(fd);
|
||||
|
||||
var procfs_buf: ["/proc/self/fd/-2147483648\x00".len]u8 = undefined;
|
||||
@ -2310,8 +2310,10 @@ pub fn realpathW(pathname: [*]const u16, out_buffer: *[MAX_PATH_BYTES]u8) RealPa
|
||||
pathname,
|
||||
windows.GENERIC_READ,
|
||||
windows.FILE_SHARE_READ,
|
||||
null,
|
||||
windows.OPEN_EXISTING,
|
||||
windows.FILE_ATTRIBUTE_NORMAL,
|
||||
null,
|
||||
);
|
||||
defer windows.CloseHandle(h_file);
|
||||
|
||||
|
||||
@ -5,6 +5,8 @@ use @import("../windows/bits.zig");
|
||||
pub const fd_t = HANDLE;
|
||||
pub const pid_t = HANDLE;
|
||||
|
||||
pub const PATH_MAX = 260;
|
||||
|
||||
pub const time_t = c_longlong;
|
||||
|
||||
pub const timespec = extern struct {
|
||||
@ -153,10 +155,13 @@ pub const ETIME = 137;
|
||||
pub const ETIMEDOUT = 138;
|
||||
pub const ETXTBSY = 139;
|
||||
pub const EWOULDBLOCK = 140;
|
||||
pub const EDQUOT = 10069;
|
||||
|
||||
pub const F_OK = 0;
|
||||
|
||||
// These are workarounds for "use of undeclared identifier" compile errors
|
||||
// TODO make the compiler even more lazy. don't emit "use of undeclared identifier" errors
|
||||
// for if branches that aren't taken.
|
||||
pub const SIGKILL = @compileError("Windows libc does not have this");
|
||||
pub const EDQUOT = @compileError("Windows libc does not have this");
|
||||
pub const F_OK = 0;
|
||||
|
||||
|
||||
|
||||
@ -48,21 +48,25 @@ pub fn CreateFile(
|
||||
file_path: []const u8,
|
||||
desired_access: DWORD,
|
||||
share_mode: DWORD,
|
||||
lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES,
|
||||
creation_disposition: DWORD,
|
||||
flags_and_attrs: DWORD,
|
||||
hTemplateFile: ?HANDLE,
|
||||
) CreateFileError!HANDLE {
|
||||
const file_path_w = try sliceToPrefixedFileW(file_path);
|
||||
return CreateFileW(&file_path_w, desired_access, share_mode, creation_disposition, flags_and_attrs);
|
||||
return CreateFileW(&file_path_w, desired_access, share_mode, lpSecurityAttributes, creation_disposition, flags_and_attrs, hTemplateFile);
|
||||
}
|
||||
|
||||
pub fn CreateFileW(
|
||||
file_path_w: [*]const u16,
|
||||
desired_access: DWORD,
|
||||
share_mode: DWORD,
|
||||
lpSecurityAttributes: ?LPSECURITY_ATTRIBUTES,
|
||||
creation_disposition: DWORD,
|
||||
flags_and_attrs: DWORD,
|
||||
hTemplateFile: ?HANDLE,
|
||||
) CreateFileError!HANDLE {
|
||||
const result = kernel32.CreateFileW(file_path_w, desired_access, share_mode, null, creation_disposition, flags_and_attrs, null);
|
||||
const result = kernel32.CreateFileW(file_path_w, desired_access, share_mode, lpSecurityAttributes, creation_disposition, flags_and_attrs, hTemplateFile);
|
||||
|
||||
if (result == INVALID_HANDLE_VALUE) {
|
||||
switch (kernel32.GetLastError()) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user