1 /* 2 * PROJECT: ReactOS System Control Panel Applet 3 * LICENSE: GPL - See COPYING in the top level directory 4 * FILE: dll/cpl/sysdm/startrec.c 5 * PURPOSE: Computer settings for startup and recovery 6 * COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com> 7 * Copyright 2006 Christoph von Wittich <Christoph@ApiViewer.de> 8 * Copyright 2007 Johannes Anderwald <johannes.anderwald@reactos.org> 9 */ 10 11 #include "precomp.h" 12 13 #include <shlwapi.h> 14 15 typedef struct _BOOTRECORD 16 { 17 DWORD BootType; 18 WCHAR szSectionName[128]; 19 WCHAR szBootPath[MAX_PATH]; 20 WCHAR szOptions[512]; 21 } BOOTRECORD, *PBOOTRECORD; 22 23 typedef struct _STARTINFO 24 { 25 WCHAR szFreeldrIni[MAX_PATH + 15]; 26 WCHAR szDumpFile[MAX_PATH]; 27 WCHAR szMinidumpDir[MAX_PATH]; 28 DWORD dwCrashDumpEnabled; 29 INT iFreeLdrIni; 30 } STARTINFO, *PSTARTINFO; 31 32 BOOL SaveRecoveryOptions; 33 34 static VOID 35 SetTimeout(HWND hwndDlg, INT Timeout) 36 { 37 if (Timeout == 0) 38 { 39 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECLISTUPDWN), FALSE); 40 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECLISTEDIT), FALSE); 41 } 42 else 43 { 44 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECLISTUPDWN), TRUE); 45 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECLISTEDIT), TRUE); 46 } 47 SendDlgItemMessageW(hwndDlg, IDC_STRRECLISTUPDWN, UDM_SETRANGE, (WPARAM) 0, (LPARAM) MAKELONG((short) 999, 0)); 48 SendDlgItemMessageW(hwndDlg, IDC_STRRECLISTUPDWN, UDM_SETPOS, (WPARAM) 0, (LPARAM) MAKELONG((short) Timeout, 0)); 49 } 50 51 static VOID 52 SetRecoveryTimeout(HWND hwndDlg, INT Timeout) 53 { 54 if (Timeout == 0) 55 { 56 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECRECUPDWN), FALSE); 57 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECRECEDIT), FALSE); 58 } 59 else 60 { 61 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECRECUPDWN), TRUE); 62 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECRECEDIT), TRUE); 63 } 64 SendDlgItemMessageW(hwndDlg, IDC_STRRECRECUPDWN, UDM_SETRANGE, (WPARAM) 0, (LPARAM) MAKELONG((short) 999, 0)); 65 SendDlgItemMessageW(hwndDlg, IDC_STRRECRECUPDWN, UDM_SETPOS, (WPARAM) 0, (LPARAM) MAKELONG((short) Timeout, 0)); 66 } 67 68 69 static DWORD 70 GetSystemDrive(WCHAR **szSystemDrive) 71 { 72 DWORD dwBufSize; 73 74 /* Get Path to freeldr.ini or boot.ini */ 75 *szSystemDrive = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(WCHAR)); 76 if (*szSystemDrive != NULL) 77 { 78 dwBufSize = GetEnvironmentVariableW(L"SystemDrive", *szSystemDrive, MAX_PATH); 79 if (dwBufSize > MAX_PATH) 80 { 81 WCHAR *szTmp; 82 DWORD dwBufSize2; 83 84 szTmp = HeapReAlloc(GetProcessHeap(), 0, *szSystemDrive, dwBufSize * sizeof(WCHAR)); 85 if (szTmp == NULL) 86 goto FailGetSysDrive; 87 88 *szSystemDrive = szTmp; 89 90 dwBufSize2 = GetEnvironmentVariableW(L"SystemDrive", *szSystemDrive, dwBufSize); 91 if (dwBufSize2 > dwBufSize || dwBufSize2 == 0) 92 goto FailGetSysDrive; 93 } 94 else if (dwBufSize == 0) 95 { 96 FailGetSysDrive: 97 HeapFree(GetProcessHeap(), 0, *szSystemDrive); 98 *szSystemDrive = NULL; 99 return 0; 100 } 101 102 return dwBufSize; 103 } 104 105 return 0; 106 } 107 108 static PBOOTRECORD 109 ReadFreeldrSection(HINF hInf, WCHAR *szSectionName) 110 { 111 PBOOTRECORD pRecord; 112 INFCONTEXT InfContext; 113 WCHAR szName[MAX_PATH]; 114 WCHAR szValue[MAX_PATH]; 115 DWORD LineLength; 116 117 if (!SetupFindFirstLineW(hInf, 118 szSectionName, 119 NULL, 120 &InfContext)) 121 { 122 /* Failed to find section */ 123 return NULL; 124 } 125 126 pRecord = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD)); 127 if (pRecord == NULL) 128 { 129 return NULL; 130 } 131 132 wcscpy(pRecord->szSectionName, szSectionName); 133 134 do 135 { 136 if (!SetupGetStringFieldW(&InfContext, 137 0, 138 szName, 139 sizeof(szName) / sizeof(WCHAR), 140 &LineLength)) 141 { 142 break; 143 } 144 145 if (!SetupGetStringFieldW(&InfContext, 146 1, 147 szValue, 148 sizeof(szValue) / sizeof(WCHAR), 149 &LineLength)) 150 { 151 break; 152 } 153 154 if (!_wcsnicmp(szName, L"BootType", 8)) 155 { 156 if (!_wcsnicmp(szValue, L"ReactOS", 7)) 157 { 158 // FIXME: Store as enum 159 pRecord->BootType = 1; 160 } 161 else 162 { 163 pRecord->BootType = 0; 164 } 165 } 166 else if (!_wcsnicmp(szName, L"SystemPath", 10)) 167 { 168 wcscpy(pRecord->szBootPath, szValue); 169 } 170 else if (!_wcsnicmp(szName, L"Options", 7)) 171 { 172 // FIXME: Store flags as values 173 wcscpy(pRecord->szOptions, szValue); 174 } 175 176 } 177 while (SetupFindNextLine(&InfContext, &InfContext)); 178 179 return pRecord; 180 } 181 182 183 static INT 184 LoadFreeldrSettings(HINF hInf, HWND hwndDlg) 185 { 186 INFCONTEXT InfContext; 187 PBOOTRECORD pRecord; 188 WCHAR szDefaultOs[MAX_PATH]; 189 WCHAR szName[MAX_PATH]; 190 WCHAR szValue[MAX_PATH]; 191 DWORD LineLength; 192 DWORD TimeOut; 193 LRESULT lResult; 194 195 if (!SetupFindFirstLineW(hInf, 196 L"FREELOADER", 197 L"DefaultOS", 198 &InfContext)) 199 { 200 /* Failed to find default os */ 201 return FALSE; 202 } 203 204 if (!SetupGetStringFieldW(&InfContext, 205 1, 206 szDefaultOs, 207 sizeof(szDefaultOs) / sizeof(WCHAR), 208 &LineLength)) 209 { 210 /* No key */ 211 return FALSE; 212 } 213 214 if (!SetupFindFirstLineW(hInf, 215 L"FREELOADER", 216 L"TimeOut", 217 &InfContext)) 218 { 219 /* Expected to find timeout value */ 220 return FALSE; 221 } 222 223 224 if (!SetupGetIntField(&InfContext, 225 1, 226 (PINT)&TimeOut)) 227 { 228 /* Failed to retrieve timeout */ 229 return FALSE; 230 } 231 232 if (!SetupFindFirstLineW(hInf, 233 L"Operating Systems", 234 NULL, 235 &InfContext)) 236 { 237 /* Expected list of operating systems */ 238 return FALSE; 239 } 240 241 do 242 { 243 if (!SetupGetStringFieldW(&InfContext, 244 0, 245 szName, 246 sizeof(szName) / sizeof(WCHAR), 247 &LineLength)) 248 { 249 /* The ini file is messed up */ 250 return FALSE; 251 } 252 253 if (!SetupGetStringFieldW(&InfContext, 254 1, 255 szValue, 256 sizeof(szValue) / sizeof(WCHAR), 257 &LineLength)) 258 { 259 /* The ini file is messed up */ 260 return FALSE; 261 } 262 263 pRecord = ReadFreeldrSection(hInf, szName); 264 if (pRecord) 265 { 266 lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue); 267 if (lResult != CB_ERR) 268 { 269 SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pRecord); 270 if (!wcscmp(szDefaultOs, szName)) 271 { 272 /* We store the friendly name as key */ 273 wcscpy(szDefaultOs, szValue); 274 } 275 } 276 else 277 { 278 HeapFree(GetProcessHeap(), 0, pRecord); 279 } 280 } 281 } 282 while (SetupFindNextLine(&InfContext, &InfContext)); 283 284 /* Find default os in list */ 285 lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)-1, (LPARAM)szDefaultOs); 286 if (lResult != CB_ERR) 287 { 288 /* Set cur sel */ 289 SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0); 290 } 291 292 if(TimeOut) 293 { 294 SendDlgItemMessageW(hwndDlg, IDC_STRECLIST, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 295 } 296 297 SetTimeout(hwndDlg, TimeOut); 298 299 return TRUE; 300 } 301 302 static INT 303 LoadBootSettings(HINF hInf, HWND hwndDlg) 304 { 305 INFCONTEXT InfContext; 306 WCHAR szName[MAX_PATH]; 307 WCHAR szValue[MAX_PATH]; 308 DWORD LineLength; 309 DWORD TimeOut = 0; 310 WCHAR szDefaultOS[MAX_PATH]; 311 WCHAR szOptions[MAX_PATH]; 312 PBOOTRECORD pRecord; 313 LRESULT lResult; 314 315 if(!SetupFindFirstLineW(hInf, 316 L"boot loader", 317 NULL, 318 &InfContext)) 319 { 320 return FALSE; 321 } 322 323 do 324 { 325 if (!SetupGetStringFieldW(&InfContext, 326 0, 327 szName, 328 sizeof(szName) / sizeof(WCHAR), 329 &LineLength)) 330 { 331 return FALSE; 332 } 333 334 if (!SetupGetStringFieldW(&InfContext, 335 1, 336 szValue, 337 sizeof(szValue) / sizeof(WCHAR), 338 &LineLength)) 339 { 340 return FALSE; 341 } 342 343 if (!_wcsnicmp(szName, L"timeout", 7)) 344 { 345 TimeOut = _wtoi(szValue); 346 } 347 348 if (!_wcsnicmp(szName, L"default", 7)) 349 { 350 wcscpy(szDefaultOS, szValue); 351 } 352 353 } 354 while (SetupFindNextLine(&InfContext, &InfContext)); 355 356 if (!SetupFindFirstLineW(hInf, 357 L"operating systems", 358 NULL, 359 &InfContext)) 360 { 361 /* Failed to find operating systems section */ 362 return FALSE; 363 } 364 365 do 366 { 367 if (!SetupGetStringFieldW(&InfContext, 368 0, 369 szName, 370 sizeof(szName) / sizeof(WCHAR), 371 &LineLength)) 372 { 373 return FALSE; 374 } 375 376 if (!SetupGetStringFieldW(&InfContext, 377 1, 378 szValue, 379 sizeof(szValue) / sizeof(WCHAR), 380 &LineLength)) 381 { 382 return FALSE; 383 } 384 385 SetupGetStringFieldW(&InfContext, 386 2, 387 szOptions, 388 sizeof(szOptions) / sizeof(WCHAR), 389 &LineLength); 390 391 pRecord = (PBOOTRECORD) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD)); 392 if (pRecord) 393 { 394 pRecord->BootType = 0; 395 wcscpy(pRecord->szBootPath, szName); 396 wcscpy(pRecord->szSectionName, szValue); 397 wcscpy(pRecord->szOptions, szOptions); 398 399 if (!wcscmp(szName, szDefaultOS)) 400 { 401 /* ms boot ini stores the path not the friendly name */ 402 wcscpy(szDefaultOS, szValue); 403 } 404 405 lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM)szValue); 406 if (lResult != CB_ERR) 407 { 408 SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA, (WPARAM)lResult, (LPARAM)pRecord); 409 } 410 else 411 { 412 HeapFree(GetProcessHeap(), 0, pRecord); 413 } 414 } 415 416 } 417 while (SetupFindNextLine(&InfContext, &InfContext)); 418 419 /* Find default os in list */ 420 lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)0, (LPARAM)szDefaultOS); 421 if (lResult != CB_ERR) 422 { 423 /* Set cur sel */ 424 SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult, (LPARAM)0); 425 } 426 427 if(TimeOut) 428 { 429 SendDlgItemMessageW(hwndDlg, IDC_STRECLIST, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 430 } 431 432 SetTimeout(hwndDlg, TimeOut); 433 434 return TRUE; 435 } 436 437 static VOID 438 DeleteBootRecords(HWND hwndDlg) 439 { 440 LRESULT lIndex; 441 LONG index; 442 PBOOTRECORD pRecord; 443 444 lIndex = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_GETCOUNT, (WPARAM)0, (LPARAM)0); 445 if (lIndex == CB_ERR) 446 return; 447 448 for (index = 0; index <lIndex; index++) 449 { 450 pRecord = (PBOOTRECORD) SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_GETITEMDATA, (WPARAM)index, (LPARAM)0); 451 if ((INT_PTR)pRecord != CB_ERR) 452 { 453 HeapFree(GetProcessHeap(), 0, pRecord); 454 } 455 } 456 457 SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_RESETCONTENT, (WPARAM)0, (LPARAM)0); 458 } 459 460 static LRESULT 461 LoadOSList(HWND hwndDlg, PSTARTINFO pStartInfo) 462 { 463 DWORD dwBufSize; 464 WCHAR *szSystemDrive; 465 HINF hInf; 466 467 dwBufSize = GetSystemDrive(&szSystemDrive); 468 if (dwBufSize == 0) 469 return FALSE; 470 471 wcscpy(pStartInfo->szFreeldrIni, szSystemDrive); 472 wcscat(pStartInfo->szFreeldrIni, L"\\freeldr.ini"); 473 474 if (PathFileExistsW(pStartInfo->szFreeldrIni)) 475 { 476 /* Free resource previously allocated by GetSystemDrive() */ 477 HeapFree(GetProcessHeap(), 0, szSystemDrive); 478 /* freeldr.ini exists */ 479 hInf = SetupOpenInfFileW(pStartInfo->szFreeldrIni, 480 NULL, 481 INF_STYLE_OLDNT, 482 NULL); 483 484 if (hInf != INVALID_HANDLE_VALUE) 485 { 486 LoadFreeldrSettings(hInf, hwndDlg); 487 SetupCloseInfFile(hInf); 488 pStartInfo->iFreeLdrIni = 1; 489 return TRUE; 490 } 491 return FALSE; 492 } 493 494 /* Try loading boot.ini settings */ 495 wcscpy(pStartInfo->szFreeldrIni, szSystemDrive); 496 wcscat(pStartInfo->szFreeldrIni, L"\\boot.ini"); 497 498 /* Free resource previously allocated by GetSystemDrive() */ 499 HeapFree(GetProcessHeap(), 0, szSystemDrive); 500 501 if (PathFileExistsW(pStartInfo->szFreeldrIni)) 502 { 503 /* Load boot.ini settings */ 504 hInf = SetupOpenInfFileW(pStartInfo->szFreeldrIni, 505 NULL, 506 INF_STYLE_OLDNT, 507 NULL); 508 509 if (hInf != INVALID_HANDLE_VALUE) 510 { 511 LoadBootSettings(hInf, hwndDlg); 512 SetupCloseInfFile(hInf); 513 pStartInfo->iFreeLdrIni = 2; 514 return TRUE; 515 } 516 517 return FALSE; 518 } 519 520 return FALSE; 521 } 522 523 static VOID 524 SetCrashDlgItems(HWND hwnd, PSTARTINFO pStartInfo) 525 { 526 if (pStartInfo->dwCrashDumpEnabled == 0) 527 { 528 /* No crash information required */ 529 EnableWindow(GetDlgItem(hwnd, IDC_STRRECDUMPFILE), FALSE); 530 EnableWindow(GetDlgItem(hwnd, IDC_STRRECOVERWRITE), FALSE); 531 } 532 else if (pStartInfo->dwCrashDumpEnabled == 3) 533 { 534 /* Minidump type */ 535 EnableWindow(GetDlgItem(hwnd, IDC_STRRECDUMPFILE), TRUE); 536 EnableWindow(GetDlgItem(hwnd, IDC_STRRECOVERWRITE), FALSE); 537 SendMessageW(GetDlgItem(hwnd, IDC_STRRECDUMPFILE), WM_SETTEXT, (WPARAM)0, (LPARAM)pStartInfo->szMinidumpDir); 538 } 539 else if (pStartInfo->dwCrashDumpEnabled == 1 || pStartInfo->dwCrashDumpEnabled == 2) 540 { 541 /* Kernel or complete dump */ 542 EnableWindow(GetDlgItem(hwnd, IDC_STRRECDUMPFILE), TRUE); 543 EnableWindow(GetDlgItem(hwnd, IDC_STRRECOVERWRITE), TRUE); 544 SendMessageW(GetDlgItem(hwnd, IDC_STRRECDUMPFILE), WM_SETTEXT, (WPARAM)0, (LPARAM)pStartInfo->szDumpFile); 545 } 546 SendDlgItemMessageW(hwnd, IDC_STRRECDEBUGCOMBO, CB_SETCURSEL, (WPARAM)pStartInfo->dwCrashDumpEnabled, (LPARAM)0); 547 } 548 549 static VOID 550 WriteStartupRecoveryOptions(HWND hwndDlg, PSTARTINFO pStartInfo) 551 { 552 HKEY hKey; 553 DWORD lResult; 554 555 lResult = (DWORD)RegCreateKeyExW(HKEY_LOCAL_MACHINE, 556 L"System\\CurrentControlSet\\Control\\CrashControl", 557 0, 558 NULL, 559 REG_OPTION_NON_VOLATILE, 560 KEY_WRITE, 561 NULL, 562 &hKey, 563 NULL); 564 if (lResult != ERROR_SUCCESS) 565 { 566 /* Failed to open key */ 567 SetLastError(lResult); 568 ShowLastWin32Error(hwndDlg); 569 570 return; 571 } 572 573 lResult = (DWORD) SendDlgItemMessage(hwndDlg, IDC_STRRECWRITEEVENT, BM_GETCHECK, (WPARAM)0, (LPARAM)0); 574 RegSetValueExW(hKey, L"LogEvent", 0, REG_DWORD, (LPBYTE)&lResult, sizeof(lResult)); 575 576 lResult = (DWORD) SendDlgItemMessage(hwndDlg, IDC_STRRECSENDALERT, BM_GETCHECK, (WPARAM)0, (LPARAM)0); 577 RegSetValueExW(hKey, L"SendAlert", 0, REG_DWORD, (LPBYTE)&lResult, sizeof(lResult)); 578 579 lResult = (DWORD) SendDlgItemMessage(hwndDlg, IDC_STRRECRESTART, BM_GETCHECK, (WPARAM)0, (LPARAM)0); 580 RegSetValueExW(hKey, L"AutoReboot", 0, REG_DWORD, (LPBYTE)&lResult, sizeof(lResult)); 581 582 lResult = (DWORD) SendDlgItemMessage(hwndDlg, IDC_STRRECOVERWRITE, BM_GETCHECK, (WPARAM)0, (LPARAM)0); 583 RegSetValueExW(hKey, L"Overwrite", 0, REG_DWORD, (LPBYTE)&lResult, sizeof(lResult)); 584 585 586 if (pStartInfo->dwCrashDumpEnabled == 1 || pStartInfo->dwCrashDumpEnabled == 2) 587 { 588 SendDlgItemMessage(hwndDlg, IDC_STRRECDUMPFILE, WM_GETTEXT, (WPARAM)sizeof(pStartInfo->szDumpFile) / sizeof(WCHAR), (LPARAM)pStartInfo->szDumpFile); 589 RegSetValueExW(hKey, L"DumpFile", 0, REG_EXPAND_SZ, (LPBYTE)pStartInfo->szDumpFile, (wcslen(pStartInfo->szDumpFile) + 1) * sizeof(WCHAR)); 590 } 591 else if (pStartInfo->dwCrashDumpEnabled == 3) 592 { 593 SendDlgItemMessage(hwndDlg, IDC_STRRECDUMPFILE, WM_GETTEXT, (WPARAM)sizeof(pStartInfo->szDumpFile) / sizeof(WCHAR), (LPARAM)pStartInfo->szDumpFile); 594 RegSetValueExW(hKey, L"MinidumpDir", 0, REG_EXPAND_SZ, (LPBYTE)pStartInfo->szDumpFile, (wcslen(pStartInfo->szDumpFile) + 1) * sizeof(WCHAR)); 595 } 596 597 RegSetValueExW(hKey, L"CrashDumpEnabled", 0, REG_DWORD, (LPBYTE)&pStartInfo->dwCrashDumpEnabled, sizeof(pStartInfo->dwCrashDumpEnabled)); 598 RegCloseKey(hKey); 599 } 600 601 static VOID 602 LoadRecoveryOptions(HWND hwndDlg, PSTARTINFO pStartInfo) 603 { 604 HKEY hKey; 605 WCHAR szName[MAX_PATH]; 606 DWORD dwValue, dwValueLength, dwType, dwResult; 607 608 dwResult = (DWORD)RegCreateKeyExW(HKEY_LOCAL_MACHINE, 609 L"System\\CurrentControlSet\\Control\\CrashControl", 610 0, 611 NULL, 612 REG_OPTION_NON_VOLATILE, 613 KEY_READ, 614 NULL, 615 &hKey, 616 NULL); 617 if (dwResult != ERROR_SUCCESS) 618 { 619 /* Failed to open key */ 620 SetLastError(dwResult); 621 ShowLastWin32Error(hwndDlg); 622 623 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECWRITEEVENT), FALSE); 624 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECSENDALERT), FALSE); 625 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECRESTART), FALSE); 626 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECDEBUGCOMBO), FALSE); 627 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECDUMPFILE), FALSE); 628 EnableWindow(GetDlgItem(hwndDlg, IDC_STRRECOVERWRITE), FALSE); 629 630 SaveRecoveryOptions = FALSE; 631 return; 632 } 633 634 dwValueLength = sizeof(DWORD); 635 if (RegQueryValueExW(hKey, L"LogEvent", NULL, &dwType, (LPBYTE)&dwValue, &dwValueLength) == ERROR_SUCCESS && dwType == REG_DWORD && dwValue) 636 SendDlgItemMessageW(hwndDlg, IDC_STRRECWRITEEVENT, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 637 638 dwValueLength = sizeof(DWORD); 639 if (RegQueryValueExW(hKey, L"SendAlert", NULL, &dwType, (LPBYTE)&dwValue, &dwValueLength) == ERROR_SUCCESS && dwType == REG_DWORD && dwValue) 640 SendDlgItemMessageW(hwndDlg, IDC_STRRECSENDALERT, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 641 642 dwValueLength = sizeof(DWORD); 643 if (RegQueryValueExW(hKey, L"AutoReboot", NULL, &dwType, (LPBYTE)&dwValue, &dwValueLength) == ERROR_SUCCESS && dwType == REG_DWORD && dwValue) 644 SendDlgItemMessageW(hwndDlg, IDC_STRRECRESTART, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 645 646 dwValueLength = sizeof(DWORD); 647 if (RegQueryValueExW(hKey, L"Overwrite", NULL, &dwType, (LPBYTE)&dwValue, &dwValueLength) == ERROR_SUCCESS && dwType == REG_DWORD && dwValue) 648 SendDlgItemMessageW(hwndDlg, IDC_STRRECOVERWRITE, BM_SETCHECK, (WPARAM)BST_CHECKED, (LPARAM)0); 649 650 dwValueLength = sizeof(DWORD); 651 if (RegQueryValueExW(hKey, L"CrashDumpEnabled", NULL, &dwType, (LPBYTE)&dwValue, &dwValueLength) == ERROR_SUCCESS && dwType == REG_DWORD && dwValue) 652 pStartInfo->dwCrashDumpEnabled = dwValue; 653 654 dwValueLength = sizeof(pStartInfo->szDumpFile); 655 if (RegQueryValueExW(hKey, L"DumpFile", NULL, &dwType, (LPBYTE)pStartInfo->szDumpFile, &dwValueLength) != ERROR_SUCCESS) 656 pStartInfo->szDumpFile[0] = L'\0'; 657 658 dwValueLength = sizeof(pStartInfo->szMinidumpDir); 659 if (RegQueryValueExW(hKey, L"MinidumpDir", NULL, &dwType, (LPBYTE)pStartInfo->szMinidumpDir, &dwValueLength) != ERROR_SUCCESS) 660 pStartInfo->szMinidumpDir[0] = L'\0'; 661 662 if (LoadStringW(hApplet, IDS_NO_DUMP, szName, sizeof(szName) / sizeof(WCHAR))) 663 { 664 szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0'; 665 SendDlgItemMessageW(hwndDlg, IDC_STRRECDEBUGCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM) szName); 666 } 667 668 if (LoadStringW(hApplet, IDS_FULL_DUMP, szName, sizeof(szName) / sizeof(WCHAR))) 669 { 670 szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0'; 671 SendDlgItemMessageW(hwndDlg, IDC_STRRECDEBUGCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM) szName); 672 } 673 674 if (LoadStringW(hApplet, IDS_KERNEL_DUMP, szName, sizeof(szName) / sizeof(WCHAR))) 675 { 676 szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0'; 677 SendDlgItemMessageW(hwndDlg, IDC_STRRECDEBUGCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM) szName); 678 } 679 680 if (LoadStringW(hApplet, IDS_MINI_DUMP, szName, sizeof(szName) / sizeof(WCHAR))) 681 { 682 szName[(sizeof(szName)/sizeof(WCHAR))-1] = L'\0'; 683 SendDlgItemMessageW(hwndDlg, IDC_STRRECDEBUGCOMBO, CB_ADDSTRING, (WPARAM)0, (LPARAM) szName); 684 } 685 686 SetCrashDlgItems(hwndDlg, pStartInfo); 687 RegCloseKey(hKey); 688 689 SaveRecoveryOptions = TRUE; 690 } 691 692 693 /* Property page dialog callback */ 694 INT_PTR CALLBACK 695 StartRecDlgProc(HWND hwndDlg, 696 UINT uMsg, 697 WPARAM wParam, 698 LPARAM lParam) 699 { 700 PSTARTINFO pStartInfo; 701 PBOOTRECORD pRecord; 702 int iTimeout; 703 LRESULT lResult; 704 WCHAR szTimeout[10]; 705 706 UNREFERENCED_PARAMETER(lParam); 707 708 pStartInfo = (PSTARTINFO)GetWindowLongPtr(hwndDlg, DWLP_USER); 709 710 switch(uMsg) 711 { 712 case WM_INITDIALOG: 713 pStartInfo = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(STARTINFO)); 714 SetWindowLongPtr(hwndDlg, DWLP_USER, (LONG_PTR)pStartInfo); 715 716 LoadRecoveryOptions(hwndDlg, pStartInfo); 717 SetRecoveryTimeout(hwndDlg, 0); 718 return LoadOSList(hwndDlg, pStartInfo); 719 720 case WM_DESTROY: 721 DeleteBootRecords(hwndDlg); 722 HeapFree(GetProcessHeap(), 0, pStartInfo); 723 break; 724 725 case WM_COMMAND: 726 switch(LOWORD(wParam)) 727 { 728 case IDC_STRRECEDIT: 729 ShellExecuteW(0, L"open", L"notepad", pStartInfo->szFreeldrIni, NULL, SW_SHOWNORMAL); 730 // FIXME: Use CreateProcess and wait untill finished 731 // DeleteBootRecords(hwndDlg); 732 // LoadOSList(hwndDlg); 733 break; 734 735 case IDOK: 736 /* Save timeout */ 737 if (SendDlgItemMessage(hwndDlg, IDC_STRECLIST, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) 738 iTimeout = SendDlgItemMessage(hwndDlg, IDC_STRRECLISTUPDWN, UDM_GETPOS, (WPARAM)0, (LPARAM)0); 739 else 740 iTimeout = 0; 741 swprintf(szTimeout, L"%i", iTimeout); 742 743 lResult = SendDlgItemMessageW(hwndDlg, IDC_STRECOSCOMBO, CB_GETCURSEL, (WPARAM)0, (LPARAM)0); 744 if (lResult == CB_ERR) 745 { 746 /* ? */ 747 DeleteBootRecords(hwndDlg); 748 return TRUE; 749 } 750 751 pRecord = (PBOOTRECORD) SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_GETITEMDATA, (WPARAM)lResult, (LPARAM)0); 752 753 if ((INT_PTR)pRecord != CB_ERR) 754 { 755 if (pStartInfo->iFreeLdrIni == 1) // FreeLdrIni style 756 { 757 /* Set default timeout */ 758 WritePrivateProfileStringW(L"FREELOADER", 759 L"TimeOut", 760 szTimeout, 761 pStartInfo->szFreeldrIni); 762 /* Set default OS */ 763 WritePrivateProfileStringW(L"FREELOADER", 764 L"DefaultOS", 765 pRecord->szSectionName, 766 pStartInfo->szFreeldrIni); 767 768 } 769 else if (pStartInfo->iFreeLdrIni == 2) // BootIni style 770 { 771 /* Set default timeout */ 772 WritePrivateProfileStringW(L"boot loader", 773 L"timeout", 774 szTimeout, 775 pStartInfo->szFreeldrIni); 776 /* Set default OS */ 777 WritePrivateProfileStringW(L"boot loader", 778 L"default", 779 pRecord->szBootPath, 780 pStartInfo->szFreeldrIni); 781 782 } 783 } 784 785 if (SaveRecoveryOptions) 786 { 787 WriteStartupRecoveryOptions(hwndDlg, pStartInfo); 788 } 789 790 EndDialog(hwndDlg, 791 LOWORD(wParam)); 792 return TRUE; 793 794 case IDCANCEL: 795 EndDialog(hwndDlg, 796 LOWORD(wParam)); 797 return TRUE; 798 799 case IDC_STRECLIST: 800 if (SendDlgItemMessage(hwndDlg, IDC_STRECLIST, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) 801 SetTimeout(hwndDlg, 30); 802 else 803 SetTimeout(hwndDlg, 0); 804 break; 805 806 case IDC_STRRECREC: 807 if (SendDlgItemMessage(hwndDlg, IDC_STRRECREC, BM_GETCHECK, (WPARAM)0, (LPARAM)0) == BST_CHECKED) 808 SetRecoveryTimeout(hwndDlg, 30); 809 else 810 SetRecoveryTimeout(hwndDlg, 0); 811 break; 812 813 case IDC_STRRECDEBUGCOMBO: 814 if (HIWORD(wParam) == CBN_SELCHANGE) 815 { 816 LRESULT lResult; 817 818 lResult = SendDlgItemMessage(hwndDlg, IDC_STRRECDEBUGCOMBO, CB_GETCURSEL, (WPARAM)0, (LPARAM)0); 819 if (lResult != CB_ERR && lResult != (LRESULT)pStartInfo->dwCrashDumpEnabled) 820 { 821 if (pStartInfo->dwCrashDumpEnabled == 1 || pStartInfo->dwCrashDumpEnabled == 2) 822 { 823 SendDlgItemMessageW(hwndDlg, IDC_STRRECDUMPFILE, WM_GETTEXT, (WPARAM)sizeof(pStartInfo->szDumpFile) / sizeof(WCHAR), (LPARAM)pStartInfo->szDumpFile); 824 } 825 else if (pStartInfo->dwCrashDumpEnabled == 3) 826 { 827 SendDlgItemMessageW(hwndDlg, IDC_STRRECDUMPFILE, WM_GETTEXT, (WPARAM)sizeof(pStartInfo->szMinidumpDir) / sizeof(WCHAR), (LPARAM)pStartInfo->szMinidumpDir); 828 } 829 830 pStartInfo->dwCrashDumpEnabled = (DWORD)lResult; 831 SetCrashDlgItems(hwndDlg, pStartInfo); 832 } 833 } 834 break; 835 } 836 break; 837 } 838 839 return FALSE; 840 } 841