mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-09-13 09:17:20 -07:00
Add SRWLock patches and workarounds for shlwapi url functions.
This commit is contained in:
parent
c3d5bcab99
commit
9c1492069b
@ -0,0 +1,207 @@
|
||||
From 7324234ddce315b21a31e9e810593ea0c6917384 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Sat, 11 Jan 2014 02:18:10 +0100
|
||||
Subject: ntdll: Implement SRWLock functions using keyed events
|
||||
|
||||
---
|
||||
dlls/kernel32/tests/sync.c | 6 ---
|
||||
dlls/ntdll/sync.c | 119 ++++++++++++++++++++++++++++++++++++++++++--
|
||||
2 files changed, 115 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/kernel32/tests/sync.c b/dlls/kernel32/tests/sync.c
|
||||
index e5d1353..c7cceaa 100644
|
||||
--- a/dlls/kernel32/tests/sync.c
|
||||
+++ b/dlls/kernel32/tests/sync.c
|
||||
@@ -1890,9 +1890,6 @@ static void test_srwlock_base(void)
|
||||
WaitForSingleObject(h2, 100);
|
||||
WaitForSingleObject(h3, 100);
|
||||
|
||||
- /* the current implementation just consists of stubs and all tests fail */
|
||||
- todo_wine
|
||||
- {
|
||||
ok(!srwlock_base_errors.wrong_execution_order,
|
||||
"thread commands were executed in the wrong order (occurred %d times).\n",
|
||||
srwlock_base_errors.wrong_execution_order);
|
||||
@@ -1916,7 +1913,6 @@ static void test_srwlock_base(void)
|
||||
ok(!srwlock_base_errors.excl_not_preferred,
|
||||
"thread waiting for exclusive access to the SHMLock was not preferred (occurred %d times).\n",
|
||||
srwlock_base_errors.excl_not_preferred);
|
||||
- }
|
||||
}
|
||||
|
||||
static SRWLOCK srwlock_example;
|
||||
@@ -1994,8 +1990,6 @@ static void test_srwlock_example(void)
|
||||
WaitForSingleObject(h3, 1000);
|
||||
|
||||
ok(!srwlock_inside, "threads didn't terminate properly, srwlock_inside is %d.\n", srwlock_inside);
|
||||
-
|
||||
- todo_wine
|
||||
ok(!srwlock_example_errors, "errors occured while running SRWLock example test (number of errors: %d)\n",
|
||||
srwlock_example_errors);
|
||||
|
||||
diff --git a/dlls/ntdll/sync.c b/dlls/ntdll/sync.c
|
||||
index c94d9c4..d68be50 100644
|
||||
--- a/dlls/ntdll/sync.c
|
||||
+++ b/dlls/ntdll/sync.c
|
||||
@@ -1382,8 +1382,88 @@ DWORD WINAPI RtlRunOnceExecuteOnce( RTL_RUN_ONCE *once, PRTL_RUN_ONCE_INIT_FN fu
|
||||
return RtlRunOnceComplete( once, 0, context ? *context : NULL );
|
||||
}
|
||||
|
||||
+#define SRWLOCK_MASK_IN_EXCLUSIVE 0x80000000
|
||||
+#define SRWLOCK_MASK_EXCLUSIVE_QUEUE 0x7fff0000
|
||||
+#define SRWLOCK_MASK_SHARED_QUEUE 0x0000ffff
|
||||
+#define SRWLOCK_RES_EXCLUSIVE 0x00010000
|
||||
+#define SRWLOCK_RES_SHARED 0x00000001
|
||||
+
|
||||
+#ifdef WORDS_BIGENDIAN
|
||||
+#define srwlock_key_exclusive(lock) (&lock->Ptr)
|
||||
+#define srwlock_key_shared(lock) ((void *)((char *)&lock->Ptr + 2))
|
||||
+#else
|
||||
+#define srwlock_key_exclusive(lock) ((void *)((char *)&lock->Ptr + 2))
|
||||
+#define srwlock_key_shared(lock) (&lock->Ptr)
|
||||
+#endif
|
||||
+
|
||||
+static inline unsigned int srwlock_lock_exclusive( unsigned int *dest, int incr )
|
||||
+{
|
||||
+ unsigned int val, tmp;
|
||||
+ /* Atomically modifies the value of *dest by adding incr. If the shared
|
||||
+ * queue is empty and there are threads waiting for exclusive access, then
|
||||
+ * sets the mark SRWLOCK_MASK_IN_EXCLUSIVE to signal other threads that
|
||||
+ * they are allowed to use again the shared queue counter. */
|
||||
+ for (val = *dest;; val = tmp)
|
||||
+ {
|
||||
+ tmp = val + incr;
|
||||
+ if ((tmp & SRWLOCK_MASK_EXCLUSIVE_QUEUE) && !(tmp & SRWLOCK_MASK_SHARED_QUEUE))
|
||||
+ tmp |= SRWLOCK_MASK_IN_EXCLUSIVE;
|
||||
+ if ((tmp = interlocked_cmpxchg( (int *)dest, tmp, val )) == val)
|
||||
+ break;
|
||||
+ }
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+static inline unsigned int srwlock_unlock_exclusive( unsigned int *dest, int incr )
|
||||
+{
|
||||
+ unsigned int val, tmp;
|
||||
+ /* Atomically modifies the value of *dest by adding incr. If the queue of
|
||||
+ * threads waiting for exclusive access is empty, then remove the
|
||||
+ * SRWLOCK_MASK_IN_EXCLUSIVE flag (only the shared queue counter will
|
||||
+ * remain). */
|
||||
+ for (val = *dest;; val = tmp)
|
||||
+ {
|
||||
+ tmp = val + incr;
|
||||
+ if (!(tmp & SRWLOCK_MASK_EXCLUSIVE_QUEUE))
|
||||
+ tmp &= SRWLOCK_MASK_SHARED_QUEUE;
|
||||
+ if ((tmp = interlocked_cmpxchg( (int *)dest, tmp, val )) == val)
|
||||
+ break;
|
||||
+ }
|
||||
+ return val;
|
||||
+}
|
||||
+
|
||||
+static inline void srwlock_leave_exclusive( RTL_SRWLOCK *lock, unsigned int val )
|
||||
+{
|
||||
+ /* Used when a thread leaves an exclusive section. If there are other
|
||||
+ * exclusive access threads they are processed first, afterwards process
|
||||
+ * the shared waiters. */
|
||||
+ if (val & SRWLOCK_MASK_EXCLUSIVE_QUEUE)
|
||||
+ NtReleaseKeyedEvent( keyed_event, srwlock_key_exclusive(lock), FALSE, NULL );
|
||||
+ else
|
||||
+ {
|
||||
+ val &= SRWLOCK_MASK_SHARED_QUEUE; /* remove SRWLOCK_MASK_IN_EXCLUSIVE */
|
||||
+ while (val--)
|
||||
+ NtReleaseKeyedEvent( keyed_event, srwlock_key_shared(lock), FALSE, NULL );
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+static inline void srwlock_leave_shared( RTL_SRWLOCK *lock, unsigned int val )
|
||||
+{
|
||||
+ /* Wake up one exclusive thread as soon as the last shared access thread
|
||||
+ * has left. */
|
||||
+ if ((val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) && !(val & SRWLOCK_MASK_SHARED_QUEUE))
|
||||
+ NtReleaseKeyedEvent( keyed_event, srwlock_key_exclusive(lock), FALSE, NULL );
|
||||
+}
|
||||
+
|
||||
/***********************************************************************
|
||||
* RtlInitializeSRWLock (NTDLL.@)
|
||||
+ *
|
||||
+ * NOTES
|
||||
+ * Please note that SRWLocks do not keep track of the owner of a lock.
|
||||
+ * It doesn't make any difference which thread for example unlocks an
|
||||
+ * SRWLock (see corresponding tests). This implementation uses two
|
||||
+ * keyed events (one for the exclusive waiters and one for the shared
|
||||
+ * waiters) and is limited to 2^15-1 waiting threads.
|
||||
*/
|
||||
void WINAPI RtlInitializeSRWLock( RTL_SRWLOCK *lock )
|
||||
{
|
||||
@@ -1392,10 +1472,16 @@ void WINAPI RtlInitializeSRWLock( RTL_SRWLOCK *lock )
|
||||
|
||||
/***********************************************************************
|
||||
* RtlAcquireSRWLockExclusive (NTDLL.@)
|
||||
+ *
|
||||
+ * NOTES
|
||||
+ * Unlike RtlAcquireResourceExclusive this function doesn't allow
|
||||
+ * nested calls from the same thread. "Upgrading" a shared access lock
|
||||
+ * to an exclusive access lock also doesn't seem to be supported.
|
||||
*/
|
||||
void WINAPI RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
{
|
||||
- FIXME( "%p stub\n", lock );
|
||||
+ if (srwlock_lock_exclusive( (unsigned int *)&lock->Ptr, SRWLOCK_RES_EXCLUSIVE ))
|
||||
+ NtWaitForKeyedEvent( keyed_event, srwlock_key_exclusive(lock), FALSE, NULL );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1403,7 +1489,30 @@ void WINAPI RtlAcquireSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
*/
|
||||
void WINAPI RtlAcquireSRWLockShared( RTL_SRWLOCK *lock )
|
||||
{
|
||||
- FIXME( "%p stub\n", lock );
|
||||
+ unsigned int val, tmp;
|
||||
+ /* Acquires a shared lock. If its currently not possible to add elements to
|
||||
+ * the shared queue, then request exclusive access instead. */
|
||||
+ for (val = *(unsigned int *)&lock->Ptr;; val = tmp)
|
||||
+ {
|
||||
+ if ((val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) && !(val & SRWLOCK_MASK_IN_EXCLUSIVE))
|
||||
+ tmp = val + SRWLOCK_RES_EXCLUSIVE;
|
||||
+ else
|
||||
+ tmp = val + SRWLOCK_RES_SHARED;
|
||||
+ if ((tmp = interlocked_cmpxchg( (int *)&lock->Ptr, tmp, val )) == val)
|
||||
+ break;
|
||||
+ }
|
||||
+
|
||||
+ /* Drop exclusive access again and instead requeue for shared access. */
|
||||
+ if ((val & SRWLOCK_MASK_EXCLUSIVE_QUEUE) && !(val & SRWLOCK_MASK_IN_EXCLUSIVE))
|
||||
+ {
|
||||
+ NtWaitForKeyedEvent( keyed_event, srwlock_key_exclusive(lock), FALSE, NULL );
|
||||
+ val = srwlock_unlock_exclusive( (unsigned int *)&lock->Ptr, (SRWLOCK_RES_SHARED
|
||||
+ - SRWLOCK_RES_EXCLUSIVE) ) - SRWLOCK_RES_EXCLUSIVE;
|
||||
+ srwlock_leave_exclusive( lock, val );
|
||||
+ }
|
||||
+
|
||||
+ if (val & SRWLOCK_MASK_EXCLUSIVE_QUEUE)
|
||||
+ NtWaitForKeyedEvent( keyed_event, srwlock_key_shared(lock), FALSE, NULL );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1411,7 +1520,8 @@ void WINAPI RtlAcquireSRWLockShared( RTL_SRWLOCK *lock )
|
||||
*/
|
||||
void WINAPI RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
{
|
||||
- FIXME( "%p stub\n", lock );
|
||||
+ srwlock_leave_exclusive( lock, srwlock_unlock_exclusive( (unsigned int *)&lock->Ptr,
|
||||
+ - SRWLOCK_RES_EXCLUSIVE ) - SRWLOCK_RES_EXCLUSIVE );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -1419,7 +1529,8 @@ void WINAPI RtlReleaseSRWLockExclusive( RTL_SRWLOCK *lock )
|
||||
*/
|
||||
void WINAPI RtlReleaseSRWLockShared( RTL_SRWLOCK *lock )
|
||||
{
|
||||
- FIXME( "%p stub\n", lock );
|
||||
+ srwlock_leave_shared( lock, srwlock_lock_exclusive( (unsigned int *)&lock->Ptr,
|
||||
+ - SRWLOCK_RES_SHARED ) - SRWLOCK_RES_SHARED );
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
--
|
||||
1.7.9.5
|
||||
|
@ -0,0 +1,3 @@
|
||||
Revision: 1
|
||||
Author: Sebastian Lackner
|
||||
Title: Implementation of SRWLock functions.
|
@ -0,0 +1,126 @@
|
||||
From 549999ab13d6078b39210a467753e8b8dfff705e Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 17 Jan 2014 01:19:41 +0100
|
||||
Subject: shlwapi/tests: Add additional tests for UrlCombine and
|
||||
UrlCanonicalize
|
||||
|
||||
---
|
||||
dlls/shlwapi/tests/url.c | 46 ++++++++++++++++++++++++++++++++++++----------
|
||||
1 file changed, 36 insertions(+), 10 deletions(-)
|
||||
|
||||
diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c
|
||||
index f53a545..ecbdfab 100644
|
||||
--- a/dlls/shlwapi/tests/url.c
|
||||
+++ b/dlls/shlwapi/tests/url.c
|
||||
@@ -195,7 +195,15 @@ static const TEST_URL_CANONICALIZE TEST_CANONICALIZE[] = {
|
||||
{"res://c:\\tests/res\\foo%20bar/strange\\sth", URL_UNESCAPE, S_OK, "res://c:\\tests/res\\foo bar/strange\\sth", FALSE},
|
||||
{"A", 0, S_OK, "A", FALSE},
|
||||
{"../A", 0, S_OK, "../A", FALSE},
|
||||
+ {".\\A", 0, S_OK, ".\\A", FALSE},
|
||||
+ {"A\\.\\B", 0, S_OK, "A\\.\\B", FALSE},
|
||||
{"A/../B", 0, S_OK, "B", TRUE},
|
||||
+ {"A/../B/./../C", 0, S_OK, "C", TRUE},
|
||||
+ {"A/../B/./../C", URL_DONT_SIMPLIFY, S_OK, "A/../B/./../C", FALSE},
|
||||
+ {".", 0, S_OK, "/", TRUE},
|
||||
+ {"./A", 0, S_OK, "A", TRUE},
|
||||
+ {"A/./B", 0, S_OK, "A/B", TRUE},
|
||||
+ {"/:test\\", 0, S_OK, "/:test\\", TRUE},
|
||||
{"/uri-res/N2R?urn:sha1:B3K", URL_DONT_ESCAPE_EXTRA_INFO | URL_WININET_COMPATIBILITY /*0x82000000*/, S_OK, "/uri-res/N2R?urn:sha1:B3K", FALSE} /*LimeWire online installer calls this*/,
|
||||
{"http:www.winehq.org/dir/../index.html", 0, S_OK, "http:www.winehq.org/index.html"},
|
||||
{"http://localhost/test.html", URL_FILE_USE_PATHURL, S_OK, "http://localhost/test.html"},
|
||||
@@ -308,6 +316,7 @@ typedef struct _TEST_URL_COMBINE {
|
||||
DWORD flags;
|
||||
HRESULT expectret;
|
||||
const char *expecturl;
|
||||
+ BOOL todo;
|
||||
} TEST_URL_COMBINE;
|
||||
|
||||
static const TEST_URL_COMBINE TEST_COMBINE[] = {
|
||||
@@ -329,6 +338,15 @@ static const TEST_URL_COMBINE TEST_COMBINE[] = {
|
||||
{"http://www.winehq.org/test14#aaa/bbb#ccc", "#", 0, S_OK, "http://www.winehq.org/test14#"},
|
||||
{"http://www.winehq.org/tests/?query=x/y/z", "tests15", 0, S_OK, "http://www.winehq.org/tests/tests15"},
|
||||
{"http://www.winehq.org/tests/?query=x/y/z#example", "tests16", 0, S_OK, "http://www.winehq.org/tests/tests16"},
|
||||
+ {"http://www.winehq.org/tests17", ".", 0, S_OK, "http://www.winehq.org/", TRUE},
|
||||
+ {"http://www.winehq.org/tests18/test", ".", 0, S_OK, "http://www.winehq.org/tests18/", TRUE},
|
||||
+ {"http://www.winehq.org/tests19/test", "./", 0, S_OK, "http://www.winehq.org/tests19/", FALSE},
|
||||
+ {"http://www.winehq.org/tests20/test", "/", 0, S_OK, "http://www.winehq.org/", FALSE},
|
||||
+ {"http://www.winehq.org/tests/test", "./test21", 0, S_OK, "http://www.winehq.org/tests/test21", FALSE},
|
||||
+ {"http://www.winehq.org/tests/test", "./test22/../test", 0, S_OK, "http://www.winehq.org/tests/test", FALSE},
|
||||
+ {"http://www.winehq.org/tests/", "http://www.winehq.org:80/tests23", 0, S_OK, "http://www.winehq.org/tests23", TRUE},
|
||||
+ {"http://www.winehq.org/tests/", "tests24/./test/../test", 0, S_OK, "http://www.winehq.org/tests/tests24/test", FALSE},
|
||||
+ {"http://www.winehq.org/tests/./tests25", "./", 0, S_OK, "http://www.winehq.org/tests/", FALSE},
|
||||
{"file:///C:\\dir\\file.txt", "test.txt", 0, S_OK, "file:///C:/dir/test.txt"},
|
||||
{"file:///C:\\dir\\file.txt#hash\\hash", "test.txt", 0, S_OK, "file:///C:/dir/file.txt#hash/test.txt"},
|
||||
{"file:///C:\\dir\\file.html#hash\\hash", "test.html", 0, S_OK, "file:///C:/dir/test.html"},
|
||||
@@ -1077,7 +1095,7 @@ static void test_UrlCanonicalizeW(void)
|
||||
|
||||
/* ########################### */
|
||||
|
||||
-static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl)
|
||||
+static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFlags, HRESULT dwExpectReturn, const char *szExpectUrl, BOOL todo)
|
||||
{
|
||||
HRESULT hr;
|
||||
CHAR szReturnUrl[INTERNET_MAX_URL_LENGTH];
|
||||
@@ -1102,34 +1120,42 @@ static void test_url_combine(const char *szUrl1, const char *szUrl2, DWORD dwFla
|
||||
dwSize = 0;
|
||||
hr = pUrlCombineA(szUrl1, szUrl2, NULL, &dwSize, dwFlags);
|
||||
ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER);
|
||||
- ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
|
||||
+ ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
|
||||
|
||||
dwSize--;
|
||||
hr = pUrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
|
||||
ok(hr == E_POINTER, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, E_POINTER);
|
||||
- ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
|
||||
+ ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
|
||||
|
||||
hr = pUrlCombineA(szUrl1, szUrl2, szReturnUrl, &dwSize, dwFlags);
|
||||
ok(hr == dwExpectReturn, "UrlCombineA returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn);
|
||||
- ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
|
||||
- if(SUCCEEDED(hr)) {
|
||||
- ok(strcmp(szReturnUrl,szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
|
||||
+
|
||||
+ if (todo)
|
||||
+ {
|
||||
+ todo_wine ok(dwSize == dwExpectLen && (!SUCCEEDED(hr) || strcmp(szReturnUrl, szExpectUrl)==0),
|
||||
+ "Expected %s (len=%d), but got %s (len=%d)\n", szExpectUrl, dwExpectLen, SUCCEEDED(hr) ? szReturnUrl : "(null)", dwSize);
|
||||
+ }
|
||||
+ else
|
||||
+ {
|
||||
+ ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
|
||||
+ if (SUCCEEDED(hr))
|
||||
+ ok(strcmp(szReturnUrl, szExpectUrl)==0, "Expected %s, but got %s\n", szExpectUrl, szReturnUrl);
|
||||
}
|
||||
|
||||
if (pUrlCombineW) {
|
||||
dwSize = 0;
|
||||
hr = pUrlCombineW(wszUrl1, wszUrl2, NULL, &dwSize, dwFlags);
|
||||
ok(hr == E_POINTER, "Checking length of string, return was 0x%08x, expected 0x%08x\n", hr, E_POINTER);
|
||||
- ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
|
||||
+ ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
|
||||
|
||||
dwSize--;
|
||||
hr = pUrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
|
||||
ok(hr == E_POINTER, "UrlCombineW returned 0x%08x, expected 0x%08x\n", hr, E_POINTER);
|
||||
- ok(dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
|
||||
+ ok(todo || dwSize == dwExpectLen+1, "Got length %d, expected %d\n", dwSize, dwExpectLen+1);
|
||||
|
||||
hr = pUrlCombineW(wszUrl1, wszUrl2, wszReturnUrl, &dwSize, dwFlags);
|
||||
ok(hr == dwExpectReturn, "UrlCombineW returned 0x%08x, expected 0x%08x\n", hr, dwExpectReturn);
|
||||
- ok(dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
|
||||
+ ok(todo || dwSize == dwExpectLen, "Got length %d, expected %d\n", dwSize, dwExpectLen);
|
||||
if(SUCCEEDED(hr)) {
|
||||
wszConvertedUrl = GetWideString(szReturnUrl);
|
||||
ok(lstrcmpW(wszReturnUrl, wszConvertedUrl)==0, "Strings didn't match between ascii and unicode UrlCombine!\n");
|
||||
@@ -1149,7 +1175,7 @@ static void test_UrlCombine(void)
|
||||
unsigned int i;
|
||||
for(i=0; i<sizeof(TEST_COMBINE)/sizeof(TEST_COMBINE[0]); i++) {
|
||||
test_url_combine(TEST_COMBINE[i].url1, TEST_COMBINE[i].url2, TEST_COMBINE[i].flags,
|
||||
- TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl);
|
||||
+ TEST_COMBINE[i].expectret, TEST_COMBINE[i].expecturl, TEST_COMBINE[i].todo);
|
||||
}
|
||||
}
|
||||
|
||||
--
|
||||
1.7.9.5
|
||||
|
@ -0,0 +1,44 @@
|
||||
From 2f01abc1d6018646cdaa94e087b1a0444c31a0c7 Mon Sep 17 00:00:00 2001
|
||||
From: Sebastian Lackner <sebastian@fds-team.de>
|
||||
Date: Fri, 17 Jan 2014 01:27:53 +0100
|
||||
Subject: shlwapi: UrlCombineW workaround for relative paths
|
||||
|
||||
---
|
||||
dlls/shlwapi/tests/url.c | 4 ++--
|
||||
dlls/shlwapi/url.c | 5 ++++-
|
||||
2 files changed, 6 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/dlls/shlwapi/tests/url.c b/dlls/shlwapi/tests/url.c
|
||||
index ecbdfab..8a99f7e 100644
|
||||
--- a/dlls/shlwapi/tests/url.c
|
||||
+++ b/dlls/shlwapi/tests/url.c
|
||||
@@ -338,8 +338,8 @@ static const TEST_URL_COMBINE TEST_COMBINE[] = {
|
||||
{"http://www.winehq.org/test14#aaa/bbb#ccc", "#", 0, S_OK, "http://www.winehq.org/test14#"},
|
||||
{"http://www.winehq.org/tests/?query=x/y/z", "tests15", 0, S_OK, "http://www.winehq.org/tests/tests15"},
|
||||
{"http://www.winehq.org/tests/?query=x/y/z#example", "tests16", 0, S_OK, "http://www.winehq.org/tests/tests16"},
|
||||
- {"http://www.winehq.org/tests17", ".", 0, S_OK, "http://www.winehq.org/", TRUE},
|
||||
- {"http://www.winehq.org/tests18/test", ".", 0, S_OK, "http://www.winehq.org/tests18/", TRUE},
|
||||
+ {"http://www.winehq.org/tests17", ".", 0, S_OK, "http://www.winehq.org/"},
|
||||
+ {"http://www.winehq.org/tests18/test", ".", 0, S_OK, "http://www.winehq.org/tests18/"},
|
||||
{"http://www.winehq.org/tests19/test", "./", 0, S_OK, "http://www.winehq.org/tests19/", FALSE},
|
||||
{"http://www.winehq.org/tests20/test", "/", 0, S_OK, "http://www.winehq.org/", FALSE},
|
||||
{"http://www.winehq.org/tests/test", "./test21", 0, S_OK, "http://www.winehq.org/tests/test21", FALSE},
|
||||
diff --git a/dlls/shlwapi/url.c b/dlls/shlwapi/url.c
|
||||
index 11589e4..58eb87c 100644
|
||||
--- a/dlls/shlwapi/url.c
|
||||
+++ b/dlls/shlwapi/url.c
|
||||
@@ -914,7 +914,10 @@ HRESULT WINAPI UrlCombineW(LPCWSTR pszBase, LPCWSTR pszRelative,
|
||||
work = preliminary + base.cchProtocol+1+base.cchSuffix - 1;
|
||||
if (*work++ != '/')
|
||||
*(work++) = '/';
|
||||
- strcpyW(work, relative.pszSuffix);
|
||||
+ if (relative.pszSuffix[0] == '.' && relative.pszSuffix[1] == 0)
|
||||
+ *work = 0;
|
||||
+ else
|
||||
+ strcpyW(work, relative.pszSuffix);
|
||||
break;
|
||||
|
||||
default:
|
||||
--
|
||||
1.7.9.5
|
||||
|
@ -0,0 +1,3 @@
|
||||
Revision: 1
|
||||
Author: Sebastian Lackner
|
||||
Title: Workaround for broken implementation of shlwapi url functions.
|
@ -33,7 +33,7 @@ diff --git a/libs/wine/config.c b/libs/wine/config.c
|
||||
index a273502..5fa0cd5 100644
|
||||
--- a/libs/wine/config.c
|
||||
+++ b/libs/wine/config.c
|
||||
@@ -478,6 +478,32 @@ const char *wine_get_version(void)
|
||||
@@ -478,6 +478,34 @@ const char *wine_get_version(void)
|
||||
return PACKAGE_VERSION;
|
||||
}
|
||||
|
||||
@ -50,10 +50,12 @@ index a273502..5fa0cd5 100644
|
||||
+ { "cbe240e8-2c58-430a-b61c-7fbb9d0e1e11:1", "Sebastian Lackner", "Change return value of stub SetNamedPipeHandleState to TRUE." },
|
||||
+ { "00273da7-72f8-4025-9e96-0c2bc95dacdb:2", "Maarten Lankhorst", "Winepulse patches extracted from https://launchpad.net/~mlankhorst/+archive/ppa/+files/wine1.7_1.7.10-0ubuntu1~saucy1.debian.tar.gz." },
|
||||
+ { "29b2af38-7edd-11e3-a08d-0090f5c75ad5:1", "Erich E. Hoover", "Add support for security access parameters for named pipes." },
|
||||
+ { "17545d49-1dfc-4294-bb30-2df2f29b0d95:1", "Sebastian Lackner", "Implementation of SRWLock functions." },
|
||||
+ { "0b21d7ac-0387-4493-aa38-fbafe3e749f5:1", "Michael Müller", "Decrease minimum SetTimer interval from 15 to 5 ms." },
|
||||
+ { "19835498-8d90-4673-867e-2376af4d7c76:1", "Sebastian Lackner", "Allow to set wined3d strictDrawOrdering via environment variable." },
|
||||
+ { "59bd38b7-bbdc-4cfd-9ccd-1c72c4ed84c0:1", "Sebastian Lackner", "Implement X11DRV_FLUSH_GDI_DISPLAY ExtEscape command." },
|
||||
+ { "eec5dea8-879d-417b-9f97-364deaae6576:1", "Sebastian Lackner", "Add tests for IVMRMonitorConfig." },
|
||||
+ { "e46b26df-3c1b-419c-9579-f0d1e1c50bea:1", "Sebastian Lackner", "Workaround for broken implementation of shlwapi url functions." },
|
||||
+ { NULL, NULL, NULL }
|
||||
+};
|
||||
+
|
||||
|
Loading…
Reference in New Issue
Block a user