Rob Shearman : ole32: Close the named pipe after revoking local server objects.

Alexandre Julliard julliard at wine.codeweavers.com
Fri Mar 9 15:47:46 CST 2007


Module: wine
Branch: master
Commit: 880542a9f87ec7a2b023753f7e192582b478737f
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=880542a9f87ec7a2b023753f7e192582b478737f

Author: Rob Shearman <rob at codeweavers.com>
Date:   Fri Mar  9 17:42:34 2007 +0000

ole32: Close the named pipe after revoking local server objects.

---

 dlls/ole32/compobj.c         |    9 ++++++++-
 dlls/ole32/compobj_private.h |    3 ++-
 dlls/ole32/rpc.c             |   37 +++++++++++++++++++++++++++++++------
 3 files changed, 41 insertions(+), 8 deletions(-)

diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c
index bac067a..98ec995 100644
--- a/dlls/ole32/compobj.c
+++ b/dlls/ole32/compobj.c
@@ -123,6 +123,7 @@ typedef struct tagRegisteredClass
   DWORD     connectFlags;
   DWORD     dwCookie;
   LPSTREAM  pMarshaledData; /* FIXME: only really need to store OXID and IPID */
+  void     *RpcRegistration;
   struct tagRegisteredClass* nextClass;
 } RegisteredClass;
 
@@ -1574,6 +1575,7 @@ HRESULT WINAPI CoRegisterClassObject(
   newClass->runContext      = dwClsContext;
   newClass->connectFlags    = flags;
   newClass->pMarshaledData  = NULL;
+  newClass->RpcRegistration = NULL;
 
   /*
    * Use the address of the chain node as the cookie since we are sure it's
@@ -1618,7 +1620,9 @@ HRESULT WINAPI CoRegisterClassObject(
 
       IUnknown_Release(classfac);
 
-      RPC_StartLocalServer(&newClass->classIdentifier, newClass->pMarshaledData);
+      hr = RPC_StartLocalServer(&newClass->classIdentifier,
+                                newClass->pMarshaledData,
+                                &newClass->RpcRegistration);
   }
   return S_OK;
 }
@@ -1667,6 +1671,9 @@ HRESULT WINAPI CoRevokeClassObject(
        */
       *prevClassLink = curClass->nextClass;
 
+      if (curClass->runContext & CLSCTX_LOCAL_SERVER)
+        RPC_StopLocalServer(curClass->RpcRegistration);
+
       /*
        * Release the reference to the class object.
        */
diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h
index b77e05f..4c96a3c 100644
--- a/dlls/ole32/compobj_private.h
+++ b/dlls/ole32/compobj_private.h
@@ -221,7 +221,8 @@ HRESULT RPC_CreateServerChannel(IRpcChannelBuffer **chan);
 void    RPC_ExecuteCall(struct dispatch_params *params);
 HRESULT RPC_RegisterInterface(REFIID riid);
 void    RPC_UnregisterInterface(REFIID riid);
-void    RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
+HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, void **registration);
+void    RPC_StopLocalServer(void *registration);
 HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
 HRESULT RPC_RegisterChannelHook(REFGUID rguid, IChannelHook *hook);
 void    RPC_UnregisterAllChannelHooks(void);
diff --git a/dlls/ole32/rpc.c b/dlls/ole32/rpc.c
index fdb81ed..3320552 100644
--- a/dlls/ole32/rpc.c
+++ b/dlls/ole32/rpc.c
@@ -1732,6 +1732,7 @@ struct local_server_params
     CLSID clsid;
     IStream *stream;
     HANDLE ready_event;
+    HANDLE pipe;
 };
 
 /* FIXME: should call to rpcss instead */
@@ -1757,6 +1758,7 @@ static DWORD WINAPI local_server_thread(LPVOID param)
                               PIPE_TYPE_BYTE|PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
                               4096, 4096, 500 /* 0.5 second timeout */, NULL );
 
+    lsp->pipe = hPipe;
     SetEvent(lsp->ready_event);
 
     HeapFree(GetProcessHeap(), 0, lsp);
@@ -1768,9 +1770,21 @@ static DWORD WINAPI local_server_thread(LPVOID param)
     }
     
     while (1) {
-        if (!ConnectNamedPipe(hPipe,NULL) && GetLastError() != ERROR_PIPE_CONNECTED) {
-            ERR("Failure during ConnectNamedPipe %u, ABORT!\n",GetLastError());
-            break;
+        if (!ConnectNamedPipe(hPipe,NULL))
+        {
+            DWORD error = GetLastError();
+            /* client already connected isn't an error */
+            if (error != ERROR_PIPE_CONNECTED)
+            {
+                /* if error wasn't caused by RPC_StopLocalServer closing the
+                 * pipe for us */
+                if (error != ERROR_INVALID_HANDLE)
+                {
+                    ERR("Failure during ConnectNamedPipe %u\n", error);
+                    CloseHandle(hPipe);
+                }
+                break;
+            }
         }
 
         TRACE("marshalling IClassFactory to client\n");
@@ -1804,12 +1818,12 @@ static DWORD WINAPI local_server_thread(LPVOID param)
 
         TRACE("done marshalling IClassFactory\n");
     }
-    CloseHandle(hPipe);
     IStream_Release(pStm);
     return 0;
 }
 
-void RPC_StartLocalServer(REFCLSID clsid, IStream *stream)
+/* starts listening for a local server */
+HRESULT RPC_StartLocalServer(REFCLSID clsid, IStream *stream, void **registration)
 {
     DWORD tid;
     HANDLE thread, ready_event;
@@ -1821,9 +1835,20 @@ void RPC_StartLocalServer(REFCLSID clsid, IStream *stream)
     lsp->ready_event = ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
 
     thread = CreateThread(NULL, 0, local_server_thread, lsp, 0, &tid);
+    if (!thread)
+        return HRESULT_FROM_WIN32(GetLastError());
     CloseHandle(thread);
-    /* FIXME: failure handling */
 
     WaitForSingleObject(ready_event, INFINITE);
     CloseHandle(ready_event);
+
+    *registration = lsp->pipe;
+    return S_OK;
+}
+
+/* stops listening for a local server */
+void RPC_StopLocalServer(void *registration)
+{
+    HANDLE pipe = registration;
+    CloseHandle(pipe);
 }




More information about the wine-cvs mailing list