1 /*
2 * PROJECT: ReactOS DiskPart
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: base/system/diskpart/interpreter.c
5 * PURPOSE: Reads the user input and then invokes the selected
6 * command by the user.
7 * PROGRAMMERS: Lee Schroeder
8 */
9
10 #include "diskpart.h"
11 #include "diskpart_msg.h"
12
13 BOOL exit_main(INT argc, LPWSTR *argv);
14 BOOL rem_main(INT argc, LPWSTR *argv);
15
16
17 COMMAND cmds[] =
18 {
19 {L"ACTIVE", NULL, NULL, active_main, IDS_HELP_ACTIVE, MSG_COMMAND_ACTIVE},
20 {L"ADD", NULL, NULL, add_main, IDS_HELP_ADD, MSG_COMMAND_ADD},
21 {L"ASSIGN", NULL, NULL, assign_main, IDS_HELP_ASSIGN, MSG_COMMAND_ASSIGN},
22 {L"ATTACH", NULL, NULL, attach_main, IDS_HELP_ATTACH, MSG_COMMAND_ATTACH},
23 {L"ATTRIBUTES", NULL, NULL, attributes_main, IDS_HELP_ATTRIBUTES, MSG_COMMAND_ATTRIBUTES},
24 {L"AUTOMOUNT", NULL, NULL, automount_main, IDS_HELP_AUTOMOUNT, MSG_COMMAND_AUTOMOUNT},
25 {L"BREAK", NULL, NULL, break_main, IDS_HELP_BREAK, MSG_COMMAND_BREAK},
26 {L"CLEAN", NULL, NULL, clean_main, IDS_HELP_CLEAN, MSG_COMMAND_CLEAN},
27 {L"COMPACT", NULL, NULL, compact_main, IDS_HELP_COMPACT, MSG_COMMAND_COMPACT},
28 {L"CONVERT", NULL, NULL, convert_main, IDS_HELP_CONVERT, MSG_COMMAND_CONVERT},
29
30 {L"CREATE", NULL, NULL, NULL, IDS_HELP_CREATE, MSG_NONE},
31 {L"CREATE", L"PARTITION", NULL, NULL, IDS_HELP_CREATE_PARTITION, MSG_NONE},
32 // {L"CREATE", L"PARTITION", L"EFI", CreateEfiPartition, IDS_HELP_CREATE_PARTITION_EFI, MSG_COMMAND_CREATE_PARTITION_EFI},
33 {L"CREATE", L"PARTITION", L"EXTENDED", CreateExtendedPartition, IDS_HELP_CREATE_PARTITION_EXTENDED, MSG_COMMAND_CREATE_PARTITION_EXTENDED},
34 {L"CREATE", L"PARTITION", L"LOGICAL", CreateLogicalPartition, IDS_HELP_CREATE_PARTITION_LOGICAL, MSG_COMMAND_CREATE_PARTITION_LOGICAL},
35 // {L"CREATE", L"PARTITION", L"MSR", CreateMsrPartition, IDS_HELP_CREATE_PARTITION_MSR, MSG_COMMAND_CREATE_PARTITION_MSR},
36 {L"CREATE", L"PARTITION", L"PRIMARY", CreatePrimaryPartition, IDS_HELP_CREATE_PARTITION_PRIMARY, MSG_COMMAND_CREATE_PARTITION_PRIMARY},
37 {L"CREATE", L"VOLUME", NULL, NULL, IDS_HELP_CREATE_VOLUME, MSG_NONE},
38 {L"CREATE", L"VDISK", NULL, NULL, IDS_HELP_CREATE_VDISK, MSG_NONE},
39
40 {L"DELETE", NULL, NULL, NULL, IDS_HELP_DELETE, MSG_NONE},
41 {L"DELETE", L"DISK", NULL, DeleteDisk, IDS_HELP_DELETE_DISK, MSG_COMMAND_DELETE_DISK},
42 {L"DELETE", L"PARTITION", NULL, DeletePartition, IDS_HELP_DELETE_PARTITION, MSG_COMMAND_DELETE_PARTITION},
43 {L"DELETE", L"VOLUME", NULL, DeleteVolume, IDS_HELP_DELETE_VOLUME, MSG_COMMAND_DELETE_VOLUME},
44
45 {L"DETACH", NULL, NULL, detach_main, IDS_HELP_DETACH, MSG_COMMAND_DETACH},
46
47 {L"DETAIL", NULL, NULL, NULL, IDS_HELP_DETAIL, MSG_NONE},
48 {L"DETAIL", L"DISK", NULL, DetailDisk, IDS_HELP_DETAIL_DISK, MSG_COMMAND_DETAIL_DISK},
49 {L"DETAIL", L"PARTITION", NULL, DetailPartition, IDS_HELP_DETAIL_PARTITION, MSG_COMMAND_DETAIL_PARTITION},
50 {L"DETAIL", L"VOLUME", NULL, DetailVolume, IDS_HELP_DETAIL_VOLUME, MSG_COMMAND_DETAIL_VOLUME},
51
52 {L"DUMP", NULL, NULL, NULL, IDS_NONE, MSG_NONE},
53 {L"DUMP", L"DISK", NULL, DumpDisk, IDS_NONE, MSG_NONE},
54 {L"DUMP", L"PARTITION", NULL, DumpPartition, IDS_NONE, MSG_NONE},
55 {L"EXIT", NULL, NULL, NULL, IDS_HELP_EXIT, MSG_COMMAND_EXIT},
56
57 {L"EXPAND", NULL, NULL, expand_main, IDS_HELP_EXPAND, MSG_COMMAND_EXPAND},
58 {L"EXTEND", NULL, NULL, extend_main, IDS_HELP_EXTEND, MSG_COMMAND_EXTEND},
59 {L"FILESYSTEMS", NULL, NULL, filesystems_main, IDS_HELP_FILESYSTEMS, MSG_COMMAND_FILESYSTEMS},
60 {L"FORMAT", NULL, NULL, format_main, IDS_HELP_FORMAT, MSG_COMMAND_FORMAT},
61 {L"GPT", NULL, NULL, gpt_main, IDS_HELP_GPT, MSG_COMMAND_GPT},
62 {L"HELP", NULL, NULL, help_main, IDS_HELP_HELP, MSG_COMMAND_HELP},
63 {L"IMPORT", NULL, NULL, import_main, IDS_HELP_IMPORT, MSG_COMMAND_IMPORT},
64 {L"INACTIVE", NULL, NULL, inactive_main, IDS_HELP_INACTIVE, MSG_COMMAND_INACTIVE},
65
66 {L"LIST", NULL, NULL, NULL, IDS_HELP_LIST, MSG_NONE},
67 {L"LIST", L"DISK", NULL, ListDisk, IDS_HELP_LIST_DISK, MSG_COMMAND_LIST_DISK},
68 {L"LIST", L"PARTITION", NULL, ListPartition, IDS_HELP_LIST_PARTITION, MSG_COMMAND_LIST_PARTITION},
69 {L"LIST", L"VOLUME", NULL, ListVolume, IDS_HELP_LIST_VOLUME, MSG_COMMAND_LIST_VOLUME},
70 {L"LIST", L"VDISK", NULL, ListVirtualDisk, IDS_HELP_LIST_VDISK, MSG_COMMAND_LIST_VDISK},
71
72 {L"MERGE", NULL, NULL, merge_main, IDS_HELP_MERGE, MSG_COMMAND_MERGE},
73 {L"OFFLINE", NULL, NULL, offline_main, IDS_HELP_OFFLINE, MSG_COMMAND_OFFLINE},
74 {L"ONLINE", NULL, NULL, online_main, IDS_HELP_ONLINE, MSG_COMMAND_ONLINE},
75 {L"RECOVER", NULL, NULL, recover_main, IDS_HELP_RECOVER, MSG_COMMAND_RECOVER},
76 {L"REM", NULL, NULL, NULL, IDS_HELP_REM, MSG_COMMAND_REM},
77 {L"REMOVE", NULL, NULL, remove_main, IDS_HELP_REMOVE, MSG_COMMAND_REMOVE},
78 {L"REPAIR", NULL, NULL, repair_main, IDS_HELP_REPAIR, MSG_COMMAND_REPAIR},
79 {L"RESCAN", NULL, NULL, rescan_main, IDS_HELP_RESCAN, MSG_COMMAND_RESCAN},
80 {L"RETAIN", NULL, NULL, retain_main, IDS_HELP_RETAIN, MSG_COMMAND_RETAIN},
81 {L"SAN", NULL, NULL, san_main, IDS_HELP_SAN, MSG_COMMAND_SAN},
82
83 {L"SELECT", NULL, NULL, NULL, IDS_HELP_SELECT, MSG_NONE},
84 {L"SELECT", L"DISK", NULL, SelectDisk, IDS_HELP_SELECT_DISK, MSG_COMMAND_SELECT_DISK},
85 {L"SELECT", L"PARTITION", NULL, SelectPartition, IDS_HELP_SELECT_PARTITION, MSG_COMMAND_SELECT_PARTITION},
86 {L"SELECT", L"VOLUME", NULL, SelectVolume, IDS_HELP_SELECT_VOLUME, MSG_COMMAND_SELECT_VOLUME},
87 // {L"SELECT", L"VDISK", NULL, SelectVirtualDisk, IDS_HELP_SELECT_VDISK, MSG_COMMAND_SELECT_VDISK},
88
89 {L"SET", NULL, NULL, setid_main, IDS_HELP_SETID, MSG_COMMAND_SETID},
90 {L"SETID", NULL, NULL, setid_main, IDS_HELP_SETID, MSG_COMMAND_SETID},
91 {L"SHRINK", NULL, NULL, shrink_main, IDS_HELP_SHRINK, MSG_COMMAND_SHRINK},
92
93 {L"UNIQUEID", NULL, NULL, NULL, IDS_HELP_UNIQUEID, MSG_NONE},
94 {L"UNIQUEID", L"DISK", NULL, UniqueIdDisk, IDS_HELP_UNIQUEID_DISK, MSG_COMMAND_UNIQUEID_DISK},
95
96 {NULL, NULL, NULL, NULL, IDS_NONE, MSG_NONE}
97 };
98
99
100 /* FUNCTIONS *****************************************************************/
101
102 /*
103 * InterpretCmd(char *cmd_line, char *arg_line):
104 * compares the command name to a list of available commands, and
105 * determines which function to invoke.
106 */
107 BOOL
InterpretCmd(int argc,LPWSTR * argv)108 InterpretCmd(
109 int argc,
110 LPWSTR *argv)
111 {
112 PCOMMAND cmdptr;
113 PCOMMAND cmdptr1 = NULL;
114 PCOMMAND cmdptr2 = NULL;
115 PCOMMAND cmdptr3 = NULL;
116
117 /* If no args provided */
118 if (argc < 1)
119 return TRUE;
120
121 /* First, determine if the user wants to exit
122 or to use a comment */
123 if (_wcsicmp(argv[0], L"exit") == 0)
124 return FALSE;
125
126 if (_wcsicmp(argv[0], L"rem") == 0)
127 return TRUE;
128
129 /* Scan internal command table */
130 for (cmdptr = cmds; cmdptr->cmd1; cmdptr++)
131 {
132 if ((cmdptr1 == NULL) &&
133 (cmdptr->cmd1 != NULL) && (_wcsicmp(argv[0], cmdptr->cmd1) == 0))
134 cmdptr1 = cmdptr;
135
136 if ((cmdptr2 == NULL) &&
137 (argc >= 2) &&
138 (cmdptr->cmd1 != NULL) && (_wcsicmp(argv[0], cmdptr->cmd1) == 0) &&
139 (cmdptr->cmd2 != NULL) && (_wcsicmp(argv[1], cmdptr->cmd2) == 0))
140 cmdptr2 = cmdptr;
141
142 if ((cmdptr3 == NULL) &&
143 (argc >= 3) &&
144 (cmdptr->cmd1 != NULL) && (_wcsicmp(argv[0], cmdptr->cmd1) == 0) &&
145 (cmdptr->cmd2 != NULL) && (_wcsicmp(argv[1], cmdptr->cmd2) == 0) &&
146 (cmdptr->cmd3 != NULL) && (_wcsicmp(argv[2], cmdptr->cmd3) == 0))
147 cmdptr3 = cmdptr;
148 }
149
150 if (cmdptr3 != NULL)
151 {
152 if (cmdptr3->func == NULL)
153 return HelpCommand(cmdptr3);
154 else
155 return cmdptr3->func(argc, argv);
156 }
157 else if (cmdptr2 != NULL)
158 {
159 if (cmdptr2->func == NULL)
160 return HelpCommand(cmdptr2);
161 else
162 return cmdptr2->func(argc, argv);
163 }
164 else if (cmdptr1 != NULL)
165 {
166 if (cmdptr1->func == NULL)
167 return HelpCommand(cmdptr1);
168 else
169 return cmdptr1->func(argc, argv);
170 }
171
172 HelpCommandList();
173
174 return TRUE;
175 }
176
177
178 /*
179 * InterpretScript(char *line):
180 * The main function used for when reading commands from scripts.
181 */
182 BOOL
InterpretScript(LPWSTR input_line)183 InterpretScript(LPWSTR input_line)
184 {
185 LPWSTR args_vector[MAX_ARGS_COUNT];
186 INT args_count = 0;
187 BOOL bWhiteSpace = TRUE;
188 BOOL bQuote = FALSE;
189 LPWSTR ptr;
190
191 memset(args_vector, 0, sizeof(args_vector));
192
193 bQuote = FALSE;
194 ptr = input_line;
195 while (*ptr != 0)
196 {
197 if (*ptr == L'"')
198 bQuote = !bQuote;
199
200 if ((iswspace(*ptr) && (bQuote == FALSE))|| *ptr == L'\n')
201 {
202 *ptr = 0;
203 bWhiteSpace = TRUE;
204 }
205 else
206 {
207 if ((bWhiteSpace != FALSE) && (bQuote == FALSE) && (args_count < MAX_ARGS_COUNT))
208 {
209 args_vector[args_count] = ptr;
210 args_count++;
211 }
212
213 bWhiteSpace = FALSE;
214 }
215
216 ptr++;
217 }
218
219 /* sends the string to find the command */
220 return InterpretCmd(args_count, args_vector);
221 }
222
223
224 /*
225 * InterpretMain():
226 * Contents for the main program loop as it reads each line, and then
227 * it sends the string to interpret_line, where it determines what
228 * command to use.
229 */
230 VOID
InterpretMain(VOID)231 InterpretMain(VOID)
232 {
233 WCHAR input_line[MAX_STRING_SIZE];
234 LPWSTR args_vector[MAX_ARGS_COUNT];
235 INT args_count = 0;
236 BOOL bWhiteSpace = TRUE;
237 BOOL bQuote = FALSE;
238 BOOL bRun = TRUE;
239 LPWSTR ptr;
240
241 while (bRun != FALSE)
242 {
243 args_count = 0;
244 memset(args_vector, 0, sizeof(args_vector));
245
246 /* Shown just before the input where the user places commands */
247 ConResPuts(StdOut, IDS_APP_PROMPT);
248
249 /* Get input from the user. */
250 fgetws(input_line, MAX_STRING_SIZE, stdin);
251
252 bQuote = FALSE;
253 ptr = input_line;
254 while (*ptr != 0)
255 {
256 if (*ptr == L'"')
257 bQuote = !bQuote;
258
259 if ((iswspace(*ptr) && (bQuote == FALSE))|| *ptr == L'\n')
260 {
261 *ptr = 0;
262 bWhiteSpace = TRUE;
263 }
264 else
265 {
266 if ((bWhiteSpace != FALSE) && (bQuote == FALSE) && (args_count < MAX_ARGS_COUNT))
267 {
268 args_vector[args_count] = ptr;
269 args_count++;
270 }
271 bWhiteSpace = FALSE;
272 }
273 ptr++;
274 }
275
276 /* Send the string to find the command */
277 bRun = InterpretCmd(args_count, args_vector);
278 }
279 }
280