From 49f1aa9bdc2cc6b051244d65b534c8535be162af Mon Sep 17 00:00:00 2001 From: Aleksandar Andrejevic Date: Sat, 29 Mar 2014 04:05:09 +0000 Subject: [PATCH] [KERNEL32] Implement GetNextVDMCommand. svn path=/branches/ntvdm/; revision=62574 --- dll/win32/kernel32/client/vdm.c | 287 ++++++++++++++++++++++++++++++- include/reactos/subsys/win/vdm.h | 2 +- 2 files changed, 283 insertions(+), 6 deletions(-) diff --git a/dll/win32/kernel32/client/vdm.c b/dll/win32/kernel32/client/vdm.c index 9601f1038ee..fa90b3a677e 100644 --- a/dll/win32/kernel32/client/vdm.c +++ b/dll/win32/kernel32/client/vdm.c @@ -1124,16 +1124,293 @@ ExitVDM(BOOL IsWow, ULONG iWowTask) } } - /* - * @unimplemented + * @implemented */ -DWORD +BOOL WINAPI GetNextVDMCommand(PVDM_COMMAND_INFO CommandData) { - STUB; - return 0; + NTSTATUS Status; + BOOL Result = FALSE; + BASE_API_MESSAGE ApiMessage; + PBASE_GET_NEXT_VDM_COMMAND GetNextVdmCommand = &ApiMessage.Data.GetNextVDMCommandRequest; + PBASE_IS_FIRST_VDM IsFirstVdm = &ApiMessage.Data.IsFirstVDMRequest; + PCSR_CAPTURE_BUFFER CaptureBuffer = NULL; + ULONG NumStrings = 1; + + if (CommandData != NULL) + { + /* Clear the structure */ + ZeroMemory(GetNextVdmCommand, sizeof(GetNextVdmCommand)); + + /* Setup the input parameters */ + GetNextVdmCommand->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle; + GetNextVdmCommand->CmdLen = CommandData->CmdLen; + GetNextVdmCommand->AppLen = CommandData->AppLen; + GetNextVdmCommand->PifLen = CommandData->PifLen; + GetNextVdmCommand->CurDirectoryLen = CommandData->CurDirectoryLen; + GetNextVdmCommand->EnvLen = CommandData->EnvLen; + GetNextVdmCommand->DesktopLen = CommandData->DesktopLen; + GetNextVdmCommand->TitleLen = CommandData->TitleLen; + GetNextVdmCommand->ReservedLen = CommandData->ReservedLen; + + /* Count the number of strings */ + if (CommandData->CmdLen) NumStrings++; + if (CommandData->AppLen) NumStrings++; + if (CommandData->PifLen) NumStrings++; + if (CommandData->CurDirectoryLen) NumStrings++; + if (CommandData->EnvLen) NumStrings++; + if (CommandData->DesktopLen) NumStrings++; + if (CommandData->TitleLen) NumStrings++; + if (CommandData->ReservedLen) NumStrings++; + + /* Allocate the capture buffer */ + CaptureBuffer = CsrAllocateCaptureBuffer(NumStrings, + GetNextVdmCommand->CmdLen + + GetNextVdmCommand->AppLen + + GetNextVdmCommand->PifLen + + GetNextVdmCommand->CurDirectoryLen + + GetNextVdmCommand->EnvLen + + GetNextVdmCommand->DesktopLen + + GetNextVdmCommand->TitleLen + + GetNextVdmCommand->ReservedLen + + sizeof(STARTUPINFOA)); + if (CaptureBuffer == NULL) + { + BaseSetLastNTError(STATUS_NO_MEMORY); + goto Cleanup; + } + + /* Allocate memory for the startup info */ + CsrAllocateMessagePointer(CaptureBuffer, + sizeof(STARTUPINFOA), + (PVOID*)&GetNextVdmCommand->StartupInfo); + + if (CommandData->CmdLen) + { + /* Allocate memory for the command line */ + CsrAllocateMessagePointer(CaptureBuffer, + CommandData->CmdLen, + (PVOID*)&GetNextVdmCommand->CmdLine); + } + + if (CommandData->AppLen) + { + /* Allocate memory for the application name */ + CsrAllocateMessagePointer(CaptureBuffer, + CommandData->AppLen, + (PVOID*)&GetNextVdmCommand->AppName); + } + + if (CommandData->PifLen) + { + /* Allocate memory for the PIF file name */ + CsrAllocateMessagePointer(CaptureBuffer, + CommandData->PifLen, + (PVOID*)&GetNextVdmCommand->PifFile); + } + + if (CommandData->CurDirectoryLen) + { + /* Allocate memory for the current directory */ + CsrAllocateMessagePointer(CaptureBuffer, + CommandData->CurDirectoryLen, + (PVOID*)&GetNextVdmCommand->CurDirectory); + } + + if (CommandData->EnvLen) + { + /* Allocate memory for the environment */ + CsrAllocateMessagePointer(CaptureBuffer, + CommandData->EnvLen, + (PVOID*)&GetNextVdmCommand->Env); + } + + if (CommandData->DesktopLen) + { + /* Allocate memory for the desktop name */ + CsrAllocateMessagePointer(CaptureBuffer, + CommandData->DesktopLen, + (PVOID*)&GetNextVdmCommand->Desktop); + } + + if (CommandData->TitleLen) + { + /* Allocate memory for the title */ + CsrAllocateMessagePointer(CaptureBuffer, + CommandData->TitleLen, + (PVOID*)&GetNextVdmCommand->Title); + } + + if (CommandData->ReservedLen) + { + /* Allocate memory for the reserved parameter */ + CsrAllocateMessagePointer(CaptureBuffer, + CommandData->ReservedLen, + (PVOID*)&GetNextVdmCommand->Reserved); + } + + do + { + /* Call CSRSS */ + Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, + CaptureBuffer, + CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepGetNextVDMCommand), + sizeof(BASE_GET_NEXT_VDM_COMMAND)); + + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + goto Cleanup; + } + + /* Did we receive an event handle? */ + if (GetNextVdmCommand->WaitObjectForVDM != NULL) + { + /* Wait for the event to become signaled and try again */ + Status = NtWaitForSingleObject(GetNextVdmCommand->WaitObjectForVDM, + FALSE, + NULL); + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + goto Cleanup; + } + } + } + while (GetNextVdmCommand->WaitObjectForVDM != NULL); + + /* Write back the standard handles */ + CommandData->StdIn = GetNextVdmCommand->StdIn; + CommandData->StdOut = GetNextVdmCommand->StdOut; + CommandData->StdErr = GetNextVdmCommand->StdErr; + + /* Write back the startup info */ + RtlMoveMemory(&CommandData->StartupInfo, + GetNextVdmCommand->StartupInfo, + sizeof(STARTUPINFOA)); + + if (CommandData->CmdLen) + { + /* Write back the command line */ + RtlMoveMemory(CommandData->CmdLine, + GetNextVdmCommand->CmdLine, + GetNextVdmCommand->CmdLen); + + /* Set the actual length */ + CommandData->CmdLen = GetNextVdmCommand->CmdLen; + } + + if (CommandData->AppLen) + { + /* Write back the application name */ + RtlMoveMemory(CommandData->AppName, + GetNextVdmCommand->AppName, + GetNextVdmCommand->AppLen); + + /* Set the actual length */ + CommandData->AppLen = GetNextVdmCommand->AppLen; + } + + if (CommandData->PifLen) + { + /* Write back the PIF file name */ + RtlMoveMemory(CommandData->PifFile, + GetNextVdmCommand->PifFile, + GetNextVdmCommand->PifLen); + + /* Set the actual length */ + CommandData->PifLen = GetNextVdmCommand->PifLen; + } + + if (CommandData->CurDirectoryLen) + { + /* Write back the current directory */ + RtlMoveMemory(CommandData->CurDirectory, + GetNextVdmCommand->CurDirectory, + GetNextVdmCommand->CurDirectoryLen); + + /* Set the actual length */ + CommandData->CurDirectoryLen = GetNextVdmCommand->CurDirectoryLen; + } + + if (CommandData->EnvLen) + { + /* Write back the environment */ + RtlMoveMemory(CommandData->Env, + GetNextVdmCommand->Env, + GetNextVdmCommand->EnvLen); + + /* Set the actual length */ + CommandData->EnvLen = GetNextVdmCommand->EnvLen; + } + + if (CommandData->DesktopLen) + { + /* Write back the desktop name */ + RtlMoveMemory(CommandData->Desktop, + GetNextVdmCommand->Desktop, + GetNextVdmCommand->DesktopLen); + + /* Set the actual length */ + CommandData->DesktopLen = GetNextVdmCommand->DesktopLen; + } + + if (CommandData->TitleLen) + { + /* Write back the title */ + RtlMoveMemory(CommandData->Title, + GetNextVdmCommand->Title, + GetNextVdmCommand->TitleLen); + + /* Set the actual length */ + CommandData->TitleLen = GetNextVdmCommand->TitleLen; + } + + if (CommandData->ReservedLen) + { + /* Write back the reserved parameter */ + RtlMoveMemory(CommandData->Reserved, + GetNextVdmCommand->Reserved, + GetNextVdmCommand->ReservedLen); + + /* Set the actual length */ + CommandData->ReservedLen = GetNextVdmCommand->ReservedLen; + } + + /* Write the remaining output parameters */ + CommandData->TaskId = GetNextVdmCommand->iTask; + CommandData->CreationFlags = GetNextVdmCommand->dwCreationFlags; + CommandData->CodePage = GetNextVdmCommand->CodePage; + CommandData->ExitCode = GetNextVdmCommand->ExitCode; + CommandData->CurrentDrive = GetNextVdmCommand->CurrentDrive; + CommandData->VDMState = GetNextVdmCommand->VDMState; + CommandData->ComingFromBat = GetNextVdmCommand->fComingFromBat; + + /* It was successful */ + Result = TRUE; + } + else + { + /* Call CSRSS */ + Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage, + NULL, + CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX, BasepIsFirstVDM), + sizeof(BASE_IS_FIRST_VDM)); + if (!NT_SUCCESS(Status)) + { + BaseSetLastNTError(Status); + goto Cleanup; + } + + /* Return TRUE if this is the first VDM */ + Result = IsFirstVdm->FirstVDM; + } + +Cleanup: + if (CaptureBuffer != NULL) CsrFreeCaptureBuffer(CaptureBuffer); + return Result; } diff --git a/include/reactos/subsys/win/vdm.h b/include/reactos/subsys/win/vdm.h index 97dafcd2e09..2d0dafa0a12 100644 --- a/include/reactos/subsys/win/vdm.h +++ b/include/reactos/subsys/win/vdm.h @@ -50,7 +50,7 @@ typedef enum _VDM_ENTRY_CODE typedef struct { ULONG TaskId; - ULONG Unused; + ULONG CreationFlags; ULONG ExitCode; ULONG CodePage; HANDLE StdIn;