xref: /reactos/base/system/diskpart/interpreter.c (revision d4a398fb)
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
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
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
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