[patch 6 of 7]: 0006-Rewrite-with-locking-of-getcwd-family-functions
Kai Tietz
ktietz70 at googlemail.com
Thu Dec 29 10:12:54 CST 2011
Hi,
this fixth patch adds locking support for getdcwd faimily routines (as
extension part for patch 5). It fixes some quirks about unhandled
error-checkings and AFAICS also corrects the handling of function
called with valid buf and size argument.
Regards,
Kai
-------------- next part --------------
From c69f2a4d918a6f20c31be63827d0a5c1a032abdf Mon Sep 17 00:00:00 2001
From: Kai Tietz <ktietz70 at googlemail.com>
Date: Thu, 29 Dec 2011 16:10:31 +0100
Subject: Rewrite with locking of getcwd-family functions
---
dlls/msvcrt/dir.c | 157 +++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 121 insertions(+), 36 deletions(-)
diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c
index 833d9d7..223439a 100644
--- a/dlls/msvcrt/dir.c
+++ b/dlls/msvcrt/dir.c
@@ -1047,39 +1047,80 @@ MSVCRT_wchar_t* CDECL MSVCRT__wgetcwd(MSVCRT_wchar_t * buf, int size)
*/
char* CDECL MSVCRT__getdcwd(int drive, char * buf, int size)
{
- static char* dummy;
+ char drivespec[] = {'A', ':', 0};
+ char s[4], *p, *fname;
+ int i, l;
+
+ if (buf && size <= 0)
+ {
+ *MSVCRT__errno() = MSVCRT_EINVAL;
+ return NULL;
+ }
TRACE(":drive %d(%c), size %d\n",drive, drive + 'A' - 1, size);
if (!drive || drive == MSVCRT__getdrive())
return MSVCRT__getcwd(buf,size); /* current */
- else
+
+ _lock (_ENV_LOCK);
+
+ drivespec[0] += drive - 1;
+ if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE)
{
- char dir[MAX_PATH];
- char drivespec[] = {'A', ':', 0};
- int dir_len;
+ *MSVCRT___doserrno() = ERROR_INVALID_DRIVE;
+ *MSVCRT__errno() = MSVCRT_EACCES;
+ _unlock (_ENV_LOCK);
+ return NULL;
+ }
- drivespec[0] += drive - 1;
- if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE)
+ if (buf)
{
- *MSVCRT__errno() = MSVCRT_EACCES;
- return NULL;
+ buf[0] = 0;
+ i = size;
}
+ strcpy (s, "A:.");
+ s[0] += drive - 1;
- dir_len = GetFullPathNameA(drivespec,MAX_PATH,dir,&dummy);
- if (dir_len >= size || dir_len < 1)
+ if ((l = GetFullPathNameA (s, i, buf, &fname)) == 0)
+ {
+ msvcrt_set_errno (GetLastError ());
+ _unlock (_ENV_LOCK);
+ return NULL;
+ }
+
+ if (buf != NULL)
+ {
+ if (l < i)
{
- *MSVCRT__errno() = MSVCRT_ERANGE;
- return NULL; /* buf too small */
+ _unlock (_ENV_LOCK);
+ return buf;
}
- TRACE(":returning '%s'\n", dir);
- if (!buf)
- return MSVCRT__strdup(dir); /* allocate */
+ *MSVCRT__errno() = MSVCRT_ERANGE;
+ *buf = 0;
+ _unlock (_ENV_LOCK);
+ return NULL;
+ }
- strcpy(buf,dir);
+ if (l > size)
+ size = l;
+
+ if ((p = (char *) MSVCRT_malloc (size)) == NULL)
+ {
+ msvcrt_set_errno (ERROR_NOT_ENOUGH_MEMORY);
+ _unlock (_ENV_LOCK);
+ return NULL;
}
- return buf;
+ memset (p, 0, size);
+ l = GetFullPathNameA (s, size, p, &fname);
+ if (!l || l >= size)
+ {
+ msvcrt_set_errno (GetLastError ());
+ _unlock (_ENV_LOCK);
+ return NULL;
+ }
+ _unlock (_ENV_LOCK);
+ return p;
}
/*********************************************************************
@@ -1089,38 +1130,82 @@ char* CDECL MSVCRT__getdcwd(int drive, char * buf, int size)
*/
MSVCRT_wchar_t* CDECL MSVCRT__wgetdcwd(int drive, MSVCRT_wchar_t * buf, int size)
{
- static MSVCRT_wchar_t* dummy;
+ char drivespec[] = {'A', ':', 0};
+ MSVCRT_wchar_t s[4], *p, *fname;
+ int i, l;
+
+ if (buf && size <= 0)
+ {
+ *MSVCRT__errno() = MSVCRT_EINVAL;
+ return NULL;
+ }
TRACE(":drive %d(%c), size %d\n",drive, drive + 'A' - 1, size);
if (!drive || drive == MSVCRT__getdrive())
return MSVCRT__wgetcwd(buf,size); /* current */
- else
+
+ _lock (_ENV_LOCK);
+
+ drivespec[0] += drive - 1;
+ if (GetDriveTypeA(drivespec) < DRIVE_REMOVABLE)
{
- MSVCRT_wchar_t dir[MAX_PATH];
- MSVCRT_wchar_t drivespec[4] = {'A', ':', '\\', 0};
- int dir_len;
+ *MSVCRT___doserrno() = ERROR_INVALID_DRIVE;
+ *MSVCRT__errno() = MSVCRT_EACCES;
+ _unlock (_ENV_LOCK);
+ return NULL;
+ }
- drivespec[0] += drive - 1;
- if (GetDriveTypeW(drivespec) < DRIVE_REMOVABLE)
+ if (buf)
{
- *MSVCRT__errno() = MSVCRT_EACCES;
- return NULL;
+ buf[0] = 0;
+ i = size;
}
+ s[0] = 'A' + drive - 1;
+ s[1] = ':';
+ s[2] = '.';
+ s[3] = 0;
- dir_len = GetFullPathNameW(drivespec,MAX_PATH,dir,&dummy);
- if (dir_len >= size || dir_len < 1)
+ if ((l = GetFullPathNameW (s, i, buf, &fname)) == 0)
+ {
+ msvcrt_set_errno (GetLastError ());
+ _unlock (_ENV_LOCK);
+ return NULL;
+ }
+
+ if (buf != NULL)
+ {
+ if (l < i)
{
- *MSVCRT__errno() = MSVCRT_ERANGE;
- return NULL; /* buf too small */
+ _unlock (_ENV_LOCK);
+ return buf;
}
- TRACE(":returning %s\n", debugstr_w(dir));
- if (!buf)
- return MSVCRT__wcsdup(dir); /* allocate */
- strcpyW(buf,dir);
+ *MSVCRT__errno() = MSVCRT_ERANGE;
+ *buf = 0;
+ _unlock (_ENV_LOCK);
+ return NULL;
}
- return buf;
+
+ if (l > size)
+ size = l;
+
+ if ((p = (char *) MSVCRT_malloc (size * sizeof (MSVCRT_wchar_t))) == NULL)
+ {
+ msvcrt_set_errno (ERROR_NOT_ENOUGH_MEMORY);
+ _unlock (_ENV_LOCK);
+ return NULL;
+ }
+ memset (p, 0, size * sizeof (MSVCRT_wchar_t));
+ l = GetFullPathNameW (s, size, p, &fname);
+ if (!l || l >= size)
+ {
+ msvcrt_set_errno (GetLastError ());
+ _unlock (_ENV_LOCK);
+ return NULL;
+ }
+ _unlock (_ENV_LOCK);
+ return p;
}
/*********************************************************************
--
1.7.5.1
More information about the wine-patches
mailing list