Sync to Wine-20050310:
Jon Griffiths <jon_p_griffiths@yahoo.com>
- Documentation spelling fixes.
Mike McCormack <mike@codeweavers.com>
- Implement and test IPropertySetStorage.
- Fix more incorrect uses of STGM_ enumerations.
- Add struct StorageBaseImpl at the start of derived structures instead
  of trying to keep the first members the same.
- StgOpenStorage shouldn't open zero length storage files.
- Shared reading of storage files requires STGM_TRANSACTED.
- Test and fix grfMode handling in StgOpenDocfile.
- Implement StgSetTimes.
Robert Shearman <rob@codeweavers.com>
- Better tracing.
- Small cleanup of creation functions.
- Rename apartment functions to become more object-oriented.
- Rename register_ifstub to marshal_object to more accurately describe
  what it does.
- Add new function, apartment_getoxid, to prepare for a possible
  future patch where remoting is started on demand.
- Move marshaling state machine into stub manager from ifstub.
- Add additional needed states for table-weak marshaling, as shown by
  tests.
- Protect external reference count from underflows/overflows.
- Make COM use the RPC runtime as the backend for RPC calls. Based on a
  patch by Ove Ksven.
- Invoke objects in STA's in the correct thread by sending messages to
  the hidden apartment window.
- Use I_RpcGetBuffer, instead of our own buffer routines to fix an
  occasional test crash caused by heap corruption.
- Zero the memory block passed to RpcServerRegisterIfEx so we don't
  pass garbage in some of the fields we don't fill in.
- Return the correct error code from create_server and fix two handle
  leaks.
- TODO update.
- Remove cruft left over from previous RPC backend implementation in
  the apartment structure.
- Don't pass an IPID by value for proxy_manager_create_ifproxy.
- Disable more of RPC_UnregisterInterface to prevent the RPC runtime
  using freed memory.
- Rename various external RPC backend functions so that they all have
  the same "RPC_" prefix.
- Reduce the timeout of the function that connects to a local server
  to 30s, like native.
- Make each ifproxy have its own channel buffer to fix a bug where a
  proxy with multiple interfaces could invoke the wrong stub buffer on
  the server.
- The Global Interface Table should do table-strong marshaling instead
  of normal marshaling so that an interface can be retrieved more than
  one time.
Mike Hearn <mh@codeweavers.com>
- Avoid infinite loop when doing a typelib marshalled
  IUnknown::QueryInterface by only doing an extra QI if requested IID is
  not equal to marshalled IID.
Rob Shearman <rob@codeweavers.com>
Mike Hearn <mh@codeweavers.com>
- Add re-entrancy tests to the test suite.
- Run RPCs on a new thread client side so we can pump the message
  loop.
Juan Lang <juan_lang@yahoo.com>
- Fix the calling convention of DllCanUnloadNow.
- Move vtbl to end of file and get rid of unnecessary prototypes.
- Implement StgCreatePropSetStg.
Joris Huizer <jorishuizer@planet.nl>
- A few memory checks avoiding memory leaks.
Francois Gouget <fgouget@free.fr>
- Assorted spelling fixes.
Paul Vriens <Paul.Vriens@xs4all.nl>
- Added some TRACE statements.
Modified: trunk/reactos/lib/ole32/Makefile.in
Modified: trunk/reactos/lib/ole32/clipboard.c
Modified: trunk/reactos/lib/ole32/compobj.c
Modified: trunk/reactos/lib/ole32/compobj_private.h
Modified: trunk/reactos/lib/ole32/errorinfo.c
Modified: trunk/reactos/lib/ole32/filemoniker.c
Modified: trunk/reactos/lib/ole32/git.c
Modified: trunk/reactos/lib/ole32/itemmoniker.c
Modified: trunk/reactos/lib/ole32/marshal.c
Modified: trunk/reactos/lib/ole32/ole2.c
Modified: trunk/reactos/lib/ole32/ole32.spec
Modified: trunk/reactos/lib/ole32/oleproxy.c
Modified: trunk/reactos/lib/ole32/rpc.c
Modified: trunk/reactos/lib/ole32/stg_bigblockfile.c
Added: trunk/reactos/lib/ole32/stg_prop.c
Modified: trunk/reactos/lib/ole32/stg_stream.c
Modified: trunk/reactos/lib/ole32/storage32.c
Modified: trunk/reactos/lib/ole32/storage32.h
Modified: trunk/reactos/lib/ole32/stubmanager.c

Modified: trunk/reactos/lib/ole32/Makefile.in
--- trunk/reactos/lib/ole32/Makefile.in	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/Makefile.in	2005-03-14 23:17:44 UTC (rev 14083)
@@ -34,6 +34,7 @@
 	regsvr.c \
 	rpc.c \
 	stg_bigblockfile.c \
+	stg_prop.c \
 	stg_stream.c \
 	storage32.c \
 	stubmanager.c

Modified: trunk/reactos/lib/ole32/clipboard.c
--- trunk/reactos/lib/ole32/clipboard.c	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/clipboard.c	2005-03-14 23:17:44 UTC (rev 14083)
@@ -82,7 +82,7 @@
 
 /* For CoGetMalloc (MEMCTX_TASK is currently ignored) */
 #ifndef MEMCTX_TASK
-  #define MEMCTX_TASK -1
+# define MEMCTX_TASK -1
 #endif
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
@@ -799,7 +799,7 @@
      * (Recall that in OleSetClipboard, we used SetClipboardData to
      * make all HGLOBAL formats supported by the source IDataObject
      * available using delayed rendering)
-     * On receiving this mesage we must actually render the data in the
+     * On receiving this message we must actually render the data in the
      * specified format and place it on the clipboard by calling the
      * SetClipboardData function.
      */

