ReactOS 0.4.15-dev-7842-g558ab78
vdm.c File Reference
#include "basesrv.h"
#include "vdm.h"
#include <debug.h>
Include dependency graph for vdm.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

PVDM_CONSOLE_RECORD BaseSrvCreateConsoleRecord (VOID)
 
NTSTATUS BaseSrvGetConsoleRecord (HANDLE ConsoleHandle, PVDM_CONSOLE_RECORD *Record)
 
VOID BaseSrvDestroyConsoleRecord (PVDM_CONSOLE_RECORD ConsoleRecord)
 
NTSTATUS GetConsoleRecordBySessionId (ULONG TaskId, PVDM_CONSOLE_RECORD *Record)
 
ULONG GetNextDosSesId (VOID)
 
BOOLEAN BaseSrvIsVdmAllowed (VOID)
 
NTSTATUS BaseSrvCreatePairWaitHandles (PHANDLE ServerEvent, PHANDLE ClientEvent)
 
VOID BaseSrvDestroyPairWaitHandles (HANDLE ServerEvent, HANDLE ClientEvent)
 
VOID BaseSrvFreeVDMInfo (PVDM_COMMAND_INFO CommandInfo)
 
VOID BaseSrvCleanupVDMResources (IN PCSR_PROCESS CsrProcess)
 
BOOLEAN BaseSrvCopyCommand (PBASE_CHECK_VDM CheckVdmRequest, PVDM_DOS_RECORD DosRecord)
 
NTSTATUS BaseSrvFillCommandInfo (PVDM_COMMAND_INFO CommandInfo, PBASE_GET_NEXT_VDM_COMMAND Message)
 
VOID BaseInitializeVDM (VOID)
 
 CSR_API (BaseSrvCheckVDM)
 
 CSR_API (BaseSrvUpdateVDMEntry)
 
 CSR_API (BaseSrvGetNextVDMCommand)
 
 CSR_API (BaseSrvExitVDM)
 
 CSR_API (BaseSrvIsFirstVDM)
 
 CSR_API (BaseSrvGetVDMExitCode)
 
 CSR_API (BaseSrvSetReenterCount)
 
 CSR_API (BaseSrvSetVDMCurDirs)
 
 CSR_API (BaseSrvGetVDMCurDirs)
 
 CSR_API (BaseSrvBatNotification)
 
 CSR_API (BaseSrvRegisterWowExec)
 
 CSR_API (BaseSrvRefreshIniFileMapping)
 

Variables

BOOLEAN FirstVDM = TRUE
 
LIST_ENTRY VDMConsoleListHead
 
RTL_CRITICAL_SECTION DosCriticalSection
 
RTL_CRITICAL_SECTION WowCriticalSection
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 15 of file vdm.c.

Function Documentation

◆ BaseInitializeVDM()

VOID BaseInitializeVDM ( VOID  )

Definition at line 587 of file vdm.c.

588{
589 /* Initialize the list head */
591
592 /* Initialize the critical sections */
595}
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
LIST_ENTRY VDMConsoleListHead
Definition: vdm.c:21
RTL_CRITICAL_SECTION DosCriticalSection
Definition: vdm.c:22
RTL_CRITICAL_SECTION WowCriticalSection
Definition: vdm.c:23

Referenced by CSR_SERVER_DLL_INIT().

◆ BaseSrvCleanupVDMResources()

VOID BaseSrvCleanupVDMResources ( IN PCSR_PROCESS  CsrProcess)

Definition at line 296 of file vdm.c.

297{
298 ULONG ProcessId = HandleToUlong(CsrProcess->ClientId.UniqueProcess);
299 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
300 PVDM_DOS_RECORD DosRecord;
302
303 /* Enter the critical section */
305
306 /* Search for a record that has the same process handle */
308 while (i != &VDMConsoleListHead)
309 {
310 ConsoleRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry);
311 i = i->Flink;
312
313 if (ConsoleRecord->ProcessId == ProcessId)
314 {
315 if (ConsoleRecord->ServerEvent)
316 {
317 NtClose(ConsoleRecord->ServerEvent);
318 ConsoleRecord->ServerEvent = NULL;
319 }
320
321 /* Cleanup the DOS records */
322 while (!IsListEmpty(&ConsoleRecord->DosListHead))
323 {
324 DosRecord = CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
326
327 /* Set the event and close it */
328 if (DosRecord->ServerEvent)
329 {
330 NtSetEvent(DosRecord->ServerEvent, NULL);
331 NtClose(DosRecord->ServerEvent);
332 DosRecord->ServerEvent = NULL;
333 }
334
335 /* Remove the DOS entry */
336 if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
337 RemoveEntryList(&DosRecord->Entry);
338 RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
339 }
340
341 /* Remove the console record */
342 RemoveEntryList(&ConsoleRecord->Entry);
343 BaseSrvDestroyConsoleRecord(ConsoleRecord);
344 }
345 }
346
347 /* Leave the critical section */
349}
HANDLE BaseSrvHeap
Definition: init.c:29
#define HandleToUlong(h)
Definition: basetsd.h:79
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
#define NULL
Definition: types.h:112
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2711
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
base of all file and directory entries
Definition: entries.h:83
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
HANDLE ServerEvent
Definition: vdm.h:24
LIST_ENTRY Entry
Definition: vdm.h:21
LIST_ENTRY DosListHead
Definition: vdm.h:31
ULONG ProcessId
Definition: vdm.h:26
HANDLE ServerEvent
Definition: vdm.h:39
LIST_ENTRY Entry
Definition: vdm.h:36
PVDM_COMMAND_INFO CommandInfo
Definition: vdm.h:41
VOID BaseSrvDestroyConsoleRecord(PVDM_CONSOLE_RECORD ConsoleRecord)
Definition: vdm.c:71
VOID BaseSrvFreeVDMInfo(PVDM_COMMAND_INFO CommandInfo)
Definition: vdm.c:280
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
PKPROCESS CsrProcess
Definition: videoprt.c:39

Referenced by BaseClientDisconnectRoutine().

◆ BaseSrvCopyCommand()

BOOLEAN BaseSrvCopyCommand ( PBASE_CHECK_VDM  CheckVdmRequest,
PVDM_DOS_RECORD  DosRecord 
)

Definition at line 351 of file vdm.c.

