mirror of
https://github.com/reactos/reactos.git
synced 2024-12-28 18:15:11 +00:00
[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:
parent
bef68d6f6c
commit
22679f9a7c
4 changed files with 151 additions and 38 deletions
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue