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 876