ReactOS 0.4.17-dev-243-g1369312
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
31{
32 {
34 1,
35 L"AppCertDlls",
37 0,
38 NULL,
39 0
40 }
41};
42
45
47RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle);
48
49#define CMD_STRING L"cmd /c "
50
51/* FUNCTIONS ****************************************************************/
52
53VOID
56 IN HANDLE StandardHandle,
58{
60 HANDLE DuplicatedHandle;
61 SIZE_T NumberOfBytesWritten;
62
63 /* If there is no handle to duplicate, return immediately */
64 if (!StandardHandle) return;
65
66 /* Duplicate the handle */
68 StandardHandle,
70 &DuplicatedHandle,
71 0,
72 0,
75 if (!NT_SUCCESS(Status)) return;
76
77 /* Write it */
79 Address,
80 &DuplicatedHandle,
81 sizeof(HANDLE),
82 &NumberOfBytesWritten);
83}
84
89 IN LPCWSTR CommandLine,
90 OUT PUNICODE_STRING SubsysCommandLine)
91{
92 UNICODE_STRING CommandLineString, ApplicationNameString;
95
96 /* Convert to unicode strings */
97 RtlInitUnicodeString(&CommandLineString, ApplicationName);
98 RtlInitUnicodeString(&ApplicationNameString, CommandLine);
99
100 /* Allocate buffer for the output string */
101 Length = CommandLineString.MaximumLength + ApplicationNameString.MaximumLength + 32;
102 Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, Length);
103 RtlInitEmptyUnicodeString(SubsysCommandLine, Buffer, (USHORT)Length);
104 if (!Buffer)
105 {
106 /* Fail, no memory */
108 return FALSE;
109 }
110
111 /* Build the final subsystem command line */
112 RtlAppendUnicodeToString(SubsysCommandLine, SubsystemName);
113 RtlAppendUnicodeStringToString(SubsysCommandLine, &CommandLineString);
114 RtlAppendUnicodeToString(SubsysCommandLine, L" /C ");
115 RtlAppendUnicodeStringToString(SubsysCommandLine, &ApplicationNameString);
116 return TRUE;
117}
118
120WINAPI
122 IN ULONG ImageMinorVersion)
123{
124 /* Accept images for NT 3.1 or higher */
125 if (ImageMajorVersion > 3 ||
126 (ImageMajorVersion == 3 && ImageMinorVersion >= 10))
127 {
128 /* ReactOS-specific: Accept images even if they are newer than our internal NT version. */
129 if (ImageMajorVersion > SharedUserData->NtMajorVersion ||
130 (ImageMajorVersion == SharedUserData->NtMajorVersion && ImageMinorVersion > SharedUserData->NtMinorVersion))
131 {
132 DPRINT1("Accepting image version %lu.%lu, although ReactOS is an NT %hu.%hu OS!\n",
133 ImageMajorVersion,
134 ImageMinorVersion,
135 SharedUserData->NtMajorVersion,
136 SharedUserData->NtMinorVersion);
137 }
138
139 return TRUE;
140 }
141
142 return FALSE;
143}
144
146WINAPI
148{
150 CHAR Hash[16];
151
152 /* Get all the MD5 hashes */
154 if (!NT_SUCCESS(Status)) return Status;
155
156 /* Depending on which suite this is, run a bsearch and block the appropriate ones */
158 {
159 DPRINT1("Egad! This is a ReactOS Compute Server and we should prevent you from using certain APIs...but we won't.");
160 }
161 else if (SharedUserData->SuiteMask & VER_SUITE_STORAGE_SERVER)
162 {
163 DPRINT1("Gasp! This is a ReactOS Storage Server and we should prevent you from using certain APIs...but we won't.");
164 }
165 else if (SharedUserData->SuiteMask & VER_SUITE_BLADE)
166 {
167 DPRINT1("Golly! This is a ReactOS Web Blade Server and we should prevent you from using certain APIs...but we won't.");
168 }
169
170 /* Actually, fuck it, don't block anything, we're open source */
171 return STATUS_SUCCESS;
172}
173
175NTAPI
177 IN PWCHAR ComponentName,
178 IN PWCHAR DllName)
179{
180 /* Pretty much the only thing this key is used for, is malware */
183}
184
186NTAPI
193{
194 /* Add this to the certification list */
196}
197
199WINAPI
201{
202 NTSTATUS Status, Status1;
204 UINT Length;
205 HMODULE TrustLibrary;
207 ULONG CertFlag;
208 PLIST_ENTRY NextEntry;
210 UNICODE_STRING CertKey = RTL_CONSTANT_STRING(L"\\Registry\\MACHINE\\System\\CurrentControlSet\\Control\\Session Manager\\AppCertDlls");
212
213 /* Try to initialize the certification subsystem */
214 while (!g_AppCertInitialized)
215 {
216 /* Defaults */
218 Buffer = NULL;
219
220 /* Acquire the lock while initializing and see if we lost a race */
222 if (g_AppCertInitialized) break;
223
224 /* On embedded, there is a special DLL */
225 if (SharedUserData->SuiteMask & VER_SUITE_EMBEDDEDNT)
226 {
227 /* Allocate a buffer for the name */
228 Buffer = RtlAllocateHeap(RtlGetProcessHeap(),
229 0,
230 MAX_PATH * sizeof(WCHAR) +
231 sizeof(UNICODE_NULL));
232 if (!Buffer)
233 {
234 /* Fail if no memory */
236 }
237 else
238 {
239 /* Now get the system32 directory in our buffer, make sure it fits */
240 Length = GetSystemDirectoryW(Buffer, MAX_PATH - sizeof("EmbdTrst.DLL"));
241 if ((Length) && (Length <= MAX_PATH - sizeof("EmbdTrst.DLL")))
242 {
243 /* Add a slash if needed, and add the embedded cert DLL name */
244 if (Buffer[Length - 1] != '\\') Buffer[Length++] = '\\';
246 L"EmbdTrst.DLL",
247 sizeof(L"EmbdTrst.DLL"));
248
249 /* Try to load it */
250 TrustLibrary = LoadLibraryW(Buffer);
251 if (TrustLibrary)
252 {
253 /* And extract the special function out of it */
254 fEmbeddedCertFunc = (PVOID)GetProcAddress(TrustLibrary,
255 "ImageOkToRunOnEmbeddedNT");
256 }
257 }
258
259 /* If we didn't get this far, set a failure code */
261 }
262 }
263 else
264 {
265 /* Other systems have a registry entry for this */
267 if (NT_SUCCESS(Status1))
268 {
269 /* Close it, we'll query it through Rtl */
271
272 /* Do the query, which will call a special callback */
274 L"Session Manager",
276 NULL,
277 NULL);
279 {
281 }
282 }
283 }
284
285 /* Free any buffer if we had one */
286 if (Buffer) RtlFreeHeap(RtlGetProcessHeap(), 0, Buffer);
287
288 /* Check for errors, or a missing embedded/custom certification DLL */
289 if (!NT_SUCCESS(Status) ||
291 {
292 /* The subsystem is not active on this machine, so give up */
295 }
296 else
297 {
298 /* We have certification DLLs active, remember this */
300 }
301
302 /* We are done the initialization phase, release the lock */
305 }
306
307 /* If there's no certification DLLs present, return the failure code */
308 if (!g_HaveAppCerts) return g_AppCertStatus;
309
310 /* Otherwise, assume success and make sure we have *something* */
313
314 /* If the something is an embedded certification DLL, call it and return */
316
317 /* Otherwise we have custom certification DLLs, parse them */
318 NextEntry = BasepAppCertDllsList.Flink;
319 CertFlag = 2;
320 while (NextEntry != &BasepAppCertDllsList)
321 {
322 /* Make sure the entry has a callback */
324 ASSERT(Entry->fPluginCertFunc != NULL);
325
326 /* Call it and check if it failed */
327 Status = Entry->fPluginCertFunc(ApplicationName, 1);
328 if (!NT_SUCCESS(Status)) CertFlag = 3;
329
330 /* Move on */
331 NextEntry = NextEntry->Flink;
332 }
333
334 /* Now loop them again */
335 NextEntry = BasepAppCertDllsList.Flink;
336 while (NextEntry != &BasepAppCertDllsList)
337 {
338 /* Make sure the entry has a callback */
340 ASSERT(Entry->fPluginCertFunc != NULL);
341
342 /* Call it, this time with the flag from the loop above */
343 Status = Entry->fPluginCertFunc(ApplicationName, CertFlag);
344 }
345
346 /* All done, return the status */
347 return Status;
348}
349
351WINAPI
354 IN HANDLE ThreadHandle)
355{
357 ANSI_STRING SaferiReplaceProcessThreadTokens = RTL_CONSTANT_STRING("SaferiReplaceProcessThreadTokens");
358
359 /* Enter the application certification lock */
361
362 /* Check if we already know the function */
364 {
365 /* Call it */
368 ThreadHandle) ?
371 }
372 else
373 {
374 /* Check if the app certification DLL isn't loaded */
375 if (!(gSaferHandle) ||
376 (gSaferHandle == (HMODULE)-1) ||
377 (gSaferHandle == (HMODULE)-2))
378 {
379 /* Then we can't call the function */
381 }
382 else
383 {
384 /* We have the DLL, find the address of the Safer function */
386 &SaferiReplaceProcessThreadTokens,
387 0,
389 if (NT_SUCCESS(Status))
390 {
391 /* Found it, now call it */
394 ThreadHandle) ?
397 }
398 else
399 {
400 /* We couldn't find it, so this must be an unsupported DLL */
404 }
405 }
406 }
407
408 /* Release the lock and return the result */
410 return Status;
411}
412
413VOID
414WINAPI
416{
418
419 /* Sanity checks */
420 ASSERT(Handles != NULL);
421 ASSERT(Handles->Process == NULL || Handles->Process == NtCurrentProcess());
422
423 /* Close the file handle */
424 if (Handles->File)
425 {
426 Status = NtClose(Handles->File);
428 }
429
430 /* Close the section handle */
431 if (Handles->Section)
432 {
433 Status = NtClose(Handles->Section);
435 }
436
437 /* Unmap the section view */
438 if (Handles->ViewBase.QuadPart)
439 {
441 (PVOID)(ULONG_PTR)Handles->ViewBase.QuadPart);
443 }
444}
445
447VOID
448WINAPI
450 _In_ PPROCESS_START_ROUTINE lpStartAddress)
451{
453 {
454 /* Set our Start Address */
457 &lpStartAddress,
458 sizeof(PPROCESS_START_ROUTINE));
459
460 /* Call the Start Routine */
461 ExitThread(lpStartAddress());
462 }
464 {
465 /* Get the Exit code from the SEH Handler */
467 {
468 /* Kill the whole process, usually */
470 }
471 else
472 {
473 /* If running inside CSRSS, kill just this thread */
475 }
476 }
477 _SEH2_END;
478}
479
481WINAPI
484 IN PPEB RemotePeb,
485 IN LPCWSTR ApplicationPathName,
486 IN LPWSTR lpCurrentDirectory,
487 IN LPWSTR lpCommandLine,
488 IN LPVOID lpEnvironment,
489 IN LPSTARTUPINFOW StartupInfo,
490 IN DWORD CreationFlags,
491 IN BOOL InheritHandles,
492 IN ULONG ImageSubsystem,
493 IN PVOID AppCompatData,
494 IN ULONG AppCompatDataSize)
495{
496 WCHAR FullPath[MAX_PATH + 5];
497 PWCHAR Remaining, DllPathString, ScanChar;
498 PRTL_USER_PROCESS_PARAMETERS ProcessParameters, RemoteParameters;
499 PVOID RemoteAppCompatData;
503 ULONG EnviroSize;
504 SIZE_T Size;
505 BOOLEAN HavePebLock = FALSE, Result;
507
508 /* Get the full path name */
509 Size = GetFullPathNameW(ApplicationPathName,
510 MAX_PATH + 4,
511 FullPath,
512 &Remaining);
513 if ((Size) && (Size <= (MAX_PATH + 4)))
514 {
515 /* Get the DLL Path */
516 DllPathString = BaseComputeProcessDllPath(FullPath, lpEnvironment);
517 if (!DllPathString)
518 {
519 /* Fail */
521 return FALSE;
522 }
523
524 /* Initialize Strings */
525 RtlInitUnicodeString(&DllPath, DllPathString);
527 }
528 else
529 {
530 /* Couldn't get the path name. Just take the original path */
531 DllPathString = BaseComputeProcessDllPath((LPWSTR)ApplicationPathName,
532 lpEnvironment);
533 if (!DllPathString)
534 {
535 /* Fail */
537 return FALSE;
538 }
539
540 /* Initialize Strings */
541 RtlInitUnicodeString(&DllPath, DllPathString);
542 RtlInitUnicodeString(&ImageName, ApplicationPathName);
543 }
544
545 /* Initialize Strings */
546 RtlInitUnicodeString(&CommandLine, lpCommandLine);
547 RtlInitUnicodeString(&CurrentDirectory, lpCurrentDirectory);
548
549 /* Initialize more Strings from the Startup Info */
550 if (StartupInfo->lpDesktop)
551 {
552 RtlInitUnicodeString(&Desktop, StartupInfo->lpDesktop);
553 }
554 else
555 {
557 }
558 if (StartupInfo->lpReserved)
559 {
560 RtlInitUnicodeString(&Shell, StartupInfo->lpReserved);
561 }
562 else
563 {
565 }
566 if (StartupInfo->lpTitle)
567 {
568 RtlInitUnicodeString(&Title, StartupInfo->lpTitle);
569 }
570 else
571 {
572 RtlInitUnicodeString(&Title, ApplicationPathName);
573 }
574
575 /* This one is special because the length can differ */
576 Runtime.Buffer = (LPWSTR)StartupInfo->lpReserved2;
577 Runtime.MaximumLength = Runtime.Length = StartupInfo->cbReserved2;
578
579 /* Enforce no app compat data if the pointer was NULL */
580 if (!AppCompatData) AppCompatDataSize = 0;
581
582 /* Create the Parameter Block */
583 ProcessParameters = NULL;
584 DPRINT("ImageName: '%wZ'\n", &ImageName);
585 DPRINT("DllPath : '%wZ'\n", &DllPath);
586 DPRINT("CurDir : '%wZ'\n", &CurrentDirectory);
587 DPRINT("CmdLine : '%wZ'\n", &CommandLine);
588 DPRINT("Title : '%wZ'\n", &Title);
589 DPRINT("Desktop : '%wZ'\n", &Desktop);
590 DPRINT("Shell : '%wZ'\n", &Shell);
591 DPRINT("Runtime : '%wZ'\n", &Runtime);
592 Status = RtlCreateProcessParameters(&ProcessParameters,
593 &ImageName,
594 &DllPath,
595 lpCurrentDirectory ?
597 &CommandLine,
598 lpEnvironment,
599 &Title,
600 &Desktop,
601 &Shell,
602 &Runtime);
603 if (!NT_SUCCESS(Status)) goto FailPath;
604
605 /* Clear the current directory handle if not inheriting */
606 if (!InheritHandles) ProcessParameters->CurrentDirectory.Handle = NULL;
607
608 /* Check if the user passed in an environment */
609 if (lpEnvironment)
610 {
611 /* We should've made it part of the parameters block, enforce this */
612 lpEnvironment = ProcessParameters->Environment;
613 }
614 else
615 {
616 /* The user did not, so use the one from the current PEB */
617 HavePebLock = TRUE;
619 lpEnvironment = Peb->ProcessParameters->Environment;
620 }
621
622 /* Save pointer and start lookup */
623 ScanChar = lpEnvironment;
624 if (lpEnvironment)
625 {
626 /* Find the environment size */
627 while (*ScanChar++) while (*ScanChar++);
628 EnviroSize = (ULONG)((ULONG_PTR)ScanChar - (ULONG_PTR)lpEnvironment);
629
630 /* Allocate and Initialize new Environment Block */
631 Size = EnviroSize;
632 ProcessParameters->Environment = NULL;
634 (PVOID*)&ProcessParameters->Environment,
635 0,
636 &Size,
639 if (!NT_SUCCESS(Status)) goto FailPath;
640
641 /* Write the Environment Block */
643 ProcessParameters->Environment,
644 lpEnvironment,
645 EnviroSize,
646 NULL);
647
648 /* No longer need the PEB lock anymore */
649 if (HavePebLock)
650 {
651 /* Release it */
653 HavePebLock = FALSE;
654 }
655
656 /* Check if the write failed */
657 if (!NT_SUCCESS(Status)) goto FailPath;
658 }
659
660 /* Write new parameters */
661 ProcessParameters->StartingX = StartupInfo->dwX;
662 ProcessParameters->StartingY = StartupInfo->dwY;
663 ProcessParameters->CountX = StartupInfo->dwXSize;
664 ProcessParameters->CountY = StartupInfo->dwYSize;
665 ProcessParameters->CountCharsX = StartupInfo->dwXCountChars;
666 ProcessParameters->CountCharsY = StartupInfo->dwYCountChars;
667 ProcessParameters->FillAttribute = StartupInfo->dwFillAttribute;
668 ProcessParameters->WindowFlags = StartupInfo->dwFlags;
669 ProcessParameters->ShowWindowFlags = StartupInfo->wShowWindow;
670
671 /* Write the handles only if we have to */
672 if (StartupInfo->dwFlags &
673 (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))
674 {
675 ProcessParameters->StandardInput = StartupInfo->hStdInput;
676 ProcessParameters->StandardOutput = StartupInfo->hStdOutput;
677 ProcessParameters->StandardError = StartupInfo->hStdError;
678 }
679
680 /* Use Special Flags for ConDllInitialize in Kernel32 */
681 if (CreationFlags & DETACHED_PROCESS)
682 {
683 ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
684 }
685 else if (CreationFlags & CREATE_NEW_CONSOLE)
686 {
687 ProcessParameters->ConsoleHandle = HANDLE_CREATE_NEW_CONSOLE;
688 }
689 else if (CreationFlags & CREATE_NO_WINDOW)
690 {
691 ProcessParameters->ConsoleHandle = HANDLE_CREATE_NO_WINDOW;
692 }
693 else
694 {
695 /* Inherit our Console Handle */
696 ProcessParameters->ConsoleHandle = Peb->ProcessParameters->ConsoleHandle;
697
698 /* Make sure that the shell isn't trampling on our handles first */
699 if (!(StartupInfo->dwFlags &
700 (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
701 {
702 /* Copy the handle if we are inheriting or if it's a console handle */
703 if ((InheritHandles) ||
705 {
706 ProcessParameters->StandardInput = Peb->ProcessParameters->StandardInput;
707 }
708 if ((InheritHandles) ||
710 {
711 ProcessParameters->StandardOutput = Peb->ProcessParameters->StandardOutput;
712 }
713 if ((InheritHandles) ||
715 {
716 ProcessParameters->StandardError = Peb->ProcessParameters->StandardError;
717 }
718 }
719 }
720
721 /* Also set the Console Flag */
722 if ((CreationFlags & CREATE_NEW_PROCESS_GROUP) &&
723 (!(CreationFlags & CREATE_NEW_CONSOLE)))
724 {
725 ProcessParameters->ConsoleFlags = 1;
726 }
727
728 /* Check if there's a .local file present */
729 if (ParameterFlags & 1)
730 {
732 }
733
734 /* Check if we failed to open the IFEO key */
735 if (ParameterFlags & 2)
736 {
738 }
739
740 /* Allocate memory for the parameter block */
741 Size = ProcessParameters->Length;
742 RemoteParameters = NULL;
744 (PVOID*)&RemoteParameters,
745 0,
746 &Size,
749 if (!NT_SUCCESS(Status)) goto FailPath;
750
751 /* Set the allocated size */
752 ProcessParameters->MaximumLength = Size;
753
754 /* Handle some Parameter Flags */
755 ProcessParameters->Flags |= (CreationFlags & PROFILE_USER) ?
757 ProcessParameters->Flags |= (CreationFlags & PROFILE_KERNEL) ?
759 ProcessParameters->Flags |= (CreationFlags & PROFILE_SERVER) ?
761 ProcessParameters->Flags |= (Peb->ProcessParameters->Flags &
763
764 /* Write the Parameter Block */
766 RemoteParameters,
767 ProcessParameters,
768 ProcessParameters->Length,
769 NULL);
770 if (!NT_SUCCESS(Status)) goto FailPath;
771
772 /* Write the PEB Pointer */
774 &RemotePeb->ProcessParameters,
775 &RemoteParameters,
776 sizeof(PVOID),
777 NULL);
778 if (!NT_SUCCESS(Status)) goto FailPath;
779
780 /* Check if there's any app compat data to write */
781 RemoteAppCompatData = NULL;
782 if (AppCompatData)
783 {
784 /* Allocate some space for the application compatibility data */
785 Size = AppCompatDataSize;
787 &RemoteAppCompatData,
788 0,
789 &Size,
792 if (!NT_SUCCESS(Status)) goto FailPath;
793
794 /* Write the application compatibility data */
796 RemoteAppCompatData,
797 AppCompatData,
798 AppCompatDataSize,
799 NULL);
800 if (!NT_SUCCESS(Status)) goto FailPath;
801 }
802
803 /* Write the PEB Pointer to the app compat data (might be NULL) */
805 &RemotePeb->pShimData,
806 &RemoteAppCompatData,
807 sizeof(PVOID),
808 NULL);
809 if (!NT_SUCCESS(Status)) goto FailPath;
810
811 /* Now write Peb->ImageSubSystem */
812 if (ImageSubsystem)
813 {
815 &RemotePeb->ImageSubsystem,
816 &ImageSubsystem,
817 sizeof(ImageSubsystem),
818 NULL);
819 }
820
821 /* Success path */
822 Result = TRUE;
823
824Quickie:
825 /* Cleanup */
826 if (HavePebLock) RtlReleasePebLock();
827 RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath.Buffer);
828 if (ProcessParameters) RtlDestroyProcessParameters(ProcessParameters);
829 return Result;
830FailPath:
831 DPRINT1("Failure to create process parameters: %lx\n", Status);
833 Result = FALSE;
834 goto Quickie;
835}
836
837VOID
838WINAPI
840{
842
843 /* Read the UNICODE_STRING from the PEB */
844 BaseUnicodeCommandLine = NtCurrentPeb()->ProcessParameters->CommandLine;
845
846 /* Convert to ANSI_STRING for the *A callers */
849 TRUE);
850 if (!NT_SUCCESS(Status)) RtlInitEmptyAnsiString(&BaseAnsiCommandLine, 0, 0);
851}
852
853/* PUBLIC FUNCTIONS ***********************************************************/
854
855/*
856 * @implemented
857 */
858BOOL
859WINAPI
861 OUT PDWORD_PTR lpProcessAffinityMask,
862 OUT PDWORD_PTR lpSystemAffinityMask)
863{
864 PROCESS_BASIC_INFORMATION ProcessInfo;
866
867 /* Query information on the process from the kernel */
870 &ProcessInfo,
871 sizeof(ProcessInfo),
872 NULL);
873 if (!NT_SUCCESS(Status))
874 {
875 /* Fail */
877 return FALSE;
878 }
879
880 /* Copy the affinity mask, and get the system one from our shared data */
881 *lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask;
883 return TRUE;
884}
885
886/*
887 * @implemented
888 */
889BOOL
890WINAPI
892 IN DWORD_PTR dwProcessAffinityMask)
893{
895
896 /* Directly set the affinity mask */
899 (PVOID)&dwProcessAffinityMask,
900 sizeof(dwProcessAffinityMask));
901 if (!NT_SUCCESS(Status))
902 {
903 /* Handle failure */
905 return FALSE;
906 }
907
908 /* Everything was ok */
909 return TRUE;
910}
911
912/*
913 * @implemented
914 */
915BOOL
916WINAPI
918 OUT LPDWORD lpdwFlags)
919{
920 BASE_API_MESSAGE ApiMessage;
921 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &ApiMessage.Data.ShutdownParametersRequest;
922
923 /* Ask CSRSS for shutdown information */
925 NULL,
927 sizeof(*ShutdownParametersRequest));
928 if (!NT_SUCCESS(ApiMessage.Status))
929 {
930 /* Return the failure from CSRSS */
931 BaseSetLastNTError(ApiMessage.Status);
932 return FALSE;
933 }
934
935 /* Get the data back */
936 *lpdwLevel = ShutdownParametersRequest->ShutdownLevel;
937 *lpdwFlags = ShutdownParametersRequest->ShutdownFlags;
938 return TRUE;
939}
940
941/*
942 * @implemented
943 */
944BOOL
945WINAPI
948{
949 BASE_API_MESSAGE ApiMessage;
950 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &ApiMessage.Data.ShutdownParametersRequest;
951
952 /* Write the data into the CSRSS request and send it */
953 ShutdownParametersRequest->ShutdownLevel = dwLevel;
954 ShutdownParametersRequest->ShutdownFlags = dwFlags;
956 NULL,
958 sizeof(*ShutdownParametersRequest));
959 if (!NT_SUCCESS(ApiMessage.Status))
960 {
961 /* Return the failure from CSRSS */
962 BaseSetLastNTError(ApiMessage.Status);
963 return FALSE;
964 }
965
966 /* All went well */
967 return TRUE;
968}
969
970/*
971 * @implemented
972 */
973BOOL
974WINAPI
976 OUT PSIZE_T lpMinimumWorkingSetSize,
977 OUT PSIZE_T lpMaximumWorkingSetSize,
979{
980 QUOTA_LIMITS_EX QuotaLimits;
982
983 /* Query the kernel about this */
986 &QuotaLimits,
987 sizeof(QuotaLimits),
988 NULL);
989 if (!NT_SUCCESS(Status))
990 {
991 /* Return error */
993 return FALSE;
994 }
995
996 /* Copy the quota information out */
997 *lpMinimumWorkingSetSize = QuotaLimits.MinimumWorkingSetSize;
998 *lpMaximumWorkingSetSize = QuotaLimits.MaximumWorkingSetSize;
999 *Flags = QuotaLimits.Flags;
1000 return TRUE;
1001}
1002
1003/*
1004 * @implemented
1005 */
1006BOOL
1007WINAPI
1009 OUT PSIZE_T lpMinimumWorkingSetSize,
1010 OUT PSIZE_T lpMaximumWorkingSetSize)
1011{
1012 DWORD Dummy;
1014 lpMinimumWorkingSetSize,
1015 lpMaximumWorkingSetSize,
1016 &Dummy);
1017}
1018
1019/*
1020 * @implemented
1021 */
1022BOOL
1023WINAPI
1025 IN SIZE_T dwMinimumWorkingSetSize,
1026 IN SIZE_T dwMaximumWorkingSetSize,
1027 IN DWORD Flags)
1028{
1029 QUOTA_LIMITS_EX QuotaLimits;
1030 NTSTATUS Status, ReturnStatus;
1031 BOOL Result;
1032 PVOID State;
1034
1035 /* Zero out the input structure */
1036 RtlZeroMemory(&QuotaLimits, sizeof(QuotaLimits));
1037
1038 /* Check if the caller sent any limits */
1039 if ((dwMinimumWorkingSetSize) && (dwMaximumWorkingSetSize))
1040 {
1041 /* Write the quota information */
1042 QuotaLimits.MinimumWorkingSetSize = dwMinimumWorkingSetSize;
1043 QuotaLimits.MaximumWorkingSetSize = dwMaximumWorkingSetSize;
1044 QuotaLimits.Flags = Flags;
1045
1046 /* Acquire the required privilege */
1048
1049 /* Request the new quotas */
1050 ReturnStatus = NtSetInformationProcess(hProcess,
1052 &QuotaLimits,
1053 sizeof(QuotaLimits));
1054 Result = NT_SUCCESS(ReturnStatus);
1055 if (NT_SUCCESS(Status))
1056 {
1057 /* Release the privilege and set succes code */
1058 ASSERT(State != NULL);
1060 State = NULL;
1061 }
1062 }
1063 else
1064 {
1065 /* No limits, fail the call */
1066 ReturnStatus = STATUS_INVALID_PARAMETER;
1067 Result = FALSE;
1068 }
1069
1070 /* Return result code, set error code if this was a failure */
1071 if (!Result) BaseSetLastNTError(ReturnStatus);
1072 return Result;
1073}
1074
1075/*
1076 * @implemented
1077 */
1078BOOL
1079WINAPI
1081 IN SIZE_T dwMinimumWorkingSetSize,
1082 IN SIZE_T dwMaximumWorkingSetSize)
1083{
1084 /* Call the newer API */
1086 dwMinimumWorkingSetSize,
1087 dwMaximumWorkingSetSize,
1088 0);
1089}
1090
1091/*
1092 * @implemented
1093 */
1094BOOL
1095WINAPI
1097 IN LPFILETIME lpCreationTime,
1098 IN LPFILETIME lpExitTime,
1099 IN LPFILETIME lpKernelTime,
1100 IN LPFILETIME lpUserTime)
1101{
1104
1105 /* Query the times */
1108 &Kut,
1109 sizeof(Kut),
1110 NULL);
1111 if (!NT_SUCCESS(Status))
1112 {
1113 /* Handle failure */
1115 return FALSE;
1116 }
1117
1118 /* Copy all the times and return success */
1119 lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
1120 lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
1121 lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
1122 lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
1123 lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
1124 lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
1125 lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
1126 lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
1127 return TRUE;
1128}
1129
1130/*
1131 * @implemented
1132 */
1133HANDLE
1134WINAPI
1136{
1137 return (HANDLE)NtCurrentProcess();
1138}
1139
1140/*
1141 * @implemented
1142 */
1143HANDLE
1144WINAPI
1146{
1147 return (HANDLE)NtCurrentThread();
1148}
1149
1150/*
1151 * @implemented
1152 */
1153DWORD
1154WINAPI
1156{
1158}
1159
1160/*
1161 * @implemented
1162 */
1163BOOL
1164WINAPI
1166 IN LPDWORD lpExitCode)
1167{
1168 PROCESS_BASIC_INFORMATION ProcessBasic;
1170
1171 /* Ask the kernel */
1174 &ProcessBasic,
1175 sizeof(ProcessBasic),
1176 NULL);
1177 if (!NT_SUCCESS(Status))
1178 {
1179 /* We failed, was this because this is a VDM process? */
1180 if (BaseCheckForVDM(hProcess, lpExitCode) != FALSE) return TRUE;
1181
1182 /* Not a VDM process, fail the call */
1184 return FALSE;
1185 }
1186
1187 /* Succes case, return the exit code */
1188 *lpExitCode = (DWORD)ProcessBasic.ExitStatus;
1189 return TRUE;
1190}
1191
1192/*
1193 * @implemented
1194 */
1195DWORD
1196WINAPI
1198{
1199 PROCESS_BASIC_INFORMATION ProcessBasic;
1201
1202 /* Query the kernel */
1205 &ProcessBasic,
1206 sizeof(ProcessBasic),
1207 NULL);
1208 if (!NT_SUCCESS(Status))
1209 {
1210 /* Handle failure */
1212 return 0;
1213 }
1214
1215 /* Return the PID */
1216 return (DWORD)ProcessBasic.UniqueProcessId;
1217}
1218
1219/*
1220 * @implemented
1221 */
1222HANDLE
1223WINAPI
1224OpenProcess(IN DWORD dwDesiredAccess,
1227{
1232
1233 /* Setup the input client ID structure */
1236
1237 /* This is needed just to define the inheritance flags */
1239 NULL,
1241 NULL,
1242 NULL);
1243
1244 /* Now try to open the process */
1246 dwDesiredAccess,
1248 &ClientId);
1249 if (!NT_SUCCESS(Status))
1250 {
1251 /* Handle failure */
1253 return NULL;
1254 }
1255
1256 /* Otherwise return a handle to the process */
1257 return ProcessHandle;
1258}
1259
1260/*
1261 * @implemented
1262 */
1263VOID
1264WINAPI
1266{
1268
1269 /* Get the process parameters */
1270 Params = NtCurrentPeb()->ProcessParameters;
1271
1272 /* Copy the data out of there */
1273 lpStartupInfo->cb = sizeof(STARTUPINFOW);
1274 lpStartupInfo->lpReserved = Params->ShellInfo.Buffer;
1275 lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
1276 lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
1277 lpStartupInfo->dwX = Params->StartingX;
1278 lpStartupInfo->dwY = Params->StartingY;
1279 lpStartupInfo->dwXSize = Params->CountX;
1280 lpStartupInfo->dwYSize = Params->CountY;
1281 lpStartupInfo->dwXCountChars = Params->CountCharsX;
1282 lpStartupInfo->dwYCountChars = Params->CountCharsY;
1283 lpStartupInfo->dwFillAttribute = Params->FillAttribute;
1284 lpStartupInfo->dwFlags = Params->WindowFlags;
1285 lpStartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
1286 lpStartupInfo->cbReserved2 = Params->RuntimeData.Length;
1287 lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
1288
1289 /* Check if the standard handles are being used for other features */
1290 if (lpStartupInfo->dwFlags & (STARTF_USESTDHANDLES |
1292 STARTF_SHELLPRIVATE))
1293 {
1294 /* These are, so copy the standard handles too */
1295 lpStartupInfo->hStdInput = Params->StandardInput;
1296 lpStartupInfo->hStdOutput = Params->StandardOutput;
1297 lpStartupInfo->hStdError = Params->StandardError;
1298 }
1299}
1300
1301/*
1302 * @implemented
1303 */
1304BOOL
1305WINAPI
1307 IN LPCVOID lpBaseAddress,
1308 IN SIZE_T nSize)
1309{
1311
1312 /* Call the native function */
1314 if (!NT_SUCCESS(Status))
1315 {
1316 /* Handle failure case */
1318 return FALSE;
1319 }
1320
1321 /* All good */
1322 return TRUE;
1323}
1324
1325/*
1326 * @implemented
1327 */
1328VOID
1329WINAPI
1331{
1332 BASE_API_MESSAGE ApiMessage;
1333 PBASE_EXIT_PROCESS ExitProcessRequest = &ApiMessage.Data.ExitProcessRequest;
1334
1336
1337 _SEH2_TRY
1338 {
1339 /* Acquire the PEB lock */
1341
1342 /* Kill all the threads */
1343 NtTerminateProcess(NULL, uExitCode);
1344
1345 /* Unload all DLLs */
1347
1348 /* Notify Base Server of process termination */
1349 ExitProcessRequest->uExitCode = uExitCode;
1351 NULL,
1353 sizeof(*ExitProcessRequest));
1354
1355 /* Now do it again */
1357 }
1359 {
1360 /* Release the PEB lock */
1362 }
1363 _SEH2_END;
1364
1365 /* should never get here */
1366 ASSERT(0);
1367 while(1);
1368}
1369
1370/*
1371 * @implemented
1372 */
1373BOOL
1374WINAPI
1376 IN UINT uExitCode)
1377{
1379
1380 /* Check if no handle was passed in */
1381 if (!hProcess)
1382 {
1383 /* Set error code */
1385 }
1386 else
1387 {
1388 /* Otherwise, try to terminate the process */
1389 Status = NtTerminateProcess(hProcess, uExitCode);
1390 if (NT_SUCCESS(Status)) return TRUE;
1391
1392 /* It failed, convert error code */
1394 }
1395
1396 /* This is the failure path */
1397 return FALSE;
1398}
1399
1400/*
1401 * @implemented
1402 */
1403VOID
1404WINAPI
1406 LPCSTR lpMessageText)
1407{
1408 PUNICODE_STRING MessageTextU;
1409 ANSI_STRING MessageText;
1411
1412 /* Initialize the string using the static TEB pointer */
1413 MessageTextU = &NtCurrentTeb()->StaticUnicodeString;
1414 RtlInitAnsiString(&MessageText, (LPSTR)lpMessageText);
1415
1416 /* Convert to unicode, or just exit normally if this failed */
1417 Status = RtlAnsiStringToUnicodeString(MessageTextU, &MessageText, FALSE);
1418 if (!NT_SUCCESS(Status)) ExitProcess(0);
1419
1420 /* Call the Wide function */
1421 FatalAppExitW(uAction, MessageTextU->Buffer);
1422}
1423
1424/*
1425 * @implemented
1426 */
1427VOID
1428WINAPI
1430 IN LPCWSTR lpMessageText)
1431{
1435
1436 /* Setup the string to print out */
1437 RtlInitUnicodeString(&UnicodeString, lpMessageText);
1438
1439 /* Display the hard error no matter what */
1441 1,
1442 1,
1444#if DBG
1445 /* On Checked builds, Windows allows the user to cancel the operation */
1447#else
1448 OptionOk,
1449#endif
1450 &Response);
1451
1452 /* Give the user a chance to abort */
1454 {
1455 return;
1456 }
1457
1458 /* Otherwise kill the process */
1459 ExitProcess(0);
1460}
1461
1462/*
1463 * @implemented
1464 */
1465VOID
1466WINAPI
1467FatalExit(IN int ExitCode)
1468{
1469#if DBG
1470 /* On Checked builds, Windows gives the user a nice little debugger UI */
1471 CHAR Action[2];
1472 DbgPrint("FatalExit...\n\n");
1473
1474 /* Check for reactos specific flag (set by rosautotest) */
1476 {
1478 }
1479
1480 while (TRUE)
1481 {
1482 DbgPrompt("A (Abort), B (Break), I (Ignore)? ", Action, sizeof(Action));
1483 switch (Action[0])
1484 {
1485 case 'B': case 'b':
1486 DbgBreakPoint();
1487 break;
1488
1489 case 'A': case 'a':
1490 ExitProcess(ExitCode);
1491
1492 case 'I': case 'i':
1493 return;
1494 }
1495 }
1496#endif
1497 /* On other builds, just kill the process */
1498 ExitProcess(ExitCode);
1499}
1500
1501/*
1502 * @implemented
1503 */
1504DWORD
1505WINAPI
1507{
1509 PROCESS_PRIORITY_CLASS DECLSPEC_ALIGN(4) PriorityClass;
1510
1511 /* Query the kernel */
1514 &PriorityClass,
1515 sizeof(PriorityClass),
1516 NULL);
1517 if (NT_SUCCESS(Status))
1518 {
1519 /* Handle the conversion from NT to Win32 classes */
1520 switch (PriorityClass.PriorityClass)
1521 {
1528 }
1529 }
1530
1531 /* Failure path */
1533 return 0;
1534}
1535
1536/*
1537 * @implemented
1538 */
1539BOOL
1540WINAPI
1542 IN DWORD dwPriorityClass)
1543{
1545 PVOID State = NULL;
1546 PROCESS_PRIORITY_CLASS PriorityClass;
1547
1548 /* Handle conversion from Win32 to NT priority classes */
1549 switch (dwPriorityClass)
1550 {
1553 break;
1554
1557 break;
1558
1561 break;
1562
1565 break;
1566
1569 break;
1570
1572 /* Try to acquire the privilege. If it fails, just use HIGH */
1575 PriorityClass.PriorityClass += (State != NULL);
1576 break;
1577
1578 default:
1579 /* Unrecognized priority classes don't make it to the kernel */
1581 return FALSE;
1582 }
1583
1584 /* Send the request to the kernel, and don't touch the foreground flag */
1585 PriorityClass.Foreground = FALSE;
1588 &PriorityClass,
1589 sizeof(PROCESS_PRIORITY_CLASS));
1590
1591 /* Release the privilege if we had it */
1593 if (!NT_SUCCESS(Status))
1594 {
1595 /* Handle error path */
1597 return FALSE;
1598 }
1599
1600 /* All done */
1601 return TRUE;
1602}
1603
1604/*
1605 * @implemented
1606 */
1607DWORD
1608WINAPI
1610{
1611 DWORD Version = 0;
1612 PIMAGE_NT_HEADERS NtHeader;
1613 PIMAGE_DOS_HEADER DosHeader;
1614 PPEB Peb;
1615 PROCESS_BASIC_INFORMATION ProcessBasicInfo;
1620 USHORT VersionData[2];
1622
1623 /* We'll be accessing stuff that can fault, so protect everything with SEH */
1624 _SEH2_TRY
1625 {
1626 /* It this an in-process or out-of-process request? */
1627 if (!(ProcessId) || (GetCurrentProcessId() == ProcessId))
1628 {
1629 /* It's in-process, so just read our own header */
1630 NtHeader = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
1631 if (!NtHeader)
1632 {
1633 /* Unable to read the NT header, something is wrong here... */
1635 goto Error;
1636 }
1637
1638 /* Get the version straight out of the NT header */
1641 }
1642 else
1643 {
1644 /* Out-of-process, so open it */
1646 FALSE,
1647 ProcessId);
1648 if (!ProcessHandle) _SEH2_YIELD(return 0);
1649
1650 /* Try to find out where its PEB lives */
1653 &ProcessBasicInfo,
1654 sizeof(ProcessBasicInfo),
1655 NULL);
1656
1657 if (!NT_SUCCESS(Status)) goto Error;
1658 Peb = ProcessBasicInfo.PebBaseAddress;
1659
1660 /* Now that we have the PEB, read the image base address out of it */
1663 &BaseAddress,
1664 sizeof(BaseAddress),
1665 NULL);
1666 if (!Result) goto Error;
1667
1668 /* Now read the e_lfanew (offset to NT header) from the base */
1669 DosHeader = BaseAddress;
1671 &DosHeader->e_lfanew,
1672 &e_lfanew,
1673 sizeof(e_lfanew),
1674 NULL);
1675 if (!Result) goto Error;
1676
1677 /* And finally, read the NT header itself by adding the offset */
1678 NtHeader = (PVOID)((ULONG_PTR)BaseAddress + e_lfanew);
1681 &VersionData,
1682 sizeof(VersionData),
1683 NULL);
1684 if (!Result) goto Error;
1685
1686 /* Get the version straight out of the NT header */
1687 Version = MAKELONG(VersionData[0], VersionData[1]);
1688
1689Error:
1690 /* If there was an error anywhere, set the last error */
1692 }
1693 }
1695 {
1696 /* Close the process handle */
1698 }
1699 _SEH2_END;
1700
1701 /* And return the version data */
1702 return Version;
1703}
1704
1705/*
1706 * @implemented
1707 */
1708BOOL
1709WINAPI
1711 OUT PIO_COUNTERS lpIoCounters)
1712{
1714
1715 /* Query the kernel. Structures are identical, so let it do the copy too. */
1718 lpIoCounters,
1719 sizeof(IO_COUNTERS),
1720 NULL);
1721 if (!NT_SUCCESS(Status))
1722 {
1723 /* Handle error path */
1725 return FALSE;
1726 }
1727
1728 /* All done */
1729 return TRUE;
1730}
1731
1732/*
1733 * @implemented
1734 */
1735BOOL
1736WINAPI
1738 OUT PBOOL pDisablePriorityBoost)
1739{
1742
1743 /* Query the kernel */
1747 sizeof(PriorityBoost),
1748 NULL);
1749 if (NT_SUCCESS(Status))
1750 {
1751 /* Convert from ULONG to a BOOL */
1752 *pDisablePriorityBoost = PriorityBoost ? TRUE : FALSE;
1753 return TRUE;
1754 }
1755
1756 /* Handle error path */
1758 return FALSE;
1759}
1760
1761/*
1762 * @implemented
1763 */
1764BOOL
1765WINAPI
1767 IN BOOL bDisablePriorityBoost)
1768{
1771
1772 /* Enforce that this is a BOOL, and send it to the kernel as a ULONG */
1773 PriorityBoost = (bDisablePriorityBoost ? TRUE : FALSE);
1777 sizeof(ULONG));
1778 if (!NT_SUCCESS(Status))
1779 {
1780 /* Handle error path */
1782 return FALSE;
1783 }
1784
1785 /* All done */
1786 return TRUE;
1787}
1788
1789/*
1790 * @implemented
1791 */
1792BOOL
1793WINAPI
1795 OUT PDWORD pdwHandleCount)
1796{
1797 ULONG phc;
1799
1800 /* Query the kernel */
1803 &phc,
1804 sizeof(phc),
1805 NULL);
1806 if (NT_SUCCESS(Status))
1807 {
1808 /* Copy the count and return success */
1809 *pdwHandleCount = phc;
1810 return TRUE;
1811 }
1812
1813 /* Handle error path */
1815 return FALSE;
1816}
1817
1818/*
1819 * @implemented
1820 */
1821BOOL
1822WINAPI
1824 OUT PBOOL Wow64Process)
1825{
1826 ULONG_PTR pbi;
1828
1829 /* Query the kernel */
1832 &pbi,
1833 sizeof(pbi),
1834 NULL);
1835 if (!NT_SUCCESS(Status))
1836 {
1837 /* Handle error path */
1839 return FALSE;
1840 }
1841
1842 /* Enforce this is a BOOL, and return success */
1843 *Wow64Process = (pbi != 0);
1844 return TRUE;
1845}
1846
1847/*
1848 * @implemented
1849 */
1850LPSTR
1851WINAPI
1853{
1855}
1856
1857/*
1858 * @implemented
1859 */
1860LPWSTR
1861WINAPI
1863{
1865}
1866
1867/*
1868 * @implemented
1869 */
1870BOOL
1871NTAPI
1873 IN LPCVOID lpBaseAddress,
1875 IN SIZE_T nSize,
1876 OUT SIZE_T* lpNumberOfBytesRead)
1877{
1879
1880 /* Do the read */
1882 (PVOID)lpBaseAddress,
1883 lpBuffer,
1884 nSize,
1885 &nSize);
1886
1887 /* In user-mode, this parameter is optional */
1888 if (lpNumberOfBytesRead) *lpNumberOfBytesRead = nSize;
1889 if (!NT_SUCCESS(Status))
1890 {
1891 /* We failed */
1893 return FALSE;
1894 }
1895
1896 /* Return success */
1897 return TRUE;
1898}
1899
1900/*
1901 * @implemented
1902 */
1903BOOL
1904NTAPI
1906 IN LPVOID lpBaseAddress,
1908 IN SIZE_T nSize,
1909 OUT SIZE_T *lpNumberOfBytesWritten)
1910{
1912 ULONG OldValue;
1914 PVOID Base;
1916
1917 /* Set parameters for protect call */
1918 RegionSize = nSize;
1919 Base = lpBaseAddress;
1920
1921 /* Check the current status */
1923 &Base,
1924 &RegionSize,
1926 &OldValue);
1927 if (NT_SUCCESS(Status))
1928 {
1929 /* Check if we are unprotecting */
1930 UnProtect = OldValue & (PAGE_READWRITE |
1934 if (!UnProtect)
1935 {
1936 /* Set the new protection */
1938 &Base,
1939 &RegionSize,
1940 OldValue,
1941 &OldValue);
1942
1943 /* Write the memory */
1945 lpBaseAddress,
1947 nSize,
1948 &nSize);
1949
1950 /* In Win32, the parameter is optional, so handle this case */
1951 if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = nSize;
1952
1953 if (!NT_SUCCESS(Status))
1954 {
1955 /* We failed */
1957 return FALSE;
1958 }
1959
1960 /* Flush the ITLB */
1961 NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
1962 return TRUE;
1963 }
1964 else
1965 {
1966 /* Check if we were read only */
1967 if (OldValue & (PAGE_NOACCESS | PAGE_READONLY))
1968 {
1969 /* Restore protection and fail */
1971 &Base,
1972 &RegionSize,
1973 OldValue,
1974 &OldValue);
1976
1977 /* Note: This is what Windows returns and code depends on it */
1979 }
1980
1981 /* Otherwise, do the write */
1983 lpBaseAddress,
1985 nSize,
1986 &nSize);
1987
1988 /* In Win32, the parameter is optional, so handle this case */
1989 if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = nSize;
1990
1991 /* And restore the protection */
1993 &Base,
1994 &RegionSize,
1995 OldValue,
1996 &OldValue);
1997 if (!NT_SUCCESS(Status))
1998 {
1999 /* We failed */
2001
2002 /* Note: This is what Windows returns and code depends on it */
2004 }
2005
2006 /* Flush the ITLB */
2007 NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
2008 return TRUE;
2009 }
2010 }
2011 else
2012 {
2013 /* We failed */
2015 return FALSE;
2016 }
2017}
2018
2019/*
2020 * @implemented
2021 */
2022BOOL
2023WINAPI
2025 OUT PDWORD pSessionId)
2026{
2027 PROCESS_SESSION_INFORMATION SessionInformation;
2032
2033 /* Do a quick check if the pointer is not writable */
2034 if (IsBadWritePtr(pSessionId, sizeof(DWORD)))
2035 {
2036 /* Fail fast */
2038 return FALSE;
2039 }
2040
2041 /* Open the process passed in by ID */
2048 &ClientId);
2049 if (NT_SUCCESS(Status))
2050 {
2051 /* Query the session ID from the kernel */
2054 &SessionInformation,
2055 sizeof(SessionInformation),
2056 NULL);
2057
2058 /* Close the handle and check if we succeeded */
2060 if (NT_SUCCESS(Status))
2061 {
2062 /* Return the session ID */
2063 *pSessionId = SessionInformation.SessionId;
2064 return TRUE;
2065 }
2066 }
2067
2068 /* Set error code and fail */
2070 return FALSE;
2071}
2072
2073
2074#define AddToHandle(x,y) ((x) = (HANDLE)((ULONG_PTR)(x) | (y)))
2075#define RemoveFromHandle(x,y) ((x) = (HANDLE)((ULONG_PTR)(x) & ~(y)))
2077
2078/*
2079 * @implemented
2080 */
2081BOOL
2082WINAPI
2084 IN LPCWSTR lpApplicationName,
2085 IN LPWSTR lpCommandLine,
2086 IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
2087 IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
2088 IN BOOL bInheritHandles,
2089 IN DWORD dwCreationFlags,
2090 IN LPVOID lpEnvironment,
2091 IN LPCWSTR lpCurrentDirectory,
2092 IN LPSTARTUPINFOW lpStartupInfo,
2093 IN LPPROCESS_INFORMATION lpProcessInformation,
2094 OUT PHANDLE hNewToken)
2095{
2096 //
2097 // Core variables used for creating the initial process and thread
2098 //
2099 SECURITY_ATTRIBUTES LocalThreadAttributes, LocalProcessAttributes;
2100 OBJECT_ATTRIBUTES LocalObjectAttributes;
2102 SECTION_IMAGE_INFORMATION ImageInformation;
2105 ULONG NoWindow, StackSize, ErrorCode, Flags;
2107 USHORT ImageMachine;
2108 ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse;
2109 ULONG_PTR ErrorParameters[2];
2110 BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege;
2111 BOOLEAN QuerySection, SkipSaferAndAppCompat;
2113 BASE_API_MESSAGE CsrMsg[2];
2114 PBASE_CREATE_PROCESS CreateProcessMsg;
2115 PCSR_CAPTURE_BUFFER CaptureBuffer;
2116 PVOID BaseAddress, PrivilegeState, RealTimePrivilegeState;
2117 HANDLE DebugHandle, TokenHandle, JobHandle, KeyHandle, ThreadHandle;
2118 HANDLE FileHandle, SectionHandle, ProcessHandle;
2120 PROCESS_PRIORITY_CLASS PriorityClass;
2121 NTSTATUS Status, AppCompatStatus, SaferStatus, IFEOStatus, ImageDbgStatus;
2122 PPEB Peb, RemotePeb;
2123 PTEB Teb;
2124 INITIAL_TEB InitialTeb;
2125 PVOID TibValue;
2126 PIMAGE_NT_HEADERS NtHeaders;
2127 STARTUPINFOW StartupInfo;
2128 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
2129 UNICODE_STRING DebuggerString;
2130 BOOL Result;
2131 //
2132 // Variables used for command-line and argument parsing
2133 //
2134 PCHAR pcScan;
2135 SIZE_T n;
2136 WCHAR SaveChar;
2137 ULONG Length, FileAttribs, CmdQuoteLength;
2138 ULONG ResultSize;
2139 SIZE_T EnvironmentLength, CmdLineLength;
2140 PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory;
2141 PWCHAR NullBuffer, ScanString, NameBuffer, SearchPath, DebuggerCmdLine;
2142 ANSI_STRING AnsiEnv;
2143 UNICODE_STRING UnicodeEnv, PathName;
2144 BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName, HasQuotes;
2145
2146 //
2147 // Variables used for Fusion/SxS (Side-by-Side Assemblies)
2148 //
2149 RTL_PATH_TYPE SxsPathType, PathType;
2150#if _SXS_SUPPORT_ENABLED_
2151 PRTL_BUFFER ByteBuffer;
2152 PRTL_UNICODE_STRING_BUFFER ThisBuffer, Buffer, SxsStaticBuffers[5];
2153 PRTL_UNICODE_STRING_BUFFER* BufferHead, SxsStringBuffer;
2154 RTL_UNICODE_STRING_BUFFER SxsWin32ManifestPath, SxsNtManifestPath;
2155 RTL_UNICODE_STRING_BUFFER SxsWin32PolicyPath, SxsNtPolicyPath;
2156 RTL_UNICODE_STRING_BUFFER SxsWin32AssemblyDirectory;
2157 BASE_MSG_SXS_HANDLES MappedHandles, Handles, FileHandles;
2158 PVOID CapturedStrings[3];
2159 SXS_WIN32_NT_PATH_PAIR ExePathPair, ManifestPathPair, PolicyPathPair;
2160 SXS_OVERRIDE_MANIFEST OverrideManifest;
2161 UNICODE_STRING FreeString, SxsNtExePath;
2162 PWCHAR SxsConglomeratedBuffer, StaticBuffer;
2163 ULONG ConglomeratedBufferSizeBytes, StaticBufferSize, i;
2164#endif
2166
2167 //
2168 // Variables used for path conversion (and partially Fusion/SxS)
2169 //
2170 PWCHAR FilePart, PathBuffer, FreeBuffer;
2171 BOOLEAN TranslationStatus;
2172 RTL_RELATIVE_NAME_U SxsWin32RelativePath;
2173 UNICODE_STRING PathBufferString, SxsWin32ExePath;
2174
2175 //
2176 // Variables used by Application Compatibility (and partially Fusion/SxS)
2177 //
2178 PVOID AppCompatSxsData, AppCompatData;
2179 ULONG AppCompatSxsDataSize, AppCompatDataSize;
2180 //
2181 // Variables used by VDM (Virtual Dos Machine) and WOW32 (16-bit Support)
2182 //
2183 ULONG BinarySubType, VdmBinaryType, VdmTask, VdmReserve;
2184 ULONG VdmUndoLevel;
2185 BOOLEAN UseVdmReserve;
2186 HANDLE VdmWaitObject;
2187 ANSI_STRING VdmAnsiEnv;
2188 UNICODE_STRING VdmString, VdmUnicodeEnv;
2189 BOOLEAN IsWowApp;
2190 PBASE_CHECK_VDM CheckVdmMsg;
2191
2192 /* Zero out the initial core variables and handles */
2193 QuerySection = FALSE;
2194 InJob = FALSE;
2195 SkipSaferAndAppCompat = FALSE;
2196 ParameterFlags = 0;
2197 Flags = 0;
2198 DebugHandle = NULL;
2199 JobHandle = NULL;
2200 TokenHandle = NULL;
2201 FileHandle = NULL;
2202 SectionHandle = NULL;
2204 ThreadHandle = NULL;
2206 BaseAddress = (PVOID)1;
2207
2208 /* Zero out initial SxS and Application Compatibility state */
2209 AppCompatData = NULL;
2210 AppCompatDataSize = 0;
2211 AppCompatSxsData = NULL;
2212 AppCompatSxsDataSize = 0;
2213 CaptureBuffer = NULL;
2214#if _SXS_SUPPORT_ENABLED_
2215 SxsConglomeratedBuffer = NULL;
2216#endif
2217 FusionFlags = 0;
2218
2219 /* Zero out initial parsing variables -- others are initialized later */
2220 DebuggerCmdLine = NULL;
2221 PathBuffer = NULL;
2222 SearchPath = NULL;
2223 NullBuffer = NULL;
2224 FreeBuffer = NULL;
2225 NameBuffer = NULL;
2227 FilePart = NULL;
2228 DebuggerString.Buffer = NULL;
2229 HasQuotes = FALSE;
2230 QuotedCmdLine = NULL;
2231
2232 /* Zero out initial VDM state */
2233 VdmAnsiEnv.Buffer = NULL;
2234 VdmUnicodeEnv.Buffer = NULL;
2235 VdmString.Buffer = NULL;
2236 VdmTask = 0;
2237 VdmUndoLevel = 0;
2238 VdmBinaryType = 0;
2239 VdmReserve = 0;
2240 VdmWaitObject = NULL;
2241 UseVdmReserve = FALSE;
2242 IsWowApp = FALSE;
2243
2244 /* Set message structures */
2245 CreateProcessMsg = &CsrMsg[0].Data.CreateProcessRequest;
2246 CheckVdmMsg = &CsrMsg[1].Data.CheckVDMRequest;
2247
2248 /* Clear the more complex structures by zeroing out their entire memory */
2249 RtlZeroMemory(&Context, sizeof(Context));
2250#if _SXS_SUPPORT_ENABLED_
2251 RtlZeroMemory(&FileHandles, sizeof(FileHandles));
2252 RtlZeroMemory(&MappedHandles, sizeof(MappedHandles));
2253 RtlZeroMemory(&Handles, sizeof(Handles));
2254#endif
2255 RtlZeroMemory(&CreateProcessMsg->Sxs, sizeof(CreateProcessMsg->Sxs));
2256 RtlZeroMemory(&LocalProcessAttributes, sizeof(LocalProcessAttributes));
2257 RtlZeroMemory(&LocalThreadAttributes, sizeof(LocalThreadAttributes));
2258
2259 /* Zero out output arguments as well */
2260 RtlZeroMemory(lpProcessInformation, sizeof(*lpProcessInformation));
2261 if (hNewToken) *hNewToken = NULL;
2262
2263 /* Capture the special window flag */
2264 NoWindow = dwCreationFlags & CREATE_NO_WINDOW;
2265 dwCreationFlags &= ~CREATE_NO_WINDOW;
2266
2267#if _SXS_SUPPORT_ENABLED_
2268 /* Setup the SxS static string arrays and buffers */
2269 SxsStaticBuffers[0] = &SxsWin32ManifestPath;
2270 SxsStaticBuffers[1] = &SxsWin32PolicyPath;
2271 SxsStaticBuffers[2] = &SxsWin32AssemblyDirectory;
2272 SxsStaticBuffers[3] = &SxsNtManifestPath;
2273 SxsStaticBuffers[4] = &SxsNtPolicyPath;
2274 ExePathPair.Win32 = &SxsWin32ExePath;
2275 ExePathPair.Nt = &SxsNtExePath;
2276 ManifestPathPair.Win32 = &SxsWin32ManifestPath.String;
2277 ManifestPathPair.Nt = &SxsNtManifestPath.String;
2278 PolicyPathPair.Win32 = &SxsWin32PolicyPath.String;
2279 PolicyPathPair.Nt = &SxsNtPolicyPath.String;
2280#endif
2281
2282 DPRINT("CreateProcessInternalW: '%S' '%S' %lx\n", lpApplicationName, lpCommandLine, dwCreationFlags);
2283
2284 /* Finally, set our TEB and PEB */
2285 Teb = NtCurrentTeb();
2286 Peb = NtCurrentPeb();
2287
2288 /* This combination is illegal (see MSDN) */
2289 if ((dwCreationFlags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)) ==
2291 {
2292 DPRINT1("Invalid flag combo used\n");
2294 return FALSE;
2295 }
2296
2297 /* Convert the priority class */
2298 if (dwCreationFlags & IDLE_PRIORITY_CLASS)
2299 {
2301 }
2302 else if (dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS)
2303 {
2305 }
2306 else if (dwCreationFlags & NORMAL_PRIORITY_CLASS)
2307 {
2309 }
2310 else if (dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS)
2311 {
2313 }
2314 else if (dwCreationFlags & HIGH_PRIORITY_CLASS)
2315 {
2317 }
2318 else if (dwCreationFlags & REALTIME_PRIORITY_CLASS)
2319 {
2321 PriorityClass.PriorityClass += (BasepIsRealtimeAllowed(FALSE) != NULL);
2322 }
2323 else
2324 {
2326 }
2327
2328 /* Done with the priority masks, so get rid of them */
2329 PriorityClass.Foreground = FALSE;
2330 dwCreationFlags &= ~(NORMAL_PRIORITY_CLASS |
2336
2337 /* You cannot request both a shared and a separate WoW VDM */
2338 if ((dwCreationFlags & CREATE_SEPARATE_WOW_VDM) &&
2339 (dwCreationFlags & CREATE_SHARED_WOW_VDM))
2340 {
2341 /* Fail such nonsensical attempts */
2342 DPRINT1("Invalid WOW flags\n");
2344 return FALSE;
2345 }
2346 else if (!(dwCreationFlags & CREATE_SHARED_WOW_VDM) &&
2348 {
2349 /* A shared WoW VDM was not requested but system enforces separation */
2350 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
2351 }
2352
2353 /* If a shared WoW VDM is used, make sure the process isn't in a job */
2354 if (!(dwCreationFlags & CREATE_SEPARATE_WOW_VDM) &&
2356 {
2357 /* Remove the shared flag and add the separate flag */
2358 dwCreationFlags = (dwCreationFlags &~ CREATE_SHARED_WOW_VDM) |
2360 }
2361
2362 /* Convert the environment */
2363 if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
2364 {
2365 /* Scan the environment to calculate its Unicode size */
2366 AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment;
2367 while ((*pcScan) || (*(pcScan + 1))) ++pcScan;
2368
2369 /* Make sure the environment is not too large */
2370 EnvironmentLength = (pcScan + sizeof(ANSI_NULL) - (PCHAR)lpEnvironment);
2371 if (EnvironmentLength > MAXUSHORT)
2372 {
2373 /* Fail */
2375 return FALSE;
2376 }
2377
2378 /* Create our ANSI String */
2379 AnsiEnv.Length = (USHORT)EnvironmentLength;
2380 AnsiEnv.MaximumLength = AnsiEnv.Length + sizeof(ANSI_NULL);
2381
2382 /* Allocate memory for the Unicode Environment */
2383 UnicodeEnv.Buffer = NULL;
2384 RegionSize = AnsiEnv.MaximumLength * sizeof(WCHAR);
2386 (PVOID)&UnicodeEnv.Buffer,
2387 0,
2388 &RegionSize,
2389 MEM_COMMIT,
2391 if (!NT_SUCCESS(Status))
2392 {
2393 /* Fail */
2395 return FALSE;
2396 }
2397
2398 /* Use the allocated size and convert */
2399 UnicodeEnv.MaximumLength = (USHORT)RegionSize;
2400 Status = RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE);
2401 if (!NT_SUCCESS(Status))
2402 {
2403 /* Fail */
2405 (PVOID)&UnicodeEnv.Buffer,
2406 &RegionSize,
2407 MEM_RELEASE);
2409 return FALSE;
2410 }
2411
2412 /* Now set the Unicode environment as the environment string pointer */
2413 lpEnvironment = UnicodeEnv.Buffer;
2414 }
2415
2416 /* Make a copy of the caller's startup info since we'll modify it */
2417 StartupInfo = *lpStartupInfo;
2418
2419 /* Check if private data is being sent on the same channel as std handles */
2420 if ((StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
2421 (StartupInfo.dwFlags & (STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
2422 {
2423 /* Cannot use the std handles since we have monitor/hotkey values */
2424 StartupInfo.dwFlags &= ~STARTF_USESTDHANDLES;
2425 }
2426
2427 /* If there's a debugger, or we have to launch cmd.exe, we go back here */
2428AppNameRetry:
2429 /* New iteration -- free any existing name buffer */
2430 if (NameBuffer)
2431 {
2432 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
2433 NameBuffer = NULL;
2434 }
2435
2436 /* New iteration -- free any existing free buffer */
2437 if (FreeBuffer)
2438 {
2439 RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
2440 FreeBuffer = NULL;
2441 }
2442
2443 /* New iteration -- close any existing file handle */
2444 if (FileHandle)
2445 {
2447 FileHandle = NULL;
2448 }
2449
2450 /* Set the initial parsing state. This code can loop -- don't move this! */
2451 ErrorCode = 0;
2452 SearchRetry = TRUE;
2453 QuotesNeeded = FALSE;
2454 CmdLineIsAppName = FALSE;
2455
2456 /* First check if we don't have an application name */
2457 if (!lpApplicationName)
2458 {
2459 /* This should be the first time we attempt creating one */
2460 ASSERT(NameBuffer == NULL);
2461
2462 /* Allocate a buffer to hold it */
2463 NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
2464 0,
2465 MAX_PATH * sizeof(WCHAR));
2466 if (!NameBuffer)
2467 {
2469 Result = FALSE;
2470 goto Quickie;
2471 }
2472
2473 /* Initialize the application name and our parsing parameters */
2474 lpApplicationName = NullBuffer = ScanString = lpCommandLine;
2475
2476 /* Check for an initial quote*/
2477 if (*lpCommandLine == L'\"')
2478 {
2479 /* We found a quote, keep searching for another one */
2480 SearchRetry = FALSE;
2481 ScanString++;
2482 lpApplicationName = ScanString;
2483 while (*ScanString)
2484 {
2485 /* Have we found the terminating quote? */
2486 if (*ScanString == L'\"')
2487 {
2488 /* We're done, get out of here */
2489 NullBuffer = ScanString;
2490 HasQuotes = TRUE;
2491 break;
2492 }
2493
2494 /* Keep searching for the quote */
2495 ScanString++;
2496 NullBuffer = ScanString;
2497 }
2498 }
2499 else
2500 {
2501StartScan:
2502 /* We simply make the application name be the command line*/
2503 lpApplicationName = lpCommandLine;
2504 while (*ScanString)
2505 {
2506 /* Check if it starts with a space or tab */
2507 if ((*ScanString == L' ') || (*ScanString == L'\t'))
2508 {
2509 /* Break out of the search loop */
2510 NullBuffer = ScanString;
2511 break;
2512 }
2513
2514 /* Keep searching for a space or tab */
2515 ScanString++;
2516 NullBuffer = ScanString;
2517 }
2518 }
2519
2520 /* We have found the end of the application name, terminate it */
2521 SaveChar = *NullBuffer;
2522 *NullBuffer = UNICODE_NULL;
2523
2524 /* New iteration -- free any existing saved path */
2525 if (SearchPath)
2526 {
2527 RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
2528 SearchPath = NULL;
2529 }
2530
2531 /* Now compute the final EXE path based on the name */
2532 SearchPath = BaseComputeProcessExePath((LPWSTR)lpApplicationName);
2533 DPRINT("Search Path: %S\n", SearchPath);
2534 if (!SearchPath)
2535 {
2537 Result = FALSE;
2538 goto Quickie;
2539 }
2540
2541 /* And search for the executable in the search path */
2543 lpApplicationName,
2544 L".exe",
2545 MAX_PATH,
2546 NameBuffer,
2547 NULL);
2548
2549 /* Did we find it? */
2550 if ((Length) && (Length < MAX_PATH))
2551 {
2552 /* Get file attributes */
2553 FileAttribs = GetFileAttributesW(NameBuffer);
2554 if ((FileAttribs != INVALID_FILE_ATTRIBUTES) &&
2555 (FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
2556 {
2557 /* This was a directory, fail later on */
2558 Length = 0;
2559 }
2560 else
2561 {
2562 /* It's a file! */
2563 Length++;
2564 }
2565 }
2566
2567 DPRINT("Length: %lu Buffer: %S\n", Length, NameBuffer);
2568
2569 /* Check if there was a failure in SearchPathW */
2570 if ((Length) && (Length < MAX_PATH))
2571 {
2572 /* Everything looks good, restore the name */
2573 *NullBuffer = SaveChar;
2574 lpApplicationName = NameBuffer;
2575 }
2576 else
2577 {
2578 /* Check if this was a relative path, which would explain it */
2579 PathType = RtlDetermineDosPathNameType_U(lpApplicationName);
2581 {
2582 /* This should fail, and give us a detailed LastError */
2583 FileHandle = CreateFileW(lpApplicationName,
2587 NULL,
2590 NULL);
2592 {
2593 /* It worked? Return a generic error */
2595 FileHandle = NULL;
2597 }
2598 }
2599 else
2600 {
2601 /* Path was absolute, which means it doesn't exist */
2603 }
2604
2605 /* Did we already fail once? */
2606 if (ErrorCode)
2607 {
2608 /* Set the error code */
2610 }
2611 else
2612 {
2613 /* Not yet, cache it */
2615 }
2616
2617 /* Put back the command line */
2618 *NullBuffer = SaveChar;
2619 lpApplicationName = NameBuffer;
2620
2621 /* It's possible there's whitespace in the directory name */
2622 if (!(*ScanString) || !(SearchRetry))
2623 {
2624 /* Not the case, give up completely */
2625 Result = FALSE;
2626 goto Quickie;
2627 }
2628
2629 /* There are spaces, so keep trying the next possibility */
2630 ScanString++;
2631 NullBuffer = ScanString;
2632
2633 /* We will have to add a quote, since there is a space */
2634 QuotesNeeded = TRUE;
2635 HasQuotes = TRUE;
2636 goto StartScan;
2637 }
2638 }
2639 else if (!(lpCommandLine) || !(*lpCommandLine))
2640 {
2641 /* We don't have a command line, so just use the application name */
2642 CmdLineIsAppName = TRUE;
2643 lpCommandLine = (LPWSTR)lpApplicationName;
2644 }
2645
2646 /* Convert the application name to its NT path */
2647 TranslationStatus = RtlDosPathNameToRelativeNtPathName_U(lpApplicationName,
2648 &PathName,
2649 NULL,
2650 &SxsWin32RelativePath);
2651 if (!TranslationStatus)
2652 {
2653 /* Path must be invalid somehow, bail out */
2654 DPRINT1("Path translation for SxS failed\n");
2656 Result = FALSE;
2657 goto Quickie;
2658 }
2659
2660 /* Setup the buffer that needs to be freed at the end */
2661 ASSERT(FreeBuffer == NULL);
2662 FreeBuffer = PathName.Buffer;
2663
2664 /* Check what kind of path the application is, for SxS (Fusion) purposes */
2665 RtlInitUnicodeString(&SxsWin32ExePath, lpApplicationName);
2666 SxsPathType = RtlDetermineDosPathNameType_U(lpApplicationName);
2667 if ((SxsPathType != RtlPathTypeDriveAbsolute) &&
2668 (SxsPathType != RtlPathTypeLocalDevice) &&
2669 (SxsPathType != RtlPathTypeRootLocalDevice) &&
2670 (SxsPathType != RtlPathTypeUncAbsolute))
2671 {
2672 /* Relative-type path, get the full path */
2673 RtlInitEmptyUnicodeString(&PathBufferString, NULL, 0);
2674 Status = RtlGetFullPathName_UstrEx(&SxsWin32ExePath,
2675 NULL,
2676 &PathBufferString,
2677 NULL,
2678 NULL,
2679 NULL,
2680 &SxsPathType,
2681 NULL);
2682 if (!NT_SUCCESS(Status))
2683 {
2684 /* Fail the rest of the create */
2685 RtlReleaseRelativeName(&SxsWin32RelativePath);
2687 Result = FALSE;
2688 goto Quickie;
2689 }
2690
2691 /* Use this full path as the SxS path */
2692 SxsWin32ExePath = PathBufferString;
2693 PathBuffer = PathBufferString.Buffer;
2694 PathBufferString.Buffer = NULL;
2695 DPRINT("SxS Path: %S\n", PathBuffer);
2696 }
2697
2698 /* Also set the .EXE path based on the path name */
2699#if _SXS_SUPPORT_ENABLED_
2700 SxsNtExePath = PathName;
2701#endif
2702 if (SxsWin32RelativePath.RelativeName.Length)
2703 {
2704 /* If it's relative, capture the relative name */
2705 PathName = SxsWin32RelativePath.RelativeName;
2706 }
2707 else
2708 {
2709 /* Otherwise, it's absolute, make sure no relative dir is used */
2710 SxsWin32RelativePath.ContainingDirectory = NULL;
2711 }
2712
2713 /* Now use the path name, and the root path, to try opening the app */
2714 DPRINT("Path: %wZ. Dir: %p\n", &PathName, SxsWin32RelativePath.ContainingDirectory);
2715 InitializeObjectAttributes(&LocalObjectAttributes,
2716 &PathName,
2718 SxsWin32RelativePath.ContainingDirectory,
2719 NULL);
2721 SYNCHRONIZE |
2725 &LocalObjectAttributes,
2730 if (!NT_SUCCESS(Status))
2731 {
2732 /* Try to open the app just for execute purposes instead */
2735 &LocalObjectAttributes,
2740 }
2741
2742 /* Failure path, display which file failed to open */
2743 if (!NT_SUCCESS(Status))
2744 DPRINT1("Open file failed: %lx (%wZ)\n", Status, &PathName);
2745
2746 /* Cleanup in preparation for failure or success */
2747 RtlReleaseRelativeName(&SxsWin32RelativePath);
2748
2749 if (!NT_SUCCESS(Status))
2750 {
2751 /* Failure path, try to understand why */
2752 if (RtlIsDosDeviceName_U(lpApplicationName))
2753 {
2754 /* If a device is being executed, return this special error code */
2756 Result = FALSE;
2757 goto Quickie;
2758 }
2759 else
2760 {
2761 /* Otherwise return the converted NT error code */
2763 Result = FALSE;
2764 goto Quickie;
2765 }
2766 }
2767
2768 /* Did the caller specify a desktop? */
2769 if (!StartupInfo.lpDesktop)
2770 {
2771 /* Use the one from the current process */
2773 }
2774
2775 /* Create a section for this file */
2776 Status = NtCreateSection(&SectionHandle,
2778 NULL,
2779 NULL,
2781 SEC_IMAGE,
2782 FileHandle);
2783 DPRINT("Section status: %lx\n", Status);
2784 if (NT_SUCCESS(Status))
2785 {
2786 /* Are we running on Windows Embedded, Datacenter, Blade or Starter? */
2787 if (SharedUserData->SuiteMask & (VER_SUITE_EMBEDDEDNT |
2791 {
2792 /* These SKUs do not allow running certain applications */
2795 {
2796 /* And this is one of them! */
2797 DPRINT1("Invalid Blade hashes!\n");
2799 Result = FALSE;
2800 goto Quickie;
2801 }
2802
2803 /* Did we get some other failure? */
2804 if (!NT_SUCCESS(Status))
2805 {
2806 /* If we couldn't check the hashes, assume nefariousness */
2807 DPRINT1("Tampered Blade hashes!\n");
2809 Result = FALSE;
2810 goto Quickie;
2811 }
2812 }
2813
2814 /* Now do Winsafer, etc, checks */
2815 Status = BasepIsProcessAllowed((LPWSTR)lpApplicationName);
2816 if (!NT_SUCCESS(Status))
2817 {
2818 /* Fail if we're not allowed to launch the process */
2819 DPRINT1("Process not allowed to launch: %lx\n", Status);
2821 if (SectionHandle)
2822 {
2823 NtClose(SectionHandle);
2824 SectionHandle = NULL;
2825 }
2826 Result = FALSE;
2827 goto Quickie;
2828 }
2829
2830 /* Is a DOS VDM being forced, but we already have a WOW32 instance ready? */
2831 if ((dwCreationFlags & CREATE_FORCEDOS) &&
2833 {
2834 /* This request can't be satisfied, instead, a separate VDM is needed */
2835 dwCreationFlags &= ~(CREATE_FORCEDOS | CREATE_SHARED_WOW_VDM);
2836 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
2837
2838 /* Set a failure code, ask for VDM reservation */
2840 UseVdmReserve = TRUE;
2841
2842 /* Close the current handle */
2843 NtClose(SectionHandle);
2844 SectionHandle = NULL;
2845
2846 /* Don't query the section later */
2847 QuerySection = FALSE;
2848 }
2849 }
2850
2851 /* Did we already do these checks? */
2852 if (!SkipSaferAndAppCompat)
2853 {
2854 /* Is everything OK so far, OR do we have an non-MZ, non-DOS app? */
2855 if ((NT_SUCCESS(Status)) ||
2857 !(BaseIsDosApplication(&PathName, Status))))
2858 {
2859 /* Clear the machine type in case of failure */
2860 ImageMachine = 0;
2861
2862 /* Clean any app compat data that may have accumulated */
2863 BasepFreeAppCompatData(AppCompatData, AppCompatSxsData);
2864 AppCompatData = NULL;
2865 AppCompatSxsData = NULL;
2866
2867 /* Do we have a section? */
2868 if (SectionHandle)
2869 {
2870 /* Have we already queried it? */
2871 if (QuerySection)
2872 {
2873 /* Nothing to do */
2874 AppCompatStatus = STATUS_SUCCESS;
2875 }
2876 else
2877 {
2878 /* Get some information about the executable */
2879 AppCompatStatus = NtQuerySection(SectionHandle,
2881 &ImageInformation,
2882 sizeof(ImageInformation),
2883 NULL);
2884 }
2885
2886 /* Do we have section information now? */
2887 if (NT_SUCCESS(AppCompatStatus))
2888 {
2889 /* Don't ask for it again, save the machine type */
2890 QuerySection = TRUE;
2891 ImageMachine = ImageInformation.Machine;
2892 }
2893 }
2894
2895 /* Is there a reason/Shim we shouldn't run this application? */
2896 AppCompatStatus = BasepCheckBadapp(FileHandle,
2897 FreeBuffer,
2898 lpEnvironment,
2899 ImageMachine,
2900 &AppCompatData,
2901 &AppCompatDataSize,
2902 &AppCompatSxsData,
2903 &AppCompatSxsDataSize,
2904 &FusionFlags);
2905 if (!NT_SUCCESS(AppCompatStatus))
2906 {
2907 /* This is usually the status we get back */
2908 DPRINT1("App compat launch failure: %lx\n", AppCompatStatus);
2909 if (AppCompatStatus == STATUS_ACCESS_DENIED)
2910 {
2911 /* Convert it to something more Win32-specific */
2913 }
2914 else
2915 {
2916 /* Some other error */
2917 BaseSetLastNTError(AppCompatStatus);
2918 }
2919
2920 /* Did we have a section? */
2921 if (SectionHandle)
2922 {
2923 /* Clean it up */
2924 NtClose(SectionHandle);
2925 SectionHandle = NULL;
2926 }
2927
2928 /* Fail the call */
2929 Result = FALSE;
2930 goto Quickie;
2931 }
2932 }
2933 }
2934
2935 //ASSERT((dwFusionFlags & ~SXS_APPCOMPACT_FLAG_APP_RUNNING_SAFEMODE) == 0);
2936
2937 /* Have we already done, and do we need to do, SRP (WinSafer) checks? */
2938 if (!(SkipSaferAndAppCompat) &&
2939 ~(dwCreationFlags & CREATE_PRESERVE_CODE_AUTHZ_LEVEL))
2940 {
2941 /* Assume yes */
2942 SaferNeeded = TRUE;
2943 switch (Status)
2944 {
2949 /* For all DOS, 16-bit, OS/2 images, we do*/
2950 break;
2951
2953 /* For invalid files, we don't, unless it's a .BAT file */
2954 if (BaseIsDosApplication(&PathName, Status)) break;
2955
2956 default:
2957 /* Any other error codes we also don't */
2958 if (!NT_SUCCESS(Status))
2959 {
2960 SaferNeeded = FALSE;
2961 }
2962
2963 /* But for success, we do */
2964 break;
2965 }
2966
2967 /* Okay, so what did the checks above result in? */
2968 if (SaferNeeded)
2969 {
2970 /* We have to call into the WinSafer library and actually check */
2972 (LPWSTR)lpApplicationName,
2973 FileHandle,
2974 &InJob,
2975 &TokenHandle,
2976 &JobHandle);
2977 if (SaferStatus == 0xFFFFFFFF)
2978 {
2979 /* Back in 2003, they didn't have an NTSTATUS for this... */
2980 DPRINT1("WinSafer blocking process launch\n");
2982 Result = FALSE;
2983 goto Quickie;
2984 }
2985
2986 /* Other status codes are not-Safer related, just convert them */
2987 if (!NT_SUCCESS(SaferStatus))
2988 {
2989 DPRINT1("Error checking WinSafer: %lx\n", SaferStatus);
2990 BaseSetLastNTError(SaferStatus);
2991 Result = FALSE;
2992 goto Quickie;
2993 }
2994 }
2995 }
2996
2997 /* The last step is to figure out why the section object was not created */
2998 switch (Status)
2999 {
3001 {
3002 /* 16-bit binary. Should we use WOW or does the caller force VDM? */
3003 if (!(dwCreationFlags & CREATE_FORCEDOS))
3004 {
3005 /* Remember that we're launching WOW */
3006 IsWowApp = TRUE;
3007
3008 /* Create the VDM environment, it's valid for WOW too */
3009 Result = BaseCreateVDMEnvironment(lpEnvironment,
3010 &VdmAnsiEnv,
3011 &VdmUnicodeEnv);
3012 if (!Result)
3013 {
3014 DPRINT1("VDM environment for WOW app failed\n");
3015 goto Quickie;
3016 }
3017
3018 /* We're going to try this twice, so do a loop */
3019 while (TRUE)
3020 {
3021 /* Pick which kind of WOW mode we want to run in */
3022 VdmBinaryType = (dwCreationFlags &
3025
3026 /* Get all the VDM settings and current status */
3027 Status = BaseCheckVDM(VdmBinaryType,
3028 lpApplicationName,
3029 lpCommandLine,
3030 lpCurrentDirectory,
3031 &VdmAnsiEnv,
3032 &CsrMsg[1],
3033 &VdmTask,
3034 dwCreationFlags,
3035 &StartupInfo,
3036 hUserToken);
3037
3038 /* If it worked, no need to try again */
3039 if (NT_SUCCESS(Status)) break;
3040
3041 /* Check if it's disallowed or if it's our second time */
3043 if ((Status == STATUS_VDM_DISALLOWED) ||
3044 (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW) ||
3046 {
3047 /* Fail the call -- we won't try again */
3048 DPRINT1("VDM message failure for WOW: %lx\n", Status);
3049 Result = FALSE;
3050 goto Quickie;
3051 }
3052
3053 /* Try one more time, but with a separate WOW instance */
3054 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
3055 }
3056
3057 /* Check which VDM state we're currently in */
3058 switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
3060 VDM_READY))
3061 {
3062 case VDM_NOT_LOADED:
3063 /* VDM is not fully loaded, so not that much to undo */
3064 VdmUndoLevel = VDM_UNDO_PARTIAL;
3065
3066 /* Reset VDM reserve if needed */
3067 if (UseVdmReserve) VdmReserve = 1;
3068
3069 /* Get the required parameters and names for launch */
3070 Result = BaseGetVdmConfigInfo(lpCommandLine,
3071 VdmTask,
3072 VdmBinaryType,
3073 &VdmString,
3074 &VdmReserve);
3075 if (!Result)
3076 {
3077 DPRINT1("VDM Configuration failed for WOW\n");
3079 goto Quickie;
3080 }
3081
3082 /* Update the command-line with the VDM one instead */
3083 lpCommandLine = VdmString.Buffer;
3084 lpApplicationName = NULL;
3085
3086 /* We don't want a console, detachment, nor a window */
3087 dwCreationFlags |= CREATE_NO_WINDOW;
3088 dwCreationFlags &= ~(CREATE_NEW_CONSOLE | DETACHED_PROCESS);
3089
3090 /* Force feedback on */
3091 StartupInfo.dwFlags |= STARTF_FORCEONFEEDBACK;
3092 break;
3093
3094
3095 case VDM_READY:
3096 /* VDM is ready, so we have to undo everything */
3097 VdmUndoLevel = VDM_UNDO_REUSE;
3098
3099 /* Check if CSRSS wants us to wait on VDM */
3100 VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
3101 break;
3102
3103 case VDM_NOT_READY:
3104 /* Something is wrong with VDM, we'll fail the call */
3105 DPRINT1("VDM is not ready for WOW\n");
3107 Result = FALSE;
3108 goto Quickie;
3109
3110 default:
3111 break;
3112 }
3113
3114 /* Since to get NULL, we allocate from 0x1, account for this */
3115 VdmReserve--;
3116
3117 /* This implies VDM is ready, so skip everything else */
3118 if (VdmWaitObject) goto VdmShortCircuit;
3119
3120 /* Don't inherit handles since we're doing VDM now */
3121 bInheritHandles = FALSE;
3122
3123 /* Had the user passed in environment? If so, destroy it */
3124 if ((lpEnvironment) &&
3125 !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
3126 {
3127 RtlDestroyEnvironment(lpEnvironment);
3128 }
3129
3130 /* We've already done all these checks, don't do them again */
3131 SkipSaferAndAppCompat = TRUE;
3132 goto AppNameRetry;
3133 }
3134
3135 // There is no break here on purpose, so FORCEDOS drops down!
3136 }
3137
3141 {
3142 /* We're launching an executable application */
3143 BinarySubType = BINARY_TYPE_EXE;
3144
3145 /* We can drop here from other "cases" above too, so check */
3148 (BinarySubType = BaseIsDosApplication(&PathName, Status)))
3149 {
3150 /* We're launching a DOS application */
3151 VdmBinaryType = BINARY_TYPE_DOS;
3152
3153 /* Based on the caller environment, create a VDM one */
3154 Result = BaseCreateVDMEnvironment(lpEnvironment,
3155 &VdmAnsiEnv,
3156 &VdmUnicodeEnv);
3157 if (!Result)
3158 {
3159 DPRINT1("VDM environment for DOS failed\n");
3160 goto Quickie;
3161 }
3162
3163 /* Check the current state of the VDM subsystem */
3164 Status = BaseCheckVDM(VdmBinaryType | BinarySubType,
3165 lpApplicationName,
3166 lpCommandLine,
3167 lpCurrentDirectory,
3168 &VdmAnsiEnv,
3169 &CsrMsg[1],
3170 &VdmTask,
3171 dwCreationFlags,
3172 &StartupInfo,
3173 NULL);
3174 if (!NT_SUCCESS(Status))
3175 {
3176 /* Failed to inquire about VDM, fail the call */
3177 DPRINT1("VDM message failure for DOS: %lx\n", Status);
3179 Result = FALSE;
3180 goto Quickie;
3181 };
3182
3183 /* Handle possible VDM states */
3184 switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
3186 VDM_READY))
3187 {
3188 case VDM_NOT_LOADED:
3189 /* If VDM is not loaded, we'll do a partial undo */
3190 VdmUndoLevel = VDM_UNDO_PARTIAL;
3191
3192 /* A VDM process can't also be detached, so fail */
3193 if (dwCreationFlags & DETACHED_PROCESS)
3194 {
3195 DPRINT1("Detached process but no VDM, not allowed\n");
3197 return FALSE;
3198 }
3199
3200 /* Get the required parameters and names for launch */
3201 Result = BaseGetVdmConfigInfo(lpCommandLine,
3202 VdmTask,
3203 VdmBinaryType,
3204 &VdmString,
3205 &VdmReserve);
3206 if (!Result)
3207 {
3208 DPRINT1("VDM Configuration failed for DOS\n");
3210 goto Quickie;
3211 }
3212
3213 /* Update the command-line to launch VDM instead */
3214 lpCommandLine = VdmString.Buffer;
3215 lpApplicationName = NULL;
3216 break;
3217
3218 case VDM_READY:
3219 /* VDM is ready, so we have to undo everything */
3220 VdmUndoLevel = VDM_UNDO_REUSE;
3221
3222 /* Check if CSRSS wants us to wait on VDM */
3223 VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
3224 break;
3225
3226 case VDM_NOT_READY:
3227 /* Something is wrong with VDM, we'll fail the call */
3228 DPRINT1("VDM is not ready for DOS\n");
3230 Result = FALSE;
3231 goto Quickie;
3232
3233 default:
3234 break;
3235 }
3236
3237 /* Since to get NULL, we allocate from 0x1, account for this */
3238 VdmReserve--;
3239
3240 /* This implies VDM is ready, so skip everything else */
3241 if (VdmWaitObject) goto VdmShortCircuit;
3242
3243 /* Don't inherit handles since we're doing VDM now */
3244 bInheritHandles = FALSE;
3245
3246 /* Had the user passed in environment? If so, destroy it */
3247 if ((lpEnvironment) &&
3248 !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
3249 {
3250 RtlDestroyEnvironment(lpEnvironment);
3251 }
3252
3253 /* Use our VDM Unicode environment instead */
3254 lpEnvironment = VdmUnicodeEnv.Buffer;
3255 }
3256 else
3257 {
3258 /* It's a batch file, get the extension */
3259 ExtBuffer = &PathName.Buffer[PathName.Length / sizeof(WCHAR) - 4];
3260
3261 /* Make sure the extensions are correct */
3262 if ((PathName.Length < (4 * sizeof(WCHAR))) ||
3263 ((_wcsnicmp(ExtBuffer, L".bat", 4)) &&
3264 (_wcsnicmp(ExtBuffer, L".cmd", 4))))
3265 {
3266 DPRINT1("'%wZ': Invalid EXE, and not a batch or script file\n", &PathName);
3268 Result = FALSE;
3269 goto Quickie;
3270 }
3271
3272 /* Check if we need to account for quotes around the path */
3273 CmdQuoteLength = CmdLineIsAppName || HasQuotes;
3274 if (!CmdLineIsAppName)
3275 {
3276 if (HasQuotes) CmdQuoteLength++;
3277 }
3278 else
3279 {
3280 CmdQuoteLength++;
3281 }
3282
3283 /* Calculate the length of the command line */
3284 CmdLineLength = wcslen(lpCommandLine);
3285 CmdLineLength += wcslen(CMD_STRING);
3286 CmdLineLength += CmdQuoteLength + sizeof(ANSI_NULL);
3287 CmdLineLength *= sizeof(WCHAR);
3288
3289 /* Allocate space for the new command line */
3290 AnsiCmdCommand = RtlAllocateHeap(RtlGetProcessHeap(),
3291 0,
3292 CmdLineLength);
3293 if (!AnsiCmdCommand)
3294 {
3296 Result = FALSE;
3297 goto Quickie;
3298 }
3299
3300 /* Build it */
3301 wcscpy(AnsiCmdCommand, CMD_STRING);
3302 if ((CmdLineIsAppName) || (HasQuotes))
3303 {
3304 wcscat(AnsiCmdCommand, L"\"");
3305 }
3306 wcscat(AnsiCmdCommand, lpCommandLine);
3307 if ((CmdLineIsAppName) || (HasQuotes))
3308 {
3309 wcscat(AnsiCmdCommand, L"\"");
3310 }
3311
3312 /* Create it as a Unicode String */
3313 RtlInitUnicodeString(&DebuggerString, AnsiCmdCommand);
3314
3315 /* Set the command line to this */
3316 lpCommandLine = DebuggerString.Buffer;
3317 lpApplicationName = NULL;
3318 DPRINT1("Retrying with: %S\n", lpCommandLine);
3319 }
3320
3321 /* We've already done all these checks, don't do them again */
3322 SkipSaferAndAppCompat = TRUE;
3323 goto AppNameRetry;
3324 }
3325
3327 {
3328 /* 64-bit binaries are not allowed to run on 32-bit ReactOS */
3329 DPRINT1("64-bit binary, failing\n");
3331 Result = FALSE;
3332 goto Quickie;
3333 }
3334
3336 {
3337 /* Set the correct last error for this */
3338 DPRINT1("File is offline, failing\n");
3340 break;
3341 }
3342
3343 default:
3344 {
3345 /* Any other error, convert it to a generic Win32 error */
3346 if (!NT_SUCCESS(Status))
3347 {
3348 DPRINT1("Failed to create section: %lx\n", Status);
3350 Result = FALSE;
3351 goto Quickie;
3352 }
3353
3354 /* Otherwise, this must be success */
3356 break;
3357 }
3358 }
3359
3360 /* Is this not a WOW application, but a WOW32 VDM was requested for it? */
3361 if (!(IsWowApp) && (dwCreationFlags & CREATE_SEPARATE_WOW_VDM))
3362 {
3363 /* Ignore the nonsensical request */
3364 dwCreationFlags &= ~CREATE_SEPARATE_WOW_VDM;
3365 }
3366
3367 /* Did we already check information for the section? */
3368 if (!QuerySection)
3369 {
3370 /* Get some information about the executable */
3371 Status = NtQuerySection(SectionHandle,
3373 &ImageInformation,
3374 sizeof(ImageInformation),
3375 NULL);
3376 if (!NT_SUCCESS(Status))
3377 {
3378 /* We failed, bail out */
3379 DPRINT1("Section query failed\n");
3381 Result = FALSE;
3382 goto Quickie;
3383 }
3384
3385 /* Don't check this later */
3386 QuerySection = TRUE;
3387 }
3388
3389 /* Check if this was linked as a DLL */
3390 if (ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3391 {
3392 /* These aren't valid images to try to execute! */
3393 DPRINT1("Trying to launch a DLL, failing\n");
3395 Result = FALSE;
3396 goto Quickie;
3397 }
3398
3399 /* Don't let callers pass in this flag -- we'll only get it from IFEO */
3400 Flags &= ~PROCESS_CREATE_FLAGS_LARGE_PAGES;
3401
3402 /* Clear the IFEO-missing flag, before we know for sure... */
3403 ParameterFlags &= ~2;
3404
3405 /* If the process is being debugged, only read IFEO if the PEB says so */
3406 if (!(dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) ||
3408 {
3409 /* Let's do this! Attempt to open IFEO */
3410 IFEOStatus = LdrOpenImageFileOptionsKey(&PathName, 0, &KeyHandle);
3411 if (!NT_SUCCESS(IFEOStatus))
3412 {
3413 /* We failed, set the flag so we store this in the parameters */
3414 if (IFEOStatus == STATUS_OBJECT_NAME_NOT_FOUND) ParameterFlags |= 2;
3415 }
3416 else
3417 {
3418 /* Was this our first time going through this path? */
3419 if (!DebuggerCmdLine)
3420 {
3421 /* Allocate a buffer for the debugger path */
3422 DebuggerCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
3423 0,
3424 MAX_PATH * sizeof(WCHAR));
3425 if (!DebuggerCmdLine)
3426 {
3427 /* Close IFEO on failure */
3428 IFEOStatus = NtClose(KeyHandle);
3429 ASSERT(NT_SUCCESS(IFEOStatus));
3430
3431 /* Fail the call */
3433 Result = FALSE;
3434 goto Quickie;
3435 }
3436 }
3437
3438 /* Now query for the debugger */
3440 L"Debugger",
3441 REG_SZ,
3442 DebuggerCmdLine,
3443 MAX_PATH * sizeof(WCHAR),
3444 &ResultSize);
3445 if (!(NT_SUCCESS(IFEOStatus)) ||
3446 (ResultSize < sizeof(WCHAR)) ||
3447 (DebuggerCmdLine[0] == UNICODE_NULL))
3448 {
3449 /* If it's not there, or too small, or invalid, ignore it */
3450 RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
3451 DebuggerCmdLine = NULL;
3452 }
3453
3454 /* Also query if we should map with large pages */
3456 L"UseLargePages",
3457 REG_DWORD,
3458 &UseLargePages,
3459 sizeof(UseLargePages),
3460 NULL);
3461 if ((NT_SUCCESS(IFEOStatus)) && (UseLargePages))
3462 {
3463 /* Do it! This is the only way this flag can be set */
3465 }
3466
3467 /* We're done with IFEO, can close it now */
3468 IFEOStatus = NtClose(KeyHandle);
3469 ASSERT(NT_SUCCESS(IFEOStatus));
3470 }
3471 }
3472
3473 /* Make sure the image was compiled for this processor */
3474 if ((ImageInformation.Machine < SharedUserData->ImageNumberLow) ||
3475 (ImageInformation.Machine > SharedUserData->ImageNumberHigh))
3476 {
3477 /* It was not -- raise a hard error */
3478 ErrorResponse = ResponseOk;
3479 ErrorParameters[0] = (ULONG_PTR)&PathName;
3481 1,
3482 1,
3483 ErrorParameters,
3484 OptionOk,
3485 &ErrorResponse);
3487 {
3488 /* If it's really old, return this error */
3490 }
3491 else
3492 {
3493 /* Otherwise, return a more modern error */
3495 }
3496
3497 /* Go to the failure path */
3498 DPRINT1("Invalid image architecture: %lx\n", ImageInformation.Machine);
3499 Result = FALSE;
3500 goto Quickie;
3501 }
3502
3503 /* Check if this isn't a Windows image */
3504 if ((ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_GUI) &&
3505 (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_CUI))
3506 {
3507 /* Get rid of section-related information since we'll retry */
3508 NtClose(SectionHandle);
3509 SectionHandle = NULL;
3510 QuerySection = FALSE;
3511
3512 /* The only other non-Windows image type we support here is POSIX */
3513 if (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_POSIX_CUI)
3514 {
3515 /* Bail out if it's something else */
3517 Result = FALSE;
3518 goto Quickie;
3519 }
3520
3521 /* Now build the command-line to have posix launch this image */
3522 Result = BuildSubSysCommandLine(L"POSIX /P ",
3523 lpApplicationName,
3524 lpCommandLine,
3525 &DebuggerString);
3526 if (!Result)
3527 {
3528 /* Bail out if that failed */
3529 DPRINT1("Subsystem command line failed\n");
3530 goto Quickie;
3531 }
3532
3533 /* And re-try launching the process, with the new command-line now */
3534 lpCommandLine = DebuggerString.Buffer;
3535 lpApplicationName = NULL;
3536
3537 /* We've already done all these checks, don't do them again */
3538 SkipSaferAndAppCompat = TRUE;
3539 DPRINT1("Retrying with: %S\n", lpCommandLine);
3540 goto AppNameRetry;
3541 }
3542
3543 /* Was this image built for a version of Windows whose images we can run? */
3545 ImageInformation.SubSystemMinorVersion);
3546 if (!Result)
3547 {
3548 /* It was not, bail out */
3549 DPRINT1("Invalid subsystem version: %hu.%hu\n",
3550 ImageInformation.SubSystemMajorVersion,
3551 ImageInformation.SubSystemMinorVersion);
3553 goto Quickie;
3554 }
3555
3556 /* Check if there is a debugger associated with the application */
3557 if (DebuggerCmdLine)
3558 {
3559 /* Get the length of the command line */
3560 n = wcslen(lpCommandLine);
3561 if (!n)
3562 {
3563 /* There's no command line, use the application name instead */
3564 lpCommandLine = (LPWSTR)lpApplicationName;
3565 n = wcslen(lpCommandLine);
3566 }
3567
3568 /* Protect against overflow */
3570 {
3572 Result = FALSE;
3573 goto Quickie;
3574 }
3575
3576 /* Now add the length of the debugger command-line */
3577 n += wcslen(DebuggerCmdLine);
3578
3579 /* Again make sure we don't overflow */
3581 {
3583 Result = FALSE;
3584 goto Quickie;
3585 }
3586
3587 /* Account for the quotes and space between the two */
3588 n += sizeof("\" \"") - sizeof(ANSI_NULL);
3589
3590 /* Convert to bytes, and make sure we don't overflow */
3591 n *= sizeof(WCHAR);
3593 {
3595 Result = FALSE;
3596 goto Quickie;
3597 }
3598
3599 /* Allocate space for the string */
3600 DebuggerString.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, n);
3601 if (!DebuggerString.Buffer)
3602 {
3604 Result = FALSE;
3605 goto Quickie;
3606 }
3607
3608 /* Set the length */
3609 RtlInitEmptyUnicodeString(&DebuggerString,
3610 DebuggerString.Buffer,
3611 (USHORT)n);
3612
3613 /* Now perform the command line creation */
3614 ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString,
3615 DebuggerCmdLine);
3616 ASSERT(NT_SUCCESS(ImageDbgStatus));
3617 ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, L" ");
3618 ASSERT(NT_SUCCESS(ImageDbgStatus));
3619 ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, lpCommandLine);
3620 ASSERT(NT_SUCCESS(ImageDbgStatus));
3621
3622 /* Make sure it all looks nice */
3623 DbgPrint("BASE: Calling debugger with '%wZ'\n", &DebuggerString);
3624
3625 /* Update the command line and application name */
3626 lpCommandLine = DebuggerString.Buffer;
3627 lpApplicationName = NULL;
3628
3629 /* Close all temporary state */
3630 NtClose(SectionHandle);
3631 SectionHandle = NULL;
3632 QuerySection = FALSE;
3633
3634 /* Free all temporary memory */
3635 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
3636 NameBuffer = NULL;
3637 RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
3638 FreeBuffer = NULL;
3639 RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
3640 DebuggerCmdLine = NULL;
3641 DPRINT1("Retrying with: %S\n", lpCommandLine);
3642 goto AppNameRetry;
3643 }
3644
3645 /* Initialize the process object attributes */
3646 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
3647 lpProcessAttributes,
3648 NULL);
3649 if ((hUserToken) && (lpProcessAttributes))
3650 {
3651 /* Augment them with information from the user */
3652
3653 LocalProcessAttributes = *lpProcessAttributes;
3654 LocalProcessAttributes.lpSecurityDescriptor = NULL;
3655 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
3656 &LocalProcessAttributes,
3657 NULL);
3658 }
3659
3660 /* Check if we're going to be debugged */
3661 if (dwCreationFlags & DEBUG_PROCESS)
3662 {
3663 /* Set process flag */
3665 }
3666
3667 /* Check if we're going to be debugged */
3668 if (dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
3669 {
3670 /* Connect to DbgUi */
3672 if (!NT_SUCCESS(Status))
3673 {
3674 DPRINT1("Failed to connect to DbgUI!\n");
3676 Result = FALSE;
3677 goto Quickie;
3678 }
3679
3680 /* Get the debug object */
3681 DebugHandle = DbgUiGetThreadDebugObject();
3682
3683 /* Check if only this process will be debugged */
3684 if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS)
3685 {
3686 /* Set process flag */
3688 }
3689 }
3690
3691 /* Set inherit flag */
3692 if (bInheritHandles) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES;
3693
3694 /* Check if the process should be created with large pages */
3695 HavePrivilege = FALSE;
3696 PrivilegeState = NULL;
3698 {
3699 /* Acquire the required privilege so that the kernel won't fail the call */
3700 PrivilegeValue = SE_LOCK_MEMORY_PRIVILEGE;
3701 Status = RtlAcquirePrivilege(&PrivilegeValue, 1, 0, &PrivilegeState);
3702 if (NT_SUCCESS(Status))
3703 {
3704 /* Remember to release it later */
3705 HavePrivilege = TRUE;
3706 }
3707 }
3708
3709 /* Save the current TIB value since kernel overwrites it to store PEB */
3710 TibValue = Teb->NtTib.ArbitraryUserPointer;
3711
3712 /* Tell the kernel to create the process */
3717 Flags,
3718 SectionHandle,
3719 DebugHandle,
3720 NULL,
3721 InJob);
3722
3723 /* Load the PEB address from the hacky location where the kernel stores it */
3724 RemotePeb = Teb->NtTib.ArbitraryUserPointer;
3725
3726 /* And restore the old TIB value */
3727 Teb->NtTib.ArbitraryUserPointer = TibValue;
3728
3729 /* Release the large page privilege if we had acquired it */
3730 if (HavePrivilege) RtlReleasePrivilege(PrivilegeState);
3731
3732 /* And now check if the kernel failed to create the process */
3733 if (!NT_SUCCESS(Status))
3734 {
3735 /* Go to failure path */
3736 DPRINT1("Failed to create process: %lx\n", Status);
3738 Result = FALSE;
3739 goto Quickie;
3740 }
3741
3742 /* Check if there is a priority class to set */
3743 if (PriorityClass.PriorityClass)
3744 {
3745 /* Reset current privilege state */
3746 RealTimePrivilegeState = NULL;
3747
3748 /* Is realtime priority being requested? */
3750 {
3751 /* Check if the caller has real-time access, and enable it if so */
3752 RealTimePrivilegeState = BasepIsRealtimeAllowed(TRUE);
3753 }
3754
3755 /* Set the new priority class and release the privilege */
3758 &PriorityClass,
3759 sizeof(PROCESS_PRIORITY_CLASS));
3760 if (RealTimePrivilegeState) RtlReleasePrivilege(RealTimePrivilegeState);
3761
3762 /* Check if we failed to set the priority class */
3763 if (!NT_SUCCESS(Status))
3764 {
3765 /* Bail out on failure */
3766 DPRINT1("Failed to set priority class: %lx\n", Status);
3768 Result = FALSE;
3769 goto Quickie;
3770 }
3771 }
3772
3773 /* Check if the caller wants the default error mode */
3774 if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE)
3775 {
3776 /* Set Error Mode to only fail on critical errors */
3777 HardErrorMode = SEM_FAILCRITICALERRORS;
3780 &HardErrorMode,
3781 sizeof(ULONG));
3782 }
3783
3784 /* Check if this was a VDM binary */
3785 if (VdmBinaryType)
3786 {
3787 /* Update VDM by telling it the process has now been created */
3788 VdmWaitObject = ProcessHandle;
3790 &VdmWaitObject,
3791 VdmTask,
3792 VdmBinaryType);
3793
3794 if (!Result)
3795 {
3796 /* Bail out on failure */
3797 DPRINT1("Failed to update VDM with wait object\n");
3798 VdmWaitObject = NULL;
3799 goto Quickie;
3800 }
3801
3802 /* At this point, a failure means VDM has to undo all the state */
3803 VdmUndoLevel |= VDM_UNDO_FULL;
3804 }
3805
3806 /* Check if VDM needed reserved low-memory */
3807 if (VdmReserve)
3808 {
3809 /* Reserve the requested allocation */
3810 RegionSize = VdmReserve;
3812 &BaseAddress,
3813 0,
3814 &RegionSize,
3817 if (!NT_SUCCESS(Status))
3818 {
3819 /* Bail out on failure */
3820 DPRINT1("Failed to reserve memory for VDM: %lx\n", Status);
3822 Result = FALSE;
3823 goto Quickie;
3824 }
3825
3826 VdmReserve = (ULONG)RegionSize;
3827 }
3828
3829 /* Check if we've already queried information on the section */
3830 if (!QuerySection)
3831 {
3832 /* We haven't, so get some information about the executable */
3833 Status = NtQuerySection(SectionHandle,
3835 &ImageInformation,
3836 sizeof(ImageInformation),
3837 NULL);
3838 if (!NT_SUCCESS(Status))
3839 {
3840 /* Bail out on failure */
3841 DPRINT1("Failed to query section: %lx\n", Status);
3843 Result = FALSE;
3844 goto Quickie;
3845 }
3846
3847 /* If we encounter a restart, don't re-query this information again */
3848 QuerySection = TRUE;
3849 }
3850
3851 /* Do we need to apply SxS to this image? (On x86 this flag is set by PeFmtCreateSection) */
3853 {
3854 /* Too bad, we don't support this yet */
3855 DPRINT("Image should receive SxS Fusion Isolation\n");
3856 }
3857
3858 /* There's some SxS flag that we need to set if fusion flags have 1 set */
3859 if (FusionFlags & 1) CreateProcessMsg->Sxs.Flags |= 0x10;
3860
3861 /* Check if we have a current directory */
3862 if (lpCurrentDirectory)
3863 {
3864 /* Allocate a buffer so we can keep a Unicode copy */
3865 DPRINT("Current directory: %S\n", lpCurrentDirectory);
3866 CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(),
3867 0,
3868 (MAX_PATH * sizeof(WCHAR)) +
3869 sizeof(UNICODE_NULL));
3870 if (!CurrentDirectory)
3871 {
3872 /* Bail out if this failed */
3874 Result = FALSE;
3875 goto Quickie;
3876 }
3877
3878 /* Get the length in Unicode */
3879 Length = GetFullPathNameW(lpCurrentDirectory,
3880 MAX_PATH,
3882 &FilePart);
3883 if (Length > MAX_PATH)
3884 {
3885 /* The directory is too long, so bail out */
3887 Result = FALSE;
3888 goto Quickie;
3889 }
3890
3891 /* Make sure the directory is actually valid */
3892 FileAttribs = GetFileAttributesW(CurrentDirectory);
3893 if ((FileAttribs == INVALID_FILE_ATTRIBUTES) ||
3894 !(FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
3895 {
3896 /* It isn't, so bail out */
3897 DPRINT1("Current directory is invalid\n");
3899 Result = FALSE;
3900 goto Quickie;
3901 }
3902 }
3903
3904 /* Insert quotes if needed */
3905 if ((QuotesNeeded) || (CmdLineIsAppName))
3906 {
3907 /* Allocate our buffer, plus enough space for quotes and a NULL */
3908 QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
3909 0,
3910 (wcslen(lpCommandLine) * sizeof(WCHAR)) +
3911 (2 * sizeof(L'\"') + sizeof(UNICODE_NULL)));
3912 if (QuotedCmdLine)
3913 {
3914 /* Copy the first quote */
3915 wcscpy(QuotedCmdLine, L"\"");
3916
3917 /* Save the current null-character */
3918 if (QuotesNeeded)
3919 {
3920 SaveChar = *NullBuffer;
3921 *NullBuffer = UNICODE_NULL;
3922 }
3923
3924 /* Copy the command line and the final quote */
3925 wcscat(QuotedCmdLine, lpCommandLine);
3926 wcscat(QuotedCmdLine, L"\"");
3927
3928 /* Copy the null-char back */
3929 if (QuotesNeeded)
3930 {
3931 *NullBuffer = SaveChar;
3932 wcscat(QuotedCmdLine, NullBuffer);
3933 }
3934 }
3935 else
3936 {
3937 /* We can't put quotes around the thing, so try it anyway */
3938 if (QuotesNeeded) QuotesNeeded = FALSE;
3939 if (CmdLineIsAppName) CmdLineIsAppName = FALSE;
3940 }
3941 }
3942
3943 /* Use isolation if needed */
3944 if (CreateProcessMsg->Sxs.Flags & 1) ParameterFlags |= 1;
3945
3946 /* Set the new command-line if needed */
3947 if ((QuotesNeeded) || (CmdLineIsAppName)) lpCommandLine = QuotedCmdLine;
3948
3949 /* Call the helper function in charge of RTL_USER_PROCESS_PARAMETERS */
3950 Result = BasePushProcessParameters(ParameterFlags,
3952 RemotePeb,
3953 lpApplicationName,
3955 lpCommandLine,
3956 lpEnvironment,
3957 &StartupInfo,
3958 dwCreationFlags | NoWindow,
3959 bInheritHandles,
3960 IsWowApp ? IMAGE_SUBSYSTEM_WINDOWS_GUI: 0,
3961 AppCompatData,
3962 AppCompatDataSize);
3963 if (!Result)
3964 {
3965 /* The remote process would have an undefined state, so fail the call */
3966 DPRINT1("BasePushProcessParameters failed\n");
3967 goto Quickie;
3968 }
3969
3970 /* Free the VDM command line string as it's no longer needed */
3971 RtlFreeUnicodeString(&VdmString);
3972 VdmString.Buffer = NULL;
3973
3974 /* Non-VDM console applications usually inherit handles unless specified */
3975 if (!(VdmBinaryType) &&
3976 !(bInheritHandles) &&
3977 !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
3978 !(dwCreationFlags & (CREATE_NO_WINDOW |
3980 DETACHED_PROCESS)) &&
3981 (ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI))
3982 {
3983 /* Get the remote parameters */
3985 &RemotePeb->ProcessParameters,
3986 &ProcessParameters,
3988 NULL);
3989 if (NT_SUCCESS(Status))
3990 {
3991 /* Duplicate standard input unless it's a console handle */
3993 {
3996 &ProcessParameters->StandardInput);
3997 }
3998
3999 /* Duplicate standard output unless it's a console handle */
4001 {
4004 &ProcessParameters->StandardOutput);
4005 }
4006
4007 /* Duplicate standard error unless it's a console handle */
4009 {
4012 &ProcessParameters->StandardError);
4013 }
4014 }
4015 }
4016
4017 /* Create the Thread's Stack */
4018 StackSize = max(256 * 1024, ImageInformation.MaximumStackSize);
4020 ImageInformation.CommittedStackSize,
4021 StackSize,
4022 &InitialTeb);
4023 if (!NT_SUCCESS(Status))
4024 {
4025 DPRINT1("Creating the thread stack failed: %lx\n", Status);
4027 Result = FALSE;
4028 goto Quickie;
4029 }
4030
4031 /* Create the Thread's Context */
4033 RemotePeb,
4034 ImageInformation.TransferAddress,
4035 InitialTeb.StackBase,
4036 0);
4037
4038 /* Convert the thread attributes */
4039 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
4040 lpThreadAttributes,
4041 NULL);
4042 if ((hUserToken) && (lpThreadAttributes))
4043 {
4044 /* If the caller specified a user token, zero the security descriptor */
4045 LocalThreadAttributes = *lpThreadAttributes;
4046 LocalThreadAttributes.lpSecurityDescriptor = NULL;
4047 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
4048 &LocalThreadAttributes,
4049 NULL);
4050 }
4051
4052 /* Create the Kernel Thread Object */
4053 Status = NtCreateThread(&ThreadHandle,
4057 &ClientId,
4058 &Context,
4059 &InitialTeb,
4060 TRUE);
4061 if (!NT_SUCCESS(Status))
4062 {
4063 /* A process is not allowed to exist without a main thread, so fail */
4064 DPRINT1("Creating the main thread failed: %lx\n", Status);
4066 Result = FALSE;
4067 goto Quickie;
4068 }
4069
4070 /* Begin filling out the CSRSS message, first with our IDs and handles */
4071 CreateProcessMsg->ProcessHandle = ProcessHandle;
4072 CreateProcessMsg->ThreadHandle = ThreadHandle;
4073 CreateProcessMsg->ClientId = ClientId;
4074
4075 /* Write the remote PEB address and clear it locally, we no longer use it */
4076 CreateProcessMsg->PebAddressNative = RemotePeb;
4077#ifdef _WIN64
4078 DPRINT("TODO: WOW64 is not supported yet\n");
4079 CreateProcessMsg->PebAddressWow64 = 0;
4080#else
4081 CreateProcessMsg->PebAddressWow64 = (ULONG)RemotePeb;
4082#endif
4083 RemotePeb = NULL;
4084
4085 /* Now check what kind of architecture this image was made for */
4086 switch (ImageInformation.Machine)
4087 {
4088 /* IA32, IA64 and AMD64 are supported in Server 2003 */
4091 break;
4094 break;
4097 break;
4098
4099 /* Anything else results in image unknown -- but no failure */
4100 default:
4101 DbgPrint("kernel32: No mapping for ImageInformation.Machine == %04x\n",
4102 ImageInformation.Machine);
4104 break;
4105 }
4106
4107 /* Write the input creation flags except any debugger-related flags */
4108 CreateProcessMsg->CreationFlags = dwCreationFlags &
4110
4111 /* CSRSS needs to know if this is a GUI app or not */
4112 if ((ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_GUI) ||
4113 (IsWowApp))
4114 {
4115 /*
4116 * For GUI apps we turn on the 2nd bit. This allow CSRSS server dlls
4117 * (basesrv in particular) to know whether or not this is a GUI or a
4118 * TUI application.
4119 */
4120 AddToHandle(CreateProcessMsg->ProcessHandle, 2);
4121
4122 /* Also check if the parent is also a GUI process */
4124 if ((NtHeaders) &&
4126 {
4127 /* Let it know that it should display the hourglass mouse cursor */
4128 AddToHandle(CreateProcessMsg->ProcessHandle, 1);
4129 }
4130 }
4131
4132 /* For all apps, if this flag is on, the hourglass mouse cursor is shown.
4133 * Likewise, the opposite holds as well, and no-feedback has precedence. */
4134 if (StartupInfo.dwFlags & STARTF_FORCEONFEEDBACK)
4135 {
4136 AddToHandle(CreateProcessMsg->ProcessHandle, 1);
4137 }
4138 if (StartupInfo.dwFlags & STARTF_FORCEOFFFEEDBACK)
4139 {
4140 RemoveFromHandle(CreateProcessMsg->ProcessHandle, 1);
4141 }
4142
4143 /* Also store which kind of VDM app (if any) this is */
4144 CreateProcessMsg->VdmBinaryType = VdmBinaryType;
4145
4146 /* And if it really is a VDM app... */
4147 if (VdmBinaryType)
4148 {
4149 /* Store the VDM console handle (none if inherited or WOW app) and the task ID */
4150 CreateProcessMsg->hVDM = VdmTask ? NULL : Peb->ProcessParameters->ConsoleHandle;
4151 CreateProcessMsg->VdmTask = VdmTask;
4152 }
4153 else if (VdmReserve)
4154 {
4155 /* Extended VDM, set a flag */
4156 CreateProcessMsg->VdmBinaryType |= BINARY_TYPE_WOW_EX;
4157 }
4158
4159 /* Check if there's side-by-side assembly data associated with the process */
4160 if (CreateProcessMsg->Sxs.Flags)
4161 {
4162 /* This should not happen in ReactOS yet */
4163 DPRINT1("This is an SxS Message -- should not happen yet\n");
4166 Result = FALSE;
4167 goto Quickie;
4168 }
4169
4170 /* We are finally ready to call CSRSS to tell it about our new process! */
4172 CaptureBuffer,
4175 sizeof(*CreateProcessMsg));
4176
4177 /* CSRSS has returned, free the capture buffer now if we had one */
4178 if (CaptureBuffer)
4179 {
4180 CsrFreeCaptureBuffer(CaptureBuffer);
4181 CaptureBuffer = NULL;
4182 }
4183
4184 /* Check if CSRSS failed to accept ownership of the new Windows process */
4185 if (!NT_SUCCESS(CsrMsg[0].Status))
4186 {
4187 /* Terminate the process and enter failure path with the CSRSS status */
4188 DPRINT1("Failed to tell csrss about new process\n");
4189 BaseSetLastNTError(CsrMsg[0].Status);
4191 Result = FALSE;
4192 goto Quickie;
4193 }
4194
4195 /* Check if we have a token due to Authz/Safer, not passed by the user */
4196 if ((TokenHandle) && !(hUserToken))
4197 {
4198 /* Replace the process and/or thread token with the one from Safer */
4201 ThreadHandle);
4202 if (!NT_SUCCESS(Status))
4203 {
4204 /* If this failed, kill the process and enter the failure path */
4205 DPRINT1("Failed to update process token: %lx\n", Status);
4208 Result = FALSE;
4209 goto Quickie;
4210 }
4211 }
4212
4213 /* Check if a job was associated with this process */
4214 if (JobHandle)
4215 {
4216 /* Bind the process and job together now */
4218 if (!NT_SUCCESS(Status))
4219 {
4220 /* Kill the process and enter the failure path if binding failed */
4221 DPRINT1("Failed to assign process to job: %lx\n", Status);
4224 Result = FALSE;
4225 goto Quickie;
4226 }
4227 }
4228
4229 /* Finally, resume the thread to actually get the process started */
4230 if (!(dwCreationFlags & CREATE_SUSPENDED))
4231 {
4232 NtResumeThread(ThreadHandle, &ResumeCount);
4233 }
4234
4235VdmShortCircuit:
4236 /* We made it this far, meaning we have a fully created process and thread */
4237 Result = TRUE;
4238
4239 /* Anyone doing a VDM undo should now undo everything, since we are done */
4240 if (VdmUndoLevel) VdmUndoLevel |= VDM_UNDO_COMPLETED;
4241
4242 /* Having a VDM wait object implies this must be a VDM process */
4243 if (VdmWaitObject)
4244 {
4245 /* Check if it's a 16-bit separate WOW process */
4246 if (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW)
4247 {
4248 /* OR-in the special flag to indicate this, and return to caller */
4249 AddToHandle(VdmWaitObject, 2);
4250 lpProcessInformation->hProcess = VdmWaitObject;
4251
4252 /* Check if this was a re-used VDM */
4253 if (VdmUndoLevel & VDM_UNDO_REUSE)
4254 {
4255 /* No Client ID should be returned in this case */
4258 }
4259 }
4260 else
4261 {
4262 /* OR-in the special flag to indicate this is not a separate VDM,
4263 * and return the handle to the caller */
4264 AddToHandle(VdmWaitObject, 1);
4265 lpProcessInformation->hProcess = VdmWaitObject;
4266 }
4267
4268 /* Close the original process handle, since it's not needed for VDM */
4270 }
4271 else
4272 {
4273 /* This is a regular process, so return the real process handle */
4274 lpProcessInformation->hProcess = ProcessHandle;
4275 }
4276
4277 /* Return the rest of the process information based on what we have so far */
4278 lpProcessInformation->hThread = ThreadHandle;
4279 lpProcessInformation->dwProcessId = HandleToUlong(ClientId.UniqueProcess);
4280 lpProcessInformation->dwThreadId = HandleToUlong(ClientId.UniqueThread);
4281
4282 /* NULL these out here so we know to treat this as a success scenario */
4284 ThreadHandle = NULL;
4285
4286Quickie:
4287 /* Free the debugger command line if one was allocated */
4288 if (DebuggerCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
4289
4290 /* Check if an SxS full path as queried */
4291 if (PathBuffer)
4292 {
4293 /* Reinitialize the executable path */
4294 RtlInitEmptyUnicodeString(&SxsWin32ExePath, NULL, 0);
4295 SxsWin32ExePath.Length = 0;
4296
4297 /* Free the path buffer */
4298 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
4299 }
4300
4301#if _SXS_SUPPORT_ENABLED_
4302 /* Check if this was a non-VDM process */
4303 if (!VdmBinaryType)
4304 {
4305 /* Then it must've had SxS data, so close the handles used for it */
4306 BasepSxsCloseHandles(&Handles);
4307 BasepSxsCloseHandles(&FileHandles);
4308
4309 /* Check if we built SxS byte buffers for this create process request */
4310 if (SxsConglomeratedBuffer)
4311 {
4312 /* Loop all of them */
4313 for (i = 0; i < 5; i++)
4314 {
4315 /* Check if this one was allocated */
4316 ThisBuffer = SxsStaticBuffers[i];
4317 if (ThisBuffer)
4318 {
4319 /* Get the underlying RTL_BUFFER structure */
4320 ByteBuffer = &ThisBuffer->ByteBuffer;
4321 if ((ThisBuffer != (PVOID)-8) && (ByteBuffer->Buffer))
4322 {
4323 /* Check if it was dynamic */
4324 if (ByteBuffer->Buffer != ByteBuffer->StaticBuffer)
4325 {
4326 /* Free it from the heap */
4327 FreeString.Buffer = (PWCHAR)ByteBuffer->Buffer;
4329 }
4330
4331 /* Reset the buffer to its static data */
4332 ByteBuffer->Buffer = ByteBuffer->StaticBuffer;
4333 ByteBuffer->Size = ByteBuffer->StaticSize;
4334 }
4335
4336 /* Reset the string to the static buffer */
4337 RtlInitEmptyUnicodeString(&ThisBuffer->String,
4338 (PWCHAR)ByteBuffer->StaticBuffer,
4339 ByteBuffer->StaticSize);
4340 if (ThisBuffer->String.Buffer)
4341 {
4342 /* Also NULL-terminate it */
4343 *ThisBuffer->String.Buffer = UNICODE_NULL;
4344 }
4345 }
4346 }
4347 }
4348 }
4349#endif
4350 /* Check if an environment was passed in */
4351 if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
4352 {
4353 /* Destroy it */
4354 RtlDestroyEnvironment(lpEnvironment);
4355
4356 /* If this was the VDM environment too, clear that as well */
4357 if (VdmUnicodeEnv.Buffer == lpEnvironment) VdmUnicodeEnv.Buffer = NULL;
4358 lpEnvironment = NULL;
4359 }
4360
4361 /* Unconditionally free all the name parsing buffers we always allocate */
4362 RtlFreeHeap(RtlGetProcessHeap(), 0, QuotedCmdLine);
4363 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
4364 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDirectory);
4365 RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
4366
4367 /* Close open file/section handles */
4369 if (SectionHandle) NtClose(SectionHandle);
4370
4371 /* If we have a thread handle, this was a failure path */
4372 if (ThreadHandle)
4373 {
4374 /* So kill the process and close the thread handle */
4376 NtClose(ThreadHandle);
4377 }
4378
4379 /* If we have a process handle, this was a failure path, so close it */
4381
4382 /* Thread/process handles, if any, are now processed. Now close this one. */
4383 if (JobHandle) NtClose(JobHandle);
4384
4385 /* Check if we had created a token */
4386 if (TokenHandle)
4387 {
4388 /* And if the user asked for one */
4389 if (hUserToken)
4390 {
4391 /* Then return it */
4392 *hNewToken = TokenHandle;
4393 }
4394 else
4395 {
4396 /* User didn't want it, so we used it temporarily -- close it */
4398 }
4399 }
4400
4401 /* Free any temporary app compatibility data, it's no longer needed */
4402 BasepFreeAppCompatData(AppCompatData, AppCompatSxsData);
4403
4404 /* Free a few strings. The API takes care of these possibly being NULL */
4405 RtlFreeUnicodeString(&VdmString);
4406 RtlFreeUnicodeString(&DebuggerString);
4407
4408 /* Check if we had built any sort of VDM environment */
4409 if ((VdmAnsiEnv.Buffer) || (VdmUnicodeEnv.Buffer))
4410 {
4411 /* Free it */
4412 BaseDestroyVDMEnvironment(&VdmAnsiEnv, &VdmUnicodeEnv);
4413 }
4414
4415 /* Check if this was any kind of VDM application that we ended up creating */
4416 if ((VdmUndoLevel) && (!(VdmUndoLevel & VDM_UNDO_COMPLETED)))
4417 {
4418 /* Send an undo */
4420 (PHANDLE)&VdmTask,
4421 VdmUndoLevel,
4422 VdmBinaryType);
4423
4424 /* And close whatever VDM handle we were using for notifications */
4425 if (VdmWaitObject) NtClose(VdmWaitObject);
4426 }
4427
4428 /* Check if we ended up here with an allocated search path, and free it */
4429 if (SearchPath) RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
4430
4431 /* Finally, return the API's result */
4432 return Result;
4433}
4434
4435/*
4436 * @implemented
4437 */
4438BOOL
4439WINAPI
4441CreateProcessW(LPCWSTR lpApplicationName,
4442 LPWSTR lpCommandLine,
4443 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4444 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4445 BOOL bInheritHandles,
4446 DWORD dwCreationFlags,
4447 LPVOID lpEnvironment,
4448 LPCWSTR lpCurrentDirectory,
4449 LPSTARTUPINFOW lpStartupInfo,
4450 LPPROCESS_INFORMATION lpProcessInformation)
4451{
4452 /* Call the internal (but exported) version */
4454 lpApplicationName,
4455 lpCommandLine,
4456 lpProcessAttributes,
4457 lpThreadAttributes,
4458 bInheritHandles,
4459 dwCreationFlags,
4460 lpEnvironment,
4461 lpCurrentDirectory,
4462 lpStartupInfo,
4463 lpProcessInformation,
4464 NULL);
4465}
4466
4467/* EOF */
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3491
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:3083
#define NtCurrentPeb()
Definition: FLS.c:22
static IN ULONG IN PWSTR OUT PCWSTR OUT PBOOLEAN OUT PATH_TYPE_AND_UNKNOWN * PathType
static ULONG StackSize
Definition: StackOverflow.c:21
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:240
unsigned char BOOLEAN
Definition: actypes.h:127
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
#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
static CHAR Desktop[MAX_PATH]
Definition: dem.c:256
#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
#define RTL_CONSTANT_STRING(s)
Definition: combase.c:35
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:636
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:2232
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:1905
VOID WINAPI FatalAppExitA(UINT uAction, LPCSTR lpMessageText)
Definition: proc.c:1405
VOID WINAPI FatalExit(IN int ExitCode)
Definition: proc.c:1467
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:482
NTSTATUS NTAPI BasepConfigureAppCertDlls(IN PWSTR ValueName, IN ULONG ValueType, IN PVOID ValueData, IN ULONG ValueLength, IN PVOID Context, IN PVOID EntryContext)
Definition: proc.c:187
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:2083
BOOL WINAPI FlushInstructionCache(IN HANDLE hProcess, IN LPCVOID lpBaseAddress, IN SIZE_T nSize)
Definition: proc.c:1306
BOOL WINAPI GetProcessWorkingSetSizeEx(IN HANDLE hProcess, OUT PSIZE_T lpMinimumWorkingSetSize, OUT PSIZE_T lpMaximumWorkingSetSize, OUT PDWORD Flags)
Definition: proc.c:975
NTSTATUS WINAPI BasepCheckWebBladeHashes(IN HANDLE FileHandle)
Definition: proc.c:147
PBASEP_APPCERT_EMBEDDED_FUNC fEmbeddedCertFunc
Definition: proc.c:28
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:4441
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1165
RTL_QUERY_REGISTRY_TABLE BasepAppCertTable[2]
Definition: proc.c:30
UNICODE_STRING BasePathVariableName
Definition: proc.c:22
VOID WINAPI ExitProcess(IN UINT uExitCode)
Definition: proc.c:1330
VOID WINAPI StuffStdHandle(IN HANDLE ProcessHandle, IN HANDLE StandardHandle, IN PHANDLE Address)
Definition: proc.c:55
RTL_CRITICAL_SECTION gcsAppCert
Definition: proc.c:27
BOOLEAN WINAPI BuildSubSysCommandLine(IN LPCWSTR SubsystemName, IN LPCWSTR ApplicationName, IN LPCWSTR CommandLine, OUT PUNICODE_STRING SubsysCommandLine)
Definition: proc.c:87
DWORD WINAPI GetProcessVersion(IN DWORD ProcessId)
Definition: proc.c:1609
LIST_ENTRY BasepAppCertDllsList
Definition: proc.c:26
UNICODE_STRING BaseUnicodeCommandLine
Definition: proc.c:20
BOOLEAN g_AppCertInitialized
Definition: proc.c:24
BOOL WINAPI TerminateProcess(IN HANDLE hProcess, IN UINT uExitCode)
Definition: proc.c:1375
NTSTATUS WINAPI BasepIsProcessAllowed(IN LPWSTR ApplicationName)
Definition: proc.c:200
ANSI_STRING BaseAnsiCommandLine
Definition: proc.c:21
#define AddToHandle(x, y)
Definition: proc.c:2074
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1224
BOOL WINAPI GetProcessPriorityBoost(IN HANDLE hProcess, OUT PBOOL pDisablePriorityBoost)
Definition: proc.c:1737
BOOL WINAPI GetProcessTimes(IN HANDLE hProcess, IN LPFILETIME lpCreationTime, IN LPFILETIME lpExitTime, IN LPFILETIME lpKernelTime, IN LPFILETIME lpUserTime)
Definition: proc.c:1096
BOOLEAN g_HaveAppCerts
Definition: proc.c:25
PLDR_DATA_TABLE_ENTRY BasepExeLdrEntry
Definition: proc.c:23
BOOL WINAPI SetProcessWorkingSetSizeEx(IN HANDLE hProcess, IN SIZE_T dwMinimumWorkingSetSize, IN SIZE_T dwMaximumWorkingSetSize, IN DWORD Flags)
Definition: proc.c:1024
NTSTATUS WINAPI BasepReplaceProcessThreadTokens(IN HANDLE TokenHandle, IN HANDLE ProcessHandle, IN HANDLE ThreadHandle)
Definition: proc.c:352
BOOL WINAPI SetProcessWorkingSetSize(IN HANDLE hProcess, IN SIZE_T dwMinimumWorkingSetSize, IN SIZE_T dwMaximumWorkingSetSize)
Definition: proc.c:1080
BOOL WINAPI GetProcessHandleCount(IN HANDLE hProcess, OUT PDWORD pdwHandleCount)
Definition: proc.c:1794
BOOL WINAPI SetProcessShutdownParameters(IN DWORD dwLevel, IN DWORD dwFlags)
Definition: proc.c:946
HMODULE gSaferHandle
Definition: proc.c:44
NTSTATUS g_AppCertStatus
Definition: proc.c:29
BOOL WINAPI ProcessIdToSessionId(IN DWORD dwProcessId, OUT PDWORD pSessionId)
Definition: proc.c:2024
VOID WINAPI RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle)
DWORD WINAPI GetPriorityClass(IN HANDLE hProcess)
Definition: proc.c:1506
DECLSPEC_NORETURN VOID WINAPI BaseProcessStartup(_In_ PPROCESS_START_ROUTINE lpStartAddress)
Definition: proc.c:449
BOOL WINAPI GetProcessIoCounters(IN HANDLE hProcess, OUT PIO_COUNTERS lpIoCounters)
Definition: proc.c:1710
VOID WINAPI FatalAppExitW(IN UINT uAction, IN LPCWSTR lpMessageText)
Definition: proc.c:1429
BOOL WINAPI SetProcessPriorityBoost(IN HANDLE hProcess, IN BOOL bDisablePriorityBoost)
Definition: proc.c:1766
VOID WINAPI InitCommandLines(VOID)
Definition: proc.c:839
BOOL WINAPI GetProcessWorkingSetSize(IN HANDLE hProcess, OUT PSIZE_T lpMinimumWorkingSetSize, OUT PSIZE_T lpMaximumWorkingSetSize)
Definition: proc.c:1008
PSAFER_REPLACE_PROCESS_THREAD_TOKENS g_SaferReplaceProcessThreadTokens
Definition: proc.c:43
BOOL WINAPI SetPriorityClass(IN HANDLE hProcess, IN DWORD dwPriorityClass)
Definition: proc.c:1541
VOID WINAPI GetStartupInfoW(IN LPSTARTUPINFOW lpStartupInfo)
Definition: proc.c:1265
BOOL WINAPI GetProcessShutdownParameters(OUT LPDWORD lpdwLevel, OUT LPDWORD lpdwFlags)
Definition: proc.c:917
VOID WINAPI BasepSxsCloseHandles(IN PBASE_MSG_SXS_HANDLES Handles)
Definition: proc.c:415
#define CMD_STRING
Definition: proc.c:49
#define RemoveFromHandle(x, y)
Definition: proc.c:2075
BOOL WINAPI SetProcessAffinityMask(IN HANDLE hProcess, IN DWORD_PTR dwProcessAffinityMask)
Definition: proc.c:891
BOOLEAN WINAPI BasepIsImageVersionOk(IN ULONG ImageMajorVersion, IN ULONG ImageMinorVersion)
Definition: proc.c:121
NTSTATUS NTAPI BasepSaveAppCertRegistryValue(IN PLIST_ENTRY List, IN PWCHAR ComponentName, IN PWCHAR DllName)
Definition: proc.c:176
BOOL WINAPI GetProcessAffinityMask(IN HANDLE hProcess, OUT PDWORD_PTR lpProcessAffinityMask, OUT PDWORD_PTR lpSystemAffinityMask)
Definition: proc.c:860
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:355
VOID WINAPI BaseInitializeContext(IN PCONTEXT Context, IN PVOID Parameter, IN PVOID StartAddress, IN PVOID StackAddress, IN ULONG ContextType)
Definition: utils.c:514
POBJECT_ATTRIBUTES WINAPI BaseFormatObjectAttributes(OUT POBJECT_ATTRIBUTES ObjectAttributes, IN PSECURITY_ATTRIBUTES SecurityAttributes OPTIONAL, IN PUNICODE_STRING ObjectName)
Definition: utils.c:305
NTSTATUS WINAPI BasepCheckWinSaferRestrictions(IN HANDLE UserToken, IN LPWSTR ApplicationName, IN HANDLE FileHandle, OUT PBOOLEAN InJob, OUT PHANDLE NewToken, OUT PHANDLE JobHandle)
Definition: utils.c:922
PVOID WINAPI BasepIsRealtimeAllowed(IN BOOLEAN Keep)
Definition: utils.c:666
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
#define DECLSPEC_ALIGN(x)
Definition: corecrt.h:141
#define DECLSPEC_NORETURN
Definition: corecrt.h:131
_ACRTIMP size_t __cdecl wcslen(const wchar_t *)
Definition: wcs.c:2983
_ACRTIMP int __cdecl _wcsnicmp(const wchar_t *, const wchar_t *, size_t)
Definition: wcs.c:195
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:24
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
#define PROCESS_VM_READ
Definition: pstypes.h:157
#define PROCESS_CREATE_FLAGS_BREAKAWAY
Definition: pstypes.h:87
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:162
#define PROCESS_PRIORITY_CLASS_IDLE
Definition: pstypes.h:103
#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES
Definition: pstypes.h:89
#define PROCESS_PRIORITY_CLASS_INVALID
Definition: pstypes.h:102
#define PROCESS_PRIORITY_CLASS_NORMAL
Definition: pstypes.h:104
#define PROCESS_PRIORITY_CLASS_HIGH
Definition: pstypes.h:105
#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
Definition: pstypes.h:108
#define PROCESS_CREATE_FLAGS_LARGE_PAGES
Definition: pstypes.h:91
#define PROCESS_PRIORITY_CLASS_BELOW_NORMAL
Definition: pstypes.h:107
#define PROCESS_PRIORITY_CLASS_REALTIME
Definition: pstypes.h:106
#define FLG_DISABLE_DEBUG_PROMPTS
Definition: pstypes.h:81
#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT
Definition: pstypes.h:88
#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:188
NTSTATUS NTAPI LdrOpenImageFileOptionsKey(_In_ PUNICODE_STRING SubKey, _In_ BOOLEAN Wow64, _Out_ PHANDLE NewKeyHandle)
Definition: ldrinit.c:115
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:568
#define SE_LOCK_MEMORY_PRIVILEGE
Definition: security.c:558
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:115
DWORD e_lfanew
Definition: crypt.c:1299
#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 _Pre_valid_ 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)
Definition: env.c:116
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:279
_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:3950
#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 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 UNICODE_NULL
#define UNICODE_STRING_MAX_CHARS
#define UNICODE_STRING_MAX_BYTES
#define VER_SUITE_DATACENTER
#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:100
static BOOL bInheritHandle
Definition: pipe.c:110
#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:1390
NTSTATUS NTAPI NtSetInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength)
Definition: query.c:2269
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
short WCHAR
Definition: pedump.c:58
DWORD * PDWORD
Definition: pedump.c:68
#define IMAGE_FILE_DLL
Definition: pedump.c:169
unsigned short USHORT
Definition: pedump.c:61
char CHAR
Definition: pedump.c:57
static WCHAR Address[46]
Definition: ping.c:68
struct _STARTUPINFOW STARTUPINFOW
_In_ DWORD dwProcessId
Definition: shlwapi.h:193
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:204
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:104
#define _SEH2_FINALLY
Definition: pseh2_64.h:153
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:203
#define _SEH2_END
Definition: pseh2_64.h:194
#define _SEH2_TRY
Definition: pseh2_64.h:93
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:207
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
#define REG_DWORD
Definition: sdbapi.c:615
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
wcscat
wcscpy
#define SharedUserData
Entry
Definition: section.c:5216
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:3812
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
_In_ PVOID Context
Definition: storport.h:2269
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
union _BASE_API_MESSAGE::@3833 Data
BASE_CHECK_VDM CheckVDMRequest
Definition: basemsg.h:287
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:728
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:1895
PUCHAR StaticBuffer
Definition: rtltypes.h:1893
PUCHAR Buffer
Definition: rtltypes.h:1892
SIZE_T Size
Definition: rtltypes.h:1894
UNICODE_STRING RelativeName
Definition: rtltypes.h:1374
HANDLE ContainingDirectory
Definition: rtltypes.h:1375
UNICODE_STRING String
Definition: rtltypes.h:1902
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
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
uint16_t * PWSTR
Definition: typedefs.h:56
const char * LPCSTR
Definition: typedefs.h:52
uint32_t * PULONG_PTR
Definition: typedefs.h:65
const uint16_t * LPCWSTR
Definition: typedefs.h:57
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
uint16_t * LPWSTR
Definition: typedefs.h:56
#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
char * LPSTR
Definition: typedefs.h:51
#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
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::@2505 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
WDF_EXTERN_C_START typedef _Must_inspect_result_ _In_opt_ PCUNICODE_STRING UnicodeString
Definition: wdfstring.h:64
#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:1145
#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:1155
#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
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:954
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:5372
NTSYSAPI ULONG WINAPI RtlGetNtGlobalFlags(void)
Definition: libsupp.c:95
#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_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