[PATCH 1/1] msvcrt: Set ?: environment variable in _(w)chdir functions.

Kai Tietz ktietz70 at googlemail.com
Thu Aug 8 12:22:54 CDT 2013


I noticed that the testcase was out of sync.  Fixed that.

Kai
-------------- next part --------------
From fc9e8e0776eaff17b4fbfaf2444a47d991d149ad Mon Sep 17 00:00:00 2001
From: Kai Tietz <ktietz70 at googlemail.com>
Date: Thu, 29 Dec 2011 11:51:39 +0100
Subject: [PATCH 1/7] msvcrt: Set ?: environment variable in _(w)chdir
 functions.

---
 dlls/msvcrt/dir.c       |   83 ++++++++++++++++++++++--
 dlls/msvcrt/tests/dir.c |  166 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 243 insertions(+), 6 deletions(-)

diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c
index fa87ac1..44802b3 100644
--- a/dlls/msvcrt/dir.c
+++ b/dlls/msvcrt/dir.c
@@ -249,15 +249,51 @@ static void msvcrt_wfttofd64i32( const WIN32_FIND_DATAW *fd, struct MSVCRT__wfin
  *
  * NOTES
  *  See SetCurrentDirectoryA.
+ *  Additional it sets for drive-paths the proper environment variable.
  */
 int CDECL MSVCRT__chdir(const char * newdir)
 {
-  if (!SetCurrentDirectoryA(newdir))
+  char env_name[4], adir[MAX_PATH + 1];
+  int r;
+
+  if (!newdir)
   {
-    msvcrt_set_errno(newdir?GetLastError():0);
+    *MSVCRT___doserrno() = 0;
+    *MSVCRT__errno() = MSVCRT_EINVAL;
     return -1;
   }
-  return 0;
+
+  if (!SetCurrentDirectoryA (newdir))
+  {
+    msvcrt_set_errno(GetLastError());
+    return -1;
+  }
+
+  /* Now take care we set environment.  */
+  if ((r = GetCurrentDirectoryA (MAX_PATH + 1, adir)) > MAX_PATH || r == 0)
+  {
+    msvcrt_set_errno ((GetLastError ()));
+    return -1;
+  }
+
+  /* See if we have UNC ... */
+  if ((adir[0] == '\\' || adir[0] == '/')
+      && (adir[1] == '\\' || adir[1] == '/'))
+    return 0;
+
+  env_name[0] = '=';
+  env_name[1] = adir[0];
+  env_name[2] = ':';
+  env_name[3] = 0;
+
+  if (env_name[1] >= 'a' && env_name[1] <= 'z')
+    env_name[1] += 'A' - 'a';
+
+  if (SetEnvironmentVariableA (env_name, adir))
+    return 0;
+
+  msvcrt_set_errno (GetLastError ());
+  return -1;
 }
 
 /*********************************************************************
@@ -267,12 +303,47 @@ int CDECL MSVCRT__chdir(const char * newdir)
  */
 int CDECL MSVCRT__wchdir(const MSVCRT_wchar_t * newdir)
 {
-  if (!SetCurrentDirectoryW(newdir))
+  MSVCRT_wchar_t env_name[4], adir[MAX_PATH + 1];
+  int r;
+
+  if (!newdir)
   {
-    msvcrt_set_errno(newdir?GetLastError():0);
+    *MSVCRT___doserrno () = 0;
+    *MSVCRT__errno () = MSVCRT_EINVAL;
     return -1;
   }
-  return 0;
+
+  if (!SetCurrentDirectoryW (newdir))
+  {
+    msvcrt_set_errno(GetLastError());
+    return -1;
+  }
+
+  /* Now take care we set environment.  */
+  if ((r = GetCurrentDirectoryW (MAX_PATH + 1, adir)) > MAX_PATH || r == 0)
+  {
+    msvcrt_set_errno ((GetLastError ()));
+    return -1;
+  }
+
+  /* See if we have UNC ... */
+  if ((adir[0] == '\\' || adir[0] == '/')
+      && (adir[1] == '\\' || adir[1] == '/'))
+    return 0;
+
+  env_name[0] = '=';
+  env_name[1] = adir[0];
+  env_name[2] = ':';
+  env_name[3] = 0;
+
+  if (env_name[1] >= 'a' && env_name[1] <= 'z')
+    env_name[1] += 'A' - 'a';
+
+  if (SetEnvironmentVariableW (env_name, adir))
+    return 0;
+
+  msvcrt_set_errno (GetLastError ());
+  return -1;
 }
 
 /*********************************************************************
diff --git a/dlls/msvcrt/tests/dir.c b/dlls/msvcrt/tests/dir.c
index 83c533b..6cc81d1 100644
--- a/dlls/msvcrt/tests/dir.c
+++ b/dlls/msvcrt/tests/dir.c
@@ -33,6 +33,13 @@
 
 static int (__cdecl *p_makepath_s)(char *, size_t, const char *, const char *, const char *, const char *);
 static int (__cdecl *p_wmakepath_s)(wchar_t *, size_t, const wchar_t *,const wchar_t *, const wchar_t *, const wchar_t *);
+static int (__cdecl *p_chdir)(const char *);
+static int (__cdecl *p_wchdir)(const wchar_t *);
+static int (__cdecl *p_mkdir)(const char *);
+static int (__cdecl *p_wmkdir)(const wchar_t *);
+static int (__cdecl *p_rmdir)(const char *);
+static int (__cdecl *p_wrmdir)(const wchar_t *);
+static int (__cdecl *p_getdrive)(void);
 
 static void init(void)
 {
@@ -40,6 +47,14 @@ static void init(void)
 
     p_makepath_s = (void *)GetProcAddress(hmod, "_makepath_s");
     p_wmakepath_s = (void *)GetProcAddress(hmod, "_wmakepath_s");
+
+    p_chdir = (void *)GetProcAddress(hmod, "_chdir");
+    p_wchdir = (void *)GetProcAddress(hmod, "_wchdir");
+    p_mkdir = (void *)GetProcAddress(hmod, "_mkdir");
+    p_wmkdir = (void *)GetProcAddress(hmod, "_wmkdir");
+    p_rmdir = (void *)GetProcAddress(hmod, "_rmdir");
+    p_wrmdir = (void *)GetProcAddress(hmod, "_wrmdir");
+    p_getdrive = (void *)GetProcAddress(hmod, "_getdrive");
 }
 
 typedef struct
@@ -390,6 +405,156 @@ static void test_fullpath(void)
         RemoveDirectory(level1);
 }
 
+static int get_env_varA (char *d, size_t dn)
+{
+  char s[4];
+  s[0] = '=';
+  s[1] = 'A' + (*p_getdrive) () - 1;
+  s[2] = ':';
+  s[3] = 0;
+  if (!GetEnvironmentVariableA (s, d, dn))
+    return 0;
+  return 1;
+}
+
+static int test_dirlenA (void)
+{
+  int m;
+  if ((*p_mkdir) ("abc"))
+   return 0;
+  if ((*p_chdir) ("abc"))
+    return 0;
+  m = test_dirlenA ();
+  (*p_chdir) ("..");
+  (*p_rmdir) ("abc");
+  return m + 4;
+}
+
+static int test_env_varA (void)
+{
+  char s1[MAX_PATH], s2[MAX_PATH], *p1, *p2;
+  if (!get_env_varA (s1, MAX_PATH))
+    return 0;
+  (*p_mkdir) ("a");
+  if ((*p_chdir) ("a"))
+    return 0;
+  if (!get_env_varA (s2, MAX_PATH))
+    return 0;
+  (*p_chdir) ("..");
+  (*p_rmdir) ("a");
+  p1 = s1; p2 = s2;
+  while (*p1 != 0 && *p2 != 0)
+    {
+      if (*p1 == *p2
+          || ((*p1 == '\\' || *p1 == '/') && (*p2 == '\\' || *p2 == '/')))
+        {
+	  p1++, p2++;
+	  continue;
+	}
+      break;
+    }
+  if (*p1 != 0)
+    return 0;
+  if (*p2 == '\\' || *p2 == '/')
+    p2++;
+  if (*p2 != 'a')
+    return 0;
+  p2++;
+  if (*p2 == '\\' || *p2 == '/')
+    p2++;
+  if (*p2 != 0)
+    return 0;
+  return 1;
+}
+
+static int get_env_varW (wchar_t *d, size_t dn)
+{
+  wchar_t s[4];
+  s[0] = '=';
+  s[1] = 'A' + (*p_getdrive) () - 1;
+  s[2] = ':';
+  s[3] = 0;
+  if (!GetEnvironmentVariableW (s, d, dn))
+    return 0;
+  return 1;
+}
+
+static int test_dirlenW (void)
+{
+  wchar_t dotdot[3] = { '.', '.', 0};
+  wchar_t abc[4] = { 'a', 'b', 'c', 0};
+  int m;
+  if ((*p_wmkdir) (abc))
+   return 0;
+  if ((*p_wchdir) (abc))
+    return 0;
+  m = test_dirlenW ();
+  (*p_wchdir) (dotdot);
+  (*p_wrmdir) (abc);
+  return m + 4;
+}
+
+static int test_env_varW (void)
+{
+  wchar_t s1[MAX_PATH], s2[MAX_PATH], *p1, *p2;
+  wchar_t a[2] = { 'a', 0 };
+  wchar_t dotdot[3] = { '.', '.', 0 };
+  if (!get_env_varW (s1, MAX_PATH))
+    return 0;
+  (*p_wmkdir) (a);
+  if ((*p_wchdir) (a))
+    return 0;
+  if (!get_env_varW (s2, MAX_PATH))
+    return 0;
+  (*p_wchdir) (dotdot);
+  (*p_wrmdir) (a);
+  p1 = s1; p2 = s2;
+  while (*p1 != 0 && *p2 != 0)
+    {
+      if (*p1 == *p2
+          || ((*p1 == '\\' || *p1 == '/') && (*p2 == '\\' || *p2 == '/')))
+        {
+	  p1++, p2++;
+	  continue;
+	}
+      break;
+    }
+  if (*p1 != 0)
+    return 0;
+  if (*p2 == '\\' || *p2 == '/')
+    p2++;
+  if (*p2 != 'a')
+    return 0;
+  p2++;
+  if (*p2 == '\\' || *p2 == '/')
+    p2++;
+  if (*p2 != 0)
+    return 0;
+  return 1;
+}
+
+static void test_chmkrmdirA (void)
+{
+  if (!p_rmdir || !p_chdir || !p_mkdir || !p_getdrive)
+  {
+      win_skip("ASCII variant of directory functions not present.\n");
+  }
+  else
+    {
+      ok(test_dirlenA () <= MAX_PATH, "Check that directory length is <= %u", MAX_PATH);
+      ok(test_env_varA (), "Test that environment-variables %s", "are set");
+    }
+  if (!p_wrmdir || !p_wchdir || !p_wmkdir || !p_getdrive)
+  {
+      win_skip("Wide variant of directory functions not present.\n");
+  }
+  else
+    {
+      ok(test_dirlenW () <= MAX_PATH, "Check that directory lenght is <= %u", MAX_PATH);
+      ok(test_env_varW (), "Test that environment-variables %s", "are set");
+    }
+}
+
 START_TEST(dir)
 {
     init();
@@ -397,4 +562,5 @@ START_TEST(dir)
     test_fullpath();
     test_makepath();
     test_makepath_s();
+    test_chmkrmdirA();
 }
-- 
1.7.9


More information about the wine-patches mailing list