1 /*
2  * COPYRIGHT:       See COPYING in the top level directory
3  * PROJECT:         ReactOS BDA Proxy
4  * FILE:            dll/directx/bdaplgin/classfactory.cpp
5  * PURPOSE:         ClassFactory interface
6  *
7  * PROGRAMMERS:     Johannes Anderwald (johannes.anderwald@reactos.org)
8  */
9 #include "precomp.h"
10 
11 const GUID IID_IUnknown           = {0x00000000, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
12 const GUID IID_IClassFactory      = {0x00000001, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
13 
14 class CClassFactory : public IClassFactory
15 {
16 public:
17     STDMETHODIMP QueryInterface( REFIID InterfaceId, PVOID* Interface);
18 
19     STDMETHODIMP_(ULONG) AddRef()
20     {
21         InterlockedIncrement(&m_Ref);
22         return m_Ref;
23     }
24     STDMETHODIMP_(ULONG) Release()
25     {
26         InterlockedDecrement(&m_Ref);
27         if (!m_Ref)
28         {
29             delete this;
30             return 0;
31         }
32         return m_Ref;
33     }
34 
35     HRESULT WINAPI CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, LPVOID *ppvObject);
36     HRESULT WINAPI LockServer(BOOL fLock);
37 
38     CClassFactory(LPFNCREATEINSTANCE lpfnCI, PLONG pcRefDll, IID *riidInst) : m_Ref(1), m_lpfnCI(lpfnCI), m_IID(riidInst)
39     {};
40 
41     virtual ~CClassFactory(){};
42 
43 protected:
44     LONG m_Ref;
45     LPFNCREATEINSTANCE m_lpfnCI;
46     IID * m_IID;
47 };
48 
49 HRESULT
50 WINAPI
51 CClassFactory::QueryInterface(
52     REFIID riid,
53     LPVOID *ppvObj)
54 {
55     *ppvObj = NULL;
56     if(IsEqualIID(riid, IID_IUnknown) || IsEqualIID(riid, IID_IClassFactory))
57     {
58         *ppvObj = PVOID(this);
59         InterlockedIncrement(&m_Ref);
60         return S_OK;
61     }
62     return E_NOINTERFACE;
63 }
64 
65 HRESULT
66 WINAPI
67 CClassFactory::CreateInstance(
68     LPUNKNOWN pUnkOuter,
69     REFIID riid,
70     LPVOID *ppvObject)
71 {
72     *ppvObject = NULL;
73 
74     if ( m_IID == NULL || IsEqualCLSID(riid, *m_IID) || IsEqualCLSID(riid, IID_IUnknown))
75     {
76         return m_lpfnCI(pUnkOuter, riid, ppvObject);
77     }
78 
79     return E_NOINTERFACE;
80 }
81 
82 HRESULT
83 WINAPI
84 CClassFactory::LockServer(
85     BOOL fLock)
86 {
87     return E_NOTIMPL;
88 }
89 
90 IClassFactory *
91 CClassFactory_fnConstructor(
92     LPFNCREATEINSTANCE lpfnCI,
93     PLONG pcRefDll,
94     IID * riidInst)
95 {
96     CClassFactory* factory = new CClassFactory(lpfnCI, pcRefDll, riidInst);
97 
98     if (!factory)
99         return NULL;
100 
101     if (pcRefDll)
102         InterlockedIncrement(pcRefDll);
103 
104     return (LPCLASSFACTORY)factory;
105 }
106