diff --git a/dll/win32/kernel32/client/proc.c b/dll/win32/kernel32/client/proc.c index 9ade5f98ca1..206b90139a5 100644 --- a/dll/win32/kernel32/client/proc.c +++ b/dll/win32/kernel32/client/proc.c @@ -609,7 +609,6 @@ BasePushProcessParameters(IN ULONG ParameterFlags, if (lpEnvironment) { /* We should've made it part of the parameters block, enforce this */ - ASSERT(ProcessParameters->Environment == lpEnvironment); lpEnvironment = ProcessParameters->Environment; } else diff --git a/sdk/include/ndk/rtltypes.h b/sdk/include/ndk/rtltypes.h index 8dc8551f0ef..daf14fcd202 100644 --- a/sdk/include/ndk/rtltypes.h +++ b/sdk/include/ndk/rtltypes.h @@ -1575,7 +1575,7 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS UNICODE_STRING ShellInfo; UNICODE_STRING RuntimeData; RTL_DRIVE_LETTER_CURDIR CurrentDirectories[RTL_MAX_DRIVE_LETTERS]; -#if (NTDDI_VERSION >= NTDDI_LONGHORN) +#if (NTDDI_VERSION >= NTDDI_LONGHORN) || defined(__REACTOS__) SIZE_T EnvironmentSize; #endif #if (NTDDI_VERSION >= NTDDI_WIN7) diff --git a/sdk/lib/rtl/ppb.c b/sdk/lib/rtl/ppb.c index 17b4ffaef7b..a1d2aa46b77 100644 --- a/sdk/lib/rtl/ppb.c +++ b/sdk/lib/rtl/ppb.c @@ -30,11 +30,15 @@ RtlpCopyParameterString(PWCHAR *Ptr, { Destination->Length = Source->Length; Destination->MaximumLength = Size ? Size : Source->MaximumLength; - Destination->Buffer = (PWCHAR)(*Ptr); - if (Source->Length) - memmove (Destination->Buffer, Source->Buffer, Source->Length); - Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0; + if (Destination->MaximumLength != 0) + { + Destination->Buffer = (PWCHAR)(*Ptr); + if (Source->Length) + memmove (Destination->Buffer, Source->Buffer, Source->Length); + Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0; + } *Ptr += Destination->MaximumLength/sizeof(WCHAR); + *Ptr = ALIGN_UP_POINTER_BY(*Ptr, sizeof(PVOID)); } @@ -55,8 +59,11 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, { PRTL_USER_PROCESS_PARAMETERS Param = NULL; ULONG Length = 0; + SIZE_T EnvironmentSize = 0; + ULONG AllocationSize; PWCHAR Dest; - UNICODE_STRING EmptyString; + UNICODE_STRING EmptyString = { .Length = 0, .MaximumLength = sizeof(WCHAR), .Buffer = L"" }; ; + UNICODE_STRING NullString = { .Length = 0, .MaximumLength = 0, .Buffer = NULL }; ; HANDLE CurrentDirectoryHandle; HANDLE ConsoleHandle; ULONG ConsoleFlags; @@ -65,10 +72,6 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, RtlAcquirePebLock(); - EmptyString.Length = 0; - EmptyString.MaximumLength = sizeof(WCHAR); - EmptyString.Buffer = L""; - if (RtlpGetMode() == UserMode) { if (DllPath == NULL) @@ -92,6 +95,8 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, ConsoleFlags = 0; } + if (CommandLine == NULL) + CommandLine = ImagePathName; if (CommandLine == NULL) CommandLine = &EmptyString; if (WindowTitle == NULL) @@ -101,7 +106,7 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, if (ShellInfo == NULL) ShellInfo = &EmptyString; if (RuntimeData == NULL) - RuntimeData = &EmptyString; + RuntimeData = &NullString; /* size of process parameter block */ Length = sizeof(RTL_USER_PROCESS_PARAMETERS); @@ -110,16 +115,27 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, Length += (MAX_PATH * sizeof(WCHAR)); /* add string lengths */ - Length += ALIGN(DllPath->MaximumLength, sizeof(ULONG)); - Length += ALIGN(ImagePathName->Length + sizeof(WCHAR), sizeof(ULONG)); - Length += ALIGN(CommandLine->Length + sizeof(WCHAR), sizeof(ULONG)); - Length += ALIGN(WindowTitle->MaximumLength, sizeof(ULONG)); - Length += ALIGN(DesktopInfo->MaximumLength, sizeof(ULONG)); - Length += ALIGN(ShellInfo->MaximumLength, sizeof(ULONG)); - Length += ALIGN(RuntimeData->MaximumLength, sizeof(ULONG)); + Length += ALIGN(DllPath->MaximumLength, sizeof(PVOID)); + Length += ALIGN(ImagePathName->Length + sizeof(WCHAR), sizeof(PVOID)); + Length += ALIGN(CommandLine->Length + sizeof(WCHAR), sizeof(PVOID)); + Length += ALIGN(WindowTitle->MaximumLength, sizeof(PVOID)); + Length += ALIGN(DesktopInfo->MaximumLength, sizeof(PVOID)); + Length += ALIGN(ShellInfo->MaximumLength, sizeof(PVOID)); + Length += ALIGN(RuntimeData->MaximumLength, sizeof(PVOID)); + + /* Vista stores the EnvironmentSize in RTL_PROCESS_PARAMETERS */ + if (Environment != NULL) + { + PWCHAR EnvEnd = Environment; + while (*EnvEnd) + EnvEnd += wcslen(EnvEnd) + 1; + EnvironmentSize = (EnvEnd - Environment + 1) * sizeof(WCHAR); + } + + AllocationSize = Length + EnvironmentSize; /* Calculate the required block size */ - Param = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, Length); + Param = RtlAllocateHeap(RtlGetProcessHeap(), HEAP_ZERO_MEMORY, AllocationSize); if (!Param) { RtlReleasePebLock(); @@ -131,7 +147,8 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, Param->MaximumLength = Length; Param->Length = Length; Param->Flags = RTL_USER_PROCESS_PARAMETERS_NORMALIZED; - Param->Environment = Environment; + Param->Environment = NULL; + Param->EnvironmentSize = 0; Param->CurrentDirectory.Handle = CurrentDirectoryHandle; Param->ConsoleHandle = ConsoleHandle; Param->ConsoleFlags = ConsoleFlags; @@ -198,6 +215,20 @@ RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters, RuntimeData, 0); + /* Make sure we didn't go past the end of the buffer */ + ASSERT(((PUCHAR)Dest - (PUCHAR)Param) <= Param->MaximumLength); + + /* Copy the environment */ + if (Environment != NULL) + { + RtlCopyMemory(Dest, Environment, EnvironmentSize); + Param->Environment = Dest; + Param->EnvironmentSize = EnvironmentSize; + + /* Make sure we didn't go past the end of the buffer */ + ASSERT((PUCHAR)Dest + EnvironmentSize - (PUCHAR)Param <= AllocationSize); + } + RtlDeNormalizeProcessParams(Param); *ProcessParameters = Param; RtlReleasePebLock();