1 /*
2  * PROJECT:     ReactOS Applications
3  * LICENSE:     LGPL - See COPYING in the top level directory
4  * FILE:        base/applications/msconfig/freeldrpage.c
5  * PURPOSE:     Freeloader configuration page message handler
6  * COPYRIGHT:   Copyright 2005-2006 Christoph von Wittich <Christoph@ApiViewer.de>
7  *                        2011      Gregor Schneider <Gregor.Schneider@reactos.org>
8  */
9 
10 #include "precomp.h"
11 
12 HWND hFreeLdrPage;
13 HWND hFreeLdrDialog;
14 
15 typedef struct
16 {
17     ULONG TimeOut;
18     WCHAR szDefaultOS[512];
19     ULONG szDefaultPos;
20     ULONG OSConfigurationCount;
21     BOOL  UseBootIni;
22 } FREELDR_SETTINGS;
23 
24 static FREELDR_SETTINGS Settings = { 0, { 0, }, 0, 0, FALSE };
25 
26 #define BUFFER_SIZE 512
27 
28 static BOOL
29 LoadBootIni(WCHAR *szDrive, HWND hDlg)
30 {
31     WCHAR szBuffer[BUFFER_SIZE];
32     HWND hDlgCtrl;
33     FILE * file;
34     UINT length;
35     LRESULT pos;
36     HRESULT hr;
37 
38     hr = StringCbCopyW(szBuffer, sizeof(szBuffer), szDrive);
39     if (FAILED(hr))
40         return FALSE;
41 
42     hr = StringCbCatW(szBuffer, sizeof(szBuffer), L"freeldr.ini");
43     if (FAILED(hr))
44         return FALSE;
45 
46     file = _wfopen(szBuffer, L"rt");
47     if (!file)
48     {
49         hr = StringCbCopyW(szBuffer, sizeof(szBuffer), szDrive);
50         if (FAILED(hr))
51             return FALSE;
52 
53         hr = StringCbCatW(szBuffer, sizeof(szBuffer), L"boot.ini");
54         if (FAILED(hr))
55             return FALSE;
56 
57         file = _wfopen(szBuffer, L"rt");
58         if (!file)
59             return FALSE;
60     }
61 
62     hDlgCtrl = GetDlgItem(hDlg, IDC_LIST_BOX);
63 
64     while(!feof(file))
65     {
66         if (fgetws(szBuffer, BUFFER_SIZE, file))
67         {
68             length = wcslen(szBuffer);
69             if (length > 1)
70             {
71                 szBuffer[length] = L'\0';
72                 szBuffer[length - 1] = L'\0';
73 
74                 pos = SendMessageW(hDlgCtrl, LB_ADDSTRING, 0, (LPARAM)szBuffer);
75 
76                 if (szBuffer[0] == L'[')
77                     continue;
78 
79                 if (!_wcsnicmp(szBuffer, L"timeout=", 8))
80                 {
81                     Settings.TimeOut = _wtoi(&szBuffer[8]);
82                     continue;
83                 }
84 
85                 if (!_wcsnicmp(szBuffer, L"default=", 8))
86                 {
87                     wcscpy(Settings.szDefaultOS, &szBuffer[8]);
88                     continue;
89                 }
90                 if (pos != LB_ERR)
91                     SendMessage(hDlgCtrl, LB_SETITEMDATA, pos, 1); // indicate that this item is an boot entry
92                 Settings.OSConfigurationCount++;
93             }
94         }
95     }
96 
97     fclose(file);
98     Settings.UseBootIni = TRUE;
99 
100     pos = SendMessageW(hDlgCtrl, LB_FINDSTRING, 3, (LPARAM)Settings.szDefaultOS);
101     if (pos != LB_ERR)
102     {
103        Settings.szDefaultPos = pos;
104        SendMessage(hDlgCtrl, LB_SETCURSEL, pos, 0);
105     }
106 
107     SetDlgItemInt(hDlg, IDC_TXT_BOOT_TIMEOUT, Settings.TimeOut, FALSE);
108     if (Settings.OSConfigurationCount < 2)
109     {
110         EnableWindow(GetDlgItem(hDlg, IDC_BTN_SET_DEFAULT_BOOT), FALSE);
111         EnableWindow(GetDlgItem(hDlg, IDC_BTN_MOVE_UP_BOOT_OPTION), FALSE);
112         EnableWindow(GetDlgItem(hDlg, IDC_BTN_MOVE_DOWN_BOOT_OPTION), FALSE);
113     }
114     return TRUE;
115 }
116 
117 static BOOL
118 InitializeFreeLDRDialog(HWND hDlg)
119 {
120     WCHAR winDir[PATH_MAX];
121     WCHAR* ptr = NULL;
122 
123     GetWindowsDirectoryW(winDir, PATH_MAX);
124     ptr = wcschr(winDir, L'\\');
125     if (ptr == NULL)
126     {
127         return FALSE;
128     }
129     ptr[1] = L'\0';
130     return LoadBootIni(winDir, hDlg);
131 }
132 
133 INT_PTR CALLBACK
134 FreeLdrPageWndProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
135 {
136     LRESULT pos;
137 
138     switch (message) {
139     case WM_INITDIALOG:
140         hFreeLdrDialog = hDlg;
141         SetWindowPos(hDlg, NULL, 10, 32, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOSIZE | SWP_NOZORDER);
142         InitializeFreeLDRDialog(hDlg);
143         return TRUE;
144     case WM_COMMAND:
145         switch(HIWORD(wParam))
146         {
147             case LBN_SELCHANGE:
148                 pos = SendMessage((HWND)lParam, LB_GETCURSEL, 0, 0);
149                 if (pos != LB_ERR)
150                 {
151                     LPARAM res = SendMessage((HWND)lParam, LB_GETITEMDATA, pos, 0);
152                     if (!res) /* line is not a default one */
153                         SendMessage((HWND)lParam, LB_SETCURSEL, Settings.szDefaultPos, 0);
154                     else
155                         Settings.szDefaultPos = pos;
156 
157 
158                 }
159             break;
160         }
161     }
162     return 0;
163 }
164