ReactOS 0.4.16-dev-2284-g3529151
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 ASSERT(ProcessParameters->Environment == lpEnvironment);
613 lpEnvironment = ProcessParameters->Environment;
614 }
615 else
616 {
617 /* The user did not, so use the one from the current PEB */
618 HavePebLock = TRUE;
620 lpEnvironment = Peb->ProcessParameters->Environment;
621 }
622
623 /* Save pointer and start lookup */
624 ScanChar = lpEnvironment;
625 if (lpEnvironment)
626 {
627 /* Find the environment size */
628 while (*ScanChar++) while (*ScanChar++);
629 EnviroSize = (ULONG)((ULONG_PTR)ScanChar - (ULONG_PTR)lpEnvironment);
630
631 /* Allocate and Initialize new Environment Block */
632 Size = EnviroSize;
633 ProcessParameters->Environment = NULL;
635 (PVOID*)&ProcessParameters->Environment,
636 0,
637 &Size,
640 if (!NT_SUCCESS(Status)) goto FailPath;
641
642 /* Write the Environment Block */
644 ProcessParameters->Environment,
645 lpEnvironment,
646 EnviroSize,
647 NULL);
648
649 /* No longer need the PEB lock anymore */
650 if (HavePebLock)
651 {
652 /* Release it */
654 HavePebLock = FALSE;
655 }
656
657 /* Check if the write failed */
658 if (!NT_SUCCESS(Status)) goto FailPath;
659 }
660
661 /* Write new parameters */
662 ProcessParameters->StartingX = StartupInfo->dwX;
663 ProcessParameters->StartingY = StartupInfo->dwY;
664 ProcessParameters->CountX = StartupInfo->dwXSize;
665 ProcessParameters->CountY = StartupInfo->dwYSize;
666 ProcessParameters->CountCharsX = StartupInfo->dwXCountChars;
667 ProcessParameters->CountCharsY = StartupInfo->dwYCountChars;
668 ProcessParameters->FillAttribute = StartupInfo->dwFillAttribute;
669 ProcessParameters->WindowFlags = StartupInfo->dwFlags;
670 ProcessParameters->ShowWindowFlags = StartupInfo->wShowWindow;
671
672 /* Write the handles only if we have to */
673 if (StartupInfo->dwFlags &
674 (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE))
675 {
676 ProcessParameters->StandardInput = StartupInfo->hStdInput;
677 ProcessParameters->StandardOutput = StartupInfo->hStdOutput;
678 ProcessParameters->StandardError = StartupInfo->hStdError;
679 }
680
681 /* Use Special Flags for ConDllInitialize in Kernel32 */
682 if (CreationFlags & DETACHED_PROCESS)
683 {
684 ProcessParameters->ConsoleHandle = HANDLE_DETACHED_PROCESS;
685 }
686 else if (CreationFlags & CREATE_NEW_CONSOLE)
687 {
688 ProcessParameters->ConsoleHandle = HANDLE_CREATE_NEW_CONSOLE;
689 }
690 else if (CreationFlags & CREATE_NO_WINDOW)
691 {
692 ProcessParameters->ConsoleHandle = HANDLE_CREATE_NO_WINDOW;
693 }
694 else
695 {
696 /* Inherit our Console Handle */
697 ProcessParameters->ConsoleHandle = Peb->ProcessParameters->ConsoleHandle;
698
699 /* Make sure that the shell isn't trampling on our handles first */
700 if (!(StartupInfo->dwFlags &
701 (STARTF_USESTDHANDLES | STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
702 {
703 /* Copy the handle if we are inheriting or if it's a console handle */
704 if ((InheritHandles) ||
706 {
707 ProcessParameters->StandardInput = Peb->ProcessParameters->StandardInput;
708 }
709 if ((InheritHandles) ||
711 {
712 ProcessParameters->StandardOutput = Peb->ProcessParameters->StandardOutput;
713 }
714 if ((InheritHandles) ||
716 {
717 ProcessParameters->StandardError = Peb->ProcessParameters->StandardError;
718 }
719 }
720 }
721
722 /* Also set the Console Flag */
723 if ((CreationFlags & CREATE_NEW_PROCESS_GROUP) &&
724 (!(CreationFlags & CREATE_NEW_CONSOLE)))
725 {
726 ProcessParameters->ConsoleFlags = 1;
727 }
728
729 /* Check if there's a .local file present */
730 if (ParameterFlags & 1)
731 {
733 }
734
735 /* Check if we failed to open the IFEO key */
736 if (ParameterFlags & 2)
737 {
739 }
740
741 /* Allocate memory for the parameter block */
742 Size = ProcessParameters->Length;
743 RemoteParameters = NULL;
745 (PVOID*)&RemoteParameters,
746 0,
747 &Size,
750 if (!NT_SUCCESS(Status)) goto FailPath;
751
752 /* Set the allocated size */
753 ProcessParameters->MaximumLength = Size;
754
755 /* Handle some Parameter Flags */
756 ProcessParameters->Flags |= (CreationFlags & PROFILE_USER) ?
758 ProcessParameters->Flags |= (CreationFlags & PROFILE_KERNEL) ?
760 ProcessParameters->Flags |= (CreationFlags & PROFILE_SERVER) ?
762 ProcessParameters->Flags |= (Peb->ProcessParameters->Flags &
764
765 /* Write the Parameter Block */
767 RemoteParameters,
768 ProcessParameters,
769 ProcessParameters->Length,
770 NULL);
771 if (!NT_SUCCESS(Status)) goto FailPath;
772
773 /* Write the PEB Pointer */
775 &RemotePeb->ProcessParameters,
776 &RemoteParameters,
777 sizeof(PVOID),
778 NULL);
779 if (!NT_SUCCESS(Status)) goto FailPath;
780
781 /* Check if there's any app compat data to write */
782 RemoteAppCompatData = NULL;
783 if (AppCompatData)
784 {
785 /* Allocate some space for the application compatibility data */
786 Size = AppCompatDataSize;
788 &RemoteAppCompatData,
789 0,
790 &Size,
793 if (!NT_SUCCESS(Status)) goto FailPath;
794
795 /* Write the application compatibility data */
797 RemoteAppCompatData,
798 AppCompatData,
799 AppCompatDataSize,
800 NULL);
801 if (!NT_SUCCESS(Status)) goto FailPath;
802 }
803
804 /* Write the PEB Pointer to the app compat data (might be NULL) */
806 &RemotePeb->pShimData,
807 &RemoteAppCompatData,
808 sizeof(PVOID),
809 NULL);
810 if (!NT_SUCCESS(Status)) goto FailPath;
811
812 /* Now write Peb->ImageSubSystem */
813 if (ImageSubsystem)
814 {
816 &RemotePeb->ImageSubsystem,
817 &ImageSubsystem,
818 sizeof(ImageSubsystem),
819 NULL);
820 }
821
822 /* Success path */
823 Result = TRUE;
824
825Quickie:
826 /* Cleanup */
827 if (HavePebLock) RtlReleasePebLock();
828 RtlFreeHeap(RtlGetProcessHeap(), 0, DllPath.Buffer);
829 if (ProcessParameters) RtlDestroyProcessParameters(ProcessParameters);
830 return Result;
831FailPath:
832 DPRINT1("Failure to create process parameters: %lx\n", Status);
834 Result = FALSE;
835 goto Quickie;
836}
837
838VOID
839WINAPI
841{
843
844 /* Read the UNICODE_STRING from the PEB */
845 BaseUnicodeCommandLine = NtCurrentPeb()->ProcessParameters->CommandLine;
846
847 /* Convert to ANSI_STRING for the *A callers */
850 TRUE);
851 if (!NT_SUCCESS(Status)) RtlInitEmptyAnsiString(&BaseAnsiCommandLine, 0, 0);
852}
853
854/* PUBLIC FUNCTIONS ***********************************************************/
855
856/*
857 * @implemented
858 */
859BOOL
860WINAPI
862 OUT PDWORD_PTR lpProcessAffinityMask,
863 OUT PDWORD_PTR lpSystemAffinityMask)
864{
865 PROCESS_BASIC_INFORMATION ProcessInfo;
867
868 /* Query information on the process from the kernel */
871 &ProcessInfo,
872 sizeof(ProcessInfo),
873 NULL);
874 if (!NT_SUCCESS(Status))
875 {
876 /* Fail */
878 return FALSE;
879 }
880
881 /* Copy the affinity mask, and get the system one from our shared data */
882 *lpProcessAffinityMask = (DWORD)ProcessInfo.AffinityMask;
884 return TRUE;
885}
886
887/*
888 * @implemented
889 */
890BOOL
891WINAPI
893 IN DWORD_PTR dwProcessAffinityMask)
894{
896
897 /* Directly set the affinity mask */
900 (PVOID)&dwProcessAffinityMask,
901 sizeof(dwProcessAffinityMask));
902 if (!NT_SUCCESS(Status))
903 {
904 /* Handle failure */
906 return FALSE;
907 }
908
909 /* Everything was ok */
910 return TRUE;
911}
912
913/*
914 * @implemented
915 */
916BOOL
917WINAPI
919 OUT LPDWORD lpdwFlags)
920{
921 BASE_API_MESSAGE ApiMessage;
922 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &ApiMessage.Data.ShutdownParametersRequest;
923
924 /* Ask CSRSS for shutdown information */
926 NULL,
928 sizeof(*ShutdownParametersRequest));
929 if (!NT_SUCCESS(ApiMessage.Status))
930 {
931 /* Return the failure from CSRSS */
932 BaseSetLastNTError(ApiMessage.Status);
933 return FALSE;
934 }
935
936 /* Get the data back */
937 *lpdwLevel = ShutdownParametersRequest->ShutdownLevel;
938 *lpdwFlags = ShutdownParametersRequest->ShutdownFlags;
939 return TRUE;
940}
941
942/*
943 * @implemented
944 */
945BOOL
946WINAPI
949{
950 BASE_API_MESSAGE ApiMessage;
951 PBASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest = &ApiMessage.Data.ShutdownParametersRequest;
952
953 /* Write the data into the CSRSS request and send it */
954 ShutdownParametersRequest->ShutdownLevel = dwLevel;
955 ShutdownParametersRequest->ShutdownFlags = dwFlags;
957 NULL,
959 sizeof(*ShutdownParametersRequest));
960 if (!NT_SUCCESS(ApiMessage.Status))
961 {
962 /* Return the failure from CSRSS */
963 BaseSetLastNTError(ApiMessage.Status);
964 return FALSE;
965 }
966
967 /* All went well */
968 return TRUE;
969}
970
971/*
972 * @implemented
973 */
974BOOL
975WINAPI
977 OUT PSIZE_T lpMinimumWorkingSetSize,
978 OUT PSIZE_T lpMaximumWorkingSetSize,
980{
981 QUOTA_LIMITS_EX QuotaLimits;
983
984 /* Query the kernel about this */
987 &QuotaLimits,
988 sizeof(QuotaLimits),
989 NULL);
990 if (!NT_SUCCESS(Status))
991 {
992 /* Return error */
994 return FALSE;
995 }
996
997 /* Copy the quota information out */
998 *lpMinimumWorkingSetSize = QuotaLimits.MinimumWorkingSetSize;
999 *lpMaximumWorkingSetSize = QuotaLimits.MaximumWorkingSetSize;
1000 *Flags = QuotaLimits.Flags;
1001 return TRUE;
1002}
1003
1004/*
1005 * @implemented
1006 */
1007BOOL
1008WINAPI
1010 OUT PSIZE_T lpMinimumWorkingSetSize,
1011 OUT PSIZE_T lpMaximumWorkingSetSize)
1012{
1013 DWORD Dummy;
1015 lpMinimumWorkingSetSize,
1016 lpMaximumWorkingSetSize,
1017 &Dummy);
1018}
1019
1020/*
1021 * @implemented
1022 */
1023BOOL
1024WINAPI
1026 IN SIZE_T dwMinimumWorkingSetSize,
1027 IN SIZE_T dwMaximumWorkingSetSize,
1028 IN DWORD Flags)
1029{
1030 QUOTA_LIMITS_EX QuotaLimits;
1031 NTSTATUS Status, ReturnStatus;
1032 BOOL Result;
1033 PVOID State;
1035
1036 /* Zero out the input structure */
1037 RtlZeroMemory(&QuotaLimits, sizeof(QuotaLimits));
1038
1039 /* Check if the caller sent any limits */
1040 if ((dwMinimumWorkingSetSize) && (dwMaximumWorkingSetSize))
1041 {
1042 /* Write the quota information */
1043 QuotaLimits.MinimumWorkingSetSize = dwMinimumWorkingSetSize;
1044 QuotaLimits.MaximumWorkingSetSize = dwMaximumWorkingSetSize;
1045 QuotaLimits.Flags = Flags;
1046
1047 /* Acquire the required privilege */
1049
1050 /* Request the new quotas */
1051 ReturnStatus = NtSetInformationProcess(hProcess,
1053 &QuotaLimits,
1054 sizeof(QuotaLimits));
1055 Result = NT_SUCCESS(ReturnStatus);
1056 if (NT_SUCCESS(Status))
1057 {
1058 /* Release the privilege and set succes code */
1059 ASSERT(State != NULL);
1061 State = NULL;
1062 }
1063 }
1064 else
1065 {
1066 /* No limits, fail the call */
1067 ReturnStatus = STATUS_INVALID_PARAMETER;
1068 Result = FALSE;
1069 }
1070
1071 /* Return result code, set error code if this was a failure */
1072 if (!Result) BaseSetLastNTError(ReturnStatus);
1073 return Result;
1074}
1075
1076/*
1077 * @implemented
1078 */
1079BOOL
1080WINAPI
1082 IN SIZE_T dwMinimumWorkingSetSize,
1083 IN SIZE_T dwMaximumWorkingSetSize)
1084{
1085 /* Call the newer API */
1087 dwMinimumWorkingSetSize,
1088 dwMaximumWorkingSetSize,
1089 0);
1090}
1091
1092/*
1093 * @implemented
1094 */
1095BOOL
1096WINAPI
1098 IN LPFILETIME lpCreationTime,
1099 IN LPFILETIME lpExitTime,
1100 IN LPFILETIME lpKernelTime,
1101 IN LPFILETIME lpUserTime)
1102{
1105
1106 /* Query the times */
1109 &Kut,
1110 sizeof(Kut),
1111 NULL);
1112 if (!NT_SUCCESS(Status))
1113 {
1114 /* Handle failure */
1116 return FALSE;
1117 }
1118
1119 /* Copy all the times and return success */
1120 lpCreationTime->dwLowDateTime = Kut.CreateTime.u.LowPart;
1121 lpCreationTime->dwHighDateTime = Kut.CreateTime.u.HighPart;
1122 lpExitTime->dwLowDateTime = Kut.ExitTime.u.LowPart;
1123 lpExitTime->dwHighDateTime = Kut.ExitTime.u.HighPart;
1124 lpKernelTime->dwLowDateTime = Kut.KernelTime.u.LowPart;
1125 lpKernelTime->dwHighDateTime = Kut.KernelTime.u.HighPart;
1126 lpUserTime->dwLowDateTime = Kut.UserTime.u.LowPart;
1127 lpUserTime->dwHighDateTime = Kut.UserTime.u.HighPart;
1128 return TRUE;
1129}
1130
1131/*
1132 * @implemented
1133 */
1134HANDLE
1135WINAPI
1137{
1138 return (HANDLE)NtCurrentProcess();
1139}
1140
1141/*
1142 * @implemented
1143 */
1144HANDLE
1145WINAPI
1147{
1148 return (HANDLE)NtCurrentThread();
1149}
1150
1151/*
1152 * @implemented
1153 */
1154DWORD
1155WINAPI
1157{
1159}
1160
1161/*
1162 * @implemented
1163 */
1164BOOL
1165WINAPI
1167 IN LPDWORD lpExitCode)
1168{
1169 PROCESS_BASIC_INFORMATION ProcessBasic;
1171
1172 /* Ask the kernel */
1175 &ProcessBasic,
1176 sizeof(ProcessBasic),
1177 NULL);
1178 if (!NT_SUCCESS(Status))
1179 {
1180 /* We failed, was this because this is a VDM process? */
1181 if (BaseCheckForVDM(hProcess, lpExitCode) != FALSE) return TRUE;
1182
1183 /* Not a VDM process, fail the call */
1185 return FALSE;
1186 }
1187
1188 /* Succes case, return the exit code */
1189 *lpExitCode = (DWORD)ProcessBasic.ExitStatus;
1190 return TRUE;
1191}
1192
1193/*
1194 * @implemented
1195 */
1196DWORD
1197WINAPI
1199{
1200 PROCESS_BASIC_INFORMATION ProcessBasic;
1202
1203 /* Query the kernel */
1206 &ProcessBasic,
1207 sizeof(ProcessBasic),
1208 NULL);
1209 if (!NT_SUCCESS(Status))
1210 {
1211 /* Handle failure */
1213 return 0;
1214 }
1215
1216 /* Return the PID */
1217 return (DWORD)ProcessBasic.UniqueProcessId;
1218}
1219
1220/*
1221 * @implemented
1222 */
1223HANDLE
1224WINAPI
1225OpenProcess(IN DWORD dwDesiredAccess,
1228{
1233
1234 /* Setup the input client ID structure */
1237
1238 /* This is needed just to define the inheritance flags */
1240 NULL,
1242 NULL,
1243 NULL);
1244
1245 /* Now try to open the process */
1247 dwDesiredAccess,
1249 &ClientId);
1250 if (!NT_SUCCESS(Status))
1251 {
1252 /* Handle failure */
1254 return NULL;
1255 }
1256
1257 /* Otherwise return a handle to the process */
1258 return ProcessHandle;
1259}
1260
1261/*
1262 * @implemented
1263 */
1264VOID
1265WINAPI
1267{
1269
1270 /* Get the process parameters */
1271 Params = NtCurrentPeb()->ProcessParameters;
1272
1273 /* Copy the data out of there */
1274 lpStartupInfo->cb = sizeof(STARTUPINFOW);
1275 lpStartupInfo->lpReserved = Params->ShellInfo.Buffer;
1276 lpStartupInfo->lpDesktop = Params->DesktopInfo.Buffer;
1277 lpStartupInfo->lpTitle = Params->WindowTitle.Buffer;
1278 lpStartupInfo->dwX = Params->StartingX;
1279 lpStartupInfo->dwY = Params->StartingY;
1280 lpStartupInfo->dwXSize = Params->CountX;
1281 lpStartupInfo->dwYSize = Params->CountY;
1282 lpStartupInfo->dwXCountChars = Params->CountCharsX;
1283 lpStartupInfo->dwYCountChars = Params->CountCharsY;
1284 lpStartupInfo->dwFillAttribute = Params->FillAttribute;
1285 lpStartupInfo->dwFlags = Params->WindowFlags;
1286 lpStartupInfo->wShowWindow = (WORD)Params->ShowWindowFlags;
1287 lpStartupInfo->cbReserved2 = Params->RuntimeData.Length;
1288 lpStartupInfo->lpReserved2 = (LPBYTE)Params->RuntimeData.Buffer;
1289
1290 /* Check if the standard handles are being used for other features */
1291 if (lpStartupInfo->dwFlags & (STARTF_USESTDHANDLES |
1293 STARTF_SHELLPRIVATE))
1294 {
1295 /* These are, so copy the standard handles too */
1296 lpStartupInfo->hStdInput = Params->StandardInput;
1297 lpStartupInfo->hStdOutput = Params->StandardOutput;
1298 lpStartupInfo->hStdError = Params->StandardError;
1299 }
1300}
1301
1302/*
1303 * @implemented
1304 */
1305BOOL
1306WINAPI
1308 IN LPCVOID lpBaseAddress,
1309 IN SIZE_T nSize)
1310{
1312
1313 /* Call the native function */
1315 if (!NT_SUCCESS(Status))
1316 {
1317 /* Handle failure case */
1319 return FALSE;
1320 }
1321
1322 /* All good */
1323 return TRUE;
1324}
1325
1326/*
1327 * @implemented
1328 */
1329VOID
1330WINAPI
1332{
1333 BASE_API_MESSAGE ApiMessage;
1334 PBASE_EXIT_PROCESS ExitProcessRequest = &ApiMessage.Data.ExitProcessRequest;
1335
1337
1338 _SEH2_TRY
1339 {
1340 /* Acquire the PEB lock */
1342
1343 /* Kill all the threads */
1344 NtTerminateProcess(NULL, uExitCode);
1345
1346 /* Unload all DLLs */
1348
1349 /* Notify Base Server of process termination */
1350 ExitProcessRequest->uExitCode = uExitCode;
1352 NULL,
1354 sizeof(*ExitProcessRequest));
1355
1356 /* Now do it again */
1358 }
1360 {
1361 /* Release the PEB lock */
1363 }
1364 _SEH2_END;
1365
1366 /* should never get here */
1367 ASSERT(0);
1368 while(1);
1369}
1370
1371/*
1372 * @implemented
1373 */
1374BOOL
1375WINAPI
1377 IN UINT uExitCode)
1378{
1380
1381 /* Check if no handle was passed in */
1382 if (!hProcess)
1383 {
1384 /* Set error code */
1386 }
1387 else
1388 {
1389 /* Otherwise, try to terminate the process */
1390 Status = NtTerminateProcess(hProcess, uExitCode);
1391 if (NT_SUCCESS(Status)) return TRUE;
1392
1393 /* It failed, convert error code */
1395 }
1396
1397 /* This is the failure path */
1398 return FALSE;
1399}
1400
1401/*
1402 * @implemented
1403 */
1404VOID
1405WINAPI
1407 LPCSTR lpMessageText)
1408{
1409 PUNICODE_STRING MessageTextU;
1410 ANSI_STRING MessageText;
1412
1413 /* Initialize the string using the static TEB pointer */
1414 MessageTextU = &NtCurrentTeb()->StaticUnicodeString;
1415 RtlInitAnsiString(&MessageText, (LPSTR)lpMessageText);
1416
1417 /* Convert to unicode, or just exit normally if this failed */
1418 Status = RtlAnsiStringToUnicodeString(MessageTextU, &MessageText, FALSE);
1419 if (!NT_SUCCESS(Status)) ExitProcess(0);
1420
1421 /* Call the Wide function */
1422 FatalAppExitW(uAction, MessageTextU->Buffer);
1423}
1424
1425/*
1426 * @implemented
1427 */
1428VOID
1429WINAPI
1431 IN LPCWSTR lpMessageText)
1432{
1436
1437 /* Setup the string to print out */
1438 RtlInitUnicodeString(&UnicodeString, lpMessageText);
1439
1440 /* Display the hard error no matter what */
1442 1,
1443 1,
1445#if DBG
1446 /* On Checked builds, Windows allows the user to cancel the operation */
1448#else
1449 OptionOk,
1450#endif
1451 &Response);
1452
1453 /* Give the user a chance to abort */
1455 {
1456 return;
1457 }
1458
1459 /* Otherwise kill the process */
1460 ExitProcess(0);
1461}
1462
1463/*
1464 * @implemented
1465 */
1466VOID
1467WINAPI
1468FatalExit(IN int ExitCode)
1469{
1470#if DBG
1471 /* On Checked builds, Windows gives the user a nice little debugger UI */
1472 CHAR Action[2];
1473 DbgPrint("FatalExit...\n\n");
1474
1475 /* Check for reactos specific flag (set by rosautotest) */
1477 {
1479 }
1480
1481 while (TRUE)
1482 {
1483 DbgPrompt("A (Abort), B (Break), I (Ignore)? ", Action, sizeof(Action));
1484 switch (Action[0])
1485 {
1486 case 'B': case 'b':
1487 DbgBreakPoint();
1488 break;
1489
1490 case 'A': case 'a':
1491 ExitProcess(ExitCode);
1492
1493 case 'I': case 'i':
1494 return;
1495 }
1496 }
1497#endif
1498 /* On other builds, just kill the process */
1499 ExitProcess(ExitCode);
1500}
1501
1502/*
1503 * @implemented
1504 */
1505DWORD
1506WINAPI
1508{
1510 PROCESS_PRIORITY_CLASS DECLSPEC_ALIGN(4) PriorityClass;
1511
1512 /* Query the kernel */
1515 &PriorityClass,
1516 sizeof(PriorityClass),
1517 NULL);
1518 if (NT_SUCCESS(Status))
1519 {
1520 /* Handle the conversion from NT to Win32 classes */
1521 switch (PriorityClass.PriorityClass)
1522 {
1529 }
1530 }
1531
1532 /* Failure path */
1534 return 0;
1535}
1536
1537/*
1538 * @implemented
1539 */
1540BOOL
1541WINAPI
1543 IN DWORD dwPriorityClass)
1544{
1546 PVOID State = NULL;
1547 PROCESS_PRIORITY_CLASS PriorityClass;
1548
1549 /* Handle conversion from Win32 to NT priority classes */
1550 switch (dwPriorityClass)
1551 {
1554 break;
1555
1558 break;
1559
1562 break;
1563
1566 break;
1567
1570 break;
1571
1573 /* Try to acquire the privilege. If it fails, just use HIGH */
1576 PriorityClass.PriorityClass += (State != NULL);
1577 break;
1578
1579 default:
1580 /* Unrecognized priority classes don't make it to the kernel */
1582 return FALSE;
1583 }
1584
1585 /* Send the request to the kernel, and don't touch the foreground flag */
1586 PriorityClass.Foreground = FALSE;
1589 &PriorityClass,
1590 sizeof(PROCESS_PRIORITY_CLASS));
1591
1592 /* Release the privilege if we had it */
1594 if (!NT_SUCCESS(Status))
1595 {
1596 /* Handle error path */
1598 return FALSE;
1599 }
1600
1601 /* All done */
1602 return TRUE;
1603}
1604
1605/*
1606 * @implemented
1607 */
1608DWORD
1609WINAPI
1611{
1612 DWORD Version = 0;
1613 PIMAGE_NT_HEADERS NtHeader;
1614 PIMAGE_DOS_HEADER DosHeader;
1615 PPEB Peb;
1616 PROCESS_BASIC_INFORMATION ProcessBasicInfo;
1621 USHORT VersionData[2];
1623
1624 /* We'll be accessing stuff that can fault, so protect everything with SEH */
1625 _SEH2_TRY
1626 {
1627 /* It this an in-process or out-of-process request? */
1628 if (!(ProcessId) || (GetCurrentProcessId() == ProcessId))
1629 {
1630 /* It's in-process, so just read our own header */
1631 NtHeader = RtlImageNtHeader(NtCurrentPeb()->ImageBaseAddress);
1632 if (!NtHeader)
1633 {
1634 /* Unable to read the NT header, something is wrong here... */
1636 goto Error;
1637 }
1638
1639 /* Get the version straight out of the NT header */
1642 }
1643 else
1644 {
1645 /* Out-of-process, so open it */
1647 FALSE,
1648 ProcessId);
1649 if (!ProcessHandle) _SEH2_YIELD(return 0);
1650
1651 /* Try to find out where its PEB lives */
1654 &ProcessBasicInfo,
1655 sizeof(ProcessBasicInfo),
1656 NULL);
1657
1658 if (!NT_SUCCESS(Status)) goto Error;
1659 Peb = ProcessBasicInfo.PebBaseAddress;
1660
1661 /* Now that we have the PEB, read the image base address out of it */
1664 &BaseAddress,
1665 sizeof(BaseAddress),
1666 NULL);
1667 if (!Result) goto Error;
1668
1669 /* Now read the e_lfanew (offset to NT header) from the base */
1670 DosHeader = BaseAddress;
1672 &DosHeader->e_lfanew,
1673 &e_lfanew,
1674 sizeof(e_lfanew),
1675 NULL);
1676 if (!Result) goto Error;
1677
1678 /* And finally, read the NT header itself by adding the offset */
1679 NtHeader = (PVOID)((ULONG_PTR)BaseAddress + e_lfanew);
1682 &VersionData,
1683 sizeof(VersionData),
1684 NULL);
1685 if (!Result) goto Error;
1686
1687 /* Get the version straight out of the NT header */
1688 Version = MAKELONG(VersionData[0], VersionData[1]);
1689
1690Error:
1691 /* If there was an error anywhere, set the last error */
1693 }
1694 }
1696 {
1697 /* Close the process handle */
1699 }
1700 _SEH2_END;
1701
1702 /* And return the version data */
1703 return Version;
1704}
1705
1706/*
1707 * @implemented
1708 */
1709BOOL
1710WINAPI
1712 OUT PIO_COUNTERS lpIoCounters)
1713{
1715
1716 /* Query the kernel. Structures are identical, so let it do the copy too. */
1719 lpIoCounters,
1720 sizeof(IO_COUNTERS),
1721 NULL);
1722 if (!NT_SUCCESS(Status))
1723 {
1724 /* Handle error path */
1726 return FALSE;
1727 }
1728
1729 /* All done */
1730 return TRUE;
1731}
1732
1733/*
1734 * @implemented
1735 */
1736BOOL
1737WINAPI
1739 OUT PBOOL pDisablePriorityBoost)
1740{
1743
1744 /* Query the kernel */
1748 sizeof(PriorityBoost),
1749 NULL);
1750 if (NT_SUCCESS(Status))
1751 {
1752 /* Convert from ULONG to a BOOL */
1753 *pDisablePriorityBoost = PriorityBoost ? TRUE : FALSE;
1754 return TRUE;
1755 }
1756
1757 /* Handle error path */
1759 return FALSE;
1760}
1761
1762/*
1763 * @implemented
1764 */
1765BOOL
1766WINAPI
1768 IN BOOL bDisablePriorityBoost)
1769{
1772
1773 /* Enforce that this is a BOOL, and send it to the kernel as a ULONG */
1774 PriorityBoost = (bDisablePriorityBoost ? TRUE : FALSE);
1778 sizeof(ULONG));
1779 if (!NT_SUCCESS(Status))
1780 {
1781 /* Handle error path */
1783 return FALSE;
1784 }
1785
1786 /* All done */
1787 return TRUE;
1788}
1789
1790/*
1791 * @implemented
1792 */
1793BOOL
1794WINAPI
1796 OUT PDWORD pdwHandleCount)
1797{
1798 ULONG phc;
1800
1801 /* Query the kernel */
1804 &phc,
1805 sizeof(phc),
1806 NULL);
1807 if (NT_SUCCESS(Status))
1808 {
1809 /* Copy the count and return success */
1810 *pdwHandleCount = phc;
1811 return TRUE;
1812 }
1813
1814 /* Handle error path */
1816 return FALSE;
1817}
1818
1819/*
1820 * @implemented
1821 */
1822BOOL
1823WINAPI
1825 OUT PBOOL Wow64Process)
1826{
1827 ULONG_PTR pbi;
1829
1830 /* Query the kernel */
1833 &pbi,
1834 sizeof(pbi),
1835 NULL);
1836 if (!NT_SUCCESS(Status))
1837 {
1838 /* Handle error path */
1840 return FALSE;
1841 }
1842
1843 /* Enforce this is a BOOL, and return success */
1844 *Wow64Process = (pbi != 0);
1845 return TRUE;
1846}
1847
1848/*
1849 * @implemented
1850 */
1851LPSTR
1852WINAPI
1854{
1856}
1857
1858/*
1859 * @implemented
1860 */
1861LPWSTR
1862WINAPI
1864{
1866}
1867
1868/*
1869 * @implemented
1870 */
1871BOOL
1872NTAPI
1874 IN LPCVOID lpBaseAddress,
1876 IN SIZE_T nSize,
1877 OUT SIZE_T* lpNumberOfBytesRead)
1878{
1880
1881 /* Do the read */
1883 (PVOID)lpBaseAddress,
1884 lpBuffer,
1885 nSize,
1886 &nSize);
1887
1888 /* In user-mode, this parameter is optional */
1889 if (lpNumberOfBytesRead) *lpNumberOfBytesRead = nSize;
1890 if (!NT_SUCCESS(Status))
1891 {
1892 /* We failed */
1894 return FALSE;
1895 }
1896
1897 /* Return success */
1898 return TRUE;
1899}
1900
1901/*
1902 * @implemented
1903 */
1904BOOL
1905NTAPI
1907 IN LPVOID lpBaseAddress,
1909 IN SIZE_T nSize,
1910 OUT SIZE_T *lpNumberOfBytesWritten)
1911{
1913 ULONG OldValue;
1915 PVOID Base;
1917
1918 /* Set parameters for protect call */
1919 RegionSize = nSize;
1920 Base = lpBaseAddress;
1921
1922 /* Check the current status */
1924 &Base,
1925 &RegionSize,
1927 &OldValue);
1928 if (NT_SUCCESS(Status))
1929 {
1930 /* Check if we are unprotecting */
1931 UnProtect = OldValue & (PAGE_READWRITE |
1935 if (!UnProtect)
1936 {
1937 /* Set the new protection */
1939 &Base,
1940 &RegionSize,
1941 OldValue,
1942 &OldValue);
1943
1944 /* Write the memory */
1946 lpBaseAddress,
1948 nSize,
1949 &nSize);
1950
1951 /* In Win32, the parameter is optional, so handle this case */
1952 if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = nSize;
1953
1954 if (!NT_SUCCESS(Status))
1955 {
1956 /* We failed */
1958 return FALSE;
1959 }
1960
1961 /* Flush the ITLB */
1962 NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
1963 return TRUE;
1964 }
1965 else
1966 {
1967 /* Check if we were read only */
1968 if (OldValue & (PAGE_NOACCESS | PAGE_READONLY))
1969 {
1970 /* Restore protection and fail */
1972 &Base,
1973 &RegionSize,
1974 OldValue,
1975 &OldValue);
1977
1978 /* Note: This is what Windows returns and code depends on it */
1980 }
1981
1982 /* Otherwise, do the write */
1984 lpBaseAddress,
1986 nSize,
1987 &nSize);
1988
1989 /* In Win32, the parameter is optional, so handle this case */
1990 if (lpNumberOfBytesWritten) *lpNumberOfBytesWritten = nSize;
1991
1992 /* And restore the protection */
1994 &Base,
1995 &RegionSize,
1996 OldValue,
1997 &OldValue);
1998 if (!NT_SUCCESS(Status))
1999 {
2000 /* We failed */
2002
2003 /* Note: This is what Windows returns and code depends on it */
2005 }
2006
2007 /* Flush the ITLB */
2008 NtFlushInstructionCache(hProcess, lpBaseAddress, nSize);
2009 return TRUE;
2010 }
2011 }
2012 else
2013 {
2014 /* We failed */
2016 return FALSE;
2017 }
2018}
2019
2020/*
2021 * @implemented
2022 */
2023BOOL
2024WINAPI
2026 OUT PDWORD pSessionId)
2027{
2028 PROCESS_SESSION_INFORMATION SessionInformation;
2033
2034 /* Do a quick check if the pointer is not writable */
2035 if (IsBadWritePtr(pSessionId, sizeof(DWORD)))
2036 {
2037 /* Fail fast */
2039 return FALSE;
2040 }
2041
2042 /* Open the process passed in by ID */
2049 &ClientId);
2050 if (NT_SUCCESS(Status))
2051 {
2052 /* Query the session ID from the kernel */
2055 &SessionInformation,
2056 sizeof(SessionInformation),
2057 NULL);
2058
2059 /* Close the handle and check if we succeeded */
2061 if (NT_SUCCESS(Status))
2062 {
2063 /* Return the session ID */
2064 *pSessionId = SessionInformation.SessionId;
2065 return TRUE;
2066 }
2067 }
2068
2069 /* Set error code and fail */
2071 return FALSE;
2072}
2073
2074
2075#define AddToHandle(x,y) ((x) = (HANDLE)((ULONG_PTR)(x) | (y)))
2076#define RemoveFromHandle(x,y) ((x) = (HANDLE)((ULONG_PTR)(x) & ~(y)))
2078
2079/*
2080 * @implemented
2081 */
2082BOOL
2083WINAPI
2085 IN LPCWSTR lpApplicationName,
2086 IN LPWSTR lpCommandLine,
2087 IN LPSECURITY_ATTRIBUTES lpProcessAttributes,
2088 IN LPSECURITY_ATTRIBUTES lpThreadAttributes,
2089 IN BOOL bInheritHandles,
2090 IN DWORD dwCreationFlags,
2091 IN LPVOID lpEnvironment,
2092 IN LPCWSTR lpCurrentDirectory,
2093 IN LPSTARTUPINFOW lpStartupInfo,
2094 IN LPPROCESS_INFORMATION lpProcessInformation,
2095 OUT PHANDLE hNewToken)
2096{
2097 //
2098 // Core variables used for creating the initial process and thread
2099 //
2100 SECURITY_ATTRIBUTES LocalThreadAttributes, LocalProcessAttributes;
2101 OBJECT_ATTRIBUTES LocalObjectAttributes;
2103 SECTION_IMAGE_INFORMATION ImageInformation;
2106 ULONG NoWindow, StackSize, ErrorCode, Flags;
2108 USHORT ImageMachine;
2109 ULONG ParameterFlags, PrivilegeValue, HardErrorMode, ErrorResponse;
2110 ULONG_PTR ErrorParameters[2];
2111 BOOLEAN InJob, SaferNeeded, UseLargePages, HavePrivilege;
2112 BOOLEAN QuerySection, SkipSaferAndAppCompat;
2114 BASE_API_MESSAGE CsrMsg[2];
2115 PBASE_CREATE_PROCESS CreateProcessMsg;
2116 PCSR_CAPTURE_BUFFER CaptureBuffer;
2117 PVOID BaseAddress, PrivilegeState, RealTimePrivilegeState;
2118 HANDLE DebugHandle, TokenHandle, JobHandle, KeyHandle, ThreadHandle;
2119 HANDLE FileHandle, SectionHandle, ProcessHandle;
2121 PROCESS_PRIORITY_CLASS PriorityClass;
2122 NTSTATUS Status, AppCompatStatus, SaferStatus, IFEOStatus, ImageDbgStatus;
2123 PPEB Peb, RemotePeb;
2124 PTEB Teb;
2125 INITIAL_TEB InitialTeb;
2126 PVOID TibValue;
2127 PIMAGE_NT_HEADERS NtHeaders;
2128 STARTUPINFOW StartupInfo;
2129 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
2130 UNICODE_STRING DebuggerString;
2131 BOOL Result;
2132 //
2133 // Variables used for command-line and argument parsing
2134 //
2135 PCHAR pcScan;
2136 SIZE_T n;
2137 WCHAR SaveChar;
2138 ULONG Length, FileAttribs, CmdQuoteLength;
2139 ULONG ResultSize;
2140 SIZE_T EnvironmentLength, CmdLineLength;
2141 PWCHAR QuotedCmdLine, AnsiCmdCommand, ExtBuffer, CurrentDirectory;
2142 PWCHAR NullBuffer, ScanString, NameBuffer, SearchPath, DebuggerCmdLine;
2143 ANSI_STRING AnsiEnv;
2144 UNICODE_STRING UnicodeEnv, PathName;
2145 BOOLEAN SearchRetry, QuotesNeeded, CmdLineIsAppName, HasQuotes;
2146
2147 //
2148 // Variables used for Fusion/SxS (Side-by-Side Assemblies)
2149 //
2150 RTL_PATH_TYPE SxsPathType, PathType;
2151#if _SXS_SUPPORT_ENABLED_
2152 PRTL_BUFFER ByteBuffer;
2153 PRTL_UNICODE_STRING_BUFFER ThisBuffer, Buffer, SxsStaticBuffers[5];
2154 PRTL_UNICODE_STRING_BUFFER* BufferHead, SxsStringBuffer;
2155 RTL_UNICODE_STRING_BUFFER SxsWin32ManifestPath, SxsNtManifestPath;
2156 RTL_UNICODE_STRING_BUFFER SxsWin32PolicyPath, SxsNtPolicyPath;
2157 RTL_UNICODE_STRING_BUFFER SxsWin32AssemblyDirectory;
2158 BASE_MSG_SXS_HANDLES MappedHandles, Handles, FileHandles;
2159 PVOID CapturedStrings[3];
2160 SXS_WIN32_NT_PATH_PAIR ExePathPair, ManifestPathPair, PolicyPathPair;
2161 SXS_OVERRIDE_MANIFEST OverrideManifest;
2162 UNICODE_STRING FreeString, SxsNtExePath;
2163 PWCHAR SxsConglomeratedBuffer, StaticBuffer;
2164 ULONG ConglomeratedBufferSizeBytes, StaticBufferSize, i;
2165#endif
2167
2168 //
2169 // Variables used for path conversion (and partially Fusion/SxS)
2170 //
2171 PWCHAR FilePart, PathBuffer, FreeBuffer;
2172 BOOLEAN TranslationStatus;
2173 RTL_RELATIVE_NAME_U SxsWin32RelativePath;
2174 UNICODE_STRING PathBufferString, SxsWin32ExePath;
2175
2176 //
2177 // Variables used by Application Compatibility (and partially Fusion/SxS)
2178 //
2179 PVOID AppCompatSxsData, AppCompatData;
2180 ULONG AppCompatSxsDataSize, AppCompatDataSize;
2181 //
2182 // Variables used by VDM (Virtual Dos Machine) and WOW32 (16-bit Support)
2183 //
2184 ULONG BinarySubType, VdmBinaryType, VdmTask, VdmReserve;
2185 ULONG VdmUndoLevel;
2186 BOOLEAN UseVdmReserve;
2187 HANDLE VdmWaitObject;
2188 ANSI_STRING VdmAnsiEnv;
2189 UNICODE_STRING VdmString, VdmUnicodeEnv;
2190 BOOLEAN IsWowApp;
2191 PBASE_CHECK_VDM CheckVdmMsg;
2192
2193 /* Zero out the initial core variables and handles */
2194 QuerySection = FALSE;
2195 InJob = FALSE;
2196 SkipSaferAndAppCompat = FALSE;
2197 ParameterFlags = 0;
2198 Flags = 0;
2199 DebugHandle = NULL;
2200 JobHandle = NULL;
2201 TokenHandle = NULL;
2202 FileHandle = NULL;
2203 SectionHandle = NULL;
2205 ThreadHandle = NULL;
2207 BaseAddress = (PVOID)1;
2208
2209 /* Zero out initial SxS and Application Compatibility state */
2210 AppCompatData = NULL;
2211 AppCompatDataSize = 0;
2212 AppCompatSxsData = NULL;
2213 AppCompatSxsDataSize = 0;
2214 CaptureBuffer = NULL;
2215#if _SXS_SUPPORT_ENABLED_
2216 SxsConglomeratedBuffer = NULL;
2217#endif
2218 FusionFlags = 0;
2219
2220 /* Zero out initial parsing variables -- others are initialized later */
2221 DebuggerCmdLine = NULL;
2222 PathBuffer = NULL;
2223 SearchPath = NULL;
2224 NullBuffer = NULL;
2225 FreeBuffer = NULL;
2226 NameBuffer = NULL;
2228 FilePart = NULL;
2229 DebuggerString.Buffer = NULL;
2230 HasQuotes = FALSE;
2231 QuotedCmdLine = NULL;
2232
2233 /* Zero out initial VDM state */
2234 VdmAnsiEnv.Buffer = NULL;
2235 VdmUnicodeEnv.Buffer = NULL;
2236 VdmString.Buffer = NULL;
2237 VdmTask = 0;
2238 VdmUndoLevel = 0;
2239 VdmBinaryType = 0;
2240 VdmReserve = 0;
2241 VdmWaitObject = NULL;
2242 UseVdmReserve = FALSE;
2243 IsWowApp = FALSE;
2244
2245 /* Set message structures */
2246 CreateProcessMsg = &CsrMsg[0].Data.CreateProcessRequest;
2247 CheckVdmMsg = &CsrMsg[1].Data.CheckVDMRequest;
2248
2249 /* Clear the more complex structures by zeroing out their entire memory */
2250 RtlZeroMemory(&Context, sizeof(Context));
2251#if _SXS_SUPPORT_ENABLED_
2252 RtlZeroMemory(&FileHandles, sizeof(FileHandles));
2253 RtlZeroMemory(&MappedHandles, sizeof(MappedHandles));
2254 RtlZeroMemory(&Handles, sizeof(Handles));
2255#endif
2256 RtlZeroMemory(&CreateProcessMsg->Sxs, sizeof(CreateProcessMsg->Sxs));
2257 RtlZeroMemory(&LocalProcessAttributes, sizeof(LocalProcessAttributes));
2258 RtlZeroMemory(&LocalThreadAttributes, sizeof(LocalThreadAttributes));
2259
2260 /* Zero out output arguments as well */
2261 RtlZeroMemory(lpProcessInformation, sizeof(*lpProcessInformation));
2262 if (hNewToken) *hNewToken = NULL;
2263
2264 /* Capture the special window flag */
2265 NoWindow = dwCreationFlags & CREATE_NO_WINDOW;
2266 dwCreationFlags &= ~CREATE_NO_WINDOW;
2267
2268#if _SXS_SUPPORT_ENABLED_
2269 /* Setup the SxS static string arrays and buffers */
2270 SxsStaticBuffers[0] = &SxsWin32ManifestPath;
2271 SxsStaticBuffers[1] = &SxsWin32PolicyPath;
2272 SxsStaticBuffers[2] = &SxsWin32AssemblyDirectory;
2273 SxsStaticBuffers[3] = &SxsNtManifestPath;
2274 SxsStaticBuffers[4] = &SxsNtPolicyPath;
2275 ExePathPair.Win32 = &SxsWin32ExePath;
2276 ExePathPair.Nt = &SxsNtExePath;
2277 ManifestPathPair.Win32 = &SxsWin32ManifestPath.String;
2278 ManifestPathPair.Nt = &SxsNtManifestPath.String;
2279 PolicyPathPair.Win32 = &SxsWin32PolicyPath.String;
2280 PolicyPathPair.Nt = &SxsNtPolicyPath.String;
2281#endif
2282
2283 DPRINT("CreateProcessInternalW: '%S' '%S' %lx\n", lpApplicationName, lpCommandLine, dwCreationFlags);
2284
2285 /* Finally, set our TEB and PEB */
2286 Teb = NtCurrentTeb();
2287 Peb = NtCurrentPeb();
2288
2289 /* This combination is illegal (see MSDN) */
2290 if ((dwCreationFlags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)) ==
2292 {
2293 DPRINT1("Invalid flag combo used\n");
2295 return FALSE;
2296 }
2297
2298 /* Convert the priority class */
2299 if (dwCreationFlags & IDLE_PRIORITY_CLASS)
2300 {
2302 }
2303 else if (dwCreationFlags & BELOW_NORMAL_PRIORITY_CLASS)
2304 {
2306 }
2307 else if (dwCreationFlags & NORMAL_PRIORITY_CLASS)
2308 {
2310 }
2311 else if (dwCreationFlags & ABOVE_NORMAL_PRIORITY_CLASS)
2312 {
2314 }
2315 else if (dwCreationFlags & HIGH_PRIORITY_CLASS)
2316 {
2318 }
2319 else if (dwCreationFlags & REALTIME_PRIORITY_CLASS)
2320 {
2322 PriorityClass.PriorityClass += (BasepIsRealtimeAllowed(FALSE) != NULL);
2323 }
2324 else
2325 {
2327 }
2328
2329 /* Done with the priority masks, so get rid of them */
2330 PriorityClass.Foreground = FALSE;
2331 dwCreationFlags &= ~(NORMAL_PRIORITY_CLASS |
2337
2338 /* You cannot request both a shared and a separate WoW VDM */
2339 if ((dwCreationFlags & CREATE_SEPARATE_WOW_VDM) &&
2340 (dwCreationFlags & CREATE_SHARED_WOW_VDM))
2341 {
2342 /* Fail such nonsensical attempts */
2343 DPRINT1("Invalid WOW flags\n");
2345 return FALSE;
2346 }
2347 else if (!(dwCreationFlags & CREATE_SHARED_WOW_VDM) &&
2349 {
2350 /* A shared WoW VDM was not requested but system enforces separation */
2351 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
2352 }
2353
2354 /* If a shared WoW VDM is used, make sure the process isn't in a job */
2355 if (!(dwCreationFlags & CREATE_SEPARATE_WOW_VDM) &&
2357 {
2358 /* Remove the shared flag and add the separate flag */
2359 dwCreationFlags = (dwCreationFlags &~ CREATE_SHARED_WOW_VDM) |
2361 }
2362
2363 /* Convert the environment */
2364 if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
2365 {
2366 /* Scan the environment to calculate its Unicode size */
2367 AnsiEnv.Buffer = pcScan = (PCHAR)lpEnvironment;
2368 while ((*pcScan) || (*(pcScan + 1))) ++pcScan;
2369
2370 /* Make sure the environment is not too large */
2371 EnvironmentLength = (pcScan + sizeof(ANSI_NULL) - (PCHAR)lpEnvironment);
2372 if (EnvironmentLength > MAXUSHORT)
2373 {
2374 /* Fail */
2376 return FALSE;
2377 }
2378
2379 /* Create our ANSI String */
2380 AnsiEnv.Length = (USHORT)EnvironmentLength;
2381 AnsiEnv.MaximumLength = AnsiEnv.Length + sizeof(ANSI_NULL);
2382
2383 /* Allocate memory for the Unicode Environment */
2384 UnicodeEnv.Buffer = NULL;
2385 RegionSize = AnsiEnv.MaximumLength * sizeof(WCHAR);
2387 (PVOID)&UnicodeEnv.Buffer,
2388 0,
2389 &RegionSize,
2390 MEM_COMMIT,
2392 if (!NT_SUCCESS(Status))
2393 {
2394 /* Fail */
2396 return FALSE;
2397 }
2398
2399 /* Use the allocated size and convert */
2400 UnicodeEnv.MaximumLength = (USHORT)RegionSize;
2401 Status = RtlAnsiStringToUnicodeString(&UnicodeEnv, &AnsiEnv, FALSE);
2402 if (!NT_SUCCESS(Status))
2403 {
2404 /* Fail */
2406 (PVOID)&UnicodeEnv.Buffer,
2407 &RegionSize,
2408 MEM_RELEASE);
2410 return FALSE;
2411 }
2412
2413 /* Now set the Unicode environment as the environment string pointer */
2414 lpEnvironment = UnicodeEnv.Buffer;
2415 }
2416
2417 /* Make a copy of the caller's startup info since we'll modify it */
2418 StartupInfo = *lpStartupInfo;
2419
2420 /* Check if private data is being sent on the same channel as std handles */
2421 if ((StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
2422 (StartupInfo.dwFlags & (STARTF_USEHOTKEY | STARTF_SHELLPRIVATE)))
2423 {
2424 /* Cannot use the std handles since we have monitor/hotkey values */
2425 StartupInfo.dwFlags &= ~STARTF_USESTDHANDLES;
2426 }
2427
2428 /* If there's a debugger, or we have to launch cmd.exe, we go back here */
2429AppNameRetry:
2430 /* New iteration -- free any existing name buffer */
2431 if (NameBuffer)
2432 {
2433 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
2434 NameBuffer = NULL;
2435 }
2436
2437 /* New iteration -- free any existing free buffer */
2438 if (FreeBuffer)
2439 {
2440 RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
2441 FreeBuffer = NULL;
2442 }
2443
2444 /* New iteration -- close any existing file handle */
2445 if (FileHandle)
2446 {
2448 FileHandle = NULL;
2449 }
2450
2451 /* Set the initial parsing state. This code can loop -- don't move this! */
2452 ErrorCode = 0;
2453 SearchRetry = TRUE;
2454 QuotesNeeded = FALSE;
2455 CmdLineIsAppName = FALSE;
2456
2457 /* First check if we don't have an application name */
2458 if (!lpApplicationName)
2459 {
2460 /* This should be the first time we attempt creating one */
2461 ASSERT(NameBuffer == NULL);
2462
2463 /* Allocate a buffer to hold it */
2464 NameBuffer = RtlAllocateHeap(RtlGetProcessHeap(),
2465 0,
2466 MAX_PATH * sizeof(WCHAR));
2467 if (!NameBuffer)
2468 {
2470 Result = FALSE;
2471 goto Quickie;
2472 }
2473
2474 /* Initialize the application name and our parsing parameters */
2475 lpApplicationName = NullBuffer = ScanString = lpCommandLine;
2476
2477 /* Check for an initial quote*/
2478 if (*lpCommandLine == L'\"')
2479 {
2480 /* We found a quote, keep searching for another one */
2481 SearchRetry = FALSE;
2482 ScanString++;
2483 lpApplicationName = ScanString;
2484 while (*ScanString)
2485 {
2486 /* Have we found the terminating quote? */
2487 if (*ScanString == L'\"')
2488 {
2489 /* We're done, get out of here */
2490 NullBuffer = ScanString;
2491 HasQuotes = TRUE;
2492 break;
2493 }
2494
2495 /* Keep searching for the quote */
2496 ScanString++;
2497 NullBuffer = ScanString;
2498 }
2499 }
2500 else
2501 {
2502StartScan:
2503 /* We simply make the application name be the command line*/
2504 lpApplicationName = lpCommandLine;
2505 while (*ScanString)
2506 {
2507 /* Check if it starts with a space or tab */
2508 if ((*ScanString == L' ') || (*ScanString == L'\t'))
2509 {
2510 /* Break out of the search loop */
2511 NullBuffer = ScanString;
2512 break;
2513 }
2514
2515 /* Keep searching for a space or tab */
2516 ScanString++;
2517 NullBuffer = ScanString;
2518 }
2519 }
2520
2521 /* We have found the end of the application name, terminate it */
2522 SaveChar = *NullBuffer;
2523 *NullBuffer = UNICODE_NULL;
2524
2525 /* New iteration -- free any existing saved path */
2526 if (SearchPath)
2527 {
2528 RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
2529 SearchPath = NULL;
2530 }
2531
2532 /* Now compute the final EXE path based on the name */
2533 SearchPath = BaseComputeProcessExePath((LPWSTR)lpApplicationName);
2534 DPRINT("Search Path: %S\n", SearchPath);
2535 if (!SearchPath)
2536 {
2538 Result = FALSE;
2539 goto Quickie;
2540 }
2541
2542 /* And search for the executable in the search path */
2544 lpApplicationName,
2545 L".exe",
2546 MAX_PATH,
2547 NameBuffer,
2548 NULL);
2549
2550 /* Did we find it? */
2551 if ((Length) && (Length < MAX_PATH))
2552 {
2553 /* Get file attributes */
2554 FileAttribs = GetFileAttributesW(NameBuffer);
2555 if ((FileAttribs != INVALID_FILE_ATTRIBUTES) &&
2556 (FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
2557 {
2558 /* This was a directory, fail later on */
2559 Length = 0;
2560 }
2561 else
2562 {
2563 /* It's a file! */
2564 Length++;
2565 }
2566 }
2567
2568 DPRINT("Length: %lu Buffer: %S\n", Length, NameBuffer);
2569
2570 /* Check if there was a failure in SearchPathW */
2571 if ((Length) && (Length < MAX_PATH))
2572 {
2573 /* Everything looks good, restore the name */
2574 *NullBuffer = SaveChar;
2575 lpApplicationName = NameBuffer;
2576 }
2577 else
2578 {
2579 /* Check if this was a relative path, which would explain it */
2580 PathType = RtlDetermineDosPathNameType_U(lpApplicationName);
2582 {
2583 /* This should fail, and give us a detailed LastError */
2584 FileHandle = CreateFileW(lpApplicationName,
2588 NULL,
2591 NULL);
2593 {
2594 /* It worked? Return a generic error */
2596 FileHandle = NULL;
2598 }
2599 }
2600 else
2601 {
2602 /* Path was absolute, which means it doesn't exist */
2604 }
2605
2606 /* Did we already fail once? */
2607 if (ErrorCode)
2608 {
2609 /* Set the error code */
2611 }
2612 else
2613 {
2614 /* Not yet, cache it */
2616 }
2617
2618 /* Put back the command line */
2619 *NullBuffer = SaveChar;
2620 lpApplicationName = NameBuffer;
2621
2622 /* It's possible there's whitespace in the directory name */
2623 if (!(*ScanString) || !(SearchRetry))
2624 {
2625 /* Not the case, give up completely */
2626 Result = FALSE;
2627 goto Quickie;
2628 }
2629
2630 /* There are spaces, so keep trying the next possibility */
2631 ScanString++;
2632 NullBuffer = ScanString;
2633
2634 /* We will have to add a quote, since there is a space */
2635 QuotesNeeded = TRUE;
2636 HasQuotes = TRUE;
2637 goto StartScan;
2638 }
2639 }
2640 else if (!(lpCommandLine) || !(*lpCommandLine))
2641 {
2642 /* We don't have a command line, so just use the application name */
2643 CmdLineIsAppName = TRUE;
2644 lpCommandLine = (LPWSTR)lpApplicationName;
2645 }
2646
2647 /* Convert the application name to its NT path */
2648 TranslationStatus = RtlDosPathNameToRelativeNtPathName_U(lpApplicationName,
2649 &PathName,
2650 NULL,
2651 &SxsWin32RelativePath);
2652 if (!TranslationStatus)
2653 {
2654 /* Path must be invalid somehow, bail out */
2655 DPRINT1("Path translation for SxS failed\n");
2657 Result = FALSE;
2658 goto Quickie;
2659 }
2660
2661 /* Setup the buffer that needs to be freed at the end */
2662 ASSERT(FreeBuffer == NULL);
2663 FreeBuffer = PathName.Buffer;
2664
2665 /* Check what kind of path the application is, for SxS (Fusion) purposes */
2666 RtlInitUnicodeString(&SxsWin32ExePath, lpApplicationName);
2667 SxsPathType = RtlDetermineDosPathNameType_U(lpApplicationName);
2668 if ((SxsPathType != RtlPathTypeDriveAbsolute) &&
2669 (SxsPathType != RtlPathTypeLocalDevice) &&
2670 (SxsPathType != RtlPathTypeRootLocalDevice) &&
2671 (SxsPathType != RtlPathTypeUncAbsolute))
2672 {
2673 /* Relative-type path, get the full path */
2674 RtlInitEmptyUnicodeString(&PathBufferString, NULL, 0);
2675 Status = RtlGetFullPathName_UstrEx(&SxsWin32ExePath,
2676 NULL,
2677 &PathBufferString,
2678 NULL,
2679 NULL,
2680 NULL,
2681 &SxsPathType,
2682 NULL);
2683 if (!NT_SUCCESS(Status))
2684 {
2685 /* Fail the rest of the create */
2686 RtlReleaseRelativeName(&SxsWin32RelativePath);
2688 Result = FALSE;
2689 goto Quickie;
2690 }
2691
2692 /* Use this full path as the SxS path */
2693 SxsWin32ExePath = PathBufferString;
2694 PathBuffer = PathBufferString.Buffer;
2695 PathBufferString.Buffer = NULL;
2696 DPRINT("SxS Path: %S\n", PathBuffer);
2697 }
2698
2699 /* Also set the .EXE path based on the path name */
2700#if _SXS_SUPPORT_ENABLED_
2701 SxsNtExePath = PathName;
2702#endif
2703 if (SxsWin32RelativePath.RelativeName.Length)
2704 {
2705 /* If it's relative, capture the relative name */
2706 PathName = SxsWin32RelativePath.RelativeName;
2707 }
2708 else
2709 {
2710 /* Otherwise, it's absolute, make sure no relative dir is used */
2711 SxsWin32RelativePath.ContainingDirectory = NULL;
2712 }
2713
2714 /* Now use the path name, and the root path, to try opening the app */
2715 DPRINT("Path: %wZ. Dir: %p\n", &PathName, SxsWin32RelativePath.ContainingDirectory);
2716 InitializeObjectAttributes(&LocalObjectAttributes,
2717 &PathName,
2719 SxsWin32RelativePath.ContainingDirectory,
2720 NULL);
2722 SYNCHRONIZE |
2726 &LocalObjectAttributes,
2731 if (!NT_SUCCESS(Status))
2732 {
2733 /* Try to open the app just for execute purposes instead */
2736 &LocalObjectAttributes,
2741 }
2742
2743 /* Failure path, display which file failed to open */
2744 if (!NT_SUCCESS(Status))
2745 DPRINT1("Open file failed: %lx (%wZ)\n", Status, &PathName);
2746
2747 /* Cleanup in preparation for failure or success */
2748 RtlReleaseRelativeName(&SxsWin32RelativePath);
2749
2750 if (!NT_SUCCESS(Status))
2751 {
2752 /* Failure path, try to understand why */
2753 if (RtlIsDosDeviceName_U(lpApplicationName))
2754 {
2755 /* If a device is being executed, return this special error code */
2757 Result = FALSE;
2758 goto Quickie;
2759 }
2760 else
2761 {
2762 /* Otherwise return the converted NT error code */
2764 Result = FALSE;
2765 goto Quickie;
2766 }
2767 }
2768
2769 /* Did the caller specify a desktop? */
2770 if (!StartupInfo.lpDesktop)
2771 {
2772 /* Use the one from the current process */
2774 }
2775
2776 /* Create a section for this file */
2777 Status = NtCreateSection(&SectionHandle,
2779 NULL,
2780 NULL,
2782 SEC_IMAGE,
2783 FileHandle);
2784 DPRINT("Section status: %lx\n", Status);
2785 if (NT_SUCCESS(Status))
2786 {
2787 /* Are we running on Windows Embedded, Datacenter, Blade or Starter? */
2788 if (SharedUserData->SuiteMask & (VER_SUITE_EMBEDDEDNT |
2792 {
2793 /* These SKUs do not allow running certain applications */
2796 {
2797 /* And this is one of them! */
2798 DPRINT1("Invalid Blade hashes!\n");
2800 Result = FALSE;
2801 goto Quickie;
2802 }
2803
2804 /* Did we get some other failure? */
2805 if (!NT_SUCCESS(Status))
2806 {
2807 /* If we couldn't check the hashes, assume nefariousness */
2808 DPRINT1("Tampered Blade hashes!\n");
2810 Result = FALSE;
2811 goto Quickie;
2812 }
2813 }
2814
2815 /* Now do Winsafer, etc, checks */
2816 Status = BasepIsProcessAllowed((LPWSTR)lpApplicationName);
2817 if (!NT_SUCCESS(Status))
2818 {
2819 /* Fail if we're not allowed to launch the process */
2820 DPRINT1("Process not allowed to launch: %lx\n", Status);
2822 if (SectionHandle)
2823 {
2824 NtClose(SectionHandle);
2825 SectionHandle = NULL;
2826 }
2827 Result = FALSE;
2828 goto Quickie;
2829 }
2830
2831 /* Is a DOS VDM being forced, but we already have a WOW32 instance ready? */
2832 if ((dwCreationFlags & CREATE_FORCEDOS) &&
2834 {
2835 /* This request can't be satisfied, instead, a separate VDM is needed */
2836 dwCreationFlags &= ~(CREATE_FORCEDOS | CREATE_SHARED_WOW_VDM);
2837 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
2838
2839 /* Set a failure code, ask for VDM reservation */
2841 UseVdmReserve = TRUE;
2842
2843 /* Close the current handle */
2844 NtClose(SectionHandle);
2845 SectionHandle = NULL;
2846
2847 /* Don't query the section later */
2848 QuerySection = FALSE;
2849 }
2850 }
2851
2852 /* Did we already do these checks? */
2853 if (!SkipSaferAndAppCompat)
2854 {
2855 /* Is everything OK so far, OR do we have an non-MZ, non-DOS app? */
2856 if ((NT_SUCCESS(Status)) ||
2858 !(BaseIsDosApplication(&PathName, Status))))
2859 {
2860 /* Clear the machine type in case of failure */
2861 ImageMachine = 0;
2862
2863 /* Clean any app compat data that may have accumulated */
2864 BasepFreeAppCompatData(AppCompatData, AppCompatSxsData);
2865 AppCompatData = NULL;
2866 AppCompatSxsData = NULL;
2867
2868 /* Do we have a section? */
2869 if (SectionHandle)
2870 {
2871 /* Have we already queried it? */
2872 if (QuerySection)
2873 {
2874 /* Nothing to do */
2875 AppCompatStatus = STATUS_SUCCESS;
2876 }
2877 else
2878 {
2879 /* Get some information about the executable */
2880 AppCompatStatus = NtQuerySection(SectionHandle,
2882 &ImageInformation,
2883 sizeof(ImageInformation),
2884 NULL);
2885 }
2886
2887 /* Do we have section information now? */
2888 if (NT_SUCCESS(AppCompatStatus))
2889 {
2890 /* Don't ask for it again, save the machine type */
2891 QuerySection = TRUE;
2892 ImageMachine = ImageInformation.Machine;
2893 }
2894 }
2895
2896 /* Is there a reason/Shim we shouldn't run this application? */
2897 AppCompatStatus = BasepCheckBadapp(FileHandle,
2898 FreeBuffer,
2899 lpEnvironment,
2900 ImageMachine,
2901 &AppCompatData,
2902 &AppCompatDataSize,
2903 &AppCompatSxsData,
2904 &AppCompatSxsDataSize,
2905 &FusionFlags);
2906 if (!NT_SUCCESS(AppCompatStatus))
2907 {
2908 /* This is usually the status we get back */
2909 DPRINT1("App compat launch failure: %lx\n", AppCompatStatus);
2910 if (AppCompatStatus == STATUS_ACCESS_DENIED)
2911 {
2912 /* Convert it to something more Win32-specific */
2914 }
2915 else
2916 {
2917 /* Some other error */
2918 BaseSetLastNTError(AppCompatStatus);
2919 }
2920
2921 /* Did we have a section? */
2922 if (SectionHandle)
2923 {
2924 /* Clean it up */
2925 NtClose(SectionHandle);
2926 SectionHandle = NULL;
2927 }
2928
2929 /* Fail the call */
2930 Result = FALSE;
2931 goto Quickie;
2932 }
2933 }
2934 }
2935
2936 //ASSERT((dwFusionFlags & ~SXS_APPCOMPACT_FLAG_APP_RUNNING_SAFEMODE) == 0);
2937
2938 /* Have we already done, and do we need to do, SRP (WinSafer) checks? */
2939 if (!(SkipSaferAndAppCompat) &&
2940 ~(dwCreationFlags & CREATE_PRESERVE_CODE_AUTHZ_LEVEL))
2941 {
2942 /* Assume yes */
2943 SaferNeeded = TRUE;
2944 switch (Status)
2945 {
2950 /* For all DOS, 16-bit, OS/2 images, we do*/
2951 break;
2952
2954 /* For invalid files, we don't, unless it's a .BAT file */
2955 if (BaseIsDosApplication(&PathName, Status)) break;
2956
2957 default:
2958 /* Any other error codes we also don't */
2959 if (!NT_SUCCESS(Status))
2960 {
2961 SaferNeeded = FALSE;
2962 }
2963
2964 /* But for success, we do */
2965 break;
2966 }
2967
2968 /* Okay, so what did the checks above result in? */
2969 if (SaferNeeded)
2970 {
2971 /* We have to call into the WinSafer library and actually check */
2973 (LPWSTR)lpApplicationName,
2974 FileHandle,
2975 &InJob,
2976 &TokenHandle,
2977 &JobHandle);
2978 if (SaferStatus == 0xFFFFFFFF)
2979 {
2980 /* Back in 2003, they didn't have an NTSTATUS for this... */
2981 DPRINT1("WinSafer blocking process launch\n");
2983 Result = FALSE;
2984 goto Quickie;
2985 }
2986
2987 /* Other status codes are not-Safer related, just convert them */
2988 if (!NT_SUCCESS(SaferStatus))
2989 {
2990 DPRINT1("Error checking WinSafer: %lx\n", SaferStatus);
2991 BaseSetLastNTError(SaferStatus);
2992 Result = FALSE;
2993 goto Quickie;
2994 }
2995 }
2996 }
2997
2998 /* The last step is to figure out why the section object was not created */
2999 switch (Status)
3000 {
3002 {
3003 /* 16-bit binary. Should we use WOW or does the caller force VDM? */
3004 if (!(dwCreationFlags & CREATE_FORCEDOS))
3005 {
3006 /* Remember that we're launching WOW */
3007 IsWowApp = TRUE;
3008
3009 /* Create the VDM environment, it's valid for WOW too */
3010 Result = BaseCreateVDMEnvironment(lpEnvironment,
3011 &VdmAnsiEnv,
3012 &VdmUnicodeEnv);
3013 if (!Result)
3014 {
3015 DPRINT1("VDM environment for WOW app failed\n");
3016 goto Quickie;
3017 }
3018
3019 /* We're going to try this twice, so do a loop */
3020 while (TRUE)
3021 {
3022 /* Pick which kind of WOW mode we want to run in */
3023 VdmBinaryType = (dwCreationFlags &
3026
3027 /* Get all the VDM settings and current status */
3028 Status = BaseCheckVDM(VdmBinaryType,
3029 lpApplicationName,
3030 lpCommandLine,
3031 lpCurrentDirectory,
3032 &VdmAnsiEnv,
3033 &CsrMsg[1],
3034 &VdmTask,
3035 dwCreationFlags,
3036 &StartupInfo,
3037 hUserToken);
3038
3039 /* If it worked, no need to try again */
3040 if (NT_SUCCESS(Status)) break;
3041
3042 /* Check if it's disallowed or if it's our second time */
3044 if ((Status == STATUS_VDM_DISALLOWED) ||
3045 (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW) ||
3047 {
3048 /* Fail the call -- we won't try again */
3049 DPRINT1("VDM message failure for WOW: %lx\n", Status);
3050 Result = FALSE;
3051 goto Quickie;
3052 }
3053
3054 /* Try one more time, but with a separate WOW instance */
3055 dwCreationFlags |= CREATE_SEPARATE_WOW_VDM;
3056 }
3057
3058 /* Check which VDM state we're currently in */
3059 switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
3061 VDM_READY))
3062 {
3063 case VDM_NOT_LOADED:
3064 /* VDM is not fully loaded, so not that much to undo */
3065 VdmUndoLevel = VDM_UNDO_PARTIAL;
3066
3067 /* Reset VDM reserve if needed */
3068 if (UseVdmReserve) VdmReserve = 1;
3069
3070 /* Get the required parameters and names for launch */
3071 Result = BaseGetVdmConfigInfo(lpCommandLine,
3072 VdmTask,
3073 VdmBinaryType,
3074 &VdmString,
3075 &VdmReserve);
3076 if (!Result)
3077 {
3078 DPRINT1("VDM Configuration failed for WOW\n");
3080 goto Quickie;
3081 }
3082
3083 /* Update the command-line with the VDM one instead */
3084 lpCommandLine = VdmString.Buffer;
3085 lpApplicationName = NULL;
3086
3087 /* We don't want a console, detachment, nor a window */
3088 dwCreationFlags |= CREATE_NO_WINDOW;
3089 dwCreationFlags &= ~(CREATE_NEW_CONSOLE | DETACHED_PROCESS);
3090
3091 /* Force feedback on */
3092 StartupInfo.dwFlags |= STARTF_FORCEONFEEDBACK;
3093 break;
3094
3095
3096 case VDM_READY:
3097 /* VDM is ready, so we have to undo everything */
3098 VdmUndoLevel = VDM_UNDO_REUSE;
3099
3100 /* Check if CSRSS wants us to wait on VDM */
3101 VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
3102 break;
3103
3104 case VDM_NOT_READY:
3105 /* Something is wrong with VDM, we'll fail the call */
3106 DPRINT1("VDM is not ready for WOW\n");
3108 Result = FALSE;
3109 goto Quickie;
3110
3111 default:
3112 break;
3113 }
3114
3115 /* Since to get NULL, we allocate from 0x1, account for this */
3116 VdmReserve--;
3117
3118 /* This implies VDM is ready, so skip everything else */
3119 if (VdmWaitObject) goto VdmShortCircuit;
3120
3121 /* Don't inherit handles since we're doing VDM now */
3122 bInheritHandles = FALSE;
3123
3124 /* Had the user passed in environment? If so, destroy it */
3125 if ((lpEnvironment) &&
3126 !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
3127 {
3128 RtlDestroyEnvironment(lpEnvironment);
3129 }
3130
3131 /* We've already done all these checks, don't do them again */
3132 SkipSaferAndAppCompat = TRUE;
3133 goto AppNameRetry;
3134 }
3135
3136 // There is no break here on purpose, so FORCEDOS drops down!
3137 }
3138
3142 {
3143 /* We're launching an executable application */
3144 BinarySubType = BINARY_TYPE_EXE;
3145
3146 /* We can drop here from other "cases" above too, so check */
3149 (BinarySubType = BaseIsDosApplication(&PathName, Status)))
3150 {
3151 /* We're launching a DOS application */
3152 VdmBinaryType = BINARY_TYPE_DOS;
3153
3154 /* Based on the caller environment, create a VDM one */
3155 Result = BaseCreateVDMEnvironment(lpEnvironment,
3156 &VdmAnsiEnv,
3157 &VdmUnicodeEnv);
3158 if (!Result)
3159 {
3160 DPRINT1("VDM environment for DOS failed\n");
3161 goto Quickie;
3162 }
3163
3164 /* Check the current state of the VDM subsystem */
3165 Status = BaseCheckVDM(VdmBinaryType | BinarySubType,
3166 lpApplicationName,
3167 lpCommandLine,
3168 lpCurrentDirectory,
3169 &VdmAnsiEnv,
3170 &CsrMsg[1],
3171 &VdmTask,
3172 dwCreationFlags,
3173 &StartupInfo,
3174 NULL);
3175 if (!NT_SUCCESS(Status))
3176 {
3177 /* Failed to inquire about VDM, fail the call */
3178 DPRINT1("VDM message failure for DOS: %lx\n", Status);
3180 Result = FALSE;
3181 goto Quickie;
3182 };
3183
3184 /* Handle possible VDM states */
3185 switch (CheckVdmMsg->VDMState & (VDM_NOT_LOADED |
3187 VDM_READY))
3188 {
3189 case VDM_NOT_LOADED:
3190 /* If VDM is not loaded, we'll do a partial undo */
3191 VdmUndoLevel = VDM_UNDO_PARTIAL;
3192
3193 /* A VDM process can't also be detached, so fail */
3194 if (dwCreationFlags & DETACHED_PROCESS)
3195 {
3196 DPRINT1("Detached process but no VDM, not allowed\n");
3198 return FALSE;
3199 }
3200
3201 /* Get the required parameters and names for launch */
3202 Result = BaseGetVdmConfigInfo(lpCommandLine,
3203 VdmTask,
3204 VdmBinaryType,
3205 &VdmString,
3206 &VdmReserve);
3207 if (!Result)
3208 {
3209 DPRINT1("VDM Configuration failed for DOS\n");
3211 goto Quickie;
3212 }
3213
3214 /* Update the command-line to launch VDM instead */
3215 lpCommandLine = VdmString.Buffer;
3216 lpApplicationName = NULL;
3217 break;
3218
3219 case VDM_READY:
3220 /* VDM is ready, so we have to undo everything */
3221 VdmUndoLevel = VDM_UNDO_REUSE;
3222
3223 /* Check if CSRSS wants us to wait on VDM */
3224 VdmWaitObject = CheckVdmMsg->WaitObjectForParent;
3225 break;
3226
3227 case VDM_NOT_READY:
3228 /* Something is wrong with VDM, we'll fail the call */
3229 DPRINT1("VDM is not ready for DOS\n");
3231 Result = FALSE;
3232 goto Quickie;
3233
3234 default:
3235 break;
3236 }
3237
3238 /* Since to get NULL, we allocate from 0x1, account for this */
3239 VdmReserve--;
3240
3241 /* This implies VDM is ready, so skip everything else */
3242 if (VdmWaitObject) goto VdmShortCircuit;
3243
3244 /* Don't inherit handles since we're doing VDM now */
3245 bInheritHandles = FALSE;
3246
3247 /* Had the user passed in environment? If so, destroy it */
3248 if ((lpEnvironment) &&
3249 !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
3250 {
3251 RtlDestroyEnvironment(lpEnvironment);
3252 }
3253
3254 /* Use our VDM Unicode environment instead */
3255 lpEnvironment = VdmUnicodeEnv.Buffer;
3256 }
3257 else
3258 {
3259 /* It's a batch file, get the extension */
3260 ExtBuffer = &PathName.Buffer[PathName.Length / sizeof(WCHAR) - 4];
3261
3262 /* Make sure the extensions are correct */
3263 if ((PathName.Length < (4 * sizeof(WCHAR))) ||
3264 ((_wcsnicmp(ExtBuffer, L".bat", 4)) &&
3265 (_wcsnicmp(ExtBuffer, L".cmd", 4))))
3266 {
3267 DPRINT1("'%wZ': Invalid EXE, and not a batch or script file\n", &PathName);
3269 Result = FALSE;
3270 goto Quickie;
3271 }
3272
3273 /* Check if we need to account for quotes around the path */
3274 CmdQuoteLength = CmdLineIsAppName || HasQuotes;
3275 if (!CmdLineIsAppName)
3276 {
3277 if (HasQuotes) CmdQuoteLength++;
3278 }
3279 else
3280 {
3281 CmdQuoteLength++;
3282 }
3283
3284 /* Calculate the length of the command line */
3285 CmdLineLength = wcslen(lpCommandLine);
3286 CmdLineLength += wcslen(CMD_STRING);
3287 CmdLineLength += CmdQuoteLength + sizeof(ANSI_NULL);
3288 CmdLineLength *= sizeof(WCHAR);
3289
3290 /* Allocate space for the new command line */
3291 AnsiCmdCommand = RtlAllocateHeap(RtlGetProcessHeap(),
3292 0,
3293 CmdLineLength);
3294 if (!AnsiCmdCommand)
3295 {
3297 Result = FALSE;
3298 goto Quickie;
3299 }
3300
3301 /* Build it */
3302 wcscpy(AnsiCmdCommand, CMD_STRING);
3303 if ((CmdLineIsAppName) || (HasQuotes))
3304 {
3305 wcscat(AnsiCmdCommand, L"\"");
3306 }
3307 wcscat(AnsiCmdCommand, lpCommandLine);
3308 if ((CmdLineIsAppName) || (HasQuotes))
3309 {
3310 wcscat(AnsiCmdCommand, L"\"");
3311 }
3312
3313 /* Create it as a Unicode String */
3314 RtlInitUnicodeString(&DebuggerString, AnsiCmdCommand);
3315
3316 /* Set the command line to this */
3317 lpCommandLine = DebuggerString.Buffer;
3318 lpApplicationName = NULL;
3319 DPRINT1("Retrying with: %S\n", lpCommandLine);
3320 }
3321
3322 /* We've already done all these checks, don't do them again */
3323 SkipSaferAndAppCompat = TRUE;
3324 goto AppNameRetry;
3325 }
3326
3328 {
3329 /* 64-bit binaries are not allowed to run on 32-bit ReactOS */
3330 DPRINT1("64-bit binary, failing\n");
3332 Result = FALSE;
3333 goto Quickie;
3334 }
3335
3337 {
3338 /* Set the correct last error for this */
3339 DPRINT1("File is offline, failing\n");
3341 break;
3342 }
3343
3344 default:
3345 {
3346 /* Any other error, convert it to a generic Win32 error */
3347 if (!NT_SUCCESS(Status))
3348 {
3349 DPRINT1("Failed to create section: %lx\n", Status);
3351 Result = FALSE;
3352 goto Quickie;
3353 }
3354
3355 /* Otherwise, this must be success */
3357 break;
3358 }
3359 }
3360
3361 /* Is this not a WOW application, but a WOW32 VDM was requested for it? */
3362 if (!(IsWowApp) && (dwCreationFlags & CREATE_SEPARATE_WOW_VDM))
3363 {
3364 /* Ignore the nonsensical request */
3365 dwCreationFlags &= ~CREATE_SEPARATE_WOW_VDM;
3366 }
3367
3368 /* Did we already check information for the section? */
3369 if (!QuerySection)
3370 {
3371 /* Get some information about the executable */
3372 Status = NtQuerySection(SectionHandle,
3374 &ImageInformation,
3375 sizeof(ImageInformation),
3376 NULL);
3377 if (!NT_SUCCESS(Status))
3378 {
3379 /* We failed, bail out */
3380 DPRINT1("Section query failed\n");
3382 Result = FALSE;
3383 goto Quickie;
3384 }
3385
3386 /* Don't check this later */
3387 QuerySection = TRUE;
3388 }
3389
3390 /* Check if this was linked as a DLL */
3391 if (ImageInformation.ImageCharacteristics & IMAGE_FILE_DLL)
3392 {
3393 /* These aren't valid images to try to execute! */
3394 DPRINT1("Trying to launch a DLL, failing\n");
3396 Result = FALSE;
3397 goto Quickie;
3398 }
3399
3400 /* Don't let callers pass in this flag -- we'll only get it from IFEO */
3401 Flags &= ~PROCESS_CREATE_FLAGS_LARGE_PAGES;
3402
3403 /* Clear the IFEO-missing flag, before we know for sure... */
3404 ParameterFlags &= ~2;
3405
3406 /* If the process is being debugged, only read IFEO if the PEB says so */
3407 if (!(dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS)) ||
3409 {
3410 /* Let's do this! Attempt to open IFEO */
3411 IFEOStatus = LdrOpenImageFileOptionsKey(&PathName, 0, &KeyHandle);
3412 if (!NT_SUCCESS(IFEOStatus))
3413 {
3414 /* We failed, set the flag so we store this in the parameters */
3415 if (IFEOStatus == STATUS_OBJECT_NAME_NOT_FOUND) ParameterFlags |= 2;
3416 }
3417 else
3418 {
3419 /* Was this our first time going through this path? */
3420 if (!DebuggerCmdLine)
3421 {
3422 /* Allocate a buffer for the debugger path */
3423 DebuggerCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
3424 0,
3425 MAX_PATH * sizeof(WCHAR));
3426 if (!DebuggerCmdLine)
3427 {
3428 /* Close IFEO on failure */
3429 IFEOStatus = NtClose(KeyHandle);
3430 ASSERT(NT_SUCCESS(IFEOStatus));
3431
3432 /* Fail the call */
3434 Result = FALSE;
3435 goto Quickie;
3436 }
3437 }
3438
3439 /* Now query for the debugger */
3441 L"Debugger",
3442 REG_SZ,
3443 DebuggerCmdLine,
3444 MAX_PATH * sizeof(WCHAR),
3445 &ResultSize);
3446 if (!(NT_SUCCESS(IFEOStatus)) ||
3447 (ResultSize < sizeof(WCHAR)) ||
3448 (DebuggerCmdLine[0] == UNICODE_NULL))
3449 {
3450 /* If it's not there, or too small, or invalid, ignore it */
3451 RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
3452 DebuggerCmdLine = NULL;
3453 }
3454
3455 /* Also query if we should map with large pages */
3457 L"UseLargePages",
3458 REG_DWORD,
3459 &UseLargePages,
3460 sizeof(UseLargePages),
3461 NULL);
3462 if ((NT_SUCCESS(IFEOStatus)) && (UseLargePages))
3463 {
3464 /* Do it! This is the only way this flag can be set */
3466 }
3467
3468 /* We're done with IFEO, can close it now */
3469 IFEOStatus = NtClose(KeyHandle);
3470 ASSERT(NT_SUCCESS(IFEOStatus));
3471 }
3472 }
3473
3474 /* Make sure the image was compiled for this processor */
3475 if ((ImageInformation.Machine < SharedUserData->ImageNumberLow) ||
3476 (ImageInformation.Machine > SharedUserData->ImageNumberHigh))
3477 {
3478 /* It was not -- raise a hard error */
3479 ErrorResponse = ResponseOk;
3480 ErrorParameters[0] = (ULONG_PTR)&PathName;
3482 1,
3483 1,
3484 ErrorParameters,
3485 OptionOk,
3486 &ErrorResponse);
3488 {
3489 /* If it's really old, return this error */
3491 }
3492 else
3493 {
3494 /* Otherwise, return a more modern error */
3496 }
3497
3498 /* Go to the failure path */
3499 DPRINT1("Invalid image architecture: %lx\n", ImageInformation.Machine);
3500 Result = FALSE;
3501 goto Quickie;
3502 }
3503
3504 /* Check if this isn't a Windows image */
3505 if ((ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_GUI) &&
3506 (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_WINDOWS_CUI))
3507 {
3508 /* Get rid of section-related information since we'll retry */
3509 NtClose(SectionHandle);
3510 SectionHandle = NULL;
3511 QuerySection = FALSE;
3512
3513 /* The only other non-Windows image type we support here is POSIX */
3514 if (ImageInformation.SubSystemType != IMAGE_SUBSYSTEM_POSIX_CUI)
3515 {
3516 /* Bail out if it's something else */
3518 Result = FALSE;
3519 goto Quickie;
3520 }
3521
3522 /* Now build the command-line to have posix launch this image */
3523 Result = BuildSubSysCommandLine(L"POSIX /P ",
3524 lpApplicationName,
3525 lpCommandLine,
3526 &DebuggerString);
3527 if (!Result)
3528 {
3529 /* Bail out if that failed */
3530 DPRINT1("Subsystem command line failed\n");
3531 goto Quickie;
3532 }
3533
3534 /* And re-try launching the process, with the new command-line now */
3535 lpCommandLine = DebuggerString.Buffer;
3536 lpApplicationName = NULL;
3537
3538 /* We've already done all these checks, don't do them again */
3539 SkipSaferAndAppCompat = TRUE;
3540 DPRINT1("Retrying with: %S\n", lpCommandLine);
3541 goto AppNameRetry;
3542 }
3543
3544 /* Was this image built for a version of Windows whose images we can run? */
3546 ImageInformation.SubSystemMinorVersion);
3547 if (!Result)
3548 {
3549 /* It was not, bail out */
3550 DPRINT1("Invalid subsystem version: %hu.%hu\n",
3551 ImageInformation.SubSystemMajorVersion,
3552 ImageInformation.SubSystemMinorVersion);
3554 goto Quickie;
3555 }
3556
3557 /* Check if there is a debugger associated with the application */
3558 if (DebuggerCmdLine)
3559 {
3560 /* Get the length of the command line */
3561 n = wcslen(lpCommandLine);
3562 if (!n)
3563 {
3564 /* There's no command line, use the application name instead */
3565 lpCommandLine = (LPWSTR)lpApplicationName;
3566 n = wcslen(lpCommandLine);
3567 }
3568
3569 /* Protect against overflow */
3571 {
3573 Result = FALSE;
3574 goto Quickie;
3575 }
3576
3577 /* Now add the length of the debugger command-line */
3578 n += wcslen(DebuggerCmdLine);
3579
3580 /* Again make sure we don't overflow */
3582 {
3584 Result = FALSE;
3585 goto Quickie;
3586 }
3587
3588 /* Account for the quotes and space between the two */
3589 n += sizeof("\" \"") - sizeof(ANSI_NULL);
3590
3591 /* Convert to bytes, and make sure we don't overflow */
3592 n *= sizeof(WCHAR);
3594 {
3596 Result = FALSE;
3597 goto Quickie;
3598 }
3599
3600 /* Allocate space for the string */
3601 DebuggerString.Buffer = RtlAllocateHeap(RtlGetProcessHeap(), 0, n);
3602 if (!DebuggerString.Buffer)
3603 {
3605 Result = FALSE;
3606 goto Quickie;
3607 }
3608
3609 /* Set the length */
3610 RtlInitEmptyUnicodeString(&DebuggerString,
3611 DebuggerString.Buffer,
3612 (USHORT)n);
3613
3614 /* Now perform the command line creation */
3615 ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString,
3616 DebuggerCmdLine);
3617 ASSERT(NT_SUCCESS(ImageDbgStatus));
3618 ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, L" ");
3619 ASSERT(NT_SUCCESS(ImageDbgStatus));
3620 ImageDbgStatus = RtlAppendUnicodeToString(&DebuggerString, lpCommandLine);
3621 ASSERT(NT_SUCCESS(ImageDbgStatus));
3622
3623 /* Make sure it all looks nice */
3624 DbgPrint("BASE: Calling debugger with '%wZ'\n", &DebuggerString);
3625
3626 /* Update the command line and application name */
3627 lpCommandLine = DebuggerString.Buffer;
3628 lpApplicationName = NULL;
3629
3630 /* Close all temporary state */
3631 NtClose(SectionHandle);
3632 SectionHandle = NULL;
3633 QuerySection = FALSE;
3634
3635 /* Free all temporary memory */
3636 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
3637 NameBuffer = NULL;
3638 RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
3639 FreeBuffer = NULL;
3640 RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
3641 DebuggerCmdLine = NULL;
3642 DPRINT1("Retrying with: %S\n", lpCommandLine);
3643 goto AppNameRetry;
3644 }
3645
3646 /* Initialize the process object attributes */
3647 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
3648 lpProcessAttributes,
3649 NULL);
3650 if ((hUserToken) && (lpProcessAttributes))
3651 {
3652 /* Augment them with information from the user */
3653
3654 LocalProcessAttributes = *lpProcessAttributes;
3655 LocalProcessAttributes.lpSecurityDescriptor = NULL;
3656 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
3657 &LocalProcessAttributes,
3658 NULL);
3659 }
3660
3661 /* Check if we're going to be debugged */
3662 if (dwCreationFlags & DEBUG_PROCESS)
3663 {
3664 /* Set process flag */
3666 }
3667
3668 /* Check if we're going to be debugged */
3669 if (dwCreationFlags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
3670 {
3671 /* Connect to DbgUi */
3673 if (!NT_SUCCESS(Status))
3674 {
3675 DPRINT1("Failed to connect to DbgUI!\n");
3677 Result = FALSE;
3678 goto Quickie;
3679 }
3680
3681 /* Get the debug object */
3682 DebugHandle = DbgUiGetThreadDebugObject();
3683
3684 /* Check if only this process will be debugged */
3685 if (dwCreationFlags & DEBUG_ONLY_THIS_PROCESS)
3686 {
3687 /* Set process flag */
3689 }
3690 }
3691
3692 /* Set inherit flag */
3693 if (bInheritHandles) Flags |= PROCESS_CREATE_FLAGS_INHERIT_HANDLES;
3694
3695 /* Check if the process should be created with large pages */
3696 HavePrivilege = FALSE;
3697 PrivilegeState = NULL;
3699 {
3700 /* Acquire the required privilege so that the kernel won't fail the call */
3701 PrivilegeValue = SE_LOCK_MEMORY_PRIVILEGE;
3702 Status = RtlAcquirePrivilege(&PrivilegeValue, 1, 0, &PrivilegeState);
3703 if (NT_SUCCESS(Status))
3704 {
3705 /* Remember to release it later */
3706 HavePrivilege = TRUE;
3707 }
3708 }
3709
3710 /* Save the current TIB value since kernel overwrites it to store PEB */
3711 TibValue = Teb->NtTib.ArbitraryUserPointer;
3712
3713 /* Tell the kernel to create the process */
3718 Flags,
3719 SectionHandle,
3720 DebugHandle,
3721 NULL,
3722 InJob);
3723
3724 /* Load the PEB address from the hacky location where the kernel stores it */
3725 RemotePeb = Teb->NtTib.ArbitraryUserPointer;
3726
3727 /* And restore the old TIB value */
3728 Teb->NtTib.ArbitraryUserPointer = TibValue;
3729
3730 /* Release the large page privilege if we had acquired it */
3731 if (HavePrivilege) RtlReleasePrivilege(PrivilegeState);
3732
3733 /* And now check if the kernel failed to create the process */
3734 if (!NT_SUCCESS(Status))
3735 {
3736 /* Go to failure path */
3737 DPRINT1("Failed to create process: %lx\n", Status);
3739 Result = FALSE;
3740 goto Quickie;
3741 }
3742
3743 /* Check if there is a priority class to set */
3744 if (PriorityClass.PriorityClass)
3745 {
3746 /* Reset current privilege state */
3747 RealTimePrivilegeState = NULL;
3748
3749 /* Is realtime priority being requested? */
3751 {
3752 /* Check if the caller has real-time access, and enable it if so */
3753 RealTimePrivilegeState = BasepIsRealtimeAllowed(TRUE);
3754 }
3755
3756 /* Set the new priority class and release the privilege */
3759 &PriorityClass,
3760 sizeof(PROCESS_PRIORITY_CLASS));
3761 if (RealTimePrivilegeState) RtlReleasePrivilege(RealTimePrivilegeState);
3762
3763 /* Check if we failed to set the priority class */
3764 if (!NT_SUCCESS(Status))
3765 {
3766 /* Bail out on failure */
3767 DPRINT1("Failed to set priority class: %lx\n", Status);
3769 Result = FALSE;
3770 goto Quickie;
3771 }
3772 }
3773
3774 /* Check if the caller wants the default error mode */
3775 if (dwCreationFlags & CREATE_DEFAULT_ERROR_MODE)
3776 {
3777 /* Set Error Mode to only fail on critical errors */
3778 HardErrorMode = SEM_FAILCRITICALERRORS;
3781 &HardErrorMode,
3782 sizeof(ULONG));
3783 }
3784
3785 /* Check if this was a VDM binary */
3786 if (VdmBinaryType)
3787 {
3788 /* Update VDM by telling it the process has now been created */
3789 VdmWaitObject = ProcessHandle;
3791 &VdmWaitObject,
3792 VdmTask,
3793 VdmBinaryType);
3794
3795 if (!Result)
3796 {
3797 /* Bail out on failure */
3798 DPRINT1("Failed to update VDM with wait object\n");
3799 VdmWaitObject = NULL;
3800 goto Quickie;
3801 }
3802
3803 /* At this point, a failure means VDM has to undo all the state */
3804 VdmUndoLevel |= VDM_UNDO_FULL;
3805 }
3806
3807 /* Check if VDM needed reserved low-memory */
3808 if (VdmReserve)
3809 {
3810 /* Reserve the requested allocation */
3811 RegionSize = VdmReserve;
3813 &BaseAddress,
3814 0,
3815 &RegionSize,
3818 if (!NT_SUCCESS(Status))
3819 {
3820 /* Bail out on failure */
3821 DPRINT1("Failed to reserve memory for VDM: %lx\n", Status);
3823 Result = FALSE;
3824 goto Quickie;
3825 }
3826
3827 VdmReserve = (ULONG)RegionSize;
3828 }
3829
3830 /* Check if we've already queried information on the section */
3831 if (!QuerySection)
3832 {
3833 /* We haven't, so get some information about the executable */
3834 Status = NtQuerySection(SectionHandle,
3836 &ImageInformation,
3837 sizeof(ImageInformation),
3838 NULL);
3839 if (!NT_SUCCESS(Status))
3840 {
3841 /* Bail out on failure */
3842 DPRINT1("Failed to query section: %lx\n", Status);
3844 Result = FALSE;
3845 goto Quickie;
3846 }
3847
3848 /* If we encounter a restart, don't re-query this information again */
3849 QuerySection = TRUE;
3850 }
3851
3852 /* Do we need to apply SxS to this image? (On x86 this flag is set by PeFmtCreateSection) */
3854 {
3855 /* Too bad, we don't support this yet */
3856 DPRINT("Image should receive SxS Fusion Isolation\n");
3857 }
3858
3859 /* There's some SxS flag that we need to set if fusion flags have 1 set */
3860 if (FusionFlags & 1) CreateProcessMsg->Sxs.Flags |= 0x10;
3861
3862 /* Check if we have a current directory */
3863 if (lpCurrentDirectory)
3864 {
3865 /* Allocate a buffer so we can keep a Unicode copy */
3866 DPRINT("Current directory: %S\n", lpCurrentDirectory);
3867 CurrentDirectory = RtlAllocateHeap(RtlGetProcessHeap(),
3868 0,
3869 (MAX_PATH * sizeof(WCHAR)) +
3870 sizeof(UNICODE_NULL));
3871 if (!CurrentDirectory)
3872 {
3873 /* Bail out if this failed */
3875 Result = FALSE;
3876 goto Quickie;
3877 }
3878
3879 /* Get the length in Unicode */
3880 Length = GetFullPathNameW(lpCurrentDirectory,
3881 MAX_PATH,
3883 &FilePart);
3884 if (Length > MAX_PATH)
3885 {
3886 /* The directory is too long, so bail out */
3888 Result = FALSE;
3889 goto Quickie;
3890 }
3891
3892 /* Make sure the directory is actually valid */
3893 FileAttribs = GetFileAttributesW(CurrentDirectory);
3894 if ((FileAttribs == INVALID_FILE_ATTRIBUTES) ||
3895 !(FileAttribs & FILE_ATTRIBUTE_DIRECTORY))
3896 {
3897 /* It isn't, so bail out */
3898 DPRINT1("Current directory is invalid\n");
3900 Result = FALSE;
3901 goto Quickie;
3902 }
3903 }
3904
3905 /* Insert quotes if needed */
3906 if ((QuotesNeeded) || (CmdLineIsAppName))
3907 {
3908 /* Allocate our buffer, plus enough space for quotes and a NULL */
3909 QuotedCmdLine = RtlAllocateHeap(RtlGetProcessHeap(),
3910 0,
3911 (wcslen(lpCommandLine) * sizeof(WCHAR)) +
3912 (2 * sizeof(L'\"') + sizeof(UNICODE_NULL)));
3913 if (QuotedCmdLine)
3914 {
3915 /* Copy the first quote */
3916 wcscpy(QuotedCmdLine, L"\"");
3917
3918 /* Save the current null-character */
3919 if (QuotesNeeded)
3920 {
3921 SaveChar = *NullBuffer;
3922 *NullBuffer = UNICODE_NULL;
3923 }
3924
3925 /* Copy the command line and the final quote */
3926 wcscat(QuotedCmdLine, lpCommandLine);
3927 wcscat(QuotedCmdLine, L"\"");
3928
3929 /* Copy the null-char back */
3930 if (QuotesNeeded)
3931 {
3932 *NullBuffer = SaveChar;
3933 wcscat(QuotedCmdLine, NullBuffer);
3934 }
3935 }
3936 else
3937 {
3938 /* We can't put quotes around the thing, so try it anyway */
3939 if (QuotesNeeded) QuotesNeeded = FALSE;
3940 if (CmdLineIsAppName) CmdLineIsAppName = FALSE;
3941 }
3942 }
3943
3944 /* Use isolation if needed */
3945 if (CreateProcessMsg->Sxs.Flags & 1) ParameterFlags |= 1;
3946
3947 /* Set the new command-line if needed */
3948 if ((QuotesNeeded) || (CmdLineIsAppName)) lpCommandLine = QuotedCmdLine;
3949
3950 /* Call the helper function in charge of RTL_USER_PROCESS_PARAMETERS */
3951 Result = BasePushProcessParameters(ParameterFlags,
3953 RemotePeb,
3954 lpApplicationName,
3956 lpCommandLine,
3957 lpEnvironment,
3958 &StartupInfo,
3959 dwCreationFlags | NoWindow,
3960 bInheritHandles,
3961 IsWowApp ? IMAGE_SUBSYSTEM_WINDOWS_GUI: 0,
3962 AppCompatData,
3963 AppCompatDataSize);
3964 if (!Result)
3965 {
3966 /* The remote process would have an undefined state, so fail the call */
3967 DPRINT1("BasePushProcessParameters failed\n");
3968 goto Quickie;
3969 }
3970
3971 /* Free the VDM command line string as it's no longer needed */
3972 RtlFreeUnicodeString(&VdmString);
3973 VdmString.Buffer = NULL;
3974
3975 /* Non-VDM console applications usually inherit handles unless specified */
3976 if (!(VdmBinaryType) &&
3977 !(bInheritHandles) &&
3978 !(StartupInfo.dwFlags & STARTF_USESTDHANDLES) &&
3979 !(dwCreationFlags & (CREATE_NO_WINDOW |
3981 DETACHED_PROCESS)) &&
3982 (ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_CUI))
3983 {
3984 /* Get the remote parameters */
3986 &RemotePeb->ProcessParameters,
3987 &ProcessParameters,
3989 NULL);
3990 if (NT_SUCCESS(Status))
3991 {
3992 /* Duplicate standard input unless it's a console handle */
3994 {
3997 &ProcessParameters->StandardInput);
3998 }
3999
4000 /* Duplicate standard output unless it's a console handle */
4002 {
4005 &ProcessParameters->StandardOutput);
4006 }
4007
4008 /* Duplicate standard error unless it's a console handle */
4010 {
4013 &ProcessParameters->StandardError);
4014 }
4015 }
4016 }
4017
4018 /* Create the Thread's Stack */
4019 StackSize = max(256 * 1024, ImageInformation.MaximumStackSize);
4021 ImageInformation.CommittedStackSize,
4022 StackSize,
4023 &InitialTeb);
4024 if (!NT_SUCCESS(Status))
4025 {
4026 DPRINT1("Creating the thread stack failed: %lx\n", Status);
4028 Result = FALSE;
4029 goto Quickie;
4030 }
4031
4032 /* Create the Thread's Context */
4034 RemotePeb,
4035 ImageInformation.TransferAddress,
4036 InitialTeb.StackBase,
4037 0);
4038
4039 /* Convert the thread attributes */
4040 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
4041 lpThreadAttributes,
4042 NULL);
4043 if ((hUserToken) && (lpThreadAttributes))
4044 {
4045 /* If the caller specified a user token, zero the security descriptor */
4046 LocalThreadAttributes = *lpThreadAttributes;
4047 LocalThreadAttributes.lpSecurityDescriptor = NULL;
4048 ObjectAttributes = BaseFormatObjectAttributes(&LocalObjectAttributes,
4049 &LocalThreadAttributes,
4050 NULL);
4051 }
4052
4053 /* Create the Kernel Thread Object */
4054 Status = NtCreateThread(&ThreadHandle,
4058 &ClientId,
4059 &Context,
4060 &InitialTeb,
4061 TRUE);
4062 if (!NT_SUCCESS(Status))
4063 {
4064 /* A process is not allowed to exist without a main thread, so fail */
4065 DPRINT1("Creating the main thread failed: %lx\n", Status);
4067 Result = FALSE;
4068 goto Quickie;
4069 }
4070
4071 /* Begin filling out the CSRSS message, first with our IDs and handles */
4072 CreateProcessMsg->ProcessHandle = ProcessHandle;
4073 CreateProcessMsg->ThreadHandle = ThreadHandle;
4074 CreateProcessMsg->ClientId = ClientId;
4075
4076 /* Write the remote PEB address and clear it locally, we no longer use it */
4077 CreateProcessMsg->PebAddressNative = RemotePeb;
4078#ifdef _WIN64
4079 DPRINT("TODO: WOW64 is not supported yet\n");
4080 CreateProcessMsg->PebAddressWow64 = 0;
4081#else
4082 CreateProcessMsg->PebAddressWow64 = (ULONG)RemotePeb;
4083#endif
4084 RemotePeb = NULL;
4085
4086 /* Now check what kind of architecture this image was made for */
4087 switch (ImageInformation.Machine)
4088 {
4089 /* IA32, IA64 and AMD64 are supported in Server 2003 */
4092 break;
4095 break;
4098 break;
4099
4100 /* Anything else results in image unknown -- but no failure */
4101 default:
4102 DbgPrint("kernel32: No mapping for ImageInformation.Machine == %04x\n",
4103 ImageInformation.Machine);
4105 break;
4106 }
4107
4108 /* Write the input creation flags except any debugger-related flags */
4109 CreateProcessMsg->CreationFlags = dwCreationFlags &
4111
4112 /* CSRSS needs to know if this is a GUI app or not */
4113 if ((ImageInformation.SubSystemType == IMAGE_SUBSYSTEM_WINDOWS_GUI) ||
4114 (IsWowApp))
4115 {
4116 /*
4117 * For GUI apps we turn on the 2nd bit. This allow CSRSS server dlls
4118 * (basesrv in particular) to know whether or not this is a GUI or a
4119 * TUI application.
4120 */
4121 AddToHandle(CreateProcessMsg->ProcessHandle, 2);
4122
4123 /* Also check if the parent is also a GUI process */
4125 if ((NtHeaders) &&
4127 {
4128 /* Let it know that it should display the hourglass mouse cursor */
4129 AddToHandle(CreateProcessMsg->ProcessHandle, 1);
4130 }
4131 }
4132
4133 /* For all apps, if this flag is on, the hourglass mouse cursor is shown.
4134 * Likewise, the opposite holds as well, and no-feedback has precedence. */
4135 if (StartupInfo.dwFlags & STARTF_FORCEONFEEDBACK)
4136 {
4137 AddToHandle(CreateProcessMsg->ProcessHandle, 1);
4138 }
4139 if (StartupInfo.dwFlags & STARTF_FORCEOFFFEEDBACK)
4140 {
4141 RemoveFromHandle(CreateProcessMsg->ProcessHandle, 1);
4142 }
4143
4144 /* Also store which kind of VDM app (if any) this is */
4145 CreateProcessMsg->VdmBinaryType = VdmBinaryType;
4146
4147 /* And if it really is a VDM app... */
4148 if (VdmBinaryType)
4149 {
4150 /* Store the VDM console handle (none if inherited or WOW app) and the task ID */
4151 CreateProcessMsg->hVDM = VdmTask ? NULL : Peb->ProcessParameters->ConsoleHandle;
4152 CreateProcessMsg->VdmTask = VdmTask;
4153 }
4154 else if (VdmReserve)
4155 {
4156 /* Extended VDM, set a flag */
4157 CreateProcessMsg->VdmBinaryType |= BINARY_TYPE_WOW_EX;
4158 }
4159
4160 /* Check if there's side-by-side assembly data associated with the process */
4161 if (CreateProcessMsg->Sxs.Flags)
4162 {
4163 /* This should not happen in ReactOS yet */
4164 DPRINT1("This is an SxS Message -- should not happen yet\n");
4167 Result = FALSE;
4168 goto Quickie;
4169 }
4170
4171 /* We are finally ready to call CSRSS to tell it about our new process! */
4173 CaptureBuffer,
4176 sizeof(*CreateProcessMsg));
4177
4178 /* CSRSS has returned, free the capture buffer now if we had one */
4179 if (CaptureBuffer)
4180 {
4181 CsrFreeCaptureBuffer(CaptureBuffer);
4182 CaptureBuffer = NULL;
4183 }
4184
4185 /* Check if CSRSS failed to accept ownership of the new Windows process */
4186 if (!NT_SUCCESS(CsrMsg[0].Status))
4187 {
4188 /* Terminate the process and enter failure path with the CSRSS status */
4189 DPRINT1("Failed to tell csrss about new process\n");
4190 BaseSetLastNTError(CsrMsg[0].Status);
4192 Result = FALSE;
4193 goto Quickie;
4194 }
4195
4196 /* Check if we have a token due to Authz/Safer, not passed by the user */
4197 if ((TokenHandle) && !(hUserToken))
4198 {
4199 /* Replace the process and/or thread token with the one from Safer */
4202 ThreadHandle);
4203 if (!NT_SUCCESS(Status))
4204 {
4205 /* If this failed, kill the process and enter the failure path */
4206 DPRINT1("Failed to update process token: %lx\n", Status);
4209 Result = FALSE;
4210 goto Quickie;
4211 }
4212 }
4213
4214 /* Check if a job was associated with this process */
4215 if (JobHandle)
4216 {
4217 /* Bind the process and job together now */
4219 if (!NT_SUCCESS(Status))
4220 {
4221 /* Kill the process and enter the failure path if binding failed */
4222 DPRINT1("Failed to assign process to job: %lx\n", Status);
4225 Result = FALSE;
4226 goto Quickie;
4227 }
4228 }
4229
4230 /* Finally, resume the thread to actually get the process started */
4231 if (!(dwCreationFlags & CREATE_SUSPENDED))
4232 {
4233 NtResumeThread(ThreadHandle, &ResumeCount);
4234 }
4235
4236VdmShortCircuit:
4237 /* We made it this far, meaning we have a fully created process and thread */
4238 Result = TRUE;
4239
4240 /* Anyone doing a VDM undo should now undo everything, since we are done */
4241 if (VdmUndoLevel) VdmUndoLevel |= VDM_UNDO_COMPLETED;
4242
4243 /* Having a VDM wait object implies this must be a VDM process */
4244 if (VdmWaitObject)
4245 {
4246 /* Check if it's a 16-bit separate WOW process */
4247 if (VdmBinaryType == BINARY_TYPE_SEPARATE_WOW)
4248 {
4249 /* OR-in the special flag to indicate this, and return to caller */
4250 AddToHandle(VdmWaitObject, 2);
4251 lpProcessInformation->hProcess = VdmWaitObject;
4252
4253 /* Check if this was a re-used VDM */
4254 if (VdmUndoLevel & VDM_UNDO_REUSE)
4255 {
4256 /* No Client ID should be returned in this case */
4259 }
4260 }
4261 else
4262 {
4263 /* OR-in the special flag to indicate this is not a separate VDM,
4264 * and return the handle to the caller */
4265 AddToHandle(VdmWaitObject, 1);
4266 lpProcessInformation->hProcess = VdmWaitObject;
4267 }
4268
4269 /* Close the original process handle, since it's not needed for VDM */
4271 }
4272 else
4273 {
4274 /* This is a regular process, so return the real process handle */
4275 lpProcessInformation->hProcess = ProcessHandle;
4276 }
4277
4278 /* Return the rest of the process information based on what we have so far */
4279 lpProcessInformation->hThread = ThreadHandle;
4280 lpProcessInformation->dwProcessId = HandleToUlong(ClientId.UniqueProcess);
4281 lpProcessInformation->dwThreadId = HandleToUlong(ClientId.UniqueThread);
4282
4283 /* NULL these out here so we know to treat this as a success scenario */
4285 ThreadHandle = NULL;
4286
4287Quickie:
4288 /* Free the debugger command line if one was allocated */
4289 if (DebuggerCmdLine) RtlFreeHeap(RtlGetProcessHeap(), 0, DebuggerCmdLine);
4290
4291 /* Check if an SxS full path as queried */
4292 if (PathBuffer)
4293 {
4294 /* Reinitialize the executable path */
4295 RtlInitEmptyUnicodeString(&SxsWin32ExePath, NULL, 0);
4296 SxsWin32ExePath.Length = 0;
4297
4298 /* Free the path buffer */
4299 RtlFreeHeap(RtlGetProcessHeap(), 0, PathBuffer);
4300 }
4301
4302#if _SXS_SUPPORT_ENABLED_
4303 /* Check if this was a non-VDM process */
4304 if (!VdmBinaryType)
4305 {
4306 /* Then it must've had SxS data, so close the handles used for it */
4307 BasepSxsCloseHandles(&Handles);
4308 BasepSxsCloseHandles(&FileHandles);
4309
4310 /* Check if we built SxS byte buffers for this create process request */
4311 if (SxsConglomeratedBuffer)
4312 {
4313 /* Loop all of them */
4314 for (i = 0; i < 5; i++)
4315 {
4316 /* Check if this one was allocated */
4317 ThisBuffer = SxsStaticBuffers[i];
4318 if (ThisBuffer)
4319 {
4320 /* Get the underlying RTL_BUFFER structure */
4321 ByteBuffer = &ThisBuffer->ByteBuffer;
4322 if ((ThisBuffer != (PVOID)-8) && (ByteBuffer->Buffer))
4323 {
4324 /* Check if it was dynamic */
4325 if (ByteBuffer->Buffer != ByteBuffer->StaticBuffer)
4326 {
4327 /* Free it from the heap */
4328 FreeString.Buffer = (PWCHAR)ByteBuffer->Buffer;
4330 }
4331
4332 /* Reset the buffer to its static data */
4333 ByteBuffer->Buffer = ByteBuffer->StaticBuffer;
4334 ByteBuffer->Size = ByteBuffer->StaticSize;
4335 }
4336
4337 /* Reset the string to the static buffer */
4338 RtlInitEmptyUnicodeString(&ThisBuffer->String,
4339 (PWCHAR)ByteBuffer->StaticBuffer,
4340 ByteBuffer->StaticSize);
4341 if (ThisBuffer->String.Buffer)
4342 {
4343 /* Also NULL-terminate it */
4344 *ThisBuffer->String.Buffer = UNICODE_NULL;
4345 }
4346 }
4347 }
4348 }
4349 }
4350#endif
4351 /* Check if an environment was passed in */
4352 if ((lpEnvironment) && !(dwCreationFlags & CREATE_UNICODE_ENVIRONMENT))
4353 {
4354 /* Destroy it */
4355 RtlDestroyEnvironment(lpEnvironment);
4356
4357 /* If this was the VDM environment too, clear that as well */
4358 if (VdmUnicodeEnv.Buffer == lpEnvironment) VdmUnicodeEnv.Buffer = NULL;
4359 lpEnvironment = NULL;
4360 }
4361
4362 /* Unconditionally free all the name parsing buffers we always allocate */
4363 RtlFreeHeap(RtlGetProcessHeap(), 0, QuotedCmdLine);
4364 RtlFreeHeap(RtlGetProcessHeap(), 0, NameBuffer);
4365 RtlFreeHeap(RtlGetProcessHeap(), 0, CurrentDirectory);
4366 RtlFreeHeap(RtlGetProcessHeap(), 0, FreeBuffer);
4367
4368 /* Close open file/section handles */
4370 if (SectionHandle) NtClose(SectionHandle);
4371
4372 /* If we have a thread handle, this was a failure path */
4373 if (ThreadHandle)
4374 {
4375 /* So kill the process and close the thread handle */
4377 NtClose(ThreadHandle);
4378 }
4379
4380 /* If we have a process handle, this was a failure path, so close it */
4382
4383 /* Thread/process handles, if any, are now processed. Now close this one. */
4384 if (JobHandle) NtClose(JobHandle);
4385
4386 /* Check if we had created a token */
4387 if (TokenHandle)
4388 {
4389 /* And if the user asked for one */
4390 if (hUserToken)
4391 {
4392 /* Then return it */
4393 *hNewToken = TokenHandle;
4394 }
4395 else
4396 {
4397 /* User didn't want it, so we used it temporarily -- close it */
4399 }
4400 }
4401
4402 /* Free any temporary app compatibility data, it's no longer needed */
4403 BasepFreeAppCompatData(AppCompatData, AppCompatSxsData);
4404
4405 /* Free a few strings. The API takes care of these possibly being NULL */
4406 RtlFreeUnicodeString(&VdmString);
4407 RtlFreeUnicodeString(&DebuggerString);
4408
4409 /* Check if we had built any sort of VDM environment */
4410 if ((VdmAnsiEnv.Buffer) || (VdmUnicodeEnv.Buffer))
4411 {
4412 /* Free it */
4413 BaseDestroyVDMEnvironment(&VdmAnsiEnv, &VdmUnicodeEnv);
4414 }
4415
4416 /* Check if this was any kind of VDM application that we ended up creating */
4417 if ((VdmUndoLevel) && (!(VdmUndoLevel & VDM_UNDO_COMPLETED)))
4418 {
4419 /* Send an undo */
4421 (PHANDLE)&VdmTask,
4422 VdmUndoLevel,
4423 VdmBinaryType);
4424
4425 /* And close whatever VDM handle we were using for notifications */
4426 if (VdmWaitObject) NtClose(VdmWaitObject);
4427 }
4428
4429 /* Check if we ended up here with an allocated search path, and free it */
4430 if (SearchPath) RtlFreeHeap(RtlGetProcessHeap(), 0, SearchPath);
4431
4432 /* Finally, return the API's result */
4433 return Result;
4434}
4435
4436/*
4437 * @implemented
4438 */
4439BOOL
4440WINAPI
4442CreateProcessW(LPCWSTR lpApplicationName,
4443 LPWSTR lpCommandLine,
4444 LPSECURITY_ATTRIBUTES lpProcessAttributes,
4445 LPSECURITY_ATTRIBUTES lpThreadAttributes,
4446 BOOL bInheritHandles,
4447 DWORD dwCreationFlags,
4448 LPVOID lpEnvironment,
4449 LPCWSTR lpCurrentDirectory,
4450 LPSTARTUPINFOW lpStartupInfo,
4451 LPPROCESS_INFORMATION lpProcessInformation)
4452{
4453 /* Call the internal (but exported) version */
4455 lpApplicationName,
4456 lpCommandLine,
4457 lpProcessAttributes,
4458 lpThreadAttributes,
4459 bInheritHandles,
4460 dwCreationFlags,
4461 lpEnvironment,
4462 lpCurrentDirectory,
4463 lpStartupInfo,
4464 lpProcessInformation,
4465 NULL);
4466}
4467
4468/* EOF */
NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle, IN PVOID BaseAddress)
Definition: section.c:3483
NTSTATUS NTAPI NtCreateSection(OUT PHANDLE SectionHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN PLARGE_INTEGER MaximumSize OPTIONAL, IN ULONG SectionPageProtection OPTIONAL, IN ULONG AllocationAttributes, IN HANDLE FileHandle OPTIONAL)
Definition: section.c:3076
#define NtCurrentPeb()
Definition: FLS.c:22
static IN ULONG IN PWSTR OUT PCWSTR OUT PBOOLEAN OUT PATH_TYPE_AND_UNKNOWN * PathType
static ULONG StackSize
Definition: StackOverflow.c:19
#define DECLSPEC_HOTPATCH
Definition: _mingw.h:240
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
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
NTSYSAPI NTSTATUS NTAPI RtlComputeImportTableHash(IN HANDLE FileHandle, OUT PCHAR Hash, IN ULONG ImportTableHashSize)
Definition: libsupp.c:1191
static const WCHAR Title[]
Definition: oid.c:1259
#define CloseHandle
Definition: compat.h:739
#define ReadProcessMemory(a, b, c, d, e)
Definition: compat.h:758
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define PAGE_READONLY
Definition: compat.h:138
#define OPEN_EXISTING
Definition: compat.h:775
#define SetLastError(x)
Definition: compat.h:752
#define GetProcAddress(x, y)
Definition: compat.h:753
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
@ ThreadQuerySetWin32StartAddress
Definition: compat.h:944
#define GetCurrentProcess()
Definition: compat.h:759
#define GENERIC_READ
Definition: compat.h:135
#define IsWow64Process
Definition: compat.h:760
#define GetProcessId(x)
Definition: compat.h:737
#define RtlImageNtHeader
Definition: compat.h:806
#define MAX_PATH
Definition: compat.h:34
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define LoadLibraryW(x)
Definition: compat.h:747
#define ERROR_ACCESS_DENIED
Definition: compat.h:97
#define FILE_SHARE_READ
Definition: compat.h:136
PPEB Peb
Definition: dllmain.c:27
PBASE_STATIC_SERVER_DATA BaseStaticServerData
Definition: dllmain.c:19
BOOLEAN BaseRunningInServerProcess
Definition: dllmain.c:20
LONG WINAPI UnhandledExceptionFilter(IN PEXCEPTION_POINTERS ExceptionInfo)
Definition: except.c:269
BOOL NTAPI IsBadWritePtr(IN LPVOID lp, IN UINT_PTR ucb)
Definition: except.c:883
DWORD WINAPI GetFileAttributesW(LPCWSTR lpFileName)
Definition: fileinfo.c: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:1906
VOID WINAPI FatalAppExitA(UINT uAction, LPCSTR lpMessageText)
Definition: proc.c:1406
VOID WINAPI FatalExit(IN int ExitCode)
Definition: proc.c:1468
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:2084
BOOL WINAPI FlushInstructionCache(IN HANDLE hProcess, IN LPCVOID lpBaseAddress, IN SIZE_T nSize)
Definition: proc.c:1307
BOOL WINAPI GetProcessWorkingSetSizeEx(IN HANDLE hProcess, OUT PSIZE_T lpMinimumWorkingSetSize, OUT PSIZE_T lpMaximumWorkingSetSize, OUT PDWORD Flags)
Definition: proc.c:976
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:4442
BOOL WINAPI GetExitCodeProcess(IN HANDLE hProcess, IN LPDWORD lpExitCode)
Definition: proc.c:1166
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:1331
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:1610
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:1376
NTSTATUS WINAPI BasepIsProcessAllowed(IN LPWSTR ApplicationName)
Definition: proc.c:200
ANSI_STRING BaseAnsiCommandLine
Definition: proc.c:21
#define AddToHandle(x, y)
Definition: proc.c:2075
HANDLE WINAPI OpenProcess(IN DWORD dwDesiredAccess, IN BOOL bInheritHandle, IN DWORD dwProcessId)
Definition: proc.c:1225
BOOL WINAPI GetProcessPriorityBoost(IN HANDLE hProcess, OUT PBOOL pDisablePriorityBoost)
Definition: proc.c:1738
BOOL WINAPI GetProcessTimes(IN HANDLE hProcess, IN LPFILETIME lpCreationTime, IN LPFILETIME lpExitTime, IN LPFILETIME lpKernelTime, IN LPFILETIME lpUserTime)
Definition: proc.c:1097
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:1025
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:1081
BOOL WINAPI GetProcessHandleCount(IN HANDLE hProcess, OUT PDWORD pdwHandleCount)
Definition: proc.c:1795
BOOL WINAPI SetProcessShutdownParameters(IN DWORD dwLevel, IN DWORD dwFlags)
Definition: proc.c:947
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:2025
VOID WINAPI RegisterWaitForInputIdle(WaitForInputIdleType lpfnRegisterWaitForInputIdle)
DWORD WINAPI GetPriorityClass(IN HANDLE hProcess)
Definition: proc.c:1507
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:1711
VOID WINAPI FatalAppExitW(IN UINT uAction, IN LPCWSTR lpMessageText)
Definition: proc.c:1430
BOOL WINAPI SetProcessPriorityBoost(IN HANDLE hProcess, IN BOOL bDisablePriorityBoost)
Definition: proc.c:1767
VOID WINAPI InitCommandLines(VOID)
Definition: proc.c:840
BOOL WINAPI GetProcessWorkingSetSize(IN HANDLE hProcess, OUT PSIZE_T lpMinimumWorkingSetSize, OUT PSIZE_T lpMaximumWorkingSetSize)
Definition: proc.c:1009
PSAFER_REPLACE_PROCESS_THREAD_TOKENS g_SaferReplaceProcessThreadTokens
Definition: proc.c:43
BOOL WINAPI SetPriorityClass(IN HANDLE hProcess, IN DWORD dwPriorityClass)
Definition: proc.c:1542
VOID WINAPI GetStartupInfoW(IN LPSTARTUPINFOW lpStartupInfo)
Definition: proc.c:1266
BOOL WINAPI GetProcessShutdownParameters(OUT LPDWORD lpdwLevel, OUT LPDWORD lpdwFlags)
Definition: proc.c:918
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:2076
BOOL WINAPI SetProcessAffinityMask(IN HANDLE hProcess, IN DWORD_PTR dwProcessAffinityMask)
Definition: proc.c:892
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:861
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:25
GLdouble n
Definition: glext.h:7729
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define DbgPrint
Definition: hal.h:12
NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus, IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask, IN PULONG_PTR Parameters, IN ULONG ValidResponseOptions, OUT PULONG Response)
Definition: harderr.c:551
_In_ GUID _In_ PVOID ValueData
Definition: hubbusif.h:312
#define PROCESS_VM_READ
Definition: pstypes.h:162
#define PROCESS_CREATE_FLAGS_BREAKAWAY
Definition: pstypes.h:92
#define PROCESS_QUERY_INFORMATION
Definition: pstypes.h:167
#define PROCESS_PRIORITY_CLASS_IDLE
Definition: pstypes.h:108
#define PROCESS_CREATE_FLAGS_INHERIT_HANDLES
Definition: pstypes.h:94
#define PROCESS_PRIORITY_CLASS_INVALID
Definition: pstypes.h:107
#define PROCESS_PRIORITY_CLASS_NORMAL
Definition: pstypes.h:109
#define PROCESS_PRIORITY_CLASS_HIGH
Definition: pstypes.h:110
#define PROCESS_PRIORITY_CLASS_ABOVE_NORMAL
Definition: pstypes.h:113
#define PROCESS_CREATE_FLAGS_LARGE_PAGES
Definition: pstypes.h:96
#define PROCESS_PRIORITY_CLASS_BELOW_NORMAL
Definition: pstypes.h:112
#define PROCESS_PRIORITY_CLASS_REALTIME
Definition: pstypes.h:111
#define FLG_DISABLE_DEBUG_PROMPTS
Definition: pstypes.h:86
#define PROCESS_CREATE_FLAGS_NO_DEBUG_INHERIT
Definition: pstypes.h:93
#define OBJ_CASE_INSENSITIVE
Definition: winternl.h:228
#define OBJ_INHERIT
Definition: winternl.h:225
NTSYSAPI void WINAPI RtlReleasePebLock(void)
Definition: libsupp.c:84
NTSYSAPI NTSTATUS WINAPI DbgUiConnectToDbg(void)
Definition: dbgui.c:25
NTSYSAPI void WINAPI RtlAcquirePebLock(void)
Definition: libsupp.c:74
NTSYSAPI void WINAPI DbgBreakPoint(void)
NTSYSAPI void WINAPI LdrShutdownProcess(void)
Definition: ldrinit.c: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:5368
NTSYSAPI ULONG WINAPI RtlGetNtGlobalFlags(void)
Definition: libsupp.c:95
#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:668
#define SE_LOCK_MEMORY_PRIVILEGE
Definition: security.c:658
static const char const char * DllPath
Definition: image.c:34
static const char * ImageName
Definition: image.c:34
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
DWORD e_lfanew
Definition: crypt.c:1156
#define DBG(x)
Definition: moztest.c:12
unsigned int UINT
Definition: ndis.h:50
_In_ NDIS_ERROR_CODE ErrorCode
Definition: ndis.h:4436
_Must_inspect_result_ _Out_ PNDIS_STATUS _In_ NDIS_HANDLE _In_ ULONG _Out_ PNDIS_STRING _Out_ PNDIS_HANDLE KeyHandle
Definition: ndis.h:4715
#define HARDERROR_OVERRIDE_ERRORMODE
Definition: extypes.h:146
@ OptionOkCancel
Definition: extypes.h:188
@ OptionOk
Definition: extypes.h:187
@ ResponseOk
Definition: extypes.h:205
@ ResponseCancel
Definition: extypes.h:202
#define PROCESSOR_ARCHITECTURE_IA64
Definition: ketypes.h:111
#define PROCESSOR_ARCHITECTURE_UNKNOWN
Definition: ketypes.h:115
#define PROCESSOR_ARCHITECTURE_AMD64
Definition: ketypes.h:114
#define PROCESSOR_ARCHITECTURE_INTEL
Definition: ketypes.h:105
_In_ HANDLE ProcessHandle
Definition: mmfuncs.h:403
_In_ HANDLE _Outptr_result_bytebuffer_ ViewSize PVOID * BaseAddress
Definition: mmfuncs.h:404
__kernel_entry _Inout_ _Inout_ PSIZE_T RegionSize
Definition: mmfuncs.h:172
#define SEC_IMAGE
Definition: mmtypes.h:97
@ SectionImageInformation
Definition: mmtypes.h:196
#define DUPLICATE_SAME_ATTRIBUTES
Definition: obtypes.h:153
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:727
NTSYSAPI NTSTATUS NTAPI RtlDestroyProcessParameters(_In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
NTSYSAPI NTSTATUS NTAPI RtlCreateProcessParameters(_Out_ PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, _In_ PUNICODE_STRING ImagePathName, _In_opt_ PUNICODE_STRING DllPath, _In_opt_ PUNICODE_STRING CurrentDirectory, _In_opt_ PUNICODE_STRING CommandLine, _In_opt_ PWSTR Environment, _In_opt_ PUNICODE_STRING WindowTitle, _In_opt_ PUNICODE_STRING DesktopInfo, _In_opt_ PUNICODE_STRING ShellInfo, _In_opt_ PUNICODE_STRING RuntimeInfo)
NTSYSAPI ULONG NTAPI RtlIsDosDeviceName_U(_In_ PCWSTR Name)
NTSYSAPI NTSTATUS NTAPI RtlAcquirePrivilege(_In_ PULONG Privilege, _In_ ULONG NumPriv, _In_ ULONG Flags, _Out_ PVOID *ReturnedState)
_In_ PCWSTR _Inout_ _At_ QueryTable EntryContext
Definition: rtlfuncs.h:4210
NTSTATUS NTAPI RtlGetFullPathName_UstrEx(_In_ PUNICODE_STRING FileName, _In_opt_ PUNICODE_STRING StaticString, _In_opt_ PUNICODE_STRING DynamicString, _Out_opt_ PUNICODE_STRING *StringUsed, _Out_opt_ PSIZE_T FilePartSize, _Out_opt_ PBOOLEAN NameInvalid, _Out_ RTL_PATH_TYPE *PathType, _Out_opt_ PSIZE_T LengthNeeded)
VOID NTAPI RtlReleaseRelativeName(_In_ PRTL_RELATIVE_NAME_U RelativeName)
NTSYSAPI VOID NTAPI RtlDestroyEnvironment(_In_ PWSTR Environment)
NTSYSAPI RTL_PATH_TYPE NTAPI RtlDetermineDosPathNameType_U(_In_ PCWSTR Path)
NTSYSAPI VOID NTAPI RtlReleasePrivilege(_In_ PVOID ReturnedState)
NTSYSAPI NTSTATUS NTAPI RtlEnterCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
_In_opt_ ULONG Base
Definition: rtlfuncs.h:2486
NTSYSAPI NTSTATUS NTAPI RtlLeaveCriticalSection(_In_ PRTL_CRITICAL_SECTION CriticalSection)
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
NTSYSAPI ULONG NTAPI DbgPrompt(_In_z_ PCCH Prompt, _Out_writes_bytes_(MaximumResponseLength) PCH Response, _In_ ULONG MaximumResponseLength)
NTSYSAPI BOOLEAN NTAPI RtlDosPathNameToRelativeNtPathName_U(_In_ PCWSTR DosName, _Out_ PUNICODE_STRING NtName, _Out_ PCWSTR *PartName, _Out_ PRTL_RELATIVE_NAME_U RelativeName)
#define RTL_USER_PROCESS_PARAMETERS_IMAGE_KEY_MISSING
Definition: rtltypes.h:54
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_KERNEL
Definition: rtltypes.h:43
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_SERVER
Definition: rtltypes.h:44
#define SEM_FAILCRITICALERRORS
Definition: rtltypes.h:69
#define RTL_USER_PROCESS_PARAMETERS_LOCAL_DLL_PATH
Definition: rtltypes.h:53
#define RTL_USER_PROCESS_PARAMETERS_PROFILE_USER
Definition: rtltypes.h:42
@ RtlPathTypeRootLocalDevice
Definition: rtltypes.h:472
@ RtlPathTypeRelative
Definition: rtltypes.h:470
@ RtlPathTypeUncAbsolute
Definition: rtltypes.h:466
@ RtlPathTypeLocalDevice
Definition: rtltypes.h:471
@ RtlPathTypeDriveAbsolute
Definition: rtltypes.h:467
enum _RTL_PATH_TYPE RTL_PATH_TYPE
#define RTL_USER_PROCESS_PARAMETERS_DISABLE_HEAP_CHECKS
Definition: rtltypes.h:49
VOID WINAPI FreeString(_In_ LPWSTR pszString)
Definition: netsh.c:278
_In_ LPWSTR _In_ DWORD _In_ DWORD _In_ DWORD dwFlags
Definition: netsh.h:141
_Out_ LPWSTR lpBuffer
Definition: netsh.h:68
#define _In_
Definition: no_sal2.h:158
#define THREAD_ALL_ACCESS
Definition: nt_native.h:1342
NTSYSAPI NTSTATUS NTAPI NtOpenFile(OUT PHANDLE phFile, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK pIoStatusBlock, IN ULONG ShareMode, IN ULONG OpenMode)
Definition: file.c:3953
#define RTL_REGISTRY_CONTROL
Definition: nt_native.h:163
NTSYSAPI NTSTATUS NTAPI RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString)
NTSYSAPI NTSTATUS NTAPI NtOpenKey(OUT PHANDLE KeyHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes)
Definition: ntapi.c:336
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define SYNCHRONIZE
Definition: nt_native.h:61
#define PAGE_WRITECOPY
Definition: nt_native.h:1308
#define FILE_READ_DATA
Definition: nt_native.h:628
NTSYSAPI 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:75
static BOOL bInheritHandle
Definition: pipe.c:82
#define IMAGE_SUBSYSTEM_POSIX_CUI
Definition: ntimage.h:440
#define IMAGE_SUBSYSTEM_WINDOWS_CUI
Definition: ntimage.h:438
#define IMAGE_SUBSYSTEM_WINDOWS_GUI
Definition: ntimage.h:437
#define IMAGE_DLLCHARACTERISTICS_NO_ISOLATION
Definition: ntimage.h:458
#define IMAGE_FILE_MACHINE_AMD64
Definition: ntimage.h:17
#define IMAGE_FILE_MACHINE_IA64
Definition: ntimage.h:22
NTSTATUS NTAPI NtFreeVirtualMemory(IN HANDLE ProcessHandle, IN PVOID *UBaseAddress, IN PSIZE_T URegionSize, IN ULONG FreeType)
Definition: virtual.c:5192
NTSTATUS NTAPI NtWriteVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, IN PVOID Buffer, IN SIZE_T NumberOfBytesToWrite, OUT PSIZE_T NumberOfBytesWritten OPTIONAL)
Definition: virtual.c:2895
NTSTATUS NTAPI NtProtectVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UnsafeBaseAddress, IN OUT SIZE_T *UnsafeNumberOfBytesToProtect, IN ULONG NewAccessProtection, OUT PULONG UnsafeOldAccessProtection)
Definition: virtual.c:3076
NTSTATUS NTAPI NtReadVirtualMemory(IN HANDLE ProcessHandle, IN PVOID BaseAddress, OUT PVOID Buffer, IN SIZE_T NumberOfBytesToRead, OUT PSIZE_T NumberOfBytesRead OPTIONAL)
Definition: virtual.c:2781
NTSTATUS NTAPI NtAllocateVirtualMemory(IN HANDLE ProcessHandle, IN OUT PVOID *UBaseAddress, IN ULONG_PTR ZeroBits, IN OUT PSIZE_T URegionSize, IN ULONG AllocationType, IN ULONG Protect)
Definition: virtual.c:4457
NTSTATUS NTAPI NtFlushInstructionCache(_In_ HANDLE ProcessHandle, _In_opt_ PVOID BaseAddress, _In_ SIZE_T FlushSize)
Definition: virtual.c:3009
NTSTATUS NTAPI NtIsProcessInJob(IN HANDLE ProcessHandle, IN HANDLE JobHandle OPTIONAL)
Definition: job.c:361
NTSTATUS NTAPI NtAssignProcessToJobObject(HANDLE JobHandle, HANDLE ProcessHandle)
Definition: job.c:157
NTSTATUS NTAPI NtCreateProcessEx(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL, IN HANDLE ParentProcess, IN ULONG Flags, IN HANDLE SectionHandle OPTIONAL, IN HANDLE DebugPort OPTIONAL, IN HANDLE ExceptionPort OPTIONAL, IN BOOLEAN InJob)
Definition: process.c:1344
NTSTATUS NTAPI NtOpenProcess(OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId)
Definition: process.c:1440
NTSTATUS NTAPI NtSetInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _In_reads_bytes_(ProcessInformationLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength)
Definition: query.c:1389
NTSTATUS NTAPI NtSetInformationThread(_In_ HANDLE ThreadHandle, _In_ THREADINFOCLASS ThreadInformationClass, _In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation, _In_ ULONG ThreadInformationLength)
Definition: query.c:2268
NTSTATUS NTAPI NtQueryInformationProcess(_In_ HANDLE ProcessHandle, _In_ PROCESSINFOCLASS ProcessInformationClass, _Out_writes_bytes_to_opt_(ProcessInformationLength, *ReturnLength) PVOID ProcessInformation, _In_ ULONG ProcessInformationLength, _Out_opt_ PULONG ReturnLength)
Definition: query.c:211
NTSTATUS NTAPI NtResumeThread(IN HANDLE ThreadHandle, OUT PULONG SuspendCount OPTIONAL)
Definition: state.c:290
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_INVALID_IMAGE_WIN_64
Definition: ntstatus.h:1029
#define STATUS_INVALID_IMAGE_WIN_16
Definition: ntstatus.h:635
#define STATUS_INVALID_IMAGE_NE_FORMAT
Definition: ntstatus.h:613
#define STATUS_IMAGE_MACHINE_TYPE_MISMATCH_EXE
Definition: ntstatus.h:224
#define STATUS_INVALID_IMAGE_FORMAT
Definition: ntstatus.h:453
#define STATUS_FATAL_APP_EXIT
Definition: ntstatus.h:210
#define STATUS_INVALID_IMAGE_NOT_MZ
Definition: ntstatus.h:633
#define STATUS_INVALID_IMAGE_PROTECT
Definition: ntstatus.h:634
#define STATUS_VDM_DISALLOWED
Definition: ntstatus.h:1089
#define STATUS_ENTRYPOINT_NOT_FOUND
Definition: ntstatus.h:643
#define STATUS_FILE_IS_OFFLINE
Definition: ntstatus.h:862
#define STATUS_NAME_TOO_LONG
Definition: ntstatus.h:592
NTSTATUS NTAPI NtDuplicateObject(IN HANDLE SourceProcessHandle, IN HANDLE SourceHandle, IN HANDLE TargetProcessHandle OPTIONAL, OUT PHANDLE TargetHandle OPTIONAL, IN ACCESS_MASK DesiredAccess, IN ULONG HandleAttributes, IN ULONG Options)
Definition: obhandle.c:3410
#define STARTF_USEHOTKEY
Definition: pch.h:41
#define IMAGE_FILE_MACHINE_I386
Definition: pedump.c:174
DWORD * PDWORD
Definition: pedump.c:68
#define IMAGE_FILE_DLL
Definition: pedump.c:169
unsigned short USHORT
Definition: pedump.c:61
static WCHAR Address[46]
Definition: ping.c:68
struct _STARTUPINFOW STARTUPINFOW
_In_ DWORD dwProcessId
Definition: shlwapi.h:193
#define _SEH2_GetExceptionCode()
Definition: pseh2_64.h:181
#define _SEH2_EXCEPT(...)
Definition: pseh2_64.h:82
#define _SEH2_FINALLY
Definition: pseh2_64.h:130
#define _SEH2_GetExceptionInformation()
Definition: pseh2_64.h:180
#define _SEH2_END
Definition: pseh2_64.h:171
#define _SEH2_TRY
Definition: pseh2_64.h:71
#define _SEH2_YIELD(__stmt)
Definition: pseh2_64.h:184
DWORD BaseSetLastNTError(IN NTSTATUS Status)
Definition: reactos.cpp:167
#define REG_DWORD
Definition: sdbapi.c:615
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
NTSTATUS NTAPI NtQuerySection(_In_ HANDLE SectionHandle, _In_ SECTION_INFORMATION_CLASS SectionInformationClass, _Out_ PVOID SectionInformation, _In_ SIZE_T SectionInformationLength, _Out_opt_ PSIZE_T ResultLength)
Definition: section.c:3808
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:73
base of all file and directory entries
Definition: entries.h:83
Definition: ncftp.h:89
USHORT MaximumLength
Definition: env_spec_w32.h:377
Definition: kernel32.h:386
NTSTATUS Status
Definition: basemsg.h:279
BASE_CREATE_PROCESS CreateProcessRequest
Definition: basemsg.h:283
BASE_EXIT_PROCESS ExitProcessRequest
Definition: basemsg.h:286
BASE_GETSET_PROCESS_SHUTDOWN_PARAMS ShutdownParametersRequest
Definition: basemsg.h:294
BASE_CHECK_VDM CheckVDMRequest
Definition: basemsg.h:287
union _BASE_API_MESSAGE::@3712 Data
USHORT VDMState
Definition: basemsg.h:147
HANDLE WaitObjectForParent
Definition: basemsg.h:123
BASE_SXS_CREATEPROCESS_MSG Sxs
Definition: basemsg.h:96
USHORT ProcessorArchitecture
Definition: basemsg.h:99
ULONG PebAddressWow64
Definition: basemsg.h:98
HANDLE ProcessHandle
Definition: basemsg.h:89
CLIENT_ID ClientId
Definition: basemsg.h:91
HANDLE ThreadHandle
Definition: basemsg.h:90
PVOID PebAddressNative
Definition: basemsg.h:97
BOOLEAN IsWowTaskReady
Definition: base.h:135
BOOLEAN DefaultSeparateVDM
Definition: base.h:134
SYSTEM_BASIC_INFORMATION SysInfo
Definition: base.h:130
HANDLE UniqueThread
Definition: compat.h:826
HANDLE UniqueProcess
Definition: compat.h:825
HANDLE Handle
Definition: rtltypes.h:1363
IMAGE_OPTIONAL_HEADER32 OptionalHeader
Definition: ntddk_ex.h:184
PVOID StackBase
Definition: pstypes.h:733
LARGE_INTEGER UserTime
Definition: winternl.h:2377
LARGE_INTEGER CreateTime
Definition: winternl.h:2374
LARGE_INTEGER KernelTime
Definition: winternl.h:2376
LARGE_INTEGER ExitTime
Definition: winternl.h:2375
Definition: btrfs_drv.h:1876
Definition: typedefs.h:120
struct _LIST_ENTRY * Flink
Definition: typedefs.h:121
PVOID ArbitraryUserPointer
Definition: compat.h:719
BOOLEAN ReadImageFileExecOptions
Definition: ntddk_ex.h:240
PVOID ImageBaseAddress
Definition: ntddk_ex.h:245
PRTL_USER_PROCESS_PARAMETERS ProcessParameters
Definition: btrfs_drv.h:1913
ULONG ImageSubsystemMajorVersion
Definition: ntddk_ex.h:305
SIZE_T MaximumWorkingSetSize
Definition: pstypes.h:71
SIZE_T MinimumWorkingSetSize
Definition: pstypes.h:70
SIZE_T StaticSize
Definition: rtltypes.h:1897
PUCHAR StaticBuffer
Definition: rtltypes.h:1895
PUCHAR Buffer
Definition: rtltypes.h:1894
SIZE_T Size
Definition: rtltypes.h:1896
UNICODE_STRING RelativeName
Definition: rtltypes.h:1374
HANDLE ContainingDirectory
Definition: rtltypes.h:1375
UNICODE_STRING String
Definition: rtltypes.h:1904
UNICODE_STRING DesktopInfo
Definition: rtltypes.h:1574
LPVOID lpSecurityDescriptor
Definition: compat.h:193
PUNICODE_STRING Win32
Definition: kernel32.h:402
PUNICODE_STRING Nt
Definition: kernel32.h:403
KAFFINITY ActiveProcessorsAffinityMask
Definition: ntddk_ex.h:167
Definition: compat.h:836
NT_TIB NtTib
Definition: ntddk_ex.h:332
USHORT MaximumLength
Definition: env_spec_w32.h:370
#define max(a, b)
Definition: svc.c:63
#define RTL_CONSTANT_STRING(s)
Definition: tunneltest.c:14
ULONG_PTR * PSIZE_T
Definition: typedefs.h:80
uint16_t * PWSTR
Definition: typedefs.h:56
uint32_t * PULONG_PTR
Definition: typedefs.h:65
uint32_t DWORD_PTR
Definition: typedefs.h:65
unsigned char * LPBYTE
Definition: typedefs.h:53
#define NTAPI
Definition: typedefs.h:36
void * PVOID
Definition: typedefs.h:50
ULONG_PTR SIZE_T
Definition: typedefs.h:80
uint32_t * LPDWORD
Definition: typedefs.h:59
#define RtlCopyMemory(Destination, Source, Length)
Definition: typedefs.h:263
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define MAXUSHORT
Definition: typedefs.h:83
uint32_t ULONG_PTR
Definition: typedefs.h:65
#define IN
Definition: typedefs.h:39
#define MAKELONG(a, b)
Definition: typedefs.h:249
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::@2450 u
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
#define INVALID_FILE_ATTRIBUTES
Definition: vfdcmd.c:23
static int Shell(const char **args)
Definition: vfdcmd.c:1020
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK _In_opt_ PWDF_OBJECT_ATTRIBUTES KeyAttributes
Definition: wdfdevice.h:2666
_Must_inspect_result_ _In_ WDFDEVICE _In_ PWDF_DEVICE_PROPERTY_DATA _In_ DEVPROPTYPE _In_ ULONG Size
Definition: wdfdevice.h:4539
_Must_inspect_result_ _In_ WDFDEVICE _In_ LPCGUID _Out_ PINTERFACE _In_ USHORT _In_ USHORT Version
Definition: wdffdo.h:469
_In_ WDFIOTARGET _In_ _Strict_type_match_ WDF_IO_TARGET_SENT_IO_ACTION Action
Definition: wdfiotarget.h:510
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG _Out_opt_ PULONG _Out_opt_ PULONG ValueType
Definition: wdfregistry.h:282
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING ValueName
Definition: wdfregistry.h:243
_Must_inspect_result_ _In_ WDFKEY _In_ PCUNICODE_STRING _In_ ULONG ValueLength
Definition: wdfregistry.h:275
_In_ WDFREQUEST _In_ NTSTATUS _In_ CCHAR PriorityBoost
Definition: wdfrequest.h:1016
_In_ WDFIOTARGET _In_ PWDF_REQUEST_COMPLETION_PARAMS Params
Definition: wdfrequest.h:308
_Must_inspect_result_ _In_ WDFCMRESLIST List
Definition: wdfresource.h:550
#define NORMAL_PRIORITY_CLASS
Definition: winbase.h:185
#define STARTF_FORCEOFFFEEDBACK
Definition: winbase.h:475
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define CREATE_FORCEDOS
Definition: winbase.h:193
#define PROFILE_SERVER
Definition: winbase.h:219
HANDLE WINAPI GetCurrentThread(void)
Definition: proc.c:1146
#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:1156
#define CREATE_NO_WINDOW
Definition: winbase.h:216
#define CREATE_SHARED_WOW_VDM
Definition: winbase.h:192
#define GetModuleHandle
Definition: winbase.h:3576
#define CREATE_DEFAULT_ERROR_MODE
Definition: winbase.h:215
#define CREATE_SEPARATE_WOW_VDM
Definition: winbase.h:191
#define CREATE_NEW_PROCESS_GROUP
Definition: winbase.h:189
#define PROFILE_KERNEL
Definition: winbase.h:218
#define CREATE_SUSPENDED
Definition: winbase.h:182
#define DEBUG_ONLY_THIS_PROCESS
Definition: winbase.h:181
#define SearchPath
Definition: winbase.h:3649
#define PROFILE_USER
Definition: winbase.h:217
#define STARTF_USESTDHANDLES
Definition: winbase.h:476
#define CREATE_PRESERVE_CODE_AUTHZ_LEVEL
Definition: winbase.h:214
#define IDLE_PRIORITY_CLASS
Definition: winbase.h:186
#define DETACHED_PROCESS
Definition: winbase.h:183
#define STARTF_FORCEONFEEDBACK
Definition: winbase.h:474
#define CREATE_NEW_CONSOLE
Definition: winbase.h:184
#define DEBUG_PROCESS
Definition: winbase.h:180
*nSize LPSTR _Inout_ LPDWORD nSize
Definition: winbase.h:1834
#define ABOVE_NORMAL_PRIORITY_CLASS
Definition: winbase.h:195
_Inout_ PERBANDINFO * pbi
Definition: winddi.h:3917
#define WINAPI
Definition: msvc.h:6
#define ERROR_PATH_NOT_FOUND
Definition: winerror.h:228
#define ERROR_DIRECTORY
Definition: winerror.h:416
#define ERROR_NOT_READY
Definition: winerror.h:246
#define ERROR_BAD_EXE_FORMAT
Definition: winerror.h:373
#define ERROR_CHILD_NOT_COMPLETE
Definition: winerror.h:323
#define ERROR_ACCESS_DISABLED_BY_POLICY
Definition: winerror.h:1092
#define ERROR_CANCELLED
Definition: winerror.h:1055
#define ERROR_EXE_MACHINE_TYPE_MISMATCH
Definition: winerror.h:393
#define ERROR_ACCESS_DISABLED_WEBBLADE_TAMPER
Definition: winerror.h:1105
#define ERROR_ACCESS_DISABLED_WEBBLADE
Definition: winerror.h:1104
#define ERROR_FILE_OFFLINE
Definition: winerror.h:1714
#define ERROR_BAD_DEVICE
Definition: winerror.h:1032
_At_(*)(_In_ PWSK_CLIENT Client, _In_opt_ PUNICODE_STRING NodeName, _In_opt_ PUNICODE_STRING ServiceName, _In_opt_ ULONG NameSpace, _In_opt_ GUID *Provider, _In_opt_ PADDRINFOEXW Hints, _Outptr_ PADDRINFOEXW *Result, _In_opt_ PEPROCESS OwningProcess, _In_opt_ PETHREAD OwningThread, _Inout_ PIRP Irp Result)(Mem)) NTSTATUS(WSKAPI *PFN_WSK_GET_ADDRESS_INFO
Definition: wsk.h:409
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Out_ PCLIENT_ID ClientId
Definition: kefuncs.h:1151
#define DUPLICATE_SAME_ACCESS
const char * LPCSTR
Definition: xmlstorage.h:183
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
char * LPSTR
Definition: xmlstorage.h:182
char CHAR
Definition: xmlstorage.h:175