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 "amstream_private.h" 22 23 #include <rpcproxy.h> 24 25 static HINSTANCE instance; 26 27 /* For the moment, do nothing here. */ 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 * Multimedia Streams 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_AMMultiMediaStream, AM_create }, 62 { &CLSID_AMDirectDrawStream, AM_create }, 63 { &CLSID_AMAudioData, AMAudioData_create }, 64 { &CLSID_MediaStreamFilter, MediaStreamFilter_create } 65 }; 66 67 static HRESULT WINAPI AMCF_QueryInterface(IClassFactory *iface, REFIID riid, void **ppobj) 68 { 69 if (IsEqualGUID(riid, &IID_IUnknown) 70 || IsEqualGUID(riid, &IID_IClassFactory)) 71 { 72 IClassFactory_AddRef(iface); 73 *ppobj = iface; 74 return S_OK; 75 } 76 77 *ppobj = NULL; 78 WARN("(%p)->(%s,%p), not found\n", iface, debugstr_guid(riid), ppobj); 79 return E_NOINTERFACE; 80 } 81 82 static ULONG WINAPI AMCF_AddRef(IClassFactory *iface) 83 { 84 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 85 return InterlockedIncrement(&This->ref); 86 } 87 88 static ULONG WINAPI AMCF_Release(IClassFactory *iface) 89 { 90 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 91 ULONG ref = InterlockedDecrement(&This->ref); 92 93 if (ref == 0) 94 HeapFree(GetProcessHeap(), 0, This); 95 96 return ref; 97 } 98 99 100 static HRESULT WINAPI AMCF_CreateInstance(IClassFactory *iface, IUnknown *pOuter, 101 REFIID riid, void **ppobj) 102 { 103 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 104 HRESULT hres; 105 LPUNKNOWN punk; 106 107 TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj); 108 109 *ppobj = NULL; 110 hres = This->pfnCreateInstance(pOuter, (LPVOID *) &punk); 111 if (SUCCEEDED(hres)) { 112 hres = IUnknown_QueryInterface(punk, riid, ppobj); 113 IUnknown_Release(punk); 114 } 115 return hres; 116 } 117 118 static HRESULT WINAPI AMCF_LockServer(IClassFactory *iface, BOOL dolock) 119 { 120 IClassFactoryImpl *This = impl_from_IClassFactory(iface); 121 FIXME("(%p)->(%d),stub!\n",This,dolock); 122 return S_OK; 123 } 124 125 static const IClassFactoryVtbl DSCF_Vtbl = 126 { 127 AMCF_QueryInterface, 128 AMCF_AddRef, 129 AMCF_Release, 130 AMCF_CreateInstance, 131 AMCF_LockServer 132 }; 133 134 /******************************************************************************* 135 * DllGetClassObject [AMSTREAM.@] 136 * Retrieves class object from a DLL object 137 * 138 * NOTES 139 * Docs say returns STDAPI 140 * 141 * PARAMS 142 * rclsid [I] CLSID for the class object 143 * riid [I] Reference to identifier of interface for class object 144 * ppv [O] Address of variable to receive interface pointer for riid 145 * 146 * RETURNS 147 * Success: S_OK 148 * Failure: CLASS_E_CLASSNOTAVAILABLE, E_OUTOFMEMORY, E_INVALIDARG, 149 * E_UNEXPECTED 150 */ 151 HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID *ppv) 152 { 153 unsigned int i; 154 IClassFactoryImpl *factory; 155 156 TRACE("(%s,%s,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv); 157 158 if ( !IsEqualGUID( &IID_IClassFactory, riid ) 159 && ! IsEqualGUID( &IID_IUnknown, riid) ) 160 return E_NOINTERFACE; 161 162 for (i=0; i < sizeof(object_creation)/sizeof(object_creation[0]); i++) 163 { 164 if (IsEqualGUID(object_creation[i].clsid, rclsid)) 165 break; 166 } 167 168 if (i == sizeof(object_creation)/sizeof(object_creation[0])) 169 { 170 FIXME("%s: no class found.\n", debugstr_guid(rclsid)); 171 return CLASS_E_CLASSNOTAVAILABLE; 172 } 173 174 factory = HeapAlloc(GetProcessHeap(), 0, sizeof(*factory)); 175 if (factory == NULL) return E_OUTOFMEMORY; 176 177 factory->IClassFactory_iface.lpVtbl = &DSCF_Vtbl; 178 factory->ref = 1; 179 180 factory->pfnCreateInstance = object_creation[i].pfnCreateInstance; 181 182 *ppv = &factory->IClassFactory_iface; 183 return S_OK; 184 } 185 186 /*********************************************************************** 187 * DllCanUnloadNow (AMSTREAM.@) 188 */ 189 HRESULT WINAPI DllCanUnloadNow(void) 190 { 191 return S_FALSE; 192 } 193 194 /*********************************************************************** 195 * DllRegisterServer (AMSTREAM.@) 196 */ 197 HRESULT WINAPI DllRegisterServer(void) 198 { 199 return __wine_register_resources( instance ); 200 } 201 202 /*********************************************************************** 203 * DllUnregisterServer (AMSTREAM.@) 204 */ 205 HRESULT WINAPI DllUnregisterServer(void) 206 { 207 return __wine_unregister_resources( instance ); 208 } 209