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