- 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
DPRINT1("Starting '%s' ('%s')...\n", ApplicationName, CommandLine);
Result = DosStartProcess(ApplicationName,
CommandLine,
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);
if (Result != ERROR_SUCCESS)
{
DisplayMessage(L"Could not start '%S'. Error: %u", ApplicationName, Result);
#include "int32.h"
#include "dos.h"
#include "int32.h"
#include "dos.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;
/* PRIVATE VARIABLES **********************************************************/
// static BYTE CurrentDrive;
{
PDOS_MCB Mcb = SEGMENT_TO_MCB(FIRST_MCB_SEGMENT);
{
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
LPSTR DestPtr = (LPSTR)SEG_OFF_TO_PTR(SYSTEM_ENV_BLOCK, 0);
#if 0
Mcb->OwnerPsp = 0;
/* Get the environment strings */
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)
{
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;
- }
- /* Convert to ASCII */
- WideCharToMultiByte(CP_ACP,
- 0,
- SourcePtr,
- -1,
- AsciiString,
- AsciiSize,
- NULL,
- NULL);
+ /* Copy the environment string */
+ strcpy(DestPtr, SourcePtr);
- /* Copy the string into DOS memory */
- strcpy(DestPtr, AsciiString);
+ /* 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
- /* Move to the next string */
- SourcePtr += wcslen(SourcePtr) + 1;
- DestPtr += strlen(AsciiString);
- *(DestPtr++) = 0;
+ DestPtr += strlen(SourcePtr);
+
+ /* NULL-terminate the environment string */
+ *(DestPtr++) = '\0';
+ }
- /* Free the memory */
- HeapFree(GetProcessHeap(), 0, AsciiString);
+ /* Move to the next string */
+ SourcePtr += strlen(SourcePtr) + 1;
+ /* 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);
Mcb->OwnerPsp = 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;
{
PCHAR Ptr, DestBuffer = NULL;
ULONG TotalSize = 0;
Ptr = (PCHAR)Environment;
/* Calculate the size of the environment block */
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;
/* Add the string buffer size */
TotalSize += strlen(ProgramName) + 1;
DestBuffer = (PCHAR)SEG_OFF_TO_PTR(DestSegment, 0);
while (*Ptr)
{
DestBuffer = (PCHAR)SEG_OFF_TO_PTR(DestSegment, 0);
while (*Ptr)
{
+ /* Copy the string and NULL-terminate it */
-
- /* Advance to the next string */
DestBuffer += strlen(Ptr);
DestBuffer += strlen(Ptr);
- Ptr += strlen(Ptr) + 1;
+ *(DestBuffer++) = '\0';
- /* Put a zero after the string */
- *(DestBuffer++) = 0;
+ /* Move to the next string */
+ Ptr += strlen(Ptr) + 1;
-
- /* 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);
/* Store the special program name tag */
*(DestBuffer++) = LOBYTE(DOS_PROGRAM_NAME_TAG);
DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
DWORD DosLoadExecutable(IN DOS_EXEC_TYPE LoadType,
IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
OUT PDWORD StackLocation OPTIONAL,
OUT PDWORD EntryPoint OPTIONAL)
{
OUT PDWORD StackLocation OPTIONAL,
OUT PDWORD EntryPoint OPTIONAL)
{
DWORD DosStartProcess(IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
DWORD DosStartProcess(IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
IN DOS_EXEC_TYPE LoadType,
IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
IN DOS_EXEC_TYPE LoadType,
IN LPCSTR ExecutablePath,
IN LPCSTR CommandLine,
OUT PDWORD StackLocation OPTIONAL,
OUT PDWORD EntryPoint OPTIONAL
);
OUT PDWORD StackLocation OPTIONAL,
OUT PDWORD EntryPoint OPTIONAL
);
LPCSTR ProgramName,
PDOS_EXEC_PARAM_BLOCK Parameters
);
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);
VOID DosTerminateProcess(WORD Psp, BYTE ReturnCode);
BOOLEAN DosHandleIoctl(BYTE ControlCode, WORD FileHandle);