xref: /reactos/dll/cpl/sysdm/startrec.c (revision 0f92924a)
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