0b190d4a8bf839eff7e23beffe52d02d5752866a
[reactos.git] / base / setup / usetup / fslist.c
1 /*
2 * ReactOS kernel
3 * Copyright (C) 2003 ReactOS Team
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19 /*
20 * COPYRIGHT: See COPYING in the top level directory
21 * PROJECT: ReactOS text-mode setup
22 * FILE: base/setup/usetup/fslist.c
23 * PURPOSE: Filesystem list functions
24 * PROGRAMMER: Eric Kohl
25 * Casper S. Hornstrup (chorns@users.sourceforge.net)
26 */
27
28 #include "usetup.h"
29
30 #define NDEBUG
31 #include <debug.h>
32
33 /* FUNCTIONS ****************************************************************/
34
35 VOID
36 AddProvider(
37 IN OUT PFILE_SYSTEM_LIST List,
38 IN LPCWSTR FileSystemName,
39 IN FORMATEX FormatFunc,
40 IN CHKDSKEX ChkdskFunc)
41 {
42 PFILE_SYSTEM_ITEM Item;
43
44 Item = (PFILE_SYSTEM_ITEM)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_ITEM));
45 if (!Item)
46 return;
47
48 Item->FileSystemName = FileSystemName;
49 Item->FormatFunc = FormatFunc;
50 Item->ChkdskFunc = ChkdskFunc;
51 Item->QuickFormat = TRUE;
52 InsertTailList(&List->ListHead, &Item->ListEntry);
53
54 if (!FormatFunc)
55 return;
56
57 Item = (PFILE_SYSTEM_ITEM)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_ITEM));
58 if (!Item)
59 return;
60
61 Item->FileSystemName = FileSystemName;
62 Item->FormatFunc = FormatFunc;
63 Item->ChkdskFunc = ChkdskFunc;
64 Item->QuickFormat = FALSE;
65 InsertTailList(&List->ListHead, &Item->ListEntry);
66 }
67
68
69 PFILE_SYSTEM_ITEM
70 GetFileSystemByName(
71 IN PFILE_SYSTEM_LIST List,
72 IN LPWSTR FileSystemName)
73 {
74 PLIST_ENTRY ListEntry;
75 PFILE_SYSTEM_ITEM Item;
76
77 ListEntry = List->ListHead.Flink;
78 while (ListEntry != &List->ListHead)
79 {
80 Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
81 if (Item->FileSystemName && wcsicmp(FileSystemName, Item->FileSystemName) == 0)
82 return Item;
83
84 ListEntry = ListEntry->Flink;
85 }
86
87 return NULL;
88 }
89
90
91 PFILE_SYSTEM_ITEM
92 GetFileSystem(
93 IN PFILE_SYSTEM_LIST FileSystemList,
94 IN struct _PARTENTRY* PartEntry)
95 {
96 PFILE_SYSTEM_ITEM CurrentFileSystem;
97 LPWSTR FileSystemName = NULL;
98
99 CurrentFileSystem = PartEntry->FileSystem;
100
101 /* We have a file system, return it */
102 if (CurrentFileSystem != NULL && CurrentFileSystem->FileSystemName != NULL)
103 return CurrentFileSystem;
104
105 DPRINT1("File system not found, try to guess one...\n");
106
107 CurrentFileSystem = NULL;
108
109 /*
110 * We don't have one...
111 *
112 * Try to infer a preferred file system for this partition, given its ID.
113 *
114 * WARNING: This is partly a hack, since partitions with the same ID can
115 * be formatted with different file systems: for example, usual Linux
116 * partitions that are formatted in EXT2/3/4, ReiserFS, etc... have the
117 * same partition ID 0x83.
118 *
119 * The proper fix is to make a function that detects the existing FS
120 * from a given partition (not based on the partition ID).
121 * On the contrary, for unformatted partitions with a given ID, the
122 * following code is OK.
123 */
124 if ((PartEntry->PartitionType == PARTITION_FAT_12) ||
125 (PartEntry->PartitionType == PARTITION_FAT_16) ||
126 (PartEntry->PartitionType == PARTITION_HUGE ) ||
127 (PartEntry->PartitionType == PARTITION_XINT13) ||
128 (PartEntry->PartitionType == PARTITION_FAT32 ) ||
129 (PartEntry->PartitionType == PARTITION_FAT32_XINT13))
130 {
131 FileSystemName = L"FAT";
132 }
133 else if (PartEntry->PartitionType == PARTITION_EXT2)
134 {
135 // WARNING: See the warning above.
136 FileSystemName = L"EXT2";
137 }
138 else if (PartEntry->PartitionType == PARTITION_IFS)
139 {
140 // WARNING: See the warning above.
141 FileSystemName = L"NTFS"; /* FIXME: Not quite correct! */
142 }
143
144 // HACK: WARNING: We cannot write on this FS yet!
145 if (PartEntry->PartitionType == PARTITION_EXT2 || PartEntry->PartitionType == PARTITION_IFS)
146 DPRINT1("Recognized file system %S that doesn't support write support yet!\n", FileSystemName);
147
148 DPRINT1("GetFileSystem -- PartitionType: 0x%02X ; FileSystemName (guessed): %S\n",
149 PartEntry->PartitionType, FileSystemName);
150
151 if (FileSystemName != NULL)
152 CurrentFileSystem = GetFileSystemByName(FileSystemList, FileSystemName);
153
154 return CurrentFileSystem;
155 }
156
157
158 PFILE_SYSTEM_LIST
159 CreateFileSystemList(
160 IN SHORT Left,
161 IN SHORT Top,
162 IN BOOLEAN ForceFormat,
163 IN LPCWSTR ForceFileSystem)
164 {
165 PFILE_SYSTEM_LIST List;
166 PFILE_SYSTEM_ITEM Item;
167 PLIST_ENTRY ListEntry;
168
169 List = (PFILE_SYSTEM_LIST)RtlAllocateHeap(ProcessHeap, 0, sizeof(FILE_SYSTEM_LIST));
170 if (List == NULL)
171 return NULL;
172
173 List->Left = Left;
174 List->Top = Top;
175 List->Selected = NULL;
176 InitializeListHead(&List->ListHead);
177
178 AddProvider(List, L"FAT", VfatFormat, VfatChkdsk);
179 #if 0
180 AddProvider(List, L"EXT2", Ext2Format, Ext2Chkdsk);
181 AddProvider(List, L"NTFS", NtfsFormat, NtfsChkdsk);
182 #endif
183
184 if (!ForceFormat)
185 {
186 /* Add 'Keep' provider */
187 AddProvider(List, NULL, NULL, NULL);
188 }
189
190 /* Search for ForceFileSystem in list */
191 ListEntry = List->ListHead.Flink;
192 while (ListEntry != &List->ListHead)
193 {
194 Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
195 if (Item->FileSystemName && wcscmp(ForceFileSystem, Item->FileSystemName) == 0)
196 {
197 List->Selected = Item;
198 break;
199 }
200 ListEntry = ListEntry->Flink;
201 }
202 if (!List->Selected)
203 List->Selected = CONTAINING_RECORD(List->ListHead.Flink, FILE_SYSTEM_ITEM, ListEntry);
204
205 return List;
206 }
207
208
209 VOID
210 DestroyFileSystemList(
211 IN PFILE_SYSTEM_LIST List)
212 {
213 PLIST_ENTRY ListEntry = List->ListHead.Flink;
214 PFILE_SYSTEM_ITEM Item;
215 PLIST_ENTRY Next;
216
217 while (ListEntry != &List->ListHead)
218 {
219 Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
220 Next = ListEntry->Flink;
221
222 RtlFreeHeap(ProcessHeap, 0, Item);
223
224 ListEntry = Next;
225 }
226 RtlFreeHeap(ProcessHeap, 0, List);
227 }
228
229
230 VOID
231 DrawFileSystemList(
232 IN PFILE_SYSTEM_LIST List)
233 {
234 PLIST_ENTRY ListEntry;
235 PFILE_SYSTEM_ITEM Item;
236 COORD coPos;
237 DWORD Written;
238 ULONG Index = 0;
239 CHAR Buffer[128];
240
241 ListEntry = List->ListHead.Flink;
242 while (ListEntry != &List->ListHead)
243 {
244 Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
245
246 coPos.X = List->Left;
247 coPos.Y = List->Top + (SHORT)Index;
248 FillConsoleOutputAttribute(StdOutput,
249 FOREGROUND_WHITE | BACKGROUND_BLUE,
250 sizeof(Buffer),
251 coPos,
252 &Written);
253 FillConsoleOutputCharacterA(StdOutput,
254 ' ',
255 sizeof(Buffer),
256 coPos,
257 &Written);
258
259 if (Item->FileSystemName)
260 {
261 if (Item->QuickFormat)
262 snprintf(Buffer, sizeof(Buffer), MUIGetString(STRING_FORMATDISK1), Item->FileSystemName);
263 else
264 snprintf(Buffer, sizeof(Buffer), MUIGetString(STRING_FORMATDISK2), Item->FileSystemName);
265 }
266 else
267 snprintf(Buffer, sizeof(Buffer), MUIGetString(STRING_KEEPFORMAT));
268
269 if (ListEntry == &List->Selected->ListEntry)
270 CONSOLE_SetInvertedTextXY(List->Left,
271 List->Top + (SHORT)Index,
272 Buffer);
273 else
274 CONSOLE_SetTextXY(List->Left,
275 List->Top + (SHORT)Index,
276 Buffer);
277 Index++;
278 ListEntry = ListEntry->Flink;
279 }
280 }
281
282
283 VOID
284 ScrollDownFileSystemList(
285 IN PFILE_SYSTEM_LIST List)
286 {
287 if (List->Selected->ListEntry.Flink != &List->ListHead)
288 {
289 List->Selected = CONTAINING_RECORD(List->Selected->ListEntry.Flink, FILE_SYSTEM_ITEM, ListEntry);
290 DrawFileSystemList(List);
291 }
292 }
293
294
295 VOID
296 ScrollUpFileSystemList(
297 IN PFILE_SYSTEM_LIST List)
298 {
299 if (List->Selected->ListEntry.Blink != &List->ListHead)
300 {
301 List->Selected = CONTAINING_RECORD(List->Selected->ListEntry.Blink, FILE_SYSTEM_ITEM, ListEntry);
302 DrawFileSystemList(List);
303 }
304 }
305
306 /* EOF */