From: Hugh McMaster Subject: [1/4] regsvr32: Implement new method of handling arguments/flags Message-Id: <9CB7F20010CADE479EB89B7DCEDFB642687E60AE60@VMBX112.ihostexchange.net> Date: Tue, 29 Apr 2014 02:02:25 -0400 This patch replaces the existing argument/flag handler in regsvr32.c (mostly repeated calls to strcasecmp) with a new handler based on a switch statement. This patch is the first of a series of four: 1. Implement new argument/flag handler. 2. Convert source to Unicode. 3. Add WriteFile() support if WriteConsoleW() fails. 4. Improve source comments (e.g. spelling, grammar, etc.) Thank you to Akihiro Sagawa for validating this patch series. From 91ae677b3515179ea3cf0bc2ea217bc72e5565f5 Mon Sep 17 00:00:00 2001 From: Hugh McMaster Date: Mon, 28 Apr 2014 15:28:19 +1000 Subject: regsvr32-command-handler --- programs/regsvr32/regsvr32.c | 123 ++++++++++++++++++++++++------------------- 1 file changed, 70 insertions(+), 53 deletions(-) diff --git a/programs/regsvr32/regsvr32.c b/programs/regsvr32/regsvr32.c index 624acd6..d2766a7 100644 --- a/programs/regsvr32/regsvr32.c +++ b/programs/regsvr32/regsvr32.c @@ -51,6 +51,7 @@ #include "config.h" #include "wine/port.h" +#include #include #include #include @@ -202,6 +203,47 @@ static int InstallDll(BOOL install, char *strDll, WCHAR *command_line) return 0; } +static WCHAR *parse_cmdline(char *command_line) +{ + static WCHAR EmptyLine[1] = {0}; + WCHAR *wsCommandLine = NULL; + + if (command_line[0] == ':' && command_line[1]) + { + int len = strlen(command_line); + command_line++; + len--; + + /* remove double quotes */ + if (command_line[0] == '"') + { + command_line++; + len--; + if (command_line[0]) + { + len--; + command_line[len] = 0; + } + } + if (command_line[0]) + { + len = MultiByteToWideChar(CP_ACP, 0, command_line, -1, NULL, 0); + wsCommandLine = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); + if (wsCommandLine) + MultiByteToWideChar(CP_ACP, 0, command_line, -1, wsCommandLine, len); + } + else + { + wsCommandLine = EmptyLine; + } + } + else + { + wsCommandLine = EmptyLine; + } + return wsCommandLine; +} + int main(int argc, char* argv[]) { int i; @@ -210,7 +252,6 @@ int main(int argc, char* argv[]) BOOL Unregister = FALSE; BOOL DllFound = FALSE; WCHAR* wsCommandLine = NULL; - WCHAR EmptyLine[1] = {0}; OleInitialize(NULL); @@ -221,62 +262,38 @@ int main(int argc, char* argv[]) */ for(i = 1; i < argc; i++) { - if ((!strcasecmp(argv[i], "/u")) ||(!strcasecmp(argv[i], "-u"))) - Unregister = TRUE; - else if ((!strcasecmp(argv[i], "/s"))||(!strcasecmp(argv[i], "-s"))) - Silent = TRUE; - else if ((!strncasecmp(argv[i], "/i", strlen("/i")))||(!strncasecmp(argv[i], "-i", strlen("-i")))) + if (argv[i][0] == '/' || argv[i][0] == '-') { - CHAR* command_line = argv[i] + strlen("/i"); - - CallInstall = TRUE; - if (command_line[0] == ':' && command_line[1]) + if (!argv[i][1] || (argv[i][2] != '\0' && argv[i][2] != ':')) { - int len = strlen(command_line); - - command_line++; - len--; - /* remove double quotes */ - if (command_line[0] == '"') - { - command_line++; - len--; - if (command_line[0]) - { - len--; - command_line[len] = 0; - } - } - if (command_line[0]) - { - len = MultiByteToWideChar(CP_ACP, 0, command_line, -1, - NULL, 0); - wsCommandLine = HeapAlloc(GetProcessHeap(), 0, - len * sizeof(WCHAR)); - if (wsCommandLine) - MultiByteToWideChar(CP_ACP, 0, command_line, -1, - wsCommandLine, len); - } - else - { - wsCommandLine = EmptyLine; - } + output_write(STRING_UNRECOGNIZED_SWITCH, argv[i]); + output_write(STRING_USAGE); + return 1; } - else + switch (tolower(argv[i][1])) { - wsCommandLine = EmptyLine; + case 'u': + Unregister = TRUE; + break; + case 's': + Silent = TRUE; + break; + case 'i': + CallInstall = TRUE; + wsCommandLine = parse_cmdline(argv[i] + strlen("/i")); + break; + case 'n': + CallRegister = FALSE; + break; + case 'c': + /* console output */ + break; + default: + output_write(STRING_UNRECOGNIZED_SWITCH, argv[i]); + output_write(STRING_USAGE); + return 1; } } - else if((!strcasecmp(argv[i], "/n"))||(!strcasecmp(argv[i], "-n"))) - CallRegister = FALSE; - else if((!strcasecmp(argv[i], "/c"))||(!strcasecmp(argv[i], "-c"))) - /* console output */; - else if (argv[i][0] == '/' && (!argv[i][2] || argv[i][2] == ':')) - { - output_write(STRING_UNRECOGNIZED_SWITCH, argv[i]); - output_write(STRING_USAGE); - return 1; - } else { char *DllName = argv[i]; @@ -293,7 +310,7 @@ int main(int argc, char* argv[]) if (res) return res; - /* Confirmed. The windows version does stop on the first error.*/ + /* Confirmed. The Windows version does stop on the first error. */ if (CallInstall) { @@ -301,7 +318,7 @@ int main(int argc, char* argv[]) } if (res) - return res; + return res; } } -- 1.8.3.2