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