Sync from Wine-20050830 to Wine-0_9_1:
authorGé van Geldorp <ge@gse.nl>
Sun, 20 Nov 2005 15:01:10 +0000 (15:01 +0000)
committerGé van Geldorp <ge@gse.nl>
Sun, 20 Nov 2005 15:01:10 +0000 (15:01 +0000)
Francois Gouget <fgouget@free.fr>
- Assorted spelling fixes.
- Fix .spec declarations for functinos with 64bit arguments (reported by
  winapi_check).
Mike Hearn <mh@codeweavers.com>
- Robert Shearman <rob@codeweavers.com>
  Change stub manager to track the number of normal marshals instead of
  using the state machine so that multiple marshals of the same object
  and interface work correctly.
Robert Shearman <rob@codeweavers.com>
- Pass WM_QUIT to outer modal loop.
- Fix the return codes during unmarshaling so that it returns failure
  codes instead of S_FALSE returned from IStream_Read.
- Don't fail in CoRegisterClassObject if the class already exists and
  the REGCLS_MULTIPLEUSE flag is specified.
- Fix ref-counting rules to match native DCOM Dlls.
- Add exception handling for stubs.
- Implement OleRegEnumVerbs.
- The [string] attribute is only valid on byte, char and wchar_t types,
  so replace "unsigned short" by "WCHAR".
- Implement OleIsRunning.
- Add a stubbed out implementation of IAdviseSink and advise the
  delegate object to use it.
- Initialize out pointer to NULL before access check in
  IStorage_CreateStorage.
- WriteClassStg should return E_INVALIDARG if pstg is NULL instead of
  asserting.
- ReadClassStg should return E_INVALIDARG if pstg is NULL instead of
  crashing and a NULL pclsid should cause it to return the same
  value.
- Make the interfaces that should be supported by the data cache
  explicit so their is no confusion in this file as to what it should
  be implementing and what this object should implement.
- Delegate some IOleObject methods to the server IOleObject if it is
  running.
- Implement some IRunningObject functions that actually start the server
  and initialize it.
- Remove redunant braces.
- Compact multi-line comments that fit into one line.
- Remove comments that state the obvious.
- Remove extra brackets that are redundant because the -> operator
  binds tighter than &.
- Change "this" to "This" to make code more like other interface
  implementations.
- Remove redundant comparisons with NULL for pointers.
- Re-arrange some functions and vtables so we don't have declarations
  for all of the functions in the file.
- Fix a trace to refer to the object ID rather than the legacy MID.
- Fix the error case of CoMarshalInterThreadInterface to release the
  stream.
- Move all 16-bit functions to an appropriate 16-bit file.
- Implement OLE object notifications, making sure to cope with the case
  of the advise holder not being created because no notifications are
  needed.
- Implement a Stop function and use this to properly implement
  IOleObject_Close, IAdviseSink_OnClose and the destructor.
- We shouldn't pass the application name into CreateProcess because the
  value stored in the registry could include arguments.
- Extend COM_OpenKeyForCLSID to open a subkey and return an HRESULT.
- Fix up the callers and reorganize CoGetClassObject to split out the
  inproc code into another function.
Alex Villacís Lasso <a_villacis@palosanto.com>
- Add NULL check for sinkInterface in DataCache_GetAdvise.
- Add missing ! to fix a reversed condition check in
  OleCreateDefaultHandler, in order to match intent in comment.
Vincent Béron <vberon@mecano.gme.usherb.ca>
- Use the proper calling convention for 2 16-bit functions.
Alexandre Julliard <julliard@winehq.org>
- We are no longer generating .spec.c files.
- Use a more portable scheme for storing the name of a critical
  section.
- Fixed some traces to use the right printf format and avoid typecasts.
- Removed unused debug channels.
- We are no longer generating .dbg.c files.
Richard Cohen <richard@daijobu.co.uk>
- Relax the share mode validation for transacted storage, with a test.
Eric Pouech <eric.pouech@wanadoo.fr>
- Fixes for function prototypes without arguments.
Michael Jung <mjung@iss.tu-darmstadt.de>
- Added tracing to CoCreateInstance.
Markus Amsler <markus.amsler@oribi.org>
- Improve c2man Documented-Total count.

svn path=/trunk/; revision=19370

26 files changed:
reactos/lib/ole32/antimoniker.c
reactos/lib/ole32/bindctx.c
reactos/lib/ole32/clipboard.c
reactos/lib/ole32/compobj.c
reactos/lib/ole32/compobj_private.h
reactos/lib/ole32/datacache.c
reactos/lib/ole32/dcom.idl
reactos/lib/ole32/defaulthandler.c
reactos/lib/ole32/errorinfo.c
reactos/lib/ole32/git.c
reactos/lib/ole32/ifs.c
reactos/lib/ole32/marshal.c
reactos/lib/ole32/memlockbytes16.c
reactos/lib/ole32/moniker.c
reactos/lib/ole32/ole16.c
reactos/lib/ole32/ole2.c
reactos/lib/ole32/ole2.spec
reactos/lib/ole32/ole2_16.c
reactos/lib/ole32/ole2nls.c
reactos/lib/ole32/ole2stubs.c
reactos/lib/ole32/oleproxy.c
reactos/lib/ole32/rpc.c
reactos/lib/ole32/storage.c
reactos/lib/ole32/storage.spec
reactos/lib/ole32/storage32.c
reactos/lib/ole32/stubmanager.c

index c015525..bcd59e1 100644 (file)
@@ -442,7 +442,7 @@ AntiMonikerImpl_GetDisplayName(IMoniker* iface, IBindCtx* pbc,
         return E_POINTER;
 
     if (pmkToLeft!=NULL){
-        FIXME("() pmkToLeft!=NULL not implemented \n");
+        FIXME("() pmkToLeft!=NULL not implemented\n");
         return E_NOTIMPL;
     }
 
index 6b427f4..a58457d 100644 (file)
@@ -170,7 +170,7 @@ BindCtxImpl_RegisterObjectBound(IBindCtx* iface,IUnknown* punk)
     if (lastIndex == This->bindCtxTableSize){ /* the table is full so it must be resized */
 
         if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE)){
-            FIXME("This->bindCtxTableSize: %ld is out of data limite \n",This->bindCtxTableSize);
+            FIXME("This->bindCtxTableSize: %ld is out of data limite\n", This->bindCtxTableSize);
             return E_FAIL;
         }
 
@@ -351,7 +351,7 @@ BindCtxImpl_RegisterObjectParam(IBindCtx* iface,LPOLESTR pszkey, IUnknown* punk)
         This->bindCtxTableSize+=BLOCK_TAB_SIZE; /* new table size */
         if (This->bindCtxTableSize > (MAX_TAB_SIZE-BLOCK_TAB_SIZE))
         {
-            FIXME("This->bindCtxTableSize: %ld is out of data limite \n",This->bindCtxTableSize);
+            FIXME("This->bindCtxTableSize: %ld is out of data limite\n", This->bindCtxTableSize);
             return E_FAIL;
         }
         This->bindCtxTable = HeapReAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,This->bindCtxTable,
@@ -525,15 +525,6 @@ static HRESULT BindCtxImpl_Construct(BindCtxImpl* This)
     return S_OK;
 }
 
-/******************************************************************************
- *        CreateBindCtx16
- ******************************************************************************/
-HRESULT WINAPI CreateBindCtx16(DWORD reserved, LPBC * ppbc)
-{
-    FIXME("(%ld,%p),stub!\n",reserved,ppbc);
-    return E_NOTIMPL;
-}
-
 /******************************************************************************
  *        CreateBindCtx (OLE32.@)
  ******************************************************************************/
index 75b706d..61c9441 100644 (file)
@@ -303,7 +303,7 @@ typedef struct tagClipboardWindowInfo
  *  Places a pointer to the specified data object onto the clipboard,
  *  making the data object accessible to the OleGetClipboard function.
  *
- * RETURNS:
+ * RETURNS
  *
  *    S_OK                  IDataObject pointer placed on the clipboard
  *    CLIPBRD_E_CANT_OPEN   OpenClipboard failed
@@ -478,16 +478,6 @@ HRESULT WINAPI OleGetClipboard(IDataObject** ppDataObj)
   return hr;
 }
 
-/***********************************************************************
- *           OleFlushClipboard   [OLE2.76]
- */
-
-HRESULT WINAPI OleFlushClipboard16(void)
-{
-  return OleFlushClipboard();
-}
-
-
 /******************************************************************************
  *              OleFlushClipboard        [OLE32.@]
  *  Renders the data from the source IDataObject into the windows clipboard
index 8c7a8bd..b2cf72b 100644 (file)
 
 #include "windef.h"
 #include "winbase.h"
+#include "winerror.h"
+#include "winreg.h"
 #include "winuser.h"
 #include "objbase.h"
 #include "ole2.h"
 #include "ole2ver.h"
-#include "rpc.h"
-#include "winerror.h"
-#include "winreg.h"
-#include "wownt32.h"
-#include "wine/unicode.h"
-#include "objbase.h"
+
 #include "compobj_private.h"
 
+#include "wine/unicode.h"
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 
-typedef LPCSTR LPCOLESTR16;
-
 HINSTANCE OLE32_hInstance = 0; /* FIXME: make static ... */
 
 #define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
@@ -97,7 +93,7 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
 {
     0, 0, &csApartment,
     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
-      0, 0, { 0, (DWORD)(__FILE__ ": csApartment") }
+      0, 0, { (DWORD_PTR)(__FILE__ ": csApartment") }
 };
 static CRITICAL_SECTION csApartment = { &critsect_debug, -1, 0, 0, 0, 0 };
 
@@ -134,7 +130,7 @@ static CRITICAL_SECTION_DEBUG class_cs_debug =
 {
     0, 0, &csRegisteredClassList,
     { &class_cs_debug.ProcessLocksList, &class_cs_debug.ProcessLocksList },
-      0, 0, { 0, (DWORD)(__FILE__ ": csRegisteredClassList") }
+      0, 0, { (DWORD_PTR)(__FILE__ ": csRegisteredClassList") }
 };
 static CRITICAL_SECTION csRegisteredClassList = { &class_cs_debug, -1, 0, 0, 0, 0 };
 
@@ -161,7 +157,7 @@ static CRITICAL_SECTION_DEBUG dll_cs_debug =
 {
     0, 0, &csOpenDllList,
     { &dll_cs_debug.ProcessLocksList, &dll_cs_debug.ProcessLocksList },
-      0, 0, { 0, (DWORD)(__FILE__ ": csOpenDllList") }
+      0, 0, { (DWORD_PTR)(__FILE__ ": csOpenDllList") }
 };
 static CRITICAL_SECTION csOpenDllList = { &dll_cs_debug, -1, 0, 0, 0, 0 };
 
@@ -419,7 +415,8 @@ static LRESULT CALLBACK apartment_wndproc(HWND hWnd, UINT msg, WPARAM wParam, LP
     switch (msg)
     {
     case DM_EXECUTERPC:
-        return RPC_ExecuteCall((struct dispatch_params *)lParam);
+        RPC_ExecuteCall((struct dispatch_params *)lParam);
+        return 0;
     default:
         return DefWindowProcW(hWnd, msg, wParam, lParam);
     }
@@ -981,14 +978,36 @@ INT WINAPI StringFromGUID2(REFGUID id, LPOLESTR str, INT cmax)
   return MultiByteToWideChar( CP_ACP, 0, xguid, -1, str, cmax );
 }
 
-/* open HKCR\\CLSID\\{string form of clsid} key */
-DWORD COM_OpenKeyForCLSID(REFCLSID clsid, REGSAM access, HKEY *key)
+/* open HKCR\\CLSID\\{string form of clsid}\\{keyname} key */
+HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *subkey)
 {
     static const WCHAR wszCLSIDSlash[] = {'C','L','S','I','D','\\',0};
     WCHAR path[CHARS_IN_GUID + ARRAYSIZE(wszCLSIDSlash) - 1];
+    LONG res;
+    HKEY key;
+
     strcpyW(path, wszCLSIDSlash);
     StringFromGUID2(clsid, path + strlenW(wszCLSIDSlash), CHARS_IN_GUID);
-    return RegOpenKeyExW(HKEY_CLASSES_ROOT, path, 0, access, key);
+    res = RegOpenKeyExW(HKEY_CLASSES_ROOT, path, 0, keyname ? KEY_READ : access, &key);
+    if (res == ERROR_FILE_NOT_FOUND)
+        return REGDB_E_CLASSNOTREG;
+    else if (res != ERROR_SUCCESS)
+        return REGDB_E_READREGDB;
+
+    if (!keyname)
+    {
+        *subkey = key;
+        return S_OK;
+    }
+
+    res = RegOpenKeyExW(key, keyname, 0, access, subkey);
+    RegCloseKey(key);
+    if (res == ERROR_FILE_NOT_FOUND)
+        return REGDB_E_KEYMISSING;
+    else if (res != ERROR_SUCCESS)
+        return REGDB_E_READREGDB;
+
+    return S_OK;
 }
 
 /******************************************************************************
@@ -1007,25 +1026,15 @@ DWORD COM_OpenKeyForCLSID(REFCLSID clsid, REGSAM access, HKEY *key)
  */
 HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID)
 {
-  static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
-  HKEY     hkey = NULL;
-  HKEY     hkey_clsid;
-  HRESULT  ret = S_OK;
-
-  if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsid, KEY_READ, &hkey_clsid))
-    ret = REGDB_E_CLASSNOTREG;
-
-  if (ret == S_OK)
-  {
-    if (RegOpenKeyExW(hkey_clsid, wszProgID, 0, KEY_READ, &hkey))
-      ret = REGDB_E_CLASSNOTREG;
-    RegCloseKey(hkey_clsid);
-  }
-
-  if (ret == S_OK)
-  {
+    static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
+    HKEY     hkey;
+    HRESULT  ret;
     LONG progidlen = 0;
 
+    ret = COM_OpenKeyForCLSID(clsid, wszProgID, KEY_READ, &hkey);
+    if (FAILED(ret))
+        return ret;
+
     if (RegQueryValueW(hkey, NULL, NULL, &progidlen))
       ret = REGDB_E_CLASSNOTREG;
 
@@ -1040,46 +1049,9 @@ HRESULT WINAPI ProgIDFromCLSID(REFCLSID clsid, LPOLESTR *lplpszProgID)
       else
         ret = E_OUTOFMEMORY;
     }
-  }
-
-  RegCloseKey(hkey);
-  return ret;
-}
 
-/******************************************************************************
- *             CLSIDFromProgID [COMPOBJ.61]
- *
- * Converts a program ID into the respective GUID.
- *
- * PARAMS
- *  progid       [I] program id as found in registry
- *  riid         [O] associated CLSID
- *
- * RETURNS
- *     Success: S_OK
- *  Failure: CO_E_CLASSSTRING - the given ProgID cannot be found.
- */
-HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid)
-{
-       char    *buf,buf2[80];
-       LONG    buf2len;
-       HRESULT err;
-       HKEY    xhkey;
-
-       buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
-       sprintf(buf,"%s\\CLSID",progid);
-       if ((err=RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey))) {
-               HeapFree(GetProcessHeap(),0,buf);
-                return CO_E_CLASSSTRING;
-       }
-       HeapFree(GetProcessHeap(),0,buf);
-       buf2len = sizeof(buf2);
-       if ((err=RegQueryValueA(xhkey,NULL,buf2,&buf2len))) {
-               RegCloseKey(xhkey);
-                return CO_E_CLASSSTRING;
-       }
-       RegCloseKey(xhkey);
-       return __CLSIDFromStringA(buf2,riid);
+    RegCloseKey(hkey);
+    return ret;
 }
 
 /******************************************************************************
@@ -1122,7 +1094,6 @@ HRESULT WINAPI CLSIDFromProgID(LPCOLESTR progid, LPCLSID riid)
 }
 
 
-
 /*****************************************************************************
  *             CoGetPSClsid [OLE32.@]
  *
@@ -1388,7 +1359,14 @@ HRESULT WINAPI CoRegisterClassObject(
    */
   hr = COM_GetRegisteredClassObject(rclsid, dwClsContext, &foundObject);
   if (hr == S_OK) {
+    if (flags & REGCLS_MULTIPLEUSE) {
+      if (dwClsContext & CLSCTX_LOCAL_SERVER)
+        hr = CoLockObjectExternal(foundObject, TRUE, FALSE);
+      IUnknown_Release(foundObject);
+      return hr;
+    }
     IUnknown_Release(foundObject);
+    ERR("object already registered for class %s\n", debugstr_guid(rclsid));
     return CO_E_OBJISREG;
   }
 
@@ -1559,6 +1537,40 @@ HRESULT COM_RegReadPath(HKEY hkeyroot, const WCHAR *keyname, const WCHAR *valuen
        return hres;
 }
 
+static HRESULT get_inproc_class_object(HKEY hkeydll, REFCLSID rclsid, REFIID riid, void **ppv)
+{
+    HINSTANCE hLibrary;
+    typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
+    DllGetClassObjectFunc DllGetClassObject;
+    WCHAR dllpath[MAX_PATH+1];
+
+    if (COM_RegReadPath(hkeydll, NULL, NULL, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
+    {
+        /* failure: CLSID is not found in registry */
+        WARN("class %s not registered inproc\n", debugstr_guid(rclsid));
+        return REGDB_E_CLASSNOTREG;
+    }
+
+    if ((hLibrary = LoadLibraryExW(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0)
+    {
+        /* failure: DLL could not be loaded */
+        ERR("couldn't load in-process dll %s\n", debugstr_w(dllpath));
+        return E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
+    }
+
+    if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject")))
+    {
+        /* failure: the dll did not export DllGetClassObject */
+        ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(dllpath));
+        FreeLibrary( hLibrary );
+        return CO_E_DLLNOTFOUND;
+    }
+
+    /* OK: get the ClassObject */
+    COMPOBJ_DLLList_Add( hLibrary );
+    return DllGetClassObject(rclsid, riid, ppv);
+}
+
 /***********************************************************************
  *           CoGetClassObject [OLE32.@]
  *
@@ -1600,50 +1612,58 @@ HRESULT WINAPI CoGetClassObject(
       return hres;
     }
 
-    /* first try: in-process */
-    if ((CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER) & dwClsContext)
+    /* First try in-process server */
+    if (CLSCTX_INPROC_SERVER & dwClsContext)
     {
         static const WCHAR wszInprocServer32[] = {'I','n','p','r','o','c','S','e','r','v','e','r','3','2',0};
-        HINSTANCE hLibrary;
-        typedef HRESULT (CALLBACK *DllGetClassObjectFunc)(REFCLSID clsid, REFIID iid, LPVOID *ppv);
-        DllGetClassObjectFunc DllGetClassObject;
-        WCHAR dllpath[MAX_PATH+1];
         HKEY hkey;
 
-        if (ERROR_SUCCESS != COM_OpenKeyForCLSID(rclsid, KEY_READ, &hkey))
+        hres = COM_OpenKeyForCLSID(rclsid, wszInprocServer32, KEY_READ, &hkey);
+        if (FAILED(hres))
         {
-            ERR("class %s not registered\n", debugstr_guid(rclsid));
-            hres = REGDB_E_CLASSNOTREG;
+            if (hres == REGDB_E_CLASSNOTREG)
+                ERR("class %s not registered\n", debugstr_guid(rclsid));
+            else
+                WARN("class %s not registered as in-proc server\n", debugstr_guid(rclsid));
         }
 
-        if (COM_RegReadPath(hkey, wszInprocServer32, NULL, dllpath, ARRAYSIZE(dllpath)) != ERROR_SUCCESS)
+        if (SUCCEEDED(hres))
         {
-            /* failure: CLSID is not found in registry */
-            WARN("class %s not registered inproc\n", debugstr_guid(rclsid));
-            hres = REGDB_E_CLASSNOTREG;
+            hres = get_inproc_class_object(hkey, rclsid, iid, ppv);
+            RegCloseKey(hkey);
         }
-        else
+
+        /* return if we got a class, otherwise fall through to one of the
+         * other types */
+        if (SUCCEEDED(hres))
+            return hres;
+    }
+
+    /* Next try in-process handler */
+    if (CLSCTX_INPROC_HANDLER & dwClsContext)
+    {
+        static const WCHAR wszInprocHandler32[] = {'I','n','p','r','o','c','H','a','n','d','l','e','r','3','2',0};
+        HKEY hkey;
+
+        hres = COM_OpenKeyForCLSID(rclsid, wszInprocHandler32, KEY_READ, &hkey);
+        if (FAILED(hres))
         {
-            if ((hLibrary = LoadLibraryExW(dllpath, 0, LOAD_WITH_ALTERED_SEARCH_PATH)) == 0)
-            {
-                /* failure: DLL could not be loaded */
-                ERR("couldn't load InprocServer32 dll %s\n", debugstr_w(dllpath));
-                hres = E_ACCESSDENIED; /* FIXME: or should this be CO_E_DLLNOTFOUND? */
-            }
-            else if (!(DllGetClassObject = (DllGetClassObjectFunc)GetProcAddress(hLibrary, "DllGetClassObject")))
-            {
-                /* failure: the dll did not export DllGetClassObject */
-                ERR("couldn't find function DllGetClassObject in %s\n", debugstr_w(dllpath));
-                FreeLibrary( hLibrary );
-                hres = CO_E_DLLNOTFOUND;
-            }
+            if (hres == REGDB_E_CLASSNOTREG)
+                ERR("class %s not registered\n", debugstr_guid(rclsid));
             else
-            {
-                /* OK: get the ClassObject */
-                COMPOBJ_DLLList_Add( hLibrary );
-                return DllGetClassObject(rclsid, iid, ppv);
-            }
+                WARN("class %s not registered in-proc handler\n", debugstr_guid(rclsid));
         }
+
+        if (SUCCEEDED(hres))
+        {
+            hres = get_inproc_class_object(hkey, rclsid, iid, ppv);
+            RegCloseKey(hkey);
+        }
+
+        /* return if we got a class, otherwise fall through to one of the
+         * other types */
+        if (SUCCEEDED(hres))
+            return hres;
     }
 
     /* Next try out of process */
@@ -1659,25 +1679,12 @@ HRESULT WINAPI CoGetClassObject(
         hres = E_NOINTERFACE;
     }
 
+    if (FAILED(hres))
+        ERR("no class object %s could be created for for context 0x%lx\n",
+            debugstr_guid(rclsid), dwClsContext);
     return hres;
 }
 
-/***********************************************************************
- *           CoGetClassObject [COMPOBJ.7]
- *
- */
-HRESULT WINAPI CoGetClassObject16(
-    REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo,
-    REFIID iid, LPVOID *ppv)
-{
-    FIXME(", stub!\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
-
-    if (pServerInfo) {
-       FIXME("\tpServerInfo: name=%s\n",debugstr_w(pServerInfo->pwszName));
-       FIXME("\t\tpAuthInfo=%p\n",pServerInfo->pAuthInfo);
-    }
-    return E_NOTIMPL;
-}
 /***********************************************************************
  *        CoResumeClassObjects (OLE32.@)
  *
@@ -1800,6 +1807,9 @@ HRESULT WINAPI CoCreateInstance(
   HRESULT hres;
   LPCLASSFACTORY lpclf = 0;
 
+  TRACE("(rclsid=%s, pUnkOuter=%p, dwClsContext=%08lx, riid=%s, ppv=%p)\n", debugstr_guid(rclsid),
+        pUnkOuter, dwClsContext, debugstr_guid(iid), ppv);
+
   if (!COM_CurrentApt()) return CO_E_NOTINITIALIZED;
 
   /*
@@ -1854,23 +1864,6 @@ HRESULT WINAPI CoCreateInstance(
        return hres;
 }
 
-/***********************************************************************
- *           CoCreateInstance [COMPOBJ.13]
- */
-HRESULT WINAPI CoCreateInstance16(
-       REFCLSID rclsid,
-       LPUNKNOWN pUnkOuter,
-       DWORD dwClsContext,
-       REFIID iid,
-       LPVOID *ppv)
-{
-  FIXME("(%s, %p, %lx, %s, %p), stub!\n", 
-       debugstr_guid(rclsid), pUnkOuter, dwClsContext, debugstr_guid(iid),
-       ppv
-  );
-  return E_NOTIMPL;
-}
-
 /***********************************************************************
  *           CoCreateInstanceEx [OLE32.@]
  */
@@ -2207,16 +2200,12 @@ HRESULT WINAPI OleGetAutoConvert(REFCLSID clsidOld, LPCLSID pClsidNew)
     LONG len;
     HRESULT res = S_OK;
 
-    if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsidOld, KEY_READ, &hkey))
-    {
-        res = REGDB_E_CLASSNOTREG;
+    res = COM_OpenKeyForCLSID(clsidOld, wszAutoConvertTo, KEY_READ, &hkey);
+    if (FAILED(res))
         goto done;
-    }
 
     len = sizeof(buf);
-    /* we can just query for the default value of AutoConvertTo key like that,
-       without opening the AutoConvertTo key and querying for NULL (default) */
-    if (RegQueryValueW(hkey, wszAutoConvertTo, buf, &len))
+    if (RegQueryValueW(hkey, NULL, buf, &len))
     {
         res = REGDB_E_KEYMISSING;
         goto done;
@@ -2254,11 +2243,9 @@ HRESULT WINAPI CoTreatAsClass(REFCLSID clsidOld, REFCLSID clsidNew)
     LONG auto_treat_as_size = sizeof(auto_treat_as);
     CLSID id;
 
-    if (ERROR_SUCCESS != COM_OpenKeyForCLSID(clsidOld, KEY_READ | KEY_WRITE, &hkey))
-    {
-        res = REGDB_E_CLASSNOTREG;
-       goto done;
-    }
+    res = COM_OpenKeyForCLSID(clsidOld, NULL, KEY_READ | KEY_WRITE, &hkey);
+    if (FAILED(res))
+        goto done;
     if (!memcmp( clsidOld, clsidNew, sizeof(*clsidOld) ))
     {
        if (!RegQueryValueW(hkey, wszAutoTreatAs, auto_treat_as, &auto_treat_as_size) &&
@@ -2315,12 +2302,10 @@ HRESULT WINAPI CoGetTreatAsClass(REFCLSID clsidOld, LPCLSID clsidNew)
     FIXME("(%s,%p)\n", debugstr_guid(clsidOld), clsidNew);
     memcpy(clsidNew,clsidOld,sizeof(CLSID)); /* copy over old value */
 
-    if (COM_OpenKeyForCLSID(clsidOld, KEY_READ, &hkey))
-    {
-        res = REGDB_E_CLASSNOTREG;
-       goto done;
-    }
-    if (RegQueryValueW(hkey, wszTreatAs, szClsidNew, &len))
+    res = COM_OpenKeyForCLSID(clsidOld, wszTreatAs, KEY_READ, &hkey);
+    if (FAILED(res))
+        goto done;
+    if (RegQueryValueW(hkey, NULL, szClsidNew, &len))
     {
         res = S_FALSE;
        goto done;
@@ -2688,6 +2673,12 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout,
                 TRACE("received message whilst waiting for RPC: 0x%04x\n", msg.message);
                 TranslateMessage(&msg);
                 DispatchMessageW(&msg);
+                if (msg.message == WM_QUIT)
+                {
+                    TRACE("resending WM_QUIT to outer message loop\n");
+                    PostQuitMessage(msg.wParam);
+                    goto done;
+                }
             }
         }
         else if ((res >= WAIT_OBJECT_0) && (res < WAIT_OBJECT_0 + cHandles))
@@ -2708,6 +2699,7 @@ HRESULT WINAPI CoWaitForMultipleHandles(DWORD dwFlags, DWORD dwTimeout,
             break;
         }
     }
+done:
     TRACE("-- 0x%08lx\n", hr);
     return hr;
 }
index 04231e3..8364c6c 100644 (file)
@@ -71,6 +71,7 @@ struct ifstub
     IID               iid;        /* RO */
     IPID              ipid;       /* RO */
     IUnknown         *iface;      /* RO */
+    MSHLFLAGS         flags;      /* so we can enforce process-local marshalling rules (RO) */
 };
 
 
