1 /* $Id: ppb.c,v 1.20 2004/11/19 01:30:35 weiden Exp $
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)
12 /* INCLUDES ****************************************************************/
14 #include <ddk/ntddk.h>
16 #include <ntdll/ldr.h>
18 #include <ntdll/base.h>
19 #include <ntdll/rtl.h>
22 #include <ntdll/ntdll.h>
24 /* MACROS ****************************************************************/
26 #define NORMALIZE(x,addr) {if(x) x=(PVOID)((ULONG_PTR)(x)+(ULONG_PTR)(addr));}
27 #define DENORMALIZE(x,addr) {if(x) x=(PVOID)((ULONG_PTR)(x)-(ULONG_PTR)(addr));}
28 #define ALIGN(x,align) (((ULONG)(x)+(align)-1UL)&(~((align)-1UL)))
31 /* FUNCTIONS ****************************************************************/
37 RtlAcquirePebLock(VOID
)
39 PPEB Peb
= NtCurrentPeb ();
40 Peb
->FastPebLockRoutine (Peb
->FastPebLock
);
48 RtlReleasePebLock(VOID
)
50 PPEB Peb
= NtCurrentPeb ();
51 Peb
->FastPebUnlockRoutine (Peb
->FastPebLock
);
55 RtlpCopyParameterString(PWCHAR
*Ptr
,
56 PUNICODE_STRING Destination
,
57 PUNICODE_STRING Source
,
60 Destination
->Length
= Source
->Length
;
61 Destination
->MaximumLength
= Size
? Size
: Source
->MaximumLength
;
62 Destination
->Buffer
= (PWCHAR
)(*Ptr
);
64 memmove (Destination
->Buffer
, Source
->Buffer
, Source
->Length
);
65 Destination
->Buffer
[Destination
->Length
/ sizeof(WCHAR
)] = 0;
66 *Ptr
+= Destination
->MaximumLength
/sizeof(WCHAR
);
74 RtlCreateProcessParameters(PRTL_USER_PROCESS_PARAMETERS
*ProcessParameters
,
75 PUNICODE_STRING ImagePathName
,
76 PUNICODE_STRING DllPath
,
77 PUNICODE_STRING CurrentDirectory
,
78 PUNICODE_STRING CommandLine
,
80 PUNICODE_STRING WindowTitle
,
81 PUNICODE_STRING DesktopInfo
,
82 PUNICODE_STRING ShellInfo
,
83 PUNICODE_STRING RuntimeInfo
)
85 NTSTATUS Status
= STATUS_SUCCESS
;
86 PRTL_USER_PROCESS_PARAMETERS Param
= NULL
;
90 UNICODE_STRING EmptyString
;
91 HANDLE CurrentDirectoryHandle
;
95 DPRINT ("RtlCreateProcessParameters\n");
99 EmptyString
.Length
= 0;
100 EmptyString
.MaximumLength
= sizeof(WCHAR
);
101 EmptyString
.Buffer
= L
"";
103 if (NtCurrentPeb()->ProcessParameters
)
106 DllPath
= &NtCurrentPeb()->ProcessParameters
->DllPath
;
107 if (Environment
== NULL
)
108 Environment
= NtCurrentPeb()->ProcessParameters
->Environment
;
109 if (CurrentDirectory
== NULL
)
110 CurrentDirectory
= &NtCurrentPeb()->ProcessParameters
->CurrentDirectoryName
;
111 CurrentDirectoryHandle
= NtCurrentPeb()->ProcessParameters
->CurrentDirectoryHandle
;
112 ConsoleHandle
= NtCurrentPeb()->ProcessParameters
->hConsole
;
113 ConsoleFlags
= NtCurrentPeb()->ProcessParameters
->ProcessGroup
;
118 DllPath
= &EmptyString
;
119 if (CurrentDirectory
== NULL
)
120 CurrentDirectory
= &EmptyString
;
121 CurrentDirectoryHandle
= NULL
;
122 ConsoleHandle
= NULL
;
126 if (CommandLine
== NULL
)
127 CommandLine
= &EmptyString
;
128 if (WindowTitle
== NULL
)
129 WindowTitle
= &EmptyString
;
130 if (DesktopInfo
== NULL
)
131 DesktopInfo
= &EmptyString
;
132 if (ShellInfo
== NULL
)
133 ShellInfo
= &EmptyString
;
134 if (RuntimeInfo
== NULL
)
135 RuntimeInfo
= &EmptyString
;
137 /* size of process parameter block */
138 Length
= sizeof(RTL_USER_PROCESS_PARAMETERS
);
140 /* size of current directory buffer */
141 Length
+= (MAX_PATH
* sizeof(WCHAR
));
143 /* add string lengths */
144 Length
+= ALIGN(DllPath
->MaximumLength
, sizeof(ULONG
));
145 Length
+= ALIGN(ImagePathName
->Length
+ sizeof(WCHAR
), sizeof(ULONG
));
146 Length
+= ALIGN(CommandLine
->Length
+ sizeof(WCHAR
), sizeof(ULONG
));
147 Length
+= ALIGN(WindowTitle
->MaximumLength
, sizeof(ULONG
));
148 Length
+= ALIGN(DesktopInfo
->MaximumLength
, sizeof(ULONG
));
149 Length
+= ALIGN(ShellInfo
->MaximumLength
, sizeof(ULONG
));
150 Length
+= ALIGN(RuntimeInfo
->MaximumLength
, sizeof(ULONG
));
152 /* Calculate the required block size */
153 RegionSize
= ROUNDUP(Length
, PAGE_SIZE
);
155 Status
= NtAllocateVirtualMemory(NtCurrentProcess(),
159 MEM_RESERVE
| MEM_COMMIT
,
161 if (!NT_SUCCESS(Status
))
167 DPRINT ("Process parameters allocated\n");
169 Param
->AllocationSize
= RegionSize
;
170 Param
->Size
= Length
;
171 Param
->Flags
= PPF_NORMALIZED
;
172 Param
->Environment
= Environment
;
173 Param
->CurrentDirectoryHandle
= CurrentDirectoryHandle
;
174 Param
->hConsole
= ConsoleHandle
;
175 Param
->ProcessGroup
= ConsoleFlags
;
177 Dest
= (PWCHAR
)(((PBYTE
)Param
) + sizeof(RTL_USER_PROCESS_PARAMETERS
));
179 /* copy current directory */
180 RtlpCopyParameterString(&Dest
,
181 &Param
->CurrentDirectoryName
,
183 MAX_PATH
* sizeof(WCHAR
));
185 /* make sure the current directory has a trailing backslash */
186 if (Param
->CurrentDirectoryName
.Length
> 0)
190 Length
= Param
->CurrentDirectoryName
.Length
/ sizeof(WCHAR
);
191 if (Param
->CurrentDirectoryName
.Buffer
[Length
-1] != L
'\\')
193 Param
->CurrentDirectoryName
.Buffer
[Length
] = L
'\\';
194 Param
->CurrentDirectoryName
.Buffer
[Length
+ 1] = 0;
195 Param
->CurrentDirectoryName
.Length
+= sizeof(WCHAR
);
200 RtlpCopyParameterString(&Dest
,
205 /* copy image path name */
206 RtlpCopyParameterString(&Dest
,
207 &Param
->ImagePathName
,
209 ImagePathName
->Length
+ sizeof(WCHAR
));
211 /* copy command line */
212 RtlpCopyParameterString(&Dest
,
215 CommandLine
->Length
+ sizeof(WCHAR
));
218 RtlpCopyParameterString(&Dest
,
224 RtlpCopyParameterString(&Dest
,
229 /* copy shell info */
230 RtlpCopyParameterString(&Dest
,
235 /* copy runtime info */
236 RtlpCopyParameterString(&Dest
,
241 RtlDeNormalizeProcessParams(Param
);
242 *ProcessParameters
= Param
;
245 return STATUS_SUCCESS
;
252 RtlDestroyProcessParameters(PRTL_USER_PROCESS_PARAMETERS ProcessParameters
)
254 ULONG RegionSize
= 0;
256 return NtFreeVirtualMemory (NtCurrentProcess (),
257 (PVOID
)ProcessParameters
,
263 * denormalize process parameters (Pointer-->Offset)
267 PRTL_USER_PROCESS_PARAMETERS STDCALL
268 RtlDeNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params
)
270 if (Params
&& (Params
->Flags
& PPF_NORMALIZED
))
272 DENORMALIZE(Params
->CurrentDirectoryName
.Buffer
, Params
);
273 DENORMALIZE(Params
->DllPath
.Buffer
, Params
);
274 DENORMALIZE(Params
->ImagePathName
.Buffer
, Params
);
275 DENORMALIZE(Params
->CommandLine
.Buffer
, Params
);
276 DENORMALIZE(Params
->WindowTitle
.Buffer
, Params
);
277 DENORMALIZE(Params
->DesktopInfo
.Buffer
, Params
);
278 DENORMALIZE(Params
->ShellInfo
.Buffer
, Params
);
279 DENORMALIZE(Params
->RuntimeInfo
.Buffer
, Params
);
281 Params
->Flags
&= ~PPF_NORMALIZED
;
288 * normalize process parameters (Offset-->Pointer)
292 PRTL_USER_PROCESS_PARAMETERS STDCALL
293 RtlNormalizeProcessParams(PRTL_USER_PROCESS_PARAMETERS Params
)
295 if (Params
&& !(Params
->Flags
& PPF_NORMALIZED
))
297 NORMALIZE(Params
->CurrentDirectoryName
.Buffer
, Params
);
298 NORMALIZE(Params
->DllPath
.Buffer
, Params
);
299 NORMALIZE(Params
->ImagePathName
.Buffer
, Params
);
300 NORMALIZE(Params
->CommandLine
.Buffer
, Params
);
301 NORMALIZE(Params
->WindowTitle
.Buffer
, Params
);
302 NORMALIZE(Params
->DesktopInfo
.Buffer
, Params
);
303 NORMALIZE(Params
->ShellInfo
.Buffer
, Params
);
304 NORMALIZE(Params
->RuntimeInfo
.Buffer
, Params
);
306 Params
->Flags
|= PPF_NORMALIZED
;