Aric Stewart : msvcrt: Reworked _fullpath.
Alexandre Julliard
julliard at wine.codeweavers.com
Fri Jan 6 14:49:33 CST 2006
Module: wine
Branch: refs/heads/master
Commit: e09a6c8080d511fd0c4d60462da9c7b3a61245d7
URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=e09a6c8080d511fd0c4d60462da9c7b3a61245d7
Author: Aric Stewart <aric at codeweavers.com>
Date: Fri Jan 6 21:45:26 2006 +0100
msvcrt: Reworked _fullpath.
Investigation with native msvcrt revealed that it is a wrapper for
GetFullPathName and the current implementation was crashing with older
mozilla installs if the path passed in was uninitialized.
---
dlls/msvcrt/dir.c | 315 ++++++-----------------------------------------------
1 files changed, 38 insertions(+), 277 deletions(-)
diff --git a/dlls/msvcrt/dir.c b/dlls/msvcrt/dir.c
index a47a273..fa757ac 100644
--- a/dlls/msvcrt/dir.c
+++ b/dlls/msvcrt/dir.c
@@ -738,113 +738,6 @@ void _wsplitpath(const MSVCRT_wchar_t *i
if (ext) strcpyW( ext, end );
}
-/* INTERNAL: Helper for _fullpath. Modified PD code from 'snippets'. */
-static void wmsvcrt_fln_fix(MSVCRT_wchar_t *path)
-{
- int dir_flag = 0, root_flag = 0;
- MSVCRT_wchar_t *r, *p, *q, *s;
- MSVCRT_wchar_t szbsdot[] = { '\\', '.', 0 };
-
- /* Skip drive */
- if (NULL == (r = strrchrW(path, ':')))
- r = path;
- else
- ++r;
-
- /* Ignore leading slashes */
- while ('\\' == *r)
- if ('\\' == r[1])
- strcpyW(r, &r[1]);
- else
- {
- root_flag = 1;
- ++r;
- }
-
- p = r; /* Change "\\" to "\" */
- while (NULL != (p = strchrW(p, '\\')))
- if ('\\' == p[1])
- strcpyW(p, &p[1]);
- else
- ++p;
-
- while ('.' == *r) /* Scrunch leading ".\" */
- {
- if ('.' == r[1])
- {
- /* Ignore leading ".." */
- for (p = (r += 2); *p && (*p != '\\'); ++p)
- ;
- }
- else
- {
- for (p = r + 1 ;*p && (*p != '\\'); ++p)
- ;
- }
- strcpyW(r, p + ((*p) ? 1 : 0));
- }
-
- while ('\\' == path[strlenW(path)-1]) /* Strip last '\\' */
- {
- dir_flag = 1;
- path[strlenW(path)-1] = '\0';
- }
-
- s = r;
-
- /* Look for "\." in path */
-
- while (NULL != (p = strstrW(s, szbsdot)))
- {
- if ('.' == p[2])
- {
- /* Execute this section if ".." found */
- q = p - 1;
- while (q > r) /* Backup one level */
- {
- if (*q == '\\')
- break;
- --q;
- }
- if (q > r)
- {
- strcpyW(q, p + 3);
- s = q;
- }
- else if ('.' != *q)
- {
- strcpyW(q + ((*q == '\\') ? 1 : 0),
- p + 3 + ((*(p + 3)) ? 1 : 0));
- s = q;
- }
- else s = ++p;
- }
- else
- {
- /* Execute this section if "." found */
- q = p + 2;
- for ( ;*q && (*q != '\\'); ++q)
- ;
- strcpyW (p, q);
- }
- }
-
- if (root_flag) /* Embedded ".." could have bubbled up to root */
- {
- for (p = r; *p && ('.' == *p || '\\' == *p); ++p)
- ;
- if (r != p)
- strcpyW(r, p);
- }
-
- if (dir_flag)
- {
- MSVCRT_wchar_t szbs[] = { '\\', 0 };
-
- strcatW(path, szbs);
- }
-}
-
/*********************************************************************
* _wfullpath (MSVCRT.@)
*
@@ -852,17 +745,23 @@ static void wmsvcrt_fln_fix(MSVCRT_wchar
*/
MSVCRT_wchar_t *_wfullpath(MSVCRT_wchar_t * absPath, const MSVCRT_wchar_t* relPath, MSVCRT_size_t size)
{
- MSVCRT_wchar_t drive[5],dir[MAX_PATH],file[MAX_PATH],ext[MAX_PATH];
- MSVCRT_wchar_t res[MAX_PATH];
- size_t len;
- MSVCRT_wchar_t szbs[] = { '\\', 0 };
-
-
- res[0] = '\0';
+ DWORD rc;
+ WCHAR* buffer;
+ WCHAR* lastpart;
+ BOOL alloced = FALSE;
if (!relPath || !*relPath)
return _wgetcwd(absPath, size);
+ if (absPath == NULL)
+ {
+ buffer = MSVCRT_malloc(MAX_PATH * sizeof(WCHAR));
+ size = MAX_PATH;
+ alloced = TRUE;
+ }
+ else
+ buffer = absPath;
+
if (size < 4)
{
*MSVCRT__errno() = MSVCRT_ERANGE;
@@ -871,140 +770,16 @@ MSVCRT_wchar_t *_wfullpath(MSVCRT_wchar_
TRACE(":resolving relative path '%s'\n",debugstr_w(relPath));
- _wsplitpath(relPath, drive, dir, file, ext);
+ rc = GetFullPathNameW(relPath,size,buffer,&lastpart);
- /* Get Directory and drive into 'res' */
- if (!dir[0] || (dir[0] != '/' && dir[0] != '\\'))
- {
- /* Relative or no directory given */
- _wgetdcwd(drive[0] ? toupper(drive[0]) - 'A' + 1 : 0, res, MAX_PATH);
- strcatW(res,szbs);
- if (dir[0])
- strcatW(res,dir);
- if (drive[0])
- res[0] = drive[0]; /* If given a drive, preserve the letter case */
- }
+ if (rc > 0 && rc <= size )
+ return buffer;
else
{
- strcpyW(res,drive);
- strcatW(res,dir);
+ if (alloced)
+ MSVCRT_free(buffer);
+ return NULL;
}
-
- strcatW(res,szbs);
- strcatW(res, file);
- strcatW(res, ext);
- wmsvcrt_fln_fix(res);
-
- len = strlenW(res);
- if (len >= MAX_PATH || len >= (size_t)size)
- return NULL; /* FIXME: errno? */
-
- if (!absPath)
- return _wcsdup(res);
- strcpyW(absPath,res);
- return absPath;
-}
-
-/* INTERNAL: Helper for _fullpath. Modified PD code from 'snippets'. */
-static void msvcrt_fln_fix(char *path)
-{
- int dir_flag = 0, root_flag = 0;
- char *r, *p, *q, *s;
-
- /* Skip drive */
- if (NULL == (r = strrchr(path, ':')))
- r = path;
- else
- ++r;
-
- /* Ignore leading slashes */
- while ('\\' == *r)
- if ('\\' == r[1])
- strcpy(r, &r[1]);
- else
- {
- root_flag = 1;
- ++r;
- }
-
- p = r; /* Change "\\" to "\" */
- while (NULL != (p = strchr(p, '\\')))
- if ('\\' == p[1])
- strcpy(p, &p[1]);
- else
- ++p;
-
- while ('.' == *r) /* Scrunch leading ".\" */
- {
- if ('.' == r[1])
- {
- /* Ignore leading ".." */
- for (p = (r += 2); *p && (*p != '\\'); ++p)
- ;
- }
- else
- {
- for (p = r + 1 ;*p && (*p != '\\'); ++p)
- ;
- }
- strcpy(r, p + ((*p) ? 1 : 0));
- }
-
- while ('\\' == path[strlen(path)-1]) /* Strip last '\\' */
- {
- dir_flag = 1;
- path[strlen(path)-1] = '\0';
- }
-
- s = r;
-
- /* Look for "\." in path */
-
- while (NULL != (p = strstr(s, "\\.")))
- {
- if ('.' == p[2])
- {
- /* Execute this section if ".." found */
- q = p - 1;
- while (q > r) /* Backup one level */
- {
- if (*q == '\\')
- break;
- --q;
- }
- if (q > r)
- {
- strcpy(q, p + 3);
- s = q;
- }
- else if ('.' != *q)
- {
- strcpy(q + ((*q == '\\') ? 1 : 0),
- p + 3 + ((*(p + 3)) ? 1 : 0));
- s = q;
- }
- else s = ++p;
- }
- else
- {
- /* Execute this section if "." found */
- q = p + 2;
- for ( ;*q && (*q != '\\'); ++q)
- ;
- strcpy (p, q);
- }
- }
-
- if (root_flag) /* Embedded ".." could have bubbled up to root */
- {
- for (p = r; *p && ('.' == *p || '\\' == *p); ++p)
- ;
- if (r != p)
- strcpy(r, p);
- }
-
- if (dir_flag)
- strcat(path, "\\");
}
/*********************************************************************
@@ -1024,15 +799,23 @@ static void msvcrt_fln_fix(char *path)
*/
char *_fullpath(char * absPath, const char* relPath, unsigned int size)
{
- char drive[5],dir[MAX_PATH],file[MAX_PATH],ext[MAX_PATH];
- char res[MAX_PATH];
- size_t len;
-
- res[0] = '\0';
+ DWORD rc;
+ char* lastpart;
+ char* buffer;
+ BOOL alloced = FALSE;
if (!relPath || !*relPath)
return _getcwd(absPath, size);
+ if (absPath == NULL)
+ {
+ buffer = MSVCRT_malloc(MAX_PATH);
+ size = MAX_PATH;
+ alloced = TRUE;
+ }
+ else
+ buffer = absPath;
+
if (size < 4)
{
*MSVCRT__errno() = MSVCRT_ERANGE;
@@ -1041,38 +824,16 @@ char *_fullpath(char * absPath, const ch
TRACE(":resolving relative path '%s'\n",relPath);
- _splitpath(relPath, drive, dir, file, ext);
+ rc = GetFullPathNameA(relPath,size,buffer,&lastpart);
- /* Get Directory and drive into 'res' */
- if (!dir[0] || (dir[0] != '/' && dir[0] != '\\'))
- {
- /* Relative or no directory given */
- _getdcwd(drive[0] ? toupper(drive[0]) - 'A' + 1 : 0, res, MAX_PATH);
- strcat(res,"\\");
- if (dir[0])
- strcat(res,dir);
- if (drive[0])
- res[0] = drive[0]; /* If given a drive, preserve the letter case */
- }
+ if (rc > 0 && rc <= size)
+ return buffer;
else
{
- strcpy(res,drive);
- strcat(res,dir);
+ if (alloced)
+ MSVCRT_free(buffer);
+ return NULL;
}
-
- strcat(res,"\\");
- strcat(res, file);
- strcat(res, ext);
- msvcrt_fln_fix(res);
-
- len = strlen(res);
- if (len >= MAX_PATH || len >= (size_t)size)
- return NULL; /* FIXME: errno? */
-
- if (!absPath)
- return _strdup(res);
- strcpy(absPath,res);
- return absPath;
}
/*********************************************************************
More information about the wine-cvs
mailing list