102 snprintf(
name,
size,
"\\\\?\\pipe\\uv\\%p-%lu",
ptr, GetCurrentProcessId());
112 handle->pipe.conn.ipc_remote_pid = 0;
113 handle->pipe.conn.ipc_data_frame.payload_remaining = 0;
115 handle->pipe.conn.ipc_xfer_queue_length = 0;
117 handle->pipe.conn.non_overlapped_writes_tail = NULL;
126 handle->pipe.conn.eof_timer = NULL;
129 handle->pipe.conn.readfile_thread_handle = NULL;
130 InitializeCriticalSection(&
handle->pipe.conn.readfile_thread_lock);
142 pipeHandle = CreateFileW(
name,
143 GENERIC_READ | GENERIC_WRITE,
147 FILE_FLAG_OVERLAPPED,
159 if (GetLastError() == ERROR_ACCESS_DENIED) {
160 pipeHandle = CreateFileW(
name,
161 GENERIC_READ | FILE_WRITE_ATTRIBUTES,
165 FILE_FLAG_OVERLAPPED,
174 if (GetLastError() == ERROR_ACCESS_DENIED) {
175 pipeHandle = CreateFileW(
name,
176 GENERIC_WRITE | FILE_READ_ATTRIBUTES,
180 FILE_FLAG_OVERLAPPED,
194 assert(pipe->u.fd == -1 || pipe->u.fd > 2);
195 if (pipe->u.fd == -1)
196 CloseHandle(pipe->handle);
206 char*
name,
size_t nameSize) {
214 pipeHandle = CreateNamedPipeA(
name,
215 access | FILE_FLAG_OVERLAPPED | FILE_FLAG_FIRST_PIPE_INSTANCE | WRITE_DAC,
216 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT, 1, 65536, 65536, 0,
224 err = GetLastError();
225 if (
err != ERROR_PIPE_BUSY &&
err != ERROR_ACCESS_DENIED) {
233 if (CreateIoCompletionPort(pipeHandle,
237 err = GetLastError();
242 handle->handle = pipeHandle;
248 CloseHandle(pipeHandle);
259 DWORD duplex_flags) {
263 DWORD
mode = PIPE_READMODE_BYTE | PIPE_WAIT;
264 DWORD current_mode = 0;
272 if (!SetNamedPipeHandleState(pipeHandle, &
mode, NULL, NULL)) {
273 err = GetLastError();
274 if (
err == ERROR_ACCESS_DENIED) {
281 if (!GetNamedPipeHandleState(pipeHandle, ¤t_mode, NULL, NULL,
284 }
else if (current_mode & PIPE_NOWAIT) {
285 SetLastError(ERROR_ACCESS_DENIED);
291 if (
err == ERROR_INVALID_PARAMETER) {
292 SetLastError(WSAENOTSOCK);
314 if (CreateIoCompletionPort(pipeHandle,
322 handle->handle = pipeHandle;
324 handle->flags |= duplex_flags;
331 uv_pipe_accept_t*
req,
BOOL firstInstance) {
335 CreateNamedPipeW(
handle->name,
336 PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED | WRITE_DAC |
337 (firstInstance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0),
338 PIPE_TYPE_BYTE | PIPE_READMODE_BYTE | PIPE_WAIT,
339 PIPE_UNLIMITED_INSTANCES, 65536, 65536, 0, NULL);
346 if (CreateIoCompletionPort(
req->pipeHandle,
374 FlushFileBuffers(
handle->handle);
393 handle->stream.conn.shutdown_req != NULL &&
394 handle->stream.conn.write_reqs_pending == 0) {
398 handle->stream.conn.shutdown_req = NULL;
442 WT_EXECUTELONGFUNCTION);
452 err = GetLastError();
462 handle->reqs_pending == 0) {
476 socket = WSASocketW(FROM_PROTOCOL_INFO,
481 WSA_FLAG_OVERLAPPED);
484 if (
socket != INVALID_SOCKET)
487 handle->pipe.conn.ipc_xfer_queue_length = 0;
491 UnregisterWait(
handle->read_req.wait_handle);
494 if (
handle->read_req.event_handle != NULL) {
495 CloseHandle(
handle->read_req.event_handle);
496 handle->read_req.event_handle = NULL;
501 DeleteCriticalSection(&
handle->pipe.conn.readfile_thread_lock);
505 assert(
handle->pipe.serv.accept_reqs);
507 handle->pipe.serv.accept_reqs = NULL;
526 int i,
err, nameSize;
527 uv_pipe_accept_t*
req;
541 handle->pipe.serv.accept_reqs = (uv_pipe_accept_t*)
543 if (!
handle->pipe.serv.accept_reqs) {
547 for (
i = 0;
i <
handle->pipe.serv.pending_instances;
i++) {
552 req->next_pending = NULL;
556 nameSize = MultiByteToWideChar(CP_UTF8, 0,
name, -1, NULL, 0) *
sizeof(WCHAR);
562 if (!MultiByteToWideChar(CP_UTF8,
567 nameSize /
sizeof(WCHAR))) {
568 err = GetLastError();
578 &
handle->pipe.serv.accept_reqs[0],
580 err = GetLastError();
581 if (
err == ERROR_ACCESS_DENIED) {
583 }
else if (
err == ERROR_PATH_NOT_FOUND ||
err == ERROR_INVALID_NAME) {
589 handle->pipe.serv.pending_accepts = NULL;
621 while (WaitNamedPipeW(
handle->name, 30000)) {
657 nameSize = MultiByteToWideChar(CP_UTF8, 0,
name, -1, NULL, 0) *
sizeof(WCHAR);
663 if (!MultiByteToWideChar(CP_UTF8,
668 nameSize /
sizeof(WCHAR))) {
669 err = GetLastError();
675 if (GetLastError() == ERROR_PIPE_BUSY) {
679 WT_EXECUTELONGFUNCTION)) {
680 err = GetLastError();
690 err = GetLastError();
701 err = GetLastError();
718 CloseHandle(pipeHandle);
742 r = CancelIoEx(
handle->handle, &
handle->read_req.u.io.overlapped);
743 assert(
r || GetLastError() == ERROR_NOT_FOUND);
748 volatile HANDLE* thread_ptr = &
handle->pipe.conn.readfile_thread_handle;
750 EnterCriticalSection(&
handle->pipe.conn.readfile_thread_lock);
762 r = CancelSynchronousIo(
thread);
763 assert(
r || GetLastError() == ERROR_NOT_FOUND);
769 LeaveCriticalSection(&
handle->pipe.conn.readfile_thread_lock);
799 for (
i = 0;
i <
handle->pipe.serv.pending_instances;
i++) {
800 pipeHandle =
handle->pipe.serv.accept_reqs[
i].pipeHandle;
802 CloseHandle(pipeHandle);
833 if (
handle->reqs_pending == 0) {
843 uv_pipe_accept_t*
req,
BOOL firstInstance) {
856 memset(&(
req->u.io.overlapped), 0,
sizeof(
req->u.io.overlapped));
858 if (!ConnectNamedPipe(
req->pipeHandle, &
req->u.io.overlapped) &&
859 GetLastError() != ERROR_IO_PENDING) {
860 if (GetLastError() == ERROR_PIPE_CONNECTED) {
863 CloseHandle(
req->pipeHandle);
881 uv_pipe_accept_t*
req;
889 return WSAEWOULDBLOCK;
894 server->pipe.conn.ipc_xfer_queue_length--;
913 return WSAEWOULDBLOCK;
922 server->pipe.serv.pending_accepts =
req->next_pending;
923 req->next_pending = NULL;
942 handle->stream.serv.connection_cb =
cb;
954 return ERROR_NOT_SUPPORTED;
963 handle->stream.serv.connection_cb =
cb;
968 for (
i = 0;
i <
handle->pipe.serv.pending_instances;
i++) {
977 uv_read_t*
req = (uv_read_t*)
arg;
980 volatile HANDLE* thread_ptr = &
handle->pipe.conn.readfile_thread_handle;
981 CRITICAL_SECTION* lock = &
handle->pipe.conn.readfile_thread_lock;
986 assert(
req->type == UV_READ);
987 assert(
handle->type == UV_NAMED_PIPE);
992 if (!DuplicateHandle(GetCurrentProcess(),
998 DUPLICATE_SAME_ACCESS)) {
999 err = GetLastError();
1004 EnterCriticalSection(lock);
1007 err = ERROR_OPERATION_ABORTED;
1010 assert(*thread_ptr == NULL);
1013 LeaveCriticalSection(lock);
1021 err = GetLastError();
1024 assert(
thread == *thread_ptr);
1030 EnterCriticalSection(lock);
1031 LeaveCriticalSection(lock);
1056 assert(
req != NULL);
1057 assert(
req->type == UV_WRITE);
1058 assert(
handle->type == UV_NAMED_PIPE);
1059 assert(
req->write_buffer.base);
1062 req->write_buffer.base,
1063 req->write_buffer.len,
1081 assert(
req != NULL);
1086 if (!PostQueuedCompletionStatus(
handle->loop->iocp,
1087 req->u.io.overlapped.InternalHigh,
1089 &
req->u.io.overlapped)) {
1100 assert(
req != NULL);
1105 if (!PostQueuedCompletionStatus(
handle->loop->iocp,
1106 req->u.io.overlapped.InternalHigh,
1108 &
req->u.io.overlapped)) {
1126 handle->pipe.conn.readfile_thread_handle = NULL;
1129 WT_EXECUTELONGFUNCTION)) {
1135 memset(&
req->u.io.overlapped, 0,
sizeof(
req->u.io.overlapped));
1137 assert(
req->event_handle != NULL);
1138 req->u.io.overlapped.hEvent = (HANDLE) ((
uintptr_t)
req->event_handle | 1);
1146 &
req->u.io.overlapped);
1148 if (!
result && GetLastError() != ERROR_IO_PENDING) {
1156 if (!RegisterWaitForSingleObject(&
req->wait_handle,
1158 INFINITE, WT_EXECUTEINWAITTHREAD)) {
1193 handle->read_req.event_handle == NULL) {
1194 handle->read_req.event_handle = CreateEvent(NULL, 0, 0, NULL);
1195 if (
handle->read_req.event_handle == NULL) {
1208 req->next_req = NULL;
1209 if (
handle->pipe.conn.non_overlapped_writes_tail) {
1211 handle->pipe.conn.non_overlapped_writes_tail->next_req;
1213 handle->pipe.conn.non_overlapped_writes_tail =
req;
1216 handle->pipe.conn.non_overlapped_writes_tail =
req;
1224 if (
handle->pipe.conn.non_overlapped_writes_tail) {
1227 if (
req ==
handle->pipe.conn.non_overlapped_writes_tail) {
1228 handle->pipe.conn.non_overlapped_writes_tail = NULL;
1230 handle->pipe.conn.non_overlapped_writes_tail->next_req =
1247 WT_EXECUTELONGFUNCTION)) {
1265 size_t heap_buffer_length, heap_buffer_offset;
1273 for (
i = 0;
i < nbufs;
i++)
1282 heap_buffer_length =
sizeof *coalesced_write_req +
1286 heap_buffer =
uv__malloc(heap_buffer_length);
1287 if (heap_buffer == NULL)
1288 return ERROR_NOT_ENOUGH_MEMORY;
1292 coalesced_write_req->
req = *user_req;
1293 coalesced_write_req->
req.coalesced = 1;
1294 coalesced_write_req->
user_req = user_req;
1295 heap_buffer_offset =
sizeof *coalesced_write_req;
1298 data_start = &heap_buffer[heap_buffer_offset];
1299 for (
i = 0;
i < nbufs;
i++) {
1300 memcpy(&heap_buffer[heap_buffer_offset],
1305 assert(heap_buffer_offset == heap_buffer_length);
1308 *req_out = &coalesced_write_req->
req;
1309 *write_buf_out =
uv_buf_init(data_start, (
unsigned int) data_length);
1329 req->send_handle = NULL;
1333 req->event_handle = NULL;
1337 memset(&
req->u.io.overlapped, 0,
sizeof(
req->u.io.overlapped));
1339 req->event_handle = CreateEvent(NULL, 0, 0, NULL);
1340 if (
req->event_handle == NULL) {
1343 req->u.io.overlapped.hEvent = (HANDLE) ((
uintptr_t)
req->event_handle | 1);
1350 }
else if (nbufs == 1 && !copy_always) {
1352 write_buf =
bufs[0];
1369 err = GetLastError();
1373 req->u.io.queued_bytes = 0;
1378 handle->stream.conn.write_reqs_pending++;
1382 req->write_buffer = write_buf;
1384 if (
handle->stream.conn.write_reqs_pending == 0) {
1389 req->u.io.queued_bytes = write_buf.
len;
1390 handle->write_queue_size +=
req->u.io.queued_bytes;
1397 &
req->u.io.overlapped);
1399 if (!
result && GetLastError() != ERROR_IO_PENDING) {
1400 err = GetLastError();
1401 CloseHandle(
req->event_handle);
1402 req->event_handle = NULL;
1408 req->u.io.queued_bytes = 0;
1411 req->u.io.queued_bytes = write_buf.
len;
1412 handle->write_queue_size +=
req->u.io.queued_bytes;
1413 if (WaitForSingleObject(
req->event_handle, INFINITE) !=
1415 err = GetLastError();
1416 CloseHandle(
req->event_handle);
1417 req->event_handle = NULL;
1421 CloseHandle(
req->event_handle);
1422 req->event_handle = NULL;
1426 handle->stream.conn.write_reqs_pending++;
1433 &
req->u.io.overlapped);
1435 if (!
result && GetLastError() != ERROR_IO_PENDING) {
1436 return GetLastError();
1441 req->u.io.queued_bytes = 0;
1444 req->u.io.queued_bytes = write_buf.
len;
1445 handle->write_queue_size +=
req->u.io.queued_bytes;
1449 if (!RegisterWaitForSingleObject(&
req->wait_handle,
1451 INFINITE, WT_EXECUTEINWAITTHREAD)) {
1452 return GetLastError();
1459 handle->stream.conn.write_reqs_pending++;
1466 DWORD* pid = &
handle->pipe.conn.ipc_remote_pid;
1472 *pid = GetCurrentProcessId();
1482 size_t data_buf_count,
1487 size_t buf_count, buf_index;
1497 for (
i = 0;
i < data_buf_count;
i++)
1498 data_length += data_bufs[
i].
len;
1503 if (send_handle != NULL) {
1507 if (send_tcp_handle->type != UV_TCP)
1508 return ERROR_NOT_SUPPORTED;
1520 buf_count = 1 + data_buf_count;
1521 if (send_handle != NULL)
1533 return ERROR_NOT_ENOUGH_MEMORY;
1538 memset(&frame_header, 0,
sizeof frame_header);
1539 bufs[buf_index++] =
uv_buf_init((
char*) &frame_header,
sizeof frame_header);
1541 if (send_handle != NULL) {
1543 switch (xfer_type) {
1555 bufs[buf_index++] =
uv_buf_init((
char*) &xfer_info,
sizeof xfer_info);
1558 if (data_length > 0) {
1561 frame_header.data_length = (
uint32_t) data_length;
1563 for (
i = 0;
i < data_buf_count;
i++)
1564 bufs[buf_index++] = data_bufs[
i];
1572 if (
bufs != stack_bufs) {
1592 assert(send_handle == NULL);
1625 if (
error == ERROR_BROKEN_PIPE) {
1647 handle->pipe.conn.ipc_xfer_queue_length++;
1664 return GetLastError();
1677 DWORD suggested_bytes,
1685 if (
buf.base == NULL ||
buf.len == 0) {
1694 if (max_bytes >
buf.len)
1695 max_bytes =
buf.len;
1711 uint32_t* data_remaining = &
handle->pipe.conn.ipc_data_frame.payload_remaining;
1714 if (*data_remaining > 0) {
1730 handle->handle, &frame_header,
sizeof frame_header);
1748 }
else if (xfer_flags == 0) {
1767 return sizeof frame_header;
1778 return sizeof frame_header +
sizeof xfer_info;
1783 err = WSAECONNABORTED;
1794 assert(
handle->type == UV_NAMED_PIPE);
1813 if (
err != ERROR_OPERATION_ABORTED)
1823 if (!PeekNamedPipe(
handle->handle, NULL, 0, NULL, &avail, NULL))
1862 assert(
handle->type == UV_NAMED_PIPE);
1864 assert(
handle->write_queue_size >=
req->u.io.queued_bytes);
1865 handle->write_queue_size -=
req->u.io.queued_bytes;
1871 UnregisterWait(
req->wait_handle);
1874 if (
req->event_handle) {
1875 CloseHandle(
req->event_handle);
1876 req->event_handle = NULL;
1885 if (
req->coalesced) {
1895 handle->stream.conn.write_reqs_pending--;
1898 handle->pipe.conn.non_overlapped_writes_tail) {
1899 assert(
handle->stream.conn.write_reqs_pending > 0);
1903 if (
handle->stream.conn.shutdown_req != NULL &&
1904 handle->stream.conn.write_reqs_pending == 0) {
1914 uv_pipe_accept_t*
req = (uv_pipe_accept_t*) raw_req;
1916 assert(
handle->type == UV_NAMED_PIPE);
1927 req->next_pending =
handle->pipe.serv.pending_accepts;
1928 handle->pipe.serv.pending_accepts =
req;
1930 if (
handle->stream.serv.connection_cb) {
1935 CloseHandle(
req->pipeHandle);
1951 assert(
handle->type == UV_NAMED_PIPE);
1971 assert(
handle->type == UV_NAMED_PIPE);
2003 assert(pipe->pipe.conn.eof_timer == NULL);
2010 pipe->pipe.conn.eof_timer->data = pipe;
2018 if (pipe->pipe.conn.eof_timer != NULL) {
2027 if (pipe->pipe.conn.eof_timer != NULL) {
2037 assert(pipe->type == UV_NAMED_PIPE);
2050 HasOverlappedIoCompleted(&pipe->read_req.u.io.overlapped)) {
2070 if (pipe->pipe.conn.eof_timer) {
2072 pipe->pipe.conn.eof_timer = NULL;
2078 assert(
handle->type == UV_TIMER);
2088 DWORD duplex_flags = 0;
2107 DUPLICATE_SAME_ACCESS))
2125 if (!(
access.AccessFlags & FILE_WRITE_DATA) ||
2126 !(
access.AccessFlags & FILE_READ_DATA)) {
2131 if (
access.AccessFlags & FILE_WRITE_DATA)
2133 if (
access.AccessFlags & FILE_READ_DATA)
2141 duplex_flags) == -1) {
2150 assert(pipe->pipe.conn.ipc_remote_pid != (DWORD) -1);
2162 unsigned int addrlen;
2163 unsigned int name_size;
2164 unsigned int name_len;
2188 sizeof tmp_name_info,
2221 if (name_len == 0) {
2227 name_len /=
sizeof(WCHAR);
2230 addrlen = WideCharToMultiByte(CP_UTF8,
2250 addrlen = WideCharToMultiByte(CP_UTF8,
2281 return handle->pipe.conn.ipc_xfer_queue_length;
2314 if (
handle->pipe.conn.ipc_xfer_queue_length == 0)
2321 SID_IDENTIFIER_AUTHORITY sid_world = { SECURITY_WORLD_SID_AUTHORITY };
2322 PACL old_dacl, new_dacl;
2323 PSECURITY_DESCRIPTOR sd;
2336 if (!AllocateAndInitializeSid(&sid_world,
2339 0, 0, 0, 0, 0, 0, 0,
2341 error = GetLastError();
2345 if (GetSecurityInfo(
handle->handle,
2347 DACL_SECURITY_INFORMATION,
2353 error = GetLastError();
2357 memset(&ea, 0,
sizeof(EXPLICIT_ACCESS));
2359 ea.grfAccessPermissions |= GENERIC_READ | FILE_WRITE_ATTRIBUTES;
2361 ea.grfAccessPermissions |= GENERIC_WRITE | FILE_READ_ATTRIBUTES;
2362 ea.grfAccessPermissions |= SYNCHRONIZE;
2363 ea.grfAccessMode = SET_ACCESS;
2364 ea.grfInheritance = NO_INHERITANCE;
2365 ea.Trustee.TrusteeForm = TRUSTEE_IS_SID;
2366 ea.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
2367 ea.Trustee.ptstrName = (LPTSTR)everyone;
2369 if (SetEntriesInAcl(1, &ea, old_dacl, &new_dacl)) {
2370 error = GetLastError();
2374 if (SetSecurityInfo(
handle->handle,
2376 DACL_SECURITY_INFORMATION,
2381 error = GetLastError();
2388 LocalFree((HLOCAL) new_dacl);
2390 LocalFree((HLOCAL) sd);