Autosyncing with Wine HEAD
authorThe Wine Synchronizer <winesync@svn.reactos.org>
Fri, 27 Jul 2007 09:49:52 +0000 (09:49 +0000)
committerThe Wine Synchronizer <winesync@svn.reactos.org>
Fri, 27 Jul 2007 09:49:52 +0000 (09:49 +0000)
svn path=/trunk/; revision=27912

30 files changed:
reactos/dll/win32/ole32/classmoniker.c
reactos/dll/win32/ole32/compobj.c
reactos/dll/win32/ole32/compobj_private.h
reactos/dll/win32/ole32/dictionary.c
reactos/dll/win32/ole32/enumx.c
reactos/dll/win32/ole32/enumx.h
reactos/dll/win32/ole32/errorinfo.c
reactos/dll/win32/ole32/filemoniker.c
reactos/dll/win32/ole32/git.c
reactos/dll/win32/ole32/hglobalstream.c
reactos/dll/win32/ole32/ifs.c
reactos/dll/win32/ole32/marshal.c
reactos/dll/win32/ole32/ole16.c
reactos/dll/win32/ole32/ole2.c
reactos/dll/win32/ole32/ole2_16.c
reactos/dll/win32/ole32/ole2impl.c
reactos/dll/win32/ole32/ole2nls.c
reactos/dll/win32/ole32/ole32.rbuild
reactos/dll/win32/ole32/ole32.spec
reactos/dll/win32/ole32/ole32_main.c
reactos/dll/win32/ole32/ole32_ros.diff [deleted file]
reactos/dll/win32/ole32/oleproxy.c
reactos/dll/win32/ole32/rpc.c
reactos/dll/win32/ole32/stg_bigblockfile.c
reactos/dll/win32/ole32/stg_prop.c
reactos/dll/win32/ole32/stg_stream.c
reactos/dll/win32/ole32/storage.c
reactos/dll/win32/ole32/storage32.c
reactos/dll/win32/ole32/storage32.h
reactos/dll/win32/ole32/stubmanager.c

index 07db622..514990a 100644 (file)
@@ -31,7 +31,6 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winuser.h"
-#include "winnls.h"
 #include "wine/debug.h"
 #include "ole2.h"
 #include "wine/unicode.h"
index af43074..662b42a 100644 (file)
@@ -76,9 +76,10 @@ HINSTANCE OLE32_hInstance = 0; /* FIXME: make static ... */
  * TODO: Most of these things will have to be made thread-safe.
  */
 
-static HRESULT COM_GetRegisteredClassObject(REFCLSID rclsid, DWORD dwClsContext, LPUNKNOWN*  ppUnk);
-static void COM_RevokeAllClasses(void);
-static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv);
+static HRESULT COM_GetRegisteredClassObject(const struct apartment *apt, REFCLSID rclsid,
+                                            DWORD dwClsContext, LPUNKNOWN*  ppUnk);
+static void COM_RevokeAllClasses(const struct apartment *apt);
+static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv);
 
 static APARTMENT *MTA; /* protected by csApartment */
 static APARTMENT *MainApartment; /* the first STA apartment */
@@ -121,6 +122,7 @@ typedef struct tagRegisteredClass
 {
   struct list entry;
   CLSID     classIdentifier;
+  OXID      apartment_id;
   LPUNKNOWN classObject;
   DWORD     runContext;
   DWORD     connectFlags;
@@ -186,10 +188,11 @@ static const WCHAR wszAptWinClass[] = {'O','l','e','M','a','i','n','T','h','r','
 static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
 static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
                                         REFCLSID rclsid, REFIID riid, void **ppv);
+static void apartment_freeunusedlibraries(struct apartment *apt);
 
 static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret);
 static OpenDll *COMPOBJ_DllList_Get(LPCWSTR library_name);
-static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry);
+static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry, BOOL free_entry);
 
 static DWORD COM_RegReadPath(HKEY hkeyroot, const WCHAR *keyname, const WCHAR *valuename, WCHAR * dst, DWORD dstlen);
 
@@ -325,7 +328,7 @@ static APARTMENT *apartment_get_or_create(DWORD model)
     return apt;
 }
 
-static inline BOOL apartment_is_model(APARTMENT *apt, DWORD model)
+static inline BOOL apartment_is_model(const APARTMENT *apt, DWORD model)
 {
     return (apt->multi_threaded == !(model & COINIT_APARTMENTTHREADED));
 }
@@ -361,12 +364,16 @@ DWORD apartment_release(struct apartment *apt)
 
         TRACE("destroying apartment %p, oxid %s\n", apt, wine_dbgstr_longlong(apt->oxid));
 
+        /* Release the references to the registered class objects */
+        COM_RevokeAllClasses(apt);
+
         /* no locking is needed for this apartment, because no other thread
          * can access it at this point */
 
         apartment_disconnectproxies(apt);
 
         if (apt->win) DestroyWindow(apt->win);
+        if (apt->host_apt_tid) PostThreadMessageW(apt->host_apt_tid, WM_QUIT, 0, 0);
 
         LIST_FOR_EACH_SAFE(cursor, cursor2, &apt->stubmgrs)
         {
@@ -395,10 +402,16 @@ DWORD apartment_release(struct apartment *apt)
 
         if (apt->filter) IUnknown_Release(apt->filter);
 
+        /* free as many unused libraries as possible... */
+        apartment_freeunusedlibraries(apt);
+
+        /* ... and free the memory for the apartment loaded dll entry and
+         * release the dll list reference without freeing the library for the
+         * rest */
         while ((cursor = list_head(&apt->loaded_dlls)))
         {
             struct apartment_loaded_dll *apartment_loaded_dll = LIST_ENTRY(cursor, struct apartment_loaded_dll, entry);
-            COMPOBJ_DllList_ReleaseRef(apartment_loaded_dll->dll);
+            COMPOBJ_DllList_ReleaseRef(apartment_loaded_dll->dll, FALSE);
             list_remove(cursor);
             HeapFree(GetProcessHeap(), 0, apartment_loaded_dll);
         }
@@ -462,33 +475,18 @@ APARTMENT *apartment_findfromtid(DWORD tid)
     return result;
 }
 
-/* gets an apartment which has a given type. The caller must
+/* gets the main apartment if it exists. The caller must
  * release the reference from the apartment as soon as the apartment pointer
  * is no longer required. */
-static APARTMENT *apartment_findfromtype(BOOL multi_threaded, BOOL main_apartment)
+static APARTMENT *apartment_findmain(void)
 {
-    APARTMENT *result = NULL;
-    struct apartment *apt;
+    APARTMENT *result;
 
     EnterCriticalSection(&csApartment);
 
-    if (!multi_threaded && main_apartment)
-    {
-        result = MainApartment;
-        if (result) apartment_addref(result);
-        LeaveCriticalSection(&csApartment);
-        return result;
-    }
+    result = MainApartment;
+    if (result) apartment_addref(result);
 
-    LIST_FOR_EACH_ENTRY( apt, &apts, struct apartment, entry )
-    {
-        if (apt->multi_threaded == multi_threaded)
-        {
-            result = apt;
-            apartment_addref(result);
-            break;
-        }
-    }
     LeaveCriticalSection(&csApartment);
 
     return result;
@@ -499,6 +497,8 @@ struct host_object_params
     HKEY hkeydll;
     CLSID clsid; /* clsid of object to marshal */
     IID iid; /* interface to marshal */
+    HANDLE event; /* event signalling when ready for multi-threaded case */
+    HRESULT hr; /* result for multi-threaded case */
     IStream *stream; /* stream that the object will be marshaled into */
 };
 
