Reimplement several RpcServer.* methods in rpc_server.c.
Implement RpcServerInqBindings, I_RpcServerStartListening,
I_RpcServerStopListening, and I_RpcWindowProc.

diff --git a/dlls/rpcrt4/Makefile.in b/dlls/rpcrt4/Makefile.in
index 8dc5797..d542e12 100644
--- a/dlls/rpcrt4/Makefile.in
+++ b/dlls/rpcrt4/Makefile.in
@@ -18,6 +18,7 @@
 	ndr_stubless.c \
 	rpc_binding.c \
 	rpc_message.c \
+	rpc_server.c \
 	rpcrt4_main.c
 
 SUBDIRS = tests
diff --git a/dlls/rpcrt4/rpc_server.c b/dlls/rpcrt4/rpc_server.c
new file mode 100644
index 0000000..af7c80b
--- /dev/null
+++ b/dlls/rpcrt4/rpc_server.c
@@ -0,0 +1,580 @@
+/*
+ * RPC server API
+ *
+ * Copyright 2001 Ove Kåven, TransGaming Technologies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * TODO:
+ *  - a whole lot
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "winreg.h"
+
+#include "rpc.h"
+
+#include "wine/debug.h"
+
+#include "rpc_server.h"
+#include "rpc_defs.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(ole);
+
+static RpcServerProtseq* protseqs;
+static RpcServerInterface* ifs;
+
+static CRITICAL_SECTION server_cs = CRITICAL_SECTION_INIT("RpcServer");
+static BOOL std_listen;
+static LONG listen_count = -1;
+static HANDLE mgr_event, server_thread;
+
+static RpcServerInterface* RPCRT4_find_interface(UUID* object, UUID* if_id)
+{
+  UUID* MgrType = NULL;
+  RpcServerInterface* cif = NULL;
+  RPC_STATUS status;
+
+  /* FIXME: object -> MgrType */
+  EnterCriticalSection(&server_cs);
+  cif = ifs;
+  while (cif) {
+    if (UuidEqual(if_id, &cif->If->InterfaceId.SyntaxGUID, &status) &&
+       UuidEqual(MgrType, &cif->MgrTypeUuid, &status) &&
+       (std_listen || (cif->Flags & RPC_IF_AUTOLISTEN))) break;
+    cif = cif->Next;
+  }
+  LeaveCriticalSection(&server_cs);
+  return cif;
+}
+
+static DWORD CALLBACK RPCRT4_io_thread(LPVOID the_arg)
+{
+  RpcBinding* bind = (RpcBinding*)the_arg;
+  RpcPktHdr hdr;
+  DWORD dwRead;
+  RPC_MESSAGE msg;
+  RpcServerInterface* sif;
+  RPC_DISPATCH_FUNCTION func;
+
+  memset(&msg, 0, sizeof(msg));
+  msg.Handle = (RPC_BINDING_HANDLE)bind;
+
+  for (;;) {
+    /* read packet header */
+#ifdef OVERLAPPED_WORKS
+    if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, &bind->ovl)) {
+      DWORD err = GetLastError();
+      if (err != ERROR_IO_PENDING) {
+        TRACE("connection lost, error=%08lx\n", err);
+        break;
+      }
+      if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) break;
+    }
+#else
+    if (!ReadFile(bind->conn, &hdr, sizeof(hdr), &dwRead, NULL)) {
+      TRACE("connection lost, error=%08lx\n", GetLastError());
+      break;
+    }
+#endif
+    if (dwRead != sizeof(hdr)) {
+      TRACE("protocol error\n");
+      break;
+    }
+
+    /* read packet body */
+    msg.BufferLength = hdr.len;
+    msg.Buffer = HeapAlloc(GetProcessHeap(), 0, msg.BufferLength);
+#ifdef OVERLAPPED_WORKS
+    if (!ReadFile(bind->conn, msg.Buffer, msg.BufferLength, &dwRead, &bind->ovl)) {
+      DWORD err = GetLastError();
+      if (err != ERROR_IO_PENDING) {
+        TRACE("connection lost, error=%08lx\n", err);
+        break;
+      }
+      if (!GetOverlappedResult(bind->conn, &bind->ovl, &dwRead, TRUE)) break;
+    }
+#else
+    if (!ReadFile(bind->conn, msg.Buffer, msg.BufferLength, &dwRead, NULL)) {
+      TRACE("connection lost, error=%08lx\n", GetLastError());
+      break;
+    }
+#endif
+    if (dwRead != hdr.len) {
+      TRACE("protocol error\n");
+      break;
+    }
+
+    sif = RPCRT4_find_interface(&hdr.object, &hdr.if_id);
+    if (sif) {
+      msg.RpcInterfaceInformation = sif->If;
+      /* associate object with binding (this is a bit of a hack...
+       * a new binding should probably be created for each object) */
+      RPCRT4_SetBindingObject(bind, &hdr.object);
+      /* process packet*/
+      switch (hdr.ptype) {
+      case PKT_REQUEST:
+       /* find dispatch function */
+       msg.ProcNum = hdr.opnum;
+       if (sif->Flags & RPC_IF_OLE) {
+         /* native ole32 always gives us a dispatch table with a single entry
+          * (I assume that's a wrapper for IRpcStubBuffer::Invoke) */
+         func = *sif->If->DispatchTable->DispatchTable;
+       } else {
+         if (msg.ProcNum >= sif->If->DispatchTable->DispatchTableCount) {
+           ERR("invalid procnum\n");
+           func = NULL;
+         }
+         func = sif->If->DispatchTable->DispatchTable[msg.ProcNum];
+       }
+
+       /* dispatch */
+       if (func) func(&msg);
+
+       /* prepare response packet */
+       hdr.ptype = PKT_RESPONSE;
+       break;
+      default:
+       ERR("unknown packet type\n");
+       goto no_reply;
+      }
+
+      /* write reply packet */
+      hdr.len = msg.BufferLength;
+      WriteFile(bind->conn, &hdr, sizeof(hdr), NULL, NULL);
+      WriteFile(bind->conn, msg.Buffer, msg.BufferLength, NULL, NULL);
+
+    no_reply:
+      /* un-associate object */
+      RPCRT4_SetBindingObject(bind, NULL);
+      msg.RpcInterfaceInformation = NULL;
+    }
+    else {
+      ERR("got RPC packet to unregistered interface %s\n", debugstr_guid(&hdr.if_id));
+    }
+
+    /* clean up */
+    HeapFree(GetProcessHeap(), 0, msg.Buffer);
+    msg.Buffer = NULL;
+  }
+  if (msg.Buffer) HeapFree(GetProcessHeap(), 0, msg.Buffer);
+  RPCRT4_DestroyBinding(bind);
+  return 0;
+}
+
+static void RPCRT4_new_client(RpcBinding* bind)
+{
+  bind->thread = CreateThread(NULL, 0, RPCRT4_io_thread, bind, 0, NULL);
+}
+
+static DWORD CALLBACK RPCRT4_server_thread(LPVOID the_arg)
+{
+  HANDLE m_event = mgr_event, b_handle;
+  HANDLE *objs = NULL;
+  DWORD count, res;
+  RpcServerProtseq* cps;
+  RpcBinding* bind;
+  RpcBinding* cbind;
+
+  for (;;) {
+    EnterCriticalSection(&server_cs);
+    /* open and count bindings */
+    count = 1;
+    cps = protseqs;
+    while (cps) {
+      bind = cps->bind;
+      while (bind) {
+       RPCRT4_OpenBinding(bind);
+        if (bind->ovl.hEvent) count++;
+        bind = bind->Next;
+      }
+      cps = cps->Next;
+    }
+    /* make array of bindings */
+    objs = HeapReAlloc(GetProcessHeap(), 0, objs, count*sizeof(HANDLE));
+    objs[0] = m_event;
+    count = 1;
+    cps = protseqs;
+    while (cps) {
+      bind = cps->bind;
+      while (bind) {
+        if (bind->ovl.hEvent) objs[count++] = bind->ovl.hEvent;
+        bind = bind->Next;
+      }
+      cps = cps->Next;
+    }
+    LeaveCriticalSection(&server_cs);
+
+    /* start waiting */
+    res = WaitForMultipleObjects(count, objs, FALSE, INFINITE);
+    if (res == WAIT_OBJECT_0) {
+      if (listen_count == -1) break;
+    }
+    else if (res == WAIT_FAILED) {
+      ERR("wait failed\n");
+    }
+    else {
+      b_handle = objs[res - WAIT_OBJECT_0];
+      /* find which binding got a RPC */
+      EnterCriticalSection(&server_cs);
+      bind = NULL;
+      cps = protseqs;
+      while (cps) {
+        bind = cps->bind;
+        while (bind) {
+          if (bind->ovl.hEvent == b_handle) break;
+          bind = bind->Next;
+        }
+        if (bind) break;
+        cps = cps->Next;
+      }
+      cbind = NULL;
+      if (bind) RPCRT4_SpawnBinding(&cbind, bind);
+      LeaveCriticalSection(&server_cs);
+      if (!bind) {
+        ERR("failed to locate binding for handle %d\n", b_handle);
+      }
+      if (cbind) RPCRT4_new_client(cbind);
+    }
+  }
+  HeapFree(GetProcessHeap(), 0, objs);
+  EnterCriticalSection(&server_cs);
+  /* close bindings */
+  cps = protseqs;
+  while (cps) {
+    bind = cps->bind;
+    while (bind) {
+      RPCRT4_CloseBinding(bind);
+      bind = bind->Next;
+    }
+    cps = cps->Next;
+  }
+  LeaveCriticalSection(&server_cs);
+  return 0;
+}
+
+static void RPCRT4_start_listen(void)
+{
+  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?) ---------------------------
+
+static void RPCRT4_stop_listen(void)
+{
+  HANDLE m_event = mgr_event;
+  if (InterlockedDecrement(&listen_count) < 0)
+    SetEvent(m_event);
+}
+
+--------------------- */
+
+static RPC_STATUS RPCRT4_use_protseq(RpcServerProtseq* ps)
+{
+  RPCRT4_CreateBindingA(&ps->bind, TRUE, ps->Protseq);
+  RPCRT4_CompleteBindingA(ps->bind, NULL, ps->Endpoint, NULL);
+
+  EnterCriticalSection(&server_cs);
+  ps->Next = protseqs;
+  protseqs = ps;
+  LeaveCriticalSection(&server_cs);
+
+  if (listen_count >= 0) SetEvent(mgr_event);
+
+  return RPC_S_OK;
+}
+
+/***********************************************************************
+ *             RpcServerInqBindings (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerInqBindings( RPC_BINDING_VECTOR** BindingVector )
+{
+  RPC_STATUS status;
+  DWORD count;
+  RpcServerProtseq* ps;
+  RpcBinding* bind;
+
+  EnterCriticalSection(&server_cs);
+  /* count bindings */
+  count = 0;
+  ps = protseqs;
+  while (ps) {
+    bind = ps->bind;
+    while (bind) {
+      count++;
+      bind = bind->Next;
+    }
+    ps = ps->Next;
+  }
+  if (count) {
+    /* export bindings */
+    *BindingVector = HeapAlloc(GetProcessHeap(), 0,
+                              sizeof(RPC_BINDING_VECTOR) +
+                              sizeof(RPC_BINDING_HANDLE)*(count-1));
+    (*BindingVector)->Count = count;
+    count = 0;
+    ps = protseqs;
+    while (ps) {
+      bind = ps->bind;
+      while (bind) {
+       RPCRT4_ExportBinding((RpcBinding**)&(*BindingVector)->BindingH[count],
+                            bind);
+       count++;
+       bind = bind->Next;
+      }
+      ps = ps->Next;
+    }
+    status = RPC_S_OK;
+  } else {
+    *BindingVector = NULL;
+    status = RPC_S_NO_BINDINGS;
+  }
+  LeaveCriticalSection(&server_cs);
+  return status;
+}
+
+/***********************************************************************
+ *             RpcServerUseProtseqEpA (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerUseProtseqEpA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor )
+{
+  RPC_POLICY policy;
+  
+  TRACE( "(%s,%u,%s,%p)\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor );
+  
+  /* This should provide the default behaviour */
+  policy.Length        = sizeof( policy );
+  policy.EndpointFlags = 0;
+  policy.NICFlags      = 0;
+  
+  return RpcServerUseProtseqEpExA( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy );
+}
+
+/***********************************************************************
+ *             RpcServerUseProtseqEpW (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerUseProtseqEpW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor )
+{
+  RPC_POLICY policy;
+  
+  TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor );
+  
+  /* This should provide the default behaviour */
+  policy.Length        = sizeof( policy );
+  policy.EndpointFlags = 0;
+  policy.NICFlags      = 0;
+  
+  return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy );
+}
+
+/***********************************************************************
+ *             RpcServerUseProtseqEpExA (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerUseProtseqEpExA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor,
+                                            PRPC_POLICY lpPolicy )
+{
+  RpcServerProtseq* ps;
+
+  TRACE("(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", debugstr_a( Protseq ), MaxCalls,
+       debugstr_a( Endpoint ), SecurityDescriptor,
+       lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
+
+  ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerProtseq));
+  ps->MaxCalls = MaxCalls;
+  ps->Protseq = RPCRT4_strdupA(Protseq);
+  ps->Endpoint = RPCRT4_strdupA(Endpoint);
+
+  return RPCRT4_use_protseq(ps);
+}
+
+/***********************************************************************
+ *             RpcServerUseProtseqEpExW (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerUseProtseqEpExW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor,
+                                            PRPC_POLICY lpPolicy )
+{
+  RpcServerProtseq* ps;
+
+  TRACE("(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", debugstr_w( Protseq ), MaxCalls,
+       debugstr_w( Endpoint ), SecurityDescriptor,
+       lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
+
+  ps = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerProtseq));
+  ps->MaxCalls = MaxCalls;
+  /* FIXME: Did Ove have these next two as RPCRT4_strdupW for a reason? */
+  ps->Protseq = RPCRT4_strdupWtoA(Protseq);
+  ps->Endpoint = RPCRT4_strdupWtoA(Endpoint);
+
+  return RPCRT4_use_protseq(ps);
+}
+
+/***********************************************************************
+ *             RpcServerRegisterIf (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerRegisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv )
+{
+  TRACE("(%p,%s,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv);
+  return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT, (UINT)-1, NULL );
+}
+
+/***********************************************************************
+ *             RpcServerRegisterIfEx (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
+                       UINT Flags, UINT MaxCalls, RPC_IF_CALLBACK_FN* IfCallbackFn )
+{
+  TRACE("(%p,%s,%p,%u,%u,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv, Flags, MaxCalls, IfCallbackFn);
+  return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, Flags, MaxCalls, (UINT)-1, IfCallbackFn );
+}
+
+/***********************************************************************
+ *             RpcServerRegisterIf2 (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
+                      UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn )
+{
+  PRPC_SERVER_INTERFACE If = (PRPC_SERVER_INTERFACE)IfSpec;
+  RpcServerInterface* sif;
+  int i;
+
+  TRACE("(%p,%s,%p,%u,%u,%u,%p)\n", IfSpec, debugstr_guid(MgrTypeUuid), MgrEpv, Flags, MaxCalls,
+         MaxRpcSize, IfCallbackFn);
+  TRACE(" interface id: %s %d.%d\n", debugstr_guid(&If->InterfaceId.SyntaxGUID),
+                                     If->InterfaceId.SyntaxVersion.MajorVersion,
+                                     If->InterfaceId.SyntaxVersion.MinorVersion);
+  TRACE(" transfer syntax: %s %d.%d\n", debugstr_guid(&If->InterfaceId.SyntaxGUID),
+                                        If->InterfaceId.SyntaxVersion.MajorVersion,
+                                        If->InterfaceId.SyntaxVersion.MinorVersion);
+  TRACE(" dispatch table: %p\n", If->DispatchTable);
+  if (If->DispatchTable) {
+    TRACE("  dispatch table count: %d\n", If->DispatchTable->DispatchTableCount);
+    for (i=0; i<If->DispatchTable->DispatchTableCount; i++) {
+      TRACE("   entry %d: %p\n", i, If->DispatchTable->DispatchTable[i]);
+    }
+    TRACE("  reserved: %ld\n", If->DispatchTable->Reserved);
+  }
+  TRACE(" protseq endpoint count: %d\n", If->RpcProtseqEndpointCount);
+  TRACE(" default manager epv: %p\n", If->DefaultManagerEpv);
+  TRACE(" interpreter info: %p\n", If->InterpreterInfo);
+  TRACE(" flags: %08x\n", If->Flags);
+
+  sif = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(RpcServerInterface));
+  sif->If           = If;
+  if (MgrTypeUuid)
+    memcpy(&sif->MgrTypeUuid, MgrTypeUuid, sizeof(UUID));
+  else
+    memset(&sif->MgrTypeUuid, 0, sizeof(UUID));
+  sif->MgrEpv       = MgrEpv;
+  sif->Flags        = Flags;
+  sif->MaxCalls     = MaxCalls;
+  sif->MaxRpcSize   = MaxRpcSize;
+  sif->IfCallbackFn = IfCallbackFn;
+
+  EnterCriticalSection(&server_cs);
+  sif->Next = ifs;
+  ifs = sif;
+  LeaveCriticalSection(&server_cs);
+
+  if (sif->Flags & RPC_IF_AUTOLISTEN) {
+    /* well, start listening, I think... */
+    RPCRT4_start_listen();
+  }
+
+  return RPC_S_OK;
+}
+
+/***********************************************************************
+ *             RpcServerRegisterAuthInfoA (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( LPSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
+                            LPVOID Arg )
+{
+  FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg );
+  
+  return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
+}
+
+/***********************************************************************
+ *             RpcServerRegisterAuthInfoW (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
+                            LPVOID Arg )
+{
+  FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg );
+  
+  return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
+}
+
+/***********************************************************************
+ *             RpcServerListen (RPCRT4.@)
+ */
+RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait )
+{
+  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;
+  RPCRT4_start_listen();
+
+  if (DontWait) return RPC_S_OK;
+
+  /* RpcMgmtWaitServerListen(); */
+  FIXME("can't wait yet\n");
+  return RPC_S_OK;
+}
+
+/***********************************************************************
+ *             I_RpcServerStartListening (RPCRT4.@)
+ */
+RPC_STATUS WINAPI I_RpcServerStartListening( void* hWnd )
+{
+  FIXME( "(%p): stub\n", hWnd );
+
+  return RPC_S_OK;
+}
+
+/***********************************************************************
+ *             I_RpcServerStopListening (RPCRT4.@)
+ */
+RPC_STATUS WINAPI I_RpcServerStopListening( void )
+{
+  FIXME( "(): stub\n" );
+
+  return RPC_S_OK;
+}
+
+/***********************************************************************
+ *             I_RpcWindowProc (RPCRT4.@)
+ */
+UINT WINAPI I_RpcWindowProc( void* hWnd, UINT Message, UINT wParam, ULONG lParam )
+{
+  FIXME( "(%p,%08x,%08x,%08lx): stub\n", hWnd, Message, wParam, lParam );
+
+  return 0;
+}
diff --git a/dlls/rpcrt4/rpc_server.h b/dlls/rpcrt4/rpc_server.h
new file mode 100644
index 0000000..da15d84
--- /dev/null
+++ b/dlls/rpcrt4/rpc_server.h
@@ -0,0 +1,47 @@
+/*
+ * RPC server API
+ *
+ * Copyright 2001 Ove Kåven, TransGaming Technologies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef __WINE_RPC_SERVER_H
+#define __WINE_RPC_SERVER_H
+
+#include "rpc_binding.h"
+
+typedef struct _RpcServerProtseq
+{
+  struct _RpcServerProtseq* Next;
+  LPSTR Protseq;
+  LPSTR Endpoint;
+  UINT MaxCalls;
+  RpcBinding* bind;
+} RpcServerProtseq;
+
+typedef struct _RpcServerInterface
+{
+  struct _RpcServerInterface* Next;
+  RPC_SERVER_INTERFACE* If;
+  UUID MgrTypeUuid;
+  RPC_MGR_EPV* MgrEpv;
+  UINT Flags;
+  UINT MaxCalls;
+  UINT MaxRpcSize;
+  RPC_IF_CALLBACK_FN* IfCallbackFn;
+} RpcServerInterface;
+
+#endif  /* __WINE_RPC_SERVER_H */
diff --git a/dlls/rpcrt4/rpcrt4.spec b/dlls/rpcrt4/rpcrt4.spec
index ca749ce..a99e7b1 100644
--- a/dlls/rpcrt4/rpcrt4.spec
+++ b/dlls/rpcrt4/rpcrt4.spec
@@ -105,7 +105,7 @@
 @ stub RpcRegisterAsyncInfo
 @ stub RpcRevertToSelf
 @ stub RpcRevertToSelfEx
