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