[SYSSETUP][NETCFGX][INF] Install the TCPIP protocol driver properly
[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 hr = INetCfgComponent_GetInstanceGuid(iface, &InstanceGUID);
525 if (FAILED(hr))
526 return hr;
527
528 hr = StringFromCLSID(&InstanceGUID, &pStr);
529 if (FAILED(hr))
530 return hr;
531
532 wcscat(szName, pStr);
533 CoTaskMemFree(pStr);
534
535 wcscat(szName, L"\\NDI");
536
537 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) != ERROR_SUCCESS)
538 return E_FAIL;
539
540 dwSize = sizeof(szName);
541 lRet = RegQueryValueExW(hKey, L"ClsID", NULL, &dwType, (LPBYTE)szName, &dwSize);
542 RegCloseKey(hKey);
543
544 if (lRet != ERROR_SUCCESS && dwType != REG_SZ)
545 return E_FAIL;
546
547 hr = CLSIDFromString(szName, &CLSID_NotifyObject);
548 if (FAILED(hr))
549 return E_FAIL;
550
551 hr = CoCreateInstance(&CLSID_NotifyObject, NULL, CLSCTX_INPROC_SERVER, &IID_INetCfgComponentPropertyUi, (LPVOID*)&pNCCPU);
552 if (FAILED(hr))
553 return E_FAIL;
554
555 hr = INetCfgComponentPropertyUi_QueryInterface(pNCCPU, &IID_INetCfgComponentControl, (LPVOID*)&pNCCC);
556 if (FAILED(hr))
557 {
558 INetCfgComponentPropertyUi_Release(pNCCPU);
559 return hr;
560 }
561
562 hr = INetCfgComponentPropertyUi_QueryPropertyUi(pNCCPU, pUnk);
563 if (FAILED(hr))
564 {
565 INetCfgComponentPropertyUi_Release(pNCCPU);
566 return hr;
567 }
568
569 hr = INetCfgComponentControl_Initialize(pNCCC, iface, This->pNCfg, FALSE);
570 if (FAILED(hr))
571 {
572 INetCfgComponentControl_Release(pNCCC);
573 INetCfgComponentPropertyUi_Release(pNCCPU);
574 return hr;
575 }
576
577 hr = INetCfgComponentPropertyUi_SetContext(pNCCPU, pUnk);
578 if (FAILED(hr))
579 {
580 INetCfgComponentPropertyUi_Release(pNCCPU);
581 return hr;
582 }
583 This->pProperty = pNCCPU;
584 This->pItem->pNCCC = pNCCC;
585
586 return S_OK;
587 }
588
589 static int CALLBACK
590 PropSheetProc(HWND hwndDlg, UINT uMsg, LPARAM lParam)
591 {
592 // NOTE: This callback is needed to set large icon correctly.
593 HICON hIcon;
594 switch (uMsg)
595 {
596 case PSCB_INITIALIZED:
597 {
598 hIcon = LoadIconW(netcfgx_hInstance, MAKEINTRESOURCEW(IDI_INTERNET));
599 SendMessageW(hwndDlg, WM_SETICON, ICON_BIG, (LPARAM)hIcon);
600 break;
601 }
602 }
603 return 0;
604 }
605
606 HRESULT
607 WINAPI
608 INetCfgComponent_fnRaisePropertyUi(
609 INetCfgComponent * iface,
610 IN HWND hwndParent,
611 IN DWORD dwFlags,
612 IN IUnknown *pUnk)
613 {
614 HRESULT hr;
615 DWORD dwDefPages;
616 UINT Pages;
617 PROPSHEETHEADERW pinfo;
618 HPROPSHEETPAGE * hppages;
619 INT_PTR iResult;
620 INetCfgComponentImpl * This = (INetCfgComponentImpl*)iface;
621
622 if (!This->pProperty)
623 {
624 hr = CreateNotificationObject(This,iface, pUnk);
625 if (FAILED(hr))
626 return hr;
627 }
628
629 if (dwFlags == NCRP_QUERY_PROPERTY_UI)
630 return S_OK;
631
632 dwDefPages = 0;
633 Pages = 0;
634
635 hr = INetCfgComponentPropertyUi_MergePropPages(This->pProperty, &dwDefPages, (BYTE**)&hppages, &Pages, hwndParent, NULL);
636 if (FAILED(hr) || !Pages)
637 {
638 return hr;
639 }
640 ZeroMemory(&pinfo, sizeof(PROPSHEETHEADERW));
641 pinfo.dwSize = sizeof(PROPSHEETHEADERW);
642 pinfo.dwFlags = PSH_NOCONTEXTHELP | PSH_PROPTITLE | PSH_NOAPPLYNOW |
643 PSH_USEICONID | PSH_USECALLBACK;
644 pinfo.u3.phpage = hppages;
645 pinfo.hwndParent = hwndParent;
646 pinfo.nPages = Pages;
647 pinfo.hInstance = netcfgx_hInstance;
648 pinfo.pszCaption = This->pItem->szDisplayName;
649 pinfo.u.pszIcon = MAKEINTRESOURCEW(IDI_INTERNET);
650 pinfo.pfnCallback = PropSheetProc;
651
652 iResult = PropertySheetW(&pinfo);
653 CoTaskMemFree(hppages);
654 if (iResult > 0)
655 {
656 /* indicate that settings should be stored */
657 This->pItem->bChanged = TRUE;
658 return S_OK;
659 }
660 return S_FALSE;
661 }
662 static const INetCfgComponentVtbl vt_NetCfgComponent =
663 {
664 INetCfgComponent_fnQueryInterface,
665 INetCfgComponent_fnAddRef,
666 INetCfgComponent_fnRelease,
667 INetCfgComponent_fnGetDisplayName,
668 INetCfgComponent_fnSetDisplayName,
669 INetCfgComponent_fnGetHelpText,
670 INetCfgComponent_fnGetId,
671 INetCfgComponent_fnGetCharacteristics,
672 INetCfgComponent_fnGetInstanceGuid,
673 INetCfgComponent_fnGetPnpDevNodeId,
674 INetCfgComponent_fnGetClassGuid,
675 INetCfgComponent_fnGetBindName,
676 INetCfgComponent_fnGetDeviceStatus,
677 INetCfgComponent_fnOpenParamKey,
678 INetCfgComponent_fnRaisePropertyUi
679 };
680
681 HRESULT
682 WINAPI
683 INetCfgComponent_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv, NetCfgComponentItem * pItem, INetCfg * pNCfg)
684 {
685 INetCfgComponentImpl *This;
686
687 if (!ppv)
688 return E_POINTER;
689
690 This = (INetCfgComponentImpl *) CoTaskMemAlloc(sizeof (INetCfgComponentImpl));
691 if (!This)
692 return E_OUTOFMEMORY;
693
694 This->ref = 1;
695 This->lpVtbl = (const INetCfgComponent*)&vt_NetCfgComponent;
696 This->lpVtblComponentBindings = (const INetCfgComponentBindings*)&vt_NetCfgComponentBindings;
697 This->pProperty = NULL;
698 This->pItem = pItem;
699 This->pNCfg = pNCfg;
700
701 if (!SUCCEEDED (INetCfgComponent_QueryInterface ((INetCfgComponent*)This, riid, ppv)))
702 {
703 INetCfgComponent_Release((INetCfg*)This);
704 return E_NOINTERFACE;
705 }
706
707 INetCfgComponent_Release((INetCfgComponent*)This);
708 return S_OK;
709 }
710
711
712 /***************************************************************
713 * IEnumNetCfgComponent
714 */
715
716 HRESULT
717 WINAPI
718 IEnumNetCfgComponent_fnQueryInterface(
719 IEnumNetCfgComponent * iface,
720 REFIID iid,
721 LPVOID * ppvObj)
722 {
723 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
724 *ppvObj = NULL;
725
726 if (IsEqualIID (iid, &IID_IUnknown) ||
727 IsEqualIID (iid, &IID_IEnumNetCfgComponent))
728 {
729 *ppvObj = This;
730 INetCfg_AddRef(iface);
731 return S_OK;
732 }
733
734 return E_NOINTERFACE;
735 }
736
737
738 ULONG
739 WINAPI
740 IEnumNetCfgComponent_fnAddRef(
741 IEnumNetCfgComponent * iface)
742 {
743 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
744 ULONG refCount = InterlockedIncrement(&This->ref);
745
746 return refCount;
747 }
748
749 ULONG
750 WINAPI
751 IEnumNetCfgComponent_fnRelease(
752 IEnumNetCfgComponent * iface)
753 {
754 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
755 ULONG refCount = InterlockedDecrement(&This->ref);
756
757 return refCount;
758 }
759
760 HRESULT
761 WINAPI
762 IEnumNetCfgComponent_fnNext(
763 IEnumNetCfgComponent * iface,
764 ULONG celt,
765 INetCfgComponent **rgelt,
766 ULONG *pceltFetched)
767 {
768 HRESULT hr;
769 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
770
771 if (!iface || !rgelt)
772 return E_POINTER;
773
774 if (celt != 1)
775 return E_INVALIDARG;
776
777 if (!This->pCurrent)
778 return S_FALSE;
779
780 hr = INetCfgComponent_Constructor (NULL, &IID_INetCfgComponent, (LPVOID*)rgelt, This->pCurrent, This->pNCfg);
781 if (SUCCEEDED(hr))
782 {
783 This->pCurrent = This->pCurrent->pNext;
784 if (pceltFetched)
785 *pceltFetched = 1;
786 }
787 return hr;
788 }
789
790 HRESULT
791 WINAPI
792 IEnumNetCfgComponent_fnSkip(
793 IEnumNetCfgComponent * iface,
794 ULONG celt)
795 {
796 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
797
798 if (!This->pCurrent)
799 return S_FALSE;
800
801 while(celt-- > 0 && This->pCurrent)
802 This->pCurrent = This->pCurrent->pNext;
803
804 if (!celt)
805 return S_OK;
806 else
807 return S_FALSE;
808 }
809
810 HRESULT
811 WINAPI
812 IEnumNetCfgComponent_fnReset(
813 IEnumNetCfgComponent * iface)
814 {
815 IEnumNetCfgComponentImpl * This = (IEnumNetCfgComponentImpl*)iface;
816
817 This->pCurrent = This->pHead;
818 return S_OK;
819 }
820
821 HRESULT
822 WINAPI
823 IEnumNetCfgComponent_fnClone(
824 IEnumNetCfgComponent * iface,
825 IEnumNetCfgComponent **ppenum)
826 {
827 return E_NOTIMPL;
828 }
829
830 static const IEnumNetCfgComponentVtbl vt_EnumNetCfgComponent =
831 {
832 IEnumNetCfgComponent_fnQueryInterface,
833 IEnumNetCfgComponent_fnAddRef,
834 IEnumNetCfgComponent_fnRelease,
835 IEnumNetCfgComponent_fnNext,
836 IEnumNetCfgComponent_fnSkip,
837 IEnumNetCfgComponent_fnReset,
838 IEnumNetCfgComponent_fnClone
839 };
840
841 HRESULT
842 WINAPI
843 IEnumNetCfgComponent_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv, NetCfgComponentItem * pItem, INetCfg * pNCfg)
844 {
845 IEnumNetCfgComponentImpl *This;
846
847 if (!ppv)
848 return E_POINTER;
849
850 This = (IEnumNetCfgComponentImpl *) CoTaskMemAlloc(sizeof (IEnumNetCfgComponentImpl));
851 if (!This)
852 return E_OUTOFMEMORY;
853
854 This->ref = 1;
855 This->lpVtbl = (const IEnumNetCfgComponent*)&vt_EnumNetCfgComponent;
856 This->pCurrent = pItem;
857 This->pHead = pItem;
858 This->pNCfg = pNCfg;
859
860 if (!SUCCEEDED (IEnumNetCfgComponent_QueryInterface ((INetCfgComponent*)This, riid, ppv)))
861 {
862 IEnumNetCfgComponent_Release((INetCfg*)This);
863 return E_NOINTERFACE;
864 }
865
866 IEnumNetCfgComponent_Release((IEnumNetCfgComponent*)This);
867 return S_OK;
868 }
869
870