Modified: trunk/reactos/lib/ole32/compobj.c
--- trunk/reactos/lib/ole32/compobj.c	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/compobj.c	2005-03-14 23:17:44 UTC (rev 14083)
@@ -30,13 +30,12 @@
  *
  *   - Implement the service control manager (in rpcss) to keep track
  *     of registered class objects: ISCM::ServerRegisterClsid et al
- *   - Implement the OXID resolver so we don't need magic pipe names for
+ *   - Implement the OXID resolver so we don't need magic endpoint names for
  *     clients and servers to meet up
- *   - Flip our marshalling on top of the RPC runtime transport API,
- *     so we no longer use named pipes to communicate
- *   - Implement RPC thread affinity (should fix InstallShield painting
- *     problems)
  *
+ *   - Pump the message loop during RPC calls.
+ *   - Call IMessageFilter functions.
+ *
  *   - Make all ole interface marshaling use NDR to be wire compatible with
  *     native DCOM
  *   - Use & interpret ORPCTHIS & ORPCTHAT.
@@ -163,7 +162,7 @@
 };
 static CRITICAL_SECTION csOpenDllList = { &dll_cs_debug, -1, 0, 0, 0, 0 };
 
-static const char aptWinClass[] = "WINE_OLE32_APT_CLASS";
+static const WCHAR wszAptWinClass[] = {'W','I','N','E','_','O','L','E','3','2','_','A','P','T','_','C','L','A','S','S',0};
 static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam);
 
 static void COMPOBJ_DLLList_Add(HANDLE hLibrary);
@@ -171,7 +170,7 @@
 
 void COMPOBJ_InitProcess( void )
 {
-    WNDCLASSA wclass;
+    WNDCLASSW wclass;
 
     /* Dispatching to the correct thread in an apartment is done through
      * window messages rather than RPC transports. When an interface is
@@ -183,15 +182,15 @@
      * was unmarshalled.
      */
     memset(&wclass, 0, sizeof(wclass));
-    wclass.lpfnWndProc = &COM_AptWndProc;
+    wclass.lpfnWndProc = COM_AptWndProc;
     wclass.hInstance = OLE32_hInstance;
-    wclass.lpszClassName = aptWinClass;
-    RegisterClassA(&wclass);
+    wclass.lpszClassName = wszAptWinClass;
+    RegisterClassW(&wclass);
 }
 
 void COMPOBJ_UninitProcess( void )
 {
-    UnregisterClassA(aptWinClass, OLE32_hInstance);
+    UnregisterClassW(wszAptWinClass, OLE32_hInstance);
 }
 
 void COM_TlsDestroy()
@@ -239,7 +238,7 @@
     {
         /* FIXME: should be randomly generated by in an RPC call to rpcss */
         apt->oxid = ((OXID)GetCurrentProcessId() << 32) | GetCurrentThreadId();
-        apt->win = CreateWindowA(aptWinClass, NULL, 0,
+        apt->win = CreateWindowW(wszAptWinClass, NULL, 0,
                                  0, 0, 0, 0,
                                  0, 0, OLE32_hInstance, NULL);
     }
@@ -249,8 +248,6 @@
         apt->oxid = ((OXID)GetCurrentProcessId() << 32) | 0xcafe;
     }
 
-    apt->shutdown_event = CreateEventW(NULL, TRUE, FALSE, NULL);
-    
     TRACE("Created apartment on OXID %s\n", wine_dbgstr_longlong(apt->oxid));
 
     /* the locking here is not currently needed for the MTA case, but it
@@ -354,8 +351,6 @@
         if (apt->filter) IUnknown_Release(apt->filter);
 
         DeleteCriticalSection(&apt->cs);
-        SetEvent(apt->shutdown_event);
-        CloseHandle(apt->shutdown_event);
         CloseHandle(apt->thread);
         HeapFree(GetProcessHeap(), 0, apt);
     }
@@ -425,10 +420,15 @@
     return apt->win;
 }
 
-/* Currently inter-thread marshalling is not fully implemented, so this does nothing */
 static LRESULT CALLBACK COM_AptWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
-  return DefWindowProcA(hWnd, msg, wParam, lParam);
+    switch (msg)
+    {
+    case DM_EXECUTERPC:
+        return RPC_ExecuteCall((RPCOLEMESSAGE *)wParam, (IRpcStubBuffer *)lParam);
+    default:
+        return DefWindowProcW(hWnd, msg, wParam, lParam);
+    }
 }
 
 /*****************************************************************************
@@ -473,7 +473,7 @@
 static void COMPOBJ_DllList_FreeUnused(int Timeout)
 {
     OpenDll *curr, *next, *prev = NULL;
-    typedef HRESULT(*DllCanUnloadNowFunc)(void);
+    typedef HRESULT (WINAPI *DllCanUnloadNowFunc)(void);
     DllCanUnloadNowFunc DllCanUnloadNow;
 
     TRACE("\n");
@@ -1629,7 +1629,7 @@
     /* Next try out of process */
     if (CLSCTX_LOCAL_SERVER & dwClsContext)
     {
-        return create_marshalled_proxy(rclsid,iid,ppv);
+        return RPC_GetLocalClassObject(rclsid,iid,ppv);
     }
 
     /* Finally try remote: this requires networked DCOM (a lot of work) */

Modified: trunk/reactos/lib/ole32/compobj_private.h
--- trunk/reactos/lib/ole32/compobj_private.h	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/compobj_private.h	2005-03-14 23:17:44 UTC (rev 14083)
@@ -53,10 +53,12 @@
 
 typedef enum ifstub_state
 {
-    IFSTUB_STATE_NORMAL_MARSHALED,
-    IFSTUB_STATE_NORMAL_UNMARSHALED,
-    IFSTUB_STATE_TABLE_MARSHALED
-} IFSTUB_STATE;
+    STUBSTATE_NORMAL_MARSHALED,
+    STUBSTATE_NORMAL_UNMARSHALED,
+    STUBSTATE_TABLE_WEAK_MARSHALED,
+    STUBSTATE_TABLE_WEAK_UNMARSHALED,
+    STUBSTATE_TABLE_STRONG,
+} STUB_STATE;
 
 /* an interface stub */
 struct ifstub   
