1 /* Copyright (C) 1999 Aladdin Enterprises. All rights reserved.
2
3 This software is provided AS-IS with no warranty, either express or
4 implied.
5
6 This software is distributed under license and may not be copied,
7 modified or distributed except as expressly authorized under the terms
8 of the license contained in the file LICENSE in this distribution.
9
10 For more information about licensing, please refer to
11 http://www.ghostscript.com/licensing/. For information on
12 commercial licensing, go to http://www.artifex.com/licensing/ or
13 contact Artifex Software, Inc., 101 Lucas Valley Road #110,
14 San Rafael, CA 94903, U.S.A., +1(415)492-9861.
15 */
16
17 /* $Id: gp_mshdl.c,v 1.4 2002/02/21 22:24:52 giles Exp $ */
18 /* %handle% IODevice */
19 #include "errno_.h"
20 #include "stdio_.h"
21 #include "string_.h"
22 #include "ctype_.h"
23 #include <io.h>
24 #include "gserror.h"
25 #include "gstypes.h"
26 #include "gsmemory.h" /* for gxiodev.h */
27 #include "gxiodev.h"
28
29 /* The MS-Windows handle IODevice */
30
31 /* This allows an MS-Windows file handle to be passed in to
32 * Ghostscript as %handle%NNNNNNNN where NNNNNNNN is the hexadecimal
33 * value of the handle.
34 * The typical use is for another program to create a pipe,
35 * pass the write end into Ghostscript using
36 * -sOutputFile="%handle%NNNNNNNN"
37 * so that Ghostscript printer output can be captured by the
38 * other program. The handle would be created with CreatePipe().
39 * If Ghostscript is not a DLL, the pipe will have to be inheritable
40 * by the Ghostscript process.
41 */
42
43 private iodev_proc_fopen(mswin_handle_fopen);
44 private iodev_proc_fclose(mswin_handle_fclose);
45 const gx_io_device gs_iodev_handle = {
46 "%handle%", "FileSystem",
47 {iodev_no_init, iodev_no_open_device,
48 NULL /*iodev_os_open_file */ , mswin_handle_fopen, mswin_handle_fclose,
49 iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status,
50 iodev_no_enumerate_files, NULL, NULL,
51 iodev_no_get_params, iodev_no_put_params
52 }
53 };
54
55 /* The file device procedures */
56 #ifndef INVALID_HANDLE_VALUE
57 #define INVALID_HANDLE_VALUE (-1)
58 #endif
59
60 /* Allow printer filename specified by -sOutputFile="..."
61 * to contain a hexadecimal encoded OS file handle in the
62 * form -sOutputFile="\\handle\\000001c5"
63 *
64 * Returns:
65 * The OS file handle on success.
66 * INVALID_HANDLE_VALUE on failure.
67 *
68 * This allows the caller to create an OS pipe and give us a
69 * handle to the write end of the pipe.
70 * If we are called as an EXE, the OS file handle must be
71 * inherited by Ghostscript.
72 * Pipes aren't supported under Win32s.
73 */
74 private long
get_os_handle(const char * name)75 get_os_handle(const char *name)
76 {
77 ulong hfile; /* This must be as long as the longest handle. */
78 /* This is correct for Win32, maybe wrong for Win64. */
79 int i, ch;
80
81 for (i = 0; (ch = name[i]) != 0; ++i)
82 if (!isxdigit(ch))
83 return (long)INVALID_HANDLE_VALUE;
84 if (sscanf(name, "%lx", &hfile) != 1)
85 return (long)INVALID_HANDLE_VALUE;
86 return (long)hfile;
87 }
88
89 private int
mswin_handle_fopen(gx_io_device * iodev,const char * fname,const char * access,FILE ** pfile,char * rfname,uint rnamelen)90 mswin_handle_fopen(gx_io_device * iodev, const char *fname, const char *access,
91 FILE ** pfile, char *rfname, uint rnamelen)
92 {
93 int fd;
94 long hfile; /* Correct for Win32, may be wrong for Win64 */
95 errno = 0;
96
97 if ((hfile = get_os_handle(fname)) == (long)INVALID_HANDLE_VALUE)
98 return_error(gs_fopen_errno_to_code(EBADF));
99
100 /* associate a C file handle with an OS file handle */
101 fd = _open_osfhandle((long)hfile, 0);
102 if (fd == -1)
103 return_error(gs_fopen_errno_to_code(EBADF));
104
105 /* associate a C file stream with C file handle */
106 *pfile = fdopen(fd, (char *)access);
107 if (*pfile == NULL)
108 return_error(gs_fopen_errno_to_code(errno));
109
110 if (rfname != NULL)
111 strcpy(rfname, fname);
112 return 0;
113 }
114
115 private int
mswin_handle_fclose(gx_io_device * iodev,FILE * file)116 mswin_handle_fclose(gx_io_device * iodev, FILE * file)
117 {
118 fclose(file);
119 return 0;
120 }
121