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 871