[NTVDM][KERNEL32][BASESRV]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 17 May 2014 22:26:37 +0000 (22:26 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Sat, 17 May 2014 22:26:37 +0000 (22:26 +0000)
Modify BaseSrvFillCommandInfo to always return the correct lengths of the parameters.
In BaseSrvGetNextVDMCommand, check if BaseSrvFillCommandInfo failed.
In CommandThreadProc, expand the size of the environment if necessary.
Add a useful DPRINT1 in BiosKbdBufferPush.
Finish implementing BaseCreateVDMEnvironment.
In GetNextVDMCommand, return the correct lengths of parameters if BaseSrvGetNextVDMCommand
failed.

svn path=/trunk/; revision=63337

reactos/dll/win32/kernel32/client/vdm.c
reactos/subsystems/ntvdm/bios/bios32/kbdbios32.c
reactos/subsystems/ntvdm/ntvdm.c
reactos/subsystems/win/basesrv/vdm.c

index c37a3cf..e6fa9c3 100644 (file)
@@ -662,7 +662,8 @@ BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment,
 {
     BOOL Result;
     ULONG RegionSize, EnvironmentSize = 0;
 {
     BOOL Result;
     ULONG RegionSize, EnvironmentSize = 0;
-    PWCHAR p, Environment, NewEnvironment = NULL;
+    PWCHAR SourcePtr, DestPtr, Environment, NewEnvironment = NULL;
+    WCHAR PathBuffer[MAX_PATH];
     NTSTATUS Status;
 
     /* Make sure we have both strings */
     NTSTATUS Status;
 
     /* Make sure we have both strings */
@@ -695,8 +696,8 @@ BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment,
     }
 
     /* Count how much space the whole environment takes */
     }
 
     /* Count how much space the whole environment takes */
-    p = Environment;
-    while ((*p++ != UNICODE_NULL) && (*p != UNICODE_NULL)) EnvironmentSize++;
+    SourcePtr = Environment;
+    while ((*SourcePtr++ != UNICODE_NULL) && (*SourcePtr != UNICODE_NULL)) EnvironmentSize++;
     EnvironmentSize += sizeof(UNICODE_NULL);
 
     /* Allocate a new copy */
     EnvironmentSize += sizeof(UNICODE_NULL);
 
     /* Allocate a new copy */
@@ -715,16 +716,73 @@ BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment,
     }
 
     /* Begin parsing the new environment */
     }
 
     /* Begin parsing the new environment */
-    p = NewEnvironment;
+    SourcePtr = Environment;
+    DestPtr   = NewEnvironment;
 
 
-    /* FIXME: Code here */
-    DPRINT1("BaseCreateVDMEnvironment is half-plemented!\n");
+    while (*SourcePtr != UNICODE_NULL)
+    {
+        while (*SourcePtr != UNICODE_NULL)
+        {
+            if (*SourcePtr == L'=')
+            {
+                /* Store the '=' sign */
+                *DestPtr++ = *SourcePtr++;
+
+                /* Check if this is likely a full path */
+                if (isalphaW(SourcePtr[0])
+                    && (SourcePtr[1] == L':')
+                    && ((SourcePtr[2] == '\\') || (SourcePtr[2] == '/')))
+                {
+                    PWCHAR Delimiter = wcschr(SourcePtr, L';');
+                    ULONG NumChars;
+
+                    if (Delimiter != NULL)
+                    {
+                        wcsncpy(PathBuffer,
+                                SourcePtr,
+                                min(Delimiter - SourcePtr, MAX_PATH));
+
+                        /* Seek to the part after the delimiter */
+                        SourcePtr = Delimiter + 1;
+                    }
+                    else
+                    {
+                        wcsncpy(PathBuffer, SourcePtr, MAX_PATH);
+
+                        /* Seek to the end of the string */
+                        SourcePtr = wcschr(SourcePtr, UNICODE_NULL);
+                    }
+
+                    /* Convert the path into a short path */
+                    NumChars = GetShortPathNameW(PathBuffer,
+                                                 DestPtr,
+                                                 EnvironmentSize - (DestPtr - NewEnvironment));
+                    if (NumChars)
+                    {
+                        /*
+                         * If it failed, this block won't be executed, so it
+                         * will continue from the character after the '=' sign.
+                         */
+                        DestPtr += NumChars;
+
+                        /* Append the delimiter */
+                        if (Delimiter != NULL) *DestPtr++ = L';';
+                    }
+                }
+            }
+            else if (islowerW(*SourcePtr)) *DestPtr++ = toupperW(*SourcePtr++);
+            else *DestPtr++ = *SourcePtr++;
+        }
+
+        /* Copy the terminating NULL character */
+        *DestPtr++ = *SourcePtr++;
+    }
 
     /* Terminate it */
 
     /* Terminate it */
