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