[1/9] windowscodecs: add stub implementation of IWICImagingFactory

Vincent Povirk madewokherd+8cd9 at gmail.com
Sat Jun 27 20:48:55 CDT 2009


Vincent Povirk
-------------- next part --------------
From 3a92f79254b10d43c5b46e33e9b74fbd893c6a8d Mon Sep 17 00:00:00 2001
From: Vincent Povirk <vincent at codeweavers.com>
Date: Mon, 1 Jun 2009 13:32:41 -0500
Subject: [PATCH 1/9] windowscodecs: add stub implementation of IWICImagingFactory

---
 dlls/windowscodecs/Makefile.in         |    5 +-
 dlls/windowscodecs/clsfactory.c        |  171 ++++++++++++++++
 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(+), 2 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 1449089..7e6f97c 100644
--- a/dlls/windowscodecs/Makefile.in
+++ b/dlls/windowscodecs/Makefile.in
@@ -3,9 +3,12 @@ TOPOBJDIR = ../..
 SRCDIR    = @srcdir@
 VPATH     = @srcdir@
 MODULE    = windowscodecs.dll
-IMPORTS   = kernel32
+IMPORTS   = kernel32 uuid advapi32 ole32
 
 C_SRCS = \
+	clsfactory.c \
+	imgfactory.c \
+	regsvr.c \
 	main.c
 
 @MAKE_DLL_RULES@
diff --git a/dlls/windowscodecs/clsfactory.c b/dlls/windowscodecs/clsfactory.c
new file mode 100644
index 0000000..103f928
--- /dev/null
+++ b/dlls/windowscodecs/clsfactory.c
@@ -0,0 +1,171 @@
+/*
+ * 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 @@ 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
 
-- 
1.6.3.1


More information about the wine-patches mailing list