ReactOS 0.4.15-dev-5666-gc548b97
vdm.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Base API Server DLL
4 * FILE: subsystems/win/basesrv/vdm.c
5 * PURPOSE: Virtual DOS Machines (VDM) Support
6 * PROGRAMMERS: Hermes Belusca-Maito (hermes.belusca@sfr.fr)
7 * Aleksandar Andrejevic <theflash AT sdf DOT lonestar DOT org>
8 */
9
10/* INCLUDES *******************************************************************/
11
12#include "basesrv.h"
13#include "vdm.h"
14
15#define NDEBUG
16#include <debug.h>
17
18/* GLOBALS ********************************************************************/
19
24
25/* HELPER FUNCTIONS ***********************************************************/
26
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}
48
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}
70
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
93}
94
96{
98 PVDM_CONSOLE_RECORD CurrentRecord = NULL;
99
100 /* Search for a record that has the same console handle */
101 for (i = VDMConsoleListHead.Flink; i != &VDMConsoleListHead; i = i->Flink)
102 {
103 CurrentRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry);
104 if (CurrentRecord->SessionId == TaskId) break;
105 }
106
107 /* Check if nothing was found */
108 if (i == &VDMConsoleListHead) CurrentRecord = NULL;
109
110 *Record = CurrentRecord;
111 return CurrentRecord ? STATUS_SUCCESS : STATUS_NOT_FOUND;
112}
113
115{
118 PVDM_CONSOLE_RECORD CurrentRecord = NULL;
120
121 /* Search for an available session ID */
122 for (SessionId = 1; SessionId != 0; SessionId++)
123 {
124 Found = FALSE;
125
126 /* Check if the ID is already in use */
127 for (i = VDMConsoleListHead.Flink; i != &VDMConsoleListHead; i = i->Flink)
128 {
129 CurrentRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry);
130 if (CurrentRecord->SessionId == SessionId) Found = TRUE;
131 }
132
133 /* If not, we found one */
134 if (!Found) break;
135 }
136
137 ASSERT(SessionId != 0);
138
139 /* Return the session ID */
140 return SessionId;
141}
142
144{
146 BOOLEAN VdmAllowed = TRUE;
148 UNICODE_STRING KeyName, ValueName, MachineKeyName;
150 UCHAR ValueBuffer[sizeof(KEY_VALUE_PARTIAL_INFORMATION) + sizeof(ULONG)];
152 ULONG ActualSize;
153
154 /* Initialize the unicode strings */
155 RtlInitUnicodeString(&MachineKeyName, L"\\Registry\\Machine");
158
160 &MachineKeyName,
162 NULL,
163 NULL);
164
165 /* Open the local machine key */
167 if (!NT_SUCCESS(Status)) return FALSE;
168
170 &KeyName,
172 RootKey,
173 NULL);
174
175 /* Open the policy key in the local machine hive, if it exists */
177 {
178 /* Read the value, if it's set */
180 &ValueName,
182 ValueInfo,
183 sizeof(ValueBuffer),
184 &ActualSize)))
185 {
186 if (*((PULONG)ValueInfo->Data))
187 {
188 /* The VDM has been disabled in the registry */
189 VdmAllowed = FALSE;
190 }
191 }
192
194 }
195
196 /* Close the local machine key */
198
199 /* If it's disabled system-wide, there's no need to check the user key */
200 if (!VdmAllowed) return FALSE;
201
202 /* Open the current user key of the client */
203 if (!CsrImpersonateClient(NULL)) return VdmAllowed;
206
207 /* If that fails, return the system-wide setting */
208 if (!NT_SUCCESS(Status)) return VdmAllowed;
209
211 &KeyName,
213 RootKey,
214 NULL);
215
216 /* Open the policy key in the current user hive, if it exists */
218 {
219 /* Read the value, if it's set */
221 &ValueName,
223 ValueInfo,
224 sizeof(ValueBuffer),
225 &ActualSize)))
226 {
227 if (*((PULONG)ValueInfo->Data))
228 {
229 /* The VDM has been disabled in the registry */
230 VdmAllowed = FALSE;
231 }
232 }
233
235 }
236
237 return VdmAllowed;
238}
239
241{
243
244 /* Create the event */
246 if (!NT_SUCCESS(Status)) return Status;
247
248 /* Duplicate the event into the client process */
250 *ServerEvent,
251 CsrGetClientThread()->Process->ProcessHandle,
252 ClientEvent,
253 0,
254 0,
256
257 if (!NT_SUCCESS(Status)) NtClose(*ServerEvent);
258 return Status;
259}
260
262{
263 if (ServerEvent) NtClose(ServerEvent);
264 if (ClientEvent)
265 {
266 /* Close the remote handle */
268 ClientEvent,
269 NULL,
270 NULL,
271 0,
272 0,
274 }
275}
276
277/* WOW SUPPORT FUNCTIONS ******************************************************/
278
279/* DOS SUPPORT FUNCTIONS ******************************************************/
280
282{
283 /* Free the allocated structure members */
292
293 /* Free the structure itself */
295}
296
298{
299 ULONG ProcessId = HandleToUlong(CsrProcess->ClientId.UniqueProcess);
300 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
301 PVDM_DOS_RECORD DosRecord;
303
304 /* Enter the critical section */
306
307 /* Search for a record that has the same process handle */
309 while (i != &VDMConsoleListHead)
310 {
311 ConsoleRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry);
312 i = i->Flink;
313
314 if (ConsoleRecord->ProcessId == ProcessId)
315 {
316 if (ConsoleRecord->ServerEvent)
317 {
318 NtClose(ConsoleRecord->ServerEvent);
319 ConsoleRecord->ServerEvent = NULL;
320 }
321
322 /* Cleanup the DOS records */
323 while (!IsListEmpty(&ConsoleRecord->DosListHead))
324 {
325 DosRecord = CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
327
328 /* Set the event and close it */
329 if (DosRecord->ServerEvent)
330 {
331 NtSetEvent(DosRecord->ServerEvent, NULL);
332 NtClose(DosRecord->ServerEvent);
333 DosRecord->ServerEvent = NULL;
334 }
335
336 /* Remove the DOS entry */
337 if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
338 RemoveEntryList(&DosRecord->Entry);
339 RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
340 }
341
342 /* Remove the console record */
343 RemoveEntryList(&ConsoleRecord->Entry);
344 BaseSrvDestroyConsoleRecord(ConsoleRecord);
345 }
346 }
347
348 /* Leave the critical section */
350}
351
353{
356
357 /* Allocate the command information structure */
360 sizeof(VDM_COMMAND_INFO));
361 if (CommandInfo == NULL) return FALSE;
362
363 /* Fill the structure */
364 CommandInfo->TaskId = CheckVdmRequest->iTask;
365 CommandInfo->ExitCode = DosRecord->ExitCode;
366 CommandInfo->CodePage = CheckVdmRequest->CodePage;
367 CommandInfo->StdIn = CheckVdmRequest->StdIn;
368 CommandInfo->StdOut = CheckVdmRequest->StdOut;
369 CommandInfo->StdErr = CheckVdmRequest->StdErr;
370
371 /* Allocate memory for the command line */
374 CheckVdmRequest->CmdLen);
375 if (CommandInfo->CmdLine == NULL) goto Cleanup;
376
377 /* Copy the command line */
378 RtlMoveMemory(CommandInfo->CmdLine, CheckVdmRequest->CmdLine, CheckVdmRequest->CmdLen);
379
380 /* Allocate memory for the application name */
383 CheckVdmRequest->AppLen);
384 if (CommandInfo->AppName == NULL) goto Cleanup;
385
386 /* Copy the application name */
387 RtlMoveMemory(CommandInfo->AppName, CheckVdmRequest->AppName, CheckVdmRequest->AppLen);
388
389 /* Allocate memory for the PIF file name */
390 if (CheckVdmRequest->PifLen != 0)
391 {
394 CheckVdmRequest->PifLen);
395 if (CommandInfo->PifFile == NULL) goto Cleanup;
396
397 /* Copy the PIF file name */
398 RtlMoveMemory(CommandInfo->PifFile, CheckVdmRequest->PifFile, CheckVdmRequest->PifLen);
399 }
400 else CommandInfo->PifFile = NULL;
401
402 /* Allocate memory for the current directory */
403 if (CheckVdmRequest->CurDirectoryLen != 0)
404 {
407 CheckVdmRequest->CurDirectoryLen);
408 if (CommandInfo->CurDirectory == NULL) goto Cleanup;
409
410 /* Copy the current directory */
412 CheckVdmRequest->CurDirectory,
413 CheckVdmRequest->CurDirectoryLen);
414 }
416
417 /* Allocate memory for the environment block */
420 CheckVdmRequest->EnvLen);
421 if (CommandInfo->Env == NULL) goto Cleanup;
422
423 /* Copy the environment block */
424 RtlMoveMemory(CommandInfo->Env, CheckVdmRequest->Env, CheckVdmRequest->EnvLen);
425
426 CommandInfo->EnvLen = CheckVdmRequest->EnvLen;
428 CheckVdmRequest->StartupInfo,
429 sizeof(STARTUPINFOA));
430
431 /* Allocate memory for the desktop */
432 if (CheckVdmRequest->DesktopLen != 0)
433 {
436 CheckVdmRequest->DesktopLen);
437 if (CommandInfo->Desktop == NULL) goto Cleanup;
438
439 /* Copy the desktop name */
440 RtlMoveMemory(CommandInfo->Desktop, CheckVdmRequest->Desktop, CheckVdmRequest->DesktopLen);
441 }
442 else CommandInfo->Desktop = NULL;
443
444 CommandInfo->DesktopLen = CheckVdmRequest->DesktopLen;
445
446 /* Allocate memory for the title */
447 if (CheckVdmRequest->TitleLen != 0)
448 {
451 CheckVdmRequest->TitleLen);
452 if (CommandInfo->Title == NULL) goto Cleanup;
453
454 /* Copy the title */
455 RtlMoveMemory(CommandInfo->Title, CheckVdmRequest->Title, CheckVdmRequest->TitleLen);
456 }
457 else CommandInfo->Title = NULL;
458
459 CommandInfo->TitleLen = CheckVdmRequest->TitleLen;
460
461 /* Allocate memory for the reserved field */
462 if (CheckVdmRequest->ReservedLen != 0)
463 {
466 CheckVdmRequest->ReservedLen);
467 if (CommandInfo->Reserved == NULL) goto Cleanup;
468
469 /* Copy the reserved field */
471 CheckVdmRequest->Reserved,
472 CheckVdmRequest->ReservedLen);
473 }
474 else CommandInfo->Reserved = NULL;
475
476 CommandInfo->ReservedLen = CheckVdmRequest->ReservedLen;
477
478 CommandInfo->CmdLen = CheckVdmRequest->CmdLen;
479 CommandInfo->AppLen = CheckVdmRequest->AppLen;
480 CommandInfo->PifLen = CheckVdmRequest->PifLen;
481 CommandInfo->CurDirectoryLen = CheckVdmRequest->CurDirectoryLen;
482 CommandInfo->VDMState = DosRecord->State;
483 // TODO: Set CommandInfo->CurrentDrive
484 // TODO: Set CommandInfo->ComingFromBat
485
486 /* Set the DOS record's command structure */
487 DosRecord->CommandInfo = CommandInfo;
488
489 /* The operation was successful */
490 Success = TRUE;
491
492Cleanup:
493 /* If it wasn't successful, free the memory */
495
496 return Success;
497}
498
501{
503
504 /* Copy the data */
505 Message->iTask = CommandInfo->TaskId;
506 Message->StdIn = CommandInfo->StdIn;
507 Message->StdOut = CommandInfo->StdOut;
508 Message->StdErr = CommandInfo->StdErr;
509 Message->CodePage = CommandInfo->CodePage;
510 Message->dwCreationFlags = CommandInfo->CreationFlags;
511 Message->ExitCode = CommandInfo->ExitCode;
512 Message->CurrentDrive = CommandInfo->CurrentDrive;
513 Message->VDMState = CommandInfo->VDMState;
514 Message->fComingFromBat = CommandInfo->ComingFromBat;
515
516 if (Message->CmdLen >= CommandInfo->CmdLen)
517 {
518 /* Copy the command line */
520 }
522 Message->CmdLen = CommandInfo->CmdLen;
523
524 if (Message->AppLen >= CommandInfo->AppLen)
525 {
526 /* Copy the application name */
528 }
530 Message->AppLen = CommandInfo->AppLen;
531
532 if (Message->PifLen >= CommandInfo->PifLen)
533 {
534 /* Copy the PIF file name */
536 }
538 Message->PifLen = CommandInfo->PifLen;
539
540 if (Message->CurDirectoryLen >= CommandInfo->CurDirectoryLen)
541 {
542 /* Copy the current directory */
544 }
546 Message->CurDirectoryLen = CommandInfo->CurDirectoryLen;
547
548 if (Message->EnvLen >= CommandInfo->EnvLen)
549 {
550 /* Copy the environment */
552 }
554 Message->EnvLen = CommandInfo->EnvLen;
555
556 /* Copy the startup info */
557 RtlMoveMemory(Message->StartupInfo,
559 sizeof(STARTUPINFOA));
560
561 if (Message->DesktopLen >= CommandInfo->DesktopLen)
562 {
563 /* Copy the desktop name */
565 }
567 Message->DesktopLen = CommandInfo->DesktopLen;
568
569 if (Message->TitleLen >= CommandInfo->TitleLen)
570 {
571 /* Copy the title */
573 }
575 Message->TitleLen = CommandInfo->TitleLen;
576
577 if (Message->ReservedLen >= CommandInfo->ReservedLen)
578 {
579 /* Copy the reserved parameter */
581 }
583 Message->ReservedLen = CommandInfo->ReservedLen;
584
585 return Status;
586}
587
589{
590 /* Initialize the list head */
592
593 /* Initialize the critical sections */
596}
597
598/* PUBLIC SERVER APIS *********************************************************/
599
600CSR_API(BaseSrvCheckVDM)
601{
603 PBASE_CHECK_VDM CheckVdmRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.CheckVDMRequest;
605 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
606 PVDM_DOS_RECORD DosRecord = NULL;
607 BOOLEAN NewConsoleRecord = FALSE;
608 BOOLEAN NewDosRecord = FALSE;
609
610 /* Don't do anything if the VDM has been disabled in the registry */
612
613 /* Validate the message buffers */
614 if (!CsrValidateMessageBuffer(ApiMessage,
615 (PVOID*)&CheckVdmRequest->CmdLine,
616 CheckVdmRequest->CmdLen,
617 sizeof(*CheckVdmRequest->CmdLine))
618 || !CsrValidateMessageBuffer(ApiMessage,
619 (PVOID*)&CheckVdmRequest->AppName,
620 CheckVdmRequest->AppLen,
621 sizeof(*CheckVdmRequest->AppName))
622 || !CsrValidateMessageBuffer(ApiMessage,
623 (PVOID*)&CheckVdmRequest->PifFile,
624 CheckVdmRequest->PifLen,
625 sizeof(*CheckVdmRequest->PifFile))
626 || !CsrValidateMessageBuffer(ApiMessage,
627 (PVOID*)&CheckVdmRequest->CurDirectory,
628 CheckVdmRequest->CurDirectoryLen,
629 sizeof(*CheckVdmRequest->CurDirectory))
630 || !CsrValidateMessageBuffer(ApiMessage,
631 (PVOID*)&CheckVdmRequest->Desktop,
632 CheckVdmRequest->DesktopLen,
633 sizeof(*CheckVdmRequest->Desktop))
634 || !CsrValidateMessageBuffer(ApiMessage,
635 (PVOID*)&CheckVdmRequest->Title,
636 CheckVdmRequest->TitleLen,
637 sizeof(*CheckVdmRequest->Title))
638 || !CsrValidateMessageBuffer(ApiMessage,
639 (PVOID*)&CheckVdmRequest->Reserved,
640 CheckVdmRequest->ReservedLen,
641 sizeof(*CheckVdmRequest->Reserved)))
642 {
644 }
645
649
650 /* Enter the critical section */
652
653 /* Check if this is a DOS or WOW VDM */
654 if (CheckVdmRequest->BinaryType != BINARY_TYPE_SEPARATE_WOW)
655 {
656 /* Get the console record */
658 &ConsoleRecord);
659 if (!NT_SUCCESS(Status))
660 {
661 /* Allocate a new console record */
662 ConsoleRecord = BaseSrvCreateConsoleRecord();
663 if (ConsoleRecord == NULL)
664 {
666 goto Cleanup;
667 }
668
669 /* Initialize the console record */
670 ConsoleRecord->ConsoleHandle = CheckVdmRequest->ConsoleHandle;
671 if (ConsoleRecord->ConsoleHandle == NULL)
672 {
673 /* The parent doesn't have a console, get a new session ID */
674 ConsoleRecord->SessionId = GetNextDosSesId();
675 }
676 else
677 {
678 /* No session ID is needed */
679 ConsoleRecord->SessionId = 0;
680 }
681
682 /* Remember that the console record was allocated here */
683 NewConsoleRecord = TRUE;
684 }
685
686 if (!NewConsoleRecord)
687 {
688 /* Get the primary DOS record */
689 DosRecord = (PVDM_DOS_RECORD)CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
691
692 if (DosRecord->State != VDM_READY) // == VDM_NOT_READY
693 {
694 /* Allocate a new DOS record */
697 sizeof(VDM_DOS_RECORD));
698 if (DosRecord == NULL)
699 {
701 goto Cleanup;
702 }
703
704 /* Remember that the DOS record was allocated here */
705 NewDosRecord = TRUE;
706 }
707 }
708 else
709 {
710 /* Allocate a new DOS record */
713 sizeof(VDM_DOS_RECORD));
714 if (DosRecord == NULL)
715 {
717 goto Cleanup;
718 }
719
720 /* Remember that the DOS record was allocated here */
721 NewDosRecord = TRUE;
722 }
723
724 /* Initialize the DOS record */
725 DosRecord->State = VDM_NOT_READY;
726 DosRecord->ExitCode = 0;
727
728 /* Translate the input structure into a VDM command structure and set it in the DOS record */
729 if (!BaseSrvCopyCommand(CheckVdmRequest, DosRecord))
730 {
731 /* The only possibility is that an allocation failure occurred */
733 goto Cleanup;
734 }
735
736 if (NewDosRecord)
737 {
738 /* Add the DOS record */
739 InsertHeadList(&ConsoleRecord->DosListHead, &DosRecord->Entry);
740 }
741
742 if (!NewConsoleRecord)
743 {
745 if (!NT_SUCCESS(Status)) goto Cleanup;
746
747 /* Return the client event handle */
748 CheckVdmRequest->WaitObjectForParent = DosRecord->ClientEvent;
749 }
750
751 // FIXME: We may notify ONLY if ConsoleRecord->nReEntrancy is > 0
752 // in case NewConsoleRecord == FALSE AND NewDosRecord == TRUE.
753 if (ConsoleRecord->ServerEvent)
754 {
755 /* Signal the session event */
756 NtSetEvent(ConsoleRecord->ServerEvent, NULL);
757 }
758
759 if (NewConsoleRecord)
760 {
761 /* Add the console record */
762 InsertTailList(&VDMConsoleListHead, &ConsoleRecord->Entry);
763 }
764
765 CheckVdmRequest->iTask = ConsoleRecord->SessionId;
766 CheckVdmRequest->VDMState = NewConsoleRecord ? VDM_NOT_LOADED : VDM_READY;
768 }
769 else
770 {
771 // TODO: NOT IMPLEMENTED
774 }
775
776Cleanup:
777 /* Check if it failed */
778 if (!NT_SUCCESS(Status))
779 {
780 /* Free the DOS record if it was allocated here */
781 if (NewDosRecord)
782 {
783 ASSERT(DosRecord != NULL);
784
786 DosRecord->ClientEvent);
787
788 RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
789 DosRecord = NULL;
790 }
791
792 /* Free the console record if it was allocated here */
793 if (NewConsoleRecord)
794 {
795 ASSERT(ConsoleRecord != NULL);
796
797 RtlFreeHeap(BaseSrvHeap, 0, ConsoleRecord);
798 ConsoleRecord = NULL;
799 }
800 }
801
802 /* Leave the critical section */
804
805 return Status;
806}
807
808CSR_API(BaseSrvUpdateVDMEntry)
809{
811 PBASE_UPDATE_VDM_ENTRY UpdateVdmEntryRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.UpdateVDMEntryRequest;
813 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
814 PVDM_DOS_RECORD DosRecord = NULL;
815
816 CriticalSection = (UpdateVdmEntryRequest->BinaryType != BINARY_TYPE_SEPARATE_WOW)
819
820 /* Enter the critical section */
822
823 /* Check if this is a DOS or WOW VDM */
824 if (UpdateVdmEntryRequest->BinaryType != BINARY_TYPE_SEPARATE_WOW)
825 {
826 if (UpdateVdmEntryRequest->iTask != 0)
827 {
828 /* Get the console record using the task ID */
829 Status = GetConsoleRecordBySessionId(UpdateVdmEntryRequest->iTask,
830 &ConsoleRecord);
831 }
832 else
833 {
834 /* Get the console record using the console handle */
835 Status = BaseSrvGetConsoleRecord(UpdateVdmEntryRequest->ConsoleHandle,
836 &ConsoleRecord);
837 }
838
839 if (!NT_SUCCESS(Status)) goto Cleanup;
840
841 /* Get the primary DOS record */
842 DosRecord = (PVDM_DOS_RECORD)CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
844
845 switch (UpdateVdmEntryRequest->EntryIndex)
846 {
847 case VdmEntryUndo:
848 {
849 /* Close the server event handle, the client will close the client handle */
850 NtClose(DosRecord->ServerEvent);
851 DosRecord->ServerEvent = DosRecord->ClientEvent = NULL;
852
853 if (UpdateVdmEntryRequest->VDMCreationState & (VDM_UNDO_PARTIAL | VDM_UNDO_FULL))
854 {
855 /* Remove the DOS record */
856 if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
857 RemoveEntryList(&DosRecord->Entry);
858 RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
859
860 /*
861 * Since this is an undo, if that was the only DOS record the VDM
862 * won't even start, so the console record should be removed too.
863 */
864 if (ConsoleRecord->DosListHead.Flink == &ConsoleRecord->DosListHead)
865 {
866 RemoveEntryList(&ConsoleRecord->Entry);
867 BaseSrvDestroyConsoleRecord(ConsoleRecord);
868 }
869 }
870
871 /* It was successful */
873
874 break;
875 }
876
878 {
879 /* Duplicate the VDM process handle */
881 UpdateVdmEntryRequest->VDMProcessHandle,
883 &ConsoleRecord->ProcessHandle,
884 0,
885 0,
887 if (!NT_SUCCESS(Status)) goto Cleanup;
888
889 //
890 // FIXME! Should we always do the following??
891 //
892
893 /* Create a pair of handles to one event object */
895 &DosRecord->ClientEvent);
896 if (!NT_SUCCESS(Status)) goto Cleanup;
897
898 /* Return the client event handle */
899 UpdateVdmEntryRequest->WaitObjectForParent = DosRecord->ClientEvent;
900
901 break;
902 }
903
905 {
906 // TODO: NOT IMPLEMENTED
907 DPRINT1("BaseSrvUpdateVDMEntry: VdmEntryUpdateControlCHandler not implemented!");
909
910 break;
911 }
912
913 default:
914 {
915 /* Invalid */
917 }
918 }
919 }
920 else
921 {
922 // TODO: NOT IMPLEMENTED
925 }
926
927Cleanup:
928 /* Leave the critical section */
930
931 return Status;
932}
933
934CSR_API(BaseSrvGetNextVDMCommand)
935{
937 PBASE_GET_NEXT_VDM_COMMAND GetNextVdmCommandRequest =
938 &((PBASE_API_MESSAGE)ApiMessage)->Data.GetNextVDMCommandRequest;
941 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
942 PVDM_DOS_RECORD DosRecord = NULL;
943
944 /* Validate the message buffers */
945 if (!CsrValidateMessageBuffer(ApiMessage,
946 (PVOID*)&GetNextVdmCommandRequest->CmdLine,
947 GetNextVdmCommandRequest->CmdLen,
948 sizeof(*GetNextVdmCommandRequest->CmdLine))
949 || !CsrValidateMessageBuffer(ApiMessage,
950 (PVOID*)&GetNextVdmCommandRequest->AppName,
951 GetNextVdmCommandRequest->AppLen,
952 sizeof(*GetNextVdmCommandRequest->AppName))
953 || !CsrValidateMessageBuffer(ApiMessage,
954 (PVOID*)&GetNextVdmCommandRequest->PifFile,
955 GetNextVdmCommandRequest->PifLen,
956 sizeof(*GetNextVdmCommandRequest->PifFile))
957 || !CsrValidateMessageBuffer(ApiMessage,
958 (PVOID*)&GetNextVdmCommandRequest->CurDirectory,
959 GetNextVdmCommandRequest->CurDirectoryLen,
960 sizeof(*GetNextVdmCommandRequest->CurDirectory))
961 || !CsrValidateMessageBuffer(ApiMessage,
962 (PVOID*)&GetNextVdmCommandRequest->Env,
963 GetNextVdmCommandRequest->EnvLen,
964 sizeof(*GetNextVdmCommandRequest->Env))
965 || !CsrValidateMessageBuffer(ApiMessage,
966 (PVOID*)&GetNextVdmCommandRequest->Desktop,
967 GetNextVdmCommandRequest->DesktopLen,
968 sizeof(*GetNextVdmCommandRequest->Desktop))
969 || !CsrValidateMessageBuffer(ApiMessage,
970 (PVOID*)&GetNextVdmCommandRequest->Title,
971 GetNextVdmCommandRequest->TitleLen,
972 sizeof(*GetNextVdmCommandRequest->Title))
973 || !CsrValidateMessageBuffer(ApiMessage,
974 (PVOID*)&GetNextVdmCommandRequest->Reserved,
975 GetNextVdmCommandRequest->ReservedLen,
976 sizeof(*GetNextVdmCommandRequest->Reserved))
977 || !CsrValidateMessageBuffer(ApiMessage,
978 (PVOID*)&GetNextVdmCommandRequest->StartupInfo,
979 1,
980 sizeof(STARTUPINFOA)))
981 {
983 }
984
985 CriticalSection = (GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW)
988
989 /* Enter the critical section */
991
992 if (GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW)
993 {
994 // TODO: WOW SUPPORT NOT IMPLEMENTED
997 goto Cleanup;
998 }
999 // else if (!(GetNextVdmCommandRequest->VDMState & VDM_FLAG_WOW))
1000 {
1001 if (GetNextVdmCommandRequest->iTask != 0)
1002 {
1003 /* Get the console record using the task ID */
1004 Status = GetConsoleRecordBySessionId(GetNextVdmCommandRequest->iTask,
1005 &ConsoleRecord);
1006 }
1007 else
1008 {
1009 /* Get the console record using the console handle */
1010 Status = BaseSrvGetConsoleRecord(GetNextVdmCommandRequest->ConsoleHandle,
1011 &ConsoleRecord);
1012 }
1013
1014 /* Make sure we found the console record */
1015 if (!NT_SUCCESS(Status)) goto Cleanup;
1016
1017 /* Return the session ID */
1018 GetNextVdmCommandRequest->iTask = ConsoleRecord->SessionId;
1019 GetNextVdmCommandRequest->WaitObjectForVDM = NULL;
1020
1021 if (GetNextVdmCommandRequest->VDMState & VDM_GET_FIRST_COMMAND)
1022 {
1023 /* Check if the DOS record list is empty */
1024 if (ConsoleRecord->DosListHead.Flink == &ConsoleRecord->DosListHead)
1025 {
1027 goto Cleanup;
1028 }
1029
1030 /* Get the first DOS record */
1031 DosRecord = CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink, VDM_DOS_RECORD, Entry);
1032
1033 /* Make sure its command information is still there */
1034 if (DosRecord->CommandInfo == NULL)
1035 {
1037 goto Cleanup;
1038 }
1039
1040 /* Check if the console handle hasn't been set yet */
1041 if (ConsoleRecord->ConsoleHandle == NULL)
1042 {
1043 /* Set it now */
1044 ConsoleRecord->ConsoleHandle = GetNextVdmCommandRequest->ConsoleHandle;
1045 }
1046
1047 /* Fill the command information */
1048 Status = BaseSrvFillCommandInfo(DosRecord->CommandInfo, GetNextVdmCommandRequest);
1049 goto Cleanup;
1050 }
1051
1052 /* Check if we should set the state of a running DOS record to ready */
1053 if (!(GetNextVdmCommandRequest->VDMState
1055 {
1056 /* Search for a DOS record that is currently running */
1057 for (i = ConsoleRecord->DosListHead.Flink; i != &ConsoleRecord->DosListHead; i = i->Flink)
1058 {
1059 DosRecord = CONTAINING_RECORD(i, VDM_DOS_RECORD, Entry);
1060 if (DosRecord->State == VDM_NOT_READY) break;
1061 }
1062
1063 /* Check if we found any */
1064 if (i == &ConsoleRecord->DosListHead)
1065 {
1067 goto Cleanup;
1068 }
1069
1070 /* Set the exit code */
1071 DosRecord->ExitCode = GetNextVdmCommandRequest->ExitCode;
1072
1073 /* Update the VDM state */
1074 DosRecord->State = VDM_READY;
1075
1076 /* Notify all waiting threads that the task is finished */
1077 NtSetEvent(DosRecord->ServerEvent, NULL);
1078 NtClose(DosRecord->ServerEvent);
1079 DosRecord->ServerEvent = NULL;
1080 }
1081
1082 /* Search for a DOS record that is currently running and has command information */
1083 for (i = ConsoleRecord->DosListHead.Flink; i != &ConsoleRecord->DosListHead; i = i->Flink)
1084 {
1085 DosRecord = CONTAINING_RECORD(i, VDM_DOS_RECORD, Entry);
1086 if ((DosRecord->State == VDM_NOT_READY) && (DosRecord->CommandInfo != NULL)) break;
1087 }
1088
1089 /* Check if we found any */
1090 if (i != &ConsoleRecord->DosListHead)
1091 {
1092 ASSERT(DosRecord->CommandInfo != NULL);
1093
1094 /* Check if the caller only wants environment data */
1095 if (GetNextVdmCommandRequest->VDMState & VDM_GET_ENVIRONMENT)
1096 {
1097 if (GetNextVdmCommandRequest->EnvLen < DosRecord->CommandInfo->EnvLen)
1098 {
1099 /* Not enough space was reserved */
1100 GetNextVdmCommandRequest->EnvLen = DosRecord->CommandInfo->EnvLen;
1102 goto Cleanup;
1103 }
1104
1105 /* Copy the environment data */
1106 RtlMoveMemory(GetNextVdmCommandRequest->Env,
1107 DosRecord->CommandInfo->Env,
1108 DosRecord->CommandInfo->EnvLen);
1109
1110 /* Return the actual size to the caller */
1111 GetNextVdmCommandRequest->EnvLen = DosRecord->CommandInfo->EnvLen;
1112 }
1113 else
1114 {
1115 /* Fill the command information */
1116 Status = BaseSrvFillCommandInfo(DosRecord->CommandInfo, GetNextVdmCommandRequest);
1117 if (!NT_SUCCESS(Status)) goto Cleanup;
1118
1119 /* Free the command information, it's no longer needed */
1120 BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
1121 DosRecord->CommandInfo = NULL;
1122
1123 /* Update the VDM state */
1124 DosRecord->State = VDM_NOT_READY;
1125 }
1126
1128 goto Cleanup;
1129 }
1130 }
1131
1132 GetNextVdmCommandRequest->WaitObjectForVDM = NULL;
1133
1134 /*
1135 * There is no command yet. Prepare for waiting if we asked so,
1136 * and if we were not retrying a request.
1137 */
1138 if (!(GetNextVdmCommandRequest->VDMState & VDM_FLAG_DONT_WAIT) ||
1139 !(GetNextVdmCommandRequest->VDMState & VDM_FLAG_RETRY))
1140 {
1141 if (ConsoleRecord->ServerEvent)
1142 {
1143 /* Reset the event */
1144 NtResetEvent(ConsoleRecord->ServerEvent, NULL);
1145 }
1146 else
1147 {
1148 /* Create a pair of wait handles */
1150 &ConsoleRecord->ClientEvent);
1151 if (!NT_SUCCESS(Status)) goto Cleanup;
1152 }
1153
1154 /* Return the client event handle */
1155 GetNextVdmCommandRequest->WaitObjectForVDM = ConsoleRecord->ClientEvent;
1156 }
1157
1158Cleanup:
1159 /* Leave the critical section */
1161
1162 return Status;
1163}
1164
1165CSR_API(BaseSrvExitVDM)
1166{
1168 PBASE_EXIT_VDM ExitVdmRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.ExitVDMRequest;
1170 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
1171 PVDM_DOS_RECORD DosRecord;
1172
1173 CriticalSection = (ExitVdmRequest->iWowTask == 0)
1176
1177 /* Enter the critical section */
1179
1180 if (ExitVdmRequest->iWowTask == 0)
1181 {
1182 /* Get the console record */
1183 Status = BaseSrvGetConsoleRecord(ExitVdmRequest->ConsoleHandle, &ConsoleRecord);
1184 if (!NT_SUCCESS(Status)) goto Cleanup;
1185
1186 if (ConsoleRecord->ServerEvent)
1187 ExitVdmRequest->WaitObjectForVDM = ConsoleRecord->ClientEvent;
1188
1189 // NOTE: The following is the same as in BaseSrvCleanupVDMResources.
1190
1191 if (ConsoleRecord->ServerEvent)
1192 {
1193 NtClose(ConsoleRecord->ServerEvent);
1194 ConsoleRecord->ServerEvent = NULL;
1195 }
1196
1197 /* Cleanup the DOS records */
1198 while (!IsListEmpty(&ConsoleRecord->DosListHead))
1199 {
1200 DosRecord = CONTAINING_RECORD(ConsoleRecord->DosListHead.Flink,
1202
1203 /* Set the event and close it */
1204 if (DosRecord->ServerEvent)
1205 {
1206 NtSetEvent(DosRecord->ServerEvent, NULL);
1207 NtClose(DosRecord->ServerEvent);
1208 DosRecord->ServerEvent = NULL;
1209 }
1210
1211 /* Remove the DOS entry */
1212 if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
1213 RemoveEntryList(&DosRecord->Entry);
1214 RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
1215 }
1216
1217 /* Remove the console record */
1218 RemoveEntryList(&ConsoleRecord->Entry);
1219 BaseSrvDestroyConsoleRecord(ConsoleRecord);
1220 }
1221 else
1222 {
1223 // TODO: NOT IMPLEMENTED
1226 }
1227
1228Cleanup:
1229 /* Leave the critical section */
1231
1232 return Status;
1233}
1234
1235CSR_API(BaseSrvIsFirstVDM)
1236{
1237 PBASE_IS_FIRST_VDM IsFirstVDMRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.IsFirstVDMRequest;
1238
1239 /* Return the result */
1240 IsFirstVDMRequest->FirstVDM = FirstVDM;
1241
1242 /* Clear the first VDM flag */
1243 FirstVDM = FALSE;
1244
1245 return STATUS_SUCCESS;
1246}
1247
1248CSR_API(BaseSrvGetVDMExitCode)
1249{
1251 PBASE_GET_VDM_EXIT_CODE GetVDMExitCodeRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.GetVDMExitCodeRequest;
1252 PLIST_ENTRY i = NULL;
1253 PVDM_CONSOLE_RECORD ConsoleRecord = NULL;
1254 PVDM_DOS_RECORD DosRecord = NULL;
1255
1256 /* Enter the critical section */
1258
1259 /* Get the console record */
1260 Status = BaseSrvGetConsoleRecord(GetVDMExitCodeRequest->ConsoleHandle, &ConsoleRecord);
1261 if (!NT_SUCCESS(Status)) goto Cleanup;
1262
1263 /* Search for a DOS record that has the same parent process handle */
1264 for (i = ConsoleRecord->DosListHead.Flink; i != &ConsoleRecord->DosListHead; i = i->Flink)
1265 {
1266 DosRecord = CONTAINING_RECORD(i, VDM_DOS_RECORD, Entry);
1267 if (DosRecord->ClientEvent == GetVDMExitCodeRequest->hParent) break;
1268 }
1269
1270 /* Check if no DOS record was found */
1271 if (i == &ConsoleRecord->DosListHead)
1272 {
1274 goto Cleanup;
1275 }
1276
1277 /* Check if this task is still running */
1278 if (DosRecord->State != VDM_READY)
1279 {
1280 GetVDMExitCodeRequest->ExitCode = STATUS_PENDING;
1281 goto Cleanup;
1282 }
1283
1284 /* Return the exit code */
1285 GetVDMExitCodeRequest->ExitCode = DosRecord->ExitCode;
1286
1287 // FIXME: We may just change DosRecord->State to VDM_READY in some cases...
1288
1289 /* Since this is a zombie task record, remove it */
1290 if (DosRecord->CommandInfo) BaseSrvFreeVDMInfo(DosRecord->CommandInfo);
1291 RemoveEntryList(&DosRecord->Entry);
1292 RtlFreeHeap(BaseSrvHeap, 0, DosRecord);
1293
1294Cleanup:
1295 /* Leave the critical section */
1297
1298 return Status;
1299}
1300
1301CSR_API(BaseSrvSetReenterCount)
1302{
1304 PBASE_SET_REENTER_COUNT SetReenterCountRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.SetReenterCountRequest;
1305 PVDM_CONSOLE_RECORD ConsoleRecord;
1306
1307 /* Enter the critical section */
1309
1310 /* Get the console record */
1311 Status = BaseSrvGetConsoleRecord(SetReenterCountRequest->ConsoleHandle, &ConsoleRecord);
1312 if (!NT_SUCCESS(Status)) goto Cleanup;
1313
1314 if (SetReenterCountRequest->fIncDec == VDM_INC_REENTER_COUNT)
1315 {
1316 ConsoleRecord->ReenterCount++;
1317 }
1318 else if (SetReenterCountRequest->fIncDec == VDM_DEC_REENTER_COUNT)
1319 {
1320 ConsoleRecord->ReenterCount--;
1321 if (ConsoleRecord->ServerEvent)
1322 NtSetEvent(ConsoleRecord->ServerEvent, NULL);
1323 }
1324 else
1325 {
1327 }
1328
1329Cleanup:
1330 /* Leave the critical section */
1332
1333 return Status;
1334}
1335
1336CSR_API(BaseSrvSetVDMCurDirs)
1337{
1339 PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.VDMCurrentDirsRequest;
1340 PVDM_CONSOLE_RECORD ConsoleRecord;
1341 PCHAR Buffer = NULL;
1342
1343 /* Validate the input buffer */
1344 if (!CsrValidateMessageBuffer(ApiMessage,
1345 (PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs,
1346 VDMCurrentDirsRequest->cchCurDirs,
1347 sizeof(*VDMCurrentDirsRequest->lpszzCurDirs)))
1348 {
1350 }
1351
1352 /* Enter the critical section */
1354
1355 /* Find the console record */
1356 Status = BaseSrvGetConsoleRecord(VDMCurrentDirsRequest->ConsoleHandle, &ConsoleRecord);
1357 if (!NT_SUCCESS(Status)) goto Cleanup;
1358
1359 if (ConsoleRecord->CurrentDirs == NULL)
1360 {
1361 /* Allocate memory for the current directory information */
1364 VDMCurrentDirsRequest->cchCurDirs);
1365 }
1366 else
1367 {
1368 /* Resize the amount of allocated memory */
1371 ConsoleRecord->CurrentDirs,
1372 VDMCurrentDirsRequest->cchCurDirs);
1373 }
1374
1375 if (Buffer == NULL)
1376 {
1377 /* Allocation failed */
1379 goto Cleanup;
1380 }
1381
1382 /* Update the console record */
1383 ConsoleRecord->CurrentDirs = Buffer;
1384 ConsoleRecord->CurDirsLength = VDMCurrentDirsRequest->cchCurDirs;
1385
1386 /* Copy the data */
1387 RtlMoveMemory(ConsoleRecord->CurrentDirs,
1388 VDMCurrentDirsRequest->lpszzCurDirs,
1389 VDMCurrentDirsRequest->cchCurDirs);
1390
1391Cleanup:
1392 /* Leave the critical section */
1394
1395 return Status;
1396}
1397
1398CSR_API(BaseSrvGetVDMCurDirs)
1399{
1401 PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &((PBASE_API_MESSAGE)ApiMessage)->Data.VDMCurrentDirsRequest;
1402 PVDM_CONSOLE_RECORD ConsoleRecord;
1403
1404 /* Validate the output buffer */
1405 if (!CsrValidateMessageBuffer(ApiMessage,
1406 (PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs,
1407 VDMCurrentDirsRequest->cchCurDirs,
1408 sizeof(*VDMCurrentDirsRequest->lpszzCurDirs)))
1409 {
1411 }
1412
1413 /* Enter the critical section */
1415
1416 /* Find the console record */
1417 Status = BaseSrvGetConsoleRecord(VDMCurrentDirsRequest->ConsoleHandle, &ConsoleRecord);
1418 if (!NT_SUCCESS(Status)) goto Cleanup;
1419
1420 /* Return the actual size of the current directory information */
1421 VDMCurrentDirsRequest->cchCurDirs = ConsoleRecord->CurDirsLength;
1422
1423 /* Check if the buffer is large enough */
1424 if (VDMCurrentDirsRequest->cchCurDirs < ConsoleRecord->CurDirsLength)
1425 {
1427 goto Cleanup;
1428 }
1429
1430 /* Copy the data */
1431 RtlMoveMemory(VDMCurrentDirsRequest->lpszzCurDirs,
1432 ConsoleRecord->CurrentDirs,
1433 ConsoleRecord->CurDirsLength);
1434
1435Cleanup:
1436 /* Leave the critical section */
1438
1439 return Status;
1440}
1441
1442CSR_API(BaseSrvBatNotification)
1443{
1444 DPRINT1("%s not yet implemented\n", __FUNCTION__);
1446}
1447
1448CSR_API(BaseSrvRegisterWowExec)
1449{
1450 DPRINT1("%s not yet implemented\n", __FUNCTION__);
1452}
1453
1454CSR_API(BaseSrvRefreshIniFileMapping)
1455{
1456 DPRINT1("%s not yet implemented\n", __FUNCTION__);
1458}
1459
1460/* EOF */
unsigned char BOOLEAN
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
struct _BASE_API_MESSAGE * PBASE_API_MESSAGE
HANDLE BaseSrvHeap
Definition: init.c:29
#define HandleToUlong(h)
Definition: basetsd.h:79
#define UNIMPLEMENTED
Definition: debug.h:115
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
return Found
Definition: dirsup.c:1270
Definition: bufpool.h:45
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1430
#define CsrGetClientThread()
Definition: csrsrv.h:77
BOOLEAN NTAPI CsrImpersonateClient(IN PCSR_THREAD CsrThread)
Definition: procsup.c:932
#define CSR_API(n)
Definition: csrsrv.h:176
BOOLEAN NTAPI CsrRevertToSelf(VOID)
Definition: procsup.c:1057
static VDM_COMMAND_INFO CommandInfo
Definition: dem.c:246
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
ULONG SessionId
Definition: dllmain.c:28
static const WCHAR Message[]
Definition: register.c:74
static const WCHAR Cleanup[]
Definition: register.c:80
#define __FUNCTION__
Definition: types.h:112
#define RemoveEntryList(Entry)
Definition: env_spec_w32.h:986
#define InsertTailList(ListHead, Entry)
#define InsertHeadList(ListHead, Entry)
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
@ Success
Definition: eventcreate.c:712
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2711
_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
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
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2667
CRITICAL_SECTION CriticalSection
Definition: iprtprio.c:40
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
unsigned int * PULONG
Definition: retypes.h:1
signed char * PCHAR
Definition: retypes.h:7
unsigned int ULONG
Definition: retypes.h:1
#define ASSERT(a)
Definition: mode.c:44
#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
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:153
NTSYSAPI NTSTATUS NTAPI RtlOpenCurrentUser(_In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE KeyHandle)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
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)
#define NtCurrentProcess()
Definition: nt_native.h:1657
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
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
@ NotificationEvent
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:455
NTSTATUS NTAPI NtResetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:386
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
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_PENDING
Definition: ntstatus.h:82
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_VDM_DISALLOWED
Definition: ntstatus.h:957
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:239
#define L(x)
Definition: ntvdm.h:50
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
struct VDM_COMMAND_INFO * PVDM_COMMAND_INFO
#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_UNDO_PARTIAL
Definition: vdm.h:27
#define VDM_INC_REENTER_COUNT
Definition: vdm.h:57
#define VDM_NOT_READY
Definition: vdm.h:47
#define BINARY_TYPE_SEPARATE_WOW
Definition: vdm.h:39
#define VDM_GET_ENVIRONMENT
Definition: vdm.h:62
@ VdmEntryUndo
Definition: vdm.h:19
@ VdmEntryUpdateControlCHandler
Definition: vdm.h:21
@ VdmEntryUpdateProcess
Definition: vdm.h:20
#define VDM_DEC_REENTER_COUNT
Definition: vdm.h:58
#define VDM_UNDO_FULL
Definition: vdm.h:28
#define VDM_FLAG_WOW
Definition: vdm.h:54
#define VDM_READY
Definition: vdm.h:48
#define VDM_NOT_LOADED
Definition: vdm.h:46
#define VDM_GET_FIRST_COMMAND
Definition: vdm.h:61
#define VDM_FLAG_NESTED_TASK
Definition: vdm.h:59
static PMEMKEY RootKey
Definition: registry.c:55
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_NOT_FOUND
Definition: shellext.h:72
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:66
base of all file and directory entries
Definition: entries.h:83
LPSTR CmdLine
Definition: vdm.h:77
HANDLE StdOut
Definition: vdm.h:75
STARTUPINFOA StartupInfo
Definition: vdm.h:83
BOOLEAN ComingFromBat
Definition: vdm.h:96
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
USHORT CurrentDrive
Definition: vdm.h:95
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 CreationFlags
Definition: vdm.h:71
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
USHORT VDMState
Definition: basemsg.h:147
HANDLE StdOut
Definition: basemsg.h:125
HANDLE WaitObjectForParent
Definition: basemsg.h:123
PCHAR PifFile
Definition: basemsg.h:131
HANDLE StdErr
Definition: basemsg.h:126
ULONG ReservedLen
Definition: basemsg.h:141
HANDLE ConsoleHandle
Definition: basemsg.h:121
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
ULONG BinaryType
Definition: basemsg.h:122
PCHAR CurDirectory
Definition: basemsg.h:132
USHORT CmdLen
Definition: basemsg.h:142
USHORT AppLen
Definition: basemsg.h:143
HANDLE WaitObjectForVDM
Definition: basemsg.h:198
ULONG iWowTask
Definition: basemsg.h:197
HANDLE ConsoleHandle
Definition: basemsg.h:196
LPSTARTUPINFOA StartupInfo
Definition: basemsg.h:178
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
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
HANDLE ServerEvent
Definition: vdm.h:24
HANDLE ProcessHandle
Definition: vdm.h:23
ULONG SessionId
Definition: vdm.h:30
HANDLE ConsoleHandle
Definition: vdm.h:22
LIST_ENTRY Entry
Definition: vdm.h:21
PCHAR CurrentDirs
Definition: vdm.h:28
LIST_ENTRY DosListHead
Definition: vdm.h:31
ULONG CurDirsLength
Definition: vdm.h:29
ULONG ReenterCount
Definition: vdm.h:27
ULONG ProcessId
Definition: vdm.h:26
HANDLE ClientEvent
Definition: vdm.h:25
HANDLE ClientEvent
Definition: vdm.h:40
HANDLE ServerEvent
Definition: vdm.h:39
ULONG ExitCode
Definition: vdm.h:38
LIST_ENTRY Entry
Definition: vdm.h:36
USHORT State
Definition: vdm.h:37
PVDM_COMMAND_INFO CommandInfo
Definition: vdm.h:41
NTSTATUS BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo, PBASE_GET_NEXT_VDM_COMMAND Message)
Definition: vdm.c:499
LIST_ENTRY VDMConsoleListHead
Definition: vdm.c:21
RTL_CRITICAL_SECTION DosCriticalSection
Definition: vdm.c:22
VOID BaseSrvCleanupVDMResources(IN PCSR_PROCESS CsrProcess)
Definition: vdm.c:297
VOID BaseSrvDestroyConsoleRecord(PVDM_CONSOLE_RECORD ConsoleRecord)
Definition: vdm.c:71
NTSTATUS BaseSrvGetConsoleRecord(HANDLE ConsoleHandle, PVDM_CONSOLE_RECORD *Record)
Definition: vdm.c:49
NTSTATUS BaseSrvCreatePairWaitHandles(PHANDLE ServerEvent, PHANDLE ClientEvent)
Definition: vdm.c:240
VOID BaseSrvDestroyPairWaitHandles(HANDLE ServerEvent, HANDLE ClientEvent)
Definition: vdm.c:261
BOOLEAN FirstVDM
Definition: vdm.c:20
VOID BaseInitializeVDM(VOID)
Definition: vdm.c:588
BOOLEAN BaseSrvCopyCommand(PBASE_CHECK_VDM CheckVdmRequest, PVDM_DOS_RECORD DosRecord)
Definition: vdm.c:352
ULONG GetNextDosSesId(VOID)
Definition: vdm.c:114
NTSTATUS GetConsoleRecordBySessionId(ULONG TaskId, PVDM_CONSOLE_RECORD *Record)
Definition: vdm.c:95
VOID BaseSrvFreeVDMInfo(PVDM_COMMAND_INFO CommandInfo)
Definition: vdm.c:281
RTL_CRITICAL_SECTION WowCriticalSection
Definition: vdm.c:23
BOOLEAN BaseSrvIsVdmAllowed(VOID)
Definition: vdm.c:143
PVDM_CONSOLE_RECORD BaseSrvCreateConsoleRecord(VOID)
Definition: vdm.c:27
#define VDM_POLICY_KEY_NAME
Definition: vdm.h:16
struct _VDM_DOS_RECORD * PVDM_DOS_RECORD
#define VDM_DISALLOWED_VALUE_NAME
Definition: vdm.h:17
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
PKPROCESS CsrProcess
Definition: videoprt.c:39
_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
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:256
#define DUPLICATE_SAME_ACCESS
#define DUPLICATE_CLOSE_SOURCE
unsigned char UCHAR
Definition: xmlstorage.h:181