[NTVDM:DOS]

- Use the correct environment strings block when starting DOS programs.
- When building the DOS master env block, remove the current directory env strings (they start with '='), upcase the environment names (not their values) and remove the WINDIR environment that we inherited when we started NTVDM DOS.

svn path=/trunk/; revision=65335
This commit is contained in:
Hermès Bélusca-Maïto 2014-11-09 00:49:17 +00:00
parent 612333a5c0
commit 0a21e7b198
4 changed files with 58 additions and 64 deletions

View file

@ -462,7 +462,7 @@ static VOID WINAPI DosStart(LPWORD Stack)
DPRINT1("Starting '%s' ('%s')...\n", ApplicationName, CommandLine);
Result = DosStartProcess(ApplicationName,
CommandLine,
GetEnvironmentStrings());
SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0));
if (Result != ERROR_SUCCESS)
{
DisplayMessage(L"Could not start '%S'. Error: %u", ApplicationName, Result);

View file

@ -14,9 +14,19 @@
#include "int32.h"
#include "dos.h"
#include "bios/bios.h"
// This is needed because on UNICODE this symbol is redirected to
// GetEnvironmentStringsW whereas on ANSI it corresponds to the real
// "ANSI" function (and GetEnvironmentStringsA is aliased to it).
#undef GetEnvironmentStrings
// Symmetrize the dumbness of the previous symbol: on UNICODE
// FreeEnvironmentStrings aliases to FreeEnvironmentStringsW but
// on "ANSI" FreeEnvironmentStrings aliases to FreeEnvironmentStringsA
#undef FreeEnvironmentStrings
#define FreeEnvironmentStrings FreeEnvironmentStringsA
/* PRIVATE VARIABLES **********************************************************/
// static BYTE CurrentDrive;
@ -81,9 +91,7 @@ BOOLEAN DosBIOSInitialize(VOID)
{
PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
LPWSTR SourcePtr, Environment;
LPSTR AsciiString;
DWORD AsciiSize;
LPSTR SourcePtr, Environment;
LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
#if 0
@ -114,55 +122,46 @@ BOOLEAN DosBIOSInitialize(VOID)
Mcb->OwnerPsp = 0;
/* Get the environment strings */
SourcePtr = Environment = GetEnvironmentStringsW();
SourcePtr = Environment = GetEnvironmentStrings();
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)
/*
* - Ignore environment strings starting with a '=',
* they describe current directories.
* - Ignore also the WINDIR environment variable since
* DOS apps should ignore that we started from ReactOS.
* - Upper-case the environment names, not their values.
*/
if (*SourcePtr != '=' && _strnicmp(SourcePtr, "WINDIR", 6) != 0)
{
FreeEnvironmentStringsW(Environment);
return FALSE;
PCHAR Delim = NULL;
/* Copy the environment string */
strcpy(DestPtr, SourcePtr);
/* Upper-case the environment name */
Delim = strchr(DestPtr, '='); // Find the '=' delimiter
if (Delim) *Delim = '\0'; // Temporarily replace it by NULL
_strupr(DestPtr); // Upper-case
if (Delim) *Delim = '='; // Restore the delimiter
DestPtr += strlen(SourcePtr);
/* NULL-terminate the environment string */
*(DestPtr++) = '\0';
}
/* 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);
SourcePtr += strlen(SourcePtr) + 1;
}
*DestPtr = 0;
/* NULL-terminate the environment block */
*DestPtr = '\0';
/* Free the memory allocated for environment strings */
FreeEnvironmentStringsW(Environment);
FreeEnvironmentStrings(Environment);
#if 0

View file

@ -403,7 +403,7 @@ static VOID DosChangeMemoryOwner(WORD Segment, WORD NewOwner)
Mcb->OwnerPsp = NewOwner;
}
static WORD DosCopyEnvironmentBlock(LPCVOID Environment, LPCSTR ProgramName)
static WORD DosCopyEnvironmentBlock(LPCSTR Environment, LPCSTR ProgramName)
{
PCHAR Ptr, DestBuffer = NULL;
ULONG TotalSize = 0;
@ -412,12 +412,8 @@ static WORD DosCopyEnvironmentBlock(LPCVOID Environment, LPCSTR ProgramName)
Ptr = (PCHAR)Environment;
/* Calculate the size of the environment block */
while (*Ptr)
{
TotalSize += strlen(Ptr) + 1;
Ptr += strlen(Ptr) + 1;
}
TotalSize++;
while (*Ptr) Ptr += strlen(Ptr) + 1;
TotalSize = (ULONG_PTR)Ptr - (ULONG_PTR)Environment + 1; // Add final NULL-terminator
/* Add the string buffer size */
TotalSize += strlen(ProgramName) + 1;
@ -434,19 +430,16 @@ static WORD DosCopyEnvironmentBlock(LPCVOID Environment, LPCSTR ProgramName)
DestBuffer = (PCHAR)SEG_OFF_TO_PTR(DestSegment, 0);
while (*Ptr)
{
/* Copy the string */
/* Copy the string and NULL-terminate it */
strcpy(DestBuffer, Ptr);
/* Advance to the next string */
DestBuffer += strlen(Ptr);
*(DestBuffer++) = '\0';
/* Move to the next string */
Ptr += strlen(Ptr) + 1;
/* Put a zero after the string */
*(DestBuffer++) = 0;
}
/* Set the final zero */
*(DestBuffer++) = 0;
/* NULL-terminate the environment block */
*(DestBuffer++) = '\0';
/* Store the special program name tag */
*(DestBuffer++) = LOBYTE(DOS_PROGRAM_NAME_TAG);
@ -907,7 +900,7 @@ VOID DosInitializePsp(WORD PspSegment, LPCSTR CommandLine, WORD ProgramSize, WOR
DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
IN PVOID Environment,
IN LPCSTR Environment,
OUT PDWORD StackLocation OPTIONAL,
OUT PDWORD EntryPoint OPTIONAL)
{
@ -1151,7 +1144,7 @@ Cleanup:
DWORD DosStartProcess(IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
IN PVOID Environment)
IN LPCSTR Environment)
{
DWORD Result;

View file

@ -224,7 +224,7 @@ DWORD DosLoadExecutable(
IN DOS_EXEC_TYPE LoadType,
IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
IN PVOID Environment,
IN LPCSTR Environment,
OUT PDWORD StackLocation OPTIONAL,
OUT PDWORD EntryPoint OPTIONAL
);
@ -233,9 +233,11 @@ WORD DosCreateProcess(
LPCSTR ProgramName,
PDOS_EXEC_PARAM_BLOCK Parameters
);
DWORD DosStartProcess(IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
IN PVOID Environment);
DWORD DosStartProcess(
IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
IN LPCSTR Environment
);
VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode);
BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle);