Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- 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
June 2018
- 68 participants
- 1149 messages
Out for a few days
by Alexandre Julliard
Folks,
I'm going to be out from tomorrow until Sunday, so release 3.10 is going
to be delayed until Monday.
--
Alexandre Julliard
julliard(a)winehq.org
June 6, 2018
Re: [PATCH 2/3] kernel32: Implement Wow64GetThreadContext().
by Zebediah Figura
On 06/06/2018 09:34 AM, Alexandre Julliard wrote:
> Zebediah Figura <zfigura(a)codeweavers.com> writes:
>
>> Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
>> ---
>> With code essentially copied from ntdll. As far as I can tell there is no
>> ntdll entry point for this function.
>
> RtlWow64GetThreadContext() is probably what you are looking for. It will
> need some test cases obviously.
>
Thanks; I can see I was looking in the wrong place. I've sent updated
patches.
June 6, 2018
[PATCH v2 5/5] kernel32: Implement Wow64SetThreadContext().
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/kernel32/kernel32.spec | 2 +-
dlls/kernel32/thread.c | 17 +++++++++++++++++
include/winbase.h | 1 +
include/winternl.h | 1 +
4 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 1cb0b54..de6f007 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -1603,7 +1603,7 @@
@ stdcall Wow64GetThreadContext(long ptr)
# @ stub Wow64GetThreadSelectorEntry
@ stdcall Wow64RevertWow64FsRedirection(ptr)
-# @ stub Wow64SetThreadContext
+@ stdcall Wow64SetThreadContext(long ptr)
# @ stub Wow64SuspendThread
@ stdcall WriteConsoleA(long ptr long ptr ptr)
@ stdcall WriteConsoleInputA(long ptr long ptr)
diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c
index 3aa2887..eb304dc 100644
--- a/dlls/kernel32/thread.c
+++ b/dlls/kernel32/thread.c
@@ -236,6 +236,23 @@ BOOL WINAPI SetThreadContext( HANDLE handle, /* [in] Handle to thread
/***********************************************************************
+ * Wow64SetThreadContext [KERNEL32.@]
+ */
+BOOL WINAPI Wow64SetThreadContext( HANDLE handle, const WOW64_CONTEXT *context)
+{
+#ifdef __i386__
+ NTSTATUS status = NtSetContextThread( handle, (const CONTEXT *)context );
+#elif defined(_WIN64)
+ NTSTATUS status = RtlWow64SetThreadContext( handle, context );
+#else
+ NTSTATUS status = STATUS_NOT_IMPLEMENTED;
+ FIXME("not implemented on this platform\n");
+#endif
+ if (status) SetLastError( RtlNtStatusToDosError(status) );
+ return !status;
+}
+
+/***********************************************************************
* GetThreadContext [KERNEL32.@] Retrieves context of thread.
*
* RETURNS
diff --git a/include/winbase.h b/include/winbase.h
index f7239b8..667df96 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2708,6 +2708,7 @@ WINBASEAPI BOOL WINAPI Wow64DisableWow64FsRedirection(PVOID*);
WINBASEAPI BOOLEAN WINAPI Wow64EnableWow64FsRedirection(BOOLEAN);
WINBASEAPI BOOL WINAPI Wow64GetThreadContext(HANDLE, WOW64_CONTEXT *);
WINBASEAPI BOOL WINAPI Wow64RevertWow64FsRedirection(PVOID);
+WINBASEAPI BOOL WINAPI Wow64SetThreadContext(HANDLE, const WOW64_CONTEXT *);
WINADVAPI DWORD WINAPI WriteEncryptedFileRaw(PFE_IMPORT_FUNC,PVOID,PVOID);
WINBASEAPI BOOL WINAPI WriteFile(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED);
WINBASEAPI BOOL WINAPI WriteFileEx(HANDLE,LPCVOID,DWORD,LPOVERLAPPED,LPOVERLAPPED_COMPLETION_ROUTINE);
diff --git a/include/winternl.h b/include/winternl.h
index 9361825..9341c40 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2838,6 +2838,7 @@ NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirection(BOOLEAN);
NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx(ULONG,ULONG*);
#ifdef _WIN64
NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE, WOW64_CONTEXT *);
+NTSYSAPI NTSTATUS WINAPI RtlWow64SetThreadContext(HANDLE, const WOW64_CONTEXT *);
#endif
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG,PCWSTR,PCWSTR,ULONG,PVOID,ULONG);
NTSYSAPI NTSTATUS WINAPI RtlZombifyActivationContext(HANDLE);
--
2.7.4
June 6, 2018
[PATCH v2 4/5] kernel32: Implement Wow64GetThreadContext().
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/kernel32/kernel32.spec | 2 +-
dlls/kernel32/thread.c | 18 ++++++++++++++++++
include/winbase.h | 1 +
include/winternl.h | 3 +++
4 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec
index 9ed5dfb..1cb0b54 100644
--- a/dlls/kernel32/kernel32.spec
+++ b/dlls/kernel32/kernel32.spec
@@ -1600,7 +1600,7 @@
@ stdcall WinExec(str long)
@ stdcall Wow64EnableWow64FsRedirection(long)
@ stdcall Wow64DisableWow64FsRedirection(ptr)
-# @ stub Wow64GetThreadContext
+@ stdcall Wow64GetThreadContext(long ptr)
# @ stub Wow64GetThreadSelectorEntry
@ stdcall Wow64RevertWow64FsRedirection(ptr)
# @ stub Wow64SetThreadContext
diff --git a/dlls/kernel32/thread.c b/dlls/kernel32/thread.c
index b6ca9f260..3aa2887 100644
--- a/dlls/kernel32/thread.c
+++ b/dlls/kernel32/thread.c
@@ -251,6 +251,24 @@ BOOL WINAPI GetThreadContext( HANDLE handle, /* [in] Handle to thread with
}
+/***********************************************************************
+ * Wow64GetThreadContext [KERNEL32.@]
+ */
+BOOL WINAPI Wow64GetThreadContext( HANDLE handle, WOW64_CONTEXT *context)
+{
+#ifdef __i386__
+ NTSTATUS status = NtGetContextThread( handle, (CONTEXT *)context );
+#elif defined(_WIN64)
+ NTSTATUS status = RtlWow64GetThreadContext( handle, context );
+#else
+ NTSTATUS status = STATUS_NOT_IMPLEMENTED;
+ FIXME("not implemented on this platform\n");
+#endif
+ if (status) SetLastError( RtlNtStatusToDosError(status) );
+ return !status;
+}
+
+
/**********************************************************************
* SuspendThread [KERNEL32.@] Suspends a thread.
*
diff --git a/include/winbase.h b/include/winbase.h
index 4ddc1d3..f7239b8 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -2706,6 +2706,7 @@ WINBASEAPI VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE);
WINBASEAPI UINT WINAPI WinExec(LPCSTR,UINT);
WINBASEAPI BOOL WINAPI Wow64DisableWow64FsRedirection(PVOID*);
WINBASEAPI BOOLEAN WINAPI Wow64EnableWow64FsRedirection(BOOLEAN);
+WINBASEAPI BOOL WINAPI Wow64GetThreadContext(HANDLE, WOW64_CONTEXT *);
WINBASEAPI BOOL WINAPI Wow64RevertWow64FsRedirection(PVOID);
WINADVAPI DWORD WINAPI WriteEncryptedFileRaw(PFE_IMPORT_FUNC,PVOID,PVOID);
WINBASEAPI BOOL WINAPI WriteFile(HANDLE,LPCVOID,DWORD,LPDWORD,LPOVERLAPPED);
diff --git a/include/winternl.h b/include/winternl.h
index 3ecd068..9361825 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -2836,6 +2836,9 @@ NTSYSAPI void WINAPI RtlWakeConditionVariable(RTL_CONDITION_VARIABLE *);
NTSYSAPI NTSTATUS WINAPI RtlWalkHeap(HANDLE,PVOID);
NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirection(BOOLEAN);
NTSYSAPI NTSTATUS WINAPI RtlWow64EnableFsRedirectionEx(ULONG,ULONG*);
+#ifdef _WIN64
+NTSYSAPI NTSTATUS WINAPI RtlWow64GetThreadContext(HANDLE, WOW64_CONTEXT *);
+#endif
NTSYSAPI NTSTATUS WINAPI RtlWriteRegistryValue(ULONG,PCWSTR,PCWSTR,ULONG,PVOID,ULONG);
NTSYSAPI NTSTATUS WINAPI RtlZombifyActivationContext(HANDLE);
NTSYSAPI NTSTATUS WINAPI RtlpNtCreateKey(PHANDLE,ACCESS_MASK,const OBJECT_ATTRIBUTES*,ULONG,const UNICODE_STRING*,ULONG,PULONG);
--
2.7.4
June 6, 2018
[PATCH v2 3/5] ntdll: Implement RtlWow64SetThreadContext().
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/tests/exception.c | 6 +++
dlls/ntdll/thread.c | 96 +++++++++++++++++++++++++++++++++++++++-----
3 files changed, 93 insertions(+), 10 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index f1dd6ed..77cc1ae 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -978,6 +978,7 @@
@ stdcall RtlWow64EnableFsRedirection(long)
@ stdcall RtlWow64EnableFsRedirectionEx(long ptr)
@ stdcall -arch=win64 RtlWow64GetThreadContext(long ptr)
+@ stdcall -arch=win64 RtlWow64SetThreadContext(long ptr)
@ stub RtlWriteMemoryStream
@ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long)
@ stub RtlZeroHeap
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 0ab3812..f09e86d 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -150,6 +150,7 @@ static EXCEPTION_DISPOSITION (WINAPI *p__C_specific_handler)(EXCEPTION_RECORD*,
static VOID (WINAPI *pRtlCaptureContext)(CONTEXT*);
static VOID (CDECL *pRtlRestoreContext)(CONTEXT*, EXCEPTION_RECORD*);
static NTSTATUS (WINAPI *pRtlWow64GetThreadContext)(HANDLE, WOW64_CONTEXT *);
+static NTSTATUS (WINAPI *pRtlWow64SetThreadContext)(HANDLE, const WOW64_CONTEXT *);
static VOID (CDECL *pRtlUnwindEx)(VOID*, VOID*, EXCEPTION_RECORD*, VOID*, CONTEXT*, UNWIND_HISTORY_TABLE*);
static int (CDECL *p_setjmp)(_JUMP_BUFFER*);
#endif
@@ -2520,6 +2521,9 @@ static void test_wow64_context(void)
ok(*(WORD *)ctx.ExtendedRegisters == 0x27f, "got SSE control word %04x\n",
*(WORD *)ctx.ExtendedRegisters);
+ ret = pRtlWow64SetThreadContext( pi.hThread, &ctx );
+ ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
+
pNtTerminateProcess(pi.hProcess, 0);
}
@@ -3163,6 +3167,8 @@ START_TEST(exception)
"RtlUnwindEx" );
pRtlWow64GetThreadContext = (void *)GetProcAddress( hntdll,
"RtlWow64GetThreadContext" );
+ pRtlWow64SetThreadContext = (void *)GetProcAddress( hntdll,
+ "RtlWow64SetThreadContext" );
p_setjmp = (void *)GetProcAddress( hmsvcrt,
"_setjmp" );
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index df04b33..52c7953 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -851,23 +851,16 @@ TEB_ACTIVE_FRAME * WINAPI RtlGetFrame(void)
return NtCurrentTeb()->ActiveFrame;
}
-
-/***********************************************************************
- * set_thread_context
- */
-NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
+static NTSTATUS set_server_context( HANDLE handle, const context_t *context, BOOL *self )
{
NTSTATUS ret;
DWORD dummy, i;
- context_t server_context;
-
- context_to_server( &server_context, context );
SERVER_START_REQ( set_thread_context )
{
req->handle = wine_server_obj_handle( handle );
req->suspend = 1;
- wine_server_add_data( req, &server_context, sizeof(server_context) );
+ wine_server_add_data( req, context, sizeof(*context) );
ret = wine_server_call( req );
*self = reply->self;
}
@@ -881,7 +874,7 @@ NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
{
req->handle = wine_server_obj_handle( handle );
req->suspend = 0;
- wine_server_add_data( req, &server_context, sizeof(server_context) );
+ wine_server_add_data( req, context, sizeof(*context) );
ret = wine_server_call( req );
}
SERVER_END_REQ;
@@ -900,6 +893,12 @@ NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
return ret;
}
+NTSTATUS set_thread_context( HANDLE handle, const CONTEXT *context, BOOL *self )
+{
+ context_t server_context;
+ context_to_server( &server_context, context );
+ return set_server_context( handle, &server_context, self );
+}
/* convert CPU-specific flags to generic server flags */
static inline unsigned int get_server_context_flags( DWORD flags )
@@ -978,6 +977,83 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self)
}
#ifdef _WIN64
+static NTSTATUS wow64_context_to_server( context_t *to, const WOW64_CONTEXT *from )
+{
+ DWORD flags = from->ContextFlags & ~WOW64_CONTEXT_i386; /* get rid of CPU id */
+
+ memset( to, 0, sizeof(*to) );
+ to->cpu = CPU_x86;
+
+ if (flags & WOW64_CONTEXT_CONTROL)
+ {
+ to->flags |= SERVER_CTX_CONTROL;
+ to->ctl.i386_regs.ebp = from->Ebp;
+ to->ctl.i386_regs.esp = from->Esp;
+ to->ctl.i386_regs.eip = from->Eip;
+ to->ctl.i386_regs.cs = from->SegCs;
+ to->ctl.i386_regs.ss = from->SegSs;
+ to->ctl.i386_regs.eflags = from->EFlags;
+ }
+ if (flags & WOW64_CONTEXT_INTEGER)
+ {
+ to->flags |= SERVER_CTX_INTEGER;
+ to->integer.i386_regs.eax = from->Eax;
+ to->integer.i386_regs.ebx = from->Ebx;
+ to->integer.i386_regs.ecx = from->Ecx;
+ to->integer.i386_regs.edx = from->Edx;
+ to->integer.i386_regs.esi = from->Esi;
+ to->integer.i386_regs.edi = from->Edi;
+ }
+ if (flags & WOW64_CONTEXT_SEGMENTS)
+ {
+ to->flags |= SERVER_CTX_SEGMENTS;
+ to->seg.i386_regs.ds = from->SegDs;
+ to->seg.i386_regs.es = from->SegEs;
+ to->seg.i386_regs.fs = from->SegFs;
+ to->seg.i386_regs.gs = from->SegGs;
+ }
+ if (flags & WOW64_CONTEXT_FLOATING_POINT)
+ {
+ to->flags |= SERVER_CTX_FLOATING_POINT;
+ to->fp.i386_regs.ctrl = from->FloatSave.ControlWord;
+ to->fp.i386_regs.status = from->FloatSave.StatusWord;
+ to->fp.i386_regs.tag = from->FloatSave.TagWord;
+ to->fp.i386_regs.err_off = from->FloatSave.ErrorOffset;
+ to->fp.i386_regs.err_sel = from->FloatSave.ErrorSelector;
+ to->fp.i386_regs.data_off = from->FloatSave.DataOffset;
+ to->fp.i386_regs.data_sel = from->FloatSave.DataSelector;
+ to->fp.i386_regs.cr0npx = from->FloatSave.Cr0NpxState;
+ memcpy( to->fp.i386_regs.regs, from->FloatSave.RegisterArea, sizeof(to->fp.i386_regs.regs) );
+ }
+ if (flags & WOW64_CONTEXT_DEBUG_REGISTERS)
+ {
+ to->flags |= SERVER_CTX_DEBUG_REGISTERS;
+ to->debug.i386_regs.dr0 = from->Dr0;
+ to->debug.i386_regs.dr1 = from->Dr1;
+ to->debug.i386_regs.dr2 = from->Dr2;
+ to->debug.i386_regs.dr3 = from->Dr3;
+ to->debug.i386_regs.dr6 = from->Dr6;
+ to->debug.i386_regs.dr7 = from->Dr7;
+ }
+ if (flags & WOW64_CONTEXT_EXTENDED_REGISTERS)
+ {
+ to->flags |= SERVER_CTX_EXTENDED_REGISTERS;
+ memcpy( to->ext.i386_regs, from->ExtendedRegisters, sizeof(to->ext.i386_regs) );
+ }
+ return STATUS_SUCCESS;
+}
+
+/******************************************************************************
+ * RtlWow64SetThreadContext (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlWow64SetThreadContext( HANDLE handle, const WOW64_CONTEXT *context )
+{
+ BOOL self;
+ context_t server_context;
+ wow64_context_to_server( &server_context, context );
+ return set_server_context( handle, &server_context, &self );
+}
+
/* convert CPU-specific flags to generic server flags */
static inline unsigned int wow64_get_server_context_flags( DWORD flags )
{
--
2.7.4
June 6, 2018
[PATCH v2 2/5] ntdll: Implement RtlWow64GetThreadContext().
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/ntdll/ntdll.spec | 1 +
dlls/ntdll/tests/exception.c | 36 ++++++++++++++
dlls/ntdll/thread.c | 114 ++++++++++++++++++++++++++++++++++++++++---
3 files changed, 143 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index c0f5d6f..f1dd6ed 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -977,6 +977,7 @@
@ stdcall RtlWalkHeap(long ptr)
@ stdcall RtlWow64EnableFsRedirection(long)
@ stdcall RtlWow64EnableFsRedirectionEx(long ptr)
+@ stdcall -arch=win64 RtlWow64GetThreadContext(long ptr)
@ stub RtlWriteMemoryStream
@ stdcall RtlWriteRegistryValue(long ptr ptr long ptr long)
@ stub RtlZeroHeap
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index c47c8cb..0ab3812 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -149,6 +149,7 @@ static PRUNTIME_FUNCTION (WINAPI *pRtlLookupFunctionEntry)(ULONG64, ULONG64*, UN
static EXCEPTION_DISPOSITION (WINAPI *p__C_specific_handler)(EXCEPTION_RECORD*, ULONG64, CONTEXT*, DISPATCHER_CONTEXT*);
static VOID (WINAPI *pRtlCaptureContext)(CONTEXT*);
static VOID (CDECL *pRtlRestoreContext)(CONTEXT*, EXCEPTION_RECORD*);
+static NTSTATUS (WINAPI *pRtlWow64GetThreadContext)(HANDLE, WOW64_CONTEXT *);
static VOID (CDECL *pRtlUnwindEx)(VOID*, VOID*, EXCEPTION_RECORD*, VOID*, CONTEXT*, UNWIND_HISTORY_TABLE*);
static int (CDECL *p_setjmp)(_JUMP_BUFFER*);
#endif
@@ -2490,6 +2491,38 @@ static void test_dpe_exceptions(void)
pRtlRemoveVectoredExceptionHandler(handler);
}
+static void test_wow64_context(void)
+{
+ char cmdline[] = "C:\\windows\\syswow64\\notepad.exe";
+ PROCESS_INFORMATION pi;
+ STARTUPINFOA si = {0};
+ WOW64_CONTEXT ctx;
+ NTSTATUS ret;
+
+ memset(&ctx, 0x55, sizeof(ctx));
+ ctx.ContextFlags = WOW64_CONTEXT_ALL;
+ ret = pRtlWow64GetThreadContext( GetCurrentThread(), &ctx );
+ ok(ret == STATUS_INVALID_PARAMETER, "got %#x\n", ret);
+
+ CreateProcessA(NULL, cmdline, NULL, NULL, FALSE, CREATE_SUSPENDED, NULL, NULL, &si, &pi);
+
+ ret = pRtlWow64GetThreadContext( pi.hThread, &ctx );
+ ok(ret == STATUS_SUCCESS, "got %#x\n", ret);
+ ok(ctx.ContextFlags == WOW64_CONTEXT_ALL, "got context flags %#x\n", ctx.ContextFlags);
+ ok(!ctx.Ebp, "got ebp %08x\n", ctx.Ebp);
+ ok(!ctx.Ecx, "got ecx %08x\n", ctx.Ecx);
+ ok(!ctx.Edx, "got edx %08x\n", ctx.Edx);
+ ok(!ctx.Esi, "got esi %08x\n", ctx.Esi);
+ ok(!ctx.Edi, "got edi %08x\n", ctx.Edi);
+ ok((ctx.EFlags & ~2) == 0x200, "got eflags %08x\n", ctx.EFlags);
+ ok((WORD) ctx.FloatSave.ControlWord == 0x27f, "got control word %08x\n",
+ ctx.FloatSave.ControlWord);
+ ok(*(WORD *)ctx.ExtendedRegisters == 0x27f, "got SSE control word %04x\n",
+ *(WORD *)ctx.ExtendedRegisters);
+
+ pNtTerminateProcess(pi.hProcess, 0);
+}
+
#endif /* __x86_64__ */
#if defined(__i386__) || defined(__x86_64__)
@@ -3128,6 +3161,8 @@ START_TEST(exception)
"RtlRestoreContext" );
pRtlUnwindEx = (void *)GetProcAddress( hntdll,
"RtlUnwindEx" );
+ pRtlWow64GetThreadContext = (void *)GetProcAddress( hntdll,
+ "RtlWow64GetThreadContext" );
p_setjmp = (void *)GetProcAddress( hmsvcrt,
"_setjmp" );
@@ -3143,6 +3178,7 @@ START_TEST(exception)
test_restore_context();
test_prot_fault();
test_dpe_exceptions();
+ test_wow64_context();
if (pRtlAddFunctionTable && pRtlDeleteFunctionTable && pRtlInstallFunctionTableCallback && pRtlLookupFunctionEntry)
test_dynamic_unwind();
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index 35e23d2..df04b33 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -924,22 +924,18 @@ static inline unsigned int get_server_context_flags( DWORD flags )
return ret;
}
-/***********************************************************************
- * get_thread_context
- */
-NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
+static NTSTATUS get_server_context( HANDLE handle, unsigned int server_flags,
+ context_t *context, BOOL *self )
{
NTSTATUS ret;
DWORD dummy, i;
- unsigned int server_flags = get_server_context_flags( context->ContextFlags );
- context_t server_context;
SERVER_START_REQ( get_thread_context )
{
req->handle = wine_server_obj_handle( handle );
req->flags = server_flags;
req->suspend = 1;
- wine_server_set_reply( req, &server_context, sizeof(server_context) );
+ wine_server_set_reply( req, context, sizeof(*context) );
ret = wine_server_call( req );
*self = reply->self;
}
@@ -954,7 +950,7 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
req->handle = wine_server_obj_handle( handle );
req->flags = server_flags;
req->suspend = 0;
- wine_server_set_reply( req, &server_context, sizeof(server_context) );
+ wine_server_set_reply( req, context, sizeof(*context) );
ret = wine_server_call( req );
}
SERVER_END_REQ;
@@ -969,10 +965,112 @@ NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self )
NtResumeThread( handle, &dummy );
if (ret == STATUS_PENDING) ret = STATUS_ACCESS_DENIED;
}
+ return ret;
+}
+
+NTSTATUS get_thread_context( HANDLE handle, CONTEXT *context, BOOL *self)
+{
+ context_t server_context;
+ unsigned int server_flags = get_server_context_flags( context->ContextFlags );
+ NTSTATUS ret = get_server_context( handle, server_flags, &server_context, self);
if (!ret) ret = context_from_server( context, &server_context );
return ret;
}
+#ifdef _WIN64
+/* convert CPU-specific flags to generic server flags */
+static inline unsigned int wow64_get_server_context_flags( DWORD flags )
+{
+ unsigned int ret = 0;
+
+ flags &= 0x3f; /* mask CPU id flags */
+ if (flags & WOW64_CONTEXT_CONTROL) ret |= SERVER_CTX_CONTROL;
+ if (flags & WOW64_CONTEXT_INTEGER) ret |= SERVER_CTX_INTEGER;
+ if (flags & WOW64_CONTEXT_SEGMENTS) ret |= SERVER_CTX_SEGMENTS;
+ if (flags & WOW64_CONTEXT_FLOATING_POINT) ret |= SERVER_CTX_FLOATING_POINT;
+ if (flags & WOW64_CONTEXT_DEBUG_REGISTERS) ret |= SERVER_CTX_DEBUG_REGISTERS;
+ if (flags & WOW64_CONTEXT_EXTENDED_REGISTERS) ret |= SERVER_CTX_EXTENDED_REGISTERS;
+ return ret;
+}
+
+static NTSTATUS wow64_context_from_server( WOW64_CONTEXT *to, const context_t *from )
+{
+ if (from->cpu != CPU_x86) return STATUS_INVALID_PARAMETER;
+
+ to->ContextFlags = WOW64_CONTEXT_i386;
+ if (from->flags & SERVER_CTX_CONTROL)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_CONTROL;
+ to->Ebp = from->ctl.i386_regs.ebp;
+ to->Esp = from->ctl.i386_regs.esp;
+ to->Eip = from->ctl.i386_regs.eip;
+ to->SegCs = from->ctl.i386_regs.cs;
+ to->SegSs = from->ctl.i386_regs.ss;
+ to->EFlags = from->ctl.i386_regs.eflags;
+ }
+ if (from->flags & SERVER_CTX_INTEGER)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_INTEGER;
+ to->Eax = from->integer.i386_regs.eax;
+ to->Ebx = from->integer.i386_regs.ebx;
+ to->Ecx = from->integer.i386_regs.ecx;
+ to->Edx = from->integer.i386_regs.edx;
+ to->Esi = from->integer.i386_regs.esi;
+ to->Edi = from->integer.i386_regs.edi;
+ }
+ if (from->flags & SERVER_CTX_SEGMENTS)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_SEGMENTS;
+ to->SegDs = from->seg.i386_regs.ds;
+ to->SegEs = from->seg.i386_regs.es;
+ to->SegFs = from->seg.i386_regs.fs;
+ to->SegGs = from->seg.i386_regs.gs;
+ }
+ if (from->flags & SERVER_CTX_FLOATING_POINT)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_FLOATING_POINT;
+ to->FloatSave.ControlWord = from->fp.i386_regs.ctrl;
+ to->FloatSave.StatusWord = from->fp.i386_regs.status;
+ to->FloatSave.TagWord = from->fp.i386_regs.tag;
+ to->FloatSave.ErrorOffset = from->fp.i386_regs.err_off;
+ to->FloatSave.ErrorSelector = from->fp.i386_regs.err_sel;
+ to->FloatSave.DataOffset = from->fp.i386_regs.data_off;
+ to->FloatSave.DataSelector = from->fp.i386_regs.data_sel;
+ to->FloatSave.Cr0NpxState = from->fp.i386_regs.cr0npx;
+ memcpy( to->FloatSave.RegisterArea, from->fp.i386_regs.regs, sizeof(to->FloatSave.RegisterArea) );
+ }
+ if (from->flags & SERVER_CTX_DEBUG_REGISTERS)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_DEBUG_REGISTERS;
+ to->Dr0 = from->debug.i386_regs.dr0;
+ to->Dr1 = from->debug.i386_regs.dr1;
+ to->Dr2 = from->debug.i386_regs.dr2;
+ to->Dr3 = from->debug.i386_regs.dr3;
+ to->Dr6 = from->debug.i386_regs.dr6;
+ to->Dr7 = from->debug.i386_regs.dr7;
+ }
+ if (from->flags & SERVER_CTX_EXTENDED_REGISTERS)
+ {
+ to->ContextFlags |= WOW64_CONTEXT_EXTENDED_REGISTERS;
+ memcpy( to->ExtendedRegisters, from->ext.i386_regs, sizeof(to->ExtendedRegisters) );
+ }
+ return STATUS_SUCCESS;
+}
+
+
+/******************************************************************************
+ * RtlWow64GetThreadContext (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlWow64GetThreadContext( HANDLE handle, WOW64_CONTEXT *context )
+{
+ BOOL self;
+ context_t server_context;
+ unsigned int server_flags = wow64_get_server_context_flags( context->ContextFlags );
+ NTSTATUS ret = get_server_context( handle, server_flags, &server_context, &self );
+ if (!ret) ret = wow64_context_from_server( context, &server_context );
+ return ret;
+}
+#endif
/******************************************************************************
* NtQueryInformationThread (NTDLL.@)
--
2.7.4
June 6, 2018
[PATCH v2 1/5] winnt.h: Add some WOW64 definitions.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
include/winnt.h | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/include/winnt.h b/include/winnt.h
index 54bf11d..c41eff4 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -2112,6 +2112,96 @@ typedef CONTEXT *PCONTEXT;
NTSYSAPI void WINAPI RtlCaptureContext(CONTEXT*);
+#define WOW64_CONTEXT_i386 0x00010000
+#define WOW64_CONTEXT_i486 0x00010000
+#define WOW64_CONTEXT_CONTROL (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000001))
+#define WOW64_CONTEXT_INTEGER (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000002))
+#define WOW64_CONTEXT_SEGMENTS (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000004))
+#define WOW64_CONTEXT_FLOATING_POINT (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000008))
+#define WOW64_CONTEXT_DEBUG_REGISTERS (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000010))
+#define WOW64_CONTEXT_EXTENDED_REGISTERS (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000020))
+#define WOW64_CONTEXT_FULL (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | WOW64_CONTEXT_SEGMENTS)
+#define WOW64_CONTEXT_ALL (WOW64_CONTEXT_CONTROL | WOW64_CONTEXT_INTEGER | \
+ WOW64_CONTEXT_SEGMENTS | WOW64_CONTEXT_FLOATING_POINT | \
+ WOW64_CONTEXT_DEBUG_REGISTERS | WOW64_CONTEXT_EXTENDED_REGISTERS)
+
+#define WOW64_CONTEXT_XSTATE (WOW64_CONTEXT_i386 | __MSABI_LONG(0x00000040))
+
+#define WOW64_CONTEXT_EXCEPTION_ACTIVE 0x08000000
+#define WOW64_CONTEXT_SERVICE_ACTIVE 0x10000000
+#define WOW64_CONTEXT_EXCEPTION_REQUEST 0x40000000
+#define WOW64_CONTEXT_EXCEPTION_REPORTING 0x80000000
+
+#define WOW64_SIZE_OF_80387_REGISTERS 80
+#define WOW64_MAXIMUM_SUPPORTED_EXTENSION 512
+
+typedef struct _WOW64_FLOATING_SAVE_AREA {
+ DWORD ControlWord;
+ DWORD StatusWord;
+ DWORD TagWord;
+ DWORD ErrorOffset;
+ DWORD ErrorSelector;
+ DWORD DataOffset;
+ DWORD DataSelector;
+ BYTE RegisterArea[WOW64_SIZE_OF_80387_REGISTERS];
+ DWORD Cr0NpxState;
+} WOW64_FLOATING_SAVE_AREA, *PWOW64_FLOATING_SAVE_AREA;
+
+#include "pshpack4.h"
+typedef struct _WOW64_CONTEXT {
+ DWORD ContextFlags;
+ DWORD Dr0;
+ DWORD Dr1;
+ DWORD Dr2;
+ DWORD Dr3;
+ DWORD Dr6;
+ DWORD Dr7;
+ WOW64_FLOATING_SAVE_AREA FloatSave;
+ DWORD SegGs;
+ DWORD SegFs;
+ DWORD SegEs;
+ DWORD SegDs;
+ DWORD Edi;
+ DWORD Esi;
+ DWORD Ebx;
+ DWORD Edx;
+ DWORD Ecx;
+ DWORD Eax;
+ DWORD Ebp;
+ DWORD Eip;
+ DWORD SegCs;
+ DWORD EFlags;
+ DWORD Esp;
+ DWORD SegSs;
+ BYTE ExtendedRegisters[WOW64_MAXIMUM_SUPPORTED_EXTENSION];
+} WOW64_CONTEXT, *PWOW64_CONTEXT;
+#include "poppack.h"
+
+typedef struct _WOW64_LDT_ENTRY {
+ WORD LimitLow;
+ WORD BaseLow;
+ union {
+ struct {
+ BYTE BaseMid;
+ BYTE Flags1;
+ BYTE Flags2;
+ BYTE BaseHi;
+ } Bytes;
+ struct {
+ DWORD BaseMid : 8;
+ DWORD Type : 5;
+ DWORD Dpl : 2;
+ DWORD Pres : 1;
+ DWORD LimitHi : 4;
+ DWORD Sys : 1;
+ DWORD Reserved_0 : 1;
+ DWORD Default_Big : 1;
+ DWORD Granularity : 1;
+ DWORD BaseHi : 8;
+ } Bits;
+ } HighWord;
+} WOW64_LDT_ENTRY, *PWOW64_LDT_ENTRY;
+
/*
* Product types
*/
--
2.7.4
June 6, 2018
Re: [PATCH 4/5] d3d9: Get rid of an unnecessary wined3d_device_set_base_vertex_index() call.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 6, 2018
Re: [PATCH 5/5] d3d11/tests: Add test for negative viewport coordinates.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 6, 2018
Re: [PATCH] d3d8/tests: Use the available ARRAY_SIZE() macro
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 6, 2018
Re: [PATCH 2/5] d3d9/tests: Test how state is reset after DrawPrimitive[Indexed]UP().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 6, 2018
Re: [PATCH 3/5] wined3d: Set stream stride and offset even when buffer is NULL.
by Matteo Bruni
2018-06-06 18:35 GMT+02:00 Henri Verbeet <hverbeet(a)gmail.com>:
> On 6 June 2018 at 00:32, Matteo Bruni <mbruni(a)codeweavers.com> wrote:
>> Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
>> ---
>> dlls/d3d8/device.c | 8 ++++++++
>> dlls/d3d9/device.c | 8 ++++++++
>> dlls/d3d9/tests/device.c | 2 +-
>> dlls/d3d9/tests/visual.c | 2 +-
>> dlls/wined3d/device.c | 6 ++----
>> 5 files changed, 20 insertions(+), 6 deletions(-)
>>
> This introduces test failures:
>
> ../../../../../src/wine-git/tools/runtest -q -P wine -T ../../.. -M
> d3d10core.dll -p d3d10core_test.exe.so device && touch device.ok
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 0.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 0.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 1.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 1.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 2.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 2.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 3.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 3.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 4.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 4.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 5.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 5.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 6.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 6.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 7.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 7.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 8.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 8.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 9.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 9.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 10.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 10.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 11.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 11.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 12.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 12.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 13.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 13.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 14.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 14.
> device.c:5496: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 15.
> device.c:5497: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 15.
>
> ../../../../../src/wine-git/tools/runtest -q -P wine -T ../../.. -M
> d3d11.dll -p d3d11_test.exe.so d3d11 && touch d3d11.ok
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 0.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 0.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 1.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 1.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 2.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 2.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 3.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 3.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 4.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 4.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 5.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 5.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 6.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 6.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 7.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 7.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 8.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 8.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 9.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 9.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 10.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 10.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 11.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 11.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 12.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 12.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 13.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 13.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 14.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 14.
> d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 15.
> d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 15.
> d3d11.c:20644: Tests skipped: Raw buffers are not supported.
> d3d11.c:20644: Tests skipped: Raw buffers are not supported.
>
> ../../../../../src/wine-git/tools/runtest -q -P wine -T ../../.. -M
> d3dx10_43.dll -p d3dx10_43_test.exe.so d3dx10 && touch d3dx10.ok
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 0.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 0.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 1.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 1.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 2.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 2.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 3.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 3.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 4.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 4.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 5.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 5.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 6.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 6.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 7.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 7.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 8.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 8.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 9.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 9.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 10.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 10.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 11.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 11.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 12.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 12.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 13.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 13.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 14.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 14.
> d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
> 0 in slot 15.
> d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
> 0 in slot 15.
Urgh, not sure how I missed these...
June 6, 2018
Re: [PATCH 3/5] wined3d: Set stream stride and offset even when buffer is NULL.
by Henri Verbeet
On 6 June 2018 at 00:32, Matteo Bruni <mbruni(a)codeweavers.com> wrote:
> Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
> ---
> dlls/d3d8/device.c | 8 ++++++++
> dlls/d3d9/device.c | 8 ++++++++
> dlls/d3d9/tests/device.c | 2 +-
> dlls/d3d9/tests/visual.c | 2 +-
> dlls/wined3d/device.c | 6 ++----
> 5 files changed, 20 insertions(+), 6 deletions(-)
>
This introduces test failures:
../../../../../src/wine-git/tools/runtest -q -P wine -T ../../.. -M
d3d10core.dll -p d3d10core_test.exe.so device && touch device.ok
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 0.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 0.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 1.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 1.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 2.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 2.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 3.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 3.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 4.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 4.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 5.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 5.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 6.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 6.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 7.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 7.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 8.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 8.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 9.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 9.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 10.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 10.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 11.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 11.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 12.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 12.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 13.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 13.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 14.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 14.
device.c:5496: Test succeeded inside todo block: Got unexpected stride
0 in slot 15.
device.c:5497: Test succeeded inside todo block: Got unexpected offset
0 in slot 15.
../../../../../src/wine-git/tools/runtest -q -P wine -T ../../.. -M
d3d11.dll -p d3d11_test.exe.so d3d11 && touch d3d11.ok
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 0.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 0.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 1.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 1.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 2.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 2.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 3.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 3.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 4.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 4.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 5.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 5.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 6.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 6.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 7.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 7.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 8.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 8.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 9.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 9.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 10.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 10.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 11.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 11.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 12.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 12.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 13.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 13.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 14.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 14.
d3d11.c:10652: Test succeeded inside todo block: Got unexpected stride
0 in slot 15.
d3d11.c:10653: Test succeeded inside todo block: Got unexpected offset
0 in slot 15.
d3d11.c:20644: Tests skipped: Raw buffers are not supported.
d3d11.c:20644: Tests skipped: Raw buffers are not supported.
../../../../../src/wine-git/tools/runtest -q -P wine -T ../../.. -M
d3dx10_43.dll -p d3dx10_43_test.exe.so d3dx10 && touch d3dx10.ok
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 0.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 0.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 1.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 1.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 2.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 2.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 3.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 3.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 4.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 4.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 5.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 5.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 6.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 6.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 7.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 7.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 8.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 8.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 9.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 9.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 10.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 10.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 11.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 11.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 12.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 12.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 13.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 13.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 14.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 14.
d3dx10.c:483: Test succeeded inside todo block: Got unexpected stride
0 in slot 15.
d3dx10.c:484: Test succeeded inside todo block: Got unexpected offset
0 in slot 15.
June 6, 2018
Re: [PATCH 1/5] wined3d: Declare the correct number and type of fragment shader color outputs.
by Matteo Bruni
2018-06-06 18:30 GMT+02:00 Henri Verbeet <hverbeet(a)gmail.com>:
> On 6 June 2018 at 18:25, Matteo Bruni <matteo.mystral(a)gmail.com> wrote:
>> Hmm, it was intentional but it looks like it doesn't matter in
>> practice. We only execute that if (!needs_legacy_glsl_syntax()), which
>> means GLSL 1.30+ and thus OpenGL 3.0+. That requires that
>> GL_MAX_DRAW_BUFFERS is >= 8. OpenGL ES apparently only mandates 4 draw
>> buffers so things would be a bit more murky there, except that there
>> is no glBindFragDataLocation() in ES at all (you're supposed to use
>> layout qualifiers in the fragment shader instead - I guess I'll have
>> to rework it again to handle that).
>>
>> Anyway, I can switch to gl_info->limits.buffers, it shouldn't hurt and
>> I have to resend it anyway...
>>
> I don't think it (currently) happens in practice, but
> gl_info->limits.buffers can potentially be larger than
> MAX_RENDER_TARGET_VIEWS.
Yeah, it's currently clamped to MAX_RENDER_TARGET_VIEWS.
I can also leave this as-is :)
June 6, 2018
Re: [PATCH 1/5] wined3d: Declare the correct number and type of fragment shader color outputs.
by Henri Verbeet
On 6 June 2018 at 18:25, Matteo Bruni <matteo.mystral(a)gmail.com> wrote:
> Hmm, it was intentional but it looks like it doesn't matter in
> practice. We only execute that if (!needs_legacy_glsl_syntax()), which
> means GLSL 1.30+ and thus OpenGL 3.0+. That requires that
> GL_MAX_DRAW_BUFFERS is >= 8. OpenGL ES apparently only mandates 4 draw
> buffers so things would be a bit more murky there, except that there
> is no glBindFragDataLocation() in ES at all (you're supposed to use
> layout qualifiers in the fragment shader instead - I guess I'll have
> to rework it again to handle that).
>
> Anyway, I can switch to gl_info->limits.buffers, it shouldn't hurt and
> I have to resend it anyway...
>
I don't think it (currently) happens in practice, but
gl_info->limits.buffers can potentially be larger than
MAX_RENDER_TARGET_VIEWS.
June 6, 2018
Re: [PATCH 1/5] wined3d: Declare the correct number and type of fragment shader color outputs.
by Matteo Bruni
2018-06-06 3:32 GMT+02:00 Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>:
> Hi Matteo,
>
>
> On 06/06/18 08:32, Matteo Bruni wrote:
>> {
>> - GL_EXTCALL(glBindFragDataLocation(program_id, 0, "ps_out"));
>> - checkGLcall("glBindFragDataLocation");
>> + for (i = 0; i < MAX_RENDER_TARGET_VIEWS; ++i)
> Is there a reason why MAX_RENDER_TARGET_VIEWS is used instead of
> "gl_info->limits.buffers"?
Hmm, it was intentional but it looks like it doesn't matter in
practice. We only execute that if (!needs_legacy_glsl_syntax()), which
means GLSL 1.30+ and thus OpenGL 3.0+. That requires that
GL_MAX_DRAW_BUFFERS is >= 8. OpenGL ES apparently only mandates 4 draw
buffers so things would be a bit more murky there, except that there
is no glBindFragDataLocation() in ES at all (you're supposed to use
layout qualifiers in the fragment shader instead - I guess I'll have
to rework it again to handle that).
Anyway, I can switch to gl_info->limits.buffers, it shouldn't hurt and
I have to resend it anyway...
June 6, 2018
Re: [PATCH 4/4] winevulkan: Update Vulkan support to 1.0.76.
by Roderick Colenbrander
On Wed, Jun 6, 2018 at 2:20 AM, Józef Kucia <joseph.kucia(a)gmail.com> wrote:
> On Tue, Jun 5, 2018 at 3:19 PM, Alexandre Julliard <julliard(a)winehq.org> wrote:
>> Roderick Colenbrander <thunderbird2k(a)gmail.com> writes:
>>
>>> Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
>>> ---
>>> dlls/vulkan-1/vulkan-1.spec | 28 +
>>> dlls/winevulkan/make_vulkan | 206 +-
>>> dlls/winevulkan/vk.xml | 6448 ++++++++++++++++++++++++++-------------
>>
>> I'd suggest downloading vk.xml like we do for the OpenGL spec
>> files. It's not clear that the license exception also applies to the
>> source file, so I think it would be better if we didn't distribute it.
>
> Thanks. I've submitted a patch to remove vk.xml from the repository.
> The patch is probably stuck in the moderation queue.
Thanks, I didn't have time for it yet (busy week).
June 6, 2018
Re: [PATCH 4/4] msi: Implement deferral for standard and custom actions.
by Zebediah Figura
On 06/06/18 04:05, Hans Leidekker wrote:
> On Wed, 2018-06-06 at 00:59 -0500, Zebediah Figura wrote:
>> Fixes https://bugs.winehq.org/show_bug.cgi?id=34989.
>>
>> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
>> ---
>> Tested for regressions against winetricks-test and Microsoft Office 2010.
>
> The patch looks good but it introduces an error in the wine-mono installer:
>
> 0017:trace:msi:HANDLE_CustomType34 cmd L"rundll32 setupapi.dll,InstallHinfSection DefaultInstall 128 C:\\windows\\mono\\mono-2.0\\support\\dotnetfakedlls.inf" dir L"C:\\windows\\mono\\mono-2.0\\support\\"
> 0017:err:msi:execute_command unable to execute command 267
>
> Looks like custom action INSTALLFAKEDLLS depended on the wrong order. Marking
> it as a deferred custom action should fix that.
>
>
>
Thanks; I've sent a pull request to wine-mono.
June 6, 2018
Re: [PATCH] imm32/tests: Use the available ARRAY_SIZE() macro
by Aric Stewart
Signed-off-by: Aric Stewart <aric(a)codeweavers.com>
On 6/5/18 1:09 PM, Michael Stefaniuc wrote:
> Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
> ---
> dlls/imm32/tests/imm32.c | 14 ++++++--------
> 1 file changed, 6 insertions(+), 8 deletions(-)
>
> diff --git a/dlls/imm32/tests/imm32.c b/dlls/imm32/tests/imm32.c
> index be3ddfce03..ee1aeb3965 100644
> --- a/dlls/imm32/tests/imm32.c
> +++ b/dlls/imm32/tests/imm32.c
> @@ -26,8 +26,6 @@
> #include "imm.h"
> #include "ddk/imm.h"
>
> -#define NUMELEMS(array) (sizeof((array))/sizeof((array)[0]))
> -
> static BOOL (WINAPI *pImmAssociateContextEx)(HWND,HIMC,DWORD);
> static BOOL (WINAPI *pImmIsUIMessageA)(HWND,UINT,WPARAM,LPARAM);
> static UINT (WINAPI *pSendInput) (UINT, INPUT*, size_t);
> @@ -73,7 +71,7 @@ static LRESULT CALLBACK get_msg_filter(int nCode, WPARAM wParam, LPARAM lParam)
> MSG *msg = (MSG*)lParam;
>
> if ((msg->hwnd == msg_spy.hwnd || msg_spy.hwnd == NULL) &&
> - (msg_spy.i_msg < NUMELEMS(msg_spy.msgs)))
> + (msg_spy.i_msg < ARRAY_SIZE(msg_spy.msgs)))
> {
> msg_spy.msgs[msg_spy.i_msg].msg.hwnd = msg->hwnd;
> msg_spy.msgs[msg_spy.i_msg].msg.message = msg->message;
> @@ -94,7 +92,7 @@ static LRESULT CALLBACK call_wnd_proc_filter(int nCode, WPARAM wParam,
> CWPSTRUCT *cwp = (CWPSTRUCT*)lParam;
>
> if (((cwp->hwnd == msg_spy.hwnd || msg_spy.hwnd == NULL)) &&
> - (msg_spy.i_msg < NUMELEMS(msg_spy.msgs)))
> + (msg_spy.i_msg < ARRAY_SIZE(msg_spy.msgs)))
> {
> memcpy(&msg_spy.msgs[msg_spy.i_msg].msg, cwp, sizeof(msg_spy.msgs[0].msg));
> msg_spy.msgs[msg_spy.i_msg].post = FALSE;
> @@ -126,7 +124,7 @@ static imm_msgs* msg_spy_find_next_msg(UINT message, UINT *start) {
>
> msg_spy_pump_msg_queue();
>
> - if (msg_spy.i_msg >= NUMELEMS(msg_spy.msgs))
> + if (msg_spy.i_msg >= ARRAY_SIZE(msg_spy.msgs))
> fprintf(stdout, "%s:%d: msg_spy: message buffer overflow!\n",
> __FILE__, __LINE__);
>
> @@ -1067,8 +1065,8 @@ static BOOL CALLBACK is_ime_window_proc(HWND hWnd, LPARAM param)
> static const WCHAR imeW[] = {'I','M','E',0};
> WCHAR class_nameW[16];
> HWND *ime_window = (HWND *)param;
> - if (GetClassNameW(hWnd, class_nameW, sizeof(class_nameW)/sizeof(class_nameW[0])) &&
> - !lstrcmpW(class_nameW, imeW)) {
> + if (GetClassNameW(hWnd, class_nameW, ARRAY_SIZE(class_nameW)) && !lstrcmpW(class_nameW, imeW))
> + {
> *ime_window = hWnd;
> return FALSE;
> }
> @@ -1229,7 +1227,7 @@ static void test_default_ime_window_creation(void)
> { FALSE, FALSE }
> };
>
> - for (i = 0; i < sizeof(testcases)/sizeof(testcases[0]); i++)
> + for (i = 0; i < ARRAY_SIZE(testcases); i++)
> {
> thread = CreateThread(NULL, 0, test_default_ime_window_cb, &testcases[i], 0, NULL);
> ok(thread != NULL, "CreateThread failed with error %u\n", GetLastError());
>
June 6, 2018
Re: [PATCH] ntoskrnl: Have MmIsAddressValid use IsBadReadPtr.
by Derek Lesho
Hi Thomas, in your example, does &Base refer to the base of
ntoskrnl.exe? If so, why are you allocating a buffer there, wouldn't
that corrupt the memory of ntoskrnl, or am I misunderstanding what
your code is doing. On windows, do drivers have access to change the
memory of ntoskrnl?
Atleast in EAC, they find the address of a function inside of the
ntoskrnl address space, and continuously decrement the address until
MMisAddressValid returns FALSE. Without my patch, wine always returns
FALSE to EAC, even on the first address check.
On Wed, Jun 6, 2018 at 3:51 AM, Thomas Faber <thomas.faber(a)reactos.org> wrote:
>
> On 2018-06-06 04:36, Zhiyi Zhang wrote:
> > The function is meant to be used in nt kernel space, however wineserver is
> > in user space as far as I know. So we would need different implementation.
> >
> > May be we could do something like return !IsBadWritePtr(VirtualAddress, 1) || !IsBadReadPtr(VirtualAddress, 1).
> > And write a test to verify such behavior.
>
> IsBadReadPtr(x) implies IsBadWritePtr(x), since Windows does not have a
> concept of "write-only" access to pages. So checking both seems
> unnecessary.
> The real difference between IsBadReadPtr and MmIsAddressValid is that
> the former can actually _make_ the address valid by causing a page
> fault (and paging in or zeroing the page). MmIsAddressValid on the
> other hand would simply look at the current state of the page table
> entry without side effects.
>
> This stuff isn't hard to test per se, but a full test that's correct for
> Windows kernel land will not currently work in Wine due to unimplemented
> Mm stuff, e.g.
>
> for (protection in [PAGE_NOACCESS, PAGE_READONLY, PAGE_READWRITE])
> {
> ZwAllocateVirtualMemory(..., &Base, ..., MEM_COMMIT, protection);
> // physical page is not assigned until first access
> todo_wine ok(!MmIsAddressValid(Base, 1), ...);
> // force a physical page to appear and prevent it from getting paged out
> mdl = IoAllocateMdl(Base, 1, FALSE, FALSE, NULL);
> __TRY { MmProbeAndLockPages(mdl, UserMode, IoModifyAccess); todo_wine ok(protection != PAGE_NOACCESS, ...); }
> __EXCEPT_PAGE_FAULT { ok(protection == PAGE_NOACCESS, ...); goto Next; }
> // the system address is now guaranteed to be valid
> todo_wine ok(MmIsAddressValid(MmGetSystemAddressForMdlSafe(mdl, NormalPagePriority), 1), ...);
> MmUnlockPages...
> Next:
> IoFreeMdl...
> ZwFreeVirtualMemory...
> }
>
> ... has a todo with pretty much every ok(), with or without the patch :\
>
>
> With some luck, the simpler
> void test_function()
> {
> ok(MmIsAddressValid((void*)test_function, ...); // fails in master, succeeds with patch?
> ptr = ExAllocatePoolWithTag(NonPagedPool, ...)
> ok(MmIsAddressValid(ptr, ...);
> ExFreePoolWithTag...
> ok(!MmIsAddressValid(NULL), ...);
> }
>
> might be enough to show that the patch is correct though.
June 6, 2018
Re: [PATCH 1/5] wined3d: Declare the correct number and type of fragment shader color outputs.
by Henri Verbeet
On 6 June 2018 at 00:32, Matteo Bruni <mbruni(a)codeweavers.com> wrote:
> +static void shader_glsl_generate_color_output(struct wined3d_string_buffer *buffer,
> + const struct wined3d_gl_info *gl_info, const struct wined3d_shader *shader)
> +{
> + const struct wined3d_shader_signature *output_signature = &shader->output_signature;
> + unsigned int i;
> +
> + if (output_signature->element_count)
> + {
> + for (i = 0; i < output_signature->element_count; ++i)
> + {
> + const struct wined3d_shader_signature_element *output = &output_signature->elements[i];
> +
> + if (strncasecmp(output->semantic_name, "SV_Target", sizeof("SV_Target")))
> + continue;
Should this really match against the "semantic_name" string, or does
the "sysval_semantic" field also contain that information?
> + switch (output->component_type)
> + {
> + case WINED3D_TYPE_UINT:
> + shader_addline(buffer, "color_out%u = floatBitsToUint(ps_out[%u]);\n",
> + output->semantic_idx, output->semantic_idx);
> + break;
> + case WINED3D_TYPE_INT:
> + shader_addline(buffer, "color_out%u = floatBitsToInt(ps_out[%u]);\n",
> + output->semantic_idx, output->semantic_idx);
> + break;
> +
> + default:
> + FIXME("Unhandled type %#x.\n", output->component_type);
> + /* Fall through. */
> + case WINED3D_TYPE_UNKNOWN:
> + case WINED3D_TYPE_FLOAT:
> + shader_addline(buffer, "color_out%u = ps_out[%u];\n",
> + output->semantic_idx, output->semantic_idx);
> + }
I think shader_glsl_sprintf_cast() with appropriate arguments could
also handle this.
June 6, 2018
Re: [PATCH 2/3] kernel32: Implement Wow64GetThreadContext().
by Alexandre Julliard
Zebediah Figura <zfigura(a)codeweavers.com> writes:
> Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
> ---
> With code essentially copied from ntdll. As far as I can tell there is no
> ntdll entry point for this function.
RtlWow64GetThreadContext() is probably what you are looking for. It will
need some test cases obviously.
--
Alexandre Julliard
julliard(a)winehq.org
June 6, 2018
Re: [PATCH] jscript/tests: Use the available ARRAY_SIZE() macro
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
June 6, 2018
Re: [PATCH 0/4] winevulkan: Update to 1.0.76
by Józef Kucia
On Mon, Jun 4, 2018 at 12:52 AM, Roderick Colenbrander
<thunderbird2k(a)gmail.com> wrote:
> Vulkan 1.1 moved a lot of extensions into its Core including interop extensions
> for memory, fences and semaphores. These rely on platform specific functionality
> and would need some more implementation work to support. (It is also the question
> how we would deal with these. Probably needs to be implemented in winex11.drv to
> allow vkd3d to use them).
I think it would be better to simply implement external objects
extensions in winevulkan, at least initially.
June 6, 2018
[PATCH 4/4] webservices: Fix handling of empty text field mappings.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/reader.c | 355 +++++++++++++++++++---------------------
dlls/webservices/tests/reader.c | 150 +++++++++++++++++
2 files changed, 314 insertions(+), 191 deletions(-)
diff --git a/dlls/webservices/reader.c b/dlls/webservices/reader.c
index 6925200a59..087ad0a9cc 100644
--- a/dlls/webservices/reader.c
+++ b/dlls/webservices/reader.c
@@ -4442,24 +4442,24 @@ static HRESULT text_to_bool( const WS_XML_TEXT *text, BOOL *val )
static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_BOOL_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
- BOOL found, val = FALSE;
+ BOOL val = FALSE;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_bool( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_bool( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -4468,7 +4468,7 @@ static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -4476,7 +4476,7 @@ static HRESULT read_type_bool( struct reader *reader, WS_TYPE_MAPPING mapping,
{
BOOL *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -4524,25 +4524,24 @@ static HRESULT text_to_int8( const WS_XML_TEXT *text, INT64 *val )
static HRESULT read_type_int8( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_INT8_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
INT64 val = 0;
- BOOL found;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_int8( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_int8( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -4551,7 +4550,7 @@ static HRESULT read_type_int8( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -4559,7 +4558,7 @@ static HRESULT read_type_int8( struct reader *reader, WS_TYPE_MAPPING mapping,
{
INT8 *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -4607,25 +4606,24 @@ static HRESULT text_to_int16( const WS_XML_TEXT *text, INT64 *val )
static HRESULT read_type_int16( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_INT16_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
INT64 val = 0;
- BOOL found;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_int16( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_int16( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -4634,7 +4632,7 @@ static HRESULT read_type_int16( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -4642,7 +4640,7 @@ static HRESULT read_type_int16( struct reader *reader, WS_TYPE_MAPPING mapping,
{
INT16 *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -4688,25 +4686,24 @@ static HRESULT text_to_int32( const WS_XML_TEXT *text, INT64 *val )
static HRESULT read_type_int32( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_INT32_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
INT64 val = 0;
- BOOL found;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_int32( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_int32( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -4715,7 +4712,7 @@ static HRESULT read_type_int32( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -4723,7 +4720,7 @@ static HRESULT read_type_int32( struct reader *reader, WS_TYPE_MAPPING mapping,
{
INT32 *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -4769,25 +4766,24 @@ static HRESULT text_to_int64( const WS_XML_TEXT *text, INT64 *val )
static HRESULT read_type_int64( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_INT64_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
INT64 val = 0;
- BOOL found;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_int64( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_int64( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -4796,7 +4792,7 @@ static HRESULT read_type_int64( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -4804,7 +4800,7 @@ static HRESULT read_type_int64( struct reader *reader, WS_TYPE_MAPPING mapping,
{
INT64 *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -4851,25 +4847,24 @@ static HRESULT text_to_uint8( const WS_XML_TEXT *text, UINT64 *val )
static HRESULT read_type_uint8( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_UINT8_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
UINT64 val = 0;
- BOOL found;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_uint8( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_uint8( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -4878,7 +4873,7 @@ static HRESULT read_type_uint8( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -4886,7 +4881,7 @@ static HRESULT read_type_uint8( struct reader *reader, WS_TYPE_MAPPING mapping,
{
UINT8 *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -4942,25 +4937,24 @@ static HRESULT text_to_uint16( const WS_XML_TEXT *text, UINT64 *val )
static HRESULT read_type_uint16( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_UINT16_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
UINT64 val = 0;
- BOOL found;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_uint16( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_uint16( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -4969,7 +4963,7 @@ static HRESULT read_type_uint16( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -4977,7 +4971,7 @@ static HRESULT read_type_uint16( struct reader *reader, WS_TYPE_MAPPING mapping,
{
UINT16 *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5032,25 +5026,24 @@ static HRESULT text_to_uint32( const WS_XML_TEXT *text, UINT64 *val )
static HRESULT read_type_uint32( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_UINT32_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
UINT64 val = 0;
- BOOL found;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_uint32( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_uint32( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -5059,7 +5052,7 @@ static HRESULT read_type_uint32( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -5067,7 +5060,7 @@ static HRESULT read_type_uint32( struct reader *reader, WS_TYPE_MAPPING mapping,
{
UINT32 *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5120,25 +5113,24 @@ static HRESULT text_to_uint64( const WS_XML_TEXT *text, UINT64 *val )
static HRESULT read_type_uint64( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_UINT64_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
UINT64 val = 0;
- BOOL found;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_uint64( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_uint64( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -5147,7 +5139,7 @@ static HRESULT read_type_uint64( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -5155,7 +5147,7 @@ static HRESULT read_type_uint64( struct reader *reader, WS_TYPE_MAPPING mapping,
{
UINT64 *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5201,22 +5193,21 @@ static HRESULT text_to_float( const WS_XML_TEXT *text, float *val )
static HRESULT read_type_float( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_FLOAT_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
float val = 0.0;
- BOOL found;
if (desc) FIXME( "ignoring description\n" );
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_float( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_float( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -5225,7 +5216,7 @@ static HRESULT read_type_float( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -5233,7 +5224,7 @@ static HRESULT read_type_float( struct reader *reader, WS_TYPE_MAPPING mapping,
{
float *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5279,22 +5270,21 @@ static HRESULT text_to_double( const WS_XML_TEXT *text, double *val )
static HRESULT read_type_double( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_DOUBLE_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
double val = 0.0;
- BOOL found;
if (desc) FIXME( "ignoring description\n" );
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_double( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_double( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -5303,7 +5293,7 @@ static HRESULT read_type_double( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -5311,7 +5301,7 @@ static HRESULT read_type_double( struct reader *reader, WS_TYPE_MAPPING mapping,
{
double *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5343,20 +5333,19 @@ static HRESULT text_to_wsz( const WS_XML_TEXT *text, WS_HEAP *heap, WCHAR **ret
static HRESULT read_type_wsz( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_WSZ_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, WCHAR **ret, ULONG size )
+ WS_HEAP *heap, WCHAR **ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
WCHAR *str = NULL;
- BOOL found;
if (desc)
{
FIXME( "description not supported\n" );
return E_NOTIMPL;
}
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_wsz( text, heap, &str )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_wsz( text, heap, &str )) != S_OK) return hr;
switch (option)
{
@@ -5398,22 +5387,21 @@ static HRESULT get_enum_value( const WS_XML_TEXT *text, const WS_ENUM_DESCRIPTIO
static HRESULT read_type_enum( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_ENUM_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
int val = 0;
- BOOL found;
if (!desc) return E_INVALIDARG;
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = get_enum_value( text, desc, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = get_enum_value( text, desc, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -5422,7 +5410,7 @@ static HRESULT read_type_enum( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -5430,7 +5418,7 @@ static HRESULT read_type_enum( struct reader *reader, WS_TYPE_MAPPING mapping,
{
int *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5476,22 +5464,21 @@ static HRESULT text_to_datetime( const WS_XML_TEXT *text, WS_DATETIME *val )
static HRESULT read_type_datetime( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_DATETIME_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
HRESULT hr;
WS_DATETIME val = {0, WS_DATETIME_FORMAT_UTC};
- BOOL found;
if (desc) FIXME( "ignoring description\n" );
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_datetime( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_datetime( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -5500,7 +5487,7 @@ static HRESULT read_type_datetime( struct reader *reader, WS_TYPE_MAPPING mappin
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -5508,7 +5495,7 @@ static HRESULT read_type_datetime( struct reader *reader, WS_TYPE_MAPPING mappin
{
WS_DATETIME *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5554,22 +5541,21 @@ static HRESULT text_to_guid( const WS_XML_TEXT *text, GUID *val )
static HRESULT read_type_guid( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_GUID_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
GUID val = {0};
HRESULT hr;
- BOOL found;
if (desc) FIXME( "ignoring description\n" );
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_guid( text, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_guid( text, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -5578,7 +5564,7 @@ static HRESULT read_type_guid( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -5586,7 +5572,7 @@ static HRESULT read_type_guid( struct reader *reader, WS_TYPE_MAPPING mapping,
{
GUID *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5634,22 +5620,21 @@ static HRESULT text_to_unique_id( const WS_XML_TEXT *text, WS_HEAP *heap, WS_UNI
static HRESULT read_type_unique_id( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_UNIQUE_ID_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
WS_UNIQUE_ID val = {{0}};
HRESULT hr;
- BOOL found;
if (desc) FIXME( "ignoring description\n" );
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_unique_id( text, heap, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_unique_id( text, heap, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -5658,7 +5643,7 @@ static HRESULT read_type_unique_id( struct reader *reader, WS_TYPE_MAPPING mappi
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -5666,7 +5651,7 @@ static HRESULT read_type_unique_id( struct reader *reader, WS_TYPE_MAPPING mappi
{
WS_UNIQUE_ID *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5714,17 +5699,16 @@ static HRESULT text_to_string( const WS_XML_TEXT *text, WS_HEAP *heap, WS_STRING
static HRESULT read_type_string( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_STRING_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
WS_STRING val = {0};
HRESULT hr;
- BOOL found;
if (desc) FIXME( "ignoring description\n" );
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_string( text, heap, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_string( text, heap, &val )) != S_OK) return hr;
switch (option)
{
@@ -5748,7 +5732,7 @@ static HRESULT read_type_string( struct reader *reader, WS_TYPE_MAPPING mapping,
{
WS_STRING *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5796,17 +5780,16 @@ static HRESULT text_to_bytes( const WS_XML_TEXT *text, WS_HEAP *heap, WS_BYTES *
static HRESULT read_type_bytes( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_BYTES_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
WS_BYTES val = {0};
HRESULT hr;
- BOOL found;
if (desc) FIXME( "ignoring description\n" );
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_bytes( text, heap, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_bytes( text, heap, &val )) != S_OK) return hr;
switch (option)
{
@@ -5830,7 +5813,7 @@ static HRESULT read_type_bytes( struct reader *reader, WS_TYPE_MAPPING mapping,
{
WS_BYTES *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5856,17 +5839,16 @@ static HRESULT text_to_xml_string( const WS_XML_TEXT *text, WS_HEAP *heap, WS_XM
static HRESULT read_type_xml_string( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_XML_STRING_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
WS_XML_STRING val = {0};
HRESULT hr;
- BOOL found;
if (desc) FIXME( "ignoring description\n" );
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_xml_string( text, heap, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_xml_string( text, heap, &val )) != S_OK) return hr;
switch (option)
{
@@ -5890,7 +5872,7 @@ static HRESULT read_type_xml_string( struct reader *reader, WS_TYPE_MAPPING mapp
{
WS_XML_STRING *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -5941,12 +5923,11 @@ static HRESULT text_to_qname( struct reader *reader, const WS_XML_TEXT *text, WS
static HRESULT read_type_qname( struct reader *reader, WS_TYPE_MAPPING mapping,
const WS_XML_STRING *localname, const WS_XML_STRING *ns,
const WS_XML_QNAME_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
const WS_XML_TEXT *text;
WS_XML_QNAME val = {{0}};
HRESULT hr;
- BOOL found;
if (desc) FIXME( "ignoring description\n" );
@@ -5954,13 +5935,13 @@ static HRESULT read_type_qname( struct reader *reader, WS_TYPE_MAPPING mapping,
if ((hr = read_startelement( reader )) != S_OK) return hr;
if (node_type( reader->current ) != WS_XML_NODE_TYPE_TEXT) return WS_E_INVALID_FORMAT;
- if ((hr = get_text( reader, mapping, localname, ns, &text, &found )) != S_OK) return hr;
- if (found && (hr = text_to_qname( reader, text, heap, &val )) != S_OK) return hr;
+ if ((hr = get_text( reader, mapping, localname, ns, &text, found )) != S_OK) return hr;
+ if (*found && (hr = text_to_qname( reader, text, heap, &val )) != S_OK) return hr;
switch (option)
{
case WS_READ_REQUIRED_VALUE:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_NILLABLE_VALUE:
@@ -5969,7 +5950,7 @@ static HRESULT read_type_qname( struct reader *reader, WS_TYPE_MAPPING mapping,
break;
case WS_READ_REQUIRED_POINTER:
- if (!found) return WS_E_INVALID_FORMAT;
+ if (!*found) return WS_E_INVALID_FORMAT;
/* fall through */
case WS_READ_OPTIONAL_POINTER:
@@ -5977,7 +5958,7 @@ static HRESULT read_type_qname( struct reader *reader, WS_TYPE_MAPPING mapping,
{
WS_XML_QNAME *heap_val = NULL;
if (size != sizeof(heap_val)) return E_INVALIDARG;
- if (found)
+ if (*found)
{
if (!(heap_val = ws_alloc( heap, sizeof(*heap_val) ))) return WS_E_QUOTA_EXCEEDED;
*heap_val = val;
@@ -6224,7 +6205,7 @@ static HRESULT read_type_union( struct reader *reader, const WS_UNION_DESCRIPTIO
static HRESULT read_type( struct reader *, WS_TYPE_MAPPING, WS_TYPE, const WS_XML_STRING *,
const WS_XML_STRING *, const void *, WS_READ_OPTION, WS_HEAP *,
- void *, ULONG );
+ void *, ULONG, BOOL * );
static HRESULT read_type_array( struct reader *reader, const WS_FIELD_DESCRIPTION *desc, WS_HEAP *heap,
void **ret, ULONG *count )
@@ -6232,6 +6213,7 @@ static HRESULT read_type_array( struct reader *reader, const WS_FIELD_DESCRIPTIO
HRESULT hr;
ULONG item_size, nb_items = 0, nb_allocated = 1, offset = 0;
WS_READ_OPTION option;
+ BOOL found;
char *buf;
if (!(option = get_field_read_option( desc->type, desc->options ))) return E_INVALIDARG;
@@ -6257,7 +6239,6 @@ static HRESULT read_type_array( struct reader *reader, const WS_FIELD_DESCRIPTIO
if (desc->type == WS_UNION_TYPE)
{
- BOOL found;
hr = read_type_union( reader, desc->typeDescription, heap, buf + offset, item_size, &found );
if (hr != S_OK)
{
@@ -6269,7 +6250,7 @@ static HRESULT read_type_array( struct reader *reader, const WS_FIELD_DESCRIPTIO
else
{
hr = read_type( reader, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->itemLocalName, desc->itemNs,
- desc->typeDescription, option, heap, buf + offset, item_size );
+ desc->typeDescription, option, heap, buf + offset, item_size, &found );
if (hr == WS_E_INVALID_FORMAT) break;
if (hr != S_OK)
{
@@ -6301,18 +6282,22 @@ static HRESULT read_type_array( struct reader *reader, const WS_FIELD_DESCRIPTIO
static HRESULT read_type_text( struct reader *reader, const WS_FIELD_DESCRIPTION *desc,
WS_READ_OPTION option, WS_HEAP *heap, void *ret, ULONG size )
{
+ struct reader_pos pos;
+ BOOL found;
HRESULT hr;
+
if (reader->current == reader->last)
{
- BOOL found;
if ((hr = read_to_startelement( reader, &found )) != S_OK) return hr;
if (!found) return WS_E_INVALID_FORMAT;
}
- if ((hr = read_next_node( reader )) != S_OK) return hr;
- if (node_type( reader->current ) != WS_XML_NODE_TYPE_TEXT) return WS_E_INVALID_FORMAT;
- return read_type( reader, WS_ANY_ELEMENT_TYPE_MAPPING, desc->type, NULL, NULL,
- desc->typeDescription, option, heap, ret, size );
+ save_reader_position( reader, &pos );
+ if ((hr = read_next_node( reader )) != S_OK) return hr;
+ hr = read_type( reader, WS_ANY_ELEMENT_TYPE_MAPPING, desc->type, NULL, NULL,
+ desc->typeDescription, option, heap, ret, size, &found );
+ if (hr == S_OK && !found) restore_reader_position( reader, &pos );
+ return hr;
}
static HRESULT read_type_field( struct reader *reader, const WS_FIELD_DESCRIPTION *desc, WS_HEAP *heap, char *buf,
@@ -6322,6 +6307,7 @@ static HRESULT read_type_field( struct reader *reader, const WS_FIELD_DESCRIPTIO
WS_READ_OPTION option;
ULONG size;
HRESULT hr;
+ BOOL found;
if (!desc) return E_INVALIDARG;
if (desc->options & ~(WS_FIELD_POINTER|WS_FIELD_OPTIONAL|WS_FIELD_NILLABLE|WS_FIELD_NILLABLE_ITEM))
@@ -6345,17 +6331,16 @@ static HRESULT read_type_field( struct reader *reader, const WS_FIELD_DESCRIPTIO
case WS_ATTRIBUTE_FIELD_MAPPING:
hr = read_type( reader, WS_ATTRIBUTE_TYPE_MAPPING, desc->type, desc->localName, desc->ns,
- desc->typeDescription, option, heap, ptr, size );
+ desc->typeDescription, option, heap, ptr, size, &found );
break;
case WS_ELEMENT_FIELD_MAPPING:
hr = read_type( reader, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->localName, desc->ns,
- desc->typeDescription, option, heap, ptr, size );
+ desc->typeDescription, option, heap, ptr, size, &found );
break;
case WS_ELEMENT_CHOICE_FIELD_MAPPING:
{
- BOOL found;
if (desc->type != WS_UNION_TYPE || !desc->typeDescription ||
(desc->options & (WS_FIELD_POINTER|WS_FIELD_NILLABLE))) return E_INVALIDARG;
hr = read_type_union( reader, desc->typeDescription, heap, ptr, size, &found );
@@ -6406,7 +6391,7 @@ static HRESULT read_type_field( struct reader *reader, const WS_FIELD_DESCRIPTIO
static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping, const WS_XML_STRING *localname,
const WS_XML_STRING *ns, const WS_STRUCT_DESCRIPTION *desc, WS_READ_OPTION option,
- WS_HEAP *heap, void *ret, ULONG size )
+ WS_HEAP *heap, void *ret, ULONG size, BOOL *found )
{
ULONG i, offset;
HRESULT hr;
@@ -6481,6 +6466,8 @@ static HRESULT read_type_struct( struct reader *reader, WS_TYPE_MAPPING mapping,
struct node *parent = find_parent( reader );
parent->flags |= NODE_FLAG_IGNORE_TRAILING_ELEMENT_CONTENT;
}
+
+ *found = TRUE;
return S_OK;
}
@@ -6576,7 +6563,7 @@ static HRESULT is_nil_element( const WS_XML_ELEMENT_NODE *elem )
static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYPE type,
const WS_XML_STRING *localname, const WS_XML_STRING *ns, const void *desc,
- WS_READ_OPTION option, WS_HEAP *heap, void *value, ULONG size )
+ WS_READ_OPTION option, WS_HEAP *heap, void *value, ULONG size, BOOL *found )
{
HRESULT hr;
@@ -6585,114 +6572,94 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP
if (mapping == WS_ELEMENT_TYPE_MAPPING && is_nil_element( &reader->current->hdr ))
{
if (option != WS_READ_NILLABLE_POINTER && option != WS_READ_NILLABLE_VALUE) return WS_E_INVALID_FORMAT;
+ *found = TRUE;
return end_mapping( reader, mapping );
}
switch (type)
{
case WS_BOOL_TYPE:
- if ((hr = read_type_bool( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_bool( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_INT8_TYPE:
- if ((hr = read_type_int8( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_int8( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_INT16_TYPE:
- if ((hr = read_type_int16( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_int16( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_INT32_TYPE:
- if ((hr = read_type_int32( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_int32( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_INT64_TYPE:
- if ((hr = read_type_int64( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_int64( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_UINT8_TYPE:
- if ((hr = read_type_uint8( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_uint8( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_UINT16_TYPE:
- if ((hr = read_type_uint16( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_uint16( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_UINT32_TYPE:
- if ((hr = read_type_uint32( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_uint32( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_UINT64_TYPE:
- if ((hr = read_type_uint64( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_uint64( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_FLOAT_TYPE:
- if ((hr = read_type_float( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_float( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_DOUBLE_TYPE:
- if ((hr = read_type_double( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_double( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_DATETIME_TYPE:
- if ((hr = read_type_datetime( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_datetime( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_GUID_TYPE:
- if ((hr = read_type_guid( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_guid( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_UNIQUE_ID_TYPE:
- if ((hr = read_type_unique_id( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_unique_id( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_STRING_TYPE:
- if ((hr = read_type_string( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_string( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_WSZ_TYPE:
- if ((hr = read_type_wsz( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_wsz( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_BYTES_TYPE:
- if ((hr = read_type_bytes( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_bytes( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_XML_STRING_TYPE:
- if ((hr = read_type_xml_string( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_xml_string( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_XML_QNAME_TYPE:
- if ((hr = read_type_qname( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_qname( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_STRUCT_TYPE:
- if ((hr = read_type_struct( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_struct( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
case WS_ENUM_TYPE:
- if ((hr = read_type_enum( reader, mapping, localname, ns, desc, option, heap, value, size )) != S_OK)
- return hr;
+ hr = read_type_enum( reader, mapping, localname, ns, desc, option, heap, value, size, found );
break;
default:
@@ -6700,6 +6667,7 @@ static HRESULT read_type( struct reader *reader, WS_TYPE_MAPPING mapping, WS_TYP
return E_NOTIMPL;
}
+ if (hr != S_OK) return hr;
return end_mapping( reader, mapping );
}
@@ -6711,6 +6679,7 @@ HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TY
ULONG size, WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ BOOL found;
HRESULT hr;
TRACE( "%p %u %u %p %u %p %p %u %p\n", handle, mapping, type, desc, option, heap, value,
@@ -6727,7 +6696,7 @@ HRESULT WINAPI WsReadType( WS_XML_READER *handle, WS_TYPE_MAPPING mapping, WS_TY
return E_INVALIDARG;
}
- if ((hr = read_type( reader, mapping, type, NULL, NULL, desc, option, heap, value, size )) != S_OK)
+ if ((hr = read_type( reader, mapping, type, NULL, NULL, desc, option, heap, value, size, &found )) != S_OK)
{
LeaveCriticalSection( &reader->cs );
return hr;
@@ -6754,6 +6723,7 @@ HRESULT read_header( WS_XML_READER *handle, const WS_XML_STRING *localname, cons
ULONG size )
{
struct reader *reader = (struct reader *)handle;
+ BOOL found;
HRESULT hr;
EnterCriticalSection( &reader->cs );
@@ -6765,7 +6735,7 @@ HRESULT read_header( WS_XML_READER *handle, const WS_XML_STRING *localname, cons
}
hr = read_type( reader, WS_ELEMENT_CONTENT_TYPE_MAPPING, type, localname, ns, desc, option, heap,
- value, size );
+ value, size, &found );
LeaveCriticalSection( &reader->cs );
return hr;
@@ -6779,6 +6749,7 @@ HRESULT WINAPI WsReadElement( WS_XML_READER *handle, const WS_ELEMENT_DESCRIPTIO
WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ BOOL found;
HRESULT hr;
TRACE( "%p %p %u %p %p %u %p\n", handle, desc, option, heap, value, size, error );
@@ -6795,7 +6766,7 @@ HRESULT WINAPI WsReadElement( WS_XML_READER *handle, const WS_ELEMENT_DESCRIPTIO
}
hr = read_type( reader, WS_ELEMENT_TYPE_MAPPING, desc->type, desc->elementLocalName,
- desc->elementNs, desc->typeDescription, option, heap, value, size );
+ desc->elementNs, desc->typeDescription, option, heap, value, size, &found );
LeaveCriticalSection( &reader->cs );
return hr;
@@ -6809,6 +6780,7 @@ HRESULT WINAPI WsReadValue( WS_XML_READER *handle, WS_VALUE_TYPE value_type, voi
{
struct reader *reader = (struct reader *)handle;
WS_TYPE type = map_value_type( value_type );
+ BOOL found;
HRESULT hr;
TRACE( "%p %u %p %u %p\n", handle, type, value, size, error );
@@ -6825,7 +6797,7 @@ HRESULT WINAPI WsReadValue( WS_XML_READER *handle, WS_VALUE_TYPE value_type, voi
}
hr = read_type( reader, WS_ELEMENT_TYPE_MAPPING, type, NULL, NULL, NULL, WS_READ_REQUIRED_VALUE,
- NULL, value, size );
+ NULL, value, size, &found );
LeaveCriticalSection( &reader->cs );
return hr;
@@ -6839,6 +6811,7 @@ HRESULT WINAPI WsReadAttribute( WS_XML_READER *handle, const WS_ATTRIBUTE_DESCRI
WS_ERROR *error )
{
struct reader *reader = (struct reader *)handle;
+ BOOL found;
HRESULT hr;
TRACE( "%p %p %u %p %p %u %p\n", handle, desc, option, heap, value, size, error );
@@ -6861,7 +6834,7 @@ HRESULT WINAPI WsReadAttribute( WS_XML_READER *handle, const WS_ATTRIBUTE_DESCRI
}
hr = read_type( reader, WS_ATTRIBUTE_TYPE_MAPPING, desc->type, desc->attributeLocalName,
- desc->attributeNs, desc->typeDescription, option, heap, value, size );
+ desc->attributeNs, desc->typeDescription, option, heap, value, size, &found );
LeaveCriticalSection( &reader->cs );
return hr;
diff --git a/dlls/webservices/tests/reader.c b/dlls/webservices/tests/reader.c
index 7dd7979522..bd8a37cc52 100644
--- a/dlls/webservices/tests/reader.c
+++ b/dlls/webservices/tests/reader.c
@@ -6539,6 +6539,155 @@ static void test_repeating_element_choice(void)
WsFreeHeap( heap );
}
+static void test_empty_text_field(void)
+{
+ static WS_XML_STRING str_ns = {0, NULL}, str_t = {1, (BYTE *)"t"};
+ HRESULT hr;
+ WS_XML_READER *reader;
+ WS_HEAP *heap;
+ WS_FIELD_DESCRIPTION f, *fields[1];
+ WS_STRUCT_DESCRIPTION s;
+ struct test
+ {
+ WS_STRING str;
+ } *test;
+ struct test2
+ {
+ WCHAR *str;
+ } *test2;
+ struct test3
+ {
+ BOOL bool;
+ } *test3;
+ struct test4
+ {
+ WS_XML_STRING str;
+ } *test4;
+ struct test5
+ {
+ WS_BYTES bytes;
+ } *test5;
+
+ hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsCreateReader( NULL, 0, &reader, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ memset( &f, 0, sizeof(f) );
+ f.mapping = WS_TEXT_FIELD_MAPPING;
+ f.type = WS_STRING_TYPE;
+ f.offset = FIELD_OFFSET(struct test, str);
+ fields[0] = &f;
+
+ memset( &s, 0, sizeof(s) );
+ s.size = sizeof(struct test);
+ s.alignment = TYPE_ALIGNMENT(struct test);
+ s.fields = fields;
+ s.fieldCount = 1;
+ s.typeLocalName = &str_t;
+ s.typeNs = &str_ns;
+
+ test = NULL;
+ prepare_struct_type_test( reader, "<t></t>" );
+ hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+ WS_READ_REQUIRED_POINTER, heap, &test, sizeof(test), NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( test != NULL, "test not set\n" );
+ ok( !test->str.length, "got %u\n", test->str.length );
+ todo_wine ok( test->str.chars != NULL, "chars not set\n" );
+
+ memset( &f, 0, sizeof(f) );
+ f.mapping = WS_TEXT_FIELD_MAPPING;
+ f.type = WS_WSZ_TYPE;
+ f.offset = FIELD_OFFSET(struct test2, str);
+ fields[0] = &f;
+
+ memset( &s, 0, sizeof(s) );
+ s.size = sizeof(struct test2);
+ s.alignment = TYPE_ALIGNMENT(struct test2);
+ s.fields = fields;
+ s.fieldCount = 1;
+ s.typeLocalName = &str_t;
+ s.typeNs = &str_ns;
+
+ test2 = NULL;
+ prepare_struct_type_test( reader, "<t></t>" );
+ hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+ WS_READ_REQUIRED_POINTER, heap, &test2, sizeof(test2), NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( test2 != NULL, "test2 not set\n" );
+ ok( test2->str != NULL, "str not set\n" );
+ ok( !test2->str[0], "not empty\n" );
+
+ memset( &f, 0, sizeof(f) );
+ f.mapping = WS_TEXT_FIELD_MAPPING;
+ f.type = WS_BOOL_TYPE;
+ f.offset = FIELD_OFFSET(struct test3, bool);
+ fields[0] = &f;
+
+ memset( &s, 0, sizeof(s) );
+ s.size = sizeof(struct test3);
+ s.alignment = TYPE_ALIGNMENT(struct test3);
+ s.fields = fields;
+ s.fieldCount = 1;
+ s.typeLocalName = &str_t;
+ s.typeNs = &str_ns;
+
+ prepare_struct_type_test( reader, "<t></t>" );
+ hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+ WS_READ_REQUIRED_POINTER, heap, &test3, sizeof(test3), NULL );
+ ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
+
+ memset( &f, 0, sizeof(f) );
+ f.mapping = WS_TEXT_FIELD_MAPPING;
+ f.type = WS_XML_STRING_TYPE;
+ f.offset = FIELD_OFFSET(struct test4, str);
+ fields[0] = &f;
+
+ memset( &s, 0, sizeof(s) );
+ s.size = sizeof(struct test4);
+ s.alignment = TYPE_ALIGNMENT(struct test4);
+ s.fields = fields;
+ s.fieldCount = 1;
+ s.typeLocalName = &str_t;
+ s.typeNs = &str_ns;
+
+ test4 = NULL;
+ prepare_struct_type_test( reader, "<t></t>" );
+ hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+ WS_READ_REQUIRED_POINTER, heap, &test4, sizeof(test4), NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( test4 != NULL, "test4 not set\n" );
+ ok( !test4->str.length, "got %u\n", test4->str.length );
+ todo_wine ok( test4->str.bytes != NULL, "bytes not set\n" );
+
+ memset( &f, 0, sizeof(f) );
+ f.mapping = WS_TEXT_FIELD_MAPPING;
+ f.type = WS_BYTES_TYPE;
+ f.offset = FIELD_OFFSET(struct test5, bytes);
+ fields[0] = &f;
+
+ memset( &s, 0, sizeof(s) );
+ s.size = sizeof(struct test5);
+ s.alignment = TYPE_ALIGNMENT(struct test5);
+ s.fields = fields;
+ s.fieldCount = 1;
+ s.typeLocalName = &str_t;
+ s.typeNs = &str_ns;
+
+ test5 = NULL;
+ prepare_struct_type_test( reader, "<t></t>" );
+ hr = WsReadType( reader, WS_ELEMENT_TYPE_MAPPING, WS_STRUCT_TYPE, &s,
+ WS_READ_REQUIRED_POINTER, heap, &test5, sizeof(test5), NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( test5 != NULL, "test5 not set\n" );
+ ok( !test5->bytes.length, "got %u\n", test5->bytes.length );
+ todo_wine ok( test5->bytes.bytes != NULL, "bytes not set\n" );
+
+ WsFreeReader( reader );
+ WsFreeHeap( heap );
+}
START_TEST(reader)
{
@@ -6588,4 +6737,5 @@ START_TEST(reader)
test_union_type();
test_float();
test_repeating_element_choice();
+ test_empty_text_field();
}
--
2.11.0
June 6, 2018