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] 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