@@ -87,7 +88,14 @@ struct stub_manager
     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) */
+
+    /* We need to keep a count of the outstanding marshals, so we can enforce the
+     * marshalling rules (ie, you can only unmarshal normal marshals once). Note
+     * that these counts do NOT include unmarshalled interfaces, once a stream is
+     * unmarshalled and a proxy set up, this count is decremented.
+     */
+
+    ULONG             norm_refs;  /* refcount of normal marshals (CS lock) */
 };
 
 /* imported interface proxy */
@@ -163,22 +171,23 @@ extern void* StdGlobalInterfaceTableInstance;
 extern HRESULT WINE_StringFromCLSID(const CLSID *id,LPSTR idstr);
 HRESULT WINAPI __CLSIDFromStringA(LPCSTR idstr, CLSID *id);
 
-DWORD COM_OpenKeyForCLSID(REFCLSID clsid, REGSAM access, HKEY *key);
+HRESULT COM_OpenKeyForCLSID(REFCLSID clsid, LPCWSTR keyname, REGSAM access, HKEY *key);
 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, MSHLFLAGS mshlflags);
+struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object);
 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);
+struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, MSHLFLAGS flags);
+struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags);
 struct stub_manager *get_stub_manager(APARTMENT *apt, OID oid);
 struct stub_manager *get_stub_manager_from_object(APARTMENT *apt, void *object);
-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);
+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);
+void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid);
 HRESULT ipid_to_stub_manager(const IPID *ipid, APARTMENT **stub_apt, struct stub_manager **stubmgr_ret);
 IRpcStubBuffer *ipid_to_apt_and_stubbuffer(const IPID *ipid, APARTMENT **stub_apt);
 HRESULT start_apartment_remote_unknown(void);
@@ -191,7 +200,7 @@ struct dispatch_params;
 
 void    RPC_StartRemoting(struct apartment *apt);
 HRESULT RPC_CreateClientChannel(const OXID *oxid, const IPID *ipid, IRpcChannelBuffer **pipebuf);
-HRESULT RPC_ExecuteCall(struct dispatch_params *params);
+void    RPC_ExecuteCall(struct dispatch_params *params);
 HRESULT RPC_RegisterInterface(REFIID riid);
 void    RPC_UnregisterInterface(REFIID riid);
 void    RPC_StartLocalServer(REFCLSID clsid, IStream *stream);
@@ -247,13 +256,8 @@ static inline APARTMENT* COM_CurrentApt(void)
 #define ICOM_THIS_MULTI(impl,field,iface) impl* const This=(impl*)((char*)(iface) - offsetof(impl,field))
 
 /* helpers for debugging */
-#ifdef __i386__
-# define DEBUG_SET_CRITSEC_NAME(cs, name) (cs)->DebugInfo->Spare[1] = (DWORD)(__FILE__ ": " name)
-# define DEBUG_CLEAR_CRITSEC_NAME(cs) (cs)->DebugInfo->Spare[1] = 0
-#else
-# define DEBUG_SET_CRITSEC_NAME(cs, name)
-# define DEBUG_CLEAR_CRITSEC_NAME(cs)
-#endif
+# define DEBUG_SET_CRITSEC_NAME(cs, name) (cs)->DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": " name)
+# define DEBUG_CLEAR_CRITSEC_NAME(cs) (cs)->DebugInfo->Spare[0] = 0
 
 extern HINSTANCE OLE32_hInstance; /* FIXME: make static */
 
index 6079bb5..a3beaca 100644 (file)
@@ -1390,9 +1390,11 @@ static HRESULT WINAPI DataCache_GetAdvise(
 
   if (ppAdvSink!=NULL)
   {
-    IAdviseSink_QueryInterface(this->sinkInterface,
+    if (this->sinkInterface != NULL)
+        IAdviseSink_QueryInterface(this->sinkInterface,
                               &IID_IAdviseSink,
                               (void**)ppAdvSink);
+    else *ppAdvSink = NULL;
   }
 
   return S_OK;
index 37c6b47..7d95f37 100644 (file)
-/*\r
- * Copyright 2003 Ove Kåven, TransGaming Technologies\r
- *\r
- * This library is free software; you can redistribute it and/or\r
- * modify it under the terms of the GNU Lesser General Public\r
- * License as published by the Free Software Foundation; either\r
- * version 2.1 of the License, or (at your option) any later version.\r
- *\r
- * This library is distributed in the hope that it will be useful,\r
- * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\r
- * Lesser General Public License for more details.\r
- *\r
- * You should have received a copy of the GNU Lesser General Public\r
- * License along with this library; if not, write to the Free Software\r
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
- */\r
-\r
-/* see http://www.microsoft.com/msj/0398/dcom.htm */\r
-/* and the official DCOM specification\r
- * (there's a copy at http://www.grimes.demon.co.uk/DCOM/DCOMSpec.htm) */\r
-\r
-import "unknwn.idl";\r
-\r
-[\r
-  uuid(99fcfe60-5260-101b-bbcb-00aa0021347a),\r
-  pointer_default(unique)\r
-]\r
-interface ObjectRpcBaseTypes\r
-{\r
-  typedef unsigned hyper ID;\r
-  typedef ID MID;\r
-  typedef ID OXID;\r
-  typedef ID OID;\r
-  typedef ID SETID;\r
-  typedef GUID IPID;\r
-  typedef GUID CID;\r
-  typedef REFGUID REFIPID;\r
-\r
-  const unsigned short COM_MINOR_VERSION_1 = 1;\r
-  const unsigned short COM_MINOR_VERSION_2 = 2;\r
-\r
-  const unsigned short COM_MAJOR_VERSION = 5;\r
-  const unsigned short COM_MINOR_VERSION = 3;\r
-\r
-  typedef struct tagCOMVERSION {\r
-    unsigned short MajorVersion;\r
-    unsigned short MinorVersion;\r
-  } COMVERSION;\r
-\r
-  const unsigned long ORPCF_NULL = 0;\r
-  const unsigned long ORPCF_LOCAL = 1;\r
-  const unsigned long ORPCF_RESERVED1 = 2;\r
-  const unsigned long ORPCF_RESERVED2 = 4;\r
-  const unsigned long ORPCF_RESERVED3 = 8;\r
-  const unsigned long ORPCF_RESERVED4 = 16;\r
-\r
-  typedef struct tagORPC_EXTENT {\r
-    GUID id;\r
-    unsigned long size;\r
-    [size_is((size+7)&~7)] byte data[];\r
-  } ORPC_EXTENT;\r
-\r
-  typedef struct tagORPC_EXTENT_ARRAY {\r
-    unsigned long size;\r
-    unsigned long reserved;\r
-    [size_is((size+1)&~1,), unique] ORPC_EXTENT **extent;\r
-  } ORPC_EXTENT_ARRAY;\r
-\r
-  typedef struct tagORPCTHIS {\r
-    COMVERSION version;\r
-    unsigned long flags;\r
-    unsigned long reserved1;\r
-    CID cid;\r
-    [unique] ORPC_EXTENT_ARRAY *extensions;\r
-  } ORPCTHIS;\r
-\r
-  typedef struct tagORPCTHAT {\r
-    unsigned long flags;\r
-    [unique] ORPC_EXTENT_ARRAY *extensions;\r
-  } ORPCTHAT;\r
-\r
-  const unsigned short NCADG_IP_UDP = 0x08;\r
-  const unsigned short NCACN_IP_TCP = 0x07;\r
-  const unsigned short NCADG_IPX = 0x0E;\r
-  const unsigned short NCACN_SPX = 0x0C;\r
-  const unsigned short NCACN_NB_NB = 0x12;\r
-  const unsigned short NCACN_NB_IPX = 0x0D;\r
-  const unsigned short NCACN_DNET_NSP = 0x04;\r
-  const unsigned short NCACN_HTTP = 0x1F;\r
-\r
-  typedef struct tagSTRINGBINDING {\r
-    unsigned short wTowerId;\r
-    [string] unsigned short aNetworkAddr[];\r
-  } STRINGBINDING;\r
-\r
-  const unsigned short COM_C_AUTHZ_NONE = 0xffff;\r
-\r
-  typedef struct tagSECURITYBINDING {\r
-    unsigned short wAuthnSvc;\r
-    unsigned short wAuthzSvc;\r
-    [string] unsigned short aPrincName[];\r
-  } SECURITYBINDING;\r
-\r
-  typedef struct tagDUALSTRINGARRAY {\r
-    unsigned short wNumEntries;\r
-    unsigned short wSecurityOffset;\r
-    [size_is(wNumEntries)] unsigned short aStringArray[];\r
-  } DUALSTRINGARRAY;\r
-\r
-  const unsigned long OBJREF_SIGNATURE = 0x574f454d; /* "MEOW" */\r
-  const unsigned long OBJREF_STANDARD = 0x1;\r
-  const unsigned long OBJREF_HANDLER = 0x2;\r
-  const unsigned long OBJREF_CUSTOM = 0x4;\r
-  const unsigned long SORF_OXRES1 = 0x1;\r
-  const unsigned long SORF_OXRES2 = 0x20;\r
-  const unsigned long SORF_OXRES3 = 0x40;\r
-  const unsigned long SORF_OXRES4 = 0x80;\r
-  const unsigned long SORF_OXRES5 = 0x100;\r
-  const unsigned long SORF_OXRES6 = 0x200;\r
-  const unsigned long SORF_OXRES7 = 0x400;\r
-  const unsigned long SORF_OXRES8 = 0x800;\r
-  const unsigned long SORF_NULL = 0x0;\r
-  const unsigned long SORF_NOPING = 0x1000;\r
-\r
-  typedef struct tagSTDOBJREF {\r
-    unsigned long flags;\r
-    unsigned long cPublicRefs;\r
-    OXID oxid;\r
-    OID oid;\r
-    IPID ipid;\r
-  } STDOBJREF;\r
-\r
-  typedef struct tagOBJREF {\r
-    unsigned long signature;\r
-    unsigned long flags;\r
-    GUID iid;\r
-    [switch_is(flags)] union {\r
-    [case(OBJREF_STANDARD)] struct OR_STANDARD {\r
-        STDOBJREF std;\r
-        DUALSTRINGARRAY saResAddr;\r
-      } u_standard;\r
-    [case(OBJREF_HANDLER)] struct OR_HANDLER {\r
-        STDOBJREF std;\r
-        CLSID clsid;\r
-        DUALSTRINGARRAY saResAddr;\r
-      } u_handler;\r
-    [case(OBJREF_CUSTOM)] struct OR_CUSTOM {\r
-        CLSID clsid;\r
-        unsigned long cbExtension;\r
-        unsigned long size;\r
-        [size_is(size), ref] byte *pData;\r
-      } u_custom;\r
-    } u_objref;\r
-  } OBJREF;\r
-\r
-  typedef struct tagMInterfacePointer {\r
-    ULONG ulCntData;\r
-    [size_is(ulCntData)] BYTE abData[];\r
-  } MInterfacePointer;\r
-\r
-  typedef [unique] MInterfacePointer *PMInterfacePointer;\r
-\r
-} /* interface ObjectRpcBaseTypes */\r
-\r
-[\r
-  object,\r
-  uuid(00000131-0000-0000-C000-000000000046)\r
-]\r
-interface IRemUnknown : IUnknown\r
-{\r
-  typedef [unique] IRemUnknown *LPREMUNKNOWN;\r
-\r
-  typedef struct tagREMQIRESULT {\r
-    HRESULT hResult;\r
-    STDOBJREF std;\r
-  } REMQIRESULT;\r
-\r
-  typedef struct tagREMINTERFACEREF {\r
-    IPID ipid;\r
-    unsigned long cPublicRefs;\r
-    unsigned long cPrivateRefs;\r
-  } REMINTERFACEREF; \r
-\r
-  HRESULT RemQueryInterface(\r
-    [in] REFIPID ripid,\r
-    [in] unsigned long cRefs,\r
-    [in] unsigned short cIids,\r
-    [in, size_is(cIids)] IID *iids,\r
-    [out, size_is(,cIids)] REMQIRESULT **ppQIResults);\r
-\r
-  HRESULT RemAddRef(\r
-    [in] unsigned short cInterfaceRefs,\r
-    [in, size_is(cInterfaceRefs)] REMINTERFACEREF* InterfaceRefs,\r
-    [out, size_is(cInterfaceRefs)] HRESULT *pResults);\r
-\r
-  HRESULT RemRelease(\r
-    [in] unsigned short cInterfaceRefs,\r
-    [in, size_is(cInterfaceRefs)] REMINTERFACEREF* InterfaceRefs);\r
-}\r
-\r
-[\r
-  object,\r
-  uuid(00000142-0000-0000-C000-000000000046)\r
-]\r
-interface IRemUnknown2 : IRemUnknown\r
-{\r
-  typedef [unique] IRemUnknown2 *LPREMUNKNOWN2;\r
-\r
-  HRESULT RemQueryInterface2(\r
-    [in] REFIPID ripid,\r
-    [in] unsigned short cIids,\r
-    [in, size_is(cIids)] IID *iids,\r
-    [out, size_is(cIids)] HRESULT *phr,\r
-    [out, size_is(cIids)] MInterfacePointer **ppMIF);\r
-}\r
-\r
-cpp_quote("#if 0")\r
-[\r
-  uuid(99fcfec4-5260-101b-bbcb-00aa0021347a),\r
-  pointer_default(unique)\r
-]\r
-interface IOXIDResolver\r
-{\r
-  [idempotent] error_status_t ResolveOxid(\r
-    [in] handle_t hRpc,\r
-    [in] OXID *pOxid,\r
-    [in] unsigned short cRequestedProtseqs,\r
-    [in, ref, size_is(cRequestedProtseqs)] unsigned short arRequestedProtseqs[],\r
-    [out, ref] DUALSTRINGARRAY **ppdsaOxidBindings,\r
-    [out, ref] IPID *pipidRemUnknown,\r
-    [out, ref] DWORD *pAuthnHint);\r
-\r
-  [idempotent] error_status_t SimplePing(\r
-    [in] handle_t hRpc,\r
-    [in] SETID *pSetId);\r
-\r
-  [idempotent] error_status_t ComplexPing(\r
-    [in] handle_t hRpc,\r
-    [in, out] SETID *pSetId,\r
-    [in] unsigned short SequenceNum,\r
-    [in] unsigned short cAddToSet,\r
-    [in] unsigned short cDelFromSet,\r
-    [in, unique, size_is(cAddToSet)] OID AddToSet[],\r
-    [in, unique, size_is(cDelFromSet)] OID DelFromSet[],\r
-    [out] unsigned short *pPingBackoffFactor);\r
-\r
-  [idempotent] error_status_t ServerAlive(\r
-    [in] handle_t hRpc);\r
-\r
-  [idempotent] error_status_t ResolveOxid2(\r
-    [in] handle_t hRpc,\r
-    [in] OXID *pOxid,\r
-    [in] unsigned short cRequestedProtseqs,\r
-    [in, ref, size_is(cRequestedProtseqs)] unsigned short arRequestedProtseqs[],\r
-    [out, ref] DUALSTRINGARRAY **ppdsaOxidBindings,\r
-    [out, ref] IPID *pipidRemUnknown,\r
-    [out, ref] DWORD *pAuthnHint,\r
-    [out, ref] COMVERSION *pComVersion); \r
-}\r
-\r
-[\r
-  uuid(4d9f4ab8-7d1c-11cf-861e-0020af6e7c57),\r
-  pointer_default(unique)\r
-]\r
-interface IRemoteActivation\r
-{\r
-  const unsigned long MODE_GET_CLASS_OBJECT = 0xffffffff;\r
-\r
-  HRESULT RemoteActivation(\r
-    [in] handle_t hRpc,\r
-    [in] ORPCTHIS *ORPCthis,\r
-    [out] ORPCTHAT *ORPCthat,\r
-    [in] GUID *Clsid,\r
-    [in, string, unique] WCHAR *pwszObjectName,\r
-    [in, unique] MInterfacePointer *pObjectStorage,\r
-    [in] DWORD ClientImpLevel,\r
-    [in] DWORD Mode,\r
-    [in] DWORD Interfaces,\r
-    [in, unique, size_is(Interfaces)] IID *pIIDs,\r
-    [in] unsigned short cRequestedProtseqs,\r
-    [in, size_is(cRequestedProtseqs)] unsigned short RequestedProtseqs[],\r
-    [out] OXID *pOxid,\r
-    [out] DUALSTRINGARRAY **ppdsaOxidBindings,\r
-    [out] IPID *pipidRemUnknown,\r
-    [out] DWORD *pAuthnHint,\r
-    [out] COMVERSION *pServerVersion,\r
-    [out] HRESULT *phr,\r
-    [out,size_is(Interfaces)] MInterfacePointer **ppInterfaceData,\r
-    [out,size_is(Interfaces)] HRESULT *pResults);\r
-}\r
-cpp_quote("#endif")\r
+/*
+ * Copyright 2003 Ove Kåven, TransGaming Technologies
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/* see http://www.microsoft.com/msj/0398/dcom.htm */
+/* and the official DCOM specification
+ * (there's a copy at http://www.grimes.demon.co.uk/DCOM/DCOMSpec.htm) */
+
+import "unknwn.idl";
+
+[
+  uuid(99fcfe60-5260-101b-bbcb-00aa0021347a),
+  pointer_default(unique)
+]
+interface ObjectRpcBaseTypes
+{
+  typedef unsigned hyper ID;
+  typedef ID MID;
+  typedef ID OXID;
+  typedef ID OID;
+  typedef ID SETID;
+  typedef GUID IPID;
+  typedef GUID CID;
+  typedef REFGUID REFIPID;
+
+  const unsigned short COM_MINOR_VERSION_1 = 1;
+  const unsigned short COM_MINOR_VERSION_2 = 2;
+
+  const unsigned short COM_MAJOR_VERSION = 5;
+  const unsigned short COM_MINOR_VERSION = 3;
+
+  typedef struct tagCOMVERSION {
+    unsigned short MajorVersion;
+    unsigned short MinorVersion;
+  } COMVERSION;
+
+  const unsigned long ORPCF_NULL = 0;
+  const unsigned long ORPCF_LOCAL = 1;
+  const unsigned long ORPCF_RESERVED1 = 2;
+  const unsigned long ORPCF_RESERVED2 = 4;
+  const unsigned long ORPCF_RESERVED3 = 8;
+  const unsigned long ORPCF_RESERVED4 = 16;
+
+  typedef struct tagORPC_EXTENT {
+    GUID id;
+    unsigned long size;
+    [size_is((size+7)&~7)] byte data[];
+  } ORPC_EXTENT;
+
+  typedef struct tagORPC_EXTENT_ARRAY {
+    unsigned long size;
+    unsigned long reserved;
+    [size_is((size+1)&~1,), unique] ORPC_EXTENT **extent;
+  } ORPC_EXTENT_ARRAY;
+
+  typedef struct tagORPCTHIS {
+    COMVERSION version;
+    unsigned long flags;
+    unsigned long reserved1;
+    CID cid;
+    [unique] ORPC_EXTENT_ARRAY *extensions;
+  } ORPCTHIS;
+
+  typedef struct tagORPCTHAT {
+    unsigned long flags;
+    [unique] ORPC_EXTENT_ARRAY *extensions;
+  } ORPCTHAT;
+
+  const unsigned short NCADG_IP_UDP = 0x08;
+  const unsigned short NCACN_IP_TCP = 0x07;
+  const unsigned short NCADG_IPX = 0x0E;
+  const unsigned short NCACN_SPX = 0x0C;
+  const unsigned short NCACN_NB_NB = 0x12;
+  const unsigned short NCACN_NB_IPX = 0x0D;
+  const unsigned short NCACN_DNET_NSP = 0x04;
+  const unsigned short NCACN_HTTP = 0x1F;
+
+  typedef struct tagSTRINGBINDING {
+    unsigned short wTowerId;
+    [string] WCHAR aNetworkAddr[];
+  } STRINGBINDING;
+
+  const unsigned short COM_C_AUTHZ_NONE = 0xffff;
+
+  typedef struct tagSECURITYBINDING {
+    unsigned short wAuthnSvc;
+    unsigned short wAuthzSvc;
+    [string] WCHAR aPrincName[];
+  } SECURITYBINDING;
+
+  typedef struct tagDUALSTRINGARRAY {
+    unsigned short wNumEntries;
+    unsigned short wSecurityOffset;
+    [size_is(wNumEntries)] unsigned short aStringArray[];
+  } DUALSTRINGARRAY;
+
+  const unsigned long OBJREF_SIGNATURE = 0x574f454d; /* "MEOW" */
+  const unsigned long OBJREF_STANDARD = 0x1;
+  const unsigned long OBJREF_HANDLER = 0x2;
+  const unsigned long OBJREF_CUSTOM = 0x4;
+  const unsigned long SORF_OXRES1 = 0x1;
+  const unsigned long SORF_OXRES2 = 0x20;
+  const unsigned long SORF_OXRES3 = 0x40;
+  const unsigned long SORF_OXRES4 = 0x80;
+  const unsigned long SORF_OXRES5 = 0x100;
+  const unsigned long SORF_OXRES6 = 0x200;
+  const unsigned long SORF_OXRES7 = 0x400;
+  const unsigned long SORF_OXRES8 = 0x800;
+  const unsigned long SORF_NULL = 0x0;
+  const unsigned long SORF_NOPING = 0x1000;
+
+  typedef struct tagSTDOBJREF {
+    unsigned long flags;
+    unsigned long cPublicRefs;
+    OXID oxid;
+    OID oid;
+    IPID ipid;
+  } STDOBJREF;
+
+  typedef struct tagOBJREF {
+    unsigned long signature;
+    unsigned long flags;
+    GUID iid;
+    [switch_is(flags)] union {
+    [case(OBJREF_STANDARD)] struct OR_STANDARD {
+        STDOBJREF std;
+        DUALSTRINGARRAY saResAddr;
+      } u_standard;
+    [case(OBJREF_HANDLER)] struct OR_HANDLER {
+        STDOBJREF std;
+        CLSID clsid;
+        DUALSTRINGARRAY saResAddr;
+      } u_handler;
+    [case(OBJREF_CUSTOM)] struct OR_CUSTOM {
+        CLSID clsid;
+        unsigned long cbExtension;
+        unsigned long size;
+        [size_is(size), ref] byte *pData;
+      } u_custom;
+    } u_objref;
+  } OBJREF;
+
+  typedef struct tagMInterfacePointer {
+    ULONG ulCntData;
+    [size_is(ulCntData)] BYTE abData[];
+  } MInterfacePointer;
+
+  typedef [unique] MInterfacePointer *PMInterfacePointer;
+
+} /* interface ObjectRpcBaseTypes */
+
+[
+  object,
+  uuid(00000131-0000-0000-C000-000000000046)
+]
+interface IRemUnknown : IUnknown
+{
+  typedef [unique] IRemUnknown *LPREMUNKNOWN;
+
+  typedef struct tagREMQIRESULT {
+    HRESULT hResult;
+    STDOBJREF std;
+  } REMQIRESULT;
+
+  typedef struct tagREMINTERFACEREF {
+    IPID ipid;
+    unsigned long cPublicRefs;
+    unsigned long cPrivateRefs;
+  } REMINTERFACEREF; 
+
+  HRESULT RemQueryInterface(
+    [in] REFIPID ripid,
+    [in] unsigned long cRefs,
+    [in] unsigned short cIids,
+    [in, size_is(cIids)] IID *iids,
+    [out, size_is(,cIids)] REMQIRESULT **ppQIResults);
+
+  HRESULT RemAddRef(
+    [in] unsigned short cInterfaceRefs,
+    [in, size_is(cInterfaceRefs)] REMINTERFACEREF* InterfaceRefs,
+    [out, size_is(cInterfaceRefs)] HRESULT *pResults);
+
+  HRESULT RemRelease(
+    [in] unsigned short cInterfaceRefs,
+    [in, size_is(cInterfaceRefs)] REMINTERFACEREF* InterfaceRefs);
+}
+
+[
+  object,
+  uuid(00000142-0000-0000-C000-000000000046)
+]
+interface IRemUnknown2 : IRemUnknown
+{
+  typedef [unique] IRemUnknown2 *LPREMUNKNOWN2;
+
+  HRESULT RemQueryInterface2(
+    [in] REFIPID ripid,
+    [in] unsigned short cIids,
+    [in, size_is(cIids)] IID *iids,
+    [out, size_is(cIids)] HRESULT *phr,
+    [out, size_is(cIids)] MInterfacePointer **ppMIF);
+}
+
+cpp_quote("#if 0")
+[
+  uuid(99fcfec4-5260-101b-bbcb-00aa0021347a),
+  pointer_default(unique)
+]
+interface IOXIDResolver
+{
+  [idempotent] error_status_t ResolveOxid(
+    [in] handle_t hRpc,
+    [in] OXID *pOxid,
+    [in] unsigned short cRequestedProtseqs,
+    [in, ref, size_is(cRequestedProtseqs)] unsigned short arRequestedProtseqs[],
+    [out, ref] DUALSTRINGARRAY **ppdsaOxidBindings,
+    [out, ref] IPID *pipidRemUnknown,
+    [out, ref] DWORD *pAuthnHint);
+
+  [idempotent] error_status_t SimplePing(
+    [in] handle_t hRpc,
+    [in] SETID *pSetId);
+
+  [idempotent] error_status_t ComplexPing(
+    [in] handle_t hRpc,
+    [in, out] SETID *pSetId,
+    [in] unsigned short SequenceNum,
+    [in] unsigned short cAddToSet,
+    [in] unsigned short cDelFromSet,
+    [in, unique, size_is(cAddToSet)] OID AddToSet[],
+    [in, unique, size_is(cDelFromSet)] OID DelFromSet[],
+    [out] unsigned short *pPingBackoffFactor);
+
+  [idempotent] error_status_t ServerAlive(
+    [in] handle_t hRpc);
+
+  [idempotent] error_status_t ResolveOxid2(
+    [in] handle_t hRpc,
+    [in] OXID *pOxid,
+    [in] unsigned short cRequestedProtseqs,
+    [in, ref, size_is(cRequestedProtseqs)] unsigned short arRequestedProtseqs[],
+    [out, ref] DUALSTRINGARRAY **ppdsaOxidBindings,
+    [out, ref] IPID *pipidRemUnknown,
+    [out, ref] DWORD *pAuthnHint,
+    [out, ref] COMVERSION *pComVersion); 
+}
+
+[
+  uuid(4d9f4ab8-7d1c-11cf-861e-0020af6e7c57),
+  pointer_default(unique)
+]
+interface IRemoteActivation
+{
+  const unsigned long MODE_GET_CLASS_OBJECT = 0xffffffff;
+
+  HRESULT RemoteActivation(
+    [in] handle_t hRpc,
+    [in] ORPCTHIS *ORPCthis,
+    [out] ORPCTHAT *ORPCthat,
+    [in] GUID *Clsid,
+    [in, string, unique] WCHAR *pwszObjectName,
+    [in, unique] MInterfacePointer *pObjectStorage,
+    [in] DWORD ClientImpLevel,
+    [in] DWORD Mode,
+    [in] DWORD Interfaces,
+    [in, unique, size_is(Interfaces)] IID *pIIDs,
+    [in] unsigned short cRequestedProtseqs,
+    [in, size_is(cRequestedProtseqs)] unsigned short RequestedProtseqs[],
+    [out] OXID *pOxid,
+    [out] DUALSTRINGARRAY **ppdsaOxidBindings,
+    [out] IPID *pipidRemUnknown,
+    [out] DWORD *pAuthnHint,
+    [out] COMVERSION *pServerVersion,
+    [out] HRESULT *phr,
+    [out,size_is(Interfaces)] MInterfacePointer **ppInterfaceData,
+    [out,size_is(Interfaces)] HRESULT *pResults);
+}
+cpp_quote("#endif")
index 7486a52..ffd2386 100644 (file)
@@ -67,37 +67,25 @@ WINE_DEFAULT_DEBUG_CHANNEL(ole);
  */
 struct DefaultHandler
 {
-  /*
-   * List all interface VTables here
-   */
   const IOleObjectVtbl*      lpVtbl;
   const IUnknownVtbl*        lpvtblIUnknown;
   const IDataObjectVtbl*     lpvtblIDataObject;
   const IRunnableObjectVtbl* lpvtblIRunnableObject;
+  const IAdviseSinkVtbl     *lpvtblIAdviseSink;
 
-  /*
-   * Reference count of this object
-   */
+  /* Reference count of this object */
   LONG ref;
 
-  /*
-   * IUnknown implementation of the outer object.
-p   */
+  /* IUnknown implementation of the outer object. */
   IUnknown* outerUnknown;
 
-  /*
-   * Class Id that this handler object represents.
-   */
+  /* Class Id that this handler object represents. */
   CLSID clsid;
 
-  /*
-   * IUnknown implementation of the datacache.
-   */
+  /* IUnknown implementation of the datacache. */
   IUnknown* dataCache;
 
-  /*
-   * Client site for the embedded object.
-   */
+  /* Client site for the embedded object. */
   IOleClientSite* clientSite;
 
   /*
@@ -112,19 +100,24 @@ p   */
    */
   IDataAdviseHolder* dataAdviseHolder;
 
-  /*
-   * Name of the container and object contained
-   */
+  /* Name of the container and object contained */
   LPWSTR containerApp;
   LPWSTR containerObj;
 
+  /* IOleObject delegate */
+  IOleObject *pOleDelegate;
+  /* IPersistStorage delegate */
+  IPersistStorage *pPSDelegate;
+
+  /* connection cookie for the advise on the delegate OLE object */
+  DWORD dwAdvConn;
 };
 
 typedef struct DefaultHandler DefaultHandler;
 
 /*
  * Here, I define utility functions to help with the casting of the
- * "this" parameter.
+ * "This" parameter.
  * There is a version to accommodate all of the VTables implemented
  * by this object.
  */
@@ -148,436 +141,14 @@ static inline DefaultHandler *impl_from_IRunnableObject( IRunnableObject *iface
     return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIRunnableObject));
 }
 
