2015-05-01 15:42:54 +00:00
/*
* COPYRIGHT : GPL - See COPYING in the top level directory
* PROJECT : ReactOS Virtual DOS Machine
2015-09-18 17:01:49 +00:00
* FILE : subsystems / mvdm / ntvdm / dos / dos32krnl / process . c
2015-05-01 15:42:54 +00:00
* PURPOSE : DOS32 Processes
* PROGRAMMERS : Aleksandar Andrejevic < theflash AT sdf DOT lonestar DOT org >
* Hermes Belusca - Maito ( hermes . belusca @ sfr . fr )
*/
2015-10-04 11:49:28 +00:00
/* INCLUDES *******************************************************************/
2015-10-03 19:17:55 +00:00
# include "ntvdm.h"
2015-05-01 15:42:54 +00:00
# define NDEBUG
2015-10-03 19:17:55 +00:00
# include <debug.h>
2015-05-01 15:42:54 +00:00
2015-10-04 11:49:28 +00:00
# include "emulator.h"
# include "cpu/cpu.h"
# include "dos.h"
# include "dos/dem.h"
# include "dosfiles.h"
# include "handle.h"
# include "process.h"
# include "memory.h"
# include "bios/bios.h"
# include "io.h"
# include "hardware/ps2.h"
# include "vddsup.h"
2015-05-01 15:42:54 +00:00
/* PRIVATE FUNCTIONS **********************************************************/
2015-08-18 12:26:38 +00:00
static VOID DosInitPsp ( IN WORD Segment ,
IN WORD EnvBlock ,
IN LPCSTR CommandLine ,
IN LPCSTR ProgramName )
2015-05-01 15:42:54 +00:00
{
PDOS_PSP PspBlock = SEGMENT_TO_PSP ( Segment ) ;
2015-08-18 12:26:38 +00:00
PDOS_MCB Mcb = SEGMENT_TO_MCB ( Segment - 1 ) ;
LPCSTR PspName ;
USHORT i ;
/* Link the environment block */
PspBlock - > EnvBlock = EnvBlock ;
2015-05-01 15:42:54 +00:00
2015-05-02 01:23:27 +00:00
/*
2015-08-18 12:26:38 +00:00
* Copy the command line .
2015-05-02 01:23:27 +00:00
* Format of the CommandLine parameter : 1 byte for size ; 127 bytes for contents .
*/
PspBlock - > CommandLineSize = min ( * ( PBYTE ) CommandLine , DOS_CMDLINE_LENGTH ) ;
CommandLine + + ;
RtlCopyMemory ( PspBlock - > CommandLine , CommandLine , DOS_CMDLINE_LENGTH ) ;
2015-08-18 12:26:38 +00:00
/*
* Initialize the owner name of the MCB of the PSP .
*/
/* Find the start of the file name, skipping all the path elements */
PspName = ProgramName ;
while ( * ProgramName )
{
switch ( * ProgramName + + )
{
/* Path delimiter, skip it */
case ' : ' : case ' \\ ' : case ' / ' :
PspName = ProgramName ;
break ;
}
}
/* Copy the file name up to the extension... */
for ( i = 0 ; i < sizeof ( Mcb - > Name ) & & PspName [ i ] ! = ' . ' & & PspName [ i ] ! = ' \0 ' ; + + i )
{
Mcb - > Name [ i ] = RtlUpperChar ( PspName [ i ] ) ;
}
/* ... and NULL-terminate if needed */
if ( i < sizeof ( Mcb - > Name ) ) Mcb - > Name [ i ] = ' \0 ' ;
// FIXME: Initialize the FCBs
2015-05-01 15:42:54 +00:00
}
2015-05-02 18:51:03 +00:00
static inline VOID DosSaveState ( VOID )
{
PDOS_REGISTER_STATE State ;
WORD StackPointer = getSP ( ) ;
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
DPRINT1 ( " \n "
" DosSaveState(before) -- SS:SP == %04X:%04X \n "
" Original CPU State = \n "
" DS = %04X; ES = %04X; AX = %04X; CX = %04X \n "
" DX = %04X; BX = %04X; BP = %04X; SI = %04X; DI = %04X "
" \n " ,
getSS ( ) , getSP ( ) ,
getDS ( ) , getES ( ) , getAX ( ) , getCX ( ) ,
getDX ( ) , getBX ( ) , getBP ( ) , getSI ( ) , getDI ( ) ) ;
2015-06-07 20:29:56 +00:00
/*
* Allocate stack space for the registers . Note that we
* already have one word allocated ( the interrupt number ) .
*/
StackPointer - = sizeof ( DOS_REGISTER_STATE ) - sizeof ( WORD ) ;
2015-05-02 18:51:03 +00:00
State = SEG_OFF_TO_PTR ( getSS ( ) , StackPointer ) ;
2015-05-08 23:26:15 +00:00
setSP ( StackPointer ) ;
2015-05-02 18:51:03 +00:00
/* Save */
State - > DS = getDS ( ) ;
State - > ES = getES ( ) ;
2015-06-07 20:29:56 +00:00
State - > AX = getAX ( ) ;
State - > CX = getCX ( ) ;
State - > DX = getDX ( ) ;
State - > BX = getBX ( ) ;
State - > BP = getBP ( ) ;
State - > SI = getSI ( ) ;
State - > DI = getDI ( ) ;
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
DPRINT1 ( " \n "
" DosSaveState(after) -- SS:SP == %04X:%04X \n "
" Saved State = \n "
" DS = %04X; ES = %04X; AX = %04X; CX = %04X \n "
" DX = %04X; BX = %04X; BP = %04X; SI = %04X; DI = %04X "
" \n " ,
getSS ( ) , getSP ( ) ,
State - > DS , State - > ES , State - > AX , State - > CX ,
State - > DX , State - > BX , State - > BP , State - > SI , State - > DI ) ;
2015-05-02 18:51:03 +00:00
}
static inline VOID DosRestoreState ( VOID )
{
PDOS_REGISTER_STATE State ;
2015-08-17 20:11:51 +00:00
/*
* Pop the state structure from the stack . Note that we
* already have one word allocated ( the interrupt number ) .
*/
2015-05-08 23:26:15 +00:00
State = SEG_OFF_TO_PTR ( getSS ( ) , getSP ( ) ) ;
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
DPRINT1 ( " \n "
" DosRestoreState(before) -- SS:SP == %04X:%04X \n "
" Saved State = \n "
" DS = %04X; ES = %04X; AX = %04X; CX = %04X \n "
" DX = %04X; BX = %04X; BP = %04X; SI = %04X; DI = %04X "
" \n " ,
getSS ( ) , getSP ( ) ,
State - > DS , State - > ES , State - > AX , State - > CX ,
State - > DX , State - > BX , State - > BP , State - > SI , State - > DI ) ;
2015-06-07 20:29:56 +00:00
setSP ( getSP ( ) + sizeof ( DOS_REGISTER_STATE ) - sizeof ( WORD ) ) ;
2015-05-02 18:51:03 +00:00
/* Restore */
setDS ( State - > DS ) ;
setES ( State - > ES ) ;
2015-06-07 20:29:56 +00:00
setAX ( State - > AX ) ;
setCX ( State - > CX ) ;
setDX ( State - > DX ) ;
setBX ( State - > BX ) ;
setBP ( State - > BP ) ;
setSI ( State - > SI ) ;
setDI ( State - > DI ) ;
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
DPRINT1 ( " \n "
" DosRestoreState(after) -- SS:SP == %04X:%04X \n "
" Restored CPU State = \n "
" DS = %04X; ES = %04X; AX = %04X; CX = %04X \n "
" DX = %04X; BX = %04X; BP = %04X; SI = %04X; DI = %04X "
" \n " ,
getSS ( ) , getSP ( ) ,
getDS ( ) , getES ( ) , getAX ( ) , getCX ( ) ,
getDX ( ) , getBX ( ) , getBP ( ) , getSI ( ) , getDI ( ) ) ;
2015-05-02 18:51:03 +00:00
}
2015-08-17 20:11:51 +00:00
static WORD DosCopyEnvironmentBlock ( IN LPCSTR Environment OPTIONAL ,
IN LPCSTR ProgramName )
2015-05-01 15:42:54 +00:00
{
PCHAR Ptr , DestBuffer = NULL ;
ULONG TotalSize = 0 ;
WORD DestSegment ;
/* If we have an environment strings list, compute its size */
if ( Environment )
{
/* Calculate the size of the environment block */
Ptr = ( PCHAR ) Environment ;
while ( * Ptr ) Ptr + = strlen ( Ptr ) + 1 ;
TotalSize = ( ULONG_PTR ) Ptr - ( ULONG_PTR ) Environment ;
}
else
{
/* Empty environment string */
TotalSize = 1 ;
}
/* Add the final environment block NULL-terminator */
TotalSize + + ;
/* Add the two bytes for the program name tag */
TotalSize + = 2 ;
/* Add the string buffer size */
TotalSize + = strlen ( ProgramName ) + 1 ;
/* Allocate the memory for the environment block */
DestSegment = DosAllocateMemory ( ( WORD ) ( ( TotalSize + 0x0F ) > > 4 ) , NULL ) ;
if ( ! DestSegment ) return 0 ;
DestBuffer = ( PCHAR ) SEG_OFF_TO_PTR ( DestSegment , 0 ) ;
/* If we have an environment strings list, copy it */
if ( Environment )
{
Ptr = ( PCHAR ) Environment ;
while ( * Ptr )
{
/* Copy the string and NULL-terminate it */
strcpy ( DestBuffer , Ptr ) ;
DestBuffer + = strlen ( Ptr ) ;
* ( DestBuffer + + ) = ' \0 ' ;
/* Move to the next string */
Ptr + = strlen ( Ptr ) + 1 ;
}
}
else
{
/* Empty environment string */
* ( DestBuffer + + ) = ' \0 ' ;
}
/* NULL-terminate the environment block */
* ( DestBuffer + + ) = ' \0 ' ;
/* Store the special program name tag */
* ( DestBuffer + + ) = LOBYTE ( DOS_PROGRAM_NAME_TAG ) ;
* ( DestBuffer + + ) = HIBYTE ( DOS_PROGRAM_NAME_TAG ) ;
/* Copy the program name after the environment block */
strcpy ( DestBuffer , ProgramName ) ;
return DestSegment ;
}
/* PUBLIC FUNCTIONS ***********************************************************/
VOID DosClonePsp ( WORD DestSegment , WORD SourceSegment )
{
2015-05-02 01:23:27 +00:00
PDOS_PSP DestPsp = SEGMENT_TO_PSP ( DestSegment ) ;
PDOS_PSP SourcePsp = SEGMENT_TO_PSP ( SourceSegment ) ;
2015-05-01 15:42:54 +00:00
LPDWORD IntVecTable = ( LPDWORD ) ( ( ULONG_PTR ) BaseAddress ) ;
/* Literally copy the PSP first */
2015-07-13 01:21:46 +00:00
RtlCopyMemory ( DestPsp , SourcePsp , sizeof ( * DestPsp ) ) ;
2015-05-01 15:42:54 +00:00
/* Save the interrupt vectors */
DestPsp - > TerminateAddress = IntVecTable [ 0x22 ] ;
DestPsp - > BreakAddress = IntVecTable [ 0x23 ] ;
DestPsp - > CriticalAddress = IntVecTable [ 0x24 ] ;
/* No parent PSP */
DestPsp - > ParentPsp = 0 ;
/* Set the handle table pointers to the internal handle table */
DestPsp - > HandleTableSize = DEFAULT_JFT_SIZE ;
2015-05-02 01:23:27 +00:00
DestPsp - > HandleTablePtr = MAKELONG ( 0x18 , DestSegment ) ;
2015-05-01 15:42:54 +00:00
/* Copy the parent handle table without referencing the SFT */
RtlCopyMemory ( FAR_POINTER ( DestPsp - > HandleTablePtr ) ,
FAR_POINTER ( SourcePsp - > HandleTablePtr ) ,
DEFAULT_JFT_SIZE ) ;
}
VOID DosCreatePsp ( WORD Segment , WORD ProgramSize )
{
2015-05-02 01:23:27 +00:00
PDOS_PSP PspBlock = SEGMENT_TO_PSP ( Segment ) ;
2015-05-01 15:42:54 +00:00
LPDWORD IntVecTable = ( LPDWORD ) ( ( ULONG_PTR ) BaseAddress ) ;
RtlZeroMemory ( PspBlock , sizeof ( * PspBlock ) ) ;
/* Set the exit interrupt */
PspBlock - > Exit [ 0 ] = 0xCD ; // int 0x20
PspBlock - > Exit [ 1 ] = 0x20 ;
/* Set the number of the last paragraph */
2015-07-29 02:03:48 +00:00
PspBlock - > LastParagraph = Segment + ProgramSize ;
2015-05-01 15:42:54 +00:00
/* Save the interrupt vectors */
PspBlock - > TerminateAddress = IntVecTable [ 0x22 ] ;
PspBlock - > BreakAddress = IntVecTable [ 0x23 ] ;
PspBlock - > CriticalAddress = IntVecTable [ 0x24 ] ;
/* Set the parent PSP */
2015-05-11 02:54:46 +00:00
PspBlock - > ParentPsp = Sda - > CurrentPsp ;
2015-05-01 15:42:54 +00:00
2015-06-05 22:22:04 +00:00
if ( Sda - > CurrentPsp ! = SYSTEM_PSP )
{
/* Link to the parent's environment block */
PspBlock - > EnvBlock = SEGMENT_TO_PSP ( Sda - > CurrentPsp ) - > EnvBlock ;
}
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
/*
else
{
PspBlock - > EnvBlock = SEG_OFF_TO_PTR ( SYSTEM_ENV_BLOCK , 0 ) ;
}
*/
2015-05-01 15:42:54 +00:00
/* Copy the parent handle table */
DosCopyHandleTable ( PspBlock - > HandleTable ) ;
/* Set the handle table pointers to the internal handle table */
PspBlock - > HandleTableSize = DEFAULT_JFT_SIZE ;
2015-05-02 01:23:27 +00:00
PspBlock - > HandleTablePtr = MAKELONG ( 0x18 , Segment ) ;
2015-05-01 15:42:54 +00:00
/* Set the DOS version */
2015-07-13 01:21:46 +00:00
// FIXME: This is here that SETVER stuff enters into action!
PspBlock - > DosVersion = DosData - > DosVersion ;
2015-05-01 15:42:54 +00:00
/* Set the far call opcodes */
PspBlock - > FarCall [ 0 ] = 0xCD ; // int 0x21
PspBlock - > FarCall [ 1 ] = 0x21 ;
PspBlock - > FarCall [ 2 ] = 0xCB ; // retf
}
VOID DosSetProcessContext ( WORD Segment )
{
2015-05-11 02:54:46 +00:00
Sda - > CurrentPsp = Segment ;
Sda - > DiskTransferArea = MAKELONG ( 0x80 , Segment ) ;
2015-05-01 15:42:54 +00:00
}
2015-08-17 20:11:51 +00:00
DWORD DosLoadExecutableInternal ( IN DOS_EXEC_TYPE LoadType ,
IN LPBYTE ExeBuffer ,
IN DWORD ExeBufferSize ,
IN LPCSTR ExePath ,
IN PDOS_EXEC_PARAM_BLOCK Parameters ,
IN LPCSTR CommandLine OPTIONAL ,
IN LPCSTR Environment OPTIONAL ,
IN DWORD ReturnAddress OPTIONAL )
2015-05-01 15:42:54 +00:00
{
DWORD Result = ERROR_SUCCESS ;
WORD Segment = 0 ;
WORD EnvBlock = 0 ;
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
WORD ExeSignature ;
2015-05-01 15:42:54 +00:00
WORD LoadSegment ;
WORD MaxAllocSize ;
2015-08-17 20:11:51 +00:00
WORD FinalSS , FinalSP ;
WORD FinalCS , FinalIP ;
2015-05-01 15:42:54 +00:00
2015-05-02 01:23:27 +00:00
/* Buffer for command line conversion: 1 byte for size; 127 bytes for contents */
CHAR CmdLineBuffer [ 1 + DOS_CMDLINE_LENGTH ] ;
2015-08-17 20:11:51 +00:00
DPRINT1 ( " DosLoadExecutableInternal(%d, 0x%p, '%s', 0x%p, 0x%p, 0x%p) \n " ,
LoadType , ExeBuffer , ExePath , Parameters , CommandLine , Environment ) ;
2015-05-01 15:42:54 +00:00
if ( LoadType ! = DOS_LOAD_OVERLAY )
{
2015-05-02 01:23:27 +00:00
/* If an optional Win32 command line is given... */
if ( CommandLine )
{
/* ... convert it into DOS format */
BYTE CmdLineLen ;
PBYTE CmdLineSize = ( PBYTE ) CmdLineBuffer ;
LPSTR CmdLineStart = CmdLineBuffer + 1 ;
LPSTR CmdLinePtr = CmdLineStart ;
// For debugging purposes
RtlFillMemory ( CmdLineBuffer , sizeof ( CmdLineBuffer ) , 0xFF ) ;
/*
* Set the command line : it is either an empty command line or has
* the format : " foo bar ... " ( with at least one leading whitespace ) ,
* and is then always followed by ' \r ' ( and optionally by ' \n ' ) .
*/
CmdLineLen = ( BYTE ) strlen ( CommandLine ) ;
* CmdLineSize = 0 ;
/*
* Add the leading space if the command line is not empty
* and doesn ' t already start with some whitespace . . .
*/
if ( * CommandLine & & * CommandLine ! = ' \r ' & & * CommandLine ! = ' \n ' & &
* CommandLine ! = ' ' & & * CommandLine ! = ' \t ' )
{
( * CmdLineSize ) + + ;
* CmdLinePtr + + = ' ' ;
}
2015-05-01 15:42:54 +00:00
2015-05-02 01:23:27 +00:00
/* Compute the number of characters we need to copy from the original command line */
CmdLineLen = min ( CmdLineLen , DOS_CMDLINE_LENGTH - * CmdLineSize ) ;
/* The trailing '\r' or '\n' do not count in the PSP command line size parameter */
while ( CmdLineLen & & ( CommandLine [ CmdLineLen - 1 ] = = ' \r ' | | CommandLine [ CmdLineLen - 1 ] = = ' \n ' ) )
{
CmdLineLen - - ;
}
/* Finally, set everything up */
* CmdLineSize + = CmdLineLen ;
RtlCopyMemory ( CmdLinePtr , CommandLine , CmdLineLen ) ;
CmdLineStart [ * CmdLineSize ] = ' \r ' ;
/* Finally make the pointer point to the static buffer */
CommandLine = CmdLineBuffer ;
}
else
2015-05-01 15:42:54 +00:00
{
2015-05-02 01:23:27 +00:00
/*
* . . . otherwise , get the one from the parameter block .
* Format of the command line : 1 byte for size ; 127 bytes for contents .
*/
ASSERT ( Parameters ) ;
2015-05-01 15:42:54 +00:00
CommandLine = ( LPCSTR ) FAR_POINTER ( Parameters - > CommandLine ) ;
}
2015-05-02 01:23:27 +00:00
/* If no optional environment is given... */
2015-05-01 15:42:54 +00:00
if ( Environment = = NULL )
{
2015-05-02 01:23:27 +00:00
ASSERT ( Parameters ) ;
2015-07-13 01:21:46 +00:00
/* ... get the one from the parameter block (if not NULL)... */
if ( Parameters - > Environment )
Environment = ( LPCSTR ) SEG_OFF_TO_PTR ( Parameters - > Environment , 0 ) ;
/* ... or the one from the parent (otherwise) */
else
Environment = ( LPCSTR ) SEG_OFF_TO_PTR ( SEGMENT_TO_PSP ( Sda - > CurrentPsp ) - > EnvBlock , 0 ) ;
2015-05-01 15:42:54 +00:00
}
/* Copy the environment block to DOS memory */
2015-08-17 20:11:51 +00:00
EnvBlock = DosCopyEnvironmentBlock ( Environment , ExePath ) ;
2015-05-01 15:42:54 +00:00
if ( EnvBlock = = 0 )
{
2015-07-13 01:21:46 +00:00
Result = Sda - > LastErrorCode ;
2015-05-01 15:42:54 +00:00
goto Cleanup ;
}
}
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
/*
* Check if this is an EXE file or a COM file by looking
* at the MZ signature :
* 0x4D5A ' MZ ' : old signature ( stored as 0x5A , 0x4D )
* 0x5A4D ' ZM ' : new signature ( stored as 0x4D , 0x5A )
*/
ExeSignature = * ( PWORD ) ExeBuffer ;
if ( ExeSignature = = ' MZ ' | | ExeSignature = = ' ZM ' )
2015-05-01 15:42:54 +00:00
{
/* EXE file */
PIMAGE_DOS_HEADER Header ;
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
DWORD BaseSize ;
2015-05-01 15:42:54 +00:00
PDWORD RelocationTable ;
PWORD RelocWord ;
WORD RelocFactor ;
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
WORD i ;
2015-05-01 15:42:54 +00:00
/* Get the MZ header */
2015-08-17 20:11:51 +00:00
Header = ( PIMAGE_DOS_HEADER ) ExeBuffer ;
2015-05-01 15:42:54 +00:00
/* Get the base size of the file, in paragraphs (rounded up) */
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
#if 0 // Normally this is not needed to check for the number of bytes in the last pages.
BaseSize = ( ( ( ( Header - > e_cp - ( Header - > e_cblp ! = 0 ) ) * 512 ) + Header - > e_cblp ) > > 4 )
- Header - > e_cparhdr ;
# else
// e_cp is the number of 512-byte blocks. 512 == (1 << 9)
// so this corresponds to (1 << 5) number of paragraphs.
//
// For DOS compatibility we need to truncate BaseSize to a WORD value.
// This fact is exploited by some EXEs which are bigger than 1 Mb while
// being able to load on DOS, the main EXE code loads the remaining data.
BaseSize = ( ( Header - > e_cp < < 5 ) - Header - > e_cparhdr ) & 0xFFFF ;
# endif
2015-05-01 15:42:54 +00:00
if ( LoadType ! = DOS_LOAD_OVERLAY )
{
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
BOOLEAN LoadHigh = FALSE ;
DWORD TotalSize ;
2015-05-01 15:42:54 +00:00
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
/* Find the maximum amount of memory that can be allocated */
DosAllocateMemory ( 0xFFFF , & MaxAllocSize ) ;
2015-05-01 15:42:54 +00:00
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
/* Compute the total needed size, in paragraphs */
TotalSize = BaseSize + ( sizeof ( DOS_PSP ) > > 4 ) ;
2015-05-01 15:42:54 +00:00
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
/* We must have the required minimum amount of memory. If not, bail out. */
if ( MaxAllocSize < TotalSize + Header - > e_minalloc )
2015-05-01 15:42:54 +00:00
{
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
Result = ERROR_NOT_ENOUGH_MEMORY ;
goto Cleanup ;
2015-05-01 15:42:54 +00:00
}
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
/* Check if the program should be loaded high */
if ( Header - > e_minalloc = = 0 & & Header - > e_maxalloc = = 0 )
{
/* Yes it should. Use all the available memory. */
LoadHigh = TRUE ;
TotalSize = MaxAllocSize ;
}
else
{
/* Compute the maximum memory size that can be allocated */
if ( Header - > e_maxalloc ! = 0 )
TotalSize = min ( TotalSize + Header - > e_maxalloc , MaxAllocSize ) ;
else
TotalSize = MaxAllocSize ; // Use all the available memory
}
2015-05-01 15:42:54 +00:00
/* Try to allocate that much memory */
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
Segment = DosAllocateMemory ( ( WORD ) TotalSize , NULL ) ;
2015-05-01 15:42:54 +00:00
if ( Segment = = 0 )
{
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
Result = Sda - > LastErrorCode ;
goto Cleanup ;
2015-05-01 15:42:54 +00:00
}
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
/* The process owns its memory */
2015-08-17 20:11:51 +00:00
DosChangeMemoryOwner ( Segment , Segment ) ;
2015-05-01 15:42:54 +00:00
DosChangeMemoryOwner ( EnvBlock , Segment ) ;
2015-06-07 20:29:56 +00:00
/* Set INT 22h to the return address */
( ( PULONG ) BaseAddress ) [ 0x22 ] = ReturnAddress ;
2015-05-01 15:42:54 +00:00
2015-08-18 12:26:38 +00:00
/* Create the PSP and initialize it */
2015-05-01 15:42:54 +00:00
DosCreatePsp ( Segment , ( WORD ) TotalSize ) ;
2015-08-18 12:26:38 +00:00
DosInitPsp ( Segment , EnvBlock , CommandLine , ExePath ) ;
2015-05-01 15:42:54 +00:00
/* Calculate the segment where the program should be loaded */
2015-07-13 01:21:46 +00:00
if ( ! LoadHigh )
LoadSegment = Segment + ( sizeof ( DOS_PSP ) > > 4 ) ;
else
LoadSegment = Segment + TotalSize - BaseSize ;
2015-05-01 15:42:54 +00:00
RelocFactor = LoadSegment ;
}
else
{
2015-05-02 01:23:27 +00:00
ASSERT ( Parameters ) ;
2015-05-01 15:42:54 +00:00
LoadSegment = Parameters - > Overlay . Segment ;
RelocFactor = Parameters - > Overlay . RelocationFactor ;
}
/* Copy the program to the code segment */
RtlCopyMemory ( SEG_OFF_TO_PTR ( LoadSegment , 0 ) ,
2015-08-17 20:11:51 +00:00
ExeBuffer + ( Header - > e_cparhdr < < 4 ) ,
min ( ExeBufferSize - ( Header - > e_cparhdr < < 4 ) , BaseSize < < 4 ) ) ;
2015-05-01 15:42:54 +00:00
/* Get the relocation table */
2015-08-17 20:11:51 +00:00
RelocationTable = ( PDWORD ) ( ExeBuffer + Header - > e_lfarlc ) ;
2015-05-01 15:42:54 +00:00
/* Perform relocations */
for ( i = 0 ; i < Header - > e_crlc ; i + + )
{
/* Get a pointer to the word that needs to be patched */
RelocWord = ( PWORD ) SEG_OFF_TO_PTR ( LoadSegment + HIWORD ( RelocationTable [ i ] ) ,
LOWORD ( RelocationTable [ i ] ) ) ;
/* Add the relocation factor to it */
* RelocWord + = RelocFactor ;
}
2015-08-17 20:11:51 +00:00
/* Set the stack to the location from the header */
FinalSS = LoadSegment + Header - > e_ss ;
FinalSP = Header - > e_sp ;
2015-05-11 23:04:24 +00:00
2015-08-17 20:11:51 +00:00
/* Set the code segment/pointer */
FinalCS = LoadSegment + Header - > e_cs ;
FinalIP = Header - > e_ip ;
2015-05-01 15:42:54 +00:00
}
else
{
/* COM file */
if ( LoadType ! = DOS_LOAD_OVERLAY )
{
/* Find the maximum amount of memory that can be allocated */
DosAllocateMemory ( 0xFFFF , & MaxAllocSize ) ;
/* Make sure it's enough for the whole program and the PSP */
2015-08-17 20:11:51 +00:00
if ( ( ( DWORD ) MaxAllocSize < < 4 ) < ( ExeBufferSize + sizeof ( DOS_PSP ) ) )
2015-05-01 15:42:54 +00:00
{
Result = ERROR_NOT_ENOUGH_MEMORY ;
goto Cleanup ;
}
/* Allocate all of it */
Segment = DosAllocateMemory ( MaxAllocSize , NULL ) ;
if ( Segment = = 0 )
{
2015-05-11 02:54:46 +00:00
Result = Sda - > LastErrorCode ;
2015-05-01 15:42:54 +00:00
goto Cleanup ;
}
[NTVDM]
- Support loading executables with the old EXE signature ('ZM' instead of 'MZ').
- Fix the EXE loader so that:
* we can load programs of >= 1Mb size, by exploiting the fact that on real DOS, the computed exe size (which uses the number of 512-byte blocks, stored in the EXE header) is stored in a WORD variable.
This has as an effect to truncate the value, and if it is such that the truncated value is less than the size of available memory, the EXE can be loaded (partly, of course). Some apps expect this behaviour,
for example, Turbo C++ IDE.
* Simplify the memory limits computation, according to http://www.tavi.co.uk/phobos/exeformat.html , which is the correct algorithm used by DOS (and confirmed by FreeDOS also).
svn path=/trunk/; revision=69261
2015-09-17 23:04:05 +00:00
/* The process owns its memory */
2015-08-17 20:11:51 +00:00
DosChangeMemoryOwner ( Segment , Segment ) ;
2015-05-01 15:42:54 +00:00
DosChangeMemoryOwner ( EnvBlock , Segment ) ;
2015-06-07 20:29:56 +00:00
/* Set INT 22h to the return address */
( ( PULONG ) BaseAddress ) [ 0x22 ] = ReturnAddress ;
2015-05-01 15:42:54 +00:00
2015-08-18 12:26:38 +00:00
/* Create the PSP and initialize it */
2015-05-01 15:42:54 +00:00
DosCreatePsp ( Segment , MaxAllocSize ) ;
2015-08-18 12:26:38 +00:00
DosInitPsp ( Segment , EnvBlock , CommandLine , ExePath ) ;
2015-05-01 15:42:54 +00:00
/* Calculate the segment where the program should be loaded */
LoadSegment = Segment + ( sizeof ( DOS_PSP ) > > 4 ) ;
}
else
{
2015-05-02 01:23:27 +00:00
ASSERT ( Parameters ) ;
2015-05-01 15:42:54 +00:00
LoadSegment = Parameters - > Overlay . Segment ;
}
2015-05-02 01:23:27 +00:00
/* Copy the program to the code segment */
2015-05-01 15:42:54 +00:00
RtlCopyMemory ( SEG_OFF_TO_PTR ( LoadSegment , 0 ) ,
2015-08-17 20:11:51 +00:00
ExeBuffer , ExeBufferSize ) ;
2015-05-01 15:42:54 +00:00
2015-08-17 20:11:51 +00:00
/* Set the stack to the last word of the segment */
FinalSS = Segment ;
FinalSP = 0xFFFE ;
2015-05-01 15:42:54 +00:00
2015-08-17 20:11:51 +00:00
/*
* Set the value on the stack to 0x0000 , so that a near return
* jumps to PSP : 0000 which has the exit code .
*/
* ( ( LPWORD ) SEG_OFF_TO_PTR ( Segment , 0xFFFE ) ) = 0x0000 ;
2015-05-01 15:42:54 +00:00
2015-08-17 20:11:51 +00:00
/* Set the code segment/pointer */
FinalCS = Segment ;
FinalIP = 0x0100 ;
}
2015-05-11 23:04:24 +00:00
2015-08-17 20:11:51 +00:00
if ( LoadType = = DOS_LOAD_AND_EXECUTE )
{
/* Save the program state */
if ( Sda - > CurrentPsp ! = SYSTEM_PSP )
2015-05-01 15:42:54 +00:00
{
2015-08-17 20:11:51 +00:00
/* Push the task state */
DosSaveState ( ) ;
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
DPRINT1 ( " Sda->CurrentPsp = 0x%04x; Old LastStack = 0x%08x, New LastStack = 0x%08x \n " ,
Sda - > CurrentPsp , SEGMENT_TO_PSP ( Sda - > CurrentPsp ) - > LastStack , MAKELONG ( getSP ( ) , getSS ( ) ) ) ;
2015-08-17 20:11:51 +00:00
/* Update the last stack in the PSP */
SEGMENT_TO_PSP ( Sda - > CurrentPsp ) - > LastStack = MAKELONG ( getSP ( ) , getSS ( ) ) ;
2015-05-01 15:42:54 +00:00
}
2015-08-17 20:11:51 +00:00
/* Set the initial segment registers */
setDS ( Segment ) ;
setES ( Segment ) ;
/* Set the stack */
setSS ( FinalSS ) ;
setSP ( FinalSP ) ;
/*
* Set the other registers as in real DOS : some demos expect them so !
* See http : //www.fysnet.net/yourhelp.htm
* and http : //www.beroset.com/asm/showregs.asm
*/
setDX ( Segment ) ;
setDI ( FinalSP ) ;
2015-08-17 20:22:10 +00:00
setBP ( 0x091E ) ; // DOS base stack pointer relic value. In MS-DOS 5.0 and Windows' NTVDM it's 0x091C. This is in fact the old SP value inside DosData disk stack.
2015-08-17 20:11:51 +00:00
setSI ( FinalIP ) ;
setAX ( 0 /*0xFFFF*/ ) ; // FIXME: fcbcode
setBX ( 0 /*0xFFFF*/ ) ; // FIXME: fcbcode
setCX ( 0x00FF ) ;
/*
* Keep critical flags , clear test flags ( OF , SF , ZF , AF , PF , CF )
* and explicitely set the interrupt flag .
*/
setEFLAGS ( ( getEFLAGS ( ) & ~ 0x08D5 ) | 0x0200 ) ;
/* Notify VDDs of process execution */
VDDCreateUserHook ( Segment ) ;
/* Execute */
DosSetProcessContext ( Segment ) ;
CpuExecute ( FinalCS , FinalIP ) ;
}
else if ( LoadType = = DOS_LOAD_ONLY )
{
ASSERT ( Parameters ) ;
Parameters - > StackLocation = MAKELONG ( FinalSP , FinalSS ) ;
Parameters - > EntryPoint = MAKELONG ( FinalIP , FinalCS ) ;
2015-05-01 15:42:54 +00:00
}
Cleanup :
if ( Result ! = ERROR_SUCCESS )
{
/* It was not successful, cleanup the DOS memory */
if ( EnvBlock ) DosFreeMemory ( EnvBlock ) ;
2015-05-11 23:04:24 +00:00
if ( Segment ) DosFreeMemory ( Segment ) ;
2015-05-01 15:42:54 +00:00
}
2015-08-17 20:11:51 +00:00
return Result ;
}
DWORD DosLoadExecutable ( IN DOS_EXEC_TYPE LoadType ,
IN LPCSTR ExecutablePath ,
IN PDOS_EXEC_PARAM_BLOCK Parameters ,
IN LPCSTR CommandLine OPTIONAL ,
IN LPCSTR Environment OPTIONAL ,
IN DWORD ReturnAddress OPTIONAL )
{
DWORD Result = ERROR_SUCCESS ;
HANDLE FileHandle = INVALID_HANDLE_VALUE , FileMapping = NULL ;
DWORD FileSize ;
LPBYTE Address = NULL ;
CHAR FullPath [ MAX_PATH ] ;
CHAR ShortFullPath [ MAX_PATH ] ;
DPRINT1 ( " DosLoadExecutable(%d, '%s', 0x%p, 0x%p, 0x%p) \n " ,
LoadType , ExecutablePath , Parameters , CommandLine , Environment ) ;
/* Try to get the full path to the executable */
if ( GetFullPathNameA ( ExecutablePath , sizeof ( FullPath ) , FullPath , NULL ) )
{
/* Get the corresponding short path */
if ( GetShortPathNameA ( FullPath , ShortFullPath , sizeof ( ShortFullPath ) ) )
{
/* Use the shortened full path from now on */
ExecutablePath = ShortFullPath ;
}
}
/* Open a handle to the executable */
FileHandle = CreateFileA ( ExecutablePath ,
GENERIC_READ ,
FILE_SHARE_READ ,
NULL ,
OPEN_EXISTING ,
FILE_ATTRIBUTE_NORMAL ,
NULL ) ;
if ( FileHandle = = INVALID_HANDLE_VALUE )
{
Result = GetLastError ( ) ;
goto Cleanup ;
}
/* Get the file size */
FileSize = GetFileSize ( FileHandle , NULL ) ;
/* Create a mapping object for the file */
FileMapping = CreateFileMapping ( FileHandle ,
NULL ,
PAGE_READONLY ,
0 ,
0 ,
NULL ) ;
if ( FileMapping = = NULL )
{
Result = GetLastError ( ) ;
goto Cleanup ;
}
/* Map the file into memory */
Address = ( LPBYTE ) MapViewOfFile ( FileMapping , FILE_MAP_READ , 0 , 0 , 0 ) ;
if ( Address = = NULL )
{
Result = GetLastError ( ) ;
goto Cleanup ;
}
Result = DosLoadExecutableInternal ( LoadType ,
Address ,
FileSize ,
ExecutablePath ,
Parameters ,
CommandLine ,
Environment ,
ReturnAddress ) ;
Cleanup :
2015-05-01 15:42:54 +00:00
/* Unmap the file*/
if ( Address ! = NULL ) UnmapViewOfFile ( Address ) ;
/* Close the file mapping object */
if ( FileMapping ! = NULL ) CloseHandle ( FileMapping ) ;
/* Close the file handle */
if ( FileHandle ! = INVALID_HANDLE_VALUE ) CloseHandle ( FileHandle ) ;
return Result ;
}
2015-08-17 20:11:51 +00:00
WORD DosCreateProcess ( IN LPCSTR ProgramName ,
IN PDOS_EXEC_PARAM_BLOCK Parameters ,
IN DWORD ReturnAddress OPTIONAL )
2015-05-01 15:42:54 +00:00
{
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
DWORD Result = ERROR_SUCCESS ;
2015-05-01 15:42:54 +00:00
DWORD BinaryType ;
/* Get the binary type */
if ( ! GetBinaryTypeA ( ProgramName , & BinaryType ) ) return GetLastError ( ) ;
/* Check the type of the program */
switch ( BinaryType )
{
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
/* Those are handled by NTVDM */
2015-05-01 15:42:54 +00:00
case SCS_WOW_BINARY :
{
2016-09-04 11:46:08 +00:00
DisplayMessage ( L " Trying to load '%S'. \n "
L " WOW16 applications are not supported internally by NTVDM at the moment. \n "
L " Press 'OK' to continue. " ,
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
ProgramName ) ;
// Fall through
}
case SCS_DOS_BINARY :
{
2015-05-01 15:42:54 +00:00
/* Load the executable */
Result = DosLoadExecutable ( DOS_LOAD_AND_EXECUTE ,
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
ProgramName ,
2015-05-01 15:42:54 +00:00
Parameters ,
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
NULL ,
NULL ,
2015-06-07 20:29:56 +00:00
ReturnAddress ) ;
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
if ( Result ! = ERROR_SUCCESS )
2015-05-01 15:42:54 +00:00
{
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
DisplayMessage ( L " Could not load '%S'. Error: %u " , ProgramName , Result ) ;
2015-05-01 15:42:54 +00:00
}
break ;
}
/* Not handled by NTVDM */
default :
{
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
LPSTR Environment = NULL ;
CHAR CmdLine [ MAX_PATH + DOS_CMDLINE_LENGTH + 1 ] ;
LPSTR CmdLinePtr ;
ULONG CmdLineSize ;
/* Did the caller specify an environment segment? */
if ( Parameters - > Environment )
{
/* Yes, use it instead of the parent one */
Environment = ( LPSTR ) SEG_OFF_TO_PTR ( Parameters - > Environment , 0 ) ;
}
2015-05-01 15:42:54 +00:00
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
/*
* Convert the DOS command line to Win32 - compatible format , by concatenating
* the program name with the converted command line .
* Format of the DOS command line : 1 byte for size ; 127 bytes for contents .
*/
CmdLinePtr = CmdLine ;
strncpy ( CmdLinePtr , ProgramName , MAX_PATH ) ; // Concatenate the program name
CmdLinePtr + = strlen ( CmdLinePtr ) ;
* CmdLinePtr + + = ' ' ; // Add separating space
CmdLineSize = min ( * ( PBYTE ) FAR_POINTER ( Parameters - > CommandLine ) , DOS_CMDLINE_LENGTH ) ;
RtlCopyMemory ( CmdLinePtr ,
( LPSTR ) FAR_POINTER ( Parameters - > CommandLine ) + 1 ,
CmdLineSize ) ;
/* NULL-terminate it */
CmdLinePtr [ CmdLineSize ] = ' \0 ' ;
/* Remove any trailing return carriage character and NULL-terminate the command line */
while ( * CmdLinePtr & & * CmdLinePtr ! = ' \r ' & & * CmdLinePtr ! = ' \n ' ) CmdLinePtr + + ;
* CmdLinePtr = ' \0 ' ;
Result = DosStartProcess32 ( ProgramName , CmdLine ,
Environment , ReturnAddress ,
TRUE ) ;
if ( Result ! = ERROR_SUCCESS )
{
DisplayMessage ( L " Could not load 32-bit '%S'. Error: %u " , ProgramName , Result ) ;
}
2015-05-01 15:42:54 +00:00
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
break ;
}
}
2015-05-01 15:42:54 +00:00
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
return Result ;
2015-05-01 15:42:54 +00:00
}
VOID DosTerminateProcess ( WORD Psp , BYTE ReturnCode , WORD KeepResident )
{
[NTVDM]
EMS:
- Introduce (and use) helpers for checking validity of EMS handles.
- Do not hardcode the EMS page frame segment, but instead allow it to be changed (for now, it is still set to a default value; in the future, via some configuration file or via the registry). This is done by acquiring a UMB block (see after).
XMS:
- Implement functions 0x01 "Request HMA" and 0x02 "Release HMA".
- Fix the return value of functions 0x04 "Global disable A20" and 0x08 "Query free Extended Memory"; simplify code of function 0x0B "Move EMB".
- Halfplement function 0x0F "Reallocate Extended Memory Block" in the simple case of size reduction (size expansion is left to the programmer as an exercise :PP )
- Rewrite the UMB provider support (functions 0x10, 0x11, 0x12) by calling the Upper Memory Area manager helpers (see after) (this is closer to reality: UMBs are either provided by XMS driver itself, or by an EMS driver which hooks into the XMS driver chain -- as it is done with MS' himem+EMM386; sometimes all that stuff is contained inside one driver only --) instead of calling back into DOS. This is the DOS which calls XMS for getting the UMB blocks and initializing them! (and not the other way around as it was done in r68001!).
NTVDM:
- Introduce an "Upper Memory Area manager" which maintains a list of areas of upper memory (>= A000:0000 and <= FFFF:000F) that can be used as RAM blocks. It is intended to work closely with the NTVDM memory manager and be used by XMS for getting possible free UMBs, and by VDDs for implementing the VDDInclude/ExcludeMem APIs (which adds/remove blocks in/from the UMB pool; those are unaccessible to DOS if those APIs are called after NTVDM have been started, but are accessible by XMS).
DOS:
- Add a helper function for detecting early DOS arena corruptions (for debugging purposes only).
- Make the DOS memory manager really UMB-compatible. This means:
* not hardcoding the start of the UMB chain;
* getting all the available UMB blocks from XMS and initializing them, marking the reserved blocks as read-only (with a correct header; reserved blocks are eg. VGA memory area, ROM blocks...).
There is room for improvements obviously (see the FIXMEs in the code). Used documentation is mentioned in comments in the code.
This commit should fix quite some apps, as well as it fixes corruptions of loaded ROMs in upper memory: that's how I came into working on fixing the UMB support. In other words, during those two last weeks, I was like in: http://i.imgur.com/zoWpqEB.gifv
CORE-9969 #resolve
svn path=/trunk/; revision=68586
2015-08-01 17:07:07 +00:00
WORD McbSegment = SysVars - > FirstMcb ;
2015-05-01 15:42:54 +00:00
PDOS_MCB CurrentMcb ;
LPDWORD IntVecTable = ( LPDWORD ) ( ( ULONG_PTR ) BaseAddress ) ;
PDOS_PSP PspBlock = SEGMENT_TO_PSP ( Psp ) ;
2015-06-07 20:29:56 +00:00
LPWORD Stack ;
2015-08-17 20:11:51 +00:00
BYTE TerminationType ;
2015-05-01 15:42:54 +00:00
DPRINT ( " DosTerminateProcess: Psp 0x%04X, ReturnCode 0x%02X, KeepResident 0x%04X \n " ,
2015-08-17 20:11:51 +00:00
Psp , ReturnCode , KeepResident ) ;
2015-05-01 15:42:54 +00:00
2015-05-11 23:04:24 +00:00
/* Notify VDDs of process termination */
VDDTerminateUserHook ( Psp ) ;
2015-08-17 20:22:10 +00:00
/* Check if this PSP is its own parent */
2015-08-17 20:11:51 +00:00
if ( PspBlock - > ParentPsp = = Psp ) goto Done ;
2015-05-01 15:42:54 +00:00
if ( KeepResident = = 0 )
{
2015-08-17 20:11:51 +00:00
WORD i ;
2015-05-01 15:42:54 +00:00
for ( i = 0 ; i < PspBlock - > HandleTableSize ; i + + )
{
/* Close the handle */
DosCloseHandle ( i ) ;
}
}
/* Free the memory used by the process */
while ( TRUE )
{
/* Get a pointer to the MCB */
CurrentMcb = SEGMENT_TO_MCB ( McbSegment ) ;
/* Make sure the MCB is valid */
if ( CurrentMcb - > BlockType ! = ' M ' & & CurrentMcb - > BlockType ! = ' Z ' ) break ;
/* Check if this block was allocated by the process */
if ( CurrentMcb - > OwnerPsp = = Psp )
{
2015-05-02 02:59:21 +00:00
if ( KeepResident )
2015-05-01 15:42:54 +00:00
{
2015-05-02 02:59:21 +00:00
/* Check if this is the PSP block and we should reduce its size */
2015-05-05 03:52:25 +00:00
if ( ( McbSegment + 1 ) = = Psp & & KeepResident < CurrentMcb - > Size )
2015-05-02 02:59:21 +00:00
{
/* Reduce the size of the block */
DosResizeMemory ( McbSegment + 1 , KeepResident , NULL ) ;
break ;
}
2015-05-01 15:42:54 +00:00
}
else
{
2015-05-02 02:59:21 +00:00
/* Free this entire block */
DosFreeMemory ( McbSegment + 1 ) ;
2015-05-01 15:42:54 +00:00
}
}
/* If this was the last block, quit */
if ( CurrentMcb - > BlockType = = ' Z ' ) break ;
/* Update the segment and continue */
McbSegment + = CurrentMcb - > Size + 1 ;
}
Done :
/* Restore the interrupt vectors */
IntVecTable [ 0x22 ] = PspBlock - > TerminateAddress ;
IntVecTable [ 0x23 ] = PspBlock - > BreakAddress ;
IntVecTable [ 0x24 ] = PspBlock - > CriticalAddress ;
2015-08-17 20:11:51 +00:00
/* Update the current PSP with the parent's one */
2015-05-11 02:54:46 +00:00
if ( Psp = = Sda - > CurrentPsp )
2015-05-01 15:42:54 +00:00
{
2015-08-17 20:11:51 +00:00
DosSetProcessContext ( PspBlock - > ParentPsp ) ;
2015-05-11 02:54:46 +00:00
if ( Sda - > CurrentPsp = = SYSTEM_PSP )
2015-05-01 15:42:54 +00:00
{
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
// NOTE: we can also use the DOS BIOS exit code.
2015-05-01 15:42:54 +00:00
CpuUnsimulate ( ) ;
2015-05-02 18:51:03 +00:00
return ;
2015-05-01 15:42:54 +00:00
}
}
2015-08-17 20:11:51 +00:00
/* Save the return code - Normal termination or TSR */
TerminationType = ( KeepResident ! = 0 ? 0x03 : 0x00 ) ;
Sda - > ErrorLevel = MAKEWORD ( ReturnCode , TerminationType ) ;
2015-05-01 15:42:54 +00:00
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
DPRINT1 ( " PspBlock->ParentPsp = 0x%04x; Sda->CurrentPsp = 0x%04x \n " ,
PspBlock - > ParentPsp , Sda - > CurrentPsp ) ;
2015-08-17 20:11:51 +00:00
if ( Sda - > CurrentPsp ! = SYSTEM_PSP )
{
[NTVDM]
- Add support for DOS VDM reentry, i.e. the fact that a DOS app can start a 32-bit app, which in turn can start another DOS app, ad infinitum...
CORE-9711 CORE-9773 #resolve
- Add a small COMMAND.COM which is, for now, completely included in NTVDM. This COMMAND.COM is needed in order to support reentrancy. The fact that I chose to put it inside NTVDM is that any user can use instead his/her own COMMAND.COM, while retaining the possibility to perform VDM reentrancy (on Windows, if you remove the COMMAND.COM in windows\system32 and replace it with your own, you will break VDM reentrancy on windows' ntvdm).
CORE-5221 #resolve #comment I choose for the moment an internal COMMAND.COM, but you can recompile NTVDM to use it externally instead.
Global remarks:
- Quite a few DPRINTs were added for diagnostic purposes (since DOS reentrancy is a new feature), to be sure everything behaves as expected when being used with a large panel of applications. They will be removed when everything is OK.
- Support for current directories and 16/32-bit environment translation (in ntvdm + basevdm-side) remain to be implemented.
Other changes:
- Improve a bit the VDM shutdown code by gathering it at one place (there's still room for other improvements).
- Add suppport for properly pausing/resuming NTVDM.
- Bufferize some console events before dispatching.
Have fun ;^)
svn path=/trunk/; revision=69204
2015-09-12 20:09:25 +00:00
DPRINT1 ( " Sda->CurrentPsp = 0x%04x; Old SS:SP = %04X:%04X going to be LastStack = 0x%08x \n " ,
Sda - > CurrentPsp , getSS ( ) , getSP ( ) , SEGMENT_TO_PSP ( Sda - > CurrentPsp ) - > LastStack ) ;
2015-08-17 20:11:51 +00:00
/* Restore the parent's stack */
setSS ( HIWORD ( SEGMENT_TO_PSP ( Sda - > CurrentPsp ) - > LastStack ) ) ;
setSP ( LOWORD ( SEGMENT_TO_PSP ( Sda - > CurrentPsp ) - > LastStack ) ) ;
2015-05-02 02:59:21 +00:00
2015-08-17 20:11:51 +00:00
/* Pop the task state */
DosRestoreState ( ) ;
}
2015-05-02 18:51:03 +00:00
2015-05-01 15:42:54 +00:00
/* Return control to the parent process */
2015-06-07 20:29:56 +00:00
Stack = ( LPWORD ) SEG_OFF_TO_PTR ( getSS ( ) , getSP ( ) ) ;
Stack [ STACK_CS ] = HIWORD ( PspBlock - > TerminateAddress ) ;
Stack [ STACK_IP ] = LOWORD ( PspBlock - > TerminateAddress ) ;
2015-05-01 15:42:54 +00:00
}
2015-08-17 20:11:51 +00:00
/* EOF */