Remove #ifdef WINNT conditionals; just use the NT definitions.
[wine/dcerpc.git] / dlls / rpcrt4 / rpc_server.c
blobe91305cb280e4c7d0b0444317233f88010615542
1 /*
2 * RPC server API
4 * Copyright 2001 Ove Kåven, TransGaming Technologies
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 * TODO:
21 * - a whole lot
24 #include <stdio.h>
25 #include <string.h>
26 #include <assert.h>
28 #include "windef.h"
29 #include "winbase.h"
30 #include "winerror.h"
31 #include "winreg.h"
33 #include "rpc.h"
35 #include "wine/debug.h"
37 #include "rpc_server.h"
38 #include "rpc_defs.h"
40 WINE_DEFAULT_DEBUG_CHANNEL(ole);
42 static RpcServerProtseq* protseqs;
43 static RpcServerInterface* ifs;
45 static CRITICAL_SECTION server_cs = CRITICAL_SECTION_INIT("RpcServer");
46 static CRITICAL_SECTION listen_cs = CRITICAL_SECTION_INIT("RpcListen");
47 static BOOL std_listen;
48 static LONG listen_count = -1;
49 static HANDLE mgr_event, server_thread;
51 static RpcServerInterface* RPCRT4_find_interface(UUID* object, UUID* if_id)
53 UUID* MgrType = NULL;
54 RpcServerInterface* cif = NULL;
55 RPC_STATUS status;
57 /* FIXME: object -> MgrType */
58 EnterCriticalSection(&server_cs);
59 cif = ifs;
60 while (cif) {
61 if (UuidEqual(if_id, &cif->If->InterfaceId.SyntaxGUID, &status) &&
62 UuidEqual(MgrType, &cif->MgrTypeUuid, &status) &&
63 (std_listen || (cif->Flags & RPC_IF_AUTOLISTEN))) break;
64 cif = cif->Next;
66 LeaveCriticalSection(&server_cs);
67 return cif;
70 static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
72 RpcBinding* bind = (RpcBinding*)the_arg;
73 RpcPktHdr hdr;
74 DWORD dwRead;
75 RPC_MESSAGE msg;
76 RpcServerInterface* sif;
77 RPC_DISPATCH_FUNCTION func;
79 memset(&msg, 0, sizeof(msg));
80 msg.Handle = (RPC_BINDING_HANDLE)bind;
82 for (;;) {
83 /* read packet header */
84 #ifdef OVERLAPPED_WORKS
85 if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, &bind->ovl)) {
86 DWORD err = GetLastError();
87 if (err != ERROR_IO_PENDING) {
88 TRACE("connection lost, error=%08lx\n", err);
89 break;
91 if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) break;
93 #else
94 if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, NULL)) {
95 TRACE("connection lost, error=%08lx\n", GetLastError());
96 break;
98 #endif
99 if (dwRead != sizeof(hdr)) {
100 if (dwRead) TRACE("protocol error: <hdrsz == %d, dwRead == %lu>\n", sizeof(hdr), dwRead);
101 break;
104 /* read packet body */
105 msg.BufferLength = hdr.len;
106 msg.Buffer = HeapAlloc(GetProcessHeap(), 0, msg.BufferLength);
107 #ifdef OVERLAPPED_WORKS
108 if (!ReadFile(bind->conn, msg.Buffer, msg.BufferLength, &dwRead, &bind->ovl)) {
109 DWORD err = GetLastError();
110 if (err != ERROR_IO_PENDING) {
111 TRACE("connection lost, error=%08lx\n", err);
112 break;
114 if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) break;
116 #else
117 if (!ReadFile(bind->conn, msg.Buffer, msg.BufferLength, &dwRead, NULL)) {
118 TRACE("connection lost, error=%08lx\n", GetLastError());
119 break;
121 #endif
122 if (dwRead != hdr.len) {
123 TRACE("protocol error: <bodylen == %d, dwRead == %lu>\n", hdr.len, dwRead);
124 break;
127 sif = RPCRT4_find_interface(&hdr.object, &hdr.if_id);
128 if (sif) {
129 msg.RpcInterfaceInformation = sif->If;
130 /* associate object with binding (this is a bit of a hack...
131 * a new binding should probably be created for each object) */
132 RPCRT4_SetBindingObject(bind, &hdr.object);
133 /* process packet*/
134 switch (hdr.ptype) {
135 case PKT_REQUEST:
136 /* find dispatch function */
137 msg.ProcNum = hdr.opnum;
138 if (sif->Flags & RPC_IF_OLE) {
139 /* native ole32 always gives us a dispatch table with a single entry
140 * (I assume that's a wrapper for IRpcStubBuffer::Invoke) */
141 func = *sif->If->DispatchTable->DispatchTable;
142 } else {
143 if (msg.ProcNum >= sif->If->DispatchTable->DispatchTableCount) {
144 ERR("invalid procnum\n");
145 func = NULL;
147 func = sif->If->DispatchTable->DispatchTable[msg.ProcNum];
150 /* put in the drep. FIXME: is this more universally applicable?
151 perhaps we should move this outward... */
152 msg.DataRepresentation =
153 MAKELONG( MAKEWORD(hdr.drep[0], hdr.drep[1]),
154 MAKEWORD(hdr.drep[2], 0));
156 /* dispatch */
157 if (func) func(&msg);
159 /* prepare response packet */
160 hdr.ptype = PKT_RESPONSE;
161 break;
162 default:
163 ERR("unknown packet type\n");
164 goto no_reply;
167 /* write reply packet */
168 hdr.len = msg.BufferLength;
169 WriteFile(bind->conn, &hdr, sizeof(hdr), NULL, NULL);
170 WriteFile(bind->conn, msg.Buffer, msg.BufferLength, NULL, NULL);
172 no_reply:
173 /* un-associate object */
174 RPCRT4_SetBindingObject(bind, NULL);
175 msg.RpcInterfaceInformation = NULL;
177 else {
178 ERR("got RPC packet to unregistered interface %s\n", debugstr_guid(&hdr.if_id));
181 /* clean up */
182 HeapFree(GetProcessHeap(), 0, msg.Buffer);
183 msg.Buffer = NULL;
185 if (msg.Buffer) HeapFree(GetProcessHeap(), 0, msg.Buffer);
186 RPCRT4_DestroyBinding(bind);
187 return 0;
190 static void RPCRT4_new_client(RpcBinding* bind)
192 bind->thread = CreateThread(NULL, 0, RPCRT4_io_thread, bind, 0, NULL);
195 static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
197 HANDLE m_event = mgr_event, b_handle;
198 HANDLE *objs = NULL;
199 DWORD count, res;
200 RpcServerProtseq* cps;
201 RpcBinding* bind;
202 RpcBinding* cbind;
204 for (;;) {
205 EnterCriticalSection(&server_cs);
206 /* open and count bindings */
207 count = 1;
208 cps = protseqs;
209 while (cps) {
210 bind = cps->bind;
211 while (bind) {
212 RPCRT4_OpenBinding(bind);
213 if (bind->ovl.hEvent) count++;
214 bind = bind->Next;
216 cps = cps->Next;
218 /* make array of bindings */
219 objs = HeapReAlloc(GetProcessHeap(), 0, objs, count*sizeof(HANDLE));
220 objs[0] = m_event;
221 count = 1;
222 cps = protseqs;
223 while (cps) {
224 bind = cps->bind;
225 while (bind) {
226 if (bind->ovl.hEvent) objs[count++] = bind->ovl.hEvent;
227 bind = bind->Next;
229 cps = cps->Next;
231 LeaveCriticalSection(&server_cs);
233 /* start waiting */
234 res = WaitForMultipleObjects(count, objs, FALSE, INFINITE);
235 if (res == WAIT_OBJECT_0) {
236 ResetEvent(m_event);
237 if (!std_listen) break;
239 else if (res == WAIT_FAILED) {
240 ERR("wait failed\n");
242 else {
243 b_handle = objs[res - WAIT_OBJECT_0];
244 /* find which binding got a RPC */
245 EnterCriticalSection(&server_cs);
246 bind = NULL;
247 cps = protseqs;
248 while (cps) {
249 bind = cps->bind;
250 while (bind) {
251 if (bind->ovl.hEvent == b_handle) break;
252 bind = bind->Next;
254 if (bind) break;
255 cps = cps->Next;
257 cbind = NULL;
258 if (bind) RPCRT4_SpawnBinding(&cbind, bind);
259 LeaveCriticalSection(&server_cs);
260 if (!bind) {
261 ERR("failed to locate binding for handle %p\n", b_handle);
263 if (cbind) RPCRT4_new_client(cbind);
266 HeapFree(GetProcessHeap(), 0, objs);
267 EnterCriticalSection(&server_cs);
268 /* close bindings */
269 cps = protseqs;
270 while (cps) {
271 bind = cps->bind;
272 while (bind) {
273 RPCRT4_CloseBinding(bind);
274 bind = bind->Next;
276 cps = cps->Next;
278 LeaveCriticalSection(&server_cs);
279 return 0;
282 static void RPCRT4_start_listen(void)
284 TRACE("\n");
286 EnterCriticalSection(&listen_cs);
287 if (! ++listen_count) {
288 if (!mgr_event) mgr_event = CreateEventA(NULL, TRUE, FALSE, NULL);
289 std_listen = TRUE;
290 server_thread = CreateThread(NULL, 0, RPCRT4_server_thread, NULL, 0, NULL);
291 LeaveCriticalSection(&listen_cs);
292 } else {
293 LeaveCriticalSection(&listen_cs);
294 SetEvent(mgr_event);
298 static void RPCRT4_stop_listen(void)
300 EnterCriticalSection(&listen_cs);
301 if (listen_count == -1)
302 LeaveCriticalSection(&listen_cs);
303 else if (--listen_count == -1) {
304 std_listen = FALSE;
305 LeaveCriticalSection(&listen_cs);
306 SetEvent(mgr_event);
307 } else
308 LeaveCriticalSection(&listen_cs);
309 assert(listen_count > -2);
312 static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps)
314 RPCRT4_CreateBindingA(&ps->bind, TRUE, ps->Protseq);
315 RPCRT4_CompleteBindingA(ps->bind, NULL, ps->Endpoint, NULL);
317 EnterCriticalSection(&server_cs);
318 ps->Next = protseqs;
319 protseqs = ps;
320 LeaveCriticalSection(&server_cs);
322 if (std_listen) SetEvent(mgr_event);
324 return RPC_S_OK;
327 /***********************************************************************
328 * RpcServerInqBindings (RPCRT4.@)
330 RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
332 RPC_STATUS status;
333 DWORD count;
334 RpcServerProtseq* ps;
335 RpcBinding* bind;
337 if (BindingVector)
338 TRACE("(*BindingVector == ^%p)\n", *BindingVector);
339 else
340 ERR("(BindingVector == ^null!!?)\n");
342 EnterCriticalSection(&server_cs);
343 /* count bindings */
344 count = 0;
345 ps = protseqs;
346 while (ps) {
347 bind = ps->bind;
348 while (bind) {
349 count++;
350 bind = bind->Next;
352 ps = ps->Next;
354 if (count) {
355 /* export bindings */
356 *BindingVector = HeapAlloc(GetProcessHeap(), 0,
357 sizeof(RPC_BINDING_VECTOR) +
358 sizeof(RPC_BINDING_HANDLE)*(count-1));
359 (*BindingVector)->Count = count;
360 count = 0;
361 ps = protseqs;
362 while (ps) {
363 bind = ps->bind;
364 while (bind) {
365 RPCRT4_ExportBinding((RpcBinding**)&(*BindingVector)->BindingH[count],
366 bind);
367 count++;
368 bind = bind->Next;
370 ps = ps->Next;
372 status = RPC_S_OK;
373 } else {
374 *BindingVector = NULL;
375 status = RPC_S_NO_BINDINGS;
377 LeaveCriticalSection(&server_cs);
378 return status;
381 /***********************************************************************
382 * RpcServerUseProtseqEpA (RPCRT4.@)
384 RPC_STATUS WINAPI RpcServerUseProtseqEpA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor )
386 RPC_POLICY policy;
388 TRACE( "(%s,%u,%s,%p)\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor );
390 /* This should provide the default behaviour */
391 policy.Length = sizeof( policy );
392 policy.EndpointFlags = 0;
393 policy.NICFlags = 0;
395 return RpcServerUseProtseqEpExA( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy );
398 /***********************************************************************
399 * RpcServerUseProtseqEpW (RPCRT4.@)
401 RPC_STATUS WINAPI RpcServerUseProtseqEpW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor )
403 RPC_POLICY policy;
405 TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor );
407 /* This should provide the default behaviour */
408 policy.Length = sizeof( policy );
409 policy.EndpointFlags = 0;
410 policy.NICFlags = 0;
412 return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy );
415 /***********************************************************************
416 * RpcServerUseProtseqEpExA (RPCRT4.@)
418 RPC_STATUS WINAPI RpcServerUseProtseqEpExA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor,
419 PRPC_POLICY lpPolicy )
421 RpcServerProtseq* ps;
423 TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_a( Protseq ), MaxCalls,
424 debugstr_a( Endpoint ), SecurityDescriptor,
425 lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
427 ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerProtseq));
428 ps->MaxCalls = MaxCalls;
429 ps->Protseq = RPCRT4_strdupA(Protseq);
430 ps->Endpoint = RPCRT4_strdupA(Endpoint);
432 return RPCRT4_use_protseq(ps);
435 /***********************************************************************
436 * RpcServerUseProtseqEpExW (RPCRT4.@)
438 RPC_STATUS WINAPI RpcServerUseProtseqEpExW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor,
439 PRPC_POLICY lpPolicy )
441 RpcServerProtseq* ps;
443 TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_w( Protseq ), MaxCalls,
444 debugstr_w( Endpoint ), SecurityDescriptor,
445 lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
447 ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerProtseq));
448 ps->MaxCalls = MaxCalls;
449 /* FIXME: Did Ove have these next two as RPCRT4_strdupW for a reason? */
450 ps->Protseq = RPCRT4_strdupWtoA(Protseq);
451 ps->Endpoint = RPCRT4_strdupWtoA(Endpoint);
453 return RPCRT4_use_protseq(ps);
456 /***********************************************************************
457 * RpcServerUseProtseqA (RPCRT4.@)
459 RPC_STATUS WINAPI RpcServerUseProtseqA(LPSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
461 TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)", debugstr_a(Protseq), MaxCalls, SecurityDescriptor);
462 return RpcServerUseProtseqEpA(Protseq, MaxCalls, NULL, SecurityDescriptor);
465 /***********************************************************************
466 * RpcServerUseProtseqW (RPCRT4.@)
468 RPC_STATUS WINAPI RpcServerUseProtseqW(LPWSTR Protseq, unsigned int MaxCalls, void *SecurityDescriptor)
470 TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)", debugstr_w(Protseq), MaxCalls, SecurityDescriptor);
471 return RpcServerUseProtseqEpW(Protseq, MaxCalls, NULL, SecurityDescriptor);
474 /***********************************************************************
475 * RpcServerRegisterIf (RPCRT4.@)
477 RPC_STATUS WINAPI RpcServerRegisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv )
479 TRACE("(%p,%s,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv);
480 return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT, (UINT)-1, NULL );
483 /***********************************************************************
484 * RpcServerRegisterIfEx (RPCRT4.@)
486 RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
487 UINT Flags, UINT MaxCalls, RPC_IF_CALLBACK_FN* IfCallbackFn )
489 TRACE("(%p,%s,%p,%u,%u,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv, Flags, MaxCalls, IfCallbackFn);
490 return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, Flags, MaxCalls, (UINT)-1, IfCallbackFn );
493 /***********************************************************************
494 * RpcServerRegisterIf2 (RPCRT4.@)
496 RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
497 UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn )
499 PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
500 RpcServerInterface* sif;
501 int i;
503 TRACE("(%p,%s,%p,%u,%u,%u,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv, Flags, MaxCalls,
504 MaxRpcSize, IfCallbackFn);
505 TRACE(" interface id: %s %d.%d\n", debugstr_guid(&If->InterfaceId.SyntaxGUID),
506 If->InterfaceId.SyntaxVersion.MajorVersion,
507 If->InterfaceId.SyntaxVersion.MinorVersion);
508 TRACE(" transfer syntax: %s %d.%d\n", debugstr_guid(&If->TransferSyntax.SyntaxGUID),
509 If->TransferSyntax.SyntaxVersion.MajorVersion,
510 If->TransferSyntax.SyntaxVersion.MinorVersion);
511 TRACE(" dispatch table: %p\n", If->DispatchTable);
512 if (If->DispatchTable) {
513 TRACE(" dispatch table count: %d\n", If->DispatchTable->DispatchTableCount);
514 for (i=0; i<If->DispatchTable->DispatchTableCount; i++) {
515 TRACE(" entry %d: %p\n", i, If->DispatchTable->DispatchTable[i]);
517 TRACE(" reserved: %ld\n", If->DispatchTable->Reserved);
519 TRACE(" protseq endpoint count: %d\n", If->RpcProtseqEndpointCount);
520 TRACE(" default manager epv: %p\n", If->DefaultManagerEpv);
521 TRACE(" interpreter info: %p\n", If->InterpreterInfo);
522 TRACE(" flags: %08x\n", If->Flags);
524 sif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerInterface));
525 sif->If = If;
526 if (MgrTypeUuid)
527 memcpy(&sif->MgrTypeUuid, MgrTypeUuid, sizeof(UUID));
528 else
529 memset(&sif->MgrTypeUuid, 0, sizeof(UUID));
530 sif->MgrEpv = MgrEpv;
531 sif->Flags = Flags;
532 sif->MaxCalls = MaxCalls;
533 sif->MaxRpcSize = MaxRpcSize;
534 sif->IfCallbackFn = IfCallbackFn;
536 EnterCriticalSection(&server_cs);
537 sif->Next = ifs;
538 ifs = sif;
539 LeaveCriticalSection(&server_cs);
541 if (sif->Flags & RPC_IF_AUTOLISTEN) {
542 /* well, start listening, I think... */
543 RPCRT4_start_listen();
546 return RPC_S_OK;
549 /***********************************************************************
550 * RpcServerUnregisterIf (RPCRT4.@)
552 RPC_STATUS WINAPI RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, UINT WaitForCallsToComplete )
554 FIXME("(IfSpec == (RPC_IF_HANDLE)^%p, MgrTypeUuid == %s, WaitForCallsToComplete == %u): stub\n",
555 IfSpec, debugstr_guid(MgrTypeUuid), WaitForCallsToComplete);
557 return RPC_S_OK;
560 /***********************************************************************
561 * RpcServerUnregisterIfEx (RPCRT4.@)
563 RPC_STATUS WINAPI RpcServerUnregisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, int RundownContextHandles )
565 FIXME("(IfSpec == (RPC_IF_HANDLE)^%p, MgrTypeUuid == %s, RundownContextHandles == %d): stub\n",
566 IfSpec, debugstr_guid(MgrTypeUuid), RundownContextHandles);
568 return RPC_S_OK;
571 /***********************************************************************
572 * RpcServerRegisterAuthInfoA (RPCRT4.@)
574 RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( LPSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
575 LPVOID Arg )
577 FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg );
579 return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
582 /***********************************************************************
583 * RpcServerRegisterAuthInfoW (RPCRT4.@)
585 RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
586 LPVOID Arg )
588 FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg );
590 return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
593 /***********************************************************************
594 * RpcServerListen (RPCRT4.@)
596 RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait )
598 TRACE("(%u,%u,%u)\n", MinimumCallThreads, MaxCalls, DontWait);
600 if (!protseqs)
601 return RPC_S_NO_PROTSEQS_REGISTERED;
603 EnterCriticalSection(&listen_cs);
605 if (std_listen) {
606 LeaveCriticalSection(&listen_cs);
607 return RPC_S_ALREADY_LISTENING;
610 RPCRT4_start_listen();
612 LeaveCriticalSection(&listen_cs);
614 if (DontWait) return RPC_S_OK;
616 return RpcMgmtWaitServerListen();
619 /***********************************************************************
620 * RpcMgmtServerWaitListen (RPCRT4.@)
622 RPC_STATUS WINAPI RpcMgmtWaitServerListen( void )
624 RPC_STATUS rslt = RPC_S_OK;
626 TRACE("\n");
628 EnterCriticalSection(&listen_cs);
630 if (!std_listen)
631 if ( (rslt = RpcServerListen(1, 0, TRUE)) != RPC_S_OK ) {
632 LeaveCriticalSection(&listen_cs);
633 return rslt;
636 LeaveCriticalSection(&listen_cs);
638 while (std_listen) {
639 WaitForSingleObject(mgr_event, INFINITE);
640 if (!std_listen) {
641 Sleep(100); /* don't spin violently */
642 TRACE("spinning.\n");
646 return rslt;
649 /***********************************************************************
650 * RpcMgmtStopServerListening (RPCRT4.@)
652 RPC_STATUS WINAPI RpcMgmtStopServerListening ( RPC_BINDING_HANDLE Binding )
654 TRACE("(Binding == (RPC_BINDING_HANDLE)^%p)\n", Binding);
656 if (Binding) {
657 FIXME("client-side invocation not implemented.\n");
658 return RPC_S_WRONG_KIND_OF_BINDING;
661 /* hmm... */
662 EnterCriticalSection(&listen_cs);
663 while (std_listen)
664 RPCRT4_stop_listen();
665 LeaveCriticalSection(&listen_cs);
667 return RPC_S_OK;
670 /***********************************************************************
671 * I_RpcServerStartListening (RPCRT4.@)
673 RPC_STATUS WINAPI I_RpcServerStartListening( void* hWnd )
675 FIXME( "(%p): stub\n", hWnd );
677 return RPC_S_OK;
680 /***********************************************************************
681 * I_RpcServerStopListening (RPCRT4.@)
683 RPC_STATUS WINAPI I_RpcServerStopListening( void )
685 FIXME( "(): stub\n" );
687 return RPC_S_OK;
690 /***********************************************************************
691 * I_RpcWindowProc (RPCRT4.@)
693 LONG WINAPI I_RpcWindowProc( HWND hWnd, UINT Message, WPARAM wParam, LPARAM lParam )
695 FIXME( "(%p,%08x,%08x,%08lx): stub\n", hWnd, Message, wParam, lParam );
697 return 0;