-
-/*
- * Prototypes for the methods of the DefaultHandler class.
- */
-static DefaultHandler* DefaultHandler_Construct(REFCLSID  clsid,
-                                               LPUNKNOWN pUnkOuter);
-static void            DefaultHandler_Destroy(DefaultHandler* ptrToDestroy);
-
-/*
- * Prototypes for the methods of the DefaultHandler class
- * that implement non delegating IUnknown methods.
- */
-static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
-            IUnknown*      iface,
-            REFIID         riid,
-            void**         ppvObject);
-static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
-            IUnknown*      iface);
-static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
-            IUnknown*      iface);
-
-/*
- * Prototypes for the methods of the DefaultHandler class
- * that implement IOleObject methods.
- */
-static HRESULT WINAPI DefaultHandler_QueryInterface(
-            IOleObject*      iface,
-            REFIID           riid,
-            void**           ppvObject);
-static ULONG WINAPI DefaultHandler_AddRef(
-            IOleObject*        iface);
-static ULONG WINAPI DefaultHandler_Release(
-            IOleObject*        iface);
-static HRESULT WINAPI DefaultHandler_SetClientSite(
-           IOleObject*        iface,
-           IOleClientSite*    pClientSite);
-static HRESULT WINAPI DefaultHandler_GetClientSite(
-           IOleObject*        iface,
-           IOleClientSite**   ppClientSite);
-static HRESULT WINAPI DefaultHandler_SetHostNames(
-           IOleObject*        iface,
-           LPCOLESTR          szContainerApp,
-           LPCOLESTR          szContainerObj);
-static HRESULT WINAPI DefaultHandler_Close(
-           IOleObject*        iface,
-           DWORD              dwSaveOption);
-static HRESULT WINAPI DefaultHandler_SetMoniker(
-           IOleObject*        iface,
-           DWORD              dwWhichMoniker,
-           IMoniker*          pmk);
-static HRESULT WINAPI DefaultHandler_GetMoniker(
-           IOleObject*        iface,
-           DWORD              dwAssign,
-           DWORD              dwWhichMoniker,
-           IMoniker**         ppmk);
-static HRESULT WINAPI DefaultHandler_InitFromData(
-           IOleObject*        iface,
-           IDataObject*       pDataObject,
-           BOOL               fCreation,
-           DWORD              dwReserved);
-static HRESULT WINAPI DefaultHandler_GetClipboardData(
-           IOleObject*        iface,
-           DWORD              dwReserved,
-           IDataObject**      ppDataObject);
-static HRESULT WINAPI DefaultHandler_DoVerb(
-           IOleObject*        iface,
-           LONG               iVerb,
-           struct tagMSG*     lpmsg,
-           IOleClientSite*    pActiveSite,
-           LONG               lindex,
-           HWND               hwndParent,
-           LPCRECT            lprcPosRect);
-static HRESULT WINAPI DefaultHandler_EnumVerbs(
-           IOleObject*        iface,
-           IEnumOLEVERB**     ppEnumOleVerb);
-static HRESULT WINAPI DefaultHandler_Update(
-           IOleObject*        iface);
-static HRESULT WINAPI DefaultHandler_IsUpToDate(
-           IOleObject*        iface);
-static HRESULT WINAPI DefaultHandler_GetUserClassID(
-           IOleObject*        iface,
-           CLSID*             pClsid);
-static HRESULT WINAPI DefaultHandler_GetUserType(
-           IOleObject*        iface,
-           DWORD              dwFormOfType,
-           LPOLESTR*          pszUserType);
-static HRESULT WINAPI DefaultHandler_SetExtent(
-           IOleObject*        iface,
-           DWORD              dwDrawAspect,
-           SIZEL*             psizel);
-static HRESULT WINAPI DefaultHandler_GetExtent(
-           IOleObject*        iface,
-           DWORD              dwDrawAspect,
-           SIZEL*             psizel);
-static HRESULT WINAPI DefaultHandler_Advise(
-           IOleObject*        iface,
-           IAdviseSink*       pAdvSink,
-           DWORD*             pdwConnection);
-static HRESULT WINAPI DefaultHandler_Unadvise(
-           IOleObject*        iface,
-           DWORD              dwConnection);
-static HRESULT WINAPI DefaultHandler_EnumAdvise(
-           IOleObject*        iface,
-           IEnumSTATDATA**    ppenumAdvise);
-static HRESULT WINAPI DefaultHandler_GetMiscStatus(
-           IOleObject*        iface,
-           DWORD              dwAspect,
-           DWORD*             pdwStatus);
-static HRESULT WINAPI DefaultHandler_SetColorScheme(
-           IOleObject*           iface,
-           struct tagLOGPALETTE* pLogpal);
-
-/*
- * Prototypes for the methods of the DefaultHandler class
- * that implement IDataObject methods.
- */
-static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
-            IDataObject*     iface,
-            REFIID           riid,
-            void**           ppvObject);
-static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
-            IDataObject*     iface);
-static ULONG WINAPI DefaultHandler_IDataObject_Release(
-            IDataObject*     iface);
-static HRESULT WINAPI DefaultHandler_GetData(
-           IDataObject*     iface,
-           LPFORMATETC      pformatetcIn,
-           STGMEDIUM*       pmedium);
-static HRESULT WINAPI DefaultHandler_GetDataHere(
-           IDataObject*     iface,
-           LPFORMATETC      pformatetc,
-           STGMEDIUM*       pmedium);
-static HRESULT WINAPI DefaultHandler_QueryGetData(
-           IDataObject*     iface,
-           LPFORMATETC      pformatetc);
-static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
-           IDataObject*     iface,
-           LPFORMATETC      pformatectIn,
-           LPFORMATETC      pformatetcOut);
-static HRESULT WINAPI DefaultHandler_SetData(
-           IDataObject*     iface,
-           LPFORMATETC      pformatetc,
-           STGMEDIUM*       pmedium,
-           BOOL             fRelease);
-static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
-           IDataObject*     iface,
-           DWORD            dwDirection,
-           IEnumFORMATETC** ppenumFormatEtc);
-static HRESULT WINAPI DefaultHandler_DAdvise(
-           IDataObject*     iface,
-           FORMATETC*       pformatetc,
-           DWORD            advf,
-           IAdviseSink*     pAdvSink,
-           DWORD*           pdwConnection);
-static HRESULT WINAPI DefaultHandler_DUnadvise(
-           IDataObject*     iface,
-           DWORD            dwConnection);
-static HRESULT WINAPI DefaultHandler_EnumDAdvise(
-           IDataObject*     iface,
-           IEnumSTATDATA**  ppenumAdvise);
-
-/*
- * Prototypes for the methods of the DefaultHandler class
- * that implement IRunnableObject methods.
- */
-static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
-            IRunnableObject*     iface,
-            REFIID               riid,
-            void**               ppvObject);
-static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
-            IRunnableObject*     iface);
-static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
-            IRunnableObject*     iface);
-static HRESULT WINAPI DefaultHandler_GetRunningClass(
-            IRunnableObject*     iface,
-           LPCLSID              lpClsid);
-static HRESULT WINAPI DefaultHandler_Run(
-            IRunnableObject*     iface,
-           IBindCtx*            pbc);
-static BOOL    WINAPI DefaultHandler_IsRunning(
-            IRunnableObject*     iface);
-static HRESULT WINAPI DefaultHandler_LockRunning(
-            IRunnableObject*     iface,
-           BOOL                 fLock,
-           BOOL                 fLastUnlockCloses);
-static HRESULT WINAPI DefaultHandler_SetContainedObject(
-            IRunnableObject*     iface,
-           BOOL                 fContained);
-
-
-/*
- * Virtual function tables for the DefaultHandler class.
- */
-static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
-{
-  DefaultHandler_QueryInterface,
-  DefaultHandler_AddRef,
-  DefaultHandler_Release,
-  DefaultHandler_SetClientSite,
-  DefaultHandler_GetClientSite,
-  DefaultHandler_SetHostNames,
-  DefaultHandler_Close,
-  DefaultHandler_SetMoniker,
-  DefaultHandler_GetMoniker,
-  DefaultHandler_InitFromData,
-  DefaultHandler_GetClipboardData,
-  DefaultHandler_DoVerb,
-  DefaultHandler_EnumVerbs,
-  DefaultHandler_Update,
-  DefaultHandler_IsUpToDate,
-  DefaultHandler_GetUserClassID,
-  DefaultHandler_GetUserType,
-  DefaultHandler_SetExtent,
-  DefaultHandler_GetExtent,
-  DefaultHandler_Advise,
-  DefaultHandler_Unadvise,
-  DefaultHandler_EnumAdvise,
-  DefaultHandler_GetMiscStatus,
-  DefaultHandler_SetColorScheme
-};
-
-static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
-{
-  DefaultHandler_NDIUnknown_QueryInterface,
-  DefaultHandler_NDIUnknown_AddRef,
-  DefaultHandler_NDIUnknown_Release,
-};
-
-static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
-{
-  DefaultHandler_IDataObject_QueryInterface,
-  DefaultHandler_IDataObject_AddRef,
-  DefaultHandler_IDataObject_Release,
-  DefaultHandler_GetData,
-  DefaultHandler_GetDataHere,
-  DefaultHandler_QueryGetData,
-  DefaultHandler_GetCanonicalFormatEtc,
-  DefaultHandler_SetData,
-  DefaultHandler_EnumFormatEtc,
-  DefaultHandler_DAdvise,
-  DefaultHandler_DUnadvise,
-  DefaultHandler_EnumDAdvise
-};
-
-static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
-{
-  DefaultHandler_IRunnableObject_QueryInterface,
-  DefaultHandler_IRunnableObject_AddRef,
-  DefaultHandler_IRunnableObject_Release,
-  DefaultHandler_GetRunningClass,
-  DefaultHandler_Run,
-  DefaultHandler_IsRunning,
-  DefaultHandler_LockRunning,
-  DefaultHandler_SetContainedObject
-};
-
-/******************************************************************************
- * OleCreateDefaultHandler [OLE32.@]
- */
-HRESULT WINAPI OleCreateDefaultHandler(
-  REFCLSID  clsid,
-  LPUNKNOWN pUnkOuter,
-  REFIID    riid,
-  LPVOID*   ppvObj)
-{
-  DefaultHandler* newHandler = NULL;
-  HRESULT         hr         = S_OK;
-
-  TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
-
-  /*
-   * Sanity check
-   */
-  if (ppvObj==0)
-    return E_POINTER;
-
-  *ppvObj = 0;
-
-  /*
-   * If this handler is constructed for aggregation, make sure
-   * the caller is requesting the IUnknown interface.
-   * This is necessary because it's the only time the non-delegating
-   * IUnknown pointer can be returned to the outside.
-   */
-  if ( (pUnkOuter!=NULL) &&
-       (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) != 0) )
-    return CLASS_E_NOAGGREGATION;
-
-  /*
-   * Try to construct a new instance of the class.
-   */
-  newHandler = DefaultHandler_Construct(clsid,
-                                       pUnkOuter);
-
-  if (newHandler == 0)
-    return E_OUTOFMEMORY;
-
-  /*
-   * Make sure it supports the interface required by the caller.
-   */
-  hr = IUnknown_QueryInterface((IUnknown*)&(newHandler->lpvtblIUnknown), riid, ppvObj);
-
-  /*
-   * Release the reference obtained in the constructor. If
-   * the QueryInterface was unsuccessful, it will free the class.
-   */
-  IUnknown_Release((IUnknown*)&(newHandler->lpvtblIUnknown));
-
-  return hr;
-}
-
-/*********************************************************
- * Methods implementation for the DefaultHandler class.
- */
-static DefaultHandler* DefaultHandler_Construct(
-  REFCLSID  clsid,
-  LPUNKNOWN pUnkOuter)
+static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface )
 {
-  DefaultHandler* newObject = 0;
-
-  /*
-   * Allocate space for the object.
-   */
-  newObject = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
-
-  if (newObject==0)
-    return newObject;
-
-  /*
-   * Initialize the virtual function table.
-   */
-  newObject->lpVtbl = &DefaultHandler_IOleObject_VTable;
-  newObject->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
-  newObject->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
-  newObject->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
-
-  /*
-   * Start with one reference count. The caller of this function
-   * must release the interface pointer when it is done.
-   */
-  newObject->ref = 1;
-
-  /*
-   * Initialize the outer unknown
-   * We don't keep a reference on the outer unknown since, the way
-   * aggregation works, our lifetime is at least as large as it's
-   * lifetime.
-   */
-  if (pUnkOuter==NULL)
-    pUnkOuter = (IUnknown*)&(newObject->lpvtblIUnknown);
-
-  newObject->outerUnknown = pUnkOuter;
-
-  /*
-   * Create a datacache object.
-   * We aggregate with the datacache. Make sure we pass our outer
-   * unknown as the datacache's outer unknown.
-   */
-  CreateDataCache(newObject->outerUnknown,
-                 clsid,
-                 &IID_IUnknown,
-                 (void**)&newObject->dataCache);
-
-  /*
-   * Initialize the other data members of the class.
-   */
-  memcpy(&(newObject->clsid), clsid, sizeof(CLSID));
-  newObject->clientSite = NULL;
-  newObject->oleAdviseHolder = NULL;
-  newObject->dataAdviseHolder = NULL;
-  newObject->containerApp = NULL;
-  newObject->containerObj = NULL;
-
-  return newObject;
+    return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIAdviseSink));
 }
 
