Wine-Devel
Threads by month
- ----- 2026 -----
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 17 participants
- 84524 discussions
Oct. 27, 2021
1
0
[PATCH 1/3] uiautomationcore: Implement UiaGetReservedNotSupportedValue.
by Connor McAdams Oct. 27, 2021
by Connor McAdams Oct. 27, 2021
Oct. 27, 2021
Signed-off-by: Connor McAdams <cmcadams(a)codeweavers.com>
---
dlls/uiautomationcore/Makefile.in | 1 +
dlls/uiautomationcore/uia_main.c | 196 +++++++++++++++++++++++++++++-
2 files changed, 195 insertions(+), 2 deletions(-)
diff --git a/dlls/uiautomationcore/Makefile.in b/dlls/uiautomationcore/Makefile.in
index 71ea7b99c94..5a72ea144c4 100644
--- a/dlls/uiautomationcore/Makefile.in
+++ b/dlls/uiautomationcore/Makefile.in
@@ -1,5 +1,6 @@
MODULE = uiautomationcore.dll
IMPORTLIB = uiautomationcore
+IMPORTS = uuid ole32
EXTRADLLFLAGS = -Wb,--prefer-native
diff --git a/dlls/uiautomationcore/uia_main.c b/dlls/uiautomationcore/uia_main.c
index 2dada95af80..e51a4b4d555 100644
--- a/dlls/uiautomationcore/uia_main.c
+++ b/dlls/uiautomationcore/uia_main.c
@@ -16,12 +16,199 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
+#define COBJMACROS
+
#include "uiautomation.h"
#include "wine/debug.h"
+#include "wine/heap.h"
WINE_DEFAULT_DEBUG_CHANNEL(uiautomation);
+struct uia_rsrv_ftmarshaler
+{
+ IMarshal IMarshal_iface;
+
+ IUnknown *inner_unk;
+ IMarshal *marshal;
+};
+
+/*
+ * Create a custom proxy IMarshal, so that IMarshal::Release actually releases
+ * the interface.
+ */
+static struct uia_rsrv_ftmarshaler *impl_uia_rsrv_ft_from_IMarshal(IMarshal *iface)
+{
+ return CONTAINING_RECORD(iface, struct uia_rsrv_ftmarshaler, IMarshal_iface);
+}
+
+static HRESULT WINAPI uia_rsrv_ftmarshaler_QueryInterface(IMarshal *iface, REFIID riid, void **obj)
+{
+ struct uia_rsrv_ftmarshaler *marshaler = impl_uia_rsrv_ft_from_IMarshal(iface);
+
+ TRACE("%p, %s, %p\n", iface, debugstr_guid(riid), obj);
+
+ return IMarshal_QueryInterface(marshaler->marshal, riid, obj);
+}
+
+static ULONG WINAPI uia_rsrv_ftmarshaler_AddRef(IMarshal *iface)
+{
+ struct uia_rsrv_ftmarshaler *marshaler = impl_uia_rsrv_ft_from_IMarshal(iface);
+ ULONG ref = IUnknown_AddRef(marshaler->inner_unk);
+
+ TRACE("%p, ref %d\n", iface, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI uia_rsrv_ftmarshaler_Release(IMarshal *iface)
+{
+ struct uia_rsrv_ftmarshaler *marshaler = impl_uia_rsrv_ft_from_IMarshal(iface);
+ ULONG ref = IUnknown_Release(marshaler->inner_unk);
+
+ TRACE("%p, ref %d\n", iface, ref);
+
+ if (!ref)
+ heap_free(marshaler);
+
+ return ref;
+}
+
+static HRESULT WINAPI uia_rsrv_ftmarshaler_GetUnmarshalClass(IMarshal *iface, REFIID riid, void *pv,
+ DWORD dest_context, void *pvDestContext, DWORD mshlflags, CLSID *clsid)
+{
+ struct uia_rsrv_ftmarshaler *marshaler = impl_uia_rsrv_ft_from_IMarshal(iface);
+ TRACE("%s, %p, %#x, %p, %#x, %p\n", debugstr_guid(riid), pv, dest_context, pvDestContext, mshlflags, clsid);
+ return IMarshal_GetUnmarshalClass(marshaler->marshal, riid, pv, dest_context, pvDestContext, mshlflags, clsid);
+}
+
+static HRESULT WINAPI uia_rsrv_ftmarshaler_GetMarshalSizeMax(IMarshal *iface, REFIID riid, void *pv,
+ DWORD dest_context, void *pvDestContext, DWORD mshlflags, DWORD *size)
+{
+ struct uia_rsrv_ftmarshaler *marshaler = impl_uia_rsrv_ft_from_IMarshal(iface);
+ TRACE("%s, %p, %#x, %p, %#x, %p\n", debugstr_guid(riid), pv, dest_context, pvDestContext, mshlflags, size);
+ return IMarshal_GetMarshalSizeMax(marshaler->marshal, riid, pv, dest_context, pvDestContext, mshlflags, size);
+}
+
+static HRESULT WINAPI uia_rsrv_ftmarshaler_MarshalInterface(IMarshal *iface, IStream *stream, REFIID riid,
+ void *pv, DWORD dest_context, void *pvDestContext, DWORD mshlflags)
+{
+ struct uia_rsrv_ftmarshaler *marshaler = impl_uia_rsrv_ft_from_IMarshal(iface);
+ TRACE("%p, %s, %p, %#x, %p, %#x\n", stream, debugstr_guid(riid), pv, dest_context, pvDestContext, mshlflags);
+ return IMarshal_MarshalInterface(marshaler->marshal, stream, riid, pv, dest_context, pvDestContext, mshlflags);
+}
+
+static HRESULT WINAPI uia_rsrv_ftmarshaler_UnmarshalInterface(IMarshal *iface, IStream *stream, REFIID riid, void **ppv)
+{
+ struct uia_rsrv_ftmarshaler *marshaler = impl_uia_rsrv_ft_from_IMarshal(iface);
+ TRACE("%p, %s, %p\n", stream, debugstr_guid(riid), ppv);
+ return IMarshal_UnmarshalInterface(marshaler->marshal, stream, riid, ppv);
+}
+
+static HRESULT WINAPI uia_rsrv_ftmarshaler_ReleaseMarshalData(IMarshal *iface, IStream *stream)
+{
+ struct uia_rsrv_ftmarshaler *marshaler = impl_uia_rsrv_ft_from_IMarshal(iface);
+ TRACE("%p\n", stream);
+ return IMarshal_ReleaseMarshalData(marshaler->marshal, stream);
+}
+
+static HRESULT WINAPI uia_rsrv_ftmarshaler_DisconnectObject(IMarshal *iface, DWORD reserved)
+{
+ struct uia_rsrv_ftmarshaler *marshaler = impl_uia_rsrv_ft_from_IMarshal(iface);
+ TRACE("\n");
+ return IMarshal_DisconnectObject(marshaler->marshal, reserved);
+}
+
+static const IMarshalVtbl uia_rsrv_ftmarshaler_vtbl =
+{
+ uia_rsrv_ftmarshaler_QueryInterface,
+ uia_rsrv_ftmarshaler_AddRef,
+ uia_rsrv_ftmarshaler_Release,
+ uia_rsrv_ftmarshaler_GetUnmarshalClass,
+ uia_rsrv_ftmarshaler_GetMarshalSizeMax,
+ uia_rsrv_ftmarshaler_MarshalInterface,
+ uia_rsrv_ftmarshaler_UnmarshalInterface,
+ uia_rsrv_ftmarshaler_ReleaseMarshalData,
+ uia_rsrv_ftmarshaler_DisconnectObject
+};
+
+/*
+ * When passing the ReservedNotSupportedValue/ReservedMixedAttributeValue
+ * interface pointers across apartments within the same process, use the
+ * free threaded marshaler to preserve the pointer value. Wrap the IMarshal
+ * interface received by CoCreateFreeThreadedMarshaler so that we can maintain
+ * our own reference count and release the object when it hits 0.
+ */
+static HRESULT uia_reserved_val_create_ftm(IUnknown *outer, IMarshal **marshaler)
+{
+ struct uia_rsrv_ftmarshaler *object;
+ IUnknown *ftm_unk;
+ HRESULT hr;
+
+ TRACE("%p, %p\n", outer, marshaler);
+
+ hr = CoCreateFreeThreadedMarshaler(outer, &ftm_unk);
+ if (FAILED(hr)) return hr;
+
+ object = heap_alloc(sizeof(*object));
+ if (!object)
+ {
+ IUnknown_Release(ftm_unk);
+ return E_OUTOFMEMORY;
+ }
+
+ object->IMarshal_iface.lpVtbl = &uia_rsrv_ftmarshaler_vtbl;
+ object->inner_unk = ftm_unk;
+ hr = IUnknown_QueryInterface(ftm_unk, &IID_IMarshal, (void **)&object->marshal);
+ if (FAILED(hr))
+ FIXME("Failed to QI for IMarshal.\n");
+
+ *marshaler = &object->IMarshal_iface;
+
+ return S_OK;
+}
+
+/*
+ * UiaReservedNotSupported object.
+ */
+static HRESULT WINAPI uia_reserved_ns_QueryInterface(IUnknown *iface,
+ REFIID riid, void **ppv)
+{
+ *ppv = NULL;
+ if (IsEqualIID(riid, &IID_IUnknown))
+ *ppv = iface;
+ else if (IsEqualIID(riid, &IID_IMarshal))
+ {
+ IMarshal *ftm;
+
+ if (FAILED(uia_reserved_val_create_ftm(iface, &ftm)))
+ return E_NOINTERFACE;
+ *ppv = ftm;
+ }
+ else
+ return E_NOINTERFACE;
+
+ return S_OK;
+}
+
+static ULONG WINAPI uia_reserved_ns_AddRef(IUnknown *iface)
+{
+ return 1;
+}
+
+static ULONG WINAPI uia_reserved_ns_Release(IUnknown *iface)
+{
+ return 1;
+}
+
+static const IUnknownVtbl uia_reserved_ns_vtbl = {
+ uia_reserved_ns_QueryInterface,
+ uia_reserved_ns_AddRef,
+ uia_reserved_ns_Release,
+};
+
+static IUnknown uia_reserved_ns_iface = {&uia_reserved_ns_vtbl};
+
/***********************************************************************
* UiaClientsAreListening (uiautomationcore.@)
*/
@@ -46,8 +233,13 @@ HRESULT WINAPI UiaGetReservedMixedAttributeValue(IUnknown **value)
*/
HRESULT WINAPI UiaGetReservedNotSupportedValue(IUnknown **value)
{
- FIXME("(%p) stub!\n", value);
- *value = NULL;
+ TRACE("(%p)\n", value);
+
+ if (!value)
+ return E_INVALIDARG;
+
+ *value = &uia_reserved_ns_iface;
+
return S_OK;
}
--
2.25.1
2
7
[PATCH v2] include: Add async_uuid for IBackgroundCopyCallback in bits.idl
by Biswapriyo Nath Oct. 27, 2021
by Biswapriyo Nath Oct. 27, 2021
Oct. 27, 2021
3
2
Oct. 27, 2021
Always build the Mac preloader with '-mmacosx-version-min=10.7', which
works with all supported toolchains.
Fixes bug when building with Xcode 9 where preloader flags would be added
to EXTRACFLAGS and cause build failures on 32-bit.
Signed-off-by: Brendan Shanks <bshanks(a)codeweavers.com>
---
configure.ac | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/configure.ac b/configure.ac
index b8356679e63..ef0d09e974d 100644
--- a/configure.ac
+++ b/configure.ac
@@ -739,14 +739,12 @@ case $host_os in
WINEPRELOADER_LDFLAGS="-nostartfiles -nodefaultlibs -e _start -ldylib1.o -Wl,-image_base,0x7d400000,-segalign,0x1000,-pagezero_size,0x1000,-sectcreate,__TEXT,__info_plist,loader/wine_info.plist,-segaddr,WINE_4GB_RESERVE,0x100000000"
WINE_TRY_CFLAGS([-Wl,-no_new_main -e _main],
[WINEPRELOADER_LDFLAGS="-Wl,-no_new_main $WINEPRELOADER_LDFLAGS"
- WINE_TRY_CFLAGS([-Wl,-no_new_main -e _main -nostartfiles -nodefaultlibs],,
- [WINE_TRY_CFLAGS([-Wl,-no_new_main -e _main -mmacosx-version-min=10.7 -nostartfiles -nodefaultlibs],
- [WINEPRELOADER_LDFLAGS="-mmacosx-version-min=10.7 $WINEPRELOADER_LDFLAGS"],
- [wine_can_build_preloader=no])])],
- [WINE_TRY_CFLAGS([-nostartfiles -nodefaultlibs],,
- [WINE_TRY_CFLAGS([-mmacosx-version-min=10.7 -nostartfiles -nodefaultlibs],
- [WINEPRELOADER_LDFLAGS="-mmacosx-version-min=10.7 $WINEPRELOADER_LDFLAGS"],
- [wine_can_build_preloader=no])])])
+ WINE_TRY_CFLAGS([-Wl,-no_new_main -e _main -mmacosx-version-min=10.7 -nostartfiles -nodefaultlibs],
+ [WINEPRELOADER_LDFLAGS="-mmacosx-version-min=10.7 $WINEPRELOADER_LDFLAGS"],
+ [wine_can_build_preloader=no])],
+ [WINE_TRY_CFLAGS([-mmacosx-version-min=10.7 -nostartfiles -nodefaultlibs],
+ [WINEPRELOADER_LDFLAGS="-mmacosx-version-min=10.7 $WINEPRELOADER_LDFLAGS"],
+ [wine_can_build_preloader=no])])
if test "$wine_can_build_preloader" = "yes"
then
WINE_TRY_CFLAGS([-Wl,-no_pie],
--
2.30.1 (Apple Git-130)
1
0
Hello Brent,
Seems to work fine for me using your Makefile after fixing a few casing
issues, undefined functions and creating the Debug folder.
Are you working on a Linux filesystem where you have enough permissions? There
seems to be something very weird with your setup.
Your not running under WSL or have some other uncommon setup, right?
Regards,
Fabian Maurer
2
1
I'm not sure if this mailing list is the correct place to ask for porting help, as it seems to be solely dedicated to improving WINE, but the forums on the web site seem mostly for using WINE to run programs directly, not using it for porting. If there is a better place for this query, please let me know.
So... the wine wrapper seems to run our application GUI just fine, however we need to marry the Win32 GUI code to system-level accesses so that we can port the application to Linux. I was having some luck using version 5.0, but had to do some weird linking shenanigans and using pipes to channel data from the linux side to the windows side and vice versa... it was too cumbersome and slow for our purposes, so we walked away. Hearing of version 6, we thought this new architecture might solve our problems so threw together an exploratory project simply to show that it could work. Unfortunately, I've been having some issues and having a hard time determining where they are.
If I leave out the resources and compile with the -v option, this is the build/linking step (the .onlx is a gcc direct-compiled .o file... I've also tried it as an actual .o file in case that is confusing winebuild... same result.)
winegcc -o Debug/winetest.exe -v -mwindows Debug/WINETEST.o Debug/SERVICE.o Debug/USERCODE.o Debug/CLIENT.o Debug/linux.olnx
/opt/wine-devel/bin/winebuild -v -fno-asynchronous-unwind-tables "--cc-cmd=/usr/bin/gcc -m64" --ld-cmd=/usr/bin/ld -fPIC --exe -o winetest.exe-61799713.spec.o -F winetest.exe --subsystem windows -L/opt/wine-devel/bin/../lib64/wine/x86_64-unix -L/opt/wine-devel/bin/../lib64 -- Debug/WINETEST.o Debug/SERVICE.o Debug/USERCODE.o Debug/CLIENT.o /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libshell32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libcomdlg32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libgdi32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libadvapi32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libuser32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libwinecrt0.a /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libkernel32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libntdll.def
winebuild: Unable to create output file 'winetest.exe-61799713.spec-61799714.s'
winegcc: /opt/wine-devel/bin/winebuild failed
make: *** [Makefile:90: all] Error 2
So, one of these subprocesses is trying to create a .s file on the way to creating the .o file, and having issues? I note a few problems that seem to exist... one, the folder for the EXE doesn't seem to be getting passed to winebuild (-F winetest.exe instead of -F Debug/winetest.exe) and the -o winetest.exe-61799713.spec.o is similarly not specifying a folder. However adding a Debug in front of them manually doesn't do anything so I don't think that's the basic problem.
/opt/wine-devel/bin/winebuild -v -fno-asynchronous-unwind-tables "--cc-cmd=/usr/bin/gcc -m64" --ld-cmd=/usr/bin/ld -fPIC --exe -o Debug/winetest.exe-61799713.spec.o -F Debug/winetest.exe --subsystem windows -L/opt/wine-devel/bin/../lib64/wine/x86_64-unix -L/opt/wine-devel/bin/../lib64 -- Debug/WINETEST.o Debug/SERVICE.o Debug/USERCODE.o Debug/CLIENT.o /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libshell32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libcomdlg32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libgdi32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libadvapi32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libuser32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libwinecrt0.a /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libkernel32.def /opt/wine-devel/bin/../lib64/wine/x86_64-unix/libntdll.def
winebuild: Unable to create output file 'winetest.exe-61799713.spec-61799cc7.s'
Any ideas on what I'm doing wrong? Bad environmental variables or other flags that need to be added? Attached is a copy of my makefile, designed so that I can pull from multiple source folders, keep track of Win32 vs linux source files, etc. It has various dummy targets to more easily experiment with different things or dump variable lists. Attaching the var_o and tar_c outputs as well, just to demonstrate the input values
I also experimented with trying to do things with gcc and ld, but didn't come across any breakthroughs.
In a similar vein, and probably related, I can't get WRC to work either. If I comment in RCflags to get debug level 31, I get the output in rc_debug31.txt in the same folder as my Makefile (ie. Writable folder)
The error output normally seems pretty non-sensical as the .res file should be an output?
wrc -foDebug/WINETEST.res WINETEST.RC
Error: Could not open Debug/WINETEST.res-61799fb9 for input : Permission denied
make: *** [Makefile:144: Debug/WINETEST.res] Error 2
This is a much simpler test program than our actual program to port, and I can't even seem to get this one to compile... it's frustrating. I'd love to be able to use WINE to support Linux servers, etc, but I'm stuck.
Any pointers people could offer would be greatly appreciated.
Thank you,
Brent
3
3
Oct. 27, 2021
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/ntdll/tests/Makefile.in | 1 +
dlls/ntdll/tests/om.c | 574 -------------------------------
dlls/ntdll/tests/sync.c | 631 +++++++++++++++++++++++++++++++++++
3 files changed, 632 insertions(+), 574 deletions(-)
create mode 100644 dlls/ntdll/tests/sync.c
diff --git a/dlls/ntdll/tests/Makefile.in b/dlls/ntdll/tests/Makefile.in
index 7ad39e0992c..8c6a86fb965 100644
--- a/dlls/ntdll/tests/Makefile.in
+++ b/dlls/ntdll/tests/Makefile.in
@@ -21,6 +21,7 @@ C_SRCS = \
rtlbitmap.c \
rtlstr.c \
string.c \
+ sync.c \
threadpool.c \
time.c \
virtual.c \
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index af5e014f069..77eb58a23b5 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -30,10 +30,6 @@
static VOID (WINAPI *pRtlInitUnicodeString)( PUNICODE_STRING, LPCWSTR );
static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, EVENT_TYPE, BOOLEAN);
static NTSTATUS (WINAPI *pNtOpenEvent) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES);
-static NTSTATUS (WINAPI *pNtPulseEvent) ( HANDLE, PLONG );
-static NTSTATUS (WINAPI *pNtQueryEvent) ( HANDLE, EVENT_INFORMATION_CLASS, PVOID, ULONG, PULONG );
-static NTSTATUS (WINAPI *pNtResetEvent) ( HANDLE, LONG* );
-static NTSTATUS (WINAPI *pNtSetEvent) ( HANDLE, LONG* );
static NTSTATUS (WINAPI *pNtCreateJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
static NTSTATUS (WINAPI *pNtOpenJobObject)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
static NTSTATUS (WINAPI *pNtCreateKey)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG,
@@ -44,11 +40,8 @@ static NTSTATUS (WINAPI *pNtCreateMailslotFile)( PHANDLE, ACCESS_MASK, POBJECT_A
ULONG, ULONG, ULONG, PLARGE_INTEGER );
static NTSTATUS (WINAPI *pNtCreateMutant)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, BOOLEAN );
static NTSTATUS (WINAPI *pNtOpenMutant) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
-static NTSTATUS (WINAPI *pNtQueryMutant) ( HANDLE, MUTANT_INFORMATION_CLASS, PVOID, ULONG, PULONG );
-static NTSTATUS (WINAPI *pNtReleaseMutant)( HANDLE, PLONG );
static NTSTATUS (WINAPI *pNtCreateSemaphore)( PHANDLE, ACCESS_MASK,const POBJECT_ATTRIBUTES,LONG,LONG );
static NTSTATUS (WINAPI *pNtOpenSemaphore)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
-static NTSTATUS (WINAPI *pNtQuerySemaphore)( PHANDLE, SEMAPHORE_INFORMATION_CLASS, PVOID, ULONG, PULONG );
static NTSTATUS (WINAPI *pNtCreateTimer) ( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, TIMER_TYPE );
static NTSTATUS (WINAPI *pNtOpenTimer)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES );
static NTSTATUS (WINAPI *pNtCreateSection)( PHANDLE, ACCESS_MASK, const POBJECT_ATTRIBUTES, const PLARGE_INTEGER,
@@ -67,15 +60,9 @@ static NTSTATUS (WINAPI *pNtQueryObject)(HANDLE,OBJECT_INFORMATION_CLASS,PVOID,U
static NTSTATUS (WINAPI *pNtReleaseSemaphore)(HANDLE, ULONG, PULONG);
static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG );
static NTSTATUS (WINAPI *pNtOpenKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
-static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
-static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
static NTSTATUS (WINAPI *pNtCreateIoCompletion)(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG);
static NTSTATUS (WINAPI *pNtOpenIoCompletion)( PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES );
static NTSTATUS (WINAPI *pNtQueryInformationFile)(HANDLE, PIO_STATUS_BLOCK, void *, ULONG, FILE_INFORMATION_CLASS);
-static NTSTATUS (WINAPI *pNtQuerySystemTime)( LARGE_INTEGER * );
-static NTSTATUS (WINAPI *pRtlWaitOnAddress)( const void *, const void *, SIZE_T, const LARGE_INTEGER * );
-static void (WINAPI *pRtlWakeAddressAll)( const void * );
-static void (WINAPI *pRtlWakeAddressSingle)( const void * );
static NTSTATUS (WINAPI *pNtOpenProcess)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, const CLIENT_ID * );
static NTSTATUS (WINAPI *pNtCreateDebugObject)( HANDLE *, ACCESS_MASK, OBJECT_ATTRIBUTES *, ULONG );
static NTSTATUS (WINAPI *pNtGetNextThread)(HANDLE process, HANDLE thread, ACCESS_MASK access, ULONG attributes,
@@ -1939,286 +1926,6 @@ static void test_type_mismatch(void)
pNtClose( h );
}
-static void test_event(void)
-{
- HANDLE Event;
- HANDLE Event2;
- LONG prev_state = 0xdeadbeef;
- NTSTATUS status;
- UNICODE_STRING str;
- OBJECT_ATTRIBUTES attr;
- EVENT_BASIC_INFORMATION info;
-
- pRtlInitUnicodeString( &str, L"\\BaseNamedObjects\\testEvent" );
- InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
-
- status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, 2, 0);
- ok( status == STATUS_INVALID_PARAMETER, "NtCreateEvent failed %08x\n", status );
-
- status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, NotificationEvent, 0);
- ok( status == STATUS_SUCCESS, "NtCreateEvent failed %08x\n", status );
- memset(&info, 0xcc, sizeof(info));
- status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
- ok( info.EventType == NotificationEvent && info.EventState == 0,
- "NtQueryEvent failed, expected 0 0, got %d %d\n", info.EventType, info.EventState );
- pNtClose(Event);
-
- status = pNtCreateEvent(&Event, GENERIC_ALL, &attr, SynchronizationEvent, 0);
- ok( status == STATUS_SUCCESS, "NtCreateEvent failed %08x\n", status );
-
- status = pNtPulseEvent(Event, &prev_state);
- ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
- ok( !prev_state, "prev_state = %x\n", prev_state );
-
- memset(&info, 0xcc, sizeof(info));
- status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
- ok( info.EventType == SynchronizationEvent && info.EventState == 0,
- "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
-
- status = pNtOpenEvent(&Event2, GENERIC_ALL, &attr);
- ok( status == STATUS_SUCCESS, "NtOpenEvent failed %08x\n", status );
-
- pNtClose(Event);
- Event = Event2;
-
- memset(&info, 0xcc, sizeof(info));
- status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
- ok( info.EventType == SynchronizationEvent && info.EventState == 0,
- "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
-
- status = pNtSetEvent( Event, &prev_state );
- ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
- ok( !prev_state, "prev_state = %x\n", prev_state );
-
- memset(&info, 0xcc, sizeof(info));
- status = pNtQueryEvent(Event, EventBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
- ok( info.EventType == SynchronizationEvent && info.EventState == 1,
- "NtQueryEvent failed, expected 1 1, got %d %d\n", info.EventType, info.EventState );
-
- status = pNtSetEvent( Event, &prev_state );
- ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
- ok( prev_state == 1, "prev_state = %x\n", prev_state );
-
- status = pNtResetEvent( Event, &prev_state );
- ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
- ok( prev_state == 1, "prev_state = %x\n", prev_state );
-
- status = pNtResetEvent( Event, &prev_state );
- ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
- ok( !prev_state, "prev_state = %x\n", prev_state );
-
- status = pNtPulseEvent( Event, &prev_state );
- ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
- ok( !prev_state, "prev_state = %x\n", prev_state );
-
- status = pNtSetEvent( Event, &prev_state );
- ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
- ok( !prev_state, "prev_state = %x\n", prev_state );
-
- status = pNtPulseEvent( Event, &prev_state );
- ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
- ok( prev_state == 1, "prev_state = %x\n", prev_state );
-
- pNtClose(Event);
-}
-
-static const WCHAR keyed_nameW[] = L"\\BaseNamedObjects\\WineTestEvent";
-
-static DWORD WINAPI keyed_event_thread( void *arg )
-{
- HANDLE handle;
- NTSTATUS status;
- LARGE_INTEGER timeout;
- OBJECT_ATTRIBUTES attr;
- UNICODE_STRING str;
- ULONG_PTR i;
-
- attr.Length = sizeof(attr);
- attr.RootDirectory = 0;
- attr.ObjectName = &str;
- attr.Attributes = 0;
- attr.SecurityDescriptor = NULL;
- attr.SecurityQualityOfService = NULL;
- RtlInitUnicodeString( &str, keyed_nameW );
-
- status = pNtOpenKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr );
- ok( !status, "NtOpenKeyedEvent failed %x\n", status );
-
- for (i = 0; i < 20; i++)
- {
- if (i & 1)
- status = pNtWaitForKeyedEvent( handle, (void *)(i * 2), 0, NULL );
- else
- status = pNtReleaseKeyedEvent( handle, (void *)(i * 2), 0, NULL );
- ok( status == STATUS_SUCCESS, "%li: failed %x\n", i, status );
- Sleep( 20 - i );
- }
-
- status = pNtReleaseKeyedEvent( handle, (void *)0x1234, 0, NULL );
- ok( status == STATUS_SUCCESS, "NtReleaseKeyedEvent %x\n", status );
-
- timeout.QuadPart = -10000;
- status = pNtWaitForKeyedEvent( handle, (void *)0x5678, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( handle, (void *)0x9abc, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
-
- NtClose( handle );
- return 0;
-}
-
-static void test_keyed_events(void)
-{
- OBJECT_ATTRIBUTES attr;
- UNICODE_STRING str;
- HANDLE handle, event, thread;
- NTSTATUS status;
- LARGE_INTEGER timeout;
- ULONG_PTR i;
-
- if (!pNtCreateKeyedEvent)
- {
- win_skip( "Keyed events not supported\n" );
- return;
- }
-
- attr.Length = sizeof(attr);
- attr.RootDirectory = 0;
- attr.ObjectName = &str;
- attr.Attributes = 0;
- attr.SecurityDescriptor = NULL;
- attr.SecurityQualityOfService = NULL;
- RtlInitUnicodeString( &str, keyed_nameW );
-
- status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS | SYNCHRONIZE, &attr, 0 );
- ok( !status, "NtCreateKeyedEvent failed %x\n", status );
-
- status = WaitForSingleObject( handle, 1000 );
- ok( status == 0, "WaitForSingleObject %x\n", status );
-
- timeout.QuadPart = -100000;
- status = pNtWaitForKeyedEvent( handle, (void *)255, 0, &timeout );
- ok( status == STATUS_INVALID_PARAMETER_1, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( handle, (void *)255, 0, &timeout );
- ok( status == STATUS_INVALID_PARAMETER_1, "NtReleaseKeyedEvent %x\n", status );
-
- status = pNtWaitForKeyedEvent( handle, (void *)254, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( handle, (void *)254, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
-
- status = pNtWaitForKeyedEvent( handle, NULL, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( handle, NULL, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
-
- status = pNtWaitForKeyedEvent( NULL, (void *)8, 0, &timeout );
- ok( status == STATUS_TIMEOUT || broken(status == STATUS_INVALID_HANDLE), /* XP/2003 */
- "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( NULL, (void *)8, 0, &timeout );
- ok( status == STATUS_TIMEOUT || broken(status == STATUS_INVALID_HANDLE), /* XP/2003 */
- "NtReleaseKeyedEvent %x\n", status );
-
- status = pNtWaitForKeyedEvent( (HANDLE)0xdeadbeef, (void *)9, 0, &timeout );
- ok( status == STATUS_INVALID_PARAMETER_1, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( (HANDLE)0xdeadbeef, (void *)9, 0, &timeout );
- ok( status == STATUS_INVALID_PARAMETER_1, "NtReleaseKeyedEvent %x\n", status );
-
- status = pNtWaitForKeyedEvent( (HANDLE)0xdeadbeef, (void *)8, 0, &timeout );
- ok( status == STATUS_INVALID_HANDLE, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( (HANDLE)0xdeadbeef, (void *)8, 0, &timeout );
- ok( status == STATUS_INVALID_HANDLE, "NtReleaseKeyedEvent %x\n", status );
-
- thread = CreateThread( NULL, 0, keyed_event_thread, 0, 0, NULL );
- for (i = 0; i < 20; i++)
- {
- if (i & 1)
- status = pNtReleaseKeyedEvent( handle, (void *)(i * 2), 0, NULL );
- else
- status = pNtWaitForKeyedEvent( handle, (void *)(i * 2), 0, NULL );
- ok( status == STATUS_SUCCESS, "%li: failed %x\n", i, status );
- Sleep( i );
- }
- status = pNtWaitForKeyedEvent( handle, (void *)0x1234, 0, &timeout );
- ok( status == STATUS_SUCCESS, "NtWaitForKeyedEvent %x\n", status );
- status = pNtWaitForKeyedEvent( handle, (void *)0x5678, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( handle, (void *)0x9abc, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
-
- ok( WaitForSingleObject( thread, 30000 ) == 0, "wait failed\n" );
-
- NtClose( handle );
-
- /* test access rights */
-
- status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_WAIT, &attr, 0 );
- ok( !status, "NtCreateKeyedEvent failed %x\n", status );
- status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
- ok( status == STATUS_ACCESS_DENIED, "NtReleaseKeyedEvent %x\n", status );
- NtClose( handle );
-
- status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_WAKE, &attr, 0 );
- ok( !status, "NtCreateKeyedEvent failed %x\n", status );
- status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
- ok( status == STATUS_ACCESS_DENIED, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
- NtClose( handle );
-
- status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr, 0 );
- ok( !status, "NtCreateKeyedEvent failed %x\n", status );
- status = WaitForSingleObject( handle, 1000 );
- ok( status == WAIT_FAILED && GetLastError() == ERROR_ACCESS_DENIED,
- "WaitForSingleObject %x err %u\n", status, GetLastError() );
- status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
- NtClose( handle );
-
- /* GENERIC_READ gives wait access */
- status = pNtCreateKeyedEvent( &handle, GENERIC_READ, &attr, 0 );
- ok( !status, "NtCreateKeyedEvent failed %x\n", status );
- status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
- ok( status == STATUS_ACCESS_DENIED, "NtReleaseKeyedEvent %x\n", status );
- NtClose( handle );
-
- /* GENERIC_WRITE gives wake access */
- status = pNtCreateKeyedEvent( &handle, GENERIC_WRITE, &attr, 0 );
- ok( !status, "NtCreateKeyedEvent failed %x\n", status );
- status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
- ok( status == STATUS_ACCESS_DENIED, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
- ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
-
- /* it's not an event */
- status = pNtPulseEvent( handle, NULL );
- ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtPulseEvent %x\n", status );
-
- status = pNtCreateEvent( &event, GENERIC_ALL, &attr, NotificationEvent, FALSE );
- ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH /* 7+ */,
- "CreateEvent %x\n", status );
-
- NtClose( handle );
-
- status = pNtCreateEvent( &event, GENERIC_ALL, &attr, NotificationEvent, FALSE );
- ok( status == 0, "CreateEvent %x\n", status );
- status = pNtWaitForKeyedEvent( event, (void *)8, 0, &timeout );
- ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtWaitForKeyedEvent %x\n", status );
- status = pNtReleaseKeyedEvent( event, (void *)8, 0, &timeout );
- ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtReleaseKeyedEvent %x\n", status );
- NtClose( event );
-}
-
static void test_null_device(void)
{
OBJECT_ATTRIBUTES attr;
@@ -2292,269 +1999,6 @@ static void test_null_device(void)
CloseHandle(ov.hEvent);
}
-static DWORD WINAPI mutant_thread( void *arg )
-{
- MUTANT_BASIC_INFORMATION info;
- NTSTATUS status;
- HANDLE mutant;
- DWORD ret;
-
- mutant = arg;
- ret = WaitForSingleObject( mutant, 1000 );
- ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
-
- memset(&info, 0xcc, sizeof(info));
- status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
- ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
- ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
- ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
- /* abandon mutant */
-
- return 0;
-}
-
-static void test_mutant(void)
-{
- MUTANT_BASIC_INFORMATION info;
- OBJECT_ATTRIBUTES attr;
- UNICODE_STRING str;
- NTSTATUS status;
- HANDLE mutant;
- HANDLE thread;
- DWORD ret;
- ULONG len;
- LONG prev;
-
- pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\test_mutant");
- InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
- status = pNtCreateMutant(&mutant, GENERIC_ALL, &attr, TRUE);
- ok( status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status );
-
- /* bogus */
- status = pNtQueryMutant(mutant, MutantBasicInformation, &info, 0, NULL);
- ok( status == STATUS_INFO_LENGTH_MISMATCH,
- "Failed to NtQueryMutant, expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status );
- status = pNtQueryMutant(mutant, 0x42, &info, sizeof(info), NULL);
- ok( status == STATUS_INVALID_INFO_CLASS || broken(status == STATUS_NOT_IMPLEMENTED), /* 32-bit on Vista/2k8 */
- "Failed to NtQueryMutant, expected STATUS_INVALID_INFO_CLASS, got %08x\n", status );
- status = pNtQueryMutant((HANDLE)0xdeadbeef, MutantBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_INVALID_HANDLE,
- "Failed to NtQueryMutant, expected STATUS_INVALID_HANDLE, got %08x\n", status );
-
- /* new */
- len = -1;
- memset(&info, 0xcc, sizeof(info));
- status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), &len);
- ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
- ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
- ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
- ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
- ok( len == sizeof(info), "got %u\n", len );
-
- ret = WaitForSingleObject( mutant, 1000 );
- ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
-
- memset(&info, 0xcc, sizeof(info));
- status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
- ok( info.CurrentCount == -1, "expected -1, got %d\n", info.CurrentCount );
- ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
- ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
-
- prev = 0xdeadbeef;
- status = pNtReleaseMutant(mutant, &prev);
- ok( status == STATUS_SUCCESS, "NtReleaseMutant failed %08x\n", status );
- ok( prev == -1, "NtReleaseMutant failed, expected -1, got %d\n", prev );
-
- prev = 0xdeadbeef;
- status = pNtReleaseMutant(mutant, &prev);
- ok( status == STATUS_SUCCESS, "NtReleaseMutant failed %08x\n", status );
- ok( prev == 0, "NtReleaseMutant failed, expected 0, got %d\n", prev );
-
- memset(&info, 0xcc, sizeof(info));
- status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
- ok( info.CurrentCount == 1, "expected 1, got %d\n", info.CurrentCount );
- ok( info.OwnedByCaller == FALSE, "expected FALSE, got %d\n", info.OwnedByCaller );
- ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
-
- /* abandoned */
- thread = CreateThread( NULL, 0, mutant_thread, mutant, 0, NULL );
- ret = WaitForSingleObject( thread, 1000 );
- ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
- CloseHandle( thread );
-
- memset(&info, 0xcc, sizeof(info));
- status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
- ok( info.CurrentCount == 1, "expected 0, got %d\n", info.CurrentCount );
- ok( info.OwnedByCaller == FALSE, "expected FALSE, got %d\n", info.OwnedByCaller );
- ok( info.AbandonedState == TRUE, "expected TRUE, got %d\n", info.AbandonedState );
-
- ret = WaitForSingleObject( mutant, 1000 );
- ok( ret == WAIT_ABANDONED_0, "WaitForSingleObject failed %08x\n", ret );
-
- memset(&info, 0xcc, sizeof(info));
- status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
- ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
- ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
- ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
-
- NtClose( mutant );
-}
-
-static void test_semaphore(void)
-{
- SEMAPHORE_BASIC_INFORMATION info;
- OBJECT_ATTRIBUTES attr;
- UNICODE_STRING str;
- NTSTATUS status;
- HANDLE semaphore;
- ULONG prev;
- ULONG len;
- DWORD ret;
-
- pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\test_semaphore");
- InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
-
- status = pNtCreateSemaphore(&semaphore, GENERIC_ALL, &attr, 2, 1);
- ok( status == STATUS_INVALID_PARAMETER, "Failed to create Semaphore(%08x)\n", status );
- status = pNtCreateSemaphore(&semaphore, GENERIC_ALL, &attr, 1, 2);
- ok( status == STATUS_SUCCESS, "Failed to create Semaphore(%08x)\n", status );
-
- /* bogus */
- status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, 0, NULL);
- ok( status == STATUS_INFO_LENGTH_MISMATCH,
- "Failed to NtQuerySemaphore, expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status );
- status = pNtQuerySemaphore(semaphore, 0x42, &info, sizeof(info), NULL);
- ok( status == STATUS_INVALID_INFO_CLASS,
- "Failed to NtQuerySemaphore, expected STATUS_INVALID_INFO_CLASS, got %08x\n", status );
- status = pNtQuerySemaphore((HANDLE)0xdeadbeef, SemaphoreBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_INVALID_HANDLE,
- "Failed to NtQuerySemaphore, expected STATUS_INVALID_HANDLE, got %08x\n", status );
-
- len = -1;
- memset(&info, 0xcc, sizeof(info));
- status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), &len);
- ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
- ok( info.CurrentCount == 1, "expected 1, got %d\n", info.CurrentCount );
- ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
- ok( len == sizeof(info), "got %u\n", len );
-
- ret = WaitForSingleObject( semaphore, 1000 );
- ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
-
- memset(&info, 0xcc, sizeof(info));
- status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
- ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
- ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
-
- prev = 0xdeadbeef;
- status = pNtReleaseSemaphore(semaphore, 3, &prev);
- ok( status == STATUS_SEMAPHORE_LIMIT_EXCEEDED, "NtReleaseSemaphore failed %08x\n", status );
- ok( prev == 0xdeadbeef, "NtReleaseSemaphore failed, expected 0xdeadbeef, got %d\n", prev );
-
- prev = 0xdeadbeef;
- status = pNtReleaseSemaphore(semaphore, 1, &prev);
- ok( status == STATUS_SUCCESS, "NtReleaseSemaphore failed %08x\n", status );
- ok( prev == 0, "NtReleaseSemaphore failed, expected 0, got %d\n", prev );
-
- prev = 0xdeadbeef;
- status = pNtReleaseSemaphore(semaphore, 1, &prev);
- ok( status == STATUS_SUCCESS, "NtReleaseSemaphore failed %08x\n", status );
- ok( prev == 1, "NtReleaseSemaphore failed, expected 1, got %d\n", prev );
-
- prev = 0xdeadbeef;
- status = pNtReleaseSemaphore(semaphore, 1, &prev);
- ok( status == STATUS_SEMAPHORE_LIMIT_EXCEEDED, "NtReleaseSemaphore failed %08x\n", status );
- ok( prev == 0xdeadbeef, "NtReleaseSemaphore failed, expected 0xdeadbeef, got %d\n", prev );
-
- memset(&info, 0xcc, sizeof(info));
- status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), NULL);
- ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
- ok( info.CurrentCount == 2, "expected 2, got %d\n", info.CurrentCount );
- ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
-
- NtClose( semaphore );
-}
-
-static void test_wait_on_address(void)
-{
- SIZE_T size;
- NTSTATUS status;
- LARGE_INTEGER start, end, timeout;
- DWORD elapsed;
- LONG64 address, compare;
-
- if (!pRtlWaitOnAddress)
- {
- win_skip("RtlWaitOnAddress not supported, skipping test\n");
- return;
- }
-
- if (0) /* crash on Windows */
- {
- pRtlWaitOnAddress(&address, NULL, 8, NULL);
- pRtlWaitOnAddress(NULL, &compare, 8, NULL);
- pRtlWaitOnAddress(NULL, NULL, 8, NULL);
- }
-
- /* don't crash */
- pRtlWakeAddressSingle(NULL);
- pRtlWakeAddressAll(NULL);
-
- /* invalid values */
- address = 0;
- compare = 0;
- status = pRtlWaitOnAddress(&address, &compare, 5, NULL);
- ok(status == STATUS_INVALID_PARAMETER, "got %x\n", status);
-
- /* values match */
- address = 0;
- compare = 0;
- pNtQuerySystemTime(&start);
- timeout.QuadPart = start.QuadPart + 100 * 10000;
- status = pRtlWaitOnAddress(&address, &compare, 8, &timeout);
- pNtQuerySystemTime(&end);
- ok(status == STATUS_TIMEOUT, "got 0x%08x\n", status);
- elapsed = (end.QuadPart - start.QuadPart) / 10000;
- ok(90 <= elapsed && elapsed <= 900, "timed out in %u ms\n", elapsed);
- ok(address == 0, "got %s\n", wine_dbgstr_longlong(address));
- ok(compare == 0, "got %s\n", wine_dbgstr_longlong(compare));
-
- /* different address size */
- for (size = 1; size <= 4; size <<= 1)
- {
- compare = ~0;
- compare <<= size * 8;
-
- pNtQuerySystemTime(&start);
- timeout.QuadPart = -100 * 10000;
- status = pRtlWaitOnAddress(&address, &compare, size, &timeout);
- pNtQuerySystemTime(&end);
- ok(status == STATUS_TIMEOUT, "got 0x%08x\n", status);
- elapsed = (end.QuadPart - start.QuadPart) / 10000;
- ok(90 <= elapsed && elapsed <= 900, "timed out in %u ms\n", elapsed);
-
- status = pRtlWaitOnAddress(&address, &compare, size << 1, &timeout);
- ok(!status, "got 0x%08x\n", status);
- }
- address = 0;
- compare = 1;
- status = pRtlWaitOnAddress(&address, &compare, 8, NULL);
- ok(!status, "got 0x%08x\n", status);
-
- /* no waiters */
- address = 0;
- pRtlWakeAddressSingle(&address);
- ok(address == 0, "got %s\n", wine_dbgstr_longlong(address));
- pRtlWakeAddressAll(&address);
- ok(address == 0, "got %s\n", wine_dbgstr_longlong(address));
-}
-
static void test_process(void)
{
OBJECT_ATTRIBUTES attr;
@@ -2957,13 +2401,7 @@ START_TEST(om)
pNtCreateMailslotFile = (void *)GetProcAddress(hntdll, "NtCreateMailslotFile");
pNtCreateMutant = (void *)GetProcAddress(hntdll, "NtCreateMutant");
pNtOpenEvent = (void *)GetProcAddress(hntdll, "NtOpenEvent");
- pNtQueryEvent = (void *)GetProcAddress(hntdll, "NtQueryEvent");
- pNtPulseEvent = (void *)GetProcAddress(hntdll, "NtPulseEvent");
- pNtResetEvent = (void *)GetProcAddress(hntdll, "NtResetEvent");
- pNtSetEvent = (void *)GetProcAddress(hntdll, "NtSetEvent");
pNtOpenMutant = (void *)GetProcAddress(hntdll, "NtOpenMutant");
- pNtQueryMutant = (void *)GetProcAddress(hntdll, "NtQueryMutant");
- pNtReleaseMutant = (void *)GetProcAddress(hntdll, "NtReleaseMutant");
pNtOpenFile = (void *)GetProcAddress(hntdll, "NtOpenFile");
pNtClose = (void *)GetProcAddress(hntdll, "NtClose");
pRtlInitUnicodeString = (void *)GetProcAddress(hntdll, "RtlInitUnicodeString");
@@ -2975,7 +2413,6 @@ START_TEST(om)
pNtQuerySymbolicLinkObject = (void *)GetProcAddress(hntdll, "NtQuerySymbolicLinkObject");
pNtCreateSemaphore = (void *)GetProcAddress(hntdll, "NtCreateSemaphore");
pNtOpenSemaphore = (void *)GetProcAddress(hntdll, "NtOpenSemaphore");
- pNtQuerySemaphore = (void *)GetProcAddress(hntdll, "NtQuerySemaphore");
pNtCreateTimer = (void *)GetProcAddress(hntdll, "NtCreateTimer");
pNtOpenTimer = (void *)GetProcAddress(hntdll, "NtOpenTimer");
pNtCreateSection = (void *)GetProcAddress(hntdll, "NtCreateSection");
@@ -2984,15 +2421,9 @@ START_TEST(om)
pNtReleaseSemaphore = (void *)GetProcAddress(hntdll, "NtReleaseSemaphore");
pNtCreateKeyedEvent = (void *)GetProcAddress(hntdll, "NtCreateKeyedEvent");
pNtOpenKeyedEvent = (void *)GetProcAddress(hntdll, "NtOpenKeyedEvent");
- pNtWaitForKeyedEvent = (void *)GetProcAddress(hntdll, "NtWaitForKeyedEvent");
- pNtReleaseKeyedEvent = (void *)GetProcAddress(hntdll, "NtReleaseKeyedEvent");
pNtCreateIoCompletion = (void *)GetProcAddress(hntdll, "NtCreateIoCompletion");
pNtOpenIoCompletion = (void *)GetProcAddress(hntdll, "NtOpenIoCompletion");
pNtQueryInformationFile = (void *)GetProcAddress(hntdll, "NtQueryInformationFile");
- pNtQuerySystemTime = (void *)GetProcAddress(hntdll, "NtQuerySystemTime");
- pRtlWaitOnAddress = (void *)GetProcAddress(hntdll, "RtlWaitOnAddress");
- pRtlWakeAddressAll = (void *)GetProcAddress(hntdll, "RtlWakeAddressAll");
- pRtlWakeAddressSingle = (void *)GetProcAddress(hntdll, "RtlWakeAddressSingle");
pNtOpenProcess = (void *)GetProcAddress(hntdll, "NtOpenProcess");
pNtCreateDebugObject = (void *)GetProcAddress(hntdll, "NtCreateDebugObject");
pNtGetNextThread = (void *)GetProcAddress(hntdll, "NtGetNextThread");
@@ -3009,12 +2440,7 @@ START_TEST(om)
test_symboliclink();
test_query_object();
test_type_mismatch();
- test_event();
- test_mutant();
- test_semaphore();
- test_keyed_events();
test_null_device();
- test_wait_on_address();
test_process();
test_token();
test_duplicate_object();
diff --git a/dlls/ntdll/tests/sync.c b/dlls/ntdll/tests/sync.c
new file mode 100644
index 00000000000..7e389c9762b
--- /dev/null
+++ b/dlls/ntdll/tests/sync.c
@@ -0,0 +1,631 @@
+/*
+ * Unit tests for NT synchronization objects
+ *
+ * Copyright 2020 Zebediah Figura
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "windef.h"
+#include "winternl.h"
+#include "wine/test.h"
+
+static NTSTATUS (WINAPI *pNtClose)( HANDLE );
+static NTSTATUS (WINAPI *pNtCreateEvent) ( PHANDLE, ACCESS_MASK, const OBJECT_ATTRIBUTES *, EVENT_TYPE, BOOLEAN);
+static NTSTATUS (WINAPI *pNtCreateKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, ULONG );
+static NTSTATUS (WINAPI *pNtCreateMutant)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, BOOLEAN );
+static NTSTATUS (WINAPI *pNtCreateSemaphore)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES *, LONG, LONG );
+static NTSTATUS (WINAPI *pNtOpenEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
+static NTSTATUS (WINAPI *pNtOpenKeyedEvent)( HANDLE *, ACCESS_MASK, const OBJECT_ATTRIBUTES * );
+static NTSTATUS (WINAPI *pNtPulseEvent)( HANDLE, LONG * );
+static NTSTATUS (WINAPI *pNtQueryEvent)( HANDLE, EVENT_INFORMATION_CLASS, void *, ULONG, ULONG * );
+static NTSTATUS (WINAPI *pNtQueryMutant)( HANDLE, MUTANT_INFORMATION_CLASS, void *, ULONG, ULONG * );
+static NTSTATUS (WINAPI *pNtQuerySemaphore)( HANDLE, SEMAPHORE_INFORMATION_CLASS, void *, ULONG, ULONG * );
+static NTSTATUS (WINAPI *pNtQuerySystemTime)( LARGE_INTEGER * );
+static NTSTATUS (WINAPI *pNtReleaseKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
+static NTSTATUS (WINAPI *pNtReleaseMutant)( HANDLE, LONG * );
+static NTSTATUS (WINAPI *pNtReleaseSemaphore)( HANDLE, ULONG, ULONG * );
+static NTSTATUS (WINAPI *pNtResetEvent)( HANDLE, LONG * );
+static NTSTATUS (WINAPI *pNtSetEvent)( HANDLE, LONG * );
+static NTSTATUS (WINAPI *pNtWaitForKeyedEvent)( HANDLE, const void *, BOOLEAN, const LARGE_INTEGER * );
+static void (WINAPI *pRtlInitUnicodeString)( UNICODE_STRING *, const WCHAR * );
+static NTSTATUS (WINAPI *pRtlWaitOnAddress)( const void *, const void *, SIZE_T, const LARGE_INTEGER * );
+static void (WINAPI *pRtlWakeAddressAll)( const void * );
+static void (WINAPI *pRtlWakeAddressSingle)( const void * );
+
+#define KEYEDEVENT_WAIT 0x0001
+#define KEYEDEVENT_WAKE 0x0002
+#define KEYEDEVENT_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x0003)
+
+static void test_event(void)
+{
+ HANDLE event;
+ HANDLE event2;
+ LONG prev_state = 0xdeadbeef;
+ NTSTATUS status;
+ UNICODE_STRING str;
+ OBJECT_ATTRIBUTES attr;
+ EVENT_BASIC_INFORMATION info;
+
+ pRtlInitUnicodeString( &str, L"\\BaseNamedObjects\\testEvent" );
+ InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
+
+ status = pNtCreateEvent(&event, GENERIC_ALL, &attr, 2, 0);
+ ok( status == STATUS_INVALID_PARAMETER, "NtCreateEvent failed %08x\n", status );
+
+ status = pNtCreateEvent(&event, GENERIC_ALL, &attr, NotificationEvent, 0);
+ ok( status == STATUS_SUCCESS, "NtCreateEvent failed %08x\n", status );
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQueryEvent(event, EventBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
+ ok( info.EventType == NotificationEvent && info.EventState == 0,
+ "NtQueryEvent failed, expected 0 0, got %d %d\n", info.EventType, info.EventState );
+ pNtClose(event);
+
+ status = pNtCreateEvent(&event, GENERIC_ALL, &attr, SynchronizationEvent, 0);
+ ok( status == STATUS_SUCCESS, "NtCreateEvent failed %08x\n", status );
+
+ status = pNtPulseEvent(event, &prev_state);
+ ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
+ ok( !prev_state, "prev_state = %x\n", prev_state );
+
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQueryEvent(event, EventBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
+ ok( info.EventType == SynchronizationEvent && info.EventState == 0,
+ "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
+
+ status = pNtOpenEvent(&event2, GENERIC_ALL, &attr);
+ ok( status == STATUS_SUCCESS, "NtOpenEvent failed %08x\n", status );
+
+ pNtClose(event);
+ event = event2;
+
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQueryEvent(event, EventBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
+ ok( info.EventType == SynchronizationEvent && info.EventState == 0,
+ "NtQueryEvent failed, expected 1 0, got %d %d\n", info.EventType, info.EventState );
+
+ status = pNtSetEvent( event, &prev_state );
+ ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
+ ok( !prev_state, "prev_state = %x\n", prev_state );
+
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQueryEvent(event, EventBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQueryEvent failed %08x\n", status );
+ ok( info.EventType == SynchronizationEvent && info.EventState == 1,
+ "NtQueryEvent failed, expected 1 1, got %d %d\n", info.EventType, info.EventState );
+
+ status = pNtSetEvent( event, &prev_state );
+ ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
+ ok( prev_state == 1, "prev_state = %x\n", prev_state );
+
+ status = pNtResetEvent( event, &prev_state );
+ ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
+ ok( prev_state == 1, "prev_state = %x\n", prev_state );
+
+ status = pNtResetEvent( event, &prev_state );
+ ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
+ ok( !prev_state, "prev_state = %x\n", prev_state );
+
+ status = pNtPulseEvent( event, &prev_state );
+ ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
+ ok( !prev_state, "prev_state = %x\n", prev_state );
+
+ status = pNtSetEvent( event, &prev_state );
+ ok( status == STATUS_SUCCESS, "NtSetEvent failed: %08x\n", status );
+ ok( !prev_state, "prev_state = %x\n", prev_state );
+
+ status = pNtPulseEvent( event, &prev_state );
+ ok( status == STATUS_SUCCESS, "NtPulseEvent failed %08x\n", status );
+ ok( prev_state == 1, "prev_state = %x\n", prev_state );
+
+ pNtClose(event);
+}
+
+static const WCHAR keyed_nameW[] = L"\\BaseNamedObjects\\WineTestEvent";
+
+static DWORD WINAPI keyed_event_thread( void *arg )
+{
+ HANDLE handle;
+ NTSTATUS status;
+ LARGE_INTEGER timeout;
+ OBJECT_ATTRIBUTES attr;
+ UNICODE_STRING str;
+ ULONG_PTR i;
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &str;
+ attr.Attributes = 0;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+ RtlInitUnicodeString( &str, keyed_nameW );
+
+ status = pNtOpenKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr );
+ ok( !status, "NtOpenKeyedEvent failed %x\n", status );
+
+ for (i = 0; i < 20; i++)
+ {
+ if (i & 1)
+ status = pNtWaitForKeyedEvent( handle, (void *)(i * 2), 0, NULL );
+ else
+ status = pNtReleaseKeyedEvent( handle, (void *)(i * 2), 0, NULL );
+ ok( status == STATUS_SUCCESS, "%li: failed %x\n", i, status );
+ Sleep( 20 - i );
+ }
+
+ status = pNtReleaseKeyedEvent( handle, (void *)0x1234, 0, NULL );
+ ok( status == STATUS_SUCCESS, "NtReleaseKeyedEvent %x\n", status );
+
+ timeout.QuadPart = -10000;
+ status = pNtWaitForKeyedEvent( handle, (void *)0x5678, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( handle, (void *)0x9abc, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
+
+ NtClose( handle );
+ return 0;
+}
+
+static void test_keyed_events(void)
+{
+ OBJECT_ATTRIBUTES attr;
+ UNICODE_STRING str;
+ HANDLE handle, event, thread;
+ NTSTATUS status;
+ LARGE_INTEGER timeout;
+ ULONG_PTR i;
+
+ if (!pNtCreateKeyedEvent)
+ {
+ win_skip( "Keyed events not supported\n" );
+ return;
+ }
+
+ attr.Length = sizeof(attr);
+ attr.RootDirectory = 0;
+ attr.ObjectName = &str;
+ attr.Attributes = 0;
+ attr.SecurityDescriptor = NULL;
+ attr.SecurityQualityOfService = NULL;
+ RtlInitUnicodeString( &str, keyed_nameW );
+
+ status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS | SYNCHRONIZE, &attr, 0 );
+ ok( !status, "NtCreateKeyedEvent failed %x\n", status );
+
+ status = WaitForSingleObject( handle, 1000 );
+ ok( status == 0, "WaitForSingleObject %x\n", status );
+
+ timeout.QuadPart = -100000;
+ status = pNtWaitForKeyedEvent( handle, (void *)255, 0, &timeout );
+ ok( status == STATUS_INVALID_PARAMETER_1, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( handle, (void *)255, 0, &timeout );
+ ok( status == STATUS_INVALID_PARAMETER_1, "NtReleaseKeyedEvent %x\n", status );
+
+ status = pNtWaitForKeyedEvent( handle, (void *)254, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( handle, (void *)254, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
+
+ status = pNtWaitForKeyedEvent( handle, NULL, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( handle, NULL, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
+
+ status = pNtWaitForKeyedEvent( NULL, (void *)8, 0, &timeout );
+ ok( status == STATUS_TIMEOUT || broken(status == STATUS_INVALID_HANDLE), /* XP/2003 */
+ "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( NULL, (void *)8, 0, &timeout );
+ ok( status == STATUS_TIMEOUT || broken(status == STATUS_INVALID_HANDLE), /* XP/2003 */
+ "NtReleaseKeyedEvent %x\n", status );
+
+ status = pNtWaitForKeyedEvent( (HANDLE)0xdeadbeef, (void *)9, 0, &timeout );
+ ok( status == STATUS_INVALID_PARAMETER_1, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( (HANDLE)0xdeadbeef, (void *)9, 0, &timeout );
+ ok( status == STATUS_INVALID_PARAMETER_1, "NtReleaseKeyedEvent %x\n", status );
+
+ status = pNtWaitForKeyedEvent( (HANDLE)0xdeadbeef, (void *)8, 0, &timeout );
+ ok( status == STATUS_INVALID_HANDLE, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( (HANDLE)0xdeadbeef, (void *)8, 0, &timeout );
+ ok( status == STATUS_INVALID_HANDLE, "NtReleaseKeyedEvent %x\n", status );
+
+ thread = CreateThread( NULL, 0, keyed_event_thread, 0, 0, NULL );
+ for (i = 0; i < 20; i++)
+ {
+ if (i & 1)
+ status = pNtReleaseKeyedEvent( handle, (void *)(i * 2), 0, NULL );
+ else
+ status = pNtWaitForKeyedEvent( handle, (void *)(i * 2), 0, NULL );
+ ok( status == STATUS_SUCCESS, "%li: failed %x\n", i, status );
+ Sleep( i );
+ }
+ status = pNtWaitForKeyedEvent( handle, (void *)0x1234, 0, &timeout );
+ ok( status == STATUS_SUCCESS, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtWaitForKeyedEvent( handle, (void *)0x5678, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( handle, (void *)0x9abc, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
+
+ ok( WaitForSingleObject( thread, 30000 ) == 0, "wait failed\n" );
+
+ NtClose( handle );
+
+ /* test access rights */
+
+ status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_WAIT, &attr, 0 );
+ ok( !status, "NtCreateKeyedEvent failed %x\n", status );
+ status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
+ ok( status == STATUS_ACCESS_DENIED, "NtReleaseKeyedEvent %x\n", status );
+ NtClose( handle );
+
+ status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_WAKE, &attr, 0 );
+ ok( !status, "NtCreateKeyedEvent failed %x\n", status );
+ status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
+ ok( status == STATUS_ACCESS_DENIED, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
+ NtClose( handle );
+
+ status = pNtCreateKeyedEvent( &handle, KEYEDEVENT_ALL_ACCESS, &attr, 0 );
+ ok( !status, "NtCreateKeyedEvent failed %x\n", status );
+ status = WaitForSingleObject( handle, 1000 );
+ ok( status == WAIT_FAILED && GetLastError() == ERROR_ACCESS_DENIED,
+ "WaitForSingleObject %x err %u\n", status, GetLastError() );
+ status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
+ NtClose( handle );
+
+ /* GENERIC_READ gives wait access */
+ status = pNtCreateKeyedEvent( &handle, GENERIC_READ, &attr, 0 );
+ ok( !status, "NtCreateKeyedEvent failed %x\n", status );
+ status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
+ ok( status == STATUS_ACCESS_DENIED, "NtReleaseKeyedEvent %x\n", status );
+ NtClose( handle );
+
+ /* GENERIC_WRITE gives wake access */
+ status = pNtCreateKeyedEvent( &handle, GENERIC_WRITE, &attr, 0 );
+ ok( !status, "NtCreateKeyedEvent failed %x\n", status );
+ status = pNtWaitForKeyedEvent( handle, (void *)8, 0, &timeout );
+ ok( status == STATUS_ACCESS_DENIED, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( handle, (void *)8, 0, &timeout );
+ ok( status == STATUS_TIMEOUT, "NtReleaseKeyedEvent %x\n", status );
+
+ /* it's not an event */
+ status = pNtPulseEvent( handle, NULL );
+ ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtPulseEvent %x\n", status );
+
+ status = pNtCreateEvent( &event, GENERIC_ALL, &attr, NotificationEvent, FALSE );
+ ok( status == STATUS_OBJECT_NAME_COLLISION || status == STATUS_OBJECT_TYPE_MISMATCH /* 7+ */,
+ "CreateEvent %x\n", status );
+
+ NtClose( handle );
+
+ status = pNtCreateEvent( &event, GENERIC_ALL, &attr, NotificationEvent, FALSE );
+ ok( status == 0, "CreateEvent %x\n", status );
+ status = pNtWaitForKeyedEvent( event, (void *)8, 0, &timeout );
+ ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtWaitForKeyedEvent %x\n", status );
+ status = pNtReleaseKeyedEvent( event, (void *)8, 0, &timeout );
+ ok( status == STATUS_OBJECT_TYPE_MISMATCH, "NtReleaseKeyedEvent %x\n", status );
+ NtClose( event );
+}
+
+static DWORD WINAPI mutant_thread( void *arg )
+{
+ MUTANT_BASIC_INFORMATION info;
+ NTSTATUS status;
+ HANDLE mutant;
+ DWORD ret;
+
+ mutant = arg;
+ ret = WaitForSingleObject( mutant, 1000 );
+ ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
+
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
+ ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
+ ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
+ ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
+ /* abandon mutant */
+
+ return 0;
+}
+
+static void test_mutant(void)
+{
+ MUTANT_BASIC_INFORMATION info;
+ OBJECT_ATTRIBUTES attr;
+ UNICODE_STRING str;
+ NTSTATUS status;
+ HANDLE mutant;
+ HANDLE thread;
+ DWORD ret;
+ ULONG len;
+ LONG prev;
+
+ pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\test_mutant");
+ InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
+ status = pNtCreateMutant(&mutant, GENERIC_ALL, &attr, TRUE);
+ ok( status == STATUS_SUCCESS, "Failed to create Mutant(%08x)\n", status );
+
+ /* bogus */
+ status = pNtQueryMutant(mutant, MutantBasicInformation, &info, 0, NULL);
+ ok( status == STATUS_INFO_LENGTH_MISMATCH,
+ "Failed to NtQueryMutant, expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status );
+ status = pNtQueryMutant(mutant, 0x42, &info, sizeof(info), NULL);
+ ok( status == STATUS_INVALID_INFO_CLASS || broken(status == STATUS_NOT_IMPLEMENTED), /* 32-bit on Vista/2k8 */
+ "Failed to NtQueryMutant, expected STATUS_INVALID_INFO_CLASS, got %08x\n", status );
+ status = pNtQueryMutant((HANDLE)0xdeadbeef, MutantBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_INVALID_HANDLE,
+ "Failed to NtQueryMutant, expected STATUS_INVALID_HANDLE, got %08x\n", status );
+
+ /* new */
+ len = -1;
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), &len);
+ ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
+ ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
+ ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
+ ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
+ ok( len == sizeof(info), "got %u\n", len );
+
+ ret = WaitForSingleObject( mutant, 1000 );
+ ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
+
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
+ ok( info.CurrentCount == -1, "expected -1, got %d\n", info.CurrentCount );
+ ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
+ ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
+
+ prev = 0xdeadbeef;
+ status = pNtReleaseMutant(mutant, &prev);
+ ok( status == STATUS_SUCCESS, "NtReleaseMutant failed %08x\n", status );
+ ok( prev == -1, "NtReleaseMutant failed, expected -1, got %d\n", prev );
+
+ prev = 0xdeadbeef;
+ status = pNtReleaseMutant(mutant, &prev);
+ ok( status == STATUS_SUCCESS, "NtReleaseMutant failed %08x\n", status );
+ ok( prev == 0, "NtReleaseMutant failed, expected 0, got %d\n", prev );
+
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
+ ok( info.CurrentCount == 1, "expected 1, got %d\n", info.CurrentCount );
+ ok( info.OwnedByCaller == FALSE, "expected FALSE, got %d\n", info.OwnedByCaller );
+ ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
+
+ /* abandoned */
+ thread = CreateThread( NULL, 0, mutant_thread, mutant, 0, NULL );
+ ret = WaitForSingleObject( thread, 1000 );
+ ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
+ CloseHandle( thread );
+
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
+ ok( info.CurrentCount == 1, "expected 0, got %d\n", info.CurrentCount );
+ ok( info.OwnedByCaller == FALSE, "expected FALSE, got %d\n", info.OwnedByCaller );
+ ok( info.AbandonedState == TRUE, "expected TRUE, got %d\n", info.AbandonedState );
+
+ ret = WaitForSingleObject( mutant, 1000 );
+ ok( ret == WAIT_ABANDONED_0, "WaitForSingleObject failed %08x\n", ret );
+
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQueryMutant(mutant, MutantBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQueryMutant failed %08x\n", status );
+ ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
+ ok( info.OwnedByCaller == TRUE, "expected TRUE, got %d\n", info.OwnedByCaller );
+ ok( info.AbandonedState == FALSE, "expected FALSE, got %d\n", info.AbandonedState );
+
+ NtClose( mutant );
+}
+
+static void test_semaphore(void)
+{
+ SEMAPHORE_BASIC_INFORMATION info;
+ OBJECT_ATTRIBUTES attr;
+ UNICODE_STRING str;
+ NTSTATUS status;
+ HANDLE semaphore;
+ ULONG prev;
+ ULONG len;
+ DWORD ret;
+
+ pRtlInitUnicodeString(&str, L"\\BaseNamedObjects\\test_semaphore");
+ InitializeObjectAttributes(&attr, &str, 0, 0, NULL);
+
+ status = pNtCreateSemaphore(&semaphore, GENERIC_ALL, &attr, 2, 1);
+ ok( status == STATUS_INVALID_PARAMETER, "Failed to create Semaphore(%08x)\n", status );
+ status = pNtCreateSemaphore(&semaphore, GENERIC_ALL, &attr, 1, 2);
+ ok( status == STATUS_SUCCESS, "Failed to create Semaphore(%08x)\n", status );
+
+ /* bogus */
+ status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, 0, NULL);
+ ok( status == STATUS_INFO_LENGTH_MISMATCH,
+ "Failed to NtQuerySemaphore, expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status );
+ status = pNtQuerySemaphore(semaphore, 0x42, &info, sizeof(info), NULL);
+ ok( status == STATUS_INVALID_INFO_CLASS,
+ "Failed to NtQuerySemaphore, expected STATUS_INVALID_INFO_CLASS, got %08x\n", status );
+ status = pNtQuerySemaphore((HANDLE)0xdeadbeef, SemaphoreBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_INVALID_HANDLE,
+ "Failed to NtQuerySemaphore, expected STATUS_INVALID_HANDLE, got %08x\n", status );
+
+ len = -1;
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), &len);
+ ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
+ ok( info.CurrentCount == 1, "expected 1, got %d\n", info.CurrentCount );
+ ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
+ ok( len == sizeof(info), "got %u\n", len );
+
+ ret = WaitForSingleObject( semaphore, 1000 );
+ ok( ret == WAIT_OBJECT_0, "WaitForSingleObject failed %08x\n", ret );
+
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
+ ok( info.CurrentCount == 0, "expected 0, got %d\n", info.CurrentCount );
+ ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
+
+ prev = 0xdeadbeef;
+ status = pNtReleaseSemaphore(semaphore, 3, &prev);
+ ok( status == STATUS_SEMAPHORE_LIMIT_EXCEEDED, "NtReleaseSemaphore failed %08x\n", status );
+ ok( prev == 0xdeadbeef, "NtReleaseSemaphore failed, expected 0xdeadbeef, got %d\n", prev );
+
+ prev = 0xdeadbeef;
+ status = pNtReleaseSemaphore(semaphore, 1, &prev);
+ ok( status == STATUS_SUCCESS, "NtReleaseSemaphore failed %08x\n", status );
+ ok( prev == 0, "NtReleaseSemaphore failed, expected 0, got %d\n", prev );
+
+ prev = 0xdeadbeef;
+ status = pNtReleaseSemaphore(semaphore, 1, &prev);
+ ok( status == STATUS_SUCCESS, "NtReleaseSemaphore failed %08x\n", status );
+ ok( prev == 1, "NtReleaseSemaphore failed, expected 1, got %d\n", prev );
+
+ prev = 0xdeadbeef;
+ status = pNtReleaseSemaphore(semaphore, 1, &prev);
+ ok( status == STATUS_SEMAPHORE_LIMIT_EXCEEDED, "NtReleaseSemaphore failed %08x\n", status );
+ ok( prev == 0xdeadbeef, "NtReleaseSemaphore failed, expected 0xdeadbeef, got %d\n", prev );
+
+ memset(&info, 0xcc, sizeof(info));
+ status = pNtQuerySemaphore(semaphore, SemaphoreBasicInformation, &info, sizeof(info), NULL);
+ ok( status == STATUS_SUCCESS, "NtQuerySemaphore failed %08x\n", status );
+ ok( info.CurrentCount == 2, "expected 2, got %d\n", info.CurrentCount );
+ ok( info.MaximumCount == 2, "expected 2, got %d\n", info.MaximumCount );
+
+ NtClose( semaphore );
+}
+
+static void test_wait_on_address(void)
+{
+ SIZE_T size;
+ NTSTATUS status;
+ LARGE_INTEGER start, end, timeout;
+ DWORD elapsed;
+ LONG64 address, compare;
+
+ if (!pRtlWaitOnAddress)
+ {
+ win_skip("RtlWaitOnAddress not supported, skipping test\n");
+ return;
+ }
+
+ if (0) /* crash on Windows */
+ {
+ pRtlWaitOnAddress(&address, NULL, 8, NULL);
+ pRtlWaitOnAddress(NULL, &compare, 8, NULL);
+ pRtlWaitOnAddress(NULL, NULL, 8, NULL);
+ }
+
+ /* don't crash */
+ pRtlWakeAddressSingle(NULL);
+ pRtlWakeAddressAll(NULL);
+
+ /* invalid values */
+ address = 0;
+ compare = 0;
+ status = pRtlWaitOnAddress(&address, &compare, 5, NULL);
+ ok(status == STATUS_INVALID_PARAMETER, "got %x\n", status);
+
+ /* values match */
+ address = 0;
+ compare = 0;
+ pNtQuerySystemTime(&start);
+ timeout.QuadPart = start.QuadPart + 100 * 10000;
+ status = pRtlWaitOnAddress(&address, &compare, 8, &timeout);
+ pNtQuerySystemTime(&end);
+ ok(status == STATUS_TIMEOUT, "got 0x%08x\n", status);
+ elapsed = (end.QuadPart - start.QuadPart) / 10000;
+ ok(90 <= elapsed && elapsed <= 900, "timed out in %u ms\n", elapsed);
+ ok(address == 0, "got %s\n", wine_dbgstr_longlong(address));
+ ok(compare == 0, "got %s\n", wine_dbgstr_longlong(compare));
+
+ /* different address size */
+ for (size = 1; size <= 4; size <<= 1)
+ {
+ compare = ~0;
+ compare <<= size * 8;
+
+ pNtQuerySystemTime(&start);
+ timeout.QuadPart = -100 * 10000;
+ status = pRtlWaitOnAddress(&address, &compare, size, &timeout);
+ pNtQuerySystemTime(&end);
+ ok(status == STATUS_TIMEOUT, "got 0x%08x\n", status);
+ elapsed = (end.QuadPart - start.QuadPart) / 10000;
+ ok(90 <= elapsed && elapsed <= 900, "timed out in %u ms\n", elapsed);
+
+ status = pRtlWaitOnAddress(&address, &compare, size << 1, &timeout);
+ ok(!status, "got 0x%08x\n", status);
+ }
+ address = 0;
+ compare = 1;
+ status = pRtlWaitOnAddress(&address, &compare, 8, NULL);
+ ok(!status, "got 0x%08x\n", status);
+
+ /* no waiters */
+ address = 0;
+ pRtlWakeAddressSingle(&address);
+ ok(address == 0, "got %s\n", wine_dbgstr_longlong(address));
+ pRtlWakeAddressAll(&address);
+ ok(address == 0, "got %s\n", wine_dbgstr_longlong(address));
+}
+
+START_TEST(sync)
+{
+ HMODULE module = GetModuleHandleA("ntdll.dll");
+
+ pNtClose = (void *)GetProcAddress(module, "NtClose");
+ pNtCreateEvent = (void *)GetProcAddress(module, "NtCreateEvent");
+ pNtCreateKeyedEvent = (void *)GetProcAddress(module, "NtCreateKeyedEvent");
+ pNtCreateMutant = (void *)GetProcAddress(module, "NtCreateMutant");
+ pNtCreateSemaphore = (void *)GetProcAddress(module, "NtCreateSemaphore");
+ pNtOpenEvent = (void *)GetProcAddress(module, "NtOpenEvent");
+ pNtOpenKeyedEvent = (void *)GetProcAddress(module, "NtOpenKeyedEvent");
+ pNtPulseEvent = (void *)GetProcAddress(module, "NtPulseEvent");
+ pNtQueryEvent = (void *)GetProcAddress(module, "NtQueryEvent");
+ pNtQueryMutant = (void *)GetProcAddress(module, "NtQueryMutant");
+ pNtQuerySemaphore = (void *)GetProcAddress(module, "NtQuerySemaphore");
+ pNtQuerySystemTime = (void *)GetProcAddress(module, "NtQuerySystemTime");
+ pNtReleaseKeyedEvent = (void *)GetProcAddress(module, "NtReleaseKeyedEvent");
+ pNtReleaseMutant = (void *)GetProcAddress(module, "NtReleaseMutant");
+ pNtReleaseSemaphore = (void *)GetProcAddress(module, "NtReleaseSemaphore");
+ pNtResetEvent = (void *)GetProcAddress(module, "NtResetEvent");
+ pNtSetEvent = (void *)GetProcAddress(module, "NtSetEvent");
+ pNtWaitForKeyedEvent = (void *)GetProcAddress(module, "NtWaitForKeyedEvent");
+ pRtlInitUnicodeString = (void *)GetProcAddress(module, "RtlInitUnicodeString");
+ pRtlWaitOnAddress = (void *)GetProcAddress(module, "RtlWaitOnAddress");
+ pRtlWakeAddressAll = (void *)GetProcAddress(module, "RtlWakeAddressAll");
+ pRtlWakeAddressSingle = (void *)GetProcAddress(module, "RtlWakeAddressSingle");
+
+ test_wait_on_address();
+ test_event();
+ test_mutant();
+ test_semaphore();
+ test_keyed_events();
+}
--
2.33.0
2
2
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
Maybe we could merge hid with plugplay too, but it may end up being
a bit too much verbose, I'm not completely sure yet.
dlls/winebus.sys/bus_sdl.c | 4 +---
dlls/winebus.sys/bus_udev.c | 22 ++++++++++------------
dlls/winebus.sys/main.c | 7 +++----
3 files changed, 14 insertions(+), 19 deletions(-)
diff --git a/dlls/winebus.sys/bus_sdl.c b/dlls/winebus.sys/bus_sdl.c
index fe3a960649c..d172d5382fd 100644
--- a/dlls/winebus.sys/bus_sdl.c
+++ b/dlls/winebus.sys/bus_sdl.c
@@ -59,8 +59,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
#ifdef SONAME_LIBSDL2
-WINE_DECLARE_DEBUG_CHANNEL(hid_report);
-
static pthread_mutex_t sdl_cs = PTHREAD_MUTEX_INITIALIZER;
static struct sdl_bus_options options;
@@ -847,7 +845,7 @@ static void process_device_event(SDL_Event *event)
struct sdl_device *impl;
SDL_JoystickID id;
- TRACE_(hid_report)("Received action %x\n", event->type);
+ TRACE("Received action %x\n", event->type);
pthread_mutex_lock(&sdl_cs);
diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 4c00fe6ad39..780af549916 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -101,8 +101,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
#ifdef HAVE_UDEV
-WINE_DECLARE_DEBUG_CHANNEL(hid_report);
-
static pthread_mutex_t udev_cs = PTHREAD_MUTEX_INITIALIZER;
static struct udev *udev_context = NULL;
@@ -344,9 +342,9 @@ static void hidraw_device_read_report(struct unix_device *iface)
int size = read(impl->base.device_fd, report_buffer, sizeof(report_buffer));
if (size == -1)
- TRACE_(hid_report)("Read failed. Likely an unplugged device %d %s\n", errno, strerror(errno));
+ TRACE("Read failed. Likely an unplugged device %d %s\n", errno, strerror(errno));
else if (size == 0)
- TRACE_(hid_report)("Failed to read report\n");
+ TRACE("Failed to read report\n");
else
{
/* As described in the Linux kernel driver, when connected over bluetooth, DS4 controllers
@@ -380,7 +378,7 @@ static void hidraw_device_set_output_report(struct unix_device *iface, HID_XFER_
if ((buffer[0] = packet->reportId))
count = write(impl->base.device_fd, packet->reportBuffer, length);
else if (length > sizeof(buffer) - 1)
- ERR_(hid_report)("id %d length %u >= 8192, cannot write\n", packet->reportId, length);
+ ERR("id %d length %u >= 8192, cannot write\n", packet->reportId, length);
else
{
memcpy(buffer + 1, packet->reportBuffer, length);
@@ -394,7 +392,7 @@ static void hidraw_device_set_output_report(struct unix_device *iface, HID_XFER_
}
else
{
- ERR_(hid_report)("id %d write failed error: %d %s\n", packet->reportId, errno, strerror(errno));
+ ERR("id %d write failed error: %d %s\n", packet->reportId, errno, strerror(errno));
io->Information = 0;
io->Status = STATUS_UNSUCCESSFUL;
}
@@ -412,7 +410,7 @@ static void hidraw_device_get_feature_report(struct unix_device *iface, HID_XFER
if ((buffer[0] = packet->reportId) && length <= 0x1fff)
count = ioctl(impl->base.device_fd, HIDIOCGFEATURE(length), packet->reportBuffer);
else if (length > sizeof(buffer) - 1)
- ERR_(hid_report)("id %d length %u >= 8192, cannot read\n", packet->reportId, length);
+ ERR("id %d length %u >= 8192, cannot read\n", packet->reportId, length);
else
{
count = ioctl(impl->base.device_fd, HIDIOCGFEATURE(length + 1), buffer);
@@ -426,7 +424,7 @@ static void hidraw_device_get_feature_report(struct unix_device *iface, HID_XFER
}
else
{
- ERR_(hid_report)("id %d read failed, error: %d %s\n", packet->reportId, errno, strerror(errno));
+ ERR("id %d read failed, error: %d %s\n", packet->reportId, errno, strerror(errno));
io->Information = 0;
io->Status = STATUS_UNSUCCESSFUL;
}
@@ -448,7 +446,7 @@ static void hidraw_device_set_feature_report(struct unix_device *iface, HID_XFER
if ((buffer[0] = packet->reportId) && length <= 0x1fff)
count = ioctl(impl->base.device_fd, HIDIOCSFEATURE(length), packet->reportBuffer);
else if (length > sizeof(buffer) - 1)
- ERR_(hid_report)("id %d length %u >= 8192, cannot write\n", packet->reportId, length);
+ ERR("id %d length %u >= 8192, cannot write\n", packet->reportId, length);
else
{
memcpy(buffer + 1, packet->reportBuffer, length);
@@ -462,7 +460,7 @@ static void hidraw_device_set_feature_report(struct unix_device *iface, HID_XFER
}
else
{
- ERR_(hid_report)("id %d write failed, error: %d %s\n", packet->reportId, errno, strerror(errno));
+ ERR("id %d write failed, error: %d %s\n", packet->reportId, errno, strerror(errno));
io->Information = 0;
io->Status = STATUS_UNSUCCESSFUL;
}
@@ -802,9 +800,9 @@ static void lnxev_device_read_report(struct unix_device *iface)
size = read(impl->base.device_fd, &ie, sizeof(ie));
if (size == -1)
- TRACE_(hid_report)("Read failed. Likely an unplugged device\n");
+ TRACE("Read failed. Likely an unplugged device\n");
else if (size == 0)
- TRACE_(hid_report)("Failed to read report\n");
+ TRACE("Failed to read report\n");
else if (set_report_from_event(iface, &ie))
bus_event_queue_input_report(&event_queue, iface, state->report_buf, state->report_len);
}
diff --git a/dlls/winebus.sys/main.c b/dlls/winebus.sys/main.c
index 433963b44d4..1353df7d000 100644
--- a/dlls/winebus.sys/main.c
+++ b/dlls/winebus.sys/main.c
@@ -41,7 +41,6 @@
#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(plugplay);
-WINE_DECLARE_DEBUG_CHANNEL(hid_report);
static DRIVER_OBJECT *driver_obj;
@@ -1045,21 +1044,21 @@ static NTSTATUS WINAPI hid_internal_dispatch(DEVICE_OBJECT *device, IRP *irp)
case IOCTL_HID_WRITE_REPORT:
{
HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer);
- TRACE_(hid_report)("IOCTL_HID_WRITE_REPORT / IOCTL_HID_SET_OUTPUT_REPORT\n");
+ TRACE("IOCTL_HID_WRITE_REPORT / IOCTL_HID_SET_OUTPUT_REPORT\n");
unix_device_set_output_report(device, packet, &irp->IoStatus);
break;
}
case IOCTL_HID_GET_FEATURE:
{
HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer);
- TRACE_(hid_report)("IOCTL_HID_GET_FEATURE\n");
+ TRACE("IOCTL_HID_GET_FEATURE\n");
unix_device_get_feature_report(device, packet, &irp->IoStatus);
break;
}
case IOCTL_HID_SET_FEATURE:
{
HID_XFER_PACKET *packet = (HID_XFER_PACKET*)(irp->UserBuffer);
- TRACE_(hid_report)("IOCTL_HID_SET_FEATURE\n");
+ TRACE("IOCTL_HID_SET_FEATURE\n");
unix_device_set_feature_report(device, packet, &irp->IoStatus);
break;
}
--
2.33.0
2
3
[PATCH 1/4] evr/mixer: Improve output type candidates attributes configuration.
by Nikolay Sivov Oct. 27, 2021
by Nikolay Sivov Oct. 27, 2021
Oct. 27, 2021
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/evr/mixer.c | 35 +++++++++++++++++++++++----
dlls/evr/tests/evr.c | 56 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 86 insertions(+), 5 deletions(-)
diff --git a/dlls/evr/mixer.c b/dlls/evr/mixer.c
index f821dc7e6d9..1db2fd3a9f4 100644
--- a/dlls/evr/mixer.c
+++ b/dlls/evr/mixer.c
@@ -675,14 +675,27 @@ static unsigned int video_mixer_get_interlace_mode_from_video_desc(const DXVA2_V
}
}
+static void mf_get_attribute_uint32(IMFMediaType *media_type, const GUID *key, UINT32 *value,
+ UINT32 default_value)
+{
+ if (FAILED(IMFMediaType_GetUINT32(media_type, key, value)))
+ *value = default_value;
+}
+
+static void mf_get_attribute_uint64(IMFMediaType *media_type, const GUID *key, UINT64 *value,
+ UINT64 default_value)
+{
+ if (FAILED(IMFMediaType_GetUINT64(media_type, key, value)))
+ *value = default_value;
+}
+
static HRESULT video_mixer_collect_output_types(struct video_mixer *mixer, const DXVA2_VideoDesc *video_desc,
IMFMediaType *media_type, IDirectXVideoProcessorService *service, unsigned int device_count,
const GUID *devices, unsigned int flags)
{
- unsigned int i, j, format_count, count, interlace_mode;
struct rt_format *rt_formats = NULL, *ptr;
+ unsigned int i, j, format_count, count;
HRESULT hr = MF_E_INVALIDMEDIATYPE;
- MFVideoArea aperture;
D3DFORMAT *formats;
GUID subtype;
@@ -710,6 +723,10 @@ static HRESULT video_mixer_collect_output_types(struct video_mixer *mixer, const
if (count && !(flags & MFT_SET_TYPE_TEST_ONLY))
{
+ UINT32 fixed_samples, interlace_mode;
+ MFVideoArea aperture;
+ UINT64 par;
+
if (!(mixer->output.rt_formats = calloc(count, sizeof(*mixer->output.rt_formats))))
{
free(rt_formats);
@@ -718,9 +735,16 @@ static HRESULT video_mixer_collect_output_types(struct video_mixer *mixer, const
memcpy(&subtype, &MFVideoFormat_Base, sizeof(subtype));
memset(&aperture, 0, sizeof(aperture));
- aperture.Area.cx = video_desc->SampleWidth;
- aperture.Area.cy = video_desc->SampleHeight;
+ if (FAILED(IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)&aperture,
+ sizeof(aperture), NULL)))
+ {
+ aperture.Area.cx = video_desc->SampleWidth;
+ aperture.Area.cy = video_desc->SampleHeight;
+ }
interlace_mode = video_mixer_get_interlace_mode_from_video_desc(video_desc);
+ mf_get_attribute_uint64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &par, (UINT64)1 << 32 | 1);
+ mf_get_attribute_uint32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &fixed_samples, 1);
+
for (i = 0; i < count; ++i)
{
IMFMediaType *rt_media_type;
@@ -731,9 +755,12 @@ static HRESULT video_mixer_collect_output_types(struct video_mixer *mixer, const
MFCreateMediaType(&rt_media_type);
IMFMediaType_CopyAllItems(media_type, (IMFAttributes *)rt_media_type);
IMFMediaType_SetGUID(rt_media_type, &MF_MT_SUBTYPE, &subtype);
+ IMFMediaType_SetUINT64(rt_media_type, &MF_MT_FRAME_SIZE, (UINT64)aperture.Area.cx << 32 | aperture.Area.cy);
IMFMediaType_SetBlob(rt_media_type, &MF_MT_GEOMETRIC_APERTURE, (const UINT8 *)&aperture, sizeof(aperture));
IMFMediaType_SetBlob(rt_media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (const UINT8 *)&aperture, sizeof(aperture));
IMFMediaType_SetUINT32(rt_media_type, &MF_MT_INTERLACE_MODE, interlace_mode);
+ IMFMediaType_SetUINT64(rt_media_type, &MF_MT_PIXEL_ASPECT_RATIO, par);
+ IMFMediaType_SetUINT32(rt_media_type, &MF_MT_FIXED_SIZE_SAMPLES, fixed_samples);
mixer->output.rt_formats[i].media_type = rt_media_type;
}
diff --git a/dlls/evr/tests/evr.c b/dlls/evr/tests/evr.c
index 5bf03fa49f8..818731e1e55 100644
--- a/dlls/evr/tests/evr.c
+++ b/dlls/evr/tests/evr.c
@@ -946,6 +946,7 @@ static void test_default_mixer_type_negotiation(void)
IDirect3DDevice9 *device;
IMFMediaType *video_type;
IMFTransform *transform;
+ MFVideoArea aperture;
DWORD index, count;
IUnknown *unk;
HWND window;
@@ -1020,10 +1021,19 @@ static void test_default_mixer_type_negotiation(void)
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = IMFMediaType_SetUINT32(video_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ memset(&aperture, 0, sizeof(aperture));
+ aperture.Area.cx = 100; aperture.Area.cy = 200;
+ hr = IMFMediaType_SetBlob(video_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)&aperture, sizeof(aperture));
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IMFMediaType_SetUINT32(video_type, &MF_MT_FIXED_SIZE_SAMPLES, 2);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = IMFTransform_SetInputType(transform, 0, video_type, MFT_SET_TYPE_TEST_ONLY);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type);
+ ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
+
hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type);
ok(hr == MF_E_TRANSFORM_TYPE_NOT_SET, "Unexpected hr %#x.\n", hr);
@@ -1040,25 +1050,69 @@ static void test_default_mixer_type_negotiation(void)
IMFMediaType_Release(media_type);
IMFMediaType_Release(media_type2);
+ /* Modified after type was set. */
+ hr = IMFMediaType_SetUINT64(video_type, &MF_MT_PIXEL_ASPECT_RATIO, (UINT64)56 << 32 | 55);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
/* Check attributes on available output types. */
index = 0;
while (SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, index++, &media_type)))
{
- UINT64 frame_size;
+ UINT64 frame_size, ratio;
+ MFVideoArea aperture;
GUID subtype, major;
UINT32 value;
hr = IMFMediaType_GetGUID(media_type, &MF_MT_MAJOR_TYPE, &major);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(IsEqualGUID(&major, &MFMediaType_Video), "Unexpected major type.\n");
hr = IMFMediaType_GetGUID(media_type, &MF_MT_SUBTYPE, &subtype);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = IMFMediaType_GetUINT64(media_type, &MF_MT_FRAME_SIZE, &frame_size);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(frame_size == ((UINT64)100 << 32 | 200), "Unexpected frame size %s.\n", wine_dbgstr_longlong(frame_size));
hr = IMFMediaType_GetUINT32(media_type, &MF_MT_ALL_SAMPLES_INDEPENDENT, &value);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
hr = IMFMediaType_GetUINT32(media_type, &MF_MT_INTERLACE_MODE, &value);
ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
ok(value == MFVideoInterlace_Progressive, "Unexpected interlace mode.\n");
+ /* Ratio from input type */
+ hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(ratio == ((UINT64)1 << 32 | 1), "Unexpected PAR %s.\n", wine_dbgstr_longlong(ratio));
+ hr = IMFMediaType_GetBlob(media_type, &MF_MT_GEOMETRIC_APERTURE, (UINT8 *)&aperture, sizeof(aperture), NULL);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(aperture.Area.cx == 100 && aperture.Area.cy == 200, "Unexpected aperture area.\n");
+ hr = IMFMediaType_GetBlob(media_type, &MF_MT_MINIMUM_DISPLAY_APERTURE, (UINT8 *)&aperture, sizeof(aperture), NULL);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(aperture.Area.cx == 100 && aperture.Area.cy == 200, "Unexpected aperture area.\n");
+ hr = IMFMediaType_GetUINT32(video_type, &MF_MT_FIXED_SIZE_SAMPLES, &value);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(value == 2, "Unexpected value %u.\n", value);
+
+ IMFMediaType_Release(media_type);
+ }
+ ok(index > 1, "Unexpected number of available types.\n");
+
+ hr = IMFMediaType_DeleteItem(video_type, &MF_MT_FIXED_SIZE_SAMPLES);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ hr = IMFTransform_SetInputType(transform, 0, video_type, 0);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ index = 0;
+ while (SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, index++, &media_type)))
+ {
+ UINT32 value;
+ UINT64 ratio;
+
+ hr = IMFMediaType_GetUINT64(media_type, &MF_MT_PIXEL_ASPECT_RATIO, &ratio);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(ratio == ((UINT64)56 << 32 | 55), "Unexpected PAR %s.\n", wine_dbgstr_longlong(ratio));
+
+ hr = IMFMediaType_GetUINT32(media_type, &MF_MT_FIXED_SIZE_SAMPLES, &value);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(value == 1, "Unexpected value %u.\n", value);
IMFMediaType_Release(media_type);
}
--
2.33.0
1
3
Oct. 27, 2021
Testing on Windows shows typically handles are not sign extended,
however sometimes they are. It's not clear what triggers the change
in behaviour.
Signed-off-by: Francisco Casas <fcasas(a)codeweavers.com>
---
dlls/gdi32/objects.c | 2 +-
dlls/win32u/gdiobj.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/gdi32/objects.c b/dlls/gdi32/objects.c
index 196cea9ba92..04b91cfd60f 100644
--- a/dlls/gdi32/objects.c
+++ b/dlls/gdi32/objects.c
@@ -102,7 +102,7 @@ static inline GDI_HANDLE_ENTRY *handle_entry( HGDIOBJ handle )
static HGDIOBJ entry_to_handle( GDI_HANDLE_ENTRY *entry )
{
unsigned int idx = entry - get_gdi_shared()->Handles;
- return LongToHandle( idx | (entry->Unique << NTGDI_HANDLE_TYPE_SHIFT) );
+ return ULongToHandle( idx | (entry->Unique << NTGDI_HANDLE_TYPE_SHIFT) );
}
static DWORD get_object_type( HGDIOBJ obj )
diff --git a/dlls/win32u/gdiobj.c b/dlls/win32u/gdiobj.c
index a661cefe0bd..06bade61a56 100644
--- a/dlls/win32u/gdiobj.c
+++ b/dlls/win32u/gdiobj.c
@@ -55,7 +55,7 @@ const struct user_callbacks *user_callbacks = NULL;
static inline HGDIOBJ entry_to_handle( GDI_HANDLE_ENTRY *entry )
{
unsigned int idx = entry - gdi_shared->Handles;
- return LongToHandle( idx | (entry->Unique << NTGDI_HANDLE_TYPE_SHIFT) );
+ return ULongToHandle( idx | (entry->Unique << NTGDI_HANDLE_TYPE_SHIFT) );
}
static inline GDI_HANDLE_ENTRY *handle_entry( HGDIOBJ handle )
--
2.25.1
2
1