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 22 #include <rpcproxy.h> 23 24 static HINSTANCE instance; 25 26 BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv) 27 { 28 switch(fdwReason) { 29 case DLL_PROCESS_ATTACH: 30 instance = hInstDLL; 31 DisableThreadLibraryCalls(hInstDLL); 32 break; 33 } 34 return TRUE; 35 } 36 37 /****************************************************************************** 38 * DirectShow ClassFactory 39 */ 40 typedef struct { 41 IClassFactory IClassFactory_iface; 42 LONG ref; 43 HRESULT (*pfnCreateInstance)(IUnknown *pUnkOuter, LPVOID *ppObj); 44 } IClassFactoryImpl; 45 46 static inline IClassFactoryImpl *impl_from_IClassFactory(IClassFactory *iface) 47 { 48 return CONTAINING_RECORD(iface, IClassFactoryImpl, IClassFactory_iface); 49 } 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_AMTimeline, AMTimeline_create }, 60 { &CLSID_MediaDet, MediaDet_create }, 61 { &CLSID_SampleGrabber, SampleGrabber_create }, 62 }; 63 64 static HRESULT WINAPI DSCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) 65 { 66 if (IsEqualGUID(riid, &IID_IUnknown) 67 || IsEqualGUID(riid, &IID_IClassFactory)) 68 { 69 IClassFactory_AddRef(iface); 70 *ppobj = iface; 71 return S_OK; 72 } 73 74 *ppobj = NULL; 75 WARN("(%p)->(%s,%p), not found\n", iface, debugstr_guid(riid), ppobj); 76 return E_NOINTERFACE; 77 } 78 79 static ULONG WINAPI DSCF_AddRef(IClassFactory *iface) 80 { 81 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 82 return InterlockedIncrement(&This->ref); 83 } 84 85 static ULONG WINAPI DSCF_Release(IClassFactory *iface) 86 { 87 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 88 ULONG ref = InterlockedDecrement(&This->ref); 89 90 if (ref == 0) 91 CoTaskMemFree(This); 92 93 return ref; 94 } 95 96 static HRESULT WINAPI DSCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, REFIID riid, 97 void **ppobj) 98 { 99 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 100 HRESULT hres; 101 LPUNKNOWN punk; 102 103 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); 104 105 *ppobj = NULL; 106 if (pOuter && !IsEqualGUID(&IID_IUnknown, riid)) 107 return E_INVALIDARG; 108 109 hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk); 110 if (SUCCEEDED(hres)) { 111 hres = IUnknown_QueryInterface(punk, riid, ppobj); 112 IUnknown_Release(punk); 113 } 114 return hres; 115 } 116 117 static HRESULT WINAPI DSCF_LockServer(IClassFactory *iface, BOOL dolock) 118 { 119 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 120 FIXME("(%p)->(%d),stub!\n",This,dolock); 121 return S_OK; 122 } 123 124 static const IClassFactoryVtbl DSCF_Vtbl = 125 { 126 DSCF_QueryInterface, 127 DSCF_AddRef, 128 DSCF_Release, 129 DSCF_CreateInstance, 130 DSCF_LockServer 131 }; 132 133 134 /*********************************************************************** 135 * DllCanUnloadNow (QEDIT.@) 136 */ 137 HRESULT WINAPI DllCanUnloadNow(void) 138 { 139 return S_FALSE; 140 } 141 142 /******************************************************************************* 143 * DllGetClassObject [QEDIT.@] 144 * Retrieves class object from a DLL object 145 * 146 * PARAMS 147 * rclsid [I] CLSID for the class object 148 * riid [I] Reference to identifier of interface for class object 149 * ppv [O] Address of variable to receive interface pointer for riid 150 * 151 * RETURNS 152 * Success: S_OK 153 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG, 154 * E_UNEXPECTED, E_NOINTERFACE 155 */ 156 157 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 158 { 159 unsigned int i; 160 IClassFactoryImpl *factory; 161 162 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); 163 164 if ( !IsEqualGUID( &IID_IClassFactory, riid ) 165 && ! IsEqualGUID( &IID_IUnknown, riid) ) 166 return E_NOINTERFACE; 167 168 for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) 169 { 170 if (IsEqualGUID(object_creation[i].clsid, rclsid)) 171 break; 172 } 173 174 if (i == sizeof(object_creation)/sizeof(object_creation[0])) 175 { 176 FIXME("%s: no class found.\n", debugstr_guid(rclsid)); 177 return CLASS_E_CLASSNOTAVAILABLE; 178 } 179 180 factory = CoTaskMemAlloc(sizeof(*factory)); 181 if (factory == NULL) return E_OUTOFMEMORY; 182 183 factory->IClassFactory_iface.lpVtbl = &DSCF_Vtbl; 184 factory->ref = 1; 185 186 factory->pfnCreateInstance = object_creation[i].pfnCreateInstance; 187 188 *ppv = &factory->IClassFactory_iface; 189 return S_OK; 190 } 191 192 /*********************************************************************** 193 * DllRegisterServer (QEDIT.@) 194 */ 195 HRESULT WINAPI DllRegisterServer(void) 196 { 197 return __wine_register_resources( instance ); 198 } 199 200 /*********************************************************************** 201 * DllUnregisterServer (QEDIT.@) 202 */ 203 HRESULT WINAPI DllUnregisterServer(void) 204 { 205 return __wine_unregister_resources( instance ); 206 } 207