[SHELL32]
[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 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 ULONG Length;
151
152 Length = Param->CurrentDirectory.DosPath.Length / sizeof(WCHAR);
153 if (Param->CurrentDirectory.DosPath.Buffer[Length-1] != L'\\')
154 {
155 Param->CurrentDirectory.DosPath.Buffer[Length] = L'\\';
156 Param->CurrentDirectory.DosPath.Buffer[Length + 1] = 0;
157 Param->CurrentDirectory.DosPath.Length += sizeof(WCHAR);
158 }
159 }
160
161 /* copy dll path */
162 RtlpCopyParameterString(&Dest,
163 &Param->DllPath,
164 DllPath,
165 0);
166
167 /* copy image path name */
168 RtlpCopyParameterString(&Dest,
169 &Param->ImagePathName,
170 ImagePathName,
171 ImagePathName->Length + sizeof(WCHAR));
172
173 /* copy command line */
174 RtlpCopyParameterString(&Dest,
175 &Param->CommandLine,
176 CommandLine,
177 CommandLine->Length + sizeof(WCHAR));
178
179 /* copy title */
180 RtlpCopyParameterString(&Dest,
181 &Param->WindowTitle,
182 WindowTitle,
183 0);
184
185 /* copy desktop */
186 RtlpCopyParameterString(&Dest,
187 &Param->DesktopInfo,
188 DesktopInfo,
189 0);
190
191 /* copy shell info */
192 RtlpCopyParameterString(&Dest,
193 &Param->ShellInfo,
194 ShellInfo,
195 0);
196
197 /* copy runtime info */
198 RtlpCopyParameterString(&Dest,
199 &Param->RuntimeData,
200 RuntimeData,
201 0);
202
203 RtlDeNormalizeProcessParams(Param);
204 *ProcessParameters = Param;
205 RtlReleasePebLock();
206
207 return STATUS_SUCCESS;
208 }
209
210 /*
211 * @implemented
212 */
213 NTSTATUS
214 NTAPI
215 RtlDestroyProcessParameters(IN PRTL_USER_PROCESS_PARAMETERS ProcessParameters)
216 {
217 RtlFreeHeap(RtlGetProcessHeap(), 0, ProcessParameters);
218 return STATUS_SUCCESS;
219 }
220
221 /*
222 * denormalize process parameters (Pointer-->Offset)
223 *
224 * @implemented
225 */
226 PRTL_USER_PROCESS_PARAMETERS NTAPI
227 RtlDeNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params)
228 {
229 if (Params && (Params->Flags & RTL_USER_PROCESS_PARAMETERS_NORMALIZED))
230 {
231 DENORMALIZE(Params->CurrentDirectory.DosPath.Buffer, Params);
232 DENORMALIZE(Params->DllPath.Buffer, Params);
233 DENORMALIZE(Params->ImagePathName.Buffer, Params);
234 DENORMALIZE(Params->CommandLine.Buffer, Params);
235 DENORMALIZE(Params->WindowTitle.Buffer, Params);
236 DENORMALIZE(Params->DesktopInfo.Buffer, Params);
237 DENORMALIZE(Params->ShellInfo.Buffer, Params);
238 DENORMALIZE(Params->RuntimeData.Buffer, Params);
239
240 Params->Flags &= ~RTL_USER_PROCESS_PARAMETERS_NORMALIZED;
241 }
242
243 return Params;
244 }
245
246 /*
247 * normalize process parameters (Offset-->Pointer)
248 *
249 * @implemented
250 */
251 PRTL_USER_PROCESS_PARAMETERS NTAPI
252 RtlNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params)
253 {
254 if (Params && !(Params->Flags & RTL_USER_PROCESS_PARAMETERS_NORMALIZED))
255 {
256 NORMALIZE(Params->CurrentDirectory.DosPath.Buffer, Params);
257 NORMALIZE(Params->DllPath.Buffer, Params);
258 NORMALIZE(Params->ImagePathName.Buffer, Params);
259 NORMALIZE(Params->CommandLine.Buffer, Params);
260 NORMALIZE(Params->WindowTitle.Buffer, Params);
261 NORMALIZE(Params->DesktopInfo.Buffer, Params);
262 NORMALIZE(Params->ShellInfo.Buffer, Params);
263 NORMALIZE(Params->RuntimeData.Buffer, Params);
264
265 Params->Flags |= RTL_USER_PROCESS_PARAMETERS_NORMALIZED;
266 }
267
268 return Params;
269 }
270
271 /* EOF */