1*3ff48bf5SDavid du Colombier /* Copyright (C) 1992, 2000 Aladdin Enterprises. All rights reserved. 27dd7cddfSDavid du Colombier 3*3ff48bf5SDavid du Colombier This file is part of AFPL Ghostscript. 47dd7cddfSDavid du Colombier 5*3ff48bf5SDavid du Colombier AFPL Ghostscript is distributed with NO WARRANTY OF ANY KIND. No author or 6*3ff48bf5SDavid du Colombier distributor accepts any responsibility for the consequences of using it, or 7*3ff48bf5SDavid du Colombier for whether it serves any particular purpose or works at all, unless he or 8*3ff48bf5SDavid du Colombier she says so in writing. Refer to the Aladdin Free Public License (the 9*3ff48bf5SDavid du Colombier "License") for full details. 107dd7cddfSDavid du Colombier 11*3ff48bf5SDavid du Colombier Every copy of AFPL Ghostscript must include a copy of the License, normally 12*3ff48bf5SDavid du Colombier in a plain ASCII text file named PUBLIC. The License grants you the right 13*3ff48bf5SDavid du Colombier to copy, modify and redistribute AFPL Ghostscript, but only under certain 14*3ff48bf5SDavid du Colombier conditions described in the License. Among other things, the License 15*3ff48bf5SDavid du Colombier requires that the copyright notice and this notice be preserved on all 16*3ff48bf5SDavid du Colombier copies. 177dd7cddfSDavid du Colombier */ 187dd7cddfSDavid du Colombier 19*3ff48bf5SDavid du Colombier /*$Id: gp_mswin.c,v 1.7 2001/09/22 07:07:02 ghostgum Exp $ */ 207dd7cddfSDavid du Colombier /* 21*3ff48bf5SDavid du Colombier * Microsoft Windows platform support for Ghostscript. 227dd7cddfSDavid du Colombier * 237dd7cddfSDavid du Colombier * Original version by Russell Lang and Maurice Castro with help from 247dd7cddfSDavid du Colombier * Programming Windows, 2nd Ed., Charles Petzold, Microsoft Press; 257dd7cddfSDavid du Colombier * initially created from gp_dosfb.c and gp_itbc.c 5th June 1992. 267dd7cddfSDavid du Colombier */ 277dd7cddfSDavid du Colombier 287dd7cddfSDavid du Colombier /* Modified for Win32 & Microsoft C/C++ 8.0 32-Bit, 26.Okt.1994 */ 297dd7cddfSDavid du Colombier /* by Friedrich Nowak */ 307dd7cddfSDavid du Colombier 317dd7cddfSDavid du Colombier /* Original EXE and GSview specific code removed */ 327dd7cddfSDavid du Colombier /* DLL version must now be used under MS-Windows */ 337dd7cddfSDavid du Colombier /* Russell Lang 16 March 1996 */ 347dd7cddfSDavid du Colombier 357dd7cddfSDavid du Colombier #include "stdio_.h" 367dd7cddfSDavid du Colombier #include "string_.h" 377dd7cddfSDavid du Colombier #include "memory_.h" 387dd7cddfSDavid du Colombier #include <stdlib.h> 397dd7cddfSDavid du Colombier #include <stdarg.h> 407dd7cddfSDavid du Colombier #include "ctype_.h" 417dd7cddfSDavid du Colombier #include "dos_.h" 427dd7cddfSDavid du Colombier #include <io.h> 437dd7cddfSDavid du Colombier #include "malloc_.h" 447dd7cddfSDavid du Colombier #include <fcntl.h> 457dd7cddfSDavid du Colombier #include <signal.h> 467dd7cddfSDavid du Colombier #include "gx.h" 477dd7cddfSDavid du Colombier #include "gp.h" 487dd7cddfSDavid du Colombier #include "gpcheck.h" 49*3ff48bf5SDavid du Colombier #include "gpmisc.h" 507dd7cddfSDavid du Colombier #include "gserrors.h" 517dd7cddfSDavid du Colombier #include "gsexit.h" 527dd7cddfSDavid du Colombier 537dd7cddfSDavid du Colombier #include "windows_.h" 547dd7cddfSDavid du Colombier #include <shellapi.h> 557dd7cddfSDavid du Colombier #include <winspool.h> 567dd7cddfSDavid du Colombier #include "gp_mswin.h" 577dd7cddfSDavid du Colombier 587dd7cddfSDavid du Colombier /* Library routines not declared in a standard header */ 597dd7cddfSDavid du Colombier extern char *getenv(P1(const char *)); 607dd7cddfSDavid du Colombier 617dd7cddfSDavid du Colombier /* limits */ 627dd7cddfSDavid du Colombier #define MAXSTR 255 637dd7cddfSDavid du Colombier 64*3ff48bf5SDavid du Colombier /* GLOBAL VARIABLE that needs to be removed */ 65*3ff48bf5SDavid du Colombier char win_prntmp[MAXSTR]; /* filename of PRN temporary file */ 66*3ff48bf5SDavid du Colombier 67*3ff48bf5SDavid du Colombier /* GLOBAL VARIABLES - initialised at DLL load time */ 687dd7cddfSDavid du Colombier HINSTANCE phInstance; 69*3ff48bf5SDavid du Colombier BOOL is_win32s = FALSE; 707dd7cddfSDavid du Colombier 717dd7cddfSDavid du Colombier const LPSTR szAppName = "Ghostscript"; 727dd7cddfSDavid du Colombier private int is_printer(const char *name); 737dd7cddfSDavid du Colombier 747dd7cddfSDavid du Colombier 757dd7cddfSDavid du Colombier /* ====== Generic platform procedures ====== */ 767dd7cddfSDavid du Colombier 777dd7cddfSDavid du Colombier /* ------ Initialization/termination (from gp_itbc.c) ------ */ 787dd7cddfSDavid du Colombier 797dd7cddfSDavid du Colombier /* Do platform-dependent initialization. */ 807dd7cddfSDavid du Colombier void 817dd7cddfSDavid du Colombier gp_init(void) 827dd7cddfSDavid du Colombier { 837dd7cddfSDavid du Colombier } 847dd7cddfSDavid du Colombier 857dd7cddfSDavid du Colombier /* Do platform-dependent cleanup. */ 867dd7cddfSDavid du Colombier void 877dd7cddfSDavid du Colombier gp_exit(int exit_status, int code) 887dd7cddfSDavid du Colombier { 897dd7cddfSDavid du Colombier } 907dd7cddfSDavid du Colombier 917dd7cddfSDavid du Colombier /* Exit the program. */ 927dd7cddfSDavid du Colombier void 937dd7cddfSDavid du Colombier gp_do_exit(int exit_status) 947dd7cddfSDavid du Colombier { 957dd7cddfSDavid du Colombier } 967dd7cddfSDavid du Colombier 977dd7cddfSDavid du Colombier /* ------ Printer accessing ------ */ 987dd7cddfSDavid du Colombier 997dd7cddfSDavid du Colombier /* Forward references */ 1007dd7cddfSDavid du Colombier private int gp_printfile(P2(const char *, const char *)); 1017dd7cddfSDavid du Colombier 1027dd7cddfSDavid du Colombier /* Open a connection to a printer. A null file name means use the */ 1037dd7cddfSDavid du Colombier /* standard printer connected to the machine, if any. */ 1047dd7cddfSDavid du Colombier /* Return NULL if the connection could not be opened. */ 1057dd7cddfSDavid du Colombier FILE * 1067dd7cddfSDavid du Colombier gp_open_printer(char fname[gp_file_name_sizeof], int binary_mode) 1077dd7cddfSDavid du Colombier { 1087dd7cddfSDavid du Colombier if (is_printer(fname)) { 1097dd7cddfSDavid du Colombier FILE *pfile; 1107dd7cddfSDavid du Colombier 1117dd7cddfSDavid du Colombier /* Open a scratch file, which we will send to the */ 1127dd7cddfSDavid du Colombier /* actual printer in gp_close_printer. */ 1137dd7cddfSDavid du Colombier pfile = gp_open_scratch_file(gp_scratch_file_name_prefix, 1147dd7cddfSDavid du Colombier win_prntmp, "wb"); 1157dd7cddfSDavid du Colombier return pfile; 1167dd7cddfSDavid du Colombier } else 1177dd7cddfSDavid du Colombier return fopen(fname, (binary_mode ? "wb" : "w")); 1187dd7cddfSDavid du Colombier } 1197dd7cddfSDavid du Colombier 1207dd7cddfSDavid du Colombier /* Close the connection to the printer. */ 1217dd7cddfSDavid du Colombier void 1227dd7cddfSDavid du Colombier gp_close_printer(FILE * pfile, const char *fname) 1237dd7cddfSDavid du Colombier { 1247dd7cddfSDavid du Colombier fclose(pfile); 1257dd7cddfSDavid du Colombier if (!is_printer(fname)) 1267dd7cddfSDavid du Colombier return; /* a file, not a printer */ 1277dd7cddfSDavid du Colombier 1287dd7cddfSDavid du Colombier gp_printfile(win_prntmp, fname); 1297dd7cddfSDavid du Colombier unlink(win_prntmp); 1307dd7cddfSDavid du Colombier } 1317dd7cddfSDavid du Colombier 1327dd7cddfSDavid du Colombier 1337dd7cddfSDavid du Colombier /* Dialog box to select printer port */ 134*3ff48bf5SDavid du Colombier BOOL CALLBACK 1357dd7cddfSDavid du Colombier SpoolDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 1367dd7cddfSDavid du Colombier { 1377dd7cddfSDavid du Colombier LPSTR entry; 1387dd7cddfSDavid du Colombier 1397dd7cddfSDavid du Colombier switch (message) { 1407dd7cddfSDavid du Colombier case WM_INITDIALOG: 1417dd7cddfSDavid du Colombier entry = (LPSTR) lParam; 1427dd7cddfSDavid du Colombier while (*entry) { 1437dd7cddfSDavid du Colombier SendDlgItemMessage(hDlg, SPOOL_PORT, LB_ADDSTRING, 0, (LPARAM) entry); 1447dd7cddfSDavid du Colombier entry += lstrlen(entry) + 1; 1457dd7cddfSDavid du Colombier } 1467dd7cddfSDavid du Colombier SendDlgItemMessage(hDlg, SPOOL_PORT, LB_SETCURSEL, 0, (LPARAM) 0); 1477dd7cddfSDavid du Colombier return TRUE; 1487dd7cddfSDavid du Colombier case WM_COMMAND: 1497dd7cddfSDavid du Colombier switch (LOWORD(wParam)) { 1507dd7cddfSDavid du Colombier case SPOOL_PORT: 151*3ff48bf5SDavid du Colombier if (HIWORD(wParam) == LBN_DBLCLK) 1527dd7cddfSDavid du Colombier PostMessage(hDlg, WM_COMMAND, IDOK, 0L); 1537dd7cddfSDavid du Colombier return FALSE; 1547dd7cddfSDavid du Colombier case IDOK: 1557dd7cddfSDavid du Colombier EndDialog(hDlg, 1 + (int)SendDlgItemMessage(hDlg, SPOOL_PORT, LB_GETCURSEL, 0, 0L)); 1567dd7cddfSDavid du Colombier return TRUE; 1577dd7cddfSDavid du Colombier case IDCANCEL: 1587dd7cddfSDavid du Colombier EndDialog(hDlg, 0); 1597dd7cddfSDavid du Colombier return TRUE; 1607dd7cddfSDavid du Colombier } 1617dd7cddfSDavid du Colombier } 1627dd7cddfSDavid du Colombier return FALSE; 1637dd7cddfSDavid du Colombier } 1647dd7cddfSDavid du Colombier 1657dd7cddfSDavid du Colombier /* return TRUE if queue looks like a valid printer name */ 1667dd7cddfSDavid du Colombier int 1677dd7cddfSDavid du Colombier is_spool(const char *queue) 1687dd7cddfSDavid du Colombier { 1697dd7cddfSDavid du Colombier char *prefix = "\\\\spool"; /* 7 characters long */ 1707dd7cddfSDavid du Colombier int i; 1717dd7cddfSDavid du Colombier 1727dd7cddfSDavid du Colombier for (i = 0; i < 7; i++) { 1737dd7cddfSDavid du Colombier if (prefix[i] == '\\') { 1747dd7cddfSDavid du Colombier if ((*queue != '\\') && (*queue != '/')) 1757dd7cddfSDavid du Colombier return FALSE; 1767dd7cddfSDavid du Colombier } else if (tolower(*queue) != prefix[i]) 1777dd7cddfSDavid du Colombier return FALSE; 1787dd7cddfSDavid du Colombier queue++; 1797dd7cddfSDavid du Colombier } 1807dd7cddfSDavid du Colombier if (*queue && (*queue != '\\') && (*queue != '/')) 1817dd7cddfSDavid du Colombier return FALSE; 1827dd7cddfSDavid du Colombier return TRUE; 1837dd7cddfSDavid du Colombier } 1847dd7cddfSDavid du Colombier 1857dd7cddfSDavid du Colombier 1867dd7cddfSDavid du Colombier private int 1877dd7cddfSDavid du Colombier is_printer(const char *name) 1887dd7cddfSDavid du Colombier { 1897dd7cddfSDavid du Colombier char buf[128]; 1907dd7cddfSDavid du Colombier 1917dd7cddfSDavid du Colombier /* is printer if no name given */ 1927dd7cddfSDavid du Colombier if (strlen(name) == 0) 1937dd7cddfSDavid du Colombier return TRUE; 1947dd7cddfSDavid du Colombier 1957dd7cddfSDavid du Colombier /* is printer if name appears in win.ini [ports] section */ 1967dd7cddfSDavid du Colombier GetProfileString("ports", name, "XYZ", buf, sizeof(buf)); 1977dd7cddfSDavid du Colombier if (strlen(name) == 0 || strcmp(buf, "XYZ")) 1987dd7cddfSDavid du Colombier return TRUE; 1997dd7cddfSDavid du Colombier 2007dd7cddfSDavid du Colombier /* is printer if name prefixed by \\spool\ */ 2017dd7cddfSDavid du Colombier if (is_spool(name)) 2027dd7cddfSDavid du Colombier return TRUE; 2037dd7cddfSDavid du Colombier 2047dd7cddfSDavid du Colombier return FALSE; 2057dd7cddfSDavid du Colombier } 2067dd7cddfSDavid du Colombier 2077dd7cddfSDavid du Colombier 2087dd7cddfSDavid du Colombier /******************************************************************/ 2097dd7cddfSDavid du Colombier /* Print File to port or queue */ 2107dd7cddfSDavid du Colombier /* port==NULL means prompt for port or queue with dialog box */ 2117dd7cddfSDavid du Colombier 2127dd7cddfSDavid du Colombier /* This is messy because Microsoft changed the spooler interface */ 213*3ff48bf5SDavid du Colombier /* between Windows 3.1 and Windows 95/NT */ 2147dd7cddfSDavid du Colombier /* and didn't provide the spooler interface in Win32s */ 2157dd7cddfSDavid du Colombier 2167dd7cddfSDavid du Colombier /* Win95, WinNT: Use OpenPrinter, WritePrinter etc. */ 2177dd7cddfSDavid du Colombier private int gp_printfile_win32(const char *filename, char *port); 2187dd7cddfSDavid du Colombier 2197dd7cddfSDavid du Colombier /* Win32s: Pass to Win16 spooler via gs16spl.exe */ 2207dd7cddfSDavid du Colombier private int gp_printfile_gs16spl(const char *filename, const char *port); 2217dd7cddfSDavid du Colombier 2227dd7cddfSDavid du Colombier /* 2237dd7cddfSDavid du Colombier * Valid values for pmport are: 2247dd7cddfSDavid du Colombier * "" 2257dd7cddfSDavid du Colombier * action: WinNT and Win95 use default queue, Win32s prompts for port 2267dd7cddfSDavid du Colombier * "LPT1:" (or other port that appears in win.ini [ports] 2277dd7cddfSDavid du Colombier * action: start gs16spl.exe to print to the port 2287dd7cddfSDavid du Colombier * "\\spool\printer name" 2297dd7cddfSDavid du Colombier * action: send to printer using WritePrinter (WinNT and Win95). 2307dd7cddfSDavid du Colombier * action: translate to port name using win.ini [Devices] 2317dd7cddfSDavid du Colombier * then use gs16spl.exe (Win32s). 2327dd7cddfSDavid du Colombier * "\\spool" 2337dd7cddfSDavid du Colombier * action: prompt for queue name then send to printer using 2347dd7cddfSDavid du Colombier * WritePrinter (WinNT and Win95). 2357dd7cddfSDavid du Colombier * action: prompt for port then use gs16spl.exe (Win32s). 2367dd7cddfSDavid du Colombier */ 2377dd7cddfSDavid du Colombier /* Print File */ 2387dd7cddfSDavid du Colombier private int 2397dd7cddfSDavid du Colombier gp_printfile(const char *filename, const char *pmport) 2407dd7cddfSDavid du Colombier { 2417dd7cddfSDavid du Colombier /* treat WinNT and Win95 differently to Win32s */ 2427dd7cddfSDavid du Colombier if (!is_win32s) { 2437dd7cddfSDavid du Colombier if (strlen(pmport) == 0) { /* get default printer */ 2447dd7cddfSDavid du Colombier char buf[256]; 2457dd7cddfSDavid du Colombier char *p; 2467dd7cddfSDavid du Colombier 2477dd7cddfSDavid du Colombier /* WinNT stores default printer in registry and win.ini */ 2487dd7cddfSDavid du Colombier /* Win95 stores default printer in win.ini */ 2497dd7cddfSDavid du Colombier GetProfileString("windows", "device", "", buf, sizeof(buf)); 2507dd7cddfSDavid du Colombier if ((p = strchr(buf, ',')) != NULL) 2517dd7cddfSDavid du Colombier *p = '\0'; 2527dd7cddfSDavid du Colombier return gp_printfile_win32(filename, buf); 2537dd7cddfSDavid du Colombier } else if (is_spool(pmport)) { 2547dd7cddfSDavid du Colombier if (strlen(pmport) >= 8) 2557dd7cddfSDavid du Colombier return gp_printfile_win32(filename, (char *)pmport + 8); 2567dd7cddfSDavid du Colombier else 2577dd7cddfSDavid du Colombier return gp_printfile_win32(filename, (char *)NULL); 2587dd7cddfSDavid du Colombier } else 2597dd7cddfSDavid du Colombier return gp_printfile_gs16spl(filename, pmport); 2607dd7cddfSDavid du Colombier } else { 2617dd7cddfSDavid du Colombier /* Win32s */ 2627dd7cddfSDavid du Colombier if (is_spool(pmport)) { 2637dd7cddfSDavid du Colombier if (strlen(pmport) >= 8) { 2647dd7cddfSDavid du Colombier /* extract port name from win.ini */ 2657dd7cddfSDavid du Colombier char driverbuf[256]; 2667dd7cddfSDavid du Colombier char *output; 2677dd7cddfSDavid du Colombier 2687dd7cddfSDavid du Colombier GetProfileString("Devices", pmport + 8, "", driverbuf, sizeof(driverbuf)); 2697dd7cddfSDavid du Colombier strtok(driverbuf, ","); 2707dd7cddfSDavid du Colombier output = strtok(NULL, ","); 2717dd7cddfSDavid du Colombier return gp_printfile_gs16spl(filename, output); 2727dd7cddfSDavid du Colombier } else 2737dd7cddfSDavid du Colombier return gp_printfile_gs16spl(filename, (char *)NULL); 2747dd7cddfSDavid du Colombier } else 2757dd7cddfSDavid du Colombier return gp_printfile_gs16spl(filename, pmport); 2767dd7cddfSDavid du Colombier } 2777dd7cddfSDavid du Colombier } 2787dd7cddfSDavid du Colombier 2797dd7cddfSDavid du Colombier #define PRINT_BUF_SIZE 16384u 2807dd7cddfSDavid du Colombier #define PORT_BUF_SIZE 4096 2817dd7cddfSDavid du Colombier 2827dd7cddfSDavid du Colombier char * 2837dd7cddfSDavid du Colombier get_queues(void) 2847dd7cddfSDavid du Colombier { 2857dd7cddfSDavid du Colombier int i; 2867dd7cddfSDavid du Colombier DWORD count, needed; 2877dd7cddfSDavid du Colombier PRINTER_INFO_1 *prinfo; 2887dd7cddfSDavid du Colombier char *enumbuffer; 2897dd7cddfSDavid du Colombier char *buffer; 2907dd7cddfSDavid du Colombier char *p; 2917dd7cddfSDavid du Colombier 2927dd7cddfSDavid du Colombier /* enumerate all available printers */ 2937dd7cddfSDavid du Colombier EnumPrinters(PRINTER_ENUM_CONNECTIONS | PRINTER_ENUM_LOCAL, NULL, 1, NULL, 0, &needed, &count); 2947dd7cddfSDavid du Colombier if (needed == 0) { 2957dd7cddfSDavid du Colombier /* no printers */ 2967dd7cddfSDavid du Colombier enumbuffer = malloc(4); 2977dd7cddfSDavid du Colombier if (enumbuffer == (char *)NULL) 2987dd7cddfSDavid du Colombier return NULL; 2997dd7cddfSDavid du Colombier memset(enumbuffer, 0, 4); 3007dd7cddfSDavid du Colombier return enumbuffer; 3017dd7cddfSDavid du Colombier } 3027dd7cddfSDavid du Colombier enumbuffer = malloc(needed); 3037dd7cddfSDavid du Colombier if (enumbuffer == (char *)NULL) 3047dd7cddfSDavid du Colombier return NULL; 3057dd7cddfSDavid du Colombier if (!EnumPrinters(PRINTER_ENUM_CONNECTIONS | PRINTER_ENUM_LOCAL, NULL, 1, (LPBYTE) enumbuffer, needed, &needed, &count)) { 3067dd7cddfSDavid du Colombier char buf[256]; 3077dd7cddfSDavid du Colombier 3087dd7cddfSDavid du Colombier free(enumbuffer); 3097dd7cddfSDavid du Colombier sprintf(buf, "EnumPrinters() failed, error code = %d", GetLastError()); 3107dd7cddfSDavid du Colombier MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 3117dd7cddfSDavid du Colombier return NULL; 3127dd7cddfSDavid du Colombier } 3137dd7cddfSDavid du Colombier prinfo = (PRINTER_INFO_1 *) enumbuffer; 3147dd7cddfSDavid du Colombier if ((buffer = malloc(PORT_BUF_SIZE)) == (char *)NULL) { 3157dd7cddfSDavid du Colombier free(enumbuffer); 3167dd7cddfSDavid du Colombier return NULL; 3177dd7cddfSDavid du Colombier } 3187dd7cddfSDavid du Colombier /* copy printer names to single buffer */ 3197dd7cddfSDavid du Colombier p = buffer; 3207dd7cddfSDavid du Colombier for (i = 0; i < count; i++) { 3217dd7cddfSDavid du Colombier if (strlen(prinfo[i].pName) + 1 < (PORT_BUF_SIZE - (p - buffer))) { 3227dd7cddfSDavid du Colombier strcpy(p, prinfo[i].pName); 3237dd7cddfSDavid du Colombier p += strlen(p) + 1; 3247dd7cddfSDavid du Colombier } 3257dd7cddfSDavid du Colombier } 3267dd7cddfSDavid du Colombier *p = '\0'; /* double null at end */ 3277dd7cddfSDavid du Colombier free(enumbuffer); 3287dd7cddfSDavid du Colombier return buffer; 3297dd7cddfSDavid du Colombier } 3307dd7cddfSDavid du Colombier 3317dd7cddfSDavid du Colombier 3327dd7cddfSDavid du Colombier char * 3337dd7cddfSDavid du Colombier get_ports(void) 3347dd7cddfSDavid du Colombier { 3357dd7cddfSDavid du Colombier char *buffer; 3367dd7cddfSDavid du Colombier 3377dd7cddfSDavid du Colombier if (!is_win32s) 3387dd7cddfSDavid du Colombier return get_queues(); 3397dd7cddfSDavid du Colombier 3407dd7cddfSDavid du Colombier if ((buffer = malloc(PORT_BUF_SIZE)) == (char *)NULL) 3417dd7cddfSDavid du Colombier return NULL; 3427dd7cddfSDavid du Colombier GetProfileString("ports", NULL, "", buffer, PORT_BUF_SIZE); 3437dd7cddfSDavid du Colombier return buffer; 3447dd7cddfSDavid du Colombier } 3457dd7cddfSDavid du Colombier 3467dd7cddfSDavid du Colombier /* return TRUE if queuename available */ 3477dd7cddfSDavid du Colombier /* return FALSE if cancelled or error */ 3487dd7cddfSDavid du Colombier /* if queue non-NULL, use as suggested queue */ 3497dd7cddfSDavid du Colombier BOOL 3507dd7cddfSDavid du Colombier get_queuename(char *portname, const char *queue) 3517dd7cddfSDavid du Colombier { 3527dd7cddfSDavid du Colombier char *buffer; 3537dd7cddfSDavid du Colombier char *p; 3547dd7cddfSDavid du Colombier int i, iport; 3557dd7cddfSDavid du Colombier 3567dd7cddfSDavid du Colombier buffer = get_queues(); 3577dd7cddfSDavid du Colombier if (buffer == NULL) 3587dd7cddfSDavid du Colombier return FALSE; 3597dd7cddfSDavid du Colombier if ((queue == (char *)NULL) || (strlen(queue) == 0)) { 3607dd7cddfSDavid du Colombier /* select a queue */ 3617dd7cddfSDavid du Colombier iport = DialogBoxParam(phInstance, "QueueDlgBox", (HWND) NULL, SpoolDlgProc, (LPARAM) buffer); 3627dd7cddfSDavid du Colombier if (!iport) { 3637dd7cddfSDavid du Colombier free(buffer); 3647dd7cddfSDavid du Colombier return FALSE; 3657dd7cddfSDavid du Colombier } 3667dd7cddfSDavid du Colombier p = buffer; 3677dd7cddfSDavid du Colombier for (i = 1; i < iport && strlen(p) != 0; i++) 3687dd7cddfSDavid du Colombier p += lstrlen(p) + 1; 3697dd7cddfSDavid du Colombier /* prepend \\spool\ which is used by Ghostscript to distinguish */ 3707dd7cddfSDavid du Colombier /* real files from queues */ 3717dd7cddfSDavid du Colombier strcpy(portname, "\\\\spool\\"); 3727dd7cddfSDavid du Colombier strcat(portname, p); 3737dd7cddfSDavid du Colombier } else { 3747dd7cddfSDavid du Colombier strcpy(portname, "\\\\spool\\"); 3757dd7cddfSDavid du Colombier strcat(portname, queue); 3767dd7cddfSDavid du Colombier } 3777dd7cddfSDavid du Colombier 3787dd7cddfSDavid du Colombier free(buffer); 3797dd7cddfSDavid du Colombier return TRUE; 3807dd7cddfSDavid du Colombier } 3817dd7cddfSDavid du Colombier 3827dd7cddfSDavid du Colombier /* return TRUE if portname available */ 3837dd7cddfSDavid du Colombier /* return FALSE if cancelled or error */ 3847dd7cddfSDavid du Colombier /* if port non-NULL, use as suggested port */ 3857dd7cddfSDavid du Colombier BOOL 3867dd7cddfSDavid du Colombier get_portname(char *portname, const char *port) 3877dd7cddfSDavid du Colombier { 3887dd7cddfSDavid du Colombier char *buffer; 3897dd7cddfSDavid du Colombier char *p; 3907dd7cddfSDavid du Colombier int i, iport; 3917dd7cddfSDavid du Colombier char filename[MAXSTR]; 3927dd7cddfSDavid du Colombier 3937dd7cddfSDavid du Colombier buffer = get_ports(); 3947dd7cddfSDavid du Colombier if (buffer == NULL) 3957dd7cddfSDavid du Colombier return FALSE; 3967dd7cddfSDavid du Colombier if ((port == (char *)NULL) || (strlen(port) == 0)) { 3977dd7cddfSDavid du Colombier if (buffer == (char *)NULL) 3987dd7cddfSDavid du Colombier return FALSE; 3997dd7cddfSDavid du Colombier /* select a port */ 4007dd7cddfSDavid du Colombier iport = DialogBoxParam(phInstance, "SpoolDlgBox", (HWND) NULL, SpoolDlgProc, (LPARAM) buffer); 4017dd7cddfSDavid du Colombier if (!iport) { 4027dd7cddfSDavid du Colombier free(buffer); 4037dd7cddfSDavid du Colombier return FALSE; 4047dd7cddfSDavid du Colombier } 4057dd7cddfSDavid du Colombier p = buffer; 4067dd7cddfSDavid du Colombier for (i = 1; i < iport && strlen(p) != 0; i++) 4077dd7cddfSDavid du Colombier p += lstrlen(p) + 1; 4087dd7cddfSDavid du Colombier strcpy(portname, p); 4097dd7cddfSDavid du Colombier } else 4107dd7cddfSDavid du Colombier strcpy(portname, port); 4117dd7cddfSDavid du Colombier 4127dd7cddfSDavid du Colombier if (strlen(portname) == 0) 4137dd7cddfSDavid du Colombier return FALSE; 4147dd7cddfSDavid du Colombier if (strcmp(portname, "FILE:") == 0) { 4157dd7cddfSDavid du Colombier OPENFILENAME ofn; 4167dd7cddfSDavid du Colombier 4177dd7cddfSDavid du Colombier filename[0] = '\0'; 4187dd7cddfSDavid du Colombier memset(&ofn, 0, sizeof(OPENFILENAME)); 4197dd7cddfSDavid du Colombier ofn.lStructSize = sizeof(OPENFILENAME); 4207dd7cddfSDavid du Colombier ofn.hwndOwner = (HWND) NULL; 4217dd7cddfSDavid du Colombier ofn.lpstrFile = filename; 4227dd7cddfSDavid du Colombier ofn.nMaxFile = sizeof(filename); 4237dd7cddfSDavid du Colombier ofn.Flags = OFN_PATHMUSTEXIST; 4247dd7cddfSDavid du Colombier if (!GetSaveFileName(&ofn)) { 4257dd7cddfSDavid du Colombier free(buffer); 4267dd7cddfSDavid du Colombier return FALSE; 4277dd7cddfSDavid du Colombier } 4287dd7cddfSDavid du Colombier strcpy(portname, filename); 4297dd7cddfSDavid du Colombier } 4307dd7cddfSDavid du Colombier free(buffer); 4317dd7cddfSDavid du Colombier return TRUE; 4327dd7cddfSDavid du Colombier } 4337dd7cddfSDavid du Colombier 4347dd7cddfSDavid du Colombier 4357dd7cddfSDavid du Colombier /* True Win32 method, using OpenPrinter, WritePrinter etc. */ 4367dd7cddfSDavid du Colombier private int 4377dd7cddfSDavid du Colombier gp_printfile_win32(const char *filename, char *port) 4387dd7cddfSDavid du Colombier { 4397dd7cddfSDavid du Colombier DWORD count; 4407dd7cddfSDavid du Colombier char *buffer; 4417dd7cddfSDavid du Colombier char portname[MAXSTR]; 4427dd7cddfSDavid du Colombier FILE *f; 4437dd7cddfSDavid du Colombier HANDLE printer; 4447dd7cddfSDavid du Colombier DOC_INFO_1 di; 4457dd7cddfSDavid du Colombier DWORD written; 4467dd7cddfSDavid du Colombier 4477dd7cddfSDavid du Colombier if (!get_queuename(portname, port)) 4487dd7cddfSDavid du Colombier return FALSE; 4497dd7cddfSDavid du Colombier port = portname + 8; /* skip over \\spool\ */ 4507dd7cddfSDavid du Colombier 4517dd7cddfSDavid du Colombier if ((buffer = malloc(PRINT_BUF_SIZE)) == (char *)NULL) 4527dd7cddfSDavid du Colombier return FALSE; 4537dd7cddfSDavid du Colombier 4547dd7cddfSDavid du Colombier if ((f = fopen(filename, "rb")) == (FILE *) NULL) { 4557dd7cddfSDavid du Colombier free(buffer); 4567dd7cddfSDavid du Colombier return FALSE; 4577dd7cddfSDavid du Colombier } 4587dd7cddfSDavid du Colombier /* open a printer */ 4597dd7cddfSDavid du Colombier if (!OpenPrinter(port, &printer, NULL)) { 4607dd7cddfSDavid du Colombier char buf[256]; 4617dd7cddfSDavid du Colombier 4627dd7cddfSDavid du Colombier sprintf(buf, "OpenPrinter() failed for \042%s\042, error code = %d", port, GetLastError()); 4637dd7cddfSDavid du Colombier MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 4647dd7cddfSDavid du Colombier free(buffer); 4657dd7cddfSDavid du Colombier return FALSE; 4667dd7cddfSDavid du Colombier } 4677dd7cddfSDavid du Colombier /* from here until ClosePrinter, should AbortPrinter on error */ 4687dd7cddfSDavid du Colombier 4697dd7cddfSDavid du Colombier di.pDocName = szAppName; 4707dd7cddfSDavid du Colombier di.pOutputFile = NULL; 4717dd7cddfSDavid du Colombier di.pDatatype = "RAW"; /* for available types see EnumPrintProcessorDatatypes */ 4727dd7cddfSDavid du Colombier if (!StartDocPrinter(printer, 1, (LPBYTE) & di)) { 4737dd7cddfSDavid du Colombier char buf[256]; 4747dd7cddfSDavid du Colombier 4757dd7cddfSDavid du Colombier sprintf(buf, "StartDocPrinter() failed, error code = %d", GetLastError()); 4767dd7cddfSDavid du Colombier MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 4777dd7cddfSDavid du Colombier AbortPrinter(printer); 4787dd7cddfSDavid du Colombier free(buffer); 4797dd7cddfSDavid du Colombier return FALSE; 4807dd7cddfSDavid du Colombier } 4817dd7cddfSDavid du Colombier /* copy file to printer */ 4827dd7cddfSDavid du Colombier while ((count = fread(buffer, 1, PRINT_BUF_SIZE, f)) != 0) { 4837dd7cddfSDavid du Colombier if (!WritePrinter(printer, (LPVOID) buffer, count, &written)) { 4847dd7cddfSDavid du Colombier free(buffer); 4857dd7cddfSDavid du Colombier fclose(f); 4867dd7cddfSDavid du Colombier AbortPrinter(printer); 4877dd7cddfSDavid du Colombier return FALSE; 4887dd7cddfSDavid du Colombier } 4897dd7cddfSDavid du Colombier } 4907dd7cddfSDavid du Colombier fclose(f); 4917dd7cddfSDavid du Colombier free(buffer); 4927dd7cddfSDavid du Colombier 4937dd7cddfSDavid du Colombier if (!EndDocPrinter(printer)) { 4947dd7cddfSDavid du Colombier char buf[256]; 4957dd7cddfSDavid du Colombier 4967dd7cddfSDavid du Colombier sprintf(buf, "EndDocPrinter() failed, error code = %d", GetLastError()); 4977dd7cddfSDavid du Colombier MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 4987dd7cddfSDavid du Colombier AbortPrinter(printer); 4997dd7cddfSDavid du Colombier return FALSE; 5007dd7cddfSDavid du Colombier } 5017dd7cddfSDavid du Colombier if (!ClosePrinter(printer)) { 5027dd7cddfSDavid du Colombier char buf[256]; 5037dd7cddfSDavid du Colombier 5047dd7cddfSDavid du Colombier sprintf(buf, "ClosePrinter() failed, error code = %d", GetLastError()); 5057dd7cddfSDavid du Colombier MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 5067dd7cddfSDavid du Colombier return FALSE; 5077dd7cddfSDavid du Colombier } 5087dd7cddfSDavid du Colombier return TRUE; 5097dd7cddfSDavid du Colombier } 5107dd7cddfSDavid du Colombier 5117dd7cddfSDavid du Colombier 5127dd7cddfSDavid du Colombier /* Start a 16-bit application gs16spl.exe to print a file */ 5137dd7cddfSDavid du Colombier /* Intended for Win32s where 16-bit spooler functions are not available */ 5147dd7cddfSDavid du Colombier /* and Win32 spooler functions are not implemented. */ 5157dd7cddfSDavid du Colombier int 5167dd7cddfSDavid du Colombier gp_printfile_gs16spl(const char *filename, const char *port) 5177dd7cddfSDavid du Colombier { 5187dd7cddfSDavid du Colombier /* Get printer port list from win.ini */ 5197dd7cddfSDavid du Colombier char portname[MAXSTR]; 5207dd7cddfSDavid du Colombier HINSTANCE hinst; 5217dd7cddfSDavid du Colombier char command[MAXSTR]; 5227dd7cddfSDavid du Colombier char *p; 5237dd7cddfSDavid du Colombier HWND hwndspl; 5247dd7cddfSDavid du Colombier 5257dd7cddfSDavid du Colombier if (!get_portname(portname, port)) 5267dd7cddfSDavid du Colombier return FALSE; 5277dd7cddfSDavid du Colombier 5287dd7cddfSDavid du Colombier /* get path to EXE - same as DLL */ 5297dd7cddfSDavid du Colombier GetModuleFileName(phInstance, command, sizeof(command)); 5307dd7cddfSDavid du Colombier if ((p = strrchr(command, '\\')) != (char *)NULL) 5317dd7cddfSDavid du Colombier p++; 5327dd7cddfSDavid du Colombier else 5337dd7cddfSDavid du Colombier p = command; 5347dd7cddfSDavid du Colombier *p = '\0'; 5357dd7cddfSDavid du Colombier sprintf(command + strlen(command), "gs16spl.exe %s %s", 5367dd7cddfSDavid du Colombier portname, filename); 5377dd7cddfSDavid du Colombier 5387dd7cddfSDavid du Colombier hinst = (HINSTANCE) WinExec(command, SW_SHOWNORMAL); 5397dd7cddfSDavid du Colombier if (hinst < (HINSTANCE) HINSTANCE_ERROR) { 5407dd7cddfSDavid du Colombier char buf[MAXSTR]; 5417dd7cddfSDavid du Colombier 5427dd7cddfSDavid du Colombier sprintf(buf, "Can't run: %s", command); 5437dd7cddfSDavid du Colombier MessageBox((HWND) NULL, buf, szAppName, MB_OK | MB_ICONSTOP); 5447dd7cddfSDavid du Colombier return FALSE; 5457dd7cddfSDavid du Colombier } 5467dd7cddfSDavid du Colombier hwndspl = FindWindow(NULL, "GS Win32s/Win16 spooler"); 5477dd7cddfSDavid du Colombier 5487dd7cddfSDavid du Colombier while (IsWindow(hwndspl)) { 5497dd7cddfSDavid du Colombier gp_check_interrupts(); 5507dd7cddfSDavid du Colombier } 5517dd7cddfSDavid du Colombier 5527dd7cddfSDavid du Colombier return 0; 5537dd7cddfSDavid du Colombier } 5547dd7cddfSDavid du Colombier 5557dd7cddfSDavid du Colombier 5567dd7cddfSDavid du Colombier 5577dd7cddfSDavid du Colombier 5587dd7cddfSDavid du Colombier /* ------ File naming and accessing ------ */ 5597dd7cddfSDavid du Colombier 5607dd7cddfSDavid du Colombier /* Create and open a scratch file with a given name prefix. */ 5617dd7cddfSDavid du Colombier /* Write the actual file name at fname. */ 5627dd7cddfSDavid du Colombier FILE * 5637dd7cddfSDavid du Colombier gp_open_scratch_file(const char *prefix, char *fname, const char *mode) 5647dd7cddfSDavid du Colombier { /* The -7 is for XXXXXX plus a possible final \. */ 565*3ff48bf5SDavid du Colombier int prefix_length = strlen(prefix); 566*3ff48bf5SDavid du Colombier int len = gp_file_name_sizeof - prefix_length - 7; 5677dd7cddfSDavid du Colombier 568*3ff48bf5SDavid du Colombier if (gp_file_name_is_absolute(prefix, prefix_length) || 569*3ff48bf5SDavid du Colombier gp_gettmpdir(fname, &len) != 0 570*3ff48bf5SDavid du Colombier ) 5717dd7cddfSDavid du Colombier *fname = 0; 5727dd7cddfSDavid du Colombier else { 5737dd7cddfSDavid du Colombier char *temp; 5747dd7cddfSDavid du Colombier 5757dd7cddfSDavid du Colombier /* Prevent X's in path from being converted by mktemp. */ 5767dd7cddfSDavid du Colombier for (temp = fname; *temp; temp++) 5777dd7cddfSDavid du Colombier *temp = tolower(*temp); 5787dd7cddfSDavid du Colombier if (strlen(fname) && (fname[strlen(fname) - 1] != '\\')) 5797dd7cddfSDavid du Colombier strcat(fname, "\\"); 5807dd7cddfSDavid du Colombier } 581*3ff48bf5SDavid du Colombier if (strlen(fname) + prefix_length + 7 >= gp_file_name_sizeof) 582*3ff48bf5SDavid du Colombier return 0; /* file name too long */ 5837dd7cddfSDavid du Colombier strcat(fname, prefix); 5847dd7cddfSDavid du Colombier strcat(fname, "XXXXXX"); 5857dd7cddfSDavid du Colombier mktemp(fname); 586*3ff48bf5SDavid du Colombier return gp_fopentemp(fname, mode); 5877dd7cddfSDavid du Colombier } 5887dd7cddfSDavid du Colombier 5897dd7cddfSDavid du Colombier /* Open a file with the given name, as a stream of uninterpreted bytes. */ 5907dd7cddfSDavid du Colombier FILE * 5917dd7cddfSDavid du Colombier gp_fopen(const char *fname, const char *mode) 5927dd7cddfSDavid du Colombier { 5937dd7cddfSDavid du Colombier return fopen(fname, mode); 5947dd7cddfSDavid du Colombier } 595*3ff48bf5SDavid du Colombier 596