[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); DPRINT1("Starting '%s' ('%s')...\n", ApplicationName, CommandLine);
Result = DosStartProcess(ApplicationName, Result = DosStartProcess(ApplicationName,
CommandLine, CommandLine,
GetEnvironmentStrings()); SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0));
if (Result != ERROR_SUCCESS) if (Result != ERROR_SUCCESS)
{ {
DisplayMessage(L"Could not start '%S'. Error: %u", ApplicationName, Result); DisplayMessage(L"Could not start '%S'. Error: %u", ApplicationName, Result);

View file

@ -14,9 +14,19 @@
#include "int32.h" #include "int32.h"
#include "dos.h" #include "dos.h"
#include "bios/bios.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 **********************************************************/ /* PRIVATE VARIABLES **********************************************************/
// static BYTE CurrentDrive; // static BYTE CurrentDrive;
@ -81,9 +91,7 @@ BOOLEAN DosBIOSInitialize(VOID)
{ {
PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT); PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
LPWSTR SourcePtr, Environment; LPSTR SourcePtr, Environment;
LPSTR AsciiString;
DWORD AsciiSize;
LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0); LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
#if 0 #if 0
@ -114,55 +122,46 @@ BOOLEAN DosBIOSInitialize(VOID)
Mcb->OwnerPsp = 0; Mcb->OwnerPsp = 0;
/* Get the environment strings */ /* Get the environment strings */
SourcePtr = Environment = GetEnvironmentStringsW(); SourcePtr = Environment = GetEnvironmentStrings();
if (Environment == NULL) return FALSE; if (Environment == NULL) return FALSE;
/* Fill the DOS system environment block */ /* Fill the DOS system environment block */
while (*SourcePtr) while (*SourcePtr)
{ {
/* Get the size of the ASCII string */ /*
AsciiSize = WideCharToMultiByte(CP_ACP, * - Ignore environment strings starting with a '=',
0, * they describe current directories.
SourcePtr, * - Ignore also the WINDIR environment variable since
-1, * DOS apps should ignore that we started from ReactOS.
NULL, * - Upper-case the environment names, not their values.
0, */
NULL, if (*SourcePtr != '=' && _strnicmp(SourcePtr, "WINDIR", 6) != 0)
NULL);
/* Allocate memory for the ASCII string */
AsciiString = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, AsciiSize);
if (AsciiString == NULL)
{ {
FreeEnvironmentStringsW(Environment); PCHAR Delim = NULL;
return FALSE;
/* 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 */ /* Move to the next string */
SourcePtr += wcslen(SourcePtr) + 1; SourcePtr += strlen(SourcePtr) + 1;
DestPtr += strlen(AsciiString);
*(DestPtr++) = 0;
/* Free the memory */
HeapFree(GetProcessHeap(), 0, AsciiString);
} }
*DestPtr = 0; /* NULL-terminate the environment block */
*DestPtr = '\0';
/* Free the memory allocated for environment strings */ /* Free the memory allocated for environment strings */
FreeEnvironmentStringsW(Environment); FreeEnvironmentStrings(Environment);
#if 0 #if 0

View file

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

View file

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