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