352{
355
356 /* Allocate the command information structure */
359 sizeof(VDM_COMMAND_INFO));
360 if (CommandInfo == NULL) return FALSE;
361
362 /* Fill the structure */
363 CommandInfo->TaskId = CheckVdmRequest->iTask;
364 CommandInfo->ExitCode = DosRecord->ExitCode;
365 CommandInfo->CodePage = CheckVdmRequest->CodePage;
366 CommandInfo->StdIn = CheckVdmRequest->StdIn;
367 CommandInfo->StdOut = CheckVdmRequest->StdOut;
368 CommandInfo->StdErr = CheckVdmRequest->StdErr;
369
370 /* Allocate memory for the command line */
373 CheckVdmRequest->CmdLen);
374 if (CommandInfo->CmdLine == NULL) goto Cleanup;
375
376 /* Copy the command line */
377 RtlMoveMemory(CommandInfo->CmdLine, CheckVdmRequest->CmdLine, CheckVdmRequest->CmdLen);
378
379 /* Allocate memory for the application name */
382 CheckVdmRequest->AppLen);
383 if (CommandInfo->AppName == NULL) goto Cleanup;
384
385 /* Copy the application name */
386 RtlMoveMemory(CommandInfo->AppName, CheckVdmRequest->AppName, CheckVdmRequest->AppLen);
387
388 /* Allocate memory for the PIF file name */
389 if (CheckVdmRequest->PifLen != 0)
390 {
393 CheckVdmRequest->PifLen);
394 if (CommandInfo->PifFile == NULL) goto Cleanup;
395
396 /* Copy the PIF file name */
397 RtlMoveMemory(CommandInfo->PifFile, CheckVdmRequest->PifFile, CheckVdmRequest->PifLen);
398 }
399 else CommandInfo->PifFile = NULL;
400
401 /* Allocate memory for the current directory */
402 if (CheckVdmRequest->CurDirectoryLen != 0)
403 {
406 CheckVdmRequest->CurDirectoryLen);
407 if (CommandInfo->CurDirectory == NULL) goto Cleanup;
408
409 /* Copy the current directory */
411 CheckVdmRequest->CurDirectory,
412 CheckVdmRequest->CurDirectoryLen);
413 }
415
416 /* Allocate memory for the environment block */
419 CheckVdmRequest->EnvLen);
420 if (CommandInfo->Env == NULL) goto Cleanup;
421
422 /* Copy the environment block */
423 RtlMoveMemory(CommandInfo->Env, CheckVdmRequest->Env, CheckVdmRequest->EnvLen);
424
425 CommandInfo->EnvLen = CheckVdmRequest->EnvLen;
427 CheckVdmRequest->StartupInfo,
428 sizeof(STARTUPINFOA));
429
430 /* Allocate memory for the desktop */
431 if (CheckVdmRequest->DesktopLen != 0)
432 {
435 CheckVdmRequest->DesktopLen);
436 if (CommandInfo->Desktop == NULL) goto Cleanup;
437
438 /* Copy the desktop name */
439 RtlMoveMemory(CommandInfo->Desktop, CheckVdmRequest->Desktop, CheckVdmRequest->DesktopLen);
440 }
441 else CommandInfo->Desktop = NULL;
442
443 CommandInfo->DesktopLen = CheckVdmRequest->DesktopLen;
444
445 /* Allocate memory for the title */
446 if (CheckVdmRequest->TitleLen != 0)
447 {
450 CheckVdmRequest->TitleLen);
451 if (CommandInfo->Title == NULL) goto Cleanup;
452
453 /* Copy the title */
454 RtlMoveMemory(CommandInfo->Title, CheckVdmRequest->Title, CheckVdmRequest->TitleLen);
455 }
456 else CommandInfo->Title = NULL;
457
458 CommandInfo->TitleLen = CheckVdmRequest->TitleLen;
459
460 /* Allocate memory for the reserved field */
461 if (CheckVdmRequest->ReservedLen != 0)
462 {
465 CheckVdmRequest->ReservedLen);
466 if (CommandInfo->Reserved == NULL) goto Cleanup;
467
468 /* Copy the reserved field */
470 CheckVdmRequest->Reserved,
471 CheckVdmRequest->ReservedLen);
472 }
473 else CommandInfo->Reserved = NULL;
474
475 CommandInfo->ReservedLen = CheckVdmRequest->ReservedLen;
476
477 CommandInfo->CmdLen = CheckVdmRequest->CmdLen;
478 CommandInfo->AppLen = CheckVdmRequest->AppLen;
479 CommandInfo->PifLen = CheckVdmRequest->PifLen;
480 CommandInfo->CurDirectoryLen = CheckVdmRequest->CurDirectoryLen;
481 CommandInfo->VDMState = DosRecord->State;
482 // TODO: Set CommandInfo->CurrentDrive
483 // TODO: Set CommandInfo->ComingFromBat
484
485 /* Set the DOS record's command structure */
486 DosRecord->CommandInfo = CommandInfo;
487
488 /* The operation was successful */
489 Success = TRUE;
490
491Cleanup:
492 /* If it wasn't successful, free the memory */
494
495 return Success;
496}
unsigned char BOOLEAN
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
static VDM_COMMAND_INFO CommandInfo
Definition: dem.c:246
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
static const WCHAR Cleanup[]
Definition: register.c:80
@ Success
Definition: eventcreate.c:712
struct VDM_COMMAND_INFO * PVDM_COMMAND_INFO
LPSTR CmdLine
Definition: vdm.h:77
HANDLE StdOut
Definition: vdm.h:75
STARTUPINFOA StartupInfo
Definition: vdm.h:83
LPSTR CurDirectory
Definition: vdm.h:80
LPSTR Title
Definition: vdm.h:86
USHORT AppLen
Definition: vdm.h:91
ULONG ReservedLen
Definition: vdm.h:89
HANDLE StdIn
Definition: vdm.h:74
USHORT CmdLen
Definition: vdm.h:90
LPSTR Desktop
Definition: vdm.h:84
USHORT PifLen
Definition: vdm.h:92
LPSTR Env
Definition: vdm.h:81
ULONG TitleLen
Definition: vdm.h:87
ULONG CodePage
Definition: vdm.h:73
USHORT CurDirectoryLen
Definition: vdm.h:93
LPSTR PifFile
Definition: vdm.h:79
LPSTR AppName
Definition: vdm.h:78
ULONG TaskId
Definition: vdm.h:70
LPVOID Reserved
Definition: vdm.h:88
ULONG DesktopLen
Definition: vdm.h:85
HANDLE StdErr
Definition: vdm.h:76
USHORT VDMState
Definition: vdm.h:94
ULONG EnvLen
Definition: vdm.h:82
ULONG ExitCode
Definition: vdm.h:72
ULONG EnvLen
Definition: basemsg.h:134
ULONG CodePage
Definition: basemsg.h:127
ULONG TitleLen
Definition: basemsg.h:139
PCHAR Desktop
Definition: basemsg.h:136
USHORT CurDirectoryLen
Definition: basemsg.h:145
HANDLE StdOut
Definition: basemsg.h:125
PCHAR PifFile
Definition: basemsg.h:131
HANDLE StdErr
Definition: basemsg.h:126
ULONG ReservedLen
Definition: basemsg.h:141
PCHAR Reserved
Definition: basemsg.h:140
HANDLE StdIn
Definition: basemsg.h:124
PCHAR CmdLine
Definition: basemsg.h:129
ULONG DesktopLen
Definition: basemsg.h:137
PCHAR AppName
Definition: basemsg.h:130
LPSTARTUPINFOA StartupInfo
Definition: basemsg.h:135
USHORT PifLen
Definition: basemsg.h:144
PCHAR CurDirectory
Definition: basemsg.h:132
USHORT CmdLen
Definition: basemsg.h:142
USHORT AppLen
Definition: basemsg.h:143
ULONG ExitCode
Definition: vdm.h:38
USHORT State
Definition: vdm.h:37
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264

Referenced by CSR_API().

◆ BaseSrvCreateConsoleRecord()

PVDM_CONSOLE_RECORD BaseSrvCreateConsoleRecord ( VOID  )

Definition at line 27 of file vdm.c.

28{
29 PVDM_CONSOLE_RECORD ConsoleRecord;
30
32 sizeof(VDM_CONSOLE_RECORD));
33 if (ConsoleRecord == NULL)
34 return NULL;
35
36 /* Initialize the console record */
37 ConsoleRecord->ConsoleHandle = NULL;
38 ConsoleRecord->ProcessHandle = NULL;
39 ConsoleRecord->ServerEvent = ConsoleRecord->ClientEvent = NULL;
40 ConsoleRecord->ReenterCount = 0;
41 ConsoleRecord->CurrentDirs = NULL;
42 ConsoleRecord->CurDirsLength = 0;
43 ConsoleRecord->SessionId = 0;
44 InitializeListHead(&ConsoleRecord->DosListHead);
45
46 return ConsoleRecord;
47}
HANDLE ProcessHandle
Definition: vdm.h:23
ULONG SessionId
Definition: vdm.h:30
HANDLE ConsoleHandle
Definition: vdm.h:22
PCHAR CurrentDirs
Definition: vdm.h:28
ULONG CurDirsLength
Definition: vdm.h:29
ULONG ReenterCount
Definition: vdm.h:27
HANDLE ClientEvent
Definition: vdm.h:25

