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
SetTimeout(HWND hwndDlg,INT Timeout)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
SetRecoveryTimeout(HWND hwndDlg,INT Timeout)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
GetSystemDrive(WCHAR ** szSystemDrive)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
ReadFreeldrSection(HINF hInf,WCHAR * szSectionName)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
LoadFreeldrSettings(HINF hInf,HWND hwndDlg)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
LoadBootSettings(HINF hInf,HWND hwndDlg)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
DeleteBootRecords(HWND hwndDlg)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
LoadOSList(HWND hwndDlg,PSTARTINFO pStartInfo)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
SetCrashDlgItems(HWND hwnd,PSTARTINFO pStartInfo)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
WriteStartupRecoveryOptions(HWND hwndDlg,PSTARTINFO pStartInfo)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
LoadRecoveryOptions(HWND hwndDlg,PSTARTINFO pStartInfo)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
StartRecDlgProc(HWND hwndDlg,UINT uMsg,WPARAM wParam,LPARAM lParam)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