diff --git a/dlls/ntdll/env.c b/dlls/ntdll/env.c index 6ce84ac4db1..5875f97aed6 100644 --- a/dlls/ntdll/env.c +++ b/dlls/ntdll/env.c @@ -334,6 +334,153 @@ NTSTATUS WINAPI RtlExpandEnvironmentStrings_U(PWSTR renv, const UNICODE_STRING* return (count) ? STATUS_SUCCESS : STATUS_BUFFER_TOO_SMALL; } + +static inline void normalize( void *base, WCHAR **ptr ) +{ + if (*ptr) *ptr = (WCHAR *)((char *)base + (UINT_PTR)*ptr); +} + +/****************************************************************************** + * RtlNormalizeProcessParams [NTDLL.@] + */ +PRTL_USER_PROCESS_PARAMETERS WINAPI RtlNormalizeProcessParams( RTL_USER_PROCESS_PARAMETERS *params ) +{ + if (params && !(params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED)) + { + normalize( params, ¶ms->CurrentDirectoryName.Buffer ); + normalize( params, ¶ms->DllPath.Buffer ); + normalize( params, ¶ms->ImagePathName.Buffer ); + normalize( params, ¶ms->CommandLine.Buffer ); + normalize( params, ¶ms->WindowTitle.Buffer ); + normalize( params, ¶ms->Desktop.Buffer ); + normalize( params, ¶ms->ShellInfo.Buffer ); + normalize( params, ¶ms->RuntimeInfo.Buffer ); + params->Flags |= PROCESS_PARAMS_FLAG_NORMALIZED; + } + return params; +} + + +static inline void denormalize( void *base, WCHAR **ptr ) +{ + if (*ptr) *ptr = (WCHAR *)(UINT_PTR)((char *)*ptr - (char *)base); +} + +/****************************************************************************** + * RtlDeNormalizeProcessParams [NTDLL.@] + */ +PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams( RTL_USER_PROCESS_PARAMETERS *params ) +{ + if (params && (params->Flags & PROCESS_PARAMS_FLAG_NORMALIZED)) + { + denormalize( params, ¶ms->CurrentDirectoryName.Buffer ); + denormalize( params, ¶ms->DllPath.Buffer ); + denormalize( params, ¶ms->ImagePathName.Buffer ); + denormalize( params, ¶ms->CommandLine.Buffer ); + denormalize( params, ¶ms->WindowTitle.Buffer ); + denormalize( params, ¶ms->Desktop.Buffer ); + denormalize( params, ¶ms->ShellInfo.Buffer ); + denormalize( params, ¶ms->RuntimeInfo.Buffer ); + params->Flags &= ~PROCESS_PARAMS_FLAG_NORMALIZED; + } + return params; +} + + +/* append a unicode string to the process params data; helper for RtlCreateProcessParameters */ +static void append_unicode_string( void **data, const UNICODE_STRING *src, + UNICODE_STRING *dst ) +{ + dst->Length = src->Length; + dst->MaximumLength = src->MaximumLength; + dst->Buffer = *data; + memcpy( dst->Buffer, src->Buffer, dst->MaximumLength ); + *data = (char *)dst->Buffer + dst->MaximumLength; +} + + +/****************************************************************************** + * RtlCreateProcessParameters [NTDLL.@] + */ +NTSTATUS WINAPI RtlCreateProcessParameters( RTL_USER_PROCESS_PARAMETERS **result, + const UNICODE_STRING *ImagePathName, + const UNICODE_STRING *DllPath, + const UNICODE_STRING *CurrentDirectoryName, + const UNICODE_STRING *CommandLine, + PWSTR Environment, + const UNICODE_STRING *WindowTitle, + const UNICODE_STRING *Desktop, + const UNICODE_STRING *ShellInfo, + const UNICODE_STRING *RuntimeInfo ) +{ + static const WCHAR empty[] = {0}; + static const UNICODE_STRING empty_str = { 0, sizeof(empty), (WCHAR *)empty }; + + const RTL_USER_PROCESS_PARAMETERS *cur_params; + ULONG size, total_size; + void *ptr; + NTSTATUS status; + + RtlAcquirePebLock(); + cur_params = NtCurrentTeb()->Peb->ProcessParameters; + if (!DllPath) DllPath = &cur_params->DllPath; + if (!CurrentDirectoryName) CurrentDirectoryName = &cur_params->CurrentDirectoryName; + if (!CommandLine) CommandLine = ImagePathName; + if (!Environment) Environment = cur_params->Environment; + if (!WindowTitle) WindowTitle = &empty_str; + if (!Desktop) Desktop = &empty_str; + if (!ShellInfo) ShellInfo = &empty_str; + if (!RuntimeInfo) RuntimeInfo = &empty_str; + + size = (sizeof(RTL_USER_PROCESS_PARAMETERS) + + ImagePathName->MaximumLength + + DllPath->MaximumLength + + CurrentDirectoryName->MaximumLength + + CommandLine->MaximumLength + + WindowTitle->MaximumLength + + Desktop->MaximumLength + + ShellInfo->MaximumLength + + RuntimeInfo->MaximumLength); + + total_size = size; + if ((status = NtAllocateVirtualMemory( NtCurrentProcess(), &ptr, NULL, &total_size, + MEM_COMMIT, PAGE_READWRITE )) == STATUS_SUCCESS) + { + RTL_USER_PROCESS_PARAMETERS *params = ptr; + params->AllocationSize = total_size; + params->Size = size; + params->Flags = PROCESS_PARAMS_FLAG_NORMALIZED; + params->ProcessGroup = cur_params->ProcessGroup; + params->Environment = Environment; + /* all other fields are zero */ + + ptr = params + 1; + append_unicode_string( &ptr, CurrentDirectoryName, ¶ms->CurrentDirectoryName ); + append_unicode_string( &ptr, DllPath, ¶ms->DllPath ); + append_unicode_string( &ptr, ImagePathName, ¶ms->ImagePathName ); + append_unicode_string( &ptr, CommandLine, ¶ms->CommandLine ); + append_unicode_string( &ptr, WindowTitle, ¶ms->WindowTitle ); + append_unicode_string( &ptr, Desktop, ¶ms->Desktop ); + append_unicode_string( &ptr, ShellInfo, ¶ms->ShellInfo ); + append_unicode_string( &ptr, RuntimeInfo, ¶ms->RuntimeInfo ); + *result = RtlDeNormalizeProcessParams( params ); + } + RtlReleasePebLock(); + return status; +} + + +/****************************************************************************** + * RtlDestroyProcessParameters [NTDLL.@] + */ +void WINAPI RtlDestroyProcessParameters( RTL_USER_PROCESS_PARAMETERS *params ) +{ + void *ptr = params; + ULONG size = 0; + NtFreeVirtualMemory( NtCurrentProcess(), &ptr, &size, MEM_RELEASE ); +} + + /*********************************************************************** * build_environment * diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec index 1509fa11f66..a0b74a246d2 100644 --- a/dlls/ntdll/ntdll.spec +++ b/dlls/ntdll/ntdll.spec @@ -323,7 +323,7 @@ @ stub RtlCreateAndSetSD @ stdcall RtlCreateEnvironment(long ptr) @ stdcall RtlCreateHeap(long ptr long long ptr ptr) -@ stub RtlCreateProcessParameters +@ stdcall RtlCreateProcessParameters(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr) @ stub RtlCreateQueryDebugBuffer @ stub RtlCreateRegistryKey @ stdcall RtlCreateSecurityDescriptor(ptr long) @@ -335,7 +335,7 @@ @ stub RtlCreateUserThread @ stub RtlCustomCPToUnicodeN @ stub RtlCutoverTimeToSystemTime -@ stub RtlDeNormalizeProcessParams +@ stdcall RtlDeNormalizeProcessParams(ptr) @ stub RtlDecompressBuffer @ stub RtlDecompressFragment @ stub RtlDelete @@ -347,7 +347,7 @@ @ stdcall RtlDeleteSecurityObject(long) @ stdcall RtlDestroyEnvironment(ptr) @ stdcall RtlDestroyHeap(long) -@ stub RtlDestroyProcessParameters +@ stdcall RtlDestroyProcessParameters(ptr) @ stub RtlDestroyQueryDebugBuffer @ stdcall RtlDetermineDosPathNameType_U(wstr) @ stdcall RtlDoesFileExists_U(wstr) diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c index bc8cd7a55e2..1023187109a 100644 --- a/dlls/ntdll/rtl.c +++ b/dlls/ntdll/rtl.c @@ -339,15 +339,6 @@ DWORD WINAPI RtlDeleteSecurityObject(DWORD x1) { return 0; } -/************************************************************************** - * RtlNormalizeProcessParams [NTDLL.@] - */ -LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x) -{ - FIXME("(%p), stub\n",x); - return x; -} - /************************************************************************** * RtlGetNtProductType [NTDLL.@] */ diff --git a/include/winternl.h b/include/winternl.h index a6428a227f9..e3b6f72ef41 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -114,6 +114,8 @@ typedef struct _RTL_USER_PROCESS_PARAMETERS RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20]; } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; +/* value for Flags field (FIXME: not the correct name) */ +#define PROCESS_PARAMS_FLAG_NORMALIZED 1 typedef struct _PEB_LDR_DATA { @@ -1080,6 +1082,11 @@ void WINAPI RtlCopyUnicodeString(UNICODE_STRING*,const UNICODE_STRING*); NTSTATUS WINAPI RtlCreateAcl(PACL,DWORD,DWORD); NTSTATUS WINAPI RtlCreateEnvironment(BOOLEAN, PWSTR*); HANDLE WINAPI RtlCreateHeap(ULONG,PVOID,ULONG,ULONG,PVOID,PRTL_HEAP_DEFINITION); +NTSTATUS WINAPI RtlCreateProcessParameters(RTL_USER_PROCESS_PARAMETERS**,const UNICODE_STRING*, + const UNICODE_STRING*,const UNICODE_STRING*, + const UNICODE_STRING*,PWSTR,const UNICODE_STRING*, + const UNICODE_STRING*,const UNICODE_STRING*, + const UNICODE_STRING*); NTSTATUS WINAPI RtlCreateSecurityDescriptor(PSECURITY_DESCRIPTOR,DWORD); BOOLEAN WINAPI RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR); BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR); @@ -1087,8 +1094,10 @@ BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR); NTSTATUS WINAPI RtlDeleteCriticalSection(RTL_CRITICAL_SECTION *); void WINAPI RtlDeleteResource(LPRTL_RWLOCK); DWORD WINAPI RtlDeleteSecurityObject(DWORD); +PRTL_USER_PROCESS_PARAMETERS WINAPI RtlDeNormalizeProcessParams(RTL_USER_PROCESS_PARAMETERS*); NTSTATUS WINAPI RtlDestroyEnvironment(PWSTR); HANDLE WINAPI RtlDestroyHeap(HANDLE); +void WINAPI RtlDestroyProcessParameters(RTL_USER_PROCESS_PARAMETERS*); DOS_PATHNAME_TYPE WINAPI RtlDetermineDosPathNameType_U(PCWSTR); BOOLEAN WINAPI RtlDoesFileExists_U(LPCWSTR); BOOLEAN WINAPI RtlDosPathNameToNtPathName_U(LPWSTR,PUNICODE_STRING,PWSTR*,CURDIR*); @@ -1196,7 +1205,7 @@ NTSTATUS WINAPI RtlMultiByteToUnicodeN(LPWSTR,DWORD,LPDWORD,LPCSTR,DWORD); NTSTATUS WINAPI RtlMultiByteToUnicodeSize(DWORD*,LPCSTR,UINT); DWORD WINAPI RtlNewSecurityObject(DWORD,DWORD,DWORD,DWORD,DWORD,DWORD); -LPVOID WINAPI RtlNormalizeProcessParams(LPVOID); +PRTL_USER_PROCESS_PARAMETERS WINAPI RtlNormalizeProcessParams(RTL_USER_PROCESS_PARAMETERS*); ULONG WINAPI RtlNtStatusToDosError(NTSTATUS); ULONG WINAPI RtlNumberOfSetBits(PCRTL_BITMAP); ULONG WINAPI RtlNumberOfClearBits(PCRTL_BITMAP);