示例#1
0
VOID cmdReturnExitCode (VOID)
{
VDMINFO VDMInfo;
PREDIRCOMPLETE_INFO pRdrInfo;

    VDMInfo.VDMState = RETURN_ON_NO_COMMAND;
    VDMInfo.EnviornmentSize = 0;
    VDMInfo.ErrorCode = (ULONG)getDX();
    VDMInfo.CmdSize = 0;
    VDMInfo.TitleLen = 0;
    VDMInfo.ReservedLen = 0;
    VDMInfo.DesktopLen = 0;
    VDMInfo.CurDirectoryLen = 0;


    CntrlHandlerState = (CntrlHandlerState & ~CNTRL_SHELLCOUNT) |
                         (((WORD)(CntrlHandlerState & CNTRL_SHELLCOUNT))+1);

    nt_block_event_thread(0);
    fBlock = TRUE;

    // a dos program just terminate, inherit its current directories
    // and tell base too.
    cmdUpdateCurrentDirectories((BYTE)getAL());

    // Check for any copying needed for redirection
    pRdrInfo = (PREDIRCOMPLETE_INFO) (((ULONG)getBX() << 16) + (ULONG)getCX());

    if (cmdCheckCopyForRedirection (pRdrInfo) == FALSE)
            VDMInfo.ErrorCode = ERROR_NOT_ENOUGH_MEMORY;

    GetNextVDMCommand (&VDMInfo);
    if (VDMInfo.CmdSize > 0){
        setCF(1);
        IsRepeatCall = TRUE;
    }
    else {
        setCF(0);
        setAL((UCHAR)dwExitCode32);
        nt_resume_event_thread();
        nt_std_handle_notification(fSoftpcRedirectionOnShellOut);
        fBlock = FALSE;
    }

    CntrlHandlerState = (CntrlHandlerState & ~CNTRL_SHELLCOUNT) |
                         (((WORD)(CntrlHandlerState & CNTRL_SHELLCOUNT))-1);

    return;
}
示例#2
0
文件: dem.c 项目: GYGit/reactos
DWORD DosStartProcess32(IN LPCSTR ExecutablePath,
                        IN LPCSTR CommandLine,
                        IN LPCSTR Environment OPTIONAL,
                        IN DWORD ReturnAddress OPTIONAL,
                        IN BOOLEAN StartComSpec)
{
    DWORD Result = ERROR_SUCCESS;
    HANDLE CommandThread;
    DOS_START_PROC32 DosStartProc32;
#ifndef STANDALONE
    BOOL Success;
    VDM_COMMAND_INFO CommandInfo;
#endif

    DosStartProc32.ExecutablePath = (LPSTR)ExecutablePath;
    DosStartProc32.CommandLine    = (LPSTR)CommandLine;
    DosStartProc32.Environment    = (LPSTR)Environment;

#ifndef STANDALONE
    DosStartProc32.ComSpecInfo =
        RtlAllocateHeap(RtlGetProcessHeap(),
                        HEAP_ZERO_MEMORY,
                        sizeof(*DosStartProc32.ComSpecInfo));
    ASSERT(DosStartProc32.ComSpecInfo);

    DosStartProc32.hEvent = CreateEventW(NULL, FALSE, FALSE, NULL);
    ASSERT(DosStartProc32.hEvent);
#endif

    /* Pause the VM and detach from the console */
    EmulatorPause();
    DosProcessConsoleDetach();

    /* Start the 32-bit process via another thread */
    CommandThread = CreateThread(NULL, 0, &CommandThreadProc, &DosStartProc32, 0, NULL);
    if (CommandThread == NULL)
    {
        DisplayMessage(L"FATAL: Failed to create the command processing thread: %d", GetLastError());
        Result = GetLastError();
        goto Quit;
    }

#ifndef STANDALONE
    /* Close the thread handle */
    CloseHandle(CommandThread);

    /* Wait for the process to be ready to start */
    WaitForSingleObject(DosStartProc32.hEvent, INFINITE);

    /* Wait for any potential new DOS app started by the 32-bit process */
    RtlZeroMemory(&CommandInfo, sizeof(CommandInfo));

Retry:
    CommandInfo.VDMState = VDM_FLAG_NESTED_TASK | VDM_FLAG_DONT_WAIT;
    DPRINT1("Calling GetNextVDMCommand 32bit for possible new VDM task...\n");
    Success = GetNextVDMCommand(&CommandInfo);
    DPRINT1("GetNextVDMCommand 32bit awaited, success = %s, last error = %d\n", Success ? "true" : "false", GetLastError());

    /*
     * Check whether we were awaited because the 32-bit process was stopped,
     * or because it started a new DOS application.
     */
    if (CommandInfo.CmdLen != 0 || CommandInfo.AppLen != 0 || CommandInfo.PifLen != 0)
    {
        DPRINT1("GetNextVDMCommand 32bit, this is for a new VDM task - CmdLen = %d, AppLen = %d, PifLen = %d\n",
                CommandInfo.CmdLen, CommandInfo.AppLen, CommandInfo.PifLen);

        /* Repeat the request */
        Repeat = TRUE;

        /*
         * Set 'Reentry' to TRUE or FALSE depending on whether we are going
         * to reenter with a new COMMAND.COM. See the comment for:
         *     BOP_CMD 0x10 'Get start information'
         * (dem.c!DosCmdInterpreterBop) for more details.
         */
        Reentry = StartComSpec;

        /* If needed, start a new command interpreter to handle the possible incoming DOS commands */
        if (StartComSpec)
        {
            //
            // DosStartProcess32 was only called by DosCreateProcess, called from INT 21h,
            // so the caller stack is already prepared for running a new DOS program
            // (Flags, CS and IP, and the extra interrupt number, are already pushed).
            //
            Result = DosStartComSpec(FALSE, Environment, ReturnAddress,
                                     &DosStartProc32.ComSpecInfo->ComSpecPsp);
            if (Result != ERROR_SUCCESS)
            {
                DosDisplayMessage("Failed to start a new Command Interpreter (Error: %u).\n", Result);
                goto Quit;
            }
        }
        else
        {
            /* Retrieve the PSP of the COMSPEC (current PSP set by DosLoadExecutable) */
            DosStartProc32.ComSpecInfo->ComSpecPsp = Sda->CurrentPsp;
            Result = ERROR_SUCCESS;
        }

        /* Insert the new entry in the list; it will be freed when needed by COMMAND.COM */
        InsertComSpecInfo(DosStartProc32.ComSpecInfo);
    }
    else
    {
        DPRINT1("GetNextVDMCommand 32bit, 32-bit app stopped\n");

        /* Check whether this was our 32-bit app which was killed */
        if (!DosStartProc32.ComSpecInfo->Terminated)
        {
            DPRINT1("Not our 32-bit app, retrying...\n");
            goto Retry;
        }

        Result = DosStartProc32.ComSpecInfo->dwExitCode;

        /* Delete the entry */
        RtlFreeHeap(RtlGetProcessHeap(), 0, DosStartProc32.ComSpecInfo);
    }
#else
    /* Wait for the thread to finish */
    WaitForSingleObject(CommandThread, INFINITE);
    GetExitCodeThread(CommandThread, &Result);

    /* Close the thread handle */
    CloseHandle(CommandThread);

    DPRINT1("32-bit app stopped\n");
#endif

Quit:
#ifndef STANDALONE
    CloseHandle(DosStartProc32.hEvent);
#endif

    /* Attach to the console and resume the VM */
    DosProcessConsoleAttach();
    EmulatorResume();

    return Result;
}
示例#3
0
文件: dem.c 项目: GYGit/reactos
static DWORD
WINAPI
CommandThreadProc(LPVOID Parameter)
{
    BOOL Success;
    PROCESS_INFORMATION ProcessInfo;
    STARTUPINFOA StartupInfo;
    DWORD dwExitCode;
    PDOS_START_PROC32 DosStartProc32 = (PDOS_START_PROC32)Parameter;
#ifndef STANDALONE
    VDM_COMMAND_INFO CommandInfo;
    PCOMSPEC_INFO ComSpecInfo = DosStartProc32->ComSpecInfo;
#endif

    /* Set up the VDM, startup and process info structures */
#ifndef STANDALONE
    RtlZeroMemory(&CommandInfo, sizeof(CommandInfo));
#endif
    RtlZeroMemory(&ProcessInfo, sizeof(ProcessInfo));
    RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
    StartupInfo.cb = sizeof(StartupInfo);

    // FIXME: Build suitable 32-bit environment!!

#ifndef STANDALONE
    /*
     * Wait for signaling a new VDM task and increment the VDM re-entry count so
     * that we can handle 16-bit apps that may be possibly started by the 32-bit app.
     */
    CommandInfo.VDMState = VDM_INC_REENTER_COUNT;
    DPRINT1("Calling GetNextVDMCommand reenter++\n");
    Success = GetNextVDMCommand(&CommandInfo);
    DPRINT1("GetNextVDMCommand reenter++ success = %s, last error = %d\n", Success ? "true" : "false", GetLastError());
    ++ReentrancyCount;
#endif

    /* Start the process */
    Success = CreateProcessA(NULL, // ProgramName,
                             DosStartProc32->CommandLine,
                             NULL,
                             NULL,
                             TRUE, // Inherit handles
                             CREATE_DEFAULT_ERROR_MODE | CREATE_SUSPENDED,
                             DosStartProc32->Environment,
                             NULL, // lpCurrentDirectory, see "START" command in cmd.exe
                             &StartupInfo,
                             &ProcessInfo);

#ifndef STANDALONE
    /* Signal our caller the process was started */
    SetEvent(DosStartProc32->hEvent);
    // After this point, 'DosStartProc32' is not valid anymore.
#endif

    if (Success)
    {
        /* Resume the process */
        ResumeThread(ProcessInfo.hThread);

        /* Wait for the process to finish running and retrieve its exit code */
        WaitForSingleObject(ProcessInfo.hProcess, INFINITE);
        GetExitCodeProcess(ProcessInfo.hProcess, &dwExitCode);

        /* Close the handles */
        CloseHandle(ProcessInfo.hThread);
        CloseHandle(ProcessInfo.hProcess);
    }
    else
    {
        dwExitCode = GetLastError();
    }

#ifndef STANDALONE
    ASSERT(ComSpecInfo);
    ComSpecInfo->Terminated = TRUE;
    ComSpecInfo->dwExitCode = dwExitCode;

    /* Decrement the VDM re-entry count */
    CommandInfo.VDMState = VDM_DEC_REENTER_COUNT;
    DPRINT1("Calling GetNextVDMCommand reenter--\n");
    Success = GetNextVDMCommand(&CommandInfo);
    DPRINT1("GetNextVDMCommand reenter-- success = %s, last error = %d\n", Success ? "true" : "false", GetLastError());
    --ReentrancyCount;

    return 0;
#else
    return dwExitCode;
#endif
}
示例#4
0
文件: dem.c 项目: GYGit/reactos
static VOID CmdSetExitCode(VOID)
{
#ifndef STANDALONE
    BOOL Success;
    PCOMSPEC_INFO ComSpecInfo;
    VDM_COMMAND_INFO CommandInfo;
#endif

    /* Pause the VM */
    EmulatorPause();

#ifndef STANDALONE
    /*
     * Check whether we need to shell out now in case we were started by a 32-bit app,
     * or we were started alone along with the root 32-bit app.
     */
    ComSpecInfo = FindComSpecInfoByPsp(Sda->CurrentPsp);
    if ((ComSpecInfo && ComSpecInfo->Terminated) ||
        (ComSpecInfo == &RootCmd && SessionId != 0))
    {
        RemoveComSpecInfo(ComSpecInfo);
#endif
        DPRINT1("Exit DOS from ExitCode (prologue)!\n");
        setCF(0);
        goto Quit;
#ifndef STANDALONE
    }

    /* Clear the VDM structure */
    RtlZeroMemory(&CommandInfo, sizeof(CommandInfo));

Retry:
    /* Update the VDM state of the task */
    // CommandInfo.TaskId = SessionId;
    CommandInfo.ExitCode = getDX();
    CommandInfo.VDMState = VDM_FLAG_DONT_WAIT;
    DPRINT1("Calling GetNextVDMCommand 32bit end of VDM task\n");
    Success = GetNextVDMCommand(&CommandInfo);
    DPRINT1("GetNextVDMCommand 32bit end of VDM task success = %s, last error = %d\n", Success ? "true" : "false", GetLastError());

    /*
     * Check whether we were awaited because the 32-bit process was stopped,
     * or because it started a new DOS application.
     */
    if (CommandInfo.CmdLen != 0 || CommandInfo.AppLen != 0 || CommandInfo.PifLen != 0)
    {
        DPRINT1("GetNextVDMCommand end-of-app, this is for a new VDM task - CmdLen = %d, AppLen = %d, PifLen = %d\n",
                CommandInfo.CmdLen, CommandInfo.AppLen, CommandInfo.PifLen);

        /* Repeat the request */
        Repeat = TRUE;
        setCF(1);
    }
    else
    {
        DPRINT1("GetNextVDMCommand end-of-app, the app stopped\n");

        /* Check whether we need to shell out now in case we were started by a 32-bit app */
        ComSpecInfo = FindComSpecInfoByPsp(Sda->CurrentPsp);
        if (!ComSpecInfo || !ComSpecInfo->Terminated)
        {
            DPRINT1("Not our 32-bit app, retrying...\n");
            goto Retry;
        }

        ASSERT(ComSpecInfo->Terminated == TRUE);

        /* Record found, remove it and exit now */
        RemoveComSpecInfo(ComSpecInfo);

        DPRINT1("Exit DOS from ExitCode wait!\n");
        setCF(0);
    }
#endif

    // FIXME: Use the retrieved exit code as the value of our exit code
    // when COMMAND.COM will shell-out ??

Quit:
    /* Resume the VM */
    EmulatorResume();
}
示例#5
0
文件: dem.c 项目: GYGit/reactos
static VOID CmdStartProcess(VOID)
{
#ifndef STANDALONE
    PCOMSPEC_INFO ComSpecInfo;
#endif
    SIZE_T CmdLen;
    PNEXT_CMD DataStruct = (PNEXT_CMD)SEG_OFF_TO_PTR(getDS(), getDX());

    DPRINT1("CmdStartProcess -- DS:DX = %04X:%04X (DataStruct = 0x%p)\n",
            getDS(), getDX(), DataStruct);

    /* Pause the VM */
    EmulatorPause();

#ifndef STANDALONE
    /* Check whether we need to shell out now in case we were started by a 32-bit app */
    ComSpecInfo = FindComSpecInfoByPsp(Sda->CurrentPsp);
    if (ComSpecInfo && ComSpecInfo->Terminated)
    {
        RemoveComSpecInfo(ComSpecInfo);

        DPRINT1("Exit DOS from start-app BOP\n");
        setCF(1);
        goto Quit;
    }

    /* Clear the structure */
    RtlZeroMemory(&CommandInfo, sizeof(CommandInfo));

    /* Initialize the structure members */
    CommandInfo.TaskId = SessionId;
    CommandInfo.VDMState = VDM_FLAG_DOS;
    CommandInfo.CmdLine = CmdLine;
    CommandInfo.CmdLen = sizeof(CmdLine);
    CommandInfo.AppName = AppName;
    CommandInfo.AppLen = sizeof(AppName);
    CommandInfo.PifFile = PifFile;
    CommandInfo.PifLen = sizeof(PifFile);
    CommandInfo.CurDirectory = CurDirectory;
    CommandInfo.CurDirectoryLen = sizeof(CurDirectory);
    CommandInfo.Desktop = Desktop;
    CommandInfo.DesktopLen = sizeof(Desktop);
    CommandInfo.Title = Title;
    CommandInfo.TitleLen = sizeof(Title);
    CommandInfo.Env = Env;
    CommandInfo.EnvLen = EnvSize;

    if (First) CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;

Command:

    if (Repeat) CommandInfo.VDMState |= VDM_FLAG_RETRY;
    Repeat = FALSE;

    /* Get the VDM command information */
    DPRINT1("Calling GetNextVDMCommand in CmdStartProcess: wait for new VDM task...\n");
    if (!GetNextVDMCommand(&CommandInfo))
    {
        DPRINT1("CmdStartProcess - GetNextVDMCommand failed, retrying... last error = %d\n", GetLastError());
        if (CommandInfo.EnvLen > EnvSize)
        {
            /* Expand the environment size */
            EnvSize = CommandInfo.EnvLen;
            CommandInfo.Env = Env = RtlReAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Env, EnvSize);

            /* Repeat the request */
            Repeat = TRUE;
            goto Command;
        }

        /* Shouldn't happen */
        DisplayMessage(L"An unrecoverable failure happened from start-app BOP; exiting DOS.");
        setCF(1);
        goto Quit;
    }

    // FIXME: What happens if some other 32-bit app is killed while we are waiting there??

    DPRINT1("CmdStartProcess - GetNextVDMCommand succeeded, start app...\n");

