[NETCFGX] Read a components bind value and implement the IsBoundTo method.
[reactos.git] / dll / win32 / netcfgx / inetcfgcomp_iface.c
1 #include "precomp.h"
2
3 typedef struct
4 {
5 const INetCfgComponent *lpVtbl;
6 const INetCfgComponentBindings *lpVtblComponentBindings;
7 LONG ref;
8 NetCfgComponentItem * pItem;
9 INetCfgComponentPropertyUi * pProperty;
10 INetCfg * pNCfg;
11 } INetCfgComponentImpl;
12
13 typedef struct
14 {
15 const IEnumNetCfgComponent * lpVtbl;
16 LONG ref;
17 NetCfgComponentItem * pCurrent;
18 NetCfgComponentItem * pHead;
19 INetCfg * pNCfg;
20 } IEnumNetCfgComponentImpl;
21
22 static __inline INetCfgComponentImpl* impl_from_INetCfgComponentBindings(INetCfgComponentBindings *iface)
23 {
24 return (INetCfgComponentImpl*)((char *)iface - FIELD_OFFSET(INetCfgComponentImpl, lpVtblComponentBindings));
25 }
26
27
28 /***************************************************************
29 * INetCfgComponentBindings
30 */
31
32 HRESULT
33 WINAPI
34 INetCfgComponentBindings_fnQueryInterface(
35 INetCfgComponentBindings *iface,
36 REFIID iid,
37 LPVOID *ppvObj)
38 {
39 INetCfgComponentImpl *This = impl_from_INetCfgComponentBindings(iface);
40 return INetCfgComponent_QueryInterface((INetCfgComponent*)This, iid, ppvObj);
41 }
42
43 ULONG
44 WINAPI
45 INetCfgComponentBindings_fnAddRef(
46 INetCfgComponentBindings *iface)
47 {
48 INetCfgComponentImpl *This = impl_from_INetCfgComponentBindings(iface);
49 return INetCfgComponent_AddRef((INetCfgComponent*)This);
50 }
51
52 ULONG
53 WINAPI
54 INetCfgComponentBindings_fnRelease(
55 INetCfgComponentBindings *iface)
56 {
57 INetCfgComponentImpl *This = impl_from_INetCfgComponentBindings(iface);
58 return INetCfgComponent_Release((INetCfgComponent*)This);
59 }
60
61 HRESULT
62 WINAPI
63 INetCfgComponentBindings_fnBindTo(
64 INetCfgComponentBindings *iface,
65 INetCfgComponent *pnccItem)
66 {
67 return E_NOTIMPL;
68 }
69
70 HRESULT
71 WINAPI
72 INetCfgComponentBindings_fnUnbindFrom(
73 INetCfgComponentBindings *iface,
74 INetCfgComponent *pnccItem)
75 {
76 return E_NOTIMPL;
77 }
78
79 HRESULT
80 WINAPI
81 INetCfgComponentBindings_fnSupportsBindingInterface(
82 INetCfgComponentBindings *iface,
83 DWORD dwFlags,
84 LPCWSTR pszwInterfaceName)
85 {
86 return E_NOTIMPL;
87 }
88
89 HRESULT
90 WINAPI
91 INetCfgComponentBindings_fnIsBoundTo(
92 INetCfgComponentBindings *iface,
93 INetCfgComponent *pnccItem)
94 {
95 INetCfgComponentImpl *pComponent;
96 PWSTR pszBindName, ptr;
97 INT len;
98
99 pComponent = impl_from_INetCfgComponentBindings(iface);
100 if (pComponent == NULL ||
101 pComponent->pItem == NULL ||
102 pComponent->pItem->pszBinding == NULL)
103 return E_POINTER;
104
105 if (pnccItem == NULL ||
106 ((INetCfgComponentImpl*)pnccItem)->pItem == NULL ||
107 ((INetCfgComponentImpl*)pnccItem)->pItem->szBindName == NULL)
108 return E_POINTER;
109
110 pszBindName = ((INetCfgComponentImpl*)pnccItem)->pItem->szBindName;
111
112 ptr = pComponent->pItem->pszBinding;
113 while (*ptr != UNICODE_NULL)
114 {
115 len = wcslen(ptr);
116
117 if (len > 8 && _wcsicmp(&ptr[8], pszBindName) == 0)
118 return S_OK;
119
120 ptr = ptr + len + 1;
121 }
122
123 return S_FALSE;
124 }
125
126 HRESULT
127 WINAPI
128 INetCfgComponentBindings_fnIsBindableTo(
129 INetCfgComponentBindings *iface,
130 INetCfgComponent *pnccItem)
131 {
132 return E_NOTIMPL;
133 }
134
135 HRESULT
136 WINAPI
137 INetCfgComponentBindings_fnEnumBindingPaths(
138 INetCfgComponentBindings *iface,
139 DWORD dwFlags,
140 IEnumNetCfgBindingPath **ppIEnum)
141 {
142 return IEnumNetCfgBindingPath_Constructor(NULL, &IID_IEnumNetCfgBindingPath, (LPVOID *)ppIEnum, dwFlags);
143 }
144
145 HRESULT
146 WINAPI
147 INetCfgComponentBindings_fnMoveBefore(
148 INetCfgComponentBindings *iface,
149 DWORD dwFlags,
150 INetCfgBindingPath *pncbItemSrc,
151 INetCfgBindingPath *pncbItemDest)
152 {
153 return E_NOTIMPL;
154 }
155
156 HRESULT
157 WINAPI
158 INetCfgComponentBindings_fnMoveAfter(
159 INetCfgComponentBindings *iface,
160 DWORD dwFlags,
161 INetCfgBindingPath *pncbItemSrc,
162 INetCfgBindingPath *pncbItemDest)
163 {
164 return E_NOTIMPL;
165 }
166
167 static const INetCfgComponentBindingsVtbl vt_NetCfgComponentBindings =
168 {
169 INetCfgComponentBindings_fnQueryInterface,
170 INetCfgComponentBindings_fnAddRef,
171 INetCfgComponentBindings_fnRelease,
172 INetCfgComponentBindings_fnBindTo,
173 INetCfgComponentBindings_fnUnbindFrom,
174 INetCfgComponentBindings_fnSupportsBindingInterface,
175 INetCfgComponentBindings_fnIsBoundTo,
176 INetCfgComponentBindings_fnIsBindableTo,
177 INetCfgComponentBindings_fnEnumBindingPaths,
178 INetCfgComponentBindings_fnMoveBefore,
179 INetCfgComponentBindings_fnMoveAfter,
180 };
181
182 /***************************************************************
183 * INetCfgComponent
184 */
185
186 HRESULT
187 WINAPI
188 INetCfgComponent_fnQueryInterface(
189 INetCfgComponent * iface,
190 REFIID iid,
191 LPVOID * ppvObj)
192 {
193 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
194 *ppvObj = NULL;
195
196 if (IsEqualIID (iid, &IID_IUnknown) ||
197 IsEqualIID (iid, &IID_INetCfgComponent))
198 {
199 *ppvObj = This;
200 INetCfg_AddRef(iface);
201 return S_OK;
202 }
203 else if (IsEqualIID (iid, &IID_INetCfgComponentBindings))
204 {
205 *ppvObj = (LPVOID)&This->lpVtblComponentBindings;
206 INetCfgComponentBindings_AddRef(iface);
207 return S_OK;
208 }
209
210 return E_NOINTERFACE;
211 }
212
213 ULONG
214 WINAPI
215 INetCfgComponent_fnAddRef(
216 INetCfgComponent * iface)
217 {
218 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
219 ULONG refCount = InterlockedIncrement(&This->ref);
220
221 return refCount;
222 }
223
224 ULONG
225 WINAPI
226 INetCfgComponent_fnRelease(
227 INetCfgComponent * iface)
228 {
229 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
230 ULONG refCount = InterlockedDecrement(&This->ref);
231
232 if (!refCount)
233 {
234 CoTaskMemFree(This);
235 }
236 return refCount;
237 }
238
239 HRESULT
240 WINAPI
241 INetCfgComponent_fnGetDisplayName(
242 INetCfgComponent * iface,
243 LPWSTR * ppszwDisplayName)
244 {
245 LPWSTR szName;
246 UINT Length;
247 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
248
249 if (This == NULL || ppszwDisplayName == NULL)
250 return E_POINTER;
251
252 if (This->pItem->szDisplayName)
253 Length = wcslen(This->pItem->szDisplayName)+1;
254 else
255 Length = 1;
256
257 szName = CoTaskMemAlloc(Length * sizeof(WCHAR));
258 if (!szName)
259 return E_OUTOFMEMORY;
260
261 if (Length > 1)
262 wcscpy(szName, This->pItem->szDisplayName);
263 else
264 szName[0] = L'\0';
265
266 *ppszwDisplayName = szName;
267
268 return S_OK;
269 }
270
271 HRESULT
272 WINAPI
273 INetCfgComponent_fnSetDisplayName(
274 INetCfgComponent * iface,
275 LPCWSTR ppszwDisplayName)
276 {
277 LPWSTR szName;
278 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
279
280 if (This == NULL || ppszwDisplayName == NULL)
281 return E_POINTER;
282
283 /* setting name is only supported for network cards */
284 if (!IsEqualGUID(&This->pItem->ClassGUID, &GUID_DEVCLASS_NET))
285 return E_NOTIMPL;
286
287 /// FIXME
288 /// check for invalid characters
289 /// check for write lock
290
291 szName = CoTaskMemAlloc((wcslen(ppszwDisplayName)+1) * sizeof(WCHAR));
292 if (!szName)
293 return E_OUTOFMEMORY;
294
295 wcscpy(szName, ppszwDisplayName);
296 CoTaskMemFree(This->pItem->szDisplayName);
297 This->pItem->szDisplayName = szName;
298 This->pItem->bChanged = TRUE;
299
300 return S_OK;
301 }
302
303 HRESULT
304 WINAPI
305 INetCfgComponent_fnGetHelpText(
306 INetCfgComponent * iface,
307 LPWSTR * ppszwHelpText)
308 {
309 LPWSTR szHelp;
310 UINT Length;
311 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
312
313 if (This == NULL || ppszwHelpText == NULL)
314 return E_POINTER;
315
316 if (This->pItem->szHelpText)
317 Length = wcslen(This->pItem->szHelpText)+1;
318 else
319 Length = 1;
320
321 szHelp = CoTaskMemAlloc(Length * sizeof(WCHAR));
322 if (!szHelp)
323 return E_OUTOFMEMORY;
324
325 if (Length > 1)
326 wcscpy(szHelp, This->pItem->szHelpText);
327 else
328 szHelp[0] = L'\0';
329
330 *ppszwHelpText = szHelp;
331
332 return S_OK;
333 }
334
335 HRESULT
336 WINAPI
337 INetCfgComponent_fnGetId(
338 INetCfgComponent * iface,
339 LPWSTR * ppszwId)
340 {
341 LPWSTR szId;
342 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
343
344 if (This == NULL || ppszwId == NULL)
345 return E_POINTER;
346
347 szId = CoTaskMemAlloc((wcslen(This->pItem->szId)+1) * sizeof(WCHAR));
348 if (!szId)
349 return E_OUTOFMEMORY;
350
351 wcscpy(szId, This->pItem->szId);
352 *ppszwId = szId;
353
354 return S_OK;
355 }
356
357 HRESULT
358 WINAPI
359 INetCfgComponent_fnGetCharacteristics(
360 INetCfgComponent * iface,
361 DWORD * pdwCharacteristics)
362 {
363 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
364
365 if (This == NULL || pdwCharacteristics == NULL)
366 return E_POINTER;
367
368 *pdwCharacteristics = This->pItem->dwCharacteristics;
369
370 return S_OK;
371 }
372
373 HRESULT
374 WINAPI
375 INetCfgComponent_fnGetInstanceGuid(
376 INetCfgComponent * iface,
377 GUID * pGuid)
378 {
379 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
380
381 if (This == NULL || pGuid == NULL)
382 return E_POINTER;
383
384 CopyMemory(pGuid, &This->pItem->InstanceId, sizeof(GUID));
385 return S_OK;
386 }
387
388 HRESULT
389 WINAPI
390 INetCfgComponent_fnGetPnpDevNodeId(
391 INetCfgComponent * iface,
392 LPWSTR * ppszwDevNodeId)
393 {
394 LPWSTR szNode;
395 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
396
397 if (This == NULL || ppszwDevNodeId == NULL)
398 return E_POINTER;
399
400 if (!IsEqualGUID(&GUID_DEVCLASS_NET, &This->pItem->ClassGUID))
401 return E_NOTIMPL;
402
403 szNode = CoTaskMemAlloc((wcslen(This->pItem->szNodeId)+1) * sizeof(WCHAR));
404 if (!szNode)
405 return E_OUTOFMEMORY;
406
407 wcscpy(szNode, This->pItem->szNodeId);
408 *ppszwDevNodeId = szNode;
409 return S_OK;
410 }
411
412 HRESULT
413 WINAPI
414 INetCfgComponent_fnGetClassGuid(
415 INetCfgComponent * iface,
416 GUID * pGuid)
417 {
418 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
419
420 if (This == NULL || pGuid == NULL)
421 return E_POINTER;
422
423 CopyMemory(pGuid, &This->pItem->ClassGUID, sizeof(GUID));
424 return S_OK;
425 }
426
427 HRESULT
428 WINAPI
429 INetCfgComponent_fnGetBindName(
430 INetCfgComponent * iface,
431 LPWSTR * ppszwBindName)
432 {
433 LPWSTR szBind;
434 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
435
436 if (This == NULL || ppszwBindName == NULL)
437 return E_POINTER;
438
439 szBind = CoTaskMemAlloc((wcslen(This->pItem->szBindName)+1) * sizeof(WCHAR));
440 if (!szBind)
441 return E_OUTOFMEMORY;
442
443 wcscpy(szBind, This->pItem->szBindName);
444 *ppszwBindName = szBind;
445
446 return S_OK;
447 }
448
449 HRESULT
450 WINAPI
451 INetCfgComponent_fnGetDeviceStatus(
452 INetCfgComponent * iface,
453 ULONG * pStatus)
454 {
455 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
456
457 if (This == NULL || pStatus == NULL)
458 return E_POINTER;
459
460 if (!IsEqualGUID(&GUID_DEVCLASS_NET, &This->pItem->ClassGUID))
461 return E_UNEXPECTED;
462
463 *pStatus = This->pItem->Status;
464
465 return S_OK;
466 }
467
468 HRESULT
469 WINAPI
470 INetCfgComponent_fnOpenParamKey(
471 INetCfgComponent * iface,
472 HKEY * phkey)
473 {
474 WCHAR szBuffer[200] = L"SYSTEM\\CurrentControlSet\\Services\\";
475 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
476
477 if (This == NULL || phkey == NULL)
478 return E_POINTER;
479
480 wcscat(szBuffer, This->pItem->szBindName);
481 wcscat(szBuffer, L"\\Parameters");
482
483 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ | KEY_WRITE, phkey) == ERROR_SUCCESS)
484 return S_OK;
485 else
486 return E_FAIL;
487 }
488
489
490 HRESULT
491 CreateNotificationObject(
492 INetCfgComponentImpl * This,
493 INetCfgComponent * iface,
494 IUnknown *pUnk)
495 {
496 WCHAR szName[150];
497 HKEY hKey;
498 DWORD dwSize, dwType;
499 GUID CLSID_NotifyObject;
500 LPOLESTR pStr;
501 INetCfgComponentPropertyUi * pNCCPU;
502 INetCfgComponentControl * pNCCC;
503 HRESULT hr;
504 LONG lRet;
505 CLSID ClassGUID;
506 //CLSID InstanceGUID;
507
508 wcscpy(szName,L"SYSTEM\\CurrentControlSet\\Control\\Network\\");
509
510 /* get the Class GUID */
511 hr = INetCfgComponent_GetClassGuid(iface, &ClassGUID);
512 if (FAILED(hr))
513 return hr;
514
515 hr = StringFromCLSID(&ClassGUID, &pStr);
516 if (FAILED(hr))
517 return hr;
518
519 wcscat(szName, pStr);
520 CoTaskMemFree(pStr);
521 wcscat(szName, L"\\");
522
523 /* get the Instance GUID */
524 #if 0
525 hr = INetCfgComponent_GetInstanceGuid(iface, &InstanceGUID);
526 if (FAILED(hr))
527 return hr;
528
529 hr = StringFromCLSID(&InstanceGUID, &pStr);
530 if (FAILED(hr))
531 return hr;
532
533 wcscat(szName, pStr);
534 CoTaskMemFree(pStr);
535 #else
536 // HACK HACK HACK HACK HACK
537 wcscat(szName, L"{RandomProtocolGUID_TCPIP}");
538 #endif
539
540 wcscat(szName, L"\\NDI");
541
542 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
543 return E_FAIL;
544
545 dwSize = sizeof(szName);
546 lRet = RegQueryValueExW(hKey, L"ClsID", NULL, &dwType, (LPBYTE)szName, &dwSize);
547 RegCloseKey(hKey);
548
549 if (lRet != ERROR_SUCCESS && dwType != REG_SZ)
550 return E_FAIL;
551
552 hr = CLSIDFromString(szName, &CLSID_NotifyObject);
553 if (FAILED(hr))
554 return E_FAIL;
555
556 hr = CoCreateInstance(&CLSID_NotifyObject, NULL, CLSCTX_INPROC_SERVER, &IID_INetCfgComponentPropertyUi, (LPVOID*)&pNCCPU);
557 if (FAILED(hr))
558 return E_FAIL;
559
560 hr = INetCfgComponentPropertyUi_QueryInterface(pNCCPU, &IID_INetCfgComponentControl, (LPVOID*)&pNCCC);
561 if (FAILED(hr))
562 {
563 INetCfgComponentPropertyUi_Release(pNCCPU);
564 return hr;
565 }
566
567 hr = INetCfgComponentPropertyUi_QueryPropertyUi(pNCCPU, pUnk);
568 if (FAILED(hr))
569 {
570 INetCfgComponentPropertyUi_Release(pNCCPU);
571 return hr;
572 }
573
574 hr = INetCfgComponentControl_Initialize(pNCCC, iface, This->pNCfg, FALSE);
575 if (FAILED(hr))
576 {
577 INetCfgComponentControl_Release(pNCCC);
578 INetCfgComponentPropertyUi_Release(pNCCPU);
579 return hr;
580 }
581
582 hr = INetCfgComponentPropertyUi_SetContext(pNCCPU, pUnk);
583 if (FAILED(hr))
584 {
585 INetCfgComponentPropertyUi_Release(pNCCPU);
586 return hr;
587 }
588 This->pProperty = pNCCPU;
589 This->pItem->pNCCC = pNCCC;
590
591 return S_OK;
592 }
593
594 static int CALLBACK
595 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
596 {
597 // NOTE: This callback is needed to set large icon correctly.
598 HICON hIcon;
599 switch (uMsg)
600 {
601 case PSCB_INITIALIZED:
602 {
603 hIcon = LoadIconW(netcfgx_hInstance, MAKEINTRESOURCEW(IDI_INTERNET));
604 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
605 break;
606 }
607 }
608 return 0;
609 }
610
611 HRESULT
612 WINAPI
613 INetCfgComponent_fnRaisePropertyUi(
614 INetCfgComponent * iface,
615 IN HWND hwndParent,
616 IN DWORD dwFlags,
617 IN IUnknown *pUnk)
618 {
619 HRESULT hr;
620 DWORD dwDefPages;
621 UINT Pages;
622 PROPSHEETHEADERW pinfo;
623 HPROPSHEETPAGE * hppages;
624 INT_PTR iResult;
625 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
626
627 if (!This->pProperty)
628 {
629 hr = CreateNotificationObject(This,iface, pUnk);
630 if (FAILED(hr))
631 return hr;
632 }
633
634 if (dwFlags == NCRP_QUERY_PROPERTY_UI)
635 return S_OK;
636
637 dwDefPages = 0;
638 Pages = 0;
639
640 hr = INetCfgComponentPropertyUi_MergePropPages(This->pProperty, &dwDefPages, (BYTE**)&hppages, &Pages, hwndParent, NULL);
641 if (FAILED(hr) || !Pages)
642 {
643 return hr;
644 }
645 ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW));
646 pinfo.dwSize = sizeof(PROPSHEETHEADERW);
647 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW |
648 PSH_USEICONID | PSH_USECALLBACK;
649 pinfo.u3.phpage = hppages;
650 pinfo.hwndParent = hwndParent;
651 pinfo.nPages = Pages;
652 pinfo.hInstance = netcfgx_hInstance;
653 pinfo.pszCaption = This->pItem->szDisplayName;
654 pinfo.u.pszIcon = MAKEINTRESOURCEW(IDI_INTERNET);
655 pinfo.pfnCallback = PropSheetProc;
656
657 iResult = PropertySheetW(&pinfo);
658 CoTaskMemFree(hppages);
659 if (iResult > 0)
660 {
661 /* indicate that settings should be stored */
662 This->pItem->bChanged = TRUE;
663 return S_OK;
664 }
665 return S_FALSE;
666 }
667 static const INetCfgComponentVtbl vt_NetCfgComponent =
668 {
669 INetCfgComponent_fnQueryInterface,
670 INetCfgComponent_fnAddRef,
671 INetCfgComponent_fnRelease,
672 INetCfgComponent_fnGetDisplayName,
673 INetCfgComponent_fnSetDisplayName,
674 INetCfgComponent_fnGetHelpText,
675 INetCfgComponent_fnGetId,
676 INetCfgComponent_fnGetCharacteristics,
677 INetCfgComponent_fnGetInstanceGuid,
678 INetCfgComponent_fnGetPnpDevNodeId,
679 INetCfgComponent_fnGetClassGuid,
680 INetCfgComponent_fnGetBindName,
681 INetCfgComponent_fnGetDeviceStatus,
682 INetCfgComponent_fnOpenParamKey,
683 INetCfgComponent_fnRaisePropertyUi
684 };
685
686 HRESULT
687 WINAPI
688 INetCfgComponent_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv, NetCfgComponentItem * pItem, INetCfg * pNCfg)
689 {
690 INetCfgComponentImpl *This;
691
692 if (!ppv)
693 return E_POINTER;
694
695 This = (INetCfgComponentImpl *) CoTaskMemAlloc(sizeof (INetCfgComponentImpl));
696 if (!This)
697 return E_OUTOFMEMORY;
698
699 This->ref = 1;
700 This->lpVtbl = (const INetCfgComponent*)&vt_NetCfgComponent;
701 This->lpVtblComponentBindings = (const INetCfgComponentBindings*)&vt_NetCfgComponentBindings;
702 This->pProperty = NULL;
703 This->pItem = pItem;
704 This->pNCfg = pNCfg;
705
706 if (!SUCCEEDED (INetCfgComponent_QueryInterface ((INetCfgComponent*)This, riid, ppv)))
707 {
708 INetCfgComponent_Release((INetCfg*)This);
709 return E_NOINTERFACE;
710 }
711
712 INetCfgComponent_Release((INetCfgComponent*)This);
713 return S_OK;
714 }
715
716
717 /***************************************************************
718 * IEnumNetCfgComponent
719 */
720
721 HRESULT
722 WINAPI
723 IEnumNetCfgComponent_fnQueryInterface(
724 IEnumNetCfgComponent * iface,
725 REFIID iid,
726 LPVOID * ppvObj)
727 {
728 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
729 *ppvObj = NULL;
730
731 if (IsEqualIID (iid, &IID_IUnknown) ||
732 IsEqualIID (iid, &IID_IEnumNetCfgComponent))
733 {
734 *ppvObj = This;
735 INetCfg_AddRef(iface);
736 return S_OK;
737 }
738
739 return E_NOINTERFACE;
740 }
741
742
743 ULONG
744 WINAPI
745 IEnumNetCfgComponent_fnAddRef(
746 IEnumNetCfgComponent * iface)
747 {
748 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
749 ULONG refCount = InterlockedIncrement(&This->ref);
750
751 return refCount;
752 }
753
754 ULONG
755 WINAPI
756 IEnumNetCfgComponent_fnRelease(
757 IEnumNetCfgComponent * iface)
758 {
759 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
760 ULONG refCount = InterlockedDecrement(&This->ref);
761
762 return refCount;
763 }
764
765 HRESULT
766 WINAPI
767 IEnumNetCfgComponent_fnNext(
768 IEnumNetCfgComponent * iface,
769 ULONG celt,
770 INetCfgComponent **rgelt,
771 ULONG *pceltFetched)
772 {
773 HRESULT hr;
774 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
775
776 if (!iface || !rgelt)
777 return E_POINTER;
778
779 if (celt != 1)
780 return E_INVALIDARG;
781
782 if (!This->pCurrent)
783 return S_FALSE;
784
785 hr = INetCfgComponent_Constructor (NULL, &IID_INetCfgComponent, (LPVOID*)rgelt, This->pCurrent, This->pNCfg);
786 if (SUCCEEDED(hr))
787 {
788 This->pCurrent = This->pCurrent->pNext;
789 if (pceltFetched)
790 *pceltFetched = 1;
791 }
792 return hr;
793 }
794
795 HRESULT
796 WINAPI
797 IEnumNetCfgComponent_fnSkip(
798 IEnumNetCfgComponent * iface,
799 ULONG celt)
800 {
801 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
802
803 if (!This->pCurrent)
804 return S_FALSE;
805
806 while(celt-- > 0 && This->pCurrent)
807 This->pCurrent = This->pCurrent->pNext;
808
809 if (!celt)
810 return S_OK;
811 else
812 return S_FALSE;
813 }
814
815 HRESULT
816 WINAPI
817 IEnumNetCfgComponent_fnReset(
818 IEnumNetCfgComponent * iface)
819 {
820 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
821
822 This->pCurrent = This->pHead;
823 return S_OK;
824 }
825
826 HRESULT
827 WINAPI
828 IEnumNetCfgComponent_fnClone(
829 IEnumNetCfgComponent * iface,
830 IEnumNetCfgComponent **ppenum)
831 {
832 return E_NOTIMPL;
833 }
834
835 static const IEnumNetCfgComponentVtbl vt_EnumNetCfgComponent =
836 {
837 IEnumNetCfgComponent_fnQueryInterface,
838 IEnumNetCfgComponent_fnAddRef,
839 IEnumNetCfgComponent_fnRelease,
840 IEnumNetCfgComponent_fnNext,
841 IEnumNetCfgComponent_fnSkip,
842 IEnumNetCfgComponent_fnReset,
843 IEnumNetCfgComponent_fnClone
844 };
845
846 HRESULT
847 WINAPI
848 IEnumNetCfgComponent_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv, NetCfgComponentItem * pItem, INetCfg * pNCfg)
849 {
850 IEnumNetCfgComponentImpl *This;
851
852 if (!ppv)
853 return E_POINTER;
854
855 This = (IEnumNetCfgComponentImpl *) CoTaskMemAlloc(sizeof (IEnumNetCfgComponentImpl));
856 if (!This)
857 return E_OUTOFMEMORY;
858
859 This->ref = 1;
860 This->lpVtbl = (const IEnumNetCfgComponent*)&vt_EnumNetCfgComponent;
861 This->pCurrent = pItem;
862 This->pHead = pItem;
863 This->pNCfg = pNCfg;
864
865 if (!SUCCEEDED (IEnumNetCfgComponent_QueryInterface ((INetCfgComponent*)This, riid, ppv)))
866 {
867 IEnumNetCfgComponent_Release((INetCfg*)This);
868 return E_NOINTERFACE;
869 }
870
871 IEnumNetCfgComponent_Release((IEnumNetCfgComponent*)This);
872 return S_OK;
873 }
874
875