Referenced by CSR_API().

◆ BaseSrvCreatePairWaitHandles()

NTSTATUS BaseSrvCreatePairWaitHandles ( PHANDLE  ServerEvent,
PHANDLE  ClientEvent 
)

Definition at line 239 of file vdm.c.

240{
242
243 /* Create the event */
245 if (!NT_SUCCESS(Status)) return Status;
246
247 /* Duplicate the event into the client process */
249 *ServerEvent,
250 CsrGetClientThread()->Process->ProcessHandle,
251 ClientEvent,
252 0,
253 0,
255
256 if (!NT_SUCCESS(Status)) NtClose(*ServerEvent);
257 return Status;
258}
LONG NTSTATUS
Definition: precomp.h:26
#define CsrGetClientThread()
Definition: csrsrv.h:77
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:153
#define NtCurrentProcess()
Definition: nt_native.h:1657
@ NotificationEvent
NTSTATUS NTAPI NtCreateEvent(OUT PHANDLE EventHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN EVENT_TYPE EventType, IN BOOLEAN InitialState)
Definition: event.c:96
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3410
#define DUPLICATE_SAME_ACCESS

Referenced by CSR_API().

◆ BaseSrvDestroyConsoleRecord()

VOID BaseSrvDestroyConsoleRecord ( PVDM_CONSOLE_RECORD  ConsoleRecord)

Definition at line 71 of file vdm.c.

72{
73 if (ConsoleRecord->CurrentDirs != NULL)
74 {
75 /* Free the current directories */
76 RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord->CurrentDirs);
77 ConsoleRecord->CurrentDirs = NULL;
78 ConsoleRecord->CurDirsLength = 0;
79 }
80
81 /* Close the process handle */
82 if (ConsoleRecord->ProcessHandle)
83 NtClose(ConsoleRecord->ProcessHandle);
84
85 /* Close the event handle */
86 if (ConsoleRecord->ServerEvent)
87 NtClose(ConsoleRecord->ServerEvent);
88
89 /* Remove the console record */
90 // RemoveEntryList(&ConsoleRecord->Entry);
91 RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
92}

Referenced by BaseSrvCleanupVDMResources(), and CSR_API().

◆ BaseSrvDestroyPairWaitHandles()

VOID BaseSrvDestroyPairWaitHandles ( HANDLE  ServerEvent,
HANDLE  ClientEvent 
)

Definition at line 260 of file vdm.c.

261{
262 if (ServerEvent) NtClose(ServerEvent);
263 if (ClientEvent)
264 {
265 /* Close the remote handle */
267 ClientEvent,
268 NULL,
269 NULL,
270 0,
271 0,
273 }
274}
#define DUPLICATE_CLOSE_SOURCE

Referenced by CSR_API().

◆ BaseSrvFillCommandInfo()

NTSTATUS BaseSrvFillCommandInfo ( PVDM_COMMAND_INFO  CommandInfo,
PBASE_GET_NEXT_VDM_COMMAND  Message 
)

Definition at line 498 of file vdm.c.

500{
502
503 /* Copy the data */
504 Message->iTask = CommandInfo->TaskId;
505 Message->StdIn = CommandInfo->StdIn;
506 Message->StdOut = CommandInfo->StdOut;
507 Message->StdErr = CommandInfo->StdErr;
508 Message->CodePage = CommandInfo->CodePage;
509 Message->dwCreationFlags = CommandInfo->CreationFlags;
510 Message->ExitCode = CommandInfo->ExitCode;
511 Message->CurrentDrive = CommandInfo->CurrentDrive;
512 Message->VDMState = CommandInfo->VDMState;
513 Message->fComingFromBat = CommandInfo->ComingFromBat;
514
515 if (Message->CmdLen >= CommandInfo->CmdLen)
516 {
517 /* Copy the command line */
519 }
521 Message->CmdLen = CommandInfo->CmdLen;
522
523 if (Message->AppLen >= CommandInfo->AppLen)
524 {
525 /* Copy the application name */
527 }
529 Message->AppLen = CommandInfo->AppLen;
530
531 if (Message->PifLen >= CommandInfo->PifLen)
532 {
533 /* Copy the PIF file name */
535 }
537 Message->PifLen = CommandInfo->PifLen;
538
539 if (Message->CurDirectoryLen >= CommandInfo->CurDirectoryLen)
540 {
541 /* Copy the current directory */
543 }
545 Message->CurDirectoryLen = CommandInfo->CurDirectoryLen;
546
547 if (Message->EnvLen >= CommandInfo->EnvLen)
548 {
549 /* Copy the environment */
551 }
553 Message->EnvLen = CommandInfo->EnvLen;
554
555 /* Copy the startup info */
556 RtlMoveMemory(Message->StartupInfo,
558 sizeof(STARTUPINFOA));
559
560 if (Message->DesktopLen >= CommandInfo->DesktopLen)
561 {
562 /* Copy the desktop name */
564 }
566 Message->DesktopLen = CommandInfo->DesktopLen;
567
568 if (Message->TitleLen >= CommandInfo->TitleLen)
569 {
570 /* Copy the title */
572 }
574 Message->TitleLen = CommandInfo->TitleLen;
575
576 if (Message->ReservedLen >= CommandInfo->ReservedLen)
577 {
578 /* Copy the reserved parameter */
580 }
582 Message->ReservedLen = CommandInfo->ReservedLen;
583
584 return Status;
585}
static const WCHAR Message[]
Definition: register.c:74
#define STATUS_SUCCESS
Definition: shellext.h:65
BOOLEAN ComingFromBat
Definition: vdm.h:96
USHORT CurrentDrive
Definition: vdm.h:95
ULONG CreationFlags
Definition: vdm.h:71
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135

Referenced by CSR_API().

◆ BaseSrvFreeVDMInfo()

VOID BaseSrvFreeVDMInfo ( PVDM_COMMAND_INFO  CommandInfo)

◆ BaseSrvGetConsoleRecord()

NTSTATUS BaseSrvGetConsoleRecord ( HANDLE  ConsoleHandle,
PVDM_CONSOLE_RECORD Record 
)

Definition at line 49 of file vdm.c.

50{
52 PVDM_CONSOLE_RECORD CurrentRecord = NULL;
53
54 /* NULL is not a valid console handle */
55 if (ConsoleHandle == NULL) return STATUS_INVALID_PARAMETER;
56
57 /* Search for a record that has the same console handle */
58 for (i = VDMConsoleListHead.Flink; i != &VDMConsoleListHead; i = i->Flink)
59 {
61 if (CurrentRecord->ConsoleHandle == ConsoleHandle) break;
62 }
63
64 /* Check if nothing was found */
65 if (i == &VDMConsoleListHead) CurrentRecord = NULL;
66
67 *Record = CurrentRecord;
68 return CurrentRecord ? STATUS_SUCCESS : STATUS_NOT_FOUND;
69}
#define STATUS_NOT_FOUND
Definition: shellext.h:72
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:268

Referenced by CSR_API().

◆ BaseSrvIsVdmAllowed()

BOOLEAN BaseSrvIsVdmAllowed ( VOID  )

Definition at line 142 of file vdm.c.