-static void DefaultHandler_Destroy(
-  DefaultHandler* ptrToDestroy)
-{
-  /*
-   * Free the strings idenfitying the object
-   */
-  HeapFree( GetProcessHeap(), 0, ptrToDestroy->containerApp );
-  ptrToDestroy->containerApp = NULL;
-  HeapFree( GetProcessHeap(), 0, ptrToDestroy->containerObj );
-  ptrToDestroy->containerObj = NULL;
-
-  /*
-   * Release our reference to the data cache.
-   */
-  if (ptrToDestroy->dataCache!=NULL)
-  {
-    IUnknown_Release(ptrToDestroy->dataCache);
-    ptrToDestroy->dataCache = NULL;
-  }
-
-  /*
-   * Same thing for the client site.
-   */
-  if (ptrToDestroy->clientSite!=NULL)
-  {
-    IOleClientSite_Release(ptrToDestroy->clientSite);
-    ptrToDestroy->clientSite = NULL;
-  }
-
-  /*
-   * And the advise holder.
-   */
-  if (ptrToDestroy->oleAdviseHolder!=NULL)
-  {
-    IOleAdviseHolder_Release(ptrToDestroy->oleAdviseHolder);
-    ptrToDestroy->oleAdviseHolder = NULL;
-  }
-
-  /*
-   * And the data advise holder.
-   */
-  if (ptrToDestroy->dataAdviseHolder!=NULL)
-  {
-    IDataAdviseHolder_Release(ptrToDestroy->dataAdviseHolder);
-    ptrToDestroy->dataAdviseHolder = NULL;
-  }
+static void DefaultHandler_Destroy(DefaultHandler* This);
 
 
-  /*
-   * Free the actual default handler structure.
-   */
-  HeapFree(GetProcessHeap(), 0, ptrToDestroy);
-}
-
 /*********************************************************
  * Method implementation for the  non delegating IUnknown
  * part of the DefaultHandler class.
@@ -596,51 +167,36 @@ static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
             REFIID         riid,
             void**         ppvObject)
 {
-  DefaultHandler *this = impl_from_NDIUnknown(iface);
+  DefaultHandler *This = impl_from_NDIUnknown(iface);
 
-  /*
-   * Perform a sanity check on the parameters.
-   */
-  if ( (this==0) || (ppvObject==0) )
+  /* Perform a sanity check on the parameters. */
+  if (!ppvObject)
     return E_INVALIDARG;
 
-  /*
-   * Initialize the return parameter.
-   */
-  *ppvObject = 0;
+  *ppvObject = NULL;
 
-  /*
-   * Compare the riid with the interface IDs implemented by this object.
-   */
-  if (memcmp(&IID_IUnknown, riid, sizeof(IID_IUnknown)) == 0)
-  {
+  if (IsEqualIID(&IID_IUnknown, riid))
     *ppvObject = iface;
-  }
-  else if (memcmp(&IID_IOleObject, riid, sizeof(IID_IOleObject)) == 0)
+  else if (IsEqualIID(&IID_IOleObject, riid))
+    *ppvObject = (IOleObject*)&This->lpVtbl;
+  else if (IsEqualIID(&IID_IDataObject, riid))
+    *ppvObject = (IDataObject*)&This->lpvtblIDataObject;
+  else if (IsEqualIID(&IID_IRunnableObject, riid))
+    *ppvObject = (IRunnableObject*)&This->lpvtblIRunnableObject;
+  else if (IsEqualIID(&IID_IPersist, riid) ||
+           IsEqualIID(&IID_IPersistStorage, riid) ||
+           IsEqualIID(&IID_IViewObject, riid) ||
+           IsEqualIID(&IID_IViewObject2, riid) ||
+           IsEqualIID(&IID_IOleCache, riid) ||
+           IsEqualIID(&IID_IOleCache2, riid))
   {
-    *ppvObject = (IOleObject*)&(this->lpVtbl);
-  }
-  else if (memcmp(&IID_IDataObject, riid, sizeof(IID_IDataObject)) == 0)
-  {
-    *ppvObject = (IDataObject*)&(this->lpvtblIDataObject);
-  }
-  else if (memcmp(&IID_IRunnableObject, riid, sizeof(IID_IRunnableObject)) == 0)
-  {
-    *ppvObject = (IRunnableObject*)&(this->lpvtblIRunnableObject);
-  }
-  else
-  {
-    /*
-     * Blind aggregate the data cache to "inherit" it's interfaces.
-     */
-    if (IUnknown_QueryInterface(this->dataCache, riid, ppvObject) == S_OK)
-       return S_OK;
+    HRESULT hr = IUnknown_QueryInterface(This->dataCache, riid, ppvObject);
+    if (FAILED(hr)) FIXME("interface %s not implemented by data cache\n", debugstr_guid(riid));
+    return hr;
   }
 
-  /*
-   * Check that we obtained an interface.
-   */
-  if ((*ppvObject)==0)
+  /* Check that we obtained an interface. */
+  if (*ppvObject == NULL)
   {
     WARN( "() : asking for un supported interface %s\n", debugstr_guid(riid));
     return E_NOINTERFACE;
@@ -666,8 +222,8 @@ static HRESULT WINAPI DefaultHandler_NDIUnknown_QueryInterface(
 static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
             IUnknown*      iface)
 {
-  DefaultHandler *this = impl_from_NDIUnknown(iface);
-  return InterlockedIncrement(&this->ref);
+  DefaultHandler *This = impl_from_NDIUnknown(iface);
+  return InterlockedIncrement(&This->ref);
 }
 
 /************************************************************************
@@ -681,18 +237,13 @@ static ULONG WINAPI DefaultHandler_NDIUnknown_AddRef(
 static ULONG WINAPI DefaultHandler_NDIUnknown_Release(
             IUnknown*      iface)
 {
-  DefaultHandler *this = impl_from_NDIUnknown(iface);
+  DefaultHandler *This = impl_from_NDIUnknown(iface);
   ULONG ref;
 
-  /*
-   * Decrease the reference count on this object.
-   */
-  ref = InterlockedDecrement(&this->ref);
+  /* Decrease the reference count on this object. */
+  ref = InterlockedDecrement(&This->ref);
 
-  /*
-   * If the reference count goes down to 0, perform suicide.
-   */
-  if (ref == 0) DefaultHandler_Destroy(this);
+  if (!ref) DefaultHandler_Destroy(This);
 
   return ref;
 }
@@ -712,9 +263,9 @@ static HRESULT WINAPI DefaultHandler_QueryInterface(
             REFIID           riid,
             void**           ppvObject)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
-  return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
+  return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
 }
 
 /************************************************************************
@@ -725,9 +276,9 @@ static HRESULT WINAPI DefaultHandler_QueryInterface(
 static ULONG WINAPI DefaultHandler_AddRef(
             IOleObject*        iface)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
-  return IUnknown_AddRef(this->outerUnknown);
+  return IUnknown_AddRef(This->outerUnknown);
 }
 
 /************************************************************************
@@ -738,9 +289,9 @@ static ULONG WINAPI DefaultHandler_AddRef(
 static ULONG WINAPI DefaultHandler_Release(
             IOleObject*        iface)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
-  return IUnknown_Release(this->outerUnknown);
+  return IUnknown_Release(This->outerUnknown);
 }
 
 /************************************************************************
@@ -755,7 +306,7 @@ static HRESULT WINAPI DefaultHandler_SetClientSite(
            IOleObject*        iface,
            IOleClientSite*    pClientSite)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
   TRACE("(%p, %p)\n", iface, pClientSite);
 
@@ -763,17 +314,13 @@ static HRESULT WINAPI DefaultHandler_SetClientSite(
    * Make sure we release the previous client site if there
    * was one.
    */
-  if (this->clientSite!=NULL)
-  {
-    IOleClientSite_Release(this->clientSite);
-  }
+  if (This->clientSite)
+    IOleClientSite_Release(This->clientSite);
 
-  this->clientSite = pClientSite;
+  This->clientSite = pClientSite;
 
-  if (this->clientSite!=NULL)
-  {
-    IOleClientSite_AddRef(this->clientSite);
-  }
+  if (This->clientSite)
+    IOleClientSite_AddRef(This->clientSite);
 
   return S_OK;
 }
@@ -790,20 +337,16 @@ static HRESULT WINAPI DefaultHandler_GetClientSite(
            IOleObject*        iface,
            IOleClientSite**   ppClientSite)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
-  /*
-   * Sanity check.
-   */
-  if (ppClientSite == NULL)
+  /* Sanity check. */
+  if (!ppClientSite)
     return E_POINTER;
 
-  *ppClientSite = this->clientSite;
+  *ppClientSite = This->clientSite;
 
-  if (this->clientSite != NULL)
-  {
-    IOleClientSite_AddRef(this->clientSite);
-  }
+  if (This->clientSite)
+    IOleClientSite_AddRef(This->clientSite);
 
   return S_OK;
 }
@@ -821,40 +364,55 @@ static HRESULT WINAPI DefaultHandler_SetHostNames(
            LPCOLESTR          szContainerApp,
            LPCOLESTR          szContainerObj)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
   TRACE("(%p, %s, %s)\n",
        iface,
        debugstr_w(szContainerApp),
        debugstr_w(szContainerObj));
 
-  /*
-   * Be sure to cleanup before re-assinging the strings.
-   */
-  HeapFree( GetProcessHeap(), 0, this->containerApp );
-  this->containerApp = NULL;
-  HeapFree( GetProcessHeap(), 0, this->containerObj );
-  this->containerObj = NULL;
+  /* Be sure to cleanup before re-assinging the strings. */
+  HeapFree( GetProcessHeap(), 0, This->containerApp );
+  This->containerApp = NULL;
+  HeapFree( GetProcessHeap(), 0, This->containerObj );
+  This->containerObj = NULL;
 
