Author: aandrejevic Date: Fri Mar 7 23:46:43 2014 New Revision: 62451
URL: http://svn.reactos.org/svn/reactos?rev=62451&view=rev Log: [BASESRV] - Move more constants to the global header. - Implement GetConsoleRecordBySessionId. - Implement BaseSrvUpdateVDMEntry. - Improve and fix bugs in the cleanup code.
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/include... ============================================================================== --- branches/ntvdm/dll/win32/kernel32/include/vdm.h [iso-8859-1] (original) +++ branches/ntvdm/dll/win32/kernel32/include/vdm.h [iso-8859-1] Fri Mar 7 23:46:43 2014 @@ -7,23 +7,6 @@ */
#pragma once - -/* CONSTANTS ******************************************************************/ - -typedef enum _VDM_ENTRY_CODE -{ - VdmEntryUndo, - VdmEntryUpdateProcess, - VdmEntryUpdateControlCHandler -} VDM_ENTRY_CODE; - -// -// Undo States -// -#define VDM_UNDO_PARTIAL 0x01 -#define VDM_UNDO_FULL 0x02 -#define VDM_UNDO_REUSE 0x04 -#define VDM_UNDO_COMPLETED 0x08
/* FUNCTION PROTOTYPES ********************************************************/
Modified: branches/ntvdm/include/reactos/subsys/win/vdm.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/include/reactos/subsys/win... ============================================================================== --- branches/ntvdm/include/reactos/subsys/win/vdm.h [iso-8859-1] (original) +++ branches/ntvdm/include/reactos/subsys/win/vdm.h [iso-8859-1] Fri Mar 7 23:46:43 2014 @@ -11,6 +11,23 @@ #define _VDM_H
#pragma once + +/* CONSTANTS ******************************************************************/ + +typedef enum _VDM_ENTRY_CODE +{ + VdmEntryUndo, + VdmEntryUpdateProcess, + VdmEntryUpdateControlCHandler +} VDM_ENTRY_CODE; + +// +// Undo States +// +#define VDM_UNDO_PARTIAL 0x01 +#define VDM_UNDO_FULL 0x02 +#define VDM_UNDO_REUSE 0x04 +#define VDM_UNDO_COMPLETED 0x08
// // Binary Types to share with VDM
Modified: branches/ntvdm/subsystems/win/basesrv/vdm.c URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/win/basesrv/vdm... ============================================================================== --- branches/ntvdm/subsystems/win/basesrv/vdm.c [iso-8859-1] (original) +++ branches/ntvdm/subsystems/win/basesrv/vdm.c [iso-8859-1] Fri Mar 7 23:46:43 2014 @@ -34,6 +34,22 @@ { CurrentRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry); if (CurrentRecord->ConsoleHandle == ConsoleHandle) break; + } + + *Record = CurrentRecord; + return CurrentRecord ? STATUS_SUCCESS : STATUS_NOT_FOUND; +} + +NTSTATUS NTAPI GetConsoleRecordBySessionId(ULONG TaskId, PVDM_CONSOLE_RECORD *Record) +{ + PLIST_ENTRY i; + PVDM_CONSOLE_RECORD CurrentRecord = NULL; + + /* Search for a record that has the same console handle */ + for (i = VDMConsoleListHead.Flink; i != &VDMConsoleListHead; i = i->Flink) + { + CurrentRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry); + if (CurrentRecord->SessionId == TaskId) break; }
*Record = CurrentRecord; @@ -463,6 +479,9 @@ 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)) { @@ -487,7 +506,7 @@ { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; }
Cleanup: @@ -497,6 +516,19 @@ /* 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); + } + RtlFreeHeap(BaseSrvHeap, 0, DosRecord); DosRecord = NULL; } @@ -517,8 +549,125 @@
CSR_API(BaseSrvUpdateVDMEntry) { - DPRINT1("%s not yet implemented\n", __FUNCTION__); - return STATUS_NOT_IMPLEMENTED; + NTSTATUS Status; + PBASE_UPDATE_VDM_ENTRY UpdateVdmEntryRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.UpdateVDMEntryRequest; + PRTL_CRITICAL_SECTION CriticalSection = NULL; + PVDM_CONSOLE_RECORD ConsoleRecord = NULL; + PVDM_DOS_RECORD DosRecord = NULL; + + CriticalSection = (UpdateVdmEntryRequest->BinaryType != BINARY_TYPE_SEPARATE_WOW) + ? &DosCriticalSection + : &WowCriticalSection; + + /* Enter the critical section */ + RtlEnterCriticalSection(CriticalSection); + + /* Check if this is a DOS or WOW VDM */ + if (UpdateVdmEntryRequest->BinaryType != BINARY_TYPE_SEPARATE_WOW) + { + if (UpdateVdmEntryRequest->iTask != 0) + { + /* Get the console record using the task ID */ + Status = GetConsoleRecordBySessionId(UpdateVdmEntryRequest->iTask, + &ConsoleRecord); + } + else + { + /* Get the console record using the console handle */ + Status = BaseSrvGetConsoleRecord(UpdateVdmEntryRequest->ConsoleHandle, + &ConsoleRecord); + } + + if (!NT_SUCCESS(Status)) goto Cleanup; + + /* Get the primary DOS record */ + DosRecord = (PVDM_DOS_RECORD)CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink, + VDM_DOS_RECORD, + Entry); + + switch (UpdateVdmEntryRequest->EntryIndex) + { + case VdmEntryUndo: + { + /* Close the server event handle, the client will close the client handle */ + NtClose(DosRecord->ServerEvent); + DosRecord->ServerEvent = DosRecord->ClientEvent = NULL; + + if (UpdateVdmEntryRequest->VDMCreationState & (VDM_UNDO_PARTIAL | VDM_UNDO_FULL)) + { + /* Remove the DOS record */ + if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo); + RemoveEntryList(&DosRecord->Entry); + RtlFreeHeap(BaseSrvHeap, 0, DosRecord); + + /* + * Since this is an undo, if that was the only DOS record the VDM + * won't even start, so the console record should be removed too. + */ + if (ConsoleRecord->DosListHead.Flink == &ConsoleRecord->DosListHead) + { + RemoveEntryList(&ConsoleRecord->Entry); + RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord); + } + } + + /* It was successful */ + Status = STATUS_SUCCESS; + + break; + } + + case VdmEntryUpdateProcess: + { + /* Duplicate the VDM process handle */ + Status = NtDuplicateObject(CsrGetClientThread()->Process->ProcessHandle, + UpdateVdmEntryRequest->VDMProcessHandle, + NtCurrentProcess(), + &ConsoleRecord->ProcessHandle, + 0, + 0, + DUPLICATE_SAME_ATTRIBUTES | DUPLICATE_SAME_ACCESS); + if (!NT_SUCCESS(Status)) goto Cleanup; + + /* Create a pair of handles to one event object */ + Status = BaseSrvCreatePairWaitHandles(&DosRecord->ServerEvent, + &DosRecord->ClientEvent); + if (!NT_SUCCESS(Status)) goto Cleanup; + + /* Return the client event handle */ + UpdateVdmEntryRequest->WaitObjectForParent = DosRecord->ClientEvent; + + break; + } + + case VdmEntryUpdateControlCHandler: + { + // TODO: NOT IMPLEMENTED + DPRINT1("BaseSrvUpdateVDMEntry: VdmEntryUpdateControlCHandler not implemented!"); + Status = STATUS_NOT_IMPLEMENTED; + + break; + } + + default: + { + /* Invalid */ + Status = STATUS_INVALID_PARAMETER; + } + } + } + else + { + // TODO: NOT IMPLEMENTED + UNIMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; + } + +Cleanup: + /* Leave the critical section */ + RtlLeaveCriticalSection(CriticalSection); + + return Status; }
CSR_API(BaseSrvGetNextVDMCommand) @@ -555,7 +704,12 @@ VDM_DOS_RECORD, Entry);
+ /* Set the event and close it */ + NtSetEvent(DosRecord->ServerEvent, NULL); + NtClose(DosRecord->ServerEvent); + /* Remove the DOS entry */ + if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo); RemoveEntryList(&DosRecord->Entry); RtlFreeHeap(BaseSrvHeap, 0, DosRecord); } @@ -576,7 +730,7 @@ { // TODO: NOT IMPLEMENTED UNIMPLEMENTED; - return STATUS_NOT_IMPLEMENTED; + Status = STATUS_NOT_IMPLEMENTED; }
Cleanup: @@ -639,6 +793,7 @@ GetVDMExitCodeRequest->ExitCode = DosRecord->ExitCode;
/* Since this is a zombie task record, remove it */ + if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo); RemoveEntryList(&DosRecord->Entry); RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
Modified: branches/ntvdm/subsystems/win/basesrv/vdm.h URL: http://svn.reactos.org/svn/reactos/branches/ntvdm/subsystems/win/basesrv/vdm... ============================================================================== --- branches/ntvdm/subsystems/win/basesrv/vdm.h [iso-8859-1] (original) +++ branches/ntvdm/subsystems/win/basesrv/vdm.h [iso-8859-1] Fri Mar 7 23:46:43 2014 @@ -20,6 +20,7 @@ { LIST_ENTRY Entry; HANDLE ConsoleHandle; + HANDLE ProcessHandle; PCHAR CurrentDirs; ULONG CurDirsLength; ULONG SessionId;