From b47be04e640f03748edc8a5e6693c37df2a68d27 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 30 Aug 2015 08:38:30 +0200
Subject: kernel32: Allow non-nullterminated string as working directory in
 create_startup_info.

---
 dlls/kernel32/process.c | 31 ++++++++++++++++++-------------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index a40f124..6622fcb 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -1629,7 +1629,7 @@ static startup_info_t *create_startup_info( LPCWSTR filename, LPCWSTR cmdline,
     const RTL_USER_PROCESS_PARAMETERS *cur_params;
     const WCHAR *title;
     startup_info_t *info;
-    DWORD size;
+    DWORD size, cur_dir_length;
     void *ptr;
     UNICODE_STRING newdir;
     WCHAR imagepath[MAX_PATH];
@@ -1643,24 +1643,27 @@ static startup_info_t *create_startup_info( LPCWSTR filename, LPCWSTR cmdline,
     cur_params = NtCurrentTeb()->Peb->ProcessParameters;
 
     newdir.Buffer = NULL;
-    if (cur_dir)
+    if (cur_dir && RtlDosPathNameToNtPathName_U( cur_dir, &newdir, NULL, NULL ))
     {
-        if (RtlDosPathNameToNtPathName_U( cur_dir, &newdir, NULL, NULL ))
-            cur_dir = newdir.Buffer + 4;  /* skip \??\ prefix */
-        else
-            cur_dir = NULL;
+        cur_dir = newdir.Buffer + 4;  /* skip \??\ prefix */
+        cur_dir_length = newdir.Length - 4 * sizeof(WCHAR);
     }
-    if (!cur_dir)
+    else if (NtCurrentTeb()->Tib.SubSystemTib)  /* FIXME: hack */
     {
-        if (NtCurrentTeb()->Tib.SubSystemTib)  /* FIXME: hack */
-            cur_dir = ((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir.DosPath.Buffer;
-        else
-            cur_dir = cur_params->CurrentDirectory.DosPath.Buffer;
+        const UNICODE_STRING *dir = &((WIN16_SUBSYSTEM_TIB *)NtCurrentTeb()->Tib.SubSystemTib)->curdir.DosPath;
+        cur_dir = dir->Buffer;
+        cur_dir_length = dir->Length;
+    }
+    else
+    {
+        const UNICODE_STRING *dir = &cur_params->CurrentDirectory.DosPath;
+        cur_dir = dir->Buffer;
+        cur_dir_length = dir->Length;
     }
     title = startup->lpTitle ? startup->lpTitle : imagepath;
 
     size = sizeof(*info);
-    size += strlenW( cur_dir ) * sizeof(WCHAR);
+    size += cur_dir_length;
     size += cur_params->DllPath.Length;
     size += strlenW( imagepath ) * sizeof(WCHAR);
     size += strlenW( cmdline ) * sizeof(WCHAR);
@@ -1717,7 +1720,9 @@ static startup_info_t *create_startup_info( LPCWSTR filename, LPCWSTR cmdline,
     info->show      = startup->wShowWindow;
 
     ptr = info + 1;
-    info->curdir_len = append_string( &ptr, cur_dir );
+    info->curdir_len = cur_dir_length;
+    memcpy( ptr, cur_dir, cur_dir_length );
+    ptr = (char *)ptr + cur_dir_length;
     info->dllpath_len = cur_params->DllPath.Length;
     memcpy( ptr, cur_params->DllPath.Buffer, cur_params->DllPath.Length );
     ptr = (char *)ptr + cur_params->DllPath.Length;
-- 
2.5.0

