kernel32: Clear the module handle on failure in GetModuleHandleEx.
[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     hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk);
109     if (SUCCEEDED(hres)) {
110         hres = IUnknown_QueryInterface(punk, riid, ppobj);
111         IUnknown_Release(punk);
112     }
113     return hres;
114 }
115
116 static HRESULT WINAPI DSCF_LockServer(LPCLASSFACTORY iface, BOOL dolock)
117 {
118     IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
119     FIXME("(%p)->(%d),stub!\n",This,dolock);
120     return S_OK;
121 }
122
123 static const IClassFactoryVtbl DSCF_Vtbl =
124 {
125     DSCF_QueryInterface,
126     DSCF_AddRef,
127     DSCF_Release,
128     DSCF_CreateInstance,
129     DSCF_LockServer
130 };
131
132
133 /***********************************************************************
134  *              DllCanUnloadNow (QEDIT.@)
135  */
136 HRESULT WINAPI DllCanUnloadNow(void)
137 {
138     return S_OK;
139 }
140
141 /*******************************************************************************
142  * DllGetClassObject [QEDIT.@]
143  * Retrieves class object from a DLL object
144  *
145  * PARAMS
146  *    rclsid [I] CLSID for the class object
147  *    riid   [I] Reference to identifier of interface for class object
148  *    ppv    [O] Address of variable to receive interface pointer for riid
149  *
150  * RETURNS
151  *    Success: S_OK
152  *    Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG,
153  *             E_UNEXPECTED, E_NOINTERFACE
154  */
155
156 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv)
157 {
158     unsigned int i;
159     IClassFactoryImpl *factory;
160
161     TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
162
163     if ( !IsEqualGUID( &IID_IClassFactory, riid )
164          && ! IsEqualGUID( &IID_IUnknown, riid) )
165         return E_NOINTERFACE;
166
167     for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++)
168     {
169         if (IsEqualGUID(object_creation[i].clsid, rclsid))
170             break;
171     }
172
173     if (i == sizeof(object_creation)/sizeof(object_creation[0]))
174     {
175         FIXME("%s: no class found.\n", debugstr_guid(rclsid));
176         return CLASS_E_CLASSNOTAVAILABLE;
177     }
178
179     factory = CoTaskMemAlloc(sizeof(*factory));
180     if (factory == NULL) return E_OUTOFMEMORY;
181
182     factory->ITF_IClassFactory.lpVtbl = &DSCF_Vtbl;
183     factory->ref = 1;
184
185     factory->pfnCreateInstance = object_creation[i].pfnCreateInstance;
186
187     *ppv = &(factory->ITF_IClassFactory);
188     return S_OK;
189 }
190
191 /***********************************************************************
192  *              DllRegisterServer (QEDIT.@)
193  */
194 HRESULT WINAPI DllRegisterServer(void)
195 {
196     return __wine_register_resources( instance );
197 }
198
199 /***********************************************************************
200  *              DllUnregisterServer (QEDIT.@)
201  */
202 HRESULT WINAPI DllUnregisterServer(void)
203 {
204     return __wine_unregister_resources( instance );
205 }