Rebase against 00b08fad99745db326ef060627c3e9dc668a734a

This commit is contained in:
Alistair Leslie-Hughes 2018-11-28 09:19:40 +11:00
parent 7d49250016
commit c30bad1531
13 changed files with 46 additions and 1380 deletions

View File

@ -1,4 +1,4 @@
From 926d6492812bd4753109f8e4525d84d8105ab5fb Mon Sep 17 00:00:00 2001
From f6d4e6e5fe2d789d5ce21a99daf3a1864d883544 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Mon, 12 Jun 2017 00:16:08 +0200
Subject: [PATCH] loader: Implement preloader for Mac OS.
@ -9,35 +9,35 @@ Subject: [PATCH] loader: Implement preloader for Mac OS.
dlls/ntdll/virtual.c | 2 -
libs/wine/config.c | 2 +-
loader/Makefile.in | 4 +-
loader/main.c | 44 +----
loader/preloader.c | 468 +++++++++++++++++++++++++++++++++++++++++++++++++--
loader/main.c | 44 +---
loader/preloader.c | 468 ++++++++++++++++++++++++++++++++++++++++++-
7 files changed, 491 insertions(+), 53 deletions(-)
diff --git a/Makefile.in b/Makefile.in
index 6f1af8c..397ff16 100644
index 13b5a5a0536..c55655b87c0 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -90,6 +90,7 @@ WINELOADER_PROGRAMS = @WINELOADER_PROGRAMS@
@@ -87,6 +87,7 @@ conf_manext = 5
WINELOADER_PROGRAMS = @WINELOADER_PROGRAMS@
WINELOADER_DEPENDS = @WINELOADER_DEPENDS@
WINELOADER_INSTALL = @WINELOADER_INSTALL@
WINELOADER_LDFLAGS = @WINELOADER_LDFLAGS@
+WINEPRELOADER_LDFLAGS = @WINEPRELOADER_LDFLAGS@
LIBWINE_SHAREDLIB = @LIBWINE_SHAREDLIB@
LIBWINE_IMPORTLIB = @LIBWINE_IMPORTLIB@
LIBWINE_INSTALL_LIB = @LIBWINE_INSTALL_LIB@
LIBWINE_LDFLAGS = @LIBWINE_LDFLAGS@
diff --git a/configure.ac b/configure.ac
index fc79b7a..40dcc70 100644
index 73953cbb980..d8130ec3b87 100644
--- a/configure.ac
+++ b/configure.ac
@@ -707,6 +707,7 @@ AC_SUBST(LDRPATH_INSTALL,"")
AC_SUBST(LDRPATH_LOCAL,"")
AC_SUBST(LDEXECFLAGS,"")
@@ -724,6 +724,7 @@ AC_SUBST(LDEXECFLAGS,"")
AC_SUBST(TOP_INSTALL_LIB,"")
AC_SUBST(TOP_INSTALL_DEV,"")
AC_SUBST(WINELOADER_LDFLAGS,"")
+AC_SUBST(WINEPRELOADER_LDFLAGS,"")
LIBEXT="so"
DLLEXT=".so"
IMPLIBEXT="def"
@@ -765,9 +766,17 @@ case $host_os in
@@ -784,9 +785,17 @@ case $host_os in
AC_SUBST(APPLICATIONSERVICES_LIBS,"-framework ApplicationServices")
AC_SUBST(CORESERVICES_LIBS,"-framework CoreServices")
AC_SUBST(APPKIT_LIBS,"-framework AppKit")
@ -57,7 +57,7 @@ index fc79b7a..40dcc70 100644
if test "$ac_cv_header_DiskArbitration_DiskArbitration_h" = "yes"
then
dnl DiskArbitration API is not public on Darwin < 8.0, use it only if header found
@@ -880,6 +889,7 @@ case $host_os in
@@ -902,6 +911,7 @@ case $host_os in
enable_wineandroid_drv=${enable_wineandroid_drv:-yes}
WINE_TRY_CFLAGS([-fPIC -Wl,--export-dynamic],
[WINELOADER_LDFLAGS="-Wl,--export-dynamic"])
@ -65,7 +65,7 @@ index fc79b7a..40dcc70 100644
WINE_TRY_CFLAGS([-fPIC -Wl,--rpath,\$ORIGIN/../lib],
[LDRPATH_INSTALL="-Wl,--rpath,\\\$\$ORIGIN/\`\$(MAKEDEP) -R \${bindir} \${libdir}\`"
LDRPATH_LOCAL="-Wl,--rpath,\\\$\$ORIGIN/\$(top_builddir)/libs/wine"],
@@ -927,6 +937,7 @@ case $host_os in
@@ -949,6 +959,7 @@ case $host_os in
WINE_TRY_CFLAGS([-fPIC -Wl,--export-dynamic],
[WINELOADER_LDFLAGS="-Wl,--export-dynamic"])
@ -73,7 +73,7 @@ index fc79b7a..40dcc70 100644
WINE_TRY_CFLAGS([-fPIC -Wl,--rpath,\$ORIGIN/../lib],
[LDRPATH_INSTALL="-Wl,--rpath,\\\$\$ORIGIN/\`\$(MAKEDEP) -R \${bindir} \${libdir}\`:\$(DESTDIR)\${libdir}"
@@ -2089,6 +2100,14 @@ case $host_os in
@@ -2143,6 +2154,14 @@ case $host_os in
;;
esac
;;
@ -89,7 +89,7 @@ index fc79b7a..40dcc70 100644
dnl **** Check for functions ****
diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c
index 6efdf5a..8303a03 100644
index 7713869fe45..b200d0df7f8 100644
--- a/dlls/ntdll/virtual.c
+++ b/dlls/ntdll/virtual.c
@@ -2424,11 +2424,9 @@ void virtual_release_address_space(void)
@ -105,7 +105,7 @@ index 6efdf5a..8303a03 100644
server_leave_uninterrupted_section( &csVirtual, &sigset );
diff --git a/libs/wine/config.c b/libs/wine/config.c
index 45a7c48..cba4224 100644
index 45a7c483ab5..cba4224f537 100644
--- a/libs/wine/config.c
+++ b/libs/wine/config.c
@@ -678,7 +678,7 @@ void wine_exec_wine_binary( const char *name, char **argv, const char *env_var )
@ -118,10 +118,10 @@ index 45a7c48..cba4224 100644
#else
use_preloader = 0;
diff --git a/loader/Makefile.in b/loader/Makefile.in
index 4fb91ff..b715f02 100644
index bbb1b953391..90e322bd749 100644
--- a/loader/Makefile.in
+++ b/loader/Makefile.in
@@ -26,7 +26,7 @@ wine64_DEPS = $(WINELOADER_DEPENDS)
@@ -24,7 +24,7 @@ wine64_DEPS = $(WINELOADER_DEPENDS)
wine64_LDFLAGS = $(WINELOADER_LDFLAGS) $(LDEXECFLAGS) -lwine $(PTHREAD_LIBS)
wine_preloader_OBJS = preloader.o
@ -132,7 +132,7 @@ index 4fb91ff..b715f02 100644
-wine64_preloader_LDFLAGS = -static -nostartfiles -nodefaultlibs -Wl,-Ttext=0x7c400000
+wine64_preloader_LDFLAGS = $(WINEPRELOADER_LDFLAGS)
diff --git a/loader/main.c b/loader/main.c
index 39d26e6..da32fc9 100644
index 39d26e61ca3..da32fc903e6 100644
--- a/loader/main.c
+++ b/loader/main.c
@@ -50,30 +50,6 @@
@ -215,7 +215,7 @@ index 39d26e6..da32fc9 100644
wine_init( argc, argv, error, sizeof(error) );
diff --git a/loader/preloader.c b/loader/preloader.c
index 725926e..d2f8dc15 100644
index 644244bc30f..f69a43955a8 100644
--- a/loader/preloader.c
+++ b/loader/preloader.c
@@ -4,6 +4,8 @@
@ -525,7 +525,7 @@ index 725926e..d2f8dc15 100644
#ifdef __i386__
/* data for setting up the glibc-style thread-local storage in %gs */
@@ -564,16 +804,17 @@ SYSCALL_NOERR( wld_getegid, 177 /* SYS_getegid */ );
@@ -536,16 +776,17 @@ SYSCALL_NOERR( wld_getegid, 177 /* SYS_getegid */ );
#else
#error preloader not implemented for this CPU
#endif
@ -545,7 +545,7 @@ index 725926e..d2f8dc15 100644
{
if (len <= 0) return 0;
while ((--len > 0) && *str1 && (*str1 == *str2)) { str1++; str2++; }
@@ -666,6 +907,8 @@ static __attribute__((noreturn,format(printf,1,2))) void fatal_error(const char
@@ -638,6 +879,8 @@ static __attribute__((noreturn,format(printf,1,2))) void fatal_error(const char
wld_exit(1);
}
@ -554,7 +554,7 @@ index 725926e..d2f8dc15 100644
#ifdef DUMP_AUX_INFO
/*
* Dump interesting bits of the ELF auxv_t structure that is passed
@@ -1148,6 +1391,8 @@ found:
@@ -1120,6 +1363,8 @@ found:
return (void *)(symtab[idx].st_value + map->l_addr);
}
@ -563,7 +563,7 @@ index 725926e..d2f8dc15 100644
/*
* preload_reserve
*
@@ -1179,6 +1424,7 @@ static void preload_reserve( const char *str )
@@ -1151,6 +1396,7 @@ static void preload_reserve( const char *str )
/* sanity checks */
if (end <= start) start = end = NULL;
@ -571,7 +571,7 @@ index 725926e..d2f8dc15 100644
else if ((char *)end > preloader_start &&
(char *)start <= preloader_end)
{
@@ -1186,6 +1432,7 @@ static void preload_reserve( const char *str )
@@ -1158,6 +1404,7 @@ static void preload_reserve( const char *str )
start, end, preloader_start, preloader_end );
start = end = NULL;
}
@ -579,7 +579,7 @@ index 725926e..d2f8dc15 100644
/* check for overlap with low memory areas */
for (i = 0; preload_info[i].size; i++)
@@ -1210,7 +1457,7 @@ error:
@@ -1182,7 +1429,7 @@ error:
}
/* check if address is in one of the reserved ranges */
@ -588,7 +588,7 @@ index 725926e..d2f8dc15 100644
{
int i;
@@ -1234,6 +1481,203 @@ static void remove_preload_range( int i )
@@ -1206,6 +1453,203 @@ static void remove_preload_range( int i )
}
}
@ -792,12 +792,12 @@ index 725926e..d2f8dc15 100644
/*
* is_in_preload_range
*
@@ -1406,3 +1850,5 @@ void* wld_start( void **stack )
@@ -1374,3 +1818,5 @@ void* wld_start( void **stack )
return (void *)ld_so_map.l_entry;
}
+
+#endif /* __APPLE__ */
--
1.9.1
2.19.2

View File

@ -1,62 +0,0 @@
From c5f36ac202c20faa00fc67c9d1cdc977ce877933 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Sun, 19 Aug 2018 17:42:12 -0500
Subject: [PATCH 05/17] ntoskrnl.exe: Implement KeClearEvent().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 8 --------
dlls/ntoskrnl.exe/sync.c | 8 ++++++++
include/ddk/wdm.h | 1 +
3 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 99fa910..646c528 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -3730,14 +3730,6 @@ NTSTATUS WINAPI IoCreateFile(HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBUT
}
/***********************************************************************
- * KeClearEvent (NTOSKRNL.EXE.@)
- */
-VOID WINAPI KeClearEvent(PRKEVENT event)
-{
- FIXME("stub: %p\n", event);
-}
-
-/***********************************************************************
* KeAcquireInStackQueuedSpinLock (NTOSKRNL.EXE.@)
*/
#ifdef DEFINE_FASTCALL2_ENTRYPOINT
diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c
index f011a60..a905fb3 100644
--- a/dlls/ntoskrnl.exe/sync.c
+++ b/dlls/ntoskrnl.exe/sync.c
@@ -165,3 +165,11 @@ LONG WINAPI KeResetEvent( PRKEVENT event )
return ret;
}
+
+/***********************************************************************
+ * KeClearEvent (NTOSKRNL.EXE.@)
+ */
+void WINAPI KeClearEvent( PRKEVENT event )
+{
+ KeResetEvent( event );
+}
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 350a08e..0fe73f2 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1418,6 +1418,7 @@ void WINAPI IoReleaseCancelSpinLock(KIRQL);
NTSTATUS WINAPI IoSetDeviceInterfaceState(UNICODE_STRING*,BOOLEAN);
NTSTATUS WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT,ULONG);
+void WINAPI KeClearEvent(PRKEVENT);
PKTHREAD WINAPI KeGetCurrentThread(void);
void WINAPI KeInitializeEvent(PRKEVENT,EVENT_TYPE,BOOLEAN);
void WINAPI KeInitializeSemaphore(PRKSEMAPHORE,LONG,LONG);
--
2.7.4

