ReactOS 0.4.16-dev-1946-g52006dd
proc.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: dll/win32/kernel32/client/proc.c
5 * PURPOSE: Process functions
6 * PROGRAMMERS: Ariadne (ariadne@xs4all.nl)
7 * UPDATE HISTORY:
8 * Created 01/11/98
9 */
10
11/* INCLUDES ****************************************************************/
12
13#include <k32.h>
14
15#define NDEBUG
16#include <debug.h>
17
18/* GLOBALS *******************************************************************/
19
33{
34 {
36 1,
37 L"AppCertDlls",
39 0,
40 NULL,
41 0
42 }
43};
44
47
49RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
50
51#define CMD_STRING L"cmd /c "
52
53/* FUNCTIONS ****************************************************************/
54
55VOID
58 IN HANDLE StandardHandle,
60{
62 HANDLE DuplicatedHandle;
63 SIZE_T NumberOfBytesWritten;
64
65 /* If there is no handle to duplicate, return immediately */
66 if (!StandardHandle) return;
67
68 /* Duplicate the handle */
70 StandardHandle,
72 &DuplicatedHandle,
73 0,
74 0,
77 if (!NT_SUCCESS(Status)) return;
78
79 /* Write it */
81 Address,
82 &DuplicatedHandle,
83 sizeof(HANDLE),
84 &NumberOfBytesWritten);
85}
86
91 IN LPCWSTR CommandLine,
92 OUT PUNICODE_STRING SubsysCommandLine)
93{
94 UNICODE_STRING CommandLineString, ApplicationNameString;
97
98 /* Convert to unicode strings */
99 RtlInitUnicodeString(&CommandLineString, ApplicationName);
100 RtlInitUnicodeString(&ApplicationNameString, CommandLine);
101
102 /* Allocate buffer for the output string */
103 Length = CommandLineString.MaximumLength + ApplicationNameString.MaximumLength + 32;
104 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
105 RtlInitEmptyUnicodeString(SubsysCommandLine, Buffer, (USHORT)Length);
106 if (!Buffer)
107 {
108 /* Fail, no memory */
110 return FALSE;
111 }
112
113 /* Build the final subsystem command line */
114 RtlAppendUnicodeToString(SubsysCommandLine, SubsystemName);
115 RtlAppendUnicodeStringToString(SubsysCommandLine, &CommandLineString);
116 RtlAppendUnicodeToString(SubsysCommandLine, L" /C ");
117 RtlAppendUnicodeStringToString(SubsysCommandLine, &ApplicationNameString);
118 return TRUE;
119}
120
122WINAPI
124 IN ULONG ImageMinorVersion)
125{
126 /* Accept images for NT 3.1 or higher */
127 if (ImageMajorVersion > 3 ||
128 (ImageMajorVersion == 3 && ImageMinorVersion >= 10))
129 {
130 /* ReactOS-specific: Accept images even if they are newer than our internal NT version. */
131 if (ImageMajorVersion > SharedUserData->NtMajorVersion ||
132 (ImageMajorVersion == SharedUserData->NtMajorVersion && ImageMinorVersion > SharedUserData->NtMinorVersion))
133 {
134 DPRINT1("Accepting image version %lu.%lu, although ReactOS is an NT %hu.%hu OS!\n",
135 ImageMajorVersion,
136 ImageMinorVersion,
137 SharedUserData->NtMajorVersion,
138 SharedUserData->NtMinorVersion);
139 }
140
141 return TRUE;
142 }
143
144 return FALSE;
145}
146
148WINAPI
150{
152 CHAR Hash[16];
153
154 /* Get all the MD5 hashes */
156 if (!NT_SUCCESS(Status)) return Status;
157
158 /* Depending on which suite this is, run a bsearch and block the appropriate ones */
160 {
161 DPRINT1("Egad! This is a ReactOS Compute Server and we should prevent you from using certain APIs...but we won't.");
162 }
163 else if (SharedUserData->SuiteMask & VER_SUITE_STORAGE_SERVER)
164 {
165 DPRINT1("Gasp! This is a ReactOS Storage Server and we should prevent you from using certain APIs...but we won't.");
166 }
167 else if (SharedUserData->SuiteMask & VER_SUITE_BLADE)
168 {
169 DPRINT1("Golly! This is a ReactOS Web Blade Server and we should prevent you from using certain APIs...but we won't.");
170 }
171
172 /* Actually, fuck it, don't block anything, we're open source */
173 return STATUS_SUCCESS;
174}
175
177NTAPI
179 IN PWCHAR ComponentName,
180 IN PWCHAR DllName)
181{
182 /* Pretty much the only thing this key is used for, is malware */
185}
186
188NTAPI
195{
196 /* Add this to the certification list */
198}
199
201WINAPI
203{
204 NTSTATUS Status, Status1;
206 UINT Length;
207 HMODULE TrustLibrary;
209 ULONG CertFlag;
210 PLIST_ENTRY NextEntry;
212 UNICODE_STRING CertKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\AppCertDlls");
214
215 /* Try to initialize the certification subsystem */
216 while (!g_AppCertInitialized)
217 {
218 /* Defaults */
220 Buffer = NULL;
221
222 /* Acquire the lock while initializing and see if we lost a race */
224 if (g_AppCertInitialized) break;
225
226 /* On embedded, there is a special DLL */
227 if (SharedUserData->SuiteMask & VER_SUITE_EMBEDDEDNT)
228 {
229 /* Allocate a buffer for the name */
230 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
231 0,
232 MAX_PATH * sizeof(WCHAR) +
233 sizeof(UNICODE_NULL));
234 if (!Buffer)
235 {
236 /* Fail if no memory */
238 }
239 else
240 {
241 /* Now get the system32 directory in our buffer, make sure it fits */
242 Length = GetSystemDirectoryW(Buffer, MAX_PATH - sizeof("EmbdTrst.DLL"));
243 if ((Length) && (Length <= MAX_PATH - sizeof("EmbdTrst.DLL")))
244 {
245 /* Add a slash if needed, and add the embedded cert DLL name */
246 if (Buffer[Length - 1] != '\\') Buffer[Length++] = '\\';
248 L"EmbdTrst.DLL",
249 sizeof(L"EmbdTrst.DLL"));
250
251 /* Try to load it */
252 TrustLibrary = LoadLibraryW(Buffer);
253 if (TrustLibrary)
254 {
255 /* And extract the special function out of it */
256 fEmbeddedCertFunc = (PVOID)GetProcAddress(TrustLibrary,
257 "ImageOkToRunOnEmbeddedNT");
258 }
259 }
260
261 /* If we didn't get this far, set a failure code */
263 }
264 }
265 else
266 {
267 /* Other systems have a registry entry for this */
269 if (NT_SUCCESS(Status1))
270 {
271 /* Close it, we'll query it through Rtl */
273
274 /* Do the query, which will call a special callback */
276 L"Session Manager",
278 NULL,
279 NULL);
281 {
283 }
284 }
285 }
286
287 /* Free any buffer if we had one */
288 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
289
290 /* Check for errors, or a missing embedded/custom certification DLL */
291 if (!NT_SUCCESS(Status) ||
293 {
294 /* The subsystem is not active on this machine, so give up */
297 }
298 else
299 {
300 /* We have certification DLLs active, remember this */
302 }
303
304 /* We are done the initialization phase, release the lock */
307 }
308
309 /* If there's no certification DLLs present, return the failure code */
310 if (!g_HaveAppCerts) return g_AppCertStatus;
311
312 /* Otherwise, assume success and make sure we have *something* */
315
316 /* If the something is an embedded certification DLL, call it and return */
318
319 /* Otherwise we have custom certification DLLs, parse them */
320 NextEntry = BasepAppCertDllsList.Flink;
321 CertFlag = 2;
322 while (NextEntry != &BasepAppCertDllsList)
323 {
324 /* Make sure the entry has a callback */
326 ASSERT(Entry->fPluginCertFunc != NULL);
327
328 /* Call it and check if it failed */
329 Status = Entry->fPluginCertFunc(ApplicationName, 1);
330 if (!NT_SUCCESS(Status)) CertFlag = 3;
331
332 /* Move on */
333 NextEntry = NextEntry->Flink;
334 }
335
336 /* Now loop them again */
337 NextEntry = BasepAppCertDllsList.Flink;
338 while (NextEntry != &BasepAppCertDllsList)
339 {
340 /* Make sure the entry has a callback */
342 ASSERT(Entry->fPluginCertFunc != NULL);
343
344 /* Call it, this time with the flag from the loop above */
345 Status = Entry->fPluginCertFunc(ApplicationName, CertFlag);
346 }
347
348 /* All done, return the status */
349 return Status;
350}
351
353WINAPI
356 IN HANDLE ThreadHandle)
357{
359 ANSI_STRING SaferiReplaceProcessThreadTokens = RTL_CONSTANT_STRING("SaferiReplaceProcessThreadTokens");
360
361 /* Enter the application certification lock */
363
364 /* Check if we already know the function */
366 {
367 /* Call it */
370 ThreadHandle) ?
373 }
374 else
375 {
376 /* Check if the app certification DLL isn't loaded */
377 if (!(gSaferHandle) ||
378 (gSaferHandle == (HMODULE)-1) ||
379 (gSaferHandle == (HMODULE)-2))
380 {
381 /* Then we can't call the function */
383 }
384 else
385 {
386 /* We have the DLL, find the address of the Safer function */
388 &SaferiReplaceProcessThreadTokens,
389 0,
391 if (NT_SUCCESS(Status))
392 {
393 /* Found it, now call it */
396 ThreadHandle) ?
399 }
400 else
401 {
402 /* We couldn't find it, so this must be an unsupported DLL */
406 }
407 }
408 }
409
410 /* Release the lock and return the result */
412 return Status;
413}
414
415VOID
416WINAPI
418{
420
421 /* Sanity checks */
422 ASSERT(Handles != NULL);
423 ASSERT(Handles->Process == NULL || Handles->Process == NtCurrentProcess());
424
425 /* Close the file handle */
426 if (Handles->File)
427 {
428 Status = NtClose(Handles->File);
430 }
431
432 /* Close the section handle */
433 if (Handles->Section)
434 {
435 Status = NtClose(Handles->Section);
437 }
438
439 /* Unmap the section view */
440 if (Handles->ViewBase.QuadPart)
441 {
443 (PVOID)(ULONG_PTR)Handles->ViewBase.QuadPart);
445 }
446}
447
449VOID
450WINAPI
452 _In_ PPROCESS_START_ROUTINE lpStartAddress)
453{
455 {
456 /* Set our Start Address */
459 &lpStartAddress,
460 sizeof(PPROCESS_START_ROUTINE));
461
462 /* Call the Start Routine */
463 ExitThread(lpStartAddress());
464 }
466 {
467 /* Get the Exit code from the SEH Handler */
469 {
470 /* Kill the whole process, usually */
472 }
473 else
474 {
475 /* If running inside CSRSS, kill just this thread */
477 }
478 }
479 _SEH2_END;
480}
481
483WINAPI
486 IN PPEB RemotePeb,
487 IN LPCWSTR ApplicationPathName,
488 IN LPWSTR lpCurrentDirectory,
489 IN LPWSTR lpCommandLine,
490 IN LPVOID lpEnvironment,
491 IN LPSTARTUPINFOW StartupInfo,
492 IN DWORD CreationFlags,
493 IN BOOL InheritHandles,
494 IN ULONG ImageSubsystem,
495 IN PVOID AppCompatData,
496 IN ULONG AppCompatDataSize)
497{
498 WCHAR FullPath[MAX_PATH + 5];
499 PWCHAR Remaining, DllPathString, ScanChar;
500 PRTL_USER_PROCESS_PARAMETERS ProcessParameters, RemoteParameters;
501 PVOID RemoteAppCompatData;
505 ULONG EnviroSize;
506 SIZE_T Size;
507 BOOLEAN HavePebLock = FALSE, Result;
509
510 /* Get the full path name */
511 Size = GetFullPathNameW(ApplicationPathName,
512 MAX_PATH + 4,
513 FullPath,
514 &Remaining);
515 if ((Size) && (Size <= (MAX_PATH + 4)))
516 {
517 /* Get the DLL Path */
518 DllPathString = BaseComputeProcessDllPath(FullPath, lpEnvironment);
519 if (!DllPathString)
520 {
521 /* Fail */
523 return FALSE;
524 }
525
526 /* Initialize Strings */
527 RtlInitUnicodeString(&DllPath, DllPathString);
529 }
530 else
531 {
532 /* Couldn't get the path name. Just take the original path */
533 DllPathString = BaseComputeProcessDllPath((LPWSTR)ApplicationPathName,
534 lpEnvironment);
535 if (!DllPathString)
536 {
537 /* Fail */
539 return FALSE;
540 }
541
542 /* Initialize Strings */
543 RtlInitUnicodeString(&DllPath, DllPathString);
544 RtlInitUnicodeString(&ImageName, ApplicationPathName);
545 }
546
547 /* Initialize Strings */
548 RtlInitUnicodeString(&CommandLine, lpCommandLine);
549 RtlInitUnicodeString(&CurrentDirectory, lpCurrentDirectory);
550
551 /* Initialize more Strings from the Startup Info */
552 if (StartupInfo->lpDesktop)
553 {
554 RtlInitUnicodeString(&Desktop, StartupInfo->lpDesktop);
555 }
556 else
557 {
559 }
560 if (StartupInfo->lpReserved)
561 {
562 RtlInitUnicodeString(&Shell, StartupInfo->lpReserved);
563 }
564 else
565 {
567 }
568 if (StartupInfo->lpTitle)
569 {
570 RtlInitUnicodeString(&Title, StartupInfo->lpTitle);
571 }
572 else
573 {
574 RtlInitUnicodeString(&Title, ApplicationPathName);
575 }
576
577 /* This one is special because the length can differ */
578 Runtime.Buffer = (LPWSTR)StartupInfo->lpReserved2;
579 Runtime.MaximumLength = Runtime.Length = StartupInfo->cbReserved2;
580
581 /* Enforce no app compat data if the pointer was NULL */
582 if (!AppCompatData) AppCompatDataSize = 0;
583
584 /* Create the Parameter Block */
585 ProcessParameters = NULL;
586 DPRINT("ImageName: '%wZ'\n", &ImageName);
587 DPRINT("DllPath : '%wZ'\n", &DllPath);
588 DPRINT("CurDir : '%wZ'\n", &CurrentDirectory);
589 DPRINT("CmdLine : '%wZ'\n", &CommandLine);
590 DPRINT("Title : '%wZ'\n", &Title);
591 DPRINT("Desktop : '%wZ'\n", &Desktop);
592 DPRINT("Shell : '%wZ'\n", &Shell);
593 DPRINT("Runtime : '%wZ'\n", &Runtime);
594 Status = RtlCreateProcessParameters(&ProcessParameters,
595 &ImageName,
596 &DllPath,
597 lpCurrentDirectory ?
599 &CommandLine,
600 lpEnvironment,
601 &Title,
602 &Desktop,
603 &Shell,
604 &Runtime);
605 if (!NT_SUCCESS(Status)) goto FailPath;
606
607 /* Clear the current directory handle if not inheriting */
608 if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL;
609
610 /* Check if the user passed in an environment */
611 if (lpEnvironment)
612 {
613 /* We should've made it part of the parameters block, enforce this */
614 ASSERT(ProcessParameters->Environment == lpEnvironment);
615 lpEnvironment = ProcessParameters->Environment;
616 }
617 else
618 {
619 /* The user did not, so use the one from the current PEB */
620 HavePebLock = TRUE;
622 lpEnvironment = Peb->ProcessParameters->Environment;
623 }
624
625 /* Save pointer and start lookup */
626 ScanChar = lpEnvironment;
627 if (lpEnvironment)
628 {
629 /* Find the environment size */
630 while (*ScanChar++) while (*ScanChar++);
631 EnviroSize = (ULONG)((ULONG_PTR)ScanChar - (ULONG_PTR)lpEnvironment);
632
633 /* Allocate and Initialize new Environment Block */
634 Size = EnviroSize;
635 ProcessParameters->Environment = NULL;
637 (PVOID*)&ProcessParameters->Environment,
638 0,
639 &Size,
642 if (!NT_SUCCESS(Status)) goto FailPath;
643
644 /* Write the Environment Block */
646 ProcessParameters->Environment,
647 lpEnvironment,
648 EnviroSize,
649 NULL);
650
651 /* No longer need the PEB lock anymore */
652 if (HavePebLock)
653 {
654 /* Release it */
656 HavePebLock = FALSE;
657 }
658
659 /* Check if the write failed */
660 if (!NT_SUCCESS(Status)) goto FailPath;
661 }
662
663 /* Write new parameters */
664 ProcessParameters->StartingX = StartupInfo->dwX;
665 ProcessParameters->StartingY = StartupInfo->dwY;
666 ProcessParameters->CountX = StartupInfo->dwXSize;
667 ProcessParameters->CountY = StartupInfo->dwYSize;
668 ProcessParameters->CountCharsX = StartupInfo->dwXCountChars;
669 ProcessParameters->CountCharsY = StartupInfo->dwYCountChars;
670 ProcessParameters->FillAttribute = StartupInfo->dwFillAttribute;
671 ProcessParameters->WindowFlags = StartupInfo->dwFlags;
672 ProcessParameters->ShowWindowFlags = StartupInfo->wShowWindow;
673
674 /* Write the handles only if we have to */
675 if (StartupInfo->dwFlags &
676 (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))
677 {
678 ProcessParameters->StandardInput = StartupInfo->hStdInput;
679 ProcessParameters->StandardOutput = StartupInfo->hStdOutput;
680 ProcessParameters->StandardError = StartupInfo->hStdError;
681 }
682
683 /* Use Special Flags for ConDllInitialize in Kernel32 */
684 if (CreationFlags & DETACHED_PROCESS)
685 {
686 ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
687 }
688 else if (CreationFlags & CREATE_NEW_CONSOLE)
689 {
690 ProcessParameters->ConsoleHandle = HANDLE_CREATE_NEW_CONSOLE;
691 }
692 else if (CreationFlags & CREATE_NO_WINDOW)
693 {
694 ProcessParameters->ConsoleHandle = HANDLE_CREATE_NO_WINDOW;
695 }
696 else
697 {
698 /* Inherit our Console Handle */
699 ProcessParameters->ConsoleHandle = Peb->ProcessParameters->ConsoleHandle;
700
701 /* Make sure that the shell isn't trampling on our handles first */
702 if (!(StartupInfo->dwFlags &
703 (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
704 {
705 /* Copy the handle if we are inheriting or if it's a console handle */
706 if ((InheritHandles) ||
708 {
709 ProcessParameters->StandardInput = Peb->ProcessParameters->StandardInput;
710 }
711 if ((InheritHandles) ||
713 {
714 ProcessParameters->StandardOutput = Peb->ProcessParameters->StandardOutput;
715 }
716 if ((InheritHandles) ||
718 {
719 ProcessParameters->StandardError = Peb->ProcessParameters->StandardError;
720 }
721 }
722 }
723
724 /* Also set the Console Flag */
725 if ((CreationFlags & CREATE_NEW_PROCESS_GROUP) &&
726 (!(CreationFlags & CREATE_NEW_CONSOLE)))
727 {
728 ProcessParameters->ConsoleFlags = 1;
729 }
730
731 /* Check if there's a .local file present */
732 if (ParameterFlags & 1)
733 {
735 }
736
737 /* Check if we failed to open the IFEO key */
738 if (ParameterFlags & 2)
739 {
741 }
742
743 /* Allocate memory for the parameter block */
744 Size = ProcessParameters->Length;
745 RemoteParameters = NULL;
747 (PVOID*)&RemoteParameters,
748 0,
749 &Size,
752 if (!NT_SUCCESS(Status)) goto FailPath;
753
754 /* Set the allocated size */
755 ProcessParameters->MaximumLength = Size;
756
757 /* Handle some Parameter Flags */
758 ProcessParameters->Flags |= (CreationFlags & PROFILE_USER) ?
760 ProcessParameters->Flags |= (CreationFlags & PROFILE_KERNEL) ?
762 ProcessParameters->Flags |= (CreationFlags & PROFILE_SERVER) ?
764 ProcessParameters->Flags |= (Peb->ProcessParameters->Flags &
766
767 /* Write the Parameter Block */
769 RemoteParameters,
770 ProcessParameters,
771 ProcessParameters->Length,
772 NULL);
773 if (!NT_SUCCESS(Status)) goto FailPath;
774
775 /* Write the PEB Pointer */
777 &RemotePeb->ProcessParameters,
778 &RemoteParameters,
779 sizeof(PVOID),
780 NULL);
781 if (!NT_SUCCESS(Status)) goto FailPath;
782
783 /* Check if there's any app compat data to write */
784 RemoteAppCompatData = NULL;
785 if (AppCompatData)
786 {
787 /* Allocate some space for the application compatibility data */
788 Size = AppCompatDataSize;
790 &RemoteAppCompatData,
791 0,
792 &Size,
795 if (!NT_SUCCESS(Status)) goto FailPath;
796
797 /* Write the application compatibility data */
799 RemoteAppCompatData,
800 AppCompatData,
801 AppCompatDataSize,
802 NULL);
803 if (!NT_SUCCESS(Status)) goto FailPath;
804 }
805
806 /* Write the PEB Pointer to the app compat data (might be NULL) */
808 &RemotePeb->pShimData,
809 &RemoteAppCompatData,
810 sizeof(PVOID),
811 NULL);
812 if (!NT_SUCCESS(Status)) goto FailPath;
813
814 /* Now write Peb->ImageSubSystem */
815 if (ImageSubsystem)
816 {
818 &RemotePeb->ImageSubsystem,
819 &ImageSubsystem,
820 sizeof(ImageSubsystem),
821 NULL);
822 }
823
824 /* Success path */
825 Result = TRUE;
826
827Quickie:
828 /* Cleanup */
829 if (HavePebLock) RtlReleasePebLock();
830 RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath.Buffer);
831 if (ProcessParameters) RtlDestroyProcessParameters(ProcessParameters);
832 return Result;
833FailPath:
834 DPRINT1("Failure to create process parameters: %lx\n", Status);
836 Result = FALSE;
837 goto Quickie;
838}
839
840VOID
841WINAPI
843{
845
846 /* Read the UNICODE_STRING from the PEB */
847 BaseUnicodeCommandLine = NtCurrentPeb()->ProcessParameters->CommandLine;
848
849 /* Convert to ANSI_STRING for the *A callers */
852 TRUE);
853 if (!NT_SUCCESS(Status)) RtlInitEmptyAnsiString(&BaseAnsiCommandLine, 0, 0);
854}
855
856/* PUBLIC FUNCTIONS ***********************************************************/
857
858/*
859 * @implemented
860 */
861BOOL
862WINAPI
864 OUT PDWORD_PTR lpProcessAffinityMask,
865 OUT PDWORD_PTR lpSystemAffinityMask)
866{
867 PROCESS_BASIC_INFORMATION ProcessInfo;
869
870 /* Query information on the process from the kernel */
873 &ProcessInfo,
874 sizeof(ProcessInfo),
875 NULL);
876 if (!NT_SUCCESS(Status))
877 {
878 /* Fail */
880 return FALSE;
881 }
882
883 /* Copy the affinity mask, and get the system one from our shared data */
884 *lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask;
886 return TRUE;
887}
888
889/*
890 * @implemented
891 */
892BOOL
893WINAPI
895 IN DWORD_PTR dwProcessAffinityMask)
896{
898
899 /* Directly set the affinity mask */
902 (PVOID)&dwProcessAffinityMask,
903 sizeof(dwProcessAffinityMask));
904 if (!NT_SUCCESS(Status))
905 {
906 /* Handle failure */
908 return FALSE;
909 }
910
911 /* Everything was ok */
912 return TRUE;
913}
914
915/*
916 * @implemented
917 */
918BOOL
919WINAPI
921 OUT LPDWORD lpdwFlags)
922{
923 BASE_API_MESSAGE ApiMessage;
924 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &ApiMessage.Data.ShutdownParametersRequest;
925
926 /* Ask CSRSS for shutdown information */
928 NULL,
930 sizeof(*ShutdownParametersRequest));
931 if (!NT_SUCCESS(ApiMessage.Status))
932 {
933 /* Return the failure from CSRSS */
934 BaseSetLastNTError(ApiMessage.Status);
935 return FALSE;
936 }
937
938 /* Get the data back */
939 *lpdwLevel = ShutdownParametersRequest->ShutdownLevel;
940 *lpdwFlags = ShutdownParametersRequest->ShutdownFlags;
941 return TRUE;
942}
943
944/*
945 * @implemented
946 */
947BOOL
948WINAPI
951{
952 BASE_API_MESSAGE ApiMessage;
953 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &ApiMessage.Data.ShutdownParametersRequest;
954
955 /* Write the data into the CSRSS request and send it */
956 ShutdownParametersRequest->ShutdownLevel = dwLevel;
957 ShutdownParametersRequest->ShutdownFlags = dwFlags;
959 NULL,
961 sizeof(*ShutdownParametersRequest));
962 if (!NT_SUCCESS(ApiMessage.Status))
963 {
964 /* Return the failure from CSRSS */
965 BaseSetLastNTError(ApiMessage.Status);
966 return FALSE;
967 }
968
969 /* All went well */
970 return TRUE;
971}
972
973/*
974 * @implemented
975 */
976BOOL
977WINAPI
979 OUT PSIZE_T lpMinimumWorkingSetSize,
980 OUT PSIZE_T lpMaximumWorkingSetSize,
982{
983 QUOTA_LIMITS_EX QuotaLimits;
985
986 /* Query the kernel about this */
989 &QuotaLimits,
990 sizeof(QuotaLimits),
991 NULL);
992 if (!NT_SUCCESS(Status))
993 {
994 /* Return error */
996 return FALSE;
997 }
998
999 /* Copy the quota information out */
1000 *lpMinimumWorkingSetSize = QuotaLimits.MinimumWorkingSetSize;
1001 *lpMaximumWorkingSetSize = QuotaLimits.MaximumWorkingSetSize;
1002 *Flags = QuotaLimits.Flags;
1003 return TRUE;
1004}
1005
1006/*
1007 * @implemented
1008 */
1009BOOL
1010WINAPI
1012 OUT PSIZE_T lpMinimumWorkingSetSize,
1013 OUT PSIZE_T lpMaximumWorkingSetSize)
1014{
1015 DWORD Dummy;
1017 lpMinimumWorkingSetSize,
1018 lpMaximumWorkingSetSize,
1019 &Dummy);
1020}
1021
1022/*
1023 * @implemented
1024 */
1025BOOL
1026WINAPI
1028 IN SIZE_T dwMinimumWorkingSetSize,
1029 IN SIZE_T dwMaximumWorkingSetSize,
1030 IN DWORD Flags)
1031{
1032 QUOTA_LIMITS_EX QuotaLimits;
1033 NTSTATUS Status, ReturnStatus;
1034 BOOL Result;
1035 PVOID State;
1037
1038 /* Zero out the input structure */
1039 RtlZeroMemory(&QuotaLimits, sizeof(QuotaLimits));
1040
1041 /* Check if the caller sent any limits */
1042 if ((dwMinimumWorkingSetSize) && (dwMaximumWorkingSetSize))
1043 {
1044 /* Write the quota information */
1045 QuotaLimits.MinimumWorkingSetSize = dwMinimumWorkingSetSize;
1046 QuotaLimits.MaximumWorkingSetSize = dwMaximumWorkingSetSize;
1047 QuotaLimits.Flags = Flags;
1048
1049 /* Acquire the required privilege */
1051
1052 /* Request the new quotas */
1053 ReturnStatus = NtSetInformationProcess(hProcess,
1055 &QuotaLimits,
1056 sizeof(QuotaLimits));
1057 Result = NT_SUCCESS(ReturnStatus);
1058 if (NT_SUCCESS(Status))
1059 {
1060 /* Release the privilege and set succes code */
1061 ASSERT(State != NULL);
1063 State = NULL;
1064 }
1065 }
1066 else
1067 {
1068 /* No limits, fail the call */
1069 ReturnStatus = STATUS_INVALID_PARAMETER;
1070 Result = FALSE;
1071 }
1072
1073 /* Return result code, set error code if this was a failure */
1074 if (!Result) BaseSetLastNTError(ReturnStatus);
1075 return Result;
1076}
1077
1078/*
1079 * @implemented
1080 */
1081BOOL
1082WINAPI
1084 IN SIZE_T dwMinimumWorkingSetSize,
1085 IN SIZE_T dwMaximumWorkingSetSize)
1086{
1087 /* Call the newer API */
1089 dwMinimumWorkingSetSize,
1090 dwMaximumWorkingSetSize,
1091 0);
1092}
1093
1094/*
1095 * @implemented
1096 */
1097BOOL
1098WINAPI
1100 IN LPFILETIME lpCreationTime,
1101 IN LPFILETIME lpExitTime,
1102 IN LPFILETIME lpKernelTime,
1103 IN LPFILETIME lpUserTime)
1104{
1107
1108 /* Query the times */
1111 &Kut,
1112 sizeof(Kut),
1113 NULL);
1114 if (!NT_SUCCESS(Status))
1115 {
1116 /* Handle failure */
1118 return FALSE;
1119 }
1120
1121 /* Copy all the times and return success */
1122 lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
1123 lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
1124 lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
1125 lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
1126 lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
1127 lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
1128 lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
1129 lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
1130 return TRUE;
1131}
1132
1133/*
1134 * @implemented
1135 */
1136HANDLE
1137WINAPI
1139{
1140 return (HANDLE)NtCurrentProcess();
1141}
1142
1143/*
1144 * @implemented
1145 */
1146HANDLE
1147WINAPI
1149{
1150 return (HANDLE)NtCurrentThread();
1151}
1152
1153/*
1154 * @implemented
1155 */
1156DWORD
1157WINAPI
1159{
1161}
1162
1163/*
1164 * @implemented
1165 */
1166BOOL
1167WINAPI
1169 IN LPDWORD lpExitCode)
1170{
1171 PROCESS_BASIC_INFORMATION ProcessBasic;
1173
1174 /* Ask the kernel */
1177 &ProcessBasic,
1178 sizeof(ProcessBasic),
1179 NULL);
1180 if (!NT_SUCCESS(Status))
1181 {
1182 /* We failed, was this because this is a VDM process? */
1183 if (BaseCheckForVDM(hProcess, lpExitCode) != FALSE) return TRUE;
1184
1185 /* Not a VDM process, fail the call */
1187 return FALSE;
1188 }
1189
1190 /* Succes case, return the exit code */
1191 *lpExitCode = (DWORD)ProcessBasic.ExitStatus;
1192 return TRUE;
1193}
1194
1195/*
1196 * @implemented
1197 */
1198DWORD
1199WINAPI
1201{
1202 PROCESS_BASIC_INFORMATION ProcessBasic;
1204
1205 /* Query the kernel */
1208 &ProcessBasic,
1209 sizeof(ProcessBasic),
1210 NULL);
1211 if (!NT_SUCCESS(Status))
1212 {
1213 /* Handle failure */
1215 return 0;
1216 }
1217
1218 /* Return the PID */
1219 return (DWORD)ProcessBasic.UniqueProcessId;
1220}
1221
1222/*
1223 * @implemented
1224 */
1225HANDLE
1226WINAPI
1227OpenProcess(IN DWORD dwDesiredAccess,
1230{
1235
1236 /* Setup the input client ID structure */
1239
1240 /* This is needed just to define the inheritance flags */
1242 NULL,
1244 NULL,
1245 NULL);
1246
1247 /* Now try to open the process */
1249 dwDesiredAccess,
1251 &ClientId);
1252 if (!NT_SUCCESS(Status))
1253 {
1254 /* Handle failure */
1256 return NULL;
1257 }
1258
1259 /* Otherwise return a handle to the process */
1260 return ProcessHandle;
1261}
1262
1263/*
1264 * @implemented
1265 */
1266VOID
1267WINAPI
1269{
1270 /* Write the global function pointer */
1271 UserWaitForInputIdleRoutine = lpfnRegisterWaitForInputIdle;
1272}
1273
1274/*
1275 * @implemented
1276 */
1277VOID
1278WINAPI
1280{
1282
1283 /* Get the process parameters */
1284 Params = NtCurrentPeb()->ProcessParameters;
1285
1286 /* Copy the data out of there */
1287 lpStartupInfo->cb = sizeof(STARTUPINFOW);
1288 lpStartupInfo->lpReserved = Params->ShellInfo.Buffer;
1289 lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
1290 lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
1291 lpStartupInfo->dwX = Params->StartingX;
1292 lpStartupInfo->dwY = Params->StartingY;
1293 lpStartupInfo->dwXSize = Params->CountX;
1294 lpStartupInfo->dwYSize = Params->CountY;
1295 lpStartupInfo->dwXCountChars = Params->CountCharsX;
1296 lpStartupInfo->dwYCountChars = Params->CountCharsY;
1297 lpStartupInfo->dwFillAttribute = Params->FillAttribute;
1298 lpStartupInfo->dwFlags = Params->WindowFlags;
1299 lpStartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
1300 lpStartupInfo->cbReserved2 = Params->RuntimeData.Length;
1301 lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
1302
1303 /* Check if the standard handles are being used for other features */
1304 if (lpStartupInfo->dwFlags & (STARTF_USESTDHANDLES |
1306 STARTF_SHELLPRIVATE))
1307 {
1308 /* These are, so copy the standard handles too */
1309 lpStartupInfo->hStdInput = Params->StandardInput;
1310 lpStartupInfo->hStdOutput = Params->StandardOutput;
1311 lpStartupInfo->hStdError = Params->StandardError;
1312 }
1313}
1314
1315/*
1316 * @implemented
1317 */
1318VOID
1319WINAPI
1321{
1323 ANSI_STRING TitleString, ShellString, DesktopString;
1324 LPSTARTUPINFOA StartupInfo;
1326
1327 /* Get the cached information as well as the PEB parameters */
1328 StartupInfo = BaseAnsiStartupInfo;
1329 Params = NtCurrentPeb()->ProcessParameters;
1330
1331 /* Check if this is the first time we have to get the cached version */
1332 while (!StartupInfo)
1333 {
1334 /* Create new ANSI startup info */
1335 StartupInfo = RtlAllocateHeap(RtlGetProcessHeap(),
1336 0,
1337 sizeof(*StartupInfo));
1338 if (StartupInfo)
1339 {
1340 /* Zero out string pointers in case we fail to create them */
1341 StartupInfo->lpReserved = NULL;
1342 StartupInfo->lpDesktop = NULL;
1343 StartupInfo->lpTitle = NULL;
1344
1345 /* Set the size */
1346 StartupInfo->cb = sizeof(*StartupInfo);
1347
1348 /* Copy what's already stored in the PEB */
1349 StartupInfo->dwX = Params->StartingX;
1350 StartupInfo->dwY = Params->StartingY;
1351 StartupInfo->dwXSize = Params->CountX;
1352 StartupInfo->dwYSize = Params->CountY;
1353 StartupInfo->dwXCountChars = Params->CountCharsX;
1354 StartupInfo->dwYCountChars = Params->CountCharsY;
1355 StartupInfo->dwFillAttribute = Params->FillAttribute;
1356 StartupInfo->dwFlags = Params->WindowFlags;
1357 StartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
1358 StartupInfo->cbReserved2 = Params->RuntimeData.Length;
1359 StartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
1360 StartupInfo->hStdInput = Params->StandardInput;
1361 StartupInfo->hStdOutput = Params->StandardOutput;
1362 StartupInfo->hStdError = Params->StandardError;
1363
1364 /* Copy shell info string */
1365 Status = RtlUnicodeStringToAnsiString(&ShellString,
1366 &Params->ShellInfo,
1367 TRUE);
1368 if (NT_SUCCESS(Status))
1369 {
1370 /* Save it */
1371 StartupInfo->lpReserved = ShellString.Buffer;
1372
1373 /* Copy desktop info string */
1374 Status = RtlUnicodeStringToAnsiString(&DesktopString,
1375 &Params->DesktopInfo,
1376 TRUE);
1377 if (NT_SUCCESS(Status))
1378 {
1379 /* Save it */
1380 StartupInfo->lpDesktop = DesktopString.Buffer;
1381
1382 /* Copy window title string */
1383 Status = RtlUnicodeStringToAnsiString(&TitleString,
1384 &Params->WindowTitle,
1385 TRUE);
1386 if (NT_SUCCESS(Status))
1387 {
1388 /* Save it */
1389 StartupInfo->lpTitle = TitleString.Buffer;
1390
1391 /* We finished with the ANSI version, try to cache it */
1393 StartupInfo,
1394 NULL))
1395 {
1396 /* We were the first thread through, use the data */
1397 break;
1398 }
1399
1400 /* Someone beat us to it, we will use their data instead */
1402
1403 /* We're going to free our own stuff, but not raise */
1404 RtlFreeAnsiString(&TitleString);
1405 }
1406 RtlFreeAnsiString(&DesktopString);
1407 }
1408 RtlFreeAnsiString(&ShellString);
1409 }
1410 RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo);
1411
1412 /* Get the cached information again: either still NULL or set by another thread */
1413 StartupInfo = BaseAnsiStartupInfo;
1414 }
1415 else
1416 {
1417 /* No memory, fail */
1419 }
1420
1421 /* Raise an error unless we got here due to the race condition */
1422 if (!StartupInfo) RtlRaiseStatus(Status);
1423 }
1424
1425 /* Now copy from the cached ANSI version */
1426 lpStartupInfo->cb = StartupInfo->cb;
1427 lpStartupInfo->lpReserved = StartupInfo->lpReserved;
1428 lpStartupInfo->lpDesktop = StartupInfo->lpDesktop;
1429 lpStartupInfo->lpTitle = StartupInfo->lpTitle;
1430 lpStartupInfo->dwX = StartupInfo->dwX;
1431 lpStartupInfo->dwY = StartupInfo->dwY;
1432 lpStartupInfo->dwXSize = StartupInfo->dwXSize;
1433 lpStartupInfo->dwYSize = StartupInfo->dwYSize;
1434 lpStartupInfo->dwXCountChars = StartupInfo->dwXCountChars;
1435 lpStartupInfo->dwYCountChars = StartupInfo->dwYCountChars;
1436 lpStartupInfo->dwFillAttribute = StartupInfo->dwFillAttribute;
1437 lpStartupInfo->dwFlags = StartupInfo->dwFlags;
1438 lpStartupInfo->wShowWindow = StartupInfo->wShowWindow;
1439 lpStartupInfo->cbReserved2 = StartupInfo->cbReserved2;
1440 lpStartupInfo->lpReserved2 = StartupInfo->lpReserved2;
1441
1442 /* Check if the shell is hijacking the handles for other features */
1443 if (lpStartupInfo->dwFlags &
1444 (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))
1445 {
1446 /* It isn't, so we can return the raw values */
1447 lpStartupInfo->hStdInput = StartupInfo->hStdInput;
1448 lpStartupInfo->hStdOutput = StartupInfo->hStdOutput;
1449 lpStartupInfo->hStdError = StartupInfo->hStdError;
1450 }
1451 else
1452 {
1453 /* It is, so make sure nobody uses these as console handles */
1454 lpStartupInfo->hStdInput = INVALID_HANDLE_VALUE;
1455 lpStartupInfo->hStdOutput = INVALID_HANDLE_VALUE;
1456 lpStartupInfo->hStdError = INVALID_HANDLE_VALUE;
1457 }
1458}
1459
1460/*
1461 * @implemented
1462 */
1463BOOL
1464WINAPI
1466 IN LPCVOID lpBaseAddress,
1467 IN SIZE_T nSize)
1468{
1470
1471 /* Call the native function */
1473 if (!NT_SUCCESS(Status))
1474 {
1475 /* Handle failure case */
1477 return FALSE;
1478 }
1479
1480 /* All good */
1481 return TRUE;
1482}
1483
1484/*
1485 * @implemented
1486 */
1487VOID
1488WINAPI
1490{
1491 BASE_API_MESSAGE ApiMessage;
1492 PBASE_EXIT_PROCESS ExitProcessRequest = &ApiMessage.Data.ExitProcessRequest;
1493
1495
1496 _SEH2_TRY
1497 {
1498 /* Acquire the PEB lock */
1500
1501 /* Kill all the threads */
1502 NtTerminateProcess(NULL, uExitCode);
1503
1504 /* Unload all DLLs */
1506
1507 /* Notify Base Server of process termination */
1508 ExitProcessRequest->uExitCode = uExitCode;
1510 NULL,
1512 sizeof(*ExitProcessRequest));
1513
1514 /* Now do it again */
1516 }
1518 {
1519 /* Release the PEB lock */
1521 }
1522 _SEH2_END;
1523
1524 /* should never get here */
1525 ASSERT(0);
1526 while(1);
1527}
1528
1529/*
1530 * @implemented
1531 */
1532BOOL
1533WINAPI
1535 IN UINT uExitCode)
1536{
1538
1539 /* Check if no handle was passed in */
1540 if (!hProcess)
1541 {
1542 /* Set error code */
1544 }
1545 else
1546 {
1547 /* Otherwise, try to terminate the process */
1548 Status = NtTerminateProcess(hProcess, uExitCode);
1549 if (NT_SUCCESS(Status)) return TRUE;
1550
1551 /* It failed, convert error code */
1553 }
1554
1555 /* This is the failure path */
1556 return FALSE;
1557}
1558
1559/*
1560 * @implemented
1561 */
1562VOID
1563WINAPI
1565 LPCSTR lpMessageText)
1566{
1567 PUNICODE_STRING MessageTextU;
1568 ANSI_STRING MessageText;
1570
1571 /* Initialize the string using the static TEB pointer */
1572 MessageTextU = &NtCurrentTeb()->StaticUnicodeString;
1573 RtlInitAnsiString(&MessageText, (LPSTR)lpMessageText);
1574
1575 /* Convert to unicode, or just exit normally if this failed */
1576 Status = RtlAnsiStringToUnicodeString(MessageTextU, &MessageText, FALSE);
1577 if (!NT_SUCCESS(Status)) ExitProcess(0);
1578
1579 /* Call the Wide function */
1580 FatalAppExitW(uAction, MessageTextU->Buffer);
1581}
1582
1583/*
1584 * @implemented
1585 */
1586VOID
1587WINAPI
1589 IN LPCWSTR lpMessageText)
1590{
1594
1595 /* Setup the string to print out */
1596 RtlInitUnicodeString(&UnicodeString, lpMessageText);
1597
1598 /* Display the hard error no matter what */
1600 1,
1601 1,
1603#if DBG
1604 /* On Checked builds, Windows allows the user to cancel the operation */
1606#else
1607 OptionOk,
1608#endif
1609 &Response);
1610
1611 /* Give the user a chance to abort */
1613 {
1614 return;
1615 }
1616
1617 /* Otherwise kill the process */
1618 ExitProcess(0);
1619}
1620
1621/*
1622 * @implemented
1623 */
1624VOID
1625WINAPI
1626FatalExit(IN int ExitCode)
1627{
1628#if DBG
1629 /* On Checked builds, Windows gives the user a nice little debugger UI */
1630 CHAR Action[2];
1631 DbgPrint("FatalExit...\n\n");
1632
1633 /* Check for reactos specific flag (set by rosautotest) */
1635 {
1637 }
1638
1639 while (TRUE)
1640 {
1641 DbgPrompt("A (Abort), B (Break), I (Ignore)? ", Action, sizeof(Action));
1642 switch (Action[0])
1643 {
1644 case 'B': case 'b':
1645 DbgBreakPoint();
1646 break;
1647
1648 case 'A': case 'a':
1649 ExitProcess(ExitCode);
1650
1651 case 'I': case 'i':
1652 return;
1653 }
1654 }
1655#endif
1656 /* On other builds, just kill the process */
1657 ExitProcess(ExitCode);
1658}
1659
1660/*
1661 * @implemented
1662 */
1663DWORD
1664WINAPI
1666{
1668 PROCESS_PRIORITY_CLASS DECLSPEC_ALIGN(4) PriorityClass;
1669
1670 /* Query the kernel */
1673 &PriorityClass,
1674 sizeof(PriorityClass),
1675 NULL);
1676 if (NT_SUCCESS(Status))
1677 {
1678 /* Handle the conversion from NT to Win32 classes */
1679 switch (PriorityClass.PriorityClass)
1680 {
1687 }
1688 }
1689
1690 /* Failure path */
1692 return 0;
1693}
1694
1695/*
1696 * @implemented
1697 */
1698BOOL
1699WINAPI
1701 IN DWORD dwPriorityClass)
1702{
1704 PVOID State = NULL;
1705 PROCESS_PRIORITY_CLASS PriorityClass;
1706
1707 /* Handle conversion from Win32 to NT priority classes */
1708 switch (dwPriorityClass)
1709 {
1712 break;
1713
1716 break;
1717
1720 break;
1721
1724 break;
1725
1728 break;
1729
1731 /* Try to acquire the privilege. If it fails, just use HIGH */
1734 PriorityClass.PriorityClass += (State != NULL);
1735 break;
1736
1737 default:
1738 /* Unrecognized priority classes don't make it to the kernel */
1740 return FALSE;
1741 }
1742
1743 /* Send the request to the kernel, and don't touch the foreground flag */
1744 PriorityClass.Foreground = FALSE;
1747 &PriorityClass,
1748 sizeof(PROCESS_PRIORITY_CLASS));
1749
1750 /* Release the privilege if we had it */
1752 if (!NT_SUCCESS(Status))
1753 {
1754 /* Handle error path */
1756 return FALSE;
1757 }
1758
1759 /* All done */
1760 return TRUE;
1761}
1762
1763/*
1764 * @implemented
1765 */
1766DWORD
1767WINAPI
1769{
1770 DWORD Version = 0;
1771 PIMAGE_NT_HEADERS NtHeader;
1772 PIMAGE_DOS_HEADER DosHeader;
1773 PPEB Peb;
1774 PROCESS_BASIC_INFORMATION ProcessBasicInfo;
1779 USHORT VersionData[2];
1781
1782 /* We'll be accessing stuff that can fault, so protect everything with SEH */
1783 _SEH2_TRY
1784 {
1785 /* It this an in-process or out-of-process request? */
1786 if (!(ProcessId) || (GetCurrentProcessId() == ProcessId))
1787 {
1788 /* It's in-process, so just read our own header */
1789 NtHeader = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
1790 if (!NtHeader)
1791 {
1792 /* Unable to read the NT header, something is wrong here... */
1794 goto Error;
1795 }
1796
1797 /* Get the version straight out of the NT header */
1800 }
1801 else
1802 {
1803 /* Out-of-process, so open it */
1805 FALSE,
1806 ProcessId);
1807 if (!ProcessHandle) _SEH2_YIELD(return 0);
1808
1809 /* Try to find out where its PEB lives */
1812 &ProcessBasicInfo,
1813 sizeof(ProcessBasicInfo),
1814 NULL);
1815
1816 if (!NT_SUCCESS(Status)) goto Error;
1817 Peb = ProcessBasicInfo.PebBaseAddress;
1818
1819 /* Now that we have the PEB, read the image base address out of it */
1822 &BaseAddress,
1823 sizeof(BaseAddress),
1824 NULL);
1825 if (!Result) goto Error;
1826
1827 /* Now read the e_lfanew (offset to NT header) from the base */
1828 DosHeader = BaseAddress;
1830 &DosHeader->e_lfanew,
1831 &e_lfanew,
1832 sizeof(e_lfanew),
1833 NULL);
1834 if (!Result) goto Error;
1835
1836 /* And finally, read the NT header itself by adding the offset */
1837 NtHeader = (PVOID)((ULONG_PTR)BaseAddress + e_lfanew);
1840 &VersionData,
1841 sizeof(VersionData),
1842 NULL);
1843 if (!Result) goto Error;
1844
1845 /* Get the version straight out of the NT header */
1846 Version = MAKELONG(VersionData[0], VersionData[1]);
1847
1848Error:
1849 /* If there was an error anywhere, set the last error */
1851 }
1852 }
1854 {
1855 /* Close the process handle */
1857 }
1858 _SEH2_END;
1859
1860 /* And return the version data */
1861 return Version;
1862}
1863
1864/*
1865 * @implemented
1866 */
1867BOOL
1868WINAPI
1870 OUT PIO_COUNTERS lpIoCounters)
1871{
1873
1874 /* Query the kernel. Structures are identical, so let it do the copy too. */
1877 lpIoCounters,
1878 sizeof(IO_COUNTERS),
1879 NULL);
1880 if (!NT_SUCCESS(Status))
1881 {
1882 /* Handle error path */
1884 return FALSE;
1885 }
1886
1887 /* All done */
1888 return TRUE;
1889}
1890
1891/*
1892 * @implemented
1893 */
1894BOOL
1895WINAPI
1897 OUT PBOOL pDisablePriorityBoost)
1898{
1901
1902 /* Query the kernel */
1906 sizeof(PriorityBoost),
1907 NULL);
1908 if (NT_SUCCESS(Status))
1909 {
1910 /* Convert from ULONG to a BOOL */
1911 *pDisablePriorityBoost = PriorityBoost ? TRUE : FALSE;
1912 return TRUE;
1913 }
1914
1915 /* Handle error path */
1917 return FALSE;
1918}
1919
1920/*
1921 * @implemented
1922 */
1923BOOL
1924WINAPI
1926 IN BOOL bDisablePriorityBoost)
1927{
1930
1931 /* Enforce that this is a BOOL, and send it to the kernel as a ULONG */
1932 PriorityBoost = (bDisablePriorityBoost ? TRUE : FALSE);
1936 sizeof(ULONG));
1937 if (!NT_SUCCESS(Status))
1938 {
1939 /* Handle error path */
1941 return FALSE;
1942 }
1943
1944 /* All done */
1945 return TRUE;
1946}
1947
1948/*
1949 * @implemented
1950 */
1951BOOL
1952WINAPI
1954 OUT PDWORD pdwHandleCount)
1955{
1956 ULONG phc;
1958
1959 /* Query the kernel */
1962 &phc,
1963 sizeof(phc),
1964 NULL);
1965 if (NT_SUCCESS(Status))
1966 {
1967 /* Copy the count and return success */
1968 *pdwHandleCount = phc;
1969 return TRUE;
1970 }
1971
1972 /* Handle error path */
1974 return FALSE;
1975}
1976
1977/*
1978 * @implemented
1979 */
1980BOOL
1981WINAPI
1983 OUT PBOOL Wow64Process)
1984{
1985 ULONG_PTR pbi;
1987
1988 /* Query the kernel */
1991 &pbi,
1992 sizeof(pbi),
1993 NULL);
1994 if (!NT_SUCCESS(Status))
1995 {
1996 /* Handle error path */
1998 return FALSE;
1999 }
2000
2001 /* Enforce this is a BOOL, and return success */
2002 *Wow64Process = (pbi != 0);
2003 return TRUE;
2004}
2005
2006/*
2007 * @implemented
2008 */
2009LPSTR
2010WINAPI
2012{
2014}
2015
2016/*
2017 * @implemented
2018 */
2019LPWSTR
2020WINAPI
2022{
2024}
2025
2026/*
2027 * @implemented
2028 */
2029BOOL
2030NTAPI
2032 IN LPCVOID lpBaseAddress,
2034 IN SIZE_T nSize,
2035 OUT SIZE_T* lpNumberOfBytesRead)
2036{
2038
2039 /* Do the read */
2041 (PVOID)lpBaseAddress,
2042 lpBuffer,
2043 nSize,
2044 &nSize);
2045
2046 /* In user-mode, this parameter is optional */
2047 if (lpNumberOfBytesRead) *lpNumberOfBytesRead = nSize;
2048 if (!NT_SUCCESS(Status))
2049 {
2050 /* We failed */
2052 return FALSE;
2053 }
2054
2055 /* Return success */
2056 return TRUE;
2057}
2058
2059/*
2060 * @implemented
2061 */
2062BOOL
2063NTAPI
2065 IN LPVOID lpBaseAddress,
2067 IN SIZE_T nSize,
2068 OUT SIZE_T *lpNumberOfBytesWritten)
2069{
2071 ULONG OldValue;
2073 PVOID Base;
2075
2076 /* Set parameters for protect call */
2077 RegionSize = nSize;
2078 Base = lpBaseAddress;
2079
2080 /* Check the current status */
2082 &Base,
2083 &RegionSize,
2085 &OldValue);
2086 if (NT_SUCCESS(Status))
2087 {
2088 /* Check if we are unprotecting */
2089 UnProtect = OldValue & (PAGE_READWRITE |
2093 if (!UnProtect)
2094 {
2095 /* Set the new protection */
2097 &Base,
2098 &RegionSize,
2099 OldValue,
2100 &OldValue);
2101
2102 /* Write the memory */
2104 lpBaseAddress,
2106 nSize,
2107 &nSize);
2108
2109 /* In Win32, the parameter is optional, so handle this case */
2110 if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = nSize;
2111
2112 if (!NT_SUCCESS(Status))
2113 {
2114 /* We failed */
2116 return FALSE;
2117 }
2118
2119 /* Flush the ITLB */
2120 NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
2121 return TRUE;
2122 }
2123 else
2124 {
2125 /* Check if we were read only */
2126 if (OldValue & (PAGE_NOACCESS | PAGE_READONLY))
2127 {
2128 /* Restore protection and fail */
2130 &Base,
2131 &RegionSize,
2132 OldValue,
2133 &OldValue);
2135
2136 /* Note: This is what Windows returns and code depends on it */
2138 }
2139
2140 /* Otherwise, do the write */
2142 lpBaseAddress,
2144 nSize,
2145 &nSize);
2146
2147 /* In Win32, the parameter is optional, so handle this case */
2148 if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = nSize;
2149
2150 /* And restore the protection */
2152 &Base,
2153 &RegionSize,
2154 OldValue,
2155 &OldValue);
2156 if (!NT_SUCCESS(Status))
2157 {
2158 /* We failed */
2160
2161 /* Note: This is what Windows returns and code depends on it */
2163 }
2164
2165 /* Flush the ITLB */
2166 NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
2167 return TRUE;
2168 }
2169 }
2170 else
2171 {
2172 /* We failed */
2174 return FALSE;
2175 }
2176}
2177
2178/*
2179 * @implemented
2180 */
2181BOOL
2182WINAPI
2184 OUT PDWORD pSessionId)
2185{
2186 PROCESS_SESSION_INFORMATION SessionInformation;
2191
2192 /* Do a quick check if the pointer is not writable */
2193 if (IsBadWritePtr(pSessionId, sizeof(DWORD)))
2194 {
2195 /* Fail fast */
2197 return FALSE;
2198 }
2199
2200 /* Open the process passed in by ID */
2207 &ClientId);
2208 if (NT_SUCCESS(Status))
2209 {
2210 /* Query the session ID from the kernel */
2213 &SessionInformation,
2214 sizeof(SessionInformation),
2215 NULL);
2216
2217 /* Close the handle and check if we succeeded */
2219 if (NT_SUCCESS(Status))
2220 {
2221 /* Return the session ID */
2222 *pSessionId = SessionInformation.SessionId;
2223 return TRUE;
2224 }
2225 }
2226
2227 /* Set error code and fail */
2229 return FALSE;
2230}
2231
2232
2233#define AddToHandle(x,y) ((x) = (HANDLE)((ULONG_PTR)(x) | (y)))
2234#define RemoveFromHandle(x,y) ((x) = (HANDLE)((ULONG_PTR)(x) & ~(y)))
2236
2237/*
2238 * @implemented
2239 */
2240BOOL
2241WINAPI
2243 IN LPCWSTR lpApplicationName,
2244 IN LPWSTR lpCommandLine,
2245 IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
2246 IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
2247 IN BOOL bInheritHandles,
2248 IN DWORD dwCreationFlags,
2249 IN LPVOID lpEnvironment,
2250 IN LPCWSTR lpCurrentDirectory,
2251 IN LPSTARTUPINFOW lpStartupInfo,
2252 IN LPPROCESS_INFORMATION lpProcessInformation,
2253 OUT PHANDLE hNewToken)
2254{
2255 //
2256 // Core variables used for creating the initial process and thread
2257 //
2258 SECURITY_ATTRIBUTES LocalThreadAttributes, LocalProcessAttributes;
2259 OBJECT_ATTRIBUTES LocalObjectAttributes;
2261 SECTION_IMAGE_INFORMATION ImageInformation;
2264 ULONG NoWindow, StackSize, ErrorCode, Flags;
2266 USHORT ImageMachine;
2267 ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse;
2268 ULONG_PTR ErrorParameters[2];
2269 BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege;
2270 BOOLEAN QuerySection, SkipSaferAndAppCompat;
2272 BASE_API_MESSAGE CsrMsg[2];
2273 PBASE_CREATE_PROCESS CreateProcessMsg;
2274 PCSR_CAPTURE_BUFFER CaptureBuffer;
2275 PVOID BaseAddress, PrivilegeState, RealTimePrivilegeState;
2276 HANDLE DebugHandle, TokenHandle, JobHandle, KeyHandle, ThreadHandle;
2277 HANDLE FileHandle, SectionHandle, ProcessHandle;
2279 PROCESS_PRIORITY_CLASS PriorityClass;
2280 NTSTATUS Status, AppCompatStatus, SaferStatus, IFEOStatus, ImageDbgStatus;
2281 PPEB Peb, RemotePeb;
2282 PTEB Teb;
2283 INITIAL_TEB InitialTeb;
2284 PVOID TibValue;
2285 PIMAGE_NT_HEADERS NtHeaders;
2286 STARTUPINFOW StartupInfo;
2287 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
2288 UNICODE_STRING DebuggerString;
2289 BOOL Result;
2290 //
2291 // Variables used for command-line and argument parsing
2292 //
2293 PCHAR pcScan;
2294 SIZE_T n;
2295 WCHAR SaveChar;
2296 ULONG Length, FileAttribs, CmdQuoteLength;
2297 ULONG ResultSize;
2298 SIZE_T EnvironmentLength, CmdLineLength;
2299 PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory;
2300 PWCHAR NullBuffer, ScanString, NameBuffer, SearchPath, DebuggerCmdLine;
2301 ANSI_STRING AnsiEnv;
2302 UNICODE_STRING UnicodeEnv, PathName;
2303 BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName, HasQuotes;
2304
2305 //
2306 // Variables used for Fusion/SxS (Side-by-Side Assemblies)
2307 //
2308 RTL_PATH_TYPE SxsPathType, PathType;
2309#if _SXS_SUPPORT_ENABLED_
2310 PRTL_BUFFER ByteBuffer;
2311 PRTL_UNICODE_STRING_BUFFER ThisBuffer, Buffer, SxsStaticBuffers[5];
2312 PRTL_UNICODE_STRING_BUFFER* BufferHead, SxsStringBuffer;
2313 RTL_UNICODE_STRING_BUFFER SxsWin32ManifestPath, SxsNtManifestPath;
2314 RTL_UNICODE_STRING_BUFFER SxsWin32PolicyPath, SxsNtPolicyPath;
2315 RTL_UNICODE_STRING_BUFFER SxsWin32AssemblyDirectory;
2316 BASE_MSG_SXS_HANDLES MappedHandles, Handles, FileHandles;
2317 PVOID CapturedStrings[3];
2318 SXS_WIN32_NT_PATH_PAIR ExePathPair, ManifestPathPair, PolicyPathPair;
2319 SXS_OVERRIDE_MANIFEST OverrideManifest;
2320 UNICODE_STRING FreeString, SxsNtExePath;
2321 PWCHAR SxsConglomeratedBuffer, StaticBuffer;
2322 ULONG ConglomeratedBufferSizeBytes, StaticBufferSize, i;
2323#endif
2325
2326 //
2327 // Variables used for path conversion (and partially Fusion/SxS)
2328 //
2329 PWCHAR FilePart, PathBuffer, FreeBuffer;
2330 BOOLEAN TranslationStatus;
2331 RTL_RELATIVE_NAME_U SxsWin32RelativePath;
2332 UNICODE_STRING PathBufferString, SxsWin32ExePath;
2333
2334 //
2335 // Variables used by Application Compatibility (and partially Fusion/SxS)
2336 //
2337 PVOID AppCompatSxsData, AppCompatData;
2338 ULONG AppCompatSxsDataSize, AppCompatDataSize;
2339 //
2340 // Variables used by VDM (Virtual Dos Machine) and WOW32 (16-bit Support)
2341 //
2342 ULONG BinarySubType, VdmBinaryType, VdmTask, VdmReserve;
2343 ULONG VdmUndoLevel;
2344 BOOLEAN UseVdmReserve;
2345 HANDLE VdmWaitObject;
2346 ANSI_STRING VdmAnsiEnv;
2347 UNICODE_STRING VdmString, VdmUnicodeEnv;
2348 BOOLEAN IsWowApp;
2349 PBASE_CHECK_VDM CheckVdmMsg;
2350
2351 /* Zero out the initial core variables and handles */
2352 QuerySection = FALSE;
2353 InJob = FALSE;
2354 SkipSaferAndAppCompat = FALSE;
2355 ParameterFlags = 0;
2356 Flags = 0;
2357 DebugHandle = NULL;
2358 JobHandle = NULL;
2359 TokenHandle = NULL;
2360 FileHandle = NULL;
2361 SectionHandle = NULL;
2363 ThreadHandle = NULL;
2365 BaseAddress = (PVOID)1;
2366
2367 /* Zero out initial SxS and Application Compatibility state */
2368 AppCompatData = NULL;
2369 AppCompatDataSize = 0;
2370 AppCompatSxsData = NULL;
2371 AppCompatSxsDataSize = 0;
2372 CaptureBuffer = NULL;
2373#if _SXS_SUPPORT_ENABLED_
2374 SxsConglomeratedBuffer = NULL;
2375#endif
2376 FusionFlags = 0;
2377
2378 /* Zero out initial parsing variables -- others are initialized later */
2379 DebuggerCmdLine = NULL;
2380 PathBuffer = NULL;
2381 SearchPath = NULL;
2382 NullBuffer = NULL;
2383 FreeBuffer = NULL;
2384 NameBuffer = NULL;
2386 FilePart = NULL;
2387 DebuggerString.Buffer = NULL;
2388 HasQuotes = FALSE;
2389 QuotedCmdLine = NULL;
2390
2391 /* Zero out initial VDM state */
2392 VdmAnsiEnv.Buffer = NULL;
2393 VdmUnicodeEnv.Buffer = NULL;
2394 VdmString.Buffer = NULL;
2395 VdmTask = 0;
2396 VdmUndoLevel = 0;
2397 VdmBinaryType = 0;
2398 VdmReserve = 0;
2399 VdmWaitObject = NULL;
2400 UseVdmReserve = FALSE;
2401 IsWowApp = FALSE;
2402
2403 /* Set message structures */
2404 CreateProcessMsg = &CsrMsg[0].Data.CreateProcessRequest;
2405 CheckVdmMsg = &CsrMsg[1].Data.CheckVDMRequest;
2406
2407 /* Clear the more complex structures by zeroing out their entire memory */
2408 RtlZeroMemory(&Context, sizeof(Context));
2409#if _SXS_SUPPORT_ENABLED_
2410 RtlZeroMemory(&FileHandles, sizeof(FileHandles));
2411 RtlZeroMemory(&MappedHandles, sizeof(MappedHandles));
2412 RtlZeroMemory(&Handles, sizeof(Handles));
2413#endif
2414 RtlZeroMemory(&CreateProcessMsg->Sxs, sizeof(CreateProcessMsg->Sxs));
2415 RtlZeroMemory(&LocalProcessAttributes, sizeof(LocalProcessAttributes));
2416 RtlZeroMemory(&LocalThreadAttributes, sizeof(LocalThreadAttributes));
2417
2418 /* Zero out output arguments as well */
2419 RtlZeroMemory(lpProcessInformation, sizeof(*lpProcessInformation));
2420 if (hNewToken) *hNewToken = NULL;
2421
2422 /* Capture the special window flag */
2423 NoWindow = dwCreationFlags & CREATE_NO_WINDOW;
2424 dwCreationFlags &= ~CREATE_NO_WINDOW;
2425
2426#if _SXS_SUPPORT_ENABLED_
2427 /* Setup the SxS static string arrays and buffers */
2428 SxsStaticBuffers[0] = &SxsWin32ManifestPath;
2429 SxsStaticBuffers[1] = &SxsWin32PolicyPath;
2430 SxsStaticBuffers[2] = &SxsWin32AssemblyDirectory;
2431 SxsStaticBuffers[3] = &SxsNtManifestPath;
2432 SxsStaticBuffers[4] = &SxsNtPolicyPath;
2433 ExePathPair.Win32 = &SxsWin32ExePath;
2434 ExePathPair.Nt = &SxsNtExePath;
2435 ManifestPathPair.Win32 = &SxsWin32ManifestPath.String;
2436 ManifestPathPair.Nt = &SxsNtManifestPath.String;
2437 PolicyPathPair.Win32 = &SxsWin32PolicyPath.String;
2438 PolicyPathPair.Nt = &SxsNtPolicyPath.String;
2439#endif
2440
2441 DPRINT("CreateProcessInternalW: '%S' '%S' %lx\n", lpApplicationName, lpCommandLine, dwCreationFlags);
2442
2443 /* Finally, set our TEB and PEB */
2444 Teb = NtCurrentTeb();
2445 Peb = NtCurrentPeb();
2446
2447 /* This combination is illegal (see MSDN) */
2448 if ((dwCreationFlags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)) ==
2450 {
2451 DPRINT1("Invalid flag combo used\n");
2453 return FALSE;
2454 }
2455
2456 /* Convert the priority class */
2457 if (dwCreationFlags & IDLE_PRIORITY_CLASS)
2458 {
2460 }
2461 else if (dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS)
2462 {
2464 }
2465 else if (dwCreationFlags & NORMAL_PRIORITY_CLASS)
2466 {
2468 }
2469 else if (dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS)
2470 {
2472 }
2473 else if (dwCreationFlags & HIGH_PRIORITY_CLASS)
2474 {
2476 }
2477 else if (dwCreationFlags & REALTIME_PRIORITY_CLASS)
2478 {
2480 PriorityClass.PriorityClass += (BasepIsRealtimeAllowed(FALSE) != NULL);
2481 }
2482 else
2483 {
2485 }
2486
2487 /* Done with the priority masks, so get rid of them */
2488 PriorityClass.Foreground = FALSE;
2489 dwCreationFlags &= ~(NORMAL_PRIORITY_CLASS |
2495
2496 /* You cannot request both a shared and a separate WoW VDM */
2497 if ((dwCreationFlags & CREATE_SEPARATE_WOW_VDM) &&
2498 (dwCreationFlags & CREATE_SHARED_WOW_VDM))
2499 {
2500 /* Fail such nonsensical attempts */
2501 DPRINT1("Invalid WOW flags\n");
2503 return FALSE;
2504 }
2505 else if (!(dwCreationFlags & CREATE_SHARED_WOW_VDM) &&
2507 {
2508 /* A shared WoW VDM was not requested but system enforces separation */
2509 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
2510 }
2511
2512 /* If a shared WoW VDM is used, make sure the process isn't in a job */
2513 if (!(dwCreationFlags & CREATE_SEPARATE_WOW_VDM) &&
2515 {
2516 /* Remove the shared flag and add the separate flag */
2517 dwCreationFlags = (dwCreationFlags &~ CREATE_SHARED_WOW_VDM) |
2519 }
2520
2521 /* Convert the environment */
2522 if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
2523 {
2524 /* Scan the environment to calculate its Unicode size */
2525 AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment;
2526 while ((*pcScan) || (*(pcScan + 1))) ++pcScan;
2527
2528 /* Make sure the environment is not too large */
2529 EnvironmentLength = (pcScan + sizeof(ANSI_NULL) - (PCHAR)lpEnvironment);
2530 if (EnvironmentLength > MAXUSHORT)
2531 {
2532 /* Fail */
2534 return FALSE;
2535 }
2536
2537 /* Create our ANSI String */
2538 AnsiEnv.Length = (USHORT)EnvironmentLength;
2539 AnsiEnv.MaximumLength = AnsiEnv.Length + sizeof(ANSI_NULL);
2540
2541 /* Allocate memory for the Unicode Environment */
2542 UnicodeEnv.Buffer = NULL;
2543 RegionSize = AnsiEnv.MaximumLength * sizeof(WCHAR);
2545 (PVOID)&UnicodeEnv.Buffer,
2546 0,
2547 &RegionSize,
2548 MEM_COMMIT,
2550 if (!NT_SUCCESS(Status))
2551 {
2552 /* Fail */
2554 return FALSE;
2555 }
2556
2557 /* Use the allocated size and convert */
2558 UnicodeEnv.MaximumLength = (USHORT)RegionSize;
2559 Status = RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE);
2560 if (!NT_SUCCESS(Status))
2561 {
2562 /* Fail */
2564 (PVOID)&UnicodeEnv.Buffer,
2565 &RegionSize,
2566 MEM_RELEASE);
2568 return FALSE;
2569 }
2570
2571 /* Now set the Unicode environment as the environment string pointer */
2572 lpEnvironment = UnicodeEnv.Buffer;
2573 }
2574
2575 /* Make a copy of the caller's startup info since we'll modify it */
2576 StartupInfo = *lpStartupInfo;
2577
2578 /* Check if private data is being sent on the same channel as std handles */
2579 if ((StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
2580 (StartupInfo.dwFlags & (STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
2581 {
2582 /* Cannot use the std handles since we have monitor/hotkey values */
2583 StartupInfo.dwFlags &= ~STARTF_USESTDHANDLES;
2584 }
2585
2586 /* If there's a debugger, or we have to launch cmd.exe, we go back here */
2587AppNameRetry:
2588 /* New iteration -- free any existing name buffer */
2589 if (NameBuffer)
2590 {
2591 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
2592 NameBuffer = NULL;
2593 }
2594
2595 /* New iteration -- free any existing free buffer */
2596 if (FreeBuffer)
2597 {
2598 RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
2599 FreeBuffer = NULL;
2600 }
2601
2602 /* New iteration -- close any existing file handle */
2603 if (FileHandle)
2604 {
2606 FileHandle = NULL;
2607 }
2608
2609 /* Set the initial parsing state. This code can loop -- don't move this! */
2610 ErrorCode = 0;
2611 SearchRetry = TRUE;
2612 QuotesNeeded = FALSE;
2613 CmdLineIsAppName = FALSE;
2614
2615 /* First check if we don't have an application name */
2616 if (!lpApplicationName)
2617 {
2618 /* This should be the first time we attempt creating one */
2619 ASSERT(NameBuffer == NULL);
2620
2621 /* Allocate a buffer to hold it */
2622 NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
2623 0,
2624 MAX_PATH * sizeof(WCHAR));
2625 if (!NameBuffer)
2626 {
2628 Result = FALSE;
2629 goto Quickie;
2630 }
2631
2632 /* Initialize the application name and our parsing parameters */
2633 lpApplicationName = NullBuffer = ScanString = lpCommandLine;
2634
2635 /* Check for an initial quote*/
2636 if (*lpCommandLine == L'\"')
2637 {
2638 /* We found a quote, keep searching for another one */
2639 SearchRetry = FALSE;
2640 ScanString++;
2641 lpApplicationName = ScanString;
2642 while (*ScanString)
2643 {
2644 /* Have we found the terminating quote? */
2645 if (*ScanString == L'\"')
2646 {
2647 /* We're done, get out of here */
2648 NullBuffer = ScanString;
2649 HasQuotes = TRUE;
2650 break;
2651 }
2652
2653 /* Keep searching for the quote */
2654 ScanString++;
2655 NullBuffer = ScanString;
2656 }
2657 }
2658 else
2659 {
2660StartScan:
2661 /* We simply make the application name be the command line*/
2662 lpApplicationName = lpCommandLine;
2663 while (*ScanString)
2664 {
2665 /* Check if it starts with a space or tab */
2666 if ((*ScanString == L' ') || (*ScanString == L'\t'))
2667 {
2668 /* Break out of the search loop */
2669 NullBuffer = ScanString;
2670 break;
2671 }
2672
2673 /* Keep searching for a space or tab */
2674 ScanString++;
2675 NullBuffer = ScanString;
2676 }
2677 }
2678
2679 /* We have found the end of the application name, terminate it */
2680 SaveChar = *NullBuffer;
2681 *NullBuffer = UNICODE_NULL;
2682
2683 /* New iteration -- free any existing saved path */
2684 if (SearchPath)
2685 {
2686 RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
2687 SearchPath = NULL;
2688 }
2689
2690 /* Now compute the final EXE path based on the name */
2691 SearchPath = BaseComputeProcessExePath((LPWSTR)lpApplicationName);
2692 DPRINT("Search Path: %S\n", SearchPath);
2693 if (!SearchPath)
2694 {
2696 Result = FALSE;
2697 goto Quickie;
2698 }
2699
2700 /* And search for the executable in the search path */
2702 lpApplicationName,
2703 L".exe",
2704 MAX_PATH,
2705 NameBuffer,
2706 NULL);
2707
2708 /* Did we find it? */
2709 if ((Length) && (Length < MAX_PATH))
2710 {
2711 /* Get file attributes */
2712 FileAttribs = GetFileAttributesW(NameBuffer);
2713 if ((FileAttribs != INVALID_FILE_ATTRIBUTES) &&
2714 (FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
2715 {
2716 /* This was a directory, fail later on */
2717 Length = 0;
2718 }
2719 else
2720 {
2721 /* It's a file! */
2722 Length++;
2723 }
2724 }
2725
2726 DPRINT("Length: %lu Buffer: %S\n", Length, NameBuffer);
2727
2728 /* Check if there was a failure in SearchPathW */
2729 if ((Length) && (Length < MAX_PATH))
2730 {
2731 /* Everything looks good, restore the name */
2732 *NullBuffer = SaveChar;
2733 lpApplicationName = NameBuffer;
2734 }
2735 else
2736 {
2737 /* Check if this was a relative path, which would explain it */
2738 PathType = RtlDetermineDosPathNameType_U(lpApplicationName);
2740 {
2741 /* This should fail, and give us a detailed LastError */
2742 FileHandle = CreateFileW(lpApplicationName,
2746 NULL,
2749 NULL);
2751 {
2752 /* It worked? Return a generic error */
2754 FileHandle = NULL;
2756 }
2757 }
2758 else
2759 {
2760 /* Path was absolute, which means it doesn't exist */
2762 }
2763
2764 /* Did we already fail once? */
2765 if (ErrorCode)
2766 {
2767 /* Set the error code */
2769 }
2770 else
2771 {
2772 /* Not yet, cache it */
2774 }
2775
2776 /* Put back the command line */
2777 *NullBuffer = SaveChar;
2778 lpApplicationName = NameBuffer;
2779
2780 /* It's possible there's whitespace in the directory name */
2781 if (!(*ScanString) || !(SearchRetry))
2782 {
2783 /* Not the case, give up completely */
2784 Result = FALSE;
2785 goto Quickie;
2786 }
2787
2788 /* There are spaces, so keep trying the next possibility */
2789 ScanString++;
2790 NullBuffer = ScanString;
2791
2792 /* We will have to add a quote, since there is a space */
2793 QuotesNeeded = TRUE;
2794 HasQuotes = TRUE;
2795 goto StartScan;
2796 }
2797 }
2798 else if (!(lpCommandLine) || !(*lpCommandLine))
2799 {
2800 /* We don't have a command line, so just use the application name */
2801 CmdLineIsAppName = TRUE;
2802 lpCommandLine = (LPWSTR)lpApplicationName;
2803 }
2804
2805 /* Convert the application name to its NT path */
2806 TranslationStatus = RtlDosPathNameToRelativeNtPathName_U(lpApplicationName,
2807 &PathName,
2808 NULL,
2809 &SxsWin32RelativePath);
2810 if (!TranslationStatus)
2811 {
2812 /* Path must be invalid somehow, bail out */
2813 DPRINT1("Path translation for SxS failed\n");
2815 Result = FALSE;
2816 goto Quickie;
2817 }
2818
2819 /* Setup the buffer that needs to be freed at the end */
2820 ASSERT(FreeBuffer == NULL);
2821 FreeBuffer = PathName.Buffer;
2822
2823 /* Check what kind of path the application is, for SxS (Fusion) purposes */
2824 RtlInitUnicodeString(&SxsWin32ExePath, lpApplicationName);
2825 SxsPathType = RtlDetermineDosPathNameType_U(lpApplicationName);
2826 if ((SxsPathType != RtlPathTypeDriveAbsolute) &&
2827 (SxsPathType != RtlPathTypeLocalDevice) &&
2828 (SxsPathType != RtlPathTypeRootLocalDevice) &&
2829 (SxsPathType != RtlPathTypeUncAbsolute))
2830 {
2831 /* Relative-type path, get the full path */
2832 RtlInitEmptyUnicodeString(&PathBufferString, NULL, 0);
2833 Status = RtlGetFullPathName_UstrEx(&SxsWin32ExePath,
2834 NULL,
2835 &PathBufferString,
2836 NULL,
2837 NULL,
2838 NULL,
2839 &SxsPathType,
2840 NULL);
2841 if (!NT_SUCCESS(Status))
2842 {
2843 /* Fail the rest of the create */
2844 RtlReleaseRelativeName(&SxsWin32RelativePath);
2846 Result = FALSE;
2847 goto Quickie;
2848 }
2849
2850 /* Use this full path as the SxS path */
2851 SxsWin32ExePath = PathBufferString;
2852 PathBuffer = PathBufferString.Buffer;
2853 PathBufferString.Buffer = NULL;
2854 DPRINT("SxS Path: %S\n", PathBuffer);
2855 }
2856
2857 /* Also set the .EXE path based on the path name */
2858#if _SXS_SUPPORT_ENABLED_
2859 SxsNtExePath = PathName;
2860#endif
2861 if (SxsWin32RelativePath.RelativeName.Length)
2862 {
2863 /* If it's relative, capture the relative name */
2864 PathName = SxsWin32RelativePath.RelativeName;
2865 }
2866 else
2867 {
2868 /* Otherwise, it's absolute, make sure no relative dir is used */
2869 SxsWin32RelativePath.ContainingDirectory = NULL;
2870 }
2871
2872 /* Now use the path name, and the root path, to try opening the app */
2873 DPRINT("Path: %wZ. Dir: %p\n", &PathName, SxsWin32RelativePath.ContainingDirectory);
2874 InitializeObjectAttributes(&LocalObjectAttributes,
2875 &PathName,
2877 SxsWin32RelativePath.ContainingDirectory,
2878 NULL);
2880 SYNCHRONIZE |
2884 &LocalObjectAttributes,
2889 if (!NT_SUCCESS(Status))
2890 {
2891 /* Try to open the app just for execute purposes instead */
2894 &LocalObjectAttributes,
2899 }
2900
2901 /* Failure path, display which file failed to open */
2902 if (!NT_SUCCESS(Status))
2903 DPRINT1("Open file failed: %lx (%wZ)\n", Status, &PathName);
2904
2905 /* Cleanup in preparation for failure or success */
2906 RtlReleaseRelativeName(&SxsWin32RelativePath);
2907
2908 if (!NT_SUCCESS(Status))
2909 {
2910 /* Failure path, try to understand why */
2911 if (RtlIsDosDeviceName_U(lpApplicationName))
2912 {
2913 /* If a device is being executed, return this special error code */
2915 Result = FALSE;
2916 goto Quickie;
2917 }
2918 else
2919 {
2920 /* Otherwise return the converted NT error code */
2922 Result = FALSE;
2923 goto Quickie;
2924 }
2925 }
2926
2927 /* Did the caller specify a desktop? */
2928 if (!StartupInfo.lpDesktop)
2929 {
2930 /* Use the one from the current process */
2932 }
2933
2934 /* Create a section for this file */
2935 Status = NtCreateSection(&SectionHandle,
2937 NULL,
2938 NULL,
2940 SEC_IMAGE,
2941 FileHandle);
2942 DPRINT("Section status: %lx\n", Status);
2943 if (NT_SUCCESS(Status))
2944 {
2945 /* Are we running on Windows Embedded, Datacenter, Blade or Starter? */
2946 if (SharedUserData->SuiteMask & (VER_SUITE_EMBEDDEDNT |
2950 {
2951 /* These SKUs do not allow running certain applications */
2954 {
2955 /* And this is one of them! */
2956 DPRINT1("Invalid Blade hashes!\n");
2958 Result = FALSE;
2959 goto Quickie;
2960 }
2961
2962 /* Did we get some other failure? */
2963 if (!NT_SUCCESS(Status))
2964 {
2965 /* If we couldn't check the hashes, assume nefariousness */
2966 DPRINT1("Tampered Blade hashes!\n");
2968 Result = FALSE;
2969 goto Quickie;
2970 }
2971 }
2972
2973 /* Now do Winsafer, etc, checks */
2974 Status = BasepIsProcessAllowed((LPWSTR)lpApplicationName);
2975 if (!NT_SUCCESS(Status))
2976 {
2977 /* Fail if we're not allowed to launch the process */
2978 DPRINT1("Process not allowed to launch: %lx\n", Status);
2980 if (SectionHandle)
2981 {
2982 NtClose(SectionHandle);
2983 SectionHandle = NULL;
2984 }
2985 Result = FALSE;
2986 goto Quickie;
2987 }
2988
2989 /* Is a DOS VDM being forced, but we already have a WOW32 instance ready? */
2990 if ((dwCreationFlags & CREATE_FORCEDOS) &&
2992 {
2993 /* This request can't be satisfied, instead, a separate VDM is needed */
2994 dwCreationFlags &= ~(CREATE_FORCEDOS | CREATE_SHARED_WOW_VDM);
2995 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
2996
2997 /* Set a failure code, ask for VDM reservation */
2999 UseVdmReserve = TRUE;
3000
3001 /* Close the current handle */
3002 NtClose(SectionHandle);
3003 SectionHandle = NULL;
3004
3005 /* Don't query the section later */
3006 QuerySection = FALSE;
3007 }
3008 }
3009
3010 /* Did we already do these checks? */
3011 if (!SkipSaferAndAppCompat)
3012 {
3013 /* Is everything OK so far, OR do we have an non-MZ, non-DOS app? */
3014 if ((NT_SUCCESS(Status)) ||
3016 !(BaseIsDosApplication(&PathName, Status))))
3017 {
3018 /* Clear the machine type in case of failure */
3019 ImageMachine = 0;
3020
3021 /* Clean any app compat data that may have accumulated */
3022 BasepFreeAppCompatData(AppCompatData, AppCompatSxsData);
3023 AppCompatData = NULL;
3024 AppCompatSxsData = NULL;
3025
3026 /* Do we have a section? */
3027 if (SectionHandle)
3028 {
3029 /* Have we already queried it? */
3030 if (QuerySection)
3031 {
3032 /* Nothing to do */
3033 AppCompatStatus = STATUS_SUCCESS;
3034 }
3035 else
3036 {
3037 /* Get some information about the executable */
3038 AppCompatStatus = NtQuerySection(SectionHandle,
3040 &ImageInformation,
3041 sizeof(ImageInformation),
3042 NULL);
3043 }
3044
3045 /* Do we have section information now? */
3046 if (NT_SUCCESS(AppCompatStatus))
3047 {
3048 /* Don't ask for it again, save the machine type */
3049 QuerySection = TRUE;
3050 ImageMachine = ImageInformation.Machine;
3051 }
3052 }
3053
3054 /* Is there a reason/Shim we shouldn't run this application? */
3055 AppCompatStatus = BasepCheckBadapp(FileHandle,
3056 FreeBuffer,
3057 lpEnvironment,
3058 ImageMachine,
3059 &AppCompatData,
3060 &AppCompatDataSize,
3061 &AppCompatSxsData,
3062 &AppCompatSxsDataSize,
3063 &FusionFlags);
3064 if (!NT_SUCCESS(AppCompatStatus))
3065 {
3066 /* This is usually the status we get back */
3067 DPRINT1("App compat launch failure: %lx\n", AppCompatStatus);
3068 if (AppCompatStatus == STATUS_ACCESS_DENIED)
3069 {
3070 /* Convert it to something more Win32-specific */
3072 }
3073 else
3074 {
3075 /* Some other error */
3076 BaseSetLastNTError(AppCompatStatus);
3077 }
3078
3079 /* Did we have a section? */
3080 if (SectionHandle)
3081 {
3082 /* Clean it up */
3083 NtClose(SectionHandle);
3084 SectionHandle = NULL;
3085 }
3086
3087 /* Fail the call */
3088 Result = FALSE;
3089 goto Quickie;
3090 }
3091 }
3092 }
3093
3094 //ASSERT((dwFusionFlags & ~SXS_APPCOMPACT_FLAG_APP_RUNNING_SAFEMODE) == 0);
3095
3096 /* Have we already done, and do we need to do, SRP (WinSafer) checks? */
3097 if (!(SkipSaferAndAppCompat) &&
3098 ~(dwCreationFlags & CREATE_PRESERVE_CODE_AUTHZ_LEVEL))
3099 {
3100 /* Assume yes */
3101 SaferNeeded = TRUE;
3102 switch (Status)
3103 {
3108 /* For all DOS, 16-bit, OS/2 images, we do*/
3109 break;
3110
3112 /* For invalid files, we don't, unless it's a .BAT file */
3113 if (BaseIsDosApplication(&PathName, Status)) break;
3114
3115 default:
3116 /* Any other error codes we also don't */
3117 if (!NT_SUCCESS(Status))
3118 {
3119 SaferNeeded = FALSE;
3120 }
3121
3122 /* But for success, we do */
3123 break;
3124 }
3125
3126 /* Okay, so what did the checks above result in? */
3127 if (SaferNeeded)
3128 {
3129 /* We have to call into the WinSafer library and actually check */
3131 (LPWSTR)lpApplicationName,
3132 FileHandle,
3133 &InJob,
3134 &TokenHandle,
3135 &JobHandle);
3136 if (SaferStatus == 0xFFFFFFFF)
3137 {
3138 /* Back in 2003, they didn't have an NTSTATUS for this... */
3139 DPRINT1("WinSafer blocking process launch\n");
3141 Result = FALSE;
3142 goto Quickie;
3143 }
3144
3145 /* Other status codes are not-Safer related, just convert them */
3146 if (!NT_SUCCESS(SaferStatus))
3147 {
3148 DPRINT1("Error checking WinSafer: %lx\n", SaferStatus);
3149 BaseSetLastNTError(SaferStatus);
3150 Result = FALSE;
3151 goto Quickie;
3152 }
3153 }
3154 }
3155
3156 /* The last step is to figure out why the section object was not created */
3157 switch (Status)
3158 {
3160 {
3161 /* 16-bit binary. Should we use WOW or does the caller force VDM? */
3162 if (!(dwCreationFlags & CREATE_FORCEDOS))
3163 {
3164 /* Remember that we're launching WOW */
3165 IsWowApp = TRUE;
3166
3167 /* Create the VDM environment, it's valid for WOW too */
3168 Result = BaseCreateVDMEnvironment(lpEnvironment,
3169 &VdmAnsiEnv,
3170 &VdmUnicodeEnv);
3171 if (!Result)
3172 {
3173 DPRINT1("VDM environment for WOW app failed\n");
3174 goto Quickie;
3175 }
3176
3177 /* We're going to try this twice, so do a loop */
3178 while (TRUE)
3179 {
3180 /* Pick which kind of WOW mode we want to run in */
3181 VdmBinaryType = (dwCreationFlags &
3184
3185 /* Get all the VDM settings and current status */
3186 Status = BaseCheckVDM(VdmBinaryType,
3187 lpApplicationName,
3188 lpCommandLine,
3189 lpCurrentDirectory,
3190 &VdmAnsiEnv,
3191 &CsrMsg[1],
3192 &VdmTask,
3193 dwCreationFlags,
3194 &StartupInfo,
3195 hUserToken);
3196
3197 /* If it worked, no need to try again */
3198 if (NT_SUCCESS(Status)) break;
3199
3200 /* Check if it's disallowed or if it's our second time */
3202 if ((Status == STATUS_VDM_DISALLOWED) ||
3203 (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW) ||
3205 {
3206 /* Fail the call -- we won't try again */
3207 DPRINT1("VDM message failure for WOW: %lx\n", Status);
3208 Result = FALSE;
3209 goto Quickie;
3210 }
3211
3212 /* Try one more time, but with a separate WOW instance */
3213 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
3214 }
3215
3216 /* Check which VDM state we're currently in */
3217 switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
3219 VDM_READY))
3220 {
3221 case VDM_NOT_LOADED:
3222 /* VDM is not fully loaded, so not that much to undo */
3223 VdmUndoLevel = VDM_UNDO_PARTIAL;
3224
3225 /* Reset VDM reserve if needed */
3226 if (UseVdmReserve) VdmReserve = 1;
3227
3228 /* Get the required parameters and names for launch */
3229 Result = BaseGetVdmConfigInfo(lpCommandLine,
3230 VdmTask,
3231 VdmBinaryType,
3232 &VdmString,
3233 &VdmReserve);
3234 if (!Result)
3235 {
3236 DPRINT1("VDM Configuration failed for WOW\n");
3238 goto Quickie;
3239 }
3240
3241 /* Update the command-line with the VDM one instead */
3242 lpCommandLine = VdmString.Buffer;
3243 lpApplicationName = NULL;
3244
3245 /* We don't want a console, detachment, nor a window */
3246 dwCreationFlags |= CREATE_NO_WINDOW;
3247 dwCreationFlags &= ~(CREATE_NEW_CONSOLE | DETACHED_PROCESS);
3248
3249 /* Force feedback on */
3250 StartupInfo.dwFlags |= STARTF_FORCEONFEEDBACK;
3251 break;
3252
3253
3254 case VDM_READY:
3255 /* VDM is ready, so we have to undo everything */
3256 VdmUndoLevel = VDM_UNDO_REUSE;
3257
3258 /* Check if CSRSS wants us to wait on VDM */
3259 VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
3260 break;
3261
3262 case VDM_NOT_READY:
3263 /* Something is wrong with VDM, we'll fail the call */
3264 DPRINT1("VDM is not ready for WOW\n");
3266 Result = FALSE;
3267 goto Quickie;
3268
3269 default:
3270 break;
3271 }
3272
3273 /* Since to get NULL, we allocate from 0x1, account for this */
3274 VdmReserve--;
3275
3276 /* This implies VDM is ready, so skip everything else */
3277 if (VdmWaitObject) goto VdmShortCircuit;
3278
3279 /* Don't inherit handles since we're doing VDM now */
3280 bInheritHandles = FALSE;
3281
3282 /* Had the user passed in environment? If so, destroy it */
3283 if ((lpEnvironment) &&
3284 !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
3285 {
3286 RtlDestroyEnvironment(lpEnvironment);
3287 }
3288
3289 /* We've already done all these checks, don't do them again */
3290 SkipSaferAndAppCompat = TRUE;
3291 goto AppNameRetry;
3292 }
3293
3294 // There is no break here on purpose, so FORCEDOS drops down!
3295 }
3296
3300 {
3301 /* We're launching an executable application */
3302 BinarySubType = BINARY_TYPE_EXE;
3303
3304 /* We can drop here from other "cases" above too, so check */
3307 (BinarySubType = BaseIsDosApplication(&PathName, Status)))
3308 {
3309 /* We're launching a DOS application */
3310 VdmBinaryType = BINARY_TYPE_DOS;
3311
3312 /* Based on the caller environment, create a VDM one */
3313 Result = BaseCreateVDMEnvironment(lpEnvironment,
3314 &VdmAnsiEnv,
3315 &VdmUnicodeEnv);
3316 if (!Result)
3317 {
3318 DPRINT1("VDM environment for DOS failed\n");
3319 goto Quickie;
3320 }
3321
3322 /* Check the current state of the VDM subsystem */
3323 Status = BaseCheckVDM(VdmBinaryType | BinarySubType,
3324 lpApplicationName,
3325 lpCommandLine,
3326 lpCurrentDirectory,
3327 &VdmAnsiEnv,
3328 &CsrMsg[1],
3329 &VdmTask,
3330 dwCreationFlags,
3331 &StartupInfo,
3332 NULL);
3333 if (!NT_SUCCESS(Status))
3334 {
3335 /* Failed to inquire about VDM, fail the call */
3336 DPRINT1("VDM message failure for DOS: %lx\n", Status);
3338 Result = FALSE;
3339 goto Quickie;
3340 };
3341
3342 /* Handle possible VDM states */
3343 switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
3345 VDM_READY))
3346 {
3347 case VDM_NOT_LOADED:
3348 /* If VDM is not loaded, we'll do a partial undo */
3349 VdmUndoLevel = VDM_UNDO_PARTIAL;
3350
3351 /* A VDM process can't also be detached, so fail */
3352 if (dwCreationFlags & DETACHED_PROCESS)
3353 {
3354 DPRINT1("Detached process but no VDM, not allowed\n");
3356 return FALSE;
3357 }
3358
3359 /* Get the required parameters and names for launch */
3360 Result = BaseGetVdmConfigInfo(lpCommandLine,
3361 VdmTask,
3362 VdmBinaryType,
3363 &VdmString,
3364 &VdmReserve);
3365 if (!Result)
3366 {
3367 DPRINT1("VDM Configuration failed for DOS\n");
3369 goto Quickie;
3370 }
3371
3372 /* Update the command-line to launch VDM instead */
3373 lpCommandLine = VdmString.Buffer;
3374 lpApplicationName = NULL;
3375 break;
3376
3377 case VDM_READY:
3378 /* VDM is ready, so we have to undo everything */
3379 VdmUndoLevel = VDM_UNDO_REUSE;
3380
3381 /* Check if CSRSS wants us to wait on VDM */
3382 VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
3383 break;
3384
3385 case VDM_NOT_READY:
3386 /* Something is wrong with VDM, we'll fail the call */
3387 DPRINT1("VDM is not ready for DOS\n");
3389 Result = FALSE;
3390 goto Quickie;
3391
3392 default:
3393 break;
3394 }
3395
3396 /* Since to get NULL, we allocate from 0x1, account for this */
3397 VdmReserve--;
3398
3399 /* This implies VDM is ready, so skip everything else */
3400 if (VdmWaitObject) goto VdmShortCircuit;
3401
3402 /* Don't inherit handles since we're doing VDM now */
3403 bInheritHandles = FALSE;
3404
3405 /* Had the user passed in environment? If so, destroy it */
3406 if ((lpEnvironment) &&
3407 !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
3408 {
3409 RtlDestroyEnvironment(lpEnvironment);
3410 }
3411
3412 /* Use our VDM Unicode environment instead */
3413 lpEnvironment = VdmUnicodeEnv.Buffer;
3414 }
3415 else
3416 {
3417 /* It's a batch file, get the extension */
3418 ExtBuffer = &PathName.Buffer[PathName.Length / sizeof(WCHAR) - 4];
3419
3420 /* Make sure the extensions are correct */
3421 if ((PathName.Length < (4 * sizeof(WCHAR))) ||
3422 ((_wcsnicmp(ExtBuffer, L".bat", 4)) &&
3423 (_wcsnicmp(ExtBuffer, L".cmd", 4))))
3424 {
3425 DPRINT1("'%wZ': Invalid EXE, and not a batch or script file\n", &PathName);
3427 Result = FALSE;
3428 goto Quickie;
3429 }
3430
3431 /* Check if we need to account for quotes around the path */
3432 CmdQuoteLength = CmdLineIsAppName || HasQuotes;
3433 if (!CmdLineIsAppName)
3434 {
3435 if (HasQuotes) CmdQuoteLength++;
3436 }
3437 else
3438 {
3439 CmdQuoteLength++;
3440 }
3441
3442 /* Calculate the length of the command line */
3443 CmdLineLength = wcslen(lpCommandLine);
3444 CmdLineLength += wcslen(CMD_STRING);
3445 CmdLineLength += CmdQuoteLength + sizeof(ANSI_NULL);
3446 CmdLineLength *= sizeof(WCHAR);
3447
3448 /* Allocate space for the new command line */
3449 AnsiCmdCommand = RtlAllocateHeap(RtlGetProcessHeap(),
3450 0,
3451 CmdLineLength);
3452 if (!AnsiCmdCommand)
3453 {
3455 Result = FALSE;
3456 goto Quickie;
3457 }
3458
3459 /* Build it */
3460 wcscpy(AnsiCmdCommand, CMD_STRING);
3461 if ((CmdLineIsAppName) || (HasQuotes))
3462 {
3463 wcscat(AnsiCmdCommand, L"\"");
3464 }
3465 wcscat(AnsiCmdCommand, lpCommandLine);
3466 if ((CmdLineIsAppName) || (HasQuotes))
3467 {
3468 wcscat(AnsiCmdCommand, L"\"");
3469 }
3470
3471 /* Create it as a Unicode String */
3472 RtlInitUnicodeString(&DebuggerString, AnsiCmdCommand);
3473
3474 /* Set the command line to this */
3475 lpCommandLine = DebuggerString.Buffer;
3476 lpApplicationName = NULL;
3477 DPRINT1("Retrying with: %S\n", lpCommandLine);
3478 }
3479
3480 /* We've already done all these checks, don't do them again */
3481 SkipSaferAndAppCompat = TRUE;
3482 goto AppNameRetry;
3483 }
3484
3486 {
3487 /* 64-bit binaries are not allowed to run on 32-bit ReactOS */
3488 DPRINT1("64-bit binary, failing\n");
3490 Result = FALSE;
3491 goto Quickie;
3492 }
3493
3495 {
3496 /* Set the correct last error for this */
3497 DPRINT1("File is offline, failing\n");
3499 break;
3500 }
3501
3502 default:
3503 {
3504 /* Any other error, convert it to a generic Win32 error */
3505 if (!NT_SUCCESS(Status))
3506 {
3507 DPRINT1("Failed to create section: %lx\n", Status);
3509 Result = FALSE;
3510 goto Quickie;
3511 }
3512
3513 /* Otherwise, this must be success */
3515 break;
3516 }
3517 }
3518
3519 /* Is this not a WOW application, but a WOW32 VDM was requested for it? */
3520 if (!(IsWowApp) && (dwCreationFlags & CREATE_SEPARATE_WOW_VDM))
3521 {
3522 /* Ignore the nonsensical request */
3523 dwCreationFlags &= ~CREATE_SEPARATE_WOW_VDM;
3524 }
3525
3526 /* Did we already check information for the section? */
3527 if (!QuerySection)
3528 {
3529 /* Get some information about the executable */
3530 Status = NtQuerySection(SectionHandle,
3532 &ImageInformation,
3533 sizeof(ImageInformation),
3534 NULL);
3535 if (!NT_SUCCESS(Status))
3536 {
3537 /* We failed, bail out */
3538 DPRINT1("Section query failed\n");
3540 Result = FALSE;
3541 goto Quickie;
3542 }
3543
3544 /* Don't check this later */
3545 QuerySection = TRUE;
3546 }
3547
3548 /* Check if this was linked as a DLL */
3549 if (ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3550 {
3551 /* These aren't valid images to try to execute! */
3552 DPRINT1("Trying to launch a DLL, failing\n");
3554 Result = FALSE;
3555 goto Quickie;
3556 }
3557
3558 /* Don't let callers pass in this flag -- we'll only get it from IFEO */
3559 Flags &= ~PROCESS_CREATE_FLAGS_LARGE_PAGES;
3560
3561 /* Clear the IFEO-missing flag, before we know for sure... */
3562 ParameterFlags &= ~2;
3563
3564 /* If the process is being debugged, only read IFEO if the PEB says so */
3565 if (!(dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) ||
3567 {
3568 /* Let's do this! Attempt to open IFEO */
3569 IFEOStatus = LdrOpenImageFileOptionsKey(&PathName, 0, &KeyHandle);
3570 if (!NT_SUCCESS(IFEOStatus))
3571 {
3572 /* We failed, set the flag so we store this in the parameters */
3573 if (IFEOStatus == STATUS_OBJECT_NAME_NOT_FOUND) ParameterFlags |= 2;
3574 }
3575 else
3576 {
3577 /* Was this our first time going through this path? */
3578 if (!DebuggerCmdLine)
3579 {
3580 /* Allocate a buffer for the debugger path */
3581 DebuggerCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
3582 0,
3583 MAX_PATH * sizeof(WCHAR));
3584 if (!DebuggerCmdLine)
3585 {
3586 /* Close IFEO on failure */
3587 IFEOStatus = NtClose(KeyHandle);
3588 ASSERT(NT_SUCCESS(IFEOStatus));
3589
3590 /* Fail the call */
3592 Result = FALSE;
3593 goto Quickie;
3594 }
3595 }
3596
3597 /* Now query for the debugger */
3599 L"Debugger",
3600 REG_SZ,
3601 DebuggerCmdLine,
3602 MAX_PATH * sizeof(WCHAR),
3603 &ResultSize);
3604 if (!(NT_SUCCESS(IFEOStatus)) ||
3605 (ResultSize < sizeof(WCHAR)) ||
3606 (DebuggerCmdLine[0] == UNICODE_NULL))
3607 {
3608 /* If it's not there, or too small, or invalid, ignore it */
3609 RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
3610 DebuggerCmdLine = NULL;
3611 }
3612
3613 /* Also query if we should map with large pages */
3615 L"UseLargePages",
3616 REG_DWORD,
3617 &UseLargePages,
3618 sizeof(UseLargePages),
3619 NULL);
3620 if ((NT_SUCCESS(IFEOStatus)) && (UseLargePages))
3621 {
3622 /* Do it! This is the only way this flag can be set */
3624 }
3625
3626 /* We're done with IFEO, can close it now */
3627 IFEOStatus = NtClose(KeyHandle);
3628 ASSERT(NT_SUCCESS(IFEOStatus));
3629 }
3630 }
3631
3632 /* Make sure the image was compiled for this processor */
3633 if ((ImageInformation.Machine < SharedUserData->ImageNumberLow) ||
3634 (ImageInformation.Machine > SharedUserData->ImageNumberHigh))
3635 {
3636 /* It was not -- raise a hard error */
3637 ErrorResponse = ResponseOk;
3638 ErrorParameters[0] = (ULONG_PTR)&PathName;
3640 1,
3641 1,
3642 ErrorParameters,
3643 OptionOk,
3644 &ErrorResponse);
3646 {
3647 /* If it's really old, return this error */
3649 }
3650 else
3651 {
3652 /* Otherwise, return a more modern error */
3654 }
3655
3656 /* Go to the failure path */
3657 DPRINT1("Invalid image architecture: %lx\n", ImageInformation.Machine);
3658 Result = FALSE;
3659 goto Quickie;
3660 }
3661
3662 /* Check if this isn't a Windows image */
3663 if ((ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_GUI) &&
3664 (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_CUI))
3665 {
3666 /* Get rid of section-related information since we'll retry */
3667 NtClose(SectionHandle);
3668 SectionHandle = NULL;
3669 QuerySection = FALSE;
3670
3671 /* The only other non-Windows image type we support here is POSIX */
3672 if (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_POSIX_CUI)
3673 {
3674 /* Bail out if it's something else */
3676 Result = FALSE;
3677 goto Quickie;
3678 }
3679
3680 /* Now build the command-line to have posix launch this image */
3681 Result = BuildSubSysCommandLine(L"POSIX /P ",
3682 lpApplicationName,
3683 lpCommandLine,
3684 &DebuggerString);
3685 if (!Result)
3686 {
3687 /* Bail out if that failed */
3688 DPRINT1("Subsystem command line failed\n");
3689 goto Quickie;
3690 }
3691
3692 /* And re-try launching the process, with the new command-line now */
3693 lpCommandLine = DebuggerString.Buffer;
3694 lpApplicationName = NULL;
3695
3696 /* We've already done all these checks, don't do them again */
3697 SkipSaferAndAppCompat = TRUE;
3698 DPRINT1("Retrying with: %S\n", lpCommandLine);
3699 goto AppNameRetry;
3700 }
3701
3702 /* Was this image built for a version of Windows whose images we can run? */
3704 ImageInformation.SubSystemMinorVersion);
3705 if (!Result)
3706 {
3707 /* It was not, bail out */
3708 DPRINT1("Invalid subsystem version: %hu.%hu\n",
3709 ImageInformation.SubSystemMajorVersion,
3710 ImageInformation.SubSystemMinorVersion);
3712 goto Quickie;
3713 }
3714
3715 /* Check if there is a debugger associated with the application */
3716 if (DebuggerCmdLine)
3717 {
3718 /* Get the length of the command line */
3719 n = wcslen(lpCommandLine);
3720 if (!n)
3721 {
3722 /* There's no command line, use the application name instead */
3723 lpCommandLine = (LPWSTR)lpApplicationName;
3724 n = wcslen(lpCommandLine);
3725 }
3726
3727 /* Protect against overflow */
3729 {
3731 Result = FALSE;
3732 goto Quickie;
3733 }
3734
3735 /* Now add the length of the debugger command-line */
3736 n += wcslen(DebuggerCmdLine);
3737
3738 /* Again make sure we don't overflow */
3740 {
3742 Result = FALSE;
3743 goto Quickie;
3744 }
3745
3746 /* Account for the quotes and space between the two */
3747 n += sizeof("\" \"") - sizeof(ANSI_NULL);
3748
3749 /* Convert to bytes, and make sure we don't overflow */
3750 n *= sizeof(WCHAR);
3752 {
3754 Result = FALSE;
3755 goto Quickie;
3756 }
3757
3758 /* Allocate space for the string */
3759 DebuggerString.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, n);
3760 if (!DebuggerString.Buffer)
3761 {
3763 Result = FALSE;
3764 goto Quickie;
3765 }
3766
3767 /* Set the length */
3768 RtlInitEmptyUnicodeString(&DebuggerString,
3769 DebuggerString.Buffer,
3770 (USHORT)n);
3771
3772 /* Now perform the command line creation */
3773 ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString,
3774 DebuggerCmdLine);
3775 ASSERT(NT_SUCCESS(ImageDbgStatus));
3776 ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, L" ");
3777 ASSERT(NT_SUCCESS(ImageDbgStatus));
3778 ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, lpCommandLine);
3779 ASSERT(NT_SUCCESS(ImageDbgStatus));
3780
3781 /* Make sure it all looks nice */
3782 DbgPrint("BASE: Calling debugger with '%wZ'\n", &DebuggerString);
3783
3784 /* Update the command line and application name */
3785 lpCommandLine = DebuggerString.Buffer;
3786 lpApplicationName = NULL;
3787
3788 /* Close all temporary state */
3789 NtClose(SectionHandle);
3790 SectionHandle = NULL;
3791 QuerySection = FALSE;
3792
3793 /* Free all temporary memory */
3794 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
3795 NameBuffer = NULL;
3796 RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
3797 FreeBuffer = NULL;
3798 RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
3799 DebuggerCmdLine = NULL;
3800 DPRINT1("Retrying with: %S\n", lpCommandLine);
3801 goto AppNameRetry;
3802 }
3803
3804 /* Initialize the process object attributes */
3805 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
3806 lpProcessAttributes,
3807 NULL);
3808 if ((hUserToken) && (lpProcessAttributes))
3809 {
3810 /* Augment them with information from the user */
3811
3812 LocalProcessAttributes = *lpProcessAttributes;
3813 LocalProcessAttributes.lpSecurityDescriptor = NULL;
3814 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
3815 &LocalProcessAttributes,
3816 NULL);
3817 }
3818
3819 /* Check if we're going to be debugged */
3820 if (dwCreationFlags & DEBUG_PROCESS)
3821 {
3822 /* Set process flag */
3824 }
3825
3826 /* Check if we're going to be debugged */
3827 if (dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
3828 {
3829 /* Connect to DbgUi */
3831 if (!NT_SUCCESS(Status))
3832 {
3833 DPRINT1("Failed to connect to DbgUI!\n");
3835 Result = FALSE;
3836 goto Quickie;
3837 }
3838
3839 /* Get the debug object */
3840 DebugHandle = DbgUiGetThreadDebugObject();
3841
3842 /* Check if only this process will be debugged */
3843 if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS)
3844 {
3845 /* Set process flag */
3847 }
3848 }
3849
3850 /* Set inherit flag */
3851 if (bInheritHandles) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES;
3852
3853 /* Check if the process should be created with large pages */
3854 HavePrivilege = FALSE;
3855 PrivilegeState = NULL;
3857 {
3858 /* Acquire the required privilege so that the kernel won't fail the call */
3859 PrivilegeValue = SE_LOCK_MEMORY_PRIVILEGE;
3860 Status = RtlAcquirePrivilege(&PrivilegeValue, 1, 0, &PrivilegeState);
3861 if (NT_SUCCESS(Status))
3862 {
3863 /* Remember to release it later */
3864 HavePrivilege = TRUE;
3865 }
3866 }
3867
3868 /* Save the current TIB value since kernel overwrites it to store PEB */
3869 TibValue = Teb->NtTib.ArbitraryUserPointer;
3870
3871 /* Tell the kernel to create the process */
3876 Flags,
3877 SectionHandle,
3878 DebugHandle,
3879 NULL,
3880 InJob);
3881
3882 /* Load the PEB address from the hacky location where the kernel stores it */
3883 RemotePeb = Teb->NtTib.ArbitraryUserPointer;
3884
3885 /* And restore the old TIB value */
3886 Teb->NtTib.ArbitraryUserPointer = TibValue;
3887
3888 /* Release the large page privilege if we had acquired it */
3889 if (HavePrivilege) RtlReleasePrivilege(PrivilegeState);
3890
3891 /* And now check if the kernel failed to create the process */
3892 if (!NT_SUCCESS(Status))
3893 {
3894 /* Go to failure path */
3895 DPRINT1("Failed to create process: %lx\n", Status);
3897 Result = FALSE;
3898 goto Quickie;
3899 }
3900
3901 /* Check if there is a priority class to set */
3902 if (PriorityClass.PriorityClass)
3903 {
3904 /* Reset current privilege state */
3905 RealTimePrivilegeState = NULL;
3906
3907 /* Is realtime priority being requested? */
3909 {
3910 /* Check if the caller has real-time access, and enable it if so */
3911 RealTimePrivilegeState = BasepIsRealtimeAllowed(TRUE);
3912 }
3913
3914 /* Set the new priority class and release the privilege */
3917 &PriorityClass,
3918 sizeof(PROCESS_PRIORITY_CLASS));
3919 if (RealTimePrivilegeState) RtlReleasePrivilege(RealTimePrivilegeState);
3920
3921 /* Check if we failed to set the priority class */
3922 if (!NT_SUCCESS(Status))
3923 {
3924 /* Bail out on failure */
3925 DPRINT1("Failed to set priority class: %lx\n", Status);
3927 Result = FALSE;
3928 goto Quickie;
3929 }
3930 }
3931
3932 /* Check if the caller wants the default error mode */
3933 if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE)
3934 {
3935 /* Set Error Mode to only fail on critical errors */
3936 HardErrorMode = SEM_FAILCRITICALERRORS;
3939 &HardErrorMode,
3940 sizeof(ULONG));
3941 }
3942
3943 /* Check if this was a VDM binary */
3944 if (VdmBinaryType)
3945 {
3946 /* Update VDM by telling it the process has now been created */
3947 VdmWaitObject = ProcessHandle;
3949 &VdmWaitObject,
3950 VdmTask,
3951 VdmBinaryType);
3952
3953 if (!Result)
3954 {
3955 /* Bail out on failure */
3956 DPRINT1("Failed to update VDM with wait object\n");
3957 VdmWaitObject = NULL;
3958 goto Quickie;
3959 }
3960
3961 /* At this point, a failure means VDM has to undo all the state */
3962 VdmUndoLevel |= VDM_UNDO_FULL;
3963 }
3964
3965 /* Check if VDM needed reserved low-memory */
3966 if (VdmReserve)
3967 {
3968 /* Reserve the requested allocation */
3969 RegionSize = VdmReserve;
3971 &BaseAddress,
3972 0,
3973 &RegionSize,
3976 if (!NT_SUCCESS(Status))
3977 {
3978 /* Bail out on failure */
3979 DPRINT1("Failed to reserve memory for VDM: %lx\n", Status);
3981 Result = FALSE;
3982 goto Quickie;
3983 }
3984
3985 VdmReserve = (ULONG)RegionSize;
3986 }
3987
3988 /* Check if we've already queried information on the section */
3989 if (!QuerySection)
3990 {
3991 /* We haven't, so get some information about the executable */
3992 Status = NtQuerySection(SectionHandle,
3994 &ImageInformation,
3995 sizeof(ImageInformation),
3996 NULL);
3997 if (!NT_SUCCESS(Status))
3998 {
3999 /* Bail out on failure */
4000 DPRINT1("Failed to query section: %lx\n", Status);
4002 Result = FALSE;
4003 goto Quickie;
4004 }
4005
4006 /* If we encounter a restart, don't re-query this information again */
4007 QuerySection = TRUE;
4008 }
4009
4010 /* Do we need to apply SxS to this image? (On x86 this flag is set by PeFmtCreateSection) */
4012 {
4013 /* Too bad, we don't support this yet */
4014 DPRINT("Image should receive SxS Fusion Isolation\n");
4015 }
4016
4017 /* There's some SxS flag that we need to set if fusion flags have 1 set */
4018 if (FusionFlags & 1) CreateProcessMsg->Sxs.Flags |= 0x10;
4019
4020 /* Check if we have a current directory */
4021 if (lpCurrentDirectory)
4022 {
4023 /* Allocate a buffer so we can keep a Unicode copy */
4024 DPRINT("Current directory: %S\n", lpCurrentDirectory);
4025 CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(),
4026 0,
4027 (MAX_PATH * sizeof(WCHAR)) +
4028 sizeof(UNICODE_NULL));
4029 if (!CurrentDirectory)
4030 {
4031 /* Bail out if this failed */
4033 Result = FALSE;
4034 goto Quickie;
4035 }
4036
4037 /* Get the length in Unicode */
4038 Length = GetFullPathNameW(lpCurrentDirectory,
4039 MAX_PATH,
4041 &FilePart);
4042 if (Length > MAX_PATH)
4043 {
4044 /* The directory is too long, so bail out */
4046 Result = FALSE;
4047 goto Quickie;
4048 }
4049
4050 /* Make sure the directory is actually valid */
4051 FileAttribs = GetFileAttributesW(CurrentDirectory);
4052 if ((FileAttribs == INVALID_FILE_ATTRIBUTES) ||
4053 !(FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
4054 {
4055 /* It isn't, so bail out */
4056 DPRINT1("Current directory is invalid\n");
4058 Result = FALSE;
4059 goto Quickie;
4060 }
4061 }
4062
4063 /* Insert quotes if needed */
4064 if ((QuotesNeeded) || (CmdLineIsAppName))
4065 {
4066 /* Allocate our buffer, plus enough space for quotes and a NULL */
4067 QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
4068 0,
4069 (wcslen(lpCommandLine) * sizeof(WCHAR)) +
4070 (2 * sizeof(L'\"') + sizeof(UNICODE_NULL)));
4071 if (QuotedCmdLine)
4072 {
4073 /* Copy the first quote */
4074 wcscpy(QuotedCmdLine, L"\"");
4075
4076 /* Save the current null-character */
4077 if (QuotesNeeded)
4078 {
4079 SaveChar = *NullBuffer;
4080 *NullBuffer = UNICODE_NULL;
4081 }
4082
4083 /* Copy the command line and the final quote */
4084 wcscat(QuotedCmdLine, lpCommandLine);
4085 wcscat(QuotedCmdLine, L"\"");
4086
4087 /* Copy the null-char back */
4088 if (QuotesNeeded)
4089 {
4090 *NullBuffer = SaveChar;
4091 wcscat(QuotedCmdLine, NullBuffer);
4092 }
4093 }
4094 else
4095 {
4096 /* We can't put quotes around the thing, so try it anyway */
4097 if (QuotesNeeded) QuotesNeeded = FALSE;
4098 if (CmdLineIsAppName) CmdLineIsAppName = FALSE;
4099 }
4100 }
4101
4102 /* Use isolation if needed */
4103 if (CreateProcessMsg->Sxs.Flags & 1) ParameterFlags |= 1;
4104
4105 /* Set the new command-line if needed */
4106 if ((QuotesNeeded) || (CmdLineIsAppName)) lpCommandLine = QuotedCmdLine;
4107
4108 /* Call the helper function in charge of RTL_USER_PROCESS_PARAMETERS */
4109 Result = BasePushProcessParameters(ParameterFlags,
4111 RemotePeb,
4112 lpApplicationName,
4114 lpCommandLine,
4115 lpEnvironment,
4116 &StartupInfo,
4117 dwCreationFlags | NoWindow,
4118 bInheritHandles,
4119 IsWowApp ? IMAGE_SUBSYSTEM_WINDOWS_GUI: 0,
4120 AppCompatData,
4121 AppCompatDataSize);
4122 if (!Result)
4123 {
4124 /* The remote process would have an undefined state, so fail the call */
4125 DPRINT1("BasePushProcessParameters failed\n");
4126 goto Quickie;
4127 }
4128
4129 /* Free the VDM command line string as it's no longer needed */
4130 RtlFreeUnicodeString(&VdmString);
4131 VdmString.Buffer = NULL;
4132
4133 /* Non-VDM console applications usually inherit handles unless specified */
4134 if (!(VdmBinaryType) &&
4135 !(bInheritHandles) &&
4136 !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
4137 !(dwCreationFlags & (CREATE_NO_WINDOW |
4139 DETACHED_PROCESS)) &&
4140 (ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI))
4141 {
4142 /* Get the remote parameters */
4144 &RemotePeb->ProcessParameters,
4145 &ProcessParameters,
4147 NULL);
4148 if (NT_SUCCESS(Status))
4149 {
4150 /* Duplicate standard input unless it's a console handle */
4152 {
4155 &ProcessParameters->StandardInput);
4156 }
4157
4158 /* Duplicate standard output unless it's a console handle */
4160 {
4163 &ProcessParameters->StandardOutput);
4164 }
4165
4166 /* Duplicate standard error unless it's a console handle */
4168 {
4171 &ProcessParameters->StandardError);
4172 }
4173 }
4174 }
4175
4176 /* Create the Thread's Stack */
4177 StackSize = max(256 * 1024, ImageInformation.MaximumStackSize);
4179 ImageInformation.CommittedStackSize,
4180 StackSize,
4181 &InitialTeb);
4182 if (!NT_SUCCESS(Status))
4183 {
4184 DPRINT1("Creating the thread stack failed: %lx\n", Status);
4186 Result = FALSE;
4187 goto Quickie;
4188 }
4189
4190 /* Create the Thread's Context */
4192 RemotePeb,
4193 ImageInformation.TransferAddress,
4194 InitialTeb.StackBase,
4195 0);
4196
4197 /* Convert the thread attributes */
4198 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
4199 lpThreadAttributes,
4200 NULL);
4201 if ((hUserToken) && (lpThreadAttributes))
4202 {
4203 /* If the caller specified a user token, zero the security descriptor */
4204 LocalThreadAttributes = *lpThreadAttributes;
4205 LocalThreadAttributes.lpSecurityDescriptor = NULL;
4206 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
4207 &LocalThreadAttributes,
4208 NULL);
4209 }
4210
4211 /* Create the Kernel Thread Object */
4212 Status = NtCreateThread(&ThreadHandle,
4216 &ClientId,
4217 &Context,
4218 &InitialTeb,
4219 TRUE);
4220 if (!NT_SUCCESS(Status))
4221 {
4222 /* A process is not allowed to exist without a main thread, so fail */
4223 DPRINT1("Creating the main thread failed: %lx\n", Status);
4225 Result = FALSE;
4226 goto Quickie;
4227 }
4228
4229 /* Begin filling out the CSRSS message, first with our IDs and handles */
4230 CreateProcessMsg->ProcessHandle = ProcessHandle;
4231 CreateProcessMsg->ThreadHandle = ThreadHandle;
4232 CreateProcessMsg->ClientId = ClientId;
4233
4234 /* Write the remote PEB address and clear it locally, we no longer use it */
4235 CreateProcessMsg->PebAddressNative = RemotePeb;
4236#ifdef _WIN64
4237 DPRINT("TODO: WOW64 is not supported yet\n");
4238 CreateProcessMsg->PebAddressWow64 = 0;
4239#else
4240 CreateProcessMsg->PebAddressWow64 = (ULONG)RemotePeb;
4241#endif
4242 RemotePeb = NULL;
4243
4244 /* Now check what kind of architecture this image was made for */
4245 switch (ImageInformation.Machine)
4246 {
4247 /* IA32, IA64 and AMD64 are supported in Server 2003 */
4250 break;
4253 break;
4256 break;
4257
4258 /* Anything else results in image unknown -- but no failure */
4259 default:
4260 DbgPrint("kernel32: No mapping for ImageInformation.Machine == %04x\n",
4261 ImageInformation.Machine);
4263 break;
4264 }
4265
4266 /* Write the input creation flags except any debugger-related flags */
4267 CreateProcessMsg->CreationFlags = dwCreationFlags &
4269
4270 /* CSRSS needs to know if this is a GUI app or not */
4271 if ((ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_GUI) ||
4272 (IsWowApp))
4273 {
4274 /*
4275 * For GUI apps we turn on the 2nd bit. This allow CSRSS server dlls
4276 * (basesrv in particular) to know whether or not this is a GUI or a
4277 * TUI application.
4278 */
4279 AddToHandle(CreateProcessMsg->ProcessHandle, 2);
4280
4281 /* Also check if the parent is also a GUI process */
4283 if ((NtHeaders) &&
4285 {
4286 /* Let it know that it should display the hourglass mouse cursor */
4287 AddToHandle(CreateProcessMsg->ProcessHandle, 1);
4288 }
4289 }
4290
4291 /* For all apps, if this flag is on, the hourglass mouse cursor is shown.
4292 * Likewise, the opposite holds as well, and no-feedback has precedence. */
4293 if (StartupInfo.dwFlags & STARTF_FORCEONFEEDBACK)
4294 {
4295 AddToHandle(CreateProcessMsg->ProcessHandle, 1);
4296 }
4297 if (StartupInfo.dwFlags & STARTF_FORCEOFFFEEDBACK)
4298 {
4299 RemoveFromHandle(CreateProcessMsg->ProcessHandle, 1);
4300 }
4301
4302 /* Also store which kind of VDM app (if any) this is */
4303 CreateProcessMsg->VdmBinaryType = VdmBinaryType;
4304
4305 /* And if it really is a VDM app... */
4306 if (VdmBinaryType)
4307 {
4308 /* Store the VDM console handle (none if inherited or WOW app) and the task ID */
4309 CreateProcessMsg->hVDM = VdmTask ? NULL : Peb->ProcessParameters->ConsoleHandle;
4310 CreateProcessMsg->VdmTask = VdmTask;
4311 }
4312 else if (VdmReserve)
4313 {
4314 /* Extended VDM, set a flag */
4315 CreateProcessMsg->VdmBinaryType |= BINARY_TYPE_WOW_EX;
4316 }
4317
4318 /* Check if there's side-by-side assembly data associated with the process */
4319 if (CreateProcessMsg->Sxs.Flags)
4320 {
4321 /* This should not happen in ReactOS yet */
4322 DPRINT1("This is an SxS Message -- should not happen yet\n");
4325 Result = FALSE;
4326 goto Quickie;
4327 }
4328
4329 /* We are finally ready to call CSRSS to tell it about our new process! */
4331 CaptureBuffer,
4334 sizeof(*CreateProcessMsg));
4335
4336 /* CSRSS has returned, free the capture buffer now if we had one */
4337 if (CaptureBuffer)
4338 {
4339 CsrFreeCaptureBuffer(CaptureBuffer);
4340 CaptureBuffer = NULL;
4341 }
4342
4343 /* Check if CSRSS failed to accept ownership of the new Windows process */
4344 if (!NT_SUCCESS(CsrMsg[0].Status))
4345 {
4346 /* Terminate the process and enter failure path with the CSRSS status */
4347 DPRINT1("Failed to tell csrss about new process\n");
4348 BaseSetLastNTError(CsrMsg[0].Status);
4350 Result = FALSE;
4351 goto Quickie;
4352 }
4353
4354 /* Check if we have a token due to Authz/Safer, not passed by the user */
4355 if ((TokenHandle) && !(hUserToken))
4356 {
4357 /* Replace the process and/or thread token with the one from Safer */
4360 ThreadHandle);
4361 if (!NT_SUCCESS(Status))
4362 {
4363 /* If this failed, kill the process and enter the failure path */
4364 DPRINT1("Failed to update process token: %lx\n", Status);
4367 Result = FALSE;
4368 goto Quickie;
4369 }
4370 }
4371
4372 /* Check if a job was associated with this process */
4373 if (JobHandle)
4374 {
4375 /* Bind the process and job together now */
4377 if (!NT_SUCCESS(Status))
4378 {
4379 /* Kill the process and enter the failure path if binding failed */
4380 DPRINT1("Failed to assign process to job: %lx\n", Status);
4383 Result = FALSE;
4384 goto Quickie;
4385 }
4386 }
4387
4388 /* Finally, resume the thread to actually get the process started */
4389 if (!(dwCreationFlags & CREATE_SUSPENDED))
4390 {
4391 NtResumeThread(ThreadHandle, &ResumeCount);
4392 }
4393
4394VdmShortCircuit:
4395 /* We made it this far, meaning we have a fully created process and thread */
4396 Result = TRUE;
4397
4398 /* Anyone doing a VDM undo should now undo everything, since we are done */
4399 if (VdmUndoLevel) VdmUndoLevel |= VDM_UNDO_COMPLETED;
4400
4401 /* Having a VDM wait object implies this must be a VDM process */
4402 if (VdmWaitObject)
4403 {
4404 /* Check if it's a 16-bit separate WOW process */
4405 if (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW)
4406 {
4407 /* OR-in the special flag to indicate this, and return to caller */
4408 AddToHandle(VdmWaitObject, 2);
4409 lpProcessInformation->hProcess = VdmWaitObject;
4410
4411 /* Check if this was a re-used VDM */
4412 if (VdmUndoLevel & VDM_UNDO_REUSE)
4413 {
4414 /* No Client ID should be returned in this case */
4417 }
4418 }
4419 else
4420 {
4421 /* OR-in the special flag to indicate this is not a separate VDM,
4422 * and return the handle to the caller */
4423 AddToHandle(VdmWaitObject, 1);
4424 lpProcessInformation->hProcess = VdmWaitObject;
4425 }
4426
4427 /* Close the original process handle, since it's not needed for VDM */
4429 }
4430 else
4431 {
4432 /* This is a regular process, so return the real process handle */
4433 lpProcessInformation->hProcess = ProcessHandle;
4434 }
4435
4436 /* Return the rest of the process information based on what we have so far */
4437 lpProcessInformation->hThread = ThreadHandle;
4438 lpProcessInformation->dwProcessId = HandleToUlong(ClientId.UniqueProcess);
4439 lpProcessInformation->dwThreadId = HandleToUlong(ClientId.UniqueThread);
4440
4441 /* NULL these out here so we know to treat this as a success scenario */
4443 ThreadHandle = NULL;
4444
4445Quickie:
4446 /* Free the debugger command line if one was allocated */
4447 if (DebuggerCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
4448
4449 /* Check if an SxS full path as queried */
4450 if (PathBuffer)
4451 {
4452 /* Reinitialize the executable path */
4453 RtlInitEmptyUnicodeString(&SxsWin32ExePath, NULL, 0);
4454 SxsWin32ExePath.Length = 0;
4455
4456 /* Free the path buffer */
4457 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
4458 }
4459
4460#if _SXS_SUPPORT_ENABLED_
4461 /* Check if this was a non-VDM process */
4462 if (!VdmBinaryType)
4463 {
4464 /* Then it must've had SxS data, so close the handles used for it */
4465 BasepSxsCloseHandles(&Handles);
4466 BasepSxsCloseHandles(&FileHandles);
4467
4468 /* Check if we built SxS byte buffers for this create process request */
4469 if (SxsConglomeratedBuffer)
4470 {
4471 /* Loop all of them */
4472 for (i = 0; i < 5; i++)
4473 {
4474 /* Check if this one was allocated */
4475 ThisBuffer = SxsStaticBuffers[i];
4476 if (ThisBuffer)
4477 {
4478 /* Get the underlying RTL_BUFFER structure */
4479 ByteBuffer = &ThisBuffer->ByteBuffer;
4480 if ((ThisBuffer != (PVOID)-8) && (ByteBuffer->Buffer))
4481 {
4482 /* Check if it was dynamic */
4483 if (ByteBuffer->Buffer != ByteBuffer->StaticBuffer)
4484 {
4485 /* Free it from the heap */
4486 FreeString.Buffer = (PWCHAR)ByteBuffer->Buffer;
4488 }
4489
4490 /* Reset the buffer to its static data */
4491 ByteBuffer->Buffer = ByteBuffer->StaticBuffer;
4492 ByteBuffer->Size = ByteBuffer->StaticSize;
4493 }
4494
4495 /* Reset the string to the static buffer */
4496 RtlInitEmptyUnicodeString(&ThisBuffer->String,
4497 (PWCHAR)ByteBuffer->StaticBuffer,
4498 ByteBuffer->StaticSize);
4499 if (ThisBuffer->String.Buffer)
4500 {
4501 /* Also NULL-terminate it */
4502 *ThisBuffer->String.Buffer = UNICODE_NULL;
4503 }
4504 }
4505 }
4506 }
4507 }
4508#endif
4509 /* Check if an environment was passed in */
4510 if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
4511 {
4512 /* Destroy it */
4513 RtlDestroyEnvironment(lpEnvironment);
4514
4515 /* If this was the VDM environment too, clear that as well */
4516 if (VdmUnicodeEnv.Buffer == lpEnvironment) VdmUnicodeEnv.Buffer = NULL;
4517 lpEnvironment = NULL;
4518 }
4519
4520 /* Unconditionally free all the name parsing buffers we always allocate */
4521 RtlFreeHeap(RtlGetProcessHeap(), 0, QuotedCmdLine);
4522 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
4523 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDirectory);
4524 RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
4525
4526 /* Close open file/section handles */
4528 if (SectionHandle) NtClose(SectionHandle);
4529
4530 /* If we have a thread handle, this was a failure path */
4531 if (ThreadHandle)
4532 {
4533 /* So kill the process and close the thread handle */
4535 NtClose(ThreadHandle);
4536 }
4537
4538 /* If we have a process handle, this was a failure path, so close it */
4540
4541 /* Thread/process handles, if any, are now processed. Now close this one. */
4542 if (JobHandle) NtClose(JobHandle);
4543
4544 /* Check if we had created a token */
4545 if (TokenHandle)
4546 {
4547 /* And if the user asked for one */
4548 if (hUserToken)
4549 {
4550 /* Then return it */
4551 *hNewToken = TokenHandle;
4552 }
4553 else
4554 {
4555 /* User didn't want it, so we used it temporarily -- close it */
4557 }
4558 }
4559
4560 /* Free any temporary app compatibility data, it's no longer needed */
4561 BasepFreeAppCompatData(AppCompatData, AppCompatSxsData);
4562
4563 /* Free a few strings. The API takes care of these possibly being NULL */
4564 RtlFreeUnicodeString(&VdmString);
4565 RtlFreeUnicodeString(&DebuggerString);
4566
4567 /* Check if we had built any sort of VDM environment */
4568 if ((VdmAnsiEnv.Buffer) || (VdmUnicodeEnv.Buffer))
4569 {
4570 /* Free it */
4571 BaseDestroyVDMEnvironment(&VdmAnsiEnv, &VdmUnicodeEnv);
4572 }
4573
4574 /* Check if this was any kind of VDM application that we ended up creating */
4575 if ((VdmUndoLevel) && (!(VdmUndoLevel & VDM_UNDO_COMPLETED)))
4576 {
4577 /* Send an undo */
4579 (PHANDLE)&VdmTask,
4580 VdmUndoLevel,
4581 VdmBinaryType);
4582
4583 /* And close whatever VDM handle we were using for notifications */
4584 if (VdmWaitObject) NtClose(VdmWaitObject);
4585 }
4586
4587 /* Check if we ended up here with an allocated search path, and free it */
4588 if (SearchPath) RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
4589
4590 /* Finally, return the API's result */
4591 return Result;
4592}
4593
4594/*
4595 * @implemented
4596 */
4597BOOL
4598WINAPI
4600CreateProcessW(LPCWSTR lpApplicationName,
4601 LPWSTR lpCommandLine,
4602 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4603 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4604 BOOL bInheritHandles,
4605 DWORD dwCreationFlags,
4606 LPVOID lpEnvironment,
4607 LPCWSTR lpCurrentDirectory,
4608 LPSTARTUPINFOW lpStartupInfo,
4609 LPPROCESS_INFORMATION lpProcessInformation)
4610{
4611 /* Call the internal (but exported) version */
4613 lpApplicationName,
4614 lpCommandLine,
4615 lpProcessAttributes,
4616 lpThreadAttributes,
4617 bInheritHandles,
4618 dwCreationFlags,
4619 lpEnvironment,
4620 lpCurrentDirectory,
4621 lpStartupInfo,
4622 lpProcessInformation,
4623 NULL);
4624}
4625
4626/*
4627 * @implemented
4628 */
4629BOOL
4630WINAPI
4632 LPCSTR lpApplicationName,
4633 LPSTR lpCommandLine,
4634 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4635 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4636 BOOL bInheritHandles,
4637 DWORD dwCreationFlags,
4638 LPVOID lpEnvironment,
4639 LPCSTR lpCurrentDirectory,
4640 LPSTARTUPINFOA lpStartupInfo,
4641 LPPROCESS_INFORMATION lpProcessInformation,
4642 PHANDLE hNewToken)
4643{
4644 UNICODE_STRING CommandLine;
4647 BOOL bRetVal;
4648 STARTUPINFOW StartupInfo;
4649
4650 DPRINT("dwCreationFlags %x, lpEnvironment %p, lpCurrentDirectory %p, "
4651 "lpStartupInfo %p, lpProcessInformation %p\n",
4652 dwCreationFlags, lpEnvironment, lpCurrentDirectory,
4653 lpStartupInfo, lpProcessInformation);
4654
4655 /* Copy Startup Info */
4656 RtlMoveMemory(&StartupInfo, lpStartupInfo, sizeof(*lpStartupInfo));
4657
4658 /* Initialize all strings to nothing */
4659 CommandLine.Buffer = NULL;
4660 ApplicationName.Buffer = NULL;
4661 CurrentDirectory.Buffer = NULL;
4662 StartupInfo.lpDesktop = NULL;
4663 StartupInfo.lpReserved = NULL;
4664 StartupInfo.lpTitle = NULL;
4665
4666 /* Convert the Command line */
4667 if (lpCommandLine)
4668 {
4670 lpCommandLine);
4671 }
4672
4673 /* Convert the Name and Directory */
4674 if (lpApplicationName)
4675 {
4677 lpApplicationName);
4678 }
4679 if (lpCurrentDirectory)
4680 {
4682 lpCurrentDirectory);
4683 }
4684
4685 /* Now convert Startup Strings */
4686 if (lpStartupInfo->lpReserved)
4687 {
4689 &StartupInfo.lpReserved);
4690 }
4691 if (lpStartupInfo->lpDesktop)
4692 {
4694 &StartupInfo.lpDesktop);
4695 }
4696 if (lpStartupInfo->lpTitle)
4697 {
4699 &StartupInfo.lpTitle);
4700 }
4701
4702 /* Call the Unicode function */
4703 bRetVal = CreateProcessInternalW(hToken,
4704 ApplicationName.Buffer,
4705 CommandLine.Buffer,
4706 lpProcessAttributes,
4707 lpThreadAttributes,
4708 bInheritHandles,
4709 dwCreationFlags,
4710 lpEnvironment,
4711 CurrentDirectory.Buffer,
4712 &StartupInfo,
4713 lpProcessInformation,
4714 hNewToken);
4715
4716 /* Clean up */
4718 RtlFreeUnicodeString(&CommandLine);
4720 RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpDesktop);
4721 RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpReserved);
4722 RtlFreeHeap(RtlGetProcessHeap(), 0, StartupInfo.lpTitle);
4723
4724 /* Return what Unicode did */
4725 return bRetVal;
4726}
4727
4728/*
4729 * FUNCTION: The CreateProcess function creates a new process and its
4730 * primary thread. The new process executes the specified executable file
4731 * ARGUMENTS:
4732 *
4733 * lpApplicationName = Pointer to name of executable module
4734 * lpCommandLine = Pointer to command line string
4735 * lpProcessAttributes = Process security attributes
4736 * lpThreadAttributes = Thread security attributes
4737 * bInheritHandles = Handle inheritance flag
4738 * dwCreationFlags = Creation flags
4739 * lpEnvironment = Pointer to new environment block
4740 * lpCurrentDirectory = Pointer to current directory name
4741 * lpStartupInfo = Pointer to startup info
4742 * lpProcessInformation = Pointer to process information
4743 *
4744 * @implemented
4745 */
4746BOOL
4747WINAPI
4749CreateProcessA(LPCSTR lpApplicationName,
4750 LPSTR lpCommandLine,
4751 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4752 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4753 BOOL bInheritHandles,
4754 DWORD dwCreationFlags,
4755 LPVOID lpEnvironment,
4756 LPCSTR lpCurrentDirectory,
4757 LPSTARTUPINFOA lpStartupInfo,
4758 LPPROCESS_INFORMATION lpProcessInformation)
4759{
4760 /* Call the internal (but exported) version */
4762 lpApplicationName,
4763 lpCommandLine,
4764 lpProcessAttributes,
4765 lpThreadAttributes,
4766 bInheritHandles,
4767 dwCreationFlags,
4768 lpEnvironment,
4769 lpCurrentDirectory,
4770 lpStartupInfo,
4771 lpProcessInformation,
4772 NULL);
4773}
4774
4775/*
4776 * @implemented
4777 */
4778UINT
4779WINAPI
4781WinExec(LPCSTR lpCmdLine,
4782 UINT uCmdShow)
4783{
4784 STARTUPINFOA StartupInfo;
4785 PROCESS_INFORMATION ProcessInformation;
4786 DWORD dosErr;
4787
4788 RtlZeroMemory(&StartupInfo, sizeof(StartupInfo));
4789 StartupInfo.cb = sizeof(STARTUPINFOA);
4790 StartupInfo.wShowWindow = (WORD)uCmdShow;
4791 StartupInfo.dwFlags = 0;
4792
4793 if (!CreateProcessA(NULL,
4794 (PVOID)lpCmdLine,
4795 NULL,
4796 NULL,
4797 FALSE,
4798 0,
4799 NULL,
4800 NULL,
4801 &StartupInfo,
4802 &ProcessInformation))
4803 {
4804 dosErr = GetLastError();
4805 return dosErr < 32 ? dosErr : ERROR_BAD_FORMAT;
4806 }
4807
4809 {
4810 UserWaitForInputIdleRoutine(ProcessInformation.hProcess,
4811 10000);
4812 }
4813
4814 NtClose(ProcessInformation.hProcess);
4815 NtClose(ProcessInformation.hThread);
4816
4817 return 33; /* Something bigger than 31 means success. */
4818}
4819
4820/* EOF */
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3483
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3076
#define NtCurrentPeb()
Definition: FLS.c:22
unsigned char BOOLEAN
static IN ULONG IN PWSTR OUT PCWSTR OUT PBOOLEAN OUT PATH_TYPE_AND_UNKNOWN * PathType
static ULONG StackSize
Definition: StackOverflow.c:19
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:240
NTSTATUS WINAPI BasepCheckBadapp(IN HANDLE FileHandle, IN PWCHAR ApplicationName, IN PWCHAR Environment, IN USHORT ExeType, IN PVOID *SdbQueryAppCompatData, IN PULONG SdbQueryAppCompatDataSize, IN PVOID *SxsData, IN PULONG SxsDataSize, OUT PULONG FusionFlags)
Definition: appcache.c:374
VOID WINAPI BasepFreeAppCompatData(IN PVOID AppCompatData, IN PVOID AppCompatSxsData)
Definition: appcache.c:444
LONG NTSTATUS
Definition: precomp.h:26
#define FILE_NON_DIRECTORY_FILE
Definition: constants.h:492
#define DPRINT1
Definition: precomp.h:8
HANDLE hUserToken
Definition: install.c:39
BOOL Error
Definition: chkdsk.c:66
WCHAR CurrentDirectory[1024]
Definition: chkdsk.c:74
static DWORD ResumeCount
Definition: database.c:31
@ BasepCreateProcess
Definition: basemsg.h:21
@ BasepGetProcessShutdownParam
Definition: basemsg.h:34
@ BasepSetProcessShutdownParam
Definition: basemsg.h:33
@ BasepExitProcess
Definition: basemsg.h:24
#define BASESRV_SERVERDLL_INDEX
Definition: basemsg.h:15
#define UlongToHandle(ul)
Definition: basetsd.h:91
ULONG_PTR * PDWORD_PTR
Definition: basetsd.h:176
#define HandleToUlong(h)
Definition: basetsd.h:73
#define UNIMPLEMENTED
Definition: ntoskrnl.c:15
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:616
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:634
@ ProcessBasicInformation
Definition: cicbase.cpp:63
@ ProcessWow64Information
Definition: cicbase.cpp:65
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
SIZE_T LPSTARTUPINFOW
Definition: cordebug.idl:85
SIZE_T LPPROCESS_INFORMATION
Definition: cordebug.idl:86
wcscat
wcscpy
#define CSR_CREATE_API_NUMBER(ServerId, ApiId)
Definition: csrmsg.h:37
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define STATUS_NOT_IMPLEMENTED
Definition: d3dkmdt.h:42
#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
NTSYSAPI NTSTATUS NTAPI RtlComputeImportTableHash(IN HANDLE FileHandle, OUT PCHAR Hash, IN ULONG ImportTableHashSize)
Definition: libsupp.c:1191
static const WCHAR Title[]
Definition: oid.c:1259
#define CloseHandle
Definition: compat.h:739
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:758
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define PAGE_READONLY
Definition: compat.h:138
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
@ ThreadQuerySetWin32StartAddress
Definition: compat.h:944
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define IsWow64Process
Definition: compat.h:760
#define GetProcessId(x)
Definition: compat.h:737
#define RtlImageNtHeader
Definition: compat.h:806
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define LoadLibraryW(x)
Definition: compat.h:747
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
PPEB Peb
Definition: dllmain.c:27
PBASE_STATIC_SERVER_DATA BaseStaticServerData
Definition: dllmain.c:19
BOOLEAN BaseRunningInServerProcess
Definition: dllmain.c:20
LONG WINAPI UnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
Definition: except.c:269
BOOL NTAPI IsBadWritePtr(IN LPVOID lp, IN UINT_PTR ucb)
Definition: except.c:883
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c:652
LPWSTR WINAPI BaseComputeProcessDllPath(IN LPWSTR FullPath, IN PVOID Environment)
Definition: path.c:420
LPWSTR WINAPI BaseComputeProcessExePath(IN LPWSTR FullPath)
Definition: path.c:405
DWORD WINAPI SearchPathW(IN LPCWSTR lpPath OPTIONAL, IN LPCWSTR lpFileName, IN LPCWSTR lpExtension OPTIONAL, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart OPTIONAL)
Definition: path.c:1298
UINT WINAPI GetSystemDirectoryW(OUT LPWSTR lpBuffer, IN UINT uSize)
Definition: path.c:2313
DWORD WINAPI GetFullPathNameW(IN LPCWSTR lpFileName, IN DWORD nBufferLength, OUT LPWSTR lpBuffer, OUT LPWSTR *lpFilePart)
Definition: path.c:1106
BOOL NTAPI WriteProcessMemory(IN HANDLE hProcess, IN LPVOID lpBaseAddress, IN LPCVOID lpBuffer, IN SIZE_T nSize, OUT SIZE_T *lpNumberOfBytesWritten)
Definition: proc.c:2064
VOID WINAPI FatalAppExitA(UINT uAction, LPCSTR lpMessageText)
Definition: proc.c:1564
VOID WINAPI FatalExit(IN int ExitCode)
Definition: proc.c:1626
BOOL WINAPI CreateProcessInternalA(HANDLE hToken, LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation, PHANDLE hNewToken)
Definition: proc.c:4631
BOOLEAN WINAPI BasePushProcessParameters(IN ULONG ParameterFlags, IN HANDLE ProcessHandle, IN PPEB RemotePeb, IN LPCWSTR ApplicationPathName, IN LPWSTR lpCurrentDirectory, IN LPWSTR lpCommandLine, IN LPVOID lpEnvironment, IN LPSTARTUPINFOW StartupInfo, IN DWORD CreationFlags, IN BOOL InheritHandles, IN ULONG ImageSubsystem, IN PVOID AppCompatData, IN ULONG AppCompatDataSize)
Definition: proc.c:484
NTSTATUS NTAPI BasepConfigureAppCertDlls(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: proc.c:189
BOOL WINAPI CreateProcessInternalW(IN HANDLE hUserToken, IN LPCWSTR lpApplicationName, IN LPWSTR lpCommandLine, IN LPSECURITY_ATTRIBUTES lpProcessAttributes, IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN BOOL bInheritHandles, IN DWORD dwCreationFlags, IN LPVOID lpEnvironment, IN LPCWSTR lpCurrentDirectory, IN LPSTARTUPINFOW lpStartupInfo, IN LPPROCESS_INFORMATION lpProcessInformation, OUT PHANDLE hNewToken)
Definition: proc.c:2242
BOOL WINAPI FlushInstructionCache(IN HANDLE hProcess, IN LPCVOID lpBaseAddress, IN SIZE_T nSize)
Definition: proc.c:1465
BOOL WINAPI GetProcessWorkingSetSizeEx(IN HANDLE hProcess, OUT PSIZE_T lpMinimumWorkingSetSize, OUT PSIZE_T lpMaximumWorkingSetSize, OUT PDWORD Flags)
Definition: proc.c:978
NTSTATUS WINAPI BasepCheckWebBladeHashes(IN HANDLE FileHandle)
Definition: proc.c:149
PBASEP_APPCERT_EMBEDDED_FUNC fEmbeddedCertFunc
Definition: proc.c:30
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessW(LPCWSTR lpApplicationName, LPWSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCWSTR lpCurrentDirectory, LPSTARTUPINFOW lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4600
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1168
RTL_QUERY_REGISTRY_TABLE BasepAppCertTable[2]
Definition: proc.c:32
UNICODE_STRING BasePathVariableName
Definition: proc.c:23
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1489
VOID WINAPI StuffStdHandle(IN HANDLE ProcessHandle, IN HANDLE StandardHandle, IN PHANDLE Address)
Definition: proc.c:57
RTL_CRITICAL_SECTION gcsAppCert
Definition: proc.c:29
BOOLEAN WINAPI BuildSubSysCommandLine(IN LPCWSTR SubsystemName, IN LPCWSTR ApplicationName, IN LPCWSTR CommandLine, OUT PUNICODE_STRING SubsysCommandLine)
Definition: proc.c:89
DWORD WINAPI GetProcessVersion(IN DWORD ProcessId)
Definition: proc.c:1768
LIST_ENTRY BasepAppCertDllsList
Definition: proc.c:28
UNICODE_STRING BaseUnicodeCommandLine
Definition: proc.c:21
WaitForInputIdleType UserWaitForInputIdleRoutine
Definition: proc.c:20
BOOLEAN g_AppCertInitialized
Definition: proc.c:26
BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation)
Definition: proc.c:4749
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1534
NTSTATUS WINAPI BasepIsProcessAllowed(IN LPWSTR ApplicationName)
Definition: proc.c:202
ANSI_STRING BaseAnsiCommandLine
Definition: proc.c:22
#define AddToHandle(x, y)
Definition: proc.c:2233
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1227
BOOL WINAPI GetProcessPriorityBoost(IN HANDLE hProcess, OUT PBOOL pDisablePriorityBoost)
Definition: proc.c:1896
BOOL WINAPI GetProcessTimes(IN HANDLE hProcess, IN LPFILETIME lpCreationTime, IN LPFILETIME lpExitTime, IN LPFILETIME lpKernelTime, IN LPFILETIME lpUserTime)
Definition: proc.c:1099
BOOLEAN g_HaveAppCerts
Definition: proc.c:27
PLDR_DATA_TABLE_ENTRY BasepExeLdrEntry
Definition: proc.c:25
BOOL WINAPI SetProcessWorkingSetSizeEx(IN HANDLE hProcess, IN SIZE_T dwMinimumWorkingSetSize, IN SIZE_T dwMaximumWorkingSetSize, IN DWORD Flags)
Definition: proc.c:1027
NTSTATUS WINAPI BasepReplaceProcessThreadTokens(IN HANDLE TokenHandle, IN HANDLE ProcessHandle, IN HANDLE ThreadHandle)
Definition: proc.c:354
BOOL WINAPI SetProcessWorkingSetSize(IN HANDLE hProcess, IN SIZE_T dwMinimumWorkingSetSize, IN SIZE_T dwMaximumWorkingSetSize)
Definition: proc.c:1083
BOOL WINAPI GetProcessHandleCount(IN HANDLE hProcess, OUT PDWORD pdwHandleCount)
Definition: proc.c:1953
BOOL WINAPI SetProcessShutdownParameters(IN DWORD dwLevel, IN DWORD dwFlags)
Definition: proc.c:949
HMODULE gSaferHandle
Definition: proc.c:46
NTSTATUS g_AppCertStatus
Definition: proc.c:31
BOOL WINAPI ProcessIdToSessionId(IN DWORD dwProcessId, OUT PDWORD pSessionId)
Definition: proc.c:2183
VOID WINAPI RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle)
DWORD WINAPI GetPriorityClass(IN HANDLE hProcess)
Definition: proc.c:1665
DECLSPEC_NORETURN VOID WINAPI BaseProcessStartup(_In_ PPROCESS_START_ROUTINE lpStartAddress)
Definition: proc.c:451
BOOL WINAPI GetProcessIoCounters(IN HANDLE hProcess, OUT PIO_COUNTERS lpIoCounters)
Definition: proc.c:1869
VOID WINAPI FatalAppExitW(IN UINT uAction, IN LPCWSTR lpMessageText)
Definition: proc.c:1588
BOOL WINAPI SetProcessPriorityBoost(IN HANDLE hProcess, IN BOOL bDisablePriorityBoost)
Definition: proc.c:1925
VOID WINAPI InitCommandLines(VOID)
Definition: proc.c:842
BOOL WINAPI GetProcessWorkingSetSize(IN HANDLE hProcess, OUT PSIZE_T lpMinimumWorkingSetSize, OUT PSIZE_T lpMaximumWorkingSetSize)
Definition: proc.c:1011
PSAFER_REPLACE_PROCESS_THREAD_TOKENS g_SaferReplaceProcessThreadTokens
Definition: proc.c:45
BOOL WINAPI SetPriorityClass(IN HANDLE hProcess, IN DWORD dwPriorityClass)
Definition: proc.c:1700
VOID WINAPI GetStartupInfoW(IN LPSTARTUPINFOW lpStartupInfo)
Definition: proc.c:1279
BOOL WINAPI GetProcessShutdownParameters(OUT LPDWORD lpdwLevel, OUT LPDWORD lpdwFlags)
Definition: proc.c:920
VOID WINAPI BasepSxsCloseHandles(IN PBASE_MSG_SXS_HANDLES Handles)
Definition: proc.c:417
#define CMD_STRING
Definition: proc.c:51
#define RemoveFromHandle(x, y)
Definition: proc.c:2234
BOOL WINAPI SetProcessAffinityMask(IN HANDLE hProcess, IN DWORD_PTR dwProcessAffinityMask)
Definition: proc.c:894
BOOLEAN WINAPI BasepIsImageVersionOk(IN ULONG ImageMajorVersion, IN ULONG ImageMinorVersion)
Definition: proc.c:123
VOID WINAPI GetStartupInfoA(IN LPSTARTUPINFOA lpStartupInfo)
Definition: proc.c:1320
LPSTARTUPINFOA BaseAnsiStartupInfo
Definition: proc.c:24
NTSTATUS NTAPI BasepSaveAppCertRegistryValue(IN PLIST_ENTRY List, IN PWCHAR ComponentName, IN PWCHAR DllName)
Definition: proc.c:178
UINT WINAPI DECLSPEC_HOTPATCH WinExec(LPCSTR lpCmdLine, UINT uCmdShow)
Definition: proc.c:4781
BOOL WINAPI GetProcessAffinityMask(IN HANDLE hProcess, OUT PDWORD_PTR lpProcessAffinityMask, OUT PDWORD_PTR lpSystemAffinityMask)
Definition: proc.c:863
VOID WINAPI ExitThread(IN DWORD uExitCode)
Definition: thread.c:365
NTSTATUS WINAPI BaseCreateStack(_In_ HANDLE hProcess, _In_opt_ SIZE_T StackCommit, _In_opt_ SIZE_T StackReserve, _Out_ PINITIAL_TEB InitialTeb)
Definition: utils.c:354
BOOLEAN WINAPI Basep8BitStringToDynamicUnicodeString(OUT PUNICODE_STRING UnicodeString, IN LPCSTR String)
Definition: utils.c:225
VOID WINAPI BaseInitializeContext(IN PCONTEXT Context, IN PVOID Parameter, IN PVOID StartAddress, IN PVOID StackAddress, IN ULONG ContextType)
Definition: utils.c:513
POBJECT_ATTRIBUTES WINAPI BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes, IN PSECURITY_ATTRIBUTES SecurityAttributes OPTIONAL, IN PUNICODE_STRING ObjectName)
Definition: utils.c:304
VOID WINAPI BasepAnsiStringToHeapUnicodeString(IN LPCSTR AnsiString, OUT LPWSTR *UnicodeString)
Definition: utils.c:263
NTSTATUS WINAPI BasepCheckWinSaferRestrictions(IN HANDLE UserToken, IN LPWSTR ApplicationName, IN HANDLE FileHandle, OUT PBOOLEAN InJob, OUT PHANDLE NewToken, OUT PHANDLE JobHandle)
Definition: utils.c:921
PVOID WINAPI BasepIsRealtimeAllowed(IN BOOLEAN Keep)
Definition: utils.c:665
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
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
BOOL WINAPI BaseUpdateVDMEntry(IN ULONG UpdateIndex, IN OUT PHANDLE WaitHandle, IN ULONG IndexInfo, IN ULONG BinaryType)
Definition: vdm.c:542
BOOL NTAPI BaseCreateVDMEnvironment(IN PWCHAR lpEnvironment, OUT PANSI_STRING AnsiEnv, OUT PUNICODE_STRING UnicodeEnv)
Definition: vdm.c:744
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
#define HANDLE_CREATE_NEW_CONSOLE
Definition: console.h:14
#define HANDLE_CREATE_NO_WINDOW
Definition: console.h:15
#define HANDLE_DETACHED_PROCESS
Definition: console.h:13
LPWSTR WINAPI GetCommandLineW(void)
Definition: process.c:1338
LPSTR WINAPI GetCommandLineA(void)
Definition: process.c:1329
static int Hash(const char *)
Definition: reader.c:2237
#define L(x)
Definition: resources.c:13
#define ULONG_PTR
Definition: config.h:101
#define IsListEmpty(ListHead)
Definition: env_spec_w32.h:954
NTSTATUS RtlAppendUnicodeToString(IN PUNICODE_STRING Str1, IN PWSTR Str2)
Definition: string_lib.cpp:62
IN PLARGE_INTEGER IN PLARGE_INTEGER PEPROCESS ProcessId
Definition: fatprocs.h:2712
unsigned short WORD
Definition: ntddk_ex.h:93
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
_Must_inspect_result_ _In_opt_ PFLT_INSTANCE _Out_ PHANDLE FileHandle
Definition: fltkernel.h:1231
#define STATUS_ACCESS_VIOLATION
#define FILE_SYNCHRONOUS_IO_NONALERT
Definition: from_kernel.h:31
_Must_inspect_result_ _In_ PLARGE_INTEGER _In_ PLARGE_INTEGER _In_ ULONG _In_ PFILE_OBJECT _In_ PVOID Process
Definition: fsrtlfuncs.h:223
Status
Definition: gdiplustypes.h:25
GLdouble n
Definition: glext.h:7729
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 DbgPrint
Definition: hal.h:12
NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
Definition: harderr.c:551
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
_CRTIMP size_t __cdecl wcslen(_In_z_ const wchar_t *_Str)
#define PROCESS_VM_READ
Definition: pstypes.h:162
#define PROCESS_CREATE_FLAGS_BREAKAWAY
Definition: pstypes.h:92
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:167
#define PROCESS_PRIORITY_CLASS_IDLE
Definition: pstypes.h:108
#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES
Definition: pstypes.h:94
#define PROCESS_PRIORITY_CLASS_INVALID
Definition: pstypes.h:107
#define PROCESS_PRIORITY_CLASS_NORMAL
Definition: pstypes.h:109
#define PROCESS_PRIORITY_CLASS_HIGH
Definition: pstypes.h:110
#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
Definition: pstypes.h:113
#define PROCESS_CREATE_FLAGS_LARGE_PAGES
Definition: pstypes.h:96
#define PROCESS_PRIORITY_CLASS_BELOW_NORMAL
Definition: pstypes.h:112
#define PROCESS_PRIORITY_CLASS_REALTIME
Definition: pstypes.h:111
#define FLG_DISABLE_DEBUG_PROMPTS
Definition: pstypes.h:86
#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT
Definition: pstypes.h:93
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:84
NTSYSAPI NTSTATUS WINAPI DbgUiConnectToDbg(void)
Definition: dbgui.c:25
NTSYSAPI void WINAPI RtlAcquirePebLock(void)
Definition: libsupp.c:74
NTSYSAPI void WINAPI DbgBreakPoint(void)
NTSYSAPI void WINAPI LdrShutdownProcess(void)
Definition: ldrinit.c:950
NTSYSAPI HANDLE WINAPI DbgUiGetThreadDebugObject(void)
Definition: dbgui.c:333
NTSYSAPI NTSTATUS WINAPI RtlQueryRegistryValues(ULONG, PCWSTR, PRTL_QUERY_REGISTRY_TABLE, PVOID, PVOID)
@ ProcessSessionInformation
Definition: winternl.h:1906
@ ProcessAffinityMask
Definition: winternl.h:1903
@ ProcessPriorityClass
Definition: winternl.h:1900
@ ProcessPriorityBoost
Definition: winternl.h:1904
@ ProcessIoCounters
Definition: winternl.h:1884
@ ProcessDefaultHardErrorMode
Definition: winternl.h:1894
@ ProcessQuotaLimits
Definition: winternl.h:1883
@ ProcessTimes
Definition: winternl.h:1886
@ ProcessHandleCount
Definition: winternl.h:1902
#define NtCurrentThread()
Definition: winternl.h:5364
NTSYSAPI ULONG WINAPI RtlGetNtGlobalFlags(void)
Definition: libsupp.c:95
#define InterlockedCompareExchangePointer
Definition: interlocked.h:144
#define C_ASSERT(e)
Definition: intsafe.h:73
#define NtCurrentTeb
NTSTATUS(NTAPI * PSAFER_REPLACE_PROCESS_THREAD_TOKENS)(IN HANDLE Token, IN HANDLE Process, IN HANDLE Thread)
Definition: kernel32.h:379
DWORD(* WaitForInputIdleType)(HANDLE hProcess, DWORD dwMilliseconds)
Definition: kernel32.h:112
NTSTATUS(NTAPI * PBASEP_APPCERT_EMBEDDED_FUNC)(IN LPWSTR ApplicationName)
Definition: kernel32.h:374
DWORD(WINAPI * PPROCESS_START_ROUTINE)(VOID)
Definition: kernel32.h:246
#define REG_SZ
Definition: layer.c:22
NTSTATUS NTAPI LdrQueryImageFileKeyOption(_In_ HANDLE KeyHandle, _In_ PCWSTR ValueName, _In_ ULONG Type, _Out_ PVOID Buffer, _In_ ULONG BufferSize, _Out_opt_ PULONG ReturnedLength)
Definition: ldrinit.c:184
NTSTATUS NTAPI LdrOpenImageFileOptionsKey(_In_ PUNICODE_STRING SubKey, _In_ BOOLEAN Wow64, _Out_ PHANDLE NewKeyHandle)
Definition: ldrinit.c:111
NTSTATUS NTAPI LdrUnloadDll(_In_ PVOID BaseAddress)
Definition: ldrapi.c:1291
NTSTATUS NTAPI LdrGetProcedureAddress(_In_ PVOID BaseAddress, _In_opt_ _When_(Ordinal==0, _Notnull_) PANSI_STRING Name, _In_opt_ _When_(Name==NULL, _In_range_(>, 0)) ULONG Ordinal, _Out_ PVOID *ProcedureAddress)
Definition: ldrapi.c:789
if(dx< 0)
Definition: linetemp.h:194
_In_ BOOL _In_ HANDLE hProcess
Definition: mapping.h:71
CONST void * LPCVOID
Definition: minwindef.h:164
BOOL * PBOOL
Definition: minwindef.h:137
#define PCHAR
Definition: match.c:90
#define ASSERT(a)
Definition: mode.c:44
PVOID PVOID PWCHAR PVOID USHORT PULONG PVOID PULONG PVOID PULONG PULONG FusionFlags
Definition: env.c:49
PVOID PVOID PWCHAR ApplicationName
Definition: env.c:47
#define SE_INC_BASE_PRIORITY_PRIVILEGE
Definition: security.c:668
#define SE_LOCK_MEMORY_PRIVILEGE
Definition: security.c:658
static const char const char * DllPath
Definition: image.c:34
static const char * ImageName
Definition: image.c:34
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
DWORD e_lfanew
Definition: crypt.c:1156
#define DBG(x)
Definition: moztest.c:12
unsigned int UINT
Definition: ndis.h:50
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define HARDERROR_OVERRIDE_ERRORMODE
Definition: extypes.h:146
@ OptionOkCancel
Definition: extypes.h:188
@ OptionOk
Definition: extypes.h:187
@ ResponseOk
Definition: extypes.h:205
@ ResponseCancel
Definition: extypes.h:202
#define PROCESSOR_ARCHITECTURE_IA64
Definition: ketypes.h:111
#define PROCESSOR_ARCHITECTURE_UNKNOWN
Definition: ketypes.h:115
#define PROCESSOR_ARCHITECTURE_AMD64
Definition: ketypes.h:114
#define PROCESSOR_ARCHITECTURE_INTEL
Definition: ketypes.h:105
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
#define SEC_IMAGE
Definition: mmtypes.h:97
@ SectionImageInformation
Definition: mmtypes.h:196
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:153
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:727
NTSYSAPI NTSTATUS NTAPI RtlDestroyProcessParameters(_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
NTSYSAPI NTSTATUS NTAPI RtlCreateProcessParameters(_Out_ PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, _In_ PUNICODE_STRING ImagePathName, _In_opt_ PUNICODE_STRING DllPath, _In_opt_ PUNICODE_STRING CurrentDirectory, _In_opt_ PUNICODE_STRING CommandLine, _In_opt_ PWSTR Environment, _In_opt_ PUNICODE_STRING WindowTitle, _In_opt_ PUNICODE_STRING DesktopInfo, _In_opt_ PUNICODE_STRING ShellInfo, _In_opt_ PUNICODE_STRING RuntimeInfo)
NTSYSAPI ULONG NTAPI RtlIsDosDeviceName_U(_In_ PCWSTR Name)
NTSYSAPI NTSTATUS NTAPI RtlAcquirePrivilege(_In_ PULONG Privilege, _In_ ULONG NumPriv, _In_ ULONG Flags, _Out_ PVOID *ReturnedState)
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4210
NTSTATUS NTAPI RtlGetFullPathName_UstrEx(_In_ PUNICODE_STRING FileName, _In_opt_ PUNICODE_STRING StaticString, _In_opt_ PUNICODE_STRING DynamicString, _Out_opt_ PUNICODE_STRING *StringUsed, _Out_opt_ PSIZE_T FilePartSize, _Out_opt_ PBOOLEAN NameInvalid, _Out_ RTL_PATH_TYPE *PathType, _Out_opt_ PSIZE_T LengthNeeded)
VOID NTAPI RtlReleaseRelativeName(_In_ PRTL_RELATIVE_NAME_U RelativeName)
NTSYSAPI VOID NTAPI RtlDestroyEnvironment(_In_ PWSTR Environment)
NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path)
NTSYSAPI VOID NTAPI RtlReleasePrivilege(_In_ PVOID ReturnedState)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2486
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSYSAPI ULONG NTAPI DbgPrompt(_In_z_ PCCH Prompt, _Out_writes_bytes_(MaximumResponseLength) PCH Response, _In_ ULONG MaximumResponseLength)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToRelativeNtPathName_U(_In_ PCWSTR DosName, _Out_ PUNICODE_STRING NtName, _Out_ PCWSTR *PartName, _Out_ PRTL_RELATIVE_NAME_U RelativeName)
#define RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING
Definition: rtltypes.h:54
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_KERNEL
Definition: rtltypes.h:43
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_SERVER
Definition: rtltypes.h:44
#define SEM_FAILCRITICALERRORS
Definition: rtltypes.h:69
#define RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH
Definition: rtltypes.h:53
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_USER
Definition: rtltypes.h:42
@ RtlPathTypeRootLocalDevice
Definition: rtltypes.h:472
@ RtlPathTypeRelative
Definition: rtltypes.h:470
@ RtlPathTypeUncAbsolute
Definition: rtltypes.h:466
@ RtlPathTypeLocalDevice
Definition: rtltypes.h:471
@ RtlPathTypeDriveAbsolute
Definition: rtltypes.h:467
enum _RTL_PATH_TYPE RTL_PATH_TYPE
#define RTL_USER_PROCESS_PARAMETERS_DISABLE_HEAP_CHECKS
Definition: rtltypes.h:49
VOID WINAPI FreeString(_In_ LPWSTR pszString)
Definition: netsh.c:278
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
_Out_ LPWSTR lpBuffer
Definition: netsh.h:68
#define _In_
Definition: no_sal2.h:158
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1342
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3953
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define PAGE_WRITECOPY
Definition: nt_native.h:1308
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSYSAPI VOID NTAPI RtlFreeAnsiString(PANSI_STRING AnsiString)
NTSYSAPI NTSTATUS NTAPI RtlAppendUnicodeStringToString(PUNICODE_STRING Destination, PUNICODE_STRING Source)
#define PAGE_READWRITE
Definition: nt_native.h:1307
#define SECTION_ALL_ACCESS
Definition: nt_native.h:1296
#define FILE_READ_ATTRIBUTES
Definition: nt_native.h:647
#define KEY_READ
Definition: nt_native.h:1026
#define PROCESS_ALL_ACCESS
Definition: nt_native.h:1327
NTSYSAPI NTSTATUS NTAPI RtlAnsiStringToUnicodeString(PUNICODE_STRING DestinationString, PANSI_STRING SourceString, BOOLEAN AllocateDestinationString)
#define PAGE_EXECUTE
Definition: nt_native.h:1309
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSTATUS NTAPI NtTerminateProcess(HANDLE ProcessHandle, LONG ExitStatus)
#define NtCurrentProcess()
Definition: nt_native.h:1660
#define FILE_SHARE_DELETE
Definition: nt_native.h:682
#define FILE_EXECUTE
Definition: nt_native.h:642
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
#define PAGE_EXECUTE_WRITECOPY
Definition: nt_native.h:1312
#define FILE_ATTRIBUTE_DIRECTORY
Definition: nt_native.h:705
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define MEM_RESERVE
Definition: nt_native.h:1317
#define MEM_RELEASE
Definition: nt_native.h:1319
#define DWORD
Definition: nt_native.h:44
NTSYSAPI NTSTATUS NTAPI NtCreateThread(OUT PHANDLE phThread, IN ACCESS_MASK AccessMask, IN POBJECT_ATTRIBUTES ObjectAttributes, IN HANDLE hProcess, OUT PCLIENT_ID pClientId, IN PCONTEXT pContext, OUT PSTACKINFO pStackInfo, IN BOOLEAN bSuspended)
#define MEM_COMMIT
Definition: nt_native.h:1316
NTSYSAPI VOID NTAPI RtlInitAnsiString(PANSI_STRING DestinationString, PCSZ SourceString)
#define PAGE_NOACCESS
Definition: nt_native.h:1305
#define PAGE_EXECUTE_READWRITE
Definition: nt_native.h:1311
#define DECLSPEC_ALIGN(x)
Definition: ntbasedef.h:263
#define UNICODE_NULL
#define UNICODE_STRING_MAX_CHARS
#define UNICODE_STRING_MAX_BYTES
#define VER_SUITE_DATACENTER
#define DECLSPEC_NORETURN
Definition: ntbasedef.h:179
#define VER_SUITE_STORAGE_SERVER
#define VER_SUITE_COMPUTE_SERVER
#define VER_SUITE_PERSONAL
#define ANSI_NULL
#define VER_SUITE_BLADE
#define VER_SUITE_EMBEDDEDNT
_In_ ULONG _In_ ULONG _In_ ULONG Length
Definition: ntddpcm.h:102
#define RTL_CONSTANT_OBJECT_ATTRIBUTES(n, a)
static OUT PIO_STATUS_BLOCK IoStatusBlock
Definition: pipe.c:75
static BOOL bInheritHandle
Definition: pipe.c:82
#define IMAGE_SUBSYSTEM_POSIX_CUI
Definition: ntimage.h:440
#define IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: ntimage.h:438
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION
Definition: ntimage.h:458
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
#define IMAGE_FILE_MACHINE_IA64
Definition: ntimage.h:22
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5192
NTSTATUS NTAPI NtWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN SIZE_T NumberOfBytesToWrite, OUT PSIZE_T NumberOfBytesWritten OPTIONAL)
Definition: virtual.c:2895
NTSTATUS NTAPI NtProtectVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UnsafeBaseAddress, IN OUT SIZE_T *UnsafeNumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG UnsafeOldAccessProtection)
Definition: virtual.c:3076
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2781
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:4457
NTSTATUS NTAPI NtFlushInstructionCache(_In_ HANDLE ProcessHandle, _In_opt_ PVOID BaseAddress, _In_ SIZE_T FlushSize)
Definition: virtual.c:3009
NTSTATUS NTAPI NtIsProcessInJob(IN HANDLE ProcessHandle, IN HANDLE JobHandle OPTIONAL)
Definition: job.c:361
NTSTATUS NTAPI NtAssignProcessToJobObject(HANDLE JobHandle, HANDLE ProcessHandle)
Definition: job.c:157
NTSTATUS NTAPI NtCreateProcessEx(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ParentProcess, IN ULONG Flags, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL, IN BOOLEAN InJob)
Definition: process.c:1344
NTSTATUS NTAPI NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId)
Definition: process.c:1440
NTSTATUS NTAPI NtSetInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)
Definition: query.c:1389
NTSTATUS NTAPI NtSetInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength)
Definition: query.c:2268
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:211
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_IMAGE_WIN_64
Definition: ntstatus.h:1029
#define STATUS_INVALID_IMAGE_WIN_16
Definition: ntstatus.h:635
#define STATUS_INVALID_IMAGE_NE_FORMAT
Definition: ntstatus.h:613
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE
Definition: ntstatus.h:224
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:453
#define STATUS_FATAL_APP_EXIT
Definition: ntstatus.h:210
#define STATUS_INVALID_IMAGE_NOT_MZ
Definition: ntstatus.h:633
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:634
#define STATUS_VDM_DISALLOWED
Definition: ntstatus.h:1089
#define STATUS_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:643
#define STATUS_FILE_IS_OFFLINE
Definition: ntstatus.h:862
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:592
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3410
#define STARTF_USEHOTKEY
Definition: pch.h:41
#define IMAGE_FILE_MACHINE_I386
Definition: pedump.c:174
DWORD * PDWORD
Definition: pedump.c:68
#define IMAGE_FILE_DLL
Definition: pedump.c:169
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
struct _STARTUPINFOA STARTUPINFOA
struct _STARTUPINFOW STARTUPINFOW
_In_ DWORD dwProcessId
Definition: shlwapi.h:193
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_FINALLY
Definition: pseh2_64.h:130
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:180
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:184
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
#define REG_DWORD
Definition: sdbapi.c:615
_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)
VOID NTAPI CsrFreeCaptureBuffer(_In_ _Frees_ptr_ PCSR_CAPTURE_BUFFER CaptureBuffer)
Definition: capture.c:210
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 IsConsoleHandle(h)
Definition: console.h:14
#define BINARY_TYPE_WOW
Definition: vdm.h:40
#define VDM_UNDO_PARTIAL
Definition: vdm.h:27
#define VDM_UNDO_COMPLETED
Definition: vdm.h:30
#define BINARY_TYPE_WOW_EX
Definition: vdm.h:41
#define VDM_NOT_READY
Definition: vdm.h:47
#define BINARY_TYPE_SEPARATE_WOW
Definition: vdm.h:39
#define VDM_UNDO_REUSE
Definition: vdm.h:29
@ VdmEntryUndo
Definition: vdm.h:19
@ VdmEntryUpdateProcess
Definition: vdm.h:20
#define VDM_UNDO_FULL
Definition: vdm.h:28
#define BINARY_TYPE_DOS
Definition: vdm.h:38
#define VDM_READY
Definition: vdm.h:48
#define VDM_NOT_LOADED
Definition: vdm.h:46
#define BINARY_TYPE_EXE
Definition: vdm.h:35
#define SharedUserData
NTSTATUS NTAPI NtQuerySection(_In_ HANDLE SectionHandle, _In_ SECTION_INFORMATION_CLASS SectionInformationClass, _Out_ PVOID SectionInformation, _In_ SIZE_T SectionInformationLength, _Out_opt_ PSIZE_T ResultLength)
Definition: section.c:3808
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
base of all file and directory entries
Definition: entries.h:83
Definition: ncftp.h:89
USHORT MaximumLength
Definition: env_spec_w32.h:377
Definition: kernel32.h:386
NTSTATUS Status
Definition: basemsg.h:279
BASE_CREATE_PROCESS CreateProcessRequest
Definition: basemsg.h:283
BASE_EXIT_PROCESS ExitProcessRequest
Definition: basemsg.h:286
BASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest
Definition: basemsg.h:294
BASE_CHECK_VDM CheckVDMRequest
Definition: basemsg.h:287
union _BASE_API_MESSAGE::@3736 Data
USHORT VDMState
Definition: basemsg.h:147
HANDLE WaitObjectForParent
Definition: basemsg.h:123
BASE_SXS_CREATEPROCESS_MSG Sxs
Definition: basemsg.h:96
USHORT ProcessorArchitecture
Definition: basemsg.h:99
ULONG PebAddressWow64
Definition: basemsg.h:98
HANDLE ProcessHandle
Definition: basemsg.h:89
CLIENT_ID ClientId
Definition: basemsg.h:91
HANDLE ThreadHandle
Definition: basemsg.h:90
PVOID PebAddressNative
Definition: basemsg.h:97
BOOLEAN IsWowTaskReady
Definition: base.h:135
BOOLEAN DefaultSeparateVDM
Definition: base.h:134
SYSTEM_BASIC_INFORMATION SysInfo
Definition: base.h:130
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
HANDLE Handle
Definition: rtltypes.h:1363
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
PVOID StackBase
Definition: pstypes.h:733
LARGE_INTEGER UserTime
Definition: winternl.h:2377
LARGE_INTEGER CreateTime
Definition: winternl.h:2374
LARGE_INTEGER KernelTime
Definition: winternl.h:2376
LARGE_INTEGER ExitTime
Definition: winternl.h:2375
Definition: btrfs_drv.h:1876
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PVOID ArbitraryUserPointer
Definition: compat.h:719
BOOLEAN ReadImageFileExecOptions
Definition: ntddk_ex.h:240
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1913
ULONG ImageSubsystemMajorVersion
Definition: ntddk_ex.h:305
SIZE_T MaximumWorkingSetSize
Definition: pstypes.h:71
SIZE_T MinimumWorkingSetSize
Definition: pstypes.h:70
SIZE_T StaticSize
Definition: rtltypes.h:1897
PUCHAR StaticBuffer
Definition: rtltypes.h:1895
PUCHAR Buffer
Definition: rtltypes.h:1894
SIZE_T Size
Definition: rtltypes.h:1896
UNICODE_STRING RelativeName
Definition: rtltypes.h:1374
HANDLE ContainingDirectory
Definition: rtltypes.h:1375
UNICODE_STRING String
Definition: rtltypes.h:1904
UNICODE_STRING DesktopInfo
Definition: rtltypes.h:1574
LPVOID lpSecurityDescriptor
Definition: compat.h:193
PUNICODE_STRING Win32
Definition: kernel32.h:402
PUNICODE_STRING Nt
Definition: kernel32.h:403
KAFFINITY ActiveProcessorsAffinityMask
Definition: ntddk_ex.h:167
Definition: compat.h:836
NT_TIB NtTib
Definition: ntddk_ex.h:332
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define max(a, b)
Definition: svc.c:63
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
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 MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define MAKELONG(a, b)
Definition: typedefs.h:249
#define RtlMoveMemory(Destination, Source, Length)
Definition: typedefs.h:264
uint16_t * PWCHAR
Definition: typedefs.h:56
HANDLE HMODULE
Definition: typedefs.h:77
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
char * PCHAR
Definition: typedefs.h:51
#define STATUS_ACCESS_DENIED
Definition: udferr_usr.h:145
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_OBJECT_NAME_NOT_FOUND
Definition: udferr_usr.h:149
struct _LARGE_INTEGER::@2479 u
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static int Shell(const char **args)
Definition: vfdcmd.c:1020
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK _In_opt_ PWDF_OBJECT_ATTRIBUTES KeyAttributes
Definition: wdfdevice.h:2666
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
_In_ WDFREQUEST _In_ NTSTATUS _In_ CCHAR PriorityBoost
Definition: wdfrequest.h:1016
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define NORMAL_PRIORITY_CLASS
Definition: winbase.h:185
#define STARTF_FORCEOFFFEEDBACK
Definition: winbase.h:475
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CREATE_FORCEDOS
Definition: winbase.h:193
#define PROFILE_SERVER
Definition: winbase.h:219
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1148
#define REALTIME_PRIORITY_CLASS
Definition: winbase.h:188
#define BELOW_NORMAL_PRIORITY_CLASS
Definition: winbase.h:194
#define CREATE_UNICODE_ENVIRONMENT
Definition: winbase.h:190
#define HIGH_PRIORITY_CLASS
Definition: winbase.h:187
DWORD WINAPI GetCurrentProcessId(void)
Definition: proc.c:1158
#define CREATE_NO_WINDOW
Definition: winbase.h:216
#define CREATE_SHARED_WOW_VDM
Definition: winbase.h:192
#define GetModuleHandle
Definition: winbase.h:3576
#define CREATE_DEFAULT_ERROR_MODE
Definition: winbase.h:215
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:191
#define CREATE_NEW_PROCESS_GROUP
Definition: winbase.h:189
#define PROFILE_KERNEL
Definition: winbase.h:218
#define CREATE_SUSPENDED
Definition: winbase.h:182
#define DEBUG_ONLY_THIS_PROCESS
Definition: winbase.h:181
#define SearchPath
Definition: winbase.h:3649
#define PROFILE_USER
Definition: winbase.h:217
#define STARTF_USESTDHANDLES
Definition: winbase.h:476
#define CREATE_PRESERVE_CODE_AUTHZ_LEVEL
Definition: winbase.h:214
#define IDLE_PRIORITY_CLASS
Definition: winbase.h:186
#define DETACHED_PROCESS
Definition: winbase.h:183
#define STARTF_FORCEONFEEDBACK
Definition: winbase.h:474
#define CREATE_NEW_CONSOLE
Definition: winbase.h:184
#define DEBUG_PROCESS
Definition: winbase.h:180
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:1834
#define ABOVE_NORMAL_PRIORITY_CLASS
Definition: winbase.h:195
_Inout_ PERBANDINFO * pbi
Definition: winddi.h:3917
#define WINAPI
Definition: msvc.h:6
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define ERROR_DIRECTORY
Definition: winerror.h:416
#define ERROR_NOT_READY
Definition: winerror.h:246
#define ERROR_BAD_EXE_FORMAT
Definition: winerror.h:373
#define ERROR_CHILD_NOT_COMPLETE
Definition: winerror.h:323
#define ERROR_ACCESS_DISABLED_BY_POLICY
Definition: winerror.h:1092
#define ERROR_CANCELLED
Definition: winerror.h:1055
#define ERROR_EXE_MACHINE_TYPE_MISMATCH
Definition: winerror.h:393
#define ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER
Definition: winerror.h:1105
#define ERROR_ACCESS_DISABLED_WEBBLADE
Definition: winerror.h:1104
#define ERROR_BAD_FORMAT
Definition: winerror.h:236
#define ERROR_FILE_OFFLINE
Definition: winerror.h:1714
#define ERROR_BAD_DEVICE
Definition: winerror.h:1032
_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
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
#define DUPLICATE_SAME_ACCESS
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182
char CHAR
Definition: xmlstorage.h:175