Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
44ac5af0
Commit
44ac5af0
authored
May 14, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
May 14, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernelbase: Duplicate some path handling functions from shlwapi.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
7c02ab5e
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
780 additions
and
27 deletions
+780
-27
kernelbase.spec
dlls/kernelbase/kernelbase.spec
+27
-27
path.c
dlls/kernelbase/path.c
+753
-0
No files found.
dlls/kernelbase/kernelbase.spec
View file @
44ac5af0
...
...
@@ -1020,16 +1020,16 @@
# @ stub ParseApplicationUserModelId
@ stdcall ParseURLA(str ptr) shlwapi.ParseURLA
@ stdcall ParseURLW(wstr ptr) shlwapi.ParseURLW
@ stdcall PathAddBackslashA(str)
shlwapi.PathAddBackslashA
@ stdcall PathAddBackslashW(wstr)
shlwapi.PathAddBackslashW
@ stdcall PathAddExtensionA(str str)
shlwapi.PathAddExtensionA
@ stdcall PathAddExtensionW(wstr wstr)
shlwapi.PathAddExtensionW
@ stdcall PathAddBackslashA(str)
@ stdcall PathAddBackslashW(wstr)
@ stdcall PathAddExtensionA(str str)
@ stdcall PathAddExtensionW(wstr wstr)
@ stdcall PathAllocCanonicalize(wstr long ptr)
@ stdcall PathAllocCombine(wstr wstr long ptr)
@ stdcall PathAppendA(str str)
shlwapi.PathAppendA
@ stdcall PathAppendW(wstr wstr)
shlwapi.PathAppendW
@ stdcall PathCanonicalizeA(ptr str)
shlwapi.PathCanonicalizeA
@ stdcall PathCanonicalizeW(ptr wstr)
shlwapi.PathCanonicalizeW
@ stdcall PathAppendA(str str)
@ stdcall PathAppendW(wstr wstr)
@ stdcall PathCanonicalizeA(ptr str)
@ stdcall PathCanonicalizeW(ptr wstr)
@ stdcall PathCchAddBackslash(wstr long)
@ stdcall PathCchAddBackslashEx(wstr long ptr ptr)
@ stdcall PathCchAddExtension(wstr long wstr)
...
...
@@ -1049,17 +1049,17 @@
@ stdcall PathCchSkipRoot(wstr ptr)
@ stdcall PathCchStripPrefix(wstr long)
@ stdcall PathCchStripToRoot(wstr long)
@ stdcall PathCombineA(ptr str str)
shlwapi.PathCombineA
@ stdcall PathCombineW(ptr wstr wstr)
shlwapi.PathCombineW
@ stdcall PathCommonPrefixA(str str ptr)
shlwapi.PathCommonPrefixA
@ stdcall PathCommonPrefixW(wstr wstr ptr)
shlwapi.PathCommonPrefixW
@ stdcall PathCombineA(ptr str str)
@ stdcall PathCombineW(ptr wstr wstr)
@ stdcall PathCommonPrefixA(str str ptr)
@ stdcall PathCommonPrefixW(wstr wstr ptr)
@ stdcall PathCreateFromUrlA(str ptr ptr long) shlwapi.PathCreateFromUrlA
@ stdcall PathCreateFromUrlAlloc(wstr ptr long) shlwapi.PathCreateFromUrlAlloc
@ stdcall PathCreateFromUrlW(wstr ptr ptr long) shlwapi.PathCreateFromUrlW
@ stdcall PathFileExistsA(str) shlwapi.PathFileExistsA
@ stdcall PathFileExistsW(wstr) shlwapi.PathFileExistsW
@ stdcall PathFindExtensionA(str)
shlwapi.PathFindExtensionA
@ stdcall PathFindExtensionW(wstr)
shlwapi.PathFindExtensionW
@ stdcall PathFindExtensionA(str)
@ stdcall PathFindExtensionW(wstr)
@ stdcall PathFindFileNameA(str) shlwapi.PathFindFileNameA
@ stdcall PathFindFileNameW(wstr) shlwapi.PathFindFileNameW
@ stdcall PathFindNextComponentA(str) shlwapi.PathFindNextComponentA
...
...
@@ -1074,21 +1074,21 @@
@ stdcall PathIsFileSpecW(wstr) shlwapi.PathIsFileSpecW
@ stdcall PathIsLFNFileSpecA(str) shlwapi.PathIsLFNFileSpecA
@ stdcall PathIsLFNFileSpecW(wstr) shlwapi.PathIsLFNFileSpecW
@ stdcall PathIsPrefixA(str str)
shlwapi.PathIsPrefixA
@ stdcall PathIsPrefixW(wstr wstr)
shlwapi.PathIsPrefixW
@ stdcall PathIsRelativeA(str)
shlwapi.PathIsRelativeA
@ stdcall PathIsRelativeW(wstr)
shlwapi.PathIsRelativeW
@ stdcall PathIsRootA(str)
shlwapi.PathIsRootA
@ stdcall PathIsRootW(wstr)
shlwapi.PathIsRootW
@ stdcall PathIsPrefixA(str str)
@ stdcall PathIsPrefixW(wstr wstr)
@ stdcall PathIsRelativeA(str)
@ stdcall PathIsRelativeW(wstr)
@ stdcall PathIsRootA(str)
@ stdcall PathIsRootW(wstr)
@ stdcall PathIsSameRootA(str str) shlwapi.PathIsSameRootA
@ stdcall PathIsSameRootW(wstr wstr) shlwapi.PathIsSameRootW
@ stdcall PathIsUNCA(str)
shlwapi.PathIsUNCA
@ stdcall PathIsUNCA(str)
@ stdcall PathIsUNCEx(wstr ptr)
@ stdcall PathIsUNCServerA(str) shlwapi.PathIsUNCServerA
@ stdcall PathIsUNCServerShareA(str)
shlwapi.PathIsUNCServerShareA
@ stdcall PathIsUNCServerShareW(wstr)
shlwapi.PathIsUNCServerShareW
@ stdcall PathIsUNCServerShareA(str)
@ stdcall PathIsUNCServerShareW(wstr)
@ stdcall PathIsUNCServerW(wstr) shlwapi.PathIsUNCServerW
@ stdcall PathIsUNCW(wstr)
shlwapi.PathIsUNCW
@ stdcall PathIsUNCW(wstr)
@ stdcall PathIsURLA(str) shlwapi.PathIsURLA
@ stdcall PathIsURLW(wstr) shlwapi.PathIsURLW
@ stdcall PathIsValidCharA(long long) shlwapi.PathIsValidCharA
...
...
@@ -1109,8 +1109,8 @@
@ stdcall PathRemoveBlanksW(wstr) shlwapi.PathRemoveBlanksW
@ stdcall PathRemoveExtensionA(str) shlwapi.PathRemoveExtensionA
@ stdcall PathRemoveExtensionW(wstr) shlwapi.PathRemoveExtensionW
@ stdcall PathRemoveFileSpecA(str)
shlwapi.PathRemoveFileSpecA
@ stdcall PathRemoveFileSpecW(wstr)
shlwapi.PathRemoveFileSpecW
@ stdcall PathRemoveFileSpecA(str)
@ stdcall PathRemoveFileSpecW(wstr)
@ stdcall PathRenameExtensionA(str str) shlwapi.PathRenameExtensionA
@ stdcall PathRenameExtensionW(wstr wstr) shlwapi.PathRenameExtensionW
@ stdcall PathSearchAndQualifyA(str ptr long) shlwapi.PathSearchAndQualifyA
...
...
@@ -1120,7 +1120,7 @@
@ stdcall PathStripPathA(str) shlwapi.PathStripPathA
@ stdcall PathStripPathW(wstr) shlwapi.PathStripPathW
@ stdcall PathStripToRootA(str) shlwapi.PathStripToRootA
@ stdcall PathStripToRootW(wstr)
shlwapi.PathStripToRootW
@ stdcall PathStripToRootW(wstr)
@ stdcall PathUnExpandEnvStringsA(str ptr long) shlwapi.PathUnExpandEnvStringsA
@ stdcall PathUnExpandEnvStringsW(wstr ptr long) shlwapi.PathUnExpandEnvStringsW
@ stdcall PathUnquoteSpacesA(str) shlwapi.PathUnquoteSpacesA
...
...
dlls/kernelbase/path.c
View file @
44ac5af0
...
...
@@ -29,6 +29,13 @@
WINE_DEFAULT_DEBUG_CHANNEL
(
path
);
char
*
char_next
(
const
char
*
ptr
)
{
if
(
!*
ptr
)
return
(
LPSTR
)
ptr
;
if
(
IsDBCSLeadByte
(
ptr
[
0
]
)
&&
ptr
[
1
])
return
(
LPSTR
)(
ptr
+
2
);
return
(
LPSTR
)(
ptr
+
1
);
}
static
SIZE_T
strnlenW
(
const
WCHAR
*
string
,
SIZE_T
maxlen
)
{
SIZE_T
i
;
...
...
@@ -865,3 +872,749 @@ BOOL WINAPI PathIsUNCEx(const WCHAR *path, const WCHAR **server)
if
(
server
)
*
server
=
result
;
return
!!
result
;
}
BOOL
WINAPI
PathIsUNCA
(
const
char
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
return
path
&&
(
path
[
0
]
==
'\\'
)
&&
(
path
[
1
]
==
'\\'
);
}
BOOL
WINAPI
PathIsUNCW
(
const
WCHAR
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
return
path
&&
(
path
[
0
]
==
'\\'
)
&&
(
path
[
1
]
==
'\\'
);
}
BOOL
WINAPI
PathIsRelativeA
(
const
char
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
!
path
||
!*
path
||
IsDBCSLeadByte
(
*
path
))
return
TRUE
;
return
!
(
*
path
==
'\\'
||
(
*
path
&&
path
[
1
]
==
':'
));
}
BOOL
WINAPI
PathIsRelativeW
(
const
WCHAR
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
!
path
||
!*
path
)
return
TRUE
;
return
!
(
*
path
==
'\\'
||
(
*
path
&&
path
[
1
]
==
':'
));
}
BOOL
WINAPI
PathIsUNCServerShareA
(
const
char
*
path
)
{
BOOL
seen_slash
=
FALSE
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
path
&&
*
path
++
==
'\\'
&&
*
path
++
==
'\\'
)
{
while
(
*
path
)
{
if
(
*
path
==
'\\'
)
{
if
(
seen_slash
)
return
FALSE
;
seen_slash
=
TRUE
;
}
path
=
char_next
(
path
);
}
}
return
seen_slash
;
}
BOOL
WINAPI
PathIsUNCServerShareW
(
const
WCHAR
*
path
)
{
BOOL
seen_slash
=
FALSE
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
path
&&
*
path
++
==
'\\'
&&
*
path
++
==
'\\'
)
{
while
(
*
path
)
{
if
(
*
path
==
'\\'
)
{
if
(
seen_slash
)
return
FALSE
;
seen_slash
=
TRUE
;
}
path
++
;
}
}
return
seen_slash
;
}
BOOL
WINAPI
PathIsRootA
(
const
char
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
!
path
||
!*
path
)
return
FALSE
;
if
(
*
path
==
'\\'
)
{
if
(
!
path
[
1
])
return
TRUE
;
/* \ */
else
if
(
path
[
1
]
==
'\\'
)
{
BOOL
seen_slash
=
FALSE
;
path
+=
2
;
/* Check for UNC root path */
while
(
*
path
)
{
if
(
*
path
==
'\\'
)
{
if
(
seen_slash
)
return
FALSE
;
seen_slash
=
TRUE
;
}
path
=
char_next
(
path
);
}
return
TRUE
;
}
}
else
if
(
path
[
1
]
==
':'
&&
path
[
2
]
==
'\\'
&&
path
[
3
]
==
'\0'
)
return
TRUE
;
/* X:\ */
return
FALSE
;
}
BOOL
WINAPI
PathIsRootW
(
const
WCHAR
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
!
path
||
!*
path
)
return
FALSE
;
if
(
*
path
==
'\\'
)
{
if
(
!
path
[
1
])
return
TRUE
;
/* \ */
else
if
(
path
[
1
]
==
'\\'
)
{
BOOL
seen_slash
=
FALSE
;
path
+=
2
;
/* Check for UNC root path */
while
(
*
path
)
{
if
(
*
path
==
'\\'
)
{
if
(
seen_slash
)
return
FALSE
;
seen_slash
=
TRUE
;
}
path
++
;
}
return
TRUE
;
}
}
else
if
(
path
[
1
]
==
':'
&&
path
[
2
]
==
'\\'
&&
path
[
3
]
==
'\0'
)
return
TRUE
;
/* X:\ */
return
FALSE
;
}
BOOL
WINAPI
PathRemoveFileSpecA
(
char
*
path
)
{
char
*
filespec
=
path
;
BOOL
modified
=
FALSE
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
!
path
)
return
FALSE
;
/* Skip directory or UNC path */
if
(
*
path
==
'\\'
)
filespec
=
++
path
;
if
(
*
path
==
'\\'
)
filespec
=
++
path
;
while
(
*
path
)
{
if
(
*
path
==
'\\'
)
filespec
=
path
;
/* Skip dir */
else
if
(
*
path
==
':'
)
{
filespec
=
++
path
;
/* Skip drive */
if
(
*
path
==
'\\'
)
filespec
++
;
}
if
(
!
(
path
=
char_next
(
path
)))
break
;
}
if
(
*
filespec
)
{
*
filespec
=
'\0'
;
modified
=
TRUE
;
}
return
modified
;
}
BOOL
WINAPI
PathRemoveFileSpecW
(
WCHAR
*
path
)
{
WCHAR
*
filespec
=
path
;
BOOL
modified
=
FALSE
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
!
path
)
return
FALSE
;
/* Skip directory or UNC path */
if
(
*
path
==
'\\'
)
filespec
=
++
path
;
if
(
*
path
==
'\\'
)
filespec
=
++
path
;
while
(
*
path
)
{
if
(
*
path
==
'\\'
)
filespec
=
path
;
/* Skip dir */
else
if
(
*
path
==
':'
)
{
filespec
=
++
path
;
/* Skip drive */
if
(
*
path
==
'\\'
)
filespec
++
;
}
path
++
;
}
if
(
*
filespec
)
{
*
filespec
=
'\0'
;
modified
=
TRUE
;
}
return
modified
;
}
BOOL
WINAPI
PathStripToRootA
(
char
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
!
path
)
return
FALSE
;
while
(
!
PathIsRootA
(
path
))
if
(
!
PathRemoveFileSpecA
(
path
))
return
FALSE
;
return
TRUE
;
}
BOOL
WINAPI
PathStripToRootW
(
WCHAR
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
!
path
)
return
FALSE
;
while
(
!
PathIsRootW
(
path
))
if
(
!
PathRemoveFileSpecW
(
path
))
return
FALSE
;
return
TRUE
;
}
LPSTR
WINAPI
PathAddBackslashA
(
char
*
path
)
{
unsigned
int
len
;
char
*
prev
=
path
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
!
path
||
(
len
=
strlen
(
path
))
>=
MAX_PATH
)
return
NULL
;
if
(
len
)
{
do
{
path
=
char_next
(
prev
);
if
(
*
path
)
prev
=
path
;
}
while
(
*
path
);
if
(
*
prev
!=
'\\'
)
{
*
path
++
=
'\\'
;
*
path
=
'\0'
;
}
}
return
path
;
}
LPWSTR
WINAPI
PathAddBackslashW
(
WCHAR
*
path
)
{
unsigned
int
len
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
!
path
||
(
len
=
strlenW
(
path
))
>=
MAX_PATH
)
return
NULL
;
if
(
len
)
{
path
+=
len
;
if
(
path
[
-
1
]
!=
'\\'
)
{
*
path
++
=
'\\'
;
*
path
=
'\0'
;
}
}
return
path
;
}
LPSTR
WINAPI
PathFindExtensionA
(
const
char
*
path
)
{
const
char
*
lastpoint
=
NULL
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
path
)
{
while
(
*
path
)
{
if
(
*
path
==
'\\'
||
*
path
==
' '
)
lastpoint
=
NULL
;
else
if
(
*
path
==
'.'
)
lastpoint
=
path
;
path
=
char_next
(
path
);
}
}
return
(
LPSTR
)(
lastpoint
?
lastpoint
:
path
);
}
LPWSTR
WINAPI
PathFindExtensionW
(
const
WCHAR
*
path
)
{
const
WCHAR
*
lastpoint
=
NULL
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
path
)
{
while
(
*
path
)
{
if
(
*
path
==
'\\'
||
*
path
==
' '
)
lastpoint
=
NULL
;
else
if
(
*
path
==
'.'
)
lastpoint
=
path
;
path
++
;
}
}
return
(
LPWSTR
)(
lastpoint
?
lastpoint
:
path
);
}
BOOL
WINAPI
PathAddExtensionA
(
char
*
path
,
const
char
*
ext
)
{
unsigned
int
len
;
TRACE
(
"%s, %s
\n
"
,
wine_dbgstr_a
(
path
),
wine_dbgstr_a
(
ext
));
if
(
!
path
||
!
ext
||
*
(
PathFindExtensionA
(
path
)))
return
FALSE
;
len
=
strlen
(
path
);
if
(
len
+
strlen
(
ext
)
>=
MAX_PATH
)
return
FALSE
;
strcpy
(
path
+
len
,
ext
);
return
TRUE
;
}
BOOL
WINAPI
PathAddExtensionW
(
WCHAR
*
path
,
const
WCHAR
*
ext
)
{
unsigned
int
len
;
TRACE
(
"%s, %s
\n
"
,
wine_dbgstr_w
(
path
),
wine_dbgstr_w
(
ext
));
if
(
!
path
||
!
ext
||
*
(
PathFindExtensionW
(
path
)))
return
FALSE
;
len
=
strlenW
(
path
);
if
(
len
+
strlenW
(
ext
)
>=
MAX_PATH
)
return
FALSE
;
strcpyW
(
path
+
len
,
ext
);
return
TRUE
;
}
BOOL
WINAPI
PathCanonicalizeW
(
WCHAR
*
buffer
,
const
WCHAR
*
path
)
{
const
WCHAR
*
src
=
path
;
WCHAR
*
dst
=
buffer
;
TRACE
(
"%p, %s
\n
"
,
buffer
,
wine_dbgstr_w
(
path
));
if
(
dst
)
*
dst
=
'\0'
;
if
(
!
dst
||
!
path
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
if
(
!*
path
)
{
*
buffer
++
=
'\\'
;
*
buffer
=
'\0'
;
return
TRUE
;
}
/* Copy path root */
if
(
*
src
==
'\\'
)
{
*
dst
++
=
*
src
++
;
}
else
if
(
*
src
&&
src
[
1
]
==
':'
)
{
/* X:\ */
*
dst
++
=
*
src
++
;
*
dst
++
=
*
src
++
;
if
(
*
src
==
'\\'
)
*
dst
++
=
*
src
++
;
}
/* Canonicalize the rest of the path */
while
(
*
src
)
{
if
(
*
src
==
'.'
)
{
if
(
src
[
1
]
==
'\\'
&&
(
src
==
path
||
src
[
-
1
]
==
'\\'
||
src
[
-
1
]
==
':'
))
{
src
+=
2
;
/* Skip .\ */
}
else
if
(
src
[
1
]
==
'.'
&&
(
dst
==
buffer
||
dst
[
-
1
]
==
'\\'
))
{
/* \.. backs up a directory, over the root if it has no \ following X:.
* .. is ignored if it would remove a UNC server name or initial \\
*/
if
(
dst
!=
buffer
)
{
*
dst
=
'\0'
;
/* Allow PathIsUNCServerShareA test on lpszBuf */
if
(
dst
>
buffer
+
1
&&
dst
[
-
1
]
==
'\\'
&&
(
dst
[
-
2
]
!=
'\\'
||
dst
>
buffer
+
2
))
{
if
(
dst
[
-
2
]
==
':'
&&
(
dst
>
buffer
+
3
||
dst
[
-
3
]
==
':'
))
{
dst
-=
2
;
while
(
dst
>
buffer
&&
*
dst
!=
'\\'
)
dst
--
;
if
(
*
dst
==
'\\'
)
dst
++
;
/* Reset to last '\' */
else
dst
=
buffer
;
/* Start path again from new root */
}
else
if
(
dst
[
-
2
]
!=
':'
&&
!
PathIsUNCServerShareW
(
buffer
))
dst
-=
2
;
}
while
(
dst
>
buffer
&&
*
dst
!=
'\\'
)
dst
--
;
if
(
dst
==
buffer
)
{
*
dst
++
=
'\\'
;
src
++
;
}
}
src
+=
2
;
/* Skip .. in src path */
}
else
*
dst
++
=
*
src
++
;
}
else
*
dst
++
=
*
src
++
;
}
/* Append \ to naked drive specs */
if
(
dst
-
buffer
==
2
&&
dst
[
-
1
]
==
':'
)
*
dst
++
=
'\\'
;
*
dst
++
=
'\0'
;
return
TRUE
;
}
BOOL
WINAPI
PathCanonicalizeA
(
char
*
buffer
,
const
char
*
path
)
{
WCHAR
pathW
[
MAX_PATH
],
bufferW
[
MAX_PATH
];
BOOL
ret
;
int
len
;
TRACE
(
"%p, %s
\n
"
,
buffer
,
wine_dbgstr_a
(
path
));
if
(
buffer
)
*
buffer
=
'\0'
;
if
(
!
buffer
||
!
path
)
{
SetLastError
(
ERROR_INVALID_PARAMETER
);
return
FALSE
;
}
len
=
MultiByteToWideChar
(
CP_ACP
,
0
,
path
,
-
1
,
pathW
,
ARRAY_SIZE
(
pathW
));
if
(
!
len
)
return
FALSE
;
ret
=
PathCanonicalizeW
(
bufferW
,
pathW
);
WideCharToMultiByte
(
CP_ACP
,
0
,
bufferW
,
-
1
,
buffer
,
MAX_PATH
,
0
,
0
);
return
ret
;
}
WCHAR
*
WINAPI
PathCombineW
(
WCHAR
*
dst
,
const
WCHAR
*
dir
,
const
WCHAR
*
file
)
{
BOOL
use_both
=
FALSE
,
strip
=
FALSE
;
WCHAR
tmp
[
MAX_PATH
];
TRACE
(
"%p, %s, %s
\n
"
,
dst
,
wine_dbgstr_w
(
dir
),
wine_dbgstr_w
(
file
));
/* Invalid parameters */
if
(
!
dst
)
return
NULL
;
if
(
!
dir
&&
!
file
)
{
dst
[
0
]
=
0
;
return
NULL
;
}
if
((
!
file
||
!*
file
)
&&
dir
)
{
/* Use dir only */
lstrcpynW
(
tmp
,
dir
,
ARRAY_SIZE
(
tmp
));
}
else
if
(
!
dir
||
!*
dir
||
!
PathIsRelativeW
(
file
))
{
if
(
!
dir
||
!*
dir
||
*
file
!=
'\\'
||
PathIsUNCW
(
file
))
{
/* Use file only */
lstrcpynW
(
tmp
,
file
,
ARRAY_SIZE
(
tmp
));
}
else
{
use_both
=
TRUE
;
strip
=
TRUE
;
}
}
else
use_both
=
TRUE
;
if
(
use_both
)
{
lstrcpynW
(
tmp
,
dir
,
ARRAY_SIZE
(
tmp
));
if
(
strip
)
{
PathStripToRootW
(
tmp
);
file
++
;
/* Skip '\' */
}
if
(
!
PathAddBackslashW
(
tmp
)
||
strlenW
(
tmp
)
+
strlenW
(
file
)
>=
MAX_PATH
)
{
dst
[
0
]
=
0
;
return
NULL
;
}
strcatW
(
tmp
,
file
);
}
PathCanonicalizeW
(
dst
,
tmp
);
return
dst
;
}
LPSTR
WINAPI
PathCombineA
(
char
*
dst
,
const
char
*
dir
,
const
char
*
file
)
{
WCHAR
dstW
[
MAX_PATH
],
dirW
[
MAX_PATH
],
fileW
[
MAX_PATH
];
TRACE
(
"%p, %s, %s
\n
"
,
dst
,
wine_dbgstr_a
(
dir
),
wine_dbgstr_a
(
file
));
/* Invalid parameters */
if
(
!
dst
)
return
NULL
;
dst
[
0
]
=
0
;
if
(
!
dir
&&
!
file
)
return
NULL
;
if
(
dir
&&
!
MultiByteToWideChar
(
CP_ACP
,
0
,
dir
,
-
1
,
dirW
,
ARRAY_SIZE
(
dirW
)))
return
NULL
;
if
(
file
&&
!
MultiByteToWideChar
(
CP_ACP
,
0
,
file
,
-
1
,
fileW
,
ARRAY_SIZE
(
fileW
)))
return
NULL
;
if
(
PathCombineW
(
dstW
,
dir
?
dirW
:
NULL
,
file
?
fileW
:
NULL
))
if
(
WideCharToMultiByte
(
CP_ACP
,
0
,
dstW
,
-
1
,
dst
,
MAX_PATH
,
0
,
0
))
return
dst
;
return
NULL
;
}
BOOL
WINAPI
PathAppendA
(
char
*
path
,
const
char
*
append
)
{
TRACE
(
"%s, %s
\n
"
,
wine_dbgstr_a
(
path
),
wine_dbgstr_a
(
append
));
if
(
path
&&
append
)
{
if
(
!
PathIsUNCA
(
append
))
while
(
*
append
==
'\\'
)
append
++
;
if
(
PathCombineA
(
path
,
path
,
append
))
return
TRUE
;
}
return
FALSE
;
}
BOOL
WINAPI
PathAppendW
(
WCHAR
*
path
,
const
WCHAR
*
append
)
{
TRACE
(
"%s, %s
\n
"
,
wine_dbgstr_w
(
path
),
wine_dbgstr_w
(
append
));
if
(
path
&&
append
)
{
if
(
!
PathIsUNCW
(
append
))
while
(
*
append
==
'\\'
)
append
++
;
if
(
PathCombineW
(
path
,
path
,
append
))
return
TRUE
;
}
return
FALSE
;
}
int
WINAPI
PathCommonPrefixA
(
const
char
*
file1
,
const
char
*
file2
,
char
*
path
)
{
const
char
*
iter1
=
file1
;
const
char
*
iter2
=
file2
;
unsigned
int
len
=
0
;
TRACE
(
"%s, %s, %p.
\n
"
,
wine_dbgstr_a
(
file1
),
wine_dbgstr_a
(
file2
),
path
);
if
(
path
)
*
path
=
'\0'
;
if
(
!
file1
||
!
file2
)
return
0
;
/* Handle roots first */
if
(
PathIsUNCA
(
file1
))
{
if
(
!
PathIsUNCA
(
file2
))
return
0
;
iter1
+=
2
;
iter2
+=
2
;
}
else
if
(
PathIsUNCA
(
file2
))
return
0
;
for
(;;)
{
/* Update len */
if
((
!*
iter1
||
*
iter1
==
'\\'
)
&&
(
!*
iter2
||
*
iter2
==
'\\'
))
len
=
iter1
-
file1
;
/* Common to this point */
if
(
!*
iter1
||
(
tolower
(
*
iter1
)
!=
tolower
(
*
iter2
)))
break
;
/* Strings differ at this point */
iter1
++
;
iter2
++
;
}
if
(
len
==
2
)
len
++
;
/* Feature/Bug compatible with Win32 */
if
(
len
&&
path
)
{
memcpy
(
path
,
file1
,
len
);
path
[
len
]
=
'\0'
;
}
return
len
;
}
int
WINAPI
PathCommonPrefixW
(
const
WCHAR
*
file1
,
const
WCHAR
*
file2
,
WCHAR
*
path
)
{
const
WCHAR
*
iter1
=
file1
;
const
WCHAR
*
iter2
=
file2
;
unsigned
int
len
=
0
;
TRACE
(
"%s, %s, %p
\n
"
,
wine_dbgstr_w
(
file1
),
wine_dbgstr_w
(
file2
),
path
);
if
(
path
)
*
path
=
'\0'
;
if
(
!
file1
||
!
file2
)
return
0
;
/* Handle roots first */
if
(
PathIsUNCW
(
file1
))
{
if
(
!
PathIsUNCW
(
file2
))
return
0
;
iter1
+=
2
;
iter2
+=
2
;
}
else
if
(
PathIsUNCW
(
file2
))
return
0
;
for
(;;)
{
/* Update len */
if
((
!*
iter1
||
*
iter1
==
'\\'
)
&&
(
!*
iter2
||
*
iter2
==
'\\'
))
len
=
iter1
-
file1
;
/* Common to this point */
if
(
!*
iter1
||
(
tolowerW
(
*
iter1
)
!=
tolowerW
(
*
iter2
)))
break
;
/* Strings differ at this point */
iter1
++
;
iter2
++
;
}
if
(
len
==
2
)
len
++
;
/* Feature/Bug compatible with Win32 */
if
(
len
&&
path
)
{
memcpy
(
path
,
file1
,
len
*
sizeof
(
WCHAR
));
path
[
len
]
=
'\0'
;
}
return
len
;
}
BOOL
WINAPI
PathIsPrefixA
(
const
char
*
prefix
,
const
char
*
path
)
{
TRACE
(
"%s, %s
\n
"
,
wine_dbgstr_a
(
prefix
),
wine_dbgstr_a
(
path
));
return
prefix
&&
path
&&
PathCommonPrefixA
(
path
,
prefix
,
NULL
)
==
(
int
)
strlen
(
prefix
);
}
BOOL
WINAPI
PathIsPrefixW
(
const
WCHAR
*
prefix
,
const
WCHAR
*
path
)
{
TRACE
(
"%s, %s
\n
"
,
wine_dbgstr_w
(
prefix
),
wine_dbgstr_w
(
path
));
return
prefix
&&
path
&&
PathCommonPrefixW
(
path
,
prefix
,
NULL
)
==
(
int
)
strlenW
(
prefix
);
}
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