99fe2f8460cc6a73c3648dddea1d0b853265a32f
[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 FS_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 HOST_CreateFileSystemList(List);
179
180 if (!ForceFormat)
181 {
182 /* Add 'Keep' provider */
183 FS_AddProvider(List, NULL, NULL, NULL);
184 }
185
186 /* Search for ForceFileSystem in list */
187 ListEntry = List->ListHead.Flink;
188 while (ListEntry != &List->ListHead)
189 {
190 Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
191 if (Item->FileSystemName && wcscmp(ForceFileSystem, Item->FileSystemName) == 0)
192 {
193 List->Selected = Item;
194 break;
195 }
196 ListEntry = ListEntry->Flink;
197 }
198 if (!List->Selected)
199 List->Selected = CONTAINING_RECORD(List->ListHead.Flink, FILE_SYSTEM_ITEM, ListEntry);
200
201 return List;
202 }
203
204
205 VOID
206 DestroyFileSystemList(
207 IN PFILE_SYSTEM_LIST List)
208 {
209 PLIST_ENTRY ListEntry = List->ListHead.Flink;
210 PFILE_SYSTEM_ITEM Item;
211 PLIST_ENTRY Next;
212
213 while (ListEntry != &List->ListHead)
214 {
215 Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
216 Next = ListEntry->Flink;
217
218 RtlFreeHeap(ProcessHeap, 0, Item);
219
220 ListEntry = Next;
221 }
222 RtlFreeHeap(ProcessHeap, 0, List);
223 }
224
225
226 VOID
227 DrawFileSystemList(
228 IN PFILE_SYSTEM_LIST List)
229 {
230 PLIST_ENTRY ListEntry;
231 PFILE_SYSTEM_ITEM Item;
232 COORD coPos;
233 DWORD Written;
234 ULONG Index = 0;
235 CHAR Buffer[128];
236
237 ListEntry = List->ListHead.Flink;
238 while (ListEntry != &List->ListHead)
239 {
240 Item = CONTAINING_RECORD(ListEntry, FILE_SYSTEM_ITEM, ListEntry);
241
242 coPos.X = List->Left;
243 coPos.Y = List->Top + (SHORT)Index;
244 FillConsoleOutputAttribute(StdOutput,
245 FOREGROUND_WHITE | BACKGROUND_BLUE,
246 sizeof(Buffer),
247 coPos,
248 &Written);
249 FillConsoleOutputCharacterA(StdOutput,
250 ' ',
251 sizeof(Buffer),
252 coPos,
253 &Written);
254
255 if (Item->FileSystemName)
256 {
257 if (Item->QuickFormat)
258 snprintf(Buffer, sizeof(Buffer), MUIGetString(STRING_FORMATDISK1), Item->FileSystemName);
259 else
260 snprintf(Buffer, sizeof(Buffer), MUIGetString(STRING_FORMATDISK2), Item->FileSystemName);
261 }
262 else
263 snprintf(Buffer, sizeof(Buffer), MUIGetString(STRING_KEEPFORMAT));
264
265 if (ListEntry == &List->Selected->ListEntry)
266 CONSOLE_SetInvertedTextXY(List->Left,
267 List->Top + (SHORT)Index,
268 Buffer);
269 else
270 CONSOLE_SetTextXY(List->Left,
271 List->Top + (SHORT)Index,
272 Buffer);
273 Index++;
274 ListEntry = ListEntry->Flink;
275 }
276 }
277
278
279 VOID
280 ScrollDownFileSystemList(
281 IN PFILE_SYSTEM_LIST List)
282 {
283 if (List->Selected->ListEntry.Flink != &List->ListHead)
284 {
285 List->Selected = CONTAINING_RECORD(List->Selected->ListEntry.Flink, FILE_SYSTEM_ITEM, ListEntry);
286 DrawFileSystemList(List);
287 }
288 }
289
290
291 VOID
292 ScrollUpFileSystemList(
293 IN PFILE_SYSTEM_LIST List)
294 {
295 if (List->Selected->ListEntry.Blink != &List->ListHead)
296 {
297 List->Selected = CONTAINING_RECORD(List->Selected->ListEntry.Blink, FILE_SYSTEM_ITEM, ListEntry);
298 DrawFileSystemList(List);
299 }
300 }
301
302 /* EOF */