mirror of
https://github.com/reactos/reactos.git
synced 2024-10-15 05:37:44 +00:00
[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. svn path=/branches/ntvdm/; revision=62683
This commit is contained in:
parent
6c0fe9b984
commit
bd153df890
|
@ -66,4 +66,17 @@ BaseCheckVDM(
|
|||
IN HANDLE hUserToken OPTIONAL
|
||||
);
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
GetNextVDMCommand(
|
||||
IN OUT PVDM_COMMAND_INFO CommandData OPTIONAL
|
||||
);
|
||||
|
||||
VOID
|
||||
WINAPI
|
||||
ExitVDM(
|
||||
IN BOOL IsWow,
|
||||
IN ULONG iWowTask
|
||||
);
|
||||
|
||||
/* EOF */
|
||||
|
|
|
@ -50,6 +50,7 @@ typedef enum _VDM_ENTRY_CODE
|
|||
//
|
||||
// VDM Magic Values
|
||||
//
|
||||
#define VDM_FLAG_WOW 0x02
|
||||
#define VDM_INC_REENTER_COUNT 0x10
|
||||
#define VDM_DEC_REENTER_COUNT 0x20
|
||||
|
||||
|
|
|
@ -366,7 +366,7 @@ Cleanup:
|
|||
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 @@ VOID NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
|
|||
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 @@ VOID NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
|
|||
&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 @@ CSR_API(BaseSrvCheckVDM)
|
|||
{
|
||||
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;
|
||||
|
@ -501,11 +518,6 @@ CSR_API(BaseSrvCheckVDM)
|
|||
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
|
||||
: &WowCriticalSection;
|
||||
|
@ -532,19 +544,18 @@ CSR_API(BaseSrvCheckVDM)
|
|||
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 @@ CSR_API(BaseSrvCheckVDM)
|
|||
}
|
||||
|
||||
/* 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 @@ CSR_API(BaseSrvCheckVDM)
|
|||
/* 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 @@ Cleanup:
|
|||
/* Leave the critical section */
|
||||
RtlLeaveCriticalSection(CriticalSection);
|
||||
|
||||
/* Unlock the process */
|
||||
CsrUnlockProcess(ClientProcess);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
|
@ -695,6 +708,7 @@ CSR_API(BaseSrvUpdateVDMEntry)
|
|||
*/
|
||||
if (ConsoleRecord->DosListHead.Flink == &ConsoleRecord->DosListHead)
|
||||
{
|
||||
if (ConsoleRecord->ServerEvent) NtClose(ConsoleRecord->ServerEvent);
|
||||
RemoveEntryList(&ConsoleRecord->Entry);
|
||||
RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
|
||||
}
|
||||
|
@ -761,8 +775,149 @@ Cleanup:
|
|||
|
||||
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 @@ CSR_API(BaseSrvExitVDM)
|
|||
ConsoleRecord->CurDirsLength = 0;
|
||||
}
|
||||
|
||||
/* Close the event handle */
|
||||
if (ConsoleRecord->ServerEvent) NtClose(ConsoleRecord->ServerEvent);
|
||||
|
||||
/* Remove the console record */
|
||||
RemoveEntryList(&ConsoleRecord->Entry);
|
||||
RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
|
||||
|
|
|
@ -28,7 +28,6 @@ typedef struct _VDM_CONSOLE_RECORD
|
|||
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 @@ typedef struct _VDM_DOS_RECORD
|
|||
HANDLE ServerEvent;
|
||||
HANDLE ClientEvent;
|
||||
PVDM_COMMAND_INFO CommandInfo;
|
||||
// TODO: Structure incomplete!!!
|
||||
} VDM_DOS_RECORD, *PVDM_DOS_RECORD;
|
||||
|
||||
/* FUNCTIONS ******************************************************************/
|
||||
|
|
Loading…
Reference in a new issue