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
35 #include "wine/debug.h"
37 #include "rpc_server.h"
40 #define MAX_THREADS 128
42 WINE_DEFAULT_DEBUG_CHANNEL(ole
);
44 typedef struct _RpcPacket
46 struct _RpcPacket
* next
;
47 struct _RpcConnection
* conn
;
52 static RpcServerProtseq
* protseqs
;
53 static RpcServerInterface
* ifs
;
55 static CRITICAL_SECTION server_cs
= CRITICAL_SECTION_INIT("RpcServer");
56 static CRITICAL_SECTION listen_cs
= CRITICAL_SECTION_INIT("RpcListen");
57 static BOOL std_listen
;
58 static LONG listen_count
= -1;
59 static HANDLE mgr_event
, server_thread
;
61 static CRITICAL_SECTION spacket_cs
= CRITICAL_SECTION_INIT("RpcServerPacket");
62 static RpcPacket
* spacket_head
;
63 static RpcPacket
* spacket_tail
;
64 static HANDLE server_sem
;
66 static DWORD worker_count
, worker_free
;
68 static RpcServerInterface
* RPCRT4_find_interface(UUID
* object
, UUID
* if_id
)
71 RpcServerInterface
* cif
= NULL
;
74 /* FIXME: object -> MgrType */
75 EnterCriticalSection(&server_cs
);
78 if (UuidEqual(if_id
, &cif
->If
->InterfaceId
.SyntaxGUID
, &status
) &&
79 UuidEqual(MgrType
, &cif
->MgrTypeUuid
, &status
) &&
80 (std_listen
|| (cif
->Flags
& RPC_IF_AUTOLISTEN
))) break;
83 LeaveCriticalSection(&server_cs
);
87 static void RPCRT4_push_packet(RpcPacket
* packet
)
90 EnterCriticalSection(&spacket_cs
);
91 if (spacket_tail
) spacket_tail
->next
= packet
;
93 spacket_head
= packet
;
94 spacket_tail
= packet
;
96 LeaveCriticalSection(&spacket_cs
);
99 static RpcPacket
* RPCRT4_pop_packet(void)
102 EnterCriticalSection(&spacket_cs
);
103 packet
= spacket_head
;
105 spacket_head
= packet
->next
;
106 if (!spacket_head
) spacket_tail
= NULL
;
108 LeaveCriticalSection(&spacket_cs
);
109 if (packet
) packet
->next
= NULL
;
113 static void RPCRT4_process_packet(RpcConnection
* conn
, RpcPktHdr
* hdr
, void* buf
)
117 RpcServerInterface
* sif
;
118 RPC_DISPATCH_FUNCTION func
;
120 memset(&msg
, 0, sizeof(msg
));
121 msg
.BufferLength
= hdr
->len
;
123 sif
= RPCRT4_find_interface(&hdr
->object
, &hdr
->if_id
);
125 TRACE("packet received for interface %s\n", debugstr_guid(&hdr
->if_id
));
126 msg
.RpcInterfaceInformation
= sif
->If
;
127 /* create temporary binding for dispatch */
128 RPCRT4_MakeBinding(&pbind
, conn
);
129 RPCRT4_SetBindingObject(pbind
, &hdr
->object
);
130 msg
.Handle
= (RPC_BINDING_HANDLE
)pbind
;
132 switch (hdr
->ptype
) {
134 /* find dispatch function */
135 msg
.ProcNum
= hdr
->opnum
;
136 if (sif
->Flags
& RPC_IF_OLE
) {
137 /* native ole32 always gives us a dispatch table with a single entry
138 * (I assume that's a wrapper for IRpcStubBuffer::Invoke) */
139 func
= *sif
->If
->DispatchTable
->DispatchTable
;
141 if (msg
.ProcNum
>= sif
->If
->DispatchTable
->DispatchTableCount
) {
142 ERR("invalid procnum\n");
145 func
= sif
->If
->DispatchTable
->DispatchTable
[msg
.ProcNum
];
148 /* put in the drep. FIXME: is this more universally applicable?
149 perhaps we should move this outward... */
150 msg
.DataRepresentation
=
151 MAKELONG( MAKEWORD(hdr
->drep
[0], hdr
->drep
[1]),
152 MAKEWORD(hdr
->drep
[2], 0));
155 if (func
) func(&msg
);
157 /* send response packet */
161 ERR("unknown packet type\n");
165 RPCRT4_DestroyBinding(pbind
);
167 msg
.RpcInterfaceInformation
= NULL
;
170 ERR("got RPC packet to unregistered interface %s\n", debugstr_guid(&hdr
->if_id
));
174 HeapFree(GetProcessHeap(), 0, msg
.Buffer
);
178 static DWORD CALLBACK
RPCRT4_worker_thread(LPVOID the_arg
)
184 /* idle timeout after 5s */
185 obj
= WaitForSingleObject(server_sem
, 5000);
186 if (obj
== WAIT_TIMEOUT
) {
187 /* if another idle thread exist, self-destruct */
188 if (worker_free
> 1) break;
191 pkt
= RPCRT4_pop_packet();
193 InterlockedDecrement(&worker_free
);
195 RPCRT4_process_packet(pkt
->conn
, &pkt
->hdr
, pkt
->buf
);
196 HeapFree(GetProcessHeap(), 0, pkt
);
197 /* try to grab another packet here without waiting
198 * on the semaphore, in case it hits max */
199 pkt
= RPCRT4_pop_packet();
201 /* decrement semaphore */
202 WaitForSingleObject(server_sem
, 0);
204 InterlockedIncrement(&worker_free
);
206 InterlockedDecrement(&worker_free
);
207 InterlockedDecrement(&worker_count
);
211 static void RPCRT4_create_worker_if_needed(void)
213 if (!worker_free
&& worker_count
< MAX_THREADS
) {
215 InterlockedIncrement(&worker_count
);
216 InterlockedIncrement(&worker_free
);
217 thread
= CreateThread(NULL
, 0, RPCRT4_worker_thread
, NULL
, 0, NULL
);
218 if (thread
) CloseHandle(thread
);
220 InterlockedDecrement(&worker_free
);
221 InterlockedDecrement(&worker_count
);
226 static DWORD CALLBACK
RPCRT4_io_thread(LPVOID the_arg
)
228 RpcConnection
* conn
= (RpcConnection
*)the_arg
;
234 TRACE("(%p)\n", conn
);
237 /* read packet header */
238 #ifdef OVERLAPPED_WORKS
239 if (!ReadFile(conn
->conn
, &hdr
, sizeof(hdr
), &dwRead
, &conn
->ovl
)) {
240 DWORD err
= GetLastError();
241 if (err
!= ERROR_IO_PENDING
) {
242 TRACE("connection lost, error=%08lx\n", err
);
245 if (!GetOverlappedResult(conn
->conn
, &conn
->ovl
, &dwRead
, TRUE
)) break;
248 if (!ReadFile(conn
->conn
, &hdr
, sizeof(hdr
), &dwRead
, NULL
)) {
249 TRACE("connection lost, error=%08lx\n", GetLastError());
253 if (dwRead
!= sizeof(hdr
)) {
254 if (dwRead
) TRACE("protocol error: <hdrsz == %d, dwRead == %lu>\n", sizeof(hdr
), dwRead
);
258 /* read packet body */
259 buf
= HeapAlloc(GetProcessHeap(), 0, hdr
.len
);
260 TRACE("receiving payload=%d\n", hdr
.len
);
261 if (!hdr
.len
) dwRead
= 0; else
262 #ifdef OVERLAPPED_WORKS
263 if (!ReadFile(conn
->conn
, buf
, hdr
.len
, &dwRead
, &conn
->ovl
)) {
264 DWORD err
= GetLastError();
265 if (err
!= ERROR_IO_PENDING
) {
266 TRACE("connection lost, error=%08lx\n", err
);
269 if (!GetOverlappedResult(conn
->conn
, &conn
->ovl
, &dwRead
, TRUE
)) break;
272 if (!ReadFile(conn
->conn
, buf
, hdr
.len
, &dwRead
, NULL
)) {
273 TRACE("connection lost, error=%08lx\n", GetLastError());
277 if (dwRead
!= hdr
.len
) {
278 TRACE("protocol error: <bodylen == %d, dwRead == %lu>\n", hdr
.len
, dwRead
);
283 RPCRT4_process_packet(conn
, &hdr
, buf
);
285 packet
= HeapAlloc(GetProcessHeap(), 0, sizeof(RpcPacket
));
289 RPCRT4_create_worker_if_needed();
290 RPCRT4_push_packet(packet
);
291 ReleaseSemaphore(server_sem
, 1, NULL
);
295 if (buf
) HeapFree(GetProcessHeap(), 0, buf
);
296 RPCRT4_DestroyConnection(conn
);
300 static void RPCRT4_new_client(RpcConnection
* conn
)
302 conn
->thread
= CreateThread(NULL
, 0, RPCRT4_io_thread
, conn
, 0, NULL
);
304 DWORD err
= GetLastError();
305 ERR("failed to create thread, error=%08lx\n", err
);
309 static DWORD CALLBACK
RPCRT4_server_thread(LPVOID the_arg
)
311 HANDLE m_event
= mgr_event
, b_handle
;
314 RpcServerProtseq
* cps
;
316 RpcConnection
* cconn
;
319 EnterCriticalSection(&server_cs
);
320 /* open and count connections */
326 RPCRT4_OpenConnection(conn
);
327 if (conn
->ovl
.hEvent
) count
++;
332 /* make array of connings */
333 objs
= HeapReAlloc(GetProcessHeap(), 0, objs
, count
*sizeof(HANDLE
));
340 if (conn
->ovl
.hEvent
) objs
[count
++] = conn
->ovl
.hEvent
;
345 LeaveCriticalSection(&server_cs
);
348 res
= WaitForMultipleObjects(count
, objs
, FALSE
, INFINITE
);
349 if (res
== WAIT_OBJECT_0
) {
351 if (!std_listen
) break;
353 else if (res
== WAIT_FAILED
) {
354 ERR("wait failed\n");
357 b_handle
= objs
[res
- WAIT_OBJECT_0
];
358 /* find which connection got a RPC */
359 EnterCriticalSection(&server_cs
);
365 if (conn
->ovl
.hEvent
== b_handle
) break;
372 if (conn
) RPCRT4_SpawnConnection(&cconn
, conn
);
373 LeaveCriticalSection(&server_cs
);
375 ERR("failed to locate connection for handle %p\n", b_handle
);
377 if (cconn
) RPCRT4_new_client(cconn
);
380 HeapFree(GetProcessHeap(), 0, objs
);
381 EnterCriticalSection(&server_cs
);
382 /* close connections */
387 RPCRT4_CloseConnection(conn
);
392 LeaveCriticalSection(&server_cs
);
396 static void RPCRT4_start_listen(void)
400 EnterCriticalSection(&listen_cs
);
401 if (! ++listen_count
) {
402 if (!mgr_event
) mgr_event
= CreateEventA(NULL
, TRUE
, FALSE
, NULL
);
403 if (!server_sem
) server_sem
= CreateSemaphoreA(NULL
, 0, MAX_THREADS
, NULL
);
405 server_thread
= CreateThread(NULL
, 0, RPCRT4_server_thread
, NULL
, 0, NULL
);
406 LeaveCriticalSection(&listen_cs
);
408 LeaveCriticalSection(&listen_cs
);
413 static void RPCRT4_stop_listen(void)
415 EnterCriticalSection(&listen_cs
);
416 if (listen_count
== -1)
417 LeaveCriticalSection(&listen_cs
);
418 else if (--listen_count
== -1) {
420 LeaveCriticalSection(&listen_cs
);
423 LeaveCriticalSection(&listen_cs
);
424 assert(listen_count
> -2);
427 static RPC_STATUS
RPCRT4_use_protseq(RpcServerProtseq
* ps
)
429 RPCRT4_CreateConnection(&ps
->conn
, TRUE
, ps
->Protseq
, NULL
, ps
->Endpoint
, NULL
);
431 EnterCriticalSection(&server_cs
);
434 LeaveCriticalSection(&server_cs
);
436 if (std_listen
) SetEvent(mgr_event
);
441 /***********************************************************************
442 * RpcServerInqBindings (RPCRT4.@)
444 RPC_STATUS WINAPI
RpcServerInqBindings( RPC_BINDING_VECTOR
** BindingVector
)
448 RpcServerProtseq
* ps
;
452 TRACE("(*BindingVector == ^%p)\n", *BindingVector
);
454 ERR("(BindingVector == ^null!!?)\n");
456 EnterCriticalSection(&server_cs
);
457 /* count connections */
469 /* export bindings */
470 *BindingVector
= HeapAlloc(GetProcessHeap(), 0,
471 sizeof(RPC_BINDING_VECTOR
) +
472 sizeof(RPC_BINDING_HANDLE
)*(count
-1));
473 (*BindingVector
)->Count
= count
;
479 RPCRT4_MakeBinding((RpcBinding
**)&(*BindingVector
)->BindingH
[count
],
488 *BindingVector
= NULL
;
489 status
= RPC_S_NO_BINDINGS
;
491 LeaveCriticalSection(&server_cs
);
495 /***********************************************************************
496 * RpcServerUseProtseqEpA (RPCRT4.@)
498 RPC_STATUS WINAPI
RpcServerUseProtseqEpA( LPSTR Protseq
, UINT MaxCalls
, LPSTR Endpoint
, LPVOID SecurityDescriptor
)
502 TRACE( "(%s,%u,%s,%p)\n", Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
);
504 /* This should provide the default behaviour */
505 policy
.Length
= sizeof( policy
);
506 policy
.EndpointFlags
= 0;
509 return RpcServerUseProtseqEpExA( Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
, &policy
);
512 /***********************************************************************
513 * RpcServerUseProtseqEpW (RPCRT4.@)
515 RPC_STATUS WINAPI
RpcServerUseProtseqEpW( LPWSTR Protseq
, UINT MaxCalls
, LPWSTR Endpoint
, LPVOID SecurityDescriptor
)
519 TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq
), MaxCalls
, debugstr_w( Endpoint
), SecurityDescriptor
);
521 /* This should provide the default behaviour */
522 policy
.Length
= sizeof( policy
);
523 policy
.EndpointFlags
= 0;
526 return RpcServerUseProtseqEpExW( Protseq
, MaxCalls
, Endpoint
, SecurityDescriptor
, &policy
);
529 /***********************************************************************
530 * RpcServerUseProtseqEpExA (RPCRT4.@)
532 RPC_STATUS WINAPI
RpcServerUseProtseqEpExA( LPSTR Protseq
, UINT MaxCalls
, LPSTR Endpoint
, LPVOID SecurityDescriptor
,
533 PRPC_POLICY lpPolicy
)
535 RpcServerProtseq
* ps
;
537 TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_a( Protseq
), MaxCalls
,
538 debugstr_a( Endpoint
), SecurityDescriptor
,
539 lpPolicy
->Length
, lpPolicy
->EndpointFlags
, lpPolicy
->NICFlags
);
541 ps
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(RpcServerProtseq
));
542 ps
->MaxCalls
= MaxCalls
;
543 ps
->Protseq
= RPCRT4_strdupA(Protseq
);
544 ps
->Endpoint
= RPCRT4_strdupA(Endpoint
);
546 return RPCRT4_use_protseq(ps
);
549 /***********************************************************************
550 * RpcServerUseProtseqEpExW (RPCRT4.@)
552 RPC_STATUS WINAPI
RpcServerUseProtseqEpExW( LPWSTR Protseq
, UINT MaxCalls
, LPWSTR Endpoint
, LPVOID SecurityDescriptor
,
553 PRPC_POLICY lpPolicy
)
555 RpcServerProtseq
* ps
;
557 TRACE("(%s,%u,%s,%p,{%u,%lu,%lu})\n", debugstr_w( Protseq
), MaxCalls
,
558 debugstr_w( Endpoint
), SecurityDescriptor
,
559 lpPolicy
->Length
, lpPolicy
->EndpointFlags
, lpPolicy
->NICFlags
);
561 ps
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(RpcServerProtseq
));
562 ps
->MaxCalls
= MaxCalls
;
563 /* FIXME: Did Ove have these next two as RPCRT4_strdupW for a reason? */
564 ps
->Protseq
= RPCRT4_strdupWtoA(Protseq
);
565 ps
->Endpoint
= RPCRT4_strdupWtoA(Endpoint
);
567 return RPCRT4_use_protseq(ps
);
570 /***********************************************************************
571 * RpcServerUseProtseqA (RPCRT4.@)
573 RPC_STATUS WINAPI
RpcServerUseProtseqA(LPSTR Protseq
, unsigned int MaxCalls
, void *SecurityDescriptor
)
575 TRACE("(Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)", debugstr_a(Protseq
), MaxCalls
, SecurityDescriptor
);
576 return RpcServerUseProtseqEpA(Protseq
, MaxCalls
, NULL
, SecurityDescriptor
);
579 /***********************************************************************
580 * RpcServerUseProtseqW (RPCRT4.@)
582 RPC_STATUS WINAPI
RpcServerUseProtseqW(LPWSTR Protseq
, unsigned int MaxCalls
, void *SecurityDescriptor
)
584 TRACE("Protseq == %s, MaxCalls == %d, SecurityDescriptor == ^%p)", debugstr_w(Protseq
), MaxCalls
, SecurityDescriptor
);
585 return RpcServerUseProtseqEpW(Protseq
, MaxCalls
, NULL
, SecurityDescriptor
);
588 /***********************************************************************
589 * RpcServerRegisterIf (RPCRT4.@)
591 RPC_STATUS WINAPI
RpcServerRegisterIf( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
)
593 TRACE("(%p,%s,%p)\n", IfSpec
, debugstr_guid(MgrTypeUuid
), MgrEpv
);
594 return RpcServerRegisterIf2( IfSpec
, MgrTypeUuid
, MgrEpv
, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT
, (UINT
)-1, NULL
);
597 /***********************************************************************
598 * RpcServerRegisterIfEx (RPCRT4.@)
600 RPC_STATUS WINAPI
RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
,
601 UINT Flags
, UINT MaxCalls
, RPC_IF_CALLBACK_FN
* IfCallbackFn
)
603 TRACE("(%p,%s,%p,%u,%u,%p)\n", IfSpec
, debugstr_guid(MgrTypeUuid
), MgrEpv
, Flags
, MaxCalls
, IfCallbackFn
);
604 return RpcServerRegisterIf2( IfSpec
, MgrTypeUuid
, MgrEpv
, Flags
, MaxCalls
, (UINT
)-1, IfCallbackFn
);
607 /***********************************************************************
608 * RpcServerRegisterIf2 (RPCRT4.@)
610 RPC_STATUS WINAPI
RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, RPC_MGR_EPV
* MgrEpv
,
611 UINT Flags
, UINT MaxCalls
, UINT MaxRpcSize
, RPC_IF_CALLBACK_FN
* IfCallbackFn
)
613 PRPC_SERVER_INTERFACE If
= (PRPC_SERVER_INTERFACE
)IfSpec
;
614 RpcServerInterface
* sif
;
617 TRACE("(%p,%s,%p,%u,%u,%u,%p)\n", IfSpec
, debugstr_guid(MgrTypeUuid
), MgrEpv
, Flags
, MaxCalls
,
618 MaxRpcSize
, IfCallbackFn
);
619 TRACE(" interface id: %s %d.%d\n", debugstr_guid(&If
->InterfaceId
.SyntaxGUID
),
620 If
->InterfaceId
.SyntaxVersion
.MajorVersion
,
621 If
->InterfaceId
.SyntaxVersion
.MinorVersion
);
622 TRACE(" transfer syntax: %s %d.%d\n", debugstr_guid(&If
->TransferSyntax
.SyntaxGUID
),
623 If
->TransferSyntax
.SyntaxVersion
.MajorVersion
,
624 If
->TransferSyntax
.SyntaxVersion
.MinorVersion
);
625 TRACE(" dispatch table: %p\n", If
->DispatchTable
);
626 if (If
->DispatchTable
) {
627 TRACE(" dispatch table count: %d\n", If
->DispatchTable
->DispatchTableCount
);
628 for (i
=0; i
<If
->DispatchTable
->DispatchTableCount
; i
++) {
629 TRACE(" entry %d: %p\n", i
, If
->DispatchTable
->DispatchTable
[i
]);
631 TRACE(" reserved: %ld\n", If
->DispatchTable
->Reserved
);
633 TRACE(" protseq endpoint count: %d\n", If
->RpcProtseqEndpointCount
);
634 TRACE(" default manager epv: %p\n", If
->DefaultManagerEpv
);
635 TRACE(" interpreter info: %p\n", If
->InterpreterInfo
);
636 TRACE(" flags: %08x\n", If
->Flags
);
638 sif
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(RpcServerInterface
));
641 memcpy(&sif
->MgrTypeUuid
, MgrTypeUuid
, sizeof(UUID
));
643 memset(&sif
->MgrTypeUuid
, 0, sizeof(UUID
));
644 sif
->MgrEpv
= MgrEpv
;
646 sif
->MaxCalls
= MaxCalls
;
647 sif
->MaxRpcSize
= MaxRpcSize
;
648 sif
->IfCallbackFn
= IfCallbackFn
;
650 EnterCriticalSection(&server_cs
);
653 LeaveCriticalSection(&server_cs
);
655 if (sif
->Flags
& RPC_IF_AUTOLISTEN
) {
656 /* well, start listening, I think... */
657 RPCRT4_start_listen();
663 /***********************************************************************
664 * RpcServerUnregisterIf (RPCRT4.@)
666 RPC_STATUS WINAPI
RpcServerUnregisterIf( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, UINT WaitForCallsToComplete
)
668 FIXME("(IfSpec == (RPC_IF_HANDLE)^%p, MgrTypeUuid == %s, WaitForCallsToComplete == %u): stub\n",
669 IfSpec
, debugstr_guid(MgrTypeUuid
), WaitForCallsToComplete
);
674 /***********************************************************************
675 * RpcServerUnregisterIfEx (RPCRT4.@)
677 RPC_STATUS WINAPI
RpcServerUnregisterIfEx( RPC_IF_HANDLE IfSpec
, UUID
* MgrTypeUuid
, int RundownContextHandles
)
679 FIXME("(IfSpec == (RPC_IF_HANDLE)^%p, MgrTypeUuid == %s, RundownContextHandles == %d): stub\n",
680 IfSpec
, debugstr_guid(MgrTypeUuid
), RundownContextHandles
);
685 /***********************************************************************
686 * RpcServerRegisterAuthInfoA (RPCRT4.@)
688 RPC_STATUS WINAPI
RpcServerRegisterAuthInfoA( LPSTR ServerPrincName
, ULONG AuthnSvc
, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn
,
691 FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName
, AuthnSvc
, GetKeyFn
, Arg
);
693 return RPC_S_UNKNOWN_AUTHN_SERVICE
; /* We don't know any authentication services */
696 /***********************************************************************
697 * RpcServerRegisterAuthInfoW (RPCRT4.@)
699 RPC_STATUS WINAPI
RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName
, ULONG AuthnSvc
, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn
,
702 FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName
), AuthnSvc
, GetKeyFn
, Arg
);
704 return RPC_S_UNKNOWN_AUTHN_SERVICE
; /* We don't know any authentication services */
707 /***********************************************************************
708 * RpcServerListen (RPCRT4.@)
710 RPC_STATUS WINAPI
RpcServerListen( UINT MinimumCallThreads
, UINT MaxCalls
, UINT DontWait
)
712 TRACE("(%u,%u,%u)\n", MinimumCallThreads
, MaxCalls
, DontWait
);
715 return RPC_S_NO_PROTSEQS_REGISTERED
;
717 EnterCriticalSection(&listen_cs
);
720 LeaveCriticalSection(&listen_cs
);
721 return RPC_S_ALREADY_LISTENING
;
724 RPCRT4_start_listen();
726 LeaveCriticalSection(&listen_cs
);
728 if (DontWait
) return RPC_S_OK
;
730 return RpcMgmtWaitServerListen();
733 /***********************************************************************
734 * RpcMgmtServerWaitListen (RPCRT4.@)
736 RPC_STATUS WINAPI
RpcMgmtWaitServerListen( void )
738 RPC_STATUS rslt
= RPC_S_OK
;
742 EnterCriticalSection(&listen_cs
);
745 if ( (rslt
= RpcServerListen(1, 0, TRUE
)) != RPC_S_OK
) {
746 LeaveCriticalSection(&listen_cs
);
750 LeaveCriticalSection(&listen_cs
);
753 WaitForSingleObject(mgr_event
, INFINITE
);
755 Sleep(100); /* don't spin violently */
756 TRACE("spinning.\n");
763 /***********************************************************************
764 * RpcMgmtStopServerListening (RPCRT4.@)
766 RPC_STATUS WINAPI
RpcMgmtStopServerListening ( RPC_BINDING_HANDLE Binding
)
768 TRACE("(Binding == (RPC_BINDING_HANDLE)^%p)\n", Binding
);
771 FIXME("client-side invocation not implemented.\n");
772 return RPC_S_WRONG_KIND_OF_BINDING
;
776 EnterCriticalSection(&listen_cs
);
778 RPCRT4_stop_listen();
779 LeaveCriticalSection(&listen_cs
);
784 /***********************************************************************
785 * I_RpcServerStartListening (RPCRT4.@)
787 RPC_STATUS WINAPI
I_RpcServerStartListening( void* hWnd
)
789 FIXME( "(%p): stub\n", hWnd
);
794 /***********************************************************************
795 * I_RpcServerStopListening (RPCRT4.@)
797 RPC_STATUS WINAPI
I_RpcServerStopListening( void )
799 FIXME( "(): stub\n" );
804 /***********************************************************************
805 * I_RpcWindowProc (RPCRT4.@)
807 UINT WINAPI
I_RpcWindowProc( void *hWnd
, UINT Message
, UINT wParam
, ULONG lParam
)
809 FIXME( "(%p,%08x,%08x,%08lx): stub\n", hWnd
, Message
, wParam
, lParam
);