@@ -66,7 +68,6 @@
     IID               iid;        /* RO */
     IPID              ipid;       /* RO */
     IUnknown         *iface;      /* RO */
-    IFSTUB_STATE      state;      /* CS stub_manager->lock */
 };
 
 
@@ -78,11 +79,12 @@
     CRITICAL_SECTION  lock;
     APARTMENT        *apt;        /* owning apt (RO) */
 
-    ULONG             extrefs;    /* number of 'external' references (LOCK) */
+    ULONG             extrefs;    /* number of 'external' references (CS lock) */
     ULONG             refs;       /* internal reference count (CS apt->cs) */
     OID               oid;        /* apartment-scoped unique identifier (RO) */
     IUnknown         *object;     /* the object we are managing the stub for (RO) */
     ULONG             next_ipid;  /* currently unused (LOCK) */
+    STUB_STATE        state;      /* state machine (CS lock) */
 };
 
 /* imported interface proxy */
@@ -95,6 +97,7 @@
   IPID ipid;               /* imported interface ID (RO) */
   LPRPCPROXYBUFFER proxy;  /* interface proxy (RO) */
   DWORD refs;              /* imported (public) references (CS parent->cs) */
+  IRpcChannelBuffer *chan; /* channel to object (CS parent->cs) */
 };
 
 /* imported object / proxy manager */
@@ -103,7 +106,6 @@
   const IMultiQIVtbl *lpVtbl;
   struct apartment *parent; /* owning apartment (RO) */
   struct list entry;        /* entry in apartment (CS parent->cs) */
-  LPRPCCHANNELBUFFER chan;  /* channel to object (CS cs) */
   OXID oxid;                /* object exported ID (RO) */
   OID oid;                  /* object ID (RO) */
   struct list interfaces;   /* imported interfaces (CS cs) */
@@ -130,11 +132,10 @@
   struct list proxies;     /* imported objects (CS cs) */
   struct list stubmgrs;    /* stub managers for exported objects (CS cs) */
   BOOL remunk_exported;    /* has the IRemUnknown interface for this apartment been created yet? (CS cs) */
+  LONG remoting_started;   /* has the RPC system been started for this apartment? (LOCK) */
 
-  /* FIXME: These should all be removed long term as they leak information that should be encapsulated */
+  /* FIXME: OID's should be given out by RPCSS */
   OID oidc;                /* object ID counter, starts at 1, zero is invalid OID (CS cs) */
-  DWORD listenertid;       /* id of apartment_listener_thread */
-  HANDLE shutdown_event;   /* event used to tell the client_dispatch_thread to shut down */
 };
 
 /* this is what is stored in TEB->ReservedForOle */
@@ -146,60 +147,50 @@
     DWORD            inits;        /* number of times CoInitializeEx called */
 };
 
+
+/* Global Interface Table Functions */
+
 extern void* StdGlobalInterfaceTable_Construct(void);
 extern void  StdGlobalInterfaceTable_Destroy(void* self);
 extern HRESULT StdGlobalInterfaceTable_GetFactory(LPVOID *ppv);
+extern void* StdGlobalInterfaceTableInstance;
 
 /* FIXME: these shouldn't be needed, except for 16-bit functions */
 extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
 HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
 
-extern HRESULT create_marshalled_proxy(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
-
-extern void* StdGlobalInterfaceTableInstance;
-
-/* Standard Marshalling definitions */
-typedef struct _wine_marshal_id {
-    OXID    oxid;       /* id of apartment */
-    OID     oid;        /* id of stub manager */
-    IPID    ipid;       /* id of interface pointer */
-} wine_marshal_id;
-
-inline static BOOL
-MARSHAL_Compare_Mids(wine_marshal_id *mid1,wine_marshal_id *mid2) {
-    return
-	(mid1->oxid == mid2->oxid)	&&
-	(mid1->oid == mid2->oid)	&&
-	IsEqualGUID(&(mid1->ipid),&(mid2->ipid))
-    ;
-}
-
 HRESULT MARSHAL_Disconnect_Proxies(APARTMENT *apt);
 HRESULT MARSHAL_GetStandardMarshalCF(LPVOID *ppv);
 
+/* Stub Manager */
+
 ULONG stub_manager_int_addref(struct stub_manager *This);
 ULONG stub_manager_int_release(struct stub_manager *This);
-struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object);
+struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object, MSHLFLAGS mshlflags);
 ULONG stub_manager_ext_addref(struct stub_manager *m, ULONG refs);
 ULONG stub_manager_ext_release(struct stub_manager *m, ULONG refs);
-struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, BOOL tablemarshal);
+struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid);
 struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid);
 struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object);
 void apartment_disconnect_object(APARTMENT *apt, void *object);
-BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid);
-BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid);
+BOOL stub_manager_notify_unmarshal(struct stub_manager *m);
+BOOL stub_manager_is_table_marshaled(struct stub_manager *m);
+void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs);
 HRESULT register_ifstub(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *obj, MSHLFLAGS mshlflags);
 HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret);
-IRpcStubBuffer *ipid_to_stubbuffer(const IPID *ipid);
+IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt);
 HRESULT start_apartment_remote_unknown(void);
 
-IRpcStubBuffer *mid_to_stubbuffer(wine_marshal_id *mid);
+/* RPC Backend */
 
