diff --git a/dlls/dsquery/Makefile.in b/dlls/dsquery/Makefile.in index a3f322419a5..8fbe92dfc89 100644 --- a/dlls/dsquery/Makefile.in +++ b/dlls/dsquery/Makefile.in @@ -1,4 +1,5 @@ MODULE = dsquery.dll +IMPORTS = uuid C_SRCS = \ main.c diff --git a/dlls/dsquery/main.c b/dlls/dsquery/main.c index ccf59f8aaac..eee32cbe9df 100644 --- a/dlls/dsquery/main.c +++ b/dlls/dsquery/main.c @@ -20,16 +20,183 @@ #include +#define COBJMACROS + #include "windef.h" #include "winbase.h" #include "objbase.h" #include "rpcproxy.h" +#include "initguid.h" +#include "cmnquery.h" #include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(dsquery); static HINSTANCE instance; +/****************************************************************** + * IClassFactory implementation + */ +struct query_class_factory { + IClassFactory IClassFactory_iface; + LONG ref; + HRESULT (*pfnCreateInstance)(IUnknown *outer, REFIID riid, void **out); +}; + +static inline struct query_class_factory *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, struct query_class_factory, IClassFactory_iface); +} + +static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **out) +{ + TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_IClassFactory) || IsEqualGUID(riid, &IID_IUnknown)) + { + IClassFactory_AddRef(iface); + *out = iface; + return S_OK; + } + + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface) +{ + struct query_class_factory *This = impl_from_IClassFactory(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) increasing refcount to %u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI ClassFactory_Release(IClassFactory *iface) +{ + struct query_class_factory *This = impl_from_IClassFactory(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) decreasing refcount to %u\n", iface, ref); + + if (ref == 0) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, + IUnknown *outer, REFIID riid, void **out) +{ + struct query_class_factory *This = impl_from_IClassFactory(iface); + + TRACE("(%p)->(%p, %s, %p)\n", iface, outer, debugstr_guid(riid), out); + + return This->pfnCreateInstance(outer, riid, out); +} + +static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL dolock) +{ + FIXME("(%p)->(%d)\n", iface, dolock); + + return S_OK; +} + +static const IClassFactoryVtbl query_class_factory_vtbl = +{ + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, + ClassFactory_CreateInstance, + ClassFactory_LockServer, +}; + +/****************************************************************** + * ICommonQuery implementation + */ +struct common_query { + ICommonQuery ICommonQuery_iface; + LONG ref; +}; + +static inline struct common_query *impl_from_ICommonQuery(ICommonQuery *iface) +{ + return CONTAINING_RECORD(iface, struct common_query, ICommonQuery_iface); +} + +static HRESULT WINAPI CommonQuery_QueryInterface(ICommonQuery *iface, REFIID riid, void **out) +{ + TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), out); + + if (IsEqualGUID(riid, &IID_ICommonQuery) || IsEqualGUID(riid, &IID_IUnknown)) + { + ICommonQuery_AddRef(iface); + *out = iface; + return S_OK; + } + + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI CommonQuery_AddRef(ICommonQuery *iface) +{ + struct common_query *This = impl_from_ICommonQuery(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) increasing refcount to %u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI CommonQuery_Release(ICommonQuery *iface) +{ + struct common_query *This = impl_from_ICommonQuery(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) decreasing refcount to %u\n", iface, ref); + + if (ref == 0) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI CommonQuery_OpenQueryWindow(ICommonQuery *iface, + HWND parent, LPOPENQUERYWINDOW query_window, IDataObject **data_object) +{ + FIXME("(%p)->(%p, %p, %p) stub!\n", iface, parent, query_window, data_object); + + return E_NOTIMPL; +} + +static const ICommonQueryVtbl CommonQuery_vtbl = +{ + CommonQuery_QueryInterface, + CommonQuery_AddRef, + CommonQuery_Release, + CommonQuery_OpenQueryWindow, +}; + +static HRESULT CommonQuery_create(IUnknown *outer, REFIID riid, void **out) +{ + struct common_query *query; + + TRACE("outer %p, riid %s, out %p\n", outer, debugstr_guid(riid), out); + + if (outer) + return CLASS_E_NOAGGREGATION; + + if (!(query = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*query)))) + return E_OUTOFMEMORY; + + query->ICommonQuery_iface.lpVtbl = &CommonQuery_vtbl; + return ICommonQuery_QueryInterface(&query->ICommonQuery_iface, riid, out); +} + /*********************************************************************** * DllMain */ @@ -63,6 +230,26 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, void **out) { TRACE("rclsid %s, riid %s, out %p\n", debugstr_guid(rclsid), debugstr_guid(riid), out); + if (!IsEqualGUID( &IID_IClassFactory, riid) + && !IsEqualGUID( &IID_IUnknown, riid)) + { + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; + } + + if (IsEqualGUID(&CLSID_CommonQuery, rclsid)) + { + struct query_class_factory *factory = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*factory)); + if (!factory) return E_OUTOFMEMORY; + + factory->IClassFactory_iface.lpVtbl = &query_class_factory_vtbl; + factory->ref = 1; + factory->pfnCreateInstance = CommonQuery_create; + *out = factory; + return S_OK; + } + FIXME("%s: no class found\n", debugstr_guid(rclsid)); *out = NULL; return CLASS_E_CLASSNOTAVAILABLE;