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