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
4b33a339
Commit
4b33a339
authored
Dec 07, 2014
by
Sebastian Lackner
Committed by
Alexandre Julliard
Dec 16, 2014
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
shlwapi: Add implementation for StrCatChainW.
Based on a patch by Huw Campbell.
parent
8dfe0ff2
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
165 additions
and
1 deletion
+165
-1
api-ms-win-downlevel-shlwapi-l1-1-0.spec
...l-shlwapi-l1-1-0/api-ms-win-downlevel-shlwapi-l1-1-0.spec
+1
-1
shlwapi.spec
dlls/shlwapi/shlwapi.spec
+1
-0
string.c
dlls/shlwapi/string.c
+41
-0
string.c
dlls/shlwapi/tests/string.c
+122
-0
No files found.
dlls/api-ms-win-downlevel-shlwapi-l1-1-0/api-ms-win-downlevel-shlwapi-l1-1-0.spec
View file @
4b33a339
...
@@ -86,7 +86,7 @@
...
@@ -86,7 +86,7 @@
@ stdcall SHRegSetUSValueW( wstr wstr long ptr long long) shlwapi.SHRegSetUSValueW
@ stdcall SHRegSetUSValueW( wstr wstr long ptr long long) shlwapi.SHRegSetUSValueW
@ stdcall StrCatBuffA(str str long) shlwapi.StrCatBuffA
@ stdcall StrCatBuffA(str str long) shlwapi.StrCatBuffA
@ stdcall StrCatBuffW(wstr wstr long) shlwapi.StrCatBuffW
@ stdcall StrCatBuffW(wstr wstr long) shlwapi.StrCatBuffW
@ st
ub
StrCatChainW
@ st
dcall StrCatChainW(ptr long long wstr) shlwapi.
StrCatChainW
@ stdcall StrChrA(str long) shlwapi.StrChrA
@ stdcall StrChrA(str long) shlwapi.StrChrA
@ stdcall StrChrIA(str long) shlwapi.StrChrIA
@ stdcall StrChrIA(str long) shlwapi.StrChrIA
@ stdcall StrChrIW(wstr long) shlwapi.StrChrIW
@ stdcall StrChrIW(wstr long) shlwapi.StrChrIW
...
...
dlls/shlwapi/shlwapi.spec
View file @
4b33a339
...
@@ -759,6 +759,7 @@
...
@@ -759,6 +759,7 @@
@ stdcall StrCSpnW (wstr wstr)
@ stdcall StrCSpnW (wstr wstr)
@ stdcall StrCatBuffA (str str long)
@ stdcall StrCatBuffA (str str long)
@ stdcall StrCatBuffW (wstr wstr long)
@ stdcall StrCatBuffW (wstr wstr long)
@ stdcall StrCatChainW (ptr long long wstr)
@ stdcall StrCatW (ptr wstr)
@ stdcall StrCatW (ptr wstr)
@ stdcall StrChrA (str long)
@ stdcall StrChrA (str long)
@ stdcall StrChrIA (str long)
@ stdcall StrChrIA (str long)
...
...
dlls/shlwapi/string.c
View file @
4b33a339
...
@@ -459,6 +459,47 @@ LPWSTR WINAPI StrCatW(LPWSTR lpszStr, LPCWSTR lpszSrc)
...
@@ -459,6 +459,47 @@ LPWSTR WINAPI StrCatW(LPWSTR lpszStr, LPCWSTR lpszSrc)
}
}
/*************************************************************************
/*************************************************************************
* StrCatChainW [SHLWAPI.@]
*
* Concatenates two unicode strings.
*
* PARAMS
* lpszStr [O] Initial string
* cchMax [I] Length of destination buffer
* ichAt [I] Offset from the destination buffer to begin concatenation
* lpszCat [I] String to concatenate
*
* RETURNS
* The offset from the beginning of pszDst to the terminating NULL.
*/
DWORD
WINAPI
StrCatChainW
(
LPWSTR
lpszStr
,
DWORD
cchMax
,
DWORD
ichAt
,
LPCWSTR
lpszCat
)
{
TRACE
(
"(%s,%u,%d,%s)
\n
"
,
debugstr_w
(
lpszStr
),
cchMax
,
ichAt
,
debugstr_w
(
lpszCat
));
if
(
ichAt
==
-
1
)
ichAt
=
strlenW
(
lpszStr
);
if
(
!
cchMax
)
return
ichAt
;
if
(
ichAt
==
cchMax
)
ichAt
--
;
if
(
lpszCat
&&
ichAt
<
cchMax
)
{
lpszStr
+=
ichAt
;
while
(
ichAt
<
cchMax
-
1
&&
*
lpszCat
)
{
*
lpszStr
++
=
*
lpszCat
++
;
ichAt
++
;
}
*
lpszStr
=
0
;
}
return
ichAt
;
}
/*************************************************************************
* StrCpyW [SHLWAPI.@]
* StrCpyW [SHLWAPI.@]
*
*
* Copy a string to another string.
* Copy a string to another string.
...
...
dlls/shlwapi/tests/string.c
View file @
4b33a339
...
@@ -48,6 +48,7 @@ static DWORD (WINAPI *pSHAnsiToAnsi)(LPCSTR,LPSTR,int);
...
@@ -48,6 +48,7 @@ static DWORD (WINAPI *pSHAnsiToAnsi)(LPCSTR,LPSTR,int);
static
DWORD
(
WINAPI
*
pSHUnicodeToUnicode
)(
LPCWSTR
,
LPWSTR
,
int
);
static
DWORD
(
WINAPI
*
pSHUnicodeToUnicode
)(
LPCWSTR
,
LPWSTR
,
int
);
static
LPSTR
(
WINAPI
*
pStrCatBuffA
)(
LPSTR
,
LPCSTR
,
INT
);
static
LPSTR
(
WINAPI
*
pStrCatBuffA
)(
LPSTR
,
LPCSTR
,
INT
);
static
LPWSTR
(
WINAPI
*
pStrCatBuffW
)(
LPWSTR
,
LPCWSTR
,
INT
);
static
LPWSTR
(
WINAPI
*
pStrCatBuffW
)(
LPWSTR
,
LPCWSTR
,
INT
);
static
DWORD
(
WINAPI
*
pStrCatChainW
)(
LPWSTR
,
DWORD
,
DWORD
,
LPCWSTR
);
static
LPSTR
(
WINAPI
*
pStrCpyNXA
)(
LPSTR
,
LPCSTR
,
int
);
static
LPSTR
(
WINAPI
*
pStrCpyNXA
)(
LPSTR
,
LPCSTR
,
int
);
static
LPWSTR
(
WINAPI
*
pStrCpyNXW
)(
LPWSTR
,
LPCWSTR
,
int
);
static
LPWSTR
(
WINAPI
*
pStrCpyNXW
)(
LPWSTR
,
LPCWSTR
,
int
);
static
LPSTR
(
WINAPI
*
pStrFormatByteSize64A
)(
LONGLONG
,
LPSTR
,
UINT
);
static
LPSTR
(
WINAPI
*
pStrFormatByteSize64A
)(
LONGLONG
,
LPSTR
,
UINT
);
...
@@ -1481,6 +1482,125 @@ static void test_StrStrNIW(void)
...
@@ -1481,6 +1482,125 @@ static void test_StrStrNIW(void)
}
}
}
}
static
void
test_StrCatChainW
(
void
)
{
static
const
WCHAR
deadbeefW
[]
=
{
'D'
,
'e'
,
'A'
,
'd'
,
'B'
,
'e'
,
'E'
,
'f'
,
0
};
static
const
WCHAR
deadW
[]
=
{
'D'
,
'e'
,
'A'
,
'd'
,
0
};
static
const
WCHAR
beefW
[]
=
{
'B'
,
'e'
,
'E'
,
'f'
,
0
};
WCHAR
buf
[
32
+
1
];
DWORD
ret
;
if
(
!
pStrCatChainW
)
{
win_skip
(
"StrCatChainW is not available
\n
"
);
return
;
}
/* Test with NULL buffer */
ret
=
pStrCatChainW
(
NULL
,
0
,
0
,
beefW
);
ok
(
ret
==
0
,
"Expected StrCatChainW to return 0, got %u
\n
"
,
ret
);
/* Test with empty buffer */
memset
(
buf
,
0x11
,
sizeof
(
buf
));
ret
=
pStrCatChainW
(
buf
,
0
,
0
,
beefW
);
ok
(
ret
==
0
,
"Expected StrCatChainW to return 0, got %u
\n
"
,
ret
);
ok
(
buf
[
0
]
==
0x1111
,
"Expected buf[0] = 0x1111, got %x
\n
"
,
buf
[
0
]);
memcpy
(
buf
,
deadbeefW
,
sizeof
(
deadbeefW
));
ret
=
pStrCatChainW
(
buf
,
0
,
-
1
,
beefW
);
ok
(
ret
==
8
,
"Expected StrCatChainW to return 8, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadbeefW
,
sizeof
(
deadbeefW
)),
"Buffer contains wrong data
\n
"
);
/* Append data to existing string with offset = -1 */
memset
(
buf
,
0x11
,
sizeof
(
buf
));
ret
=
pStrCatChainW
(
buf
,
32
,
0
,
deadW
);
ok
(
ret
==
4
,
"Expected StrCatChainW to return 4, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadW
,
sizeof
(
deadW
)),
"Buffer contains wrong data
\n
"
);
ret
=
pStrCatChainW
(
buf
,
32
,
-
1
,
beefW
);
ok
(
ret
==
8
,
"Expected StrCatChainW to return 8, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadbeefW
,
sizeof
(
deadbeefW
)),
"Buffer contains wrong data
\n
"
);
/* Append data at a fixed offset */
memset
(
buf
,
0x11
,
sizeof
(
buf
));
ret
=
pStrCatChainW
(
buf
,
32
,
0
,
deadW
);
ok
(
ret
==
4
,
"Expected StrCatChainW to return 4, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadW
,
sizeof
(
deadW
)),
"Buffer contains wrong data
\n
"
);
ret
=
pStrCatChainW
(
buf
,
32
,
4
,
beefW
);
ok
(
ret
==
8
,
"Expected StrCatChainW to return 8, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadbeefW
,
sizeof
(
deadbeefW
)),
"Buffer contains wrong data
\n
"
);
/* Buffer exactly sufficient for string + terminating null */
memset
(
buf
,
0x11
,
sizeof
(
buf
));
ret
=
pStrCatChainW
(
buf
,
5
,
0
,
deadW
);
ok
(
ret
==
4
,
"Expected StrCatChainW to return 4, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadW
,
sizeof
(
deadW
)),
"Buffer contains wrong data
\n
"
);
/* Buffer too small, string will be truncated */
memset
(
buf
,
0x11
,
sizeof
(
buf
));
ret
=
pStrCatChainW
(
buf
,
4
,
0
,
deadW
);
if
(
ret
==
4
)
{
/* Windows 2000 and XP uses a slightly different implementation
* for StrCatChainW, which doesn't ensure that strings are null-
* terminated. Skip test if we detect such an implementation. */
win_skip
(
"Windows2000/XP behaviour detected for StrCatChainW, skipping tests
\n
"
);
return
;
}
ok
(
ret
==
3
,
"Expected StrCatChainW to return 3, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadW
,
3
*
sizeof
(
WCHAR
)),
"Buffer contains wrong data
\n
"
);
ok
(
!
buf
[
3
],
"String is not nullterminated
\n
"
);
ok
(
buf
[
4
]
==
0x1111
,
"Expected buf[4] = 0x1111, got %x
\n
"
,
buf
[
4
]);
/* Overwrite part of an existing string */
ret
=
pStrCatChainW
(
buf
,
4
,
1
,
beefW
);
ok
(
ret
==
3
,
"Expected StrCatChainW to return 3, got %u
\n
"
,
ret
);
ok
(
buf
[
0
]
==
'D'
,
"Expected buf[0] = 'D', got %x
\n
"
,
buf
[
0
]);
ok
(
buf
[
1
]
==
'B'
,
"Expected buf[1] = 'B', got %x
\n
"
,
buf
[
1
]);
ok
(
buf
[
2
]
==
'e'
,
"Expected buf[2] = 'e', got %x
\n
"
,
buf
[
2
]);
ok
(
!
buf
[
3
],
"String is not nullterminated
\n
"
);
ok
(
buf
[
4
]
==
0x1111
,
"Expected buf[4] = 0x1111, got %x
\n
"
,
buf
[
4
]);
/* Test appending to full buffer */
memset
(
buf
,
0x11
,
sizeof
(
buf
));
memcpy
(
buf
,
deadbeefW
,
sizeof
(
deadbeefW
));
memcpy
(
buf
+
9
,
deadW
,
sizeof
(
deadW
));
ret
=
pStrCatChainW
(
buf
,
9
,
8
,
beefW
);
ok
(
ret
==
8
,
"Expected StrCatChainW to return 8, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadbeefW
,
sizeof
(
deadbeefW
)),
"Buffer contains wrong data
\n
"
);
ok
(
!
memcmp
(
buf
+
9
,
deadW
,
sizeof
(
deadW
)),
"Buffer contains wrong data
\n
"
);
/* Offset points at the end of the buffer */
ret
=
pStrCatChainW
(
buf
,
9
,
9
,
beefW
);
ok
(
ret
==
8
,
"Expected StrCatChainW to return 8, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadbeefW
,
sizeof
(
deadbeefW
)),
"Buffer contains wrong data
\n
"
);
ok
(
!
memcmp
(
buf
+
9
,
deadW
,
sizeof
(
deadW
)),
"Buffer contains wrong data
\n
"
);
/* Offset points outside of the buffer */
ret
=
pStrCatChainW
(
buf
,
9
,
10
,
beefW
);
ok
(
ret
==
10
,
"Expected StrCatChainW to return 10, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadbeefW
,
sizeof
(
deadbeefW
)),
"Buffer contains wrong data
\n
"
);
ok
(
!
memcmp
(
buf
+
9
,
deadW
,
sizeof
(
deadW
)),
"Buffer contains wrong data
\n
"
);
/* The same but without nullterminated string */
memcpy
(
buf
,
deadbeefW
,
sizeof
(
deadbeefW
));
ret
=
pStrCatChainW
(
buf
,
5
,
-
1
,
deadW
);
ok
(
ret
==
8
,
"Expected StrCatChainW to return 8, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadbeefW
,
sizeof
(
deadbeefW
)),
"Buffer contains wrong data
\n
"
);
ret
=
pStrCatChainW
(
buf
,
5
,
5
,
deadW
);
ok
(
ret
==
4
,
"Expected StrCatChainW to return 4, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadW
,
sizeof
(
deadW
)),
"Buffer contains wrong data
\n
"
);
ok
(
buf
[
5
]
==
'e'
,
"Expected buf[5] = 'e', got %x
\n
"
,
buf
[
5
]);
ret
=
pStrCatChainW
(
buf
,
5
,
6
,
deadW
);
ok
(
ret
==
6
,
"Expected StrCatChainW to return 6, got %u
\n
"
,
ret
);
ok
(
!
memcmp
(
buf
,
deadW
,
sizeof
(
deadW
)),
"Buffer contains wrong data
\n
"
);
ok
(
buf
[
5
]
==
'e'
,
"Expected buf[5] = 'e', got %x
\n
"
,
buf
[
5
]);
}
START_TEST
(
string
)
START_TEST
(
string
)
{
{
HMODULE
hShlwapi
;
HMODULE
hShlwapi
;
...
@@ -1500,6 +1620,7 @@ START_TEST(string)
...
@@ -1500,6 +1620,7 @@ START_TEST(string)
pSHUnicodeToUnicode
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
(
LPSTR
)
346
);
pSHUnicodeToUnicode
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
(
LPSTR
)
346
);
pStrCatBuffA
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
"StrCatBuffA"
);
pStrCatBuffA
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
"StrCatBuffA"
);
pStrCatBuffW
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
"StrCatBuffW"
);
pStrCatBuffW
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
"StrCatBuffW"
);
pStrCatChainW
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
"StrCatChainW"
);
pStrCpyNXA
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
(
LPSTR
)
399
);
pStrCpyNXA
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
(
LPSTR
)
399
);
pStrCpyNXW
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
(
LPSTR
)
400
);
pStrCpyNXW
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
(
LPSTR
)
400
);
pStrChrNW
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
"StrChrNW"
);
pStrChrNW
=
(
void
*
)
GetProcAddress
(
hShlwapi
,
"StrChrNW"
);
...
@@ -1565,6 +1686,7 @@ START_TEST(string)
...
@@ -1565,6 +1686,7 @@ START_TEST(string)
test_StrStrIW
();
test_StrStrIW
();
test_StrStrNW
();
test_StrStrNW
();
test_StrStrNIW
();
test_StrStrNIW
();
test_StrCatChainW
();
CoUninitialize
();
CoUninitialize
();
}
}
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