View File

@ -1,64 +0,0 @@
From 26324192918d2d16d92978abebed83d63c7ffc3f Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Sun, 19 Aug 2018 20:22:29 -0500
Subject: [PATCH 08/17] ntoskrnl.exe: Implement KeInitializeSemaphore().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 9 ---------
dlls/ntoskrnl.exe/sync.c | 15 +++++++++++++++
2 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 3002d4e..db8af82 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2116,15 +2116,6 @@ LONG WINAPI KeReleaseMutex(PRKMUTEX Mutex, BOOLEAN Wait)
/***********************************************************************
- * KeInitializeSemaphore (NTOSKRNL.EXE.@)
- */
-void WINAPI KeInitializeSemaphore( PRKSEMAPHORE Semaphore, LONG Count, LONG Limit )
-{
- FIXME( "(%p %d %d) stub\n", Semaphore , Count, Limit );
-}
-
-
-/***********************************************************************
* KeInitializeSpinLock (NTOSKRNL.EXE.@)
*/
void WINAPI KeInitializeSpinLock( PKSPIN_LOCK SpinLock )
diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c
index 423fdcf..c072d36 100644
--- a/dlls/ntoskrnl.exe/sync.c
+++ b/dlls/ntoskrnl.exe/sync.c
@@ -38,6 +38,7 @@ enum object_type
{
TYPE_MANUAL_EVENT = 0,
TYPE_AUTO_EVENT = 1,
+ TYPE_SEMAPHORE = 5,
};
static CRITICAL_SECTION sync_cs;
@@ -182,3 +183,17 @@ void WINAPI KeClearEvent( PRKEVENT event )
{
KeResetEvent( event );
}
+
+/***********************************************************************
+ * KeInitializeSemaphore (NTOSKRNL.EXE.@)
+ */
+void WINAPI KeInitializeSemaphore( PRKSEMAPHORE semaphore, LONG count, LONG limit )
+{
+ TRACE("semaphore %p, count %d, limit %d.\n", semaphore, count, limit);
+
+ semaphore->Header.Type = TYPE_SEMAPHORE;
+ semaphore->Header.SignalState = count;
+ semaphore->Header.WaitListHead.Blink = NULL;
+ semaphore->Header.WaitListHead.Flink = NULL;
+ semaphore->Limit = limit;
+}
--
2.7.4

View File

