Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/dsuiext/Makefile.in | 10 ++ dlls/dsuiext/dsuiext.c | 361 ++++++++++++++++++++++++++++++++++++++ dlls/dsuiext/dsuiext.idl | 25 +++ dlls/dsuiext/dsuiext.spec | 9 + include/Makefile.in | 1 + include/dsclient.h | 61 +++++++ 6 files changed, 467 insertions(+) create mode 100644 dlls/dsuiext/Makefile.in create mode 100644 dlls/dsuiext/dsuiext.c create mode 100644 dlls/dsuiext/dsuiext.idl create mode 100644 dlls/dsuiext/dsuiext.spec create mode 100644 include/dsclient.h
diff --git a/dlls/dsuiext/Makefile.in b/dlls/dsuiext/Makefile.in new file mode 100644 index 0000000000..825ffd784c --- /dev/null +++ b/dlls/dsuiext/Makefile.in @@ -0,0 +1,10 @@ +MODULE = dsuiext.dll +IMPORTS = ole32 uuid + +EXTRADLLFLAGS = -mno-cygwin + +C_SRCS = \ + dsuiext.c + +IDL_SRCS = \ + dsuiext.idl diff --git a/dlls/dsuiext/dsuiext.c b/dlls/dsuiext/dsuiext.c new file mode 100644 index 0000000000..9d21d013df --- /dev/null +++ b/dlls/dsuiext/dsuiext.c @@ -0,0 +1,361 @@ +/* + * Copyright 2020 Dmitry Timoshkov + * + * This file contains only stubs to get the printui.dll up and running + * activeds.dll is much much more than this + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include <stdarg.h> + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "objbase.h" +#include "rpcproxy.h" +#include "initguid.h" +#include "iads.h" +#include "dsclient.h" + +#include "wine/heap.h" +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(dsuiext); + +static HMODULE hmodule; + +typedef struct +{ + IDsDisplaySpecifier IDsDisplaySpecifier_iface; + LONG ref; +} DisplaySpec; + +static inline DisplaySpec *impl_from_IDsDisplaySpecifier(IDsDisplaySpecifier *iface) +{ + return CONTAINING_RECORD(iface, DisplaySpec, IDsDisplaySpecifier_iface); +} + +static HRESULT WINAPI dispspec_QueryInterface(IDsDisplaySpecifier *iface, REFIID riid, void **obj) +{ + TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj); + + if (!riid || !obj) return E_INVALIDARG; + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IDsDisplaySpecifier)) + { + iface->lpVtbl->AddRef(iface); + *obj = iface; + return S_OK; + } + + FIXME("interface %s is not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI dispspec_AddRef(IDsDisplaySpecifier *iface) +{ + DisplaySpec *dispspec = impl_from_IDsDisplaySpecifier(iface); + return InterlockedIncrement(&dispspec->ref); +} + +static ULONG WINAPI dispspec_Release(IDsDisplaySpecifier *iface) +{ + DisplaySpec *dispspec = impl_from_IDsDisplaySpecifier(iface); + LONG ref = InterlockedDecrement(&dispspec->ref); + + if (!ref) + { + TRACE("destroying %p\n", iface); + heap_free(dispspec); + } + + return ref; +} + +static HRESULT WINAPI dispspec_SetServer(IDsDisplaySpecifier *iface, LPCWSTR server, LPCWSTR user, + LPCWSTR password, DWORD flags) +{ + FIXME("%p,%s,%s,%p,%08x: stub\n", iface, debugstr_w(server), debugstr_w(user), password, flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI dispspec_SetLanguageID(IDsDisplaySpecifier *iface, LANGID lang) +{ + FIXME("%p,%08x: stub\n", iface, lang); + return E_NOTIMPL; +} + +static HRESULT WINAPI dispspec_GetDisplaySpecifier(IDsDisplaySpecifier *iface, LPCWSTR object, + REFIID iid, void **obj) +{ + FIXME("%p,%s,%s,%p: stub\n", iface, debugstr_w(object), debugstr_guid(iid), obj); + return E_NOTIMPL; +} + +static HRESULT WINAPI dispspec_GetIconLocation(IDsDisplaySpecifier *iface, LPCWSTR object, + DWORD flags, LPWSTR buffer, INT size, INT *id) +{ + FIXME("%p,%s,%08x,%p,%d,%p: stub\n", iface, debugstr_w(object), flags, buffer, size, id); + return E_NOTIMPL; +} + +static HICON WINAPI dispspec_GetIcon(IDsDisplaySpecifier *iface, LPCWSTR object, + DWORD flags, INT cx, INT cy) +{ + FIXME("%p,%s,%08x,%dx%d: stub\n", iface, debugstr_w(object), flags, cx, cy); + return 0; +} + +static HRESULT WINAPI dispspec_GetFriendlyClassName(IDsDisplaySpecifier *iface, LPCWSTR object, + LPWSTR buffer, INT size) +{ + FIXME("%p,%s,%p,%d: stub\n", iface, debugstr_w(object), buffer, size); + return E_NOTIMPL; +} + +static HRESULT WINAPI dispspec_GetFriendlyAttributeName(IDsDisplaySpecifier *iface, LPCWSTR object, + LPCWSTR name, LPWSTR buffer, UINT size) +{ + FIXME("%p,%s,%s,%p,%d: stub\n", iface, debugstr_w(object), debugstr_w(name), buffer, size); + return E_NOTIMPL; +} + +static BOOL WINAPI dispspec_IsClassContainer(IDsDisplaySpecifier *iface, LPCWSTR object, + LPCWSTR path, DWORD flags) +{ + FIXME("%p,%s,%s,%08x: stub\n", iface, debugstr_w(object), debugstr_w(path), flags); + return FALSE; +} + +static HRESULT WINAPI dispspec_GetClassCreationInfo(IDsDisplaySpecifier *iface, LPCWSTR object, + LPDSCLASSCREATIONINFO *info) +{ + FIXME("%p,%s,%p: stub\n", iface, debugstr_w(object), info); + return E_NOTIMPL; +} + +static HRESULT WINAPI dispspec_EnumClassAttributes(IDsDisplaySpecifier *iface, LPCWSTR object, + LPDSENUMATTRIBUTES cb, LPARAM param) +{ + FIXME("%p,%s,%p,%08lx: stub\n", iface, debugstr_w(object), cb, param); + return E_NOTIMPL; +} + +static ADSTYPE WINAPI dispspec_GetAttributeADsType(IDsDisplaySpecifier *iface, LPCWSTR name) +{ + FIXME("%p,%s: stub\n", iface, debugstr_w(name)); + return ADSTYPE_INVALID; +} + +static const IDsDisplaySpecifierVtbl IDsDisplaySpecifier_vtbl = +{ + dispspec_QueryInterface, + dispspec_AddRef, + dispspec_Release, + dispspec_SetServer, + dispspec_SetLanguageID, + dispspec_GetDisplaySpecifier, + dispspec_GetIconLocation, + dispspec_GetIcon, + dispspec_GetFriendlyClassName, + dispspec_GetFriendlyAttributeName, + dispspec_IsClassContainer, + dispspec_GetClassCreationInfo, + dispspec_EnumClassAttributes, + dispspec_GetAttributeADsType +}; + +static HRESULT DsDisplaySpecifier_create(REFIID riid, void **obj) +{ + DisplaySpec *dispspec; + HRESULT hr; + + dispspec = heap_alloc(sizeof(*dispspec)); + if (!dispspec) return E_OUTOFMEMORY; + + dispspec->IDsDisplaySpecifier_iface.lpVtbl = &IDsDisplaySpecifier_vtbl; + dispspec->ref = 1; + + hr = dispspec->IDsDisplaySpecifier_iface.lpVtbl->QueryInterface(&dispspec->IDsDisplaySpecifier_iface, riid, obj); + dispspec->IDsDisplaySpecifier_iface.lpVtbl->Release(&dispspec->IDsDisplaySpecifier_iface); + + return hr; +} + +static const struct class_info +{ + const CLSID *clsid; + HRESULT (*constructor)(REFIID, void **); +} class_info[] = +{ + { &CLSID_DsDisplaySpecifier, DsDisplaySpecifier_create } +}; + +typedef struct +{ + IClassFactory IClassFactory_iface; + LONG ref; + const struct class_info *info; +} class_factory; + +static inline class_factory *impl_from_IClassFactory(IClassFactory *iface) +{ + return CONTAINING_RECORD(iface, class_factory, IClassFactory_iface); +} + +static HRESULT WINAPI factory_QueryInterface(IClassFactory *iface, REFIID riid, LPVOID *obj) +{ + TRACE("%p,%s,%p\n", iface, debugstr_guid(riid), obj); + + if (!riid || !obj) return E_INVALIDARG; + + if (IsEqualIID(riid, &IID_IUnknown) || + IsEqualIID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef(iface); + *obj = iface; + return S_OK; + } + + *obj = NULL; + FIXME("interface %s is not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI factory_AddRef(IClassFactory *iface) +{ + class_factory *factory = impl_from_IClassFactory(iface); + ULONG ref = InterlockedIncrement(&factory->ref); + + TRACE("(%p) ref %u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI factory_Release(IClassFactory *iface) +{ + class_factory *factory = impl_from_IClassFactory(iface); + ULONG ref = InterlockedDecrement(&factory->ref); + + TRACE("(%p) ref %u\n", iface, ref); + + if (!ref) + heap_free(factory); + + return ref; +} + +static HRESULT WINAPI factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj) +{ + class_factory *factory = impl_from_IClassFactory(iface); + + TRACE("%p,%s,%p\n", outer, debugstr_guid(riid), obj); + + if (!riid || !obj) return E_INVALIDARG; + + *obj = NULL; + if (outer) return CLASS_E_NOAGGREGATION; + + return factory->info->constructor(riid, obj); +} + +static HRESULT WINAPI factory_LockServer(IClassFactory *iface, BOOL lock) +{ + FIXME("%p,%d: stub\n", iface, lock); + return S_OK; +} + +static const struct IClassFactoryVtbl factory_vtbl = +{ + factory_QueryInterface, + factory_AddRef, + factory_Release, + factory_CreateInstance, + factory_LockServer +}; + +static HRESULT factory_constructor(const struct class_info *info, REFIID riid, void **obj) +{ + class_factory *factory; + HRESULT hr; + + factory = heap_alloc(sizeof(*factory)); + if (!factory) return E_OUTOFMEMORY; + + factory->IClassFactory_iface.lpVtbl = &factory_vtbl; + factory->ref = 1; + factory->info = info; + + hr = IClassFactory_QueryInterface(&factory->IClassFactory_iface, riid, obj); + IClassFactory_Release(&factory->IClassFactory_iface); + + return hr; +} + +HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, LPVOID *obj) +{ + int i; + + TRACE("%s,%s,%p\n", debugstr_guid(clsid), debugstr_guid(iid), obj); + + if (!clsid || !iid || !obj) return E_INVALIDARG; + + *obj = NULL; + + for (i = 0; i < ARRAY_SIZE(class_info); i++) + { + if (IsEqualCLSID(class_info[i].clsid, clsid)) + return factory_constructor(&class_info[i], iid, obj); + } + + FIXME("class %s/%s is not implemented\n", debugstr_guid(clsid), debugstr_guid(iid)); + return CLASS_E_CLASSNOTAVAILABLE; +} + +HRESULT WINAPI DllCanUnloadNow(void) +{ + return S_FALSE; +} + +HRESULT WINAPI DllRegisterServer(void) +{ + return __wine_register_resources(hmodule); +} + +HRESULT WINAPI DllUnregisterServer(void) +{ + return __wine_unregister_resources(hmodule); +} + +BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved) +{ + TRACE("%p,%u,%p\n", hinst, reason, reserved); + + switch (reason) + { + case DLL_WINE_PREATTACH: + return FALSE; /* prefer native version */ + + case DLL_PROCESS_ATTACH: + hmodule = hinst; + DisableThreadLibraryCalls(hinst); + break; + } + + return TRUE; +} diff --git a/dlls/dsuiext/dsuiext.idl b/dlls/dsuiext/dsuiext.idl new file mode 100644 index 0000000000..3fa84ca42b --- /dev/null +++ b/dlls/dsuiext/dsuiext.idl @@ -0,0 +1,25 @@ +/* + * Copyright 2020 Dmitry Timoshkov + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#pragma makedep register + +[ + uuid(1ab4a8c0-6a0b-11d2-ad49-00c04fa31a86), + threading(apartment) +] +coclass DisplaySpecifier { interface IDsDisplaySpecifier; } diff --git a/dlls/dsuiext/dsuiext.spec b/dlls/dsuiext/dsuiext.spec new file mode 100644 index 0000000000..5b1ac2a559 --- /dev/null +++ b/dlls/dsuiext/dsuiext.spec @@ -0,0 +1,9 @@ +@ stdcall -private DllCanUnloadNow() +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stub DllInstall +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() +@ stub DsBrowseForContainerA +@ stub DsBrowseForContainerW +@ stub DsGetFriendlyClassName +@ stub DsGetIcon diff --git a/include/Makefile.in b/include/Makefile.in index eea1543822..32b72107b8 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -232,6 +232,7 @@ SOURCES = \ dplobby8.h \ dpnathlp.h \ drmexternals.idl \ + dsclient.h \ dsconf.h \ dsgetdc.h \ dshow.h \ diff --git a/include/dsclient.h b/include/dsclient.h new file mode 100644 index 0000000000..8e4f165384 --- /dev/null +++ b/include/dsclient.h @@ -0,0 +1,61 @@ +/* + * Copyright 2020 Dmitry Timoshkov + * + * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef __DSCLIENT_H_ +#define __DSCLIENT_H_ + +DEFINE_GUID(CLSID_DsDisplaySpecifier,0x1ab4a8c0,0x6a0b,0x11d2,0xad,0x49,0x00,0xc0,0x4f,0xa3,0x1a,0x86); +#define IID_IDsDisplaySpecifier CLSID_DsDisplaySpecifier + +#define DSECAF_NOTLISTED 0x00000001 + +typedef HRESULT (CALLBACK *LPDSENUMATTRIBUTES)(LPARAM, LPCWSTR, LPCWSTR, DWORD); + +#define DSCCIF_HASWIZARDDIALOG 0x00000001 +#define DSCCIF_HASWIZARDPRIMARYPAGE 0x00000002 + +typedef struct +{ + DWORD dwFlags; + CLSID clsidWizardDialog; + CLSID clsidWizardPrimaryPage; + DWORD cWizardExtensions; + CLSID aWizardExtensions[1]; +} DSCLASSCREATIONINFO, * LPDSCLASSCREATIONINFO; + +#undef INTERFACE +#define INTERFACE IDsDisplaySpecifier +DECLARE_INTERFACE_IID_(IDsDisplaySpecifier, IUnknown, "1ab4a8c0-6a0b-11d2-ad49-00c04fa31a86") +{ + STDMETHOD(QueryInterface)(THIS_ REFIID iid, void **obj) PURE; + STDMETHOD_(ULONG,AddRef)(THIS) PURE; + STDMETHOD_(ULONG,Release)(THIS) PURE; + STDMETHOD(SetServer)(THIS_ LPCWSTR server, LPCWSTR user, LPCWSTR password, DWORD flags) PURE; + STDMETHOD(SetLanguageID)(THIS_ LANGID lang) PURE; + STDMETHOD(GetDisplaySpecifier)(THIS_ LPCWSTR object, REFIID riid, void **obj) PURE; + STDMETHOD(GetIconLocation)(THIS_ LPCWSTR object, DWORD flags, LPWSTR buffer, INT size, INT *id) PURE; + STDMETHOD_(HICON, GetIcon)(THIS_ LPCWSTR object, DWORD flags, INT cx, INT cy) PURE; + STDMETHOD(GetFriendlyClassName)(THIS_ LPCWSTR object, LPWSTR buffer, INT size) PURE; + STDMETHOD(GetFriendlyAttributeName)(THIS_ LPCWSTR object, LPCWSTR name, LPWSTR buffer, UINT size) PURE; + STDMETHOD_(BOOL, IsClassContainer)(THIS_ LPCWSTR object, LPCWSTR path, DWORD flags) PURE; + STDMETHOD(GetClassCreationInfo)(THIS_ LPCWSTR object, LPDSCLASSCREATIONINFO *info) PURE; + STDMETHOD(EnumClassAttributes)(THIS_ LPCWSTR object, LPDSENUMATTRIBUTES cb, LPARAM param) PURE; + STDMETHOD_(ADSTYPE, GetAttributeADsType)(THIS_ LPCWSTR name) PURE; +}; + +#endif /* __DSCLIENT_H_ */