From 3cb242d2708b3fc7f38aa3cf0c2172d0f01ba1e6 Mon Sep 17 00:00:00 2001 From: John Klehm Date: Mon, 25 Feb 2008 05:56:44 -0600 Subject: Implement class factory --- dlls/inkobj/classfactory.c | 135 +++++++++++++++++++++++++++++++++++++++++ dlls/inkobj/inkobj.c | 1 + dlls/inkobj/inkobj_internal.h | 5 ++ 3 files changed, 141 insertions(+), 0 deletions(-) create mode 100644 dlls/inkobj/classfactory.c diff --git a/dlls/inkobj/classfactory.c b/dlls/inkobj/classfactory.c new file mode 100644 index 0000000..4cb302f --- /dev/null +++ b/dlls/inkobj/classfactory.c @@ -0,0 +1,135 @@ +/* Copyright (C) 2007 C John Klehm + * + * 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 "inkobj_internal.h" + +WINE_DEFAULT_DEBUG_CHANNEL(inkobj); + + +/* ClassFactory object - declare internal data members here */ +typedef struct tagClassFactory +{ + const IClassFactoryVtbl* lpVtbl; + /* lpVtbl must be first! */ + + ULONG refCount; + CreateInstanceFunc fnCreateInstance; +} ClassFactory; + +static HRESULT WINAPI ClassFactory_QueryInterface( + IClassFactory* This, REFIID riid, void** ppvObject) +{ + *ppvObject = NULL; + + if (IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IClassFactory)) + { + IClassFactory_AddRef(This); + *ppvObject = This; + return S_OK; + } + + WARN("riid=%s is not supported.\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI ClassFactory_AddRef(IClassFactory* This) +{ + ClassFactory* privateThis = (ClassFactory*)This; + ULONG newRefCount = InterlockedIncrement(&(privateThis->refCount)); + + TRACE("refCount=%i after increment\n", newRefCount); + + return newRefCount; +} + +static ULONG WINAPI ClassFactory_Release(IClassFactory* This) +{ + ClassFactory* privateThis = (ClassFactory*)This; + ULONG newRefCount = InterlockedDecrement(&(privateThis->refCount)); + + TRACE("refCount=%i after decrement\n", newRefCount); + + if (0 == newRefCount) + { + HeapFree(GetProcessHeap(), 0, This); + InterlockedDecrement(&INKOBJ_refCount); + } + + return newRefCount; +} + +static HRESULT WINAPI ClassFactory_CreateInstance( + IClassFactory* This, IUnknown* pUnkOuter, REFIID riid, void** ppvObject) +{ + ClassFactory* privateThis = (ClassFactory*)This; + + return privateThis->fnCreateInstance( + pUnkOuter, riid, ppvObject); +} + +static HRESULT WINAPI ClassFactory_LockServer(IClassFactory* This, BOOL doLock) +{ + TRACE("this=%p, doLock=%x, INKOBJ_refCount=%i before change\n", + This, doLock, INKOBJ_refCount); + + if (doLock) + { + InterlockedIncrement(&INKOBJ_refCount); + } + else + { + InterlockedDecrement(&INKOBJ_refCount); + } + + return S_OK; +} + +static const IClassFactoryVtbl InkCollectorClassFactoryVtbl = +{ + ClassFactory_QueryInterface, + ClassFactory_AddRef, + ClassFactory_Release, + ClassFactory_CreateInstance, + ClassFactory_LockServer +}; + +HRESULT ClassFactory_Create(REFIID riid, void** ppvObject, + CreateInstanceFunc fnCreateInstance) +{ + ClassFactory* newCFObject = HeapAlloc( + GetProcessHeap(), 0, sizeof(ClassFactory)); + HRESULT result = E_NOINTERFACE; + + newCFObject->lpVtbl = &InkCollectorClassFactoryVtbl; + newCFObject->refCount = 0; + newCFObject->fnCreateInstance = fnCreateInstance; + + result = IClassFactory_QueryInterface( + (IClassFactory*)newCFObject, riid, ppvObject); + if (SUCCEEDED(result)) + { + InterlockedIncrement(&INKOBJ_refCount); + } + else + { + HeapFree(GetProcessHeap(), 0, newCFObject); + *ppvObject = NULL; + } + + return result; +} diff --git a/dlls/inkobj/inkobj.c b/dlls/inkobj/inkobj.c index 8cddeb7..4f0997d 100644 --- a/dlls/inkobj/inkobj.c +++ b/dlls/inkobj/inkobj.c @@ -15,6 +15,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ +#include "initguid.h" #include "inkobj_internal.h" WINE_DEFAULT_DEBUG_CHANNEL(inkobj); diff --git a/dlls/inkobj/inkobj_internal.h b/dlls/inkobj/inkobj_internal.h index cfd9b5b..0d8c2ba 100644 --- a/dlls/inkobj/inkobj_internal.h +++ b/dlls/inkobj/inkobj_internal.h @@ -33,4 +33,9 @@ extern LONG INKOBJ_refCount; extern HINSTANCE INKOBJ_hInstance; +typedef HRESULT (*CreateInstanceFunc) + (IUnknown* This, REFIID riid, void** ppvObject); +extern HRESULT ClassFactory_Create( + REFIID riid, void** ppvObject, CreateInstanceFunc fnCreateInstance); + #endif /* INKOBJ_INTERNAL_H */ -- 1.5.4.2