@ -1,176 +0,0 @@
From 503285d89d3c0d63331697d6e87d0b225d2ccb05 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Sun, 19 Aug 2018 20:45:54 -0500
Subject: [PATCH 09/17] ntoskrnl.exe: Implement KeReleaseSemaphore() and
waiting on semaphores.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 11 -------
dlls/ntoskrnl.exe/sync.c | 31 +++++++++++++++++++
dlls/ntoskrnl.exe/tests/driver.c | 64 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 95 insertions(+), 11 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index db8af82..b367323 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2209,17 +2209,6 @@ void WINAPI KeQueryTickCount( LARGE_INTEGER *count )
/***********************************************************************
- * KeReleaseSemaphore (NTOSKRNL.EXE.@)
- */
-LONG WINAPI KeReleaseSemaphore( PRKSEMAPHORE Semaphore, KPRIORITY Increment,
- LONG Adjustment, BOOLEAN Wait )
-{
- FIXME("(%p %d %d %d) stub\n", Semaphore, Increment, Adjustment, Wait );
- return 0;
-}
-
-
-/***********************************************************************
* KeQueryTimeIncrement (NTOSKRNL.EXE.@)
*/
ULONG WINAPI KeQueryTimeIncrement(void)
diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c
index c072d36..30160f7 100644
--- a/dlls/ntoskrnl.exe/sync.c
+++ b/dlls/ntoskrnl.exe/sync.c
@@ -83,6 +83,13 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
case TYPE_AUTO_EVENT:
objs[i]->WaitListHead.Blink = CreateEventW( NULL, FALSE, objs[i]->SignalState, NULL );
break;
+ case TYPE_SEMAPHORE:
+ {
+ KSEMAPHORE *semaphore = CONTAINING_RECORD(objs[i], KSEMAPHORE, Header);
+ objs[i]->WaitListHead.Blink = CreateSemaphoreW( NULL,
+ semaphore->Header.SignalState, semaphore->Limit, NULL );
+ break;
+ }
}
}
@@ -102,6 +109,9 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
case TYPE_AUTO_EVENT:
objs[i]->SignalState = FALSE;
break;
+ case TYPE_SEMAPHORE:
+ --objs[i]->SignalState;
+ break;
}
}
@@ -197,3 +207,24 @@ void WINAPI KeInitializeSemaphore( PRKSEMAPHORE semaphore, LONG count, LONG limi
semaphore->Header.WaitListHead.Flink = NULL;
semaphore->Limit = limit;
}
+
+/***********************************************************************
+ * KeReleaseSemaphore (NTOSKRNL.EXE.@)
+ */
+LONG WINAPI KeReleaseSemaphore( PRKSEMAPHORE semaphore, KPRIORITY increment,
+ LONG count, BOOLEAN wait )
+{
+ HANDLE handle = semaphore->Header.WaitListHead.Blink;
+ LONG ret;
+
+ TRACE("semaphore %p, increment %d, count %d, wait %u.\n",
+ semaphore, increment, count, wait);
+
+ EnterCriticalSection( &sync_cs );
+ ret = interlocked_xchg_add( &semaphore->Header.SignalState, count );
+ if (handle)
+ ReleaseSemaphore( handle, count, NULL );
+ LeaveCriticalSection( &sync_cs );
+
+ return ret;
+}
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index 07a0adb..852a726 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -228,9 +228,11 @@ static NTSTATUS wait_multiple(ULONG count, void *objs[], WAIT_TYPE wait_type, UL
static void test_sync(void)
{
+ KSEMAPHORE semaphore, semaphore2;
KEVENT manual_event, auto_event;
void *objs[2];
NTSTATUS ret;
+ int i;
KeInitializeEvent(&manual_event, NotificationEvent, FALSE);
@@ -323,6 +325,68 @@ static void test_sync(void)
ret = wait_multiple(2, objs, WaitAny, 0);
ok(ret == 1, "got %#x\n", ret);
+
+ /* test semaphores */
+ KeInitializeSemaphore(&semaphore, 0, 5);
+
+ ret = wait_single(&semaphore, 0);
+ ok(ret == STATUS_TIMEOUT, "got %u\n", ret);
+
+ ret = KeReleaseSemaphore(&semaphore, 0, 1, FALSE);
+ ok(ret == 0, "got prev %d\n", ret);
+
+ ret = KeReleaseSemaphore(&semaphore, 0, 2, FALSE);
+ ok(ret == 1, "got prev %d\n", ret);
+
+ ret = KeReleaseSemaphore(&semaphore, 0, 1, FALSE);
+ ok(ret == 3, "got prev %d\n", ret);
+
+ for (i = 0; i < 4; i++)
+ {
+ ret = wait_single(&semaphore, 0);
+ ok(ret == 0, "got %#x\n", ret);
+ }
+
+ ret = wait_single(&semaphore, 0);
+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
+
+ KeInitializeSemaphore(&semaphore2, 3, 5);
+
+ ret = KeReleaseSemaphore(&semaphore2, 0, 1, FALSE);
+ ok(ret == 3, "got prev %d\n", ret);
+
+ for (i = 0; i < 4; i++)
+ {
+ ret = wait_single(&semaphore2, 0);
+ ok(ret == 0, "got %#x\n", ret);
+ }
+
+ objs[0] = &semaphore;
+ objs[1] = &semaphore2;
+
+ ret = wait_multiple(2, objs, WaitAny, 0);
+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
+
+ KeReleaseSemaphore(&semaphore, 0, 1, FALSE);
+ KeReleaseSemaphore(&semaphore2, 0, 1, FALSE);
+
+ ret = wait_multiple(2, objs, WaitAny, 0);
+ ok(ret == 0, "got %#x\n", ret);
+
+ ret = wait_multiple(2, objs, WaitAny, 0);
+ ok(ret == 1, "got %#x\n", ret);
+
+ ret = wait_multiple(2, objs, WaitAny, 0);
+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
+
+ KeReleaseSemaphore(&semaphore, 0, 1, FALSE);
+ KeReleaseSemaphore(&semaphore2, 0, 1, FALSE);
+
+ ret = wait_multiple(2, objs, WaitAll, 0);
+ ok(ret == 0, "got %#x\n", ret);
+
+ ret = wait_multiple(2, objs, WaitAny, 0);
+ ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
}
static NTSTATUS main_test(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
--
2.7.4

View File

@ -1,76 +0,0 @@
From 07bc793086700ec42b25667e3e019a616ed13723 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Sun, 19 Aug 2018 21:24:51 -0500
Subject: [PATCH 10/17] ntoskrnl.exe: Implement KeInitializeMutex().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 9 ---------
dlls/ntoskrnl.exe/sync.c | 14 ++++++++++++++
include/ddk/wdm.h | 1 +
3 files changed, 15 insertions(+), 9 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index b367323..920fb74 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2086,15 +2086,6 @@ PRKTHREAD WINAPI KeGetCurrentThread(void)
}
/***********************************************************************
- * KeInitializeMutex (NTOSKRNL.EXE.@)
- */
-void WINAPI KeInitializeMutex(PRKMUTEX Mutex, ULONG Level)
-{
- FIXME( "stub: %p, %u\n", Mutex, Level );
-}
-
-
- /***********************************************************************
* KeWaitForMutexObject (NTOSKRNL.EXE.@)
*/
NTSTATUS WINAPI KeWaitForMutexObject(PRKMUTEX Mutex, KWAIT_REASON WaitReason, KPROCESSOR_MODE WaitMode,
diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c
index 30160f7..7535ae8 100644
--- a/dlls/ntoskrnl.exe/sync.c
+++ b/dlls/ntoskrnl.exe/sync.c
@@ -38,6 +38,7 @@ enum object_type
{
TYPE_MANUAL_EVENT = 0,
TYPE_AUTO_EVENT = 1,
+ TYPE_MUTEX = 2,
TYPE_SEMAPHORE = 5,
};
@@ -228,3 +229,16 @@ LONG WINAPI KeReleaseSemaphore( PRKSEMAPHORE semaphore, KPRIORITY increment,
return ret;
}
+
+/***********************************************************************
+ * KeInitializeMutex (NTOSKRNL.EXE.@)
+ */
+void WINAPI KeInitializeMutex( PRKMUTEX mutex, ULONG level )
+{
+ TRACE("mutex %p, level %u.\n", mutex, level);
+
+ mutex->Header.Type = TYPE_MUTEX;
+ mutex->Header.SignalState = 1;
+ mutex->Header.WaitListHead.Blink = NULL;
+ mutex->Header.WaitListHead.Flink = NULL;
+}
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 6b6ac19..c8adc7d 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1421,6 +1421,7 @@ NTSTATUS WINAPI IoWMIRegistrationControl(PDEVICE_OBJECT,ULONG);
void WINAPI KeClearEvent(PRKEVENT);
PKTHREAD WINAPI KeGetCurrentThread(void);
void WINAPI KeInitializeEvent(PRKEVENT,EVENT_TYPE,BOOLEAN);
+void WINAPI KeInitializeMutex(PRKMUTEX,ULONG);
void WINAPI KeInitializeSemaphore(PRKSEMAPHORE,LONG,LONG);
void WINAPI KeInitializeTimerEx(PKTIMER,TIMER_TYPE);
void WINAPI KeQuerySystemTime(LARGE_INTEGER*);
--
2.7.4

View File

@ -1,214 +0,0 @@
From 7505150045f3ce4cd805e863913289156322b41d Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Sun, 19 Aug 2018 21:43:37 -0500
Subject: [PATCH 11/17] ntoskrnl.exe: Implement KeReleaseMutex() and waiting on
mutexes.
We can get away with storing the mutex object in the KMUTEX for as long as
it's held, since on Windows it's illegal to destroy a mutex until it's
released.
Setting the flag OBJ_KERNEL_HANDLE on okfile is necessary to allow it to be
written to by system threads.
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 10 -------
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +-
dlls/ntoskrnl.exe/sync.c | 44 ++++++++++++++++++++++++++--
dlls/ntoskrnl.exe/tests/driver.c | 58 +++++++++++++++++++++++++++++++++++++
4 files changed, 101 insertions(+), 13 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 920fb74..cc88100 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2096,16 +2096,6 @@ NTSTATUS WINAPI KeWaitForMutexObject(PRKMUTEX Mutex, KWAIT_REASON WaitReason, KP
}
- /***********************************************************************
- * KeReleaseMutex (NTOSKRNL.EXE.@)
- */
-LONG WINAPI KeReleaseMutex(PRKMUTEX Mutex, BOOLEAN Wait)
-{
- FIXME( "stub: %p, %d\n", Mutex, Wait );
- return STATUS_NOT_IMPLEMENTED;
-}
-
-
/***********************************************************************
* KeInitializeSpinLock (NTOSKRNL.EXE.@)
*/
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index 422d575..f089f41 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -1402,7 +1402,7 @@
@ stdcall -private ZwUnloadKey(ptr) NtUnloadKey
@ stdcall -private ZwUnmapViewOfSection(long ptr) NtUnmapViewOfSection
@ stdcall -private ZwWaitForMultipleObjects(long ptr long long ptr) NtWaitForMultipleObjects
-@ stdcall -private ZwWaitForSingleObject(long long ptr) NtWaitForSingleObject
+@ stdcall ZwWaitForSingleObject(long long ptr) NtWaitForSingleObject
@ stdcall ZwWriteFile(long long ptr ptr ptr ptr long ptr ptr) NtWriteFile
@ stdcall -private ZwYieldExecution() NtYieldExecution
@ stdcall -private -arch=arm,x86_64 -norelay __chkstk()
diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c
index 7535ae8..a038a07 100644
--- a/dlls/ntoskrnl.exe/sync.c
+++ b/dlls/ntoskrnl.exe/sync.c
@@ -84,6 +84,9 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
case TYPE_AUTO_EVENT:
objs[i]->WaitListHead.Blink = CreateEventW( NULL, FALSE, objs[i]->SignalState, NULL );
break;
+ case TYPE_MUTEX:
+ objs[i]->WaitListHead.Blink = CreateMutexW( NULL, FALSE, NULL );
+ break;
case TYPE_SEMAPHORE:
{
KSEMAPHORE *semaphore = CONTAINING_RECORD(objs[i], KSEMAPHORE, Header);
@@ -110,6 +113,7 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
case TYPE_AUTO_EVENT:
objs[i]->SignalState = FALSE;
break;
+ case TYPE_MUTEX:
case TYPE_SEMAPHORE:
--objs[i]->SignalState;
break;
@@ -118,8 +122,22 @@ NTSTATUS WINAPI KeWaitForMultipleObjects(ULONG count, void *pobjs[],
if (!--*((ULONG_PTR *)&objs[i]->WaitListHead.Flink))
{
- CloseHandle(objs[i]->WaitListHead.Blink);
- objs[i]->WaitListHead.Blink = NULL;
+ switch (objs[i]->Type)
+ {
+ case TYPE_MANUAL_EVENT:
+ case TYPE_AUTO_EVENT:
+ case TYPE_SEMAPHORE:
+ CloseHandle(objs[i]->WaitListHead.Blink);
+ objs[i]->WaitListHead.Blink = NULL;
+ break;
+ case TYPE_MUTEX:
+ if (objs[i]->SignalState == 1)
+ {
+ CloseHandle(objs[i]->WaitListHead.Blink);
+ objs[i]->WaitListHead.Blink = NULL;
+ }
+ break;
+ }
}
}
LeaveCriticalSection( &sync_cs );
@@ -242,3 +260,25 @@ void WINAPI KeInitializeMutex( PRKMUTEX mutex, ULONG level )
mutex->Header.WaitListHead.Blink = NULL;
mutex->Header.WaitListHead.Flink = NULL;
}
+
+/***********************************************************************
+ * KeReleaseMutex (NTOSKRNL.EXE.@)
+ */
+LONG WINAPI KeReleaseMutex( PRKMUTEX mutex, BOOLEAN wait )
+{
+ HANDLE handle = mutex->Header.WaitListHead.Blink;
+ LONG ret;
+
+ TRACE("mutex %p, wait %u.\n", mutex, wait);
+
+ EnterCriticalSection( &sync_cs );
+ ret = mutex->Header.SignalState++;
+ if (!ret && !mutex->Header.WaitListHead.Flink)
+ {
+ CloseHandle( handle );
+ mutex->Header.WaitListHead.Blink = NULL;
+ }
+ LeaveCriticalSection( &sync_cs );
+
+ return ret;
+}
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index 852a726..e758e3f 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -226,6 +226,36 @@ static NTSTATUS wait_multiple(ULONG count, void *objs[], WAIT_TYPE wait_type, UL
return KeWaitForMultipleObjects(count, objs, wait_type, Executive, KernelMode, FALSE, &integer, NULL);
}
+static void run_thread(PKSTART_ROUTINE proc, void *arg)
+{
+ OBJECT_ATTRIBUTES attr = {0};
+ HANDLE thread;
+ NTSTATUS ret;
+
+ attr.Length = sizeof(attr);
+ attr.Attributes = OBJ_KERNEL_HANDLE;
+ ret = PsCreateSystemThread(&thread, THREAD_ALL_ACCESS, &attr, NULL, NULL, proc, arg);
+ ok(!ret, "got %#x\n", ret);
+
+ ret = ZwWaitForSingleObject(thread, FALSE, NULL);
+ ok(!ret, "got %#x\n", ret);
+ ret = ZwClose(thread);
+ ok(!ret, "got %#x\n", ret);
+}
+
+static KMUTEX test_mutex;
+
+static void WINAPI mutex_thread(void *arg)
+{
+ NTSTATUS ret, expect = (NTSTATUS)(DWORD_PTR)arg;
+
+ ret = wait_single(&test_mutex, 0);
+ ok(ret == expect, "expected %#x, got %#x\n", expect, ret);
+
+ if (!ret) KeReleaseMutex(&test_mutex, FALSE);
+ PsTerminateSystemThread(STATUS_SUCCESS);
+}
+
static void test_sync(void)
{
KSEMAPHORE semaphore, semaphore2;
@@ -387,6 +417,33 @@ static void test_sync(void)
ret = wait_multiple(2, objs, WaitAny, 0);
ok(ret == STATUS_TIMEOUT, "got %#x\n", ret);
+
+ /* test mutexes */
+ KeInitializeMutex(&test_mutex, 0);
+
+ for (i = 0; i < 10; i++)
+ {
+ ret = wait_single(&test_mutex, 0);
+ ok(ret == 0, "got %#x\n", ret);
+ }
+
+ for (i = 0; i < 10; i++)
+ {
+ ret = KeReleaseMutex(&test_mutex, FALSE);
+ ok(ret == i - 9, "expected %d, got %d\n", i - 9, ret);
+ }
+
+ run_thread(mutex_thread, (void *)0);
+
+ ret = wait_single(&test_mutex, 0);
+ ok(ret == 0, "got %#x\n", ret);
+
+ run_thread(mutex_thread, (void *)STATUS_TIMEOUT);
+
+ ret = KeReleaseMutex(&test_mutex, 0);
+ ok(ret == 0, "got %#x\n", ret);
+
+ run_thread(mutex_thread, (void *)0);
}
static NTSTATUS main_test(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
@@ -410,6 +467,7 @@ static NTSTATUS main_test(IRP *irp, IO_STACK_LOCATION *stack, ULONG_PTR *info)
winetest_debug = test_input->winetest_debug;
winetest_report_success = test_input->winetest_report_success;
attr.ObjectName = &pathU;
+ attr.Attributes = OBJ_KERNEL_HANDLE;
ZwOpenFile(&okfile, FILE_APPEND_DATA, &attr, &io, 0, 0);
test_currentprocess();
--
2.7.4

View File

@ -1,57 +0,0 @@
From 6f82120ba57b09b999bf02bf73828cf834601526 Mon Sep 17 00:00:00 2001
From: Zebediah Figura <z.figura12@gmail.com>
Date: Sun, 19 Aug 2018 22:54:07 -0500
Subject: [PATCH 12/17] ntoskrnl.exe: Implement KeWaitForMutexObject().
Signed-off-by: Zebediah Figura <z.figura12@gmail.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 11 -----------
dlls/ntoskrnl.exe/sync.c | 10 ++++++++++
2 files changed, 10 insertions(+), 11 deletions(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index cc88100..5034c5d 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2085,17 +2085,6 @@ PRKTHREAD WINAPI KeGetCurrentThread(void)
return NULL;
}
- /***********************************************************************
- * KeWaitForMutexObject (NTOSKRNL.EXE.@)
- */
-NTSTATUS WINAPI KeWaitForMutexObject(PRKMUTEX Mutex, KWAIT_REASON WaitReason, KPROCESSOR_MODE WaitMode,
- BOOLEAN Alertable, PLARGE_INTEGER Timeout)
-{
- FIXME( "stub: %p, %d, %d, %d, %p\n", Mutex, WaitReason, WaitMode, Alertable, Timeout );
- return STATUS_NOT_IMPLEMENTED;
-}
-
-
/***********************************************************************
* KeInitializeSpinLock (NTOSKRNL.EXE.@)
*/
diff --git a/dlls/ntoskrnl.exe/sync.c b/dlls/ntoskrnl.exe/sync.c
index a038a07..acbbe3b 100644
--- a/dlls/ntoskrnl.exe/sync.c
+++ b/dlls/ntoskrnl.exe/sync.c
@@ -155,6 +155,16 @@ NTSTATUS WINAPI KeWaitForSingleObject( void *obj, KWAIT_REASON reason,
}
/***********************************************************************
+ * KeWaitForMutexObject (NTOSKRNL.EXE.@)
+ */
+NTSTATUS WINAPI KeWaitForMutexObject( PRKMUTEX mutex, KWAIT_REASON reason,
+ KPROCESSOR_MODE mode, BOOLEAN alertable, LARGE_INTEGER *timeout)
+{
+ return KeWaitForSingleObject( mutex, reason, mode, alertable, timeout );
+}
+
+
+/***********************************************************************
* KeInitializeEvent (NTOSKRNL.EXE.@)
*/
void WINAPI KeInitializeEvent( PRKEVENT event, EVENT_TYPE type, BOOLEAN state )
--
2.7.4

View File

@ -52,7 +52,7 @@ usage()
# Get the upstream commit sha
upstream_commit()
{
echo "92f38bc8790cbfb31badf97a211ed890ac00c1db"
echo "00b08fad99745db326ef060627c3e9dc668a734a"
}
# Show version information
@ -305,7 +305,6 @@ patch_enable_all ()
enable_stdole32_tlb_SLTG_Typelib="$1"
enable_taskmgr_Memory_Usage="$1"
enable_uianimation_stubs="$1"
enable_user32_Auto_Radio_Button="$1"
enable_user32_DM_SETDEFID="$1"
enable_user32_Dialog_Focus="$1"
enable_user32_Dialog_Paint_Event="$1"
@ -1077,9 +1076,6 @@ patch_enable ()
uianimation-stubs)
enable_uianimation_stubs="$2"
;;
user32-Auto_Radio_Button)
enable_user32_Auto_Radio_Button="$2"
;;
user32-DM_SETDEFID)
enable_user32_DM_SETDEFID="$2"
;;
@ -5258,24 +5254,12 @@ fi
# | dlls/ntoskrnl.exe/tests/driver.c, include/ddk/wdm.h
# |
if test "$enable_ntoskrnl_Synchronization" -eq 1; then
patch_apply ntoskrnl-Synchronization/0005-ntoskrnl.exe-Implement-KeClearEvent.patch
patch_apply ntoskrnl-Synchronization/0008-ntoskrnl.exe-Implement-KeInitializeSemaphore.patch
patch_apply ntoskrnl-Synchronization/0009-ntoskrnl.exe-Implement-KeReleaseSemaphore-and-waitin.patch
patch_apply ntoskrnl-Synchronization/0010-ntoskrnl.exe-Implement-KeInitializeMutex.patch
patch_apply ntoskrnl-Synchronization/0011-ntoskrnl.exe-Implement-KeReleaseMutex-and-waiting-on.patch
patch_apply ntoskrnl-Synchronization/0012-ntoskrnl.exe-Implement-KeWaitForMutexObject.patch
patch_apply ntoskrnl-Synchronization/0013-ntoskrnl.exe-Implement-KeInitializeTimerEx.patch
patch_apply ntoskrnl-Synchronization/0014-ntoskrnl.exe-Implement-KeSetTimerEx-and-waiting-on-t.patch
patch_apply ntoskrnl-Synchronization/0015-ntoskrnl.exe-Implement-KeCancelTimer.patch
patch_apply ntoskrnl-Synchronization/0016-ntoskrnl.exe-tests-Add-tests-for-waiting-on-timers.patch
patch_apply ntoskrnl-Synchronization/0017-ntoskrnl.exe-Implement-KeDelayExecutionThread.patch
(
printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement KeClearEvent().", 1 },';
printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement KeInitializeSemaphore().", 1 },';
printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement KeReleaseSemaphore() and waiting on semaphores.", 1 },';
printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement KeInitializeMutex().", 1 },';
printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement KeReleaseMutex() and waiting on mutexes.", 1 },';
printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement KeWaitForMutexObject().", 1 },';
printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement KeInitializeTimerEx().", 1 },';
printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement KeSetTimerEx() and waiting on timers.", 1 },';
printf '%s\n' '+ { "Zebediah Figura", "ntoskrnl.exe: Implement KeCancelTimer().", 1 },';
@ -6398,26 +6382,6 @@ if test "$enable_uianimation_stubs" -eq 1; then
) >> "$patchlist"
fi
# Patchset user32-Auto_Radio_Button
# |
# | This patchset fixes the following Wine bugs:
# | * [#42010] Move the auto radio button group logic from BM_SETCHECK to WM_LBUTTONUP handler
# | * [#16845] Add support for navigating a group of radio buttons using a keyboard.
# |
# | Modified files:
# | * dlls/user32/dialog.c, dlls/user32/tests/msg.c, dlls/user32/tests/resource.rc
# |
if test "$enable_user32_Auto_Radio_Button" -eq 1; then
patch_apply user32-Auto_Radio_Button/0003-user32-tests-Simplify-the-test-for-BM_CLICK-on-autor.patch
patch_apply user32-Auto_Radio_Button/0004-user32-tests-Add-a-test-for-navigating-a-group-of-bu.patch
patch_apply user32-Auto_Radio_Button/0005-user32-Add-support-for-navigating-a-group-of-radio-b.patch
(
printf '%s\n' '+ { "Dmitry Timoshkov", "user32/tests: Simplify the test for BM_CLICK on autoradio button by using a dialog.", 1 },';
printf '%s\n' '+ { "Dmitry Timoshkov", "user32/tests: Add a test for navigating a group of buttons using keyboard events.", 1 },';
printf '%s\n' '+ { "Dmitry Timoshkov", "user32: Add support for navigating a group of radio buttons using a keyboard.", 1 },';
) >> "$patchlist"
fi
# Patchset user32-DM_SETDEFID
# |
# | This patchset fixes the following Wine bugs:

