Module: wine Branch: refs/heads/master Commit: e09a6c8080d511fd0c4d60462da9c7b3a61245d7 URL: http://source.winehq.org/git/?p=wine.git;a=commit;h=e09a6c8080d511fd0c4d6046...
Author: Aric Stewart aric@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; }
/*********************************************************************