-void start_apartment_listener_thread(void);
+void    RPC_StartRemoting(struct apartment *apt);
+HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **pipebuf);
+HRESULT RPC_ExecuteCall(RPCOLEMESSAGE *msg, IRpcStubBuffer *stub);
+HRESULT RPC_RegisterInterface(REFIID riid);
+void    RPC_UnregisterInterface(REFIID riid);
+void    RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
+HRESULT RPC_GetLocalClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv);
 
-extern HRESULT PIPE_GetNewPipeBuf(wine_marshal_id *mid, IRpcChannelBuffer **pipebuf);
-void RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
-
 /* This function initialize the Running Object Table */
 HRESULT WINAPI RunningObjectTableImpl_Initialize(void);
 
@@ -209,12 +200,17 @@
 /* This function decomposes a String path to a String Table containing all the elements ("\" or "subDirectory" or "Directory" or "FileName") of the path */
 int WINAPI FileMonikerImpl_DecomposePath(LPCOLESTR str, LPOLESTR** stringTable);
 
-/* compobj.c */
+
+/* Apartment Functions */
+
 APARTMENT *COM_ApartmentFromOXID(OXID oxid, BOOL ref);
 APARTMENT *COM_ApartmentFromTID(DWORD tid);
 DWORD COM_ApartmentAddRef(struct apartment *apt);
 DWORD COM_ApartmentRelease(struct apartment *apt);
 
+/* messages used by the apartment window (not compatible with native) */
+#define DM_EXECUTERPC   (WM_USER + 0) /* WPARAM = (RPCOLEMESSAGE *), LPARAM = (IRpcStubBuffer *) */
+
 /*
  * Per-thread values are stored in the TEB on offset 0xF80,
  * see http://www.microsoft.com/msj/1099/bugslayer/bugslayer1099.htm

Modified: trunk/reactos/lib/ole32/errorinfo.c
--- trunk/reactos/lib/ole32/errorinfo.c	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/errorinfo.c	2005-03-14 23:17:44 UTC (rev 14083)
@@ -386,11 +386,10 @@
 	LPOLESTR szHelpFile)
 {
 	_ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);
-	TRACE("(%p)\n",This);
+	TRACE("(%p,%s)\n",This,debugstr_w(szHelpFile));
 	if (This->bstrHelpFile != NULL)
 	    ERRORINFO_SysFreeString(This->bstrHelpFile);
 	This->bstrHelpFile = ERRORINFO_SysAllocString(szHelpFile);
-
 	return S_OK;
 }
 
@@ -399,9 +398,8 @@
  	DWORD dwHelpContext)
 {
 	_ICOM_THIS_From_ICreateErrorInfo(ErrorInfoImpl, iface);
-	TRACE("(%p)\n",This);
+	TRACE("(%p,%ld)\n",This,dwHelpContext);
 	This->m_dwHelpContext = dwHelpContext;
-
 	return S_OK;
 }
 

Modified: trunk/reactos/lib/ole32/filemoniker.c
--- trunk/reactos/lib/ole32/filemoniker.c	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/filemoniker.c	2005-03-14 23:17:44 UTC (rev 14083)
@@ -157,7 +157,7 @@
 {
     FileMonikerImpl *This = (FileMonikerImpl *)iface;
 
-  TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
+  TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
 
     /* Perform a sanity check on the parameters.*/
     if ( (This==0) || (ppvObject==0) )
@@ -223,7 +223,7 @@
 HRESULT WINAPI FileMonikerImpl_GetClassID(IMoniker* iface,
                                           CLSID *pClassID)/* Pointer to CLSID of object */
 {
-    TRACE("(%p,%p),stub!\n",iface,pClassID);
+    TRACE("(%p,%p)\n",iface,pClassID);
 
     if (pClassID==NULL)
         return E_POINTER;
@@ -473,7 +473,7 @@
     static const WCHAR bkSlash[]={'\\',0};
     BYTE addBkSlash;
 
-    TRACE("(%p,%p)\n",This,lpszPathName);
+    TRACE("(%p,%s)\n",This,debugstr_w(lpszPathName));
 
     /* Initialize the virtual fgunction table. */
     This->lpvtbl1      = &VT_FileMonikerImpl;
@@ -566,7 +566,7 @@
 
     *ppvResult=0;
 
-    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
 
     if(pmkToLeft==NULL){
 
@@ -673,7 +673,7 @@
     IStorage *pstg=0;
     HRESULT res;
 
-    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject);
+    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvObject);
 
     if (pmkToLeft==NULL){
 
@@ -708,7 +708,7 @@
     }
     else {
 
-        FIXME("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvObject);
+        FIXME("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvObject);
 
         return E_NOTIMPL;
     }
@@ -1243,6 +1243,8 @@
 
     strcpyW(*ppszDisplayName,This->filePathName);
 
+    TRACE("-- %s\n", debugstr_w(*ppszDisplayName));
+    
     return S_OK;
 }
 
@@ -1283,7 +1285,7 @@
 
     ICOM_THIS_From_IROTData(IMoniker, iface);
 
-    TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
+    TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
 
     return FileMonikerImpl_QueryInterface(This, riid, ppvObject);
 }
@@ -1329,29 +1331,28 @@
  ******************************************************************************/
 HRESULT WINAPI CreateFileMoniker(LPCOLESTR lpszPathName, LPMONIKER * ppmk)
 {
-    FileMonikerImpl* newFileMoniker = 0;
-    HRESULT  hr = E_FAIL;
-    IID riid=IID_IMoniker;
+    FileMonikerImpl* newFileMoniker;
+    HRESULT  hr;
 
-    TRACE("(%p,%p)\n",lpszPathName,ppmk);
+    TRACE("(%s,%p)\n",debugstr_w(lpszPathName),ppmk);
 
-    if (ppmk==NULL)
+    if (!ppmk)
         return E_POINTER;
 
-    if(lpszPathName==NULL)
+    if(!lpszPathName)
         return MK_E_SYNTAX;
 
-    *ppmk=0;
+    *ppmk=NULL;
 
     newFileMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(FileMonikerImpl));
 
