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 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 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 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 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 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