Author: aandrejevic
Date: Mon Apr 7 23:16:22 2014
New Revision: 62683
URL:
http://svn.reactos.org/svn/reactos?rev=62683&view=rev
Log:
[BASESRV]
Fix BaseSrvCheckVDM - DOS records should be initialized with a state of VDM_NOT_LOADED.
Fix BaseSrvFillCommandInfo - Check the size of the buffers.
Start implementing BaseSrvGetNextVDMCommand.
Modified:
branches/ntvdm/dll/win32/kernel32/include/vdm.h
branches/ntvdm/include/reactos/subsys/win/vdm.h
branches/ntvdm/subsystems/win/basesrv/vdm.c
branches/ntvdm/subsystems/win/basesrv/vdm.h
Modified: branches/ntvdm/dll/win32/kernel32/include/vdm.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/dll/win32/kernel32/includ…
==============================================================================
--- branches/ntvdm/dll/win32/kernel32/include/vdm.h [iso-8859-1] (original)
+++ branches/ntvdm/dll/win32/kernel32/include/vdm.h [iso-8859-1] Mon Apr 7 23:16:22 2014
@@ -66,4 +66,17 @@
IN HANDLE hUserToken OPTIONAL
);
+BOOL
+WINAPI
+GetNextVDMCommand(
+ IN OUT PVDM_COMMAND_INFO CommandData OPTIONAL
+);
+
+VOID
+WINAPI
+ExitVDM(
+ IN BOOL IsWow,
+ IN ULONG iWowTask
+);
+
/* EOF */
Modified: branches/ntvdm/include/reactos/subsys/win/vdm.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/include/reactos/subsys/wi…
==============================================================================
--- branches/ntvdm/include/reactos/subsys/win/vdm.h [iso-8859-1] (original)
+++ branches/ntvdm/include/reactos/subsys/win/vdm.h [iso-8859-1] Mon Apr 7 23:16:22 2014
@@ -50,6 +50,7 @@
//
// VDM Magic Values
//
+#define VDM_FLAG_WOW 0x02
#define VDM_INC_REENTER_COUNT 0x10
#define VDM_DEC_REENTER_COUNT 0x20
Modified: branches/ntvdm/subsystems/win/basesrv/vdm.c
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/win/basesrv/vd…
==============================================================================
--- branches/ntvdm/subsystems/win/basesrv/vdm.c [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/win/basesrv/vdm.c [iso-8859-1] Mon Apr 7 23:16:22 2014
@@ -366,7 +366,7 @@
return Success;
}
-VOID NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
+NTSTATUS NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
PBASE_GET_NEXT_VDM_COMMAND Message)
{
/* Copy the data */
@@ -381,36 +381,46 @@
Message->VDMState = CommandInfo->VDMState;
Message->fComingFromBat = CommandInfo->ComingFromBat;
- if (CommandInfo->CmdLen)
- {
+ if (CommandInfo->CmdLen && Message->CmdLen)
+ {
+ if (Message->CmdLen < CommandInfo->CmdLen) return
STATUS_BUFFER_TOO_SMALL;
+
/* Copy the command line */
RtlMoveMemory(Message->CmdLine, CommandInfo->CmdLine,
CommandInfo->CmdLen);
Message->CmdLen = CommandInfo->CmdLen;
}
- if (CommandInfo->AppLen)
- {
+ if (CommandInfo->AppLen && Message->AppLen)
+ {
+ if (Message->AppLen < CommandInfo->CmdLen) return
STATUS_BUFFER_TOO_SMALL;
+
/* Copy the application name */
RtlMoveMemory(Message->AppName, CommandInfo->AppName,
CommandInfo->AppLen);
Message->AppLen = CommandInfo->AppLen;
}
- if (CommandInfo->PifLen)
- {
+ if (CommandInfo->PifLen && Message->PifLen)
+ {
+ if (Message->PifLen < CommandInfo->PifLen) return
STATUS_BUFFER_TOO_SMALL;
+
/* Copy the PIF file name */
RtlMoveMemory(Message->PifFile, CommandInfo->PifFile,
CommandInfo->PifLen);
Message->PifLen = CommandInfo->PifLen;
}
- if (CommandInfo->CurDirectoryLen)
- {
+ if (CommandInfo->CurDirectoryLen && Message->CurDirectoryLen)
+ {
+ if (Message->CurDirectoryLen < CommandInfo->CurDirectoryLen) return
STATUS_BUFFER_TOO_SMALL;
+
/* Copy the current directory */
RtlMoveMemory(Message->CurDirectory, CommandInfo->CurDirectory,
CommandInfo->CurDirectoryLen);
Message->CurDirectoryLen = CommandInfo->CurDirectoryLen;
}
- if (CommandInfo->EnvLen)
- {
+ if (CommandInfo->EnvLen && Message->EnvLen)
+ {
+ if (Message->EnvLen < CommandInfo->EnvLen) return
STATUS_BUFFER_TOO_SMALL;
+
/* Copy the environment */
RtlMoveMemory(Message->Env, CommandInfo->Env, CommandInfo->EnvLen);
Message->EnvLen = CommandInfo->EnvLen;
@@ -421,26 +431,34 @@
&CommandInfo->StartupInfo,
sizeof(STARTUPINFOA));
- if (CommandInfo->DesktopLen)
- {
+ if (CommandInfo->DesktopLen && Message->DesktopLen)
+ {
+ if (Message->DesktopLen < CommandInfo->DesktopLen) return
STATUS_BUFFER_TOO_SMALL;
+
/* Copy the desktop name */
RtlMoveMemory(Message->Desktop, CommandInfo->Desktop,
CommandInfo->DesktopLen);
Message->DesktopLen = CommandInfo->DesktopLen;
}
- if (CommandInfo->TitleLen)
- {
+ if (CommandInfo->TitleLen && Message->TitleLen)
+ {
+ if (Message->TitleLen < CommandInfo->TitleLen) return
STATUS_BUFFER_TOO_SMALL;
+
/* Copy the title */
RtlMoveMemory(Message->Title, CommandInfo->Title,
CommandInfo->TitleLen);
Message->TitleLen = CommandInfo->TitleLen;
}
- if (CommandInfo->ReservedLen)
- {
+ if (CommandInfo->ReservedLen && Message->ReservedLen)
+ {
+ if (Message->ReservedLen < CommandInfo->ReservedLen) return
STATUS_BUFFER_TOO_SMALL;
+
/* Copy the reserved parameter */
RtlMoveMemory(Message->Reserved, CommandInfo->Reserved,
CommandInfo->ReservedLen);
Message->ReservedLen = CommandInfo->ReservedLen;
}
+
+ return STATUS_SUCCESS;
}
VOID NTAPI BaseInitializeVDM(VOID)
@@ -459,7 +477,6 @@
{
NTSTATUS Status;
PBASE_CHECK_VDM CheckVdmRequest =
&((PBASE_API_MESSAGE)ApiMessage)->Data.CheckVDMRequest;
- PCSR_PROCESS ClientProcess;
PRTL_CRITICAL_SECTION CriticalSection = NULL;
PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
PVDM_DOS_RECORD DosRecord = NULL;
@@ -500,11 +517,6 @@
{
return STATUS_INVALID_PARAMETER;
}
-
- /* Lock the process */
- Status = CsrLockProcessByClientId(ApiMessage->Header.ClientId.UniqueProcess,
- &ClientProcess);
- if (!NT_SUCCESS(Status)) return Status;
CriticalSection = (CheckVdmRequest->BinaryType != BINARY_TYPE_SEPARATE_WOW)
? &DosCriticalSection
@@ -532,19 +544,18 @@
goto Cleanup;
}
+ /* Remember that the console record was allocated here */
+ NewConsoleRecord = TRUE;
+
/* Initialize the console record */
ConsoleRecord->ConsoleHandle = CheckVdmRequest->ConsoleHandle;
- ConsoleRecord->ProcessHandle = ClientProcess->ProcessHandle;
+ ConsoleRecord->ProcessHandle =
CsrGetClientThread()->Process->ProcessHandle;
ConsoleRecord->ServerEvent = ConsoleRecord->ClientEvent = NULL;
ConsoleRecord->ReenterCount = 0;
ConsoleRecord->CurrentDirs = NULL;
ConsoleRecord->CurDirsLength = 0;
ConsoleRecord->SessionId = GetNextDosSesId();
InitializeListHead(&ConsoleRecord->DosListHead);
- // TODO: The console record structure is incomplete
-
- /* Remember that the console record was allocated here */
- NewConsoleRecord = TRUE;
}
/* Allocate a new DOS record */
@@ -558,9 +569,8 @@
}
/* Initialize the DOS record */
- DosRecord->State = NewConsoleRecord ? VDM_NOT_LOADED : VDM_READY;
+ DosRecord->State = VDM_NOT_LOADED;
DosRecord->ExitCode = 0;
- // TODO: The DOS record structure is incomplete
Status = BaseSrvCreatePairWaitHandles(&DosRecord->ServerEvent,
&DosRecord->ClientEvent);
if (!NT_SUCCESS(Status)) goto Cleanup;
@@ -579,13 +589,19 @@
/* Add the DOS record */
InsertHeadList(&ConsoleRecord->DosListHead, &DosRecord->Entry);
+ if (ConsoleRecord->ServerEvent)
+ {
+ /* Signal the session event */
+ NtSetEvent(ConsoleRecord->ServerEvent, NULL);
+ }
+
if (NewConsoleRecord)
{
/* Add the console record */
InsertTailList(&VDMConsoleListHead, &ConsoleRecord->Entry);
}
- CheckVdmRequest->VDMState = DosRecord->State;
+ CheckVdmRequest->VDMState = NewConsoleRecord ? VDM_NOT_LOADED : VDM_READY;
Status = STATUS_SUCCESS;
}
else
@@ -630,9 +646,6 @@
/* Leave the critical section */
RtlLeaveCriticalSection(CriticalSection);
- /* Unlock the process */
- CsrUnlockProcess(ClientProcess);
-
return Status;
}
@@ -695,6 +708,7 @@
*/
if (ConsoleRecord->DosListHead.Flink ==
&ConsoleRecord->DosListHead)
{
+ if (ConsoleRecord->ServerEvent)
NtClose(ConsoleRecord->ServerEvent);
RemoveEntryList(&ConsoleRecord->Entry);
RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
}
@@ -761,8 +775,149 @@
CSR_API(BaseSrvGetNextVDMCommand)
{
- DPRINT1("%s not yet implemented\n", __FUNCTION__);
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PBASE_GET_NEXT_VDM_COMMAND GetNextVdmCommandRequest =
+ &((PBASE_API_MESSAGE)ApiMessage)->Data.GetNextVDMCommandRequest;
+ PRTL_CRITICAL_SECTION CriticalSection;
+ PLIST_ENTRY i = NULL;
+ PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
+ PVDM_DOS_RECORD DosRecord = NULL;
+
+ /* Validate the message buffers */
+ if (!CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&GetNextVdmCommandRequest->CmdLine,
+ GetNextVdmCommandRequest->CmdLen,
+ sizeof(*GetNextVdmCommandRequest->CmdLine))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&GetNextVdmCommandRequest->AppName,
+ GetNextVdmCommandRequest->AppLen,
+ sizeof(*GetNextVdmCommandRequest->AppName))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&GetNextVdmCommandRequest->PifFile,
+ GetNextVdmCommandRequest->PifLen,
+ sizeof(*GetNextVdmCommandRequest->PifFile))
+ || !CsrValidateMessageBuffer(ApiMessage,
+
(PVOID*)&GetNextVdmCommandRequest->CurDirectory,
+ GetNextVdmCommandRequest->CurDirectoryLen,
+ sizeof(*GetNextVdmCommandRequest->CurDirectory))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&GetNextVdmCommandRequest->Env,
+ GetNextVdmCommandRequest->EnvLen,
+ sizeof(*GetNextVdmCommandRequest->Env))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&GetNextVdmCommandRequest->Desktop,
+ GetNextVdmCommandRequest->DesktopLen,
+ sizeof(*GetNextVdmCommandRequest->Desktop))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&GetNextVdmCommandRequest->Title,
+ GetNextVdmCommandRequest->TitleLen,
+ sizeof(*GetNextVdmCommandRequest->Title))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&GetNextVdmCommandRequest->Reserved,
+ GetNextVdmCommandRequest->ReservedLen,
+ sizeof(*GetNextVdmCommandRequest->Reserved))
+ || !CsrValidateMessageBuffer(ApiMessage,
+
(PVOID*)&GetNextVdmCommandRequest->StartupInfo,
+ 1,
+ sizeof(STARTUPINFOA)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ CriticalSection = (GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW)
+ ? &WowCriticalSection
+ : &DosCriticalSection;
+
+ /* Enter the critical section */
+ RtlEnterCriticalSection(CriticalSection);
+
+ if (!(GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW))
+ {
+ if (GetNextVdmCommandRequest->iTask != 0)
+ {
+ /* Get the console record using the task ID */
+ Status = GetConsoleRecordBySessionId(GetNextVdmCommandRequest->iTask,
+ &ConsoleRecord);
+ }
+ else
+ {
+ /* Get the console record using the console handle */
+ Status = BaseSrvGetConsoleRecord(GetNextVdmCommandRequest->ConsoleHandle,
+ &ConsoleRecord);
+ }
+
+ /* Return the session ID */
+ GetNextVdmCommandRequest->iTask = ConsoleRecord->SessionId;
+ GetNextVdmCommandRequest->WaitObjectForVDM = NULL;
+
+ // HACK: I'm not sure if this should happen...
+ for (i = ConsoleRecord->DosListHead.Flink; i !=
&ConsoleRecord->DosListHead; i = i->Flink)
+ {
+ DosRecord = CONTAINING_RECORD(i, VDM_DOS_RECORD, Entry);
+ if (DosRecord->State == VDM_NOT_READY)
+ {
+ /* If NTVDM is asking for a new command, it means these are done */
+ DosRecord->State = VDM_READY;
+
+ NtSetEvent(DosRecord->ServerEvent, NULL);
+ NtClose(DosRecord->ServerEvent);
+ DosRecord->ServerEvent = NULL;
+ }
+ }
+
+ /* Search for a DOS record that isn't loaded yet */
+ for (i = ConsoleRecord->DosListHead.Flink; i !=
&ConsoleRecord->DosListHead; i = i->Flink)
+ {
+ DosRecord = CONTAINING_RECORD(i, VDM_DOS_RECORD, Entry);
+ if (DosRecord->State == VDM_NOT_LOADED) break;
+ }
+
+ if (i != &ConsoleRecord->DosListHead)
+ {
+ /* 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);
+ DosRecord->CommandInfo = NULL;
+
+ /* Update the VDM state */
+ DosRecord->State = VDM_NOT_READY;
+
+ Status = STATUS_SUCCESS;
+ goto Cleanup;
+ }
+ }
+ else
+ {
+ // TODO: WOW SUPPORT NOT IMPLEMENTED
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Cleanup;
+ }
+
+ /* There is no command yet */
+ if (ConsoleRecord->ServerEvent)
+ {
+ /* Reset the event */
+ NtResetEvent(ConsoleRecord->ServerEvent, NULL);
+ }
+ else
+ {
+ /* Create a pair of wait handles */
+ Status = BaseSrvCreatePairWaitHandles(&ConsoleRecord->ServerEvent,
+ &ConsoleRecord->ClientEvent);
+ if (!NT_SUCCESS(Status)) goto Cleanup;
+ }
+
+ /* Return the client event handle */
+ GetNextVdmCommandRequest->WaitObjectForVDM = ConsoleRecord->ClientEvent;
+
+Cleanup:
+ /* Leave the critical section */
+ RtlLeaveCriticalSection(CriticalSection);
+
+ return Status;
}
CSR_API(BaseSrvExitVDM)
@@ -811,6 +966,9 @@
ConsoleRecord->CurDirsLength = 0;
}
+ /* Close the event handle */
+ if (ConsoleRecord->ServerEvent) NtClose(ConsoleRecord->ServerEvent);
+
/* Remove the console record */
RemoveEntryList(&ConsoleRecord->Entry);
RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
Modified: branches/ntvdm/subsystems/win/basesrv/vdm.h
URL:
http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/win/basesrv/vd…
==============================================================================
--- branches/ntvdm/subsystems/win/basesrv/vdm.h [iso-8859-1] (original)
+++ branches/ntvdm/subsystems/win/basesrv/vdm.h [iso-8859-1] Mon Apr 7 23:16:22 2014
@@ -28,7 +28,6 @@
ULONG CurDirsLength;
ULONG SessionId;
LIST_ENTRY DosListHead;
- // TODO: Structure incomplete!!!
} VDM_CONSOLE_RECORD, *PVDM_CONSOLE_RECORD;
typedef struct _VDM_DOS_RECORD
@@ -39,7 +38,6 @@
HANDLE ServerEvent;
HANDLE ClientEvent;
PVDM_COMMAND_INFO CommandInfo;
- // TODO: Structure incomplete!!!
} VDM_DOS_RECORD, *PVDM_DOS_RECORD;
/* FUNCTIONS ******************************************************************/