143{
145 BOOLEAN VdmAllowed = TRUE;
147 UNICODE_STRING KeyName, ValueName, MachineKeyName;
149 UCHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
151 ULONG ActualSize;
152
153 /* Initialize the unicode strings */
154 RtlInitUnicodeString(&MachineKeyName, L"\\Registry\\Machine");
157
159 &MachineKeyName,
161 NULL,
162 NULL);
163
164 /* Open the local machine key */
166 if (!NT_SUCCESS(Status)) return FALSE;
167
169 &KeyName,
171 RootKey,
172 NULL);
173
174 /* Open the policy key in the local machine hive, if it exists */
176 {
177 /* Read the value, if it's set */
179 &ValueName,
181 ValueInfo,
182 sizeof(ValueBuffer),
183 &ActualSize)))
184 {
185 if (*((PULONG)ValueInfo->Data))
186 {
187 /* The VDM has been disabled in the registry */
188 VdmAllowed = FALSE;
189 }
190 }
191
193 }
194
195 /* Close the local machine key */
197
198 /* If it's disabled system-wide, there's no need to check the user key */
199 if (!VdmAllowed) return FALSE;
200
201 /* Open the current user key of the client */
202 if (!CsrImpersonateClient(NULL)) return VdmAllowed;
205
206 /* If that fails, return the system-wide setting */
207 if (!NT_SUCCESS(Status)) return VdmAllowed;
208
210 &KeyName,
212 RootKey,
213 NULL);
214
215 /* Open the policy key in the current user hive, if it exists */
217 {
218 /* Read the value, if it's set */
220 &ValueName,
222 ValueInfo,
223 sizeof(ValueBuffer),
224 &ActualSize)))
225 {
226 if (*((PULONG)ValueInfo->Data))
227 {
228 /* The VDM has been disabled in the registry */
229 VdmAllowed = FALSE;
230 }
231 }
232
234 }
235
236 return VdmAllowed;
237}
BOOLEAN NTAPI CsrImpersonateClient(IN PCSR_THREAD CsrThread)
Definition: procsup.c:932
BOOLEAN NTAPI CsrRevertToSelf(VOID)
Definition: procsup.c:1057
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
NTSYSAPI NTSTATUS NTAPI RtlOpenCurrentUser(_In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE KeyHandle)
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
@ KeyValuePartialInformation
Definition: nt_native.h:1182
#define KEY_READ
Definition: nt_native.h:1023
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI NTSTATUS NTAPI NtQueryValueKey(IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName, IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass, IN PVOID KeyValueInformation, IN ULONG Length, IN PULONG ResultLength)
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
#define L(x)
Definition: ntvdm.h:50
static PMEMKEY RootKey
Definition: registry.c:55
#define VDM_POLICY_KEY_NAME
Definition: vdm.h:16
#define VDM_DISALLOWED_VALUE_NAME
Definition: vdm.h:17
uint32_t * PULONG
Definition: typedefs.h:59
_Must_inspect_result_ _In_ WDFDMAENABLER _In_ _In_opt_ PWDF_OBJECT_ATTRIBUTES Attributes
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING KeyName
Definition: wdfdevice.h:2699
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by CSR_API().

◆ CSR_API() [1/12]

CSR_API ( BaseSrvBatNotification  )

Definition at line 1441 of file vdm.c.

1442{
1443 DPRINT1("%s not yet implemented\n", __FUNCTION__);
1445}
#define DPRINT1
Definition: precomp.h:8
#define __FUNCTION__
Definition: types.h:116
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239

◆ CSR_API() [2/12]

CSR_API ( BaseSrvCheckVDM  )

Definition at line 599 of file vdm.c.

600{
602 PBASE_CHECK_VDM CheckVdmRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.CheckVDMRequest;
604 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
605 PVDM_DOS_RECORD DosRecord = NULL;
606 BOOLEAN NewConsoleRecord = FALSE;
607 BOOLEAN NewDosRecord = FALSE;
608
609 /* Don't do anything if the VDM has been disabled in the registry */
611
612 /* Validate the message buffers */
613 if (!CsrValidateMessageBuffer(ApiMessage,
614 (PVOID*)&CheckVdmRequest->CmdLine,
615 CheckVdmRequest->CmdLen,
616 sizeof(*CheckVdmRequest->CmdLine))
617 || !CsrValidateMessageBuffer(ApiMessage,
618 (PVOID*)&CheckVdmRequest->AppName,
619 CheckVdmRequest->AppLen,
620 sizeof(*CheckVdmRequest->AppName))
621 || !CsrValidateMessageBuffer(ApiMessage,
622 (PVOID*)&CheckVdmRequest->PifFile,
623 CheckVdmRequest->PifLen,
624 sizeof(*CheckVdmRequest->PifFile))
625 || !CsrValidateMessageBuffer(ApiMessage,
626 (PVOID*)&CheckVdmRequest->CurDirectory,
627 CheckVdmRequest->CurDirectoryLen,
628 sizeof(*CheckVdmRequest->CurDirectory))
629 || !CsrValidateMessageBuffer(ApiMessage,
630 (PVOID*)&CheckVdmRequest->Desktop,
631 CheckVdmRequest->DesktopLen,
632 sizeof(*CheckVdmRequest->Desktop))
633 || !CsrValidateMessageBuffer(ApiMessage,
634 (PVOID*)&CheckVdmRequest->Title,
635 CheckVdmRequest->TitleLen,
636 sizeof(*CheckVdmRequest->Title))
637 || !CsrValidateMessageBuffer(ApiMessage,
638 (PVOID*)&CheckVdmRequest->Reserved,
639 CheckVdmRequest->ReservedLen,
640 sizeof(*CheckVdmRequest->Reserved)))
641 {
643 }
644
648
649 /* Enter the critical section */
651
652 /* Check if this is a DOS or WOW VDM */
653 if (CheckVdmRequest->BinaryType != BINARY_TYPE_SEPARATE_WOW)
654 {
655 /* Get the console record */
657 &ConsoleRecord);
658 if (!NT_SUCCESS(Status))
659 {
660 /* Allocate a new console record */
661 ConsoleRecord = BaseSrvCreateConsoleRecord();
662 if (ConsoleRecord == NULL)
663 {
665 goto Cleanup;
666 }
667
668 /* Initialize the console record */
669 ConsoleRecord->ConsoleHandle = CheckVdmRequest->ConsoleHandle;
670 if (ConsoleRecord->ConsoleHandle == NULL)
671 {
672 /* The parent doesn't have a console, get a new session ID */
673 ConsoleRecord->SessionId = GetNextDosSesId();
674 }
675 else
676 {
677 /* No session ID is needed */
678 ConsoleRecord->SessionId = 0;
679 }
680
681 /* Remember that the console record was allocated here */
682 NewConsoleRecord = TRUE;
683 }
684
685 if (!NewConsoleRecord)
686 {
687 /* Get the primary DOS record */
688 DosRecord = (PVDM_DOS_RECORD)CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
690
691 if (DosRecord->State != VDM_READY) // == VDM_NOT_READY
692 {
693 /* Allocate a new DOS record */
696 sizeof(VDM_DOS_RECORD));
697 if (DosRecord == NULL)
698 {
700 goto Cleanup;
701 }
702
703 /* Remember that the DOS record was allocated here */
704 NewDosRecord = TRUE;
705 }
706 }
707 else
708 {
709 /* Allocate a new DOS record */
712 sizeof(VDM_DOS_RECORD));
713 if (DosRecord == NULL)
714 {
716 goto Cleanup;
717 }
718
719 /* Remember that the DOS record was allocated here */
720 NewDosRecord = TRUE;
721 }
722
723 /* Initialize the DOS record */
724 DosRecord->State = VDM_NOT_READY;
725 DosRecord->ExitCode = 0;
726
727 /* Translate the input structure into a VDM command structure and set it in the DOS record */
728 if (!BaseSrvCopyCommand(CheckVdmRequest, DosRecord))
729 {
730 /* The only possibility is that an allocation failure occurred */
732 goto Cleanup;
733 }
734
735 if (NewDosRecord)
736 {
737 /* Add the DOS record */
738 InsertHeadList(&ConsoleRecord->DosListHead, &DosRecord->Entry);
739 }
740
741 if (!NewConsoleRecord)
742 {
744 if (!NT_SUCCESS(Status)) goto Cleanup;
745
746 /* Return the client event handle */
747 CheckVdmRequest->WaitObjectForParent = DosRecord->ClientEvent;
748 }
749
750 // FIXME: We may notify ONLY if ConsoleRecord->nReEntrancy is > 0
751 // in case NewConsoleRecord == FALSE AND NewDosRecord == TRUE.
752 if (ConsoleRecord->ServerEvent)
753 {
754 /* Signal the session event */
755 NtSetEvent(ConsoleRecord->ServerEvent, NULL);
756 }
757
758 if (NewConsoleRecord)
759 {
760 /* Add the console record */
761 InsertTailList(&VDMConsoleListHead, &ConsoleRecord->Entry);
762 }
763
764 CheckVdmRequest->iTask = ConsoleRecord->SessionId;
765 CheckVdmRequest->VDMState = NewConsoleRecord ? VDM_NOT_LOADED : VDM_READY;
767 }
768 else
769 {
770 // TODO: NOT IMPLEMENTED
773 }
774
775Cleanup:
776 /* Check if it failed */
777 if (!NT_SUCCESS(Status))
778 {
779 /* Free the DOS record if it was allocated here */
780 if (NewDosRecord)
781 {
782 ASSERT(DosRecord != NULL);
783
785 DosRecord->ClientEvent);
786
787 RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
788 DosRecord = NULL;
789 }
790
791 /* Free the console record if it was allocated here */
792 if (NewConsoleRecord)
793 {
794 ASSERT(ConsoleRecord != NULL);
795
796 RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
797 ConsoleRecord = NULL;
798 }
799 }
800
801 /* Leave the critical section */
803
804 return Status;
805}
struct _BASE_API_MESSAGE * PBASE_API_MESSAGE
#define UNIMPLEMENTED
Definition: debug.h:115
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1430
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
CRITICAL_SECTION CriticalSection
Definition: iprtprio.c:40
#define ASSERT(a)
Definition: mode.c:44
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_VDM_DISALLOWED
Definition: ntstatus.h:957
#define VDM_NOT_READY
Definition: vdm.h:47
#define BINARY_TYPE_SEPARATE_WOW
Definition: vdm.h:39
#define VDM_READY
Definition: vdm.h:48
#define VDM_NOT_LOADED
Definition: vdm.h:46
USHORT VDMState
Definition: basemsg.h:147
HANDLE WaitObjectForParent
Definition: basemsg.h:123
HANDLE ConsoleHandle
Definition: basemsg.h:121
ULONG BinaryType
Definition: basemsg.h:122
HANDLE ClientEvent
Definition: vdm.h:40
NTSTATUS BaseSrvGetConsoleRecord(HANDLE ConsoleHandle, PVDM_CONSOLE_RECORD *Record)
Definition: vdm.c:49
NTSTATUS BaseSrvCreatePairWaitHandles(PHANDLE ServerEvent, PHANDLE ClientEvent)
Definition: vdm.c:239
VOID BaseSrvDestroyPairWaitHandles(HANDLE ServerEvent, HANDLE ClientEvent)
Definition: vdm.c:260
BOOLEAN BaseSrvCopyCommand(PBASE_CHECK_VDM CheckVdmRequest, PVDM_DOS_RECORD DosRecord)
Definition: vdm.c:351
ULONG GetNextDosSesId(VOID)
Definition: vdm.c:113
BOOLEAN BaseSrvIsVdmAllowed(VOID)
Definition: vdm.c:142
PVDM_CONSOLE_RECORD BaseSrvCreateConsoleRecord(VOID)
Definition: vdm.c:27
struct _VDM_DOS_RECORD * PVDM_DOS_RECORD