#else

    if (!First)
    {
        DPRINT1("Exit DOS from start-app BOP\n");
        setCF(1);
        goto Quit;
    }

#endif

    /* Compute the command line length, not counting the terminating "\r\n" */
    CmdLen = strlen(CmdLine);
    if (CmdLen >= 2 && CmdLine[CmdLen - 2] == '\r')
        CmdLen -= 2;

    DPRINT1("Starting '%s' ('%.*s')...\n", AppName, CmdLen, CmdLine);

    /* Start the process */
    // FIXME: Merge 'Env' with the master environment SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0)
    // FIXME: Environment
    RtlCopyMemory(SEG_OFF_TO_PTR(DataStruct->AppNameSeg, DataStruct->AppNameOff), AppName, MAX_PATH);
    *(PBYTE)(SEG_OFF_TO_PTR(DataStruct->CmdLineSeg, DataStruct->CmdLineOff)) = (BYTE)CmdLen;
    RtlCopyMemory(SEG_OFF_TO_PTR(DataStruct->CmdLineSeg, DataStruct->CmdLineOff + 1), CmdLine, DOS_CMDLINE_LENGTH);

#ifndef STANDALONE
    /* Update console title if we run in a separate console */
    if (SessionId != 0)
        SetConsoleTitleA(AppName);