-@ stub RpcServerInqBindings
+@ stdcall RpcServerInqBindings(ptr) RpcServerInqBindings
 @ stub RpcServerInqDefaultPrincNameA
 @ stub RpcServerInqDefaultPrincNameW
 @ stub RpcServerInqIf
@@ -467,8 +467,8 @@
 @ stub I_RpcServerInqTransportType
 @ stub I_RpcServerRegisterForwardFunction
 @ stub I_RpcServerSetAddressChangeFn
-@ stub I_RpcServerStartListening # win9x
-@ stub I_RpcServerStopListening # win9x
+@ stdcall I_RpcServerStartListening(ptr) I_RpcServerStartListening # win9x
+@ stdcall I_RpcServerStopListening() I_RpcServerStopListening # win9x
 @ stub I_RpcServerUnregisterEndpointA # win9x
 @ stub I_RpcServerUnregisterEndpointW # win9x
 @ stub I_RpcServerUseProtseq2A
@@ -505,7 +505,7 @@
 @ stub I_RpcTransServerReallocBuffer # win9x
 @ stub I_RpcTransServerReceiveDirectReady # win9x
 @ stub I_RpcTransServerUnprotectThread # win9x
-@ stub I_RpcWindowProc # win9x
+@ stdcall I_RpcWindowProc(ptr long long long) I_RpcWindowProc # win9x
 @ stub I_RpcltDebugSetPDUFilter
 @ stub I_UuidCreate
 
