os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/win/stub16.c
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 /* 
     2  * stub16.c 
     3  *
     4  *	A helper program used for running 16-bit DOS applications under
     5  *	Windows 95.
     6  *
     7  * Copyright (c) 1996 by Sun Microsystems, Inc.
     8  *
     9  * See the file "license.terms" for information on usage and redistribution
    10  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    11  *
    12  * RCS: @(#) $Id: stub16.c,v 1.4 1999/04/21 21:50:34 rjohnson Exp $
    13  */
    14 
    15 #define STRICT
    16 
    17 #include <windows.h>
    18 #include <stdio.h>
    19 
    20 static HANDLE		CreateTempFile(void);
    21 
    22 /*
    23  *---------------------------------------------------------------------------
    24  *
    25  * main
    26  *
    27  *	Entry point for the 32-bit console mode app used by Windows 95 to
    28  *	help run the 16-bit program specified on the command line.
    29  *
    30  *	1. EOF on a pipe that connects a detached 16-bit process and a
    31  *	32-bit process is never seen.  So, this process runs the 16-bit
    32  *	process _attached_, and then it is run detached from the calling
    33  *	32-bit process.  
    34  * 
    35  *	2. If a 16-bit process blocks reading from or writing to a pipe,
    36  *	it never wakes up, and eventually brings the whole system down
    37  *	with it if you try to kill the process.  This app simulates
    38  *	pipes.  If any of the stdio handles is a pipe, this program
    39  *	accumulates information into temp files and forwards it to or
    40  *	from the DOS application as appropriate.  This means that this
    41  *	program must receive EOF from a stdin pipe before it will actually
    42  *	start the DOS app, and the DOS app must finish generating stdout
    43  *	or stderr before the data will be sent to the next stage of the
    44  *	pipe.  If the stdio handles are not pipes, no accumulation occurs
    45  *	and the data is passed straight through to and from the DOS
    46  *	application.
    47  *
    48  * Results:
    49  *	None.
    50  *
    51  * Side effects:
    52  *	The child process is created and this process waits for it to
    53  *	complete.
    54  *
    55  *---------------------------------------------------------------------------
    56  */
    57 
    58 int
    59 main()
    60 {
    61     DWORD dwRead, dwWrite;
    62     char *cmdLine;
    63     HANDLE hStdInput, hStdOutput, hStdError;
    64     HANDLE hFileInput, hFileOutput, hFileError;
    65     STARTUPINFO si;
    66     PROCESS_INFORMATION pi;
    67     char buf[8192];
    68     DWORD result;
    69 
    70     hFileInput = INVALID_HANDLE_VALUE;
    71     hFileOutput = INVALID_HANDLE_VALUE;
    72     hFileError = INVALID_HANDLE_VALUE;
    73     result = 1;
    74 
    75     /*
    76      * Don't get command line from argc, argv, because the command line
    77      * tokenizer will have stripped off all the escape sequences needed
    78      * for quotes and backslashes, and then we'd have to put them all
    79      * back in again.  Get the raw command line and parse off what we
    80      * want ourselves.  The command line should be of the form:
    81      *
    82      * stub16.exe program arg1 arg2 ...
    83      */
    84 
    85     cmdLine = strchr(GetCommandLine(), ' ');
    86     if (cmdLine == NULL) {
    87 	return 1;
    88     }
    89     cmdLine++;
    90 
    91     hStdInput = GetStdHandle(STD_INPUT_HANDLE);
    92     hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    93     hStdError = GetStdHandle(STD_ERROR_HANDLE);
    94 
    95     if (GetFileType(hStdInput) == FILE_TYPE_PIPE) {
    96 	hFileInput = CreateTempFile();
    97 	if (hFileInput == INVALID_HANDLE_VALUE) {
    98 	    goto cleanup;
    99 	}
   100 	while (ReadFile(hStdInput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
   101 	    if (dwRead == 0) {
   102 		break;
   103 	    }
   104 	    if (WriteFile(hFileInput, buf, dwRead, &dwWrite, NULL) == FALSE) {
   105 		goto cleanup;
   106 	    }
   107 	}
   108 	SetFilePointer(hFileInput, 0, 0, FILE_BEGIN);
   109 	SetStdHandle(STD_INPUT_HANDLE, hFileInput);
   110     }
   111     if (GetFileType(hStdOutput) == FILE_TYPE_PIPE) {
   112 	hFileOutput = CreateTempFile();
   113 	if (hFileOutput == INVALID_HANDLE_VALUE) {
   114 	    goto cleanup;
   115 	}
   116 	SetStdHandle(STD_OUTPUT_HANDLE, hFileOutput);
   117     }
   118     if (GetFileType(hStdError) == FILE_TYPE_PIPE) {
   119 	hFileError = CreateTempFile();
   120 	if (hFileError == INVALID_HANDLE_VALUE) {
   121 	    goto cleanup;
   122 	}
   123 	SetStdHandle(STD_ERROR_HANDLE, hFileError);
   124     }
   125 
   126     ZeroMemory(&si, sizeof(si));
   127     si.cb = sizeof(si);
   128     if (CreateProcess(NULL, cmdLine, NULL, NULL, TRUE, 0, NULL, NULL, &si, 
   129 	    &pi) == FALSE) {
   130 	goto cleanup;
   131     }
   132 
   133     WaitForInputIdle(pi.hProcess, 5000);
   134     WaitForSingleObject(pi.hProcess, INFINITE);
   135     GetExitCodeProcess(pi.hProcess, &result);
   136     CloseHandle(pi.hProcess);
   137     CloseHandle(pi.hThread);
   138 
   139     if (hFileOutput != INVALID_HANDLE_VALUE) {
   140 	SetFilePointer(hFileOutput, 0, 0, FILE_BEGIN);
   141 	while (ReadFile(hFileOutput, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
   142 	    if (dwRead == 0) {
   143 		break;
   144 	    }
   145 	    if (WriteFile(hStdOutput, buf, dwRead, &dwWrite, NULL) == FALSE) {
   146 		break;
   147 	    }
   148 	}
   149     }
   150     if (hFileError != INVALID_HANDLE_VALUE) {
   151 	SetFilePointer(hFileError, 0, 0, FILE_BEGIN);
   152 	while (ReadFile(hFileError, buf, sizeof(buf), &dwRead, NULL) != FALSE) {
   153 	    if (dwRead == 0) {
   154 		break;
   155 	    }
   156 	    if (WriteFile(hStdError, buf, dwRead, &dwWrite, NULL) == FALSE) {
   157 		break;
   158 	    }
   159 	}
   160     }
   161 
   162 cleanup:
   163     if (hFileInput != INVALID_HANDLE_VALUE) {
   164 	CloseHandle(hFileInput);
   165     }
   166     if (hFileOutput != INVALID_HANDLE_VALUE) {
   167 	CloseHandle(hFileOutput);
   168     }
   169     if (hFileError != INVALID_HANDLE_VALUE) {
   170 	CloseHandle(hFileError);
   171     }
   172     CloseHandle(hStdInput);
   173     CloseHandle(hStdOutput);
   174     CloseHandle(hStdError);
   175     ExitProcess(result);
   176     return 1;
   177 }
   178 
   179 static HANDLE
   180 CreateTempFile()
   181 {
   182     char name[MAX_PATH];
   183     SECURITY_ATTRIBUTES sa;
   184 
   185     if (GetTempPath(sizeof(name), name) == 0) {
   186 	return INVALID_HANDLE_VALUE;
   187     }
   188     if (GetTempFileName(name, "tcl", 0, name) == 0) {
   189 	return INVALID_HANDLE_VALUE;
   190     }
   191 
   192     sa.nLength = sizeof(sa);
   193     sa.lpSecurityDescriptor = NULL;
   194     sa.bInheritHandle = TRUE;
   195     return CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0, &sa, 
   196 	    CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
   197 	    NULL);
   198 }