Index: epm_towers.h =================================================================== --- epm_towers.h (working copy) +++ epm_towers.h (working copy) @@ -17,11 +17,11 @@ * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * */ -#include "epm.h" +#include "epm_c.h" #define EPM_PROTOCOL_DNET_NSP 0x04 #define EPM_PROTOCOL_OSI_TP4 0x05 #define EPM_PROTOCOL_OSI_CLNS 0x06 #define EPM_PROTOCOL_TCP 0x07 Index: ndr_marshall.c =================================================================== --- ndr_marshall.c (working copy) +++ ndr_marshall.c (working copy) @@ -6032,6 +6032,7 @@ case RPC_FC_WCHAR: case RPC_FC_SHORT: case RPC_FC_USHORT: + case RPC_FC_ENUM16: { USHORT d; ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); Index: rpc_epmap.c =================================================================== --- rpc_epmap.c (working copy) +++ rpc_epmap.c (working copy) @@ -30,11 +30,11 @@ #include "wine/debug.h" #include "wine/exception.h" #include "rpc_binding.h" -#include "epm.h" +#include "epm_c.h" #include "epm_towers.h" WINE_DEFAULT_DEBUG_CHANNEL(ole); /* The "real" RPC portmapper endpoints that I know of are: Index: rpc_server.c =================================================================== --- rpc_server.c (working copy) +++ rpc_server.c (working copy) @@ -1040,22 +1040,28 @@ /*********************************************************************** * RpcMgmtServerWaitListen (RPCRT4.@) */ RPC_STATUS WINAPI RpcMgmtWaitServerListen( void ) { - TRACE("()\n"); + RpcServerProtseq *cps; EnterCriticalSection(&listen_cs); if (!std_listen) { LeaveCriticalSection(&listen_cs); return RPC_S_NOT_LISTENING; } + do { LeaveCriticalSection(&listen_cs); + LIST_FOR_EACH_ENTRY(cps, &protseqs, RpcServerProtseq, entry) + WaitForSingleObject(cps->server_ready_event, INFINITE); - FIXME("not waiting for server calls to finish\n"); + EnterCriticalSection(&listen_cs); + } while (!std_listen); + + LeaveCriticalSection(&listen_cs); return RPC_S_OK; } /*********************************************************************** Index: rpc_transport.c =================================================================== --- rpc_transport.c (working copy) +++ rpc_transport.c (working copy) @@ -65,10 +65,13 @@ # include # endif # define closesocket close #endif /* defined(__MINGW32__) || defined (_MSC_VER) */ +#include +#include + #include "windef.h" #include "winbase.h" #include "winnls.h" #include "winerror.h" #include "winternl.h" @@ -82,10 +85,12 @@ #include "rpc_binding.h" #include "rpc_message.h" #include "rpc_server.h" #include "epm_towers.h" +#include "unix_func.h" + #ifndef SOL_TCP # define SOL_TCP IPPROTO_TCP #endif WINE_DEFAULT_DEBUG_CHANNEL(rpc); @@ -94,11 +99,11 @@ typedef struct _RpcConnection_np { RpcConnection common; HANDLE pipe; - OVERLAPPED ovl; + OVERLAPPED ovl[2]; BOOL listening; } RpcConnection_np; static RpcConnection *rpcrt4_conn_np_alloc(void) { @@ -118,17 +123,17 @@ return RPC_S_OK; npc->listening = TRUE; for (;;) { - if (ConnectNamedPipe(npc->pipe, &npc->ovl)) + if (ConnectNamedPipe(npc->pipe, &npc->ovl[0])) return RPC_S_OK; switch(GetLastError()) { case ERROR_PIPE_CONNECTED: - SetEvent(npc->ovl.hEvent); + SetEvent(npc->ovl[0].hEvent); return RPC_S_OK; case ERROR_IO_PENDING: /* will be completed in rpcrt4_protseq_np_wait_for_new_connection */ return RPC_S_OK; case ERROR_NO_DATA_DETECTED: @@ -146,11 +151,11 @@ static RPC_STATUS rpcrt4_conn_create_pipe(RpcConnection *Connection, LPCSTR pname) { RpcConnection_np *npc = (RpcConnection_np *) Connection; TRACE("listening on %s\n", pname); - npc->pipe = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX, + npc->pipe = CreateNamedPipeA(pname, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, PIPE_UNLIMITED_INSTANCES, RPC_MAX_PACKET_SIZE, RPC_MAX_PACKET_SIZE, 5000, NULL); if (npc->pipe == INVALID_HANDLE_VALUE) { WARN("CreateNamedPipe failed with error %d\n", GetLastError()); @@ -159,11 +164,12 @@ else return RPC_S_CANT_CREATE_ENDPOINT; } memset(&npc->ovl, 0, sizeof(npc->ovl)); - npc->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + npc->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + npc->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); /* Note: we don't call ConnectNamedPipe here because it must be done in the * server thread as the thread must be alertable */ return RPC_S_OK; } @@ -220,11 +226,12 @@ /* success */ memset(&npc->ovl, 0, sizeof(npc->ovl)); /* pipe is connected; change to message-read mode. */ dwMode = PIPE_READMODE_MESSAGE; SetNamedPipeHandleState(pipe, &dwMode, NULL, NULL); - npc->ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + npc->ovl[0].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); + npc->ovl[1].hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); npc->pipe = pipe; return RPC_S_OK; } @@ -326,11 +333,12 @@ { /* because of the way named pipes work, we'll transfer the connected pipe * to the child, then reopen the server binding to continue listening */ new_npc->pipe = old_npc->pipe; - new_npc->ovl = old_npc->ovl; + new_npc->ovl[0] = old_npc->ovl[0]; + new_npc->ovl[1] = old_npc->ovl[1]; old_npc->pipe = 0; memset(&old_npc->ovl, 0, sizeof(old_npc->ovl)); old_npc->listening = FALSE; } @@ -377,13 +385,18 @@ unsigned int bytes_left = count; while (bytes_left) { DWORD bytes_read; - ret = ReadFile(npc->pipe, buf, bytes_left, &bytes_read, NULL); - if (!ret || !bytes_read) + ret = ReadFile(npc->pipe, buf, bytes_left, &bytes_read, &npc->ovl[0]); + if ((!ret || !bytes_read) && (GetLastError() != ERROR_IO_PENDING)) + break; + + ret = GetOverlappedResult(npc->pipe, &npc->ovl[0], &bytes_read, TRUE); + if (!ret && (GetLastError() != ERROR_MORE_DATA)) break; + bytes_left -= bytes_read; buf += bytes_read; } return ret ? count : -1; } @@ -397,13 +410,18 @@ unsigned int bytes_left = count; while (bytes_left) { DWORD bytes_written; - ret = WriteFile(npc->pipe, buf, bytes_left, &bytes_written, NULL); - if (!ret || !bytes_written) + ret = WriteFile(npc->pipe, buf, bytes_left, &bytes_written, &npc->ovl[1]); + if ((!ret || !bytes_written) && (GetLastError() != ERROR_IO_PENDING)) + break; + + ret = GetOverlappedResult(npc->pipe, &npc->ovl[1], &bytes_written, TRUE); + if (!ret && (GetLastError() != ERROR_MORE_DATA)) break; + bytes_left -= bytes_written; buf += bytes_written; } return ret ? count : -1; } @@ -414,13 +432,17 @@ if (npc->pipe) { FlushFileBuffers(npc->pipe); CloseHandle(npc->pipe); npc->pipe = 0; } - if (npc->ovl.hEvent) { - CloseHandle(npc->ovl.hEvent); - npc->ovl.hEvent = 0; + if (npc->ovl[0].hEvent) { + CloseHandle(npc->ovl[0].hEvent); + npc->ovl[0].hEvent = 0; + } + if (npc->ovl[1].hEvent) { + CloseHandle(npc->ovl[1].hEvent); + npc->ovl[1].hEvent = 0; } return 0; } static void rpcrt4_conn_np_cancel_call(RpcConnection *Connection) @@ -579,11 +601,11 @@ /* open and count connections */ *count = 1; conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common); while (conn) { rpcrt4_conn_listen_pipe(conn); - if (conn->ovl.hEvent) + if (conn->ovl[0].hEvent) (*count)++; conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common); } /* make array of connections */ @@ -600,11 +622,11 @@ objs[0] = npps->mgr_event; *count = 1; conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common); while (conn) { - if ((objs[*count] = conn->ovl.hEvent)) + if ((objs[*count] = conn->ovl[0].hEvent)) (*count)++; conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common); } LeaveCriticalSection(&protseq->cs); return objs; @@ -647,11 +669,11 @@ b_handle = objs[res - WAIT_OBJECT_0]; /* find which connection got a RPC */ EnterCriticalSection(&protseq->cs); conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common); while (conn) { - if (b_handle == conn->ovl.hEvent) break; + if (b_handle == conn->ovl[0].hEvent) break; conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common); } cconn = NULL; if (conn) RPCRT4_SpawnConnection(&cconn, &conn->common);