gdiplus: Add a test for image stream refcount.
[wine] / dlls / qedit / main.c
1 /*              DirectShow Editing Services (qedit.dll)
2  *
3  * Copyright 2008 Google (Lei Zhang)
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
18  */
19
20 #include "qedit_private.h"
21 #include "rpcproxy.h"
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(qedit);
25
26 static HINSTANCE instance;
27
28 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
29 {
30     switch(fdwReason) {
31         case DLL_PROCESS_ATTACH:
32             instance = hInstDLL;
33             DisableThreadLibraryCalls(hInstDLL);
34             break;
35         case DLL_PROCESS_DETACH:
36             break;
37     }
38     return TRUE;
39 }
40
41 /******************************************************************************
42  * DirectShow ClassFactory
43  */
44 typedef struct {
45     IClassFactory ITF_IClassFactory;
46
47     LONG ref;
48     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
49 } IClassFactoryImpl;
50
51 struct object_creation_info
52 {
53     const CLSID *clsid;
54     HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj);
55 };
56
57 static const struct object_creation_info object_creation[] =
58 {
59     { &CLSID_MediaDet, MediaDet_create },
60     { &CLSID_SampleGrabber, SampleGrabber_create },
61 };
62
63 static HRESULT WINAPI
64 DSCF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj)
65 {
66     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
67
68     if (IsEqualGUID(riid, &IID_IUnknown)
69         || IsEqualGUID(riid, &IID_IClassFactory))
70     {
71         IClassFactory_AddRef(iface);
72         *ppobj = This;
73         return S_OK;
74     }
75
76     *ppobj = NULL;
77     WARN("(%p)->(%s,%p),not found\n",This,debugstr_guid(riid),ppobj);
78     return E_NOINTERFACE;
79 }
80
81 static ULONG WINAPI DSCF_AddRef(LPCLASSFACTORY iface)
82 {
83     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
84     return InterlockedIncrement(&This->ref);
85 }
86
87 static ULONG WINAPI DSCF_Release(LPCLASSFACTORY iface)
88 {
89     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
90
91     ULONG ref = InterlockedDecrement(&This->ref);
92
93     if (ref == 0)
94         CoTaskMemFree(This);
95
96     return ref;
97 }
98
99 static HRESULT WINAPI DSCF_CreateInstance(LPCLASSFACTORY iface, LPUNKNOWN pOuter, REFIID riid, LPVOID *ppobj)
100 {
101     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
102     HRESULT hres;
103     LPUNKNOWN punk;
104
105     TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
106
107     *ppobj = NULL;
108     if (pOuter && !IsEqualGUID(&IID_IUnknown, riid))
109         return E_INVALIDARG;
110
111     hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk);
112     if (SUCCEEDED(hres)) {
113         hres = IUnknown_QueryInterface(punk, riid, ppobj);
114         IUnknown_Release(punk);
115     }
116     return hres;
117 }
118
119 static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
120 {
121     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
122     FIXME("(%p)->(%d),stub!\n",This,dolock);
123     return S_OK;
124 }
125
126 static const IClassFactoryVtbl DSCF_Vtbl =
127 {
128     DSCF_QueryInterface,
129     DSCF_AddRef,
130     DSCF_Release,
131     DSCF_CreateInstance,
132     DSCF_LockServer
133 };
134
135
136 /***********************************************************************
137  *              DllCanUnloadNow (QEDIT.@)
138  */
139 HRESULT WINAPI DllCanUnloadNow(void)
140 {
141     return S_OK;
142 }
143
144 /*******************************************************************************
145  * DllGetClassObject [QEDIT.@]
146  * Retrieves class object from a DLL object
147  *
148  * PARAMS
149  *    rclsid [I] CLSID for the class object
150  *    riid   [I] Reference to identifier of interface for class object
151  *    ppv    [O] Address of variable to receive interface pointer for riid
152  *
153  * RETURNS
154  *    Success: S_OK
155  *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
156  *             E_UNEXPECTED, E_NOINTERFACE
157  */
158
159 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
160 {
161     unsigned int i;
162     IClassFactoryImpl *factory;
163
164     TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
165
166     if ( !IsEqualGUID( &IID_IClassFactory, riid )
167          && ! IsEqualGUID( &IID_IUnknown, riid) )
168         return E_NOINTERFACE;
169
170     for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
171     {
172         if (IsEqualGUID(object_creation[i].clsid, rclsid))
173             break;
174     }
175
176     if (i == sizeof(object_creation)/sizeof(object_creation[0]))
177     {
178         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
179         return CLASS_E_CLASSNOTAVAILABLE;
180     }
181
182     factory = CoTaskMemAlloc(sizeof(*factory));
183     if (factory == NULL) return E_OUTOFMEMORY;
184
185     factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl;
186     factory->ref = 1;
187
188     factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
189
190     *ppv = &(factory->ITF_IClassFactory);
191     return S_OK;
192 }
193
194 /***********************************************************************
195  *              DllRegisterServer (QEDIT.@)
196  */
197 HRESULT WINAPI DllRegisterServer(void)
198 {
199     return __wine_register_resources( instance );
200 }
201
202 /***********************************************************************
203  *              DllUnregisterServer (QEDIT.@)
204  */
205 HRESULT WINAPI DllUnregisterServer(void)
206 {
207     return __wine_unregister_resources( instance );
208 }