* FILE: subsystems/win/basesrv/vdm.c
* PURPOSE: Virtual DOS Machines (VDM) Support
* PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
+ * Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
*/
/* INCLUDES *******************************************************************/
#include "basesrv.h"
+#include "vdm.h"
#define NDEBUG
#include <debug.h>
+/* GLOBALS ********************************************************************/
+
+BOOLEAN FirstVDM = TRUE;
+LIST_ENTRY VDMConsoleListHead;
+RTL_CRITICAL_SECTION DosCriticalSection;
+
+/* FUNCTIONS ******************************************************************/
+
+NTSTATUS NTAPI BaseSrvGetConsoleRecord(HANDLE ConsoleHandle, 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->ConsoleHandle == ConsoleHandle) break;
+ }
+
+ *Record = CurrentRecord;
+ return CurrentRecord ? STATUS_SUCCESS : STATUS_NOT_FOUND;
+}
+
+VOID NTAPI BaseInitializeVDM(VOID)
+{
+ /* Initialize the list head */
+ InitializeListHead(&VDMConsoleListHead);
+
+ /* Initialize the critical section */
+ RtlInitializeCriticalSection(&DosCriticalSection);
+}
+
/* PUBLIC SERVER APIS *********************************************************/
CSR_API(BaseSrvCheckVDM)
{
- DPRINT1("%s not yet implemented\n", __FUNCTION__);
+ PBASE_CHECK_VDM CheckVdmRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.CheckVDMRequest;
+
+ /* Validate the message buffers */
+ if (!CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&CheckVdmRequest->CmdLine,
+ CheckVdmRequest->CmdLen,
+ sizeof(*CheckVdmRequest->CmdLine))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&CheckVdmRequest->AppName,
+ CheckVdmRequest->AppLen,
+ sizeof(*CheckVdmRequest->AppName))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&CheckVdmRequest->PifFile,
+ CheckVdmRequest->PifLen,
+ sizeof(*CheckVdmRequest->PifFile))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&CheckVdmRequest->CurDirectory,
+ CheckVdmRequest->CurDirectoryLen,
+ sizeof(*CheckVdmRequest->CurDirectory))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&CheckVdmRequest->Desktop,
+ CheckVdmRequest->DesktopLen,
+ sizeof(*CheckVdmRequest->Desktop))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&CheckVdmRequest->Title,
+ CheckVdmRequest->TitleLen,
+ sizeof(*CheckVdmRequest->Title))
+ || !CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&CheckVdmRequest->Reserved,
+ CheckVdmRequest->ReservedLen,
+ sizeof(*CheckVdmRequest->Reserved)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ // TODO: NOT IMPLEMENTED
return STATUS_NOT_IMPLEMENTED;
}
CSR_API(BaseSrvIsFirstVDM)
{
- DPRINT1("%s not yet implemented\n", __FUNCTION__);
- return STATUS_NOT_IMPLEMENTED;
+ PBASE_IS_FIRST_VDM IsFirstVDMRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.IsFirstVDMRequest;
+
+ /* Return the result */
+ IsFirstVDMRequest->FirstVDM = FirstVDM;
+
+ /* Clear the first VDM flag */
+ FirstVDM = FALSE;
+
+ return STATUS_SUCCESS;
}
CSR_API(BaseSrvGetVDMExitCode)
CSR_API(BaseSrvSetVDMCurDirs)
{
- DPRINT1("%s not yet implemented\n", __FUNCTION__);
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.VDMCurrentDirsRequest;
+ PVDM_CONSOLE_RECORD ConsoleRecord;
+ PCHAR Buffer = NULL;
+
+ /* Validate the input buffer */
+ if (!CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs,
+ VDMCurrentDirsRequest->cchCurDirs,
+ sizeof(*VDMCurrentDirsRequest->lpszzCurDirs)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Enter the critical section */
+ RtlEnterCriticalSection(&DosCriticalSection);
+
+ /* Find the console record */
+ Status = BaseSrvGetConsoleRecord(VDMCurrentDirsRequest->ConsoleHandle, &ConsoleRecord);
+ if (!NT_SUCCESS(Status)) goto Cleanup;
+
+ if (ConsoleRecord->CurrentDirs == NULL)
+ {
+ /* Allocate memory for the current directory information */
+ Buffer = RtlAllocateHeap(BaseSrvHeap,
+ HEAP_ZERO_MEMORY,
+ VDMCurrentDirsRequest->cchCurDirs);
+ }
+ else
+ {
+ /* Resize the amount of allocated memory */
+ Buffer = RtlReAllocateHeap(BaseSrvHeap,
+ HEAP_ZERO_MEMORY,
+ ConsoleRecord->CurrentDirs,
+ VDMCurrentDirsRequest->cchCurDirs);
+ }
+
+ if (Buffer == NULL)
+ {
+ /* Allocation failed */
+ Status = STATUS_NO_MEMORY;
+ goto Cleanup;
+ }
+
+ /* Update the console record */
+ ConsoleRecord->CurrentDirs = Buffer;
+ ConsoleRecord->CurDirsLength = VDMCurrentDirsRequest->cchCurDirs;
+
+ /* Copy the data */
+ RtlMoveMemory(ConsoleRecord->CurrentDirs,
+ VDMCurrentDirsRequest->lpszzCurDirs,
+ VDMCurrentDirsRequest->cchCurDirs);
+
+Cleanup:
+ /* Leave the critical section */
+ RtlLeaveCriticalSection(&DosCriticalSection);
+
+ return Status;
}
CSR_API(BaseSrvGetVDMCurDirs)
{
- DPRINT1("%s not yet implemented\n", __FUNCTION__);
- return STATUS_NOT_IMPLEMENTED;
+ NTSTATUS Status;
+ PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.VDMCurrentDirsRequest;
+ PVDM_CONSOLE_RECORD ConsoleRecord;
+
+ /* Validate the output buffer */
+ if (!CsrValidateMessageBuffer(ApiMessage,
+ (PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs,
+ VDMCurrentDirsRequest->cchCurDirs,
+ sizeof(*VDMCurrentDirsRequest->lpszzCurDirs)))
+ {
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ /* Enter the critical section */
+ RtlEnterCriticalSection(&DosCriticalSection);
+
+ /* Find the console record */
+ Status = BaseSrvGetConsoleRecord(VDMCurrentDirsRequest->ConsoleHandle, &ConsoleRecord);
+ if (!NT_SUCCESS(Status)) goto Cleanup;
+
+ /* Return the actual size of the current directory information */
+ VDMCurrentDirsRequest->cchCurDirs = ConsoleRecord->CurDirsLength;
+
+ /* Check if the buffer is large enough */
+ if (VDMCurrentDirsRequest->cchCurDirs < ConsoleRecord->CurDirsLength)
+ {
+ Status = STATUS_BUFFER_TOO_SMALL;
+ goto Cleanup;
+ }
+
+ /* Copy the data */
+ RtlMoveMemory(VDMCurrentDirsRequest->lpszzCurDirs,
+ ConsoleRecord->CurrentDirs,
+ ConsoleRecord->CurDirsLength);
+
+Cleanup:
+ /* Leave the critical section */
+ RtlLeaveCriticalSection(&DosCriticalSection);
+
+ return Status;
}
CSR_API(BaseSrvBatNotification)