ReactOS  0.4.14-dev-77-gd9e7c48
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 {
51  PLIST_ENTRY i;
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  {
60  CurrentRecord = CONTAINING_RECORD(i, VDM_CONSOLE_RECORD, Entry);
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 {
97  PLIST_ENTRY i;
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 {
117  PLIST_ENTRY i;
118  PVDM_CONSOLE_RECORD CurrentRecord = NULL;
119  BOOLEAN Found;
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 */
197  NtClose(RootKey);
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;
205  CsrRevertToSelf();
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 */
267  NtDuplicateObject(CsrGetClientThread()->Process->ProcessHandle,
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;
302  PLIST_ENTRY i;
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  }
415  else CommandInfo->CurDirectory = NULL;
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 
492 Cleanup:
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 
600 CSR_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 
646  CriticalSection = (CheckVdmRequest->BinaryType != BINARY_TYPE_SEPARATE_WOW)
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 */
657  Status = BaseSrvGetConsoleRecord(CheckVdmRequest->ConsoleHandle,
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  {
744  Status = BaseSrvCreatePairWaitHandles(&DosRecord->ServerEvent, &DosRecord->ClientEvent);
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 
776 Cleanup:
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 
808 CSR_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 
927 Cleanup:
928  /* Leave the critical section */
930 
931  return Status;
932 }
933 
934 CSR_API(BaseSrvGetNextVDMCommand)
935 {
937  PBASE_GET_NEXT_VDM_COMMAND GetNextVdmCommandRequest =
938  &((PBASE_API_MESSAGE)ApiMessage)->Data.GetNextVDMCommandRequest;
940  PLIST_ENTRY i = NULL;
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 
1158 Cleanup:
1159  /* Leave the critical section */
1161 
1162  return Status;
1163 }
1164 
1165 CSR_API(BaseSrvExitVDM)
1166 {
1167  NTSTATUS Status;
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)
1175  : &WowCriticalSection;
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
1224  UNIMPLEMENTED;
1226  }
1227 
1228 Cleanup:
1229  /* Leave the critical section */
1231 
1232  return Status;
1233 }
1234 
1235 CSR_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 
1248 CSR_API(BaseSrvGetVDMExitCode)
1249 {
1250  NTSTATUS Status;
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 
1294 Cleanup:
1295  /* Leave the critical section */
1297 
1298  return Status;
1299 }
1300 
1301 CSR_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 
1329 Cleanup:
1330  /* Leave the critical section */
1332 
1333  return Status;
1334 }
1335 
1336 CSR_API(BaseSrvSetVDMCurDirs)
1337 {
1338  NTSTATUS Status;
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  {
1349  return STATUS_INVALID_PARAMETER;
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 
1391 Cleanup:
1392  /* Leave the critical section */
1394 
1395  return Status;
1396 }
1397 
1398 CSR_API(BaseSrvGetVDMCurDirs)
1399 {
1400  NTSTATUS Status;
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  {
1410  return STATUS_INVALID_PARAMETER;
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 
1435 Cleanup:
1436  /* Leave the critical section */
1438 
1439  return Status;
1440 }
1441 
1442 CSR_API(BaseSrvBatNotification)
1443 {
1444  DPRINT1("%s not yet implemented\n", __FUNCTION__);
1445  return STATUS_NOT_IMPLEMENTED;
1446 }
1447 
1448 CSR_API(BaseSrvRegisterWowExec)
1449 {
1450  DPRINT1("%s not yet implemented\n", __FUNCTION__);
1451  return STATUS_NOT_IMPLEMENTED;
1452 }
1453 
1454 CSR_API(BaseSrvRefreshIniFileMapping)
1455 {
1456  DPRINT1("%s not yet implemented\n", __FUNCTION__);
1457  return STATUS_NOT_IMPLEMENTED;
1458 }
1459 
1460 /* EOF */
signed char * PCHAR
Definition: retypes.h:7
LPSTR Desktop
Definition: vdm.h:84
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING KeyName
Definition: ndis.h:4711
HANDLE StdOut
Definition: basemsg.h:125
#define IN
Definition: typedefs.h:38
#define DUPLICATE_CLOSE_SOURCE
#define CsrGetClientThread()
Definition: csrsrv.h:77
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2697
#define TRUE
Definition: types.h:120
ULONG DesktopLen
Definition: vdm.h:85
USHORT State
Definition: vdm.h:37
ULONG ExitCode
Definition: vdm.h:72
HANDLE WaitObjectForVDM
Definition: basemsg.h:198
#define VDM_POLICY_KEY_NAME
Definition: vdm.h:16
NTSTATUS BaseSrvGetConsoleRecord(HANDLE ConsoleHandle, PVDM_CONSOLE_RECORD *Record)
Definition: vdm.c:49
PCHAR AppName
Definition: basemsg.h:130
static PMEMKEY RootKey
Definition: registry.c:55
HANDLE ClientEvent
Definition: vdm.h:25
USHORT CurrentDrive
Definition: vdm.h:95
#define VDM_FLAG_WOW
Definition: vdm.h:54
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4711
#define STATUS_NOT_IMPLEMENTED
Definition: ntstatus.h:225
Definition: basemsg.h:150
LPSTR CmdLine
Definition: vdm.h:77
static VDM_COMMAND_INFO CommandInfo
Definition: dem.c:246
PCHAR CmdLine
Definition: basemsg.h:129
struct _VDM_DOS_RECORD * PVDM_DOS_RECORD
HANDLE StdErr
Definition: vdm.h:76
#define KEY_READ
Definition: nt_native.h:1023
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
FORCEINLINE VOID InsertHeadList(_Inout_ PLIST_ENTRY ListHead, _Inout_ __drv_aliasesMem PLIST_ENTRY Entry)
Definition: rtlfuncs.h:201
ULONG DesktopLen
Definition: basemsg.h:137
ULONG ReenterCount
Definition: vdm.h:27
ULONG SessionId
Definition: dllmain.c:28
LONG NTSTATUS
Definition: precomp.h:26
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:606
ULONG CurDirsLength
Definition: vdm.h:29
#define HandleToUlong(h)
Definition: basetsd.h:79
BOOLEAN NTAPI CsrValidateMessageBuffer(IN PCSR_API_MESSAGE ApiMessage, IN PVOID *Buffer, IN ULONG ElementCount, IN ULONG ElementSize)
Definition: api.c:1315
PCHAR CurDirectory
Definition: basemsg.h:132
BOOLEAN NTAPI CsrRevertToSelf(VOID)
Definition: procsup.c:1048
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:100
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
USHORT PifLen
Definition: vdm.h:92
USHORT PifLen
Definition: basemsg.h:144
VOID BaseSrvFreeVDMInfo(PVDM_COMMAND_INFO CommandInfo)
Definition: vdm.c:281
#define InsertTailList(ListHead, Entry)
USHORT CmdLen
Definition: vdm.h:90
NTSYSAPI PVOID WINAPI RtlReAllocateHeap(HANDLE, ULONG, PVOID, SIZE_T)
Definition: heap.c:2561
#define STATUS_VDM_DISALLOWED
Definition: ntstatus.h:943
HANDLE ServerEvent
Definition: vdm.h:39
_Must_inspect_result_ FORCEINLINE BOOLEAN IsListEmpty(_In_ const LIST_ENTRY *ListHead)
Definition: rtlfuncs.h:57
NTSTATUS NTAPI NtResetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:389
NTSTATUS BaseSrvFillCommandInfo(PVDM_COMMAND_INFO CommandInfo, PBASE_GET_NEXT_VDM_COMMAND Message)
Definition: vdm.c:499
ULONG BinaryType
Definition: basemsg.h:153
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:64
#define VDM_GET_ENVIRONMENT
Definition: vdm.h:62
BOOLEAN ComingFromBat
Definition: vdm.h:96
ULONG TitleLen
Definition: basemsg.h:139
FORCEINLINE BOOLEAN RemoveEntryList(_In_ PLIST_ENTRY Entry)
Definition: rtlfuncs.h:105
USHORT CurDirectoryLen
Definition: vdm.h:93
#define VDM_READY
Definition: vdm.h:48
_In_ PUNICODE_STRING ValueName
Definition: cmfuncs.h:264
_In_ struct _KBUGCHECK_REASON_CALLBACK_RECORD * Record
Definition: ketypes.h:256
HANDLE ProcessHandle
Definition: vdm.h:23
BOOLEAN FirstVDM
Definition: vdm.c:20
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 DUPLICATE_SAME_ACCESS
ULONG ExitCode
Definition: vdm.h:38
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
RTL_CRITICAL_SECTION WowCriticalSection
Definition: vdm.c:23
#define EVENT_ALL_ACCESS
Definition: isotest.c:82
NTSTATUS GetConsoleRecordBySessionId(ULONG TaskId, PVDM_CONSOLE_RECORD *Record)
Definition: vdm.c:95
LPVOID Reserved
Definition: vdm.h:88
HANDLE WaitObjectForParent
Definition: basemsg.h:123
HANDLE StdErr
Definition: basemsg.h:126
CRITICAL_SECTION CriticalSection
Definition: iprtprio.c:40
struct _BASE_API_MESSAGE * PBASE_API_MESSAGE
HANDLE StdIn
Definition: vdm.h:74
#define VDM_GET_FIRST_COMMAND
Definition: vdm.h:61
unsigned char BOOLEAN
smooth NULL
Definition: ftsmooth.c:416
#define VDM_FLAG_RETRY
Definition: vdm.h:56
struct VDM_COMMAND_INFO * PVDM_COMMAND_INFO
Definition: bufpool.h:45
USHORT VDMState
Definition: vdm.h:94
CSR_API(BaseSrvCheckVDM)
Definition: vdm.c:600
#define VDM_DEC_REENTER_COUNT
Definition: vdm.h:58
return Found
Definition: dirsup.c:1270
LIST_ENTRY VDMConsoleListHead
Definition: vdm.c:21
HANDLE WaitObjectForParent
Definition: basemsg.h:156
PFLT_MESSAGE_WAITER_QUEUE CONTAINING_RECORD(Csq, DEVICE_EXTENSION, IrpQueue)) -> WaiterQ.mLock) _IRQL_raises_(DISPATCH_LEVEL) VOID NTAPI FltpAcquireMessageWaiterLock(_In_ PIO_CSQ Csq, _Out_ PKIRQL Irql)
Definition: Messaging.c:560
#define VDM_UNDO_FULL
Definition: vdm.h:28
#define VDM_FLAG_NESTED_TASK
Definition: vdm.h:59
#define NtCurrentProcess()
Definition: nt_native.h:1657
USHORT CmdLen
Definition: basemsg.h:142
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:588
BOOLEAN BaseSrvIsVdmAllowed(VOID)
Definition: vdm.c:143
VOID BaseInitializeVDM(VOID)
Definition: vdm.c:588
ULONG CreationFlags
Definition: vdm.h:71
struct _LIST_ENTRY * Flink
Definition: typedefs.h:119
#define STATUS_NOT_FOUND
Definition: shellext.h:67
LPSTARTUPINFOA StartupInfo
Definition: basemsg.h:178
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)
PVDM_COMMAND_INFO CommandInfo
Definition: vdm.h:41
ULONG SessionId
Definition: vdm.h:30
LPSTR CurDirectory
Definition: vdm.h:80
RTL_CRITICAL_SECTION DosCriticalSection
Definition: vdm.c:22
ULONG iWowTask
Definition: basemsg.h:197
NTSTATUS NTAPI NtSetEvent(IN HANDLE EventHandle, OUT PLONG PreviousState OPTIONAL)
Definition: event.c:458
NTSYSAPI NTSTATUS NTAPI RtlInitializeCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
#define STATUS_PENDING
Definition: ntstatus.h:82
struct _KEY_VALUE_PARTIAL_INFORMATION * PKEY_VALUE_PARTIAL_INFORMATION
ULONG ProcessId
Definition: vdm.h:26
LPSTR PifFile
Definition: vdm.h:79
USHORT AppLen
Definition: vdm.h:91
ULONG iTask
Definition: basemsg.h:152
PCHAR CurrentDirs
Definition: vdm.h:28
#define BINARY_TYPE_SEPARATE_WOW
Definition: vdm.h:39
LPSTR Env
Definition: vdm.h:81
VOID BaseSrvDestroyConsoleRecord(PVDM_CONSOLE_RECORD ConsoleRecord)
Definition: vdm.c:71
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3399
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
HANDLE ConsoleHandle
Definition: vdm.h:22
CHAR Message[80]
Definition: alive.c:5
PCHAR PifFile
Definition: basemsg.h:131
unsigned char UCHAR
Definition: xmlstorage.h:181
HANDLE StdIn
Definition: basemsg.h:124
static const WCHAR L[]
Definition: oid.c:1250
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:414
Definition: typedefs.h:117
LIST_ENTRY DosListHead
Definition: vdm.h:31
NTSYSAPI NTSTATUS NTAPI RtlOpenCurrentUser(_In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE KeyHandle)
static const WCHAR Cleanup[]
Definition: register.c:80
LPSTARTUPINFOA StartupInfo
Definition: basemsg.h:135
ULONG GetNextDosSesId(VOID)
Definition: vdm.c:114
ULONG EnvLen
Definition: vdm.h:82
Status
Definition: gdiplustypes.h:24
HANDLE ClientEvent
Definition: vdm.h:40
USHORT EntryIndex
Definition: basemsg.h:157
HANDLE BaseSrvHeap
Definition: init.c:29
_Must_inspect_result_ _In_ USHORT _In_ PHIDP_PREPARSED_DATA _Out_writes_to_ LengthAttributes PHIDP_EXTENDED_ATTRIBUTES Attributes
Definition: hidpi.h:348
PVDM_CONSOLE_RECORD BaseSrvCreateConsoleRecord(VOID)
Definition: vdm.c:27
USHORT VDMCreationState
Definition: basemsg.h:158
#define STATUS_BUFFER_OVERFLOW
Definition: shellext.h:61
ULONG BinaryType
Definition: basemsg.h:122
PCHAR Desktop
Definition: basemsg.h:136
struct _KEY_VALUE_PARTIAL_INFORMATION KEY_VALUE_PARTIAL_INFORMATION
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LPSTR AppName
Definition: vdm.h:78
#define VDM_NOT_LOADED
Definition: vdm.h:46
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:153
HANDLE VDMProcessHandle
Definition: basemsg.h:155
#define STATUS_NO_MEMORY
Definition: ntstatus.h:246
#define VDM_NOT_READY
Definition: vdm.h:47
#define VDM_UNDO_PARTIAL
Definition: vdm.h:27
unsigned int * PULONG
Definition: retypes.h:1
#define HEAP_ZERO_MEMORY
Definition: compat.h:123
HANDLE ConsoleHandle
Definition: basemsg.h:154
NTSTATUS BaseSrvCreatePairWaitHandles(PHANDLE ServerEvent, PHANDLE ClientEvent)
Definition: vdm.c:240
USHORT VDMState
Definition: basemsg.h:147
#define DPRINT1
Definition: precomp.h:8
LPSTR Title
Definition: vdm.h:86
HANDLE ConsoleHandle
Definition: basemsg.h:196
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
#define VDM_DISALLOWED_VALUE_NAME
Definition: vdm.h:17
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:219
#define VDM_INC_REENTER_COUNT
Definition: vdm.h:57
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:3407
VOID BaseSrvCleanupVDMResources(IN PCSR_PROCESS CsrProcess)
Definition: vdm.c:297
unsigned int ULONG
Definition: retypes.h:1
#define VDM_FLAG_FIRST_TASK
Definition: vdm.h:53
ULONG CodePage
Definition: basemsg.h:127
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define UNIMPLEMENTED
Definition: debug.h:114
BOOLEAN NTAPI CsrImpersonateClient(IN PCSR_THREAD CsrThread)
Definition: procsup.c:925
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
USHORT CurDirectoryLen
Definition: basemsg.h:145
ULONG ReservedLen
Definition: basemsg.h:141
STARTUPINFOA StartupInfo
Definition: vdm.h:83
ULONG EnvLen
Definition: basemsg.h:134
HANDLE StdOut
Definition: vdm.h:75
ULONG ReservedLen
Definition: vdm.h:89
LIST_ENTRY Entry
Definition: vdm.h:21
PCHAR Reserved
Definition: basemsg.h:140
ULONG TitleLen
Definition: vdm.h:87
IN BOOLEAN OUT PSTR Buffer
Definition: progress.h:34
LIST_ENTRY Entry
Definition: vdm.h:36
HANDLE ServerEvent
Definition: vdm.h:24
return STATUS_SUCCESS
Definition: btrfs.c:2966
ULONG CodePage
Definition: vdm.h:73
#define __FUNCTION__
Definition: types.h:112
ULONG TaskId
Definition: vdm.h:70
base of all file and directory entries
Definition: entries.h:82
USHORT AppLen
Definition: basemsg.h:143
#define VDM_FLAG_DONT_WAIT
Definition: vdm.h:60
BOOLEAN BaseSrvCopyCommand(PBASE_CHECK_VDM CheckVdmRequest, PVDM_DOS_RECORD DosRecord)
Definition: vdm.c:352
VOID BaseSrvDestroyPairWaitHandles(HANDLE ServerEvent, HANDLE ClientEvent)
Definition: vdm.c:261
HANDLE ConsoleHandle
Definition: basemsg.h:121