Reactos
at master 280 lines 14 kB view raw
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 14COMMAND cmds[] = 15{ 16 {L"ACTIVE", NULL, NULL, active_main, IDS_HELP_ACTIVE, MSG_COMMAND_ACTIVE}, 17// {L"ADD", NULL, NULL, add_main, IDS_HELP_ADD, MSG_COMMAND_ADD}, 18 {L"ASSIGN", NULL, NULL, assign_main, IDS_HELP_ASSIGN, MSG_COMMAND_ASSIGN}, 19// {L"ATTACH", NULL, NULL, attach_main, IDS_HELP_ATTACH, MSG_COMMAND_ATTACH}, 20// {L"ATTRIBUTES", NULL, NULL, attributes_main, IDS_HELP_ATTRIBUTES, MSG_COMMAND_ATTRIBUTES}, 21 {L"AUTOMOUNT", NULL, NULL, automount_main, IDS_HELP_AUTOMOUNT, MSG_COMMAND_AUTOMOUNT}, 22// {L"BREAK", NULL, NULL, break_main, IDS_HELP_BREAK, MSG_COMMAND_BREAK}, 23 {L"CLEAN", NULL, NULL, clean_main, IDS_HELP_CLEAN, MSG_COMMAND_CLEAN}, 24// {L"COMPACT", NULL, NULL, compact_main, IDS_HELP_COMPACT, MSG_COMMAND_COMPACT}, 25 26 {L"CONVERT", NULL, NULL, NULL, IDS_HELP_CONVERT, MSG_NONE}, 27 {L"CONVERT", L"GPT", NULL, ConvertGPT, IDS_HELP_CONVERT_GPT, MSG_COMMAND_CONVERT_GPT}, 28 {L"CONVERT", L"MBR", NULL, ConvertMBR, IDS_HELP_CONVERT_MBR, MSG_COMMAND_CONVERT_MBR}, 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 */ 107EXIT_CODE 108InterpretCmd( 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 EXIT_SUCCESS; 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 EXIT_EXIT; 125 126 if (_wcsicmp(argv[0], L"rem") == 0) 127 return EXIT_SUCCESS; 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 EXIT_SUCCESS; 175} 176 177 178/* 179 * InterpretScript(char *line): 180 * The main function used for when reading commands from scripts. 181 */ 182EXIT_CODE 183InterpretScript( 184 _In_ PWSTR input_line) 185{ 186 PWSTR args_vector[MAX_ARGS_COUNT]; 187 INT args_count = 0; 188 BOOL bWhiteSpace = TRUE; 189 BOOL bQuote = FALSE; 190 PWSTR ptr; 191 192 memset(args_vector, 0, sizeof(args_vector)); 193 194 bQuote = FALSE; 195 ptr = input_line; 196 while (*ptr != 0) 197 { 198 if (*ptr == L'"') 199 bQuote = !bQuote; 200 201 if ((iswspace(*ptr) && (bQuote == FALSE))|| *ptr == L'\n') 202 { 203 *ptr = 0; 204 bWhiteSpace = TRUE; 205 } 206 else 207 { 208 if ((bWhiteSpace != FALSE) && (bQuote == FALSE) && (args_count < MAX_ARGS_COUNT)) 209 { 210 args_vector[args_count] = ptr; 211 args_count++; 212 } 213 214 bWhiteSpace = FALSE; 215 } 216 217 ptr++; 218 } 219 220 /* sends the string to find the command */ 221 return InterpretCmd(args_count, args_vector); 222} 223 224 225/* 226 * InterpretMain(): 227 * Contents for the main program loop as it reads each line, and then 228 * it sends the string to interpret_line, where it determines what 229 * command to use. 230 */ 231VOID 232InterpretMain(VOID) 233{ 234 WCHAR input_line[MAX_STRING_SIZE]; 235 LPWSTR args_vector[MAX_ARGS_COUNT]; 236 INT args_count = 0; 237 BOOL bWhiteSpace = TRUE; 238 BOOL bQuote = FALSE; 239 EXIT_CODE ExitCode = EXIT_SUCCESS; 240 LPWSTR ptr; 241 242 while (ExitCode != EXIT_EXIT) 243 { 244 args_count = 0; 245 memset(args_vector, 0, sizeof(args_vector)); 246 247 /* Shown just before the input where the user places commands */ 248 ConResPuts(StdOut, IDS_APP_PROMPT); 249 250 /* Get input from the user. */ 251 fgetws(input_line, MAX_STRING_SIZE, stdin); 252 253 bQuote = FALSE; 254 ptr = input_line; 255 while (*ptr != 0) 256 { 257 if (*ptr == L'"') 258 bQuote = !bQuote; 259 260 if ((iswspace(*ptr) && (bQuote == FALSE))|| *ptr == L'\n') 261 { 262 *ptr = 0; 263 bWhiteSpace = TRUE; 264 } 265 else 266 { 267 if ((bWhiteSpace != FALSE) && (bQuote == FALSE) && (args_count < MAX_ARGS_COUNT)) 268 { 269 args_vector[args_count] = ptr; 270 args_count++; 271 } 272 bWhiteSpace = FALSE; 273 } 274 ptr++; 275 } 276 277 /* Send the string to find the command */ 278 ExitCode = InterpretCmd(args_count, args_vector); 279 } 280}