xref: /reactos/sdk/lib/rtl/ppb.c (revision c2c66aff)
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