[PATCH 1/1] msvcrt: Set ?: environment variable in _(w)chdir functions.
Kai Tietz
ktietz70 at googlemail.com
Thu Aug 8 11:44:26 CDT 2013
Hi,
this patch sets environment-variable Ä<drive-letter>=' on call of
_wchdir/_chdir.
Ok for apply?
Kai
-------------- next part --------------
From 59bb61f1c89b51963c00dff6e3fbf03d1eab6f48 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/1] msvcrt: Set ?: environment variable in _(w)chdir
functions.
---
dlls/msvcrt/dir.c | 83 ++++++++++++++++++++++--
dlls/msvcrt/tests/dir.c | 161 +++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 238 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..8c5c243 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,152 @@ 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 (!GetEnvironmentVariableA (s, d, dn))
+ return 0;
+ return 1;
+}
+
+static int test_dirlenW (void)
+{
+ int m;
+ if ((*p_wmkdir) (L"abc"))
+ return 0;
+ if ((*p_wchdir) (L"abc"))
+ return 0;
+ m = test_dirlenW ();
+ (*p_wchdir) (L"..");
+ (*p_wrmdir) (L"abc");
+ return m + 4;
+}
+
+static int test_env_varW (void)
+{
+ wchar_t s1[MAX_PATH], s2[MAX_PATH], *p1, *p2;
+ if (!get_env_varW (s1, MAX_PATH))
+ return 0;
+ (*p_wmkdir) (L"a");
+ if ((*p_wchdir) (L"a"))
+ return 0;
+ if (!get_env_varW (s2, MAX_PATH))
+ return 0;
+ (*p_wchdir) (L"..");
+ (*p_wrmdir) (L"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);
+ ok(test_env_varA ());
+ }
+ 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);
+ ok(test_env_varW ());
+ }
+}
+
START_TEST(dir)
{
init();
--
1.7.9
More information about the wine-patches
mailing list