◆ CSR_API() [3/12]

CSR_API ( BaseSrvExitVDM  )

Definition at line 1164 of file vdm.c.

1165{
1167 PBASE_EXIT_VDM ExitVdmRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.ExitVDMRequest;
1169 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
1170 PVDM_DOS_RECORD DosRecord;
1171
1172 CriticalSection = (ExitVdmRequest->iWowTask == 0)
1175
1176 /* Enter the critical section */
1178
1179 if (ExitVdmRequest->iWowTask == 0)
1180 {
1181 /* Get the console record */
1182 Status = BaseSrvGetConsoleRecord(ExitVdmRequest->ConsoleHandle, &ConsoleRecord);
1183 if (!NT_SUCCESS(Status)) goto Cleanup;
1184
1185 if (ConsoleRecord->ServerEvent)
1186 ExitVdmRequest->WaitObjectForVDM = ConsoleRecord->ClientEvent;
1187
1188 // NOTE: The following is the same as in BaseSrvCleanupVDMResources.
1189
1190 if (ConsoleRecord->ServerEvent)
1191 {
1192 NtClose(ConsoleRecord->ServerEvent);
1193 ConsoleRecord->ServerEvent = NULL;
1194 }
1195
1196 /* Cleanup the DOS records */
1197 while (!IsListEmpty(&ConsoleRecord->DosListHead))
1198 {
1199 DosRecord = CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
1201
1202 /* Set the event and close it */
1203 if (DosRecord->ServerEvent)
1204 {
1205 NtSetEvent(DosRecord->ServerEvent, NULL);
1206 NtClose(DosRecord->ServerEvent);
1207 DosRecord->ServerEvent = NULL;
1208 }
1209
1210 /* Remove the DOS entry */
1211 if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
1212 RemoveEntryList(&DosRecord->Entry);
1213 RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
1214 }
1215
1216 /* Remove the console record */
1217 RemoveEntryList(&ConsoleRecord->Entry);
1218 BaseSrvDestroyConsoleRecord(ConsoleRecord);
1219 }
1220 else
1221 {
1222 // TODO: NOT IMPLEMENTED
1225 }
1226
1227Cleanup:
1228 /* Leave the critical section */
1230
1231 return Status;
1232}
HANDLE WaitObjectForVDM
Definition: basemsg.h:198
ULONG iWowTask
Definition: basemsg.h:197
HANDLE ConsoleHandle
Definition: basemsg.h:196

◆ CSR_API() [4/12]

CSR_API ( BaseSrvGetNextVDMCommand  )

Definition at line 933 of file vdm.c.

