1c2c66affSColin Finck /*
2*c1585bb8SAmine Khaldi  * Device Enumeration
3c2c66affSColin Finck  *
4c2c66affSColin Finck  * Copyright (C) 2002 John K. Hohm
5c2c66affSColin Finck  * Copyright (C) 2002 Robert Shearman
6c2c66affSColin Finck  *
7c2c66affSColin Finck  * This library is free software; you can redistribute it and/or
8c2c66affSColin Finck  * modify it under the terms of the GNU Lesser General Public
9c2c66affSColin Finck  * License as published by the Free Software Foundation; either
10c2c66affSColin Finck  * version 2.1 of the License, or (at your option) any later version.
11c2c66affSColin Finck  *
12c2c66affSColin Finck  * This library is distributed in the hope that it will be useful,
13c2c66affSColin Finck  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14c2c66affSColin Finck  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15c2c66affSColin Finck  * Lesser General Public License for more details.
16c2c66affSColin Finck  *
17c2c66affSColin Finck  * You should have received a copy of the GNU Lesser General Public
18c2c66affSColin Finck  * License along with this library; if not, write to the Free Software
19c2c66affSColin Finck  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20c2c66affSColin Finck  */
21c2c66affSColin Finck 
22c2c66affSColin Finck #include "devenum_private.h"
23dbcbc1cdSAmine Khaldi #include "rpcproxy.h"
24dbcbc1cdSAmine Khaldi #include "wine/debug.h"
25c2c66affSColin Finck 
26dbcbc1cdSAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(devenum);
27c2c66affSColin Finck 
28c2c66affSColin Finck DECLSPEC_HIDDEN LONG dll_refs;
29*c1585bb8SAmine Khaldi static HINSTANCE devenum_instance;
30c2c66affSColin Finck 
31c2c66affSColin Finck #ifdef __REACTOS__
32c2c66affSColin Finck static void DEVENUM_RegisterQuartz(void);
33c2c66affSColin Finck #endif
34c2c66affSColin Finck 
35c2c66affSColin Finck /***********************************************************************
36c2c66affSColin Finck  *		DllEntryPoint
37c2c66affSColin Finck  */
DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID fImpLoad)38c2c66affSColin Finck BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
39c2c66affSColin Finck {
40c2c66affSColin Finck     TRACE("%p 0x%x %p\n", hinstDLL, fdwReason, fImpLoad);
41c2c66affSColin Finck 
42c2c66affSColin Finck     switch(fdwReason) {
43c2c66affSColin Finck     case DLL_PROCESS_ATTACH:
44*c1585bb8SAmine Khaldi         devenum_instance = hinstDLL;
45c2c66affSColin Finck         DisableThreadLibraryCalls(hinstDLL);
46c2c66affSColin Finck 	break;
47c2c66affSColin Finck     }
48c2c66affSColin Finck     return TRUE;
49c2c66affSColin Finck }
50c2c66affSColin Finck 
51*c1585bb8SAmine Khaldi struct class_factory
52*c1585bb8SAmine Khaldi {
53*c1585bb8SAmine Khaldi     IClassFactory IClassFactory_iface;
54*c1585bb8SAmine Khaldi     IUnknown *obj;
55*c1585bb8SAmine Khaldi };
56*c1585bb8SAmine Khaldi 
impl_from_IClassFactory(IClassFactory * iface)57*c1585bb8SAmine Khaldi static inline struct class_factory *impl_from_IClassFactory( IClassFactory *iface )
58*c1585bb8SAmine Khaldi {
59*c1585bb8SAmine Khaldi     return CONTAINING_RECORD( iface, struct class_factory, IClassFactory_iface );
60*c1585bb8SAmine Khaldi }
61*c1585bb8SAmine Khaldi 
ClassFactory_QueryInterface(IClassFactory * iface,REFIID iid,void ** obj)62*c1585bb8SAmine Khaldi static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void **obj)
63*c1585bb8SAmine Khaldi {
64*c1585bb8SAmine Khaldi     TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), obj);
65*c1585bb8SAmine Khaldi 
66*c1585bb8SAmine Khaldi     if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
67*c1585bb8SAmine Khaldi     {
68*c1585bb8SAmine Khaldi         IClassFactory_AddRef(iface);
69*c1585bb8SAmine Khaldi         *obj = iface;
70*c1585bb8SAmine Khaldi         return S_OK;
71*c1585bb8SAmine Khaldi     }
72*c1585bb8SAmine Khaldi 
73*c1585bb8SAmine Khaldi     *obj = NULL;
74*c1585bb8SAmine Khaldi     WARN("no interface for %s\n", debugstr_guid(iid));
75*c1585bb8SAmine Khaldi     return E_NOINTERFACE;
76*c1585bb8SAmine Khaldi }
77*c1585bb8SAmine Khaldi 
ClassFactory_AddRef(IClassFactory * iface)78*c1585bb8SAmine Khaldi static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
79*c1585bb8SAmine Khaldi {
80*c1585bb8SAmine Khaldi     DEVENUM_LockModule();
81*c1585bb8SAmine Khaldi     return 2;
82*c1585bb8SAmine Khaldi }
83*c1585bb8SAmine Khaldi 
ClassFactory_Release(IClassFactory * iface)84*c1585bb8SAmine Khaldi static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
85*c1585bb8SAmine Khaldi {
86*c1585bb8SAmine Khaldi     DEVENUM_UnlockModule();
87*c1585bb8SAmine Khaldi     return 1;
88*c1585bb8SAmine Khaldi }
89*c1585bb8SAmine Khaldi 
ClassFactory_CreateInstance(IClassFactory * iface,IUnknown * outer,REFIID iid,void ** obj)90*c1585bb8SAmine Khaldi static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface,
91*c1585bb8SAmine Khaldi     IUnknown *outer, REFIID iid, void **obj)
92*c1585bb8SAmine Khaldi {
93*c1585bb8SAmine Khaldi     struct class_factory *This = impl_from_IClassFactory( iface );
94*c1585bb8SAmine Khaldi 
95*c1585bb8SAmine Khaldi     TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj);
96*c1585bb8SAmine Khaldi 
97*c1585bb8SAmine Khaldi     if (!obj) return E_POINTER;
98*c1585bb8SAmine Khaldi 
99*c1585bb8SAmine Khaldi     if (outer) return CLASS_E_NOAGGREGATION;
100*c1585bb8SAmine Khaldi 
101*c1585bb8SAmine Khaldi     return IUnknown_QueryInterface(This->obj, iid, obj);
102*c1585bb8SAmine Khaldi }
103*c1585bb8SAmine Khaldi 
ClassFactory_LockServer(IClassFactory * iface,BOOL lock)104*c1585bb8SAmine Khaldi static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock)
105*c1585bb8SAmine Khaldi {
106*c1585bb8SAmine Khaldi     if (lock)
107*c1585bb8SAmine Khaldi         DEVENUM_LockModule();
108*c1585bb8SAmine Khaldi     else
109*c1585bb8SAmine Khaldi         DEVENUM_UnlockModule();
110*c1585bb8SAmine Khaldi     return S_OK;
111*c1585bb8SAmine Khaldi }
112*c1585bb8SAmine Khaldi 
113*c1585bb8SAmine Khaldi static const IClassFactoryVtbl ClassFactory_vtbl = {
114*c1585bb8SAmine Khaldi     ClassFactory_QueryInterface,
115*c1585bb8SAmine Khaldi     ClassFactory_AddRef,
116*c1585bb8SAmine Khaldi     ClassFactory_Release,
117*c1585bb8SAmine Khaldi     ClassFactory_CreateInstance,
118*c1585bb8SAmine Khaldi     ClassFactory_LockServer
119*c1585bb8SAmine Khaldi };
120*c1585bb8SAmine Khaldi 
121*c1585bb8SAmine Khaldi static struct class_factory create_devenum_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_CreateDevEnum };
122*c1585bb8SAmine Khaldi static struct class_factory device_moniker_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_ParseDisplayName };
123*c1585bb8SAmine Khaldi 
124c2c66affSColin Finck /***********************************************************************
125c2c66affSColin Finck  *		DllGetClassObject (DEVENUM.@)
126c2c66affSColin Finck  */
DllGetClassObject(REFCLSID clsid,REFIID iid,void ** obj)127*c1585bb8SAmine Khaldi HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **obj)
128c2c66affSColin Finck {
129*c1585bb8SAmine Khaldi     TRACE("(%s, %s, %p)\n", debugstr_guid(clsid), debugstr_guid(iid), obj);
130c2c66affSColin Finck 
131*c1585bb8SAmine Khaldi     *obj = NULL;
132c2c66affSColin Finck 
133*c1585bb8SAmine Khaldi     if (IsEqualGUID(clsid, &CLSID_SystemDeviceEnum))
134*c1585bb8SAmine Khaldi         return IClassFactory_QueryInterface(&create_devenum_cf.IClassFactory_iface, iid, obj);
135*c1585bb8SAmine Khaldi     else if (IsEqualGUID(clsid, &CLSID_CDeviceMoniker))
136*c1585bb8SAmine Khaldi         return IClassFactory_QueryInterface(&device_moniker_cf.IClassFactory_iface, iid, obj);
137c2c66affSColin Finck 
138*c1585bb8SAmine Khaldi     FIXME("class %s not available\n", debugstr_guid(clsid));
139c2c66affSColin Finck     return CLASS_E_CLASSNOTAVAILABLE;
140c2c66affSColin Finck }
141c2c66affSColin Finck 
142c2c66affSColin Finck /***********************************************************************
143c2c66affSColin Finck  *		DllCanUnloadNow (DEVENUM.@)
144c2c66affSColin Finck  */
DllCanUnloadNow(void)145c2c66affSColin Finck HRESULT WINAPI DllCanUnloadNow(void)
146c2c66affSColin Finck {
147c2c66affSColin Finck     return dll_refs != 0 ? S_FALSE : S_OK;
148c2c66affSColin Finck }
149c2c66affSColin Finck 
150c2c66affSColin Finck /***********************************************************************
151c2c66affSColin Finck  *		DllRegisterServer (DEVENUM.@)
152c2c66affSColin Finck  */
DllRegisterServer(void)153c2c66affSColin Finck HRESULT WINAPI DllRegisterServer(void)
154c2c66affSColin Finck {
155c2c66affSColin Finck     HRESULT res;
156c2c66affSColin Finck     IFilterMapper2 * pMapper = NULL;
157c2c66affSColin Finck     LPVOID mapvptr;
158c2c66affSColin Finck 
159c2c66affSColin Finck     TRACE("\n");
160c2c66affSColin Finck 
161*c1585bb8SAmine Khaldi     res = __wine_register_resources( devenum_instance );
162c2c66affSColin Finck     if (FAILED(res))
163c2c66affSColin Finck         return res;
164c2c66affSColin Finck 
165c2c66affSColin Finck #ifdef __REACTOS__
166c2c66affSColin Finck     /* Quartz is needed for IFilterMapper2 */
167c2c66affSColin Finck     DEVENUM_RegisterQuartz();
168c2c66affSColin Finck #endif
169c2c66affSColin Finck 
170c2c66affSColin Finck /*** ActiveMovieFilter Categories ***/
171c2c66affSColin Finck 
172c2c66affSColin Finck     CoInitialize(NULL);
173c2c66affSColin Finck 
174c2c66affSColin Finck     res = CoCreateInstance(&CLSID_FilterMapper2, NULL, CLSCTX_INPROC,
175c2c66affSColin Finck                            &IID_IFilterMapper2,  &mapvptr);
176c2c66affSColin Finck     if (SUCCEEDED(res))
177c2c66affSColin Finck     {
178c2c66affSColin Finck         static const WCHAR friendlyvidcap[] = {'V','i','d','e','o',' ','C','a','p','t','u','r','e',' ','S','o','u','r','c','e','s',0};
179c2c66affSColin Finck         static const WCHAR friendlydshow[] = {'D','i','r','e','c','t','S','h','o','w',' ','F','i','l','t','e','r','s',0};
180c2c66affSColin Finck         static const WCHAR friendlyvidcomp[] = {'V','i','d','e','o',' ','C','o','m','p','r','e','s','s','o','r','s',0};
181c2c66affSColin Finck         static const WCHAR friendlyaudcap[] = {'A','u','d','i','o',' ','C','a','p','t','u','r','e',' ','S','o','u','r','c','e','s',0};
182c2c66affSColin Finck         static const WCHAR friendlyaudcomp[] = {'A','u','d','i','o',' ','C','o','m','p','r','e','s','s','o','r','s',0};
183c2c66affSColin Finck         static const WCHAR friendlyaudrend[] = {'A','u','d','i','o',' ','R','e','n','d','e','r','e','r','s',0};
184c2c66affSColin Finck         static const WCHAR friendlymidirend[] = {'M','i','d','i',' ','R','e','n','d','e','r','e','r','s',0};
185c2c66affSColin Finck         static const WCHAR friendlyextrend[] = {'E','x','t','e','r','n','a','l',' ','R','e','n','d','e','r','e','r','s',0};
186c2c66affSColin Finck         static const WCHAR friendlydevctrl[] = {'D','e','v','i','c','e',' ','C','o','n','t','r','o','l',' ','F','i','l','t','e','r','s',0};
187c2c66affSColin Finck 
188c2c66affSColin Finck         pMapper = mapvptr;
189c2c66affSColin Finck 
190c2c66affSColin Finck         IFilterMapper2_CreateCategory(pMapper, &CLSID_VideoInputDeviceCategory, MERIT_DO_NOT_USE, friendlyvidcap);
191c2c66affSColin Finck         IFilterMapper2_CreateCategory(pMapper, &CLSID_LegacyAmFilterCategory, MERIT_NORMAL, friendlydshow);
192c2c66affSColin Finck         IFilterMapper2_CreateCategory(pMapper, &CLSID_VideoCompressorCategory, MERIT_DO_NOT_USE, friendlyvidcomp);
193c2c66affSColin Finck         IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioInputDeviceCategory, MERIT_DO_NOT_USE, friendlyaudcap);
194c2c66affSColin Finck         IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioCompressorCategory, MERIT_DO_NOT_USE, friendlyaudcomp);
195c2c66affSColin Finck         IFilterMapper2_CreateCategory(pMapper, &CLSID_AudioRendererCategory, MERIT_NORMAL, friendlyaudrend);
196c2c66affSColin Finck         IFilterMapper2_CreateCategory(pMapper, &CLSID_MidiRendererCategory, MERIT_NORMAL, friendlymidirend);
197c2c66affSColin Finck         IFilterMapper2_CreateCategory(pMapper, &CLSID_TransmitCategory, MERIT_DO_NOT_USE, friendlyextrend);
198c2c66affSColin Finck         IFilterMapper2_CreateCategory(pMapper, &CLSID_DeviceControlCategory, MERIT_DO_NOT_USE, friendlydevctrl);
199c2c66affSColin Finck 
200c2c66affSColin Finck         IFilterMapper2_Release(pMapper);
201c2c66affSColin Finck     }
202c2c66affSColin Finck 
203c2c66affSColin Finck     CoUninitialize();
204c2c66affSColin Finck 
205c2c66affSColin Finck     return res;
206c2c66affSColin Finck }
207c2c66affSColin Finck 
208c2c66affSColin Finck /***********************************************************************
209c2c66affSColin Finck  *		DllUnregisterServer (DEVENUM.@)
210c2c66affSColin Finck  */
DllUnregisterServer(void)211c2c66affSColin Finck HRESULT WINAPI DllUnregisterServer(void)
212c2c66affSColin Finck {
213c2c66affSColin Finck     FIXME("stub!\n");
214*c1585bb8SAmine Khaldi     return __wine_unregister_resources( devenum_instance );
215c2c66affSColin Finck }
216c2c66affSColin Finck 
217c2c66affSColin Finck #ifdef __REACTOS__
218c2c66affSColin Finck 
219c2c66affSColin Finck typedef HRESULT (WINAPI *DllRegisterServer_func)(void);
220c2c66affSColin Finck 
221c2c66affSColin Finck /* calls DllRegisterServer() for the Quartz DLL */
DEVENUM_RegisterQuartz(void)222c2c66affSColin Finck static void DEVENUM_RegisterQuartz(void)
223c2c66affSColin Finck {
224c2c66affSColin Finck     HANDLE hDLL = LoadLibraryA("quartz.dll");
225c2c66affSColin Finck     DllRegisterServer_func pDllRegisterServer = NULL;
226c2c66affSColin Finck     if (hDLL)
227c2c66affSColin Finck         pDllRegisterServer = (DllRegisterServer_func)GetProcAddress(hDLL, "DllRegisterServer");
228c2c66affSColin Finck     if (pDllRegisterServer)
229c2c66affSColin Finck     {
230c2c66affSColin Finck         HRESULT hr = pDllRegisterServer();
231c2c66affSColin Finck         if (FAILED(hr))
232c2c66affSColin Finck             ERR("Failed to register Quartz. Error was 0x%x)\n", hr);
233c2c66affSColin Finck     }
234c2c66affSColin Finck }
235c2c66affSColin Finck 
236c2c66affSColin Finck #endif
237