3 * PROJECT: ReactOS System Control Panel Applet
4 * LICENSE: GPL - See COPYING in the top level directory
5 * FILE: dll/cpl/sysdm/startrec.c
6 * PURPOSE: Computer settings for startup and recovery
7 * COPYRIGHT: Copyright 2006 Ged Murphy <gedmurphy@gmail.com>
8 * Copyright 2006 Christoph von Wittich <Christoph@ApiViewer.de>
9 * Copyright 2007 Johannes Anderwald <johannes dot anderwald at student dot tugraz dot at>
13 static TCHAR m_szFreeldrIni
[MAX_PATH
+ 15];
14 static int m_FreeLdrIni
= 0;
15 static TCHAR m_szDumpFile
[MAX_PATH
];
16 static TCHAR m_szMinidumpDir
[MAX_PATH
];
17 static DWORD m_dwCrashDumpEnabled
= 0;
19 void SetTimeout(HWND hwndDlg
, int Timeout
)
23 EnableWindow(GetDlgItem(hwndDlg
, IDC_STRRECLISTUPDWN
), FALSE
);
27 EnableWindow(GetDlgItem(hwndDlg
, IDC_STRRECLISTUPDWN
), TRUE
);
29 SendDlgItemMessage(hwndDlg
, IDC_STRRECLISTUPDWN
, UDM_SETPOS
, (WPARAM
) 0, (LPARAM
) MAKELONG((short) Timeout
, 0));
32 DWORD
GetSystemDrive(TCHAR
** szSystemDrive
)
35 /* get Path to freeldr.ini or boot.ini */
36 *szSystemDrive
= HeapAlloc(GetProcessHeap(), 0, MAX_PATH
* sizeof(TCHAR
));
37 if (szSystemDrive
!= NULL
)
39 dwBufSize
= GetEnvironmentVariable(_T("SystemDrive"), *szSystemDrive
, MAX_PATH
);
40 if (dwBufSize
> MAX_PATH
)
45 szTmp
= HeapReAlloc(GetProcessHeap(), 0, *szSystemDrive
, dwBufSize
* sizeof(TCHAR
));
49 *szSystemDrive
= szTmp
;
51 dwBufSize2
= GetEnvironmentVariable(_T("SystemDrive"), *szSystemDrive
, dwBufSize
);
52 if (dwBufSize2
> dwBufSize
|| dwBufSize2
== 0)
55 else if (dwBufSize
== 0)
58 HeapFree(GetProcessHeap(), 0, szSystemDrive
);
59 *szSystemDrive
= NULL
;
67 PBOOTRECORD
ReadFreeldrSection(HINF hInf
, TCHAR
* szSectionName
)
70 INFCONTEXT InfContext
;
71 TCHAR szName
[MAX_PATH
];
72 TCHAR szValue
[MAX_PATH
];
75 if (!SetupFindFirstLine(hInf
,
80 /* failed to find section */
84 pRecord
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BOOTRECORD
));
89 _tcscpy(pRecord
->szSectionName
, szSectionName
);
93 if (!SetupGetStringField(&InfContext
,
96 sizeof(szName
) / sizeof(TCHAR
),
102 if (!SetupGetStringField(&InfContext
,
105 sizeof(szValue
) / sizeof(TCHAR
),
112 if (!_tcsnicmp(szName
, _T("BootType"), 8))
114 if (!_tcsnicmp(szValue
, _T("ReactOS"), 7))
116 //FIXME store as enum
117 pRecord
->BootType
= 1;
121 pRecord
->BootType
= 0;
124 else if (!_tcsnicmp(szName
, _T("SystemPath"), 10))
126 _tcscpy(pRecord
->szBootPath
, szValue
);
128 else if (!_tcsnicmp(szName
, _T("Options"), 7))
130 //FIXME store flags as values
131 _tcscpy(pRecord
->szOptions
, szValue
);
134 }while(SetupFindNextLine(&InfContext
, &InfContext
));
140 int LoadFreeldrSettings(HINF hInf
, HWND hwndDlg
)
142 INFCONTEXT InfContext
;
144 TCHAR szDefaultOs
[MAX_PATH
];
145 TCHAR szName
[MAX_PATH
];
146 TCHAR szValue
[MAX_PATH
];
151 if (!SetupFindFirstLine(hInf
,
156 /* failed to find default os */
160 if (!SetupGetStringField(&InfContext
,
163 sizeof(szDefaultOs
) / sizeof(TCHAR
),
170 if (!SetupFindFirstLine(hInf
,
175 /* expected to find timeout value */
180 if (!SetupGetIntField(&InfContext
,
184 /* failed to retrieve timeout */
188 if (!SetupFindFirstLine(hInf
,
189 _T("Operating Systems"),
193 /* expected list of operating systems */
199 if (!SetupGetStringField(&InfContext
,
202 sizeof(szName
) / sizeof(TCHAR
),
205 /* the ini file is messed up */
209 if (!SetupGetStringField(&InfContext
,
212 sizeof(szValue
) / sizeof(TCHAR
),
215 /* the ini file is messed up */
219 pRecord
= ReadFreeldrSection(hInf
, szName
);
222 lResult
= SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_ADDSTRING
, (WPARAM
)0, (LPARAM
)szValue
);
223 if (lResult
!= CB_ERR
)
225 SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_SETITEMDATA
, (WPARAM
)lResult
, (LPARAM
)pRecord
);
226 if (!_tcscmp(szDefaultOs
, szName
))
228 /* we store the friendly name as key */
229 _tcscpy(szDefaultOs
, szValue
);
235 HeapFree(GetProcessHeap(), 0, pRecord
);
239 }while(SetupFindNextLine(&InfContext
, &InfContext
));
241 /* find default os in list */
242 lResult
= SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_FINDSTRING
, (WPARAM
)-1, (LPARAM
)szDefaultOs
);
243 if (lResult
!= CB_ERR
)
246 SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_SETCURSEL
, (WPARAM
)lResult
, (LPARAM
)0);
249 SetTimeout(hwndDlg
, TimeOut
);
253 int LoadBootSettings(HINF hInf
, HWND hwndDlg
)
255 INFCONTEXT InfContext
;
256 TCHAR szName
[MAX_PATH
];
257 TCHAR szValue
[MAX_PATH
];
260 TCHAR szDefaultOS
[MAX_PATH
];
261 TCHAR szOptions
[MAX_PATH
];
265 if(!SetupFindFirstLine(hInf
,
275 if (!SetupGetStringField(&InfContext
,
278 sizeof(szName
) / sizeof(TCHAR
),
284 if (!SetupGetStringField(&InfContext
,
287 sizeof(szValue
) / sizeof(TCHAR
),
293 if (!_tcsnicmp(szName
, _T("timeout"), 7))
295 TimeOut
= _ttoi(szValue
);
298 if (!_tcsnicmp(szName
, _T("default"), 7))
300 _tcscpy(szDefaultOS
, szValue
);
303 }while(SetupFindNextLine(&InfContext
, &InfContext
));
305 if (!SetupFindFirstLine(hInf
,
306 _T("operating systems"),
310 /* failed to find operating systems section */
316 if (!SetupGetStringField(&InfContext
,
319 sizeof(szName
) / sizeof(TCHAR
),
325 if (!SetupGetStringField(&InfContext
,
328 sizeof(szValue
) / sizeof(TCHAR
),
334 SetupGetStringField(&InfContext
,
337 sizeof(szOptions
) / sizeof(TCHAR
),
340 pRecord
= (PBOOTRECORD
) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(BOOTRECORD
));
343 pRecord
->BootType
= 0;
344 _tcscpy(pRecord
->szBootPath
, szName
);
345 _tcscpy(pRecord
->szSectionName
, szValue
);
346 _tcscpy(pRecord
->szOptions
, szOptions
);
348 if (!_tcscmp(szName
, szDefaultOS
))
350 /* ms boot ini stores the path not the friendly name */
351 _tcscpy(szDefaultOS
, szValue
);
354 lResult
= SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_ADDSTRING
, (WPARAM
)0, (LPARAM
)szValue
);
355 if (lResult
!= CB_ERR
)
357 SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_SETITEMDATA
, (WPARAM
)lResult
, (LPARAM
)pRecord
);
361 HeapFree(GetProcessHeap(), 0, pRecord
);
365 }while(SetupFindNextLine(&InfContext
, &InfContext
));
366 /* find default os in list */
367 lResult
= SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_FINDSTRING
, (WPARAM
)0, (LPARAM
)szDefaultOS
);
368 if (lResult
!= CB_ERR
)
371 SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_SETCURSEL
, (WPARAM
)lResult
, (LPARAM
)0);
374 SetTimeout(hwndDlg
, TimeOut
);
378 void DeleteBootRecords(HWND hwndDlg
)
385 lIndex
= SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_GETCOUNT
, (WPARAM
)0, (LPARAM
)0);
386 if (lIndex
== CB_ERR
)
389 for (index
= 0; index
<lIndex
; index
++)
391 pRecord
= (PBOOTRECORD
) SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_GETITEMDATA
, (WPARAM
)index
, (LPARAM
)0);
392 if ((INT
)pRecord
!= CB_ERR
)
394 HeapFree(GetProcessHeap(), 0, pRecord
);
397 SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_RESETCONTENT
, (WPARAM
)0, (LPARAM
)0);
400 LRESULT
LoadOSList(HWND hwndDlg
)
403 TCHAR
*szSystemDrive
;
406 dwBufSize
= GetSystemDrive(&szSystemDrive
);
411 _tcscpy(m_szFreeldrIni
, szSystemDrive
);
412 _tcscat(m_szFreeldrIni
, _T("\\freeldr.ini"));
413 if (PathFileExists(m_szFreeldrIni
))
415 /* freeldr.ini exists */
416 hInf
= SetupOpenInfFile(m_szFreeldrIni
,
421 if (hInf
!= INVALID_HANDLE_VALUE
)
423 LoadFreeldrSettings(hInf
, hwndDlg
);
424 SetupCloseInfFile(hInf
);
430 /* try load boot.ini settings */
431 _tcscpy(m_szFreeldrIni
, szSystemDrive
);
432 _tcscat(m_szFreeldrIni
, _T("\\boot.ini"));
434 if (PathFileExists(m_szFreeldrIni
))
436 /* load boot.ini settings */
437 hInf
= SetupOpenInfFile(m_szFreeldrIni
,
442 if (hInf
!= INVALID_HANDLE_VALUE
)
444 LoadBootSettings(hInf
, hwndDlg
);
445 SetupCloseInfFile(hInf
);
454 void SetCrashDlgItems(HWND hwnd
)
456 if (m_dwCrashDumpEnabled
== 0)
458 /* no crash information required */
459 EnableWindow(GetDlgItem(hwnd
, IDC_STRRECDUMPFILE
), FALSE
);
460 EnableWindow(GetDlgItem(hwnd
, IDC_STRRECOVERWRITE
), FALSE
);
462 else if (m_dwCrashDumpEnabled
== 3)
465 EnableWindow(GetDlgItem(hwnd
, IDC_STRRECDUMPFILE
), TRUE
);
466 EnableWindow(GetDlgItem(hwnd
, IDC_STRRECOVERWRITE
), FALSE
);
467 SendMessage(GetDlgItem(hwnd
, IDC_STRRECDUMPFILE
), WM_SETTEXT
, (WPARAM
)0, (LPARAM
)m_szMinidumpDir
);
469 else if (m_dwCrashDumpEnabled
== 1 || m_dwCrashDumpEnabled
== 2)
471 /* kernel or complete dump */
472 EnableWindow(GetDlgItem(hwnd
, IDC_STRRECDUMPFILE
), TRUE
);
473 EnableWindow(GetDlgItem(hwnd
, IDC_STRRECOVERWRITE
), TRUE
);
474 SendMessage(GetDlgItem(hwnd
, IDC_STRRECDUMPFILE
), WM_SETTEXT
, (WPARAM
)0, (LPARAM
)m_szDumpFile
);
476 SendDlgItemMessage(hwnd
, IDC_STRRECDEBUGCOMBO
, CB_SETCURSEL
, (WPARAM
)m_dwCrashDumpEnabled
, (LPARAM
)0);
479 void WriteStartupRecoveryOptions(HWND hwndDlg
)
483 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
484 _T("System\\CurrentControlSet\\Control\\CrashControl"),
487 &hKey
) != ERROR_SUCCESS
)
489 /* failed to open key */
493 lResult
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_STRRECWRITEEVENT
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0);
494 RegSetValueEx(hKey
, _T("LogEvent"), 0, REG_DWORD
, (LPBYTE
)&lResult
, sizeof(lResult
));
496 lResult
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_STRRECSENDALERT
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0);
497 RegSetValueEx(hKey
, _T("SendAlert"), 0, REG_DWORD
, (LPBYTE
)&lResult
, sizeof(lResult
));
499 lResult
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_STRRECRESTART
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0);
500 RegSetValueEx(hKey
, _T("AutoReboot"), 0, REG_DWORD
, (LPBYTE
)&lResult
, sizeof(lResult
));
502 lResult
= (DWORD
) SendDlgItemMessage(hwndDlg
, IDC_STRRECOVERWRITE
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0);
503 RegSetValueEx(hKey
, _T("Overwrite"), 0, REG_DWORD
, (LPBYTE
)&lResult
, sizeof(lResult
));
506 if (m_dwCrashDumpEnabled
== 1 || m_dwCrashDumpEnabled
== 2)
508 SendDlgItemMessage(hwndDlg
, IDC_STRRECDUMPFILE
, WM_GETTEXT
, (WPARAM
)sizeof(m_szDumpFile
) / sizeof(TCHAR
), (LPARAM
)m_szDumpFile
);
509 RegSetValueEx(hKey
, _T("DumpFile"), 0, REG_EXPAND_SZ
, (LPBYTE
)&m_szDumpFile
, (_tcslen(m_szDumpFile
) + 1) * sizeof(TCHAR
));
511 else if (m_dwCrashDumpEnabled
== 3)
513 SendDlgItemMessage(hwndDlg
, IDC_STRRECDUMPFILE
, WM_GETTEXT
, (WPARAM
)sizeof(m_szDumpFile
) / sizeof(TCHAR
), (LPARAM
)m_szDumpFile
);
514 RegSetValueEx(hKey
, _T("MinidumpDir"), 0, REG_EXPAND_SZ
, (LPBYTE
)&m_szDumpFile
, (_tcslen(m_szDumpFile
) + 1) * sizeof(TCHAR
));
517 RegSetValueEx(hKey
, _T("CrashDumpEnabled"), 0, REG_DWORD
, (LPBYTE
)&m_dwCrashDumpEnabled
, sizeof(m_dwCrashDumpEnabled
));
521 void LoadRecoveryOptions(HWND hwndDlg
)
525 TCHAR szName
[MAX_PATH
];
526 TCHAR szValue
[MAX_PATH
];
527 DWORD i
, dwName
, dwValue
, dwValueLength
, dwType
;
529 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE
,
530 _T("System\\CurrentControlSet\\Control\\CrashControl"),
533 &hKey
) != ERROR_SUCCESS
)
535 /* failed to open key */
539 if (RegQueryInfoKey(hKey
,
550 NULL
) != ERROR_SUCCESS
)
556 for (i
= 0; i
< dwValues
; i
++)
558 dwName
= sizeof(szName
) / sizeof(TCHAR
);
560 RegEnumValue(hKey
, i
, szName
, &dwName
, NULL
, &dwType
, NULL
, NULL
);
561 if (dwType
== REG_DWORD
)
563 dwValueLength
= sizeof(dwValue
);
564 dwName
= sizeof(szName
) / sizeof(TCHAR
);
565 if (RegEnumValue(hKey
, i
, szName
, &dwName
, NULL
, &dwType
, (LPBYTE
)&dwValue
, &dwValueLength
) != ERROR_SUCCESS
)
570 dwValueLength
= sizeof(szValue
);
571 dwName
= sizeof(szName
) / sizeof(TCHAR
);
572 if (RegEnumValue(hKey
, i
, szName
, &dwName
, NULL
, &dwType
, (LPBYTE
)&szValue
, &dwValueLength
) != ERROR_SUCCESS
)
576 if (!_tcscmp(szName
, _T("LogEvent")))
579 SendDlgItemMessage(hwndDlg
, IDC_STRRECWRITEEVENT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, (LPARAM
)0);
581 else if (!_tcscmp(szName
, _T("SendAlert")))
584 SendDlgItemMessage(hwndDlg
, IDC_STRRECSENDALERT
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, (LPARAM
)0);
586 else if (!_tcscmp(szName
, _T("AutoReboot")))
589 SendDlgItemMessage(hwndDlg
, IDC_STRRECRESTART
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, (LPARAM
)0);
591 else if (!_tcscmp(szName
, _T("Overwrite")))
594 SendDlgItemMessage(hwndDlg
, IDC_STRRECOVERWRITE
, BM_SETCHECK
, (WPARAM
)BST_CHECKED
, (LPARAM
)0);
596 else if (!_tcscmp(szName
, _T("DumpFile")))
598 _tcscpy(m_szDumpFile
, szValue
);
600 else if (!_tcscmp(szName
, _T("MinidumpDir")))
602 _tcscpy(m_szMinidumpDir
, szValue
);
604 else if (!_tcscmp(szName
, _T("CrashDumpEnabled")))
606 m_dwCrashDumpEnabled
= dwValue
;
610 if (LoadString(hApplet
, IDS_NO_DUMP
, szValue
, sizeof(szValue
) / sizeof(TCHAR
)) < sizeof(szValue
) / sizeof(TCHAR
))
611 SendDlgItemMessage(hwndDlg
, IDC_STRRECDEBUGCOMBO
, CB_ADDSTRING
, (WPARAM
)0, (LPARAM
) szValue
);
612 if (LoadString(hApplet
, IDS_FULL_DUMP
, szValue
, sizeof(szValue
) / sizeof(TCHAR
)) < sizeof(szValue
) / sizeof(TCHAR
))
613 SendDlgItemMessage(hwndDlg
, IDC_STRRECDEBUGCOMBO
, CB_ADDSTRING
, (WPARAM
)0, (LPARAM
) szValue
);
614 if (LoadString(hApplet
, IDS_KERNEL_DUMP
, szValue
, sizeof(szValue
) / sizeof(TCHAR
)) < sizeof(szValue
) / sizeof(TCHAR
))
615 SendDlgItemMessage(hwndDlg
, IDC_STRRECDEBUGCOMBO
, CB_ADDSTRING
, (WPARAM
)0, (LPARAM
) szValue
);
616 if (LoadString(hApplet
, IDS_MINI_DUMP
, szValue
, sizeof(szValue
) / sizeof(TCHAR
)) < sizeof(szValue
) / sizeof(TCHAR
))
617 SendDlgItemMessage(hwndDlg
, IDC_STRRECDEBUGCOMBO
, CB_ADDSTRING
, (WPARAM
)0, (LPARAM
) szValue
);
619 SetCrashDlgItems(hwndDlg
);
625 /* Property page dialog callback */
627 StartRecDlgProc(HWND hwndDlg
,
637 UNREFERENCED_PARAMETER(lParam
);
643 LoadRecoveryOptions(hwndDlg
);
644 return LoadOSList(hwndDlg
);
650 switch(LOWORD(wParam
))
654 ShellExecute(0, _T("open"), _T("notepad"), m_szFreeldrIni
, NULL
, SW_SHOWNORMAL
);
655 // FIXME use CreateProcess and wait untill finished
656 // DeleteBootRecords(hwndDlg);
657 // LoadOSList(hwndDlg);
663 if (SendDlgItemMessage(hwndDlg
, IDC_STRECLIST
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
664 iTimeout
= SendDlgItemMessage(hwndDlg
, IDC_STRRECLISTUPDWN
, UDM_GETPOS
, (WPARAM
)0, (LPARAM
)0);
667 _stprintf(szTimeout
, _T("%i"), iTimeout
);
669 lResult
= SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_GETCURSEL
, (WPARAM
)0, (LPARAM
)0);
670 if (lResult
== CB_ERR
)
673 DeleteBootRecords(hwndDlg
);
678 pRecord
= (PBOOTRECORD
) SendDlgItemMessage(hwndDlg
, IDC_STRECOSCOMBO
, CB_GETITEMDATA
, (WPARAM
)lResult
, (LPARAM
)0);
680 if ((INT
)pRecord
!= CB_ERR
)
682 if (m_FreeLdrIni
== 1) // FreeLdrIni style
684 /* set default timeout */
685 WritePrivateProfileString(_T("FREELOADER"),
690 WritePrivateProfileString(_T("FREELOADER"),
692 pRecord
->szSectionName
,
696 else if (m_FreeLdrIni
== 2) // BootIni style
698 /* set default timeout */
699 WritePrivateProfileString(_T("boot loader"),
704 WritePrivateProfileString(_T("boot loader"),
711 WriteStartupRecoveryOptions(hwndDlg
);
712 DeleteBootRecords(hwndDlg
);
719 DeleteBootRecords(hwndDlg
);
726 if (SendDlgItemMessage(hwndDlg
, IDC_STRECLIST
, BM_GETCHECK
, (WPARAM
)0, (LPARAM
)0) == BST_CHECKED
)
727 SetTimeout(hwndDlg
, 30);
729 SetTimeout(hwndDlg
, 0);
731 case IDC_STRRECDEBUGCOMBO
:
733 if (HIWORD(wParam
) == CBN_SELCHANGE
)
737 lResult
= SendDlgItemMessage(hwndDlg
, IDC_STRRECDEBUGCOMBO
, CB_GETCURSEL
, (WPARAM
)0, (LPARAM
)0);
738 if (lResult
!= CB_ERR
&& lResult
!= m_dwCrashDumpEnabled
)
740 if (m_dwCrashDumpEnabled
== 1 || m_dwCrashDumpEnabled
== 2)
742 SendDlgItemMessage(hwndDlg
, IDC_STRRECDUMPFILE
, WM_GETTEXT
, (WPARAM
)sizeof(m_szDumpFile
) / sizeof(TCHAR
), (LPARAM
)m_szDumpFile
);
744 else if (m_dwCrashDumpEnabled
== 3)
746 SendDlgItemMessage(hwndDlg
, IDC_STRRECDUMPFILE
, WM_GETTEXT
, (WPARAM
)sizeof(m_szMinidumpDir
) / sizeof(TCHAR
), (LPARAM
)m_szMinidumpDir
);
748 m_dwCrashDumpEnabled
= lResult
;
749 SetCrashDlgItems(hwndDlg
);