3 * COPYRIGHT: See COPYING in the top level directory
4 * PROJECT: ReactOS system libraries
5 * FILE: lib/ntdll/rtl/ppb.c
6 * PURPOSE: Process parameters functions
7 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
12 /* INCLUDES ****************************************************************/
14 #include <ddk/ntddk.h>
15 #include <ntdll/ldr.h>
17 #include <ntdll/base.h>
18 #include <ntdll/rtl.h>
21 #include <ntdll/ntdll.h>
23 /* MACROS ****************************************************************/
25 #define NORMALIZE(x,addr) {if(x) x=(VOID*)((ULONG)(x)+(ULONG)(addr));}
26 #define DENORMALIZE(x,addr) {if(x) x=(VOID*)((ULONG)(x)-(ULONG)(addr));}
27 #define ALIGN(x,align) (((ULONG)(x)+(align)-1UL)&(~((align)-1UL)))
30 /* FUNCTIONS ****************************************************************/
36 RtlAcquirePebLock(VOID)
38 PPEB Peb = NtCurrentPeb ();
39 Peb->FastPebLockRoutine (Peb->FastPebLock);
47 RtlReleasePebLock(VOID)
49 PPEB Peb = NtCurrentPeb ();
50 Peb->FastPebUnlockRoutine (Peb->FastPebLock);
54 RtlpCopyParameterString(PWCHAR *Ptr,
55 PUNICODE_STRING Destination,
56 PUNICODE_STRING Source,
59 Destination->Length = Source->Length;
60 Destination->MaximumLength = Size ? Size : Source->MaximumLength;
61 Destination->Buffer = (PWCHAR)(*Ptr);
63 memmove (Destination->Buffer, Source->Buffer, Source->Length);
64 Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0;
65 *Ptr += Destination->MaximumLength/sizeof(WCHAR);
73 RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
74 PUNICODE_STRING ImagePathName,
75 PUNICODE_STRING DllPath,
76 PUNICODE_STRING CurrentDirectory,
77 PUNICODE_STRING CommandLine,
79 PUNICODE_STRING WindowTitle,
80 PUNICODE_STRING DesktopInfo,
81 PUNICODE_STRING ShellInfo,
82 PUNICODE_STRING RuntimeInfo)
84 NTSTATUS Status = STATUS_SUCCESS;
85 PRTL_USER_PROCESS_PARAMETERS Param = NULL;
89 UNICODE_STRING EmptyString;
90 HANDLE CurrentDirectoryHandle;
94 DPRINT ("RtlCreateProcessParameters\n");
98 EmptyString.Length = 0;
99 EmptyString.MaximumLength = sizeof(WCHAR);
100 EmptyString.Buffer = L"";
102 if (NtCurrentPeb()->ProcessParameters)
105 DllPath = &NtCurrentPeb()->ProcessParameters->DllPath;
106 if (Environment == NULL)
107 Environment = NtCurrentPeb()->ProcessParameters->Environment;
108 if (CurrentDirectory == NULL)
109 CurrentDirectory = &NtCurrentPeb()->ProcessParameters->CurrentDirectoryName;
110 CurrentDirectoryHandle = NtCurrentPeb()->ProcessParameters->CurrentDirectoryHandle;
111 ConsoleHandle = NtCurrentPeb()->ProcessParameters->hConsole;
112 ConsoleFlags = NtCurrentPeb()->ProcessParameters->ProcessGroup;
117 DllPath = &EmptyString;
118 if (CurrentDirectory == NULL)
119 CurrentDirectory = &EmptyString;
120 CurrentDirectoryHandle = NULL;
121 ConsoleHandle = NULL;
125 if (CommandLine == NULL)
126 CommandLine = &EmptyString;
127 if (WindowTitle == NULL)
128 WindowTitle = &EmptyString;
129 if (DesktopInfo == NULL)
130 DesktopInfo = &EmptyString;
131 if (ShellInfo == NULL)
132 ShellInfo = &EmptyString;
133 if (RuntimeInfo == NULL)
134 RuntimeInfo = &EmptyString;
136 /* size of process parameter block */
137 Length = sizeof(RTL_USER_PROCESS_PARAMETERS);
139 /* size of current directory buffer */
140 Length += (MAX_PATH * sizeof(WCHAR));
142 /* add string lengths */
143 Length += ALIGN(DllPath->MaximumLength, sizeof(ULONG));
144 Length += ALIGN(ImagePathName->Length + sizeof(WCHAR), sizeof(ULONG));
145 Length += ALIGN(CommandLine->Length + sizeof(WCHAR), sizeof(ULONG));
146 Length += ALIGN(WindowTitle->MaximumLength, sizeof(ULONG));
147 Length += ALIGN(DesktopInfo->MaximumLength, sizeof(ULONG));
148 Length += ALIGN(ShellInfo->MaximumLength, sizeof(ULONG));
149 Length += ALIGN(RuntimeInfo->MaximumLength, sizeof(ULONG));
151 /* Calculate the required block size */
152 RegionSize = ROUNDUP(Length, PAGE_SIZE);
154 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
158 MEM_RESERVE | MEM_COMMIT,
160 if (!NT_SUCCESS(Status))
166 DPRINT ("Process parameters allocated\n");
168 Param->AllocationSize = RegionSize;
169 Param->Size = Length;
170 Param->Flags = PPF_NORMALIZED;
171 Param->Environment = Environment;
172 Param->CurrentDirectoryHandle = CurrentDirectoryHandle;
173 Param->hConsole = ConsoleHandle;
174 Param->ProcessGroup = ConsoleFlags;
176 Dest = (PWCHAR)(((PBYTE)Param) + sizeof(RTL_USER_PROCESS_PARAMETERS));
178 /* copy current directory */
179 RtlpCopyParameterString(&Dest,
180 &Param->CurrentDirectoryName,
182 MAX_PATH * sizeof(WCHAR));
184 /* make sure the current directory has a trailing backslash */
185 if (Param->CurrentDirectoryName.Length > 0)
189 Length = Param->CurrentDirectoryName.Length / sizeof(WCHAR);
190 if (Param->CurrentDirectoryName.Buffer[Length-1] != L'\\')
192 Param->CurrentDirectoryName.Buffer[Length] = L'\\';
193 Param->CurrentDirectoryName.Buffer[Length + 1] = 0;
194 Param->CurrentDirectoryName.Length += sizeof(WCHAR);
199 RtlpCopyParameterString(&Dest,
204 /* copy image path name */
205 RtlpCopyParameterString(&Dest,
206 &Param->ImagePathName,
208 ImagePathName->Length + sizeof(WCHAR));
210 /* copy command line */
211 RtlpCopyParameterString(&Dest,
214 CommandLine->Length + sizeof(WCHAR));
217 RtlpCopyParameterString(&Dest,
223 RtlpCopyParameterString(&Dest,
228 /* copy shell info */
229 RtlpCopyParameterString(&Dest,
234 /* copy runtime info */
235 RtlpCopyParameterString(&Dest,
240 RtlDeNormalizeProcessParams(Param);
241 *ProcessParameters = Param;
244 return STATUS_SUCCESS;
251 RtlDestroyProcessParameters(PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
253 ULONG RegionSize = 0;
255 return NtFreeVirtualMemory (NtCurrentProcess (),
256 (PVOID)ProcessParameters,
262 * denormalize process parameters (Pointer-->Offset)
266 PRTL_USER_PROCESS_PARAMETERS STDCALL
267 RtlDeNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params)
269 if (Params && (Params->Flags & PPF_NORMALIZED))
271 DENORMALIZE(Params->CurrentDirectoryName.Buffer, Params);
272 DENORMALIZE(Params->DllPath.Buffer, Params);
273 DENORMALIZE(Params->ImagePathName.Buffer, Params);
274 DENORMALIZE(Params->CommandLine.Buffer, Params);
275 DENORMALIZE(Params->WindowTitle.Buffer, Params);
276 DENORMALIZE(Params->DesktopInfo.Buffer, Params);
277 DENORMALIZE(Params->ShellInfo.Buffer, Params);
278 DENORMALIZE(Params->RuntimeInfo.Buffer, Params);
280 Params->Flags &= ~PPF_NORMALIZED;
287 * normalize process parameters (Offset-->Pointer)
291 PRTL_USER_PROCESS_PARAMETERS STDCALL
292 RtlNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params)
294 if (Params && !(Params->Flags & PPF_NORMALIZED))
296 NORMALIZE(Params->CurrentDirectoryName.Buffer, Params);
297 NORMALIZE(Params->DllPath.Buffer, Params);
298 NORMALIZE(Params->ImagePathName.Buffer, Params);
299 NORMALIZE(Params->CommandLine.Buffer, Params);
300 NORMALIZE(Params->WindowTitle.Buffer, Params);
301 NORMALIZE(Params->DesktopInfo.Buffer, Params);
302 NORMALIZE(Params->ShellInfo.Buffer, Params);
303 NORMALIZE(Params->RuntimeInfo.Buffer, Params);
305 Params->Flags |= PPF_NORMALIZED;