#endif

    First = FALSE;
    setCF(0);

    DPRINT1("App started!\n");

Quit:
    /* Resume the VM */
    EmulatorResume();
}
示例#6
0
文件: dem.c 项目: GYGit/reactos
static VOID WINAPI DosStart(LPWORD Stack)
{
    BOOLEAN Success;
    DWORD Result;
#ifndef STANDALONE
    INT i;
#endif

    DPRINT("DosStart\n");

    /*
     * We succeeded, deregister the DOS Starting BOP
     * so that no app will be able to call us back.
     */
    RegisterBop(BOP_START_DOS, NULL);

    /* Initialize the callback context */
    InitializeContext(&DosContext, BIOS_CODE_SEGMENT, 0x0010);

    Success  = DosBIOSInitialize();
//  Success &= DosKRNLInitialize();
    if (!Success)
    {
        BiosDisplayMessage("DOS32 loading failed (Error: %u). The VDM will shut down.\n", GetLastError());
        EmulatorTerminate();
        return;
    }

    /* Load the mouse driver */
    DosMouseInitialize();

#ifndef STANDALONE

    /* Parse the command line arguments */
    for (i = 1; i < NtVdmArgc; i++)
    {
        if (wcsncmp(NtVdmArgv[i], L"-i", 2) == 0)
        {
            /* This is the session ID (hex format) */
            SessionId = wcstoul(NtVdmArgv[i] + 2, NULL, 16);
        }
    }

    /* Initialize Win32-VDM environment */
    Env = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, EnvSize);
    if (Env == NULL)
    {
        DosDisplayMessage("Failed to initialize the global environment (Error: %u). The VDM will shut down.\n", GetLastError());
        EmulatorTerminate();
        return;
    }

    /* Clear the structure */
    RtlZeroMemory(&CommandInfo, sizeof(CommandInfo));

    /* Get the initial information */
    CommandInfo.TaskId = SessionId;
    CommandInfo.VDMState = VDM_GET_FIRST_COMMAND | VDM_FLAG_DOS;
    GetNextVDMCommand(&CommandInfo);

