kernel32: GetShortPathNameW should accept paths starting with "\\?\".
Rein Klazes
wijn at online.nl
Thu Aug 6 06:02:19 CDT 2009
Makes ConvertXtoDVD in bug#17479 proceed a little further.
---
dlls/kernel32/path.c | 32 +++++++++++++++++++++++++++-----
dlls/kernel32/tests/path.c | 7 +++++++
2 files changed, 34 insertions(+), 5 deletions(-)
diff --git a/dlls/kernel32/path.c b/dlls/kernel32/path.c
index 299db1c..47f3168 100644
--- a/dlls/kernel32/path.c
+++ b/dlls/kernel32/path.c
@@ -429,6 +429,7 @@ DWORD WINAPI GetLongPathNameA( LPCSTR shortpath, LPSTR longpath, DWORD longlen )
*/
DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortlen )
{
+ static const WCHAR LongFileNamePfxW[4] = {'\\','\\','?','\\'};
WCHAR tmpshortpath[MAX_PATHNAME_LEN];
LPCWSTR p;
DWORD sp = 0, lp = 0;
@@ -451,19 +452,27 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
return 0;
}
+ /* skip "\\?\" */
+ if( !strncmpW( longpath, LongFileNamePfxW, 4))
+ {
+ memcpy( tmpshortpath, longpath, 4 * sizeof(WCHAR));
+ sp = 4;
+ lp = 4;
+ }
+
/* check for drive letter */
- if (longpath[0] != '/' && longpath[1] == ':' )
+ if (longpath[lp] != '/' && longpath[lp+1] == ':' )
{
- tmpshortpath[0] = longpath[0];
- tmpshortpath[1] = ':';
- sp = lp = 2;
+ tmpshortpath[sp++] = longpath[lp];
+ tmpshortpath[sp++] = ':';
+ lp += 2;
}
ustr.Buffer = ustr_buf;
ustr.Length = 0;
ustr.MaximumLength = sizeof(ustr_buf);
- while (longpath[lp])
+ while (longpath[lp] && sp < MAX_PATHNAME_LEN)
{
/* check for path delimiters and reproduce them */
if (longpath[lp] == '\\' || longpath[lp] == '/')
@@ -473,6 +482,7 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
/* strip double "\\" */
tmpshortpath[sp] = '\\';
sp++;
+ if( sp >= MAX_PATHNAME_LEN) continue;
}
tmpshortpath[sp] = 0; /* terminate string */
lp++;
@@ -481,6 +491,12 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
for (p = longpath + lp; *p && *p != '/' && *p != '\\'; p++);
tmplen = p - (longpath + lp);
+ /* is there enough space for what we are trying to do ? */
+ if( sp + tmplen + 1 >= MAX_PATHNAME_LEN)
+ {
+ sp = MAX_PATHNAME_LEN;
+ continue;
+ }
lstrcpynW(tmpshortpath + sp, longpath + lp, tmplen + 1);
/* Check, if the current element is a valid dos name */
if (tmplen <= 8+1+3)
@@ -505,6 +521,12 @@ DWORD WINAPI GetShortPathNameW( LPCWSTR longpath, LPWSTR shortpath, DWORD shortl
sp += strlenW(tmpshortpath + sp);
lp += tmplen;
}
+
+ if( sp >= MAX_PATHNAME_LEN) {
+ ERR("Insufficient space in internal buffer!\n");
+ return 0;
+ }
+
tmpshortpath[sp] = 0;
tmplen = strlenW(tmpshortpath) + 1;
diff --git a/dlls/kernel32/tests/path.c b/dlls/kernel32/tests/path.c
index de26fc9..585ce73 100644
--- a/dlls/kernel32/tests/path.c
+++ b/dlls/kernel32/tests/path.c
@@ -982,6 +982,7 @@ static void test_GetShortPathNameW(void)
{
WCHAR test_path[] = { 'L', 'o', 'n', 'g', 'D', 'i', 'r', 'e', 'c', 't', 'o', 'r', 'y', 'N', 'a', 'm', 'e', 0 };
WCHAR path[MAX_PATH];
+ WCHAR pathex[MAX_PATH] = { '\\', '\\', '?', '\\', 0};
WCHAR short_path[MAX_PATH];
DWORD length;
HANDLE file;
@@ -1001,6 +1002,7 @@ static void test_GetShortPathNameW(void)
lstrcatW( path, backSlash );
ret = CreateDirectoryW( path, NULL );
ok( ret, "Directory was not created. LastError = %d\n", GetLastError() );
+ lstrcatW( pathex, path);
/* Starting a main part of test */
length = GetShortPathNameW( path, short_path, 0 );
@@ -1010,6 +1012,11 @@ static void test_GetShortPathNameW(void)
lstrcatW( short_path, name );
file = CreateFileW( short_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
ok( file != INVALID_HANDLE_VALUE, "File was not created.\n" );
+ /* test with the path starting with \\?\ */
+ length = GetShortPathNameW( pathex, short_path, MAX_PATH );
+ ok( length, "GetShortPathNameW returned 0.\n" );
+ ok( !wcsncmp( pathex, short_path, 4), "Short path should begin with \"\\\\?\\\"\n");
+ lstrcatW( short_path, name );
/* End test */
CloseHandle( file );
--
1.6.3.3
More information about the wine-patches
mailing list