[NTVDM:DOS]
authorHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 9 Nov 2014 00:49:17 +0000 (00:49 +0000)
committerHermès Bélusca-Maïto <hermes.belusca-maito@reactos.org>
Sun, 9 Nov 2014 00:49:17 +0000 (00:49 +0000)
- 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

reactos/subsystems/ntvdm/dos/dem.c
reactos/subsystems/ntvdm/dos/dos32krnl/bios.c
reactos/subsystems/ntvdm/dos/dos32krnl/dos.c
reactos/subsystems/ntvdm/dos/dos32krnl/dos.h

index 84443de..1d586b9 100644 (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);
index 5c0fbcc..7c44873 100644 (file)
 #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;
 
-        /* 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;
     }
-    *DestPtr = 0;
+    /* NULL-terminate the environment block */
+    *DestPtr = '\0';
 
     /* Free the memory allocated for environment strings */
-    FreeEnvironmentStringsW(Environment);
+    FreeEnvironmentStrings(Environment);
 
 
 #if 0
index 582e43c..743b4b6 100644 (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);
-        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);
@@ -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;
 
index dd44396..3da70b6 100644 (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);