Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
9ccb73a8
Commit
9ccb73a8
authored
Jan 15, 2004
by
Eric Pouech
Committed by
Alexandre Julliard
Jan 15, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Reimplemented Get{Short|Long}PathName and updated the regression
tests.
parent
87323579
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
370 additions
and
296 deletions
+370
-296
Makefile.in
dlls/kernel/Makefile.in
+1
-0
path.c
dlls/kernel/path.c
+352
-0
path.c
dlls/kernel/tests/path.c
+15
-23
path.c
dlls/ntdll/path.c
+2
-1
dos_fs.c
files/dos_fs.c
+0
-272
No files found.
dlls/kernel/Makefile.in
View file @
9ccb73a8
...
...
@@ -51,6 +51,7 @@ C_SRCS = \
module.c
\
ne_module.c
\
ne_segment.c
\
path.c
\
powermgnt.c
\
process.c
\
profile.c
\
...
...
dlls/kernel/path.c
0 → 100644
View file @
9ccb73a8
/*
* File handling functions
*
* Copyright 1993 Erik Bos
* Copyright 1996 Alexandre Julliard
* Copyright 2003 Eric Pouech
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
#include "config.h"
#include "wine/port.h"
#include <stdarg.h>
#define NONAMELESSUNION
#define NONAMELESSSTRUCT
#include "winerror.h"
#include "ntstatus.h"
#include "windef.h"
#include "winbase.h"
#include "winreg.h"
#include "winternl.h"
#include "wine/unicode.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL
(
file
);
#define MAX_PATHNAME_LEN 1024
/***********************************************************************
* GetLongPathNameW (KERNEL32.@)
*
* NOTES
* observed (Win2000):
* shortpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
* shortpath="": LastError=ERROR_PATH_NOT_FOUND, ret=0
*/
DWORD
WINAPI
GetLongPathNameW
(
LPCWSTR
shortpath
,
LPWSTR
longpath
,
DWORD
longlen
)
{
WCHAR
tmplongpath
[
MAX_PATHNAME_LEN
];
LPCWSTR
p
;
DWORD
sp
=
0
,
lp
=
0
;
DWORD
tmplen
;
BOOL
unixabsolute
=
(
shortpath
[
0
]
==
'/'
);
WIN32_FIND_DATAW
wfd
;
HANDLE
goit
;
if
(
!
shortpath
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
if
(
!
shortpath
[
0
])
{
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
0
;
}
TRACE
(
"%s,%p,%ld
\n
"
,
debugstr_w
(
shortpath
),
longpath
,
longlen
);
if
(
shortpath
[
0
]
==
'\\'
&&
shortpath
[
1
]
==
'\\'
)
{
ERR
(
"UNC pathname %s
\n
"
,
debugstr_w
(
shortpath
));
lstrcpynW
(
longpath
,
shortpath
,
longlen
);
return
strlenW
(
longpath
);
}
/* check for drive letter */
if
(
!
unixabsolute
&&
shortpath
[
1
]
==
':'
)
{
tmplongpath
[
0
]
=
shortpath
[
0
];
tmplongpath
[
1
]
=
':'
;
lp
=
sp
=
2
;
}
while
(
shortpath
[
sp
])
{
/* check for path delimiters and reproduce them */
if
(
shortpath
[
sp
]
==
'\\'
||
shortpath
[
sp
]
==
'/'
)
{
if
(
!
lp
||
tmplongpath
[
lp
-
1
]
!=
'\\'
)
{
/* strip double "\\" */
tmplongpath
[
lp
++
]
=
'\\'
;
}
tmplongpath
[
lp
]
=
0
;
/* terminate string */
sp
++
;
continue
;
}
p
=
shortpath
+
sp
;
if
(
sp
==
0
&&
p
[
0
]
==
'.'
&&
(
p
[
1
]
==
'/'
||
p
[
1
]
==
'\\'
))
{
tmplongpath
[
lp
++
]
=
*
p
++
;
tmplongpath
[
lp
++
]
=
*
p
++
;
}
for
(;
*
p
&&
*
p
!=
'/'
&&
*
p
!=
'\\'
;
p
++
);
tmplen
=
p
-
(
shortpath
+
sp
);
lstrcpynW
(
tmplongpath
+
lp
,
shortpath
+
sp
,
tmplen
+
1
);
/* Check if the file exists and use the existing file name */
goit
=
FindFirstFileW
(
tmplongpath
,
&
wfd
);
if
(
goit
==
INVALID_HANDLE_VALUE
)
{
TRACE
(
"not found %s!
\n
"
,
debugstr_w
(
tmplongpath
));
SetLastError
(
ERROR_FILE_NOT_FOUND
);
return
0
;
}
FindClose
(
goit
);
strcpyW
(
tmplongpath
+
lp
,
wfd
.
cFileName
);
lp
+=
strlenW
(
tmplongpath
+
lp
);
sp
+=
tmplen
;
}
tmplen
=
strlenW
(
shortpath
)
-
1
;
if
((
shortpath
[
tmplen
]
==
'/'
||
shortpath
[
tmplen
]
==
'\\'
)
&&
(
tmplongpath
[
lp
-
1
]
!=
'/'
&&
tmplongpath
[
lp
-
1
]
!=
'\\'
))
tmplongpath
[
lp
++
]
=
shortpath
[
tmplen
];
tmplongpath
[
lp
]
=
0
;
tmplen
=
strlenW
(
tmplongpath
)
+
1
;
if
(
tmplen
<=
longlen
)
{
strcpyW
(
longpath
,
tmplongpath
);
TRACE
(
"returning %s
\n
"
,
debugstr_w
(
longpath
));
tmplen
--
;
/* length without 0 */
}
return
tmplen
;
}
/***********************************************************************
* GetLongPathNameA (KERNEL32.@)
*/
DWORD
WINAPI
GetLongPathNameA
(
LPCSTR
shortpath
,
LPSTR
longpath
,
DWORD
longlen
)
{
UNICODE_STRING
shortpathW
;
WCHAR
longpathW
[
MAX_PATH
];
DWORD
ret
,
retW
;
if
(
!
shortpath
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
TRACE
(
"%s
\n
"
,
debugstr_a
(
shortpath
));
if
(
!
RtlCreateUnicodeStringFromAsciiz
(
&
shortpathW
,
shortpath
))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
0
;
}
retW
=
GetLongPathNameW
(
shortpathW
.
Buffer
,
longpathW
,
MAX_PATH
);
if
(
!
retW
)
ret
=
0
;
else
if
(
retW
>
MAX_PATH
)
{
SetLastError
(
ERROR_FILENAME_EXCED_RANGE
);
ret
=
0
;
}
else
{
ret
=
WideCharToMultiByte
(
CP_ACP
,
0
,
longpathW
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
if
(
ret
<=
longlen
)
{
WideCharToMultiByte
(
CP_ACP
,
0
,
longpathW
,
-
1
,
longpath
,
longlen
,
NULL
,
NULL
);
ret
--
;
/* length without 0 */
}
}
RtlFreeUnicodeString
(
&
shortpathW
);
return
ret
;
}
/***********************************************************************
* GetShortPathNameW (KERNEL32.@)
*
* NOTES
* observed:
* longpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
* longpath="" or invalid: LastError=ERROR_BAD_PATHNAME, ret=0
*
* more observations ( with NT 3.51 (WinDD) ):
* longpath <= 8.3 -> just copy longpath to shortpath
* longpath > 8.3 ->
* a) file does not exist -> return 0, LastError = ERROR_FILE_NOT_FOUND
* b) file does exist -> set the short filename.
* - trailing slashes are reproduced in the short name, even if the
* file is not a directory
* - the absolute/relative path of the short name is reproduced like found
* in the long name
* - longpath and shortpath may have the same address
* Peter Ganten, 1999
*/
DWORD
WINAPI
GetShortPathNameW
(
LPCWSTR
longpath
,
LPWSTR
shortpath
,
DWORD
shortlen
)
{
WCHAR
tmpshortpath
[
MAX_PATHNAME_LEN
];
LPCWSTR
p
;
DWORD
sp
=
0
,
lp
=
0
;
DWORD
tmplen
;
BOOL
unixabsolute
=
(
longpath
[
0
]
==
'/'
);
WIN32_FIND_DATAW
wfd
;
HANDLE
goit
;
UNICODE_STRING
ustr
;
WCHAR
ustr_buf
[
8
+
1
+
3
+
1
];
TRACE
(
"%s
\n
"
,
debugstr_w
(
longpath
));
if
(
!
longpath
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
if
(
!
longpath
[
0
])
{
SetLastError
(
ERROR_BAD_PATHNAME
);
return
0
;
}
/* check for drive letter */
if
(
!
unixabsolute
&&
longpath
[
1
]
==
':'
)
{
tmpshortpath
[
0
]
=
longpath
[
0
];
tmpshortpath
[
1
]
=
':'
;
sp
=
lp
=
2
;
}
ustr
.
Buffer
=
ustr_buf
;
ustr
.
Length
=
0
;
ustr
.
MaximumLength
=
sizeof
(
ustr_buf
);
while
(
longpath
[
lp
])
{
/* check for path delimiters and reproduce them */
if
(
longpath
[
lp
]
==
'\\'
||
longpath
[
lp
]
==
'/'
)
{
if
(
!
sp
||
tmpshortpath
[
sp
-
1
]
!=
'\\'
)
{
/* strip double "\\" */
tmpshortpath
[
sp
]
=
'\\'
;
sp
++
;
}
tmpshortpath
[
sp
]
=
0
;
/* terminate string */
lp
++
;
continue
;
}
for
(
p
=
longpath
+
lp
;
*
p
&&
*
p
!=
'/'
&&
*
p
!=
'\\'
;
p
++
);
tmplen
=
p
-
(
longpath
+
lp
);
lstrcpynW
(
tmpshortpath
+
sp
,
longpath
+
lp
,
tmplen
+
1
);
if
(
tmplen
<=
8
+
1
+
3
+
1
)
{
memcpy
(
ustr_buf
,
longpath
+
lp
,
tmplen
*
sizeof
(
WCHAR
));
ustr_buf
[
tmplen
]
=
'\0'
;
ustr
.
Length
=
tmplen
*
sizeof
(
WCHAR
);
/* Check, if the current element is a valid dos name */
if
(
!
RtlIsNameLegalDOS8Dot3
(
&
ustr
,
NULL
,
NULL
))
goto
notfound
;
sp
+=
tmplen
;
lp
+=
tmplen
;
continue
;
}
/* Check if the file exists and use the existing file name */
goit
=
FindFirstFileW
(
tmpshortpath
,
&
wfd
);
if
(
goit
==
INVALID_HANDLE_VALUE
)
goto
notfound
;
FindClose
(
goit
);
strcpyW
(
tmpshortpath
+
sp
,
wfd
.
cAlternateFileName
);
sp
+=
strlenW
(
tmpshortpath
+
sp
);
lp
+=
tmplen
;
}
tmpshortpath
[
sp
]
=
0
;
tmplen
=
strlenW
(
tmpshortpath
)
+
1
;
if
(
tmplen
<=
shortlen
)
{
strcpyW
(
shortpath
,
tmpshortpath
);
TRACE
(
"returning %s
\n
"
,
debugstr_w
(
shortpath
));
tmplen
--
;
/* length without 0 */
}
return
tmplen
;
notfound:
TRACE
(
"not found!
\n
"
);
SetLastError
(
ERROR_FILE_NOT_FOUND
);
return
0
;
}
/***********************************************************************
* GetShortPathNameA (KERNEL32.@)
*/
DWORD
WINAPI
GetShortPathNameA
(
LPCSTR
longpath
,
LPSTR
shortpath
,
DWORD
shortlen
)
{
UNICODE_STRING
longpathW
;
WCHAR
shortpathW
[
MAX_PATH
];
DWORD
ret
,
retW
;
if
(
!
longpath
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
TRACE
(
"%s
\n
"
,
debugstr_a
(
longpath
));
if
(
!
RtlCreateUnicodeStringFromAsciiz
(
&
longpathW
,
longpath
))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
0
;
}
retW
=
GetShortPathNameW
(
longpathW
.
Buffer
,
shortpathW
,
MAX_PATH
);
if
(
!
retW
)
ret
=
0
;
else
if
(
retW
>
MAX_PATH
)
{
SetLastError
(
ERROR_FILENAME_EXCED_RANGE
);
ret
=
0
;
}
else
{
ret
=
WideCharToMultiByte
(
CP_ACP
,
0
,
shortpathW
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
if
(
ret
<=
shortlen
)
{
WideCharToMultiByte
(
CP_ACP
,
0
,
shortpathW
,
-
1
,
shortpath
,
shortlen
,
NULL
,
NULL
);
ret
--
;
/* length without 0 */
}
}
RtlFreeUnicodeString
(
&
longpathW
);
return
ret
;
}
dlls/kernel/tests/path.c
View file @
9ccb73a8
...
...
@@ -141,7 +141,7 @@ static void test_ValidPathA(CHAR *curdir, CHAR *subdir, CHAR *filename,
We test both conversion from GetFullPathNameA and from GetShortPathNameA
*/
if
(
pGetLongPathNameA
)
{
if
(
len
=
=
0
)
{
if
(
len
!
=
0
)
{
SetLastError
(
0
);
len
=
pGetLongPathNameA
(
shortstr
,
tmpstr
,
MAX_PATH
);
if
(
passfail
==
NULL
)
{
...
...
@@ -160,12 +160,9 @@ static void test_ValidPathA(CHAR *curdir, CHAR *subdir, CHAR *filename,
if
(
passfail
==
NULL
)
{
ok
(
len
,
"%s: GetLongPathNameA failed"
,
errstr
);
if
(
HAS_TRAIL_SLASH_A
(
fullpath
))
{
/* Wine strips off the trailing '\\' Neither Win98 nor Win2k do this */
todo_wine
{
ok
(
lstrcmpiA
(
fullpathlong
,
tmpstr
)
==
0
,
ok
(
lstrcmpiA
(
fullpathlong
,
tmpstr
)
==
0
,
"%s: GetLongPathNameA returned '%s' instead of '%s'"
,
errstr
,
tmpstr
,
fullpathlong
);
}
}
else
{
ok
(
lstrcmpiA
(
fullpathlong
,
tmpstr
)
==
0
,
"%s: GetLongPathNameA returned '%s' instead of '%s'"
,
...
...
@@ -229,7 +226,7 @@ static void test_LongtoShortA(CHAR *teststr,CHAR *goodstr,
/* Test that Get(Short|Long|Full)PathNameA work correctly with interesting
characters in the filename.
'valid' indicates whether this would be an allowed filename
'todo' indic
ta
es that wine doesn't get this right yet.
'todo' indic
at
es that wine doesn't get this right yet.
NOTE: We always call this routine with a non-existent filename, so
Get(Short|Long)PathNameA should never pass, but GetFullPathNameA
should.
...
...
@@ -518,13 +515,11 @@ static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
"GetLongPathNameA: wrong return code, %ld instead of %d"
,
rc1
,
strlen
(
tmpstr
)
+
1
);
todo_wine
{
sprintf
(
dir
,
"%c:"
,
curDrive
);
rc1
=
(
*
pGetLongPathNameA
)(
dir
,
tmpstr
,
sizeof
(
tmpstr
));
ok
(
strcmp
(
dir
,
tmpstr
)
==
0
,
"GetLongPathNameA: returned '%s' instead of '%s' (rc=%ld)"
,
tmpstr
,
dir
,
rc1
);
}
sprintf
(
dir
,
"%c:"
,
curDrive
);
rc1
=
(
*
pGetLongPathNameA
)(
dir
,
tmpstr
,
sizeof
(
tmpstr
));
ok
(
strcmp
(
dir
,
tmpstr
)
==
0
,
"GetLongPathNameA: returned '%s' instead of '%s' (rc=%ld)"
,
tmpstr
,
dir
,
rc1
);
}
/* Check the cases where both file and directory exist first */
...
...
@@ -773,11 +768,9 @@ static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
ok
(
GetShortPathNameA
(
LONGDIR
,
tmpstr
,
MAX_PATH
),
"GetShortPathNameA failed"
);
test_SplitShortPathA
(
tmpstr
,
dir
,
eight
,
three
);
if
(
pGetLongPathNameA
)
{
ok
(
pGetLongPathNameA
(
tmpstr
,
tmpstr1
,
MAX_PATH
),
"GetShortPathNameA failed"
);
todo_wine
{
ok
(
lstrcmpiA
(
tmpstr1
,
LONGDIR
)
==
0
,
"GetLongPathNameA returned '%s' instead of '%s'"
,
tmpstr1
,
LONGDIR
);
}
ok
(
pGetLongPathNameA
(
tmpstr
,
tmpstr1
,
MAX_PATH
),
"GetLongPathNameA failed"
);
ok
(
lstrcmpiA
(
tmpstr1
,
LONGDIR
)
==
0
,
"GetLongPathNameA returned '%s' instead of '%s'"
,
tmpstr1
,
LONGDIR
);
}
sprintf
(
tmpstr
,
".
\\
%s"
,
LONGDIR
);
ok
(
GetShortPathNameA
(
tmpstr
,
tmpstr1
,
MAX_PATH
),
"GetShortPathNameA failed"
);
...
...
@@ -785,11 +778,10 @@ static void test_PathNameA(CHAR *curdir, CHAR curDrive, CHAR otherDrive)
ok
(
lstrcmpiA
(
dir
,
"."
)
==
0
||
dir
[
0
]
==
'\0'
,
"GetShortPathNameA did not keep relative directory [%s]"
,
tmpstr1
);
if
(
pGetLongPathNameA
)
{
ok
(
pGetLongPathNameA
(
tmpstr1
,
tmpstr1
,
MAX_PATH
),
"GetShortPathNameA failed"
);
todo_wine
{
ok
(
lstrcmpiA
(
tmpstr1
,
tmpstr
)
==
0
,
"GetLongPathNameA returned '%s' instead of '%s'"
,
tmpstr1
,
tmpstr
);
}
ok
(
pGetLongPathNameA
(
tmpstr1
,
tmpstr1
,
MAX_PATH
),
"GetLongPathNameA failed %s"
,
tmpstr
);
ok
(
lstrcmpiA
(
tmpstr1
,
tmpstr
)
==
0
,
"GetLongPathNameA returned '%s' instead of '%s'"
,
tmpstr1
,
tmpstr
);
}
/* Check out Get*PathNameA on some funny characters */
for
(
i
=
0
;
i
<
lstrlenA
(
funny_chars
);
i
++
)
{
...
...
dlls/ntdll/path.c
View file @
9ccb73a8
...
...
@@ -615,6 +615,7 @@ DWORD WINAPI RtlGetLongestNtPathLength(void)
BOOLEAN
WINAPI
RtlIsNameLegalDOS8Dot3
(
const
UNICODE_STRING
*
unicode
,
OEM_STRING
*
oem
,
BOOLEAN
*
spaces
)
{
static
const
char
*
illegal
=
"*?<>|
\"
+=,;[]:/
\\\345
"
;
int
dot
=
-
1
;
unsigned
int
i
;
char
buffer
[
12
];
...
...
@@ -655,7 +656,7 @@ BOOLEAN WINAPI RtlIsNameLegalDOS8Dot3( const UNICODE_STRING *unicode,
dot
=
i
;
break
;
default:
/* FIXME: check for invalid chars */
if
(
strchr
(
illegal
,
oem
->
Buffer
[
i
]))
return
FALSE
;
break
;
}
}
...
...
files/dos_fs.c
View file @
9ccb73a8
...
...
@@ -1173,278 +1173,6 @@ BOOL DOSFS_GetFullName( LPCWSTR name, BOOL check_last, DOS_FULL_NAME *full )
/***********************************************************************
* GetShortPathNameW (KERNEL32.@)
*
* NOTES
* observed:
* longpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
* longpath="" or invalid: LastError=ERROR_BAD_PATHNAME, ret=0
*
* more observations ( with NT 3.51 (WinDD) ):
* longpath <= 8.3 -> just copy longpath to shortpath
* longpath > 8.3 ->
* a) file does not exist -> return 0, LastError = ERROR_FILE_NOT_FOUND
* b) file does exist -> set the short filename.
* - trailing slashes are reproduced in the short name, even if the
* file is not a directory
* - the absolute/relative path of the short name is reproduced like found
* in the long name
* - longpath and shortpath may have the same address
* Peter Ganten, 1999
*/
DWORD
WINAPI
GetShortPathNameW
(
LPCWSTR
longpath
,
LPWSTR
shortpath
,
DWORD
shortlen
)
{
DOS_FULL_NAME
full_name
;
WCHAR
tmpshortpath
[
MAX_PATHNAME_LEN
];
const
WCHAR
*
p
;
DWORD
sp
=
0
,
lp
=
0
;
int
drive
;
DWORD
tmplen
;
UINT
flags
;
BOOL
unixabsolute
=
*
longpath
==
'/'
;
TRACE
(
"%s
\n
"
,
debugstr_w
(
longpath
));
if
(
!
longpath
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
if
(
!
longpath
[
0
])
{
SetLastError
(
ERROR_BAD_PATHNAME
);
return
0
;
}
/* check for drive letter */
if
(
!
unixabsolute
&&
longpath
[
1
]
==
':'
)
{
tmpshortpath
[
0
]
=
longpath
[
0
];
tmpshortpath
[
1
]
=
':'
;
sp
=
2
;
}
if
(
(
drive
=
DOSFS_GetPathDrive
(
&
longpath
))
==
-
1
)
return
0
;
flags
=
DRIVE_GetFlags
(
drive
);
if
(
unixabsolute
&&
drive
!=
DRIVE_GetCurrentDrive
())
{
tmpshortpath
[
0
]
=
drive
+
'A'
;
tmpshortpath
[
1
]
=
':'
;
sp
=
2
;
}
while
(
longpath
[
lp
]
)
{
/* check for path delimiters and reproduce them */
if
(
longpath
[
lp
]
==
'\\'
||
longpath
[
lp
]
==
'/'
)
{
if
(
!
sp
||
tmpshortpath
[
sp
-
1
]
!=
'\\'
)
{
/* strip double "\\" */
tmpshortpath
[
sp
]
=
'\\'
;
sp
++
;
}
tmpshortpath
[
sp
]
=
0
;
/*terminate string*/
lp
++
;
continue
;
}
tmplen
=
0
;
for
(
p
=
longpath
+
lp
;
*
p
&&
*
p
!=
'/'
&&
*
p
!=
'\\'
;
p
++
)
tmplen
++
;
lstrcpynW
(
tmpshortpath
+
sp
,
longpath
+
lp
,
tmplen
+
1
);
/* Check, if the current element is a valid dos name */
if
(
DOSFS_ValidDOSName
(
longpath
+
lp
,
!
(
flags
&
DRIVE_CASE_SENSITIVE
)
)
)
{
sp
+=
tmplen
;
lp
+=
tmplen
;
continue
;
}
/* Check if the file exists and use the existing file name */
if
(
DOSFS_GetFullName
(
tmpshortpath
,
TRUE
,
&
full_name
)
)
{
strcpyW
(
tmpshortpath
+
sp
,
strrchrW
(
full_name
.
short_name
,
'\\'
)
+
1
);
sp
+=
strlenW
(
tmpshortpath
+
sp
);
lp
+=
tmplen
;
continue
;
}
TRACE
(
"not found!
\n
"
);
SetLastError
(
ERROR_FILE_NOT_FOUND
);
return
0
;
}
tmpshortpath
[
sp
]
=
0
;
tmplen
=
strlenW
(
tmpshortpath
)
+
1
;
if
(
tmplen
<=
shortlen
)
{
strcpyW
(
shortpath
,
tmpshortpath
);
TRACE
(
"returning %s
\n
"
,
debugstr_w
(
shortpath
));
tmplen
--
;
/* length without 0 */
}
return
tmplen
;
}
/***********************************************************************
* GetShortPathNameA (KERNEL32.@)
*/
DWORD
WINAPI
GetShortPathNameA
(
LPCSTR
longpath
,
LPSTR
shortpath
,
DWORD
shortlen
)
{
UNICODE_STRING
longpathW
;
WCHAR
shortpathW
[
MAX_PATH
];
DWORD
ret
,
retW
;
if
(
!
longpath
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
TRACE
(
"%s
\n
"
,
debugstr_a
(
longpath
));
if
(
!
RtlCreateUnicodeStringFromAsciiz
(
&
longpathW
,
longpath
))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
0
;
}
retW
=
GetShortPathNameW
(
longpathW
.
Buffer
,
shortpathW
,
MAX_PATH
);
if
(
!
retW
)
ret
=
0
;
else
if
(
retW
>
MAX_PATH
)
{
SetLastError
(
ERROR_FILENAME_EXCED_RANGE
);
ret
=
0
;
}
else
{
ret
=
WideCharToMultiByte
(
CP_ACP
,
0
,
shortpathW
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
if
(
ret
<=
shortlen
)
{
WideCharToMultiByte
(
CP_ACP
,
0
,
shortpathW
,
-
1
,
shortpath
,
shortlen
,
NULL
,
NULL
);
ret
--
;
/* length without 0 */
}
}
RtlFreeUnicodeString
(
&
longpathW
);
return
ret
;
}
/***********************************************************************
* GetLongPathNameW (KERNEL32.@)
*
* NOTES
* observed (Win2000):
* shortpath=NULL: LastError=ERROR_INVALID_PARAMETER, ret=0
* shortpath="": LastError=ERROR_PATH_NOT_FOUND, ret=0
*/
DWORD
WINAPI
GetLongPathNameW
(
LPCWSTR
shortpath
,
LPWSTR
longpath
,
DWORD
longlen
)
{
DOS_FULL_NAME
full_name
;
const
char
*
root
;
LPWSTR
p
;
int
drive
;
DWORD
ret
,
len
=
0
;
if
(
!
shortpath
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
if
(
!
shortpath
[
0
])
{
SetLastError
(
ERROR_PATH_NOT_FOUND
);
return
0
;
}
TRACE
(
"%s,%p,%ld
\n
"
,
debugstr_w
(
shortpath
),
longpath
,
longlen
);
if
(
shortpath
[
0
]
==
'\\'
&&
shortpath
[
1
]
==
'\\'
)
{
ERR
(
"UNC pathname %s
\n
"
,
debugstr_w
(
shortpath
));
lstrcpynW
(
longpath
,
full_name
.
short_name
,
longlen
);
return
strlenW
(
longpath
);
}
if
(
!
DOSFS_GetFullName
(
shortpath
,
TRUE
,
&
full_name
))
return
0
;
root
=
full_name
.
long_name
;
drive
=
DRIVE_FindDriveRoot
(
&
root
);
ret
=
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
root
,
-
1
,
NULL
,
0
);
ret
+=
3
;
/* A:\ */
/* reproduce terminating slash */
if
(
ret
>
4
)
/* if not drive root */
{
len
=
strlenW
(
shortpath
);
if
(
shortpath
[
len
-
1
]
==
'\\'
||
shortpath
[
len
-
1
]
==
'/'
)
len
=
1
;
}
ret
+=
len
;
if
(
ret
<=
longlen
)
{
longpath
[
0
]
=
'A'
+
drive
;
longpath
[
1
]
=
':'
;
MultiByteToWideChar
(
CP_UNIXCP
,
0
,
root
,
-
1
,
longpath
+
2
,
longlen
-
2
);
for
(
p
=
longpath
;
*
p
;
p
++
)
if
(
*
p
==
'/'
)
*
p
=
'\\'
;
if
(
len
)
{
longpath
[
ret
-
2
]
=
'\\'
;
longpath
[
ret
-
1
]
=
0
;
}
TRACE
(
"returning %s
\n
"
,
debugstr_w
(
longpath
));
ret
--
;
/* length without 0 */
}
return
ret
;
}
/***********************************************************************
* GetLongPathNameA (KERNEL32.@)
*/
DWORD
WINAPI
GetLongPathNameA
(
LPCSTR
shortpath
,
LPSTR
longpath
,
DWORD
longlen
)
{
UNICODE_STRING
shortpathW
;
WCHAR
longpathW
[
MAX_PATH
];
DWORD
ret
,
retW
;
if
(
!
shortpath
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
0
;
}
TRACE
(
"%s
\n
"
,
debugstr_a
(
shortpath
));
if
(
!
RtlCreateUnicodeStringFromAsciiz
(
&
shortpathW
,
shortpath
))
{
SetLastError
(
ERROR_NOT_ENOUGH_MEMORY
);
return
0
;
}
retW
=
GetLongPathNameW
(
shortpathW
.
Buffer
,
longpathW
,
MAX_PATH
);
if
(
!
retW
)
ret
=
0
;
else
if
(
retW
>
MAX_PATH
)
{
SetLastError
(
ERROR_FILENAME_EXCED_RANGE
);
ret
=
0
;
}
else
{
ret
=
WideCharToMultiByte
(
CP_ACP
,
0
,
longpathW
,
-
1
,
NULL
,
0
,
NULL
,
NULL
);
if
(
ret
<=
longlen
)
{
WideCharToMultiByte
(
CP_ACP
,
0
,
longpathW
,
-
1
,
longpath
,
longlen
,
NULL
,
NULL
);
ret
--
;
/* length without 0 */
}
}
RtlFreeUnicodeString
(
&
shortpathW
);
return
ret
;
}
/***********************************************************************
* DOSFS_DoGetFullPathName
*
* Implementation of GetFullPathNameA/W.
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment