diff options
Diffstat (limited to 'win/tclWin16.c')
-rw-r--r-- | win/tclWin16.c | 347 |
1 files changed, 347 insertions, 0 deletions
diff --git a/win/tclWin16.c b/win/tclWin16.c new file mode 100644 index 0000000..d8ea801 --- /dev/null +++ b/win/tclWin16.c @@ -0,0 +1,347 @@ +/* + * tclWin16.c -- + * + * This file contains code for a 16-bit DLL to handle 32-to-16 bit + * thunking. This is necessary for the Win32s SynchSpawn() call. + * + * Copyright (c) 1994-1997 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * SCCS: @(#) tclWin16.c 1.18 97/05/23 13:13:32 + */ + +#define STRICT + +#include <windows.h> +#include <toolhelp.h> + +#include <stdio.h> +#include <string.h> + +static int WinSpawn(char *command); +static int DosSpawn(char *command, char *fromFileName, + char *toFileName); +static int WaitForExit(int inst); + +/* + * The following data is used to construct a .pif file that wraps the + * .bat file that runs the 16-bit application (that Jack built). + * The .pif file causes the .bat file to run in an iconified window. + * Otherwise, when we try to exec something, a DOS box pops up, + * obscuring everything, and then almost immediately flickers out of + * existence, which is rather disconcerting. + */ + +static char pifData[545] = { +'\000', '\013', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\200', '\000', '\200', '\000', '\103', '\117', '\115', '\115', +'\101', '\116', '\104', '\056', '\103', '\117', '\115', '\000', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\020', '\000', '\000', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\177', '\001', '\000', +'\377', '\031', '\120', '\000', '\000', '\007', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\340', +'\040', '\115', '\111', '\103', '\122', '\117', '\123', '\117', +'\106', '\124', '\040', '\120', '\111', '\106', '\105', '\130', +'\000', '\207', '\001', '\000', '\000', '\161', '\001', '\127', +'\111', '\116', '\104', '\117', '\127', '\123', '\040', '\063', +'\070', '\066', '\040', '\063', '\056', '\060', '\000', '\005', +'\002', '\235', '\001', '\150', '\000', '\200', '\002', '\200', +'\000', '\144', '\000', '\062', '\000', '\000', '\004', '\000', +'\000', '\000', '\004', '\000', '\000', '\002', '\020', '\002', +'\000', '\037', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\000', '\000', '\000', +'\000', '\000', '\000', '\000', '\000', '\057', '\143', '\040', +'\146', '\157', '\157', '\056', '\142', '\141', '\164', '\000', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\040', '\040', '\040', +'\040', '\040', '\040', '\040', '\040', '\127', '\111', '\116', +'\104', '\117', '\127', '\123', '\040', '\062', '\070', '\066', +'\040', '\063', '\056', '\060', '\000', '\377', '\377', '\033', +'\002', '\006', '\000', '\000', '\000', '\000', '\000', '\000', +'\000' +}; + +static HINSTANCE hInstance; + + +/* + *---------------------------------------------------------------------- + * + * LibMain -- + * + * 16-bit DLL entry point. + * + * Results: + * Returns 1. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +int CALLBACK +LibMain( + HINSTANCE hinst, + WORD wDS, + WORD cbHeap, + LPSTR unused) +{ + hInstance = hinst; + wDS = wDS; /* lint. */ + cbHeap = cbHeap; /* lint. */ + unused = unused; /* lint. */ + + return TRUE; +} + +/* + *---------------------------------------------------------------------- + * + * UTProc -- + * + * Universal Thunk dispatch routine. Executes a 16-bit DOS + * application or a 16-bit or 32-bit Windows application and + * waits for it to complete. + * + * Results: + * 1 if the application could be run, 0 or -1 on failure. + * + * Side effects: + * Executes 16-bit code. + * + *---------------------------------------------------------------------- + */ + +int WINAPI +UTProc(buf, func) + void *buf; + DWORD func; +{ + char **args; + + args = (char **) buf; + if (func == 0) { + return DosSpawn(args[0], args[1], args[2]); + } else { + return WinSpawn(args[0]); + } +} + +/* + *------------------------------------------------------------------------- + * + * WinSpawn -- + * + * Start a 16-bit or 32-bit Windows application with optional + * command line arguments and wait for it to finish. Windows + * applications do not handle input/output redirection. + * + * Results: + * The return value is 1 if the application could be run, 0 otherwise. + * + * Side effects: + * Whatever the application does. + * + *------------------------------------------------------------------------- + */ + +static int +WinSpawn(command) + char *command; /* The command line, consisting of the name + * of the executable to run followed by any + * number of arguments to the executable. */ +{ + return WaitForExit(WinExec(command, SW_SHOW)); +} + +/* + *--------------------------------------------------------------------------- + * + * DosSpawn -- + * + * Start a 16-bit DOS program with optional command line arguments + * and wait for it to finish. Input and output can be redirected + * from the specified files, but there is no such thing as stderr + * under Win32s. + * + * This procedure to constructs a temporary .pif file that wraps a + * temporary .bat file that runs the 16-bit application. The .bat + * file is necessary to get the redirection symbols '<' and '>' to + * work, because WinExec() doesn't accept them. The .pif file is + * necessary to cause the .bat file to run in an iconified window, + * to avoid having a large DOS box pop up, obscuring everything, and + * then almost immediately flicker out of existence, which is rather + * disconcerting. + * + * Results: + * The return value is 1 if the application could be run, 0 otherwise. + * + * Side effects: + * Whatever the application does. + * + *--------------------------------------------------------------------------- + */ + +static int +DosSpawn(command, fromFileName, toFileName) + char *command; /* The name of the program, plus any + * arguments, to be run. */ + char *fromFileName; /* Standard input for the program is to be + * redirected from this file, or NULL for no + * standard input. */ + char *toFileName; /* Standard output for the program is to be + * redirected to this file, or NULL to + * discard standard output. */ +{ + int result; + HFILE batFile, pifFile; + char batFileName[144], pifFileName[144]; + + GetTempFileName(0, "tcl", 0, batFileName); + unlink(batFileName); + strcpy(strrchr(batFileName, '.'), ".bat"); + batFile = _lcreat(batFileName, 0); + + GetTempFileName(0, "tcl", 0, pifFileName); + unlink(pifFileName); + strcpy(strrchr(pifFileName, '.'), ".pif"); + pifFile = _lcreat(pifFileName, 0); + + _lwrite(batFile, command, strlen(command)); + if (fromFileName == NULL) { + _lwrite(batFile, " < nul", 6); + } else { + _lwrite(batFile, " < ", 3); + _lwrite(batFile, fromFileName, strlen(fromFileName)); + } + if (toFileName == NULL) { + _lwrite(batFile, " > nul", 6); + } else { + _lwrite(batFile, " > ", 3); + _lwrite(batFile, toFileName, strlen(toFileName)); + } + _lwrite(batFile, "\r\n\032", 3); + _lclose(batFile); + + strcpy(pifData + 0x1c8, batFileName); + _lwrite(pifFile, pifData, sizeof(pifData)); + _lclose(pifFile); + + result = WaitForExit(WinExec(pifFileName, SW_MINIMIZE)); + + unlink(pifFileName); + unlink(batFileName); + + return result; +} + +/* + *------------------------------------------------------------------------- + * + * WaitForExit -- + * + * Wait until the application with the given instance handle has + * finished. PeekMessage() is used to yield the processor; + * otherwise, nothing else could execute on the system. + * + * Results: + * The return value is 1 if the process exited successfully, + * or 0 otherwise. + * + * Side effects: + * None. + * + *--------------------------------------------------------------------------- + */ + +static int +WaitForExit(inst) + int inst; /* Identifies the instance handle of the + * process to wait for. */ +{ + TASKENTRY te; + MSG msg; + UINT timer; + + if (inst < 32) { + return 0; + } + + te.dwSize = sizeof(te); + te.hInst = 0; + TaskFirst(&te); + do { + if (te.hInst == (HINSTANCE) inst) { + break; + } + } while (TaskNext(&te) != FALSE); + + if (te.hInst != (HINSTANCE) inst) { + return 0; + } + + timer = SetTimer(NULL, 0, 0, NULL); + while (1) { + if (GetMessage(&msg, NULL, 0, 0) != 0) { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + TaskFirst(&te); + do { + if (te.hInst == (HINSTANCE) inst) { + break; + } + } while (TaskNext(&te) != FALSE); + + if (te.hInst != (HINSTANCE) inst) { + KillTimer(NULL, timer); + return 1; + } + } +} |