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 ****************************************************************/
33 RtlAcquirePebLock(VOID)
35 PPEB Peb = NtCurrentPeb ();
36 Peb->FastPebLockRoutine (Peb->FastPebLock);
41 RtlReleasePebLock(VOID)
43 PPEB Peb = NtCurrentPeb ();
44 Peb->FastPebUnlockRoutine (Peb->FastPebLock);
48 RtlpCopyParameterString(PWCHAR *Ptr,
49 PUNICODE_STRING Destination,
50 PUNICODE_STRING Source,
53 Destination->Length = Source->Length;
54 Destination->MaximumLength = Size ? Size : Source->MaximumLength;
55 Destination->Buffer = (PWCHAR)(*Ptr);
57 memmove (Destination->Buffer, Source->Buffer, Source->Length);
58 Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0;
59 *Ptr += Destination->MaximumLength/sizeof(WCHAR);
64 RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
65 PUNICODE_STRING ImagePathName,
66 PUNICODE_STRING DllPath,
67 PUNICODE_STRING CurrentDirectory,
68 PUNICODE_STRING CommandLine,
70 PUNICODE_STRING WindowTitle,
71 PUNICODE_STRING DesktopInfo,
72 PUNICODE_STRING ShellInfo,
73 PUNICODE_STRING RuntimeInfo)
75 NTSTATUS Status = STATUS_SUCCESS;
76 PRTL_USER_PROCESS_PARAMETERS Param = NULL;
80 UNICODE_STRING EmptyString;
81 HANDLE CurrentDirectoryHandle;
85 DPRINT ("RtlCreateProcessParameters\n");
89 EmptyString.Length = 0;
90 EmptyString.MaximumLength = sizeof(WCHAR);
91 EmptyString.Buffer = L"";
93 if (NtCurrentPeb()->ProcessParameters)
96 DllPath = &NtCurrentPeb()->ProcessParameters->DllPath;
97 if (Environment == NULL)
98 Environment = NtCurrentPeb()->ProcessParameters->Environment;
99 if (CurrentDirectory == NULL)
100 CurrentDirectory = &NtCurrentPeb()->ProcessParameters->CurrentDirectoryName;
\r
101 CurrentDirectoryHandle = NtCurrentPeb()->ProcessParameters->CurrentDirectoryHandle;
\r
102 ConsoleHandle = NtCurrentPeb()->ProcessParameters->hConsole;
\r
103 ConsoleFlags = NtCurrentPeb()->ProcessParameters->ProcessGroup;
\r
108 DllPath = &EmptyString;
109 if (CurrentDirectory == NULL)
110 CurrentDirectory = &EmptyString;
111 CurrentDirectoryHandle = NULL;
112 ConsoleHandle = NULL;
116 if (CommandLine == NULL)
117 CommandLine = &EmptyString;
118 if (WindowTitle == NULL)
119 WindowTitle = &EmptyString;
120 if (DesktopInfo == NULL)
121 DesktopInfo = &EmptyString;
122 if (ShellInfo == NULL)
123 ShellInfo = &EmptyString;
124 if (RuntimeInfo == NULL)
125 RuntimeInfo = &EmptyString;
127 /* size of process parameter block */
128 Length = sizeof(RTL_USER_PROCESS_PARAMETERS);
130 /* size of current directory buffer */
131 Length += (MAX_PATH * sizeof(WCHAR));
133 /* add string lengths */
134 Length += ALIGN(DllPath->MaximumLength, sizeof(ULONG));
135 Length += ALIGN(ImagePathName->Length + sizeof(WCHAR), sizeof(ULONG));
136 Length += ALIGN(CommandLine->Length + sizeof(WCHAR), sizeof(ULONG));
137 Length += ALIGN(WindowTitle->MaximumLength, sizeof(ULONG));
138 Length += ALIGN(DesktopInfo->MaximumLength, sizeof(ULONG));
139 Length += ALIGN(ShellInfo->MaximumLength, sizeof(ULONG));
140 Length += ALIGN(RuntimeInfo->MaximumLength, sizeof(ULONG));
142 /* Calculate the required block size */
143 RegionSize = ROUNDUP(Length, PAGE_SIZE);
145 Status = NtAllocateVirtualMemory(NtCurrentProcess(),
149 MEM_RESERVE | MEM_COMMIT,
151 if (!NT_SUCCESS(Status))
157 DPRINT ("Process parameters allocated\n");
159 Param->AllocationSize = RegionSize;
\r
160 Param->Size = Length;
\r
161 Param->Flags = PPF_NORMALIZED;
162 Param->Environment = Environment;
163 Param->CurrentDirectoryHandle = CurrentDirectoryHandle;
\r
164 Param->hConsole = ConsoleHandle;
\r
165 Param->ProcessGroup = ConsoleFlags;
\r
167 Dest = (PWCHAR)(((PBYTE)Param) + sizeof(RTL_USER_PROCESS_PARAMETERS));
169 /* copy current directory */
170 RtlpCopyParameterString(&Dest,
171 &Param->CurrentDirectoryName,
\r
173 MAX_PATH * sizeof(WCHAR));
175 /* make sure the current directory has a trailing backslash */
176 if (Param->CurrentDirectoryName.Length > 0)
\r
180 Length = Param->CurrentDirectoryName.Length / sizeof(WCHAR);
\r
181 if (Param->CurrentDirectoryName.Buffer[Length-1] != L'\\')
\r
183 Param->CurrentDirectoryName.Buffer[Length] = L'\\';
\r
184 Param->CurrentDirectoryName.Buffer[Length + 1] = 0;
\r
185 Param->CurrentDirectoryName.Length += sizeof(WCHAR);
\r
190 RtlpCopyParameterString(&Dest,
195 /* copy image path name */
196 RtlpCopyParameterString(&Dest,
197 &Param->ImagePathName,
199 ImagePathName->Length + sizeof(WCHAR));
201 /* copy command line */
202 RtlpCopyParameterString(&Dest,
205 CommandLine->Length + sizeof(WCHAR));
208 RtlpCopyParameterString(&Dest,
214 RtlpCopyParameterString(&Dest,
219 /* copy shell info */
220 RtlpCopyParameterString(&Dest,
225 /* copy runtime info */
226 RtlpCopyParameterString(&Dest,
231 RtlDeNormalizeProcessParams(Param);
232 *ProcessParameters = Param;
235 return STATUS_SUCCESS;
239 RtlDestroyProcessParameters(PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
241 ULONG RegionSize = 0;
243 NtFreeVirtualMemory (NtCurrentProcess (),
244 (PVOID)ProcessParameters,
250 * denormalize process parameters (Pointer-->Offset)
252 PRTL_USER_PROCESS_PARAMETERS STDCALL
253 RtlDeNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params)
255 if (Params && (Params->Flags & PPF_NORMALIZED))
257 DENORMALIZE(Params->CurrentDirectoryName.Buffer, Params);
\r
258 DENORMALIZE(Params->DllPath.Buffer, Params);
259 DENORMALIZE(Params->ImagePathName.Buffer, Params);
260 DENORMALIZE(Params->CommandLine.Buffer, Params);
261 DENORMALIZE(Params->WindowTitle.Buffer, Params);
262 DENORMALIZE(Params->DesktopInfo.Buffer, Params);
263 DENORMALIZE(Params->ShellInfo.Buffer, Params);
264 DENORMALIZE(Params->RuntimeInfo.Buffer, Params);
266 Params->Flags &= ~PPF_NORMALIZED;
273 * normalize process parameters (Offset-->Pointer)
275 PRTL_USER_PROCESS_PARAMETERS STDCALL
276 RtlNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params)
278 if (Params && !(Params->Flags & PPF_NORMALIZED))
280 NORMALIZE(Params->CurrentDirectoryName.Buffer, Params);
\r
281 NORMALIZE(Params->DllPath.Buffer, Params);
282 NORMALIZE(Params->ImagePathName.Buffer, Params);
283 NORMALIZE(Params->CommandLine.Buffer, Params);
284 NORMALIZE(Params->WindowTitle.Buffer, Params);
285 NORMALIZE(Params->DesktopInfo.Buffer, Params);
286 NORMALIZE(Params->ShellInfo.Buffer, Params);
287 NORMALIZE(Params->RuntimeInfo.Buffer, Params);
289 Params->Flags |= PPF_NORMALIZED;