Commit | Line | Data |
---|---|---|
3fd4a536 DR |
1 | /* |
2 | * Implementation of the Printer User Interface Dialogs | |
3 | * | |
d97a3b33 | 4 | * Copyright 2006-2007 Detlef Riekenberg |
3fd4a536 DR |
5 | * |
6 | * This library is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU Lesser General Public | |
8 | * License as published by the Free Software Foundation; either | |
9 | * version 2.1 of the License, or (at your option) any later version. | |
10 | * | |
11 | * This library is distributed in the hope that it will be useful, | |
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 | * Lesser General Public License for more details. | |
15 | * | |
16 | * You should have received a copy of the GNU Lesser General Public | |
17 | * License along with this library; if not, write to the Free Software | |
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA | |
19 | */ | |
20 | ||
21 | #include <stdarg.h> | |
22 | ||
23 | #define COBJMACROS | |
24 | #define NONAMELESSUNION | |
25 | ||
26 | #include "windef.h" | |
27 | #include "winbase.h" | |
28 | #include "wingdi.h" | |
29 | #include "winuser.h" | |
30 | #include "winreg.h" | |
31 | #include "winver.h" | |
32 | #include "winnls.h" | |
d97a3b33 | 33 | #include "shellapi.h" |
3fd4a536 DR |
34 | |
35 | #include "wine/unicode.h" | |
36 | #include "wine/debug.h" | |
d97a3b33 | 37 | #include "printui_private.h" |
3fd4a536 DR |
38 | |
39 | WINE_DEFAULT_DEBUG_CHANNEL(printui); | |
40 | ||
41 | HINSTANCE PRINTUI_hInstance = NULL; | |
42 | ||
d97a3b33 DR |
43 | /* ################################# */ |
44 | ||
45 | /* Must be in order with OPT_* */ | |
46 | static const WCHAR optionsW[OPT_MAX+1]={'a','b','c','f','h','j','l','m','n','t','r','v',0}; | |
47 | ||
48 | /* Must be in order with FLAG_* */ | |
49 | static const WCHAR flagsW[FLAG_MAX+1]={'q','w','y','z','Z',0}; | |
50 | ||
51 | ||
52 | /* ################################ | |
53 | * get_next_wstr() [Internal] | |
54 | * | |
55 | * Get the next WSTR, when available | |
56 | * | |
57 | */ | |
58 | ||
59 | static LPWSTR get_next_wstr(context_t * cx) | |
60 | { | |
61 | LPWSTR ptr; | |
62 | ||
63 | ptr = cx->pNextCharW; | |
64 | if (ptr && ptr[0]) { | |
65 | cx->pNextCharW = NULL; | |
66 | return ptr; | |
67 | } | |
68 | ||
69 | /* Get the next Parameter, when available */ | |
70 | if (cx->next_arg < cx->argc) { | |
71 | ptr = cx->argv[cx->next_arg]; | |
72 | cx->next_arg++; | |
73 | cx->pNextCharW = NULL; | |
74 | return ptr; | |
75 | } | |
76 | return NULL; | |
77 | } | |
78 | ||
79 | ||
80 | /* ################################ | |
81 | * get_next_wchar() [Internal] | |
82 | * | |
83 | * Get the next WCHAR from the Commandline or from the File (@ Filename) | |
84 | * | |
85 | * ToDo: Support Parameter from a File ( "@Filename" ) | |
86 | * | |
87 | */ | |
88 | ||
89 | static WCHAR get_next_wchar(context_t * cx, BOOL use_next_parameter) | |
90 | { | |
91 | WCHAR c; | |
92 | ||
93 | /* Try the next WCHAR in the actual Parameter */ | |
94 | if (cx->pNextCharW) { | |
95 | c = *cx->pNextCharW; | |
96 | if (c) { | |
97 | cx->pNextCharW++; | |
98 | return c; | |
99 | } | |
100 | /* We reached the end of the Parameter */ | |
101 | cx->pNextCharW = NULL; | |
102 | } | |
103 | ||
104 | /* Get the next Parameter, when available and allowed */ | |
105 | if ((cx->pNextCharW == NULL) && (cx->next_arg < cx->argc) && (use_next_parameter)) { | |
106 | cx->pNextCharW = cx->argv[cx->next_arg]; | |
107 | cx->next_arg++; | |
108 | } | |
109 | ||
110 | if (cx->pNextCharW) { | |
111 | c = *cx->pNextCharW; | |
112 | if (c) { | |
113 | cx->pNextCharW++; | |
114 | } | |
115 | else | |
116 | { | |
117 | /* We reached the end of the Parameter */ | |
118 | cx->pNextCharW = NULL; | |
119 | } | |
120 | return c; | |
121 | } | |
122 | return '\0'; | |
123 | } | |
124 | ||
125 | /* ################################ */ | |
126 | static BOOL parse_rundll(context_t * cx) | |
127 | { | |
128 | LPWSTR ptr; | |
129 | DWORD index; | |
130 | WCHAR txtW[2]; | |
131 | WCHAR c; | |
132 | ||
133 | ||
134 | c = get_next_wchar(cx, TRUE); | |
135 | txtW[1] = '\0'; | |
136 | ||
137 | while (c) | |
138 | { | |
139 | ||
140 | while ( (c == ' ') || (c == '\t')) | |
141 | { | |
142 | c = get_next_wchar(cx, TRUE); | |
143 | } | |
144 | txtW[0] = c; | |
145 | ||
146 | if (c == '@') { | |
147 | /* read commands from a File */ | |
148 | ptr = get_next_wstr(cx); | |
149 | FIXME("redir not supported: %s\n", debugstr_w(ptr)); | |
150 | return FALSE; | |
151 | } | |
152 | else if (c == '/') { | |
153 | c = get_next_wchar(cx, FALSE); | |
154 | while ( c ) | |
155 | { | |
156 | txtW[0] = c; | |
157 | ptr = strchrW(optionsW, c); | |
158 | if (ptr) { | |
159 | index = ptr - optionsW; | |
160 | cx->options[index] = get_next_wstr(cx); | |
161 | TRACE(" opt: %s %s\n", debugstr_w(txtW), debugstr_w(cx->options[index])); | |
162 | c = 0; | |
163 | } | |
164 | else | |
165 | { | |
166 | ptr = strchrW(flagsW, c); | |
167 | if (ptr) { | |
168 | index = ptr - flagsW; | |
169 | cx->flags[index] = TRUE; | |
170 | TRACE("flag: %s\n", debugstr_w(txtW)); | |
171 | } | |
172 | else | |
173 | { | |
174 | cx->command = c; | |
175 | cx->subcommand = '\0'; | |
176 | TRACE(" cmd: %s\n", debugstr_w(txtW)); | |
177 | } | |
178 | ||
179 | /* help has priority over all commands */ | |
180 | if (c == '?') { | |
181 | return TRUE; | |
182 | } | |
183 | ||
184 | c = get_next_wchar(cx, FALSE); | |
185 | ||
186 | /* Some commands use two wchar */ | |
187 | if ((cx->command == 'd') || (cx->command == 'g') || (cx->command == 'i') || | |
188 | (cx->command == 'S') || (cx->command == 'X') ){ | |
189 | cx->subcommand = c; | |
190 | txtW[0] = c; | |
191 | TRACE(" sub: %s\n", debugstr_w(txtW)); | |
192 | c = get_next_wchar(cx, FALSE); | |
193 | } | |
194 | } | |
195 | } | |
196 | c = get_next_wchar(cx, TRUE); | |
197 | ||
198 | } | |
199 | else | |
200 | { | |
201 | /* The commands 'S' and 'X' have additional Parameter */ | |
202 | if ((cx->command == 'S') || (cx->command == 'X')) { | |
203 | ||
204 | /* the actual WCHAR is the start from the extra Parameter */ | |
205 | cx->pNextCharW--; | |
206 | TRACE("%d extra Parameter, starting with %s\n", 1 + (cx->argc - cx->next_arg), debugstr_w(cx->pNextCharW)); | |
207 | return TRUE; | |
208 | } | |
209 | FIXME("0x%x: %s is unknown\n", c, debugstr_wn(&c, 1)); | |
210 | return FALSE; | |
211 | } | |
212 | ||
213 | } | |
214 | return TRUE; | |
215 | } | |
216 | ||
3fd4a536 DR |
217 | /***************************************************** |
218 | * DllMain | |
219 | */ | |
220 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) | |
221 | { | |
222 | TRACE("(%p, %d, %p)\n",hinstDLL, fdwReason, lpvReserved); | |
223 | ||
224 | switch(fdwReason) | |
225 | { | |
226 | case DLL_WINE_PREATTACH: | |
227 | return FALSE; /* prefer native version */ | |
228 | ||
229 | case DLL_PROCESS_ATTACH: | |
230 | PRINTUI_hInstance = hinstDLL; | |
231 | DisableThreadLibraryCalls( hinstDLL ); | |
232 | break; | |
233 | } | |
234 | return TRUE; | |
235 | } | |
236 | ||
237 | ||
238 | /***************************************************** | |
239 | * PrintUIEntryW [printui.@] | |
240 | * Commandline-Interface for using printui.dll with rundll32.exe | |
241 | * | |
242 | */ | |
243 | void WINAPI PrintUIEntryW(HWND hWnd, HINSTANCE hInst, LPCWSTR pCommand, DWORD nCmdShow) | |
244 | { | |
d97a3b33 DR |
245 | context_t cx; |
246 | BOOL res = FALSE; | |
247 | ||
248 | TRACE("(%p, %p, %s, 0x%x)\n", hWnd, hInst, debugstr_w(pCommand), nCmdShow); | |
249 | ||
250 | memset(&cx, 0, sizeof(context_t)); | |
251 | cx.hWnd = hWnd; | |
252 | cx.nCmdShow = nCmdShow; | |
253 | ||
254 | if ((pCommand) && (pCommand[0])) { | |
255 | /* result is allocated with GlobalAlloc() */ | |
256 | cx.argv = CommandLineToArgvW(pCommand, &cx.argc); | |
257 | TRACE("got %d args at %p\n", cx.argc, cx.argv); | |
258 | ||
259 | res = parse_rundll(&cx); | |
260 | } | |
261 | ||
262 | if (res && cx.command) { | |
263 | switch (cx.command) | |
264 | { | |
265 | ||
266 | default: | |
267 | { | |
268 | WCHAR txtW[3]; | |
269 | txtW[0] = cx.command; | |
270 | txtW[1] = cx.subcommand; | |
271 | txtW[2] = '\0'; | |
272 | FIXME("command not implemented: %s\n", debugstr_w(txtW)); | |
273 | } | |
274 | } | |
275 | } | |
276 | ||
277 | if ((res == FALSE) || (cx.command == '\0')) { | |
278 | FIXME("dialog: Printer / The operation was not successful\n"); | |
279 | } | |
280 | ||
281 | GlobalFree(cx.argv); | |
282 | ||
3fd4a536 | 283 | } |