示例#1
0
文件: dem.c 项目: GYGit/reactos
static VOID CmdStartExternalCommand(VOID)
{
    DWORD Result;

    // TODO: improve: this code has strong similarities
    // with the 'default' case of DosCreateProcess.

    LPSTR Command = (LPSTR)SEG_OFF_TO_PTR(getDS(), getSI());
    CHAR CmdLine[sizeof("cmd.exe /c ") + DOS_CMDLINE_LENGTH + 1] = "";
    LPSTR CmdLinePtr;
    ULONG CmdLineLen;

    /* Spawn a user-defined 32-bit command preprocessor */

    // FIXME: Use COMSPEC env var!!
    CmdLinePtr = CmdLine;
    strcpy(CmdLinePtr, "cmd.exe /c ");
    CmdLinePtr += strlen(CmdLinePtr);

    /* Build a Win32-compatible command-line */
    CmdLineLen = min(strlen(Command), sizeof(CmdLine) - strlen(CmdLinePtr) - 1);
    RtlCopyMemory(CmdLinePtr, Command, CmdLineLen);
    CmdLinePtr[CmdLineLen] = '\0';

    /* Remove any trailing return carriage character and NULL-terminate the command line */
    while (*CmdLinePtr && *CmdLinePtr != '\r' && *CmdLinePtr != '\n') CmdLinePtr++;
    *CmdLinePtr = '\0';

    DPRINT1("CMD Run Command '%s' ('%s')\n", Command, CmdLine);

    /*
     * No need to prepare the stack for DosStartComSpec since we won't start it.
     */
    Result = DosStartProcess32(Command, CmdLine,
                               SEG_OFF_TO_PTR(getES(), 0) /*Environment*/,
                               MAKELONG(getIP(), getCS()) /*ReturnAddress*/,
                               FALSE);
    if (Result != ERROR_SUCCESS)
    {
        DosDisplayMessage("Failed to start command '%s' ('%s'). Error: %u\n", Command, CmdLine, Result);
        setCF(0);
        setAL((UCHAR)Result);
    }
    else
    {
        DosDisplayMessage("Command '%s' ('%s') started successfully.\n", Command, CmdLine);
#ifndef STANDALONE
        setCF(Repeat); // Set CF if we need to start a 16-bit process
#else
        setCF(0);
#endif
    }
}
示例#2
0
文件: cpu.c 项目: staring/RosFE
VOID EmulatorException(BYTE ExceptionNumber, LPWORD Stack)
{
    WORD CodeSegment, InstructionPointer;
    PBYTE Opcode;

    ASSERT(ExceptionNumber < 8);

    /* Get the CS:IP */
    InstructionPointer = Stack[STACK_IP];
    CodeSegment = Stack[STACK_CS];
    Opcode = (PBYTE)SEG_OFF_TO_PTR(CodeSegment, InstructionPointer);

    /* Display a message to the user */
    DisplayMessage(L"Exception: %s occured at %04X:%04X\n"
                   L"Opcode: %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X",
                   ExceptionName[ExceptionNumber],
                   CodeSegment,
                   InstructionPointer,
                   Opcode[0],
                   Opcode[1],
                   Opcode[2],
                   Opcode[3],
                   Opcode[4],
                   Opcode[5],
                   Opcode[6],
                   Opcode[7],
                   Opcode[8],
                   Opcode[9]);

    /* Stop the VDM */
    EmulatorTerminate();
    return;
}
示例#3
0
BOOLEAN DiskBios32Initialize(VOID)
{
    /*
     * Initialize BIOS Disk ROM static data
     */

    /* Floppy Parameter Table */
    RtlCopyMemory(SEG_OFF_TO_PTR(BIOS_SEGMENT, 0xEFC7),
                  &FloppyParamTable.FloppyParamTable,
                  sizeof(FloppyParamTable.FloppyParamTable));

    //
    // FIXME: Must be done by HW floppy controller!
    //

    /* Detect and initialize the supported disks */
    // TODO: the "Detect" part is missing.
    FloppyDrive[0] = RetrieveDisk(FLOPPY_DISK, 0);
    FloppyDrive[1] = RetrieveDisk(FLOPPY_DISK, 1);
    HardDrive[0]   = RetrieveDisk(HARD_DISK, 0);
    HardDrive[1]   = RetrieveDisk(HARD_DISK, 1);
    HardDrive[2]   = RetrieveDisk(HARD_DISK, 2);
    HardDrive[3]   = RetrieveDisk(HARD_DISK, 3);

    return TRUE;
}
示例#4
0
文件: dem.c 项目: hackbunny/reactos
static VOID WINAPI DosSystemBop(LPWORD Stack)
{
    /* Get the Function Number and skip it */
    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
    setIP(getIP() + 1);

    switch (FuncNum)
    {
        case 0x11:  // Load the DOS kernel
        {
            BOOLEAN Success = FALSE;
            HANDLE  hDosKernel;
            ULONG   ulDosKernelSize = 0;

            DPRINT1("You are loading Windows NT DOS!\n");

            /* Open the DOS kernel file */
            hDosKernel = FileOpen("ntdos.sys", &ulDosKernelSize);

            /* If we failed, bail out */
            if (hDosKernel == NULL) goto Quit;

            /*
             * Attempt to load the DOS kernel into memory.
             * The segment where to load the DOS kernel is defined
             * by the DOS BIOS and is found in DI:0000 .
             */
            Success = FileLoadByHandle(hDosKernel,
                                       REAL_TO_PHYS(TO_LINEAR(getDI(), 0x0000)),
                                       ulDosKernelSize,
                                       &ulDosKernelSize);

            DPRINT1("Windows NT DOS loading %s at 0x%04X:0x%04X, size 0x%x ; GetLastError() = %u\n",
                    (Success ? "succeeded" : "failed"),
                    getDI(), 0x0000,
                    ulDosKernelSize,
                    GetLastError());

            /* Close the DOS kernel file */
            FileClose(hDosKernel);

Quit:
            if (!Success)
            {
                /* We failed everything, stop the VDM */
                EmulatorTerminate();
            }

            break;
        }

        default:
        {

            DPRINT1("Unknown DOS System BOP Function: 0x%02X\n", FuncNum);
            // setCF(1); // Disable, otherwise we enter an infinite loop
            break;
        }
    }
}
示例#5
0
文件: country.c 项目: GYGit/reactos
BOOLEAN DosCountryInitialize(VOID)
{
    UINT i;

    /* Initialize some memory to store country information */
    // FIXME: Can we use instead some static area from the DOS data structure??
    CountryDataSegment = DosAllocateMemory(sizeof(COUNTRY_DATA), NULL);
    if (CountryDataSegment == 0) return FALSE;
    CountryData = (PCOUNTRY_DATA)SEG_OFF_TO_PTR(CountryDataSegment, 0x0000);

    RtlMoveMemory(CountryData->CaseMapRoutine,
                  CaseMapRoutine,
                  sizeof(CaseMapRoutine));

    CountryData->UpCaseTbl.Size = ARRAYSIZE(CountryData->UpCaseTbl.Data);
    for (i = 0; i < CountryData->UpCaseTbl.Size; ++i)
        CountryData->UpCaseTbl.Data[i] = 0x80 + i;

    CountryData->LoCaseTbl.Size = ARRAYSIZE(CountryData->LoCaseTbl.Data);
    for (i = 0; i < CountryData->LoCaseTbl.Size; ++i)
        CountryData->LoCaseTbl.Data[i] = i;

    CountryData->FNameTermTbl.Size = ARRAYSIZE(CountryData->FNameTermTbl.Data);
    CountryData->FNameTermTbl.Data[ 0] = 0x01; // Dummy Byte
    CountryData->FNameTermTbl.Data[ 1] = 0x00; //  Lowest permissible Character Value for Filename
    CountryData->FNameTermTbl.Data[ 2] = 0xFF; // Highest permissible Character Value for Filename
    CountryData->FNameTermTbl.Data[ 3] = 0x00; // Dummy Byte
    CountryData->FNameTermTbl.Data[ 4] = 0x00; // First excluded Character in Range \ all characters in this
    CountryData->FNameTermTbl.Data[ 5] = 0x20; //  Last excluded Character in Range / range are illegal
    CountryData->FNameTermTbl.Data[ 6] = 0x02; // Dummy Byte
    CountryData->FNameTermTbl.Data[ 7] = 14;   // Number of illegal (terminator) Characters
//  CountryData->FNameTermTbl.Data[ 8] = ".\"/\\[]:|<>+=;,"; // Characters which terminate a Filename
    CountryData->FNameTermTbl.Data[ 8] = '.';
    CountryData->FNameTermTbl.Data[ 9] = '\"';
    CountryData->FNameTermTbl.Data[10] = '/';
    CountryData->FNameTermTbl.Data[11] = '\\';
    CountryData->FNameTermTbl.Data[12] = '[';
    CountryData->FNameTermTbl.Data[13] = ']';
    CountryData->FNameTermTbl.Data[14] = ':';
    CountryData->FNameTermTbl.Data[15] = '|';
    CountryData->FNameTermTbl.Data[16] = '<';
    CountryData->FNameTermTbl.Data[17] = '>';
    CountryData->FNameTermTbl.Data[18] = '+';
    CountryData->FNameTermTbl.Data[19] = '=';
    CountryData->FNameTermTbl.Data[20] = ';';
    CountryData->FNameTermTbl.Data[21] = ',';

    CountryData->CollateTbl.Size = ARRAYSIZE(CountryData->CollateTbl.Data);
    for (i = 0; i < CountryData->CollateTbl.Size; ++i)
        CountryData->CollateTbl.Data[i] = i;

    CountryData->DBCSLeadTbl.Size = 0; // Empty DBCS table
    CountryData->DBCSLeadTbl.Data[0] = 0x0000;

    return TRUE;
}
示例#6
0
文件: emulator.c 项目: staring/RosFE
PVOID
WINAPI
VdmMapFlat(IN USHORT   Segment,
           IN ULONG    Offset,
           IN VDM_MODE Mode)
{
    // FIXME
    UNREFERENCED_PARAMETER(Mode);

    return SEG_OFF_TO_PTR(Segment, Offset);
}
示例#7
0
文件: int32.c 项目: RPG-7/reactos
ULONG
RegisterInt16(IN  ULONG   FarPtr,
              IN  BYTE    IntNumber,
              IN  LPBYTE  CallbackCode,
              IN  SIZE_T  CallbackSize,
              OUT PSIZE_T CodeSize OPTIONAL)
{
    /* Get a pointer to the IVT and set the corresponding entry (far pointer) */
    LPDWORD IntVecTable = (LPDWORD)SEG_OFF_TO_PTR(0x0000, 0x0000);
    IntVecTable[IntNumber] = FarPtr;

    /* Register the 16-bit callback */
    return RegisterCallback16(FarPtr,
                              CallbackCode,
                              CallbackSize,
                              CodeSize);
}
示例#8
0
文件: int32.c 项目: RPG-7/reactos
static VOID WINAPI ControlBop(LPWORD Stack)
{
    /* Get the Function Number and skip it */
    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
    setIP(getIP() + 1);

    switch (FuncNum)
    {
        case BOP_CONTROL_INT32:
            Int32Dispatch(Stack);
            break;

        default:
            // DPRINT1("Unassigned Control BOP Function: 0x%02X\n", FuncNum);
            DisplayMessage(L"Unassigned Control BOP Function: 0x%02X", FuncNum);
            break;
    }
}
示例#9
0
文件: dem.c 项目: staring/RosFE
VOID DosBootsectorInitialize(VOID)
{
    /* We write the bootsector at 0000:7C00 */
    ULONG_PTR Address = (ULONG_PTR)SEG_OFF_TO_PTR(0x0000, 0x7C00);
    CHAR DosKernelFileName[] = ""; // No DOS file name, therefore we'll load DOS32

    DPRINT("DosBootsectorInitialize\n");

    /* Write the "bootsector" */
    RtlCopyMemory((PVOID)Address, Bootsector1, sizeof(Bootsector1));
    Address += sizeof(Bootsector1);
    RtlCopyMemory((PVOID)Address, DosKernelFileName, sizeof(DosKernelFileName));
    Address += sizeof(DosKernelFileName);
    RtlCopyMemory((PVOID)Address, Bootsector2, sizeof(Bootsector2));

    /* Register the DOS Loading BOP */
    RegisterBop(BOP_LOAD_DOS, DosInitialize);
}
示例#10
0
文件: dem.c 项目: GYGit/reactos
static VOID CmdStartComSpec32(VOID)
{
    DWORD Result;

    // TODO: improve: this code has strong similarities with the
    // 'default' case of DosCreateProcess and with the 'case 0x08'.

    CHAR CmdLine[sizeof("cmd.exe") + 1] = "";

    /* Spawn a user-defined 32-bit command preprocessor */

    // FIXME: Use COMSPEC env var!!
    strcpy(CmdLine, "cmd.exe");

    DPRINT1("CMD Run 32-bit Command Interpreter '%s'\n", CmdLine);

    /*
     * No need to prepare the stack for DosStartComSpec since we won't start it.
     */
    Result = DosStartProcess32(CmdLine, CmdLine,
                               SEG_OFF_TO_PTR(getES(), 0) /*Environment*/,
                               MAKELONG(getIP(), getCS()) /*ReturnAddress*/,
                               FALSE);
    if (Result != ERROR_SUCCESS)
    {
        DosDisplayMessage("Failed to start 32-bit Command Interpreter '%s'. Error: %u\n", CmdLine, Result);
        setCF(0);
        setAL((UCHAR)Result);
    }
    else
    {
        DosDisplayMessage("32-bit Command Interpreter '%s' started successfully.\n", CmdLine);
#ifndef STANDALONE
        setCF(Repeat); // Set CF if we need to start a 16-bit process
#else
        setCF(0);
#endif
    }
}
示例#11
0
文件: dem.c 项目: GYGit/reactos
static VOID WINAPI DosSystemBop(LPWORD Stack)
{
    /* Get the Function Number and skip it */
    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
    setIP(getIP() + 1);

    switch (FuncNum)
    {
        /* Load the DOS kernel */
        case 0x11:
        {
            DemLoadNTDOSKernel();
            break;
        }

        /* Call 32-bit Driver Strategy Routine */
        case BOP_DRV_STRATEGY:
        {
            DeviceStrategyBop();
            break;
        }

        /* Call 32-bit Driver Interrupt Routine */
        case BOP_DRV_INTERRUPT:
        {
            DeviceInterruptBop();
            break;
        }

        default:
        {
            DPRINT1("Unknown DOS System BOP Function: 0x%02X\n", FuncNum);
            // setCF(1); // Disable, otherwise we enter an infinite loop
            break;
        }
    }
}
示例#12
0
文件: dem.c 项目: GYGit/reactos
VOID DosBootsectorInitialize(VOID)
{
    /* We write the bootsector at 0000:7C00 */
    ULONG_PTR StartAddress = (ULONG_PTR)SEG_OFF_TO_PTR(0x0000, 0x7C00);
    ULONG_PTR Address = StartAddress;
    CHAR DosKernelFileName[] = ""; // No DOS BIOS file name, therefore we will load DOS32

    DPRINT("DosBootsectorInitialize\n");

    /* Write the "bootsector" */
    RtlCopyMemory((PVOID)Address, Bootsector1, sizeof(Bootsector1));
    Address += sizeof(Bootsector1);
    RtlCopyMemory((PVOID)Address, DosKernelFileName, sizeof(DosKernelFileName));
    Address += sizeof(DosKernelFileName);
    RtlCopyMemory((PVOID)Address, Bootsector2, sizeof(Bootsector2));
    Address += sizeof(Bootsector2);

    /* Initialize the callback context */
    InitializeContext(&DosContext, 0x0000,
                      (ULONG_PTR)MEM_ALIGN_UP(0x7C00 + Address - StartAddress, sizeof(WORD)));

    /* Register the DOS Loading BOP */
    RegisterBop(BOP_LOAD_DOS, DosInitialize);
}
示例#13
0
文件: dem.c 项目: GYGit/reactos
static VOID WINAPI DosInitialize(LPWORD Stack)
{
    /* Get the DOS BIOS file name (NULL-terminated) */
    // FIXME: Isn't it possible to use some DS:SI instead??
    LPCSTR DosBiosFileName = (LPCSTR)SEG_OFF_TO_PTR(getCS(), getIP());
    setIP(getIP() + strlen(DosBiosFileName) + 1); // Skip it

    DPRINT("DosInitialize('%s')\n", DosBiosFileName);

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

    /* Register the DOS BOPs */
    RegisterBop(BOP_DOS, DosSystemBop        );
    RegisterBop(BOP_CMD, DosCmdInterpreterBop);

    if (DosBiosFileName[0] != '\0')
    {
        BOOLEAN Success = FALSE;
        HANDLE  hDosBios;
        ULONG   ulDosBiosSize = 0;

        /* Open the DOS BIOS file */
        hDosBios = FileOpen(DosBiosFileName, &ulDosBiosSize);
        if (hDosBios == NULL) goto Quit;

        /* Attempt to load the DOS BIOS into memory */
        Success = FileLoadByHandle(hDosBios,
                                   REAL_TO_PHYS(TO_LINEAR(0x0070, 0x0000)),
                                   ulDosBiosSize,
                                   &ulDosBiosSize);

        DPRINT1("DOS BIOS file '%s' loading %s at %04X:%04X, size 0x%X (Error: %u).\n",
                DosBiosFileName,
                (Success ? "succeeded" : "failed"),
                0x0070, 0x0000,
                ulDosBiosSize,
                GetLastError());

        /* Close the DOS BIOS file */
        FileClose(hDosBios);

Quit:
        if (!Success)
        {
            BiosDisplayMessage("DOS BIOS file '%s' loading failed (Error: %u). The VDM will shut down.\n",
                               DosBiosFileName, GetLastError());
            return;
        }
    }
    else
    {
        /* Load the 16-bit startup code for DOS32 and register its Starting BOP */
        RtlCopyMemory(SEG_OFF_TO_PTR(0x0070, 0x0000), Startup, sizeof(Startup));

        // This is the equivalent of BOP_LOAD_DOS, function 0x11 "Load the DOS kernel"
        // for the Windows NT DOS.
        RegisterBop(BOP_START_DOS, DosStart);
    }

    /* Position execution pointers for DOS startup and return */
    setCS(0x0070);
    setIP(0x0000);
}
示例#14
0
文件: dem.c 项目: staring/RosFE
static VOID WINAPI DosStart(LPWORD Stack)
{
#ifdef STANDALONE
    DWORD Result;
    CHAR ApplicationName[MAX_PATH];
    CHAR CommandLine[DOS_CMDLINE_LENGTH];
#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);

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

#ifndef STANDALONE

    /* Create the GetNextVDMCommand thread */
    CommandThread = CreateThread(NULL, 0, &CommandThreadProc, NULL, 0, NULL);
    if (CommandThread == NULL)
    {
        wprintf(L"FATAL: Failed to create the command processing thread: %d\n", GetLastError());
        goto Quit;
    }

    /* Wait for the command thread to exit */
    WaitForSingleObject(CommandThread, INFINITE);

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

#else

    if (NtVdmArgc >= 2)
    {
        WideCharToMultiByte(CP_ACP, 0, NtVdmArgv[1], -1, ApplicationName, sizeof(ApplicationName), NULL, NULL);

        if (NtVdmArgc >= 3)
            WideCharToMultiByte(CP_ACP, 0, NtVdmArgv[2], -1, CommandLine, sizeof(CommandLine), NULL, NULL);
        else
            strcpy(CommandLine, "");
    }
    else
    {
        DisplayMessage(L"Invalid DOS command line\n");
        goto Quit;
    }

    /* Start the process from the command line */
    DPRINT1("Starting '%s' ('%s')...\n", ApplicationName, CommandLine);
    Result = DosStartProcess(ApplicationName,
                             CommandLine,
                             SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0));
    if (Result != ERROR_SUCCESS)
    {
        DisplayMessage(L"Could not start '%S'. Error: %u", ApplicationName, Result);
        goto Quit;
    }

#endif

Quit:
    /* Stop the VDM */
    EmulatorTerminate();
}
示例#15
0
文件: dem.c 项目: hackbunny/reactos
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;
        }
    }
}
示例#16
0
文件: dem.c 项目: GYGit/reactos
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)
    {
        /* Kill the VDM */
        case 0x00:
        {
            /* Stop the VDM */
            EmulatorTerminate();
            return;
        }

        /*
         * Get a new app to start
         *
         * Input
         *     DS:DX : Data block.
         *
         * Output
         *     CF    : 0: Success; 1: Failure.
         */
        case 0x01:
        {
            CmdStartProcess();
            break;
        }

        /*
         * Check binary format
         *
         * Input
         *     DS:DX : Program to check.
         *
         * Output
         *     CF    : 0: Success; 1: Failure.
         *     AX    : Error code.
         */
        case 0x07:
        {
            DWORD BinaryType;
            LPSTR ProgramName = (LPSTR)SEG_OFF_TO_PTR(getDS(), getDX());

            if (!GetBinaryTypeA(ProgramName, &BinaryType))
            {
                /* An error happened, bail out */
                setCF(1);
                setAX(LOWORD(GetLastError()));
                break;
            }

            // FIXME: We only support DOS binaries for now...
            ASSERT(BinaryType == SCS_DOS_BINARY);
            if (BinaryType != SCS_DOS_BINARY)
            {
                /* An error happened, bail out */
                setCF(1);
                setAX(LOWORD(ERROR_BAD_EXE_FORMAT));
                break;
            }

            /* Return success: DOS application */
            setCF(0);
            break;
        }

        /*
         * Start an external command
         *
         * Input
         *     DS:SI : Command to start.
         *     ES    : Environment block segment.
         *     AL    : Current drive number.
         *     AH    : 0: Directly start the command;
         *             1: Use "cmd.exe /c" to start the command.
         *
         * Output
         *     CF    : 0: Shell-out; 1: Continue.
         *     AL    : Error/Exit code.
         */
        case 0x08:
        {
            CmdStartExternalCommand();
            break;
        }

        /*
         * Start the default 32-bit command interpreter (COMSPEC)
         *
         * Input
         *     ES    : Environment block segment.
         *     AL    : Current drive number.
         *
         * Output
         *     CF    : 0: Shell-out; 1: Continue.
         *     AL    : Error/Exit code.
         */
        case 0x0A:
        {
            CmdStartComSpec32();
            break;
        }

        /*
         * Set exit code
         *
         * Input
         *     DX    : Exit code
         *
         * Output
         *     CF    : 0: Shell-out; 1: Continue.
         */
        case 0x0B:
        {
            CmdSetExitCode();
            break;
        }

        /*
         * Get start information
         *
         * Output
         *     AL    : 0 (resp. 1): Started from (resp. without) an existing console.
         */
        case 0x10:
        {
#ifndef STANDALONE
            /*
             * When a new instance of our (internal) COMMAND.COM is started,
             * we check whether we need to run a 32-bit COMSPEC. This goes by
             * checking whether we were started in a new console (no parent
             * console process) or from an existing one.
             *
             * However COMMAND.COM can also be started in the case where a
             * 32-bit process (started by a 16-bit parent) wants to start a new
             * 16-bit process: to ensure DOS reentry we need to start a new
             * instance of COMMAND.COM. On Windows the COMMAND.COM is started
             * just before the 32-bit process (in fact, it is this COMMAND.COM
             * which starts the 32-bit process via an undocumented command-line
             * switch '/z', which syntax is:
             *     COMMAND.COM /z\bAPPNAME.EXE
             * notice the '\b' character inserted in-between. Then COMMAND.COM
             * issues a BOP_CMD 08h with AH=00h to start the process).
             *
             * Instead, we do the reverse, i.e. we start the 32-bit process,
             * and *only* if needed, i.e. if this process wants to start a
             * new 16-bit process, we start our COMMAND.COM.
             *
             * The problem we then face is that our COMMAND.COM will possibly
             * want to start a new COMSPEC, however we do not want this.
             * The chosen solution is to flag this case -- done with the 'Reentry'
             * boolean -- so that COMMAND.COM will not attempt to start COMSPEC
             * but instead will directly try to start the 16-bit process.
             */
            // setAL(SessionId != 0);
            setAL((SessionId != 0) && !Reentry);
            /* Reset 'Reentry' */
            Reentry = FALSE;
#else
            setAL(0);
#endif
            break;
        }

        default:
        {
            DPRINT1("Unknown DOS CMD Interpreter BOP Function: 0x%02X\n", FuncNum);
            // setCF(1); // Disable, otherwise we enter an infinite loop
            break;
        }
    }
}
示例#17
0
文件: emsdrv.c 项目: reactos/reactos
static VOID WINAPI EmsIntHandler(LPWORD Stack)
{
    switch (getAH())
    {
        /* Get Manager Status */
        case 0x40:
        {
            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Get Page Frame Segment */
        case 0x41:
        {
            setAH(EMS_STATUS_SUCCESS);
            setBX(EmsSegment);
            break;
        }

        /* Get Number of Unallocated Pages */
        case 0x42:
        {
            setAH(EMS_STATUS_SUCCESS);
            setBX(RtlNumberOfClearBits(&AllocBitmap));
            setDX(EmsTotalPages);
            break;
        }

        /* Get Handle and Allocate Memory */
        case 0x43:
        {
            USHORT Handle;
            UCHAR Status = EmsAlloc(getBX(), &Handle);

            if (Status == EMS_STATUS_SUCCESS)
                setDX(Handle);

            setAH(Status);
            break;
        }

        /* Map Memory */
        case 0x44:
        {
            setAH(EmsMap(getDX(), getAL(), getBX()));
            break;
        }

        /* Release Handle and Memory */
        case 0x45:
        {
            setAH(EmsFree(getDX()));
            break;
        }

        /* Get EMM Version */
        case 0x46:
        {
            setAH(EMS_STATUS_SUCCESS);
            setAL(EMS_VERSION_NUM);
            break;
        }

        /* Save Page Map */
        case 0x47:
        {
            // FIXME: This depends on an EMS handle given in DX
            RtlCopyMemory(MappingBackup, Mapping, sizeof(Mapping));
            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Restore Page Map */
        case 0x48:
        {
            // FIXME: This depends on an EMS handle given in DX
            RtlCopyMemory(Mapping, MappingBackup, sizeof(Mapping));
            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Get Number of Opened Handles */
        case 0x4B:
        {
            USHORT NumOpenHandles = 0;
            USHORT i;

            for (i = 0; i < ARRAYSIZE(HandleTable); i++)
            {
                if (HandleTable[i].Allocated)
                    ++NumOpenHandles;
            }

            setAH(EMS_STATUS_SUCCESS);
            setBX(NumOpenHandles);
            break;
        }

        /* Get Handle Number of Pages */
        case 0x4C:
        {
            PEMS_HANDLE HandleEntry = GetHandleRecord(getDX());

            if (!ValidateHandle(HandleEntry))
            {
                setAH(EMS_STATUS_INVALID_HANDLE);
                break;
            }

            setAH(EMS_STATUS_SUCCESS);
            setBX(HandleEntry->PageCount);
            break;
        }

        /* Get All Handles Number of Pages */
        case 0x4D:
        {
            PEMS_HANDLE_PAGE_INFO HandlePageInfo = (PEMS_HANDLE_PAGE_INFO)SEG_OFF_TO_PTR(getES(), getDI());
            USHORT NumOpenHandles = 0;
            USHORT i;

            for (i = 0; i < ARRAYSIZE(HandleTable); i++)
            {
                if (HandleTable[i].Allocated)
                {
                    HandlePageInfo->Handle = i;
                    HandlePageInfo->PageCount = HandleTable[i].PageCount;
                    ++HandlePageInfo;
                    ++NumOpenHandles;
                }
            }

            setAH(EMS_STATUS_SUCCESS);
            setBX(NumOpenHandles);
            break;
        }

        /* Get or Set Page Map */
        case 0x4E:
        {
            switch (getAL())
            {
                /* Get Mapping Registers  */
                // case 0x00: // TODO: NOT IMPLEMENTED
 
                /* Set Mapping Registers */
                // case 0x01: // TODO: NOT IMPLEMENTED

                /* Get and Set Mapping Registers At Once */
                // case 0x02: // TODO: NOT IMPLEMENTED

                /* Get Size of Page-Mapping Array */
                case 0x03:
                {
                    setAH(EMS_STATUS_SUCCESS);
                    setAL(sizeof(Mapping));
                    break;
                }

                default:
                {
                    DPRINT1("EMS function AH = 0x4E, subfunction AL = %02X NOT IMPLEMENTED\n", getAL());
                    setAH(EMS_STATUS_UNKNOWN_FUNCTION);
                    break;
                }
            }
            
            break;
        }

        /* Get/Set Handle Name */
        case 0x53:
        {
            PEMS_HANDLE HandleEntry = GetHandleRecord(getDX());

            if (!ValidateHandle(HandleEntry))
            {
                setAH(EMS_STATUS_INVALID_HANDLE);
                break;
            }

            if (getAL() == 0x00)
            {
                /* Retrieve the name */
                RtlCopyMemory(SEG_OFF_TO_PTR(getES(), getDI()),
                              HandleEntry->Name,
                              sizeof(HandleEntry->Name));
                setAH(EMS_STATUS_SUCCESS);
            }
            else if (getAL() == 0x01)
            {
                /* Store the name */
                RtlCopyMemory(HandleEntry->Name,
                              SEG_OFF_TO_PTR(getDS(), getSI()),
                              sizeof(HandleEntry->Name));
                setAH(EMS_STATUS_SUCCESS);
            }
            else
            {
                DPRINT1("Invalid subfunction %02X for EMS function AH = 53h\n", getAL());
                setAH(EMS_STATUS_INVALID_SUBFUNCTION);
            }

            break;
        }

        /* Handle Directory functions */
        case 0x54:
        {
            if (getAL() == 0x00)
            {
                /* Get Handle Directory */

                PEMS_HANDLE_DIR_ENTRY HandleDir = (PEMS_HANDLE_DIR_ENTRY)SEG_OFF_TO_PTR(getES(), getDI());
                USHORT NumOpenHandles = 0;
                USHORT i;

                for (i = 0; i < ARRAYSIZE(HandleTable); i++)
                {
                    if (HandleTable[i].Allocated)
                    {
                        HandleDir->Handle = i;
                        RtlCopyMemory(HandleDir->Name,
                                      HandleTable[i].Name,
                                      sizeof(HandleDir->Name));
                        ++HandleDir;
                        ++NumOpenHandles;
                    }
                }

                setAH(EMS_STATUS_SUCCESS);
                setAL((UCHAR)NumOpenHandles);
            }
            else if (getAL() == 0x01)
            {
                /* Search for Named Handle */

                PUCHAR HandleName = (PUCHAR)SEG_OFF_TO_PTR(getDS(), getSI());
                PEMS_HANDLE HandleFound = NULL;
                USHORT i;

                for (i = 0; i < ARRAYSIZE(HandleTable); i++)
                {
                    if (HandleTable[i].Allocated &&
                        RtlCompareMemory(HandleName,
                                         HandleTable[i].Name,
                                         sizeof(HandleTable[i].Name)) == sizeof(HandleTable[i].Name))
                    {
                        HandleFound = &HandleTable[i];
                        break;
                    }
                }

                /* Bail out if no handle was found */
                if (i >= ARRAYSIZE(HandleTable)) // HandleFound == NULL
                {
                    setAH(EMS_STATUS_HANDLE_NOT_FOUND);
                    break;
                }

                /* Return the handle number */
                setDX(i);

                /* Sanity check: Check whether the handle was unnamed */
                i = 0;
                while ((i < sizeof(HandleFound->Name)) && (HandleFound->Name[i] == '\0'))
                    ++i;

                if (i >= sizeof(HandleFound->Name))
                {
                    setAH(EMS_STATUS_UNNAMED_HANDLE);
                }
                else
                {
                    setAH(EMS_STATUS_SUCCESS);
                }
            }
            else if (getAL() == 0x02)
            {
                /*
                 * Get Total Number of Handles
                 *
                 * This function retrieves the maximum number of handles
                 * (allocated or not) the memory manager supports, which
                 * a program may request.
                 */
                setAH(EMS_STATUS_SUCCESS);
                setBX(ARRAYSIZE(HandleTable));
            }
            else
            {
                DPRINT1("Invalid subfunction %02X for EMS function AH = 54h\n", getAL());
                setAH(EMS_STATUS_INVALID_SUBFUNCTION);
            }

            break;
        }

        /* Move/Exchange Memory */
        case 0x57:
        {
            PUCHAR SourcePtr, DestPtr;
            PEMS_HANDLE HandleEntry;
            PEMS_PAGE PageEntry;
            BOOLEAN Exchange = getAL();
            PEMS_COPY_DATA Data = (PEMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI());

            if (Data->SourceType)
            {
                /* Expanded memory */
                HandleEntry = GetHandleRecord(Data->SourceHandle);
                if (!ValidateHandle(HandleEntry))
                {
                    setAH(EMS_STATUS_INVALID_HANDLE);
                    break;
                }

                PageEntry = GetLogicalPage(HandleEntry, Data->SourceSegment);
                if (!PageEntry)
                {
                    setAH(EMS_STATUS_INV_LOGICAL_PAGE);
                    break;
                }

                SourcePtr = (PUCHAR)((ULONG_PTR)EmsMemory
                                     + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE
                                     + Data->SourceOffset);
            }
            else
            {
                /* Conventional memory */
                SourcePtr = (PUCHAR)SEG_OFF_TO_PTR(Data->SourceSegment, Data->SourceOffset);
            }

            if (Data->DestType)
            {
                /* Expanded memory */
                HandleEntry = GetHandleRecord(Data->DestHandle);
                if (!ValidateHandle(HandleEntry))
                {
                    setAH(EMS_STATUS_INVALID_HANDLE);
                    break;
                }

                PageEntry = GetLogicalPage(HandleEntry, Data->DestSegment);
                if (!PageEntry)
                {
                    setAH(EMS_STATUS_INV_LOGICAL_PAGE);
                    break;
                }

                DestPtr = (PUCHAR)((ULONG_PTR)EmsMemory
                                   + ARRAY_INDEX(PageEntry, PageTable) * EMS_PAGE_SIZE
                                   + Data->DestOffset);
            }
            else
            {
                /* Conventional memory */
                DestPtr = (PUCHAR)SEG_OFF_TO_PTR(Data->DestSegment, Data->DestOffset);
            }

            if (Exchange)
            {
                ULONG i;

                /* Exchange */
                for (i = 0; i < Data->RegionLength; i++)
                {
                    UCHAR Temp = DestPtr[i];
                    DestPtr[i] = SourcePtr[i];
                    SourcePtr[i] = Temp;
                }
            }
            else
            {
                /* Move */
                RtlMoveMemory(DestPtr, SourcePtr, Data->RegionLength);
            }

            setAH(EMS_STATUS_SUCCESS);
            break;
        }

        /* Get Mappable Physical Address Array */
        case 0x58:
        {
            if (getAL() == 0x00)
            {
                PEMS_MAPPABLE_PHYS_PAGE PageArray = (PEMS_MAPPABLE_PHYS_PAGE)SEG_OFF_TO_PTR(getES(), getDI());
                ULONG i;

                for (i = 0; i < EMS_PHYSICAL_PAGES; i++)
                {
                    PageArray->PageSegment = EMS_SEGMENT + i * (EMS_PAGE_SIZE >> 4);
                    PageArray->PageNumber  = i;
                    ++PageArray;
                }

                setAH(EMS_STATUS_SUCCESS);
                setCX(EMS_PHYSICAL_PAGES);
            }
            else if (getAL() == 0x01)
            {
                setAH(EMS_STATUS_SUCCESS);
                setCX(EMS_PHYSICAL_PAGES);
            }
            else
            {
                DPRINT1("Invalid subfunction %02X for EMS function AH = 58h\n", getAL());
                setAH(EMS_STATUS_INVALID_SUBFUNCTION);
            }

            break;
        }
示例#18
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();
}
示例#19
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;
}
示例#20
0
文件: dem.c 项目: staring/RosFE
static VOID WINAPI DosInitialize(LPWORD Stack)
{
    BOOLEAN Success = FALSE;

    /* Get the DOS kernel file name (NULL-terminated) */
    // FIXME: Isn't it possible to use some DS:SI instead??
    LPCSTR DosKernelFileName = (LPCSTR)SEG_OFF_TO_PTR(getCS(), getIP());
    setIP(getIP() + strlen(DosKernelFileName) + 1); // Skip it

    DPRINT("DosInitialize('%s')\n", DosKernelFileName);

    /* Register the DOS BOPs */
    RegisterBop(BOP_DOS, DosSystemBop        );
    RegisterBop(BOP_CMD, DosCmdInterpreterBop);

    if (DosKernelFileName && DosKernelFileName[0] != '\0')
    {
        HANDLE  hDosBios;
        ULONG   ulDosBiosSize = 0;

        /* Open the DOS BIOS file */
        hDosBios = FileOpen(DosKernelFileName, &ulDosBiosSize);

        /* If we failed, bail out */
        if (hDosBios == NULL) goto QuitCustom;

        /* Attempt to load the DOS BIOS into memory */
        Success = FileLoadByHandle(hDosBios,
                                   REAL_TO_PHYS(TO_LINEAR(0x0070, 0x0000)),
                                   ulDosBiosSize,
                                   &ulDosBiosSize);

        DPRINT1("DOS BIOS loading %s at %04X:%04X, size 0x%X ; GetLastError() = %u\n",
                (Success ? "succeeded" : "failed"),
                0x0070, 0x0000,
                ulDosBiosSize,
                GetLastError());

        /* Close the DOS BIOS file */
        FileClose(hDosBios);

        if (!Success) goto QuitCustom;

        /* Position execution pointers and return */
        setCS(0x0070);
        setIP(0x0000);

        /* Return control */
QuitCustom:
        if (!Success)
            DisplayMessage(L"Custom DOS '%S' loading failed, what to do??", DosKernelFileName);
    }
    else
    {
        Success = DosBIOSInitialize();
        // Success &= DosKRNLInitialize();

        if (!Success) goto Quit32;

        /* Write the "bootsector" */
        RtlCopyMemory(SEG_OFF_TO_PTR(0x0070, 0x0000), Startup, sizeof(Startup));

        /* Register the DOS Starting BOP */
        RegisterBop(BOP_START_DOS, DosStart);

        /* Position execution pointers and return */
        setCS(0x0070);
        setIP(0x0000);

        /* Return control */
Quit32:
        if (!Success)
            DisplayMessage(L"DOS32 loading failed, what to do??");
    }

    if (Success)
    {
        /*
         * We succeeded, deregister the DOS Loading BOP
         * so that no app will be able to call us back.
         */
        RegisterBop(BOP_LOAD_DOS, NULL);
    }
}
示例#21
0
VOID WINAPI ThirdPartyVDDBop(LPWORD Stack)
{
    /* Get the Function Number and skip it */
    BYTE FuncNum = *(PBYTE)SEG_OFF_TO_PTR(getCS(), getIP());
    setIP(getIP() + 1);

    switch (FuncNum)
    {
        /* RegisterModule */
        case 0:
        {
            BOOL Success = TRUE;
            WORD RetVal  = 0;
            WORD Entry   = 0;
            LPCSTR DllName = NULL,
                   InitRoutineName     = NULL,
                   DispatchRoutineName = NULL;
            HMODULE hDll = NULL;
            VDD_PROC InitRoutine     = NULL,
                     DispatchRoutine = NULL;

            DPRINT("RegisterModule() called\n");

            /* Clear the Carry Flag (no error happened so far) */
            setCF(0);

            /* Retrieve the next free entry in the table (used later on) */
            Entry = GetNextFreeVDDEntry();
            if (Entry >= MAX_VDD_MODULES)
            {
                DPRINT1("Failed to create a new VDD module entry\n");
                Success = FALSE;
                RetVal = 4;
                goto Quit;
            }

            /* Retrieve the VDD name in DS:SI */
            DllName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getSI());

            /* Retrieve the initialization routine API name in ES:DI (optional --> ES=DI=0) */
            if (TO_LINEAR(getES(), getDI()) != 0)
                InitRoutineName = (LPCSTR)SEG_OFF_TO_PTR(getES(), getDI());

            /* Retrieve the dispatch routine API name in DS:BX */
            DispatchRoutineName = (LPCSTR)SEG_OFF_TO_PTR(getDS(), getBX());

            DPRINT1("DllName = '%s' - InitRoutineName = '%s' - DispatchRoutineName = '%s'\n",
                    (DllName ? DllName : "n/a"),
                    (InitRoutineName ? InitRoutineName : "n/a"),
                    (DispatchRoutineName ? DispatchRoutineName : "n/a"));

            /* Load the VDD DLL */
            hDll = LoadLibraryA(DllName);
            if (hDll == NULL)
            {
                DWORD LastError = GetLastError();
                Success = FALSE;

                if (LastError == ERROR_NOT_ENOUGH_MEMORY)
                {
                    DPRINT1("Not enough memory to load DLL '%s'\n", DllName);
                    RetVal = 4;
                    goto Quit;
                }
                else
                {
                    DPRINT1("Failed to load DLL '%s'; last error = %d\n", DllName, LastError);
                    RetVal = 1;
                    goto Quit;
                }
            }

            /* Load the initialization routine if needed */
            if (InitRoutineName)
            {
                InitRoutine = (VDD_PROC)GetProcAddress(hDll, InitRoutineName);
                if (InitRoutine == NULL)
                {
                    DPRINT1("Failed to load the initialization routine '%s'\n", InitRoutineName);
                    Success = FALSE;
                    RetVal = 3;
                    goto Quit;
                }
            }

            /* Load the dispatch routine */
            DispatchRoutine = (VDD_PROC)GetProcAddress(hDll, DispatchRoutineName);
            if (DispatchRoutine == NULL)
            {
                DPRINT1("Failed to load the dispatch routine '%s'\n", DispatchRoutineName);
                Success = FALSE;
                RetVal = 2;
                goto Quit;
            }

            /* If we arrived there, that means everything is OK */

            /* Register the VDD DLL */
            VDDList[Entry].hDll = hDll;
            VDDList[Entry].DispatchRoutine = DispatchRoutine;

            /* Call the initialization routine if needed */
            if (InitRoutine) InitRoutine();

            /* We succeeded. RetVal will contain a valid VDD DLL handle */
            Success = TRUE;
            RetVal  = ENTRY_TO_HANDLE(Entry); // Convert the entry to a valid handle

Quit:
            if (!Success)
            {
                /* Unload the VDD DLL */
                if (hDll) FreeLibrary(hDll);

                /* Set the Carry Flag to indicate that an error happened */
                setCF(1);
            }
            // else
            // {
                // /* Clear the Carry Flag (success) */
                // setCF(0);
            // }
            setAX(RetVal);
            break;
        }

        /* UnRegisterModule */
        case 1:
        {
            WORD Handle = getAX();
            WORD Entry  = HANDLE_TO_ENTRY(Handle); // Convert the handle to a valid entry

            DPRINT("UnRegisterModule() called\n");

            /* Sanity checks */
            if (!IS_VALID_HANDLE(Handle) || VDDList[Entry].hDll == NULL)
            {
                DPRINT1("Invalid VDD DLL Handle: %d\n", Entry);
                /* Stop the VDM */
                EmulatorTerminate();
                return;
            }

            /* Unregister the VDD DLL */
            FreeLibrary(VDDList[Entry].hDll);
            VDDList[Entry].hDll = NULL;
            VDDList[Entry].DispatchRoutine = NULL;
            break;
        }

        /* DispatchCall */
        case 2:
        {
            WORD Handle = getAX();
            WORD Entry  = HANDLE_TO_ENTRY(Handle); // Convert the handle to a valid entry

            DPRINT("DispatchCall() called\n");

            /* Sanity checks */
            if (!IS_VALID_HANDLE(Handle)    ||
                VDDList[Entry].hDll == NULL ||
                VDDList[Entry].DispatchRoutine == NULL)
            {
                DPRINT1("Invalid VDD DLL Handle: %d\n", Entry);
                /* Stop the VDM */
                EmulatorTerminate();
                return;
            }

            /* Call the dispatch routine */
            VDDList[Entry].DispatchRoutine();
            break;
        }

        default:
        {
            DPRINT1("Unknown 3rd-party VDD BOP Function: 0x%02X\n", FuncNum);
            setCF(1);
            break;
        }
    }
}
示例#22
0
文件: bios.c 项目: hackbunny/reactos
BOOLEAN DosBIOSInitialize(VOID)
{
    PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);

    LPWSTR SourcePtr, Environment;
    LPSTR AsciiString;
    DWORD AsciiSize;
    LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);

#if 0
    UCHAR i;
    CHAR CurrentDirectory[MAX_PATH];
    CHAR DosDirectory[DOS_DIR_LENGTH];
    LPSTR Path;

    FILE *Stream;
    WCHAR Buffer[256];
#endif

    /* Initialize the MCB */
    Mcb->BlockType = 'Z';
    Mcb->Size = USER_MEMORY_SIZE;
    Mcb->OwnerPsp = 0;

    /* Initialize the link MCB to the UMB area */
    Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT + USER_MEMORY_SIZE + 1);
    Mcb->BlockType = 'M';
    Mcb->Size = UMB_START_SEGMENT - FIRST_MCB_SEGMENT - USER_MEMORY_SIZE - 2;
    Mcb->OwnerPsp = SYSTEM_PSP;

    /* Initialize the UMB area */
    Mcb = SEGMENT_TO_MCB(UMB_START_SEGMENT);
    Mcb->BlockType = 'Z';
    Mcb->Size = UMB_END_SEGMENT - UMB_START_SEGMENT;
    Mcb->OwnerPsp = 0;

    /* Get the environment strings */
    SourcePtr = Environment = GetEnvironmentStringsW();
    if (Environment == NULL) return FALSE;

    /* Fill the DOS system environment block */
    while (*SourcePtr)
    {
        /* Get the size of the ASCII string */
        AsciiSize = WideCharToMultiByte(CP_ACP,
                                        0,
                                        SourcePtr,
                                        -1,
                                        NULL,
                                        0,
                                        NULL,
                                        NULL);

        /* Allocate memory for the ASCII string */
        AsciiString = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, AsciiSize);
        if (AsciiString == NULL)
        {
            FreeEnvironmentStringsW(Environment);
            return FALSE;
        }

        /* Convert to ASCII */
        WideCharToMultiByte(CP_ACP,
                            0,
                            SourcePtr,
                            -1,
                            AsciiString,
                            AsciiSize,
                            NULL,
                            NULL);

        /* Copy the string into DOS memory */
        strcpy(DestPtr, AsciiString);

        /* Move to the next string */
        SourcePtr += wcslen(SourcePtr) + 1;
        DestPtr += strlen(AsciiString);
        *(DestPtr++) = 0;

        /* Free the memory */
        HeapFree(GetProcessHeap(), 0, AsciiString);
    }
    *DestPtr = 0;

    /* Free the memory allocated for environment strings */
    FreeEnvironmentStringsW(Environment);


