diff -pudN e:\wine\dlls\rpcrt4/cproxy.c e:\reactos\dll\win32\rpcrt4/cproxy.c --- e:\wine\dlls\rpcrt4/cproxy.c 2016-11-16 17:29:34 +0100 +++ e:\reactos\dll\win32\rpcrt4/cproxy.c 2015-08-27 22:03:34 +0100 @@ -150,6 +150,30 @@ static inline void init_thunk( struct th thunk->call_stubless = call_stubless_func; } +#elif defined(__arm__) + +extern void call_stubless_func(void); +__ASM_GLOBAL_FUNC(call_stubless_func, + "DCD 0xDEFC\n\t" // _assertfail + "" ); + +#include "pshpack1.h" +struct thunk +{ + DWORD assertfail; +}; +#include "poppack.h" + +static const struct thunk thunk_template = +{ + { 0xDEFC } /* _assertfail */ +}; + +static inline void init_thunk( struct thunk *thunk, unsigned int index ) +{ + *thunk = thunk_template; +} + #else /* __i386__ */ #warning You must implement stubless proxies for your CPU diff -pudN e:\wine\dlls\rpcrt4/cstub.c e:\reactos\dll\win32\rpcrt4/cstub.c --- e:\wine\dlls\rpcrt4/cstub.c 2016-11-16 17:29:34 +0100 +++ e:\reactos\dll\win32\rpcrt4/cstub.c 2016-05-20 23:26:31 +0100 @@ -156,6 +156,13 @@ typedef struct static const BYTE opcodes[16] = { 0x48, 0x8b, 0x49, 0x20, 0x48, 0x8b, 0x01, 0xff, 0xa0, 0, 0, 0, 0, 0x48, 0x8d, 0x36 }; +#elif defined(__arm__) +typedef struct +{ + DWORD offset; +} vtbl_method_t; +static const BYTE opcodes[1]; + #else #warning You must implement delegated proxies/stubs for your CPU diff -pudN e:\wine\dlls\rpcrt4/rpc_epmap.c e:\reactos\dll\win32\rpcrt4/rpc_epmap.c --- e:\wine\dlls\rpcrt4/rpc_epmap.c 2016-11-16 17:29:34 +0100 +++ e:\reactos\dll\win32\rpcrt4/rpc_epmap.c 2016-11-17 12:09:06 +0100 @@ -171,7 +173,7 @@ static RPC_STATUS get_epm_handle_server( static LONG WINAPI rpc_filter(EXCEPTION_POINTERS *__eptr) { - switch (GetExceptionCode()) + switch (__eptr->ExceptionRecord->ExceptionCode) { case EXCEPTION_ACCESS_VIOLATION: case EXCEPTION_ILLEGAL_INSTRUCTION: diff -pudN e:\wine\dlls\rpcrt4/rpc_transport.c e:\reactos\dll\win32\rpcrt4/rpc_transport.c --- e:\wine\dlls\rpcrt4/rpc_transport.c 2016-11-16 17:33:13 +0100 +++ e:\reactos\dll\win32\rpcrt4/rpc_transport.c 2016-11-17 00:00:46 +0100 @@ -82,6 +79,7 @@ #define DEFAULT_NCACN_HTTP_TIMEOUT (60 * 1000) +#undef ARRAYSIZE #define ARRAYSIZE(a) (sizeof((a)) / sizeof((a)[0])) WINE_DEFAULT_DEBUG_CHANNEL(rpc); @@ -94,31 +92,41 @@ typedef struct _RpcConnection_np { RpcConnection common; HANDLE pipe; - HANDLE listen_thread; + OVERLAPPED ovl; BOOL listening; } RpcConnection_np; static RpcConnection *rpcrt4_conn_np_alloc(void) { RpcConnection_np *npc = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcConnection_np)); + if (npc) + { + npc->pipe = NULL; + memset(&npc->ovl, 0, sizeof(npc->ovl)); + npc->listening = FALSE; + } return &npc->common; } -static DWORD CALLBACK listen_thread(void *arg) +static RPC_STATUS rpcrt4_conn_listen_pipe(RpcConnection_np *npc) { - RpcConnection_np *npc = arg; + if (npc->listening) + return RPC_S_OK; + + npc->listening = TRUE; for (;;) { - if (ConnectNamedPipe(npc->pipe, NULL)) + if (ConnectNamedPipe(npc->pipe, &npc->ovl)) return RPC_S_OK; switch(GetLastError()) { case ERROR_PIPE_CONNECTED: + SetEvent(npc->ovl.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_HANDLES_CLOSED: - /* connection closed during listen */ - return RPC_S_NO_CONTEXT_AVAILABLE; case ERROR_NO_DATA_DETECTED: /* client has disconnected, retry */ DisconnectNamedPipe( npc->pipe ); @@ -131,6 +139,7 @@ static DWORD CALLBACK listen_thread(void } } +#ifndef __REACTOS__ static RPC_STATUS rpcrt4_conn_listen_pipe(RpcConnection_np *npc) { if (npc->listening) @@ -146,13 +155,14 @@ static RPC_STATUS rpcrt4_conn_listen_pip } return RPC_S_OK; } +#endif 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); @@ -164,6 +174,9 @@ static RPC_STATUS rpcrt4_conn_create_pip return RPC_S_CANT_CREATE_ENDPOINT; } + memset(&npc->ovl, 0, sizeof(npc->ovl)); + npc->ovl.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; @@ -210,6 +223,9 @@ static RPC_STATUS rpcrt4_conn_open_pipe( if (err == ERROR_PIPE_BUSY) { TRACE("connection failed, error=%x\n", err); return RPC_S_SERVER_TOO_BUSY; + } else if (err == ERROR_BAD_NETPATH) { + TRACE("connection failed, error=%x\n", err); + return RPC_S_SERVER_UNAVAILABLE; } if (!wait || !WaitNamedPipeA(pname, NMPWAIT_WAIT_FOREVER)) { err = GetLastError(); @@ -219,9 +235,11 @@ static RPC_STATUS rpcrt4_conn_open_pipe( } /* 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->pipe = pipe; return RPC_S_OK; @@ -304,15 +322,64 @@ static char *ncacn_pipe_name(const char static RPC_STATUS rpcrt4_ncacn_np_open(RpcConnection* Connection) { RpcConnection_np *npc = (RpcConnection_np *) Connection; + static const char prefix[] = "\\\\"; + static const char local[] = "."; + BOOL bUseLocalName = TRUE; + CHAR ComputerName[MAX_COMPUTERNAME_LENGTH + 1]; + DWORD bufLen = sizeof(ComputerName)/sizeof(ComputerName[0]); RPC_STATUS r; LPSTR pname; + LPSTR NetworkAddr; + INT size; /* already connected? */ if (npc->pipe) return RPC_S_OK; - pname = ncacn_pipe_name(Connection->Endpoint); - r = rpcrt4_conn_open_pipe(Connection, pname, FALSE); + /* protseq=ncacn_np: named pipes */ + size = strlen(prefix); + + if (Connection->NetworkAddr == NULL || strlen(Connection->NetworkAddr) == 0) + { + bUseLocalName = TRUE; + size += strlen(local); + } + else + { + NetworkAddr = Connection->NetworkAddr; + if (NetworkAddr[0] == '\\' && NetworkAddr[1] == '\\') + NetworkAddr += 2; + + if (GetComputerNameA(ComputerName, &bufLen)) + { + if (stricmp(ComputerName, NetworkAddr) == 0) + { + bUseLocalName = TRUE; + size += strlen(local); + } + else + { + bUseLocalName = FALSE; + size += strlen(NetworkAddr); + } + } + else + { + bUseLocalName = FALSE; + size += strlen(NetworkAddr); + } + } + + size += strlen(Connection->Endpoint) + 1; + + pname = I_RpcAllocate(size); + strcpy(pname, prefix); + if (bUseLocalName) + strcat(pname, local); + else + strcat(pname, NetworkAddr); + strcat(pname, Connection->Endpoint); + r = rpcrt4_conn_open_pipe(Connection, pname, TRUE); I_RpcFree(pname); return r; @@ -358,9 +425,9 @@ static void rpcrt4_conn_np_handoff(RpcCo * to the child, then reopen the server binding to continue listening */ new_npc->pipe = old_npc->pipe; - new_npc->listen_thread = old_npc->listen_thread; + new_npc->ovl = old_npc->ovl; old_npc->pipe = 0; - old_npc->listen_thread = 0; + memset(&old_npc->ovl, 0, sizeof(old_npc->ovl)); old_npc->listening = FALSE; } @@ -444,20 +511,29 @@ static int rpcrt4_conn_np_read(RpcConnec void *buffer, unsigned int count) { RpcConnection_np *npc = (RpcConnection_np *) Connection; - IO_STATUS_BLOCK io_status; char *buf = buffer; + BOOL ret = TRUE; unsigned int bytes_left = count; - NTSTATUS status; + OVERLAPPED ovl; + + ZeroMemory(&ovl, sizeof(ovl)); + ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); while (bytes_left) { - status = NtReadFile(npc->pipe, NULL, NULL, NULL, &io_status, buf, bytes_left, NULL, NULL); - if (status && status != STATUS_BUFFER_OVERFLOW) - return -1; - bytes_left -= io_status.Information; - buf += io_status.Information; + DWORD bytes_read; + ret = ReadFile(npc->pipe, buf, bytes_left, &bytes_read, &ovl); + if (!ret && GetLastError() == ERROR_IO_PENDING) + ret = GetOverlappedResult(npc->pipe, &ovl, &bytes_read, TRUE); + if (!ret && GetLastError() == ERROR_MORE_DATA) + ret = TRUE; + if (!ret || !bytes_read) + break; + bytes_left -= bytes_read; + buf += bytes_read; } - return count; + CloseHandle(ovl.hEvent); + return ret ? count : -1; } static int rpcrt4_conn_np_write(RpcConnection *Connection, @@ -467,16 +543,23 @@ static int rpcrt4_conn_np_write(RpcConne const char *buf = buffer; BOOL ret = TRUE; unsigned int bytes_left = count; + OVERLAPPED ovl; + + ZeroMemory(&ovl, sizeof(ovl)); + ovl.hEvent = CreateEventW(NULL, TRUE, FALSE, NULL); while (bytes_left) { DWORD bytes_written; - ret = WriteFile(npc->pipe, buf, bytes_left, &bytes_written, NULL); + ret = WriteFile(npc->pipe, buf, bytes_left, &bytes_written, &ovl); + if (!ret && GetLastError() == ERROR_IO_PENDING) + ret = GetOverlappedResult(npc->pipe, &ovl, &bytes_written, TRUE); if (!ret || !bytes_written) break; bytes_left -= bytes_written; buf += bytes_written; } + CloseHandle(ovl.hEvent); return ret ? count : -1; } @@ -488,9 +571,9 @@ static int rpcrt4_conn_np_close(RpcConne CloseHandle(npc->pipe); npc->pipe = 0; } - if (npc->listen_thread) { - CloseHandle(npc->listen_thread); - npc->listen_thread = 0; + if (npc->ovl.hEvent) { + CloseHandle(npc->ovl.hEvent); + npc->ovl.hEvent = 0; } return 0; } @@ -694,7 +777,7 @@ static void *rpcrt4_protseq_np_get_wait_ conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common); while (conn) { rpcrt4_conn_listen_pipe(conn); - if (conn->listen_thread) + if (conn->ovl.hEvent) (*count)++; conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common); } @@ -715,7 +798,7 @@ static void *rpcrt4_protseq_np_get_wait_ *count = 1; conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common); while (conn) { - if ((objs[*count] = conn->listen_thread)) + if ((objs[*count] = conn->ovl.hEvent)) (*count)++; conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common); } @@ -762,18 +845,12 @@ static int rpcrt4_protseq_np_wait_for_ne EnterCriticalSection(&protseq->cs); conn = CONTAINING_RECORD(protseq->conn, RpcConnection_np, common); while (conn) { - if (b_handle == conn->listen_thread) break; + if (b_handle == conn->ovl.hEvent) break; conn = CONTAINING_RECORD(conn->common.Next, RpcConnection_np, common); } cconn = NULL; if (conn) - { - DWORD exit_code; - if (GetExitCodeThread(conn->listen_thread, &exit_code) && exit_code == RPC_S_OK) - RPCRT4_SpawnConnection(&cconn, &conn->common); - CloseHandle(conn->listen_thread); - conn->listen_thread = 0; - } + RPCRT4_SpawnConnection(&cconn, &conn->common); else ERR("failed to locate connection for handle %p\n", b_handle); LeaveCriticalSection(&protseq->cs);