From e071823484b0948daa6914da203e257a16df1eb3 Mon Sep 17 00:00:00 2001 From: John Klehm Date: Fri, 28 Sep 2007 07:18:32 -0500 Subject: [PATCH] inkobj: Implement IClassFactory --- dlls/inkobj/Makefile.in | 3 +- dlls/inkobj/inkobj_classfactory.c | 125 +++++++++++++++++++++++++++++++++++++ dlls/inkobj/inkobj_internal.h | 19 +++++- dlls/inkobj/regsvr.c | 15 +---- 4 files changed, 146 insertions(+), 16 deletions(-) create mode 100644 dlls/inkobj/inkobj_classfactory.c diff --git a/dlls/inkobj/Makefile.in b/dlls/inkobj/Makefile.in index e914a8e..91e6eaf 100644 --- a/dlls/inkobj/Makefile.in +++ b/dlls/inkobj/Makefile.in @@ -7,7 +7,8 @@ IMPORTS = advapi32 kernel32 ole32 user32 C_SRCS = \ inkobj.c \ - regsvr.c + regsvr.c \ + inkobj_classfactory.c @MAKE_DLL_RULES@ diff --git a/dlls/inkobj/inkobj_classfactory.c b/dlls/inkobj/inkobj_classfactory.c new file mode 100644 index 0000000..aca22d0 --- /dev/null +++ b/dlls/inkobj/inkobj_classfactory.c @@ -0,0 +1,125 @@ +/* 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! */ + + LONG 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; + } + + FIXME("interface %s not implemented\n", debugstr_guid(riid)); + return E_NOINTERFACE; +} + +static ULONG WINAPI ClassFactory_AddRef(IClassFactory* This) +{ + TRACE("refCount=%i before increment\n", ( (ClassFactory*)This )->refCount); + + return InterlockedIncrement(&( ((ClassFactory*)This)->refCount )); +} + +static ULONG WINAPI ClassFactory_Release(IClassFactory* This) +{ + TRACE("refCount=%i before decrement\n", ( (ClassFactory*)This )->refCount); + + if (InterlockedDecrement(&( ((ClassFactory*)This)->refCount )) == 0) + { + HeapFree(GetProcessHeap(), 0, This); + InterlockedDecrement(&INKOBJ_refCount); + return 0; /* This->refCount == 0 */ + } + + return ( (ClassFactory*)This )->refCount; +} + +static HRESULT WINAPI ClassFactory_CreateInstance( + IClassFactory* This, IUnknown* pUnkOuter, REFIID riid, void** ppvObject) +{ + return ( (ClassFactory*)This )->fnCreateInstance( + pUnkOuter, riid, ppvObject); +} + +static HRESULT WINAPI ClassFactory_LockServer(IClassFactory* This, BOOL doLock) +{ + TRACE("this=%p, doLock=%x, refCount=%i\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* ret = HeapAlloc(GetProcessHeap(), 0, sizeof(ClassFactory)); + HRESULT result = E_NOINTERFACE; + + ret->lpVtbl = &InkCollectorClassFactoryVtbl; + ret->refCount = 0; + ret->fnCreateInstance = fnCreateInstance; + + result = IClassFactory_QueryInterface((IClassFactory*)ret, riid, ppvObject); + if (SUCCEEDED(result)) + { + InterlockedIncrement(&INKOBJ_refCount); + } + else + { + HeapFree(GetProcessHeap(), 0, ret); + *ppvObject = NULL; + } + + return result; +} diff --git a/dlls/inkobj/inkobj_internal.h b/dlls/inkobj/inkobj_internal.h index 24bbf26..ed6ed80 100644 --- a/dlls/inkobj/inkobj_internal.h +++ b/dlls/inkobj/inkobj_internal.h @@ -22,9 +22,14 @@ #include #include #include +#include -#include +#define COBJMACROS +#include +#include +#include +#include /* * start inkobj.c declaration @@ -36,5 +41,17 @@ extern HINSTANCE INKOBJ_hInstance; /* * end inkobj.c declarations */ +/* + * start inkobj_classfactory.c declarations + */ + +typedef HRESULT (*CreateInstanceFunc)(IUnknown*,REFIID,void**); + +extern HRESULT ClassFactory_Create( + REFIID riid, void** ppvObject, CreateInstanceFunc fnCreateInstance); + +/* + * end inkobj_classfactory.c declarations + */ #endif /* INKOBJ_INTERNAL_H */ diff --git a/dlls/inkobj/regsvr.c b/dlls/inkobj/regsvr.c index 5f5b8c6..9b4c2d2 100644 --- a/dlls/inkobj/regsvr.c +++ b/dlls/inkobj/regsvr.c @@ -18,21 +18,8 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */ -#include - -#include -#include -#include -#include -#include -#include #include -#include - -#include - -#include - +#include "inkobj_internal.h" WINE_DEFAULT_DEBUG_CHANNEL(inkobj); -- 1.5.2.5