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