934{
936 PBASE_GET_NEXT_VDM_COMMAND GetNextVdmCommandRequest =
937 &((PBASE_API_MESSAGE)ApiMessage)->Data.GetNextVDMCommandRequest;
940 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
941 PVDM_DOS_RECORD DosRecord = NULL;
942
943 /* Validate the message buffers */
944 if (!CsrValidateMessageBuffer(ApiMessage,
945 (PVOID*)&GetNextVdmCommandRequest->CmdLine,
946 GetNextVdmCommandRequest->CmdLen,
947 sizeof(*GetNextVdmCommandRequest->CmdLine))
948 || !CsrValidateMessageBuffer(ApiMessage,
949 (PVOID*)&GetNextVdmCommandRequest->AppName,
950 GetNextVdmCommandRequest->AppLen,
951 sizeof(*GetNextVdmCommandRequest->AppName))
952 || !CsrValidateMessageBuffer(ApiMessage,
953 (PVOID*)&GetNextVdmCommandRequest->PifFile,
954 GetNextVdmCommandRequest->PifLen,
955 sizeof(*GetNextVdmCommandRequest->PifFile))
956 || !CsrValidateMessageBuffer(ApiMessage,
957 (PVOID*)&GetNextVdmCommandRequest->CurDirectory,
958 GetNextVdmCommandRequest->CurDirectoryLen,
959 sizeof(*GetNextVdmCommandRequest->CurDirectory))
960 || !CsrValidateMessageBuffer(ApiMessage,
961 (PVOID*)&GetNextVdmCommandRequest->Env,
962 GetNextVdmCommandRequest->EnvLen,
963 sizeof(*GetNextVdmCommandRequest->Env))
964 || !CsrValidateMessageBuffer(ApiMessage,
965 (PVOID*)&GetNextVdmCommandRequest->Desktop,
966 GetNextVdmCommandRequest->DesktopLen,
967 sizeof(*GetNextVdmCommandRequest->Desktop))
968 || !CsrValidateMessageBuffer(ApiMessage,
969 (PVOID*)&GetNextVdmCommandRequest->Title,
970 GetNextVdmCommandRequest->TitleLen,
971 sizeof(*GetNextVdmCommandRequest->Title))
972 || !CsrValidateMessageBuffer(ApiMessage,
973 (PVOID*)&GetNextVdmCommandRequest->Reserved,
974 GetNextVdmCommandRequest->ReservedLen,
975 sizeof(*GetNextVdmCommandRequest->Reserved))
976 || !CsrValidateMessageBuffer(ApiMessage,
977 (PVOID*)&GetNextVdmCommandRequest->StartupInfo,
978 1,
979 sizeof(STARTUPINFOA)))
980 {
982 }
983
984 CriticalSection = (GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW)
987
988 /* Enter the critical section */
990
991 if (GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW)
992 {
993 // TODO: WOW SUPPORT NOT IMPLEMENTED
996 goto Cleanup;
997 }
998 // else if (!(GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW))
999 {
1000 if (GetNextVdmCommandRequest->iTask != 0)
1001 {
1002 /* Get the console record using the task ID */
1003 Status = GetConsoleRecordBySessionId(GetNextVdmCommandRequest->iTask,
1004 &ConsoleRecord);
1005 }
1006 else
1007 {
1008 /* Get the console record using the console handle */
1009 Status = BaseSrvGetConsoleRecord(GetNextVdmCommandRequest->ConsoleHandle,
1010 &ConsoleRecord);
1011 }
1012
1013 /* Make sure we found the console record */
1014 if (!NT_SUCCESS(Status)) goto Cleanup;
1015
1016 /* Return the session ID */
1017 GetNextVdmCommandRequest->iTask = ConsoleRecord->SessionId;
1018 GetNextVdmCommandRequest->WaitObjectForVDM = NULL;
1019
1020 if (GetNextVdmCommandRequest->VDMState & VDM_GET_FIRST_COMMAND)
1021 {
1022 /* Check if the DOS record list is empty */
1023 if (ConsoleRecord->DosListHead.Flink == &ConsoleRecord->DosListHead)
1024 {
1026 goto Cleanup;
1027 }
1028
1029 /* Get the first DOS record */
1030 DosRecord = CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink, VDM_DOS_RECORD, Entry);
1031
1032 /* Make sure its command information is still there */
1033 if (DosRecord->CommandInfo == NULL)
1034 {
1036 goto Cleanup;
1037 }
1038
1039 /* Check if the console handle hasn't been set yet */
1040 if (ConsoleRecord->ConsoleHandle == NULL)
1041 {
1042 /* Set it now */
1043 ConsoleRecord->ConsoleHandle = GetNextVdmCommandRequest->ConsoleHandle;
1044 }
1045
1046 /* Fill the command information */
1047 Status = BaseSrvFillCommandInfo(DosRecord->CommandInfo, GetNextVdmCommandRequest);
1048 goto Cleanup;
1049 }
1050
1051 /* Check if we should set the state of a running DOS record to ready */
1052 if (!(GetNextVdmCommandRequest->VDMState
1054 {
1055 /* Search for a DOS record that is currently running */
1056 for (i = ConsoleRecord->DosListHead.Flink; i != &ConsoleRecord->DosListHead; i = i->Flink)
1057 {
1058 DosRecord = CONTAINING_RECORD(i, VDM_DOS_RECORD, Entry);
1059 if (DosRecord->State == VDM_NOT_READY) break;
1060 }
1061
1062 /* Check if we found any */
1063 if (i == &ConsoleRecord->DosListHead)
1064 {
1066 goto Cleanup;
1067 }
1068
1069 /* Set the exit code */
1070 DosRecord->ExitCode = GetNextVdmCommandRequest->ExitCode;
1071
1072 /* Update the VDM state */
1073 DosRecord->State = VDM_READY;
1074
1075 /* Notify all waiting threads that the task is finished */
1076 NtSetEvent(DosRecord->ServerEvent, NULL);
1077 NtClose(DosRecord->ServerEvent);
1078 DosRecord->ServerEvent = NULL;
1079 }
1080
1081 /* Search for a DOS record that is currently running and has command information */
1082 for (i = ConsoleRecord->DosListHead.Flink; i != &ConsoleRecord->DosListHead; i = i->Flink)
1083 {
1084 DosRecord = CONTAINING_RECORD(i, VDM_DOS_RECORD, Entry);
1085 if ((DosRecord->State == VDM_NOT_READY) && (DosRecord->CommandInfo != NULL)) break;
1086 }
1087
1088 /* Check if we found any */
1089 if (i != &ConsoleRecord->DosListHead)
1090 {
1091 ASSERT(DosRecord->CommandInfo != NULL);
1092
1093 /* Check if the caller only wants environment data */
1094 if (GetNextVdmCommandRequest->VDMState & VDM_GET_ENVIRONMENT)
1095 {
1096 if (GetNextVdmCommandRequest->EnvLen < DosRecord->CommandInfo->EnvLen)
1097 {
1098 /* Not enough space was reserved */
1099 GetNextVdmCommandRequest->EnvLen = DosRecord->CommandInfo->EnvLen;
1101 goto Cleanup;
1102 }
1103
1104 /* Copy the environment data */
1105 RtlMoveMemory(GetNextVdmCommandRequest->Env,
1106 DosRecord->CommandInfo->Env,
1107 DosRecord->CommandInfo->EnvLen);
1108
1109 /* Return the actual size to the caller */
1110 GetNextVdmCommandRequest->EnvLen = DosRecord->CommandInfo->EnvLen;
1111 }
1112 else
1113 {
1114 /* Fill the command information */
1115 Status = BaseSrvFillCommandInfo(DosRecord->CommandInfo, GetNextVdmCommandRequest);
1116 if (!NT_SUCCESS(Status)) goto Cleanup;
1117
1118 /* Free the command information, it's no longer needed */
1119 BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
1120 DosRecord->CommandInfo = NULL;
1121
1122 /* Update the VDM state */
1123 DosRecord->State = VDM_NOT_READY;
1124 }
1125
1127 goto Cleanup;
1128 }
1129 }
1130
1131 GetNextVdmCommandRequest->WaitObjectForVDM = NULL;
1132
1133 /*
1134 * There is no command yet. Prepare for waiting if we asked so,
1135 * and if we were not retrying a request.
1136 */
1137 if (!(GetNextVdmCommandRequest->VDMState & VDM_FLAG_DONT_WAIT) ||
1138 !(GetNextVdmCommandRequest->VDMState & VDM_FLAG_RETRY))
1139 {
1140 if (ConsoleRecord->ServerEvent)
1141 {
1142 /* Reset the event */
1143 NtResetEvent(ConsoleRecord->ServerEvent, NULL);
1144 }
1145 else
1146 {
1147 /* Create a pair of wait handles */
1149 &ConsoleRecord->ClientEvent);
1150 if (!NT_SUCCESS(Status)) goto Cleanup;
1151 }
1152
1153 /* Return the client event handle */
1154 GetNextVdmCommandRequest->WaitObjectForVDM = ConsoleRecord->ClientEvent;
1155 }
1156
1157Cleanup:
1158 /* Leave the critical section */
1160
1161 return Status;
1162}
NTSTATUS NTAPI NtResetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:386
#define VDM_FLAG_RETRY
Definition: vdm.h:56
#define VDM_FLAG_FIRST_TASK
Definition: vdm.h:53
#define VDM_FLAG_DONT_WAIT
Definition: vdm.h:60
#define VDM_GET_ENVIRONMENT
Definition: vdm.h:62
#define VDM_FLAG_WOW
Definition: vdm.h:54
#define VDM_GET_FIRST_COMMAND
Definition: vdm.h:61
#define VDM_FLAG_NESTED_TASK
Definition: vdm.h:59
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
LPSTARTUPINFOA StartupInfo
Definition: basemsg.h:178
NTSTATUS BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo, PBASE_GET_NEXT_VDM_COMMAND Message)
Definition: vdm.c:498
NTSTATUS GetConsoleRecordBySessionId(ULONG TaskId, PVDM_CONSOLE_RECORD *Record)
Definition: vdm.c:94

