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/includ…
==============================================================================
--- 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/wi…
==============================================================================
--- 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/vd…
==============================================================================
--- 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/vd…
==============================================================================
--- 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;