1 /*
2  * PROJECT:     ReactOS Applications
3  * LICENSE:     LGPL - See COPYING in the top level directory
4  * FILE:        base/applications/msconfig_new/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  *              Copyright 2011-2012 Hermes BELUSCA - MAITO <hermes.belusca@sfr.fr>
9  */
10 
11 #include "precomp.h"
12 #include <share.h>
13 
14 #include <wingdi.h>
15 #include "comctl32supp.h"
16 
17 #include "utils.h"
18 
19 static HWND hFreeLdrPage;
20 
21 LPCWSTR lpszFreeLdrIni = L"%SystemDrive%\\freeldr.ini";
22 LPCWSTR lpszBootIni    = L"%SystemDrive%\\boot.ini";
23 
24 typedef struct _FREELDR_SETTINGS
25 {
26     ULONG TimeOut;
27     WCHAR szDefaultOS[512];
28     ULONG szDefaultPos;
29     ULONG OSConfigurationCount;
30     BOOL  UseBootIni;
31 } FREELDR_SETTINGS;
32 
33 static FREELDR_SETTINGS Settings = { 0, {0}, 0, 0, FALSE };
34 
35 static BOOL
36 LoadIniFile(HWND hDlg,
37             LPCWSTR lpszIniFile)
38 {
39     DWORD  dwNumOfChars;
40     LPWSTR lpszFileName;
41     FILE*  file;
42 
43     WCHAR szBuffer[512];
44     HWND hDlgCtrl;
45     SIZE_T length;
46     LRESULT pos;
47 
48     SIZE size;
49     LONG horzExt;
50 
51     HDC hDC;
52     HFONT hFont, hOldFont;
53 
54     /*
55      * Open for read + write (without file creation if it didn't already exist)
56      * of a read-only text stream.
57      */
58     dwNumOfChars = ExpandEnvironmentStringsW(lpszIniFile, NULL, 0);
59     lpszFileName = (LPWSTR)MemAlloc(0, dwNumOfChars * sizeof(WCHAR));
60     ExpandEnvironmentStringsW(lpszIniFile, lpszFileName, dwNumOfChars);
61 
62     file = _wfsopen(lpszFileName, L"rt", _SH_DENYWR); // r+t <-- read write text ; rt <-- read text
63     MemFree(lpszFileName);
64 
65     if (!file) return FALSE;
66 
67     hDlgCtrl = GetDlgItem(hDlg, IDC_LIST_BOX);
68 
69     hDC      = GetDC(hDlgCtrl);
70     hFont    = (HFONT)SendMessageW(hDlgCtrl, WM_GETFONT, 0, 0);
71     hOldFont = (HFONT)SelectObject(hDC, hFont);
72 
73     while (!feof(file) && fgetws(szBuffer, ARRAYSIZE(szBuffer), file))
74     {
75         length = wcslen(szBuffer);
76         if (length > 1)
77         {
78             /* Remove \r\n */
79             szBuffer[length-1] = szBuffer[length] = L'\0';
80 
81             pos = ListBox_AddString(hDlgCtrl, szBuffer);
82 
83             GetTextExtentPoint32W(hDC, szBuffer, (int)wcslen(szBuffer), &size);
84             horzExt = max((LONG)ListBox_GetHorizontalExtent(hDlgCtrl), size.cx + 5); // 5 to have a little room between the text and the end of the list box.
85             ListBox_SetHorizontalExtent(hDlgCtrl, horzExt);
86 
87             if (szBuffer[0] == L'[')
88                 continue;
89 
90             if (!_wcsnicmp(szBuffer, L"timeout=", 8))
91             {
92                 Settings.TimeOut = _wtoi(&szBuffer[8]);
93                 continue;
94             }
95 
96             if (!_wcsnicmp(szBuffer, L"default=", 8))
97             {
98                 wcscpy(Settings.szDefaultOS, &szBuffer[8]);
99                 continue;
100             }
101             if (pos != LB_ERR)
102                 ListBox_SetItemData(hDlgCtrl, pos, 1); // indicate that this item is a boot entry
103 
104             Settings.OSConfigurationCount++;
105         }
106     }
107 
108     SelectObject(hDC, hOldFont);
109     ReleaseDC(hDlgCtrl, hDC);
110 
111     fclose(file);
112     Settings.UseBootIni = TRUE;
113 
114     /*
115      * Start to search for the string at the "operating systems" section
116      * (after the "boot loader" section, which takes 3 lines in the .INI file).
117      */
118     pos = ListBox_FindString(hDlgCtrl, 3, Settings.szDefaultOS);
119     if (pos != LB_ERR)
120     {
121         Settings.szDefaultPos = (ULONG)pos;
122         ListBox_SetCurSel(hDlgCtrl, pos);
123         // SendMessageW(hDlgCtrl, WM_VSCROLL, SB_LINEDOWN, 0); // Or use SetScroll...()
124     }
125 
126     SetDlgItemInt(hDlg, IDC_TXT_BOOT_TIMEOUT, Settings.TimeOut, FALSE);
127     if (Settings.OSConfigurationCount < 2)
128     {
129         EnableWindow(GetDlgItem(hDlg, IDC_BTN_SET_DEFAULT_BOOT), FALSE);
130         EnableWindow(GetDlgItem(hDlg, IDC_BTN_MOVE_UP_BOOT_OPTION), FALSE);
131         EnableWindow(GetDlgItem(hDlg, IDC_BTN_MOVE_DOWN_BOOT_OPTION), FALSE);
132     }
133 
134     return TRUE;
135 }
136 
137 INT_PTR CALLBACK
138 FreeLdrPageWndProc(HWND   hDlg,
139                    UINT   message,
140                    WPARAM wParam,
141                    LPARAM lParam)
142 {
143     switch (message)
144     {
145         case WM_INITDIALOG:
146         {
147             LPPROPSHEETPAGEW psp = (LPPROPSHEETPAGEW)lParam;
148 
149             hFreeLdrPage = hDlg;
150             LoadIniFile(hDlg, (LPWSTR)(psp->lParam));
151             return TRUE;
152         }
153 
154         case WM_COMMAND:
155         {
156             switch (LOWORD(wParam))
157             {
158                 case IDC_BTN_ADVANCED_OPTIONS:
159                     // DialogBoxW(hInst, MAKEINTRESOURCEW(IDD_FREELDR_ADVANCED_DIALOG), hDlg /* hMainWnd */, NULL /*FileExtractDialogWndProc*/);
160                     break;
161 
162                 // default:
163                 //     return FALSE;
164             }
165 
166             switch (HIWORD(wParam))
167             {
168                 case LBN_SELCHANGE:
169                 {
170                     HWND hWnd = (HWND)lParam;
171                     LRESULT pos;
172 
173                     pos = ListBox_GetCurSel(hWnd);
174                     if (pos != LB_ERR)
175                     {
176                         if (!ListBox_GetItemData(hWnd, pos)) // Line is not a default one
177                             ListBox_SetCurSel(hWnd, Settings.szDefaultPos);
178                         else
179                             Settings.szDefaultPos = (ULONG)pos;
180 
181                         // SendMessageW((HWND)lParam, WM_VSCROLL, SB_LINEDOWN, 0); // Or use SetScroll...()
182                     }
183 
184                     return TRUE;
185                 }
186             }
187         }
188 
189         default:
190             return FALSE;
191     }
192 
193     // return FALSE;
194 }
195