-    if (newFileMoniker == 0)
+    if (!newFileMoniker)
         return E_OUTOFMEMORY;
 
     hr = FileMonikerImpl_Construct(newFileMoniker,lpszPathName);
 
     if (SUCCEEDED(hr))
-	hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&riid,(void**)ppmk);
+	hr = FileMonikerImpl_QueryInterface((IMoniker*)newFileMoniker,&IID_IMoniker,(void**)ppmk);
     else
         HeapFree(GetProcessHeap(),0,newFileMoniker);
 

Modified: trunk/reactos/lib/ole32/git.c
--- trunk/reactos/lib/ole32/git.c	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/git.c	2005-03-14 23:17:44 UTC (rev 14083)
@@ -223,6 +223,7 @@
   IStream* stream = NULL;
   HRESULT hres;
   StdGITEntry* entry;
+  static const LARGE_INTEGER zero;
 
   TRACE("iface=%p, pUnk=%p, riid=%s, pdwCookie=0x%p\n", iface, pUnk, debugstr_guid(riid), pdwCookie);
 
@@ -230,8 +231,18 @@
   
   /* marshal the interface */
   TRACE("About to marshal the interface\n");
-  hres = CoMarshalInterThreadInterfaceInStream(riid, pUnk, &stream);
+
+  hres = CreateStreamOnHGlobal(0, TRUE, &stream);
   if (hres) return hres;
+  hres = CoMarshalInterface(stream, riid, pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_TABLESTRONG);
+  if (hres)
+  {
+    IStream_Release(stream);
+    return hres;
+  }
+
+  IStream_Seek(stream, zero, SEEK_SET, NULL);
+
   entry = HeapAlloc(GetProcessHeap(), 0, sizeof(StdGITEntry));
   if (entry == NULL) return E_OUTOFMEMORY;
 
@@ -261,6 +272,7 @@
 HRESULT WINAPI StdGlobalInterfaceTable_RevokeInterfaceFromGlobal(IGlobalInterfaceTable* iface, DWORD dwCookie) {
   StdGlobalInterfaceTableImpl* const self = (StdGlobalInterfaceTableImpl*) iface;
   StdGITEntry* entry;
+  HRESULT hr;
 
   TRACE("iface=%p, dwCookie=0x%x\n", iface, (UINT)dwCookie);
   
@@ -271,6 +283,12 @@
   }
   
   /* Free the stream */
+  hr = CoReleaseMarshalData(entry->stream);
+  if (hr != S_OK)
+  {
+    WARN("Failed to release marshal data, hr = 0x%08lx\n", hr);
+    return hr;
+  }
   IStream_Release(entry->stream);
 		    
   /* chop entry out of the list, and free the memory */

