windowscodecs: Add stub implementation of IWICImagingFactory.
diff --git a/dlls/windowscodecs/Makefile.in b/dlls/windowscodecs/Makefile.in
index 1449089..05d5521 100644
--- a/dlls/windowscodecs/Makefile.in
+++ b/dlls/windowscodecs/Makefile.in
@@ -3,10 +3,13 @@
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 0000000..b74746c
--- /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 <stdarg.h>
+
+#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 0000000..f422a8a
--- /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 <stdarg.h>
+
+#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 0000000..fef2979
--- /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 <stdarg.h>
+#include <string.h>
+
+#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 0000000..b453920
--- /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 8fc2026..8e3729e 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 7e6ae73..cd9e609 100644
--- a/tools/wine.inf.in
+++ b/tools/wine.inf.in
@@ -2427,6 +2427,7 @@
11,,rsaenh.dll,1
11,,shdocvw.dll,1
11,,urlmon.dll,1
+11,,windowscodecs.dll,1
11,,wintrust.dll,1
11,,wuapi.dll,1