-    *p++ = UNICODE_NULL;
+    *DestPtr++ = UNICODE_NULL;
 
     /* Initialize the unicode string to hold it */
 
     /* Initialize the unicode string to hold it */
-    EnvironmentSize = (p - NewEnvironment) * sizeof(WCHAR);
+    EnvironmentSize = (DestPtr - NewEnvironment) * sizeof(WCHAR);
     RtlInitEmptyUnicodeString(UnicodeEnv, NewEnvironment, (USHORT)EnvironmentSize);
     UnicodeEnv->Length = (USHORT)EnvironmentSize;
 
     RtlInitEmptyUnicodeString(UnicodeEnv, NewEnvironment, (USHORT)EnvironmentSize);
     UnicodeEnv->Length = (USHORT)EnvironmentSize;
 
@@ -1267,6 +1325,16 @@ GetNextVDMCommand(PVDM_COMMAND_INFO CommandData)
 
                 if (!NT_SUCCESS(Status))
                 {
 
                 if (!NT_SUCCESS(Status))
                 {
+                    /* Store the correct lengths */
+                    CommandData->CmdLen = GetNextVdmCommand->CmdLen;
+                    CommandData->AppLen = GetNextVdmCommand->AppLen;
+                    CommandData->PifLen = GetNextVdmCommand->PifLen;
+                    CommandData->CurDirectoryLen = GetNextVdmCommand->CurDirectoryLen;
+                    CommandData->EnvLen = GetNextVdmCommand->EnvLen;
+                    CommandData->DesktopLen = GetNextVdmCommand->DesktopLen;
+                    CommandData->TitleLen = GetNextVdmCommand->TitleLen;
+                    CommandData->ReservedLen = GetNextVdmCommand->ReservedLen;
+
                     BaseSetLastNTError(Status);
                     goto Cleanup;
                 }
                     BaseSetLastNTError(Status);
                     goto Cleanup;
                 }
index d3a4ad8..11cbd28 100644 (file)
@@ -35,7 +35,11 @@ static BOOLEAN BiosKbdBufferPush(WORD Data)
     if (NextElement >= Bda->KeybdBufferEnd) NextElement = Bda->KeybdBufferStart;
 
     /* If it's full, fail */
     if (NextElement >= Bda->KeybdBufferEnd) NextElement = Bda->KeybdBufferStart;
 
     /* If it's full, fail */
-    if (NextElement == Bda->KeybdBufferHead) return FALSE;
+    if (NextElement == Bda->KeybdBufferHead)
+    {
+        DPRINT1("BIOS keyboard buffer full.\n");
+        return FALSE;
+    }
 
     /* Put the value in the queue */
     *((LPWORD)((ULONG_PTR)Bda + Bda->KeybdBufferTail)) = Data;
 
     /* Put the value in the queue */
     *((LPWORD)((ULONG_PTR)Bda + Bda->KeybdBufferTail)) = Data;
index 1239def..300c34f 100644 (file)
@@ -401,9 +401,11 @@ CommandThreadProc(LPVOID Parameter)
     CHAR PifFile[MAX_PATH];
     CHAR Desktop[MAX_PATH];
     CHAR Title[MAX_PATH];
     CHAR PifFile[MAX_PATH];
     CHAR Desktop[MAX_PATH];
     CHAR Title[MAX_PATH];
-    CHAR Env[MAX_PATH];
+    ULONG EnvSize = 256;
+    PVOID Env = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, EnvSize);
 
     UNREFERENCED_PARAMETER(Parameter);
 
     UNREFERENCED_PARAMETER(Parameter);
+    ASSERT(Env != NULL);
 
     do
     {
 
     do
     {
@@ -424,12 +426,23 @@ CommandThreadProc(LPVOID Parameter)
         CommandInfo.Title = Title;
         CommandInfo.TitleLen = sizeof(Title);
         CommandInfo.Env = Env;
         CommandInfo.Title = Title;
         CommandInfo.TitleLen = sizeof(Title);
         CommandInfo.Env = Env;
-        CommandInfo.EnvLen = sizeof(Env);
+        CommandInfo.EnvLen = EnvSize;
 
         if (First) CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;
 
 
         if (First) CommandInfo.VDMState |= VDM_FLAG_FIRST_TASK;
 
-        /* Wait for the next available VDM */
-        if (!GetNextVDMCommand(&CommandInfo)) break;
+        if (!GetNextVDMCommand(&CommandInfo))
+        {
+            if (CommandInfo.EnvLen > EnvSize)
+            {
+                /* Expand the environment size */
+                EnvSize = CommandInfo.EnvLen;
+                Env = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Env, EnvSize);
+
+                continue;
+            }
+
+            break;
+        }
 
         /* Start the process from the command line */
         DPRINT1("Starting '%s' ('%s')...\n", AppName, CmdLine);
 
         /* Start the process from the command line */
         DPRINT1("Starting '%s' ('%s')...\n", AppName, CmdLine);
@@ -445,6 +458,7 @@ CommandThreadProc(LPVOID Parameter)
     }
     while (AcceptCommands);
 
     }
     while (AcceptCommands);
 
