845bf7213ac3fed9a35ba75aee5eee2a70e2d9ca
[reactos.git] / reactos / dll / win32 / netcfgx / netcfg_iface.c
1 #include "precomp.h"
2 #include <devguid.h>
3
4 typedef struct
5 {
6 const INetCfg * lpVtbl;
7 const INetCfgLock * lpVtblLock;
8 LONG ref;
9 BOOL bInitialized;
10 HANDLE hMutex;
11 NetCfgComponentItem *pNet;
12 NetCfgComponentItem * pService;
13 NetCfgComponentItem * pClient;
14 NetCfgComponentItem * pProtocol;
15 } INetCfgImpl, *LPINetCfgImpl;
16
17 static __inline LPINetCfgImpl impl_from_INetCfgLock(INetCfgLock *iface)
18 {
19 return (INetCfgImpl*)((char *)iface - FIELD_OFFSET(INetCfgImpl, lpVtblLock));
20 }
21
22
23
24 HRESULT
25 WINAPI
26 INetCfgLock_fnQueryInterface(
27 INetCfgLock * iface,
28 REFIID iid,
29 LPVOID * ppvObj)
30 {
31 INetCfgImpl * This = impl_from_INetCfgLock(iface);
32 return INetCfg_QueryInterface((INetCfg*)This, iid, ppvObj);
33 }
34
35
36 ULONG
37 WINAPI
38 INetCfgLock_fnAddRef(
39 INetCfgLock * iface)
40 {
41 INetCfgImpl * This = impl_from_INetCfgLock(iface);
42
43 return INetCfg_AddRef((INetCfg*)This);
44 }
45
46 ULONG
47 WINAPI
48 INetCfgLock_fnRelease(
49 INetCfgLock * iface)
50 {
51 INetCfgImpl * This = impl_from_INetCfgLock(iface);
52 return INetCfg_Release((INetCfg*)This);
53 }
54
55 HRESULT
56 WINAPI
57 INetCfgLock_fnAcquireWriteLock(
58 INetCfgLock * iface,
59 DWORD cmsTimeout,
60 LPCWSTR pszwClientDescription,
61 LPWSTR *ppszwClientDescription)
62 {
63 DWORD dwResult;
64 HKEY hKey;
65 WCHAR szValue[100];
66 INetCfgImpl * This = impl_from_INetCfgLock(iface);
67
68 if (This->bInitialized)
69 return NETCFG_E_ALREADY_INITIALIZED;
70
71 dwResult = WaitForSingleObject(This->hMutex, cmsTimeout);
72 if (dwResult == WAIT_TIMEOUT)
73 {
74 if (ppszwClientDescription)
75 {
76 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, KEY_READ, &hKey) == ERROR_SUCCESS)
77 {
78 dwResult = sizeof(szValue);
79 if (RegQueryValueExW(hKey, NULL, NULL, NULL, (LPBYTE)szValue, &dwResult) == ERROR_SUCCESS)
80 {
81 szValue[(sizeof(szValue)/sizeof(WCHAR))-1] = L'\0';
82 *ppszwClientDescription = CoTaskMemAlloc((wcslen(szValue)+1) * sizeof(WCHAR));
83 if (*ppszwClientDescription)
84 wcscpy(*ppszwClientDescription, szValue);
85 }
86 RegCloseKey(hKey);
87 }
88 }
89 return S_FALSE;
90 }
91 else if (dwResult == WAIT_OBJECT_0)
92 {
93 if (RegCreateKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, NULL, 0, KEY_WRITE, NULL, &hKey, NULL) == ERROR_SUCCESS)
94 {
95 RegSetValueExW(hKey, NULL, 0, REG_SZ, (LPBYTE)pszwClientDescription, (wcslen(pszwClientDescription)+1) * sizeof(WCHAR));
96 RegCloseKey(hKey);
97 }
98 return S_OK;
99 }
100
101 return E_FAIL;
102 }
103
104 HRESULT
105 WINAPI
106 INetCfgLock_fnReleaseWriteLock(
107 INetCfgLock * iface)
108 {
109 INetCfgImpl * This = impl_from_INetCfgLock(iface);
110
111 if (This->bInitialized)
112 return NETCFG_E_ALREADY_INITIALIZED;
113
114
115 if (ReleaseMutex(This->hMutex))
116 return S_OK;
117 else
118 return S_FALSE;
119 }
120
121 HRESULT
122 WINAPI
123 INetCfgLock_fnIsWriteLocked(
124 INetCfgLock * iface,
125 LPWSTR *ppszwClientDescription)
126 {
127 HKEY hKey;
128 WCHAR szValue[100];
129 DWORD dwSize, dwType;
130 HRESULT hr;
131
132 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Control\\Network\\NetCfgLockHolder", 0, KEY_READ, &hKey) != ERROR_SUCCESS)
133 return S_FALSE;
134
135 dwSize = sizeof(szValue);
136 if (RegQueryValueExW(hKey, NULL, NULL, &dwType, (LPBYTE)szValue, &dwSize) == ERROR_SUCCESS && dwType == REG_SZ)
137 {
138 hr = S_OK;
139 szValue[(sizeof(szValue)/sizeof(WCHAR))-1] = L'\0';
140 *ppszwClientDescription = CoTaskMemAlloc((wcslen(szValue)+1) * sizeof(WCHAR));
141 if (*ppszwClientDescription)
142 wcscpy(*ppszwClientDescription, szValue);
143 else
144 hr = E_OUTOFMEMORY;
145 }
146 else
147 {
148 hr = E_FAIL;
149 }
150 RegCloseKey(hKey);
151 return hr;
152 }
153
154 static const INetCfgLockVtbl vt_NetCfgLock =
155 {
156 INetCfgLock_fnQueryInterface,
157 INetCfgLock_fnAddRef,
158 INetCfgLock_fnRelease,
159 INetCfgLock_fnAcquireWriteLock,
160 INetCfgLock_fnReleaseWriteLock,
161 INetCfgLock_fnIsWriteLocked
162 };
163
164 /***************************************************************
165 * INetCfg
166 */
167
168 HRESULT
169 EnumClientServiceProtocol(HKEY hKey, const GUID * pGuid, NetCfgComponentItem ** pHead)
170 {
171 DWORD dwIndex = 0;
172 DWORD dwSize;
173 DWORD dwType;
174 DWORD dwCharacteristics;
175 WCHAR szName[100];
176 WCHAR szText[100];
177 HKEY hSubKey, hNDIKey;
178 NetCfgComponentItem * pLast = NULL, *pCurrent;
179
180 *pHead = NULL;
181 do
182 {
183 dwCharacteristics = 0;
184 szText[0] = L'\0';
185
186 dwSize = sizeof(szName)/sizeof(WCHAR);
187 if (RegEnumKeyExW(hKey, dwIndex++, szName, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS)
188 {
189 pCurrent = CoTaskMemAlloc(sizeof(NetCfgComponentItem));
190 if (!pCurrent)
191 return E_OUTOFMEMORY;
192
193 ZeroMemory(pCurrent, sizeof(NetCfgComponentItem));
194 CopyMemory(&pCurrent->ClassGUID, pGuid, sizeof(GUID));
195
196 if (FAILED(CLSIDFromString(szName, &pCurrent->InstanceId)))
197 {
198 /// ReactOS tcpip guid is not yet generated
199 //CoTaskMemFree(pCurrent);
200 //return E_FAIL;
201 }
202 if (RegOpenKeyExW(hKey, szName, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS)
203 {
204 /* retrieve Characteristics */
205 dwSize = sizeof(DWORD);
206
207 RegQueryValueExW(hSubKey, L"Characteristics", NULL, &dwType, (LPBYTE)&pCurrent->dwCharacteristics, &dwSize);
208 if (dwType != REG_DWORD)
209 pCurrent->dwCharacteristics = 0;
210
211 /* retrieve ComponentId */
212 dwSize = sizeof(szText);
213 if (RegQueryValueExW(hSubKey, L"ComponentId", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS)
214 {
215 if (dwType == REG_SZ)
216 {
217 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
218 pCurrent->szId = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR));
219 if (pCurrent->szId)
220 wcscpy(pCurrent->szId, szText);
221 }
222 }
223
224 /* retrieve Description */
225 dwSize = sizeof(szText);
226 if (RegQueryValueExW(hSubKey, L"Description", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS)
227 {
228 if (dwType == REG_SZ)
229 {
230 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
231 pCurrent->szDisplayName = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR));
232 if (pCurrent->szDisplayName)
233 wcscpy(pCurrent->szDisplayName, szText);
234 }
235 }
236
237 if (RegOpenKeyExW(hKey, L"NDI", 0, KEY_READ, &hNDIKey) == ERROR_SUCCESS)
238 {
239 /* retrieve HelpText */
240 dwSize = sizeof(szText);
241 if (RegQueryValueExW(hNDIKey, L"HelpText", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS)
242 {
243 if (dwType == REG_SZ)
244 {
245 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
246 pCurrent->szHelpText = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR));
247 if (pCurrent->szHelpText)
248 wcscpy(pCurrent->szHelpText, szText);
249 }
250 }
251
252 /* retrieve Service */
253 dwSize = sizeof(szText);
254 if (RegQueryValueExW(hNDIKey, L"Service", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS)
255 {
256 if (dwType == REG_SZ)
257 {
258 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0';
259 pCurrent->szBindName = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR));
260 if (pCurrent->szBindName)
261 wcscpy(pCurrent->szBindName, szText);
262 }
263 }
264 RegCloseKey(hNDIKey);
265 }
266 RegCloseKey(hSubKey);
267
268 if (!pLast)
269 *pHead = pCurrent;
270 else
271 pLast->pNext = pCurrent;
272
273 pLast = pCurrent;
274 }
275 }
276 else
277 break;
278
279 }while(TRUE);
280 return S_OK;
281 }
282
283
284
285 HRESULT
286 EnumerateNetworkComponent(
287 const GUID *pGuid, NetCfgComponentItem ** pHead)
288 {
289 HKEY hKey;
290 LPOLESTR pszGuid;
291 HRESULT hr;
292 WCHAR szName[150];
293
294 hr = StringFromCLSID(pGuid, &pszGuid);
295 if (SUCCEEDED(hr))
296 {
297 swprintf(szName, L"SYSTEM\\CurrentControlSet\\Control\\Network\\%s", pszGuid);
298 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
299 {
300 hr = EnumClientServiceProtocol(hKey, pGuid, pHead);
301 RegCloseKey(hKey);
302 }
303 CoTaskMemFree(pszGuid);
304 }
305 return hr;
306 }
307
308 HRESULT
309 EnumerateNetworkAdapter(NetCfgComponentItem ** pHead)
310 {
311 DWORD dwSize, dwIndex;
312 HDEVINFO hInfo;
313 SP_DEVINFO_DATA DevInfo;
314 HKEY hKey;
315 WCHAR szNetCfg[50];
316 WCHAR szAdapterNetCfg[50];
317 WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\";
318 WCHAR szName[130] = L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\";
319 NetCfgComponentItem * pLast = NULL, *pCurrent;
320
321 hInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT );
322 if (!hInfo)
323 {
324 return E_FAIL;
325 }
326
327 dwIndex = 0;
328 do
329 {
330 ZeroMemory(&DevInfo, sizeof(SP_DEVINFO_DATA));
331 DevInfo.cbSize = sizeof(DevInfo);
332
333 /* get device info */
334 if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, &DevInfo))
335 break;
336
337 /* get device software registry path */
338 if (!SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize))
339 break;
340
341 /* open device registry key */
342 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
343 break;
344
345 /* query NetCfgInstanceId for current device */
346 dwSize = sizeof(szNetCfg);
347 if (RegQueryValueExW(hKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS)
348 {
349 RegCloseKey(hKey);
350 break;
351 }
352
353 /* allocate new INetConnectionItem */
354 pCurrent = CoTaskMemAlloc(sizeof(NetCfgComponentItem));
355 if (!pCurrent)
356 break;
357
358 ZeroMemory(pCurrent, sizeof(NetCfgComponentItem));
359 CopyMemory(&pCurrent->ClassGUID, &GUID_DEVCLASS_NET, sizeof(GUID));
360 CLSIDFromString(szNetCfg, &pCurrent->InstanceId); //FIXME
361
362 /* set bind name */
363 pCurrent->szBindName = CoTaskMemAlloc((wcslen(szNetCfg)+1) *sizeof(WCHAR));
364 if (pCurrent->szBindName)
365 wcscpy(pCurrent->szBindName, szNetCfg);
366
367 /* retrieve ComponentId */
368 dwSize = sizeof(szAdapterNetCfg);
369 if (RegQueryValueExW(hKey, L"ComponentId", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS)
370 {
371 pCurrent->szId = CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR));
372 if (pCurrent->szId)
373 wcscpy(pCurrent->szId, szAdapterNetCfg);
374 }
375 /* set INetCfgComponent::GetDisplayName */
376 dwSize = sizeof(szAdapterNetCfg);
377 if (RegQueryValueExW(hKey, L"DriverDesc", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS)
378 {
379 pCurrent->szDisplayName = CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR));
380 if (pCurrent->szDisplayName)
381 wcscpy(pCurrent->szDisplayName, szAdapterNetCfg);
382 }
383
384 RegCloseKey(hKey);
385 /* open network connections details */
386 wcscpy(&szName[80], szNetCfg);
387 wcscpy(&szName[118], L"\\Connection");
388
389 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
390 {
391 /* retrieve pnp instance id */
392 dwSize = sizeof(szAdapterNetCfg);
393 if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS)
394 {
395 pCurrent->szNodeId = CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR));
396 if (pCurrent->szNodeId)
397 wcscpy(pCurrent->szNodeId, szAdapterNetCfg);
398 }
399 RegCloseKey(hKey);
400 }
401
402 if (SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DEVICEDESC, NULL, (PBYTE)szNetCfg, sizeof(szNetCfg)/sizeof(WCHAR), &dwSize))
403 {
404 szNetCfg[(sizeof(szNetCfg)/sizeof(WCHAR))-1] = L'\0';
405 pCurrent->szDisplayName = CoTaskMemAlloc((wcslen(szNetCfg)+1) * sizeof(WCHAR));
406 if (pCurrent->szDisplayName)
407 wcscpy(pCurrent->szDisplayName, szNetCfg);
408 }
409
410 if (pLast)
411 pLast->pNext = pCurrent;
412 else
413 *pHead = pCurrent;
414
415 pLast = pCurrent;
416
417 }while(TRUE);
418
419 SetupDiDestroyDeviceInfoList(hInfo);
420 return NOERROR;
421 }
422
423
424 HRESULT
425 FindNetworkComponent(
426 NetCfgComponentItem * pHead,
427 LPCWSTR pszwComponentId,
428 INetCfgComponent **pComponent,
429 INetCfg * iface)
430 {
431 while(pHead)
432 {
433 if (!wcsicmp(pHead->szId, pszwComponentId))
434 {
435 return INetCfgComponent_Constructor(NULL, &IID_INetCfgComponent, (LPVOID*)pComponent, pHead, iface);
436 }
437 pHead = pHead->pNext;
438 }
439 return S_FALSE;
440 }
441
442
443
444 HRESULT
445 WINAPI
446 INetCfg_fnQueryInterface(
447 INetCfg * iface,
448 REFIID iid,
449 LPVOID * ppvObj)
450 {
451 INetCfgImpl * This = (INetCfgImpl*)iface;
452 *ppvObj = NULL;
453
454 if (IsEqualIID (iid, &IID_IUnknown) ||
455 IsEqualIID (iid, &IID_INetCfg))
456 {
457 *ppvObj = This;
458 INetCfg_AddRef(iface);
459 return S_OK;
460 }
461 else if (IsEqualIID (iid, &IID_INetCfgLock))
462 {
463 if (This->bInitialized)
464 return NETCFG_E_ALREADY_INITIALIZED;
465
466 *ppvObj = (LPVOID)&This->lpVtblLock;
467 This->hMutex = CreateMutexW(NULL, FALSE, L"NetCfgLock");
468
469 INetCfgLock_AddRef(iface);
470 return S_OK;
471 }
472
473 return E_NOINTERFACE;
474 }
475
476 ULONG
477 WINAPI
478 INetCfg_fnAddRef(
479 INetCfg * iface)
480 {
481 INetCfgImpl * This = (INetCfgImpl*)iface;
482 ULONG refCount = InterlockedIncrement(&This->ref);
483
484 return refCount;
485 }
486
487 ULONG
488 WINAPI
489 INetCfg_fnRelease(
490 INetCfg * iface)
491 {
492 INetCfgImpl * This = (INetCfgImpl*)iface;
493 ULONG refCount = InterlockedDecrement(&This->ref);
494
495 if (!refCount)
496 {
497 CoTaskMemFree (This);
498 }
499 return refCount;
500 }
501
502 HRESULT
503 WINAPI
504 INetCfg_fnInitialize(
505 INetCfg * iface,
506 PVOID pReserved)
507 {
508 HRESULT hr;
509 INetCfgImpl *This = (INetCfgImpl *)iface;
510
511 if (This->bInitialized)
512 return NETCFG_E_ALREADY_INITIALIZED;
513
514 hr = EnumerateNetworkAdapter(&This->pNet);
515 if (FAILED(hr))
516 return hr;
517
518
519 hr = EnumerateNetworkComponent(&GUID_DEVCLASS_NETCLIENT, &This->pClient);
520 if (FAILED(hr))
521 return hr;
522
523 hr = EnumerateNetworkComponent(&GUID_DEVCLASS_NETSERVICE, &This->pService);
524 if (FAILED(hr))
525 return hr;
526
527
528 hr = EnumerateNetworkComponent(&GUID_DEVCLASS_NETTRANS, &This->pProtocol);
529 if (FAILED(hr))
530 return hr;
531
532 This->bInitialized = TRUE;
533 return S_OK;
534 }
535
536 VOID
537 ApplyOrCancelChanges(
538 NetCfgComponentItem *pHead,
539 const CLSID * lpClassGUID,
540 BOOL bApply)
541 {
542 HKEY hKey;
543 WCHAR szName[200];
544 LPOLESTR pszGuid;
545
546 while(pHead)
547 {
548 if (pHead->bChanged)
549 {
550 if (IsEqualGUID(lpClassGUID, &GUID_DEVCLASS_NET))
551 {
552 if (bApply)
553 {
554 if (StringFromCLSID(&pHead->InstanceId, &pszGuid) == NOERROR)
555 {
556 swprintf(szName, L"SYSTEM\\CurrentControlSet\\Control\\Network\\%s", pszGuid);
557 CoTaskMemFree(pszGuid);
558
559 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) == ERROR_SUCCESS)
560 {
561 RegSetValueExW(hKey, NULL, 0, REG_SZ, (LPBYTE)pHead->szDisplayName, (wcslen(pHead->szDisplayName)+1) * sizeof(WCHAR));
562 RegCloseKey(hKey);
563 }
564 }
565 }
566 }
567 else if (pHead->pNCCC)
568 {
569 if (bApply)
570 {
571 INetCfgComponentControl_ApplyRegistryChanges(pHead->pNCCC);
572 //FIXME
573 // implement INetCfgPnpReconfigCallback and pass it to
574 //INetCfgComponentControl_ApplyPnpChanges(pHead->pNCCC, NULL);
575 }
576 else
577 {
578 INetCfgComponentControl_CancelChanges(pHead->pNCCC);
579 }
580 }
581 }
582 pHead = pHead->pNext;
583 }
584 }
585
586 HRESULT
587 WINAPI
588 INetCfg_fnUninitialize(
589 INetCfg * iface)
590 {
591 INetCfgImpl *This = (INetCfgImpl *)iface;
592
593 if (!This->bInitialized)
594 return NETCFG_E_NOT_INITIALIZED;
595
596 return E_FAIL;
597 }
598
599
600 HRESULT
601 WINAPI
602 INetCfg_fnApply(
603 INetCfg * iface)
604 {
605 INetCfgImpl *This = (INetCfgImpl *)iface;
606
607 if (!This->bInitialized)
608 return NETCFG_E_NOT_INITIALIZED;
609
610 ApplyOrCancelChanges(This->pNet, &GUID_DEVCLASS_NET, TRUE);
611 ApplyOrCancelChanges(This->pClient, &GUID_DEVCLASS_NETCLIENT, TRUE);
612 ApplyOrCancelChanges(This->pService, &GUID_DEVCLASS_NETSERVICE, TRUE);
613 ApplyOrCancelChanges(This->pProtocol, &GUID_DEVCLASS_NETTRANS, TRUE);
614
615 return S_OK;
616 }
617
618 HRESULT
619 WINAPI
620 INetCfg_fnCancel(
621 INetCfg * iface)
622 {
623 INetCfgImpl *This = (INetCfgImpl *)iface;
624
625 if (!This->bInitialized)
626 return NETCFG_E_NOT_INITIALIZED;
627
628 ApplyOrCancelChanges(This->pClient, &GUID_DEVCLASS_NETCLIENT, FALSE);
629 ApplyOrCancelChanges(This->pService, &GUID_DEVCLASS_NETSERVICE, FALSE);
630 ApplyOrCancelChanges(This->pProtocol, &GUID_DEVCLASS_NETTRANS, FALSE);
631
632 return S_OK;
633 }
634
635 HRESULT
636 WINAPI
637 INetCfg_fnEnumComponents(
638 INetCfg * iface,
639 const GUID *pguidClass,
640 IEnumNetCfgComponent **ppenumComponent)
641 {
642 INetCfgImpl *This = (INetCfgImpl *)iface;
643
644 if (!This->bInitialized)
645 return NETCFG_E_NOT_INITIALIZED;
646
647 if (IsEqualGUID(&GUID_DEVCLASS_NET, pguidClass))
648 return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pNet, iface);
649 else if (IsEqualGUID(&GUID_DEVCLASS_NETCLIENT, pguidClass))
650 return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pClient, iface);
651 else if (IsEqualGUID(&GUID_DEVCLASS_NETSERVICE, pguidClass))
652 return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pService, iface);
653 else if (IsEqualGUID(&GUID_DEVCLASS_NETTRANS, pguidClass))
654 return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pProtocol, iface);
655 else
656 return E_NOINTERFACE;
657 }
658
659
660 HRESULT
661 WINAPI
662 INetCfg_fnFindComponent(
663 INetCfg * iface,
664 LPCWSTR pszwComponentId,
665 INetCfgComponent **pComponent)
666 {
667 HRESULT hr;
668 INetCfgImpl *This = (INetCfgImpl *)iface;
669
670 if (!This->bInitialized)
671 return NETCFG_E_NOT_INITIALIZED;
672
673 hr = FindNetworkComponent(This->pClient, pszwComponentId, pComponent, iface);
674 if (hr == S_OK)
675 return hr;
676
677 hr = FindNetworkComponent(This->pService, pszwComponentId, pComponent, iface);
678 if (hr == S_OK)
679 return hr;
680
681 hr = FindNetworkComponent(This->pProtocol, pszwComponentId, pComponent, iface);
682 if (hr == S_OK)
683 return hr;
684
685 return S_FALSE;
686 }
687
688 HRESULT
689 WINAPI
690 INetCfg_fnQueryNetCfgClass(
691 INetCfg * iface,
692 const GUID *pguidClass,
693 REFIID riid,
694 void **ppvObject)
695 {
696 return E_FAIL;
697 }
698
699 static const INetCfgVtbl vt_NetCfg =
700 {
701 INetCfg_fnQueryInterface,
702 INetCfg_fnAddRef,
703 INetCfg_fnRelease,
704 INetCfg_fnInitialize,
705 INetCfg_fnUninitialize,
706 INetCfg_fnApply,
707 INetCfg_fnCancel,
708 INetCfg_fnEnumComponents,
709 INetCfg_fnFindComponent,
710 INetCfg_fnQueryNetCfgClass,
711 };
712
713 HRESULT WINAPI INetCfg_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv)
714 {
715 INetCfgImpl *This;
716
717 if (!ppv)
718 return E_POINTER;
719
720 This = (INetCfgImpl *) CoTaskMemAlloc(sizeof (INetCfgImpl));
721 if (!This)
722 return E_OUTOFMEMORY;
723
724 This->ref = 1;
725 This->lpVtbl = (const INetCfg*)&vt_NetCfg;
726 This->lpVtblLock = (const INetCfgLock*)&vt_NetCfgLock;
727 This->hMutex = NULL;
728 This->bInitialized = FALSE;
729 This->pNet = NULL;
730 This->pClient = NULL;
731 This->pService = NULL;
732 This->pProtocol = NULL;
733
734 if (!SUCCEEDED (INetCfg_QueryInterface ((INetCfg*)This, riid, ppv)))
735 {
736 INetCfg_Release((INetCfg*)This);
737 return E_NOINTERFACE;
738 }
739
740 INetCfg_Release((INetCfg*)This);
741 return S_OK;
742 }