[NTVDM][KERNEL32][BASESRV]

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
This commit is contained in:
Aleksandar Andrejevic 2014-05-17 22:26:37 +00:00
parent bef68d6f6c
commit 22679f9a7c
4 changed files with 151 additions and 38 deletions

View file

@ -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;
}

View 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->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;

View file

@ -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

View file

@ -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);