source: trunk/src/quartz/devenum.c@ 8266

Last change on this file since 8266 was 6952, checked in by sandervl, 24 years ago

Wine 20011004 resync

File size: 4.8 KB
Line 
1/*
2 * Implementation of CLSID_SystemDeviceEnum.
3 *
4 * FIXME - not tested enough.
5 *
6 * hidenori@a2.ctktv.ne.jp
7 */
8
9#include "config.h"
10
11#include "windef.h"
12#include "winbase.h"
13#include "wingdi.h"
14#include "winuser.h"
15#include "winreg.h"
16#include "winerror.h"
17#include "wine/obj_base.h"
18#include "objidl.h"
19#include "oleidl.h"
20#include "ocidl.h"
21#include "strmif.h"
22#include "control.h"
23#include "uuids.h"
24#include "wine/unicode.h"
25
26#include "debugtools.h"
27DEFAULT_DEBUG_CHANNEL(quartz);
28
29#include "quartz_private.h"
30#include "devenum.h"
31#include "regsvr.h"
32#include "enumunk.h"
33#include "complist.h"
34#include "devmon.h"
35
36
37/***************************************************************************
38 *
39 * new/delete for CLSID_SystemDeviceEnum
40 *
41 */
42
43/* can I use offsetof safely? - FIXME? */
44static QUARTZ_IFEntry IFEntries[] =
45{
46 { &IID_ICreateDevEnum, offsetof(CSysDevEnum,createdevenum)-offsetof(CSysDevEnum,unk) },
47};
48
49
50static void QUARTZ_DestroySystemDeviceEnum(IUnknown* punk)
51{
52 CSysDevEnum_THIS(punk,unk);
53
54 CSysDevEnum_UninitICreateDevEnum( This );
55}
56
57HRESULT QUARTZ_CreateSystemDeviceEnum(IUnknown* punkOuter,void** ppobj)
58{
59 CSysDevEnum* psde;
60 HRESULT hr;
61
62 TRACE("(%p,%p)\n",punkOuter,ppobj);
63
64 psde = (CSysDevEnum*)QUARTZ_AllocObj( sizeof(CSysDevEnum) );
65 if ( psde == NULL )
66 return E_OUTOFMEMORY;
67
68 QUARTZ_IUnkInit( &psde->unk, punkOuter );
69
70 hr = CSysDevEnum_InitICreateDevEnum( psde );
71 if ( FAILED(hr) )
72 {
73 QUARTZ_FreeObj( psde );
74 return hr;
75 }
76
77 psde->unk.pEntries = IFEntries;
78 psde->unk.dwEntries = sizeof(IFEntries)/sizeof(IFEntries[0]);
79 psde->unk.pOnFinalRelease = QUARTZ_DestroySystemDeviceEnum;
80
81 *ppobj = (void*)(&psde->unk);
82
83 return S_OK;
84}
85
86
87/***************************************************************************
88 *
89 * CSysDevEnum::ICreateDevEnum
90 *
91 */
92
93
94static HRESULT WINAPI
95ICreateDevEnum_fnQueryInterface(ICreateDevEnum* iface,REFIID riid,void** ppobj)
96{
97 CSysDevEnum_THIS(iface,createdevenum);
98
99 TRACE("(%p)->()\n",This);
100
101 return IUnknown_QueryInterface(This->unk.punkControl,riid,ppobj);
102}
103
104static ULONG WINAPI
105ICreateDevEnum_fnAddRef(ICreateDevEnum* iface)
106{
107 CSysDevEnum_THIS(iface,createdevenum);
108
109 TRACE("(%p)->()\n",This);
110
111 return IUnknown_AddRef(This->unk.punkControl);
112}
113
114static ULONG WINAPI
115ICreateDevEnum_fnRelease(ICreateDevEnum* iface)
116{
117 CSysDevEnum_THIS(iface,createdevenum);
118
119 TRACE("(%p)->()\n",This);
120
121 return IUnknown_Release(This->unk.punkControl);
122}
123
124static HRESULT WINAPI
125ICreateDevEnum_fnCreateClassEnumerator(ICreateDevEnum* iface,REFCLSID rclsidDeviceClass,IEnumMoniker** ppobj, DWORD dwFlags)
126{
127 CSysDevEnum_THIS(iface,createdevenum);
128 HRESULT hr;
129 HKEY hKey;
130 QUARTZ_CompList* pMonList;
131 IMoniker* pMon;
132 DWORD dwIndex;
133 LONG lr;
134 WCHAR wszPath[ 1024 ];
135 DWORD dwLen;
136 DWORD dwNameMax;
137 DWORD cbName;
138 FILETIME ftLastWrite;
139
140 TRACE("(%p)->(%s,%p,%08lx)\n",This,
141 debugstr_guid(rclsidDeviceClass),ppobj,dwFlags);
142 if ( dwFlags != 0 )
143 {
144 FIXME("unknown flags %08lx\n",dwFlags);
145 return E_NOTIMPL;
146 }
147
148 if ( ppobj == NULL )
149 return E_POINTER;
150 *ppobj = NULL;
151
152 hr = QUARTZ_CreateCLSIDPath(
153 wszPath, sizeof(wszPath)/sizeof(wszPath[0]),
154 rclsidDeviceClass, QUARTZ_wszInstance );
155 if ( FAILED(hr) )
156 return hr;
157
158 if ( RegOpenKeyExW( HKEY_CLASSES_ROOT, wszPath,
159 0, KEY_READ, &hKey ) != ERROR_SUCCESS )
160 return E_FAIL;
161
162 dwLen = strlenW(wszPath);
163 wszPath[dwLen++] = '\\'; wszPath[dwLen] = 0;
164 dwNameMax = sizeof(wszPath)/sizeof(wszPath[0]) - dwLen - 8;
165
166 pMonList = QUARTZ_CompList_Alloc();
167 if ( pMonList == NULL )
168 {
169 hr = E_OUTOFMEMORY;
170 goto err;
171 }
172
173 /* enumerate all subkeys. */
174 dwIndex = 0;
175 while ( 1 )
176 {
177 cbName = dwNameMax;
178 lr = RegEnumKeyExW(
179 hKey, dwIndex, &wszPath[dwLen], &cbName,
180 NULL, NULL, NULL, &ftLastWrite );
181 if ( lr == ERROR_NO_MORE_ITEMS )
182 break;
183 if ( lr != ERROR_SUCCESS )
184 {
185 hr = E_FAIL;
186 goto err;
187 }
188
189 hr = QUARTZ_CreateDeviceMoniker(
190 HKEY_CLASSES_ROOT, wszPath, &pMon );
191 if ( FAILED(hr) )
192 goto err;
193
194 hr = QUARTZ_CompList_AddComp(
195 pMonList, (IUnknown*)pMon, NULL, 0 );
196 IMoniker_Release( pMon );
197
198 if ( FAILED(hr) )
199 goto err;
200
201 dwIndex ++;
202 }
203
204 /* create an enumerator. */
205 hr = QUARTZ_CreateEnumUnknown(
206 &IID_IEnumMoniker, (void**)ppobj, pMonList );
207 if ( FAILED(hr) )
208 goto err;
209
210 hr = S_OK;
211err:
212 if ( pMonList != NULL )
213 QUARTZ_CompList_Free( pMonList );
214 RegCloseKey( hKey );
215
216 return hr;
217}
218
219static ICOM_VTABLE(ICreateDevEnum) icreatedevenum =
220{
221 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
222 /* IUnknown fields */
223 ICreateDevEnum_fnQueryInterface,
224 ICreateDevEnum_fnAddRef,
225 ICreateDevEnum_fnRelease,
226 /* ICreateDevEnum fields */
227 ICreateDevEnum_fnCreateClassEnumerator,
228};
229
230HRESULT CSysDevEnum_InitICreateDevEnum( CSysDevEnum* psde )
231{
232 TRACE("(%p)\n",psde);
233 ICOM_VTBL(&psde->createdevenum) = &icreatedevenum;
234
235 return NOERROR;
236}
237
238void CSysDevEnum_UninitICreateDevEnum( CSysDevEnum* psde )
239{
240 TRACE("(%p)\n",psde);
241}
Note: See TracBrowser for help on using the repository browser.