Commit 3eafbfcd authored by Greg Turner's avatar Greg Turner Committed by Alexandre Julliard

- Fix offset bug in the conformant string unmarshall routine.

- Fix discrepancy between headers and implementation of I_RpcBindingSetAsync when compiling under WINNT. - Eliminate race conditions in the relationship between "listen_count" and "std_listen" in rpc_server.h. - Code-stubs for RpcServerUnregisterIf, RpcServerUnregisterIfEx. - Attempt to implement RpcMgmtStopServerListening (definitely not happy just yet). - RpcServerUnregisterIfEx wasn't xp-sepcific after all; this leads me to suspect there are more such mistakes in the spec-file comments, but I haven't looked into it or fixed them yet (coming soon). - Cleanups, trace-enhancements, etc.
parent 775fcfde
...@@ -67,10 +67,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole); ...@@ -67,10 +67,11 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
* NdrConformantString: * NdrConformantString:
* *
* What MS calls a ConformantString is, in DCE terminology, * 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') * 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') * length: DWORD (# of CHARTYPE characters, inclusive of '\0')
* [ * [
* data: CHARTYPE[maxlen] * data: CHARTYPE[maxlen]
...@@ -199,7 +200,7 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg ...@@ -199,7 +200,7 @@ unsigned char *WINAPI NdrConformantStringUnmarshall( PMIDL_STUB_MESSAGE pStubMsg
len = LITTLE_ENDIAN_UINT32_READ(pStubMsg->Buffer); len = LITTLE_ENDIAN_UINT32_READ(pStubMsg->Buffer);
pStubMsg->Buffer += 4; 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') while ((*c++ = *(pStubMsg->Buffer++)) != '\0')
; ;
......
...@@ -865,14 +865,21 @@ RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, LPWSTR ...@@ -865,14 +865,21 @@ RPC_STATUS WINAPI RpcBindingToStringBindingW( RPC_BINDING_HANDLE Binding, LPWSTR
* Exists in win9x and winNT, but with different number of arguments * Exists in win9x and winNT, but with different number of arguments
* (9x version has 3 arguments, NT has 2). * (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 ) RPC_STATUS WINAPI I_RpcBindingSetAsync( RPC_BINDING_HANDLE Binding, RPC_BLOCKING_FN BlockingFn, unsigned long ServerTid )
#endif
{ {
RpcBinding* bind = (RpcBinding*)Binding; RpcBinding* bind = (RpcBinding*)Binding;
TRACE( "(%p,%p,%ld): stub\n", Binding, BlockingFn, ServerTid ); TRACE( "(%p,%p,%ld): stub\n", Binding, BlockingFn, ServerTid );
bind->BlockingFn = BlockingFn; bind->BlockingFn = BlockingFn;
#ifndef WINNT
bind->ServerTid = ServerTid; bind->ServerTid = ServerTid;
#endif
return RPC_S_OK; return RPC_S_OK;
} }
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <assert.h>
#include "windef.h" #include "windef.h"
#include "winbase.h" #include "winbase.h"
...@@ -42,6 +43,7 @@ static RpcServerProtseq* protseqs; ...@@ -42,6 +43,7 @@ static RpcServerProtseq* protseqs;
static RpcServerInterface* ifs; static RpcServerInterface* ifs;
static CRITICAL_SECTION server_cs = CRITICAL_SECTION_INIT("RpcServer"); static CRITICAL_SECTION server_cs = CRITICAL_SECTION_INIT("RpcServer");
static CRITICAL_SECTION listen_cs = CRITICAL_SECTION_INIT("RpcListen");
static BOOL std_listen; static BOOL std_listen;
static LONG listen_count = -1; static LONG listen_count = -1;
static HANDLE mgr_event, server_thread; static HANDLE mgr_event, server_thread;
...@@ -95,7 +97,7 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) ...@@ -95,7 +97,7 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
} }
#endif #endif
if (dwRead != sizeof(hdr)) { if (dwRead != sizeof(hdr)) {
TRACE("protocol error\n"); if (dwRead) TRACE("protocol error: <hdrsz == %d, dwRead == %lu>\n", sizeof(hdr), dwRead);
break; break;
} }
...@@ -118,7 +120,7 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg) ...@@ -118,7 +120,7 @@ static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
} }
#endif #endif
if (dwRead != hdr.len) { if (dwRead != hdr.len) {
TRACE("protocol error\n"); TRACE("protocol error: <bodylen == %d, dwRead == %lu>\n", hdr.len, dwRead);
break; break;
} }
...@@ -231,7 +233,8 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg) ...@@ -231,7 +233,8 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
/* start waiting */ /* start waiting */
res = WaitForMultipleObjects(count, objs, FALSE, INFINITE); res = WaitForMultipleObjects(count, objs, FALSE, INFINITE);
if (res == WAIT_OBJECT_0) { if (res == WAIT_OBJECT_0) {
if (listen_count == -1) break; ResetEvent(m_event);
if (!std_listen) break;
} }
else if (res == WAIT_FAILED) { else if (res == WAIT_FAILED) {
ERR("wait failed\n"); ERR("wait failed\n");
...@@ -279,24 +282,33 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg) ...@@ -279,24 +282,33 @@ static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
static void RPCRT4_start_listen(void) static void RPCRT4_start_listen(void)
{ {
TRACE("\n"); TRACE("\n");
if (!InterlockedIncrement(&listen_count)) {
mgr_event = CreateEventA(NULL, FALSE, FALSE, NULL); 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); server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, NULL, 0, NULL);
LeaveCriticalSection(&listen_cs);
} else {
LeaveCriticalSection(&listen_cs);
SetEvent(mgr_event);
} }
else SetEvent(mgr_event);
} }
/* not used (WTF?) ---------------------------
static void RPCRT4_stop_listen(void) static void RPCRT4_stop_listen(void)
{ {
HANDLE m_event = mgr_event; EnterCriticalSection(&listen_cs);
if (InterlockedDecrement(&listen_count) < 0) if (listen_count == -1)
SetEvent(m_event); 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) static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps)
{ {
RPCRT4_CreateBindingA(&ps->bind, TRUE, ps->Protseq); RPCRT4_CreateBindingA(&ps->bind, TRUE, ps->Protseq);
...@@ -307,7 +319,7 @@ static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps) ...@@ -307,7 +319,7 @@ static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps)
protseqs = ps; protseqs = ps;
LeaveCriticalSection(&server_cs); LeaveCriticalSection(&server_cs);
if (listen_count >= 0) SetEvent(mgr_event); if (std_listen) SetEvent(mgr_event);
return RPC_S_OK; return RPC_S_OK;
} }
...@@ -535,6 +547,28 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, ...@@ -535,6 +547,28 @@ RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid,
} }
/*********************************************************************** /***********************************************************************
* 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.@) * RpcServerRegisterAuthInfoA (RPCRT4.@)
*/ */
RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( LPSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn, RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( LPSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
...@@ -563,15 +597,20 @@ RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT ...@@ -563,15 +597,20 @@ RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT
{ {
TRACE("(%u,%u,%u)\n", MinimumCallThreads, MaxCalls, DontWait); TRACE("(%u,%u,%u)\n", MinimumCallThreads, MaxCalls, DontWait);
if (std_listen)
return RPC_S_ALREADY_LISTENING;
if (!protseqs) if (!protseqs)
return RPC_S_NO_PROTSEQS_REGISTERED; 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(); RPCRT4_start_listen();
LeaveCriticalSection(&listen_cs);
if (DontWait) return RPC_S_OK; if (DontWait) return RPC_S_OK;
return RpcMgmtWaitServerListen(); return RpcMgmtWaitServerListen();
...@@ -585,18 +624,50 @@ RPC_STATUS WINAPI RpcMgmtWaitServerListen( void ) ...@@ -585,18 +624,50 @@ RPC_STATUS WINAPI RpcMgmtWaitServerListen( void )
RPC_STATUS rslt = RPC_S_OK; RPC_STATUS rslt = RPC_S_OK;
TRACE("\n"); TRACE("\n");
EnterCriticalSection(&listen_cs);
if (!std_listen) 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; return rslt;
}
LeaveCriticalSection(&listen_cs);
while (std_listen) { 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; 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.@) * I_RpcServerStartListening (RPCRT4.@)
*/ */
RPC_STATUS WINAPI I_RpcServerStartListening( void* hWnd ) RPC_STATUS WINAPI I_RpcServerStartListening( void* hWnd )
......
...@@ -98,7 +98,7 @@ init RPCRT4_LibMain ...@@ -98,7 +98,7 @@ init RPCRT4_LibMain
@ stub RpcMgmtSetParameter # win9x @ stub RpcMgmtSetParameter # win9x
@ stub RpcMgmtSetServerStackSize @ stub RpcMgmtSetServerStackSize
@ stub RpcMgmtStatsVectorFree @ stub RpcMgmtStatsVectorFree
@ stub RpcMgmtStopServerListening @ stdcall RpcMgmtStopServerListening(ptr) RpcMgmtStopServerListening
@ stdcall RpcMgmtWaitServerListen() RpcMgmtWaitServerListen @ stdcall RpcMgmtWaitServerListen() RpcMgmtWaitServerListen
@ stub RpcNetworkInqProtseqsA @ stub RpcNetworkInqProtseqsA
@ stub RpcNetworkInqProtseqsW @ stub RpcNetworkInqProtseqsW
...@@ -128,8 +128,8 @@ init RPCRT4_LibMain ...@@ -128,8 +128,8 @@ init RPCRT4_LibMain
@ stdcall RpcServerRegisterIfEx(ptr ptr ptr long long ptr) RpcServerRegisterIfEx @ stdcall RpcServerRegisterIfEx(ptr ptr ptr long long ptr) RpcServerRegisterIfEx
@ stdcall RpcServerRegisterIf2(ptr ptr ptr long long long ptr) RpcServerRegisterIf2 @ stdcall RpcServerRegisterIf2(ptr ptr ptr long long long ptr) RpcServerRegisterIf2
@ stub RpcServerTestCancel @ stub RpcServerTestCancel
@ stub RpcServerUnregisterIf @ stdcall RpcServerUnregisterIf(ptr ptr long) RpcServerUnregisterIf
@ stub RpcServerUnregisterIfEx # wxp @ stdcall RpcServerUnregisterIfEx(ptr ptr long) RpcServerUnregisterIfEx
@ stub RpcServerUseAllProtseqs @ stub RpcServerUseAllProtseqs
@ stub RpcServerUseAllProtseqsEx @ stub RpcServerUseAllProtseqsEx
@ stub RpcServerUseAllProtseqsIf @ stub RpcServerUseAllProtseqsIf
......
...@@ -173,6 +173,9 @@ RPCRTAPI RPC_STATUS RPC_ENTRY ...@@ -173,6 +173,9 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
RpcMgmtWaitServerListen( void ); RpcMgmtWaitServerListen( void );
RPCRTAPI RPC_STATUS RPC_ENTRY 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 ); RpcServerRegisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv );
RPCRTAPI RPC_STATUS RPC_ENTRY RPCRTAPI RPC_STATUS RPC_ENTRY
...@@ -183,6 +186,12 @@ RPCRTAPI RPC_STATUS RPC_ENTRY ...@@ -183,6 +186,12 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv, RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn ); 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 RPCRTAPI RPC_STATUS RPC_ENTRY
RpcServerUseProtseqA(LPSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor); RpcServerUseProtseqA(LPSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor);
...@@ -190,7 +199,6 @@ RPCRTAPI RPC_STATUS RPC_ENTRY ...@@ -190,7 +199,6 @@ RPCRTAPI RPC_STATUS RPC_ENTRY
RpcServerUseProtseqW(LPWSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor); RpcServerUseProtseqW(LPWSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor);
#define RpcServerUseProtseq WINELIB_NAME_AW(RpcServerUseProtseq) #define RpcServerUseProtseq WINELIB_NAME_AW(RpcServerUseProtseq)
RPCRTAPI RPC_STATUS RPC_ENTRY RPCRTAPI RPC_STATUS RPC_ENTRY
RpcServerUseProtseqEpA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor ); RpcServerUseProtseqEpA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor );
RPCRTAPI RPC_STATUS RPC_ENTRY RPCRTAPI RPC_STATUS RPC_ENTRY
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment