1 /* 2 * COPYRIGHT: See COPYING in the top level directory 3 * PROJECT: ReactOS system libraries 4 * PURPOSE: System setup 5 * FILE: dll/win32/syssetup/netinstall.c 6 * PROGRAMER: Eric Kohl 7 */ 8 9 /* INCLUDES *****************************************************************/ 10 11 #include "precomp.h" 12 13 #include <rpc.h> 14 15 #define NDEBUG 16 #include <debug.h> 17 18 typedef struct _COMPONENT_INFO 19 { 20 PWSTR pszInfPath; 21 PWSTR pszInfSection; 22 PWSTR pszComponentId; 23 PWSTR pszDescription; 24 PWSTR pszClassGuid; 25 DWORD dwCharacteristics; 26 } COMPONENT_INFO, *PCOMPONENT_INFO; 27 28 29 /* GLOBALS ******************************************************************/ 30 31 32 /* FUNCTIONS ****************************************************************/ 33 34 static 35 BOOL 36 InstallInfSections( 37 _In_ HWND hWnd, 38 _In_ HKEY hKey, 39 _In_ LPCWSTR InfFile, 40 _In_ LPCWSTR InfSection) 41 { 42 WCHAR Buffer[MAX_PATH]; 43 HINF hInf = INVALID_HANDLE_VALUE; 44 UINT BufferSize; 45 PVOID Context = NULL; 46 BOOL ret = FALSE; 47 48 DPRINT("InstallInfSections()\n"); 49 50 if (InfSection == NULL) 51 return FALSE; 52 53 /* Get Windows directory */ 54 BufferSize = ARRAYSIZE(Buffer) - 5 - wcslen(InfFile); 55 if (GetWindowsDirectoryW(Buffer, BufferSize) > BufferSize) 56 { 57 /* Function failed */ 58 SetLastError(ERROR_GEN_FAILURE); 59 goto cleanup; 60 } 61 62 /* We have enough space to add some information in the buffer */ 63 if (Buffer[wcslen(Buffer) - 1] != '\\') 64 wcscat(Buffer, L"\\"); 65 wcscat(Buffer, L"Inf\\"); 66 wcscat(Buffer, InfFile); 67 68 /* Install specified section */ 69 hInf = SetupOpenInfFileW(Buffer, NULL, INF_STYLE_WIN4, NULL); 70 if (hInf == INVALID_HANDLE_VALUE) 71 goto cleanup; 72 73 Context = SetupInitDefaultQueueCallback(hWnd); 74 if (Context == NULL) 75 goto cleanup; 76 77 ret = SetupInstallFromInfSectionW( 78 hWnd, hInf, 79 InfSection, SPINST_ALL, 80 hKey, NULL, SP_COPY_NEWER, 81 SetupDefaultQueueCallbackW, Context, 82 NULL, NULL); 83 if (ret == FALSE) 84 { 85 DPRINT1("SetupInstallFromInfSectionW(%S) failed (Error %lx)\n", InfSection, GetLastError()); 86 goto cleanup; 87 } 88 89 wcscpy(Buffer, InfSection); 90 wcscat(Buffer, L".Services"); 91 92 ret = SetupInstallServicesFromInfSectionW(hInf, Buffer, 0); 93 if (ret == FALSE) 94 { 95 DPRINT1("SetupInstallServicesFromInfSectionW(%S) failed (Error %lx)\n", Buffer, GetLastError()); 96 goto cleanup; 97 } 98 99 cleanup: 100 if (Context) 101 SetupTermDefaultQueueCallback(Context); 102 103 if (hInf != INVALID_HANDLE_VALUE) 104 SetupCloseInfFile(hInf); 105 106 DPRINT("InstallInfSections() done %u\n", ret); 107 108 return ret; 109 } 110 111 112 static 113 BOOL 114 CreateInstanceKey( 115 _In_ PCOMPONENT_INFO pComponentInfo, 116 _Out_ PHKEY pInstanceKey) 117 { 118 WCHAR szKeyBuffer[128]; 119 LPWSTR UuidString = NULL; 120 UUID Uuid; 121 RPC_STATUS RpcStatus; 122 HKEY hInstanceKey; 123 DWORD rc; 124 BOOL ret = FALSE; 125 126 DPRINT("CreateInstanceKey()\n"); 127 128 *pInstanceKey = NULL; 129 130 wcscpy(szKeyBuffer, L"SYSTEM\\CurrentControlSet\\Control\\Network\\"); 131 wcscat(szKeyBuffer, pComponentInfo->pszClassGuid); 132 wcscat(szKeyBuffer, L"\\{"); 133 134 /* Create a new UUID */ 135 RpcStatus = UuidCreate(&Uuid); 136 if (RpcStatus != RPC_S_OK && RpcStatus != RPC_S_UUID_LOCAL_ONLY) 137 { 138 DPRINT1("UuidCreate() failed with RPC status 0x%lx\n", RpcStatus); 139 goto done; 140 } 141 142 RpcStatus = UuidToStringW(&Uuid, &UuidString); 143 if (RpcStatus != RPC_S_OK) 144 { 145 DPRINT1("UuidToStringW() failed with RPC status 0x%lx\n", RpcStatus); 146 goto done; 147 } 148 149 wcscat(szKeyBuffer, UuidString); 150 wcscat(szKeyBuffer, L"}"); 151 152 RpcStringFreeW(&UuidString); 153 154 DPRINT("szKeyBuffer %S\n", szKeyBuffer); 155 156 rc = RegCreateKeyExW(HKEY_LOCAL_MACHINE, 157 szKeyBuffer, 158 0, 159 NULL, 160 REG_OPTION_NON_VOLATILE, 161 KEY_CREATE_SUB_KEY | KEY_SET_VALUE, 162 NULL, 163 &hInstanceKey, 164 NULL); 165 if (rc != ERROR_SUCCESS) 166 { 167 DPRINT1("RegCreateKeyExW() failed with error 0x%lx\n", rc); 168 goto done; 169 } 170 171 rc = RegSetValueExW(hInstanceKey, 172 L"Characteristics", 173 0, 174 REG_DWORD, 175 (LPBYTE)&pComponentInfo->dwCharacteristics, 176 sizeof(DWORD)); 177 if (rc != ERROR_SUCCESS) 178 { 179 DPRINT1("RegSetValueExW() failed with error 0x%lx\n", rc); 180 goto done; 181 } 182 183 rc = RegSetValueExW(hInstanceKey, 184 L"ComponentId", 185 0, 186 REG_SZ, 187 (LPBYTE)pComponentInfo->pszComponentId, 188 (wcslen(pComponentInfo->pszComponentId) + 1) * sizeof(WCHAR)); 189 if (rc != ERROR_SUCCESS) 190 { 191 DPRINT1("RegSetValueExW() failed with error 0x%lx\n", rc); 192 goto done; 193 } 194 195 rc = RegSetValueExW(hInstanceKey, 196 L"Description", 197 0, 198 REG_SZ, 199 (LPBYTE)pComponentInfo->pszDescription, 200 (wcslen(pComponentInfo->pszDescription) + 1) * sizeof(WCHAR)); 201 if (rc != ERROR_SUCCESS) 202 { 203 DPRINT1("RegSetValueExW() failed with error 0x%lx\n", rc); 204 goto done; 205 } 206 207 rc = RegSetValueExW(hInstanceKey, 208 L"InfPath", 209 0, 210 REG_SZ, 211 (LPBYTE)pComponentInfo->pszInfPath, 212 (wcslen(pComponentInfo->pszInfPath) + 1) * sizeof(WCHAR)); 213 if (rc != ERROR_SUCCESS) 214 { 215 DPRINT1("RegSetValueExW() failed with error 0x%lx\n", rc); 216 goto done; 217 } 218 219 rc = RegSetValueExW(hInstanceKey, 220 L"InfSection", 221 0, 222 REG_SZ, 223 (LPBYTE)pComponentInfo->pszInfSection, 224 (wcslen(pComponentInfo->pszInfSection) + 1) * sizeof(WCHAR)); 225 if (rc != ERROR_SUCCESS) 226 { 227 DPRINT1("RegSetValueExW() failed with error 0x%lx\n", rc); 228 goto done; 229 } 230 231 *pInstanceKey = hInstanceKey; 232 ret = TRUE; 233 234 done: 235 if (ret == FALSE) 236 RegCloseKey(hInstanceKey); 237 238 DPRINT("CreateInstanceKey() done %u\n", ret); 239 240 return ret; 241 } 242 243 244 static 245 BOOL 246 CheckInfFile( 247 _In_ PWSTR pszFullInfName, 248 _In_ PWSTR pszComponentId, 249 _In_ PCOMPONENT_INFO pComponentInfo) 250 { 251 WCHAR szLineBuffer[MAX_PATH]; 252 HINF hInf = INVALID_HANDLE_VALUE; 253 INFCONTEXT MfgContext, DevContext, MiscContext; 254 DWORD dwLength; 255 256 hInf = SetupOpenInfFileW(pszFullInfName, 257 NULL, 258 INF_STYLE_WIN4, 259 NULL); 260 if (hInf == INVALID_HANDLE_VALUE) 261 { 262 DPRINT1("\n"); 263 return FALSE; 264 } 265 266 if (!SetupFindFirstLineW(hInf, 267 L"Manufacturer", 268 NULL, 269 &MfgContext)) 270 { 271 DPRINT("No Manufacurer section found!\n"); 272 goto done; 273 } 274 275 for (;;) 276 { 277 if (!SetupGetStringFieldW(&MfgContext, 278 1, 279 szLineBuffer, 280 MAX_PATH, 281 NULL)) 282 break; 283 284 DPRINT("Manufacturer: %S\n", szLineBuffer); 285 if (!SetupFindFirstLineW(hInf, 286 szLineBuffer, 287 NULL, 288 &DevContext)) 289 break; 290 291 for (;;) 292 { 293 if (!SetupGetStringFieldW(&DevContext, 294 2, 295 szLineBuffer, 296 MAX_PATH, 297 NULL)) 298 break; 299 300 DPRINT("Device: %S\n", szLineBuffer); 301 if (_wcsicmp(szLineBuffer, pszComponentId) == 0) 302 { 303 DPRINT("Found it!\n"); 304 305 /* Get the section name*/ 306 SetupGetStringFieldW(&DevContext, 307 1, 308 NULL, 309 0, 310 &dwLength); 311 312 pComponentInfo->pszInfSection = HeapAlloc(GetProcessHeap(), 313 0, 314 dwLength * sizeof(WCHAR)); 315 if (pComponentInfo->pszInfSection) 316 { 317 SetupGetStringFieldW(&DevContext, 318 1, 319 pComponentInfo->pszInfSection, 320 dwLength, 321 &dwLength); 322 } 323 324 /* Get the description*/ 325 SetupGetStringFieldW(&DevContext, 326 0, 327 NULL, 328 0, 329 &dwLength); 330 331 pComponentInfo->pszDescription = HeapAlloc(GetProcessHeap(), 332 0, 333 dwLength * sizeof(WCHAR)); 334 if (pComponentInfo->pszDescription) 335 { 336 SetupGetStringFieldW(&DevContext, 337 0, 338 pComponentInfo->pszDescription, 339 dwLength, 340 &dwLength); 341 } 342 343 /* Get the class GUID */ 344 if (SetupFindFirstLineW(hInf, 345 L"Version", 346 L"ClassGuid", 347 &MiscContext)) 348 { 349 SetupGetStringFieldW(&MiscContext, 350 1, 351 NULL, 352 0, 353 &dwLength); 354 355 pComponentInfo->pszClassGuid = HeapAlloc(GetProcessHeap(), 356 0, 357 dwLength * sizeof(WCHAR)); 358 if (pComponentInfo->pszInfSection) 359 { 360 SetupGetStringFieldW(&MiscContext, 361 1, 362 pComponentInfo->pszClassGuid, 363 dwLength, 364 &dwLength); 365 } 366 } 367 368 /* Get the Characteristics value */ 369 if (SetupFindFirstLineW(hInf, 370 pComponentInfo->pszInfSection, 371 L"Characteristics", 372 &MiscContext)) 373 { 374 SetupGetIntField(&MiscContext, 375 1, 376 (PINT)&pComponentInfo->dwCharacteristics); 377 } 378 379 SetupCloseInfFile(hInf); 380 return TRUE; 381 } 382 383 if (!SetupFindNextLine(&DevContext, &DevContext)) 384 break; 385 } 386 387 if (!SetupFindNextLine(&MfgContext, &MfgContext)) 388 break; 389 } 390 391 done: 392 if (hInf != INVALID_HANDLE_VALUE) 393 SetupCloseInfFile(hInf); 394 395 return FALSE; 396 } 397 398 399 static 400 BOOL 401 ScanForInfFile( 402 _In_ PWSTR pszComponentId, 403 _In_ PCOMPONENT_INFO pComponentInfo) 404 { 405 WCHAR szInfPath[MAX_PATH]; 406 WCHAR szFullInfName[MAX_PATH]; 407 WCHAR szPathBuffer[MAX_PATH]; 408 WIN32_FIND_DATAW fdw; 409 HANDLE hFindFile = INVALID_HANDLE_VALUE; 410 BOOL bFound = FALSE; 411 412 GetWindowsDirectoryW(szInfPath, MAX_PATH); 413 wcscat(szInfPath, L"\\inf"); 414 415 wcscpy(szPathBuffer, szInfPath); 416 wcscat(szPathBuffer, L"\\*.inf"); 417 418 hFindFile = FindFirstFileW(szPathBuffer, &fdw); 419 if (hFindFile == INVALID_HANDLE_VALUE) 420 return FALSE; 421 422 for (;;) 423 { 424 if (wcscmp(fdw.cFileName, L".") == 0 || 425 wcscmp(fdw.cFileName, L"..") == 0) 426 continue; 427 428 DPRINT("FileName: %S\n", fdw.cFileName); 429 430 wcscpy(szFullInfName, szInfPath); 431 wcscat(szFullInfName, L"\\"); 432 wcscat(szFullInfName, fdw.cFileName); 433 434 DPRINT("Full Inf Name: %S\n", szFullInfName); 435 if (CheckInfFile(szFullInfName, 436 pszComponentId, 437 pComponentInfo)) 438 { 439 pComponentInfo->pszInfPath = HeapAlloc(GetProcessHeap(), 440 0, 441 (wcslen(fdw.cFileName) + 1) * sizeof(WCHAR)); 442 if (pComponentInfo->pszInfPath) 443 wcscpy(pComponentInfo->pszInfPath, fdw.cFileName); 444 445 pComponentInfo->pszComponentId = HeapAlloc(GetProcessHeap(), 446 0, 447 (wcslen(pszComponentId) + 1) * sizeof(WCHAR)); 448 if (pComponentInfo->pszComponentId) 449 wcscpy(pComponentInfo->pszComponentId, pszComponentId); 450 451 bFound = TRUE; 452 break; 453 } 454 455 if (!FindNextFileW(hFindFile, &fdw)) 456 break; 457 } 458 459 if (hFindFile != INVALID_HANDLE_VALUE) 460 FindClose(hFindFile); 461 462 return bFound; 463 } 464 465 466 BOOL 467 InstallNetworkComponent( 468 _In_ PWSTR pszComponentId) 469 { 470 COMPONENT_INFO ComponentInfo; 471 HKEY hInstanceKey = NULL; 472 BOOL bResult = FALSE; 473 474 DPRINT("InstallNetworkComponent(%S)\n", pszComponentId); 475 476 ZeroMemory(&ComponentInfo, sizeof(COMPONENT_INFO)); 477 478 if (!ScanForInfFile(pszComponentId, &ComponentInfo)) 479 goto done; 480 481 DPRINT("Characteristics: 0x%lx\n", ComponentInfo.dwCharacteristics); 482 DPRINT("ComponentId: %S\n", ComponentInfo.pszComponentId); 483 DPRINT("Description: %S\n", ComponentInfo.pszDescription); 484 DPRINT("InfPath: %S\n", ComponentInfo.pszInfPath); 485 DPRINT("InfSection: %S\n", ComponentInfo.pszInfSection); 486 DPRINT("ClassGuid: %S\n", ComponentInfo.pszClassGuid); 487 488 if (!CreateInstanceKey(&ComponentInfo, 489 &hInstanceKey)) 490 { 491 DPRINT1("CreateInstanceKey() failed (Error %lx)\n", GetLastError()); 492 goto done; 493 } 494 495 if (!InstallInfSections(NULL, 496 hInstanceKey, 497 ComponentInfo.pszInfPath, 498 ComponentInfo.pszInfSection)) 499 { 500 DPRINT1("InstallInfSections() failed (Error %lx)\n", GetLastError()); 501 goto done; 502 } 503 504 bResult = TRUE; 505 506 done: 507 if (hInstanceKey != NULL) 508 RegCloseKey(hInstanceKey); 509 510 if (ComponentInfo.pszInfPath) 511 HeapFree(GetProcessHeap(), 0, ComponentInfo.pszInfPath); 512 513 if (ComponentInfo.pszInfSection) 514 HeapFree(GetProcessHeap(), 0, ComponentInfo.pszInfSection); 515 516 if (ComponentInfo.pszComponentId) 517 HeapFree(GetProcessHeap(), 0, ComponentInfo.pszComponentId); 518 519 if (ComponentInfo.pszDescription) 520 HeapFree(GetProcessHeap(), 0, ComponentInfo.pszDescription); 521 522 if (ComponentInfo.pszClassGuid) 523 HeapFree(GetProcessHeap(), 0, ComponentInfo.pszClassGuid); 524 525 return bResult; 526 } 527 528 /* EOF */ 529