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