◆ CSR_API() [5/12]

CSR_API ( BaseSrvGetVDMCurDirs  )

Definition at line 1397 of file vdm.c.

1398{
1400 PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.VDMCurrentDirsRequest;
1401 PVDM_CONSOLE_RECORD ConsoleRecord;
1402
1403 /* Validate the output buffer */
1404 if (!CsrValidateMessageBuffer(ApiMessage,
1405 (PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs,
1406 VDMCurrentDirsRequest->cchCurDirs,
1407 sizeof(*VDMCurrentDirsRequest->lpszzCurDirs)))
1408 {
1410 }
1411
1412 /* Enter the critical section */
1414
1415 /* Find the console record */
1416 Status = BaseSrvGetConsoleRecord(VDMCurrentDirsRequest->ConsoleHandle, &ConsoleRecord);
1417 if (!NT_SUCCESS(Status)) goto Cleanup;
1418
1419 /* Return the actual size of the current directory information */
1420 VDMCurrentDirsRequest->cchCurDirs = ConsoleRecord->CurDirsLength;
1421
1422 /* Check if the buffer is large enough */
1423 if (VDMCurrentDirsRequest->cchCurDirs < ConsoleRecord->CurDirsLength)
1424 {
1426 goto Cleanup;
1427 }
1428
1429 /* Copy the data */
1430 RtlMoveMemory(VDMCurrentDirsRequest->lpszzCurDirs,
1431 ConsoleRecord->CurrentDirs,
1432 ConsoleRecord->CurDirsLength);
1433
1434Cleanup:
1435 /* Leave the critical section */
1437
1438 return Status;
1439}
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69

◆ CSR_API() [6/12]

CSR_API ( BaseSrvGetVDMExitCode  )

Definition at line 1247 of file vdm.c.

1248{
1250 PBASE_GET_VDM_EXIT_CODE GetVDMExitCodeRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.GetVDMExitCodeRequest;
1251 PLIST_ENTRY i = NULL;
1252 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
1253 PVDM_DOS_RECORD DosRecord = NULL;
1254
1255 /* Enter the critical section */
1257
1258 /* Get the console record */
1259 Status = BaseSrvGetConsoleRecord(GetVDMExitCodeRequest->ConsoleHandle, &ConsoleRecord);
1260 if (!NT_SUCCESS(Status)) goto Cleanup;
1261
1262 /* Search for a DOS record that has the same parent process handle */
1263 for (i = ConsoleRecord->DosListHead.Flink; i != &ConsoleRecord->DosListHead; i = i->Flink)
1264 {
1265 DosRecord = CONTAINING_RECORD(i, VDM_DOS_RECORD, Entry);
1266 if (DosRecord->ClientEvent == GetVDMExitCodeRequest->hParent) break;
1267 }
1268
1269 /* Check if no DOS record was found */
1270 if (i == &ConsoleRecord->DosListHead)
1271 {
1273 goto Cleanup;
1274 }
1275
1276 /* Check if this task is still running */
1277 if (DosRecord->State != VDM_READY)
1278 {
1279 GetVDMExitCodeRequest->ExitCode = STATUS_PENDING;
1280 goto Cleanup;
1281 }
1282
1283 /* Return the exit code */
1284 GetVDMExitCodeRequest->ExitCode = DosRecord->ExitCode;
1285
1286 // FIXME: We may just change DosRecord->State to VDM_READY in some cases...
1287
1288 /* Since this is a zombie task record, remove it */
1289 if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
1290 RemoveEntryList(&DosRecord->Entry);
1291 RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
1292
1293Cleanup:
1294 /* Leave the critical section */
1296
1297 return Status;
1298}
#define STATUS_PENDING
Definition: ntstatus.h:82

◆ CSR_API() [7/12]

CSR_API ( BaseSrvIsFirstVDM  )

Definition at line 1234 of file vdm.c.

1235{
1236 PBASE_IS_FIRST_VDM IsFirstVDMRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.IsFirstVDMRequest;
1237
1238 /* Return the result */
1239 IsFirstVDMRequest->FirstVDM = FirstVDM;
1240
1241 /* Clear the first VDM flag */
1242 FirstVDM = FALSE;
1243
1244 return STATUS_SUCCESS;
1245}
BOOLEAN FirstVDM
Definition: vdm.c:20

◆ CSR_API() [8/12]

CSR_API ( BaseSrvRefreshIniFileMapping  )

Definition at line 1453 of file vdm.c.

1454{
1455 DPRINT1("%s not yet implemented\n", __FUNCTION__);
1457}

◆ CSR_API() [9/12]

CSR_API ( BaseSrvRegisterWowExec  )

Definition at line 1447 of file vdm.c.

1448{
1449 DPRINT1("%s not yet implemented\n", __FUNCTION__);
1451}

◆ CSR_API() [10/12]

CSR_API ( BaseSrvSetReenterCount  )

Definition at line 1300 of file vdm.c.

1301{
1303 PBASE_SET_REENTER_COUNT SetReenterCountRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.SetReenterCountRequest;
1304 PVDM_CONSOLE_RECORD ConsoleRecord;
1305
1306 /* Enter the critical section */
1308
1309 /* Get the console record */
1310 Status = BaseSrvGetConsoleRecord(SetReenterCountRequest->ConsoleHandle, &ConsoleRecord);
1311 if (!NT_SUCCESS(Status)) goto Cleanup;
1312
1313 if (SetReenterCountRequest->fIncDec == VDM_INC_REENTER_COUNT)
1314 {
1315 ConsoleRecord->ReenterCount++;
1316 }
1317 else if (SetReenterCountRequest->fIncDec == VDM_DEC_REENTER_COUNT)
1318 {
1319 ConsoleRecord->ReenterCount--;
1320 if (ConsoleRecord->ServerEvent)
1321 NtSetEvent(ConsoleRecord->ServerEvent, NULL);
1322 }
1323 else
1324 {
1326 }
1327
1328Cleanup:
1329 /* Leave the critical section */
1331
1332 return Status;
1333}
#define VDM_INC_REENTER_COUNT
Definition: vdm.h:57
#define VDM_DEC_REENTER_COUNT
Definition: vdm.h:58

◆ CSR_API() [11/12]

CSR_API ( BaseSrvSetVDMCurDirs  )

Definition at line 1335 of file vdm.c.

1336{
1338 PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.VDMCurrentDirsRequest;
1339 PVDM_CONSOLE_RECORD ConsoleRecord;
1340 PCHAR Buffer = NULL;
1341
1342 /* Validate the input buffer */
1343 if (!CsrValidateMessageBuffer(ApiMessage,
1344 (PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs,
1345 VDMCurrentDirsRequest->cchCurDirs,
1346 sizeof(*VDMCurrentDirsRequest->lpszzCurDirs)))
1347 {
1349 }
1350
1351 /* Enter the critical section */
1353
1354 /* Find the console record */
1355 Status = BaseSrvGetConsoleRecord(VDMCurrentDirsRequest->ConsoleHandle, &ConsoleRecord);
1356 if (!NT_SUCCESS(Status)) goto Cleanup;
1357
1358 if (ConsoleRecord->CurrentDirs == NULL)
1359 {
1360 /* Allocate memory for the current directory information */
1363 VDMCurrentDirsRequest->cchCurDirs);
1364 }
1365 else
1366 {
1367 /* Resize the amount of allocated memory */
1370 ConsoleRecord->CurrentDirs,
1371 VDMCurrentDirsRequest->cchCurDirs);
1372 }
1373
1374 if (Buffer == NULL)
1375 {
1376 /* Allocation failed */
1378 goto Cleanup;
1379 }
1380
1381 /* Update the console record */
1382 ConsoleRecord->CurrentDirs = Buffer;
1383 ConsoleRecord->CurDirsLength = VDMCurrentDirsRequest->cchCurDirs;
1384
1385 /* Copy the data */
1386 RtlMoveMemory(ConsoleRecord->CurrentDirs,
1387 VDMCurrentDirsRequest->lpszzCurDirs,
1388 VDMCurrentDirsRequest->cchCurDirs);
1389
1390Cleanup:
1391 /* Leave the critical section */
1393
1394 return Status;
1395}
Definition: bufpool.h:45
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2667
char * PCHAR
Definition: typedefs.h:51

