Make rtl use a single header. Helps for PCH and will help for the new Headers (no...
[reactos.git] / reactos / lib / rtl / ppb.c
1 /* $Id$
2 *
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)
8 * UPDATE HISTORY:
9 * Created 01/11/98
10 */
11
12 /* INCLUDES ****************************************************************/
13
14 #include "rtl.h"
15
16 #define NDEBUG
17 #include <debug.h>
18
19 /* MACROS ****************************************************************/
20
21 #define NORMALIZE(x,addr) {if(x) x=(PVOID)((ULONG_PTR)(x)+(ULONG_PTR)(addr));}
22 #define DENORMALIZE(x,addr) {if(x) x=(PVOID)((ULONG_PTR)(x)-(ULONG_PTR)(addr));}
23 #define ALIGN(x,align) (((ULONG)(x)+(align)-1UL)&(~((align)-1UL)))
24
25
26 KPROCESSOR_MODE
27 RtlpGetMode();
28
29
30 /* FUNCTIONS ****************************************************************/
31
32
33 static inline VOID
34 RtlpCopyParameterString(PWCHAR *Ptr,
35 PUNICODE_STRING Destination,
36 PUNICODE_STRING Source,
37 ULONG Size)
38 {
39 Destination->Length = Source->Length;
40 Destination->MaximumLength = Size ? Size : Source->MaximumLength;
41 Destination->Buffer = (PWCHAR)(*Ptr);
42 if (Source->Length)
43 memmove (Destination->Buffer, Source->Buffer, Source->Length);
44 Destination->Buffer[Destination->Length / sizeof(WCHAR)] = 0;
45 *Ptr += Destination->MaximumLength/sizeof(WCHAR);
46 }
47
48
49 /*
50 * @implemented
51 */
52 NTSTATUS STDCALL
53 RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS *ProcessParameters,
54 PUNICODE_STRING ImagePathName,
55 PUNICODE_STRING DllPath,
56 PUNICODE_STRING CurrentDirectory,
57 PUNICODE_STRING CommandLine,
58 PWSTR Environment,
59 PUNICODE_STRING WindowTitle,
60 PUNICODE_STRING DesktopInfo,
61 PUNICODE_STRING ShellInfo,
62 PUNICODE_STRING RuntimeInfo)
63 {
64 NTSTATUS Status = STATUS_SUCCESS;
65 PRTL_USER_PROCESS_PARAMETERS Param = NULL;
66 ULONG RegionSize = 0;
67 ULONG Length = 0;
68 PWCHAR Dest;
69 UNICODE_STRING EmptyString;
70 HANDLE CurrentDirectoryHandle;
71 HANDLE ConsoleHandle;
72 ULONG ConsoleFlags;
73
74 DPRINT ("RtlCreateProcessParameters\n");
75
76 RtlAcquirePebLock();
77
78 EmptyString.Length = 0;
79 EmptyString.MaximumLength = sizeof(WCHAR);
80 EmptyString.Buffer = L"";
81
82 if (RtlpGetMode() == UserMode)
83 {
84 if (DllPath == NULL)
85 DllPath = &NtCurrentPeb()->ProcessParameters->DllPath;
86 if (Environment == NULL)
87 Environment = NtCurrentPeb()->ProcessParameters->Environment;
88 if (CurrentDirectory == NULL)
89 CurrentDirectory = &NtCurrentPeb()->ProcessParameters->CurrentDirectoryName;
90 CurrentDirectoryHandle = NtCurrentPeb()->ProcessParameters->CurrentDirectoryHandle;
91 ConsoleHandle = NtCurrentPeb()->ProcessParameters->hConsole;
92 ConsoleFlags = NtCurrentPeb()->ProcessParameters->ProcessGroup;
93 }
94 else
95 {
96 if (DllPath == NULL)
97 DllPath = &EmptyString;
98 if (CurrentDirectory == NULL)
99 CurrentDirectory = &EmptyString;
100 CurrentDirectoryHandle = NULL;
101 ConsoleHandle = NULL;
102 ConsoleFlags = 0;
103 }
104
105 if (CommandLine == NULL)
106 CommandLine = &EmptyString;
107 if (WindowTitle == NULL)
108 WindowTitle = &EmptyString;
109 if (DesktopInfo == NULL)
110 DesktopInfo = &EmptyString;
111 if (ShellInfo == NULL)
112 ShellInfo = &EmptyString;
113 if (RuntimeInfo == NULL)
114 RuntimeInfo = &EmptyString;
115
116 /* size of process parameter block */
117 Length = sizeof(RTL_USER_PROCESS_PARAMETERS);
118
119 /* size of current directory buffer */
120 Length += (MAX_PATH * sizeof(WCHAR));
121
122 /* add string lengths */
123 Length += ALIGN(DllPath->MaximumLength, sizeof(ULONG));
124 Length += ALIGN(ImagePathName->Length + sizeof(WCHAR), sizeof(ULONG));
125 Length += ALIGN(CommandLine->Length + sizeof(WCHAR), sizeof(ULONG));
126 Length += ALIGN(WindowTitle->MaximumLength, sizeof(ULONG));
127 Length += ALIGN(DesktopInfo->MaximumLength, sizeof(ULONG));
128 Length += ALIGN(ShellInfo->MaximumLength, sizeof(ULONG));
129 Length += ALIGN(RuntimeInfo->MaximumLength, sizeof(ULONG));
130
131 /* Calculate the required block size */
132 RegionSize = ROUNDUP(Length, PAGE_SIZE);
133
134 Status = ZwAllocateVirtualMemory(NtCurrentProcess(),
135 (PVOID*)&Param,
136 0,
137 &RegionSize,
138 MEM_RESERVE | MEM_COMMIT,
139 PAGE_READWRITE);
140 if (!NT_SUCCESS(Status))
141 {
142 RtlReleasePebLock();
143 return Status;
144 }
145
146 DPRINT ("Process parameters allocated\n");
147
148 Param->AllocationSize = RegionSize;
149 Param->Size = Length;
150 Param->Flags = PPF_NORMALIZED;
151 Param->Environment = Environment;
152 Param->CurrentDirectoryHandle = CurrentDirectoryHandle;
153 Param->hConsole = ConsoleHandle;
154 Param->ProcessGroup = ConsoleFlags;
155
156 Dest = (PWCHAR)(((PBYTE)Param) + sizeof(RTL_USER_PROCESS_PARAMETERS));
157
158 /* copy current directory */
159 RtlpCopyParameterString(&Dest,
160 &Param->CurrentDirectoryName,
161 CurrentDirectory,
162 MAX_PATH * sizeof(WCHAR));
163
164 /* make sure the current directory has a trailing backslash */
165 if (Param->CurrentDirectoryName.Length > 0)
166 {
167 ULONG Length;
168
169 Length = Param->CurrentDirectoryName.Length / sizeof(WCHAR);
170 if (Param->CurrentDirectoryName.Buffer[Length-1] != L'\\')
171 {
172 Param->CurrentDirectoryName.Buffer[Length] = L'\\';
173 Param->CurrentDirectoryName.Buffer[Length + 1] = 0;
174 Param->CurrentDirectoryName.Length += sizeof(WCHAR);
175 }
176 }
177
178 /* copy dll path */
179 RtlpCopyParameterString(&Dest,
180 &Param->DllPath,
181 DllPath,
182 0);
183
184 /* copy image path name */
185 RtlpCopyParameterString(&Dest,
186 &Param->ImagePathName,
187 ImagePathName,
188 ImagePathName->Length + sizeof(WCHAR));
189
190 /* copy command line */
191 RtlpCopyParameterString(&Dest,
192 &Param->CommandLine,
193 CommandLine,
194 CommandLine->Length + sizeof(WCHAR));
195
196 /* copy title */
197 RtlpCopyParameterString(&Dest,
198 &Param->WindowTitle,
199 WindowTitle,
200 0);
201
202 /* copy desktop */
203 RtlpCopyParameterString(&Dest,
204 &Param->DesktopInfo,
205 DesktopInfo,
206 0);
207
208 /* copy shell info */
209 RtlpCopyParameterString(&Dest,
210 &Param->ShellInfo,
211 ShellInfo,
212 0);
213
214 /* copy runtime info */
215 RtlpCopyParameterString(&Dest,
216 &Param->RuntimeInfo,
217 RuntimeInfo,
218 0);
219
220 RtlDeNormalizeProcessParams(Param);
221 *ProcessParameters = Param;
222 RtlReleasePebLock();
223
224 return STATUS_SUCCESS;
225 }
226
227 /*
228 * @implemented
229 */
230 NTSTATUS STDCALL
231 RtlDestroyProcessParameters(PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
232 {
233 ULONG RegionSize = 0;
234
235 return ZwFreeVirtualMemory (NtCurrentProcess (),
236 (PVOID)ProcessParameters,
237 &RegionSize,
238 MEM_RELEASE);
239 }
240
241 /*
242 * denormalize process parameters (Pointer-->Offset)
243 *
244 * @implemented
245 */
246 PRTL_USER_PROCESS_PARAMETERS STDCALL
247 RtlDeNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params)
248 {
249 if (Params && (Params->Flags & PPF_NORMALIZED))
250 {
251 DENORMALIZE(Params->CurrentDirectoryName.Buffer, Params);
252 DENORMALIZE(Params->DllPath.Buffer, Params);
253 DENORMALIZE(Params->ImagePathName.Buffer, Params);
254 DENORMALIZE(Params->CommandLine.Buffer, Params);
255 DENORMALIZE(Params->WindowTitle.Buffer, Params);
256 DENORMALIZE(Params->DesktopInfo.Buffer, Params);
257 DENORMALIZE(Params->ShellInfo.Buffer, Params);
258 DENORMALIZE(Params->RuntimeInfo.Buffer, Params);
259
260 Params->Flags &= ~PPF_NORMALIZED;
261 }
262
263 return Params;
264 }
265
266 /*
267 * normalize process parameters (Offset-->Pointer)
268 *
269 * @implemented
270 */
271 PRTL_USER_PROCESS_PARAMETERS STDCALL
272 RtlNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params)
273 {
274 if (Params && !(Params->Flags & PPF_NORMALIZED))
275 {
276 NORMALIZE(Params->CurrentDirectoryName.Buffer, Params);
277 NORMALIZE(Params->DllPath.Buffer, Params);
278 NORMALIZE(Params->ImagePathName.Buffer, Params);
279 NORMALIZE(Params->CommandLine.Buffer, Params);
280 NORMALIZE(Params->WindowTitle.Buffer, Params);
281 NORMALIZE(Params->DesktopInfo.Buffer, Params);
282 NORMALIZE(Params->ShellInfo.Buffer, Params);
283 NORMALIZE(Params->RuntimeInfo.Buffer, Params);
284
285 Params->Flags |= PPF_NORMALIZED;
286 }
287
288 return Params;
289 }
290
291 /* EOF */