#if 0

    /* Clear the current directory buffer */
    ZeroMemory(CurrentDirectories, sizeof(CurrentDirectories));

    /* Get the current directory */
    if (!GetCurrentDirectoryA(MAX_PATH, CurrentDirectory))
    {
        // TODO: Use some kind of default path?
        return FALSE;
    }

    /* Convert that to a DOS path */
    if (!GetShortPathNameA(CurrentDirectory, DosDirectory, DOS_DIR_LENGTH))
    {
        // TODO: Use some kind of default path?
        return FALSE;
    }

    /* Set the drive */
    CurrentDrive = DosDirectory[0] - 'A';

    /* Get the directory part of the path */
    Path = strchr(DosDirectory, '\\');
    if (Path != NULL)
    {
        /* Skip the backslash */
        Path++;
    }

    /* Set the directory */
    if (Path != NULL)
    {
        strncpy(CurrentDirectories[CurrentDrive], Path, DOS_DIR_LENGTH);
    }

    /* Read CONFIG.SYS */
    Stream = _wfopen(DOS_CONFIG_PATH, L"r");
    if (Stream != NULL)
    {
        while (fgetws(Buffer, sizeof(Buffer)/sizeof(Buffer[0]), Stream))
        {
            // TODO: Parse the line
        }
        fclose(Stream);
    }