#else

    /* Retrieve the command to start */
    if (NtVdmArgc >= 2)
    {
        WideCharToMultiByte(CP_ACP, 0, NtVdmArgv[1], -1, AppName, sizeof(AppName), NULL, NULL);

        if (NtVdmArgc >= 3)
            WideCharToMultiByte(CP_ACP, 0, NtVdmArgv[2], -1, CmdLine, sizeof(CmdLine), NULL, NULL);
        else
            strcpy(CmdLine, "");
    }
    else
    {
        DosDisplayMessage("Invalid DOS command line\n");
        EmulatorTerminate();
        return;
    }

#endif

    /*
     * At this point, CS:IP points to the DOS BIOS exit code. If the
     * root command interpreter fails to start (or if it exits), DOS
     * exits and the VDM terminates.
     */

    /* Start the root command interpreter */
    // TODO: Really interpret the 'SHELL=' line of CONFIG.NT, and use it!

    /*
     * Prepare the stack for DosStartComSpec:
     * push Flags, CS and IP, and an extra WORD.
     */
    setSP(getSP() - sizeof(WORD));
    *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = (WORD)getEFLAGS();
    setSP(getSP() - sizeof(WORD));
    *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = getCS();
    setSP(getSP() - sizeof(WORD));
    *((LPWORD)SEG_OFF_TO_PTR(getSS(), getSP())) = getIP();
    setSP(getSP() - sizeof(WORD));

    Result = DosStartComSpec(TRUE, SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0),
                             MAKELONG(getIP(), getCS()),