Modified: trunk/reactos/lib/ole32/itemmoniker.c
--- trunk/reactos/lib/ole32/itemmoniker.c	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/itemmoniker.c	2005-03-14 23:17:44 UTC (rev 14083)
@@ -156,7 +156,7 @@
 {
     ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
 
-  TRACE("(%p,%p,%p)\n",This,riid,ppvObject);
+  TRACE("(%p,%s,%p)\n",This,debugstr_guid(riid),ppvObject);
 
   /* Perform a sanity check on the parameters.*/
     if ( (This==0) || (ppvObject==0) )
@@ -221,7 +221,7 @@
  ******************************************************************************/
 HRESULT WINAPI ItemMonikerImpl_GetClassID(IMoniker* iface,CLSID *pClassID)
 {
-    TRACE("(%p,%p),stub!\n",iface,pClassID);
+    TRACE("(%p,%p)\n",iface,pClassID);
 
     if (pClassID==NULL)
         return E_POINTER;
@@ -257,6 +257,8 @@
     CHAR *itemNameA,*itemDelimiterA;
     ULONG bread;
 
+    TRACE("\n");
+
     /* for more details about data read by this function see coments of ItemMonikerImpl_Save function */
 
     /* read item delimiter string length + 1 */
@@ -335,6 +337,8 @@
     WideCharToMultiByte( CP_ACP, 0, This->itemName, -1, itemNameA, nameLength, NULL, NULL);
     WideCharToMultiByte( CP_ACP, 0, This->itemDelimiter, -1, itemDelimiterA, delimiterLength, NULL, NULL);
 
+    TRACE("%p, %s\n", pStm, fClearDirty ? "TRUE" : "FALSE");
+
     res=IStream_Write(pStm,&delimiterLength,sizeof(DWORD),NULL);
     res=IStream_Write(pStm,itemDelimiterA,delimiterLength * sizeof(CHAR),NULL);
     res=IStream_Write(pStm,&nameLength,sizeof(DWORD),NULL);
@@ -381,7 +385,7 @@
     static const OLECHAR emptystr[1];
     LPCOLESTR	delim;
 
-    TRACE("(%p,%p)\n",This,lpszItem);
+    TRACE("(%p,%s,%s)\n",This,debugstr_w(lpszDelim),debugstr_w(lpszItem));
 
     /* Initialize the virtual fgunction table. */
     This->lpvtbl1      = &VT_ItemMonikerImpl;
@@ -437,7 +441,7 @@
     IID    refid=IID_IOleItemContainer;
     IOleItemContainer *poic=0;
 
-    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
 
     if(ppvResult ==NULL)
         return E_POINTER;
@@ -473,7 +477,7 @@
     HRESULT   res;
     IOleItemContainer *poic=0;
 
-    TRACE("(%p,%p,%p,%p,%p)\n",iface,pbc,pmkToLeft,riid,ppvResult);
+    TRACE("(%p,%p,%p,%s,%p)\n",iface,pbc,pmkToLeft,debugstr_guid(riid),ppvResult);
 
     *ppvResult=0;
 
@@ -781,6 +785,9 @@
 HRESULT WINAPI ItemMonikerImpl_CommonPrefixWith(IMoniker* iface,IMoniker* pmkOther,IMoniker** ppmkPrefix)
 {
     DWORD mkSys;
+    
+    TRACE("(%p,%p)\n", pmkOther, ppmkPrefix);
+
     IMoniker_IsSystemMoniker(pmkOther,&mkSys);
     /* If the other moniker is an item moniker that is equal to this moniker, this method sets *ppmkPrefix */
     /* to this moniker and returns MK_S_US */
@@ -841,6 +848,8 @@
     lstrcpyW(*ppszDisplayName,This->itemDelimiter);
     lstrcatW(*ppszDisplayName,This->itemName);
 
+    TRACE("-- %s\n", debugstr_w(*ppszDisplayName));
+
     return S_OK;
 }
 
@@ -860,6 +869,8 @@
     HRESULT res;
     ItemMonikerImpl *This = (ItemMonikerImpl *)iface;
 
+    TRACE("%s\n", debugstr_w(pszDisplayName));
+
     /* If pmkToLeft is NULL, this method returns MK_E_SYNTAX */
     if (pmkToLeft==NULL)
 
@@ -955,15 +966,14 @@
  ******************************************************************************/
 HRESULT WINAPI CreateItemMoniker(LPCOLESTR lpszDelim,LPCOLESTR  lpszItem, LPMONIKER * ppmk)
 {
-    ItemMonikerImpl* newItemMoniker = 0;
-    HRESULT        hr = S_OK;
-    IID riid=IID_IMoniker;
+    ItemMonikerImpl* newItemMoniker;
+    HRESULT        hr;
 
-    TRACE("(%p,%p,%p)\n",lpszDelim,lpszItem,ppmk);
+    TRACE("(%s,%s,%p)\n",debugstr_w(lpszDelim),debugstr_w(lpszItem),ppmk);
 
     newItemMoniker = HeapAlloc(GetProcessHeap(), 0, sizeof(ItemMonikerImpl));
 
-    if (newItemMoniker == 0)
+    if (!newItemMoniker)
         return STG_E_INSUFFICIENTMEMORY;
 
     hr = ItemMonikerImpl_Construct(newItemMoniker,lpszDelim,lpszItem);
@@ -974,5 +984,5 @@
     return hr;
     }
 
-    return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&riid,(void**)ppmk);
+    return ItemMonikerImpl_QueryInterface((IMoniker*)newItemMoniker,&IID_IMoniker,(void**)ppmk);
 }

Modified: trunk/reactos/lib/ole32/marshal.c
--- trunk/reactos/lib/ole32/marshal.c	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/marshal.c	2005-03-14 23:17:44 UTC (rev 14083)
@@ -117,13 +117,15 @@
 
     stdobjref->oxid = apt->oxid;
 
+    /* FIXME: what happens if we register an interface twice with different
+     * marshaling flags? */
     if ((manager = get_stub_manager_from_object(apt, obj)))
         TRACE("registering new ifstub on pre-existing manager\n");
     else
     {
         TRACE("constructing new stub manager\n");
 
-        manager = new_stub_manager(apt, obj);
+        manager = new_stub_manager(apt, obj, mshlflags);
         if (!manager)
             return E_OUTOFMEMORY;
     }
@@ -131,7 +133,7 @@
 
     tablemarshal = ((mshlflags & MSHLFLAGS_TABLESTRONG) || (mshlflags & MSHLFLAGS_TABLEWEAK));
 
-    ifstub = stub_manager_new_ifstub(manager, stub, obj, riid, tablemarshal);
+    ifstub = stub_manager_new_ifstub(manager, stub, obj, riid);
     if (!ifstub)
     {
         IRpcStubBuffer_Release(stub);
@@ -153,6 +155,9 @@
             stub_manager_ext_addref(manager, 1);
     }
 
+    /* FIXME: check return value */
+    RPC_RegisterInterface(riid);
+
     stdobjref->ipid = ifstub->ipid;
 
     stub_manager_int_release(manager);
@@ -372,12 +377,17 @@
     return hr;
 }
 
+/* should be called inside This->parent->cs critical section */
 static void ifproxy_disconnect(struct ifproxy * This)
 {
     ifproxy_release_public_refs(This);
     if (This->proxy) IRpcProxyBuffer_Disconnect(This->proxy);
+
+    IRpcChannelBuffer_Release(This->chan);
+    This->chan = NULL;
 }
 