@@ -510,7 +510,7 @@ static HRESULT apartment_hostobject(struct apartment *apt,
     static const LARGE_INTEGER llZero;
     WCHAR dllpath[MAX_PATH+1];
 
-    TRACE("\n");
+    TRACE("clsid %s, iid %s\n", debugstr_guid(&params->clsid), debugstr_guid(&params->iid));
 
     if (COM_RegReadPath(params->hkeydll, NULL, NULL, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
     {
@@ -545,6 +545,167 @@ static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LP
     }
 }
 
+struct host_thread_params
+{
+    COINIT threading_model;
+    HANDLE ready_event;
+    HWND apartment_hwnd;
+};
+
+static DWORD CALLBACK apartment_hostobject_thread(LPVOID p)
+{
+    struct host_thread_params *params = p;
+    MSG msg;
+    HRESULT hr;
+    struct apartment *apt;
+
+    TRACE("\n");
+
+    hr = CoInitializeEx(NULL, params->threading_model);
+    if (FAILED(hr)) return hr;
+
+    apt = COM_CurrentApt();
+    if (params->threading_model == COINIT_APARTMENTTHREADED)
+    {
+        apartment_createwindowifneeded(apt);
+        params->apartment_hwnd = apartment_getwindow(apt);
+    }
+    else
+        params->apartment_hwnd = NULL;
+
+    /* force the message queue to be created before signaling parent thread */
+    PeekMessageW(&msg, NULL, WM_USER, WM_USER, PM_NOREMOVE);
+
+    SetEvent(params->ready_event);
+    params = NULL; /* can't touch params after here as it may be invalid */
+
+    while (GetMessageW(&msg, NULL, 0, 0))
+    {
+        if (!msg.hwnd && (msg.message == DM_HOSTOBJECT))
+        {
+            struct host_object_params *params = (struct host_object_params *)msg.lParam;
+            params->hr = apartment_hostobject(apt, params);
+            SetEvent(params->event);
+        }
+        else
+        {
+            TranslateMessage(&msg);
+            DispatchMessageW(&msg);
+        }
+    }
+
+    TRACE("exiting\n");
+
+    CoUninitialize();
+
+    return S_OK;
+}
+
+static HRESULT apartment_hostobject_in_hostapt(struct apartment *apt, BOOL multi_threaded, BOOL main_apartment, HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv)
+{
+    struct host_object_params params;
+    HWND apartment_hwnd = NULL;
+    DWORD apartment_tid = 0;
+    HRESULT hr;
+
+    if (!multi_threaded && main_apartment)
+    {
+        APARTMENT *host_apt = apartment_findmain();
+        if (host_apt)
+        {
+            apartment_hwnd = apartment_getwindow(host_apt);
+            apartment_release(host_apt);
+        }
+    }
+
+    if (!apartment_hwnd)
+    {
+        EnterCriticalSection(&apt->cs);
+
+        if (!apt->host_apt_tid)
+        {
+            struct host_thread_params thread_params;
+            HANDLE handles[2];
+            DWORD wait_value;
+
+            thread_params.threading_model = multi_threaded ? COINIT_MULTITHREADED : COINIT_APARTMENTTHREADED;
+            handles[0] = thread_params.ready_event = CreateEventW(NULL, FALSE, FALSE, NULL);
+            thread_params.apartment_hwnd = NULL;
+            handles[1] = CreateThread(NULL, 0, apartment_hostobject_thread, &thread_params, 0, &apt->host_apt_tid);
+            if (!handles[1])
+            {
+                CloseHandle(handles[0]);
+                LeaveCriticalSection(&apt->cs);
+                return E_OUTOFMEMORY;
+            }
+            wait_value = WaitForMultipleObjects(2, handles, FALSE, INFINITE);
+            CloseHandle(handles[0]);
+            CloseHandle(handles[1]);
+            if (wait_value == WAIT_OBJECT_0)
+                apt->host_apt_hwnd = thread_params.apartment_hwnd;
+            else
+            {
+                LeaveCriticalSection(&apt->cs);
+                return E_OUTOFMEMORY;
+            }
+        }
+
+        if (multi_threaded || !main_apartment)
+        {
+            apartment_hwnd = apt->host_apt_hwnd;
+            apartment_tid = apt->host_apt_tid;
+        }
+
+        LeaveCriticalSection(&apt->cs);
+    }
+
+    /* another thread may have become the main apartment in the time it took
+     * us to create the thread for the host apartment */
+    if (!apartment_hwnd && !multi_threaded && main_apartment)
+    {
+        APARTMENT *host_apt = apartment_findmain();
+        if (host_apt)
+        {
+            apartment_hwnd = apartment_getwindow(host_apt);
+            apartment_release(host_apt);
+        }
+    }
+
+    params.hkeydll = hkeydll;
+    params.clsid = *rclsid;
+    params.iid = *riid;
+    hr = CreateStreamOnHGlobal(NULL, TRUE, &params.stream);
+    if (FAILED(hr))
+        return hr;
+    if (multi_threaded)
+    {
+        params.hr = S_OK;
+        params.event = CreateEventW(NULL, FALSE, FALSE, NULL);
+        if (!PostThreadMessageW(apartment_tid, DM_HOSTOBJECT, 0, (LPARAM)&params))
+            hr = E_OUTOFMEMORY;
+        else
+        {
+            WaitForSingleObject(params.event, INFINITE);
+            hr = params.hr;
+        }
+        CloseHandle(params.event);
+    }
+    else
+    {
+        if (!apartment_hwnd)
+        {
+            ERR("host apartment didn't create window\n");
+            hr = E_OUTOFMEMORY;
+        }
+        else
+            hr = SendMessageW(apartment_hwnd, DM_HOSTOBJECT, 0, (LPARAM)&params);
+    }
+    if (SUCCEEDED(hr))
+        hr = CoUnmarshalInterface(params.stream, riid, ppv);
+    IStream_Release(params.stream);
+    return hr;
+}
+
 HRESULT apartment_createwindowifneeded(struct apartment *apt)
 {
     if (apt->multi_threaded)
@@ -568,7 +729,7 @@ HRESULT apartment_createwindowifneeded(struct apartment *apt)
     return S_OK;
 }
 
-HWND apartment_getwindow(struct apartment *apt)
+HWND apartment_getwindow(const struct apartment *apt)
 {
     assert(!apt->multi_threaded);
     return apt->win;
@@ -583,10 +744,24 @@ void apartment_joinmta(void)
 static HRESULT apartment_getclassobject(struct apartment *apt, LPCWSTR dllpath,
                                         REFCLSID rclsid, REFIID riid, void **ppv)
 {
+    static const WCHAR wszOle32[] = {'o','l','e','3','2','.','d','l','l',0};
     HRESULT hr = S_OK;
     BOOL found = FALSE;
     struct apartment_loaded_dll *apartment_loaded_dll;
 
+    if (!strcmpiW(dllpath, wszOle32))
+    {
+        /* we don't need to control the lifetime of this dll, so use the local
+         * implementation of DllGetClassObject directly */
+        TRACE("calling ole32!DllGetClassObject\n");
+        hr = DllGetClassObject(rclsid, riid, ppv);
+
+        if (hr != S_OK)
+            ERR("DllGetClassObject returned error 0x%08x\n", hr);
+
+        return hr;
+    }
+
     EnterCriticalSection(&apt->cs);
 
     LIST_FOR_EACH_ENTRY(apartment_loaded_dll, &apt->loaded_dlls, struct apartment_loaded_dll, entry)
@@ -639,7 +814,7 @@ static void apartment_freeunusedlibraries(struct apartment *apt)
        if (entry->dll->DllCanUnloadNow && (entry->dll->DllCanUnloadNow() == S_OK))
         {
             list_remove(&entry->entry);
-            COMPOBJ_DllList_ReleaseRef(entry->dll);
+            COMPOBJ_DllList_ReleaseRef(entry->dll, TRUE);
             HeapFree(GetProcessHeap(), 0, entry);
         }
     }
@@ -675,9 +850,9 @@ static HRESULT COMPOBJ_DllList_Add(LPCWSTR library_name, OpenDll **ret)
         return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
     }
 
-    DllCanUnloadNow = GetProcAddress(hLibrary, "DllCanUnloadNow");
+    DllCanUnloadNow = (void *)GetProcAddress(hLibrary, "DllCanUnloadNow");
     /* Note: failing to find DllCanUnloadNow is not a failure */
-    DllGetClassObject = GetProcAddress(hLibrary, "DllGetClassObject");
+    DllGetClassObject = (void *)GetProcAddress(hLibrary, "DllGetClassObject");
     if (!DllGetClassObject)
     {
         /* failure: the dll did not export DllGetClassObject */
@@ -741,9 +916,11 @@ static OpenDll *COMPOBJ_DllList_Get(LPCWSTR library_name)
     return ret;
 }
 
-static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry)
+/* pass FALSE for free_entry to release a reference without destroying the
+ * entry if it reaches zero or TRUE otherwise */
+static void COMPOBJ_DllList_ReleaseRef(OpenDll *entry, BOOL free_entry)
 {
-    if (!InterlockedDecrement(&entry->refs))
+    if (!InterlockedDecrement(&entry->refs) && free_entry)
     {
         EnterCriticalSection(&csOpenDllList);
         list_remove(&entry->entry);
@@ -879,31 +1056,6 @@ HRESULT WINAPI CoInitializeEx(LPVOID lpReserved, DWORD dwCoInit)
   return hr;
 }
 
-/* On COM finalization for a STA thread, the message queue is flushed to ensure no
-   pending RPCs are ignored. Non-COM messages are discarded at this point.
- */
-static void COM_FlushMessageQueue(void)
-{
-    MSG message;
-    APARTMENT *apt = COM_CurrentApt();
-
-    if (!apt || !apt->win) return;
-
-    TRACE("Flushing STA message queue\n");
-
-    while (PeekMessageA(&message, NULL, 0, 0, PM_REMOVE))
-    {
-        if (message.hwnd != apt->win)
-        {
-            WARN("discarding message 0x%x for window %p\n", message.message, message.hwnd);
-            continue;
-        }
-
-        TranslateMessage(&message);
-        DispatchMessageA(&message);
-    }
-}
-
 /***********************************************************************
  *           CoUninitialize   [OLE32.@]
  *
@@ -954,15 +1106,6 @@ void WINAPI CoUninitialize(void)
     TRACE("() - Releasing the COM libraries\n");
 
     RunningObjectTableImpl_UnInitialize();
-
-    /* Release the references to the registered class objects */
-    COM_RevokeAllClasses();
-
-    /* This will free the loaded COM Dlls  */
-    CoFreeAllLibraries();
-
-    /* This ensures we deal with any pending RPCs */
-    COM_FlushMessageQueue();
   }
   else if (lCOMRefCnt<1) {
     ERR( "CoUninitialize() - not CoInitialized.\n" );
@@ -1581,10 +1724,8 @@ HRESULT WINAPI CoRegisterPSClsid(REFIID riid, REFCLSID rclsid)
  *                 to normal COM usage, this method will increase the
  *                 reference count on this object.
  */
-static HRESULT COM_GetRegisteredClassObject(
-       REFCLSID    rclsid,
-       DWORD       dwClsContext,
-       LPUNKNOWN*  ppUnk)
+static HRESULT COM_GetRegisteredClassObject(const struct apartment *apt, REFCLSID rclsid,
+                                            DWORD dwClsContext, LPUNKNOWN* ppUnk)
 {
   HRESULT hr = S_FALSE;
   RegisteredClass *curClass;
@@ -1601,7 +1742,8 @@ static HRESULT COM_GetRegisteredClassObject(
     /*
      * Check if we have a match on the class ID and context.
      */
-    if ((dwClsContext & curClass->runContext) &&
+    if ((apt->oxid == curClass->apartment_id) &&
+        (dwClsContext & curClass->runContext) &&
         IsEqualGUID(&(curClass->classIdentifier), rclsid))
     {
       /*
@@ -1643,6 +1785,11 @@ static HRESULT COM_GetRegisteredClassObject(
  * SEE ALSO
  *   CoRevokeClassObject, CoGetClassObject
  *
+ * NOTES
+ *  In-process objects are only registered for the current apartment.
+ *  CoGetClassObject() and CoCreateInstance() will not return objects registered
+ *  in other apartments.
+ *
  * BUGS
  *  MSDN claims that multiple interface registrations are legal, but we
  *  can't do that with our current implementation.
@@ -1657,6 +1804,7 @@ HRESULT WINAPI CoRegisterClassObject(
   RegisteredClass* newClass;
   LPUNKNOWN        foundObject;
   HRESULT          hr;
+  APARTMENT *apt;
 
   TRACE("(%s,%p,0x%08x,0x%08x,%p)\n",
        debugstr_guid(rclsid),pUnk,dwClsContext,flags,lpdwRegister);
@@ -1664,7 +1812,8 @@ HRESULT WINAPI CoRegisterClassObject(
   if ( (lpdwRegister==0) || (pUnk==0) )
     return E_INVALIDARG;
 
-  if (!COM_CurrentApt())
+  apt = COM_CurrentApt();
+  if (!apt)
   {
       ERR("COM was not initialized\n");
       return CO_E_NOTINITIALIZED;
@@ -1681,7 +1830,7 @@ HRESULT WINAPI CoRegisterClassObject(
    * First, check if the class is already registered.
    * If it is, this should cause an error.
    */
-  hr = COM_GetRegisteredClassObject(rclsid, dwClsContext, &foundObject);
+  hr = COM_GetRegisteredClassObject(apt, rclsid, dwClsContext, &foundObject);
   if (hr == S_OK) {
     if (flags & REGCLS_MULTIPLEUSE) {
       if (dwClsContext & CLSCTX_LOCAL_SERVER)
@@ -1699,6 +1848,7 @@ HRESULT WINAPI CoRegisterClassObject(
     return E_OUTOFMEMORY;
 
   newClass->classIdentifier = *rclsid;
+  newClass->apartment_id    = apt->oxid;
   newClass->runContext      = dwClsContext;
   newClass->connectFlags    = flags;
   newClass->pMarshaledData  = NULL;
@@ -1724,29 +1874,19 @@ HRESULT WINAPI CoRegisterClassObject(
   *lpdwRegister = newClass->dwCookie;
 
   if (dwClsContext & CLSCTX_LOCAL_SERVER) {
-      IClassFactory *classfac;
-
-      hr = IUnknown_QueryInterface(newClass->classObject, &IID_IClassFactory,
-                                   (LPVOID*)&classfac);
-      if (hr) return hr;
-
       hr = CreateStreamOnHGlobal(0, TRUE, &newClass->pMarshaledData);
       if (hr) {
           FIXME("Failed to create stream on hglobal, %x\n", hr);
-          IUnknown_Release(classfac);
           return hr;
       }
       hr = CoMarshalInterface(newClass->pMarshaledData, &IID_IClassFactory,
-                              (LPVOID)classfac, MSHCTX_LOCAL, NULL,
+                              newClass->classObject, MSHCTX_LOCAL, NULL,
                               MSHLFLAGS_TABLESTRONG);
       if (hr) {
           FIXME("CoMarshalInterface failed, %x!\n",hr);
-          IUnknown_Release(classfac);
           return hr;
       }
 
-      IUnknown_Release(classfac);
-
       hr = RPC_StartLocalServer(&newClass->classIdentifier,
                                 newClass->pMarshaledData,
                                 flags & (REGCLS_MULTIPLEUSE|REGCLS_MULTI_SEPARATE),
@@ -1755,6 +1895,44 @@ HRESULT WINAPI CoRegisterClassObject(
   return S_OK;
 }
 
+static void COM_RevokeRegisteredClassObject(RegisteredClass *curClass)
+{
+    list_remove(&curClass->entry);
+
+    if (curClass->runContext & CLSCTX_LOCAL_SERVER)
+        RPC_StopLocalServer(curClass->RpcRegistration);
+
+    /*
+     * Release the reference to the class object.
+     */
+    IUnknown_Release(curClass->classObject);
+
+    if (curClass->pMarshaledData)
+    {
+        LARGE_INTEGER zero;
+        memset(&zero, 0, sizeof(zero));
+        IStream_Seek(curClass->pMarshaledData, zero, STREAM_SEEK_SET, NULL);
+        CoReleaseMarshalData(curClass->pMarshaledData);
+    }
+
+    HeapFree(GetProcessHeap(), 0, curClass);
+}
+
+static void COM_RevokeAllClasses(const struct apartment *apt)
+{
+  RegisteredClass *curClass, *cursor;
+
+  EnterCriticalSection( &csRegisteredClassList );
+
+  LIST_FOR_EACH_ENTRY_SAFE(curClass, cursor, &RegisteredClassList, RegisteredClass, entry)
+  {
+    if (curClass->apartment_id == apt->oxid)
+      COM_RevokeRegisteredClassObject(curClass);
+  }
+
+  LeaveCriticalSection( &csRegisteredClassList );
+}
+
 /***********************************************************************
  *           CoRevokeClassObject [OLE32.@]
  *
@@ -1767,6 +1945,10 @@ HRESULT WINAPI CoRegisterClassObject(
  *  Success: S_OK.
  *  Failure: HRESULT code.
  *
+ * NOTES
+ *  Must be called from the same apartment that called CoRegisterClassObject(),
+ *  otherwise it will fail with RPC_E_WRONG_THREAD.
+ *
  * SEE ALSO
  *  CoRegisterClassObject
  */
@@ -1775,9 +1957,17 @@ HRESULT WINAPI CoRevokeClassObject(
 {
   HRESULT hr = E_INVALIDARG;
   RegisteredClass *curClass;
+  APARTMENT *apt;
 
   TRACE("(%08x)\n",dwRegister);
 
+  apt = COM_CurrentApt();
+  if (!apt)
+  {
+    ERR("COM was not initialized\n");
+    return CO_E_NOTINITIALIZED;
+  }
+
   EnterCriticalSection( &csRegisteredClassList );
 
   LIST_FOR_EACH_ENTRY(curClass, &RegisteredClassList, RegisteredClass, entry)
@@ -1787,30 +1977,17 @@ HRESULT WINAPI CoRevokeClassObject(
      */
     if (curClass->dwCookie == dwRegister)
     {
-      list_remove(&curClass->entry);
-
-      if (curClass->runContext & CLSCTX_LOCAL_SERVER)
-        RPC_StopLocalServer(curClass->RpcRegistration);
-
-      /*
-       * Release the reference to the class object.
-       */
-      IUnknown_Release(curClass->classObject);
-
-      if (curClass->pMarshaledData)
+      if (curClass->apartment_id == apt->oxid)
       {
-        LARGE_INTEGER zero;
-        memset(&zero, 0, sizeof(zero));
-        IStream_Seek(curClass->pMarshaledData, zero, STREAM_SEEK_SET, NULL);
-        CoReleaseMarshalData(curClass->pMarshaledData);
+          COM_RevokeRegisteredClassObject(curClass);
+          hr = S_OK;
+      }
+      else
+      {
+          ERR("called from wrong apartment, should be called from %s\n",
+              wine_dbgstr_longlong(curClass->apartment_id));
+          hr = RPC_E_WRONG_THREAD;
       }
-
-      /*
-       * Free the memory used by the chain node.
-       */
-      HeapFree(GetProcessHeap(), 0, curClass);
-
-      hr = S_OK;
       break;
     }
   }
@@ -1858,53 +2035,27 @@ static void get_threading_model(HKEY key, LPWSTR value, DWORD len)
         value[0] = '\0';
 }
 
-static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv)
+static HRESULT get_inproc_class_object(APARTMENT *apt, HKEY hkeydll,
+                                       REFCLSID rclsid, REFIID riid, void **ppv)
 {
     static const WCHAR wszApartment[] = {'A','p','a','r','t','m','e','n','t',0};
     static const WCHAR wszFree[] = {'F','r','e','e',0};
     static const WCHAR wszBoth[] = {'B','o','t','h',0};
     WCHAR dllpath[MAX_PATH+1];
     WCHAR threading_model[10 /* strlenW(L"apartment")+1 */];
-    HRESULT hr;
-    APARTMENT *apt = COM_CurrentApt();
 
     get_threading_model(hkeydll, threading_model, ARRAYSIZE(threading_model));
     /* "Apartment" */
     if (!strcmpiW(threading_model, wszApartment))
     {
         if (apt->multi_threaded)
-        {
-            /* try to find an STA */
-            APARTMENT *host_apt = apartment_findfromtype(FALSE, FALSE);
-            if (!host_apt)
-                FIXME("create a host apartment for apartment-threaded object %s\n", debugstr_guid(rclsid));
-            if (host_apt)
-            {
-                struct host_object_params params;
-                HWND hwnd = apartment_getwindow(host_apt);
-
-                params.hkeydll = hkeydll;
-                params.clsid = *rclsid;
-                params.iid = *riid;
-                hr = CreateStreamOnHGlobal(NULL, TRUE, &params.stream);
-                if (FAILED(hr))
-                    return hr;
-                hr = SendMessageW(hwnd, DM_HOSTOBJECT, 0, (LPARAM)&params);
-                if (SUCCEEDED(hr))
-                    hr = CoUnmarshalInterface(params.stream, riid, ppv);
-                IStream_Release(params.stream);
-                return hr;
-            }
-        }
+            return apartment_hostobject_in_hostapt(apt, FALSE, FALSE, hkeydll, rclsid, riid, ppv);
     }
     /* "Free" */
     else if (!strcmpiW(threading_model, wszFree))
     {
         if (!apt->multi_threaded)
-        {
-            FIXME("should create object %s in multi-threaded apartment\n",
-                debugstr_guid(rclsid));
-        }
+            return apartment_hostobject_in_hostapt(apt, TRUE, FALSE, hkeydll, rclsid, riid, ppv);
     }
     /* everything except "Apartment", "Free" and "Both" */
     else if (strcmpiW(threading_model, wszBoth))
@@ -1915,29 +2066,7 @@ static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID rii
                 debugstr_w(threading_model), debugstr_guid(rclsid));
 
         if (apt->multi_threaded || !apt->main)
-        {
-            /* try to find an STA */
-            APARTMENT *host_apt = apartment_findfromtype(FALSE, TRUE);
-            if (!host_apt)
-                FIXME("create a host apartment for main-threaded object %s\n", debugstr_guid(rclsid));
-            if (host_apt)
-            {
-                struct host_object_params params;
-                HWND hwnd = apartment_getwindow(host_apt);
-
-                params.hkeydll = hkeydll;
-                params.clsid = *rclsid;
-                params.iid = *riid;
-                hr = CreateStreamOnHGlobal(NULL, TRUE, &params.stream);
-                if (FAILED(hr))
-                    return hr;
-                hr = SendMessageW(hwnd, DM_HOSTOBJECT, 0, (LPARAM)&params);
-                if (SUCCEEDED(hr))
-                    hr = CoUnmarshalInterface(params.stream, riid, ppv);
-                IStream_Release(params.stream);
-                return hr;
-            }
-        }
+            return apartment_hostobject_in_hostapt(apt, FALSE, TRUE, hkeydll, rclsid, riid, ppv);
     }
 
     if (COM_RegReadPath(hkeydll, NULL, NULL, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
@@ -1982,6 +2111,7 @@ HRESULT WINAPI CoGetClassObject(
 {
     LPUNKNOWN  regClassObject;
     HRESULT    hres = E_UNEXPECTED;
+    APARTMENT  *apt;
 
     TRACE("\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
 
@@ -1990,7 +2120,8 @@ HRESULT WINAPI CoGetClassObject(
 
     *ppv = NULL;
 
-    if (!COM_CurrentApt())
+    apt = COM_CurrentApt();
+    if (!apt)
     {
         ERR("apartment not initialised\n");
         return CO_E_NOTINITIALIZED;
@@ -2005,7 +2136,8 @@ HRESULT WINAPI CoGetClassObject(
      * First, try and see if we can't match the class ID with one of the
      * registered classes.
      */
-    if (S_OK == COM_GetRegisteredClassObject(rclsid, dwClsContext, &regClassObject))
+    if (S_OK == COM_GetRegisteredClassObject(apt, rclsid, dwClsContext,
+                                             &regClassObject))
     {
       /* Get the required interface from the retrieved pointer. */
       hres = IUnknown_QueryInterface(regClassObject, iid, ppv);
@@ -2034,13 +2166,16 @@ HRESULT WINAPI CoGetClassObject(
         {
             if (hres == REGDB_E_CLASSNOTREG)
                 ERR("class %s not registered\n", debugstr_guid(rclsid));
-            else
+            else if (hres == REGDB_E_KEYMISSING)
+            {
                 WARN("class %s not registered as in-proc server\n", debugstr_guid(rclsid));
+                hres = REGDB_E_CLASSNOTREG;
+            }
         }
 
         if (SUCCEEDED(hres))
         {
-            hres = get_inproc_class_object(hkey, rclsid, iid, ppv);
+            hres = get_inproc_class_object(apt, hkey, rclsid, iid, ppv);
             RegCloseKey(hkey);
         }
 
@@ -2061,13 +2196,16 @@ HRESULT WINAPI CoGetClassObject(
         {
             if (hres == REGDB_E_CLASSNOTREG)
                 ERR("class %s not registered\n", debugstr_guid(rclsid));
-            else
+            else if (hres == REGDB_E_KEYMISSING)
+            {
                 WARN("class %s not registered in-proc handler\n", debugstr_guid(rclsid));
+                hres = REGDB_E_CLASSNOTREG;
+            }
         }
 
         if (SUCCEEDED(hres))
         {
-            hres = get_inproc_class_object(hkey, rclsid, iid, ppv);
+            hres = get_inproc_class_object(apt, hkey, rclsid, iid, ppv);
             RegCloseKey(hkey);
         }
 
@@ -2388,20 +2526,6 @@ HRESULT WINAPI CoFileTimeNow( FILETIME *lpFileTime )
     return S_OK;
 }
 
-static void COM_RevokeAllClasses(void)
-{
-  EnterCriticalSection( &csRegisteredClassList );
-
-  while (list_head(&RegisteredClassList))
-  {
-    RegisteredClass *curClass = LIST_ENTRY(list_head(&RegisteredClassList),
-                                           RegisteredClass, entry);
-    CoRevokeClassObject(curClass->dwCookie);
-  }
-
-  LeaveCriticalSection( &csRegisteredClassList );
-}
-
 /******************************************************************************
  *             CoLockObjectExternal    [OLE32.@]
  *
index e877cce..c12150a 100644 (file)
@@ -158,6 +158,8 @@ struct apartment
   LONG remoting_started;   /* has the RPC system been started for this apartment? (LOCK) */
   struct list psclsids;    /* list of registered PS CLSIDs (CS cs) */
   struct list loaded_dlls; /* list of dlls loaded by this apartment (CS cs) */
+  DWORD host_apt_tid;      /* thread ID of apartment hosting objects of differing threading model (CS cs) */
+  HWND host_apt_hwnd;      /* handle to apartment window of host apartment (CS cs) */
 
   /* FIXME: OID's should be given out by RPCSS */
   OID oidc;                /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
@@ -253,13 +255,13 @@ DWORD apartment_addref(struct apartment *apt);
 DWORD apartment_release(struct apartment *apt);
 HRESULT apartment_disconnectproxies(struct apartment *apt);
 void apartment_disconnectobject(struct apartment *apt, void *object);
-static inline HRESULT apartment_getoxid(struct apartment *apt, OXID *oxid)
+static inline HRESULT apartment_getoxid(const struct apartment *apt, OXID *oxid)
 {
     *oxid = apt->oxid;
     return S_OK;
 }
 HRESULT apartment_createwindowifneeded(struct apartment *apt);
-HWND apartment_getwindow(struct apartment *apt);
+HWND apartment_getwindow(const struct apartment *apt);
 void apartment_joinmta(void);
 
 
index 6e11478..593a4ff 100644 (file)
@@ -126,8 +126,8 @@ void dictionary_insert(struct dictionary *d, const void *k, const void *v)
     }
     else
     {
-        struct dictionary_entry *elem = (struct dictionary_entry *)
-         HeapAlloc(GetProcessHeap(), 0, sizeof(struct dictionary_entry));
+        struct dictionary_entry *elem = HeapAlloc(GetProcessHeap(), 0,
+                                            sizeof(struct dictionary_entry));
 
         if (!elem)
             return;
index 232abec..9610dbe 100644 (file)
@@ -189,7 +189,7 @@ enumx_impl *enumx_allocate(REFIID riid, const void *vtbl, ULONG elem_size)
  *
  * Add an element to the enumeration.
  */
-void *enumx_add_element(enumx_impl *enumx, void *data)
+void *enumx_add_element(enumx_impl *enumx, const void *data)
 {
     struct list *element;
 
index 2d36b73..5d45c94 100644 (file)
@@ -29,6 +29,6 @@ extern HRESULT WINAPI enumx_Skip(enumx_impl *, ULONG);
 extern HRESULT WINAPI enumx_Reset(enumx_impl *);
 extern HRESULT WINAPI enumx_Clone(enumx_impl *, enumx_impl **);
 extern enumx_impl *enumx_allocate(REFIID, const void *, ULONG);
-extern void *enumx_add_element(enumx_impl *, void *);
+extern void *enumx_add_element(enumx_impl *, const void *);
 
 #endif
index 01dc305..7318a97 100644 (file)
@@ -465,8 +465,18 @@ static const ISupportErrorInfoVtbl ISupportErrorInfoImpl_VTable =
 
   ISupportErrorInfoImpl_InterfaceSupportsErrorInfo
 };
+
 /***********************************************************************
  *             CreateErrorInfo (OLE32.@)
+ *
+ * Creates an object used to set details for an error info object.
+ *
+ * PARAMS
+ *  pperrinfo [O]. Address where error info creation object will be stored.
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: HRESULT code.
  */
 HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo)
 {
@@ -483,6 +493,21 @@ HRESULT WINAPI CreateErrorInfo(ICreateErrorInfo **pperrinfo)
 
 /***********************************************************************
  *             GetErrorInfo (OLE32.@)
+ *
+ * Retrieves the error information object for the current thread.
+ *
+ * PARAMS
+ *  dwReserved [I]. Reserved. Must be zero.
+ *  pperrinfo  [O]. Address where error information object will be stored on return.
+ *
+ * RETURNS
+ *  Success: S_OK if an error information object was set for the current thread.
+ *           S_FALSE if otherwise.
+ *  Failure: E_INVALIDARG if dwReserved is not zero.
+ *
+ * NOTES
+ *  This function causes the current error info object for the thread to be
+ *  cleared if one was set beforehand.
  */
 HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
 {
@@ -511,6 +536,16 @@ HRESULT WINAPI GetErrorInfo(ULONG dwReserved, IErrorInfo **pperrinfo)
 
 /***********************************************************************
  *             SetErrorInfo (OLE32.@)
+ *
+ * Sets the error information object for the current thread.
+ *
+ * PARAMS
+ *  dwReserved [I] Reserved. Must be zero.
+ *  perrinfo   [I] Error info object.
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: E_INVALIDARG if dwReserved is not zero.
  */
 HRESULT WINAPI SetErrorInfo(ULONG dwReserved, IErrorInfo *perrinfo)
 {
index 7578836..4ef7d59 100644 (file)
@@ -1011,19 +1011,27 @@ FileMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** p
 int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
 {
     static const WCHAR bSlash[] = {'\\',0};
-    WCHAR word[MAX_PATH];
-    int i=0,j,tabIndex=0;
+    LPOLESTR word;
+    int i=0,j,tabIndex=0, ret=0;
     LPOLESTR *strgtable ;
 
     int len=lstrlenW(str);
 
     TRACE("%s, %p\n", debugstr_w(str), *stringTable);
 
-    strgtable =CoTaskMemAlloc(len*sizeof(LPOLESTR));
+    strgtable = CoTaskMemAlloc(len*sizeof(WCHAR));
 
     if (strgtable==NULL)
        return E_OUTOFMEMORY;
 
+    word = CoTaskMemAlloc((len + 1)*sizeof(WCHAR));
+
+    if (word==NULL)
+    {
+        ret = E_OUTOFMEMORY;
+        goto lend;
+    }
+
     while(str[i]!=0){
 
         if(str[i]==bSlash[0]){
@@ -1031,7 +1039,10 @@ int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
             strgtable[tabIndex]=CoTaskMemAlloc(2*sizeof(WCHAR));
 
             if (strgtable[tabIndex]==NULL)
-               return E_OUTOFMEMORY;
+            {
+                ret = E_OUTOFMEMORY;
+                goto lend;
+            }
 
             strcpyW(strgtable[tabIndex++],bSlash);
 
@@ -1048,7 +1059,10 @@ int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
             strgtable[tabIndex]=CoTaskMemAlloc(sizeof(WCHAR)*(j+1));
 
             if (strgtable[tabIndex]==NULL)
-                return E_OUTOFMEMORY;
+            {
+                ret = E_OUTOFMEMORY;
+                goto lend;
+            }
 
             strcpyW(strgtable[tabIndex++],word);
         }
@@ -1057,7 +1071,21 @@ int FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable)
 
     *stringTable=strgtable;
 
-    return tabIndex;
+    ret = tabIndex;
+
+lend:
+    if (ret < 0)
+    {
+        for (i = 0; i < tabIndex; i++)
+            CoTaskMemFree(strgtable[i]);
+
+        CoTaskMemFree(strgtable);
+    }
+
+    if (word)
+        CoTaskMemFree(word);
+
+    return ret;
 }
 
 /******************************************************************************
index 222eb6f..e878f83 100644 (file)
@@ -96,7 +96,7 @@ static void StdGlobalInterfaceTable_Destroy(void* self)
 
 /***
  * A helper function to traverse the list and find the entry that matches the cookie.
- * Returns NULL if not found
+ * Returns NULL if not found. Must be called inside git_section critical section.
  */
 static StdGITEntry*
 StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie)
@@ -106,14 +106,10 @@ StdGlobalInterfaceTable_FindEntry(IGlobalInterfaceTable* iface, DWORD cookie)
 
   TRACE("iface=%p, cookie=0x%x\n", iface, (UINT)cookie);
 
-  EnterCriticalSection(&git_section);
   LIST_FOR_EACH_ENTRY(e, &self->list, StdGITEntry, entry) {
-    if (e->cookie == cookie) {
-      LeaveCriticalSection(&git_section);
+    if (e->cookie == cookie)
       return e;
-    }
   }
-  LeaveCriticalSection(&git_section);
   
   TRACE("Entry not found\n");
   return NULL;
@@ -232,12 +228,19 @@ StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
   HRESULT hr;
 
   TRACE("iface=%p, dwCookie=0x%x\n", iface, (UINT)dwCookie);
-  
+
+  EnterCriticalSection(&git_section);
+
   entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
   if (entry == NULL) {
     TRACE("Entry not found\n");
+    LeaveCriticalSection(&git_section);
     return E_INVALIDARG; /* not found */
   }
+
+  list_remove(&entry->entry);
+
+  LeaveCriticalSection(&git_section);
   
   /* Free the stream */
   hr = CoReleaseMarshalData(entry->stream);
@@ -248,11 +251,6 @@ StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(
   }
   IStream_Release(entry->stream);
                    
-  /* chop entry out of the list, and free the memory */
-  EnterCriticalSection(&git_section);
-  list_remove(&entry->entry);
-  LeaveCriticalSection(&git_section);
-
   HeapFree(GetProcessHeap(), 0, entry);
   return S_OK;
 }
@@ -264,36 +262,39 @@ StdGlobalInterfaceTable_GetInterfaceFromGlobal(
 {
   StdGITEntry* entry;
   HRESULT hres;
-  LARGE_INTEGER move;
-  LPUNKNOWN lpUnk;
-  
+  IStream *stream;
+
   TRACE("dwCookie=0x%x, riid=%s, ppv=%p\n", dwCookie, debugstr_guid(riid), ppv);
-  
-  entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
-  if (entry == NULL) return E_INVALIDARG;
 
-  if (!IsEqualIID(&entry->iid, riid)) {
-    WARN("entry->iid (%s) != riid\n", debugstr_guid(&entry->iid));
+  EnterCriticalSection(&git_section);
+
+  entry = StdGlobalInterfaceTable_FindEntry(iface, dwCookie);
+  if (entry == NULL) {
+    WARN("Entry for cookie 0x%x not found\n", dwCookie);
+    LeaveCriticalSection(&git_section);
     return E_INVALIDARG;
   }
+
   TRACE("entry=%p\n", entry);
-  
+
+  hres = IStream_Clone(entry->stream, &stream);
+
+  LeaveCriticalSection(&git_section);
+
+  if (hres) {
+    WARN("Failed to clone stream with error 0x%08x\n", hres);
+    return hres;
+  }
+
   /* unmarshal the interface */
-  hres = CoUnmarshalInterface(entry->stream, riid, ppv);
-  
-  /* rewind stream, in case it's used again */
-  move.u.LowPart = 0;
-  move.u.HighPart = 0;
-  IStream_Seek(entry->stream, move, STREAM_SEEK_SET, NULL);
+  hres = CoUnmarshalInterface(stream, riid, ppv);
+  IStream_Release(stream);
 
   if (hres) {
     WARN("Failed to unmarshal stream\n");
     return hres;
   }
 
-  /* addref it */
-  lpUnk = *ppv;
-  IUnknown_AddRef(lpUnk);
   TRACE("ppv=%p\n", *ppv);
   return S_OK;
 }
index d98c0c5..e6d2f73 100644 (file)
@@ -39,7 +39,6 @@
 #include "objbase.h"
 #include "ole2.h"
 #include "winerror.h"
-#include "winreg.h"
 #include "winternl.h"
 
 #include "wine/debug.h"
@@ -234,6 +233,12 @@ static HRESULT WINAPI HGLOBALStreamImpl_Read(
    * Lock the buffer in position and copy the data.
    */
   supportBuffer = GlobalLock(This->supportHandle);
+  if (!supportBuffer)
+  {
+      WARN("read from invalid hglobal %p\n", This->supportHandle);
+      *pcbRead = 0;
+      return S_OK;
+  }
 
   memcpy(pv, (char *) supportBuffer+This->currentPosition.u.LowPart, bytesToReadFromBuffer);
 
@@ -294,6 +299,8 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
   if (cb == 0)
     goto out;
 
+  *pcbWritten = 0;
+
   newSize.u.HighPart = 0;
   newSize.u.LowPart = This->currentPosition.u.LowPart + cb;
 
@@ -315,6 +322,11 @@ static HRESULT WINAPI HGLOBALStreamImpl_Write(
    * Lock the buffer in position and copy the data.
    */
   supportBuffer = GlobalLock(This->supportHandle);
+  if (!supportBuffer)
+  {
+      WARN("write to invalid hglobal %p\n", This->supportHandle);
+      return S_OK;
+  }
 
   memcpy((char *) supportBuffer+This->currentPosition.u.LowPart, pv, cb);
 
index 37ef44e..ec20da3 100644 (file)
@@ -56,7 +56,7 @@ typedef struct {
        DWORD SpyedAllocationsLeft; /* number of spyed allocations left */
        BOOL SpyReleasePending;     /* CoRevokeMallocSpy called with spyed allocations left*/
         LPVOID * SpyedBlocks;       /* root of the table */
-        int SpyedBlockTableLength;  /* size of the table*/
+        DWORD SpyedBlockTableLength;/* size of the table*/
 } _Malloc32;
 
 /* this is the static object instance */
@@ -73,7 +73,7 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
 static CRITICAL_SECTION IMalloc32_SpyCS = { &critsect_debug, -1, 0, 0, 0, 0 };
 
 /* resize the old table */
-static int SetSpyedBlockTableLength ( int NewLength )
+static int SetSpyedBlockTableLength ( DWORD NewLength )
 {
        LPVOID *NewSpyedBlocks;
 
@@ -103,7 +103,9 @@ static int AddMemoryLocation(LPVOID * pMem)
             Current++;
            if (Current >= Malloc32.SpyedBlocks + Malloc32.SpyedBlockTableLength) {
                /* no more space in table, grow it */
+                DWORD old_length = Malloc32.SpyedBlockTableLength;
                if (!SetSpyedBlockTableLength( Malloc32.SpyedBlockTableLength + 0x1000 )) return 0;
+                Current = Malloc32.SpyedBlocks + old_length;
            }
        };
 
@@ -114,7 +116,7 @@ static int AddMemoryLocation(LPVOID * pMem)
         return 1;
 }
 
-static int RemoveMemoryLocation(LPVOID * pMem)
+static int RemoveMemoryLocation(LPCVOID pMem)
 {
         LPVOID * Current;
 
index 120361a..d918347 100644 (file)
@@ -283,6 +283,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
         {
             hr = IRemUnknown_RemQueryInterface(remunk, ipid, NORMALEXTREFS,
                                                nonlocal_mqis, iids, &qiresults);
+            IRemUnknown_Release(remunk);
             if (FAILED(hr))
                 ERR("IRemUnknown_RemQueryInterface failed with error 0x%08x\n", hr);
         }
@@ -297,7 +298,7 @@ static HRESULT WINAPI ClientIdentity_QueryMultipleInterfaces(IMultiQI *iface, UL
                 ULONG index = mapping[i];
                 HRESULT hrobj = qiresults[i].hResult;
                 if (hrobj == S_OK)
-                    hrobj = unmarshal_object(&qiresults[i].std, This->parent,
+                    hrobj = unmarshal_object(&qiresults[i].std, COM_CurrentApt(),
                                              This->dest_context,
                                              This->dest_context_data,
                                              pMQIs[index].pIID, &This->oxid_info,
@@ -375,22 +376,29 @@ static HRESULT WINAPI Proxy_MarshalInterface(
     if (SUCCEEDED(hr))
     {
         STDOBJREF stdobjref = ifproxy->stdobjref;
-        ULONG cPublicRefs = ifproxy->refs;
-        ULONG cPublicRefsOld;
 
-        /* optimization - share out proxy's public references if possible
-         * instead of making new proxy do a roundtrip through the server */
-        do
+        stdobjref.cPublicRefs = 0;
+
+        if ((mshlflags != MSHLFLAGS_TABLEWEAK) &&
+            (mshlflags != MSHLFLAGS_TABLESTRONG))
         {
-            ULONG cPublicRefsNew;
-            cPublicRefsOld = cPublicRefs;
-            stdobjref.cPublicRefs = cPublicRefs / 2;
-            cPublicRefsNew = cPublicRefs - stdobjref.cPublicRefs;
-            cPublicRefs = InterlockedCompareExchange(
-                (LONG *)&ifproxy->refs, cPublicRefsNew, cPublicRefsOld);
-        } while (cPublicRefs != cPublicRefsOld);
-
-        if (!stdobjref.cPublicRefs)
+            ULONG cPublicRefs = ifproxy->refs;
+            ULONG cPublicRefsOld;
+            /* optimization - share out proxy's public references if possible
+             * instead of making new proxy do a roundtrip through the server */
+            do
+            {
+                ULONG cPublicRefsNew;
+                cPublicRefsOld = cPublicRefs;
+                stdobjref.cPublicRefs = cPublicRefs / 2;
+                cPublicRefsNew = cPublicRefs - stdobjref.cPublicRefs;
+                cPublicRefs = InterlockedCompareExchange(
+                    (LONG *)&ifproxy->refs, cPublicRefsNew, cPublicRefsOld);
+            } while (cPublicRefs != cPublicRefsOld);
+        }
+
+        /* normal and table-strong marshaling need at least one reference */
+        if (!stdobjref.cPublicRefs && (mshlflags != MSHLFLAGS_TABLEWEAK))
         {
             IRemUnknown *remunk;
             hr = proxy_manager_get_remunknown(This, &remunk);
@@ -399,11 +407,17 @@ static HRESULT WINAPI Proxy_MarshalInterface(
                 HRESULT hrref = S_OK;
                 REMINTERFACEREF rif;
                 rif.ipid = ifproxy->stdobjref.ipid;
-                rif.cPublicRefs = NORMALEXTREFS;
+                rif.cPublicRefs = (mshlflags == MSHLFLAGS_TABLESTRONG) ? 1 : NORMALEXTREFS;
                 rif.cPrivateRefs = 0;
                 hr = IRemUnknown_RemAddRef(remunk, 1, &rif, &hrref);
+                IRemUnknown_Release(remunk);
                 if (hr == S_OK && hrref == S_OK)
-                    stdobjref.cPublicRefs = rif.cPublicRefs;
+                {
+                    /* table-strong marshaling doesn't give the refs to the
+                     * client that unmarshals the STDOBJREF */
+                    if (mshlflags != MSHLFLAGS_TABLESTRONG)
+                        stdobjref.cPublicRefs = rif.cPublicRefs;
+                }
                 else
                     ERR("IRemUnknown_RemAddRef returned with 0x%08x, hrref = 0x%08x\n", hr, hrref);
             }
@@ -455,6 +469,7 @@ static HRESULT WINAPI Proxy_MarshalInterface(
             }
             else
                 ERR("IRemUnknown_RemQueryInterface failed with error 0x%08x\n", hr);
+            IRemUnknown_Release(remunk);
         }
     }
 
@@ -565,6 +580,7 @@ static HRESULT ifproxy_get_public_ref(struct ifproxy * This)
             rif.cPublicRefs = NORMALEXTREFS;
             rif.cPrivateRefs = 0;
             hr = IRemUnknown_RemAddRef(remunk, 1, &rif, &hrref);
+            IRemUnknown_Release(remunk);
             if (hr == S_OK && hrref == S_OK)
                 InterlockedExchangeAdd((LONG *)&This->refs, NORMALEXTREFS);
             else
@@ -602,6 +618,7 @@ static HRESULT ifproxy_release_public_refs(struct ifproxy * This)
             rif.cPublicRefs = public_refs;
             rif.cPrivateRefs = 0;
             hr = IRemUnknown_RemRelease(remunk, 1, &rif);
+            IRemUnknown_Release(remunk);
             if (hr == S_OK)
                 InterlockedExchangeAdd((LONG *)&This->refs, -public_refs);
             else if (hr == RPC_E_DISCONNECTED)
@@ -947,16 +964,30 @@ static void proxy_manager_disconnect(struct proxy_manager * This)
 static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnknown **remunk)
 {
     HRESULT hr = S_OK;
+    struct apartment *apt;
+    BOOL called_in_original_apt;
 
     /* we don't want to try and unmarshal or use IRemUnknown if we don't want
      * lifetime management */
     if (This->sorflags & SORFP_NOLIFETIMEMGMT)
         return S_FALSE;
 
+    apt = COM_CurrentApt();
+    if (!apt)
+        return CO_E_NOTINITIALIZED;
+
+    called_in_original_apt = This->parent && (This->parent->oxid == apt->oxid);
+
     EnterCriticalSection(&This->cs);
-    if (This->remunk)
+    /* only return the cached object if called from the original apartment.
+     * in future, we might want to make the IRemUnknown proxy callable from any
+     * apartment to avoid these checks */
+    if (This->remunk && called_in_original_apt)
+    {
         /* already created - return existing object */
         *remunk = This->remunk;
+        IRemUnknown_AddRef(*remunk);
+    }
     else if (!This->parent)
         /* disconnected - we can't create IRemUnknown */
         hr = S_FALSE;
@@ -974,11 +1005,14 @@ static HRESULT proxy_manager_get_remunknown(struct proxy_manager * This, IRemUnk
         stdobjref.ipid = This->oxid_info.ipidRemUnknown;
 
         /* do the unmarshal */
-        hr = unmarshal_object(&stdobjref, This->parent, This->dest_context,
+        hr = unmarshal_object(&stdobjref, COM_CurrentApt(), This->dest_context,
                               This->dest_context_data, &IID_IRemUnknown,
-                              &This->oxid_info, (void**)&This->remunk);
-        if (hr == S_OK)
-            *remunk = This->remunk;
+                              &This->oxid_info, (void**)remunk);
+        if (hr == S_OK && called_in_original_apt)
+        {
+            This->remunk = *remunk;
+            IRemUnknown_AddRef(This->remunk);
+        }
     }
     LeaveCriticalSection(&This->cs);
 
index d9c2202..b89efa8 100644 (file)
@@ -35,7 +35,6 @@
 #include "winuser.h"
 #include "objbase.h"
 #include "ole2.h"
-#include "ole2ver.h"
 #include "rpc.h"
 #include "winerror.h"
 #include "winreg.h"
index 908eb09..e58385b 100644 (file)
 #include "winuser.h"
 #include "winnls.h"
 #include "winreg.h"
-#include "commctrl.h"
 #include "ole2.h"
 #include "ole2ver.h"
-#include "wownt32.h"
 
 #include "wine/unicode.h"
 #include "compobj_private.h"
@@ -149,7 +147,7 @@ extern void OLEClipbrd_Initialize(void);
 static void            OLEDD_Initialize(void);
 static DropTargetNode* OLEDD_FindDropTarget(
                          HWND hwndOfTarget);
-static void            OLEDD_FreeDropTarget(DropTargetNode*);
+static void            OLEDD_FreeDropTarget(DropTargetNode*, BOOL);
 static LRESULT WINAPI  OLEDD_DragTrackerWindowProc(
                         HWND   hwnd,
                         UINT   uMsg,
@@ -355,7 +353,7 @@ HRESULT WINAPI RevokeDragDrop(
   if (dropTargetInfo==NULL)
     return DRAGDROP_E_NOTREGISTERED;
 
-  OLEDD_FreeDropTarget(dropTargetInfo);
+  OLEDD_FreeDropTarget(dropTargetInfo, TRUE);
 
   return S_OK;
 }
@@ -1389,7 +1387,7 @@ static LRESULT CALLBACK OLEMenu_CallWndProc(INT code, WPARAM wParam, LPARAM lPar
   OleMenuHookItem *pHookItem = NULL;
   WORD fuFlags;
 
-  TRACE("%i, %04x, %08x\n", code, wParam, (unsigned)lParam );
+  TRACE("%i, %04lx, %08lx\n", code, wParam, lParam );
 
   /* Check if we're being asked to process the message */
   if ( HC_ACTION != code )
@@ -1494,7 +1492,7 @@ static LRESULT CALLBACK OLEMenu_GetMsgProc(INT code, WPARAM wParam, LPARAM lPara
   OleMenuHookItem *pHookItem = NULL;
   WORD wCode;
 
-  TRACE("%i, %04x, %08x\n", code, wParam, (unsigned)lParam );
+  TRACE("%i, %04lx, %08lx\n", code, wParam, lParam );
 
   /* Check if we're being asked to process a  messages */
   if ( HC_ACTION != code )
@@ -1713,9 +1711,8 @@ BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* l
        return FALSE;
     }
     if((lpMsg->message != WM_KEYDOWN &&
-       lpMsg->message != WM_KEYUP &&
        lpMsg->message != WM_SYSKEYDOWN &&
-       lpMsg->message != WM_SYSKEYUP &&
+       lpMsg->message != WM_SYSCHAR &&
        lpMsg->message != WM_CHAR)) return FALSE;
     lpAccelTbl = HeapAlloc(GetProcessHeap(), 0, cAccelEntries * sizeof(ACCEL));
     if (NULL == lpAccelTbl)
@@ -1730,7 +1727,7 @@ BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* l
     }
 
     TRACE_(accel)("hAccel=%p, cAccelEntries=%d,"
-               "msg->hwnd=%p, msg->message=%04x, wParam=%08x, lParam=%08lx\n",
+               "msg->hwnd=%p, msg->message=%04x, wParam=%08lx, lParam=%08lx\n",
                hAccel, cAccelEntries,
                lpMsg->hwnd, lpMsg->message, lpMsg->wParam, lpMsg->lParam);
     for(i = 0; i < cAccelEntries; i++)
@@ -1742,7 +1739,7 @@ BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* l
        {
            if(!(lpAccelTbl[i].fVirt & FALT) && !(lpAccelTbl[i].fVirt & FVIRTKEY))
            {
-               TRACE_(accel)("found accel for WM_CHAR: ('%c')\n", lpMsg->wParam & 0xff);
+               TRACE_(accel)("found accel for WM_CHAR: ('%c')\n", LOWORD(lpMsg->wParam) & 0xff);
                goto found;
            }
        }
@@ -1751,7 +1748,7 @@ BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* l
            if(lpAccelTbl[i].fVirt & FVIRTKEY)
            {
                INT mask = 0;
-               TRACE_(accel)("found accel for virt_key %04x (scan %04x)\n",
+               TRACE_(accel)("found accel for virt_key %04lx (scan %04x)\n",
                                lpMsg->wParam, HIWORD(lpMsg->lParam) & 0xff);
                if(GetKeyState(VK_SHIFT) & 0x8000) mask |= FSHIFT;
                if(GetKeyState(VK_CONTROL) & 0x8000) mask |= FCONTROL;
@@ -1765,7 +1762,7 @@ BOOL WINAPI IsAccelerator(HACCEL hAccel, int cAccelEntries, LPMSG lpMsg, WORD* l
                {
                    if((lpAccelTbl[i].fVirt & FALT) && (lpMsg->lParam & 0x20000000))
                    {                                                  /* ^^ ALT pressed */
-                       TRACE_(accel)("found accel for Alt-%c\n", lpMsg->wParam & 0xff);
+                       TRACE_(accel)("found accel for Alt-%c\n", LOWORD(lpMsg->wParam) & 0xff);
                        goto found;
                    }
                }
@@ -1897,10 +1894,10 @@ static void OLEDD_Initialize(void)
  *
  * Frees the drag and drop data structure
  */
-static void OLEDD_FreeDropTarget(DropTargetNode *dropTargetInfo)
+static void OLEDD_FreeDropTarget(DropTargetNode *dropTargetInfo, BOOL release_drop_target)
 {
   list_remove(&dropTargetInfo->entry);
-  IDropTarget_Release(dropTargetInfo->dropTarget);
+  if (release_drop_target) IDropTarget_Release(dropTargetInfo->dropTarget);
   HeapFree(GetProcessHeap(), 0, dropTargetInfo);
 }
 
@@ -1916,9 +1913,8 @@ void OLEDD_UnInitialize(void)
    */
   while (!list_empty(&targetListHead))
   {
-    DropTargetNode* curNode;
-    curNode = LIST_ENTRY(list_head(&targetListHead), DropTargetNode, entry);
-    OLEDD_FreeDropTarget(curNode);
+    DropTargetNode* curNode = LIST_ENTRY(list_head(&targetListHead), DropTargetNode, entry);
+    OLEDD_FreeDropTarget(curNode, FALSE);
   }
 }
 
@@ -2601,7 +2597,7 @@ BSTR WINAPI PropSysAllocString(LPCOLESTR str)
      * string.
      */
     stringBuffer = (WCHAR*)newBuffer;
-    stringBuffer[len] = L'\0';
+    stringBuffer[len] = '\0';
 
     return (LPWSTR)stringBuffer;
 }
index 20e9725..90a1ed2 100644 (file)
 #include "winbase.h"
 #include "wingdi.h"
 #include "winuser.h"
-#include "winnls.h"
-#include "commctrl.h"
 #include "ole2.h"
-#include "ole2ver.h"
 #include "winerror.h"
-#include "wownt32.h"
 
 #include "wine/winbase16.h"
 #include "wine/wingdi16.h"
index f123fe9..da50f4a 100644 (file)
@@ -32,7 +32,6 @@
 #include "wine/debug.h"
 #include "ole2.h"
 #include "olestd.h"
-#include "winreg.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
index 9851d70..f42ddf9 100644 (file)
 
 #include "windef.h"
 #include "winbase.h"
-#include "winerror.h"
 #include "winnls.h"
-#include "winreg.h"
 #include "winuser.h"
-#include "winver.h"
 
 #include "wine/winbase16.h"
 
index e44265b..c8db8d4 100644 (file)
@@ -2,7 +2,6 @@
        <autoregister infsection="OleControlDlls" type="DllRegisterServer" />
        <importlibrary definition="ole32.spec.def" />
        <include base="ole32">.</include>
-       <include base="ole32" root="intermediate">.</include>
        <include base="ReactOS">include/reactos/wine</include>
        <define name="__REACTOS__" />
        <define name="__WINESRC__" />
@@ -54,5 +53,6 @@
        <file>usrmarshal.c</file>
        <file>ole32res.rc</file>
        <file>dcom.idl</file>
+       <include base="ole32" root="intermediate">.</include>
        <file>ole32.spec</file>
 </module>
index 3ae0240..e018b0f 100644 (file)
@@ -58,6 +58,7 @@
 @ stdcall CoRegisterMessageFilter(ptr ptr)
 @ stdcall CoRegisterPSClsid(ptr ptr)
 @ stub CoRegisterSurrogate
+@ stub CoRegisterSurrogateEx
 @ stdcall CoReleaseMarshalData(ptr)
 @ stdcall CoReleaseServerProcess()
 @ stdcall CoResumeClassObjects()
index 328a972..1d58d55 100644 (file)
@@ -22,7 +22,6 @@
 #include <stdio.h>
 
 #include "windef.h"
-#include "winerror.h"
 #include "winbase.h"
 #include "wingdi.h"
 #include "winuser.h"
diff --git a/reactos/dll/win32/ole32/ole32_ros.diff b/reactos/dll/win32/ole32/ole32_ros.diff
deleted file mode 100644 (file)
index 091e7aa..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-Index: rpc.c
-===================================================================
---- rpc.c      (revision 23782)
-+++ rpc.c      (working copy)
-@@ -24,6 +24,7 @@
- #include "wine/port.h"
- #include <stdarg.h>
-+#include <stdio.h>
- #include <string.h>
- #define COBJMACROS
index dd12e5c..e807941 100644 (file)
@@ -53,7 +53,6 @@
 #include "ole2.h"
 #include "rpc.h"
 #include "winerror.h"
-#include "winreg.h"
 #include "wtypes.h"
 
 #include "compobj_private.h"
index 39957d0..9c3ab83 100644 (file)
@@ -24,7 +24,6 @@
 #include "wine/port.h"
 
 #include <stdarg.h>
-#include <stdio.h>
 #include <string.h>
 
 #define COBJMACROS
index 4f22207..0fe2a3b 100644 (file)
@@ -896,7 +896,7 @@ static HRESULT WINAPI ImplBIGBLOCKFILE_WriteAt(
 
         if (bytes_left)
         {
-            readPtr = (LPBYTE)readPtr + bytes_to_page;
+            readPtr = (const BYTE *)readPtr + bytes_to_page;
             page_index ++;
             offset_in_page = 0;
             if (bytes_left > PAGE_SIZE)
@@ -920,7 +920,7 @@ HRESULT     BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
 }
 
 HRESULT    BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
-                void* buffer, const ULONG size, ULONG* bytesRead)
+                const void* buffer, ULONG size, ULONG* bytesRead)
 {
     if (This->fileBased)
         return ImplBIGBLOCKFILE_WriteAt(This,offset,buffer,size,bytesRead);
index 45c760e..76a86ca 100644 (file)
@@ -1617,7 +1617,7 @@ end:
 }
 
 static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
- DWORD propNum, DWORD propid, PROPVARIANT *var, DWORD *sectionOffset)
+ DWORD propNum, DWORD propid, const PROPVARIANT *var, DWORD *sectionOffset)
 {
     HRESULT hr;
     LARGE_INTEGER seek;
@@ -1717,7 +1717,7 @@ static HRESULT PropertyStorage_WritePropertyToStream(PropertyStorage_impl *This,
         FILETIME temp;
 
         StorageUtl_WriteULargeInteger((BYTE *)&temp, 0,
-         (ULARGE_INTEGER *)&var->u.filetime);
+         (const ULARGE_INTEGER *)&var->u.filetime);
         hr = IStream_Write(This->stm, &temp, sizeof(FILETIME), &count);
         bytesWritten = count;
         break;
@@ -1775,8 +1775,8 @@ static BOOL PropertyStorage_PropertiesWriter(const void *key, const void *value,
     assert(value);
     assert(extra);
     assert(closure);
-    c->hr = PropertyStorage_WritePropertyToStream(This,
-     c->propNum++, (DWORD)key, (PROPVARIANT *)value, c->sectionOffset);
+    c->hr = PropertyStorage_WritePropertyToStream(This, c->propNum++,
+     (DWORD)key, value, c->sectionOffset);
     return SUCCEEDED(c->hr);
 }
 
index e144b2c..1bcb40b 100644 (file)
@@ -36,7 +36,6 @@
 #include "windef.h"
 #include "winbase.h"
 #include "winerror.h"
-#include "winreg.h"
 #include "winternl.h"
 #include "wine/debug.h"
 
index 401c984..febdc12 100644 (file)
@@ -36,7 +36,6 @@
 #define NONAMELESSSTRUCT
 #include "windef.h"
 #include "winbase.h"
-#include "winreg.h"
 #include "winternl.h"
 #include "winerror.h"
 #include "wine/winbase16.h"
@@ -553,7 +552,7 @@ STORAGE_get_small_block(stream_access16 *str,int blocknr,BYTE *sblock) {
  * STORAGE_put_small_block [INTERNAL]
  */
 static BOOL
-STORAGE_put_small_block(stream_access16 *str,int blocknr,BYTE *sblock) {
+STORAGE_put_small_block(stream_access16 *str,int blocknr,const BYTE *sblock) {
        BYTE                            block[BIGSIZE];
        int                             bigblocknr;
        struct storage_pps_entry        root;
@@ -655,7 +654,7 @@ STORAGE_get_pps_entry(stream_access16*str,int n,struct storage_pps_entry *pstde)
  *             STORAGE_put_pps_entry   [Internal]
  */
 static int
-STORAGE_put_pps_entry(stream_access16*str,int n,struct storage_pps_entry *pstde) {
+STORAGE_put_pps_entry(stream_access16*str,int n,const struct storage_pps_entry *pstde) {
        int     blocknr;
        BYTE    block[BIGSIZE];
        struct storage_pps_entry *stde = (struct storage_pps_entry*)(((LPBYTE)block)+128*(n&3));
index 97f53df..584b132 100644 (file)
@@ -91,7 +91,7 @@ static StorageInternalImpl* StorageInternalImpl_Construct(StorageImpl* ancestorS
                                                           DWORD openFlags, ULONG rootTropertyIndex);
 static void StorageImpl_Destroy(StorageBaseImpl* iface);
 static BOOL StorageImpl_ReadBigBlock(StorageImpl* This, ULONG blockIndex, void* buffer);
-static BOOL StorageImpl_WriteBigBlock(StorageImpl* This, ULONG blockIndex, void* buffer);
+static BOOL StorageImpl_WriteBigBlock(StorageImpl* This, ULONG blockIndex, const void* buffer);
 static void StorageImpl_SetNextBlockInChain(StorageImpl* This, ULONG blockIndex, ULONG nextBlock);
 static HRESULT StorageImpl_LoadFileHeader(StorageImpl* This);
 static void StorageImpl_SaveFileHeader(StorageImpl* This);
@@ -279,7 +279,7 @@ static HRESULT StorageImpl_ReadAt(StorageImpl* This,
 
 static HRESULT StorageImpl_WriteAt(StorageImpl* This,
   ULARGE_INTEGER offset,
-  void*          buffer,
+  const void*    buffer,
   const ULONG    size,
   ULONG*         bytesWritten)
 {
@@ -753,6 +753,7 @@ static HRESULT WINAPI StorageBaseImpl_Stat(
       grfStatFlag);
 
     pstatstg->grfMode = This->openFlags;
+    pstatstg->grfStateBits = This->stateBits;
 
     res = S_OK;
     goto end;
@@ -2352,8 +2353,9 @@ static HRESULT WINAPI StorageImpl_SetStateBits(
   DWORD         grfStateBits,/* [in] */
   DWORD         grfMask)     /* [in] */
 {
-  FIXME("not implemented!\n");
-  return E_NOTIMPL;
+  StorageImpl* const This = (StorageImpl*)iface;
+  This->base.stateBits = (This->base.stateBits & ~grfMask) | (grfStateBits & grfMask);
+  return S_OK;
 }
 
 /*
@@ -3371,9 +3373,9 @@ BOOL StorageImpl_ReadProperty(
  * Write the specified property into the property chain
  */
 BOOL StorageImpl_WriteProperty(
-  StorageImpl* This,
-  ULONG          index,
-  StgProperty*   buffer)
+  StorageImpl*          This,
+  ULONG                 index,
+  const StgProperty*    buffer)
 {
   BYTE           currentProperty[PROPSET_BLOCK_SIZE];
   ULARGE_INTEGER offsetInPropSet;
@@ -3490,9 +3492,9 @@ static BOOL StorageImpl_ReadDWordFromBigBlock(
 }
 
 static BOOL StorageImpl_WriteBigBlock(
-  StorageImpl* This,
-  ULONG          blockIndex,
-  void*          buffer)
+  StorageImpl*  This,
+  ULONG         blockIndex,
+  const void*   buffer)
 {
   ULARGE_INTEGER ulOffset;
   DWORD  wrote;
@@ -4223,16 +4225,13 @@ static StorageInternalImpl* StorageInternalImpl_Construct(
   /*
    * Allocate space for the new storage object
    */
-  newStorage = HeapAlloc(GetProcessHeap(), 0, sizeof(StorageInternalImpl));
+  newStorage = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(StorageInternalImpl));
 
   if (newStorage!=0)
   {
-    memset(newStorage, 0, sizeof(StorageInternalImpl));
-
     /*
      * Initialize the stream list
      */
-
     list_init(&newStorage->base.strmHead);
 
     /*
@@ -4338,9 +4337,9 @@ void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value)
 }
 
 void StorageUtl_CopyPropertyToSTATSTG(
-  STATSTG*     destination,
-  StgProperty* source,
-  int          statFlags)
+  STATSTG*              destination,
+  const StgProperty*    source,
+  int                   statFlags)
 {
   /*
    * The copy of the string occurs only when the flag is not set
@@ -4644,10 +4643,6 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This,
     return STG_E_DOCFILECORRUPT;
   }
 
-  /*
-   * Here, I'm casting away the constness on the buffer variable
-   * This is OK since we don't intend to modify that buffer.
-   */
   *bytesWritten   = 0;
   bufferWalker = (const BYTE*)buffer;
 
@@ -4668,7 +4663,7 @@ HRESULT BlockChainStream_WriteAt(BlockChainStream* This,
 
     StorageImpl_WriteAt(This->parentStorage,
          ulOffset,
-         (BYTE*)bufferWalker,
+         bufferWalker,
          bytesToWrite,
          &bytesWrittenAt);
 
@@ -5683,6 +5678,10 @@ HRESULT WINAPI StgCreateDocfile(
   if (reserved != 0)
     return STG_E_INVALIDPARAMETER;
 
+  /* if no share mode given then DENY_NONE is the default */
+  if (STGM_SHARE_MODE(grfMode) == 0)
+      grfMode |= STGM_SHARE_DENY_NONE;
+
   /*
    * Validate the STGM flags
    */
@@ -5699,14 +5698,6 @@ HRESULT WINAPI StgCreateDocfile(
     goto end;
   }
 
-  /* if no share mode given then DENY_NONE is the default */     
-  if (STGM_SHARE_MODE(grfMode) == 0)
-    grfMode |= STGM_SHARE_DENY_NONE;
-
-  /* must have at least one access mode */
-  if (STGM_ACCESS_MODE(grfMode) == 0)
-    goto end;
-  
   /* in direct mode, can only use SHARE_EXCLUSIVE */
   if (!(grfMode & STGM_TRANSACTED) && (STGM_SHARE_MODE(grfMode) != STGM_SHARE_EXCLUSIVE))
     goto end;
@@ -6869,7 +6860,7 @@ static HRESULT OLECONVERT_SaveOLE10(OLECONVERT_OLESTREAM_DATA *pData, LPOLESTREA
  *
  *
  */
-static void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, BYTE *pBuffer, DWORD nBufferLength)
+static void OLECONVERT_GetOLE20FromOLE10(LPSTORAGE pDestStorage, const BYTE *pBuffer, DWORD nBufferLength)
 {
     HRESULT hRes;
     HANDLE hFile;
@@ -7419,7 +7410,7 @@ static void OLECONVERT_CreateOlePresStream(LPSTORAGE pStorage, DWORD dwExtentX,
  *     Might need to verify the data and return appropriate error message
  *
  */
-static void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, BYTE *pData, DWORD dwDataLength)
+static void OLECONVERT_CreateOle10NativeStream(LPSTORAGE pStorage, const BYTE *pData, DWORD dwDataLength)
 {
     HRESULT hRes;
     IStream *pStream;
index ffad550..76db895 100644 (file)
@@ -189,7 +189,7 @@ void           BIGBLOCKFILE_SetSize(LPBIGBLOCKFILE This, ULARGE_INTEGER newSize)
 HRESULT        BIGBLOCKFILE_ReadAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
            void* buffer, ULONG size, ULONG* bytesRead);
 HRESULT        BIGBLOCKFILE_WriteAt(LPBIGBLOCKFILE This, ULARGE_INTEGER offset,
-           void* buffer, const ULONG size, ULONG* bytesRead);
+           const void* buffer, ULONG size, ULONG* bytesRead);
 
 /*************************************************************************
  * Ole Convert support
@@ -245,6 +245,11 @@ struct StorageBaseImpl
    * flags that this storage was opened or created with
    */
   DWORD openFlags;
+
+  /*
+   * State bits appear to only be preserved while running. No in the stream
+   */
+  DWORD stateBits;
 };
 
 /****************************************************************************
@@ -306,14 +311,14 @@ struct StorageImpl
 };
 
 BOOL StorageImpl_ReadProperty(
-            StorageImpl* This,
-           ULONG          index,
-           StgProperty*    buffer);
+            StorageImpl*    This,
+            ULONG           index,
+            StgProperty*    buffer);
 
 BOOL StorageImpl_WriteProperty(
-            StorageImpl* This,
-           ULONG          index,
-           StgProperty*   buffer);
+            StorageImpl*        This,
+            ULONG               index,
+            const StgProperty*  buffer);
 
 BlockChainStream* Storage32Impl_SmallBlocksToBigBlocks(
                       StorageImpl* This,
@@ -418,9 +423,8 @@ void StorageUtl_WriteULargeInteger(BYTE* buffer, ULONG offset,
  const ULARGE_INTEGER *value);
 void StorageUtl_ReadGUID(const BYTE* buffer, ULONG offset, GUID* value);
 void StorageUtl_WriteGUID(BYTE* buffer, ULONG offset, const GUID* value);
-void StorageUtl_CopyPropertyToSTATSTG(STATSTG*     destination,
-                                            StgProperty* source,
-                                            int          statFlags);
+void StorageUtl_CopyPropertyToSTATSTG(STATSTG* destination, const StgProperty* source,
+ int statFlags);
 
 /****************************************************************************
  * BlockChainStream definitions.
index 76e07a2..2243f33 100644 (file)
@@ -364,7 +364,7 @@ HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub
 {
     /* FIXME: hack for IRemUnknown */
     if (ipid->Data2 == 0xffff)
-        *stub_apt = apartment_findfromoxid(*(OXID *)ipid->Data4, TRUE);
+        *stub_apt = apartment_findfromoxid(*(const OXID *)ipid->Data4, TRUE);
     else
         *stub_apt = apartment_findfromtid(ipid->Data2);
     if (!*stub_apt)