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
1cef84a1
Commit
1cef84a1
authored
May 21, 2019
by
Nikolay Sivov
Committed by
Alexandre Julliard
May 21, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernelbase: Add most of path API from shlwapi.
Signed-off-by:
Nikolay Sivov
<
nsivov@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
d4c96034
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
441 additions
and
19 deletions
+441
-19
kernelbase.spec
dlls/kernelbase/kernelbase.spec
+19
-19
path.c
dlls/kernelbase/path.c
+422
-0
No files found.
dlls/kernelbase/kernelbase.spec
View file @
1cef84a1
...
...
@@ -1056,14 +1056,14 @@
@ 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 PathFileExistsA(str)
@ stdcall PathFileExistsW(wstr)
@ stdcall PathFindExtensionA(str)
@ stdcall PathFindExtensionW(wstr)
@ stdcall PathFindFileNameA(str)
@ stdcall PathFindFileNameW(wstr)
@ stdcall PathFindNextComponentA(str)
shlwapi.PathFindNextComponentA
@ stdcall PathFindNextComponentW(wstr)
shlwapi.PathFindNextComponentW
@ stdcall PathFindNextComponentA(str)
@ stdcall PathFindNextComponentW(wstr)
@ stdcall PathGetArgsA(str)
@ stdcall PathGetArgsW(wstr)
@ stdcall PathGetCharTypeA(long)
...
...
@@ -1080,8 +1080,8 @@
@ stdcall PathIsRelativeW(wstr)
@ stdcall PathIsRootA(str)
@ stdcall PathIsRootW(wstr)
@ stdcall PathIsSameRootA(str str)
shlwapi.PathIsSameRootA
@ stdcall PathIsSameRootW(wstr wstr)
shlwapi.PathIsSameRootW
@ stdcall PathIsSameRootA(str str)
@ stdcall PathIsSameRootW(wstr wstr)
@ stdcall PathIsUNCA(str)
@ stdcall PathIsUNCEx(wstr ptr)
@ stdcall PathIsUNCServerA(str)
...
...
@@ -1093,16 +1093,16 @@
@ stdcall PathIsURLW(wstr) shlwapi.PathIsURLW
@ stdcall PathIsValidCharA(long long)
@ stdcall PathIsValidCharW(long long)
@ stdcall PathMatchSpecA(str str)
shlwapi.PathMatchSpecA
@ stdcall PathMatchSpecA(str str)
# @ stub PathMatchSpecExA
# @ stub PathMatchSpecExW
@ stdcall PathMatchSpecW(wstr wstr)
shlwapi.PathMatchSpecW
@ stdcall PathMatchSpecW(wstr wstr)
@ stdcall PathParseIconLocationA(str) shlwapi.PathParseIconLocationA
@ stdcall PathParseIconLocationW(wstr) shlwapi.PathParseIconLocationW
@ stdcall PathQuoteSpacesA(str)
shlwapi.PathQuoteSpacesA
@ stdcall PathQuoteSpacesW(wstr)
shlwapi.PathQuoteSpacesW
@ stdcall PathRelativePathToA(ptr str long str long)
shlwapi.PathRelativePathToA
@ stdcall PathRelativePathToW(ptr wstr long wstr long)
shlwapi.PathRelativePathToW
@ stdcall PathQuoteSpacesA(str)
@ stdcall PathQuoteSpacesW(wstr)
@ stdcall PathRelativePathToA(ptr str long str long)
@ stdcall PathRelativePathToW(ptr wstr long wstr long)
@ stdcall PathRemoveBackslashA(str)
@ stdcall PathRemoveBackslashW(wstr)
@ stdcall PathRemoveBlanksA(str)
...
...
@@ -1113,13 +1113,13 @@
@ stdcall PathRemoveFileSpecW(wstr)
@ stdcall PathRenameExtensionA(str str)
@ stdcall PathRenameExtensionW(wstr wstr)
@ stdcall PathSearchAndQualifyA(str ptr long)
shlwapi.PathSearchAndQualifyA
@ stdcall PathSearchAndQualifyW(wstr ptr long)
shlwapi.PathSearchAndQualifyW
@ stdcall PathSkipRootA(str)
shlwapi.PathSkipRootA
@ stdcall PathSkipRootW(wstr)
shlwapi.PathSkipRootW
@ stdcall PathStripPathA(str)
shlwapi.PathStripPathA
@ stdcall PathStripPathW(wstr)
shlwapi.PathStripPathW
@ stdcall PathStripToRootA(str)
shlwapi.PathStripToRootA
@ stdcall PathSearchAndQualifyA(str ptr long)
@ stdcall PathSearchAndQualifyW(wstr ptr long)
@ stdcall PathSkipRootA(str)
@ stdcall PathSkipRootW(wstr)
@ stdcall PathStripPathA(str)
@ stdcall PathStripPathW(wstr)
@ stdcall PathStripToRootA(str)
@ stdcall PathStripToRootW(wstr)
@ stdcall PathUnExpandEnvStringsA(str ptr long) shlwapi.PathUnExpandEnvStringsA
@ stdcall PathUnExpandEnvStringsW(wstr ptr long) shlwapi.PathUnExpandEnvStringsW
...
...
dlls/kernelbase/path.c
View file @
1cef84a1
...
...
@@ -2176,3 +2176,425 @@ BOOL WINAPI PathIsValidCharW(WCHAR c, DWORD class)
return
class
&
path_charclass
[
c
];
}
char
*
WINAPI
PathFindNextComponentA
(
const
char
*
path
)
{
char
*
slash
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
!
path
||
!*
path
)
return
NULL
;
if
((
slash
=
StrChrA
(
path
,
'\\'
)))
{
if
(
slash
[
1
]
==
'\\'
)
slash
++
;
return
slash
+
1
;
}
return
(
char
*
)
path
+
strlen
(
path
);
}
WCHAR
*
WINAPI
PathFindNextComponentW
(
const
WCHAR
*
path
)
{
WCHAR
*
slash
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
!
path
||
!*
path
)
return
NULL
;
if
((
slash
=
StrChrW
(
path
,
'\\'
)))
{
if
(
slash
[
1
]
==
'\\'
)
slash
++
;
return
slash
+
1
;
}
return
(
WCHAR
*
)
path
+
strlenW
(
path
);
}
char
*
WINAPI
PathSkipRootA
(
const
char
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
!
path
||
!*
path
)
return
NULL
;
if
(
*
path
==
'\\'
&&
path
[
1
]
==
'\\'
)
{
/* Network share: skip share server and mount point */
path
+=
2
;
if
((
path
=
StrChrA
(
path
,
'\\'
))
&&
(
path
=
StrChrA
(
path
+
1
,
'\\'
)))
path
++
;
return
(
char
*
)
path
;
}
if
(
IsDBCSLeadByte
(
*
path
))
return
NULL
;
/* Check x:\ */
if
(
path
[
0
]
&&
path
[
1
]
==
':'
&&
path
[
2
]
==
'\\'
)
return
(
char
*
)
path
+
3
;
return
NULL
;
}
WCHAR
*
WINAPI
PathSkipRootW
(
const
WCHAR
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
!
path
||
!*
path
)
return
NULL
;
if
(
*
path
==
'\\'
&&
path
[
1
]
==
'\\'
)
{
/* Network share: skip share server and mount point */
path
+=
2
;
if
((
path
=
StrChrW
(
path
,
'\\'
))
&&
(
path
=
StrChrW
(
path
+
1
,
'\\'
)))
path
++
;
return
(
WCHAR
*
)
path
;
}
/* Check x:\ */
if
(
path
[
0
]
&&
path
[
1
]
==
':'
&&
path
[
2
]
==
'\\'
)
return
(
WCHAR
*
)
path
+
3
;
return
NULL
;
}
void
WINAPI
PathStripPathA
(
char
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
path
)
{
char
*
filename
=
PathFindFileNameA
(
path
);
if
(
filename
!=
path
)
RtlMoveMemory
(
path
,
filename
,
strlen
(
filename
)
+
1
);
}
}
void
WINAPI
PathStripPathW
(
WCHAR
*
path
)
{
WCHAR
*
filename
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
filename
=
PathFindFileNameW
(
path
);
if
(
filename
!=
path
)
RtlMoveMemory
(
path
,
filename
,
(
strlenW
(
filename
)
+
1
)
*
sizeof
(
WCHAR
));
}
BOOL
WINAPI
PathSearchAndQualifyA
(
const
char
*
path
,
char
*
buffer
,
UINT
length
)
{
TRACE
(
"%s, %p, %u
\n
"
,
wine_dbgstr_a
(
path
),
buffer
,
length
);
if
(
SearchPathA
(
NULL
,
path
,
NULL
,
length
,
buffer
,
NULL
))
return
TRUE
;
return
!!
GetFullPathNameA
(
path
,
length
,
buffer
,
NULL
);
}
BOOL
WINAPI
PathSearchAndQualifyW
(
const
WCHAR
*
path
,
WCHAR
*
buffer
,
UINT
length
)
{
TRACE
(
"%s, %p, %u
\n
"
,
wine_dbgstr_w
(
path
),
buffer
,
length
);
if
(
SearchPathW
(
NULL
,
path
,
NULL
,
length
,
buffer
,
NULL
))
return
TRUE
;
return
!!
GetFullPathNameW
(
path
,
length
,
buffer
,
NULL
);
}
BOOL
WINAPI
PathRelativePathToA
(
char
*
path
,
const
char
*
from
,
DWORD
attributes_from
,
const
char
*
to
,
DWORD
attributes_to
)
{
WCHAR
pathW
[
MAX_PATH
],
fromW
[
MAX_PATH
],
toW
[
MAX_PATH
];
BOOL
ret
;
TRACE
(
"%p, %s, %#x, %s, %#x
\n
"
,
path
,
wine_dbgstr_a
(
from
),
attributes_from
,
wine_dbgstr_a
(
to
),
attributes_to
);
if
(
!
path
||
!
from
||
!
to
)
return
FALSE
;
MultiByteToWideChar
(
CP_ACP
,
0
,
from
,
-
1
,
fromW
,
ARRAY_SIZE
(
fromW
));
MultiByteToWideChar
(
CP_ACP
,
0
,
to
,
-
1
,
toW
,
ARRAY_SIZE
(
toW
));
ret
=
PathRelativePathToW
(
pathW
,
fromW
,
attributes_from
,
toW
,
attributes_to
);
WideCharToMultiByte
(
CP_ACP
,
0
,
pathW
,
-
1
,
path
,
MAX_PATH
,
0
,
0
);
return
ret
;
}
BOOL
WINAPI
PathRelativePathToW
(
WCHAR
*
path
,
const
WCHAR
*
from
,
DWORD
attributes_from
,
const
WCHAR
*
to
,
DWORD
attributes_to
)
{
static
const
WCHAR
szPrevDirSlash
[]
=
{
'.'
,
'.'
,
'\\'
,
'\0'
};
static
const
WCHAR
szPrevDir
[]
=
{
'.'
,
'.'
,
'\0'
};
WCHAR
fromW
[
MAX_PATH
],
toW
[
MAX_PATH
];
DWORD
len
;
TRACE
(
"%p, %s, %#x, %s, %#x
\n
"
,
path
,
wine_dbgstr_w
(
from
),
attributes_from
,
wine_dbgstr_w
(
to
),
attributes_to
);
if
(
!
path
||
!
from
||
!
to
)
return
FALSE
;
*
path
=
'\0'
;
lstrcpynW
(
fromW
,
from
,
ARRAY_SIZE
(
fromW
));
lstrcpynW
(
toW
,
to
,
ARRAY_SIZE
(
toW
));
if
(
!
(
attributes_from
&
FILE_ATTRIBUTE_DIRECTORY
))
PathRemoveFileSpecW
(
fromW
);
if
(
!
(
attributes_to
&
FILE_ATTRIBUTE_DIRECTORY
))
PathRemoveFileSpecW
(
toW
);
/* Paths can only be relative if they have a common root */
if
(
!
(
len
=
PathCommonPrefixW
(
fromW
,
toW
,
0
)))
return
FALSE
;
/* Strip off 'from' components to the root, by adding "..\" */
from
=
fromW
+
len
;
if
(
!*
from
)
{
path
[
0
]
=
'.'
;
path
[
1
]
=
'\0'
;
}
if
(
*
from
==
'\\'
)
from
++
;
while
(
*
from
)
{
from
=
PathFindNextComponentW
(
from
);
strcatW
(
path
,
*
from
?
szPrevDirSlash
:
szPrevDir
);
}
/* From the root add the components of 'to' */
to
+=
len
;
/* We check to[-1] to avoid skipping end of string. See the notes for this function. */
if
(
*
to
&&
to
[
-
1
])
{
if
(
*
to
!=
'\\'
)
to
--
;
len
=
strlenW
(
path
);
if
(
len
+
strlenW
(
to
)
>=
MAX_PATH
)
{
*
path
=
'\0'
;
return
FALSE
;
}
strcpyW
(
path
+
len
,
to
);
}
return
TRUE
;
}
static
BOOL
path_match_maskA
(
const
char
*
name
,
const
char
*
mask
)
{
while
(
*
name
&&
*
mask
&&
*
mask
!=
';'
)
{
if
(
*
mask
==
'*'
)
{
do
{
if
(
path_match_maskA
(
name
,
mask
+
1
))
return
TRUE
;
/* try substrings */
}
while
(
*
name
++
);
return
FALSE
;
}
if
(
toupper
(
*
mask
)
!=
toupper
(
*
name
)
&&
*
mask
!=
'?'
)
return
FALSE
;
name
=
CharNextA
(
name
);
mask
=
CharNextA
(
mask
);
}
if
(
!*
name
)
{
while
(
*
mask
==
'*'
)
mask
++
;
if
(
!*
mask
||
*
mask
==
';'
)
return
TRUE
;
}
return
FALSE
;
}
BOOL
WINAPI
PathMatchSpecA
(
const
char
*
path
,
const
char
*
mask
)
{
TRACE
(
"%s, %s
\n
"
,
wine_dbgstr_a
(
path
),
wine_dbgstr_a
(
mask
));
if
(
!
lstrcmpA
(
mask
,
"*.*"
))
return
TRUE
;
/* Matches every path */
while
(
*
mask
)
{
while
(
*
mask
==
' '
)
mask
++
;
/* Eat leading spaces */
if
(
path_match_maskA
(
path
,
mask
))
return
TRUE
;
/* Matches the current mask */
while
(
*
mask
&&
*
mask
!=
';'
)
mask
=
CharNextA
(
mask
);
/* masks separated by ';' */
if
(
*
mask
==
';'
)
mask
++
;
}
return
FALSE
;
}
static
BOOL
path_match_maskW
(
const
WCHAR
*
name
,
const
WCHAR
*
mask
)
{
while
(
*
name
&&
*
mask
&&
*
mask
!=
';'
)
{
if
(
*
mask
==
'*'
)
{
do
{
if
(
path_match_maskW
(
name
,
mask
+
1
))
return
TRUE
;
/* try substrings */
}
while
(
*
name
++
);
return
FALSE
;
}
if
(
toupperW
(
*
mask
)
!=
toupperW
(
*
name
)
&&
*
mask
!=
'?'
)
return
FALSE
;
name
++
;
mask
++
;
}
if
(
!*
name
)
{
while
(
*
mask
==
'*'
)
mask
++
;
if
(
!*
mask
||
*
mask
==
';'
)
return
TRUE
;
}
return
FALSE
;
}
BOOL
WINAPI
PathMatchSpecW
(
const
WCHAR
*
path
,
const
WCHAR
*
mask
)
{
static
const
WCHAR
maskallW
[]
=
{
'*'
,
'.'
,
'*'
,
0
};
TRACE
(
"%s, %s
\n
"
,
wine_dbgstr_w
(
path
),
wine_dbgstr_w
(
mask
));
if
(
!
lstrcmpW
(
mask
,
maskallW
))
return
TRUE
;
/* Matches every path */
while
(
*
mask
)
{
while
(
*
mask
==
' '
)
mask
++
;
/* Eat leading spaces */
if
(
path_match_maskW
(
path
,
mask
))
return
TRUE
;
/* Matches the current path */
while
(
*
mask
&&
*
mask
!=
';'
)
mask
++
;
/* masks separated by ';' */
if
(
*
mask
==
';'
)
mask
++
;
}
return
FALSE
;
}
void
WINAPI
PathQuoteSpacesA
(
char
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
path
&&
StrChrA
(
path
,
' '
))
{
size_t
len
=
strlen
(
path
)
+
1
;
if
(
len
+
2
<
MAX_PATH
)
{
memmove
(
path
+
1
,
path
,
len
);
path
[
0
]
=
'"'
;
path
[
len
]
=
'"'
;
path
[
len
+
1
]
=
'\0'
;
}
}
}
void
WINAPI
PathQuoteSpacesW
(
WCHAR
*
path
)
{
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
path
&&
StrChrW
(
path
,
' '
))
{
int
len
=
strlenW
(
path
)
+
1
;
if
(
len
+
2
<
MAX_PATH
)
{
memmove
(
path
+
1
,
path
,
len
*
sizeof
(
WCHAR
));
path
[
0
]
=
'"'
;
path
[
len
]
=
'"'
;
path
[
len
+
1
]
=
'\0'
;
}
}
}
BOOL
WINAPI
PathIsSameRootA
(
const
char
*
path1
,
const
char
*
path2
)
{
const
char
*
start
;
int
len
;
TRACE
(
"%s, %s
\n
"
,
wine_dbgstr_a
(
path1
),
wine_dbgstr_a
(
path2
));
if
(
!
path1
||
!
path2
||
!
(
start
=
PathSkipRootA
(
path1
)))
return
FALSE
;
len
=
PathCommonPrefixA
(
path1
,
path2
,
NULL
)
+
1
;
return
start
-
path1
<=
len
;
}
BOOL
WINAPI
PathIsSameRootW
(
const
WCHAR
*
path1
,
const
WCHAR
*
path2
)
{
const
WCHAR
*
start
;
int
len
;
TRACE
(
"%s, %s
\n
"
,
wine_dbgstr_w
(
path1
),
wine_dbgstr_w
(
path2
));
if
(
!
path1
||
!
path2
||
!
(
start
=
PathSkipRootW
(
path1
)))
return
FALSE
;
len
=
PathCommonPrefixW
(
path1
,
path2
,
NULL
)
+
1
;
return
start
-
path1
<=
len
;
}
BOOL
WINAPI
PathFileExistsA
(
const
char
*
path
)
{
UINT
prev_mode
;
DWORD
attrs
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_a
(
path
));
if
(
!
path
)
return
FALSE
;
/* Prevent a dialog box if path is on a disk that has been ejected. */
prev_mode
=
SetErrorMode
(
SEM_FAILCRITICALERRORS
);
attrs
=
GetFileAttributesA
(
path
);
SetErrorMode
(
prev_mode
);
return
attrs
!=
INVALID_FILE_ATTRIBUTES
;
}
BOOL
WINAPI
PathFileExistsW
(
const
WCHAR
*
path
)
{
UINT
prev_mode
;
DWORD
attrs
;
TRACE
(
"%s
\n
"
,
wine_dbgstr_w
(
path
));
if
(
!
path
)
return
FALSE
;
prev_mode
=
SetErrorMode
(
SEM_FAILCRITICALERRORS
);
attrs
=
GetFileAttributesW
(
path
);
SetErrorMode
(
prev_mode
);
return
attrs
!=
INVALID_FILE_ATTRIBUTES
;
}
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