◆ CSR_API() [12/12]

CSR_API ( BaseSrvUpdateVDMEntry  )

Definition at line 807 of file vdm.c.

808{
810 PBASE_UPDATE_VDM_ENTRY UpdateVdmEntryRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.UpdateVDMEntryRequest;
812 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
813 PVDM_DOS_RECORD DosRecord = NULL;
814
815 CriticalSection = (UpdateVdmEntryRequest->BinaryType != BINARY_TYPE_SEPARATE_WOW)
818
819 /* Enter the critical section */
821
822 /* Check if this is a DOS or WOW VDM */
823 if (UpdateVdmEntryRequest->BinaryType != BINARY_TYPE_SEPARATE_WOW)
824 {
825 if (UpdateVdmEntryRequest->iTask != 0)
826 {
827 /* Get the console record using the task ID */
828 Status = GetConsoleRecordBySessionId(UpdateVdmEntryRequest->iTask,
829 &ConsoleRecord);
830 }
831 else
832 {
833 /* Get the console record using the console handle */
834 Status = BaseSrvGetConsoleRecord(UpdateVdmEntryRequest->ConsoleHandle,
835 &ConsoleRecord);
836 }
837
838 if (!NT_SUCCESS(Status)) goto Cleanup;
839
840 /* Get the primary DOS record */
841 DosRecord = (PVDM_DOS_RECORD)CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
843
844 switch (UpdateVdmEntryRequest->EntryIndex)
845 {
846 case VdmEntryUndo:
847 {
848 /* Close the server event handle, the client will close the client handle */
849 NtClose(DosRecord->ServerEvent);
850 DosRecord->ServerEvent = DosRecord->ClientEvent = NULL;
851
852 if (UpdateVdmEntryRequest->VDMCreationState & (VDM_UNDO_PARTIAL | VDM_UNDO_FULL))
853 {
854 /* Remove the DOS record */
855 if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
856 RemoveEntryList(&DosRecord->Entry);
857 RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
858
859 /*
860 * Since this is an undo, if that was the only DOS record the VDM
861 * won't even start, so the console record should be removed too.
862 */
863 if (ConsoleRecord->DosListHead.Flink == &ConsoleRecord->DosListHead)
864 {
865 RemoveEntryList(&ConsoleRecord->Entry);
866 BaseSrvDestroyConsoleRecord(ConsoleRecord);
867 }
868 }
869
870 /* It was successful */
872
873 break;
874 }
875
877 {
878 /* Duplicate the VDM process handle */
880 UpdateVdmEntryRequest->VDMProcessHandle,
882 &ConsoleRecord->ProcessHandle,
883 0,
884 0,
886 if (!NT_SUCCESS(Status)) goto Cleanup;
887
888 //
889 // FIXME! Should we always do the following??
890 //
891
892 /* Create a pair of handles to one event object */
894 &DosRecord->ClientEvent);
895 if (!NT_SUCCESS(Status)) goto Cleanup;
896
897 /* Return the client event handle */
898 UpdateVdmEntryRequest->WaitObjectForParent = DosRecord->ClientEvent;
899
900 break;
901 }
902
904 {
905 // TODO: NOT IMPLEMENTED
906 DPRINT1("BaseSrvUpdateVDMEntry: VdmEntryUpdateControlCHandler not implemented\n");
908
909 break;
910 }
911
912 default:
913 {
914 /* Invalid */
916 }
917 }
918 }
919 else
920 {
921 // TODO: NOT IMPLEMENTED
924 }
925
926Cleanup:
927 /* Leave the critical section */
929
930 return Status;
931}
#define VDM_UNDO_PARTIAL
Definition: vdm.h:27
@ VdmEntryUndo
Definition: vdm.h:19
@ VdmEntryUpdateControlCHandler
Definition: vdm.h:21
@ VdmEntryUpdateProcess
Definition: vdm.h:20
#define VDM_UNDO_FULL
Definition: vdm.h:28
Definition: basemsg.h:151
ULONG BinaryType
Definition: basemsg.h:153
HANDLE WaitObjectForParent
Definition: basemsg.h:156
HANDLE VDMProcessHandle
Definition: basemsg.h:155
USHORT VDMCreationState
Definition: basemsg.h:158
USHORT EntryIndex
Definition: basemsg.h:157
ULONG iTask
Definition: basemsg.h:152
HANDLE ConsoleHandle
Definition: basemsg.h:154

◆ GetConsoleRecordBySessionId()

NTSTATUS GetConsoleRecordBySessionId ( ULONG  TaskId,
PVDM_CONSOLE_RECORD Record 
)

Definition at line 94 of file vdm.c.

95{
97 PVDM_CONSOLE_RECORD CurrentRecord = NULL;
98
99 /* Search for a record that has the same console handle */
100 for (i = VDMConsoleListHead.Flink; i != &VDMConsoleListHead; i = i->Flink)
101 {
102 CurrentRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry);
103 if (CurrentRecord->SessionId == TaskId) break;
104 }
105
106 /* Check if nothing was found */
107 if (i == &VDMConsoleListHead) CurrentRecord = NULL;
108
109 *Record = CurrentRecord;
110 return CurrentRecord ? STATUS_SUCCESS : STATUS_NOT_FOUND;
111}

Referenced by CSR_API().

◆ GetNextDosSesId()

ULONG GetNextDosSesId ( VOID  )

Definition at line 113 of file vdm.c.

114{
117 PVDM_CONSOLE_RECORD CurrentRecord = NULL;
119
120 /* Search for an available session ID */
121 for (SessionId = 1; SessionId != 0; SessionId++)
122 {
123 Found = FALSE;
124
125 /* Check if the ID is already in use */
126 for (i = VDMConsoleListHead.Flink; i != &VDMConsoleListHead; i = i->Flink)
127 {
128 CurrentRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry);
129 if (CurrentRecord->SessionId == SessionId) Found = TRUE;
130 }
131
132 /* If not, we found one */
133 if (!Found) break;
134 }
135
136 ASSERT(SessionId != 0);
137
138 /* Return the session ID */
139 return SessionId;
140}
return Found
Definition: dirsup.c:1270
ULONG SessionId
Definition: dllmain.c:28

Referenced by CSR_API().

Variable Documentation

◆ DosCriticalSection

RTL_CRITICAL_SECTION DosCriticalSection

Definition at line 22 of file vdm.c.

Referenced by BaseInitializeVDM(), BaseSrvCleanupVDMResources(), and CSR_API().

◆ FirstVDM

BOOLEAN FirstVDM = TRUE

Definition at line 20 of file vdm.c.

Referenced by CSR_API().

◆ VDMConsoleListHead

◆ WowCriticalSection

RTL_CRITICAL_SECTION WowCriticalSection

Definition at line 23 of file vdm.c.

Referenced by BaseInitializeVDM(), and CSR_API().