stub16.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:6k
源码类别:

通讯编程

开发平台:

Visual C++

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