+/* should be called in This->parent->cs critical section if it is an entry in parent's list */
 static void ifproxy_destroy(struct ifproxy * This)
 {
     TRACE("%p\n", This);
@@ -388,6 +398,12 @@
 
     list_remove(&This->entry);
 
+    if (This->chan)
+    {
+        IRpcChannelBuffer_Release(This->chan);
+        This->chan = NULL;
+    }
+
     /* note: we don't call Release for This->proxy because its lifetime is
      * controlled by the return value from ClientIdentity_Release, which this
      * function is always called from */
@@ -397,7 +413,7 @@
 
 static HRESULT proxy_manager_construct(
     APARTMENT * apt, ULONG sorflags, OXID oxid, OID oid,
-    IRpcChannelBuffer * channel, struct proxy_manager ** proxy_manager)
+    struct proxy_manager ** proxy_manager)
 {
     struct proxy_manager * This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
     if (!This) return E_OUTOFMEMORY;
@@ -423,9 +439,6 @@
      * should store the STDOBJREF flags in the proxy manager. */
     This->sorflags = sorflags;
 
-    assert(channel);
-    This->chan = channel; /* FIXME: we should take the binding strings and construct the channel in this function */
-
     /* we create the IRemUnknown proxy on demand */
     This->remunk = NULL;
 
@@ -473,8 +486,8 @@
 }
 
 static HRESULT proxy_manager_create_ifproxy(
-    struct proxy_manager * This, IPID ipid, REFIID riid, ULONG cPublicRefs,
-    struct ifproxy ** iif_out)
+    struct proxy_manager * This, const IPID *ipid, REFIID riid, ULONG cPublicRefs,
+    IRpcChannelBuffer * channel, struct ifproxy ** iif_out)
 {
     HRESULT hr;
     IPSFactoryBuffer * psfb;
@@ -484,11 +497,14 @@
     list_init(&ifproxy->entry);
 
     ifproxy->parent = This;
-    ifproxy->ipid = ipid;
+    ifproxy->ipid = *ipid;
     ifproxy->iid = *riid;
     ifproxy->refs = cPublicRefs;
     ifproxy->proxy = NULL;
 
+    assert(channel);
+    ifproxy->chan = channel; /* FIXME: we should take the binding strings and construct the channel in this function */
+
     /* the IUnknown interface is special because it does not have a
      * proxy associated with the ifproxy as we handle IUnknown ourselves */
     if (IsEqualIID(riid, &IID_IUnknown))
@@ -517,7 +533,7 @@
                 debugstr_guid(riid), hr);
 
         if (hr == S_OK)
-            hr = IRpcProxyBuffer_Connect(ifproxy->proxy, This->chan);
+            hr = IRpcProxyBuffer_Connect(ifproxy->proxy, ifproxy->chan);
     }
 
     /* get at least one external reference to the object to keep it alive */
@@ -532,7 +548,7 @@
 
         *iif_out = ifproxy;
         TRACE("ifproxy %p created for IPID %s, interface %s with %lu public refs\n",
-              ifproxy, debugstr_guid(&ipid), debugstr_guid(riid), cPublicRefs);
+              ifproxy, debugstr_guid(ipid), debugstr_guid(riid), cPublicRefs);
     }
     else
         ifproxy_destroy(ifproxy);
@@ -579,11 +595,6 @@
     /* apartment is being destroyed so don't keep a pointer around to it */
     This->parent = NULL;
 
-    /* FIXME: will this still be necessary if/when we use a real RPC
-     * channel? */
-    IRpcChannelBuffer_Release(This->chan);
-    This->chan = NULL;
-
     LeaveCriticalSection(&This->cs);
 }
 
@@ -671,7 +682,6 @@
     }
 
     if (This->remunk) IRemUnknown_Release(This->remunk);
-    if (This->chan) IRpcChannelBuffer_Release(This->chan);
 
     DeleteCriticalSection(&This->cs);
 
@@ -792,8 +802,8 @@
       return CO_E_NOTINITIALIZED;
   }
 
-  start_apartment_listener_thread(); /* just to be sure we have one running. */
-  start_apartment_remote_unknown();
+  /* make sure this apartment can be reached from other threads / processes */
+  RPC_StartRemoting(apt);
 
   hres = IUnknown_QueryInterface((LPUNKNOWN)pv, riid, (LPVOID*)&pUnk);
   if (hres != S_OK)
@@ -839,18 +849,9 @@
      * object */
     if (!find_proxy_manager(apt, stdobjref->oxid, stdobjref->oid, &proxy_manager))
     {
-        IRpcChannelBuffer *chanbuf;
-        wine_marshal_id mid;
-
-        mid.oxid = stdobjref->oxid;
-        mid.oid = stdobjref->oid;
-        mid.ipid = stdobjref->ipid;
-
-        hr = PIPE_GetNewPipeBuf(&mid,&chanbuf);
-        if (hr == S_OK)
-            hr = proxy_manager_construct(apt, stdobjref->flags,
-                                         stdobjref->oxid, stdobjref->oid,
-                                         chanbuf, &proxy_manager);
+        hr = proxy_manager_construct(apt, stdobjref->flags,
+                                     stdobjref->oxid, stdobjref->oid,
+                                     &proxy_manager);
     }
     else
         TRACE("proxy manager already created, using\n");
@@ -860,9 +861,14 @@
         struct ifproxy * ifproxy;
         hr = proxy_manager_find_ifproxy(proxy_manager, riid, &ifproxy);
         if (hr == E_NOINTERFACE)
-            hr = proxy_manager_create_ifproxy(proxy_manager, stdobjref->ipid,
-                                              riid, stdobjref->cPublicRefs,
-                                              &ifproxy);
+        {
+            IRpcChannelBuffer *chanbuf;
+            hr = RPC_CreateClientChannel(&stdobjref->oxid, &stdobjref->ipid, &chanbuf);
+            if (hr == S_OK)
+                hr = proxy_manager_create_ifproxy(proxy_manager, &stdobjref->ipid,
+                                                  riid, stdobjref->cPublicRefs,
+                                                  chanbuf, &ifproxy);
+        }
 
         if (hr == S_OK)
         {
@@ -911,7 +917,7 @@
       hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);
       
       /* unref the ifstub. FIXME: only do this on success? */
-      if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid))
+      if (!stub_manager_is_table_marshaled(stubmgr))
           stub_manager_ext_release(stubmgr, 1);
 
       stub_manager_int_release(stubmgr);
@@ -927,7 +933,7 @@
   {
       if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))
       {
-          if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid))
+          if (!stub_manager_notify_unmarshal(stubmgr))
               hres = CO_E_OBJNOTCONNECTED;
 
           stub_manager_int_release(stubmgr);
@@ -982,9 +988,7 @@
         return RPC_E_INVALID_OBJREF;
     }
 
-    /* FIXME: don't release if table-weak and already unmarshaled an object */
-    /* FIXME: this should also depend on stdobjref.cPublicRefs */
-    stub_manager_ext_release(stubmgr, 1);
+    stub_manager_release_marshal_data(stubmgr, stdobjref.cPublicRefs);
 
     stub_manager_int_release(stubmgr);
     COM_ApartmentRelease(apt);
@@ -1418,11 +1422,19 @@
 
     if (hr == S_OK)
     {
-        hr = IUnknown_QueryInterface(object, &iid, ppv);
-        if (hr)
-            ERR("Couldn't query for interface %s, hr = 0x%08lx\n",
-                debugstr_guid(riid), hr);
-        IUnknown_Release(object);
+        if (!IsEqualIID(riid, &iid))
+        {
+            TRACE("requested interface != marshalled interface, additional QI needed\n");
+            hr = IUnknown_QueryInterface(object, &iid, ppv);
+            if (hr)
+                ERR("Couldn't query for interface %s, hr = 0x%08lx\n",
+                    debugstr_guid(riid), hr);
+            IUnknown_Release(object);
+        }
+        else
+        {
+            *ppv = object;
+        }
     }
 
     IMarshal_Release(pMarshal);

Modified: trunk/reactos/lib/ole32/ole2.c
--- trunk/reactos/lib/ole32/ole2.c	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/ole2.c	2005-03-14 23:17:44 UTC (rev 14083)
@@ -1036,7 +1036,7 @@
  * All menu messages from these groups should be routed to the server.
  *
  * RETURNS: TRUE if the popup menu is part of a server owned group
- *          FASE if the popup menu is part of a container owned group
+ *          FALSE if the popup menu is part of a container owned group
  */
 BOOL OLEMenu_SetIsServerMenu( HMENU hmenu, OleMenuDescriptor *pOleMenuDescriptor )
 {

Modified: trunk/reactos/lib/ole32/ole32.spec
--- trunk/reactos/lib/ole32/ole32.spec	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/ole32.spec	2005-03-14 23:17:44 UTC (rev 14083)
@@ -233,6 +233,7 @@
 @ stub SNB_UserUnmarshal
 @ stdcall StgCreateDocfile(wstr long long ptr)
 @ stdcall StgCreateDocfileOnILockBytes(ptr long long ptr)
+@ stdcall StgCreatePropSetStg(ptr long ptr)
 @ stdcall StgCreateStorageEx(wstr long long long ptr ptr ptr ptr)
 @ stub StgGetIFillLockBytesOnFile
 @ stub StgGetIFillLockBytesOnILockBytes

Modified: trunk/reactos/lib/ole32/oleproxy.c
--- trunk/reactos/lib/ole32/oleproxy.c	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/oleproxy.c	2005-03-14 23:17:44 UTC (rev 14083)
@@ -191,10 +191,8 @@
 
 	msg->cbBuffer = ststg.cbSize.u.LowPart;
 
-	if (msg->Buffer)
-	    msg->Buffer = HeapReAlloc(GetProcessHeap(),0,msg->Buffer,ststg.cbSize.u.LowPart);
-	else
-	    msg->Buffer = HeapAlloc(GetProcessHeap(),0,ststg.cbSize.u.LowPart);
+        I_RpcGetBuffer((RPC_MESSAGE *)msg);
+        if (hres) return hres;
 
 	seekto.u.LowPart = 0;seekto.u.HighPart = 0;
 	hres = IStream_Seek(pStm,seekto,SEEK_SET,&newpos);
@@ -547,10 +545,10 @@
 
     /* out */
     pMsg->cbBuffer = cIids * sizeof(REMQIRESULT);
-    if (pMsg->Buffer)
-        pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->cbBuffer);
-	else
-        pMsg->Buffer = HeapAlloc(GetProcessHeap(), 0, pMsg->cbBuffer);
+
+    I_RpcGetBuffer((RPC_MESSAGE *)pMsg);
+    if (hr) return hr;
+
     buf = pMsg->Buffer;
     /* FIXME: pQIResults is a unique pointer so pQIResults can be NULL! */
     memcpy(buf, pQIResults, cIids * sizeof(REMQIRESULT));
@@ -574,13 +572,14 @@
 
     /* out */
     pMsg->cbBuffer = cIids * sizeof(HRESULT);
-    if (pMsg->Buffer)
-        pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->cbBuffer);
-	else
-        pMsg->Buffer = HeapAlloc(GetProcessHeap(), 0, pMsg->cbBuffer);
-    buf = pMsg->Buffer;
-    memcpy(buf, pResults, cIids * sizeof(HRESULT));
 
+    I_RpcGetBuffer((RPC_MESSAGE *)pMsg);
+    if (!hr)
+    {
+        buf = pMsg->Buffer;
+        memcpy(buf, pResults, cIids * sizeof(HRESULT));
+    }
+
     CoTaskMemFree(pResults);
 
     break;

Modified: trunk/reactos/lib/ole32/rpc.c
--- trunk/reactos/lib/ole32/rpc.c	2005-03-14 22:56:02 UTC (rev 14082)
+++ trunk/reactos/lib/ole32/rpc.c	2005-03-14 23:17:44 UTC (rev 14083)
@@ -1,6 +1,7 @@
 /*
  *	(Local) RPC Stuff
  *
+ * Copyright 2001  Ove KÕven, TransGaming Technologies
  * Copyright 2002  Marcus Meissner
  * Copyright 2005  Mike Hearn, Rob Shearman for CodeWeavers
  *
@@ -49,425 +50,530 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
[truncated at 1000 lines; 2487 more skipped]