diff --git a/reactos/lib/ole32/antimoniker.c b/reactos/lib/ole32/antimoniker.c index c01552510e0..bcd59e12684 100644 --- a/reactos/lib/ole32/antimoniker.c +++ b/reactos/lib/ole32/antimoniker.c @@ -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; } diff --git a/reactos/lib/ole32/bindctx.c b/reactos/lib/ole32/bindctx.c index 6b427f4dd61..a58457d133a 100644 --- a/reactos/lib/ole32/bindctx.c +++ b/reactos/lib/ole32/bindctx.c @@ -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.@) ******************************************************************************/ diff --git a/reactos/lib/ole32/clipboard.c b/reactos/lib/ole32/clipboard.c index 75b706dc142..61c9441a0b8 100644 --- a/reactos/lib/ole32/clipboard.c +++ b/reactos/lib/ole32/clipboard.c @@ -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 diff --git a/reactos/lib/ole32/compobj.c b/reactos/lib/ole32/compobj.c index 8c7a8bd0441..b2cf72b07cb 100644 --- a/reactos/lib/ole32/compobj.c +++ b/reactos/lib/ole32/compobj.c @@ -56,24 +56,20 @@ #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; } diff --git a/reactos/lib/ole32/compobj_private.h b/reactos/lib/ole32/compobj_private.h index 04231e34909..8364c6caae6 100644 --- a/reactos/lib/ole32/compobj_private.h +++ b/reactos/lib/ole32/compobj_private.h @@ -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 */ diff --git a/reactos/lib/ole32/datacache.c b/reactos/lib/ole32/datacache.c index 6079bb55e99..a3beacab4ee 100644 --- a/reactos/lib/ole32/datacache.c +++ b/reactos/lib/ole32/datacache.c @@ -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; diff --git a/reactos/lib/ole32/dcom.idl b/reactos/lib/ole32/dcom.idl index 37c6b47e280..7d95f3704c4 100644 --- a/reactos/lib/ole32/dcom.idl +++ b/reactos/lib/ole32/dcom.idl @@ -1,292 +1,292 @@ -/* - * 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] unsigned short aNetworkAddr[]; - } STRINGBINDING; - - const unsigned short COM_C_AUTHZ_NONE = 0xffff; - - typedef struct tagSECURITYBINDING { - unsigned short wAuthnSvc; - unsigned short wAuthzSvc; - [string] unsigned short 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") +/* + * 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") diff --git a/reactos/lib/ole32/defaulthandler.c b/reactos/lib/ole32/defaulthandler.c index 7486a524b11..ffd23864f3d 100644 --- a/reactos/lib/ole32/defaulthandler.c +++ b/reactos/lib/ole32/defaulthandler.c @@ -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,435 +141,13 @@ 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 = +static inline DefaultHandler *impl_from_IAdviseSink( IAdviseSink *iface ) { - 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; + return (DefaultHandler *)((char*)iface - FIELD_OFFSET(DefaultHandler, lpvtblIAdviseSink)); } -/********************************************************* - * Methods implementation for the DefaultHandler class. - */ -static DefaultHandler* DefaultHandler_Construct( - REFCLSID clsid, - LPUNKNOWN pUnkOuter) -{ - DefaultHandler* newObject = 0; +static void DefaultHandler_Destroy(DefaultHandler* This); - /* - * 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; -} - -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; - } - - - /* - * Free the actual default handler structure. - */ - HeapFree(GetProcessHeap(), 0, ptrToDestroy); -} /********************************************************* * Method implementation for the non delegating IUnknown @@ -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); - hres = OleRegGetMiscStatus(&(this->clsid), dwAspect, pdwStatus); + if (This->pOleDelegate) + return IOleObject_GetMiscStatus(This->pOleDelegate, dwAspect, pdwStatus); + + if (This->pOleDelegate) + return IOleObject_GetMiscStatus(This->pOleDelegate, 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; +} diff --git a/reactos/lib/ole32/errorinfo.c b/reactos/lib/ole32/errorinfo.c index fbeed0404c8..730f0d80a57 100644 --- a/reactos/lib/ole32/errorinfo.c +++ b/reactos/lib/ole32/errorinfo.c @@ -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) diff --git a/reactos/lib/ole32/git.c b/reactos/lib/ole32/git.c index f51714c8a79..cdf763a2f5a 100644 --- a/reactos/lib/ole32/git.c +++ b/reactos/lib/ole32/git.c @@ -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 }; diff --git a/reactos/lib/ole32/ifs.c b/reactos/lib/ole32/ifs.c index 5c087f32628..0696139edf2 100644 --- a/reactos/lib/ole32/ifs.c +++ b/reactos/lib/ole32/ifs.c @@ -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 }; diff --git a/reactos/lib/ole32/marshal.c b/reactos/lib/ole32/marshal.c index 72763276d52..6b4679d8b5a 100644 --- a/reactos/lib/ole32/marshal.c +++ b/reactos/lib/ole32/marshal.c @@ -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; } diff --git a/reactos/lib/ole32/memlockbytes16.c b/reactos/lib/ole32/memlockbytes16.c index d2c65989c7a..61078f8fede 100644 --- a/reactos/lib/ole32/memlockbytes16.c +++ b/reactos/lib/ole32/memlockbytes16.c @@ -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. * */ diff --git a/reactos/lib/ole32/moniker.c b/reactos/lib/ole32/moniker.c index 216317fd079..a7425f13002 100644 --- a/reactos/lib/ole32/moniker.c +++ b/reactos/lib/ole32/moniker.c @@ -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.@) */ diff --git a/reactos/lib/ole32/ole16.c b/reactos/lib/ole32/ole16.c index 4beb8e6e74e..f7d76f36e3a 100644 --- a/reactos/lib/ole32/ole16.c +++ b/reactos/lib/ole32/ole16.c @@ -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; +} diff --git a/reactos/lib/ole32/ole2.c b/reactos/lib/ole32/ole2.c index 6192ef2a2ed..4bc815e9058 100644 --- a/reactos/lib/ole32/ole2.c +++ b/reactos/lib/ole32/ole2.c @@ -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" @@ -57,10 +54,6 @@ 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; } /*********************************************************************** diff --git a/reactos/lib/ole32/ole2.spec b/reactos/lib/ole32/ole2.spec index 0c8e732ed76..1c337376231 100644 --- a/reactos/lib/ole32/ole2.spec +++ b/reactos/lib/ole32/ole2.spec @@ -149,10 +149,10 @@ 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 diff --git a/reactos/lib/ole32/ole2_16.c b/reactos/lib/ole32/ole2_16.c index 79094122861..12599002332 100644 --- a/reactos/lib/ole32/ole2_16.c +++ b/reactos/lib/ole32/ole2_16.c @@ -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(); +} diff --git a/reactos/lib/ole32/ole2nls.c b/reactos/lib/ole32/ole2nls.c index 82dff4b6b93..c30807e0c27 100644 --- a/reactos/lib/ole32/ole2nls.c +++ b/reactos/lib/ole32/ole2nls.c @@ -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 */ } - diff --git a/reactos/lib/ole32/ole2stubs.c b/reactos/lib/ole32/ole2stubs.c index 44970be9131..9eca37ab216 100644 --- a/reactos/lib/ole32/ole2stubs.c +++ b/reactos/lib/ole32/ole2stubs.c @@ -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; -} diff --git a/reactos/lib/ole32/oleproxy.c b/reactos/lib/ole32/oleproxy.c index b7c23198b81..095876b940b 100644 --- a/reactos/lib/ole32/oleproxy.c +++ b/reactos/lib/ole32/oleproxy.c @@ -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; } diff --git a/reactos/lib/ole32/rpc.c b/reactos/lib/ole32/rpc.c index a867a9b3f95..b50c594d932 100644 --- a/reactos/lib/ole32/rpc.c +++ b/reactos/lib/ole32/rpc.c @@ -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, ¶ms->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; + return hres; } - 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 */ - } - - 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; diff --git a/reactos/lib/ole32/storage.c b/reactos/lib/ole32/storage.c index 2129c770f30..d1bd1933727 100644 --- a/reactos/lib/ole32/storage.c +++ b/reactos/lib/ole32/storage.c @@ -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) { diff --git a/reactos/lib/ole32/storage.spec b/reactos/lib/ole32/storage.spec index fe6399d03c6..58273caa449 100644 --- a/reactos/lib/ole32/storage.spec +++ b/reactos/lib/ole32/storage.spec @@ -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 diff --git a/reactos/lib/ole32/storage32.c b/reactos/lib/ole32/storage32.c index 6f7f22dbfb5..708d99442e2 100644 --- a/reactos/lib/ole32/storage32.c +++ b/reactos/lib/ole32/storage32.c @@ -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 */ diff --git a/reactos/lib/ole32/stubmanager.c b/reactos/lib/ole32/stubmanager.c index ef96e0558b8..413f4f3e426 100644 --- a/reactos/lib/ole32/stubmanager.c +++ b/reactos/lib/ole32/stubmanager.c @@ -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); }