-  /*
-   * Copy the string supplied.
-   */
-  if (szContainerApp != NULL)
+  /* Copy the string supplied. */
+  if (szContainerApp)
   {
-      if ((this->containerApp = HeapAlloc( GetProcessHeap(), 0,
+      if ((This->containerApp = HeapAlloc( GetProcessHeap(), 0,
                                            (lstrlenW(szContainerApp) + 1) * sizeof(WCHAR) )))
-          strcpyW( this->containerApp, szContainerApp );
+          strcpyW( This->containerApp, szContainerApp );
   }
 
-  if (szContainerObj != NULL)
+  if (szContainerObj)
   {
-      if ((this->containerObj = HeapAlloc( GetProcessHeap(), 0,
+      if ((This->containerObj = HeapAlloc( GetProcessHeap(), 0,
                                            (lstrlenW(szContainerObj) + 1) * sizeof(WCHAR) )))
-          strcpyW( this->containerObj, szContainerObj );
+          strcpyW( This->containerObj, szContainerObj );
   }
   return S_OK;
 }
 
+/* undos the work done by DefaultHandler_Run */
+static void WINAPI DefaultHandler_Stop(DefaultHandler *This)
+{
+  if (!This->pOleDelegate)
+    return;
+
+  IOleObject_Unadvise(This->pOleDelegate, This->dwAdvConn);
+
+  /* FIXME: call IOleCache_OnStop */
+
+  if (This->pPSDelegate)
+  {
+     IPersistStorage_Release(This->pPSDelegate);
+     This->pPSDelegate = NULL;
+  }
+  IOleObject_Release(This->pOleDelegate);
+  This->pOleDelegate = NULL;
+}
+
 /************************************************************************
  * DefaultHandler_Close (IOleObject)
  *
@@ -867,8 +425,19 @@ static HRESULT WINAPI DefaultHandler_Close(
            IOleObject*        iface,
            DWORD              dwSaveOption)
 {
-  TRACE("()\n");
-  return S_OK;
+  DefaultHandler *This = impl_from_IOleObject(iface);
+  HRESULT hr;
+
+  TRACE("(%ld)\n", dwSaveOption);
+
+  if (!This->pOleDelegate)
+    return S_OK;
+
+  hr = IOleObject_Close(This->pOleDelegate, dwSaveOption);
+
+  DefaultHandler_Stop(This);
+
+  return hr;
 }
 
 /************************************************************************
@@ -904,14 +473,14 @@ static HRESULT WINAPI DefaultHandler_GetMoniker(
            DWORD              dwWhichMoniker,
            IMoniker**         ppmk)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
   TRACE("(%p, %ld, %ld, %p)\n",
        iface, dwAssign, dwWhichMoniker, ppmk);
 
-  if (this->clientSite)
+  if (This->clientSite)
   {
-    return IOleClientSite_GetMoniker(this->clientSite,
+    return IOleClientSite_GetMoniker(This->clientSite,
                                     dwAssign,
                                     dwWhichMoniker,
                                     ppmk);
@@ -983,11 +552,18 @@ static HRESULT WINAPI DefaultHandler_EnumVerbs(
            IOleObject*        iface,
            IEnumOLEVERB**     ppEnumOleVerb)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
+  HRESULT hr = OLE_S_USEREG;
 
   TRACE("(%p, %p)\n", iface, ppEnumOleVerb);
 
-  return OleRegEnumVerbs(&this->clsid, ppEnumOleVerb);
+  if (This->pOleDelegate)
+    hr = IOleObject_EnumVerbs(This->pOleDelegate, ppEnumOleVerb);
+
+  if (hr == OLE_S_USEREG)
+    return OleRegEnumVerbs(&This->clsid, ppEnumOleVerb);
+  else
+    return hr;
 }
 
 static HRESULT WINAPI DefaultHandler_Update(
@@ -1023,17 +599,21 @@ static HRESULT WINAPI DefaultHandler_GetUserClassID(
            IOleObject*        iface,
            CLSID*             pClsid)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
   TRACE("(%p, %p)\n", iface, pClsid);
 
-  /*
-   * Sanity check.
-   */
-  if (pClsid==NULL)
+  if (This->pOleDelegate)
+    return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
+
+  if (This->pOleDelegate)
+    return IOleObject_GetUserClassID(This->pOleDelegate, pClsid);
+
+  /* Sanity check. */
+  if (!pClsid)
     return E_POINTER;
 
-  memcpy(pClsid, &this->clsid, sizeof(CLSID));
+  memcpy(pClsid, &This->clsid, sizeof(CLSID));
 
   return S_OK;
 }
@@ -1051,11 +631,11 @@ static HRESULT WINAPI DefaultHandler_GetUserType(
            DWORD              dwFormOfType,
            LPOLESTR*          pszUserType)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
   TRACE("(%p, %ld, %p)\n", iface, dwFormOfType, pszUserType);
 
-  return OleRegGetUserType(&this->clsid, dwFormOfType, pszUserType);
+  return OleRegGetUserType(&This->clsid, dwFormOfType, pszUserType);
 }
 
 /************************************************************************
@@ -1092,11 +672,11 @@ static HRESULT WINAPI DefaultHandler_GetExtent(
   IViewObject2*   cacheView = NULL;
   HRESULT         hres;
 
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
   TRACE("(%p, %lx, %p)\n", iface, dwDrawAspect, psizel);
 
-  hres = IUnknown_QueryInterface(this->dataCache, &IID_IViewObject2, (void**)&cacheView);
+  hres = IUnknown_QueryInterface(This->dataCache, &IID_IViewObject2, (void**)&cacheView);
 
   if (FAILED(hres))
     return E_UNEXPECTED;
@@ -1139,24 +719,18 @@ static HRESULT WINAPI DefaultHandler_Advise(
            DWORD*             pdwConnection)
 {
   HRESULT hres = S_OK;
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
   TRACE("(%p, %p, %p)\n", iface, pAdvSink, pdwConnection);
 
-  /*
-   * Make sure we have an advise holder before we start.
-   */
-  if (this->oleAdviseHolder==NULL)
-  {
-    hres = CreateOleAdviseHolder(&this->oleAdviseHolder);
-  }
+  /* Make sure we have an advise holder before we start. */
+  if (!This->oleAdviseHolder)
+    hres = CreateOleAdviseHolder(&This->oleAdviseHolder);
 
   if (SUCCEEDED(hres))
-  {
-    hres = IOleAdviseHolder_Advise(this->oleAdviseHolder,
+    hres = IOleAdviseHolder_Advise(This->oleAdviseHolder,
                                   pAdvSink,
                                   pdwConnection);
-  }
 
   return hres;
 }
@@ -1173,7 +747,7 @@ static HRESULT WINAPI DefaultHandler_Unadvise(
            IOleObject*        iface,
            DWORD              dwConnection)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
   TRACE("(%p, %ld)\n", iface, dwConnection);
 
@@ -1181,10 +755,10 @@ static HRESULT WINAPI DefaultHandler_Unadvise(
    * If we don't have an advise holder yet, it means we don't have
    * a connection.
    */
-  if (this->oleAdviseHolder==NULL)
+  if (!This->oleAdviseHolder)
     return OLE_E_NOCONNECTION;
 
-  return IOleAdviseHolder_Unadvise(this->oleAdviseHolder,
+  return IOleAdviseHolder_Unadvise(This->oleAdviseHolder,
                                   dwConnection);
 }
 
@@ -1200,23 +774,18 @@ static HRESULT WINAPI DefaultHandler_EnumAdvise(
            IOleObject*        iface,
            IEnumSTATDATA**    ppenumAdvise)
 {
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
 
   TRACE("(%p, %p)\n", iface, ppenumAdvise);
 
-  /*
-   * Sanity check
-   */
-  if (ppenumAdvise==NULL)
+  /* Sanity check */
+  if (!ppenumAdvise)
     return E_POINTER;
 
-  /*
-   * Initialize the out parameter.
-   */
   *ppenumAdvise = NULL;
 
-  if (this->oleAdviseHolder==NULL)
-    return IOleAdviseHolder_EnumAdvise(this->oleAdviseHolder,
+  if (!This->oleAdviseHolder)
+    return IOleAdviseHolder_EnumAdvise(This->oleAdviseHolder,
                                       ppenumAdvise);
 
   return S_OK;
@@ -1236,11 +805,17 @@ static HRESULT WINAPI DefaultHandler_GetMiscStatus(
            DWORD*             pdwStatus)
 {
   HRESULT hres;
-  DefaultHandler *this = impl_from_IOleObject(iface);
+  DefaultHandler *This = impl_from_IOleObject(iface);
+
+  TRACE("(%p, %lx, %p)\n", iface, dwAspect, pdwStatus);
+
+  if (This->pOleDelegate)
+    return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
 
-  TRACE("(%p, %lx, %p)\n", iface, dwAspect, pdwStatus);
+  if (This->pOleDelegate)
+    return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus);
 
-  hres = OleRegGetMiscStatus(&(this->clsid), dwAspect, pdwStatus);
+  hres = OleRegGetMiscStatus(&This->clsid, dwAspect, pdwStatus);
 
   if (FAILED(hres))
     *pdwStatus = 0;
@@ -1278,9 +853,9 @@ static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
            REFIID           riid,
             void**           ppvObject)
 {
-  DefaultHandler *this = impl_from_IDataObject(iface);
+  DefaultHandler *This = impl_from_IDataObject(iface);
 
-  return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
+  return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
 }
 
 /************************************************************************
@@ -1291,9 +866,9 @@ static HRESULT WINAPI DefaultHandler_IDataObject_QueryInterface(
 static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
             IDataObject*     iface)
 {
-  DefaultHandler *this = impl_from_IDataObject(iface);
+  DefaultHandler *This = impl_from_IDataObject(iface);
 
-  return IUnknown_AddRef(this->outerUnknown);
+  return IUnknown_AddRef(This->outerUnknown);
 }
 
 /************************************************************************
@@ -1304,9 +879,9 @@ static ULONG WINAPI DefaultHandler_IDataObject_AddRef(
 static ULONG WINAPI DefaultHandler_IDataObject_Release(
             IDataObject*     iface)
 {
-  DefaultHandler *this = impl_from_IDataObject(iface);
+  DefaultHandler *This = impl_from_IDataObject(iface);
 
-  return IUnknown_Release(this->outerUnknown);
+  return IUnknown_Release(This->outerUnknown);
 }
 
 /************************************************************************
@@ -1324,11 +899,11 @@ static HRESULT WINAPI DefaultHandler_GetData(
   IDataObject* cacheDataObject = NULL;
   HRESULT      hres;
 
-  DefaultHandler *this = impl_from_IDataObject(iface);
+  DefaultHandler *This = impl_from_IDataObject(iface);
 
   TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pmedium);
 
-  hres = IUnknown_QueryInterface(this->dataCache,
+  hres = IUnknown_QueryInterface(This->dataCache,
                                 &IID_IDataObject,
                                 (void**)&cacheDataObject);
 
@@ -1368,11 +943,11 @@ static HRESULT WINAPI DefaultHandler_QueryGetData(
   IDataObject* cacheDataObject = NULL;
   HRESULT      hres;
 
-  DefaultHandler *this = impl_from_IDataObject(iface);
+  DefaultHandler *This = impl_from_IDataObject(iface);
 
   TRACE("(%p, %p)\n", iface, pformatetc);
 
-  hres = IUnknown_QueryInterface(this->dataCache,
+  hres = IUnknown_QueryInterface(This->dataCache,
                                 &IID_IDataObject,
                                 (void**)&cacheDataObject);
 
@@ -1396,12 +971,20 @@ static HRESULT WINAPI DefaultHandler_QueryGetData(
  */
 static HRESULT WINAPI DefaultHandler_GetCanonicalFormatEtc(
            IDataObject*     iface,
-           LPFORMATETC      pformatectIn,
+           LPFORMATETC      pformatetcIn,
            LPFORMATETC      pformatetcOut)
 {
-  FIXME("(%p, %p, %p)\n", iface, pformatectIn, pformatetcOut);
+  DefaultHandler *This = impl_from_IDataObject(iface);
+  IDataObject *pDataObject;
+  HRESULT hr;
 
-  return OLE_E_NOTRUNNING;
+  TRACE("(%p, %p, %p)\n", iface, pformatetcIn, pformatetcOut);
+
+  if (!This->pOleDelegate)
+    return OLE_E_NOTRUNNING;
+
+  hr = IOleObject_QueryInterface(This->pOleDelegate, &IID_IDataObject, (void **)&pDataObject);
+  return IDataObject_GetCanonicalFormatEtc(pDataObject, pformatetcIn, pformatetcOut);
 }
 
 /************************************************************************
@@ -1418,14 +1001,13 @@ static HRESULT WINAPI DefaultHandler_SetData(
            STGMEDIUM*       pmedium,
            BOOL             fRelease)
 {
+  DefaultHandler *This = impl_from_IDataObject(iface);
   IDataObject* cacheDataObject = NULL;
   HRESULT      hres;
 
-  DefaultHandler *this = impl_from_IDataObject(iface);
-
   TRACE("(%p, %p, %p, %d)\n", iface, pformatetc, pmedium, fRelease);
 
-  hres = IUnknown_QueryInterface(this->dataCache,
+  hres = IUnknown_QueryInterface(This->dataCache,
                                 &IID_IDataObject,
                                 (void**)&cacheDataObject);
 
@@ -1445,7 +1027,7 @@ static HRESULT WINAPI DefaultHandler_SetData(
 /************************************************************************
  * DefaultHandler_EnumFormatEtc (IDataObject)
  *
- * The default handler's implementation of this method simply delegates
+ * The default handler's implementation of This method simply delegates
  * to OleRegEnumFormatEtc.
  *
  * See Windows documentation for more details on IDataObject methods.
@@ -1456,11 +1038,11 @@ static HRESULT WINAPI DefaultHandler_EnumFormatEtc(
            IEnumFORMATETC** ppenumFormatEtc)
 {
   HRESULT hres;
-  DefaultHandler *this = impl_from_IDataObject(iface);
+  DefaultHandler *This = impl_from_IDataObject(iface);
 
   TRACE("(%p, %lx, %p)\n", iface, dwDirection, ppenumFormatEtc);
 
-  hres = OleRegEnumFormatEtc(&(this->clsid), dwDirection, ppenumFormatEtc);
+  hres = OleRegEnumFormatEtc(&This->clsid, dwDirection, ppenumFormatEtc);
 
   return hres;
 }
@@ -1481,28 +1063,22 @@ static HRESULT WINAPI DefaultHandler_DAdvise(
            DWORD*           pdwConnection)
 {
   HRESULT hres = S_OK;
-  DefaultHandler *this = impl_from_IDataObject(iface);
+  DefaultHandler *This = impl_from_IDataObject(iface);
 
   TRACE("(%p, %p, %ld, %p, %p)\n",
        iface, pformatetc, advf, pAdvSink, pdwConnection);
 
-  /*
-   * Make sure we have a data advise holder before we start.
-   */
-  if (this->dataAdviseHolder==NULL)
-  {
-    hres = CreateDataAdviseHolder(&this->dataAdviseHolder);
-  }
+  /* Make sure we have a data advise holder before we start. */
+  if (!This->dataAdviseHolder)
+    hres = CreateDataAdviseHolder(&This->dataAdviseHolder);
 
   if (SUCCEEDED(hres))
-  {
-    hres = IDataAdviseHolder_Advise(this->dataAdviseHolder,
+    hres = IDataAdviseHolder_Advise(This->dataAdviseHolder,
                                    iface,
                                    pformatetc,
                                    advf,
                                    pAdvSink,
                                    pdwConnection);
-  }
 
   return hres;
 }
@@ -1519,7 +1095,7 @@ static HRESULT WINAPI DefaultHandler_DUnadvise(
            IDataObject*     iface,
            DWORD            dwConnection)
 {
-  DefaultHandler *this = impl_from_IDataObject(iface);
+  DefaultHandler *This = impl_from_IDataObject(iface);
 
   TRACE("(%p, %ld)\n", iface, dwConnection);
 
@@ -1527,12 +1103,10 @@ static HRESULT WINAPI DefaultHandler_DUnadvise(
    * If we don't have a data advise holder yet, it means that
    * we don't have any connections..
    */
-  if (this->dataAdviseHolder==NULL)
-  {
+  if (!This->dataAdviseHolder)
     return OLE_E_NOCONNECTION;
-  }
 
-  return IDataAdviseHolder_Unadvise(this->dataAdviseHolder,
+  return IDataAdviseHolder_Unadvise(This->dataAdviseHolder,
                                    dwConnection);
 }
 
@@ -1548,29 +1122,20 @@ static HRESULT WINAPI DefaultHandler_EnumDAdvise(
            IDataObject*     iface,
            IEnumSTATDATA**  ppenumAdvise)
 {
-  DefaultHandler *this = impl_from_IDataObject(iface);
+  DefaultHandler *This = impl_from_IDataObject(iface);
 
   TRACE("(%p, %p)\n", iface, ppenumAdvise);
 
-  /*
-   * Sanity check
-   */
-  if (ppenumAdvise == NULL)
+  /* Sanity check */
+  if (!ppenumAdvise)
     return E_POINTER;
 
-  /*
-   * Initialize the out parameter.
-   */
   *ppenumAdvise = NULL;
 
-  /*
-   * If we have a data advise holder object, delegate.
-   */
-  if (this->dataAdviseHolder!=NULL)
-  {
-    return IDataAdviseHolder_EnumAdvise(this->dataAdviseHolder,
+  /* If we have a data advise holder object, delegate. */
+  if (This->dataAdviseHolder)
+    return IDataAdviseHolder_EnumAdvise(This->dataAdviseHolder,
                                        ppenumAdvise);
-  }
 
   return S_OK;
 }
@@ -1590,9 +1155,9 @@ static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
             REFIID               riid,
             void**               ppvObject)
 {
-  DefaultHandler *this = impl_from_IRunnableObject(iface);
+  DefaultHandler *This = impl_from_IRunnableObject(iface);
 
-  return IUnknown_QueryInterface(this->outerUnknown, riid, ppvObject);
+  return IUnknown_QueryInterface(This->outerUnknown, riid, ppvObject);
 }
 
 /************************************************************************
@@ -1603,9 +1168,9 @@ static HRESULT WINAPI DefaultHandler_IRunnableObject_QueryInterface(
 static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
             IRunnableObject*     iface)
 {
-  DefaultHandler *this = impl_from_IRunnableObject(iface);
+  DefaultHandler *This = impl_from_IRunnableObject(iface);
 
-  return IUnknown_AddRef(this->outerUnknown);
+  return IUnknown_AddRef(This->outerUnknown);
 }
 
 /************************************************************************
@@ -1616,25 +1181,21 @@ static ULONG WINAPI DefaultHandler_IRunnableObject_AddRef(
 static ULONG WINAPI DefaultHandler_IRunnableObject_Release(
             IRunnableObject*     iface)
 {
-  DefaultHandler *this = impl_from_IRunnableObject(iface);
+  DefaultHandler *This = impl_from_IRunnableObject(iface);
 
-  return IUnknown_Release(this->outerUnknown);
+  return IUnknown_Release(This->outerUnknown);
 }
 
 /************************************************************************
  * DefaultHandler_GetRunningClass (IRunnableObject)
  *
- * According to Brockscmidt, Chapter 19, the default handler's
- * implementation of IRunnableobject does nothing until the object
- * is actually running.
- *
  * See Windows documentation for more details on IRunnableObject methods.
  */
 static HRESULT WINAPI DefaultHandler_GetRunningClass(
             IRunnableObject*     iface,
            LPCLSID              lpClsid)
 {
-  TRACE("()\n");
+  FIXME("()\n");
   return S_OK;
 }
 
@@ -1642,33 +1203,66 @@ static HRESULT WINAPI DefaultHandler_Run(
             IRunnableObject*     iface,
            IBindCtx*            pbc)
 {
-  FIXME(": Stub\n");
-  return E_NOTIMPL;
+  DefaultHandler *This = impl_from_IRunnableObject(iface);
+  HRESULT hr;
+
+  FIXME("(%p): semi-stub\n", pbc);
+
+  /* already running? if so nothing to do */
+  if (This->pOleDelegate)
+    return S_OK;
+
+  hr = CoCreateInstance(&This->clsid, NULL, CLSCTX_LOCAL_SERVER, &IID_IOleObject, (void **)&This->pOleDelegate);
+  if (FAILED(hr))
+    return hr;
+
+  hr = IOleObject_Advise(This->pOleDelegate, (IAdviseSink *)&This->lpvtblIAdviseSink, &This->dwAdvConn);
+
+  if (SUCCEEDED(hr) && This->clientSite)
+    hr = IOleObject_SetClientSite(This->pOleDelegate, This->clientSite);
+
+  if (SUCCEEDED(hr))
+  {
+    IOleObject_QueryInterface(This->pOleDelegate, &IID_IPersistStorage, (void **)&This->pPSDelegate);
+    if (This->pPSDelegate)
+      hr = IPersistStorage_InitNew(This->pPSDelegate, NULL);
+  }
+
+  if (SUCCEEDED(hr) && This->containerApp)
+    hr = IOleObject_SetHostNames(This->pOleDelegate, This->containerApp, This->containerObj);
+
+  /* FIXME: do more stuff here:
+   * - IOleObject_GetMiscStatus
+   * - IOleObject_GetMoniker
+   * - IOleCache_OnRun
+   */
+
+  /* FIXME: if we failed, Close the object */
+
+  return hr;
 }
 
 /************************************************************************
  * DefaultHandler_IsRunning (IRunnableObject)
  *
- * According to Brockscmidt, Chapter 19, the default handler's
- * implementation of IRunnableobject does nothing until the object
- * is actually running.
- *
  * See Windows documentation for more details on IRunnableObject methods.
  */
 static BOOL    WINAPI DefaultHandler_IsRunning(
             IRunnableObject*     iface)
 {
+  DefaultHandler *This = impl_from_IRunnableObject(iface);
+
   TRACE("()\n");
-  return S_FALSE;
+
+  if (This->pOleDelegate)
+    return TRUE;
+  else
+    return FALSE;
 }
 
 /************************************************************************
  * DefaultHandler_LockRunning (IRunnableObject)
  *
- * According to Brockscmidt, Chapter 19, the default handler's
- * implementation of IRunnableobject does nothing until the object
- * is actually running.
- *
  * See Windows documentation for more details on IRunnableObject methods.
  */
 static HRESULT WINAPI DefaultHandler_LockRunning(
@@ -1676,23 +1270,345 @@ static HRESULT WINAPI DefaultHandler_LockRunning(
            BOOL                 fLock,
            BOOL                 fLastUnlockCloses)
 {
-  TRACE("()\n");
+  FIXME("()\n");
   return S_OK;
 }
 
 /************************************************************************
  * DefaultHandler_SetContainedObject (IRunnableObject)
  *
- * According to Brockscmidt, Chapter 19, the default handler's
- * implementation of IRunnableobject does nothing until the object
- * is actually running.
- *
  * See Windows documentation for more details on IRunnableObject methods.
  */
 static HRESULT WINAPI DefaultHandler_SetContainedObject(
             IRunnableObject*     iface,
            BOOL                 fContained)
 {
-  TRACE("()\n");
+  FIXME("()\n");
   return S_OK;
 }
+
+static HRESULT WINAPI DefaultHandler_IAdviseSink_QueryInterface(
+    IAdviseSink *iface,
+    REFIID riid,
+    void **ppvObject)
+{
+    if (IsEqualIID(riid, &IID_IUnknown) ||
+        IsEqualIID(riid, &IID_IAdviseSink))
+    {
+        *ppvObject = iface;
+        IAdviseSink_AddRef(iface);
+        return S_OK;
+    }
+
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI DefaultHandler_IAdviseSink_AddRef(
+    IAdviseSink *iface)
+{
+    DefaultHandler *This = impl_from_IAdviseSink(iface);
+
+    return IUnknown_AddRef((IUnknown *)&This->lpvtblIUnknown);
+}
+
+static ULONG WINAPI DefaultHandler_IAdviseSink_Release(
+            IAdviseSink *iface)
+{
+    DefaultHandler *This = impl_from_IAdviseSink(iface);
+
+    return IUnknown_Release((IUnknown *)&This->lpvtblIUnknown);
+}
+
+static void WINAPI DefaultHandler_IAdviseSink_OnDataChange(
+    IAdviseSink *iface,
+    FORMATETC *pFormatetc,
+    STGMEDIUM *pStgmed)
+{
+    FIXME(": stub\n");
+}
+
+static void WINAPI DefaultHandler_IAdviseSink_OnViewChange(
+    IAdviseSink *iface,
+    DWORD dwAspect,
+    LONG lindex)
+{
+    FIXME(": stub\n");
+}
+
+static void WINAPI DefaultHandler_IAdviseSink_OnRename(
+    IAdviseSink *iface,
+    IMoniker *pmk)
+{
+    DefaultHandler *This = impl_from_IAdviseSink(iface);
+
+    TRACE("(%p)\n", pmk);
+
+    if (This->oleAdviseHolder)
+        IOleAdviseHolder_SendOnRename(This->oleAdviseHolder, pmk);
+}
+
+static void WINAPI DefaultHandler_IAdviseSink_OnSave(
+    IAdviseSink *iface)
+{
+    DefaultHandler *This = impl_from_IAdviseSink(iface);
+
+    TRACE("()\n");
+
+    if (This->oleAdviseHolder)
+        IOleAdviseHolder_SendOnSave(This->oleAdviseHolder);
+}
+
+static void WINAPI DefaultHandler_IAdviseSink_OnClose(
+    IAdviseSink *iface)
+{
+    DefaultHandler *This = impl_from_IAdviseSink(iface);
+    
+    TRACE("()\n");
+
+    if (This->oleAdviseHolder)
+        IOleAdviseHolder_SendOnClose(This->oleAdviseHolder);
+
+    DefaultHandler_Stop(This);
+}
+
+/*
+ * Virtual function tables for the DefaultHandler class.
+ */
+static const IOleObjectVtbl DefaultHandler_IOleObject_VTable =
+{
+  DefaultHandler_QueryInterface,
+  DefaultHandler_AddRef,
+  DefaultHandler_Release,
+  DefaultHandler_SetClientSite,
+  DefaultHandler_GetClientSite,
+  DefaultHandler_SetHostNames,
+  DefaultHandler_Close,
+  DefaultHandler_SetMoniker,
+  DefaultHandler_GetMoniker,
+  DefaultHandler_InitFromData,
+  DefaultHandler_GetClipboardData,
+  DefaultHandler_DoVerb,
+  DefaultHandler_EnumVerbs,
+  DefaultHandler_Update,
+  DefaultHandler_IsUpToDate,
+  DefaultHandler_GetUserClassID,
+  DefaultHandler_GetUserType,
+  DefaultHandler_SetExtent,
+  DefaultHandler_GetExtent,
+  DefaultHandler_Advise,
+  DefaultHandler_Unadvise,
+  DefaultHandler_EnumAdvise,
+  DefaultHandler_GetMiscStatus,
+  DefaultHandler_SetColorScheme
+};
+
+static const IUnknownVtbl DefaultHandler_NDIUnknown_VTable =
+{
+  DefaultHandler_NDIUnknown_QueryInterface,
+  DefaultHandler_NDIUnknown_AddRef,
+  DefaultHandler_NDIUnknown_Release,
+};
+
+static const IDataObjectVtbl DefaultHandler_IDataObject_VTable =
+{
+  DefaultHandler_IDataObject_QueryInterface,
+  DefaultHandler_IDataObject_AddRef,
+  DefaultHandler_IDataObject_Release,
+  DefaultHandler_GetData,
+  DefaultHandler_GetDataHere,
+  DefaultHandler_QueryGetData,
+  DefaultHandler_GetCanonicalFormatEtc,
+  DefaultHandler_SetData,
+  DefaultHandler_EnumFormatEtc,
+  DefaultHandler_DAdvise,
+  DefaultHandler_DUnadvise,
+  DefaultHandler_EnumDAdvise
+};
+
+static const IRunnableObjectVtbl DefaultHandler_IRunnableObject_VTable =
+{
+  DefaultHandler_IRunnableObject_QueryInterface,
+  DefaultHandler_IRunnableObject_AddRef,
+  DefaultHandler_IRunnableObject_Release,
+  DefaultHandler_GetRunningClass,
+  DefaultHandler_Run,
+  DefaultHandler_IsRunning,
+  DefaultHandler_LockRunning,
+  DefaultHandler_SetContainedObject
+};
+
+static const IAdviseSinkVtbl DefaultHandler_IAdviseSink_VTable =
+{
+  DefaultHandler_IAdviseSink_QueryInterface,
+  DefaultHandler_IAdviseSink_AddRef,
+  DefaultHandler_IAdviseSink_Release,
+  DefaultHandler_IAdviseSink_OnDataChange,
+  DefaultHandler_IAdviseSink_OnViewChange,
+  DefaultHandler_IAdviseSink_OnRename,
+  DefaultHandler_IAdviseSink_OnSave,
+  DefaultHandler_IAdviseSink_OnClose
+};
+
+/*********************************************************
+ * Methods implementation for the DefaultHandler class.
+ */
+static DefaultHandler* DefaultHandler_Construct(
+  REFCLSID  clsid,
+  LPUNKNOWN pUnkOuter)
+{
+  DefaultHandler* This = NULL;
+
+  /*
+   * Allocate space for the object.
+   */
+  This = HeapAlloc(GetProcessHeap(), 0, sizeof(DefaultHandler));
+
+  if (!This)
+    return This;
+
+  This->lpVtbl = &DefaultHandler_IOleObject_VTable;
+  This->lpvtblIUnknown = &DefaultHandler_NDIUnknown_VTable;
+  This->lpvtblIDataObject = &DefaultHandler_IDataObject_VTable;
+  This->lpvtblIRunnableObject = &DefaultHandler_IRunnableObject_VTable;
+  This->lpvtblIAdviseSink = &DefaultHandler_IAdviseSink_VTable;
+
+  /*
+   * Start with one reference count. The caller of this function
+   * must release the interface pointer when it is done.
+   */
+  This->ref = 1;
+
+  /*
+   * Initialize the outer unknown
+   * We don't keep a reference on the outer unknown since, the way
+   * aggregation works, our lifetime is at least as large as it's
+   * lifetime.
+   */
+  if (!pUnkOuter)
+    pUnkOuter = (IUnknown*)&This->lpvtblIUnknown;
+
+  This->outerUnknown = pUnkOuter;
+
+  /*
+   * Create a datacache object.
+   * We aggregate with the datacache. Make sure we pass our outer
+   * unknown as the datacache's outer unknown.
+   */
+  CreateDataCache(This->outerUnknown,
+                 clsid,
+                 &IID_IUnknown,
+                 (void**)&This->dataCache);
+
+  /*
+   * Initialize the other data members of the class.
+   */
+  memcpy(&This->clsid, clsid, sizeof(CLSID));
+  This->clientSite = NULL;
+  This->oleAdviseHolder = NULL;
+  This->dataAdviseHolder = NULL;
+  This->containerApp = NULL;
+  This->containerObj = NULL;
+  This->pOleDelegate = NULL;
+  This->pPSDelegate = NULL;
+
+  This->dwAdvConn = 0;
+
+  return This;
+}
+
+static void DefaultHandler_Destroy(
+  DefaultHandler* This)
+{
+  /* release delegates */
+  DefaultHandler_Stop(This);
+
+  /* Free the strings idenfitying the object */
+  HeapFree( GetProcessHeap(), 0, This->containerApp );
+  This->containerApp = NULL;
+  HeapFree( GetProcessHeap(), 0, This->containerObj );
+  This->containerObj = NULL;
+
+  /* Release our reference to the data cache. */
+  if (This->dataCache)
+  {
+    IUnknown_Release(This->dataCache);
+    This->dataCache = NULL;
+  }
+
+  /* Same thing for the client site. */
+  if (This->clientSite)
+  {
+    IOleClientSite_Release(This->clientSite);
+    This->clientSite = NULL;
+  }
+
+  /* And the advise holder. */
+  if (This->oleAdviseHolder)
+  {
+    IOleAdviseHolder_Release(This->oleAdviseHolder);
+    This->oleAdviseHolder = NULL;
+  }
+
+  /* And the data advise holder. */
+  if (This->dataAdviseHolder)
+  {
+    IDataAdviseHolder_Release(This->dataAdviseHolder);
+    This->dataAdviseHolder = NULL;
+  }
+
+  /* Free the actual default handler structure. */
+  HeapFree(GetProcessHeap(), 0, This);
+}
+
+/******************************************************************************
+ * OleCreateDefaultHandler [OLE32.@]
+ */
+HRESULT WINAPI OleCreateDefaultHandler(
+  REFCLSID  clsid,
+  LPUNKNOWN pUnkOuter,
+  REFIID    riid,
+  LPVOID*   ppvObj)
+{
+  DefaultHandler* newHandler = NULL;
+  HRESULT         hr         = S_OK;
+
+  TRACE("(%s, %p, %s, %p)\n", debugstr_guid(clsid), pUnkOuter, debugstr_guid(riid), ppvObj);
+
+  /*
+   * Sanity check
+   */
+  if (!ppvObj)
+    return E_POINTER;
+
+  *ppvObj = NULL;
+
+  /*
+   * If This handler is constructed for aggregation, make sure
+   * the caller is requesting the IUnknown interface.
+   * This is necessary because it's the only time the non-delegating
+   * IUnknown pointer can be returned to the outside.
+   */
+  if (pUnkOuter && !IsEqualIID(&IID_IUnknown, riid))
+    return CLASS_E_NOAGGREGATION;
+
+  /*
+   * Try to construct a new instance of the class.
+   */
+  newHandler = DefaultHandler_Construct(clsid, pUnkOuter);
+
+  if (!newHandler)
+    return E_OUTOFMEMORY;
+
+  /*
+   * Make sure it supports the interface required by the caller.
+   */
+  hr = IUnknown_QueryInterface((IUnknown*)&newHandler->lpvtblIUnknown, riid, ppvObj);
+
+  /*
+   * Release the reference obtained in the constructor. If
+   * the QueryInterface was unsuccessful, it will free the class.
+   */
+  IUnknown_Release((IUnknown*)&newHandler->lpvtblIUnknown);
+
+  return hr;
+}
index fbeed04..730f0d8 100644 (file)
@@ -171,7 +171,7 @@ static inline ErrorInfoImpl *impl_from_ISupportErrorInfo( ISupportErrorInfo *ifa
 #define _ICreateErrorInfo_(This)       (ICreateErrorInfo*)&(This->lpvtcei)
 #define _ISupportErrorInfo_(This)      (ISupportErrorInfo*)&(This->lpvtsei)
 
-IErrorInfo * IErrorInfoImpl_Constructor()
+IErrorInfo * IErrorInfoImpl_Constructor(void)
 {
        ErrorInfoImpl * ei = HeapAlloc(GetProcessHeap(), 0, sizeof(ErrorInfoImpl));
        if (ei)
index f51714c..cdf763a 100644 (file)
@@ -88,7 +88,7 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
 {
     0, 0, &git_section,
     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
-      0, 0, { 0, (DWORD)(__FILE__ ": global interface table") }
+      0, 0, { (DWORD_PTR)(__FILE__ ": global interface table") }
 };
 static CRITICAL_SECTION git_section = { &critsect_debug, -1, 0, 0, 0, 0 };
 
index 5c087f3..0696139 100644 (file)
@@ -68,7 +68,7 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
 {
     0, 0, &IMalloc32_SpyCS,
     { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
-      0, 0, { 0, (DWORD)(__FILE__ ": IMalloc32_SpyCS") }
+      0, 0, { (DWORD_PTR)(__FILE__ ": IMalloc32_SpyCS") }
 };
 static CRITICAL_SECTION IMalloc32_SpyCS = { &critsect_debug, -1, 0, 0, 0, 0 };
 
index 7276327..6b4679d 100644 (file)
@@ -84,7 +84,7 @@ inline static HRESULT get_facbuf_for_iid(REFIID riid, IPSFactoryBuffer **facbuf)
         &IID_IPSFactoryBuffer, (LPVOID*)facbuf);
 }
 
-/* creates a new stub manager */
+/* marshals an object into a STDOBJREF structure */
 HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnknown *object, MSHLFLAGS mshlflags)
 {
     struct stub_manager *manager;
@@ -135,15 +135,13 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
     else
         stdobjref->flags = SORF_NULL;
 
-    /* FIXME: what happens if we register an interface twice with different
-     * marshaling flags? */
     if ((manager = get_stub_manager_from_object(apt, object)))
         TRACE("registering new ifstub on pre-existing manager\n");
     else
     {
         TRACE("constructing new stub manager\n");
 
-        manager = new_stub_manager(apt, object, mshlflags);
+        manager = new_stub_manager(apt, object);
         if (!manager)
         {
             if (stub) IRpcStubBuffer_Release(stub);
@@ -155,15 +153,20 @@ HRESULT marshal_object(APARTMENT *apt, STDOBJREF *stdobjref, REFIID riid, IUnkno
 
     tablemarshal = ((mshlflags & MSHLFLAGS_TABLESTRONG) || (mshlflags & MSHLFLAGS_TABLEWEAK));
 
-    ifstub = stub_manager_new_ifstub(manager, stub, iobject, riid);
-    IUnknown_Release(iobject);
-    if (stub) IRpcStubBuffer_Release(stub);
+    /* make sure ifstub that we are creating is unique */
+    ifstub = stub_manager_find_ifstub(manager, riid, mshlflags);
     if (!ifstub)
     {
-        stub_manager_int_release(manager);
-        /* FIXME: should we do another release to completely destroy the
-         * stub manager? */
-        return E_OUTOFMEMORY;
+        ifstub = stub_manager_new_ifstub(manager, stub, iobject, riid, mshlflags);
+        IUnknown_Release(iobject);
+        if (stub) IRpcStubBuffer_Release(stub);
+        if (!ifstub)
+        {
+            stub_manager_int_release(manager);
+            /* FIXME: should we do another release to completely destroy the
+             * stub manager? */
+            return E_OUTOFMEMORY;
+        }
     }
 
     if (!tablemarshal)
@@ -625,6 +628,7 @@ static HRESULT proxy_manager_create_ifproxy(
     if (IsEqualIID(riid, &IID_IUnknown))
     {
         ifproxy->iface = (void *)&This->lpVtbl;
+        IMultiQI_AddRef((IMultiQI *)&This->lpVtbl);
         hr = S_OK;
     }
     else
@@ -699,18 +703,19 @@ static void proxy_manager_disconnect(struct proxy_manager * This)
     TRACE("oxid = %s, oid = %s\n", wine_dbgstr_longlong(This->oxid),
         wine_dbgstr_longlong(This->oid));
 
+    EnterCriticalSection(&This->cs);
+
     /* SORFP_NOLIFTIMEMGMT proxies (for IRemUnknown) shouldn't be
      * disconnected - it won't do anything anyway, except cause
      * problems for other objects that depend on this proxy always
      * working */
-    if (This->sorflags & SORFP_NOLIFETIMEMGMT) return;
-
-    EnterCriticalSection(&This->cs);
-
-    LIST_FOR_EACH(cursor, &This->interfaces)
+    if (!(This->sorflags & SORFP_NOLIFETIMEMGMT))
     {
-        struct ifproxy * ifproxy = LIST_ENTRY(cursor, struct ifproxy, entry);
-        ifproxy_disconnect(ifproxy);
+        LIST_FOR_EACH(cursor, &This->interfaces)
+        {
+            struct ifproxy * ifproxy = LIST_ENTRY(cursor, struct ifproxy, entry);
+            ifproxy_disconnect(ifproxy);
+        }
     }
 
     /* apartment is being destroyed so don't keep a pointer around to it */
@@ -983,12 +988,11 @@ static HRESULT unmarshal_object(const STDOBJREF *stdobjref, APARTMENT *apt, REFI
                 hr = proxy_manager_create_ifproxy(proxy_manager, stdobjref,
                                                   riid, chanbuf, &ifproxy);
         }
+        else
+            IUnknown_AddRef((IUnknown *)ifproxy->iface);
 
         if (hr == S_OK)
-        {
-            ClientIdentity_AddRef((IMultiQI*)&proxy_manager->lpVtbl);
             *object = ifproxy->iface;
-        }
     }
 
     /* release our reference to the proxy manager - the client/apartment
@@ -1020,7 +1024,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
 
     /* read STDOBJREF from wire */
     hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
-    if (hres) return hres;
+    if (hres) return STG_E_READFAULT;
 
     hres = apartment_getoxid(apt, &oxid);
     if (hres) return hres;
@@ -1034,7 +1038,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
         hres = IUnknown_QueryInterface(stubmgr->object, riid, ppv);
       
         /* unref the ifstub. FIXME: only do this on success? */
-        if (!stub_manager_is_table_marshaled(stubmgr))
+        if (!stub_manager_is_table_marshaled(stubmgr, &stdobjref.ipid))
             stub_manager_ext_release(stubmgr, stdobjref.cPublicRefs);
 
         stub_manager_int_release(stubmgr);
@@ -1050,7 +1054,7 @@ StdMarshalImpl_UnmarshalInterface(LPMARSHAL iface, IStream *pStm, REFIID riid, v
     {
         if ((stubmgr = get_stub_manager(stub_apt, stdobjref.oid)))
         {
-            if (!stub_manager_notify_unmarshal(stubmgr))
+            if (!stub_manager_notify_unmarshal(stubmgr, &stdobjref.ipid))
                 hres = CO_E_OBJNOTCONNECTED;
 
             stub_manager_int_release(stubmgr);
@@ -1090,7 +1094,7 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
     TRACE("iface=%p, pStm=%p\n", iface, pStm);
     
     hres = IStream_Read(pStm, &stdobjref, sizeof(stdobjref), &res);
-    if (hres) return hres;
+    if (hres) return STG_E_READFAULT;
 
     TRACE("oxid = %s, oid = %s, ipid = %s\n",
         wine_dbgstr_longlong(stdobjref.oxid),
@@ -1106,12 +1110,12 @@ StdMarshalImpl_ReleaseMarshalData(LPMARSHAL iface, IStream *pStm)
 
     if (!(stubmgr = get_stub_manager(apt, stdobjref.oid)))
     {
-        ERR("could not map MID to stub manager, oxid=%s, oid=%s\n",
+        ERR("could not map object ID to stub manager, oxid=%s, oid=%s\n",
             wine_dbgstr_longlong(stdobjref.oxid), wine_dbgstr_longlong(stdobjref.oid));
         return RPC_E_INVALID_OBJREF;
     }
 
-    stub_manager_release_marshal_data(stubmgr, stdobjref.cPublicRefs);
+    stub_manager_release_marshal_data(stubmgr, stdobjref.cPublicRefs, &stdobjref.ipid);
 
     stub_manager_int_release(stubmgr);
     apartment_release(apt);
@@ -1343,6 +1347,18 @@ HRESULT WINAPI CoGetMarshalSizeMax(ULONG *pulSize, REFIID riid, IUnknown *pUnk,
 }
 
 
+static void dump_MSHLFLAGS(MSHLFLAGS flags)
+{
+    if (flags & MSHLFLAGS_TABLESTRONG)
+        TRACE(" MSHLFLAGS_TABLESTRONG");
+    if (flags & MSHLFLAGS_TABLEWEAK)
+        TRACE(" MSHLFLAGS_TABLEWEAK");
+    if (!(flags & (MSHLFLAGS_TABLESTRONG|MSHLFLAGS_TABLEWEAK)))
+        TRACE(" MSHLFLAGS_NORMAL");
+    if (flags & MSHLFLAGS_NOPING)
+        TRACE(" MSHLFLAGS_NOPING");
+}
+
 /***********************************************************************
  *             CoMarshalInterface      [OLE32.@]
  *
@@ -1384,8 +1400,10 @@ HRESULT WINAPI CoMarshalInterface(IStream *pStream, REFIID riid, IUnknown *pUnk,
     OBJREF objref;
     LPMARSHAL pMarshal;
 
-    TRACE("(%p, %s, %p, %lx, %p, %lx)\n", pStream, debugstr_guid(riid), pUnk,
-        dwDestContext, pvDestContext, mshlFlags);
+    TRACE("(%p, %s, %p, %lx, %p,", pStream, debugstr_guid(riid), pUnk,
+        dwDestContext, pvDestContext);
+    dump_MSHLFLAGS(mshlFlags);
+    TRACE(")\n");
 
     if (pUnk == NULL)
         return E_INVALIDARG;
@@ -1603,13 +1621,20 @@ HRESULT WINAPI CoMarshalInterThreadInterfaceInStream(
 
     TRACE("(%s, %p, %p)\n",debugstr_guid(riid), pUnk, ppStm);
 
-    hres = CreateStreamOnHGlobal(0, TRUE, ppStm);
+    hres = CreateStreamOnHGlobal(NULL, TRUE, ppStm);
     if (FAILED(hres)) return hres;
     hres = CoMarshalInterface(*ppStm, riid, pUnk, MSHCTX_INPROC, NULL, MSHLFLAGS_NORMAL);
 
-    /* FIXME: is this needed? */
-    memset(&seekto,0,sizeof(seekto));
-    IStream_Seek(*ppStm,seekto,SEEK_SET,&xpos);
+    if (SUCCEEDED(hres))
+    {
+        memset(&seekto, 0, sizeof(seekto));
+        IStream_Seek(*ppStm, seekto, SEEK_SET, &xpos);
+    }
+    else
+    {
+        IStream_Release(*ppStm);
+        *ppStm = NULL;
+    }
 
     return hres;
 }
index d2c6598..61078f8 100644 (file)
@@ -500,12 +500,12 @@ HRESULT HGLOBALLockBytesImpl16_Stat(
  * 
  * Creates an ILockBytes interface for a HGLOBAL handle.
  *
- * Params:
+ * PARAMS
  *     hGlobal                 the global handle (16bit)
  *     fDeleteOnRelease        delete handle on release.
  *     ppLkbyt                 pointer to ILockBytes interface.
  *
- * Returns:
+ * RETURNS
  *     Staddard OLE error return codes.
  *
  */
index 216317f..a7425f1 100644 (file)
@@ -641,16 +641,6 @@ RunningObjectTableImpl_EnumRunning(IRunningObjectTable* iface,
     return hr;
 }
 
-/******************************************************************************
- *             GetRunningObjectTable (OLE2.30)
- */
-HRESULT WINAPI
-GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
-{
-    FIXME("(%ld,%p),stub!\n",reserved,pprot);
-    return E_NOTIMPL;
-}
-
 /***********************************************************************
  *           GetRunningObjectTable (OLE32.@)
  */
index 4beb8e6..f7d76f3 100644 (file)
@@ -204,6 +204,9 @@ IMalloc16_Constructor()
 
 /***********************************************************************
  *           CoGetMalloc    [COMPOBJ.4]
+ *
+ * Retrieve the current win16 IMalloc interface.
+ *
  * RETURNS
  *     The current win16 IMalloc
  */
@@ -344,43 +347,45 @@ HRESULT WINAPI StringFromCLSID16(
 
 /******************************************************************************
  * ProgIDFromCLSID [COMPOBJ.62]
+ *
  * Converts a class id into the respective Program ID. (By using a registry lookup)
- * RETURNS S_OK on success
- * riid associated with the progid
+ *
+ * RETURNS
+ *  S_OK on success
+ *  riid associated with the progid
  */
 HRESULT WINAPI ProgIDFromCLSID16(
   REFCLSID clsid, /* [in] class id as found in registry */
   LPOLESTR16 *lplpszProgID/* [out] associated Prog ID */
 ) {
   static const WCHAR wszProgID[] = {'P','r','o','g','I','D',0};
-  HKEY     xhkey;
   HKEY     hkey;
-  HRESULT  ret = S_OK;
+  HRESULT  ret;
+  LONG     len;
+  char    *buffer;
 
-  if (COM_OpenKeyForCLSID(clsid, KEY_READ, &hkey))
-    ret = REGDB_E_CLASSNOTREG;
+  ret = COM_OpenKeyForCLSID(clsid, wszProgID, KEY_READ, &hkey);
+  if (FAILED(ret))
+    return ret;
   
-  if ((ret == S_OK) &&
-      RegOpenKeyW(hkey, wszProgID, &xhkey))
-    ret = REGDB_E_CLASSNOTREG;
+  if (RegQueryValueA(hkey, NULL, NULL, &len))
+    ret = REGDB_E_READREGDB;
 
   if (ret == S_OK)
   {
-    LONG buf2len;
-    char *buf2 = HeapAlloc(GetProcessHeap(), 0, 255);
-    buf2len = 255;
-    if (RegQueryValueA(xhkey, NULL, buf2, &buf2len))
-      ret = REGDB_E_CLASSNOTREG;
+    buffer = HeapAlloc(GetProcessHeap(), 0, len);
+    if (RegQueryValueA(hkey, NULL, buffer, &len))
+      ret = REGDB_E_READREGDB;
 
     if (ret == S_OK)
     {
-      ret = _xmalloc16(buf2len+1, (SEGPTR*)lplpszProgID);
+      ret = _xmalloc16(len, (SEGPTR*)lplpszProgID);
       if (ret == S_OK)
-        strcpy(MapSL((SEGPTR)*lplpszProgID),buf2);
+        strcpy(MapSL((SEGPTR)*lplpszProgID),buffer);
     }
-    HeapFree(GetProcessHeap(), 0, buf2);
+    HeapFree(GetProcessHeap(), 0, buffer);
   }
-  RegCloseKey(xhkey);
+  RegCloseKey(hkey);
   return ret;
 }
 
@@ -517,3 +522,92 @@ SEGPTR WINAPI CoMemAlloc(DWORD size, DWORD dwMemContext, DWORD x) {
                return (SEGPTR)0;
        return segptr;
 }
+
+/******************************************************************************
+ *             CLSIDFromProgID [COMPOBJ.61]
+ *
+ * Converts a program ID into the respective GUID.
+ *
+ * PARAMS
+ *  progid       [I] program id as found in registry
+ *  riid         [O] associated CLSID
+ *
+ * RETURNS
+ *     Success: S_OK
+ *  Failure: CO_E_CLASSSTRING - the given ProgID cannot be found.
+ */
+HRESULT WINAPI CLSIDFromProgID16(LPCOLESTR16 progid, LPCLSID riid)
+{
+       char    *buf,buf2[80];
+       LONG    buf2len;
+       HRESULT err;
+       HKEY    xhkey;
+
+       buf = HeapAlloc(GetProcessHeap(),0,strlen(progid)+8);
+       sprintf(buf,"%s\\CLSID",progid);
+       if ((err=RegOpenKeyA(HKEY_CLASSES_ROOT,buf,&xhkey))) {
+               HeapFree(GetProcessHeap(),0,buf);
+                return CO_E_CLASSSTRING;
+       }
+       HeapFree(GetProcessHeap(),0,buf);
+       buf2len = sizeof(buf2);
+       if ((err=RegQueryValueA(xhkey,NULL,buf2,&buf2len))) {
+               RegCloseKey(xhkey);
+                return CO_E_CLASSSTRING;
+       }
+       RegCloseKey(xhkey);
+       return __CLSIDFromStringA(buf2,riid);
+}
+
+/***********************************************************************
+ *           CoGetClassObject [COMPOBJ.7]
+ *
+ */
+HRESULT WINAPI CoGetClassObject16(
+    REFCLSID rclsid, DWORD dwClsContext, COSERVERINFO *pServerInfo,
+    REFIID iid, LPVOID *ppv)
+{
+    FIXME(", stub!\n\tCLSID:\t%s,\n\tIID:\t%s\n", debugstr_guid(rclsid), debugstr_guid(iid));
+
+    if (pServerInfo) {
+       FIXME("\tpServerInfo: name=%s\n",debugstr_w(pServerInfo->pwszName));
+       FIXME("\t\tpAuthInfo=%p\n",pServerInfo->pAuthInfo);
+    }
+    return E_NOTIMPL;
+}
+
+/***********************************************************************
+ *           CoCreateInstance [COMPOBJ.13]
+ */
+HRESULT WINAPI CoCreateInstance16(
+       REFCLSID rclsid,
+       LPUNKNOWN pUnkOuter,
+       DWORD dwClsContext,
+       REFIID iid,
+       LPVOID *ppv)
+{
+  FIXME("(%s, %p, %lx, %s, %p), stub!\n", 
+       debugstr_guid(rclsid), pUnkOuter, dwClsContext, debugstr_guid(iid),
+       ppv
+  );
+  return E_NOTIMPL;
+}
+
+/***********************************************************************
+ *           DllGetClassObject                          [OLE2.4]
+ */
+HRESULT WINAPI DllGetClassObject16(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
+{
+  FIXME("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
+  return E_NOTIMPL;
+}
+
+/******************************************************************************
+ *             GetRunningObjectTable (OLE2.30)
+ */
+HRESULT WINAPI
+GetRunningObjectTable16(DWORD reserved, LPRUNNINGOBJECTTABLE *pprot)
+{
+    FIXME("(%ld,%p),stub!\n",reserved,pprot);
+    return E_NOTIMPL;
+}
index 6192ef2..4bc815e 100644 (file)
@@ -47,9 +47,6 @@
 #include "wownt32.h"
 
 #include "wine/unicode.h"
-#include "wine/winbase16.h"
-#include "wine/wingdi16.h"
-#include "wine/winuser16.h"
 #include "compobj_private.h"
 
 #include "wine/debug.h"
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
 WINE_DECLARE_DEBUG_CHANNEL(accel);
 
-#define HICON_16(h32)          (LOWORD(h32))
-#define HICON_32(h16)          ((HICON)(ULONG_PTR)(h16))
-#define HINSTANCE_32(h16)      ((HINSTANCE)(ULONG_PTR)(h16))
-
 /******************************************************************************
  * These are static/global variables and internal data structures that the
  * OLE module uses to maintain it's state.
@@ -674,6 +667,258 @@ HRESULT WINAPI OleRegGetMiscStatus(
   return S_OK;
 }
 
+static HRESULT EnumOLEVERB_Construct(HKEY hkeyVerb, ULONG index, IEnumOLEVERB **ppenum);
+
+typedef struct
+{
+    const IEnumOLEVERBVtbl *lpvtbl;
+    LONG ref;
+
+    HKEY hkeyVerb;
+    ULONG index;
+} EnumOLEVERB;
+
+static HRESULT WINAPI EnumOLEVERB_QueryInterface(
+    IEnumOLEVERB *iface, REFIID riid, void **ppv)
+{
+    TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
+    if (IsEqualIID(riid, &IID_IUnknown) ||
+        IsEqualIID(riid, &IID_IEnumOLEVERB))
+    {
+        IUnknown_AddRef(iface);
+        *ppv = iface;
+        return S_OK;
+    }
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI EnumOLEVERB_AddRef(
+    IEnumOLEVERB *iface)
+{
+    EnumOLEVERB *This = (EnumOLEVERB *)iface;
+    TRACE("()\n");
+    return InterlockedIncrement(&This->ref);
+}
+
+static ULONG WINAPI EnumOLEVERB_Release(
+    IEnumOLEVERB *iface)
+{
+    EnumOLEVERB *This = (EnumOLEVERB *)iface;
+    LONG refs = InterlockedDecrement(&This->ref);
+    TRACE("()\n");
+    if (!refs)
+    {
+        RegCloseKey(This->hkeyVerb);
+        HeapFree(GetProcessHeap(), 0, This);
+    }
+    return refs;
+}
+
+static HRESULT WINAPI EnumOLEVERB_Next(
+    IEnumOLEVERB *iface, ULONG celt, LPOLEVERB rgelt,
+    ULONG *pceltFetched)
+{
+    EnumOLEVERB *This = (EnumOLEVERB *)iface;
+    HRESULT hr = S_OK;
+
+    TRACE("(%ld, %p, %p)\n", celt, rgelt, pceltFetched);
+
+    if (pceltFetched)
+        *pceltFetched = 0;
+
+    for (; celt; celt--, rgelt++)
+    {
+        WCHAR wszSubKey[20];
+        LONG cbData;
+        LPWSTR pwszOLEVERB;
+        LPWSTR pwszMenuFlags;
+        LPWSTR pwszAttribs;
+        LONG res = RegEnumKeyW(This->hkeyVerb, This->index, wszSubKey, sizeof(wszSubKey)/sizeof(wszSubKey[0]));
+        if (res == ERROR_NO_MORE_ITEMS)
+        {
+            hr = S_FALSE;
+            break;
+        }
+        else if (res != ERROR_SUCCESS)
+        {
+            ERR("RegEnumKeyW failed with error %ld\n", res);
+            hr = REGDB_E_READREGDB;
+            break;
+        }
+        res = RegQueryValueW(This->hkeyVerb, wszSubKey, NULL, &cbData);
+        if (res != ERROR_SUCCESS)
+        {
+            ERR("RegQueryValueW failed with error %ld\n", res);
+            hr = REGDB_E_READREGDB;
+            break;
+        }
+        pwszOLEVERB = CoTaskMemAlloc(cbData);
+        if (!pwszOLEVERB)
+        {
+            hr = E_OUTOFMEMORY;
+            break;
+        }
+        res = RegQueryValueW(This->hkeyVerb, wszSubKey, pwszOLEVERB, &cbData);
+        if (res != ERROR_SUCCESS)
+        {
+            ERR("RegQueryValueW failed with error %ld\n", res);
+            hr = REGDB_E_READREGDB;
+            CoTaskMemFree(pwszOLEVERB);
+            break;
+        }
+
+        TRACE("verb string: %s\n", debugstr_w(pwszOLEVERB));
+        pwszMenuFlags = strchrW(pwszOLEVERB, ',');
+        if (!pwszMenuFlags)
+        {
+            hr = OLEOBJ_E_INVALIDVERB;
+            CoTaskMemFree(pwszOLEVERB);
+            break;
+        }
+        /* nul terminate the name string and advance to first character */
+        *pwszMenuFlags = '\0';
+        pwszMenuFlags++;
+        pwszAttribs = strchrW(pwszMenuFlags, ',');
+        if (!pwszAttribs)
+        {
+            hr = OLEOBJ_E_INVALIDVERB;
+            CoTaskMemFree(pwszOLEVERB);
+            break;
+        }
+        /* nul terminate the menu string and advance to first character */
+        *pwszAttribs = '\0';
+        pwszAttribs++;
+
+        /* fill out structure for this verb */
+        rgelt->lVerb = atolW(wszSubKey);
+        rgelt->lpszVerbName = pwszOLEVERB; /* user should free */
+        rgelt->fuFlags = atolW(pwszMenuFlags);
+        rgelt->grfAttribs = atolW(pwszAttribs);
+
+        if (pceltFetched)
+            *pceltFetched++;
+        This->index++;
+    }
+    return hr;
+}
+
+static HRESULT WINAPI EnumOLEVERB_Skip(
+    IEnumOLEVERB *iface, ULONG celt)
+{
+    EnumOLEVERB *This = (EnumOLEVERB *)iface;
+
+    TRACE("(%ld)\n", celt);
+
+    This->index += celt;
+    return S_OK;
+}
+
+static HRESULT WINAPI EnumOLEVERB_Reset(
+    IEnumOLEVERB *iface)
+{
+    EnumOLEVERB *This = (EnumOLEVERB *)iface;
+
+    TRACE("()\n");
+
+    This->index = 0;
+    return S_OK;
+}
+
+static HRESULT WINAPI EnumOLEVERB_Clone(
+    IEnumOLEVERB *iface,
+    IEnumOLEVERB **ppenum)
+{
+    EnumOLEVERB *This = (EnumOLEVERB *)iface;
+    HKEY hkeyVerb;
+    TRACE("(%p)\n", ppenum);
+    if (!DuplicateHandle(GetCurrentProcess(), This->hkeyVerb, GetCurrentProcess(), (HANDLE *)&hkeyVerb, 0, FALSE, DUPLICATE_SAME_ACCESS))
+        return HRESULT_FROM_WIN32(GetLastError());
+    return EnumOLEVERB_Construct(hkeyVerb, This->index, ppenum);
+}
+
+static const IEnumOLEVERBVtbl EnumOLEVERB_VTable =
+{
+    EnumOLEVERB_QueryInterface,
+    EnumOLEVERB_AddRef,
+    EnumOLEVERB_Release,
+    EnumOLEVERB_Next,
+    EnumOLEVERB_Skip,
+    EnumOLEVERB_Reset,
+    EnumOLEVERB_Clone
+};
+
+static HRESULT EnumOLEVERB_Construct(HKEY hkeyVerb, ULONG index, IEnumOLEVERB **ppenum)
+{
+    EnumOLEVERB *This = HeapAlloc(GetProcessHeap(), 0, sizeof(*This));
+    if (!This)
+    {
+        RegCloseKey(hkeyVerb);
+        return E_OUTOFMEMORY;
+    }
+    This->lpvtbl = &EnumOLEVERB_VTable;
+    This->ref = 1;
+    This->index = index;
+    This->hkeyVerb = hkeyVerb;
+    *ppenum = (IEnumOLEVERB *)&This->lpvtbl;
+    return S_OK;    
+}
+
+/***********************************************************************
+ *           OleRegEnumVerbs    [OLE32.@]
+ *
+ * Enumerates verbs associated with a class stored in the registry.
+ *
+ * PARAMS
+ *  clsid  [I] Class ID to enumerate the verbs for.
+ *  ppenum [O] Enumerator.
+ *
+ * RETURNS
+ *  S_OK: Success.
+ *  REGDB_E_CLASSNOTREG: The specified class does not have a key in the registry.
+ *  REGDB_E_READREGDB: The class key could not be opened for some other reason.
+ *  OLE_E_REGDB_KEY: The Verb subkey for the class is not present.
+ *  OLEOBJ_E_NOVERBS: The Verb subkey for the class is empty.
+ */
+HRESULT WINAPI OleRegEnumVerbs (REFCLSID clsid, LPENUMOLEVERB* ppenum)
+{
+    LONG res;
+    HKEY hkeyVerb;
+    DWORD dwSubKeys;
+    static const WCHAR wszVerb[] = {'V','e','r','b',0};
+
+    TRACE("(%s, %p)\n", debugstr_guid(clsid), ppenum);
+
+    res = COM_OpenKeyForCLSID(clsid, wszVerb, KEY_READ, &hkeyVerb);
+    if (FAILED(res))
+    {
+        if (res == REGDB_E_CLASSNOTREG)
+            ERR("CLSID %s not registered\n", debugstr_guid(clsid));
+        else if (res == REGDB_E_KEYMISSING)
+            ERR("no Verbs key for class %s\n", debugstr_guid(clsid));
+        else
+            ERR("failed to open Verbs key for CLSID %s with error %ld\n",
+                debugstr_guid(clsid), res);
+        return res;
+    }
+
+    res = RegQueryInfoKeyW(hkeyVerb, NULL, NULL, NULL, &dwSubKeys, NULL,
+                          NULL, NULL, NULL, NULL, NULL, NULL);
+    if (res != ERROR_SUCCESS)
+    {
+        ERR("failed to get subkey count with error %ld\n", GetLastError());
+        return REGDB_E_READREGDB;
+    }
+
+    if (!dwSubKeys)
+    {
+        WARN("class %s has no verbs\n", debugstr_guid(clsid));
+        RegCloseKey(hkeyVerb);
+        return OLEOBJ_E_NOVERBS;
+    }
+
+    return EnumOLEVERB_Construct(hkeyVerb, 0, ppenum);
+}
+
 /******************************************************************************
  *              OleSetContainedObject        [OLE32.@]
  */
@@ -1308,21 +1553,23 @@ HRESULT WINAPI OleDestroyMenuDescriptor(
 
 /***********************************************************************
  * OleSetMenuDescriptor [OLE32.@]
- * Installs or removes OLE dispatching code for the containers frame window
- * FIXME: The lpFrame and lpActiveObject parameters are currently ignored
- * OLE should install context sensitive help F1 filtering for the app when
- * these are non null.
+ * Installs or removes OLE dispatching code for the containers frame window.
  *
- * PARAMS:
+ * PARAMS
  *     hOleMenu         Handle to composite menu descriptor
  *     hwndFrame        Handle to containers frame window
  *     hwndActiveObject Handle to objects in-place activation window
  *     lpFrame          Pointer to IOleInPlaceFrame on containers window
  *     lpActiveObject   Pointer to IOleInPlaceActiveObject on active in-place object
  *
- * RETURNS:
+ * RETURNS
  *      S_OK                               - menu installed correctly
  *      E_FAIL, E_INVALIDARG, E_UNEXPECTED - failure
+ *
+ * FIXME
+ *      The lpFrame and lpActiveObject parameters are currently ignored
+ *      OLE should install context sensitive help F1 filtering for the app when
+ *      these are non null.
  */
 HRESULT WINAPI OleSetMenuDescriptor(
   HOLEMENU               hOleMenu,
@@ -1339,8 +1586,8 @@ HRESULT WINAPI OleSetMenuDescriptor(
 
   if ( lpFrame || lpActiveObject )
   {
-     FIXME("(%x, %p, %p, %p, %p), Context sensitive help filtering not implemented!\n",
-       (unsigned int)hOleMenu,
+     FIXME("(%p, %p, %p, %p, %p), Context sensitive help filtering not implemented!\n",
+       hOleMenu,
        hwndFrame,
        hwndActiveObject,
        lpFrame,
@@ -2286,7 +2533,7 @@ HRESULT WINAPI OleCreate(
 
     *ppvObj = pUnk;
 
-    TRACE("-- %p \n", pUnk);
+    TRACE("-- %p\n", pUnk);
     return hres;
 }
 
@@ -2302,11 +2549,9 @@ HRESULT WINAPI OleSetAutoConvert(REFCLSID clsidOld, REFCLSID clsidNew)
 
     TRACE("(%s,%s)\n", debugstr_guid(clsidOld), debugstr_guid(clsidNew));
     
-    if (COM_OpenKeyForCLSID(clsidOld, KEY_READ | KEY_WRITE, &hkey))
-    {
-        res = REGDB_E_CLASSNOTREG;
-       goto done;
-    }
+    res = COM_OpenKeyForCLSID(clsidOld, NULL, KEY_READ | KEY_WRITE, &hkey);
+    if (FAILED(res))
+        goto done;
     StringFromGUID2(clsidNew, szClsidNew, CHARS_IN_GUID);
     if (RegSetValueW(hkey, wszAutoConvertTo, REG_SZ, szClsidNew, (strlenW(szClsidNew)+1) * sizeof(WCHAR)))
     {
@@ -2329,12 +2574,22 @@ HRESULT WINAPI OleDoAutoConvert(LPSTORAGE pStg, LPCLSID pClsidNew)
 }
 
 /******************************************************************************
- *              OleDoAutoConvert        [OLE2.79]
+ *              OleIsRunning        [OLE32.@]
  */
-HRESULT WINAPI OleDoAutoConvert16(LPSTORAGE pStg, LPCLSID pClsidNew)
+BOOL WINAPI OleIsRunning(LPOLEOBJECT pObject)
 {
-    FIXME("(%p,%p) : stub\n",pStg,pClsidNew);
-    return E_NOTIMPL;
+    IRunnableObject *pRunnable;
+    HRESULT hr;
+    BOOL running;
+
+    TRACE("(%p)\n", pObject);
+
+    hr = IOleObject_QueryInterface(pObject, &IID_IRunnableObject, (void **)&pRunnable);
+    if (FAILED(hr))
+        return FALSE;
+    running = IRunnableObject_IsRunning(pRunnable);
+    IRunnableObject_Release(pRunnable);
+    return running;
 }
 
 /***********************************************************************
index 0c8e732..1c33737 100644 (file)
 500 cdecl HGLOBALLockBytesImpl16_QueryInterface(segptr ptr ptr) HGLOBALLockBytesImpl16_QueryInterface
 501 cdecl HGLOBALLockBytesImpl16_AddRef(ptr) HGLOBALLockBytesImpl16_AddRef
 502 cdecl HGLOBALLockBytesImpl16_Release(ptr) HGLOBALLockBytesImpl16_Release
-503 cdecl HGLOBALLockBytesImpl16_ReadAt(ptr long long ptr long ptr) HGLOBALLockBytesImpl16_ReadAt
-504 cdecl HGLOBALLockBytesImpl16_WriteAt(ptr long long ptr long ptr) HGLOBALLockBytesImpl16_WriteAt
+503 cdecl HGLOBALLockBytesImpl16_ReadAt(ptr double ptr long ptr) HGLOBALLockBytesImpl16_ReadAt
+504 cdecl HGLOBALLockBytesImpl16_WriteAt(ptr double ptr long ptr) HGLOBALLockBytesImpl16_WriteAt
 505 cdecl HGLOBALLockBytesImpl16_Flush(ptr) HGLOBALLockBytesImpl16_Flush
-506 cdecl HGLOBALLockBytesImpl16_SetSize(ptr long long) HGLOBALLockBytesImpl16_SetSize
-507 cdecl HGLOBALLockBytesImpl16_LockRegion(ptr long long long long long) HGLOBALLockBytesImpl16_LockRegion
-508 cdecl HGLOBALLockBytesImpl16_UnlockRegion(ptr long long long long long) HGLOBALLockBytesImpl16_UnlockRegion
+506 cdecl HGLOBALLockBytesImpl16_SetSize(ptr double) HGLOBALLockBytesImpl16_SetSize
+507 cdecl HGLOBALLockBytesImpl16_LockRegion(ptr double double long) HGLOBALLockBytesImpl16_LockRegion
+508 cdecl HGLOBALLockBytesImpl16_UnlockRegion(ptr double double long) HGLOBALLockBytesImpl16_UnlockRegion
 509 cdecl HGLOBALLockBytesImpl16_Stat(ptr ptr long) HGLOBALLockBytesImpl16_Stat
index 7909412..1259900 100644 (file)
@@ -50,7 +50,6 @@
 #include "wine/debug.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(ole);
-WINE_DECLARE_DEBUG_CHANNEL(accel);
 
 #define HICON_16(h32)          (LOWORD(h32))
 #define HICON_32(h16)          ((HICON)(ULONG_PTR)(h16))
@@ -209,3 +208,39 @@ HRESULT WINAPI OleLoad16(
   FIXME("(%lx,%s,%lx,%p), stub!\n", pStg, debugstr_guid(riid), pClientSite, ppvObj);
   return E_NOTIMPL;
 }
+
+/******************************************************************************
+ *              OleDoAutoConvert        [OLE2.79]
+ */
+HRESULT WINAPI OleDoAutoConvert16(LPSTORAGE pStg, LPCLSID pClsidNew)
+{
+    FIXME("(%p,%p) : stub\n",pStg,pClsidNew);
+    return E_NOTIMPL;
+}
+
+/***********************************************************************
+ *           OleSetClipboard                            [OLE2.49]
+ */
+HRESULT WINAPI OleSetClipboard16(IDataObject* pDataObj)
+{
+  FIXME("(%p): stub\n", pDataObj);
+  return S_OK;
+}
+
+/***********************************************************************
+ *           OleGetClipboard                            [OLE2.50]
+ */
+HRESULT WINAPI OleGetClipboard16(IDataObject** ppDataObj)
+{
+  FIXME("(%p): stub\n", ppDataObj);
+  return E_NOTIMPL;
+}
+
+/***********************************************************************
+ *           OleFlushClipboard   [OLE2.76]
+ */
+
+HRESULT WINAPI OleFlushClipboard16(void)
+{
+  return OleFlushClipboard();
+}
index 82dff4b..c30807e 100644 (file)
@@ -98,8 +98,8 @@ LANGID WINAPI GetSystemDefaultLangID16(void)
 /******************************************************************************
  *             LCMapStringA    [OLE2NLS.6]
  */
-INT16 LCMapString16(LCID lcid, DWORD mapflags, LPCSTR srcstr, INT16 srclen,
-                   LPSTR dststr, INT16 dstlen)
+INT16 WINAPI LCMapString16(LCID lcid, DWORD mapflags, LPCSTR srcstr, INT16 srclen,
+                          LPSTR dststr, INT16 dstlen)
 {
     return LCMapStringA(lcid, mapflags, srcstr, srclen, dststr, dstlen);
 }
@@ -133,4 +133,3 @@ BOOL16 WINAPI RegisterNLSInfoChanged16(LPVOID lpNewNLSInfo) /* [???] FIXME */
 
        return FALSE; /* ptr not set */
 }
-
index 44970be..9eca37a 100644 (file)
@@ -107,24 +107,6 @@ HRESULT WINAPI  OleCreateLinkFromData(LPDATAOBJECT pSrcDataObj, REFIID riid,
   return E_NOTIMPL;
 }
 
-/******************************************************************************
- *              OleIsRunning        [OLE32.@]
- */
-BOOL WINAPI OleIsRunning(LPOLEOBJECT pObject)
-{
-  FIXME("(%p), stub!\n", pObject);
-  return TRUE;
-}
-
-/***********************************************************************
- *           OleRegEnumVerbs    [OLE32.@]
- */
-HRESULT WINAPI OleRegEnumVerbs (REFCLSID clsid, LPENUMOLEVERB* ppenum)
-{
-    FIXME("(%p,%p), stub!\n", clsid, ppenum);
-    return OLEOBJ_E_NOVERBS;
-}
-
 /***********************************************************************
  *           OleRegEnumFormatEtc    [OLE32.@]
  */
@@ -137,30 +119,3 @@ HRESULT     WINAPI OleRegEnumFormatEtc (
 
     return E_NOTIMPL;
 }
-
-/***********************************************************************
- *           DllGetClassObject                          [OLE2.4]
- */
-HRESULT WINAPI DllGetClassObject16(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
-{
-  FIXME("(%s, %s, %p): stub\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
-  return E_NOTIMPL;
-}
-
-/***********************************************************************
- *           OleSetClipboard                            [OLE2.49]
- */
-HRESULT WINAPI OleSetClipboard16(IDataObject* pDataObj)
-{
-  FIXME("(%p): stub\n", pDataObj);
-  return S_OK;
-}
-
-/***********************************************************************
- *           OleGetClipboard                            [OLE2.50]
- */
-HRESULT WINAPI OleGetClipboard16(IDataObject** ppDataObj)
-{
-  FIXME("(%p): stub\n", ppDataObj);
-  return E_NOTIMPL;
-}
index b7c2319..095876b 100644 (file)
@@ -302,9 +302,8 @@ static ULONG WINAPI IRpcProxyBufferImpl_Release(LPRPCPROXYBUFFER iface) {
     ULONG ref = InterlockedDecrement(&This->ref);
 
     if (!ref) {
-       IRpcChannelBuffer_Release(This->chanbuf);
-       This->chanbuf = NULL;
-       HeapFree(GetProcessHeap(),0,This);
+        IRpcProxyBuffer_Disconnect(iface);
+        HeapFree(GetProcessHeap(),0,This);
     }
     return ref;
 }
@@ -452,11 +451,13 @@ CFProxy_Construct(IUnknown *pUnkOuter, LPVOID *ppv,LPVOID *ppProxy) {
 
     cf->lpvtbl_cf      = &cfproxyvt;
     cf->lpvtbl_proxy   = &pspbvtbl;
-    /* only one reference for the proxy buffer */
+    /* one reference for the proxy buffer */
     cf->ref            = 1;
     cf->outer_unknown = pUnkOuter;
     *ppv               = &(cf->lpvtbl_cf);
     *ppProxy           = &(cf->lpvtbl_proxy);
+    /* and one reference for the object */
+    IUnknown_AddRef((IUnknown *)*ppv);
     return S_OK;
 }
 
@@ -698,9 +699,15 @@ static HRESULT WINAPI RemUnkProxy_QueryInterface(LPREMUNKNOWN iface, REFIID riid
 static ULONG WINAPI RemUnkProxy_AddRef(LPREMUNKNOWN iface)
 {
   RemUnkProxy *This = (RemUnkProxy *)iface;
+  ULONG refs;
 
   TRACE("(%p)->AddRef()\n",This);
-  return InterlockedIncrement(&This->refs);
+
+  if (This->outer_unknown)
+      refs = IUnknown_AddRef(This->outer_unknown);
+  else
+      refs = InterlockedIncrement(&This->refs);
+  return refs;
 }
 
 static ULONG WINAPI RemUnkProxy_Release(LPREMUNKNOWN iface)
@@ -871,8 +878,8 @@ static ULONG WINAPI RURpcProxyBufferImpl_Release(LPRPCPROXYBUFFER iface) {
     ULONG ref = InterlockedDecrement(&This->refs);
     TRACE("%p, %ld\n", iface, ref);
     if (!ref) {
-       IRpcChannelBuffer_Release(This->chan);This->chan = NULL;
-       HeapFree(GetProcessHeap(),0,This);
+        IRpcProxyBuffer_Disconnect(iface);
+        HeapFree(GetProcessHeap(),0,This);
     }
     return ref;
 }
@@ -918,6 +925,8 @@ RemUnkProxy_Construct(IUnknown *pUnkOuter, LPVOID *ppv,LPVOID *ppProxy) {
     This->outer_unknown = pUnkOuter;
     *ppv               = &(This->lpvtbl_remunk);
     *ppProxy           = &(This->lpvtbl_proxy);
+    /* and one reference for the object */
+    IUnknown_AddRef((IUnknown *)*ppv);
     return S_OK;
 }
 
index a867a9b..b50c594 100644 (file)
@@ -42,7 +42,9 @@
 #include "winerror.h"
 #include "winreg.h"
 #include "wtypes.h"
+#include "excpt.h"
 #include "wine/unicode.h"
+#include "wine/exception.h"
 
 #include "compobj_private.h"
 
@@ -63,7 +65,7 @@ static CRITICAL_SECTION_DEBUG csRegIf_debug =
 {
     0, 0, &csRegIf,
     { &csRegIf_debug.ProcessLocksList, &csRegIf_debug.ProcessLocksList },
-      0, 0, { 0, (DWORD)(__FILE__ ": dcom registered server interfaces") }
+      0, 0, { (DWORD_PTR)(__FILE__ ": dcom registered server interfaces") }
 };
 static CRITICAL_SECTION csRegIf = { &csRegIf_debug, -1, 0, 0, 0, 0 };
 
@@ -105,8 +107,17 @@ struct dispatch_params
     IRpcChannelBuffer *chan; /* server channel buffer, if applicable */
     HANDLE             handle; /* handle that will become signaled when call finishes */
     RPC_STATUS         status; /* status (out) */
+    HRESULT            hr; /* hresult (out) */
 };
 
+static WINE_EXCEPTION_FILTER(ole_filter)
+{
+    if (GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION ||
+        GetExceptionCode() == EXCEPTION_PRIV_INSTRUCTION)
+        return EXCEPTION_CONTINUE_SEARCH;
+    return EXCEPTION_EXECUTE_HANDLER;
+}
+
 static HRESULT WINAPI RpcChannelBuffer_QueryInterface(LPRPCCHANNELBUFFER iface, REFIID riid, LPVOID *ppv)
 {
     *ppv = NULL;
@@ -228,6 +239,7 @@ static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPC
     
     params->msg = olemsg;
     params->status = RPC_S_OK;
+    params->hr = S_OK;
 
     /* Note: this is an optimization in the Microsoft OLE runtime that we need
      * to copy, as shown by the test_no_couninitialize_client test. without
@@ -271,6 +283,8 @@ static HRESULT WINAPI RpcChannelBuffer_SendReceive(LPRPCCHANNELBUFFER iface, RPC
         hr = CoWaitForMultipleHandles(0, INFINITE, 1, &params->handle, &index);
     CloseHandle(params->handle);
 
+    if (hr == S_OK) hr = params->hr;
+
     status = params->status;
     HeapFree(GetProcessHeap(), 0, params);
     params = NULL;
@@ -434,12 +448,19 @@ HRESULT RPC_CreateServerChannel(IRpcChannelBuffer **chan)
 }
 
 
-HRESULT RPC_ExecuteCall(struct dispatch_params *params)
+void RPC_ExecuteCall(struct dispatch_params *params)
 {
-    HRESULT hr = IRpcStubBuffer_Invoke(params->stub, params->msg, params->chan);
+    __TRY
+    {
+        params->hr = IRpcStubBuffer_Invoke(params->stub, params->msg, params->chan);
+    }
+    __EXCEPT(ole_filter)
+    {
+        params->hr = GetExceptionCode();
+    }
+    __ENDTRY
     IRpcStubBuffer_Release(params->stub);
     if (params->handle) SetEvent(params->handle);
-    return hr;
 }
 
 static void __RPC_STUB dispatch_rpc(RPC_MESSAGE *msg)
@@ -600,30 +621,20 @@ static HRESULT create_server(REFCLSID rclsid)
 {
     static const WCHAR  wszLocalServer32[] = { 'L','o','c','a','l','S','e','r','v','e','r','3','2',0 };
     static const WCHAR  embedding[] = { ' ', '-','E','m','b','e','d','d','i','n','g',0 };
-    HKEY                hkeyclsid;
     HKEY                key;
-    HRESULT             hres = E_UNEXPECTED;
-    WCHAR               exe[MAX_PATH+1];
-    DWORD               exelen = sizeof(exe);
+    HRESULT             hres;
     WCHAR               command[MAX_PATH+sizeof(embedding)/sizeof(WCHAR)];
+    DWORD               size = MAX_PATH+1 * sizeof(WCHAR);
     STARTUPINFOW        sinfo;
     PROCESS_INFORMATION pinfo;
 
-    hres = HRESULT_FROM_WIN32(COM_OpenKeyForCLSID(rclsid, KEY_READ, &hkeyclsid));
-    if (hres != S_OK) {
+    hres = COM_OpenKeyForCLSID(rclsid, wszLocalServer32, KEY_READ, &key);
+    if (FAILED(hres)) {
         ERR("class %s not registered\n", debugstr_guid(rclsid));
-        return REGDB_E_READREGDB;
-    }
-
-    hres = RegOpenKeyExW(hkeyclsid, wszLocalServer32, 0, KEY_READ, &key);
-
-    if (hres != ERROR_SUCCESS) {
-        WARN("class %s not registered as LocalServer32\n", debugstr_guid(rclsid));
-        return REGDB_E_READREGDB; /* Probably */
+        return hres;
     }
 
-    memset(exe,0,sizeof(exe));
-    hres= RegQueryValueExW(key, NULL, NULL, NULL, (LPBYTE)exe, &exelen);
+    hres = RegQueryValueExW(key, NULL, NULL, NULL, (LPBYTE)command, &size);
     RegCloseKey(key);
     if (hres) {
         WARN("No default value for LocalServer32 key\n");
@@ -633,17 +644,16 @@ static HRESULT create_server(REFCLSID rclsid)
     memset(&sinfo,0,sizeof(sinfo));
     sinfo.cb = sizeof(sinfo);
 
-    /* EXE servers are started with the -Embedding switch. MSDN also claims /Embedding is used,
-     * 9x does -Embedding, perhaps an 9x/NT difference?
-     */
+    /* EXE servers are started with the -Embedding switch. */
 
-    strcpyW(command, exe);
     strcatW(command, embedding);
 
     TRACE("activating local server %s for %s\n", debugstr_w(command), debugstr_guid(rclsid));
 
-    if (!CreateProcessW(exe, command, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo)) {
-        WARN("failed to run local server %s\n", debugstr_w(exe));
+    /* FIXME: Win2003 supports a ServerExecutable value that is passed into
+     * CreateProcess */
+    if (!CreateProcessW(NULL, command, NULL, NULL, FALSE, 0, NULL, NULL, &sinfo, &pinfo)) {
+        WARN("failed to run local server %s\n", debugstr_w(command));
         return HRESULT_FROM_WIN32(GetLastError());
     }
     CloseHandle(pinfo.hProcess);
@@ -694,7 +704,7 @@ static DWORD start_local_service(LPCWSTR name, DWORD num, LPWSTR *params)
  */
 static HRESULT create_local_service(REFCLSID rclsid)
 {
-    HRESULT hres = REGDB_E_READREGDB;
+    HRESULT hres;
     WCHAR buf[CHARS_IN_GUID], keyname[50];
     static const WCHAR szAppId[] = { 'A','p','p','I','d',0 };
     static const WCHAR szAppIdKey[] = { 'A','p','p','I','d','\\',0 };
@@ -707,11 +717,11 @@ static HRESULT create_local_service(REFCLSID rclsid)
     TRACE("Attempting to start Local service for %s\n", debugstr_guid(rclsid));
 
     /* read the AppID value under the class's key */
-    r = COM_OpenKeyForCLSID(rclsid, KEY_READ, &hkey);
-    if (r!=ERROR_SUCCESS)
+    hres = COM_OpenKeyForCLSID(rclsid, szAppId, KEY_READ, &hkey);
+    if (FAILED(hres))
         return hres;
     sz = sizeof buf;
-    r = RegQueryValueExW(hkey, szAppId, NULL, &type, (LPBYTE)buf, &sz);
+    r = RegQueryValueExW(hkey, NULL, NULL, &type, (LPBYTE)buf, &sz);
     RegCloseKey(hkey);
     if (r!=ERROR_SUCCESS || type!=REG_SZ)
         return hres;
index 2129c77..d1bd193 100644 (file)
@@ -2227,7 +2227,12 @@ HRESULT WINAPI StgOpenStorageOnILockBytes16(
  * the WriteClassStg.
  *
  * PARAMS
- *  pstg Segmented LPSTORAGE pointer.
+ *  pstg    [I] Segmented LPSTORAGE pointer.
+ *  pclsid  [O] Pointer to where the CLSID is written
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: HRESULT code.
  */
 HRESULT WINAPI ReadClassStg16(SEGPTR pstg, CLSID *pclsid)
 {
index fe6399d..58273ca 100644 (file)
@@ -48,7 +48,7 @@
 521 cdecl IStream16_Read(ptr ptr long ptr) IStream16_fnRead
 #522 cdecl IStream16_Write(ptr ptr long ptr) IStream16_fnWrite
 522 stub  IStream16_Write
-523 cdecl IStream16_Seek(ptr long long long ptr) IStream16_fnSeek
+523 cdecl IStream16_Seek(ptr double long ptr) IStream16_fnSeek
 524 stub  IStream16_SetSize
 525 stub  IStream16_CopyTo
 526 stub  IStream16_Commit
index 6f7f22d..708d994 100644 (file)
@@ -1057,24 +1057,30 @@ HRESULT WINAPI StorageImpl_CreateStorage(
   if (pwcsName == 0)
     return STG_E_INVALIDNAME;
 
+  /*
+   * Initialize the out parameter
+   */
+  *ppstg = NULL;
+
   /*
    * Validate the STGM flags
    */
   if ( FAILED( validateSTGM(grfMode) ) ||
        (grfMode & STGM_DELETEONRELEASE) )
+  {
+    WARN("bad grfMode: 0x%lx\n", grfMode);
     return STG_E_INVALIDFLAG;
+  }
 
   /*
    * Check that we're compatible with the parent's storage mode
    */
   parent_grfMode = STGM_ACCESS_MODE( This->base.ancestorStorage->base.openFlags );
   if ( STGM_ACCESS_MODE( grfMode ) > STGM_ACCESS_MODE( parent_grfMode ) )
+  {
+    WARN("access denied\n");
     return STG_E_ACCESSDENIED;
-
-  /*
-   * Initialize the out parameter
-   */
-  *ppstg = 0;
+  }
 
   /*
    * Create a property enumeration and search the properties
@@ -1095,7 +1101,10 @@ HRESULT WINAPI StorageImpl_CreateStorage(
     if (STGM_CREATE_MODE(grfMode) == STGM_CREATE)
       IStorage_DestroyElement(iface, pwcsName);
     else
+    {
+      WARN("file already exists\n");
       return STG_E_FILEALREADYEXISTS;
+    }
   }
 
   /*
@@ -1106,7 +1115,10 @@ HRESULT WINAPI StorageImpl_CreateStorage(
   newProperty.sizeOfNameString = (lstrlenW(pwcsName)+1)*sizeof(WCHAR);
 
   if (newProperty.sizeOfNameString > PROPERTY_NAME_BUFFER_LEN)
+  {
+    FIXME("name too long\n");
     return STG_E_INVALIDNAME;
+  }
 
   strcpyW(newProperty.name, pwcsName);
 
@@ -5802,15 +5814,16 @@ HRESULT WINAPI StgOpenStorage(
   /*
    * Validate the sharing mode
    */
-  switch(STGM_SHARE_MODE(grfMode))
-  {
-  case STGM_SHARE_EXCLUSIVE:
-  case STGM_SHARE_DENY_WRITE:
-    break;
-  default:
-    hr = STG_E_INVALIDFLAG;
-    goto end;
-  }
+  if (!(grfMode & STGM_TRANSACTED))
+    switch(STGM_SHARE_MODE(grfMode))
+    {
+      case STGM_SHARE_EXCLUSIVE:
+      case STGM_SHARE_DENY_WRITE:
+        break;
+      default:
+        hr = STG_E_INVALIDFLAG;
+        goto end;
+    }
 
   /*
    * Validate the STGM flags
@@ -6116,7 +6129,8 @@ HRESULT WINAPI WriteClassStg(IStorage* pStg, REFCLSID rclsid)
 {
   HRESULT hRes;
 
-  assert(pStg != 0);
+  if(!pStg)
+    return E_INVALIDARG;
 
   hRes = IStorage_SetClass(pStg, rclsid);
 
@@ -6126,17 +6140,27 @@ HRESULT WINAPI WriteClassStg(IStorage* pStg, REFCLSID rclsid)
 /***********************************************************************
  *    ReadClassStg (OLE32.@)
  *
- * This method reads the CLSID previously written to a storage object with the WriteClassStg.
+ * This method reads the CLSID previously written to a storage object with
+ * the WriteClassStg.
+ *
+ * PARAMS
+ *  pstg    [I] IStorage pointer
+ *  pclsid  [O] Pointer to where the CLSID is written
+ *
+ * RETURNS
+ *  Success: S_OK.
+ *  Failure: HRESULT code.
  */
 HRESULT WINAPI ReadClassStg(IStorage *pstg,CLSID *pclsid){
 
     STATSTG pstatstg;
     HRESULT hRes;
 
-    TRACE("()\n");
+    TRACE("(%p, %p)\n", pstg, pclsid);
+
+    if(!pstg || !pclsid)
+        return E_INVALIDARG;
 
-    if(pclsid==NULL)
-        return E_POINTER;
    /*
     * read a STATSTG structure (contains the clsid) from the storage
     */
index ef96e05..413f4f3 100644 (file)
@@ -49,7 +49,7 @@ static struct ifstub *stub_manager_ipid_to_ifstub(struct stub_manager *m, const
 /* creates a new stub manager and adds it into the apartment. caller must
  * release stub manager when it is no longer required. the apartment and
  * external refs together take one implicit ref */
-struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object, MSHLFLAGS mshlflags)
+struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object)
 {
     struct stub_manager *sm;
 
@@ -79,15 +79,8 @@ struct stub_manager *new_stub_manager(APARTMENT *apt, IUnknown *object, MSHLFLAG
      */
     sm->extrefs = 0;
 
-    if (mshlflags & MSHLFLAGS_TABLESTRONG)
-        sm->state = STUBSTATE_TABLE_STRONG;
-    else if (mshlflags & MSHLFLAGS_TABLEWEAK)
-        sm->state = STUBSTATE_TABLE_WEAK_UNMARSHALED;
-    else
-        sm->state = STUBSTATE_NORMAL_MARSHALED;
-    
     EnterCriticalSection(&apt->cs);
-    sm->oid    = apt->oidc++;
+    sm->oid = apt->oidc++;
     list_add_head(&apt->stubmgrs, &sm->entry);
     LeaveCriticalSection(&apt->cs);
 
@@ -301,6 +294,25 @@ static struct ifstub *stub_manager_ipid_to_ifstub(struct stub_manager *m, const
     return result;
 }
 
+struct ifstub *stub_manager_find_ifstub(struct stub_manager *m, REFIID iid, MSHLFLAGS flags)
+{
+    struct ifstub  *result = NULL;
+    struct ifstub  *ifstub;
+
+    EnterCriticalSection(&m->lock);
+    LIST_FOR_EACH_ENTRY( ifstub, &m->ifstubs, struct ifstub, entry )
+    {
+        if (IsEqualIID(iid, &ifstub->iid) && (ifstub->flags == flags))
+        {
+            result = ifstub;
+            break;
+        }
+    }
+    LeaveCriticalSection(&m->lock);
+
+    return result;
+}
+
 /* gets the stub manager associated with an ipid - caller must have
  * a reference to the apartment while a reference to the stub manager is held.
  * it must also call release on the stub manager when it is no longer needed */
@@ -402,7 +414,7 @@ static inline HRESULT generate_ipid(struct stub_manager *m, IPID *ipid)
 }
 
 /* registers a new interface stub COM object with the stub manager and returns registration record */
-struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid)
+struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *sb, IUnknown *iptr, REFIID iid, MSHLFLAGS flags)
 {
     struct ifstub *stub;
 
@@ -417,11 +429,16 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
 
     IUnknown_AddRef(iptr);
     stub->iface = iptr;
-
+    stub->flags = flags;
     stub->iid = *iid;
 
-    /* FIXME: hack for IRemUnknown because we don't notify SCM of our IPID
-     * yet, so we need to use a well-known one */
+    /* 
+     * FIXME: this is a hack for marshalling IRemUnknown. In real
+     * DCOM, the IPID of the IRemUnknown interface is generated like
+     * any other and passed to the OXID resolver which then returns it
+     * when queried. We don't have an OXID resolver yet so instead we
+     * use a magic IPID reserved for IRemUnknown.
+     */
     if (IsEqualIID(iid, &IID_IRemUnknown))
     {
         stub->ipid.Data1 = 0xffffffff;
@@ -435,6 +452,8 @@ struct ifstub *stub_manager_new_ifstub(struct stub_manager *m, IRpcStubBuffer *s
 
     EnterCriticalSection(&m->lock);
     list_add_head(&m->ifstubs, &stub->entry);
+    /* every normal marshal is counted so we don't allow more than we should */
+    if (flags & MSHLFLAGS_NORMAL) m->norm_refs++;
     LeaveCriticalSection(&m->lock);
 
     TRACE("ifstub %p created with ipid %s\n", stub, debugstr_guid(&stub->ipid));
@@ -457,34 +476,29 @@ static void stub_manager_delete_ifstub(struct stub_manager *m, struct ifstub *if
 }
 
 /* returns TRUE if it is possible to unmarshal, FALSE otherwise. */
-BOOL stub_manager_notify_unmarshal(struct stub_manager *m)
+BOOL stub_manager_notify_unmarshal(struct stub_manager *m, const IPID *ipid)
 {
-    BOOL ret;
+    BOOL ret = TRUE;
+    struct ifstub *ifstub;
+
+    if (!(ifstub = stub_manager_ipid_to_ifstub(m, ipid)))
+    {
+        ERR("attempted unmarshal of unknown IPID %s\n", debugstr_guid(ipid));
+        return FALSE;
+    }
 
     EnterCriticalSection(&m->lock);
 
-    switch (m->state)
+    /* track normal marshals so we can enforce rules whilst in-process */
+    if (ifstub->flags & MSHLFLAGS_NORMAL)
     {
-    case STUBSTATE_TABLE_STRONG:
-    case STUBSTATE_TABLE_WEAK_MARSHALED:
-        /* no transition */
-        ret = TRUE;
-        break;
-    case STUBSTATE_TABLE_WEAK_UNMARSHALED:
-        m->state = STUBSTATE_TABLE_WEAK_MARSHALED;
-        ret = TRUE;
-        break;
-    case STUBSTATE_NORMAL_MARSHALED:
-        m->state = STUBSTATE_NORMAL_UNMARSHALED;
-        ret = TRUE;
-        break;
-    default:
-        WARN("object OID %s already unmarshaled\n",
-            wine_dbgstr_longlong(m->oid));
-        ret = TRUE; /* FIXME: the state management should be per-ifstub, so
-                     * it is disabled at the moment so that InstallShield
-                     * works again */
-        break;
+        if (m->norm_refs)
+            m->norm_refs--;
+        else
+        {
+            ERR("attempted invalid normal unmarshal, norm_refs is zero\n");
+            ret = FALSE;
+        }
     }
 
     LeaveCriticalSection(&m->lock);
@@ -492,42 +506,30 @@ BOOL stub_manager_notify_unmarshal(struct stub_manager *m)
     return ret;
 }
 
-void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs)
+/* handles refcounting for CoReleaseMarshalData */
+void stub_manager_release_marshal_data(struct stub_manager *m, ULONG refs, const IPID *ipid)
 {
-    EnterCriticalSection(&m->lock);
-
-    switch (m->state)
-    {
-    case STUBSTATE_NORMAL_MARSHALED:
-    case STUBSTATE_NORMAL_UNMARSHALED: /* FIXME: check this */
-        /* nothing to change */
-        break;
-    case STUBSTATE_TABLE_WEAK_UNMARSHALED:
-    case STUBSTATE_TABLE_STRONG:
+    struct ifstub *ifstub;
+    if (!(ifstub = stub_manager_ipid_to_ifstub(m, ipid)))
+        return;
+    if (ifstub->flags & MSHLFLAGS_TABLEWEAK)
+        refs = 0;
+    else
         refs = 1;
-        break;
-    case STUBSTATE_TABLE_WEAK_MARSHALED:
-        refs = 0; /* like native */
-        break;
-    }
-
-    LeaveCriticalSection(&m->lock);
 
     stub_manager_ext_release(m, refs);
 }
 
 /* is an ifstub table marshaled? */
-BOOL stub_manager_is_table_marshaled(struct stub_manager *m)
+BOOL stub_manager_is_table_marshaled(struct stub_manager *m, const IPID *ipid)
 {
-    BOOL ret;
-
-    EnterCriticalSection(&m->lock);
-    ret = ((m->state == STUBSTATE_TABLE_STRONG) ||
-           (m->state == STUBSTATE_TABLE_WEAK_MARSHALED) ||
-           (m->state == STUBSTATE_TABLE_WEAK_UNMARSHALED));
-    LeaveCriticalSection(&m->lock);
-
-    return ret;
+    struct ifstub *ifstub = stub_manager_ipid_to_ifstub(m, ipid);
+    assert( ifstub );
+    
+    return ifstub->flags & (MSHLFLAGS_TABLESTRONG | MSHLFLAGS_TABLEWEAK);
 }