Author: hbelusca
Date: Sat Sep 12 16:23:32 2015
New Revision: 69201
URL:
http://svn.reactos.org/svn/reactos?rev=69201&view=rev
Log:
[KERNEL32]
GetNextVDMCommand function:
- Avoid using deep nested levels of indentation.
- Fix the error check conditions (+ status value) for the CsrClientCallServer call to make
it compatible with what windows' basesrv can return to us.
[BASESRV]
- Remove some useless "NTAPI" from functions.
- Factor out some code used for creating and destroying console records, and for the
destruction of the pair of event handles.
- Use "IsListEmpty" when needed.
- Fix BaseSrvFillCommandInfo so that it returns the needed lengths (even if the user-given
lengths are zero) and set the expected status error in case the buffer lenghts are too
small (not STATUS_BUFFER_TOO_SMALL but STATUS_INVALID_PARAMETER because it's what
kernel32 error check expects, for windows compat; see above).
- Fix initialization of new DOS records: no need to create a new one if there is one
already free (status VDM_READY).
- Fix the loop that searches for a valid DOS record containing command information
available as well as the conditions in which case our caller needs to wait in
GetNextVDMCommand call.
NOTE: The internal state flags of the DOS records have normally nothing to do with the VDM
state flags we report back to the user.
CORE-8247 CORE-9711 CORE-9773
Modified:
trunk/reactos/dll/win32/kernel32/client/vdm.c
trunk/reactos/subsystems/win/basesrv/vdm.c
trunk/reactos/subsystems/win/basesrv/vdm.h
Modified: trunk/reactos/dll/win32/kernel32/client/vdm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/dll/win32/kernel32/client/…
==============================================================================
--- trunk/reactos/dll/win32/kernel32/client/vdm.c [iso-8859-1] (original)
+++ trunk/reactos/dll/win32/kernel32/client/vdm.c [iso-8859-1] Sat Sep 12 16:23:32
2015
@@ -1411,8 +1411,8 @@
WINAPI
GetNextVDMCommand(PVDM_COMMAND_INFO CommandData)
{
+ BOOL Success = FALSE;
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;
@@ -1420,311 +1420,343 @@
PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
ULONG NumStrings = 0;
- if (CommandData != NULL)
- {
- if ((CommandData->VDMState == VDM_INC_REENTER_COUNT)
- || (CommandData->VDMState == VDM_DEC_REENTER_COUNT))
+ /*
+ * Special case to test whether the VDM is the first one.
+ */
+ if (CommandData == NULL)
+ {
+ /* Call CSRSS */
+ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+ NULL,
+ CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX,
BasepIsFirstVDM),
+ sizeof(*IsFirstVdm));
+ if (!NT_SUCCESS(ApiMessage.Status))
{
- /* Setup the input parameters */
- SetReenterCount->ConsoleHandle =
NtCurrentPeb()->ProcessParameters->ConsoleHandle;
- SetReenterCount->fIncDec = CommandData->VDMState;
-
- /* Call CSRSS */
- Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
- NULL,
- CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX,
BasepSetReenterCount),
- sizeof(*SetReenterCount));
+ BaseSetLastNTError(ApiMessage.Status);
+ return FALSE;
+ }
+
+ /* Return TRUE if this is the first VDM */
+ return IsFirstVdm->FirstVDM;
+ }
+
+ /* CommandData != NULL */
+
+ /*
+ * Special case to increment or decrement the reentrancy count.
+ */
+ if ((CommandData->VDMState == VDM_INC_REENTER_COUNT) ||
+ (CommandData->VDMState == VDM_DEC_REENTER_COUNT))
+ {
+ /* Setup the input parameters */
+ SetReenterCount->ConsoleHandle =
NtCurrentPeb()->ProcessParameters->ConsoleHandle;
+ SetReenterCount->fIncDec = CommandData->VDMState;
+
+ /* Call CSRSS */
+ CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+ NULL,
+ CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX,
BasepSetReenterCount),
+ sizeof(*SetReenterCount));
+ if (!NT_SUCCESS(ApiMessage.Status))
+ {
+ BaseSetLastNTError(ApiMessage.Status);
+ return FALSE;
+ }
+
+ return TRUE;
+ }
+
+ /*
+ * TODO!
+ * Special case to retrieve or set WOW information.
+ */
+ // TODO: if CommandData->VDMState & (VDM_LIST_WOW_PROCESSES |
VDM_LIST_WOW_TASKS | VDM_ADD_WOW_TASK)
+ // then call BasepGetNextVDMCommand in a simpler way!
+
+ /*
+ * Regular case.
+ */
+
+ /* Clear the structure */
+ RtlZeroMemory(GetNextVdmCommand, sizeof(*GetNextVdmCommand));
+
+ /* Setup the input parameters */
+ GetNextVdmCommand->iTask = CommandData->TaskId;
+ 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;
+ GetNextVdmCommand->VDMState = CommandData->VDMState;
+
+ /* 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 + 1,
+ GetNextVdmCommand->CmdLen
+ + GetNextVdmCommand->AppLen
+ + GetNextVdmCommand->PifLen
+ + GetNextVdmCommand->CurDirectoryLen
+ + GetNextVdmCommand->EnvLen
+ + GetNextVdmCommand->DesktopLen
+ + GetNextVdmCommand->TitleLen
+ + GetNextVdmCommand->ReservedLen
+ +
sizeof(*GetNextVdmCommand->StartupInfo));
+ if (CaptureBuffer == NULL)
+ {
+ BaseSetLastNTError(STATUS_NO_MEMORY);
+ goto Cleanup;
+ }
+
+ /* Capture the data */
+
+ CsrAllocateMessagePointer(CaptureBuffer,
+ sizeof(*GetNextVdmCommand->StartupInfo),
+ (PVOID*)&GetNextVdmCommand->StartupInfo);
+
+ if (CommandData->CmdLen)
+ {
+ CsrAllocateMessagePointer(CaptureBuffer,
+ CommandData->CmdLen,
+ (PVOID*)&GetNextVdmCommand->CmdLine);
+ }
+
+ if (CommandData->AppLen)
+ {
+ CsrAllocateMessagePointer(CaptureBuffer,
+ CommandData->AppLen,
+ (PVOID*)&GetNextVdmCommand->AppName);
+ }
+
+ if (CommandData->PifLen)
+ {
+ CsrAllocateMessagePointer(CaptureBuffer,
+ CommandData->PifLen,
+ (PVOID*)&GetNextVdmCommand->PifFile);
+ }
+
+ if (CommandData->CurDirectoryLen)
+ {
+ CsrAllocateMessagePointer(CaptureBuffer,
+ CommandData->CurDirectoryLen,
+ (PVOID*)&GetNextVdmCommand->CurDirectory);
+ }
+
+ if (CommandData->EnvLen)
+ {
+ CsrAllocateMessagePointer(CaptureBuffer,
+ CommandData->EnvLen,
+ (PVOID*)&GetNextVdmCommand->Env);
+ }
+
+ if (CommandData->DesktopLen)
+ {
+ CsrAllocateMessagePointer(CaptureBuffer,
+ CommandData->DesktopLen,
+ (PVOID*)&GetNextVdmCommand->Desktop);
+ }
+
+ if (CommandData->TitleLen)
+ {
+ CsrAllocateMessagePointer(CaptureBuffer,
+ CommandData->TitleLen,
+ (PVOID*)&GetNextVdmCommand->Title);
+ }
+
+ if (CommandData->ReservedLen)
+ {
+ CsrAllocateMessagePointer(CaptureBuffer,
+ CommandData->ReservedLen,
+ (PVOID*)&GetNextVdmCommand->Reserved);
+ }
+
+ while (TRUE)
+ {
+ /* Call CSRSS */
+ Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
+ CaptureBuffer,
+ CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX,
BasepGetNextVDMCommand),
+ sizeof(*GetNextVdmCommand));
+
+ /* Exit the waiting loop if we did not receive any event handle */
+ if (GetNextVdmCommand->WaitObjectForVDM == NULL)
+ break;
+
+ /* Wait for the event to become signaled and try again */
+ Status = NtWaitForSingleObject(GetNextVdmCommand->WaitObjectForVDM,
+ FALSE, NULL);
+ if (Status != STATUS_SUCCESS)
+ {
+ /* Fail if we timed out, or if some other error happened */
BaseSetLastNTError(Status);
- Result = NT_SUCCESS(Status);
+ goto Cleanup;
+ }
+
+ /* Set the retry flag, clear the exit code, and retry a query */
+ GetNextVdmCommand->VDMState |= VDM_FLAG_RETRY;
+ GetNextVdmCommand->ExitCode = 0;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ if (Status == STATUS_INVALID_PARAMETER)
+ {
+ /*
+ * One of the buffer lengths was less than required. Store the correct ones.
+ * Note that the status code is not STATUS_BUFFER_TOO_SMALL as one would
expect,
+ * in order to keep compatibility with Windows 2003 BASESRV.DLL.
+ */
+ 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;
}
else
{
- /* Clear the structure */
- ZeroMemory(GetNextVdmCommand, sizeof(*GetNextVdmCommand));
-
- /* Setup the input parameters */
- GetNextVdmCommand->iTask = CommandData->TaskId;
- 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;
- GetNextVdmCommand->VDMState = CommandData->VDMState;
-
- /* 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 + 1,
- 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(*GetNextVdmCommand));
- 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;
- }
-
- /* 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;
- }
-
- /* Set the retry flag and clear the exit code */
- GetNextVdmCommand->VDMState |= VDM_FLAG_RETRY;
- GetNextVdmCommand->ExitCode = 0;
- }
- }
- 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;
+ /* Any other failure */
+ CommandData->CmdLen = 0;
+ CommandData->AppLen = 0;
+ CommandData->PifLen = 0;
+ CommandData->CurDirectoryLen = 0;
+ CommandData->EnvLen = 0;
+ CommandData->DesktopLen = 0;
+ CommandData->TitleLen = 0;
+ CommandData->ReservedLen = 0;
}
- }
- else
- {
- /* Call CSRSS */
- Status = CsrClientCallServer((PCSR_API_MESSAGE)&ApiMessage,
- NULL,
- CSR_CREATE_API_NUMBER(BASESRV_SERVERDLL_INDEX,
BasepIsFirstVDM),
- sizeof(*IsFirstVdm));
- if (!NT_SUCCESS(Status))
- {
- BaseSetLastNTError(Status);
- goto Cleanup;
- }
-
- /* Return TRUE if this is the first VDM */
- Result = IsFirstVdm->FirstVDM;
- }
+
+ BaseSetLastNTError(Status);
+ goto Cleanup;
+ }
+
+ /* 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(*GetNextVdmCommand->StartupInfo));
+
+ 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 */
+ Success = TRUE;
Cleanup:
if (CaptureBuffer != NULL) CsrFreeCaptureBuffer(CaptureBuffer);
- return Result;
+ return Success;
}
Modified: trunk/reactos/subsystems/win/basesrv/vdm.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win/basesrv/vdm…
==============================================================================
--- trunk/reactos/subsystems/win/basesrv/vdm.c [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win/basesrv/vdm.c [iso-8859-1] Sat Sep 12 16:23:32 2015
@@ -22,9 +22,31 @@
RTL_CRITICAL_SECTION DosCriticalSection;
RTL_CRITICAL_SECTION WowCriticalSection;
-/* FUNCTIONS ******************************************************************/
-
-NTSTATUS NTAPI BaseSrvGetConsoleRecord(HANDLE ConsoleHandle, PVDM_CONSOLE_RECORD *Record)
+/* HELPER FUNCTIONS ***********************************************************/
+
+PVDM_CONSOLE_RECORD BaseSrvCreateConsoleRecord(VOID)
+{
+ PVDM_CONSOLE_RECORD ConsoleRecord;
+
+ ConsoleRecord = RtlAllocateHeap(BaseSrvHeap, HEAP_ZERO_MEMORY,
+ sizeof(VDM_CONSOLE_RECORD));
+ if (ConsoleRecord == NULL)
+ return NULL;
+
+ /* Initialize the console record */
+ ConsoleRecord->ConsoleHandle = NULL;
+ ConsoleRecord->ProcessHandle = NULL;
+ ConsoleRecord->ServerEvent = ConsoleRecord->ClientEvent = NULL;
+ ConsoleRecord->ReenterCount = 0;
+ ConsoleRecord->CurrentDirs = NULL;
+ ConsoleRecord->CurDirsLength = 0;
+ ConsoleRecord->SessionId = 0;
+ InitializeListHead(&ConsoleRecord->DosListHead);
+
+ return ConsoleRecord;
+}
+
+NTSTATUS BaseSrvGetConsoleRecord(HANDLE ConsoleHandle, PVDM_CONSOLE_RECORD *Record)
{
PLIST_ENTRY i;
PVDM_CONSOLE_RECORD CurrentRecord = NULL;
@@ -46,7 +68,31 @@
return CurrentRecord ? STATUS_SUCCESS : STATUS_NOT_FOUND;
}
-NTSTATUS NTAPI GetConsoleRecordBySessionId(ULONG TaskId, PVDM_CONSOLE_RECORD *Record)
+VOID BaseSrvDestroyConsoleRecord(PVDM_CONSOLE_RECORD ConsoleRecord)
+{
+ if (ConsoleRecord->CurrentDirs != NULL)
+ {
+ /* Free the current directories */
+ RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord->CurrentDirs);
+ ConsoleRecord->CurrentDirs = NULL;
+ ConsoleRecord->CurDirsLength = 0;
+ }
+
+ /* Close the process handle */
+ if (ConsoleRecord->ProcessHandle)
+ NtClose(ConsoleRecord->ProcessHandle);
+
+ /* Close the event handle */
+ if (ConsoleRecord->ServerEvent)
+ NtClose(ConsoleRecord->ServerEvent);
+
+ /* Remove the console record */
+ // RemoveEntryList(&ConsoleRecord->Entry);
+ RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
+
+}
+
+NTSTATUS GetConsoleRecordBySessionId(ULONG TaskId, PVDM_CONSOLE_RECORD *Record)
{
PLIST_ENTRY i;
PVDM_CONSOLE_RECORD CurrentRecord = NULL;
@@ -65,7 +111,7 @@
return CurrentRecord ? STATUS_SUCCESS : STATUS_NOT_FOUND;
}
-ULONG NTAPI GetNextDosSesId(VOID)
+ULONG GetNextDosSesId(VOID)
{
ULONG SessionId;
PLIST_ENTRY i;
@@ -94,7 +140,7 @@
return SessionId;
}
-BOOLEAN NTAPI BaseSrvIsVdmAllowed(VOID)
+BOOLEAN BaseSrvIsVdmAllowed(VOID)
{
NTSTATUS Status;
BOOLEAN VdmAllowed = TRUE;
@@ -191,7 +237,7 @@
return VdmAllowed;
}
-NTSTATUS NTAPI BaseSrvCreatePairWaitHandles(PHANDLE ServerEvent, PHANDLE ClientEvent)
+NTSTATUS BaseSrvCreatePairWaitHandles(PHANDLE ServerEvent, PHANDLE ClientEvent)
{
NTSTATUS Status;
@@ -212,7 +258,27 @@
return Status;
}
-VOID NTAPI BaseSrvFreeVDMInfo(PVDM_COMMAND_INFO CommandInfo)
+VOID BaseSrvDestroyPairWaitHandles(HANDLE ServerEvent, HANDLE ClientEvent)
+{
+ if (ServerEvent) NtClose(ServerEvent);
+ if (ClientEvent)
+ {
+ /* Close the remote handle */
+ NtDuplicateObject(CsrGetClientThread()->Process->ProcessHandle,
+ ClientEvent,
+ NULL,
+ NULL,
+ 0,
+ 0,
+ DUPLICATE_CLOSE_SOURCE);
+ }
+}
+
+/* WOW SUPPORT FUNCTIONS ******************************************************/
+
+/* DOS SUPPORT FUNCTIONS ******************************************************/
+
+VOID BaseSrvFreeVDMInfo(PVDM_COMMAND_INFO CommandInfo)
{
/* Free the allocated structure members */
if (CommandInfo->CmdLine != NULL) RtlFreeHeap(BaseSrvHeap, 0,
CommandInfo->CmdLine);
@@ -228,9 +294,7 @@
RtlFreeHeap(BaseSrvHeap, 0, CommandInfo);
}
-VOID
-NTAPI
-BaseSrvCleanupVDMResources(IN PCSR_PROCESS CsrProcess)
+VOID BaseSrvCleanupVDMResources(IN PCSR_PROCESS CsrProcess)
{
ULONG ProcessId = HandleToUlong(CsrProcess->ClientId.UniqueProcess);
PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
@@ -241,22 +305,33 @@
RtlEnterCriticalSection(&DosCriticalSection);
/* Search for a record that has the same process handle */
- for (i = VDMConsoleListHead.Flink; i != &VDMConsoleListHead; i = i->Flink)
+ i = VDMConsoleListHead.Flink;
+ while (i != &VDMConsoleListHead)
{
ConsoleRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry);
+ i = i->Flink;
if (ConsoleRecord->ProcessId == ProcessId)
{
+ if (ConsoleRecord->ServerEvent)
+ {
+ NtClose(ConsoleRecord->ServerEvent);
+ ConsoleRecord->ServerEvent = NULL;
+ }
+
/* Cleanup the DOS records */
- while (ConsoleRecord->DosListHead.Flink !=
&ConsoleRecord->DosListHead)
+ while (!IsListEmpty(&ConsoleRecord->DosListHead))
{
DosRecord = CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
- VDM_DOS_RECORD,
- Entry);
+ VDM_DOS_RECORD, Entry);
/* Set the event and close it */
- NtSetEvent(DosRecord->ServerEvent, NULL);
- NtClose(DosRecord->ServerEvent);
+ if (DosRecord->ServerEvent)
+ {
+ NtSetEvent(DosRecord->ServerEvent, NULL);
+ NtClose(DosRecord->ServerEvent);
+ DosRecord->ServerEvent = NULL;
+ }
/* Remove the DOS entry */
if (DosRecord->CommandInfo)
BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
@@ -264,24 +339,9 @@
RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
}
- if (ConsoleRecord->CurrentDirs != NULL)
- {
- /* Free the current directories */
- RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord->CurrentDirs);
- ConsoleRecord->CurrentDirs = NULL;
- ConsoleRecord->CurDirsLength = 0;
- }
-
- /* Close the process handle */
- if (ConsoleRecord->ProcessHandle)
NtClose(ConsoleRecord->ProcessHandle);
-
- /* Close the event handle */
- if (ConsoleRecord->ServerEvent) NtClose(ConsoleRecord->ServerEvent);
-
/* Remove the console record */
- i = i->Blink;
RemoveEntryList(&ConsoleRecord->Entry);
- RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
+ BaseSrvDestroyConsoleRecord(ConsoleRecord);
}
}
@@ -289,7 +349,7 @@
RtlLeaveCriticalSection(&DosCriticalSection);
}
-BOOLEAN NTAPI BaseSrvCopyCommand(PBASE_CHECK_VDM CheckVdmRequest, PVDM_DOS_RECORD
DosRecord)
+BOOLEAN BaseSrvCopyCommand(PBASE_CHECK_VDM CheckVdmRequest, PVDM_DOS_RECORD DosRecord)
{
BOOLEAN Success = FALSE;
PVDM_COMMAND_INFO CommandInfo = NULL;
@@ -436,8 +496,8 @@
return Success;
}
-NTSTATUS NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
- PBASE_GET_NEXT_VDM_COMMAND Message)
+NTSTATUS BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
+ PBASE_GET_NEXT_VDM_COMMAND Message)
{
NTSTATUS Status = STATUS_SUCCESS;
@@ -453,116 +513,84 @@
Message->VDMState = CommandInfo->VDMState;
Message->fComingFromBat = CommandInfo->ComingFromBat;
- if (CommandInfo->CmdLen && Message->CmdLen)
- {
- if (Message->CmdLen >= CommandInfo->CmdLen)
- {
- /* Copy the command line */
- RtlMoveMemory(Message->CmdLine, CommandInfo->CmdLine,
CommandInfo->CmdLen);
- }
- else Status = STATUS_BUFFER_TOO_SMALL;
-
- Message->CmdLen = CommandInfo->CmdLen;
- }
-
- if (CommandInfo->AppLen && Message->AppLen)
- {
- if (Message->AppLen >= CommandInfo->AppLen)
- {
- /* Copy the application name */
- RtlMoveMemory(Message->AppName, CommandInfo->AppName,
CommandInfo->AppLen);
- }
- else Status = STATUS_BUFFER_TOO_SMALL;
-
- Message->AppLen = CommandInfo->AppLen;
- }
-
- if (CommandInfo->PifLen && Message->PifLen)
- {
- if (Message->PifLen >= CommandInfo->PifLen)
- {
- /* Copy the PIF file name */
- RtlMoveMemory(Message->PifFile, CommandInfo->PifFile,
CommandInfo->PifLen);
- }
- else Status = STATUS_BUFFER_TOO_SMALL;
-
- Message->PifLen = CommandInfo->PifLen;
- }
-
- if (CommandInfo->CurDirectoryLen && Message->CurDirectoryLen)
- {
- if (Message->CurDirectoryLen >= CommandInfo->CurDirectoryLen)
- {
- /* Copy the current directory */
- RtlMoveMemory(Message->CurDirectory, CommandInfo->CurDirectory,
CommandInfo->CurDirectoryLen);
- }
- else Status = STATUS_BUFFER_TOO_SMALL;
-
- Message->CurDirectoryLen = CommandInfo->CurDirectoryLen;
- }
-
- if (CommandInfo->EnvLen && Message->EnvLen)
- {
- if (Message->EnvLen >= CommandInfo->EnvLen)
- {
- /* Copy the environment */
- RtlMoveMemory(Message->Env, CommandInfo->Env, CommandInfo->EnvLen);
- }
- else Status = STATUS_BUFFER_TOO_SMALL;
-
- Message->EnvLen = CommandInfo->EnvLen;
- }
+ if (Message->CmdLen >= CommandInfo->CmdLen)
+ {
+ /* Copy the command line */
+ RtlMoveMemory(Message->CmdLine, CommandInfo->CmdLine,
CommandInfo->CmdLen);
+ }
+ else Status = STATUS_INVALID_PARAMETER;
+ Message->CmdLen = CommandInfo->CmdLen;
+
+ if (Message->AppLen >= CommandInfo->AppLen)
+ {
+ /* Copy the application name */
+ RtlMoveMemory(Message->AppName, CommandInfo->AppName,
CommandInfo->AppLen);
+ }
+ else Status = STATUS_INVALID_PARAMETER;
+ Message->AppLen = CommandInfo->AppLen;
+
+ if (Message->PifLen >= CommandInfo->PifLen)
+ {
+ /* Copy the PIF file name */
+ RtlMoveMemory(Message->PifFile, CommandInfo->PifFile,
CommandInfo->PifLen);
+ }
+ else Status = STATUS_INVALID_PARAMETER;
+ Message->PifLen = CommandInfo->PifLen;
+
+ if (Message->CurDirectoryLen >= CommandInfo->CurDirectoryLen)
+ {
+ /* Copy the current directory */
+ RtlMoveMemory(Message->CurDirectory, CommandInfo->CurDirectory,
CommandInfo->CurDirectoryLen);
+ }
+ else Status = STATUS_INVALID_PARAMETER;
+ Message->CurDirectoryLen = CommandInfo->CurDirectoryLen;
+
+ if (Message->EnvLen >= CommandInfo->EnvLen)
+ {
+ /* Copy the environment */
+ RtlMoveMemory(Message->Env, CommandInfo->Env, CommandInfo->EnvLen);
+ }
+ else Status = STATUS_INVALID_PARAMETER;
+ Message->EnvLen = CommandInfo->EnvLen;
/* Copy the startup info */
RtlMoveMemory(Message->StartupInfo,
&CommandInfo->StartupInfo,
sizeof(STARTUPINFOA));
- if (CommandInfo->DesktopLen && Message->DesktopLen)
- {
- if (Message->DesktopLen >= CommandInfo->DesktopLen)
- {
- /* Copy the desktop name */
- RtlMoveMemory(Message->Desktop, CommandInfo->Desktop,
CommandInfo->DesktopLen);
- }
- else Status = STATUS_BUFFER_TOO_SMALL;
-
- Message->DesktopLen = CommandInfo->DesktopLen;
- }
-
- if (CommandInfo->TitleLen && Message->TitleLen)
- {
- if (Message->TitleLen >= CommandInfo->TitleLen)
- {
- /* Copy the title */
- RtlMoveMemory(Message->Title, CommandInfo->Title,
CommandInfo->TitleLen);
- }
- else Status = STATUS_BUFFER_TOO_SMALL;
-
- Message->TitleLen = CommandInfo->TitleLen;
- }
-
- if (CommandInfo->ReservedLen && Message->ReservedLen)
- {
- if (Message->ReservedLen >= CommandInfo->ReservedLen)
- {
- /* Copy the reserved parameter */
- RtlMoveMemory(Message->Reserved, CommandInfo->Reserved,
CommandInfo->ReservedLen);
- }
- else Status = STATUS_BUFFER_TOO_SMALL;
-
- Message->ReservedLen = CommandInfo->ReservedLen;
- }
+ if (Message->DesktopLen >= CommandInfo->DesktopLen)
+ {
+ /* Copy the desktop name */
+ RtlMoveMemory(Message->Desktop, CommandInfo->Desktop,
CommandInfo->DesktopLen);
+ }
+ else Status = STATUS_INVALID_PARAMETER;
+ Message->DesktopLen = CommandInfo->DesktopLen;
+
+ if (Message->TitleLen >= CommandInfo->TitleLen)
+ {
+ /* Copy the title */
+ RtlMoveMemory(Message->Title, CommandInfo->Title,
CommandInfo->TitleLen);
+ }
+ else Status = STATUS_INVALID_PARAMETER;
+ Message->TitleLen = CommandInfo->TitleLen;
+
+ if (Message->ReservedLen >= CommandInfo->ReservedLen)
+ {
+ /* Copy the reserved parameter */
+ RtlMoveMemory(Message->Reserved, CommandInfo->Reserved,
CommandInfo->ReservedLen);
+ }
+ else Status = STATUS_INVALID_PARAMETER;
+ Message->ReservedLen = CommandInfo->ReservedLen;
return Status;
}
-VOID NTAPI BaseInitializeVDM(VOID)
+VOID BaseInitializeVDM(VOID)
{
/* Initialize the list head */
InitializeListHead(&VDMConsoleListHead);
- /* Initialize the critical section */
+ /* Initialize the critical sections */
RtlInitializeCriticalSection(&DosCriticalSection);
RtlInitializeCriticalSection(&WowCriticalSection);
}
@@ -577,6 +605,7 @@
PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
PVDM_DOS_RECORD DosRecord = NULL;
BOOLEAN NewConsoleRecord = FALSE;
+ BOOLEAN NewDosRecord = FALSE;
/* Don't do anything if the VDM has been disabled in the registry */
if (!BaseSrvIsVdmAllowed()) return STATUS_VDM_DISALLOWED;
@@ -627,52 +656,74 @@
/* Get the console record */
Status = BaseSrvGetConsoleRecord(CheckVdmRequest->ConsoleHandle,
&ConsoleRecord);
-
if (!NT_SUCCESS(Status))
{
/* Allocate a new console record */
- ConsoleRecord = (PVDM_CONSOLE_RECORD)RtlAllocateHeap(BaseSrvHeap,
- HEAP_ZERO_MEMORY,
-
sizeof(VDM_CONSOLE_RECORD));
+ ConsoleRecord = BaseSrvCreateConsoleRecord();
if (ConsoleRecord == NULL)
{
Status = STATUS_NO_MEMORY;
goto Cleanup;
}
+ /* Initialize the console record */
+ ConsoleRecord->ConsoleHandle = CheckVdmRequest->ConsoleHandle;
+ if (ConsoleRecord->ConsoleHandle == NULL)
+ {
+ /* The parent doesn't have a console, get a new session ID */
+ ConsoleRecord->SessionId = GetNextDosSesId();
+ }
+ else
+ {
+ /* No session ID is needed */
+ ConsoleRecord->SessionId = 0;
+ }
+
/* Remember that the console record was allocated here */
NewConsoleRecord = TRUE;
-
- /* Initialize the console record */
- ConsoleRecord->ConsoleHandle = CheckVdmRequest->ConsoleHandle;
- ConsoleRecord->ProcessHandle = NULL;
- ConsoleRecord->ServerEvent = ConsoleRecord->ClientEvent = NULL;
- ConsoleRecord->ReenterCount = 0;
- ConsoleRecord->CurrentDirs = NULL;
- ConsoleRecord->CurDirsLength = 0;
- ConsoleRecord->SessionId = GetNextDosSesId();
- InitializeListHead(&ConsoleRecord->DosListHead);
- }
-
- /* Allocate a new DOS record */
- DosRecord = (PVDM_DOS_RECORD)RtlAllocateHeap(BaseSrvHeap,
- HEAP_ZERO_MEMORY,
- sizeof(VDM_DOS_RECORD));
- if (DosRecord == NULL)
- {
- Status = STATUS_NO_MEMORY;
- goto Cleanup;
+ }
+
+ if (!NewConsoleRecord)
+ {
+ /* Get the primary DOS record */
+ DosRecord =
(PVDM_DOS_RECORD)CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
+ VDM_DOS_RECORD, Entry);
+
+ if (DosRecord->State != VDM_READY) // == VDM_NOT_READY
+ {
+ /* Allocate a new DOS record */
+ DosRecord = (PVDM_DOS_RECORD)RtlAllocateHeap(BaseSrvHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof(VDM_DOS_RECORD));
+ if (DosRecord == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Remember that the DOS record was allocated here */
+ NewDosRecord = TRUE;
+ }
+ }
+ else
+ {
+ /* Allocate a new DOS record */
+ DosRecord = (PVDM_DOS_RECORD)RtlAllocateHeap(BaseSrvHeap,
+ HEAP_ZERO_MEMORY,
+ sizeof(VDM_DOS_RECORD));
+ if (DosRecord == NULL)
+ {
+ Status = STATUS_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Remember that the DOS record was allocated here */
+ NewDosRecord = TRUE;
}
/* Initialize the DOS record */
- DosRecord->State = VDM_NOT_LOADED;
+ DosRecord->State = VDM_NOT_READY;
DosRecord->ExitCode = 0;
-
- Status = BaseSrvCreatePairWaitHandles(&DosRecord->ServerEvent,
&DosRecord->ClientEvent);
- if (!NT_SUCCESS(Status)) goto Cleanup;
-
- /* Return the client event handle */
- CheckVdmRequest->WaitObjectForParent = DosRecord->ClientEvent;
/* Translate the input structure into a VDM command structure and set it in the
DOS record */
if (!BaseSrvCopyCommand(CheckVdmRequest, DosRecord))
@@ -682,9 +733,23 @@
goto Cleanup;
}
- /* Add the DOS record */
- InsertHeadList(&ConsoleRecord->DosListHead, &DosRecord->Entry);
-
+ if (NewDosRecord)
+ {
+ /* Add the DOS record */
+ InsertHeadList(&ConsoleRecord->DosListHead, &DosRecord->Entry);
+ }
+
+ if (!NewConsoleRecord)
+ {
+ Status = BaseSrvCreatePairWaitHandles(&DosRecord->ServerEvent,
&DosRecord->ClientEvent);
+ if (!NT_SUCCESS(Status)) goto Cleanup;
+
+ /* Return the client event handle */
+ CheckVdmRequest->WaitObjectForParent = DosRecord->ClientEvent;
+ }
+
+ // FIXME: We may notify ONLY if ConsoleRecord->nReEntrancy is > 0
+ // in case NewConsoleRecord == FALSE AND NewDosRecord == TRUE.
if (ConsoleRecord->ServerEvent)
{
/* Signal the session event */
@@ -697,13 +762,7 @@
InsertTailList(&VDMConsoleListHead, &ConsoleRecord->Entry);
}
- if (ConsoleRecord->ConsoleHandle == NULL)
- {
- /* The parent doesn't have a console, so return the session ID */
- CheckVdmRequest->iTask = ConsoleRecord->SessionId;
- }
- else CheckVdmRequest->iTask = 0;
-
+ CheckVdmRequest->iTask = ConsoleRecord->SessionId;
CheckVdmRequest->VDMState = NewConsoleRecord ? VDM_NOT_LOADED : VDM_READY;
Status = STATUS_SUCCESS;
}
@@ -718,21 +777,13 @@
/* Check if it failed */
if (!NT_SUCCESS(Status))
{
- /* Free the DOS record */
- if (DosRecord != NULL)
- {
- if (DosRecord->ServerEvent) NtClose(DosRecord->ServerEvent);
- if (DosRecord->ClientEvent)
- {
- /* Close the remote handle */
- NtDuplicateObject(CsrGetClientThread()->Process->ProcessHandle,
- DosRecord->ClientEvent,
- NULL,
- NULL,
- 0,
- 0,
- DUPLICATE_CLOSE_SOURCE);
- }
+ /* Free the DOS record if it was allocated here */
+ if (NewDosRecord)
+ {
+ ASSERT(DosRecord != NULL);
+
+ BaseSrvDestroyPairWaitHandles(DosRecord->ServerEvent,
+ DosRecord->ClientEvent);
RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
DosRecord = NULL;
@@ -741,6 +792,8 @@
/* Free the console record if it was allocated here */
if (NewConsoleRecord)
{
+ ASSERT(ConsoleRecord != NULL);
+
RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
ConsoleRecord = NULL;
}
@@ -787,8 +840,7 @@
/* Get the primary DOS record */
DosRecord =
(PVDM_DOS_RECORD)CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
- VDM_DOS_RECORD,
- Entry);
+ VDM_DOS_RECORD, Entry);
switch (UpdateVdmEntryRequest->EntryIndex)
{
@@ -811,10 +863,8 @@
*/
if (ConsoleRecord->DosListHead.Flink ==
&ConsoleRecord->DosListHead)
{
- if (ConsoleRecord->ProcessHandle)
NtClose(ConsoleRecord->ProcessHandle);
- if (ConsoleRecord->ServerEvent)
NtClose(ConsoleRecord->ServerEvent);
RemoveEntryList(&ConsoleRecord->Entry);
- RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
+ BaseSrvDestroyConsoleRecord(ConsoleRecord);
}
}
@@ -836,6 +886,10 @@
DUPLICATE_SAME_ATTRIBUTES |
DUPLICATE_SAME_ACCESS);
if (!NT_SUCCESS(Status)) goto Cleanup;
+ //
+ // FIXME! Should we always do the following??
+ //
+
/* Create a pair of handles to one event object */
Status = BaseSrvCreatePairWaitHandles(&DosRecord->ServerEvent,
&DosRecord->ClientEvent);
@@ -881,7 +935,7 @@
{
NTSTATUS Status;
PBASE_GET_NEXT_VDM_COMMAND GetNextVdmCommandRequest =
- &((PBASE_API_MESSAGE)ApiMessage)->Data.GetNextVDMCommandRequest;
+ &((PBASE_API_MESSAGE)ApiMessage)->Data.GetNextVDMCommandRequest;
PRTL_CRITICAL_SECTION CriticalSection;
PLIST_ENTRY i = NULL;
PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
@@ -935,7 +989,14 @@
/* Enter the critical section */
RtlEnterCriticalSection(CriticalSection);
- if (!(GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW))
+ if (GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW)
+ {
+ // TODO: WOW SUPPORT NOT IMPLEMENTED
+ UNIMPLEMENTED;
+ Status = STATUS_NOT_IMPLEMENTED;
+ goto Cleanup;
+ }
+ // else if (!(GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW))
{
if (GetNextVdmCommandRequest->iTask != 0)
{
@@ -1018,16 +1079,16 @@
DosRecord->ServerEvent = NULL;
}
- /* Search for a DOS record that isn't loaded yet */
+ /* Search for a DOS record that is currently running and has command information
*/
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 ((DosRecord->State == VDM_NOT_READY) &&
(DosRecord->CommandInfo != NULL)) break;
+ }
+
+ /* Check if we found any */
if (i != &ConsoleRecord->DosListHead)
{
- /* DOS tasks which haven't been loaded yet should have a command info
structure */
ASSERT(DosRecord->CommandInfo != NULL);
/* Check if the caller only wants environment data */
@@ -1060,22 +1121,22 @@
DosRecord->CommandInfo = NULL;
/* Update the VDM state */
- GetNextVdmCommandRequest->VDMState = DosRecord->State =
VDM_NOT_READY;
+ 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 (!(GetNextVdmCommandRequest->VDMState & VDM_FLAG_DONT_WAIT))
+
+ GetNextVdmCommandRequest->WaitObjectForVDM = NULL;
+
+ /*
+ * There is no command yet. Prepare for waiting if we asked so,
+ * and if we were not retrying a request.
+ */
+ if (!(GetNextVdmCommandRequest->VDMState & VDM_FLAG_DONT_WAIT) ||
+ !(GetNextVdmCommandRequest->VDMState & VDM_FLAG_RETRY))
{
if (ConsoleRecord->ServerEvent)
{
@@ -1122,16 +1183,30 @@
Status = BaseSrvGetConsoleRecord(ExitVdmRequest->ConsoleHandle,
&ConsoleRecord);
if (!NT_SUCCESS(Status)) goto Cleanup;
+ if (ConsoleRecord->ServerEvent)
+ ExitVdmRequest->WaitObjectForVDM = ConsoleRecord->ClientEvent;
+
+ // NOTE: The following is the same as in BaseSrvCleanupVDMResources.
+
+ if (ConsoleRecord->ServerEvent)
+ {
+ NtClose(ConsoleRecord->ServerEvent);
+ ConsoleRecord->ServerEvent = NULL;
+ }
+
/* Cleanup the DOS records */
- while (ConsoleRecord->DosListHead.Flink != &ConsoleRecord->DosListHead)
+ while (!IsListEmpty(&ConsoleRecord->DosListHead))
{
DosRecord = CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
- VDM_DOS_RECORD,
- Entry);
+ VDM_DOS_RECORD, Entry);
/* Set the event and close it */
- NtSetEvent(DosRecord->ServerEvent, NULL);
- NtClose(DosRecord->ServerEvent);
+ if (DosRecord->ServerEvent)
+ {
+ NtSetEvent(DosRecord->ServerEvent, NULL);
+ NtClose(DosRecord->ServerEvent);
+ DosRecord->ServerEvent = NULL;
+ }
/* Remove the DOS entry */
if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
@@ -1139,20 +1214,9 @@
RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
}
- if (ConsoleRecord->CurrentDirs != NULL)
- {
- /* Free the current directories */
- RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord->CurrentDirs);
- ConsoleRecord->CurrentDirs = NULL;
- ConsoleRecord->CurDirsLength = 0;
- }
-
- /* Close the event handle */
- if (ConsoleRecord->ServerEvent) NtClose(ConsoleRecord->ServerEvent);
-
/* Remove the console record */
RemoveEntryList(&ConsoleRecord->Entry);
- RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
+ BaseSrvDestroyConsoleRecord(ConsoleRecord);
}
else
{
@@ -1220,6 +1284,8 @@
/* Return the exit code */
GetVDMExitCodeRequest->ExitCode = DosRecord->ExitCode;
+ // FIXME: We may just change DosRecord->State to VDM_READY in some cases...
+
/* Since this is a zombie task record, remove it */
if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
RemoveEntryList(&DosRecord->Entry);
@@ -1245,13 +1311,20 @@
Status = BaseSrvGetConsoleRecord(SetReenterCountRequest->ConsoleHandle,
&ConsoleRecord);
if (!NT_SUCCESS(Status)) goto Cleanup;
- if (SetReenterCountRequest->fIncDec == VDM_INC_REENTER_COUNT)
ConsoleRecord->ReenterCount++;
+ if (SetReenterCountRequest->fIncDec == VDM_INC_REENTER_COUNT)
+ {
+ ConsoleRecord->ReenterCount++;
+ }
else if (SetReenterCountRequest->fIncDec == VDM_DEC_REENTER_COUNT)
{
ConsoleRecord->ReenterCount--;
- if (ConsoleRecord->ServerEvent != NULL)
NtSetEvent(ConsoleRecord->ServerEvent, NULL);
- }
- else Status = STATUS_INVALID_PARAMETER;
+ if (ConsoleRecord->ServerEvent)
+ NtSetEvent(ConsoleRecord->ServerEvent, NULL);
+ }
+ else
+ {
+ Status = STATUS_INVALID_PARAMETER;
+ }
Cleanup:
/* Leave the critical section */
Modified: trunk/reactos/subsystems/win/basesrv/vdm.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win/basesrv/vdm…
==============================================================================
--- trunk/reactos/subsystems/win/basesrv/vdm.h [iso-8859-1] (original)
+++ trunk/reactos/subsystems/win/basesrv/vdm.h [iso-8859-1] Sat Sep 12 16:23:32 2015
@@ -43,18 +43,11 @@
/* FUNCTIONS ******************************************************************/
-NTSTATUS NTAPI BaseSrvGetConsoleRecord(HANDLE ConsoleHandle, PVDM_CONSOLE_RECORD
*Record);
-NTSTATUS NTAPI GetConsoleRecordBySessionId(ULONG TaskId, PVDM_CONSOLE_RECORD *Record);
-ULONG NTAPI GetNextDosSesId(VOID);
-BOOLEAN NTAPI BaseSrvIsVdmAllowed(VOID);
-NTSTATUS NTAPI BaseSrvCreatePairWaitHandles(PHANDLE ServerEvent, PHANDLE ClientEvent);
-VOID NTAPI BaseSrvFreeVDMInfo(PVDM_COMMAND_INFO CommandInfo);
-VOID NTAPI BaseSrvCleanupVDMResources(IN PCSR_PROCESS CsrProcess);
-BOOLEAN NTAPI BaseSrvCopyCommand(PBASE_CHECK_VDM CheckVdmRequest, PVDM_DOS_RECORD
DosRecord);
-NTSTATUS NTAPI BaseSrvFillCommandInfo(
- PVDM_COMMAND_INFO CommandInfo,
- PBASE_GET_NEXT_VDM_COMMAND Message
-);
-VOID NTAPI BaseInitializeVDM(VOID);
+NTSTATUS BaseSrvGetConsoleRecord(HANDLE ConsoleHandle, PVDM_CONSOLE_RECORD *Record);
+NTSTATUS GetConsoleRecordBySessionId(ULONG TaskId, PVDM_CONSOLE_RECORD *Record);
+
+BOOLEAN BaseSrvIsVdmAllowed(VOID);
+VOID BaseInitializeVDM(VOID);
+VOID BaseSrvCleanupVDMResources(IN PCSR_PROCESS CsrProcess);
#endif // __VDM_H__