[BASESRV]
authorAleksandar Andrejevic <aandrejevic@reactos.org>
Tue, 29 Apr 2014 00:41:48 +0000 (00:41 +0000)
committerAleksandar Andrejevic <aandrejevic@reactos.org>
Tue, 29 Apr 2014 00:41:48 +0000 (00:41 +0000)
Implement BaseSrvDisconnect and BaseSrvCleanupVdmRecords, which will remove VDM console and DOS records
which have been left behind by a terminated ntvdm process.
Implement the "VDM voodoo" in BaseSrvCreateProcess. It's supposed to store the process ID of the VDM
in the VDM console record.
Fix minor bugs.
Add function declarations to the header file.

svn path=/branches/ntvdm/; revision=63042

subsystems/win/basesrv/init.c
subsystems/win/basesrv/proc.c
subsystems/win/basesrv/vdm.c
subsystems/win/basesrv/vdm.h

index 79d1d46..ef98ed3 100644 (file)
@@ -570,6 +570,14 @@ BaseInitializeStaticServerData(IN PCSR_SERVER_DLL LoadedServerDll)
     LoadedServerDll->SharedSection = BaseStaticServerData;
 }
 
+VOID
+NTAPI
+BaseSrvDisconnect(PCSR_PROCESS Process)
+{
+    /* Cleanup the VDM console records */
+    BaseSrvCleanupVdmRecords(HandleToUlong(Process->ClientId.UniqueProcess));
+}
+
 CSR_SERVER_DLL_INIT(ServerDllInitialization)
 {
     /* Setup the DLL Object */
@@ -582,7 +590,7 @@ CSR_SERVER_DLL_INIT(ServerDllInitialization)
 #endif
     LoadedServerDll->SizeOfProcessData = 0;
     LoadedServerDll->ConnectCallback = NULL;
-    LoadedServerDll->DisconnectCallback = NULL;
+    LoadedServerDll->DisconnectCallback = BaseSrvDisconnect;
     LoadedServerDll->ShutdownProcessCallback = NULL;
 
     BaseSrvDllInstance = LoadedServerDll->ServerHandle;
index e61405c..53113f7 100644 (file)
@@ -9,6 +9,7 @@
 /* INCLUDES *******************************************************************/
 
 #include "basesrv.h"
+#include "vdm.h"
 
 #define NDEBUG
 #include <debug.h>
@@ -167,7 +168,30 @@ CSR_API(BaseSrvCreateProcess)
 
     /* FIXME: Should notify user32 */
 
-    /* FIXME: VDM vodoo */
+    /* Check if this is a VDM process */
+    if (CreateProcessRequest->VdmBinaryType)
+    {
+        PVDM_CONSOLE_RECORD ConsoleRecord;
+
+        if (CreateProcessRequest->VdmTask != 0)
+        {
+            /* Get the console record using the task ID */
+            Status = GetConsoleRecordBySessionId(CreateProcessRequest->VdmTask,
+                                                 &ConsoleRecord);
+        }
+        else
+        {
+            /* Get the console record using the console handle */
+            Status = BaseSrvGetConsoleRecord(CreateProcessRequest->hVDM,
+                                             &ConsoleRecord);
+        }
+
+        /* Check if it failed */
+        if (!NT_SUCCESS(Status)) return Status;
+
+        /* Store the process ID of the VDM in the console record */
+        ConsoleRecord->ProcessId = HandleToUlong(CreateProcessRequest->ClientId.UniqueProcess);
+    }
 
     /* Return the result of this operation */
     return Status;
index ec4a144..e809495 100644 (file)
@@ -203,7 +203,7 @@ NTSTATUS NTAPI BaseSrvCreatePairWaitHandles(PHANDLE ServerEvent, PHANDLE ClientE
     return Status;
 }
 
-VOID BaseSrvFreeVDMInfo(PVDM_COMMAND_INFO CommandInfo)
+VOID NTAPI BaseSrvFreeVDMInfo(PVDM_COMMAND_INFO CommandInfo)
 {
     /* Free the allocated structure members */
     if (CommandInfo->CmdLine != NULL) RtlFreeHeap(BaseSrvHeap, 0, CommandInfo->CmdLine);
@@ -219,6 +219,61 @@ VOID BaseSrvFreeVDMInfo(PVDM_COMMAND_INFO CommandInfo)
     RtlFreeHeap(BaseSrvHeap, 0, CommandInfo);
 }
 
+VOID NTAPI BaseSrvCleanupVdmRecords(ULONG ProcessId)
+{
+    PLIST_ENTRY i;
+    PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
+    PVDM_DOS_RECORD DosRecord;
+
+    /* Enter the critical section */
+    RtlEnterCriticalSection(&DosCriticalSection);
+
+    /* Search for a record that has the same process handle */
+    for (i = VDMConsoleListHead.Flink; i != &VDMConsoleListHead; i = i->Flink)
+    {
+        ConsoleRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry);
+
+        if (ConsoleRecord->ProcessId == ProcessId)
+        {
+            /* Cleanup the DOS records */
+            while (ConsoleRecord->DosListHead.Flink != &ConsoleRecord->DosListHead)
+            {
+                DosRecord = CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
+                                              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);
+            }
+
+            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 */
+            i = i->Blink;
+            RemoveEntryList(&ConsoleRecord->Entry);
+            RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
+        }
+    }
+
+    /* Leave the critical section */
+    RtlLeaveCriticalSection(&DosCriticalSection);
+}
+
 BOOLEAN NTAPI BaseSrvCopyCommand(PBASE_CHECK_VDM CheckVdmRequest, PVDM_DOS_RECORD DosRecord)
 {
     BOOLEAN Success = FALSE;
@@ -367,7 +422,7 @@ Cleanup:
 }
 
 NTSTATUS NTAPI BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo,
-                                  PBASE_GET_NEXT_VDM_COMMAND Message)
+                                      PBASE_GET_NEXT_VDM_COMMAND Message)
 {
     /* Copy the data */
     Message->iTask = CommandInfo->TaskId;
index ae4cd27..3da59d9 100644 (file)
@@ -23,6 +23,7 @@ typedef struct _VDM_CONSOLE_RECORD
     HANDLE ProcessHandle;
     HANDLE ServerEvent;
     HANDLE ClientEvent;
+    ULONG ProcessId;
     ULONG ReenterCount;
     PCHAR CurrentDirs;
     ULONG CurDirsLength;
@@ -43,6 +44,17 @@ typedef struct _VDM_DOS_RECORD
 /* 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 BaseSrvCleanupVdmRecords(ULONG ProcessId);
+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);
 
 #endif // __VDM_H__