+    HeapFree(GetProcessHeap(), 0, Env);
     return 0;
 }
 #endif
     return 0;
 }
 #endif
index 782918c..81873a1 100644 (file)
@@ -436,6 +436,8 @@ Cleanup:
 NTSTATUS NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
                                       PBASE_GET_NEXT_VDM_COMMAND Message)
 {
 NTSTATUS NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
                                       PBASE_GET_NEXT_VDM_COMMAND Message)
 {
+    NTSTATUS Status = STATUS_SUCCESS;
+
     /* Copy the data */
     Message->iTask = CommandInfo->TaskId;
     Message->StdIn = CommandInfo->StdIn;
     /* Copy the data */
     Message->iTask = CommandInfo->TaskId;
     Message->StdIn = CommandInfo->StdIn;
@@ -450,46 +452,61 @@ NTSTATUS NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
 
     if (CommandInfo->CmdLen && Message->CmdLen)
     {
 
     if (CommandInfo->CmdLen && Message->CmdLen)
     {
-        if (Message->CmdLen < CommandInfo->CmdLen) return STATUS_BUFFER_TOO_SMALL;
+        if (Message->CmdLen >= CommandInfo->CmdLen)
+        {
+            /* Copy the command line */
+            RtlMoveMemory(Message->CmdLine, CommandInfo->CmdLine, CommandInfo->CmdLen);
+        }
+        else Status = STATUS_BUFFER_TOO_SMALL;
 
 
-        /* Copy the command line */
-        RtlMoveMemory(Message->CmdLine, CommandInfo->CmdLine, CommandInfo->CmdLen);
         Message->CmdLen = CommandInfo->CmdLen;
     }
 
     if (CommandInfo->AppLen && Message->AppLen)
     {
         Message->CmdLen = CommandInfo->CmdLen;
     }
 
     if (CommandInfo->AppLen && Message->AppLen)
     {
-        if (Message->AppLen < CommandInfo->CmdLen) return STATUS_BUFFER_TOO_SMALL;
+        if (Message->AppLen >= CommandInfo->AppLen)
+        {
+            /* Copy the application name */
+            RtlMoveMemory(Message->AppName, CommandInfo->AppName, CommandInfo->AppLen);
+        }
+        else Status = STATUS_BUFFER_TOO_SMALL;
 
 
-        /* Copy the application name */
-        RtlMoveMemory(Message->AppName, CommandInfo->AppName, CommandInfo->AppLen);
         Message->AppLen = CommandInfo->AppLen;
     }
 
     if (CommandInfo->PifLen && Message->PifLen)
     {
         Message->AppLen = CommandInfo->AppLen;
     }
 
     if (CommandInfo->PifLen && Message->PifLen)
     {
-        if (Message->PifLen < CommandInfo->PifLen) return STATUS_BUFFER_TOO_SMALL;
+        if (Message->PifLen >= CommandInfo->PifLen)
+        {
+            /* Copy the PIF file name */
+            RtlMoveMemory(Message->PifFile, CommandInfo->PifFile, CommandInfo->PifLen);
+        }
+        else Status = STATUS_BUFFER_TOO_SMALL;
 
 
-        /* Copy the PIF file name */
-        RtlMoveMemory(Message->PifFile, CommandInfo->PifFile, CommandInfo->PifLen);
         Message->PifLen = CommandInfo->PifLen;
     }
 
     if (CommandInfo->CurDirectoryLen && Message->CurDirectoryLen)
     {
         Message->PifLen = CommandInfo->PifLen;
     }
 
     if (CommandInfo->CurDirectoryLen && Message->CurDirectoryLen)
     {
-        if (Message->CurDirectoryLen < CommandInfo->CurDirectoryLen) return STATUS_BUFFER_TOO_SMALL;
+        if (Message->CurDirectoryLen >= CommandInfo->CurDirectoryLen)
+        {
+            /* Copy the current directory */
+            RtlMoveMemory(Message->CurDirectory, CommandInfo->CurDirectory, CommandInfo->CurDirectoryLen);
+        }
+        else Status = STATUS_BUFFER_TOO_SMALL;
 
 
-        /* Copy the current directory */
-        RtlMoveMemory(Message->CurDirectory, CommandInfo->CurDirectory, CommandInfo->CurDirectoryLen);
         Message->CurDirectoryLen = CommandInfo->CurDirectoryLen;
     }
 
     if (CommandInfo->EnvLen && Message->EnvLen)
     {
         Message->CurDirectoryLen = CommandInfo->CurDirectoryLen;
     }
 
     if (CommandInfo->EnvLen && Message->EnvLen)
     {
-        if (Message->EnvLen < CommandInfo->EnvLen) return STATUS_BUFFER_TOO_SMALL;
+        if (Message->EnvLen >= CommandInfo->EnvLen)
+        {
+            /* Copy the environment */
+            RtlMoveMemory(Message->Env, CommandInfo->Env, CommandInfo->EnvLen);
+        }
+        else Status = STATUS_BUFFER_TOO_SMALL;
 
 
-        /* Copy the environment */
-        RtlMoveMemory(Message->Env, CommandInfo->Env, CommandInfo->EnvLen);
         Message->EnvLen = CommandInfo->EnvLen;
     }
 
         Message->EnvLen = CommandInfo->EnvLen;
     }
 
@@ -500,32 +517,41 @@ NTSTATUS NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
 
     if (CommandInfo->DesktopLen && Message->DesktopLen)
     {
 
     if (CommandInfo->DesktopLen && Message->DesktopLen)
     {
-        if (Message->DesktopLen < CommandInfo->DesktopLen) return STATUS_BUFFER_TOO_SMALL;
+        if (Message->DesktopLen >= CommandInfo->DesktopLen)
+        {
+            /* Copy the desktop name */
+            RtlMoveMemory(Message->Desktop, CommandInfo->Desktop, CommandInfo->DesktopLen);
+        }
+        else Status = STATUS_BUFFER_TOO_SMALL;
 
 
-        /* Copy the desktop name */
-        RtlMoveMemory(Message->Desktop, CommandInfo->Desktop, CommandInfo->DesktopLen);
         Message->DesktopLen = CommandInfo->DesktopLen;
     }
 
     if (CommandInfo->TitleLen && Message->TitleLen)
     {
         Message->DesktopLen = CommandInfo->DesktopLen;
     }
 
     if (CommandInfo->TitleLen && Message->TitleLen)
     {
-        if (Message->TitleLen < CommandInfo->TitleLen) return STATUS_BUFFER_TOO_SMALL;
+        if (Message->TitleLen >= CommandInfo->TitleLen)
+        {
+            /* Copy the title */
+            RtlMoveMemory(Message->Title, CommandInfo->Title, CommandInfo->TitleLen);
+        }
+        else Status = STATUS_BUFFER_TOO_SMALL;
 
 
-        /* Copy the title */
-        RtlMoveMemory(Message->Title, CommandInfo->Title, CommandInfo->TitleLen);
         Message->TitleLen = CommandInfo->TitleLen;
     }
 
     if (CommandInfo->ReservedLen && Message->ReservedLen)
     {
         Message->TitleLen = CommandInfo->TitleLen;
     }
 
     if (CommandInfo->ReservedLen && Message->ReservedLen)
     {
-        if (Message->ReservedLen < CommandInfo->ReservedLen) return STATUS_BUFFER_TOO_SMALL;
+        if (Message->ReservedLen >= CommandInfo->ReservedLen)
+        {
+            /* Copy the reserved parameter */
+            RtlMoveMemory(Message->Reserved, CommandInfo->Reserved, CommandInfo->ReservedLen);
+        }
+        else Status = STATUS_BUFFER_TOO_SMALL;
 
 
-        /* Copy the reserved parameter */
-        RtlMoveMemory(Message->Reserved, CommandInfo->Reserved, CommandInfo->ReservedLen);
         Message->ReservedLen = CommandInfo->ReservedLen;
     }
 
         Message->ReservedLen = CommandInfo->ReservedLen;
     }
 
-    return STATUS_SUCCESS;
+    return Status;
 }
 
 VOID NTAPI BaseInitializeVDM(VOID)
 }
 
 VOID NTAPI BaseInitializeVDM(VOID)
@@ -1017,6 +1043,7 @@ CSR_API(BaseSrvGetNextVDMCommand)
             {
                 /* Fill the command information */
                 Status = BaseSrvFillCommandInfo(DosRecord->CommandInfo, GetNextVdmCommandRequest);
             {
                 /* Fill the command information */
                 Status = BaseSrvFillCommandInfo(DosRecord->CommandInfo, GetNextVdmCommandRequest);
+                if (!NT_SUCCESS(Status)) goto Cleanup;
 
                 /* Free the command information, it's no longer needed */
                 BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
 
                 /* Free the command information, it's no longer needed */
                 BaseSrvFreeVDMInfo(DosRecord->CommandInfo);