winspool: perform spooler lookup
Huw D M Davies
h.davies1 at physics.ox.ac.uk
Wed Jul 20 06:29:39 CDT 2005
Huw Davies <huw at codeweavers.com>
Lookup the port in the spooler registry key and map it to a unix
filename or a pipe like OpenJob16 does.
--
Huw Davies
huw at codeweavers.com
Index: dlls/winspool/info.c
===================================================================
RCS file: /home/wine/wine/dlls/winspool/info.c,v
retrieving revision 1.120
diff -u -p -r1.120 info.c
--- dlls/winspool/info.c 19 Jul 2005 19:12:13 -0000 1.120
+++ dlls/winspool/info.c 20 Jul 2005 11:24:04 -0000
@@ -31,6 +31,8 @@
#include <string.h>
#include <ctype.h>
#include <stddef.h>
+#include <unistd.h>
+#include <signal.h>
#ifdef HAVE_CUPS_CUPS_H
# include <cups/cups.h>
# ifndef SONAME_LIBCUPS
@@ -5215,6 +5217,104 @@ static BOOL schedule_file(LPCWSTR filena
}
return FALSE;
}
+
+/*****************************************************************************
+ * schedule_pipe
+ */
+static BOOL schedule_pipe(LPCWSTR cmd, LPCWSTR filename)
+{
+#ifdef HAVE_FORK
+ char *unixname, *cmdA;
+ DWORD len;
+ int fds[2] = {-1, -1}, file_fd = -1, no_read;
+ BOOL ret = FALSE;
+ char buf[1024];
+
+ if(!(unixname = wine_get_unix_file_name(filename)))
+ return FALSE;
+
+ len = WideCharToMultiByte(CP_ACP, 0, cmd, -1, NULL, 0, NULL, NULL);
+ cmdA = HeapAlloc(GetProcessHeap(), 0, len);
+ WideCharToMultiByte(CP_ACP, 0, cmd, -1, cmdA, len, NULL, NULL);
+
+ TRACE("printing with: %s\n", cmdA);
+
+ if((file_fd = open(unixname, O_RDONLY)) == -1)
+ goto end;
+
+ if (pipe(fds))
+ {
+ ERR("pipe() failed!\n");
+ goto end;
+ }
+
+ if (fork() == 0)
+ {
+ close(0);
+ dup2(fds[0], 0);
+ close(fds[1]);
+
+ /* reset signals that we previously set to SIG_IGN */
+ signal(SIGPIPE, SIG_DFL);
+ signal(SIGCHLD, SIG_DFL);
+
+ system(cmdA);
+ exit(0);
+ }
+
+ while((no_read = read(file_fd, buf, sizeof(buf))))
+ write(fds[1], buf, no_read);
+
+ ret = TRUE;
+
+end:
+ if(file_fd != -1) close(file_fd);
+ if(fds[0] != -1) close(fds[0]);
+ if(fds[1] != -1) close(fds[1]);
+
+ HeapFree(GetProcessHeap(), 0, cmdA);
+ HeapFree(GetProcessHeap(), 0, unixname);
+ return ret;
+#else
+ return FALSE;
+#endif
+}
+
+/*****************************************************************************
+ * schedule_unixfile
+ */
+static BOOL schedule_unixfile(LPCWSTR output, LPCWSTR filename)
+{
+ int in_fd, out_fd, no_read;
+ char buf[1024];
+ BOOL ret = FALSE;
+ char *unixname, *outputA;
+ DWORD len;
+
+ if(!(unixname = wine_get_unix_file_name(filename)))
+ return FALSE;
+
+ len = WideCharToMultiByte(CP_ACP, 0, output, -1, NULL, 0, NULL, NULL);
+ outputA = HeapAlloc(GetProcessHeap(), 0, len);
+ WideCharToMultiByte(CP_ACP, 0, output, -1, outputA, len, NULL, NULL);
+
+ out_fd = open(outputA, O_CREAT | O_TRUNC | O_WRONLY, 0666);
+ in_fd = open(unixname, O_RDONLY);
+ if(out_fd == -1 || in_fd == -1)
+ goto end;
+
+ while((no_read = read(in_fd, buf, sizeof(buf))))
+ write(out_fd, buf, no_read);
+
+ ret = TRUE;
+end:
+ if(in_fd != -1) close(in_fd);
+ if(out_fd != -1) close(out_fd);
+ HeapFree(GetProcessHeap(), 0, outputA);
+ HeapFree(GetProcessHeap(), 0, unixname);
+ return ret;
+}
+
/*****************************************************************************
* ScheduleJob [WINSPOOL.@]
*
@@ -5243,6 +5343,10 @@ BOOL WINAPI ScheduleJob( HANDLE hPrinter
{
PRINTER_INFO_5W *pi5;
DWORD needed;
+ HKEY hkey;
+ WCHAR output[1024];
+ static const WCHAR spooler_key[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
+ 'P','r','i','n','t','i','n','g','\\','S','p','o','o','l','e','r',0};
GetPrinterW(hPrinter, 5, NULL, 0, &needed);
pi5 = HeapAlloc(GetProcessHeap(), 0, needed);
@@ -5250,7 +5354,24 @@ BOOL WINAPI ScheduleJob( HANDLE hPrinter
TRACE("need to schedule job %ld filename %s to port %s\n", job->job_id, debugstr_w(job->filename),
debugstr_w(pi5->pPortName));
- if(!strncmpW(pi5->pPortName, LPR_Port, strlenW(LPR_Port)))
+ output[0] = 0;
+
+ /* @@ Wine registry key: HKCU\Software\Wine\Printing\Spooler */
+ if(RegOpenKeyW(HKEY_CURRENT_USER, spooler_key, &hkey) == ERROR_SUCCESS)
+ {
+ DWORD type, count = sizeof(output);
+ RegQueryValueExW(hkey, pi5->pPortName, NULL, &type, (LPBYTE)output, &count);
+ RegCloseKey(hkey);
+ }
+ if(output[0] == '|')
+ {
+ schedule_pipe(output + 1, job->filename);
+ }
+ else if(output[0])
+ {
+ schedule_unixfile(output, job->filename);
+ }
+ else if(!strncmpW(pi5->pPortName, LPR_Port, strlenW(LPR_Port)))
{
schedule_lpr(pi5->pPortName + strlenW(LPR_Port), job->filename);
}
More information about the wine-patches
mailing list