Author: janderwald
Date: Mon Aug 20 23:21:54 2007
New Revision: 28433
URL:
http://svn.reactos.org/svn/reactos?rev=28433&view=rev
Log:
- support reading multiple boot configuration
- support saving prefered boot configuration (freeldr / boot ini style)
- parsing of boot options needs to be done
Modified:
trunk/reactos/dll/cpl/sysdm/precomp.h
trunk/reactos/dll/cpl/sysdm/startrec.c
trunk/reactos/dll/cpl/sysdm/sysdm.rbuild
Modified: trunk/reactos/dll/cpl/sysdm/precomp.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/sysdm/precomp.h?re…
==============================================================================
--- trunk/reactos/dll/cpl/sysdm/precomp.h (original)
+++ trunk/reactos/dll/cpl/sysdm/precomp.h Mon Aug 20 23:21:54 2007
@@ -3,7 +3,6 @@
#include <ntstatus.h>
#define WIN32_NO_STATUS
-#include <windows.h>
#include <windows.h>
#include <commctrl.h>
#include <powrprof.h>
@@ -16,6 +15,7 @@
#include <shlobj.h>
#include <cplext.h>
#include <regstr.h>
+#include <setupapi.h>
#include "resource.h"
#define NUM_APPLETS (1)
@@ -66,5 +66,13 @@
PAGEFILE Pagefile[26];
} VIRTMEM, *PVIRTMEM;
+typedef struct _BOOTRECORD
+{
+ DWORD BootType;
+ TCHAR szSectionName[128];
+ TCHAR szBootPath[MAX_PATH];
+ TCHAR szOptions[512];
+
+}BOOTRECORD, *PBOOTRECORD;
#endif /* __CPL_SYSDM_H */
Modified: trunk/reactos/dll/cpl/sysdm/startrec.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/sysdm/startrec.c?r…
==============================================================================
--- trunk/reactos/dll/cpl/sysdm/startrec.c (original)
+++ trunk/reactos/dll/cpl/sysdm/startrec.c Mon Aug 20 23:21:54 2007
@@ -10,10 +10,8 @@
*/
#include "precomp.h"
-
static TCHAR m_szFreeldrIni[MAX_PATH + 15];
-static TCHAR szBootLdrSection[12];
-static TCHAR szBootLdrDefault[10];
+static int m_FreeLdrIni = 0;
void SetTimeout(HWND hwndDlg, int Timeout)
{
@@ -27,6 +25,431 @@
}
SendDlgItemMessage(hwndDlg, IDC_STRRECLISTUPDWN, UDM_SETPOS, (WPARAM) 0, (LPARAM)
MAKELONG((short) Timeout, 0));
}
+
+DWORD GetSystemDrive(TCHAR ** szSystemDrive)
+{
+ DWORD dwBufSize;
+ /* get Path to freeldr.ini or boot.ini */
+ *szSystemDrive = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(TCHAR));
+ if (szSystemDrive != NULL)
+ {
+ dwBufSize = GetEnvironmentVariable(_T("SystemDrive"), *szSystemDrive,
MAX_PATH);
+ if (dwBufSize > MAX_PATH)
+ {
+ TCHAR *szTmp;
+ DWORD dwBufSize2;
+
+ szTmp = HeapReAlloc(GetProcessHeap(), 0, *szSystemDrive, dwBufSize *
sizeof(TCHAR));
+ if (szTmp == NULL)
+ goto FailGetSysDrive;
+
+ *szSystemDrive = szTmp;
+
+ dwBufSize2 = GetEnvironmentVariable(_T("SystemDrive"),
*szSystemDrive, dwBufSize);
+ if (dwBufSize2 > dwBufSize || dwBufSize2 == 0)
+ goto FailGetSysDrive;
+ }
+ else if (dwBufSize == 0)
+ {
+FailGetSysDrive:
+ HeapFree(GetProcessHeap(), 0, szSystemDrive);
+ *szSystemDrive = NULL;
+ return FALSE;
+ }
+ return dwBufSize;
+ }
+ return FALSE;
+}
+
+PBOOTRECORD ReadFreeldrSection(HINF hInf, TCHAR * szSectionName)
+{
+ PBOOTRECORD pRecord;
+ INFCONTEXT InfContext;
+ TCHAR szName[MAX_PATH];
+ TCHAR szValue[MAX_PATH];
+ DWORD LineLength;
+
+ if (!SetupFindFirstLine(hInf,
+ szSectionName,
+ NULL,
+ &InfContext))
+ {
+ /* failed to find section */
+ return NULL;
+ }
+
+ pRecord = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(BOOTRECORD));
+ if (pRecord == NULL)
+ {
+ return NULL;
+ }
+ _tcscpy(pRecord->szSectionName, szSectionName);
+
+ do
+ {
+ if (!SetupGetStringField(&InfContext,
+ 0,
+ szName,
+ sizeof(szName) / sizeof(TCHAR),
+ &LineLength))
+ {
+ break;
+ }
+
+ if (!SetupGetStringField(&InfContext,
+ 1,
+ szValue,
+ sizeof(szValue) / sizeof(TCHAR),
+ &LineLength))
+ {
+ break;
+ }
+
+
+ if (!_tcsnicmp(szName, _T("BootType"), 8))
+ {
+ if (!_tcsnicmp(szValue, _T("ReactOS"), 7))
+ {
+ //FIXME store as enum
+ pRecord->BootType = 1;
+ }
+ else
+ {
+ pRecord->BootType = 0;
+ }
+ }
+ else if (!_tcsnicmp(szName, _T("SystemPath"), 10))
+ {
+ _tcscpy(pRecord->szBootPath, szValue);
+ }
+ else if (!_tcsnicmp(szName, _T("Options"), 7))
+ {
+ //FIXME store flags as values
+ _tcscpy(pRecord->szOptions, szValue);
+ }
+
+ }while(SetupFindNextLine(&InfContext, &InfContext));
+
+ return pRecord;
+}
+
+
+int LoadFreeldrSettings(HINF hInf, HWND hwndDlg)
+{
+ INFCONTEXT InfContext;
+ PBOOTRECORD pRecord;
+ TCHAR szDefaultOs[MAX_PATH];
+ TCHAR szName[MAX_PATH];
+ TCHAR szValue[MAX_PATH];
+ DWORD LineLength;
+ DWORD TimeOut;
+ LRESULT lResult;
+
+ if (!SetupFindFirstLine(hInf,
+ _T("FREELOADER"),
+ _T("DefaultOS"),
+ &InfContext))
+ {
+ /* failed to find default os */
+ return FALSE;
+ }
+
+ if (!SetupGetStringField(&InfContext,
+ 1,
+ szDefaultOs,
+ sizeof(szDefaultOs) / sizeof(TCHAR),
+ &LineLength))
+ {
+ /* no key */
+ return FALSE;
+ }
+
+ if (!SetupFindFirstLine(hInf,
+ _T("FREELOADER"),
+ _T("TimeOut"),
+ &InfContext))
+ {
+ /* expected to find timeout value */
+ return FALSE;
+ }
+
+
+ if (!SetupGetIntField(&InfContext,
+ 1,
+ (PINT)&TimeOut))
+ {
+ /* failed to retrieve timeout */
+ return FALSE;
+ }
+
+ if (!SetupFindFirstLine(hInf,
+ _T("Operating Systems"),
+ NULL,
+ &InfContext))
+ {
+ /* expected list of operating systems */
+ return FALSE;
+ }
+
+ do
+ {
+ if (!SetupGetStringField(&InfContext,
+ 0,
+ szName,
+ sizeof(szName) / sizeof(TCHAR),
+ &LineLength))
+ {
+ /* the ini file is messed up */
+ return FALSE;
+ }
+
+ if (!SetupGetStringField(&InfContext,
+ 1,
+ szValue,
+ sizeof(szValue) / sizeof(TCHAR),
+ &LineLength))
+ {
+ /* the ini file is messed up */
+ return FALSE;
+ }
+
+ pRecord = ReadFreeldrSection(hInf, szName);
+ if (pRecord)
+ {
+ lResult = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING,
(WPARAM)0, (LPARAM)szValue);
+ if (lResult != CB_ERR)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA,
(WPARAM)lResult, (LPARAM)pRecord);
+ if (!_tcscmp(szDefaultOs, szName))
+ {
+ /* we store the friendly name as key */
+ _tcscpy(szDefaultOs, szValue);
+ }
+
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, pRecord);
+ }
+ }
+
+ }while(SetupFindNextLine(&InfContext, &InfContext));
+
+ /* find default os in list */
+ lResult = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)-1,
(LPARAM)szDefaultOs);
+ if (lResult != CB_ERR)
+ {
+ /* set cur sel */
+ SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult,
(LPARAM)0);
+ }
+
+ SetTimeout(hwndDlg, TimeOut);
+ return TRUE;
+}
+
+int LoadBootSettings(HINF hInf, HWND hwndDlg)
+{
+ INFCONTEXT InfContext;
+ TCHAR szName[MAX_PATH];
+ TCHAR szValue[MAX_PATH];
+ DWORD LineLength;
+ DWORD TimeOut = 0;
+ TCHAR szDefaultOS[MAX_PATH];
+ TCHAR szOptions[MAX_PATH];
+ PBOOTRECORD pRecord;
+ LRESULT lResult;
+
+ if(!SetupFindFirstLine(hInf,
+ _T("boot loader"),
+ NULL,
+ &InfContext))
+ {
+ return FALSE;
+ }
+
+ do
+ {
+ if (!SetupGetStringField(&InfContext,
+ 0,
+ szName,
+ sizeof(szName) / sizeof(TCHAR),
+ &LineLength))
+ {
+ return FALSE;
+ }
+
+ if (!SetupGetStringField(&InfContext,
+ 1,
+ szValue,
+ sizeof(szValue) / sizeof(TCHAR),
+ &LineLength))
+ {
+ return FALSE;
+ }
+
+ if (!_tcsnicmp(szName, _T("timeout"), 7))
+ {
+ TimeOut = _ttoi(szValue);
+ }
+
+ if (!_tcsnicmp(szName, _T("default"), 7))
+ {
+ _tcscpy(szDefaultOS, szValue);
+ }
+
+ }while(SetupFindNextLine(&InfContext, &InfContext));
+
+ if (!SetupFindFirstLine(hInf,
+ _T("operating systems"),
+ NULL,
+ &InfContext))
+ {
+ /* failed to find operating systems section */
+ return FALSE;
+ }
+
+ do
+ {
+ if (!SetupGetStringField(&InfContext,
+ 0,
+ szName,
+ sizeof(szName) / sizeof(TCHAR),
+ &LineLength))
+ {
+ return FALSE;
+ }
+
+ if (!SetupGetStringField(&InfContext,
+ 1,
+ szValue,
+ sizeof(szValue) / sizeof(TCHAR),
+ &LineLength))
+ {
+ return FALSE;
+ }
+
+ SetupGetStringField(&InfContext,
+ 2,
+ szOptions,
+ sizeof(szOptions) / sizeof(TCHAR),
+ &LineLength);
+
+ pRecord = (PBOOTRECORD) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
sizeof(BOOTRECORD));
+ if (pRecord)
+ {
+ pRecord->BootType = 0;
+ _tcscpy(pRecord->szBootPath, szName);
+ _tcscpy(pRecord->szSectionName, szValue);
+ _tcscpy(pRecord->szOptions, szOptions);
+
+ if (!_tcscmp(szName, szDefaultOS))
+ {
+ /* ms boot ini stores the path not the friendly name */
+ _tcscpy(szDefaultOS, szValue);
+ }
+
+ lResult = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING,
(WPARAM)0, (LPARAM)szValue);
+ if (lResult != CB_ERR)
+ {
+ SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_SETITEMDATA,
(WPARAM)lResult, (LPARAM)pRecord);
+ }
+ else
+ {
+ HeapFree(GetProcessHeap(), 0, pRecord);
+ }
+ }
+
+ }while(SetupFindNextLine(&InfContext, &InfContext));
+ /* find default os in list */
+ lResult = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_FINDSTRING, (WPARAM)0,
(LPARAM)szDefaultOS);
+ if (lResult != CB_ERR)
+ {
+ /* set cur sel */
+ SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)lResult,
(LPARAM)0);
+ }
+
+ SetTimeout(hwndDlg, TimeOut);
+ return TRUE;
+}
+
+void DeleteBootRecords(HWND hwndDlg)
+{
+ LRESULT lIndex;
+ LONG index;
+ PBOOTRECORD pRecord;
+
+
+ lIndex = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_GETCOUNT, (WPARAM)0,
(LPARAM)0);
+ if (lIndex == CB_ERR)
+ return;
+
+ for (index = 0; index <lIndex; index++)
+ {
+ pRecord = (PBOOTRECORD) SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO,
CB_GETITEMDATA, (WPARAM)index, (LPARAM)0);
+ if ((INT)pRecord != CB_ERR)
+ {
+ HeapFree(GetProcessHeap(), 0, pRecord);
+ }
+ }
+ SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_RESETCONTENT, (WPARAM)0,
(LPARAM)0);
+}
+
+LRESULT LoadOSList(HWND hwndDlg)
+{
+ DWORD dwBufSize;
+ TCHAR *szSystemDrive;
+ HINF hInf;
+
+ SetDlgItemText(hwndDlg, IDC_STRRECDUMPFILE, _T("%SystemRoot%\\MiniDump"));
+
+ dwBufSize = GetSystemDrive(&szSystemDrive);
+ if (!dwBufSize)
+ return FALSE;
+
+
+ _tcscpy(m_szFreeldrIni, szSystemDrive);
+ _tcscat(m_szFreeldrIni, _T("\\freeldr.ini"));
+ if (PathFileExists(m_szFreeldrIni))
+ {
+ /* freeldr.ini exists */
+ hInf = SetupOpenInfFile(m_szFreeldrIni,
+ NULL,
+ INF_STYLE_OLDNT,
+ NULL);
+
+ if (hInf != INVALID_HANDLE_VALUE)
+ {
+ LoadFreeldrSettings(hInf, hwndDlg);
+ SetupCloseInfFile(hInf);
+ m_FreeLdrIni = 1;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ /* try load boot.ini settings */
+ _tcscpy(m_szFreeldrIni, szSystemDrive);
+ _tcscat(m_szFreeldrIni, _T("\\boot.ini"));
+
+ if (PathFileExists(m_szFreeldrIni))
+ {
+ /* load boot.ini settings */
+ hInf = SetupOpenInfFile(m_szFreeldrIni,
+ NULL,
+ INF_STYLE_OLDNT,
+ NULL);
+
+ if (hInf != INVALID_HANDLE_VALUE)
+ {
+ LoadBootSettings(hInf, hwndDlg);
+ SetupCloseInfFile(hInf);
+ m_FreeLdrIni = 2;
+ return TRUE;
+ }
+ return FALSE;
+ }
+ return FALSE;
+}
+
/* Property page dialog callback */
INT_PTR CALLBACK
@@ -35,11 +458,10 @@
WPARAM wParam,
LPARAM lParam)
{
- TCHAR *szSystemDrive;
- TCHAR szDefaultOS[MAX_PATH];
- TCHAR szDefaultOSName[MAX_PATH];
+ PBOOTRECORD pRecord;
+ int iTimeout;
+ LRESULT lResult;
TCHAR szTimeout[10];
- int iTimeout;
UNREFERENCED_PARAMETER(lParam);
@@ -47,76 +469,7 @@
{
case WM_INITDIALOG:
{
- DWORD dwBufSize;
-
- /* get Path to freeldr.ini or boot.ini */
- szSystemDrive = HeapAlloc(GetProcessHeap(), 0, MAX_PATH * sizeof(TCHAR));
- if (szSystemDrive != NULL)
- {
- dwBufSize = GetEnvironmentVariable(_T("SystemDrive"),
szSystemDrive, MAX_PATH);
- if (dwBufSize > MAX_PATH)
- {
- TCHAR *szTmp;
- DWORD dwBufSize2;
-
- szTmp = HeapReAlloc(GetProcessHeap(), 0, szSystemDrive, dwBufSize *
sizeof(TCHAR));
- if (szTmp == NULL)
- goto FailGetSysDrive;
-
- szSystemDrive = szTmp;
-
- dwBufSize2 = GetEnvironmentVariable(_T("SystemDrive"),
szSystemDrive, dwBufSize);
- if (dwBufSize2 > dwBufSize || dwBufSize2 == 0)
- goto FailGetSysDrive;
- }
- else if (dwBufSize == 0)
- {
-FailGetSysDrive:
- HeapFree(GetProcessHeap(), 0, szSystemDrive);
- szSystemDrive = NULL;
- return FALSE;
- }
-
- if (szSystemDrive != NULL)
- {
- if (m_szFreeldrIni != NULL)
- {
- _tcscpy(m_szFreeldrIni, szSystemDrive);
- _tcscat(m_szFreeldrIni, _T("\\freeldr.ini"));
- if (!PathFileExists(m_szFreeldrIni))
- {
- _tcscpy(m_szFreeldrIni, szSystemDrive);
- _tcscat(m_szFreeldrIni, _T("\\boot.ini"));
- _tcscpy(szBootLdrSection, _T("boot loader"));
- _tcscpy(szBootLdrDefault, _T("default"));
- }
- else
- {
- _tcscpy(szBootLdrSection, _T("FREELOADER"));
- _tcscpy(szBootLdrDefault, _T("DefaultOS"));
- }
- }
- HeapFree(GetProcessHeap(), 0, szSystemDrive);
- }
- }
-
- if (m_szFreeldrIni == NULL)
- return FALSE;
-
- SetDlgItemText(hwndDlg, IDC_STRRECDUMPFILE,
_T("%SystemRoot%\\MiniDump"));
-
- /* load settings from freeldr.ini */
- GetPrivateProfileString(szBootLdrSection, szBootLdrDefault, NULL,
szDefaultOS, MAX_PATH, m_szFreeldrIni);
- GetPrivateProfileString(_T("operating systems"), szDefaultOS, NULL,
szDefaultOSName, MAX_PATH, m_szFreeldrIni);
- SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_ADDSTRING, (WPARAM)0,
(LPARAM)szDefaultOSName);
- SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_SETCURSEL, (WPARAM)0,
(LPARAM)0);
-
- /* timeout */
- iTimeout = GetPrivateProfileInt(szBootLdrSection, _T("timeout"), 0,
m_szFreeldrIni);
- SetTimeout(hwndDlg, iTimeout);
- if (iTimeout != 0)
- SendDlgItemMessage(hwndDlg, IDC_STRECLIST, BM_SETCHECK,
(WPARAM)BST_CHECKED, (LPARAM)0);
-
+ return LoadOSList(hwndDlg);
}
break;
@@ -127,6 +480,9 @@
case IDC_STRRECEDIT:
{
ShellExecute(0, _T("open"), _T("notepad"),
m_szFreeldrIni, NULL, SW_SHOWNORMAL);
+ // FIXME use CreateProcess and wait untill finished
+ // DeleteBootRecords(hwndDlg);
+ // LoadOSList(hwndDlg);
break;
}
case IDOK:
@@ -137,14 +493,63 @@
else
iTimeout = 0;
_stprintf(szTimeout, _T("%i"), iTimeout);
- WritePrivateProfileString(szBootLdrSection, _T("timeout"),
szTimeout, m_szFreeldrIni);
- }
- case IDCANCEL:
- {
+
+ lResult = SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO, CB_GETCURSEL,
(WPARAM)0, (LPARAM)0);
+ if (lResult == CB_ERR)
+ {
+ /* ? */
+ DeleteBootRecords(hwndDlg);
+ return TRUE;
+ }
+
+
+ pRecord = (PBOOTRECORD) SendDlgItemMessage(hwndDlg, IDC_STRECOSCOMBO,
CB_GETITEMDATA, (WPARAM)lResult, (LPARAM)0);
+
+
+
+ if ((INT)pRecord != CB_ERR)
+ {
+ if (m_FreeLdrIni == 1) // FreeLdrIni style
+ {
+ /* set default timeout */
+ WritePrivateProfileString(_T("FREELOADER"),
+ _T("TimeOut"),
+ szTimeout,
+ m_szFreeldrIni);
+ /* set default os */
+ WritePrivateProfileString(_T("FREELOADER"),
+ _T("DefaultOS"),
+ pRecord->szSectionName,
+ m_szFreeldrIni);
+
+ }
+ else if (m_FreeLdrIni == 2) // BootIni style
+ {
+ /* set default timeout */
+ WritePrivateProfileString(_T("boot loader"),
+ _T("timeout"),
+ szTimeout,
+ m_szFreeldrIni);
+ /* set default os */
+ WritePrivateProfileString(_T("boot loader"),
+ _T("default"),
+ pRecord->szBootPath,
+ m_szFreeldrIni);
+
+ }
+ }
+ DeleteBootRecords(hwndDlg);
EndDialog(hwndDlg,
LOWORD(wParam));
return TRUE;
break;
+ }
+ case IDCANCEL:
+ {
+ DeleteBootRecords(hwndDlg);
+ EndDialog(hwndDlg,
+ LOWORD(wParam));
+ return TRUE;
}
case IDC_STRECLIST:
{
Modified: trunk/reactos/dll/cpl/sysdm/sysdm.rbuild
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/cpl/sysdm/sysdm.rbuild…
==============================================================================
--- trunk/reactos/dll/cpl/sysdm/sysdm.rbuild (original)
+++ trunk/reactos/dll/cpl/sysdm/sysdm.rbuild Mon Aug 20 23:21:54 2007
@@ -8,6 +8,7 @@
<define name="WINVER">0x501</define>
<library>kernel32</library>
<library>advapi32</library>
+ <library>setupapi</library>
<library>msvcrt</library>
<library>user32</library>
<library>gdi32</library>