localui: Implement ConfigurePortUI for COMx.
[wine/gsoc_dplay.git] / dlls / localui / localui.c
blob133fd60049bc04422a0b7c08c09ffc77611b95b6
1 /*
2 * Implementation of the Local Printmonitor User Interface
4 * Copyright 2007 Detlef Riekenberg
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.
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.
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
21 #include <stdarg.h>
23 #define NONAMELESSUNION
25 #include "windef.h"
26 #include "winbase.h"
27 #include "wingdi.h"
28 #include "winreg.h"
29 #include "winuser.h"
31 #include "winspool.h"
32 #include "ddk/winsplp.h"
34 #include "wine/debug.h"
35 #include "wine/unicode.h"
36 #include "localui.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(localui);
40 /*****************************************************/
42 static HINSTANCE LOCALUI_hInstance;
44 static const WCHAR cmd_DeletePortW[] = {'D','e','l','e','t','e','P','o','r','t',0};
45 static const WCHAR cmd_GetDefaultCommConfigW[] = {'G','e','t',
46 'D','e','f','a','u','l','t',
47 'C','o','m','m','C','o','n','f','i','g',0};
48 static const WCHAR cmd_SetDefaultCommConfigW[] = {'S','e','t',
49 'D','e','f','a','u','l','t',
50 'C','o','m','m','C','o','n','f','i','g',0};
52 static const WCHAR portname_LPT[] = {'L','P','T',0};
53 static const WCHAR portname_COM[] = {'C','O','M',0};
54 static const WCHAR portname_FILE[] = {'F','I','L','E',':',0};
55 static const WCHAR portname_CUPS[] = {'C','U','P','S',':',0};
56 static const WCHAR portname_LPR[] = {'L','P','R',':',0};
58 static const WCHAR XcvPortW[] = {',','X','c','v','P','o','r','t',' ',0};
61 /*****************************************************
62 * strdupWW [internal]
65 static LPWSTR strdupWW(LPCWSTR pPrefix, LPCWSTR pSuffix)
67 LPWSTR ptr;
68 DWORD len;
70 len = lstrlenW(pPrefix) + (pSuffix ? lstrlenW(pSuffix) : 0) + 1;
71 ptr = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
72 if (ptr) {
73 lstrcpyW(ptr, pPrefix);
74 if (pSuffix) lstrcatW(ptr, pSuffix);
76 return ptr;
79 /*****************************************************
80 * dlg_configure_com [internal]
84 static BOOL dlg_configure_com(HANDLE hXcv, HWND hWnd, PCWSTR pPortName)
86 COMMCONFIG cfg;
87 LPWSTR shortname;
88 DWORD status;
89 DWORD dummy;
90 DWORD len;
91 BOOL res;
93 /* strip the colon (pPortName is never empty here) */
94 len = lstrlenW(pPortName);
95 shortname = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
96 if (shortname) {
97 memcpy(shortname, pPortName, (len -1) * sizeof(WCHAR));
98 shortname[len-1] = '\0';
100 /* get current settings */
101 len = sizeof(cfg);
102 status = ERROR_SUCCESS;
103 res = XcvDataW( hXcv, cmd_GetDefaultCommConfigW,
104 (PBYTE) shortname,
105 (lstrlenW(shortname) +1) * sizeof(WCHAR),
106 (PBYTE) &cfg, len, &len, &status);
108 if (res && (status == ERROR_SUCCESS)) {
109 /* display the Dialog */
110 res = CommConfigDialogW(pPortName, hWnd, &cfg);
111 if (res) {
112 status = ERROR_SUCCESS;
113 /* set new settings */
114 res = XcvDataW(hXcv, cmd_SetDefaultCommConfigW,
115 (PBYTE) &cfg, len,
116 (PBYTE) &dummy, 0, &len, &status);
119 HeapFree(GetProcessHeap(), 0, shortname);
120 return res;
122 return FALSE;
125 /******************************************************************
126 * display the Dialog "Nothing to configure"
130 static void dlg_nothingtoconfig(HWND hWnd)
132 WCHAR res_PortW[IDS_LOCALPORT_MAXLEN];
133 WCHAR res_nothingW[IDS_NOTHINGTOCONFIG_MAXLEN];
135 res_PortW[0] = '\0';
136 res_nothingW[0] = '\0';
137 LoadStringW(LOCALUI_hInstance, IDS_LOCALPORT, res_PortW, IDS_LOCALPORT_MAXLEN);
138 LoadStringW(LOCALUI_hInstance, IDS_NOTHINGTOCONFIG, res_nothingW, IDS_NOTHINGTOCONFIG_MAXLEN);
140 MessageBoxW(hWnd, res_nothingW, res_PortW, MB_OK | MB_ICONINFORMATION);
143 /*****************************************************
144 * get_type_from_name (internal)
148 static DWORD get_type_from_name(LPCWSTR name)
150 HANDLE hfile;
152 if (!strncmpiW(name, portname_LPT, sizeof(portname_LPT) / sizeof(WCHAR) -1))
153 return PORT_IS_LPT;
155 if (!strncmpiW(name, portname_COM, sizeof(portname_COM) / sizeof(WCHAR) -1))
156 return PORT_IS_COM;
158 if (!strcmpiW(name, portname_FILE))
159 return PORT_IS_FILE;
161 if (name[0] == '/')
162 return PORT_IS_UNIXNAME;
164 if (name[0] == '|')
165 return PORT_IS_PIPE;
167 if (!strncmpW(name, portname_CUPS, sizeof(portname_CUPS) / sizeof(WCHAR) -1))
168 return PORT_IS_CUPS;
170 if (!strncmpW(name, portname_LPR, sizeof(portname_LPR) / sizeof(WCHAR) -1))
171 return PORT_IS_LPR;
173 /* Must be a file or a directory. Does the file exist ? */
174 hfile = CreateFileW(name, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
175 TRACE("%p for OPEN_EXISTING on %s\n", hfile, debugstr_w(name));
176 if (hfile == INVALID_HANDLE_VALUE) {
177 /* Can we create the file? */
178 hfile = CreateFileW(name, GENERIC_WRITE, 0, NULL, OPEN_ALWAYS, FILE_FLAG_DELETE_ON_CLOSE, NULL);
179 TRACE("%p for OPEN_ALWAYS\n", hfile);
181 if (hfile != INVALID_HANDLE_VALUE) {
182 CloseHandle(hfile);
183 return PORT_IS_FILENAME;
185 /* We can't use the name. use GetLastError() for the reason */
186 return PORT_IS_UNKNOWN;
189 /*****************************************************
190 * open_monitor_by_name [internal]
193 static BOOL open_monitor_by_name(LPCWSTR pPrefix, LPCWSTR pPort, HANDLE * phandle)
195 PRINTER_DEFAULTSW pd;
196 LPWSTR fullname;
197 BOOL res;
199 * phandle = 0;
200 TRACE("(%s,%s)\n", debugstr_w(pPrefix),debugstr_w(pPort) );
202 fullname = strdupWW(pPrefix, pPort);
203 pd.pDatatype = NULL;
204 pd.pDevMode = NULL;
205 pd.DesiredAccess = SERVER_ACCESS_ADMINISTER;
207 res = OpenPrinterW(fullname, phandle, &pd);
208 HeapFree(GetProcessHeap(), 0, fullname);
209 return res;
212 /*****************************************************
213 * localui_AddPortUI [exported through MONITORUI]
215 * Display a Dialog to add a local Port
217 * PARAMS
218 * pName [I] Servername or NULL (local Computer)
219 * hWnd [I] Handle to parent Window for the Dialog-Box or NULL
220 * pMonitorName[I] Name of the Monitor, that should be used to add a Port or NULL
221 * ppPortName [O] PTR to PTR of a buffer, that receive the Name of the new Port or NULL
223 * RETURNS
224 * Success: TRUE
225 * Failure: FALSE
228 static BOOL WINAPI localui_AddPortUI(PCWSTR pName, HWND hWnd, PCWSTR pMonitorName, PWSTR *ppPortName)
230 FIXME("(%s, %p, %s, %p) stub\n", debugstr_w(pName), hWnd, debugstr_w(pMonitorName), ppPortName);
231 return TRUE;
235 /*****************************************************
236 * localui_ConfigurePortUI [exported through MONITORUI]
238 * Display the Configuration-Dialog for a specific Port
240 * PARAMS
241 * pName [I] Servername or NULL (local Computer)
242 * hWnd [I] Handle to parent Window for the Dialog-Box or NULL
243 * pPortName [I] Name of the Port, that should be configured
245 * RETURNS
246 * Success: TRUE
247 * Failure: FALSE
250 static BOOL WINAPI localui_ConfigurePortUI(PCWSTR pName, HWND hWnd, PCWSTR pPortName)
252 HANDLE hXcv;
253 DWORD res;
255 TRACE("(%s, %p, %s)\n", debugstr_w(pName), hWnd, debugstr_w(pPortName));
256 if (open_monitor_by_name(XcvPortW, pPortName, &hXcv)) {
258 res = get_type_from_name(pPortName);
259 switch(res)
262 case PORT_IS_COM:
263 res = dlg_configure_com(hXcv, hWnd, pPortName);
264 break;
266 default:
267 dlg_nothingtoconfig(hWnd);
268 SetLastError(ERROR_CANCELLED);
269 res = FALSE;
272 ClosePrinter(hXcv);
273 return res;
275 return FALSE;
279 /*****************************************************
280 * localui_DeletePortUI [exported through MONITORUI]
282 * Delete a specific Port
284 * PARAMS
285 * pName [I] Servername or NULL (local Computer)
286 * hWnd [I] Handle to parent Window
287 * pPortName [I] Name of the Port, that should be deleted
289 * RETURNS
290 * Success: TRUE
291 * Failure: FALSE
293 * NOTES
294 * Native localui does not allow to delete a COM / LPT - Port (ERROR_NOT_SUPPORTED)
297 static BOOL WINAPI localui_DeletePortUI(PCWSTR pName, HWND hWnd, PCWSTR pPortName)
299 HANDLE hXcv;
300 DWORD dummy;
301 DWORD needed;
302 DWORD status;
304 TRACE("(%s, %p, %s)\n", debugstr_w(pName), hWnd, debugstr_w(pPortName));
306 if ((!pPortName) || (!pPortName[0])) {
307 SetLastError(ERROR_INVALID_PARAMETER);
308 return FALSE;
311 if (open_monitor_by_name(XcvPortW, pPortName, &hXcv)) {
312 /* native localui tests here for LPT / COM - Ports and failed with
313 ERROR_NOT_SUPPORTED. */
314 if (XcvDataW(hXcv, cmd_DeletePortW, (LPBYTE) pPortName,
315 (lstrlenW(pPortName)+1) * sizeof(WCHAR), (LPBYTE) &dummy, 0, &needed, &status)) {
317 ClosePrinter(hXcv);
318 if (status != ERROR_SUCCESS) SetLastError(status);
319 return (status == ERROR_SUCCESS);
321 ClosePrinter(hXcv);
322 return FALSE;
324 SetLastError(ERROR_UNKNOWN_PORT);
325 return FALSE;
328 /*****************************************************
329 * InitializePrintMonitorUI (LOCALUI.@)
331 * Initialize the User-Interface for the Local Ports
333 * RETURNS
334 * Success: Pointer to a MONITORUI Structure
335 * Failure: NULL
339 PMONITORUI WINAPI InitializePrintMonitorUI(void)
341 static MONITORUI mymonitorui =
343 sizeof(MONITORUI),
344 localui_AddPortUI,
345 localui_ConfigurePortUI,
346 localui_DeletePortUI
349 TRACE("=> %p\n", &mymonitorui);
350 return &mymonitorui;
353 /*****************************************************
354 * DllMain
356 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
358 TRACE("(%p, %d, %p)\n",hinstDLL, fdwReason, lpvReserved);
360 switch(fdwReason)
362 case DLL_WINE_PREATTACH:
363 return FALSE; /* prefer native version */
365 case DLL_PROCESS_ATTACH:
366 DisableThreadLibraryCalls( hinstDLL );
367 LOCALUI_hInstance = hinstDLL;
368 break;
370 return TRUE;