ReactOS 0.4.15-dev-8428-g6910fa6
vdm.c
Go to the documentation of this file.
1/*
2 * PROJECT: ReactOS Win32 Base API
3 * LICENSE: GPL - See COPYING in the top level directory
4 * FILE: dll/win32/kernel32/client/vdm.c
5 * PURPOSE: Virtual DOS Machines (VDM) Support
6 * PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
7 */
8
9/* INCLUDES *******************************************************************/
10
11#include <k32.h>
12
13#define NDEBUG
14#include <debug.h>
15
16/* TYPES **********************************************************************/
17
18#define BINARY_UNKNOWN (0)
19#define BINARY_PE_EXE32 (1)
20#define BINARY_PE_DLL32 (2)
21#define BINARY_PE_EXE64 (3)
22#define BINARY_PE_DLL64 (4)
23#define BINARY_WIN16 (5)
24#define BINARY_OS216 (6)
25#define BINARY_DOS (7)
26#define BINARY_UNIX_EXE (8)
27#define BINARY_UNIX_LIB (9)
28
29
30typedef enum _ENV_NAME_TYPE
31{
36
37typedef struct _ENV_INFO
38{
43
44/* GLOBALS ********************************************************************/
45
46#define ENV_NAME_ENTRY(type, name) \
47 {(type), _ARRAYSIZE(name) - 1, (name)}
48
50{
53 ENV_NAME_ENTRY(EnvNameSinglePath , L"SYSTEMROOT"),
56};
57
61
62/* FUNCTIONS ******************************************************************/
63
68{
70
71 /* Is it a .com? */
73 String.Buffer = &PathName->Buffer[(PathName->Length - String.Length) / sizeof(WCHAR)];
75
76 /* Is it a .pif? */
78 String.Buffer = &PathName->Buffer[(PathName->Length - String.Length) / sizeof(WCHAR)];
80
81 /* Is it an exe? */
83 String.Buffer = &PathName->Buffer[(PathName->Length - String.Length) / sizeof(WCHAR)];
85
86 return 0;
87}
88
93 IN PCWCH CommandLine,
95 IN PANSI_STRING AnsiEnvironment,
96 IN PBASE_API_MESSAGE ApiMessage,
97 IN OUT PULONG iTask,
98 IN DWORD CreationFlags,
99 IN LPSTARTUPINFOW StartupInfo,
101{
103 PBASE_CHECK_VDM CheckVdm = &ApiMessage->Data.CheckVDMRequest;
104 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
105 PWCHAR CurrentDir = NULL;
106 PWCHAR ShortAppName = NULL;
107 PWCHAR ShortCurrentDir = NULL;
109 PCHAR AnsiCmdLine = NULL;
110 PCHAR AnsiAppName = NULL;
111 PCHAR AnsiCurDirectory = NULL;
112 PCHAR AnsiDesktop = NULL;
113 PCHAR AnsiTitle = NULL;
114 PCHAR AnsiReserved = NULL;
115 STARTUPINFOA AnsiStartupInfo;
116 ULONG NumStrings = 5;
117
118 /* Parameters validation */
119 if (ApplicationName == NULL || CommandLine == NULL)
120 {
122 }
123
124 /* Trim leading whitespace from ApplicationName */
125 while (*ApplicationName == L' ' || *ApplicationName == L'\t')
127
128 /* Calculate the size of the short application name */
130 if (Length == 0)
131 {
133 goto Cleanup;
134 }
135
136 /* Allocate memory for the short application name */
137 ShortAppName = (PWCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
139 Length * sizeof(WCHAR));
140 if (!ShortAppName)
141 {
143 goto Cleanup;
144 }
145
146 /* Get the short application name */
147 if (GetShortPathNameW(ApplicationName, ShortAppName, Length) == 0)
148 {
149 /* Try to determine which error occurred */
150 switch (GetLastError())
151 {
153 {
155 break;
156 }
157
159 {
161 break;
162 }
163
164 default:
165 {
167 }
168 }
169
170 goto Cleanup;
171 }
172
173 /* Trim leading whitespace from CommandLine */
174 while (*CommandLine == L' ' || *CommandLine == L'\t')
175 ++CommandLine;
176
177 /*
178 * CommandLine is usually formatted as: 'ApplicationName param0 ...'.
179 * So we want to strip the first token (ApplicationName) from it.
180 * Two cases are in fact possible:
181 * - either the first token is indeed ApplicationName, so we just skip it;
182 * - or the first token is not exactly ApplicationName, because it happened
183 * that somebody else already preprocessed CommandLine. Therefore we
184 * suppose that the first token corresponds to an application name and
185 * we skip it. Care should be taken when quotes are present in this token.
186 */
187 if (*CommandLine)
188 {
189 /* The first part of CommandLine should be the ApplicationName... */
191 if (Length <= wcslen(CommandLine) &&
192 _wcsnicmp(ApplicationName, CommandLine, Length) == 0)
193 {
194 /* Skip it */
195 CommandLine += Length;
196 }
197 /*
198 * ... but it is not, however we still have a token. We suppose that
199 * it corresponds to some sort of application name, so we skip it too.
200 */
201 else
202 {
203 /* Get rid of the first token. We stop when we see whitespace. */
204 while (*CommandLine && !(*CommandLine == L' ' || *CommandLine == L'\t'))
205 {
206 if (*CommandLine == L'\"')
207 {
208 /* We enter a quoted part, skip it */
209 ++CommandLine;
210 while (*CommandLine && *CommandLine++ != L'\"') ;
211 }
212 else
213 {
214 /* Go to the next character */
215 ++CommandLine;
216 }
217 }
218 }
219 }
220
221 /*
222 * Trim remaining whitespace from CommandLine that may be
223 * present between the application name and the parameters.
224 */
225 while (*CommandLine == L' ' || *CommandLine == L'\t')
226 ++CommandLine;
227
228 /* Get the current directory */
229 if (CurrentDirectory == NULL)
230 {
231 /* Allocate memory for the current directory path */
233 CurrentDir = (PWCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
235 Length * sizeof(WCHAR));
236 if (CurrentDir == NULL)
237 {
239 goto Cleanup;
240 }
241
242 /* Get the current directory */
243 GetCurrentDirectoryW(Length, CurrentDir);
244 CurrentDirectory = CurrentDir;
245 }
246
247 /* Calculate the size of the short current directory path */
249
250 /* Allocate memory for the short current directory path */
251 ShortCurrentDir = (PWCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
253 Length * sizeof(WCHAR));
254 if (!ShortCurrentDir)
255 {
257 goto Cleanup;
258 }
259
260 /* Get the short current directory path */
261 if (!GetShortPathNameW(CurrentDirectory, ShortCurrentDir, Length))
262 {
263 /* Try to determine which error occurred */
264 switch (GetLastError())
265 {
267 {
269 break;
270 }
271
273 {
275 break;
276 }
277
278 default:
279 {
281 }
282 }
283 goto Cleanup;
284 }
285
286 /* Make sure that the command line isn't too long */
287 Length = wcslen(CommandLine);
289 {
291 goto Cleanup;
292 }
293
294 /* Setup the input parameters */
295 CheckVdm->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
296 CheckVdm->BinaryType = BinaryType;
297 CheckVdm->CodePage = CP_ACP;
298 CheckVdm->dwCreationFlags = CreationFlags;
299 CheckVdm->CurDrive = CurrentDirectory[0] - L'A';
300 CheckVdm->CmdLen = (USHORT)Length + 1;
301 CheckVdm->AppLen = (USHORT)wcslen(ShortAppName) + 1;
302 CheckVdm->PifLen = 0; // TODO: PIF file support!
303 CheckVdm->CurDirectoryLen = (USHORT)wcslen(ShortCurrentDir) + 1;
304 CheckVdm->EnvLen = AnsiEnvironment->Length;
305 CheckVdm->DesktopLen = (StartupInfo->lpDesktop != NULL) ? (wcslen(StartupInfo->lpDesktop) + 1) : 0;
306 CheckVdm->TitleLen = (StartupInfo->lpTitle != NULL) ? (wcslen(StartupInfo->lpTitle) + 1) : 0;
307 CheckVdm->ReservedLen = (StartupInfo->lpReserved != NULL) ? (wcslen(StartupInfo->lpReserved) + 1) : 0;
308
309 if (StartupInfo->dwFlags & STARTF_USESTDHANDLES)
310 {
311 /* Set the standard handles */
312 CheckVdm->StdIn = StartupInfo->hStdInput;
313 CheckVdm->StdOut = StartupInfo->hStdOutput;
314 CheckVdm->StdErr = StartupInfo->hStdError;
315 }
316
317 /* Allocate memory for the ANSI strings */
318 // We need to add the newline characters '\r\n' to the command line
319 AnsiCmdLine = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CheckVdm->CmdLen + 2);
320 AnsiAppName = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CheckVdm->AppLen);
321 AnsiCurDirectory = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, CheckVdm->CurDirectoryLen);
322 if (StartupInfo->lpDesktop)
323 AnsiDesktop = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
325 CheckVdm->DesktopLen);
326 if (StartupInfo->lpTitle)
327 AnsiTitle = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
329 CheckVdm->TitleLen);
330 if (StartupInfo->lpReserved)
331 AnsiReserved = (PCHAR)RtlAllocateHeap(RtlGetProcessHeap(),
333 CheckVdm->ReservedLen);
334
335 if (!AnsiCmdLine
336 || !AnsiAppName
337 || !AnsiCurDirectory
338 || (StartupInfo->lpDesktop && !AnsiDesktop)
339 || (StartupInfo->lpTitle && !AnsiTitle)
340 || (StartupInfo->lpReserved && !AnsiReserved))
341 {
343 goto Cleanup;
344 }
345
346 /* Convert the command line into an ANSI string */
348 0,
349 CommandLine,
350 CheckVdm->CmdLen,
351 AnsiCmdLine,
352 CheckVdm->CmdLen,
353 NULL,
354 NULL);
355 /* Add the needed newline and NULL-terminate */
356 CheckVdm->CmdLen--; // Rewind back to the NULL character
357 AnsiCmdLine[CheckVdm->CmdLen++] = '\r';
358 AnsiCmdLine[CheckVdm->CmdLen++] = '\n';
359 AnsiCmdLine[CheckVdm->CmdLen++] = 0;
360
361 /* Convert the short application name into an ANSI string */
363 0,
364 ShortAppName,
365 CheckVdm->AppLen,
366 AnsiAppName,
367 CheckVdm->AppLen,
368 NULL,
369 NULL);
370
371 /* Convert the short current directory path into an ANSI string */
373 0,
374 ShortCurrentDir,
375 CheckVdm->CurDirectoryLen,
376 AnsiCurDirectory,
377 CheckVdm->CurDirectoryLen,
378 NULL,
379 NULL);
380
381 if (StartupInfo->lpDesktop)
382 {
383 /* Convert the desktop name into an ANSI string */
385 0,
386 StartupInfo->lpDesktop,
387 CheckVdm->DesktopLen,
388 AnsiDesktop,
389 CheckVdm->DesktopLen,
390 NULL,
391 NULL);
392 NumStrings++;
393 }
394
395 if (StartupInfo->lpTitle)
396 {
397 /* Convert the title into an ANSI string */
399 0,
400 StartupInfo->lpTitle,
401 CheckVdm->TitleLen,
402 AnsiTitle,
403 CheckVdm->TitleLen,
404 NULL,
405 NULL);
406 NumStrings++;
407 }
408
409 if (StartupInfo->lpReserved)
410 {
411 /* Convert the reserved value into an ANSI string */
413 0,
414 StartupInfo->lpReserved,
415 CheckVdm->ReservedLen,
416 AnsiReserved,
417 CheckVdm->ReservedLen,
418 NULL,
419 NULL);
420 NumStrings++;
421 }
422
423 /* Fill the ANSI startup info structure */
424 RtlCopyMemory(&AnsiStartupInfo, StartupInfo, sizeof(AnsiStartupInfo));
425 AnsiStartupInfo.lpReserved = AnsiReserved;
426 AnsiStartupInfo.lpDesktop = AnsiDesktop;
427 AnsiStartupInfo.lpTitle = AnsiTitle;
428
429 /* Allocate the capture buffer */
430 CaptureBuffer = CsrAllocateCaptureBuffer(NumStrings,
431 CheckVdm->CmdLen
432 + CheckVdm->AppLen
433 + CheckVdm->PifLen
434 + CheckVdm->CurDirectoryLen
435 + CheckVdm->DesktopLen
436 + CheckVdm->TitleLen
437 + CheckVdm->ReservedLen
438 + CheckVdm->EnvLen
439 + sizeof(*CheckVdm->StartupInfo));
440 if (CaptureBuffer == NULL)
441 {
443 goto Cleanup;
444 }
445
446 /* Capture the command line */
447 CsrCaptureMessageBuffer(CaptureBuffer,
448 AnsiCmdLine,
449 CheckVdm->CmdLen,
450 (PVOID*)&CheckVdm->CmdLine);
451
452 /* Capture the application name */
453 CsrCaptureMessageBuffer(CaptureBuffer,
454 AnsiAppName,
455 CheckVdm->AppLen,
456 (PVOID*)&CheckVdm->AppName);
457
458 CheckVdm->PifFile = NULL; // TODO: PIF file support!
459
460 /* Capture the current directory */
461 CsrCaptureMessageBuffer(CaptureBuffer,
462 AnsiCurDirectory,
463 CheckVdm->CurDirectoryLen,
464 (PVOID*)&CheckVdm->CurDirectory);
465
466 /* Capture the environment */
467 CsrCaptureMessageBuffer(CaptureBuffer,
468 AnsiEnvironment->Buffer,
469 CheckVdm->EnvLen,
470 (PVOID*)&CheckVdm->Env);
471
472 /* Capture the startup info structure */
473 CsrCaptureMessageBuffer(CaptureBuffer,
474 &AnsiStartupInfo,
475 sizeof(*CheckVdm->StartupInfo),
476 (PVOID*)&CheckVdm->StartupInfo);
477
478 if (StartupInfo->lpDesktop)
479 {
480 /* Capture the desktop name */
481 CsrCaptureMessageBuffer(CaptureBuffer,
482 AnsiDesktop,
483 CheckVdm->DesktopLen,
484 (PVOID*)&CheckVdm->Desktop);
485 }
486 else CheckVdm->Desktop = NULL;
487
488 if (StartupInfo->lpTitle)
489 {
490 /* Capture the title */
491 CsrCaptureMessageBuffer(CaptureBuffer,
492 AnsiTitle,
493 CheckVdm->TitleLen,
494 (PVOID*)&CheckVdm->Title);
495 }
496 else CheckVdm->Title = NULL;
497
498 if (StartupInfo->lpReserved)
499 {
500 /* Capture the reserved parameter */
501 CsrCaptureMessageBuffer(CaptureBuffer,
502 AnsiReserved,
503 CheckVdm->ReservedLen,
504 (PVOID*)&CheckVdm->Reserved);
505 }
506 else CheckVdm->Reserved = NULL;
507
508 /* Send the message to CSRSS */
510 CaptureBuffer,
512 sizeof(*CheckVdm));
513
514 /* Write back the task ID */
515 *iTask = CheckVdm->iTask;
516
517Cleanup:
518
519 /* Free the ANSI strings */
520 if (AnsiCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiCmdLine);
521 if (AnsiAppName) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiAppName);
522 if (AnsiCurDirectory) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiCurDirectory);
523 if (AnsiDesktop) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiDesktop);
524 if (AnsiTitle) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiTitle);
525 if (AnsiReserved) RtlFreeHeap(RtlGetProcessHeap(), 0, AnsiReserved);
526
527 /* Free the capture buffer */
528 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
529
530 /* Free the current directory, if it was allocated here, and its short path */
531 if (ShortCurrentDir) RtlFreeHeap(RtlGetProcessHeap(), 0, ShortCurrentDir);
532 if (CurrentDir) RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDir);
533
534 /* Free the short app name */
535 if (ShortAppName) RtlFreeHeap(RtlGetProcessHeap(), 0, ShortAppName);
536
537 return Status;
538}
539
540BOOL
541WINAPI
543 IN OUT PHANDLE WaitHandle,
544 IN ULONG IndexInfo,
545 IN ULONG BinaryType)
546{
547 BASE_API_MESSAGE ApiMessage;
548 PBASE_UPDATE_VDM_ENTRY UpdateVdmEntry = &ApiMessage.Data.UpdateVDMEntryRequest;
549
550 /* Check what update is being sent */
551 switch (UpdateIndex)
552 {
553 /* VDM is being undone */
554 case VdmEntryUndo:
555 {
556 /* Tell the server how far we had gotten along */
557 UpdateVdmEntry->iTask = HandleToUlong(*WaitHandle);
558 UpdateVdmEntry->VDMCreationState = IndexInfo;
559 break;
560 }
561
562 /* VDM is ready with a new process handle */
564 {
565 /* Send it the process handle */
566 UpdateVdmEntry->VDMProcessHandle = *WaitHandle;
567 UpdateVdmEntry->iTask = IndexInfo;
568 break;
569 }
570 }
571
572 /* Also check what kind of binary this is for the console handle */
573 if (BinaryType == BINARY_TYPE_WOW)
574 {
575 /* Magic value for 16-bit apps */
576 UpdateVdmEntry->ConsoleHandle = (HANDLE)-1;
577 }
578 else if (UpdateVdmEntry->iTask)
579 {
580 /* No handle for true VDM */
581 UpdateVdmEntry->ConsoleHandle = NULL;
582 }
583 else
584 {
585 /* Otherwise, use the regular console handle */
586 UpdateVdmEntry->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
587 }
588
589 /* Finally write the index and binary type */
590 UpdateVdmEntry->EntryIndex = UpdateIndex;
591 UpdateVdmEntry->BinaryType = BinaryType;
592
593 /* Send the message to CSRSS */
595 NULL,
597 sizeof(*UpdateVdmEntry));
598 if (!NT_SUCCESS(ApiMessage.Status))
599 {
600 /* Handle failure */
601 BaseSetLastNTError(ApiMessage.Status);
602 return FALSE;
603 }
604
605 /* If this was an update, CSRSS returns a new wait handle */
606 if (UpdateIndex == VdmEntryUpdateProcess)
607 {
608 /* Return it to the caller */
609 *WaitHandle = UpdateVdmEntry->WaitObjectForParent;
610 }
611
612 /* We made it */
613 return TRUE;
614}
615
616BOOL
617WINAPI
619 OUT LPDWORD ExitCode)
620{
622 EVENT_BASIC_INFORMATION EventBasicInfo;
623 BASE_API_MESSAGE ApiMessage;
624 PBASE_GET_VDM_EXIT_CODE GetVdmExitCode = &ApiMessage.Data.GetVDMExitCodeRequest;
625
626 /* It's VDM if the process is actually a wait handle (an event) */
629 &EventBasicInfo,
630 sizeof(EventBasicInfo),
631 NULL);
632 if (!NT_SUCCESS(Status)) return FALSE;
633
634 /* Setup the input parameters */
635 GetVdmExitCode->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
636 GetVdmExitCode->hParent = ProcessHandle;
637
638 /* Call CSRSS */
640 NULL,
642 sizeof(*GetVdmExitCode));
643 if (!NT_SUCCESS(Status)) return FALSE;
644
645 /* Get the exit code from the reply */
646 *ExitCode = GetVdmExitCode->ExitCode;
647 return TRUE;
648}
649
650BOOL
651WINAPI
652BaseGetVdmConfigInfo(IN LPCWSTR CommandLineReserved,
653 IN ULONG DosSeqId,
654 IN ULONG BinaryType,
655 IN PUNICODE_STRING CmdLineString,
656 OUT PULONG VdmSize)
657{
659 WCHAR CommandLine[MAX_PATH * 2];
661
662 /* Clear the buffer in case we fail */
663 CmdLineString->Buffer = 0;
664
665 /* Always return the same size: 16 Mb */
666 *VdmSize = 0x1000000;
667
668 /* Get the system directory */
670 if (!(Length) || (Length >= MAX_PATH))
671 {
672 /* Eliminate no path or path too big */
674 return FALSE;
675 }
676
677 /* Check if this is VDM with a DOS Sequence ID */
678 if (DosSeqId)
679 {
680 /*
681 * Build the VDM string for it:
682 * -i%lx : Gives the DOS Sequence ID;
683 * %s%c : Nothing if DOS VDM, -w if WoW VDM, -ws if separate WoW VDM.
684 */
685 _snwprintf(CommandLine,
686 ARRAYSIZE(CommandLine),
687 L"\"%s\\ntvdm.exe\" -i%lx %s%c",
688 Buffer,
689 DosSeqId,
690 (BinaryType == BINARY_TYPE_DOS) ? L" " : L"-w",
691 (BinaryType == BINARY_TYPE_SEPARATE_WOW) ? L's' : L' ');
692 }
693 else
694 {
695 /*
696 * Build the string for it without the DOS Sequence ID:
697 * %s%c : Nothing if DOS VDM, -w if WoW VDM, -ws if separate WoW VDM.
698 */
699 _snwprintf(CommandLine,
700 ARRAYSIZE(CommandLine),
701 L"\"%s\\ntvdm.exe\" %s%c",
702 Buffer,
703 (BinaryType == BINARY_TYPE_DOS) ? L" " : L"-w",
704 (BinaryType == BINARY_TYPE_SEPARATE_WOW) ? L's' : L' ');
705 }
706
707 /* Create the actual string */
708 return RtlCreateUnicodeString(CmdLineString, CommandLine);
709}
710
712WINAPI
714 IN ULONG NameLength)
715{
716 PENV_INFO EnvInfo;
718 ULONG i;
719
720 /* Start by assuming the environment variable doesn't describe paths */
722
723 /* Loop all the environment names */
724 for (i = 0; i < ARRAYSIZE(BasepEnvNameType); i++)
725 {
726 /* Get this entry */
727 EnvInfo = &BasepEnvNameType[i];
728
729 /* Check if it matches the name */
730 if ((EnvInfo->NameLength == NameLength) &&
731 (_wcsnicmp(EnvInfo->Name, Name, NameLength) == 0))
732 {
733 /* It does, return the type */
734 NameType = EnvInfo->NameType;
735 break;
736 }
737 }
738
739 return NameType;
740}
741
742BOOL
743NTAPI
745 OUT PANSI_STRING AnsiEnv,
746 OUT PUNICODE_STRING UnicodeEnv)
747{
748#define IS_ALPHA(x) \
749 ( ((x) >= L'A' && (x) <= L'Z') || ((x) >= L'a' && (x) <= L'z') )
750
751// From lib/rtl/path.c :
752// Can be put in some .h ??
753#define IS_PATH_SEPARATOR(x) ((x) == L'\\' || (x) == L'/')
754
757 ULONG EnvironmentSize = 0;
759 PWCHAR Environment, NewEnvironment = NULL;
761 ULONG NameLength, NumChars, Remaining;
762 PWCHAR SourcePtr, DestPtr, StartPtr;
763
764 /* Make sure we have both strings */
765 if (!AnsiEnv || !UnicodeEnv)
766 {
767 /* Fail */
769 return FALSE;
770 }
771
772 /* Check if an environment was passed in */
773 if (!lpEnvironment)
774 {
775 /* Nope, create one */
777 if (!NT_SUCCESS(Status)) goto Cleanup;
778 }
779 else
780 {
781 /* Use the one we got */
782 Environment = lpEnvironment;
783 }
784
785 /* Do we have something now ? */
786 if (!Environment)
787 {
788 /* Still not, bail out */
790 goto Cleanup;
791 }
792
793 /*
794 * Count how much space the whole environment takes. The environment block is
795 * doubly NULL-terminated (NULL from last string and final NULL terminator).
796 */
797 SourcePtr = Environment;
798 while (!(*SourcePtr++ == UNICODE_NULL && *SourcePtr == UNICODE_NULL))
799 ++EnvironmentSize;
800 EnvironmentSize += 2; // Add the two terminating NULLs
801
802 /*
803 * Allocate a new copy large enough to hold all the environment with paths
804 * in their short form. Since the short form of a path can be a bit longer
805 * than its long form, for example in the case where characters that are
806 * invalid in the 8.3 representation are present in the long path name:
807 * 'C:\\a+b' --> 'C:\\A_B~1', or:
808 * 'C:\\a b' --> 'C:\\AB2761~1' (with checksum inserted),
809 * we suppose that the possible total number of extra characters needed to
810 * convert the long paths into their short form is at most equal to MAX_PATH.
811 */
812 RegionSize = (EnvironmentSize + MAX_PATH) * sizeof(WCHAR);
814 (PVOID*)&NewEnvironment,
815 0,
816 &RegionSize,
819 if (!NT_SUCCESS(Status))
820 {
821 /* We failed, bail out */
823 NewEnvironment = NULL;
824 goto Cleanup;
825 }
826
827 /* Parse the environment block */
828 Remaining = MAX_PATH - 2; // '-2': remove the last two NULLs. FIXME: is it really needed??
829 SourcePtr = Environment;
830 DestPtr = NewEnvironment;
831
832 /* Loop through all the environment strings */
833 while (*SourcePtr != UNICODE_NULL)
834 {
835 /*
836 * 1. Check the type of the environment variable and copy its name.
837 */
838
839 /* Regular environment variable */
840 if (*SourcePtr != L'=')
841 {
842 StartPtr = SourcePtr;
843
844 /* Copy the environment variable name, including the '=' */
845 while (*SourcePtr != UNICODE_NULL)
846 {
847 *DestPtr++ = *SourcePtr;
848 if (*SourcePtr++ == L'=') break;
849 }
850
851 /* Guess the type of the environment variable */
852 NameType = BaseGetEnvNameType_U(StartPtr, SourcePtr - StartPtr - 1);
853 }
854 /* 'Current directory' environment variable (i.e. of '=X:=' form) */
855 else // if (*SourcePtr == L'=')
856 {
857 /* First assume we have a possibly malformed environment variable */
859
860 /* Check for a valid 'Current directory' environment variable */
861 if (IS_ALPHA(SourcePtr[1]) && SourcePtr[2] == L':' && SourcePtr[3] == L'=')
862 {
863 /*
864 * Small optimization: convert the path to short form only if
865 * the current directory is not the root directory (i.e. not
866 * of the '=X:=Y:\' form), otherwise just do a simple copy.
867 */
868 if ( wcslen(SourcePtr) >= ARRAYSIZE("=X:=Y:\\")-1 &&
869 !( IS_ALPHA(SourcePtr[4]) && SourcePtr[5] == L':' &&
870 IS_PATH_SEPARATOR(SourcePtr[6]) && SourcePtr[7] == UNICODE_NULL ) )
871 {
873
874 /* Copy the '=X:=' prefix */
875 *DestPtr++ = SourcePtr[0];
876 *DestPtr++ = SourcePtr[1];
877 *DestPtr++ = SourcePtr[2];
878 *DestPtr++ = SourcePtr[3];
879 SourcePtr += 4;
880 }
881 }
882 else
883 {
884 /*
885 * Invalid stuff starting with '=', i.e.:
886 * =? (with '?' not being a letter)
887 * =X??? (with '?' not being ":=" and not followed by something longer than 3 characters)
888 * =X:=??? (with '?' not being "X:\\")
889 *
890 * 'NameType' is already set to 'EnvNameNotAPath'.
891 */
892 }
893 }
894
895
896 /*
897 * 2. Copy the environment value and perform conversions accordingly.
898 */
899
901 {
902 /* Copy everything, including the NULL terminator */
903 do
904 {
905 *DestPtr++ = *SourcePtr;
906 } while (*SourcePtr++ != UNICODE_NULL);
907 }
908 else if (NameType == EnvNameSinglePath)
909 {
910 /* Convert the path to its short form */
911 NameLength = wcslen(SourcePtr);
912 NumChars = GetShortPathNameW(SourcePtr, DestPtr, NameLength + 1 + Remaining);
913 if (NumChars == 0 || NumChars > NameLength + Remaining)
914 {
915 /* If the conversion failed, just copy the original value */
916 RtlCopyMemory(DestPtr, SourcePtr, NameLength * sizeof(WCHAR));
917 NumChars = NameLength;
918 }
919 DestPtr += NumChars;
920 if (NumChars > NameLength)
921 Remaining -= (NumChars - NameLength);
922
923 SourcePtr += NameLength;
924
925 /* Copy the NULL terminator */
926 *DestPtr++ = *SourcePtr++;
927 }
928 else // if (NameType == EnvNameMultiplePath)
929 {
930 WCHAR Delimiter;
931
932 /* Loop through the list of paths (delimited by ';') and convert each path to its short form */
933 do
934 {
935 /* Copy any trailing ';' before going to the next path */
936 while (*SourcePtr == L';')
937 {
938 *DestPtr++ = *SourcePtr++;
939 }
940
941 StartPtr = SourcePtr;
942
943 /* Find the next path list delimiter or the NULL terminator */
944 while (*SourcePtr != UNICODE_NULL && *SourcePtr != L';')
945 {
946 ++SourcePtr;
947 }
948 Delimiter = *SourcePtr;
949
950 NameLength = SourcePtr - StartPtr;
951 if (NameLength)
952 {
953 /*
954 * Temporarily replace the possible path list delimiter by NULL.
955 * 'lpEnvironment' must point to a read+write memory buffer!
956 */
957 *SourcePtr = UNICODE_NULL;
958
959 NumChars = GetShortPathNameW(StartPtr, DestPtr, NameLength + 1 + Remaining);
960 if ( NumChars == 0 ||
961 (Delimiter == L';' ? NumChars > NameLength + Remaining
962 : NumChars > NameLength /* + Remaining ?? */) )
963 {
964 /* If the conversion failed, just copy the original value */
965 RtlCopyMemory(DestPtr, StartPtr, NameLength * sizeof(WCHAR));
966 NumChars = NameLength;
967 }
968 DestPtr += NumChars;
969 if (NumChars > NameLength)
970 Remaining -= (NumChars - NameLength);
971
972 /* If removed, restore the path list delimiter in the source environment value and copy it */
973 if (Delimiter != UNICODE_NULL)
974 {
975 *SourcePtr = Delimiter;
976 *DestPtr++ = *SourcePtr++;
977 }
978 }
979 } while (*SourcePtr != UNICODE_NULL);
980
981 /* Copy the NULL terminator */
982 *DestPtr++ = *SourcePtr++;
983 }
984 }
985
986 /* NULL-terminate the environment block */
987 *DestPtr++ = UNICODE_NULL;
988
989 /* Initialize the Unicode string to hold it */
990 RtlInitEmptyUnicodeString(UnicodeEnv, NewEnvironment,
991 (DestPtr - NewEnvironment) * sizeof(WCHAR));
992 UnicodeEnv->Length = UnicodeEnv->MaximumLength;
993
994 /* Create its ANSI version */
995 Status = RtlUnicodeStringToAnsiString(AnsiEnv, UnicodeEnv, TRUE);
996 if (!NT_SUCCESS(Status))
997 {
998 /* Set last error if conversion failure */
1000 }
1001 else
1002 {
1003 /* Everything went okay, so return success */
1004 Success = TRUE;
1005 NewEnvironment = NULL;
1006 }
1007
1008Cleanup:
1009 /* Cleanup path starts here, start by destroying the environment copy */
1010 if (!lpEnvironment && Environment) RtlDestroyEnvironment(Environment);
1011
1012 /* See if we are here due to failure */
1013 if (NewEnvironment)
1014 {
1015 /* Initialize the paths to be empty */
1016 RtlInitEmptyUnicodeString(UnicodeEnv, NULL, 0);
1017 RtlInitEmptyAnsiString(AnsiEnv, NULL, 0);
1018
1019 /* Free the environment copy */
1020 RegionSize = 0;
1022 (PVOID*)&NewEnvironment,
1023 &RegionSize,
1024 MEM_RELEASE);
1026 }
1027
1028 /* Return the result */
1029 return Success;
1030}
1031
1032BOOL
1033NTAPI
1035 IN PUNICODE_STRING UnicodeEnv)
1036{
1037 SIZE_T Dummy = 0;
1038
1039 /* Clear the ANSI buffer since Rtl creates this for us */
1040 if (AnsiEnv->Buffer) RtlFreeAnsiString(AnsiEnv);
1041
1042 /* The Unicode buffer is build by hand, though */
1043 if (UnicodeEnv->Buffer)
1044 {
1045 /* So clear it through the API */
1047 (PVOID*)&UnicodeEnv->Buffer,
1048 &Dummy,
1049 MEM_RELEASE);
1050 }
1051
1052 /* All done */
1053 return TRUE;
1054}
1055
1056
1057/* Check whether a file is an OS/2 or a very old Windows executable
1058 * by testing on import of KERNEL.
1059 *
1060 * FIXME: is reading the module imports the only way of discerning
1061 * old Windows binaries from OS/2 ones ? At least it seems so...
1062 */
1063static DWORD WINAPI
1065{
1066 DWORD CurPos;
1067 LPWORD modtab = NULL;
1068 LPSTR nametab = NULL;
1069 DWORD Read, Ret;
1070 int i;
1071
1072 Ret = BINARY_OS216;
1073 CurPos = SetFilePointer(hFile, 0, NULL, FILE_CURRENT);
1074
1075 /* read modref table */
1077 (!(modtab = HeapAlloc(GetProcessHeap(), 0, ne->ne_cmod * sizeof(WORD)))) ||
1078 (!(ReadFile(hFile, modtab, ne->ne_cmod * sizeof(WORD), &Read, NULL))) ||
1079 (Read != (DWORD)ne->ne_cmod * sizeof(WORD)))
1080 {
1081 goto broken;
1082 }
1083
1084 /* read imported names table */
1086 (!(nametab = HeapAlloc(GetProcessHeap(), 0, ne->ne_enttab - ne->ne_imptab))) ||
1087 (!(ReadFile(hFile, nametab, ne->ne_enttab - ne->ne_imptab, &Read, NULL))) ||
1088 (Read != (DWORD)ne->ne_enttab - ne->ne_imptab))
1089 {
1090 goto broken;
1091 }
1092
1093 for(i = 0; i < ne->ne_cmod; i++)
1094 {
1095 LPSTR module;
1096 module = &nametab[modtab[i]];
1097 if(!strncmp(&module[1], "KERNEL", module[0]))
1098 {
1099 /* very old windows file */
1100 Ret = BINARY_WIN16;
1101 goto done;
1102 }
1103 }
1104
1105 broken:
1106 DPRINT1("InternalIsOS2OrOldWin(): Binary file seems to be broken\n");
1107
1108 done:
1109 HeapFree(GetProcessHeap(), 0, modtab);
1110 HeapFree(GetProcessHeap(), 0, nametab);
1112 return Ret;
1113}
1114
1115static DWORD WINAPI
1117{
1118 union
1119 {
1120 struct
1121 {
1122 unsigned char magic[4];
1123 unsigned char ignored[12];
1124 unsigned short type;
1125 } elf;
1126 struct
1127 {
1128 unsigned long magic;
1129 unsigned long cputype;
1130 unsigned long cpusubtype;
1131 unsigned long filetype;
1132 } macho;
1134 } Header;
1135 char magic[4];
1136 DWORD Read;
1137
1139 (!ReadFile(hFile, &Header, sizeof(Header), &Read, NULL) ||
1140 (Read != sizeof(Header))))
1141 {
1142 return BINARY_UNKNOWN;
1143 }
1144
1145 if(!memcmp(Header.elf.magic, "\177ELF", sizeof(Header.elf.magic)))
1146 {
1147 /* FIXME: we don't bother to check byte order, architecture, etc. */
1148 switch(Header.elf.type)
1149 {
1150 case 2:
1151 return BINARY_UNIX_EXE;
1152 case 3:
1153 return BINARY_UNIX_LIB;
1154 }
1155 return BINARY_UNKNOWN;
1156 }
1157
1158 /* Mach-o File with Endian set to Big Endian or Little Endian*/
1159 if(Header.macho.magic == 0xFEEDFACE ||
1160 Header.macho.magic == 0xCEFAEDFE)
1161 {
1162 switch(Header.macho.filetype)
1163 {
1164 case 0x8:
1165 /* MH_BUNDLE */
1166 return BINARY_UNIX_LIB;
1167 }
1168 return BINARY_UNKNOWN;
1169 }
1170
1171 /* Not ELF, try DOS */
1172 if(Header.mz.e_magic == IMAGE_DOS_SIGNATURE)
1173 {
1174 /* We do have a DOS image so we will now try to seek into
1175 * the file by the amount indicated by the field
1176 * "Offset to extended header" and read in the
1177 * "magic" field information at that location.
1178 * This will tell us if there is more header information
1179 * to read or not.
1180 */
1182 (!ReadFile(hFile, magic, sizeof(magic), &Read, NULL) ||
1183 (Read != sizeof(magic))))
1184 {
1185 return BINARY_DOS;
1186 }
1187
1188 /* Reading the magic field succeeded so
1189 * we will try to determine what type it is.
1190 */
1191 if(!memcmp(magic, "PE\0\0", sizeof(magic)))
1192 {
1193 IMAGE_FILE_HEADER FileHeader;
1194 if(!ReadFile(hFile, &FileHeader, sizeof(IMAGE_FILE_HEADER), &Read, NULL) ||
1195 (Read != sizeof(IMAGE_FILE_HEADER)))
1196 {
1197 return BINARY_DOS;
1198 }
1199
1200 /* FIXME - detect 32/64 bit */
1201
1202 if(FileHeader.Characteristics & IMAGE_FILE_DLL)
1203 return BINARY_PE_DLL32;
1204 return BINARY_PE_EXE32;
1205 }
1206
1207 if(!memcmp(magic, "NE", 2))
1208 {
1209 /* This is a Windows executable (NE) header. This can
1210 * mean either a 16-bit OS/2 or a 16-bit Windows or even a
1211 * DOS program (running under a DOS extender). To decide
1212 * which, we'll have to read the NE header.
1213 */
1215 if((SetFilePointer(hFile, Header.mz.e_lfanew, NULL, FILE_BEGIN) == 1) ||
1216 !ReadFile(hFile, &ne, sizeof(IMAGE_OS2_HEADER), &Read, NULL) ||
1217 (Read != sizeof(IMAGE_OS2_HEADER)))
1218 {
1219 /* Couldn't read header, so abort. */
1220 return BINARY_DOS;
1221 }
1222
1223 switch(ne.ne_exetyp)
1224 {
1225 case 2:
1226 return BINARY_WIN16;
1227 case 5:
1228 return BINARY_DOS;
1229 default:
1230 return InternalIsOS2OrOldWin(hFile, &Header.mz, &ne);
1231 }
1232 }
1233 return BINARY_DOS;
1234 }
1235 return BINARY_UNKNOWN;
1236}
1237
1238/*
1239 * @implemented
1240 */
1241BOOL
1242WINAPI
1244 LPCWSTR lpApplicationName,
1245 LPDWORD lpBinaryType
1246 )
1247{
1248 HANDLE hFile;
1249 DWORD BinType;
1250
1251 if(!lpApplicationName || !lpBinaryType)
1252 {
1254 return FALSE;
1255 }
1256
1257 hFile = CreateFileW(lpApplicationName, GENERIC_READ, FILE_SHARE_READ, NULL,
1258 OPEN_EXISTING, 0, 0);
1260 {
1261 return FALSE;
1262 }
1263
1264 BinType = InternalGetBinaryType(hFile);
1266
1267 switch(BinType)
1268 {
1269 case BINARY_UNKNOWN:
1270 {
1271 WCHAR *dot;
1272
1273 /*
1274 * guess from filename
1275 */
1276 if(!(dot = wcsrchr(lpApplicationName, L'.')))
1277 {
1278 return FALSE;
1279 }
1280 if(!lstrcmpiW(dot, L".COM"))
1281 {
1282 *lpBinaryType = SCS_DOS_BINARY;
1283 return TRUE;
1284 }
1285 if(!lstrcmpiW(dot, L".PIF"))
1286 {
1287 *lpBinaryType = SCS_PIF_BINARY;
1288 return TRUE;
1289 }
1290 return FALSE;
1291 }
1292 case BINARY_PE_EXE32:
1293 case BINARY_PE_DLL32:
1294 {
1295 *lpBinaryType = SCS_32BIT_BINARY;
1296 return TRUE;
1297 }
1298 case BINARY_PE_EXE64:
1299 case BINARY_PE_DLL64:
1300 {
1301 *lpBinaryType = SCS_64BIT_BINARY;
1302 return TRUE;
1303 }
1304 case BINARY_WIN16:
1305 {
1306 *lpBinaryType = SCS_WOW_BINARY;
1307 return TRUE;
1308 }
1309 case BINARY_OS216:
1310 {
1311 *lpBinaryType = SCS_OS216_BINARY;
1312 return TRUE;
1313 }
1314 case BINARY_DOS:
1315 {
1316 *lpBinaryType = SCS_DOS_BINARY;
1317 return TRUE;
1318 }
1319 case BINARY_UNIX_EXE:
1320 case BINARY_UNIX_LIB:
1321 {
1322 return FALSE;
1323 }
1324 }
1325
1326 DPRINT1("Invalid binary type %lu returned!\n", BinType);
1327 return FALSE;
1328}
1329
1330/*
1331 * @implemented
1332 */
1333BOOL
1334WINAPI
1335GetBinaryTypeA(IN LPCSTR lpApplicationName,
1336 OUT LPDWORD lpBinaryType)
1337{
1338 ANSI_STRING ApplicationNameString;
1339 UNICODE_STRING ApplicationNameW;
1340 BOOL StringAllocated = FALSE, Result;
1342
1343 RtlInitAnsiString(&ApplicationNameString, lpApplicationName);
1344
1345 if (ApplicationNameString.Length * sizeof(WCHAR) >= NtCurrentTeb()->StaticUnicodeString.MaximumLength)
1346 {
1347 StringAllocated = TRUE;
1348 Status = RtlAnsiStringToUnicodeString(&ApplicationNameW, &ApplicationNameString, TRUE);
1349 }
1350 else
1351 {
1352 Status = RtlAnsiStringToUnicodeString(&(NtCurrentTeb()->StaticUnicodeString), &ApplicationNameString, FALSE);
1353 }
1354
1355 if (!NT_SUCCESS(Status))
1356 {
1358 return FALSE;
1359 }
1360
1361 if (StringAllocated)
1362 {
1363 Result = GetBinaryTypeW(ApplicationNameW.Buffer, lpBinaryType);
1364 RtlFreeUnicodeString(&ApplicationNameW);
1365 }
1366 else
1367 {
1368 Result = GetBinaryTypeW(NtCurrentTeb()->StaticUnicodeString.Buffer, lpBinaryType);
1369 }
1370
1371 return Result;
1372}
1373
1374/*
1375 * @unimplemented
1376 */
1377BOOL
1378WINAPI
1381 )
1382{
1383 STUB;
1384 return FALSE;
1385}
1386
1387/*
1388 * @implemented
1389 */
1390VOID
1391WINAPI
1392ExitVDM(BOOL IsWow, ULONG iWowTask)
1393{
1394 BASE_API_MESSAGE ApiMessage;
1395 PBASE_EXIT_VDM ExitVdm = &ApiMessage.Data.ExitVDMRequest;
1396
1397 /* Setup the input parameters */
1398 ExitVdm->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1399 ExitVdm->iWowTask = IsWow ? iWowTask : 0; /* Always zero for DOS tasks */
1400 ExitVdm->WaitObjectForVDM = NULL;
1401
1402 /* Call CSRSS */
1404 NULL,
1406 sizeof(*ExitVdm));
1407
1408 /* Close the returned wait object handle, if any */
1409 if (NT_SUCCESS(ApiMessage.Status) && (ExitVdm->WaitObjectForVDM != NULL))
1410 {
1411 CloseHandle(ExitVdm->WaitObjectForVDM);
1412 }
1413}
1414
1415/*
1416 * @implemented
1417 */
1418BOOL
1419WINAPI
1421{
1422 BOOL Success = FALSE;
1424 BASE_API_MESSAGE ApiMessage;
1425 PBASE_GET_NEXT_VDM_COMMAND GetNextVdmCommand = &ApiMessage.Data.GetNextVDMCommandRequest;
1426 PBASE_IS_FIRST_VDM IsFirstVdm = &ApiMessage.Data.IsFirstVDMRequest;
1427 PBASE_SET_REENTER_COUNT SetReenterCount = &ApiMessage.Data.SetReenterCountRequest;
1428 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
1429 ULONG NumStrings = 0;
1430
1431 /*
1432 * Special case to test whether the VDM is the first one.
1433 */
1434 if (CommandData == NULL)
1435 {
1436 /* Call CSRSS */
1438 NULL,
1440 sizeof(*IsFirstVdm));
1441 if (!NT_SUCCESS(ApiMessage.Status))
1442 {
1443 BaseSetLastNTError(ApiMessage.Status);
1444 return FALSE;
1445 }
1446
1447 /* Return TRUE if this is the first VDM */
1448 return IsFirstVdm->FirstVDM;
1449 }
1450
1451 /* CommandData != NULL */
1452
1453 /*
1454 * Special case to increment or decrement the reentrancy count.
1455 */
1456 if ((CommandData->VDMState == VDM_INC_REENTER_COUNT) ||
1457 (CommandData->VDMState == VDM_DEC_REENTER_COUNT))
1458 {
1459 /* Setup the input parameters */
1460 SetReenterCount->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1461 SetReenterCount->fIncDec = CommandData->VDMState;
1462
1463 /* Call CSRSS */
1465 NULL,
1467 sizeof(*SetReenterCount));
1468 if (!NT_SUCCESS(ApiMessage.Status))
1469 {
1470 BaseSetLastNTError(ApiMessage.Status);
1471 return FALSE;
1472 }
1473
1474 return TRUE;
1475 }
1476
1477 /*
1478 * TODO!
1479 * Special case to retrieve or set WOW information.
1480 */
1481 // TODO: if CommandData->VDMState & (VDM_LIST_WOW_PROCESSES | VDM_LIST_WOW_TASKS | VDM_ADD_WOW_TASK)
1482 // then call BasepGetNextVDMCommand in a simpler way!
1483
1484 /*
1485 * Regular case.
1486 */
1487
1488 /* Clear the structure */
1489 RtlZeroMemory(GetNextVdmCommand, sizeof(*GetNextVdmCommand));
1490
1491 /* Setup the input parameters */
1492 GetNextVdmCommand->iTask = CommandData->TaskId;
1493 GetNextVdmCommand->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1494 GetNextVdmCommand->CmdLen = CommandData->CmdLen;
1495 GetNextVdmCommand->AppLen = CommandData->AppLen;
1496 GetNextVdmCommand->PifLen = CommandData->PifLen;
1497 GetNextVdmCommand->CurDirectoryLen = CommandData->CurDirectoryLen;
1498 GetNextVdmCommand->EnvLen = CommandData->EnvLen;
1499 GetNextVdmCommand->DesktopLen = CommandData->DesktopLen;
1500 GetNextVdmCommand->TitleLen = CommandData->TitleLen;
1501 GetNextVdmCommand->ReservedLen = CommandData->ReservedLen;
1502 GetNextVdmCommand->VDMState = CommandData->VDMState;
1503
1504 /* Count the number of strings */
1505 if (CommandData->CmdLen) NumStrings++;
1506 if (CommandData->AppLen) NumStrings++;
1507 if (CommandData->PifLen) NumStrings++;
1508 if (CommandData->CurDirectoryLen) NumStrings++;
1509 if (CommandData->EnvLen) NumStrings++;
1510 if (CommandData->DesktopLen) NumStrings++;
1511 if (CommandData->TitleLen) NumStrings++;
1512 if (CommandData->ReservedLen) NumStrings++;
1513
1514 /* Allocate the capture buffer */
1515 CaptureBuffer = CsrAllocateCaptureBuffer(NumStrings + 1,
1516 GetNextVdmCommand->CmdLen
1517 + GetNextVdmCommand->AppLen
1518 + GetNextVdmCommand->PifLen
1519 + GetNextVdmCommand->CurDirectoryLen
1520 + GetNextVdmCommand->EnvLen
1521 + GetNextVdmCommand->DesktopLen
1522 + GetNextVdmCommand->TitleLen
1523 + GetNextVdmCommand->ReservedLen
1524 + sizeof(*GetNextVdmCommand->StartupInfo));
1525 if (CaptureBuffer == NULL)
1526 {
1528 goto Cleanup;
1529 }
1530
1531 /* Capture the data */
1532
1533 CsrAllocateMessagePointer(CaptureBuffer,
1534 sizeof(*GetNextVdmCommand->StartupInfo),
1535 (PVOID*)&GetNextVdmCommand->StartupInfo);
1536
1537 if (CommandData->CmdLen)
1538 {
1539 CsrAllocateMessagePointer(CaptureBuffer,
1540 CommandData->CmdLen,
1541 (PVOID*)&GetNextVdmCommand->CmdLine);
1542 }
1543
1544 if (CommandData->AppLen)
1545 {
1546 CsrAllocateMessagePointer(CaptureBuffer,
1547 CommandData->AppLen,
1548 (PVOID*)&GetNextVdmCommand->AppName);
1549 }
1550
1551 if (CommandData->PifLen)
1552 {
1553 CsrAllocateMessagePointer(CaptureBuffer,
1554 CommandData->PifLen,
1555 (PVOID*)&GetNextVdmCommand->PifFile);
1556 }
1557
1558 if (CommandData->CurDirectoryLen)
1559 {
1560 CsrAllocateMessagePointer(CaptureBuffer,
1561 CommandData->CurDirectoryLen,
1562 (PVOID*)&GetNextVdmCommand->CurDirectory);
1563 }
1564
1565 if (CommandData->EnvLen)
1566 {
1567 CsrAllocateMessagePointer(CaptureBuffer,
1568 CommandData->EnvLen,
1569 (PVOID*)&GetNextVdmCommand->Env);
1570 }
1571
1572 if (CommandData->DesktopLen)
1573 {
1574 CsrAllocateMessagePointer(CaptureBuffer,
1575 CommandData->DesktopLen,
1576 (PVOID*)&GetNextVdmCommand->Desktop);
1577 }
1578
1579 if (CommandData->TitleLen)
1580 {
1581 CsrAllocateMessagePointer(CaptureBuffer,
1582 CommandData->TitleLen,
1583 (PVOID*)&GetNextVdmCommand->Title);
1584 }
1585
1586 if (CommandData->ReservedLen)
1587 {
1588 CsrAllocateMessagePointer(CaptureBuffer,
1589 CommandData->ReservedLen,
1590 (PVOID*)&GetNextVdmCommand->Reserved);
1591 }
1592
1593 while (TRUE)
1594 {
1595 /* Call CSRSS */
1597 CaptureBuffer,
1599 sizeof(*GetNextVdmCommand));
1600
1601 /* Exit the waiting loop if we did not receive any event handle */
1602 if (GetNextVdmCommand->WaitObjectForVDM == NULL)
1603 break;
1604
1605 /* Wait for the event to become signaled and try again */
1606 Status = NtWaitForSingleObject(GetNextVdmCommand->WaitObjectForVDM,
1607 FALSE, NULL);
1608 if (Status != STATUS_SUCCESS)
1609 {
1610 /* Fail if we timed out, or if some other error happened */
1612 goto Cleanup;
1613 }
1614
1615 /* Set the retry flag, clear the exit code, and retry a query */
1616 GetNextVdmCommand->VDMState |= VDM_FLAG_RETRY;
1617 GetNextVdmCommand->ExitCode = 0;
1618 }
1619
1620 if (!NT_SUCCESS(Status))
1621 {
1623 {
1624 /*
1625 * One of the buffer lengths was less than required. Store the correct ones.
1626 * Note that the status code is not STATUS_BUFFER_TOO_SMALL as one would expect,
1627 * in order to keep compatibility with Windows 2003 BASESRV.DLL.
1628 */
1629 CommandData->CmdLen = GetNextVdmCommand->CmdLen;
1630 CommandData->AppLen = GetNextVdmCommand->AppLen;
1631 CommandData->PifLen = GetNextVdmCommand->PifLen;
1632 CommandData->CurDirectoryLen = GetNextVdmCommand->CurDirectoryLen;
1633 CommandData->EnvLen = GetNextVdmCommand->EnvLen;
1634 CommandData->DesktopLen = GetNextVdmCommand->DesktopLen;
1635 CommandData->TitleLen = GetNextVdmCommand->TitleLen;
1636 CommandData->ReservedLen = GetNextVdmCommand->ReservedLen;
1637 }
1638 else
1639 {
1640 /* Any other failure */
1641 CommandData->CmdLen = 0;
1642 CommandData->AppLen = 0;
1643 CommandData->PifLen = 0;
1644 CommandData->CurDirectoryLen = 0;
1645 CommandData->EnvLen = 0;
1646 CommandData->DesktopLen = 0;
1647 CommandData->TitleLen = 0;
1648 CommandData->ReservedLen = 0;
1649 }
1650
1652 goto Cleanup;
1653 }
1654
1655 /* Write back the standard handles */
1656 CommandData->StdIn = GetNextVdmCommand->StdIn;
1657 CommandData->StdOut = GetNextVdmCommand->StdOut;
1658 CommandData->StdErr = GetNextVdmCommand->StdErr;
1659
1660 /* Write back the startup info */
1661 RtlMoveMemory(&CommandData->StartupInfo,
1662 GetNextVdmCommand->StartupInfo,
1663 sizeof(*GetNextVdmCommand->StartupInfo));
1664
1665 if (CommandData->CmdLen)
1666 {
1667 /* Write back the command line */
1668 RtlMoveMemory(CommandData->CmdLine,
1669 GetNextVdmCommand->CmdLine,
1670 GetNextVdmCommand->CmdLen);
1671
1672 /* Set the actual length */
1673 CommandData->CmdLen = GetNextVdmCommand->CmdLen;
1674 }
1675
1676 if (CommandData->AppLen)
1677 {
1678 /* Write back the application name */
1679 RtlMoveMemory(CommandData->AppName,
1680 GetNextVdmCommand->AppName,
1681 GetNextVdmCommand->AppLen);
1682
1683 /* Set the actual length */
1684 CommandData->AppLen = GetNextVdmCommand->AppLen;
1685 }
1686
1687 if (CommandData->PifLen)
1688 {
1689 /* Write back the PIF file name */
1690 RtlMoveMemory(CommandData->PifFile,
1691 GetNextVdmCommand->PifFile,
1692 GetNextVdmCommand->PifLen);
1693
1694 /* Set the actual length */
1695 CommandData->PifLen = GetNextVdmCommand->PifLen;
1696 }
1697
1698 if (CommandData->CurDirectoryLen)
1699 {
1700 /* Write back the current directory */
1701 RtlMoveMemory(CommandData->CurDirectory,
1702 GetNextVdmCommand->CurDirectory,
1703 GetNextVdmCommand->CurDirectoryLen);
1704
1705 /* Set the actual length */
1706 CommandData->CurDirectoryLen = GetNextVdmCommand->CurDirectoryLen;
1707 }
1708
1709 if (CommandData->EnvLen)
1710 {
1711 /* Write back the environment */
1712 RtlMoveMemory(CommandData->Env,
1713 GetNextVdmCommand->Env,
1714 GetNextVdmCommand->EnvLen);
1715
1716 /* Set the actual length */
1717 CommandData->EnvLen = GetNextVdmCommand->EnvLen;
1718 }
1719
1720 if (CommandData->DesktopLen)
1721 {
1722 /* Write back the desktop name */
1723 RtlMoveMemory(CommandData->Desktop,
1724 GetNextVdmCommand->Desktop,
1725 GetNextVdmCommand->DesktopLen);
1726
1727 /* Set the actual length */
1728 CommandData->DesktopLen = GetNextVdmCommand->DesktopLen;
1729 }
1730
1731 if (CommandData->TitleLen)
1732 {
1733 /* Write back the title */
1734 RtlMoveMemory(CommandData->Title,
1735 GetNextVdmCommand->Title,
1736 GetNextVdmCommand->TitleLen);
1737
1738 /* Set the actual length */
1739 CommandData->TitleLen = GetNextVdmCommand->TitleLen;
1740 }
1741
1742 if (CommandData->ReservedLen)
1743 {
1744 /* Write back the reserved parameter */
1745 RtlMoveMemory(CommandData->Reserved,
1746 GetNextVdmCommand->Reserved,
1747 GetNextVdmCommand->ReservedLen);
1748
1749 /* Set the actual length */
1750 CommandData->ReservedLen = GetNextVdmCommand->ReservedLen;
1751 }
1752
1753 /* Write the remaining output parameters */
1754 CommandData->TaskId = GetNextVdmCommand->iTask;
1755 CommandData->CreationFlags = GetNextVdmCommand->dwCreationFlags;
1756 CommandData->CodePage = GetNextVdmCommand->CodePage;
1757 CommandData->ExitCode = GetNextVdmCommand->ExitCode;
1758 CommandData->CurrentDrive = GetNextVdmCommand->CurrentDrive;
1759 CommandData->VDMState = GetNextVdmCommand->VDMState;
1760 CommandData->ComingFromBat = GetNextVdmCommand->fComingFromBat;
1761
1762 /* It was successful */
1763 Success = TRUE;
1764
1765Cleanup:
1766 if (CaptureBuffer != NULL) CsrFreeCaptureBuffer(CaptureBuffer);
1767 return Success;
1768}
1769
1770
1771/*
1772 * @implemented
1773 */
1774DWORD
1775WINAPI
1776GetVDMCurrentDirectories(DWORD cchCurDirs, PCHAR lpszzCurDirs)
1777{
1778 BASE_API_MESSAGE ApiMessage;
1779 PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &ApiMessage.Data.VDMCurrentDirsRequest;
1780 PCSR_CAPTURE_BUFFER CaptureBuffer;
1781
1782 /* Allocate the capture buffer */
1783 CaptureBuffer = CsrAllocateCaptureBuffer(1, cchCurDirs);
1784 if (CaptureBuffer == NULL)
1785 {
1787 return 0;
1788 }
1789
1790 /* Setup the input parameters */
1791 VDMCurrentDirsRequest->cchCurDirs = cchCurDirs;
1792 CsrAllocateMessagePointer(CaptureBuffer,
1793 cchCurDirs,
1794 (PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs);
1795
1796 /* Call CSRSS */
1798 CaptureBuffer,
1800 sizeof(*VDMCurrentDirsRequest));
1801
1802 /* Set the last error */
1803 BaseSetLastNTError(ApiMessage.Status);
1804
1805 if (NT_SUCCESS(ApiMessage.Status))
1806 {
1807 /* Copy the result */
1808 RtlMoveMemory(lpszzCurDirs, VDMCurrentDirsRequest->lpszzCurDirs, cchCurDirs);
1809 }
1810
1811 /* Free the capture buffer */
1812 CsrFreeCaptureBuffer(CaptureBuffer);
1813
1814 /* Return the size if it was successful, or if the buffer was too small */
1815 return (NT_SUCCESS(ApiMessage.Status) || (ApiMessage.Status == STATUS_BUFFER_TOO_SMALL))
1816 ? VDMCurrentDirsRequest->cchCurDirs : 0;
1817}
1818
1819
1820/*
1821 * @implemented (undocumented)
1822 */
1823BOOL
1824WINAPI
1826 IN HANDLE hStartHardwareEvent,
1827 IN HANDLE hEndHardwareEvent,
1828 IN HANDLE hErrorHardwareEvent,
1829 IN DWORD dwUnusedVar,
1830 OUT LPDWORD lpVideoStateLength,
1831 OUT PVOID* lpVideoState, // PVIDEO_HARDWARE_STATE_HEADER*
1832 IN PVOID lpUnusedBuffer,
1833 IN DWORD dwUnusedBufferLength,
1834 IN COORD dwVDMBufferSize,
1835 OUT PVOID* lpVDMBuffer)
1836{
1837 BOOL Success;
1838 CONSOLE_API_MESSAGE ApiMessage;
1839 PCONSOLE_REGISTERVDM RegisterVDMRequest = &ApiMessage.Data.RegisterVDMRequest;
1840 PCSR_CAPTURE_BUFFER CaptureBuffer = NULL;
1841
1842 /* Set up the data to send to the Console Server */
1843 RegisterVDMRequest->ConsoleHandle = NtCurrentPeb()->ProcessParameters->ConsoleHandle;
1844 RegisterVDMRequest->RegisterFlags = dwRegisterFlags;
1845
1846 if (dwRegisterFlags != 0)
1847 {
1848 RegisterVDMRequest->StartHardwareEvent = hStartHardwareEvent;
1849 RegisterVDMRequest->EndHardwareEvent = hEndHardwareEvent;
1850 RegisterVDMRequest->ErrorHardwareEvent = hErrorHardwareEvent;
1851
1852 RegisterVDMRequest->VDMBufferSize = dwVDMBufferSize;
1853
1854#if 0
1855 RegisterVDMRequest->UnusedBufferLength = dwUnusedBufferLength;
1856
1857 /* Allocate a Capture Buffer */
1858 CaptureBuffer = CsrAllocateCaptureBuffer(1, dwUnusedBufferLength);
1859 if (CaptureBuffer == NULL)
1860 {
1861 DPRINT1("CsrAllocateCaptureBuffer failed!\n");
1863 return FALSE;
1864 }
1865
1866 /* Capture the buffer to write */
1867 CsrCaptureMessageBuffer(CaptureBuffer,
1868 (PVOID)lpUnusedBuffer,
1869 dwUnusedBufferLength,
1870 (PVOID*)&RegisterVDMRequest->UnusedBuffer);
1871#endif
1872 }
1873 else
1874 {
1875 // CaptureBuffer = NULL;
1876 }
1877
1878 /* Call the server */
1880 CaptureBuffer,
1882 sizeof(*RegisterVDMRequest));
1883
1884 /* Check for success */
1885 Success = NT_SUCCESS(ApiMessage.Status);
1886
1887 /* Release the capture buffer if needed */
1888 if (CaptureBuffer) CsrFreeCaptureBuffer(CaptureBuffer);
1889
1890 /* Retrieve the results */
1891 if (Success)
1892 {
1893 if (dwRegisterFlags != 0)
1894 {
1895 _SEH2_TRY
1896 {
1897 *lpVideoStateLength = RegisterVDMRequest->VideoStateLength;
1898 *lpVideoState = RegisterVDMRequest->VideoState;
1899 *lpVDMBuffer = RegisterVDMRequest->VDMBuffer;
1900 }
1902 {
1904 Success = FALSE;
1905 }
1906 _SEH2_END;
1907 }
1908 }
1909 else
1910 {
1911 BaseSetLastNTError(ApiMessage.Status);
1912 }
1913
1914 /* Return success status */
1915 return Success;
1916}
1917
1918
1919/*
1920 * @unimplemented
1921 */
1922BOOL
1923WINAPI
1925 DWORD Unknown0
1926 )
1927{
1928 STUB;
1929 return FALSE;
1930}
1931
1932
1933/*
1934 * @unimplemented
1935 */
1936BOOL
1937WINAPI
1939 DWORD Unknown0
1940 )
1941{
1942 STUB;
1943 return FALSE;
1944}
1945
1946
1947/*
1948 * @implemented
1949 */
1950BOOL
1951WINAPI
1952SetVDMCurrentDirectories(DWORD cchCurDirs, PCHAR lpszzCurDirs)
1953{
1954 BASE_API_MESSAGE ApiMessage;
1955 PBASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest = &ApiMessage.Data.VDMCurrentDirsRequest;
1956 PCSR_CAPTURE_BUFFER CaptureBuffer;
1957
1958 /* Allocate the capture buffer */
1959 CaptureBuffer = CsrAllocateCaptureBuffer(1, cchCurDirs);
1960 if (CaptureBuffer == NULL)
1961 {
1963 return FALSE;
1964 }
1965
1966 /* Setup the input parameters */
1967 VDMCurrentDirsRequest->cchCurDirs = cchCurDirs;
1968 CsrCaptureMessageBuffer(CaptureBuffer,
1969 lpszzCurDirs,
1970 cchCurDirs,
1971 (PVOID*)&VDMCurrentDirsRequest->lpszzCurDirs);
1972
1973 /* Call CSRSS */
1975 CaptureBuffer,
1977 sizeof(*VDMCurrentDirsRequest));
1978
1979 /* Free the capture buffer */
1980 CsrFreeCaptureBuffer(CaptureBuffer);
1981
1982 /* Set the last error */
1983 BaseSetLastNTError(ApiMessage.Status);
1984
1985 return NT_SUCCESS(ApiMessage.Status) ? TRUE : FALSE;
1986}
1987
1988/*
1989 * @unimplemented
1990 */
1991DWORD
1992WINAPI
1994 DWORD Unknown0,
1995 DWORD Unknown1
1996 )
1997{
1998 STUB;
1999 return 0;
2000}
2001
2002
2003/*
2004 * @unimplemented
2005 */
2006BOOL
2007WINAPI
2009{
2010 DPRINT1("VDMOperationStarted(%d)\n", Unknown0);
2011
2013 NULL,
2014 0,
2015 Unknown0);
2016}
#define NtCurrentPeb()
Definition: FLS.c:22
#define broken(x)
Definition: _sntprintf.h:21
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
ACPI_PHYSICAL_ADDRESS ACPI_SIZE BOOLEAN Warn UINT32 *TableIdx UINT32 ACPI_TABLE_HEADER *OutTableHeader ACPI_TABLE_HEADER **OutTable ACPI_HANDLE UINT32 ACPI_WALK_CALLBACK ACPI_WALK_CALLBACK void void **ReturnValue UINT32 NameType
Definition: acpixf.h:658
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
HANDLE hUserToken
Definition: install.c:39
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
@ BasepIsFirstVDM
Definition: basemsg.h:30
@ BasepGetNextVDMCommand
Definition: basemsg.h:28
@ BasepGetVDMCurDirs
Definition: basemsg.h:39
@ BasepSetVDMCurDirs
Definition: basemsg.h:38
@ BasepCheckVDM
Definition: basemsg.h:26
@ BasepExitVDM
Definition: basemsg.h:29
@ BasepGetVDMExitCode
Definition: basemsg.h:31
@ BasepUpdateVDMEntry
Definition: basemsg.h:27
@ BasepSetReenterCount
Definition: basemsg.h:32
#define BASESRV_SERVERDLL_INDEX
Definition: basemsg.h:15
#define HandleToUlong(h)
Definition: basetsd.h:79
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
Definition: Header.h:9
@ ConsolepRegisterVDM
Definition: conmsg.h:69
#define CONSRV_SERVERDLL_INDEX
Definition: conmsg.h:15
NTSYSAPI BOOLEAN NTAPI RtlCreateUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
SIZE_T LPSTARTUPINFOW
Definition: cordebug.idl:85
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
#define ERROR_NOT_ENOUGH_MEMORY
Definition: dderror.h:7
#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:33
#define ARRAYSIZE(array)
Definition: filtermapper.c:47
#define CloseHandle
Definition: compat.h:739
#define GetProcessHeap()
Definition: compat.h:736
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define FILE_BEGIN
Definition: compat.h:761
#define INVALID_SET_FILE_POINTER
Definition: compat.h:732
#define GetCurrentDirectoryW(x, y)
Definition: compat.h:756
#define wcsrchr
Definition: compat.h:16
#define CP_ACP
Definition: compat.h:109
#define OPEN_EXISTING
Definition: compat.h:775
#define ReadFile(a, b, c, d, e)
Definition: compat.h:742
#define SetFilePointer
Definition: compat.h:743
#define SetLastError(x)
Definition: compat.h:752
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define HeapAlloc
Definition: compat.h:733
#define GENERIC_READ
Definition: compat.h:135
#define MAX_PATH
Definition: compat.h:34
#define HeapFree(x, y, z)
Definition: compat.h:735
#define CreateFileW
Definition: compat.h:741
#define WideCharToMultiByte
Definition: compat.h:111
#define FILE_SHARE_READ
Definition: compat.h:136
#define ERROR_INVALID_NAME
Definition: compat.h:103
#define HEAP_ZERO_MEMORY
Definition: compat.h:134
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
DWORD WINAPI GetShortPathNameW(IN LPCWSTR lpszLongPath, OUT LPWSTR lpszShortPath, IN DWORD cchBuffer)
Definition: path.c:1833
BOOL WINAPI GetBinaryTypeA(IN LPCSTR lpApplicationName, OUT LPDWORD lpBinaryType)
Definition: vdm.c:1335
#define ENV_NAME_ENTRY(type, name)
Definition: vdm.c:46
static ENV_INFO BasepEnvNameType[]
Definition: vdm.c:49
struct _ENV_INFO ENV_INFO
#define BINARY_PE_EXE32
Definition: vdm.c:19
VOID WINAPI ExitVDM(BOOL IsWow, ULONG iWowTask)
Definition: vdm.c:1392
#define BINARY_DOS
Definition: vdm.c:25
BOOL WINAPI RegisterWowBaseHandlers(DWORD Unknown0)
Definition: vdm.c:1924
ULONG WINAPI BaseIsDosApplication(IN PUNICODE_STRING PathName, IN NTSTATUS Status)
Definition: vdm.c:66
BOOL NTAPI BaseDestroyVDMEnvironment(IN PANSI_STRING AnsiEnv, IN PUNICODE_STRING UnicodeEnv)
Definition: vdm.c:1034
enum _ENV_NAME_TYPE ENV_NAME_TYPE
BOOL WINAPI GetBinaryTypeW(LPCWSTR lpApplicationName, LPDWORD lpBinaryType)
Definition: vdm.c:1243
#define BINARY_PE_EXE64
Definition: vdm.c:21
static UNICODE_STRING BaseDotComSuffixName
Definition: vdm.c:58
ENV_NAME_TYPE WINAPI BaseGetEnvNameType_U(IN PWCHAR Name, IN ULONG NameLength)
Definition: vdm.c:713
BOOL WINAPI CmdBatNotification(DWORD Unknown)
Definition: vdm.c:1379
static UNICODE_STRING BaseDotExeSuffixName
Definition: vdm.c:60
#define BINARY_UNIX_EXE
Definition: vdm.c:26
#define BINARY_UNIX_LIB
Definition: vdm.c:27
#define BINARY_PE_DLL64
Definition: vdm.c:22
#define BINARY_OS216
Definition: vdm.c:24
BOOL WINAPI BaseGetVdmConfigInfo(IN LPCWSTR CommandLineReserved, IN ULONG DosSeqId, IN ULONG BinaryType, IN PUNICODE_STRING CmdLineString, OUT PULONG VdmSize)
Definition: vdm.c:652
BOOL WINAPI BaseCheckForVDM(IN HANDLE ProcessHandle, OUT LPDWORD ExitCode)
Definition: vdm.c:618
DWORD WINAPI VDMConsoleOperation(DWORD Unknown0, DWORD Unknown1)
Definition: vdm.c:1993
_ENV_NAME_TYPE
Definition: vdm.c:31
@ EnvNameSinglePath
Definition: vdm.c:33
@ EnvNameMultiplePath
Definition: vdm.c:34
@ EnvNameNotAPath
Definition: vdm.c:32
BOOL WINAPI RegisterWowExec(DWORD Unknown0)
Definition: vdm.c:1938
BOOL WINAPI BaseUpdateVDMEntry(IN ULONG UpdateIndex, IN OUT PHANDLE WaitHandle, IN ULONG IndexInfo, IN ULONG BinaryType)
Definition: vdm.c:542
BOOL WINAPI SetVDMCurrentDirectories(DWORD cchCurDirs, PCHAR lpszzCurDirs)
Definition: vdm.c:1952
#define IS_PATH_SEPARATOR(x)
#define BINARY_WIN16
Definition: vdm.c:23
BOOL WINAPI RegisterConsoleVDM(IN DWORD dwRegisterFlags, IN HANDLE hStartHardwareEvent, IN HANDLE hEndHardwareEvent, IN HANDLE hErrorHardwareEvent, IN DWORD dwUnusedVar, OUT LPDWORD lpVideoStateLength, OUT PVOID *lpVideoState, IN PVOID lpUnusedBuffer, IN DWORD dwUnusedBufferLength, IN COORD dwVDMBufferSize, OUT PVOID *lpVDMBuffer)
Definition: vdm.c:1825
BOOL WINAPI GetNextVDMCommand(PVDM_COMMAND_INFO CommandData)
Definition: vdm.c:1420
#define BINARY_UNKNOWN
Definition: vdm.c:18
BOOL NTAPI BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment, OUT PANSI_STRING AnsiEnv, OUT PUNICODE_STRING UnicodeEnv)
Definition: vdm.c:744
static DWORD WINAPI InternalIsOS2OrOldWin(HANDLE hFile, IMAGE_DOS_HEADER *mz, IMAGE_OS2_HEADER *ne)
Definition: vdm.c:1064
#define IS_ALPHA(x)
BOOL WINAPI VDMOperationStarted(IN ULONG Unknown0)
Definition: vdm.c:2008
static UNICODE_STRING BaseDotPifSuffixName
Definition: vdm.c:59
static DWORD WINAPI InternalGetBinaryType(HANDLE hFile)
Definition: vdm.c:1116
#define BINARY_PE_DLL32
Definition: vdm.c:20
struct _ENV_INFO * PENV_INFO
NTSTATUS WINAPI BaseCheckVDM(IN ULONG BinaryType, IN PCWCH ApplicationName, IN PCWCH CommandLine, IN PCWCH CurrentDirectory, IN PANSI_STRING AnsiEnvironment, IN PBASE_API_MESSAGE ApiMessage, IN OUT PULONG iTask, IN DWORD CreationFlags, IN LPSTARTUPINFOW StartupInfo, IN HANDLE hUserToken OPTIONAL)
Definition: vdm.c:91
DWORD WINAPI GetVDMCurrentDirectories(DWORD cchCurDirs, PCHAR lpszzCurDirs)
Definition: vdm.c:1776
int WINAPI lstrcmpiW(LPCWSTR str1, LPCWSTR str2)
Definition: locale.c:4261
static const WCHAR Cleanup[]
Definition: register.c:80
@ Success
Definition: eventcreate.c:712
#define _SEH2_END
Definition: filesup.c:22
#define _SEH2_TRY
Definition: filesup.c:19
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
uint8_t ignored[3]
Definition: fsck.fat.h:0
Status
Definition: gdiplustypes.h:25
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
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
@ Unknown
Definition: i8042prt.h:114
#define EXCEPTION_EXECUTE_HANDLER
Definition: excpt.h:85
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define NtCurrentTeb
#define STUB
Definition: kernel32.h:27
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
int _snwprintf(wchar_t *buffer, size_t count, const wchar_t *format,...)
PVOID PVOID PWCHAR PVOID Environment
Definition: env.c:47
PVOID PVOID PWCHAR ApplicationName
Definition: env.c:47
_In_ HANDLE hFile
Definition: mswsock.h:90
_In_ NDIS_STATUS _In_ ULONG _In_ USHORT NumStrings
Definition: ndis.h:4753
@ EventBasicInformation
Definition: extypes.h:357
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
NTSYSAPI NTSTATUS NTAPI RtlCreateEnvironment(_In_ BOOLEAN Inherit, _Out_ PWSTR *Environment)
NTSYSAPI VOID NTAPI RtlDestroyEnvironment(_In_ PWSTR Environment)
u32_t magic(void)
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
#define PAGE_READWRITE
Definition: nt_native.h:1304
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI BOOLEAN NTAPI RtlEqualUnicodeString(PUNICODE_STRING String1, PUNICODE_STRING String2, BOOLEAN CaseInSensitive)
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define MEM_RELEASE
Definition: nt_native.h:1316
NTSYSAPI NTSTATUS NTAPI NtWaitForSingleObject(IN HANDLE hObject, IN BOOLEAN bAlertable, IN PLARGE_INTEGER Timeout)
#define MEM_COMMIT
Definition: nt_native.h:1313
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
CONST WCHAR * PCWCH
Definition: ntbasedef.h:411
#define UNICODE_NULL
#define UNICODE_STRING_MAX_CHARS
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
NTSTATUS NTAPI NtQueryEvent(IN HANDLE EventHandle, IN EVENT_INFORMATION_CLASS EventInformationClass, OUT PVOID EventInformation, IN ULONG EventInformationLength, OUT PULONG ReturnLength OPTIONAL)
Definition: event.c:313
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5230
NTSTATUS NTAPI NtAllocateVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UBaseAddress, IN ULONG_PTR ZeroBits, IN OUT PSIZE_T URegionSize, IN ULONG AllocationType, IN ULONG Protect)
Definition: virtual.c:4492
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
#define STATUS_OBJECT_PATH_INVALID
Definition: ntstatus.h:293
#define L(x)
Definition: ntvdm.h:50
#define IMAGE_FILE_DLL
Definition: pedump.c:169
unsigned short USHORT
Definition: pedump.c:61
#define IMAGE_DOS_SIGNATURE
Definition: pedump.c:89
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:66
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
_Check_return_ _CRTIMP int __cdecl _wcsnicmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
PCSR_CAPTURE_BUFFER NTAPI CsrAllocateCaptureBuffer(_In_ ULONG ArgumentCount, _In_ ULONG BufferSize)
Definition: capture.c:87
ULONG NTAPI CsrAllocateMessagePointer(_Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, _In_ ULONG MessageLength, _Out_ PVOID *CapturedData)
Definition: capture.c:152
VOID NTAPI CsrFreeCaptureBuffer(_In_ _Frees_ptr_ PCSR_CAPTURE_BUFFER CaptureBuffer)
Definition: capture.c:210
VOID NTAPI CsrCaptureMessageBuffer(_Inout_ PCSR_CAPTURE_BUFFER CaptureBuffer, _In_opt_ PVOID MessageBuffer, _In_ ULONG MessageLength, _Out_ PVOID *CapturedData)
Definition: capture.c:189
NTSTATUS NTAPI CsrClientCallServer(_Inout_ PCSR_API_MESSAGE ApiMessage, _Inout_opt_ PCSR_CAPTURE_BUFFER CaptureBuffer, _In_ CSR_API_NUMBER ApiNumber, _In_ ULONG DataLength)
Definition: connect.c:366
#define VDM_FLAG_RETRY
Definition: vdm.h:56
#define BINARY_TYPE_WOW
Definition: vdm.h:40
#define VDM_INC_REENTER_COUNT
Definition: vdm.h:57
#define BINARY_TYPE_SEPARATE_WOW
Definition: vdm.h:39
@ 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 BINARY_TYPE_DOS
Definition: vdm.h:38
#define BINARY_TYPE_EXE
Definition: vdm.h:35
#define BINARY_TYPE_PIF
Definition: vdm.h:37
#define BINARY_TYPE_COM
Definition: vdm.h:36
LOCAL char * filetype(int t)
Definition: tree.c:114
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
PULONG MinorVersion OPTIONAL
Definition: CrossNt.h:68
_In_ BOOLEAN Read
Definition: strmini.h:479
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
NTSTATUS Status
Definition: basemsg.h:279
BASE_GETSET_VDM_CURDIRS VDMCurrentDirsRequest
Definition: basemsg.h:295
BASE_UPDATE_VDM_ENTRY UpdateVDMEntryRequest
Definition: basemsg.h:288
BASE_SET_REENTER_COUNT SetReenterCountRequest
Definition: basemsg.h:293
BASE_IS_FIRST_VDM IsFirstVDMRequest
Definition: basemsg.h:291
BASE_EXIT_VDM ExitVDMRequest
Definition: basemsg.h:290
union _BASE_API_MESSAGE::@3536 Data
BASE_GET_NEXT_VDM_COMMAND GetNextVDMCommandRequest
Definition: basemsg.h:289
BASE_GET_VDM_EXIT_CODE GetVDMExitCodeRequest
Definition: basemsg.h:292
ULONG EnvLen
Definition: basemsg.h:134
USHORT CurDrive
Definition: basemsg.h:146
ULONG CodePage
Definition: basemsg.h:127
ULONG TitleLen
Definition: basemsg.h:139
PCHAR Desktop
Definition: basemsg.h:136
USHORT CurDirectoryLen
Definition: basemsg.h:145
HANDLE StdOut
Definition: basemsg.h:125
PCHAR PifFile
Definition: basemsg.h:131
HANDLE StdErr
Definition: basemsg.h:126
ULONG ReservedLen
Definition: basemsg.h:141
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 dwCreationFlags
Definition: basemsg.h:128
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
NTSTATUS Status
Definition: conmsg.h:919
CONSOLE_REGISTERVDM RegisterVDMRequest
Definition: conmsg.h:1020
union _CONSOLE_API_MESSAGE::@3538 Data
HANDLE EndHardwareEvent
Definition: conmsg.h:880
HANDLE ErrorHardwareEvent
Definition: conmsg.h:881
ULONG UnusedBufferLength
Definition: conmsg.h:891
HANDLE ConsoleHandle
Definition: conmsg.h:877
ULONG VideoStateLength
Definition: conmsg.h:886
HANDLE StartHardwareEvent
Definition: conmsg.h:879
Definition: bl.h:1338
NTSTATUS Status
Definition: csrmsg.h:110
Definition: vdm.c:38
ULONG NameLength
Definition: vdm.c:40
ENV_NAME_TYPE NameType
Definition: vdm.c:39
PWCHAR Name
Definition: vdm.c:41
LPSTR lpTitle
Definition: winbase.h:834
LPSTR lpReserved
Definition: winbase.h:832
LPSTR lpDesktop
Definition: winbase.h:833
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
uint32_t * PULONG
Definition: typedefs.h:59
uint16_t * LPWORD
Definition: typedefs.h:56
#define NTAPI
Definition: typedefs.h:36
PVOID HANDLE
Definition: typedefs.h:73
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
_Must_inspect_result_ _In_ WDFDEVICE _In_ WDFSTRING String
Definition: wdfdevice.h:2433
#define SCS_PIF_BINARY
Definition: winbase.h:240
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define SCS_OS216_BINARY
Definition: winbase.h:239
#define SCS_DOS_BINARY
Definition: winbase.h:238
#define FILE_CURRENT
Definition: winbase.h:113
#define SCS_32BIT_BINARY
Definition: winbase.h:236
#define STARTF_USESTDHANDLES
Definition: winbase.h:499
#define SCS_64BIT_BINARY
Definition: winbase.h:237
#define SCS_WOW_BINARY
Definition: winbase.h:242
#define WINAPI
Definition: msvc.h:6
#define ERROR_BAD_ENVIRONMENT
Definition: winerror.h:113
#define ERROR_INVALID_ACCESS
Definition: winerror.h:115
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
const char * LPCSTR
Definition: xmlstorage.h:183
char * LPSTR
Definition: xmlstorage.h:182
__wchar_t WCHAR
Definition: xmlstorage.h:180
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185