185 lines
4.2 KiB
C
185 lines
4.2 KiB
C
|
/*++
|
||
|
*
|
||
|
* WOW v1.0
|
||
|
*
|
||
|
* Copyright (c) 1993, Microsoft Corporation
|
||
|
*
|
||
|
* WIN.C
|
||
|
* Simple WIN.COM which spawns program given on command line.
|
||
|
* This allows DOS install which run "win appname" to work.
|
||
|
*
|
||
|
* History:
|
||
|
* Created 29-Mar-1993 Dave Hart (davehart)
|
||
|
* 20-Jul-1994 Dave Hart (davehart) Changed from console to windows app.
|
||
|
--*/
|
||
|
|
||
|
#include <windows.h>
|
||
|
|
||
|
//
|
||
|
// Support for debug output disabled for build (no console).
|
||
|
// DPRINTF macro must be used with two sets of parens:
|
||
|
// DPRINTF(("Hello %s\n", szName));
|
||
|
//
|
||
|
|
||
|
#if 0
|
||
|
#include <stdio.h>
|
||
|
#define DPRINTF(args) printf args
|
||
|
#else
|
||
|
#define DPRINTF(args)
|
||
|
#endif
|
||
|
|
||
|
|
||
|
//
|
||
|
// SKIP_BLANKS -- Handy macro to skip blanks.
|
||
|
//
|
||
|
|
||
|
#define SKIP_BLANKS(pch) {while (' ' == *(pch)) { (pch)++; }}
|
||
|
|
||
|
//
|
||
|
// SKIP_NONBLANKS -- Handy macro to skip everything but blanks.
|
||
|
//
|
||
|
|
||
|
#define SKIP_NONBLANKS(pch) {while (*(pch) && ' ' != *(pch)) { (pch)++; }}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
//
|
||
|
// WinMain
|
||
|
//
|
||
|
|
||
|
int WinMain(
|
||
|
HINSTANCE hInst,
|
||
|
HINSTANCE hPrevInst,
|
||
|
LPSTR pszCommandLine,
|
||
|
int nCmdShow
|
||
|
)
|
||
|
{
|
||
|
char *psz;
|
||
|
BOOL fSuccess;
|
||
|
DWORD dwExitCode;
|
||
|
STARTUPINFO si;
|
||
|
PROCESS_INFORMATION pi;
|
||
|
|
||
|
DPRINTF(("win.com: Command line is '%s'.\n", pszCommandLine));
|
||
|
|
||
|
//
|
||
|
// Throw away any switches on the command line. The command line
|
||
|
// looks like:
|
||
|
//
|
||
|
// win [/r] [/2] [/s] [/3] [/n] [winapp winapp-args]
|
||
|
//
|
||
|
// So we'll go into a loop of skipping all words that begin with
|
||
|
// "/" or "-" until we hit a word that doesn't start with either,
|
||
|
// which is presumably the winapp name.
|
||
|
//
|
||
|
|
||
|
psz = pszCommandLine;
|
||
|
SKIP_BLANKS(psz);
|
||
|
|
||
|
//
|
||
|
// psz now points to either the first word of our command
|
||
|
// line ("win" not included), or to a null terminator if
|
||
|
// we were invoked without arguments.
|
||
|
//
|
||
|
|
||
|
while ('-' == *psz || '/' == *psz) {
|
||
|
|
||
|
SKIP_NONBLANKS(psz);
|
||
|
|
||
|
//
|
||
|
// psz now points to either a space or the null terminator.
|
||
|
//
|
||
|
|
||
|
SKIP_BLANKS(psz);
|
||
|
|
||
|
//
|
||
|
// psz now points to either the beginning of the next word
|
||
|
// on the command line, or the null terminator.
|
||
|
//
|
||
|
|
||
|
}
|
||
|
|
||
|
if (!(*psz)) {
|
||
|
|
||
|
//
|
||
|
// If psz now points to a null terminator, then win.com was invoked
|
||
|
// either without arguments or all arguments were switches that we
|
||
|
// skipped above. So there's nothing to do!
|
||
|
//
|
||
|
|
||
|
return 0;
|
||
|
|
||
|
|
||
|
}
|
||
|
|
||
|
DPRINTF(("win.com: Invoking '%s'.\n", psz));
|
||
|
|
||
|
//
|
||
|
// Run that program.
|
||
|
//
|
||
|
|
||
|
RtlZeroMemory(&si, sizeof(si));
|
||
|
si.cb = sizeof(si);
|
||
|
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_FORCEONFEEDBACK;
|
||
|
si.wShowWindow = (WORD) nCmdShow;
|
||
|
|
||
|
fSuccess = CreateProcess(
|
||
|
NULL, // image name (in the command line instead)
|
||
|
psz, // command line (begins with image name)
|
||
|
NULL, // lpsaProcess
|
||
|
NULL, // lpsaThread
|
||
|
FALSE, // no handle inheritance
|
||
|
0, // dwCreateOptions
|
||
|
NULL, // pointer to environment
|
||
|
NULL, // pointer to curdir
|
||
|
&si, // startup info struct
|
||
|
&pi // process information (gets handles)
|
||
|
);
|
||
|
|
||
|
if (!fSuccess) {
|
||
|
|
||
|
dwExitCode = GetLastError();
|
||
|
DPRINTF(("CreateProcess fails with error %d.\n", dwExitCode));
|
||
|
return dwExitCode;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// Close the thread handle, we're only using the process handle.
|
||
|
//
|
||
|
|
||
|
CloseHandle(pi.hThread);
|
||
|
|
||
|
|
||
|
//
|
||
|
// Wait for the process to terminate and return its exit code as
|
||
|
// our exit code.
|
||
|
//
|
||
|
|
||
|
if (0xffffffff == WaitForSingleObject(pi.hProcess, INFINITE)) {
|
||
|
|
||
|
dwExitCode = GetLastError();
|
||
|
DPRINTF(("WaitForSingleObject(hProcess, INFINITE) fails with error %d.\n",
|
||
|
dwExitCode));
|
||
|
goto Cleanup;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
if (!GetExitCodeProcess(pi.hProcess, &dwExitCode)) {
|
||
|
|
||
|
dwExitCode = GetLastError();
|
||
|
DPRINTF(("GetExitCodeProcess() fails with error %d.\n", dwExitCode));
|
||
|
goto Cleanup;
|
||
|
|
||
|
}
|
||
|
|
||
|
DPRINTF(("win.com: Returning child's exit code (%d)\n", dwExitCode));
|
||
|
|
||
|
Cleanup:
|
||
|
CloseHandle(pi.hProcess);
|
||
|
return dwExitCode;
|
||
|
}
|