diff --git a/dlls/ole32/compobj.c b/dlls/ole32/compobj.c index 9050f0a0927..7dd10a79942 100644 --- a/dlls/ole32/compobj.c +++ b/dlls/ole32/compobj.c @@ -2996,6 +2996,8 @@ HRESULT WINAPI DECLSPEC_HOTPATCH CoGetClassObject( if (release_apt) apartment_release(apt); return FTMarshalCF_Create(iid, ppv); } + if (IsEqualCLSID(rclsid, &CLSID_GlobalOptions)) + return IClassFactory_QueryInterface(&GlobalOptionsCF, iid, ppv); } if (CLSCTX_INPROC & dwClsContext) @@ -5072,6 +5074,102 @@ HRESULT WINAPI CoGetApartmentType(APTTYPE *type, APTTYPEQUALIFIER *qualifier) return info->apt ? S_OK : CO_E_NOTINITIALIZED; } +typedef struct { + IGlobalOptions IGlobalOptions_iface; + LONG ref; +} GlobalOptions; + +static inline GlobalOptions *impl_from_IGlobalOptions(IGlobalOptions *iface) +{ + return CONTAINING_RECORD(iface, GlobalOptions, IGlobalOptions_iface); +} + +static HRESULT WINAPI GlobalOptions_QueryInterface(IGlobalOptions *iface, REFIID riid, void **ppv) +{ + GlobalOptions *This = impl_from_IGlobalOptions(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv); + + if (IsEqualGUID(&IID_IGlobalOptions, riid) || IsEqualGUID(&IID_IUnknown, riid)) + { + *ppv = iface; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI GlobalOptions_AddRef(IGlobalOptions *iface) +{ + GlobalOptions *This = impl_from_IGlobalOptions(iface); + LONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + return ref; +} + +static ULONG WINAPI GlobalOptions_Release(IGlobalOptions *iface) +{ + GlobalOptions *This = impl_from_IGlobalOptions(iface); + LONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%d\n", This, ref); + + if (!ref) + heap_free(This); + + return ref; +} + +static HRESULT WINAPI GlobalOptions_Set(IGlobalOptions *iface, GLOBALOPT_PROPERTIES property, ULONG_PTR value) +{ + GlobalOptions *This = impl_from_IGlobalOptions(iface); + FIXME("(%p)->(%u %lx)\n", This, property, value); + return S_OK; +} + +static HRESULT WINAPI GlobalOptions_Query(IGlobalOptions *iface, GLOBALOPT_PROPERTIES property, ULONG_PTR *value) +{ + GlobalOptions *This = impl_from_IGlobalOptions(iface); + FIXME("(%p)->(%u %p)\n", This, property, value); + return E_NOTIMPL; +} + +static const IGlobalOptionsVtbl GlobalOptionsVtbl = { + GlobalOptions_QueryInterface, + GlobalOptions_AddRef, + GlobalOptions_Release, + GlobalOptions_Set, + GlobalOptions_Query +}; + +HRESULT WINAPI GlobalOptions_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **ppv) +{ + GlobalOptions *global_options; + HRESULT hres; + + TRACE("(%p %s %p)\n", outer, debugstr_guid(riid), ppv); + + if (outer) + return E_INVALIDARG; + + global_options = heap_alloc(sizeof(*global_options)); + if (!global_options) + return E_OUTOFMEMORY; + global_options->IGlobalOptions_iface.lpVtbl = &GlobalOptionsVtbl; + global_options->ref = 1; + + hres = IGlobalOptions_QueryInterface(&global_options->IGlobalOptions_iface, riid, ppv); + IGlobalOptions_Release(&global_options->IGlobalOptions_iface); + return hres; +} + /*********************************************************************** * DllMain (OLE32.@) */ diff --git a/dlls/ole32/compobj_private.h b/dlls/ole32/compobj_private.h index b9d1e8574d4..6488287c802 100644 --- a/dlls/ole32/compobj_private.h +++ b/dlls/ole32/compobj_private.h @@ -297,6 +297,10 @@ extern HRESULT WINAPI OLE32_DllUnregisterServer(void) DECLSPEC_HIDDEN; extern HRESULT Handler_DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN; extern HRESULT HandlerCF_Create(REFCLSID rclsid, REFIID riid, LPVOID *ppv) DECLSPEC_HIDDEN; +extern HRESULT WINAPI GlobalOptions_CreateInstance(IClassFactory *iface, IUnknown *pUnk, + REFIID riid, void **ppv) DECLSPEC_HIDDEN; +extern IClassFactory GlobalOptionsCF DECLSPEC_HIDDEN; + /* Exported non-interface Data Advise Holder functions */ HRESULT DataAdviseHolder_OnConnect(IDataAdviseHolder *iface, IDataObject *pDelegate) DECLSPEC_HIDDEN; void DataAdviseHolder_OnDisconnect(IDataAdviseHolder *iface) DECLSPEC_HIDDEN; diff --git a/dlls/ole32/oleproxy.c b/dlls/ole32/oleproxy.c index bc8e1ea04d7..a7b8e395104 100644 --- a/dlls/ole32/oleproxy.c +++ b/dlls/ole32/oleproxy.c @@ -150,6 +150,17 @@ static const IClassFactoryVtbl ComCatCFVtbl = static IClassFactory ComCatCF = { &ComCatCFVtbl }; +static const IClassFactoryVtbl GlobalOptionsCFVtbl = +{ + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, + GlobalOptions_CreateInstance, + ClassFactory_LockServer +}; + +IClassFactory GlobalOptionsCF = { &GlobalOptionsCFVtbl }; + /*********************************************************************** * DllGetClassObject [OLE32.@] */ diff --git a/dlls/ole32/tests/compobj.c b/dlls/ole32/tests/compobj.c index 4468ad946e5..8f6ff7107c0 100644 --- a/dlls/ole32/tests/compobj.c +++ b/dlls/ole32/tests/compobj.c @@ -32,6 +32,7 @@ #include "shlguid.h" #include "urlmon.h" /* for CLSID_FileProtocol */ #include "dde.h" +#include "cguid.h" #include "ctxtcall.h" @@ -96,6 +97,7 @@ static const GUID IID_TestPS = { 0x66666666, 0x8888, 0x7777, { 0x66, 0x66, 0x55, DEFINE_GUID(CLSID_InProcFreeMarshaler, 0x0000033a,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); DEFINE_GUID(CLSID_testclsid, 0xacd014c7,0x9535,0x4fac,0x8b,0x53,0xa4,0x8c,0xa7,0xf4,0xd7,0x26); +DEFINE_GUID(CLSID_GlobalOptions, 0x0000034b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); static const WCHAR stdfont[] = {'S','t','d','F','o','n','t',0}; static const WCHAR wszNonExistent[] = {'N','o','n','E','x','i','s','t','e','n','t',0}; @@ -3558,6 +3560,26 @@ todo_wine { CoUninitialize(); } +static void test_GlobalOptions(void) +{ + IGlobalOptions *global_options; + HRESULT hres; + + CoInitialize(NULL); + + hres = CoCreateInstance(&CLSID_GlobalOptions, NULL, CLSCTX_INPROC_SERVER, + &IID_IGlobalOptions, (void**)&global_options); + ok(hres == S_OK, "CoCreateInstance(CLSID_GlobalOptions) failed: %08x\n", hres); + + IGlobalOptions_Release(global_options); + + hres = CoCreateInstance(&CLSID_GlobalOptions, (IUnknown*)0xdeadbeef, CLSCTX_INPROC_SERVER, + &IID_IGlobalOptions, (void**)&global_options); + ok(hres == E_INVALIDARG, "CoCreateInstance(CLSID_GlobalOptions) failed: %08x\n", hres); + + CoUninitialize(); +} + static void init_funcs(void) { HMODULE hOle32 = GetModuleHandleA("ole32"); @@ -3629,4 +3651,5 @@ START_TEST(compobj) test_CoGetCurrentLogicalThreadId(); test_IInitializeSpy(); test_CoGetInstanceFromFile(); + test_GlobalOptions(); } diff --git a/dlls/uuid/uuid.c b/dlls/uuid/uuid.c index 92ec9d01c83..913e99cc6a2 100644 --- a/dlls/uuid/uuid.c +++ b/dlls/uuid/uuid.c @@ -124,6 +124,7 @@ DEFINE_GUID(CLSID_StdEvent, 0x0000032b,0x0000,0x0000,0xc0,0x00,0x0 DEFINE_GUID(CLSID_ManualResetEvent, 0x0000032c,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); DEFINE_GUID(CLSID_SynchronizeContainer, 0x0000032d,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); DEFINE_GUID(CLSID_InProcFreeMarshaler, 0x0000033a,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); +DEFINE_GUID(CLSID_GlobalOptions, 0x0000034b,0x0000,0x0000,0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46); DEFINE_GUID(CLSID_TF_ThreadMgr, 0x529a9e6b,0x6587,0x4f23,0xab,0x9e,0x9c,0x7d,0x68,0x3e,0x3c,0x50); DEFINE_GUID(CLSID_TF_InputProcessorProfiles, 0x33c53a50,0xf456,0x4884,0xb0,0x49,0x85,0xfd,0x64,0x3e,0xcf,0xed); DEFINE_GUID(CLSID_TF_CategoryMgr, 0xA4B544A1,0x438D,0x4B41,0x93,0x25,0x86,0x95,0x23,0xE2,0xD6,0xC7); diff --git a/include/cguid.h b/include/cguid.h index fa9593da448..bacf64c4329 100644 --- a/include/cguid.h +++ b/include/cguid.h @@ -99,6 +99,7 @@ extern const CLSID CLSID_InProcFreeMarshaler; extern const CLSID CLSID_Picture_Metafile; extern const CLSID CLSID_Picture_EnhMetafile; extern const CLSID CLSID_Picture_Dib; +extern const CLSID CLSID_GlobalOptions; extern const GUID GUID_TRISTATE;