#ifndef STANDALONE
                             &RootCmd.ComSpecPsp
#else
                             NULL
#endif
                             );
    if (Result != ERROR_SUCCESS)
    {
        /* Unprepare the stack for DosStartComSpec */
        setSP(getSP() + 4*sizeof(WORD));

        DosDisplayMessage("Failed to start the Command Interpreter (Error: %u). The VDM will shut down.\n", Result);
        EmulatorTerminate();
        return;
    }

#ifndef STANDALONE
    RootCmd.Terminated = FALSE;
    InsertComSpecInfo(&RootCmd);
#endif

    /**/
    /* Attach to the console and resume the VM */
    DosProcessConsoleAttach();
    EmulatorResume();
    /**/

    return;
}
示例#7
0
VOID cmdExec32 (PCHAR pCmd32, PCHAR pEnv)
{

    DWORD dwThreadId;
    HANDLE hThread;

    pCommand32 = pCmd32;
    pEnv32 = pEnv;

    CntrlHandlerState = (CntrlHandlerState & ~CNTRL_SHELLCOUNT) |
                         (((WORD)(CntrlHandlerState & CNTRL_SHELLCOUNT))+1);

    nt_block_event_thread(0);
    fSoftpcRedirectionOnShellOut = fSoftpcRedirection;
    fBlock = TRUE;

    if((hThread = CreateThread (NULL,
                     0,
                     (LPTHREAD_START_ROUTINE)cmdCreateProcess,
                     NULL,
                     0,
                     &dwThreadId)) == FALSE) {
        setCF(0);
	setAL((UCHAR)GetLastError());
        nt_resume_event_thread();
        nt_std_handle_notification(fSoftpcRedirectionOnShellOut);
        fBlock = FALSE;
        CntrlHandlerState = (CntrlHandlerState & ~CNTRL_SHELLCOUNT) |
                         (((WORD)(CntrlHandlerState & CNTRL_SHELLCOUNT))-1);
        return;
    }
    else
        CloseHandle (hThread);

    // Wait for next command to be re-entered
    VDMInfo.VDMState = NO_PARENT_TO_WAKE | RETURN_ON_NO_COMMAND;
    VDMInfo.EnviornmentSize = 0;
    VDMInfo.ErrorCode = 0;
    VDMInfo.CmdSize = 0;
    VDMInfo.TitleLen = 0;
    VDMInfo.ReservedLen = 0;
    VDMInfo.DesktopLen = 0;
    VDMInfo.CurDirectoryLen = 0;
    GetNextVDMCommand (&VDMInfo);
    if (VDMInfo.CmdSize > 0){
        setCF(1);
        IsRepeatCall = TRUE;
    }
    else {
        setCF(0);
        setAL((UCHAR)dwExitCode32);
        nt_resume_event_thread();
        nt_std_handle_notification(fSoftpcRedirectionOnShellOut);
        fBlock = FALSE;
    }


    CntrlHandlerState = (CntrlHandlerState & ~CNTRL_SHELLCOUNT) |
                         (((WORD)(CntrlHandlerState & CNTRL_SHELLCOUNT))-1);
    return;
}
示例#8
0
VOID cmdCreateProcess ( VOID )
{

    VDMINFO VDMInfoForCount;
    STARTUPINFO StartupInfo;
    PROCESS_INFORMATION ProcessInformation;
    HANDLE hStd16In,hStd16Out,hStd16Err;
    CHAR CurDirVar [] = "=?:";
    CHAR Buffer [MAX_DIR];
    CHAR *CurDir = Buffer;
    DWORD dwRet;
    BOOL  Status;
    NTSTATUS NtStatus;
    UNICODE_STRING Unicode;
    OEM_STRING	   OemString;
    LPVOID lpNewEnv=NULL;
    PSTD_HANDLES pStdHandles;
    ANSI_STRING Env_A;

    // we have one more 32 executable active
    Exe32ActiveCount++;

    // Increment the Re-enterancy count for the VDM
    VDMInfoForCount.VDMState = INCREMENT_REENTER_COUNT;
    GetNextVDMCommand (&VDMInfoForCount);

    RtlZeroMemory((PVOID)&StartupInfo,sizeof(STARTUPINFO));
    StartupInfo.cb = sizeof(STARTUPINFO);

    CurDirVar [1] = chDefaultDrive;

    dwRet = GetEnvironmentVariable (CurDirVar,Buffer,MAX_DIR);

    if (dwRet == 0 || dwRet == MAX_DIR)
	CurDir = NULL;

    pStdHandles = (PSTD_HANDLES) GetVDMAddr (getSS(), getBP());
    if ((hStd16In = (HANDLE) FETCHDWORD(pStdHandles->hStdIn)) != (HANDLE)-1)
        SetStdHandle (STD_INPUT_HANDLE, hStd16In);

    if ((hStd16Out = (HANDLE) FETCHDWORD(pStdHandles->hStdOut)) != (HANDLE)-1)
        SetStdHandle (STD_OUTPUT_HANDLE, hStd16Out);

    if ((hStd16Err = (HANDLE) FETCHDWORD(pStdHandles->hStdErr)) != (HANDLE)-1)
        SetStdHandle (STD_ERROR_HANDLE, hStd16Err);

    /*
     *  Warning, pEnv32 currently points to an ansi environment.
     *  The DOS is using an ANSI env which isn't quite correct.
     *  If the DOS is changed to use an OEM env then we will
     *  have to convert the env back to ansi before spawning
     *  non-dos exes ?!?
     *  16-Jan-1993 Jonle
     */

    Env_A.Buffer = NULL;

    RtlInitString((PSTRING)&OemString, pCommand32);
    NtStatus = RtlOemStringToUnicodeString(&Unicode,&OemString,TRUE);
    if (NT_SUCCESS(NtStatus)) {
        NtStatus = RtlUnicodeStringToAnsiString((PANSI_STRING)&OemString, &Unicode, FALSE);
        RtlFreeUnicodeString( &Unicode );
        }
    if (!NT_SUCCESS(NtStatus)) {
        SetLastError(RtlNtStatusToDosError(NtStatus));
        Status = FALSE;
        }
    else {
	if (pEnv32 != NULL && !cmdXformEnvironment (pEnv32, &Env_A)) {
	    SetLastError(ERROR_NOT_ENOUGH_MEMORY);
	    Status = FALSE;
	}
	else {

	    Status = CreateProcess (
                           NULL,
                           (LPTSTR)pCommand32,
                           NULL,
                           NULL,
                           TRUE,
                           CREATE_SUSPENDED | CREATE_DEFAULT_ERROR_MODE,
			   Env_A.Buffer,
                           (LPTSTR)CurDir,
                           &StartupInfo,
			   &ProcessInformation);
	}
    }

    if (Status == FALSE)
        dwExitCode32 = GetLastError ();

    if (hStd16In != (HANDLE)-1)
        SetStdHandle (STD_INPUT_HANDLE, SCS_hStdIn);

    if (hStd16Out != (HANDLE)-1)
        SetStdHandle (STD_OUTPUT_HANDLE, SCS_hStdOut);

    if (hStd16Err != (HANDLE)-1)
        SetStdHandle (STD_ERROR_HANDLE, SCS_hStdErr);

    if (Status) {
	ResumeThread (ProcessInformation.hThread);
        WaitForSingleObject(ProcessInformation.hProcess, (DWORD)-1);
        GetExitCodeProcess (ProcessInformation.hProcess, &dwExitCode32);
        CloseHandle (ProcessInformation.hProcess);
        CloseHandle (ProcessInformation.hThread);
    }

    if (Env_A.Buffer)
	RtlFreeAnsiString(&Env_A);

    // Decrement the Re-enterancy count for the VDM
    VDMInfoForCount.VDMState = DECREMENT_REENTER_COUNT;
    GetNextVDMCommand (&VDMInfoForCount);

    // one less 32 executable active
    Exe32ActiveCount--;

    // Kill this thread
    ExitThread (0);
}
示例#9
0
文件: dem.c 项目: staring/RosFE
static DWORD
WINAPI
CommandThreadProc(LPVOID Parameter)
{
    BOOLEAN First = TRUE;
    DWORD Result;
    VDM_COMMAND_INFO CommandInfo;
    CHAR CmdLine[MAX_PATH];
    CHAR AppName[MAX_PATH];
    CHAR PifFile[MAX_PATH];
    CHAR Desktop[MAX_PATH];
    CHAR Title[MAX_PATH];
    ULONG EnvSize = 256;
    PVOID Env = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, EnvSize);

    UNREFERENCED_PARAMETER(Parameter);
    ASSERT(Env != NULL);

    do
    {
        /* Clear the structure */
        RtlZeroMemory(&CommandInfo, sizeof(CommandInfo));

        /* Initialize the structure members */
        CommandInfo.TaskId = SessionId;
        CommandInfo.VDMState = VDM_FLAG_DOS;
        CommandInfo.CmdLine = CmdLine;
        CommandInfo.CmdLen = sizeof(CmdLine);
        CommandInfo.AppName = AppName;
        CommandInfo.AppLen = sizeof(AppName);
        CommandInfo.PifFile = PifFile;
        CommandInfo.PifLen = sizeof(PifFile);
        CommandInfo.Desktop = Desktop;
        CommandInfo.DesktopLen = sizeof(Desktop);
        CommandInfo.Title = Title;
        CommandInfo.TitleLen = sizeof(Title);
        CommandInfo.Env = Env;
        CommandInfo.EnvLen = EnvSize;

        if (First) CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;

Command:
        if (!GetNextVDMCommand(&CommandInfo))
        {
            if (CommandInfo.EnvLen > EnvSize)
            {
                /* Expand the environment size */
                EnvSize = CommandInfo.EnvLen;
                Env = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Env, EnvSize);

                /* Repeat the request */
                goto Command;
            }

            break;
        }

        /* Start the process from the command line */
        DPRINT1("Starting '%s' ('%s')...\n", AppName, CmdLine);
        Result = DosStartProcess(AppName, CmdLine, Env);
        if (Result != ERROR_SUCCESS)
        {
            DisplayMessage(L"Could not start '%S'. Error: %u", AppName, Result);
            // break;
            continue;
        }

        First = FALSE;
    }
    while (AcceptCommands);

    HeapFree(GetProcessHeap(), 0, Env);
    return 0;
}