From b01c652d4b3ce0e3bea34223eb19f3f8fa36d5d4 Mon Sep 17 00:00:00 2001 From: Vincent Povirk Date: Mon, 1 Jun 2009 13:32:41 -0500 Subject: [PATCH] windowscodecs: Add stub implementation of IWICImagingFactory. --- dlls/windowscodecs/Makefile.in | 7 +- dlls/windowscodecs/clsfactory.c | 170 +++++++++++++ dlls/windowscodecs/imgfactory.c | 339 +++++++++++++++++++++++++ dlls/windowscodecs/regsvr.c | 333 ++++++++++++++++++++++++ dlls/windowscodecs/wincodecs_private.h | 24 ++ dlls/windowscodecs/windowscodecs.spec | 4 +- tools/wine.inf.in | 1 + 7 files changed, 875 insertions(+), 3 deletions(-) create mode 100644 dlls/windowscodecs/clsfactory.c create mode 100644 dlls/windowscodecs/imgfactory.c create mode 100644 dlls/windowscodecs/regsvr.c create mode 100644 dlls/windowscodecs/wincodecs_private.h diff --git a/dlls/windowscodecs/Makefile.in b/dlls/windowscodecs/Makefile.in index 1449089313c..05d5521ad1a 100644 --- a/dlls/windowscodecs/Makefile.in +++ b/dlls/windowscodecs/Makefile.in @@ -3,10 +3,13 @@ TOPOBJDIR = ../.. SRCDIR = @srcdir@ VPATH = @srcdir@ MODULE = windowscodecs.dll -IMPORTS = kernel32 +IMPORTS = uuid ole32 advapi32 kernel32 C_SRCS = \ - main.c + clsfactory.c \ + imgfactory.c \ + main.c \ + regsvr.c @MAKE_DLL_RULES@ diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c new file mode 100644 index 00000000000..b74746c6e71 --- /dev/null +++ b/dlls/windowscodecs/clsfactory.c @@ -0,0 +1,170 @@ +/* + * Copyright 2009 Vincent Povirk for CodeWeavers + * + * 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 "config.h" + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "objbase.h" +#include "ocidl.h" +#include "initguid.h" +#include "wincodec.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +typedef struct { + REFCLSID classid; + HRESULT (*constructor)(IUnknown*,REFIID,void**); +} classinfo; + +static classinfo wic_classes[] = { + {&CLSID_WICImagingFactory, ImagingFactory_CreateInstance}, + {0}}; + +typedef struct { + const IClassFactoryVtbl *lpIClassFactoryVtbl; + LONG ref; + classinfo *info; +} ClassFactoryImpl; + +static HRESULT WINAPI ClassFactoryImpl_QueryInterface(IClassFactory *iface, + REFIID iid, void **ppv) +{ + ClassFactoryImpl *This = (ClassFactoryImpl*)iface; + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IClassFactory, iid)) + { + *ppv = This; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI ClassFactoryImpl_AddRef(IClassFactory *iface) +{ + ClassFactoryImpl *This = (ClassFactoryImpl*)iface; + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI ClassFactoryImpl_Release(IClassFactory *iface) +{ + ClassFactoryImpl *This = (ClassFactoryImpl*)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + if (ref == 0) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI ClassFactoryImpl_CreateInstance(IClassFactory *iface, + IUnknown *pUnkOuter, REFIID riid, void **ppv) +{ + ClassFactoryImpl *This = (ClassFactoryImpl*)iface; + + return This->info->constructor(pUnkOuter, riid, ppv); +} + +static HRESULT WINAPI ClassFactoryImpl_LockServer(IClassFactory *iface, BOOL lock) +{ + TRACE("(%p, %i): stub\n", iface, lock); + return E_NOTIMPL; +} + +static const IClassFactoryVtbl ClassFactoryImpl_Vtbl = { + ClassFactoryImpl_QueryInterface, + ClassFactoryImpl_AddRef, + ClassFactoryImpl_Release, + ClassFactoryImpl_CreateInstance, + ClassFactoryImpl_LockServer +}; + +static HRESULT ClassFactoryImpl_Constructor(classinfo *info, REFIID riid, LPVOID *ppv) +{ + ClassFactoryImpl *This; + HRESULT ret; + + *ppv = NULL; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassFactoryImpl)); + if (!This) return E_OUTOFMEMORY; + + This->lpIClassFactoryVtbl = &ClassFactoryImpl_Vtbl; + This->ref = 1; + This->info = info; + + ret = IClassFactory_QueryInterface((IClassFactory*)This, riid, ppv); + IClassFactory_Release((IClassFactory*)This); + + return ret; +} + +HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv) +{ + HRESULT ret; + classinfo *info=NULL; + int i; + + TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv); + + if (!rclsid || !iid || !ppv) + return E_INVALIDARG; + + *ppv = NULL; + + for (i=0; wic_classes[i].classid; i++) + { + if (IsEqualCLSID(wic_classes[i].classid, rclsid)) + { + info = &wic_classes[i]; + break; + } + } + + if (info) + ret = ClassFactoryImpl_Constructor(info, iid, ppv); + else + ret = CLASS_E_CLASSNOTAVAILABLE; + + TRACE("<-- %08X\n", ret); + return ret; +} diff --git a/dlls/windowscodecs/imgfactory.c b/dlls/windowscodecs/imgfactory.c new file mode 100644 index 00000000000..f422a8a5b5a --- /dev/null +++ b/dlls/windowscodecs/imgfactory.c @@ -0,0 +1,339 @@ +/* + * Copyright 2009 Vincent Povirk for CodeWeavers + * + * 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 "config.h" + +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winreg.h" +#include "objbase.h" +#include "wincodec.h" + +#include "wincodecs_private.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +typedef struct { + const IWICImagingFactoryVtbl *lpIWICImagingFactoryVtbl; + LONG ref; +} ImagingFactory; + +HRESULT WINAPI ImagingFactory_QueryInterface(IWICImagingFactory *iface, REFIID iid, + void **ppv) +{ + ImagingFactory *This = (ImagingFactory*)iface; + TRACE("(%p,%s,%p)\n", iface, debugstr_guid(iid), ppv); + + if (!ppv) return E_INVALIDARG; + + if (IsEqualIID(&IID_IUnknown, iid) || IsEqualIID(&IID_IWICImagingFactory, iid)) + { + *ppv = This; + } + else + { + *ppv = NULL; + return E_NOINTERFACE; + } + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static ULONG WINAPI ImagingFactory_AddRef(IWICImagingFactory *iface) +{ + ImagingFactory *This = (ImagingFactory*)iface; + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + return ref; +} + +static ULONG WINAPI ImagingFactory_Release(IWICImagingFactory *iface) +{ + ImagingFactory *This = (ImagingFactory*)iface; + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) refcount=%u\n", iface, ref); + + if (ref == 0) + HeapFree(GetProcessHeap(), 0, This); + + return ref; +} + +static HRESULT WINAPI ImagingFactory_CreateDecoderFromFilename( + IWICImagingFactory *iface, LPCWSTR wzFilename, const GUID *pguidVendor, + DWORD dwDesiredAccess, WICDecodeOptions metadataOptions, + IWICBitmapDecoder **ppIDecoder) +{ + FIXME("(%p,%s,%s,%u,%u,%p): stub\n", iface, debugstr_w(wzFilename), + debugstr_guid(pguidVendor), dwDesiredAccess, metadataOptions, ppIDecoder); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateDecoderFromStream( + IWICImagingFactory *iface, IStream *pIStream, const GUID *pguidVendor, + WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder) +{ + FIXME("(%p,%p,%s,%u,%p): stub\n", iface, pIStream, debugstr_guid(pguidVendor), + metadataOptions, ppIDecoder); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateDecoderFromFileHandle( + IWICImagingFactory *iface, ULONG_PTR hFile, const GUID *pguidVendor, + WICDecodeOptions metadataOptions, IWICBitmapDecoder **ppIDecoder) +{ + FIXME("(%p,%lx,%s,%u,%p): stub\n", iface, hFile, debugstr_guid(pguidVendor), + metadataOptions, ppIDecoder); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateComponentInfo(IWICImagingFactory *iface, + REFCLSID clsidComponent, IWICComponentInfo **ppIInfo) +{ + FIXME("(%p,%s,%p): stub\n", iface, debugstr_guid(clsidComponent), ppIInfo); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateDecoder(IWICImagingFactory *iface, + REFGUID guidContainerFormat, const GUID *pguidVendor, + IWICBitmapDecoder **ppIDecoder) +{ + FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidContainerFormat), + debugstr_guid(pguidVendor), ppIDecoder); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateEncoder(IWICImagingFactory *iface, + REFGUID guidContainerFormat, const GUID *pguidVendor, + IWICBitmapEncoder **ppIEncoder) +{ + FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidContainerFormat), + debugstr_guid(pguidVendor), ppIEncoder); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreatePalette(IWICImagingFactory *iface, + IWICPalette **ppIPalette) +{ + FIXME("(%p,%p): stub\n", iface, ppIPalette); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateFormatConverter(IWICImagingFactory *iface, + IWICFormatConverter **ppIFormatConverter) +{ + FIXME("(%p,%p): stub", iface, ppIFormatConverter); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateBitmapScaler(IWICImagingFactory *iface, + IWICBitmapScaler **ppIBitmapScaler) +{ + FIXME("(%p,%p): stub", iface, ppIBitmapScaler); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateBitmapClipper(IWICImagingFactory *iface, + IWICBitmapClipper **ppIBitmapClipper) +{ + FIXME("(%p,%p): stub", iface, ppIBitmapClipper); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateBitmapFlipRotator(IWICImagingFactory *iface, + IWICBitmapFlipRotator **ppIBitmapFlipRotator) +{ + FIXME("(%p,%p): stub", iface, ppIBitmapFlipRotator); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateStream(IWICImagingFactory *iface, + IWICStream **ppIWICStream) +{ + FIXME("(%p,%p): stub", iface, ppIWICStream); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateColorContext(IWICImagingFactory *iface, + IWICColorContext **ppIColorContext) +{ + FIXME("(%p,%p): stub", iface, ppIColorContext); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateColorTransformer(IWICImagingFactory *iface, + IWICColorTransform **ppIColorTransform) +{ + FIXME("(%p,%p): stub", iface, ppIColorTransform); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateBitmap(IWICImagingFactory *iface, + UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat, + WICBitmapCreateCacheOption option, IWICBitmap **ppIBitmap) +{ + FIXME("(%p,%u,%u,%s,%u,%p): stub\n", iface, uiWidth, uiHeight, + debugstr_guid(pixelFormat), option, ppIBitmap); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateBitmapFromSource(IWICImagingFactory *iface, + IWICBitmapSource *piBitmapSource, WICBitmapCreateCacheOption option, + IWICBitmap **ppIBitmap) +{ + FIXME("(%p,%p,%u,%p): stub\n", iface, piBitmapSource, option, ppIBitmap); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateBitmapFromSourceRect(IWICImagingFactory *iface, + IWICBitmapSource *piBitmapSource, UINT x, UINT y, UINT width, UINT height, + IWICBitmap **ppIBitmap) +{ + FIXME("(%p,%p,%u,%u,%u,%u,%p): stub\n", iface, piBitmapSource, x, y, width, + height, ppIBitmap); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateBitmapFromMemory(IWICImagingFactory *iface, + UINT uiWidth, UINT uiHeight, REFWICPixelFormatGUID pixelFormat, UINT cbStride, + UINT cbBufferSize, BYTE *pbBuffer, IWICBitmap **ppIBitmap) +{ + FIXME("(%p,%u,%u,%s,%u,%u,%p,%p): stub\n", iface, uiWidth, uiHeight, + debugstr_guid(pixelFormat), cbStride, cbBufferSize, pbBuffer, ppIBitmap); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateBitmapFromHBITMAP(IWICImagingFactory *iface, + HBITMAP hBitmap, HPALETTE hPalette, WICBitmapAlphaChannelOption options, + IWICBitmap **ppIBitmap) +{ + FIXME("(%p,%p,%p,%u,%p): stub\n", iface, hBitmap, hPalette, options, ppIBitmap); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateBitmapFromHICON(IWICImagingFactory *iface, + HICON hIcon, IWICBitmap **ppIBitmap) +{ + FIXME("(%p,%p,%p): stub\n", iface, hIcon, ppIBitmap); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateComponentEnumerator(IWICImagingFactory *iface, + DWORD componentTypes, DWORD options, IEnumUnknown **ppIEnumUnknown) +{ + FIXME("(%p,%u,%u,%p): stub\n", iface, componentTypes, options, ppIEnumUnknown); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromDecoder( + IWICImagingFactory *iface, IWICBitmapDecoder *pIDecoder, + IWICFastMetadataEncoder **ppIFastEncoder) +{ + FIXME("(%p,%p,%p): stub\n", iface, pIDecoder, ppIFastEncoder); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateFastMetadataEncoderFromFrameDecode( + IWICImagingFactory *iface, IWICBitmapFrameDecode *pIFrameDecoder, + IWICFastMetadataEncoder **ppIFastEncoder) +{ + FIXME("(%p,%p,%p): stub\n", iface, pIFrameDecoder, ppIFastEncoder); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateQueryWriter(IWICImagingFactory *iface, + REFGUID guidMetadataFormat, const GUID *pguidVendor, + IWICMetadataQueryWriter **ppIQueryWriter) +{ + FIXME("(%p,%s,%s,%p): stub\n", iface, debugstr_guid(guidMetadataFormat), + debugstr_guid(pguidVendor), ppIQueryWriter); + return E_NOTIMPL; +} + +static HRESULT WINAPI ImagingFactory_CreateQueryWriterFromReader(IWICImagingFactory *iface, + IWICMetadataQueryReader *pIQueryReader, const GUID *pguidVendor, + IWICMetadataQueryWriter **ppIQueryWriter) +{ + FIXME("(%p,%p,%s,%p): stub\n", iface, pIQueryReader, debugstr_guid(pguidVendor), + ppIQueryWriter); + return E_NOTIMPL; +} + +static const IWICImagingFactoryVtbl ImagingFactory_Vtbl = { + ImagingFactory_QueryInterface, + ImagingFactory_AddRef, + ImagingFactory_Release, + ImagingFactory_CreateDecoderFromFilename, + ImagingFactory_CreateDecoderFromStream, + ImagingFactory_CreateDecoderFromFileHandle, + ImagingFactory_CreateComponentInfo, + ImagingFactory_CreateDecoder, + ImagingFactory_CreateEncoder, + ImagingFactory_CreatePalette, + ImagingFactory_CreateFormatConverter, + ImagingFactory_CreateBitmapScaler, + ImagingFactory_CreateBitmapClipper, + ImagingFactory_CreateBitmapFlipRotator, + ImagingFactory_CreateStream, + ImagingFactory_CreateColorContext, + ImagingFactory_CreateColorTransformer, + ImagingFactory_CreateBitmap, + ImagingFactory_CreateBitmapFromSource, + ImagingFactory_CreateBitmapFromSourceRect, + ImagingFactory_CreateBitmapFromMemory, + ImagingFactory_CreateBitmapFromHBITMAP, + ImagingFactory_CreateBitmapFromHICON, + ImagingFactory_CreateComponentEnumerator, + ImagingFactory_CreateFastMetadataEncoderFromDecoder, + ImagingFactory_CreateFastMetadataEncoderFromFrameDecode, + ImagingFactory_CreateQueryWriter, + ImagingFactory_CreateQueryWriterFromReader +}; + +HRESULT ImagingFactory_CreateInstance(IUnknown *pUnkOuter, REFIID iid, void** ppv) +{ + ImagingFactory *This; + HRESULT ret; + + TRACE("(%p,%s,%p)\n", pUnkOuter, debugstr_guid(iid), ppv); + + *ppv = NULL; + + if (pUnkOuter) return CLASS_E_NOAGGREGATION; + + This = HeapAlloc(GetProcessHeap(), 0, sizeof(ImagingFactory)); + if (!This) return E_OUTOFMEMORY; + + This->lpIWICImagingFactoryVtbl = &ImagingFactory_Vtbl; + This->ref = 1; + + ret = IUnknown_QueryInterface((IUnknown*)This, iid, ppv); + IUnknown_Release((IUnknown*)This); + + return ret; +} diff --git a/dlls/windowscodecs/regsvr.c b/dlls/windowscodecs/regsvr.c new file mode 100644 index 00000000000..fef29799c00 --- /dev/null +++ b/dlls/windowscodecs/regsvr.c @@ -0,0 +1,333 @@ +/* + * Copyright 2009 Vincent Povirk for CodeWeavers + * + * 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 + */ + +#define NONAMELESSUNION +#define NONAMELESSSTRUCT +#define COBJMACROS +#include +#include + +#include "windef.h" +#include "winbase.h" +#include "wingdi.h" +#include "winuser.h" +#include "winreg.h" +#include "winerror.h" + +#include "objbase.h" +#include "ocidl.h" +#include "wincodec.h" + +#include "wine/debug.h" + +WINE_DEFAULT_DEBUG_CHANNEL(wincodecs); + +/*********************************************************************** + * interface for self-registering + */ +struct regsvr_coclass +{ + CLSID const *clsid; /* NULL for end of list */ + LPCSTR name; /* can be NULL to omit */ + LPCSTR ips; /* can be NULL to omit */ + LPCSTR ips32; /* can be NULL to omit */ + LPCSTR ips32_tmodel; /* can be NULL to omit */ + LPCSTR progid; /* can be NULL to omit */ + LPCSTR viprogid; /* can be NULL to omit */ + LPCSTR progid_extra; /* can be NULL to omit */ +}; + +static HRESULT register_coclasses(struct regsvr_coclass const *list); +static HRESULT unregister_coclasses(struct regsvr_coclass const *list); + +/*********************************************************************** + * static string constants + */ +static WCHAR const clsid_keyname[6] = { + 'C', 'L', 'S', 'I', 'D', 0 }; +static WCHAR const curver_keyname[7] = { + 'C', 'u', 'r', 'V', 'e', 'r', 0 }; +static WCHAR const ips_keyname[13] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', + 0 }; +static WCHAR const ips32_keyname[15] = { + 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r', + '3', '2', 0 }; +static WCHAR const progid_keyname[7] = { + 'P', 'r', 'o', 'g', 'I', 'D', 0 }; +static WCHAR const viprogid_keyname[25] = { + 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p', + 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D', + 0 }; +static char const tmodel_valuename[] = "ThreadingModel"; + +/*********************************************************************** + * static helper functions + */ +static LONG register_key_defvalueW(HKEY base, WCHAR const *name, + WCHAR const *value); +static LONG register_key_defvalueA(HKEY base, WCHAR const *name, + char const *value); +static LONG register_progid(WCHAR const *clsid, + char const *progid, char const *curver_progid, + char const *name, char const *extra); + +/*********************************************************************** + * register_coclasses + */ +static HRESULT register_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL); + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + HKEY clsid_key; + + StringFromGUID2(list->clsid, buf, 39); + res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->name) { + res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ, + (CONST BYTE*)(list->name), + strlen(list->name) + 1); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips) { + res = register_key_defvalueA(clsid_key, ips_keyname, list->ips); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->ips32) { + HKEY ips32_key; + + res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, + &ips32_key, NULL); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ, + (CONST BYTE*)list->ips32, + lstrlenA(list->ips32) + 1); + if (res == ERROR_SUCCESS && list->ips32_tmodel) + res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ, + (CONST BYTE*)list->ips32_tmodel, + strlen(list->ips32_tmodel) + 1); + RegCloseKey(ips32_key); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->progid) { + res = register_key_defvalueA(clsid_key, progid_keyname, + list->progid); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = register_progid(buf, list->progid, NULL, + list->name, list->progid_extra); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + if (list->viprogid) { + res = register_key_defvalueA(clsid_key, viprogid_keyname, + list->viprogid); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + + res = register_progid(buf, list->viprogid, list->progid, + list->name, list->progid_extra); + if (res != ERROR_SUCCESS) goto error_close_clsid_key; + } + + error_close_clsid_key: + RegCloseKey(clsid_key); + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * unregister_coclasses + */ +static HRESULT unregister_coclasses(struct regsvr_coclass const *list) +{ + LONG res = ERROR_SUCCESS; + HKEY coclass_key; + + res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, + KEY_READ | KEY_WRITE, &coclass_key); + if (res == ERROR_FILE_NOT_FOUND) return S_OK; + if (res != ERROR_SUCCESS) goto error_return; + + for (; res == ERROR_SUCCESS && list->clsid; ++list) { + WCHAR buf[39]; + + StringFromGUID2(list->clsid, buf, 39); + res = RegDeleteTreeW(coclass_key, buf); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + + if (list->progid) { + res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + + if (list->viprogid) { + res = RegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid); + if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS; + if (res != ERROR_SUCCESS) goto error_close_coclass_key; + } + } + +error_close_coclass_key: + RegCloseKey(coclass_key); +error_return: + return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK; +} + +/*********************************************************************** + * register_key_defvalueW + */ +static LONG register_key_defvalueW( + HKEY base, + WCHAR const *name, + WCHAR const *value) +{ + LONG res; + HKEY key; + + res = RegCreateKeyExW(base, name, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) return res; + res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value, + (lstrlenW(value) + 1) * sizeof(WCHAR)); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * register_key_defvalueA + */ +static LONG register_key_defvalueA( + HKEY base, + WCHAR const *name, + char const *value) +{ + LONG res; + HKEY key; + + res = RegCreateKeyExW(base, name, 0, NULL, 0, + KEY_READ | KEY_WRITE, NULL, &key, NULL); + if (res != ERROR_SUCCESS) return res; + res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value, + lstrlenA(value) + 1); + RegCloseKey(key); + return res; +} + +/*********************************************************************** + * register_progid + */ +static LONG register_progid( + WCHAR const *clsid, + char const *progid, + char const *curver_progid, + char const *name, + char const *extra) +{ + LONG res; + HKEY progid_key; + + res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0, + NULL, 0, KEY_READ | KEY_WRITE, NULL, + &progid_key, NULL); + if (res != ERROR_SUCCESS) return res; + + if (name) { + res = RegSetValueExA(progid_key, NULL, 0, REG_SZ, + (CONST BYTE*)name, strlen(name) + 1); + if (res != ERROR_SUCCESS) goto error_close_progid_key; + } + + if (clsid) { + res = register_key_defvalueW(progid_key, clsid_keyname, clsid); + if (res != ERROR_SUCCESS) goto error_close_progid_key; + } + + if (curver_progid) { + res = register_key_defvalueA(progid_key, curver_keyname, + curver_progid); + if (res != ERROR_SUCCESS) goto error_close_progid_key; + } + + if (extra) { + HKEY extra_key; + + res = RegCreateKeyExA(progid_key, extra, 0, + NULL, 0, KEY_READ | KEY_WRITE, NULL, + &extra_key, NULL); + if (res == ERROR_SUCCESS) + RegCloseKey(extra_key); + } + +error_close_progid_key: + RegCloseKey(progid_key); + return res; +} + +/*********************************************************************** + * coclass list + */ +static struct regsvr_coclass const coclass_list[] = { + { &CLSID_WICImagingFactory, + "WIC Imaging Factory", + NULL, + "windowscodecs.dll", + "Apartment" + }, + { NULL } /* list terminator */ +}; + +HRESULT WINAPI DllRegisterServer(void) +{ + HRESULT hr; + + TRACE("\n"); + + hr = register_coclasses(coclass_list); + return hr; +} + +HRESULT WINAPI DllUnregisterServer(void) +{ + HRESULT hr; + + TRACE("\n"); + + hr = unregister_coclasses(coclass_list); + return hr; +} diff --git a/dlls/windowscodecs/wincodecs_private.h b/dlls/windowscodecs/wincodecs_private.h new file mode 100644 index 00000000000..b4539208d5e --- /dev/null +++ b/dlls/windowscodecs/wincodecs_private.h @@ -0,0 +1,24 @@ +/* + * Copyright 2009 Vincent Povirk for CodeWeavers + * + * 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 WINCODECS_PRIVATE_H +#define WINCODECS_PRIVATE_H + +extern HRESULT ImagingFactory_CreateInstance(IUnknown *pUnkOuter, REFIID riid, void** ppv); + +#endif /* WINCODECS_PRIVATE_H */ diff --git a/dlls/windowscodecs/windowscodecs.spec b/dlls/windowscodecs/windowscodecs.spec index 8fc2026a1b4..8e3729eb4f1 100644 --- a/dlls/windowscodecs/windowscodecs.spec +++ b/dlls/windowscodecs/windowscodecs.spec @@ -1,4 +1,6 @@ -@ stub DllGetClassObject +@ stdcall -private DllGetClassObject(ptr ptr ptr) +@ stdcall -private DllRegisterServer() +@ stdcall -private DllUnregisterServer() @ stub IEnumString_Next_WIC_Proxy @ stub IEnumString_Reset_WIC_Proxy @ stub IPropertyBag2_Write_Proxy diff --git a/tools/wine.inf.in b/tools/wine.inf.in index 7e6ae73a09c..cd9e60956fe 100644 --- a/tools/wine.inf.in +++ b/tools/wine.inf.in @@ -2427,6 +2427,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G" 11,,rsaenh.dll,1 11,,shdocvw.dll,1 11,,urlmon.dll,1 +11,,windowscodecs.dll,1 11,,wintrust.dll,1 11,,wuapi.dll,1