See also https://bugs.winehq.org/show_bug.cgi?id=56361
This patch makes piped commands work like for example "echo os get version|wmic" or "type file.txt | wmic" where file.txt contains some commands. (probably used by program in aforementioned bugreport)
Also support interactive mode (wine wmic.exe)
Marked for now as draft.
-- v11: wmic.exe: Support interactive mode and piped commands.
From: Louis Lenders xerox.xerox2000x@gmail.com
See also https://bugs.winehq.org/show_bug.cgi?id=56361
This patch makes piped commands work like for example "echo os get version|wmic" or "type file.txt | wmic" where file.txt contains some commands. (probably used by program in aforementioned bugreport)
Also support interactive mode (wine wmic.exe) --- programs/wmic/Makefile.in | 2 +- programs/wmic/main.c | 46 ++++++++++++++++++++++++++++++++++++++- programs/wmic/wmic.h | 1 + programs/wmic/wmic.rc | 1 + 4 files changed, 48 insertions(+), 2 deletions(-)
diff --git a/programs/wmic/Makefile.in b/programs/wmic/Makefile.in index 973232f8480..83a9539ea38 100644 --- a/programs/wmic/Makefile.in +++ b/programs/wmic/Makefile.in @@ -1,5 +1,5 @@ MODULE = wmic.exe -IMPORTS = oleaut32 ole32 user32 +IMPORTS = oleaut32 ole32 user32 shell32
EXTRADLLFLAGS = -mconsole -municode
diff --git a/programs/wmic/main.c b/programs/wmic/main.c index 936fe45139d..3cbbf28f604 100644 --- a/programs/wmic/main.c +++ b/programs/wmic/main.c @@ -28,12 +28,14 @@ #include "initguid.h" #include "objidl.h" #include "wbemcli.h" +#include "shellapi.h" #include "wmic.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(wmic);
+#define MAX_STRING 4096 static const struct { const WCHAR *alias; @@ -333,7 +335,7 @@ done: return ret; }
-int __cdecl wmain(int argc, WCHAR *argv[]) +static int process_args( int argc, WCHAR *argv[] ) { const WCHAR *class, *value; int i; @@ -391,3 +393,45 @@ not_supported: output_error( STRING_CMDLINE_NOT_SUPPORTED ); return 1; } + +int __cdecl wmain(int argc, WCHAR *argv[]) +{ + WCHAR cmd[MAX_STRING]; + int ret = 0; + + setlocale( LC_ALL, "" ); + + if (argc == 1) + { + fputws( L"wbem:root\cli>", stdout ); + + while (fgetws(cmd, sizeof(cmd), stdin) != NULL) + { + WCHAR wmic[MAX_STRING] = L"wmic.exe "; + + cmd[wcslen(cmd)-1] = 0; /* remove trailing '\n' */ + + WINE_TRACE("command: %s\n", debugstr_w(cmd)); + if (!wcsicmp( strip_spaces(cmd), L"exit" ) || !wcsicmp( strip_spaces(cmd), L"quit" )) + return 0; + + if (!cmd[0]) + output_error( STRING_USAGE ); + else + { + int _argc; + WCHAR **_argv; + + _argv = CommandLineToArgvW( wcscat( wmic, cmd ), &_argc ); + ret = process_args( _argc, _argv ); + LocalFree(_argv); + + output_newline(); + } + fputws( L"wbem:root\cli>", stdout ); + } + return ret; + } + + return process_args( argc, argv ); +} diff --git a/programs/wmic/wmic.h b/programs/wmic/wmic.h index 27272706af5..fef2113feb0 100644 --- a/programs/wmic/wmic.h +++ b/programs/wmic/wmic.h @@ -22,3 +22,4 @@ #define STRING_ALIAS_NOT_FOUND 102 #define STRING_INVALID_QUERY 103 #define STRING_INVALID_PATH 104 +#define STRING_USAGE 105 diff --git a/programs/wmic/wmic.rc b/programs/wmic/wmic.rc index 0789ef34631..797fe7dbe08 100644 --- a/programs/wmic/wmic.rc +++ b/programs/wmic/wmic.rc @@ -28,4 +28,5 @@ STRINGTABLE STRING_ALIAS_NOT_FOUND, "Error: Alias not found\n" STRING_INVALID_QUERY, "Error: Invalid query\n" STRING_INVALID_PATH, "Error: Invalid syntax for PATH\n" + STRING_USAGE, "Supply a command\n" }
CommandLineToArgvW() has special handling for whitespace and quotes on the command line. I doubt that the same rules apply in interactive mode.
I would start by splitting the buffer into class (possibly preceded by 'path' specifier), verb and properties.
Hi, sorry I still fear I don't get the point why this is needed.
I did a few tests both in wine and on windows and I cannot see a difference yet between a command ran in interactive mode/piped and a normal command with arguments.
In wine and windows:
In interactive mode: " os " "get" " name " --> does not work (invalid alias)
In cmd: wmic " os " "get" " name " --> does not work (invalid alias)
In interactive mode: "os" "get" " name " --> works
In cmd: wmic "os" "get" " name " --> works
etc.
There's difference between wine and windows with regards to single quotes around properties (e.g 'name') but here too interactive mode and command with arguments currently seem to behave the same both in wine and windows afaict
`
I see, it does behave like the command line w.r.t quotes, and you sidestep the leading spaces case by prepending "wmic ", but that's not pretty. It would be better to strip whitespace from the command buffer and pass that to CommandLineToArgvW().
process_args() then doesn't need to handle command line switches or call setlocale() again. STRING_CMDLINE_NOT_SUPPORTED doesn't make sense in interactive mode. I think we should split it into STRING_SWITCH_NOT_SUPPORTED and STRING_COMMAND_NOT_SUPPORTED.