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
Re: [PATCH vkd3d 11/12] tests: Add simple test for layered rendering.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
Re: [PATCH vkd3d 12/12] libs/vkd3d-shader: Fix returning multiple components from dot product instructions.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
Re: [PATCH vkd3d 09/12] libs/vkd3d-shader: Do not emit output setup for ret in geometry shaders.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
Re: [PATCH vkd3d 08/12] libs/vkd3d-shader: Generate correct SPIR-V code for arrayed shader inputs.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
Re: [PATCH vkd3d 07/12] libs/vkd3d-shader: Pass register index to vkd3d_find_signature_element_for_reg().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
Re: [PATCH vkd3d 06/12] libs/vkd3d-shader: Simplify vkd3d_dxbc_compiler_emit_input().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
Re: [PATCH vkd3d 05/12] libs/vkd3d-shader: Enable "geometry" capability for SpvBuiltInLayer.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
Re: [PATCH vkd3d 04/12] libs/vkd3d-shader: Do not force input register type to float4.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
Re: [PATCH vkd3d 03/12] libs/vkd3d-shader: Add initial support for typed registers.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
Re: [PATCH vkd3d 02/12] libs/vkd3d-shader: Do not generate code in vkd3d_dxbc_compiler_get_register_info().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
Re: [PATCH vkd3d 01/12] libs/vkd3d-shader: Split SPIR-V built-ins table into two tables.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 26, 2018
[PATCH] ntoskrnl.exe: add stub for IoUnregisterPlugPlayNotification
by Louis Lenders
Fr https://bugs.winehq.org/show_bug.cgi?id=45378
Signed-off-by: Louis Lenders <xerox.xerox2000x(a)gmail.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 9 +++++++++
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +-
2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index e4c1c3530b..c8f9173738 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2763,6 +2763,15 @@ NTSTATUS WINAPI IoRegisterPlugPlayNotification(IO_NOTIFICATION_EVENT_CATEGORY ca
return STATUS_SUCCESS;
}
+/*****************************************************
+ * IoUnregisterPlugPlayNotification (NTOSKRNL.EXE.@)
+ */
+NTSTATUS WINAPI IoUnregisterPlugPlayNotification(PVOID notification)
+{
+ FIXME("stub: %p\n", notification);
+ return STATUS_SUCCESS;
+}
+
/*****************************************************
* IoCsqInitialize (NTOSKRNL.EXE.@)
*/
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index 4129542cdc..64597c41df 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -472,7 +472,7 @@
@ stub IoThreadToProcess
@ stdcall IoUnregisterFileSystem(ptr)
@ stub IoUnregisterFsRegistrationChange
-@ stub IoUnregisterPlugPlayNotification
+@ stdcall IoUnregisterPlugPlayNotification(ptr)
@ stdcall IoUnregisterShutdownNotification(ptr)
@ stub IoUpdateShareAccess
@ stub IoValidateDeviceIoControlAccess
--
2.17.1
June 26, 2018
[PATCH] icinfo: vsnprintfW takes characters as buffer size not bytes
by Marcus Meissner
Signed-off-by: Marcus Meissner <meissner(a)suse.de>
---
programs/icinfo/icinfo.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/programs/icinfo/icinfo.c b/programs/icinfo/icinfo.c
index bfbef6b69b..601ec8c8b3 100644
--- a/programs/icinfo/icinfo.c
+++ b/programs/icinfo/icinfo.c
@@ -26,14 +26,14 @@
static int mywprintf(const WCHAR *format, ...)
{
static char output_bufA[65536];
- static WCHAR output_bufW[sizeof(output_bufA) / sizeof(WCHAR)];
+ static WCHAR output_bufW[sizeof(output_bufA)];
va_list parms;
DWORD nOut;
BOOL res = FALSE;
HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
va_start(parms, format);
- vsnprintfW(output_bufW, sizeof(output_bufW), format, parms);
+ vsnprintfW(output_bufW, sizeof(output_bufW)/sizeof(output_bufW[0]), format, parms);
va_end(parms);
/* Try to write as unicode whenever we think it's a console */
--
2.17.1
June 26, 2018
[PATCH] shlwapi: SHGetIniStringW buffer size is in characters
by Marcus Meissner
Signed-off-by: Marcus Meissner <meissner(a)suse.de>
---
dlls/shlwapi/tests/ordinal.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/shlwapi/tests/ordinal.c b/dlls/shlwapi/tests/ordinal.c
index f192849cd4..db59e625f8 100644
--- a/dlls/shlwapi/tests/ordinal.c
+++ b/dlls/shlwapi/tests/ordinal.c
@@ -2724,8 +2724,8 @@ static void test_SHGetIniString(void)
if(0){
/* these crash on Windows */
pSHGetIniStringW(NULL, NULL, NULL, 0, NULL);
- pSHGetIniStringW(NULL, AKeyW, out, sizeof(out), pathW);
- pSHGetIniStringW(TestAppW, AKeyW, NULL, sizeof(out), pathW);
+ pSHGetIniStringW(NULL, AKeyW, out, ARRAY_SIZE(out), pathW);
+ pSHGetIniStringW(TestAppW, AKeyW, NULL, ARRAY_SIZE(out), pathW);
}
ret = pSHGetIniStringW(TestAppW, AKeyW, out, 0, pathW);
@@ -2734,21 +2734,21 @@ static void test_SHGetIniString(void)
/* valid arguments */
out[0] = 0;
SetLastError(0xdeadbeef);
- ret = pSHGetIniStringW(TestAppW, NULL, out, sizeof(out), pathW);
+ ret = pSHGetIniStringW(TestAppW, NULL, out, ARRAY_SIZE(out), pathW);
ok(ret == 4, "SHGetIniStringW should have given 4, instead: %d\n", ret);
ok(!lstrcmpW(out, AKeyW), "Expected %s, got: %s, %d\n",
wine_dbgstr_w(AKeyW), wine_dbgstr_w(out), GetLastError());
- ret = pSHGetIniStringW(TestAppW, AKeyW, out, sizeof(out), pathW);
+ ret = pSHGetIniStringW(TestAppW, AKeyW, out, ARRAY_SIZE(out), pathW);
ok(ret == 1, "SHGetIniStringW should have given 1, instead: %d\n", ret);
ok(!strcmp_wa(out, "1"), "Expected L\"1\", got: %s\n", wine_dbgstr_w(out));
- ret = pSHGetIniStringW(TestAppW, AnotherKeyW, out, sizeof(out), pathW);
+ ret = pSHGetIniStringW(TestAppW, AnotherKeyW, out, ARRAY_SIZE(out), pathW);
ok(ret == 4, "SHGetIniStringW should have given 4, instead: %d\n", ret);
ok(!strcmp_wa(out, "asdf"), "Expected L\"asdf\", got: %s\n", wine_dbgstr_w(out));
out[0] = 1;
- ret = pSHGetIniStringW(TestAppW, JunkKeyW, out, sizeof(out), pathW);
+ ret = pSHGetIniStringW(TestAppW, JunkKeyW, out, ARRAY_SIZE(out), pathW);
ok(ret == 0, "SHGetIniStringW should have given 0, instead: %d\n", ret);
ok(*out == 0, "Expected L\"\", got: %s\n", wine_dbgstr_w(out));
--
2.17.1
June 26, 2018
[PATCH] psapi: GetProcessImageFileName gets character count as argument
by Marcus Meissner
Signed-off-by: Marcus Meissner <meissner(a)suse.de>
---
dlls/psapi/tests/psapi_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
index ec74716651..13205b3b8f 100644
--- a/dlls/psapi/tests/psapi_main.c
+++ b/dlls/psapi/tests/psapi_main.c
@@ -645,7 +645,7 @@ static void test_GetProcessImageFileName(void)
}
SetLastError(0xdeadbeef);
- pGetProcessImageFileNameW(NULL, szImgPathW, sizeof(szImgPathW));
+ pGetProcessImageFileNameW(NULL, szImgPathW, ARRAY_SIZE(szImgPathW));
ok(GetLastError() == ERROR_INVALID_HANDLE, "expected error=ERROR_INVALID_HANDLE but got %d\n", GetLastError());
/* no information about correct buffer size returned: */
--
2.17.1
June 26, 2018
Re: [PATCH 3/5] devenum: Make some variables static.
by Zebediah Figura
On 26/06/18 06:34, Alexandre Julliard wrote:
> Zebediah Figura <z.figura12(a)gmail.com> writes:
>
>> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
>> ---
>> dlls/devenum/createdevenum.c | 14 ++++++--------
>> dlls/devenum/devenum_main.c | 13 ++++---------
>> dlls/devenum/devenum_private.h | 4 +---
>> dlls/devenum/mediacatenum.c | 4 +++-
>> 4 files changed, 14 insertions(+), 21 deletions(-)
>
> It doesn't work here:
>
> ../../../tools/runtest -q -P wine -T ../../.. -M devenum.dll -p devenum_test.exe.so devenum && touch devenum.ok
> devenum.c:585: Test failed: filter should be registered
> devenum.c:592: Test failed: Read failed: 0x80070002
> devenum.c:595: Test failed: expected L"{DEADBEEF-CF51-43E6-B6C5-299EA8B6B591}", got L"\58e1\e0f1\cb04\11d0\4ebd\a000\11c9\86ce\2a92\37e9\d9aa\11d2\84bf\f28e\55b1\ed5a\29d1\e306\27e5\11ce\5d87\6000\b78c\6680\29d2\e306\27e5\11ce\5d87\6000\b78c\6680\9faf\0558\c356\11ce\01bf\aa00\5500\5a59\ca52\2ca8\3c3f\11d2\3db7\c000\b64f\3dbd\a762\33d9\90c8\11d0\43bd\a000\11c9\86ce\8d32\a5ea\253d\11d1\f1b3"...
> devenum.c:600: Test failed: Read failed: 0x80070002
> devenum.c:601: Test failed: expected L"{DEADBEEF-CF51-43E6-B6C5-299EA8B6B591}", got L"\58e1\e0f1\cb04\11d0\4ebd\a000\11c9\86ce\2a92\37e9\d9aa\11d2\84bf\f28e\55b1\ed5a\29d1\e306\27e5\11ce\5d87\6000\b78c\6680\29d2\e306\27e5\11ce\5d87\6000\b78c\6680\9faf\0558\c356\11ce\01bf\aa00\5500\5a59\ca52\2ca8\3c3f\11d2\3db7\c000\b64f\3dbd\a762\33d9\90c8\11d0\43bd\a000\11c9\86ce\8d32\a5ea\253d\11d1\f1b3"...
> Makefile:183: recipe for target 'devenum.ok' failed
> make: *** [devenum.ok] Error 5
>
Apologies; I missed a spot. Resent.
June 26, 2018
[PATCH v2 5/5] include: Make fil_data.idl a common header.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/Makefile.in | 3 +-
dlls/devenum/createdevenum.c | 2 +-
dlls/devenum/fil_data.idl | 47 --------------------------
dlls/dxdiagn/Makefile.in | 3 +-
dlls/dxdiagn/provider.c | 2 +-
dlls/quartz/Makefile.in | 1 -
dlls/quartz/fil_data.idl | 52 -----------------------------
dlls/quartz/filtermapper.c | 2 +-
dlls/quartz/tests/Makefile.in | 1 -
dlls/quartz/tests/fil_data.idl | 52 -----------------------------
dlls/quartz/tests/filtermapper.c | 2 +-
include/Makefile.in | 1 +
{dlls/dxdiagn => include/wine}/fil_data.idl | 21 ++----------
13 files changed, 10 insertions(+), 179 deletions(-)
delete mode 100644 dlls/devenum/fil_data.idl
delete mode 100644 dlls/quartz/fil_data.idl
delete mode 100644 dlls/quartz/tests/fil_data.idl
rename {dlls/dxdiagn => include/wine}/fil_data.idl (67%)
diff --git a/dlls/devenum/Makefile.in b/dlls/devenum/Makefile.in
index d1407a9..2760eed 100644
--- a/dlls/devenum/Makefile.in
+++ b/dlls/devenum/Makefile.in
@@ -9,7 +9,6 @@ C_SRCS = \
parsedisplayname.c
IDL_SRCS = \
- devenum_classes.idl \
- fil_data.idl
+ devenum_classes.idl
RC_SRCS = devenum.rc
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index e3ae54f..4b2feca 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -37,7 +37,7 @@
#include "mmddk.h"
#include "initguid.h"
-#include "fil_data.h"
+#include "wine/fil_data.h"
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
diff --git a/dlls/devenum/fil_data.idl b/dlls/devenum/fil_data.idl
deleted file mode 100644
index 7e37a75..0000000
--- a/dlls/devenum/fil_data.idl
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 Vitaliy Margolen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#pragma makedep header
-
-import "objidl.idl";
-import "strmif.idl";
-import "unknwn.idl";
-
-
-/*****************************************************************************
- * IAMFilterData interface
- */
-[
- object,
- uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
- pointer_default(unique)
-]
-interface IAMFilterData : IUnknown
-{
- typedef [unique] IAMFilterData *LPIAMFILTERDATA;
-
- HRESULT ParseFilterData(
- [in] BYTE * rgbFilterData,
- [in] ULONG cb,
- [out] BYTE ** prgbRegFilter2);
-
- HRESULT CreateFilterData(
- [in] REGFILTER2 * prf2,
- [out] BYTE ** prgbFilterData,
- [out] ULONG * pcb);
-}
diff --git a/dlls/dxdiagn/Makefile.in b/dlls/dxdiagn/Makefile.in
index 3a1017e..c16396e 100644
--- a/dlls/dxdiagn/Makefile.in
+++ b/dlls/dxdiagn/Makefile.in
@@ -9,5 +9,4 @@ C_SRCS = \
RC_SRCS = dxdiagn.rc
IDL_SRCS = \
- dxdiagn.idl \
- fil_data.idl
+ dxdiagn.idl
diff --git a/dlls/dxdiagn/provider.c b/dlls/dxdiagn/provider.c
index 4f964ad..1fdab5e 100644
--- a/dlls/dxdiagn/provider.c
+++ b/dlls/dxdiagn/provider.c
@@ -35,7 +35,7 @@
#include "d3d9.h"
#include "strmif.h"
#include "initguid.h"
-#include "fil_data.h"
+#include "wine/fil_data.h"
#include "psapi.h"
#include "wbemcli.h"
diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in
index e938865..5eb8d44 100644
--- a/dlls/quartz/Makefile.in
+++ b/dlls/quartz/Makefile.in
@@ -30,7 +30,6 @@ RC_SRCS = version.rc
IDL_SRCS = \
control_tlb.idl \
- fil_data.idl \
quartz_strmif.idl
dlldata_EXTRADEFS = -DENTRY_PREFIX=QUARTZ_ -DPROXY_DELEGATION -DWINE_REGISTER_DLL
diff --git a/dlls/quartz/fil_data.idl b/dlls/quartz/fil_data.idl
deleted file mode 100644
index ab93499..0000000
--- a/dlls/quartz/fil_data.idl
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 Vitaliy Margolen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#pragma makedep header
-
-import "objidl.idl";
-import "strmif.idl";
-import "unknwn.idl";
-
-
-/*****************************************************************************
- * IAMFilterData interface
- *
- * Notes:
- * - This interface is deprecated and IFilterMapper2 should be used instead.
- * - There is no full replacement for IAMFilterData::ParseFilterData short of manually
- * parsing out the REGFILTER2 struct from the binary blob.
- */
-[
- object,
- uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
- pointer_default(unique)
-]
-interface IAMFilterData : IUnknown
-{
- typedef [unique] IAMFilterData *LPIAMFILTERDATA;
-
- HRESULT ParseFilterData(
- [in] BYTE * rgbFilterData,
- [in] ULONG cb,
- [out] BYTE ** prgbRegFilter2);
-
- HRESULT CreateFilterData(
- [in] REGFILTER2 * prf2,
- [out] BYTE ** prgbFilterData,
- [out] ULONG * pcb);
-}
diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c
index 20c7e3a..d78f643 100644
--- a/dlls/quartz/filtermapper.c
+++ b/dlls/quartz/filtermapper.c
@@ -37,7 +37,7 @@
#include "wine/unicode.h"
#include "uuids.h"
#include "initguid.h"
-#include "fil_data.h"
+#include "wine/fil_data.h"
#include "wine/debug.h"
diff --git a/dlls/quartz/tests/Makefile.in b/dlls/quartz/tests/Makefile.in
index 4f54666..6b880c3 100644
--- a/dlls/quartz/tests/Makefile.in
+++ b/dlls/quartz/tests/Makefile.in
@@ -12,7 +12,6 @@ C_SRCS = \
referenceclock.c \
videorenderer.c
-IDL_SRCS = fil_data.idl
RC_SRCS = \
rsrc.rc
diff --git a/dlls/quartz/tests/fil_data.idl b/dlls/quartz/tests/fil_data.idl
deleted file mode 100644
index ab93499..0000000
--- a/dlls/quartz/tests/fil_data.idl
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 Vitaliy Margolen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#pragma makedep header
-
-import "objidl.idl";
-import "strmif.idl";
-import "unknwn.idl";
-
-
-/*****************************************************************************
- * IAMFilterData interface
- *
- * Notes:
- * - This interface is deprecated and IFilterMapper2 should be used instead.
- * - There is no full replacement for IAMFilterData::ParseFilterData short of manually
- * parsing out the REGFILTER2 struct from the binary blob.
- */
-[
- object,
- uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
- pointer_default(unique)
-]
-interface IAMFilterData : IUnknown
-{
- typedef [unique] IAMFilterData *LPIAMFILTERDATA;
-
- HRESULT ParseFilterData(
- [in] BYTE * rgbFilterData,
- [in] ULONG cb,
- [out] BYTE ** prgbRegFilter2);
-
- HRESULT CreateFilterData(
- [in] REGFILTER2 * prf2,
- [out] BYTE ** prgbFilterData,
- [out] ULONG * pcb);
-}
diff --git a/dlls/quartz/tests/filtermapper.c b/dlls/quartz/tests/filtermapper.c
index 5a43785..7b6a018 100644
--- a/dlls/quartz/tests/filtermapper.c
+++ b/dlls/quartz/tests/filtermapper.c
@@ -26,7 +26,7 @@
#include "dshow.h"
#include "winternl.h"
-#include "fil_data.h"
+#include "wine/fil_data.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
diff --git a/include/Makefile.in b/include/Makefile.in
index 39f2691..995544a 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -664,6 +664,7 @@ SOURCES = \
windowsx.h \
wine/debug.h \
wine/exception.h \
+ wine/fil_data.idl \
wine/itss.idl \
wine/library.h \
wine/svcctl.idl \
diff --git a/dlls/dxdiagn/fil_data.idl b/include/wine/fil_data.idl
similarity index 67%
rename from dlls/dxdiagn/fil_data.idl
rename to include/wine/fil_data.idl
index 7e37a75..19dfa8a 100644
--- a/dlls/dxdiagn/fil_data.idl
+++ b/include/wine/fil_data.idl
@@ -16,16 +16,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#pragma makedep header
-
-import "objidl.idl";
-import "strmif.idl";
import "unknwn.idl";
+import "strmif.idl";
-
-/*****************************************************************************
- * IAMFilterData interface
- */
[
object,
uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
@@ -33,15 +26,7 @@ import "unknwn.idl";
]
interface IAMFilterData : IUnknown
{
- typedef [unique] IAMFilterData *LPIAMFILTERDATA;
+ HRESULT ParseFilterData( [in] BYTE *data, [in] ULONG size, [out] BYTE **regfilter );
- HRESULT ParseFilterData(
- [in] BYTE * rgbFilterData,
- [in] ULONG cb,
- [out] BYTE ** prgbRegFilter2);
-
- HRESULT CreateFilterData(
- [in] REGFILTER2 * prf2,
- [out] BYTE ** prgbFilterData,
- [out] ULONG * pcb);
+ HRESULT CreateFilterData( [in] REGFILTER2 *regfilter, [out] BYTE **data, [out] ULONG *size );
}
--
2.7.4
June 26, 2018
[PATCH v2 4/5] devenum: Remove an unused typedef.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/devenum_main.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/dlls/devenum/devenum_main.c b/dlls/devenum/devenum_main.c
index 98ad1ad..b17bc93 100644
--- a/dlls/devenum/devenum_main.c
+++ b/dlls/devenum/devenum_main.c
@@ -28,13 +28,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(devenum);
DECLSPEC_HIDDEN LONG dll_refs;
static HINSTANCE devenum_instance;
-typedef struct
-{
- REFCLSID clsid;
- LPCWSTR friendly_name;
- BOOL instance;
-} register_info;
-
/***********************************************************************
* DllEntryPoint
*/
--
2.7.4
June 26, 2018
[PATCH v2 3/5] devenum: Make some variables static.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/createdevenum.c | 15 +++++++--------
dlls/devenum/devenum_main.c | 13 ++++---------
dlls/devenum/devenum_private.h | 4 +---
dlls/devenum/mediacatenum.c | 4 +++-
4 files changed, 15 insertions(+), 21 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index 06c264c..e3ae54f 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -41,8 +41,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
-extern HINSTANCE DEVENUM_hInstance;
-
static const WCHAR wszFilterKeyName[] = {'F','i','l','t','e','r',0};
static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};
static const WCHAR wszPins[] = {'P','i','n','s',0};
@@ -424,6 +422,7 @@ static void register_legacy_filters(void)
TRACE("Registering %s\n", debugstr_w(wszFilterSubkeyName));
strcpyW(wszRegKey, clsidW);
+ strcatW(wszRegKey, backslashW);
strcatW(wszRegKey, wszFilterSubkeyName);
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, wszRegKey, 0, KEY_READ, &classkey) != ERROR_SUCCESS)
@@ -460,7 +459,7 @@ static void register_legacy_filters(void)
V_VT(&var) = VT_BSTR;
if (!(V_BSTR(&var) = SysAllocString(wszFilterSubkeyName)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
@@ -537,7 +536,7 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
StringFromGUID2(&CLSID_DSoundRender, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
@@ -620,7 +619,7 @@ static void register_waveout_devices(void)
StringFromGUID2(&CLSID_AudioRender, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
@@ -693,7 +692,7 @@ static void register_wavein_devices(void)
StringFromGUID2(&CLSID_AudioRecord, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
@@ -765,7 +764,7 @@ static void register_midiout_devices(void)
StringFromGUID2(&CLSID_AVIMIDIRender, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
@@ -854,7 +853,7 @@ static void register_vfw_codecs(void)
StringFromGUID2(&CLSID_AVICo, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
diff --git a/dlls/devenum/devenum_main.c b/dlls/devenum/devenum_main.c
index 3499f99..98ad1ad 100644
--- a/dlls/devenum/devenum_main.c
+++ b/dlls/devenum/devenum_main.c
@@ -26,7 +26,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
DECLSPEC_HIDDEN LONG dll_refs;
-DECLSPEC_HIDDEN HINSTANCE DEVENUM_hInstance;
+static HINSTANCE devenum_instance;
typedef struct
{
@@ -36,11 +36,6 @@ typedef struct
} register_info;
/***********************************************************************
- * Global string constant definitions
- */
-const WCHAR clsid_keyname[6] = { 'C', 'L', 'S', 'I', 'D', 0 };
-
-/***********************************************************************
* DllEntryPoint
*/
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
@@ -49,7 +44,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
- DEVENUM_hInstance = hinstDLL;
+ devenum_instance = hinstDLL;
DisableThreadLibraryCalls(hinstDLL);
break;
}
@@ -166,7 +161,7 @@ HRESULT WINAPI DllRegisterServer(void)
TRACE("\n");
- res = __wine_register_resources( DEVENUM_hInstance );
+ res = __wine_register_resources( devenum_instance );
if (FAILED(res))
return res;
@@ -214,5 +209,5 @@ HRESULT WINAPI DllRegisterServer(void)
HRESULT WINAPI DllUnregisterServer(void)
{
FIXME("stub!\n");
- return __wine_unregister_resources( DEVENUM_hInstance );
+ return __wine_unregister_resources( devenum_instance );
}
diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h
index ea4e017..e18c57d 100644
--- a/dlls/devenum/devenum_private.h
+++ b/dlls/devenum/devenum_private.h
@@ -83,7 +83,7 @@ extern IParseDisplayName DEVENUM_ParseDisplayName DECLSPEC_HIDDEN;
*/
static const WCHAR backslashW[] = {'\\',0};
-static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0};
+static const WCHAR clsidW[] = {'C','L','S','I','D',0};
static const WCHAR instanceW[] = {'\\','I','n','s','t','a','n','c','e',0};
static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
@@ -93,5 +93,3 @@ static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0};
static const WCHAR dmoW[] = {'d','m','o',':',0};
static const WCHAR swW[] = {'s','w',':',0};
static const WCHAR cmW[] = {'c','m',':',0};
-
-extern const WCHAR clsid_keyname[6] DECLSPEC_HIDDEN;
diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c
index c4338a2..660e81c 100644
--- a/dlls/devenum/mediacatenum.c
+++ b/dlls/devenum/mediacatenum.c
@@ -347,6 +347,7 @@ static HRESULT create_PropertyBag(MediaCatMoniker *mon, IPropertyBag **ppBag)
else if (rpb->type == DEVICE_FILTER)
{
strcpyW(rpb->path, clsidW);
+ strcatW(rpb->path, backslashW);
if (mon->has_class)
{
StringFromGUID2(&mon->class, rpb->path + strlenW(rpb->path), CHARS_IN_GUID);
@@ -496,7 +497,7 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToObject(IMoniker *iface, IBi
if (SUCCEEDED(res))
{
V_VT(&var) = VT_LPWSTR;
- res = IPropertyBag_Read(pProp, clsid_keyname, &var, NULL);
+ res = IPropertyBag_Read(pProp, clsidW, &var, NULL);
}
if (SUCCEEDED(res))
{
@@ -1027,6 +1028,7 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
pEnumMoniker->class = *class;
strcpyW(buffer, clsidW);
+ strcatW(buffer, backslashW);
StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
strcatW(buffer, instanceW);
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->sw_key))
--
2.7.4
June 26, 2018
[PATCH v2 2/5] devenum: Use separate factories for CLSID_SystemDeviceEnum and CLSID_CDeviceMoniker.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/devenum_main.c | 46 +++++++++++++++++++++++----------------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/dlls/devenum/devenum_main.c b/dlls/devenum/devenum_main.c
index 7bfc593..3499f99 100644
--- a/dlls/devenum/devenum_main.c
+++ b/dlls/devenum/devenum_main.c
@@ -56,6 +56,17 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
return TRUE;
}
+struct class_factory
+{
+ IClassFactory IClassFactory_iface;
+ IUnknown *obj;
+};
+
+static inline struct class_factory *impl_from_IClassFactory( IClassFactory *iface )
+{
+ return CONTAINING_RECORD( iface, struct class_factory, IClassFactory_iface );
+}
+
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void **obj)
{
TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), obj);
@@ -87,24 +98,15 @@ static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface,
IUnknown *outer, REFIID iid, void **obj)
{
+ struct class_factory *This = impl_from_IClassFactory( iface );
+
TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj);
if (!obj) return E_POINTER;
if (outer) return CLASS_E_NOAGGREGATION;
- if (IsEqualGUID(&IID_ICreateDevEnum, iid))
- {
- *obj = &DEVENUM_CreateDevEnum;
- return S_OK;
- }
- if (IsEqualGUID(&IID_IParseDisplayName, iid))
- {
- *obj = &DEVENUM_ParseDisplayName;
- return S_OK;
- }
-
- return CLASS_E_CLASSNOTAVAILABLE;
+ return IUnknown_QueryInterface(This->obj, iid, obj);
}
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock)
@@ -124,24 +126,24 @@ static const IClassFactoryVtbl ClassFactory_vtbl = {
ClassFactory_LockServer
};
-static IClassFactory devenum_cf = { &ClassFactory_vtbl };
+static struct class_factory create_devenum_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_CreateDevEnum };
+static struct class_factory device_moniker_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_ParseDisplayName };
/***********************************************************************
* DllGetClassObject (DEVENUM.@)
*/
-HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
+HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **obj)
{
- TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
+ TRACE("(%s, %s, %p)\n", debugstr_guid(clsid), debugstr_guid(iid), obj);
- *ppv = NULL;
+ *obj = NULL;
- /* FIXME: we should really have two class factories.
- * Oh well - works just fine as it is */
- if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) ||
- IsEqualGUID(rclsid, &CLSID_CDeviceMoniker))
- return IClassFactory_QueryInterface(&devenum_cf, iid, ppv);
+ if (IsEqualGUID(clsid, &CLSID_SystemDeviceEnum))
+ return IClassFactory_QueryInterface(&create_devenum_cf.IClassFactory_iface, iid, obj);
+ else if (IsEqualGUID(clsid, &CLSID_CDeviceMoniker))
+ return IClassFactory_QueryInterface(&device_moniker_cf.IClassFactory_iface, iid, obj);
- FIXME("CLSID: %s, IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid));
+ FIXME("class %s not available\n", debugstr_guid(clsid));
return CLASS_E_CLASSNOTAVAILABLE;
}
--
2.7.4
June 26, 2018
[PATCH v2 1/5] devenum: Merge factory.c into devenum_main.c.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/Makefile.in | 1 -
dlls/devenum/devenum_main.c | 74 ++++++++++++++++++++++-
dlls/devenum/devenum_private.h | 10 ---
dlls/devenum/factory.c | 134 -----------------------------------------
4 files changed, 72 insertions(+), 147 deletions(-)
delete mode 100644 dlls/devenum/factory.c
diff --git a/dlls/devenum/Makefile.in b/dlls/devenum/Makefile.in
index ae138b6..d1407a9 100644
--- a/dlls/devenum/Makefile.in
+++ b/dlls/devenum/Makefile.in
@@ -5,7 +5,6 @@ DELAYIMPORTS = msvfw32
C_SRCS = \
createdevenum.c \
devenum_main.c \
- factory.c \
mediacatenum.c \
parsedisplayname.c
diff --git a/dlls/devenum/devenum_main.c b/dlls/devenum/devenum_main.c
index cb4b454..7bfc593 100644
--- a/dlls/devenum/devenum_main.c
+++ b/dlls/devenum/devenum_main.c
@@ -1,5 +1,5 @@
/*
- * exported dll functions for devenum.dll
+ * Device Enumeration
*
* Copyright (C) 2002 John K. Hohm
* Copyright (C) 2002 Robert Shearman
@@ -56,6 +56,76 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
return TRUE;
}
+static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void **obj)
+{
+ TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), obj);
+
+ if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
+ {
+ IClassFactory_AddRef(iface);
+ *obj = iface;
+ return S_OK;
+ }
+
+ *obj = NULL;
+ WARN("no interface for %s\n", debugstr_guid(iid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
+{
+ DEVENUM_LockModule();
+ return 2;
+}
+
+static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
+{
+ DEVENUM_UnlockModule();
+ return 1;
+}
+
+static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface,
+ IUnknown *outer, REFIID iid, void **obj)
+{
+ TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj);
+
+ if (!obj) return E_POINTER;
+
+ if (outer) return CLASS_E_NOAGGREGATION;
+
+ if (IsEqualGUID(&IID_ICreateDevEnum, iid))
+ {
+ *obj = &DEVENUM_CreateDevEnum;
+ return S_OK;
+ }
+ if (IsEqualGUID(&IID_IParseDisplayName, iid))
+ {
+ *obj = &DEVENUM_ParseDisplayName;
+ return S_OK;
+ }
+
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock)
+{
+ if (lock)
+ DEVENUM_LockModule();
+ else
+ DEVENUM_UnlockModule();
+ return S_OK;
+}
+
+static const IClassFactoryVtbl ClassFactory_vtbl = {
+ ClassFactory_QueryInterface,
+ ClassFactory_AddRef,
+ ClassFactory_Release,
+ ClassFactory_CreateInstance,
+ ClassFactory_LockServer
+};
+
+static IClassFactory devenum_cf = { &ClassFactory_vtbl };
+
/***********************************************************************
* DllGetClassObject (DEVENUM.@)
*/
@@ -69,7 +139,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
* Oh well - works just fine as it is */
if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) ||
IsEqualGUID(rclsid, &CLSID_CDeviceMoniker))
- return IClassFactory_QueryInterface(&DEVENUM_ClassFactory.IClassFactory_iface, iid, ppv);
+ return IClassFactory_QueryInterface(&devenum_cf, iid, ppv);
FIXME("CLSID: %s, IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid));
return CLASS_E_CLASSNOTAVAILABLE;
diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h
index df0080d..ea4e017 100644
--- a/dlls/devenum/devenum_private.h
+++ b/dlls/devenum/devenum_private.h
@@ -51,15 +51,6 @@ extern LONG dll_refs DECLSPEC_HIDDEN;
static inline void DEVENUM_LockModule(void) { InterlockedIncrement(&dll_refs); }
static inline void DEVENUM_UnlockModule(void) { InterlockedDecrement(&dll_refs); }
-
-/**********************************************************************
- * ClassFactory declaration for devenum.dll
- */
-typedef struct
-{
- IClassFactory IClassFactory_iface;
-} ClassFactoryImpl;
-
enum device_type
{
DEVICE_FILTER,
@@ -84,7 +75,6 @@ typedef struct
MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN;
HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **enum_mon) DECLSPEC_HIDDEN;
-extern ClassFactoryImpl DEVENUM_ClassFactory DECLSPEC_HIDDEN;
extern ICreateDevEnum DEVENUM_CreateDevEnum DECLSPEC_HIDDEN;
extern IParseDisplayName DEVENUM_ParseDisplayName DECLSPEC_HIDDEN;
diff --git a/dlls/devenum/factory.c b/dlls/devenum/factory.c
deleted file mode 100644
index c808fa5..0000000
--- a/dlls/devenum/factory.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * ClassFactory implementation for DEVENUM.dll
- *
- * Copyright (C) 2002 John K. Hohm
- * Copyright (C) 2002 Robert Shearman
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "devenum_private.h"
-
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(devenum);
-
-/**********************************************************************
- * DEVENUM_IClassFactory_QueryInterface (also IUnknown)
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_QueryInterface(IClassFactory *iface, REFIID riid,
- void **ppvObj)
-{
- TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObj);
-
- if (ppvObj == NULL) return E_POINTER;
-
- if (IsEqualGUID(riid, &IID_IUnknown) ||
- IsEqualGUID(riid, &IID_IClassFactory))
- {
- *ppvObj = iface;
- IClassFactory_AddRef(iface);
- return S_OK;
- }
- else if (IsEqualGUID(riid, &IID_IParseDisplayName))
- {
- return IClassFactory_CreateInstance(iface, NULL, riid, ppvObj);
- }
-
- FIXME("- no interface IID: %s\n", debugstr_guid(riid));
- return E_NOINTERFACE;
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_AddRef (also IUnknown)
- */
-static ULONG WINAPI DEVENUM_IClassFactory_AddRef(IClassFactory *iface)
-{
- TRACE("\n");
-
- DEVENUM_LockModule();
-
- return 2; /* non-heap based object */
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_Release (also IUnknown)
- */
-static ULONG WINAPI DEVENUM_IClassFactory_Release(IClassFactory *iface)
-{
- TRACE("\n");
-
- DEVENUM_UnlockModule();
-
- return 1; /* non-heap based object */
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_CreateInstance
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_CreateInstance(IClassFactory *iface,
- IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
-{
- TRACE("(%p)->(%p, %s, %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppvObj);
-
- if (ppvObj == NULL) return E_POINTER;
-
- /* Don't support aggregation (Windows doesn't) */
- if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION;
-
- if (IsEqualGUID(&IID_ICreateDevEnum, riid))
- {
- *ppvObj = &DEVENUM_CreateDevEnum;
- return S_OK;
- }
- if (IsEqualGUID(&IID_IParseDisplayName, riid))
- {
- *ppvObj = &DEVENUM_ParseDisplayName;
- return S_OK;
- }
-
- return CLASS_E_CLASSNOTAVAILABLE;
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_LockServer
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
-{
- TRACE("\n");
-
- if (fLock)
- DEVENUM_LockModule();
- else
- DEVENUM_UnlockModule();
- return S_OK;
-}
-
-/**********************************************************************
- * IClassFactory_Vtbl
- */
-static const IClassFactoryVtbl IClassFactory_Vtbl =
-{
- DEVENUM_IClassFactory_QueryInterface,
- DEVENUM_IClassFactory_AddRef,
- DEVENUM_IClassFactory_Release,
- DEVENUM_IClassFactory_CreateInstance,
- DEVENUM_IClassFactory_LockServer
-};
-
-/**********************************************************************
- * static ClassFactory instance
- */
-ClassFactoryImpl DEVENUM_ClassFactory = { { &IClassFactory_Vtbl } };
--
2.7.4
June 26, 2018
[PATCH] kernel32: GetVolumePathNamesForVolumeNameW gets character as buffer size
by Marcus Meissner
Signed-off-by: Marcus Meissner <meissner(a)suse.de>
---
dlls/kernel32/tests/volume.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c
index c47043d288..f673fd2917 100644
--- a/dlls/kernel32/tests/volume.c
+++ b/dlls/kernel32/tests/volume.c
@@ -983,7 +983,7 @@ static void test_GetVolumePathNamesForVolumeNameW(void)
return;
}
- ret = pGetVolumeNameForVolumeMountPointW( drive_c, volume, sizeof(volume)/sizeof(volume[0]) );
+ ret = pGetVolumeNameForVolumeMountPointW( drive_c, volume, ARRAY_SIZE(volume) );
ok(ret, "failed to get volume name %u\n", GetLastError());
SetLastError( 0xdeadbeef );
@@ -1005,16 +1005,16 @@ static void test_GetVolumePathNamesForVolumeNameW(void)
ok(error == ERROR_MORE_DATA, "expected ERROR_MORE_DATA got %u\n", error);
if (0) { /* crash */
- ret = pGetVolumePathNamesForVolumeNameW( volume, NULL, sizeof(buffer), NULL );
+ ret = pGetVolumePathNamesForVolumeNameW( volume, NULL, ARRAY_SIZE(buffer), NULL );
ok(ret, "failed to get path names %u\n", GetLastError());
}
- ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, sizeof(buffer), NULL );
+ ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, ARRAY_SIZE(buffer), NULL );
ok(ret, "failed to get path names %u\n", GetLastError());
len = 0;
memset( buffer, 0xff, sizeof(buffer) );
- ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, sizeof(buffer), &len );
+ ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, ARRAY_SIZE(buffer), &len );
ok(ret, "failed to get path names %u\n", GetLastError());
ok(len == 5, "expected 5 got %u\n", len);
ok(!buffer[4], "expected double null-terminated buffer\n");
@@ -1023,7 +1023,7 @@ static void test_GetVolumePathNamesForVolumeNameW(void)
volume[1] = '?';
volume[lstrlenW( volume ) - 1] = 0;
SetLastError( 0xdeadbeef );
- ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, sizeof(buffer), &len );
+ ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, ARRAY_SIZE(buffer), &len );
error = GetLastError();
ok(!ret, "expected failure\n");
ok(error == ERROR_INVALID_NAME, "expected ERROR_INVALID_NAME got %u\n", error);
@@ -1032,7 +1032,7 @@ static void test_GetVolumePathNamesForVolumeNameW(void)
volume[0] = '\\';
volume[1] = 0;
SetLastError( 0xdeadbeef );
- ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, sizeof(buffer), &len );
+ ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, ARRAY_SIZE(buffer), &len );
error = GetLastError();
ok(!ret, "expected failure\n");
todo_wine ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER got %u\n", error);
@@ -1040,7 +1040,7 @@ static void test_GetVolumePathNamesForVolumeNameW(void)
len = 0;
lstrcpyW( volume, volume_null );
SetLastError( 0xdeadbeef );
- ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, sizeof(buffer), &len );
+ ret = pGetVolumePathNamesForVolumeNameW( volume, buffer, ARRAY_SIZE(buffer), &len );
error = GetLastError();
ok(!ret, "expected failure\n");
ok(error == ERROR_FILE_NOT_FOUND, "expected ERROR_FILE_NOT_FOUND got %u\n", error);
--
2.17.1
June 26, 2018
[PATCH] kernel32: GetCalendarInfoW gets character sizes
by Marcus Meissner
found by grep
Signed-off-by: Marcus Meissner <meissner(a)suse.de>
---
dlls/kernel32/tests/time.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/time.c b/dlls/kernel32/tests/time.c
index e6e779c703..8bbad2b8a2 100644
--- a/dlls/kernel32/tests/time.c
+++ b/dlls/kernel32/tests/time.c
@@ -697,7 +697,7 @@ static void test_GetCalendarInfo(void)
ok( ret == 5, "wrong size %u\n", ret );
ok( atoi( bufferA ) == val1, "wrong value %s/%u\n", bufferA, val1 );
- ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferW, sizeof(bufferW), NULL );
+ ret = pGetCalendarInfoW( 0x0409, CAL_GREGORIAN, CAL_ITWODIGITYEARMAX, bufferW, ARRAY_SIZE(bufferW), NULL );
ok( ret, "GetCalendarInfoW failed err %u\n", GetLastError() );
ok( ret == 5, "wrong size %u\n", ret );
memset( bufferA, 0x55, sizeof(bufferA) );
@@ -731,7 +731,7 @@ static void test_GetCalendarInfo(void)
ok( ret == ret2, "got %d, expected %d\n", ret2, ret );
ret2 = pGetCalendarInfoW( LANG_SYSTEM_DEFAULT, CAL_GREGORIAN, CAL_SDAYNAME1,
- bufferW, sizeof(bufferW), NULL);
+ bufferW, ARRAY_SIZE(bufferW), NULL);
ok( ret2, "GetCalendarInfoW failed err %u\n", GetLastError() );
ret2 = WideCharToMultiByte( CP_ACP, 0, bufferW, -1, NULL, 0, NULL, NULL );
ok( ret == ret2, "got %d, expected %d\n", ret, ret2 );
--
2.17.1
June 26, 2018
[PATCH 5/5] winmm: Support TIME_MIDI position in MIDI stream.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/winmm/tests/midi.c | 4 ++--
dlls/winmm/winmm.c | 19 ++++++++++++++++---
2 files changed, 18 insertions(+), 5 deletions(-)
June 26, 2018
[PATCH 4/5] winmm: Make TIME_TICKS position continuous.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/winmm/tests/midi.c | 2 +-
dlls/winmm/winmm.c | 28 ++++++++++++++++++++++++++--
2 files changed, 27 insertions(+), 3 deletions(-)
June 26, 2018
[PATCH 3/5] winmm/tests: Add more MIDI stream position tests.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/winmm/tests/midi.c | 33 +++++++++++++++++++++++++++++++++
1 file changed, 33 insertions(+)
June 26, 2018
[PATCH 2/5] winmm: Preserve fractions in microseconds to compensate rounding errors.
by Akihiro Sagawa
Otherwise, a song is played faster than expected in some cases.
For instance, we assume that 40 pan control change (CC#10) messages are
expressed in 12.5ms each,
* Prior art omits fractions, i.e. 12ms + 12ms + ... = 480ms.
* Proposal technique saves fractions, i.e. 12ms + 13ms + ... = 500ms.
Ideal duration is 500ms. So, the proposed method is better than prior one.
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/winmm/winmm.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
June 26, 2018
[PATCH 1/5] winmm: Don't allow to set time division property while playing.
by Akihiro Sagawa
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/winmm/tests/midi.c | 6 ++++++
dlls/winmm/winmm.c | 8 ++++++--
2 files changed, 12 insertions(+), 2 deletions(-)
June 26, 2018
[PATCH] testbot/WineRunTask: Better detect standard Wine tests.
by Francois Gouget
It's better to take the step dependencies into account and to verify
that the previous step was dealing with a Wine patch.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index ff8aab9f4..9fa263eea 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -441,9 +441,10 @@ if ($Step->Type eq "single")
}
$Script .= "> $RptFileName\r\n";
- # If StepNo is 1 then the user gave us an executable. Then there is no
- # telling if it's going to follow the Wine test standards.
- $IsWineTest = ($StepNo != 1);
+ # If the user gave us an executable there is no telling
+ # if it is going going to follow the Wine test standards.
+ $IsWineTest = (defined $Step->PreviousNo and
+ $Job->Steps->GetItem($Step->PreviousNo)->FileType eq "patchdlls");
}
elsif ($Step->Type eq "suite")
{
--
2.18.0
June 26, 2018
[PATCH] testbot/WineRun*: Standardize a couple of TestBot error messages.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunBuild.pl | 2 +-
testbot/bin/WineRunTask.pl | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/testbot/bin/WineRunBuild.pl b/testbot/bin/WineRunBuild.pl
index ff04ded0c..176ade6b6 100755
--- a/testbot/bin/WineRunBuild.pl
+++ b/testbot/bin/WineRunBuild.pl
@@ -458,7 +458,7 @@ foreach my $TestInfo (values %{$Impacts->{Tests}})
}
elsif ($TA->GetLastError() !~ /: No such file or directory/)
{
- FatalTAError($TA, "Could not retrieve '$Local'");
+ FatalTAError($TA, "An error occurred while retrieving '$Local'");
}
}
}
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 9fa263eea..9faae28c3 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -482,7 +482,7 @@ elsif ($Step->Type eq "suite")
Debug(Elapsed($Start), " Sending the script: [$Script]\n");
if (!$TA->SendFileFromString($Script, "script.bat", $TestAgent::SENDFILE_EXE))
{
- FatalTAError($TA, "Could not send the script to the VM");
+ FatalTAError($TA, "Could not send the task script to the VM");
}
--
2.18.0
June 26, 2018
[PATCH] testbot: Rename the Makefiles patch impact to MakeMakefiles.
by Francois Gouget
This makes it clearer that it does not mean a makefile was modified, but
that the make_makefiles script should be rerun.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/build/Build.pl | 2 +-
testbot/bin/build/WineTest.pl | 2 +-
testbot/lib/WineTestBot/PatchUtils.pm | 6 +++---
3 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index 4df107005..a3cb170a0 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -103,7 +103,7 @@ sub ApplyPatch($)
}
my $Impacts = GetPatchImpact($PatchFile, "nounits");
- if ($Impacts->{Makefiles})
+ if ($Impacts->{MakeMakefiles})
{
InfoMsg "\nRunning make_makefiles\n";
system("cd '$DataDir/wine' && set -x && ./tools/make_makefiles");
diff --git a/testbot/bin/build/WineTest.pl b/testbot/bin/build/WineTest.pl
index 01396f9bf..032ee4640 100755
--- a/testbot/bin/build/WineTest.pl
+++ b/testbot/bin/build/WineTest.pl
@@ -100,7 +100,7 @@ sub ApplyPatch($)
}
my $Impacts = GetPatchImpact($PatchFile, "nounits");
- if ($Impacts->{Makefiles})
+ if ($Impacts->{MakeMakefiles})
{
InfoMsg "\nRunning make_makefiles\n";
system("cd '$DataDir/wine' && set -x && ./tools/make_makefiles");
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index c37a1d3ab..b2bfe6a9a 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -178,7 +178,7 @@ sub _HandleFile($$$)
if ($Change eq "new" or $Change eq "rm")
{
# This adds / removes a directory
- $Impacts->{Makefiles} = 1;
+ $Impacts->{MakeMakefiles} = 1;
}
return;
}
@@ -216,7 +216,7 @@ sub _HandleFile($$$)
{
# This may or may not be a Wine patch but the new Makefile.in will be
# added to the build by make_makefiles.
- $Impacts->{WineBuild} = $Impacts->{Makefiles} = 1;
+ $Impacts->{WineBuild} = $Impacts->{MakeMakefiles} = 1;
}
}
}
@@ -289,7 +289,7 @@ sub GetPatchImpact($;$$)
}
elsif ($Line =~ m=^--- \w+/tools/make_makefiles$=)
{
- $Impacts->{WineBuild} = $Impacts->{Makefiles} = 1;
+ $Impacts->{WineBuild} = $Impacts->{MakeMakefiles} = 1;
$Impacts->{IsWinePatch} = 1;
}
elsif ($Line =~ m=^--- /dev/null$=)
--
2.18.0
June 26, 2018
[PATCH vkd3d 12/12] libs/vkd3d-shader: Fix returning multiple components from dot product instructions.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 76 +++++++++++++++++++++++++----------------------
tests/d3d12.c | 23 ++++++++++++++
2 files changed, 64 insertions(+), 35 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index a5e51c9643cb..bfa2bc0dacf7 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2219,6 +2219,35 @@ static uint32_t vkd3d_dxbc_compiler_emit_array_variable(struct vkd3d_dxbc_compil
return vkd3d_spirv_build_op_variable(builder, stream, ptr_type_id, storage_class, 0);
}
+static uint32_t vkd3d_dxbc_compiler_emit_construct_vector(struct vkd3d_dxbc_compiler *compiler,
+ enum vkd3d_component_type component_type, unsigned int component_count,
+ uint32_t val_id, unsigned int val_component_idx, unsigned int val_component_count)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ uint32_t components[VKD3D_VEC4_SIZE];
+ uint32_t type_id, result_id;
+ unsigned int i;
+
+ assert(val_component_idx < val_component_count);
+
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
+ if (val_component_count == 1)
+ {
+ for (i = 0; i < component_count; ++i)
+ components[i] = val_id;
+ result_id = vkd3d_spirv_build_op_composite_construct(builder,
+ type_id, components, component_count);
+ }
+ else
+ {
+ for (i = 0; i < component_count; ++i)
+ components[i] = val_component_idx;
+ result_id = vkd3d_spirv_build_op_vector_shuffle(builder,
+ type_id, val_id, val_id, components, component_count);
+ }
+ return result_id;
+}
+
static uint32_t vkd3d_dxbc_compiler_emit_load_src(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_src_param *src, DWORD write_mask);
@@ -4202,11 +4231,13 @@ static void vkd3d_dxbc_compiler_emit_dot(struct vkd3d_dxbc_compiler *compiler,
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
+ enum vkd3d_component_type component_type;
uint32_t type_id, val_id, src_ids[2];
+ unsigned int component_count, i;
DWORD write_mask;
- unsigned int i;
- assert(vkd3d_write_mask_component_count(dst->write_mask) == 1);
+ component_count = vkd3d_write_mask_component_count(dst->write_mask);
+ component_type = vkd3d_component_type_from_data_type(dst->reg.data_type);
if (instruction->handler_idx == VKD3DSIH_DP4)
write_mask = VKD3DSP_WRITEMASK_ALL;
@@ -4219,11 +4250,15 @@ static void vkd3d_dxbc_compiler_emit_dot(struct vkd3d_dxbc_compiler *compiler,
for (i = 0; i < ARRAY_SIZE(src_ids); ++i)
src_ids[i] = vkd3d_dxbc_compiler_emit_load_src(compiler, &src[i], write_mask);
- type_id = vkd3d_spirv_get_type_id(builder,
- vkd3d_component_type_from_data_type(dst->reg.data_type), 1);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
val_id = vkd3d_spirv_build_op_tr2(builder, &builder->function_stream,
SpvOpDot, type_id, src_ids[0], src_ids[1]);
+ if (component_count > 1)
+ {
+ val_id = vkd3d_dxbc_compiler_emit_construct_vector(compiler,
+ component_type, component_count, val_id, 0, 1);
+ }
vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id);
}
@@ -5270,35 +5305,6 @@ static void vkd3d_dxbc_compiler_emit_ld_raw_structured(struct vkd3d_dxbc_compile
}
}
-static uint32_t vkd3d_dxbc_compiler_emit_construct_vec4(struct vkd3d_dxbc_compiler *compiler,
- uint32_t val_id, enum vkd3d_component_type component_type,
- unsigned int component_idx, unsigned int component_count)
-{
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- uint32_t components[VKD3D_VEC4_SIZE];
- uint32_t type_id, result_id;
- unsigned int i;
-
- assert(component_idx < component_count);
-
- type_id = vkd3d_spirv_get_type_id(builder, component_type, VKD3D_VEC4_SIZE);
- if (component_count == 1)
- {
- for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
- components[i] = val_id;
- result_id = vkd3d_spirv_build_op_composite_construct(builder,
- type_id, components, VKD3D_VEC4_SIZE);
- }
- else
- {
- for (i = 0; i < VKD3D_VEC4_SIZE; ++i)
- components[i] = component_idx;
- result_id = vkd3d_spirv_build_op_vector_shuffle(builder,
- type_id, val_id, val_id, components, VKD3D_VEC4_SIZE);
- }
- return result_id;
-}
-
static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
@@ -5325,8 +5331,8 @@ static void vkd3d_dxbc_compiler_emit_store_uav_raw_structured(struct vkd3d_dxbc_
for (component_idx = 0; component_idx < component_count; ++component_idx)
{
/* Mesa Vulkan drivers require the texel parameter to be a vector. */
- texel_id = vkd3d_dxbc_compiler_emit_construct_vec4(compiler,
- val_id, VKD3D_TYPE_UINT, component_idx, component_count);
+ texel_id = vkd3d_dxbc_compiler_emit_construct_vector(compiler,
+ VKD3D_TYPE_UINT, VKD3D_VEC4_SIZE, val_id, component_idx, component_count);
coordinate_id = base_coordinate_id;
if (component_idx)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index a761c0d3cad4..c6220aa0113d 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -4919,6 +4919,26 @@ static void test_shader_instructions(void)
0x00000000, 0x0100003e,
};
static const D3D12_SHADER_BYTECODE ps_dot2 = {ps_dot2_code, sizeof(ps_dot2_code)};
+ static const DWORD ps_dot3_code[] =
+ {
+#if 0
+ float4 src0;
+ float3 src1;
+
+ float4 main() : SV_Target
+ {
+ return dot(src0, src1);
+ }
+#endif
+ 0x43425844, 0xa75a4a95, 0x5d09936e, 0xdc5c694f, 0x68b6b04f, 0x00000001, 0x000000c8, 0x00000003,
+ 0x0000002c, 0x0000003c, 0x00000070, 0x4e475349, 0x00000008, 0x00000000, 0x00000008, 0x4e47534f,
+ 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
+ 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x00000050, 0x00000050, 0x00000014,
+ 0x0100086a, 0x04000059, 0x00208e46, 0x00000000, 0x00000002, 0x03000065, 0x001020f2, 0x00000000,
+ 0x09000010, 0x001020f2, 0x00000000, 0x00208246, 0x00000000, 0x00000000, 0x00208246, 0x00000000,
+ 0x00000001, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE ps_dot3 = {ps_dot3_code, sizeof(ps_dot3_code)};
static const DWORD ps_eq_code[] =
{
#if 0
@@ -6119,6 +6139,9 @@ static void test_shader_instructions(void)
{&ps_dot2, {{1.0f, 1.0f}, {1.0f, 1.0f}}, {{2.0f}}},
{&ps_dot2, {{1.0f, 1.0f}, {2.0f, 3.0f}}, {{5.0f}}},
+ {&ps_dot3, {{1.0f, 2.0f, 3.0f, 4.0f}, {1.0f, 1.0f, 1.0f, 1.0f}}, {{6.0f, 6.0f, 6.0f, 6.0f}}},
+ {&ps_dot3, {{1.0f, 2.0f, 3.0f}, {3.0f, 1.0f, 2.0f}}, {{11.0f, 11.0f, 11.0f, 11.0f}}},
+
{&ps_eq, {{0.0f}, {0.0f}}, {.u = {0xffffffff}}},
{&ps_eq, {{1.0f}, {0.0f}}, {.u = {0x00000000}}},
{&ps_eq, {{0.0f}, {1.0f}}, {.u = {0x00000000}}},
--
2.16.4
June 26, 2018
[PATCH vkd3d 11/12] tests: Add simple test for layered rendering.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
tests/d3d12.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++-
tests/vkd3d_d3d12_test.h | 6 +-
2 files changed, 211 insertions(+), 5 deletions(-)
diff --git a/tests/d3d12.c b/tests/d3d12.c
index 0e35fc866bbc..a761c0d3cad4 100644
--- a/tests/d3d12.c
+++ b/tests/d3d12.c
@@ -663,7 +663,7 @@ static void check_sub_resource_float_(unsigned int line, ID3D12Resource *texture
{
struct resource_readback rb;
- get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list);
+ get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
check_readback_data_float_(line, &rb, NULL, expected, max_diff);
release_resource_readback(&rb);
}
@@ -745,7 +745,7 @@ static void check_sub_resource_uint16_(unsigned int line, ID3D12Resource *textur
{
struct resource_readback rb;
- get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list);
+ get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
check_readback_data_uint16_(line, &rb, NULL, expected, max_diff);
release_resource_readback(&rb);
}
@@ -17034,6 +17034,211 @@ static void test_geometry_shader(void)
destroy_test_context(&context);
}
+static void test_layered_rendering(void)
+{
+ D3D12_GRAPHICS_PIPELINE_STATE_DESC pso_desc;
+ ID3D12GraphicsCommandList *command_list;
+ D3D12_INPUT_LAYOUT_DESC input_layout;
+ struct test_context_desc desc;
+ D3D12_VERTEX_BUFFER_VIEW vbv;
+ struct test_context context;
+ ID3D12CommandQueue *queue;
+ ID3D12PipelineState *pso;
+ ID3D12Device *device;
+ ID3D12Resource *vb;
+ HRESULT hr;
+
+ static const float white[] = {1.0f, 1.0f, 1.0f, 1.0f};
+ static const struct
+ {
+ uint32_t color;
+ struct vec4 position;
+ uint32_t layer;
+ }
+ vertices[] =
+ {
+ {0x00000000, {-1.0f, -1.0f, 0.0f, 1.0f}, 2},
+ {0x00000000, {-1.0f, 1.0f, 0.0f, 1.0f}, 2},
+ {0x00000000, { 1.0f, -1.0f, 0.0f, 1.0f}, 2},
+ {0x00000000, { 1.0f, 1.0f, 0.0f, 1.0f}, 2},
+ {0xff00ff00, {-1.0f, -1.0f, 0.0f, 1.0f}, 0},
+ {0xff00ff00, {-1.0f, 1.0f, 0.0f, 1.0f}, 0},
+ {0xff00ff00, { 1.0f, -1.0f, 0.0f, 1.0f}, 0},
+ {0xff00ff00, { 1.0f, 1.0f, 0.0f, 1.0f}, 0},
+ {0xffffff00, {-1.0f, -1.0f, 0.0f, 1.0f}, 3},
+ {0xffffff00, {-1.0f, 1.0f, 0.0f, 1.0f}, 3},
+ {0xffffff00, { 1.0f, -1.0f, 0.0f, 1.0f}, 3},
+ {0xffffff00, { 1.0f, 1.0f, 0.0f, 1.0f}, 3},
+ };
+ static const D3D12_INPUT_ELEMENT_DESC layout_desc[] =
+ {
+ {"COLOR", 0, DXGI_FORMAT_R8G8B8A8_UNORM, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ {"SV_POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 4, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ {"LAYER", 0, DXGI_FORMAT_R32_UINT, 0, 20, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0},
+ };
+ static const DWORD vs_code[] =
+ {
+#if 0
+ struct vertex
+ {
+ float4 color : COLOR;
+ float4 position : SV_Position;
+ uint layer : LAYER;
+ };
+
+ struct vertex main(in vertex v)
+ {
+ return v;
+ }
+#endif
+ 0x43425844, 0x96d7f39a, 0x03d06cd5, 0x32c1fa04, 0xd509128f, 0x00000001, 0x000001ac, 0x00000003,
+ 0x0000002c, 0x0000009c, 0x0000010c, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000056, 0x00000000, 0x00000000,
+ 0x00000003, 0x00000001, 0x00000f0f, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000002,
+ 0x00000101, 0x4f4c4f43, 0x56530052, 0x736f505f, 0x6f697469, 0x414c006e, 0x00524559, 0x4e47534f,
+ 0x00000068, 0x00000003, 0x00000008, 0x00000050, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
+ 0x0000000f, 0x00000056, 0x00000000, 0x00000001, 0x00000003, 0x00000001, 0x0000000f, 0x00000062,
+ 0x00000000, 0x00000000, 0x00000001, 0x00000002, 0x00000e01, 0x4f4c4f43, 0x56530052, 0x736f505f,
+ 0x6f697469, 0x414c006e, 0x00524559, 0x58454853, 0x00000098, 0x00010050, 0x00000026, 0x0100086a,
+ 0x0300005f, 0x001010f2, 0x00000000, 0x0300005f, 0x001010f2, 0x00000001, 0x0300005f, 0x00101012,
+ 0x00000002, 0x03000065, 0x001020f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000001, 0x00000001,
+ 0x03000065, 0x00102012, 0x00000002, 0x05000036, 0x001020f2, 0x00000000, 0x00101e46, 0x00000000,
+ 0x05000036, 0x001020f2, 0x00000001, 0x00101e46, 0x00000001, 0x05000036, 0x00102012, 0x00000002,
+ 0x0010100a, 0x00000002, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE vs = {vs_code, sizeof(vs_code)};
+ static const DWORD gs_code[] =
+ {
+#if 0
+ struct gs_in
+ {
+ float4 color : COLOR;
+ float4 position : SV_Position;
+ uint layer : LAYER;
+ };
+
+ struct gs_out
+ {
+ float4 color : COLOR;
+ float4 position : SV_Position;
+ uint layer : SV_RenderTargetArrayIndex;
+ };
+
+ [maxvertexcount(3)]
+ void main(triangle gs_in vin[3], inout TriangleStream<gs_out> vout)
+ {
+ gs_out o;
+
+ o.color = vin[0].color;
+ o.position = vin[0].position;
+ o.layer = vin[0].layer;
+ vout.Append(o);
+
+ o.color = vin[1].color;
+ o.position = vin[1].position;
+ o.layer = vin[1].layer;
+ vout.Append(o);
+
+ o.color = vin[2].color;
+ o.position = vin[2].position;
+ o.layer = vin[2].layer;
+ vout.Append(o);
+ }
+#endif
+ 0x43425844, 0x29d7c0a0, 0xcf146fd1, 0x5cd36ca7, 0xab2b10ff, 0x00000001, 0x000002bc, 0x00000003,
+ 0x0000002c, 0x0000009c, 0x0000012c, 0x4e475349, 0x00000068, 0x00000003, 0x00000008, 0x00000050,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x00000056, 0x00000000, 0x00000001,
+ 0x00000003, 0x00000001, 0x00000f0f, 0x00000062, 0x00000000, 0x00000000, 0x00000001, 0x00000002,
+ 0x00000101, 0x4f4c4f43, 0x56530052, 0x736f505f, 0x6f697469, 0x414c006e, 0x00524559, 0x3547534f,
+ 0x00000088, 0x00000003, 0x00000008, 0x00000000, 0x0000005c, 0x00000000, 0x00000000, 0x00000003,
+ 0x00000000, 0x0000000f, 0x00000000, 0x00000062, 0x00000000, 0x00000001, 0x00000003, 0x00000001,
+ 0x0000000f, 0x00000000, 0x0000006e, 0x00000000, 0x00000004, 0x00000001, 0x00000002, 0x00000e01,
+ 0x4f4c4f43, 0x56530052, 0x736f505f, 0x6f697469, 0x5653006e, 0x6e65525f, 0x54726564, 0x65677261,
+ 0x72724174, 0x6e497961, 0x00786564, 0x58454853, 0x00000188, 0x00020050, 0x00000062, 0x0100086a,
+ 0x0400005f, 0x002010f2, 0x00000003, 0x00000000, 0x05000061, 0x002010f2, 0x00000003, 0x00000001,
+ 0x00000001, 0x0400005f, 0x00201012, 0x00000003, 0x00000002, 0x0100185d, 0x0300008f, 0x00110000,
+ 0x00000000, 0x0100285c, 0x03000065, 0x001020f2, 0x00000000, 0x04000067, 0x001020f2, 0x00000001,
+ 0x00000001, 0x04000067, 0x00102012, 0x00000002, 0x00000004, 0x0200005e, 0x00000003, 0x06000036,
+ 0x001020f2, 0x00000000, 0x00201e46, 0x00000000, 0x00000000, 0x06000036, 0x001020f2, 0x00000001,
+ 0x00201e46, 0x00000000, 0x00000001, 0x06000036, 0x00102012, 0x00000002, 0x0020100a, 0x00000000,
+ 0x00000002, 0x03000075, 0x00110000, 0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00201e46,
+ 0x00000001, 0x00000000, 0x06000036, 0x001020f2, 0x00000001, 0x00201e46, 0x00000001, 0x00000001,
+ 0x06000036, 0x00102012, 0x00000002, 0x0020100a, 0x00000001, 0x00000002, 0x03000075, 0x00110000,
+ 0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00201e46, 0x00000002, 0x00000000, 0x06000036,
+ 0x001020f2, 0x00000001, 0x00201e46, 0x00000002, 0x00000001, 0x06000036, 0x00102012, 0x00000002,
+ 0x0020100a, 0x00000002, 0x00000002, 0x03000075, 0x00110000, 0x00000000, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE gs = {gs_code, sizeof(gs_code)};
+ static const DWORD ps_code[] =
+ {
+#if 0
+ float4 main(float4 color : COLOR) : SV_Target0
+ {
+ return color;
+ }
+#endif
+ 0x43425844, 0xdccf00bf, 0xcc96375e, 0xba21f157, 0xe47b8b1c, 0x00000001, 0x000000d4, 0x00000003,
+ 0x0000002c, 0x0000005c, 0x00000090, 0x4e475349, 0x00000028, 0x00000001, 0x00000008, 0x00000020,
+ 0x00000000, 0x00000000, 0x00000003, 0x00000000, 0x00000f0f, 0x4f4c4f43, 0xabab0052, 0x4e47534f,
+ 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, 0x00000000,
+ 0x0000000f, 0x545f5653, 0x65677261, 0xabab0074, 0x58454853, 0x0000003c, 0x00000050, 0x0000000f,
+ 0x0100086a, 0x03001062, 0x001010f2, 0x00000000, 0x03000065, 0x001020f2, 0x00000000, 0x05000036,
+ 0x001020f2, 0x00000000, 0x00101e46, 0x00000000, 0x0100003e,
+ };
+ static const D3D12_SHADER_BYTECODE ps = {ps_code, sizeof(ps_code)};
+
+ memset(&desc, 0, sizeof(desc));
+ desc.rt_array_size = 4;
+ desc.root_signature_flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
+ desc.no_pipeline = true;
+ if (!init_test_context(&context, &desc))
+ return;
+ device = context.device;
+ command_list = context.list;
+ queue = context.queue;
+
+ input_layout.pInputElementDescs = layout_desc;
+ input_layout.NumElements = ARRAY_SIZE(layout_desc);
+
+ init_pipeline_state_desc(&pso_desc, context.root_signature,
+ context.render_target_desc.Format, &vs, &ps, &input_layout);
+ pso_desc.GS = gs;
+ hr = ID3D12Device_CreateGraphicsPipelineState(device, &pso_desc,
+ &IID_ID3D12PipelineState, (void **)&pso);
+ ok(hr == S_OK, "Failed to create graphics pipeline state, hr %#x.\n", hr);
+
+ vb = create_upload_buffer(context.device, sizeof(vertices), vertices);
+ vbv.BufferLocation = ID3D12Resource_GetGPUVirtualAddress(vb);
+ vbv.StrideInBytes = sizeof(*vertices);
+ vbv.SizeInBytes = sizeof(vertices);
+
+ ID3D12GraphicsCommandList_ClearRenderTargetView(command_list, context.rtv, white, 0, NULL);
+
+ ID3D12GraphicsCommandList_OMSetRenderTargets(command_list, 1, &context.rtv, FALSE, NULL);
+ ID3D12GraphicsCommandList_RSSetScissorRects(command_list, 1, &context.scissor_rect);
+ ID3D12GraphicsCommandList_RSSetViewports(command_list, 1, &context.viewport);
+ ID3D12GraphicsCommandList_SetGraphicsRootSignature(command_list, context.root_signature);
+ ID3D12GraphicsCommandList_SetPipelineState(command_list, pso);
+ ID3D12GraphicsCommandList_IASetPrimitiveTopology(command_list, D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
+ ID3D12GraphicsCommandList_IASetVertexBuffers(command_list, 0, 1, &vbv);
+ ID3D12GraphicsCommandList_DrawInstanced(command_list, 12, 1, 0, 0);
+
+ transition_resource_state(command_list, context.render_target,
+ D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE);
+
+ check_sub_resource_uint(context.render_target, 0, queue, command_list, 0xff00ff00, 0);
+ reset_command_list(command_list, context.allocator);
+ check_sub_resource_uint(context.render_target, 1, queue, command_list, 0xffffffff, 0);
+ reset_command_list(command_list, context.allocator);
+ check_sub_resource_uint(context.render_target, 2, queue, command_list, 0x00000000, 0);
+ reset_command_list(command_list, context.allocator);
+ check_sub_resource_uint(context.render_target, 3, queue, command_list, 0xffffff00, 0);
+
+ ID3D12Resource_Release(vb);
+ ID3D12PipelineState_Release(pso);
+ destroy_test_context(&context);
+}
+
static void test_render_a8(void)
{
static const float black[] = {0.0f, 0.0f, 0.0f, 0.0f};
@@ -17191,5 +17396,6 @@ START_TEST(d3d12)
run_test(test_face_culling);
run_test(test_multithread_command_queue_exec);
run_test(test_geometry_shader);
+ run_test(test_layered_rendering);
run_test(test_render_a8);
}
diff --git a/tests/vkd3d_d3d12_test.h b/tests/vkd3d_d3d12_test.h
index 538479e922c1..b4a9a442a5d2 100644
--- a/tests/vkd3d_d3d12_test.h
+++ b/tests/vkd3d_d3d12_test.h
@@ -313,7 +313,7 @@ static void check_sub_resource_uint_(unsigned int line, ID3D12Resource *texture,
{
struct resource_readback rb;
- get_texture_readback_with_command_list(texture, 0, &rb, queue, command_list);
+ get_texture_readback_with_command_list(texture, sub_resource_idx, &rb, queue, command_list);
check_readback_data_uint_(line, &rb, NULL, expected, max_diff);
release_resource_readback(&rb);
}
@@ -492,7 +492,7 @@ static ID3D12PipelineState *create_pipeline_state_(unsigned int line, ID3D12Devi
struct test_context_desc
{
- unsigned int rt_width, rt_height;
+ unsigned int rt_width, rt_height, rt_array_size;
DXGI_FORMAT rt_format;
unsigned int rt_descriptor_count;
unsigned int root_signature_flags;
@@ -540,7 +540,7 @@ static void create_render_target_(unsigned int line, struct test_context *contex
resource_desc.Alignment = 0;
resource_desc.Width = desc && desc->rt_width ? desc->rt_width : 32;
resource_desc.Height = desc && desc->rt_height ? desc->rt_height : 32;
- resource_desc.DepthOrArraySize = 1;
+ resource_desc.DepthOrArraySize = desc && desc->rt_array_size ? desc->rt_array_size : 1;
resource_desc.MipLevels = 1;
resource_desc.Format = desc && desc->rt_format ? desc->rt_format : DXGI_FORMAT_R8G8B8A8_UNORM;
resource_desc.SampleDesc.Count = 1;
--
2.16.4
June 26, 2018
[PATCH vkd3d 10/12] libs/vkd3d: Add support for 2D array render target views.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d/command.c | 41 +++++++++++++++++++++++------------------
libs/vkd3d/resource.c | 8 ++++++--
libs/vkd3d/vkd3d_private.h | 2 ++
3 files changed, 31 insertions(+), 20 deletions(-)
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 82a99fda2511..ee1d3f6e1018 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1583,7 +1583,7 @@ static HRESULT STDMETHODCALLTYPE d3d12_command_list_ClearState(ID3D12GraphicsCom
}
static void d3d12_command_list_get_fb_extent(struct d3d12_command_list *list,
- uint32_t *width, uint32_t *height)
+ uint32_t *width, uint32_t *height, uint32_t *layer_count)
{
struct d3d12_device *device = list->device;
@@ -1591,11 +1591,15 @@ static void d3d12_command_list_get_fb_extent(struct d3d12_command_list *list,
{
*width = list->fb_width;
*height = list->fb_height;
+ if (layer_count)
+ *layer_count = list->fb_layer_count;
}
else
{
*width = device->vk_info.device_limits.maxFramebufferWidth;
*height = device->vk_info.device_limits.maxFramebufferHeight;
+ if (layer_count)
+ *layer_count = 1;
}
}
@@ -1620,8 +1624,7 @@ static bool d3d12_command_list_update_current_framebuffer(struct d3d12_command_l
fb_desc.renderPass = list->state->u.graphics.render_pass;
fb_desc.attachmentCount = list->state->u.graphics.attachment_count;
fb_desc.pAttachments = &list->views[start_idx];
- d3d12_command_list_get_fb_extent(list, &fb_desc.width, &fb_desc.height);
- fb_desc.layers = 1;
+ d3d12_command_list_get_fb_extent(list, &fb_desc.width, &fb_desc.height, &fb_desc.layers);
if ((vr = VK_CALL(vkCreateFramebuffer(device->vk_device, &fb_desc, NULL, &vk_framebuffer))) < 0)
{
WARN("Failed to create Vulkan framebuffer, vr %d.\n", vr);
@@ -2212,7 +2215,7 @@ static bool d3d12_command_list_begin_render_pass(struct d3d12_command_list *list
begin_desc.renderArea.offset.x = 0;
begin_desc.renderArea.offset.y = 0;
d3d12_command_list_get_fb_extent(list,
- &begin_desc.renderArea.extent.width, &begin_desc.renderArea.extent.height);
+ &begin_desc.renderArea.extent.width, &begin_desc.renderArea.extent.height, NULL);
begin_desc.clearValueCount = 0;
begin_desc.pClearValues = NULL;
VK_CALL(vkCmdBeginRenderPass(list->vk_command_buffer, &begin_desc, VK_SUBPASS_CONTENTS_INLINE));
@@ -3438,6 +3441,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
list->fb_width = 0;
list->fb_height = 0;
+ list->fb_layer_count = 0;
for (i = 0; i < render_target_descriptor_count; ++i)
{
if (single_descriptor_handle)
@@ -3448,10 +3452,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
d3d12_command_list_track_resource_usage(list, rtv_desc->resource);
list->views[i + 1] = rtv_desc->vk_view;
- if (rtv_desc->width > list->fb_width)
- list->fb_width = rtv_desc->width;
- if (rtv_desc->height > list->fb_height)
- list->fb_height = rtv_desc->height;
+ list->fb_width = max(list->fb_width, rtv_desc->width);
+ list->fb_height = max(list->fb_height, rtv_desc->height);
+ list->fb_layer_count = max(list->fb_layer_count, rtv_desc->layer_count);
}
if (depth_stencil_descriptor)
@@ -3460,10 +3463,9 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
d3d12_command_list_track_resource_usage(list, dsv_desc->resource);
- if (dsv_desc->width > list->fb_width)
- list->fb_width = dsv_desc->width;
- if (dsv_desc->height > list->fb_height)
- list->fb_height = dsv_desc->height;
+ list->fb_width = max(list->fb_width, dsv_desc->width);
+ list->fb_height = max(list->fb_height, dsv_desc->height);
+ list->fb_layer_count = max(list->fb_layer_count, 1);
list->views[0] = dsv_desc->vk_view;
}
@@ -3471,9 +3473,10 @@ static void STDMETHODCALLTYPE d3d12_command_list_OMSetRenderTargets(ID3D12Graphi
d3d12_command_list_invalidate_current_framebuffer(list);
}
-static void d3d12_command_list_clear(struct d3d12_command_list *list, const struct vkd3d_vk_device_procs *vk_procs,
- const struct VkAttachmentDescription *attachment_desc, const struct VkAttachmentReference *color_reference,
- const struct VkAttachmentReference *ds_reference, VkImageView vk_view, size_t width, size_t height,
+static void d3d12_command_list_clear(struct d3d12_command_list *list,
+ const struct vkd3d_vk_device_procs *vk_procs, const struct VkAttachmentDescription *attachment_desc,
+ const struct VkAttachmentReference *color_reference, const struct VkAttachmentReference *ds_reference,
+ VkImageView vk_view, size_t width, size_t height, unsigned int layer_count,
const union VkClearValue *clear_value, unsigned int rect_count, const D3D12_RECT *rects)
{
struct VkSubpassDescription sub_pass_desc;
@@ -3538,7 +3541,7 @@ static void d3d12_command_list_clear(struct d3d12_command_list *list, const stru
fb_desc.pAttachments = &vk_view;
fb_desc.width = width;
fb_desc.height = height;
- fb_desc.layers = 1;
+ fb_desc.layers = layer_count;
if ((vr = VK_CALL(vkCreateFramebuffer(list->device->vk_device, &fb_desc, NULL, &vk_framebuffer))) < 0)
{
WARN("Failed to create Vulkan framebuffer, vr %d.\n", vr);
@@ -3615,7 +3618,7 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearDepthStencilView(ID3D12Gra
ds_reference.layout = VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL;
d3d12_command_list_clear(list, &list->device->vk_procs, &attachment_desc, NULL, &ds_reference,
- dsv_desc->vk_view, dsv_desc->width, dsv_desc->height, &clear_value, rect_count, rects);
+ dsv_desc->vk_view, dsv_desc->width, dsv_desc->height, 1, &clear_value, rect_count, rects);
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12GraphicsCommandList *iface,
@@ -3646,7 +3649,8 @@ static void STDMETHODCALLTYPE d3d12_command_list_ClearRenderTargetView(ID3D12Gra
color_reference.layout = VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL;
d3d12_command_list_clear(list, &list->device->vk_procs, &attachment_desc, &color_reference, NULL,
- rtv_desc->vk_view, rtv_desc->width, rtv_desc->height, &clear_value, rect_count, rects);
+ rtv_desc->vk_view, rtv_desc->width, rtv_desc->height, rtv_desc->layer_count,
+ &clear_value, rect_count, rects);
}
static void STDMETHODCALLTYPE d3d12_command_list_ClearUnorderedAccessViewUint(ID3D12GraphicsCommandList *iface,
@@ -4005,6 +4009,7 @@ static HRESULT d3d12_command_list_init(struct d3d12_command_list *list, struct d
memset(list->views, 0, sizeof(list->views));
list->fb_width = 0;
list->fb_height = 0;
+ list->fb_layer_count = 0;
list->current_framebuffer = VK_NULL_HANDLE;
list->current_pipeline = VK_NULL_HANDLE;
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index 2ccb84797514..e45c90083229 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -1534,6 +1534,7 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev
struct d3d12_resource *resource, const D3D12_RENDER_TARGET_VIEW_DESC *desc)
{
const struct vkd3d_format *format;
+ VkImageViewType vk_view_type;
uint32_t miplevel_idx;
d3d12_rtv_desc_destroy(rtv_desc, device);
@@ -1566,13 +1567,16 @@ void d3d12_rtv_desc_create_rtv(struct d3d12_rtv_desc *rtv_desc, struct d3d12_dev
FIXME("Ignoring plane slice %u.\n", desc->u.Texture2D.PlaneSlice);
miplevel_idx = desc ? desc->u.Texture2D.MipSlice : 0;
- if (vkd3d_create_texture_view(device, resource, format, VK_IMAGE_VIEW_TYPE_2D,
- miplevel_idx, 1, 0, 1, false, &rtv_desc->vk_view) < 0)
+ vk_view_type = resource->desc.DepthOrArraySize > 1
+ ? VK_IMAGE_VIEW_TYPE_2D_ARRAY : VK_IMAGE_VIEW_TYPE_2D;
+ if (vkd3d_create_texture_view(device, resource, format, vk_view_type,
+ miplevel_idx, 1, 0, VK_REMAINING_ARRAY_LAYERS, false, &rtv_desc->vk_view) < 0)
return;
rtv_desc->format = format->vk_format;
rtv_desc->width = d3d12_resource_desc_get_width(&resource->desc, miplevel_idx);
rtv_desc->height = d3d12_resource_desc_get_height(&resource->desc, miplevel_idx);
+ rtv_desc->layer_count = resource->desc.DepthOrArraySize;
rtv_desc->magic = VKD3D_DESCRIPTOR_MAGIC_RTV;
rtv_desc->resource = resource;
}
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 7506471fbe6c..38f0bf38e215 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -287,6 +287,7 @@ struct d3d12_rtv_desc
VkFormat format;
uint64_t width;
unsigned int height;
+ unsigned int layer_count;
VkImageView vk_view;
struct d3d12_resource *resource;
};
@@ -587,6 +588,7 @@ struct d3d12_command_list
VkImageView views[D3D12_SIMULTANEOUS_RENDER_TARGET_COUNT + 1];
unsigned int fb_width;
unsigned int fb_height;
+ unsigned int fb_layer_count;
VkFramebuffer current_framebuffer;
VkPipeline current_pipeline;
--
2.16.4
June 26, 2018
[PATCH vkd3d 09/12] libs/vkd3d-shader: Do not emit output setup for ret in geometry shaders.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 1961ba62f202..a5e51c9643cb 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -4541,7 +4541,8 @@ static void vkd3d_dxbc_compiler_emit_return(struct vkd3d_dxbc_compiler *compiler
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- vkd3d_dxbc_compiler_emit_output_setup_invocation(compiler);
+ if (compiler->shader_type != VKD3D_SHADER_TYPE_GEOMETRY)
+ vkd3d_dxbc_compiler_emit_output_setup_invocation(compiler);
vkd3d_spirv_build_op_return(builder);
}
--
2.16.4
June 26, 2018
[PATCH vkd3d 08/12] libs/vkd3d-shader: Generate correct SPIR-V code for arrayed shader inputs.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 41 ++++++++++++++++++++++++++++-------------
1 file changed, 28 insertions(+), 13 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 881f8109ea3d..1961ba62f202 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2983,16 +2983,17 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
const struct vkd3d_shader_signature_element *signature_element;
const struct vkd3d_shader_register *reg = &dst->reg;
+ uint32_t type_id, ptr_type_id, float_type_id;
const struct vkd3d_spirv_builtin *builtin;
enum vkd3d_component_type component_type;
uint32_t val_id, input_id, var_id;
- uint32_t type_id, float_type_id;
struct vkd3d_symbol reg_symbol;
SpvStorageClass storage_class;
struct rb_entry *entry = NULL;
bool use_private_var = false;
unsigned int array_size;
unsigned int reg_idx;
+ uint32_t i, index;
assert(!reg->idx[0].rel_addr);
assert(!reg->idx[1].rel_addr);
@@ -3071,22 +3072,36 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
if (use_private_var)
{
type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count);
- val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone);
+ for (i = 0; i < max(array_size, 1); ++i)
+ {
+ struct vkd3d_shader_register dst_reg = *reg;
- if (builtin && builtin->fixup_pfn)
- val_id = builtin->fixup_pfn(compiler, val_id);
+ val_id = input_id;
+ if (array_size)
+ {
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, SpvStorageClassInput, type_id);
+ index = vkd3d_dxbc_compiler_get_constant_uint(compiler, i);
+ val_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder,
+ ptr_type_id, input_id, &index, 1);
+ dst_reg.idx[0].offset = i;
+ }
+ val_id = vkd3d_spirv_build_op_load(builder, type_id, val_id, SpvMemoryAccessMaskNone);
- if (component_type != VKD3D_TYPE_FLOAT)
- {
- float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, input_component_count);
- val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id);
- }
+ if (builtin && builtin->fixup_pfn)
+ val_id = builtin->fixup_pfn(compiler, val_id);
- if (input_component_count != component_count)
- val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
- val_id, VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, dst->write_mask);
+ if (component_type != VKD3D_TYPE_FLOAT)
+ {
+ float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, input_component_count);
+ val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id);
+ }
- vkd3d_dxbc_compiler_emit_store_reg(compiler, reg, dst->write_mask, val_id);
+ if (input_component_count != component_count)
+ val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
+ val_id, VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, dst->write_mask);
+
+ vkd3d_dxbc_compiler_emit_store_reg(compiler, &dst_reg, dst->write_mask, val_id);
+ }
}
return input_id;
--
2.16.4
June 26, 2018
[PATCH vkd3d 07/12] libs/vkd3d-shader: Pass register index to vkd3d_find_signature_element_for_reg().
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 28cfb8977ea2..881f8109ea3d 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2949,13 +2949,13 @@ static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(enum vkd3d_shad
static const struct vkd3d_shader_signature_element *vkd3d_find_signature_element_for_reg(
const struct vkd3d_shader_signature *signature, unsigned int *signature_element_index,
- const struct vkd3d_shader_register *reg, DWORD write_mask)
+ unsigned int reg_idx, DWORD write_mask)
{
unsigned int signature_idx;
for (signature_idx = 0; signature_idx < signature->element_count; ++signature_idx)
{
- if (signature->elements[signature_idx].register_index == reg->idx[0].offset
+ if (signature->elements[signature_idx].register_index == reg_idx
&& (signature->elements[signature_idx].mask & 0xff) == write_mask)
{
if (signature_element_index)
@@ -2965,7 +2965,7 @@ static const struct vkd3d_shader_signature_element *vkd3d_find_signature_element
}
FIXME("Could not find shader signature element (register %u, write mask %#x).\n",
- reg->idx[0].offset, write_mask);
+ reg_idx, write_mask);
if (signature_element_index)
*signature_element_index = ~0u;
return NULL;
@@ -3020,7 +3020,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
else
{
signature_element = vkd3d_find_signature_element_for_reg(compiler->input_signature,
- NULL, reg, dst->write_mask);
+ NULL, reg_idx, dst->write_mask);
component_type = signature_element ? signature_element->component_type : VKD3D_TYPE_FLOAT;
input_component_count = component_count;
}
@@ -3164,7 +3164,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *comp
uint32_t id, var_id;
signature_element = vkd3d_find_signature_element_for_reg(compiler->output_signature,
- &signature_idx, reg, dst->write_mask);
+ &signature_idx, reg->idx[0].offset, dst->write_mask);
builtin = vkd3d_get_spirv_builtin(dst->reg.type, sysval);
component_idx = vkd3d_write_mask_get_component_idx(dst->write_mask);
--
2.16.4
June 26, 2018
[PATCH vkd3d 06/12] libs/vkd3d-shader: Simplify vkd3d_dxbc_compiler_emit_input().
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 40 ++++++++++++++++++----------------------
1 file changed, 18 insertions(+), 22 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index f2a1b1141e23..28cfb8977ea2 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2985,7 +2985,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
const struct vkd3d_shader_register *reg = &dst->reg;
const struct vkd3d_spirv_builtin *builtin;
enum vkd3d_component_type component_type;
- uint32_t val_id = 0, input_id, var_id;
+ uint32_t val_id, input_id, var_id;
uint32_t type_id, float_type_id;
struct vkd3d_symbol reg_symbol;
SpvStorageClass storage_class;
@@ -3043,26 +3043,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
vkd3d_spirv_build_op_decorate1(builder, input_id, SpvDecorationComponent, component_idx);
}
- if (component_type != VKD3D_TYPE_FLOAT || component_count != VKD3D_VEC4_SIZE)
- {
- type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count);
- val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone);
-
- if (builtin && builtin->fixup_pfn)
- val_id = builtin->fixup_pfn(compiler, val_id);
-
- if (component_type != VKD3D_TYPE_FLOAT)
- {
- float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, input_component_count);
- val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id);
- }
-
- use_private_var = true;
- }
-
- if (val_id && input_component_count != component_count)
- val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
- val_id, VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, dst->write_mask);
+ use_private_var = component_type != VKD3D_TYPE_FLOAT || component_count != VKD3D_VEC4_SIZE;
vkd3d_symbol_make_register(®_symbol, reg);
@@ -3089,7 +3070,22 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
if (use_private_var)
{
- assert(val_id);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, input_component_count);
+ val_id = vkd3d_spirv_build_op_load(builder, type_id, input_id, SpvMemoryAccessMaskNone);
+
+ if (builtin && builtin->fixup_pfn)
+ val_id = builtin->fixup_pfn(compiler, val_id);
+
+ if (component_type != VKD3D_TYPE_FLOAT)
+ {
+ float_type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, input_component_count);
+ val_id = vkd3d_spirv_build_op_bitcast(builder, float_type_id, val_id);
+ }
+
+ if (input_component_count != component_count)
+ val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
+ val_id, VKD3D_TYPE_FLOAT, VKD3D_NO_SWIZZLE, dst->write_mask);
+
vkd3d_dxbc_compiler_emit_store_reg(compiler, reg, dst->write_mask, val_id);
}
--
2.16.4
June 26, 2018
[PATCH vkd3d 05/12] libs/vkd3d-shader: Enable "geometry" capability for SpvBuiltInLayer.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index cf4fbf6d7a3a..f2a1b1141e23 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2770,8 +2770,21 @@ static void vkd3d_dxbc_compiler_decorate_builtin(struct vkd3d_dxbc_compiler *com
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL && builtin == SpvBuiltInPosition)
- builtin = SpvBuiltInFragCoord;
+ switch (builtin)
+ {
+ case SpvBuiltInPosition:
+ if (compiler->shader_type == VKD3D_SHADER_TYPE_PIXEL)
+ builtin = SpvBuiltInFragCoord;
+ break;
+ case SpvBuiltInFragDepth:
+ vkd3d_spirv_enable_depth_replacing(builder);
+ break;
+ case SpvBuiltInLayer:
+ vkd3d_spirv_enable_capability(builder, SpvCapabilityGeometry);
+ break;
+ default:
+ break;
+ }
vkd3d_spirv_build_op_decorate1(builder, target_id, SpvDecorationBuiltIn, builtin);
}
@@ -3228,9 +3241,6 @@ static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *comp
compiler->output_setup_function_id = vkd3d_spirv_alloc_id(builder);
}
- if (builtin && builtin->spirv_builtin == SpvBuiltInFragDepth)
- vkd3d_spirv_enable_depth_replacing(builder);
-
return id;
}
--
2.16.4
June 26, 2018
[PATCH vkd3d 04/12] libs/vkd3d-shader: Do not force input register type to float4.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Produces slightly smaller and cleaner SPIR-V code.
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 76 +++++++++++++++++++++++++++++++++++++++++++----
1 file changed, 70 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 71db4be6b493..cf4fbf6d7a3a 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2886,26 +2886,51 @@ vkd3d_register_builtins[] =
{VKD3DSPR_DEPTHOUT, {VKD3D_TYPE_FLOAT, 1, SpvBuiltInFragDepth}},
};
-static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(enum vkd3d_shader_register_type reg_type,
+static const struct vkd3d_spirv_builtin *get_spirv_builtin_for_sysval(
enum vkd3d_shader_input_sysval_semantic sysval)
{
unsigned int i;
+ if (!sysval)
+ return NULL;
+
for (i = 0; i < ARRAY_SIZE(vkd3d_system_value_builtins); ++i)
{
if (vkd3d_system_value_builtins[i].sysval == sysval)
return &vkd3d_system_value_builtins[i].builtin;
}
+ FIXME("Unhandled builtin (sysval %#x).\n", sysval);
+
+ return NULL;
+}
+
+static const struct vkd3d_spirv_builtin *get_spirv_builtin_for_register(
+ enum vkd3d_shader_register_type reg_type)
+{
+ unsigned int i;
+
for (i = 0; i < ARRAY_SIZE(vkd3d_register_builtins); ++i)
{
if (vkd3d_register_builtins[i].reg_type == reg_type)
return &vkd3d_register_builtins[i].builtin;
}
- if (sysval != VKD3D_SIV_NONE
- || (reg_type != VKD3DSPR_INPUT && reg_type != VKD3DSPR_OUTPUT && reg_type != VKD3DSPR_COLOROUT))
- FIXME("Unhandled builtin (register type %#x, semantic %#x).\n", reg_type, sysval);
+ return NULL;
+}
+
+static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(enum vkd3d_shader_register_type reg_type,
+ enum vkd3d_shader_input_sysval_semantic sysval)
+{
+ const struct vkd3d_spirv_builtin *builtin;
+
+ if ((builtin = get_spirv_builtin_for_sysval(sysval)))
+ return builtin;
+ if ((builtin = get_spirv_builtin_for_register(reg_type)))
+ return builtin;
+
+ if (sysval != VKD3D_SIV_NONE || (reg_type != VKD3DSPR_OUTPUT && reg_type != VKD3DSPR_COLOROUT))
+ FIXME("Unhandled builtin (register type %#x, sysval %#x).\n", reg_type, sysval);
return NULL;
}
@@ -2970,7 +2995,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
reg_idx = reg->idx[0].offset;
}
- builtin = vkd3d_get_spirv_builtin(reg->type, sysval);
+ builtin = get_spirv_builtin_for_sysval(sysval);
component_idx = vkd3d_write_mask_get_component_idx(dst->write_mask);
component_count = vkd3d_write_mask_component_count(dst->write_mask);
@@ -3058,6 +3083,40 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
return input_id;
}
+static void vkd3d_dxbc_compiler_emit_input_register(struct vkd3d_dxbc_compiler *compiler,
+ const struct vkd3d_shader_dst_param *dst)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ const struct vkd3d_shader_register *reg = &dst->reg;
+ const struct vkd3d_spirv_builtin *builtin;
+ struct vkd3d_symbol reg_symbol;
+ uint32_t input_id;
+
+ assert(!reg->idx[0].rel_addr);
+ assert(!reg->idx[1].rel_addr);
+ assert(reg->idx[1].offset == ~0u);
+
+ if (!(builtin = get_spirv_builtin_for_register(reg->type)))
+ {
+ FIXME("Unhandled register %#x.\n", reg->type);
+ return;
+ }
+
+ input_id = vkd3d_dxbc_compiler_emit_variable(compiler,
+ &builder->global_stream, SpvStorageClassInput,
+ builtin->component_type, builtin->component_count);
+ vkd3d_spirv_add_iface_variable(builder, input_id);
+ vkd3d_dxbc_compiler_decorate_builtin(compiler, input_id, builtin->spirv_builtin);
+
+ vkd3d_symbol_make_register(®_symbol, reg);
+ reg_symbol.id = input_id;
+ reg_symbol.info.reg.storage_class = SpvStorageClassInput;
+ reg_symbol.info.reg.component_type = builtin->component_type;
+ reg_symbol.info.reg.write_mask = vkd3d_write_mask_from_component_count(builtin->component_count);
+ vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
+ vkd3d_dxbc_compiler_emit_register_debug_name(builder, input_id, reg);
+}
+
static unsigned int vkd3d_dxbc_compiler_get_output_variable_index(
struct vkd3d_dxbc_compiler *compiler, unsigned int register_idx)
{
@@ -3649,7 +3708,12 @@ static void vkd3d_dxbc_compiler_emit_dcl_tgsm_structured(struct vkd3d_dxbc_compi
static void vkd3d_dxbc_compiler_emit_dcl_input(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_instruction *instruction)
{
- vkd3d_dxbc_compiler_emit_input(compiler, &instruction->declaration.dst, VKD3D_SIV_NONE);
+ const struct vkd3d_shader_dst_param *dst = &instruction->declaration.dst;
+
+ if (dst->reg.type != VKD3DSPR_INPUT)
+ vkd3d_dxbc_compiler_emit_input_register(compiler, dst);
+ else
+ vkd3d_dxbc_compiler_emit_input(compiler, dst, VKD3D_SIV_NONE);
}
static void vkd3d_dxbc_compiler_emit_interpolation_decorations(struct vkd3d_dxbc_compiler *compiler,
--
2.16.4
June 26, 2018
[PATCH vkd3d 03/12] libs/vkd3d-shader: Add initial support for typed registers.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 119 ++++++++++++++++++++++++-------
libs/vkd3d-shader/vkd3d_shader_private.h | 6 ++
2 files changed, 98 insertions(+), 27 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 8f6a833cd313..71db4be6b493 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -1667,6 +1667,8 @@ struct vkd3d_symbol_register_data
{
SpvStorageClass storage_class;
uint32_t member_idx;
+ enum vkd3d_component_type component_type;
+ unsigned int write_mask;
unsigned int structure_stride;
};
@@ -2243,6 +2245,8 @@ struct vkd3d_shader_register_info
{
uint32_t id;
SpvStorageClass storage_class;
+ enum vkd3d_component_type component_type;
+ unsigned int write_mask;
uint32_t member_idx;
unsigned int structure_stride;
};
@@ -2260,6 +2264,8 @@ static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *co
assert(reg->idx[0].offset < compiler->temp_count);
register_info->id = compiler->temp_id + reg->idx[0].offset;
register_info->storage_class = SpvStorageClassFunction;
+ register_info->component_type = VKD3D_TYPE_FLOAT;
+ register_info->write_mask = VKD3DSP_WRITEMASK_ALL;
register_info->member_idx = 0;
return true;
}
@@ -2275,6 +2281,8 @@ static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *co
symbol = RB_ENTRY_VALUE(entry, struct vkd3d_symbol, entry);
register_info->id = symbol->id;
register_info->storage_class = symbol->info.reg.storage_class;
+ register_info->component_type = symbol->info.reg.component_type;
+ register_info->write_mask = symbol->info.reg.write_mask;
register_info->structure_stride = symbol->info.reg.structure_stride;
register_info->member_idx = symbol->info.reg.member_idx;
@@ -2356,14 +2364,15 @@ static uint32_t vkd3d_dxbc_compiler_get_register_id(struct vkd3d_dxbc_compiler *
}
}
-static uint32_t vkd3d_dxbc_compiler_emit_swizzle(struct vkd3d_dxbc_compiler *compiler,
- uint32_t val_id, enum vkd3d_component_type component_type, DWORD swizzle, DWORD write_mask)
+static uint32_t vkd3d_dxbc_compiler_emit_swizzle_ext(struct vkd3d_dxbc_compiler *compiler,
+ uint32_t val_id, unsigned int val_write_mask, enum vkd3d_component_type component_type,
+ unsigned int swizzle, unsigned int write_mask)
{
+ unsigned int i, component_idx, component_count, val_component_count;
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- unsigned int i, component_idx, component_count;
uint32_t type_id, components[VKD3D_VEC4_SIZE];
- if (swizzle == VKD3D_NO_SWIZZLE && write_mask == VKD3DSP_WRITEMASK_ALL)
+ if (swizzle == VKD3D_NO_SWIZZLE && write_mask == val_write_mask)
return val_id;
component_count = vkd3d_write_mask_component_count(write_mask);
@@ -2376,6 +2385,20 @@ static uint32_t vkd3d_dxbc_compiler_emit_swizzle(struct vkd3d_dxbc_compiler *com
return vkd3d_spirv_build_op_composite_extract1(builder, type_id, val_id, component_idx);
}
+ val_component_count = vkd3d_write_mask_component_count(val_write_mask);
+ if (val_component_count == 1)
+ {
+ for (i = 0, component_idx = 0; i < VKD3D_VEC4_SIZE; ++i)
+ {
+ if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
+ {
+ assert(VKD3DSP_WRITEMASK_0 << vkd3d_swizzle_get_component(swizzle, i) == val_write_mask);
+ components[component_idx++] = val_id;
+ }
+ }
+ return vkd3d_spirv_build_op_composite_construct(builder, type_id, components, component_count);
+ }
+
for (i = 0, component_idx = 0; i < VKD3D_VEC4_SIZE; ++i)
{
if (write_mask & (VKD3DSP_WRITEMASK_0 << i))
@@ -2385,6 +2408,13 @@ static uint32_t vkd3d_dxbc_compiler_emit_swizzle(struct vkd3d_dxbc_compiler *com
type_id, val_id, val_id, components, component_count);
}
+static uint32_t vkd3d_dxbc_compiler_emit_swizzle(struct vkd3d_dxbc_compiler *compiler,
+ uint32_t val_id, enum vkd3d_component_type component_type, DWORD swizzle, DWORD write_mask)
+{
+ return vkd3d_dxbc_compiler_emit_swizzle_ext(compiler,
+ val_id, VKD3DSP_WRITEMASK_ALL, component_type, swizzle, write_mask);
+}
+
static uint32_t vkd3d_dxbc_compiler_emit_load_constant(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
{
@@ -2416,36 +2446,44 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- uint32_t type_id, ptr_type_id, indexes[1], chain_id, val_id;
+ uint32_t type_id, ptr_type_id, indexes[1], reg_id, val_id;
+ unsigned int component_idx, reg_component_count;
struct vkd3d_shader_register_info reg_info;
- unsigned int component_idx;
+ enum vkd3d_component_type component_type;
assert(reg->type != VKD3DSPR_IMMCONST);
assert(vkd3d_write_mask_component_count(write_mask) == 1);
component_idx = vkd3d_write_mask_get_component_idx(write_mask);
component_idx = vkd3d_swizzle_get_component(swizzle, component_idx);
+ component_type = vkd3d_component_type_from_data_type(reg->data_type);
if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®_info))
{
- type_id = vkd3d_spirv_get_type_id(builder,
- vkd3d_component_type_from_data_type(reg->data_type), 1);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
}
vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info);
+ reg_component_count = vkd3d_write_mask_component_count(reg_info.write_mask);
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 1);
- ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id);
- indexes[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx);
- chain_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder,
- ptr_type_id, reg_info.id, indexes, ARRAY_SIZE(indexes));
+ if (component_idx > reg_component_count)
+ ERR("Invalid component_idx for register %#x, %u.\n", reg->type, reg->idx[0].offset);
- val_id = vkd3d_spirv_build_op_load(builder, type_id, chain_id, SpvMemoryAccessMaskNone);
+ type_id = vkd3d_spirv_get_type_id(builder, reg_info.component_type, 1);
+ reg_id = reg_info.id;
+ if (reg_component_count != 1)
+ {
+ ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id);
+ indexes[0] = vkd3d_dxbc_compiler_get_constant_uint(compiler, component_idx);
+ reg_id = vkd3d_spirv_build_op_in_bounds_access_chain(builder,
+ ptr_type_id, reg_id, indexes, ARRAY_SIZE(indexes));
+ }
- if (reg->data_type != VKD3D_DATA_FLOAT)
+ val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_id, SpvMemoryAccessMaskNone);
+
+ if (component_type != reg_info.component_type)
{
- type_id = vkd3d_spirv_get_type_id(builder,
- vkd3d_component_type_from_data_type(reg->data_type), 1);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, 1);
val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
}
@@ -2456,8 +2494,10 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
const struct vkd3d_shader_register *reg, DWORD swizzle, DWORD write_mask)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
- uint32_t src_id, type_id, val_id;
+ struct vkd3d_shader_register_info reg_info;
+ enum vkd3d_component_type component_type;
unsigned int component_count;
+ uint32_t type_id, val_id;
if (reg->type == VKD3DSPR_IMMCONST)
return vkd3d_dxbc_compiler_emit_load_constant(compiler, reg, swizzle, write_mask);
@@ -2466,17 +2506,24 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_reg(struct vkd3d_dxbc_compiler *co
if (component_count == 1)
return vkd3d_dxbc_compiler_emit_load_scalar(compiler, reg, swizzle, write_mask);
- src_id = vkd3d_dxbc_compiler_get_register_id(compiler, reg);
- type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE);
- val_id = vkd3d_spirv_build_op_load(builder, type_id, src_id, SpvMemoryAccessMaskNone);
+ component_type = vkd3d_component_type_from_data_type(reg->data_type);
+ if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®_info))
+ {
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
+ return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
+ }
+ vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info);
- val_id = vkd3d_dxbc_compiler_emit_swizzle(compiler,
- val_id, VKD3D_TYPE_FLOAT, swizzle, write_mask);
+ type_id = vkd3d_spirv_get_type_id(builder,
+ reg_info.component_type, vkd3d_write_mask_component_count(reg_info.write_mask));
+ val_id = vkd3d_spirv_build_op_load(builder, type_id, reg_info.id, SpvMemoryAccessMaskNone);
- if (reg->data_type != VKD3D_DATA_FLOAT)
+ val_id = vkd3d_dxbc_compiler_emit_swizzle_ext(compiler,
+ val_id, reg_info.write_mask, reg_info.component_type, swizzle, write_mask);
+
+ if (component_type != reg_info.component_type)
{
- type_id = vkd3d_spirv_get_type_id(builder,
- vkd3d_component_type_from_data_type(reg->data_type), component_count);
+ type_id = vkd3d_spirv_get_type_id(builder, component_type, component_count);
val_id = vkd3d_spirv_build_op_bitcast(builder, type_id, val_id);
}
@@ -2995,6 +3042,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_input(struct vkd3d_dxbc_compiler *compi
{
reg_symbol.id = var_id;
reg_symbol.info.reg.storage_class = storage_class;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_FLOAT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
@@ -3105,6 +3154,8 @@ static uint32_t vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *comp
{
reg_symbol.id = var_id;
reg_symbol.info.reg.storage_class = storage_class;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_FLOAT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
vkd3d_dxbc_compiler_emit_register_debug_name(builder, var_id, reg);
@@ -3221,6 +3272,8 @@ static void vkd3d_dxbc_compiler_emit_push_constant_buffers(struct vkd3d_dxbc_com
reg_symbol.id = var_id;
reg_symbol.info.reg.storage_class = storage_class;
reg_symbol.info.reg.member_idx = j;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_FLOAT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
++j;
@@ -3281,6 +3334,8 @@ static void vkd3d_dxbc_compiler_emit_dcl_constant_buffer(struct vkd3d_dxbc_compi
reg_symbol.id = var_id;
reg_symbol.info.reg.storage_class = storage_class;
reg_symbol.info.reg.member_idx = 0;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_FLOAT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
}
@@ -3314,6 +3369,8 @@ static void vkd3d_dxbc_compiler_emit_dcl_immediate_constant_buffer(struct vkd3d_
vkd3d_symbol_make_register(®_symbol, ®);
reg_symbol.id = icb_id;
reg_symbol.info.reg.storage_class = SpvStorageClassPrivate;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_FLOAT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_ALL;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
}
@@ -3566,6 +3623,8 @@ static void vkd3d_dxbc_compiler_emit_workgroup_memory(struct vkd3d_dxbc_compiler
reg_symbol.id = var_id;
reg_symbol.info.reg.storage_class = storage_class;
reg_symbol.info.reg.member_idx = 0;
+ reg_symbol.info.reg.component_type = VKD3D_TYPE_UINT;
+ reg_symbol.info.reg.write_mask = VKD3DSP_WRITEMASK_0;
reg_symbol.info.reg.structure_stride = structure_stride;
vkd3d_dxbc_compiler_put_symbol(compiler, ®_symbol);
}
@@ -3959,13 +4018,19 @@ static void vkd3d_dxbc_compiler_emit_mov(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_dst_param *dst = instruction->dst;
const struct vkd3d_shader_src_param *src = instruction->src;
uint32_t val_id, dst_val_id, type_id, dst_id, src_id;
+ struct vkd3d_shader_register_info reg_info;
uint32_t components[VKD3D_VEC4_SIZE];
unsigned int i, component_count;
component_count = vkd3d_write_mask_component_count(dst->write_mask);
+ memset(®_info, 0, sizeof(reg_info));
+ if (src->reg.type != VKD3DSPR_IMMCONST)
+ vkd3d_dxbc_compiler_get_register_info(compiler, &src->reg, ®_info);
+
if (component_count == 1 || component_count == VKD3D_VEC4_SIZE
- || dst->modifiers || src->modifiers || src->reg.type == VKD3DSPR_IMMCONST)
+ || dst->modifiers || src->modifiers || src->reg.type == VKD3DSPR_IMMCONST
+ || reg_info.component_type != VKD3D_TYPE_FLOAT || reg_info.write_mask != VKD3DSP_WRITEMASK_ALL)
{
val_id = vkd3d_dxbc_compiler_emit_load_src(compiler, src, dst->write_mask);
vkd3d_dxbc_compiler_emit_store_dst(compiler, dst, val_id);
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 7fc42627f820..9eb2c126332d 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -872,6 +872,12 @@ static inline unsigned int vkd3d_write_mask_component_count(DWORD write_mask)
return count;
}
+static inline unsigned int vkd3d_write_mask_from_component_count(unsigned int component_count)
+{
+ assert(component_count <= 4);
+ return (VKD3DSP_WRITEMASK_0 << component_count) - 1;
+}
+
static inline unsigned int vkd3d_swizzle_get_component(DWORD swizzle,
unsigned int idx)
{
--
2.16.4
June 26, 2018
[PATCH vkd3d 02/12] libs/vkd3d-shader: Do not generate code in vkd3d_dxbc_compiler_get_register_info().
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 289797de9f01..8f6a833cd313 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2243,18 +2243,15 @@ struct vkd3d_shader_register_info
{
uint32_t id;
SpvStorageClass storage_class;
+ uint32_t member_idx;
unsigned int structure_stride;
};
static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *compiler,
const struct vkd3d_shader_register *reg, struct vkd3d_shader_register_info *register_info)
{
- struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
struct vkd3d_symbol reg_symbol, *symbol;
- uint32_t type_id, ptr_type_id;
- uint32_t index_count = 0;
struct rb_entry *entry;
- uint32_t indexes[2];
assert(reg->type != VKD3DSPR_IMMCONST);
@@ -2263,6 +2260,7 @@ static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *co
assert(reg->idx[0].offset < compiler->temp_count);
register_info->id = compiler->temp_id + reg->idx[0].offset;
register_info->storage_class = SpvStorageClassFunction;
+ register_info->member_idx = 0;
return true;
}
@@ -2278,11 +2276,23 @@ static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *co
register_info->id = symbol->id;
register_info->storage_class = symbol->info.reg.storage_class;
register_info->structure_stride = symbol->info.reg.structure_stride;
+ register_info->member_idx = symbol->info.reg.member_idx;
+
+ return true;
+}
+
+static void vkd3d_dxbc_compiler_emit_dereference_register(struct vkd3d_dxbc_compiler *compiler,
+ const struct vkd3d_shader_register *reg, struct vkd3d_shader_register_info *register_info)
+{
+ struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
+ uint32_t type_id, ptr_type_id;
+ unsigned int index_count = 0;
+ uint32_t indexes[2];
if (reg->type == VKD3DSPR_CONSTBUFFER)
{
assert(!reg->idx[0].rel_addr);
- indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, symbol->info.reg.member_idx);
+ indexes[index_count++] = vkd3d_dxbc_compiler_get_constant_uint(compiler, register_info->member_idx);
indexes[index_count++] = vkd3d_dxbc_compiler_emit_register_addressing(compiler, ®->idx[1]);
}
else if (reg->type == VKD3DSPR_IMMCONSTBUFFER)
@@ -2306,8 +2316,6 @@ static bool vkd3d_dxbc_compiler_get_register_info(struct vkd3d_dxbc_compiler *co
register_info->id = vkd3d_spirv_build_op_access_chain(builder, ptr_type_id,
register_info->id, indexes, index_count);
}
-
- return true;
}
static uint32_t vkd3d_dxbc_compiler_get_register_id(struct vkd3d_dxbc_compiler *compiler,
@@ -2331,7 +2339,10 @@ static uint32_t vkd3d_dxbc_compiler_get_register_id(struct vkd3d_dxbc_compiler *
case VKD3DSPR_LOCALTHREADINDEX:
case VKD3DSPR_THREADGROUPID:
if (vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®ister_info))
+ {
+ vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®ister_info);
return register_info.id;
+ }
return vkd3d_dxbc_compiler_emit_variable(compiler, &builder->global_stream,
SpvStorageClassPrivate, VKD3D_TYPE_FLOAT, VKD3D_VEC4_SIZE);
case VKD3DSPR_IMMCONST:
@@ -2421,6 +2432,7 @@ static uint32_t vkd3d_dxbc_compiler_emit_load_scalar(struct vkd3d_dxbc_compiler
vkd3d_component_type_from_data_type(reg->data_type), 1);
return vkd3d_spirv_build_op_undef(builder, &builder->global_stream, type_id);
}
+ vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 1);
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id);
@@ -2565,6 +2577,7 @@ static void vkd3d_dxbc_compiler_emit_store_scalar(struct vkd3d_dxbc_compiler *co
if (!vkd3d_dxbc_compiler_get_register_info(compiler, reg, ®_info))
return;
+ vkd3d_dxbc_compiler_emit_dereference_register(compiler, reg, ®_info);
type_id = vkd3d_spirv_get_type_id(builder, VKD3D_TYPE_FLOAT, 1);
ptr_type_id = vkd3d_spirv_get_op_type_pointer(builder, reg_info.storage_class, type_id);
--
2.16.4
June 26, 2018
[PATCH vkd3d 01/12] libs/vkd3d-shader: Split SPIR-V built-ins table into two tables.
by Józef Kucia
From: Józef Kucia <jkucia(a)codeweavers.com>
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 75 +++++++++++++++++++++++++++--------------------
1 file changed, 43 insertions(+), 32 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 10806a5a9a2f..289797de9f01 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2747,7 +2747,7 @@ typedef uint32_t (*vkd3d_spirv_builtin_fixup_pfn)(struct vkd3d_dxbc_compiler *co
uint32_t val_id);
/* Substitute "InstanceIndex - BaseInstance" for SV_InstanceID. */
-static uint32_t vkd3d_spirv_instance_id_fixup(struct vkd3d_dxbc_compiler *compiler,
+static uint32_t sv_instance_id_fixup(struct vkd3d_dxbc_compiler *compiler,
uint32_t instance_index_id)
{
struct vkd3d_spirv_builder *builder = &compiler->spirv_builder;
@@ -2773,47 +2773,57 @@ static uint32_t vkd3d_spirv_instance_id_fixup(struct vkd3d_dxbc_compiler *compil
type_id, instance_index_id, base_instance_id);
}
-static uint32_t vkd3d_spirv_front_facing_fixup(struct vkd3d_dxbc_compiler *compiler,
+static uint32_t sv_front_face_fixup(struct vkd3d_dxbc_compiler *compiler,
uint32_t front_facing_id)
{
return vkd3d_dxbc_compiler_emit_bool_to_int(compiler, 1, front_facing_id);
}
-/*
- * The following table is based on the "14.6. Built-In Variables" section from
- * the Vulkan spec.
- */
-static const struct vkd3d_spirv_builtin
+struct vkd3d_spirv_builtin
{
- enum vkd3d_shader_input_sysval_semantic sysval;
- enum vkd3d_shader_register_type reg_type;
-
enum vkd3d_component_type component_type;
unsigned int component_count;
SpvBuiltIn spirv_builtin;
vkd3d_spirv_builtin_fixup_pfn fixup_pfn;
+};
+
+/*
+ * The following tables are based on the "14.6. Built-In Variables" section
+ * from the Vulkan spec.
+ */
+static const struct
+{
+ enum vkd3d_shader_input_sysval_semantic sysval;
+ struct vkd3d_spirv_builtin builtin;
}
-vkd3d_spirv_builtin_table[] =
+vkd3d_system_value_builtins[] =
{
- {VKD3D_SIV_NONE, VKD3DSPR_THREADID, VKD3D_TYPE_INT, 3, SpvBuiltInGlobalInvocationId},
- {VKD3D_SIV_NONE, VKD3DSPR_LOCALTHREADID, VKD3D_TYPE_INT, 3, SpvBuiltInLocalInvocationId},
- {VKD3D_SIV_NONE, VKD3DSPR_LOCALTHREADINDEX, VKD3D_TYPE_INT, 1, SpvBuiltInLocalInvocationIndex},
- {VKD3D_SIV_NONE, VKD3DSPR_THREADGROUPID, VKD3D_TYPE_INT, 3, SpvBuiltInWorkgroupId},
+ {VKD3D_SIV_POSITION, {VKD3D_TYPE_FLOAT, 4, SpvBuiltInPosition}},
+ {VKD3D_SIV_VERTEX_ID, {VKD3D_TYPE_INT, 1, SpvBuiltInVertexIndex}},
+ {VKD3D_SIV_INSTANCE_ID, {VKD3D_TYPE_INT, 1, SpvBuiltInInstanceIndex, sv_instance_id_fixup}},
- {VKD3D_SIV_NONE, VKD3DSPR_GSINSTID, VKD3D_TYPE_INT, 1, SpvBuiltInInvocationId},
- {VKD3D_SIV_NONE, VKD3DSPR_OUTPOINTID, VKD3D_TYPE_INT, 1, SpvBuiltInInvocationId},
+ {VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX, {VKD3D_TYPE_INT, 1, SpvBuiltInLayer}},
- {VKD3D_SIV_NONE, VKD3DSPR_TESSCOORD, VKD3D_TYPE_FLOAT, 3, SpvBuiltInTessCoord},
-
- {VKD3D_SIV_NONE, VKD3DSPR_DEPTHOUT, VKD3D_TYPE_FLOAT, 1, SpvBuiltInFragDepth},
+ {VKD3D_SIV_IS_FRONT_FACE, {VKD3D_TYPE_BOOL, 1, SpvBuiltInFrontFacing, sv_front_face_fixup}},
+};
+static const struct
+{
+ enum vkd3d_shader_register_type reg_type;
+ struct vkd3d_spirv_builtin builtin;
+}
+vkd3d_register_builtins[] =
+{
+ {VKD3DSPR_THREADID, {VKD3D_TYPE_INT, 3, SpvBuiltInGlobalInvocationId}},
+ {VKD3DSPR_LOCALTHREADID, {VKD3D_TYPE_INT, 3, SpvBuiltInLocalInvocationId}},
+ {VKD3DSPR_LOCALTHREADINDEX, {VKD3D_TYPE_INT, 1, SpvBuiltInLocalInvocationIndex}},
+ {VKD3DSPR_THREADGROUPID, {VKD3D_TYPE_INT, 3, SpvBuiltInWorkgroupId}},
- {VKD3D_SIV_POSITION, ~0u, VKD3D_TYPE_FLOAT, 4, SpvBuiltInPosition},
- {VKD3D_SIV_VERTEX_ID, ~0u, VKD3D_TYPE_INT, 1, SpvBuiltInVertexIndex},
- {VKD3D_SIV_INSTANCE_ID, ~0u, VKD3D_TYPE_INT, 1, SpvBuiltInInstanceIndex, vkd3d_spirv_instance_id_fixup},
+ {VKD3DSPR_GSINSTID, {VKD3D_TYPE_INT, 1, SpvBuiltInInvocationId}},
+ {VKD3DSPR_OUTPOINTID, {VKD3D_TYPE_INT, 1, SpvBuiltInInvocationId}},
- {VKD3D_SIV_RENDER_TARGET_ARRAY_INDEX, ~0u, VKD3D_TYPE_INT, 1, SpvBuiltInLayer},
+ {VKD3DSPR_TESSCOORD, {VKD3D_TYPE_FLOAT, 3, SpvBuiltInTessCoord}},
- {VKD3D_SIV_IS_FRONT_FACE, ~0u, VKD3D_TYPE_BOOL, 1, SpvBuiltInFrontFacing, vkd3d_spirv_front_facing_fixup},
+ {VKD3DSPR_DEPTHOUT, {VKD3D_TYPE_FLOAT, 1, SpvBuiltInFragDepth}},
};
static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(enum vkd3d_shader_register_type reg_type,
@@ -2821,15 +2831,16 @@ static const struct vkd3d_spirv_builtin *vkd3d_get_spirv_builtin(enum vkd3d_shad
{
unsigned int i;
- for (i = 0; i < ARRAY_SIZE(vkd3d_spirv_builtin_table); ++i)
+ for (i = 0; i < ARRAY_SIZE(vkd3d_system_value_builtins); ++i)
{
- const struct vkd3d_spirv_builtin* current = &vkd3d_spirv_builtin_table[i];
-
- if (current->sysval == VKD3D_SIV_NONE && current->reg_type == reg_type)
- return current;
+ if (vkd3d_system_value_builtins[i].sysval == sysval)
+ return &vkd3d_system_value_builtins[i].builtin;
+ }
- if (current->reg_type == ~0u && current->sysval == sysval)
- return current;
+ for (i = 0; i < ARRAY_SIZE(vkd3d_register_builtins); ++i)
+ {
+ if (vkd3d_register_builtins[i].reg_type == reg_type)
+ return &vkd3d_register_builtins[i].builtin;
}
if (sysval != VKD3D_SIV_NONE
--
2.16.4
June 26, 2018
[PATCH] testbot/web: Adjust the GetFile MIME type based on Step->FileType.
by Francois Gouget
This lets the browser offer to open the patches in a text editor instead
of systematically suggesting to save them to disk.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
Not an urgent or very important patch but I believe it will make some
people pretty happy.
testbot/web/GetFile.pl | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/testbot/web/GetFile.pl b/testbot/web/GetFile.pl
index 7e274a8bf..1fe140788 100644
--- a/testbot/web/GetFile.pl
+++ b/testbot/web/GetFile.pl
@@ -84,9 +84,11 @@ sub GetFile($$$)
# HTTP/1.0
$Request->headers_out->add("Pragma", "no-cache");
-
- # Binary file
- $Request->content_type("application/octet-stream");
+
+ # Text or binary file
+ my $MIME = $Step->FileType eq "patchdlls" ? "text/plain" :
+ "application/octet-stream";
+ $Request->content_type($MIME);
$Request->headers_out->add("Content-Disposition",
'attachment; filename="' . $Step->FileName . '"');
--
2.18.0
June 26, 2018
Re: [PATCH 3/5] devenum: Make some variables static.
by Alexandre Julliard
Zebediah Figura <z.figura12(a)gmail.com> writes:
> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> ---
> dlls/devenum/createdevenum.c | 14 ++++++--------
> dlls/devenum/devenum_main.c | 13 ++++---------
> dlls/devenum/devenum_private.h | 4 +---
> dlls/devenum/mediacatenum.c | 4 +++-
> 4 files changed, 14 insertions(+), 21 deletions(-)
It doesn't work here:
../../../tools/runtest -q -P wine -T ../../.. -M devenum.dll -p devenum_test.exe.so devenum && touch devenum.ok
devenum.c:585: Test failed: filter should be registered
devenum.c:592: Test failed: Read failed: 0x80070002
devenum.c:595: Test failed: expected L"{DEADBEEF-CF51-43E6-B6C5-299EA8B6B591}", got L"\58e1\e0f1\cb04\11d0\4ebd\a000\11c9\86ce\2a92\37e9\d9aa\11d2\84bf\f28e\55b1\ed5a\29d1\e306\27e5\11ce\5d87\6000\b78c\6680\29d2\e306\27e5\11ce\5d87\6000\b78c\6680\9faf\0558\c356\11ce\01bf\aa00\5500\5a59\ca52\2ca8\3c3f\11d2\3db7\c000\b64f\3dbd\a762\33d9\90c8\11d0\43bd\a000\11c9\86ce\8d32\a5ea\253d\11d1\f1b3"...
devenum.c:600: Test failed: Read failed: 0x80070002
devenum.c:601: Test failed: expected L"{DEADBEEF-CF51-43E6-B6C5-299EA8B6B591}", got L"\58e1\e0f1\cb04\11d0\4ebd\a000\11c9\86ce\2a92\37e9\d9aa\11d2\84bf\f28e\55b1\ed5a\29d1\e306\27e5\11ce\5d87\6000\b78c\6680\29d2\e306\27e5\11ce\5d87\6000\b78c\6680\9faf\0558\c356\11ce\01bf\aa00\5500\5a59\ca52\2ca8\3c3f\11d2\3db7\c000\b64f\3dbd\a762\33d9\90c8\11d0\43bd\a000\11c9\86ce\8d32\a5ea\253d\11d1\f1b3"...
Makefile:183: recipe for target 'devenum.ok' failed
make: *** [devenum.ok] Error 5
--
Alexandre Julliard
julliard(a)winehq.org
June 26, 2018
[PATCH 7/7] testbot/WineSendLog: Fix detection of new errors.
by Francois Gouget
Comparing the compilation log with the reference WineTest report makes
no sense. So handle the WineTest reports and task logs separately.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineSendLog.pl | 29 ++++++++++++++++++++++-------
1 file changed, 22 insertions(+), 7 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index 53b184cff..29da4a04d 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -439,13 +439,23 @@ EOF
my $TaskDir = $StepTask->GetTaskDir();
my ($BotFailure, $MessagesFromErr) = CheckErrLog("$TaskDir/err");
- if (! $BotFailure)
+ if ($BotFailure)
+ {
+ # TestBot errors are not the developer's fault and prevent us from doing
+ # any meaningful analysis. So skip.
+ Error "A TestBot error was found in $TaskDir/err\n";
+ next;
+ }
+
+ my $MessagesFromLog = "";
+ my $LogFiles = GetLogFileNames($TaskDir);
+ my $LogName = $LogFiles->[0] || "log";
+ if ($LogName =~ /\.report$/)
{
$StepTask->FileName =~ m/^(.*)_test(64)?\.exe$/;
my ($BaseName, $Bits) = ($1, $2 || "32");
my $LatestName = "$DataDir/latest/" . $StepTask->VM->Name . "_$Bits";
my ($LatestBotFailure, $Dummy) = CheckErrLog("$LatestName.err");
- my $MessagesFromLog = "";
if (! $LatestBotFailure)
{
if (defined($StepTask->CmdLineArg))
@@ -463,15 +473,20 @@ EOF
{
Error "BotFailure found in ${LatestName}.err\n";
}
- if ($MessagesFromErr || $MessagesFromLog)
+ }
+ elsif (open(my $LogFile, "<", "$TaskDir/$LogName"))
+ {
+ foreach my $Line (<$LogFile>)
{
- $Messages .= "\n=== " . $StepTask->GetTitle() . " ===\n" .
- $MessagesFromLog . $MessagesFromErr;
+ my $Category = GetLogLineCategory($Line);
+ $MessagesFromLog .= $Line if ($Category eq "error");
}
+ close($LogFile);
}
- elsif ($BotFailure)
+ if ($MessagesFromErr || $MessagesFromLog)
{
- Error "BotFailure found in $TaskDir/err\n";
+ $Messages .= "\n=== " . $StepTask->GetTitle() . " ===\n" .
+ $MessagesFromLog . $MessagesFromErr;
}
}
--
2.18.0
June 26, 2018
[PATCH 6/7] testbot/WineSendLog: Use LogUtils to get the report / log filename.
by Francois Gouget
Currently we will either have a test report or a task log file so it's
ok to only take into account the first file returned by
GetLogFileNames().
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineSendLog.pl | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index 33978095e..53b184cff 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -272,11 +272,13 @@ EOF
foreach my $Key (@SortedKeys)
{
my $StepTask = $StepsTasks->GetItem($Key);
+ my $TaskDir = $StepTask->GetTaskDir();
print SENDMAIL "\n=== ", $StepTask->GetTitle(), " ===\n";
- my $TaskDir = $StepTask->GetTaskDir();
- if (open LOGFILE, "<$TaskDir/log")
+ my $LogFiles = GetLogFileNames($TaskDir);
+ my $LogName = $LogFiles->[0] || "log";
+ if (open LOGFILE, "<$TaskDir/$LogName")
{
my $HasLogEntries = !1;
my $PrintedSomething = !1;
@@ -376,6 +378,7 @@ EOF
foreach my $Key (@SortedKeys)
{
my $StepTask = $StepsTasks->GetItem($Key);
+ my $TaskDir = $StepTask->GetTaskDir();
print SENDMAIL <<"EOF";
--$PART_BOUNDARY
@@ -387,9 +390,10 @@ EOF
$StepTask->VM->Name, ".log\n\n";
print SENDMAIL "Not dumping logs in debug mode\n" if ($Debug);
+ my $LogFiles = GetLogFileNames($TaskDir);
+ my $LogName = $LogFiles->[0] || "log";
my $PrintSeparator = !1;
- my $TaskDir = $StepTask->GetTaskDir();
- if (open LOGFILE, "<$TaskDir/log")
+ if (open LOGFILE, "<$TaskDir/$LogName")
{
my $Line;
while (defined($Line = <LOGFILE>))
@@ -432,8 +436,8 @@ EOF
foreach my $Key (@FailureKeys)
{
my $StepTask = $StepsTasks->GetItem($Key);
-
my $TaskDir = $StepTask->GetTaskDir();
+
my ($BotFailure, $MessagesFromErr) = CheckErrLog("$TaskDir/err");
if (! $BotFailure)
{
@@ -449,7 +453,9 @@ EOF
# Filter out failures that happened in the full test suite:
# the test suite is run against code which is already in Wine
# so any failure it reported is not caused by this patch.
- $MessagesFromLog = CompareLogs("$LatestName.log", "$TaskDir/log",
+ my $LogFiles = GetLogFileNames($TaskDir);
+ my $LogName = $LogFiles->[0] || "log";
+ $MessagesFromLog = CompareLogs("$LatestName.log", "$TaskDir/$LogName",
$BaseName, $StepTask->CmdLineArg);
}
}
@@ -537,11 +543,14 @@ EOF
foreach my $Key (@SortedKeys)
{
my $StepTask = $StepsTasks->GetItem($Key);
+ my $TaskDir = $StepTask->GetTaskDir();
+
print $result "\n=== ", $StepTask->GetTitle(), " ===\n";
+ my $LogFiles = GetLogFileNames($TaskDir);
+ my $LogName = $LogFiles->[0] || "log";
my $PrintSeparator = !1;
- my $TaskDir = $StepTask->GetTaskDir();
- if (open(my $logfile, "<", "$TaskDir/log"))
+ if (open(my $logfile, "<", "$TaskDir/$LogName"))
{
my $Line;
while (defined($Line = <$logfile>))
--
2.18.0
June 26, 2018
[PATCH 5/7] testbot/WineSendLog: Use LogUtils to identify errors in the log files.
by Francois Gouget
GetLogLineCategory()'s error detection is much more complete and this
avoids code duplication.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineSendLog.pl | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index 2f097796e..33978095e 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -45,6 +45,7 @@ use Algorithm::Diff;
use WineTestBot::Config;
use WineTestBot::Jobs;
use WineTestBot::Log;
+use WineTestBot::LogUtils;
use WineTestBot::StepsTasks;
@@ -290,8 +291,8 @@ EOF
{
$CurrentDll = $1;
}
- if ($Line =~ m/: Test failed: / || $Line =~ m/ done \(258\)/ ||
- $Line =~ m/: unhandled exception [0-9a-fA-F]{8} at /)
+ my $Category = GetLogLineCategory($Line);
+ if ($Category eq "error")
{
if ($PrintedDll ne $CurrentDll)
{
--
2.18.0
June 26, 2018
[PATCH 4/7] testbot: Avoid duplicating the part boundary uuid.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineSendLog.pl | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index ed3453b80..2f097796e 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -48,6 +48,9 @@ use WineTestBot::Log;
use WineTestBot::StepsTasks;
+my $PART_BOUNDARY = "==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==";
+
+
#
# Logging and error handling helpers
#
@@ -241,9 +244,9 @@ sub SendLog($)
}
print SENDMAIL <<"EOF";
MIME-Version: 1.0
-Content-Type: multipart/mixed; boundary="==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47=="
+Content-Type: multipart/mixed; boundary="$PART_BOUNDARY"
---==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==
+--$PART_BOUNDARY
Content-Type: text/plain; charset="UTF-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
@@ -374,7 +377,7 @@ EOF
my $StepTask = $StepsTasks->GetItem($Key);
print SENDMAIL <<"EOF";
---==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==
+--$PART_BOUNDARY
Content-Type: text/plain; charset="UTF-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 8bit
@@ -414,7 +417,7 @@ EOF
}
}
- print SENDMAIL "--==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==--\n";
+ print SENDMAIL "--$PART_BOUNDARY--\n";
close(SENDMAIL);
# This is all for jobs submitted from the website
--
2.18.0
June 26, 2018
[PATCH 3/7] testbot/WineSendLog: Add proper command line handling and options.
by Francois Gouget
When run in --debug mode WineSendLog prints the emails it would normally
send instead of piping them to sendmail.
Also the script now prints the error messages to stderr by default to
make it easier to figure things out when running it on the command
line. The --log-only option can be used when that's not desired.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/Engine.pl | 2 +-
testbot/bin/WineSendLog.pl | 193 +++++++++++++++++++++++++++++++------
2 files changed, 164 insertions(+), 31 deletions(-)
diff --git a/testbot/bin/Engine.pl b/testbot/bin/Engine.pl
index ce3509440..464b6db45 100755
--- a/testbot/bin/Engine.pl
+++ b/testbot/bin/Engine.pl
@@ -320,7 +320,7 @@ sub HandleJobStatusChange($$$)
CloseAllDBBackEnds();
WineTestBot::Log::SetupRedirects();
- exec("$BinDir/${ProjectName}SendLog.pl $JobKey") or
+ exec("$BinDir/${ProjectName}SendLog.pl --log-only $JobKey") or
LogMsg "Unable to exec ${ProjectName}SendLog.pl: $!\n";
exit(1);
}
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index e03395af1..ed3453b80 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -36,14 +36,47 @@ sub BEGIN
unshift @INC, "$::RootDir/lib";
}
}
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
use Algorithm::Diff;
+
use WineTestBot::Config;
use WineTestBot::Jobs;
use WineTestBot::Log;
use WineTestBot::StepsTasks;
+#
+# Logging and error handling helpers
+#
+
+my $Debug;
+sub Debug(@)
+{
+ print STDERR @_ if ($Debug);
+}
+
+sub DebugTee($@)
+{
+ my ($File) = shift;
+ print $File @_;
+ Debug(@_);
+}
+
+my $LogOnly;
+sub Error(@)
+{
+ print STDERR "$Name0:error: ", @_ if (!$LogOnly);
+ LogMsg @_;
+}
+
+
+#
+# Log analysis
+#
+
sub IsBotFailure($)
{
my ($ErrLine) = @_;
@@ -121,7 +154,7 @@ sub ReadLog($$$)
}
else
{
- LogMsg "Unable to open '$LogName' for reading: $!\n";
+ Error "Unable to open '$LogName' for reading: $!\n";
}
return \@Messages;
@@ -179,7 +212,19 @@ sub SendLog($)
my $StepsTasks = CreateStepsTasks(undef, $Job);
my @SortedKeys = sort @{$StepsTasks->GetKeys()};
- open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+ #
+ # Send a job summary and all the logs as attachments to the developer
+ #
+
+ Debug("-------------------- Developer email --------------------\n");
+ if ($Debug)
+ {
+ open(SENDMAIL, ">>&=", 1);
+ }
+ else
+ {
+ open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+ }
print SENDMAIL "From: $RobotEMail\n";
print SENDMAIL "To: $To\n";
my $Subject = "TestBot job " . $Job->Id . " results";
@@ -218,6 +263,7 @@ EOF
$TestFailures;
}
+ # Print the job summary
my @FailureKeys;
foreach my $Key (@SortedKeys)
{
@@ -322,6 +368,7 @@ EOF
}
}
+ # Print the log attachments
foreach my $Key (@SortedKeys)
{
my $StepTask = $StepsTasks->GetItem($Key);
@@ -334,6 +381,7 @@ Content-Transfer-Encoding: 8bit
EOF
print SENDMAIL "Content-Disposition: attachment; filename=",
$StepTask->VM->Name, ".log\n\n";
+ print SENDMAIL "Not dumping logs in debug mode\n" if ($Debug);
my $PrintSeparator = !1;
my $TaskDir = $StepTask->GetTaskDir();
@@ -343,7 +391,7 @@ EOF
while (defined($Line = <LOGFILE>))
{
$Line =~ s/\s*$//;
- print SENDMAIL "$Line\n";
+ print SENDMAIL "$Line\n" if (!$Debug);
$PrintSeparator = 1;
}
close LOGFILE;
@@ -356,11 +404,11 @@ EOF
{
if ($PrintSeparator)
{
- print SENDMAIL "\n";
+ print SENDMAIL "\n" if (!$Debug);
$PrintSeparator = !1;
}
$Line =~ s/\s*$//;
- print SENDMAIL "$Line\n";
+ print SENDMAIL "$Line\n" if (!$Debug);
}
close ERRFILE;
}
@@ -369,10 +417,12 @@ EOF
print SENDMAIL "--==13F70BD1-BA1B-449A-9CCB-B6A8E90CED47==--\n";
close(SENDMAIL);
- if (! defined($Job->Patch))
- {
- return;
- }
+ # This is all for jobs submitted from the website
+ return if (!defined $Job->Patch);
+
+ #
+ # Build a job summary with only the new errors
+ #
my $Messages = "";
foreach my $Key (@FailureKeys)
@@ -401,7 +451,7 @@ EOF
}
else
{
- LogMsg "BotFailure found in ${LatestName}.err\n";
+ Error "BotFailure found in ${LatestName}.err\n";
}
if ($MessagesFromErr || $MessagesFromLog)
{
@@ -411,15 +461,28 @@ EOF
}
elsif ($BotFailure)
{
- LogMsg "BotFailure found in $TaskDir/err\n";
+ Error "BotFailure found in $TaskDir/err\n";
}
}
+ #
+ # Send a summary of the new errors to the mailing list
+ #
+
+ Debug("\n-------------------- Mailing list email --------------------\n");
+
my $WebSite = ($UseSSL ? "https://" : "http://") . $WebHostName;
if ($Messages)
{
- open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+ if ($Debug)
+ {
+ open(SENDMAIL, ">>&=", 1);
+ }
+ else
+ {
+ open (SENDMAIL, "|/usr/sbin/sendmail -oi -t -odq");
+ }
print SENDMAIL "From: $RobotEMail\n";
print SENDMAIL "To: $To\n";
print SENDMAIL "Cc: $WinePatchCc\n";
@@ -445,6 +508,14 @@ EOF
print SENDMAIL $Messages;
close SENDMAIL;
}
+ else
+ {
+ Debug("Found no error to report to the mailing list\n");
+ }
+
+ #
+ # Create a .testbot file for the patches website
+ #
my $Patch = $Job->Patch;
if (defined $Patch->WebPatchId and -d "$DataDir/webpatches")
@@ -452,9 +523,12 @@ EOF
my $BaseName = "$DataDir/webpatches/" . $Patch->WebPatchId;
if (open (my $result, ">", "$BaseName.testbot"))
{
- print $result "Status: " . ($Messages ? "Failed" : "OK") . "\n";
- print $result "Job-ID: " . $Job->Id . "\n";
- print $result "URL: $WebSite/JobDetails.pl?Key=" . $Job->GetKey() . "\n";
+ Debug("\n-------------------- WebPatches report --------------------\n");
+ # Only take into account new errors to decide whether the job was
+ # successful or not.
+ DebugTee($result, "Status: ". ($Messages ? "Failed" : "OK") ."\n");
+ DebugTee($result, "Job-ID: ". $Job->Id ."\n");
+ DebugTee($result, "URL: $WebSite/JobDetails.pl?Key=". $Job->GetKey() ."\n");
foreach my $Key (@SortedKeys)
{
@@ -496,7 +570,7 @@ EOF
}
else
{
- LogMsg "Job " . $Job->Id . ": Unable to open '$BaseName.testbot' for writing: $!";
+ Error "Job ". $Job->Id .": Unable to open '$BaseName.testbot' for writing: $!";
}
}
}
@@ -509,37 +583,96 @@ EOF
$ENV{PATH} = "/usr/bin:/bin";
delete $ENV{ENV};
-my $JobId = $ARGV[0];
-if (! $JobId)
+my $Usage;
+sub ValidateNumber($$)
+{
+ my ($Name, $Value) = @_;
+
+ # Validate and untaint the value
+ return $1 if ($Value =~ /^(\d+)$/);
+ Error "$Value is not a valid $Name\n";
+ $Usage = 2;
+ return undef;
+}
+
+my ($JobId);
+while (@ARGV)
{
- die "Usage: WineSendLog.pl JobId";
+ my $Arg = shift @ARGV;
+ if ($Arg eq "--debug")
+ {
+ $Debug = 1;
+ }
+ elsif ($Arg eq "--log-only")
+ {
+ $LogOnly = 1;
+ }
+ elsif ($Arg =~ /^(?:-\?|-h|--help)$/)
+ {
+ $Usage = 0;
+ last;
+ }
+ elsif ($Arg =~ /^-/)
+ {
+ Error "unknown option '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+ elsif (!defined $JobId)
+ {
+ $JobId = ValidateNumber('job id', $Arg);
+ }
+ else
+ {
+ Error "unexpected argument '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
}
-# Untaint parameters
-if ($JobId =~ /^(\d+)$/)
+# Check parameters
+if (!defined $Usage)
{
- $JobId = $1;
+ if (!defined $JobId)
+ {
+ Error "you must specify the job id\n";
+ $Usage = 2;
+ }
}
-else
+if (defined $Usage)
{
- LogMsg "Invalid JobId $JobId\n";
- exit(1);
+ if ($Usage)
+ {
+ Error "try '$Name0 --help' for more information\n";
+ exit $Usage;
+ }
+ print "Usage: $Name0 [--debug] [--help] JOBID\n";
+ print "\n";
+ print "Analyze the job's logs and notifies the developer and the patches website.\n";
+ print "\n";
+ print "Where:\n";
+ print " JOBID Id of the job to report on.\n";
+ print " --debug More verbose messages for debugging.\n";
+ print " --log-only Only send error messages to the log instead of also printing them\n";
+ print " on stderr.\n";
+ print " --help Shows this usage message.\n";
+ exit 0;
}
my $Job = CreateJobs()->GetItem($JobId);
-if (! defined($Job))
+if (!defined $Job)
{
- LogMsg "Job $JobId doesn't exist\n";
- exit(1);
+ Error "Job $JobId doesn't exist\n";
+ exit 1;
}
#
-# Analyze the log and notify the developer
+# Analyze the log, notify the developer and the Patches website
#
SendLog($Job);
LogMsg "Log for job $JobId sent\n";
-exit(0);
+exit 0;
--
2.18.0
June 26, 2018
[PATCH 2/7] testbot/web: Let LogUtils build the list of task reports and logs.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/LogUtils.pm | 55 ++++++++++++++++++++++++++++-
testbot/web/JobDetails.pl | 20 ++++-------
2 files changed, 60 insertions(+), 15 deletions(-)
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index daa9c0bd8..3dfd7c5e7 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -27,7 +27,7 @@ WineTestBot::LogUtils - Provides functions to parse task logs
use Exporter 'import';
-our @EXPORT = qw(GetLogLineCategory ParseTaskLog);
+our @EXPORT = qw(GetLogFileNames GetLogLabel GetLogLineCategory ParseTaskLog);
#
@@ -133,4 +133,57 @@ sub GetLogLineCategory($)
return "none";
}
+=pod
+=over 12
+
+=item C<GetLogFileNames()>
+
+Scans the directory for test reports and task logs and returns their filenames.
+The filenames are returned in the order in which the logs are meant to be
+presented.
+
+=back
+=cut
+
+sub GetLogFileNames($;$)
+{
+ my ($Dir, $IncludeOld) = @_;
+
+ my @Candidates = ("exe32.report", "exe64.report",
+ "log", "err");
+ push @Candidates, "log.old", "err.old" if ($IncludeOld);
+
+ my @Logs;
+ foreach my $FileName (@Candidates)
+ {
+ push @Logs, $FileName if (-f "$Dir/$FileName" and !-z "$Dir/$FileName");
+ }
+ return \@Logs;
+}
+
+my %_LogFileLabels = (
+ "exe32.report" => "32 bit Windows report",
+ "exe64.report" => "64 bit Windows report",
+ "err" => "task errors",
+ "log" => "task log",
+ "err.old" => "old task errors",
+ "log.old" => "old logs",
+);
+
+=pod
+=over 12
+
+=item C<GetLogLabel()>
+
+Returns a user-friendly description of the content of the specified log file.
+
+=back
+=cut
+
+sub GetLogLabel($)
+{
+ my ($LogFileName) = @_;
+ return $_LogFileLabels{$LogFileName};
+}
+
1;
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 07924f4e6..e5f792929 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -261,14 +261,6 @@ sub GetHtmlLine($$$)
return $Html;
}
-my @MILogFiles = qw(exe32.report exe64.report log log.old);
-my %MILogLabels = (
- "exe32.report" => "32 bit Windows report",
- "exe64.report" => "64 bit Windows report",
- "log" => "task log",
- "log.old" => "old logs",
-);
-
sub InitMoreInfo($)
{
my ($self) = @_;
@@ -282,15 +274,15 @@ sub InitMoreInfo($)
my $Value = $self->GetParam("f$Key");
my $TaskDir = $StepTask->GetTaskDir();
- foreach my $Log (@MILogFiles)
+ foreach my $Log (@{GetLogFileNames($TaskDir, 1)})
{
- if (!-f "$TaskDir/$Log" or -z "$TaskDir/$Log")
+ if ($Log =~ s/^err/log/)
{
- my $Err = $Log;
- next if ($Err !~ s/^log/err/ or !-f "$TaskDir/$Err" or -z "$TaskDir/$Err");
+ # We don't want separate entries for log* and err* but we also want a
+ # log* entry even if only err* exists.
+ next if (($More->{$Key}->{Logs}->[-1] || "") eq $Log);
}
push @{$More->{$Key}->{Logs}}, $Log;
-
$More->{$Key}->{Full} = $Log if (uri_escape($Log) eq $Value);
}
$More->{$Key}->{Full} ||= "";
@@ -385,7 +377,7 @@ sub GenerateBody($)
foreach my $Log (@{$MoreInfo->{Logs}})
{
- $self->GenerateMoreInfoLink($Key, $MILogLabels{$Log}, "Full", $Log);
+ $self->GenerateMoreInfoLink($Key, GetLogLabel($Log), "Full", $Log);
}
print "</div>\n";
--
2.18.0
June 26, 2018
[PATCH 1/7] testbot: Move log line categorization to LogUtils and simplify line highlighting.
by Francois Gouget
GetLogLineCategory() identifies log lines of interest which makes it
possible to decide how to display them.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
This makes it reusable in WineSendLog.pl.
testbot/lib/WineTestBot/LogUtils.pm | 61 +++++++++++++++++++++-
testbot/web/JobDetails.pl | 78 +++++++++++------------------
2 files changed, 88 insertions(+), 51 deletions(-)
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index 3e40fbc35..daa9c0bd8 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -27,7 +27,7 @@ WineTestBot::LogUtils - Provides functions to parse task logs
use Exporter 'import';
-our @EXPORT = qw(ParseTaskLog);
+our @EXPORT = qw(GetLogLineCategory ParseTaskLog);
#
@@ -74,4 +74,63 @@ sub ParseTaskLog($$)
return "nolog:Unable to open the task log for reading: $!";
}
+
+#
+# Log querying and formatting
+#
+
+=pod
+=over 12
+
+=item C<GetLogLineCategory()>
+
+Identifies the category of the given log line: an error message, a todo, just
+an informational message or none of these. The category can then be used to
+decide whether to hide the line or, on the contrary, highlight it.
+
+=back
+=cut
+
+sub GetLogLineCategory($)
+{
+ my ($Line) = @_;
+
+ if ($Line =~ /: Test marked todo: /)
+ {
+ return "todo";
+ }
+ if ($Line =~ /: Tests skipped: / or
+ $Line =~ /^\w+:\w+ skipped /)
+ {
+ return "skip";
+ }
+ if ($Line =~ /: Test (?:failed|succeeded inside todo block): / or
+ $Line =~ /Fatal: test .* does not exist/ or
+ $Line =~ / done \(258\)/ or
+ $Line =~ /: unhandled exception [0-9a-fA-F]{8} at / or
+ $Line =~ /^Unhandled exception: / or
+ # Git errors
+ $Line =~ /^CONFLICT / or
+ $Line =~ /^error: patch failed:/ or
+ $Line =~ /^error: corrupt patch / or
+ # Build errors
+ $Line =~ /: error: / or
+ $Line =~ /^Makefile:[0-9]+: recipe for target .* failed$/ or
+ $Line =~ /^(?:Build|Reconfig|Task): (?!ok)/ or
+ # Typical perl errors
+ $Line =~ /^Use of uninitialized value/)
+ {
+ return "error";
+ }
+ if ($Line =~ /^\+ \S/ or
+ $Line =~ /^\w+:\w+ start / or
+ # Build messages
+ $Line =~ /^(?:Build|Reconfig|Task): ok/)
+ {
+ return "info";
+ }
+
+ return "none";
+}
+
1;
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index f05c0f62e..07924f4e6 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -28,6 +28,7 @@ use URI::Escape;
use WineTestBot::Config;
use WineTestBot::Jobs;
+use WineTestBot::LogUtils;
use WineTestBot::StepsTasks;
use WineTestBot::Engine::Notify;
@@ -228,59 +229,36 @@ sub GeneratePage($)
$self->SUPER::GeneratePage();
}
+=pod
+=over 12
+
+=item C<GetHtmlLine()>
+
+Determines if the log line should be shown, how, and escapes it so it is valid
+HTML.
+
+When not showing the full log, returns undef except for error messages which
+are the only lines tha should be shown.
+When showing the full log error messages and other lines of interest are
+highlighted to make the log more readable.
+
+=back
+=cut
+
sub GetHtmlLine($$$)
{
my ($self, $FullLog, $Line) = @_;
- $Line = $self->escapeHTML($Line);
- if ($Line =~ /: Test marked todo: /)
- {
- return (undef, $Line) if (!$FullLog);
- my $Html = $Line;
- $Html =~ s~^(.*\S)\s*\r?$~<span class='log-todo'>$1</span>~;
- return ($Html, $Line);
- }
- if ($Line =~ /: Tests skipped: / or
- $Line =~ /^\w+:\w+ skipped /)
- {
- return (undef, $Line) if (!$FullLog);
- my $Html = $Line;
- $Html =~ s~^(.*\S)\s*\r?$~<span class='log-skip'>$1</span>~;
- return ($Html, $Line);
- }
- if ($Line =~ /: Test (?:failed|succeeded inside todo block): / or
- $Line =~ /Fatal: test .* does not exist/ or
- $Line =~ / done \(258\)/ or
- $Line =~ /: unhandled exception [0-9a-fA-F]{8} at / or
- $Line =~ /^Unhandled exception: / or
- # Git errors
- $Line =~ /^CONFLICT / or
- $Line =~ /^error: patch failed:/ or
- $Line =~ /^error: corrupt patch / or
- # Build errors
- $Line =~ /: error: / or
- $Line =~ /^Makefile:[0-9]+: recipe for target .* failed$/ or
- $Line =~ /^(?:Build|Reconfig|Task): (?!ok)/ or
- # Typical perl errors
- $Line =~ /^Use of uninitialized value/)
- {
- return ($Line, $Line) if (!$FullLog);
- my $Html = $Line;
- $Html =~ s~^(.*\S)\s*\r?$~<span class='log-error'>$1</span>~;
- return ($Html, $Line);
- }
- if ($FullLog &&
- ($Line =~ /^\+ \S/ or
- $Line =~ /^\w+:\w+ start / or
- # Build messages
- $Line =~ /^(?:Build|Reconfig|Task): ok/))
+ my $Category = GetLogLineCategory($Line);
+ return undef if ($Category ne "error" and !$FullLog);
+
+ my $Html = $self->escapeHTML($Line);
+ if ($FullLog and $Category ne "none")
{
- my $Html = $Line;
- $Html =~ s~^(.*\S)\s*\r?$~<span class='log-info'>$1</span>~;
- return ($Html, $Line);
+ # Highlight all line categories in the full log
+ $Html =~ s~^(.*\S)\s*\r?$~<span class='log-$Category'>$1</span>~;
}
-
- return (undef, $Line);
+ return $Html;
}
my @MILogFiles = qw(exe32.report exe64.report log log.old);
@@ -429,8 +407,8 @@ sub GenerateBody($)
{
$CurrentDll = $1;
}
- my ($Highlight, $Plain) = $self->GetHtmlLine($MoreInfo->{Full}, $Line);
- next if (!$MoreInfo->{Full} and !defined $Highlight);
+ my $Html = $self->GetHtmlLine($MoreInfo->{Full}, $Line);
+ next if (!defined $Html);
if ($PrintedDll ne $CurrentDll && !$MoreInfo->{Full})
{
@@ -451,7 +429,7 @@ sub GenerateBody($)
}
else
{
- print(($Highlight || $Plain), "\n");
+ print "$Html\n";
}
}
close($LogFile);
--
2.18.0
June 26, 2018
Re: [PATCH 2/2] msvcp120: Add test for Concurrent_vector_grow_to_at_least_with_result.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
June 26, 2018
Re: [PATCH 1/2] msvcp120: Add test for Concurrent_vector_grow_by.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
June 26, 2018
[PATCH 2/2] msvcp120: Add test for Concurrent_vector_grow_to_at_least_with_result.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp120/tests/msvcp120.c | 46 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c
index b5e470cba3..2974482ec1 100644
--- a/dlls/msvcp120/tests/msvcp120.c
+++ b/dlls/msvcp120/tests/msvcp120.c
@@ -420,6 +420,8 @@ static void* (__thiscall *p_vector_base_v4__Internal_compact)(
void (__cdecl*)(void*, const void*, size_t));
static size_t (__thiscall *p_vector_base_v4__Internal_grow_by)(
vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
+static size_t (__thiscall *p_vector_base_v4__Internal_grow_to_at_least_with_result)(
+ vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
static HMODULE msvcp;
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
@@ -572,6 +574,8 @@ static BOOL init(void)
"?_Internal_compact(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAPEAX_KPEAXP6AX10(a)ZP6AX1PEBX0@Z(a)Z");
SET(p_vector_base_v4__Internal_grow_by,
"?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAA_K_K0P6AXPEAXPEBX0(a)Z2@Z");
+ SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
+ "?_Internal_grow_to_at_least_with_result(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAA_K_K0P6AXPEAXPEBX0(a)Z2@Z");
} else {
SET(p_tr2_sys__File_size,
"?_File_size(a)sys@tr2(a)std@@YA_KPBD(a)Z");
@@ -693,6 +697,8 @@ static BOOL init(void)
"?_Internal_compact(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEPAXIPAXP6AX0I(a)ZP6AX0PBXI@Z(a)Z");
SET(p_vector_base_v4__Internal_grow_by,
"?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEIIIP6AXPAXPBXI(a)Z1@Z");
+ SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
+ "?_Internal_grow_to_at_least_with_result(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEIIIP6AXPAXPBXI(a)Z1@Z");
#else
SET(p__Thrd_current,
"_Thrd_current");
@@ -742,6 +748,8 @@ static BOOL init(void)
"?_Internal_compact(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAAPAXIPAXP6AX0I(a)ZP6AX0PBXI@Z(a)Z");
SET(p_vector_base_v4__Internal_grow_by,
"?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAAIIIP6AXPAXPBXI(a)Z1@Z");
+ SET(p_vector_base_v4__Internal_grow_to_at_least_with_result,
+ "?_Internal_grow_to_at_least_with_result(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAAIIIP6AXPAXPBXI(a)Z1@Z");
#endif
}
SET(p__Thrd_equal,
@@ -3036,6 +3044,44 @@ static void test_vector_base_v4(void)
CHECK_CALLED(concurrent_vector_int_destroy);
concurrent_vector_int_dtor(&v2);
+ /* test for Internal_grow_to_at_least_with_result */
+ concurrent_vector_int_ctor(&v2);
+ SET_EXPECT(concurrent_vector_int_alloc);
+ data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ ok(data != NULL, "_Internal_push_back returned NULL\n");
+ data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
+ ok(data != NULL, "_Internal_push_back returned NULL\n");
+ vector_elem_count += 2;
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
+ i = 0;
+ SET_EXPECT(concurrent_vector_int_alloc);
+ SET_EXPECT(concurrent_vector_int_copy);
+ idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_to_at_least_with_result,
+ &v2, 3, sizeof(int), concurrent_vector_int_copy, &i);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ CHECK_CALLED(concurrent_vector_int_copy);
+ ok(idx == 2, "_Internal_grow_to_at_least_with_result returned %ld expected 2\n", (long)idx);
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
+ i = 0;
+ SET_EXPECT(concurrent_vector_int_alloc);
+ SET_EXPECT(concurrent_vector_int_copy);
+ idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_to_at_least_with_result,
+ &v2, 5, sizeof(int), concurrent_vector_int_copy, &i);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ CHECK_CALLED(concurrent_vector_int_copy);
+ ok(idx == 3, "_Internal_grow_to_at_least_with_result returned %ld expected 3\n", (long)idx);
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n", (long)v2.early_size);
+ SET_EXPECT(concurrent_vector_int_destroy);
+ size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
+ &v2, concurrent_vector_int_destroy);
+ ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
+ CHECK_CALLED(concurrent_vector_int_destroy);
+ concurrent_vector_int_dtor(&v2);
+
SET_EXPECT(concurrent_vector_int_destroy);
size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
&vector, concurrent_vector_int_destroy);
--
2.11.0
June 26, 2018
[PATCH 1/2] msvcp120: Add test for Concurrent_vector_grow_by.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp120/tests/msvcp120.c | 46 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 45 insertions(+), 1 deletion(-)
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c
index 0ec9fbd3b1..b5e470cba3 100644
--- a/dlls/msvcp120/tests/msvcp120.c
+++ b/dlls/msvcp120/tests/msvcp120.c
@@ -418,6 +418,8 @@ static void (__thiscall *p_vector_base_v4__Internal_swap)(
static void* (__thiscall *p_vector_base_v4__Internal_compact)(
vector_base_v4*, size_t, void*, void (__cdecl*)(void*, size_t),
void (__cdecl*)(void*, const void*, size_t));
+static size_t (__thiscall *p_vector_base_v4__Internal_grow_by)(
+ vector_base_v4*, size_t, size_t, void (__cdecl*)(void*, const void*, size_t), const void *);
static HMODULE msvcp;
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
@@ -568,6 +570,8 @@ static BOOL init(void)
"?_Internal_swap(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAXAEAV123@@Z");
SET(p_vector_base_v4__Internal_compact,
"?_Internal_compact(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAPEAX_KPEAXP6AX10(a)ZP6AX1PEBX0@Z(a)Z");
+ SET(p_vector_base_v4__Internal_grow_by,
+ "?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAA_K_K0P6AXPEAXPEBX0(a)Z2@Z");
} else {
SET(p_tr2_sys__File_size,
"?_File_size(a)sys@tr2(a)std@@YA_KPBD(a)Z");
@@ -687,6 +691,8 @@ static BOOL init(void)
"?_Internal_swap(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEXAAV123@@Z");
SET(p_vector_base_v4__Internal_compact,
"?_Internal_compact(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEPAXIPAXP6AX0I(a)ZP6AX0PBXI@Z(a)Z");
+ SET(p_vector_base_v4__Internal_grow_by,
+ "?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEIIIP6AXPAXPBXI(a)Z1@Z");
#else
SET(p__Thrd_current,
"_Thrd_current");
@@ -734,7 +740,8 @@ static BOOL init(void)
"?_Internal_swap(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAAXAAV123@@Z");
SET(p_vector_base_v4__Internal_compact,
"?_Internal_compact(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAAPAXIPAXP6AX0I(a)ZP6AX0PBXI@Z(a)Z");
-
+ SET(p_vector_base_v4__Internal_grow_by,
+ "?_Internal_grow_by(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAAIIIP6AXPAXPBXI(a)Z1@Z");
#endif
}
SET(p__Thrd_equal,
@@ -2992,6 +2999,43 @@ static void test_vector_base_v4(void)
CHECK_CALLED(concurrent_vector_int_destroy);
concurrent_vector_int_dtor(&v2);
+ /* test for Internal_grow_by */
+ concurrent_vector_int_ctor(&v2);
+ SET_EXPECT(concurrent_vector_int_alloc);
+ data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ ok(data != NULL, "_Internal_push_back returned NULL\n");
+ data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
+ ok(data != NULL, "_Internal_push_back returned NULL\n");
+ vector_elem_count += 2;
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 2, "v2.early_size got %ld expected 2\n", (long)v2.early_size);
+ i = 0;
+ SET_EXPECT(concurrent_vector_int_alloc);
+ SET_EXPECT(concurrent_vector_int_copy);
+ idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_by,
+ &v2, 1, sizeof(int), concurrent_vector_int_copy, &i);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ CHECK_CALLED(concurrent_vector_int_copy);
+ ok(idx == 2, "_Internal_grow_by returned %ld expected 2\n", (long)idx);
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 3, "v2.early_size got %ld expected 3\n", (long)v2.early_size);
+ SET_EXPECT(concurrent_vector_int_alloc);
+ SET_EXPECT(concurrent_vector_int_copy);
+ idx = (size_t)call_func5(p_vector_base_v4__Internal_grow_by,
+ &v2, 2, sizeof(int), concurrent_vector_int_copy, &i);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ CHECK_CALLED(concurrent_vector_int_copy);
+ ok(idx == 3, "_Internal_grow_by returned %ld expected 3\n", (long)idx);
+ ok(v2.first_block == 1, "v2.first_block got %ld expected 1\n", (long)v2.first_block);
+ ok(v2.early_size == 5, "v2.early_size got %ld expected 5\n", (long)v2.early_size);
+ SET_EXPECT(concurrent_vector_int_destroy);
+ size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
+ &v2, concurrent_vector_int_destroy);
+ ok(size == 3, "_Internal_clear returned %ld expected 3\n", (long)size);
+ CHECK_CALLED(concurrent_vector_int_destroy);
+ concurrent_vector_int_dtor(&v2);
+
SET_EXPECT(concurrent_vector_int_destroy);
size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
&vector, concurrent_vector_int_destroy);
--
2.11.0
June 26, 2018
Re: [PATCH] gdi32/tests: Use the available ARRAY_SIZE() macro
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 26, 2018
[PATCH 2/2] testbot/Janitor: Clean up the latest directory too.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/Janitor.pl | 46 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/testbot/bin/Janitor.pl b/testbot/bin/Janitor.pl
index 9252efa65..a9cdd52cd 100755
--- a/testbot/bin/Janitor.pl
+++ b/testbot/bin/Janitor.pl
@@ -299,6 +299,52 @@ else
Error "Unable to open '$DataDir/staging': $!";
}
+# Check the content of the latest directory
+if (opendir(my $dh, "$DataDir/latest"))
+{
+ # We will be deleting files so read the directory in one go
+ my @Entries = readdir($dh);
+ close($dh);
+
+ my $AllVMs = $VMs->Clone();
+ foreach my $Entry (@Entries)
+ {
+ next if ($Entry eq "." or $Entry eq "..");
+ $Entry =~ m%^([^/]+)$%;
+ my $FileName = "$DataDir/latest/$1";
+ my $Age = int((-M $FileName) + 0.5);
+
+ if ($Entry =~ /^(.*)_[a-z0-9]+\.(?:err|log)$/)
+ {
+ # Keep the reference WineTest reports for all VMs even if they are
+ # retired or scheduled for deletion.
+ my $VMName = $1;
+ next if ($AllVMs->GetItem($VMName));
+ }
+ elsif ($Entry =~ /^(?:TestLauncher[0-9]*\.exe|winefiles.txt|winetest[0-9]*-latest\.exe)$/)
+ {
+ next;
+ }
+
+ Trace "Found a suspicious latest file: $Entry\n";
+ if ($JobPurgeDays != 0)
+ {
+ if ($Age >= $JobPurgeDays + 7)
+ {
+ DeletePath($FileName);
+ }
+ elsif ($Age > $JobPurgeDays)
+ {
+ Trace "'$FileName' will be deleted in ", $JobPurgeDays + 7 - $Age, " day(s).\n";
+ }
+ }
+ }
+}
+else
+{
+ Error "Unable to open '$DataDir/latest': $!";
+}
+
# Delete obsolete record groups
if ($JobPurgeDays != 0)
{
--
2.18.0
June 26, 2018
[PATCH 1/2] testbot/Janitor: Add DeletePath() to simplify deleting file/directories.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/Janitor.pl | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/testbot/bin/Janitor.pl b/testbot/bin/Janitor.pl
index 9fb38efde..9252efa65 100755
--- a/testbot/bin/Janitor.pl
+++ b/testbot/bin/Janitor.pl
@@ -116,6 +116,17 @@ if (defined $Usage)
# Main
#
+sub DeletePath($)
+{
+ my ($Path) = @_;
+
+ Trace "Deleting '$Path'\n";
+ if (!$DryRun and !rmtree($Path))
+ {
+ Error "Could not delete '$Path': $!\n";
+ }
+}
+
# Delete obsolete Jobs
if ($JobPurgeDays != 0)
{
@@ -268,11 +279,7 @@ if (opendir(my $dh, "$DataDir/staging"))
{
if ($Age >= $JobPurgeDays + 7)
{
- Trace "Deleting '$FileName'\n";
- if (!$DryRun and !rmtree($FileName))
- {
- Error "Could not delete '$FileName': $!\n";
- }
+ DeletePath($FileName);
}
elsif ($Age > $JobPurgeDays)
{
@@ -282,12 +289,8 @@ if (opendir(my $dh, "$DataDir/staging"))
}
elsif ($Age >= 1)
{
- Trace "Deleting '$FileName'\n";
- if (!$DryRun and !unlink $FileName)
- {
- # The user abandoned the submit procedure half-way through
- Error "Could not delete '$FileName': $!\n";
- }
+ # The user abandoned the submit procedure half-way through
+ DeletePath($FileName);
}
}
}
--
2.18.0
June 26, 2018
[PATCH 2/2] crypt32: Fix string arguments tracing.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/base64.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/crypt32/base64.c b/dlls/crypt32/base64.c
index 4a904d41cc..2ba8055961 100644
--- a/dlls/crypt32/base64.c
+++ b/dlls/crypt32/base64.c
@@ -622,7 +622,7 @@ static LONG Base64WithHeaderAndTrailerToBinaryA(LPCSTR pszString,
if (!(headerBegins = strstr(pszString, header)))
{
- TRACE("Can't find %s in %s.\n", header, pszString);
+ TRACE("Can't find %s in %s.\n", header, debugstr_an(pszString, cchString));
return ERROR_INVALID_DATA;
}
@@ -746,7 +746,7 @@ BOOL WINAPI CryptStringToBinaryA(LPCSTR pszString,
StringToBinaryAFunc decoder;
LONG ret;
- TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_a(pszString),
+ TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_an(pszString, cchString ? cchString : -1),
cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags);
if (!pszString)
@@ -833,7 +833,7 @@ static LONG Base64WithHeaderAndTrailerToBinaryW(LPCWSTR pszString,
if (!(headerBegins = strstrW(pszString, header)))
{
- TRACE("Can't find %s in %s.\n", debugstr_w(header), debugstr_w(pszString));
+ TRACE("Can't find %s in %s.\n", debugstr_w(header), debugstr_wn(pszString, cchString));
return ERROR_INVALID_DATA;
}
@@ -957,7 +957,7 @@ BOOL WINAPI CryptStringToBinaryW(LPCWSTR pszString,
StringToBinaryWFunc decoder;
LONG ret;
- TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_w(pszString),
+ TRACE("(%s, %d, %08x, %p, %p, %p, %p)\n", debugstr_wn(pszString, cchString ? cchString : -1),
cchString, dwFlags, pbBinary, pcbBinary, pdwSkip, pdwFlags);
if (!pszString)
--
2.18.0
June 26, 2018
[PATCH 1/2] crypt32: Implement verification of ECDSA signatures.
by Nikolay Sivov
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
Modifications from original patch:
- few renames to make it closer to existing code;
- removed unrelated formatting changes in existing code;
- new BCrypt path is rearranged to match existing order : import -> hash -> verify.
dlls/crypt32/Makefile.in | 2 +-
dlls/crypt32/cert.c | 260 +++++++++++++++++++++++++++++++++++++--
2 files changed, 250 insertions(+), 12 deletions(-)
diff --git a/dlls/crypt32/Makefile.in b/dlls/crypt32/Makefile.in
index d3a409fcae..0934222119 100644
--- a/dlls/crypt32/Makefile.in
+++ b/dlls/crypt32/Makefile.in
@@ -1,7 +1,7 @@
EXTRADEFS = -D_CRYPT32_
MODULE = crypt32.dll
IMPORTLIB = crypt32
-IMPORTS = user32 advapi32
+IMPORTS = user32 advapi32 bcrypt
DELAYIMPORTS = cryptnet
EXTRALIBS = $(SECURITY_LIBS)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index 83aac5d8f4..1667b42b0b 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -21,9 +21,14 @@
#include <stdarg.h>
#define NONAMELESSUNION
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
#include "windef.h"
#include "winbase.h"
+#include "winternl.h"
+#define CRYPT_OID_INFO_HAS_EXTRA_FIELDS
#include "wincrypt.h"
+#include "bcrypt.h"
#include "winnls.h"
#include "rpc.h"
#include "wine/debug.h"
@@ -2408,22 +2413,13 @@ BOOL WINAPI CryptVerifyCertificateSignature(HCRYPTPROV_LEGACY hCryptProv,
CRYPT_VERIFY_CERT_SIGN_ISSUER_PUBKEY, pPublicKey, 0, NULL);
}
-static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv,
- DWORD dwCertEncodingType, PCERT_PUBLIC_KEY_INFO pubKeyInfo,
- const CERT_SIGNED_CONTENT_INFO *signedCert)
+static BOOL CRYPT_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType,
+ CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info)
{
BOOL ret;
HCRYPTKEY key;
- PCCRYPT_OID_INFO info;
ALG_ID pubKeyID, hashID;
- info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
- signedCert->SignatureAlgorithm.pszObjId, 0);
- if (!info || info->dwGroupId != CRYPT_SIGN_ALG_OID_GROUP_ID)
- {
- SetLastError(NTE_BAD_ALGID);
- return FALSE;
- }
hashID = info->u.Algid;
if (info->ExtraInfo.cbData >= sizeof(ALG_ID))
pubKeyID = *(ALG_ID *)info->ExtraInfo.pbData;
@@ -2453,6 +2449,248 @@ static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptP
return ret;
}
+static BOOL CNG_CalcHash(const WCHAR *algorithm, const CERT_SIGNED_CONTENT_INFO *signedCert,
+ BYTE **hash_value, DWORD *hash_len)
+{
+ BCRYPT_HASH_HANDLE hash = NULL;
+ BCRYPT_ALG_HANDLE alg = NULL;
+ NTSTATUS status;
+ DWORD size;
+
+ if ((status = BCryptOpenAlgorithmProvider(&alg, algorithm, NULL, 0)))
+ goto done;
+
+ if ((status = BCryptCreateHash(alg, &hash, NULL, 0, NULL, 0, 0)))
+ goto done;
+
+ if ((status = BCryptHashData(hash, signedCert->ToBeSigned.pbData, signedCert->ToBeSigned.cbData, 0)))
+ goto done;
+
+ if ((status = BCryptGetProperty(hash, BCRYPT_HASH_LENGTH, (BYTE *)hash_len, sizeof(*hash_len), &size, 0)))
+ goto done;
+
+ if (!(*hash_value = CryptMemAlloc(*hash_len)))
+ {
+ status = STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ if ((status = BCryptFinishHash(hash, *hash_value, *hash_len, 0)))
+ {
+ CryptMemFree(*hash_value);
+ goto done;
+ }
+
+done:
+ if (hash) BCryptDestroyHash(hash);
+ if (alg) BCryptCloseAlgorithmProvider(alg, 0);
+ if (status) SetLastError(RtlNtStatusToDosError(status));
+ return status == 0;
+}
+
+static BOOL CNG_ImportECCPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key)
+{
+ DWORD blob_magic, ecckey_len, size;
+ BCRYPT_ALG_HANDLE alg = NULL;
+ BCRYPT_ECCKEY_BLOB *ecckey;
+ const WCHAR *sign_algo;
+ char **ecc_curve;
+ NTSTATUS status;
+
+ if (!pubKeyInfo->PublicKey.cbData)
+ {
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if (pubKeyInfo->PublicKey.pbData[0] != 0x4)
+ {
+ FIXME("Compressed ECC curves (%02x) not yet supported\n", pubKeyInfo->PublicKey.pbData[0]);
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_OBJECT_IDENTIFIER, pubKeyInfo->Algorithm.Parameters.pbData,
+ pubKeyInfo->Algorithm.Parameters.cbData, CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_curve, &size))
+ return FALSE;
+
+ if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P256))
+ {
+ sign_algo = BCRYPT_ECDSA_P256_ALGORITHM;
+ blob_magic = BCRYPT_ECDSA_PUBLIC_P256_MAGIC;
+ }
+ else if (!strcmp(*ecc_curve, szOID_ECC_CURVE_P384))
+ {
+ sign_algo = BCRYPT_ECDSA_P384_ALGORITHM;
+ blob_magic = BCRYPT_ECDSA_PUBLIC_P384_MAGIC;
+ }
+ else
+ {
+ FIXME("Unsupported ecc curve type: %s\n", *ecc_curve);
+ sign_algo = NULL;
+ blob_magic = 0;
+ }
+ LocalFree(ecc_curve);
+
+ if (!sign_algo)
+ {
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if ((status = BCryptOpenAlgorithmProvider(&alg, sign_algo, NULL, 0)))
+ goto done;
+
+ ecckey_len = sizeof(BCRYPT_ECCKEY_BLOB) + pubKeyInfo->PublicKey.cbData - 1;
+ if (!(ecckey = CryptMemAlloc(ecckey_len)))
+ {
+ status = STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ ecckey->dwMagic = blob_magic;
+ ecckey->cbKey = (pubKeyInfo->PublicKey.cbData - 1) / 2;
+ memcpy(ecckey + 1, pubKeyInfo->PublicKey.pbData + 1, pubKeyInfo->PublicKey.cbData - 1);
+
+ status = BCryptImportKeyPair(alg, NULL, BCRYPT_ECCPUBLIC_BLOB, key, (BYTE*)ecckey, ecckey_len, 0);
+
+done:
+ if (alg) BCryptCloseAlgorithmProvider(alg, 0);
+ if (status) SetLastError(RtlNtStatusToDosError(status));
+ return !status;
+}
+
+static BOOL CNG_ImportPubKey(CERT_PUBLIC_KEY_INFO *pubKeyInfo, BCRYPT_KEY_HANDLE *key)
+{
+ if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY))
+ return CNG_ImportECCPubKey(pubKeyInfo, key);
+
+ FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId));
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+}
+
+static BOOL CNG_PrepareSignatureECC(BYTE *encoded_sig, DWORD encoded_size, BYTE **sig_value, DWORD *sig_len)
+{
+ CERT_ECC_SIGNATURE *ecc_sig;
+ DWORD size;
+ int i;
+
+ if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_ECC_SIGNATURE, encoded_sig, encoded_size,
+ CRYPT_DECODE_ALLOC_FLAG, NULL, &ecc_sig, &size))
+ return FALSE;
+
+ if (!ecc_sig->r.cbData || !ecc_sig->s.cbData)
+ {
+ LocalFree(ecc_sig);
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+
+ *sig_len = ecc_sig->r.cbData + ecc_sig->s.cbData;
+ if (!(*sig_value = CryptMemAlloc(*sig_len)))
+ {
+ LocalFree(ecc_sig);
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ for (i = 0; i < ecc_sig->r.cbData; i++)
+ (*sig_value)[i] = ecc_sig->r.pbData[ecc_sig->r.cbData - i - 1];
+ for (i = 0; i < ecc_sig->s.cbData; i++)
+ (*sig_value)[ecc_sig->r.cbData + i] = ecc_sig->s.pbData[ecc_sig->s.cbData - i - 1];
+
+ LocalFree(ecc_sig);
+ return TRUE;
+}
+
+static BOOL CNG_PrepareSignature(CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert,
+ BYTE **sig_value, DWORD *sig_len)
+{
+ BYTE *encoded_sig;
+ BOOL ret = FALSE;
+ int i;
+
+ if (!signedCert->Signature.cbData)
+ {
+ SetLastError(ERROR_INVALID_DATA);
+ return FALSE;
+ }
+
+ if (!(encoded_sig = CryptMemAlloc(signedCert->Signature.cbData)))
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
+ }
+
+ for (i = 0; i < signedCert->Signature.cbData; i++)
+ encoded_sig[i] = signedCert->Signature.pbData[signedCert->Signature.cbData - i - 1];
+
+ if (!strcmp(pubKeyInfo->Algorithm.pszObjId, szOID_ECC_PUBLIC_KEY))
+ ret = CNG_PrepareSignatureECC(encoded_sig, signedCert->Signature.cbData, sig_value, sig_len);
+ else
+ {
+ FIXME("Unsupported public key type: %s\n", debugstr_a(pubKeyInfo->Algorithm.pszObjId));
+ SetLastError(NTE_BAD_ALGID);
+ }
+
+ CryptMemFree(encoded_sig);
+ return ret;
+}
+
+static BOOL CNG_VerifySignature(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType,
+ CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert, const CRYPT_OID_INFO *info)
+{
+ BCRYPT_KEY_HANDLE key = NULL;
+ BYTE *hash_value = NULL, *sig_value;
+ DWORD hash_len, sig_len;
+ NTSTATUS status;
+ BOOL ret;
+
+ ret = CNG_ImportPubKey(pubKeyInfo, &key);
+ if (ret)
+ {
+ ret = CNG_CalcHash(info->pwszCNGAlgid, signedCert, &hash_value, &hash_len);
+ if (ret)
+ {
+ ret = CNG_PrepareSignature(pubKeyInfo, signedCert, &sig_value, &sig_len);
+ if (ret)
+ {
+ status = BCryptVerifySignature(key, NULL, hash_value, hash_len, sig_value, sig_len, 0);
+ if (status)
+ {
+ FIXME("Failed to verify signature: %08x\n", status);
+ SetLastError(RtlNtStatusToDosError(status));
+ ret = FALSE;
+ }
+ CryptMemFree(sig_value);
+ }
+ CryptMemFree(hash_value);
+ }
+ BCryptDestroyKey(key);
+ }
+
+ return ret;
+}
+
+static BOOL CRYPT_VerifyCertSignatureFromPublicKeyInfo(HCRYPTPROV_LEGACY hCryptProv, DWORD dwCertEncodingType,
+ CERT_PUBLIC_KEY_INFO *pubKeyInfo, const CERT_SIGNED_CONTENT_INFO *signedCert)
+{
+ CCRYPT_OID_INFO *info;
+
+ info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, signedCert->SignatureAlgorithm.pszObjId, 0);
+ if (!info || info->dwGroupId != CRYPT_SIGN_ALG_OID_GROUP_ID)
+ {
+ SetLastError(NTE_BAD_ALGID);
+ return FALSE;
+ }
+
+ if (info->u.Algid == CALG_OID_INFO_CNG_ONLY)
+ return CNG_VerifySignature(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info);
+ else
+ return CRYPT_VerifySignature(hCryptProv, dwCertEncodingType, pubKeyInfo, signedCert, info);
+}
+
BOOL WINAPI CryptVerifyCertificateSignatureEx(HCRYPTPROV_LEGACY hCryptProv,
DWORD dwCertEncodingType, DWORD dwSubjectType, void *pvSubject,
DWORD dwIssuerType, void *pvIssuer, DWORD dwFlags, void *pvReserved)
--
2.18.0
June 26, 2018
[PATCH] msi: Remove checks for negative value.
by Hans Leidekker
From: Andrey Gusev <andrey.goosev(a)gmail.com>
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/msi/format.c | 2 +-
dlls/msi/string.c | 5 ++---
dlls/msi/table.c | 4 +---
3 files changed, 4 insertions(+), 7 deletions(-)
diff --git a/dlls/msi/format.c b/dlls/msi/format.c
index 9356c9e30d..d32afb2a60 100644
--- a/dlls/msi/format.c
+++ b/dlls/msi/format.c
@@ -242,7 +242,7 @@ static WCHAR *deformat_file( FORMAT *format, FORMSTR *str, BOOL shortname, int *
if ((ret = strdupW( file->TargetPath ))) len = strlenW( ret );
goto done;
}
- if ((len = GetShortPathNameW(file->TargetPath, NULL, 0)) <= 0)
+ if (!(len = GetShortPathNameW(file->TargetPath, NULL, 0)))
{
if ((ret = strdupW( file->TargetPath ))) len = strlenW( ret );
goto done;
diff --git a/dlls/msi/string.c b/dlls/msi/string.c
index f094a53c9e..7383fddbed 100644
--- a/dlls/msi/string.c
+++ b/dlls/msi/string.c
@@ -233,7 +233,7 @@ static void set_st_entry( string_table *st, UINT n, WCHAR *str, int len, USHORT
static UINT string2id( const string_table *st, const char *buffer, UINT *id )
{
- DWORD sz;
+ int sz;
UINT r = ERROR_INVALID_PARAMETER;
LPWSTR str;
@@ -245,8 +245,7 @@ static UINT string2id( const string_table *st, const char *buffer, UINT *id )
return ERROR_SUCCESS;
}
- sz = MultiByteToWideChar( st->codepage, 0, buffer, -1, NULL, 0 );
- if( sz <= 0 )
+ if (!(sz = MultiByteToWideChar( st->codepage, 0, buffer, -1, NULL, 0 )))
return r;
str = msi_alloc( sz*sizeof(WCHAR) );
if( !str )
diff --git a/dlls/msi/table.c b/dlls/msi/table.c
index 45a181445a..e046c5c9e2 100644
--- a/dlls/msi/table.c
+++ b/dlls/msi/table.c
@@ -1279,9 +1279,7 @@ static UINT get_table_value_from_record( MSITABLEVIEW *tv, MSIRECORD *rec, UINT
UINT r;
int ival;
- if ( (iField <= 0) ||
- (iField > tv->num_cols) ||
- MSI_RecordIsNull( rec, iField ) )
+ if (!iField || iField > tv->num_cols || MSI_RecordIsNull( rec, iField ))
return ERROR_FUNCTION_FAILED;
columninfo = tv->columns[ iField - 1 ];
--
2.11.0
June 26, 2018
[PATCH] shell32: use characters as arguments to GetTempPathW and GetLongPathNameW
by Marcus Meissner
Signed-off-by: Marcus Meissner <marcus(a)jet.franken.de>
---
dlls/shell32/tests/shlfolder.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/tests/shlfolder.c b/dlls/shell32/tests/shlfolder.c
index 6460fd9381..bb303f66e4 100644
--- a/dlls/shell32/tests/shlfolder.c
+++ b/dlls/shell32/tests/shlfolder.c
@@ -244,8 +244,8 @@ todo_wine_if(parse_tests[i].todo)
CoTaskMemFree(pidl);
/* Relative paths are interpreted relative to the desktop. */
- GetTempPathW(sizeof(buffer), buffer);
- GetLongPathNameW(buffer, buffer, sizeof(buffer));
+ GetTempPathW(ARRAY_SIZE(buffer), buffer);
+ GetLongPathNameW(buffer, buffer, ARRAY_SIZE(buffer));
SetCurrentDirectoryW(buffer);
CreateDirectoryW(testdirW, NULL);
--
2.17.1
June 26, 2018
Re: [PATCH 5/5] include: Make fil_data.idl a common header.
by Marvin
Hi,
While running your changed tests on Windows, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at
https://testbot.winehq.org/JobDetails.pl?Key=39362
Your paranoid android.
=== w2008s64 (64 bit referenceclock) ===
TestBot process got stuck or died unexpectedly
The previous 1 run(s) terminated abnormally
June 26, 2018
[PATCH 5/5] include: Make fil_data.idl a common header.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/Makefile.in | 3 +-
dlls/devenum/createdevenum.c | 2 +-
dlls/devenum/fil_data.idl | 47 --------------------------
dlls/dxdiagn/Makefile.in | 3 +-
dlls/dxdiagn/provider.c | 2 +-
dlls/quartz/Makefile.in | 1 -
dlls/quartz/fil_data.idl | 52 -----------------------------
dlls/quartz/filtermapper.c | 2 +-
dlls/quartz/tests/Makefile.in | 1 -
dlls/quartz/tests/fil_data.idl | 52 -----------------------------
dlls/quartz/tests/filtermapper.c | 2 +-
include/Makefile.in | 1 +
{dlls/dxdiagn => include/wine}/fil_data.idl | 21 ++----------
13 files changed, 10 insertions(+), 179 deletions(-)
delete mode 100644 dlls/devenum/fil_data.idl
delete mode 100644 dlls/quartz/fil_data.idl
delete mode 100644 dlls/quartz/tests/fil_data.idl
rename {dlls/dxdiagn => include/wine}/fil_data.idl (67%)
diff --git a/dlls/devenum/Makefile.in b/dlls/devenum/Makefile.in
index d1407a9..2760eed 100644
--- a/dlls/devenum/Makefile.in
+++ b/dlls/devenum/Makefile.in
@@ -9,7 +9,6 @@ C_SRCS = \
parsedisplayname.c
IDL_SRCS = \
- devenum_classes.idl \
- fil_data.idl
+ devenum_classes.idl
RC_SRCS = devenum.rc
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index 8275c99..c138cb7 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -37,7 +37,7 @@
#include "mmddk.h"
#include "initguid.h"
-#include "fil_data.h"
+#include "wine/fil_data.h"
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
diff --git a/dlls/devenum/fil_data.idl b/dlls/devenum/fil_data.idl
deleted file mode 100644
index 7e37a75..0000000
--- a/dlls/devenum/fil_data.idl
+++ /dev/null
@@ -1,47 +0,0 @@
-/*
- * Copyright (C) 2009 Vitaliy Margolen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#pragma makedep header
-
-import "objidl.idl";
-import "strmif.idl";
-import "unknwn.idl";
-
-
-/*****************************************************************************
- * IAMFilterData interface
- */
-[
- object,
- uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
- pointer_default(unique)
-]
-interface IAMFilterData : IUnknown
-{
- typedef [unique] IAMFilterData *LPIAMFILTERDATA;
-
- HRESULT ParseFilterData(
- [in] BYTE * rgbFilterData,
- [in] ULONG cb,
- [out] BYTE ** prgbRegFilter2);
-
- HRESULT CreateFilterData(
- [in] REGFILTER2 * prf2,
- [out] BYTE ** prgbFilterData,
- [out] ULONG * pcb);
-}
diff --git a/dlls/dxdiagn/Makefile.in b/dlls/dxdiagn/Makefile.in
index 3a1017e..c16396e 100644
--- a/dlls/dxdiagn/Makefile.in
+++ b/dlls/dxdiagn/Makefile.in
@@ -9,5 +9,4 @@ C_SRCS = \
RC_SRCS = dxdiagn.rc
IDL_SRCS = \
- dxdiagn.idl \
- fil_data.idl
+ dxdiagn.idl
diff --git a/dlls/dxdiagn/provider.c b/dlls/dxdiagn/provider.c
index 4f964ad..1fdab5e 100644
--- a/dlls/dxdiagn/provider.c
+++ b/dlls/dxdiagn/provider.c
@@ -35,7 +35,7 @@
#include "d3d9.h"
#include "strmif.h"
#include "initguid.h"
-#include "fil_data.h"
+#include "wine/fil_data.h"
#include "psapi.h"
#include "wbemcli.h"
diff --git a/dlls/quartz/Makefile.in b/dlls/quartz/Makefile.in
index e938865..5eb8d44 100644
--- a/dlls/quartz/Makefile.in
+++ b/dlls/quartz/Makefile.in
@@ -30,7 +30,6 @@ RC_SRCS = version.rc
IDL_SRCS = \
control_tlb.idl \
- fil_data.idl \
quartz_strmif.idl
dlldata_EXTRADEFS = -DENTRY_PREFIX=QUARTZ_ -DPROXY_DELEGATION -DWINE_REGISTER_DLL
diff --git a/dlls/quartz/fil_data.idl b/dlls/quartz/fil_data.idl
deleted file mode 100644
index ab93499..0000000
--- a/dlls/quartz/fil_data.idl
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 Vitaliy Margolen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#pragma makedep header
-
-import "objidl.idl";
-import "strmif.idl";
-import "unknwn.idl";
-
-
-/*****************************************************************************
- * IAMFilterData interface
- *
- * Notes:
- * - This interface is deprecated and IFilterMapper2 should be used instead.
- * - There is no full replacement for IAMFilterData::ParseFilterData short of manually
- * parsing out the REGFILTER2 struct from the binary blob.
- */
-[
- object,
- uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
- pointer_default(unique)
-]
-interface IAMFilterData : IUnknown
-{
- typedef [unique] IAMFilterData *LPIAMFILTERDATA;
-
- HRESULT ParseFilterData(
- [in] BYTE * rgbFilterData,
- [in] ULONG cb,
- [out] BYTE ** prgbRegFilter2);
-
- HRESULT CreateFilterData(
- [in] REGFILTER2 * prf2,
- [out] BYTE ** prgbFilterData,
- [out] ULONG * pcb);
-}
diff --git a/dlls/quartz/filtermapper.c b/dlls/quartz/filtermapper.c
index 20c7e3a..d78f643 100644
--- a/dlls/quartz/filtermapper.c
+++ b/dlls/quartz/filtermapper.c
@@ -37,7 +37,7 @@
#include "wine/unicode.h"
#include "uuids.h"
#include "initguid.h"
-#include "fil_data.h"
+#include "wine/fil_data.h"
#include "wine/debug.h"
diff --git a/dlls/quartz/tests/Makefile.in b/dlls/quartz/tests/Makefile.in
index 4f54666..6b880c3 100644
--- a/dlls/quartz/tests/Makefile.in
+++ b/dlls/quartz/tests/Makefile.in
@@ -12,7 +12,6 @@ C_SRCS = \
referenceclock.c \
videorenderer.c
-IDL_SRCS = fil_data.idl
RC_SRCS = \
rsrc.rc
diff --git a/dlls/quartz/tests/fil_data.idl b/dlls/quartz/tests/fil_data.idl
deleted file mode 100644
index ab93499..0000000
--- a/dlls/quartz/tests/fil_data.idl
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * Copyright (C) 2009 Vitaliy Margolen
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#pragma makedep header
-
-import "objidl.idl";
-import "strmif.idl";
-import "unknwn.idl";
-
-
-/*****************************************************************************
- * IAMFilterData interface
- *
- * Notes:
- * - This interface is deprecated and IFilterMapper2 should be used instead.
- * - There is no full replacement for IAMFilterData::ParseFilterData short of manually
- * parsing out the REGFILTER2 struct from the binary blob.
- */
-[
- object,
- uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
- pointer_default(unique)
-]
-interface IAMFilterData : IUnknown
-{
- typedef [unique] IAMFilterData *LPIAMFILTERDATA;
-
- HRESULT ParseFilterData(
- [in] BYTE * rgbFilterData,
- [in] ULONG cb,
- [out] BYTE ** prgbRegFilter2);
-
- HRESULT CreateFilterData(
- [in] REGFILTER2 * prf2,
- [out] BYTE ** prgbFilterData,
- [out] ULONG * pcb);
-}
diff --git a/dlls/quartz/tests/filtermapper.c b/dlls/quartz/tests/filtermapper.c
index 5a43785..7b6a018 100644
--- a/dlls/quartz/tests/filtermapper.c
+++ b/dlls/quartz/tests/filtermapper.c
@@ -26,7 +26,7 @@
#include "dshow.h"
#include "winternl.h"
-#include "fil_data.h"
+#include "wine/fil_data.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
diff --git a/include/Makefile.in b/include/Makefile.in
index 39f2691..995544a 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -664,6 +664,7 @@ SOURCES = \
windowsx.h \
wine/debug.h \
wine/exception.h \
+ wine/fil_data.idl \
wine/itss.idl \
wine/library.h \
wine/svcctl.idl \
diff --git a/dlls/dxdiagn/fil_data.idl b/include/wine/fil_data.idl
similarity index 67%
rename from dlls/dxdiagn/fil_data.idl
rename to include/wine/fil_data.idl
index 7e37a75..19dfa8a 100644
--- a/dlls/dxdiagn/fil_data.idl
+++ b/include/wine/fil_data.idl
@@ -16,16 +16,9 @@
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/
-#pragma makedep header
-
-import "objidl.idl";
-import "strmif.idl";
import "unknwn.idl";
+import "strmif.idl";
-
-/*****************************************************************************
- * IAMFilterData interface
- */
[
object,
uuid(97f7c4d4-547b-4a5f-8332-536430ad2e4d),
@@ -33,15 +26,7 @@ import "unknwn.idl";
]
interface IAMFilterData : IUnknown
{
- typedef [unique] IAMFilterData *LPIAMFILTERDATA;
+ HRESULT ParseFilterData( [in] BYTE *data, [in] ULONG size, [out] BYTE **regfilter );
- HRESULT ParseFilterData(
- [in] BYTE * rgbFilterData,
- [in] ULONG cb,
- [out] BYTE ** prgbRegFilter2);
-
- HRESULT CreateFilterData(
- [in] REGFILTER2 * prf2,
- [out] BYTE ** prgbFilterData,
- [out] ULONG * pcb);
+ HRESULT CreateFilterData( [in] REGFILTER2 *regfilter, [out] BYTE **data, [out] ULONG *size );
}
--
2.7.4
June 26, 2018
[PATCH 4/5] devenum: Remove an unused typedef.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/devenum_main.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/dlls/devenum/devenum_main.c b/dlls/devenum/devenum_main.c
index 98ad1ad..b17bc93 100644
--- a/dlls/devenum/devenum_main.c
+++ b/dlls/devenum/devenum_main.c
@@ -28,13 +28,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(devenum);
DECLSPEC_HIDDEN LONG dll_refs;
static HINSTANCE devenum_instance;
-typedef struct
-{
- REFCLSID clsid;
- LPCWSTR friendly_name;
- BOOL instance;
-} register_info;
-
/***********************************************************************
* DllEntryPoint
*/
--
2.7.4
June 26, 2018
[PATCH 3/5] devenum: Make some variables static.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/createdevenum.c | 14 ++++++--------
dlls/devenum/devenum_main.c | 13 ++++---------
dlls/devenum/devenum_private.h | 4 +---
dlls/devenum/mediacatenum.c | 4 +++-
4 files changed, 14 insertions(+), 21 deletions(-)
diff --git a/dlls/devenum/createdevenum.c b/dlls/devenum/createdevenum.c
index 06c264c..8275c99 100644
--- a/dlls/devenum/createdevenum.c
+++ b/dlls/devenum/createdevenum.c
@@ -41,8 +41,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
-extern HINSTANCE DEVENUM_hInstance;
-
static const WCHAR wszFilterKeyName[] = {'F','i','l','t','e','r',0};
static const WCHAR wszMeritName[] = {'M','e','r','i','t',0};
static const WCHAR wszPins[] = {'P','i','n','s',0};
@@ -460,7 +458,7 @@ static void register_legacy_filters(void)
V_VT(&var) = VT_BSTR;
if (!(V_BSTR(&var) = SysAllocString(wszFilterSubkeyName)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
@@ -537,7 +535,7 @@ static BOOL CALLBACK register_dsound_devices(GUID *guid, const WCHAR *desc, cons
StringFromGUID2(&CLSID_DSoundRender, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
@@ -620,7 +618,7 @@ static void register_waveout_devices(void)
StringFromGUID2(&CLSID_AudioRender, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
@@ -693,7 +691,7 @@ static void register_wavein_devices(void)
StringFromGUID2(&CLSID_AudioRecord, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
@@ -765,7 +763,7 @@ static void register_midiout_devices(void)
StringFromGUID2(&CLSID_AVIMIDIRender, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
@@ -854,7 +852,7 @@ static void register_vfw_codecs(void)
StringFromGUID2(&CLSID_AVICo, clsid, CHARS_IN_GUID);
if (!(V_BSTR(&var) = SysAllocString(clsid)))
goto cleanup;
- hr = IPropertyBag_Write(prop_bag, clsid_keyname, &var);
+ hr = IPropertyBag_Write(prop_bag, clsidW, &var);
if (FAILED(hr)) goto cleanup;
VariantClear(&var);
diff --git a/dlls/devenum/devenum_main.c b/dlls/devenum/devenum_main.c
index 3499f99..98ad1ad 100644
--- a/dlls/devenum/devenum_main.c
+++ b/dlls/devenum/devenum_main.c
@@ -26,7 +26,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(devenum);
DECLSPEC_HIDDEN LONG dll_refs;
-DECLSPEC_HIDDEN HINSTANCE DEVENUM_hInstance;
+static HINSTANCE devenum_instance;
typedef struct
{
@@ -36,11 +36,6 @@ typedef struct
} register_info;
/***********************************************************************
- * Global string constant definitions
- */
-const WCHAR clsid_keyname[6] = { 'C', 'L', 'S', 'I', 'D', 0 };
-
-/***********************************************************************
* DllEntryPoint
*/
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
@@ -49,7 +44,7 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
switch(fdwReason) {
case DLL_PROCESS_ATTACH:
- DEVENUM_hInstance = hinstDLL;
+ devenum_instance = hinstDLL;
DisableThreadLibraryCalls(hinstDLL);
break;
}
@@ -166,7 +161,7 @@ HRESULT WINAPI DllRegisterServer(void)
TRACE("\n");
- res = __wine_register_resources( DEVENUM_hInstance );
+ res = __wine_register_resources( devenum_instance );
if (FAILED(res))
return res;
@@ -214,5 +209,5 @@ HRESULT WINAPI DllRegisterServer(void)
HRESULT WINAPI DllUnregisterServer(void)
{
FIXME("stub!\n");
- return __wine_unregister_resources( DEVENUM_hInstance );
+ return __wine_unregister_resources( devenum_instance );
}
diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h
index ea4e017..e18c57d 100644
--- a/dlls/devenum/devenum_private.h
+++ b/dlls/devenum/devenum_private.h
@@ -83,7 +83,7 @@ extern IParseDisplayName DEVENUM_ParseDisplayName DECLSPEC_HIDDEN;
*/
static const WCHAR backslashW[] = {'\\',0};
-static const WCHAR clsidW[] = {'C','L','S','I','D','\\',0};
+static const WCHAR clsidW[] = {'C','L','S','I','D',0};
static const WCHAR instanceW[] = {'\\','I','n','s','t','a','n','c','e',0};
static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\',
'M','i','c','r','o','s','o','f','t','\\',
@@ -93,5 +93,3 @@ static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0};
static const WCHAR dmoW[] = {'d','m','o',':',0};
static const WCHAR swW[] = {'s','w',':',0};
static const WCHAR cmW[] = {'c','m',':',0};
-
-extern const WCHAR clsid_keyname[6] DECLSPEC_HIDDEN;
diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c
index c4338a2..660e81c 100644
--- a/dlls/devenum/mediacatenum.c
+++ b/dlls/devenum/mediacatenum.c
@@ -347,6 +347,7 @@ static HRESULT create_PropertyBag(MediaCatMoniker *mon, IPropertyBag **ppBag)
else if (rpb->type == DEVICE_FILTER)
{
strcpyW(rpb->path, clsidW);
+ strcatW(rpb->path, backslashW);
if (mon->has_class)
{
StringFromGUID2(&mon->class, rpb->path + strlenW(rpb->path), CHARS_IN_GUID);
@@ -496,7 +497,7 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_BindToObject(IMoniker *iface, IBi
if (SUCCEEDED(res))
{
V_VT(&var) = VT_LPWSTR;
- res = IPropertyBag_Read(pProp, clsid_keyname, &var, NULL);
+ res = IPropertyBag_Read(pProp, clsidW, &var, NULL);
}
if (SUCCEEDED(res))
{
@@ -1027,6 +1028,7 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
pEnumMoniker->class = *class;
strcpyW(buffer, clsidW);
+ strcatW(buffer, backslashW);
StringFromGUID2(class, buffer + strlenW(buffer), CHARS_IN_GUID);
strcatW(buffer, instanceW);
if (RegOpenKeyExW(HKEY_CLASSES_ROOT, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->sw_key))
--
2.7.4
June 26, 2018
[PATCH 2/5] devenum: Use separate factories for CLSID_SystemDeviceEnum and CLSID_CDeviceMoniker.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/devenum_main.c | 46 +++++++++++++++++++++++----------------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/dlls/devenum/devenum_main.c b/dlls/devenum/devenum_main.c
index 7bfc593..3499f99 100644
--- a/dlls/devenum/devenum_main.c
+++ b/dlls/devenum/devenum_main.c
@@ -56,6 +56,17 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
return TRUE;
}
+struct class_factory
+{
+ IClassFactory IClassFactory_iface;
+ IUnknown *obj;
+};
+
+static inline struct class_factory *impl_from_IClassFactory( IClassFactory *iface )
+{
+ return CONTAINING_RECORD( iface, struct class_factory, IClassFactory_iface );
+}
+
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void **obj)
{
TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), obj);
@@ -87,24 +98,15 @@ static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface,
IUnknown *outer, REFIID iid, void **obj)
{
+ struct class_factory *This = impl_from_IClassFactory( iface );
+
TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj);
if (!obj) return E_POINTER;
if (outer) return CLASS_E_NOAGGREGATION;
- if (IsEqualGUID(&IID_ICreateDevEnum, iid))
- {
- *obj = &DEVENUM_CreateDevEnum;
- return S_OK;
- }
- if (IsEqualGUID(&IID_IParseDisplayName, iid))
- {
- *obj = &DEVENUM_ParseDisplayName;
- return S_OK;
- }
-
- return CLASS_E_CLASSNOTAVAILABLE;
+ return IUnknown_QueryInterface(This->obj, iid, obj);
}
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock)
@@ -124,24 +126,24 @@ static const IClassFactoryVtbl ClassFactory_vtbl = {
ClassFactory_LockServer
};
-static IClassFactory devenum_cf = { &ClassFactory_vtbl };
+static struct class_factory create_devenum_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_CreateDevEnum };
+static struct class_factory device_moniker_cf = { { &ClassFactory_vtbl }, (IUnknown *)&DEVENUM_ParseDisplayName };
/***********************************************************************
* DllGetClassObject (DEVENUM.@)
*/
-HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
+HRESULT WINAPI DllGetClassObject(REFCLSID clsid, REFIID iid, void **obj)
{
- TRACE("(%s, %s, %p)\n", debugstr_guid(rclsid), debugstr_guid(iid), ppv);
+ TRACE("(%s, %s, %p)\n", debugstr_guid(clsid), debugstr_guid(iid), obj);
- *ppv = NULL;
+ *obj = NULL;
- /* FIXME: we should really have two class factories.
- * Oh well - works just fine as it is */
- if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) ||
- IsEqualGUID(rclsid, &CLSID_CDeviceMoniker))
- return IClassFactory_QueryInterface(&devenum_cf, iid, ppv);
+ if (IsEqualGUID(clsid, &CLSID_SystemDeviceEnum))
+ return IClassFactory_QueryInterface(&create_devenum_cf.IClassFactory_iface, iid, obj);
+ else if (IsEqualGUID(clsid, &CLSID_CDeviceMoniker))
+ return IClassFactory_QueryInterface(&device_moniker_cf.IClassFactory_iface, iid, obj);
- FIXME("CLSID: %s, IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid));
+ FIXME("class %s not available\n", debugstr_guid(clsid));
return CLASS_E_CLASSNOTAVAILABLE;
}
--
2.7.4
June 26, 2018
[PATCH 1/5] devenum: Merge factory.c into devenum_main.c.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/Makefile.in | 1 -
dlls/devenum/devenum_main.c | 74 ++++++++++++++++++++++-
dlls/devenum/devenum_private.h | 10 ---
dlls/devenum/factory.c | 134 -----------------------------------------
4 files changed, 72 insertions(+), 147 deletions(-)
delete mode 100644 dlls/devenum/factory.c
diff --git a/dlls/devenum/Makefile.in b/dlls/devenum/Makefile.in
index ae138b6..d1407a9 100644
--- a/dlls/devenum/Makefile.in
+++ b/dlls/devenum/Makefile.in
@@ -5,7 +5,6 @@ DELAYIMPORTS = msvfw32
C_SRCS = \
createdevenum.c \
devenum_main.c \
- factory.c \
mediacatenum.c \
parsedisplayname.c
diff --git a/dlls/devenum/devenum_main.c b/dlls/devenum/devenum_main.c
index cb4b454..7bfc593 100644
--- a/dlls/devenum/devenum_main.c
+++ b/dlls/devenum/devenum_main.c
@@ -1,5 +1,5 @@
/*
- * exported dll functions for devenum.dll
+ * Device Enumeration
*
* Copyright (C) 2002 John K. Hohm
* Copyright (C) 2002 Robert Shearman
@@ -56,6 +56,76 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
return TRUE;
}
+static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void **obj)
+{
+ TRACE("(%p, %s, %p)\n", iface, debugstr_guid(iid), obj);
+
+ if (IsEqualGUID(iid, &IID_IUnknown) || IsEqualGUID(iid, &IID_IClassFactory))
+ {
+ IClassFactory_AddRef(iface);
+ *obj = iface;
+ return S_OK;
+ }
+
+ *obj = NULL;
+ WARN("no interface for %s\n", debugstr_guid(iid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
+{
+ DEVENUM_LockModule();
+ return 2;
+}
+
+static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
+{
+ DEVENUM_UnlockModule();
+ return 1;
+}
+
+static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface,
+ IUnknown *outer, REFIID iid, void **obj)
+{
+ TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj);
+
+ if (!obj) return E_POINTER;
+
+ if (outer) return CLASS_E_NOAGGREGATION;
+
+ if (IsEqualGUID(&IID_ICreateDevEnum, iid))
+ {
+ *obj = &DEVENUM_CreateDevEnum;
+ return S_OK;
+ }
+ if (IsEqualGUID(&IID_IParseDisplayName, iid))
+ {
+ *obj = &DEVENUM_ParseDisplayName;
+ return S_OK;
+ }
+
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
+
+static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock)
+{
+ if (lock)
+ DEVENUM_LockModule();
+ else
+ DEVENUM_UnlockModule();
+ return S_OK;
+}
+
+static const IClassFactoryVtbl ClassFactory_vtbl = {
+ ClassFactory_QueryInterface,
+ ClassFactory_AddRef,
+ ClassFactory_Release,
+ ClassFactory_CreateInstance,
+ ClassFactory_LockServer
+};
+
+static IClassFactory devenum_cf = { &ClassFactory_vtbl };
+
/***********************************************************************
* DllGetClassObject (DEVENUM.@)
*/
@@ -69,7 +139,7 @@ HRESULT WINAPI DllGetClassObject(REFCLSID rclsid, REFIID iid, LPVOID *ppv)
* Oh well - works just fine as it is */
if (IsEqualGUID(rclsid, &CLSID_SystemDeviceEnum) ||
IsEqualGUID(rclsid, &CLSID_CDeviceMoniker))
- return IClassFactory_QueryInterface(&DEVENUM_ClassFactory.IClassFactory_iface, iid, ppv);
+ return IClassFactory_QueryInterface(&devenum_cf, iid, ppv);
FIXME("CLSID: %s, IID: %s\n", debugstr_guid(rclsid), debugstr_guid(iid));
return CLASS_E_CLASSNOTAVAILABLE;
diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h
index df0080d..ea4e017 100644
--- a/dlls/devenum/devenum_private.h
+++ b/dlls/devenum/devenum_private.h
@@ -51,15 +51,6 @@ extern LONG dll_refs DECLSPEC_HIDDEN;
static inline void DEVENUM_LockModule(void) { InterlockedIncrement(&dll_refs); }
static inline void DEVENUM_UnlockModule(void) { InterlockedDecrement(&dll_refs); }
-
-/**********************************************************************
- * ClassFactory declaration for devenum.dll
- */
-typedef struct
-{
- IClassFactory IClassFactory_iface;
-} ClassFactoryImpl;
-
enum device_type
{
DEVICE_FILTER,
@@ -84,7 +75,6 @@ typedef struct
MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN;
HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **enum_mon) DECLSPEC_HIDDEN;
-extern ClassFactoryImpl DEVENUM_ClassFactory DECLSPEC_HIDDEN;
extern ICreateDevEnum DEVENUM_CreateDevEnum DECLSPEC_HIDDEN;
extern IParseDisplayName DEVENUM_ParseDisplayName DECLSPEC_HIDDEN;
diff --git a/dlls/devenum/factory.c b/dlls/devenum/factory.c
deleted file mode 100644
index c808fa5..0000000
--- a/dlls/devenum/factory.c
+++ /dev/null
@@ -1,134 +0,0 @@
-/*
- * ClassFactory implementation for DEVENUM.dll
- *
- * Copyright (C) 2002 John K. Hohm
- * Copyright (C) 2002 Robert Shearman
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2.1 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#include "devenum_private.h"
-
-#include "wine/debug.h"
-
-WINE_DEFAULT_DEBUG_CHANNEL(devenum);
-
-/**********************************************************************
- * DEVENUM_IClassFactory_QueryInterface (also IUnknown)
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_QueryInterface(IClassFactory *iface, REFIID riid,
- void **ppvObj)
-{
- TRACE("(%p)->(%s, %p)\n", iface, debugstr_guid(riid), ppvObj);
-
- if (ppvObj == NULL) return E_POINTER;
-
- if (IsEqualGUID(riid, &IID_IUnknown) ||
- IsEqualGUID(riid, &IID_IClassFactory))
- {
- *ppvObj = iface;
- IClassFactory_AddRef(iface);
- return S_OK;
- }
- else if (IsEqualGUID(riid, &IID_IParseDisplayName))
- {
- return IClassFactory_CreateInstance(iface, NULL, riid, ppvObj);
- }
-
- FIXME("- no interface IID: %s\n", debugstr_guid(riid));
- return E_NOINTERFACE;
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_AddRef (also IUnknown)
- */
-static ULONG WINAPI DEVENUM_IClassFactory_AddRef(IClassFactory *iface)
-{
- TRACE("\n");
-
- DEVENUM_LockModule();
-
- return 2; /* non-heap based object */
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_Release (also IUnknown)
- */
-static ULONG WINAPI DEVENUM_IClassFactory_Release(IClassFactory *iface)
-{
- TRACE("\n");
-
- DEVENUM_UnlockModule();
-
- return 1; /* non-heap based object */
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_CreateInstance
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_CreateInstance(IClassFactory *iface,
- IUnknown *pUnkOuter, REFIID riid, void **ppvObj)
-{
- TRACE("(%p)->(%p, %s, %p)\n", iface, pUnkOuter, debugstr_guid(riid), ppvObj);
-
- if (ppvObj == NULL) return E_POINTER;
-
- /* Don't support aggregation (Windows doesn't) */
- if (pUnkOuter != NULL) return CLASS_E_NOAGGREGATION;
-
- if (IsEqualGUID(&IID_ICreateDevEnum, riid))
- {
- *ppvObj = &DEVENUM_CreateDevEnum;
- return S_OK;
- }
- if (IsEqualGUID(&IID_IParseDisplayName, riid))
- {
- *ppvObj = &DEVENUM_ParseDisplayName;
- return S_OK;
- }
-
- return CLASS_E_CLASSNOTAVAILABLE;
-}
-
-/**********************************************************************
- * DEVENUM_IClassFactory_LockServer
- */
-static HRESULT WINAPI DEVENUM_IClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
-{
- TRACE("\n");
-
- if (fLock)
- DEVENUM_LockModule();
- else
- DEVENUM_UnlockModule();
- return S_OK;
-}
-
-/**********************************************************************
- * IClassFactory_Vtbl
- */
-static const IClassFactoryVtbl IClassFactory_Vtbl =
-{
- DEVENUM_IClassFactory_QueryInterface,
- DEVENUM_IClassFactory_AddRef,
- DEVENUM_IClassFactory_Release,
- DEVENUM_IClassFactory_CreateInstance,
- DEVENUM_IClassFactory_LockServer
-};
-
-/**********************************************************************
- * static ClassFactory instance
- */
-ClassFactoryImpl DEVENUM_ClassFactory = { { &IClassFactory_Vtbl } };
--
2.7.4
June 26, 2018
[PATCH v2 3/3] comctl32/taskdialog: Add support for command links.
by Zhiyi Zhang
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/comctl32/taskdialog.c | 62 +++++++++++++++++++++++++++++---
dlls/comctl32/tests/taskdialog.c | 61 +++++++++++++++++--------------
2 files changed, 93 insertions(+), 30 deletions(-)
diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 207f77b012..42d50a93cb 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -60,6 +60,8 @@ struct taskdialog_info
HWND progress_bar;
HWND *radio_buttons;
INT radio_button_count;
+ HWND *command_links;
+ INT command_link_count;
HWND *buttons;
INT button_count;
HWND default_button;
@@ -184,7 +186,8 @@ static HWND taskdialog_find_button(HWND *buttons, INT count, INT id)
static void taskdialog_enable_button(const struct taskdialog_info *dialog_info, INT id, BOOL enable)
{
- HWND hwnd = taskdialog_find_button(dialog_info->buttons, dialog_info->button_count, id);
+ HWND hwnd = taskdialog_find_button(dialog_info->command_links, dialog_info->command_link_count, id);
+ if (!hwnd) hwnd = taskdialog_find_button(dialog_info->buttons, dialog_info->button_count, id);
if (hwnd) EnableWindow(hwnd, enable);
}
@@ -253,6 +256,11 @@ static BOOL taskdialog_hyperlink_enabled(struct taskdialog_info *dialog_info)
return dialog_info->taskconfig->dwFlags & TDF_ENABLE_HYPERLINKS;
}
+static BOOL taskdialog_use_command_link(struct taskdialog_info *dialog_info)
+{
+ return dialog_info->taskconfig->dwFlags & (TDF_USE_COMMAND_LINKS | TDF_USE_COMMAND_LINKS_NO_ICON);
+}
+
static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND hwnd, LONG max_width, SIZE *size,
BOOL syslink)
{
@@ -486,6 +494,34 @@ static void taskdialog_add_radio_buttons(struct taskdialog_info *dialog_info)
}
}
+static void taskdialog_add_command_links(struct taskdialog_info *dialog_info)
+{
+ const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
+ DWORD default_style = BS_MULTILINE | BS_LEFT | BS_TOP | WS_CHILD | WS_VISIBLE | WS_TABSTOP, style;
+ BOOL is_default;
+ WCHAR *textW;
+ INT i;
+
+ if (!taskconfig->cButtons || !taskconfig->pButtons || !taskdialog_use_command_link(dialog_info)) return;
+
+ dialog_info->command_links = Alloc(taskconfig->cButtons * sizeof(*dialog_info->command_links));
+ if (!dialog_info->command_links) return;
+
+ dialog_info->command_link_count = taskconfig->cButtons;
+ for (i = 0; i < dialog_info->command_link_count; i++)
+ {
+ is_default = taskconfig->pButtons[i].nButtonID == taskconfig->nDefaultButton;
+ style = is_default ? default_style | BS_DEFCOMMANDLINK : default_style | BS_COMMANDLINK;
+ textW = taskdialog_gettext(dialog_info, TRUE, taskconfig->pButtons[i].pszButtonText);
+ dialog_info->command_links[i] = CreateWindowW(WC_BUTTONW, textW, style, 0, 0, 0, 0, dialog_info->hwnd,
+ (HMENU)taskconfig->pButtons[i].nButtonID, 0, NULL);
+ SendMessageW(dialog_info->command_links[i], WM_SETFONT, (WPARAM)dialog_info->font, 0);
+ Free(textW);
+
+ if (is_default && !dialog_info->default_button) dialog_info->default_button = dialog_info->command_links[i];
+ }
+}
+
static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT_PTR id, const WCHAR *text,
BOOL custom_button)
{
@@ -504,17 +540,18 @@ static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *but
static void taskdialog_add_buttons(struct taskdialog_info *dialog_info)
{
const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
+ BOOL use_command_links = taskdialog_use_command_link(dialog_info);
DWORD flags = taskconfig->dwCommonButtons;
INT count, max_count;
/* Allocate enough memory for the custom and the default buttons. Maximum 6 default buttons possible. */
max_count = 6;
- if (taskconfig->cButtons && taskconfig->pButtons) max_count += taskconfig->cButtons;
+ if (!use_command_links && taskconfig->cButtons && taskconfig->pButtons) max_count += taskconfig->cButtons;
dialog_info->buttons = Alloc(max_count * sizeof(*dialog_info->buttons));
if (!dialog_info->buttons) return;
- for (count = 0; count < taskconfig->cButtons; count++)
+ for (count = 0; !use_command_links && count < taskconfig->cButtons; count++)
taskdialog_add_button(dialog_info, &dialog_info->buttons[count], taskconfig->pButtons[count].nButtonID,
taskconfig->pButtons[count].pszButtonText, TRUE);
@@ -532,7 +569,7 @@ static void taskdialog_add_buttons(struct taskdialog_info *dialog_info)
if (flags & TDCBF_CANCEL_BUTTON) TASKDIALOG_INIT_COMMON_BUTTON(CANCEL);
if (flags & TDCBF_CLOSE_BUTTON) TASKDIALOG_INIT_COMMON_BUTTON(CLOSE);
- if (!count) TASKDIALOG_INIT_COMMON_BUTTON(OK);
+ if (!count && !dialog_info->command_link_count) TASKDIALOG_INIT_COMMON_BUTTON(OK);
#undef TASKDIALOG_INIT_COMMON_BUTTON
dialog_info->button_count = count;
@@ -621,6 +658,19 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info)
dialog_height = y + size.cy;
}
+ /* Command links */
+ for (i = 0; i < dialog_info->command_link_count; i++)
+ {
+ x = main_icon_right + h_spacing;
+ y = dialog_height + v_spacing;
+ taskdialog_get_label_size(dialog_info, dialog_info->command_links[i], dialog_width - x - h_spacing, &size, FALSE);
+ size.cx = dialog_width - x - h_spacing;
+ /* Add spacing */
+ size.cy += 4;
+ SetWindowPos(dialog_info->command_links[i], 0, x, y, size.cx, size.cy, SWP_NOZORDER);
+ dialog_height = y + size.cy;
+ }
+
dialog_height = max(dialog_height, main_icon_bottom);
/* Common and custom buttons */
@@ -756,9 +806,12 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd)
taskdialog_add_content(dialog_info);
taskdialog_add_progress_bar(dialog_info);
taskdialog_add_radio_buttons(dialog_info);
+ taskdialog_add_command_links(dialog_info);
taskdialog_add_buttons(dialog_info);
/* Set default button */
+ if (!dialog_info->default_button && dialog_info->command_links)
+ dialog_info->default_button = dialog_info->command_links[0];
if (!dialog_info->default_button) dialog_info->default_button = dialog_info->buttons[0];
SendMessageW(dialog_info->hwnd, WM_NEXTDLGCTL, (WPARAM)dialog_info->default_button, TRUE);
id = GetWindowLongW(dialog_info->default_button, GWLP_ID);
@@ -774,6 +827,7 @@ static void taskdialog_destroy(struct taskdialog_info *dialog_info)
if (dialog_info->main_instruction_font) DeleteObject(dialog_info->main_instruction_font);
if (dialog_info->buttons) Free(dialog_info->buttons);
if (dialog_info->radio_buttons) Free(dialog_info->radio_buttons);
+ if (dialog_info->command_links) Free(dialog_info->command_links);
}
static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
index 2cda04081f..33d3757308 100644
--- a/dlls/comctl32/tests/taskdialog.c
+++ b/dlls/comctl32/tests/taskdialog.c
@@ -323,7 +323,7 @@ static void test_callback(void)
static void test_buttons(void)
{
TASKDIALOGCONFIG info = {0};
-
+ static const DWORD command_link_flags[] = {0, TDF_USE_COMMAND_LINKS, TDF_USE_COMMAND_LINKS_NO_ICON};
TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS], radio_buttons[TEST_NUM_RADIO_BUTTONS];
const WCHAR button_format[] = {'%','0','2','d',0};
/* Each button has two digits as title, plus null-terminator */
@@ -373,31 +373,40 @@ static void test_buttons(void)
info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_CLOSE_BUTTON;
run_test(&info, IDCANCEL, 0, msg_return_press_cancel, "default button: unset default");
- /* Test with all common and custom buttons and invalid default ID */
- info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
- info.cButtons = TEST_NUM_BUTTONS;
- info.pButtons = custom_buttons;
- run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, with common buttons - 1");
-
- info.nDefaultButton = -1; /* Should work despite button ID -1 */
- run_test(&info, -1, 0, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
-
- info.nDefaultButton = -2; /* Should also default to first created button */
- run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, with common buttons - 3");
-
- /* Test with only custom buttons and invalid default ID */
- info.dwCommonButtons = 0;
- run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, no common buttons");
-
- /* Test with common and custom buttons and valid default ID */
- info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
- | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
- info.nDefaultButton = IDRETRY;
- run_test(&info, IDRETRY, 0, msg_return_press_retry, "default button: valid default - 1");
-
- /* Test with common and custom buttons and valid default ID */
- info.nDefaultButton = ID_START_BUTTON + 3;
- run_test(&info, ID_START_BUTTON + 3, 0, msg_return_press_custom4, "default button: valid default - 2");
+ /* Custom buttons could be command links */
+ for (i = 0; i < ARRAY_SIZE(command_link_flags); i++)
+ {
+ info.dwFlags = command_link_flags[i];
+
+ /* Test with all common and custom buttons and invalid default ID */
+ info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
+ info.cButtons = TEST_NUM_BUTTONS;
+ info.pButtons = custom_buttons;
+ run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1,
+ "default button: invalid default, with common buttons - 1");
+
+ info.nDefaultButton = -1; /* Should work despite button ID -1 */
+ run_test(&info, -1, 0, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
+
+ info.nDefaultButton = -2; /* Should also default to first created button */
+ run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1,
+ "default button: invalid default, with common buttons - 3");
+
+ /* Test with only custom buttons and invalid default ID */
+ info.dwCommonButtons = 0;
+ run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1,
+ "default button: invalid default, no common buttons");
+
+ /* Test with common and custom buttons and valid default ID */
+ info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON
+ | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
+ info.nDefaultButton = IDRETRY;
+ run_test(&info, IDRETRY, 0, msg_return_press_retry, "default button: valid default - 1");
+
+ /* Test with common and custom buttons and valid default ID */
+ info.nDefaultButton = ID_START_BUTTON + 3;
+ run_test(&info, ID_START_BUTTON + 3, 0, msg_return_press_custom4, "default button: valid default - 2");
+ }
/* Test radio buttons */
info.nDefaultButton = 0;
--
2.17.1
June 26, 2018
[PATCH v2 2/3] comctl32/taskdialog: Add support for radio buttons.
by Zhiyi Zhang
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/comctl32/taskdialog.c | 139 ++++++++++++++++++++++++-
dlls/comctl32/tests/taskdialog.c | 172 +++++++++++++++++++++++++++----
2 files changed, 290 insertions(+), 21 deletions(-)
diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 5625f2bc24..207f77b012 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -58,6 +58,8 @@ struct taskdialog_info
HWND main_instruction;
HWND content;
HWND progress_bar;
+ HWND *radio_buttons;
+ INT radio_button_count;
HWND *buttons;
INT button_count;
HWND default_button;
@@ -69,6 +71,7 @@ struct taskdialog_info
LONG h_spacing;
LONG v_spacing;
} m;
+ INT selected_radio_id;
};
struct button_layout_info
@@ -185,6 +188,18 @@ static void taskdialog_enable_button(const struct taskdialog_info *dialog_info,
if (hwnd) EnableWindow(hwnd, enable);
}
+static void taskdialog_enable_radio_button(const struct taskdialog_info *dialog_info, INT id, BOOL enable)
+{
+ HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id);
+ if (hwnd) EnableWindow(hwnd, enable);
+}
+
+static void taskdialog_click_radio_button(const struct taskdialog_info *dialog_info, INT id)
+{
+ HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id);
+ if (hwnd) SendMessageW(hwnd, BM_CLICK, 0, 0);
+}
+
static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notification, WPARAM wparam, LPARAM lparam)
{
const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
@@ -193,8 +208,18 @@ static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notif
: S_OK;
}
-static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, WORD command_id)
+static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, INT command_id)
{
+ HWND radio_button;
+
+ radio_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, command_id);
+ if (radio_button)
+ {
+ dialog_info->selected_radio_id = command_id;
+ taskdialog_notify(dialog_info, TDN_RADIO_BUTTON_CLICKED, command_id, 0);
+ return;
+ }
+
if (taskdialog_notify(dialog_info, TDN_BUTTON_CLICKED, command_id, 0) == S_OK)
EndDialog(dialog_info->hwnd, command_id);
}
@@ -269,6 +294,49 @@ static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND
Free(text);
}
+static void taskdialog_get_radio_button_size(struct taskdialog_info *dialog_info, HWND hwnd, LONG max_width, SIZE *size)
+{
+ DWORD style = DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK;
+ HFONT hfont, old_hfont;
+ HDC hdc;
+ RECT rect = {0};
+ INT text_length;
+ WCHAR *text;
+ INT text_offset, radio_box_width, radio_box_height;
+
+ hdc = GetDC(hwnd);
+ hfont = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
+ old_hfont = SelectObject(hdc, hfont);
+
+ radio_box_width = 12 * GetDeviceCaps(hdc, LOGPIXELSX) / 96 + 1;
+ radio_box_height = 12 * GetDeviceCaps(hdc, LOGPIXELSY) / 96 + 1;
+ GetCharWidthW(hdc, '0', '0', &text_offset);
+ text_offset /= 2;
+
+ if (dialog_info->taskconfig->dwFlags & TDF_RTL_LAYOUT)
+ style |= DT_RIGHT | DT_RTLREADING;
+ else
+ style |= DT_LEFT;
+
+ rect.right = max_width - radio_box_width - text_offset;
+ text_length = GetWindowTextLengthW(hwnd);
+ text = Alloc((text_length + 1) * sizeof(WCHAR));
+ if (!text)
+ {
+ size->cx = 0;
+ size->cy = 0;
+ return;
+ }
+ GetWindowTextW(hwnd, text, text_length + 1);
+ size->cy = DrawTextW(hdc, text, text_length, &rect, style);
+ size->cx = min(max_width - radio_box_width - text_offset, rect.right - rect.left);
+ size->cx += radio_box_width + text_offset;
+ size->cy = max(size->cy, radio_box_height);
+ if (old_hfont) SelectObject(hdc, old_hfont);
+ Free(text);
+ ReleaseDC(hwnd, hdc);
+}
+
static ULONG_PTR taskdialog_get_standard_icon(LPCWSTR icon)
{
if (icon == TD_WARNING_ICON)
@@ -309,6 +377,28 @@ static void taskdialog_set_icon(struct taskdialog_info *dialog_info, INT element
}
}
+static void taskdialog_check_default_radio_buttons(struct taskdialog_info *dialog_info)
+{
+ const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
+ HWND default_button;
+ INT id;
+
+ if (!dialog_info->radio_button_count) return;
+
+ default_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count,
+ taskconfig->nDefaultRadioButton);
+
+ if (!default_button && !(taskconfig->dwFlags & TDF_NO_DEFAULT_RADIO_BUTTON))
+ default_button = dialog_info->radio_buttons[0];
+
+ if (default_button)
+ {
+ SendMessageW(default_button, BM_SETCHECK, BST_CHECKED, 0);
+ id = GetWindowLongW(default_button, GWLP_ID);
+ taskdialog_on_button_click(dialog_info, id);
+ }
+}
+
static void taskdialog_add_main_icon(struct taskdialog_info *dialog_info)
{
if (!dialog_info->taskconfig->u.hMainIcon) return;
@@ -372,6 +462,30 @@ static void taskdialog_add_progress_bar(struct taskdialog_info *dialog_info)
CreateWindowW(PROGRESS_CLASSW, NULL, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL);
}
+static void taskdialog_add_radio_buttons(struct taskdialog_info *dialog_info)
+{
+ const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
+ static const DWORD style = BS_AUTORADIOBUTTON | BS_MULTILINE | BS_TOP | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
+ WCHAR *textW;
+ INT i;
+
+ if (!taskconfig->cRadioButtons || !taskconfig->pRadioButtons) return;
+
+ dialog_info->radio_buttons = Alloc(taskconfig->cRadioButtons * sizeof(*dialog_info->radio_buttons));
+ if (!dialog_info->radio_buttons) return;
+
+ dialog_info->radio_button_count = taskconfig->cRadioButtons;
+ for (i = 0; i < dialog_info->radio_button_count; i++)
+ {
+ textW = taskdialog_gettext(dialog_info, TRUE, taskconfig->pRadioButtons[i].pszButtonText);
+ dialog_info->radio_buttons[i] =
+ CreateWindowW(WC_BUTTONW, textW, i == 0 ? style | WS_GROUP : style, 0, 0, 0, 0, dialog_info->hwnd,
+ (HMENU)taskconfig->pRadioButtons[i].nButtonID, 0, NULL);
+ SendMessageW(dialog_info->radio_buttons[i], WM_SETFONT, (WPARAM)dialog_info->font, 0);
+ Free(textW);
+ }
+}
+
static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT_PTR id, const WCHAR *text,
BOOL custom_button)
{
@@ -496,6 +610,17 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info)
dialog_height = y + size.cy;
}
+ /* Radio buttons */
+ for (i = 0; i < dialog_info->radio_button_count; i++)
+ {
+ x = main_icon_right + h_spacing;
+ y = dialog_height;
+ taskdialog_get_radio_button_size(dialog_info, dialog_info->radio_buttons[i], dialog_width - x - h_spacing, &size);
+ size.cx = dialog_width - x - h_spacing;
+ SetWindowPos(dialog_info->radio_buttons[i], 0, x, y, size.cx, size.cy, SWP_NOZORDER);
+ dialog_height = y + size.cy;
+ }
+
dialog_height = max(dialog_height, main_icon_bottom);
/* Common and custom buttons */
@@ -630,6 +755,7 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd)
taskdialog_add_main_instruction(dialog_info);
taskdialog_add_content(dialog_info);
taskdialog_add_progress_bar(dialog_info);
+ taskdialog_add_radio_buttons(dialog_info);
taskdialog_add_buttons(dialog_info);
/* Set default button */
@@ -647,6 +773,7 @@ static void taskdialog_destroy(struct taskdialog_info *dialog_info)
if (dialog_info->font) DeleteObject(dialog_info->font);
if (dialog_info->main_instruction_font) DeleteObject(dialog_info->main_instruction_font);
if (dialog_info->buttons) Free(dialog_info->buttons);
+ if (dialog_info->radio_buttons) Free(dialog_info->radio_buttons);
}
static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -698,6 +825,12 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
case TDM_SET_PROGRESS_BAR_MARQUEE:
SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, lParam);
break;
+ case TDM_CLICK_RADIO_BUTTON:
+ taskdialog_click_radio_button(dialog_info, wParam);
+ break;
+ case TDM_ENABLE_RADIO_BUTTON:
+ taskdialog_enable_radio_button(dialog_info, wParam, lParam);
+ break;
case WM_INITDIALOG:
dialog_info = (struct taskdialog_info *)lParam;
@@ -706,6 +839,8 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
SetPropW(hwnd, taskdialog_info_propnameW, dialog_info);
taskdialog_notify(dialog_info, TDN_DIALOG_CONSTRUCTED, 0, 0);
taskdialog_notify(dialog_info, TDN_CREATED, 0, 0);
+ /* Default radio button click notification sent after TDN_CREATED */
+ taskdialog_check_default_radio_buttons(dialog_info);
return FALSE;
case WM_COMMAND:
if (HIWORD(wParam) == BN_CLICKED)
@@ -771,7 +906,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *taskconfig, int *butto
Free(template);
if (button) *button = ret;
- if (radio_button) *radio_button = taskconfig->nDefaultButton;
+ if (radio_button) *radio_button = dialog_info.selected_radio_id;
if (verification_flag_checked) *verification_flag_checked = TRUE;
return S_OK;
diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
index e91a878876..2cda04081f 100644
--- a/dlls/comctl32/tests/taskdialog.c
+++ b/dlls/comctl32/tests/taskdialog.c
@@ -35,9 +35,11 @@
#define TASKDIALOG_SEQ_INDEX 0
#define TEST_NUM_BUTTONS 10 /* Number of custom buttons to test with */
+#define TEST_NUM_RADIO_BUTTONS 3
#define ID_START 20 /* Lower IDs might be used by the system */
#define ID_START_BUTTON (ID_START + 0)
+#define ID_START_RADIO_BUTTON (ID_START + 20)
static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
static HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *,
@@ -141,6 +143,78 @@ static const struct message_info msg_got_tdn_help[] =
{ 0 }
};
+/* Three radio buttons */
+static const struct message_info msg_return_default_radio_button_1[] =
+{
+ { TDN_CREATED, 0, 0, S_OK, NULL },
+ { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
+ { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
+ { 0 }
+};
+
+static const struct message_info msg_return_default_radio_button_2[] =
+{
+ { TDN_CREATED, 0, 0, S_OK, NULL },
+ { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_send_click_ok },
+ { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
+ { 0 }
+};
+
+static const struct message_info msg_return_default_radio_button_3[] =
+{
+ { TDN_CREATED, 0, 0, S_OK, NULL },
+ { TDN_RADIO_BUTTON_CLICKED, -2, 0, S_OK, msg_send_click_ok },
+ { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
+ { 0 }
+};
+
+static const struct message_info msg_select_first_radio_button[] =
+{
+ { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
+ { 0 }
+};
+
+static const struct message_info msg_return_first_radio_button[] =
+{
+ { TDN_CREATED, 0, 0, S_OK, NULL },
+ { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_radio_button },
+ { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
+ { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
+ { 0 }
+};
+
+static const struct message_info msg_select_first_disabled_radio_button_and_press_ok[] =
+{
+ { TDM_ENABLE_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
+ { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
+ { TDM_CLICK_BUTTON, IDOK, 0 },
+ { 0 }
+};
+
+static const struct message_info msg_return_default_radio_button_clicking_disabled[] =
+{
+ { TDN_CREATED, 0, 0, S_OK, NULL },
+ { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_disabled_radio_button_and_press_ok },
+ { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
+ { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
+ { 0 }
+};
+
+static const struct message_info msg_return_no_default_radio_button_flag[] =
+{
+ { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
+ { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
+ { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
+ { 0 }
+};
+
+static const struct message_info msg_return_no_default_radio_button_id_and_flag[] =
+{
+ { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
+ { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
+ { 0 }
+};
+
static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct message *msg)
{
msg->message = WM_TD_CALLBACK;
@@ -151,11 +225,13 @@ static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct
msg->stage = 0;
}
-#define run_test(info, expect_button, seq, context) \
- run_test_(info, expect_button, seq, context, ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
+#define run_test(info, expect_button, expect_radio_button, seq, context) \
+ run_test_(info, expect_button, expect_radio_button, seq, context, \
+ ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
-static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct message_info *test_messages,
- const char *context, int test_messages_len, const char *file, int line)
+static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio_button,
+ const struct message_info *test_messages, const char *context, int test_messages_len,
+ const char *file, int line)
{
struct message *msg, *msg_start;
int ret_button = 0;
@@ -182,6 +258,8 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct me
ok_sequence_(sequences, TASKDIALOG_SEQ_INDEX, msg_start, context, FALSE, file, line);
ok_(file, line)(ret_button == expect_button,
"Wrong button. Expected %d, got %d\n", expect_button, ret_button);
+ ok_(file, line)(ret_radio == expect_radio_button,
+ "Wrong radio button. Expected %d, got %d\n", expect_radio_button, ret_radio);
heap_free(msg_start);
}
@@ -239,16 +317,17 @@ static void test_callback(void)
info.pfCallback = taskdialog_callback_proc;
info.lpCallbackData = test_ref_data;
- run_test(&info, IDOK, msg_return_press_ok, "Press VK_RETURN.");
+ run_test(&info, IDOK, 0, msg_return_press_ok, "Press VK_RETURN.");
}
static void test_buttons(void)
{
TASKDIALOGCONFIG info = {0};
- TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS];
+ TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS], radio_buttons[TEST_NUM_RADIO_BUTTONS];
const WCHAR button_format[] = {'%','0','2','d',0};
- WCHAR button_titles[TEST_NUM_BUTTONS * 3]; /* Each button has two digits as title, plus null-terminator */
+ /* Each button has two digits as title, plus null-terminator */
+ WCHAR button_titles[TEST_NUM_BUTTONS * 3], radio_button_titles[TEST_NUM_BUTTONS * 3];
int i;
info.cbSize = sizeof(TASKDIALOGCONFIG);
@@ -266,48 +345,103 @@ static void test_buttons(void)
}
custom_buttons[TEST_NUM_BUTTONS - 1].nButtonID = -1;
+ /* Init radio buttons */
+ for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
+ {
+ WCHAR *text = &radio_button_titles[i * 3];
+ wsprintfW(text, button_format, i);
+
+ radio_buttons[i].pszButtonText = text;
+ radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
+ }
+ radio_buttons[TEST_NUM_RADIO_BUTTONS - 1].nButtonID = -2;
+
/* Test nDefaultButton */
/* Test common buttons with invalid default ID */
info.nDefaultButton = 0; /* Should default to first created button */
info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
| TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
- run_test(&info, IDOK, msg_return_press_ok, "default button: unset default");
+ run_test(&info, IDOK, 0, msg_return_press_ok, "default button: unset default");
info.dwCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
| TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
- run_test(&info, IDYES, msg_return_press_yes, "default button: unset default");
+ run_test(&info, IDYES, 0, msg_return_press_yes, "default button: unset default");
info.dwCommonButtons = TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
- run_test(&info, IDNO, msg_return_press_no, "default button: unset default");
+ run_test(&info, IDNO, 0, msg_return_press_no, "default button: unset default");
info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
- run_test(&info, IDRETRY, msg_return_press_retry, "default button: unset default");
+ run_test(&info, IDRETRY, 0, msg_return_press_retry, "default button: unset default");
info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_CLOSE_BUTTON;
- run_test(&info, IDCANCEL, msg_return_press_cancel, "default button: unset default");
+ run_test(&info, IDCANCEL, 0, msg_return_press_cancel, "default button: unset default");
/* Test with all common and custom buttons and invalid default ID */
info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
info.cButtons = TEST_NUM_BUTTONS;
info.pButtons = custom_buttons;
- run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 1");
+ run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, with common buttons - 1");
info.nDefaultButton = -1; /* Should work despite button ID -1 */
- run_test(&info, -1, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
+ run_test(&info, -1, 0, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
info.nDefaultButton = -2; /* Should also default to first created button */
- run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 3");
+ run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, with common buttons - 3");
/* Test with only custom buttons and invalid default ID */
info.dwCommonButtons = 0;
- run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, no common buttons");
+ run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, no common buttons");
/* Test with common and custom buttons and valid default ID */
info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
| TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
info.nDefaultButton = IDRETRY;
- run_test(&info, IDRETRY, msg_return_press_retry, "default button: valid default - 1");
+ run_test(&info, IDRETRY, 0, msg_return_press_retry, "default button: valid default - 1");
/* Test with common and custom buttons and valid default ID */
info.nDefaultButton = ID_START_BUTTON + 3;
- run_test(&info, ID_START_BUTTON + 3, msg_return_press_custom4, "default button: valid default - 2");
+ run_test(&info, ID_START_BUTTON + 3, 0, msg_return_press_custom4, "default button: valid default - 2");
+
+ /* Test radio buttons */
+ info.nDefaultButton = 0;
+ info.cButtons = 0;
+ info.pButtons = 0;
+ info.dwCommonButtons = TDCBF_OK_BUTTON;
+ info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
+ info.pRadioButtons = radio_buttons;
+
+ /* Test default first radio button */
+ run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_1, "default radio button: default first radio button");
+
+ /* Test default radio button */
+ info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
+ run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_2, "default radio button: default radio button");
+
+ /* Test default radio button with -2 */
+ info.nDefaultRadioButton = -2;
+ run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_3, "default radio button: default radio button with id -2");
+
+ /* Test default radio button after clicking the first, messages still work even radio button is disabled */
+ info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
+ run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_first_radio_button, "default radio button: radio button after clicking");
+
+ /* Test radio button after disabling and clicking the first */
+ info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
+ run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_clicking_disabled, "default radio button: disable radio button before clicking");
+
+ /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set, TDN_RADIO_BUTTON_CLICKED will still be received, just radio button not selected */
+ info.nDefaultRadioButton = ID_START_RADIO_BUTTON;
+ info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
+ run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_no_default_radio_button_flag, "default radio button: no default radio flag");
+
+ /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is 0.
+ * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
+ info.nDefaultRadioButton = 0;
+ info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
+ run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default radio id and flag");
+
+ /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is invalid.
+ * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
+ info.nDefaultRadioButton = 0xff;
+ info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
+ run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default flag, invalid id");
}
static void test_help(void)
@@ -319,7 +453,7 @@ static void test_help(void)
info.lpCallbackData = test_ref_data;
info.dwCommonButtons = TDCBF_OK_BUTTON;
- run_test(&info, IDOK, msg_got_tdn_help, "send f1");
+ run_test(&info, IDOK, 0, msg_got_tdn_help, "send f1");
}
struct timer_notification_data
--
2.17.1
June 26, 2018
[PATCH v2 1/3] comctl32/taskdialog: Use dynamic buffer for taskdialog_get_label_size().
by Zhiyi Zhang
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/comctl32/taskdialog.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
index 33fb578910..5625f2bc24 100644
--- a/dlls/comctl32/taskdialog.c
+++ b/dlls/comctl32/taskdialog.c
@@ -235,7 +235,7 @@ static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND
HFONT hfont, old_hfont;
HDC hdc;
RECT rect = {0};
- WCHAR text[1024];
+ WCHAR *text;
INT text_length;
if (syslink)
@@ -250,7 +250,15 @@ static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND
style |= DT_LEFT;
hfont = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
- text_length = GetWindowTextW(hwnd, text, ARRAY_SIZE(text));
+ text_length = GetWindowTextLengthW(hwnd);
+ text = Alloc((text_length + 1) * sizeof(WCHAR));
+ if (!text)
+ {
+ size->cx = 0;
+ size->cy = 0;
+ return;
+ }
+ GetWindowTextW(hwnd, text, text_length + 1);
hdc = GetDC(hwnd);
old_hfont = SelectObject(hdc, hfont);
rect.right = max_width;
@@ -258,6 +266,7 @@ static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND
size->cx = min(max_width, rect.right - rect.left);
if (old_hfont) SelectObject(hdc, old_hfont);
ReleaseDC(hwnd, hdc);
+ Free(text);
}
static ULONG_PTR taskdialog_get_standard_icon(LPCWSTR icon)
--
2.17.1
June 26, 2018
Re: [PATCH v2 4/4] winemac.drv: Implement waking up the display when activity occurs.
by Ken Thomases
This prevents display sleep and/or wakes a sleeping display, but doesn't prevent the screensaver from kicking in. We don't know why and don't see any other suitable API, so:
Signed-off-by: Ken Thomases <ken(a)codeweavers.com>
June 25, 2018
[PATCH 3/3] wsdapi: Send Probe Matches message via UDP unicast.
by Owen Rudge
Signed-off-by: Owen Rudge <orudge(a)codeweavers.com>
---
dlls/wsdapi/network.c | 32 ++++++++++++++++++++++++++++++++
dlls/wsdapi/soap.c | 4 ++--
dlls/wsdapi/tests/discovery.c | 22 +++++++++++-----------
dlls/wsdapi/wsdapi_internal.h | 1 +
4 files changed, 46 insertions(+), 13 deletions(-)
June 25, 2018
[PATCH 2/3] wsdapi: Implement generation of ProbeMatches message.
by Owen Rudge
Signed-off-by: Owen Rudge <orudge(a)codeweavers.com>
---
dlls/wsdapi/soap.c | 169
+++++++++++++++++++++++++++++++++++++++++-
dlls/wsdapi/tests/discovery.c | 2 +-
2 files changed, 169 insertions(+), 2 deletions(-)
June 25, 2018
[PATCH 1/3] wsdapi: Implement matching of names in MatchProbeEx.
by Owen Rudge
Signed-off-by: Owen Rudge <orudge(a)codeweavers.com>
---
dlls/wsdapi/discovery.c | 58
++++++++++++++++++++++++++++++++++++++++---
dlls/wsdapi/soap.c | 9 +++++++
dlls/wsdapi/wsdapi_internal.h | 6 +++++
3 files changed, 69 insertions(+), 4 deletions(-)
June 25, 2018
wine-3.0.2-rc3 Available
by Michael Stefaniuc
Hello guys,
I have pushed wine-3.0.2-rc3 (with tag) to
https://github.com/mstefani/wine-stable/tree/stable
http://static-winehq.193b.starter-ca-central-1.openshiftapps.com/stable/
Changes since rc2:
- Added "ddraw: Fix D3DEXECUTEDATA.dwSize handling." as that is a
dependency for "ddraw: Don't read past the end of the executebuffer."
bye
michael
June 25, 2018
Re: [PATCH v2] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Zebediah Figura
On 25/06/18 15:09, Alexandre Julliard wrote:
> Zebediah Figura <z.figura12(a)gmail.com> writes:
>
>> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
>> ---
>> dlls/hnetcfg/apps.c | 17 ++++++++++++-----
>> dlls/hnetcfg/tests/policy.c | 5 ++++-
>> 2 files changed, 16 insertions(+), 6 deletions(-)
>
> It doesn't work here:
>
> ../../../tools/runtest -q -P wine -T ../../.. -M hnetcfg.dll -p hnetcfg_test.exe.so policy && touch policy.ok
> 0009:err:seh:raise_exception Unhandled exception code c0000005 flags 0 addr 0x7bc4ed69
> Makefile:183: recipe for target 'policy.ok' failed
>
Sorry I'm so sloppy today. Updated version sent.
June 25, 2018
[PATCH v3] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/hnetcfg/apps.c | 17 ++++++++++++-----
dlls/hnetcfg/tests/policy.c | 5 ++++-
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/dlls/hnetcfg/apps.c b/dlls/hnetcfg/apps.c
index 34ef108..69eabd6 100644
--- a/dlls/hnetcfg/apps.c
+++ b/dlls/hnetcfg/apps.c
@@ -268,7 +268,7 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
{
fw_app *This = impl_from_INetFwAuthorizedApplication( iface );
UNIVERSAL_NAME_INFOW *info;
- WCHAR *netpath;
+ WCHAR *path;
DWORD res;
DWORD sz;
@@ -281,22 +281,29 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, NULL, &sz);
if (res == WN_MORE_DATA)
{
- if (!(netpath = heap_alloc(sz)))
+ if (!(path = heap_alloc(sz)))
return E_OUTOFMEMORY;
- info = (UNIVERSAL_NAME_INFOW *)&netpath;
+ info = (UNIVERSAL_NAME_INFOW *)&path;
res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
if (res == NO_ERROR)
{
SysFreeString(This->filename);
This->filename = SysAllocString(info->lpUniversalName);
}
- heap_free(netpath);
+ heap_free(path);
return HRESULT_FROM_WIN32(res);
}
+ sz = GetFullPathNameW(image, 0, NULL, NULL);
+ if (!(path = heap_alloc(++sz * sizeof(WCHAR))))
+ return E_OUTOFMEMORY;
+
+ GetFullPathNameW(image, sz, path, NULL);
+
SysFreeString( This->filename );
- This->filename = SysAllocString(image);
+ This->filename = SysAllocString(path);
+ heap_free(path);
return This->filename ? S_OK : E_OUTOFMEMORY;
}
diff --git a/dlls/hnetcfg/tests/policy.c b/dlls/hnetcfg/tests/policy.c
index f2d1372..954af5c 100644
--- a/dlls/hnetcfg/tests/policy.c
+++ b/dlls/hnetcfg/tests/policy.c
@@ -107,6 +107,7 @@ static void test_NetFwAuthorizedApplication(void)
INetFwAuthorizedApplication *app;
static WCHAR empty[] = {0};
UNIVERSAL_NAME_INFOW *info;
+ WCHAR fullpath[MAX_PATH];
WCHAR netpath[MAX_PATH];
WCHAR image[MAX_PATH];
HRESULT hr;
@@ -138,13 +139,15 @@ static void test_NetFwAuthorizedApplication(void)
ok(hr == S_OK, "got: %08x\n", hr);
SysFreeString(bstr);
+ GetFullPathNameW(image, ARRAY_SIZE(fullpath), fullpath, NULL);
+
info = (UNIVERSAL_NAME_INFOW *)&netpath;
sz = sizeof(netpath);
hr = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
if (hr != NO_ERROR)
{
info->lpUniversalName = netpath + sizeof(*info)/sizeof(WCHAR);
- lstrcpyW(info->lpUniversalName, image);
+ lstrcpyW(info->lpUniversalName, fullpath);
}
hr = INetFwAuthorizedApplication_get_ProcessImageFileName(app, &bstr);
--
2.7.4
June 25, 2018
Re: [PATCH v2] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Alexandre Julliard
Zebediah Figura <z.figura12(a)gmail.com> writes:
> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> ---
> dlls/hnetcfg/apps.c | 17 ++++++++++++-----
> dlls/hnetcfg/tests/policy.c | 5 ++++-
> 2 files changed, 16 insertions(+), 6 deletions(-)
It doesn't work here:
../../../tools/runtest -q -P wine -T ../../.. -M hnetcfg.dll -p hnetcfg_test.exe.so policy && touch policy.ok
0009:err:seh:raise_exception Unhandled exception code c0000005 flags 0 addr 0x7bc4ed69
Makefile:183: recipe for target 'policy.ok' failed
--
Alexandre Julliard
julliard(a)winehq.org
June 25, 2018
[PATCH v2 4/4] winemac.drv: Implement waking up the display when activity occurs.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/winemac.drv/macdrv_main.c | 12 ++++++++++++
dlls/winemac.drv/winemac.drv.spec | 3 +++
2 files changed, 15 insertions(+)
diff --git a/dlls/winemac.drv/macdrv_main.c b/dlls/winemac.drv/macdrv_main.c
index 491ab06..ea0beec 100644
--- a/dlls/winemac.drv/macdrv_main.c
+++ b/dlls/winemac.drv/macdrv_main.c
@@ -451,3 +451,15 @@ BOOL CDECL macdrv_SystemParametersInfo( UINT action, UINT int_param, void *ptr_p
}
return FALSE;
}
+
+/***********************************************************************
+ * wine_notify_activity (MACDRV.@)
+ *
+ * Notify the display server that activity has occurred, e.g. to wake up
+ * the display and reset any power management related timeouts.
+ */
+void CDECL macdrv_notify_activity(void)
+{
+ static IOPMAssertionID assertion;
+ IOPMAssertionDeclareUserActivity(CFSTR("Wine user input"), kIOPMUserActiveLocal, &assertion);
+}
diff --git a/dlls/winemac.drv/winemac.drv.spec b/dlls/winemac.drv/winemac.drv.spec
index 6fa723a..9658fad 100644
--- a/dlls/winemac.drv/winemac.drv.spec
+++ b/dlls/winemac.drv/winemac.drv.spec
@@ -45,6 +45,9 @@
@ cdecl WindowPosChanged(long long long ptr ptr ptr ptr ptr) macdrv_WindowPosChanged
@ cdecl WindowPosChanging(long long long ptr ptr ptr ptr) macdrv_WindowPosChanging
+# Desktop
+@ cdecl wine_notify_activity() macdrv_notify_activity
+
# System tray
@ cdecl wine_notify_icon(long ptr)
--
2.7.4
June 25, 2018
[PATCH v2 3/4] winex11.drv: Implement waking up the display when activity occurs.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/winex11.drv/winex11.drv.spec | 1 +
dlls/winex11.drv/x11drv_main.c | 12 ++++++++++++
2 files changed, 13 insertions(+)
diff --git a/dlls/winex11.drv/winex11.drv.spec b/dlls/winex11.drv/winex11.drv.spec
index 614f0b9..c833edb 100644
--- a/dlls/winex11.drv/winex11.drv.spec
+++ b/dlls/winex11.drv/winex11.drv.spec
@@ -57,6 +57,7 @@
# Desktop
@ cdecl wine_create_desktop(long long) X11DRV_create_desktop
+@ cdecl wine_notify_activity() X11DRV_notify_activity
# System tray
@ cdecl wine_notify_icon(long ptr)
diff --git a/dlls/winex11.drv/x11drv_main.c b/dlls/winex11.drv/x11drv_main.c
index 4654556..0dbd4f6 100644
--- a/dlls/winex11.drv/x11drv_main.c
+++ b/dlls/winex11.drv/x11drv_main.c
@@ -739,3 +739,15 @@ BOOL CDECL X11DRV_SystemParametersInfo( UINT action, UINT int_param, void *ptr_p
}
return FALSE; /* let user32 handle it */
}
+
+/***********************************************************************
+ * wine_notify_activity (X11DRV.@)
+ *
+ * Notify the display server that activity has occurred, e.g. to wake up
+ * the display and reset any power management related timeouts.
+ */
+void CDECL X11DRV_notify_activity(void)
+{
+ XResetScreenSaver( gdi_display );
+ XFlush( gdi_display );
+}
--
2.7.4
June 25, 2018
[PATCH v2 2/4] dinput: Notify the desktop window when device input is received.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/dinput/device.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 7b83a39..daa6406 100644
--- a/dlls/dinput/device.c
+++ b/dlls/dinput/device.c
@@ -39,6 +39,8 @@
#include "device_private.h"
#include "dinput_private.h"
+#define WM_WINE_NOTIFY_ACTIVITY WM_USER
+
WINE_DEFAULT_DEBUG_CHANNEL(dinput);
static inline IDirectInputDeviceImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface)
@@ -935,6 +937,8 @@ void queue_event(LPDIRECTINPUTDEVICE8A iface, int inst_id, DWORD data, DWORD tim
/* Event is being set regardless of the queue state */
if (This->hEvent) SetEvent(This->hEvent);
+ SendMessageW(GetDesktopWindow(), WM_WINE_NOTIFY_ACTIVITY, 0, 0);
+
if (!This->queue_len || This->overflow || ofs < 0) return;
next_pos = (This->queue_head + 1) % This->queue_len;
--
2.7.4
June 25, 2018
[PATCH v2 1/4] explorer: Add a private message to notify the graphics driver when activity occurs.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
programs/explorer/desktop.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/programs/explorer/desktop.c b/programs/explorer/desktop.c
index a2d9e1a..f5a01c2 100644
--- a/programs/explorer/desktop.c
+++ b/programs/explorer/desktop.c
@@ -46,6 +46,10 @@ static const WCHAR default_driver[] = {'m','a','c',',','x','1','1',0};
static const WCHAR default_driver[] = {'x','1','1',0};
#endif
+static void (CDECL *wine_notify_activity)(void);
+
+#define WM_WINE_NOTIFY_ACTIVITY WM_USER
+
static BOOL using_root;
struct launcher
@@ -661,6 +665,11 @@ static LRESULT WINAPI desktop_wnd_proc( HWND hwnd, UINT message, WPARAM wp, LPAR
}
return 0;
+ case WM_WINE_NOTIFY_ACTIVITY:
+ if (wine_notify_activity)
+ wine_notify_activity();
+ return 0;
+
default:
return DefWindowProcW( hwnd, message, wp, lp );
}
@@ -1005,6 +1014,8 @@ void manage_desktop( WCHAR *arg )
{
pShellDDEInit( TRUE );
}
+
+ wine_notify_activity = (void *)GetProcAddress( graphics_driver, "wine_notify_activity" );
}
}
--
2.7.4
June 25, 2018
[PATCH] gdi32/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/gdi32/tests/bitmap.c | 10 ++++-----
dlls/gdi32/tests/brush.c | 2 +-
dlls/gdi32/tests/dc.c | 6 +++---
dlls/gdi32/tests/dib.c | 38 ++++++++++++++++-----------------
dlls/gdi32/tests/font.c | 52 ++++++++++++++++++++++-----------------------
dlls/gdi32/tests/gdiobj.c | 2 +-
dlls/gdi32/tests/icm.c | 2 +-
dlls/gdi32/tests/metafile.c | 7 +++---
dlls/gdi32/tests/path.c | 14 ++++++------
dlls/gdi32/tests/pen.c | 2 +-
10 files changed, 67 insertions(+), 68 deletions(-)
diff --git a/dlls/gdi32/tests/bitmap.c b/dlls/gdi32/tests/bitmap.c
index a4002c83b5..4748691791 100644
--- a/dlls/gdi32/tests/bitmap.c
+++ b/dlls/gdi32/tests/bitmap.c
@@ -84,7 +84,7 @@ static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHE
SetLastError(0xdeadbeef);
test_size[0] = bm.bmWidthBytes * bm.bmHeight;
/* NULL output buffer with different count values */
- for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(test_size); i++)
{
ret = GetBitmapBits(hbm, test_size[i], NULL);
ok(ret == bm.bmWidthBytes * bm.bmHeight, "%d != %d\n", ret, bm.bmWidthBytes * bm.bmHeight);
@@ -94,7 +94,7 @@ static void test_bitmap_info(HBITMAP hbm, INT expected_depth, const BITMAPINFOHE
memset(buf_cmp, 0, bm.bmWidthBytes * bm.bmHeight);
/* Correct output buffer with different count values */
- for (i = 0; i < sizeof(test_size) / sizeof(test_size[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(test_size); i++)
{
int expect = i == 1 ? 0 : bm.bmWidthBytes * bm.bmHeight;
memset(buf, 0xAA, sizeof(buf));
@@ -1745,7 +1745,7 @@ static void test_mono_bitmap(void)
SelectObject( hdc, hbmp );
- for (col = 0; col < sizeof(colors) / sizeof(colors[0]); col++)
+ for (col = 0; col < ARRAY_SIZE(colors); col++)
{
SetTextColor( hdc, colors[col][0] );
SetBkColor( hdc, colors[col][1] );
@@ -2690,7 +2690,7 @@ static void test_select_object(void)
DeleteObject(hbm);
- for(i = 0; i < sizeof(depths)/sizeof(depths[0]); i++) {
+ for(i = 0; i < ARRAY_SIZE(depths); i++) {
/* test a color bitmap to dc bpp matching */
planes = GetDeviceCaps(hdc, PLANES);
bpp = GetDeviceCaps(hdc, BITSPIXEL);
@@ -5710,7 +5710,7 @@ static void test_D3DKMTCreateDCFromMemory( void )
status = pD3DKMTCreateDCFromMemory( NULL );
ok(status == STATUS_INVALID_PARAMETER, "Got unexpected status %#x.\n", status);
- for (i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
+ for (i = 0; i < ARRAY_SIZE(test_data); ++i)
{
memset( data, 0xaa, sizeof(data) );
diff --git a/dlls/gdi32/tests/brush.c b/dlls/gdi32/tests/brush.c
index 1a10429c05..a3ebb91e1e 100644
--- a/dlls/gdi32/tests/brush.c
+++ b/dlls/gdi32/tests/brush.c
@@ -48,7 +48,7 @@ static void test_solidbrush(void)
size_t i;
INT ret;
- for(i=0; i<sizeof(stock)/sizeof(stock[0]); i++) {
+ for(i = 0; i < ARRAY_SIZE(stock); i++) {
solidBrush = CreateSolidBrush(stock[i].color);
if(stock[i].stockobj != -1) {
diff --git a/dlls/gdi32/tests/dc.c b/dlls/gdi32/tests/dc.c
index 3c1fa603a6..5ad3b31483 100644
--- a/dlls/gdi32/tests/dc.c
+++ b/dlls/gdi32/tests/dc.c
@@ -361,7 +361,7 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
if (GetObjectType( hdc ) == OBJ_METADC)
{
- for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(caps); i++)
ok( GetDeviceCaps( hdc, caps[i] ) == (caps[i] == TECHNOLOGY ? DT_METAFILE : 0),
"wrong caps on %s for %u: %u\n", descr, caps[i],
GetDeviceCaps( hdc, caps[i] ) );
@@ -384,7 +384,7 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
}
else
{
- for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(caps); i++)
{
INT precision = 0;
INT hdc_caps = GetDeviceCaps( hdc, caps[i] );
@@ -506,7 +506,7 @@ static void test_device_caps( HDC hdc, HDC ref_dc, const char *descr, int scale
dib = CreateDIBSection( ref_dc, info, DIB_RGB_COLORS, NULL, NULL, 0 );
old = SelectObject( hdc, dib );
- for (i = 0; i < sizeof(caps)/sizeof(caps[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(caps); i++)
ok( GetDeviceCaps( hdc, caps[i] ) == GetDeviceCaps( ref_dc, caps[i] ),
"mismatched caps on %s and DIB for %u: %u/%u\n", descr, caps[i],
GetDeviceCaps( hdc, caps[i] ), GetDeviceCaps( ref_dc, caps[i] ) );
diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c
index e3f188749d..d16cb0df5c 100644
--- a/dlls/gdi32/tests/dib.c
+++ b/dlls/gdi32/tests/dib.c
@@ -1559,7 +1559,7 @@ static const POINT polypoly_lines[] =
static const DWORD polypoly_counts[] =
{
- sizeof(polypoly_lines)/sizeof(polypoly_lines[0])
+ ARRAY_SIZE(polypoly_lines)
};
static const RECT patblt_clips[] =
@@ -1816,7 +1816,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
}
compare_hash(hdc, bmi, bits, "diagonal solid lines");
- for(i = 0; i < sizeof(bias_check) / sizeof(bias_check[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(bias_check); i++)
{
MoveToEx(hdc, bias_check[i].left, bias_check[i].top, NULL);
LineTo(hdc, bias_check[i].right, bias_check[i].bottom);
@@ -1851,21 +1851,21 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
ExtSelectClipRgn(hdc, hrgn, RGN_COPY);
DeleteObject(hrgn2);
- for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(hline_clips); i++)
{
MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
}
compare_hash(hdc, bmi, bits, "clipped solid hlines");
- for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(vline_clips); i++)
{
MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
}
compare_hash(hdc, bmi, bits, "clipped solid vlines");
- for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(line_clips); i++)
{
MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
@@ -1873,7 +1873,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
compare_hash(hdc, bmi, bits, "clipped solid diagonal lines");
/* clipped PatBlt */
- for(i = 0; i < sizeof(patblt_clips) / sizeof(patblt_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(patblt_clips); i++)
{
PatBlt(hdc, patblt_clips[i].left, patblt_clips[i].top,
patblt_clips[i].right - patblt_clips[i].left,
@@ -1887,35 +1887,35 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
SetBkMode(hdc, TRANSPARENT);
SetBkColor(hdc, RGB(0, 0xff, 0));
- for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(hline_clips); i++)
{
MoveToEx(hdc, hline_clips[i].left, hline_clips[i].top, NULL);
LineTo(hdc, hline_clips[i].right, hline_clips[i].bottom);
}
compare_hash(hdc, bmi, bits, "clipped dashed hlines");
- for(i = 0; i < sizeof(hline_clips)/sizeof(hline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(hline_clips); i++)
{
MoveToEx(hdc, hline_clips[i].right - 1, hline_clips[i].bottom, NULL);
LineTo(hdc, hline_clips[i].left - 1, hline_clips[i].top);
}
compare_hash(hdc, bmi, bits, "clipped dashed hlines r -> l");
- for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(vline_clips); i++)
{
MoveToEx(hdc, vline_clips[i].left, vline_clips[i].top, NULL);
LineTo(hdc, vline_clips[i].right, vline_clips[i].bottom);
}
compare_hash(hdc, bmi, bits, "clipped dashed vlines");
- for(i = 0; i < sizeof(vline_clips)/sizeof(vline_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(vline_clips); i++)
{
MoveToEx(hdc, vline_clips[i].right, vline_clips[i].bottom - 1, NULL);
LineTo(hdc, vline_clips[i].left, vline_clips[i].top - 1);
}
compare_hash(hdc, bmi, bits, "clipped dashed vlines b -> t");
- for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(line_clips); i++)
{
MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
@@ -1924,7 +1924,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
SetBkMode(hdc, OPAQUE);
- for(i = 0; i < sizeof(line_clips)/sizeof(line_clips[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(line_clips); i++)
{
MoveToEx(hdc, line_clips[i].left, line_clips[i].top, NULL);
LineTo(hdc, line_clips[i].right, line_clips[i].bottom);
@@ -2163,13 +2163,13 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
SelectObject(hdc, solid_pen);
SelectObject(hdc, solid_brush);
- for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(rectangles); i++)
{
Rectangle(hdc, rectangles[i].left, rectangles[i].top, rectangles[i].right, rectangles[i].bottom);
}
SelectObject(hdc, dashed_pen);
- for(i = 0; i < sizeof(rectangles)/sizeof(rectangles[0]); i++)
+ for(i = 0; i < ARRAY_SIZE(rectangles); i++)
{
Rectangle(hdc, rectangles[i].left, rectangles[i].top + 150, rectangles[i].right, rectangles[i].bottom + 150);
}
@@ -2775,7 +2775,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
wide_pen = CreatePen( PS_SOLID, 7, RGB( 0xff, 0, 0 ) );
SelectObject( hdc, wide_pen );
- for (i = 0; i < sizeof( wide_lines ) / sizeof( wide_lines[0] ); i++)
+ for (i = 0; i < ARRAY_SIZE(wide_lines); i++)
{
MoveToEx( hdc, wide_lines[i].left, wide_lines[i].top, NULL );
LineTo( hdc, wide_lines[i].right, wide_lines[i].bottom );
@@ -2794,7 +2794,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
9, &log_brush, 0, NULL );
SelectObject( hdc, wide_pen );
SetBrushOrgEx( hdc, 3, 3, NULL );
- Polyline( hdc, poly_lines, sizeof(poly_lines) / sizeof(poly_lines[0]) );
+ Polyline( hdc, poly_lines, ARRAY_SIZE( poly_lines ));
compare_hash_broken_todo( hdc, bmi, bits, "wide pen - flat caps, mitred", is_ddb, is_ddb );
SetBrushOrgEx( hdc, 0, 0, NULL );
@@ -2805,7 +2805,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
16, &log_brush, 0, NULL );
SelectObject( hdc, wide_pen );
- Polyline( hdc, poly_lines, sizeof(poly_lines) / sizeof(poly_lines[0]) );
+ Polyline( hdc, poly_lines, ARRAY_SIZE( poly_lines ));
compare_hash_broken_todo( hdc, bmi, bits, "wide pen - square caps, bevelled", is_ddb, is_ddb );
SelectObject( hdc, orig_pen );
@@ -2815,7 +2815,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
9, &log_brush, 0, NULL );
SelectObject( hdc, wide_pen );
- PolyPolyline( hdc, polypoly_lines, polypoly_counts, sizeof(polypoly_counts)/sizeof(polypoly_counts[0]) );
+ PolyPolyline( hdc, polypoly_lines, polypoly_counts, ARRAY_SIZE( polypoly_counts ));
compare_hash_broken_todo( hdc, bmi, bits, "wide pen - empty segments", is_ddb, is_ddb );
SelectObject( hdc, orig_pen );
@@ -2833,7 +2833,7 @@ static void draw_graphics(HDC hdc, const BITMAPINFO *bmi, BYTE *bits)
12, &log_brush, 0, NULL );
ok( wide_pen != 0, "failed to create pen\n" );
SelectObject( hdc, wide_pen );
- Polyline( hdc, poly_lines, sizeof(poly_lines) / sizeof(poly_lines[0]) );
+ Polyline( hdc, poly_lines, ARRAY_SIZE( poly_lines ));
for (i = 1; i < 20; i++)
{
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 6243a6d339..8f5454b918 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -937,7 +937,7 @@ static void test_bitmap_font_metrics(void)
screen_log_pixels = GetDeviceCaps(hdc, LOGPIXELSY);
diff = 32768;
font_res = 0;
- for (i = 0; i < sizeof(font_log_pixels)/sizeof(font_log_pixels[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(font_log_pixels); i++)
{
int new_diff = abs(font_log_pixels[i] - screen_log_pixels);
if (new_diff < diff)
@@ -948,7 +948,7 @@ static void test_bitmap_font_metrics(void)
}
trace("best font resolution is %d\n", font_res);
- for (i = 0; i < sizeof(fd)/sizeof(fd[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(fd); i++)
{
int bit, height;
@@ -1190,7 +1190,7 @@ static void test_GetCharABCWidths(void)
UINT cs;
UINT a;
UINT w;
- BOOL r[sizeof range / sizeof range[0]];
+ BOOL r[ARRAY_SIZE(range)];
} c[] =
{
{ANSI_CHARSET, 0x30, 0x30,
@@ -1253,7 +1253,7 @@ static void test_GetCharABCWidths(void)
hfont = SelectObject(hdc, hfont);
DeleteObject(hfont);
- for (i = 0; i < sizeof c / sizeof c[0]; ++i)
+ for (i = 0; i < ARRAY_SIZE(c); ++i)
{
ABC a[2], w[2];
ABC full[256];
@@ -1285,7 +1285,7 @@ static void test_GetCharABCWidths(void)
ok(memcmp(&a[0], &full[code], sizeof(ABC)) == 0,
"GetCharABCWidthsA info should match. codepage = %u\n", c[i].cs);
- for (j = 0; j < sizeof range / sizeof range[0]; ++j)
+ for (j = 0; j < ARRAY_SIZE(range); ++j)
{
memset(full, 0xdd, sizeof full);
ret = pGetCharABCWidthsA(hdc, range[j].first, range[j].last, full);
@@ -1774,7 +1774,7 @@ static void test_GetKerningPairs(void)
return;
}
- for (i = 0; i < sizeof(kd)/sizeof(kd[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(kd); i++)
{
OUTLINETEXTMETRICW otm;
UINT uiRet;
@@ -2095,7 +2095,7 @@ static void test_height_selection_vdmx( HDC hdc )
return;
}
- for (i = 0; i < sizeof(data) / sizeof(data[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(data); i++)
{
res = get_res_data( "wine_vdmx.ttf", &size );
@@ -2356,7 +2356,7 @@ static void testJustification(HDC hdc, PCSTR str, RECT *clientArea)
{
SetTextJustification(hdc, areaWidth - size.cx, breakCount);
GetTextExtentPoint32A(hdc, pFirstChar, pLastChar - pFirstChar, &size);
- if (size.cx != areaWidth && nErrors < sizeof(error)/sizeof(error[0]) - 1)
+ if (size.cx != areaWidth && nErrors < ARRAY_SIZE(error) - 1)
{
error[nErrors].start = pFirstChar;
error[nErrors].len = pLastChar - pFirstChar;
@@ -2613,7 +2613,7 @@ static void test_font_charset(void)
return;
}
- for (i = 0; i < sizeof(cd)/sizeof(cd[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(cd); i++)
{
if (cd[i].charset == SYMBOL_CHARSET)
{
@@ -2687,7 +2687,7 @@ static void test_GdiGetCodePage(void)
acp = GetACP();
- for (i = 0; i < sizeof(matching_data) / sizeof(struct _matching_data); i++)
+ for (i = 0; i < ARRAY_SIZE(matching_data); i++)
{
/* only test data matched current locale codepage */
if (matching_data[i].current_codepage != acp)
@@ -3700,7 +3700,7 @@ static int match_name_table_language( const sfnt_name *name, LANGID lang )
break;
case TT_PLATFORM_MACINTOSH:
if (!IsValidCodePage( get_mac_code_page( name ))) return 0;
- if (GET_BE_WORD(name->language_id) >= sizeof(mac_langid_table)/sizeof(mac_langid_table[0])) return 0;
+ if (GET_BE_WORD(name->language_id) >= ARRAY_SIZE(mac_langid_table)) return 0;
name_lang = mac_langid_table[GET_BE_WORD(name->language_id)];
break;
case TT_PLATFORM_APPLE_UNICODE:
@@ -3710,7 +3710,7 @@ static int match_name_table_language( const sfnt_name *name, LANGID lang )
case TT_APPLE_ID_DEFAULT:
case TT_APPLE_ID_ISO_10646:
case TT_APPLE_ID_UNICODE_2_0:
- if (GET_BE_WORD(name->language_id) >= sizeof(mac_langid_table)/sizeof(mac_langid_table[0])) return 0;
+ if (GET_BE_WORD(name->language_id) >= ARRAY_SIZE(mac_langid_table)) return 0;
name_lang = mac_langid_table[GET_BE_WORD(name->language_id)];
break;
default:
@@ -4105,7 +4105,7 @@ static void test_nonexistent_font(void)
hdc = CreateCompatibleDC(0);
- for (i = 0; i < sizeof(shell_subst)/sizeof(shell_subst[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(shell_subst); i++)
{
ret = is_font_installed(shell_subst[i].name);
ok(ret || broken(!ret) /* win2000 */, "%s should be enumerated\n", shell_subst[i].name);
@@ -4201,7 +4201,7 @@ todo_wine /* Wine uses Arial for all substitutions */
ok(cs == ANSI_CHARSET, "expected ANSI_CHARSET, got %d\n", cs);
DeleteObject(SelectObject(hdc, hfont));
- for (i = 0; i < sizeof(font_subst)/sizeof(font_subst[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(font_subst); i++)
{
ret = is_font_installed(font_subst[i].name);
todo_wine
@@ -4487,8 +4487,8 @@ static void test_GetTextFace(void)
dc = GetDC(NULL);
g = SelectObject(dc, f);
- n = GetTextFaceW(dc, sizeof bufW / sizeof bufW[0], bufW);
- ok(n == sizeof faceW / sizeof faceW[0], "GetTextFaceW returned %d\n", n);
+ n = GetTextFaceW(dc, ARRAY_SIZE(bufW), bufW);
+ ok(n == ARRAY_SIZE(faceW), "GetTextFaceW returned %d\n", n);
ok(lstrcmpW(faceW, bufW) == 0, "GetTextFaceW\n");
/* Play with the count arg. */
@@ -4508,7 +4508,7 @@ static void test_GetTextFace(void)
ok(bufW[0] == faceW[0] && bufW[1] == '\0', "GetTextFaceW didn't copy\n");
n = GetTextFaceW(dc, 0, NULL);
- ok(n == sizeof faceW / sizeof faceW[0], "GetTextFaceW returned %d\n", n);
+ ok(n == ARRAY_SIZE(faceW), "GetTextFaceW returned %d\n", n);
DeleteObject(SelectObject(dc, g));
ReleaseDC(NULL, dc);
@@ -4719,7 +4719,7 @@ static void test_GetGlyphOutline(void)
if (GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
ok(ret == GDI_ERROR, "GetGlyphOutlineW should return an error when the buffer size is too small.\n");
- for (i = 0; i < sizeof(fmt) / sizeof(fmt[0]); ++i)
+ for (i = 0; i < ARRAY_SIZE(fmt); ++i)
{
DWORD dummy;
@@ -4785,7 +4785,7 @@ static void test_GetGlyphOutline(void)
SelectObject(hdc, old_hfont);
DeleteObject(hfont);
- for (i = 0; i < sizeof c / sizeof c[0]; ++i)
+ for (i = 0; i < ARRAY_SIZE(c); ++i)
{
static const MAT2 rotate_mat = {{0, 0}, {0, -1}, {0, 1}, {0, 0}};
TEXTMETRICA tm;
@@ -4955,7 +4955,7 @@ static void test_CreateFontIndirect(void)
lf.lfItalic = FALSE;
lf.lfWeight = FW_DONTCARE;
- for (i = 0; i < sizeof(TestName)/sizeof(TestName[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(TestName); i++)
{
lstrcpyA(lf.lfFaceName, TestName[i]);
hfont = CreateFontIndirectA(&lf);
@@ -5409,7 +5409,7 @@ static void test_fullname(void)
lf.lfItalic = FALSE;
lf.lfWeight = FW_DONTCARE;
- for (i = 0; i < sizeof(TestName) / sizeof(TestName[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(TestName); i++)
{
if (!is_font_installed_fullname("Lucida Sans", TestName[i]))
{
@@ -6058,7 +6058,7 @@ static void test_vertical_font(void)
ok(hgi != vgi, "same glyph h:%u v:%u\n", hgi, vgi);
- for (i = 0; i < sizeof(face_list)/sizeof(face_list[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(face_list); i++) {
const char* face = face_list[i];
if (!is_truetype_font_installed(face)) {
skip("%s is not installed\n", face);
@@ -6092,7 +6092,7 @@ static void test_east_asian_font_selection(void)
hdc = GetDC(NULL);
- for (i = 0; i < sizeof(charset)/sizeof(charset[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(charset); i++)
{
LOGFONTA lf;
HFONT hfont;
@@ -6214,7 +6214,7 @@ static void test_stock_fonts(void)
};
int i, j;
- for (i = 0; i < sizeof(font)/sizeof(font[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(font); i++)
{
HFONT hfont;
LOGFONTA lf;
@@ -6314,7 +6314,7 @@ static void test_max_height(void)
DeleteObject(SelectObject(hdc, hfont_old));
/* test an invalid value */
- for (i = 0; i < sizeof(invalid_height)/sizeof(invalid_height[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(invalid_height); i++) {
lf.lfHeight = invalid_height[i];
hfont = CreateFontIndirectA(&lf);
hfont_old = SelectObject(hdc, hfont);
@@ -6638,7 +6638,7 @@ static void test_bitmap_font_glyph_index(void)
bmi.bmiHeader.biHeight = 32;
bmi.bmiHeader.biCompression = BI_RGB;
- for (i = 0; i < sizeof(bitmap_font_list)/sizeof(bitmap_font_list[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(bitmap_font_list); i++) {
memset(&lf, 0, sizeof(lf));
lf.lfCharSet = bitmap_font_list[i].charset;
strcpy(lf.lfFaceName, bitmap_font_list[i].face);
diff --git a/dlls/gdi32/tests/gdiobj.c b/dlls/gdi32/tests/gdiobj.c
index 65374ea85d..8f3d01c27d 100644
--- a/dlls/gdi32/tests/gdiobj.c
+++ b/dlls/gdi32/tests/gdiobj.c
@@ -345,7 +345,7 @@ static void test_handles_on_win64(void)
if (sizeof(void*) != 8)
return;
- for (i = 0; i < sizeof(cases)/sizeof(cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(cases); i++)
{
hrgn = CreateRectRgn(10, 10, 20, 20);
hrgn_test = (HRGN)(ULONG_PTR)((ULONG_PTR)hrgn | ((ULONGLONG)cases[i].high << 32) | cases[i].low);
diff --git a/dlls/gdi32/tests/icm.c b/dlls/gdi32/tests/icm.c
index 620809018a..340ebeef55 100644
--- a/dlls/gdi32/tests/icm.c
+++ b/dlls/gdi32/tests/icm.c
@@ -278,7 +278,7 @@ static void test_SetICMProfileW( HDC dc )
return;
}
- len = sizeof(profile)/sizeof(profile[0]);
+ len = ARRAY_SIZE(profile);
ret = GetICMProfileW( dc, &len, profile );
ok(ret, "GetICMProfileW failed %u\n", GetLastError());
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c
index 780b65f1b6..230d1e6d84 100644
--- a/dlls/gdi32/tests/metafile.c
+++ b/dlls/gdi32/tests/metafile.c
@@ -183,7 +183,7 @@ static void test_ExtTextOut(void)
static const RECT rc = { 0, 0, 100, 100 };
BOOL ret;
- assert(sizeof(dx)/sizeof(dx[0]) >= lstrlenA(text));
+ assert(ARRAY_SIZE(dx) >= lstrlenA(text));
/* Win9x doesn't play EMFs on invisible windows */
hwnd = CreateWindowExA(0, "static", NULL, WS_POPUP | WS_VISIBLE,
@@ -3895,8 +3895,7 @@ static void test_emf_GradientFill(void)
* written to the EMF, but is not considered in the bounds
* calculation.
*/
- ret = GdiGradientFill( mf, v, sizeof(v) / sizeof(v[0]), tri, sizeof(tri) / sizeof(tri[0]),
- GRADIENT_FILL_TRIANGLE );
+ ret = GdiGradientFill( mf, v, ARRAY_SIZE(v), tri, ARRAY_SIZE(tri), GRADIENT_FILL_TRIANGLE );
ok( ret, "GradientFill\n" );
hemf = CloseEnhMetaFile( mf );
@@ -4117,7 +4116,7 @@ static void test_emf_WorldTransform(void)
{ "manual modify", TRUE, FALSE }
};
- for(i = 0; i < sizeof(test_data) / sizeof(*test_data); ++i)
+ for(i = 0; i < ARRAY_SIZE(test_data); ++i)
{
hdcMetafile = CreateEnhMetaFileA(GetDC(0), NULL, NULL, NULL);
ok(hdcMetafile != 0, "CreateEnhMetaFileA error %d\n", GetLastError());
diff --git a/dlls/gdi32/tests/path.c b/dlls/gdi32/tests/path.c
index 48ef4f016a..80145fc6b2 100644
--- a/dlls/gdi32/tests/path.c
+++ b/dlls/gdi32/tests/path.c
@@ -495,7 +495,7 @@ static void test_arcto(void)
CloseFigure(hdc);
EndPath(hdc);
- ok_path(hdc, "arcto_path", arcto_path, sizeof(arcto_path)/sizeof(path_test_t));
+ ok_path(hdc, "arcto_path", arcto_path, ARRAY_SIZE(arcto_path));
done:
ReleaseDC(0, hdc);
}
@@ -540,7 +540,7 @@ static void test_anglearc(void)
CloseFigure(hdc);
EndPath(hdc);
- ok_path(hdc, "anglearc_path", anglearc_path, sizeof(anglearc_path)/sizeof(path_test_t));
+ ok_path(hdc, "anglearc_path", anglearc_path, ARRAY_SIZE(anglearc_path));
done:
ReleaseDC(0, hdc);
}
@@ -681,7 +681,7 @@ static void test_polydraw(void)
ok( pos.x == 80 && pos.y == 80, "wrong pos %d,%d\n", pos.x, pos.y );
EndPath(hdc);
- ok_path(hdc, "polydraw_path", polydraw_path, sizeof(polydraw_path)/sizeof(path_test_t));
+ ok_path(hdc, "polydraw_path", polydraw_path, ARRAY_SIZE(polydraw_path));
GetCurrentPositionEx( hdc, &pos );
ok( pos.x == 80 && pos.y == 80, "wrong pos %d,%d\n", pos.x, pos.y );
done:
@@ -966,7 +966,7 @@ static void test_rectangle(void)
SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
EndPath( hdc );
SetMapMode( hdc, MM_TEXT );
- ok_path( hdc, "rectangle_path", rectangle_path, sizeof(rectangle_path)/sizeof(path_test_t) );
+ ok_path( hdc, "rectangle_path", rectangle_path, ARRAY_SIZE(rectangle_path) );
ReleaseDC( 0, hdc );
}
@@ -1327,7 +1327,7 @@ static void test_roundrect(void)
SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
EndPath( hdc );
SetMapMode( hdc, MM_TEXT );
- ok_path( hdc, "roundrect_path", roundrect_path, sizeof(roundrect_path)/sizeof(path_test_t) );
+ ok_path( hdc, "roundrect_path", roundrect_path, ARRAY_SIZE(roundrect_path) );
ReleaseDC( 0, hdc );
}
@@ -1707,7 +1707,7 @@ static void test_ellipse(void)
SetArcDirection( hdc, AD_COUNTERCLOCKWISE );
EndPath( hdc );
SetMapMode( hdc, MM_TEXT );
- ok_path( hdc, "ellipse_path", ellipse_path, sizeof(ellipse_path)/sizeof(path_test_t) );
+ ok_path( hdc, "ellipse_path", ellipse_path, ARRAY_SIZE(ellipse_path) );
}
static const path_test_t all_funcs_path[] =
@@ -1890,7 +1890,7 @@ static void test_all_functions(void)
LineTo( hdc, 150, 150 );
/* FIXME: ExtTextOut */
EndPath( hdc );
- ok_path( hdc, "all_funcs_path", all_funcs_path, sizeof(all_funcs_path)/sizeof(path_test_t) );
+ ok_path( hdc, "all_funcs_path", all_funcs_path, ARRAY_SIZE(all_funcs_path) );
ReleaseDC( 0, hdc );
}
diff --git a/dlls/gdi32/tests/pen.c b/dlls/gdi32/tests/pen.c
index 43f00d8f50..badc585f57 100644
--- a/dlls/gdi32/tests/pen.c
+++ b/dlls/gdi32/tests/pen.c
@@ -72,7 +72,7 @@ static void test_logpen(void)
EXTLOGPEN *ext_pen = (EXTLOGPEN *)elp_buffer;
DWORD *ext_style = ext_pen->elpStyleEntry;
- for (i = 0; i < sizeof(pen)/sizeof(pen[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(pen); i++)
{
trace("%d: testing style %u\n", i, pen[i].style);
--
2.14.4
June 25, 2018
Re: [PATCH] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Zebediah Figura
On 25/06/18 08:20, Nikolay Sivov wrote:
> On 06/25/2018 06:46 AM, Zebediah Figura wrote:
>
>> Should hopefully fix test failures on Windows.
>>
>> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
>> ---
>> dlls/hnetcfg/apps.c | 17 ++++++++++++-----
>> dlls/hnetcfg/tests/policy.c | 5 ++++-
>> 2 files changed, 16 insertions(+), 6 deletions(-)
>>
>> diff --git a/dlls/hnetcfg/apps.c b/dlls/hnetcfg/apps.c
>> index 34ef108..fe47721 100644
>> --- a/dlls/hnetcfg/apps.c
>> +++ b/dlls/hnetcfg/apps.c
>> @@ -268,7 +268,7 @@ static HRESULT WINAPI
>> fw_app_put_ProcessImageFileName(
>> {
>> fw_app *This = impl_from_INetFwAuthorizedApplication( iface );
>> UNIVERSAL_NAME_INFOW *info;
>> - WCHAR *netpath;
>> + WCHAR *path;
>> DWORD res;
>> DWORD sz;
>> @@ -281,22 +281,29 @@ static HRESULT WINAPI
>> fw_app_put_ProcessImageFileName(
>> res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL,
>> NULL, &sz);
>> if (res == WN_MORE_DATA)
>> {
>> - if (!(netpath = heap_alloc(sz)))
>> + if (!(path = heap_alloc(sz)))
>> return E_OUTOFMEMORY;
>> - info = (UNIVERSAL_NAME_INFOW *)&netpath;
>> + info = (UNIVERSAL_NAME_INFOW *)&path;
>> res = WNetGetUniversalNameW(image,
>> UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
>> if (res == NO_ERROR)
>> {
>> SysFreeString(This->filename);
>> This->filename = SysAllocString(info->lpUniversalName);
>> }
>> - heap_free(netpath);
>> + heap_free(path);
>> return HRESULT_FROM_WIN32(res);
>> }
>> + sz = GetFullPathNameW(image, 0, NULL, NULL);
>> + if (!(path = heap_alloc(++sz)))
>> + return E_OUTOFMEMORY;
>> +
>> + GetFullPathNameW(image, sz, path, NULL);
>
> ...
>
>>
>> + GetFullPathNameW(image, sizeof(fullpath), fullpath, NULL);
> ...
>
> This one takes character length I think, not byte length.
>
>
Thanks for the catch; resent.
June 25, 2018
[PATCH v2] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/hnetcfg/apps.c | 17 ++++++++++++-----
dlls/hnetcfg/tests/policy.c | 5 ++++-
2 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/dlls/hnetcfg/apps.c b/dlls/hnetcfg/apps.c
index 34ef108..fe47721 100644
--- a/dlls/hnetcfg/apps.c
+++ b/dlls/hnetcfg/apps.c
@@ -268,7 +268,7 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
{
fw_app *This = impl_from_INetFwAuthorizedApplication( iface );
UNIVERSAL_NAME_INFOW *info;
- WCHAR *netpath;
+ WCHAR *path;
DWORD res;
DWORD sz;
@@ -281,22 +281,29 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, NULL, &sz);
if (res == WN_MORE_DATA)
{
- if (!(netpath = heap_alloc(sz)))
+ if (!(path = heap_alloc(sz)))
return E_OUTOFMEMORY;
- info = (UNIVERSAL_NAME_INFOW *)&netpath;
+ info = (UNIVERSAL_NAME_INFOW *)&path;
res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
if (res == NO_ERROR)
{
SysFreeString(This->filename);
This->filename = SysAllocString(info->lpUniversalName);
}
- heap_free(netpath);
+ heap_free(path);
return HRESULT_FROM_WIN32(res);
}
+ sz = GetFullPathNameW(image, 0, NULL, NULL);
+ if (!(path = heap_alloc(++sz)))
+ return E_OUTOFMEMORY;
+
+ GetFullPathNameW(image, sz, path, NULL);
+
SysFreeString( This->filename );
- This->filename = SysAllocString(image);
+ This->filename = SysAllocString(path);
+ heap_free(path);
return This->filename ? S_OK : E_OUTOFMEMORY;
}
diff --git a/dlls/hnetcfg/tests/policy.c b/dlls/hnetcfg/tests/policy.c
index f2d1372..954af5c 100644
--- a/dlls/hnetcfg/tests/policy.c
+++ b/dlls/hnetcfg/tests/policy.c
@@ -107,6 +107,7 @@ static void test_NetFwAuthorizedApplication(void)
INetFwAuthorizedApplication *app;
static WCHAR empty[] = {0};
UNIVERSAL_NAME_INFOW *info;
+ WCHAR fullpath[MAX_PATH];
WCHAR netpath[MAX_PATH];
WCHAR image[MAX_PATH];
HRESULT hr;
@@ -138,13 +139,15 @@ static void test_NetFwAuthorizedApplication(void)
ok(hr == S_OK, "got: %08x\n", hr);
SysFreeString(bstr);
+ GetFullPathNameW(image, ARRAY_SIZE(fullpath), fullpath, NULL);
+
info = (UNIVERSAL_NAME_INFOW *)&netpath;
sz = sizeof(netpath);
hr = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
if (hr != NO_ERROR)
{
info->lpUniversalName = netpath + sizeof(*info)/sizeof(WCHAR);
- lstrcpyW(info->lpUniversalName, image);
+ lstrcpyW(info->lpUniversalName, fullpath);
}
hr = INetFwAuthorizedApplication_get_ProcessImageFileName(app, &bstr);
--
2.7.4
June 25, 2018
[PATCH] hnetcfg: GetModuleFileNameW gets characters, not bytes (Coverity)
by Marcus Meissner
CID 1437516
Signed-off-by: Marcus Meissner <meissner(a)suse.de>
---
dlls/hnetcfg/tests/policy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/hnetcfg/tests/policy.c b/dlls/hnetcfg/tests/policy.c
index f2d1372ba6..b28535d448 100644
--- a/dlls/hnetcfg/tests/policy.c
+++ b/dlls/hnetcfg/tests/policy.c
@@ -117,7 +117,7 @@ static void test_NetFwAuthorizedApplication(void)
&IID_INetFwAuthorizedApplication, (void**)&app);
ok(hr == S_OK, "got: %08x\n", hr);
- hr = GetModuleFileNameW(NULL, image, sizeof(image));
+ hr = GetModuleFileNameW(NULL, image, ARRAY_SIZE(image));
ok(hr, "GetModuleFileName failed: %u\n", GetLastError());
hr = INetFwAuthorizedApplication_get_ProcessImageFileName(app, NULL);
--
2.17.1
June 25, 2018
[PATCH v3] comctl32/imagelist: fix ImageList_Read
by Denis Malikov
Fix for versions x600 and x620 and pointer calculation for mixing image and mask bits.
Tested on *.reg files extracted from:
- XP/2003 key HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\TrayNotify;
- Vista/7 key HKEY_CLASSES_ROOT\Local Settings\Software\Microsoft\Windows\CurrentVersion\TrayNotify
Signed-off-by: Denis Malikov <mdn40000(a)mail.ru>
---
dlls/comctl32/imagelist.c | 16 ++++++++++------
1 file changed, 10 insertions(+), 6 deletions(-)
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index a08d60752e..be901462a0 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -2267,7 +2267,9 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
return NULL;
if (ilHead.usMagic != (('L' << 8) | 'I'))
return NULL;
- if (ilHead.usVersion != 0x101) /* probably version? */
+ if (ilHead.usVersion != 0x101 &&
+ ilHead.usVersion != 0x600 && /* XP/2003 version */
+ ilHead.usVersion != 0x620) /* Vista/7 version */
return NULL;
TRACE("cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n",
@@ -2296,23 +2298,25 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
{
DWORD *ptr = image_bits;
BYTE *mask_ptr = mask_bits;
- int stride = himl->cy * image_info->bmiHeader.biWidth;
+ int stride = himl->cy * (ilHead.usVersion != 0x101 ? himl->cx : image_info->bmiHeader.biWidth);
+ int image_step = ilHead.usVersion != 0x101 ? 1 : TILE_COUNT;
+ int mask_step = ilHead.usVersion != 0x101 ? 4 : 8;
if (image_info->bmiHeader.biHeight > 0) /* bottom-up */
{
ptr += image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride;
- mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / 8;
+ mask_ptr += (image_info->bmiHeader.biHeight * image_info->bmiHeader.biWidth - stride) / mask_step;
stride = -stride;
image_info->bmiHeader.biHeight = himl->cy;
}
else image_info->bmiHeader.biHeight = -himl->cy;
- for (i = 0; i < ilHead.cCurImage; i += TILE_COUNT)
+ for (i = 0; i < ilHead.cCurImage; i += image_step)
{
- add_dib_bits( himl, i, min( ilHead.cCurImage - i, TILE_COUNT ),
+ add_dib_bits( himl, i, min( ilHead.cCurImage - i, image_step ),
himl->cx, himl->cy, image_info, mask_info, ptr, mask_ptr );
ptr += stride;
- mask_ptr += stride / 8;
+ mask_ptr += stride / mask_step;
}
}
else
--
2.16.2.windows.1
June 25, 2018
Re: [PATCH] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Nikolay Sivov
On 06/25/2018 06:46 AM, Zebediah Figura wrote:
> Should hopefully fix test failures on Windows.
>
> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> ---
> dlls/hnetcfg/apps.c | 17 ++++++++++++-----
> dlls/hnetcfg/tests/policy.c | 5 ++++-
> 2 files changed, 16 insertions(+), 6 deletions(-)
>
> diff --git a/dlls/hnetcfg/apps.c b/dlls/hnetcfg/apps.c
> index 34ef108..fe47721 100644
> --- a/dlls/hnetcfg/apps.c
> +++ b/dlls/hnetcfg/apps.c
> @@ -268,7 +268,7 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
> {
> fw_app *This = impl_from_INetFwAuthorizedApplication( iface );
> UNIVERSAL_NAME_INFOW *info;
> - WCHAR *netpath;
> + WCHAR *path;
> DWORD res;
> DWORD sz;
>
> @@ -281,22 +281,29 @@ static HRESULT WINAPI fw_app_put_ProcessImageFileName(
> res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, NULL, &sz);
> if (res == WN_MORE_DATA)
> {
> - if (!(netpath = heap_alloc(sz)))
> + if (!(path = heap_alloc(sz)))
> return E_OUTOFMEMORY;
>
> - info = (UNIVERSAL_NAME_INFOW *)&netpath;
> + info = (UNIVERSAL_NAME_INFOW *)&path;
> res = WNetGetUniversalNameW(image, UNIVERSAL_NAME_INFO_LEVEL, &info, &sz);
> if (res == NO_ERROR)
> {
> SysFreeString(This->filename);
> This->filename = SysAllocString(info->lpUniversalName);
> }
> - heap_free(netpath);
> + heap_free(path);
> return HRESULT_FROM_WIN32(res);
> }
>
> + sz = GetFullPathNameW(image, 0, NULL, NULL);
> + if (!(path = heap_alloc(++sz)))
> + return E_OUTOFMEMORY;
> +
> + GetFullPathNameW(image, sz, path, NULL);
...
>
>
> + GetFullPathNameW(image, sizeof(fullpath), fullpath, NULL);
...
This one takes character length I think, not byte length.
June 25, 2018
[PATCH] fonts: Add clock images to Wingdings font. (v2)
by Dmitry Timoshkov
v2: I've created the glyphs on my own.
wingding.ttf should be rebuilt in maintainer mode after applying this patch.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
fonts/wingding.sfd | 760 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 758 insertions(+), 2 deletions(-)
diff --git a/fonts/wingding.sfd b/fonts/wingding.sfd
index c46152b077..d5b7ec871b 100644
--- a/fonts/wingding.sfd
+++ b/fonts/wingding.sfd
@@ -50,9 +50,9 @@ NameList: Adobe Glyph List
DisplaySize: -48
AntiAlias: 1
FitToEm: 1
-WinInfo: 0 29 12
+WinInfo: 0 38 13
TeXData: 1 0 0 708670 354335 236222 1342177 -2147484 236222 783286 444596 497025 792723 393216 433062 380633 303038 157286 324010 404750 52429 2506097 1059062 262144
-BeginChars: 256 38
+BeginChars: 256 50
StartChar: f020
Encoding: 0 61472 0
@@ -788,5 +788,761 @@ LayerCount: 2
Fore
Refer: 34 63724 N 0 1 -1 0 1653 -173 2
EndChar
+
+StartChar: oneoclock
+Encoding: 183 8721 38
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1045.63 1112.56 m 1,0,-1
+ 1117 1081.1 l 1,1,-1
+ 888.373 614.638 l 1,2,-1
+ 817 646.1 l 1,3,-1
+ 1045.63 1112.56 l 1,0,-1
+1045.63 1112.56 m 1,4,-1
+ 1117 1081.1 l 1,5,-1
+ 888.373 614.638 l 1,6,-1
+ 817 646.1 l 1,7,-1
+ 1045.63 1112.56 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: twooclock
+Encoding: 184 8719 39
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1259.61 981.841 m 1,0,-1
+ 1308.09 920.734 l 1,1,-1
+ 888.373 614.638 l 1,2,-1
+ 839.896 675.744 l 1,3,-1
+ 1259.61 981.841 l 1,0,-1
+1259.61 981.841 m 1,4,-1
+ 1308.09 920.734 l 1,5,-1
+ 888.373 614.638 l 1,6,-1
+ 839.896 675.744 l 1,7,-1
+ 1259.61 981.841 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: threeoclock
+Encoding: 185 960 40
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1417 769.1 m 1,0,-1
+ 1492 769.1 l 1,1,-1
+ 1492 682.1 l 1,2,-1
+ 1417 682.1 l 1,3,-1
+ 1417 769.1 l 1,0,-1
+1354 760.1 m 1,4,-1
+ 1357.3 682.17 l 1,5,-1
+ 837.828 681.208 l 1,6,-1
+ 834.522 759.138 l 1,7,-1
+ 1354 760.1 l 1,4,-1
+1354 760.1 m 1,8,-1
+ 1357.3 682.17 l 1,9,-1
+ 837.828 681.208 l 1,10,-1
+ 834.522 759.138 l 1,11,-1
+ 1354 760.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+871 1297.1 m 1,16,-1
+ 949 1297.1 l 1,17,-1
+ 949 595.1 l 1,18,-1
+ 871 595.1 l 1,19,-1
+ 871 1297.1 l 1,16,-1
+868 238.1 m 1,20,-1
+ 943 238.1 l 1,21,-1
+ 943 151.1 l 1,22,-1
+ 868 151.1 l 1,23,-1
+ 868 238.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: fouroclock
+Encoding: 186 8747 41
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1400.73 513.884 m 1,0,-1
+ 1377.42 439.448 l 1,1,-1
+ 888.373 614.638 l 1,2,-1
+ 911.681 689.074 l 1,3,-1
+ 1400.73 513.884 l 1,0,-1
+1400.73 513.884 m 1,4,-1
+ 1377.42 439.448 l 1,5,-1
+ 888.373 614.638 l 1,6,-1
+ 911.681 689.074 l 1,7,-1
+ 1400.73 513.884 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: fiveoclock
+Encoding: 187 170 42
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1169.2 333.396 m 1,0,-1
+ 1105 289.1 l 1,1,-1
+ 827.557 728.283 l 1,2,-1
+ 891.758 772.579 l 1,3,-1
+ 1169.2 333.396 l 1,0,-1
+1169.2 333.396 m 1,4,-1
+ 1105 289.1 l 1,5,-1
+ 827.557 728.283 l 1,6,-1
+ 891.758 772.579 l 1,7,-1
+ 1169.2 333.396 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: sixoclock
+Encoding: 188 186 43
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+872.619 844.557 m 1,0,-1
+ 950.58 847.024 l 1,1,-1
+ 945.961 327.567 l 1,2,-1
+ 868 325.1 l 1,3,-1
+ 872.619 844.557 l 1,0,-1
+872.619 844.557 m 1,4,-1
+ 950.58 847.024 l 1,5,-1
+ 945.961 327.567 l 1,6,-1
+ 868 325.1 l 1,7,-1
+ 872.619 844.557 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: sevenoclock
+Encoding: 189 937 44
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+682 289.1 m 1,0,-1
+ 616.783 331.886 l 1,1,-1
+ 919.107 754.327 l 1,2,-1
+ 984.324 711.541 l 1,3,-1
+ 682 289.1 l 1,0,-1
+682 289.1 m 1,4,-1
+ 616.783 331.886 l 1,5,-1
+ 919.107 754.327 l 1,6,-1
+ 984.324 711.541 l 1,7,-1
+ 682 289.1 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: eightoclock
+Encoding: 190 230 45
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+544.217 438.639 m 1,0,-1
+ 501.419 503.848 l 1,1,-1
+ 946.903 771.055 l 1,2,-1
+ 989.703 705.847 l 1,3,-1
+ 544.217 438.639 l 1,0,-1
+544.217 438.639 m 1,4,-1
+ 501.419 503.848 l 1,5,-1
+ 946.903 771.055 l 1,6,-1
+ 989.703 705.847 l 1,7,-1
+ 544.217 438.639 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: nineoclock
+Encoding: 191 248 46
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+517 679.1 m 1,0,-1
+ 513.82 757.034 l 1,1,-1
+ 1033.3 757.157 l 1,2,-1
+ 1036.48 679.223 l 1,3,-1
+ 517 679.1 l 1,0,-1
+517 679.1 m 1,4,-1
+ 513.82 757.034 l 1,5,-1
+ 1033.3 757.157 l 1,6,-1
+ 1036.48 679.223 l 1,7,-1
+ 517 679.1 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: tenoclock
+Encoding: 192 191 47
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+555.232 898.87 m 1,0,-1
+ 598 964.1 l 1,1,-1
+ 1020.53 661.897 l 1,2,-1
+ 977.762 596.668 l 1,3,-1
+ 555.232 898.87 l 1,0,-1
+555.232 898.87 m 1,4,-1
+ 598 964.1 l 1,5,-1
+ 1020.53 661.897 l 1,6,-1
+ 977.762 596.668 l 1,7,-1
+ 555.232 898.87 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: elevenoclock
+Encoding: 193 161 48
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+693.722 1059.02 m 1,0,-1
+ 758.041 1103.14 l 1,1,-1
+ 1034.32 663.226 l 1,2,-1
+ 970 619.1 l 1,3,-1
+ 693.722 1059.02 l 1,0,-1
+693.722 1059.02 m 1,4,-1
+ 758.041 1103.14 l 1,5,-1
+ 1034.32 663.226 l 1,6,-1
+ 970 619.1 l 1,7,-1
+ 693.722 1059.02 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
+
+StartChar: twelveoclock
+Encoding: 194 172 49
+Width: 1825
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+872.906 1111.69 m 1,0,-1
+ 950.853 1114.57 l 1,1,-1
+ 949 595.1 l 1,2,-1
+ 871.054 592.217 l 1,3,-1
+ 872.906 1111.69 l 1,0,-1
+872.906 1111.69 m 1,4,-1
+ 950.853 1114.57 l 1,5,-1
+ 949 595.1 l 1,6,-1
+ 871.054 592.217 l 1,7,-1
+ 872.906 1111.69 l 1,4,-1
+871 1297.1 m 1,8,-1
+ 949 1297.1 l 1,9,-1
+ 949 595.1 l 1,10,-1
+ 871 595.1 l 1,11,-1
+ 871 1297.1 l 1,8,-1
+871 1297.1 m 1,12,-1
+ 949 1297.1 l 1,13,-1
+ 949 595.1 l 1,14,-1
+ 871 595.1 l 1,15,-1
+ 871 1297.1 l 1,12,-1
+868 238.1 m 1,16,-1
+ 943 238.1 l 1,17,-1
+ 943 151.1 l 1,18,-1
+ 868 151.1 l 1,19,-1
+ 868 238.1 l 1,16,-1
+1408 784.1 m 1,20,-1
+ 1483 784.1 l 1,21,-1
+ 1483 697.1 l 1,22,-1
+ 1408 697.1 l 1,23,-1
+ 1408 784.1 l 1,20,-1
+340 763.1 m 1,24,-1
+ 415 763.1 l 1,25,-1
+ 415 676.1 l 1,26,-1
+ 340 676.1 l 1,27,-1
+ 340 763.1 l 1,24,-1
+438.5 254.1 m 0,28,29
+ 680.837 45.2673 680.837 45.2673 917.027 58.1245 c 0,30,31
+ 1187.65 72.8563 1187.65 72.8563 1382.5 266.1 c 0,32,33
+ 1576.5 458.508 1576.5 458.508 1574.5 734.1 c 0,34,35
+ 1571.93 1022.95 1571.93 1022.95 1414 1180.1 c 0,36,37
+ 1202.96 1390.1 1202.96 1390.1 906.5 1390.1 c 0,38,39
+ 620.354 1390.1 620.354 1390.1 442.5 1198.1 c 0,40,41
+ 236.614 975.839 236.614 975.839 246.5 722.1 c 0,42,43
+ 258.697 409.044 258.697 409.044 438.5 254.1 c 0,28,29
+1430.5 1245.5 m 128,-1,45
+ 1644 1032 1644 1032 1644 730 c 256,46,47
+ 1644 428 1644 428 1430.5 214 c 128,-1,48
+ 1217 0 1217 0 914 0 c 0,49,50
+ 612 0 612 0 398.5 214 c 128,-1,51
+ 185 428 185 428 185 730 c 256,52,53
+ 185 1032 185 1032 398.5 1245.5 c 128,-1,54
+ 612 1459 612 1459 914 1459 c 0,55,44
+ 1217 1459 1217 1459 1430.5 1245.5 c 128,-1,45
+EndSplineSet
+EndChar
EndChars
EndSplineFont
--
2.16.3
June 25, 2018
[PATCH] crypt32: Correctly return how the issuer of a self signed certificate was matched.
by Nikolay Sivov
Original patch by Michael Müller.
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/chain.c | 53 +++++++++++++++-------------------
dlls/crypt32/crypt32_private.h | 2 +-
2 files changed, 24 insertions(+), 31 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index 6e8076c66c..d7015d797d 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -265,10 +265,10 @@ typedef struct _CertificateChain
LONG ref;
} CertificateChain;
-BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
+DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert)
{
+ DWORD size, status = 0;
PCERT_EXTENSION ext;
- DWORD size;
BOOL ret;
if ((ext = CertFindExtension(szOID_AUTHORITY_KEY_IDENTIFIER2,
@@ -296,10 +296,9 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
&info->AuthorityCertIssuer.rgAltEntry[i];
if (directoryName)
{
- ret = CertCompareCertificateName(cert->dwCertEncodingType,
- &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer)
- && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber,
- &cert->pCertInfo->SerialNumber);
+ if (CertCompareCertificateName(cert->dwCertEncodingType, &directoryName->u.DirectoryName, &cert->pCertInfo->Issuer)
+ && CertCompareIntegerBlob(&info->AuthorityCertSerialNumber, &cert->pCertInfo->SerialNumber))
+ status = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
}
else
{
@@ -317,16 +316,12 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
if (buf)
{
- CertGetCertificateContextProperty(cert,
- CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
- ret = !memcmp(buf, info->KeyId.pbData, size);
+ CertGetCertificateContextProperty(cert, CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
+ if (!memcmp(buf, info->KeyId.pbData, size))
+ status = CERT_TRUST_HAS_KEY_MATCH_ISSUER;
CryptMemFree(buf);
}
- else
- ret = FALSE;
}
- else
- ret = FALSE;
}
LocalFree(info);
}
@@ -344,10 +339,9 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
{
if (info->CertIssuer.cbData && info->CertSerialNumber.cbData)
{
- ret = CertCompareCertificateName(cert->dwCertEncodingType,
- &info->CertIssuer, &cert->pCertInfo->Issuer) &&
- CertCompareIntegerBlob(&info->CertSerialNumber,
- &cert->pCertInfo->SerialNumber);
+ if (CertCompareCertificateName(cert->dwCertEncodingType, &info->CertIssuer, &cert->pCertInfo->Issuer)
+ && CertCompareIntegerBlob(&info->CertSerialNumber, &cert->pCertInfo->SerialNumber))
+ status = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
}
else if (info->KeyId.cbData)
{
@@ -361,24 +355,23 @@ BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert)
{
CertGetCertificateContextProperty(cert,
CERT_KEY_IDENTIFIER_PROP_ID, buf, &size);
- ret = !memcmp(buf, info->KeyId.pbData, size);
+ if (!memcmp(buf, info->KeyId.pbData, size))
+ status = CERT_TRUST_HAS_KEY_MATCH_ISSUER;
CryptMemFree(buf);
}
- else
- ret = FALSE;
}
- else
- ret = FALSE;
}
- else
- ret = FALSE;
LocalFree(info);
}
}
else
- ret = CertCompareCertificateName(cert->dwCertEncodingType,
- &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer);
- return ret;
+ if (CertCompareCertificateName(cert->dwCertEncodingType, &cert->pCertInfo->Subject, &cert->pCertInfo->Issuer))
+ status = CERT_TRUST_HAS_NAME_MATCH_ISSUER;
+
+ if (status)
+ status |= CERT_TRUST_IS_SELF_SIGNED;
+
+ return status;
}
static void CRYPT_FreeChainElement(PCERT_CHAIN_ELEMENT element)
@@ -1890,6 +1883,7 @@ static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine,
int i;
BOOL pathLengthConstraintViolated = FALSE;
CERT_BASIC_CONSTRAINTS2_INFO constraints = { FALSE, FALSE, 0 };
+ DWORD status;
TRACE_(chain)("checking chain with %d elements for time %s\n",
chain->cElement, filetime_to_str(time));
@@ -1977,10 +1971,9 @@ static void CRYPT_CheckSimpleChain(CertificateChainEngine *engine,
}
CRYPT_CheckChainNameConstraints(chain);
CRYPT_CheckChainPolicies(chain);
- if (CRYPT_IsCertificateSelfSigned(rootElement->pCertContext))
+ if ((status = CRYPT_IsCertificateSelfSigned(rootElement->pCertContext)))
{
- rootElement->TrustStatus.dwInfoStatus |=
- CERT_TRUST_IS_SELF_SIGNED | CERT_TRUST_HAS_NAME_MATCH_ISSUER;
+ rootElement->TrustStatus.dwInfoStatus |= status;
CRYPT_CheckRootCert(engine->hRoot, rootElement);
}
CRYPT_CombineTrustStatus(&chain->TrustStatus, &rootElement->TrustStatus);
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index dbf6dca411..95ee67c6cb 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -343,7 +343,7 @@ void CRYPT_ImportSystemRootCertsToReg(void) DECLSPEC_HIDDEN;
BOOL CRYPT_SerializeContextsToReg(HKEY key, DWORD flags, const WINE_CONTEXT_INTERFACE *contextInterface,
HCERTSTORE memStore) DECLSPEC_HIDDEN;
-BOOL CRYPT_IsCertificateSelfSigned(PCCERT_CONTEXT cert) DECLSPEC_HIDDEN;
+DWORD CRYPT_IsCertificateSelfSigned(const CERT_CONTEXT *cert) DECLSPEC_HIDDEN;
/* Allocates and initializes a certificate chain engine, but without creating
* the root store. Instead, it uses root, and assumes the caller has done any
--
2.18.0
June 25, 2018
Wine staging 3.11 release
by Alistair Leslie-Hughes
Binary packages for various distributions will be available from:
https://www.winehq.org/download
Summary of the past few weeks
* Rebased to current wine 3.11 (900 patches are applied to wine vanilla)
* Reviewed and upstreamed patches.
Added
* [34989] msi: Implement deferral for standard and custom actions
Where can you help
* Run Steam/Battle.net/UPlay.
* Try you favorite game: Upward lonely robot
* Test your favorite applications.
* Steal staging patches and get them accepted upstream.
As always, if you find a bug, please report it via
https://bugs.winehq.org
Best Regards
Alistair.
June 25, 2018
[PATCH] wininet: Remove checks for negative value.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/wininet/ftp.c | 2 +-
dlls/wininet/http.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/wininet/ftp.c b/dlls/wininet/ftp.c
index e12e494160..9e4da08fdf 100644
--- a/dlls/wininet/ftp.c
+++ b/dlls/wininet/ftp.c
@@ -3290,7 +3290,7 @@ static BOOL FTP_SendData(ftp_session_t *lpwfs, INT nDataSocket, HANDLE hFile)
{
nBytesToSend = nBytesRead - nBytesSent;
- if (nBytesToSend <= 0)
+ if (nBytesToSend == 0)
{
/* Read data from file. */
nBytesSent = 0;
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index b91dbdf175..3e14049b4e 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -6264,7 +6264,7 @@ static DWORD HTTP_InsertCustomHeader(http_request_t *request, LPHTTPHEADERW lpHd
*/
static BOOL HTTP_DeleteCustomHeader(http_request_t *request, DWORD index)
{
- if( request->nCustHeaders <= 0 )
+ if( request->nCustHeaders == 0 )
return FALSE;
if( index >= request->nCustHeaders )
return FALSE;
--
2.17.1
June 25, 2018
[PATCH] msi: Remove checks for negative value.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/msi/format.c | 2 +-
dlls/msi/string.c | 2 +-
dlls/msi/table.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/msi/format.c b/dlls/msi/format.c
index 9356c9e30d..2534b8f6a3 100644
--- a/dlls/msi/format.c
+++ b/dlls/msi/format.c
@@ -242,7 +242,7 @@ static WCHAR *deformat_file( FORMAT *format, FORMSTR *str, BOOL shortname, int *
if ((ret = strdupW( file->TargetPath ))) len = strlenW( ret );
goto done;
}
- if ((len = GetShortPathNameW(file->TargetPath, NULL, 0)) <= 0)
+ if ((len = GetShortPathNameW(file->TargetPath, NULL, 0)) == 0)
{
if ((ret = strdupW( file->TargetPath ))) len = strlenW( ret );
goto done;
diff --git a/dlls/msi/string.c b/dlls/msi/string.c
index f094a53c9e..b0e61e5d76 100644
--- a/dlls/msi/string.c
+++ b/dlls/msi/string.c
@@ -246,7 +246,7 @@ static UINT string2id( const string_table *st, const char *buffer, UINT *id )
}
sz = MultiByteToWideChar( st->codepage, 0, buffer, -1, NULL, 0 );
- if( sz <= 0 )
+ if( sz == 0 )
return r;
str = msi_alloc( sz*sizeof(WCHAR) );
if( !str )
diff --git a/dlls/msi/table.c b/dlls/msi/table.c
index 45a181445a..41e313736f 100644
--- a/dlls/msi/table.c
+++ b/dlls/msi/table.c
@@ -1279,7 +1279,7 @@ static UINT get_table_value_from_record( MSITABLEVIEW *tv, MSIRECORD *rec, UINT
UINT r;
int ival;
- if ( (iField <= 0) ||
+ if ( (iField == 0) ||
(iField > tv->num_cols) ||
MSI_RecordIsNull( rec, iField ) )
return ERROR_FUNCTION_FAILED;
--
2.17.1
June 25, 2018
[PATCH] comctl32: Remove checks for negative value.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/comctl32/rebar.c | 2 +-
dlls/comctl32/tab.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c
index 20ce49b3f9..2d00dfd7ca 100644
--- a/dlls/comctl32/rebar.c
+++ b/dlls/comctl32/rebar.c
@@ -2090,7 +2090,7 @@ REBAR_HandleUDDrag (REBAR_INFO *infoPtr, const POINT *ptsmove)
INT iHitBand, iRowBegin, iNextRowBegin;
REBAR_BAND *hitBand, *rowBeginBand;
- if(infoPtr->uNumBands <= 0)
+ if(infoPtr->uNumBands == 0)
ERR("There are no bands in this rebar\n");
/* Up/down dragging can only occur when there is more than one
diff --git a/dlls/comctl32/tab.c b/dlls/comctl32/tab.c
index f8a54935ca..2e17e142f6 100644
--- a/dlls/comctl32/tab.c
+++ b/dlls/comctl32/tab.c
@@ -365,7 +365,7 @@ static BOOL TAB_InternalGetItemRect(
RECT tmpItemRect,clientRect;
/* Perform a sanity check and a trivial visibility check. */
- if ( (infoPtr->uNumItem <= 0) ||
+ if ( (infoPtr->uNumItem == 0) ||
(itemIndex >= infoPtr->uNumItem) ||
(!(((infoPtr->dwStyle & TCS_MULTILINE) || (infoPtr->dwStyle & TCS_VERTICAL))) &&
(itemIndex < infoPtr->leftmostVisible)))
--
2.17.1
June 25, 2018
[PATCH] advapi32: Remove checks for negative value.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/advapi32/crypt.c | 2 +-
dlls/advapi32/crypt_lmhash.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/advapi32/crypt.c b/dlls/advapi32/crypt.c
index 01d5880423..6ac63e7f08 100644
--- a/dlls/advapi32/crypt.c
+++ b/dlls/advapi32/crypt.c
@@ -661,7 +661,7 @@ BOOL WINAPI CryptReleaseContext (HCRYPTPROV hProv, ULONG_PTR dwFlags)
}
pProv->refcount--;
- if (pProv->refcount <= 0)
+ if (pProv->refcount == 0)
{
ret = pProv->pFuncs->pCPReleaseContext(pProv->hPrivate, dwFlags);
pProv->dwMagic = 0;
diff --git a/dlls/advapi32/crypt_lmhash.c b/dlls/advapi32/crypt_lmhash.c
index 345c89ddb7..de4fce2511 100644
--- a/dlls/advapi32/crypt_lmhash.c
+++ b/dlls/advapi32/crypt_lmhash.c
@@ -196,7 +196,7 @@ NTSTATUS WINAPI SystemFunction004(const struct ustring *in,
unsigned char deskey[7];
unsigned int crypt_len, ofs;
- if (key->Length<=0)
+ if (key->Length==0)
return STATUS_INVALID_PARAMETER_2;
crypt_len = ((in->Length+7)&~7);
@@ -255,7 +255,7 @@ NTSTATUS WINAPI SystemFunction005(const struct ustring *in,
unsigned char deskey[7];
unsigned int ofs, crypt_len;
- if (key->Length<=0)
+ if (key->Length==0)
return STATUS_INVALID_PARAMETER_2;
if (key->Length<sizeof deskey)
--
2.17.1
June 25, 2018
Re: [PATCH 2/3] comctl32/taskdialog: Add support for radio buttons.
by Zhiyi Zhang
On Mon 6 25 13:22, Nikolay Sivov wrote:
>
>
> On 06/17/2018 11:17 AM, Zhiyi Zhang wrote:
>> Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
>> ---
>> dlls/comctl32/taskdialog.c | 130 ++++++++++++++++++++++-
>> dlls/comctl32/tests/taskdialog.c | 172 +++++++++++++++++++++++++++----
>> 2 files changed, 281 insertions(+), 21 deletions(-)
>>
>> diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
>> index 33fb578910..c3c5fa0420 100644
>> --- a/dlls/comctl32/taskdialog.c
>> +++ b/dlls/comctl32/taskdialog.c
>> @@ -58,6 +58,8 @@ struct taskdialog_info
>> HWND main_instruction;
>> HWND content;
>> HWND progress_bar;
>> + HWND *radio_buttons;
>> + INT radio_button_count;
>> HWND *buttons;
>> INT button_count;
>> HWND default_button;
>> @@ -69,6 +71,7 @@ struct taskdialog_info
>> LONG h_spacing;
>> LONG v_spacing;
>> } m;
>> + INT selected_radio_id;
>> };
>> struct button_layout_info
>> @@ -185,6 +188,18 @@ static void taskdialog_enable_button(const struct taskdialog_info *dialog_info,
>> if (hwnd) EnableWindow(hwnd, enable);
>> }
>> +static void taskdialog_enable_radio_button(const struct taskdialog_info *dialog_info, INT id, BOOL enable)
>> +{
>> + HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id);
>> + if (hwnd) EnableWindow(hwnd, enable);
>> +}
>> +
>> +static void taskdialog_click_radio_button(const struct taskdialog_info *dialog_info, INT id)
>> +{
>> + HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id);
>> + if (hwnd) SendMessageW(hwnd, BM_CLICK, 0, 0);
>> +}
>> +
>> static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notification, WPARAM wparam, LPARAM lparam)
>> {
>> const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
>> @@ -193,8 +208,18 @@ static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notif
>> : S_OK;
>> }
>> -static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, WORD command_id)
>> +static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, unsigned long command_id)
>
> Why the type change?
>
In taskdialog_check_default_radio_buttons(), id via GetWindowLongW(default_button, GWLP_ID) is passed to
taskdialog_on_button_click(). And id is originally int in pRadioButtons. So WORD is not enough. Tested on
Windows, 0x1FFFF is allowed as a valid id. And on second thought, an INT should be enough.
>> {
>> + HWND radio_button;
>> +
>> + radio_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, command_id);
>> + if (radio_button)
>> + {
>> + dialog_info->selected_radio_id = command_id;
>> + taskdialog_notify(dialog_info, TDN_RADIO_BUTTON_CLICKED, command_id, 0);
>> + return;
>> + }
>> +
>> if (taskdialog_notify(dialog_info, TDN_BUTTON_CLICKED, command_id, 0) == S_OK)
>> EndDialog(dialog_info->hwnd, command_id);
>> }
>> @@ -260,6 +285,40 @@ static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND
>> ReleaseDC(hwnd, hdc);
>> }
>> +static void taskdialog_get_checkbox_height(struct taskdialog_info *dialog_info, HWND hwnd, LONG max_width, SIZE *size)
>
> Do we call that "checkbox" anywhere in wine? It doesn't feel right.
>
>> +{
>> + DWORD style = DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK;
>> + HFONT hfont, old_hfont;
>> + HDC hdc;
>> + RECT rect = {0};
>> + WCHAR text[1024];
>
> I think it's better to make this dynamic.
>
>> + INT text_length;
>> + LONG text_offset, checkbox_width, checkbox_height;
>> +
>> + hdc = GetDC(hwnd);
>> + hfont = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
>> + old_hfont = SelectObject(hdc, hfont);
>> +
>> + checkbox_width = 12 * GetDeviceCaps(hdc, LOGPIXELSX) / 96 + 1;
>> + checkbox_height = 12 * GetDeviceCaps(hdc, LOGPIXELSY) / 96 + 1;
>> + GetCharWidthW(hdc, '0', '0', &text_offset);
>> + text_offset /= 2;
>> +
>> + if (dialog_info->taskconfig->dwFlags & TDF_RTL_LAYOUT)
>> + style |= DT_RIGHT | DT_RTLREADING;
>> + else
>> + style |= DT_LEFT;
>> +
>> + rect.right = max_width - checkbox_width - text_offset;
>> + text_length = GetWindowTextW(hwnd, text, ARRAY_SIZE(text));
>> + size->cy = DrawTextW(hdc, text, text_length, &rect, style);
>> + size->cx = min(max_width - checkbox_width - text_offset, rect.right - rect.left);
>> + size->cx += checkbox_width + text_offset;
>> + size->cy = max(size->cy, checkbox_height);
>> + if (old_hfont) SelectObject(hdc, old_hfont);
>> + ReleaseDC(hwnd, hdc);
>> +}
>> +
>> static ULONG_PTR taskdialog_get_standard_icon(LPCWSTR icon)
>> {
>> if (icon == TD_WARNING_ICON)
>> @@ -300,6 +359,28 @@ static void taskdialog_set_icon(struct taskdialog_info *dialog_info, INT element
>> }
>> }
>> +static void taskdialog_check_default_radio_buttons(struct taskdialog_info *dialog_info)
>> +{
>> + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
>> + HWND default_button;
>> + INT id;
>> +
>> + if (!dialog_info->radio_button_count) return;
>> +
>> + default_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count,
>> + taskconfig->nDefaultRadioButton);
>> +
>> + if (!default_button && !(taskconfig->dwFlags & TDF_NO_DEFAULT_RADIO_BUTTON))
>> + default_button = dialog_info->radio_buttons[0];
>> +
>> + if (default_button)
>> + {
>> + SendMessageW(default_button, BM_SETCHECK, BST_CHECKED, 0);
>> + id = GetWindowLongW(default_button, GWLP_ID);
>> + taskdialog_on_button_click(dialog_info, id);
>> + }
>> +}
>> +
>> static void taskdialog_add_main_icon(struct taskdialog_info *dialog_info)
>> {
>> if (!dialog_info->taskconfig->u.hMainIcon) return;
>> @@ -363,6 +444,30 @@ static void taskdialog_add_progress_bar(struct taskdialog_info *dialog_info)
>> CreateWindowW(PROGRESS_CLASSW, NULL, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL);
>> }
>> +static void taskdialog_add_radio_buttons(struct taskdialog_info *dialog_info)
>> +{
>> + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
>> + static const DWORD style = BS_AUTORADIOBUTTON | BS_MULTILINE | BS_TOP | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
>> + WCHAR *textW;
>> + INT i;
>> +
>> + if (!taskconfig->cRadioButtons || !taskconfig->pRadioButtons) return;
>> +
>> + dialog_info->radio_buttons = Alloc(taskconfig->cRadioButtons * sizeof(*dialog_info->radio_buttons));
>> + if (!dialog_info->radio_buttons) return;
>> +
>> + dialog_info->radio_button_count = taskconfig->cRadioButtons;
>> + for (i = 0; i < dialog_info->radio_button_count; i++)
>> + {
>> + textW = taskdialog_gettext(dialog_info, TRUE, taskconfig->pRadioButtons[i].pszButtonText);
>> + dialog_info->radio_buttons[i] =
>> + CreateWindowW(WC_BUTTONW, textW, i == 0 ? style | WS_GROUP : style, 0, 0, 0, 0, dialog_info->hwnd,
>> + (HMENU)taskconfig->pRadioButtons[i].nButtonID, 0, NULL);
>> + SendMessageW(dialog_info->radio_buttons[i], WM_SETFONT, (WPARAM)dialog_info->font, 0);
>> + Free(textW);
>> + }
>> +}
>> +
>> static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT_PTR id, const WCHAR *text,
>> BOOL custom_button)
>> {
>> @@ -487,6 +592,17 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info)
>> dialog_height = y + size.cy;
>> }
>> + /* Radio buttons */
>> + for (i = 0; i < dialog_info->radio_button_count; i++)
>> + {
>> + x = main_icon_right + h_spacing;
>> + y = dialog_height;
>> + taskdialog_get_checkbox_height(dialog_info, dialog_info->radio_buttons[i], dialog_width - x - h_spacing, &size);
>> + size.cx = dialog_width - x - h_spacing;
>> + SetWindowPos(dialog_info->radio_buttons[i], 0, x, y, size.cx, size.cy, SWP_NOZORDER);
>> + dialog_height = y + size.cy;
>> + }
>> +
>> dialog_height = max(dialog_height, main_icon_bottom);
>> /* Common and custom buttons */
>> @@ -621,6 +737,7 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd)
>> taskdialog_add_main_instruction(dialog_info);
>> taskdialog_add_content(dialog_info);
>> taskdialog_add_progress_bar(dialog_info);
>> + taskdialog_add_radio_buttons(dialog_info);
>> taskdialog_add_buttons(dialog_info);
>> /* Set default button */
>> @@ -638,6 +755,7 @@ static void taskdialog_destroy(struct taskdialog_info *dialog_info)
>> if (dialog_info->font) DeleteObject(dialog_info->font);
>> if (dialog_info->main_instruction_font) DeleteObject(dialog_info->main_instruction_font);
>> if (dialog_info->buttons) Free(dialog_info->buttons);
>> + if (dialog_info->radio_buttons) Free(dialog_info->radio_buttons);
>> }
>> static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
>> @@ -689,6 +807,12 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
>> case TDM_SET_PROGRESS_BAR_MARQUEE:
>> SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, lParam);
>> break;
>> + case TDM_CLICK_RADIO_BUTTON:
>> + taskdialog_click_radio_button(dialog_info, wParam);
>> + break;
>> + case TDM_ENABLE_RADIO_BUTTON:
>> + taskdialog_enable_radio_button(dialog_info, wParam, lParam);
>> + break;
>> case WM_INITDIALOG:
>> dialog_info = (struct taskdialog_info *)lParam;
>> @@ -697,6 +821,8 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
>> SetPropW(hwnd, taskdialog_info_propnameW, dialog_info);
>> taskdialog_notify(dialog_info, TDN_DIALOG_CONSTRUCTED, 0, 0);
>> taskdialog_notify(dialog_info, TDN_CREATED, 0, 0);
>> + /* Default radio button click notification sent after TDN_CREATED */
>> + taskdialog_check_default_radio_buttons(dialog_info);
>> return FALSE;
>> case WM_COMMAND:
>> if (HIWORD(wParam) == BN_CLICKED)
>> @@ -762,7 +888,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *taskconfig, int *butto
>> Free(template);
>> if (button) *button = ret;
>> - if (radio_button) *radio_button = taskconfig->nDefaultButton;
>> + if (radio_button) *radio_button = dialog_info.selected_radio_id;
>> if (verification_flag_checked) *verification_flag_checked = TRUE;
>> return S_OK;
>> diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
>> index e91a878876..2cda04081f 100644
>> --- a/dlls/comctl32/tests/taskdialog.c
>> +++ b/dlls/comctl32/tests/taskdialog.c
>> @@ -35,9 +35,11 @@
>> #define TASKDIALOG_SEQ_INDEX 0
>> #define TEST_NUM_BUTTONS 10 /* Number of custom buttons to test with */
>> +#define TEST_NUM_RADIO_BUTTONS 3
>> #define ID_START 20 /* Lower IDs might be used by the system */
>> #define ID_START_BUTTON (ID_START + 0)
>> +#define ID_START_RADIO_BUTTON (ID_START + 20)
>> static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
>> static HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *,
>> @@ -141,6 +143,78 @@ static const struct message_info msg_got_tdn_help[] =
>> { 0 }
>> };
>> +/* Three radio buttons */
>> +static const struct message_info msg_return_default_radio_button_1[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, NULL },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_default_radio_button_2[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, NULL },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_send_click_ok },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_default_radio_button_3[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, NULL },
>> + { TDN_RADIO_BUTTON_CLICKED, -2, 0, S_OK, msg_send_click_ok },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_select_first_radio_button[] =
>> +{
>> + { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_first_radio_button[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, NULL },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_radio_button },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_select_first_disabled_radio_button_and_press_ok[] =
>> +{
>> + { TDM_ENABLE_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
>> + { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
>> + { TDM_CLICK_BUTTON, IDOK, 0 },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_default_radio_button_clicking_disabled[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, NULL },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_disabled_radio_button_and_press_ok },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_no_default_radio_button_flag[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
>> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> +static const struct message_info msg_return_no_default_radio_button_id_and_flag[] =
>> +{
>> + { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
>> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
>> + { 0 }
>> +};
>> +
>> static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct message *msg)
>> {
>> msg->message = WM_TD_CALLBACK;
>> @@ -151,11 +225,13 @@ static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct
>> msg->stage = 0;
>> }
>> -#define run_test(info, expect_button, seq, context) \
>> - run_test_(info, expect_button, seq, context, ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
>> +#define run_test(info, expect_button, expect_radio_button, seq, context) \
>> + run_test_(info, expect_button, expect_radio_button, seq, context, \
>> + ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
>> -static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct message_info *test_messages,
>> - const char *context, int test_messages_len, const char *file, int line)
>> +static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio_button,
>> + const struct message_info *test_messages, const char *context, int test_messages_len,
>> + const char *file, int line)
>> {
>> struct message *msg, *msg_start;
>> int ret_button = 0;
>> @@ -182,6 +258,8 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct me
>> ok_sequence_(sequences, TASKDIALOG_SEQ_INDEX, msg_start, context, FALSE, file, line);
>> ok_(file, line)(ret_button == expect_button,
>> "Wrong button. Expected %d, got %d\n", expect_button, ret_button);
>> + ok_(file, line)(ret_radio == expect_radio_button,
>> + "Wrong radio button. Expected %d, got %d\n", expect_radio_button, ret_radio);
>> heap_free(msg_start);
>> }
>> @@ -239,16 +317,17 @@ static void test_callback(void)
>> info.pfCallback = taskdialog_callback_proc;
>> info.lpCallbackData = test_ref_data;
>> - run_test(&info, IDOK, msg_return_press_ok, "Press VK_RETURN.");
>> + run_test(&info, IDOK, 0, msg_return_press_ok, "Press VK_RETURN.");
>> }
>> static void test_buttons(void)
>> {
>> TASKDIALOGCONFIG info = {0};
>> - TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS];
>> + TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS], radio_buttons[TEST_NUM_RADIO_BUTTONS];
>> const WCHAR button_format[] = {'%','0','2','d',0};
>> - WCHAR button_titles[TEST_NUM_BUTTONS * 3]; /* Each button has two digits as title, plus null-terminator */
>> + /* Each button has two digits as title, plus null-terminator */
>> + WCHAR button_titles[TEST_NUM_BUTTONS * 3], radio_button_titles[TEST_NUM_BUTTONS * 3];
>> int i;
>> info.cbSize = sizeof(TASKDIALOGCONFIG);
>> @@ -266,48 +345,103 @@ static void test_buttons(void)
>> }
>> custom_buttons[TEST_NUM_BUTTONS - 1].nButtonID = -1;
>> + /* Init radio buttons */
>> + for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
>> + {
>> + WCHAR *text = &radio_button_titles[i * 3];
>> + wsprintfW(text, button_format, i);
>> +
>> + radio_buttons[i].pszButtonText = text;
>> + radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
>> + }
>> + radio_buttons[TEST_NUM_RADIO_BUTTONS - 1].nButtonID = -2;
>> +
>> /* Test nDefaultButton */
>> /* Test common buttons with invalid default ID */
>> info.nDefaultButton = 0; /* Should default to first created button */
>> info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
>> | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
>> - run_test(&info, IDOK, msg_return_press_ok, "default button: unset default");
>> + run_test(&info, IDOK, 0, msg_return_press_ok, "default button: unset default");
>> info.dwCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
>> | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
>> - run_test(&info, IDYES, msg_return_press_yes, "default button: unset default");
>> + run_test(&info, IDYES, 0, msg_return_press_yes, "default button: unset default");
>> info.dwCommonButtons = TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
>> - run_test(&info, IDNO, msg_return_press_no, "default button: unset default");
>> + run_test(&info, IDNO, 0, msg_return_press_no, "default button: unset default");
>> info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
>> - run_test(&info, IDRETRY, msg_return_press_retry, "default button: unset default");
>> + run_test(&info, IDRETRY, 0, msg_return_press_retry, "default button: unset default");
>> info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_CLOSE_BUTTON;
>> - run_test(&info, IDCANCEL, msg_return_press_cancel, "default button: unset default");
>> + run_test(&info, IDCANCEL, 0, msg_return_press_cancel, "default button: unset default");
>> /* Test with all common and custom buttons and invalid default ID */
>> info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
>> info.cButtons = TEST_NUM_BUTTONS;
>> info.pButtons = custom_buttons;
>> - run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 1");
>> + run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, with common buttons - 1");
>> info.nDefaultButton = -1; /* Should work despite button ID -1 */
>> - run_test(&info, -1, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
>> + run_test(&info, -1, 0, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
>> info.nDefaultButton = -2; /* Should also default to first created button */
>> - run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 3");
>> + run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, with common buttons - 3");
>> /* Test with only custom buttons and invalid default ID */
>> info.dwCommonButtons = 0;
>> - run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, no common buttons");
>> + run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, no common buttons");
>> /* Test with common and custom buttons and valid default ID */
>> info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
>> | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
>> info.nDefaultButton = IDRETRY;
>> - run_test(&info, IDRETRY, msg_return_press_retry, "default button: valid default - 1");
>> + run_test(&info, IDRETRY, 0, msg_return_press_retry, "default button: valid default - 1");
>> /* Test with common and custom buttons and valid default ID */
>> info.nDefaultButton = ID_START_BUTTON + 3;
>> - run_test(&info, ID_START_BUTTON + 3, msg_return_press_custom4, "default button: valid default - 2");
>> + run_test(&info, ID_START_BUTTON + 3, 0, msg_return_press_custom4, "default button: valid default - 2");
>> +
>> + /* Test radio buttons */
>> + info.nDefaultButton = 0;
>> + info.cButtons = 0;
>> + info.pButtons = 0;
>> + info.dwCommonButtons = TDCBF_OK_BUTTON;
>> + info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
>> + info.pRadioButtons = radio_buttons;
>> +
>> + /* Test default first radio button */
>> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_1, "default radio button: default first radio button");
>> +
>> + /* Test default radio button */
>> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
>> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_2, "default radio button: default radio button");
>> +
>> + /* Test default radio button with -2 */
>> + info.nDefaultRadioButton = -2;
>> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_3, "default radio button: default radio button with id -2");
>> +
>> + /* Test default radio button after clicking the first, messages still work even radio button is disabled */
>> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
>> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_first_radio_button, "default radio button: radio button after clicking");
>> +
>> + /* Test radio button after disabling and clicking the first */
>> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
>> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_clicking_disabled, "default radio button: disable radio button before clicking");
>> +
>> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set, TDN_RADIO_BUTTON_CLICKED will still be received, just radio button not selected */
>> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON;
>> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
>> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_no_default_radio_button_flag, "default radio button: no default radio flag");
>> +
>> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is 0.
>> + * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
>> + info.nDefaultRadioButton = 0;
>> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
>> + run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default radio id and flag");
>> +
>> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is invalid.
>> + * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
>> + info.nDefaultRadioButton = 0xff;
>> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
>> + run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default flag, invalid id");
>> }
>> static void test_help(void)
>> @@ -319,7 +453,7 @@ static void test_help(void)
>> info.lpCallbackData = test_ref_data;
>> info.dwCommonButtons = TDCBF_OK_BUTTON;
>> - run_test(&info, IDOK, msg_got_tdn_help, "send f1");
>> + run_test(&info, IDOK, 0, msg_got_tdn_help, "send f1");
>> }
>> struct timer_notification_data
>
>
>
June 25, 2018
Re: [PATCH 2/3] comctl32/taskdialog: Add support for radio buttons.
by Nikolay Sivov
On 06/17/2018 11:17 AM, Zhiyi Zhang wrote:
> Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
> ---
> dlls/comctl32/taskdialog.c | 130 ++++++++++++++++++++++-
> dlls/comctl32/tests/taskdialog.c | 172 +++++++++++++++++++++++++++----
> 2 files changed, 281 insertions(+), 21 deletions(-)
>
> diff --git a/dlls/comctl32/taskdialog.c b/dlls/comctl32/taskdialog.c
> index 33fb578910..c3c5fa0420 100644
> --- a/dlls/comctl32/taskdialog.c
> +++ b/dlls/comctl32/taskdialog.c
> @@ -58,6 +58,8 @@ struct taskdialog_info
> HWND main_instruction;
> HWND content;
> HWND progress_bar;
> + HWND *radio_buttons;
> + INT radio_button_count;
> HWND *buttons;
> INT button_count;
> HWND default_button;
> @@ -69,6 +71,7 @@ struct taskdialog_info
> LONG h_spacing;
> LONG v_spacing;
> } m;
> + INT selected_radio_id;
> };
>
> struct button_layout_info
> @@ -185,6 +188,18 @@ static void taskdialog_enable_button(const struct taskdialog_info *dialog_info,
> if (hwnd) EnableWindow(hwnd, enable);
> }
>
> +static void taskdialog_enable_radio_button(const struct taskdialog_info *dialog_info, INT id, BOOL enable)
> +{
> + HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id);
> + if (hwnd) EnableWindow(hwnd, enable);
> +}
> +
> +static void taskdialog_click_radio_button(const struct taskdialog_info *dialog_info, INT id)
> +{
> + HWND hwnd = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, id);
> + if (hwnd) SendMessageW(hwnd, BM_CLICK, 0, 0);
> +}
> +
> static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notification, WPARAM wparam, LPARAM lparam)
> {
> const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
> @@ -193,8 +208,18 @@ static HRESULT taskdialog_notify(struct taskdialog_info *dialog_info, UINT notif
> : S_OK;
> }
>
> -static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, WORD command_id)
> +static void taskdialog_on_button_click(struct taskdialog_info *dialog_info, unsigned long command_id)
Why the type change?
> {
> + HWND radio_button;
> +
> + radio_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count, command_id);
> + if (radio_button)
> + {
> + dialog_info->selected_radio_id = command_id;
> + taskdialog_notify(dialog_info, TDN_RADIO_BUTTON_CLICKED, command_id, 0);
> + return;
> + }
> +
> if (taskdialog_notify(dialog_info, TDN_BUTTON_CLICKED, command_id, 0) == S_OK)
> EndDialog(dialog_info->hwnd, command_id);
> }
> @@ -260,6 +285,40 @@ static void taskdialog_get_label_size(struct taskdialog_info *dialog_info, HWND
> ReleaseDC(hwnd, hdc);
> }
>
> +static void taskdialog_get_checkbox_height(struct taskdialog_info *dialog_info, HWND hwnd, LONG max_width, SIZE *size)
Do we call that "checkbox" anywhere in wine? It doesn't feel right.
> +{
> + DWORD style = DT_EXPANDTABS | DT_CALCRECT | DT_WORDBREAK;
> + HFONT hfont, old_hfont;
> + HDC hdc;
> + RECT rect = {0};
> + WCHAR text[1024];
I think it's better to make this dynamic.
> + INT text_length;
> + LONG text_offset, checkbox_width, checkbox_height;
> +
> + hdc = GetDC(hwnd);
> + hfont = (HFONT)SendMessageW(hwnd, WM_GETFONT, 0, 0);
> + old_hfont = SelectObject(hdc, hfont);
> +
> + checkbox_width = 12 * GetDeviceCaps(hdc, LOGPIXELSX) / 96 + 1;
> + checkbox_height = 12 * GetDeviceCaps(hdc, LOGPIXELSY) / 96 + 1;
> + GetCharWidthW(hdc, '0', '0', &text_offset);
> + text_offset /= 2;
> +
> + if (dialog_info->taskconfig->dwFlags & TDF_RTL_LAYOUT)
> + style |= DT_RIGHT | DT_RTLREADING;
> + else
> + style |= DT_LEFT;
> +
> + rect.right = max_width - checkbox_width - text_offset;
> + text_length = GetWindowTextW(hwnd, text, ARRAY_SIZE(text));
> + size->cy = DrawTextW(hdc, text, text_length, &rect, style);
> + size->cx = min(max_width - checkbox_width - text_offset, rect.right - rect.left);
> + size->cx += checkbox_width + text_offset;
> + size->cy = max(size->cy, checkbox_height);
> + if (old_hfont) SelectObject(hdc, old_hfont);
> + ReleaseDC(hwnd, hdc);
> +}
> +
> static ULONG_PTR taskdialog_get_standard_icon(LPCWSTR icon)
> {
> if (icon == TD_WARNING_ICON)
> @@ -300,6 +359,28 @@ static void taskdialog_set_icon(struct taskdialog_info *dialog_info, INT element
> }
> }
>
> +static void taskdialog_check_default_radio_buttons(struct taskdialog_info *dialog_info)
> +{
> + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
> + HWND default_button;
> + INT id;
> +
> + if (!dialog_info->radio_button_count) return;
> +
> + default_button = taskdialog_find_button(dialog_info->radio_buttons, dialog_info->radio_button_count,
> + taskconfig->nDefaultRadioButton);
> +
> + if (!default_button && !(taskconfig->dwFlags & TDF_NO_DEFAULT_RADIO_BUTTON))
> + default_button = dialog_info->radio_buttons[0];
> +
> + if (default_button)
> + {
> + SendMessageW(default_button, BM_SETCHECK, BST_CHECKED, 0);
> + id = GetWindowLongW(default_button, GWLP_ID);
> + taskdialog_on_button_click(dialog_info, id);
> + }
> +}
> +
> static void taskdialog_add_main_icon(struct taskdialog_info *dialog_info)
> {
> if (!dialog_info->taskconfig->u.hMainIcon) return;
> @@ -363,6 +444,30 @@ static void taskdialog_add_progress_bar(struct taskdialog_info *dialog_info)
> CreateWindowW(PROGRESS_CLASSW, NULL, style, 0, 0, 0, 0, dialog_info->hwnd, NULL, 0, NULL);
> }
>
> +static void taskdialog_add_radio_buttons(struct taskdialog_info *dialog_info)
> +{
> + const TASKDIALOGCONFIG *taskconfig = dialog_info->taskconfig;
> + static const DWORD style = BS_AUTORADIOBUTTON | BS_MULTILINE | BS_TOP | WS_CHILD | WS_VISIBLE | WS_TABSTOP;
> + WCHAR *textW;
> + INT i;
> +
> + if (!taskconfig->cRadioButtons || !taskconfig->pRadioButtons) return;
> +
> + dialog_info->radio_buttons = Alloc(taskconfig->cRadioButtons * sizeof(*dialog_info->radio_buttons));
> + if (!dialog_info->radio_buttons) return;
> +
> + dialog_info->radio_button_count = taskconfig->cRadioButtons;
> + for (i = 0; i < dialog_info->radio_button_count; i++)
> + {
> + textW = taskdialog_gettext(dialog_info, TRUE, taskconfig->pRadioButtons[i].pszButtonText);
> + dialog_info->radio_buttons[i] =
> + CreateWindowW(WC_BUTTONW, textW, i == 0 ? style | WS_GROUP : style, 0, 0, 0, 0, dialog_info->hwnd,
> + (HMENU)taskconfig->pRadioButtons[i].nButtonID, 0, NULL);
> + SendMessageW(dialog_info->radio_buttons[i], WM_SETFONT, (WPARAM)dialog_info->font, 0);
> + Free(textW);
> + }
> +}
> +
> static void taskdialog_add_button(struct taskdialog_info *dialog_info, HWND *button, INT_PTR id, const WCHAR *text,
> BOOL custom_button)
> {
> @@ -487,6 +592,17 @@ static void taskdialog_layout(struct taskdialog_info *dialog_info)
> dialog_height = y + size.cy;
> }
>
> + /* Radio buttons */
> + for (i = 0; i < dialog_info->radio_button_count; i++)
> + {
> + x = main_icon_right + h_spacing;
> + y = dialog_height;
> + taskdialog_get_checkbox_height(dialog_info, dialog_info->radio_buttons[i], dialog_width - x - h_spacing, &size);
> + size.cx = dialog_width - x - h_spacing;
> + SetWindowPos(dialog_info->radio_buttons[i], 0, x, y, size.cx, size.cy, SWP_NOZORDER);
> + dialog_height = y + size.cy;
> + }
> +
> dialog_height = max(dialog_height, main_icon_bottom);
>
> /* Common and custom buttons */
> @@ -621,6 +737,7 @@ static void taskdialog_init(struct taskdialog_info *dialog_info, HWND hwnd)
> taskdialog_add_main_instruction(dialog_info);
> taskdialog_add_content(dialog_info);
> taskdialog_add_progress_bar(dialog_info);
> + taskdialog_add_radio_buttons(dialog_info);
> taskdialog_add_buttons(dialog_info);
>
> /* Set default button */
> @@ -638,6 +755,7 @@ static void taskdialog_destroy(struct taskdialog_info *dialog_info)
> if (dialog_info->font) DeleteObject(dialog_info->font);
> if (dialog_info->main_instruction_font) DeleteObject(dialog_info->main_instruction_font);
> if (dialog_info->buttons) Free(dialog_info->buttons);
> + if (dialog_info->radio_buttons) Free(dialog_info->radio_buttons);
> }
>
> static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
> @@ -689,6 +807,12 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
> case TDM_SET_PROGRESS_BAR_MARQUEE:
> SendMessageW(dialog_info->progress_bar, PBM_SETMARQUEE, wParam, lParam);
> break;
> + case TDM_CLICK_RADIO_BUTTON:
> + taskdialog_click_radio_button(dialog_info, wParam);
> + break;
> + case TDM_ENABLE_RADIO_BUTTON:
> + taskdialog_enable_radio_button(dialog_info, wParam, lParam);
> + break;
> case WM_INITDIALOG:
> dialog_info = (struct taskdialog_info *)lParam;
>
> @@ -697,6 +821,8 @@ static INT_PTR CALLBACK taskdialog_proc(HWND hwnd, UINT msg, WPARAM wParam, LPAR
> SetPropW(hwnd, taskdialog_info_propnameW, dialog_info);
> taskdialog_notify(dialog_info, TDN_DIALOG_CONSTRUCTED, 0, 0);
> taskdialog_notify(dialog_info, TDN_CREATED, 0, 0);
> + /* Default radio button click notification sent after TDN_CREATED */
> + taskdialog_check_default_radio_buttons(dialog_info);
> return FALSE;
> case WM_COMMAND:
> if (HIWORD(wParam) == BN_CLICKED)
> @@ -762,7 +888,7 @@ HRESULT WINAPI TaskDialogIndirect(const TASKDIALOGCONFIG *taskconfig, int *butto
> Free(template);
>
> if (button) *button = ret;
> - if (radio_button) *radio_button = taskconfig->nDefaultButton;
> + if (radio_button) *radio_button = dialog_info.selected_radio_id;
> if (verification_flag_checked) *verification_flag_checked = TRUE;
>
> return S_OK;
> diff --git a/dlls/comctl32/tests/taskdialog.c b/dlls/comctl32/tests/taskdialog.c
> index e91a878876..2cda04081f 100644
> --- a/dlls/comctl32/tests/taskdialog.c
> +++ b/dlls/comctl32/tests/taskdialog.c
> @@ -35,9 +35,11 @@
> #define TASKDIALOG_SEQ_INDEX 0
>
> #define TEST_NUM_BUTTONS 10 /* Number of custom buttons to test with */
> +#define TEST_NUM_RADIO_BUTTONS 3
>
> #define ID_START 20 /* Lower IDs might be used by the system */
> #define ID_START_BUTTON (ID_START + 0)
> +#define ID_START_RADIO_BUTTON (ID_START + 20)
>
> static HRESULT (WINAPI *pTaskDialogIndirect)(const TASKDIALOGCONFIG *, int *, int *, BOOL *);
> static HRESULT (WINAPI *pTaskDialog)(HWND, HINSTANCE, const WCHAR *, const WCHAR *, const WCHAR *,
> @@ -141,6 +143,78 @@ static const struct message_info msg_got_tdn_help[] =
> { 0 }
> };
>
> +/* Three radio buttons */
> +static const struct message_info msg_return_default_radio_button_1[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, NULL },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_default_radio_button_2[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, NULL },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_send_click_ok },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_default_radio_button_3[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, NULL },
> + { TDN_RADIO_BUTTON_CLICKED, -2, 0, S_OK, msg_send_click_ok },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_select_first_radio_button[] =
> +{
> + { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_first_radio_button[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, NULL },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_radio_button },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, msg_send_click_ok },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_select_first_disabled_radio_button_and_press_ok[] =
> +{
> + { TDM_ENABLE_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
> + { TDM_CLICK_RADIO_BUTTON, ID_START_RADIO_BUTTON, 0 },
> + { TDM_CLICK_BUTTON, IDOK, 0 },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_default_radio_button_clicking_disabled[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, NULL },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON + 1, 0, S_OK, msg_select_first_disabled_radio_button_and_press_ok },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_no_default_radio_button_flag[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
> + { TDN_RADIO_BUTTON_CLICKED, ID_START_RADIO_BUTTON, 0, S_OK, NULL },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> +static const struct message_info msg_return_no_default_radio_button_id_and_flag[] =
> +{
> + { TDN_CREATED, 0, 0, S_OK, msg_send_click_ok },
> + { TDN_BUTTON_CLICKED, IDOK, 0, S_OK, NULL },
> + { 0 }
> +};
> +
> static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct message *msg)
> {
> msg->message = WM_TD_CALLBACK;
> @@ -151,11 +225,13 @@ static void init_test_message(UINT message, WPARAM wParam, LPARAM lParam, struct
> msg->stage = 0;
> }
>
> -#define run_test(info, expect_button, seq, context) \
> - run_test_(info, expect_button, seq, context, ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
> +#define run_test(info, expect_button, expect_radio_button, seq, context) \
> + run_test_(info, expect_button, expect_radio_button, seq, context, \
> + ARRAY_SIZE(seq) - 1, __FILE__, __LINE__)
>
> -static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct message_info *test_messages,
> - const char *context, int test_messages_len, const char *file, int line)
> +static void run_test_(TASKDIALOGCONFIG *info, int expect_button, int expect_radio_button,
> + const struct message_info *test_messages, const char *context, int test_messages_len,
> + const char *file, int line)
> {
> struct message *msg, *msg_start;
> int ret_button = 0;
> @@ -182,6 +258,8 @@ static void run_test_(TASKDIALOGCONFIG *info, int expect_button, const struct me
> ok_sequence_(sequences, TASKDIALOG_SEQ_INDEX, msg_start, context, FALSE, file, line);
> ok_(file, line)(ret_button == expect_button,
> "Wrong button. Expected %d, got %d\n", expect_button, ret_button);
> + ok_(file, line)(ret_radio == expect_radio_button,
> + "Wrong radio button. Expected %d, got %d\n", expect_radio_button, ret_radio);
>
> heap_free(msg_start);
> }
> @@ -239,16 +317,17 @@ static void test_callback(void)
> info.pfCallback = taskdialog_callback_proc;
> info.lpCallbackData = test_ref_data;
>
> - run_test(&info, IDOK, msg_return_press_ok, "Press VK_RETURN.");
> + run_test(&info, IDOK, 0, msg_return_press_ok, "Press VK_RETURN.");
> }
>
> static void test_buttons(void)
> {
> TASKDIALOGCONFIG info = {0};
>
> - TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS];
> + TASKDIALOG_BUTTON custom_buttons[TEST_NUM_BUTTONS], radio_buttons[TEST_NUM_RADIO_BUTTONS];
> const WCHAR button_format[] = {'%','0','2','d',0};
> - WCHAR button_titles[TEST_NUM_BUTTONS * 3]; /* Each button has two digits as title, plus null-terminator */
> + /* Each button has two digits as title, plus null-terminator */
> + WCHAR button_titles[TEST_NUM_BUTTONS * 3], radio_button_titles[TEST_NUM_BUTTONS * 3];
> int i;
>
> info.cbSize = sizeof(TASKDIALOGCONFIG);
> @@ -266,48 +345,103 @@ static void test_buttons(void)
> }
> custom_buttons[TEST_NUM_BUTTONS - 1].nButtonID = -1;
>
> + /* Init radio buttons */
> + for (i = 0; i < TEST_NUM_RADIO_BUTTONS; i++)
> + {
> + WCHAR *text = &radio_button_titles[i * 3];
> + wsprintfW(text, button_format, i);
> +
> + radio_buttons[i].pszButtonText = text;
> + radio_buttons[i].nButtonID = ID_START_RADIO_BUTTON + i;
> + }
> + radio_buttons[TEST_NUM_RADIO_BUTTONS - 1].nButtonID = -2;
> +
> /* Test nDefaultButton */
>
> /* Test common buttons with invalid default ID */
> info.nDefaultButton = 0; /* Should default to first created button */
> info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
> | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
> - run_test(&info, IDOK, msg_return_press_ok, "default button: unset default");
> + run_test(&info, IDOK, 0, msg_return_press_ok, "default button: unset default");
> info.dwCommonButtons = TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
> | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
> - run_test(&info, IDYES, msg_return_press_yes, "default button: unset default");
> + run_test(&info, IDYES, 0, msg_return_press_yes, "default button: unset default");
> info.dwCommonButtons = TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
> - run_test(&info, IDNO, msg_return_press_no, "default button: unset default");
> + run_test(&info, IDNO, 0, msg_return_press_no, "default button: unset default");
> info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
> - run_test(&info, IDRETRY, msg_return_press_retry, "default button: unset default");
> + run_test(&info, IDRETRY, 0, msg_return_press_retry, "default button: unset default");
> info.dwCommonButtons = TDCBF_CANCEL_BUTTON | TDCBF_CLOSE_BUTTON;
> - run_test(&info, IDCANCEL, msg_return_press_cancel, "default button: unset default");
> + run_test(&info, IDCANCEL, 0, msg_return_press_cancel, "default button: unset default");
>
> /* Test with all common and custom buttons and invalid default ID */
> info.nDefaultButton = 0xff; /* Random ID, should also default to first created button */
> info.cButtons = TEST_NUM_BUTTONS;
> info.pButtons = custom_buttons;
> - run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 1");
> + run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, with common buttons - 1");
>
> info.nDefaultButton = -1; /* Should work despite button ID -1 */
> - run_test(&info, -1, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
> + run_test(&info, -1, 0, msg_return_press_custom10, "default button: invalid default, with common buttons - 2");
>
> info.nDefaultButton = -2; /* Should also default to first created button */
> - run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, with common buttons - 3");
> + run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, with common buttons - 3");
>
> /* Test with only custom buttons and invalid default ID */
> info.dwCommonButtons = 0;
> - run_test(&info, ID_START_BUTTON, msg_return_press_custom1, "default button: invalid default, no common buttons");
> + run_test(&info, ID_START_BUTTON, 0, msg_return_press_custom1, "default button: invalid default, no common buttons");
>
> /* Test with common and custom buttons and valid default ID */
> info.dwCommonButtons = TDCBF_OK_BUTTON | TDCBF_YES_BUTTON | TDCBF_NO_BUTTON
> | TDCBF_CANCEL_BUTTON | TDCBF_RETRY_BUTTON | TDCBF_CLOSE_BUTTON;
> info.nDefaultButton = IDRETRY;
> - run_test(&info, IDRETRY, msg_return_press_retry, "default button: valid default - 1");
> + run_test(&info, IDRETRY, 0, msg_return_press_retry, "default button: valid default - 1");
>
> /* Test with common and custom buttons and valid default ID */
> info.nDefaultButton = ID_START_BUTTON + 3;
> - run_test(&info, ID_START_BUTTON + 3, msg_return_press_custom4, "default button: valid default - 2");
> + run_test(&info, ID_START_BUTTON + 3, 0, msg_return_press_custom4, "default button: valid default - 2");
> +
> + /* Test radio buttons */
> + info.nDefaultButton = 0;
> + info.cButtons = 0;
> + info.pButtons = 0;
> + info.dwCommonButtons = TDCBF_OK_BUTTON;
> + info.cRadioButtons = TEST_NUM_RADIO_BUTTONS;
> + info.pRadioButtons = radio_buttons;
> +
> + /* Test default first radio button */
> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_1, "default radio button: default first radio button");
> +
> + /* Test default radio button */
> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_2, "default radio button: default radio button");
> +
> + /* Test default radio button with -2 */
> + info.nDefaultRadioButton = -2;
> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_default_radio_button_3, "default radio button: default radio button with id -2");
> +
> + /* Test default radio button after clicking the first, messages still work even radio button is disabled */
> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_first_radio_button, "default radio button: radio button after clicking");
> +
> + /* Test radio button after disabling and clicking the first */
> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON + 1;
> + run_test(&info, IDOK, ID_START_RADIO_BUTTON, msg_return_default_radio_button_clicking_disabled, "default radio button: disable radio button before clicking");
> +
> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set, TDN_RADIO_BUTTON_CLICKED will still be received, just radio button not selected */
> + info.nDefaultRadioButton = ID_START_RADIO_BUTTON;
> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
> + run_test(&info, IDOK, info.nDefaultRadioButton, msg_return_no_default_radio_button_flag, "default radio button: no default radio flag");
> +
> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is 0.
> + * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
> + info.nDefaultRadioButton = 0;
> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
> + run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default radio id and flag");
> +
> + /* Test no default radio button, TDF_NO_DEFAULT_RADIO_BUTTON is set and nDefaultRadioButton is invalid.
> + * TDN_RADIO_BUTTON_CLICKED will not be sent, and just radio button not selected */
> + info.nDefaultRadioButton = 0xff;
> + info.dwFlags = TDF_NO_DEFAULT_RADIO_BUTTON;
> + run_test(&info, IDOK, 0, msg_return_no_default_radio_button_id_and_flag, "default radio button: no default flag, invalid id");
> }
>
> static void test_help(void)
> @@ -319,7 +453,7 @@ static void test_help(void)
> info.lpCallbackData = test_ref_data;
> info.dwCommonButtons = TDCBF_OK_BUTTON;
>
> - run_test(&info, IDOK, msg_got_tdn_help, "send f1");
> + run_test(&info, IDOK, 0, msg_got_tdn_help, "send f1");
> }
>
> struct timer_notification_data
June 25, 2018