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
03d19f3e
Commit
03d19f3e
authored
Nov 22, 2018
by
Zhiyi Zhang
Committed by
Alexandre Julliard
Nov 22, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
kernelbase: Implement PathCchSkipRoot.
Signed-off-by:
Zhiyi Zhang
<
zzhang@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
2ec414c8
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
239 additions
and
2 deletions
+239
-2
api-ms-win-core-path-l1-1-0.spec
...-ms-win-core-path-l1-1-0/api-ms-win-core-path-l1-1-0.spec
+1
-1
kernelbase.spec
dlls/kernelbase/kernelbase.spec
+1
-1
path.c
dlls/kernelbase/path.c
+108
-0
path.c
dlls/kernelbase/tests/path.c
+128
-0
pathcch.h
include/pathcch.h
+1
-0
No files found.
dlls/api-ms-win-core-path-l1-1-0/api-ms-win-core-path-l1-1-0.spec
View file @
03d19f3e
...
...
@@ -16,7 +16,7 @@
@ stdcall PathCchRemoveExtension(wstr long) kernelbase.PathCchRemoveExtension
@ stub PathCchRemoveFileSpec
@ stdcall PathCchRenameExtension(wstr long wstr) kernelbase.PathCchRenameExtension
@ st
ub
PathCchSkipRoot
@ st
dcall PathCchSkipRoot(wstr ptr) kernelbase.
PathCchSkipRoot
@ stdcall PathCchStripPrefix(wstr long) kernelbase.PathCchStripPrefix
@ stub PathCchStripToRoot
@ stdcall PathIsUNCEx(wstr ptr) kernelbase.PathIsUNCEx
dlls/kernelbase/kernelbase.spec
View file @
03d19f3e
...
...
@@ -1045,7 +1045,7 @@
@ stdcall PathCchRemoveExtension(wstr long)
# @ stub PathCchRemoveFileSpec
@ stdcall PathCchRenameExtension(wstr long wstr)
# @ stub PathCchSkipRoot
@ stdcall PathCchSkipRoot(wstr ptr)
@ stdcall PathCchStripPrefix(wstr long)
# @ stub PathCchStripToRoot
@ stdcall PathCombineA(ptr str str) shlwapi.PathCombineA
...
...
dlls/kernelbase/path.c
View file @
03d19f3e
...
...
@@ -50,6 +50,82 @@ static BOOL is_prefixed_disk(const WCHAR *string)
return
!
strncmpW
(
string
,
prefix
,
ARRAY_SIZE
(
prefix
))
&&
isalphaW
(
string
[
4
])
&&
string
[
5
]
==
':'
;
}
static
BOOL
is_prefixed_volume
(
const
WCHAR
*
string
)
{
static
const
WCHAR
prefixed_volume
[]
=
{
'\\'
,
'\\'
,
'?'
,
'\\'
,
'V'
,
'o'
,
'l'
,
'u'
,
'm'
,
'e'
};
const
WCHAR
*
guid
;
INT
i
=
0
;
if
(
strncmpiW
(
string
,
prefixed_volume
,
ARRAY_SIZE
(
prefixed_volume
)))
return
FALSE
;
guid
=
string
+
ARRAY_SIZE
(
prefixed_volume
);
while
(
i
<=
37
)
{
switch
(
i
)
{
case
0
:
if
(
guid
[
i
]
!=
'{'
)
return
FALSE
;
break
;
case
9
:
case
14
:
case
19
:
case
24
:
if
(
guid
[
i
]
!=
'-'
)
return
FALSE
;
break
;
case
37
:
if
(
guid
[
i
]
!=
'}'
)
return
FALSE
;
break
;
default:
if
(
!
isalnumW
(
guid
[
i
]))
return
FALSE
;
break
;
}
i
++
;
}
return
TRUE
;
}
/* Get the next character beyond end of the segment.
Return TRUE if the last segment ends with a backslash */
static
BOOL
get_next_segment
(
const
WCHAR
*
next
,
const
WCHAR
**
next_segment
)
{
while
(
*
next
&&
*
next
!=
'\\'
)
next
++
;
if
(
*
next
==
'\\'
)
{
*
next_segment
=
next
+
1
;
return
TRUE
;
}
else
{
*
next_segment
=
next
;
return
FALSE
;
}
}
/* Find the last character of the root in a path, if there is one, without any segments */
static
const
WCHAR
*
get_root_end
(
const
WCHAR
*
path
)
{
/* Find path root */
if
(
is_prefixed_volume
(
path
))
return
path
[
48
]
==
'\\'
?
path
+
48
:
path
+
47
;
else
if
(
is_prefixed_unc
(
path
))
return
path
+
7
;
else
if
(
is_prefixed_disk
(
path
))
return
path
[
6
]
==
'\\'
?
path
+
6
:
path
+
5
;
/* \\ */
else
if
(
path
[
0
]
==
'\\'
&&
path
[
1
]
==
'\\'
)
return
path
+
1
;
/* \ */
else
if
(
path
[
0
]
==
'\\'
)
return
path
;
/* X:\ */
else
if
(
isalphaW
(
path
[
0
])
&&
path
[
1
]
==
':'
)
return
path
[
2
]
==
'\\'
?
path
+
2
:
path
+
1
;
else
return
NULL
;
}
HRESULT
WINAPI
PathCchAddBackslash
(
WCHAR
*
path
,
SIZE_T
size
)
{
return
PathCchAddBackslashEx
(
path
,
size
,
NULL
,
NULL
);
...
...
@@ -196,6 +272,38 @@ HRESULT WINAPI PathCchRenameExtension(WCHAR *path, SIZE_T size, const WCHAR *ext
return
FAILED
(
hr
)
?
hr
:
S_OK
;
}
HRESULT
WINAPI
PathCchSkipRoot
(
const
WCHAR
*
path
,
const
WCHAR
**
root_end
)
{
static
const
WCHAR
unc_prefix
[]
=
{
'\\'
,
'\\'
,
'?'
};
TRACE
(
"%s %p
\n
"
,
debugstr_w
(
path
),
root_end
);
if
(
!
path
||
!
path
[
0
]
||
!
root_end
||
(
!
memicmpW
(
unc_prefix
,
path
,
ARRAY_SIZE
(
unc_prefix
))
&&
!
is_prefixed_volume
(
path
)
&&
!
is_prefixed_unc
(
path
)
&&
!
is_prefixed_disk
(
path
)))
return
E_INVALIDARG
;
*
root_end
=
get_root_end
(
path
);
if
(
*
root_end
)
{
(
*
root_end
)
++
;
if
(
is_prefixed_unc
(
path
))
{
get_next_segment
(
*
root_end
,
root_end
);
get_next_segment
(
*
root_end
,
root_end
);
}
else
if
(
path
[
0
]
==
'\\'
&&
path
[
1
]
==
'\\'
&&
path
[
2
]
!=
'?'
)
{
/* Skip share server */
get_next_segment
(
*
root_end
,
root_end
);
/* If mount point is empty, don't skip over mount point */
if
(
**
root_end
!=
'\\'
)
get_next_segment
(
*
root_end
,
root_end
);
}
}
return
*
root_end
?
S_OK
:
E_INVALIDARG
;
}
HRESULT
WINAPI
PathCchStripPrefix
(
WCHAR
*
path
,
SIZE_T
size
)
{
TRACE
(
"%s %lu
\n
"
,
wine_dbgstr_w
(
path
),
size
);
...
...
dlls/kernelbase/tests/path.c
View file @
03d19f3e
...
...
@@ -37,6 +37,7 @@ HRESULT (WINAPI *pPathCchCombineEx)(WCHAR *out, SIZE_T size, const WCHAR *path1,
HRESULT
(
WINAPI
*
pPathCchFindExtension
)(
const
WCHAR
*
path
,
SIZE_T
size
,
const
WCHAR
**
extension
);
HRESULT
(
WINAPI
*
pPathCchRemoveExtension
)(
WCHAR
*
path
,
SIZE_T
size
);
HRESULT
(
WINAPI
*
pPathCchRenameExtension
)(
WCHAR
*
path
,
SIZE_T
size
,
const
WCHAR
*
extension
);
HRESULT
(
WINAPI
*
pPathCchSkipRoot
)(
const
WCHAR
*
path
,
const
WCHAR
**
root_end
);
HRESULT
(
WINAPI
*
pPathCchStripPrefix
)(
WCHAR
*
path
,
SIZE_T
size
);
BOOL
(
WINAPI
*
pPathIsUNCEx
)(
const
WCHAR
*
path
,
const
WCHAR
**
server
);
...
...
@@ -634,6 +635,131 @@ static void test_PathCchRenameExtension(void)
}
}
struct
skiproot_test
{
const
char
*
path
;
int
root_offset
;
HRESULT
hr
;
};
static
const
struct
skiproot_test
skiproot_tests
[]
=
{
/* Basic combination */
{
""
,
0
,
E_INVALIDARG
},
{
"C:
\\
"
,
3
,
S_OK
},
{
"
\\
"
,
1
,
S_OK
},
{
"
\\\\
.
\\
"
,
4
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\
"
,
8
,
S_OK
},
{
"
\\\\
?
\\
C:
\\
"
,
7
,
S_OK
},
/* Basic + \ */
{
"C:
\\\\
"
,
3
,
S_OK
},
{
"
\\\\
"
,
2
,
S_OK
},
{
"
\\\\
.
\\\\
"
,
4
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\\\
"
,
9
,
S_OK
},
{
"
\\\\
?
\\
C:
\\\\
"
,
7
,
S_OK
},
/* Basic + a */
{
"a"
,
0
,
E_INVALIDARG
},
{
"C:
\\
a"
,
3
,
S_OK
},
{
"
\\
a"
,
1
,
S_OK
},
{
"
\\\\
.
\\
a"
,
5
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\
a"
,
9
,
S_OK
},
/* Basic + \a */
{
"
\\
a"
,
1
,
S_OK
},
{
"C:
\\\\
a"
,
3
,
S_OK
},
{
"
\\\\
a"
,
3
,
S_OK
},
{
"
\\\\
.
\\\\
a"
,
4
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\\\
a"
,
10
,
S_OK
},
{
"
\\\\
?
\\
C:
\\\\
a"
,
7
,
S_OK
},
/* Basic + a\ */
{
"a
\\
"
,
0
,
E_INVALIDARG
},
{
"C:
\\
a
\\
"
,
3
,
S_OK
},
{
"
\\
a
\\
"
,
1
,
S_OK
},
{
"
\\\\
.
\\
a
\\
"
,
6
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\
a
\\
"
,
10
,
S_OK
},
{
"
\\\\
?
\\
C:
\\
a
\\
"
,
7
,
S_OK
},
/* Network share */
{
"
\\\\\\\\
"
,
3
,
S_OK
},
{
"
\\\\
a
\\
"
,
4
,
S_OK
},
{
"
\\\\
a
\\
b"
,
5
,
S_OK
},
{
"
\\\\
a
\\
b
\\
"
,
6
,
S_OK
},
{
"
\\\\
a
\\
b
\\\\
"
,
6
,
S_OK
},
{
"
\\\\
a
\\
b
\\\\
c"
,
6
,
S_OK
},
{
"
\\\\
a
\\
b
\\
c"
,
6
,
S_OK
},
{
"
\\\\
a
\\
b
\\
c
\\
"
,
6
,
S_OK
},
{
"
\\\\
a
\\
b
\\
c
\\
d"
,
6
,
S_OK
},
{
"
\\\\
a
\\\\
b
\\
c
\\
"
,
4
,
S_OK
},
{
"
\\\\
aa
\\
bb
\\
cc
\\
"
,
8
,
S_OK
},
/* UNC */
{
"
\\\\
?
\\
UNC
\\\\
"
,
9
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\
a
\\
b"
,
11
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\
a
\\
b"
,
11
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\
a
\\
b
\\
"
,
12
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\
a
\\
b
\\
c"
,
12
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\
a
\\
b
\\
c
\\
"
,
12
,
S_OK
},
{
"
\\\\
?
\\
UNC
\\
a
\\
b
\\
c
\\
d"
,
12
,
S_OK
},
{
"
\\\\
?
\\
C:"
,
6
,
S_OK
},
{
"
\\\\
?
\\
Volume{e51a1864-6f2d-4019-b73d-f4e60e600c26}"
,
48
,
S_OK
},
{
"
\\\\
?
\\
Volume{e51a1864-6f2d-4019-b73d-f4e60e600c26}
\\
"
,
49
,
S_OK
},
{
"
\\\\
?
\\
unc
\\
a
\\
b"
,
11
,
S_OK
},
{
"
\\\\
?
\\
volume{e51a1864-6f2d-4019-b73d-f4e60e600c26}
\\
"
,
49
,
S_OK
},
{
"
\\\\
?
\\
volume{e51a1864-6f2d-4019-b73d-f4e60e600c26}
\\
a"
,
49
,
S_OK
},
/* Malformed */
{
"C:"
,
2
,
S_OK
},
{
":"
,
0
,
E_INVALIDARG
},
{
":
\\
"
,
0
,
E_INVALIDARG
},
{
"C
\\
"
,
0
,
E_INVALIDARG
},
{
"
\\
?"
,
1
,
S_OK
},
{
"
\\
?
\\
UNC"
,
1
,
S_OK
},
{
"
\\\\
?
\\
"
,
0
,
E_INVALIDARG
},
{
"
\\\\
?
\\
UNC"
,
0
,
E_INVALIDARG
},
{
"
\\\\
?
\\
::
\\
"
,
0
,
E_INVALIDARG
},
{
"
\\\\
?
\\
Volume"
,
0
,
E_INVALIDARG
},
{
"
\\
."
,
1
,
S_OK
},
{
"
\\\\
.."
,
4
,
S_OK
},
{
"
\\\\
..a"
,
5
,
S_OK
}
};
static
void
test_PathCchSkipRoot
(
void
)
{
WCHAR
pathW
[
MAX_PATH
];
const
WCHAR
*
root_end
;
HRESULT
hr
;
INT
i
;
if
(
!
pPathCchSkipRoot
)
{
win_skip
(
"PathCchSkipRoot() is not available.
\n
"
);
return
;
}
root_end
=
(
const
WCHAR
*
)
0xdeadbeef
;
hr
=
pPathCchSkipRoot
(
NULL
,
&
root_end
);
ok
(
hr
==
E_INVALIDARG
,
"Expect result %#x, got %#x
\n
"
,
E_INVALIDARG
,
hr
);
ok
(
root_end
==
(
const
WCHAR
*
)
0xdeadbeef
,
"Expect root_end 0xdeadbeef, got %p
\n
"
,
root_end
);
MultiByteToWideChar
(
CP_ACP
,
0
,
"C:
\\
"
,
-
1
,
pathW
,
ARRAY_SIZE
(
pathW
));
hr
=
pPathCchSkipRoot
(
pathW
,
NULL
);
ok
(
hr
==
E_INVALIDARG
,
"Expect result %#x, got %#x
\n
"
,
E_INVALIDARG
,
hr
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
skiproot_tests
);
i
++
)
{
const
struct
skiproot_test
*
t
=
skiproot_tests
+
i
;
MultiByteToWideChar
(
CP_ACP
,
0
,
t
->
path
,
-
1
,
pathW
,
ARRAY_SIZE
(
pathW
));
hr
=
pPathCchSkipRoot
(
pathW
,
&
root_end
);
ok
(
hr
==
t
->
hr
,
"path %s expect result %#x, got %#x
\n
"
,
t
->
path
,
t
->
hr
,
hr
);
if
(
SUCCEEDED
(
hr
))
ok
(
root_end
-
pathW
==
t
->
root_offset
,
"path %s expect root offset %d, got %ld
\n
"
,
t
->
path
,
t
->
root_offset
,
(
INT_PTR
)(
root_end
-
pathW
));
}
}
struct
stripprefix_test
{
const
CHAR
*
path
;
...
...
@@ -789,6 +915,7 @@ START_TEST(path)
pPathCchFindExtension
=
(
void
*
)
GetProcAddress
(
hmod
,
"PathCchFindExtension"
);
pPathCchRemoveExtension
=
(
void
*
)
GetProcAddress
(
hmod
,
"PathCchRemoveExtension"
);
pPathCchRenameExtension
=
(
void
*
)
GetProcAddress
(
hmod
,
"PathCchRenameExtension"
);
pPathCchSkipRoot
=
(
void
*
)
GetProcAddress
(
hmod
,
"PathCchSkipRoot"
);
pPathCchStripPrefix
=
(
void
*
)
GetProcAddress
(
hmod
,
"PathCchStripPrefix"
);
pPathIsUNCEx
=
(
void
*
)
GetProcAddress
(
hmod
,
"PathIsUNCEx"
);
...
...
@@ -799,6 +926,7 @@ START_TEST(path)
test_PathCchFindExtension
();
test_PathCchRemoveExtension
();
test_PathCchRenameExtension
();
test_PathCchSkipRoot
();
test_PathCchStripPrefix
();
test_PathIsUNCEx
();
}
include/pathcch.h
View file @
03d19f3e
...
...
@@ -32,5 +32,6 @@ HRESULT WINAPI PathCchCombineEx(WCHAR *out, SIZE_T size, const WCHAR *path1, con
HRESULT
WINAPI
PathCchFindExtension
(
const
WCHAR
*
path
,
SIZE_T
size
,
const
WCHAR
**
extension
);
HRESULT
WINAPI
PathCchRemoveExtension
(
WCHAR
*
path
,
SIZE_T
size
);
HRESULT
WINAPI
PathCchRenameExtension
(
WCHAR
*
path
,
SIZE_T
size
,
const
WCHAR
*
extension
);
HRESULT
WINAPI
PathCchSkipRoot
(
const
WCHAR
*
path
,
const
WCHAR
**
root_end
);
HRESULT
WINAPI
PathCchStripPrefix
(
WCHAR
*
path
,
SIZE_T
size
);
BOOL
WINAPI
PathIsUNCEx
(
const
WCHAR
*
path
,
const
WCHAR
**
server
);
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