diff options
Diffstat (limited to '3rdparty/libuv/src/win')
33 files changed, 0 insertions, 23219 deletions
diff --git a/3rdparty/libuv/src/win/async.c b/3rdparty/libuv/src/win/async.c deleted file mode 100644 index ad240ab8972..00000000000 --- a/3rdparty/libuv/src/win/async.c +++ /dev/null @@ -1,99 +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. - */ - -#include <assert.h> - -#include "uv.h" -#include "internal.h" -#include "atomicops-inl.h" -#include "handle-inl.h" -#include "req-inl.h" - - -void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING && - !handle->async_sent) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) { - uv_req_t* req; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_ASYNC); - handle->async_sent = 0; - handle->async_cb = async_cb; - - req = &handle->async_req; - uv_req_init(loop, req); - req->type = UV_WAKEUP; - req->data = handle; - - uv__handle_start(handle); - - return 0; -} - - -void uv_async_close(uv_loop_t* loop, uv_async_t* handle) { - if (!((uv_async_t*)handle)->async_sent) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - - uv__handle_closing(handle); -} - - -int uv_async_send(uv_async_t* handle) { - uv_loop_t* loop = handle->loop; - - if (handle->type != UV_ASYNC) { - /* Can't set errno because that's not thread-safe. */ - return -1; - } - - /* The user should make sure never to call uv_async_send to a closing */ - /* or closed handle. */ - assert(!(handle->flags & UV__HANDLE_CLOSING)); - - if (!uv__atomic_exchange_set(&handle->async_sent)) { - POST_COMPLETION_FOR_REQ(loop, &handle->async_req); - } - - return 0; -} - - -void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, - uv_req_t* req) { - assert(handle->type == UV_ASYNC); - assert(req->type == UV_WAKEUP); - - handle->async_sent = 0; - - if (handle->flags & UV__HANDLE_CLOSING) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } else if (handle->async_cb != NULL) { - handle->async_cb(handle); - } -} diff --git a/3rdparty/libuv/src/win/atomicops-inl.h b/3rdparty/libuv/src/win/atomicops-inl.h deleted file mode 100644 index 61e006026c1..00000000000 --- a/3rdparty/libuv/src/win/atomicops-inl.h +++ /dev/null @@ -1,56 +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" - - -/* 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 __declspec(inline) uv__atomic_exchange_set(char volatile* target) { - return _InterlockedOr8(target, 1); -} - -#else /* GCC */ - -/* Mingw-32 version, hopefully this works for 64-bit gcc as well. */ -static inline char uv__atomic_exchange_set(char volatile* target) { - 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; -} - -#endif - -#endif /* UV_WIN_ATOMICOPS_INL_H_ */ diff --git a/3rdparty/libuv/src/win/core.c b/3rdparty/libuv/src/win/core.c deleted file mode 100644 index ba306ebc083..00000000000 --- a/3rdparty/libuv/src/win/core.c +++ /dev/null @@ -1,493 +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. - */ - -#include <assert.h> -#include <errno.h> -#include <limits.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR) -#include <crtdbg.h> -#endif - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -static uv_loop_t default_loop_struct; -static uv_loop_t* default_loop_ptr; - -/* uv_once initialization guards */ -static uv_once_t uv_init_guard_ = UV_ONCE_INIT; - - -#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)) -/* Our crt debug report handler allows us to temporarily disable asserts - * just for the current thread. - */ - -UV_THREAD_LOCAL int uv__crt_assert_enabled = TRUE; - -static int uv__crt_dbg_report_handler(int report_type, char *message, int *ret_val) { - if (uv__crt_assert_enabled || report_type != _CRT_ASSERT) - return FALSE; - - if (ret_val) { - /* Set ret_val to 0 to continue with normal execution. - * Set ret_val to 1 to trigger a breakpoint. - */ - - if(IsDebuggerPresent()) - *ret_val = 1; - else - *ret_val = 0; - } - - /* Don't call _CrtDbgReport. */ - return TRUE; -} -#else -UV_THREAD_LOCAL int uv__crt_assert_enabled = FALSE; -#endif - - -#if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800 -static void uv__crt_invalid_parameter_handler(const wchar_t* expression, - const wchar_t* function, const wchar_t * file, unsigned int line, - uintptr_t reserved) { - /* No-op. */ -} -#endif - - -static void uv_init(void) { - /* Tell Windows that we will handle critical errors. */ - SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | - SEM_NOOPENFILEERRORBOX); - - /* Tell the CRT to not exit the application when an invalid parameter is - * passed. The main issue is that invalid FDs will trigger this behavior. - */ -#if !defined(__MINGW32__) || __MSVCRT_VERSION__ >= 0x800 - _set_invalid_parameter_handler(uv__crt_invalid_parameter_handler); -#endif - - /* We also need to setup our debug report handler because some CRT - * functions (eg _get_osfhandle) raise an assert when called with invalid - * FDs even though they return the proper error code in the release build. - */ -#if defined(_DEBUG) && (defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR)) - _CrtSetReportHook(uv__crt_dbg_report_handler); -#endif - - /* Fetch winapi function pointers. This must be done first because other - * initialization code might need these function pointers to be loaded. - */ - uv_winapi_init(); - - /* Initialize winsock */ - uv_winsock_init(); - - /* Initialize FS */ - uv_fs_init(); - - /* Initialize signal stuff */ - uv_signals_init(); - - /* Initialize console */ - uv_console_init(); - - /* Initialize utilities */ - uv__util_init(); -} - - -int uv_loop_init(uv_loop_t* loop) { - int err; - - /* Initialize libuv itself first */ - uv__once_init(); - - /* Create an I/O completion port */ - loop->iocp = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 1); - if (loop->iocp == NULL) - return uv_translate_sys_error(GetLastError()); - - /* To prevent uninitialized memory access, loop->time must be initialized - * to zero before calling uv_update_time for the first time. - */ - loop->time = 0; - uv_update_time(loop); - - QUEUE_INIT(&loop->wq); - QUEUE_INIT(&loop->handle_queue); - QUEUE_INIT(&loop->active_reqs); - loop->active_handles = 0; - - loop->pending_reqs_tail = NULL; - - loop->endgame_handles = NULL; - - RB_INIT(&loop->timers); - - loop->check_handles = NULL; - loop->prepare_handles = NULL; - loop->idle_handles = NULL; - - loop->next_prepare_handle = NULL; - loop->next_check_handle = NULL; - loop->next_idle_handle = NULL; - - memset(&loop->poll_peer_sockets, 0, sizeof loop->poll_peer_sockets); - - loop->active_tcp_streams = 0; - loop->active_udp_streams = 0; - - loop->timer_counter = 0; - loop->stop_flag = 0; - - err = uv_mutex_init(&loop->wq_mutex); - if (err) - goto fail_mutex_init; - - err = uv_async_init(loop, &loop->wq_async, uv__work_done); - if (err) - goto fail_async_init; - - uv__handle_unref(&loop->wq_async); - loop->wq_async.flags |= UV__HANDLE_INTERNAL; - - return 0; - -fail_async_init: - uv_mutex_destroy(&loop->wq_mutex); - -fail_mutex_init: - CloseHandle(loop->iocp); - loop->iocp = INVALID_HANDLE_VALUE; - - return err; -} - - -void uv__once_init(void) { - uv_once(&uv_init_guard_, uv_init); -} - - -void uv__loop_close(uv_loop_t* loop) { - size_t i; - - /* close the async handle without needing an extra loop iteration */ - assert(!loop->wq_async.async_sent); - loop->wq_async.close_cb = NULL; - uv__handle_closing(&loop->wq_async); - uv__handle_close(&loop->wq_async); - - for (i = 0; i < ARRAY_SIZE(loop->poll_peer_sockets); i++) { - SOCKET sock = loop->poll_peer_sockets[i]; - if (sock != 0 && sock != INVALID_SOCKET) - closesocket(sock); - } - - uv_mutex_lock(&loop->wq_mutex); - assert(QUEUE_EMPTY(&loop->wq) && "thread pool work queue not empty!"); - assert(!uv__has_active_reqs(loop)); - uv_mutex_unlock(&loop->wq_mutex); - uv_mutex_destroy(&loop->wq_mutex); - - CloseHandle(loop->iocp); -} - - -int uv__loop_configure(uv_loop_t* loop, uv_loop_option option, va_list ap) { - return UV_ENOSYS; -} - - -int uv_backend_fd(const uv_loop_t* loop) { - return -1; -} - - -int uv_backend_timeout(const uv_loop_t* loop) { - if (loop->stop_flag != 0) - return 0; - - if (!uv__has_active_handles(loop) && !uv__has_active_reqs(loop)) - return 0; - - if (loop->pending_reqs_tail) - return 0; - - if (loop->endgame_handles) - return 0; - - if (loop->idle_handles) - return 0; - - return uv__next_timeout(loop); -} - - -static void uv_poll(uv_loop_t* loop, DWORD timeout) { - DWORD bytes; - ULONG_PTR key; - OVERLAPPED* overlapped; - uv_req_t* req; - int repeat; - uint64_t timeout_time; - - timeout_time = loop->time + timeout; - - for (repeat = 0; ; repeat++) { - GetQueuedCompletionStatus(loop->iocp, - &bytes, - &key, - &overlapped, - timeout); - - if (overlapped) { - /* Package was dequeued */ - req = uv_overlapped_to_req(overlapped); - uv_insert_pending_req(loop, req); - - /* Some time might have passed waiting for I/O, - * so update the loop time here. - */ - uv_update_time(loop); - } else if (GetLastError() != WAIT_TIMEOUT) { - /* Serious error */ - uv_fatal_error(GetLastError(), "GetQueuedCompletionStatus"); - } else if (timeout > 0) { - /* GetQueuedCompletionStatus can occasionally return a little early. - * Make sure that the desired timeout target time is reached. - */ - uv_update_time(loop); - if (timeout_time > loop->time) { - timeout = (DWORD)(timeout_time - loop->time); - /* The first call to GetQueuedCompletionStatus should return very - * close to the target time and the second should reach it, but - * this is not stated in the documentation. To make sure a busy - * loop cannot happen, the timeout is increased exponentially - * starting on the third round. - */ - timeout += repeat ? (1 << (repeat - 1)) : 0; - continue; - } - } - break; - } -} - - -static void uv_poll_ex(uv_loop_t* loop, DWORD timeout) { - BOOL success; - uv_req_t* req; - OVERLAPPED_ENTRY overlappeds[128]; - ULONG count; - ULONG i; - int repeat; - uint64_t timeout_time; - - timeout_time = loop->time + timeout; - - for (repeat = 0; ; repeat++) { - success = pGetQueuedCompletionStatusEx(loop->iocp, - overlappeds, - ARRAY_SIZE(overlappeds), - &count, - timeout, - FALSE); - - if (success) { - for (i = 0; i < count; i++) { - /* Package was dequeued */ - req = uv_overlapped_to_req(overlappeds[i].lpOverlapped); - uv_insert_pending_req(loop, req); - } - - /* Some time might have passed waiting for I/O, - * so update the loop time here. - */ - uv_update_time(loop); - } else if (GetLastError() != WAIT_TIMEOUT) { - /* Serious error */ - uv_fatal_error(GetLastError(), "GetQueuedCompletionStatusEx"); - } else if (timeout > 0) { - /* GetQueuedCompletionStatus can occasionally return a little early. - * Make sure that the desired timeout target time is reached. - */ - uv_update_time(loop); - if (timeout_time > loop->time) { - timeout = (DWORD)(timeout_time - loop->time); - /* The first call to GetQueuedCompletionStatus should return very - * close to the target time and the second should reach it, but - * this is not stated in the documentation. To make sure a busy - * loop cannot happen, the timeout is increased exponentially - * starting on the third round. - */ - timeout += repeat ? (1 << (repeat - 1)) : 0; - continue; - } - } - break; - } -} - - -static int uv__loop_alive(const uv_loop_t* loop) { - return loop->active_handles > 0 || - !QUEUE_EMPTY(&loop->active_reqs) || - loop->endgame_handles != NULL; -} - - -int uv_loop_alive(const uv_loop_t* loop) { - return uv__loop_alive(loop); -} - - -int uv_run(uv_loop_t *loop, uv_run_mode mode) { - DWORD timeout; - int r; - int ran_pending; - void (*poll)(uv_loop_t* loop, DWORD timeout); - - if (pGetQueuedCompletionStatusEx) - poll = &uv_poll_ex; - else - poll = &uv_poll; - - r = uv__loop_alive(loop); - if (!r) - uv_update_time(loop); - - while (r != 0 && loop->stop_flag == 0) { - uv_update_time(loop); - uv_process_timers(loop); - - ran_pending = uv_process_reqs(loop); - uv_idle_invoke(loop); - uv_prepare_invoke(loop); - - timeout = 0; - if ((mode == UV_RUN_ONCE && !ran_pending) || mode == UV_RUN_DEFAULT) - timeout = uv_backend_timeout(loop); - - (*poll)(loop, timeout); - - uv_check_invoke(loop); - uv_process_endgames(loop); - - if (mode == UV_RUN_ONCE) { - /* UV_RUN_ONCE implies forward progress: at least one callback must have - * been invoked when it returns. uv__io_poll() can return without doing - * I/O (meaning: no callbacks) when its timeout expires - which means we - * have pending timers that satisfy the forward progress constraint. - * - * UV_RUN_NOWAIT makes no guarantees about progress so it's omitted from - * the check. - */ - uv_process_timers(loop); - } - - r = uv__loop_alive(loop); - if (mode == UV_RUN_ONCE || mode == UV_RUN_NOWAIT) - break; - } - - /* The if statement lets the compiler compile it to a conditional store. - * Avoids dirtying a cache line. - */ - if (loop->stop_flag != 0) - loop->stop_flag = 0; - - return r; -} - - -int uv_fileno(const uv_handle_t* handle, uv_os_fd_t* fd) { - uv_os_fd_t fd_out; - - switch (handle->type) { - case UV_TCP: - fd_out = (uv_os_fd_t)((uv_tcp_t*) handle)->socket; - break; - - case UV_NAMED_PIPE: - fd_out = ((uv_pipe_t*) handle)->handle; - break; - - case UV_TTY: - fd_out = ((uv_tty_t*) handle)->handle; - break; - - case UV_UDP: - fd_out = (uv_os_fd_t)((uv_udp_t*) handle)->socket; - break; - - case UV_POLL: - fd_out = (uv_os_fd_t)((uv_poll_t*) handle)->socket; - break; - - default: - return UV_EINVAL; - } - - if (uv_is_closing(handle) || fd_out == INVALID_HANDLE_VALUE) - return UV_EBADF; - - *fd = fd_out; - return 0; -} - - -int uv__socket_sockopt(uv_handle_t* handle, int optname, int* value) { - int r; - int len; - SOCKET socket; - - if (handle == NULL || value == NULL) - return UV_EINVAL; - - if (handle->type == UV_TCP) - socket = ((uv_tcp_t*) handle)->socket; - else if (handle->type == UV_UDP) - socket = ((uv_udp_t*) handle)->socket; - else - return UV_ENOTSUP; - - len = sizeof(*value); - - if (*value == 0) - r = getsockopt(socket, SOL_SOCKET, optname, (char*) value, &len); - else - r = setsockopt(socket, SOL_SOCKET, optname, (const char*) value, len); - - if (r == SOCKET_ERROR) - return uv_translate_sys_error(WSAGetLastError()); - - return 0; -} diff --git a/3rdparty/libuv/src/win/dl.c b/3rdparty/libuv/src/win/dl.c deleted file mode 100644 index 39e400ab2db..00000000000 --- a/3rdparty/libuv/src/win/dl.c +++ /dev/null @@ -1,118 +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. - */ - -#include "uv.h" -#include "internal.h" - -static int uv__dlerror(uv_lib_t* lib, int errorno); - - -int uv_dlopen(const char* filename, uv_lib_t* lib) { - WCHAR filename_w[32768]; - - lib->handle = NULL; - lib->errmsg = NULL; - - if (!MultiByteToWideChar(CP_UTF8, - 0, - filename, - -1, - filename_w, - ARRAY_SIZE(filename_w))) { - return uv__dlerror(lib, GetLastError()); - } - - lib->handle = LoadLibraryExW(filename_w, NULL, LOAD_WITH_ALTERED_SEARCH_PATH); - if (lib->handle == NULL) { - return uv__dlerror(lib, GetLastError()); - } - - return 0; -} - - -void uv_dlclose(uv_lib_t* lib) { - if (lib->errmsg) { - LocalFree((void*)lib->errmsg); - lib->errmsg = NULL; - } - - if (lib->handle) { - /* Ignore errors. No good way to signal them without leaking memory. */ - FreeLibrary(lib->handle); - lib->handle = NULL; - } -} - - -int uv_dlsym(uv_lib_t* lib, const char* name, void** ptr) { - *ptr = (void*) GetProcAddress(lib->handle, name); - return uv__dlerror(lib, *ptr ? 0 : GetLastError()); -} - - -const char* uv_dlerror(const uv_lib_t* lib) { - return lib->errmsg ? lib->errmsg : "no error"; -} - - -static void uv__format_fallback_error(uv_lib_t* lib, int errorno){ - DWORD_PTR args[1] = { (DWORD_PTR) errorno }; - LPSTR fallback_error = "error: %1!d!"; - - FormatMessageA(FORMAT_MESSAGE_FROM_STRING | - FORMAT_MESSAGE_ARGUMENT_ARRAY | - FORMAT_MESSAGE_ALLOCATE_BUFFER, - fallback_error, 0, 0, - (LPSTR) &lib->errmsg, - 0, (va_list*) args); -} - - - -static int uv__dlerror(uv_lib_t* lib, int errorno) { - DWORD res; - - if (lib->errmsg) { - LocalFree((void*)lib->errmsg); - lib->errmsg = NULL; - } - - if (errorno) { - res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, - MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), - (LPSTR) &lib->errmsg, 0, NULL); - if (!res && GetLastError() == ERROR_MUI_FILE_NOT_FOUND) { - res = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, - 0, (LPSTR) &lib->errmsg, 0, NULL); - } - - if (!res) { - uv__format_fallback_error(lib, errorno); - } - } - - return errorno ? -1 : 0; -} diff --git a/3rdparty/libuv/src/win/error.c b/3rdparty/libuv/src/win/error.c deleted file mode 100644 index c512f35af97..00000000000 --- a/3rdparty/libuv/src/win/error.c +++ /dev/null @@ -1,170 +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. - */ - -#include <assert.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" - - -/* - * Display an error message and abort the event loop. - */ -void uv_fatal_error(const int errorno, const char* syscall) { - char* buf = NULL; - const char* errmsg; - - FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, NULL, errorno, - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&buf, 0, NULL); - - if (buf) { - errmsg = buf; - } else { - errmsg = "Unknown error"; - } - - /* FormatMessage messages include a newline character already, */ - /* so don't add another. */ - if (syscall) { - fprintf(stderr, "%s: (%d) %s", syscall, errorno, errmsg); - } else { - fprintf(stderr, "(%d) %s", errorno, errmsg); - } - - if (buf) { - LocalFree(buf); - } - - *((char*)NULL) = 0xff; /* Force debug break */ - abort(); -} - - -int uv_translate_sys_error(int sys_errno) { - if (sys_errno <= 0) { - return sys_errno; /* If < 0 then it's already a libuv error. */ - } - - switch (sys_errno) { - case ERROR_NOACCESS: return UV_EACCES; - case WSAEACCES: return UV_EACCES; - case ERROR_ADDRESS_ALREADY_ASSOCIATED: return UV_EADDRINUSE; - case WSAEADDRINUSE: return UV_EADDRINUSE; - case WSAEADDRNOTAVAIL: return UV_EADDRNOTAVAIL; - case WSAEAFNOSUPPORT: return UV_EAFNOSUPPORT; - case WSAEWOULDBLOCK: return UV_EAGAIN; - case WSAEALREADY: return UV_EALREADY; - case ERROR_INVALID_FLAGS: return UV_EBADF; - case ERROR_INVALID_HANDLE: return UV_EBADF; - case ERROR_LOCK_VIOLATION: return UV_EBUSY; - case ERROR_PIPE_BUSY: return UV_EBUSY; - case ERROR_SHARING_VIOLATION: return UV_EBUSY; - case ERROR_OPERATION_ABORTED: return UV_ECANCELED; - case WSAEINTR: return UV_ECANCELED; - case ERROR_NO_UNICODE_TRANSLATION: return UV_ECHARSET; - case ERROR_CONNECTION_ABORTED: return UV_ECONNABORTED; - case WSAECONNABORTED: return UV_ECONNABORTED; - case ERROR_CONNECTION_REFUSED: return UV_ECONNREFUSED; - case WSAECONNREFUSED: return UV_ECONNREFUSED; - case ERROR_NETNAME_DELETED: return UV_ECONNRESET; - case WSAECONNRESET: return UV_ECONNRESET; - case ERROR_ALREADY_EXISTS: return UV_EEXIST; - case ERROR_FILE_EXISTS: return UV_EEXIST; - case ERROR_BUFFER_OVERFLOW: return UV_EFAULT; - case WSAEFAULT: return UV_EFAULT; - case ERROR_HOST_UNREACHABLE: return UV_EHOSTUNREACH; - case WSAEHOSTUNREACH: return UV_EHOSTUNREACH; - case ERROR_INSUFFICIENT_BUFFER: return UV_EINVAL; - case ERROR_INVALID_DATA: return UV_EINVAL; - case ERROR_INVALID_PARAMETER: return UV_EINVAL; - case ERROR_SYMLINK_NOT_SUPPORTED: return UV_EINVAL; - case WSAEINVAL: return UV_EINVAL; - case WSAEPFNOSUPPORT: return UV_EINVAL; - case WSAESOCKTNOSUPPORT: return UV_EINVAL; - case ERROR_BEGINNING_OF_MEDIA: return UV_EIO; - case ERROR_BUS_RESET: return UV_EIO; - case ERROR_CRC: return UV_EIO; - case ERROR_DEVICE_DOOR_OPEN: return UV_EIO; - case ERROR_DEVICE_REQUIRES_CLEANING: return UV_EIO; - case ERROR_DISK_CORRUPT: return UV_EIO; - case ERROR_EOM_OVERFLOW: return UV_EIO; - case ERROR_FILEMARK_DETECTED: return UV_EIO; - case ERROR_GEN_FAILURE: return UV_EIO; - case ERROR_INVALID_BLOCK_LENGTH: return UV_EIO; - case ERROR_IO_DEVICE: return UV_EIO; - case ERROR_NO_DATA_DETECTED: return UV_EIO; - case ERROR_NO_SIGNAL_SENT: return UV_EIO; - case ERROR_OPEN_FAILED: return UV_EIO; - case ERROR_SETMARK_DETECTED: return UV_EIO; - case ERROR_SIGNAL_REFUSED: return UV_EIO; - case WSAEISCONN: return UV_EISCONN; - case ERROR_CANT_RESOLVE_FILENAME: return UV_ELOOP; - case ERROR_TOO_MANY_OPEN_FILES: return UV_EMFILE; - case WSAEMFILE: return UV_EMFILE; - case WSAEMSGSIZE: return UV_EMSGSIZE; - case ERROR_FILENAME_EXCED_RANGE: return UV_ENAMETOOLONG; - case ERROR_NETWORK_UNREACHABLE: return UV_ENETUNREACH; - case WSAENETUNREACH: return UV_ENETUNREACH; - case WSAENOBUFS: return UV_ENOBUFS; - case ERROR_BAD_PATHNAME: return UV_ENOENT; - case ERROR_DIRECTORY: return UV_ENOENT; - case ERROR_FILE_NOT_FOUND: return UV_ENOENT; - case ERROR_INVALID_NAME: return UV_ENOENT; - case ERROR_INVALID_DRIVE: return UV_ENOENT; - case ERROR_INVALID_REPARSE_DATA: return UV_ENOENT; - case ERROR_MOD_NOT_FOUND: return UV_ENOENT; - case ERROR_PATH_NOT_FOUND: return UV_ENOENT; - case WSAHOST_NOT_FOUND: return UV_ENOENT; - case WSANO_DATA: return UV_ENOENT; - case ERROR_NOT_ENOUGH_MEMORY: return UV_ENOMEM; - case ERROR_OUTOFMEMORY: return UV_ENOMEM; - case ERROR_CANNOT_MAKE: return UV_ENOSPC; - case ERROR_DISK_FULL: return UV_ENOSPC; - case ERROR_EA_TABLE_FULL: return UV_ENOSPC; - case ERROR_END_OF_MEDIA: return UV_ENOSPC; - case ERROR_HANDLE_DISK_FULL: return UV_ENOSPC; - case ERROR_NOT_CONNECTED: return UV_ENOTCONN; - case WSAENOTCONN: return UV_ENOTCONN; - case ERROR_DIR_NOT_EMPTY: return UV_ENOTEMPTY; - case WSAENOTSOCK: return UV_ENOTSOCK; - case ERROR_NOT_SUPPORTED: return UV_ENOTSUP; - case ERROR_BROKEN_PIPE: return UV_EOF; - case ERROR_ACCESS_DENIED: return UV_EPERM; - case ERROR_PRIVILEGE_NOT_HELD: return UV_EPERM; - case ERROR_BAD_PIPE: return UV_EPIPE; - case ERROR_NO_DATA: return UV_EPIPE; - case ERROR_PIPE_NOT_CONNECTED: return UV_EPIPE; - case WSAESHUTDOWN: return UV_EPIPE; - case WSAEPROTONOSUPPORT: return UV_EPROTONOSUPPORT; - case ERROR_WRITE_PROTECT: return UV_EROFS; - case ERROR_SEM_TIMEOUT: return UV_ETIMEDOUT; - case WSAETIMEDOUT: return UV_ETIMEDOUT; - case ERROR_NOT_SAME_DEVICE: return UV_EXDEV; - case ERROR_INVALID_FUNCTION: return UV_EISDIR; - case ERROR_META_EXPANSION_TOO_LONG: return UV_E2BIG; - default: return UV_UNKNOWN; - } -} diff --git a/3rdparty/libuv/src/win/fs-event.c b/3rdparty/libuv/src/win/fs-event.c deleted file mode 100644 index 77c935a2d8c..00000000000 --- a/3rdparty/libuv/src/win/fs-event.c +++ /dev/null @@ -1,550 +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. - */ - -#include <assert.h> -#include <errno.h> -#include <stdio.h> -#include <string.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -const unsigned int uv_directory_watcher_buffer_size = 4096; - - -static void uv_fs_event_queue_readdirchanges(uv_loop_t* loop, - uv_fs_event_t* handle) { - assert(handle->dir_handle != INVALID_HANDLE_VALUE); - assert(!handle->req_pending); - - memset(&(handle->req.u.io.overlapped), 0, - sizeof(handle->req.u.io.overlapped)); - if (!ReadDirectoryChangesW(handle->dir_handle, - handle->buffer, - uv_directory_watcher_buffer_size, - (handle->flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE, - FILE_NOTIFY_CHANGE_FILE_NAME | - FILE_NOTIFY_CHANGE_DIR_NAME | - FILE_NOTIFY_CHANGE_ATTRIBUTES | - FILE_NOTIFY_CHANGE_SIZE | - FILE_NOTIFY_CHANGE_LAST_WRITE | - FILE_NOTIFY_CHANGE_LAST_ACCESS | - FILE_NOTIFY_CHANGE_CREATION | - FILE_NOTIFY_CHANGE_SECURITY, - NULL, - &handle->req.u.io.overlapped, - NULL)) { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(&handle->req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)&handle->req); - } - - handle->req_pending = 1; -} - -static void uv_relative_path(const WCHAR* filename, - const WCHAR* dir, - WCHAR** relpath) { - size_t dirlen = wcslen(dir); - if (dirlen > 0 && dir[dirlen - 1] == '\\') - dirlen--; - size_t filenamelen = wcslen(filename); - size_t relpathlen = filenamelen - dirlen - 1; - *relpath = uv__malloc((relpathlen + 1) * sizeof(WCHAR)); - if (!*relpath) - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - wcsncpy(*relpath, filename + dirlen + 1, relpathlen); - (*relpath)[relpathlen] = L'\0'; -} - -static int uv_split_path(const WCHAR* filename, WCHAR** dir, - WCHAR** file) { - int len = wcslen(filename); - int i = len; - while (i > 0 && filename[--i] != '\\' && filename[i] != '/'); - - if (i == 0) { - if (dir) { - *dir = (WCHAR*)uv__malloc((MAX_PATH + 1) * sizeof(WCHAR)); - if (!*dir) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - if (!GetCurrentDirectoryW(MAX_PATH, *dir)) { - uv__free(*dir); - *dir = NULL; - return -1; - } - } - - *file = wcsdup(filename); - } else { - if (dir) { - *dir = (WCHAR*)uv__malloc((i + 2) * sizeof(WCHAR)); - if (!*dir) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - wcsncpy(*dir, filename, i + 1); - (*dir)[i + 1] = L'\0'; - } - - *file = (WCHAR*)uv__malloc((len - i) * sizeof(WCHAR)); - if (!*file) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - wcsncpy(*file, filename + i + 1, len - i - 1); - (*file)[len - i - 1] = L'\0'; - } - - return 0; -} - - -int uv_fs_event_init(uv_loop_t* loop, uv_fs_event_t* handle) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_FS_EVENT); - handle->dir_handle = INVALID_HANDLE_VALUE; - handle->buffer = NULL; - handle->req_pending = 0; - handle->filew = NULL; - handle->short_filew = NULL; - handle->dirw = NULL; - - uv_req_init(loop, (uv_req_t*)&handle->req); - handle->req.type = UV_FS_EVENT_REQ; - handle->req.data = handle; - - return 0; -} - - -int uv_fs_event_start(uv_fs_event_t* handle, - uv_fs_event_cb cb, - const char* path, - unsigned int flags) { - int name_size, is_path_dir; - DWORD attr, last_error; - WCHAR* dir = NULL, *dir_to_watch, *pathw = NULL; - WCHAR short_path[MAX_PATH]; - - if (uv__is_active(handle)) - return UV_EINVAL; - - handle->cb = cb; - handle->path = uv__strdup(path); - if (!handle->path) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - uv__handle_start(handle); - - /* Convert name to UTF16. */ - - name_size = MultiByteToWideChar(CP_UTF8, 0, path, -1, NULL, 0) * - sizeof(WCHAR); - pathw = (WCHAR*)uv__malloc(name_size); - if (!pathw) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - if (!MultiByteToWideChar(CP_UTF8, - 0, - path, - -1, - pathw, - name_size / sizeof(WCHAR))) { - return uv_translate_sys_error(GetLastError()); - } - - /* Determine whether path is a file or a directory. */ - attr = GetFileAttributesW(pathw); - if (attr == INVALID_FILE_ATTRIBUTES) { - last_error = GetLastError(); - goto error; - } - - is_path_dir = (attr & FILE_ATTRIBUTE_DIRECTORY) ? 1 : 0; - - if (is_path_dir) { - /* path is a directory, so that's the directory that we will watch. */ - handle->dirw = pathw; - dir_to_watch = pathw; - } else { - /* - * path is a file. So we split path into dir & file parts, and - * watch the dir directory. - */ - - /* Convert to short path. */ - if (!GetShortPathNameW(pathw, short_path, ARRAY_SIZE(short_path))) { - last_error = GetLastError(); - goto error; - } - - if (uv_split_path(pathw, &dir, &handle->filew) != 0) { - last_error = GetLastError(); - goto error; - } - - if (uv_split_path(short_path, NULL, &handle->short_filew) != 0) { - last_error = GetLastError(); - goto error; - } - - dir_to_watch = dir; - uv__free(pathw); - pathw = NULL; - } - - handle->dir_handle = CreateFileW(dir_to_watch, - FILE_LIST_DIRECTORY, - FILE_SHARE_READ | FILE_SHARE_DELETE | - FILE_SHARE_WRITE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OVERLAPPED, - NULL); - - if (dir) { - uv__free(dir); - dir = NULL; - } - - if (handle->dir_handle == INVALID_HANDLE_VALUE) { - last_error = GetLastError(); - goto error; - } - - if (CreateIoCompletionPort(handle->dir_handle, - handle->loop->iocp, - (ULONG_PTR)handle, - 0) == NULL) { - last_error = GetLastError(); - goto error; - } - - if (!handle->buffer) { - handle->buffer = (char*)uv__malloc(uv_directory_watcher_buffer_size); - } - if (!handle->buffer) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - memset(&(handle->req.u.io.overlapped), 0, - sizeof(handle->req.u.io.overlapped)); - - if (!ReadDirectoryChangesW(handle->dir_handle, - handle->buffer, - uv_directory_watcher_buffer_size, - (flags & UV_FS_EVENT_RECURSIVE) ? TRUE : FALSE, - FILE_NOTIFY_CHANGE_FILE_NAME | - FILE_NOTIFY_CHANGE_DIR_NAME | - FILE_NOTIFY_CHANGE_ATTRIBUTES | - FILE_NOTIFY_CHANGE_SIZE | - FILE_NOTIFY_CHANGE_LAST_WRITE | - FILE_NOTIFY_CHANGE_LAST_ACCESS | - FILE_NOTIFY_CHANGE_CREATION | - FILE_NOTIFY_CHANGE_SECURITY, - NULL, - &handle->req.u.io.overlapped, - NULL)) { - last_error = GetLastError(); - goto error; - } - - handle->req_pending = 1; - return 0; - -error: - if (handle->path) { - uv__free(handle->path); - handle->path = NULL; - } - - if (handle->filew) { - uv__free(handle->filew); - handle->filew = NULL; - } - - if (handle->short_filew) { - uv__free(handle->short_filew); - handle->short_filew = NULL; - } - - uv__free(pathw); - - if (handle->dir_handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->dir_handle); - handle->dir_handle = INVALID_HANDLE_VALUE; - } - - if (handle->buffer) { - uv__free(handle->buffer); - handle->buffer = NULL; - } - - return uv_translate_sys_error(last_error); -} - - -int uv_fs_event_stop(uv_fs_event_t* handle) { - if (!uv__is_active(handle)) - return 0; - - if (handle->dir_handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->dir_handle); - handle->dir_handle = INVALID_HANDLE_VALUE; - } - - uv__handle_stop(handle); - - if (handle->filew) { - uv__free(handle->filew); - handle->filew = NULL; - } - - if (handle->short_filew) { - uv__free(handle->short_filew); - handle->short_filew = NULL; - } - - if (handle->path) { - uv__free(handle->path); - handle->path = NULL; - } - - if (handle->dirw) { - uv__free(handle->dirw); - handle->dirw = NULL; - } - - return 0; -} - - -void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, - uv_fs_event_t* handle) { - FILE_NOTIFY_INFORMATION* file_info; - int err, sizew, size; - char* filename = NULL; - WCHAR* filenamew, *long_filenamew = NULL; - DWORD offset = 0; - - assert(req->type == UV_FS_EVENT_REQ); - assert(handle->req_pending); - handle->req_pending = 0; - - /* Don't report any callbacks if: - * - We're closing, just push the handle onto the endgame queue - * - We are not active, just ignore the callback - */ - if (!uv__is_active(handle)) { - if (handle->flags & UV__HANDLE_CLOSING) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - return; - } - - file_info = (FILE_NOTIFY_INFORMATION*)(handle->buffer + offset); - - if (REQ_SUCCESS(req)) { - if (req->u.io.overlapped.InternalHigh > 0) { - do { - file_info = (FILE_NOTIFY_INFORMATION*)((char*)file_info + offset); - assert(!filename); - assert(!long_filenamew); - - /* - * Fire the event only if we were asked to watch a directory, - * or if the filename filter matches. - */ - if (handle->dirw || - _wcsnicmp(handle->filew, file_info->FileName, - file_info->FileNameLength / sizeof(WCHAR)) == 0 || - _wcsnicmp(handle->short_filew, file_info->FileName, - file_info->FileNameLength / sizeof(WCHAR)) == 0) { - - if (handle->dirw) { - /* - * We attempt to resolve the long form of the file name explicitly. - * We only do this for file names that might still exist on disk. - * If this fails, we use the name given by ReadDirectoryChangesW. - * This may be the long form or the 8.3 short name in some cases. - */ - if (file_info->Action != FILE_ACTION_REMOVED && - file_info->Action != FILE_ACTION_RENAMED_OLD_NAME) { - /* Construct a full path to the file. */ - size = wcslen(handle->dirw) + - file_info->FileNameLength / sizeof(WCHAR) + 2; - - filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); - if (!filenamew) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - _snwprintf(filenamew, size, L"%s\\%.*s", handle->dirw, - file_info->FileNameLength / sizeof(WCHAR), - file_info->FileName); - - filenamew[size - 1] = L'\0'; - - /* Convert to long name. */ - size = GetLongPathNameW(filenamew, NULL, 0); - - if (size) { - long_filenamew = (WCHAR*)uv__malloc(size * sizeof(WCHAR)); - if (!long_filenamew) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - size = GetLongPathNameW(filenamew, long_filenamew, size); - if (size) { - long_filenamew[size] = '\0'; - } else { - uv__free(long_filenamew); - long_filenamew = NULL; - } - } - - uv__free(filenamew); - - if (long_filenamew) { - /* Get the file name out of the long path. */ - uv_relative_path(long_filenamew, - handle->dirw, - &filenamew); - uv__free(long_filenamew); - long_filenamew = filenamew; - sizew = -1; - } - } - /* - * Removed or renamed events cannot be resolved to the long form. - * We therefore use the name given by ReadDirectoryChangesW. - * This may be the long form or the 8.3 short name in some cases. - */ - if (!long_filenamew) { - filenamew = file_info->FileName; - sizew = file_info->FileNameLength / sizeof(WCHAR); - } - } else { - /* We already have the long name of the file, so just use it. */ - filenamew = handle->filew; - sizew = -1; - } - - if (filenamew) { - /* Convert the filename to utf8. */ - size = WideCharToMultiByte(CP_UTF8, - 0, - filenamew, - sizew, - NULL, - 0, - NULL, - NULL); - if (size) { - filename = (char*)uv__malloc(size + 1); - if (!filename) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - size = WideCharToMultiByte(CP_UTF8, - 0, - filenamew, - sizew, - filename, - size, - NULL, - NULL); - if (size) { - filename[size] = '\0'; - } else { - uv__free(filename); - filename = NULL; - } - } - } - - switch (file_info->Action) { - case FILE_ACTION_ADDED: - case FILE_ACTION_REMOVED: - case FILE_ACTION_RENAMED_OLD_NAME: - case FILE_ACTION_RENAMED_NEW_NAME: - handle->cb(handle, filename, UV_RENAME, 0); - break; - - case FILE_ACTION_MODIFIED: - handle->cb(handle, filename, UV_CHANGE, 0); - break; - } - - uv__free(filename); - filename = NULL; - uv__free(long_filenamew); - long_filenamew = NULL; - } - - offset = file_info->NextEntryOffset; - } while (offset && !(handle->flags & UV__HANDLE_CLOSING)); - } else { - handle->cb(handle, NULL, UV_CHANGE, 0); - } - } else { - err = GET_REQ_ERROR(req); - handle->cb(handle, NULL, 0, uv_translate_sys_error(err)); - } - - if (!(handle->flags & UV__HANDLE_CLOSING)) { - uv_fs_event_queue_readdirchanges(loop, handle); - } else { - uv_want_endgame(loop, (uv_handle_t*)handle); - } -} - - -void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle) { - uv_fs_event_stop(handle); - - uv__handle_closing(handle); - - if (!handle->req_pending) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - -} - - -void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle) { - if ((handle->flags & UV__HANDLE_CLOSING) && !handle->req_pending) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - if (handle->buffer) { - uv__free(handle->buffer); - handle->buffer = NULL; - } - - uv__handle_close(handle); - } -} diff --git a/3rdparty/libuv/src/win/fs.c b/3rdparty/libuv/src/win/fs.c deleted file mode 100644 index 16e3ae7cf1b..00000000000 --- a/3rdparty/libuv/src/win/fs.c +++ /dev/null @@ -1,2471 +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. - */ - -#include <assert.h> -#include <stdlib.h> -#include <direct.h> -#include <errno.h> -#include <fcntl.h> -#include <io.h> -#include <limits.h> -#include <sys/stat.h> -#include <sys/utime.h> -#include <stdio.h> - -#include "uv.h" -#include "internal.h" -#include "req-inl.h" -#include "handle-inl.h" - -#include <wincrypt.h> - - -#define UV_FS_FREE_PATHS 0x0002 -#define UV_FS_FREE_PTR 0x0008 -#define UV_FS_CLEANEDUP 0x0010 - - -#define QUEUE_FS_TP_JOB(loop, req) \ - do { \ - uv__req_register(loop, req); \ - uv__work_submit((loop), &(req)->work_req, uv__fs_work, uv__fs_done); \ - } while (0) - -#define SET_REQ_RESULT(req, result_value) \ - do { \ - req->result = (result_value); \ - if (req->result == -1) { \ - req->sys_errno_ = _doserrno; \ - req->result = uv_translate_sys_error(req->sys_errno_); \ - } \ - } while (0) - -#define SET_REQ_WIN32_ERROR(req, sys_errno) \ - do { \ - req->sys_errno_ = (sys_errno); \ - req->result = uv_translate_sys_error(req->sys_errno_); \ - } while (0) - -#define SET_REQ_UV_ERROR(req, uv_errno, sys_errno) \ - do { \ - req->result = (uv_errno); \ - req->sys_errno_ = (sys_errno); \ - } while (0) - -#define VERIFY_FD(fd, req) \ - if (fd == -1) { \ - req->result = UV_EBADF; \ - req->sys_errno_ = ERROR_INVALID_HANDLE; \ - return; \ - } - -#define FILETIME_TO_UINT(filetime) \ - (*((uint64_t*) &(filetime)) - 116444736000000000ULL) - -#define FILETIME_TO_TIME_T(filetime) \ - (FILETIME_TO_UINT(filetime) / 10000000ULL) - -#define FILETIME_TO_TIME_NS(filetime, secs) \ - ((FILETIME_TO_UINT(filetime) - (secs * 10000000ULL)) * 100) - -#define FILETIME_TO_TIMESPEC(ts, filetime) \ - do { \ - (ts).tv_sec = (long) FILETIME_TO_TIME_T(filetime); \ - (ts).tv_nsec = (long) FILETIME_TO_TIME_NS(filetime, (ts).tv_sec); \ - } while(0) - -#define TIME_T_TO_FILETIME(time, filetime_ptr) \ - do { \ - uint64_t bigtime = ((int64_t) (time) * 10000000LL) + \ - 116444736000000000ULL; \ - (filetime_ptr)->dwLowDateTime = bigtime & 0xFFFFFFFF; \ - (filetime_ptr)->dwHighDateTime = bigtime >> 32; \ - } while(0) - -#define IS_SLASH(c) ((c) == L'\\' || (c) == L'/') -#define IS_LETTER(c) (((c) >= L'a' && (c) <= L'z') || \ - ((c) >= L'A' && (c) <= L'Z')) - -const WCHAR JUNCTION_PREFIX[] = L"\\??\\"; -const WCHAR JUNCTION_PREFIX_LEN = 4; - -const WCHAR LONG_PATH_PREFIX[] = L"\\\\?\\"; -const WCHAR LONG_PATH_PREFIX_LEN = 4; - -const WCHAR UNC_PATH_PREFIX[] = L"\\\\?\\UNC\\"; -const WCHAR UNC_PATH_PREFIX_LEN = 8; - - -void uv_fs_init() { - _fmode = _O_BINARY; -} - - -INLINE static int fs__capture_path(uv_fs_t* req, const char* path, - const char* new_path, const int copy_path) { - char* buf; - char* pos; - ssize_t buf_sz = 0, path_len, pathw_len = 0, new_pathw_len = 0; - - /* new_path can only be set if path is also set. */ - assert(new_path == NULL || path != NULL); - - if (path != NULL) { - pathw_len = MultiByteToWideChar(CP_UTF8, - 0, - path, - -1, - NULL, - 0); - if (pathw_len == 0) { - return GetLastError(); - } - - buf_sz += pathw_len * sizeof(WCHAR); - } - - if (path != NULL && copy_path) { - path_len = 1 + strlen(path); - buf_sz += path_len; - } - - if (new_path != NULL) { - new_pathw_len = MultiByteToWideChar(CP_UTF8, - 0, - new_path, - -1, - NULL, - 0); - if (new_pathw_len == 0) { - return GetLastError(); - } - - buf_sz += new_pathw_len * sizeof(WCHAR); - } - - - if (buf_sz == 0) { - req->file.pathw = NULL; - req->fs.info.new_pathw = NULL; - req->path = NULL; - return 0; - } - - buf = (char*) uv__malloc(buf_sz); - if (buf == NULL) { - return ERROR_OUTOFMEMORY; - } - - pos = buf; - - if (path != NULL) { - DWORD r = MultiByteToWideChar(CP_UTF8, - 0, - path, - -1, - (WCHAR*) pos, - pathw_len); - assert(r == (DWORD) pathw_len); - req->file.pathw = (WCHAR*) pos; - pos += r * sizeof(WCHAR); - } else { - req->file.pathw = NULL; - } - - if (new_path != NULL) { - DWORD r = MultiByteToWideChar(CP_UTF8, - 0, - new_path, - -1, - (WCHAR*) pos, - new_pathw_len); - assert(r == (DWORD) new_pathw_len); - req->fs.info.new_pathw = (WCHAR*) pos; - pos += r * sizeof(WCHAR); - } else { - req->fs.info.new_pathw = NULL; - } - - if (!copy_path) { - req->path = path; - } else if (path) { - memcpy(pos, path, path_len); - assert(path_len == buf_sz - (pos - buf)); - req->path = pos; - } else { - req->path = NULL; - } - - req->flags |= UV_FS_FREE_PATHS; - - return 0; -} - - - -INLINE static void uv_fs_req_init(uv_loop_t* loop, uv_fs_t* req, - uv_fs_type fs_type, const uv_fs_cb cb) { - uv_req_init(loop, (uv_req_t*) req); - - req->type = UV_FS; - req->loop = loop; - req->flags = 0; - req->fs_type = fs_type; - req->result = 0; - req->ptr = NULL; - req->path = NULL; - req->cb = cb; -} - - -static int fs__wide_to_utf8(WCHAR* w_source_ptr, - DWORD w_source_len, - char** target_ptr, - uint64_t* target_len_ptr) { - int r; - int target_len; - char* target; - target_len = WideCharToMultiByte(CP_UTF8, - 0, - w_source_ptr, - w_source_len, - NULL, - 0, - NULL, - NULL); - - if (target_len == 0) { - return -1; - } - - if (target_len_ptr != NULL) { - *target_len_ptr = target_len; - } - - if (target_ptr == NULL) { - return 0; - } - - target = uv__malloc(target_len + 1); - if (target == NULL) { - SetLastError(ERROR_OUTOFMEMORY); - return -1; - } - - r = WideCharToMultiByte(CP_UTF8, - 0, - w_source_ptr, - w_source_len, - target, - target_len, - NULL, - NULL); - assert(r == target_len); - target[target_len] = '\0'; - *target_ptr = target; - return 0; -} - - -INLINE static int fs__readlink_handle(HANDLE handle, char** target_ptr, - uint64_t* target_len_ptr) { - char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; - REPARSE_DATA_BUFFER* reparse_data = (REPARSE_DATA_BUFFER*) buffer; - WCHAR* w_target; - DWORD w_target_len; - DWORD bytes; - - if (!DeviceIoControl(handle, - FSCTL_GET_REPARSE_POINT, - NULL, - 0, - buffer, - sizeof buffer, - &bytes, - NULL)) { - return -1; - } - - if (reparse_data->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - /* Real symlink */ - w_target = reparse_data->SymbolicLinkReparseBuffer.PathBuffer + - (reparse_data->SymbolicLinkReparseBuffer.SubstituteNameOffset / - sizeof(WCHAR)); - w_target_len = - reparse_data->SymbolicLinkReparseBuffer.SubstituteNameLength / - sizeof(WCHAR); - - /* Real symlinks can contain pretty much everything, but the only thing */ - /* we really care about is undoing the implicit conversion to an NT */ - /* namespaced path that CreateSymbolicLink will perform on absolute */ - /* paths. If the path is win32-namespaced then the user must have */ - /* explicitly made it so, and we better just return the unmodified */ - /* reparse data. */ - if (w_target_len >= 4 && - w_target[0] == L'\\' && - w_target[1] == L'?' && - w_target[2] == L'?' && - w_target[3] == L'\\') { - /* Starts with \??\ */ - if (w_target_len >= 6 && - ((w_target[4] >= L'A' && w_target[4] <= L'Z') || - (w_target[4] >= L'a' && w_target[4] <= L'z')) && - w_target[5] == L':' && - (w_target_len == 6 || w_target[6] == L'\\')) { - /* \??\<drive>:\ */ - w_target += 4; - w_target_len -= 4; - - } else if (w_target_len >= 8 && - (w_target[4] == L'U' || w_target[4] == L'u') && - (w_target[5] == L'N' || w_target[5] == L'n') && - (w_target[6] == L'C' || w_target[6] == L'c') && - w_target[7] == L'\\') { - /* \??\UNC\<server>\<share>\ - make sure the final path looks like */ - /* \\<server>\<share>\ */ - w_target += 6; - w_target[0] = L'\\'; - w_target_len -= 6; - } - } - - } else if (reparse_data->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { - /* Junction. */ - w_target = reparse_data->MountPointReparseBuffer.PathBuffer + - (reparse_data->MountPointReparseBuffer.SubstituteNameOffset / - sizeof(WCHAR)); - w_target_len = reparse_data->MountPointReparseBuffer.SubstituteNameLength / - sizeof(WCHAR); - - /* Only treat junctions that look like \??\<drive>:\ as symlink. */ - /* Junctions can also be used as mount points, like \??\Volume{<guid>}, */ - /* but that's confusing for programs since they wouldn't be able to */ - /* actually understand such a path when returned by uv_readlink(). */ - /* UNC paths are never valid for junctions so we don't care about them. */ - if (!(w_target_len >= 6 && - w_target[0] == L'\\' && - w_target[1] == L'?' && - w_target[2] == L'?' && - w_target[3] == L'\\' && - ((w_target[4] >= L'A' && w_target[4] <= L'Z') || - (w_target[4] >= L'a' && w_target[4] <= L'z')) && - w_target[5] == L':' && - (w_target_len == 6 || w_target[6] == L'\\'))) { - SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); - return -1; - } - - /* Remove leading \??\ */ - w_target += 4; - w_target_len -= 4; - - } else { - /* Reparse tag does not indicate a symlink. */ - SetLastError(ERROR_SYMLINK_NOT_SUPPORTED); - return -1; - } - - return fs__wide_to_utf8(w_target, w_target_len, target_ptr, target_len_ptr); -} - - -void fs__open(uv_fs_t* req) { - DWORD access; - DWORD share; - DWORD disposition; - DWORD attributes = 0; - HANDLE file; - int fd, current_umask; - int flags = req->fs.info.file_flags; - - /* Obtain the active umask. umask() never fails and returns the previous */ - /* umask. */ - current_umask = umask(0); - umask(current_umask); - - /* convert flags and mode to CreateFile parameters */ - switch (flags & (_O_RDONLY | _O_WRONLY | _O_RDWR)) { - case _O_RDONLY: - access = FILE_GENERIC_READ; - attributes |= FILE_FLAG_BACKUP_SEMANTICS; - break; - case _O_WRONLY: - access = FILE_GENERIC_WRITE; - break; - case _O_RDWR: - access = FILE_GENERIC_READ | FILE_GENERIC_WRITE; - break; - default: - goto einval; - } - - if (flags & _O_APPEND) { - access &= ~FILE_WRITE_DATA; - access |= FILE_APPEND_DATA; - attributes &= ~FILE_FLAG_BACKUP_SEMANTICS; - } - - /* - * Here is where we deviate significantly from what CRT's _open() - * does. We indiscriminately use all the sharing modes, to match - * UNIX semantics. In particular, this ensures that the file can - * be deleted even whilst it's open, fixing issue #1449. - */ - share = FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE; - - switch (flags & (_O_CREAT | _O_EXCL | _O_TRUNC)) { - case 0: - case _O_EXCL: - disposition = OPEN_EXISTING; - break; - case _O_CREAT: - disposition = OPEN_ALWAYS; - break; - case _O_CREAT | _O_EXCL: - case _O_CREAT | _O_TRUNC | _O_EXCL: - disposition = CREATE_NEW; - break; - case _O_TRUNC: - case _O_TRUNC | _O_EXCL: - disposition = TRUNCATE_EXISTING; - break; - case _O_CREAT | _O_TRUNC: - disposition = CREATE_ALWAYS; - break; - default: - goto einval; - } - - attributes |= FILE_ATTRIBUTE_NORMAL; - if (flags & _O_CREAT) { - if (!((req->fs.info.mode & ~current_umask) & _S_IWRITE)) { - attributes |= FILE_ATTRIBUTE_READONLY; - } - } - - if (flags & _O_TEMPORARY ) { - attributes |= FILE_FLAG_DELETE_ON_CLOSE | FILE_ATTRIBUTE_TEMPORARY; - access |= DELETE; - } - - if (flags & _O_SHORT_LIVED) { - attributes |= FILE_ATTRIBUTE_TEMPORARY; - } - - switch (flags & (_O_SEQUENTIAL | _O_RANDOM)) { - case 0: - break; - case _O_SEQUENTIAL: - attributes |= FILE_FLAG_SEQUENTIAL_SCAN; - break; - case _O_RANDOM: - attributes |= FILE_FLAG_RANDOM_ACCESS; - break; - default: - goto einval; - } - - /* Setting this flag makes it possible to open a directory. */ - attributes |= FILE_FLAG_BACKUP_SEMANTICS; - - file = CreateFileW(req->file.pathw, - access, - share, - NULL, - disposition, - attributes, - NULL); - if (file == INVALID_HANDLE_VALUE) { - DWORD error = GetLastError(); - if (error == ERROR_FILE_EXISTS && (flags & _O_CREAT) && - !(flags & _O_EXCL)) { - /* Special case: when ERROR_FILE_EXISTS happens and O_CREAT was */ - /* specified, it means the path referred to a directory. */ - SET_REQ_UV_ERROR(req, UV_EISDIR, error); - } else { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } - return; - } - - fd = _open_osfhandle((intptr_t) file, flags); - if (fd < 0) { - /* The only known failure mode for _open_osfhandle() is EMFILE, in which - * case GetLastError() will return zero. However we'll try to handle other - * errors as well, should they ever occur. - */ - if (errno == EMFILE) - SET_REQ_UV_ERROR(req, UV_EMFILE, ERROR_TOO_MANY_OPEN_FILES); - else if (GetLastError() != ERROR_SUCCESS) - SET_REQ_WIN32_ERROR(req, GetLastError()); - else - SET_REQ_WIN32_ERROR(req, UV_UNKNOWN); - CloseHandle(file); - return; - } - - SET_REQ_RESULT(req, fd); - return; - - einval: - SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); -} - -void fs__close(uv_fs_t* req) { - int fd = req->file.fd; - int result; - - VERIFY_FD(fd, req); - - if (fd > 2) - result = _close(fd); - else - result = 0; - - /* _close doesn't set _doserrno on failure, but it does always set errno - * to EBADF on failure. - */ - if (result == -1) { - assert(errno == EBADF); - SET_REQ_UV_ERROR(req, UV_EBADF, ERROR_INVALID_HANDLE); - } else { - req->result = 0; - } -} - - -void fs__read(uv_fs_t* req) { - int fd = req->file.fd; - int64_t offset = req->fs.info.offset; - HANDLE handle; - OVERLAPPED overlapped, *overlapped_ptr; - LARGE_INTEGER offset_; - DWORD bytes; - DWORD error; - int result; - unsigned int index; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (offset != -1) { - memset(&overlapped, 0, sizeof overlapped); - overlapped_ptr = &overlapped; - } else { - overlapped_ptr = NULL; - } - - index = 0; - bytes = 0; - do { - DWORD incremental_bytes; - - if (offset != -1) { - offset_.QuadPart = offset + bytes; - overlapped.Offset = offset_.LowPart; - overlapped.OffsetHigh = offset_.HighPart; - } - - result = ReadFile(handle, - req->fs.info.bufs[index].base, - req->fs.info.bufs[index].len, - &incremental_bytes, - overlapped_ptr); - bytes += incremental_bytes; - ++index; - } while (result && index < req->fs.info.nbufs); - - if (result || bytes > 0) { - SET_REQ_RESULT(req, bytes); - } else { - error = GetLastError(); - if (error == ERROR_HANDLE_EOF) { - SET_REQ_RESULT(req, bytes); - } else { - SET_REQ_WIN32_ERROR(req, error); - } - } -} - - -void fs__write(uv_fs_t* req) { - int fd = req->file.fd; - int64_t offset = req->fs.info.offset; - HANDLE handle; - OVERLAPPED overlapped, *overlapped_ptr; - LARGE_INTEGER offset_; - DWORD bytes; - int result; - unsigned int index; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (offset != -1) { - memset(&overlapped, 0, sizeof overlapped); - overlapped_ptr = &overlapped; - } else { - overlapped_ptr = NULL; - } - - index = 0; - bytes = 0; - do { - DWORD incremental_bytes; - - if (offset != -1) { - offset_.QuadPart = offset + bytes; - overlapped.Offset = offset_.LowPart; - overlapped.OffsetHigh = offset_.HighPart; - } - - result = WriteFile(handle, - req->fs.info.bufs[index].base, - req->fs.info.bufs[index].len, - &incremental_bytes, - overlapped_ptr); - bytes += incremental_bytes; - ++index; - } while (result && index < req->fs.info.nbufs); - - if (result || bytes > 0) { - SET_REQ_RESULT(req, bytes); - } else { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } -} - - -void fs__rmdir(uv_fs_t* req) { - int result = _wrmdir(req->file.pathw); - SET_REQ_RESULT(req, result); -} - - -void fs__unlink(uv_fs_t* req) { - const WCHAR* pathw = req->file.pathw; - HANDLE handle; - BY_HANDLE_FILE_INFORMATION info; - FILE_DISPOSITION_INFORMATION disposition; - IO_STATUS_BLOCK iosb; - NTSTATUS status; - - handle = CreateFileW(pathw, - FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES | DELETE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (!GetFileInformationByHandle(handle, &info)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - CloseHandle(handle); - return; - } - - if (info.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - /* Do not allow deletion of directories, unless it is a symlink. When */ - /* the path refers to a non-symlink directory, report EPERM as mandated */ - /* by POSIX.1. */ - - /* Check if it is a reparse point. If it's not, it's a normal directory. */ - if (!(info.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) { - SET_REQ_WIN32_ERROR(req, ERROR_ACCESS_DENIED); - CloseHandle(handle); - return; - } - - /* Read the reparse point and check if it is a valid symlink. */ - /* If not, don't unlink. */ - if (fs__readlink_handle(handle, NULL, NULL) < 0) { - DWORD error = GetLastError(); - if (error == ERROR_SYMLINK_NOT_SUPPORTED) - error = ERROR_ACCESS_DENIED; - SET_REQ_WIN32_ERROR(req, error); - CloseHandle(handle); - return; - } - } - - if (info.dwFileAttributes & FILE_ATTRIBUTE_READONLY) { - /* Remove read-only attribute */ - FILE_BASIC_INFORMATION basic = { 0 }; - - basic.FileAttributes = info.dwFileAttributes & ~(FILE_ATTRIBUTE_READONLY); - - status = pNtSetInformationFile(handle, - &iosb, - &basic, - sizeof basic, - FileBasicInformation); - if (!NT_SUCCESS(status)) { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - CloseHandle(handle); - return; - } - } - - /* Try to set the delete flag. */ - disposition.DeleteFile = TRUE; - status = pNtSetInformationFile(handle, - &iosb, - &disposition, - sizeof disposition, - FileDispositionInformation); - if (NT_SUCCESS(status)) { - SET_REQ_SUCCESS(req); - } else { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - } - - CloseHandle(handle); -} - - -void fs__mkdir(uv_fs_t* req) { - /* TODO: use req->mode. */ - int result = _wmkdir(req->file.pathw); - SET_REQ_RESULT(req, result); -} - - -/* OpenBSD original: lib/libc/stdio/mktemp.c */ -void fs__mkdtemp(uv_fs_t* req) { - static const WCHAR *tempchars = - L"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; - static const size_t num_chars = 62; - static const size_t num_x = 6; - WCHAR *cp, *ep; - unsigned int tries, i; - size_t len; - HCRYPTPROV h_crypt_prov; - uint64_t v; - BOOL released; - - len = wcslen(req->file.pathw); - ep = req->file.pathw + len; - if (len < num_x || wcsncmp(ep - num_x, L"XXXXXX", num_x)) { - SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_INVALID_PARAMETER); - return; - } - - if (!CryptAcquireContext(&h_crypt_prov, NULL, NULL, PROV_RSA_FULL, - CRYPT_VERIFYCONTEXT)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - tries = TMP_MAX; - do { - if (!CryptGenRandom(h_crypt_prov, sizeof(v), (BYTE*) &v)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - break; - } - - cp = ep - num_x; - for (i = 0; i < num_x; i++) { - *cp++ = tempchars[v % num_chars]; - v /= num_chars; - } - - if (_wmkdir(req->file.pathw) == 0) { - len = strlen(req->path); - wcstombs((char*) req->path + len - num_x, ep - num_x, num_x); - SET_REQ_RESULT(req, 0); - break; - } else if (errno != EEXIST) { - SET_REQ_RESULT(req, -1); - break; - } - } while (--tries); - - released = CryptReleaseContext(h_crypt_prov, 0); - assert(released); - if (tries == 0) { - SET_REQ_RESULT(req, -1); - } -} - - -void fs__scandir(uv_fs_t* req) { - static const size_t dirents_initial_size = 32; - - HANDLE dir_handle = INVALID_HANDLE_VALUE; - - uv__dirent_t** dirents = NULL; - size_t dirents_size = 0; - size_t dirents_used = 0; - - IO_STATUS_BLOCK iosb; - NTSTATUS status; - - /* Buffer to hold directory entries returned by NtQueryDirectoryFile. - * It's important that this buffer can hold at least one entry, regardless - * of the length of the file names present in the enumerated directory. - * A file name is at most 256 WCHARs long. - * According to MSDN, the buffer must be aligned at an 8-byte boundary. - */ -#if _MSC_VER - __declspec(align(8)) char buffer[8192]; -#else - __attribute__ ((aligned (8))) char buffer[8192]; -#endif - - STATIC_ASSERT(sizeof buffer >= - sizeof(FILE_DIRECTORY_INFORMATION) + 256 * sizeof(WCHAR)); - - /* Open the directory. */ - dir_handle = - CreateFileW(req->file.pathw, - FILE_LIST_DIRECTORY | SYNCHRONIZE, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - if (dir_handle == INVALID_HANDLE_VALUE) - goto win32_error; - - /* Read the first chunk. */ - status = pNtQueryDirectoryFile(dir_handle, - NULL, - NULL, - NULL, - &iosb, - &buffer, - sizeof buffer, - FileDirectoryInformation, - FALSE, - NULL, - TRUE); - - /* If the handle is not a directory, we'll get STATUS_INVALID_PARAMETER. - * This should be reported back as UV_ENOTDIR. - */ - if (status == STATUS_INVALID_PARAMETER) - goto not_a_directory_error; - - while (NT_SUCCESS(status)) { - char* position = buffer; - size_t next_entry_offset = 0; - - do { - FILE_DIRECTORY_INFORMATION* info; - uv__dirent_t* dirent; - - size_t wchar_len; - size_t utf8_len; - - /* Obtain a pointer to the current directory entry. */ - position += next_entry_offset; - info = (FILE_DIRECTORY_INFORMATION*) position; - - /* Fetch the offset to the next directory entry. */ - next_entry_offset = info->NextEntryOffset; - - /* Compute the length of the filename in WCHARs. */ - wchar_len = info->FileNameLength / sizeof info->FileName[0]; - - /* Skip over '.' and '..' entries. */ - if (wchar_len == 1 && info->FileName[0] == L'.') - continue; - if (wchar_len == 2 && info->FileName[0] == L'.' && - info->FileName[1] == L'.') - continue; - - /* Compute the space required to store the filename as UTF-8. */ - utf8_len = WideCharToMultiByte( - CP_UTF8, 0, &info->FileName[0], wchar_len, NULL, 0, NULL, NULL); - if (utf8_len == 0) - goto win32_error; - - /* Resize the dirent array if needed. */ - if (dirents_used >= dirents_size) { - size_t new_dirents_size = - dirents_size == 0 ? dirents_initial_size : dirents_size << 1; - uv__dirent_t** new_dirents = - uv__realloc(dirents, new_dirents_size * sizeof *dirents); - - if (new_dirents == NULL) - goto out_of_memory_error; - - dirents_size = new_dirents_size; - dirents = new_dirents; - } - - /* Allocate space for the uv dirent structure. The dirent structure - * includes room for the first character of the filename, but `utf8_len` - * doesn't count the NULL terminator at this point. - */ - dirent = uv__malloc(sizeof *dirent + utf8_len); - if (dirent == NULL) - goto out_of_memory_error; - - dirents[dirents_used++] = dirent; - - /* Convert file name to UTF-8. */ - if (WideCharToMultiByte(CP_UTF8, - 0, - &info->FileName[0], - wchar_len, - &dirent->d_name[0], - utf8_len, - NULL, - NULL) == 0) - goto win32_error; - - /* Add a null terminator to the filename. */ - dirent->d_name[utf8_len] = '\0'; - - /* Fill out the type field. */ - if (info->FileAttributes & FILE_ATTRIBUTE_DEVICE) - dirent->d_type = UV__DT_CHAR; - else if (info->FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) - dirent->d_type = UV__DT_LINK; - else if (info->FileAttributes & FILE_ATTRIBUTE_DIRECTORY) - dirent->d_type = UV__DT_DIR; - else - dirent->d_type = UV__DT_FILE; - } while (next_entry_offset != 0); - - /* Read the next chunk. */ - status = pNtQueryDirectoryFile(dir_handle, - NULL, - NULL, - NULL, - &iosb, - &buffer, - sizeof buffer, - FileDirectoryInformation, - FALSE, - NULL, - FALSE); - - /* After the first pNtQueryDirectoryFile call, the function may return - * STATUS_SUCCESS even if the buffer was too small to hold at least one - * directory entry. - */ - if (status == STATUS_SUCCESS && iosb.Information == 0) - status = STATUS_BUFFER_OVERFLOW; - } - - if (status != STATUS_NO_MORE_FILES) - goto nt_error; - - CloseHandle(dir_handle); - - /* Store the result in the request object. */ - req->ptr = dirents; - if (dirents != NULL) - req->flags |= UV_FS_FREE_PTR; - - SET_REQ_RESULT(req, dirents_used); - - /* `nbufs` will be used as index by uv_fs_scandir_next. */ - req->fs.info.nbufs = 0; - - return; - -nt_error: - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - goto cleanup; - -win32_error: - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto cleanup; - -not_a_directory_error: - SET_REQ_UV_ERROR(req, UV_ENOTDIR, ERROR_DIRECTORY); - goto cleanup; - -out_of_memory_error: - SET_REQ_UV_ERROR(req, UV_ENOMEM, ERROR_OUTOFMEMORY); - goto cleanup; - -cleanup: - if (dir_handle != INVALID_HANDLE_VALUE) - CloseHandle(dir_handle); - while (dirents_used > 0) - uv__free(dirents[--dirents_used]); - if (dirents != NULL) - uv__free(dirents); -} - - -INLINE static int fs__stat_handle(HANDLE handle, uv_stat_t* statbuf) { - FILE_ALL_INFORMATION file_info; - FILE_FS_VOLUME_INFORMATION volume_info; - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - - nt_status = pNtQueryInformationFile(handle, - &io_status, - &file_info, - sizeof file_info, - FileAllInformation); - - /* Buffer overflow (a warning status code) is expected here. */ - if (NT_ERROR(nt_status)) { - SetLastError(pRtlNtStatusToDosError(nt_status)); - return -1; - } - - nt_status = pNtQueryVolumeInformationFile(handle, - &io_status, - &volume_info, - sizeof volume_info, - FileFsVolumeInformation); - - /* Buffer overflow (a warning status code) is expected here. */ - if (io_status.Status == STATUS_NOT_IMPLEMENTED) { - statbuf->st_dev = 0; - } else if (NT_ERROR(nt_status)) { - SetLastError(pRtlNtStatusToDosError(nt_status)); - return -1; - } else { - statbuf->st_dev = volume_info.VolumeSerialNumber; - } - - /* Todo: st_mode should probably always be 0666 for everyone. We might also - * want to report 0777 if the file is a .exe or a directory. - * - * Currently it's based on whether the 'readonly' attribute is set, which - * makes little sense because the semantics are so different: the 'read-only' - * flag is just a way for a user to protect against accidental deletion, and - * serves no security purpose. Windows uses ACLs for that. - * - * Also people now use uv_fs_chmod() to take away the writable bit for good - * reasons. Windows however just makes the file read-only, which makes it - * impossible to delete the file afterwards, since read-only files can't be - * deleted. - * - * IOW it's all just a clusterfuck and we should think of something that - * makes slightly more sense. - * - * And uv_fs_chmod should probably just fail on windows or be a total no-op. - * There's nothing sensible it can do anyway. - */ - statbuf->st_mode = 0; - - if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) { - statbuf->st_mode |= S_IFLNK; - if (fs__readlink_handle(handle, NULL, &statbuf->st_size) != 0) - return -1; - - } else if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_DIRECTORY) { - statbuf->st_mode |= _S_IFDIR; - statbuf->st_size = 0; - - } else { - statbuf->st_mode |= _S_IFREG; - statbuf->st_size = file_info.StandardInformation.EndOfFile.QuadPart; - } - - if (file_info.BasicInformation.FileAttributes & FILE_ATTRIBUTE_READONLY) - statbuf->st_mode |= _S_IREAD | (_S_IREAD >> 3) | (_S_IREAD >> 6); - else - statbuf->st_mode |= (_S_IREAD | _S_IWRITE) | ((_S_IREAD | _S_IWRITE) >> 3) | - ((_S_IREAD | _S_IWRITE) >> 6); - - FILETIME_TO_TIMESPEC(statbuf->st_atim, file_info.BasicInformation.LastAccessTime); - FILETIME_TO_TIMESPEC(statbuf->st_ctim, file_info.BasicInformation.ChangeTime); - FILETIME_TO_TIMESPEC(statbuf->st_mtim, file_info.BasicInformation.LastWriteTime); - FILETIME_TO_TIMESPEC(statbuf->st_birthtim, file_info.BasicInformation.CreationTime); - - statbuf->st_ino = file_info.InternalInformation.IndexNumber.QuadPart; - - /* st_blocks contains the on-disk allocation size in 512-byte units. */ - statbuf->st_blocks = - file_info.StandardInformation.AllocationSize.QuadPart >> 9ULL; - - statbuf->st_nlink = file_info.StandardInformation.NumberOfLinks; - - /* The st_blksize is supposed to be the 'optimal' number of bytes for reading - * and writing to the disk. That is, for any definition of 'optimal' - it's - * supposed to at least avoid read-update-write behavior when writing to the - * disk. - * - * However nobody knows this and even fewer people actually use this value, - * and in order to fill it out we'd have to make another syscall to query the - * volume for FILE_FS_SECTOR_SIZE_INFORMATION. - * - * Therefore we'll just report a sensible value that's quite commonly okay - * on modern hardware. - */ - statbuf->st_blksize = 2048; - - /* Todo: set st_flags to something meaningful. Also provide a wrapper for - * chattr(2). - */ - statbuf->st_flags = 0; - - /* Windows has nothing sensible to say about these values, so they'll just - * remain empty. - */ - statbuf->st_gid = 0; - statbuf->st_uid = 0; - statbuf->st_rdev = 0; - statbuf->st_gen = 0; - - return 0; -} - - -INLINE static void fs__stat_prepare_path(WCHAR* pathw) { - size_t len = wcslen(pathw); - - /* TODO: ignore namespaced paths. */ - if (len > 1 && pathw[len - 2] != L':' && - (pathw[len - 1] == L'\\' || pathw[len - 1] == L'/')) { - pathw[len - 1] = '\0'; - } -} - - -INLINE static void fs__stat_impl(uv_fs_t* req, int do_lstat) { - HANDLE handle; - DWORD flags; - - flags = FILE_FLAG_BACKUP_SEMANTICS; - if (do_lstat) { - flags |= FILE_FLAG_OPEN_REPARSE_POINT; - } - - handle = CreateFileW(req->file.pathw, - FILE_READ_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - flags, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (fs__stat_handle(handle, &req->statbuf) != 0) { - DWORD error = GetLastError(); - if (do_lstat && error == ERROR_SYMLINK_NOT_SUPPORTED) { - /* We opened a reparse point but it was not a symlink. Try again. */ - fs__stat_impl(req, 0); - - } else { - /* Stat failed. */ - SET_REQ_WIN32_ERROR(req, GetLastError()); - } - - CloseHandle(handle); - return; - } - - req->ptr = &req->statbuf; - req->result = 0; - CloseHandle(handle); -} - - -static void fs__stat(uv_fs_t* req) { - fs__stat_prepare_path(req->file.pathw); - fs__stat_impl(req, 0); -} - - -static void fs__lstat(uv_fs_t* req) { - fs__stat_prepare_path(req->file.pathw); - fs__stat_impl(req, 1); -} - - -static void fs__fstat(uv_fs_t* req) { - int fd = req->file.fd; - HANDLE handle; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (fs__stat_handle(handle, &req->statbuf) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - req->ptr = &req->statbuf; - req->result = 0; -} - - -static void fs__rename(uv_fs_t* req) { - if (!MoveFileExW(req->file.pathw, req->fs.info.new_pathw, MOVEFILE_REPLACE_EXISTING)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - SET_REQ_RESULT(req, 0); -} - - -INLINE static void fs__sync_impl(uv_fs_t* req) { - int fd = req->file.fd; - int result; - - VERIFY_FD(fd, req); - - result = FlushFileBuffers(uv__get_osfhandle(fd)) ? 0 : -1; - if (result == -1) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } else { - SET_REQ_RESULT(req, result); - } -} - - -static void fs__fsync(uv_fs_t* req) { - fs__sync_impl(req); -} - - -static void fs__fdatasync(uv_fs_t* req) { - fs__sync_impl(req); -} - - -static void fs__ftruncate(uv_fs_t* req) { - int fd = req->file.fd; - HANDLE handle; - NTSTATUS status; - IO_STATUS_BLOCK io_status; - FILE_END_OF_FILE_INFORMATION eof_info; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - eof_info.EndOfFile.QuadPart = req->fs.info.offset; - - status = pNtSetInformationFile(handle, - &io_status, - &eof_info, - sizeof eof_info, - FileEndOfFileInformation); - - if (NT_SUCCESS(status)) { - SET_REQ_RESULT(req, 0); - } else { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(status)); - } -} - - -static void fs__sendfile(uv_fs_t* req) { - int fd_in = req->file.fd, fd_out = req->fs.info.fd_out; - size_t length = req->fs.info.bufsml[0].len; - int64_t offset = req->fs.info.offset; - const size_t max_buf_size = 65536; - size_t buf_size = length < max_buf_size ? length : max_buf_size; - int n, result = 0; - int64_t result_offset = 0; - char* buf = (char*) uv__malloc(buf_size); - if (!buf) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - if (offset != -1) { - result_offset = _lseeki64(fd_in, offset, SEEK_SET); - } - - if (result_offset == -1) { - result = -1; - } else { - while (length > 0) { - n = _read(fd_in, buf, length < buf_size ? length : buf_size); - if (n == 0) { - break; - } else if (n == -1) { - result = -1; - break; - } - - length -= n; - - n = _write(fd_out, buf, n); - if (n == -1) { - result = -1; - break; - } - - result += n; - } - } - - uv__free(buf); - - SET_REQ_RESULT(req, result); -} - - -static void fs__access(uv_fs_t* req) { - DWORD attr = GetFileAttributesW(req->file.pathw); - - if (attr == INVALID_FILE_ATTRIBUTES) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - /* - * Access is possible if - * - write access wasn't requested, - * - or the file isn't read-only, - * - or it's a directory. - * (Directories cannot be read-only on Windows.) - */ - if (!(req->flags & W_OK) || - !(attr & FILE_ATTRIBUTE_READONLY) || - (attr & FILE_ATTRIBUTE_DIRECTORY)) { - SET_REQ_RESULT(req, 0); - } else { - SET_REQ_WIN32_ERROR(req, UV_EPERM); - } - -} - - -static void fs__chmod(uv_fs_t* req) { - int result = _wchmod(req->file.pathw, req->fs.info.mode); - SET_REQ_RESULT(req, result); -} - - -static void fs__fchmod(uv_fs_t* req) { - int fd = req->file.fd; - HANDLE handle; - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_BASIC_INFORMATION file_info; - - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - nt_status = pNtQueryInformationFile(handle, - &io_status, - &file_info, - sizeof file_info, - FileBasicInformation); - - if (!NT_SUCCESS(nt_status)) { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status)); - return; - } - - if (req->fs.info.mode & _S_IWRITE) { - file_info.FileAttributes &= ~FILE_ATTRIBUTE_READONLY; - } else { - file_info.FileAttributes |= FILE_ATTRIBUTE_READONLY; - } - - nt_status = pNtSetInformationFile(handle, - &io_status, - &file_info, - sizeof file_info, - FileBasicInformation); - - if (!NT_SUCCESS(nt_status)) { - SET_REQ_WIN32_ERROR(req, pRtlNtStatusToDosError(nt_status)); - return; - } - - SET_REQ_SUCCESS(req); -} - - -INLINE static int fs__utime_handle(HANDLE handle, double atime, double mtime) { - FILETIME filetime_a, filetime_m; - - TIME_T_TO_FILETIME((time_t) atime, &filetime_a); - TIME_T_TO_FILETIME((time_t) mtime, &filetime_m); - - if (!SetFileTime(handle, NULL, &filetime_a, &filetime_m)) { - return -1; - } - - return 0; -} - - -static void fs__utime(uv_fs_t* req) { - HANDLE handle; - - handle = CreateFileW(req->file.pathw, - FILE_WRITE_ATTRIBUTES, - FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - CloseHandle(handle); - return; - } - - CloseHandle(handle); - - req->result = 0; -} - - -static void fs__futime(uv_fs_t* req) { - int fd = req->file.fd; - HANDLE handle; - VERIFY_FD(fd, req); - - handle = uv__get_osfhandle(fd); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, ERROR_INVALID_HANDLE); - return; - } - - if (fs__utime_handle(handle, req->fs.time.atime, req->fs.time.mtime) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - req->result = 0; -} - - -static void fs__link(uv_fs_t* req) { - DWORD r = CreateHardLinkW(req->fs.info.new_pathw, req->file.pathw, NULL); - if (r == 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } else { - req->result = 0; - } -} - - -static void fs__create_junction(uv_fs_t* req, const WCHAR* path, - const WCHAR* new_path) { - HANDLE handle = INVALID_HANDLE_VALUE; - REPARSE_DATA_BUFFER *buffer = NULL; - int created = 0; - int target_len; - int is_absolute, is_long_path; - int needed_buf_size, used_buf_size, used_data_size, path_buf_len; - int start, len, i; - int add_slash; - DWORD bytes; - WCHAR* path_buf; - - target_len = wcslen(path); - is_long_path = wcsncmp(path, LONG_PATH_PREFIX, LONG_PATH_PREFIX_LEN) == 0; - - if (is_long_path) { - is_absolute = 1; - } else { - is_absolute = target_len >= 3 && IS_LETTER(path[0]) && - path[1] == L':' && IS_SLASH(path[2]); - } - - if (!is_absolute) { - /* Not supporting relative paths */ - SET_REQ_UV_ERROR(req, UV_EINVAL, ERROR_NOT_SUPPORTED); - return; - } - - /* Do a pessimistic calculation of the required buffer size */ - needed_buf_size = - FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + - JUNCTION_PREFIX_LEN * sizeof(WCHAR) + - 2 * (target_len + 2) * sizeof(WCHAR); - - /* Allocate the buffer */ - buffer = (REPARSE_DATA_BUFFER*)uv__malloc(needed_buf_size); - if (!buffer) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - /* Grab a pointer to the part of the buffer where filenames go */ - path_buf = (WCHAR*)&(buffer->MountPointReparseBuffer.PathBuffer); - path_buf_len = 0; - - /* Copy the substitute (internal) target path */ - start = path_buf_len; - - wcsncpy((WCHAR*)&path_buf[path_buf_len], JUNCTION_PREFIX, - JUNCTION_PREFIX_LEN); - path_buf_len += JUNCTION_PREFIX_LEN; - - add_slash = 0; - for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) { - if (IS_SLASH(path[i])) { - add_slash = 1; - continue; - } - - if (add_slash) { - path_buf[path_buf_len++] = L'\\'; - add_slash = 0; - } - - path_buf[path_buf_len++] = path[i]; - } - path_buf[path_buf_len++] = L'\\'; - len = path_buf_len - start; - - /* Set the info about the substitute name */ - buffer->MountPointReparseBuffer.SubstituteNameOffset = start * sizeof(WCHAR); - buffer->MountPointReparseBuffer.SubstituteNameLength = len * sizeof(WCHAR); - - /* Insert null terminator */ - path_buf[path_buf_len++] = L'\0'; - - /* Copy the print name of the target path */ - start = path_buf_len; - add_slash = 0; - for (i = is_long_path ? LONG_PATH_PREFIX_LEN : 0; path[i] != L'\0'; i++) { - if (IS_SLASH(path[i])) { - add_slash = 1; - continue; - } - - if (add_slash) { - path_buf[path_buf_len++] = L'\\'; - add_slash = 0; - } - - path_buf[path_buf_len++] = path[i]; - } - len = path_buf_len - start; - if (len == 2) { - path_buf[path_buf_len++] = L'\\'; - len++; - } - - /* Set the info about the print name */ - buffer->MountPointReparseBuffer.PrintNameOffset = start * sizeof(WCHAR); - buffer->MountPointReparseBuffer.PrintNameLength = len * sizeof(WCHAR); - - /* Insert another null terminator */ - path_buf[path_buf_len++] = L'\0'; - - /* Calculate how much buffer space was actually used */ - used_buf_size = FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer.PathBuffer) + - path_buf_len * sizeof(WCHAR); - used_data_size = used_buf_size - - FIELD_OFFSET(REPARSE_DATA_BUFFER, MountPointReparseBuffer); - - /* Put general info in the data buffer */ - buffer->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - buffer->ReparseDataLength = used_data_size; - buffer->Reserved = 0; - - /* Create a new directory */ - if (!CreateDirectoryW(new_path, NULL)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto error; - } - created = 1; - - /* Open the directory */ - handle = CreateFileW(new_path, - GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_BACKUP_SEMANTICS | - FILE_FLAG_OPEN_REPARSE_POINT, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto error; - } - - /* Create the actual reparse point */ - if (!DeviceIoControl(handle, - FSCTL_SET_REPARSE_POINT, - buffer, - used_buf_size, - NULL, - 0, - &bytes, - NULL)) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - goto error; - } - - /* Clean up */ - CloseHandle(handle); - uv__free(buffer); - - SET_REQ_RESULT(req, 0); - return; - -error: - uv__free(buffer); - - if (handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle); - } - - if (created) { - RemoveDirectoryW(new_path); - } -} - - -static void fs__symlink(uv_fs_t* req) { - WCHAR* pathw = req->file.pathw; - WCHAR* new_pathw = req->fs.info.new_pathw; - int flags = req->fs.info.file_flags; - int result; - - - if (flags & UV_FS_SYMLINK_JUNCTION) { - fs__create_junction(req, pathw, new_pathw); - } else if (pCreateSymbolicLinkW) { - result = pCreateSymbolicLinkW(new_pathw, - pathw, - flags & UV_FS_SYMLINK_DIR ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0) ? 0 : -1; - if (result == -1) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - } else { - SET_REQ_RESULT(req, result); - } - } else { - SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED); - } -} - - -static void fs__readlink(uv_fs_t* req) { - HANDLE handle; - - handle = CreateFileW(req->file.pathw, - 0, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, - NULL); - - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (fs__readlink_handle(handle, (char**) &req->ptr, NULL) != 0) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - CloseHandle(handle); - return; - } - - req->flags |= UV_FS_FREE_PTR; - SET_REQ_RESULT(req, 0); - - CloseHandle(handle); -} - - -static size_t fs__realpath_handle(HANDLE handle, char** realpath_ptr) { - int r; - DWORD w_realpath_len; - WCHAR* w_realpath_ptr = NULL; - WCHAR* w_realpath_buf; - - w_realpath_len = pGetFinalPathNameByHandleW(handle, NULL, 0, VOLUME_NAME_DOS); - if (w_realpath_len == 0) { - return -1; - } - - w_realpath_buf = uv__malloc((w_realpath_len + 1) * sizeof(WCHAR)); - if (w_realpath_buf == NULL) { - SetLastError(ERROR_OUTOFMEMORY); - return -1; - } - w_realpath_ptr = w_realpath_buf; - - if (pGetFinalPathNameByHandleW(handle, - w_realpath_ptr, - w_realpath_len, - VOLUME_NAME_DOS) == 0) { - uv__free(w_realpath_buf); - SetLastError(ERROR_INVALID_HANDLE); - return -1; - } - - /* convert UNC path to long path */ - if (wcsncmp(w_realpath_ptr, - UNC_PATH_PREFIX, - UNC_PATH_PREFIX_LEN) == 0) { - w_realpath_ptr += 6; - *w_realpath_ptr = L'\\'; - w_realpath_len -= 6; - } else if (wcsncmp(w_realpath_ptr, - LONG_PATH_PREFIX, - LONG_PATH_PREFIX_LEN) == 0) { - w_realpath_ptr += 4; - w_realpath_len -= 4; - } else { - uv__free(w_realpath_buf); - SetLastError(ERROR_INVALID_HANDLE); - return -1; - } - - r = fs__wide_to_utf8(w_realpath_ptr, w_realpath_len, realpath_ptr, NULL); - uv__free(w_realpath_buf); - return r; -} - -static void fs__realpath(uv_fs_t* req) { - HANDLE handle; - - if (!pGetFinalPathNameByHandleW) { - SET_REQ_UV_ERROR(req, UV_ENOSYS, ERROR_NOT_SUPPORTED); - return; - } - - handle = CreateFileW(req->file.pathw, - 0, - 0, - NULL, - OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - if (fs__realpath_handle(handle, (char**) &req->ptr) == -1) { - CloseHandle(handle); - SET_REQ_WIN32_ERROR(req, GetLastError()); - return; - } - - CloseHandle(handle); - req->flags |= UV_FS_FREE_PTR; - SET_REQ_RESULT(req, 0); -} - - -static void fs__chown(uv_fs_t* req) { - req->result = 0; -} - - -static void fs__fchown(uv_fs_t* req) { - req->result = 0; -} - - -static void uv__fs_work(struct uv__work* w) { - uv_fs_t* req; - - req = container_of(w, uv_fs_t, work_req); - assert(req->type == UV_FS); - -#define XX(uc, lc) case UV_FS_##uc: fs__##lc(req); break; - switch (req->fs_type) { - XX(OPEN, open) - XX(CLOSE, close) - XX(READ, read) - XX(WRITE, write) - XX(SENDFILE, sendfile) - XX(STAT, stat) - XX(LSTAT, lstat) - XX(FSTAT, fstat) - XX(FTRUNCATE, ftruncate) - XX(UTIME, utime) - XX(FUTIME, futime) - XX(ACCESS, access) - XX(CHMOD, chmod) - XX(FCHMOD, fchmod) - XX(FSYNC, fsync) - XX(FDATASYNC, fdatasync) - XX(UNLINK, unlink) - XX(RMDIR, rmdir) - XX(MKDIR, mkdir) - XX(MKDTEMP, mkdtemp) - XX(RENAME, rename) - XX(SCANDIR, scandir) - XX(LINK, link) - XX(SYMLINK, symlink) - XX(READLINK, readlink) - XX(REALPATH, realpath) - XX(CHOWN, chown) - XX(FCHOWN, fchown); - default: - assert(!"bad uv_fs_type"); - } -} - - -static void uv__fs_done(struct uv__work* w, int status) { - uv_fs_t* req; - - req = container_of(w, uv_fs_t, work_req); - uv__req_unregister(req->loop, req); - - if (status == UV_ECANCELED) { - assert(req->result == 0); - req->result = UV_ECANCELED; - } - - req->cb(req); -} - - -void uv_fs_req_cleanup(uv_fs_t* req) { - if (req->flags & UV_FS_CLEANEDUP) - return; - - if (req->flags & UV_FS_FREE_PATHS) - uv__free(req->file.pathw); - - if (req->flags & UV_FS_FREE_PTR) - uv__free(req->ptr); - - req->path = NULL; - req->file.pathw = NULL; - req->fs.info.new_pathw = NULL; - req->ptr = NULL; - - req->flags |= UV_FS_CLEANEDUP; -} - - -int uv_fs_open(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, - int mode, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_OPEN, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.info.file_flags = flags; - req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__open(req); - return req->result; - } -} - - -int uv_fs_close(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_CLOSE, cb); - req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__close(req); - return req->result; - } -} - - -int uv_fs_read(uv_loop_t* loop, - uv_fs_t* req, - uv_file fd, - const uv_buf_t bufs[], - unsigned int nbufs, - int64_t offset, - uv_fs_cb cb) { - if (bufs == NULL || nbufs == 0) - return UV_EINVAL; - - uv_fs_req_init(loop, req, UV_FS_READ, cb); - - req->file.fd = fd; - - req->fs.info.nbufs = nbufs; - req->fs.info.bufs = req->fs.info.bufsml; - if (nbufs > ARRAY_SIZE(req->fs.info.bufsml)) - req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs)); - - if (req->fs.info.bufs == NULL) - return UV_ENOMEM; - - memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs)); - - req->fs.info.offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__read(req); - return req->result; - } -} - - -int uv_fs_write(uv_loop_t* loop, - uv_fs_t* req, - uv_file fd, - const uv_buf_t bufs[], - unsigned int nbufs, - int64_t offset, - uv_fs_cb cb) { - if (bufs == NULL || nbufs == 0) - return UV_EINVAL; - - uv_fs_req_init(loop, req, UV_FS_WRITE, cb); - - req->file.fd = fd; - - req->fs.info.nbufs = nbufs; - req->fs.info.bufs = req->fs.info.bufsml; - if (nbufs > ARRAY_SIZE(req->fs.info.bufsml)) - req->fs.info.bufs = uv__malloc(nbufs * sizeof(*bufs)); - - if (req->fs.info.bufs == NULL) - return UV_ENOMEM; - - memcpy(req->fs.info.bufs, bufs, nbufs * sizeof(*bufs)); - - req->fs.info.offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__write(req); - return req->result; - } -} - - -int uv_fs_unlink(uv_loop_t* loop, uv_fs_t* req, const char* path, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_UNLINK, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__unlink(req); - return req->result; - } -} - - -int uv_fs_mkdir(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_MKDIR, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__mkdir(req); - return req->result; - } -} - - -int uv_fs_mkdtemp(uv_loop_t* loop, uv_fs_t* req, const char* tpl, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_MKDTEMP, cb); - - err = fs__capture_path(req, tpl, NULL, TRUE); - if (err) - return uv_translate_sys_error(err); - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__mkdtemp(req); - return req->result; - } -} - - -int uv_fs_rmdir(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_RMDIR, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__rmdir(req); - return req->result; - } -} - - -int uv_fs_scandir(uv_loop_t* loop, uv_fs_t* req, const char* path, int flags, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_SCANDIR, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.info.file_flags = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__scandir(req); - return req->result; - } -} - - -int uv_fs_link(uv_loop_t* loop, uv_fs_t* req, const char* path, - const char* new_path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_LINK, cb); - - err = fs__capture_path(req, path, new_path, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__link(req); - return req->result; - } -} - - -int uv_fs_symlink(uv_loop_t* loop, uv_fs_t* req, const char* path, - const char* new_path, int flags, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_SYMLINK, cb); - - err = fs__capture_path(req, path, new_path, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.info.file_flags = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__symlink(req); - return req->result; - } -} - - -int uv_fs_readlink(uv_loop_t* loop, uv_fs_t* req, const char* path, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_READLINK, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__readlink(req); - return req->result; - } -} - - -int uv_fs_realpath(uv_loop_t* loop, uv_fs_t* req, const char* path, - uv_fs_cb cb) { - int err; - - if (!req || !path) { - return UV_EINVAL; - } - - uv_fs_req_init(loop, req, UV_FS_REALPATH, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__realpath(req); - return req->result; - } -} - - -int uv_fs_chown(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_uid_t uid, - uv_gid_t gid, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_CHOWN, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__chown(req); - return req->result; - } -} - - -int uv_fs_fchown(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_uid_t uid, - uv_gid_t gid, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FCHOWN, cb); - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fchown(req); - return req->result; - } -} - - -int uv_fs_stat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_STAT, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__stat(req); - return req->result; - } -} - - -int uv_fs_lstat(uv_loop_t* loop, uv_fs_t* req, const char* path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_LSTAT, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__lstat(req); - return req->result; - } -} - - -int uv_fs_fstat(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FSTAT, cb); - req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fstat(req); - return req->result; - } -} - - -int uv_fs_rename(uv_loop_t* loop, uv_fs_t* req, const char* path, - const char* new_path, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_RENAME, cb); - - err = fs__capture_path(req, path, new_path, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__rename(req); - return req->result; - } -} - - -int uv_fs_fsync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FSYNC, cb); - req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fsync(req); - return req->result; - } -} - - -int uv_fs_fdatasync(uv_loop_t* loop, uv_fs_t* req, uv_file fd, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FDATASYNC, cb); - req->file.fd = fd; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fdatasync(req); - return req->result; - } -} - - -int uv_fs_ftruncate(uv_loop_t* loop, uv_fs_t* req, uv_file fd, - int64_t offset, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FTRUNCATE, cb); - - req->file.fd = fd; - req->fs.info.offset = offset; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__ftruncate(req); - return req->result; - } -} - - - -int uv_fs_sendfile(uv_loop_t* loop, uv_fs_t* req, uv_file fd_out, - uv_file fd_in, int64_t in_offset, size_t length, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_SENDFILE, cb); - - req->file.fd = fd_in; - req->fs.info.fd_out = fd_out; - req->fs.info.offset = in_offset; - req->fs.info.bufsml[0].len = length; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__sendfile(req); - return req->result; - } -} - - -int uv_fs_access(uv_loop_t* loop, - uv_fs_t* req, - const char* path, - int flags, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_ACCESS, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) - return uv_translate_sys_error(err); - - req->flags = flags; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } - - fs__access(req); - return req->result; -} - - -int uv_fs_chmod(uv_loop_t* loop, uv_fs_t* req, const char* path, int mode, - uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_CHMOD, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__chmod(req); - return req->result; - } -} - - -int uv_fs_fchmod(uv_loop_t* loop, uv_fs_t* req, uv_file fd, int mode, - uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FCHMOD, cb); - - req->file.fd = fd; - req->fs.info.mode = mode; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__fchmod(req); - return req->result; - } -} - - -int uv_fs_utime(uv_loop_t* loop, uv_fs_t* req, const char* path, double atime, - double mtime, uv_fs_cb cb) { - int err; - - uv_fs_req_init(loop, req, UV_FS_UTIME, cb); - - err = fs__capture_path(req, path, NULL, cb != NULL); - if (err) { - return uv_translate_sys_error(err); - } - - req->fs.time.atime = atime; - req->fs.time.mtime = mtime; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__utime(req); - return req->result; - } -} - - -int uv_fs_futime(uv_loop_t* loop, uv_fs_t* req, uv_file fd, double atime, - double mtime, uv_fs_cb cb) { - uv_fs_req_init(loop, req, UV_FS_FUTIME, cb); - - req->file.fd = fd; - req->fs.time.atime = atime; - req->fs.time.mtime = mtime; - - if (cb) { - QUEUE_FS_TP_JOB(loop, req); - return 0; - } else { - fs__futime(req); - return req->result; - } -} diff --git a/3rdparty/libuv/src/win/getaddrinfo.c b/3rdparty/libuv/src/win/getaddrinfo.c deleted file mode 100644 index 744f8e02629..00000000000 --- a/3rdparty/libuv/src/win/getaddrinfo.c +++ /dev/null @@ -1,385 +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. - */ - -#include <assert.h> - -#include "uv.h" -#include "internal.h" -#include "req-inl.h" - -/* EAI_* constants. */ -#include <winsock2.h> - - -int uv__getaddrinfo_translate_error(int sys_err) { - switch (sys_err) { - case 0: return 0; - case WSATRY_AGAIN: return UV_EAI_AGAIN; - case WSAEINVAL: return UV_EAI_BADFLAGS; - case WSANO_RECOVERY: return UV_EAI_FAIL; - case WSAEAFNOSUPPORT: return UV_EAI_FAMILY; - case WSA_NOT_ENOUGH_MEMORY: return UV_EAI_MEMORY; - case WSAHOST_NOT_FOUND: return UV_EAI_NONAME; - case WSATYPE_NOT_FOUND: return UV_EAI_SERVICE; - case WSAESOCKTNOSUPPORT: return UV_EAI_SOCKTYPE; - default: return uv_translate_sys_error(sys_err); - } -} - - -/* - * MinGW is missing this - */ -#if !defined(_MSC_VER) && !defined(__MINGW64_VERSION_MAJOR) - typedef struct addrinfoW { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - size_t ai_addrlen; - WCHAR* ai_canonname; - struct sockaddr* ai_addr; - struct addrinfoW* ai_next; - } ADDRINFOW, *PADDRINFOW; - - DECLSPEC_IMPORT int WSAAPI GetAddrInfoW(const WCHAR* node, - const WCHAR* service, - const ADDRINFOW* hints, - PADDRINFOW* result); - - DECLSPEC_IMPORT void WSAAPI FreeAddrInfoW(PADDRINFOW pAddrInfo); -#endif - - -/* adjust size value to be multiple of 4. Use to keep pointer aligned */ -/* Do we need different versions of this for different architectures? */ -#define ALIGNED_SIZE(X) ((((X) + 3) >> 2) << 2) - - -static void uv__getaddrinfo_work(struct uv__work* w) { - uv_getaddrinfo_t* req; - struct addrinfoW* hints; - int err; - - req = container_of(w, uv_getaddrinfo_t, work_req); - hints = req->addrinfow; - req->addrinfow = NULL; - err = GetAddrInfoW(req->node, req->service, hints, &req->addrinfow); - req->retcode = uv__getaddrinfo_translate_error(err); -} - - -/* - * Called from uv_run when complete. Call user specified callback - * then free returned addrinfo - * Returned addrinfo strings are converted from UTF-16 to UTF-8. - * - * To minimize allocation we calculate total size required, - * and copy all structs and referenced strings into the one block. - * Each size calculation is adjusted to avoid unaligned pointers. - */ -static void uv__getaddrinfo_done(struct uv__work* w, int status) { - uv_getaddrinfo_t* req; - int addrinfo_len = 0; - int name_len = 0; - size_t addrinfo_struct_len = ALIGNED_SIZE(sizeof(struct addrinfo)); - struct addrinfoW* addrinfow_ptr; - struct addrinfo* addrinfo_ptr; - char* alloc_ptr = NULL; - char* cur_ptr = NULL; - - req = container_of(w, uv_getaddrinfo_t, work_req); - - /* release input parameter memory */ - uv__free(req->alloc); - req->alloc = NULL; - - if (status == UV_ECANCELED) { - assert(req->retcode == 0); - req->retcode = UV_EAI_CANCELED; - goto complete; - } - - if (req->retcode == 0) { - /* convert addrinfoW to addrinfo */ - /* first calculate required length */ - addrinfow_ptr = req->addrinfow; - while (addrinfow_ptr != NULL) { - addrinfo_len += addrinfo_struct_len + - ALIGNED_SIZE(addrinfow_ptr->ai_addrlen); - if (addrinfow_ptr->ai_canonname != NULL) { - name_len = WideCharToMultiByte(CP_UTF8, - 0, - addrinfow_ptr->ai_canonname, - -1, - NULL, - 0, - NULL, - NULL); - if (name_len == 0) { - req->retcode = uv_translate_sys_error(GetLastError()); - goto complete; - } - addrinfo_len += ALIGNED_SIZE(name_len); - } - addrinfow_ptr = addrinfow_ptr->ai_next; - } - - /* allocate memory for addrinfo results */ - alloc_ptr = (char*)uv__malloc(addrinfo_len); - - /* do conversions */ - if (alloc_ptr != NULL) { - cur_ptr = alloc_ptr; - addrinfow_ptr = req->addrinfow; - - while (addrinfow_ptr != NULL) { - /* copy addrinfo struct data */ - assert(cur_ptr + addrinfo_struct_len <= alloc_ptr + addrinfo_len); - addrinfo_ptr = (struct addrinfo*)cur_ptr; - addrinfo_ptr->ai_family = addrinfow_ptr->ai_family; - addrinfo_ptr->ai_socktype = addrinfow_ptr->ai_socktype; - addrinfo_ptr->ai_protocol = addrinfow_ptr->ai_protocol; - addrinfo_ptr->ai_flags = addrinfow_ptr->ai_flags; - addrinfo_ptr->ai_addrlen = addrinfow_ptr->ai_addrlen; - addrinfo_ptr->ai_canonname = NULL; - addrinfo_ptr->ai_addr = NULL; - addrinfo_ptr->ai_next = NULL; - - cur_ptr += addrinfo_struct_len; - - /* copy sockaddr */ - if (addrinfo_ptr->ai_addrlen > 0) { - assert(cur_ptr + addrinfo_ptr->ai_addrlen <= - alloc_ptr + addrinfo_len); - memcpy(cur_ptr, addrinfow_ptr->ai_addr, addrinfo_ptr->ai_addrlen); - addrinfo_ptr->ai_addr = (struct sockaddr*)cur_ptr; - cur_ptr += ALIGNED_SIZE(addrinfo_ptr->ai_addrlen); - } - - /* convert canonical name to UTF-8 */ - if (addrinfow_ptr->ai_canonname != NULL) { - name_len = WideCharToMultiByte(CP_UTF8, - 0, - addrinfow_ptr->ai_canonname, - -1, - NULL, - 0, - NULL, - NULL); - assert(name_len > 0); - assert(cur_ptr + name_len <= alloc_ptr + addrinfo_len); - name_len = WideCharToMultiByte(CP_UTF8, - 0, - addrinfow_ptr->ai_canonname, - -1, - cur_ptr, - name_len, - NULL, - NULL); - assert(name_len > 0); - addrinfo_ptr->ai_canonname = cur_ptr; - cur_ptr += ALIGNED_SIZE(name_len); - } - assert(cur_ptr <= alloc_ptr + addrinfo_len); - - /* set next ptr */ - addrinfow_ptr = addrinfow_ptr->ai_next; - if (addrinfow_ptr != NULL) { - addrinfo_ptr->ai_next = (struct addrinfo*)cur_ptr; - } - } - req->addrinfo = (struct addrinfo*)alloc_ptr; - } else { - req->retcode = UV_EAI_MEMORY; - } - } - - /* return memory to system */ - if (req->addrinfow != NULL) { - FreeAddrInfoW(req->addrinfow); - req->addrinfow = NULL; - } - -complete: - uv__req_unregister(req->loop, req); - - /* finally do callback with converted result */ - if (req->getaddrinfo_cb) - req->getaddrinfo_cb(req, req->retcode, req->addrinfo); -} - - -void uv_freeaddrinfo(struct addrinfo* ai) { - char* alloc_ptr = (char*)ai; - - /* release copied result memory */ - uv__free(alloc_ptr); -} - - -/* - * Entry point for getaddrinfo - * we convert the UTF-8 strings to UNICODE - * and save the UNICODE string pointers in the req - * We also copy hints so that caller does not need to keep memory until the - * callback. - * return 0 if a callback will be made - * return error code if validation fails - * - * To minimize allocation we calculate total size required, - * and copy all structs and referenced strings into the one block. - * Each size calculation is adjusted to avoid unaligned pointers. - */ -int uv_getaddrinfo(uv_loop_t* loop, - uv_getaddrinfo_t* req, - uv_getaddrinfo_cb getaddrinfo_cb, - const char* node, - const char* service, - const struct addrinfo* hints) { - int nodesize = 0; - int servicesize = 0; - int hintssize = 0; - char* alloc_ptr = NULL; - int err; - - if (req == NULL || (node == NULL && service == NULL)) { - err = WSAEINVAL; - goto error; - } - - uv_req_init(loop, (uv_req_t*)req); - - req->getaddrinfo_cb = getaddrinfo_cb; - req->addrinfo = NULL; - req->type = UV_GETADDRINFO; - req->loop = loop; - req->retcode = 0; - - /* calculate required memory size for all input values */ - if (node != NULL) { - nodesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, 0, node, -1, NULL, 0) * - sizeof(WCHAR)); - if (nodesize == 0) { - err = GetLastError(); - goto error; - } - } - - if (service != NULL) { - servicesize = ALIGNED_SIZE(MultiByteToWideChar(CP_UTF8, - 0, - service, - -1, - NULL, - 0) * - sizeof(WCHAR)); - if (servicesize == 0) { - err = GetLastError(); - goto error; - } - } - if (hints != NULL) { - hintssize = ALIGNED_SIZE(sizeof(struct addrinfoW)); - } - - /* allocate memory for inputs, and partition it as needed */ - alloc_ptr = (char*)uv__malloc(nodesize + servicesize + hintssize); - if (!alloc_ptr) { - err = WSAENOBUFS; - goto error; - } - - /* save alloc_ptr now so we can free if error */ - req->alloc = (void*)alloc_ptr; - - /* convert node string to UTF16 into allocated memory and save pointer in */ - /* the request. */ - if (node != NULL) { - req->node = (WCHAR*)alloc_ptr; - if (MultiByteToWideChar(CP_UTF8, - 0, - node, - -1, - (WCHAR*) alloc_ptr, - nodesize / sizeof(WCHAR)) == 0) { - err = GetLastError(); - goto error; - } - alloc_ptr += nodesize; - } else { - req->node = NULL; - } - - /* convert service string to UTF16 into allocated memory and save pointer */ - /* in the req. */ - if (service != NULL) { - req->service = (WCHAR*)alloc_ptr; - if (MultiByteToWideChar(CP_UTF8, - 0, - service, - -1, - (WCHAR*) alloc_ptr, - servicesize / sizeof(WCHAR)) == 0) { - err = GetLastError(); - goto error; - } - alloc_ptr += servicesize; - } else { - req->service = NULL; - } - - /* copy hints to allocated memory and save pointer in req */ - if (hints != NULL) { - req->addrinfow = (struct addrinfoW*)alloc_ptr; - req->addrinfow->ai_family = hints->ai_family; - req->addrinfow->ai_socktype = hints->ai_socktype; - req->addrinfow->ai_protocol = hints->ai_protocol; - req->addrinfow->ai_flags = hints->ai_flags; - req->addrinfow->ai_addrlen = 0; - req->addrinfow->ai_canonname = NULL; - req->addrinfow->ai_addr = NULL; - req->addrinfow->ai_next = NULL; - } else { - req->addrinfow = NULL; - } - - uv__req_register(loop, req); - - if (getaddrinfo_cb) { - uv__work_submit(loop, - &req->work_req, - uv__getaddrinfo_work, - uv__getaddrinfo_done); - return 0; - } else { - uv__getaddrinfo_work(&req->work_req); - uv__getaddrinfo_done(&req->work_req, 0); - return req->retcode; - } - -error: - if (req != NULL) { - uv__free(req->alloc); - req->alloc = NULL; - } - return uv_translate_sys_error(err); -} diff --git a/3rdparty/libuv/src/win/getnameinfo.c b/3rdparty/libuv/src/win/getnameinfo.c deleted file mode 100644 index 66b64b88324..00000000000 --- a/3rdparty/libuv/src/win/getnameinfo.c +++ /dev/null @@ -1,150 +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. -*/ - -#include <assert.h> -#include <stdio.h> - -#include "uv.h" -#include "internal.h" -#include "req-inl.h" - -#ifndef GetNameInfo -int WSAAPI GetNameInfoW( - const SOCKADDR *pSockaddr, - socklen_t SockaddrLength, - PWCHAR pNodeBuffer, - DWORD NodeBufferSize, - PWCHAR pServiceBuffer, - DWORD ServiceBufferSize, - INT Flags -); -#endif - -static void uv__getnameinfo_work(struct uv__work* w) { - uv_getnameinfo_t* req; - WCHAR host[NI_MAXHOST]; - WCHAR service[NI_MAXSERV]; - int ret = 0; - - req = container_of(w, uv_getnameinfo_t, work_req); - if (GetNameInfoW((struct sockaddr*)&req->storage, - sizeof(req->storage), - host, - ARRAY_SIZE(host), - service, - ARRAY_SIZE(service), - req->flags)) { - ret = WSAGetLastError(); - } - req->retcode = uv__getaddrinfo_translate_error(ret); - - /* convert results to UTF-8 */ - WideCharToMultiByte(CP_UTF8, - 0, - host, - -1, - req->host, - sizeof(req->host), - NULL, - NULL); - - WideCharToMultiByte(CP_UTF8, - 0, - service, - -1, - req->service, - sizeof(req->service), - NULL, - NULL); -} - - -/* -* Called from uv_run when complete. -*/ -static void uv__getnameinfo_done(struct uv__work* w, int status) { - uv_getnameinfo_t* req; - char* host; - char* service; - - req = container_of(w, uv_getnameinfo_t, work_req); - uv__req_unregister(req->loop, req); - host = service = NULL; - - if (status == UV_ECANCELED) { - assert(req->retcode == 0); - req->retcode = UV_EAI_CANCELED; - } else if (req->retcode == 0) { - host = req->host; - service = req->service; - } - - if (req->getnameinfo_cb) - req->getnameinfo_cb(req, req->retcode, host, service); -} - - -/* -* Entry point for getnameinfo -* return 0 if a callback will be made -* return error code if validation fails -*/ -int uv_getnameinfo(uv_loop_t* loop, - uv_getnameinfo_t* req, - uv_getnameinfo_cb getnameinfo_cb, - const struct sockaddr* addr, - int flags) { - if (req == NULL || addr == NULL) - return UV_EINVAL; - - if (addr->sa_family == AF_INET) { - memcpy(&req->storage, - addr, - sizeof(struct sockaddr_in)); - } else if (addr->sa_family == AF_INET6) { - memcpy(&req->storage, - addr, - sizeof(struct sockaddr_in6)); - } else { - return UV_EINVAL; - } - - uv_req_init(loop, (uv_req_t*)req); - uv__req_register(loop, req); - - req->getnameinfo_cb = getnameinfo_cb; - req->flags = flags; - req->type = UV_GETNAMEINFO; - req->loop = loop; - req->retcode = 0; - - if (getnameinfo_cb) { - uv__work_submit(loop, - &req->work_req, - uv__getnameinfo_work, - uv__getnameinfo_done); - return 0; - } else { - uv__getnameinfo_work(&req->work_req); - uv__getnameinfo_done(&req->work_req, 0); - return req->retcode; - } -} diff --git a/3rdparty/libuv/src/win/handle-inl.h b/3rdparty/libuv/src/win/handle-inl.h deleted file mode 100644 index 8d0334cc52a..00000000000 --- a/3rdparty/libuv/src/win/handle-inl.h +++ /dev/null @@ -1,179 +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_HANDLE_INL_H_ -#define UV_WIN_HANDLE_INL_H_ - -#include <assert.h> -#include <io.h> - -#include "uv.h" -#include "internal.h" - - -#define DECREASE_ACTIVE_COUNT(loop, handle) \ - do { \ - if (--(handle)->activecnt == 0 && \ - !((handle)->flags & UV__HANDLE_CLOSING)) { \ - uv__handle_stop((handle)); \ - } \ - assert((handle)->activecnt >= 0); \ - } while (0) - - -#define INCREASE_ACTIVE_COUNT(loop, handle) \ - do { \ - if ((handle)->activecnt++ == 0) { \ - uv__handle_start((handle)); \ - } \ - assert((handle)->activecnt > 0); \ - } while (0) - - -#define DECREASE_PENDING_REQ_COUNT(handle) \ - do { \ - assert(handle->reqs_pending > 0); \ - handle->reqs_pending--; \ - \ - if (handle->flags & UV__HANDLE_CLOSING && \ - handle->reqs_pending == 0) { \ - uv_want_endgame(loop, (uv_handle_t*)handle); \ - } \ - } while (0) - - -#define uv__handle_closing(handle) \ - do { \ - assert(!((handle)->flags & UV__HANDLE_CLOSING)); \ - \ - if (!(((handle)->flags & UV__HANDLE_ACTIVE) && \ - ((handle)->flags & UV__HANDLE_REF))) \ - uv__active_handle_add((uv_handle_t*) (handle)); \ - \ - (handle)->flags |= UV__HANDLE_CLOSING; \ - (handle)->flags &= ~UV__HANDLE_ACTIVE; \ - } while (0) - - -#define uv__handle_close(handle) \ - do { \ - QUEUE_REMOVE(&(handle)->handle_queue); \ - uv__active_handle_rm((uv_handle_t*) (handle)); \ - \ - (handle)->flags |= UV_HANDLE_CLOSED; \ - \ - if ((handle)->close_cb) \ - (handle)->close_cb((uv_handle_t*) (handle)); \ - } while (0) - - -INLINE static void uv_want_endgame(uv_loop_t* loop, uv_handle_t* handle) { - if (!(handle->flags & UV_HANDLE_ENDGAME_QUEUED)) { - handle->flags |= UV_HANDLE_ENDGAME_QUEUED; - - handle->endgame_next = loop->endgame_handles; - loop->endgame_handles = 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_endgame(loop, (uv_timer_t*) 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. */ - /* But it also correctly checks the FD and returns INVALID_HANDLE_VALUE */ - /* for invalid FDs in release builds (or if you let the assert continue). */ - /* So this wrapper function disables asserts when calling _get_osfhandle. */ - - HANDLE handle; - UV_BEGIN_DISABLE_CRT_ASSERT(); - handle = (HANDLE) _get_osfhandle(fd); - UV_END_DISABLE_CRT_ASSERT(); - return handle; -} - -#endif /* UV_WIN_HANDLE_INL_H_ */ diff --git a/3rdparty/libuv/src/win/handle.c b/3rdparty/libuv/src/win/handle.c deleted file mode 100644 index 72b49d97904..00000000000 --- a/3rdparty/libuv/src/win/handle.c +++ /dev/null @@ -1,154 +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. - */ - -#include <assert.h> -#include <io.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" - - -uv_handle_type uv_guess_handle(uv_file file) { - HANDLE handle; - DWORD mode; - - if (file < 0) { - return UV_UNKNOWN_HANDLE; - } - - handle = uv__get_osfhandle(file); - - switch (GetFileType(handle)) { - case FILE_TYPE_CHAR: - if (GetConsoleMode(handle, &mode)) { - return UV_TTY; - } else { - return UV_FILE; - } - - case FILE_TYPE_PIPE: - return UV_NAMED_PIPE; - - case FILE_TYPE_DISK: - return UV_FILE; - - default: - return UV_UNKNOWN_HANDLE; - } -} - - -int uv_is_active(const uv_handle_t* handle) { - return (handle->flags & UV__HANDLE_ACTIVE) && - !(handle->flags & UV__HANDLE_CLOSING); -} - - -void uv_close(uv_handle_t* handle, uv_close_cb cb) { - uv_loop_t* loop = handle->loop; - - if (handle->flags & UV__HANDLE_CLOSING) { - assert(0); - return; - } - - handle->close_cb = cb; - - /* Handle-specific close actions */ - switch (handle->type) { - case UV_TCP: - uv_tcp_close(loop, (uv_tcp_t*)handle); - return; - - case UV_NAMED_PIPE: - uv_pipe_close(loop, (uv_pipe_t*) handle); - return; - - case UV_TTY: - uv_tty_close((uv_tty_t*) handle); - return; - - case UV_UDP: - uv_udp_close(loop, (uv_udp_t*) handle); - return; - - case UV_POLL: - uv_poll_close(loop, (uv_poll_t*) handle); - return; - - case UV_TIMER: - uv_timer_stop((uv_timer_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_PREPARE: - uv_prepare_stop((uv_prepare_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_CHECK: - uv_check_stop((uv_check_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_IDLE: - uv_idle_stop((uv_idle_t*)handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - case UV_ASYNC: - uv_async_close(loop, (uv_async_t*) handle); - return; - - case UV_SIGNAL: - uv_signal_close(loop, (uv_signal_t*) handle); - return; - - case UV_PROCESS: - uv_process_close(loop, (uv_process_t*) handle); - return; - - case UV_FS_EVENT: - uv_fs_event_close(loop, (uv_fs_event_t*) handle); - return; - - case UV_FS_POLL: - uv__fs_poll_close((uv_fs_poll_t*) handle); - uv__handle_closing(handle); - uv_want_endgame(loop, handle); - return; - - default: - /* Not supported */ - abort(); - } -} - - -int uv_is_closing(const uv_handle_t* handle) { - return !!(handle->flags & (UV__HANDLE_CLOSING | UV_HANDLE_CLOSED)); -} diff --git a/3rdparty/libuv/src/win/internal.h b/3rdparty/libuv/src/win/internal.h deleted file mode 100644 index c724793bf05..00000000000 --- a/3rdparty/libuv/src/win/internal.h +++ /dev/null @@ -1,383 +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_INTERNAL_H_ -#define UV_WIN_INTERNAL_H_ - -#include "uv.h" -#include "../uv-common.h" - -#include "tree.h" -#include "winapi.h" -#include "winsock.h" - -#ifdef _MSC_VER -# define INLINE __inline -# define UV_THREAD_LOCAL __declspec( thread ) -#else -# define INLINE inline -# define UV_THREAD_LOCAL __thread -#endif - - -#ifdef _DEBUG - -extern UV_THREAD_LOCAL int uv__crt_assert_enabled; - -#define UV_BEGIN_DISABLE_CRT_ASSERT() \ - { \ - int uv__saved_crt_assert_enabled = uv__crt_assert_enabled; \ - uv__crt_assert_enabled = FALSE; - - -#define UV_END_DISABLE_CRT_ASSERT() \ - uv__crt_assert_enabled = uv__saved_crt_assert_enabled; \ - } - -#else -#define UV_BEGIN_DISABLE_CRT_ASSERT() -#define UV_END_DISABLE_CRT_ASSERT() -#endif - -/* - * Handles - * (also see handle-inl.h) - */ - -/* Used by all handles. */ -#define UV_HANDLE_CLOSED 0x00000002 -#define UV_HANDLE_ENDGAME_QUEUED 0x00000008 - -/* uv-common.h: #define UV__HANDLE_CLOSING 0x00000001 */ -/* uv-common.h: #define UV__HANDLE_ACTIVE 0x00000040 */ -/* uv-common.h: #define UV__HANDLE_REF 0x00000020 */ -/* uv-common.h: #define UV_HANDLE_INTERNAL 0x00000080 */ - -/* Used by streams and UDP handles. */ -#define UV_HANDLE_READING 0x00000100 -#define UV_HANDLE_BOUND 0x00000200 -#define UV_HANDLE_LISTENING 0x00000800 -#define UV_HANDLE_CONNECTION 0x00001000 -#define UV_HANDLE_READABLE 0x00008000 -#define UV_HANDLE_WRITABLE 0x00010000 -#define UV_HANDLE_READ_PENDING 0x00020000 -#define UV_HANDLE_SYNC_BYPASS_IOCP 0x00040000 -#define UV_HANDLE_ZERO_READ 0x00080000 -#define UV_HANDLE_EMULATE_IOCP 0x00100000 -#define UV_HANDLE_BLOCKING_WRITES 0x00200000 - -/* Used by uv_tcp_t and uv_udp_t handles */ -#define UV_HANDLE_IPV6 0x01000000 - -/* Only used by uv_tcp_t handles. */ -#define UV_HANDLE_TCP_NODELAY 0x02000000 -#define UV_HANDLE_TCP_KEEPALIVE 0x04000000 -#define UV_HANDLE_TCP_SINGLE_ACCEPT 0x08000000 -#define UV_HANDLE_TCP_ACCEPT_STATE_CHANGING 0x10000000 -#define UV_HANDLE_TCP_SOCKET_CLOSED 0x20000000 -#define UV_HANDLE_SHARED_TCP_SOCKET 0x40000000 - -/* Only used by uv_pipe_t handles. */ -#define UV_HANDLE_NON_OVERLAPPED_PIPE 0x01000000 -#define UV_HANDLE_PIPESERVER 0x02000000 -#define UV_HANDLE_PIPE_READ_CANCELABLE 0x04000000 - -/* Only used by uv_tty_t handles. */ -#define UV_HANDLE_TTY_READABLE 0x01000000 -#define UV_HANDLE_TTY_RAW 0x02000000 -#define UV_HANDLE_TTY_SAVED_POSITION 0x04000000 -#define UV_HANDLE_TTY_SAVED_ATTRIBUTES 0x08000000 - -/* Only used by uv_poll_t handles. */ -#define UV_HANDLE_POLL_SLOW 0x02000000 - - -/* - * Requests: see req-inl.h - */ - - -/* - * Streams: see stream-inl.h - */ - - -/* - * TCP - */ - -typedef struct { - WSAPROTOCOL_INFOW socket_info; - int delayed_error; -} uv__ipc_socket_info_ex; - -int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb); -int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client); -int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb); -int uv_tcp_write(uv_loop_t* loop, uv_write_t* req, uv_tcp_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); -int uv__tcp_try_write(uv_tcp_t* handle, const uv_buf_t bufs[], - unsigned int nbufs); - -void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, uv_req_t* req); -void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_write_t* req); -void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_req_t* req); -void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_connect_t* req); - -void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp); -void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle); - -int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex, - int tcp_connection); - -int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid, - LPWSAPROTOCOL_INFOW protocol_info); - - -/* - * UDP - */ -void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, uv_req_t* req); -void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, - uv_udp_send_t* req); - -void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle); -void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle); - - -/* - * Pipes - */ -int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access, - char* name, size_t nameSize); - -int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb); -int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client); -int uv_pipe_read_start(uv_pipe_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb); -int uv_pipe_write(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); -int uv_pipe_write2(uv_loop_t* loop, uv_write_t* req, uv_pipe_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_stream_t* send_handle, - uv_write_cb cb); -void uv__pipe_pause_read(uv_pipe_t* handle); -void uv__pipe_unpause_read(uv_pipe_t* handle); -void uv__pipe_stop_read(uv_pipe_t* handle); - -void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* req); -void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_write_t* req); -void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* raw_req); -void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_connect_t* req); -void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_shutdown_t* req); - -void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle); -void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle); -void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle); - - -/* - * TTY - */ -void uv_console_init(); - -int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb); -int uv_tty_read_stop(uv_tty_t* handle); -int uv_tty_write(uv_loop_t* loop, uv_write_t* req, uv_tty_t* handle, - const uv_buf_t bufs[], unsigned int nbufs, uv_write_cb cb); -int uv__tty_try_write(uv_tty_t* handle, const uv_buf_t bufs[], - unsigned int nbufs); -void uv_tty_close(uv_tty_t* handle); - -void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req); -void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, - uv_write_t* req); -/* TODO: remove me */ -void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* raw_req); -/* TODO: remove me */ -void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, - uv_connect_t* req); - -void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle); - - -/* - * Poll watchers - */ -void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, - uv_req_t* req); - -int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle); -void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle); - - -/* - * Timers - */ -void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle); - -DWORD uv__next_timeout(const uv_loop_t* loop); -void uv_process_timers(uv_loop_t* loop); - - -/* - * Loop watchers - */ -void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle); - -void uv_prepare_invoke(uv_loop_t* loop); -void uv_check_invoke(uv_loop_t* loop); -void uv_idle_invoke(uv_loop_t* loop); - -void uv__once_init(); - - -/* - * Async watcher - */ -void uv_async_close(uv_loop_t* loop, uv_async_t* handle); -void uv_async_endgame(uv_loop_t* loop, uv_async_t* handle); - -void uv_process_async_wakeup_req(uv_loop_t* loop, uv_async_t* handle, - uv_req_t* req); - - -/* - * Signal watcher - */ -void uv_signals_init(); -int uv__signal_dispatch(int signum); - -void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle); -void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle); - -void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, - uv_req_t* req); - - -/* - * Spawn - */ -void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle); -void uv_process_close(uv_loop_t* loop, uv_process_t* handle); -void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle); - - -/* - * Error - */ -int uv_translate_sys_error(int sys_errno); - - -/* - * FS - */ -void uv_fs_init(); - - -/* - * FS Event - */ -void uv_process_fs_event_req(uv_loop_t* loop, uv_req_t* req, - uv_fs_event_t* handle); -void uv_fs_event_close(uv_loop_t* loop, uv_fs_event_t* handle); -void uv_fs_event_endgame(uv_loop_t* loop, uv_fs_event_t* handle); - - -/* - * Stat poller. - */ -void uv__fs_poll_endgame(uv_loop_t* loop, uv_fs_poll_t* handle); - - -/* - * Utilities. - */ -void uv__util_init(); - -uint64_t uv__hrtime(double scale); -int uv_parent_pid(); -int uv_current_pid(); -__declspec(noreturn) void uv_fatal_error(const int errorno, const char* syscall); -int uv__getpwuid_r(uv_passwd_t* pwd); -int uv__convert_utf16_to_utf8(const WCHAR* utf16, char** utf8); - - -/* - * Process stdio handles. - */ -int uv__stdio_create(uv_loop_t* loop, - const uv_process_options_t* options, - BYTE** buffer_ptr); -void uv__stdio_destroy(BYTE* buffer); -void uv__stdio_noinherit(BYTE* buffer); -int uv__stdio_verify(BYTE* buffer, WORD size); -WORD uv__stdio_size(BYTE* buffer); -HANDLE uv__stdio_handle(BYTE* buffer, int fd); - - -/* - * Winapi and ntapi utility functions - */ -void uv_winapi_init(); - - -/* - * Winsock utility functions - */ -void uv_winsock_init(); - -int uv_ntstatus_to_winsock_error(NTSTATUS status); - -BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target); -BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target); - -int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); -int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr, - int* addr_len, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine); - -int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in, - AFD_POLL_INFO* info_out, OVERLAPPED* overlapped); - -/* Whether there are any non-IFS LSPs stacked on TCP */ -extern int uv_tcp_non_ifs_lsp_ipv4; -extern int uv_tcp_non_ifs_lsp_ipv6; - -/* Ip address used to bind to any port at any interface */ -extern struct sockaddr_in uv_addr_ip4_any_; -extern struct sockaddr_in6 uv_addr_ip6_any_; - -#endif /* UV_WIN_INTERNAL_H_ */ diff --git a/3rdparty/libuv/src/win/loop-watcher.c b/3rdparty/libuv/src/win/loop-watcher.c deleted file mode 100644 index 20e4509f838..00000000000 --- a/3rdparty/libuv/src/win/loop-watcher.c +++ /dev/null @@ -1,122 +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. - */ - -#include <assert.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" - - -void uv_loop_watcher_endgame(uv_loop_t* loop, uv_handle_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - handle->flags |= UV_HANDLE_CLOSED; - uv__handle_close(handle); - } -} - - -#define UV_LOOP_WATCHER_DEFINE(name, NAME) \ - int uv_##name##_init(uv_loop_t* loop, uv_##name##_t* handle) { \ - uv__handle_init(loop, (uv_handle_t*) handle, UV_##NAME); \ - \ - return 0; \ - } \ - \ - \ - int uv_##name##_start(uv_##name##_t* handle, uv_##name##_cb cb) { \ - uv_loop_t* loop = handle->loop; \ - uv_##name##_t* old_head; \ - \ - assert(handle->type == UV_##NAME); \ - \ - if (uv__is_active(handle)) \ - return 0; \ - \ - if (cb == NULL) \ - return UV_EINVAL; \ - \ - old_head = loop->name##_handles; \ - \ - handle->name##_next = old_head; \ - handle->name##_prev = NULL; \ - \ - if (old_head) { \ - old_head->name##_prev = handle; \ - } \ - \ - loop->name##_handles = handle; \ - \ - handle->name##_cb = cb; \ - uv__handle_start(handle); \ - \ - return 0; \ - } \ - \ - \ - int uv_##name##_stop(uv_##name##_t* handle) { \ - uv_loop_t* loop = handle->loop; \ - \ - assert(handle->type == UV_##NAME); \ - \ - if (!uv__is_active(handle)) \ - return 0; \ - \ - /* Update loop head if needed */ \ - if (loop->name##_handles == handle) { \ - loop->name##_handles = handle->name##_next; \ - } \ - \ - /* Update the iterator-next pointer of needed */ \ - if (loop->next_##name##_handle == handle) { \ - loop->next_##name##_handle = handle->name##_next; \ - } \ - \ - if (handle->name##_prev) { \ - handle->name##_prev->name##_next = handle->name##_next; \ - } \ - if (handle->name##_next) { \ - handle->name##_next->name##_prev = handle->name##_prev; \ - } \ - \ - uv__handle_stop(handle); \ - \ - return 0; \ - } \ - \ - \ - void uv_##name##_invoke(uv_loop_t* loop) { \ - uv_##name##_t* handle; \ - \ - (loop)->next_##name##_handle = (loop)->name##_handles; \ - \ - while ((loop)->next_##name##_handle != NULL) { \ - handle = (loop)->next_##name##_handle; \ - (loop)->next_##name##_handle = handle->name##_next; \ - \ - handle->name##_cb(handle); \ - } \ - } - -UV_LOOP_WATCHER_DEFINE(prepare, PREPARE) -UV_LOOP_WATCHER_DEFINE(check, CHECK) -UV_LOOP_WATCHER_DEFINE(idle, IDLE) diff --git a/3rdparty/libuv/src/win/pipe.c b/3rdparty/libuv/src/win/pipe.c deleted file mode 100644 index 2a949e79be3..00000000000 --- a/3rdparty/libuv/src/win/pipe.c +++ /dev/null @@ -1,2129 +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. - */ - -#include <assert.h> -#include <io.h> -#include <string.h> -#include <stdio.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - -typedef struct uv__ipc_queue_item_s uv__ipc_queue_item_t; - -struct uv__ipc_queue_item_s { - /* - * NOTE: It is important for socket_info_ex to be the first field, - * because we will we assigning it to the pending_ipc_info.socket_info - */ - uv__ipc_socket_info_ex socket_info_ex; - QUEUE member; - int tcp_connection; -}; - -/* A zero-size buffer for use by uv_pipe_read */ -static char uv_zero_[] = ""; - -/* Null uv_buf_t */ -static const uv_buf_t uv_null_buf_ = { 0, NULL }; - -/* The timeout that the pipe will wait for the remote end to write data */ -/* when the local ends wants to shut it down. */ -static const int64_t eof_timeout = 50; /* ms */ - -static const int default_pending_pipe_instances = 4; - -/* Pipe prefix */ -static char pipe_prefix[] = "\\\\?\\pipe"; -static const int pipe_prefix_len = sizeof(pipe_prefix) - 1; - -/* IPC protocol flags. */ -#define UV_IPC_RAW_DATA 0x0001 -#define UV_IPC_TCP_SERVER 0x0002 -#define UV_IPC_TCP_CONNECTION 0x0004 - -/* IPC frame header. */ -typedef struct { - int flags; - uint64_t raw_data_length; -} uv_ipc_frame_header_t; - -/* IPC frame, which contains an imported TCP socket stream. */ -typedef struct { - uv_ipc_frame_header_t header; - uv__ipc_socket_info_ex socket_info_ex; -} uv_ipc_frame_uv_stream; - -static void eof_timer_init(uv_pipe_t* pipe); -static void eof_timer_start(uv_pipe_t* pipe); -static void eof_timer_stop(uv_pipe_t* pipe); -static void eof_timer_cb(uv_timer_t* timer); -static void eof_timer_destroy(uv_pipe_t* pipe); -static void eof_timer_close_cb(uv_handle_t* handle); - - -static void uv_unique_pipe_name(char* ptr, char* name, size_t size) { - snprintf(name, size, "\\\\?\\pipe\\uv\\%p-%lu", ptr, GetCurrentProcessId()); -} - - -int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) { - uv_stream_init(loop, (uv_stream_t*)handle, UV_NAMED_PIPE); - - handle->reqs_pending = 0; - handle->handle = INVALID_HANDLE_VALUE; - handle->name = NULL; - handle->pipe.conn.ipc_pid = 0; - handle->pipe.conn.remaining_ipc_rawdata_bytes = 0; - QUEUE_INIT(&handle->pipe.conn.pending_ipc_info.queue); - handle->pipe.conn.pending_ipc_info.queue_len = 0; - handle->ipc = ipc; - handle->pipe.conn.non_overlapped_writes_tail = NULL; - handle->pipe.conn.readfile_thread = NULL; - - uv_req_init(loop, (uv_req_t*) &handle->pipe.conn.ipc_header_write_req); - - return 0; -} - - -static void uv_pipe_connection_init(uv_pipe_t* handle) { - uv_connection_init((uv_stream_t*) handle); - handle->read_req.data = handle; - handle->pipe.conn.eof_timer = NULL; - assert(!(handle->flags & UV_HANDLE_PIPESERVER)); - if (pCancelSynchronousIo && - handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { - uv_mutex_init(&handle->pipe.conn.readfile_mutex); - handle->flags |= UV_HANDLE_PIPE_READ_CANCELABLE; - } -} - - -static HANDLE open_named_pipe(const WCHAR* name, DWORD* duplex_flags) { - HANDLE pipeHandle; - - /* - * Assume that we have a duplex pipe first, so attempt to - * connect with GENERIC_READ | GENERIC_WRITE. - */ - pipeHandle = CreateFileW(name, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - if (pipeHandle != INVALID_HANDLE_VALUE) { - *duplex_flags = UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - return pipeHandle; - } - - /* - * If the pipe is not duplex CreateFileW fails with - * ERROR_ACCESS_DENIED. In that case try to connect - * as a read-only or write-only. - */ - if (GetLastError() == ERROR_ACCESS_DENIED) { - pipeHandle = CreateFileW(name, - GENERIC_READ | FILE_WRITE_ATTRIBUTES, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - if (pipeHandle != INVALID_HANDLE_VALUE) { - *duplex_flags = UV_HANDLE_READABLE; - return pipeHandle; - } - } - - if (GetLastError() == ERROR_ACCESS_DENIED) { - pipeHandle = CreateFileW(name, - GENERIC_WRITE | FILE_READ_ATTRIBUTES, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - if (pipeHandle != INVALID_HANDLE_VALUE) { - *duplex_flags = UV_HANDLE_WRITABLE; - return pipeHandle; - } - } - - return INVALID_HANDLE_VALUE; -} - - -static void close_pipe(uv_pipe_t* pipe) { - assert(pipe->u.fd == -1 || pipe->u.fd > 2); - if (pipe->u.fd == -1) - CloseHandle(pipe->handle); - else - close(pipe->u.fd); - - pipe->u.fd = -1; - pipe->handle = INVALID_HANDLE_VALUE; -} - - -int uv_stdio_pipe_server(uv_loop_t* loop, uv_pipe_t* handle, DWORD access, - char* name, size_t nameSize) { - HANDLE pipeHandle; - int err; - char* ptr = (char*)handle; - - for (;;) { - uv_unique_pipe_name(ptr, name, nameSize); - - pipeHandle = CreateNamedPipeA(name, - access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0, - NULL); - - if (pipeHandle != INVALID_HANDLE_VALUE) { - /* No name collisions. We're done. */ - break; - } - - err = GetLastError(); - if (err != ERROR_PIPE_BUSY && err != ERROR_ACCESS_DENIED) { - goto error; - } - - /* Pipe name collision. Increment the pointer and try again. */ - ptr++; - } - - if (CreateIoCompletionPort(pipeHandle, - loop->iocp, - (ULONG_PTR)handle, - 0) == NULL) { - err = GetLastError(); - goto error; - } - - uv_pipe_connection_init(handle); - handle->handle = pipeHandle; - - return 0; - - error: - if (pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(pipeHandle); - } - - return err; -} - - -static int uv_set_pipe_handle(uv_loop_t* loop, - uv_pipe_t* handle, - HANDLE pipeHandle, - int fd, - DWORD duplex_flags) { - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_MODE_INFORMATION mode_info; - DWORD mode = PIPE_READMODE_BYTE | PIPE_WAIT; - DWORD current_mode = 0; - DWORD err = 0; - - if (!(handle->flags & UV_HANDLE_PIPESERVER) && - handle->handle != INVALID_HANDLE_VALUE) - return UV_EBUSY; - - if (!SetNamedPipeHandleState(pipeHandle, &mode, NULL, NULL)) { - err = GetLastError(); - if (err == ERROR_ACCESS_DENIED) { - /* - * SetNamedPipeHandleState can fail if the handle doesn't have either - * GENERIC_WRITE or FILE_WRITE_ATTRIBUTES. - * But if the handle already has the desired wait and blocking modes - * we can continue. - */ - if (!GetNamedPipeHandleState(pipeHandle, ¤t_mode, NULL, NULL, - NULL, NULL, 0)) { - return -1; - } else if (current_mode & PIPE_NOWAIT) { - SetLastError(ERROR_ACCESS_DENIED); - return -1; - } - } else { - /* If this returns ERROR_INVALID_PARAMETER we probably opened - * something that is not a pipe. */ - if (err == ERROR_INVALID_PARAMETER) { - SetLastError(WSAENOTSOCK); - } - return -1; - } - } - - /* Check if the pipe was created with FILE_FLAG_OVERLAPPED. */ - nt_status = pNtQueryInformationFile(pipeHandle, - &io_status, - &mode_info, - sizeof(mode_info), - FileModeInformation); - if (nt_status != STATUS_SUCCESS) { - return -1; - } - - if (mode_info.Mode & FILE_SYNCHRONOUS_IO_ALERT || - mode_info.Mode & FILE_SYNCHRONOUS_IO_NONALERT) { - /* Non-overlapped pipe. */ - handle->flags |= UV_HANDLE_NON_OVERLAPPED_PIPE; - } else { - /* Overlapped pipe. Try to associate with IOCP. */ - if (CreateIoCompletionPort(pipeHandle, - loop->iocp, - (ULONG_PTR)handle, - 0) == NULL) { - handle->flags |= UV_HANDLE_EMULATE_IOCP; - } - } - - handle->handle = pipeHandle; - handle->u.fd = fd; - handle->flags |= duplex_flags; - - return 0; -} - - -static DWORD WINAPI pipe_shutdown_thread_proc(void* parameter) { - uv_loop_t* loop; - uv_pipe_t* handle; - uv_shutdown_t* req; - - req = (uv_shutdown_t*) parameter; - assert(req); - handle = (uv_pipe_t*) req->handle; - assert(handle); - loop = handle->loop; - assert(loop); - - FlushFileBuffers(handle->handle); - - /* Post completed */ - POST_COMPLETION_FOR_REQ(loop, req); - - return 0; -} - - -void uv_pipe_endgame(uv_loop_t* loop, uv_pipe_t* handle) { - int err; - DWORD result; - uv_shutdown_t* req; - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_PIPE_LOCAL_INFORMATION pipe_info; - uv__ipc_queue_item_t* item; - - if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - handle->flags &= ~UV_HANDLE_PIPE_READ_CANCELABLE; - uv_mutex_destroy(&handle->pipe.conn.readfile_mutex); - } - - if ((handle->flags & UV_HANDLE_CONNECTION) && - handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - req = handle->stream.conn.shutdown_req; - - /* Clear the shutdown_req field so we don't go here again. */ - handle->stream.conn.shutdown_req = NULL; - - if (handle->flags & UV__HANDLE_CLOSING) { - UNREGISTER_HANDLE_REQ(loop, handle, req); - - /* Already closing. Cancel the shutdown. */ - if (req->cb) { - req->cb(req, UV_ECANCELED); - } - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - /* Try to avoid flushing the pipe buffer in the thread pool. */ - nt_status = pNtQueryInformationFile(handle->handle, - &io_status, - &pipe_info, - sizeof pipe_info, - FilePipeLocalInformation); - - if (nt_status != STATUS_SUCCESS) { - /* Failure */ - UNREGISTER_HANDLE_REQ(loop, handle, req); - - handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */ - if (req->cb) { - err = pRtlNtStatusToDosError(nt_status); - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (pipe_info.OutboundQuota == pipe_info.WriteQuotaAvailable) { - /* Short-circuit, no need to call FlushFileBuffers. */ - uv_insert_pending_req(loop, (uv_req_t*) req); - return; - } - - /* Run FlushFileBuffers in the thread pool. */ - result = QueueUserWorkItem(pipe_shutdown_thread_proc, - req, - WT_EXECUTELONGFUNCTION); - if (result) { - return; - - } else { - /* Failure. */ - UNREGISTER_HANDLE_REQ(loop, handle, req); - - handle->flags |= UV_HANDLE_WRITABLE; /* Questionable */ - if (req->cb) { - err = GetLastError(); - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - } - - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - if (handle->flags & UV_HANDLE_CONNECTION) { - /* Free pending sockets */ - while (!QUEUE_EMPTY(&handle->pipe.conn.pending_ipc_info.queue)) { - QUEUE* q; - SOCKET socket; - - q = QUEUE_HEAD(&handle->pipe.conn.pending_ipc_info.queue); - QUEUE_REMOVE(q); - item = QUEUE_DATA(q, uv__ipc_queue_item_t, member); - - /* Materialize socket and close it */ - socket = WSASocketW(FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - &item->socket_info_ex.socket_info, - 0, - WSA_FLAG_OVERLAPPED); - uv__free(item); - - if (socket != INVALID_SOCKET) - closesocket(socket); - } - handle->pipe.conn.pending_ipc_info.queue_len = 0; - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(handle->read_req.wait_handle); - handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - } - if (handle->read_req.event_handle) { - CloseHandle(handle->read_req.event_handle); - handle->read_req.event_handle = NULL; - } - } - } - - if (handle->flags & UV_HANDLE_PIPESERVER) { - assert(handle->pipe.serv.accept_reqs); - uv__free(handle->pipe.serv.accept_reqs); - handle->pipe.serv.accept_reqs = NULL; - } - - uv__handle_close(handle); - } -} - - -void uv_pipe_pending_instances(uv_pipe_t* handle, int count) { - if (handle->flags & UV_HANDLE_BOUND) - return; - handle->pipe.serv.pending_instances = count; - handle->flags |= UV_HANDLE_PIPESERVER; -} - - -/* Creates a pipe server. */ -int uv_pipe_bind(uv_pipe_t* handle, const char* name) { - uv_loop_t* loop = handle->loop; - int i, err, nameSize; - uv_pipe_accept_t* req; - - if (handle->flags & UV_HANDLE_BOUND) { - return UV_EINVAL; - } - - if (!name) { - return UV_EINVAL; - } - - if (!(handle->flags & UV_HANDLE_PIPESERVER)) { - handle->pipe.serv.pending_instances = default_pending_pipe_instances; - } - - handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*) - uv__malloc(sizeof(uv_pipe_accept_t) * handle->pipe.serv.pending_instances); - if (!handle->pipe.serv.accept_reqs) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - for (i = 0; i < handle->pipe.serv.pending_instances; i++) { - req = &handle->pipe.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; - req->data = handle; - req->pipeHandle = INVALID_HANDLE_VALUE; - req->next_pending = NULL; - } - - /* Convert name to UTF16. */ - nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR); - handle->name = (WCHAR*)uv__malloc(nameSize); - if (!handle->name) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - if (!MultiByteToWideChar(CP_UTF8, - 0, - name, - -1, - handle->name, - nameSize / sizeof(WCHAR))) { - err = GetLastError(); - goto error; - } - - /* - * Attempt to create the first pipe with FILE_FLAG_FIRST_PIPE_INSTANCE. - * If this fails then there's already a pipe server for the given pipe name. - */ - handle->pipe.serv.accept_reqs[0].pipeHandle = CreateNamedPipeW(handle->name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | - FILE_FLAG_FIRST_PIPE_INSTANCE, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); - - if (handle->pipe.serv.accept_reqs[0].pipeHandle == INVALID_HANDLE_VALUE) { - err = GetLastError(); - if (err == ERROR_ACCESS_DENIED) { - err = WSAEADDRINUSE; /* Translates to UV_EADDRINUSE. */ - } else if (err == ERROR_PATH_NOT_FOUND || err == ERROR_INVALID_NAME) { - err = WSAEACCES; /* Translates to UV_EACCES. */ - } - goto error; - } - - if (uv_set_pipe_handle(loop, - handle, - handle->pipe.serv.accept_reqs[0].pipeHandle, - -1, - 0)) { - err = GetLastError(); - goto error; - } - - handle->pipe.serv.pending_accepts = NULL; - handle->flags |= UV_HANDLE_PIPESERVER; - handle->flags |= UV_HANDLE_BOUND; - - return 0; - -error: - if (handle->name) { - uv__free(handle->name); - handle->name = NULL; - } - - if (handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(handle->pipe.serv.accept_reqs[0].pipeHandle); - handle->pipe.serv.accept_reqs[0].pipeHandle = INVALID_HANDLE_VALUE; - } - - return uv_translate_sys_error(err); -} - - -static DWORD WINAPI pipe_connect_thread_proc(void* parameter) { - uv_loop_t* loop; - uv_pipe_t* handle; - uv_connect_t* req; - HANDLE pipeHandle = INVALID_HANDLE_VALUE; - DWORD duplex_flags; - - req = (uv_connect_t*) parameter; - assert(req); - handle = (uv_pipe_t*) req->handle; - assert(handle); - loop = handle->loop; - assert(loop); - - /* We're here because CreateFile on a pipe returned ERROR_PIPE_BUSY. */ - /* We wait for the pipe to become available with WaitNamedPipe. */ - while (WaitNamedPipeW(handle->name, 30000)) { - /* The pipe is now available, try to connect. */ - pipeHandle = open_named_pipe(handle->name, &duplex_flags); - if (pipeHandle != INVALID_HANDLE_VALUE) { - break; - } - - SwitchToThread(); - } - - if (pipeHandle != INVALID_HANDLE_VALUE && - !uv_set_pipe_handle(loop, handle, pipeHandle, -1, duplex_flags)) { - SET_REQ_SUCCESS(req); - } else { - SET_REQ_ERROR(req, GetLastError()); - } - - /* Post completed */ - POST_COMPLETION_FOR_REQ(loop, req); - - return 0; -} - - -void uv_pipe_connect(uv_connect_t* req, uv_pipe_t* handle, - const char* name, uv_connect_cb cb) { - uv_loop_t* loop = handle->loop; - int err, nameSize; - HANDLE pipeHandle = INVALID_HANDLE_VALUE; - DWORD duplex_flags; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - - /* Convert name to UTF16. */ - nameSize = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0) * sizeof(WCHAR); - handle->name = (WCHAR*)uv__malloc(nameSize); - if (!handle->name) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - if (!MultiByteToWideChar(CP_UTF8, - 0, - name, - -1, - handle->name, - nameSize / sizeof(WCHAR))) { - err = GetLastError(); - goto error; - } - - pipeHandle = open_named_pipe(handle->name, &duplex_flags); - if (pipeHandle == INVALID_HANDLE_VALUE) { - if (GetLastError() == ERROR_PIPE_BUSY) { - /* Wait for the server to make a pipe instance available. */ - if (!QueueUserWorkItem(&pipe_connect_thread_proc, - req, - WT_EXECUTELONGFUNCTION)) { - err = GetLastError(); - goto error; - } - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - - return; - } - - err = GetLastError(); - goto error; - } - - assert(pipeHandle != INVALID_HANDLE_VALUE); - - if (uv_set_pipe_handle(loop, - (uv_pipe_t*) req->handle, - pipeHandle, - -1, - duplex_flags)) { - err = GetLastError(); - goto error; - } - - SET_REQ_SUCCESS(req); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - return; - -error: - if (handle->name) { - uv__free(handle->name); - handle->name = NULL; - } - - if (pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(pipeHandle); - } - - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, err); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - return; -} - - -void uv__pipe_pause_read(uv_pipe_t* handle) { - if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - /* Pause the ReadFile task briefly, to work - around the Windows kernel bug that causes - any access to a NamedPipe to deadlock if - any process has called ReadFile */ - HANDLE h; - uv_mutex_lock(&handle->pipe.conn.readfile_mutex); - h = handle->pipe.conn.readfile_thread; - while (h) { - /* spinlock: we expect this to finish quickly, - or we are probably about to deadlock anyways - (in the kernel), so it doesn't matter */ - pCancelSynchronousIo(h); - SwitchToThread(); /* yield thread control briefly */ - h = handle->pipe.conn.readfile_thread; - } - } -} - - -void uv__pipe_unpause_read(uv_pipe_t* handle) { - if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - uv_mutex_unlock(&handle->pipe.conn.readfile_mutex); - } -} - - -void uv__pipe_stop_read(uv_pipe_t* handle) { - handle->flags &= ~UV_HANDLE_READING; - uv__pipe_pause_read((uv_pipe_t*)handle); - uv__pipe_unpause_read((uv_pipe_t*)handle); -} - - -/* Cleans up uv_pipe_t (server or connection) and all resources associated */ -/* with it. */ -void uv_pipe_cleanup(uv_loop_t* loop, uv_pipe_t* handle) { - int i; - HANDLE pipeHandle; - - uv__pipe_stop_read(handle); - - if (handle->name) { - uv__free(handle->name); - handle->name = NULL; - } - - if (handle->flags & UV_HANDLE_PIPESERVER) { - for (i = 0; i < handle->pipe.serv.pending_instances; i++) { - pipeHandle = handle->pipe.serv.accept_reqs[i].pipeHandle; - if (pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(pipeHandle); - handle->pipe.serv.accept_reqs[i].pipeHandle = INVALID_HANDLE_VALUE; - } - } - handle->handle = INVALID_HANDLE_VALUE; - } - - if (handle->flags & UV_HANDLE_CONNECTION) { - handle->flags &= ~UV_HANDLE_WRITABLE; - eof_timer_destroy(handle); - } - - if ((handle->flags & UV_HANDLE_CONNECTION) - && handle->handle != INVALID_HANDLE_VALUE) - close_pipe(handle); -} - - -void uv_pipe_close(uv_loop_t* loop, uv_pipe_t* handle) { - if (handle->flags & UV_HANDLE_READING) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - } - - if (handle->flags & UV_HANDLE_LISTENING) { - handle->flags &= ~UV_HANDLE_LISTENING; - DECREASE_ACTIVE_COUNT(loop, handle); - } - - uv_pipe_cleanup(loop, handle); - - if (handle->reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - - handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); - uv__handle_closing(handle); -} - - -static void uv_pipe_queue_accept(uv_loop_t* loop, uv_pipe_t* handle, - uv_pipe_accept_t* req, BOOL firstInstance) { - assert(handle->flags & UV_HANDLE_LISTENING); - - if (!firstInstance) { - assert(req->pipeHandle == INVALID_HANDLE_VALUE); - - req->pipeHandle = CreateNamedPipeW(handle->name, - PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, - PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, - PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL); - - if (req->pipeHandle == INVALID_HANDLE_VALUE) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } - - if (uv_set_pipe_handle(loop, handle, req->pipeHandle, -1, 0)) { - CloseHandle(req->pipeHandle); - req->pipeHandle = INVALID_HANDLE_VALUE; - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } - } - - assert(req->pipeHandle != INVALID_HANDLE_VALUE); - - /* Prepare the overlapped structure. */ - memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); - - if (!ConnectNamedPipe(req->pipeHandle, &req->u.io.overlapped) && - GetLastError() != ERROR_IO_PENDING) { - if (GetLastError() == ERROR_PIPE_CONNECTED) { - SET_REQ_SUCCESS(req); - } else { - CloseHandle(req->pipeHandle); - req->pipeHandle = INVALID_HANDLE_VALUE; - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - } - uv_insert_pending_req(loop, (uv_req_t*) req); - handle->reqs_pending++; - return; - } - - handle->reqs_pending++; -} - - -int uv_pipe_accept(uv_pipe_t* server, uv_stream_t* client) { - uv_loop_t* loop = server->loop; - uv_pipe_t* pipe_client; - uv_pipe_accept_t* req; - QUEUE* q; - uv__ipc_queue_item_t* item; - int err; - - if (server->ipc) { - if (QUEUE_EMPTY(&server->pipe.conn.pending_ipc_info.queue)) { - /* No valid pending sockets. */ - return WSAEWOULDBLOCK; - } - - q = QUEUE_HEAD(&server->pipe.conn.pending_ipc_info.queue); - QUEUE_REMOVE(q); - server->pipe.conn.pending_ipc_info.queue_len--; - item = QUEUE_DATA(q, uv__ipc_queue_item_t, member); - - err = uv_tcp_import((uv_tcp_t*)client, - &item->socket_info_ex, - item->tcp_connection); - if (err != 0) - return err; - - uv__free(item); - - } else { - pipe_client = (uv_pipe_t*)client; - - /* Find a connection instance that has been connected, but not yet */ - /* accepted. */ - req = server->pipe.serv.pending_accepts; - - if (!req) { - /* No valid connections found, so we error out. */ - return WSAEWOULDBLOCK; - } - - /* Initialize the client handle and copy the pipeHandle to the client */ - uv_pipe_connection_init(pipe_client); - pipe_client->handle = req->pipeHandle; - pipe_client->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - - /* Prepare the req to pick up a new connection */ - server->pipe.serv.pending_accepts = req->next_pending; - req->next_pending = NULL; - req->pipeHandle = INVALID_HANDLE_VALUE; - - if (!(server->flags & UV__HANDLE_CLOSING)) { - uv_pipe_queue_accept(loop, server, req, FALSE); - } - } - - return 0; -} - - -/* Starts listening for connections for the given pipe. */ -int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) { - uv_loop_t* loop = handle->loop; - int i; - - if (handle->flags & UV_HANDLE_LISTENING) { - handle->stream.serv.connection_cb = cb; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - return WSAEINVAL; - } - - if (handle->flags & UV_HANDLE_READING) { - return WSAEISCONN; - } - - if (!(handle->flags & UV_HANDLE_PIPESERVER)) { - return ERROR_NOT_SUPPORTED; - } - - handle->flags |= UV_HANDLE_LISTENING; - INCREASE_ACTIVE_COUNT(loop, handle); - handle->stream.serv.connection_cb = cb; - - /* First pipe handle should have already been created in uv_pipe_bind */ - assert(handle->pipe.serv.accept_reqs[0].pipeHandle != INVALID_HANDLE_VALUE); - - for (i = 0; i < handle->pipe.serv.pending_instances; i++) { - uv_pipe_queue_accept(loop, handle, &handle->pipe.serv.accept_reqs[i], i == 0); - } - - return 0; -} - - -static DWORD WINAPI uv_pipe_zero_readfile_thread_proc(void* parameter) { - int result; - DWORD bytes; - uv_read_t* req = (uv_read_t*) parameter; - uv_pipe_t* handle = (uv_pipe_t*) req->data; - uv_loop_t* loop = handle->loop; - HANDLE hThread = NULL; - DWORD err; - uv_mutex_t *m = &handle->pipe.conn.readfile_mutex; - - assert(req != NULL); - assert(req->type == UV_READ); - assert(handle->type == UV_NAMED_PIPE); - - if (handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - uv_mutex_lock(m); /* mutex controls *setting* of readfile_thread */ - if (DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), - GetCurrentProcess(), &hThread, - 0, TRUE, DUPLICATE_SAME_ACCESS)) { - handle->pipe.conn.readfile_thread = hThread; - } else { - hThread = NULL; - } - uv_mutex_unlock(m); - } -restart_readfile: - result = ReadFile(handle->handle, - &uv_zero_, - 0, - &bytes, - NULL); - if (!result) { - err = GetLastError(); - if (err == ERROR_OPERATION_ABORTED && - handle->flags & UV_HANDLE_PIPE_READ_CANCELABLE) { - if (handle->flags & UV_HANDLE_READING) { - /* just a brief break to do something else */ - handle->pipe.conn.readfile_thread = NULL; - /* resume after it is finished */ - uv_mutex_lock(m); - handle->pipe.conn.readfile_thread = hThread; - uv_mutex_unlock(m); - goto restart_readfile; - } else { - result = 1; /* successfully stopped reading */ - } - } - } - if (hThread) { - assert(hThread == handle->pipe.conn.readfile_thread); - /* mutex does not control clearing readfile_thread */ - handle->pipe.conn.readfile_thread = NULL; - uv_mutex_lock(m); - /* only when we hold the mutex lock is it safe to - open or close the handle */ - CloseHandle(hThread); - uv_mutex_unlock(m); - } - - if (!result) { - SET_REQ_ERROR(req, err); - } - - POST_COMPLETION_FOR_REQ(loop, req); - return 0; -} - - -static DWORD WINAPI uv_pipe_writefile_thread_proc(void* parameter) { - int result; - DWORD bytes; - uv_write_t* req = (uv_write_t*) parameter; - uv_pipe_t* handle = (uv_pipe_t*) req->handle; - uv_loop_t* loop = handle->loop; - - assert(req != NULL); - assert(req->type == UV_WRITE); - assert(handle->type == UV_NAMED_PIPE); - assert(req->write_buffer.base); - - result = WriteFile(handle->handle, - req->write_buffer.base, - req->write_buffer.len, - &bytes, - NULL); - - if (!result) { - SET_REQ_ERROR(req, GetLastError()); - } - - POST_COMPLETION_FOR_REQ(loop, req); - return 0; -} - - -static void CALLBACK post_completion_read_wait(void* context, BOOLEAN timed_out) { - uv_read_t* req; - uv_tcp_t* handle; - - req = (uv_read_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->data; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->u.io.overlapped.InternalHigh, - 0, - &req->u.io.overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void CALLBACK post_completion_write_wait(void* context, BOOLEAN timed_out) { - uv_write_t* req; - uv_tcp_t* handle; - - req = (uv_write_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->handle; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->u.io.overlapped.InternalHigh, - 0, - &req->u.io.overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void uv_pipe_queue_read(uv_loop_t* loop, uv_pipe_t* handle) { - uv_read_t* req; - int result; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - assert(handle->handle != INVALID_HANDLE_VALUE); - - req = &handle->read_req; - - if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { - if (!QueueUserWorkItem(&uv_pipe_zero_readfile_thread_proc, - req, - WT_EXECUTELONGFUNCTION)) { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - goto error; - } - } else { - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->u.io.overlapped.hEvent = (HANDLE) ((uintptr_t) req->event_handle | 1); - } - - /* Do 0-read */ - result = ReadFile(handle->handle, - &uv_zero_, - 0, - NULL, - &req->u.io.overlapped); - - if (!result && GetLastError() != ERROR_IO_PENDING) { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - goto error; - } - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (!req->event_handle) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } - if (req->wait_handle == INVALID_HANDLE_VALUE) { - if (!RegisterWaitForSingleObject(&req->wait_handle, - req->u.io.overlapped.hEvent, post_completion_read_wait, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - SET_REQ_ERROR(req, GetLastError()); - goto error; - } - } - } - } - - /* Start the eof timer if there is one */ - eof_timer_start(handle); - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - return; - -error: - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; -} - - -int uv_pipe_read_start(uv_pipe_t* handle, - uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - uv_loop_t* loop = handle->loop; - - handle->flags |= UV_HANDLE_READING; - INCREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb = read_cb; - handle->alloc_cb = alloc_cb; - - /* If reading was stopped and then started again, there could still be a */ - /* read request pending. */ - if (!(handle->flags & UV_HANDLE_READ_PENDING)) - uv_pipe_queue_read(loop, handle); - - return 0; -} - - -static void uv_insert_non_overlapped_write_req(uv_pipe_t* handle, - uv_write_t* req) { - req->next_req = NULL; - if (handle->pipe.conn.non_overlapped_writes_tail) { - req->next_req = - handle->pipe.conn.non_overlapped_writes_tail->next_req; - handle->pipe.conn.non_overlapped_writes_tail->next_req = (uv_req_t*)req; - handle->pipe.conn.non_overlapped_writes_tail = req; - } else { - req->next_req = (uv_req_t*)req; - handle->pipe.conn.non_overlapped_writes_tail = req; - } -} - - -static uv_write_t* uv_remove_non_overlapped_write_req(uv_pipe_t* handle) { - uv_write_t* req; - - if (handle->pipe.conn.non_overlapped_writes_tail) { - req = (uv_write_t*)handle->pipe.conn.non_overlapped_writes_tail->next_req; - - if (req == handle->pipe.conn.non_overlapped_writes_tail) { - handle->pipe.conn.non_overlapped_writes_tail = NULL; - } else { - handle->pipe.conn.non_overlapped_writes_tail->next_req = - req->next_req; - } - - return req; - } else { - /* queue empty */ - return NULL; - } -} - - -static void uv_queue_non_overlapped_write(uv_pipe_t* handle) { - uv_write_t* req = uv_remove_non_overlapped_write_req(handle); - if (req) { - if (!QueueUserWorkItem(&uv_pipe_writefile_thread_proc, - req, - WT_EXECUTELONGFUNCTION)) { - uv_fatal_error(GetLastError(), "QueueUserWorkItem"); - } - } -} - - -static int uv_pipe_write_impl(uv_loop_t* loop, - uv_write_t* req, - uv_pipe_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - int err; - int result; - uv_tcp_t* tcp_send_handle; - uv_write_t* ipc_header_req = NULL; - uv_ipc_frame_uv_stream ipc_frame; - - if (nbufs != 1 && (nbufs != 0 || !send_handle)) { - return ERROR_NOT_SUPPORTED; - } - - /* Only TCP handles are supported for sharing. */ - if (send_handle && ((send_handle->type != UV_TCP) || - (!(send_handle->flags & UV_HANDLE_BOUND) && - !(send_handle->flags & UV_HANDLE_CONNECTION)))) { - return ERROR_NOT_SUPPORTED; - } - - assert(handle->handle != INVALID_HANDLE_VALUE); - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - req->ipc_header = 0; - req->event_handle = NULL; - req->wait_handle = INVALID_HANDLE_VALUE; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - if (handle->ipc) { - assert(!(handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)); - ipc_frame.header.flags = 0; - - /* Use the IPC framing protocol. */ - if (send_handle) { - tcp_send_handle = (uv_tcp_t*)send_handle; - - if (handle->pipe.conn.ipc_pid == 0) { - handle->pipe.conn.ipc_pid = uv_current_pid(); - } - - err = uv_tcp_duplicate_socket(tcp_send_handle, handle->pipe.conn.ipc_pid, - &ipc_frame.socket_info_ex.socket_info); - if (err) { - return err; - } - - ipc_frame.socket_info_ex.delayed_error = tcp_send_handle->delayed_error; - - ipc_frame.header.flags |= UV_IPC_TCP_SERVER; - - if (tcp_send_handle->flags & UV_HANDLE_CONNECTION) { - ipc_frame.header.flags |= UV_IPC_TCP_CONNECTION; - } - } - - if (nbufs == 1) { - ipc_frame.header.flags |= UV_IPC_RAW_DATA; - ipc_frame.header.raw_data_length = bufs[0].len; - } - - /* - * Use the provided req if we're only doing a single write. - * If we're doing multiple writes, use ipc_header_write_req to do - * the first write, and then use the provided req for the second write. - */ - if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) { - ipc_header_req = req; - } else { - /* - * Try to use the preallocated write req if it's available. - * Otherwise allocate a new one. - */ - if (handle->pipe.conn.ipc_header_write_req.type != UV_WRITE) { - ipc_header_req = (uv_write_t*)&handle->pipe.conn.ipc_header_write_req; - } else { - ipc_header_req = (uv_write_t*)uv__malloc(sizeof(uv_write_t)); - if (!ipc_header_req) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - } - - uv_req_init(loop, (uv_req_t*) ipc_header_req); - ipc_header_req->type = UV_WRITE; - ipc_header_req->handle = (uv_stream_t*) handle; - ipc_header_req->cb = NULL; - ipc_header_req->ipc_header = 1; - } - - /* Write the header or the whole frame. */ - memset(&ipc_header_req->u.io.overlapped, 0, - sizeof(ipc_header_req->u.io.overlapped)); - - /* Using overlapped IO, but wait for completion before returning. - This write is blocking because ipc_frame is on stack. */ - ipc_header_req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL); - if (!ipc_header_req->u.io.overlapped.hEvent) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - - result = WriteFile(handle->handle, - &ipc_frame, - ipc_frame.header.flags & UV_IPC_TCP_SERVER ? - sizeof(ipc_frame) : sizeof(ipc_frame.header), - NULL, - &ipc_header_req->u.io.overlapped); - if (!result && GetLastError() != ERROR_IO_PENDING) { - err = GetLastError(); - CloseHandle(ipc_header_req->u.io.overlapped.hEvent); - return err; - } - - if (!result) { - /* Request not completed immediately. Wait for it.*/ - if (WaitForSingleObject(ipc_header_req->u.io.overlapped.hEvent, INFINITE) != - WAIT_OBJECT_0) { - err = GetLastError(); - CloseHandle(ipc_header_req->u.io.overlapped.hEvent); - return err; - } - } - ipc_header_req->u.io.queued_bytes = 0; - CloseHandle(ipc_header_req->u.io.overlapped.hEvent); - ipc_header_req->u.io.overlapped.hEvent = NULL; - - REGISTER_HANDLE_REQ(loop, handle, ipc_header_req); - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - - /* If we don't have any raw data to write - we're done. */ - if (!(ipc_frame.header.flags & UV_IPC_RAW_DATA)) { - return 0; - } - } - - if ((handle->flags & - (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) == - (UV_HANDLE_BLOCKING_WRITES | UV_HANDLE_NON_OVERLAPPED_PIPE)) { - DWORD bytes; - result = WriteFile(handle->handle, - bufs[0].base, - bufs[0].len, - &bytes, - NULL); - - if (!result) { - err = GetLastError(); - return err; - } else { - /* Request completed immediately. */ - req->u.io.queued_bytes = 0; - } - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - POST_COMPLETION_FOR_REQ(loop, req); - return 0; - } else if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE) { - req->write_buffer = bufs[0]; - uv_insert_non_overlapped_write_req(handle, req); - if (handle->stream.conn.write_reqs_pending == 0) { - uv_queue_non_overlapped_write(handle); - } - - /* Request queued by the kernel. */ - req->u.io.queued_bytes = bufs[0].len; - handle->write_queue_size += req->u.io.queued_bytes; - } else if (handle->flags & UV_HANDLE_BLOCKING_WRITES) { - /* Using overlapped IO, but wait for completion before returning */ - req->u.io.overlapped.hEvent = CreateEvent(NULL, 1, 0, NULL); - if (!req->u.io.overlapped.hEvent) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - - result = WriteFile(handle->handle, - bufs[0].base, - bufs[0].len, - NULL, - &req->u.io.overlapped); - - if (!result && GetLastError() != ERROR_IO_PENDING) { - err = GetLastError(); - CloseHandle(req->u.io.overlapped.hEvent); - return err; - } - - if (result) { - /* Request completed immediately. */ - req->u.io.queued_bytes = 0; - } else { - /* Request queued by the kernel. */ - req->u.io.queued_bytes = bufs[0].len; - handle->write_queue_size += req->u.io.queued_bytes; - if (WaitForSingleObject(req->u.io.overlapped.hEvent, INFINITE) != - WAIT_OBJECT_0) { - err = GetLastError(); - CloseHandle(req->u.io.overlapped.hEvent); - return uv_translate_sys_error(err); - } - } - CloseHandle(req->u.io.overlapped.hEvent); - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - return 0; - } else { - result = WriteFile(handle->handle, - bufs[0].base, - bufs[0].len, - NULL, - &req->u.io.overlapped); - - if (!result && GetLastError() != ERROR_IO_PENDING) { - return GetLastError(); - } - - if (result) { - /* Request completed immediately. */ - req->u.io.queued_bytes = 0; - } else { - /* Request queued by the kernel. */ - req->u.io.queued_bytes = bufs[0].len; - handle->write_queue_size += req->u.io.queued_bytes; - } - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - if (!RegisterWaitForSingleObject(&req->wait_handle, - req->u.io.overlapped.hEvent, post_completion_write_wait, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - return GetLastError(); - } - } - } - - REGISTER_HANDLE_REQ(loop, handle, req); - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - - return 0; -} - - -int uv_pipe_write(uv_loop_t* loop, - uv_write_t* req, - uv_pipe_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, NULL, cb); -} - - -int uv_pipe_write2(uv_loop_t* loop, - uv_write_t* req, - uv_pipe_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - if (!handle->ipc) { - return WSAEINVAL; - } - - return uv_pipe_write_impl(loop, req, handle, bufs, nbufs, send_handle, cb); -} - - -static void uv_pipe_read_eof(uv_loop_t* loop, uv_pipe_t* handle, - uv_buf_t buf) { - /* If there is an eof timer running, we don't need it any more, */ - /* so discard it. */ - eof_timer_destroy(handle); - - handle->flags &= ~UV_HANDLE_READABLE; - uv_read_stop((uv_stream_t*) handle); - - handle->read_cb((uv_stream_t*) handle, UV_EOF, &buf); -} - - -static void uv_pipe_read_error(uv_loop_t* loop, uv_pipe_t* handle, int error, - uv_buf_t buf) { - /* If there is an eof timer running, we don't need it any more, */ - /* so discard it. */ - eof_timer_destroy(handle); - - uv_read_stop((uv_stream_t*) handle); - - handle->read_cb((uv_stream_t*)handle, uv_translate_sys_error(error), &buf); -} - - -static void uv_pipe_read_error_or_eof(uv_loop_t* loop, uv_pipe_t* handle, - int error, uv_buf_t buf) { - if (error == ERROR_BROKEN_PIPE) { - uv_pipe_read_eof(loop, handle, buf); - } else { - uv_pipe_read_error(loop, handle, error, buf); - } -} - - -void uv__pipe_insert_pending_socket(uv_pipe_t* handle, - uv__ipc_socket_info_ex* info, - int tcp_connection) { - uv__ipc_queue_item_t* item; - - item = (uv__ipc_queue_item_t*) uv__malloc(sizeof(*item)); - if (item == NULL) - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - - memcpy(&item->socket_info_ex, info, sizeof(item->socket_info_ex)); - item->tcp_connection = tcp_connection; - QUEUE_INSERT_TAIL(&handle->pipe.conn.pending_ipc_info.queue, &item->member); - handle->pipe.conn.pending_ipc_info.queue_len++; -} - - -void uv_process_pipe_read_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* req) { - DWORD bytes, avail; - uv_buf_t buf; - uv_ipc_frame_uv_stream ipc_frame; - - assert(handle->type == UV_NAMED_PIPE); - - handle->flags &= ~UV_HANDLE_READ_PENDING; - eof_timer_stop(handle); - - if (!REQ_SUCCESS(req)) { - /* An error occurred doing the 0-read. */ - if (handle->flags & UV_HANDLE_READING) { - uv_pipe_read_error_or_eof(loop, - handle, - GET_REQ_ERROR(req), - uv_null_buf_); - } - } else { - /* Do non-blocking reads until the buffer is empty */ - while (handle->flags & UV_HANDLE_READING) { - if (!PeekNamedPipe(handle->handle, - NULL, - 0, - NULL, - &avail, - NULL)) { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), uv_null_buf_); - break; - } - - if (avail == 0) { - /* There is nothing to read after all. */ - break; - } - - if (handle->ipc) { - /* Use the IPC framing protocol to read the incoming data. */ - if (handle->pipe.conn.remaining_ipc_rawdata_bytes == 0) { - /* We're reading a new frame. First, read the header. */ - assert(avail >= sizeof(ipc_frame.header)); - - if (!ReadFile(handle->handle, - &ipc_frame.header, - sizeof(ipc_frame.header), - &bytes, - NULL)) { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), - uv_null_buf_); - break; - } - - assert(bytes == sizeof(ipc_frame.header)); - assert(ipc_frame.header.flags <= (UV_IPC_TCP_SERVER | UV_IPC_RAW_DATA | - UV_IPC_TCP_CONNECTION)); - - if (ipc_frame.header.flags & UV_IPC_TCP_SERVER) { - assert(avail - sizeof(ipc_frame.header) >= - sizeof(ipc_frame.socket_info_ex)); - - /* Read the TCP socket info. */ - if (!ReadFile(handle->handle, - &ipc_frame.socket_info_ex, - sizeof(ipc_frame) - sizeof(ipc_frame.header), - &bytes, - NULL)) { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), - uv_null_buf_); - break; - } - - assert(bytes == sizeof(ipc_frame) - sizeof(ipc_frame.header)); - - /* Store the pending socket info. */ - uv__pipe_insert_pending_socket( - handle, - &ipc_frame.socket_info_ex, - ipc_frame.header.flags & UV_IPC_TCP_CONNECTION); - } - - if (ipc_frame.header.flags & UV_IPC_RAW_DATA) { - handle->pipe.conn.remaining_ipc_rawdata_bytes = - ipc_frame.header.raw_data_length; - continue; - } - } else { - avail = min(avail, (DWORD)handle->pipe.conn.remaining_ipc_rawdata_bytes); - } - } - - handle->alloc_cb((uv_handle_t*) handle, avail, &buf); - if (buf.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); - break; - } - assert(buf.base != NULL); - - if (ReadFile(handle->handle, - buf.base, - min(buf.len, avail), - &bytes, - NULL)) { - /* Successful read */ - if (handle->ipc) { - assert(handle->pipe.conn.remaining_ipc_rawdata_bytes >= bytes); - handle->pipe.conn.remaining_ipc_rawdata_bytes = - handle->pipe.conn.remaining_ipc_rawdata_bytes - bytes; - } - handle->read_cb((uv_stream_t*)handle, bytes, &buf); - - /* Read again only if bytes == buf.len */ - if (bytes <= buf.len) { - break; - } - } else { - uv_pipe_read_error_or_eof(loop, handle, GetLastError(), buf); - break; - } - } - - /* Post another 0-read if still reading and not closing. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_pipe_queue_read(loop, handle); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_write_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_write_t* req) { - int err; - - assert(handle->type == UV_NAMED_PIPE); - - assert(handle->write_queue_size >= req->u.io.queued_bytes); - handle->write_queue_size -= req->u.io.queued_bytes; - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (req->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(req->wait_handle); - req->wait_handle = INVALID_HANDLE_VALUE; - } - if (req->event_handle) { - CloseHandle(req->event_handle); - req->event_handle = NULL; - } - } - - if (req->ipc_header) { - if (req == &handle->pipe.conn.ipc_header_write_req) { - req->type = UV_UNKNOWN_REQ; - } else { - uv__free(req); - } - } else { - if (req->cb) { - err = GET_REQ_ERROR(req); - req->cb(req, uv_translate_sys_error(err)); - } - } - - handle->stream.conn.write_reqs_pending--; - - if (handle->flags & UV_HANDLE_NON_OVERLAPPED_PIPE && - handle->pipe.conn.non_overlapped_writes_tail) { - assert(handle->stream.conn.write_reqs_pending > 0); - uv_queue_non_overlapped_write(handle); - } - - if (handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_accept_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_req_t* raw_req) { - uv_pipe_accept_t* req = (uv_pipe_accept_t*) raw_req; - - assert(handle->type == UV_NAMED_PIPE); - - if (handle->flags & UV__HANDLE_CLOSING) { - /* The req->pipeHandle should be freed already in uv_pipe_cleanup(). */ - assert(req->pipeHandle == INVALID_HANDLE_VALUE); - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (REQ_SUCCESS(req)) { - assert(req->pipeHandle != INVALID_HANDLE_VALUE); - req->next_pending = handle->pipe.serv.pending_accepts; - handle->pipe.serv.pending_accepts = req; - - if (handle->stream.serv.connection_cb) { - handle->stream.serv.connection_cb((uv_stream_t*)handle, 0); - } - } else { - if (req->pipeHandle != INVALID_HANDLE_VALUE) { - CloseHandle(req->pipeHandle); - req->pipeHandle = INVALID_HANDLE_VALUE; - } - if (!(handle->flags & UV__HANDLE_CLOSING)) { - uv_pipe_queue_accept(loop, handle, req, FALSE); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_connect_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_connect_t* req) { - int err; - - assert(handle->type == UV_NAMED_PIPE); - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (req->cb) { - err = 0; - if (REQ_SUCCESS(req)) { - uv_pipe_connection_init(handle); - } else { - err = GET_REQ_ERROR(req); - } - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_pipe_shutdown_req(uv_loop_t* loop, uv_pipe_t* handle, - uv_shutdown_t* req) { - assert(handle->type == UV_NAMED_PIPE); - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (handle->flags & UV_HANDLE_READABLE) { - /* Initialize and optionally start the eof timer. Only do this if the */ - /* pipe is readable and we haven't seen EOF come in ourselves. */ - eof_timer_init(handle); - - /* If reading start the timer right now. */ - /* Otherwise uv_pipe_queue_read will start it. */ - if (handle->flags & UV_HANDLE_READ_PENDING) { - eof_timer_start(handle); - } - - } else { - /* This pipe is not readable. We can just close it to let the other end */ - /* know that we're done writing. */ - close_pipe(handle); - } - - if (req->cb) { - req->cb(req, 0); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -static void eof_timer_init(uv_pipe_t* pipe) { - int r; - - assert(pipe->pipe.conn.eof_timer == NULL); - assert(pipe->flags & UV_HANDLE_CONNECTION); - - pipe->pipe.conn.eof_timer = (uv_timer_t*) uv__malloc(sizeof *pipe->pipe.conn.eof_timer); - - r = uv_timer_init(pipe->loop, pipe->pipe.conn.eof_timer); - assert(r == 0); /* timers can't fail */ - pipe->pipe.conn.eof_timer->data = pipe; - uv_unref((uv_handle_t*) pipe->pipe.conn.eof_timer); -} - - -static void eof_timer_start(uv_pipe_t* pipe) { - assert(pipe->flags & UV_HANDLE_CONNECTION); - - if (pipe->pipe.conn.eof_timer != NULL) { - uv_timer_start(pipe->pipe.conn.eof_timer, eof_timer_cb, eof_timeout, 0); - } -} - - -static void eof_timer_stop(uv_pipe_t* pipe) { - assert(pipe->flags & UV_HANDLE_CONNECTION); - - if (pipe->pipe.conn.eof_timer != NULL) { - uv_timer_stop(pipe->pipe.conn.eof_timer); - } -} - - -static void eof_timer_cb(uv_timer_t* timer) { - uv_pipe_t* pipe = (uv_pipe_t*) timer->data; - uv_loop_t* loop = timer->loop; - - assert(pipe->type == UV_NAMED_PIPE); - - /* This should always be true, since we start the timer only */ - /* in uv_pipe_queue_read after successfully calling ReadFile, */ - /* or in uv_process_pipe_shutdown_req if a read is pending, */ - /* and we always immediately stop the timer in */ - /* uv_process_pipe_read_req. */ - assert(pipe->flags & UV_HANDLE_READ_PENDING); - - /* If there are many packets coming off the iocp then the timer callback */ - /* may be called before the read request is coming off the queue. */ - /* Therefore we check here if the read request has completed but will */ - /* be processed later. */ - if ((pipe->flags & UV_HANDLE_READ_PENDING) && - HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) { - return; - } - - /* Force both ends off the pipe. */ - close_pipe(pipe); - - /* Stop reading, so the pending read that is going to fail will */ - /* not be reported to the user. */ - uv_read_stop((uv_stream_t*) pipe); - - /* Report the eof and update flags. This will get reported even if the */ - /* user stopped reading in the meantime. TODO: is that okay? */ - uv_pipe_read_eof(loop, pipe, uv_null_buf_); -} - - -static void eof_timer_destroy(uv_pipe_t* pipe) { - assert(pipe->flags & UV_HANDLE_CONNECTION); - - if (pipe->pipe.conn.eof_timer) { - uv_close((uv_handle_t*) pipe->pipe.conn.eof_timer, eof_timer_close_cb); - pipe->pipe.conn.eof_timer = NULL; - } -} - - -static void eof_timer_close_cb(uv_handle_t* handle) { - assert(handle->type == UV_TIMER); - uv__free(handle); -} - - -int uv_pipe_open(uv_pipe_t* pipe, uv_file file) { - HANDLE os_handle = uv__get_osfhandle(file); - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_ACCESS_INFORMATION access; - DWORD duplex_flags = 0; - - if (os_handle == INVALID_HANDLE_VALUE) - return UV_EBADF; - - /* In order to avoid closing a stdio file descriptor 0-2, duplicate the - * underlying OS handle and forget about the original fd. - * We could also opt to use the original OS handle and just never close it, - * but then there would be no reliable way to cancel pending read operations - * upon close. - */ - if (file <= 2) { - if (!DuplicateHandle(INVALID_HANDLE_VALUE, - os_handle, - INVALID_HANDLE_VALUE, - &os_handle, - 0, - FALSE, - DUPLICATE_SAME_ACCESS)) - return uv_translate_sys_error(GetLastError()); - file = -1; - } - - /* Determine what kind of permissions we have on this handle. - * Cygwin opens the pipe in message mode, but we can support it, - * just query the access flags and set the stream flags accordingly. - */ - nt_status = pNtQueryInformationFile(os_handle, - &io_status, - &access, - sizeof(access), - FileAccessInformation); - if (nt_status != STATUS_SUCCESS) - return UV_EINVAL; - - if (pipe->ipc) { - if (!(access.AccessFlags & FILE_WRITE_DATA) || - !(access.AccessFlags & FILE_READ_DATA)) { - return UV_EINVAL; - } - } - - if (access.AccessFlags & FILE_WRITE_DATA) - duplex_flags |= UV_HANDLE_WRITABLE; - if (access.AccessFlags & FILE_READ_DATA) - duplex_flags |= UV_HANDLE_READABLE; - - if (os_handle == INVALID_HANDLE_VALUE || - uv_set_pipe_handle(pipe->loop, - pipe, - os_handle, - file, - duplex_flags) == -1) { - return UV_EINVAL; - } - - uv_pipe_connection_init(pipe); - - if (pipe->ipc) { - assert(!(pipe->flags & UV_HANDLE_NON_OVERLAPPED_PIPE)); - pipe->pipe.conn.ipc_pid = uv_parent_pid(); - assert(pipe->pipe.conn.ipc_pid != -1); - } - return 0; -} - - -static int uv__pipe_getname(const uv_pipe_t* handle, char* buffer, size_t* size) { - NTSTATUS nt_status; - IO_STATUS_BLOCK io_status; - FILE_NAME_INFORMATION tmp_name_info; - FILE_NAME_INFORMATION* name_info; - WCHAR* name_buf; - unsigned int addrlen; - unsigned int name_size; - unsigned int name_len; - int err; - - name_info = NULL; - - if (handle->handle == INVALID_HANDLE_VALUE) { - *size = 0; - return UV_EINVAL; - } - - uv__pipe_pause_read((uv_pipe_t*)handle); /* cast away const warning */ - - nt_status = pNtQueryInformationFile(handle->handle, - &io_status, - &tmp_name_info, - sizeof tmp_name_info, - FileNameInformation); - if (nt_status == STATUS_BUFFER_OVERFLOW) { - name_size = sizeof(*name_info) + tmp_name_info.FileNameLength; - name_info = uv__malloc(name_size); - if (!name_info) { - *size = 0; - err = UV_ENOMEM; - goto cleanup; - } - - nt_status = pNtQueryInformationFile(handle->handle, - &io_status, - name_info, - name_size, - FileNameInformation); - } - - if (nt_status != STATUS_SUCCESS) { - *size = 0; - err = uv_translate_sys_error(pRtlNtStatusToDosError(nt_status)); - goto error; - } - - if (!name_info) { - /* the struct on stack was used */ - name_buf = tmp_name_info.FileName; - name_len = tmp_name_info.FileNameLength; - } else { - name_buf = name_info->FileName; - name_len = name_info->FileNameLength; - } - - if (name_len == 0) { - *size = 0; - err = 0; - goto error; - } - - name_len /= sizeof(WCHAR); - - /* check how much space we need */ - addrlen = WideCharToMultiByte(CP_UTF8, - 0, - name_buf, - name_len, - NULL, - 0, - NULL, - NULL); - if (!addrlen) { - *size = 0; - err = uv_translate_sys_error(GetLastError()); - goto error; - } else if (pipe_prefix_len + addrlen >= *size) { - /* "\\\\.\\pipe" + name */ - *size = pipe_prefix_len + addrlen + 1; - err = UV_ENOBUFS; - goto error; - } - - memcpy(buffer, pipe_prefix, pipe_prefix_len); - addrlen = WideCharToMultiByte(CP_UTF8, - 0, - name_buf, - name_len, - buffer+pipe_prefix_len, - *size-pipe_prefix_len, - NULL, - NULL); - if (!addrlen) { - *size = 0; - err = uv_translate_sys_error(GetLastError()); - goto error; - } - - addrlen += pipe_prefix_len; - *size = addrlen; - buffer[addrlen] = '\0'; - - err = 0; - goto cleanup; - -error: - uv__free(name_info); - -cleanup: - uv__pipe_unpause_read((uv_pipe_t*)handle); /* cast away const warning */ - return err; -} - - -int uv_pipe_pending_count(uv_pipe_t* handle) { - if (!handle->ipc) - return 0; - return handle->pipe.conn.pending_ipc_info.queue_len; -} - - -int uv_pipe_getsockname(const uv_pipe_t* handle, char* buffer, size_t* size) { - if (handle->flags & UV_HANDLE_BOUND) - return uv__pipe_getname(handle, buffer, size); - - if (handle->flags & UV_HANDLE_CONNECTION || - handle->handle != INVALID_HANDLE_VALUE) { - *size = 0; - return 0; - } - - return UV_EBADF; -} - - -int uv_pipe_getpeername(const uv_pipe_t* handle, char* buffer, size_t* size) { - /* emulate unix behaviour */ - if (handle->flags & UV_HANDLE_BOUND) - return UV_ENOTCONN; - - if (handle->handle != INVALID_HANDLE_VALUE) - return uv__pipe_getname(handle, buffer, size); - - return UV_EBADF; -} - - -uv_handle_type uv_pipe_pending_type(uv_pipe_t* handle) { - if (!handle->ipc) - return UV_UNKNOWN_HANDLE; - if (handle->pipe.conn.pending_ipc_info.queue_len == 0) - return UV_UNKNOWN_HANDLE; - else - return UV_TCP; -} diff --git a/3rdparty/libuv/src/win/poll.c b/3rdparty/libuv/src/win/poll.c deleted file mode 100644 index d479e521efe..00000000000 --- a/3rdparty/libuv/src/win/poll.c +++ /dev/null @@ -1,646 +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. - */ - -#include <assert.h> -#include <io.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -static const GUID uv_msafd_provider_ids[UV_MSAFD_PROVIDER_COUNT] = { - {0xe70f1aa0, 0xab8b, 0x11cf, - {0x8c, 0xa3, 0x00, 0x80, 0x5f, 0x48, 0xa1, 0x92}}, - {0xf9eab0c0, 0x26d4, 0x11d0, - {0xbb, 0xbf, 0x00, 0xaa, 0x00, 0x6c, 0x34, 0xe4}}, - {0x9fc48064, 0x7298, 0x43e4, - {0xb7, 0xbd, 0x18, 0x1f, 0x20, 0x89, 0x79, 0x2a}} -}; - -typedef struct uv_single_fd_set_s { - unsigned int fd_count; - SOCKET fd_array[1]; -} uv_single_fd_set_t; - - -static OVERLAPPED overlapped_dummy_; -static uv_once_t overlapped_dummy_init_guard_ = UV_ONCE_INIT; - -static AFD_POLL_INFO afd_poll_info_dummy_; - - -static void uv__init_overlapped_dummy(void) { - HANDLE event; - - event = CreateEvent(NULL, TRUE, TRUE, NULL); - if (event == NULL) - uv_fatal_error(GetLastError(), "CreateEvent"); - - memset(&overlapped_dummy_, 0, sizeof overlapped_dummy_); - overlapped_dummy_.hEvent = (HANDLE) ((uintptr_t) event | 1); -} - - -static OVERLAPPED* uv__get_overlapped_dummy() { - uv_once(&overlapped_dummy_init_guard_, uv__init_overlapped_dummy); - return &overlapped_dummy_; -} - - -static AFD_POLL_INFO* uv__get_afd_poll_info_dummy() { - return &afd_poll_info_dummy_; -} - - -static void uv__fast_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) { - uv_req_t* req; - AFD_POLL_INFO* afd_poll_info; - DWORD result; - - /* Find a yet unsubmitted req to submit. */ - if (handle->submitted_events_1 == 0) { - req = &handle->poll_req_1; - afd_poll_info = &handle->afd_poll_info_1; - handle->submitted_events_1 = handle->events; - handle->mask_events_1 = 0; - handle->mask_events_2 = handle->events; - } else if (handle->submitted_events_2 == 0) { - req = &handle->poll_req_2; - afd_poll_info = &handle->afd_poll_info_2; - handle->submitted_events_2 = handle->events; - handle->mask_events_1 = handle->events; - handle->mask_events_2 = 0; - } else { - /* Just wait until there's an unsubmitted req. */ - /* This will happen almost immediately as one of the 2 outstanding */ - /* requests is about to return. When this happens, */ - /* uv__fast_poll_process_poll_req will be called, and the pending */ - /* events, if needed, will be processed in a subsequent request. */ - return; - } - - /* Setting Exclusive to TRUE makes the other poll request return if there */ - /* is any. */ - afd_poll_info->Exclusive = TRUE; - afd_poll_info->NumberOfHandles = 1; - afd_poll_info->Timeout.QuadPart = INT64_MAX; - afd_poll_info->Handles[0].Handle = (HANDLE) handle->socket; - afd_poll_info->Handles[0].Status = 0; - afd_poll_info->Handles[0].Events = 0; - - if (handle->events & UV_READABLE) { - afd_poll_info->Handles[0].Events |= AFD_POLL_RECEIVE | - AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT; - } else { - if (handle->events & UV_DISCONNECT) { - afd_poll_info->Handles[0].Events |= AFD_POLL_DISCONNECT; - } - } - if (handle->events & UV_WRITABLE) { - afd_poll_info->Handles[0].Events |= AFD_POLL_SEND | AFD_POLL_CONNECT_FAIL; - } - - memset(&req->u.io.overlapped, 0, sizeof req->u.io.overlapped); - - result = uv_msafd_poll((SOCKET) handle->peer_socket, - afd_poll_info, - afd_poll_info, - &req->u.io.overlapped); - if (result != 0 && WSAGetLastError() != WSA_IO_PENDING) { - /* Queue this req, reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, req); - } -} - - -static int uv__fast_poll_cancel_poll_req(uv_loop_t* loop, uv_poll_t* handle) { - AFD_POLL_INFO afd_poll_info; - DWORD result; - - afd_poll_info.Exclusive = TRUE; - afd_poll_info.NumberOfHandles = 1; - afd_poll_info.Timeout.QuadPart = INT64_MAX; - afd_poll_info.Handles[0].Handle = (HANDLE) handle->socket; - afd_poll_info.Handles[0].Status = 0; - afd_poll_info.Handles[0].Events = AFD_POLL_ALL; - - result = uv_msafd_poll(handle->socket, - &afd_poll_info, - uv__get_afd_poll_info_dummy(), - uv__get_overlapped_dummy()); - - if (result == SOCKET_ERROR) { - DWORD error = WSAGetLastError(); - if (error != WSA_IO_PENDING) - return error; - } - - return 0; -} - - -static void uv__fast_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, - uv_req_t* req) { - unsigned char mask_events; - AFD_POLL_INFO* afd_poll_info; - - if (req == &handle->poll_req_1) { - afd_poll_info = &handle->afd_poll_info_1; - handle->submitted_events_1 = 0; - mask_events = handle->mask_events_1; - } else if (req == &handle->poll_req_2) { - afd_poll_info = &handle->afd_poll_info_2; - handle->submitted_events_2 = 0; - mask_events = handle->mask_events_2; - } else { - assert(0); - return; - } - - /* Report an error unless the select was just interrupted. */ - if (!REQ_SUCCESS(req)) { - DWORD error = GET_REQ_SOCK_ERROR(req); - if (error != WSAEINTR && handle->events != 0) { - handle->events = 0; /* Stop the watcher */ - handle->poll_cb(handle, uv_translate_sys_error(error), 0); - } - - } else if (afd_poll_info->NumberOfHandles >= 1) { - unsigned char events = 0; - - if ((afd_poll_info->Handles[0].Events & (AFD_POLL_RECEIVE | - AFD_POLL_DISCONNECT | AFD_POLL_ACCEPT | AFD_POLL_ABORT)) != 0) { - events |= UV_READABLE; - if ((afd_poll_info->Handles[0].Events & AFD_POLL_DISCONNECT) != 0) { - events |= UV_DISCONNECT; - } - } - if ((afd_poll_info->Handles[0].Events & (AFD_POLL_SEND | - AFD_POLL_CONNECT_FAIL)) != 0) { - events |= UV_WRITABLE; - } - - events &= handle->events & ~mask_events; - - if (afd_poll_info->Handles[0].Events & AFD_POLL_LOCAL_CLOSE) { - /* Stop polling. */ - handle->events = 0; - if (uv__is_active(handle)) - uv__handle_stop(handle); - } - - if (events != 0) { - handle->poll_cb(handle, 0, events); - } - } - - if ((handle->events & ~(handle->submitted_events_1 | - handle->submitted_events_2)) != 0) { - uv__fast_poll_submit_poll_req(loop, handle); - } else if ((handle->flags & UV__HANDLE_CLOSING) && - handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -static int uv__fast_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) { - assert(handle->type == UV_POLL); - assert(!(handle->flags & UV__HANDLE_CLOSING)); - assert((events & ~(UV_READABLE | UV_WRITABLE | UV_DISCONNECT)) == 0); - - handle->events = events; - - if (handle->events != 0) { - uv__handle_start(handle); - } else { - uv__handle_stop(handle); - } - - if ((handle->events & ~(handle->submitted_events_1 | - handle->submitted_events_2)) != 0) { - uv__fast_poll_submit_poll_req(handle->loop, handle); - } - - return 0; -} - - -static int uv__fast_poll_close(uv_loop_t* loop, uv_poll_t* handle) { - handle->events = 0; - uv__handle_closing(handle); - - if (handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - return 0; - } else { - /* Cancel outstanding poll requests by executing another, unique poll */ - /* request that forces the outstanding ones to return. */ - return uv__fast_poll_cancel_poll_req(loop, handle); - } -} - - -static SOCKET uv__fast_poll_create_peer_socket(HANDLE iocp, - WSAPROTOCOL_INFOW* protocol_info) { - SOCKET sock = 0; - - sock = WSASocketW(protocol_info->iAddressFamily, - protocol_info->iSocketType, - protocol_info->iProtocol, - protocol_info, - 0, - WSA_FLAG_OVERLAPPED); - if (sock == INVALID_SOCKET) { - return INVALID_SOCKET; - } - - if (!SetHandleInformation((HANDLE) sock, HANDLE_FLAG_INHERIT, 0)) { - goto error; - }; - - if (CreateIoCompletionPort((HANDLE) sock, - iocp, - (ULONG_PTR) sock, - 0) == NULL) { - goto error; - } - - return sock; - - error: - closesocket(sock); - return INVALID_SOCKET; -} - - -static SOCKET uv__fast_poll_get_peer_socket(uv_loop_t* loop, - WSAPROTOCOL_INFOW* protocol_info) { - int index, i; - SOCKET peer_socket; - - index = -1; - for (i = 0; (size_t) i < ARRAY_SIZE(uv_msafd_provider_ids); i++) { - if (memcmp((void*) &protocol_info->ProviderId, - (void*) &uv_msafd_provider_ids[i], - sizeof protocol_info->ProviderId) == 0) { - index = i; - } - } - - /* Check if the protocol uses an msafd socket. */ - if (index < 0) { - return INVALID_SOCKET; - } - - /* If we didn't (try) to create a peer socket yet, try to make one. Don't */ - /* try again if the peer socket creation failed earlier for the same */ - /* protocol. */ - peer_socket = loop->poll_peer_sockets[index]; - if (peer_socket == 0) { - peer_socket = uv__fast_poll_create_peer_socket(loop->iocp, protocol_info); - loop->poll_peer_sockets[index] = peer_socket; - } - - return peer_socket; -} - - -static DWORD WINAPI uv__slow_poll_thread_proc(void* arg) { - uv_req_t* req = (uv_req_t*) arg; - uv_poll_t* handle = (uv_poll_t*) req->data; - unsigned char reported_events; - int r; - uv_single_fd_set_t rfds, wfds, efds; - struct timeval timeout; - - assert(handle->type == UV_POLL); - assert(req->type == UV_POLL_REQ); - - if (handle->events & UV_READABLE) { - rfds.fd_count = 1; - rfds.fd_array[0] = handle->socket; - } else { - rfds.fd_count = 0; - } - - if (handle->events & UV_WRITABLE) { - wfds.fd_count = 1; - wfds.fd_array[0] = handle->socket; - efds.fd_count = 1; - efds.fd_array[0] = handle->socket; - } else { - wfds.fd_count = 0; - efds.fd_count = 0; - } - - /* Make the select() time out after 3 minutes. If select() hangs because */ - /* the user closed the socket, we will at least not hang indefinitely. */ - timeout.tv_sec = 3 * 60; - timeout.tv_usec = 0; - - r = select(1, (fd_set*) &rfds, (fd_set*) &wfds, (fd_set*) &efds, &timeout); - if (r == SOCKET_ERROR) { - /* Queue this req, reporting an error. */ - SET_REQ_ERROR(&handle->poll_req_1, WSAGetLastError()); - POST_COMPLETION_FOR_REQ(handle->loop, req); - return 0; - } - - reported_events = 0; - - if (r > 0) { - if (rfds.fd_count > 0) { - assert(rfds.fd_count == 1); - assert(rfds.fd_array[0] == handle->socket); - reported_events |= UV_READABLE; - } - - if (wfds.fd_count > 0) { - assert(wfds.fd_count == 1); - assert(wfds.fd_array[0] == handle->socket); - reported_events |= UV_WRITABLE; - } else if (efds.fd_count > 0) { - assert(efds.fd_count == 1); - assert(efds.fd_array[0] == handle->socket); - reported_events |= UV_WRITABLE; - } - } - - SET_REQ_SUCCESS(req); - req->u.io.overlapped.InternalHigh = (DWORD) reported_events; - POST_COMPLETION_FOR_REQ(handle->loop, req); - - return 0; -} - - -static void uv__slow_poll_submit_poll_req(uv_loop_t* loop, uv_poll_t* handle) { - uv_req_t* req; - - /* Find a yet unsubmitted req to submit. */ - if (handle->submitted_events_1 == 0) { - req = &handle->poll_req_1; - handle->submitted_events_1 = handle->events; - handle->mask_events_1 = 0; - handle->mask_events_2 = handle->events; - } else if (handle->submitted_events_2 == 0) { - req = &handle->poll_req_2; - handle->submitted_events_2 = handle->events; - handle->mask_events_1 = handle->events; - handle->mask_events_2 = 0; - } else { - assert(0); - return; - } - - if (!QueueUserWorkItem(uv__slow_poll_thread_proc, - (void*) req, - WT_EXECUTELONGFUNCTION)) { - /* Make this req pending, reporting an error. */ - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, req); - } -} - - - -static void uv__slow_poll_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, - uv_req_t* req) { - unsigned char mask_events; - int err; - - if (req == &handle->poll_req_1) { - handle->submitted_events_1 = 0; - mask_events = handle->mask_events_1; - } else if (req == &handle->poll_req_2) { - handle->submitted_events_2 = 0; - mask_events = handle->mask_events_2; - } else { - assert(0); - return; - } - - if (!REQ_SUCCESS(req)) { - /* Error. */ - if (handle->events != 0) { - err = GET_REQ_ERROR(req); - handle->events = 0; /* Stop the watcher */ - handle->poll_cb(handle, uv_translate_sys_error(err), 0); - } - } else { - /* Got some events. */ - int events = req->u.io.overlapped.InternalHigh & handle->events & ~mask_events; - if (events != 0) { - handle->poll_cb(handle, 0, events); - } - } - - if ((handle->events & ~(handle->submitted_events_1 | - handle->submitted_events_2)) != 0) { - uv__slow_poll_submit_poll_req(loop, handle); - } else if ((handle->flags & UV__HANDLE_CLOSING) && - handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -static int uv__slow_poll_set(uv_loop_t* loop, uv_poll_t* handle, int events) { - assert(handle->type == UV_POLL); - assert(!(handle->flags & UV__HANDLE_CLOSING)); - assert((events & ~(UV_READABLE | UV_WRITABLE)) == 0); - - handle->events = events; - - if (handle->events != 0) { - uv__handle_start(handle); - } else { - uv__handle_stop(handle); - } - - if ((handle->events & - ~(handle->submitted_events_1 | handle->submitted_events_2)) != 0) { - uv__slow_poll_submit_poll_req(handle->loop, handle); - } - - return 0; -} - - -static int uv__slow_poll_close(uv_loop_t* loop, uv_poll_t* handle) { - handle->events = 0; - uv__handle_closing(handle); - - if (handle->submitted_events_1 == 0 && - handle->submitted_events_2 == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } - - return 0; -} - - -int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) { - return uv_poll_init_socket(loop, handle, (SOCKET) uv__get_osfhandle(fd)); -} - - -int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle, - uv_os_sock_t socket) { - WSAPROTOCOL_INFOW protocol_info; - int len; - SOCKET peer_socket, base_socket; - DWORD bytes; - DWORD yes = 1; - - /* Set the socket to nonblocking mode */ - if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) - return uv_translate_sys_error(WSAGetLastError()); - - /* Try to obtain a base handle for the socket. This increases this chances */ - /* that we find an AFD handle and are able to use the fast poll mechanism. */ - /* This will always fail on windows XP/2k3, since they don't support the */ - /* SIO_BASE_HANDLE ioctl. */ -#ifndef NDEBUG - base_socket = INVALID_SOCKET; -#endif - - if (WSAIoctl(socket, - SIO_BASE_HANDLE, - NULL, - 0, - &base_socket, - sizeof base_socket, - &bytes, - NULL, - NULL) == 0) { - assert(base_socket != 0 && base_socket != INVALID_SOCKET); - socket = base_socket; - } - - uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL); - handle->socket = socket; - handle->events = 0; - - /* Obtain protocol information about the socket. */ - len = sizeof protocol_info; - if (getsockopt(socket, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &len) != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - /* Get the peer socket that is needed to enable fast poll. If the returned */ - /* value is NULL, the protocol is not implemented by MSAFD and we'll have */ - /* to use slow mode. */ - peer_socket = uv__fast_poll_get_peer_socket(loop, &protocol_info); - - if (peer_socket != INVALID_SOCKET) { - /* Initialize fast poll specific fields. */ - handle->peer_socket = peer_socket; - } else { - /* Initialize slow poll specific fields. */ - handle->flags |= UV_HANDLE_POLL_SLOW; - } - - /* Initialize 2 poll reqs. */ - handle->submitted_events_1 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_1)); - handle->poll_req_1.type = UV_POLL_REQ; - handle->poll_req_1.data = handle; - - handle->submitted_events_2 = 0; - uv_req_init(loop, (uv_req_t*) &(handle->poll_req_2)); - handle->poll_req_2.type = UV_POLL_REQ; - handle->poll_req_2.data = handle; - - return 0; -} - - -int uv_poll_start(uv_poll_t* handle, int events, uv_poll_cb cb) { - int err; - - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - err = uv__fast_poll_set(handle->loop, handle, events); - } else { - err = uv__slow_poll_set(handle->loop, handle, events); - } - - if (err) { - return uv_translate_sys_error(err); - } - - handle->poll_cb = cb; - - return 0; -} - - -int uv_poll_stop(uv_poll_t* handle) { - int err; - - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - err = uv__fast_poll_set(handle->loop, handle, 0); - } else { - err = uv__slow_poll_set(handle->loop, handle, 0); - } - - return uv_translate_sys_error(err); -} - - -void uv_process_poll_req(uv_loop_t* loop, uv_poll_t* handle, uv_req_t* req) { - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - uv__fast_poll_process_poll_req(loop, handle, req); - } else { - uv__slow_poll_process_poll_req(loop, handle, req); - } -} - - -int uv_poll_close(uv_loop_t* loop, uv_poll_t* handle) { - if (!(handle->flags & UV_HANDLE_POLL_SLOW)) { - return uv__fast_poll_close(loop, handle); - } else { - return uv__slow_poll_close(loop, handle); - } -} - - -void uv_poll_endgame(uv_loop_t* loop, uv_poll_t* handle) { - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - assert(handle->submitted_events_1 == 0); - assert(handle->submitted_events_2 == 0); - - uv__handle_close(handle); -} diff --git a/3rdparty/libuv/src/win/process-stdio.c b/3rdparty/libuv/src/win/process-stdio.c deleted file mode 100644 index e3c06f57dea..00000000000 --- a/3rdparty/libuv/src/win/process-stdio.c +++ /dev/null @@ -1,510 +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. - */ - -#include <assert.h> -#include <io.h> -#include <stdio.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" - - -/* - * The `child_stdio_buffer` buffer has the following layout: - * int number_of_fds - * unsigned char crt_flags[number_of_fds] - * HANDLE os_handle[number_of_fds] - */ -#define CHILD_STDIO_SIZE(count) \ - (sizeof(int) + \ - sizeof(unsigned char) * (count) + \ - sizeof(uintptr_t) * (count)) - -#define CHILD_STDIO_COUNT(buffer) \ - *((unsigned int*) (buffer)) - -#define CHILD_STDIO_CRT_FLAGS(buffer, fd) \ - *((unsigned char*) (buffer) + sizeof(int) + fd) - -#define CHILD_STDIO_HANDLE(buffer, fd) \ - *((HANDLE*) ((unsigned char*) (buffer) + \ - sizeof(int) + \ - sizeof(unsigned char) * \ - CHILD_STDIO_COUNT((buffer)) + \ - sizeof(HANDLE) * (fd))) - - -/* CRT file descriptor mode flags */ -#define FOPEN 0x01 -#define FEOFLAG 0x02 -#define FCRLF 0x04 -#define FPIPE 0x08 -#define FNOINHERIT 0x10 -#define FAPPEND 0x20 -#define FDEV 0x40 -#define FTEXT 0x80 - - -/* - * Clear the HANDLE_FLAG_INHERIT flag from all HANDLEs that were inherited - * the parent process. Don't check for errors - the stdio handles may not be - * valid, or may be closed already. There is no guarantee that this function - * does a perfect job. - */ -void uv_disable_stdio_inheritance(void) { - HANDLE handle; - STARTUPINFOW si; - - /* Make the windows stdio handles non-inheritable. */ - handle = GetStdHandle(STD_INPUT_HANDLE); - if (handle != NULL && handle != INVALID_HANDLE_VALUE) - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - - handle = GetStdHandle(STD_OUTPUT_HANDLE); - if (handle != NULL && handle != INVALID_HANDLE_VALUE) - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - - handle = GetStdHandle(STD_ERROR_HANDLE); - if (handle != NULL && handle != INVALID_HANDLE_VALUE) - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - - /* Make inherited CRT FDs non-inheritable. */ - GetStartupInfoW(&si); - if (uv__stdio_verify(si.lpReserved2, si.cbReserved2)) - uv__stdio_noinherit(si.lpReserved2); -} - - -static int uv__create_stdio_pipe_pair(uv_loop_t* loop, - uv_pipe_t* server_pipe, HANDLE* child_pipe_ptr, unsigned int flags) { - char pipe_name[64]; - SECURITY_ATTRIBUTES sa; - DWORD server_access = 0; - DWORD client_access = 0; - HANDLE child_pipe = INVALID_HANDLE_VALUE; - int err; - - if (flags & UV_READABLE_PIPE) { - /* The server needs inbound access too, otherwise CreateNamedPipe() */ - /* won't give us the FILE_READ_ATTRIBUTES permission. We need that to */ - /* probe the state of the write buffer when we're trying to shutdown */ - /* the pipe. */ - server_access |= PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND; - client_access |= GENERIC_READ | FILE_WRITE_ATTRIBUTES; - } - if (flags & UV_WRITABLE_PIPE) { - server_access |= PIPE_ACCESS_INBOUND; - client_access |= GENERIC_WRITE | FILE_READ_ATTRIBUTES; - } - - /* Create server pipe handle. */ - err = uv_stdio_pipe_server(loop, - server_pipe, - server_access, - pipe_name, - sizeof(pipe_name)); - if (err) - goto error; - - /* Create child pipe handle. */ - sa.nLength = sizeof sa; - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - child_pipe = CreateFileA(pipe_name, - client_access, - 0, - &sa, - OPEN_EXISTING, - server_pipe->ipc ? FILE_FLAG_OVERLAPPED : 0, - NULL); - if (child_pipe == INVALID_HANDLE_VALUE) { - err = GetLastError(); - goto error; - } - -#ifndef NDEBUG - /* Validate that the pipe was opened in the right mode. */ - { - DWORD mode; - BOOL r = GetNamedPipeHandleState(child_pipe, - &mode, - NULL, - NULL, - NULL, - NULL, - 0); - assert(r == TRUE); - assert(mode == (PIPE_READMODE_BYTE | PIPE_WAIT)); - } -#endif - - /* Do a blocking ConnectNamedPipe. This should not block because we have */ - /* both ends of the pipe created. */ - if (!ConnectNamedPipe(server_pipe->handle, NULL)) { - if (GetLastError() != ERROR_PIPE_CONNECTED) { - err = GetLastError(); - goto error; - } - } - - /* The server end is now readable and/or writable. */ - if (flags & UV_READABLE_PIPE) - server_pipe->flags |= UV_HANDLE_WRITABLE; - if (flags & UV_WRITABLE_PIPE) - server_pipe->flags |= UV_HANDLE_READABLE; - - *child_pipe_ptr = child_pipe; - return 0; - - error: - if (server_pipe->handle != INVALID_HANDLE_VALUE) { - uv_pipe_cleanup(loop, server_pipe); - } - - if (child_pipe != INVALID_HANDLE_VALUE) { - CloseHandle(child_pipe); - } - - return err; -} - - -static int uv__duplicate_handle(uv_loop_t* loop, HANDLE handle, HANDLE* dup) { - HANDLE current_process; - - - /* _get_osfhandle will sometimes return -2 in case of an error. This seems */ - /* to happen when fd <= 2 and the process' corresponding stdio handle is */ - /* set to NULL. Unfortunately DuplicateHandle will happily duplicate */ - /* (HANDLE) -2, so this situation goes unnoticed until someone tries to */ - /* use the duplicate. Therefore we filter out known-invalid handles here. */ - if (handle == INVALID_HANDLE_VALUE || - handle == NULL || - handle == (HANDLE) -2) { - *dup = INVALID_HANDLE_VALUE; - return ERROR_INVALID_HANDLE; - } - - current_process = GetCurrentProcess(); - - if (!DuplicateHandle(current_process, - handle, - current_process, - dup, - 0, - TRUE, - DUPLICATE_SAME_ACCESS)) { - *dup = INVALID_HANDLE_VALUE; - return GetLastError(); - } - - return 0; -} - - -static int uv__duplicate_fd(uv_loop_t* loop, int fd, HANDLE* dup) { - HANDLE handle; - - if (fd == -1) { - *dup = INVALID_HANDLE_VALUE; - return ERROR_INVALID_HANDLE; - } - - handle = uv__get_osfhandle(fd); - return uv__duplicate_handle(loop, handle, dup); -} - - -int uv__create_nul_handle(HANDLE* handle_ptr, - DWORD access) { - HANDLE handle; - SECURITY_ATTRIBUTES sa; - - sa.nLength = sizeof sa; - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - handle = CreateFileW(L"NUL", - access, - FILE_SHARE_READ | FILE_SHARE_WRITE, - &sa, - OPEN_EXISTING, - 0, - NULL); - if (handle == INVALID_HANDLE_VALUE) { - return GetLastError(); - } - - *handle_ptr = handle; - return 0; -} - - -int uv__stdio_create(uv_loop_t* loop, - const uv_process_options_t* options, - BYTE** buffer_ptr) { - BYTE* buffer; - int count, i; - int err; - - count = options->stdio_count; - - if (count < 0 || count > 255) { - /* Only support FDs 0-255 */ - return ERROR_NOT_SUPPORTED; - } else if (count < 3) { - /* There should always be at least 3 stdio handles. */ - count = 3; - } - - /* Allocate the child stdio buffer */ - buffer = (BYTE*) uv__malloc(CHILD_STDIO_SIZE(count)); - if (buffer == NULL) { - return ERROR_OUTOFMEMORY; - } - - /* Prepopulate the buffer with INVALID_HANDLE_VALUE handles so we can */ - /* clean up on failure. */ - CHILD_STDIO_COUNT(buffer) = count; - for (i = 0; i < count; i++) { - CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; - CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; - } - - for (i = 0; i < count; i++) { - uv_stdio_container_t fdopt; - if (i < options->stdio_count) { - fdopt = options->stdio[i]; - } else { - fdopt.flags = UV_IGNORE; - } - - switch (fdopt.flags & (UV_IGNORE | UV_CREATE_PIPE | UV_INHERIT_FD | - UV_INHERIT_STREAM)) { - case UV_IGNORE: - /* Starting a process with no stdin/stout/stderr can confuse it. */ - /* So no matter what the user specified, we make sure the first */ - /* three FDs are always open in their typical modes, e.g. stdin */ - /* be readable and stdout/err should be writable. For FDs > 2, don't */ - /* do anything - all handles in the stdio buffer are initialized with */ - /* INVALID_HANDLE_VALUE, which should be okay. */ - if (i <= 2) { - DWORD access = (i == 0) ? FILE_GENERIC_READ : - FILE_GENERIC_WRITE | FILE_READ_ATTRIBUTES; - - err = uv__create_nul_handle(&CHILD_STDIO_HANDLE(buffer, i), - access); - if (err) - goto error; - - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; - } - break; - - case UV_CREATE_PIPE: { - /* Create a pair of two connected pipe ends; one end is turned into */ - /* an uv_pipe_t for use by the parent. The other one is given to */ - /* the child. */ - uv_pipe_t* parent_pipe = (uv_pipe_t*) fdopt.data.stream; - HANDLE child_pipe = INVALID_HANDLE_VALUE; - - /* Create a new, connected pipe pair. stdio[i].stream should point */ - /* to an uninitialized, but not connected pipe handle. */ - assert(fdopt.data.stream->type == UV_NAMED_PIPE); - assert(!(fdopt.data.stream->flags & UV_HANDLE_CONNECTION)); - assert(!(fdopt.data.stream->flags & UV_HANDLE_PIPESERVER)); - - err = uv__create_stdio_pipe_pair(loop, - parent_pipe, - &child_pipe, - fdopt.flags); - if (err) - goto error; - - CHILD_STDIO_HANDLE(buffer, i) = child_pipe; - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE; - break; - } - - case UV_INHERIT_FD: { - /* Inherit a raw FD. */ - HANDLE child_handle; - - /* Make an inheritable duplicate of the handle. */ - err = uv__duplicate_fd(loop, fdopt.data.fd, &child_handle); - if (err) { - /* If fdopt.data.fd is not valid and fd fd <= 2, then ignore the */ - /* error. */ - if (fdopt.data.fd <= 2 && err == ERROR_INVALID_HANDLE) { - CHILD_STDIO_CRT_FLAGS(buffer, i) = 0; - CHILD_STDIO_HANDLE(buffer, i) = INVALID_HANDLE_VALUE; - break; - } - goto error; - } - - /* Figure out what the type is. */ - switch (GetFileType(child_handle)) { - case FILE_TYPE_DISK: - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN; - break; - - case FILE_TYPE_PIPE: - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FPIPE; - - case FILE_TYPE_CHAR: - case FILE_TYPE_REMOTE: - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; - break; - - case FILE_TYPE_UNKNOWN: - if (GetLastError() != 0) { - err = GetLastError(); - CloseHandle(child_handle); - goto error; - } - CHILD_STDIO_CRT_FLAGS(buffer, i) = FOPEN | FDEV; - break; - - default: - assert(0); - return -1; - } - - CHILD_STDIO_HANDLE(buffer, i) = child_handle; - break; - } - - case UV_INHERIT_STREAM: { - /* Use an existing stream as the stdio handle for the child. */ - HANDLE stream_handle, child_handle; - unsigned char crt_flags; - uv_stream_t* stream = fdopt.data.stream; - - /* Leech the handle out of the stream. */ - if (stream->type == UV_TTY) { - stream_handle = ((uv_tty_t*) stream)->handle; - crt_flags = FOPEN | FDEV; - } else if (stream->type == UV_NAMED_PIPE && - stream->flags & UV_HANDLE_CONNECTION) { - stream_handle = ((uv_pipe_t*) stream)->handle; - crt_flags = FOPEN | FPIPE; - } else { - stream_handle = INVALID_HANDLE_VALUE; - crt_flags = 0; - } - - if (stream_handle == NULL || - stream_handle == INVALID_HANDLE_VALUE) { - /* The handle is already closed, or not yet created, or the */ - /* stream type is not supported. */ - err = ERROR_NOT_SUPPORTED; - goto error; - } - - /* Make an inheritable copy of the handle. */ - err = uv__duplicate_handle(loop, stream_handle, &child_handle); - if (err) - goto error; - - CHILD_STDIO_HANDLE(buffer, i) = child_handle; - CHILD_STDIO_CRT_FLAGS(buffer, i) = crt_flags; - break; - } - - default: - assert(0); - return -1; - } - } - - *buffer_ptr = buffer; - return 0; - - error: - uv__stdio_destroy(buffer); - return err; -} - - -void uv__stdio_destroy(BYTE* buffer) { - int i, count; - - count = CHILD_STDIO_COUNT(buffer); - for (i = 0; i < count; i++) { - HANDLE handle = CHILD_STDIO_HANDLE(buffer, i); - if (handle != INVALID_HANDLE_VALUE) { - CloseHandle(handle); - } - } - - uv__free(buffer); -} - - -void uv__stdio_noinherit(BYTE* buffer) { - int i, count; - - count = CHILD_STDIO_COUNT(buffer); - for (i = 0; i < count; i++) { - HANDLE handle = CHILD_STDIO_HANDLE(buffer, i); - if (handle != INVALID_HANDLE_VALUE) { - SetHandleInformation(handle, HANDLE_FLAG_INHERIT, 0); - } - } -} - - -int uv__stdio_verify(BYTE* buffer, WORD size) { - unsigned int count; - - /* Check the buffer pointer. */ - if (buffer == NULL) - return 0; - - /* Verify that the buffer is at least big enough to hold the count. */ - if (size < CHILD_STDIO_SIZE(0)) - return 0; - - /* Verify if the count is within range. */ - count = CHILD_STDIO_COUNT(buffer); - if (count > 256) - return 0; - - /* Verify that the buffer size is big enough to hold info for N FDs. */ - if (size < CHILD_STDIO_SIZE(count)) - return 0; - - return 1; -} - - -WORD uv__stdio_size(BYTE* buffer) { - return (WORD) CHILD_STDIO_SIZE(CHILD_STDIO_COUNT((buffer))); -} - - -HANDLE uv__stdio_handle(BYTE* buffer, int fd) { - return CHILD_STDIO_HANDLE(buffer, fd); -} diff --git a/3rdparty/libuv/src/win/process.c b/3rdparty/libuv/src/win/process.c deleted file mode 100644 index 855c3740816..00000000000 --- a/3rdparty/libuv/src/win/process.c +++ /dev/null @@ -1,1247 +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. - */ - -#include <assert.h> -#include <io.h> -#include <stdio.h> -#include <stdlib.h> -#include <signal.h> -#include <limits.h> -#include <wchar.h> -#include <malloc.h> /* alloca */ - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -#define SIGKILL 9 - - -typedef struct env_var { - const WCHAR* const wide; - const WCHAR* const wide_eq; - const size_t len; /* including null or '=' */ -} env_var_t; - -#define E_V(str) { L##str, L##str L"=", sizeof(str) } - -static const env_var_t required_vars[] = { /* keep me sorted */ - E_V("HOMEDRIVE"), - E_V("HOMEPATH"), - E_V("LOGONSERVER"), - E_V("PATH"), - E_V("SYSTEMDRIVE"), - E_V("SYSTEMROOT"), - E_V("TEMP"), - E_V("USERDOMAIN"), - E_V("USERNAME"), - E_V("USERPROFILE"), - E_V("WINDIR"), -}; -static size_t n_required_vars = ARRAY_SIZE(required_vars); - - -static HANDLE uv_global_job_handle_; -static uv_once_t uv_global_job_handle_init_guard_ = UV_ONCE_INIT; - - -static void uv__init_global_job_handle(void) { - /* Create a job object and set it up to kill all contained processes when - * it's closed. Since this handle is made non-inheritable and we're not - * giving it to anyone, we're the only process holding a reference to it. - * That means that if this process exits it is closed and all the processes - * it contains are killed. All processes created with uv_spawn that are not - * spawned with the UV_PROCESS_DETACHED flag are assigned to this job. - * - * We're setting the JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag so only the - * processes that we explicitly add are affected, and *their* subprocesses - * are not. This ensures that our child processes are not limited in their - * ability to use job control on Windows versions that don't deal with - * nested jobs (prior to Windows 8 / Server 2012). It also lets our child - * processes created detached processes without explicitly breaking away - * from job control (which uv_spawn doesn't, either). - */ - SECURITY_ATTRIBUTES attr; - JOBOBJECT_EXTENDED_LIMIT_INFORMATION info; - - memset(&attr, 0, sizeof attr); - attr.bInheritHandle = FALSE; - - memset(&info, 0, sizeof info); - info.BasicLimitInformation.LimitFlags = - JOB_OBJECT_LIMIT_BREAKAWAY_OK | - JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK | - JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION | - JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE; - - uv_global_job_handle_ = CreateJobObjectW(&attr, NULL); - if (uv_global_job_handle_ == NULL) - uv_fatal_error(GetLastError(), "CreateJobObjectW"); - - if (!SetInformationJobObject(uv_global_job_handle_, - JobObjectExtendedLimitInformation, - &info, - sizeof info)) - uv_fatal_error(GetLastError(), "SetInformationJobObject"); -} - - -static int uv_utf8_to_utf16_alloc(const char* s, WCHAR** ws_ptr) { - int ws_len, r; - WCHAR* ws; - - ws_len = MultiByteToWideChar(CP_UTF8, - 0, - s, - -1, - NULL, - 0); - if (ws_len <= 0) { - return GetLastError(); - } - - ws = (WCHAR*) uv__malloc(ws_len * sizeof(WCHAR)); - if (ws == NULL) { - return ERROR_OUTOFMEMORY; - } - - r = MultiByteToWideChar(CP_UTF8, - 0, - s, - -1, - ws, - ws_len); - assert(r == ws_len); - - *ws_ptr = ws; - return 0; -} - - -static void uv_process_init(uv_loop_t* loop, uv_process_t* handle) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_PROCESS); - handle->exit_cb = NULL; - handle->pid = 0; - handle->exit_signal = 0; - handle->wait_handle = INVALID_HANDLE_VALUE; - handle->process_handle = INVALID_HANDLE_VALUE; - handle->child_stdio_buffer = NULL; - handle->exit_cb_pending = 0; - - uv_req_init(loop, (uv_req_t*)&handle->exit_req); - handle->exit_req.type = UV_PROCESS_EXIT; - handle->exit_req.data = handle; -} - - -/* - * Path search functions - */ - -/* - * Helper function for search_path - */ -static WCHAR* search_path_join_test(const WCHAR* dir, - size_t dir_len, - const WCHAR* name, - size_t name_len, - const WCHAR* ext, - size_t ext_len, - const WCHAR* cwd, - size_t cwd_len) { - WCHAR *result, *result_pos; - DWORD attrs; - if (dir_len > 2 && dir[0] == L'\\' && dir[1] == L'\\') { - /* It's a UNC path so ignore cwd */ - cwd_len = 0; - } else if (dir_len >= 1 && (dir[0] == L'/' || dir[0] == L'\\')) { - /* It's a full path without drive letter, use cwd's drive letter only */ - cwd_len = 2; - } else if (dir_len >= 2 && dir[1] == L':' && - (dir_len < 3 || (dir[2] != L'/' && dir[2] != L'\\'))) { - /* It's a relative path with drive letter (ext.g. D:../some/file) - * Replace drive letter in dir by full cwd if it points to the same drive, - * otherwise use the dir only. - */ - if (cwd_len < 2 || _wcsnicmp(cwd, dir, 2) != 0) { - cwd_len = 0; - } else { - dir += 2; - dir_len -= 2; - } - } else if (dir_len > 2 && dir[1] == L':') { - /* It's an absolute path with drive letter - * Don't use the cwd at all - */ - cwd_len = 0; - } - - /* Allocate buffer for output */ - result = result_pos = (WCHAR*)uv__malloc(sizeof(WCHAR) * - (cwd_len + 1 + dir_len + 1 + name_len + 1 + ext_len + 1)); - - /* Copy cwd */ - wcsncpy(result_pos, cwd, cwd_len); - result_pos += cwd_len; - - /* Add a path separator if cwd didn't end with one */ - if (cwd_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) { - result_pos[0] = L'\\'; - result_pos++; - } - - /* Copy dir */ - wcsncpy(result_pos, dir, dir_len); - result_pos += dir_len; - - /* Add a separator if the dir didn't end with one */ - if (dir_len && wcsrchr(L"\\/:", result_pos[-1]) == NULL) { - result_pos[0] = L'\\'; - result_pos++; - } - - /* Copy filename */ - wcsncpy(result_pos, name, name_len); - result_pos += name_len; - - if (ext_len) { - /* Add a dot if the filename didn't end with one */ - if (name_len && result_pos[-1] != '.') { - result_pos[0] = L'.'; - result_pos++; - } - - /* Copy extension */ - wcsncpy(result_pos, ext, ext_len); - result_pos += ext_len; - } - - /* Null terminator */ - result_pos[0] = L'\0'; - - attrs = GetFileAttributesW(result); - - if (attrs != INVALID_FILE_ATTRIBUTES && - !(attrs & FILE_ATTRIBUTE_DIRECTORY)) { - return result; - } - - uv__free(result); - return NULL; -} - - -/* - * Helper function for search_path - */ -static WCHAR* path_search_walk_ext(const WCHAR *dir, - size_t dir_len, - const WCHAR *name, - size_t name_len, - WCHAR *cwd, - size_t cwd_len, - int name_has_ext) { - WCHAR* result; - - /* If the name itself has a nonempty extension, try this extension first */ - if (name_has_ext) { - result = search_path_join_test(dir, dir_len, - name, name_len, - L"", 0, - cwd, cwd_len); - if (result != NULL) { - return result; - } - } - - /* Try .com extension */ - result = search_path_join_test(dir, dir_len, - name, name_len, - L"com", 3, - cwd, cwd_len); - if (result != NULL) { - return result; - } - - /* Try .exe extension */ - result = search_path_join_test(dir, dir_len, - name, name_len, - L"exe", 3, - cwd, cwd_len); - if (result != NULL) { - return result; - } - - return NULL; -} - - -/* - * search_path searches the system path for an executable filename - - * the windows API doesn't provide this as a standalone function nor as an - * option to CreateProcess. - * - * It tries to return an absolute filename. - * - * Furthermore, it tries to follow the semantics that cmd.exe, with this - * exception that PATHEXT environment variable isn't used. Since CreateProcess - * can start only .com and .exe files, only those extensions are tried. This - * behavior equals that of msvcrt's spawn functions. - * - * - Do not search the path if the filename already contains a path (either - * relative or absolute). - * - * - If there's really only a filename, check the current directory for file, - * then search all path directories. - * - * - If filename specified has *any* extension, search for the file with the - * specified extension first. - * - * - If the literal filename is not found in a directory, try *appending* - * (not replacing) .com first and then .exe. - * - * - The path variable may contain relative paths; relative paths are relative - * to the cwd. - * - * - Directories in path may or may not end with a trailing backslash. - * - * - CMD does not trim leading/trailing whitespace from path/pathex entries - * nor from the environment variables as a whole. - * - * - When cmd.exe cannot read a directory, it will just skip it and go on - * searching. However, unlike posix-y systems, it will happily try to run a - * file that is not readable/executable; if the spawn fails it will not - * continue searching. - * - * UNC path support: we are dealing with UNC paths in both the path and the - * filename. This is a deviation from what cmd.exe does (it does not let you - * start a program by specifying an UNC path on the command line) but this is - * really a pointless restriction. - * - */ -static WCHAR* search_path(const WCHAR *file, - WCHAR *cwd, - const WCHAR *path) { - int file_has_dir; - WCHAR* result = NULL; - WCHAR *file_name_start; - WCHAR *dot; - const WCHAR *dir_start, *dir_end, *dir_path; - size_t dir_len; - int name_has_ext; - - size_t file_len = wcslen(file); - size_t cwd_len = wcslen(cwd); - - /* If the caller supplies an empty filename, - * we're not gonna return c:\windows\.exe -- GFY! - */ - if (file_len == 0 - || (file_len == 1 && file[0] == L'.')) { - return NULL; - } - - /* Find the start of the filename so we can split the directory from the */ - /* name. */ - for (file_name_start = (WCHAR*)file + file_len; - file_name_start > file - && file_name_start[-1] != L'\\' - && file_name_start[-1] != L'/' - && file_name_start[-1] != L':'; - file_name_start--); - - file_has_dir = file_name_start != file; - - /* Check if the filename includes an extension */ - dot = wcschr(file_name_start, L'.'); - name_has_ext = (dot != NULL && dot[1] != L'\0'); - - if (file_has_dir) { - /* The file has a path inside, don't use path */ - result = path_search_walk_ext( - file, file_name_start - file, - file_name_start, file_len - (file_name_start - file), - cwd, cwd_len, - name_has_ext); - - } else { - dir_end = path; - - /* The file is really only a name; look in cwd first, then scan path */ - result = path_search_walk_ext(L"", 0, - file, file_len, - cwd, cwd_len, - name_has_ext); - - while (result == NULL) { - if (*dir_end == L'\0') { - break; - } - - /* Skip the separator that dir_end now points to */ - if (dir_end != path || *path == L';') { - dir_end++; - } - - /* Next slice starts just after where the previous one ended */ - dir_start = dir_end; - - /* Slice until the next ; or \0 is found */ - dir_end = wcschr(dir_start, L';'); - if (dir_end == NULL) { - dir_end = wcschr(dir_start, L'\0'); - } - - /* If the slice is zero-length, don't bother */ - if (dir_end - dir_start == 0) { - continue; - } - - dir_path = dir_start; - dir_len = dir_end - dir_start; - - /* Adjust if the path is quoted. */ - if (dir_path[0] == '"' || dir_path[0] == '\'') { - ++dir_path; - --dir_len; - } - - if (dir_path[dir_len - 1] == '"' || dir_path[dir_len - 1] == '\'') { - --dir_len; - } - - result = path_search_walk_ext(dir_path, dir_len, - file, file_len, - cwd, cwd_len, - name_has_ext); - } - } - - return result; -} - - -/* - * Quotes command line arguments - * Returns a pointer to the end (next char to be written) of the buffer - */ -WCHAR* quote_cmd_arg(const WCHAR *source, WCHAR *target) { - size_t len = wcslen(source); - size_t i; - int quote_hit; - WCHAR* start; - - if (len == 0) { - /* Need double quotation for empty argument */ - *(target++) = L'"'; - *(target++) = L'"'; - return target; - } - - if (NULL == wcspbrk(source, L" \t\"")) { - /* No quotation needed */ - wcsncpy(target, source, len); - target += len; - return target; - } - - if (NULL == wcspbrk(source, L"\"\\")) { - /* - * No embedded double quotes or backlashes, so I can just wrap - * quote marks around the whole thing. - */ - *(target++) = L'"'; - wcsncpy(target, source, len); - target += len; - *(target++) = L'"'; - return target; - } - - /* - * Expected input/output: - * input : hello"world - * output: "hello\"world" - * input : hello""world - * output: "hello\"\"world" - * input : hello\world - * output: hello\world - * input : hello\\world - * output: hello\\world - * input : hello\"world - * output: "hello\\\"world" - * input : hello\\"world - * output: "hello\\\\\"world" - * input : hello world\ - * output: "hello world\" - */ - - *(target++) = L'"'; - start = target; - quote_hit = 1; - - for (i = len; i > 0; --i) { - *(target++) = source[i - 1]; - - if (quote_hit && source[i - 1] == L'\\') { - *(target++) = L'\\'; - } else if(source[i - 1] == L'"') { - quote_hit = 1; - *(target++) = L'\\'; - } else { - quote_hit = 0; - } - } - target[0] = L'\0'; - wcsrev(start); - *(target++) = L'"'; - return target; -} - - -int make_program_args(char** args, int verbatim_arguments, WCHAR** dst_ptr) { - char** arg; - WCHAR* dst = NULL; - WCHAR* temp_buffer = NULL; - size_t dst_len = 0; - size_t temp_buffer_len = 0; - WCHAR* pos; - int arg_count = 0; - int err = 0; - - /* Count the required size. */ - for (arg = args; *arg; arg++) { - DWORD arg_len; - - arg_len = MultiByteToWideChar(CP_UTF8, - 0, - *arg, - -1, - NULL, - 0); - if (arg_len == 0) { - return GetLastError(); - } - - dst_len += arg_len; - - if (arg_len > temp_buffer_len) - temp_buffer_len = arg_len; - - arg_count++; - } - - /* Adjust for potential quotes. Also assume the worst-case scenario */ - /* that every character needs escaping, so we need twice as much space. */ - dst_len = dst_len * 2 + arg_count * 2; - - /* Allocate buffer for the final command line. */ - dst = (WCHAR*) uv__malloc(dst_len * sizeof(WCHAR)); - if (dst == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - /* Allocate temporary working buffer. */ - temp_buffer = (WCHAR*) uv__malloc(temp_buffer_len * sizeof(WCHAR)); - if (temp_buffer == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - pos = dst; - for (arg = args; *arg; arg++) { - DWORD arg_len; - - /* Convert argument to wide char. */ - arg_len = MultiByteToWideChar(CP_UTF8, - 0, - *arg, - -1, - temp_buffer, - (int) (dst + dst_len - pos)); - if (arg_len == 0) { - err = GetLastError(); - goto error; - } - - if (verbatim_arguments) { - /* Copy verbatim. */ - wcscpy(pos, temp_buffer); - pos += arg_len - 1; - } else { - /* Quote/escape, if needed. */ - pos = quote_cmd_arg(temp_buffer, pos); - } - - *pos++ = *(arg + 1) ? L' ' : L'\0'; - } - - uv__free(temp_buffer); - - *dst_ptr = dst; - return 0; - -error: - uv__free(dst); - uv__free(temp_buffer); - return err; -} - - -int env_strncmp(const wchar_t* a, int na, const wchar_t* b) { - wchar_t* a_eq; - wchar_t* b_eq; - wchar_t* A; - wchar_t* B; - int nb; - int r; - - if (na < 0) { - a_eq = wcschr(a, L'='); - assert(a_eq); - na = (int)(long)(a_eq - a); - } else { - na--; - } - b_eq = wcschr(b, L'='); - assert(b_eq); - nb = b_eq - b; - - A = alloca((na+1) * sizeof(wchar_t)); - B = alloca((nb+1) * sizeof(wchar_t)); - - r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, a, na, A, na); - assert(r==na); - A[na] = L'\0'; - r = LCMapStringW(LOCALE_INVARIANT, LCMAP_UPPERCASE, b, nb, B, nb); - assert(r==nb); - B[nb] = L'\0'; - - while (1) { - wchar_t AA = *A++; - wchar_t BB = *B++; - if (AA < BB) { - return -1; - } else if (AA > BB) { - return 1; - } else if (!AA && !BB) { - return 0; - } - } -} - - -static int qsort_wcscmp(const void *a, const void *b) { - wchar_t* astr = *(wchar_t* const*)a; - wchar_t* bstr = *(wchar_t* const*)b; - return env_strncmp(astr, -1, bstr); -} - - -/* - * The way windows takes environment variables is different than what C does; - * Windows wants a contiguous block of null-terminated strings, terminated - * with an additional null. - * - * Windows has a few "essential" environment variables. winsock will fail - * to initialize if SYSTEMROOT is not defined; some APIs make reference to - * TEMP. SYSTEMDRIVE is probably also important. We therefore ensure that - * these get defined if the input environment block does not contain any - * values for them. - * - * Also add variables known to Cygwin to be required for correct - * subprocess operation in many cases: - * https://github.com/Alexpux/Cygwin/blob/b266b04fbbd3a595f02ea149e4306d3ab9b1fe3d/winsup/cygwin/environ.cc#L955 - * - */ -int make_program_env(char* env_block[], WCHAR** dst_ptr) { - WCHAR* dst; - WCHAR* ptr; - char** env; - size_t env_len = 0; - int len; - size_t i; - DWORD var_size; - size_t env_block_count = 1; /* 1 for null-terminator */ - WCHAR* dst_copy; - WCHAR** ptr_copy; - WCHAR** env_copy; - DWORD* required_vars_value_len = alloca(n_required_vars * sizeof(DWORD*)); - - /* first pass: determine size in UTF-16 */ - for (env = env_block; *env; env++) { - int len; - if (strchr(*env, '=')) { - len = MultiByteToWideChar(CP_UTF8, - 0, - *env, - -1, - NULL, - 0); - if (len <= 0) { - return GetLastError(); - } - env_len += len; - env_block_count++; - } - } - - /* second pass: copy to UTF-16 environment block */ - dst_copy = (WCHAR*)uv__malloc(env_len * sizeof(WCHAR)); - if (!dst_copy) { - return ERROR_OUTOFMEMORY; - } - env_copy = alloca(env_block_count * sizeof(WCHAR*)); - - ptr = dst_copy; - ptr_copy = env_copy; - for (env = env_block; *env; env++) { - if (strchr(*env, '=')) { - len = MultiByteToWideChar(CP_UTF8, - 0, - *env, - -1, - ptr, - (int) (env_len - (ptr - dst_copy))); - if (len <= 0) { - DWORD err = GetLastError(); - uv__free(dst_copy); - return err; - } - *ptr_copy++ = ptr; - ptr += len; - } - } - *ptr_copy = NULL; - assert(env_len == ptr - dst_copy); - - /* sort our (UTF-16) copy */ - qsort(env_copy, env_block_count-1, sizeof(wchar_t*), qsort_wcscmp); - - /* third pass: check for required variables */ - for (ptr_copy = env_copy, i = 0; i < n_required_vars; ) { - int cmp; - if (!*ptr_copy) { - cmp = -1; - } else { - cmp = env_strncmp(required_vars[i].wide_eq, - required_vars[i].len, - *ptr_copy); - } - if (cmp < 0) { - /* missing required var */ - var_size = GetEnvironmentVariableW(required_vars[i].wide, NULL, 0); - required_vars_value_len[i] = var_size; - if (var_size != 0) { - env_len += required_vars[i].len; - env_len += var_size; - } - i++; - } else { - ptr_copy++; - if (cmp == 0) - i++; - } - } - - /* final pass: copy, in sort order, and inserting required variables */ - dst = uv__malloc((1+env_len) * sizeof(WCHAR)); - if (!dst) { - uv__free(dst_copy); - return ERROR_OUTOFMEMORY; - } - - for (ptr = dst, ptr_copy = env_copy, i = 0; - *ptr_copy || i < n_required_vars; - ptr += len) { - int cmp; - if (i >= n_required_vars) { - cmp = 1; - } else if (!*ptr_copy) { - cmp = -1; - } else { - cmp = env_strncmp(required_vars[i].wide_eq, - required_vars[i].len, - *ptr_copy); - } - if (cmp < 0) { - /* missing required var */ - len = required_vars_value_len[i]; - if (len) { - wcscpy(ptr, required_vars[i].wide_eq); - ptr += required_vars[i].len; - var_size = GetEnvironmentVariableW(required_vars[i].wide, - ptr, - (int) (env_len - (ptr - dst))); - if (var_size != len-1) { /* race condition? */ - uv_fatal_error(GetLastError(), "GetEnvironmentVariableW"); - } - } - i++; - } else { - /* copy var from env_block */ - len = wcslen(*ptr_copy) + 1; - wmemcpy(ptr, *ptr_copy, len); - ptr_copy++; - if (cmp == 0) - i++; - } - } - - /* Terminate with an extra NULL. */ - assert(env_len == (ptr - dst)); - *ptr = L'\0'; - - uv__free(dst_copy); - *dst_ptr = dst; - return 0; -} - -/* - * Attempt to find the value of the PATH environment variable in the child's - * preprocessed environment. - * - * If found, a pointer into `env` is returned. If not found, NULL is returned. - */ -static WCHAR* find_path(WCHAR *env) { - for (; env != NULL && *env != 0; env += wcslen(env) + 1) { - if (wcsncmp(env, L"PATH=", 5) == 0) - return &env[5]; - } - - return NULL; -} - -/* - * Called on Windows thread-pool thread to indicate that - * a child process has exited. - */ -static void CALLBACK exit_wait_callback(void* data, BOOLEAN didTimeout) { - uv_process_t* process = (uv_process_t*) data; - uv_loop_t* loop = process->loop; - - assert(didTimeout == FALSE); - assert(process); - assert(!process->exit_cb_pending); - - process->exit_cb_pending = 1; - - /* Post completed */ - POST_COMPLETION_FOR_REQ(loop, &process->exit_req); -} - - -/* Called on main thread after a child process has exited. */ -void uv_process_proc_exit(uv_loop_t* loop, uv_process_t* handle) { - int64_t exit_code; - DWORD status; - - assert(handle->exit_cb_pending); - handle->exit_cb_pending = 0; - - /* If we're closing, don't call the exit callback. Just schedule a close */ - /* callback now. */ - if (handle->flags & UV__HANDLE_CLOSING) { - uv_want_endgame(loop, (uv_handle_t*) handle); - return; - } - - /* Unregister from process notification. */ - if (handle->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(handle->wait_handle); - handle->wait_handle = INVALID_HANDLE_VALUE; - } - - /* Set the handle to inactive: no callbacks will be made after the exit */ - /* callback.*/ - uv__handle_stop(handle); - - if (GetExitCodeProcess(handle->process_handle, &status)) { - exit_code = status; - } else { - /* Unable to to obtain the exit code. This should never happen. */ - exit_code = uv_translate_sys_error(GetLastError()); - } - - /* Fire the exit callback. */ - if (handle->exit_cb) { - handle->exit_cb(handle, exit_code, handle->exit_signal); - } -} - - -void uv_process_close(uv_loop_t* loop, uv_process_t* handle) { - uv__handle_closing(handle); - - if (handle->wait_handle != INVALID_HANDLE_VALUE) { - /* This blocks until either the wait was cancelled, or the callback has */ - /* completed. */ - BOOL r = UnregisterWaitEx(handle->wait_handle, INVALID_HANDLE_VALUE); - if (!r) { - /* This should never happen, and if it happens, we can't recover... */ - uv_fatal_error(GetLastError(), "UnregisterWaitEx"); - } - - handle->wait_handle = INVALID_HANDLE_VALUE; - } - - if (!handle->exit_cb_pending) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } -} - - -void uv_process_endgame(uv_loop_t* loop, uv_process_t* handle) { - assert(!handle->exit_cb_pending); - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - /* Clean-up the process handle. */ - CloseHandle(handle->process_handle); - - uv__handle_close(handle); -} - - -int uv_spawn(uv_loop_t* loop, - uv_process_t* process, - const uv_process_options_t* options) { - int i; - int err = 0; - WCHAR* path = NULL, *alloc_path = NULL; - BOOL result; - WCHAR* application_path = NULL, *application = NULL, *arguments = NULL, - *env = NULL, *cwd = NULL; - STARTUPINFOW startup; - PROCESS_INFORMATION info; - DWORD process_flags; - - uv_process_init(loop, process); - process->exit_cb = options->exit_cb; - - if (options->flags & (UV_PROCESS_SETGID | UV_PROCESS_SETUID)) { - return UV_ENOTSUP; - } - - if (options->file == NULL || - options->args == NULL) { - return UV_EINVAL; - } - - assert(options->file != NULL); - assert(!(options->flags & ~(UV_PROCESS_DETACHED | - UV_PROCESS_SETGID | - UV_PROCESS_SETUID | - UV_PROCESS_WINDOWS_HIDE | - UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS))); - - err = uv_utf8_to_utf16_alloc(options->file, &application); - if (err) - goto done; - - err = make_program_args( - options->args, - options->flags & UV_PROCESS_WINDOWS_VERBATIM_ARGUMENTS, - &arguments); - if (err) - goto done; - - if (options->env) { - err = make_program_env(options->env, &env); - if (err) - goto done; - } - - if (options->cwd) { - /* Explicit cwd */ - err = uv_utf8_to_utf16_alloc(options->cwd, &cwd); - if (err) - goto done; - - } else { - /* Inherit cwd */ - DWORD cwd_len, r; - - cwd_len = GetCurrentDirectoryW(0, NULL); - if (!cwd_len) { - err = GetLastError(); - goto done; - } - - cwd = (WCHAR*) uv__malloc(cwd_len * sizeof(WCHAR)); - if (cwd == NULL) { - err = ERROR_OUTOFMEMORY; - goto done; - } - - r = GetCurrentDirectoryW(cwd_len, cwd); - if (r == 0 || r >= cwd_len) { - err = GetLastError(); - goto done; - } - } - - /* Get PATH environment variable. */ - path = find_path(env); - if (path == NULL) { - DWORD path_len, r; - - path_len = GetEnvironmentVariableW(L"PATH", NULL, 0); - if (path_len == 0) { - err = GetLastError(); - goto done; - } - - alloc_path = (WCHAR*) uv__malloc(path_len * sizeof(WCHAR)); - if (alloc_path == NULL) { - err = ERROR_OUTOFMEMORY; - goto done; - } - path = alloc_path; - - r = GetEnvironmentVariableW(L"PATH", path, path_len); - if (r == 0 || r >= path_len) { - err = GetLastError(); - goto done; - } - } - - err = uv__stdio_create(loop, options, &process->child_stdio_buffer); - if (err) - goto done; - - application_path = search_path(application, - cwd, - path); - if (application_path == NULL) { - /* Not found. */ - err = ERROR_FILE_NOT_FOUND; - goto done; - } - - startup.cb = sizeof(startup); - startup.lpReserved = NULL; - startup.lpDesktop = NULL; - startup.lpTitle = NULL; - startup.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; - - startup.cbReserved2 = uv__stdio_size(process->child_stdio_buffer); - startup.lpReserved2 = (BYTE*) process->child_stdio_buffer; - - startup.hStdInput = uv__stdio_handle(process->child_stdio_buffer, 0); - startup.hStdOutput = uv__stdio_handle(process->child_stdio_buffer, 1); - startup.hStdError = uv__stdio_handle(process->child_stdio_buffer, 2); - - if (options->flags & UV_PROCESS_WINDOWS_HIDE) { - /* Use SW_HIDE to avoid any potential process window. */ - startup.wShowWindow = SW_HIDE; - } else { - startup.wShowWindow = SW_SHOWDEFAULT; - } - - process_flags = CREATE_UNICODE_ENVIRONMENT; - - if (options->flags & UV_PROCESS_DETACHED) { - /* Note that we're not setting the CREATE_BREAKAWAY_FROM_JOB flag. That - * means that libuv might not let you create a fully daemonized process - * when run under job control. However the type of job control that libuv - * itself creates doesn't trickle down to subprocesses so they can still - * daemonize. - * - * A reason to not do this is that CREATE_BREAKAWAY_FROM_JOB makes the - * CreateProcess call fail if we're under job control that doesn't allow - * breakaway. - */ - process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP; - } - - if (!CreateProcessW(application_path, - arguments, - NULL, - NULL, - 1, - process_flags, - env, - cwd, - &startup, - &info)) { - /* CreateProcessW failed. */ - err = GetLastError(); - goto done; - } - - /* Spawn succeeded */ - /* Beyond this point, failure is reported asynchronously. */ - - process->process_handle = info.hProcess; - process->pid = info.dwProcessId; - - /* If the process isn't spawned as detached, assign to the global job */ - /* object so windows will kill it when the parent process dies. */ - if (!(options->flags & UV_PROCESS_DETACHED)) { - uv_once(&uv_global_job_handle_init_guard_, uv__init_global_job_handle); - - if (!AssignProcessToJobObject(uv_global_job_handle_, info.hProcess)) { - /* AssignProcessToJobObject might fail if this process is under job - * control and the job doesn't have the - * JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK flag set, on a Windows version - * that doesn't support nested jobs. - * - * When that happens we just swallow the error and continue without - * establishing a kill-child-on-parent-exit relationship, otherwise - * there would be no way for libuv applications run under job control - * to spawn processes at all. - */ - DWORD err = GetLastError(); - if (err != ERROR_ACCESS_DENIED) - uv_fatal_error(err, "AssignProcessToJobObject"); - } - } - - /* Set IPC pid to all IPC pipes. */ - for (i = 0; i < options->stdio_count; i++) { - const uv_stdio_container_t* fdopt = &options->stdio[i]; - if (fdopt->flags & UV_CREATE_PIPE && - fdopt->data.stream->type == UV_NAMED_PIPE && - ((uv_pipe_t*) fdopt->data.stream)->ipc) { - ((uv_pipe_t*) fdopt->data.stream)->pipe.conn.ipc_pid = info.dwProcessId; - } - } - - /* Setup notifications for when the child process exits. */ - result = RegisterWaitForSingleObject(&process->wait_handle, - process->process_handle, exit_wait_callback, (void*)process, INFINITE, - WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE); - if (!result) { - uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject"); - } - - CloseHandle(info.hThread); - - assert(!err); - - /* Make the handle active. It will remain active until the exit callback */ - /* is made or the handle is closed, whichever happens first. */ - uv__handle_start(process); - - /* Cleanup, whether we succeeded or failed. */ - done: - uv__free(application); - uv__free(application_path); - uv__free(arguments); - uv__free(cwd); - uv__free(env); - uv__free(alloc_path); - - if (process->child_stdio_buffer != NULL) { - /* Clean up child stdio handles. */ - uv__stdio_destroy(process->child_stdio_buffer); - process->child_stdio_buffer = NULL; - } - - return uv_translate_sys_error(err); -} - - -static int uv__kill(HANDLE process_handle, int signum) { - switch (signum) { - case SIGTERM: - case SIGKILL: - case SIGINT: { - /* Unconditionally terminate the process. On Windows, killed processes */ - /* normally return 1. */ - DWORD status; - int err; - - if (TerminateProcess(process_handle, 1)) - return 0; - - /* If the process already exited before TerminateProcess was called, */ - /* TerminateProcess will fail with ERROR_ACCESS_DENIED. */ - err = GetLastError(); - if (err == ERROR_ACCESS_DENIED && - GetExitCodeProcess(process_handle, &status) && - status != STILL_ACTIVE) { - return UV_ESRCH; - } - - return uv_translate_sys_error(err); - } - - case 0: { - /* Health check: is the process still alive? */ - DWORD status; - - if (!GetExitCodeProcess(process_handle, &status)) - return uv_translate_sys_error(GetLastError()); - - if (status != STILL_ACTIVE) - return UV_ESRCH; - - return 0; - } - - default: - /* Unsupported signal. */ - return UV_ENOSYS; - } -} - - -int uv_process_kill(uv_process_t* process, int signum) { - int err; - - if (process->process_handle == INVALID_HANDLE_VALUE) { - return UV_EINVAL; - } - - err = uv__kill(process->process_handle, signum); - if (err) { - return err; /* err is already translated. */ - } - - process->exit_signal = signum; - - return 0; -} - - -int uv_kill(int pid, int signum) { - int err; - HANDLE process_handle = OpenProcess(PROCESS_TERMINATE | - PROCESS_QUERY_INFORMATION, FALSE, pid); - - if (process_handle == NULL) { - err = GetLastError(); - if (err == ERROR_INVALID_PARAMETER) { - return UV_ESRCH; - } else { - return uv_translate_sys_error(err); - } - } - - err = uv__kill(process_handle, signum); - CloseHandle(process_handle); - - return err; /* err is already translated. */ -} diff --git a/3rdparty/libuv/src/win/req-inl.h b/3rdparty/libuv/src/win/req-inl.h deleted file mode 100644 index b5e502eef55..00000000000 --- a/3rdparty/libuv/src/win/req-inl.h +++ /dev/null @@ -1,224 +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_REQ_INL_H_ -#define UV_WIN_REQ_INL_H_ - -#include <assert.h> - -#include "uv.h" -#include "internal.h" - - -#define SET_REQ_STATUS(req, status) \ - (req)->u.io.overlapped.Internal = (ULONG_PTR) (status) - -#define SET_REQ_ERROR(req, error) \ - SET_REQ_STATUS((req), NTSTATUS_FROM_WIN32((error))) - -#define SET_REQ_SUCCESS(req) \ - SET_REQ_STATUS((req), STATUS_SUCCESS) - -#define GET_REQ_STATUS(req) \ - ((NTSTATUS) (req)->u.io.overlapped.Internal) - -#define REQ_SUCCESS(req) \ - (NT_SUCCESS(GET_REQ_STATUS((req)))) - -#define GET_REQ_ERROR(req) \ - (pRtlNtStatusToDosError(GET_REQ_STATUS((req)))) - -#define GET_REQ_SOCK_ERROR(req) \ - (uv_ntstatus_to_winsock_error(GET_REQ_STATUS((req)))) - - -#define REGISTER_HANDLE_REQ(loop, handle, req) \ - do { \ - INCREASE_ACTIVE_COUNT((loop), (handle)); \ - uv__req_register((loop), (req)); \ - } while (0) - -#define UNREGISTER_HANDLE_REQ(loop, handle, req) \ - do { \ - DECREASE_ACTIVE_COUNT((loop), (handle)); \ - uv__req_unregister((loop), (req)); \ - } while (0) - - -#define UV_SUCCEEDED_WITHOUT_IOCP(result) \ - ((result) && (handle->flags & UV_HANDLE_SYNC_BYPASS_IOCP)) - -#define UV_SUCCEEDED_WITH_IOCP(result) \ - ((result) || (GetLastError() == ERROR_IO_PENDING)) - - -#define POST_COMPLETION_FOR_REQ(loop, req) \ - if (!PostQueuedCompletionStatus((loop)->iocp, \ - 0, \ - 0, \ - &((req)->u.io.overlapped))) { \ - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); \ - } - - -INLINE static void uv_req_init(uv_loop_t* loop, uv_req_t* req) { - req->type = UV_UNKNOWN_REQ; - SET_REQ_SUCCESS(req); -} - - -INLINE static uv_req_t* uv_overlapped_to_req(OVERLAPPED* overlapped) { - return CONTAINING_RECORD(overlapped, uv_req_t, u.io.overlapped); -} - - -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; - } -} - - -#define DELEGATE_STREAM_REQ(loop, req, method, handle_at) \ - do { \ - switch (((uv_handle_t*) (req)->handle_at)->type) { \ - case UV_TCP: \ - uv_process_tcp_##method##_req(loop, \ - (uv_tcp_t*) ((req)->handle_at), \ - req); \ - break; \ - \ - case UV_NAMED_PIPE: \ - uv_process_pipe_##method##_req(loop, \ - (uv_pipe_t*) ((req)->handle_at), \ - req); \ - break; \ - \ - case UV_TTY: \ - uv_process_tty_##method##_req(loop, \ - (uv_tty_t*) ((req)->handle_at), \ - req); \ - break; \ - \ - default: \ - assert(0); \ - } \ - } while (0) - - -INLINE static int uv_process_reqs(uv_loop_t* loop) { - uv_req_t* req; - uv_req_t* first; - uv_req_t* next; - - if (loop->pending_reqs_tail == NULL) - return 0; - - first = loop->pending_reqs_tail->next_req; - next = first; - loop->pending_reqs_tail = NULL; - - while (next != NULL) { - req = next; - next = req->next_req != first ? req->next_req : NULL; - - switch (req->type) { - case UV_READ: - DELEGATE_STREAM_REQ(loop, req, read, data); - break; - - case UV_WRITE: - DELEGATE_STREAM_REQ(loop, (uv_write_t*) req, write, handle); - break; - - case UV_ACCEPT: - DELEGATE_STREAM_REQ(loop, req, accept, data); - break; - - case UV_CONNECT: - DELEGATE_STREAM_REQ(loop, (uv_connect_t*) req, connect, handle); - break; - - case UV_SHUTDOWN: - /* Tcp shutdown requests don't come here. */ - assert(((uv_shutdown_t*) req)->handle->type == UV_NAMED_PIPE); - uv_process_pipe_shutdown_req( - loop, - (uv_pipe_t*) ((uv_shutdown_t*) req)->handle, - (uv_shutdown_t*) req); - break; - - case UV_UDP_RECV: - uv_process_udp_recv_req(loop, (uv_udp_t*) req->data, req); - break; - - case UV_UDP_SEND: - uv_process_udp_send_req(loop, - ((uv_udp_send_t*) req)->handle, - (uv_udp_send_t*) req); - break; - - case UV_WAKEUP: - uv_process_async_wakeup_req(loop, (uv_async_t*) req->data, req); - break; - - case UV_SIGNAL_REQ: - uv_process_signal_req(loop, (uv_signal_t*) req->data, req); - break; - - case UV_POLL_REQ: - uv_process_poll_req(loop, (uv_poll_t*) req->data, req); - break; - - case UV_PROCESS_EXIT: - uv_process_proc_exit(loop, (uv_process_t*) req->data); - break; - - case UV_FS_EVENT_REQ: - uv_process_fs_event_req(loop, req, (uv_fs_event_t*) req->data); - break; - - default: - assert(0); - } - } - - return 1; -} - -#endif /* UV_WIN_REQ_INL_H_ */ diff --git a/3rdparty/libuv/src/win/req.c b/3rdparty/libuv/src/win/req.c deleted file mode 100644 index 111cc5e2893..00000000000 --- a/3rdparty/libuv/src/win/req.c +++ /dev/null @@ -1,25 +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. - */ - -#include <assert.h> - -#include "uv.h" -#include "internal.h" diff --git a/3rdparty/libuv/src/win/signal.c b/3rdparty/libuv/src/win/signal.c deleted file mode 100644 index 2c64a55dc39..00000000000 --- a/3rdparty/libuv/src/win/signal.c +++ /dev/null @@ -1,356 +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. - */ - -#include <assert.h> -#include <signal.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -RB_HEAD(uv_signal_tree_s, uv_signal_s); - -static struct uv_signal_tree_s uv__signal_tree = RB_INITIALIZER(uv__signal_tree); -static ssize_t volatile uv__signal_control_handler_refs = 0; -static CRITICAL_SECTION uv__signal_lock; - - -void uv_signals_init() { - InitializeCriticalSection(&uv__signal_lock); -} - - -static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2) { - /* Compare signums first so all watchers with the same signnum end up */ - /* adjacent. */ - if (w1->signum < w2->signum) return -1; - if (w1->signum > w2->signum) return 1; - - /* Sort by loop pointer, so we can easily look up the first item after */ - /* { .signum = x, .loop = NULL } */ - if ((uintptr_t) w1->loop < (uintptr_t) w2->loop) return -1; - if ((uintptr_t) w1->loop > (uintptr_t) w2->loop) return 1; - - if ((uintptr_t) w1 < (uintptr_t) w2) return -1; - if ((uintptr_t) w1 > (uintptr_t) w2) return 1; - - return 0; -} - - -RB_GENERATE_STATIC(uv_signal_tree_s, uv_signal_s, tree_entry, uv__signal_compare); - - -/* - * Dispatches signal {signum} to all active uv_signal_t watchers in all loops. - * Returns 1 if the signal was dispatched to any watcher, or 0 if there were - * no active signal watchers observing this signal. - */ -int uv__signal_dispatch(int signum) { - uv_signal_t lookup; - uv_signal_t* handle; - int dispatched = 0; - - EnterCriticalSection(&uv__signal_lock); - - lookup.signum = signum; - lookup.loop = NULL; - - for (handle = RB_NFIND(uv_signal_tree_s, &uv__signal_tree, &lookup); - handle != NULL && handle->signum == signum; - handle = RB_NEXT(uv_signal_tree_s, &uv__signal_tree, handle)) { - unsigned long previous = InterlockedExchange( - (volatile LONG*) &handle->pending_signum, signum); - - if (!previous) { - POST_COMPLETION_FOR_REQ(handle->loop, &handle->signal_req); - } - - dispatched = 1; - } - - LeaveCriticalSection(&uv__signal_lock); - - return dispatched; -} - - -static BOOL WINAPI uv__signal_control_handler(DWORD type) { - switch (type) { - case CTRL_C_EVENT: - return uv__signal_dispatch(SIGINT); - - case CTRL_BREAK_EVENT: - return uv__signal_dispatch(SIGBREAK); - - case CTRL_CLOSE_EVENT: - if (uv__signal_dispatch(SIGHUP)) { - /* Windows will terminate the process after the control handler */ - /* returns. After that it will just terminate our process. Therefore */ - /* block the signal handler so the main loop has some time to pick */ - /* up the signal and do something for a few seconds. */ - Sleep(INFINITE); - return TRUE; - } - return FALSE; - - case CTRL_LOGOFF_EVENT: - case CTRL_SHUTDOWN_EVENT: - /* These signals are only sent to services. Services have their own */ - /* notification mechanism, so there's no point in handling these. */ - - default: - /* We don't handle these. */ - return FALSE; - } -} - - -static int uv__signal_register_control_handler() { - /* When this function is called, the uv__signal_lock must be held. */ - - /* If the console control handler has already been hooked, just add a */ - /* reference. */ - if (uv__signal_control_handler_refs > 0) { - uv__signal_control_handler_refs++; - return 0; - } - - if (!SetConsoleCtrlHandler(uv__signal_control_handler, TRUE)) - return GetLastError(); - - uv__signal_control_handler_refs++; - - return 0; -} - - -static void uv__signal_unregister_control_handler() { - /* When this function is called, the uv__signal_lock must be held. */ - BOOL r; - - /* Don't unregister if the number of console control handlers exceeds one. */ - /* Just remove a reference in that case. */ - if (uv__signal_control_handler_refs > 1) { - uv__signal_control_handler_refs--; - return; - } - - assert(uv__signal_control_handler_refs == 1); - - r = SetConsoleCtrlHandler(uv__signal_control_handler, FALSE); - /* This should never fail; if it does it is probably a bug in libuv. */ - assert(r); - - uv__signal_control_handler_refs--; -} - - -static int uv__signal_register(int signum) { - switch (signum) { - case SIGINT: - case SIGBREAK: - case SIGHUP: - return uv__signal_register_control_handler(); - - case SIGWINCH: - /* SIGWINCH is generated in tty.c. No need to register anything. */ - return 0; - - case SIGILL: - case SIGABRT_COMPAT: - case SIGFPE: - case SIGSEGV: - case SIGTERM: - case SIGABRT: - /* Signal is never raised. */ - return 0; - - default: - /* Invalid signal. */ - return ERROR_INVALID_PARAMETER; - } -} - - -static void uv__signal_unregister(int signum) { - switch (signum) { - case SIGINT: - case SIGBREAK: - case SIGHUP: - uv__signal_unregister_control_handler(); - return; - - case SIGWINCH: - /* SIGWINCH is generated in tty.c. No need to unregister anything. */ - return; - - case SIGILL: - case SIGABRT_COMPAT: - case SIGFPE: - case SIGSEGV: - case SIGTERM: - case SIGABRT: - /* Nothing is registered for this signal. */ - return; - - default: - /* Libuv bug. */ - assert(0 && "Invalid signum"); - return; - } -} - - -int uv_signal_init(uv_loop_t* loop, uv_signal_t* handle) { - uv_req_t* req; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_SIGNAL); - handle->pending_signum = 0; - handle->signum = 0; - handle->signal_cb = NULL; - - req = &handle->signal_req; - uv_req_init(loop, req); - req->type = UV_SIGNAL_REQ; - req->data = handle; - - return 0; -} - - -int uv_signal_stop(uv_signal_t* handle) { - uv_signal_t* removed_handle; - - /* If the watcher wasn't started, this is a no-op. */ - if (handle->signum == 0) - return 0; - - EnterCriticalSection(&uv__signal_lock); - - uv__signal_unregister(handle->signum); - - removed_handle = RB_REMOVE(uv_signal_tree_s, &uv__signal_tree, handle); - assert(removed_handle == handle); - - LeaveCriticalSection(&uv__signal_lock); - - handle->signum = 0; - uv__handle_stop(handle); - - return 0; -} - - -int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) { - int err; - - /* If the user supplies signum == 0, then return an error already. If the */ - /* signum is otherwise invalid then uv__signal_register will find out */ - /* eventually. */ - if (signum == 0) { - return UV_EINVAL; - } - - /* Short circuit: if the signal watcher is already watching {signum} don't */ - /* go through the process of deregistering and registering the handler. */ - /* Additionally, this avoids pending signals getting lost in the (small) */ - /* time frame that handle->signum == 0. */ - if (signum == handle->signum) { - handle->signal_cb = signal_cb; - return 0; - } - - /* If the signal handler was already active, stop it first. */ - if (handle->signum != 0) { - int r = uv_signal_stop(handle); - /* uv_signal_stop is infallible. */ - assert(r == 0); - } - - EnterCriticalSection(&uv__signal_lock); - - err = uv__signal_register(signum); - if (err) { - /* Uh-oh, didn't work. */ - LeaveCriticalSection(&uv__signal_lock); - return uv_translate_sys_error(err); - } - - handle->signum = signum; - RB_INSERT(uv_signal_tree_s, &uv__signal_tree, handle); - - LeaveCriticalSection(&uv__signal_lock); - - handle->signal_cb = signal_cb; - uv__handle_start(handle); - - return 0; -} - - -void uv_process_signal_req(uv_loop_t* loop, uv_signal_t* handle, - uv_req_t* req) { - long dispatched_signum; - - assert(handle->type == UV_SIGNAL); - assert(req->type == UV_SIGNAL_REQ); - - dispatched_signum = InterlockedExchange( - (volatile LONG*) &handle->pending_signum, 0); - assert(dispatched_signum != 0); - - /* Check if the pending signal equals the signum that we are watching for. */ - /* These can get out of sync when the handler is stopped and restarted */ - /* while the signal_req is pending. */ - if (dispatched_signum == handle->signum) - handle->signal_cb(handle, dispatched_signum); - - if (handle->flags & UV__HANDLE_CLOSING) { - /* When it is closing, it must be stopped at this point. */ - assert(handle->signum == 0); - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -void uv_signal_close(uv_loop_t* loop, uv_signal_t* handle) { - uv_signal_stop(handle); - uv__handle_closing(handle); - - if (handle->pending_signum == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -void uv_signal_endgame(uv_loop_t* loop, uv_signal_t* handle) { - assert(handle->flags & UV__HANDLE_CLOSING); - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - assert(handle->signum == 0); - assert(handle->pending_signum == 0); - - handle->flags |= UV_HANDLE_CLOSED; - - uv__handle_close(handle); -} diff --git a/3rdparty/libuv/src/win/snprintf.c b/3rdparty/libuv/src/win/snprintf.c deleted file mode 100644 index 776c0e39217..00000000000 --- a/3rdparty/libuv/src/win/snprintf.c +++ /dev/null @@ -1,42 +0,0 @@ -/* Copyright the libuv project 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. - */ - -#if defined(_MSC_VER) && _MSC_VER < 1900 - -#include <stdio.h> -#include <stdarg.h> - -/* Emulate snprintf() on MSVC<2015, _snprintf() doesn't zero-terminate the buffer - * on overflow... - */ -int snprintf(char* buf, size_t len, const char* fmt, ...) { - int n; - va_list ap; - va_start(ap, fmt); - - n = _vscprintf(fmt, ap); - vsnprintf_s(buf, len, _TRUNCATE, fmt, ap); - - va_end(ap); - return n; -} - -#endif diff --git a/3rdparty/libuv/src/win/stream-inl.h b/3rdparty/libuv/src/win/stream-inl.h deleted file mode 100644 index b7a3c11958c..00000000000 --- a/3rdparty/libuv/src/win/stream-inl.h +++ /dev/null @@ -1,56 +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_STREAM_INL_H_ -#define UV_WIN_STREAM_INL_H_ - -#include <assert.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -INLINE static void uv_stream_init(uv_loop_t* loop, - uv_stream_t* handle, - uv_handle_type type) { - uv__handle_init(loop, (uv_handle_t*) handle, type); - handle->write_queue_size = 0; - handle->activecnt = 0; -} - - -INLINE static void uv_connection_init(uv_stream_t* handle) { - handle->flags |= UV_HANDLE_CONNECTION; - handle->stream.conn.write_reqs_pending = 0; - - uv_req_init(handle->loop, (uv_req_t*) &(handle->read_req)); - handle->read_req.event_handle = NULL; - handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - handle->read_req.type = UV_READ; - handle->read_req.data = handle; - - handle->stream.conn.shutdown_req = NULL; -} - - -#endif /* UV_WIN_STREAM_INL_H_ */ diff --git a/3rdparty/libuv/src/win/stream.c b/3rdparty/libuv/src/win/stream.c deleted file mode 100644 index a2466e5e9db..00000000000 --- a/3rdparty/libuv/src/win/stream.c +++ /dev/null @@ -1,249 +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. - */ - -#include <assert.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "req-inl.h" - - -int uv_listen(uv_stream_t* stream, int backlog, uv_connection_cb cb) { - int err; - - err = ERROR_INVALID_PARAMETER; - switch (stream->type) { - case UV_TCP: - err = uv_tcp_listen((uv_tcp_t*)stream, backlog, cb); - break; - case UV_NAMED_PIPE: - err = uv_pipe_listen((uv_pipe_t*)stream, backlog, cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_accept(uv_stream_t* server, uv_stream_t* client) { - int err; - - err = ERROR_INVALID_PARAMETER; - switch (server->type) { - case UV_TCP: - err = uv_tcp_accept((uv_tcp_t*)server, (uv_tcp_t*)client); - break; - case UV_NAMED_PIPE: - err = uv_pipe_accept((uv_pipe_t*)server, client); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - int err; - - if (handle->flags & UV_HANDLE_READING) { - return UV_EALREADY; - } - - if (!(handle->flags & UV_HANDLE_READABLE)) { - return UV_ENOTCONN; - } - - err = ERROR_INVALID_PARAMETER; - switch (handle->type) { - case UV_TCP: - err = uv_tcp_read_start((uv_tcp_t*)handle, alloc_cb, read_cb); - break; - case UV_NAMED_PIPE: - err = uv_pipe_read_start((uv_pipe_t*)handle, alloc_cb, read_cb); - break; - case UV_TTY: - err = uv_tty_read_start((uv_tty_t*) handle, alloc_cb, read_cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_read_stop(uv_stream_t* handle) { - int err; - - if (!(handle->flags & UV_HANDLE_READING)) - return 0; - - err = 0; - if (handle->type == UV_TTY) { - err = uv_tty_read_stop((uv_tty_t*) handle); - } else { - if (handle->type == UV_NAMED_PIPE) { - uv__pipe_stop_read((uv_pipe_t*) handle); - } else { - handle->flags &= ~UV_HANDLE_READING; - } - DECREASE_ACTIVE_COUNT(handle->loop, handle); - } - - return uv_translate_sys_error(err); -} - - -int uv_write(uv_write_t* req, - uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - uv_loop_t* loop = handle->loop; - int err; - - if (!(handle->flags & UV_HANDLE_WRITABLE)) { - return UV_EPIPE; - } - - err = ERROR_INVALID_PARAMETER; - switch (handle->type) { - case UV_TCP: - err = uv_tcp_write(loop, req, (uv_tcp_t*) handle, bufs, nbufs, cb); - break; - case UV_NAMED_PIPE: - err = uv_pipe_write(loop, req, (uv_pipe_t*) handle, bufs, nbufs, cb); - break; - case UV_TTY: - err = uv_tty_write(loop, req, (uv_tty_t*) handle, bufs, nbufs, cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_write2(uv_write_t* req, - uv_stream_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_stream_t* send_handle, - uv_write_cb cb) { - uv_loop_t* loop = handle->loop; - int err; - - if (!(handle->flags & UV_HANDLE_WRITABLE)) { - return UV_EPIPE; - } - - err = ERROR_INVALID_PARAMETER; - switch (handle->type) { - case UV_NAMED_PIPE: - err = uv_pipe_write2(loop, - req, - (uv_pipe_t*) handle, - bufs, - nbufs, - send_handle, - cb); - break; - default: - assert(0); - } - - return uv_translate_sys_error(err); -} - - -int uv_try_write(uv_stream_t* stream, - const uv_buf_t bufs[], - unsigned int nbufs) { - if (stream->flags & UV__HANDLE_CLOSING) - return UV_EBADF; - if (!(stream->flags & UV_HANDLE_WRITABLE)) - return UV_EPIPE; - - switch (stream->type) { - case UV_TCP: - return uv__tcp_try_write((uv_tcp_t*) stream, bufs, nbufs); - case UV_TTY: - return uv__tty_try_write((uv_tty_t*) stream, bufs, nbufs); - case UV_NAMED_PIPE: - return UV_EAGAIN; - default: - assert(0); - return UV_ENOSYS; - } -} - - -int uv_shutdown(uv_shutdown_t* req, uv_stream_t* handle, uv_shutdown_cb cb) { - uv_loop_t* loop = handle->loop; - - if (!(handle->flags & UV_HANDLE_WRITABLE)) { - return UV_EPIPE; - } - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_SHUTDOWN; - req->handle = handle; - req->cb = cb; - - handle->flags &= ~UV_HANDLE_WRITABLE; - handle->stream.conn.shutdown_req = req; - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - - uv_want_endgame(loop, (uv_handle_t*)handle); - - return 0; -} - - -int uv_is_readable(const uv_stream_t* handle) { - return !!(handle->flags & UV_HANDLE_READABLE); -} - - -int uv_is_writable(const uv_stream_t* handle) { - return !!(handle->flags & UV_HANDLE_WRITABLE); -} - - -int uv_stream_set_blocking(uv_stream_t* handle, int blocking) { - if (handle->type != UV_NAMED_PIPE) - return UV_EINVAL; - - if (blocking != 0) - handle->flags |= UV_HANDLE_BLOCKING_WRITES; - else - handle->flags &= ~UV_HANDLE_BLOCKING_WRITES; - - return 0; -} diff --git a/3rdparty/libuv/src/win/tcp.c b/3rdparty/libuv/src/win/tcp.c deleted file mode 100644 index 0f5654863e9..00000000000 --- a/3rdparty/libuv/src/win/tcp.c +++ /dev/null @@ -1,1507 +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. - */ - -#include <assert.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - - -/* - * Threshold of active tcp streams for which to preallocate tcp read buffers. - * (Due to node slab allocator performing poorly under this pattern, - * the optimization is temporarily disabled (threshold=0). This will be - * revisited once node allocator is improved.) - */ -const unsigned int uv_active_tcp_streams_threshold = 0; - -/* - * Number of simultaneous pending AcceptEx calls. - */ -const unsigned int uv_simultaneous_server_accepts = 32; - -/* A zero-size buffer for use by uv_tcp_read */ -static char uv_zero_[] = ""; - -static int uv__tcp_nodelay(uv_tcp_t* handle, SOCKET socket, int enable) { - if (setsockopt(socket, - IPPROTO_TCP, - TCP_NODELAY, - (const char*)&enable, - sizeof enable) == -1) { - return WSAGetLastError(); - } - return 0; -} - - -static int uv__tcp_keepalive(uv_tcp_t* handle, SOCKET socket, int enable, unsigned int delay) { - if (setsockopt(socket, - SOL_SOCKET, - SO_KEEPALIVE, - (const char*)&enable, - sizeof enable) == -1) { - return WSAGetLastError(); - } - - if (enable && setsockopt(socket, - IPPROTO_TCP, - TCP_KEEPALIVE, - (const char*)&delay, - sizeof delay) == -1) { - return WSAGetLastError(); - } - - return 0; -} - - -static int uv_tcp_set_socket(uv_loop_t* loop, - uv_tcp_t* handle, - SOCKET socket, - int family, - int imported) { - DWORD yes = 1; - int non_ifs_lsp; - int err; - - if (handle->socket != INVALID_SOCKET) - return UV_EBUSY; - - /* Set the socket to nonblocking mode */ - if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { - return WSAGetLastError(); - } - - /* Make the socket non-inheritable */ - if (!SetHandleInformation((HANDLE) socket, HANDLE_FLAG_INHERIT, 0)) - return GetLastError(); - - /* Associate it with the I/O completion port. */ - /* Use uv_handle_t pointer as completion key. */ - if (CreateIoCompletionPort((HANDLE)socket, - loop->iocp, - (ULONG_PTR)socket, - 0) == NULL) { - if (imported) { - handle->flags |= UV_HANDLE_EMULATE_IOCP; - } else { - return GetLastError(); - } - } - - if (family == AF_INET6) { - non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv6; - } else { - non_ifs_lsp = uv_tcp_non_ifs_lsp_ipv4; - } - - if (pSetFileCompletionNotificationModes && - !(handle->flags & UV_HANDLE_EMULATE_IOCP) && !non_ifs_lsp) { - if (pSetFileCompletionNotificationModes((HANDLE) socket, - FILE_SKIP_SET_EVENT_ON_HANDLE | - FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { - handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; - } else if (GetLastError() != ERROR_INVALID_FUNCTION) { - return GetLastError(); - } - } - - if (handle->flags & UV_HANDLE_TCP_NODELAY) { - err = uv__tcp_nodelay(handle, socket, 1); - if (err) - return err; - } - - /* TODO: Use stored delay. */ - if (handle->flags & UV_HANDLE_TCP_KEEPALIVE) { - err = uv__tcp_keepalive(handle, socket, 1, 60); - if (err) - return err; - } - - handle->socket = socket; - - if (family == AF_INET6) { - handle->flags |= UV_HANDLE_IPV6; - } else { - assert(!(handle->flags & UV_HANDLE_IPV6)); - } - - return 0; -} - - -int uv_tcp_init_ex(uv_loop_t* loop, uv_tcp_t* handle, unsigned int flags) { - int domain; - - /* Use the lower 8 bits for the domain */ - domain = flags & 0xFF; - if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) - return UV_EINVAL; - - if (flags & ~0xFF) - return UV_EINVAL; - - uv_stream_init(loop, (uv_stream_t*) handle, UV_TCP); - handle->tcp.serv.accept_reqs = NULL; - handle->tcp.serv.pending_accepts = NULL; - handle->socket = INVALID_SOCKET; - handle->reqs_pending = 0; - handle->tcp.serv.func_acceptex = NULL; - handle->tcp.conn.func_connectex = NULL; - handle->tcp.serv.processed_accepts = 0; - handle->delayed_error = 0; - - /* If anything fails beyond this point we need to remove the handle from - * the handle queue, since it was added by uv__handle_init in uv_stream_init. - */ - - if (domain != AF_UNSPEC) { - SOCKET sock; - DWORD err; - - sock = socket(domain, SOCK_STREAM, 0); - if (sock == INVALID_SOCKET) { - err = WSAGetLastError(); - QUEUE_REMOVE(&handle->handle_queue); - return uv_translate_sys_error(err); - } - - err = uv_tcp_set_socket(handle->loop, handle, sock, domain, 0); - if (err) { - closesocket(sock); - QUEUE_REMOVE(&handle->handle_queue); - return uv_translate_sys_error(err); - } - - } - - return 0; -} - - -int uv_tcp_init(uv_loop_t* loop, uv_tcp_t* handle) { - return uv_tcp_init_ex(loop, handle, AF_UNSPEC); -} - - -void uv_tcp_endgame(uv_loop_t* loop, uv_tcp_t* handle) { - int err; - unsigned int i; - uv_tcp_accept_t* req; - - if (handle->flags & UV_HANDLE_CONNECTION && - handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - - UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req); - - err = 0; - if (handle->flags & UV__HANDLE_CLOSING) { - err = ERROR_OPERATION_ABORTED; - } else if (shutdown(handle->socket, SD_SEND) == SOCKET_ERROR) { - err = WSAGetLastError(); - } - - if (handle->stream.conn.shutdown_req->cb) { - handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, - uv_translate_sys_error(err)); - } - - handle->stream.conn.shutdown_req = NULL; - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - - if (!(handle->flags & UV_HANDLE_TCP_SOCKET_CLOSED)) { - closesocket(handle->socket); - handle->socket = INVALID_SOCKET; - handle->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; - } - - if (!(handle->flags & UV_HANDLE_CONNECTION) && handle->tcp.serv.accept_reqs) { - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - for (i = 0; i < uv_simultaneous_server_accepts; i++) { - req = &handle->tcp.serv.accept_reqs[i]; - if (req->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(req->wait_handle); - req->wait_handle = INVALID_HANDLE_VALUE; - } - if (req->event_handle) { - CloseHandle(req->event_handle); - req->event_handle = NULL; - } - } - } - - uv__free(handle->tcp.serv.accept_reqs); - handle->tcp.serv.accept_reqs = NULL; - } - - if (handle->flags & UV_HANDLE_CONNECTION && - handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (handle->read_req.wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(handle->read_req.wait_handle); - handle->read_req.wait_handle = INVALID_HANDLE_VALUE; - } - if (handle->read_req.event_handle) { - CloseHandle(handle->read_req.event_handle); - handle->read_req.event_handle = NULL; - } - } - - uv__handle_close(handle); - loop->active_tcp_streams--; - } -} - - -/* Unlike on Unix, here we don't set SO_REUSEADDR, because it doesn't just - * allow binding to addresses that are in use by sockets in TIME_WAIT, it - * effectively allows 'stealing' a port which is in use by another application. - * - * SO_EXCLUSIVEADDRUSE is also not good here because it does check all sockets, - * regardless of state, so we'd get an error even if the port is in use by a - * socket in TIME_WAIT state. - * - * See issue #1360. - * - */ -static int uv_tcp_try_bind(uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - DWORD err; - int r; - - if (handle->socket == INVALID_SOCKET) { - SOCKET sock; - - /* Cannot set IPv6-only mode on non-IPv6 socket. */ - if ((flags & UV_TCP_IPV6ONLY) && addr->sa_family != AF_INET6) - return ERROR_INVALID_PARAMETER; - - sock = socket(addr->sa_family, SOCK_STREAM, 0); - if (sock == INVALID_SOCKET) { - return WSAGetLastError(); - } - - err = uv_tcp_set_socket(handle->loop, handle, sock, addr->sa_family, 0); - if (err) { - closesocket(sock); - return err; - } - } - -#ifdef IPV6_V6ONLY - if (addr->sa_family == AF_INET6) { - int on; - - on = (flags & UV_TCP_IPV6ONLY) != 0; - - /* TODO: how to handle errors? This may fail if there is no ipv4 stack */ - /* available, or when run on XP/2003 which have no support for dualstack */ - /* sockets. For now we're silently ignoring the error. */ - setsockopt(handle->socket, - IPPROTO_IPV6, - IPV6_V6ONLY, - (const char*)&on, - sizeof on); - } -#endif - - r = bind(handle->socket, addr, addrlen); - - if (r == SOCKET_ERROR) { - err = WSAGetLastError(); - if (err == WSAEADDRINUSE) { - /* Some errors are not to be reported until connect() or listen() */ - handle->delayed_error = err; - } else { - return err; - } - } - - handle->flags |= UV_HANDLE_BOUND; - - return 0; -} - - -static void CALLBACK post_completion(void* context, BOOLEAN timed_out) { - uv_req_t* req; - uv_tcp_t* handle; - - req = (uv_req_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->data; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->u.io.overlapped.InternalHigh, - 0, - &req->u.io.overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void CALLBACK post_write_completion(void* context, BOOLEAN timed_out) { - uv_write_t* req; - uv_tcp_t* handle; - - req = (uv_write_t*) context; - assert(req != NULL); - handle = (uv_tcp_t*)req->handle; - assert(handle != NULL); - assert(!timed_out); - - if (!PostQueuedCompletionStatus(handle->loop->iocp, - req->u.io.overlapped.InternalHigh, - 0, - &req->u.io.overlapped)) { - uv_fatal_error(GetLastError(), "PostQueuedCompletionStatus"); - } -} - - -static void uv_tcp_queue_accept(uv_tcp_t* handle, uv_tcp_accept_t* req) { - uv_loop_t* loop = handle->loop; - BOOL success; - DWORD bytes; - SOCKET accept_socket; - short family; - - assert(handle->flags & UV_HANDLE_LISTENING); - assert(req->accept_socket == INVALID_SOCKET); - - /* choose family and extension function */ - if (handle->flags & UV_HANDLE_IPV6) { - family = AF_INET6; - } else { - family = AF_INET; - } - - /* Open a socket for the accepted connection. */ - accept_socket = socket(family, SOCK_STREAM, 0); - if (accept_socket == INVALID_SOCKET) { - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - return; - } - - /* Make the socket non-inheritable */ - if (!SetHandleInformation((HANDLE) accept_socket, HANDLE_FLAG_INHERIT, 0)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - closesocket(accept_socket); - return; - } - - /* Prepare the overlapped structure. */ - memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); - } - - success = handle->tcp.serv.func_acceptex(handle->socket, - accept_socket, - (void*)req->accept_buffer, - 0, - sizeof(struct sockaddr_storage), - sizeof(struct sockaddr_storage), - &bytes, - &req->u.io.overlapped); - - if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { - /* Process the req without IOCP. */ - req->accept_socket = accept_socket; - handle->reqs_pending++; - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(success)) { - /* The req will be processed with IOCP. */ - req->accept_socket = accept_socket; - handle->reqs_pending++; - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - req->wait_handle == INVALID_HANDLE_VALUE && - !RegisterWaitForSingleObject(&req->wait_handle, - req->event_handle, post_completion, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - return; - } - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - /* Destroy the preallocated client socket. */ - closesocket(accept_socket); - /* Destroy the event handle */ - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - CloseHandle(req->u.io.overlapped.hEvent); - req->event_handle = NULL; - } - } -} - - -static void uv_tcp_queue_read(uv_loop_t* loop, uv_tcp_t* handle) { - uv_read_t* req; - uv_buf_t buf; - int result; - DWORD bytes, flags; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - req = &handle->read_req; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - /* - * Preallocate a read buffer if the number of active streams is below - * the threshold. - */ - if (loop->active_tcp_streams < uv_active_tcp_streams_threshold) { - handle->flags &= ~UV_HANDLE_ZERO_READ; - handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->tcp.conn.read_buffer); - if (handle->tcp.conn.read_buffer.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &handle->tcp.conn.read_buffer); - return; - } - assert(handle->tcp.conn.read_buffer.base != NULL); - buf = handle->tcp.conn.read_buffer; - } else { - handle->flags |= UV_HANDLE_ZERO_READ; - buf.base = (char*) &uv_zero_; - buf.len = 0; - } - - /* Prepare the overlapped structure. */ - memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - assert(req->event_handle); - req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); - } - - flags = 0; - result = WSARecv(handle->socket, - (WSABUF*)&buf, - 1, - &bytes, - &flags, - &req->u.io.overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Process the req without IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - req->u.io.overlapped.InternalHigh = bytes; - handle->reqs_pending++; - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* The req will be processed with IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - req->wait_handle == INVALID_HANDLE_VALUE && - !RegisterWaitForSingleObject(&req->wait_handle, - req->event_handle, post_completion, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - handle->reqs_pending++; - } -} - - -int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) { - uv_loop_t* loop = handle->loop; - unsigned int i, simultaneous_accepts; - uv_tcp_accept_t* req; - int err; - - assert(backlog > 0); - - if (handle->flags & UV_HANDLE_LISTENING) { - handle->stream.serv.connection_cb = cb; - } - - if (handle->flags & UV_HANDLE_READING) { - return WSAEISCONN; - } - - if (handle->delayed_error) { - return handle->delayed_error; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - err = uv_tcp_try_bind(handle, - (const struct sockaddr*) &uv_addr_ip4_any_, - sizeof(uv_addr_ip4_any_), - 0); - if (err) - return err; - if (handle->delayed_error) - return handle->delayed_error; - } - - if (!handle->tcp.serv.func_acceptex) { - if (!uv_get_acceptex_function(handle->socket, &handle->tcp.serv.func_acceptex)) { - return WSAEAFNOSUPPORT; - } - } - - if (!(handle->flags & UV_HANDLE_SHARED_TCP_SOCKET) && - listen(handle->socket, backlog) == SOCKET_ERROR) { - return WSAGetLastError(); - } - - handle->flags |= UV_HANDLE_LISTENING; - handle->stream.serv.connection_cb = cb; - INCREASE_ACTIVE_COUNT(loop, handle); - - simultaneous_accepts = handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT ? 1 - : uv_simultaneous_server_accepts; - - if(!handle->tcp.serv.accept_reqs) { - handle->tcp.serv.accept_reqs = (uv_tcp_accept_t*) - uv__malloc(uv_simultaneous_server_accepts * sizeof(uv_tcp_accept_t)); - if (!handle->tcp.serv.accept_reqs) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - for (i = 0; i < simultaneous_accepts; i++) { - req = &handle->tcp.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*)req); - req->type = UV_ACCEPT; - req->accept_socket = INVALID_SOCKET; - req->data = handle; - - req->wait_handle = INVALID_HANDLE_VALUE; - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } else { - req->event_handle = NULL; - } - - uv_tcp_queue_accept(handle, req); - } - - /* Initialize other unused requests too, because uv_tcp_endgame */ - /* doesn't know how how many requests were initialized, so it will */ - /* try to clean up {uv_simultaneous_server_accepts} requests. */ - for (i = simultaneous_accepts; i < uv_simultaneous_server_accepts; i++) { - req = &handle->tcp.serv.accept_reqs[i]; - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_ACCEPT; - req->accept_socket = INVALID_SOCKET; - req->data = handle; - req->wait_handle = INVALID_HANDLE_VALUE; - req->event_handle = NULL; - } - } - - return 0; -} - - -int uv_tcp_accept(uv_tcp_t* server, uv_tcp_t* client) { - uv_loop_t* loop = server->loop; - int err = 0; - int family; - - uv_tcp_accept_t* req = server->tcp.serv.pending_accepts; - - if (!req) { - /* No valid connections found, so we error out. */ - return WSAEWOULDBLOCK; - } - - if (req->accept_socket == INVALID_SOCKET) { - return WSAENOTCONN; - } - - if (server->flags & UV_HANDLE_IPV6) { - family = AF_INET6; - } else { - family = AF_INET; - } - - err = uv_tcp_set_socket(client->loop, - client, - req->accept_socket, - family, - 0); - if (err) { - closesocket(req->accept_socket); - } else { - uv_connection_init((uv_stream_t*) client); - /* AcceptEx() implicitly binds the accepted socket. */ - client->flags |= UV_HANDLE_BOUND | UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - } - - /* Prepare the req to pick up a new connection */ - server->tcp.serv.pending_accepts = req->next_pending; - req->next_pending = NULL; - req->accept_socket = INVALID_SOCKET; - - if (!(server->flags & UV__HANDLE_CLOSING)) { - /* Check if we're in a middle of changing the number of pending accepts. */ - if (!(server->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING)) { - uv_tcp_queue_accept(server, req); - } else { - /* We better be switching to a single pending accept. */ - assert(server->flags & UV_HANDLE_TCP_SINGLE_ACCEPT); - - server->tcp.serv.processed_accepts++; - - if (server->tcp.serv.processed_accepts >= uv_simultaneous_server_accepts) { - server->tcp.serv.processed_accepts = 0; - /* - * All previously queued accept requests are now processed. - * We now switch to queueing just a single accept. - */ - uv_tcp_queue_accept(server, &server->tcp.serv.accept_reqs[0]); - server->flags &= ~UV_HANDLE_TCP_ACCEPT_STATE_CHANGING; - server->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; - } - } - } - - loop->active_tcp_streams++; - - return err; -} - - -int uv_tcp_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - uv_loop_t* loop = handle->loop; - - handle->flags |= UV_HANDLE_READING; - handle->read_cb = read_cb; - handle->alloc_cb = alloc_cb; - INCREASE_ACTIVE_COUNT(loop, handle); - - /* If reading was stopped and then started again, there could still be a */ - /* read request pending. */ - if (!(handle->flags & UV_HANDLE_READ_PENDING)) { - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - !handle->read_req.event_handle) { - handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!handle->read_req.event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - } - uv_tcp_queue_read(loop, handle); - } - - return 0; -} - - -static int uv_tcp_try_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - uv_connect_cb cb) { - uv_loop_t* loop = handle->loop; - const struct sockaddr* bind_addr; - BOOL success; - DWORD bytes; - int err; - - if (handle->delayed_error) { - return handle->delayed_error; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) { - if (addrlen == sizeof(uv_addr_ip4_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; - } else if (addrlen == sizeof(uv_addr_ip6_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; - } else { - abort(); - } - err = uv_tcp_try_bind(handle, bind_addr, addrlen, 0); - if (err) - return err; - if (handle->delayed_error) - return handle->delayed_error; - } - - if (!handle->tcp.conn.func_connectex) { - if (!uv_get_connectex_function(handle->socket, &handle->tcp.conn.func_connectex)) { - return WSAEAFNOSUPPORT; - } - } - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_CONNECT; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - success = handle->tcp.conn.func_connectex(handle->socket, - addr, - addrlen, - NULL, - 0, - &bytes, - &req->u.io.overlapped); - - if (UV_SUCCEEDED_WITHOUT_IOCP(success)) { - /* Process the req without IOCP. */ - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(success)) { - /* The req will be processed with IOCP. */ - handle->reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - } else { - return WSAGetLastError(); - } - - return 0; -} - - -int uv_tcp_getsockname(const uv_tcp_t* handle, - struct sockaddr* name, - int* namelen) { - int result; - - if (handle->socket == INVALID_SOCKET) { - return UV_EINVAL; - } - - if (handle->delayed_error) { - return uv_translate_sys_error(handle->delayed_error); - } - - result = getsockname(handle->socket, name, namelen); - if (result != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_tcp_getpeername(const uv_tcp_t* handle, - struct sockaddr* name, - int* namelen) { - int result; - - if (handle->socket == INVALID_SOCKET) { - return UV_EINVAL; - } - - if (handle->delayed_error) { - return uv_translate_sys_error(handle->delayed_error); - } - - result = getpeername(handle->socket, name, namelen); - if (result != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_tcp_write(uv_loop_t* loop, - uv_write_t* req, - uv_tcp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - int result; - DWORD bytes; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - - /* Prepare the overlapped structure. */ - memset(&(req->u.io.overlapped), 0, sizeof(req->u.io.overlapped)); - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - req->event_handle = CreateEvent(NULL, 0, 0, NULL); - if (!req->event_handle) { - uv_fatal_error(GetLastError(), "CreateEvent"); - } - req->u.io.overlapped.hEvent = (HANDLE) ((ULONG_PTR) req->event_handle | 1); - req->wait_handle = INVALID_HANDLE_VALUE; - } - - result = WSASend(handle->socket, - (WSABUF*) bufs, - nbufs, - &bytes, - 0, - &req->u.io.overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Request completed immediately. */ - req->u.io.queued_bytes = 0; - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - uv_insert_pending_req(loop, (uv_req_t*) req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* Request queued by the kernel. */ - req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - handle->write_queue_size += req->u.io.queued_bytes; - if (handle->flags & UV_HANDLE_EMULATE_IOCP && - !RegisterWaitForSingleObject(&req->wait_handle, - req->event_handle, post_write_completion, (void*) req, - INFINITE, WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE)) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - } else { - /* Send failed due to an error, report it later */ - req->u.io.queued_bytes = 0; - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, (uv_req_t*) req); - } - - return 0; -} - - -int uv__tcp_try_write(uv_tcp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs) { - int result; - DWORD bytes; - - if (handle->stream.conn.write_reqs_pending > 0) - return UV_EAGAIN; - - result = WSASend(handle->socket, - (WSABUF*) bufs, - nbufs, - &bytes, - 0, - NULL, - NULL); - - if (result == SOCKET_ERROR) - return uv_translate_sys_error(WSAGetLastError()); - else - return bytes; -} - - -void uv_process_tcp_read_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_req_t* req) { - DWORD bytes, flags, err; - uv_buf_t buf; - - assert(handle->type == UV_TCP); - - handle->flags &= ~UV_HANDLE_READ_PENDING; - - if (!REQ_SUCCESS(req)) { - /* An error occurred doing the read. */ - if ((handle->flags & UV_HANDLE_READING) || - !(handle->flags & UV_HANDLE_ZERO_READ)) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - buf = (handle->flags & UV_HANDLE_ZERO_READ) ? - uv_buf_init(NULL, 0) : handle->tcp.conn.read_buffer; - - err = GET_REQ_SOCK_ERROR(req); - - if (err == WSAECONNABORTED) { - /* - * Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with Unix. - */ - err = WSAECONNRESET; - } - - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(err), - &buf); - } - } else { - if (!(handle->flags & UV_HANDLE_ZERO_READ)) { - /* The read was done with a non-zero buffer length. */ - if (req->u.io.overlapped.InternalHigh > 0) { - /* Successful read */ - handle->read_cb((uv_stream_t*)handle, - req->u.io.overlapped.InternalHigh, - &handle->tcp.conn.read_buffer); - /* Read again only if bytes == buf.len */ - if (req->u.io.overlapped.InternalHigh < handle->tcp.conn.read_buffer.len) { - goto done; - } - } else { - /* Connection closed */ - if (handle->flags & UV_HANDLE_READING) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - } - handle->flags &= ~UV_HANDLE_READABLE; - - buf.base = 0; - buf.len = 0; - handle->read_cb((uv_stream_t*)handle, UV_EOF, &handle->tcp.conn.read_buffer); - goto done; - } - } - - /* Do nonblocking reads until the buffer is empty */ - while (handle->flags & UV_HANDLE_READING) { - handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); - if (buf.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); - break; - } - assert(buf.base != NULL); - - flags = 0; - if (WSARecv(handle->socket, - (WSABUF*)&buf, - 1, - &bytes, - &flags, - NULL, - NULL) != SOCKET_ERROR) { - if (bytes > 0) { - /* Successful read */ - handle->read_cb((uv_stream_t*)handle, bytes, &buf); - /* Read again only if bytes == buf.len */ - if (bytes < buf.len) { - break; - } - } else { - /* Connection closed */ - handle->flags &= ~(UV_HANDLE_READING | UV_HANDLE_READABLE); - DECREASE_ACTIVE_COUNT(loop, handle); - - handle->read_cb((uv_stream_t*)handle, UV_EOF, &buf); - break; - } - } else { - err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { - /* Read buffer was completely empty, report a 0-byte read. */ - handle->read_cb((uv_stream_t*)handle, 0, &buf); - } else { - /* Ouch! serious error. */ - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - - if (err == WSAECONNABORTED) { - /* Turn WSAECONNABORTED into UV_ECONNRESET to be consistent with */ - /* Unix. */ - err = WSAECONNRESET; - } - - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(err), - &buf); - } - break; - } - } - -done: - /* Post another read if still reading and not closing. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_tcp_queue_read(loop, handle); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tcp_write_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_write_t* req) { - int err; - - assert(handle->type == UV_TCP); - - assert(handle->write_queue_size >= req->u.io.queued_bytes); - handle->write_queue_size -= req->u.io.queued_bytes; - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (handle->flags & UV_HANDLE_EMULATE_IOCP) { - if (req->wait_handle != INVALID_HANDLE_VALUE) { - UnregisterWait(req->wait_handle); - req->wait_handle = INVALID_HANDLE_VALUE; - } - if (req->event_handle) { - CloseHandle(req->event_handle); - req->event_handle = NULL; - } - } - - if (req->cb) { - err = uv_translate_sys_error(GET_REQ_SOCK_ERROR(req)); - if (err == UV_ECONNABORTED) { - /* use UV_ECANCELED for consistency with Unix */ - err = UV_ECANCELED; - } - req->cb(req, err); - } - - handle->stream.conn.write_reqs_pending--; - if (handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tcp_accept_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_req_t* raw_req) { - uv_tcp_accept_t* req = (uv_tcp_accept_t*) raw_req; - int err; - - assert(handle->type == UV_TCP); - - /* If handle->accepted_socket is not a valid socket, then */ - /* uv_queue_accept must have failed. This is a serious error. We stop */ - /* accepting connections and report this error to the connection */ - /* callback. */ - if (req->accept_socket == INVALID_SOCKET) { - if (handle->flags & UV_HANDLE_LISTENING) { - handle->flags &= ~UV_HANDLE_LISTENING; - DECREASE_ACTIVE_COUNT(loop, handle); - if (handle->stream.serv.connection_cb) { - err = GET_REQ_SOCK_ERROR(req); - handle->stream.serv.connection_cb((uv_stream_t*)handle, - uv_translate_sys_error(err)); - } - } - } else if (REQ_SUCCESS(req) && - setsockopt(req->accept_socket, - SOL_SOCKET, - SO_UPDATE_ACCEPT_CONTEXT, - (char*)&handle->socket, - sizeof(handle->socket)) == 0) { - req->next_pending = handle->tcp.serv.pending_accepts; - handle->tcp.serv.pending_accepts = req; - - /* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */ - if (handle->stream.serv.connection_cb) { - handle->stream.serv.connection_cb((uv_stream_t*)handle, 0); - } - } else { - /* Error related to accepted socket is ignored because the server */ - /* socket may still be healthy. If the server socket is broken */ - /* uv_queue_accept will detect it. */ - closesocket(req->accept_socket); - req->accept_socket = INVALID_SOCKET; - if (handle->flags & UV_HANDLE_LISTENING) { - uv_tcp_queue_accept(handle, req); - } - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tcp_connect_req(uv_loop_t* loop, uv_tcp_t* handle, - uv_connect_t* req) { - int err; - - assert(handle->type == UV_TCP); - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - err = 0; - if (REQ_SUCCESS(req)) { - if (setsockopt(handle->socket, - SOL_SOCKET, - SO_UPDATE_CONNECT_CONTEXT, - NULL, - 0) == 0) { - uv_connection_init((uv_stream_t*)handle); - handle->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - loop->active_tcp_streams++; - } else { - err = WSAGetLastError(); - } - } else { - err = GET_REQ_SOCK_ERROR(req); - } - req->cb(req, uv_translate_sys_error(err)); - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -int uv_tcp_import(uv_tcp_t* tcp, uv__ipc_socket_info_ex* socket_info_ex, - int tcp_connection) { - int err; - SOCKET socket = WSASocketW(FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - FROM_PROTOCOL_INFO, - &socket_info_ex->socket_info, - 0, - WSA_FLAG_OVERLAPPED); - - if (socket == INVALID_SOCKET) { - return WSAGetLastError(); - } - - err = uv_tcp_set_socket(tcp->loop, - tcp, - socket, - socket_info_ex->socket_info.iAddressFamily, - 1); - if (err) { - closesocket(socket); - return err; - } - - if (tcp_connection) { - uv_connection_init((uv_stream_t*)tcp); - tcp->flags |= UV_HANDLE_READABLE | UV_HANDLE_WRITABLE; - } - - tcp->flags |= UV_HANDLE_BOUND; - tcp->flags |= UV_HANDLE_SHARED_TCP_SOCKET; - - tcp->delayed_error = socket_info_ex->delayed_error; - - tcp->loop->active_tcp_streams++; - return 0; -} - - -int uv_tcp_nodelay(uv_tcp_t* handle, int enable) { - int err; - - if (handle->socket != INVALID_SOCKET) { - err = uv__tcp_nodelay(handle, handle->socket, enable); - if (err) - return err; - } - - if (enable) { - handle->flags |= UV_HANDLE_TCP_NODELAY; - } else { - handle->flags &= ~UV_HANDLE_TCP_NODELAY; - } - - return 0; -} - - -int uv_tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay) { - int err; - - if (handle->socket != INVALID_SOCKET) { - err = uv__tcp_keepalive(handle, handle->socket, enable, delay); - if (err) - return err; - } - - if (enable) { - handle->flags |= UV_HANDLE_TCP_KEEPALIVE; - } else { - handle->flags &= ~UV_HANDLE_TCP_KEEPALIVE; - } - - /* TODO: Store delay if handle->socket isn't created yet. */ - - return 0; -} - - -int uv_tcp_duplicate_socket(uv_tcp_t* handle, int pid, - LPWSAPROTOCOL_INFOW protocol_info) { - if (!(handle->flags & UV_HANDLE_CONNECTION)) { - /* - * We're about to share the socket with another process. Because - * this is a listening socket, we assume that the other process will - * be accepting connections on it. So, before sharing the socket - * with another process, we call listen here in the parent process. - */ - - if (!(handle->flags & UV_HANDLE_LISTENING)) { - if (!(handle->flags & UV_HANDLE_BOUND)) { - return ERROR_INVALID_PARAMETER; - } - - if (!(handle->delayed_error)) { - if (listen(handle->socket, SOMAXCONN) == SOCKET_ERROR) { - handle->delayed_error = WSAGetLastError(); - } - } - } - } - - if (WSADuplicateSocketW(handle->socket, pid, protocol_info)) { - return WSAGetLastError(); - } - - handle->flags |= UV_HANDLE_SHARED_TCP_SOCKET; - - return 0; -} - - -int uv_tcp_simultaneous_accepts(uv_tcp_t* handle, int enable) { - if (handle->flags & UV_HANDLE_CONNECTION) { - return UV_EINVAL; - } - - /* Check if we're already in the desired mode. */ - if ((enable && !(handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) || - (!enable && handle->flags & UV_HANDLE_TCP_SINGLE_ACCEPT)) { - return 0; - } - - /* Don't allow switching from single pending accept to many. */ - if (enable) { - return UV_ENOTSUP; - } - - /* Check if we're in a middle of changing the number of pending accepts. */ - if (handle->flags & UV_HANDLE_TCP_ACCEPT_STATE_CHANGING) { - return 0; - } - - handle->flags |= UV_HANDLE_TCP_SINGLE_ACCEPT; - - /* Flip the changing flag if we have already queued multiple accepts. */ - if (handle->flags & UV_HANDLE_LISTENING) { - handle->flags |= UV_HANDLE_TCP_ACCEPT_STATE_CHANGING; - } - - return 0; -} - - -static int uv_tcp_try_cancel_io(uv_tcp_t* tcp) { - SOCKET socket = tcp->socket; - int non_ifs_lsp; - - /* Check if we have any non-IFS LSPs stacked on top of TCP */ - non_ifs_lsp = (tcp->flags & UV_HANDLE_IPV6) ? uv_tcp_non_ifs_lsp_ipv6 : - uv_tcp_non_ifs_lsp_ipv4; - - /* If there are non-ifs LSPs then try to obtain a base handle for the */ - /* socket. This will always fail on Windows XP/3k. */ - if (non_ifs_lsp) { - DWORD bytes; - if (WSAIoctl(socket, - SIO_BASE_HANDLE, - NULL, - 0, - &socket, - sizeof socket, - &bytes, - NULL, - NULL) != 0) { - /* Failed. We can't do CancelIo. */ - return -1; - } - } - - assert(socket != 0 && socket != INVALID_SOCKET); - - if (!CancelIo((HANDLE) socket)) { - return GetLastError(); - } - - /* It worked. */ - return 0; -} - - -void uv_tcp_close(uv_loop_t* loop, uv_tcp_t* tcp) { - int close_socket = 1; - - if (tcp->flags & UV_HANDLE_READ_PENDING) { - /* In order for winsock to do a graceful close there must not be any */ - /* any pending reads, or the socket must be shut down for writing */ - if (!(tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET)) { - /* Just do shutdown on non-shared sockets, which ensures graceful close. */ - shutdown(tcp->socket, SD_SEND); - - } else if (uv_tcp_try_cancel_io(tcp) == 0) { - /* In case of a shared socket, we try to cancel all outstanding I/O, */ - /* If that works, don't close the socket yet - wait for the read req to */ - /* return and close the socket in uv_tcp_endgame. */ - close_socket = 0; - - } else { - /* When cancelling isn't possible - which could happen when an LSP is */ - /* present on an old Windows version, we will have to close the socket */ - /* with a read pending. That is not nice because trailing sent bytes */ - /* may not make it to the other side. */ - } - - } else if ((tcp->flags & UV_HANDLE_SHARED_TCP_SOCKET) && - tcp->tcp.serv.accept_reqs != NULL) { - /* Under normal circumstances closesocket() will ensure that all pending */ - /* accept reqs are canceled. However, when the socket is shared the */ - /* presence of another reference to the socket in another process will */ - /* keep the accept reqs going, so we have to ensure that these are */ - /* canceled. */ - if (uv_tcp_try_cancel_io(tcp) != 0) { - /* When cancellation is not possible, there is another option: we can */ - /* close the incoming sockets, which will also cancel the accept */ - /* operations. However this is not cool because we might inadvertently */ - /* close a socket that just accepted a new connection, which will */ - /* cause the connection to be aborted. */ - unsigned int i; - for (i = 0; i < uv_simultaneous_server_accepts; i++) { - uv_tcp_accept_t* req = &tcp->tcp.serv.accept_reqs[i]; - if (req->accept_socket != INVALID_SOCKET && - !HasOverlappedIoCompleted(&req->u.io.overlapped)) { - closesocket(req->accept_socket); - req->accept_socket = INVALID_SOCKET; - } - } - } - } - - if (tcp->flags & UV_HANDLE_READING) { - tcp->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, tcp); - } - - if (tcp->flags & UV_HANDLE_LISTENING) { - tcp->flags &= ~UV_HANDLE_LISTENING; - DECREASE_ACTIVE_COUNT(loop, tcp); - } - - if (close_socket) { - closesocket(tcp->socket); - tcp->socket = INVALID_SOCKET; - tcp->flags |= UV_HANDLE_TCP_SOCKET_CLOSED; - } - - tcp->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); - uv__handle_closing(tcp); - - if (tcp->reqs_pending == 0) { - uv_want_endgame(tcp->loop, (uv_handle_t*)tcp); - } -} - - -int uv_tcp_open(uv_tcp_t* handle, uv_os_sock_t sock) { - WSAPROTOCOL_INFOW protocol_info; - int opt_len; - int err; - - /* Detect the address family of the socket. */ - opt_len = (int) sizeof protocol_info; - if (getsockopt(sock, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) { - return uv_translate_sys_error(GetLastError()); - } - - err = uv_tcp_set_socket(handle->loop, - handle, - sock, - protocol_info.iAddressFamily, - 1); - if (err) { - return uv_translate_sys_error(err); - } - - return 0; -} - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__tcp_bind(uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int err; - - err = uv_tcp_try_bind(handle, addr, addrlen, flags); - if (err) - return uv_translate_sys_error(err); - - return 0; -} - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__tcp_connect(uv_connect_t* req, - uv_tcp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - uv_connect_cb cb) { - int err; - - err = uv_tcp_try_connect(req, handle, addr, addrlen, cb); - if (err) - return uv_translate_sys_error(err); - - return 0; -} diff --git a/3rdparty/libuv/src/win/thread.c b/3rdparty/libuv/src/win/thread.c deleted file mode 100644 index 91684e93875..00000000000 --- a/3rdparty/libuv/src/win/thread.c +++ /dev/null @@ -1,697 +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. - */ - -#include <assert.h> -#include <limits.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" - - -#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL) - -static int uv_cond_fallback_init(uv_cond_t* cond); -static void uv_cond_fallback_destroy(uv_cond_t* cond); -static void uv_cond_fallback_signal(uv_cond_t* cond); -static void uv_cond_fallback_broadcast(uv_cond_t* cond); -static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex); -static int uv_cond_fallback_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout); - -static int uv_cond_condvar_init(uv_cond_t* cond); -static void uv_cond_condvar_destroy(uv_cond_t* cond); -static void uv_cond_condvar_signal(uv_cond_t* cond); -static void uv_cond_condvar_broadcast(uv_cond_t* cond); -static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex); -static int uv_cond_condvar_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout); - - -static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) { - DWORD result; - HANDLE existing_event, created_event; - - created_event = CreateEvent(NULL, 1, 0, NULL); - if (created_event == 0) { - /* Could fail in a low-memory situation? */ - uv_fatal_error(GetLastError(), "CreateEvent"); - } - - existing_event = InterlockedCompareExchangePointer(&guard->event, - created_event, - NULL); - - if (existing_event == NULL) { - /* We won the race */ - callback(); - - result = SetEvent(created_event); - assert(result); - guard->ran = 1; - - } else { - /* We lost the race. Destroy the event we created and wait for the */ - /* existing one to become signaled. */ - CloseHandle(created_event); - result = WaitForSingleObject(existing_event, INFINITE); - assert(result == WAIT_OBJECT_0); - } -} - - -void uv_once(uv_once_t* guard, void (*callback)(void)) { - /* Fast case - avoid WaitForSingleObject. */ - if (guard->ran) { - return; - } - - uv__once_inner(guard, callback); -} - - -/* Verify that uv_thread_t can be stored in a TLS slot. */ -STATIC_ASSERT(sizeof(uv_thread_t) <= sizeof(void*)); - -static uv_key_t uv__current_thread_key; -static uv_once_t uv__current_thread_init_guard = UV_ONCE_INIT; - - -static void uv__init_current_thread_key(void) { - if (uv_key_create(&uv__current_thread_key)) - abort(); -} - - -struct thread_ctx { - void (*entry)(void* arg); - void* arg; - uv_thread_t self; -}; - - -static UINT __stdcall uv__thread_start(void* arg) { - struct thread_ctx *ctx_p; - struct thread_ctx ctx; - - ctx_p = arg; - ctx = *ctx_p; - uv__free(ctx_p); - - uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); - uv_key_set(&uv__current_thread_key, (void*) ctx.self); - - ctx.entry(ctx.arg); - - return 0; -} - - -int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) { - struct thread_ctx* ctx; - int err; - HANDLE thread; - - ctx = uv__malloc(sizeof(*ctx)); - if (ctx == NULL) - return UV_ENOMEM; - - ctx->entry = entry; - ctx->arg = arg; - - /* Create the thread in suspended state so we have a chance to pass - * its own creation handle to it */ - thread = (HANDLE) _beginthreadex(NULL, - 0, - uv__thread_start, - ctx, - CREATE_SUSPENDED, - NULL); - if (thread == NULL) { - err = errno; - uv__free(ctx); - } else { - err = 0; - *tid = thread; - ctx->self = thread; - ResumeThread(thread); - } - - switch (err) { - case 0: - return 0; - case EACCES: - return UV_EACCES; - case EAGAIN: - return UV_EAGAIN; - case EINVAL: - return UV_EINVAL; - } - - return UV_EIO; -} - - -uv_thread_t uv_thread_self(void) { - uv_once(&uv__current_thread_init_guard, uv__init_current_thread_key); - return (uv_thread_t) uv_key_get(&uv__current_thread_key); -} - - -int uv_thread_join(uv_thread_t *tid) { - if (WaitForSingleObject(*tid, INFINITE)) - return uv_translate_sys_error(GetLastError()); - else { - CloseHandle(*tid); - *tid = 0; - return 0; - } -} - - -int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) { - return *t1 == *t2; -} - - -int uv_mutex_init(uv_mutex_t* mutex) { - InitializeCriticalSection(mutex); - return 0; -} - - -void uv_mutex_destroy(uv_mutex_t* mutex) { - DeleteCriticalSection(mutex); -} - - -void uv_mutex_lock(uv_mutex_t* mutex) { - EnterCriticalSection(mutex); -} - - -int uv_mutex_trylock(uv_mutex_t* mutex) { - if (TryEnterCriticalSection(mutex)) - return 0; - else - return UV_EBUSY; -} - - -void uv_mutex_unlock(uv_mutex_t* mutex) { - LeaveCriticalSection(mutex); -} - - -int uv_rwlock_init(uv_rwlock_t* rwlock) { - /* Initialize the semaphore that acts as the write lock. */ - HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL); - if (handle == NULL) - return uv_translate_sys_error(GetLastError()); - rwlock->state_.write_semaphore_ = handle; - - /* Initialize the critical section protecting the reader count. */ - InitializeCriticalSection(&rwlock->state_.num_readers_lock_); - - /* Initialize the reader count. */ - rwlock->state_.num_readers_ = 0; - - return 0; -} - - -void uv_rwlock_destroy(uv_rwlock_t* rwlock) { - DeleteCriticalSection(&rwlock->state_.num_readers_lock_); - CloseHandle(rwlock->state_.write_semaphore_); -} - - -void uv_rwlock_rdlock(uv_rwlock_t* rwlock) { - /* Acquire the lock that protects the reader count. */ - EnterCriticalSection(&rwlock->state_.num_readers_lock_); - - /* Increase the reader count, and lock for write if this is the first - * reader. - */ - if (++rwlock->state_.num_readers_ == 1) { - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE); - if (r != WAIT_OBJECT_0) - uv_fatal_error(GetLastError(), "WaitForSingleObject"); - } - - /* Release the lock that protects the reader count. */ - LeaveCriticalSection(&rwlock->state_.num_readers_lock_); -} - - -int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) { - int err; - - if (!TryEnterCriticalSection(&rwlock->state_.num_readers_lock_)) - return UV_EBUSY; - - err = 0; - - if (rwlock->state_.num_readers_ == 0) { - /* Currently there are no other readers, which means that the write lock - * needs to be acquired. - */ - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0); - if (r == WAIT_OBJECT_0) - rwlock->state_.num_readers_++; - else if (r == WAIT_TIMEOUT) - err = UV_EBUSY; - else if (r == WAIT_FAILED) - uv_fatal_error(GetLastError(), "WaitForSingleObject"); - - } else { - /* The write lock has already been acquired because there are other - * active readers. - */ - rwlock->state_.num_readers_++; - } - - LeaveCriticalSection(&rwlock->state_.num_readers_lock_); - return err; -} - - -void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) { - EnterCriticalSection(&rwlock->state_.num_readers_lock_); - - if (--rwlock->state_.num_readers_ == 0) { - if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL)) - uv_fatal_error(GetLastError(), "ReleaseSemaphore"); - } - - LeaveCriticalSection(&rwlock->state_.num_readers_lock_); -} - - -void uv_rwlock_wrlock(uv_rwlock_t* rwlock) { - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE); - if (r != WAIT_OBJECT_0) - uv_fatal_error(GetLastError(), "WaitForSingleObject"); -} - - -int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) { - DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0); - if (r == WAIT_OBJECT_0) - return 0; - else if (r == WAIT_TIMEOUT) - return UV_EBUSY; - else - uv_fatal_error(GetLastError(), "WaitForSingleObject"); -} - - -void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) { - if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL)) - uv_fatal_error(GetLastError(), "ReleaseSemaphore"); -} - - -int uv_sem_init(uv_sem_t* sem, unsigned int value) { - *sem = CreateSemaphore(NULL, value, INT_MAX, NULL); - if (*sem == NULL) - return uv_translate_sys_error(GetLastError()); - else - return 0; -} - - -void uv_sem_destroy(uv_sem_t* sem) { - if (!CloseHandle(*sem)) - abort(); -} - - -void uv_sem_post(uv_sem_t* sem) { - if (!ReleaseSemaphore(*sem, 1, NULL)) - abort(); -} - - -void uv_sem_wait(uv_sem_t* sem) { - if (WaitForSingleObject(*sem, INFINITE) != WAIT_OBJECT_0) - abort(); -} - - -int uv_sem_trywait(uv_sem_t* sem) { - DWORD r = WaitForSingleObject(*sem, 0); - - if (r == WAIT_OBJECT_0) - return 0; - - if (r == WAIT_TIMEOUT) - return UV_EAGAIN; - - abort(); - return -1; /* Satisfy the compiler. */ -} - - -/* This condition variable implementation is based on the SetEvent solution - * (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html - * We could not use the SignalObjectAndWait solution (section 3.4) because - * it want the 2nd argument (type uv_mutex_t) of uv_cond_wait() and - * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs. - */ - -static int uv_cond_fallback_init(uv_cond_t* cond) { - int err; - - /* Initialize the count to 0. */ - cond->fallback.waiters_count = 0; - - InitializeCriticalSection(&cond->fallback.waiters_count_lock); - - /* Create an auto-reset event. */ - cond->fallback.signal_event = CreateEvent(NULL, /* no security */ - FALSE, /* auto-reset event */ - FALSE, /* non-signaled initially */ - NULL); /* unnamed */ - if (!cond->fallback.signal_event) { - err = GetLastError(); - goto error2; - } - - /* Create a manual-reset event. */ - cond->fallback.broadcast_event = CreateEvent(NULL, /* no security */ - TRUE, /* manual-reset */ - FALSE, /* non-signaled */ - NULL); /* unnamed */ - if (!cond->fallback.broadcast_event) { - err = GetLastError(); - goto error; - } - - return 0; - -error: - CloseHandle(cond->fallback.signal_event); -error2: - DeleteCriticalSection(&cond->fallback.waiters_count_lock); - return uv_translate_sys_error(err); -} - - -static int uv_cond_condvar_init(uv_cond_t* cond) { - pInitializeConditionVariable(&cond->cond_var); - return 0; -} - - -int uv_cond_init(uv_cond_t* cond) { - uv__once_init(); - - if (HAVE_CONDVAR_API()) - return uv_cond_condvar_init(cond); - else - return uv_cond_fallback_init(cond); -} - - -static void uv_cond_fallback_destroy(uv_cond_t* cond) { - if (!CloseHandle(cond->fallback.broadcast_event)) - abort(); - if (!CloseHandle(cond->fallback.signal_event)) - abort(); - DeleteCriticalSection(&cond->fallback.waiters_count_lock); -} - - -static void uv_cond_condvar_destroy(uv_cond_t* cond) { - /* nothing to do */ -} - - -void uv_cond_destroy(uv_cond_t* cond) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_destroy(cond); - else - uv_cond_fallback_destroy(cond); -} - - -static void uv_cond_fallback_signal(uv_cond_t* cond) { - int have_waiters; - - /* Avoid race conditions. */ - EnterCriticalSection(&cond->fallback.waiters_count_lock); - have_waiters = cond->fallback.waiters_count > 0; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - if (have_waiters) - SetEvent(cond->fallback.signal_event); -} - - -static void uv_cond_condvar_signal(uv_cond_t* cond) { - pWakeConditionVariable(&cond->cond_var); -} - - -void uv_cond_signal(uv_cond_t* cond) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_signal(cond); - else - uv_cond_fallback_signal(cond); -} - - -static void uv_cond_fallback_broadcast(uv_cond_t* cond) { - int have_waiters; - - /* Avoid race conditions. */ - EnterCriticalSection(&cond->fallback.waiters_count_lock); - have_waiters = cond->fallback.waiters_count > 0; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - if (have_waiters) - SetEvent(cond->fallback.broadcast_event); -} - - -static void uv_cond_condvar_broadcast(uv_cond_t* cond) { - pWakeAllConditionVariable(&cond->cond_var); -} - - -void uv_cond_broadcast(uv_cond_t* cond) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_broadcast(cond); - else - uv_cond_fallback_broadcast(cond); -} - - -static int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex, - DWORD dwMilliseconds) { - DWORD result; - int last_waiter; - HANDLE handles[2] = { - cond->fallback.signal_event, - cond->fallback.broadcast_event - }; - - /* Avoid race conditions. */ - EnterCriticalSection(&cond->fallback.waiters_count_lock); - cond->fallback.waiters_count++; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - /* It's ok to release the <mutex> here since Win32 manual-reset events */ - /* maintain state when used with <SetEvent>. This avoids the "lost wakeup" */ - /* bug. */ - uv_mutex_unlock(mutex); - - /* Wait for either event to become signaled due to <uv_cond_signal> being */ - /* called or <uv_cond_broadcast> being called. */ - result = WaitForMultipleObjects(2, handles, FALSE, dwMilliseconds); - - EnterCriticalSection(&cond->fallback.waiters_count_lock); - cond->fallback.waiters_count--; - last_waiter = result == WAIT_OBJECT_0 + 1 - && cond->fallback.waiters_count == 0; - LeaveCriticalSection(&cond->fallback.waiters_count_lock); - - /* Some thread called <pthread_cond_broadcast>. */ - if (last_waiter) { - /* We're the last waiter to be notified or to stop waiting, so reset the */ - /* the manual-reset event. */ - ResetEvent(cond->fallback.broadcast_event); - } - - /* Reacquire the <mutex>. */ - uv_mutex_lock(mutex); - - if (result == WAIT_OBJECT_0 || result == WAIT_OBJECT_0 + 1) - return 0; - - if (result == WAIT_TIMEOUT) - return UV_ETIMEDOUT; - - abort(); - return -1; /* Satisfy the compiler. */ -} - - -static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (uv_cond_wait_helper(cond, mutex, INFINITE)) - abort(); -} - - -static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (!pSleepConditionVariableCS(&cond->cond_var, mutex, INFINITE)) - abort(); -} - - -void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) { - if (HAVE_CONDVAR_API()) - uv_cond_condvar_wait(cond, mutex); - else - uv_cond_fallback_wait(cond, mutex); -} - - -static int uv_cond_fallback_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout) { - return uv_cond_wait_helper(cond, mutex, (DWORD)(timeout / 1e6)); -} - - -static int uv_cond_condvar_timedwait(uv_cond_t* cond, - uv_mutex_t* mutex, uint64_t timeout) { - if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6))) - return 0; - if (GetLastError() != ERROR_TIMEOUT) - abort(); - return UV_ETIMEDOUT; -} - - -int uv_cond_timedwait(uv_cond_t* cond, uv_mutex_t* mutex, - uint64_t timeout) { - if (HAVE_CONDVAR_API()) - return uv_cond_condvar_timedwait(cond, mutex, timeout); - else - return uv_cond_fallback_timedwait(cond, mutex, timeout); -} - - -int uv_barrier_init(uv_barrier_t* barrier, unsigned int count) { - int err; - - barrier->n = count; - barrier->count = 0; - - err = uv_mutex_init(&barrier->mutex); - if (err) - return err; - - err = uv_sem_init(&barrier->turnstile1, 0); - if (err) - goto error2; - - err = uv_sem_init(&barrier->turnstile2, 1); - if (err) - goto error; - - return 0; - -error: - uv_sem_destroy(&barrier->turnstile1); -error2: - uv_mutex_destroy(&barrier->mutex); - return err; - -} - - -void uv_barrier_destroy(uv_barrier_t* barrier) { - uv_sem_destroy(&barrier->turnstile2); - uv_sem_destroy(&barrier->turnstile1); - uv_mutex_destroy(&barrier->mutex); -} - - -int uv_barrier_wait(uv_barrier_t* barrier) { - int serial_thread; - - uv_mutex_lock(&barrier->mutex); - if (++barrier->count == barrier->n) { - uv_sem_wait(&barrier->turnstile2); - uv_sem_post(&barrier->turnstile1); - } - uv_mutex_unlock(&barrier->mutex); - - uv_sem_wait(&barrier->turnstile1); - uv_sem_post(&barrier->turnstile1); - - uv_mutex_lock(&barrier->mutex); - serial_thread = (--barrier->count == 0); - if (serial_thread) { - uv_sem_wait(&barrier->turnstile1); - uv_sem_post(&barrier->turnstile2); - } - uv_mutex_unlock(&barrier->mutex); - - uv_sem_wait(&barrier->turnstile2); - uv_sem_post(&barrier->turnstile2); - return serial_thread; -} - - -int uv_key_create(uv_key_t* key) { - key->tls_index = TlsAlloc(); - if (key->tls_index == TLS_OUT_OF_INDEXES) - return UV_ENOMEM; - return 0; -} - - -void uv_key_delete(uv_key_t* key) { - if (TlsFree(key->tls_index) == FALSE) - abort(); - key->tls_index = TLS_OUT_OF_INDEXES; -} - - -void* uv_key_get(uv_key_t* key) { - void* value; - - value = TlsGetValue(key->tls_index); - if (value == NULL) - if (GetLastError() != ERROR_SUCCESS) - abort(); - - return value; -} - - -void uv_key_set(uv_key_t* key, void* value) { - if (TlsSetValue(key->tls_index, value) == FALSE) - abort(); -} diff --git a/3rdparty/libuv/src/win/timer.c b/3rdparty/libuv/src/win/timer.c deleted file mode 100644 index 27ca7716af6..00000000000 --- a/3rdparty/libuv/src/win/timer.c +++ /dev/null @@ -1,195 +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. - */ - -#include <assert.h> -#include <limits.h> - -#include "uv.h" -#include "internal.h" -#include "tree.h" -#include "handle-inl.h" - - -/* The number of milliseconds in one second. */ -#define UV__MILLISEC 1000 - - -void uv_update_time(uv_loop_t* loop) { - uint64_t new_time = uv__hrtime(UV__MILLISEC); - assert(new_time >= loop->time); - loop->time = new_time; -} - - -static int uv_timer_compare(uv_timer_t* a, uv_timer_t* b) { - if (a->due < b->due) - return -1; - if (a->due > b->due) - return 1; - /* - * compare start_id when both has the same due. start_id is - * allocated with loop->timer_counter in uv_timer_start(). - */ - if (a->start_id < b->start_id) - return -1; - if (a->start_id > b->start_id) - return 1; - return 0; -} - - -RB_GENERATE_STATIC(uv_timer_tree_s, uv_timer_s, tree_entry, uv_timer_compare); - - -int uv_timer_init(uv_loop_t* loop, uv_timer_t* handle) { - uv__handle_init(loop, (uv_handle_t*) handle, UV_TIMER); - handle->timer_cb = NULL; - handle->repeat = 0; - - return 0; -} - - -void uv_timer_endgame(uv_loop_t* loop, uv_timer_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -static uint64_t get_clamped_due_time(uint64_t loop_time, uint64_t timeout) { - uint64_t clamped_timeout; - - clamped_timeout = loop_time + timeout; - if (clamped_timeout < timeout) - clamped_timeout = (uint64_t) -1; - - return clamped_timeout; -} - - -int uv_timer_start(uv_timer_t* handle, uv_timer_cb timer_cb, uint64_t timeout, - uint64_t repeat) { - uv_loop_t* loop = handle->loop; - uv_timer_t* old; - - if (timer_cb == NULL) - return UV_EINVAL; - - if (uv__is_active(handle)) - uv_timer_stop(handle); - - handle->timer_cb = timer_cb; - handle->due = get_clamped_due_time(loop->time, timeout); - handle->repeat = repeat; - uv__handle_start(handle); - - /* start_id is the second index to be compared in uv__timer_cmp() */ - handle->start_id = handle->loop->timer_counter++; - - old = RB_INSERT(uv_timer_tree_s, &loop->timers, handle); - assert(old == NULL); - - return 0; -} - - -int uv_timer_stop(uv_timer_t* handle) { - uv_loop_t* loop = handle->loop; - - if (!uv__is_active(handle)) - return 0; - - RB_REMOVE(uv_timer_tree_s, &loop->timers, handle); - uv__handle_stop(handle); - - return 0; -} - - -int uv_timer_again(uv_timer_t* handle) { - /* If timer_cb is NULL that means that the timer was never started. */ - if (!handle->timer_cb) { - return UV_EINVAL; - } - - if (handle->repeat) { - uv_timer_stop(handle); - uv_timer_start(handle, handle->timer_cb, handle->repeat, handle->repeat); - } - - return 0; -} - - -void uv_timer_set_repeat(uv_timer_t* handle, uint64_t repeat) { - assert(handle->type == UV_TIMER); - handle->repeat = repeat; -} - - -uint64_t uv_timer_get_repeat(const uv_timer_t* handle) { - assert(handle->type == UV_TIMER); - return handle->repeat; -} - - -DWORD uv__next_timeout(const uv_loop_t* loop) { - uv_timer_t* timer; - int64_t delta; - - /* Check if there are any running timers - * Need to cast away const first, since RB_MIN doesn't know what we are - * going to do with this return value, it can't be marked const - */ - timer = RB_MIN(uv_timer_tree_s, &((uv_loop_t*)loop)->timers); - if (timer) { - delta = timer->due - loop->time; - if (delta >= UINT_MAX - 1) { - /* A timeout value of UINT_MAX means infinite, so that's no good. */ - return UINT_MAX - 1; - } else if (delta < 0) { - /* Negative timeout values are not allowed */ - return 0; - } else { - return (DWORD)delta; - } - } else { - /* No timers */ - return INFINITE; - } -} - - -void uv_process_timers(uv_loop_t* loop) { - uv_timer_t* timer; - - /* Call timer callbacks */ - for (timer = RB_MIN(uv_timer_tree_s, &loop->timers); - timer != NULL && timer->due <= loop->time; - timer = RB_MIN(uv_timer_tree_s, &loop->timers)) { - - uv_timer_stop(timer); - uv_timer_again(timer); - timer->timer_cb((uv_timer_t*) timer); - } -} diff --git a/3rdparty/libuv/src/win/tty.c b/3rdparty/libuv/src/win/tty.c deleted file mode 100644 index 1b27f60a6f0..00000000000 --- a/3rdparty/libuv/src/win/tty.c +++ /dev/null @@ -1,2081 +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. - */ - -#include <assert.h> -#include <io.h> -#include <string.h> -#include <stdlib.h> - -#if defined(_MSC_VER) && _MSC_VER < 1600 -# include "stdint-msvc2008.h" -#else -# include <stdint.h> -#endif - -#ifndef COMMON_LVB_REVERSE_VIDEO -# define COMMON_LVB_REVERSE_VIDEO 0x4000 -#endif - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - - -#define UNICODE_REPLACEMENT_CHARACTER (0xfffd) - -#define ANSI_NORMAL 0x00 -#define ANSI_ESCAPE_SEEN 0x02 -#define ANSI_CSI 0x04 -#define ANSI_ST_CONTROL 0x08 -#define ANSI_IGNORE 0x10 -#define ANSI_IN_ARG 0x20 -#define ANSI_IN_STRING 0x40 -#define ANSI_BACKSLASH_SEEN 0x80 - -#define MAX_INPUT_BUFFER_LENGTH 8192 - - -static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info); -static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info); - - -/* Null uv_buf_t */ -static const uv_buf_t uv_null_buf_ = { 0, NULL }; - - -/* - * The console virtual window. - * - * Normally cursor movement in windows is relative to the console screen buffer, - * e.g. the application is allowed to overwrite the 'history'. This is very - * inconvenient, it makes absolute cursor movement pretty useless. There is - * also the concept of 'client rect' which is defined by the actual size of - * the console window and the scroll position of the screen buffer, but it's - * very volatile because it changes when the user scrolls. - * - * To make cursor movement behave sensibly we define a virtual window to which - * cursor movement is confined. The virtual window is always as wide as the - * console screen buffer, but it's height is defined by the size of the - * console window. The top of the virtual window aligns with the position - * of the caret when the first stdout/err handle is created, unless that would - * mean that it would extend beyond the bottom of the screen buffer - in that - * that case it's located as far down as possible. - * - * When the user writes a long text or many newlines, such that the output - * reaches beyond the bottom of the virtual window, the virtual window is - * shifted downwards, but not resized. - * - * Since all tty i/o happens on the same console, this window is shared - * between all stdout/stderr handles. - */ - -static int uv_tty_virtual_offset = -1; -static int uv_tty_virtual_height = -1; -static int uv_tty_virtual_width = -1; - -static CRITICAL_SECTION uv_tty_output_lock; - -static HANDLE uv_tty_output_handle = INVALID_HANDLE_VALUE; - -static WORD uv_tty_default_text_attributes = - FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - -static char uv_tty_default_fg_color = 7; -static char uv_tty_default_bg_color = 0; -static char uv_tty_default_fg_bright = 0; -static char uv_tty_default_bg_bright = 0; -static char uv_tty_default_inverse = 0; - - -void uv_console_init() { - InitializeCriticalSection(&uv_tty_output_lock); -} - - -int uv_tty_init(uv_loop_t* loop, uv_tty_t* tty, uv_file fd, int readable) { - HANDLE handle; - CONSOLE_SCREEN_BUFFER_INFO screen_buffer_info; - - handle = (HANDLE) uv__get_osfhandle(fd); - if (handle == INVALID_HANDLE_VALUE) - return UV_EBADF; - - if (fd <= 2) { - /* In order to avoid closing a stdio file descriptor 0-2, duplicate the - * underlying OS handle and forget about the original fd. - * We could also opt to use the original OS handle and just never close it, - * but then there would be no reliable way to cancel pending read operations - * upon close. - */ - if (!DuplicateHandle(INVALID_HANDLE_VALUE, - handle, - INVALID_HANDLE_VALUE, - &handle, - 0, - FALSE, - DUPLICATE_SAME_ACCESS)) - return uv_translate_sys_error(GetLastError()); - fd = -1; - } - - if (!readable) { - /* Obtain the screen buffer info with the output handle. */ - if (!GetConsoleScreenBufferInfo(handle, &screen_buffer_info)) { - return uv_translate_sys_error(GetLastError()); - } - - /* Obtain the the tty_output_lock because the virtual window state is */ - /* shared between all uv_tty_t handles. */ - EnterCriticalSection(&uv_tty_output_lock); - - /* Store the global tty output handle. This handle is used by TTY read */ - /* streams to update the virtual window when a CONSOLE_BUFFER_SIZE_EVENT */ - /* is received. */ - uv_tty_output_handle = handle; - - /* Remember the original console text attributes. */ - uv_tty_capture_initial_style(&screen_buffer_info); - - uv_tty_update_virtual_window(&screen_buffer_info); - - LeaveCriticalSection(&uv_tty_output_lock); - } - - - uv_stream_init(loop, (uv_stream_t*) tty, UV_TTY); - uv_connection_init((uv_stream_t*) tty); - - tty->handle = handle; - tty->u.fd = fd; - tty->reqs_pending = 0; - tty->flags |= UV_HANDLE_BOUND; - - if (readable) { - /* Initialize TTY input specific fields. */ - tty->flags |= UV_HANDLE_TTY_READABLE | UV_HANDLE_READABLE; - tty->tty.rd.read_line_handle = NULL; - tty->tty.rd.read_line_buffer = uv_null_buf_; - tty->tty.rd.read_raw_wait = NULL; - - /* Init keycode-to-vt100 mapper state. */ - tty->tty.rd.last_key_len = 0; - tty->tty.rd.last_key_offset = 0; - tty->tty.rd.last_utf16_high_surrogate = 0; - memset(&tty->tty.rd.last_input_record, 0, sizeof tty->tty.rd.last_input_record); - } else { - /* TTY output specific fields. */ - tty->flags |= UV_HANDLE_WRITABLE; - - /* Init utf8-to-utf16 conversion state. */ - tty->tty.wr.utf8_bytes_left = 0; - tty->tty.wr.utf8_codepoint = 0; - - /* Initialize eol conversion state */ - tty->tty.wr.previous_eol = 0; - - /* Init ANSI parser state. */ - tty->tty.wr.ansi_parser_state = ANSI_NORMAL; - } - - return 0; -} - - -/* Set the default console text attributes based on how the console was - * configured when libuv started. - */ -static void uv_tty_capture_initial_style(CONSOLE_SCREEN_BUFFER_INFO* info) { - static int style_captured = 0; - - /* Only do this once. - Assumption: Caller has acquired uv_tty_output_lock. */ - if (style_captured) - return; - - /* Save raw win32 attributes. */ - uv_tty_default_text_attributes = info->wAttributes; - - /* Convert black text on black background to use white text. */ - if (uv_tty_default_text_attributes == 0) - uv_tty_default_text_attributes = 7; - - /* Convert Win32 attributes to ANSI colors. */ - uv_tty_default_fg_color = 0; - uv_tty_default_bg_color = 0; - uv_tty_default_fg_bright = 0; - uv_tty_default_bg_bright = 0; - uv_tty_default_inverse = 0; - - if (uv_tty_default_text_attributes & FOREGROUND_RED) - uv_tty_default_fg_color |= 1; - - if (uv_tty_default_text_attributes & FOREGROUND_GREEN) - uv_tty_default_fg_color |= 2; - - if (uv_tty_default_text_attributes & FOREGROUND_BLUE) - uv_tty_default_fg_color |= 4; - - if (uv_tty_default_text_attributes & BACKGROUND_RED) - uv_tty_default_bg_color |= 1; - - if (uv_tty_default_text_attributes & BACKGROUND_GREEN) - uv_tty_default_bg_color |= 2; - - if (uv_tty_default_text_attributes & BACKGROUND_BLUE) - uv_tty_default_bg_color |= 4; - - if (uv_tty_default_text_attributes & FOREGROUND_INTENSITY) - uv_tty_default_fg_bright = 1; - - if (uv_tty_default_text_attributes & BACKGROUND_INTENSITY) - uv_tty_default_bg_bright = 1; - - if (uv_tty_default_text_attributes & COMMON_LVB_REVERSE_VIDEO) - uv_tty_default_inverse = 1; - - style_captured = 1; -} - - -int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) { - DWORD flags; - unsigned char was_reading; - uv_alloc_cb alloc_cb; - uv_read_cb read_cb; - int err; - - if (!(tty->flags & UV_HANDLE_TTY_READABLE)) { - return UV_EINVAL; - } - - if (!!mode == !!(tty->flags & UV_HANDLE_TTY_RAW)) { - return 0; - } - - switch (mode) { - case UV_TTY_MODE_NORMAL: - flags = ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; - break; - case UV_TTY_MODE_RAW: - flags = ENABLE_WINDOW_INPUT; - break; - case UV_TTY_MODE_IO: - return UV_ENOTSUP; - } - - if (!SetConsoleMode(tty->handle, flags)) { - return uv_translate_sys_error(GetLastError()); - } - - /* If currently reading, stop, and restart reading. */ - if (tty->flags & UV_HANDLE_READING) { - was_reading = 1; - alloc_cb = tty->alloc_cb; - read_cb = tty->read_cb; - err = uv_tty_read_stop(tty); - if (err) { - return uv_translate_sys_error(err); - } - } else { - was_reading = 0; - } - - /* Update flag. */ - tty->flags &= ~UV_HANDLE_TTY_RAW; - tty->flags |= mode ? UV_HANDLE_TTY_RAW : 0; - - /* If we just stopped reading, restart. */ - if (was_reading) { - err = uv_tty_read_start(tty, alloc_cb, read_cb); - if (err) { - return uv_translate_sys_error(err); - } - } - - return 0; -} - - -int uv_is_tty(uv_file file) { - DWORD result; - return GetConsoleMode((HANDLE) _get_osfhandle(file), &result) != 0; -} - - -int uv_tty_get_winsize(uv_tty_t* tty, int* width, int* height) { - CONSOLE_SCREEN_BUFFER_INFO info; - - if (!GetConsoleScreenBufferInfo(tty->handle, &info)) { - return uv_translate_sys_error(GetLastError()); - } - - EnterCriticalSection(&uv_tty_output_lock); - uv_tty_update_virtual_window(&info); - LeaveCriticalSection(&uv_tty_output_lock); - - *width = uv_tty_virtual_width; - *height = uv_tty_virtual_height; - - return 0; -} - - -static void CALLBACK uv_tty_post_raw_read(void* data, BOOLEAN didTimeout) { - uv_loop_t* loop; - uv_tty_t* handle; - uv_req_t* req; - - assert(data); - assert(!didTimeout); - - req = (uv_req_t*) data; - handle = (uv_tty_t*) req->data; - loop = handle->loop; - - UnregisterWait(handle->tty.rd.read_raw_wait); - handle->tty.rd.read_raw_wait = NULL; - - SET_REQ_SUCCESS(req); - POST_COMPLETION_FOR_REQ(loop, req); -} - - -static void uv_tty_queue_read_raw(uv_loop_t* loop, uv_tty_t* handle) { - uv_read_t* req; - BOOL r; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); - - handle->tty.rd.read_line_buffer = uv_null_buf_; - - req = &handle->read_req; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - r = RegisterWaitForSingleObject(&handle->tty.rd.read_raw_wait, - handle->handle, - uv_tty_post_raw_read, - (void*) req, - INFINITE, - WT_EXECUTEINWAITTHREAD | WT_EXECUTEONLYONCE); - if (!r) { - handle->tty.rd.read_raw_wait = NULL; - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; -} - - -static DWORD CALLBACK uv_tty_line_read_thread(void* data) { - uv_loop_t* loop; - uv_tty_t* handle; - uv_req_t* req; - DWORD bytes, read_bytes; - WCHAR utf16[MAX_INPUT_BUFFER_LENGTH / 3]; - DWORD chars, read_chars; - - assert(data); - - req = (uv_req_t*) data; - handle = (uv_tty_t*) req->data; - loop = handle->loop; - - assert(handle->tty.rd.read_line_buffer.base != NULL); - assert(handle->tty.rd.read_line_buffer.len > 0); - - /* ReadConsole can't handle big buffers. */ - if (handle->tty.rd.read_line_buffer.len < MAX_INPUT_BUFFER_LENGTH) { - bytes = handle->tty.rd.read_line_buffer.len; - } else { - bytes = MAX_INPUT_BUFFER_LENGTH; - } - - /* At last, unicode! */ - /* One utf-16 codeunit never takes more than 3 utf-8 codeunits to encode */ - chars = bytes / 3; - - if (ReadConsoleW(handle->tty.rd.read_line_handle, - (void*) utf16, - chars, - &read_chars, - NULL)) { - read_bytes = WideCharToMultiByte(CP_UTF8, - 0, - utf16, - read_chars, - handle->tty.rd.read_line_buffer.base, - bytes, - NULL, - NULL); - SET_REQ_SUCCESS(req); - req->u.io.overlapped.InternalHigh = read_bytes; - } else { - SET_REQ_ERROR(req, GetLastError()); - } - - POST_COMPLETION_FOR_REQ(loop, req); - return 0; -} - - -static void uv_tty_queue_read_line(uv_loop_t* loop, uv_tty_t* handle) { - uv_read_t* req; - BOOL r; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - assert(handle->handle && handle->handle != INVALID_HANDLE_VALUE); - - req = &handle->read_req; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - handle->alloc_cb((uv_handle_t*) handle, 8192, &handle->tty.rd.read_line_buffer); - if (handle->tty.rd.read_line_buffer.len == 0) { - handle->read_cb((uv_stream_t*) handle, - UV_ENOBUFS, - &handle->tty.rd.read_line_buffer); - return; - } - assert(handle->tty.rd.read_line_buffer.base != NULL); - - /* Duplicate the console handle, so if we want to cancel the read, we can */ - /* just close this handle duplicate. */ - if (handle->tty.rd.read_line_handle == NULL) { - HANDLE this_process = GetCurrentProcess(); - r = DuplicateHandle(this_process, - handle->handle, - this_process, - &handle->tty.rd.read_line_handle, - 0, - 0, - DUPLICATE_SAME_ACCESS); - if (!r) { - handle->tty.rd.read_line_handle = NULL; - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - goto out; - } - } - - r = QueueUserWorkItem(uv_tty_line_read_thread, - (void*) req, - WT_EXECUTELONGFUNCTION); - if (!r) { - SET_REQ_ERROR(req, GetLastError()); - uv_insert_pending_req(loop, (uv_req_t*)req); - } - - out: - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; -} - - -static void uv_tty_queue_read(uv_loop_t* loop, uv_tty_t* handle) { - if (handle->flags & UV_HANDLE_TTY_RAW) { - uv_tty_queue_read_raw(loop, handle); - } else { - uv_tty_queue_read_line(loop, handle); - } -} - - -static const char* get_vt100_fn_key(DWORD code, char shift, char ctrl, - size_t* len) { -#define VK_CASE(vk, normal_str, shift_str, ctrl_str, shift_ctrl_str) \ - case (vk): \ - if (shift && ctrl) { \ - *len = sizeof shift_ctrl_str; \ - return "\033" shift_ctrl_str; \ - } else if (shift) { \ - *len = sizeof shift_str ; \ - return "\033" shift_str; \ - } else if (ctrl) { \ - *len = sizeof ctrl_str; \ - return "\033" ctrl_str; \ - } else { \ - *len = sizeof normal_str; \ - return "\033" normal_str; \ - } - - switch (code) { - /* These mappings are the same as Cygwin's. Unmodified and alt-modified */ - /* keypad keys comply with linux console, modifiers comply with xterm */ - /* modifier usage. F1..f12 and shift-f1..f10 comply with linux console, */ - /* f6..f12 with and without modifiers comply with rxvt. */ - VK_CASE(VK_INSERT, "[2~", "[2;2~", "[2;5~", "[2;6~") - VK_CASE(VK_END, "[4~", "[4;2~", "[4;5~", "[4;6~") - VK_CASE(VK_DOWN, "[B", "[1;2B", "[1;5B", "[1;6B") - VK_CASE(VK_NEXT, "[6~", "[6;2~", "[6;5~", "[6;6~") - VK_CASE(VK_LEFT, "[D", "[1;2D", "[1;5D", "[1;6D") - VK_CASE(VK_CLEAR, "[G", "[1;2G", "[1;5G", "[1;6G") - VK_CASE(VK_RIGHT, "[C", "[1;2C", "[1;5C", "[1;6C") - VK_CASE(VK_UP, "[A", "[1;2A", "[1;5A", "[1;6A") - VK_CASE(VK_HOME, "[1~", "[1;2~", "[1;5~", "[1;6~") - VK_CASE(VK_PRIOR, "[5~", "[5;2~", "[5;5~", "[5;6~") - VK_CASE(VK_DELETE, "[3~", "[3;2~", "[3;5~", "[3;6~") - VK_CASE(VK_NUMPAD0, "[2~", "[2;2~", "[2;5~", "[2;6~") - VK_CASE(VK_NUMPAD1, "[4~", "[4;2~", "[4;5~", "[4;6~") - VK_CASE(VK_NUMPAD2, "[B", "[1;2B", "[1;5B", "[1;6B") - VK_CASE(VK_NUMPAD3, "[6~", "[6;2~", "[6;5~", "[6;6~") - VK_CASE(VK_NUMPAD4, "[D", "[1;2D", "[1;5D", "[1;6D") - VK_CASE(VK_NUMPAD5, "[G", "[1;2G", "[1;5G", "[1;6G") - VK_CASE(VK_NUMPAD6, "[C", "[1;2C", "[1;5C", "[1;6C") - VK_CASE(VK_NUMPAD7, "[A", "[1;2A", "[1;5A", "[1;6A") - VK_CASE(VK_NUMPAD8, "[1~", "[1;2~", "[1;5~", "[1;6~") - VK_CASE(VK_NUMPAD9, "[5~", "[5;2~", "[5;5~", "[5;6~") - VK_CASE(VK_DECIMAL, "[3~", "[3;2~", "[3;5~", "[3;6~") - VK_CASE(VK_F1, "[[A", "[23~", "[11^", "[23^" ) - VK_CASE(VK_F2, "[[B", "[24~", "[12^", "[24^" ) - VK_CASE(VK_F3, "[[C", "[25~", "[13^", "[25^" ) - VK_CASE(VK_F4, "[[D", "[26~", "[14^", "[26^" ) - VK_CASE(VK_F5, "[[E", "[28~", "[15^", "[28^" ) - VK_CASE(VK_F6, "[17~", "[29~", "[17^", "[29^" ) - VK_CASE(VK_F7, "[18~", "[31~", "[18^", "[31^" ) - VK_CASE(VK_F8, "[19~", "[32~", "[19^", "[32^" ) - VK_CASE(VK_F9, "[20~", "[33~", "[20^", "[33^" ) - VK_CASE(VK_F10, "[21~", "[34~", "[21^", "[34^" ) - VK_CASE(VK_F11, "[23~", "[23$", "[23^", "[23@" ) - VK_CASE(VK_F12, "[24~", "[24$", "[24^", "[24@" ) - - default: - *len = 0; - return NULL; - } -#undef VK_CASE -} - - -void uv_process_tty_read_raw_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req) { - /* Shortcut for handle->tty.rd.last_input_record.Event.KeyEvent. */ -#define KEV handle->tty.rd.last_input_record.Event.KeyEvent - - DWORD records_left, records_read; - uv_buf_t buf; - off_t buf_used; - - assert(handle->type == UV_TTY); - assert(handle->flags & UV_HANDLE_TTY_READABLE); - handle->flags &= ~UV_HANDLE_READ_PENDING; - - if (!(handle->flags & UV_HANDLE_READING) || - !(handle->flags & UV_HANDLE_TTY_RAW)) { - goto out; - } - - if (!REQ_SUCCESS(req)) { - /* An error occurred while waiting for the event. */ - if ((handle->flags & UV_HANDLE_READING)) { - handle->flags &= ~UV_HANDLE_READING; - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(GET_REQ_ERROR(req)), - &uv_null_buf_); - } - goto out; - } - - /* Fetch the number of events */ - if (!GetNumberOfConsoleInputEvents(handle->handle, &records_left)) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*)handle, - uv_translate_sys_error(GetLastError()), - &uv_null_buf_); - goto out; - } - - /* Windows sends a lot of events that we're not interested in, so buf */ - /* will be allocated on demand, when there's actually something to emit. */ - buf = uv_null_buf_; - buf_used = 0; - - while ((records_left > 0 || handle->tty.rd.last_key_len > 0) && - (handle->flags & UV_HANDLE_READING)) { - if (handle->tty.rd.last_key_len == 0) { - /* Read the next input record */ - if (!ReadConsoleInputW(handle->handle, - &handle->tty.rd.last_input_record, - 1, - &records_read)) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*) handle, - uv_translate_sys_error(GetLastError()), - &buf); - goto out; - } - records_left--; - - /* If the window was resized, recompute the virtual window size. This */ - /* will trigger a SIGWINCH signal if the window size changed in an */ - /* way that matters to libuv. */ - if (handle->tty.rd.last_input_record.EventType == WINDOW_BUFFER_SIZE_EVENT) { - CONSOLE_SCREEN_BUFFER_INFO info; - - EnterCriticalSection(&uv_tty_output_lock); - - if (uv_tty_output_handle != INVALID_HANDLE_VALUE && - GetConsoleScreenBufferInfo(uv_tty_output_handle, &info)) { - uv_tty_update_virtual_window(&info); - } - - LeaveCriticalSection(&uv_tty_output_lock); - - continue; - } - - /* Ignore other events that are not key or resize events. */ - if (handle->tty.rd.last_input_record.EventType != KEY_EVENT) { - continue; - } - - /* Ignore keyup events, unless the left alt key was held and a valid */ - /* unicode character was emitted. */ - if (!KEV.bKeyDown && !(((KEV.dwControlKeyState & LEFT_ALT_PRESSED) || - KEV.wVirtualKeyCode==VK_MENU) && KEV.uChar.UnicodeChar != 0)) { - continue; - } - - /* Ignore keypresses to numpad number keys if the left alt is held */ - /* because the user is composing a character, or windows simulating */ - /* this. */ - if ((KEV.dwControlKeyState & LEFT_ALT_PRESSED) && - !(KEV.dwControlKeyState & ENHANCED_KEY) && - (KEV.wVirtualKeyCode == VK_INSERT || - KEV.wVirtualKeyCode == VK_END || - KEV.wVirtualKeyCode == VK_DOWN || - KEV.wVirtualKeyCode == VK_NEXT || - KEV.wVirtualKeyCode == VK_LEFT || - KEV.wVirtualKeyCode == VK_CLEAR || - KEV.wVirtualKeyCode == VK_RIGHT || - KEV.wVirtualKeyCode == VK_HOME || - KEV.wVirtualKeyCode == VK_UP || - KEV.wVirtualKeyCode == VK_PRIOR || - KEV.wVirtualKeyCode == VK_NUMPAD0 || - KEV.wVirtualKeyCode == VK_NUMPAD1 || - KEV.wVirtualKeyCode == VK_NUMPAD2 || - KEV.wVirtualKeyCode == VK_NUMPAD3 || - KEV.wVirtualKeyCode == VK_NUMPAD4 || - KEV.wVirtualKeyCode == VK_NUMPAD5 || - KEV.wVirtualKeyCode == VK_NUMPAD6 || - KEV.wVirtualKeyCode == VK_NUMPAD7 || - KEV.wVirtualKeyCode == VK_NUMPAD8 || - KEV.wVirtualKeyCode == VK_NUMPAD9)) { - continue; - } - - if (KEV.uChar.UnicodeChar != 0) { - int prefix_len, char_len; - - /* Character key pressed */ - if (KEV.uChar.UnicodeChar >= 0xD800 && - KEV.uChar.UnicodeChar < 0xDC00) { - /* UTF-16 high surrogate */ - handle->tty.rd.last_utf16_high_surrogate = KEV.uChar.UnicodeChar; - continue; - } - - /* Prefix with \u033 if alt was held, but alt was not used as part */ - /* a compose sequence. */ - if ((KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) - && !(KEV.dwControlKeyState & (LEFT_CTRL_PRESSED | - RIGHT_CTRL_PRESSED)) && KEV.bKeyDown) { - handle->tty.rd.last_key[0] = '\033'; - prefix_len = 1; - } else { - prefix_len = 0; - } - - if (KEV.uChar.UnicodeChar >= 0xDC00 && - KEV.uChar.UnicodeChar < 0xE000) { - /* UTF-16 surrogate pair */ - WCHAR utf16_buffer[2] = { handle->tty.rd.last_utf16_high_surrogate, - KEV.uChar.UnicodeChar}; - char_len = WideCharToMultiByte(CP_UTF8, - 0, - utf16_buffer, - 2, - &handle->tty.rd.last_key[prefix_len], - sizeof handle->tty.rd.last_key, - NULL, - NULL); - } else { - /* Single UTF-16 character */ - char_len = WideCharToMultiByte(CP_UTF8, - 0, - &KEV.uChar.UnicodeChar, - 1, - &handle->tty.rd.last_key[prefix_len], - sizeof handle->tty.rd.last_key, - NULL, - NULL); - } - - /* Whatever happened, the last character wasn't a high surrogate. */ - handle->tty.rd.last_utf16_high_surrogate = 0; - - /* If the utf16 character(s) couldn't be converted something must */ - /* be wrong. */ - if (!char_len) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*) handle, - uv_translate_sys_error(GetLastError()), - &buf); - goto out; - } - - handle->tty.rd.last_key_len = (unsigned char) (prefix_len + char_len); - handle->tty.rd.last_key_offset = 0; - continue; - - } else { - /* Function key pressed */ - const char* vt100; - size_t prefix_len, vt100_len; - - vt100 = get_vt100_fn_key(KEV.wVirtualKeyCode, - !!(KEV.dwControlKeyState & SHIFT_PRESSED), - !!(KEV.dwControlKeyState & ( - LEFT_CTRL_PRESSED | - RIGHT_CTRL_PRESSED)), - &vt100_len); - - /* If we were unable to map to a vt100 sequence, just ignore. */ - if (!vt100) { - continue; - } - - /* Prefix with \x033 when the alt key was held. */ - if (KEV.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED)) { - handle->tty.rd.last_key[0] = '\033'; - prefix_len = 1; - } else { - prefix_len = 0; - } - - /* Copy the vt100 sequence to the handle buffer. */ - assert(prefix_len + vt100_len < sizeof handle->tty.rd.last_key); - memcpy(&handle->tty.rd.last_key[prefix_len], vt100, vt100_len); - - handle->tty.rd.last_key_len = (unsigned char) (prefix_len + vt100_len); - handle->tty.rd.last_key_offset = 0; - continue; - } - } else { - /* Copy any bytes left from the last keypress to the user buffer. */ - if (handle->tty.rd.last_key_offset < handle->tty.rd.last_key_len) { - /* Allocate a buffer if needed */ - if (buf_used == 0) { - handle->alloc_cb((uv_handle_t*) handle, 1024, &buf); - if (buf.len == 0) { - handle->read_cb((uv_stream_t*) handle, UV_ENOBUFS, &buf); - goto out; - } - assert(buf.base != NULL); - } - - buf.base[buf_used++] = handle->tty.rd.last_key[handle->tty.rd.last_key_offset++]; - - /* If the buffer is full, emit it */ - if ((size_t) buf_used == buf.len) { - handle->read_cb((uv_stream_t*) handle, buf_used, &buf); - buf = uv_null_buf_; - buf_used = 0; - } - - continue; - } - - /* Apply dwRepeat from the last input record. */ - if (--KEV.wRepeatCount > 0) { - handle->tty.rd.last_key_offset = 0; - continue; - } - - handle->tty.rd.last_key_len = 0; - continue; - } - } - - /* Send the buffer back to the user */ - if (buf_used > 0) { - handle->read_cb((uv_stream_t*) handle, buf_used, &buf); - } - - out: - /* Wait for more input events. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_tty_queue_read(loop, handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); - -#undef KEV -} - - - -void uv_process_tty_read_line_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req) { - uv_buf_t buf; - - assert(handle->type == UV_TTY); - assert(handle->flags & UV_HANDLE_TTY_READABLE); - - buf = handle->tty.rd.read_line_buffer; - - handle->flags &= ~UV_HANDLE_READ_PENDING; - handle->tty.rd.read_line_buffer = uv_null_buf_; - - if (!REQ_SUCCESS(req)) { - /* Read was not successful */ - if ((handle->flags & UV_HANDLE_READING) && - handle->tty.rd.read_line_handle != NULL) { - /* Real error */ - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb((uv_stream_t*) handle, - uv_translate_sys_error(GET_REQ_ERROR(req)), - &buf); - } else { - /* The read was cancelled, or whatever we don't care */ - handle->read_cb((uv_stream_t*) handle, 0, &buf); - } - - } else { - /* Read successful */ - /* TODO: read unicode, convert to utf-8 */ - DWORD bytes = req->u.io.overlapped.InternalHigh; - handle->read_cb((uv_stream_t*) handle, bytes, &buf); - } - - /* Wait for more input events. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_tty_queue_read(loop, handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_tty_read_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* req) { - assert(handle->type == UV_TTY); - assert(handle->flags & UV_HANDLE_TTY_READABLE); - - /* If the read_line_buffer member is zero, it must have been an raw read. */ - /* Otherwise it was a line-buffered read. */ - /* FIXME: This is quite obscure. Use a flag or something. */ - if (handle->tty.rd.read_line_buffer.len == 0) { - uv_process_tty_read_raw_req(loop, handle, req); - } else { - uv_process_tty_read_line_req(loop, handle, req); - } -} - - -int uv_tty_read_start(uv_tty_t* handle, uv_alloc_cb alloc_cb, - uv_read_cb read_cb) { - uv_loop_t* loop = handle->loop; - - if (!(handle->flags & UV_HANDLE_TTY_READABLE)) { - return ERROR_INVALID_PARAMETER; - } - - handle->flags |= UV_HANDLE_READING; - INCREASE_ACTIVE_COUNT(loop, handle); - handle->read_cb = read_cb; - handle->alloc_cb = alloc_cb; - - /* If reading was stopped and then started again, there could still be a */ - /* read request pending. */ - if (handle->flags & UV_HANDLE_READ_PENDING) { - return 0; - } - - /* Maybe the user stopped reading half-way while processing key events. */ - /* Short-circuit if this could be the case. */ - if (handle->tty.rd.last_key_len > 0) { - SET_REQ_SUCCESS(&handle->read_req); - uv_insert_pending_req(handle->loop, (uv_req_t*) &handle->read_req); - return 0; - } - - uv_tty_queue_read(loop, handle); - - return 0; -} - - -int uv_tty_read_stop(uv_tty_t* handle) { - handle->flags &= ~UV_HANDLE_READING; - DECREASE_ACTIVE_COUNT(handle->loop, handle); - - /* Cancel raw read */ - if ((handle->flags & UV_HANDLE_READ_PENDING) && - (handle->flags & UV_HANDLE_TTY_RAW)) { - /* Write some bullshit event to force the console wait to return. */ - INPUT_RECORD record; - DWORD written; - memset(&record, 0, sizeof record); - if (!WriteConsoleInputW(handle->handle, &record, 1, &written)) { - return GetLastError(); - } - } - - /* Cancel line-buffered read */ - if (handle->tty.rd.read_line_handle != NULL) { - /* Closing this handle will cancel the ReadConsole operation */ - CloseHandle(handle->tty.rd.read_line_handle); - handle->tty.rd.read_line_handle = NULL; - } - - - return 0; -} - - -static void uv_tty_update_virtual_window(CONSOLE_SCREEN_BUFFER_INFO* info) { - int old_virtual_width = uv_tty_virtual_width; - int old_virtual_height = uv_tty_virtual_height; - - uv_tty_virtual_width = info->dwSize.X; - uv_tty_virtual_height = info->srWindow.Bottom - info->srWindow.Top + 1; - - /* Recompute virtual window offset row. */ - if (uv_tty_virtual_offset == -1) { - uv_tty_virtual_offset = info->dwCursorPosition.Y; - } else if (uv_tty_virtual_offset < info->dwCursorPosition.Y - - uv_tty_virtual_height + 1) { - /* If suddenly find the cursor outside of the virtual window, it must */ - /* have somehow scrolled. Update the virtual window offset. */ - uv_tty_virtual_offset = info->dwCursorPosition.Y - - uv_tty_virtual_height + 1; - } - if (uv_tty_virtual_offset + uv_tty_virtual_height > info->dwSize.Y) { - uv_tty_virtual_offset = info->dwSize.Y - uv_tty_virtual_height; - } - if (uv_tty_virtual_offset < 0) { - uv_tty_virtual_offset = 0; - } - - /* If the virtual window size changed, emit a SIGWINCH signal. Don't emit */ - /* if this was the first time the virtual window size was computed. */ - if (old_virtual_width != -1 && old_virtual_height != -1 && - (uv_tty_virtual_width != old_virtual_width || - uv_tty_virtual_height != old_virtual_height)) { - uv__signal_dispatch(SIGWINCH); - } -} - - -static COORD uv_tty_make_real_coord(uv_tty_t* handle, - CONSOLE_SCREEN_BUFFER_INFO* info, int x, unsigned char x_relative, int y, - unsigned char y_relative) { - COORD result; - - uv_tty_update_virtual_window(info); - - /* Adjust y position */ - if (y_relative) { - y = info->dwCursorPosition.Y + y; - } else { - y = uv_tty_virtual_offset + y; - } - /* Clip y to virtual client rectangle */ - if (y < uv_tty_virtual_offset) { - y = uv_tty_virtual_offset; - } else if (y >= uv_tty_virtual_offset + uv_tty_virtual_height) { - y = uv_tty_virtual_offset + uv_tty_virtual_height - 1; - } - - /* Adjust x */ - if (x_relative) { - x = info->dwCursorPosition.X + x; - } - /* Clip x */ - if (x < 0) { - x = 0; - } else if (x >= uv_tty_virtual_width) { - x = uv_tty_virtual_width - 1; - } - - result.X = (unsigned short) x; - result.Y = (unsigned short) y; - return result; -} - - -static int uv_tty_emit_text(uv_tty_t* handle, WCHAR buffer[], DWORD length, - DWORD* error) { - DWORD written; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (!WriteConsoleW(handle->handle, - (void*) buffer, - length, - &written, - NULL)) { - *error = GetLastError(); - return -1; - } - - return 0; -} - - -static int uv_tty_move_caret(uv_tty_t* handle, int x, unsigned char x_relative, - int y, unsigned char y_relative, DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - COORD pos; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - retry: - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - } - - pos = uv_tty_make_real_coord(handle, &info, x, x_relative, y, y_relative); - - if (!SetConsoleCursorPosition(handle->handle, pos)) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - /* The console may be resized - retry */ - goto retry; - } else { - *error = GetLastError(); - return -1; - } - } - - return 0; -} - - -static int uv_tty_reset(uv_tty_t* handle, DWORD* error) { - const COORD origin = {0, 0}; - const WORD char_attrs = uv_tty_default_text_attributes; - CONSOLE_SCREEN_BUFFER_INFO info; - DWORD count, written; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - /* Reset original text attributes. */ - if (!SetConsoleTextAttribute(handle->handle, char_attrs)) { - *error = GetLastError(); - return -1; - } - - /* Move the cursor position to (0, 0). */ - if (!SetConsoleCursorPosition(handle->handle, origin)) { - *error = GetLastError(); - return -1; - } - - /* Clear the screen buffer. */ - retry: - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - count = info.dwSize.X * info.dwSize.Y; - - if (!(FillConsoleOutputCharacterW(handle->handle, - L'\x20', - count, - origin, - &written) && - FillConsoleOutputAttribute(handle->handle, - char_attrs, - written, - origin, - &written))) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - /* The console may be resized - retry */ - goto retry; - } else { - *error = GetLastError(); - return -1; - } - } - - /* Move the virtual window up to the top. */ - uv_tty_virtual_offset = 0; - uv_tty_update_virtual_window(&info); - - return 0; -} - - -static int uv_tty_clear(uv_tty_t* handle, int dir, char entire_screen, - DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - COORD start, end; - DWORD count, written; - - int x1, x2, y1, y2; - int x1r, x2r, y1r, y2r; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (dir == 0) { - /* Clear from current position */ - x1 = 0; - x1r = 1; - } else { - /* Clear from column 0 */ - x1 = 0; - x1r = 0; - } - - if (dir == 1) { - /* Clear to current position */ - x2 = 0; - x2r = 1; - } else { - /* Clear to end of row. We pretend the console is 65536 characters wide, */ - /* uv_tty_make_real_coord will clip it to the actual console width. */ - x2 = 0xffff; - x2r = 0; - } - - if (!entire_screen) { - /* Stay on our own row */ - y1 = y2 = 0; - y1r = y2r = 1; - } else { - /* Apply columns direction to row */ - y1 = x1; - y1r = x1r; - y2 = x2; - y2r = x2r; - } - - retry: - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - start = uv_tty_make_real_coord(handle, &info, x1, x1r, y1, y1r); - end = uv_tty_make_real_coord(handle, &info, x2, x2r, y2, y2r); - count = (end.Y * info.dwSize.X + end.X) - - (start.Y * info.dwSize.X + start.X) + 1; - - if (!(FillConsoleOutputCharacterW(handle->handle, - L'\x20', - count, - start, - &written) && - FillConsoleOutputAttribute(handle->handle, - info.wAttributes, - written, - start, - &written))) { - if (GetLastError() == ERROR_INVALID_PARAMETER) { - /* The console may be resized - retry */ - goto retry; - } else { - *error = GetLastError(); - return -1; - } - } - - return 0; -} - -#define FLIP_FGBG \ - do { \ - WORD fg = info.wAttributes & 0xF; \ - WORD bg = info.wAttributes & 0xF0; \ - info.wAttributes &= 0xFF00; \ - info.wAttributes |= fg << 4; \ - info.wAttributes |= bg >> 4; \ - } while (0) - -static int uv_tty_set_style(uv_tty_t* handle, DWORD* error) { - unsigned short argc = handle->tty.wr.ansi_csi_argc; - unsigned short* argv = handle->tty.wr.ansi_csi_argv; - int i; - CONSOLE_SCREEN_BUFFER_INFO info; - - char fg_color = -1, bg_color = -1; - char fg_bright = -1, bg_bright = -1; - char inverse = -1; - - if (argc == 0) { - /* Reset mode */ - fg_color = uv_tty_default_fg_color; - bg_color = uv_tty_default_bg_color; - fg_bright = uv_tty_default_fg_bright; - bg_bright = uv_tty_default_bg_bright; - inverse = uv_tty_default_inverse; - } - - for (i = 0; i < argc; i++) { - short arg = argv[i]; - - if (arg == 0) { - /* Reset mode */ - fg_color = uv_tty_default_fg_color; - bg_color = uv_tty_default_bg_color; - fg_bright = uv_tty_default_fg_bright; - bg_bright = uv_tty_default_bg_bright; - inverse = uv_tty_default_inverse; - - } else if (arg == 1) { - /* Foreground bright on */ - fg_bright = 1; - - } else if (arg == 2) { - /* Both bright off */ - fg_bright = 0; - bg_bright = 0; - - } else if (arg == 5) { - /* Background bright on */ - bg_bright = 1; - - } else if (arg == 7) { - /* Inverse: on */ - inverse = 1; - - } else if (arg == 21 || arg == 22) { - /* Foreground bright off */ - fg_bright = 0; - - } else if (arg == 25) { - /* Background bright off */ - bg_bright = 0; - - } else if (arg == 27) { - /* Inverse: off */ - inverse = 0; - - } else if (arg >= 30 && arg <= 37) { - /* Set foreground color */ - fg_color = arg - 30; - - } else if (arg == 39) { - /* Default text color */ - fg_color = uv_tty_default_fg_color; - fg_bright = uv_tty_default_fg_bright; - - } else if (arg >= 40 && arg <= 47) { - /* Set background color */ - bg_color = arg - 40; - - } else if (arg == 49) { - /* Default background color */ - bg_color = uv_tty_default_bg_color; - bg_bright = uv_tty_default_bg_bright; - - } else if (arg >= 90 && arg <= 97) { - /* Set bold foreground color */ - fg_bright = 1; - fg_color = arg - 90; - - } else if (arg >= 100 && arg <= 107) { - /* Set bold background color */ - bg_bright = 1; - bg_color = arg - 100; - - } - } - - if (fg_color == -1 && bg_color == -1 && fg_bright == -1 && - bg_bright == -1 && inverse == -1) { - /* Nothing changed */ - return 0; - } - - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - if ((info.wAttributes & COMMON_LVB_REVERSE_VIDEO) > 0) { - FLIP_FGBG; - } - - if (fg_color != -1) { - info.wAttributes &= ~(FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - if (fg_color & 1) info.wAttributes |= FOREGROUND_RED; - if (fg_color & 2) info.wAttributes |= FOREGROUND_GREEN; - if (fg_color & 4) info.wAttributes |= FOREGROUND_BLUE; - } - - if (fg_bright != -1) { - if (fg_bright) { - info.wAttributes |= FOREGROUND_INTENSITY; - } else { - info.wAttributes &= ~FOREGROUND_INTENSITY; - } - } - - if (bg_color != -1) { - info.wAttributes &= ~(BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); - if (bg_color & 1) info.wAttributes |= BACKGROUND_RED; - if (bg_color & 2) info.wAttributes |= BACKGROUND_GREEN; - if (bg_color & 4) info.wAttributes |= BACKGROUND_BLUE; - } - - if (bg_bright != -1) { - if (bg_bright) { - info.wAttributes |= BACKGROUND_INTENSITY; - } else { - info.wAttributes &= ~BACKGROUND_INTENSITY; - } - } - - if (inverse != -1) { - if (inverse) { - info.wAttributes |= COMMON_LVB_REVERSE_VIDEO; - } else { - info.wAttributes &= ~COMMON_LVB_REVERSE_VIDEO; - } - } - - if ((info.wAttributes & COMMON_LVB_REVERSE_VIDEO) > 0) { - FLIP_FGBG; - } - - if (!SetConsoleTextAttribute(handle->handle, info.wAttributes)) { - *error = GetLastError(); - return -1; - } - - return 0; -} - - -static int uv_tty_save_state(uv_tty_t* handle, unsigned char save_attributes, - DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - uv_tty_update_virtual_window(&info); - - handle->tty.wr.saved_position.X = info.dwCursorPosition.X; - handle->tty.wr.saved_position.Y = info.dwCursorPosition.Y - uv_tty_virtual_offset; - handle->flags |= UV_HANDLE_TTY_SAVED_POSITION; - - if (save_attributes) { - handle->tty.wr.saved_attributes = info.wAttributes & - (FOREGROUND_INTENSITY | BACKGROUND_INTENSITY); - handle->flags |= UV_HANDLE_TTY_SAVED_ATTRIBUTES; - } - - return 0; -} - - -static int uv_tty_restore_state(uv_tty_t* handle, - unsigned char restore_attributes, DWORD* error) { - CONSOLE_SCREEN_BUFFER_INFO info; - WORD new_attributes; - - if (*error != ERROR_SUCCESS) { - return -1; - } - - if (handle->flags & UV_HANDLE_TTY_SAVED_POSITION) { - if (uv_tty_move_caret(handle, - handle->tty.wr.saved_position.X, - 0, - handle->tty.wr.saved_position.Y, - 0, - error) != 0) { - return -1; - } - } - - if (restore_attributes && - (handle->flags & UV_HANDLE_TTY_SAVED_ATTRIBUTES)) { - if (!GetConsoleScreenBufferInfo(handle->handle, &info)) { - *error = GetLastError(); - return -1; - } - - new_attributes = info.wAttributes; - new_attributes &= ~(FOREGROUND_INTENSITY | BACKGROUND_INTENSITY); - new_attributes |= handle->tty.wr.saved_attributes; - - if (!SetConsoleTextAttribute(handle->handle, new_attributes)) { - *error = GetLastError(); - return -1; - } - } - - return 0; -} - -static int uv_tty_set_cursor_visibility(uv_tty_t* handle, - BOOL visible, - DWORD* error) { - CONSOLE_CURSOR_INFO cursor_info; - - if (!GetConsoleCursorInfo(handle->handle, &cursor_info)) { - *error = GetLastError(); - return -1; - } - - cursor_info.bVisible = visible; - - if (!SetConsoleCursorInfo(handle->handle, &cursor_info)) { - *error = GetLastError(); - return -1; - } - - return 0; -} - -static int uv_tty_write_bufs(uv_tty_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - DWORD* error) { - /* We can only write 8k characters at a time. Windows can't handle */ - /* much more characters in a single console write anyway. */ - WCHAR utf16_buf[8192]; - DWORD utf16_buf_used = 0; - unsigned int i; - -#define FLUSH_TEXT() \ - do { \ - if (utf16_buf_used > 0) { \ - uv_tty_emit_text(handle, utf16_buf, utf16_buf_used, error); \ - utf16_buf_used = 0; \ - } \ - } while (0) - -#define ENSURE_BUFFER_SPACE(wchars_needed) \ - if (wchars_needed > ARRAY_SIZE(utf16_buf) - utf16_buf_used) { \ - FLUSH_TEXT(); \ - } - - /* Cache for fast access */ - unsigned char utf8_bytes_left = handle->tty.wr.utf8_bytes_left; - unsigned int utf8_codepoint = handle->tty.wr.utf8_codepoint; - unsigned char previous_eol = handle->tty.wr.previous_eol; - unsigned char ansi_parser_state = handle->tty.wr.ansi_parser_state; - - /* Store the error here. If we encounter an error, stop trying to do i/o */ - /* but keep parsing the buffer so we leave the parser in a consistent */ - /* state. */ - *error = ERROR_SUCCESS; - - EnterCriticalSection(&uv_tty_output_lock); - - for (i = 0; i < nbufs; i++) { - uv_buf_t buf = bufs[i]; - unsigned int j; - - for (j = 0; j < buf.len; j++) { - unsigned char c = buf.base[j]; - - /* Run the character through the utf8 decoder We happily accept non */ - /* shortest form encodings and invalid code points - there's no real */ - /* harm that can be done. */ - if (utf8_bytes_left == 0) { - /* Read utf-8 start byte */ - DWORD first_zero_bit; - unsigned char not_c = ~c; -#ifdef _MSC_VER /* msvc */ - if (_BitScanReverse(&first_zero_bit, not_c)) { -#else /* assume gcc */ - if (c != 0) { - first_zero_bit = (sizeof(int) * 8) - 1 - __builtin_clz(not_c); -#endif - if (first_zero_bit == 7) { - /* Ascii - pass right through */ - utf8_codepoint = (unsigned int) c; - - } else if (first_zero_bit <= 5) { - /* Multibyte sequence */ - utf8_codepoint = (0xff >> (8 - first_zero_bit)) & c; - utf8_bytes_left = (char) (6 - first_zero_bit); - - } else { - /* Invalid continuation */ - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - } - - } else { - /* 0xff -- invalid */ - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - } - - } else if ((c & 0xc0) == 0x80) { - /* Valid continuation of utf-8 multibyte sequence */ - utf8_bytes_left--; - utf8_codepoint <<= 6; - utf8_codepoint |= ((unsigned int) c & 0x3f); - - } else { - /* Start byte where continuation was expected. */ - utf8_bytes_left = 0; - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - /* Patch buf offset so this character will be parsed again as a */ - /* start byte. */ - j--; - } - - /* Maybe we need to parse more bytes to find a character. */ - if (utf8_bytes_left != 0) { - continue; - } - - /* Parse vt100/ansi escape codes */ - if (ansi_parser_state == ANSI_NORMAL) { - switch (utf8_codepoint) { - case '\033': - ansi_parser_state = ANSI_ESCAPE_SEEN; - continue; - - case 0233: - ansi_parser_state = ANSI_CSI; - handle->tty.wr.ansi_csi_argc = 0; - continue; - } - - } else if (ansi_parser_state == ANSI_ESCAPE_SEEN) { - switch (utf8_codepoint) { - case '[': - ansi_parser_state = ANSI_CSI; - handle->tty.wr.ansi_csi_argc = 0; - continue; - - case '^': - case '_': - case 'P': - case ']': - /* Not supported, but we'll have to parse until we see a stop */ - /* code, e.g. ESC \ or BEL. */ - ansi_parser_state = ANSI_ST_CONTROL; - continue; - - case '\033': - /* Ignore double escape. */ - continue; - - case 'c': - /* Full console reset. */ - FLUSH_TEXT(); - uv_tty_reset(handle, error); - ansi_parser_state = ANSI_NORMAL; - continue; - - case '7': - /* Save the cursor position and text attributes. */ - FLUSH_TEXT(); - uv_tty_save_state(handle, 1, error); - ansi_parser_state = ANSI_NORMAL; - continue; - - case '8': - /* Restore the cursor position and text attributes */ - FLUSH_TEXT(); - uv_tty_restore_state(handle, 1, error); - ansi_parser_state = ANSI_NORMAL; - continue; - - default: - if (utf8_codepoint >= '@' && utf8_codepoint <= '_') { - /* Single-char control. */ - ansi_parser_state = ANSI_NORMAL; - continue; - } else { - /* Invalid - proceed as normal, */ - ansi_parser_state = ANSI_NORMAL; - } - } - - } else if (ansi_parser_state & ANSI_CSI) { - if (!(ansi_parser_state & ANSI_IGNORE)) { - if (utf8_codepoint >= '0' && utf8_codepoint <= '9') { - /* Parsing a numerical argument */ - - if (!(ansi_parser_state & ANSI_IN_ARG)) { - /* We were not currently parsing a number */ - - /* Check for too many arguments */ - if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) { - ansi_parser_state |= ANSI_IGNORE; - continue; - } - - ansi_parser_state |= ANSI_IN_ARG; - handle->tty.wr.ansi_csi_argc++; - handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = - (unsigned short) utf8_codepoint - '0'; - continue; - } else { - /* We were already parsing a number. Parse next digit. */ - uint32_t value = 10 * - handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1]; - - /* Check for overflow. */ - if (value > UINT16_MAX) { - ansi_parser_state |= ANSI_IGNORE; - continue; - } - - handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = - (unsigned short) value + (utf8_codepoint - '0'); - continue; - } - - } else if (utf8_codepoint == ';') { - /* Denotes the end of an argument. */ - if (ansi_parser_state & ANSI_IN_ARG) { - ansi_parser_state &= ~ANSI_IN_ARG; - continue; - - } else { - /* If ANSI_IN_ARG is not set, add another argument and */ - /* default it to 0. */ - /* Check for too many arguments */ - if (handle->tty.wr.ansi_csi_argc >= ARRAY_SIZE(handle->tty.wr.ansi_csi_argv)) { - ansi_parser_state |= ANSI_IGNORE; - continue; - } - - handle->tty.wr.ansi_csi_argc++; - handle->tty.wr.ansi_csi_argv[handle->tty.wr.ansi_csi_argc - 1] = 0; - continue; - } - - } else if (utf8_codepoint == '?' && !(ansi_parser_state & ANSI_IN_ARG) && - handle->tty.wr.ansi_csi_argc == 0) { - /* Ignores '?' if it is the first character after CSI[ */ - /* This is an extension character from the VT100 codeset */ - /* that is supported and used by most ANSI terminals today. */ - continue; - - } else if (utf8_codepoint >= '@' && utf8_codepoint <= '~' && - (handle->tty.wr.ansi_csi_argc > 0 || utf8_codepoint != '[')) { - int x, y, d; - - /* Command byte */ - switch (utf8_codepoint) { - case 'A': - /* cursor up */ - FLUSH_TEXT(); - y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1); - uv_tty_move_caret(handle, 0, 1, y, 1, error); - break; - - case 'B': - /* cursor down */ - FLUSH_TEXT(); - y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1; - uv_tty_move_caret(handle, 0, 1, y, 1, error); - break; - - case 'C': - /* cursor forward */ - FLUSH_TEXT(); - x = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1; - uv_tty_move_caret(handle, x, 1, 0, 1, error); - break; - - case 'D': - /* cursor back */ - FLUSH_TEXT(); - x = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1); - uv_tty_move_caret(handle, x, 1, 0, 1, error); - break; - - case 'E': - /* cursor next line */ - FLUSH_TEXT(); - y = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1; - uv_tty_move_caret(handle, 0, 0, y, 1, error); - break; - - case 'F': - /* cursor previous line */ - FLUSH_TEXT(); - y = -(handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 1); - uv_tty_move_caret(handle, 0, 0, y, 1, error); - break; - - case 'G': - /* cursor horizontal move absolute */ - FLUSH_TEXT(); - x = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0]) - ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0; - uv_tty_move_caret(handle, x, 0, 0, 1, error); - break; - - case 'H': - case 'f': - /* cursor move absolute */ - FLUSH_TEXT(); - y = (handle->tty.wr.ansi_csi_argc >= 1 && handle->tty.wr.ansi_csi_argv[0]) - ? handle->tty.wr.ansi_csi_argv[0] - 1 : 0; - x = (handle->tty.wr.ansi_csi_argc >= 2 && handle->tty.wr.ansi_csi_argv[1]) - ? handle->tty.wr.ansi_csi_argv[1] - 1 : 0; - uv_tty_move_caret(handle, x, 0, y, 0, error); - break; - - case 'J': - /* Erase screen */ - FLUSH_TEXT(); - d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0; - if (d >= 0 && d <= 2) { - uv_tty_clear(handle, d, 1, error); - } - break; - - case 'K': - /* Erase line */ - FLUSH_TEXT(); - d = handle->tty.wr.ansi_csi_argc ? handle->tty.wr.ansi_csi_argv[0] : 0; - if (d >= 0 && d <= 2) { - uv_tty_clear(handle, d, 0, error); - } - break; - - case 'm': - /* Set style */ - FLUSH_TEXT(); - uv_tty_set_style(handle, error); - break; - - case 's': - /* Save the cursor position. */ - FLUSH_TEXT(); - uv_tty_save_state(handle, 0, error); - break; - - case 'u': - /* Restore the cursor position */ - FLUSH_TEXT(); - uv_tty_restore_state(handle, 0, error); - break; - - case 'l': - /* Hide the cursor */ - if (handle->tty.wr.ansi_csi_argc == 1 && - handle->tty.wr.ansi_csi_argv[0] == 25) { - FLUSH_TEXT(); - uv_tty_set_cursor_visibility(handle, 0, error); - } - break; - - case 'h': - /* Show the cursor */ - if (handle->tty.wr.ansi_csi_argc == 1 && - handle->tty.wr.ansi_csi_argv[0] == 25) { - FLUSH_TEXT(); - uv_tty_set_cursor_visibility(handle, 1, error); - } - break; - } - - /* Sequence ended - go back to normal state. */ - ansi_parser_state = ANSI_NORMAL; - continue; - - } else { - /* We don't support commands that use private mode characters or */ - /* intermediaries. Ignore the rest of the sequence. */ - ansi_parser_state |= ANSI_IGNORE; - continue; - } - } else { - /* We're ignoring this command. Stop only on command character. */ - if (utf8_codepoint >= '@' && utf8_codepoint <= '~') { - ansi_parser_state = ANSI_NORMAL; - } - continue; - } - - } else if (ansi_parser_state & ANSI_ST_CONTROL) { - /* Unsupported control code */ - /* Ignore everything until we see BEL or ESC \ */ - if (ansi_parser_state & ANSI_IN_STRING) { - if (!(ansi_parser_state & ANSI_BACKSLASH_SEEN)) { - if (utf8_codepoint == '"') { - ansi_parser_state &= ~ANSI_IN_STRING; - } else if (utf8_codepoint == '\\') { - ansi_parser_state |= ANSI_BACKSLASH_SEEN; - } - } else { - ansi_parser_state &= ~ANSI_BACKSLASH_SEEN; - } - } else { - if (utf8_codepoint == '\007' || (utf8_codepoint == '\\' && - (ansi_parser_state & ANSI_ESCAPE_SEEN))) { - /* End of sequence */ - ansi_parser_state = ANSI_NORMAL; - } else if (utf8_codepoint == '\033') { - /* Escape character */ - ansi_parser_state |= ANSI_ESCAPE_SEEN; - } else if (utf8_codepoint == '"') { - /* String starting */ - ansi_parser_state |= ANSI_IN_STRING; - ansi_parser_state &= ~ANSI_ESCAPE_SEEN; - ansi_parser_state &= ~ANSI_BACKSLASH_SEEN; - } else { - ansi_parser_state &= ~ANSI_ESCAPE_SEEN; - } - } - continue; - } else { - /* Inconsistent state */ - abort(); - } - - /* We wouldn't mind emitting utf-16 surrogate pairs. Too bad, the */ - /* windows console doesn't really support UTF-16, so just emit the */ - /* replacement character. */ - if (utf8_codepoint > 0xffff) { - utf8_codepoint = UNICODE_REPLACEMENT_CHARACTER; - } - - if (utf8_codepoint == 0x0a || utf8_codepoint == 0x0d) { - /* EOL conversion - emit \r\n when we see \n. */ - - if (utf8_codepoint == 0x0a && previous_eol != 0x0d) { - /* \n was not preceded by \r; print \r\n. */ - ENSURE_BUFFER_SPACE(2); - utf16_buf[utf16_buf_used++] = L'\r'; - utf16_buf[utf16_buf_used++] = L'\n'; - } else if (utf8_codepoint == 0x0d && previous_eol == 0x0a) { - /* \n was followed by \r; do not print the \r, since */ - /* the source was either \r\n\r (so the second \r is */ - /* redundant) or was \n\r (so the \n was processed */ - /* by the last case and an \r automatically inserted). */ - } else { - /* \r without \n; print \r as-is. */ - ENSURE_BUFFER_SPACE(1); - utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint; - } - - previous_eol = (char) utf8_codepoint; - - } else if (utf8_codepoint <= 0xffff) { - /* Encode character into utf-16 buffer. */ - ENSURE_BUFFER_SPACE(1); - utf16_buf[utf16_buf_used++] = (WCHAR) utf8_codepoint; - previous_eol = 0; - } - } - } - - /* Flush remaining characters */ - FLUSH_TEXT(); - - /* Copy cached values back to struct. */ - handle->tty.wr.utf8_bytes_left = utf8_bytes_left; - handle->tty.wr.utf8_codepoint = utf8_codepoint; - handle->tty.wr.previous_eol = previous_eol; - handle->tty.wr.ansi_parser_state = ansi_parser_state; - - LeaveCriticalSection(&uv_tty_output_lock); - - if (*error == STATUS_SUCCESS) { - return 0; - } else { - return -1; - } - -#undef FLUSH_TEXT -} - - -int uv_tty_write(uv_loop_t* loop, - uv_write_t* req, - uv_tty_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - uv_write_cb cb) { - DWORD error; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_WRITE; - req->handle = (uv_stream_t*) handle; - req->cb = cb; - - handle->reqs_pending++; - handle->stream.conn.write_reqs_pending++; - REGISTER_HANDLE_REQ(loop, handle, req); - - req->u.io.queued_bytes = 0; - - if (!uv_tty_write_bufs(handle, bufs, nbufs, &error)) { - SET_REQ_SUCCESS(req); - } else { - SET_REQ_ERROR(req, error); - } - - uv_insert_pending_req(loop, (uv_req_t*) req); - - return 0; -} - - -int uv__tty_try_write(uv_tty_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs) { - DWORD error; - - if (handle->stream.conn.write_reqs_pending > 0) - return UV_EAGAIN; - - if (uv_tty_write_bufs(handle, bufs, nbufs, &error)) - return uv_translate_sys_error(error); - - return uv__count_bufs(bufs, nbufs); -} - - -void uv_process_tty_write_req(uv_loop_t* loop, uv_tty_t* handle, - uv_write_t* req) { - int err; - - handle->write_queue_size -= req->u.io.queued_bytes; - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (req->cb) { - err = GET_REQ_ERROR(req); - req->cb(req, uv_translate_sys_error(err)); - } - - handle->stream.conn.write_reqs_pending--; - if (handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*)handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_tty_close(uv_tty_t* handle) { - assert(handle->u.fd == -1 || handle->u.fd > 2); - if (handle->u.fd == -1) - CloseHandle(handle->handle); - else - close(handle->u.fd); - - if (handle->flags & UV_HANDLE_READING) - uv_tty_read_stop(handle); - - handle->u.fd = -1; - handle->handle = INVALID_HANDLE_VALUE; - handle->flags &= ~(UV_HANDLE_READABLE | UV_HANDLE_WRITABLE); - uv__handle_closing(handle); - - if (handle->reqs_pending == 0) { - uv_want_endgame(handle->loop, (uv_handle_t*) handle); - } -} - - -void uv_tty_endgame(uv_loop_t* loop, uv_tty_t* handle) { - if (!(handle->flags & UV_HANDLE_TTY_READABLE) && - handle->stream.conn.shutdown_req != NULL && - handle->stream.conn.write_reqs_pending == 0) { - UNREGISTER_HANDLE_REQ(loop, handle, handle->stream.conn.shutdown_req); - - /* TTY shutdown is really just a no-op */ - if (handle->stream.conn.shutdown_req->cb) { - if (handle->flags & UV__HANDLE_CLOSING) { - handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, UV_ECANCELED); - } else { - handle->stream.conn.shutdown_req->cb(handle->stream.conn.shutdown_req, 0); - } - } - - handle->stream.conn.shutdown_req = NULL; - - DECREASE_PENDING_REQ_COUNT(handle); - return; - } - - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - /* The console handle duplicate used for line reading should be destroyed */ - /* by uv_tty_read_stop. */ - assert(!(handle->flags & UV_HANDLE_TTY_READABLE) || - handle->tty.rd.read_line_handle == NULL); - - /* The wait handle used for raw reading should be unregistered when the */ - /* wait callback runs. */ - assert(!(handle->flags & UV_HANDLE_TTY_READABLE) || - handle->tty.rd.read_raw_wait == NULL); - - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -/* TODO: remove me */ -void uv_process_tty_accept_req(uv_loop_t* loop, uv_tty_t* handle, - uv_req_t* raw_req) { - abort(); -} - - -/* TODO: remove me */ -void uv_process_tty_connect_req(uv_loop_t* loop, uv_tty_t* handle, - uv_connect_t* req) { - abort(); -} - - -int uv_tty_reset_mode(void) { - /* Not necessary to do anything. */ - return 0; -} diff --git a/3rdparty/libuv/src/win/udp.c b/3rdparty/libuv/src/win/udp.c deleted file mode 100644 index 24792ec067e..00000000000 --- a/3rdparty/libuv/src/win/udp.c +++ /dev/null @@ -1,926 +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. - */ - -#include <assert.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" -#include "handle-inl.h" -#include "stream-inl.h" -#include "req-inl.h" - - -/* - * Threshold of active udp streams for which to preallocate udp read buffers. - */ -const unsigned int uv_active_udp_streams_threshold = 0; - -/* A zero-size buffer for use by uv_udp_read */ -static char uv_zero_[] = ""; - -int uv_udp_getsockname(const uv_udp_t* handle, - struct sockaddr* name, - int* namelen) { - int result; - - if (handle->socket == INVALID_SOCKET) { - return UV_EINVAL; - } - - result = getsockname(handle->socket, name, namelen); - if (result != 0) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -static int uv_udp_set_socket(uv_loop_t* loop, uv_udp_t* handle, SOCKET socket, - int family) { - DWORD yes = 1; - WSAPROTOCOL_INFOW info; - int opt_len; - - if (handle->socket != INVALID_SOCKET) - return UV_EBUSY; - - /* Set the socket to nonblocking mode */ - if (ioctlsocket(socket, FIONBIO, &yes) == SOCKET_ERROR) { - return WSAGetLastError(); - } - - /* Make the socket non-inheritable */ - if (!SetHandleInformation((HANDLE)socket, HANDLE_FLAG_INHERIT, 0)) { - return GetLastError(); - } - - /* Associate it with the I/O completion port. */ - /* Use uv_handle_t pointer as completion key. */ - if (CreateIoCompletionPort((HANDLE)socket, - loop->iocp, - (ULONG_PTR)socket, - 0) == NULL) { - return GetLastError(); - } - - if (pSetFileCompletionNotificationModes) { - /* All known Windows that support SetFileCompletionNotificationModes */ - /* have a bug that makes it impossible to use this function in */ - /* conjunction with datagram sockets. We can work around that but only */ - /* if the user is using the default UDP driver (AFD) and has no other */ - /* LSPs stacked on top. Here we check whether that is the case. */ - opt_len = (int) sizeof info; - if (getsockopt(socket, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &info, - &opt_len) == SOCKET_ERROR) { - return GetLastError(); - } - - if (info.ProtocolChain.ChainLen == 1) { - if (pSetFileCompletionNotificationModes((HANDLE)socket, - FILE_SKIP_SET_EVENT_ON_HANDLE | - FILE_SKIP_COMPLETION_PORT_ON_SUCCESS)) { - handle->flags |= UV_HANDLE_SYNC_BYPASS_IOCP; - handle->func_wsarecv = uv_wsarecv_workaround; - handle->func_wsarecvfrom = uv_wsarecvfrom_workaround; - } else if (GetLastError() != ERROR_INVALID_FUNCTION) { - return GetLastError(); - } - } - } - - handle->socket = socket; - - if (family == AF_INET6) { - handle->flags |= UV_HANDLE_IPV6; - } else { - assert(!(handle->flags & UV_HANDLE_IPV6)); - } - - return 0; -} - - -int uv_udp_init_ex(uv_loop_t* loop, uv_udp_t* handle, unsigned int flags) { - int domain; - - /* Use the lower 8 bits for the domain */ - domain = flags & 0xFF; - if (domain != AF_INET && domain != AF_INET6 && domain != AF_UNSPEC) - return UV_EINVAL; - - if (flags & ~0xFF) - return UV_EINVAL; - - uv__handle_init(loop, (uv_handle_t*) handle, UV_UDP); - handle->socket = INVALID_SOCKET; - handle->reqs_pending = 0; - handle->activecnt = 0; - handle->func_wsarecv = WSARecv; - handle->func_wsarecvfrom = WSARecvFrom; - handle->send_queue_size = 0; - handle->send_queue_count = 0; - uv_req_init(loop, (uv_req_t*) &(handle->recv_req)); - handle->recv_req.type = UV_UDP_RECV; - handle->recv_req.data = handle; - - /* If anything fails beyond this point we need to remove the handle from - * the handle queue, since it was added by uv__handle_init. - */ - - if (domain != AF_UNSPEC) { - SOCKET sock; - DWORD err; - - sock = socket(domain, SOCK_DGRAM, 0); - if (sock == INVALID_SOCKET) { - err = WSAGetLastError(); - QUEUE_REMOVE(&handle->handle_queue); - return uv_translate_sys_error(err); - } - - err = uv_udp_set_socket(handle->loop, handle, sock, domain); - if (err) { - closesocket(sock); - QUEUE_REMOVE(&handle->handle_queue); - return uv_translate_sys_error(err); - } - } - - return 0; -} - - -int uv_udp_init(uv_loop_t* loop, uv_udp_t* handle) { - return uv_udp_init_ex(loop, handle, AF_UNSPEC); -} - - -void uv_udp_close(uv_loop_t* loop, uv_udp_t* handle) { - uv_udp_recv_stop(handle); - closesocket(handle->socket); - handle->socket = INVALID_SOCKET; - - uv__handle_closing(handle); - - if (handle->reqs_pending == 0) { - uv_want_endgame(loop, (uv_handle_t*) handle); - } -} - - -void uv_udp_endgame(uv_loop_t* loop, uv_udp_t* handle) { - if (handle->flags & UV__HANDLE_CLOSING && - handle->reqs_pending == 0) { - assert(!(handle->flags & UV_HANDLE_CLOSED)); - uv__handle_close(handle); - } -} - - -static int uv_udp_maybe_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int r; - int err; - DWORD no = 0; - - if (handle->flags & UV_HANDLE_BOUND) - return 0; - - if ((flags & UV_UDP_IPV6ONLY) && addr->sa_family != AF_INET6) { - /* UV_UDP_IPV6ONLY is supported only for IPV6 sockets */ - return ERROR_INVALID_PARAMETER; - } - - if (handle->socket == INVALID_SOCKET) { - SOCKET sock = socket(addr->sa_family, SOCK_DGRAM, 0); - if (sock == INVALID_SOCKET) { - return WSAGetLastError(); - } - - err = uv_udp_set_socket(handle->loop, handle, sock, addr->sa_family); - if (err) { - closesocket(sock); - return err; - } - } - - if (flags & UV_UDP_REUSEADDR) { - DWORD yes = 1; - /* Set SO_REUSEADDR on the socket. */ - if (setsockopt(handle->socket, - SOL_SOCKET, - SO_REUSEADDR, - (char*) &yes, - sizeof yes) == SOCKET_ERROR) { - err = WSAGetLastError(); - return err; - } - } - - if (addr->sa_family == AF_INET6) - handle->flags |= UV_HANDLE_IPV6; - - if (addr->sa_family == AF_INET6 && !(flags & UV_UDP_IPV6ONLY)) { - /* On windows IPV6ONLY is on by default. */ - /* If the user doesn't specify it libuv turns it off. */ - - /* TODO: how to handle errors? This may fail if there is no ipv4 stack */ - /* available, or when run on XP/2003 which have no support for dualstack */ - /* sockets. For now we're silently ignoring the error. */ - setsockopt(handle->socket, - IPPROTO_IPV6, - IPV6_V6ONLY, - (char*) &no, - sizeof no); - } - - r = bind(handle->socket, addr, addrlen); - if (r == SOCKET_ERROR) { - return WSAGetLastError(); - } - - handle->flags |= UV_HANDLE_BOUND; - - return 0; -} - - -static void uv_udp_queue_recv(uv_loop_t* loop, uv_udp_t* handle) { - uv_req_t* req; - uv_buf_t buf; - DWORD bytes, flags; - int result; - - assert(handle->flags & UV_HANDLE_READING); - assert(!(handle->flags & UV_HANDLE_READ_PENDING)); - - req = &handle->recv_req; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - /* - * Preallocate a read buffer if the number of active streams is below - * the threshold. - */ - if (loop->active_udp_streams < uv_active_udp_streams_threshold) { - handle->flags &= ~UV_HANDLE_ZERO_READ; - - handle->alloc_cb((uv_handle_t*) handle, 65536, &handle->recv_buffer); - if (handle->recv_buffer.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, &handle->recv_buffer, NULL, 0); - return; - } - assert(handle->recv_buffer.base != NULL); - - buf = handle->recv_buffer; - memset(&handle->recv_from, 0, sizeof handle->recv_from); - handle->recv_from_len = sizeof handle->recv_from; - flags = 0; - - result = handle->func_wsarecvfrom(handle->socket, - (WSABUF*) &buf, - 1, - &bytes, - &flags, - (struct sockaddr*) &handle->recv_from, - &handle->recv_from_len, - &req->u.io.overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Process the req without IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - req->u.io.overlapped.InternalHigh = bytes; - handle->reqs_pending++; - uv_insert_pending_req(loop, req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* The req will be processed with IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, req); - handle->reqs_pending++; - } - - } else { - handle->flags |= UV_HANDLE_ZERO_READ; - - buf.base = (char*) uv_zero_; - buf.len = 0; - flags = MSG_PEEK; - - result = handle->func_wsarecv(handle->socket, - (WSABUF*) &buf, - 1, - &bytes, - &flags, - &req->u.io.overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Process the req without IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - req->u.io.overlapped.InternalHigh = bytes; - handle->reqs_pending++; - uv_insert_pending_req(loop, req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* The req will be processed with IOCP. */ - handle->flags |= UV_HANDLE_READ_PENDING; - handle->reqs_pending++; - } else { - /* Make this req pending reporting an error. */ - SET_REQ_ERROR(req, WSAGetLastError()); - uv_insert_pending_req(loop, req); - handle->reqs_pending++; - } - } -} - - -int uv__udp_recv_start(uv_udp_t* handle, uv_alloc_cb alloc_cb, - uv_udp_recv_cb recv_cb) { - uv_loop_t* loop = handle->loop; - int err; - - if (handle->flags & UV_HANDLE_READING) { - return WSAEALREADY; - } - - err = uv_udp_maybe_bind(handle, - (const struct sockaddr*) &uv_addr_ip4_any_, - sizeof(uv_addr_ip4_any_), - 0); - if (err) - return err; - - handle->flags |= UV_HANDLE_READING; - INCREASE_ACTIVE_COUNT(loop, handle); - loop->active_udp_streams++; - - handle->recv_cb = recv_cb; - handle->alloc_cb = alloc_cb; - - /* If reading was stopped and then started again, there could still be a */ - /* recv request pending. */ - if (!(handle->flags & UV_HANDLE_READ_PENDING)) - uv_udp_queue_recv(loop, handle); - - return 0; -} - - -int uv__udp_recv_stop(uv_udp_t* handle) { - if (handle->flags & UV_HANDLE_READING) { - handle->flags &= ~UV_HANDLE_READING; - handle->loop->active_udp_streams--; - DECREASE_ACTIVE_COUNT(loop, handle); - } - - return 0; -} - - -static int uv__send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen, - uv_udp_send_cb cb) { - uv_loop_t* loop = handle->loop; - DWORD result, bytes; - - uv_req_init(loop, (uv_req_t*) req); - req->type = UV_UDP_SEND; - req->handle = handle; - req->cb = cb; - memset(&req->u.io.overlapped, 0, sizeof(req->u.io.overlapped)); - - result = WSASendTo(handle->socket, - (WSABUF*)bufs, - nbufs, - &bytes, - 0, - addr, - addrlen, - &req->u.io.overlapped, - NULL); - - if (UV_SUCCEEDED_WITHOUT_IOCP(result == 0)) { - /* Request completed immediately. */ - req->u.io.queued_bytes = 0; - handle->reqs_pending++; - handle->send_queue_size += req->u.io.queued_bytes; - handle->send_queue_count++; - REGISTER_HANDLE_REQ(loop, handle, req); - uv_insert_pending_req(loop, (uv_req_t*)req); - } else if (UV_SUCCEEDED_WITH_IOCP(result == 0)) { - /* Request queued by the kernel. */ - req->u.io.queued_bytes = uv__count_bufs(bufs, nbufs); - handle->reqs_pending++; - handle->send_queue_size += req->u.io.queued_bytes; - handle->send_queue_count++; - REGISTER_HANDLE_REQ(loop, handle, req); - } else { - /* Send failed due to an error. */ - return WSAGetLastError(); - } - - return 0; -} - - -void uv_process_udp_recv_req(uv_loop_t* loop, uv_udp_t* handle, - uv_req_t* req) { - uv_buf_t buf; - int partial; - - assert(handle->type == UV_UDP); - - handle->flags &= ~UV_HANDLE_READ_PENDING; - - if (!REQ_SUCCESS(req)) { - DWORD err = GET_REQ_SOCK_ERROR(req); - if (err == WSAEMSGSIZE) { - /* Not a real error, it just indicates that the received packet */ - /* was bigger than the receive buffer. */ - } else if (err == WSAECONNRESET || err == WSAENETRESET) { - /* A previous sendto operation failed; ignore this error. If */ - /* zero-reading we need to call WSARecv/WSARecvFrom _without_ the */ - /* MSG_PEEK flag to clear out the error queue. For nonzero reads, */ - /* immediately queue a new receive. */ - if (!(handle->flags & UV_HANDLE_ZERO_READ)) { - goto done; - } - } else { - /* A real error occurred. Report the error to the user only if we're */ - /* currently reading. */ - if (handle->flags & UV_HANDLE_READING) { - uv_udp_recv_stop(handle); - buf = (handle->flags & UV_HANDLE_ZERO_READ) ? - uv_buf_init(NULL, 0) : handle->recv_buffer; - handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); - } - goto done; - } - } - - if (!(handle->flags & UV_HANDLE_ZERO_READ)) { - /* Successful read */ - partial = !REQ_SUCCESS(req); - handle->recv_cb(handle, - req->u.io.overlapped.InternalHigh, - &handle->recv_buffer, - (const struct sockaddr*) &handle->recv_from, - partial ? UV_UDP_PARTIAL : 0); - } else if (handle->flags & UV_HANDLE_READING) { - DWORD bytes, err, flags; - struct sockaddr_storage from; - int from_len; - - /* Do a nonblocking receive */ - /* TODO: try to read multiple datagrams at once. FIONREAD maybe? */ - handle->alloc_cb((uv_handle_t*) handle, 65536, &buf); - if (buf.len == 0) { - handle->recv_cb(handle, UV_ENOBUFS, &buf, NULL, 0); - goto done; - } - assert(buf.base != NULL); - - memset(&from, 0, sizeof from); - from_len = sizeof from; - - flags = 0; - - if (WSARecvFrom(handle->socket, - (WSABUF*)&buf, - 1, - &bytes, - &flags, - (struct sockaddr*) &from, - &from_len, - NULL, - NULL) != SOCKET_ERROR) { - - /* Message received */ - handle->recv_cb(handle, bytes, &buf, (const struct sockaddr*) &from, 0); - } else { - err = WSAGetLastError(); - if (err == WSAEMSGSIZE) { - /* Message truncated */ - handle->recv_cb(handle, - bytes, - &buf, - (const struct sockaddr*) &from, - UV_UDP_PARTIAL); - } else if (err == WSAEWOULDBLOCK) { - /* Kernel buffer empty */ - handle->recv_cb(handle, 0, &buf, NULL, 0); - } else if (err == WSAECONNRESET || err == WSAENETRESET) { - /* WSAECONNRESET/WSANETRESET is ignored because this just indicates - * that a previous sendto operation failed. - */ - handle->recv_cb(handle, 0, &buf, NULL, 0); - } else { - /* Any other error that we want to report back to the user. */ - uv_udp_recv_stop(handle); - handle->recv_cb(handle, uv_translate_sys_error(err), &buf, NULL, 0); - } - } - } - -done: - /* Post another read if still reading and not closing. */ - if ((handle->flags & UV_HANDLE_READING) && - !(handle->flags & UV_HANDLE_READ_PENDING)) { - uv_udp_queue_recv(loop, handle); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -void uv_process_udp_send_req(uv_loop_t* loop, uv_udp_t* handle, - uv_udp_send_t* req) { - int err; - - assert(handle->type == UV_UDP); - - assert(handle->send_queue_size >= req->u.io.queued_bytes); - assert(handle->send_queue_count >= 1); - handle->send_queue_size -= req->u.io.queued_bytes; - handle->send_queue_count--; - - UNREGISTER_HANDLE_REQ(loop, handle, req); - - if (req->cb) { - err = 0; - if (!REQ_SUCCESS(req)) { - err = GET_REQ_SOCK_ERROR(req); - } - req->cb(req, uv_translate_sys_error(err)); - } - - DECREASE_PENDING_REQ_COUNT(handle); -} - - -static int uv__udp_set_membership4(uv_udp_t* handle, - const struct sockaddr_in* multicast_addr, - const char* interface_addr, - uv_membership membership) { - int err; - int optname; - struct ip_mreq mreq; - - if (handle->flags & UV_HANDLE_IPV6) - return UV_EINVAL; - - /* If the socket is unbound, bind to inaddr_any. */ - err = uv_udp_maybe_bind(handle, - (const struct sockaddr*) &uv_addr_ip4_any_, - sizeof(uv_addr_ip4_any_), - UV_UDP_REUSEADDR); - if (err) - return uv_translate_sys_error(err); - - memset(&mreq, 0, sizeof mreq); - - if (interface_addr) { - err = uv_inet_pton(AF_INET, interface_addr, &mreq.imr_interface.s_addr); - if (err) - return err; - } else { - mreq.imr_interface.s_addr = htonl(INADDR_ANY); - } - - mreq.imr_multiaddr.s_addr = multicast_addr->sin_addr.s_addr; - - switch (membership) { - case UV_JOIN_GROUP: - optname = IP_ADD_MEMBERSHIP; - break; - case UV_LEAVE_GROUP: - optname = IP_DROP_MEMBERSHIP; - break; - default: - return UV_EINVAL; - } - - if (setsockopt(handle->socket, - IPPROTO_IP, - optname, - (char*) &mreq, - sizeof mreq) == SOCKET_ERROR) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv__udp_set_membership6(uv_udp_t* handle, - const struct sockaddr_in6* multicast_addr, - const char* interface_addr, - uv_membership membership) { - int optname; - int err; - struct ipv6_mreq mreq; - struct sockaddr_in6 addr6; - - if ((handle->flags & UV_HANDLE_BOUND) && !(handle->flags & UV_HANDLE_IPV6)) - return UV_EINVAL; - - err = uv_udp_maybe_bind(handle, - (const struct sockaddr*) &uv_addr_ip6_any_, - sizeof(uv_addr_ip6_any_), - UV_UDP_REUSEADDR); - - if (err) - return uv_translate_sys_error(err); - - memset(&mreq, 0, sizeof(mreq)); - - if (interface_addr) { - if (uv_ip6_addr(interface_addr, 0, &addr6)) - return UV_EINVAL; - mreq.ipv6mr_interface = addr6.sin6_scope_id; - } else { - mreq.ipv6mr_interface = 0; - } - - mreq.ipv6mr_multiaddr = multicast_addr->sin6_addr; - - switch (membership) { - case UV_JOIN_GROUP: - optname = IPV6_ADD_MEMBERSHIP; - break; - case UV_LEAVE_GROUP: - optname = IPV6_DROP_MEMBERSHIP; - break; - default: - return UV_EINVAL; - } - - if (setsockopt(handle->socket, - IPPROTO_IPV6, - optname, - (char*) &mreq, - sizeof mreq) == SOCKET_ERROR) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_udp_set_membership(uv_udp_t* handle, - const char* multicast_addr, - const char* interface_addr, - uv_membership membership) { - struct sockaddr_in addr4; - struct sockaddr_in6 addr6; - - if (uv_ip4_addr(multicast_addr, 0, &addr4) == 0) - return uv__udp_set_membership4(handle, &addr4, interface_addr, membership); - else if (uv_ip6_addr(multicast_addr, 0, &addr6) == 0) - return uv__udp_set_membership6(handle, &addr6, interface_addr, membership); - else - return UV_EINVAL; -} - - -int uv_udp_set_multicast_interface(uv_udp_t* handle, const char* interface_addr) { - struct sockaddr_storage addr_st; - struct sockaddr_in* addr4; - struct sockaddr_in6* addr6; - - addr4 = (struct sockaddr_in*) &addr_st; - addr6 = (struct sockaddr_in6*) &addr_st; - - if (!interface_addr) { - memset(&addr_st, 0, sizeof addr_st); - if (handle->flags & UV_HANDLE_IPV6) { - addr_st.ss_family = AF_INET6; - addr6->sin6_scope_id = 0; - } else { - addr_st.ss_family = AF_INET; - addr4->sin_addr.s_addr = htonl(INADDR_ANY); - } - } else if (uv_ip4_addr(interface_addr, 0, addr4) == 0) { - /* nothing, address was parsed */ - } else if (uv_ip6_addr(interface_addr, 0, addr6) == 0) { - /* nothing, address was parsed */ - } else { - return UV_EINVAL; - } - - if (!(handle->flags & UV_HANDLE_BOUND)) - return UV_EBADF; - - if (addr_st.ss_family == AF_INET) { - if (setsockopt(handle->socket, - IPPROTO_IP, - IP_MULTICAST_IF, - (char*) &addr4->sin_addr, - sizeof(addr4->sin_addr)) == SOCKET_ERROR) { - return uv_translate_sys_error(WSAGetLastError()); - } - } else if (addr_st.ss_family == AF_INET6) { - if (setsockopt(handle->socket, - IPPROTO_IPV6, - IPV6_MULTICAST_IF, - (char*) &addr6->sin6_scope_id, - sizeof(addr6->sin6_scope_id)) == SOCKET_ERROR) { - return uv_translate_sys_error(WSAGetLastError()); - } - } else { - assert(0 && "unexpected address family"); - abort(); - } - - return 0; -} - - -int uv_udp_set_broadcast(uv_udp_t* handle, int value) { - BOOL optval = (BOOL) value; - - if (!(handle->flags & UV_HANDLE_BOUND)) - return UV_EBADF; - - if (setsockopt(handle->socket, - SOL_SOCKET, - SO_BROADCAST, - (char*) &optval, - sizeof optval)) { - return uv_translate_sys_error(WSAGetLastError()); - } - - return 0; -} - - -int uv_udp_open(uv_udp_t* handle, uv_os_sock_t sock) { - WSAPROTOCOL_INFOW protocol_info; - int opt_len; - int err; - - /* Detect the address family of the socket. */ - opt_len = (int) sizeof protocol_info; - if (getsockopt(sock, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) { - return uv_translate_sys_error(GetLastError()); - } - - err = uv_udp_set_socket(handle->loop, - handle, - sock, - protocol_info.iAddressFamily); - return uv_translate_sys_error(err); -} - - -#define SOCKOPT_SETTER(name, option4, option6, validate) \ - int uv_udp_set_##name(uv_udp_t* handle, int value) { \ - DWORD optval = (DWORD) value; \ - \ - if (!(validate(value))) { \ - return UV_EINVAL; \ - } \ - \ - if (!(handle->flags & UV_HANDLE_BOUND)) \ - return UV_EBADF; \ - \ - if (!(handle->flags & UV_HANDLE_IPV6)) { \ - /* Set IPv4 socket option */ \ - if (setsockopt(handle->socket, \ - IPPROTO_IP, \ - option4, \ - (char*) &optval, \ - sizeof optval)) { \ - return uv_translate_sys_error(WSAGetLastError()); \ - } \ - } else { \ - /* Set IPv6 socket option */ \ - if (setsockopt(handle->socket, \ - IPPROTO_IPV6, \ - option6, \ - (char*) &optval, \ - sizeof optval)) { \ - return uv_translate_sys_error(WSAGetLastError()); \ - } \ - } \ - return 0; \ - } - -#define VALIDATE_TTL(value) ((value) >= 1 && (value) <= 255) -#define VALIDATE_MULTICAST_TTL(value) ((value) >= -1 && (value) <= 255) -#define VALIDATE_MULTICAST_LOOP(value) (1) - -SOCKOPT_SETTER(ttl, - IP_TTL, - IPV6_HOPLIMIT, - VALIDATE_TTL) -SOCKOPT_SETTER(multicast_ttl, - IP_MULTICAST_TTL, - IPV6_MULTICAST_HOPS, - VALIDATE_MULTICAST_TTL) -SOCKOPT_SETTER(multicast_loop, - IP_MULTICAST_LOOP, - IPV6_MULTICAST_LOOP, - VALIDATE_MULTICAST_LOOP) - -#undef SOCKOPT_SETTER -#undef VALIDATE_TTL -#undef VALIDATE_MULTICAST_TTL -#undef VALIDATE_MULTICAST_LOOP - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__udp_bind(uv_udp_t* handle, - const struct sockaddr* addr, - unsigned int addrlen, - unsigned int flags) { - int err; - - err = uv_udp_maybe_bind(handle, addr, addrlen, flags); - if (err) - return uv_translate_sys_error(err); - - return 0; -} - - -/* This function is an egress point, i.e. it returns libuv errors rather than - * system errors. - */ -int uv__udp_send(uv_udp_send_t* req, - uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen, - uv_udp_send_cb send_cb) { - const struct sockaddr* bind_addr; - int err; - - if (!(handle->flags & UV_HANDLE_BOUND)) { - if (addrlen == sizeof(uv_addr_ip4_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip4_any_; - } else if (addrlen == sizeof(uv_addr_ip6_any_)) { - bind_addr = (const struct sockaddr*) &uv_addr_ip6_any_; - } else { - abort(); - } - err = uv_udp_maybe_bind(handle, bind_addr, addrlen, 0); - if (err) - return uv_translate_sys_error(err); - } - - err = uv__send(req, handle, bufs, nbufs, addr, addrlen, send_cb); - if (err) - return uv_translate_sys_error(err); - - return 0; -} - - -int uv__udp_try_send(uv_udp_t* handle, - const uv_buf_t bufs[], - unsigned int nbufs, - const struct sockaddr* addr, - unsigned int addrlen) { - return UV_ENOSYS; -} diff --git a/3rdparty/libuv/src/win/util.c b/3rdparty/libuv/src/win/util.c deleted file mode 100644 index 1788b1780e9..00000000000 --- a/3rdparty/libuv/src/win/util.c +++ /dev/null @@ -1,1392 +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. - */ - -#include <assert.h> -#include <direct.h> -#include <limits.h> -#include <stdio.h> -#include <string.h> -#include <time.h> -#include <wchar.h> - -#include "uv.h" -#include "internal.h" - -#include <winsock2.h> -#include <winperf.h> -#include <iphlpapi.h> -#include <psapi.h> -#include <tlhelp32.h> -#include <windows.h> -#include <userenv.h> - - -/* - * Max title length; the only thing MSDN tells us about the maximum length - * of the console title is that it is smaller than 64K. However in practice - * it is much smaller, and there is no way to figure out what the exact length - * of the title is or can be, at least not on XP. To make it even more - * annoying, GetConsoleTitle fails when the buffer to be read into is bigger - * than the actual maximum length. So we make a conservative guess here; - * just don't put the novel you're writing in the title, unless the plot - * survives truncation. - */ -#define MAX_TITLE_LENGTH 8192 - -/* The number of nanoseconds in one second. */ -#define UV__NANOSEC 1000000000 - - -/* Cached copy of the process title, plus a mutex guarding it. */ -static char *process_title; -static CRITICAL_SECTION process_title_lock; - -/* Cached copy of the process id, written once. */ -static DWORD current_pid = 0; - - -/* Interval (in seconds) of the high-resolution clock. */ -static double hrtime_interval_ = 0; - - -/* - * One-time initialization code for functionality defined in util.c. - */ -void uv__util_init() { - LARGE_INTEGER perf_frequency; - - /* Initialize process title access mutex. */ - InitializeCriticalSection(&process_title_lock); - - /* Retrieve high-resolution timer frequency - * and precompute its reciprocal. - */ - if (QueryPerformanceFrequency(&perf_frequency)) { - hrtime_interval_ = 1.0 / perf_frequency.QuadPart; - } else { - hrtime_interval_= 0; - } -} - - -int uv_exepath(char* buffer, size_t* size_ptr) { - int utf8_len, utf16_buffer_len, utf16_len; - WCHAR* utf16_buffer; - int err; - - if (buffer == NULL || size_ptr == NULL || *size_ptr == 0) { - return UV_EINVAL; - } - - if (*size_ptr > 32768) { - /* Windows paths can never be longer than this. */ - utf16_buffer_len = 32768; - } else { - utf16_buffer_len = (int) *size_ptr; - } - - utf16_buffer = (WCHAR*) uv__malloc(sizeof(WCHAR) * utf16_buffer_len); - if (!utf16_buffer) { - return UV_ENOMEM; - } - - /* Get the path as UTF-16. */ - utf16_len = GetModuleFileNameW(NULL, utf16_buffer, utf16_buffer_len); - if (utf16_len <= 0) { - err = GetLastError(); - goto error; - } - - /* utf16_len contains the length, *not* including the terminating null. */ - utf16_buffer[utf16_len] = L'\0'; - - /* Convert to UTF-8 */ - utf8_len = WideCharToMultiByte(CP_UTF8, - 0, - utf16_buffer, - -1, - buffer, - *size_ptr > INT_MAX ? INT_MAX : (int) *size_ptr, - NULL, - NULL); - if (utf8_len == 0) { - err = GetLastError(); - goto error; - } - - uv__free(utf16_buffer); - - /* utf8_len *does* include the terminating null at this point, but the */ - /* returned size shouldn't. */ - *size_ptr = utf8_len - 1; - return 0; - - error: - uv__free(utf16_buffer); - return uv_translate_sys_error(err); -} - - -int uv_cwd(char* buffer, size_t* size) { - DWORD utf16_len; - WCHAR utf16_buffer[MAX_PATH]; - int r; - - if (buffer == NULL || size == NULL) { - return UV_EINVAL; - } - - utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer); - if (utf16_len == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (utf16_len > MAX_PATH) { - /* This should be impossible; however the CRT has a code path to deal */ - /* with this scenario, so I added a check anyway. */ - return UV_EIO; - } - - /* utf16_len contains the length, *not* including the terminating null. */ - utf16_buffer[utf16_len] = L'\0'; - - /* The returned directory should not have a trailing slash, unless it */ - /* points at a drive root, like c:\. Remove it if needed.*/ - if (utf16_buffer[utf16_len - 1] == L'\\' && - !(utf16_len == 3 && utf16_buffer[1] == L':')) { - utf16_len--; - utf16_buffer[utf16_len] = L'\0'; - } - - /* Check how much space we need */ - r = WideCharToMultiByte(CP_UTF8, - 0, - utf16_buffer, - -1, - NULL, - 0, - NULL, - NULL); - if (r == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (r > (int) *size) { - *size = r; - return UV_ENOBUFS; - } - - /* Convert to UTF-8 */ - r = WideCharToMultiByte(CP_UTF8, - 0, - utf16_buffer, - -1, - buffer, - *size > INT_MAX ? INT_MAX : (int) *size, - NULL, - NULL); - if (r == 0) { - return uv_translate_sys_error(GetLastError()); - } - - *size = r - 1; - return 0; -} - - -int uv_chdir(const char* dir) { - WCHAR utf16_buffer[MAX_PATH]; - size_t utf16_len; - WCHAR drive_letter, env_var[4]; - - if (dir == NULL) { - return UV_EINVAL; - } - - if (MultiByteToWideChar(CP_UTF8, - 0, - dir, - -1, - utf16_buffer, - MAX_PATH) == 0) { - DWORD error = GetLastError(); - /* The maximum length of the current working directory is 260 chars, */ - /* including terminating null. If it doesn't fit, the path name must be */ - /* too long. */ - if (error == ERROR_INSUFFICIENT_BUFFER) { - return UV_ENAMETOOLONG; - } else { - return uv_translate_sys_error(error); - } - } - - if (!SetCurrentDirectoryW(utf16_buffer)) { - return uv_translate_sys_error(GetLastError()); - } - - /* Windows stores the drive-local path in an "hidden" environment variable, */ - /* which has the form "=C:=C:\Windows". SetCurrentDirectory does not */ - /* update this, so we'll have to do it. */ - utf16_len = GetCurrentDirectoryW(MAX_PATH, utf16_buffer); - if (utf16_len == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (utf16_len > MAX_PATH) { - return UV_EIO; - } - - /* The returned directory should not have a trailing slash, unless it */ - /* points at a drive root, like c:\. Remove it if needed. */ - if (utf16_buffer[utf16_len - 1] == L'\\' && - !(utf16_len == 3 && utf16_buffer[1] == L':')) { - utf16_len--; - utf16_buffer[utf16_len] = L'\0'; - } - - if (utf16_len < 2 || utf16_buffer[1] != L':') { - /* Doesn't look like a drive letter could be there - probably an UNC */ - /* path. TODO: Need to handle win32 namespaces like \\?\C:\ ? */ - drive_letter = 0; - } else if (utf16_buffer[0] >= L'A' && utf16_buffer[0] <= L'Z') { - drive_letter = utf16_buffer[0]; - } else if (utf16_buffer[0] >= L'a' && utf16_buffer[0] <= L'z') { - /* Convert to uppercase. */ - drive_letter = utf16_buffer[0] - L'a' + L'A'; - } else { - /* Not valid. */ - drive_letter = 0; - } - - if (drive_letter != 0) { - /* Construct the environment variable name and set it. */ - env_var[0] = L'='; - env_var[1] = drive_letter; - env_var[2] = L':'; - env_var[3] = L'\0'; - - if (!SetEnvironmentVariableW(env_var, utf16_buffer)) { - return uv_translate_sys_error(GetLastError()); - } - } - - return 0; -} - - -void uv_loadavg(double avg[3]) { - /* Can't be implemented */ - avg[0] = avg[1] = avg[2] = 0; -} - - -uint64_t uv_get_free_memory(void) { - MEMORYSTATUSEX memory_status; - memory_status.dwLength = sizeof(memory_status); - - if (!GlobalMemoryStatusEx(&memory_status)) { - return -1; - } - - return (uint64_t)memory_status.ullAvailPhys; -} - - -uint64_t uv_get_total_memory(void) { - MEMORYSTATUSEX memory_status; - memory_status.dwLength = sizeof(memory_status); - - if (!GlobalMemoryStatusEx(&memory_status)) { - return -1; - } - - return (uint64_t)memory_status.ullTotalPhys; -} - - -int uv_parent_pid() { - int parent_pid = -1; - HANDLE handle; - PROCESSENTRY32 pe; - DWORD current_pid = GetCurrentProcessId(); - - pe.dwSize = sizeof(PROCESSENTRY32); - handle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - - if (Process32First(handle, &pe)) { - do { - if (pe.th32ProcessID == current_pid) { - parent_pid = pe.th32ParentProcessID; - break; - } - } while( Process32Next(handle, &pe)); - } - - CloseHandle(handle); - return parent_pid; -} - - -int uv_current_pid() { - if (current_pid == 0) { - current_pid = GetCurrentProcessId(); - } - return current_pid; -} - - -char** uv_setup_args(int argc, char** argv) { - return argv; -} - - -int uv_set_process_title(const char* title) { - int err; - int length; - WCHAR* title_w = NULL; - - uv__once_init(); - - /* Find out how big the buffer for the wide-char title must be */ - length = MultiByteToWideChar(CP_UTF8, 0, title, -1, NULL, 0); - if (!length) { - err = GetLastError(); - goto done; - } - - /* Convert to wide-char string */ - title_w = (WCHAR*)uv__malloc(sizeof(WCHAR) * length); - if (!title_w) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - length = MultiByteToWideChar(CP_UTF8, 0, title, -1, title_w, length); - if (!length) { - err = GetLastError(); - goto done; - } - - /* If the title must be truncated insert a \0 terminator there */ - if (length > MAX_TITLE_LENGTH) { - title_w[MAX_TITLE_LENGTH - 1] = L'\0'; - } - - if (!SetConsoleTitleW(title_w)) { - err = GetLastError(); - goto done; - } - - EnterCriticalSection(&process_title_lock); - uv__free(process_title); - process_title = uv__strdup(title); - LeaveCriticalSection(&process_title_lock); - - err = 0; - -done: - uv__free(title_w); - return uv_translate_sys_error(err); -} - - -static int uv__get_process_title() { - WCHAR title_w[MAX_TITLE_LENGTH]; - int length; - - if (!GetConsoleTitleW(title_w, sizeof(title_w) / sizeof(WCHAR))) { - return -1; - } - - /* Find out what the size of the buffer is that we need */ - length = WideCharToMultiByte(CP_UTF8, 0, title_w, -1, NULL, 0, NULL, NULL); - if (!length) { - return -1; - } - - assert(!process_title); - process_title = (char*)uv__malloc(length); - if (!process_title) { - uv_fatal_error(ERROR_OUTOFMEMORY, "uv__malloc"); - } - - /* Do utf16 -> utf8 conversion here */ - if (!WideCharToMultiByte(CP_UTF8, - 0, - title_w, - -1, - process_title, - length, - NULL, - NULL)) { - uv__free(process_title); - return -1; - } - - return 0; -} - - -int uv_get_process_title(char* buffer, size_t size) { - uv__once_init(); - - EnterCriticalSection(&process_title_lock); - /* - * If the process_title was never read before nor explicitly set, - * we must query it with getConsoleTitleW - */ - if (!process_title && uv__get_process_title() == -1) { - LeaveCriticalSection(&process_title_lock); - return uv_translate_sys_error(GetLastError()); - } - - assert(process_title); - strncpy(buffer, process_title, size); - LeaveCriticalSection(&process_title_lock); - - return 0; -} - - -uint64_t uv_hrtime(void) { - uv__once_init(); - return uv__hrtime(UV__NANOSEC); -} - -uint64_t uv__hrtime(double scale) { - LARGE_INTEGER counter; - - /* If the performance interval is zero, there's no support. */ - if (hrtime_interval_ == 0) { - return 0; - } - - if (!QueryPerformanceCounter(&counter)) { - return 0; - } - - /* Because we have no guarantee about the order of magnitude of the - * performance counter interval, integer math could cause this computation - * to overflow. Therefore we resort to floating point math. - */ - return (uint64_t) ((double) counter.QuadPart * hrtime_interval_ * scale); -} - - -int uv_resident_set_memory(size_t* rss) { - HANDLE current_process; - PROCESS_MEMORY_COUNTERS pmc; - - current_process = GetCurrentProcess(); - - if (!GetProcessMemoryInfo(current_process, &pmc, sizeof(pmc))) { - return uv_translate_sys_error(GetLastError()); - } - - *rss = pmc.WorkingSetSize; - - return 0; -} - - -int uv_uptime(double* uptime) { - BYTE stack_buffer[4096]; - BYTE* malloced_buffer = NULL; - BYTE* buffer = (BYTE*) stack_buffer; - size_t buffer_size = sizeof(stack_buffer); - DWORD data_size; - - PERF_DATA_BLOCK* data_block; - PERF_OBJECT_TYPE* object_type; - PERF_COUNTER_DEFINITION* counter_definition; - - DWORD i; - - for (;;) { - LONG result; - - data_size = (DWORD) buffer_size; - result = RegQueryValueExW(HKEY_PERFORMANCE_DATA, - L"2", - NULL, - NULL, - buffer, - &data_size); - if (result == ERROR_SUCCESS) { - break; - } else if (result != ERROR_MORE_DATA) { - *uptime = 0; - return uv_translate_sys_error(result); - } - - buffer_size *= 2; - /* Don't let the buffer grow infinitely. */ - if (buffer_size > 1 << 20) { - goto internalError; - } - - uv__free(malloced_buffer); - - buffer = malloced_buffer = (BYTE*) uv__malloc(buffer_size); - if (malloced_buffer == NULL) { - *uptime = 0; - return UV_ENOMEM; - } - } - - if (data_size < sizeof(*data_block)) - goto internalError; - - data_block = (PERF_DATA_BLOCK*) buffer; - - if (wmemcmp(data_block->Signature, L"PERF", 4) != 0) - goto internalError; - - if (data_size < data_block->HeaderLength + sizeof(*object_type)) - goto internalError; - - object_type = (PERF_OBJECT_TYPE*) (buffer + data_block->HeaderLength); - - if (object_type->NumInstances != PERF_NO_INSTANCES) - goto internalError; - - counter_definition = (PERF_COUNTER_DEFINITION*) (buffer + - data_block->HeaderLength + object_type->HeaderLength); - for (i = 0; i < object_type->NumCounters; i++) { - if ((BYTE*) counter_definition + sizeof(*counter_definition) > - buffer + data_size) { - break; - } - - if (counter_definition->CounterNameTitleIndex == 674 && - counter_definition->CounterSize == sizeof(uint64_t)) { - if (counter_definition->CounterOffset + sizeof(uint64_t) > data_size || - !(counter_definition->CounterType & PERF_OBJECT_TIMER)) { - goto internalError; - } else { - BYTE* address = (BYTE*) object_type + object_type->DefinitionLength + - counter_definition->CounterOffset; - uint64_t value = *((uint64_t*) address); - *uptime = (double) (object_type->PerfTime.QuadPart - value) / - (double) object_type->PerfFreq.QuadPart; - uv__free(malloced_buffer); - return 0; - } - } - - counter_definition = (PERF_COUNTER_DEFINITION*) - ((BYTE*) counter_definition + counter_definition->ByteLength); - } - - /* If we get here, the uptime value was not found. */ - uv__free(malloced_buffer); - *uptime = 0; - return UV_ENOSYS; - - internalError: - uv__free(malloced_buffer); - *uptime = 0; - return UV_EIO; -} - - -int uv_cpu_info(uv_cpu_info_t** cpu_infos_ptr, int* cpu_count_ptr) { - uv_cpu_info_t* cpu_infos; - SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION* sppi; - DWORD sppi_size; - SYSTEM_INFO system_info; - DWORD cpu_count, r, i; - NTSTATUS status; - ULONG result_size; - int err; - uv_cpu_info_t* cpu_info; - - cpu_infos = NULL; - cpu_count = 0; - sppi = NULL; - - uv__once_init(); - - GetSystemInfo(&system_info); - cpu_count = system_info.dwNumberOfProcessors; - - cpu_infos = uv__calloc(cpu_count, sizeof *cpu_infos); - if (cpu_infos == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - sppi_size = cpu_count * sizeof(*sppi); - sppi = uv__malloc(sppi_size); - if (sppi == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - status = pNtQuerySystemInformation(SystemProcessorPerformanceInformation, - sppi, - sppi_size, - &result_size); - if (!NT_SUCCESS(status)) { - err = pRtlNtStatusToDosError(status); - goto error; - } - - assert(result_size == sppi_size); - - for (i = 0; i < cpu_count; i++) { - WCHAR key_name[128]; - HKEY processor_key; - DWORD cpu_speed; - DWORD cpu_speed_size = sizeof(cpu_speed); - WCHAR cpu_brand[256]; - DWORD cpu_brand_size = sizeof(cpu_brand); - size_t len; - - len = _snwprintf(key_name, - ARRAY_SIZE(key_name), - L"HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\%d", - i); - - assert(len > 0 && len < ARRAY_SIZE(key_name)); - - r = RegOpenKeyExW(HKEY_LOCAL_MACHINE, - key_name, - 0, - KEY_QUERY_VALUE, - &processor_key); - if (r != ERROR_SUCCESS) { - err = GetLastError(); - goto error; - } - - if (RegQueryValueExW(processor_key, - L"~MHz", - NULL, - NULL, - (BYTE*) &cpu_speed, - &cpu_speed_size) != ERROR_SUCCESS) { - err = GetLastError(); - RegCloseKey(processor_key); - goto error; - } - - if (RegQueryValueExW(processor_key, - L"ProcessorNameString", - NULL, - NULL, - (BYTE*) &cpu_brand, - &cpu_brand_size) != ERROR_SUCCESS) { - err = GetLastError(); - RegCloseKey(processor_key); - goto error; - } - - RegCloseKey(processor_key); - - cpu_info = &cpu_infos[i]; - cpu_info->speed = cpu_speed; - cpu_info->cpu_times.user = sppi[i].UserTime.QuadPart / 10000; - cpu_info->cpu_times.sys = (sppi[i].KernelTime.QuadPart - - sppi[i].IdleTime.QuadPart) / 10000; - cpu_info->cpu_times.idle = sppi[i].IdleTime.QuadPart / 10000; - cpu_info->cpu_times.irq = sppi[i].InterruptTime.QuadPart / 10000; - cpu_info->cpu_times.nice = 0; - - - len = WideCharToMultiByte(CP_UTF8, - 0, - cpu_brand, - cpu_brand_size / sizeof(WCHAR), - NULL, - 0, - NULL, - NULL); - if (len == 0) { - err = GetLastError(); - goto error; - } - - assert(len > 0); - - /* Allocate 1 extra byte for the null terminator. */ - cpu_info->model = uv__malloc(len + 1); - if (cpu_info->model == NULL) { - err = ERROR_OUTOFMEMORY; - goto error; - } - - if (WideCharToMultiByte(CP_UTF8, - 0, - cpu_brand, - cpu_brand_size / sizeof(WCHAR), - cpu_info->model, - len, - NULL, - NULL) == 0) { - err = GetLastError(); - goto error; - } - - /* Ensure that cpu_info->model is null terminated. */ - cpu_info->model[len] = '\0'; - } - - uv__free(sppi); - - *cpu_count_ptr = cpu_count; - *cpu_infos_ptr = cpu_infos; - - return 0; - - error: - /* This is safe because the cpu_infos array is zeroed on allocation. */ - for (i = 0; i < cpu_count; i++) - uv__free(cpu_infos[i].model); - - uv__free(cpu_infos); - uv__free(sppi); - - return uv_translate_sys_error(err); -} - - -void uv_free_cpu_info(uv_cpu_info_t* cpu_infos, int count) { - int i; - - for (i = 0; i < count; i++) { - uv__free(cpu_infos[i].model); - } - - uv__free(cpu_infos); -} - - -static int is_windows_version_or_greater(DWORD os_major, - DWORD os_minor, - WORD service_pack_major, - WORD service_pack_minor) { - OSVERSIONINFOEX osvi; - DWORDLONG condition_mask = 0; - int op = VER_GREATER_EQUAL; - - /* Initialize the OSVERSIONINFOEX structure. */ - ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); - osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); - osvi.dwMajorVersion = os_major; - osvi.dwMinorVersion = os_minor; - osvi.wServicePackMajor = service_pack_major; - osvi.wServicePackMinor = service_pack_minor; - - /* Initialize the condition mask. */ - VER_SET_CONDITION(condition_mask, VER_MAJORVERSION, op); - VER_SET_CONDITION(condition_mask, VER_MINORVERSION, op); - VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMAJOR, op); - VER_SET_CONDITION(condition_mask, VER_SERVICEPACKMINOR, op); - - /* Perform the test. */ - return (int) VerifyVersionInfo( - &osvi, - VER_MAJORVERSION | VER_MINORVERSION | - VER_SERVICEPACKMAJOR | VER_SERVICEPACKMINOR, - condition_mask); -} - - -static int address_prefix_match(int family, - struct sockaddr* address, - struct sockaddr* prefix_address, - int prefix_len) { - uint8_t* address_data; - uint8_t* prefix_address_data; - int i; - - assert(address->sa_family == family); - assert(prefix_address->sa_family == family); - - if (family == AF_INET6) { - address_data = (uint8_t*) &(((struct sockaddr_in6 *) address)->sin6_addr); - prefix_address_data = - (uint8_t*) &(((struct sockaddr_in6 *) prefix_address)->sin6_addr); - } else { - address_data = (uint8_t*) &(((struct sockaddr_in *) address)->sin_addr); - prefix_address_data = - (uint8_t*) &(((struct sockaddr_in *) prefix_address)->sin_addr); - } - - for (i = 0; i < prefix_len >> 3; i++) { - if (address_data[i] != prefix_address_data[i]) - return 0; - } - - if (prefix_len % 8) - return prefix_address_data[i] == - (address_data[i] & (0xff << (8 - prefix_len % 8))); - - return 1; -} - - -int uv_interface_addresses(uv_interface_address_t** addresses_ptr, - int* count_ptr) { - IP_ADAPTER_ADDRESSES* win_address_buf; - ULONG win_address_buf_size; - IP_ADAPTER_ADDRESSES* adapter; - - uv_interface_address_t* uv_address_buf; - char* name_buf; - size_t uv_address_buf_size; - uv_interface_address_t* uv_address; - - int count; - - int is_vista_or_greater; - ULONG flags; - - is_vista_or_greater = is_windows_version_or_greater(6, 0, 0, 0); - if (is_vista_or_greater) { - flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER; - } else { - /* We need at least XP SP1. */ - if (!is_windows_version_or_greater(5, 1, 1, 0)) - return UV_ENOTSUP; - - flags = GAA_FLAG_SKIP_ANYCAST | GAA_FLAG_SKIP_MULTICAST | - GAA_FLAG_SKIP_DNS_SERVER | GAA_FLAG_INCLUDE_PREFIX; - } - - - /* Fetch the size of the adapters reported by windows, and then get the */ - /* list itself. */ - win_address_buf_size = 0; - win_address_buf = NULL; - - for (;;) { - ULONG r; - - /* If win_address_buf is 0, then GetAdaptersAddresses will fail with */ - /* ERROR_BUFFER_OVERFLOW, and the required buffer size will be stored in */ - /* win_address_buf_size. */ - r = GetAdaptersAddresses(AF_UNSPEC, - flags, - NULL, - win_address_buf, - &win_address_buf_size); - - if (r == ERROR_SUCCESS) - break; - - uv__free(win_address_buf); - - switch (r) { - case ERROR_BUFFER_OVERFLOW: - /* This happens when win_address_buf is NULL or too small to hold */ - /* all adapters. */ - win_address_buf = uv__malloc(win_address_buf_size); - if (win_address_buf == NULL) - return UV_ENOMEM; - - continue; - - case ERROR_NO_DATA: { - /* No adapters were found. */ - uv_address_buf = uv__malloc(1); - if (uv_address_buf == NULL) - return UV_ENOMEM; - - *count_ptr = 0; - *addresses_ptr = uv_address_buf; - - return 0; - } - - case ERROR_ADDRESS_NOT_ASSOCIATED: - return UV_EAGAIN; - - case ERROR_INVALID_PARAMETER: - /* MSDN says: - * "This error is returned for any of the following conditions: the - * SizePointer parameter is NULL, the Address parameter is not - * AF_INET, AF_INET6, or AF_UNSPEC, or the address information for - * the parameters requested is greater than ULONG_MAX." - * Since the first two conditions are not met, it must be that the - * adapter data is too big. - */ - return UV_ENOBUFS; - - default: - /* Other (unspecified) errors can happen, but we don't have any */ - /* special meaning for them. */ - assert(r != ERROR_SUCCESS); - return uv_translate_sys_error(r); - } - } - - /* Count the number of enabled interfaces and compute how much space is */ - /* needed to store their info. */ - count = 0; - uv_address_buf_size = 0; - - for (adapter = win_address_buf; - adapter != NULL; - adapter = adapter->Next) { - IP_ADAPTER_UNICAST_ADDRESS* unicast_address; - int name_size; - - /* Interfaces that are not 'up' should not be reported. Also skip */ - /* interfaces that have no associated unicast address, as to avoid */ - /* allocating space for the name for this interface. */ - if (adapter->OperStatus != IfOperStatusUp || - adapter->FirstUnicastAddress == NULL) - continue; - - /* Compute the size of the interface name. */ - name_size = WideCharToMultiByte(CP_UTF8, - 0, - adapter->FriendlyName, - -1, - NULL, - 0, - NULL, - FALSE); - if (name_size <= 0) { - uv__free(win_address_buf); - return uv_translate_sys_error(GetLastError()); - } - uv_address_buf_size += name_size; - - /* Count the number of addresses associated with this interface, and */ - /* compute the size. */ - for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*) - adapter->FirstUnicastAddress; - unicast_address != NULL; - unicast_address = unicast_address->Next) { - count++; - uv_address_buf_size += sizeof(uv_interface_address_t); - } - } - - /* Allocate space to store interface data plus adapter names. */ - uv_address_buf = uv__malloc(uv_address_buf_size); - if (uv_address_buf == NULL) { - uv__free(win_address_buf); - return UV_ENOMEM; - } - - /* Compute the start of the uv_interface_address_t array, and the place in */ - /* the buffer where the interface names will be stored. */ - uv_address = uv_address_buf; - name_buf = (char*) (uv_address_buf + count); - - /* Fill out the output buffer. */ - for (adapter = win_address_buf; - adapter != NULL; - adapter = adapter->Next) { - IP_ADAPTER_UNICAST_ADDRESS* unicast_address; - int name_size; - size_t max_name_size; - - if (adapter->OperStatus != IfOperStatusUp || - adapter->FirstUnicastAddress == NULL) - continue; - - /* Convert the interface name to UTF8. */ - max_name_size = (char*) uv_address_buf + uv_address_buf_size - name_buf; - if (max_name_size > (size_t) INT_MAX) - max_name_size = INT_MAX; - name_size = WideCharToMultiByte(CP_UTF8, - 0, - adapter->FriendlyName, - -1, - name_buf, - (int) max_name_size, - NULL, - FALSE); - if (name_size <= 0) { - uv__free(win_address_buf); - uv__free(uv_address_buf); - return uv_translate_sys_error(GetLastError()); - } - - /* Add an uv_interface_address_t element for every unicast address. */ - for (unicast_address = (IP_ADAPTER_UNICAST_ADDRESS*) - adapter->FirstUnicastAddress; - unicast_address != NULL; - unicast_address = unicast_address->Next) { - struct sockaddr* sa; - ULONG prefix_len; - - sa = unicast_address->Address.lpSockaddr; - - /* XP has no OnLinkPrefixLength field. */ - if (is_vista_or_greater) { - prefix_len = - ((IP_ADAPTER_UNICAST_ADDRESS_LH*) unicast_address)->OnLinkPrefixLength; - } else { - /* Prior to Windows Vista the FirstPrefix pointed to the list with - * single prefix for each IP address assigned to the adapter. - * Order of FirstPrefix does not match order of FirstUnicastAddress, - * so we need to find corresponding prefix. - */ - IP_ADAPTER_PREFIX* prefix; - prefix_len = 0; - - for (prefix = adapter->FirstPrefix; prefix; prefix = prefix->Next) { - /* We want the longest matching prefix. */ - if (prefix->Address.lpSockaddr->sa_family != sa->sa_family || - prefix->PrefixLength <= prefix_len) - continue; - - if (address_prefix_match(sa->sa_family, sa, - prefix->Address.lpSockaddr, prefix->PrefixLength)) { - prefix_len = prefix->PrefixLength; - } - } - - /* If there is no matching prefix information, return a single-host - * subnet mask (e.g. 255.255.255.255 for IPv4). - */ - if (!prefix_len) - prefix_len = (sa->sa_family == AF_INET6) ? 128 : 32; - } - - memset(uv_address, 0, sizeof *uv_address); - - uv_address->name = name_buf; - - if (adapter->PhysicalAddressLength == sizeof(uv_address->phys_addr)) { - memcpy(uv_address->phys_addr, - adapter->PhysicalAddress, - sizeof(uv_address->phys_addr)); - } - - uv_address->is_internal = - (adapter->IfType == IF_TYPE_SOFTWARE_LOOPBACK); - - if (sa->sa_family == AF_INET6) { - uv_address->address.address6 = *((struct sockaddr_in6 *) sa); - - uv_address->netmask.netmask6.sin6_family = AF_INET6; - memset(uv_address->netmask.netmask6.sin6_addr.s6_addr, 0xff, prefix_len >> 3); - /* This check ensures that we don't write past the size of the data. */ - if (prefix_len % 8) { - uv_address->netmask.netmask6.sin6_addr.s6_addr[prefix_len >> 3] = - 0xff << (8 - prefix_len % 8); - } - - } else { - uv_address->address.address4 = *((struct sockaddr_in *) sa); - - uv_address->netmask.netmask4.sin_family = AF_INET; - uv_address->netmask.netmask4.sin_addr.s_addr = (prefix_len > 0) ? - htonl(0xffffffff << (32 - prefix_len)) : 0; - } - - uv_address++; - } - - name_buf += name_size; - } - - uv__free(win_address_buf); - - *addresses_ptr = uv_address_buf; - *count_ptr = count; - - return 0; -} - - -void uv_free_interface_addresses(uv_interface_address_t* addresses, - int count) { - uv__free(addresses); -} - - -int uv_getrusage(uv_rusage_t *uv_rusage) { - FILETIME createTime, exitTime, kernelTime, userTime; - SYSTEMTIME kernelSystemTime, userSystemTime; - int ret; - - ret = GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime, &userTime); - if (ret == 0) { - return uv_translate_sys_error(GetLastError()); - } - - ret = FileTimeToSystemTime(&kernelTime, &kernelSystemTime); - if (ret == 0) { - return uv_translate_sys_error(GetLastError()); - } - - ret = FileTimeToSystemTime(&userTime, &userSystemTime); - if (ret == 0) { - return uv_translate_sys_error(GetLastError()); - } - - memset(uv_rusage, 0, sizeof(*uv_rusage)); - - uv_rusage->ru_utime.tv_sec = userSystemTime.wHour * 3600 + - userSystemTime.wMinute * 60 + - userSystemTime.wSecond; - uv_rusage->ru_utime.tv_usec = userSystemTime.wMilliseconds * 1000; - - uv_rusage->ru_stime.tv_sec = kernelSystemTime.wHour * 3600 + - kernelSystemTime.wMinute * 60 + - kernelSystemTime.wSecond; - uv_rusage->ru_stime.tv_usec = kernelSystemTime.wMilliseconds * 1000; - - return 0; -} - - -int uv_os_homedir(char* buffer, size_t* size) { - uv_passwd_t pwd; - wchar_t path[MAX_PATH]; - DWORD bufsize; - size_t len; - int r; - - if (buffer == NULL || size == NULL || *size == 0) - return UV_EINVAL; - - /* Check if the USERPROFILE environment variable is set first */ - len = GetEnvironmentVariableW(L"USERPROFILE", path, MAX_PATH); - - if (len == 0) { - r = GetLastError(); - - /* Don't return an error if USERPROFILE was not found */ - if (r != ERROR_ENVVAR_NOT_FOUND) - return uv_translate_sys_error(r); - } else if (len > MAX_PATH) { - /* This should not be possible */ - return UV_EIO; - } else { - /* Check how much space we need */ - bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL); - - if (bufsize == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (bufsize > *size) { - *size = bufsize; - return UV_ENOBUFS; - } - - /* Convert to UTF-8 */ - bufsize = WideCharToMultiByte(CP_UTF8, - 0, - path, - -1, - buffer, - *size, - NULL, - NULL); - - if (bufsize == 0) - return uv_translate_sys_error(GetLastError()); - - *size = bufsize - 1; - return 0; - } - - /* USERPROFILE is not set, so call uv__getpwuid_r() */ - r = uv__getpwuid_r(&pwd); - - if (r != 0) { - return r; - } - - len = strlen(pwd.homedir); - - if (len >= *size) { - *size = len + 1; - uv_os_free_passwd(&pwd); - return UV_ENOBUFS; - } - - memcpy(buffer, pwd.homedir, len + 1); - *size = len; - uv_os_free_passwd(&pwd); - - return 0; -} - - -int uv_os_tmpdir(char* buffer, size_t* size) { - wchar_t path[MAX_PATH + 1]; - DWORD bufsize; - size_t len; - - if (buffer == NULL || size == NULL || *size == 0) - return UV_EINVAL; - - len = GetTempPathW(MAX_PATH + 1, path); - - if (len == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (len > MAX_PATH + 1) { - /* This should not be possible */ - return UV_EIO; - } - - /* The returned directory should not have a trailing slash, unless it */ - /* points at a drive root, like c:\. Remove it if needed.*/ - if (path[len - 1] == L'\\' && - !(len == 3 && path[1] == L':')) { - len--; - path[len] = L'\0'; - } - - /* Check how much space we need */ - bufsize = WideCharToMultiByte(CP_UTF8, 0, path, -1, NULL, 0, NULL, NULL); - - if (bufsize == 0) { - return uv_translate_sys_error(GetLastError()); - } else if (bufsize > *size) { - *size = bufsize; - return UV_ENOBUFS; - } - - /* Convert to UTF-8 */ - bufsize = WideCharToMultiByte(CP_UTF8, - 0, - path, - -1, - buffer, - *size, - NULL, - NULL); - - if (bufsize == 0) - return uv_translate_sys_error(GetLastError()); - - *size = bufsize - 1; - return 0; -} - - -void uv_os_free_passwd(uv_passwd_t* pwd) { - if (pwd == NULL) - return; - - uv__free(pwd->username); - uv__free(pwd->homedir); - pwd->username = NULL; - pwd->homedir = NULL; -} - - -int uv__convert_utf16_to_utf8(const WCHAR* utf16, char** utf8) { - DWORD bufsize; - - if (utf16 == NULL) - return UV_EINVAL; - - /* Check how much space we need */ - bufsize = WideCharToMultiByte(CP_UTF8, 0, utf16, -1, NULL, 0, NULL, NULL); - - if (bufsize == 0) - return uv_translate_sys_error(GetLastError()); - - /* Allocate the destination buffer */ - *utf8 = uv__malloc(bufsize); - - if (*utf8 == NULL) - return UV_ENOMEM; - - /* Convert to UTF-8 */ - bufsize = WideCharToMultiByte(CP_UTF8, - 0, - utf16, - -1, - *utf8, - bufsize, - NULL, - NULL); - - if (bufsize == 0) { - uv__free(*utf8); - return uv_translate_sys_error(GetLastError()); - } - - return 0; -} - - -int uv__getpwuid_r(uv_passwd_t* pwd) { - HANDLE token; - wchar_t username[UNLEN + 1]; - wchar_t path[MAX_PATH]; - DWORD bufsize; - int r; - - if (pwd == NULL) - return UV_EINVAL; - - /* Get the home directory using GetUserProfileDirectoryW() */ - if (OpenProcessToken(GetCurrentProcess(), TOKEN_READ, &token) == 0) - return uv_translate_sys_error(GetLastError()); - - bufsize = sizeof(path); - if (!GetUserProfileDirectoryW(token, path, &bufsize)) { - r = GetLastError(); - CloseHandle(token); - - /* This should not be possible */ - if (r == ERROR_INSUFFICIENT_BUFFER) - return UV_ENOMEM; - - return uv_translate_sys_error(r); - } - - CloseHandle(token); - - /* Get the username using GetUserNameW() */ - bufsize = sizeof(username); - if (!GetUserNameW(username, &bufsize)) { - r = GetLastError(); - - /* This should not be possible */ - if (r == ERROR_INSUFFICIENT_BUFFER) - return UV_ENOMEM; - - return uv_translate_sys_error(r); - } - - pwd->homedir = NULL; - r = uv__convert_utf16_to_utf8(path, &pwd->homedir); - - if (r != 0) - return r; - - pwd->username = NULL; - r = uv__convert_utf16_to_utf8(username, &pwd->username); - - if (r != 0) { - uv__free(pwd->homedir); - return r; - } - - pwd->shell = NULL; - pwd->uid = -1; - pwd->gid = -1; - - return 0; -} - - -int uv_os_get_passwd(uv_passwd_t* pwd) { - return uv__getpwuid_r(pwd); -} diff --git a/3rdparty/libuv/src/win/winapi.c b/3rdparty/libuv/src/win/winapi.c deleted file mode 100644 index 26bd0648668..00000000000 --- a/3rdparty/libuv/src/win/winapi.c +++ /dev/null @@ -1,146 +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. - */ - -#include <assert.h> - -#include "uv.h" -#include "internal.h" - - -/* Ntdll function pointers */ -sRtlNtStatusToDosError pRtlNtStatusToDosError; -sNtDeviceIoControlFile pNtDeviceIoControlFile; -sNtQueryInformationFile pNtQueryInformationFile; -sNtSetInformationFile pNtSetInformationFile; -sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; -sNtQueryDirectoryFile pNtQueryDirectoryFile; -sNtQuerySystemInformation pNtQuerySystemInformation; - - -/* Kernel32 function pointers */ -sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; -sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes; -sCreateSymbolicLinkW pCreateSymbolicLinkW; -sCancelIoEx pCancelIoEx; -sInitializeConditionVariable pInitializeConditionVariable; -sSleepConditionVariableCS pSleepConditionVariableCS; -sSleepConditionVariableSRW pSleepConditionVariableSRW; -sWakeAllConditionVariable pWakeAllConditionVariable; -sWakeConditionVariable pWakeConditionVariable; -sCancelSynchronousIo pCancelSynchronousIo; -sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW; - - -void uv_winapi_init() { - HMODULE ntdll_module; - HMODULE kernel32_module; - - ntdll_module = GetModuleHandleA("ntdll.dll"); - if (ntdll_module == NULL) { - uv_fatal_error(GetLastError(), "GetModuleHandleA"); - } - - pRtlNtStatusToDosError = (sRtlNtStatusToDosError) GetProcAddress( - ntdll_module, - "RtlNtStatusToDosError"); - if (pRtlNtStatusToDosError == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtDeviceIoControlFile = (sNtDeviceIoControlFile) GetProcAddress( - ntdll_module, - "NtDeviceIoControlFile"); - if (pNtDeviceIoControlFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQueryInformationFile = (sNtQueryInformationFile) GetProcAddress( - ntdll_module, - "NtQueryInformationFile"); - if (pNtQueryInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtSetInformationFile = (sNtSetInformationFile) GetProcAddress( - ntdll_module, - "NtSetInformationFile"); - if (pNtSetInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQueryVolumeInformationFile = (sNtQueryVolumeInformationFile) - GetProcAddress(ntdll_module, "NtQueryVolumeInformationFile"); - if (pNtQueryVolumeInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQueryDirectoryFile = (sNtQueryDirectoryFile) - GetProcAddress(ntdll_module, "NtQueryDirectoryFile"); - if (pNtQueryVolumeInformationFile == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - pNtQuerySystemInformation = (sNtQuerySystemInformation) GetProcAddress( - ntdll_module, - "NtQuerySystemInformation"); - if (pNtQuerySystemInformation == NULL) { - uv_fatal_error(GetLastError(), "GetProcAddress"); - } - - kernel32_module = GetModuleHandleA("kernel32.dll"); - if (kernel32_module == NULL) { - uv_fatal_error(GetLastError(), "GetModuleHandleA"); - } - - pGetQueuedCompletionStatusEx = (sGetQueuedCompletionStatusEx) GetProcAddress( - kernel32_module, - "GetQueuedCompletionStatusEx"); - - pSetFileCompletionNotificationModes = (sSetFileCompletionNotificationModes) - GetProcAddress(kernel32_module, "SetFileCompletionNotificationModes"); - - pCreateSymbolicLinkW = (sCreateSymbolicLinkW) - GetProcAddress(kernel32_module, "CreateSymbolicLinkW"); - - pCancelIoEx = (sCancelIoEx) - GetProcAddress(kernel32_module, "CancelIoEx"); - - pInitializeConditionVariable = (sInitializeConditionVariable) - GetProcAddress(kernel32_module, "InitializeConditionVariable"); - - pSleepConditionVariableCS = (sSleepConditionVariableCS) - GetProcAddress(kernel32_module, "SleepConditionVariableCS"); - - pSleepConditionVariableSRW = (sSleepConditionVariableSRW) - GetProcAddress(kernel32_module, "SleepConditionVariableSRW"); - - pWakeAllConditionVariable = (sWakeAllConditionVariable) - GetProcAddress(kernel32_module, "WakeAllConditionVariable"); - - pWakeConditionVariable = (sWakeConditionVariable) - GetProcAddress(kernel32_module, "WakeConditionVariable"); - - pCancelSynchronousIo = (sCancelSynchronousIo) - GetProcAddress(kernel32_module, "CancelSynchronousIo"); - - pGetFinalPathNameByHandleW = (sGetFinalPathNameByHandleW) - GetProcAddress(kernel32_module, "GetFinalPathNameByHandleW"); -} diff --git a/3rdparty/libuv/src/win/winapi.h b/3rdparty/libuv/src/win/winapi.h deleted file mode 100644 index 122198a6d48..00000000000 --- a/3rdparty/libuv/src/win/winapi.h +++ /dev/null @@ -1,4710 +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_WINAPI_H_ -#define UV_WIN_WINAPI_H_ - -#include <windows.h> - - -/* - * Ntdll headers - */ -#ifndef STATUS_SEVERITY_SUCCESS -# define STATUS_SEVERITY_SUCCESS 0x0 -#endif - -#ifndef STATUS_SEVERITY_INFORMATIONAL -# define STATUS_SEVERITY_INFORMATIONAL 0x1 -#endif - -#ifndef STATUS_SEVERITY_WARNING -# define STATUS_SEVERITY_WARNING 0x2 -#endif - -#ifndef STATUS_SEVERITY_ERROR -# define STATUS_SEVERITY_ERROR 0x3 -#endif - -#ifndef FACILITY_NTWIN32 -# define FACILITY_NTWIN32 0x7 -#endif - -#ifndef NT_SUCCESS -# define NT_SUCCESS(status) (((NTSTATUS) (status)) >= 0) -#endif - -#ifndef NT_INFORMATION -# define NT_INFORMATION(status) ((((ULONG) (status)) >> 30) == 1) -#endif - -#ifndef NT_WARNING -# define NT_WARNING(status) ((((ULONG) (status)) >> 30) == 2) -#endif - -#ifndef NT_ERROR -# define NT_ERROR(status) ((((ULONG) (status)) >> 30) == 3) -#endif - -#ifndef STATUS_SUCCESS -# define STATUS_SUCCESS ((NTSTATUS) 0x00000000L) -#endif - -#ifndef STATUS_WAIT_0 -# define STATUS_WAIT_0 ((NTSTATUS) 0x00000000L) -#endif - -#ifndef STATUS_WAIT_1 -# define STATUS_WAIT_1 ((NTSTATUS) 0x00000001L) -#endif - -#ifndef STATUS_WAIT_2 -# define STATUS_WAIT_2 ((NTSTATUS) 0x00000002L) -#endif - -#ifndef STATUS_WAIT_3 -# define STATUS_WAIT_3 ((NTSTATUS) 0x00000003L) -#endif - -#ifndef STATUS_WAIT_63 -# define STATUS_WAIT_63 ((NTSTATUS) 0x0000003FL) -#endif - -#ifndef STATUS_ABANDONED -# define STATUS_ABANDONED ((NTSTATUS) 0x00000080L) -#endif - -#ifndef STATUS_ABANDONED_WAIT_0 -# define STATUS_ABANDONED_WAIT_0 ((NTSTATUS) 0x00000080L) -#endif - -#ifndef STATUS_ABANDONED_WAIT_63 -# define STATUS_ABANDONED_WAIT_63 ((NTSTATUS) 0x000000BFL) -#endif - -#ifndef STATUS_USER_APC -# define STATUS_USER_APC ((NTSTATUS) 0x000000C0L) -#endif - -#ifndef STATUS_KERNEL_APC -# define STATUS_KERNEL_APC ((NTSTATUS) 0x00000100L) -#endif - -#ifndef STATUS_ALERTED -# define STATUS_ALERTED ((NTSTATUS) 0x00000101L) -#endif - -#ifndef STATUS_TIMEOUT -# define STATUS_TIMEOUT ((NTSTATUS) 0x00000102L) -#endif - -#ifndef STATUS_PENDING -# define STATUS_PENDING ((NTSTATUS) 0x00000103L) -#endif - -#ifndef STATUS_REPARSE -# define STATUS_REPARSE ((NTSTATUS) 0x00000104L) -#endif - -#ifndef STATUS_MORE_ENTRIES -# define STATUS_MORE_ENTRIES ((NTSTATUS) 0x00000105L) -#endif - -#ifndef STATUS_NOT_ALL_ASSIGNED -# define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106L) -#endif - -#ifndef STATUS_SOME_NOT_MAPPED -# define STATUS_SOME_NOT_MAPPED ((NTSTATUS) 0x00000107L) -#endif - -#ifndef STATUS_OPLOCK_BREAK_IN_PROGRESS -# define STATUS_OPLOCK_BREAK_IN_PROGRESS ((NTSTATUS) 0x00000108L) -#endif - -#ifndef STATUS_VOLUME_MOUNTED -# define STATUS_VOLUME_MOUNTED ((NTSTATUS) 0x00000109L) -#endif - -#ifndef STATUS_RXACT_COMMITTED -# define STATUS_RXACT_COMMITTED ((NTSTATUS) 0x0000010AL) -#endif - -#ifndef STATUS_NOTIFY_CLEANUP -# define STATUS_NOTIFY_CLEANUP ((NTSTATUS) 0x0000010BL) -#endif - -#ifndef STATUS_NOTIFY_ENUM_DIR -# define STATUS_NOTIFY_ENUM_DIR ((NTSTATUS) 0x0000010CL) -#endif - -#ifndef STATUS_NO_QUOTAS_FOR_ACCOUNT -# define STATUS_NO_QUOTAS_FOR_ACCOUNT ((NTSTATUS) 0x0000010DL) -#endif - -#ifndef STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED -# define STATUS_PRIMARY_TRANSPORT_CONNECT_FAILED ((NTSTATUS) 0x0000010EL) -#endif - -#ifndef STATUS_PAGE_FAULT_TRANSITION -# define STATUS_PAGE_FAULT_TRANSITION ((NTSTATUS) 0x00000110L) -#endif - -#ifndef STATUS_PAGE_FAULT_DEMAND_ZERO -# define STATUS_PAGE_FAULT_DEMAND_ZERO ((NTSTATUS) 0x00000111L) -#endif - -#ifndef STATUS_PAGE_FAULT_COPY_ON_WRITE -# define STATUS_PAGE_FAULT_COPY_ON_WRITE ((NTSTATUS) 0x00000112L) -#endif - -#ifndef STATUS_PAGE_FAULT_GUARD_PAGE -# define STATUS_PAGE_FAULT_GUARD_PAGE ((NTSTATUS) 0x00000113L) -#endif - -#ifndef STATUS_PAGE_FAULT_PAGING_FILE -# define STATUS_PAGE_FAULT_PAGING_FILE ((NTSTATUS) 0x00000114L) -#endif - -#ifndef STATUS_CACHE_PAGE_LOCKED -# define STATUS_CACHE_PAGE_LOCKED ((NTSTATUS) 0x00000115L) -#endif - -#ifndef STATUS_CRASH_DUMP -# define STATUS_CRASH_DUMP ((NTSTATUS) 0x00000116L) -#endif - -#ifndef STATUS_BUFFER_ALL_ZEROS -# define STATUS_BUFFER_ALL_ZEROS ((NTSTATUS) 0x00000117L) -#endif - -#ifndef STATUS_REPARSE_OBJECT -# define STATUS_REPARSE_OBJECT ((NTSTATUS) 0x00000118L) -#endif - -#ifndef STATUS_RESOURCE_REQUIREMENTS_CHANGED -# define STATUS_RESOURCE_REQUIREMENTS_CHANGED ((NTSTATUS) 0x00000119L) -#endif - -#ifndef STATUS_TRANSLATION_COMPLETE -# define STATUS_TRANSLATION_COMPLETE ((NTSTATUS) 0x00000120L) -#endif - -#ifndef STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY -# define STATUS_DS_MEMBERSHIP_EVALUATED_LOCALLY ((NTSTATUS) 0x00000121L) -#endif - -#ifndef STATUS_NOTHING_TO_TERMINATE -# define STATUS_NOTHING_TO_TERMINATE ((NTSTATUS) 0x00000122L) -#endif - -#ifndef STATUS_PROCESS_NOT_IN_JOB -# define STATUS_PROCESS_NOT_IN_JOB ((NTSTATUS) 0x00000123L) -#endif - -#ifndef STATUS_PROCESS_IN_JOB -# define STATUS_PROCESS_IN_JOB ((NTSTATUS) 0x00000124L) -#endif - -#ifndef STATUS_VOLSNAP_HIBERNATE_READY -# define STATUS_VOLSNAP_HIBERNATE_READY ((NTSTATUS) 0x00000125L) -#endif - -#ifndef STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY -# define STATUS_FSFILTER_OP_COMPLETED_SUCCESSFULLY ((NTSTATUS) 0x00000126L) -#endif - -#ifndef STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED -# define STATUS_INTERRUPT_VECTOR_ALREADY_CONNECTED ((NTSTATUS) 0x00000127L) -#endif - -#ifndef STATUS_INTERRUPT_STILL_CONNECTED -# define STATUS_INTERRUPT_STILL_CONNECTED ((NTSTATUS) 0x00000128L) -#endif - -#ifndef STATUS_PROCESS_CLONED -# define STATUS_PROCESS_CLONED ((NTSTATUS) 0x00000129L) -#endif - -#ifndef STATUS_FILE_LOCKED_WITH_ONLY_READERS -# define STATUS_FILE_LOCKED_WITH_ONLY_READERS ((NTSTATUS) 0x0000012AL) -#endif - -#ifndef STATUS_FILE_LOCKED_WITH_WRITERS -# define STATUS_FILE_LOCKED_WITH_WRITERS ((NTSTATUS) 0x0000012BL) -#endif - -#ifndef STATUS_RESOURCEMANAGER_READ_ONLY -# define STATUS_RESOURCEMANAGER_READ_ONLY ((NTSTATUS) 0x00000202L) -#endif - -#ifndef STATUS_RING_PREVIOUSLY_EMPTY -# define STATUS_RING_PREVIOUSLY_EMPTY ((NTSTATUS) 0x00000210L) -#endif - -#ifndef STATUS_RING_PREVIOUSLY_FULL -# define STATUS_RING_PREVIOUSLY_FULL ((NTSTATUS) 0x00000211L) -#endif - -#ifndef STATUS_RING_PREVIOUSLY_ABOVE_QUOTA -# define STATUS_RING_PREVIOUSLY_ABOVE_QUOTA ((NTSTATUS) 0x00000212L) -#endif - -#ifndef STATUS_RING_NEWLY_EMPTY -# define STATUS_RING_NEWLY_EMPTY ((NTSTATUS) 0x00000213L) -#endif - -#ifndef STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT -# define STATUS_RING_SIGNAL_OPPOSITE_ENDPOINT ((NTSTATUS) 0x00000214L) -#endif - -#ifndef STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE -# define STATUS_OPLOCK_SWITCHED_TO_NEW_HANDLE ((NTSTATUS) 0x00000215L) -#endif - -#ifndef STATUS_OPLOCK_HANDLE_CLOSED -# define STATUS_OPLOCK_HANDLE_CLOSED ((NTSTATUS) 0x00000216L) -#endif - -#ifndef STATUS_WAIT_FOR_OPLOCK -# define STATUS_WAIT_FOR_OPLOCK ((NTSTATUS) 0x00000367L) -#endif - -#ifndef STATUS_OBJECT_NAME_EXISTS -# define STATUS_OBJECT_NAME_EXISTS ((NTSTATUS) 0x40000000L) -#endif - -#ifndef STATUS_THREAD_WAS_SUSPENDED -# define STATUS_THREAD_WAS_SUSPENDED ((NTSTATUS) 0x40000001L) -#endif - -#ifndef STATUS_WORKING_SET_LIMIT_RANGE -# define STATUS_WORKING_SET_LIMIT_RANGE ((NTSTATUS) 0x40000002L) -#endif - -#ifndef STATUS_IMAGE_NOT_AT_BASE -# define STATUS_IMAGE_NOT_AT_BASE ((NTSTATUS) 0x40000003L) -#endif - -#ifndef STATUS_RXACT_STATE_CREATED -# define STATUS_RXACT_STATE_CREATED ((NTSTATUS) 0x40000004L) -#endif - -#ifndef STATUS_SEGMENT_NOTIFICATION -# define STATUS_SEGMENT_NOTIFICATION ((NTSTATUS) 0x40000005L) -#endif - -#ifndef STATUS_LOCAL_USER_SESSION_KEY -# define STATUS_LOCAL_USER_SESSION_KEY ((NTSTATUS) 0x40000006L) -#endif - -#ifndef STATUS_BAD_CURRENT_DIRECTORY -# define STATUS_BAD_CURRENT_DIRECTORY ((NTSTATUS) 0x40000007L) -#endif - -#ifndef STATUS_SERIAL_MORE_WRITES -# define STATUS_SERIAL_MORE_WRITES ((NTSTATUS) 0x40000008L) -#endif - -#ifndef STATUS_REGISTRY_RECOVERED -# define STATUS_REGISTRY_RECOVERED ((NTSTATUS) 0x40000009L) -#endif - -#ifndef STATUS_FT_READ_RECOVERY_FROM_BACKUP -# define STATUS_FT_READ_RECOVERY_FROM_BACKUP ((NTSTATUS) 0x4000000AL) -#endif - -#ifndef STATUS_FT_WRITE_RECOVERY -# define STATUS_FT_WRITE_RECOVERY ((NTSTATUS) 0x4000000BL) -#endif - -#ifndef STATUS_SERIAL_COUNTER_TIMEOUT -# define STATUS_SERIAL_COUNTER_TIMEOUT ((NTSTATUS) 0x4000000CL) -#endif - -#ifndef STATUS_NULL_LM_PASSWORD -# define STATUS_NULL_LM_PASSWORD ((NTSTATUS) 0x4000000DL) -#endif - -#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH -# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH ((NTSTATUS) 0x4000000EL) -#endif - -#ifndef STATUS_RECEIVE_PARTIAL -# define STATUS_RECEIVE_PARTIAL ((NTSTATUS) 0x4000000FL) -#endif - -#ifndef STATUS_RECEIVE_EXPEDITED -# define STATUS_RECEIVE_EXPEDITED ((NTSTATUS) 0x40000010L) -#endif - -#ifndef STATUS_RECEIVE_PARTIAL_EXPEDITED -# define STATUS_RECEIVE_PARTIAL_EXPEDITED ((NTSTATUS) 0x40000011L) -#endif - -#ifndef STATUS_EVENT_DONE -# define STATUS_EVENT_DONE ((NTSTATUS) 0x40000012L) -#endif - -#ifndef STATUS_EVENT_PENDING -# define STATUS_EVENT_PENDING ((NTSTATUS) 0x40000013L) -#endif - -#ifndef STATUS_CHECKING_FILE_SYSTEM -# define STATUS_CHECKING_FILE_SYSTEM ((NTSTATUS) 0x40000014L) -#endif - -#ifndef STATUS_FATAL_APP_EXIT -# define STATUS_FATAL_APP_EXIT ((NTSTATUS) 0x40000015L) -#endif - -#ifndef STATUS_PREDEFINED_HANDLE -# define STATUS_PREDEFINED_HANDLE ((NTSTATUS) 0x40000016L) -#endif - -#ifndef STATUS_WAS_UNLOCKED -# define STATUS_WAS_UNLOCKED ((NTSTATUS) 0x40000017L) -#endif - -#ifndef STATUS_SERVICE_NOTIFICATION -# define STATUS_SERVICE_NOTIFICATION ((NTSTATUS) 0x40000018L) -#endif - -#ifndef STATUS_WAS_LOCKED -# define STATUS_WAS_LOCKED ((NTSTATUS) 0x40000019L) -#endif - -#ifndef STATUS_LOG_HARD_ERROR -# define STATUS_LOG_HARD_ERROR ((NTSTATUS) 0x4000001AL) -#endif - -#ifndef STATUS_ALREADY_WIN32 -# define STATUS_ALREADY_WIN32 ((NTSTATUS) 0x4000001BL) -#endif - -#ifndef STATUS_WX86_UNSIMULATE -# define STATUS_WX86_UNSIMULATE ((NTSTATUS) 0x4000001CL) -#endif - -#ifndef STATUS_WX86_CONTINUE -# define STATUS_WX86_CONTINUE ((NTSTATUS) 0x4000001DL) -#endif - -#ifndef STATUS_WX86_SINGLE_STEP -# define STATUS_WX86_SINGLE_STEP ((NTSTATUS) 0x4000001EL) -#endif - -#ifndef STATUS_WX86_BREAKPOINT -# define STATUS_WX86_BREAKPOINT ((NTSTATUS) 0x4000001FL) -#endif - -#ifndef STATUS_WX86_EXCEPTION_CONTINUE -# define STATUS_WX86_EXCEPTION_CONTINUE ((NTSTATUS) 0x40000020L) -#endif - -#ifndef STATUS_WX86_EXCEPTION_LASTCHANCE -# define STATUS_WX86_EXCEPTION_LASTCHANCE ((NTSTATUS) 0x40000021L) -#endif - -#ifndef STATUS_WX86_EXCEPTION_CHAIN -# define STATUS_WX86_EXCEPTION_CHAIN ((NTSTATUS) 0x40000022L) -#endif - -#ifndef STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE -# define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE ((NTSTATUS) 0x40000023L) -#endif - -#ifndef STATUS_NO_YIELD_PERFORMED -# define STATUS_NO_YIELD_PERFORMED ((NTSTATUS) 0x40000024L) -#endif - -#ifndef STATUS_TIMER_RESUME_IGNORED -# define STATUS_TIMER_RESUME_IGNORED ((NTSTATUS) 0x40000025L) -#endif - -#ifndef STATUS_ARBITRATION_UNHANDLED -# define STATUS_ARBITRATION_UNHANDLED ((NTSTATUS) 0x40000026L) -#endif - -#ifndef STATUS_CARDBUS_NOT_SUPPORTED -# define STATUS_CARDBUS_NOT_SUPPORTED ((NTSTATUS) 0x40000027L) -#endif - -#ifndef STATUS_WX86_CREATEWX86TIB -# define STATUS_WX86_CREATEWX86TIB ((NTSTATUS) 0x40000028L) -#endif - -#ifndef STATUS_MP_PROCESSOR_MISMATCH -# define STATUS_MP_PROCESSOR_MISMATCH ((NTSTATUS) 0x40000029L) -#endif - -#ifndef STATUS_HIBERNATED -# define STATUS_HIBERNATED ((NTSTATUS) 0x4000002AL) -#endif - -#ifndef STATUS_RESUME_HIBERNATION -# define STATUS_RESUME_HIBERNATION ((NTSTATUS) 0x4000002BL) -#endif - -#ifndef STATUS_FIRMWARE_UPDATED -# define STATUS_FIRMWARE_UPDATED ((NTSTATUS) 0x4000002CL) -#endif - -#ifndef STATUS_DRIVERS_LEAKING_LOCKED_PAGES -# define STATUS_DRIVERS_LEAKING_LOCKED_PAGES ((NTSTATUS) 0x4000002DL) -#endif - -#ifndef STATUS_MESSAGE_RETRIEVED -# define STATUS_MESSAGE_RETRIEVED ((NTSTATUS) 0x4000002EL) -#endif - -#ifndef STATUS_SYSTEM_POWERSTATE_TRANSITION -# define STATUS_SYSTEM_POWERSTATE_TRANSITION ((NTSTATUS) 0x4000002FL) -#endif - -#ifndef STATUS_ALPC_CHECK_COMPLETION_LIST -# define STATUS_ALPC_CHECK_COMPLETION_LIST ((NTSTATUS) 0x40000030L) -#endif - -#ifndef STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION -# define STATUS_SYSTEM_POWERSTATE_COMPLEX_TRANSITION ((NTSTATUS) 0x40000031L) -#endif - -#ifndef STATUS_ACCESS_AUDIT_BY_POLICY -# define STATUS_ACCESS_AUDIT_BY_POLICY ((NTSTATUS) 0x40000032L) -#endif - -#ifndef STATUS_ABANDON_HIBERFILE -# define STATUS_ABANDON_HIBERFILE ((NTSTATUS) 0x40000033L) -#endif - -#ifndef STATUS_BIZRULES_NOT_ENABLED -# define STATUS_BIZRULES_NOT_ENABLED ((NTSTATUS) 0x40000034L) -#endif - -#ifndef STATUS_GUARD_PAGE_VIOLATION -# define STATUS_GUARD_PAGE_VIOLATION ((NTSTATUS) 0x80000001L) -#endif - -#ifndef STATUS_DATATYPE_MISALIGNMENT -# define STATUS_DATATYPE_MISALIGNMENT ((NTSTATUS) 0x80000002L) -#endif - -#ifndef STATUS_BREAKPOINT -# define STATUS_BREAKPOINT ((NTSTATUS) 0x80000003L) -#endif - -#ifndef STATUS_SINGLE_STEP -# define STATUS_SINGLE_STEP ((NTSTATUS) 0x80000004L) -#endif - -#ifndef STATUS_BUFFER_OVERFLOW -# define STATUS_BUFFER_OVERFLOW ((NTSTATUS) 0x80000005L) -#endif - -#ifndef STATUS_NO_MORE_FILES -# define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006L) -#endif - -#ifndef STATUS_WAKE_SYSTEM_DEBUGGER -# define STATUS_WAKE_SYSTEM_DEBUGGER ((NTSTATUS) 0x80000007L) -#endif - -#ifndef STATUS_HANDLES_CLOSED -# define STATUS_HANDLES_CLOSED ((NTSTATUS) 0x8000000AL) -#endif - -#ifndef STATUS_NO_INHERITANCE -# define STATUS_NO_INHERITANCE ((NTSTATUS) 0x8000000BL) -#endif - -#ifndef STATUS_GUID_SUBSTITUTION_MADE -# define STATUS_GUID_SUBSTITUTION_MADE ((NTSTATUS) 0x8000000CL) -#endif - -#ifndef STATUS_PARTIAL_COPY -# define STATUS_PARTIAL_COPY ((NTSTATUS) 0x8000000DL) -#endif - -#ifndef STATUS_DEVICE_PAPER_EMPTY -# define STATUS_DEVICE_PAPER_EMPTY ((NTSTATUS) 0x8000000EL) -#endif - -#ifndef STATUS_DEVICE_POWERED_OFF -# define STATUS_DEVICE_POWERED_OFF ((NTSTATUS) 0x8000000FL) -#endif - -#ifndef STATUS_DEVICE_OFF_LINE -# define STATUS_DEVICE_OFF_LINE ((NTSTATUS) 0x80000010L) -#endif - -#ifndef STATUS_DEVICE_BUSY -# define STATUS_DEVICE_BUSY ((NTSTATUS) 0x80000011L) -#endif - -#ifndef STATUS_NO_MORE_EAS -# define STATUS_NO_MORE_EAS ((NTSTATUS) 0x80000012L) -#endif - -#ifndef STATUS_INVALID_EA_NAME -# define STATUS_INVALID_EA_NAME ((NTSTATUS) 0x80000013L) -#endif - -#ifndef STATUS_EA_LIST_INCONSISTENT -# define STATUS_EA_LIST_INCONSISTENT ((NTSTATUS) 0x80000014L) -#endif - -#ifndef STATUS_INVALID_EA_FLAG -# define STATUS_INVALID_EA_FLAG ((NTSTATUS) 0x80000015L) -#endif - -#ifndef STATUS_VERIFY_REQUIRED -# define STATUS_VERIFY_REQUIRED ((NTSTATUS) 0x80000016L) -#endif - -#ifndef STATUS_EXTRANEOUS_INFORMATION -# define STATUS_EXTRANEOUS_INFORMATION ((NTSTATUS) 0x80000017L) -#endif - -#ifndef STATUS_RXACT_COMMIT_NECESSARY -# define STATUS_RXACT_COMMIT_NECESSARY ((NTSTATUS) 0x80000018L) -#endif - -#ifndef STATUS_NO_MORE_ENTRIES -# define STATUS_NO_MORE_ENTRIES ((NTSTATUS) 0x8000001AL) -#endif - -#ifndef STATUS_FILEMARK_DETECTED -# define STATUS_FILEMARK_DETECTED ((NTSTATUS) 0x8000001BL) -#endif - -#ifndef STATUS_MEDIA_CHANGED -# define STATUS_MEDIA_CHANGED ((NTSTATUS) 0x8000001CL) -#endif - -#ifndef STATUS_BUS_RESET -# define STATUS_BUS_RESET ((NTSTATUS) 0x8000001DL) -#endif - -#ifndef STATUS_END_OF_MEDIA -# define STATUS_END_OF_MEDIA ((NTSTATUS) 0x8000001EL) -#endif - -#ifndef STATUS_BEGINNING_OF_MEDIA -# define STATUS_BEGINNING_OF_MEDIA ((NTSTATUS) 0x8000001FL) -#endif - -#ifndef STATUS_MEDIA_CHECK -# define STATUS_MEDIA_CHECK ((NTSTATUS) 0x80000020L) -#endif - -#ifndef STATUS_SETMARK_DETECTED -# define STATUS_SETMARK_DETECTED ((NTSTATUS) 0x80000021L) -#endif - -#ifndef STATUS_NO_DATA_DETECTED -# define STATUS_NO_DATA_DETECTED ((NTSTATUS) 0x80000022L) -#endif - -#ifndef STATUS_REDIRECTOR_HAS_OPEN_HANDLES -# define STATUS_REDIRECTOR_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000023L) -#endif - -#ifndef STATUS_SERVER_HAS_OPEN_HANDLES -# define STATUS_SERVER_HAS_OPEN_HANDLES ((NTSTATUS) 0x80000024L) -#endif - -#ifndef STATUS_ALREADY_DISCONNECTED -# define STATUS_ALREADY_DISCONNECTED ((NTSTATUS) 0x80000025L) -#endif - -#ifndef STATUS_LONGJUMP -# define STATUS_LONGJUMP ((NTSTATUS) 0x80000026L) -#endif - -#ifndef STATUS_CLEANER_CARTRIDGE_INSTALLED -# define STATUS_CLEANER_CARTRIDGE_INSTALLED ((NTSTATUS) 0x80000027L) -#endif - -#ifndef STATUS_PLUGPLAY_QUERY_VETOED -# define STATUS_PLUGPLAY_QUERY_VETOED ((NTSTATUS) 0x80000028L) -#endif - -#ifndef STATUS_UNWIND_CONSOLIDATE -# define STATUS_UNWIND_CONSOLIDATE ((NTSTATUS) 0x80000029L) -#endif - -#ifndef STATUS_REGISTRY_HIVE_RECOVERED -# define STATUS_REGISTRY_HIVE_RECOVERED ((NTSTATUS) 0x8000002AL) -#endif - -#ifndef STATUS_DLL_MIGHT_BE_INSECURE -# define STATUS_DLL_MIGHT_BE_INSECURE ((NTSTATUS) 0x8000002BL) -#endif - -#ifndef STATUS_DLL_MIGHT_BE_INCOMPATIBLE -# define STATUS_DLL_MIGHT_BE_INCOMPATIBLE ((NTSTATUS) 0x8000002CL) -#endif - -#ifndef STATUS_STOPPED_ON_SYMLINK -# define STATUS_STOPPED_ON_SYMLINK ((NTSTATUS) 0x8000002DL) -#endif - -#ifndef STATUS_CANNOT_GRANT_REQUESTED_OPLOCK -# define STATUS_CANNOT_GRANT_REQUESTED_OPLOCK ((NTSTATUS) 0x8000002EL) -#endif - -#ifndef STATUS_NO_ACE_CONDITION -# define STATUS_NO_ACE_CONDITION ((NTSTATUS) 0x8000002FL) -#endif - -#ifndef STATUS_UNSUCCESSFUL -# define STATUS_UNSUCCESSFUL ((NTSTATUS) 0xC0000001L) -#endif - -#ifndef STATUS_NOT_IMPLEMENTED -# define STATUS_NOT_IMPLEMENTED ((NTSTATUS) 0xC0000002L) -#endif - -#ifndef STATUS_INVALID_INFO_CLASS -# define STATUS_INVALID_INFO_CLASS ((NTSTATUS) 0xC0000003L) -#endif - -#ifndef STATUS_INFO_LENGTH_MISMATCH -# define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004L) -#endif - -#ifndef STATUS_ACCESS_VIOLATION -# define STATUS_ACCESS_VIOLATION ((NTSTATUS) 0xC0000005L) -#endif - -#ifndef STATUS_IN_PAGE_ERROR -# define STATUS_IN_PAGE_ERROR ((NTSTATUS) 0xC0000006L) -#endif - -#ifndef STATUS_PAGEFILE_QUOTA -# define STATUS_PAGEFILE_QUOTA ((NTSTATUS) 0xC0000007L) -#endif - -#ifndef STATUS_INVALID_HANDLE -# define STATUS_INVALID_HANDLE ((NTSTATUS) 0xC0000008L) -#endif - -#ifndef STATUS_BAD_INITIAL_STACK -# define STATUS_BAD_INITIAL_STACK ((NTSTATUS) 0xC0000009L) -#endif - -#ifndef STATUS_BAD_INITIAL_PC -# define STATUS_BAD_INITIAL_PC ((NTSTATUS) 0xC000000AL) -#endif - -#ifndef STATUS_INVALID_CID -# define STATUS_INVALID_CID ((NTSTATUS) 0xC000000BL) -#endif - -#ifndef STATUS_TIMER_NOT_CANCELED -# define STATUS_TIMER_NOT_CANCELED ((NTSTATUS) 0xC000000CL) -#endif - -#ifndef STATUS_INVALID_PARAMETER -# define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xC000000DL) -#endif - -#ifndef STATUS_NO_SUCH_DEVICE -# define STATUS_NO_SUCH_DEVICE ((NTSTATUS) 0xC000000EL) -#endif - -#ifndef STATUS_NO_SUCH_FILE -# define STATUS_NO_SUCH_FILE ((NTSTATUS) 0xC000000FL) -#endif - -#ifndef STATUS_INVALID_DEVICE_REQUEST -# define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xC0000010L) -#endif - -#ifndef STATUS_END_OF_FILE -# define STATUS_END_OF_FILE ((NTSTATUS) 0xC0000011L) -#endif - -#ifndef STATUS_WRONG_VOLUME -# define STATUS_WRONG_VOLUME ((NTSTATUS) 0xC0000012L) -#endif - -#ifndef STATUS_NO_MEDIA_IN_DEVICE -# define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xC0000013L) -#endif - -#ifndef STATUS_UNRECOGNIZED_MEDIA -# define STATUS_UNRECOGNIZED_MEDIA ((NTSTATUS) 0xC0000014L) -#endif - -#ifndef STATUS_NONEXISTENT_SECTOR -# define STATUS_NONEXISTENT_SECTOR ((NTSTATUS) 0xC0000015L) -#endif - -#ifndef STATUS_MORE_PROCESSING_REQUIRED -# define STATUS_MORE_PROCESSING_REQUIRED ((NTSTATUS) 0xC0000016L) -#endif - -#ifndef STATUS_NO_MEMORY -# define STATUS_NO_MEMORY ((NTSTATUS) 0xC0000017L) -#endif - -#ifndef STATUS_CONFLICTING_ADDRESSES -# define STATUS_CONFLICTING_ADDRESSES ((NTSTATUS) 0xC0000018L) -#endif - -#ifndef STATUS_NOT_MAPPED_VIEW -# define STATUS_NOT_MAPPED_VIEW ((NTSTATUS) 0xC0000019L) -#endif - -#ifndef STATUS_UNABLE_TO_FREE_VM -# define STATUS_UNABLE_TO_FREE_VM ((NTSTATUS) 0xC000001AL) -#endif - -#ifndef STATUS_UNABLE_TO_DELETE_SECTION -# define STATUS_UNABLE_TO_DELETE_SECTION ((NTSTATUS) 0xC000001BL) -#endif - -#ifndef STATUS_INVALID_SYSTEM_SERVICE -# define STATUS_INVALID_SYSTEM_SERVICE ((NTSTATUS) 0xC000001CL) -#endif - -#ifndef STATUS_ILLEGAL_INSTRUCTION -# define STATUS_ILLEGAL_INSTRUCTION ((NTSTATUS) 0xC000001DL) -#endif - -#ifndef STATUS_INVALID_LOCK_SEQUENCE -# define STATUS_INVALID_LOCK_SEQUENCE ((NTSTATUS) 0xC000001EL) -#endif - -#ifndef STATUS_INVALID_VIEW_SIZE -# define STATUS_INVALID_VIEW_SIZE ((NTSTATUS) 0xC000001FL) -#endif - -#ifndef STATUS_INVALID_FILE_FOR_SECTION -# define STATUS_INVALID_FILE_FOR_SECTION ((NTSTATUS) 0xC0000020L) -#endif - -#ifndef STATUS_ALREADY_COMMITTED -# define STATUS_ALREADY_COMMITTED ((NTSTATUS) 0xC0000021L) -#endif - -#ifndef STATUS_ACCESS_DENIED -# define STATUS_ACCESS_DENIED ((NTSTATUS) 0xC0000022L) -#endif - -#ifndef STATUS_BUFFER_TOO_SMALL -# define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xC0000023L) -#endif - -#ifndef STATUS_OBJECT_TYPE_MISMATCH -# define STATUS_OBJECT_TYPE_MISMATCH ((NTSTATUS) 0xC0000024L) -#endif - -#ifndef STATUS_NONCONTINUABLE_EXCEPTION -# define STATUS_NONCONTINUABLE_EXCEPTION ((NTSTATUS) 0xC0000025L) -#endif - -#ifndef STATUS_INVALID_DISPOSITION -# define STATUS_INVALID_DISPOSITION ((NTSTATUS) 0xC0000026L) -#endif - -#ifndef STATUS_UNWIND -# define STATUS_UNWIND ((NTSTATUS) 0xC0000027L) -#endif - -#ifndef STATUS_BAD_STACK -# define STATUS_BAD_STACK ((NTSTATUS) 0xC0000028L) -#endif - -#ifndef STATUS_INVALID_UNWIND_TARGET -# define STATUS_INVALID_UNWIND_TARGET ((NTSTATUS) 0xC0000029L) -#endif - -#ifndef STATUS_NOT_LOCKED -# define STATUS_NOT_LOCKED ((NTSTATUS) 0xC000002AL) -#endif - -#ifndef STATUS_PARITY_ERROR -# define STATUS_PARITY_ERROR ((NTSTATUS) 0xC000002BL) -#endif - -#ifndef STATUS_UNABLE_TO_DECOMMIT_VM -# define STATUS_UNABLE_TO_DECOMMIT_VM ((NTSTATUS) 0xC000002CL) -#endif - -#ifndef STATUS_NOT_COMMITTED -# define STATUS_NOT_COMMITTED ((NTSTATUS) 0xC000002DL) -#endif - -#ifndef STATUS_INVALID_PORT_ATTRIBUTES -# define STATUS_INVALID_PORT_ATTRIBUTES ((NTSTATUS) 0xC000002EL) -#endif - -#ifndef STATUS_PORT_MESSAGE_TOO_LONG -# define STATUS_PORT_MESSAGE_TOO_LONG ((NTSTATUS) 0xC000002FL) -#endif - -#ifndef STATUS_INVALID_PARAMETER_MIX -# define STATUS_INVALID_PARAMETER_MIX ((NTSTATUS) 0xC0000030L) -#endif - -#ifndef STATUS_INVALID_QUOTA_LOWER -# define STATUS_INVALID_QUOTA_LOWER ((NTSTATUS) 0xC0000031L) -#endif - -#ifndef STATUS_DISK_CORRUPT_ERROR -# define STATUS_DISK_CORRUPT_ERROR ((NTSTATUS) 0xC0000032L) -#endif - -#ifndef STATUS_OBJECT_NAME_INVALID -# define STATUS_OBJECT_NAME_INVALID ((NTSTATUS) 0xC0000033L) -#endif - -#ifndef STATUS_OBJECT_NAME_NOT_FOUND -# define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS) 0xC0000034L) -#endif - -#ifndef STATUS_OBJECT_NAME_COLLISION -# define STATUS_OBJECT_NAME_COLLISION ((NTSTATUS) 0xC0000035L) -#endif - -#ifndef STATUS_PORT_DISCONNECTED -# define STATUS_PORT_DISCONNECTED ((NTSTATUS) 0xC0000037L) -#endif - -#ifndef STATUS_DEVICE_ALREADY_ATTACHED -# define STATUS_DEVICE_ALREADY_ATTACHED ((NTSTATUS) 0xC0000038L) -#endif - -#ifndef STATUS_OBJECT_PATH_INVALID -# define STATUS_OBJECT_PATH_INVALID ((NTSTATUS) 0xC0000039L) -#endif - -#ifndef STATUS_OBJECT_PATH_NOT_FOUND -# define STATUS_OBJECT_PATH_NOT_FOUND ((NTSTATUS) 0xC000003AL) -#endif - -#ifndef STATUS_OBJECT_PATH_SYNTAX_BAD -# define STATUS_OBJECT_PATH_SYNTAX_BAD ((NTSTATUS) 0xC000003BL) -#endif - -#ifndef STATUS_DATA_OVERRUN -# define STATUS_DATA_OVERRUN ((NTSTATUS) 0xC000003CL) -#endif - -#ifndef STATUS_DATA_LATE_ERROR -# define STATUS_DATA_LATE_ERROR ((NTSTATUS) 0xC000003DL) -#endif - -#ifndef STATUS_DATA_ERROR -# define STATUS_DATA_ERROR ((NTSTATUS) 0xC000003EL) -#endif - -#ifndef STATUS_CRC_ERROR -# define STATUS_CRC_ERROR ((NTSTATUS) 0xC000003FL) -#endif - -#ifndef STATUS_SECTION_TOO_BIG -# define STATUS_SECTION_TOO_BIG ((NTSTATUS) 0xC0000040L) -#endif - -#ifndef STATUS_PORT_CONNECTION_REFUSED -# define STATUS_PORT_CONNECTION_REFUSED ((NTSTATUS) 0xC0000041L) -#endif - -#ifndef STATUS_INVALID_PORT_HANDLE -# define STATUS_INVALID_PORT_HANDLE ((NTSTATUS) 0xC0000042L) -#endif - -#ifndef STATUS_SHARING_VIOLATION -# define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xC0000043L) -#endif - -#ifndef STATUS_QUOTA_EXCEEDED -# define STATUS_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000044L) -#endif - -#ifndef STATUS_INVALID_PAGE_PROTECTION -# define STATUS_INVALID_PAGE_PROTECTION ((NTSTATUS) 0xC0000045L) -#endif - -#ifndef STATUS_MUTANT_NOT_OWNED -# define STATUS_MUTANT_NOT_OWNED ((NTSTATUS) 0xC0000046L) -#endif - -#ifndef STATUS_SEMAPHORE_LIMIT_EXCEEDED -# define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000047L) -#endif - -#ifndef STATUS_PORT_ALREADY_SET -# define STATUS_PORT_ALREADY_SET ((NTSTATUS) 0xC0000048L) -#endif - -#ifndef STATUS_SECTION_NOT_IMAGE -# define STATUS_SECTION_NOT_IMAGE ((NTSTATUS) 0xC0000049L) -#endif - -#ifndef STATUS_SUSPEND_COUNT_EXCEEDED -# define STATUS_SUSPEND_COUNT_EXCEEDED ((NTSTATUS) 0xC000004AL) -#endif - -#ifndef STATUS_THREAD_IS_TERMINATING -# define STATUS_THREAD_IS_TERMINATING ((NTSTATUS) 0xC000004BL) -#endif - -#ifndef STATUS_BAD_WORKING_SET_LIMIT -# define STATUS_BAD_WORKING_SET_LIMIT ((NTSTATUS) 0xC000004CL) -#endif - -#ifndef STATUS_INCOMPATIBLE_FILE_MAP -# define STATUS_INCOMPATIBLE_FILE_MAP ((NTSTATUS) 0xC000004DL) -#endif - -#ifndef STATUS_SECTION_PROTECTION -# define STATUS_SECTION_PROTECTION ((NTSTATUS) 0xC000004EL) -#endif - -#ifndef STATUS_EAS_NOT_SUPPORTED -# define STATUS_EAS_NOT_SUPPORTED ((NTSTATUS) 0xC000004FL) -#endif - -#ifndef STATUS_EA_TOO_LARGE -# define STATUS_EA_TOO_LARGE ((NTSTATUS) 0xC0000050L) -#endif - -#ifndef STATUS_NONEXISTENT_EA_ENTRY -# define STATUS_NONEXISTENT_EA_ENTRY ((NTSTATUS) 0xC0000051L) -#endif - -#ifndef STATUS_NO_EAS_ON_FILE -# define STATUS_NO_EAS_ON_FILE ((NTSTATUS) 0xC0000052L) -#endif - -#ifndef STATUS_EA_CORRUPT_ERROR -# define STATUS_EA_CORRUPT_ERROR ((NTSTATUS) 0xC0000053L) -#endif - -#ifndef STATUS_FILE_LOCK_CONFLICT -# define STATUS_FILE_LOCK_CONFLICT ((NTSTATUS) 0xC0000054L) -#endif - -#ifndef STATUS_LOCK_NOT_GRANTED -# define STATUS_LOCK_NOT_GRANTED ((NTSTATUS) 0xC0000055L) -#endif - -#ifndef STATUS_DELETE_PENDING -# define STATUS_DELETE_PENDING ((NTSTATUS) 0xC0000056L) -#endif - -#ifndef STATUS_CTL_FILE_NOT_SUPPORTED -# define STATUS_CTL_FILE_NOT_SUPPORTED ((NTSTATUS) 0xC0000057L) -#endif - -#ifndef STATUS_UNKNOWN_REVISION -# define STATUS_UNKNOWN_REVISION ((NTSTATUS) 0xC0000058L) -#endif - -#ifndef STATUS_REVISION_MISMATCH -# define STATUS_REVISION_MISMATCH ((NTSTATUS) 0xC0000059L) -#endif - -#ifndef STATUS_INVALID_OWNER -# define STATUS_INVALID_OWNER ((NTSTATUS) 0xC000005AL) -#endif - -#ifndef STATUS_INVALID_PRIMARY_GROUP -# define STATUS_INVALID_PRIMARY_GROUP ((NTSTATUS) 0xC000005BL) -#endif - -#ifndef STATUS_NO_IMPERSONATION_TOKEN -# define STATUS_NO_IMPERSONATION_TOKEN ((NTSTATUS) 0xC000005CL) -#endif - -#ifndef STATUS_CANT_DISABLE_MANDATORY -# define STATUS_CANT_DISABLE_MANDATORY ((NTSTATUS) 0xC000005DL) -#endif - -#ifndef STATUS_NO_LOGON_SERVERS -# define STATUS_NO_LOGON_SERVERS ((NTSTATUS) 0xC000005EL) -#endif - -#ifndef STATUS_NO_SUCH_LOGON_SESSION -# define STATUS_NO_SUCH_LOGON_SESSION ((NTSTATUS) 0xC000005FL) -#endif - -#ifndef STATUS_NO_SUCH_PRIVILEGE -# define STATUS_NO_SUCH_PRIVILEGE ((NTSTATUS) 0xC0000060L) -#endif - -#ifndef STATUS_PRIVILEGE_NOT_HELD -# define STATUS_PRIVILEGE_NOT_HELD ((NTSTATUS) 0xC0000061L) -#endif - -#ifndef STATUS_INVALID_ACCOUNT_NAME -# define STATUS_INVALID_ACCOUNT_NAME ((NTSTATUS) 0xC0000062L) -#endif - -#ifndef STATUS_USER_EXISTS -# define STATUS_USER_EXISTS ((NTSTATUS) 0xC0000063L) -#endif - -#ifndef STATUS_NO_SUCH_USER -# define STATUS_NO_SUCH_USER ((NTSTATUS) 0xC0000064L) -#endif - -#ifndef STATUS_GROUP_EXISTS -# define STATUS_GROUP_EXISTS ((NTSTATUS) 0xC0000065L) -#endif - -#ifndef STATUS_NO_SUCH_GROUP -# define STATUS_NO_SUCH_GROUP ((NTSTATUS) 0xC0000066L) -#endif - -#ifndef STATUS_MEMBER_IN_GROUP -# define STATUS_MEMBER_IN_GROUP ((NTSTATUS) 0xC0000067L) -#endif - -#ifndef STATUS_MEMBER_NOT_IN_GROUP -# define STATUS_MEMBER_NOT_IN_GROUP ((NTSTATUS) 0xC0000068L) -#endif - -#ifndef STATUS_LAST_ADMIN -# define STATUS_LAST_ADMIN ((NTSTATUS) 0xC0000069L) -#endif - -#ifndef STATUS_WRONG_PASSWORD -# define STATUS_WRONG_PASSWORD ((NTSTATUS) 0xC000006AL) -#endif - -#ifndef STATUS_ILL_FORMED_PASSWORD -# define STATUS_ILL_FORMED_PASSWORD ((NTSTATUS) 0xC000006BL) -#endif - -#ifndef STATUS_PASSWORD_RESTRICTION -# define STATUS_PASSWORD_RESTRICTION ((NTSTATUS) 0xC000006CL) -#endif - -#ifndef STATUS_LOGON_FAILURE -# define STATUS_LOGON_FAILURE ((NTSTATUS) 0xC000006DL) -#endif - -#ifndef STATUS_ACCOUNT_RESTRICTION -# define STATUS_ACCOUNT_RESTRICTION ((NTSTATUS) 0xC000006EL) -#endif - -#ifndef STATUS_INVALID_LOGON_HOURS -# define STATUS_INVALID_LOGON_HOURS ((NTSTATUS) 0xC000006FL) -#endif - -#ifndef STATUS_INVALID_WORKSTATION -# define STATUS_INVALID_WORKSTATION ((NTSTATUS) 0xC0000070L) -#endif - -#ifndef STATUS_PASSWORD_EXPIRED -# define STATUS_PASSWORD_EXPIRED ((NTSTATUS) 0xC0000071L) -#endif - -#ifndef STATUS_ACCOUNT_DISABLED -# define STATUS_ACCOUNT_DISABLED ((NTSTATUS) 0xC0000072L) -#endif - -#ifndef STATUS_NONE_MAPPED -# define STATUS_NONE_MAPPED ((NTSTATUS) 0xC0000073L) -#endif - -#ifndef STATUS_TOO_MANY_LUIDS_REQUESTED -# define STATUS_TOO_MANY_LUIDS_REQUESTED ((NTSTATUS) 0xC0000074L) -#endif - -#ifndef STATUS_LUIDS_EXHAUSTED -# define STATUS_LUIDS_EXHAUSTED ((NTSTATUS) 0xC0000075L) -#endif - -#ifndef STATUS_INVALID_SUB_AUTHORITY -# define STATUS_INVALID_SUB_AUTHORITY ((NTSTATUS) 0xC0000076L) -#endif - -#ifndef STATUS_INVALID_ACL -# define STATUS_INVALID_ACL ((NTSTATUS) 0xC0000077L) -#endif - -#ifndef STATUS_INVALID_SID -# define STATUS_INVALID_SID ((NTSTATUS) 0xC0000078L) -#endif - -#ifndef STATUS_INVALID_SECURITY_DESCR -# define STATUS_INVALID_SECURITY_DESCR ((NTSTATUS) 0xC0000079L) -#endif - -#ifndef STATUS_PROCEDURE_NOT_FOUND -# define STATUS_PROCEDURE_NOT_FOUND ((NTSTATUS) 0xC000007AL) -#endif - -#ifndef STATUS_INVALID_IMAGE_FORMAT -# define STATUS_INVALID_IMAGE_FORMAT ((NTSTATUS) 0xC000007BL) -#endif - -#ifndef STATUS_NO_TOKEN -# define STATUS_NO_TOKEN ((NTSTATUS) 0xC000007CL) -#endif - -#ifndef STATUS_BAD_INHERITANCE_ACL -# define STATUS_BAD_INHERITANCE_ACL ((NTSTATUS) 0xC000007DL) -#endif - -#ifndef STATUS_RANGE_NOT_LOCKED -# define STATUS_RANGE_NOT_LOCKED ((NTSTATUS) 0xC000007EL) -#endif - -#ifndef STATUS_DISK_FULL -# define STATUS_DISK_FULL ((NTSTATUS) 0xC000007FL) -#endif - -#ifndef STATUS_SERVER_DISABLED -# define STATUS_SERVER_DISABLED ((NTSTATUS) 0xC0000080L) -#endif - -#ifndef STATUS_SERVER_NOT_DISABLED -# define STATUS_SERVER_NOT_DISABLED ((NTSTATUS) 0xC0000081L) -#endif - -#ifndef STATUS_TOO_MANY_GUIDS_REQUESTED -# define STATUS_TOO_MANY_GUIDS_REQUESTED ((NTSTATUS) 0xC0000082L) -#endif - -#ifndef STATUS_GUIDS_EXHAUSTED -# define STATUS_GUIDS_EXHAUSTED ((NTSTATUS) 0xC0000083L) -#endif - -#ifndef STATUS_INVALID_ID_AUTHORITY -# define STATUS_INVALID_ID_AUTHORITY ((NTSTATUS) 0xC0000084L) -#endif - -#ifndef STATUS_AGENTS_EXHAUSTED -# define STATUS_AGENTS_EXHAUSTED ((NTSTATUS) 0xC0000085L) -#endif - -#ifndef STATUS_INVALID_VOLUME_LABEL -# define STATUS_INVALID_VOLUME_LABEL ((NTSTATUS) 0xC0000086L) -#endif - -#ifndef STATUS_SECTION_NOT_EXTENDED -# define STATUS_SECTION_NOT_EXTENDED ((NTSTATUS) 0xC0000087L) -#endif - -#ifndef STATUS_NOT_MAPPED_DATA -# define STATUS_NOT_MAPPED_DATA ((NTSTATUS) 0xC0000088L) -#endif - -#ifndef STATUS_RESOURCE_DATA_NOT_FOUND -# define STATUS_RESOURCE_DATA_NOT_FOUND ((NTSTATUS) 0xC0000089L) -#endif - -#ifndef STATUS_RESOURCE_TYPE_NOT_FOUND -# define STATUS_RESOURCE_TYPE_NOT_FOUND ((NTSTATUS) 0xC000008AL) -#endif - -#ifndef STATUS_RESOURCE_NAME_NOT_FOUND -# define STATUS_RESOURCE_NAME_NOT_FOUND ((NTSTATUS) 0xC000008BL) -#endif - -#ifndef STATUS_ARRAY_BOUNDS_EXCEEDED -# define STATUS_ARRAY_BOUNDS_EXCEEDED ((NTSTATUS) 0xC000008CL) -#endif - -#ifndef STATUS_FLOAT_DENORMAL_OPERAND -# define STATUS_FLOAT_DENORMAL_OPERAND ((NTSTATUS) 0xC000008DL) -#endif - -#ifndef STATUS_FLOAT_DIVIDE_BY_ZERO -# define STATUS_FLOAT_DIVIDE_BY_ZERO ((NTSTATUS) 0xC000008EL) -#endif - -#ifndef STATUS_FLOAT_INEXACT_RESULT -# define STATUS_FLOAT_INEXACT_RESULT ((NTSTATUS) 0xC000008FL) -#endif - -#ifndef STATUS_FLOAT_INVALID_OPERATION -# define STATUS_FLOAT_INVALID_OPERATION ((NTSTATUS) 0xC0000090L) -#endif - -#ifndef STATUS_FLOAT_OVERFLOW -# define STATUS_FLOAT_OVERFLOW ((NTSTATUS) 0xC0000091L) -#endif - -#ifndef STATUS_FLOAT_STACK_CHECK -# define STATUS_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000092L) -#endif - -#ifndef STATUS_FLOAT_UNDERFLOW -# define STATUS_FLOAT_UNDERFLOW ((NTSTATUS) 0xC0000093L) -#endif - -#ifndef STATUS_INTEGER_DIVIDE_BY_ZERO -# define STATUS_INTEGER_DIVIDE_BY_ZERO ((NTSTATUS) 0xC0000094L) -#endif - -#ifndef STATUS_INTEGER_OVERFLOW -# define STATUS_INTEGER_OVERFLOW ((NTSTATUS) 0xC0000095L) -#endif - -#ifndef STATUS_PRIVILEGED_INSTRUCTION -# define STATUS_PRIVILEGED_INSTRUCTION ((NTSTATUS) 0xC0000096L) -#endif - -#ifndef STATUS_TOO_MANY_PAGING_FILES -# define STATUS_TOO_MANY_PAGING_FILES ((NTSTATUS) 0xC0000097L) -#endif - -#ifndef STATUS_FILE_INVALID -# define STATUS_FILE_INVALID ((NTSTATUS) 0xC0000098L) -#endif - -#ifndef STATUS_ALLOTTED_SPACE_EXCEEDED -# define STATUS_ALLOTTED_SPACE_EXCEEDED ((NTSTATUS) 0xC0000099L) -#endif - -#ifndef STATUS_INSUFFICIENT_RESOURCES -# define STATUS_INSUFFICIENT_RESOURCES ((NTSTATUS) 0xC000009AL) -#endif - -#ifndef STATUS_DFS_EXIT_PATH_FOUND -# define STATUS_DFS_EXIT_PATH_FOUND ((NTSTATUS) 0xC000009BL) -#endif - -#ifndef STATUS_DEVICE_DATA_ERROR -# define STATUS_DEVICE_DATA_ERROR ((NTSTATUS) 0xC000009CL) -#endif - -#ifndef STATUS_DEVICE_NOT_CONNECTED -# define STATUS_DEVICE_NOT_CONNECTED ((NTSTATUS) 0xC000009DL) -#endif - -#ifndef STATUS_DEVICE_POWER_FAILURE -# define STATUS_DEVICE_POWER_FAILURE ((NTSTATUS) 0xC000009EL) -#endif - -#ifndef STATUS_FREE_VM_NOT_AT_BASE -# define STATUS_FREE_VM_NOT_AT_BASE ((NTSTATUS) 0xC000009FL) -#endif - -#ifndef STATUS_MEMORY_NOT_ALLOCATED -# define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS) 0xC00000A0L) -#endif - -#ifndef STATUS_WORKING_SET_QUOTA -# define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xC00000A1L) -#endif - -#ifndef STATUS_MEDIA_WRITE_PROTECTED -# define STATUS_MEDIA_WRITE_PROTECTED ((NTSTATUS) 0xC00000A2L) -#endif - -#ifndef STATUS_DEVICE_NOT_READY -# define STATUS_DEVICE_NOT_READY ((NTSTATUS) 0xC00000A3L) -#endif - -#ifndef STATUS_INVALID_GROUP_ATTRIBUTES -# define STATUS_INVALID_GROUP_ATTRIBUTES ((NTSTATUS) 0xC00000A4L) -#endif - -#ifndef STATUS_BAD_IMPERSONATION_LEVEL -# define STATUS_BAD_IMPERSONATION_LEVEL ((NTSTATUS) 0xC00000A5L) -#endif - -#ifndef STATUS_CANT_OPEN_ANONYMOUS -# define STATUS_CANT_OPEN_ANONYMOUS ((NTSTATUS) 0xC00000A6L) -#endif - -#ifndef STATUS_BAD_VALIDATION_CLASS -# define STATUS_BAD_VALIDATION_CLASS ((NTSTATUS) 0xC00000A7L) -#endif - -#ifndef STATUS_BAD_TOKEN_TYPE -# define STATUS_BAD_TOKEN_TYPE ((NTSTATUS) 0xC00000A8L) -#endif - -#ifndef STATUS_BAD_MASTER_BOOT_RECORD -# define STATUS_BAD_MASTER_BOOT_RECORD ((NTSTATUS) 0xC00000A9L) -#endif - -#ifndef STATUS_INSTRUCTION_MISALIGNMENT -# define STATUS_INSTRUCTION_MISALIGNMENT ((NTSTATUS) 0xC00000AAL) -#endif - -#ifndef STATUS_INSTANCE_NOT_AVAILABLE -# define STATUS_INSTANCE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ABL) -#endif - -#ifndef STATUS_PIPE_NOT_AVAILABLE -# define STATUS_PIPE_NOT_AVAILABLE ((NTSTATUS) 0xC00000ACL) -#endif - -#ifndef STATUS_INVALID_PIPE_STATE -# define STATUS_INVALID_PIPE_STATE ((NTSTATUS) 0xC00000ADL) -#endif - -#ifndef STATUS_PIPE_BUSY -# define STATUS_PIPE_BUSY ((NTSTATUS) 0xC00000AEL) -#endif - -#ifndef STATUS_ILLEGAL_FUNCTION -# define STATUS_ILLEGAL_FUNCTION ((NTSTATUS) 0xC00000AFL) -#endif - -#ifndef STATUS_PIPE_DISCONNECTED -# define STATUS_PIPE_DISCONNECTED ((NTSTATUS) 0xC00000B0L) -#endif - -#ifndef STATUS_PIPE_CLOSING -# define STATUS_PIPE_CLOSING ((NTSTATUS) 0xC00000B1L) -#endif - -#ifndef STATUS_PIPE_CONNECTED -# define STATUS_PIPE_CONNECTED ((NTSTATUS) 0xC00000B2L) -#endif - -#ifndef STATUS_PIPE_LISTENING -# define STATUS_PIPE_LISTENING ((NTSTATUS) 0xC00000B3L) -#endif - -#ifndef STATUS_INVALID_READ_MODE -# define STATUS_INVALID_READ_MODE ((NTSTATUS) 0xC00000B4L) -#endif - -#ifndef STATUS_IO_TIMEOUT -# define STATUS_IO_TIMEOUT ((NTSTATUS) 0xC00000B5L) -#endif - -#ifndef STATUS_FILE_FORCED_CLOSED -# define STATUS_FILE_FORCED_CLOSED ((NTSTATUS) 0xC00000B6L) -#endif - -#ifndef STATUS_PROFILING_NOT_STARTED -# define STATUS_PROFILING_NOT_STARTED ((NTSTATUS) 0xC00000B7L) -#endif - -#ifndef STATUS_PROFILING_NOT_STOPPED -# define STATUS_PROFILING_NOT_STOPPED ((NTSTATUS) 0xC00000B8L) -#endif - -#ifndef STATUS_COULD_NOT_INTERPRET -# define STATUS_COULD_NOT_INTERPRET ((NTSTATUS) 0xC00000B9L) -#endif - -#ifndef STATUS_FILE_IS_A_DIRECTORY -# define STATUS_FILE_IS_A_DIRECTORY ((NTSTATUS) 0xC00000BAL) -#endif - -#ifndef STATUS_NOT_SUPPORTED -# define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xC00000BBL) -#endif - -#ifndef STATUS_REMOTE_NOT_LISTENING -# define STATUS_REMOTE_NOT_LISTENING ((NTSTATUS) 0xC00000BCL) -#endif - -#ifndef STATUS_DUPLICATE_NAME -# define STATUS_DUPLICATE_NAME ((NTSTATUS) 0xC00000BDL) -#endif - -#ifndef STATUS_BAD_NETWORK_PATH -# define STATUS_BAD_NETWORK_PATH ((NTSTATUS) 0xC00000BEL) -#endif - -#ifndef STATUS_NETWORK_BUSY -# define STATUS_NETWORK_BUSY ((NTSTATUS) 0xC00000BFL) -#endif - -#ifndef STATUS_DEVICE_DOES_NOT_EXIST -# define STATUS_DEVICE_DOES_NOT_EXIST ((NTSTATUS) 0xC00000C0L) -#endif - -#ifndef STATUS_TOO_MANY_COMMANDS -# define STATUS_TOO_MANY_COMMANDS ((NTSTATUS) 0xC00000C1L) -#endif - -#ifndef STATUS_ADAPTER_HARDWARE_ERROR -# define STATUS_ADAPTER_HARDWARE_ERROR ((NTSTATUS) 0xC00000C2L) -#endif - -#ifndef STATUS_INVALID_NETWORK_RESPONSE -# define STATUS_INVALID_NETWORK_RESPONSE ((NTSTATUS) 0xC00000C3L) -#endif - -#ifndef STATUS_UNEXPECTED_NETWORK_ERROR -# define STATUS_UNEXPECTED_NETWORK_ERROR ((NTSTATUS) 0xC00000C4L) -#endif - -#ifndef STATUS_BAD_REMOTE_ADAPTER -# define STATUS_BAD_REMOTE_ADAPTER ((NTSTATUS) 0xC00000C5L) -#endif - -#ifndef STATUS_PRINT_QUEUE_FULL -# define STATUS_PRINT_QUEUE_FULL ((NTSTATUS) 0xC00000C6L) -#endif - -#ifndef STATUS_NO_SPOOL_SPACE -# define STATUS_NO_SPOOL_SPACE ((NTSTATUS) 0xC00000C7L) -#endif - -#ifndef STATUS_PRINT_CANCELLED -# define STATUS_PRINT_CANCELLED ((NTSTATUS) 0xC00000C8L) -#endif - -#ifndef STATUS_NETWORK_NAME_DELETED -# define STATUS_NETWORK_NAME_DELETED ((NTSTATUS) 0xC00000C9L) -#endif - -#ifndef STATUS_NETWORK_ACCESS_DENIED -# define STATUS_NETWORK_ACCESS_DENIED ((NTSTATUS) 0xC00000CAL) -#endif - -#ifndef STATUS_BAD_DEVICE_TYPE -# define STATUS_BAD_DEVICE_TYPE ((NTSTATUS) 0xC00000CBL) -#endif - -#ifndef STATUS_BAD_NETWORK_NAME -# define STATUS_BAD_NETWORK_NAME ((NTSTATUS) 0xC00000CCL) -#endif - -#ifndef STATUS_TOO_MANY_NAMES -# define STATUS_TOO_MANY_NAMES ((NTSTATUS) 0xC00000CDL) -#endif - -#ifndef STATUS_TOO_MANY_SESSIONS -# define STATUS_TOO_MANY_SESSIONS ((NTSTATUS) 0xC00000CEL) -#endif - -#ifndef STATUS_SHARING_PAUSED -# define STATUS_SHARING_PAUSED ((NTSTATUS) 0xC00000CFL) -#endif - -#ifndef STATUS_REQUEST_NOT_ACCEPTED -# define STATUS_REQUEST_NOT_ACCEPTED ((NTSTATUS) 0xC00000D0L) -#endif - -#ifndef STATUS_REDIRECTOR_PAUSED -# define STATUS_REDIRECTOR_PAUSED ((NTSTATUS) 0xC00000D1L) -#endif - -#ifndef STATUS_NET_WRITE_FAULT -# define STATUS_NET_WRITE_FAULT ((NTSTATUS) 0xC00000D2L) -#endif - -#ifndef STATUS_PROFILING_AT_LIMIT -# define STATUS_PROFILING_AT_LIMIT ((NTSTATUS) 0xC00000D3L) -#endif - -#ifndef STATUS_NOT_SAME_DEVICE -# define STATUS_NOT_SAME_DEVICE ((NTSTATUS) 0xC00000D4L) -#endif - -#ifndef STATUS_FILE_RENAMED -# define STATUS_FILE_RENAMED ((NTSTATUS) 0xC00000D5L) -#endif - -#ifndef STATUS_VIRTUAL_CIRCUIT_CLOSED -# define STATUS_VIRTUAL_CIRCUIT_CLOSED ((NTSTATUS) 0xC00000D6L) -#endif - -#ifndef STATUS_NO_SECURITY_ON_OBJECT -# define STATUS_NO_SECURITY_ON_OBJECT ((NTSTATUS) 0xC00000D7L) -#endif - -#ifndef STATUS_CANT_WAIT -# define STATUS_CANT_WAIT ((NTSTATUS) 0xC00000D8L) -#endif - -#ifndef STATUS_PIPE_EMPTY -# define STATUS_PIPE_EMPTY ((NTSTATUS) 0xC00000D9L) -#endif - -#ifndef STATUS_CANT_ACCESS_DOMAIN_INFO -# define STATUS_CANT_ACCESS_DOMAIN_INFO ((NTSTATUS) 0xC00000DAL) -#endif - -#ifndef STATUS_CANT_TERMINATE_SELF -# define STATUS_CANT_TERMINATE_SELF ((NTSTATUS) 0xC00000DBL) -#endif - -#ifndef STATUS_INVALID_SERVER_STATE -# define STATUS_INVALID_SERVER_STATE ((NTSTATUS) 0xC00000DCL) -#endif - -#ifndef STATUS_INVALID_DOMAIN_STATE -# define STATUS_INVALID_DOMAIN_STATE ((NTSTATUS) 0xC00000DDL) -#endif - -#ifndef STATUS_INVALID_DOMAIN_ROLE -# define STATUS_INVALID_DOMAIN_ROLE ((NTSTATUS) 0xC00000DEL) -#endif - -#ifndef STATUS_NO_SUCH_DOMAIN -# define STATUS_NO_SUCH_DOMAIN ((NTSTATUS) 0xC00000DFL) -#endif - -#ifndef STATUS_DOMAIN_EXISTS -# define STATUS_DOMAIN_EXISTS ((NTSTATUS) 0xC00000E0L) -#endif - -#ifndef STATUS_DOMAIN_LIMIT_EXCEEDED -# define STATUS_DOMAIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00000E1L) -#endif - -#ifndef STATUS_OPLOCK_NOT_GRANTED -# define STATUS_OPLOCK_NOT_GRANTED ((NTSTATUS) 0xC00000E2L) -#endif - -#ifndef STATUS_INVALID_OPLOCK_PROTOCOL -# define STATUS_INVALID_OPLOCK_PROTOCOL ((NTSTATUS) 0xC00000E3L) -#endif - -#ifndef STATUS_INTERNAL_DB_CORRUPTION -# define STATUS_INTERNAL_DB_CORRUPTION ((NTSTATUS) 0xC00000E4L) -#endif - -#ifndef STATUS_INTERNAL_ERROR -# define STATUS_INTERNAL_ERROR ((NTSTATUS) 0xC00000E5L) -#endif - -#ifndef STATUS_GENERIC_NOT_MAPPED -# define STATUS_GENERIC_NOT_MAPPED ((NTSTATUS) 0xC00000E6L) -#endif - -#ifndef STATUS_BAD_DESCRIPTOR_FORMAT -# define STATUS_BAD_DESCRIPTOR_FORMAT ((NTSTATUS) 0xC00000E7L) -#endif - -#ifndef STATUS_INVALID_USER_BUFFER -# define STATUS_INVALID_USER_BUFFER ((NTSTATUS) 0xC00000E8L) -#endif - -#ifndef STATUS_UNEXPECTED_IO_ERROR -# define STATUS_UNEXPECTED_IO_ERROR ((NTSTATUS) 0xC00000E9L) -#endif - -#ifndef STATUS_UNEXPECTED_MM_CREATE_ERR -# define STATUS_UNEXPECTED_MM_CREATE_ERR ((NTSTATUS) 0xC00000EAL) -#endif - -#ifndef STATUS_UNEXPECTED_MM_MAP_ERROR -# define STATUS_UNEXPECTED_MM_MAP_ERROR ((NTSTATUS) 0xC00000EBL) -#endif - -#ifndef STATUS_UNEXPECTED_MM_EXTEND_ERR -# define STATUS_UNEXPECTED_MM_EXTEND_ERR ((NTSTATUS) 0xC00000ECL) -#endif - -#ifndef STATUS_NOT_LOGON_PROCESS -# define STATUS_NOT_LOGON_PROCESS ((NTSTATUS) 0xC00000EDL) -#endif - -#ifndef STATUS_LOGON_SESSION_EXISTS -# define STATUS_LOGON_SESSION_EXISTS ((NTSTATUS) 0xC00000EEL) -#endif - -#ifndef STATUS_INVALID_PARAMETER_1 -# define STATUS_INVALID_PARAMETER_1 ((NTSTATUS) 0xC00000EFL) -#endif - -#ifndef STATUS_INVALID_PARAMETER_2 -# define STATUS_INVALID_PARAMETER_2 ((NTSTATUS) 0xC00000F0L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_3 -# define STATUS_INVALID_PARAMETER_3 ((NTSTATUS) 0xC00000F1L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_4 -# define STATUS_INVALID_PARAMETER_4 ((NTSTATUS) 0xC00000F2L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_5 -# define STATUS_INVALID_PARAMETER_5 ((NTSTATUS) 0xC00000F3L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_6 -# define STATUS_INVALID_PARAMETER_6 ((NTSTATUS) 0xC00000F4L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_7 -# define STATUS_INVALID_PARAMETER_7 ((NTSTATUS) 0xC00000F5L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_8 -# define STATUS_INVALID_PARAMETER_8 ((NTSTATUS) 0xC00000F6L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_9 -# define STATUS_INVALID_PARAMETER_9 ((NTSTATUS) 0xC00000F7L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_10 -# define STATUS_INVALID_PARAMETER_10 ((NTSTATUS) 0xC00000F8L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_11 -# define STATUS_INVALID_PARAMETER_11 ((NTSTATUS) 0xC00000F9L) -#endif - -#ifndef STATUS_INVALID_PARAMETER_12 -# define STATUS_INVALID_PARAMETER_12 ((NTSTATUS) 0xC00000FAL) -#endif - -#ifndef STATUS_REDIRECTOR_NOT_STARTED -# define STATUS_REDIRECTOR_NOT_STARTED ((NTSTATUS) 0xC00000FBL) -#endif - -#ifndef STATUS_REDIRECTOR_STARTED -# define STATUS_REDIRECTOR_STARTED ((NTSTATUS) 0xC00000FCL) -#endif - -#ifndef STATUS_STACK_OVERFLOW -# define STATUS_STACK_OVERFLOW ((NTSTATUS) 0xC00000FDL) -#endif - -#ifndef STATUS_NO_SUCH_PACKAGE -# define STATUS_NO_SUCH_PACKAGE ((NTSTATUS) 0xC00000FEL) -#endif - -#ifndef STATUS_BAD_FUNCTION_TABLE -# define STATUS_BAD_FUNCTION_TABLE ((NTSTATUS) 0xC00000FFL) -#endif - -#ifndef STATUS_VARIABLE_NOT_FOUND -# define STATUS_VARIABLE_NOT_FOUND ((NTSTATUS) 0xC0000100L) -#endif - -#ifndef STATUS_DIRECTORY_NOT_EMPTY -# define STATUS_DIRECTORY_NOT_EMPTY ((NTSTATUS) 0xC0000101L) -#endif - -#ifndef STATUS_FILE_CORRUPT_ERROR -# define STATUS_FILE_CORRUPT_ERROR ((NTSTATUS) 0xC0000102L) -#endif - -#ifndef STATUS_NOT_A_DIRECTORY -# define STATUS_NOT_A_DIRECTORY ((NTSTATUS) 0xC0000103L) -#endif - -#ifndef STATUS_BAD_LOGON_SESSION_STATE -# define STATUS_BAD_LOGON_SESSION_STATE ((NTSTATUS) 0xC0000104L) -#endif - -#ifndef STATUS_LOGON_SESSION_COLLISION -# define STATUS_LOGON_SESSION_COLLISION ((NTSTATUS) 0xC0000105L) -#endif - -#ifndef STATUS_NAME_TOO_LONG -# define STATUS_NAME_TOO_LONG ((NTSTATUS) 0xC0000106L) -#endif - -#ifndef STATUS_FILES_OPEN -# define STATUS_FILES_OPEN ((NTSTATUS) 0xC0000107L) -#endif - -#ifndef STATUS_CONNECTION_IN_USE -# define STATUS_CONNECTION_IN_USE ((NTSTATUS) 0xC0000108L) -#endif - -#ifndef STATUS_MESSAGE_NOT_FOUND -# define STATUS_MESSAGE_NOT_FOUND ((NTSTATUS) 0xC0000109L) -#endif - -#ifndef STATUS_PROCESS_IS_TERMINATING -# define STATUS_PROCESS_IS_TERMINATING ((NTSTATUS) 0xC000010AL) -#endif - -#ifndef STATUS_INVALID_LOGON_TYPE -# define STATUS_INVALID_LOGON_TYPE ((NTSTATUS) 0xC000010BL) -#endif - -#ifndef STATUS_NO_GUID_TRANSLATION -# define STATUS_NO_GUID_TRANSLATION ((NTSTATUS) 0xC000010CL) -#endif - -#ifndef STATUS_CANNOT_IMPERSONATE -# define STATUS_CANNOT_IMPERSONATE ((NTSTATUS) 0xC000010DL) -#endif - -#ifndef STATUS_IMAGE_ALREADY_LOADED -# define STATUS_IMAGE_ALREADY_LOADED ((NTSTATUS) 0xC000010EL) -#endif - -#ifndef STATUS_ABIOS_NOT_PRESENT -# define STATUS_ABIOS_NOT_PRESENT ((NTSTATUS) 0xC000010FL) -#endif - -#ifndef STATUS_ABIOS_LID_NOT_EXIST -# define STATUS_ABIOS_LID_NOT_EXIST ((NTSTATUS) 0xC0000110L) -#endif - -#ifndef STATUS_ABIOS_LID_ALREADY_OWNED -# define STATUS_ABIOS_LID_ALREADY_OWNED ((NTSTATUS) 0xC0000111L) -#endif - -#ifndef STATUS_ABIOS_NOT_LID_OWNER -# define STATUS_ABIOS_NOT_LID_OWNER ((NTSTATUS) 0xC0000112L) -#endif - -#ifndef STATUS_ABIOS_INVALID_COMMAND -# define STATUS_ABIOS_INVALID_COMMAND ((NTSTATUS) 0xC0000113L) -#endif - -#ifndef STATUS_ABIOS_INVALID_LID -# define STATUS_ABIOS_INVALID_LID ((NTSTATUS) 0xC0000114L) -#endif - -#ifndef STATUS_ABIOS_SELECTOR_NOT_AVAILABLE -# define STATUS_ABIOS_SELECTOR_NOT_AVAILABLE ((NTSTATUS) 0xC0000115L) -#endif - -#ifndef STATUS_ABIOS_INVALID_SELECTOR -# define STATUS_ABIOS_INVALID_SELECTOR ((NTSTATUS) 0xC0000116L) -#endif - -#ifndef STATUS_NO_LDT -# define STATUS_NO_LDT ((NTSTATUS) 0xC0000117L) -#endif - -#ifndef STATUS_INVALID_LDT_SIZE -# define STATUS_INVALID_LDT_SIZE ((NTSTATUS) 0xC0000118L) -#endif - -#ifndef STATUS_INVALID_LDT_OFFSET -# define STATUS_INVALID_LDT_OFFSET ((NTSTATUS) 0xC0000119L) -#endif - -#ifndef STATUS_INVALID_LDT_DESCRIPTOR -# define STATUS_INVALID_LDT_DESCRIPTOR ((NTSTATUS) 0xC000011AL) -#endif - -#ifndef STATUS_INVALID_IMAGE_NE_FORMAT -# define STATUS_INVALID_IMAGE_NE_FORMAT ((NTSTATUS) 0xC000011BL) -#endif - -#ifndef STATUS_RXACT_INVALID_STATE -# define STATUS_RXACT_INVALID_STATE ((NTSTATUS) 0xC000011CL) -#endif - -#ifndef STATUS_RXACT_COMMIT_FAILURE -# define STATUS_RXACT_COMMIT_FAILURE ((NTSTATUS) 0xC000011DL) -#endif - -#ifndef STATUS_MAPPED_FILE_SIZE_ZERO -# define STATUS_MAPPED_FILE_SIZE_ZERO ((NTSTATUS) 0xC000011EL) -#endif - -#ifndef STATUS_TOO_MANY_OPENED_FILES -# define STATUS_TOO_MANY_OPENED_FILES ((NTSTATUS) 0xC000011FL) -#endif - -#ifndef STATUS_CANCELLED -# define STATUS_CANCELLED ((NTSTATUS) 0xC0000120L) -#endif - -#ifndef STATUS_CANNOT_DELETE -# define STATUS_CANNOT_DELETE ((NTSTATUS) 0xC0000121L) -#endif - -#ifndef STATUS_INVALID_COMPUTER_NAME -# define STATUS_INVALID_COMPUTER_NAME ((NTSTATUS) 0xC0000122L) -#endif - -#ifndef STATUS_FILE_DELETED -# define STATUS_FILE_DELETED ((NTSTATUS) 0xC0000123L) -#endif - -#ifndef STATUS_SPECIAL_ACCOUNT -# define STATUS_SPECIAL_ACCOUNT ((NTSTATUS) 0xC0000124L) -#endif - -#ifndef STATUS_SPECIAL_GROUP -# define STATUS_SPECIAL_GROUP ((NTSTATUS) 0xC0000125L) -#endif - -#ifndef STATUS_SPECIAL_USER -# define STATUS_SPECIAL_USER ((NTSTATUS) 0xC0000126L) -#endif - -#ifndef STATUS_MEMBERS_PRIMARY_GROUP -# define STATUS_MEMBERS_PRIMARY_GROUP ((NTSTATUS) 0xC0000127L) -#endif - -#ifndef STATUS_FILE_CLOSED -# define STATUS_FILE_CLOSED ((NTSTATUS) 0xC0000128L) -#endif - -#ifndef STATUS_TOO_MANY_THREADS -# define STATUS_TOO_MANY_THREADS ((NTSTATUS) 0xC0000129L) -#endif - -#ifndef STATUS_THREAD_NOT_IN_PROCESS -# define STATUS_THREAD_NOT_IN_PROCESS ((NTSTATUS) 0xC000012AL) -#endif - -#ifndef STATUS_TOKEN_ALREADY_IN_USE -# define STATUS_TOKEN_ALREADY_IN_USE ((NTSTATUS) 0xC000012BL) -#endif - -#ifndef STATUS_PAGEFILE_QUOTA_EXCEEDED -# define STATUS_PAGEFILE_QUOTA_EXCEEDED ((NTSTATUS) 0xC000012CL) -#endif - -#ifndef STATUS_COMMITMENT_LIMIT -# define STATUS_COMMITMENT_LIMIT ((NTSTATUS) 0xC000012DL) -#endif - -#ifndef STATUS_INVALID_IMAGE_LE_FORMAT -# define STATUS_INVALID_IMAGE_LE_FORMAT ((NTSTATUS) 0xC000012EL) -#endif - -#ifndef STATUS_INVALID_IMAGE_NOT_MZ -# define STATUS_INVALID_IMAGE_NOT_MZ ((NTSTATUS) 0xC000012FL) -#endif - -#ifndef STATUS_INVALID_IMAGE_PROTECT -# define STATUS_INVALID_IMAGE_PROTECT ((NTSTATUS) 0xC0000130L) -#endif - -#ifndef STATUS_INVALID_IMAGE_WIN_16 -# define STATUS_INVALID_IMAGE_WIN_16 ((NTSTATUS) 0xC0000131L) -#endif - -#ifndef STATUS_LOGON_SERVER_CONFLICT -# define STATUS_LOGON_SERVER_CONFLICT ((NTSTATUS) 0xC0000132L) -#endif - -#ifndef STATUS_TIME_DIFFERENCE_AT_DC -# define STATUS_TIME_DIFFERENCE_AT_DC ((NTSTATUS) 0xC0000133L) -#endif - -#ifndef STATUS_SYNCHRONIZATION_REQUIRED -# define STATUS_SYNCHRONIZATION_REQUIRED ((NTSTATUS) 0xC0000134L) -#endif - -#ifndef STATUS_DLL_NOT_FOUND -# define STATUS_DLL_NOT_FOUND ((NTSTATUS) 0xC0000135L) -#endif - -#ifndef STATUS_OPEN_FAILED -# define STATUS_OPEN_FAILED ((NTSTATUS) 0xC0000136L) -#endif - -#ifndef STATUS_IO_PRIVILEGE_FAILED -# define STATUS_IO_PRIVILEGE_FAILED ((NTSTATUS) 0xC0000137L) -#endif - -#ifndef STATUS_ORDINAL_NOT_FOUND -# define STATUS_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000138L) -#endif - -#ifndef STATUS_ENTRYPOINT_NOT_FOUND -# define STATUS_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000139L) -#endif - -#ifndef STATUS_CONTROL_C_EXIT -# define STATUS_CONTROL_C_EXIT ((NTSTATUS) 0xC000013AL) -#endif - -#ifndef STATUS_LOCAL_DISCONNECT -# define STATUS_LOCAL_DISCONNECT ((NTSTATUS) 0xC000013BL) -#endif - -#ifndef STATUS_REMOTE_DISCONNECT -# define STATUS_REMOTE_DISCONNECT ((NTSTATUS) 0xC000013CL) -#endif - -#ifndef STATUS_REMOTE_RESOURCES -# define STATUS_REMOTE_RESOURCES ((NTSTATUS) 0xC000013DL) -#endif - -#ifndef STATUS_LINK_FAILED -# define STATUS_LINK_FAILED ((NTSTATUS) 0xC000013EL) -#endif - -#ifndef STATUS_LINK_TIMEOUT -# define STATUS_LINK_TIMEOUT ((NTSTATUS) 0xC000013FL) -#endif - -#ifndef STATUS_INVALID_CONNECTION -# define STATUS_INVALID_CONNECTION ((NTSTATUS) 0xC0000140L) -#endif - -#ifndef STATUS_INVALID_ADDRESS -# define STATUS_INVALID_ADDRESS ((NTSTATUS) 0xC0000141L) -#endif - -#ifndef STATUS_DLL_INIT_FAILED -# define STATUS_DLL_INIT_FAILED ((NTSTATUS) 0xC0000142L) -#endif - -#ifndef STATUS_MISSING_SYSTEMFILE -# define STATUS_MISSING_SYSTEMFILE ((NTSTATUS) 0xC0000143L) -#endif - -#ifndef STATUS_UNHANDLED_EXCEPTION -# define STATUS_UNHANDLED_EXCEPTION ((NTSTATUS) 0xC0000144L) -#endif - -#ifndef STATUS_APP_INIT_FAILURE -# define STATUS_APP_INIT_FAILURE ((NTSTATUS) 0xC0000145L) -#endif - -#ifndef STATUS_PAGEFILE_CREATE_FAILED -# define STATUS_PAGEFILE_CREATE_FAILED ((NTSTATUS) 0xC0000146L) -#endif - -#ifndef STATUS_NO_PAGEFILE -# define STATUS_NO_PAGEFILE ((NTSTATUS) 0xC0000147L) -#endif - -#ifndef STATUS_INVALID_LEVEL -# define STATUS_INVALID_LEVEL ((NTSTATUS) 0xC0000148L) -#endif - -#ifndef STATUS_WRONG_PASSWORD_CORE -# define STATUS_WRONG_PASSWORD_CORE ((NTSTATUS) 0xC0000149L) -#endif - -#ifndef STATUS_ILLEGAL_FLOAT_CONTEXT -# define STATUS_ILLEGAL_FLOAT_CONTEXT ((NTSTATUS) 0xC000014AL) -#endif - -#ifndef STATUS_PIPE_BROKEN -# define STATUS_PIPE_BROKEN ((NTSTATUS) 0xC000014BL) -#endif - -#ifndef STATUS_REGISTRY_CORRUPT -# define STATUS_REGISTRY_CORRUPT ((NTSTATUS) 0xC000014CL) -#endif - -#ifndef STATUS_REGISTRY_IO_FAILED -# define STATUS_REGISTRY_IO_FAILED ((NTSTATUS) 0xC000014DL) -#endif - -#ifndef STATUS_NO_EVENT_PAIR -# define STATUS_NO_EVENT_PAIR ((NTSTATUS) 0xC000014EL) -#endif - -#ifndef STATUS_UNRECOGNIZED_VOLUME -# define STATUS_UNRECOGNIZED_VOLUME ((NTSTATUS) 0xC000014FL) -#endif - -#ifndef STATUS_SERIAL_NO_DEVICE_INITED -# define STATUS_SERIAL_NO_DEVICE_INITED ((NTSTATUS) 0xC0000150L) -#endif - -#ifndef STATUS_NO_SUCH_ALIAS -# define STATUS_NO_SUCH_ALIAS ((NTSTATUS) 0xC0000151L) -#endif - -#ifndef STATUS_MEMBER_NOT_IN_ALIAS -# define STATUS_MEMBER_NOT_IN_ALIAS ((NTSTATUS) 0xC0000152L) -#endif - -#ifndef STATUS_MEMBER_IN_ALIAS -# define STATUS_MEMBER_IN_ALIAS ((NTSTATUS) 0xC0000153L) -#endif - -#ifndef STATUS_ALIAS_EXISTS -# define STATUS_ALIAS_EXISTS ((NTSTATUS) 0xC0000154L) -#endif - -#ifndef STATUS_LOGON_NOT_GRANTED -# define STATUS_LOGON_NOT_GRANTED ((NTSTATUS) 0xC0000155L) -#endif - -#ifndef STATUS_TOO_MANY_SECRETS -# define STATUS_TOO_MANY_SECRETS ((NTSTATUS) 0xC0000156L) -#endif - -#ifndef STATUS_SECRET_TOO_LONG -# define STATUS_SECRET_TOO_LONG ((NTSTATUS) 0xC0000157L) -#endif - -#ifndef STATUS_INTERNAL_DB_ERROR -# define STATUS_INTERNAL_DB_ERROR ((NTSTATUS) 0xC0000158L) -#endif - -#ifndef STATUS_FULLSCREEN_MODE -# define STATUS_FULLSCREEN_MODE ((NTSTATUS) 0xC0000159L) -#endif - -#ifndef STATUS_TOO_MANY_CONTEXT_IDS -# define STATUS_TOO_MANY_CONTEXT_IDS ((NTSTATUS) 0xC000015AL) -#endif - -#ifndef STATUS_LOGON_TYPE_NOT_GRANTED -# define STATUS_LOGON_TYPE_NOT_GRANTED ((NTSTATUS) 0xC000015BL) -#endif - -#ifndef STATUS_NOT_REGISTRY_FILE -# define STATUS_NOT_REGISTRY_FILE ((NTSTATUS) 0xC000015CL) -#endif - -#ifndef STATUS_NT_CROSS_ENCRYPTION_REQUIRED -# define STATUS_NT_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000015DL) -#endif - -#ifndef STATUS_DOMAIN_CTRLR_CONFIG_ERROR -# define STATUS_DOMAIN_CTRLR_CONFIG_ERROR ((NTSTATUS) 0xC000015EL) -#endif - -#ifndef STATUS_FT_MISSING_MEMBER -# define STATUS_FT_MISSING_MEMBER ((NTSTATUS) 0xC000015FL) -#endif - -#ifndef STATUS_ILL_FORMED_SERVICE_ENTRY -# define STATUS_ILL_FORMED_SERVICE_ENTRY ((NTSTATUS) 0xC0000160L) -#endif - -#ifndef STATUS_ILLEGAL_CHARACTER -# define STATUS_ILLEGAL_CHARACTER ((NTSTATUS) 0xC0000161L) -#endif - -#ifndef STATUS_UNMAPPABLE_CHARACTER -# define STATUS_UNMAPPABLE_CHARACTER ((NTSTATUS) 0xC0000162L) -#endif - -#ifndef STATUS_UNDEFINED_CHARACTER -# define STATUS_UNDEFINED_CHARACTER ((NTSTATUS) 0xC0000163L) -#endif - -#ifndef STATUS_FLOPPY_VOLUME -# define STATUS_FLOPPY_VOLUME ((NTSTATUS) 0xC0000164L) -#endif - -#ifndef STATUS_FLOPPY_ID_MARK_NOT_FOUND -# define STATUS_FLOPPY_ID_MARK_NOT_FOUND ((NTSTATUS) 0xC0000165L) -#endif - -#ifndef STATUS_FLOPPY_WRONG_CYLINDER -# define STATUS_FLOPPY_WRONG_CYLINDER ((NTSTATUS) 0xC0000166L) -#endif - -#ifndef STATUS_FLOPPY_UNKNOWN_ERROR -# define STATUS_FLOPPY_UNKNOWN_ERROR ((NTSTATUS) 0xC0000167L) -#endif - -#ifndef STATUS_FLOPPY_BAD_REGISTERS -# define STATUS_FLOPPY_BAD_REGISTERS ((NTSTATUS) 0xC0000168L) -#endif - -#ifndef STATUS_DISK_RECALIBRATE_FAILED -# define STATUS_DISK_RECALIBRATE_FAILED ((NTSTATUS) 0xC0000169L) -#endif - -#ifndef STATUS_DISK_OPERATION_FAILED -# define STATUS_DISK_OPERATION_FAILED ((NTSTATUS) 0xC000016AL) -#endif - -#ifndef STATUS_DISK_RESET_FAILED -# define STATUS_DISK_RESET_FAILED ((NTSTATUS) 0xC000016BL) -#endif - -#ifndef STATUS_SHARED_IRQ_BUSY -# define STATUS_SHARED_IRQ_BUSY ((NTSTATUS) 0xC000016CL) -#endif - -#ifndef STATUS_FT_ORPHANING -# define STATUS_FT_ORPHANING ((NTSTATUS) 0xC000016DL) -#endif - -#ifndef STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT -# define STATUS_BIOS_FAILED_TO_CONNECT_INTERRUPT ((NTSTATUS) 0xC000016EL) -#endif - -#ifndef STATUS_PARTITION_FAILURE -# define STATUS_PARTITION_FAILURE ((NTSTATUS) 0xC0000172L) -#endif - -#ifndef STATUS_INVALID_BLOCK_LENGTH -# define STATUS_INVALID_BLOCK_LENGTH ((NTSTATUS) 0xC0000173L) -#endif - -#ifndef STATUS_DEVICE_NOT_PARTITIONED -# define STATUS_DEVICE_NOT_PARTITIONED ((NTSTATUS) 0xC0000174L) -#endif - -#ifndef STATUS_UNABLE_TO_LOCK_MEDIA -# define STATUS_UNABLE_TO_LOCK_MEDIA ((NTSTATUS) 0xC0000175L) -#endif - -#ifndef STATUS_UNABLE_TO_UNLOAD_MEDIA -# define STATUS_UNABLE_TO_UNLOAD_MEDIA ((NTSTATUS) 0xC0000176L) -#endif - -#ifndef STATUS_EOM_OVERFLOW -# define STATUS_EOM_OVERFLOW ((NTSTATUS) 0xC0000177L) -#endif - -#ifndef STATUS_NO_MEDIA -# define STATUS_NO_MEDIA ((NTSTATUS) 0xC0000178L) -#endif - -#ifndef STATUS_NO_SUCH_MEMBER -# define STATUS_NO_SUCH_MEMBER ((NTSTATUS) 0xC000017AL) -#endif - -#ifndef STATUS_INVALID_MEMBER -# define STATUS_INVALID_MEMBER ((NTSTATUS) 0xC000017BL) -#endif - -#ifndef STATUS_KEY_DELETED -# define STATUS_KEY_DELETED ((NTSTATUS) 0xC000017CL) -#endif - -#ifndef STATUS_NO_LOG_SPACE -# define STATUS_NO_LOG_SPACE ((NTSTATUS) 0xC000017DL) -#endif - -#ifndef STATUS_TOO_MANY_SIDS -# define STATUS_TOO_MANY_SIDS ((NTSTATUS) 0xC000017EL) -#endif - -#ifndef STATUS_LM_CROSS_ENCRYPTION_REQUIRED -# define STATUS_LM_CROSS_ENCRYPTION_REQUIRED ((NTSTATUS) 0xC000017FL) -#endif - -#ifndef STATUS_KEY_HAS_CHILDREN -# define STATUS_KEY_HAS_CHILDREN ((NTSTATUS) 0xC0000180L) -#endif - -#ifndef STATUS_CHILD_MUST_BE_VOLATILE -# define STATUS_CHILD_MUST_BE_VOLATILE ((NTSTATUS) 0xC0000181L) -#endif - -#ifndef STATUS_DEVICE_CONFIGURATION_ERROR -# define STATUS_DEVICE_CONFIGURATION_ERROR ((NTSTATUS) 0xC0000182L) -#endif - -#ifndef STATUS_DRIVER_INTERNAL_ERROR -# define STATUS_DRIVER_INTERNAL_ERROR ((NTSTATUS) 0xC0000183L) -#endif - -#ifndef STATUS_INVALID_DEVICE_STATE -# define STATUS_INVALID_DEVICE_STATE ((NTSTATUS) 0xC0000184L) -#endif - -#ifndef STATUS_IO_DEVICE_ERROR -# define STATUS_IO_DEVICE_ERROR ((NTSTATUS) 0xC0000185L) -#endif - -#ifndef STATUS_DEVICE_PROTOCOL_ERROR -# define STATUS_DEVICE_PROTOCOL_ERROR ((NTSTATUS) 0xC0000186L) -#endif - -#ifndef STATUS_BACKUP_CONTROLLER -# define STATUS_BACKUP_CONTROLLER ((NTSTATUS) 0xC0000187L) -#endif - -#ifndef STATUS_LOG_FILE_FULL -# define STATUS_LOG_FILE_FULL ((NTSTATUS) 0xC0000188L) -#endif - -#ifndef STATUS_TOO_LATE -# define STATUS_TOO_LATE ((NTSTATUS) 0xC0000189L) -#endif - -#ifndef STATUS_NO_TRUST_LSA_SECRET -# define STATUS_NO_TRUST_LSA_SECRET ((NTSTATUS) 0xC000018AL) -#endif - -#ifndef STATUS_NO_TRUST_SAM_ACCOUNT -# define STATUS_NO_TRUST_SAM_ACCOUNT ((NTSTATUS) 0xC000018BL) -#endif - -#ifndef STATUS_TRUSTED_DOMAIN_FAILURE -# define STATUS_TRUSTED_DOMAIN_FAILURE ((NTSTATUS) 0xC000018CL) -#endif - -#ifndef STATUS_TRUSTED_RELATIONSHIP_FAILURE -# define STATUS_TRUSTED_RELATIONSHIP_FAILURE ((NTSTATUS) 0xC000018DL) -#endif - -#ifndef STATUS_EVENTLOG_FILE_CORRUPT -# define STATUS_EVENTLOG_FILE_CORRUPT ((NTSTATUS) 0xC000018EL) -#endif - -#ifndef STATUS_EVENTLOG_CANT_START -# define STATUS_EVENTLOG_CANT_START ((NTSTATUS) 0xC000018FL) -#endif - -#ifndef STATUS_TRUST_FAILURE -# define STATUS_TRUST_FAILURE ((NTSTATUS) 0xC0000190L) -#endif - -#ifndef STATUS_MUTANT_LIMIT_EXCEEDED -# define STATUS_MUTANT_LIMIT_EXCEEDED ((NTSTATUS) 0xC0000191L) -#endif - -#ifndef STATUS_NETLOGON_NOT_STARTED -# define STATUS_NETLOGON_NOT_STARTED ((NTSTATUS) 0xC0000192L) -#endif - -#ifndef STATUS_ACCOUNT_EXPIRED -# define STATUS_ACCOUNT_EXPIRED ((NTSTATUS) 0xC0000193L) -#endif - -#ifndef STATUS_POSSIBLE_DEADLOCK -# define STATUS_POSSIBLE_DEADLOCK ((NTSTATUS) 0xC0000194L) -#endif - -#ifndef STATUS_NETWORK_CREDENTIAL_CONFLICT -# define STATUS_NETWORK_CREDENTIAL_CONFLICT ((NTSTATUS) 0xC0000195L) -#endif - -#ifndef STATUS_REMOTE_SESSION_LIMIT -# define STATUS_REMOTE_SESSION_LIMIT ((NTSTATUS) 0xC0000196L) -#endif - -#ifndef STATUS_EVENTLOG_FILE_CHANGED -# define STATUS_EVENTLOG_FILE_CHANGED ((NTSTATUS) 0xC0000197L) -#endif - -#ifndef STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT -# define STATUS_NOLOGON_INTERDOMAIN_TRUST_ACCOUNT ((NTSTATUS) 0xC0000198L) -#endif - -#ifndef STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT -# define STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT ((NTSTATUS) 0xC0000199L) -#endif - -#ifndef STATUS_NOLOGON_SERVER_TRUST_ACCOUNT -# define STATUS_NOLOGON_SERVER_TRUST_ACCOUNT ((NTSTATUS) 0xC000019AL) -#endif - -#ifndef STATUS_DOMAIN_TRUST_INCONSISTENT -# define STATUS_DOMAIN_TRUST_INCONSISTENT ((NTSTATUS) 0xC000019BL) -#endif - -#ifndef STATUS_FS_DRIVER_REQUIRED -# define STATUS_FS_DRIVER_REQUIRED ((NTSTATUS) 0xC000019CL) -#endif - -#ifndef STATUS_IMAGE_ALREADY_LOADED_AS_DLL -# define STATUS_IMAGE_ALREADY_LOADED_AS_DLL ((NTSTATUS) 0xC000019DL) -#endif - -#ifndef STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING -# define STATUS_INCOMPATIBLE_WITH_GLOBAL_SHORT_NAME_REGISTRY_SETTING ((NTSTATUS) 0xC000019EL) -#endif - -#ifndef STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME -# define STATUS_SHORT_NAMES_NOT_ENABLED_ON_VOLUME ((NTSTATUS) 0xC000019FL) -#endif - -#ifndef STATUS_SECURITY_STREAM_IS_INCONSISTENT -# define STATUS_SECURITY_STREAM_IS_INCONSISTENT ((NTSTATUS) 0xC00001A0L) -#endif - -#ifndef STATUS_INVALID_LOCK_RANGE -# define STATUS_INVALID_LOCK_RANGE ((NTSTATUS) 0xC00001A1L) -#endif - -#ifndef STATUS_INVALID_ACE_CONDITION -# define STATUS_INVALID_ACE_CONDITION ((NTSTATUS) 0xC00001A2L) -#endif - -#ifndef STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT -# define STATUS_IMAGE_SUBSYSTEM_NOT_PRESENT ((NTSTATUS) 0xC00001A3L) -#endif - -#ifndef STATUS_NOTIFICATION_GUID_ALREADY_DEFINED -# define STATUS_NOTIFICATION_GUID_ALREADY_DEFINED ((NTSTATUS) 0xC00001A4L) -#endif - -#ifndef STATUS_NETWORK_OPEN_RESTRICTION -# define STATUS_NETWORK_OPEN_RESTRICTION ((NTSTATUS) 0xC0000201L) -#endif - -#ifndef STATUS_NO_USER_SESSION_KEY -# define STATUS_NO_USER_SESSION_KEY ((NTSTATUS) 0xC0000202L) -#endif - -#ifndef STATUS_USER_SESSION_DELETED -# define STATUS_USER_SESSION_DELETED ((NTSTATUS) 0xC0000203L) -#endif - -#ifndef STATUS_RESOURCE_LANG_NOT_FOUND -# define STATUS_RESOURCE_LANG_NOT_FOUND ((NTSTATUS) 0xC0000204L) -#endif - -#ifndef STATUS_INSUFF_SERVER_RESOURCES -# define STATUS_INSUFF_SERVER_RESOURCES ((NTSTATUS) 0xC0000205L) -#endif - -#ifndef STATUS_INVALID_BUFFER_SIZE -# define STATUS_INVALID_BUFFER_SIZE ((NTSTATUS) 0xC0000206L) -#endif - -#ifndef STATUS_INVALID_ADDRESS_COMPONENT -# define STATUS_INVALID_ADDRESS_COMPONENT ((NTSTATUS) 0xC0000207L) -#endif - -#ifndef STATUS_INVALID_ADDRESS_WILDCARD -# define STATUS_INVALID_ADDRESS_WILDCARD ((NTSTATUS) 0xC0000208L) -#endif - -#ifndef STATUS_TOO_MANY_ADDRESSES -# define STATUS_TOO_MANY_ADDRESSES ((NTSTATUS) 0xC0000209L) -#endif - -#ifndef STATUS_ADDRESS_ALREADY_EXISTS -# define STATUS_ADDRESS_ALREADY_EXISTS ((NTSTATUS) 0xC000020AL) -#endif - -#ifndef STATUS_ADDRESS_CLOSED -# define STATUS_ADDRESS_CLOSED ((NTSTATUS) 0xC000020BL) -#endif - -#ifndef STATUS_CONNECTION_DISCONNECTED -# define STATUS_CONNECTION_DISCONNECTED ((NTSTATUS) 0xC000020CL) -#endif - -#ifndef STATUS_CONNECTION_RESET -# define STATUS_CONNECTION_RESET ((NTSTATUS) 0xC000020DL) -#endif - -#ifndef STATUS_TOO_MANY_NODES -# define STATUS_TOO_MANY_NODES ((NTSTATUS) 0xC000020EL) -#endif - -#ifndef STATUS_TRANSACTION_ABORTED -# define STATUS_TRANSACTION_ABORTED ((NTSTATUS) 0xC000020FL) -#endif - -#ifndef STATUS_TRANSACTION_TIMED_OUT -# define STATUS_TRANSACTION_TIMED_OUT ((NTSTATUS) 0xC0000210L) -#endif - -#ifndef STATUS_TRANSACTION_NO_RELEASE -# define STATUS_TRANSACTION_NO_RELEASE ((NTSTATUS) 0xC0000211L) -#endif - -#ifndef STATUS_TRANSACTION_NO_MATCH -# define STATUS_TRANSACTION_NO_MATCH ((NTSTATUS) 0xC0000212L) -#endif - -#ifndef STATUS_TRANSACTION_RESPONDED -# define STATUS_TRANSACTION_RESPONDED ((NTSTATUS) 0xC0000213L) -#endif - -#ifndef STATUS_TRANSACTION_INVALID_ID -# define STATUS_TRANSACTION_INVALID_ID ((NTSTATUS) 0xC0000214L) -#endif - -#ifndef STATUS_TRANSACTION_INVALID_TYPE -# define STATUS_TRANSACTION_INVALID_TYPE ((NTSTATUS) 0xC0000215L) -#endif - -#ifndef STATUS_NOT_SERVER_SESSION -# define STATUS_NOT_SERVER_SESSION ((NTSTATUS) 0xC0000216L) -#endif - -#ifndef STATUS_NOT_CLIENT_SESSION -# define STATUS_NOT_CLIENT_SESSION ((NTSTATUS) 0xC0000217L) -#endif - -#ifndef STATUS_CANNOT_LOAD_REGISTRY_FILE -# define STATUS_CANNOT_LOAD_REGISTRY_FILE ((NTSTATUS) 0xC0000218L) -#endif - -#ifndef STATUS_DEBUG_ATTACH_FAILED -# define STATUS_DEBUG_ATTACH_FAILED ((NTSTATUS) 0xC0000219L) -#endif - -#ifndef STATUS_SYSTEM_PROCESS_TERMINATED -# define STATUS_SYSTEM_PROCESS_TERMINATED ((NTSTATUS) 0xC000021AL) -#endif - -#ifndef STATUS_DATA_NOT_ACCEPTED -# define STATUS_DATA_NOT_ACCEPTED ((NTSTATUS) 0xC000021BL) -#endif - -#ifndef STATUS_NO_BROWSER_SERVERS_FOUND -# define STATUS_NO_BROWSER_SERVERS_FOUND ((NTSTATUS) 0xC000021CL) -#endif - -#ifndef STATUS_VDM_HARD_ERROR -# define STATUS_VDM_HARD_ERROR ((NTSTATUS) 0xC000021DL) -#endif - -#ifndef STATUS_DRIVER_CANCEL_TIMEOUT -# define STATUS_DRIVER_CANCEL_TIMEOUT ((NTSTATUS) 0xC000021EL) -#endif - -#ifndef STATUS_REPLY_MESSAGE_MISMATCH -# define STATUS_REPLY_MESSAGE_MISMATCH ((NTSTATUS) 0xC000021FL) -#endif - -#ifndef STATUS_MAPPED_ALIGNMENT -# define STATUS_MAPPED_ALIGNMENT ((NTSTATUS) 0xC0000220L) -#endif - -#ifndef STATUS_IMAGE_CHECKSUM_MISMATCH -# define STATUS_IMAGE_CHECKSUM_MISMATCH ((NTSTATUS) 0xC0000221L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA -# define STATUS_LOST_WRITEBEHIND_DATA ((NTSTATUS) 0xC0000222L) -#endif - -#ifndef STATUS_CLIENT_SERVER_PARAMETERS_INVALID -# define STATUS_CLIENT_SERVER_PARAMETERS_INVALID ((NTSTATUS) 0xC0000223L) -#endif - -#ifndef STATUS_PASSWORD_MUST_CHANGE -# define STATUS_PASSWORD_MUST_CHANGE ((NTSTATUS) 0xC0000224L) -#endif - -#ifndef STATUS_NOT_FOUND -# define STATUS_NOT_FOUND ((NTSTATUS) 0xC0000225L) -#endif - -#ifndef STATUS_NOT_TINY_STREAM -# define STATUS_NOT_TINY_STREAM ((NTSTATUS) 0xC0000226L) -#endif - -#ifndef STATUS_RECOVERY_FAILURE -# define STATUS_RECOVERY_FAILURE ((NTSTATUS) 0xC0000227L) -#endif - -#ifndef STATUS_STACK_OVERFLOW_READ -# define STATUS_STACK_OVERFLOW_READ ((NTSTATUS) 0xC0000228L) -#endif - -#ifndef STATUS_FAIL_CHECK -# define STATUS_FAIL_CHECK ((NTSTATUS) 0xC0000229L) -#endif - -#ifndef STATUS_DUPLICATE_OBJECTID -# define STATUS_DUPLICATE_OBJECTID ((NTSTATUS) 0xC000022AL) -#endif - -#ifndef STATUS_OBJECTID_EXISTS -# define STATUS_OBJECTID_EXISTS ((NTSTATUS) 0xC000022BL) -#endif - -#ifndef STATUS_CONVERT_TO_LARGE -# define STATUS_CONVERT_TO_LARGE ((NTSTATUS) 0xC000022CL) -#endif - -#ifndef STATUS_RETRY -# define STATUS_RETRY ((NTSTATUS) 0xC000022DL) -#endif - -#ifndef STATUS_FOUND_OUT_OF_SCOPE -# define STATUS_FOUND_OUT_OF_SCOPE ((NTSTATUS) 0xC000022EL) -#endif - -#ifndef STATUS_ALLOCATE_BUCKET -# define STATUS_ALLOCATE_BUCKET ((NTSTATUS) 0xC000022FL) -#endif - -#ifndef STATUS_PROPSET_NOT_FOUND -# define STATUS_PROPSET_NOT_FOUND ((NTSTATUS) 0xC0000230L) -#endif - -#ifndef STATUS_MARSHALL_OVERFLOW -# define STATUS_MARSHALL_OVERFLOW ((NTSTATUS) 0xC0000231L) -#endif - -#ifndef STATUS_INVALID_VARIANT -# define STATUS_INVALID_VARIANT ((NTSTATUS) 0xC0000232L) -#endif - -#ifndef STATUS_DOMAIN_CONTROLLER_NOT_FOUND -# define STATUS_DOMAIN_CONTROLLER_NOT_FOUND ((NTSTATUS) 0xC0000233L) -#endif - -#ifndef STATUS_ACCOUNT_LOCKED_OUT -# define STATUS_ACCOUNT_LOCKED_OUT ((NTSTATUS) 0xC0000234L) -#endif - -#ifndef STATUS_HANDLE_NOT_CLOSABLE -# define STATUS_HANDLE_NOT_CLOSABLE ((NTSTATUS) 0xC0000235L) -#endif - -#ifndef STATUS_CONNECTION_REFUSED -# define STATUS_CONNECTION_REFUSED ((NTSTATUS) 0xC0000236L) -#endif - -#ifndef STATUS_GRACEFUL_DISCONNECT -# define STATUS_GRACEFUL_DISCONNECT ((NTSTATUS) 0xC0000237L) -#endif - -#ifndef STATUS_ADDRESS_ALREADY_ASSOCIATED -# define STATUS_ADDRESS_ALREADY_ASSOCIATED ((NTSTATUS) 0xC0000238L) -#endif - -#ifndef STATUS_ADDRESS_NOT_ASSOCIATED -# define STATUS_ADDRESS_NOT_ASSOCIATED ((NTSTATUS) 0xC0000239L) -#endif - -#ifndef STATUS_CONNECTION_INVALID -# define STATUS_CONNECTION_INVALID ((NTSTATUS) 0xC000023AL) -#endif - -#ifndef STATUS_CONNECTION_ACTIVE -# define STATUS_CONNECTION_ACTIVE ((NTSTATUS) 0xC000023BL) -#endif - -#ifndef STATUS_NETWORK_UNREACHABLE -# define STATUS_NETWORK_UNREACHABLE ((NTSTATUS) 0xC000023CL) -#endif - -#ifndef STATUS_HOST_UNREACHABLE -# define STATUS_HOST_UNREACHABLE ((NTSTATUS) 0xC000023DL) -#endif - -#ifndef STATUS_PROTOCOL_UNREACHABLE -# define STATUS_PROTOCOL_UNREACHABLE ((NTSTATUS) 0xC000023EL) -#endif - -#ifndef STATUS_PORT_UNREACHABLE -# define STATUS_PORT_UNREACHABLE ((NTSTATUS) 0xC000023FL) -#endif - -#ifndef STATUS_REQUEST_ABORTED -# define STATUS_REQUEST_ABORTED ((NTSTATUS) 0xC0000240L) -#endif - -#ifndef STATUS_CONNECTION_ABORTED -# define STATUS_CONNECTION_ABORTED ((NTSTATUS) 0xC0000241L) -#endif - -#ifndef STATUS_BAD_COMPRESSION_BUFFER -# define STATUS_BAD_COMPRESSION_BUFFER ((NTSTATUS) 0xC0000242L) -#endif - -#ifndef STATUS_USER_MAPPED_FILE -# define STATUS_USER_MAPPED_FILE ((NTSTATUS) 0xC0000243L) -#endif - -#ifndef STATUS_AUDIT_FAILED -# define STATUS_AUDIT_FAILED ((NTSTATUS) 0xC0000244L) -#endif - -#ifndef STATUS_TIMER_RESOLUTION_NOT_SET -# define STATUS_TIMER_RESOLUTION_NOT_SET ((NTSTATUS) 0xC0000245L) -#endif - -#ifndef STATUS_CONNECTION_COUNT_LIMIT -# define STATUS_CONNECTION_COUNT_LIMIT ((NTSTATUS) 0xC0000246L) -#endif - -#ifndef STATUS_LOGIN_TIME_RESTRICTION -# define STATUS_LOGIN_TIME_RESTRICTION ((NTSTATUS) 0xC0000247L) -#endif - -#ifndef STATUS_LOGIN_WKSTA_RESTRICTION -# define STATUS_LOGIN_WKSTA_RESTRICTION ((NTSTATUS) 0xC0000248L) -#endif - -#ifndef STATUS_IMAGE_MP_UP_MISMATCH -# define STATUS_IMAGE_MP_UP_MISMATCH ((NTSTATUS) 0xC0000249L) -#endif - -#ifndef STATUS_INSUFFICIENT_LOGON_INFO -# define STATUS_INSUFFICIENT_LOGON_INFO ((NTSTATUS) 0xC0000250L) -#endif - -#ifndef STATUS_BAD_DLL_ENTRYPOINT -# define STATUS_BAD_DLL_ENTRYPOINT ((NTSTATUS) 0xC0000251L) -#endif - -#ifndef STATUS_BAD_SERVICE_ENTRYPOINT -# define STATUS_BAD_SERVICE_ENTRYPOINT ((NTSTATUS) 0xC0000252L) -#endif - -#ifndef STATUS_LPC_REPLY_LOST -# define STATUS_LPC_REPLY_LOST ((NTSTATUS) 0xC0000253L) -#endif - -#ifndef STATUS_IP_ADDRESS_CONFLICT1 -# define STATUS_IP_ADDRESS_CONFLICT1 ((NTSTATUS) 0xC0000254L) -#endif - -#ifndef STATUS_IP_ADDRESS_CONFLICT2 -# define STATUS_IP_ADDRESS_CONFLICT2 ((NTSTATUS) 0xC0000255L) -#endif - -#ifndef STATUS_REGISTRY_QUOTA_LIMIT -# define STATUS_REGISTRY_QUOTA_LIMIT ((NTSTATUS) 0xC0000256L) -#endif - -#ifndef STATUS_PATH_NOT_COVERED -# define STATUS_PATH_NOT_COVERED ((NTSTATUS) 0xC0000257L) -#endif - -#ifndef STATUS_NO_CALLBACK_ACTIVE -# define STATUS_NO_CALLBACK_ACTIVE ((NTSTATUS) 0xC0000258L) -#endif - -#ifndef STATUS_LICENSE_QUOTA_EXCEEDED -# define STATUS_LICENSE_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000259L) -#endif - -#ifndef STATUS_PWD_TOO_SHORT -# define STATUS_PWD_TOO_SHORT ((NTSTATUS) 0xC000025AL) -#endif - -#ifndef STATUS_PWD_TOO_RECENT -# define STATUS_PWD_TOO_RECENT ((NTSTATUS) 0xC000025BL) -#endif - -#ifndef STATUS_PWD_HISTORY_CONFLICT -# define STATUS_PWD_HISTORY_CONFLICT ((NTSTATUS) 0xC000025CL) -#endif - -#ifndef STATUS_PLUGPLAY_NO_DEVICE -# define STATUS_PLUGPLAY_NO_DEVICE ((NTSTATUS) 0xC000025EL) -#endif - -#ifndef STATUS_UNSUPPORTED_COMPRESSION -# define STATUS_UNSUPPORTED_COMPRESSION ((NTSTATUS) 0xC000025FL) -#endif - -#ifndef STATUS_INVALID_HW_PROFILE -# define STATUS_INVALID_HW_PROFILE ((NTSTATUS) 0xC0000260L) -#endif - -#ifndef STATUS_INVALID_PLUGPLAY_DEVICE_PATH -# define STATUS_INVALID_PLUGPLAY_DEVICE_PATH ((NTSTATUS) 0xC0000261L) -#endif - -#ifndef STATUS_DRIVER_ORDINAL_NOT_FOUND -# define STATUS_DRIVER_ORDINAL_NOT_FOUND ((NTSTATUS) 0xC0000262L) -#endif - -#ifndef STATUS_DRIVER_ENTRYPOINT_NOT_FOUND -# define STATUS_DRIVER_ENTRYPOINT_NOT_FOUND ((NTSTATUS) 0xC0000263L) -#endif - -#ifndef STATUS_RESOURCE_NOT_OWNED -# define STATUS_RESOURCE_NOT_OWNED ((NTSTATUS) 0xC0000264L) -#endif - -#ifndef STATUS_TOO_MANY_LINKS -# define STATUS_TOO_MANY_LINKS ((NTSTATUS) 0xC0000265L) -#endif - -#ifndef STATUS_QUOTA_LIST_INCONSISTENT -# define STATUS_QUOTA_LIST_INCONSISTENT ((NTSTATUS) 0xC0000266L) -#endif - -#ifndef STATUS_FILE_IS_OFFLINE -# define STATUS_FILE_IS_OFFLINE ((NTSTATUS) 0xC0000267L) -#endif - -#ifndef STATUS_EVALUATION_EXPIRATION -# define STATUS_EVALUATION_EXPIRATION ((NTSTATUS) 0xC0000268L) -#endif - -#ifndef STATUS_ILLEGAL_DLL_RELOCATION -# define STATUS_ILLEGAL_DLL_RELOCATION ((NTSTATUS) 0xC0000269L) -#endif - -#ifndef STATUS_LICENSE_VIOLATION -# define STATUS_LICENSE_VIOLATION ((NTSTATUS) 0xC000026AL) -#endif - -#ifndef STATUS_DLL_INIT_FAILED_LOGOFF -# define STATUS_DLL_INIT_FAILED_LOGOFF ((NTSTATUS) 0xC000026BL) -#endif - -#ifndef STATUS_DRIVER_UNABLE_TO_LOAD -# define STATUS_DRIVER_UNABLE_TO_LOAD ((NTSTATUS) 0xC000026CL) -#endif - -#ifndef STATUS_DFS_UNAVAILABLE -# define STATUS_DFS_UNAVAILABLE ((NTSTATUS) 0xC000026DL) -#endif - -#ifndef STATUS_VOLUME_DISMOUNTED -# define STATUS_VOLUME_DISMOUNTED ((NTSTATUS) 0xC000026EL) -#endif - -#ifndef STATUS_WX86_INTERNAL_ERROR -# define STATUS_WX86_INTERNAL_ERROR ((NTSTATUS) 0xC000026FL) -#endif - -#ifndef STATUS_WX86_FLOAT_STACK_CHECK -# define STATUS_WX86_FLOAT_STACK_CHECK ((NTSTATUS) 0xC0000270L) -#endif - -#ifndef STATUS_VALIDATE_CONTINUE -# define STATUS_VALIDATE_CONTINUE ((NTSTATUS) 0xC0000271L) -#endif - -#ifndef STATUS_NO_MATCH -# define STATUS_NO_MATCH ((NTSTATUS) 0xC0000272L) -#endif - -#ifndef STATUS_NO_MORE_MATCHES -# define STATUS_NO_MORE_MATCHES ((NTSTATUS) 0xC0000273L) -#endif - -#ifndef STATUS_NOT_A_REPARSE_POINT -# define STATUS_NOT_A_REPARSE_POINT ((NTSTATUS) 0xC0000275L) -#endif - -#ifndef STATUS_IO_REPARSE_TAG_INVALID -# define STATUS_IO_REPARSE_TAG_INVALID ((NTSTATUS) 0xC0000276L) -#endif - -#ifndef STATUS_IO_REPARSE_TAG_MISMATCH -# define STATUS_IO_REPARSE_TAG_MISMATCH ((NTSTATUS) 0xC0000277L) -#endif - -#ifndef STATUS_IO_REPARSE_DATA_INVALID -# define STATUS_IO_REPARSE_DATA_INVALID ((NTSTATUS) 0xC0000278L) -#endif - -#ifndef STATUS_IO_REPARSE_TAG_NOT_HANDLED -# define STATUS_IO_REPARSE_TAG_NOT_HANDLED ((NTSTATUS) 0xC0000279L) -#endif - -#ifndef STATUS_REPARSE_POINT_NOT_RESOLVED -# define STATUS_REPARSE_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000280L) -#endif - -#ifndef STATUS_DIRECTORY_IS_A_REPARSE_POINT -# define STATUS_DIRECTORY_IS_A_REPARSE_POINT ((NTSTATUS) 0xC0000281L) -#endif - -#ifndef STATUS_RANGE_LIST_CONFLICT -# define STATUS_RANGE_LIST_CONFLICT ((NTSTATUS) 0xC0000282L) -#endif - -#ifndef STATUS_SOURCE_ELEMENT_EMPTY -# define STATUS_SOURCE_ELEMENT_EMPTY ((NTSTATUS) 0xC0000283L) -#endif - -#ifndef STATUS_DESTINATION_ELEMENT_FULL -# define STATUS_DESTINATION_ELEMENT_FULL ((NTSTATUS) 0xC0000284L) -#endif - -#ifndef STATUS_ILLEGAL_ELEMENT_ADDRESS -# define STATUS_ILLEGAL_ELEMENT_ADDRESS ((NTSTATUS) 0xC0000285L) -#endif - -#ifndef STATUS_MAGAZINE_NOT_PRESENT -# define STATUS_MAGAZINE_NOT_PRESENT ((NTSTATUS) 0xC0000286L) -#endif - -#ifndef STATUS_REINITIALIZATION_NEEDED -# define STATUS_REINITIALIZATION_NEEDED ((NTSTATUS) 0xC0000287L) -#endif - -#ifndef STATUS_DEVICE_REQUIRES_CLEANING -# define STATUS_DEVICE_REQUIRES_CLEANING ((NTSTATUS) 0x80000288L) -#endif - -#ifndef STATUS_DEVICE_DOOR_OPEN -# define STATUS_DEVICE_DOOR_OPEN ((NTSTATUS) 0x80000289L) -#endif - -#ifndef STATUS_ENCRYPTION_FAILED -# define STATUS_ENCRYPTION_FAILED ((NTSTATUS) 0xC000028AL) -#endif - -#ifndef STATUS_DECRYPTION_FAILED -# define STATUS_DECRYPTION_FAILED ((NTSTATUS) 0xC000028BL) -#endif - -#ifndef STATUS_RANGE_NOT_FOUND -# define STATUS_RANGE_NOT_FOUND ((NTSTATUS) 0xC000028CL) -#endif - -#ifndef STATUS_NO_RECOVERY_POLICY -# define STATUS_NO_RECOVERY_POLICY ((NTSTATUS) 0xC000028DL) -#endif - -#ifndef STATUS_NO_EFS -# define STATUS_NO_EFS ((NTSTATUS) 0xC000028EL) -#endif - -#ifndef STATUS_WRONG_EFS -# define STATUS_WRONG_EFS ((NTSTATUS) 0xC000028FL) -#endif - -#ifndef STATUS_NO_USER_KEYS -# define STATUS_NO_USER_KEYS ((NTSTATUS) 0xC0000290L) -#endif - -#ifndef STATUS_FILE_NOT_ENCRYPTED -# define STATUS_FILE_NOT_ENCRYPTED ((NTSTATUS) 0xC0000291L) -#endif - -#ifndef STATUS_NOT_EXPORT_FORMAT -# define STATUS_NOT_EXPORT_FORMAT ((NTSTATUS) 0xC0000292L) -#endif - -#ifndef STATUS_FILE_ENCRYPTED -# define STATUS_FILE_ENCRYPTED ((NTSTATUS) 0xC0000293L) -#endif - -#ifndef STATUS_WAKE_SYSTEM -# define STATUS_WAKE_SYSTEM ((NTSTATUS) 0x40000294L) -#endif - -#ifndef STATUS_WMI_GUID_NOT_FOUND -# define STATUS_WMI_GUID_NOT_FOUND ((NTSTATUS) 0xC0000295L) -#endif - -#ifndef STATUS_WMI_INSTANCE_NOT_FOUND -# define STATUS_WMI_INSTANCE_NOT_FOUND ((NTSTATUS) 0xC0000296L) -#endif - -#ifndef STATUS_WMI_ITEMID_NOT_FOUND -# define STATUS_WMI_ITEMID_NOT_FOUND ((NTSTATUS) 0xC0000297L) -#endif - -#ifndef STATUS_WMI_TRY_AGAIN -# define STATUS_WMI_TRY_AGAIN ((NTSTATUS) 0xC0000298L) -#endif - -#ifndef STATUS_SHARED_POLICY -# define STATUS_SHARED_POLICY ((NTSTATUS) 0xC0000299L) -#endif - -#ifndef STATUS_POLICY_OBJECT_NOT_FOUND -# define STATUS_POLICY_OBJECT_NOT_FOUND ((NTSTATUS) 0xC000029AL) -#endif - -#ifndef STATUS_POLICY_ONLY_IN_DS -# define STATUS_POLICY_ONLY_IN_DS ((NTSTATUS) 0xC000029BL) -#endif - -#ifndef STATUS_VOLUME_NOT_UPGRADED -# define STATUS_VOLUME_NOT_UPGRADED ((NTSTATUS) 0xC000029CL) -#endif - -#ifndef STATUS_REMOTE_STORAGE_NOT_ACTIVE -# define STATUS_REMOTE_STORAGE_NOT_ACTIVE ((NTSTATUS) 0xC000029DL) -#endif - -#ifndef STATUS_REMOTE_STORAGE_MEDIA_ERROR -# define STATUS_REMOTE_STORAGE_MEDIA_ERROR ((NTSTATUS) 0xC000029EL) -#endif - -#ifndef STATUS_NO_TRACKING_SERVICE -# define STATUS_NO_TRACKING_SERVICE ((NTSTATUS) 0xC000029FL) -#endif - -#ifndef STATUS_SERVER_SID_MISMATCH -# define STATUS_SERVER_SID_MISMATCH ((NTSTATUS) 0xC00002A0L) -#endif - -#ifndef STATUS_DS_NO_ATTRIBUTE_OR_VALUE -# define STATUS_DS_NO_ATTRIBUTE_OR_VALUE ((NTSTATUS) 0xC00002A1L) -#endif - -#ifndef STATUS_DS_INVALID_ATTRIBUTE_SYNTAX -# define STATUS_DS_INVALID_ATTRIBUTE_SYNTAX ((NTSTATUS) 0xC00002A2L) -#endif - -#ifndef STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED -# define STATUS_DS_ATTRIBUTE_TYPE_UNDEFINED ((NTSTATUS) 0xC00002A3L) -#endif - -#ifndef STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS -# define STATUS_DS_ATTRIBUTE_OR_VALUE_EXISTS ((NTSTATUS) 0xC00002A4L) -#endif - -#ifndef STATUS_DS_BUSY -# define STATUS_DS_BUSY ((NTSTATUS) 0xC00002A5L) -#endif - -#ifndef STATUS_DS_UNAVAILABLE -# define STATUS_DS_UNAVAILABLE ((NTSTATUS) 0xC00002A6L) -#endif - -#ifndef STATUS_DS_NO_RIDS_ALLOCATED -# define STATUS_DS_NO_RIDS_ALLOCATED ((NTSTATUS) 0xC00002A7L) -#endif - -#ifndef STATUS_DS_NO_MORE_RIDS -# define STATUS_DS_NO_MORE_RIDS ((NTSTATUS) 0xC00002A8L) -#endif - -#ifndef STATUS_DS_INCORRECT_ROLE_OWNER -# define STATUS_DS_INCORRECT_ROLE_OWNER ((NTSTATUS) 0xC00002A9L) -#endif - -#ifndef STATUS_DS_RIDMGR_INIT_ERROR -# define STATUS_DS_RIDMGR_INIT_ERROR ((NTSTATUS) 0xC00002AAL) -#endif - -#ifndef STATUS_DS_OBJ_CLASS_VIOLATION -# define STATUS_DS_OBJ_CLASS_VIOLATION ((NTSTATUS) 0xC00002ABL) -#endif - -#ifndef STATUS_DS_CANT_ON_NON_LEAF -# define STATUS_DS_CANT_ON_NON_LEAF ((NTSTATUS) 0xC00002ACL) -#endif - -#ifndef STATUS_DS_CANT_ON_RDN -# define STATUS_DS_CANT_ON_RDN ((NTSTATUS) 0xC00002ADL) -#endif - -#ifndef STATUS_DS_CANT_MOD_OBJ_CLASS -# define STATUS_DS_CANT_MOD_OBJ_CLASS ((NTSTATUS) 0xC00002AEL) -#endif - -#ifndef STATUS_DS_CROSS_DOM_MOVE_FAILED -# define STATUS_DS_CROSS_DOM_MOVE_FAILED ((NTSTATUS) 0xC00002AFL) -#endif - -#ifndef STATUS_DS_GC_NOT_AVAILABLE -# define STATUS_DS_GC_NOT_AVAILABLE ((NTSTATUS) 0xC00002B0L) -#endif - -#ifndef STATUS_DIRECTORY_SERVICE_REQUIRED -# define STATUS_DIRECTORY_SERVICE_REQUIRED ((NTSTATUS) 0xC00002B1L) -#endif - -#ifndef STATUS_REPARSE_ATTRIBUTE_CONFLICT -# define STATUS_REPARSE_ATTRIBUTE_CONFLICT ((NTSTATUS) 0xC00002B2L) -#endif - -#ifndef STATUS_CANT_ENABLE_DENY_ONLY -# define STATUS_CANT_ENABLE_DENY_ONLY ((NTSTATUS) 0xC00002B3L) -#endif - -#ifndef STATUS_FLOAT_MULTIPLE_FAULTS -# define STATUS_FLOAT_MULTIPLE_FAULTS ((NTSTATUS) 0xC00002B4L) -#endif - -#ifndef STATUS_FLOAT_MULTIPLE_TRAPS -# define STATUS_FLOAT_MULTIPLE_TRAPS ((NTSTATUS) 0xC00002B5L) -#endif - -#ifndef STATUS_DEVICE_REMOVED -# define STATUS_DEVICE_REMOVED ((NTSTATUS) 0xC00002B6L) -#endif - -#ifndef STATUS_JOURNAL_DELETE_IN_PROGRESS -# define STATUS_JOURNAL_DELETE_IN_PROGRESS ((NTSTATUS) 0xC00002B7L) -#endif - -#ifndef STATUS_JOURNAL_NOT_ACTIVE -# define STATUS_JOURNAL_NOT_ACTIVE ((NTSTATUS) 0xC00002B8L) -#endif - -#ifndef STATUS_NOINTERFACE -# define STATUS_NOINTERFACE ((NTSTATUS) 0xC00002B9L) -#endif - -#ifndef STATUS_DS_ADMIN_LIMIT_EXCEEDED -# define STATUS_DS_ADMIN_LIMIT_EXCEEDED ((NTSTATUS) 0xC00002C1L) -#endif - -#ifndef STATUS_DRIVER_FAILED_SLEEP -# define STATUS_DRIVER_FAILED_SLEEP ((NTSTATUS) 0xC00002C2L) -#endif - -#ifndef STATUS_MUTUAL_AUTHENTICATION_FAILED -# define STATUS_MUTUAL_AUTHENTICATION_FAILED ((NTSTATUS) 0xC00002C3L) -#endif - -#ifndef STATUS_CORRUPT_SYSTEM_FILE -# define STATUS_CORRUPT_SYSTEM_FILE ((NTSTATUS) 0xC00002C4L) -#endif - -#ifndef STATUS_DATATYPE_MISALIGNMENT_ERROR -# define STATUS_DATATYPE_MISALIGNMENT_ERROR ((NTSTATUS) 0xC00002C5L) -#endif - -#ifndef STATUS_WMI_READ_ONLY -# define STATUS_WMI_READ_ONLY ((NTSTATUS) 0xC00002C6L) -#endif - -#ifndef STATUS_WMI_SET_FAILURE -# define STATUS_WMI_SET_FAILURE ((NTSTATUS) 0xC00002C7L) -#endif - -#ifndef STATUS_COMMITMENT_MINIMUM -# define STATUS_COMMITMENT_MINIMUM ((NTSTATUS) 0xC00002C8L) -#endif - -#ifndef STATUS_REG_NAT_CONSUMPTION -# define STATUS_REG_NAT_CONSUMPTION ((NTSTATUS) 0xC00002C9L) -#endif - -#ifndef STATUS_TRANSPORT_FULL -# define STATUS_TRANSPORT_FULL ((NTSTATUS) 0xC00002CAL) -#endif - -#ifndef STATUS_DS_SAM_INIT_FAILURE -# define STATUS_DS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002CBL) -#endif - -#ifndef STATUS_ONLY_IF_CONNECTED -# define STATUS_ONLY_IF_CONNECTED ((NTSTATUS) 0xC00002CCL) -#endif - -#ifndef STATUS_DS_SENSITIVE_GROUP_VIOLATION -# define STATUS_DS_SENSITIVE_GROUP_VIOLATION ((NTSTATUS) 0xC00002CDL) -#endif - -#ifndef STATUS_PNP_RESTART_ENUMERATION -# define STATUS_PNP_RESTART_ENUMERATION ((NTSTATUS) 0xC00002CEL) -#endif - -#ifndef STATUS_JOURNAL_ENTRY_DELETED -# define STATUS_JOURNAL_ENTRY_DELETED ((NTSTATUS) 0xC00002CFL) -#endif - -#ifndef STATUS_DS_CANT_MOD_PRIMARYGROUPID -# define STATUS_DS_CANT_MOD_PRIMARYGROUPID ((NTSTATUS) 0xC00002D0L) -#endif - -#ifndef STATUS_SYSTEM_IMAGE_BAD_SIGNATURE -# define STATUS_SYSTEM_IMAGE_BAD_SIGNATURE ((NTSTATUS) 0xC00002D1L) -#endif - -#ifndef STATUS_PNP_REBOOT_REQUIRED -# define STATUS_PNP_REBOOT_REQUIRED ((NTSTATUS) 0xC00002D2L) -#endif - -#ifndef STATUS_POWER_STATE_INVALID -# define STATUS_POWER_STATE_INVALID ((NTSTATUS) 0xC00002D3L) -#endif - -#ifndef STATUS_DS_INVALID_GROUP_TYPE -# define STATUS_DS_INVALID_GROUP_TYPE ((NTSTATUS) 0xC00002D4L) -#endif - -#ifndef STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN -# define STATUS_DS_NO_NEST_GLOBALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D5L) -#endif - -#ifndef STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN -# define STATUS_DS_NO_NEST_LOCALGROUP_IN_MIXEDDOMAIN ((NTSTATUS) 0xC00002D6L) -#endif - -#ifndef STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER -# define STATUS_DS_GLOBAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D7L) -#endif - -#ifndef STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER -# define STATUS_DS_GLOBAL_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC00002D8L) -#endif - -#ifndef STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER -# define STATUS_DS_UNIVERSAL_CANT_HAVE_LOCAL_MEMBER ((NTSTATUS) 0xC00002D9L) -#endif - -#ifndef STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER -# define STATUS_DS_GLOBAL_CANT_HAVE_CROSSDOMAIN_MEMBER ((NTSTATUS) 0xC00002DAL) -#endif - -#ifndef STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER -# define STATUS_DS_LOCAL_CANT_HAVE_CROSSDOMAIN_LOCAL_MEMBER ((NTSTATUS) 0xC00002DBL) -#endif - -#ifndef STATUS_DS_HAVE_PRIMARY_MEMBERS -# define STATUS_DS_HAVE_PRIMARY_MEMBERS ((NTSTATUS) 0xC00002DCL) -#endif - -#ifndef STATUS_WMI_NOT_SUPPORTED -# define STATUS_WMI_NOT_SUPPORTED ((NTSTATUS) 0xC00002DDL) -#endif - -#ifndef STATUS_INSUFFICIENT_POWER -# define STATUS_INSUFFICIENT_POWER ((NTSTATUS) 0xC00002DEL) -#endif - -#ifndef STATUS_SAM_NEED_BOOTKEY_PASSWORD -# define STATUS_SAM_NEED_BOOTKEY_PASSWORD ((NTSTATUS) 0xC00002DFL) -#endif - -#ifndef STATUS_SAM_NEED_BOOTKEY_FLOPPY -# define STATUS_SAM_NEED_BOOTKEY_FLOPPY ((NTSTATUS) 0xC00002E0L) -#endif - -#ifndef STATUS_DS_CANT_START -# define STATUS_DS_CANT_START ((NTSTATUS) 0xC00002E1L) -#endif - -#ifndef STATUS_DS_INIT_FAILURE -# define STATUS_DS_INIT_FAILURE ((NTSTATUS) 0xC00002E2L) -#endif - -#ifndef STATUS_SAM_INIT_FAILURE -# define STATUS_SAM_INIT_FAILURE ((NTSTATUS) 0xC00002E3L) -#endif - -#ifndef STATUS_DS_GC_REQUIRED -# define STATUS_DS_GC_REQUIRED ((NTSTATUS) 0xC00002E4L) -#endif - -#ifndef STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY -# define STATUS_DS_LOCAL_MEMBER_OF_LOCAL_ONLY ((NTSTATUS) 0xC00002E5L) -#endif - -#ifndef STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS -# define STATUS_DS_NO_FPO_IN_UNIVERSAL_GROUPS ((NTSTATUS) 0xC00002E6L) -#endif - -#ifndef STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED -# define STATUS_DS_MACHINE_ACCOUNT_QUOTA_EXCEEDED ((NTSTATUS) 0xC00002E7L) -#endif - -#ifndef STATUS_MULTIPLE_FAULT_VIOLATION -# define STATUS_MULTIPLE_FAULT_VIOLATION ((NTSTATUS) 0xC00002E8L) -#endif - -#ifndef STATUS_CURRENT_DOMAIN_NOT_ALLOWED -# define STATUS_CURRENT_DOMAIN_NOT_ALLOWED ((NTSTATUS) 0xC00002E9L) -#endif - -#ifndef STATUS_CANNOT_MAKE -# define STATUS_CANNOT_MAKE ((NTSTATUS) 0xC00002EAL) -#endif - -#ifndef STATUS_SYSTEM_SHUTDOWN -# define STATUS_SYSTEM_SHUTDOWN ((NTSTATUS) 0xC00002EBL) -#endif - -#ifndef STATUS_DS_INIT_FAILURE_CONSOLE -# define STATUS_DS_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002ECL) -#endif - -#ifndef STATUS_DS_SAM_INIT_FAILURE_CONSOLE -# define STATUS_DS_SAM_INIT_FAILURE_CONSOLE ((NTSTATUS) 0xC00002EDL) -#endif - -#ifndef STATUS_UNFINISHED_CONTEXT_DELETED -# define STATUS_UNFINISHED_CONTEXT_DELETED ((NTSTATUS) 0xC00002EEL) -#endif - -#ifndef STATUS_NO_TGT_REPLY -# define STATUS_NO_TGT_REPLY ((NTSTATUS) 0xC00002EFL) -#endif - -#ifndef STATUS_OBJECTID_NOT_FOUND -# define STATUS_OBJECTID_NOT_FOUND ((NTSTATUS) 0xC00002F0L) -#endif - -#ifndef STATUS_NO_IP_ADDRESSES -# define STATUS_NO_IP_ADDRESSES ((NTSTATUS) 0xC00002F1L) -#endif - -#ifndef STATUS_WRONG_CREDENTIAL_HANDLE -# define STATUS_WRONG_CREDENTIAL_HANDLE ((NTSTATUS) 0xC00002F2L) -#endif - -#ifndef STATUS_CRYPTO_SYSTEM_INVALID -# define STATUS_CRYPTO_SYSTEM_INVALID ((NTSTATUS) 0xC00002F3L) -#endif - -#ifndef STATUS_MAX_REFERRALS_EXCEEDED -# define STATUS_MAX_REFERRALS_EXCEEDED ((NTSTATUS) 0xC00002F4L) -#endif - -#ifndef STATUS_MUST_BE_KDC -# define STATUS_MUST_BE_KDC ((NTSTATUS) 0xC00002F5L) -#endif - -#ifndef STATUS_STRONG_CRYPTO_NOT_SUPPORTED -# define STATUS_STRONG_CRYPTO_NOT_SUPPORTED ((NTSTATUS) 0xC00002F6L) -#endif - -#ifndef STATUS_TOO_MANY_PRINCIPALS -# define STATUS_TOO_MANY_PRINCIPALS ((NTSTATUS) 0xC00002F7L) -#endif - -#ifndef STATUS_NO_PA_DATA -# define STATUS_NO_PA_DATA ((NTSTATUS) 0xC00002F8L) -#endif - -#ifndef STATUS_PKINIT_NAME_MISMATCH -# define STATUS_PKINIT_NAME_MISMATCH ((NTSTATUS) 0xC00002F9L) -#endif - -#ifndef STATUS_SMARTCARD_LOGON_REQUIRED -# define STATUS_SMARTCARD_LOGON_REQUIRED ((NTSTATUS) 0xC00002FAL) -#endif - -#ifndef STATUS_KDC_INVALID_REQUEST -# define STATUS_KDC_INVALID_REQUEST ((NTSTATUS) 0xC00002FBL) -#endif - -#ifndef STATUS_KDC_UNABLE_TO_REFER -# define STATUS_KDC_UNABLE_TO_REFER ((NTSTATUS) 0xC00002FCL) -#endif - -#ifndef STATUS_KDC_UNKNOWN_ETYPE -# define STATUS_KDC_UNKNOWN_ETYPE ((NTSTATUS) 0xC00002FDL) -#endif - -#ifndef STATUS_SHUTDOWN_IN_PROGRESS -# define STATUS_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FEL) -#endif - -#ifndef STATUS_SERVER_SHUTDOWN_IN_PROGRESS -# define STATUS_SERVER_SHUTDOWN_IN_PROGRESS ((NTSTATUS) 0xC00002FFL) -#endif - -#ifndef STATUS_NOT_SUPPORTED_ON_SBS -# define STATUS_NOT_SUPPORTED_ON_SBS ((NTSTATUS) 0xC0000300L) -#endif - -#ifndef STATUS_WMI_GUID_DISCONNECTED -# define STATUS_WMI_GUID_DISCONNECTED ((NTSTATUS) 0xC0000301L) -#endif - -#ifndef STATUS_WMI_ALREADY_DISABLED -# define STATUS_WMI_ALREADY_DISABLED ((NTSTATUS) 0xC0000302L) -#endif - -#ifndef STATUS_WMI_ALREADY_ENABLED -# define STATUS_WMI_ALREADY_ENABLED ((NTSTATUS) 0xC0000303L) -#endif - -#ifndef STATUS_MFT_TOO_FRAGMENTED -# define STATUS_MFT_TOO_FRAGMENTED ((NTSTATUS) 0xC0000304L) -#endif - -#ifndef STATUS_COPY_PROTECTION_FAILURE -# define STATUS_COPY_PROTECTION_FAILURE ((NTSTATUS) 0xC0000305L) -#endif - -#ifndef STATUS_CSS_AUTHENTICATION_FAILURE -# define STATUS_CSS_AUTHENTICATION_FAILURE ((NTSTATUS) 0xC0000306L) -#endif - -#ifndef STATUS_CSS_KEY_NOT_PRESENT -# define STATUS_CSS_KEY_NOT_PRESENT ((NTSTATUS) 0xC0000307L) -#endif - -#ifndef STATUS_CSS_KEY_NOT_ESTABLISHED -# define STATUS_CSS_KEY_NOT_ESTABLISHED ((NTSTATUS) 0xC0000308L) -#endif - -#ifndef STATUS_CSS_SCRAMBLED_SECTOR -# define STATUS_CSS_SCRAMBLED_SECTOR ((NTSTATUS) 0xC0000309L) -#endif - -#ifndef STATUS_CSS_REGION_MISMATCH -# define STATUS_CSS_REGION_MISMATCH ((NTSTATUS) 0xC000030AL) -#endif - -#ifndef STATUS_CSS_RESETS_EXHAUSTED -# define STATUS_CSS_RESETS_EXHAUSTED ((NTSTATUS) 0xC000030BL) -#endif - -#ifndef STATUS_PKINIT_FAILURE -# define STATUS_PKINIT_FAILURE ((NTSTATUS) 0xC0000320L) -#endif - -#ifndef STATUS_SMARTCARD_SUBSYSTEM_FAILURE -# define STATUS_SMARTCARD_SUBSYSTEM_FAILURE ((NTSTATUS) 0xC0000321L) -#endif - -#ifndef STATUS_NO_KERB_KEY -# define STATUS_NO_KERB_KEY ((NTSTATUS) 0xC0000322L) -#endif - -#ifndef STATUS_HOST_DOWN -# define STATUS_HOST_DOWN ((NTSTATUS) 0xC0000350L) -#endif - -#ifndef STATUS_UNSUPPORTED_PREAUTH -# define STATUS_UNSUPPORTED_PREAUTH ((NTSTATUS) 0xC0000351L) -#endif - -#ifndef STATUS_EFS_ALG_BLOB_TOO_BIG -# define STATUS_EFS_ALG_BLOB_TOO_BIG ((NTSTATUS) 0xC0000352L) -#endif - -#ifndef STATUS_PORT_NOT_SET -# define STATUS_PORT_NOT_SET ((NTSTATUS) 0xC0000353L) -#endif - -#ifndef STATUS_DEBUGGER_INACTIVE -# define STATUS_DEBUGGER_INACTIVE ((NTSTATUS) 0xC0000354L) -#endif - -#ifndef STATUS_DS_VERSION_CHECK_FAILURE -# define STATUS_DS_VERSION_CHECK_FAILURE ((NTSTATUS) 0xC0000355L) -#endif - -#ifndef STATUS_AUDITING_DISABLED -# define STATUS_AUDITING_DISABLED ((NTSTATUS) 0xC0000356L) -#endif - -#ifndef STATUS_PRENT4_MACHINE_ACCOUNT -# define STATUS_PRENT4_MACHINE_ACCOUNT ((NTSTATUS) 0xC0000357L) -#endif - -#ifndef STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER -# define STATUS_DS_AG_CANT_HAVE_UNIVERSAL_MEMBER ((NTSTATUS) 0xC0000358L) -#endif - -#ifndef STATUS_INVALID_IMAGE_WIN_32 -# define STATUS_INVALID_IMAGE_WIN_32 ((NTSTATUS) 0xC0000359L) -#endif - -#ifndef STATUS_INVALID_IMAGE_WIN_64 -# define STATUS_INVALID_IMAGE_WIN_64 ((NTSTATUS) 0xC000035AL) -#endif - -#ifndef STATUS_BAD_BINDINGS -# define STATUS_BAD_BINDINGS ((NTSTATUS) 0xC000035BL) -#endif - -#ifndef STATUS_NETWORK_SESSION_EXPIRED -# define STATUS_NETWORK_SESSION_EXPIRED ((NTSTATUS) 0xC000035CL) -#endif - -#ifndef STATUS_APPHELP_BLOCK -# define STATUS_APPHELP_BLOCK ((NTSTATUS) 0xC000035DL) -#endif - -#ifndef STATUS_ALL_SIDS_FILTERED -# define STATUS_ALL_SIDS_FILTERED ((NTSTATUS) 0xC000035EL) -#endif - -#ifndef STATUS_NOT_SAFE_MODE_DRIVER -# define STATUS_NOT_SAFE_MODE_DRIVER ((NTSTATUS) 0xC000035FL) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT -# define STATUS_ACCESS_DISABLED_BY_POLICY_DEFAULT ((NTSTATUS) 0xC0000361L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PATH -# define STATUS_ACCESS_DISABLED_BY_POLICY_PATH ((NTSTATUS) 0xC0000362L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER -# define STATUS_ACCESS_DISABLED_BY_POLICY_PUBLISHER ((NTSTATUS) 0xC0000363L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_BY_POLICY_OTHER -# define STATUS_ACCESS_DISABLED_BY_POLICY_OTHER ((NTSTATUS) 0xC0000364L) -#endif - -#ifndef STATUS_FAILED_DRIVER_ENTRY -# define STATUS_FAILED_DRIVER_ENTRY ((NTSTATUS) 0xC0000365L) -#endif - -#ifndef STATUS_DEVICE_ENUMERATION_ERROR -# define STATUS_DEVICE_ENUMERATION_ERROR ((NTSTATUS) 0xC0000366L) -#endif - -#ifndef STATUS_MOUNT_POINT_NOT_RESOLVED -# define STATUS_MOUNT_POINT_NOT_RESOLVED ((NTSTATUS) 0xC0000368L) -#endif - -#ifndef STATUS_INVALID_DEVICE_OBJECT_PARAMETER -# define STATUS_INVALID_DEVICE_OBJECT_PARAMETER ((NTSTATUS) 0xC0000369L) -#endif - -#ifndef STATUS_MCA_OCCURED -# define STATUS_MCA_OCCURED ((NTSTATUS) 0xC000036AL) -#endif - -#ifndef STATUS_DRIVER_BLOCKED_CRITICAL -# define STATUS_DRIVER_BLOCKED_CRITICAL ((NTSTATUS) 0xC000036BL) -#endif - -#ifndef STATUS_DRIVER_BLOCKED -# define STATUS_DRIVER_BLOCKED ((NTSTATUS) 0xC000036CL) -#endif - -#ifndef STATUS_DRIVER_DATABASE_ERROR -# define STATUS_DRIVER_DATABASE_ERROR ((NTSTATUS) 0xC000036DL) -#endif - -#ifndef STATUS_SYSTEM_HIVE_TOO_LARGE -# define STATUS_SYSTEM_HIVE_TOO_LARGE ((NTSTATUS) 0xC000036EL) -#endif - -#ifndef STATUS_INVALID_IMPORT_OF_NON_DLL -# define STATUS_INVALID_IMPORT_OF_NON_DLL ((NTSTATUS) 0xC000036FL) -#endif - -#ifndef STATUS_DS_SHUTTING_DOWN -# define STATUS_DS_SHUTTING_DOWN ((NTSTATUS) 0x40000370L) -#endif - -#ifndef STATUS_NO_SECRETS -# define STATUS_NO_SECRETS ((NTSTATUS) 0xC0000371L) -#endif - -#ifndef STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY -# define STATUS_ACCESS_DISABLED_NO_SAFER_UI_BY_POLICY ((NTSTATUS) 0xC0000372L) -#endif - -#ifndef STATUS_FAILED_STACK_SWITCH -# define STATUS_FAILED_STACK_SWITCH ((NTSTATUS) 0xC0000373L) -#endif - -#ifndef STATUS_HEAP_CORRUPTION -# define STATUS_HEAP_CORRUPTION ((NTSTATUS) 0xC0000374L) -#endif - -#ifndef STATUS_SMARTCARD_WRONG_PIN -# define STATUS_SMARTCARD_WRONG_PIN ((NTSTATUS) 0xC0000380L) -#endif - -#ifndef STATUS_SMARTCARD_CARD_BLOCKED -# define STATUS_SMARTCARD_CARD_BLOCKED ((NTSTATUS) 0xC0000381L) -#endif - -#ifndef STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED -# define STATUS_SMARTCARD_CARD_NOT_AUTHENTICATED ((NTSTATUS) 0xC0000382L) -#endif - -#ifndef STATUS_SMARTCARD_NO_CARD -# define STATUS_SMARTCARD_NO_CARD ((NTSTATUS) 0xC0000383L) -#endif - -#ifndef STATUS_SMARTCARD_NO_KEY_CONTAINER -# define STATUS_SMARTCARD_NO_KEY_CONTAINER ((NTSTATUS) 0xC0000384L) -#endif - -#ifndef STATUS_SMARTCARD_NO_CERTIFICATE -# define STATUS_SMARTCARD_NO_CERTIFICATE ((NTSTATUS) 0xC0000385L) -#endif - -#ifndef STATUS_SMARTCARD_NO_KEYSET -# define STATUS_SMARTCARD_NO_KEYSET ((NTSTATUS) 0xC0000386L) -#endif - -#ifndef STATUS_SMARTCARD_IO_ERROR -# define STATUS_SMARTCARD_IO_ERROR ((NTSTATUS) 0xC0000387L) -#endif - -#ifndef STATUS_DOWNGRADE_DETECTED -# define STATUS_DOWNGRADE_DETECTED ((NTSTATUS) 0xC0000388L) -#endif - -#ifndef STATUS_SMARTCARD_CERT_REVOKED -# define STATUS_SMARTCARD_CERT_REVOKED ((NTSTATUS) 0xC0000389L) -#endif - -#ifndef STATUS_ISSUING_CA_UNTRUSTED -# define STATUS_ISSUING_CA_UNTRUSTED ((NTSTATUS) 0xC000038AL) -#endif - -#ifndef STATUS_REVOCATION_OFFLINE_C -# define STATUS_REVOCATION_OFFLINE_C ((NTSTATUS) 0xC000038BL) -#endif - -#ifndef STATUS_PKINIT_CLIENT_FAILURE -# define STATUS_PKINIT_CLIENT_FAILURE ((NTSTATUS) 0xC000038CL) -#endif - -#ifndef STATUS_SMARTCARD_CERT_EXPIRED -# define STATUS_SMARTCARD_CERT_EXPIRED ((NTSTATUS) 0xC000038DL) -#endif - -#ifndef STATUS_DRIVER_FAILED_PRIOR_UNLOAD -# define STATUS_DRIVER_FAILED_PRIOR_UNLOAD ((NTSTATUS) 0xC000038EL) -#endif - -#ifndef STATUS_SMARTCARD_SILENT_CONTEXT -# define STATUS_SMARTCARD_SILENT_CONTEXT ((NTSTATUS) 0xC000038FL) -#endif - -#ifndef STATUS_PER_USER_TRUST_QUOTA_EXCEEDED -# define STATUS_PER_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000401L) -#endif - -#ifndef STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED -# define STATUS_ALL_USER_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000402L) -#endif - -#ifndef STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED -# define STATUS_USER_DELETE_TRUST_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000403L) -#endif - -#ifndef STATUS_DS_NAME_NOT_UNIQUE -# define STATUS_DS_NAME_NOT_UNIQUE ((NTSTATUS) 0xC0000404L) -#endif - -#ifndef STATUS_DS_DUPLICATE_ID_FOUND -# define STATUS_DS_DUPLICATE_ID_FOUND ((NTSTATUS) 0xC0000405L) -#endif - -#ifndef STATUS_DS_GROUP_CONVERSION_ERROR -# define STATUS_DS_GROUP_CONVERSION_ERROR ((NTSTATUS) 0xC0000406L) -#endif - -#ifndef STATUS_VOLSNAP_PREPARE_HIBERNATE -# define STATUS_VOLSNAP_PREPARE_HIBERNATE ((NTSTATUS) 0xC0000407L) -#endif - -#ifndef STATUS_USER2USER_REQUIRED -# define STATUS_USER2USER_REQUIRED ((NTSTATUS) 0xC0000408L) -#endif - -#ifndef STATUS_STACK_BUFFER_OVERRUN -# define STATUS_STACK_BUFFER_OVERRUN ((NTSTATUS) 0xC0000409L) -#endif - -#ifndef STATUS_NO_S4U_PROT_SUPPORT -# define STATUS_NO_S4U_PROT_SUPPORT ((NTSTATUS) 0xC000040AL) -#endif - -#ifndef STATUS_CROSSREALM_DELEGATION_FAILURE -# define STATUS_CROSSREALM_DELEGATION_FAILURE ((NTSTATUS) 0xC000040BL) -#endif - -#ifndef STATUS_REVOCATION_OFFLINE_KDC -# define STATUS_REVOCATION_OFFLINE_KDC ((NTSTATUS) 0xC000040CL) -#endif - -#ifndef STATUS_ISSUING_CA_UNTRUSTED_KDC -# define STATUS_ISSUING_CA_UNTRUSTED_KDC ((NTSTATUS) 0xC000040DL) -#endif - -#ifndef STATUS_KDC_CERT_EXPIRED -# define STATUS_KDC_CERT_EXPIRED ((NTSTATUS) 0xC000040EL) -#endif - -#ifndef STATUS_KDC_CERT_REVOKED -# define STATUS_KDC_CERT_REVOKED ((NTSTATUS) 0xC000040FL) -#endif - -#ifndef STATUS_PARAMETER_QUOTA_EXCEEDED -# define STATUS_PARAMETER_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000410L) -#endif - -#ifndef STATUS_HIBERNATION_FAILURE -# define STATUS_HIBERNATION_FAILURE ((NTSTATUS) 0xC0000411L) -#endif - -#ifndef STATUS_DELAY_LOAD_FAILED -# define STATUS_DELAY_LOAD_FAILED ((NTSTATUS) 0xC0000412L) -#endif - -#ifndef STATUS_AUTHENTICATION_FIREWALL_FAILED -# define STATUS_AUTHENTICATION_FIREWALL_FAILED ((NTSTATUS) 0xC0000413L) -#endif - -#ifndef STATUS_VDM_DISALLOWED -# define STATUS_VDM_DISALLOWED ((NTSTATUS) 0xC0000414L) -#endif - -#ifndef STATUS_HUNG_DISPLAY_DRIVER_THREAD -# define STATUS_HUNG_DISPLAY_DRIVER_THREAD ((NTSTATUS) 0xC0000415L) -#endif - -#ifndef STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE -# define STATUS_INSUFFICIENT_RESOURCE_FOR_SPECIFIED_SHARED_SECTION_SIZE ((NTSTATUS) 0xC0000416L) -#endif - -#ifndef STATUS_INVALID_CRUNTIME_PARAMETER -# define STATUS_INVALID_CRUNTIME_PARAMETER ((NTSTATUS) 0xC0000417L) -#endif - -#ifndef STATUS_NTLM_BLOCKED -# define STATUS_NTLM_BLOCKED ((NTSTATUS) 0xC0000418L) -#endif - -#ifndef STATUS_DS_SRC_SID_EXISTS_IN_FOREST -# define STATUS_DS_SRC_SID_EXISTS_IN_FOREST ((NTSTATUS) 0xC0000419L) -#endif - -#ifndef STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST -# define STATUS_DS_DOMAIN_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041AL) -#endif - -#ifndef STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST -# define STATUS_DS_FLAT_NAME_EXISTS_IN_FOREST ((NTSTATUS) 0xC000041BL) -#endif - -#ifndef STATUS_INVALID_USER_PRINCIPAL_NAME -# define STATUS_INVALID_USER_PRINCIPAL_NAME ((NTSTATUS) 0xC000041CL) -#endif - -#ifndef STATUS_FATAL_USER_CALLBACK_EXCEPTION -# define STATUS_FATAL_USER_CALLBACK_EXCEPTION ((NTSTATUS) 0xC000041DL) -#endif - -#ifndef STATUS_ASSERTION_FAILURE -# define STATUS_ASSERTION_FAILURE ((NTSTATUS) 0xC0000420L) -#endif - -#ifndef STATUS_VERIFIER_STOP -# define STATUS_VERIFIER_STOP ((NTSTATUS) 0xC0000421L) -#endif - -#ifndef STATUS_CALLBACK_POP_STACK -# define STATUS_CALLBACK_POP_STACK ((NTSTATUS) 0xC0000423L) -#endif - -#ifndef STATUS_INCOMPATIBLE_DRIVER_BLOCKED -# define STATUS_INCOMPATIBLE_DRIVER_BLOCKED ((NTSTATUS) 0xC0000424L) -#endif - -#ifndef STATUS_HIVE_UNLOADED -# define STATUS_HIVE_UNLOADED ((NTSTATUS) 0xC0000425L) -#endif - -#ifndef STATUS_COMPRESSION_DISABLED -# define STATUS_COMPRESSION_DISABLED ((NTSTATUS) 0xC0000426L) -#endif - -#ifndef STATUS_FILE_SYSTEM_LIMITATION -# define STATUS_FILE_SYSTEM_LIMITATION ((NTSTATUS) 0xC0000427L) -#endif - -#ifndef STATUS_INVALID_IMAGE_HASH -# define STATUS_INVALID_IMAGE_HASH ((NTSTATUS) 0xC0000428L) -#endif - -#ifndef STATUS_NOT_CAPABLE -# define STATUS_NOT_CAPABLE ((NTSTATUS) 0xC0000429L) -#endif - -#ifndef STATUS_REQUEST_OUT_OF_SEQUENCE -# define STATUS_REQUEST_OUT_OF_SEQUENCE ((NTSTATUS) 0xC000042AL) -#endif - -#ifndef STATUS_IMPLEMENTATION_LIMIT -# define STATUS_IMPLEMENTATION_LIMIT ((NTSTATUS) 0xC000042BL) -#endif - -#ifndef STATUS_ELEVATION_REQUIRED -# define STATUS_ELEVATION_REQUIRED ((NTSTATUS) 0xC000042CL) -#endif - -#ifndef STATUS_NO_SECURITY_CONTEXT -# define STATUS_NO_SECURITY_CONTEXT ((NTSTATUS) 0xC000042DL) -#endif - -#ifndef STATUS_PKU2U_CERT_FAILURE -# define STATUS_PKU2U_CERT_FAILURE ((NTSTATUS) 0xC000042FL) -#endif - -#ifndef STATUS_BEYOND_VDL -# define STATUS_BEYOND_VDL ((NTSTATUS) 0xC0000432L) -#endif - -#ifndef STATUS_ENCOUNTERED_WRITE_IN_PROGRESS -# define STATUS_ENCOUNTERED_WRITE_IN_PROGRESS ((NTSTATUS) 0xC0000433L) -#endif - -#ifndef STATUS_PTE_CHANGED -# define STATUS_PTE_CHANGED ((NTSTATUS) 0xC0000434L) -#endif - -#ifndef STATUS_PURGE_FAILED -# define STATUS_PURGE_FAILED ((NTSTATUS) 0xC0000435L) -#endif - -#ifndef STATUS_CRED_REQUIRES_CONFIRMATION -# define STATUS_CRED_REQUIRES_CONFIRMATION ((NTSTATUS) 0xC0000440L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE -# define STATUS_CS_ENCRYPTION_INVALID_SERVER_RESPONSE ((NTSTATUS) 0xC0000441L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER -# define STATUS_CS_ENCRYPTION_UNSUPPORTED_SERVER ((NTSTATUS) 0xC0000442L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE -# define STATUS_CS_ENCRYPTION_EXISTING_ENCRYPTED_FILE ((NTSTATUS) 0xC0000443L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE -# define STATUS_CS_ENCRYPTION_NEW_ENCRYPTED_FILE ((NTSTATUS) 0xC0000444L) -#endif - -#ifndef STATUS_CS_ENCRYPTION_FILE_NOT_CSE -# define STATUS_CS_ENCRYPTION_FILE_NOT_CSE ((NTSTATUS) 0xC0000445L) -#endif - -#ifndef STATUS_INVALID_LABEL -# define STATUS_INVALID_LABEL ((NTSTATUS) 0xC0000446L) -#endif - -#ifndef STATUS_DRIVER_PROCESS_TERMINATED -# define STATUS_DRIVER_PROCESS_TERMINATED ((NTSTATUS) 0xC0000450L) -#endif - -#ifndef STATUS_AMBIGUOUS_SYSTEM_DEVICE -# define STATUS_AMBIGUOUS_SYSTEM_DEVICE ((NTSTATUS) 0xC0000451L) -#endif - -#ifndef STATUS_SYSTEM_DEVICE_NOT_FOUND -# define STATUS_SYSTEM_DEVICE_NOT_FOUND ((NTSTATUS) 0xC0000452L) -#endif - -#ifndef STATUS_RESTART_BOOT_APPLICATION -# define STATUS_RESTART_BOOT_APPLICATION ((NTSTATUS) 0xC0000453L) -#endif - -#ifndef STATUS_INSUFFICIENT_NVRAM_RESOURCES -# define STATUS_INSUFFICIENT_NVRAM_RESOURCES ((NTSTATUS) 0xC0000454L) -#endif - -#ifndef STATUS_INVALID_TASK_NAME -# define STATUS_INVALID_TASK_NAME ((NTSTATUS) 0xC0000500L) -#endif - -#ifndef STATUS_INVALID_TASK_INDEX -# define STATUS_INVALID_TASK_INDEX ((NTSTATUS) 0xC0000501L) -#endif - -#ifndef STATUS_THREAD_ALREADY_IN_TASK -# define STATUS_THREAD_ALREADY_IN_TASK ((NTSTATUS) 0xC0000502L) -#endif - -#ifndef STATUS_CALLBACK_BYPASS -# define STATUS_CALLBACK_BYPASS ((NTSTATUS) 0xC0000503L) -#endif - -#ifndef STATUS_FAIL_FAST_EXCEPTION -# define STATUS_FAIL_FAST_EXCEPTION ((NTSTATUS) 0xC0000602L) -#endif - -#ifndef STATUS_IMAGE_CERT_REVOKED -# define STATUS_IMAGE_CERT_REVOKED ((NTSTATUS) 0xC0000603L) -#endif - -#ifndef STATUS_PORT_CLOSED -# define STATUS_PORT_CLOSED ((NTSTATUS) 0xC0000700L) -#endif - -#ifndef STATUS_MESSAGE_LOST -# define STATUS_MESSAGE_LOST ((NTSTATUS) 0xC0000701L) -#endif - -#ifndef STATUS_INVALID_MESSAGE -# define STATUS_INVALID_MESSAGE ((NTSTATUS) 0xC0000702L) -#endif - -#ifndef STATUS_REQUEST_CANCELED -# define STATUS_REQUEST_CANCELED ((NTSTATUS) 0xC0000703L) -#endif - -#ifndef STATUS_RECURSIVE_DISPATCH -# define STATUS_RECURSIVE_DISPATCH ((NTSTATUS) 0xC0000704L) -#endif - -#ifndef STATUS_LPC_RECEIVE_BUFFER_EXPECTED -# define STATUS_LPC_RECEIVE_BUFFER_EXPECTED ((NTSTATUS) 0xC0000705L) -#endif - -#ifndef STATUS_LPC_INVALID_CONNECTION_USAGE -# define STATUS_LPC_INVALID_CONNECTION_USAGE ((NTSTATUS) 0xC0000706L) -#endif - -#ifndef STATUS_LPC_REQUESTS_NOT_ALLOWED -# define STATUS_LPC_REQUESTS_NOT_ALLOWED ((NTSTATUS) 0xC0000707L) -#endif - -#ifndef STATUS_RESOURCE_IN_USE -# define STATUS_RESOURCE_IN_USE ((NTSTATUS) 0xC0000708L) -#endif - -#ifndef STATUS_HARDWARE_MEMORY_ERROR -# define STATUS_HARDWARE_MEMORY_ERROR ((NTSTATUS) 0xC0000709L) -#endif - -#ifndef STATUS_THREADPOOL_HANDLE_EXCEPTION -# define STATUS_THREADPOOL_HANDLE_EXCEPTION ((NTSTATUS) 0xC000070AL) -#endif - -#ifndef STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_SET_EVENT_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070BL) -#endif - -#ifndef STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_RELEASE_SEMAPHORE_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070CL) -#endif - -#ifndef STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_RELEASE_MUTEX_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070DL) -#endif - -#ifndef STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED -# define STATUS_THREADPOOL_FREE_LIBRARY_ON_COMPLETION_FAILED ((NTSTATUS) 0xC000070EL) -#endif - -#ifndef STATUS_THREADPOOL_RELEASED_DURING_OPERATION -# define STATUS_THREADPOOL_RELEASED_DURING_OPERATION ((NTSTATUS) 0xC000070FL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING -# define STATUS_CALLBACK_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000710L) -#endif - -#ifndef STATUS_APC_RETURNED_WHILE_IMPERSONATING -# define STATUS_APC_RETURNED_WHILE_IMPERSONATING ((NTSTATUS) 0xC0000711L) -#endif - -#ifndef STATUS_PROCESS_IS_PROTECTED -# define STATUS_PROCESS_IS_PROTECTED ((NTSTATUS) 0xC0000712L) -#endif - -#ifndef STATUS_MCA_EXCEPTION -# define STATUS_MCA_EXCEPTION ((NTSTATUS) 0xC0000713L) -#endif - -#ifndef STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE -# define STATUS_CERTIFICATE_MAPPING_NOT_UNIQUE ((NTSTATUS) 0xC0000714L) -#endif - -#ifndef STATUS_SYMLINK_CLASS_DISABLED -# define STATUS_SYMLINK_CLASS_DISABLED ((NTSTATUS) 0xC0000715L) -#endif - -#ifndef STATUS_INVALID_IDN_NORMALIZATION -# define STATUS_INVALID_IDN_NORMALIZATION ((NTSTATUS) 0xC0000716L) -#endif - -#ifndef STATUS_NO_UNICODE_TRANSLATION -# define STATUS_NO_UNICODE_TRANSLATION ((NTSTATUS) 0xC0000717L) -#endif - -#ifndef STATUS_ALREADY_REGISTERED -# define STATUS_ALREADY_REGISTERED ((NTSTATUS) 0xC0000718L) -#endif - -#ifndef STATUS_CONTEXT_MISMATCH -# define STATUS_CONTEXT_MISMATCH ((NTSTATUS) 0xC0000719L) -#endif - -#ifndef STATUS_PORT_ALREADY_HAS_COMPLETION_LIST -# define STATUS_PORT_ALREADY_HAS_COMPLETION_LIST ((NTSTATUS) 0xC000071AL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_THREAD_PRIORITY -# define STATUS_CALLBACK_RETURNED_THREAD_PRIORITY ((NTSTATUS) 0xC000071BL) -#endif - -#ifndef STATUS_INVALID_THREAD -# define STATUS_INVALID_THREAD ((NTSTATUS) 0xC000071CL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_TRANSACTION -# define STATUS_CALLBACK_RETURNED_TRANSACTION ((NTSTATUS) 0xC000071DL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_LDR_LOCK -# define STATUS_CALLBACK_RETURNED_LDR_LOCK ((NTSTATUS) 0xC000071EL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_LANG -# define STATUS_CALLBACK_RETURNED_LANG ((NTSTATUS) 0xC000071FL) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_PRI_BACK -# define STATUS_CALLBACK_RETURNED_PRI_BACK ((NTSTATUS) 0xC0000720L) -#endif - -#ifndef STATUS_CALLBACK_RETURNED_THREAD_AFFINITY -# define STATUS_CALLBACK_RETURNED_THREAD_AFFINITY ((NTSTATUS) 0xC0000721L) -#endif - -#ifndef STATUS_DISK_REPAIR_DISABLED -# define STATUS_DISK_REPAIR_DISABLED ((NTSTATUS) 0xC0000800L) -#endif - -#ifndef STATUS_DS_DOMAIN_RENAME_IN_PROGRESS -# define STATUS_DS_DOMAIN_RENAME_IN_PROGRESS ((NTSTATUS) 0xC0000801L) -#endif - -#ifndef STATUS_DISK_QUOTA_EXCEEDED -# define STATUS_DISK_QUOTA_EXCEEDED ((NTSTATUS) 0xC0000802L) -#endif - -#ifndef STATUS_DATA_LOST_REPAIR -# define STATUS_DATA_LOST_REPAIR ((NTSTATUS) 0x80000803L) -#endif - -#ifndef STATUS_CONTENT_BLOCKED -# define STATUS_CONTENT_BLOCKED ((NTSTATUS) 0xC0000804L) -#endif - -#ifndef STATUS_BAD_CLUSTERS -# define STATUS_BAD_CLUSTERS ((NTSTATUS) 0xC0000805L) -#endif - -#ifndef STATUS_VOLUME_DIRTY -# define STATUS_VOLUME_DIRTY ((NTSTATUS) 0xC0000806L) -#endif - -#ifndef STATUS_FILE_CHECKED_OUT -# define STATUS_FILE_CHECKED_OUT ((NTSTATUS) 0xC0000901L) -#endif - -#ifndef STATUS_CHECKOUT_REQUIRED -# define STATUS_CHECKOUT_REQUIRED ((NTSTATUS) 0xC0000902L) -#endif - -#ifndef STATUS_BAD_FILE_TYPE -# define STATUS_BAD_FILE_TYPE ((NTSTATUS) 0xC0000903L) -#endif - -#ifndef STATUS_FILE_TOO_LARGE -# define STATUS_FILE_TOO_LARGE ((NTSTATUS) 0xC0000904L) -#endif - -#ifndef STATUS_FORMS_AUTH_REQUIRED -# define STATUS_FORMS_AUTH_REQUIRED ((NTSTATUS) 0xC0000905L) -#endif - -#ifndef STATUS_VIRUS_INFECTED -# define STATUS_VIRUS_INFECTED ((NTSTATUS) 0xC0000906L) -#endif - -#ifndef STATUS_VIRUS_DELETED -# define STATUS_VIRUS_DELETED ((NTSTATUS) 0xC0000907L) -#endif - -#ifndef STATUS_BAD_MCFG_TABLE -# define STATUS_BAD_MCFG_TABLE ((NTSTATUS) 0xC0000908L) -#endif - -#ifndef STATUS_CANNOT_BREAK_OPLOCK -# define STATUS_CANNOT_BREAK_OPLOCK ((NTSTATUS) 0xC0000909L) -#endif - -#ifndef STATUS_WOW_ASSERTION -# define STATUS_WOW_ASSERTION ((NTSTATUS) 0xC0009898L) -#endif - -#ifndef STATUS_INVALID_SIGNATURE -# define STATUS_INVALID_SIGNATURE ((NTSTATUS) 0xC000A000L) -#endif - -#ifndef STATUS_HMAC_NOT_SUPPORTED -# define STATUS_HMAC_NOT_SUPPORTED ((NTSTATUS) 0xC000A001L) -#endif - -#ifndef STATUS_AUTH_TAG_MISMATCH -# define STATUS_AUTH_TAG_MISMATCH ((NTSTATUS) 0xC000A002L) -#endif - -#ifndef STATUS_IPSEC_QUEUE_OVERFLOW -# define STATUS_IPSEC_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A010L) -#endif - -#ifndef STATUS_ND_QUEUE_OVERFLOW -# define STATUS_ND_QUEUE_OVERFLOW ((NTSTATUS) 0xC000A011L) -#endif - -#ifndef STATUS_HOPLIMIT_EXCEEDED -# define STATUS_HOPLIMIT_EXCEEDED ((NTSTATUS) 0xC000A012L) -#endif - -#ifndef STATUS_PROTOCOL_NOT_SUPPORTED -# define STATUS_PROTOCOL_NOT_SUPPORTED ((NTSTATUS) 0xC000A013L) -#endif - -#ifndef STATUS_FASTPATH_REJECTED -# define STATUS_FASTPATH_REJECTED ((NTSTATUS) 0xC000A014L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED -# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_DISCONNECTED ((NTSTATUS) 0xC000A080L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR -# define STATUS_LOST_WRITEBEHIND_DATA_NETWORK_SERVER_ERROR ((NTSTATUS) 0xC000A081L) -#endif - -#ifndef STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR -# define STATUS_LOST_WRITEBEHIND_DATA_LOCAL_DISK_ERROR ((NTSTATUS) 0xC000A082L) -#endif - -#ifndef STATUS_XML_PARSE_ERROR -# define STATUS_XML_PARSE_ERROR ((NTSTATUS) 0xC000A083L) -#endif - -#ifndef STATUS_XMLDSIG_ERROR -# define STATUS_XMLDSIG_ERROR ((NTSTATUS) 0xC000A084L) -#endif - -#ifndef STATUS_WRONG_COMPARTMENT -# define STATUS_WRONG_COMPARTMENT ((NTSTATUS) 0xC000A085L) -#endif - -#ifndef STATUS_AUTHIP_FAILURE -# define STATUS_AUTHIP_FAILURE ((NTSTATUS) 0xC000A086L) -#endif - -#ifndef STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS -# define STATUS_DS_OID_MAPPED_GROUP_CANT_HAVE_MEMBERS ((NTSTATUS) 0xC000A087L) -#endif - -#ifndef STATUS_DS_OID_NOT_FOUND -# define STATUS_DS_OID_NOT_FOUND ((NTSTATUS) 0xC000A088L) -#endif - -#ifndef STATUS_HASH_NOT_SUPPORTED -# define STATUS_HASH_NOT_SUPPORTED ((NTSTATUS) 0xC000A100L) -#endif - -#ifndef STATUS_HASH_NOT_PRESENT -# define STATUS_HASH_NOT_PRESENT ((NTSTATUS) 0xC000A101L) -#endif - -/* This is not the NTSTATUS_FROM_WIN32 that the DDK provides, because the */ -/* DDK got it wrong! */ -#ifdef NTSTATUS_FROM_WIN32 -# undef NTSTATUS_FROM_WIN32 -#endif -#define NTSTATUS_FROM_WIN32(error) ((NTSTATUS) (error) <= 0 ? \ - ((NTSTATUS) (error)) : ((NTSTATUS) (((error) & 0x0000FFFF) | \ - (FACILITY_NTWIN32 << 16) | ERROR_SEVERITY_WARNING))) - -#ifndef JOB_OBJECT_LIMIT_PROCESS_MEMORY -# define JOB_OBJECT_LIMIT_PROCESS_MEMORY 0x00000100 -#endif -#ifndef JOB_OBJECT_LIMIT_JOB_MEMORY -# define JOB_OBJECT_LIMIT_JOB_MEMORY 0x00000200 -#endif -#ifndef JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION -# define JOB_OBJECT_LIMIT_DIE_ON_UNHANDLED_EXCEPTION 0x00000400 -#endif -#ifndef JOB_OBJECT_LIMIT_BREAKAWAY_OK -# define JOB_OBJECT_LIMIT_BREAKAWAY_OK 0x00000800 -#endif -#ifndef JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK -# define JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK 0x00001000 -#endif -#ifndef JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE -# define JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE 0x00002000 -#endif - -/* from winternl.h */ -typedef struct _UNICODE_STRING { - USHORT Length; - USHORT MaximumLength; - PWSTR Buffer; -} UNICODE_STRING, *PUNICODE_STRING; - -typedef const UNICODE_STRING *PCUNICODE_STRING; - -/* from ntifs.h */ -#ifndef DEVICE_TYPE -# define DEVICE_TYPE DWORD -#endif - -/* MinGW already has a definition for REPARSE_DATA_BUFFER, but mingw-w64 does - * not. - */ -#if defined(_MSC_VER) || defined(__MINGW64_VERSION_MAJOR) - typedef struct _REPARSE_DATA_BUFFER { - ULONG ReparseTag; - USHORT ReparseDataLength; - USHORT Reserved; - union { - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - ULONG Flags; - WCHAR PathBuffer[1]; - } SymbolicLinkReparseBuffer; - struct { - USHORT SubstituteNameOffset; - USHORT SubstituteNameLength; - USHORT PrintNameOffset; - USHORT PrintNameLength; - WCHAR PathBuffer[1]; - } MountPointReparseBuffer; - struct { - UCHAR DataBuffer[1]; - } GenericReparseBuffer; - } DUMMYUNIONNAME; - } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER; -#endif - -typedef struct _IO_STATUS_BLOCK { - union { - NTSTATUS Status; - PVOID Pointer; - } DUMMYUNIONNAME; - ULONG_PTR Information; -} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK; - -typedef enum _FILE_INFORMATION_CLASS { - FileDirectoryInformation = 1, - FileFullDirectoryInformation, - FileBothDirectoryInformation, - FileBasicInformation, - FileStandardInformation, - FileInternalInformation, - FileEaInformation, - FileAccessInformation, - FileNameInformation, - FileRenameInformation, - FileLinkInformation, - FileNamesInformation, - FileDispositionInformation, - FilePositionInformation, - FileFullEaInformation, - FileModeInformation, - FileAlignmentInformation, - FileAllInformation, - FileAllocationInformation, - FileEndOfFileInformation, - FileAlternateNameInformation, - FileStreamInformation, - FilePipeInformation, - FilePipeLocalInformation, - FilePipeRemoteInformation, - FileMailslotQueryInformation, - FileMailslotSetInformation, - FileCompressionInformation, - FileObjectIdInformation, - FileCompletionInformation, - FileMoveClusterInformation, - FileQuotaInformation, - FileReparsePointInformation, - FileNetworkOpenInformation, - FileAttributeTagInformation, - FileTrackingInformation, - FileIdBothDirectoryInformation, - FileIdFullDirectoryInformation, - FileValidDataLengthInformation, - FileShortNameInformation, - FileIoCompletionNotificationInformation, - FileIoStatusBlockRangeInformation, - FileIoPriorityHintInformation, - FileSfioReserveInformation, - FileSfioVolumeInformation, - FileHardLinkInformation, - FileProcessIdsUsingFileInformation, - FileNormalizedNameInformation, - FileNetworkPhysicalNameInformation, - FileIdGlobalTxDirectoryInformation, - FileIsRemoteDeviceInformation, - FileAttributeCacheInformation, - FileNumaNodeInformation, - FileStandardLinkInformation, - FileRemoteProtocolInformation, - FileMaximumInformation -} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS; - -typedef struct _FILE_DIRECTORY_INFORMATION { - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION; - -typedef struct _FILE_BOTH_DIR_INFORMATION { - ULONG NextEntryOffset; - ULONG FileIndex; - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - LARGE_INTEGER EndOfFile; - LARGE_INTEGER AllocationSize; - ULONG FileAttributes; - ULONG FileNameLength; - ULONG EaSize; - CCHAR ShortNameLength; - WCHAR ShortName[12]; - WCHAR FileName[1]; -} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION; - -typedef struct _FILE_BASIC_INFORMATION { - LARGE_INTEGER CreationTime; - LARGE_INTEGER LastAccessTime; - LARGE_INTEGER LastWriteTime; - LARGE_INTEGER ChangeTime; - DWORD FileAttributes; -} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION; - -typedef struct _FILE_STANDARD_INFORMATION { - LARGE_INTEGER AllocationSize; - LARGE_INTEGER EndOfFile; - ULONG NumberOfLinks; - BOOLEAN DeletePending; - BOOLEAN Directory; -} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION; - -typedef struct _FILE_INTERNAL_INFORMATION { - LARGE_INTEGER IndexNumber; -} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION; - -typedef struct _FILE_EA_INFORMATION { - ULONG EaSize; -} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION; - -typedef struct _FILE_ACCESS_INFORMATION { - ACCESS_MASK AccessFlags; -} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION; - -typedef struct _FILE_POSITION_INFORMATION { - LARGE_INTEGER CurrentByteOffset; -} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION; - -typedef struct _FILE_MODE_INFORMATION { - ULONG Mode; -} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION; - -typedef struct _FILE_ALIGNMENT_INFORMATION { - ULONG AlignmentRequirement; -} FILE_ALIGNMENT_INFORMATION, *PFILE_ALIGNMENT_INFORMATION; - -typedef struct _FILE_NAME_INFORMATION { - ULONG FileNameLength; - WCHAR FileName[1]; -} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION; - -typedef struct _FILE_END_OF_FILE_INFORMATION { - LARGE_INTEGER EndOfFile; -} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION; - -typedef struct _FILE_ALL_INFORMATION { - FILE_BASIC_INFORMATION BasicInformation; - FILE_STANDARD_INFORMATION StandardInformation; - FILE_INTERNAL_INFORMATION InternalInformation; - FILE_EA_INFORMATION EaInformation; - FILE_ACCESS_INFORMATION AccessInformation; - FILE_POSITION_INFORMATION PositionInformation; - FILE_MODE_INFORMATION ModeInformation; - FILE_ALIGNMENT_INFORMATION AlignmentInformation; - FILE_NAME_INFORMATION NameInformation; -} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION; - -typedef struct _FILE_DISPOSITION_INFORMATION { - BOOLEAN DeleteFile; -} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION; - -typedef struct _FILE_PIPE_LOCAL_INFORMATION { - ULONG NamedPipeType; - ULONG NamedPipeConfiguration; - ULONG MaximumInstances; - ULONG CurrentInstances; - ULONG InboundQuota; - ULONG ReadDataAvailable; - ULONG OutboundQuota; - ULONG WriteQuotaAvailable; - ULONG NamedPipeState; - ULONG NamedPipeEnd; -} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION; - -#define FILE_SYNCHRONOUS_IO_ALERT 0x00000010 -#define FILE_SYNCHRONOUS_IO_NONALERT 0x00000020 - -typedef enum _FS_INFORMATION_CLASS { - FileFsVolumeInformation = 1, - FileFsLabelInformation = 2, - FileFsSizeInformation = 3, - FileFsDeviceInformation = 4, - FileFsAttributeInformation = 5, - FileFsControlInformation = 6, - FileFsFullSizeInformation = 7, - FileFsObjectIdInformation = 8, - FileFsDriverPathInformation = 9, - FileFsVolumeFlagsInformation = 10, - FileFsSectorSizeInformation = 11 -} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS; - -typedef struct _FILE_FS_VOLUME_INFORMATION { - LARGE_INTEGER VolumeCreationTime; - ULONG VolumeSerialNumber; - ULONG VolumeLabelLength; - BOOLEAN SupportsObjects; - WCHAR VolumeLabel[1]; -} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION; - -typedef struct _FILE_FS_LABEL_INFORMATION { - ULONG VolumeLabelLength; - WCHAR VolumeLabel[1]; -} FILE_FS_LABEL_INFORMATION, *PFILE_FS_LABEL_INFORMATION; - -typedef struct _FILE_FS_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER AvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION; - -typedef struct _FILE_FS_DEVICE_INFORMATION { - DEVICE_TYPE DeviceType; - ULONG Characteristics; -} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION; - -typedef struct _FILE_FS_ATTRIBUTE_INFORMATION { - ULONG FileSystemAttributes; - LONG MaximumComponentNameLength; - ULONG FileSystemNameLength; - WCHAR FileSystemName[1]; -} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION; - -typedef struct _FILE_FS_CONTROL_INFORMATION { - LARGE_INTEGER FreeSpaceStartFiltering; - LARGE_INTEGER FreeSpaceThreshold; - LARGE_INTEGER FreeSpaceStopFiltering; - LARGE_INTEGER DefaultQuotaThreshold; - LARGE_INTEGER DefaultQuotaLimit; - ULONG FileSystemControlFlags; -} FILE_FS_CONTROL_INFORMATION, *PFILE_FS_CONTROL_INFORMATION; - -typedef struct _FILE_FS_FULL_SIZE_INFORMATION { - LARGE_INTEGER TotalAllocationUnits; - LARGE_INTEGER CallerAvailableAllocationUnits; - LARGE_INTEGER ActualAvailableAllocationUnits; - ULONG SectorsPerAllocationUnit; - ULONG BytesPerSector; -} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION; - -typedef struct _FILE_FS_OBJECTID_INFORMATION { - UCHAR ObjectId[16]; - UCHAR ExtendedInfo[48]; -} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION; - -typedef struct _FILE_FS_DRIVER_PATH_INFORMATION { - BOOLEAN DriverInPath; - ULONG DriverNameLength; - WCHAR DriverName[1]; -} FILE_FS_DRIVER_PATH_INFORMATION, *PFILE_FS_DRIVER_PATH_INFORMATION; - -typedef struct _FILE_FS_VOLUME_FLAGS_INFORMATION { - ULONG Flags; -} FILE_FS_VOLUME_FLAGS_INFORMATION, *PFILE_FS_VOLUME_FLAGS_INFORMATION; - -typedef struct _FILE_FS_SECTOR_SIZE_INFORMATION { - ULONG LogicalBytesPerSector; - ULONG PhysicalBytesPerSectorForAtomicity; - ULONG PhysicalBytesPerSectorForPerformance; - ULONG FileSystemEffectivePhysicalBytesPerSectorForAtomicity; - ULONG Flags; - ULONG ByteOffsetForSectorAlignment; - ULONG ByteOffsetForPartitionAlignment; -} FILE_FS_SECTOR_SIZE_INFORMATION, *PFILE_FS_SECTOR_SIZE_INFORMATION; - -typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION { - LARGE_INTEGER IdleTime; - LARGE_INTEGER KernelTime; - LARGE_INTEGER UserTime; - LARGE_INTEGER DpcTime; - LARGE_INTEGER InterruptTime; - ULONG InterruptCount; -} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION; - -#ifndef SystemProcessorPerformanceInformation -# define SystemProcessorPerformanceInformation 8 -#endif - -#ifndef FILE_DEVICE_FILE_SYSTEM -# define FILE_DEVICE_FILE_SYSTEM 0x00000009 -#endif - -#ifndef FILE_DEVICE_NETWORK -# define FILE_DEVICE_NETWORK 0x00000012 -#endif - -#ifndef METHOD_BUFFERED -# define METHOD_BUFFERED 0 -#endif - -#ifndef METHOD_IN_DIRECT -# define METHOD_IN_DIRECT 1 -#endif - -#ifndef METHOD_OUT_DIRECT -# define METHOD_OUT_DIRECT 2 -#endif - -#ifndef METHOD_NEITHER -#define METHOD_NEITHER 3 -#endif - -#ifndef METHOD_DIRECT_TO_HARDWARE -# define METHOD_DIRECT_TO_HARDWARE METHOD_IN_DIRECT -#endif - -#ifndef METHOD_DIRECT_FROM_HARDWARE -# define METHOD_DIRECT_FROM_HARDWARE METHOD_OUT_DIRECT -#endif - -#ifndef FILE_ANY_ACCESS -# define FILE_ANY_ACCESS 0 -#endif - -#ifndef FILE_SPECIAL_ACCESS -# define FILE_SPECIAL_ACCESS (FILE_ANY_ACCESS) -#endif - -#ifndef FILE_READ_ACCESS -# define FILE_READ_ACCESS 0x0001 -#endif - -#ifndef FILE_WRITE_ACCESS -# define FILE_WRITE_ACCESS 0x0002 -#endif - -#ifndef CTL_CODE -# define CTL_CODE(device_type, function, method, access) \ - (((device_type) << 16) | ((access) << 14) | ((function) << 2) | (method)) -#endif - -#ifndef FSCTL_SET_REPARSE_POINT -# define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ - 41, \ - METHOD_BUFFERED, \ - FILE_SPECIAL_ACCESS) -#endif - -#ifndef FSCTL_GET_REPARSE_POINT -# define FSCTL_GET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ - 42, \ - METHOD_BUFFERED, \ - FILE_ANY_ACCESS) -#endif - -#ifndef FSCTL_DELETE_REPARSE_POINT -# define FSCTL_DELETE_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, \ - 43, \ - METHOD_BUFFERED, \ - FILE_SPECIAL_ACCESS) -#endif - -#ifndef IO_REPARSE_TAG_SYMLINK -# define IO_REPARSE_TAG_SYMLINK (0xA000000CL) -#endif - -typedef VOID (NTAPI *PIO_APC_ROUTINE) - (PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, - ULONG Reserved); - -typedef ULONG (NTAPI *sRtlNtStatusToDosError) - (NTSTATUS Status); - -typedef NTSTATUS (NTAPI *sNtDeviceIoControlFile) - (HANDLE FileHandle, - HANDLE Event, - PIO_APC_ROUTINE ApcRoutine, - PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, - ULONG IoControlCode, - PVOID InputBuffer, - ULONG InputBufferLength, - PVOID OutputBuffer, - ULONG OutputBufferLength); - -typedef NTSTATUS (NTAPI *sNtQueryInformationFile) - (HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass); - -typedef NTSTATUS (NTAPI *sNtSetInformationFile) - (HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass); - -typedef NTSTATUS (NTAPI *sNtQueryVolumeInformationFile) - (HANDLE FileHandle, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FsInformation, - ULONG Length, - FS_INFORMATION_CLASS FsInformationClass); - -typedef NTSTATUS (NTAPI *sNtQuerySystemInformation) - (UINT SystemInformationClass, - PVOID SystemInformation, - ULONG SystemInformationLength, - PULONG ReturnLength); - -typedef NTSTATUS (NTAPI *sNtQueryDirectoryFile) - (HANDLE FileHandle, - HANDLE Event, - PIO_APC_ROUTINE ApcRoutine, - PVOID ApcContext, - PIO_STATUS_BLOCK IoStatusBlock, - PVOID FileInformation, - ULONG Length, - FILE_INFORMATION_CLASS FileInformationClass, - BOOLEAN ReturnSingleEntry, - PUNICODE_STRING FileName, - BOOLEAN RestartScan - ); - -/* - * Kernel32 headers - */ -#ifndef FILE_SKIP_COMPLETION_PORT_ON_SUCCESS -# define FILE_SKIP_COMPLETION_PORT_ON_SUCCESS 0x1 -#endif - -#ifndef FILE_SKIP_SET_EVENT_ON_HANDLE -# define FILE_SKIP_SET_EVENT_ON_HANDLE 0x2 -#endif - -#ifndef SYMBOLIC_LINK_FLAG_DIRECTORY -# define SYMBOLIC_LINK_FLAG_DIRECTORY 0x1 -#endif - -#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) - typedef struct _OVERLAPPED_ENTRY { - ULONG_PTR lpCompletionKey; - LPOVERLAPPED lpOverlapped; - ULONG_PTR Internal; - DWORD dwNumberOfBytesTransferred; - } OVERLAPPED_ENTRY, *LPOVERLAPPED_ENTRY; -#endif - -/* from wincon.h */ -#ifndef ENABLE_INSERT_MODE -# define ENABLE_INSERT_MODE 0x20 -#endif - -#ifndef ENABLE_QUICK_EDIT_MODE -# define ENABLE_QUICK_EDIT_MODE 0x40 -#endif - -#ifndef ENABLE_EXTENDED_FLAGS -# define ENABLE_EXTENDED_FLAGS 0x80 -#endif - -/* from winerror.h */ -#ifndef ERROR_SYMLINK_NOT_SUPPORTED -# define ERROR_SYMLINK_NOT_SUPPORTED 1464 -#endif - -#ifndef ERROR_MUI_FILE_NOT_FOUND -# define ERROR_MUI_FILE_NOT_FOUND 15100 -#endif - -#ifndef ERROR_MUI_INVALID_FILE -# define ERROR_MUI_INVALID_FILE 15101 -#endif - -#ifndef ERROR_MUI_INVALID_RC_CONFIG -# define ERROR_MUI_INVALID_RC_CONFIG 15102 -#endif - -#ifndef ERROR_MUI_INVALID_LOCALE_NAME -# define ERROR_MUI_INVALID_LOCALE_NAME 15103 -#endif - -#ifndef ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME -# define ERROR_MUI_INVALID_ULTIMATEFALLBACK_NAME 15104 -#endif - -#ifndef ERROR_MUI_FILE_NOT_LOADED -# define ERROR_MUI_FILE_NOT_LOADED 15105 -#endif - -typedef BOOL (WINAPI *sGetQueuedCompletionStatusEx) - (HANDLE CompletionPort, - LPOVERLAPPED_ENTRY lpCompletionPortEntries, - ULONG ulCount, - PULONG ulNumEntriesRemoved, - DWORD dwMilliseconds, - BOOL fAlertable); - -typedef BOOL (WINAPI* sSetFileCompletionNotificationModes) - (HANDLE FileHandle, - UCHAR Flags); - -typedef BOOLEAN (WINAPI* sCreateSymbolicLinkW) - (LPCWSTR lpSymlinkFileName, - LPCWSTR lpTargetFileName, - DWORD dwFlags); - -typedef BOOL (WINAPI* sCancelIoEx) - (HANDLE hFile, - LPOVERLAPPED lpOverlapped); - -typedef VOID (WINAPI* sInitializeConditionVariable) - (PCONDITION_VARIABLE ConditionVariable); - -typedef BOOL (WINAPI* sSleepConditionVariableCS) - (PCONDITION_VARIABLE ConditionVariable, - PCRITICAL_SECTION CriticalSection, - DWORD dwMilliseconds); - -typedef BOOL (WINAPI* sSleepConditionVariableSRW) - (PCONDITION_VARIABLE ConditionVariable, - PSRWLOCK SRWLock, - DWORD dwMilliseconds, - ULONG Flags); - -typedef VOID (WINAPI* sWakeAllConditionVariable) - (PCONDITION_VARIABLE ConditionVariable); - -typedef VOID (WINAPI* sWakeConditionVariable) - (PCONDITION_VARIABLE ConditionVariable); - -typedef BOOL (WINAPI* sCancelSynchronousIo) - (HANDLE hThread); - -typedef DWORD (WINAPI* sGetFinalPathNameByHandleW) - (HANDLE hFile, - LPWSTR lpszFilePath, - DWORD cchFilePath, - DWORD dwFlags); - -/* Ntdll function pointers */ -extern sRtlNtStatusToDosError pRtlNtStatusToDosError; -extern sNtDeviceIoControlFile pNtDeviceIoControlFile; -extern sNtQueryInformationFile pNtQueryInformationFile; -extern sNtSetInformationFile pNtSetInformationFile; -extern sNtQueryVolumeInformationFile pNtQueryVolumeInformationFile; -extern sNtQueryDirectoryFile pNtQueryDirectoryFile; -extern sNtQuerySystemInformation pNtQuerySystemInformation; - - -/* Kernel32 function pointers */ -extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx; -extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes; -extern sCreateSymbolicLinkW pCreateSymbolicLinkW; -extern sCancelIoEx pCancelIoEx; -extern sInitializeConditionVariable pInitializeConditionVariable; -extern sSleepConditionVariableCS pSleepConditionVariableCS; -extern sSleepConditionVariableSRW pSleepConditionVariableSRW; -extern sWakeAllConditionVariable pWakeAllConditionVariable; -extern sWakeConditionVariable pWakeConditionVariable; -extern sCancelSynchronousIo pCancelSynchronousIo; -extern sGetFinalPathNameByHandleW pGetFinalPathNameByHandleW; - -#endif /* UV_WIN_WINAPI_H_ */ diff --git a/3rdparty/libuv/src/win/winsock.c b/3rdparty/libuv/src/win/winsock.c deleted file mode 100644 index d2e667e9f75..00000000000 --- a/3rdparty/libuv/src/win/winsock.c +++ /dev/null @@ -1,561 +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. - */ - -#include <assert.h> -#include <stdlib.h> - -#include "uv.h" -#include "internal.h" - - -/* Whether there are any non-IFS LSPs stacked on TCP */ -int uv_tcp_non_ifs_lsp_ipv4; -int uv_tcp_non_ifs_lsp_ipv6; - -/* Ip address used to bind to any port at any interface */ -struct sockaddr_in uv_addr_ip4_any_; -struct sockaddr_in6 uv_addr_ip6_any_; - - -/* - * Retrieves the pointer to a winsock extension function. - */ -static BOOL uv_get_extension_function(SOCKET socket, GUID guid, - void **target) { - int result; - DWORD bytes; - - result = WSAIoctl(socket, - SIO_GET_EXTENSION_FUNCTION_POINTER, - &guid, - sizeof(guid), - (void*)target, - sizeof(*target), - &bytes, - NULL, - NULL); - - if (result == SOCKET_ERROR) { - *target = NULL; - return FALSE; - } else { - return TRUE; - } -} - - -BOOL uv_get_acceptex_function(SOCKET socket, LPFN_ACCEPTEX* target) { - const GUID wsaid_acceptex = WSAID_ACCEPTEX; - return uv_get_extension_function(socket, wsaid_acceptex, (void**)target); -} - - -BOOL uv_get_connectex_function(SOCKET socket, LPFN_CONNECTEX* target) { - const GUID wsaid_connectex = WSAID_CONNECTEX; - return uv_get_extension_function(socket, wsaid_connectex, (void**)target); -} - - -static int error_means_no_support(DWORD error) { - return error == WSAEPROTONOSUPPORT || error == WSAESOCKTNOSUPPORT || - error == WSAEPFNOSUPPORT || error == WSAEAFNOSUPPORT; -} - - -void uv_winsock_init() { - WSADATA wsa_data; - int errorno; - SOCKET dummy; - WSAPROTOCOL_INFOW protocol_info; - int opt_len; - - /* Initialize winsock */ - errorno = WSAStartup(MAKEWORD(2, 2), &wsa_data); - if (errorno != 0) { - uv_fatal_error(errorno, "WSAStartup"); - } - - /* Set implicit binding address used by connectEx */ - if (uv_ip4_addr("0.0.0.0", 0, &uv_addr_ip4_any_)) { - abort(); - } - - if (uv_ip6_addr("::", 0, &uv_addr_ip6_any_)) { - abort(); - } - - /* Detect non-IFS LSPs */ - dummy = socket(AF_INET, SOCK_STREAM, IPPROTO_IP); - - if (dummy != INVALID_SOCKET) { - opt_len = (int) sizeof protocol_info; - if (getsockopt(dummy, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "getsockopt"); - - if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) - uv_tcp_non_ifs_lsp_ipv4 = 1; - - if (closesocket(dummy) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "closesocket"); - - } else if (!error_means_no_support(WSAGetLastError())) { - /* Any error other than "socket type not supported" is fatal. */ - uv_fatal_error(WSAGetLastError(), "socket"); - } - - /* Detect IPV6 support and non-IFS LSPs */ - dummy = socket(AF_INET6, SOCK_STREAM, IPPROTO_IP); - - if (dummy != INVALID_SOCKET) { - opt_len = (int) sizeof protocol_info; - if (getsockopt(dummy, - SOL_SOCKET, - SO_PROTOCOL_INFOW, - (char*) &protocol_info, - &opt_len) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "getsockopt"); - - if (!(protocol_info.dwServiceFlags1 & XP1_IFS_HANDLES)) - uv_tcp_non_ifs_lsp_ipv6 = 1; - - if (closesocket(dummy) == SOCKET_ERROR) - uv_fatal_error(WSAGetLastError(), "closesocket"); - - } else if (!error_means_no_support(WSAGetLastError())) { - /* Any error other than "socket type not supported" is fatal. */ - uv_fatal_error(WSAGetLastError(), "socket"); - } -} - - -int uv_ntstatus_to_winsock_error(NTSTATUS status) { - switch (status) { - case STATUS_SUCCESS: - return ERROR_SUCCESS; - - case STATUS_PENDING: - return ERROR_IO_PENDING; - - case STATUS_INVALID_HANDLE: - case STATUS_OBJECT_TYPE_MISMATCH: - return WSAENOTSOCK; - - case STATUS_INSUFFICIENT_RESOURCES: - case STATUS_PAGEFILE_QUOTA: - case STATUS_COMMITMENT_LIMIT: - case STATUS_WORKING_SET_QUOTA: - case STATUS_NO_MEMORY: - case STATUS_QUOTA_EXCEEDED: - case STATUS_TOO_MANY_PAGING_FILES: - case STATUS_REMOTE_RESOURCES: - return WSAENOBUFS; - - case STATUS_TOO_MANY_ADDRESSES: - case STATUS_SHARING_VIOLATION: - case STATUS_ADDRESS_ALREADY_EXISTS: - return WSAEADDRINUSE; - - case STATUS_LINK_TIMEOUT: - case STATUS_IO_TIMEOUT: - case STATUS_TIMEOUT: - return WSAETIMEDOUT; - - case STATUS_GRACEFUL_DISCONNECT: - return WSAEDISCON; - - case STATUS_REMOTE_DISCONNECT: - case STATUS_CONNECTION_RESET: - case STATUS_LINK_FAILED: - case STATUS_CONNECTION_DISCONNECTED: - case STATUS_PORT_UNREACHABLE: - case STATUS_HOPLIMIT_EXCEEDED: - return WSAECONNRESET; - - case STATUS_LOCAL_DISCONNECT: - case STATUS_TRANSACTION_ABORTED: - case STATUS_CONNECTION_ABORTED: - return WSAECONNABORTED; - - case STATUS_BAD_NETWORK_PATH: - case STATUS_NETWORK_UNREACHABLE: - case STATUS_PROTOCOL_UNREACHABLE: - return WSAENETUNREACH; - - case STATUS_HOST_UNREACHABLE: - return WSAEHOSTUNREACH; - - case STATUS_CANCELLED: - case STATUS_REQUEST_ABORTED: - return WSAEINTR; - - case STATUS_BUFFER_OVERFLOW: - case STATUS_INVALID_BUFFER_SIZE: - return WSAEMSGSIZE; - - case STATUS_BUFFER_TOO_SMALL: - case STATUS_ACCESS_VIOLATION: - return WSAEFAULT; - - case STATUS_DEVICE_NOT_READY: - case STATUS_REQUEST_NOT_ACCEPTED: - return WSAEWOULDBLOCK; - - case STATUS_INVALID_NETWORK_RESPONSE: - case STATUS_NETWORK_BUSY: - case STATUS_NO_SUCH_DEVICE: - case STATUS_NO_SUCH_FILE: - case STATUS_OBJECT_PATH_NOT_FOUND: - case STATUS_OBJECT_NAME_NOT_FOUND: - case STATUS_UNEXPECTED_NETWORK_ERROR: - return WSAENETDOWN; - - case STATUS_INVALID_CONNECTION: - return WSAENOTCONN; - - case STATUS_REMOTE_NOT_LISTENING: - case STATUS_CONNECTION_REFUSED: - return WSAECONNREFUSED; - - case STATUS_PIPE_DISCONNECTED: - return WSAESHUTDOWN; - - case STATUS_CONFLICTING_ADDRESSES: - case STATUS_INVALID_ADDRESS: - case STATUS_INVALID_ADDRESS_COMPONENT: - return WSAEADDRNOTAVAIL; - - case STATUS_NOT_SUPPORTED: - case STATUS_NOT_IMPLEMENTED: - return WSAEOPNOTSUPP; - - case STATUS_ACCESS_DENIED: - return WSAEACCES; - - default: - if ((status & (FACILITY_NTWIN32 << 16)) == (FACILITY_NTWIN32 << 16) && - (status & (ERROR_SEVERITY_ERROR | ERROR_SEVERITY_WARNING))) { - /* It's a windows error that has been previously mapped to an */ - /* ntstatus code. */ - return (DWORD) (status & 0xffff); - } else { - /* The default fallback for unmappable ntstatus codes. */ - return WSAEINVAL; - } - } -} - - -/* - * This function provides a workaround for a bug in the winsock implementation - * of WSARecv. The problem is that when SetFileCompletionNotificationModes is - * used to avoid IOCP notifications of completed reads, WSARecv does not - * reliably indicate whether we can expect a completion package to be posted - * when the receive buffer is smaller than the received datagram. - * - * However it is desirable to use SetFileCompletionNotificationModes because - * it yields a massive performance increase. - * - * This function provides a workaround for that bug, but it only works for the - * specific case that we need it for. E.g. it assumes that the "avoid iocp" - * bit has been set, and supports only overlapped operation. It also requires - * the user to use the default msafd driver, doesn't work when other LSPs are - * stacked on top of it. - */ -int WSAAPI uv_wsarecv_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) { - NTSTATUS status; - void* apc_context; - IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal; - AFD_RECV_INFO info; - DWORD error; - - if (overlapped == NULL || completion_routine != NULL) { - WSASetLastError(WSAEINVAL); - return SOCKET_ERROR; - } - - info.BufferArray = buffers; - info.BufferCount = buffer_count; - info.AfdFlags = AFD_OVERLAPPED; - info.TdiFlags = TDI_RECEIVE_NORMAL; - - if (*flags & MSG_PEEK) { - info.TdiFlags |= TDI_RECEIVE_PEEK; - } - - if (*flags & MSG_PARTIAL) { - info.TdiFlags |= TDI_RECEIVE_PARTIAL; - } - - if (!((intptr_t) overlapped->hEvent & 1)) { - apc_context = (void*) overlapped; - } else { - apc_context = NULL; - } - - iosb->Status = STATUS_PENDING; - iosb->Pointer = 0; - - status = pNtDeviceIoControlFile((HANDLE) socket, - overlapped->hEvent, - NULL, - apc_context, - iosb, - IOCTL_AFD_RECEIVE, - &info, - sizeof(info), - NULL, - 0); - - *flags = 0; - *bytes = (DWORD) iosb->Information; - - switch (status) { - case STATUS_SUCCESS: - error = ERROR_SUCCESS; - break; - - case STATUS_PENDING: - error = WSA_IO_PENDING; - break; - - case STATUS_BUFFER_OVERFLOW: - error = WSAEMSGSIZE; - break; - - case STATUS_RECEIVE_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL | MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL; - break; - - default: - error = uv_ntstatus_to_winsock_error(status); - break; - } - - WSASetLastError(error); - - if (error == ERROR_SUCCESS) { - return 0; - } else { - return SOCKET_ERROR; - } -} - - -/* See description of uv_wsarecv_workaround. */ -int WSAAPI uv_wsarecvfrom_workaround(SOCKET socket, WSABUF* buffers, - DWORD buffer_count, DWORD* bytes, DWORD* flags, struct sockaddr* addr, - int* addr_len, WSAOVERLAPPED *overlapped, - LPWSAOVERLAPPED_COMPLETION_ROUTINE completion_routine) { - NTSTATUS status; - void* apc_context; - IO_STATUS_BLOCK* iosb = (IO_STATUS_BLOCK*) &overlapped->Internal; - AFD_RECV_DATAGRAM_INFO info; - DWORD error; - - if (overlapped == NULL || addr == NULL || addr_len == NULL || - completion_routine != NULL) { - WSASetLastError(WSAEINVAL); - return SOCKET_ERROR; - } - - info.BufferArray = buffers; - info.BufferCount = buffer_count; - info.AfdFlags = AFD_OVERLAPPED; - info.TdiFlags = TDI_RECEIVE_NORMAL; - info.Address = addr; - info.AddressLength = addr_len; - - if (*flags & MSG_PEEK) { - info.TdiFlags |= TDI_RECEIVE_PEEK; - } - - if (*flags & MSG_PARTIAL) { - info.TdiFlags |= TDI_RECEIVE_PARTIAL; - } - - if (!((intptr_t) overlapped->hEvent & 1)) { - apc_context = (void*) overlapped; - } else { - apc_context = NULL; - } - - iosb->Status = STATUS_PENDING; - iosb->Pointer = 0; - - status = pNtDeviceIoControlFile((HANDLE) socket, - overlapped->hEvent, - NULL, - apc_context, - iosb, - IOCTL_AFD_RECEIVE_DATAGRAM, - &info, - sizeof(info), - NULL, - 0); - - *flags = 0; - *bytes = (DWORD) iosb->Information; - - switch (status) { - case STATUS_SUCCESS: - error = ERROR_SUCCESS; - break; - - case STATUS_PENDING: - error = WSA_IO_PENDING; - break; - - case STATUS_BUFFER_OVERFLOW: - error = WSAEMSGSIZE; - break; - - case STATUS_RECEIVE_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL_EXPEDITED: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL | MSG_OOB; - break; - - case STATUS_RECEIVE_PARTIAL: - error = ERROR_SUCCESS; - *flags = MSG_PARTIAL; - break; - - default: - error = uv_ntstatus_to_winsock_error(status); - break; - } - - WSASetLastError(error); - - if (error == ERROR_SUCCESS) { - return 0; - } else { - return SOCKET_ERROR; - } -} - - -int WSAAPI uv_msafd_poll(SOCKET socket, AFD_POLL_INFO* info_in, - AFD_POLL_INFO* info_out, OVERLAPPED* overlapped) { - IO_STATUS_BLOCK iosb; - IO_STATUS_BLOCK* iosb_ptr; - HANDLE event = NULL; - void* apc_context; - NTSTATUS status; - DWORD error; - - if (overlapped != NULL) { - /* Overlapped operation. */ - iosb_ptr = (IO_STATUS_BLOCK*) &overlapped->Internal; - event = overlapped->hEvent; - - /* Do not report iocp completion if hEvent is tagged. */ - if ((uintptr_t) event & 1) { - event = (HANDLE)((uintptr_t) event & ~(uintptr_t) 1); - apc_context = NULL; - } else { - apc_context = overlapped; - } - - } else { - /* Blocking operation. */ - iosb_ptr = &iosb; - event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (event == NULL) { - return SOCKET_ERROR; - } - apc_context = NULL; - } - - iosb_ptr->Status = STATUS_PENDING; - status = pNtDeviceIoControlFile((HANDLE) socket, - event, - NULL, - apc_context, - iosb_ptr, - IOCTL_AFD_POLL, - info_in, - sizeof *info_in, - info_out, - sizeof *info_out); - - if (overlapped == NULL) { - /* If this is a blocking operation, wait for the event to become */ - /* signaled, and then grab the real status from the io status block. */ - if (status == STATUS_PENDING) { - DWORD r = WaitForSingleObject(event, INFINITE); - - if (r == WAIT_FAILED) { - DWORD saved_error = GetLastError(); - CloseHandle(event); - WSASetLastError(saved_error); - return SOCKET_ERROR; - } - - status = iosb.Status; - } - - CloseHandle(event); - } - - switch (status) { - case STATUS_SUCCESS: - error = ERROR_SUCCESS; - break; - - case STATUS_PENDING: - error = WSA_IO_PENDING; - break; - - default: - error = uv_ntstatus_to_winsock_error(status); - break; - } - - WSASetLastError(error); - - if (error == ERROR_SUCCESS) { - return 0; - } else { - return SOCKET_ERROR; - } -} diff --git a/3rdparty/libuv/src/win/winsock.h b/3rdparty/libuv/src/win/winsock.h deleted file mode 100644 index 7c007ab4934..00000000000 --- a/3rdparty/libuv/src/win/winsock.h +++ /dev/null @@ -1,190 +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_WINSOCK_H_ -#define UV_WIN_WINSOCK_H_ - -#include <winsock2.h> -#include <iptypes.h> -#include <mswsock.h> -#include <ws2tcpip.h> -#include <windows.h> - -#include "winapi.h" - - -/* - * MinGW is missing these too - */ -#ifndef SO_UPDATE_CONNECT_CONTEXT -# define SO_UPDATE_CONNECT_CONTEXT 0x7010 -#endif - -#ifndef TCP_KEEPALIVE -# define TCP_KEEPALIVE 3 -#endif - -#ifndef IPV6_V6ONLY -# define IPV6_V6ONLY 27 -#endif - -#ifndef IPV6_HOPLIMIT -# define IPV6_HOPLIMIT 21 -#endif - -#ifndef SIO_BASE_HANDLE -# define SIO_BASE_HANDLE 0x48000022 -#endif - -/* - * TDI defines that are only in the DDK. - * We only need receive flags so far. - */ -#ifndef TDI_RECEIVE_NORMAL - #define TDI_RECEIVE_BROADCAST 0x00000004 - #define TDI_RECEIVE_MULTICAST 0x00000008 - #define TDI_RECEIVE_PARTIAL 0x00000010 - #define TDI_RECEIVE_NORMAL 0x00000020 - #define TDI_RECEIVE_EXPEDITED 0x00000040 - #define TDI_RECEIVE_PEEK 0x00000080 - #define TDI_RECEIVE_NO_RESPONSE_EXP 0x00000100 - #define TDI_RECEIVE_COPY_LOOKAHEAD 0x00000200 - #define TDI_RECEIVE_ENTIRE_MESSAGE 0x00000400 - #define TDI_RECEIVE_AT_DISPATCH_LEVEL 0x00000800 - #define TDI_RECEIVE_CONTROL_INFO 0x00001000 - #define TDI_RECEIVE_FORCE_INDICATION 0x00002000 - #define TDI_RECEIVE_NO_PUSH 0x00004000 -#endif - -/* - * The "Auxiliary Function Driver" is the windows kernel-mode driver that does - * TCP, UDP etc. Winsock is just a layer that dispatches requests to it. - * Having these definitions allows us to bypass winsock and make an AFD kernel - * call directly, avoiding a bug in winsock's recvfrom implementation. - */ - -#define AFD_NO_FAST_IO 0x00000001 -#define AFD_OVERLAPPED 0x00000002 -#define AFD_IMMEDIATE 0x00000004 - -#define AFD_POLL_RECEIVE_BIT 0 -#define AFD_POLL_RECEIVE (1 << AFD_POLL_RECEIVE_BIT) -#define AFD_POLL_RECEIVE_EXPEDITED_BIT 1 -#define AFD_POLL_RECEIVE_EXPEDITED (1 << AFD_POLL_RECEIVE_EXPEDITED_BIT) -#define AFD_POLL_SEND_BIT 2 -#define AFD_POLL_SEND (1 << AFD_POLL_SEND_BIT) -#define AFD_POLL_DISCONNECT_BIT 3 -#define AFD_POLL_DISCONNECT (1 << AFD_POLL_DISCONNECT_BIT) -#define AFD_POLL_ABORT_BIT 4 -#define AFD_POLL_ABORT (1 << AFD_POLL_ABORT_BIT) -#define AFD_POLL_LOCAL_CLOSE_BIT 5 -#define AFD_POLL_LOCAL_CLOSE (1 << AFD_POLL_LOCAL_CLOSE_BIT) -#define AFD_POLL_CONNECT_BIT 6 -#define AFD_POLL_CONNECT (1 << AFD_POLL_CONNECT_BIT) -#define AFD_POLL_ACCEPT_BIT 7 -#define AFD_POLL_ACCEPT (1 << AFD_POLL_ACCEPT_BIT) -#define AFD_POLL_CONNECT_FAIL_BIT 8 -#define AFD_POLL_CONNECT_FAIL (1 << AFD_POLL_CONNECT_FAIL_BIT) -#define AFD_POLL_QOS_BIT 9 -#define AFD_POLL_QOS (1 << AFD_POLL_QOS_BIT) -#define AFD_POLL_GROUP_QOS_BIT 10 -#define AFD_POLL_GROUP_QOS (1 << AFD_POLL_GROUP_QOS_BIT) - -#define AFD_NUM_POLL_EVENTS 11 -#define AFD_POLL_ALL ((1 << AFD_NUM_POLL_EVENTS) - 1) - -typedef struct _AFD_RECV_DATAGRAM_INFO { - LPWSABUF BufferArray; - ULONG BufferCount; - ULONG AfdFlags; - ULONG TdiFlags; - struct sockaddr* Address; - int* AddressLength; -} AFD_RECV_DATAGRAM_INFO, *PAFD_RECV_DATAGRAM_INFO; - -typedef struct _AFD_RECV_INFO { - LPWSABUF BufferArray; - ULONG BufferCount; - ULONG AfdFlags; - ULONG TdiFlags; -} AFD_RECV_INFO, *PAFD_RECV_INFO; - - -#define _AFD_CONTROL_CODE(operation, method) \ - ((FSCTL_AFD_BASE) << 12 | (operation << 2) | method) - -#define FSCTL_AFD_BASE FILE_DEVICE_NETWORK - -#define AFD_RECEIVE 5 -#define AFD_RECEIVE_DATAGRAM 6 -#define AFD_POLL 9 - -#define IOCTL_AFD_RECEIVE \ - _AFD_CONTROL_CODE(AFD_RECEIVE, METHOD_NEITHER) - -#define IOCTL_AFD_RECEIVE_DATAGRAM \ - _AFD_CONTROL_CODE(AFD_RECEIVE_DATAGRAM, METHOD_NEITHER) - -#define IOCTL_AFD_POLL \ - _AFD_CONTROL_CODE(AFD_POLL, METHOD_BUFFERED) - -#if defined(__MINGW32__) && !defined(__MINGW64_VERSION_MAJOR) -typedef struct _IP_ADAPTER_UNICAST_ADDRESS_XP { - /* FIXME: __C89_NAMELESS was removed */ - /* __C89_NAMELESS */ union { - ULONGLONG Alignment; - /* __C89_NAMELESS */ struct { - ULONG Length; - DWORD Flags; - }; - }; - struct _IP_ADAPTER_UNICAST_ADDRESS_XP *Next; - SOCKET_ADDRESS Address; - IP_PREFIX_ORIGIN PrefixOrigin; - IP_SUFFIX_ORIGIN SuffixOrigin; - IP_DAD_STATE DadState; - ULONG ValidLifetime; - ULONG PreferredLifetime; - ULONG LeaseLifetime; -} IP_ADAPTER_UNICAST_ADDRESS_XP,*PIP_ADAPTER_UNICAST_ADDRESS_XP; - -typedef struct _IP_ADAPTER_UNICAST_ADDRESS_LH { - union { - ULONGLONG Alignment; - struct { - ULONG Length; - DWORD Flags; - }; - }; - struct _IP_ADAPTER_UNICAST_ADDRESS_LH *Next; - SOCKET_ADDRESS Address; - IP_PREFIX_ORIGIN PrefixOrigin; - IP_SUFFIX_ORIGIN SuffixOrigin; - IP_DAD_STATE DadState; - ULONG ValidLifetime; - ULONG PreferredLifetime; - ULONG LeaseLifetime; - UINT8 OnLinkPrefixLength; -} IP_ADAPTER_UNICAST_ADDRESS_LH,*PIP_ADAPTER_UNICAST_ADDRESS_LH; - -#endif - -#endif /* UV_WIN_WINSOCK_H_ */ |