2 ===================================================================
3 --- rpc_server.c (working copy)
4 +++ rpc_server.c (working copy)
5 @@ -1017,22 +1017,30 @@
6 /***********************************************************************
7 * RpcMgmtServerWaitListen (RPCRT4.@)
9 RPC_STATUS WINAPI RpcMgmtWaitServerListen( void )
12 + RpcServerProtseq *cps;
14 EnterCriticalSection(&listen_cs);
17 LeaveCriticalSection(&listen_cs);
18 return RPC_S_NOT_LISTENING;
23 LeaveCriticalSection(&listen_cs);
25 - FIXME("not waiting for server calls to finish\n");
26 + LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry)
27 + WaitForSingleObject(cps->server_ready_event, INFINITE);
29 + EnterCriticalSection(&listen_cs);
30 + } while (!std_listen);
32 + LeaveCriticalSection(&listen_cs);
37 /***********************************************************************
38 Index: rpc_transport.c
39 ===================================================================
40 --- rpc_transport.c (working copy)
41 +++ rpc_transport.c (working copy)
44 #ifdef HAVE_SYS_POLL_H
48 +#include <winsock2.h>
49 +#include <ws2tcpip.h>
57 #include "rpc_binding.h"
58 #include "rpc_message.h"
59 #include "rpc_server.h"
60 #include "epm_towers.h"
62 +#include "unix_func.h"
65 # define SOL_TCP IPPROTO_TCP
68 WINE_DEFAULT_DEBUG_CHANNEL(rpc);
71 typedef struct _RpcConnection_np
80 static RpcConnection *rpcrt4_conn_np_alloc(void)
87 npc->listening = TRUE;
88 - if (ConnectNamedPipe(npc->pipe, &npc->ovl))
89 + if (ConnectNamedPipe(npc->pipe, &npc->ovl[0]))
92 if (GetLastError() == ERROR_PIPE_CONNECTED) {
93 - SetEvent(npc->ovl.hEvent);
94 + SetEvent(npc->ovl[0].hEvent);
97 if (GetLastError() == ERROR_IO_PENDING) {
98 /* will be completed in rpcrt4_protseq_np_wait_for_new_connection */
100 @@ -126,11 +131,11 @@
101 static RPC_STATUS rpcrt4_conn_create_pipe(RpcConnection *Connection, LPCSTR pname)
103 RpcConnection_np *npc = (RpcConnection_np *) Connection;
104 TRACE("listening on %s\n", pname);
106 - npc->pipe = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX,
107 + npc->pipe = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED,
108 PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
109 PIPE_UNLIMITED_INSTANCES,
110 RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL);
111 if (npc->pipe == INVALID_HANDLE_VALUE) {
112 WARN("CreateNamedPipe failed with error %d\n", GetLastError());
113 @@ -139,11 +144,12 @@
115 return RPC_S_CANT_CREATE_ENDPOINT;
118 memset(&npc->ovl, 0, sizeof(npc->ovl));
119 - npc->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
120 + npc->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
121 + npc->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
123 /* Note: we don't call ConnectNamedPipe here because it must be done in the
124 * server thread as the thread must be alertable */
127 @@ -202,11 +208,13 @@
129 memset(&npc->ovl, 0, sizeof(npc->ovl));
130 /* pipe is connected; change to message-read mode. */
131 dwMode = PIPE_READMODE_MESSAGE;
132 SetNamedPipeHandleState(pipe, &dwMode, NULL, NULL);
133 - npc->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
134 + npc->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
135 + npc->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL);
142 @@ -308,11 +316,12 @@
144 /* because of the way named pipes work, we'll transfer the connected pipe
145 * to the child, then reopen the server binding to continue listening */
147 new_npc->pipe = old_npc->pipe;
148 - new_npc->ovl = old_npc->ovl;
149 + new_npc->ovl[0] = old_npc->ovl[0];
150 + new_npc->ovl[1] = old_npc->ovl[1];
152 memset(&old_npc->ovl, 0, sizeof(old_npc->ovl));
153 old_npc->listening = FALSE;
156 @@ -359,13 +368,18 @@
157 unsigned int bytes_left = count;
162 - ret = ReadFile(npc->pipe, buf, bytes_left, &bytes_read, NULL);
163 - if (!ret || !bytes_read)
164 + ret = ReadFile(npc->pipe, buf, bytes_left, &bytes_read, &npc->ovl[0]);
165 + if ((!ret || !bytes_read) && (GetLastError() != ERROR_IO_PENDING))
168 + ret = GetOverlappedResult(npc->pipe, &npc->ovl[0], &bytes_read, TRUE);
169 + if (!ret && GetLastError() != ERROR_MORE_DATA)
172 bytes_left -= bytes_read;
175 return ret ? count : -1;
177 @@ -379,13 +393,18 @@
178 unsigned int bytes_left = count;
183 - ret = WriteFile(npc->pipe, buf, count, &bytes_written, NULL);
184 - if (!ret || !bytes_written)
185 + ret = WriteFile(npc->pipe, buf, count, &bytes_written, &npc->ovl[1]);
186 + if ((!ret || !bytes_written) && (GetLastError() != ERROR_IO_PENDING))
189 + ret = GetOverlappedResult(npc->pipe, &npc->ovl[1], &bytes_written, TRUE);
190 + if (!ret && GetLastError() != ERROR_MORE_DATA)
193 bytes_left -= bytes_written;
194 buf += bytes_written;
196 return ret ? count : -1;
198 @@ -396,14 +415,19 @@
200 FlushFileBuffers(npc->pipe);
201 CloseHandle(npc->pipe);
204 - if (npc->ovl.hEvent) {
205 - CloseHandle(npc->ovl.hEvent);
206 - npc->ovl.hEvent = 0;
207 + if (npc->ovl[0].hEvent) {
208 + CloseHandle(npc->ovl[0].hEvent);
209 + npc->ovl[0].hEvent = 0;
211 + if (npc->ovl[1].hEvent) {
212 + CloseHandle(npc->ovl[1].hEvent);
213 + npc->ovl[1].hEvent = 0;
219 static void rpcrt4_conn_np_cancel_call(RpcConnection *Connection)
221 @@ -547,11 +571,11 @@
222 /* open and count connections */
224 conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common);
226 rpcrt4_conn_listen_pipe(conn);
227 - if (conn->ovl.hEvent)
228 + if (conn->ovl[0].hEvent)
230 conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common);
233 /* make array of connections */
234 @@ -568,11 +592,11 @@
236 objs[0] = npps->mgr_event;
238 conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common);
240 - if ((objs[*count] = conn->ovl.hEvent))
241 + if ((objs[*count] = conn->ovl[0].hEvent))
243 conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common);
245 LeaveCriticalSection(&protseq->cs);
247 @@ -615,11 +639,11 @@
248 b_handle = objs[res - WAIT_OBJECT_0];
249 /* find which connection got a RPC */
250 EnterCriticalSection(&protseq->cs);
251 conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common);
253 - if (b_handle == conn->ovl.hEvent) break;
254 + if (b_handle == conn->ovl[0].hEvent) break;
255 conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common);
259 RPCRT4_SpawnConnection(&cconn, &conn->common);
260 @@ -713,16 +737,18 @@
261 RpcConnection_tcp *tcpc;
262 tcpc = HeapAlloc(GetProcessHeap(), 0, sizeof(RpcConnection_tcp));
267 if (socketpair(PF_UNIX, SOCK_STREAM, 0, tcpc->cancel_fds) < 0)
269 ERR("socketpair() failed: %s\n", strerror(errno));
270 HeapFree(GetProcessHeap(), 0, tcpc);
274 return &tcpc->common;
277 static RPC_STATUS rpcrt4_ncacn_ip_tcp_open(RpcConnection* Connection)
279 @@ -783,12 +809,11 @@
283 /* RPC depends on having minimal latency so disable the Nagle algorithm */
285 - setsockopt(sock, SOL_TCP, TCP_NODELAY, &val, sizeof(val));
286 - fcntl(sock, F_SETFL, O_NONBLOCK); /* make socket nonblocking */
287 + setsockopt(sock, SOL_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
292 TRACE("connected\n");
293 @@ -806,10 +831,11 @@
297 struct addrinfo *ai_cur;
298 struct addrinfo hints;
300 RpcConnection *first_connection = NULL;
302 TRACE("(%p, %s)\n", protseq, endpoint);
304 hints.ai_flags = AI_PASSIVE /* for non-localhost addresses */;
305 @@ -857,11 +883,11 @@
306 ret = bind(sock, ai_cur->ai_addr, ai_cur->ai_addrlen);
309 WARN("bind failed: %s\n", strerror(errno));
311 - if (errno == EADDRINUSE)
312 + if (errno == WSAEADDRINUSE)
313 status = RPC_S_DUPLICATE_ENDPOINT;
315 status = RPC_S_CANT_CREATE_ENDPOINT;
318 @@ -886,11 +912,12 @@
320 /* need a non-blocking socket, otherwise accept() has a potential
321 * race-condition (poll() says it is readable, connection drops,
322 * and accept() blocks until the next connection comes...)
324 - ret = fcntl(sock, F_SETFL, O_NONBLOCK);
326 + ret = ioctlsocket(sock, FIONBIO, &blocking);
329 WARN("couldn't make socket non-blocking, error %d\n", ret);
330 RPCRT4_DestroyConnection(&tcpc->common);
331 status = RPC_S_OUT_OF_RESOURCES;
332 @@ -929,10 +956,11 @@
333 static RPC_STATUS rpcrt4_conn_tcp_handoff(RpcConnection *old_conn, RpcConnection *new_conn)
336 struct sockaddr_in address;
339 RpcConnection_tcp *server = (RpcConnection_tcp*) old_conn;
340 RpcConnection_tcp *client = (RpcConnection_tcp*) new_conn;
342 addrsize = sizeof(address);
343 ret = accept(server->sock, (struct sockaddr*) &address, &addrsize);
344 @@ -940,11 +968,12 @@
346 ERR("Failed to accept a TCP connection: error %d\n", ret);
347 return RPC_S_OUT_OF_RESOURCES;
349 /* reset to blocking behaviour */
350 - fcntl(ret, F_SETFL, 0);
352 + ret = ioctlsocket(ret, FIONBIO, &blocking);
354 TRACE("Accepted a new TCP connection\n");
358 @@ -1187,14 +1216,16 @@
360 RpcServerProtseq_sock *ps = HeapAlloc(GetProcessHeap(), 0, sizeof(*ps));
365 if (!socketpair(PF_UNIX, SOCK_DGRAM, 0, fds))
367 - fcntl(fds[0], F_SETFL, O_NONBLOCK);
368 - fcntl(fds[1], F_SETFL, O_NONBLOCK);
370 + ioctlsocket(fds[0], FIONBIO, &blocking);
371 + ioctlsocket(fds[1], FIONBIO, &blocking);
372 ps->mgr_event_rcv = fds[0];
373 ps->mgr_event_snd = fds[1];