aboutsummaryrefslogtreecommitdiff
path: root/src/win
diff options
context:
space:
mode:
Diffstat (limited to 'src/win')
-rw-r--r--src/win/async.c20
-rw-r--r--src/win/atomicops-inl.h61
-rw-r--r--src/win/core.c91
-rw-r--r--src/win/fs.c25
-rw-r--r--src/win/handle-inl.h68
-rw-r--r--src/win/internal.h2
-rw-r--r--src/win/pipe.c3
-rw-r--r--src/win/req-inl.h23
-rw-r--r--src/win/udp.c7
-rw-r--r--src/win/util.c12
-rw-r--r--src/win/winapi.c99
-rw-r--r--src/win/winapi.h5
12 files changed, 219 insertions, 197 deletions
diff --git a/src/win/async.c b/src/win/async.c
index b904676e..4c2cd265 100644
--- a/src/win/async.c
+++ b/src/win/async.c
@@ -23,10 +23,28 @@
#include "uv.h"
#include "internal.h"
-#include "atomicops-inl.h"
#include "handle-inl.h"
#include "req-inl.h"
+#ifdef _MSC_VER /* MSVC */
+
+/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less
+ * efficient than InterlockedExchange, but InterlockedExchange8 does not exist,
+ * and interlocked operations on larger targets might require the target to be
+ * aligned. */
+#pragma intrinsic(_InterlockedOr8)
+
+static char uv__atomic_exchange_set(char volatile* target) {
+ return _InterlockedOr8(target, 1);
+}
+
+#else /* GCC, Clang in mingw mode */
+
+static char uv__atomic_exchange_set(char volatile* target) {
+ return __sync_fetch_and_or(target, 1);
+}
+
+#endif /* _MSC_VER */
void uv__async_endgame(uv_loop_t* loop, uv_async_t* handle) {
if (handle->flags & UV_HANDLE_CLOSING &&
diff --git a/src/win/atomicops-inl.h b/src/win/atomicops-inl.h
deleted file mode 100644
index 2f984c6d..00000000
--- a/src/win/atomicops-inl.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
- */
-
-#ifndef UV_WIN_ATOMICOPS_INL_H_
-#define UV_WIN_ATOMICOPS_INL_H_
-
-#include "uv.h"
-#include "internal.h"
-
-
-/* Atomic set operation on char */
-#ifdef _MSC_VER /* MSVC */
-
-/* _InterlockedOr8 is supported by MSVC on x32 and x64. It is slightly less
- * efficient than InterlockedExchange, but InterlockedExchange8 does not exist,
- * and interlocked operations on larger targets might require the target to be
- * aligned. */
-#pragma intrinsic(_InterlockedOr8)
-
-static char INLINE uv__atomic_exchange_set(char volatile* target) {
- return _InterlockedOr8(target, 1);
-}
-
-#else /* GCC, Clang in mingw mode */
-
-static inline char uv__atomic_exchange_set(char volatile* target) {
-#if defined(__i386__) || defined(__x86_64__)
- /* Mingw-32 version, hopefully this works for 64-bit gcc as well. */
- const char one = 1;
- char old_value;
- __asm__ __volatile__ ("lock xchgb %0, %1\n\t"
- : "=r"(old_value), "=m"(*target)
- : "0"(one), "m"(*target)
- : "memory");
- return old_value;
-#else
- return __sync_fetch_and_or(target, 1);
-#endif
-}
-
-#endif
-
-#endif /* UV_WIN_ATOMICOPS_INL_H_ */
diff --git a/src/win/core.c b/src/win/core.c
index ec50ec47..317238fd 100644
--- a/src/win/core.c
+++ b/src/win/core.c
@@ -629,6 +629,74 @@ static void uv__process_reqs(uv_loop_t* loop) {
#undef DELEGATE_STREAM_REQ
+static void uv__process_endgames(uv_loop_t* loop) {
+ uv_handle_t* handle;
+
+ while (loop->endgame_handles) {
+ handle = loop->endgame_handles;
+ loop->endgame_handles = handle->endgame_next;
+
+ handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
+
+ switch (handle->type) {
+ case UV_TCP:
+ uv__tcp_endgame(loop, (uv_tcp_t*) handle);
+ break;
+
+ case UV_NAMED_PIPE:
+ uv__pipe_endgame(loop, (uv_pipe_t*) handle);
+ break;
+
+ case UV_TTY:
+ uv__tty_endgame(loop, (uv_tty_t*) handle);
+ break;
+
+ case UV_UDP:
+ uv__udp_endgame(loop, (uv_udp_t*) handle);
+ break;
+
+ case UV_POLL:
+ uv__poll_endgame(loop, (uv_poll_t*) handle);
+ break;
+
+ case UV_TIMER:
+ uv__timer_close((uv_timer_t*) handle);
+ uv__handle_close(handle);
+ break;
+
+ case UV_PREPARE:
+ case UV_CHECK:
+ case UV_IDLE:
+ uv__loop_watcher_endgame(loop, handle);
+ break;
+
+ case UV_ASYNC:
+ uv__async_endgame(loop, (uv_async_t*) handle);
+ break;
+
+ case UV_SIGNAL:
+ uv__signal_endgame(loop, (uv_signal_t*) handle);
+ break;
+
+ case UV_PROCESS:
+ uv__process_endgame(loop, (uv_process_t*) handle);
+ break;
+
+ case UV_FS_EVENT:
+ uv__fs_event_endgame(loop, (uv_fs_event_t*) handle);
+ break;
+
+ case UV_FS_POLL:
+ uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle);
+ break;
+
+ default:
+ assert(0);
+ break;
+ }
+ }
+}
+
int uv_run(uv_loop_t *loop, uv_run_mode mode) {
DWORD timeout;
@@ -786,3 +854,26 @@ int uv__getsockpeername(const uv_handle_t* handle,
return 0;
}
+
+void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
+ req->next_req = NULL;
+ if (loop->pending_reqs_tail) {
+#ifdef _DEBUG
+ /* Ensure the request is not already in the queue, or the queue
+ * will get corrupted.
+ */
+ uv_req_t* current = loop->pending_reqs_tail;
+ do {
+ assert(req != current);
+ current = current->next_req;
+ } while (current != loop->pending_reqs_tail);
+#endif
+
+ req->next_req = loop->pending_reqs_tail->next_req;
+ loop->pending_reqs_tail->next_req = req;
+ loop->pending_reqs_tail = req;
+ } else {
+ req->next_req = req;
+ loop->pending_reqs_tail = req;
+ }
+}
diff --git a/src/win/fs.c b/src/win/fs.c
index 4e156930..cc2e8db9 100644
--- a/src/win/fs.c
+++ b/src/win/fs.c
@@ -1112,7 +1112,7 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
DWORD error;
handle = CreateFileW(pathw,
- FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE,
+ FILE_READ_ATTRIBUTES | DELETE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
@@ -1187,14 +1187,33 @@ static void fs__unlink_rmdir(uv_fs_t* req, BOOL isrmdir) {
/* Remove read-only attribute */
FILE_BASIC_INFORMATION basic = { 0 };
+ /* We opened the handle above without FILE_WRITE_ATTRIBUTES access, which
+ * is not required in the happy path. On windows, it would probably
+ * be ok to ask for them anyway, but Wine has a bug that causes such calls
+ * to fail (https://bugs.winehq.org/show_bug.cgi?id=50771). To work around
+ * this bug, we re-open the handle here */
+ HANDLE write_attributes_handle;
+
basic.FileAttributes = (info.dwFileAttributes & ~FILE_ATTRIBUTE_READONLY) |
FILE_ATTRIBUTE_ARCHIVE;
- status = pNtSetInformationFile(handle,
+ write_attributes_handle = ReOpenFile(handle, FILE_WRITE_ATTRIBUTES,
+ FILE_SHARE_READ | FILE_SHARE_WRITE |
+ FILE_SHARE_DELETE,
+ FILE_FLAG_OPEN_REPARSE_POINT |
+ FILE_FLAG_BACKUP_SEMANTICS);
+ if (write_attributes_handle == INVALID_HANDLE_VALUE) {
+ SET_REQ_WIN32_ERROR(req, GetLastError());
+ CloseHandle(handle);
+ return;
+ }
+
+ status = pNtSetInformationFile(write_attributes_handle,
&iosb,
&basic,
sizeof basic,
FileBasicInformation);
+ CloseHandle(write_attributes_handle);
if (!NT_SUCCESS(status)) {
SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status));
CloseHandle(handle);
@@ -1269,7 +1288,7 @@ void fs__mktemp(uv_fs_t* req, uv__fs_mktemp_func func) {
tries = TMP_MAX;
do {
- if (uv__random_rtlgenrandom((void *)&v, sizeof(v)) < 0) {
+ if (uv__random_winrandom(&v, sizeof(v)) < 0) {
SET_REQ_UV_ERROR(req, UV_EIO, ERROR_IO_DEVICE);
goto clobber;
}
diff --git a/src/win/handle-inl.h b/src/win/handle-inl.h
index 4722e857..e30d148c 100644
--- a/src/win/handle-inl.h
+++ b/src/win/handle-inl.h
@@ -95,74 +95,6 @@ INLINE static void uv__want_endgame(uv_loop_t* loop, uv_handle_t* handle) {
}
-INLINE static void uv__process_endgames(uv_loop_t* loop) {
- uv_handle_t* handle;
-
- while (loop->endgame_handles) {
- handle = loop->endgame_handles;
- loop->endgame_handles = handle->endgame_next;
-
- handle->flags &= ~UV_HANDLE_ENDGAME_QUEUED;
-
- switch (handle->type) {
- case UV_TCP:
- uv__tcp_endgame(loop, (uv_tcp_t*) handle);
- break;
-
- case UV_NAMED_PIPE:
- uv__pipe_endgame(loop, (uv_pipe_t*) handle);
- break;
-
- case UV_TTY:
- uv__tty_endgame(loop, (uv_tty_t*) handle);
- break;
-
- case UV_UDP:
- uv__udp_endgame(loop, (uv_udp_t*) handle);
- break;
-
- case UV_POLL:
- uv__poll_endgame(loop, (uv_poll_t*) handle);
- break;
-
- case UV_TIMER:
- uv__timer_close((uv_timer_t*) handle);
- uv__handle_close(handle);
- break;
-
- case UV_PREPARE:
- case UV_CHECK:
- case UV_IDLE:
- uv__loop_watcher_endgame(loop, handle);
- break;
-
- case UV_ASYNC:
- uv__async_endgame(loop, (uv_async_t*) handle);
- break;
-
- case UV_SIGNAL:
- uv__signal_endgame(loop, (uv_signal_t*) handle);
- break;
-
- case UV_PROCESS:
- uv__process_endgame(loop, (uv_process_t*) handle);
- break;
-
- case UV_FS_EVENT:
- uv__fs_event_endgame(loop, (uv_fs_event_t*) handle);
- break;
-
- case UV_FS_POLL:
- uv__fs_poll_endgame(loop, (uv_fs_poll_t*) handle);
- break;
-
- default:
- assert(0);
- break;
- }
- }
-}
-
INLINE static HANDLE uv__get_osfhandle(int fd)
{
/* _get_osfhandle() raises an assert in debug builds if the FD is invalid.
diff --git a/src/win/internal.h b/src/win/internal.h
index be408af6..db488be7 100644
--- a/src/win/internal.h
+++ b/src/win/internal.h
@@ -269,7 +269,7 @@ int uv__getsockpeername(const uv_handle_t* handle,
int* namelen,
int delayed_error);
-int uv__random_rtlgenrandom(void* buf, size_t buflen);
+int uv__random_winrandom(void* buf, size_t buflen);
/*
diff --git a/src/win/pipe.c b/src/win/pipe.c
index d05bfd28..8f86a1fe 100644
--- a/src/win/pipe.c
+++ b/src/win/pipe.c
@@ -2149,7 +2149,8 @@ void uv__process_pipe_read_req(uv_loop_t* loop,
} else {
/* The zero-read completed without error, indicating there is data
* available in the kernel buffer. */
- while (handle->flags & UV_HANDLE_READING) {
+ while (handle->flags & UV_HANDLE_READING &&
+ !(handle->flags & UV_HANDLE_READ_PENDING)) {
bytes_requested = 65536;
/* Depending on the type of pipe, read either IPC frames or raw data. */
if (handle->ipc)
diff --git a/src/win/req-inl.h b/src/win/req-inl.h
index c1ca8ea4..af6fb752 100644
--- a/src/win/req-inl.h
+++ b/src/win/req-inl.h
@@ -81,27 +81,6 @@
uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \
}
-INLINE static void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req) {
- req->next_req = NULL;
- if (loop->pending_reqs_tail) {
-#ifdef _DEBUG
- /* Ensure the request is not already in the queue, or the queue
- * will get corrupted.
- */
- uv_req_t* current = loop->pending_reqs_tail;
- do {
- assert(req != current);
- current = current->next_req;
- } while(current != loop->pending_reqs_tail);
-#endif
-
- req->next_req = loop->pending_reqs_tail->next_req;
- loop->pending_reqs_tail->next_req = req;
- loop->pending_reqs_tail = req;
- } else {
- req->next_req = req;
- loop->pending_reqs_tail = req;
- }
-}
+void uv__insert_pending_req(uv_loop_t* loop, uv_req_t* req);
#endif /* UV_WIN_REQ_INL_H_ */
diff --git a/src/win/udp.c b/src/win/udp.c
index e0873c2a..f8aa2435 100644
--- a/src/win/udp.c
+++ b/src/win/udp.c
@@ -1149,10 +1149,13 @@ int uv__udp_try_send2(uv_udp_t* handle,
uv_buf_t* bufs[/*count*/],
unsigned int nbufs[/*count*/],
struct sockaddr* addrs[/*count*/]) {
- unsigned int i;
+ int i;
int r;
- for (i = 0; i < count; i++) {
+ if (count > INT_MAX)
+ return UV_EINVAL;
+
+ for (i = 0; i < (int) count; i++) {
r = uv_udp_try_send(handle, bufs[i], nbufs[i], addrs[i]);
if (r < 0)
return i > 0 ? i : r; /* Error if first packet, else send count. */
diff --git a/src/win/util.c b/src/win/util.c
index 8c2681fe..9e3daac8 100644
--- a/src/win/util.c
+++ b/src/win/util.c
@@ -513,8 +513,8 @@ int uv_uptime(double* uptime) {
unsigned int uv_available_parallelism(void) {
DWORD_PTR procmask;
DWORD_PTR sysmask;
- int count;
- int i;
+ unsigned count;
+ unsigned i;
/* TODO(bnoordhuis) Use GetLogicalProcessorInformationEx() to support systems
* with > 64 CPUs? See https://github.com/libuv/libuv/pull/3458
@@ -1712,6 +1712,9 @@ int uv_os_uname(uv_utsname_t* buffer) {
case PROCESSOR_ARCHITECTURE_ARM:
uv__strscpy(buffer->machine, "arm", sizeof(buffer->machine));
break;
+ case PROCESSOR_ARCHITECTURE_ARM64:
+ uv__strscpy(buffer->machine, "arm64", sizeof(buffer->machine));
+ break;
default:
uv__strscpy(buffer->machine, "unknown", sizeof(buffer->machine));
break;
@@ -1744,10 +1747,13 @@ int uv_gettimeofday(uv_timeval64_t* tv) {
return 0;
}
-int uv__random_rtlgenrandom(void* buf, size_t buflen) {
+int uv__random_winrandom(void* buf, size_t buflen) {
if (buflen == 0)
return 0;
+ if (pProcessPrng != NULL && pProcessPrng(buf, buflen))
+ return 0;
+
if (SystemFunction036(buf, buflen) == FALSE)
return UV_EIO;
diff --git a/src/win/winapi.c b/src/win/winapi.c
index 786a9daa..7ed08dd2 100644
--- a/src/win/winapi.c
+++ b/src/win/winapi.c
@@ -39,6 +39,9 @@ sNtQueryInformationProcess pNtQueryInformationProcess;
/* Powrprof.dll function pointer */
sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
+/* bcryptprimitives.dll function pointer */
+sProcessPrng pProcessPrng;
+
/* User32.dll function pointer */
sSetWinEventHook pSetWinEventHook;
@@ -53,92 +56,118 @@ void uv__winapi_init(void) {
HMODULE powrprof_module;
HMODULE user32_module;
HMODULE ws2_32_module;
+ HMODULE bcryptprimitives_module;
HMODULE api_win_core_file_module;
+ union {
+ FARPROC proc;
+ sRtlGetVersion pRtlGetVersion;
+ sRtlNtStatusToDosError pRtlNtStatusToDosError;
+ sNtDeviceIoControlFile pNtDeviceIoControlFile;
+ sNtQueryInformationFile pNtQueryInformationFile;
+ sNtSetInformationFile pNtSetInformationFile;
+ sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile;
+ sNtQueryDirectoryFile pNtQueryDirectoryFile;
+ sNtQuerySystemInformation pNtQuerySystemInformation;
+ sNtQueryInformationProcess pNtQueryInformationProcess;
+ sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
+ sProcessPrng pProcessPrng;
+ sSetWinEventHook pSetWinEventHook;
+ uv_sGetHostNameW pGetHostNameW;
+ sGetFileInformationByName pGetFileInformationByName;
+ } u;
+
ntdll_module = GetModuleHandleW(L"ntdll.dll");
if (ntdll_module == NULL) {
uv_fatal_error(GetLastError(), "GetModuleHandleW");
}
- pRtlGetVersion = (sRtlGetVersion) GetProcAddress(ntdll_module,
- "RtlGetVersion");
+ u.proc = GetProcAddress(ntdll_module, "RtlGetVersion");
+ pRtlGetVersion = u.pRtlGetVersion;
- pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress(
- ntdll_module,
- "RtlNtStatusToDosError");
+ u.proc = GetProcAddress(ntdll_module, "RtlNtStatusToDosError");
+ pRtlNtStatusToDosError = u.pRtlNtStatusToDosError;
if (pRtlNtStatusToDosError == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
- pNtDeviceIoControlFile = (sNtDeviceIoControlFile) GetProcAddress(
- ntdll_module,
- "NtDeviceIoControlFile");
+ u.proc = GetProcAddress(ntdll_module, "NtDeviceIoControlFile");
+ pNtDeviceIoControlFile = u.pNtDeviceIoControlFile;
if (pNtDeviceIoControlFile == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
- pNtQueryInformationFile = (sNtQueryInformationFile) GetProcAddress(
- ntdll_module,
- "NtQueryInformationFile");
+ u.proc = GetProcAddress(ntdll_module, "NtQueryInformationFile");
+ pNtQueryInformationFile = u.pNtQueryInformationFile;
if (pNtQueryInformationFile == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
- pNtSetInformationFile = (sNtSetInformationFile) GetProcAddress(
- ntdll_module,
- "NtSetInformationFile");
+ u.proc = GetProcAddress(ntdll_module, "NtSetInformationFile");
+ pNtSetInformationFile = u.pNtSetInformationFile;
if (pNtSetInformationFile == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
- pNtQueryVolumeInformationFile = (sNtQueryVolumeInformationFile)
- GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile");
+ u.proc = GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile");
+ pNtQueryVolumeInformationFile = u.pNtQueryVolumeInformationFile;
if (pNtQueryVolumeInformationFile == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
- pNtQueryDirectoryFile = (sNtQueryDirectoryFile)
- GetProcAddress(ntdll_module, "NtQueryDirectoryFile");
+ u.proc = GetProcAddress(ntdll_module, "NtQueryDirectoryFile");
+ pNtQueryDirectoryFile = u.pNtQueryDirectoryFile;
if (pNtQueryDirectoryFile == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
- pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress(
- ntdll_module,
- "NtQuerySystemInformation");
+ u.proc = GetProcAddress(ntdll_module, "NtQuerySystemInformation");
+ pNtQuerySystemInformation = u.pNtQuerySystemInformation;
if (pNtQuerySystemInformation == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
- pNtQueryInformationProcess = (sNtQueryInformationProcess) GetProcAddress(
- ntdll_module,
- "NtQueryInformationProcess");
+ u.proc = GetProcAddress(ntdll_module, "NtQueryInformationProcess");
+ pNtQueryInformationProcess = u.pNtQueryInformationProcess;
if (pNtQueryInformationProcess == NULL) {
uv_fatal_error(GetLastError(), "GetProcAddress");
}
- powrprof_module = LoadLibraryExA("powrprof.dll", NULL, LOAD_LIBRARY_SEARCH_SYSTEM32);
+ powrprof_module = LoadLibraryExA("powrprof.dll",
+ NULL,
+ LOAD_LIBRARY_SEARCH_SYSTEM32);
if (powrprof_module != NULL) {
- pPowerRegisterSuspendResumeNotification = (sPowerRegisterSuspendResumeNotification)
- GetProcAddress(powrprof_module, "PowerRegisterSuspendResumeNotification");
+ u.proc = GetProcAddress(powrprof_module,
+ "PowerRegisterSuspendResumeNotification");
+ pPowerRegisterSuspendResumeNotification =
+ u.pPowerRegisterSuspendResumeNotification;
+ }
+
+ bcryptprimitives_module = LoadLibraryExA("bcryptprimitives.dll",
+ NULL,
+ LOAD_LIBRARY_SEARCH_SYSTEM32);
+ if (bcryptprimitives_module != NULL) {
+ u.proc = GetProcAddress(bcryptprimitives_module, "ProcessPrng");
+ pProcessPrng = u.pProcessPrng;
}
user32_module = GetModuleHandleW(L"user32.dll");
if (user32_module != NULL) {
- pSetWinEventHook = (sSetWinEventHook)
- GetProcAddress(user32_module, "SetWinEventHook");
+ u.proc = GetProcAddress(user32_module, "SetWinEventHook");
+ pSetWinEventHook = u.pSetWinEventHook;
}
ws2_32_module = GetModuleHandleW(L"ws2_32.dll");
if (ws2_32_module != NULL) {
- pGetHostNameW = (uv_sGetHostNameW) GetProcAddress(
- ws2_32_module,
- "GetHostNameW");
+ u.proc = GetProcAddress(ws2_32_module, "GetHostNameW");
+ pGetHostNameW = u.pGetHostNameW;
}
- api_win_core_file_module = GetModuleHandleW(L"api-ms-win-core-file-l2-1-4.dll");
+ api_win_core_file_module =
+ GetModuleHandleW(L"api-ms-win-core-file-l2-1-4.dll");
if (api_win_core_file_module != NULL) {
- pGetFileInformationByName = (sGetFileInformationByName)GetProcAddress(
- api_win_core_file_module, "GetFileInformationByName");
+ u.proc = GetProcAddress(api_win_core_file_module,
+ "GetFileInformationByName");
+ pGetFileInformationByName = u.pGetFileInformationByName;
}
}
diff --git a/src/win/winapi.h b/src/win/winapi.h
index b9c9f1ab..a7e1b179 100644
--- a/src/win/winapi.h
+++ b/src/win/winapi.h
@@ -4751,6 +4751,8 @@ typedef DWORD (WINAPI *sPowerRegisterSuspendResumeNotification)
HANDLE Recipient,
_PHPOWERNOTIFY RegistrationHandle);
+typedef BOOL (WINAPI *sProcessPrng)(/*_Out_*/PBYTE pbData, SIZE_T cbData);
+
/* from Winuser.h */
typedef VOID (CALLBACK* WINEVENTPROC)
(HWINEVENTHOOK hWinEventHook,
@@ -4815,6 +4817,9 @@ extern sNtQueryInformationProcess pNtQueryInformationProcess;
/* Powrprof.dll function pointer */
extern sPowerRegisterSuspendResumeNotification pPowerRegisterSuspendResumeNotification;
+/* bcryptprimitives.dll function pointer */
+extern sProcessPrng pProcessPrng;
+
/* User32.dll function pointer */
extern sSetWinEventHook pSetWinEventHook;