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 } 36 return TRUE; 37 } 38 39 /****************************************************************************** 40 * DirectShow ClassFactory 41 */ 42 typedef struct { 43 IClassFactory IClassFactory_iface; 44 LONG ref; 45 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); 46 } IClassFactoryImpl; 47 48 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) 49 { 50 return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); 51 } 52 53 struct object_creation_info 54 { 55 const CLSID *clsid; 56 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); 57 }; 58 59 static const struct object_creation_info object_creation[] = 60 { 61 { &CLSID_AMTimeline, AMTimeline_create }, 62 { &CLSID_MediaDet, MediaDet_create }, 63 { &CLSID_SampleGrabber, SampleGrabber_create }, 64 }; 65 66 static HRESULT WINAPI DSCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) 67 { 68 if (IsEqualGUID(riid, &IID_IUnknown) 69 || IsEqualGUID(riid, &IID_IClassFactory)) 70 { 71 IClassFactory_AddRef(iface); 72 *ppobj = iface; 73 return S_OK; 74 } 75 76 *ppobj = NULL; 77 WARN("(%p)->(%s,%p), not found\n", iface, debugstr_guid(riid), ppobj); 78 return E_NOINTERFACE; 79 } 80 81 static ULONG WINAPI DSCF_AddRef(IClassFactory *iface) 82 { 83 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 84 return InterlockedIncrement(&This->ref); 85 } 86 87 static ULONG WINAPI DSCF_Release(IClassFactory *iface) 88 { 89 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 90 ULONG ref = InterlockedDecrement(&This->ref); 91 92 if (ref == 0) 93 CoTaskMemFree(This); 94 95 return ref; 96 } 97 98 static HRESULT WINAPI DSCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, REFIID riid, 99 void **ppobj) 100 { 101 IClassFactoryImpl *This = impl_from_IClassFactory(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(IClassFactory *iface, BOOL dolock) 120 { 121 IClassFactoryImpl *This = impl_from_IClassFactory(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_FALSE; 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 < ARRAY_SIZE(object_creation); i++) 171 { 172 if (IsEqualGUID(object_creation[i].clsid, rclsid)) 173 break; 174 } 175 176 if (i == ARRAY_SIZE(object_creation)) 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->IClassFactory_iface.lpVtbl = &DSCF_Vtbl; 186 factory->ref = 1; 187 188 factory->pfnCreateInstance = object_creation[i].pfnCreateInstance; 189 190 *ppv = &factory->IClassFactory_iface; 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 } 209