Implemented RtlCreateProcessParameters and related functions.
diff --git a/dlls/ntdll/env.c b/dlls/ntdll/env.c
index 6ce84ac..5875f97 100644
--- a/dlls/ntdll/env.c
+++ b/dlls/ntdll/env.c
@@ -334,6 +334,153 @@
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 1509fa1..a0b74a2 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 bc8cd7a..1023187 100644
--- a/dlls/ntdll/rtl.c
+++ b/dlls/ntdll/rtl.c
@@ -340,15 +340,6 @@
}
/**************************************************************************
- * RtlNormalizeProcessParams [NTDLL.@]
- */
-LPVOID WINAPI RtlNormalizeProcessParams(LPVOID x)
-{
- FIXME("(%p), stub\n",x);
- return x;
-}
-
-/**************************************************************************
* RtlGetNtProductType [NTDLL.@]
*/
BOOLEAN WINAPI RtlGetNtProductType(LPDWORD type)
diff --git a/include/winternl.h b/include/winternl.h
index a6428a2..e3b6f72 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -114,6 +114,8 @@
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 @@
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 @@
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 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);