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