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 ReadBindingString( 231 NetCfgComponentItem *Item) 232 { 233 WCHAR szBuffer[200]; 234 HKEY hKey; 235 DWORD dwType, dwSize; 236 237 if (Item == NULL || Item->szBindName == NULL) 238 return S_OK; 239 240 wcscpy(szBuffer, L"SYSTEM\\CurrentControlSet\\Services\\"); 241 wcscat(szBuffer, Item->szBindName); 242 wcscat(szBuffer, L"\\Linkage"); 243 244 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szBuffer, 0, KEY_READ, &hKey) == ERROR_SUCCESS) 245 { 246 dwSize = 0; 247 RegQueryValueExW(hKey, L"Bind", NULL, &dwType, NULL, &dwSize); 248 249 if (dwSize != 0) 250 { 251 Item->pszBinding = CoTaskMemAlloc(dwSize); 252 if (Item->pszBinding == NULL) 253 return E_OUTOFMEMORY; 254 255 RegQueryValueExW(hKey, L"Bind", NULL, &dwType, (LPBYTE)Item->pszBinding, &dwSize); 256 } 257 258 RegCloseKey(hKey); 259 } 260 261 return S_OK; 262 } 263 264 HRESULT 265 EnumClientServiceProtocol(HKEY hKey, const GUID * pGuid, NetCfgComponentItem ** pHead) 266 { 267 DWORD dwIndex = 0; 268 DWORD dwSize; 269 DWORD dwType; 270 WCHAR szName[100]; 271 WCHAR szText[100]; 272 HKEY hSubKey, hNDIKey; 273 NetCfgComponentItem * pLast = NULL, *pCurrent; 274 275 *pHead = NULL; 276 do 277 { 278 szText[0] = L'\0'; 279 280 dwSize = sizeof(szName)/sizeof(WCHAR); 281 if (RegEnumKeyExW(hKey, dwIndex++, szName, &dwSize, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) 282 { 283 pCurrent = CoTaskMemAlloc(sizeof(NetCfgComponentItem)); 284 if (!pCurrent) 285 return E_OUTOFMEMORY; 286 287 ZeroMemory(pCurrent, sizeof(NetCfgComponentItem)); 288 CopyMemory(&pCurrent->ClassGUID, pGuid, sizeof(GUID)); 289 290 if (FAILED(CLSIDFromString(szName, &pCurrent->InstanceId))) 291 { 292 /// ReactOS tcpip guid is not yet generated 293 //CoTaskMemFree(pCurrent); 294 //return E_FAIL; 295 } 296 if (RegOpenKeyExW(hKey, szName, 0, KEY_READ, &hSubKey) == ERROR_SUCCESS) 297 { 298 /* retrieve Characteristics */ 299 dwSize = sizeof(DWORD); 300 301 RegQueryValueExW(hSubKey, L"Characteristics", NULL, &dwType, (LPBYTE)&pCurrent->dwCharacteristics, &dwSize); 302 if (dwType != REG_DWORD) 303 pCurrent->dwCharacteristics = 0; 304 305 /* retrieve ComponentId */ 306 dwSize = sizeof(szText); 307 if (RegQueryValueExW(hSubKey, L"ComponentId", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS) 308 { 309 if (dwType == REG_SZ) 310 { 311 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; 312 pCurrent->szId = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR)); 313 if (pCurrent->szId) 314 wcscpy(pCurrent->szId, szText); 315 } 316 } 317 318 /* retrieve Description */ 319 dwSize = sizeof(szText); 320 if (RegQueryValueExW(hSubKey, L"Description", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS) 321 { 322 if (dwType == REG_SZ) 323 { 324 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; 325 pCurrent->szDisplayName = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR)); 326 if (pCurrent->szDisplayName) 327 wcscpy(pCurrent->szDisplayName, szText); 328 } 329 } 330 331 if (RegOpenKeyExW(hSubKey, L"NDI", 0, KEY_READ, &hNDIKey) == ERROR_SUCCESS) 332 { 333 /* retrieve HelpText */ 334 dwSize = sizeof(szText); 335 if (RegQueryValueExW(hNDIKey, L"HelpText", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS) 336 { 337 if (dwType == REG_SZ) 338 { 339 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; 340 pCurrent->szHelpText = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR)); 341 if (pCurrent->szHelpText) 342 wcscpy(pCurrent->szHelpText, szText); 343 } 344 } 345 346 /* retrieve Service */ 347 dwSize = sizeof(szText); 348 if (RegQueryValueExW(hNDIKey, L"Service", NULL, &dwType, (LPBYTE)szText, &dwSize) == ERROR_SUCCESS) 349 { 350 if (dwType == REG_SZ) 351 { 352 szText[(sizeof(szText)/sizeof(WCHAR))-1] = L'\0'; 353 pCurrent->szBindName = CoTaskMemAlloc((wcslen(szText)+1)* sizeof(WCHAR)); 354 if (pCurrent->szBindName) 355 wcscpy(pCurrent->szBindName, szText); 356 } 357 } 358 RegCloseKey(hNDIKey); 359 } 360 RegCloseKey(hSubKey); 361 362 ReadBindingString(pCurrent); 363 364 if (!pLast) 365 *pHead = pCurrent; 366 else 367 pLast->pNext = pCurrent; 368 369 pLast = pCurrent; 370 } 371 } 372 else 373 break; 374 375 }while(TRUE); 376 return S_OK; 377 } 378 379 380 381 HRESULT 382 EnumerateNetworkComponent( 383 const GUID *pGuid, NetCfgComponentItem ** pHead) 384 { 385 HKEY hKey; 386 LPOLESTR pszGuid; 387 HRESULT hr; 388 WCHAR szName[150]; 389 390 hr = StringFromCLSID(pGuid, &pszGuid); 391 if (SUCCEEDED(hr)) 392 { 393 swprintf(szName, L"SYSTEM\\CurrentControlSet\\Control\\Network\\%s", pszGuid); 394 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) 395 { 396 hr = EnumClientServiceProtocol(hKey, pGuid, pHead); 397 RegCloseKey(hKey); 398 } 399 CoTaskMemFree(pszGuid); 400 } 401 return hr; 402 } 403 404 HRESULT 405 EnumerateNetworkAdapter(NetCfgComponentItem ** pHead) 406 { 407 DWORD dwSize, dwIndex; 408 HDEVINFO hInfo; 409 SP_DEVINFO_DATA DevInfo; 410 HKEY hKey; 411 WCHAR szNetCfg[50]; 412 WCHAR szAdapterNetCfg[MAX_DEVICE_ID_LEN]; 413 WCHAR szDetail[200] = L"SYSTEM\\CurrentControlSet\\Control\\Class\\"; 414 WCHAR szName[130] = L"SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\"; 415 NetCfgComponentItem * pLast = NULL, *pCurrent; 416 417 hInfo = SetupDiGetClassDevs(&GUID_DEVCLASS_NET, NULL, NULL, DIGCF_PRESENT ); 418 if (!hInfo) 419 { 420 return E_FAIL; 421 } 422 423 dwIndex = 0; 424 do 425 { 426 ZeroMemory(&DevInfo, sizeof(SP_DEVINFO_DATA)); 427 DevInfo.cbSize = sizeof(DevInfo); 428 429 /* get device info */ 430 if (!SetupDiEnumDeviceInfo(hInfo, dwIndex++, &DevInfo)) 431 break; 432 433 /* get device software registry path */ 434 if (!SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DRIVER, NULL, (LPBYTE)&szDetail[39], sizeof(szDetail)/sizeof(WCHAR) - 40, &dwSize)) 435 break; 436 437 /* open device registry key */ 438 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szDetail, 0, KEY_READ, &hKey) != ERROR_SUCCESS) 439 break; 440 441 /* query NetCfgInstanceId for current device */ 442 dwSize = sizeof(szNetCfg); 443 if (RegQueryValueExW(hKey, L"NetCfgInstanceId", NULL, NULL, (LPBYTE)szNetCfg, &dwSize) != ERROR_SUCCESS) 444 { 445 RegCloseKey(hKey); 446 break; 447 } 448 449 /* allocate new INetConnectionItem */ 450 pCurrent = CoTaskMemAlloc(sizeof(NetCfgComponentItem)); 451 if (!pCurrent) 452 break; 453 454 ZeroMemory(pCurrent, sizeof(NetCfgComponentItem)); 455 CopyMemory(&pCurrent->ClassGUID, &GUID_DEVCLASS_NET, sizeof(GUID)); 456 CLSIDFromString(szNetCfg, &pCurrent->InstanceId); //FIXME 457 458 /* set bind name */ 459 pCurrent->szBindName = CoTaskMemAlloc((wcslen(szNetCfg)+1) *sizeof(WCHAR)); 460 if (pCurrent->szBindName) 461 wcscpy(pCurrent->szBindName, szNetCfg); 462 463 /* retrieve ComponentId */ 464 dwSize = sizeof(szAdapterNetCfg); 465 if (RegQueryValueExW(hKey, L"ComponentId", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS) 466 { 467 pCurrent->szId = CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR)); 468 if (pCurrent->szId) 469 wcscpy(pCurrent->szId, szAdapterNetCfg); 470 } 471 /* set INetCfgComponent::GetDisplayName */ 472 dwSize = sizeof(szAdapterNetCfg); 473 if (RegQueryValueExW(hKey, L"DriverDesc", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS) 474 { 475 pCurrent->szDisplayName = CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR)); 476 if (pCurrent->szDisplayName) 477 wcscpy(pCurrent->szDisplayName, szAdapterNetCfg); 478 } 479 480 RegCloseKey(hKey); 481 /* open network connections details */ 482 wcscpy(&szName[80], szNetCfg); 483 wcscpy(&szName[118], L"\\Connection"); 484 485 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) 486 { 487 /* retrieve pnp instance id */ 488 dwSize = sizeof(szAdapterNetCfg); 489 if (RegQueryValueExW(hKey, L"PnpInstanceID", NULL, NULL, (LPBYTE)szAdapterNetCfg, &dwSize) == ERROR_SUCCESS) 490 { 491 pCurrent->szNodeId = CoTaskMemAlloc((wcslen(szAdapterNetCfg)+1) * sizeof(WCHAR)); 492 if (pCurrent->szNodeId) 493 wcscpy(pCurrent->szNodeId, szAdapterNetCfg); 494 } 495 RegCloseKey(hKey); 496 } 497 498 if (SetupDiGetDeviceRegistryPropertyW(hInfo, &DevInfo, SPDRP_DEVICEDESC, NULL, (PBYTE)szNetCfg, sizeof(szNetCfg)/sizeof(WCHAR), &dwSize)) 499 { 500 szNetCfg[(sizeof(szNetCfg)/sizeof(WCHAR))-1] = L'\0'; 501 pCurrent->szDisplayName = CoTaskMemAlloc((wcslen(szNetCfg)+1) * sizeof(WCHAR)); 502 if (pCurrent->szDisplayName) 503 wcscpy(pCurrent->szDisplayName, szNetCfg); 504 } 505 506 if (pLast) 507 pLast->pNext = pCurrent; 508 else 509 *pHead = pCurrent; 510 511 pLast = pCurrent; 512 513 }while(TRUE); 514 515 SetupDiDestroyDeviceInfoList(hInfo); 516 return NOERROR; 517 } 518 519 520 HRESULT 521 FindNetworkComponent( 522 NetCfgComponentItem * pHead, 523 LPCWSTR pszwComponentId, 524 INetCfgComponent **pComponent, 525 INetCfg * iface) 526 { 527 while(pHead) 528 { 529 if (!_wcsicmp(pHead->szId, pszwComponentId)) 530 { 531 return INetCfgComponent_Constructor(NULL, &IID_INetCfgComponent, (LPVOID*)pComponent, pHead, iface); 532 } 533 pHead = pHead->pNext; 534 } 535 return S_FALSE; 536 } 537 538 539 540 HRESULT 541 WINAPI 542 INetCfg_fnQueryInterface( 543 INetCfg * iface, 544 REFIID iid, 545 LPVOID * ppvObj) 546 { 547 INetCfgImpl * This = (INetCfgImpl*)iface; 548 *ppvObj = NULL; 549 550 if (IsEqualIID (iid, &IID_IUnknown) || 551 IsEqualIID (iid, &IID_INetCfg)) 552 { 553 *ppvObj = This; 554 INetCfg_AddRef(iface); 555 return S_OK; 556 } 557 else if (IsEqualIID (iid, &IID_INetCfgLock)) 558 { 559 if (This->bInitialized) 560 return NETCFG_E_ALREADY_INITIALIZED; 561 562 *ppvObj = (LPVOID)&This->lpVtblLock; 563 This->hMutex = CreateMutexW(NULL, FALSE, L"NetCfgLock"); 564 565 INetCfgLock_AddRef(iface); 566 return S_OK; 567 } 568 else if (IsEqualIID (iid, &IID_INetCfgPnpReconfigCallback)) 569 { 570 if (This->bInitialized) 571 return NETCFG_E_ALREADY_INITIALIZED; 572 573 *ppvObj = (LPVOID)&This->lpVtblPnpReconfigCallback; 574 INetCfgPnpReconfigCallback_AddRef(iface); 575 return S_OK; 576 } 577 578 return E_NOINTERFACE; 579 } 580 581 ULONG 582 WINAPI 583 INetCfg_fnAddRef( 584 INetCfg * iface) 585 { 586 INetCfgImpl * This = (INetCfgImpl*)iface; 587 ULONG refCount = InterlockedIncrement(&This->ref); 588 589 return refCount; 590 } 591 592 ULONG 593 WINAPI 594 INetCfg_fnRelease( 595 INetCfg * iface) 596 { 597 INetCfgImpl * This = (INetCfgImpl*)iface; 598 ULONG refCount = InterlockedDecrement(&This->ref); 599 600 if (!refCount) 601 { 602 CoTaskMemFree (This); 603 } 604 return refCount; 605 } 606 607 HRESULT 608 WINAPI 609 INetCfg_fnInitialize( 610 INetCfg * iface, 611 PVOID pReserved) 612 { 613 HRESULT hr; 614 INetCfgImpl *This = (INetCfgImpl *)iface; 615 616 if (This->bInitialized) 617 return NETCFG_E_ALREADY_INITIALIZED; 618 619 hr = EnumerateNetworkAdapter(&This->pNet); 620 if (FAILED(hr)) 621 return hr; 622 623 624 hr = EnumerateNetworkComponent(&GUID_DEVCLASS_NETCLIENT, &This->pClient); 625 if (FAILED(hr)) 626 return hr; 627 628 hr = EnumerateNetworkComponent(&GUID_DEVCLASS_NETSERVICE, &This->pService); 629 if (FAILED(hr)) 630 return hr; 631 632 633 hr = EnumerateNetworkComponent(&GUID_DEVCLASS_NETTRANS, &This->pProtocol); 634 if (FAILED(hr)) 635 return hr; 636 637 This->bInitialized = TRUE; 638 return S_OK; 639 } 640 641 VOID 642 ApplyOrCancelChanges( 643 NetCfgComponentItem *pHead, 644 const CLSID * lpClassGUID, 645 BOOL bApply) 646 { 647 HKEY hKey; 648 WCHAR szName[200]; 649 LPOLESTR pszGuid; 650 651 while(pHead) 652 { 653 if (pHead->bChanged) 654 { 655 if (IsEqualGUID(lpClassGUID, &GUID_DEVCLASS_NET)) 656 { 657 if (bApply) 658 { 659 if (StringFromCLSID(&pHead->InstanceId, &pszGuid) == NOERROR) 660 { 661 swprintf(szName, L"SYSTEM\\CurrentControlSet\\Control\\Network\\%s", pszGuid); 662 CoTaskMemFree(pszGuid); 663 664 if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, szName, 0, KEY_READ, &hKey) == ERROR_SUCCESS) 665 { 666 RegSetValueExW(hKey, NULL, 0, REG_SZ, (LPBYTE)pHead->szDisplayName, (wcslen(pHead->szDisplayName)+1) * sizeof(WCHAR)); 667 RegCloseKey(hKey); 668 } 669 } 670 } 671 } 672 else if (pHead->pNCCC) 673 { 674 if (bApply) 675 { 676 INetCfgComponentControl_ApplyRegistryChanges(pHead->pNCCC); 677 //FIXME 678 // implement INetCfgPnpReconfigCallback and pass it to 679 //INetCfgComponentControl_ApplyPnpChanges(pHead->pNCCC, NULL); 680 } 681 else 682 { 683 INetCfgComponentControl_CancelChanges(pHead->pNCCC); 684 } 685 } 686 } 687 pHead = pHead->pNext; 688 } 689 } 690 691 VOID 692 FreeComponentItem(NetCfgComponentItem *pItem) 693 { 694 CoTaskMemFree(pItem->szDisplayName); 695 CoTaskMemFree(pItem->szHelpText); 696 CoTaskMemFree(pItem->szId); 697 CoTaskMemFree(pItem->szBindName); 698 CoTaskMemFree(pItem->szNodeId); 699 CoTaskMemFree(pItem->pszBinding); 700 CoTaskMemFree(pItem); 701 } 702 703 HRESULT 704 WINAPI 705 INetCfg_fnUninitialize( 706 INetCfg * iface) 707 { 708 INetCfgImpl *This = (INetCfgImpl *)iface; 709 NetCfgComponentItem *pItem; 710 711 if (!This->bInitialized) 712 return NETCFG_E_NOT_INITIALIZED; 713 714 /* Free the services */ 715 while (This->pService != NULL) 716 { 717 pItem = This->pService; 718 This->pService = pItem->pNext; 719 FreeComponentItem(pItem); 720 } 721 722 /* Free the clients */ 723 while (This->pClient != NULL) 724 { 725 pItem = This->pClient; 726 This->pClient = pItem->pNext; 727 FreeComponentItem(pItem); 728 } 729 730 /* Free the protocols */ 731 while (This->pProtocol != NULL) 732 { 733 pItem = This->pProtocol; 734 This->pProtocol = pItem->pNext; 735 FreeComponentItem(pItem); 736 } 737 738 /* Free the adapters */ 739 while (This->pNet != NULL) 740 { 741 pItem = This->pNet; 742 This->pNet = pItem->pNext; 743 FreeComponentItem(pItem); 744 } 745 746 This->bInitialized = FALSE; 747 748 return S_OK; 749 } 750 751 752 HRESULT 753 WINAPI 754 INetCfg_fnApply( 755 INetCfg * iface) 756 { 757 INetCfgImpl *This = (INetCfgImpl *)iface; 758 759 if (!This->bInitialized) 760 return NETCFG_E_NOT_INITIALIZED; 761 762 ApplyOrCancelChanges(This->pNet, &GUID_DEVCLASS_NET, TRUE); 763 ApplyOrCancelChanges(This->pClient, &GUID_DEVCLASS_NETCLIENT, TRUE); 764 ApplyOrCancelChanges(This->pService, &GUID_DEVCLASS_NETSERVICE, TRUE); 765 ApplyOrCancelChanges(This->pProtocol, &GUID_DEVCLASS_NETTRANS, TRUE); 766 767 return S_OK; 768 } 769 770 HRESULT 771 WINAPI 772 INetCfg_fnCancel( 773 INetCfg * iface) 774 { 775 INetCfgImpl *This = (INetCfgImpl *)iface; 776 777 if (!This->bInitialized) 778 return NETCFG_E_NOT_INITIALIZED; 779 780 ApplyOrCancelChanges(This->pClient, &GUID_DEVCLASS_NETCLIENT, FALSE); 781 ApplyOrCancelChanges(This->pService, &GUID_DEVCLASS_NETSERVICE, FALSE); 782 ApplyOrCancelChanges(This->pProtocol, &GUID_DEVCLASS_NETTRANS, FALSE); 783 784 return S_OK; 785 } 786 787 HRESULT 788 WINAPI 789 INetCfg_fnEnumComponents( 790 INetCfg * iface, 791 const GUID *pguidClass, 792 IEnumNetCfgComponent **ppenumComponent) 793 { 794 INetCfgImpl *This = (INetCfgImpl *)iface; 795 796 if (!This->bInitialized) 797 return NETCFG_E_NOT_INITIALIZED; 798 799 if (IsEqualGUID(&GUID_DEVCLASS_NET, pguidClass)) 800 return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pNet, iface); 801 else if (IsEqualGUID(&GUID_DEVCLASS_NETCLIENT, pguidClass)) 802 return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pClient, iface); 803 else if (IsEqualGUID(&GUID_DEVCLASS_NETSERVICE, pguidClass)) 804 return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pService, iface); 805 else if (IsEqualGUID(&GUID_DEVCLASS_NETTRANS, pguidClass)) 806 return IEnumNetCfgComponent_Constructor (NULL, &IID_IEnumNetCfgComponent, (LPVOID*)ppenumComponent, This->pProtocol, iface); 807 else 808 return E_NOINTERFACE; 809 } 810 811 812 HRESULT 813 WINAPI 814 INetCfg_fnFindComponent( 815 INetCfg * iface, 816 LPCWSTR pszwComponentId, 817 INetCfgComponent **pComponent) 818 { 819 HRESULT hr; 820 INetCfgImpl *This = (INetCfgImpl *)iface; 821 822 if (!This->bInitialized) 823 return NETCFG_E_NOT_INITIALIZED; 824 825 hr = FindNetworkComponent(This->pClient, pszwComponentId, pComponent, iface); 826 if (hr == S_OK) 827 return hr; 828 829 hr = FindNetworkComponent(This->pService, pszwComponentId, pComponent, iface); 830 if (hr == S_OK) 831 return hr; 832 833 hr = FindNetworkComponent(This->pProtocol, pszwComponentId, pComponent, iface); 834 if (hr == S_OK) 835 return hr; 836 837 return S_FALSE; 838 } 839 840 HRESULT 841 WINAPI 842 INetCfg_fnQueryNetCfgClass( 843 INetCfg * iface, 844 const GUID *pguidClass, 845 REFIID riid, 846 void **ppvObject) 847 { 848 return E_FAIL; 849 } 850 851 static const INetCfgVtbl vt_NetCfg = 852 { 853 INetCfg_fnQueryInterface, 854 INetCfg_fnAddRef, 855 INetCfg_fnRelease, 856 INetCfg_fnInitialize, 857 INetCfg_fnUninitialize, 858 INetCfg_fnApply, 859 INetCfg_fnCancel, 860 INetCfg_fnEnumComponents, 861 INetCfg_fnFindComponent, 862 INetCfg_fnQueryNetCfgClass, 863 }; 864 865 HRESULT WINAPI INetCfg_Constructor (IUnknown * pUnkOuter, REFIID riid, LPVOID * ppv) 866 { 867 INetCfgImpl *This; 868 869 if (!ppv) 870 return E_POINTER; 871 872 This = (INetCfgImpl *) CoTaskMemAlloc(sizeof (INetCfgImpl)); 873 if (!This) 874 return E_OUTOFMEMORY; 875 876 This->ref = 1; 877 This->lpVtbl = (const INetCfg*)&vt_NetCfg; 878 This->lpVtblLock = (const INetCfgLock*)&vt_NetCfgLock; 879 This->lpVtblPnpReconfigCallback = (const INetCfgPnpReconfigCallback*)&vt_NetCfgPnpReconfigCallback; 880 This->hMutex = NULL; 881 This->bInitialized = FALSE; 882 This->pNet = NULL; 883 This->pClient = NULL; 884 This->pService = NULL; 885 This->pProtocol = NULL; 886 887 if (!SUCCEEDED (INetCfg_QueryInterface ((INetCfg*)This, riid, ppv))) 888 { 889 INetCfg_Release((INetCfg*)This); 890 return E_NOINTERFACE; 891 } 892 893 INetCfg_Release((INetCfg*)This); 894 return S_OK; 895 } 896