static VOID WINAPI DosCmdInterpreterBop(LPWORD Stack) { /* Get the Function Number and skip it */ BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP()); setIP(getIP() + 1); switch (FuncNum) { case 0x08: // Launch external command { #define CMDLINE_LENGTH 1024 BOOL Result; DWORD dwExitCode; LPSTR Command = (LPSTR)SEG_OFF_TO_PTR(getDS(), getSI()); LPSTR CmdPtr = Command; CHAR CommandLine[CMDLINE_LENGTH] = ""; STARTUPINFOA StartupInfo; PROCESS_INFORMATION ProcessInformation; /* NULL-terminate the command line by removing the return carriage character */ while (*CmdPtr && *CmdPtr != '\r') CmdPtr++; *CmdPtr = '\0'; DPRINT1("CMD Run Command '%s'\n", Command); /* Spawn a user-defined 32-bit command preprocessor */ /* Build the command line */ // FIXME: Use COMSPEC env var!! strcpy(CommandLine, "cmd.exe /c "); strcat(CommandLine, Command); ZeroMemory(&StartupInfo, sizeof(StartupInfo)); ZeroMemory(&ProcessInformation, sizeof(ProcessInformation)); StartupInfo.cb = sizeof(StartupInfo); VidBiosDetachFromConsole(); Result = CreateProcessA(NULL, CommandLine, NULL, NULL, TRUE, 0, NULL, NULL, &StartupInfo, &ProcessInformation); if (Result) { DPRINT1("Command '%s' launched successfully\n", Command); /* Wait for process termination */ WaitForSingleObject(ProcessInformation.hProcess, INFINITE); /* Get the exit code */ GetExitCodeProcess(ProcessInformation.hProcess, &dwExitCode); /* Close handles */ CloseHandle(ProcessInformation.hThread); CloseHandle(ProcessInformation.hProcess); } else { DPRINT1("Failed when launched command '%s'\n"); dwExitCode = GetLastError(); } VidBiosAttachToConsole(); setAL((UCHAR)dwExitCode); break; } default: { DPRINT1("Unknown DOS CMD Interpreter BOP Function: 0x%02X\n", FuncNum); // setCF(1); // Disable, otherwise we enter an infinite loop break; } } }
static VOID DosProcessConsoleDetach(VOID) { /* Detach from the console */ VidBiosDetachFromConsole(); ConsoleDetach(); }