printui: Parse args in PrintUIEntryW
Detlef Riekenberg
wine.dev at web.de
Wed Jul 4 15:47:48 CDT 2007
I did a lot of tests with rundll32 and used the results to build
a Parser on top of CommandLineToArgvW
printui: Parse args in PrintUIEntryW
--
By by ... Detlef
-------------- next part --------------
>From 87657e3dc83768b71ba292f319c9c5603d70b8bd Mon Sep 17 00:00:00 2001
From: Detlef Riekenberg <wine.dev at web.de>
Date: Wed, 4 Jul 2007 22:45:26 +0200
Subject: [PATCH] printui: Parse args in PrintUIEntryW
---
dlls/printui/Makefile.in | 2
dlls/printui/printui.c | 260 ++++++++++++++++++++++++++++++++++++++++
dlls/printui/printui_private.h | 54 ++++++++
3 files changed, 312 insertions(+), 4 deletions(-)
diff --git a/dlls/printui/Makefile.in b/dlls/printui/Makefile.in
index 2cb44b9..65aa7f6 100644
--- a/dlls/printui/Makefile.in
+++ b/dlls/printui/Makefile.in
@@ -3,7 +3,7 @@ TOPOBJDIR = ../..
SRCDIR = @srcdir@
VPATH = @srcdir@
MODULE = printui.dll
-IMPORTS = kernel32
+IMPORTS = kernel32 shell32
C_SRCS = \
printui.c
diff --git a/dlls/printui/printui.c b/dlls/printui/printui.c
index 06cbaa2..f54f17d 100644
--- a/dlls/printui/printui.c
+++ b/dlls/printui/printui.c
@@ -1,7 +1,7 @@
/*
* Implementation of the Printer User Interface Dialogs
*
- * Copyright 2006 Detlef Riekenberg
+ * Copyright 2006-2007 Detlef Riekenberg
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -30,14 +30,236 @@ #include "winuser.h"
#include "winreg.h"
#include "winver.h"
#include "winnls.h"
+#include "shellapi.h"
#include "wine/unicode.h"
#include "wine/debug.h"
+#include "printui_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(printui);
HINSTANCE PRINTUI_hInstance = NULL;
+/* ################################
+ * get_next_wstr() [Internal]
+ *
+ * Get the next WSTR, when available
+ *
+ */
+
+static LPWSTR get_next_wstr(context_t * cx)
+{
+ LPWSTR ptr;
+
+ ptr = cx->pNextCharW;
+ if (ptr && ptr[0]) {
+ cx->pNextCharW = NULL;
+ return ptr;
+ }
+
+ /* Get the next Parameter, when available */
+ if (cx->next_arg < cx->argc) {
+ ptr = cx->argv[cx->next_arg];
+ cx->next_arg++;
+ cx->pNextCharW = NULL;
+ return ptr;
+ }
+ return NULL;
+}
+
+
+/* ################################
+ * get_next_wchar() [Internal]
+ *
+ * Get the next WCHAR from the Commandline or from the File (@ Filename)
+ *
+ * ToDo: Support Parameter from a File ( "@Filename" )
+ *
+ */
+
+static WCHAR get_next_wchar(context_t * cx, BOOL use_next_parameter)
+{
+ WCHAR c;
+
+ /* Try the next WCHAR in the actual Parameter */
+ if (cx->pNextCharW) {
+ c = *cx->pNextCharW;
+ if (c) {
+ cx->pNextCharW++;
+ return c;
+ }
+ /* We reached the end of the Parameter */
+ cx->pNextCharW = NULL;
+ }
+
+ /* Get the next Parameter, when available and allowed */
+ if ((cx->pNextCharW == NULL) && (cx->next_arg < cx->argc) && (use_next_parameter)) {
+ cx->pNextCharW = cx->argv[cx->next_arg];
+ cx->next_arg++;
+ }
+
+ if (cx->pNextCharW) {
+ c = *cx->pNextCharW;
+ if (c) {
+ cx->pNextCharW++;
+ }
+ else
+ {
+ /* We reached the end of the Parameter */
+ cx->pNextCharW = NULL;
+ }
+ return c;
+ }
+ return '\0';
+}
+
+/* ################################ */
+static BOOL parse_rundll(context_t * cx)
+{
+
+ LPWSTR ptr;
+ WCHAR c;
+
+
+ c = get_next_wchar(cx, TRUE);
+
+ while (c)
+ {
+ while ( (c == ' ') || (c == '\t'))
+ {
+ c = get_next_wchar(cx, TRUE);
+ }
+
+ if (c == '@') {
+ /* read commands from a File */
+ ptr = get_next_wstr(cx);
+ FIXME("redir not supported: %s\n", debugstr_w(ptr));
+ return FALSE;
+ }
+ else if (c == '/') {
+ c = get_next_wchar(cx, FALSE);
+ while ( c )
+ {
+ switch (c)
+ {
+ case 'a':
+ cx->opt_a = get_next_wstr(cx);
+ TRACE("opt_a: %s\n", debugstr_w(cx->opt_a));
+ c = '\0';
+ break;
+
+ case 'b':
+ cx->opt_b = get_next_wstr(cx);
+ TRACE("opt_b: %s\n", debugstr_w(cx->opt_b));
+ c = '\0';
+ break;
+
+ case 'c':
+ cx->opt_c = get_next_wstr(cx);
+ TRACE("opt_c: %s\n", debugstr_w(cx->opt_c));
+ c = '\0';
+ break;
+
+ case 'f':
+ cx->opt_f = get_next_wstr(cx);
+ TRACE("opt_f: %s\n", debugstr_w(cx->opt_f));
+ c = '\0';
+ break;
+
+ case 'h':
+ cx->opt_h = get_next_wstr(cx);
+ TRACE("opt_h: %s\n", debugstr_w(cx->opt_h));
+ c = '\0';
+ break;
+
+ case 'j':
+ cx->opt_j = get_next_wstr(cx);
+ TRACE("opt_j: %s\n", debugstr_w(cx->opt_j));
+ c = '\0';
+ break;
+
+ case 'l':
+ cx->opt_l = get_next_wstr(cx);
+ TRACE("opt_l: %s\n", debugstr_w(cx->opt_l));
+ c = '\0';
+ break;
+
+ case 'm':
+ cx->opt_m = get_next_wstr(cx);
+ TRACE("opt_m: %s\n", debugstr_w(cx->opt_m));
+ c = '\0';
+ break;
+
+ case 'n':
+ cx->opt_n = get_next_wstr(cx);
+ TRACE("opt_n: %s\n", debugstr_w(cx->opt_n));
+ c = '\0';
+ break;
+
+ case 'r':
+ cx->opt_r = get_next_wstr(cx);
+ TRACE("opt_r: %s\n", debugstr_w(cx->opt_r));
+ c = '\0';
+ break;
+
+ case 't':
+ cx->opt_t = get_next_wstr(cx);
+ TRACE("opt_t: %s\n", debugstr_w(cx->opt_t));
+ c = '\0';
+ break;
+
+ case 'v':
+ cx->opt_v = get_next_wstr(cx);
+ TRACE("opt_v: %s\n", debugstr_w(cx->opt_v));
+ c = '\0';
+ break;
+
+
+ default:
+ if (c == 'q') {
+ cx->quiet = TRUE;
+ }
+ else
+ {
+ cx->command = c;
+ cx->subcommand = '\0';
+ }
+ TRACE("cmd__: %c\n", (CHAR) c);
+
+ /* help has priority over all commands */
+ if (c == '?') {
+ return TRUE;
+ }
+
+
+ c = get_next_wchar(cx, FALSE);
+ if ((cx->command == 'd') || (cx->command == 'g') || (cx->command == 'i') ||
+ (cx->command == 'S') || (cx->command == 'X') ){
+ cx->subcommand = c;
+ c = get_next_wchar(cx, FALSE);
+ }
+ }
+ }
+ c = get_next_wchar(cx, TRUE);
+
+ }
+ else
+ {
+ /* The commands 'S' and 'X' have additional Parameter */
+ if ((cx->command == 'S') || (cx->command == 'X')) {
+ /* unget the WCHAR */
+ cx->pNextCharW--;
+ TRACE("%d extra Parameter, starting with %s\n", 1 + (cx->argc - cx->next_arg), debugstr_w(cx->pNextCharW));
+ return TRUE;
+ }
+ TRACE("bad code 0x%x: %c\n", c, (CHAR) c);
+ return FALSE;
+ }
+
+ }
+ return TRUE;
+}
+
/*****************************************************
* DllMain
*/
@@ -58,7 +280,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,
return TRUE;
}
-
/*****************************************************
* PrintUIEntryW [printui.@]
* Commandline-Interface for using printui.dll with rundll32.exe
@@ -66,5 +287,38 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL,
*/
void WINAPI PrintUIEntryW(HWND hWnd, HINSTANCE hInst, LPCWSTR pCommand, DWORD nCmdShow)
{
- FIXME("(%p, %p, %s, 0x%x) stub\n", hWnd, hInst, debugstr_w(pCommand), nCmdShow);
+ context_t cx;
+ BOOL res = FALSE;
+
+ TRACE("(%p, %p, %s, 0x%x)\n", hWnd, hInst, debugstr_w(pCommand), nCmdShow);
+
+ memset(&cx, 0, sizeof(context_t));
+ cx.hWnd = hWnd;
+ cx.nCmdShow = nCmdShow;
+
+ if ((pCommand) && (pCommand[0])) {
+ cx.argv = CommandLineToArgvW(pCommand, &cx.argc);
+ TRACE("got %d args at %p\n", cx.argc, cx.argv);
+
+ res = parse_rundll(&cx);
+ }
+
+ if (res && cx.command) {
+ switch (cx.command)
+ {
+
+ default:
+ {
+ WCHAR txtW[] = {cx.command, cx.subcommand, 0};
+ FIXME("command not implemented: %s\n", debugstr_w(txtW));
+ }
+ }
+ }
+
+ if ((res == FALSE) || (cx.command == '\0')) {
+ FIXME("dialog: Printer / The operation was not successful\n");
+ }
+
+ GlobalFree(cx.argv);
+
}
diff --git a/dlls/printui/printui_private.h b/dlls/printui/printui_private.h
new file mode 100644
index 0000000..e049255
--- /dev/null
+++ b/dlls/printui/printui_private.h
@@ -0,0 +1,54 @@
+/*
+ * Implementation of the Printer User Interface Dialogs: private Header
+ *
+ * Copyright 2007 Detlef Riekenberg
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __WINE_PRINTUI_PRIVATE__
+#define __WINE_PRINTUI_PRIVATE__
+
+
+typedef struct tag_context {
+ HWND hWnd;
+ DWORD nCmdShow;
+ LPWSTR * argv;
+ LPWSTR pNextCharW;
+ int argc;
+ int next_arg;
+ LPWSTR opt_a;
+ LPWSTR opt_b;
+ LPWSTR opt_c;
+ LPWSTR opt_f;
+ LPWSTR opt_h;
+ LPWSTR opt_j;
+ LPWSTR opt_l;
+ LPWSTR opt_m;
+ LPWSTR opt_n;
+ LPWSTR opt_r;
+ LPWSTR opt_t;
+ LPWSTR opt_v;
+ WCHAR command;
+ WCHAR subcommand;
+ BOOL quiet;
+} context_t;
+
+
+/* ## DLL-wide Globals ## */
+extern HINSTANCE PRINTUI_hInstance;
+
+
+#endif
--
1.4.1
More information about the wine-patches
mailing list