#endif


    /* Register the DOS 32-bit Interrupts */
    // RegisterDosInt32(0x20, DosInt20h);

    /* Initialize the DOS kernel */
    return DosKRNLInitialize();
}
示例#23
0
文件: himem.c 项目: GYGit/reactos
static VOID WINAPI XmsBopProcedure(LPWORD Stack)
{
    switch (getAH())
    {
        /* Get XMS Version */
        case 0x00:
        {
            setAX(0x0300); /*    XMS version 3.00 */
            setBX(0x0301); /* Driver version 3.01 */
            setDX(0x0001); /* HMA present */
            break;
        }

        /* Request HMA */
        case 0x01:
        {
            /* Check whether HMA is already reserved */
            if (IsHmaReserved)
            {
                /* It is, bail out */
                setAX(0x0000);
                setBL(XMS_STATUS_HMA_IN_USE);
                break;
            }

            // NOTE: We implicitely suppose that we always have HMA.
            // If not, we should fail there with the XMS_STATUS_HMA_DOES_NOT_EXIST
            // error code.

            /* Check whether the requested size is above the minimal allowed one */
            if (getDX() < HmaMinSize)
            {
                /* It is not, bail out */
                setAX(0x0000);
                setBL(XMS_STATUS_HMA_MIN_SIZE);
                break;
            }

            /* Reserve it */
            IsHmaReserved = TRUE;
            setAX(0x0001);
            setBL(XMS_STATUS_SUCCESS);
            break;
        }

        /* Release HMA */
        case 0x02:
        {
            /* Check whether HMA was reserved */
            if (!IsHmaReserved)
            {
                /* It was not, bail out */
                setAX(0x0000);
                setBL(XMS_STATUS_HMA_NOT_ALLOCATED);
                break;
            }

            /* Release it */
            IsHmaReserved = FALSE;
            setAX(0x0001);
            setBL(XMS_STATUS_SUCCESS);
            break;
        }

        /* Global Enable A20 */
        case 0x03:
        {
            /* Enable A20 if needed */
            if (!IsA20Enabled)
            {
                XmsLocalEnableA20();
                if (getAX() != 0x0001)
                {
                    /* XmsLocalEnableA20 failed and already set AX and BL to their correct values */
                    break;
                }

                IsA20Enabled = TRUE;
            }

            setAX(0x0001); /* Line successfully enabled */
            setBL(XMS_STATUS_SUCCESS);
            break;
        }

        /* Global Disable A20 */
        case 0x04:
        {
            UCHAR Result = XMS_STATUS_SUCCESS;

            /* Disable A20 if needed */
            if (IsA20Enabled)
            {
                XmsLocalDisableA20();
                if (getAX() != 0x0001)
                {
                    /* XmsLocalDisableA20 failed and already set AX and BL to their correct values */
                    break;
                }

                IsA20Enabled = FALSE;
                Result = getBL();
            }

            setAX(0x0001); /* Line successfully disabled */
            setBL(Result);
            break;
        }

        /* Local Enable A20 */
        case 0x05:
        {
            /* This call sets AX and BL to their correct values */
            XmsLocalEnableA20();
            break;
        }

        /* Local Disable A20 */
        case 0x06:
        {
            /* This call sets AX and BL to their correct values */
            XmsLocalDisableA20();
            break;
        }

        /* Query A20 State */
        case 0x07:
        {
            setAX(EmulatorGetA20());
            setBL(XMS_STATUS_SUCCESS);
            break;
        }

        /* Query Free Extended Memory */
        case 0x08:
        {
            setAX(XmsGetLargestFreeBlock());
            setDX(FreeBlocks);

            if (FreeBlocks > 0)
                setBL(XMS_STATUS_SUCCESS);
            else
                setBL(XMS_STATUS_OUT_OF_MEMORY);

            break;
        }

        /* Allocate Extended Memory Block */
        case 0x09:
        {
            WORD Handle;
            UCHAR Result = XmsAlloc(getDX(), &Handle);

            if (Result == XMS_STATUS_SUCCESS)
            {
                setAX(1);
                setDX(Handle);
            }
            else
            {
                setAX(0);
                setBL(Result);
            }

            break;
        }

        /* Free Extended Memory Block */
        case 0x0A:
        {
            UCHAR Result = XmsFree(getDX());

            setAX(Result == XMS_STATUS_SUCCESS);
            setBL(Result);
            break;
        }

        /* Move Extended Memory Block */
        case 0x0B:
        {
            PVOID SourceAddress, DestAddress;
            PXMS_COPY_DATA CopyData = (PXMS_COPY_DATA)SEG_OFF_TO_PTR(getDS(), getSI());
            PXMS_HANDLE HandleEntry;

            if (CopyData->SourceHandle)
            {
                HandleEntry = GetHandleRecord(CopyData->SourceHandle);
                if (!ValidateHandle(HandleEntry))
                {
                    setAX(0);
                    setBL(XMS_STATUS_BAD_SRC_HANDLE);
                    break;
                }

                if (CopyData->SourceOffset >= HandleEntry->Size * XMS_BLOCK_SIZE)
                {
                    setAX(0);
                    setBL(XMS_STATUS_BAD_SRC_OFFSET);
                }

                SourceAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->SourceOffset);
            }
            else
            {
                /* The offset is actually a 16-bit segment:offset pointer */
                SourceAddress = FAR_POINTER(CopyData->SourceOffset);
            }

            if (CopyData->DestHandle)
            {
                HandleEntry = GetHandleRecord(CopyData->DestHandle);
                if (!ValidateHandle(HandleEntry))
                {
                    setAX(0);
                    setBL(XMS_STATUS_BAD_DEST_HANDLE);
                    break;
                }

                if (CopyData->DestOffset >= HandleEntry->Size * XMS_BLOCK_SIZE)
                {
                    setAX(0);
                    setBL(XMS_STATUS_BAD_DEST_OFFSET);
                }

                DestAddress = (PVOID)REAL_TO_PHYS(HandleEntry->Address + CopyData->DestOffset);
            }
            else
            {
                /* The offset is actually a 16-bit segment:offset pointer */
                DestAddress = FAR_POINTER(CopyData->DestOffset);
            }

            /* Perform the move */
            RtlMoveMemory(DestAddress, SourceAddress, CopyData->Count);

            setAX(1);
            setBL(XMS_STATUS_SUCCESS);
            break;
        }

        /* Lock Extended Memory Block */
        case 0x0C:
        {
            DWORD Address;
            UCHAR Result = XmsLock(getDX(), &Address);

            if (Result == XMS_STATUS_SUCCESS)
            {
                setAX(1);

                /* Store the LINEAR address in DX:BX */
                setDX(HIWORD(Address));
                setBX(LOWORD(Address));
            }
            else
            {
                setAX(0);
                setBL(Result);
            }

            break;
        }

        /* Unlock Extended Memory Block */
        case 0x0D:
        {
            UCHAR Result = XmsUnlock(getDX());

            setAX(Result == XMS_STATUS_SUCCESS);
            setBL(Result);
            break;
        }

        /* Get Handle Information */
        case 0x0E:
        {
            PXMS_HANDLE HandleEntry = GetHandleRecord(getDX());
            UINT i;
            UCHAR Handles = 0;

            if (!ValidateHandle(HandleEntry))
            {
                setAX(0);
                setBL(XMS_STATUS_INVALID_HANDLE);
                break;
            }

            for (i = 0; i < XMS_MAX_HANDLES; i++)
            {
                if (HandleTable[i].Handle == 0) Handles++;
            }

            setAX(1);
            setBH(HandleEntry->LockCount);
            setBL(Handles);
            setDX(HandleEntry->Size);
            break;
        }

        /* Reallocate Extended Memory Block */
        case 0x0F:
        {
            UCHAR Result = XmsRealloc(getDX(), getBX());

            setAX(Result == XMS_STATUS_SUCCESS);
            setBL(Result);
            break;
        }

        /* Request UMB */
        case 0x10:
        {
            BOOLEAN Result;
            USHORT Segment = 0x0000; /* No preferred segment  */
            USHORT Size = getDX();   /* Size is in paragraphs */

            Result = UmaDescReserve(&Segment, &Size);
            if (Result)
                setBX(Segment);
            else
                setBL(Size > 0 ? XMS_STATUS_SMALLER_UMB : XMS_STATUS_OUT_OF_UMBS);

            setDX(Size);
            setAX(Result);
            break;
        }

        /* Release UMB */
        case 0x11:
        {
            BOOLEAN Result;
            USHORT Segment = getDX();

            Result = UmaDescRelease(Segment);
            if (!Result)
                setBL(XMS_STATUS_INVALID_UMB);

            setAX(Result);
            break;
        }

        /* Reallocate UMB */
        case 0x12:
        {
            BOOLEAN Result;
            USHORT Segment = getDX();
            USHORT Size = getBX(); /* Size is in paragraphs */

            Result = UmaDescReallocate(Segment, &Size);
            if (!Result)
            {
                if (Size > 0)
                {
                    setBL(XMS_STATUS_SMALLER_UMB);
                    setDX(Size);
                }
                else
                {
                    setBL(XMS_STATUS_INVALID_UMB);
                }
            }

            setAX(Result);
            break;
        }

        default:
        {
            DPRINT1("XMS command AH = 0x%02X NOT IMPLEMENTED\n", getAH());
            setBL(XMS_STATUS_NOT_IMPLEMENTED);
        }
    }
}