View File

@ -1,8 +1,8 @@
From b84172fad2693e3dc75adab1820a95457eba80aa Mon Sep 17 00:00:00 2001
From 3f91a3758547eec6afb1a7c064af3d3f05aa235d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 11 Feb 2016 03:17:09 +0100
Subject: setupapi: Create registry keys for display devices and display
drivers.
Subject: [PATCH] setupapi: Create registry keys for display devices and
display drivers.
---
dlls/setupapi/devinst.c | 111 +++++++++++++++++++++++++++++++++++-----
@ -10,12 +10,12 @@ Subject: setupapi: Create registry keys for display devices and display
2 files changed, 101 insertions(+), 12 deletions(-)
diff --git a/dlls/setupapi/devinst.c b/dlls/setupapi/devinst.c
index 1f020b9b..0452d7a5 100644
index 64c04131b01..b8d94fa4a99 100644
--- a/dlls/setupapi/devinst.c
+++ b/dlls/setupapi/devinst.c
@@ -94,6 +94,15 @@ static const WCHAR SymbolicLink[] = {'S','y','m','b','o','l','i','c','L','i','n'
static const WCHAR Control[] = {'C','o','n','t','r','o','l',0};
@@ -95,6 +95,15 @@ static const WCHAR Control[] = {'C','o','n','t','r','o','l',0};
static const WCHAR Linked[] = {'L','i','n','k','e','d',0};
static const WCHAR emptyW[] = {0};
+/* GUIDs */
+static const WCHAR displayGUIDW[] = {'{','4','d','3','6','e','9','6','8','-','e','3','2','5','-',
@ -29,7 +29,7 @@ index 1f020b9b..0452d7a5 100644
/* is used to identify if a DeviceInfoSet pointer is
valid or not */
#define SETUP_DEVICE_INFO_SET_MAGIC 0xd00ff056
@@ -181,6 +190,90 @@ static struct device_iface *get_device_iface(HDEVINFO devinfo, const SP_DEVICE_I
@@ -184,6 +193,90 @@ static struct device_iface *get_device_iface(HDEVINFO devinfo, const SP_DEVICE_I
return (struct device_iface *)data->Reserved;
}
@ -120,7 +120,7 @@ index 1f020b9b..0452d7a5 100644
static inline void copy_device_data(SP_DEVINFO_DATA *data, const struct device *device)
{
data->ClassGuid = device->class;
@@ -470,8 +563,7 @@ static HKEY SETUPDI_CreateDevKey(struct device *device)
@@ -475,8 +568,7 @@ static HKEY SETUPDI_CreateDevKey(struct device *device)
HKEY enumKey, key = INVALID_HANDLE_VALUE;
LONG l;
@ -130,7 +130,7 @@ index 1f020b9b..0452d7a5 100644
if (!l)
{
RegCreateKeyExW(enumKey, device->instanceId, 0, NULL, 0,
@@ -563,8 +655,7 @@ static void SETUPDI_RemoveDevice(struct device *device)
@@ -567,8 +659,7 @@ static void SETUPDI_RemoveDevice(struct device *device)
HKEY enumKey;
LONG l;
@ -140,7 +140,7 @@ index 1f020b9b..0452d7a5 100644
if (!l)
{
RegDeleteTreeW(enumKey, device->instanceId);
@@ -2004,8 +2095,7 @@ static void SETUPDI_EnumerateMatchingInterfaces(HDEVINFO DeviceInfoSet,
@@ -2007,8 +2098,7 @@ static void SETUPDI_EnumerateMatchingInterfaces(HDEVINFO DeviceInfoSet,
TRACE("%s\n", debugstr_w(enumstr));
@ -150,7 +150,7 @@ index 1f020b9b..0452d7a5 100644
for (i = 0; !l; i++)
{
len = ARRAY_SIZE(subKeyName);
@@ -2231,8 +2321,7 @@ static void SETUPDI_EnumerateDevices(HDEVINFO DeviceInfoSet, const GUID *class,
@@ -2234,8 +2324,7 @@ static void SETUPDI_EnumerateDevices(HDEVINFO DeviceInfoSet, const GUID *class,
TRACE("%p, %s, %s, %08x\n", DeviceInfoSet, debugstr_guid(class),
debugstr_w(enumstr), flags);
@ -160,7 +160,7 @@ index 1f020b9b..0452d7a5 100644
if (enumKey != INVALID_HANDLE_VALUE)
{
if (enumstr)
@@ -3378,8 +3467,7 @@ static HKEY SETUPDI_OpenDevKey(struct device *device, REGSAM samDesired)
@@ -3346,8 +3435,7 @@ static HKEY SETUPDI_OpenDevKey(struct device *device, REGSAM samDesired)
HKEY enumKey, key = INVALID_HANDLE_VALUE;
LONG l;
@ -170,7 +170,7 @@ index 1f020b9b..0452d7a5 100644
if (!l)
{
RegOpenKeyExW(enumKey, device->instanceId, 0, samDesired, &key);
@@ -3471,8 +3559,7 @@ static BOOL SETUPDI_DeleteDevKey(struct device *device)
@@ -3439,8 +3527,7 @@ static BOOL SETUPDI_DeleteDevKey(struct device *device)
BOOL ret = FALSE;
LONG l;
@ -181,7 +181,7 @@ index 1f020b9b..0452d7a5 100644
{
ret = RegDeleteTreeW(enumKey, device->instanceId);
diff --git a/loader/wine.inf.in b/loader/wine.inf.in
index 5a3f8c46..51e17453 100644
index 5a3f8c46969..51e17453f3f 100644
--- a/loader/wine.inf.in
+++ b/loader/wine.inf.in
@@ -465,6 +465,8 @@ HKLM,System\CurrentControlSet\Control\ContentIndex\Language\Neutral,"Locale",0x1
@ -194,5 +194,5 @@ index 5a3f8c46..51e17453 100644
HKLM,System\CurrentControlSet\Control\Class\{4d36e978-e325-11ce-bfc1-08002be10318},"Class",,"Ports"
HKLM,System\CurrentControlSet\Control\Class\{6bdd1fc6-810f-11d0-bec7-08002be2092f},,,"Imaging devices"
--
2.19.1
2.19.2

View File

@ -1,183 +0,0 @@
From 66b4cda44a077b7e540462b5b98ebad0a58920b8 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Tue, 10 Jan 2017 15:58:14 +0800
Subject: user32/tests: Simplify the test for BM_CLICK on autoradio button by
using a dialog.
---
dlls/user32/tests/msg.c | 78 ++++++++++++++++++++++++++-----------------
dlls/user32/tests/resource.rc | 11 ++++++
2 files changed, 59 insertions(+), 30 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 643a6bf..daa8210 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -107,6 +107,8 @@ static DWORD cbt_hook_thread_id;
static const WCHAR testWindowClassW[] =
{ 'T','e','s','t','W','i','n','d','o','w','C','l','a','s','s','W',0 };
+static LRESULT WINAPI ParentMsgCheckProcA(HWND, UINT, WPARAM, LPARAM);
+
/*
FIXME: add tests for these
Window Edge Styles (Win31/Win95/98 look), in order of precedence:
@@ -6135,7 +6137,24 @@ static LRESULT CALLBACK button_hook_proc(HWND hwnd, UINT message, WPARAM wParam,
case BM_SETSTATE:
if (GetCapture())
ok(GetCapture() == hwnd, "GetCapture() = %p\n", GetCapture());
+
+ lParam = (ULONG_PTR)GetMenu(hwnd);
+ goto log_it;
+
+ case WM_GETDLGCODE:
+ if (lParam)
+ {
+ MSG *msg = (MSG *)lParam;
+ lParam = MAKELPARAM(msg->message, msg->wParam);
+ }
+ wParam = (ULONG_PTR)GetMenu(hwnd);
+ goto log_it;
+
+ case BM_SETCHECK:
+ case BM_GETCHECK:
+ lParam = (ULONG_PTR)GetMenu(hwnd);
/* fall through */
+log_it:
default:
msg.hwnd = hwnd;
msg.message = message;
@@ -6617,32 +6636,34 @@ static void test_button_bm_get_set_image(void)
ReleaseDC(0, hdc);
}
-#define ID_RADIO1 0x00e1
-#define ID_RADIO2 0x00e2
+#define ID_RADIO1 501
+#define ID_RADIO2 502
+#define ID_RADIO3 503
+#define ID_TEXT 504
-static const struct message auto_radio_button_WM_CLICK[] =
+static const struct message auto_radio_button_BM_CLICK[] =
{
{ BM_CLICK, sent|wparam|lparam, 0, 0 },
{ WM_LBUTTONDOWN, sent|wparam|lparam|defwinproc, 0, 0 },
{ EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
- { BM_SETSTATE, sent|wparam|lparam|defwinproc, BST_CHECKED, 0 },
+ { BM_SETSTATE, sent|wparam|lparam|defwinproc, BST_CHECKED, ID_RADIO2 },
{ WM_CTLCOLORSTATIC, sent|parent },
{ EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
{ WM_LBUTTONUP, sent|wparam|lparam|defwinproc, 0, 0 },
- { BM_SETSTATE, sent|wparam|lparam|defwinproc, BST_UNCHECKED, 0 },
+ { BM_SETSTATE, sent|wparam|lparam|defwinproc, BST_UNCHECKED, ID_RADIO2 },
{ WM_CTLCOLORSTATIC, sent|parent },
{ EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
- { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, 0, 0 },
- { BM_SETCHECK, sent|wparam|lparam|defwinproc, BST_CHECKED, 0 },
- { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, 0, 0 },
- { BM_SETCHECK, sent|wparam|lparam|defwinproc, 0, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, ID_RADIO2, 0 },
+ { BM_SETCHECK, sent|wparam|lparam|defwinproc, BST_CHECKED, ID_RADIO2 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, ID_RADIO1, 0 },
+ { BM_SETCHECK, sent|wparam|lparam|defwinproc, 0, ID_RADIO1 },
{ WM_CTLCOLORSTATIC, sent|parent },
{ EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
- { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, 0, 0 },
- { BM_SETCHECK, sent|wparam|lparam|defwinproc, 0, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, ID_RADIO3, 0 },
+ { BM_SETCHECK, sent|wparam|lparam|defwinproc, 0, ID_RADIO3 },
{ WM_CTLCOLORSTATIC, sent|parent },
{ EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
- { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, 0, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, ID_TEXT, 0 },
{ EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
{ WM_CAPTURECHANGED, sent|wparam|lparam|defwinproc, 0, 0 },
{ WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_RADIO2, BN_CLICKED) },
@@ -6652,30 +6673,27 @@ static const struct message auto_radio_button_WM_CLICK[] =
{ 0 }
};
-static void test_autoradio_messages(void)
+static INT_PTR WINAPI radio_test_dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
- HWND parent, radio1, radio2, radio3, child;
+ ParentMsgCheckProcA(hwnd, msg, wp, lp);
+ return 1;
+}
+
+static void test_autoradio_BM_CLICK(void)
+{
+ HWND parent, radio1, radio2, radio3;
RECT rc;
MSG msg;
DWORD ret;
subclass_button();
- parent = CreateWindowExA(0, "TestParentClass", "Test parent", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
- 100, 100, 200, 200, 0, 0, 0, NULL);
+ parent = CreateDialogParamA(0, "AUTORADIO_TEST_DIALOG_1", 0, radio_test_dlg_proc, 0);
ok(parent != 0, "failed to create parent window\n");
- radio1 = CreateWindowExA(0, "my_button_class", "radio1", WS_VISIBLE | WS_CHILD | WS_GROUP | BS_AUTORADIOBUTTON | BS_NOTIFY,
- 0, 0, 70, 18, parent, (HMENU)ID_RADIO1, 0, NULL);
- ok(radio1 != 0, "failed to create child window\n");
- radio3 = CreateWindowExA(0, "my_button_class", "radio3", WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON | BS_NOTIFY,
- 0, 25, 70, 18, parent, (HMENU)-1, 0, NULL);
- ok(radio3 != 0, "failed to create child window\n");
- child = CreateWindowExA(0, "my_button_class", "text", WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_NOTIFY,
- 0, 50, 70, 18, parent, (HMENU)-1, 0, NULL);
- ok(child != 0, "failed to create child window\n");
- radio2 = CreateWindowExA(0, "my_button_class", "radio2", WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_NOTIFY,
- 0, 75, 70, 18, parent, (HMENU)ID_RADIO2, 0, NULL);
- ok(radio2 != 0, "failed to create child window\n");
+
+ radio1 = GetDlgItem(parent, ID_RADIO1);
+ radio2 = GetDlgItem(parent, ID_RADIO2);
+ radio3 = GetDlgItem(parent, ID_RADIO3);
/* this avoids focus messages in the generated sequence */
SetFocus(radio2);
@@ -6727,7 +6745,7 @@ static void test_autoradio_messages(void)
SendMessageA(radio2, BM_CLICK, 0, 0);
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
- ok_sequence(auto_radio_button_WM_CLICK, "BM_CLICK on auto-radio button", FALSE);
+ ok_sequence(auto_radio_button_BM_CLICK, "BM_CLICK on auto-radio button", FALSE);
log_all_parent_messages--;
@@ -16961,7 +16979,7 @@ START_TEST(msg)
test_mdi_messages();
test_button_messages();
test_button_bm_get_set_image();
- test_autoradio_messages();
+ test_autoradio_BM_CLICK();
test_static_messages();
test_listbox_messages();
test_combobox_messages();
diff --git a/dlls/user32/tests/resource.rc b/dlls/user32/tests/resource.rc
index 756e38f..90d687d 100644
--- a/dlls/user32/tests/resource.rc
+++ b/dlls/user32/tests/resource.rc
@@ -75,6 +75,17 @@ FONT 8, "MS Shell Dlg"
PUSHBUTTON "Cancel", IDCANCEL,109,20,50,14, WS_TABSTOP | WS_GROUP
}
+AUTORADIO_TEST_DIALOG_1 DIALOGEX 0, 0, 200, 200
+STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
+CAPTION "Radio Button Test Dialog"
+FONT 8, "MS Shell Dlg"
+{
+ CONTROL "Radio1",501,"my_button_class",WS_VISIBLE | WS_CHILD | WS_GROUP | BS_AUTORADIOBUTTON | BS_NOTIFY | WS_TABSTOP,10,10,70,18
+ CONTROL "Radio3",503,"my_button_class",WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON | BS_NOTIFY | WS_TABSTOP,10,35,70,18
+ CONTROL "Text",504,"my_button_class",WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_NOTIFY | WS_TABSTOP,10,60,70,18
+ CONTROL "Radio2",502,"my_button_class",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_NOTIFY | WS_TABSTOP,10,85,70,18
+}
+
CLASS_TEST_DIALOG DIALOG 0, 0, 91, 28
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "CreateDialogParams Test"
--
2.7.4

View File

@ -1,377 +0,0 @@
From b2ea2a89745d96b906d45cea6494b04d01085c52 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Tue, 10 Jan 2017 16:02:36 +0800
Subject: user32/tests: Add a test for navigating a group of buttons using
keyboard events.
---
dlls/user32/tests/msg.c | 316 ++++++++++++++++++++++++++++++++++++++++++
dlls/user32/tests/resource.rc | 11 ++
2 files changed, 327 insertions(+)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index daa8210..e57f49b 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -6673,6 +6673,132 @@ static const struct message auto_radio_button_BM_CLICK[] =
{ 0 }
};
+static const struct message auto_radio_button_VK_UP_child[] =
+{
+ { WM_KEYDOWN, sent|wparam|lparam, VK_UP, 0 },
+ { WM_KEYUP, sent|wparam|lparam, VK_UP, 0 },
+ { 0 }
+};
+
+static const struct message auto_radio_button_VK_UP_parent[] =
+{
+ { WM_KEYDOWN, sent|wparam|lparam|parent, VK_UP, 0 },
+ { WM_KEYUP, sent|wparam|lparam|parent, VK_UP, 0 },
+ { 0 }
+};
+
+static const struct message auto_radio_button_VK_UP_dialog[] =
+{
+ { WM_GETDLGCODE, sent|parent, 0, 0 },
+
+ /* optional trailer seen on some windows setups */
+ { WM_CHANGEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_CTLCOLORSTATIC, sent|parent|optional },
+ { WM_CTLCOLORSTATIC, sent|parent|optional },
+ { WM_CTLCOLORSTATIC, sent|parent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_CTLCOLORSTATIC, sent|parent|optional },
+ { WM_CTLCOLORSTATIC, sent|parent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_CTLCOLORBTN, sent|parent|optional },
+ { WM_CTLCOLORBTN, sent|parent|optional },
+ { WM_UPDATEUISTATE, sent|optional },
+ { WM_CTLCOLORSTATIC, sent|parent|optional },
+ { WM_CTLCOLORSTATIC, sent|parent|optional },
+ { 0 }
+};
+
+static const struct message auto_radio_button_VK_DOWN_dialog[] =
+{
+ { WM_GETDLGCODE, sent|parent, 0, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam, ID_RADIO1, MAKELPARAM(WM_KEYDOWN, VK_DOWN) },
+ { WM_GETDLGCODE, sent|wparam|lparam, ID_RADIO1, 0 },
+ { HCBT_SETFOCUS, hook },
+ { WM_KILLFOCUS, sent, 0, 0 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_RADIO3, BN_KILLFOCUS) },
+ { EVENT_OBJECT_FOCUS, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_SETFOCUS, sent, 0, 0 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_RADIO1, BN_SETFOCUS) },
+ { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_RADIO1, BN_CLICKED) },
+ { WM_GETDLGCODE, sent|wparam|lparam, ID_RADIO1, 0 },
+ { WM_GETDLGCODE, sent|parent, 0, 0 },
+ { DM_GETDEFID, sent|parent, 0, 0 },
+ { BM_GETCHECK, sent|wparam|lparam, 0, ID_RADIO1 },
+ { BM_CLICK, sent|wparam|lparam, 1, 0 },
+ { WM_LBUTTONDOWN, sent|wparam|lparam|defwinproc, 0, 0 },
+ { EVENT_SYSTEM_CAPTURESTART, winevent_hook|wparam|lparam, 0, 0 },
+ { BM_SETSTATE, sent|wparam|lparam|defwinproc, BST_CHECKED, ID_RADIO1 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_LBUTTONUP, sent|wparam|lparam|defwinproc, 0, 0 },
+ { BM_SETSTATE, sent|wparam|lparam|defwinproc, BST_UNCHECKED, ID_RADIO1 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, ID_RADIO1, 0 },
+ { BM_SETCHECK, sent|wparam|lparam|defwinproc, BST_CHECKED, ID_RADIO1 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, ID_RADIO3, 0 },
+ { BM_SETCHECK, sent|wparam|lparam|defwinproc, BST_UNCHECKED, ID_RADIO3 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, ID_TEXT, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|defwinproc, ID_RADIO2, 0 },
+ { BM_SETCHECK, sent|wparam|lparam|defwinproc, BST_UNCHECKED, ID_RADIO2 },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { EVENT_OBJECT_STATECHANGE, winevent_hook|wparam|lparam, OBJID_CLIENT, 0 },
+ { EVENT_SYSTEM_CAPTUREEND, winevent_hook|wparam|lparam, 0, 0 },
+ { WM_CAPTURECHANGED, sent|wparam|lparam|defwinproc, 0, 0 },
+ { WM_COMMAND, sent|wparam|parent, MAKEWPARAM(ID_RADIO1, BN_CLICKED) },
+ { WM_NCHITTEST, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
+ { WM_SETCURSOR, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
+ { WM_MOUSEMOVE, sent|optional, 0, 0 }, /* FIXME: Wine doesn't send it */
+ { WM_PAINT, sent },
+ { WM_CTLCOLORSTATIC, sent|parent },
+ { 0 }
+};
+
+static const struct message auto_radio_button_VK_DOWN_radio3[] =
+{
+ { BM_GETCHECK, sent|wparam|lparam, 0, ID_RADIO1 },
+ { BM_GETCHECK, sent|wparam|lparam, 0, ID_RADIO2 },
+ { BM_GETCHECK, sent|wparam|lparam, 0, ID_RADIO3 },
+ { WM_GETDLGCODE, sent|parent, 0, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam, ID_RADIO1, MAKELPARAM(WM_KEYDOWN, VK_DOWN) },
+ { WM_GETDLGCODE, sent|wparam|lparam, ID_RADIO1, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam, ID_RADIO1, 0 },
+ { WM_GETDLGCODE, sent|wparam|lparam|parent, 0, 0 },
+ { WM_USER, sent|parent, 0, 0 },
+ { BM_GETCHECK, sent|wparam|lparam, 0, ID_RADIO1 },
+ { 0 }
+};
+
+static const struct message auto_radio_button_VK_UP_radio1[] =
+{
+ { WM_GETDLGCODE, sent|parent, 0, 0 },
+ { 0 }
+};
+
static INT_PTR WINAPI radio_test_dlg_proc(HWND hwnd, UINT msg, WPARAM wp, LPARAM lp)
{
ParentMsgCheckProcA(hwnd, msg, wp, lp);
@@ -6759,6 +6885,195 @@ static void test_autoradio_BM_CLICK(void)
DestroyWindow(parent);
}
+#define test_radio(r1, s1, r2, s2, r3, s3) test_radio_dbg(r1, s1, r2, s2, r3, s3, __LINE__)
+static void test_radio_dbg(HWND radio1, int state1, HWND radio2, int state2, HWND radio3, int state3, int line)
+{
+ DWORD ret;
+
+ ret = SendMessageA(radio1, BM_GETCHECK, 0, 0);
+ ok_(__FILE__,line)(ret == state1 ? BST_CHECKED : BST_UNCHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio2, BM_GETCHECK, 0, 0);
+ ok_(__FILE__,line)(ret == state2 ? BST_CHECKED : BST_UNCHECKED, "got %08x\n", ret);
+ ret = SendMessageA(radio3, BM_GETCHECK, 0, 0);
+ ok_(__FILE__,line)(ret == state3 ? BST_CHECKED : BST_UNCHECKED, "got %08x\n", ret);
+}
+
+static void set_radio(HWND radio1, int state1, HWND radio2, int state2, HWND radio3, int state3)
+{
+ SendMessageA(radio1, BM_SETCHECK, state1 ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendMessageA(radio2, BM_SETCHECK, state2 ? BST_CHECKED : BST_UNCHECKED, 0);
+ SendMessageA(radio3, BM_SETCHECK, state3 ? BST_CHECKED : BST_UNCHECKED, 0);
+}
+
+static void test_autoradio_kbd_move(void)
+{
+ HWND parent, radio1, radio2, radio3, hwnd;
+ RECT rc;
+ MSG msg;
+ DWORD ret;
+
+ subclass_button();
+
+ parent = CreateDialogParamA(0, "AUTORADIO_TEST_DIALOG_2", 0, radio_test_dlg_proc, 0);
+ ok(parent != 0, "failed to create parent window\n");
+
+ radio1 = GetDlgItem(parent, ID_RADIO1);
+ radio2 = GetDlgItem(parent, ID_RADIO2);
+ radio3 = GetDlgItem(parent, ID_RADIO3);
+
+ flush_events();
+ flush_sequence();
+
+ test_radio(radio1, 0, radio2, 0, radio3, 0);
+ set_radio(radio1, 1, radio2, 1, radio3, 1);
+ test_radio(radio1, 1, radio2, 1, radio3, 1);
+
+ SetFocus(radio3);
+
+ flush_events();
+ flush_sequence();
+
+ log_all_parent_messages++;
+
+ SendMessageA(radio3, WM_KEYDOWN, VK_UP, 0);
+ SendMessageA(radio3, WM_KEYUP, VK_UP, 0);
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(auto_radio_button_VK_UP_child, "press/release VK_UP on auto-radio button", FALSE);
+
+ test_radio(radio1, 1, radio2, 1, radio3, 1);
+
+ flush_events();
+ flush_sequence();
+
+ DefDlgProcA(parent, WM_KEYDOWN, VK_UP, 0);
+ DefDlgProcA(parent, WM_KEYUP, VK_UP, 0);
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(auto_radio_button_VK_UP_parent, "press/release VK_UP on dialog", FALSE);
+
+ test_radio(radio1, 1, radio2, 1, radio3, 1);
+
+ SetFocus(radio3);
+ GetWindowRect(radio3, &rc);
+
+ flush_events();
+ flush_sequence();
+
+ msg.hwnd = parent;
+ msg.message = WM_KEYDOWN;
+ msg.wParam = VK_UP;
+ msg.lParam = 0;
+ msg.pt.x = rc.left + 1;
+ msg.pt.y = rc.top + 1;
+ ret = IsDialogMessageA(parent, &msg);
+ ok(ret, "IsDialogMessage should return TRUE\n");
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+if (0) /* actual message sequence is different on every run in some Windows setups */
+ ok_sequence(auto_radio_button_VK_UP_dialog, "IsDialogMessage(VK_UP) #1", FALSE);
+ /* what really matters is that nothing has changed */
+ test_radio(radio1, 1, radio2, 1, radio3, 1);
+
+ set_radio(radio1, 0, radio2, 1, radio3, 1);
+ test_radio(radio1, 0, radio2, 1, radio3, 1);
+
+ flush_events();
+ flush_sequence();
+
+ ret = IsDialogMessageA(parent, &msg);
+ ok(ret, "IsDialogMessage should return TRUE\n");
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+if (0) /* actual message sequence is different on every run in some Windows setups */
+ ok_sequence(auto_radio_button_VK_UP_dialog, "IsDialogMessage(VK_UP) #2", FALSE);
+ /* what really matters is that nothing has changed */
+ test_radio(radio1, 0, radio2, 1, radio3, 1);
+
+ /* switch from radio3 ro radio1 */
+ SetFocus(radio3);
+ GetWindowRect(radio3, &rc);
+
+ flush_events();
+ flush_sequence();
+
+ msg.hwnd = parent;
+ msg.message = WM_KEYDOWN;
+ msg.wParam = VK_DOWN;
+ msg.lParam = 0;
+ msg.pt.x = rc.left + 1;
+ msg.pt.y = rc.top + 1;
+ ret = IsDialogMessageA(parent, &msg);
+ ok(ret, "IsDialogMessage should return TRUE\n");
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(auto_radio_button_VK_DOWN_dialog, "IsDialogMessage(VK_DOWN)", TRUE);
+
+todo_wine
+ test_radio(radio1, 1, radio2, 0, radio3, 0);
+
+ hwnd = GetFocus();
+todo_wine
+ ok(hwnd == radio1, "focus should be on radio1, not on %p\n", hwnd);
+ GetWindowRect(radio1, &rc);
+
+ msg.hwnd = parent;
+ msg.message = WM_KEYDOWN;
+ msg.wParam = VK_DOWN;
+ msg.lParam = 0;
+ msg.pt.x = rc.left + 1;
+ msg.pt.y = rc.top + 1;
+ ret = IsDialogMessageA(parent, &msg);
+ ok(ret, "IsDialogMessage should return TRUE\n");
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(auto_radio_button_VK_DOWN_radio3, "down to radio3", TRUE);
+
+todo_wine
+ test_radio(radio1, 1, radio2, 0, radio3, 0);
+
+ hwnd = GetFocus();
+todo_wine
+ ok(hwnd == radio1, "focus should be on radio1, not on %p\n", hwnd);
+
+ flush_events();
+ flush_sequence();
+
+ msg.hwnd = parent;
+ msg.message = WM_KEYDOWN;
+ msg.wParam = VK_UP;
+ msg.lParam = 0;
+ msg.pt.x = rc.left + 1;
+ msg.pt.y = rc.top + 1;
+ ret = IsDialogMessageA(parent, &msg);
+ ok(ret, "IsDialogMessage should return TRUE\n");
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+ ok_sequence(auto_radio_button_VK_UP_radio1, "up to radio1", TRUE);
+
+todo_wine
+ test_radio(radio1, 1, radio2, 0, radio3, 0);
+
+ hwnd = GetFocus();
+todo_wine
+ ok(hwnd == radio1, "focus should be on radio1, not on %p\n", hwnd);
+
+ flush_events();
+ flush_sequence();
+
+ msg.hwnd = parent;
+ msg.message = WM_KEYDOWN;
+ msg.wParam = VK_UP;
+ msg.lParam = 0;
+ msg.pt.x = rc.left + 1;
+ msg.pt.y = rc.top + 1;
+ ret = IsDialogMessageA(parent, &msg);
+ ok(ret, "IsDialogMessage should return TRUE\n");
+ while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
+if (0) /* actual message sequence is different on every run in some Windows setups */
+ ok_sequence(auto_radio_button_VK_UP_dialog, "IsDialogMessage(VK_UP) #3", FALSE);
+ /* what really matters is that nothing has changed */
+todo_wine
+ test_radio(radio1, 1, radio2, 0, radio3, 0);
+
+ log_all_parent_messages--;
+
+ DestroyWindow(parent);
+}
+
/****************** static message test *************************/
static const struct message WmSetFontStaticSeq2[] =
{
@@ -16980,6 +17295,7 @@ START_TEST(msg)
test_button_messages();
test_button_bm_get_set_image();
test_autoradio_BM_CLICK();
+ test_autoradio_kbd_move();
test_static_messages();
test_listbox_messages();
test_combobox_messages();
diff --git a/dlls/user32/tests/resource.rc b/dlls/user32/tests/resource.rc
index 90d687d..fdd1ce7 100644
--- a/dlls/user32/tests/resource.rc
+++ b/dlls/user32/tests/resource.rc
@@ -86,6 +86,17 @@ FONT 8, "MS Shell Dlg"
CONTROL "Radio2",502,"my_button_class",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_NOTIFY | WS_TABSTOP,10,85,70,18
}
+AUTORADIO_TEST_DIALOG_2 DIALOGEX 0, 0, 200, 200
+STYLE DS_SETFONT | DS_MODALFRAME | WS_CAPTION | WS_SYSMENU | WS_VISIBLE
+CAPTION "Radio Button Test Dialog"
+FONT 8, "MS Shell Dlg"
+{
+ CONTROL "Radio1",501,"my_button_class",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_NOTIFY | WS_TABSTOP,10,10,70,18
+ CONTROL "Radio3",503,"my_button_class",WS_VISIBLE | WS_CHILD | BS_RADIOBUTTON | BS_NOTIFY,10,35,70,18
+ CONTROL "Text",504,"my_button_class",WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON | BS_NOTIFY,10,60,70,18
+ CONTROL "Radio2",502,"my_button_class",WS_VISIBLE | WS_CHILD | BS_AUTORADIOBUTTON | BS_NOTIFY,10,85,70,18
+}
+
CLASS_TEST_DIALOG DIALOG 0, 0, 91, 28
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "CreateDialogParams Test"
--
2.7.4

View File

@ -1,87 +0,0 @@
From ab101021de9c3881cf70d9fc5e1af2dc2d38ebf9 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Tue, 10 Jan 2017 16:08:03 +0800
Subject: user32: Add support for navigating a group of radio buttons using a
keyboard.
It approximates the behaviour observed in the message tests but still
doesn't make the message tests pass without failures.
---
dlls/user32/dialog.c | 12 ++++++++++--
dlls/user32/tests/msg.c | 7 -------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/dlls/user32/dialog.c b/dlls/user32/dialog.c
index 7f9a72d59ee..f8571498643 100644
--- a/dlls/user32/dialog.c
+++ b/dlls/user32/dialog.c
@@ -1239,8 +1239,16 @@ BOOL WINAPI IsDialogMessageW( HWND hwndDlg, LPMSG msg )
if (!(dlgCode & DLGC_WANTARROWS))
{
BOOL fPrevious = (msg->wParam == VK_LEFT || msg->wParam == VK_UP);
- HWND hwndNext = GetNextDlgGroupItem (hwndDlg, GetFocus(), fPrevious );
- SendMessageW( hwndDlg, WM_NEXTDLGCTL, (WPARAM)hwndNext, 1 );
+ HWND hwndNext = GetNextDlgGroupItem( hwndDlg, msg->hwnd, fPrevious );
+ if (hwndNext && SendMessageW( hwndNext, WM_GETDLGCODE, msg->wParam, (LPARAM)msg ) == (DLGC_BUTTON | DLGC_RADIOBUTTON))
+ {
+ SetFocus( hwndNext );
+ if ((GetWindowLongW( hwndNext, GWL_STYLE ) & BS_TYPEMASK) == BS_AUTORADIOBUTTON &&
+ SendMessageW( hwndNext, BM_GETCHECK, 0, 0 ) != BST_CHECKED)
+ SendMessageW( hwndNext, BM_CLICK, 1, 0 );
+ }
+ else
+ SendMessageW( hwndDlg, WM_NEXTDLGCTL, (WPARAM)hwndNext, 1 );
return TRUE;
}
break;
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index ba7320d9c41..bfd2b915280 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -6451,11 +6451,9 @@ if (0) /* actual message sequence is different on every run in some Windows setu
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok_sequence(auto_radio_button_VK_DOWN_dialog, "IsDialogMessage(VK_DOWN)", TRUE);
-todo_wine
test_radio(radio1, 1, radio2, 0, radio3, 0);
hwnd = GetFocus();
-todo_wine
ok(hwnd == radio1, "focus should be on radio1, not on %p\n", hwnd);
GetWindowRect(radio1, &rc);
@@ -6470,11 +6468,9 @@ todo_wine
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok_sequence(auto_radio_button_VK_DOWN_radio3, "down to radio3", TRUE);
-todo_wine
test_radio(radio1, 1, radio2, 0, radio3, 0);
hwnd = GetFocus();
-todo_wine
ok(hwnd == radio1, "focus should be on radio1, not on %p\n", hwnd);
flush_events();
@@ -6491,11 +6487,9 @@ todo_wine
while (PeekMessageA(&msg, 0, 0, 0, PM_REMOVE)) DispatchMessageA(&msg);
ok_sequence(auto_radio_button_VK_UP_radio1, "up to radio1", TRUE);
-todo_wine
test_radio(radio1, 1, radio2, 0, radio3, 0);
hwnd = GetFocus();
-todo_wine
ok(hwnd == radio1, "focus should be on radio1, not on %p\n", hwnd);
flush_events();
@@ -6513,7 +6507,6 @@ todo_wine
if (0) /* actual message sequence is different on every run in some Windows setups */
ok_sequence(auto_radio_button_VK_UP_dialog, "IsDialogMessage(VK_UP) #3", FALSE);
/* what really matters is that nothing has changed */
-todo_wine
test_radio(radio1, 1, radio2, 0, radio3, 0);
log_all_parent_messages--;
--
2.11.0

View File

@ -1,2 +0,0 @@
Fixes: [42010] Move the auto radio button group logic from BM_SETCHECK to WM_LBUTTONUP handler
Fixes: [16845] Add support for navigating a group of radio buttons using a keyboard.