diff --git a/dlls/rpcrt4/rpcrt4_main.c b/dlls/rpcrt4/rpcrt4_main.c
index 9977beb..94e23fc 100644
--- a/dlls/rpcrt4/rpcrt4_main.c
+++ b/dlls/rpcrt4/rpcrt4_main.c
@@ -591,134 +591,6 @@
 }
 
 /***********************************************************************
- *		RpcServerUseProtseqEpA (RPCRT4.@)
- */
-
-RPC_STATUS WINAPI RpcServerUseProtseqEpA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor )
-{
-  RPC_POLICY policy;
-
-  TRACE( "(%s,%u,%s,%p)\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor );
-
-  /* This should provide the default behaviour */
-  policy.Length        = sizeof( policy );
-  policy.EndpointFlags = 0;
-  policy.NICFlags      = 0;
-
-  return RpcServerUseProtseqEpExA( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy );
-}
-
-/***********************************************************************
- *		RpcServerUseProtseqEpW (RPCRT4.@)
- */
-RPC_STATUS WINAPI RpcServerUseProtseqEpW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor )
-{
-  RPC_POLICY policy;
-
-  TRACE( "(%s,%u,%s,%p)\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ), SecurityDescriptor );
-
-  /* This should provide the default behaviour */
-  policy.Length        = sizeof( policy );
-  policy.EndpointFlags = 0;
-  policy.NICFlags      = 0;
-
-  return RpcServerUseProtseqEpExW( Protseq, MaxCalls, Endpoint, SecurityDescriptor, &policy );
-}
-
-/***********************************************************************
- *		RpcServerUseProtseqEpExA (RPCRT4.@)
- */
-RPC_STATUS WINAPI RpcServerUseProtseqEpExA( LPSTR Protseq, UINT MaxCalls, LPSTR Endpoint, LPVOID SecurityDescriptor,
-                          PRPC_POLICY lpPolicy )
-{
-  FIXME( "(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", Protseq, MaxCalls, Endpoint, SecurityDescriptor,
-                                               lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
-
-  return RPC_S_PROTSEQ_NOT_SUPPORTED; /* We don't support anything at this point */
-}
-
-/***********************************************************************
- *		RpcServerUseProtseqEpExW (RPCRT4.@)
- */
-RPC_STATUS WINAPI RpcServerUseProtseqEpExW( LPWSTR Protseq, UINT MaxCalls, LPWSTR Endpoint, LPVOID SecurityDescriptor,
-                          PRPC_POLICY lpPolicy )
-{
-  FIXME( "(%s,%u,%s,%p,{%u,%lu,%lu}): stub\n", debugstr_w( Protseq ), MaxCalls, debugstr_w( Endpoint ),
-                                               SecurityDescriptor,
-                                               lpPolicy->Length, lpPolicy->EndpointFlags, lpPolicy->NICFlags );
-
-  return RPC_S_PROTSEQ_NOT_SUPPORTED; /* We don't support anything at this point */
-}
-
-/***********************************************************************
- *		RpcServerRegisterIf (RPCRT4.@)
- */
-RPC_STATUS WINAPI RpcServerRegisterIf( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv )
-{
-  /* FIXME: Dump UUID using UuidToStringA */
-  TRACE( "(%p,%p,%p)\n", IfSpec, MgrTypeUuid, MgrEpv );
-
-  return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, 0, RPC_C_LISTEN_MAX_CALLS_DEFAULT, (UINT)-1, NULL );
-}
-
-/***********************************************************************
- *		RpcServerRegisterIfEx (RPCRT4.@)
- */
-RPC_STATUS WINAPI RpcServerRegisterIfEx( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
-                       UINT Flags, UINT MaxCalls, RPC_IF_CALLBACK_FN* IfCallbackFn )
-{
-  /* FIXME: Dump UUID using UuidToStringA */
-  TRACE( "(%p,%p,%p,%u,%u,%p)\n", IfSpec, MgrTypeUuid, MgrEpv, Flags, MaxCalls, IfCallbackFn );
-
-  return RpcServerRegisterIf2( IfSpec, MgrTypeUuid, MgrEpv, Flags, MaxCalls, (UINT)-1, IfCallbackFn );
-}
-
-/***********************************************************************
- *		RpcServerRegisterIf2 (RPCRT4.@)
- */
-RPC_STATUS WINAPI RpcServerRegisterIf2( RPC_IF_HANDLE IfSpec, UUID* MgrTypeUuid, RPC_MGR_EPV* MgrEpv,
-                      UINT Flags, UINT MaxCalls, UINT MaxRpcSize, RPC_IF_CALLBACK_FN* IfCallbackFn )
-{
-  /* FIXME: Dump UUID using UuidToStringA */
-  FIXME( "(%p,%p,%p,%u,%u,%u,%p): stub\n", IfSpec, MgrTypeUuid, MgrEpv, Flags, MaxCalls, MaxRpcSize, IfCallbackFn );
-
-  return RPC_S_UNKNOWN_IF; /* I guess this return code is as good as any failure */
-}
-
-
-/***********************************************************************
- *		RpcServerRegisterAuthInfoA (RPCRT4.@)
- */
-RPC_STATUS WINAPI RpcServerRegisterAuthInfoA( LPSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
-                            LPVOID Arg )
-{
-  FIXME( "(%s,%lu,%p,%p): stub\n", ServerPrincName, AuthnSvc, GetKeyFn, Arg );
-
-  return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
-}
-
-/***********************************************************************
- *		RpcServerRegisterAuthInfoW (RPCRT4.@)
- */
-RPC_STATUS WINAPI RpcServerRegisterAuthInfoW( LPWSTR ServerPrincName, ULONG AuthnSvc, RPC_AUTH_KEY_RETRIEVAL_FN GetKeyFn,
-                            LPVOID Arg )
-{
-  FIXME( "(%s,%lu,%p,%p): stub\n", debugstr_w( ServerPrincName ), AuthnSvc, GetKeyFn, Arg );
-
-  return RPC_S_UNKNOWN_AUTHN_SERVICE; /* We don't know any authentication services */
-}
-
-/***********************************************************************
- *		RpcServerListen (RPCRT4.@)
- */
-RPC_STATUS WINAPI RpcServerListen( UINT MinimumCallThreads, UINT MaxCalls, UINT DontWait )
-{
-  FIXME( "(%u,%u,%u): stub\n", MinimumCallThreads, MaxCalls, DontWait );
-
-  return RPC_S_NO_PROTSEQS_REGISTERED; /* Since we don't allow registration this seems reasonable */
-}
-
-/***********************************************************************
  *              DllRegisterServer (RPCRT4.@)
  */