diff --git a/dlls/rpcrt4/ndr_marshall.c b/dlls/rpcrt4/ndr_marshall.c index 7614f23f342..e14ebe968db 100644 --- a/dlls/rpcrt4/ndr_marshall.c +++ b/dlls/rpcrt4/ndr_marshall.c @@ -67,10 +67,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); * NdrConformantString: * * What MS calls a ConformantString is, in DCE terminology, - * a Varying Conformant String. + * a Varying-Conformant String. * [ * maxlen: DWORD (max # of CHARTYPE characters, inclusive of '\0') - * offset: DWORD (actual elements begin at (offset) CHARTYPE's into (data)) + * offset: DWORD (actual string data begins at (offset) CHARTYPE's + * into unmarshalled string) * length: DWORD (# of CHARTYPE characters, inclusive of '\0') * [ * data: CHARTYPE[maxlen] @@ -199,7 +200,7 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg len = LITTLE_ENDIAN_UINT32_READ(pStubMsg->Buffer); pStubMsg->Buffer += 4; - pStubMsg->Buffer += ofs; + c += ofs; /* presumably this will always be zero, otherwise the string is no good */ while ((*c++ = *(pStubMsg->Buffer++)) != '\0') ; diff --git a/dlls/rpcrt4/rpc_binding.c b/dlls/rpcrt4/rpc_binding.c index 3d6f2b43899..1972e4f3591 100644 --- a/dlls/rpcrt4/rpc_binding.c +++ b/dlls/rpcrt4/rpc_binding.c @@ -865,14 +865,21 @@ RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, LPWSTR * Exists in win9x and winNT, but with different number of arguments * (9x version has 3 arguments, NT has 2). */ +#ifdef WINNT +RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn) +#else RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn, unsigned long ServerTid ) +#endif { RpcBinding* bind = (RpcBinding*)Binding; TRACE( "(%p,%p,%ld): stub\n", Binding, BlockingFn, ServerTid ); bind->BlockingFn = BlockingFn; + + #ifndef WINNT bind->ServerTid = ServerTid; + #endif return RPC_S_OK; } diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c index 0574b9411fb..d3b4a698407 100644 --- a/dlls/rpcrt4/rpc_server.c +++ b/dlls/rpcrt4/rpc_server.c @@ -23,6 +23,7 @@ #include #include +#include #include "windef.h" #include "winbase.h" @@ -42,6 +43,7 @@ static RpcServerProtseq* protseqs; static RpcServerInterface* ifs; static CRITICAL_SECTION server_cs = CRITICAL_SECTION_INIT("RpcServer"); +static CRITICAL_SECTION listen_cs = CRITICAL_SECTION_INIT("RpcListen"); static BOOL std_listen; static LONG listen_count = -1; static HANDLE mgr_event, server_thread; @@ -95,7 +97,7 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) } #endif if (dwRead != sizeof(hdr)) { - TRACE("protocol error\n"); + if (dwRead) TRACE("protocol error: \n", sizeof(hdr), dwRead); break; } @@ -118,7 +120,7 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) } #endif if (dwRead != hdr.len) { - TRACE("protocol error\n"); + TRACE("protocol error: \n", hdr.len, dwRead); break; } @@ -231,7 +233,8 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg) /* start waiting */ res = WaitForMultipleObjects(count, objs, FALSE, INFINITE); if (res == WAIT_OBJECT_0) { - if (listen_count == -1) break; + ResetEvent(m_event); + if (!std_listen) break; } else if (res == WAIT_FAILED) { ERR("wait failed\n"); @@ -279,24 +282,33 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg) static void RPCRT4_start_listen(void) { TRACE("\n"); - if (!InterlockedIncrement(&listen_count)) { - mgr_event = CreateEventA(NULL, FALSE, FALSE, NULL); - server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, NULL, 0, NULL); - } - else SetEvent(mgr_event); -} -/* not used (WTF?) --------------------------- + EnterCriticalSection(&listen_cs); + if (! ++listen_count) { + if (!mgr_event) mgr_event = CreateEventA(NULL, TRUE, FALSE, NULL); + std_listen = TRUE; + server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, NULL, 0, NULL); + LeaveCriticalSection(&listen_cs); + } else { + LeaveCriticalSection(&listen_cs); + SetEvent(mgr_event); + } +} static void RPCRT4_stop_listen(void) { - HANDLE m_event = mgr_event; - if (InterlockedDecrement(&listen_count) < 0) - SetEvent(m_event); + EnterCriticalSection(&listen_cs); + if (listen_count == -1) + LeaveCriticalSection(&listen_cs); + else if (--listen_count == -1) { + std_listen = FALSE; + LeaveCriticalSection(&listen_cs); + SetEvent(mgr_event); + } else + LeaveCriticalSection(&listen_cs); + assert(listen_count > -2); } ---------------------- */ - static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps) { RPCRT4_CreateBindingA(&ps->bind, TRUE, ps->Protseq); @@ -307,7 +319,7 @@ static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps) protseqs = ps; LeaveCriticalSection(&server_cs); - if (listen_count >= 0) SetEvent(mgr_event); + if (std_listen) SetEvent(mgr_event); return RPC_S_OK; } @@ -534,6 +546,28 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, return RPC_S_OK; } +/*********************************************************************** + * RpcServerUnregisterIf (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete ) +{ + FIXME("(IfSpec == (RPC_IF_HANDLE)^%p, MgrTypeUuid == %s, WaitForCallsToComplete == %u): stub\n", + IfSpec, debugstr_guid(MgrTypeUuid), WaitForCallsToComplete); + + return RPC_S_OK; +} + +/*********************************************************************** + * RpcServerUnregisterIfEx (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcServerUnregisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, int RundownContextHandles ) +{ + FIXME("(IfSpec == (RPC_IF_HANDLE)^%p, MgrTypeUuid == %s, RundownContextHandles == %d): stub\n", + IfSpec, debugstr_guid(MgrTypeUuid), RundownContextHandles); + + return RPC_S_OK; +} + /*********************************************************************** * RpcServerRegisterAuthInfoA (RPCRT4.@) */ @@ -563,15 +597,20 @@ RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT { TRACE("(%u,%u,%u)\n", MinimumCallThreads, MaxCalls, DontWait); - if (std_listen) - return RPC_S_ALREADY_LISTENING; - if (!protseqs) return RPC_S_NO_PROTSEQS_REGISTERED; - std_listen = TRUE; + EnterCriticalSection(&listen_cs); + + if (std_listen) { + LeaveCriticalSection(&listen_cs); + return RPC_S_ALREADY_LISTENING; + } + RPCRT4_start_listen(); + LeaveCriticalSection(&listen_cs); + if (DontWait) return RPC_S_OK; return RpcMgmtWaitServerListen(); @@ -585,17 +624,49 @@ RPC_STATUS WINAPI RpcMgmtWaitServerListen( void ) RPC_STATUS rslt = RPC_S_OK; TRACE("\n"); + + EnterCriticalSection(&listen_cs); + if (!std_listen) - if ( (rslt = RpcServerListen(1, 0, TRUE)) != RPC_S_OK ) + if ( (rslt = RpcServerListen(1, 0, TRUE)) != RPC_S_OK ) { + LeaveCriticalSection(&listen_cs); return rslt; + } + LeaveCriticalSection(&listen_cs); + while (std_listen) { - WaitForSingleObject(mgr_event, 1000); + WaitForSingleObject(mgr_event, INFINITE); + if (!std_listen) { + Sleep(100); /* don't spin violently */ + TRACE("spinning.\n"); + } } return rslt; } +/*********************************************************************** + * RpcMgmtStopServerListening (RPCRT4.@) + */ +RPC_STATUS WINAPI RpcMgmtStopServerListening ( RPC_BINDING_HANDLE Binding ) +{ + TRACE("(Binding == (RPC_BINDING_HANDLE)^%p)\n", Binding); + + if (Binding) { + FIXME("client-side invocation not implemented.\n"); + return RPC_S_WRONG_KIND_OF_BINDING; + } + + /* hmm... */ + EnterCriticalSection(&listen_cs); + while (std_listen) + RPCRT4_stop_listen(); + LeaveCriticalSection(&listen_cs); + + return RPC_S_OK; +} + /*********************************************************************** * I_RpcServerStartListening (RPCRT4.@) */ diff --git a/dlls/rpcrt4/rpcrt4.spec b/dlls/rpcrt4/rpcrt4.spec index 1a6febfdf74..44d6d9ec288 100644 --- a/dlls/rpcrt4/rpcrt4.spec +++ b/dlls/rpcrt4/rpcrt4.spec @@ -98,7 +98,7 @@ init RPCRT4_LibMain @ stub RpcMgmtSetParameter # win9x @ stub RpcMgmtSetServerStackSize @ stub RpcMgmtStatsVectorFree -@ stub RpcMgmtStopServerListening +@ stdcall RpcMgmtStopServerListening(ptr) RpcMgmtStopServerListening @ stdcall RpcMgmtWaitServerListen() RpcMgmtWaitServerListen @ stub RpcNetworkInqProtseqsA @ stub RpcNetworkInqProtseqsW @@ -128,8 +128,8 @@ init RPCRT4_LibMain @ stdcall RpcServerRegisterIfEx(ptr ptr ptr long long ptr) RpcServerRegisterIfEx @ stdcall RpcServerRegisterIf2(ptr ptr ptr long long long ptr) RpcServerRegisterIf2 @ stub RpcServerTestCancel -@ stub RpcServerUnregisterIf -@ stub RpcServerUnregisterIfEx # wxp +@ stdcall RpcServerUnregisterIf(ptr ptr long) RpcServerUnregisterIf +@ stdcall RpcServerUnregisterIfEx(ptr ptr long) RpcServerUnregisterIfEx @ stub RpcServerUseAllProtseqs @ stub RpcServerUseAllProtseqsEx @ stub RpcServerUseAllProtseqsIf diff --git a/include/rpcdce.h b/include/rpcdce.h index b3141e76da5..6fe15c799be 100644 --- a/include/rpcdce.h +++ b/include/rpcdce.h @@ -172,6 +172,9 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RPCRTAPI RPC_STATUS RPC_ENTRY RpcMgmtWaitServerListen( void ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcMgmtStopServerListening( RPC_BINDING_HANDLE Binding ); + RPCRTAPI RPC_STATUS RPC_ENTRY RpcServerRegisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv ); @@ -183,6 +186,12 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn ); +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete ); + +RPCRTAPI RPC_STATUS RPC_ENTRY + RpcServerUnregisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, int RundownContextHandles ); + RPCRTAPI RPC_STATUS RPC_ENTRY RpcServerUseProtseqA(LPSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor); @@ -190,7 +199,6 @@ RPCRTAPI RPC_STATUS RPC_ENTRY RpcServerUseProtseqW(LPWSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor); #define RpcServerUseProtseq WINELIB_NAME_AW(RpcServerUseProtseq) - RPCRTAPI RPC_STATUS RPC_ENTRY RpcServerUseProtseqEpA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor ); RPCRTAPI RPC_STATUS RPC_ENTRY