diff --git a/reactos/dll/win32/kernel32/client/vdm.c b/reactos/dll/win32/kernel32/client/vdm.c index c37a3cf3589..e6fa9c3a04b 100644 --- a/reactos/dll/win32/kernel32/client/vdm.c +++ b/reactos/dll/win32/kernel32/client/vdm.c @@ -662,7 +662,8 @@ BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment, { 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 */ @@ -695,8 +696,8 @@ BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment, } /* 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 */ @@ -715,16 +716,73 @@ BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment, } /* 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 */ - *p++ = UNICODE_NULL; + *DestPtr++ = UNICODE_NULL; /* 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; @@ -1267,6 +1325,16 @@ GetNextVDMCommand(PVDM_COMMAND_INFO CommandData) 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; } diff --git a/reactos/subsystems/ntvdm/bios/bios32/kbdbios32.c b/reactos/subsystems/ntvdm/bios/bios32/kbdbios32.c index d3a4ad8b3e0..11cbd28b735 100644 --- a/reactos/subsystems/ntvdm/bios/bios32/kbdbios32.c +++ b/reactos/subsystems/ntvdm/bios/bios32/kbdbios32.c @@ -35,7 +35,11 @@ static BOOLEAN BiosKbdBufferPush(WORD Data) 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; diff --git a/reactos/subsystems/ntvdm/ntvdm.c b/reactos/subsystems/ntvdm/ntvdm.c index 1239defc765..300c34fb9cc 100644 --- a/reactos/subsystems/ntvdm/ntvdm.c +++ b/reactos/subsystems/ntvdm/ntvdm.c @@ -401,9 +401,11 @@ CommandThreadProc(LPVOID Parameter) 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); + ASSERT(Env != NULL); do { @@ -424,12 +426,23 @@ CommandThreadProc(LPVOID Parameter) 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; - /* 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); @@ -445,6 +458,7 @@ CommandThreadProc(LPVOID Parameter) } while (AcceptCommands); + HeapFree(GetProcessHeap(), 0, Env); return 0; } #endif diff --git a/reactos/subsystems/win/basesrv/vdm.c b/reactos/subsystems/win/basesrv/vdm.c index 782918c48ce..81873a138c2 100644 --- a/reactos/subsystems/win/basesrv/vdm.c +++ b/reactos/subsystems/win/basesrv/vdm.c @@ -436,6 +436,8 @@ Cleanup: 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; @@ -450,46 +452,61 @@ NTSTATUS NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo, 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) { - 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) { - 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) { - 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) { - 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; } @@ -500,32 +517,41 @@ NTSTATUS NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo, 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) { - 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) { - 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; } - return STATUS_SUCCESS; + return Status; } VOID NTAPI BaseInitializeVDM(VOID) @@ -1017,6 +1043,7 @@ CSR_API(BaseSrvGetNextVDMCommand) { /* 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);