[PATCH 1/2] msvcp140: Implement _Temp_get.

Stefan Dösinger stefan at codeweavers.com
Fri Dec 8 14:15:38 CST 2017


Signed-off-by: Stefan Dösinger <stefan at codeweavers.com>

---

I tried to test what happens if the temp path is longer than MAX_PATH
characters, but I could not get Windows to accept a long temp path. If
%TMP% is longer than 100 characters (or somewhere in that area, I did
not test the precise limit) it falls back to %TEMP%, %USERPROFILE% and
finally "C:\Windows".

I assume msvcp does not clear the extra bytes like GetTempPathW either
because it doesn't call GetTempPath and implements the logic itself or
because it writes to a temp buffer and copies the data. I don't know how
to trigger this possible case even with a manual test on Windows.
---
 dlls/msvcp140/msvcp140.spec    |  2 +-
 dlls/msvcp140/tests/msvcp140.c | 27 +++++++++++++++++++++++++++
 dlls/msvcp90/ios.c             |  6 ++++++
 3 files changed, 34 insertions(+), 1 deletion(-)

diff --git a/dlls/msvcp140/msvcp140.spec b/dlls/msvcp140/msvcp140.spec
index 4fc8e3c5d5..3cd1975adf 100644
--- a/dlls/msvcp140/msvcp140.spec
+++ b/dlls/msvcp140/msvcp140.spec
@@ -3718,7 +3718,7 @@
 @ stub _Strxfrm
 @ cdecl _Symlink(wstr wstr) tr2_sys__Symlink_wchar
 @ stub _Symlink_get
-@ stub _Temp_get
+@ cdecl _Temp_get(ptr)
 @ stub _Thrd_abort
 @ cdecl _Thrd_create(ptr ptr ptr) _Thrd_create
 @ cdecl -norelay _Thrd_current()
diff --git a/dlls/msvcp140/tests/msvcp140.c b/dlls/msvcp140/tests/msvcp140.c
index 620e9317c9..01ed89aceb 100644
--- a/dlls/msvcp140/tests/msvcp140.c
+++ b/dlls/msvcp140/tests/msvcp140.c
@@ -177,6 +177,7 @@ static WCHAR* (__cdecl *p_Read_dir)(WCHAR*, void*, enum file_type*);
 static MSVCP_bool (__cdecl *p_Remove_dir)(WCHAR const*);
 static enum file_type (__cdecl *p_Stat)(WCHAR const *, int *);
 static int (__cdecl *p_Symlink)(WCHAR const*, WCHAR const*);
+static WCHAR* (__cdecl *p_Temp_get)(WCHAR *);
 static int (__cdecl *p_To_byte)(const WCHAR *src, char *dst);
 static int (__cdecl *p_To_wide)(const char *src, WCHAR *dst);
 static int (__cdecl *p_Unlink)(WCHAR const*);
@@ -258,6 +259,7 @@ static BOOL init(void)
     SET(p_Remove_dir, "_Remove_dir");
     SET(p_Stat, "_Stat");
     SET(p_Symlink, "_Symlink");
+    SET(p_Temp_get, "_Temp_get");
     SET(p_To_byte, "_To_byte");
     SET(p_To_wide, "_To_wide");
     SET(p_Unlink, "_Unlink");
@@ -1054,6 +1056,30 @@ static void test_Unlink(void)
     ok(SetCurrentDirectoryW(current_path), "SetCurrentDirectoryW failed\n");
 }
 
+static void test_Temp_get(void)
+{
+    WCHAR path[MAX_PATH + 1], temp_path[MAX_PATH];
+    WCHAR *retval;
+    DWORD len;
+
+    GetTempPathW(sizeof(temp_path)/sizeof(*temp_path), temp_path);
+
+    /* This crashes on Windows, the input pointer is not validated. */
+    if (0)
+    {
+        retval = p_Temp_get(NULL);
+        ok(!retval, "_Temp_get(): Got %p\n", retval);
+    }
+
+    memset(path, 0xaa, sizeof(path));
+    retval = p_Temp_get(path);
+    ok(retval == path, "_Temp_get(): Got %p, expected %p\n", retval, path);
+    ok(!wcscmp(path, temp_path), "Expected path %s, got %s\n", wine_dbgstr_w(temp_path), wine_dbgstr_w(path));
+    len = wcslen(path);
+    ok(!path[len], "Expected a 0 terminated string\n");
+    todo_wine ok(path[len + 1] == 0xaaaa, "Too many bytes were zeroed - %x\n", path[len + 1]);
+}
+
 START_TEST(msvcp140)
 {
     if(!init()) return;
@@ -1071,5 +1097,6 @@ START_TEST(msvcp140)
     test_Stat();
     test_dir_operation();
     test_Unlink();
+    test_Temp_get();
     FreeLibrary(msvcp);
 }
diff --git a/dlls/msvcp90/ios.c b/dlls/msvcp90/ios.c
index 3f859979cb..ab9d7a44a4 100644
--- a/dlls/msvcp90/ios.c
+++ b/dlls/msvcp90/ios.c
@@ -15745,6 +15745,12 @@ enum file_type __cdecl _Lstat(WCHAR const* path, int* permissions)
     return _Stat(path, permissions);
 }
 
+WCHAR * __cdecl _Temp_get(WCHAR *dst)
+{
+    GetTempPathW(MAX_PATH, dst);
+    return dst;
+}
+
 /* ??1_Winit at std@@QAE at XZ */
 /* ??1_Winit at std@@QAE at XZ */
 DEFINE_THISCALL_WRAPPER(_Winit_dtor, 4)
-- 
2.13.6




More information about the wine-devel mailing list