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