mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-31 12:19:49 +00:00
280 lines
7.4 KiB
C
280 lines
7.4 KiB
C
/*
|
|
* Implementation of the Printer User Interface Dialogs
|
|
*
|
|
* 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
|
|
* 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
|
|
*/
|
|
|
|
#include <stdarg.h>
|
|
|
|
#define COBJMACROS
|
|
#define NONAMELESSUNION
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "wingdi.h"
|
|
#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);
|
|
|
|
/* ################################# */
|
|
|
|
/* Must be in order with OPT_* */
|
|
static const WCHAR optionsW[OPT_MAX+1]={'a','b','c','f','h','j','l','m','n','t','r','v',0};
|
|
|
|
/* Must be in order with FLAG_* */
|
|
static const WCHAR flagsW[FLAG_MAX+1]={'q','w','y','z','Z',0};
|
|
|
|
|
|
/* ################################
|
|
* 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;
|
|
DWORD index;
|
|
WCHAR txtW[2];
|
|
WCHAR c;
|
|
|
|
|
|
c = get_next_wchar(cx, TRUE);
|
|
txtW[1] = '\0';
|
|
|
|
while (c)
|
|
{
|
|
|
|
while ( (c == ' ') || (c == '\t'))
|
|
{
|
|
c = get_next_wchar(cx, TRUE);
|
|
}
|
|
txtW[0] = c;
|
|
|
|
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 )
|
|
{
|
|
txtW[0] = c;
|
|
ptr = strchrW(optionsW, c);
|
|
if (ptr) {
|
|
index = ptr - optionsW;
|
|
cx->options[index] = get_next_wstr(cx);
|
|
TRACE(" opt: %s %s\n", debugstr_w(txtW), debugstr_w(cx->options[index]));
|
|
c = 0;
|
|
}
|
|
else
|
|
{
|
|
ptr = strchrW(flagsW, c);
|
|
if (ptr) {
|
|
index = ptr - flagsW;
|
|
cx->flags[index] = TRUE;
|
|
TRACE("flag: %s\n", debugstr_w(txtW));
|
|
}
|
|
else
|
|
{
|
|
cx->command = c;
|
|
cx->subcommand = '\0';
|
|
TRACE(" cmd: %s\n", debugstr_w(txtW));
|
|
}
|
|
|
|
/* help has priority over all commands */
|
|
if (c == '?') {
|
|
return TRUE;
|
|
}
|
|
|
|
c = get_next_wchar(cx, FALSE);
|
|
|
|
/* Some commands use two wchar */
|
|
if ((cx->command == 'd') || (cx->command == 'g') || (cx->command == 'i') ||
|
|
(cx->command == 'S') || (cx->command == 'X') ){
|
|
cx->subcommand = c;
|
|
txtW[0] = c;
|
|
TRACE(" sub: %s\n", debugstr_w(txtW));
|
|
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')) {
|
|
|
|
/* the actual WCHAR is the start from the extra Parameter */
|
|
cx->pNextCharW--;
|
|
TRACE("%d extra Parameter, starting with %s\n", 1 + (cx->argc - cx->next_arg), debugstr_w(cx->pNextCharW));
|
|
return TRUE;
|
|
}
|
|
FIXME("0x%x: %s is unknown\n", c, debugstr_wn(&c, 1));
|
|
return FALSE;
|
|
}
|
|
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/*****************************************************
|
|
* DllMain
|
|
*/
|
|
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
|
{
|
|
TRACE("(%p, %d, %p)\n",hinstDLL, fdwReason, lpvReserved);
|
|
|
|
switch(fdwReason)
|
|
{
|
|
case DLL_WINE_PREATTACH:
|
|
return FALSE; /* prefer native version */
|
|
|
|
case DLL_PROCESS_ATTACH:
|
|
DisableThreadLibraryCalls( hinstDLL );
|
|
break;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
/*****************************************************
|
|
* PrintUIEntryW [printui.@]
|
|
* Commandline-Interface for using printui.dll with rundll32.exe
|
|
*
|
|
*/
|
|
void WINAPI PrintUIEntryW(HWND hWnd, HINSTANCE hInst, LPCWSTR pCommand, DWORD 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])) {
|
|
/* result is allocated with GlobalAlloc() */
|
|
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[3];
|
|
txtW[0] = cx.command;
|
|
txtW[1] = cx.subcommand;
|
|
txtW[2] = '\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);
|
|
|
|
}
|