/*********************************************************/
/*                                                       */
/*     Project:  Windows No Error Program Starter        */
/*                                                       */
/*      Module:  do.c                                    */
/*                                                       */
/*      Author:  Michael Meyling                         */
/*                                                       */
/*       Date:   2001-01-17                              */
/*                                                       */
/*     Version:  1.0                                     */
/*                                                       */
/*********************************************************/
/*                                                       */
/* Description:                                          */
/*                                                       */
/* Starting windows programs so that no critical         */
/* error messages pop up (e.g. no "Please insert         */
/* floppie disk in disk drive a:").                      */
/*                                                       */
/*********************************************************/
/*                                                       */
/*    History:                                           */
/*                                                       */
/*********************************************************/


/**** general includes ***********************************/

#include <stdio.h>
#include <windows.h>
#include <process.h>


/**** constants ******************************************/

#define TRACE

/**** dependend incluedes ********************************/

#ifdef TRACE
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
/* where the trace output goes */
#define stddbg stdout
#endif


/**** functions ******************************************/

int main(int argc, char* argv[]) {
	int i, j, result;
	char* command;
	char* sp;
    STARTUPINFO sinfo;
    PROCESS_INFORMATION pinfo;
    DWORD answer;

	if (argc <= 1) {
		/* nothing to do */
		printf("Program Starter, by Michael Meyling, 17. Januar 2001\n");
		printf("For starting programms that handle critical errors themself.\n\n");
		printf("Call: do <program> [args]\n");
		printf("  program   executable file (batch files must have \".bat\")\n");
		printf("  args	    arguments for program\n\n");
		return 0;
    }
	/* are there spaces in first argument? */
	if (strstr(argv[0], " ")) {
		fprintf(stderr, "Error: spaces in file path are not allowed\n");
		return 991;
    }
    if (!(command = GetCommandLine())) {
		fprintf(stderr, "Error: missing command line\n");
		return 992;
    }
    if (!(command = strstr(command, " "))) {
		fprintf(stderr, "Error: space separating second argument not found\n");
		return 993;
    }
    while (' ' == *command) {
		command++;
    }

    __try{
        SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOALIGNMENTFAULTEXCEPT
            | SEM_NOOPENFILEERRORBOX);

#ifdef TRACE
        fprintf(stddbg, "Starting: %s\n", command);
#endif

        sinfo.cb = sizeof(sinfo);
        sinfo.lpReserved=NULL;
        sinfo.lpDesktop=NULL;
        sinfo.lpTitle=NULL;
        sinfo.dwX=0;
        sinfo.dwY=0;
        sinfo.dwXSize = 400;
        sinfo.dwYSize = 400;
        sinfo.dwXCountChars=80;
        sinfo.dwYCountChars=25;
        sinfo.dwFillAttribute=0;
        sinfo.dwFlags=0;
        sinfo.wShowWindow=SW_HIDE;
        sinfo.cbReserved2=0;
        sinfo.lpReserved2=NULL;
        sinfo.hStdInput=NULL;
        sinfo.hStdOutput=NULL;
        sinfo.hStdError=NULL;

		if (!(result = CreateProcess(NULL, command, NULL, NULL, FALSE,
	            CREATE_SEPARATE_WOW_VDM, /* | DETACHED_PROCESS, */
	            NULL, NULL,
	            &sinfo, &pinfo))) {
#ifdef TRACE
            fprintf(stddbg, "Process could not be started\n");
#endif
            return 994;
        }
#ifdef TRACE
        fprintf(stddbg,"Process started, waiting for termination\n");
#endif
        WaitForSingleObject(pinfo.hProcess, INFINITE);
        i = GetExitCodeProcess(pinfo.hProcess, &answer);
        CloseHandle(pinfo.hProcess); CloseHandle(pinfo.hThread);
        if (i) {
            if (answer == STILL_ACTIVE) {
                fprintf(stderr, "Error: process still active\n");
                return 995;
            }
        } else {
            fprintf(stderr, "Error: process not found\n");
            return 996;
        }
#ifdef TRACE
        fprintf(stddbg,"Process exit code: %d\n", answer);
#endif
    }
    __except(EXCEPTION_EXECUTE_HANDLER){
        fprintf(stderr, "Unexpected exception occured.\n");
        return 999;
    }
    return answer;
}


