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 1/3] comctl32/taskdialog: Fix buttons might disappear.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
June 25, 2018
Re: [PATCH v2] comctl32/imagelist: fix ImageList_Read/Write.
by Nikolay Sivov
On 06/21/2018 05:53 PM, Denis Malikov wrote:
> diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
> index a08d60752e..eadbf134b4 100644
> --- a/dlls/comctl32/imagelist.c
> +++ b/dlls/comctl32/imagelist.c
> @@ -80,9 +80,11 @@ struct _IMAGELIST
> BOOL color_table_set;
>
> LONG ref; /* reference count */
> + USHORT usVersion; /* keep stream version here */
> };
Now this new field is not used anywhere.
June 25, 2018
[PATCH] user.exe16: Fix handling of DDL_DRIVES flag in DlgDirList.
by Alistair Leslie-Hughes
From: Alex Villacís Lasso <a_villacis(a)palosanto.com>
Fixes: https://bugs.winehq.org/show_bug.cgi?id=18734
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/user.exe16/dialog.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/user.exe16/dialog.c b/dlls/user.exe16/dialog.c
index e5bf7b9..385e859 100644
--- a/dlls/user.exe16/dialog.c
+++ b/dlls/user.exe16/dialog.c
@@ -636,7 +636,7 @@ INT16 WINAPI DlgDirList16( HWND16 hDlg, LPSTR spec, INT16 idLBox,
* be set automatically (this is different in Win32, and
* DIALOG_DlgDirList sends Win32 messages to the control,
* so do it here) */
- if (attrib & DDL_DRIVES) attrib |= DDL_EXCLUSIVE;
+ if (attrib == DDL_DRIVES) attrib |= DDL_EXCLUSIVE;
return DlgDirListA( WIN_Handle32(hDlg), spec, idLBox, idStatic, attrib );
}
--
1.9.1
June 25, 2018
[PATCH] hnetcfg: Store the full path in INetFwAuthorizedApplication_put_ProcessImageFileName().
by Zebediah Figura
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);
+
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..7791926 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, sizeof(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] loader: Register mp3dmod DMO.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
loader/wine.inf.in | 1 +
1 file changed, 1 insertion(+)
diff --git a/loader/wine.inf.in b/loader/wine.inf.in
index 90fb151..e844d65 100644
--- a/loader/wine.inf.in
+++ b/loader/wine.inf.in
@@ -2511,6 +2511,7 @@ HKLM,%CurrentVersion%\Telephony\Country List\998,"SameAreaRule",,"G"
11,,cryptdlg.dll,1
11,,cryptnet.dll,1
11,,devenum.dll,1
+11,,mp3dmod.dll,1
11,,mscoree.dll,1
11,,mshtml.dll,1
11,,msisip.dll,1
--
2.7.4
June 24, 2018
[PATCH 2/2] devenum: Implement enumerating DMOs.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/mediacatenum.c | 57 ++++++++++++++++++++++++++++++++++++--------
dlls/devenum/tests/devenum.c | 2 ++
2 files changed, 49 insertions(+), 10 deletions(-)
diff --git a/dlls/devenum/mediacatenum.c b/dlls/devenum/mediacatenum.c
index c0efae0..c4338a2 100644
--- a/dlls/devenum/mediacatenum.c
+++ b/dlls/devenum/mediacatenum.c
@@ -36,6 +36,7 @@ typedef struct
IEnumMoniker IEnumMoniker_iface;
CLSID class;
LONG ref;
+ IEnumDMO *dmo_enum;
HKEY sw_key;
DWORD sw_index;
HKEY cm_key;
@@ -845,6 +846,7 @@ static ULONG WINAPI DEVENUM_IEnumMoniker_Release(IEnumMoniker *iface)
if (!ref)
{
+ IEnumDMO_Release(This->dmo_enum);
RegCloseKey(This->sw_key);
RegCloseKey(This->cm_key);
CoTaskMemFree(This);
@@ -862,16 +864,31 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
LONG res;
ULONG fetched = 0;
MediaCatMoniker * pMoniker;
+ WCHAR *name;
+ CLSID clsid;
+ HRESULT hr;
HKEY hkey;
TRACE("(%p)->(%d, %p, %p)\n", iface, celt, rgelt, pceltFetched);
while (fetched < celt)
{
- /* FIXME: try PNP devices and DMOs first */
+ /* FIXME: try PNP devices first */
+ /* try DMOs */
+ if ((hr = IEnumDMO_Next(This->dmo_enum, 1, &clsid, &name, NULL)) == S_OK)
+ {
+ if (!(pMoniker = DEVENUM_IMediaCatMoniker_Construct()))
+ return E_OUTOFMEMORY;
+
+ pMoniker->type = DEVICE_DMO;
+ pMoniker->clsid = clsid;
+
+ StringFromGUID2(&clsid, buffer, CHARS_IN_GUID);
+ StringFromGUID2(&This->class, buffer + CHARS_IN_GUID - 1, CHARS_IN_GUID);
+ }
/* try DirectShow filters */
- if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, sizeof(buffer)/sizeof(WCHAR))))
+ else if (!(res = RegEnumKeyW(This->sw_key, This->sw_index, buffer, sizeof(buffer)/sizeof(WCHAR))))
{
This->sw_index++;
if ((res = RegOpenKeyExW(This->sw_key, buffer, 0, KEY_QUERY_VALUE, &hkey)))
@@ -881,6 +898,13 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
return E_OUTOFMEMORY;
pMoniker->type = DEVICE_FILTER;
+
+ if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR))))
+ {
+ IMoniker_Release(&pMoniker->IMoniker_iface);
+ return E_OUTOFMEMORY;
+ }
+ strcpyW(pMoniker->name, buffer);
}
/* then try codecs */
else if (!(res = RegEnumKeyW(This->cm_key, This->cm_index, buffer, sizeof(buffer)/sizeof(WCHAR))))
@@ -894,16 +918,17 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Next(IEnumMoniker *iface, ULONG celt,
return E_OUTOFMEMORY;
pMoniker->type = DEVICE_CODEC;
+
+ if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR))))
+ {
+ IMoniker_Release(&pMoniker->IMoniker_iface);
+ return E_OUTOFMEMORY;
+ }
+ strcpyW(pMoniker->name, buffer);
}
else
break;
- if (!(pMoniker->name = CoTaskMemAlloc((strlenW(buffer) + 1) * sizeof(WCHAR))))
- {
- IMoniker_Release(&pMoniker->IMoniker_iface);
- return E_OUTOFMEMORY;
- }
- strcpyW(pMoniker->name, buffer);
pMoniker->has_class = TRUE;
pMoniker->class = This->class;
@@ -930,10 +955,13 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Skip(IEnumMoniker *iface, ULONG celt)
while (celt--)
{
- /* FIXME: try PNP devices and DMOs first */
+ /* FIXME: try PNP devices first */
+ /* try DMOs */
+ if (IEnumDMO_Skip(This->dmo_enum, 1) == S_OK)
+ ;
/* try DirectShow filters */
- if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) != ERROR_NO_MORE_ITEMS)
+ else if (RegEnumKeyW(This->sw_key, This->sw_index, NULL, 0) != ERROR_NO_MORE_ITEMS)
{
This->sw_index++;
}
@@ -955,6 +983,7 @@ static HRESULT WINAPI DEVENUM_IEnumMoniker_Reset(IEnumMoniker *iface)
TRACE("(%p)->()\n", iface);
+ IEnumDMO_Reset(This->dmo_enum);
This->sw_index = 0;
This->cm_index = 0;
@@ -986,6 +1015,7 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
{
EnumMonikerImpl * pEnumMoniker = CoTaskMemAlloc(sizeof(EnumMonikerImpl));
WCHAR buffer[78];
+ HRESULT hr;
if (!pEnumMoniker)
return E_OUTOFMEMORY;
@@ -1007,6 +1037,13 @@ HRESULT create_EnumMoniker(REFCLSID class, IEnumMoniker **ppEnumMoniker)
if (RegOpenKeyExW(HKEY_CURRENT_USER, buffer, 0, KEY_ENUMERATE_SUB_KEYS, &pEnumMoniker->cm_key))
pEnumMoniker->cm_key = NULL;
+ hr = DMOEnum(class, 0, 0, NULL, 0, NULL, &pEnumMoniker->dmo_enum);
+ if (FAILED(hr))
+ {
+ IEnumMoniker_Release(&pEnumMoniker->IEnumMoniker_iface);
+ return hr;
+ }
+
*ppEnumMoniker = &pEnumMoniker->IEnumMoniker_iface;
DEVENUM_LockModule();
diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c
index 2f66907..6d4ce2d 100644
--- a/dlls/devenum/tests/devenum.c
+++ b/dlls/devenum/tests/devenum.c
@@ -525,6 +525,8 @@ static void test_dmo(void)
{
ok(hr == S_OK, "got %#x\n", hr);
+ ok(find_moniker(&CLSID_AudioRendererCategory, mon), "DMO should be registered\n");
+
VariantClear(&var);
hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
ok(hr == S_OK, "got %#x\n", hr);
--
2.7.4
June 24, 2018
[PATCH 1/2] devenum: Implement parsing and reading DMO monikers.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/devenum/Makefile.in | 2 +-
dlls/devenum/devenum_private.h | 10 ++++-
dlls/devenum/mediacatenum.c | 99 ++++++++++++++++++++++++++++++-----------
dlls/devenum/parsedisplayname.c | 52 ++++++++++++++++------
dlls/devenum/tests/Makefile.in | 2 +-
dlls/devenum/tests/devenum.c | 64 ++++++++++++++++++++++++++
6 files changed, 186 insertions(+), 43 deletions(-)
diff --git a/dlls/devenum/Makefile.in b/dlls/devenum/Makefile.in
index 8f81f93..ae138b6 100644
--- a/dlls/devenum/Makefile.in
+++ b/dlls/devenum/Makefile.in
@@ -1,5 +1,5 @@
MODULE = devenum.dll
-IMPORTS = strmiids uuid ole32 oleaut32 avicap32 winmm user32 advapi32 dsound
+IMPORTS = strmiids uuid ole32 oleaut32 avicap32 winmm user32 advapi32 dsound msdmo
DELAYIMPORTS = msvfw32
C_SRCS = \
diff --git a/dlls/devenum/devenum_private.h b/dlls/devenum/devenum_private.h
index d4e1141..df0080d 100644
--- a/dlls/devenum/devenum_private.h
+++ b/dlls/devenum/devenum_private.h
@@ -64,6 +64,7 @@ enum device_type
{
DEVICE_FILTER,
DEVICE_CODEC,
+ DEVICE_DMO,
};
typedef struct
@@ -73,7 +74,11 @@ typedef struct
CLSID class;
BOOL has_class;
enum device_type type;
- WCHAR *name;
+ union
+ {
+ WCHAR *name; /* for filters and codecs */
+ CLSID clsid; /* for DMOs */
+ };
} MediaCatMoniker;
MediaCatMoniker * DEVENUM_IMediaCatMoniker_Construct(void) DECLSPEC_HIDDEN;
@@ -95,5 +100,8 @@ static const WCHAR wszActiveMovieKey[] = {'S','o','f','t','w','a','r','e','\\',
'A','c','t','i','v','e','M','o','v','i','e','\\',
'd','e','v','e','n','u','m','\\',0};
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 a76c7be..c0efae0 100644
--- a/dlls/devenum/mediacatenum.c
+++ b/dlls/devenum/mediacatenum.c
@@ -25,6 +25,7 @@
#include "devenum_private.h"
#include "oleauto.h"
#include "ocidl.h"
+#include "dmoreg.h"
#include "wine/debug.h"
@@ -46,7 +47,11 @@ typedef struct
IPropertyBag IPropertyBag_iface;
LONG ref;
enum device_type type;
- WCHAR path[MAX_PATH];
+ union
+ {
+ WCHAR path[MAX_PATH]; /* for filters and codecs */
+ CLSID clsid; /* for DMOs */
+ };
} RegPropBagImpl;
@@ -114,12 +119,14 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
VARIANT* pVar,
IErrorLog* pErrorLog)
{
+ static const WCHAR FriendlyNameW[] = {'F','r','i','e','n','d','l','y','N','a','m','e',0};
LPVOID pData = NULL;
DWORD received;
DWORD type = 0;
RegPropBagImpl *This = impl_from_IPropertyBag(iface);
HRESULT res = S_OK;
LONG reswin32 = ERROR_SUCCESS;
+ WCHAR name[80];
HKEY hkey;
TRACE("(%p)->(%s, %p, %p)\n", This, debugstr_w(pszPropName), pVar, pErrorLog);
@@ -127,6 +134,21 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Read(
if (!pszPropName || !pVar)
return E_POINTER;
+ if (This->type == DEVICE_DMO)
+ {
+ if (!strcmpW(pszPropName, FriendlyNameW))
+ {
+ res = DMOGetName(&This->clsid, name);
+ if (SUCCEEDED(res))
+ {
+ V_VT(pVar) = VT_BSTR;
+ V_BSTR(pVar) = SysAllocString(name);
+ }
+ return res;
+ }
+ return HRESULT_FROM_WIN32(ERROR_NOT_FOUND);
+ }
+
if (This->type == DEVICE_FILTER)
reswin32 = RegOpenKeyW(HKEY_CLASSES_ROOT, This->path, &hkey);
else if (This->type == DEVICE_CODEC)
@@ -246,6 +268,9 @@ static HRESULT WINAPI DEVENUM_IPropertyBag_Write(
TRACE("(%p)->(%s, %p)\n", This, debugstr_w(pszPropName), pVar);
+ if (This->type == DEVICE_DMO)
+ return E_ACCESSDENIED;
+
switch (V_VT(pVar))
{
case VT_BSTR:
@@ -316,18 +341,29 @@ static HRESULT create_PropertyBag(MediaCatMoniker *mon, IPropertyBag **ppBag)
rpb->ref = 1;
rpb->type = mon->type;
- if (rpb->type == DEVICE_FILTER)
- strcpyW(rpb->path, clsidW);
- else if (rpb->type == DEVICE_CODEC)
- strcpyW(rpb->path, wszActiveMovieKey);
- if (mon->has_class)
+ if (rpb->type == DEVICE_DMO)
+ rpb->clsid = mon->clsid;
+ else if (rpb->type == DEVICE_FILTER)
{
- StringFromGUID2(&mon->class, rpb->path + strlenW(rpb->path), CHARS_IN_GUID);
- if (rpb->type == DEVICE_FILTER)
+ strcpyW(rpb->path, clsidW);
+ if (mon->has_class)
+ {
+ StringFromGUID2(&mon->class, rpb->path + strlenW(rpb->path), CHARS_IN_GUID);
strcatW(rpb->path, instanceW);
- strcatW(rpb->path, backslashW);
+ strcatW(rpb->path, backslashW);
+ }
+ strcatW(rpb->path, mon->name);
+ }
+ else if (rpb->type == DEVICE_CODEC)
+ {
+ strcpyW(rpb->path, wszActiveMovieKey);
+ if (mon->has_class)
+ {
+ StringFromGUID2(&mon->class, rpb->path + strlenW(rpb->path), CHARS_IN_GUID);
+ strcatW(rpb->path, backslashW);
+ }
+ strcatW(rpb->path, mon->name);
}
- strcatW(rpb->path, mon->name);
*ppBag = &rpb->IPropertyBag_iface;
DEVENUM_LockModule();
@@ -658,8 +694,6 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_RelativePathTo(IMoniker *iface, I
static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, IBindCtx *pbc,
IMoniker *pmkToLeft, LPOLESTR *ppszDisplayName)
{
- static const WCHAR swW[] = {'s','w',':',0};
- static const WCHAR cmW[] = {'c','m',':',0};
MediaCatMoniker *This = impl_from_IMoniker(iface);
WCHAR *buffer;
@@ -667,23 +701,36 @@ static HRESULT WINAPI DEVENUM_IMediaCatMoniker_GetDisplayName(IMoniker *iface, I
*ppszDisplayName = NULL;
- buffer = CoTaskMemAlloc((strlenW(deviceW) + 4 + (This->has_class ? CHARS_IN_GUID : 0)
- + strlenW(This->name) + 1) * sizeof(WCHAR));
- if (!buffer)
- return E_OUTOFMEMORY;
-
- strcpyW(buffer, deviceW);
- if (This->type == DEVICE_FILTER)
- strcatW(buffer, swW);
- else if (This->type == DEVICE_CODEC)
- strcatW(buffer, cmW);
-
- if (This->has_class)
+ if (This->type == DEVICE_DMO)
{
+ buffer = CoTaskMemAlloc((strlenW(deviceW) + strlenW(dmoW)
+ + 2 * CHARS_IN_GUID + 1) * sizeof(WCHAR));
+ if (!buffer) return E_OUTOFMEMORY;
+
+ strcpyW(buffer, deviceW);
+ strcatW(buffer, dmoW);
+ StringFromGUID2(&This->clsid, buffer + strlenW(buffer), CHARS_IN_GUID);
StringFromGUID2(&This->class, buffer + strlenW(buffer), CHARS_IN_GUID);
- strcatW(buffer, backslashW);
}
- strcatW(buffer, This->name);
+ else
+ {
+ buffer = CoTaskMemAlloc((strlenW(deviceW) + 3 + (This->has_class ? CHARS_IN_GUID : 0)
+ + strlenW(This->name) + 1) * sizeof(WCHAR));
+ if (!buffer) return E_OUTOFMEMORY;
+
+ strcpyW(buffer, deviceW);
+ if (This->type == DEVICE_FILTER)
+ strcatW(buffer, swW);
+ else if (This->type == DEVICE_CODEC)
+ strcatW(buffer, cmW);
+
+ if (This->has_class)
+ {
+ StringFromGUID2(&This->class, buffer + strlenW(buffer), CHARS_IN_GUID);
+ strcatW(buffer, backslashW);
+ }
+ strcatW(buffer, This->name);
+ }
*ppszDisplayName = buffer;
return S_OK;
diff --git a/dlls/devenum/parsedisplayname.c b/dlls/devenum/parsedisplayname.c
index 0f3ef3b..2992af0 100644
--- a/dlls/devenum/parsedisplayname.c
+++ b/dlls/devenum/parsedisplayname.c
@@ -91,16 +91,21 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
name = strchrW(name, ':') + 1;
- if (name[0] == 's' && name[1] == 'w' && name[2] == ':')
+ if (!strncmpW(name, swW, 3))
{
type = DEVICE_FILTER;
name += 3;
}
- else if (name[0] == 'c' && name[1] == 'm' && name[2] == ':')
+ else if (!strncmpW(name, cmW, 3))
{
type = DEVICE_CODEC;
name += 3;
}
+ else if (!strncmpW(name, dmoW, 4))
+ {
+ type = DEVICE_DMO;
+ name += 4;
+ }
else
{
FIXME("unhandled device type %s\n", debugstr_w(name));
@@ -110,23 +115,42 @@ static HRESULT WINAPI DEVENUM_IParseDisplayName_ParseDisplayName(IParseDisplayNa
if (!(mon = DEVENUM_IMediaCatMoniker_Construct()))
return E_OUTOFMEMORY;
- lstrcpynW(buffer, name, CHARS_IN_GUID);
- if (CLSIDFromString(buffer, &class) == S_OK)
+ if (type == DEVICE_DMO)
{
- mon->has_class = TRUE;
- mon->class = class;
- name += CHARS_IN_GUID;
+ lstrcpynW(buffer, name, CHARS_IN_GUID);
+ if (FAILED(CLSIDFromString(buffer, &mon->clsid)))
+ {
+ IMoniker_Release(&mon->IMoniker_iface);
+ return MK_E_SYNTAX;
+ }
+
+ lstrcpynW(buffer, name + CHARS_IN_GUID - 1, CHARS_IN_GUID);
+ if (FAILED(CLSIDFromString(buffer, &mon->class)))
+ {
+ IMoniker_Release(&mon->IMoniker_iface);
+ return MK_E_SYNTAX;
+ }
+ }
+ else
+ {
+ lstrcpynW(buffer, name, CHARS_IN_GUID);
+ if (CLSIDFromString(buffer, &class) == S_OK)
+ {
+ mon->has_class = TRUE;
+ mon->class = class;
+ name += CHARS_IN_GUID;
+ }
+
+ if (!(mon->name = CoTaskMemAlloc((strlenW(name) + 1) * sizeof(WCHAR))))
+ {
+ IMoniker_Release(&mon->IMoniker_iface);
+ return E_OUTOFMEMORY;
+ }
+ strcpyW(mon->name, name);
}
mon->type = type;
- if (!(mon->name = CoTaskMemAlloc((strlenW(name) + 1) * sizeof(WCHAR))))
- {
- IMoniker_Release(&mon->IMoniker_iface);
- return E_OUTOFMEMORY;
- }
- strcpyW(mon->name, name);
-
*ret = &mon->IMoniker_iface;
return S_OK;
diff --git a/dlls/devenum/tests/Makefile.in b/dlls/devenum/tests/Makefile.in
index b268adf..2d6ec2d 100644
--- a/dlls/devenum/tests/Makefile.in
+++ b/dlls/devenum/tests/Makefile.in
@@ -1,5 +1,5 @@
TESTDLL = devenum.dll
-IMPORTS = advapi32 dsound msvfw32 oleaut32 ole32 winmm
+IMPORTS = advapi32 dsound msdmo msvfw32 oleaut32 ole32 winmm
C_SRCS = \
devenum.c
diff --git a/dlls/devenum/tests/devenum.c b/dlls/devenum/tests/devenum.c
index 383619c..2f66907 100644
--- a/dlls/devenum/tests/devenum.c
+++ b/dlls/devenum/tests/devenum.c
@@ -32,6 +32,7 @@
#include "dsound.h"
#include "mmddk.h"
#include "vfw.h"
+#include "dmoreg.h"
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
@@ -41,6 +42,7 @@ static const WCHAR deviceW[] = {'@','d','e','v','i','c','e',':',0};
static const WCHAR clsidW[] = {'C','L','S','I','D',0};
static const WCHAR waveW[] = {'w','a','v','e',':',0};
static const WCHAR mrleW[] = {'m','r','l','e',0};
+static const WCHAR dmoW[] = {'d','m','o',':',0};
static const WCHAR swW[] = {'s','w',':',0};
static const WCHAR cmW[] = {'c','m',':',0};
static const WCHAR backslashW[] = {'\\',0};
@@ -485,6 +487,67 @@ static void test_codec(void)
IParseDisplayName_Release(parser);
}
+static void test_dmo(void)
+{
+ static const WCHAR name[] = {'d','e','v','e','n','u','m',' ','t','e','s','t',0};
+ IParseDisplayName *parser;
+ IPropertyBag *prop_bag;
+ WCHAR buffer[200];
+ IMoniker *mon;
+ VARIANT var;
+ HRESULT hr;
+
+ hr = CoCreateInstance(&CLSID_CDeviceMoniker, NULL, CLSCTX_INPROC, &IID_IParseDisplayName, (void **)&parser);
+ ok(hr == S_OK, "Failed to create ParseDisplayName: %#x\n", hr);
+
+ lstrcpyW(buffer, deviceW);
+ lstrcatW(buffer, dmoW);
+ StringFromGUID2(&CLSID_TestFilter, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+ StringFromGUID2(&CLSID_AudioRendererCategory, buffer + lstrlenW(buffer), CHARS_IN_GUID);
+ mon = check_display_name(parser, buffer);
+
+ ok(!find_moniker(&CLSID_AudioRendererCategory, mon), "DMO should not be registered\n");
+
+ hr = IMoniker_BindToStorage(mon, NULL, NULL, &IID_IPropertyBag, (void **)&prop_bag);
+ ok(hr == S_OK, "got %#x\n", hr);
+
+ VariantInit(&var);
+ hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
+ ok(hr == E_FAIL, "got %#x\n", hr);
+
+ V_VT(&var) = VT_BSTR;
+ V_BSTR(&var) = SysAllocString(name);
+ hr = IPropertyBag_Write(prop_bag, friendly_name, &var);
+ ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr);
+
+ hr = DMORegister(name, &CLSID_TestFilter, &CLSID_AudioRendererCategory, 0, 0, NULL, 0, NULL);
+ if (hr != E_ACCESSDENIED)
+ {
+ ok(hr == S_OK, "got %#x\n", hr);
+
+ VariantClear(&var);
+ hr = IPropertyBag_Read(prop_bag, friendly_name, &var, NULL);
+ ok(hr == S_OK, "got %#x\n", hr);
+ ok(!lstrcmpW(V_BSTR(&var), name), "got %s\n", wine_dbgstr_w(V_BSTR(&var)));
+
+ VariantClear(&var);
+ V_VT(&var) = VT_BSTR;
+ V_BSTR(&var) = SysAllocString(name);
+ hr = IPropertyBag_Write(prop_bag, friendly_name, &var);
+ ok(hr == E_ACCESSDENIED, "Write failed: %#x\n", hr);
+
+ VariantClear(&var);
+ hr = IPropertyBag_Read(prop_bag, clsidW, &var, NULL);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_NOT_FOUND), "got %#x\n", hr);
+
+ hr = DMOUnregister(&CLSID_TestFilter, &CLSID_AudioRendererCategory);
+ ok(hr == S_OK, "got %#x\n", hr);
+ }
+ IPropertyBag_Release(prop_bag);
+ IMoniker_Release(mon);
+ IParseDisplayName_Release(parser);
+}
+
static void test_legacy_filter(void)
{
static const WCHAR nameW[] = {'t','e','s','t',0};
@@ -974,6 +1037,7 @@ START_TEST(devenum)
test_register_filter();
test_directshow_filter();
test_codec();
+ test_dmo();
test_legacy_filter();
hr = DirectSoundEnumerateW(test_dsound, NULL);
--
2.7.4
June 24, 2018
[PATCH 5/5] [programs\xcopy] Fix copying empty directories
by Jason Edmeades
Found whilst fixing bug#44967
When a directory is searched with /e, an equivalent destination
directory is created immediately, not just when contents are found.
Signed-off-by: Jason Edmeades <us(a)edmeades.me.uk>
---
programs/xcopy/tests/xcopy.c | 1 -
programs/xcopy/xcopy.c | 13 +++++++------
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/programs/xcopy/tests/xcopy.c b/programs/xcopy/tests/xcopy.c
index 0991d49769..94cede6f67 100644
--- a/programs/xcopy/tests/xcopy.c
+++ b/programs/xcopy/tests/xcopy.c
@@ -103,7 +103,6 @@ static void test_parms_syntax(void)
rc = runcmd("xcopy /D/S/E xcopytest xcopytest2\\");
ok(rc == 0, "xcopy /D/S/E test failed rc=%u\n", rc);
- todo_wine
ok(GetFileAttributesA("xcopytest2") != INVALID_FILE_ATTRIBUTES,
"xcopy failed to copy empty directory\n");
RemoveDirectoryA("xcopytest2");
diff --git a/programs/xcopy/xcopy.c b/programs/xcopy/xcopy.c
index 97b0538e57..e380cde226 100644
--- a/programs/xcopy/xcopy.c
+++ b/programs/xcopy/xcopy.c
@@ -590,6 +590,13 @@ static int XCOPY_DoCopy(WCHAR *srcstem, WCHAR *srcspec,
/* Search 2 - do subdirs */
if (flags & OPT_RECURSIVE) {
+
+ /* If /E is supplied, create the directory now */
+ if ((flags & OPT_EMPTYDIR) &&
+ !(flags & OPT_SIMULATE)) {
+ XCOPY_CreateDirectory(deststem);
+ }
+
lstrcpyW(inputpath, srcstem);
lstrcatW(inputpath, wchr_star);
findres = TRUE;
@@ -613,12 +620,6 @@ static int XCOPY_DoCopy(WCHAR *srcstem, WCHAR *srcspec,
lstrcpyW(outputpath, deststem);
if (*destspec == 0x00) {
lstrcatW(outputpath, finddata->cFileName);
-
- /* If /E is supplied, create the directory now */
- if ((flags & OPT_EMPTYDIR) &&
- !(flags & OPT_SIMULATE))
- XCOPY_CreateDirectory(outputpath);
-
lstrcatW(outputpath, wchr_slash);
}
--
2.17.1
June 24, 2018
[PATCH 4/5] [programs/xcopy] Return code 1 for no files is never returned
by Jason Edmeades
Found whilst fixing bug#44967
Testing, and confirmed on the internet (*1) shows xcopy never
returns 1 to indicate no files were copied.
(*1) e.g. https://superuser.com/questions/1180180/is-it-possible-to-get-an-errorlevel…
Signed-off-by: Jason Edmeades <us(a)edmeades.me.uk>
---
programs/xcopy/tests/xcopy.c | 4 +---
programs/xcopy/xcopy.c | 7 ++++---
2 files changed, 5 insertions(+), 6 deletions(-)
diff --git a/programs/xcopy/tests/xcopy.c b/programs/xcopy/tests/xcopy.c
index 7ca32d6c33..0991d49769 100644
--- a/programs/xcopy/tests/xcopy.c
+++ b/programs/xcopy/tests/xcopy.c
@@ -97,17 +97,15 @@ static void test_parms_syntax(void)
DeleteFileA("xcopytest\\xcopy1"); */
rc = runcmd("xcopy /D/S xcopytest xcopytest2\\");
- todo_wine
ok(rc == 0, "xcopy /D/S test failed rc=%u\n", rc);
ok(GetFileAttributesA("xcopytest2") == INVALID_FILE_ATTRIBUTES,
"xcopy copied empty directory incorrectly\n");
rc = runcmd("xcopy /D/S/E xcopytest xcopytest2\\");
- todo_wine {
ok(rc == 0, "xcopy /D/S/E test failed rc=%u\n", rc);
+ todo_wine
ok(GetFileAttributesA("xcopytest2") != INVALID_FILE_ATTRIBUTES,
"xcopy failed to copy empty directory\n");
- }
RemoveDirectoryA("xcopytest2");
}
diff --git a/programs/xcopy/xcopy.c b/programs/xcopy/xcopy.c
index 461104a8da..97b0538e57 100644
--- a/programs/xcopy/xcopy.c
+++ b/programs/xcopy/xcopy.c
@@ -31,12 +31,14 @@
/*
* Notes:
- * Apparently, valid return codes are:
+ * Documented valid return codes are:
* 0 - OK
- * 1 - No files found to copy
+ * 1 - No files found to copy (*1)
* 2 - CTRL+C during copy
* 4 - Initialization error, or invalid source specification
* 5 - Disk write error
+ *
+ * (*1) Testing shows return code 1 is never returned
*/
@@ -1165,7 +1167,6 @@ int wmain (int argc, WCHAR *argvW[])
} else if (!(flags & OPT_NOCOPY)) {
XCOPY_wprintf(XCOPY_LoadMessage(STRING_COPY), filesCopied);
}
- if (rc == RC_OK && filesCopied == 0) rc = RC_NOFILES;
return rc;
}
--
2.17.1
June 24, 2018
[PATCH 3/5] [programes/xcopy] Handle multiple switches concatenated without whitespace
by Jason Edmeades
Fixes bug#44967
This changes xcopy to support flags supplied like /S/E without spaces
between them. Tests supplied but in writing the tests I found a few
other problems left as todo in this patch.
(Note the majority of this patch is just changing the indenting of
a large code block)
Signed-off-by: Jason Edmeades <us(a)edmeades.me.uk>
---
programs/xcopy/tests/xcopy.c | 39 +++++++
programs/xcopy/xcopy.c | 208 ++++++++++++++++++++---------------
2 files changed, 159 insertions(+), 88 deletions(-)
diff --git a/programs/xcopy/tests/xcopy.c b/programs/xcopy/tests/xcopy.c
index ec7683aecc..7ca32d6c33 100644
--- a/programs/xcopy/tests/xcopy.c
+++ b/programs/xcopy/tests/xcopy.c
@@ -73,6 +73,44 @@ static void test_date_format(void)
DeleteFileA("xcopytest\\xcopy1");
}
+static void test_parms_syntax(void)
+{
+ DWORD rc;
+
+ rc = runcmd("xcopy /H/D:20-01-2000 xcopy1 xcopytest");
+ ok(rc == 4, "xcopy /H/D:d-m-y test returned rc=%u\n", rc);
+ ok(GetFileAttributesA("xcopytest\\xcopy1") == INVALID_FILE_ATTRIBUTES,
+ "xcopy should not have created xcopytest\\xcopy1\n");
+
+ rc = runcmd("xcopy /D:01-20-2000/H xcopy1 xcopytest");
+ ok(rc == 0, "xcopy /H/D:m-d-y test failed rc=%u\n", rc);
+ ok(GetFileAttributesA("xcopytest\\xcopy1") != INVALID_FILE_ATTRIBUTES,
+ "xcopy did not create xcopytest\\xcopy1\n");
+ DeleteFileA("xcopytest\\xcopy1");
+
+ /* The following test is commented out as under wine it generates
+ a recursively deep directory tree (todo_wine)
+ rc = runcmd("xcopy /D:1-20-2000/E xcopy1 xcopytest");
+ ok(rc == 0, "xcopy /D:m-d-y/E test failed rc=%u\n", rc);
+ ok(GetFileAttributesA("xcopytest\\xcopy1") != INVALID_FILE_ATTRIBUTES,
+ "xcopy did not create xcopytest\\xcopy1\n");
+ DeleteFileA("xcopytest\\xcopy1"); */
+
+ rc = runcmd("xcopy /D/S xcopytest xcopytest2\\");
+ todo_wine
+ ok(rc == 0, "xcopy /D/S test failed rc=%u\n", rc);
+ ok(GetFileAttributesA("xcopytest2") == INVALID_FILE_ATTRIBUTES,
+ "xcopy copied empty directory incorrectly\n");
+
+ rc = runcmd("xcopy /D/S/E xcopytest xcopytest2\\");
+ todo_wine {
+ ok(rc == 0, "xcopy /D/S/E test failed rc=%u\n", rc);
+ ok(GetFileAttributesA("xcopytest2") != INVALID_FILE_ATTRIBUTES,
+ "xcopy failed to copy empty directory\n");
+ }
+ RemoveDirectoryA("xcopytest2");
+}
+
START_TEST(xcopy)
{
char tmpdir[MAX_PATH];
@@ -94,6 +132,7 @@ START_TEST(xcopy)
CloseHandle(hfile);
test_date_format();
+ test_parms_syntax();
DeleteFileA("xcopy1");
RemoveDirectoryA("xcopytest");
diff --git a/programs/xcopy/xcopy.c b/programs/xcopy/xcopy.c
index a173cc14c7..461104a8da 100644
--- a/programs/xcopy/xcopy.c
+++ b/programs/xcopy/xcopy.c
@@ -743,101 +743,133 @@ static int XCOPY_ParseCommandLine(WCHAR *suppliedsource,
Note: Windows docs say /P prompts when dest is created
but tests show it is done for each src file
regardless of the destination */
- switch (toupper(word[1])) {
- case 'I': flags |= OPT_ASSUMEDIR; break;
- case 'S': flags |= OPT_RECURSIVE; break;
- case 'Q': flags |= OPT_QUIET; break;
- case 'F': flags |= OPT_FULL; break;
- case 'L': flags |= OPT_SIMULATE; break;
- case 'W': flags |= OPT_PAUSE; break;
- case 'T': flags |= OPT_NOCOPY | OPT_RECURSIVE; break;
- case 'Y': flags |= OPT_NOPROMPT; break;
- case 'N': flags |= OPT_SHORTNAME; break;
- case 'U': flags |= OPT_MUSTEXIST; break;
- case 'R': flags |= OPT_REPLACEREAD; break;
- case 'H': flags |= OPT_COPYHIDSYS; break;
- case 'C': flags |= OPT_IGNOREERRORS; break;
- case 'P': flags |= OPT_SRCPROMPT; break;
- case 'A': flags |= OPT_ARCHIVEONLY; break;
- case 'M': flags |= OPT_ARCHIVEONLY |
- OPT_REMOVEARCH; break;
-
- /* E can be /E or /EXCLUDE */
- case 'E': if (CompareStringW(LOCALE_USER_DEFAULT,
- NORM_IGNORECASE | SORT_STRINGSORT,
- &word[1], 8,
- EXCLUDE, -1) == CSTR_EQUAL) {
- if (XCOPY_ProcessExcludeList(&word[9])) {
- XCOPY_FailMessage(ERROR_INVALID_PARAMETER);
- goto out;
- } else flags |= OPT_EXCLUDELIST;
- } else flags |= OPT_EMPTYDIR | OPT_RECURSIVE;
- break;
-
- /* D can be /D or /D: */
- case 'D': if (word[2]==':' && is_digit(word[3])) {
- SYSTEMTIME st;
- WCHAR *pos = &word[3];
- BOOL isError = FALSE;
- memset(&st, 0x00, sizeof(st));
-
- /* Microsoft xcopy's usage message implies that the date
- * format depends on the locale, but that is false.
- * It is hardcoded to month-day-year.
- */
- st.wMonth = _wtol(pos);
- while (*pos && is_digit(*pos)) pos++;
- if (*pos++ != '-') isError = TRUE;
-
- if (!isError) {
- st.wDay = _wtol(pos);
- while (*pos && is_digit(*pos)) pos++;
- if (*pos++ != '-') isError = TRUE;
- }
+ int skip=0;
+ WCHAR *rest;
+
+ while (word[0]) {
+ rest = NULL;
+
+ switch (toupper(word[1])) {
+ case 'I': flags |= OPT_ASSUMEDIR; break;
+ case 'S': flags |= OPT_RECURSIVE; break;
+ case 'Q': flags |= OPT_QUIET; break;
+ case 'F': flags |= OPT_FULL; break;
+ case 'L': flags |= OPT_SIMULATE; break;
+ case 'W': flags |= OPT_PAUSE; break;
+ case 'T': flags |= OPT_NOCOPY | OPT_RECURSIVE; break;
+ case 'Y': flags |= OPT_NOPROMPT; break;
+ case 'N': flags |= OPT_SHORTNAME; break;
+ case 'U': flags |= OPT_MUSTEXIST; break;
+ case 'R': flags |= OPT_REPLACEREAD; break;
+ case 'H': flags |= OPT_COPYHIDSYS; break;
+ case 'C': flags |= OPT_IGNOREERRORS; break;
+ case 'P': flags |= OPT_SRCPROMPT; break;
+ case 'A': flags |= OPT_ARCHIVEONLY; break;
+ case 'M': flags |= OPT_ARCHIVEONLY |
+ OPT_REMOVEARCH; break;
+
+ /* E can be /E or /EXCLUDE */
+ case 'E': if (CompareStringW(LOCALE_USER_DEFAULT,
+ NORM_IGNORECASE | SORT_STRINGSORT,
+ &word[1], 8,
+ EXCLUDE, -1) == CSTR_EQUAL) {
+ if (XCOPY_ProcessExcludeList(&word[9])) {
+ XCOPY_FailMessage(ERROR_INVALID_PARAMETER);
+ goto out;
+ } else {
+ flags |= OPT_EXCLUDELIST;
- if (!isError) {
- st.wYear = _wtol(pos);
- while (*pos && is_digit(*pos)) pos++;
- if (st.wYear < 100) st.wYear+=2000;
+ /* Do not support concatenated switches onto exclude lists yet */
+ rest = end;
+ }
+ } else {
+ flags |= OPT_EMPTYDIR | OPT_RECURSIVE;
}
+ break;
- if (!isError && SystemTimeToFileTime(&st, &dateRange)) {
+ /* D can be /D or /D: */
+ case 'D': if (word[2]==':' && is_digit(word[3])) {
SYSTEMTIME st;
- WCHAR datestring[32], timestring[32];
-
- flags |= OPT_DATERANGE;
-
- /* Debug info: */
- FileTimeToSystemTime (&dateRange, &st);
- GetDateFormatW(0, DATE_SHORTDATE, &st, NULL, datestring,
- sizeof(datestring)/sizeof(WCHAR));
- GetTimeFormatW(0, TIME_NOSECONDS, &st,
- NULL, timestring, sizeof(timestring)/sizeof(WCHAR));
+ WCHAR *pos = &word[3];
+ BOOL isError = FALSE;
+ memset(&st, 0x00, sizeof(st));
+
+ /* Microsoft xcopy's usage message implies that the date
+ * format depends on the locale, but that is false.
+ * It is hardcoded to month-day-year.
+ */
+ st.wMonth = _wtol(pos);
+ while (*pos && is_digit(*pos)) pos++;
+ if (*pos++ != '-') isError = TRUE;
- WINE_TRACE("Date being used is: %s %s\n",
- wine_dbgstr_w(datestring), wine_dbgstr_w(timestring));
+ if (!isError) {
+ st.wDay = _wtol(pos);
+ while (*pos && is_digit(*pos)) pos++;
+ if (*pos++ != '-') isError = TRUE;
+ }
+
+ if (!isError) {
+ st.wYear = _wtol(pos);
+ while (*pos && is_digit(*pos)) pos++;
+ if (st.wYear < 100) st.wYear+=2000;
+ }
+
+ /* Handle switches straight after the supplied date */
+ rest = pos;
+
+ if (!isError && SystemTimeToFileTime(&st, &dateRange)) {
+ SYSTEMTIME st;
+ WCHAR datestring[32], timestring[32];
+
+ flags |= OPT_DATERANGE;
+
+ /* Debug info: */
+ FileTimeToSystemTime (&dateRange, &st);
+ GetDateFormatW(0, DATE_SHORTDATE, &st, NULL, datestring,
+ sizeof(datestring)/sizeof(WCHAR));
+ GetTimeFormatW(0, TIME_NOSECONDS, &st,
+ NULL, timestring, sizeof(timestring)/sizeof(WCHAR));
+
+ WINE_TRACE("Date being used is: %s %s\n",
+ wine_dbgstr_w(datestring), wine_dbgstr_w(timestring));
+ } else {
+ XCOPY_FailMessage(ERROR_INVALID_PARAMETER);
+ goto out;
+ }
} else {
- XCOPY_FailMessage(ERROR_INVALID_PARAMETER);
- goto out;
+ flags |= OPT_DATENEWER;
}
- } else {
- flags |= OPT_DATENEWER;
- }
- break;
-
- case '-': if (toupper(word[2])=='Y')
- flags &= ~OPT_NOPROMPT;
- break;
- case '?': XCOPY_wprintf(XCOPY_LoadMessage(STRING_HELP));
- rc = RC_HELP;
- goto out;
- case 'V':
- WINE_FIXME("ignoring /V\n");
- break;
- default:
- WINE_TRACE("Unhandled parameter '%s'\n", wine_dbgstr_w(word));
- XCOPY_wprintf(XCOPY_LoadMessage(STRING_INVPARM), word);
- goto out;
+ break;
+
+ case '-': if (toupper(word[2])=='Y') {
+ flags &= ~OPT_NOPROMPT;
+ rest = &word[3]; /* Skip over 3 characters */
+ }
+ break;
+ case '?': XCOPY_wprintf(XCOPY_LoadMessage(STRING_HELP));
+ rc = RC_HELP;
+ goto out;
+ case 'V':
+ WINE_FIXME("ignoring /V\n");
+ break;
+ default:
+ WINE_TRACE("Unhandled parameter '%s'\n", wine_dbgstr_w(word));
+ XCOPY_wprintf(XCOPY_LoadMessage(STRING_INVPARM), word);
+ goto out;
+ }
+
+ /* Unless overriden above, skip over the '/' and the first character */
+ if (rest == NULL) rest = &word[2];
+
+ /* By now, rest should point either to the null after the
+ switch, or the beginning of the next switch if there
+ was no whitespace between them */
+ if (!skip && *rest && *rest != '/') {
+ WINE_FIXME("Unexpected characters found and ignored '%s'\n", wine_dbgstr_w(rest));
+ skip=1;
+ } else {
+ word = rest;
+ }
}
}
word = next;
--
2.17.1
June 24, 2018
[PATCH 2/5] [programs/cmd] for loops lose subdirectory prefix
by Jason Edmeades
Fixes bug 45051
A for loop can be working through a wildcarded subdirectory, but when
processing the first file in the subdirectory, it stores the prefix in
a static variable which gets overwritten during the 'for' body
processing. Take a copy on the stack to free up the static buffer
Signed-off-by: Jason Edmeades <us(a)edmeades.me.uk>
---
programs/cmd/builtins.c | 10 ++++++++--
programs/cmd/tests/test_builtins.cmd | 7 +++++++
programs/cmd/tests/test_builtins.cmd.exp | 4 ++++
3 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 541915df67..56c50790ca 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -2261,19 +2261,25 @@ void WCMD_for (WCHAR *p, CMD_LIST **cmdList) {
thisSet->bracketDepth >= thisDepth) {
/* Loop through all entries on the same line */
- WCHAR *item;
+ WCHAR *staticitem;
WCHAR *itemStart;
WCHAR buffer[MAXSTRING];
WINE_TRACE("Processing for set %p\n", thisSet);
i = 0;
- while (*(item = WCMD_parameter (thisSet->command, i, &itemStart, TRUE, FALSE))) {
+ while (*(staticitem = WCMD_parameter (thisSet->command, i, &itemStart, TRUE, FALSE))) {
/*
* If the parameter within the set has a wildcard then search for matching files
* otherwise do a literal substitution.
*/
static const WCHAR wildcards[] = {'*','?','\0'};
+
+ /* Take a copy of the item returned from WCMD_parameter as it is held in a
+ static buffer which can be overwritten during parsing of the for body */
+ WCHAR item[MAXSTRING];
+ strcpyW(item, staticitem);
+
thisCmdStart = cmdStart;
itemNum++;
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index d6edc5fff1..6f2ef4a843 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -1155,9 +1155,16 @@ mkdir foobar & cd foobar
mkdir foo
mkdir bar
mkdir baz
+mkdir pop
echo > bazbaz
echo --- basic wildcards
for %%i in (ba*) do echo %%i
+echo --- wildcards in subdirs
+echo something>pop\bar1
+echo something>pop\bar2.txt
+echo something>pop\bar3
+for %%f in (pop\ba*) do ( call echo %%f )
+rmdir /s/q pop
echo --- for /d
for /d %%i in (baz foo bar) do echo %%i 2>&1
rem Confirm we don't match files:
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index 22d83c3b19..0eb5b966e8 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -917,6 +917,10 @@ B C
B D
--- basic wildcards
bazbaz
+--- wildcards in subdirs
+pop\bar1(a)space@
+pop\bar2.txt(a)space@
+pop\bar3(a)space@
--- for /d
baz(a)space@
foo(a)space@
--
2.17.1
June 24, 2018
[PATCH 1/5] [programs/cmd] Add support for wildcards in if exist
by Jason Edmeades
Fixes bug 45052
Add support for 'if exist filenam*' style statments with associated tests
Signed-off-by: Jason Edmeades <us(a)edmeades.me.uk>
---
programs/cmd/builtins.c | 8 +++--
programs/cmd/tests/test_builtins.cmd | 43 ++++++++++++++++++++++++
programs/cmd/tests/test_builtins.cmd.exp | 8 +++++
3 files changed, 57 insertions(+), 2 deletions(-)
diff --git a/programs/cmd/builtins.c b/programs/cmd/builtins.c
index 04b098e98d..541915df67 100644
--- a/programs/cmd/builtins.c
+++ b/programs/cmd/builtins.c
@@ -2804,8 +2804,12 @@ void WCMD_if (WCHAR *p, CMD_LIST **cmdList)
WCMD_parameter(p, 2+negate, &command, FALSE, FALSE);
}
else if (!lstrcmpiW (condition, existW)) {
- test = (GetFileAttributesW(WCMD_parameter(p, 1+negate, NULL, FALSE, FALSE))
- != INVALID_FILE_ATTRIBUTES);
+ HANDLE hff = INVALID_HANDLE_VALUE;
+ WIN32_FIND_DATAW fd;
+ hff = FindFirstFileW(WCMD_parameter(p, 1+negate, NULL, FALSE, FALSE), &fd);
+ test = (hff != INVALID_HANDLE_VALUE );
+ if (!test) FindClose(hff);
+
WCMD_parameter(p, 2+negate, &command, FALSE, FALSE);
}
else if (!lstrcmpiW (condition, defdW)) {
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 63ec3cacb1..d6edc5fff1 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -979,6 +979,49 @@ for %%i in (%WINE_STR_PARMS%) do (
for %%i in (%WINE_STR_PARMS%) do (
for %%j in (%WINE_STR_PARMS%) do (
call :GTRtest %%i %%j))
+
+echo ------------ Testing if/exist ------------
+mkdir subdir
+echo something>subdir\bar
+echo something else>foo
+if exist foo (
+ echo exist explicit works
+) else (
+ echo ERROR exist explicit broken
+)
+if exist bar (
+ echo ERROR exist explicit unknown file broken
+) else (
+ echo exist explicit unknown file works
+)
+if exist subdir\bar (
+ echo exist explicit in subdir works
+) else (
+ echo ERROR exist explicit in subdir broken
+)
+if exist fo* (
+ echo exist simple wildcard works
+) else (
+ echo ERROR exist simple wildcard broken
+)
+if exist subdir\ba* (
+ echo exist wildcard works
+) else (
+ echo ERROR exist wildcard broken
+)
+if not exist subdir\ba* (
+ echo ERROR negate exist wildcard broken
+) else (
+ echo negate exist wildcard works
+)
+if exist idontexist\ba* (
+ echo ERROR exist wildcard bad subdir broken
+) else (
+ echo exist wildcard bad subdir broken works
+)
+del foo subdir\bar
+rd subdir
+
echo ------ for numbers
if -1 LSS 1 (echo negative numbers handled)
if not -1 LSS -10 (echo negative numbers handled)
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index dcc96299b9..22d83c3b19 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -768,6 +768,14 @@ BA GTR B
BA GTR AB
BA GTR AA
AA GTR A
+------------ Testing if/exist ------------
+exist explicit works
+exist explicit unknown file works
+exist explicit in subdir works
+exist simple wildcard works
+exist wildcard works
+negate exist wildcard works
+exist wildcard bad subdir broken works
------ for numbers
negative numbers handled
negative numbers handled
--
2.17.1
June 24, 2018
[PATCH] include: Add definitions of SERVICES_*_DATABASEW for generic compilers
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
include/winsvc.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/winsvc.h b/include/winsvc.h
index 7d768f5ae2..9db35dd4fe 100644
--- a/include/winsvc.h
+++ b/include/winsvc.h
@@ -39,6 +39,9 @@ extern "C" {
#elif defined(_MSC_VER)
# define SERVICES_ACTIVE_DATABASEW L"ServicesActive"
# define SERVICES_FAILED_DATABASEW L"ServicesFailed"
+#else
+static const WCHAR SERVICES_ACTIVE_DATABASEW[] = { 'S','e','r','v','i','c','e','s','A','c','t','i','v','e',0 };
+static const WCHAR SERVICES_FAILED_DATABASEW[] = { 'S','e','r','v','i','c','e','s','F','a','i','l','e','d',0 };
#endif
#define SERVICES_ACTIVE_DATABASE WINELIB_NAME_AW( SERVICES_ACTIVE_DATABASE )
--
2.17.1
June 24, 2018
[PATCH] include: Add missing type declaration to CERT_EFSBLOB_VALUE_NAME
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
include/wincrypt.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/wincrypt.h b/include/wincrypt.h
index 373acacd26..8e8c258157 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -2216,7 +2216,7 @@ static const WCHAR CERT_EFSBLOB_REGPATH[] =
{'S','o','f','t','w','a','r','e','\\','P','o','l','i','c','i','e','s','\\',
'M','i','c','r','o','s','o','f','t','\\','S','y','s','t','e','m','C','e','r',
't','i','f','i','c','a','t','e','s','\\','E','F','S',0 };
-static const CERT_EFSBLOB_VALUE_NAME[] = { 'E','F','S','B','l','o','b',0 };
+static const WCHAR CERT_EFSBLOB_VALUE_NAME[] = { 'E','F','S','B','l','o','b',0 };
#endif
#if defined(__GNUC__)
--
2.17.1
June 24, 2018
[PATCH] winetest: Allow hyphens in test filenames.
by Zebediah Figura
For vulkan-1:vulkan.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
winetest/dissect | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/winetest/dissect b/winetest/dissect
index 7416317..4db4f85 100755
--- a/winetest/dissect
+++ b/winetest/dissect
@@ -583,7 +583,7 @@ while ($line = <IN>) {
next if ($line =~ /^\s*$/);
chomp $line;
$line =~ s/\r+$//;
- if ($line =~ m%^([_.a-z0-9-]+):([_a-z0-9]+) (start|skipped) (-|[/_.a-z0-9]+) (-|[.0-9a-f]+)\r?$%)
+ if ($line =~ m%^([_.a-z0-9-]+):([_a-z0-9]+) (start|skipped) (-|[/_.a-z0-9-]+) (-|[.0-9a-f]+)\r?$%)
{
my ($l_dll, $l_unit, $l_type, $l_source, $l_rev) = ($1, $2, $3, $4, $5);
--
2.7.4
June 24, 2018
Re: [PATCH] kernel32: Always start debugger on WinSta0.
by Zebediah Figura
On 14/06/18 23:12, Alistair Leslie-Hughes wrote:
> From: Sebastian Lackner <sebastian(a)fds-team.de>
>
> Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
> ---
> dlls/kernel32/except.c | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/dlls/kernel32/except.c b/dlls/kernel32/except.c
> index de244fc..5f2166e 100644
> --- a/dlls/kernel32/except.c
> +++ b/dlls/kernel32/except.c
> @@ -304,6 +304,7 @@ static BOOL start_debugger(PEXCEPTION_POINTERS epointers, HANDLE hEvent)
> TRACE("Starting debugger %s\n", debugstr_a(cmdline));
> memset(&startup, 0, sizeof(startup));
> startup.cb = sizeof(startup);
> + startup.lpDesktop = (char *)"WinSta0";
> startup.dwFlags = STARTF_USESHOWWINDOW;
> startup.wShowWindow = SW_SHOWNORMAL;
> ret = CreateProcessA(NULL, cmdline, NULL, NULL, TRUE, 0, env, NULL, &startup, &info);
>
I guess one potential problem with this is bugs like 45369; perhaps it
would be better to suppress creating a window at all in such a case.
June 24, 2018
[PATCH v3 2/2] d3d9/tests: Add new test for DXTn volume textures.
by Connor McAdams
To properly test the functionality of DXTn volume textures, I have added
new tests for DXT1, DXT3, and DXT5 replacing the old DXT5 test. I also
check for alpha values, which the previous test did not do.
Signed-off-by: Connor McAdams <conmanx360(a)gmail.com>
---
dlls/d3d9/tests/visual.c | 183 +++++++++++++++++++++++++++++++----------------
1 file changed, 123 insertions(+), 60 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index b36c189..190ea1b 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -17741,26 +17741,73 @@ done:
DestroyWindow(window);
}
-static void volume_dxt5_test(void)
+static void volume_dxtn_test(void)
{
IDirect3DVolumeTexture9 *texture;
IDirect3DDevice9 *device;
D3DLOCKED_BOX box;
IDirect3D9 *d3d;
- unsigned int i;
+ struct surface_readback rb;
+ IDirect3DSurface9 *rt;
+ DWORD i, x;
ULONG refcount;
DWORD color;
HWND window;
HRESULT hr;
- static const char texture_data[] =
+ static const BYTE dxt1_texture_data[] =
+ {
+ 0x00, 0xF8, 0x00, 0xF8, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xE0, 0x07, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
+ };
+ static const BYTE dxt3_texture_data[] =
+ {
+ 0xFF, 0xEE, 0xFF, 0xEE, 0xFF, 0xEE, 0xFF, 0xEE, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xDD, 0xFF, 0xDD, 0xFF, 0xDD, 0xFF, 0xDD, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xCC, 0xFF, 0xCC, 0xFF, 0xCC, 0xFF, 0xCC, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xBB, 0xFF, 0xBB, 0xFF, 0xBB, 0xFF, 0xBB, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
+ };
+ static const BYTE dxt5_texture_data[] =
{
/* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x80, 0x0D, 0xD8, 0x80, 0x0D, 0xD8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
};
+ static const DWORD dxt1_expected_colors[] =
+ {
+ 0xFFFF0000, 0x00000000, 0xFF00FF00, 0xFF00FF00,
+ 0xFF0000FF, 0xFF0000FF, 0xFFFFFFFF, 0xFFFFFFFF,
+ };
+ static const DWORD dxt3_expected_colors[] =
+ {
+ 0xFFFF0000, 0xEEFF0000, 0xFF00FF00, 0xDD00FF00,
+ 0xFF0000FF, 0xCC0000FF, 0xFFFFFFFF, 0xBBFFFFFF,
+ };
+ static const DWORD dxt5_expected_colors[] =
+ {
+ 0xFFFF0000, 0x00FF0000, 0xFF00FF00, 0xFF00FF00,
+ 0xFF0000FF, 0xFF0000FF, 0xFFFFFFFF, 0xFFFFFFFF
+ };
+
+ static const struct
+ {
+ const char *dxtn;
+ const BYTE *tex_data;
+ DWORD tex_size;
+ D3DFORMAT fmt;
+ const DWORD *expected_colors;
+ }
+ dxtn_tex[] =
+ {
+ {"DXT1", dxt1_texture_data, sizeof(dxt1_texture_data), D3DFMT_DXT1, dxt1_expected_colors},
+ {"DXT3", dxt3_texture_data, sizeof(dxt3_texture_data), D3DFMT_DXT3, dxt3_expected_colors},
+ {"DXT5", dxt5_texture_data, sizeof(dxt5_texture_data), D3DFMT_DXT5, dxt5_expected_colors},
+ };
+
static const struct
{
struct vec3 position;
@@ -17778,70 +17825,86 @@ static void volume_dxt5_test(void)
{{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
{{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
};
- static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
- window = create_window();
- d3d = Direct3DCreate9(D3D_SDK_VERSION);
- ok(!!d3d, "Failed to create a D3D object.\n");
- if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
- D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
+ for (x = 0; x < ARRAY_SIZE(dxtn_tex); ++x)
{
- skip("DXT5 volume textures are not supported, skipping test.\n");
- goto done;
- }
- if (!(device = create_device(d3d, window, window, TRUE)))
- {
- skip("Failed to create a D3D device, skipping tests.\n");
- goto done;
- }
+ window = create_window();
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create a D3D object.\n");
+ if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_A8B8G8R8, 0, D3DRTYPE_VOLUMETEXTURE, dxtn_tex[x].fmt)))
+ {
+ skip("%s volume textures are not supported, skipping test.\n", dxtn_tex[x].dxtn);
+ continue;
+ }
+ if (!(device = create_device(d3d, window, window, TRUE)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ continue;
+ }
- hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
- D3DPOOL_MANAGED, &texture, NULL);
- ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, dxtn_tex[x].fmt,
+ D3DPOOL_MANAGED, &texture, NULL);
+ ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
- hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
- ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
- memcpy(box.pBits, texture_data, sizeof(texture_data));
- hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
- ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
+ hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
+ ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
+ memcpy(box.pBits, dxtn_tex[x].tex_data, dxtn_tex[x].tex_size);
- hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
- ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
- ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
- ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
- ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
+ hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
+ ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
- hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
- ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
- hr = IDirect3DDevice9_BeginScene(device);
- ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
- hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
- ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
- hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
- ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
- hr = IDirect3DDevice9_EndScene(device);
- ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
+ ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
+ ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
- for (i = 0; i < 4; i++)
- {
- color = getPixelColor(device, 80 + 160 * i, 240);
- ok (color_match(color, expected_colors[i], 1),
- "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
+ ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(dxt1_expected_colors); ++i)
+ {
+ hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
+ if(FAILED(hr))
+ {
+ trace("Can't get the render target, hr %#x.\n", hr);
+ color = 0x00000000;
+ }
+ else
+ {
+ get_rt_readback(rt, &rb);
+ color = get_readback_color(&rb, 40 + 80 * i, 240);
+ release_surface_readback(&rb);
+ IDirect3DSurface9_Release(rt);
+ }
+ ok (color_match(color, dxtn_tex[x].expected_colors[i], 1),
+ "Expected color 0x%08x, got 0x%08x, case %u.\n", dxtn_tex[x].expected_colors[i], color, i);
+ }
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
+ IDirect3DVolumeTexture9_Release(texture);
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
}
- hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
- ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
- IDirect3DVolumeTexture9_Release(texture);
- refcount = IDirect3DDevice9_Release(device);
- ok(!refcount, "Device has %u references left.\n", refcount);
-done:
IDirect3D9_Release(d3d);
DestroyWindow(window);
}
@@ -24131,7 +24194,7 @@ START_TEST(visual)
zenable_test();
fog_special_test();
volume_srgb_test();
- volume_dxt5_test();
+ volume_dxtn_test();
add_dirty_rect_test();
multisampled_depth_buffer_test();
resz_test();
--
2.7.4
June 23, 2018
[PATCH v3 1/2] wined3d: convert 3D DXTn textures
by Connor McAdams
This adds decompression functions for DXT1, DXT3, and DXT5 formats,
which covers all the possible DXT formats. These are used for
decompressing DXTn volume textures, and converting them to b8g8r8a8.
This patch also makes sure only 3D DXTn textures are uploaded by
performing a check in the wined3d_texture_upload_data function.
Signed-off-by: Connor McAdams <conmanx360(a)gmail.com>
---
dlls/wined3d/texture.c | 27 ++++++
dlls/wined3d/utils.c | 240 ++++++++++++++++++++++++++++++++++++++++++-------
2 files changed, 236 insertions(+), 31 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index c316906..0d03ea9 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1948,6 +1948,33 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
bo.addr += src_box->left * format->byte_count;
}
+ if (format->id == WINED3DFMT_DXT5 || format->id == WINED3DFMT_DXT4 ||
+ format->id == WINED3DFMT_DXT3 || format->id == WINED3DFMT_DXT2 ||
+ format->id == WINED3DFMT_DXT1 || format->id == WINED3DFMT_BC3_UNORM ||
+ format->id == WINED3DFMT_BC2_UNORM || format->id == WINED3DFMT_BC1_UNORM)
+ {
+ if (target == GL_TEXTURE_3D)
+ {
+ struct wined3d_format temp;
+
+ f = *format;
+ temp.upload = f.upload;
+ format = &f;
+ format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM, WINED3DUSAGE_TEXTURE);
+ f = *format;
+ f.upload = temp.upload;
+ f.conv_byte_count = 4;
+ format = &f;
+ texture->resource.format_flags &= ~WINED3DFMT_FLAG_BLOCKS;
+ }
+ else
+ {
+ f = *format;
+ f.upload = NULL;
+ format = &f;
+ }
+ }
+
if (format->upload)
{
unsigned int dst_row_pitch, dst_slice_pitch;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 937c1bc..df6fef1 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -840,6 +840,206 @@ static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_p
}
}
+static void dxtn_decompress_block(const BYTE *src, BYTE *dst, UINT width, UINT height, UINT depth,
+ UINT x_pos, UINT y_pos, UINT z_pos, UINT dst_slice_pitch, UINT64 cur_block, UINT fmt, BYTE block_offset)
+{
+ UINT64 alpha_block, alpha_index, color_block, color_index;
+ const UINT64 *source;
+ DWORD *dest;
+ DWORD alpha_lookup;
+ DWORD bgra;
+ DWORD temp;
+ DWORD i, x, y;
+ WORD color[2];
+ BYTE alpha_val, color_val;
+ BYTE alpha[8];
+ BYTE r[4];
+ BYTE g[4];
+ BYTE b[4];
+
+ source = (const UINT64 *)(src + cur_block * block_offset);
+ if (fmt == WINED3DFMT_DXT1)
+ {
+ color_block = source[0];
+ alpha_block = 0;
+ }
+ else
+ {
+ alpha_block = source[0];
+ color_block = source[1];
+ }
+
+ color[0] = color_block & 0xffff;
+ color[1] = (color_block >> 16) & 0xffff;
+ for (i = 0; i < 2; ++i)
+ {
+ temp = (color[i] >> 11) * 255 + 16;
+ r[i] = (temp / 32 + temp) / 32;
+ temp = ((color[i] >> 5) & 0x3f) * 255 + 32;
+ g[i] = (temp / 64 + temp) / 64;
+ temp = (color[i] & 0x1f) * 255 + 16;
+ b[i] = (temp / 32 + temp) / 32;
+ }
+
+ if (fmt == WINED3DFMT_DXT3 || fmt == WINED3DFMT_DXT5 || color[0] > color[1])
+ {
+ for (i = 0; i < 2; ++i)
+ {
+ r[2 + i] = (2 * r[0 + i] + r[1 - i]) / 3;
+ g[2 + i] = (2 * g[0 + i] + g[1 - i]) / 3;
+ b[2 + i] = (2 * b[0 + i] + b[1 - i]) / 3;
+ }
+ }
+ else if (fmt == WINED3DFMT_DXT1 && color[0] <= color[1])
+ {
+ r[2] = (r[0] + r[1]) / 2;
+ g[2] = (g[0] + g[1]) / 2;
+ b[2] = (b[0] + b[1]) / 2;
+
+ r[3] = 0;
+ g[3] = 0;
+ b[3] = 0;
+ }
+
+ switch (fmt)
+ {
+ case WINED3DFMT_DXT1:
+ alpha_index = 0;
+ for (i = 0; i < ARRAY_SIZE(alpha); ++i)
+ alpha[i] = 255;
+ if (color[0] <= color[1])
+ alpha[3] = 0;
+ break;
+ case WINED3DFMT_DXT3:
+ alpha_index = alpha_block;
+ for (i = 0; i < ARRAY_SIZE(alpha); ++i)
+ alpha[i] = 0;
+ break;
+ case WINED3DFMT_DXT5:
+ alpha_index = (alpha_block >> 16);
+ alpha[0] = alpha_block & 0xff;
+ alpha[1] = (alpha_block >> 8) & 0xff;
+ if (alpha[0] > alpha[1])
+ {
+ for (i = 0; i < 6; ++i)
+ alpha[2 + i] = (((6 - i) * alpha[0]) + ((1 + i) * alpha[1])) / 7;
+ }
+ else if (alpha[0] <= alpha[1])
+ {
+ for (i = 0; i < 4; ++i)
+ alpha[2 + i] = (((4 - i) * alpha[0]) + ((1 + i) * alpha[1])) / 5;
+ alpha[6] = 0;
+ alpha[7] = 255;
+ }
+ break;
+ default:
+ alpha_index = 0;
+ break;
+ }
+
+ color_index = (color_block >> 32) & 0xffffffff;
+ dest = (DWORD *)(dst + z_pos * dst_slice_pitch);
+ for (y = 0; y < 4; ++y)
+ {
+ if (y_pos + y >= height)
+ break;
+ for (x = 0; x < 4; ++x)
+ {
+ if (x_pos + x >= width)
+ break;
+
+ color_val = 0;
+ alpha_val = 0;
+ bgra = 0;
+
+ color_val = (color_index >> (y * 8));
+ color_val = (color_val >> (x * 2)) & 0x3;
+ switch (fmt)
+ {
+ case WINED3DFMT_DXT1:
+ alpha_val = color_val;
+ break;
+ case WINED3DFMT_DXT3:
+ alpha_lookup = (alpha_index >> (y * 16)) & 0xffff;
+ alpha_val = (alpha_lookup >> (x * 4)) & 0xf;
+ temp = alpha_val * 255 + 8;
+ alpha[0] = (temp / 16 + temp) / 16;
+ alpha_val = 0;
+ break;
+ case WINED3DFMT_DXT5:
+ alpha_lookup = (alpha_index >> (y * 12)) & 0xfff;
+ alpha_val = (alpha_lookup >> (x * 3)) & 0x7;
+ break;
+ }
+ bgra = ((alpha[alpha_val] << 24) | (r[color_val] << 16) | (g[color_val] << 8) | b[color_val]);
+ dest[(y_pos + y) * width + (x_pos + x)] = bgra;
+ }
+ }
+}
+
+static void convert_dxt5_b8g8r8a8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
+ UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
+{
+ UINT64 current_block;
+ DWORD x, y, z;
+
+ current_block = 0;
+
+ for (z = 0; z < depth; ++z)
+ {
+ for (y = 0; y < height; y += 4)
+ {
+ for (x = 0; x < width; x += 4)
+ {
+ dxtn_decompress_block(src, dst, width, height, depth, x, y, z, dst_slice_pitch, current_block, WINED3DFMT_DXT5, 16);
+ current_block++;
+ }
+ }
+ }
+}
+
+static void convert_dxt3_b8g8r8a8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
+ UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
+{
+ UINT64 current_block;
+ DWORD x, y, z;
+
+ current_block = 0;
+
+ for (z = 0; z < depth; ++z)
+ {
+ for (y = 0; y < height; y += 4)
+ {
+ for (x = 0; x < width; x += 4)
+ {
+ dxtn_decompress_block(src, dst, width, height, depth, x, y, z, dst_slice_pitch, current_block, WINED3DFMT_DXT3, 16);
+ current_block++;
+ }
+ }
+ }
+}
+
+static void convert_dxt1_b8g8r8a8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
+ UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
+{
+ UINT64 current_block;
+ DWORD x, y, z;
+
+ current_block = 0;
+
+ for (z = 0; z < depth; ++z)
+ {
+ for (y = 0; y < height; y += 4)
+ {
+ for (x = 0; x < width; x += 4)
+ {
+ dxtn_decompress_block(src, dst, width, height, depth, x, y, z, dst_slice_pitch, current_block, WINED3DFMT_DXT1, 8);
+ current_block++;
+ }
+ }
+ }
+}
+
static void x8_d24_unorm_upload(const BYTE *src, BYTE *dst,
unsigned int src_row_pitch, unsigned int src_slice_pitch,
unsigned int dst_row_pitch, unsigned int dst_slice_pitch,
@@ -1118,42 +1318,42 @@ static const struct wined3d_format_texture_info format_texture_info[] =
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt1_b8g8r8a8_unorm},
{WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt3_b8g8r8a8_unorm},
{WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt3_b8g8r8a8_unorm},
{WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt5_b8g8r8a8_unorm},
{WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt5_b8g8r8a8_unorm},
{WINED3DFMT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt1_b8g8r8a8_unorm},
{WINED3DFMT_BC2_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt3_b8g8r8a8_unorm},
{WINED3DFMT_BC3_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt5_b8g8r8a8_unorm},
{WINED3DFMT_BC4_UNORM, GL_COMPRESSED_RED_RGTC1, GL_COMPRESSED_RED_RGTC1, 0,
GL_RED, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
@@ -3394,29 +3594,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
* for dx9 GPUs support it, some do not, so not supporting DXTn volumes is OK for d3d9.
*
* Note that GL_NV_texture_compression_vtc adds this functionality to OpenGL, but the
- * block layout is not compatible with the one used by d3d. See volume_dxt5_test. */
- idx = get_format_idx(WINED3DFMT_DXT1);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT2);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT3);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT4);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT5);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_BC1_UNORM);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_BC1_UNORM_SRGB);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_BC2_UNORM);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_BC2_UNORM_SRGB);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_BC3_UNORM);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_BC3_UNORM_SRGB);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ * block layout is not compatible with the one used by d3d. See volume_dxtn_test. */
/* Similarly with ATI1N / ATI2N and GL_ARB_texture_compression_rgtc. */
idx = get_format_idx(WINED3DFMT_ATI1N);
gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
--
2.7.4
June 23, 2018
[PATCH v3 0/2] DXTn 3D Texture support
by Connor McAdams
This patch series adds support for DXTn volume textures by using the
CPU to decompress and convert them before upload.
It has been tested and works, but recently I included the BC1-BC3
formats as they use the same DXTn compression. However, I was unsure
about handling the WINED3DFMT_BCn_UNORM_SRGB. It may need to be added
to the list of formats in texture.c to prevent conversion if it's a
2D texture. Let me know if it needs changed.
Thanks,
Connor.
Connor McAdams (2):
wined3d: convert 3D DXTn textures
d3d9/tests: Add new test for DXTn volume textures.
dlls/d3d9/tests/visual.c | 183 ++++++++++++++++++++++++------------
dlls/wined3d/texture.c | 27 ++++++
dlls/wined3d/utils.c | 240 +++++++++++++++++++++++++++++++++++++++++------
3 files changed, 359 insertions(+), 91 deletions(-)
--
2.7.4
June 23, 2018
[PATCH] comctl32/listview: Don't send LVN_ENDLABELEDIT twice under some circumstances
by Fabian Maurer
Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de>
---
dlls/comctl32/listview.c | 10 +++++++++
dlls/comctl32/tests/listview.c | 41 ++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index 200bf93be55..0193c038ebb 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -326,6 +326,7 @@ typedef struct tagLISTVIEW_INFO
/* misc */
DWORD iVersion; /* CCM_[G,S]ETVERSION */
+ BOOL inEndEditLabel; /* To prevent sending LVN_ENDLABELEDIT during LVN_ENDLABELEDIT */
} LISTVIEW_INFO;
/*
@@ -5869,6 +5870,9 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL
WCHAR *pszText = NULL;
BOOL res;
+ if (infoPtr->inEndEditLabel)
+ return FALSE;
+
if (storeText)
{
DWORD len = isW ? GetWindowTextLengthW(infoPtr->hwndEdit) : GetWindowTextLengthA(infoPtr->hwndEdit);
@@ -5914,9 +5918,14 @@ static BOOL LISTVIEW_EndEditLabelT(LISTVIEW_INFO *infoPtr, BOOL storeText, BOOL
dispInfo.item.pszText = same ? NULL : pszText;
dispInfo.item.cchTextMax = textlenT(dispInfo.item.pszText, isW);
+ /* Sending LVN_ENDLABELEDITW might trigger EN_KILLFOCUS which would call this function again */
+ infoPtr->inEndEditLabel = TRUE;
+
/* Do we need to update the Item Text */
res = notify_dispinfoT(infoPtr, LVN_ENDLABELEDITW, &dispInfo, isW);
+ infoPtr->inEndEditLabel = FALSE;
+
infoPtr->nEditLabelItem = -1;
infoPtr->hwndEdit = 0;
@@ -9497,6 +9506,7 @@ static LRESULT LISTVIEW_NCCreate(HWND hwnd, WPARAM wParam, const CREATESTRUCTW *
infoPtr->itemEdit.fEnabled = FALSE;
infoPtr->iVersion = COMCTL32_VERSION;
infoPtr->colRectsDirty = FALSE;
+ infoPtr->inEndEditLabel = FALSE;
/* get default font (icon title) */
SystemParametersInfoW(SPI_GETICONTITLELOGFONT, 0, &logFont, 0);
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index e9b715ee412..3e9e9697a4f 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -75,6 +75,10 @@ static BOOL g_disp_A_to_W;
static NMLVDISPINFOA g_editbox_disp_info;
/* when this is set focus will be tested on LVN_DELETEITEM */
static BOOL g_focus_test_LVN_DELETEITEM;
+/* Whether to send WM_KILLFOCUS to the edit control during LVN_ENDLABELEDIT */
+static BOOL do_LVN_ENDLABELEDIT_killfocus = FALSE;
+/* Number of LVN_ENDLABELEDIT notifications received */
+static BOOL LVN_ENDLABELEDITA_count = 0;
static HWND subclass_editbox(HWND hwndListview);
@@ -510,6 +514,11 @@ static LRESULT WINAPI parent_wnd_proc(HWND hwnd, UINT message, WPARAM wParam, LP
ok(IsWindow(edit), "expected valid edit control handle\n");
ok((GetWindowLongA(edit, GWL_STYLE) & ES_MULTILINE) == 0, "edit is multiline\n");
+ LVN_ENDLABELEDITA_count++;
+
+ if (do_LVN_ENDLABELEDIT_killfocus)
+ SendMessageA(edit, WM_KILLFOCUS, 0, 0);
+
return TRUE;
}
case LVN_BEGINSCROLL:
@@ -6322,6 +6331,37 @@ static void test_LVSCW_AUTOSIZE(void)
DestroyWindow(hwnd);
}
+static void test_LVN_ENDLABELEDITW(void)
+{
+ HWND hwnd, hwndedit;
+ LVITEMW item = {0};
+ WCHAR text[] = {'l','a','l','a',0};
+ DWORD ret;
+
+ hwnd = create_listview_control(LVS_REPORT | LVS_EDITLABELS);
+
+ insert_column(hwnd, 0);
+
+ item.mask = LVIF_TEXT;
+ item.pszText = text;
+ ListView_InsertItemW(hwnd, &item);
+
+ SetFocus(hwnd);
+ hwndedit = (HWND)SendMessageW(hwnd, LVM_EDITLABELW, 0, 0);
+
+ ret = SendMessageA(hwndedit, WM_SETTEXT, 0, (LPARAM)"test");
+ expect(TRUE, ret);
+
+ LVN_ENDLABELEDITA_count = 0;
+ do_LVN_ENDLABELEDIT_killfocus = TRUE;
+ ret = SendMessageA(hwndedit, WM_KEYDOWN, VK_RETURN, 0);
+ do_LVN_ENDLABELEDIT_killfocus = FALSE;
+ ok(LVN_ENDLABELEDITA_count == 1,
+ "messagebox during LVN_ENDLABELEDIT gave wrong number of LVN_ENDLABELEDITA: %d\n", LVN_ENDLABELEDITA_count);
+
+ DestroyWindow(hwnd);
+}
+
START_TEST(listview)
{
ULONG_PTR ctx_cookie;
@@ -6425,6 +6465,7 @@ START_TEST(listview)
test_oneclickactivate();
test_state_image();
test_LVSCW_AUTOSIZE();
+ test_LVN_ENDLABELEDITW();
unload_v6_module(ctx_cookie, hCtx);
--
2.18.0
June 23, 2018
[PATCH v4] msvcrt: Use already existent oneexit_table functions for _onexit and _c_exit
by Piotr Caban
From: Fabian Maurer <dark.shadow4(a)web.de>
Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
v4:
- don't use __MSVCRT_ prefix for internal functions
- simplified atexit functions order test
---
dlls/msvcrt/exit.c | 201
+++++++++++++++++++++------------------------
dlls/ucrtbase/tests/misc.c | 56 ++++++++++++-
2 files changed, 149 insertions(+), 108 deletions(-)
June 23, 2018
[PATCH v2 2/2] wined3d: Add new test for DXTn volume textures.
by Connor McAdams
To properly test the functionality of DXTn volume textures, I have added
new tests for DXT1, DXT3, and DXT5 replacing the old DXT5 test. I also
check for alpha values, which the previous test did not do.
Signed-off-by: Connor McAdams <conmanx360(a)gmail.com>
---
dlls/d3d9/tests/visual.c | 183 +++++++++++++++++++++++++++++++----------------
1 file changed, 123 insertions(+), 60 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index b36c189..29fd27b 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -17741,26 +17741,73 @@ done:
DestroyWindow(window);
}
-static void volume_dxt5_test(void)
+static void volume_dxtn_test(void)
{
IDirect3DVolumeTexture9 *texture;
IDirect3DDevice9 *device;
D3DLOCKED_BOX box;
IDirect3D9 *d3d;
- unsigned int i;
+ struct surface_readback rb;
+ IDirect3DSurface9 *rt;
+ DWORD i, x;
ULONG refcount;
DWORD color;
HWND window;
HRESULT hr;
- static const char texture_data[] =
+ static const BYTE dxt1_texture_data[] =
+ {
+ 0x00, 0xF8, 0x00, 0xF8, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xE0, 0x07, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
+ };
+ static const BYTE dxt3_texture_data[] =
+ {
+ 0xFF, 0xEE, 0xFF, 0xEE, 0xFF, 0xEE, 0xFF, 0xEE, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xDD, 0xFF, 0xDD, 0xFF, 0xDD, 0xFF, 0xDD, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xCC, 0xFF, 0xCC, 0xFF, 0xCC, 0xFF, 0xCC, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xBB, 0xFF, 0xBB, 0xFF, 0xBB, 0xFF, 0xBB, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
+ };
+ static const BYTE dxt5_texture_data[] =
{
/* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x80, 0x0D, 0xD8, 0x80, 0x0D, 0xD8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
};
+ static const DWORD dxt1_expected_colors[] =
+ {
+ 0xFFFF0000, 0x00000000, 0xFF00FF00, 0xFF00FF00,
+ 0xFF0000FF, 0xFF0000FF, 0xFFFFFFFF, 0xFFFFFFFF,
+ };
+ static const DWORD dxt3_expected_colors[] =
+ {
+ 0xFFFF0000, 0xEEFF0000, 0xFF00FF00, 0xDD00FF00,
+ 0xFF0000FF, 0xCC0000FF, 0xFFFFFFFF, 0xBBFFFFFF,
+ };
+ static const DWORD dxt5_expected_colors[] =
+ {
+ 0xFFFF0000, 0x00FF0000, 0xFF00FF00, 0xFF00FF00,
+ 0xFF0000FF, 0xFF0000FF, 0xFFFFFFFF, 0xFFFFFFFF
+ };
+
+ static const struct
+ {
+ const char *dxtn;
+ const BYTE *tex_data;
+ DWORD tex_size;
+ D3DFORMAT fmt;
+ const DWORD *expected_colors;
+ }
+ dxtn_tex[] =
+ {
+ {"DXT1", dxt1_texture_data, sizeof(dxt1_texture_data), D3DFMT_DXT1, dxt1_expected_colors},
+ {"DXT3", dxt3_texture_data, sizeof(dxt3_texture_data), D3DFMT_DXT3, dxt3_expected_colors},
+ {"DXT5", dxt5_texture_data, sizeof(dxt5_texture_data), D3DFMT_DXT5, dxt5_expected_colors},
+ };
+
static const struct
{
struct vec3 position;
@@ -17778,70 +17825,86 @@ static void volume_dxt5_test(void)
{{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
{{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
};
- static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
- window = create_window();
- d3d = Direct3DCreate9(D3D_SDK_VERSION);
- ok(!!d3d, "Failed to create a D3D object.\n");
- if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
- D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
- {
- skip("DXT5 volume textures are not supported, skipping test.\n");
- goto done;
- }
- if (!(device = create_device(d3d, window, window, TRUE)))
+ for (x = 0; x < 3; ++x)
{
- skip("Failed to create a D3D device, skipping tests.\n");
- goto done;
- }
+ window = create_window();
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create a D3D object.\n");
+ if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_A8B8G8R8, 0, D3DRTYPE_VOLUMETEXTURE, dxtn_tex[x].fmt)))
+ {
+ skip("%s volume textures are not supported, skipping test.\n", dxtn_tex[x].dxtn);
+ continue;
+ }
+ if (!(device = create_device(d3d, window, window, TRUE)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ continue;
+ }
- hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
- D3DPOOL_MANAGED, &texture, NULL);
- ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, dxtn_tex[x].fmt,
+ D3DPOOL_MANAGED, &texture, NULL);
+ ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
- hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
- ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
- memcpy(box.pBits, texture_data, sizeof(texture_data));
- hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
- ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
+ hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
+ ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
+ memcpy(box.pBits, dxtn_tex[x].tex_data, dxtn_tex[x].tex_size);
- hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
- ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
- ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
- ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
- ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
+ hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
+ ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
- hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
- ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
- hr = IDirect3DDevice9_BeginScene(device);
- ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
- hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
- ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
- hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
- ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
- hr = IDirect3DDevice9_EndScene(device);
- ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
+ ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
+ ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
- for (i = 0; i < 4; i++)
- {
- color = getPixelColor(device, 80 + 160 * i, 240);
- ok (color_match(color, expected_colors[i], 1),
- "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
+ ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ for (i = 0; i < 8; ++i)
+ {
+ hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
+ if(FAILED(hr))
+ {
+ trace("Can't get the render target, hr %#x.\n", hr);
+ color = 0x00000000;
+ }
+ else
+ {
+ get_rt_readback(rt, &rb);
+ color = get_readback_color(&rb, 40 + 80 * i, 240);
+ release_surface_readback(&rb);
+ IDirect3DSurface9_Release(rt);
+ }
+ ok (color_match(color, dxtn_tex[x].expected_colors[i], 1),
+ "Expected color 0x%08x, got 0x%08x, case %u.\n", dxtn_tex[x].expected_colors[i], color, i);
+ }
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
+ IDirect3DVolumeTexture9_Release(texture);
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
}
- hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
- ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
- IDirect3DVolumeTexture9_Release(texture);
- refcount = IDirect3DDevice9_Release(device);
- ok(!refcount, "Device has %u references left.\n", refcount);
-done:
IDirect3D9_Release(d3d);
DestroyWindow(window);
}
@@ -24131,7 +24194,7 @@ START_TEST(visual)
zenable_test();
fog_special_test();
volume_srgb_test();
- volume_dxt5_test();
+ volume_dxtn_test();
add_dirty_rect_test();
multisampled_depth_buffer_test();
resz_test();
--
2.7.4
June 22, 2018
[PATCH v2 1/2] wined3d: Add decompression functions for DXT1, DXT3, and DXT5
by Connor McAdams
This adds decompression functions for DXT1, DXT3, and DXT5 formats,
which covers all the possible DXT formats. These are used for
decompressing DXTn volume textures, and converting them to b8g8r8a8.
This patch also makes sure only 3D DXTn textures are uploaded by
performing a check in the wined3d_texture_upload_data function.
Signed-off-by: Connor McAdams <conmanx360(a)gmail.com>
---
dlls/wined3d/texture.c | 26 ++++
dlls/wined3d/utils.c | 323 ++++++++++++++++++++++++++++++++++++++++++++++---
2 files changed, 333 insertions(+), 16 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index c316906..a998b9c 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1948,6 +1948,32 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
bo.addr += src_box->left * format->byte_count;
}
+ if (format->id == WINED3DFMT_DXT5 || format->id == WINED3DFMT_DXT4 ||
+ format->id == WINED3DFMT_DXT3 || format->id == WINED3DFMT_DXT2 ||
+ format->id == WINED3DFMT_DXT1)
+ {
+ if (target == GL_TEXTURE_3D)
+ {
+ struct wined3d_format temp;
+
+ f = *format;
+ temp.upload = f.upload;
+ format = &f;
+ format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM, WINED3DUSAGE_TEXTURE);
+ f = *format;
+ f.upload = temp.upload;
+ f.conv_byte_count = 4;
+ format = &f;
+ texture->resource.format_flags &= ~WINED3DFMT_FLAG_BLOCKS;
+ }
+ else
+ {
+ f = *format;
+ f.upload = NULL;
+ format = &f;
+ }
+ }
+
if (format->upload)
{
unsigned int dst_row_pitch, dst_slice_pitch;
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 937c1bc..719f23e 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -840,6 +840,307 @@ static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_p
}
}
+static void dxt5_decompress_block(const BYTE *src, BYTE *dst, UINT width, UINT height, UINT depth,
+ UINT x_pos, UINT y_pos, UINT z_pos, UINT dst_slice_pitch, UINT64 cur_block)
+{
+ UINT64 alpha_block, alpha_index, color_block, color_index;
+ const UINT64 *source;
+ DWORD *dest;
+ DWORD alpha_lookup;
+ DWORD bgra;
+ DWORD temp;
+ DWORD i, x, y;
+ WORD color[2];
+ BYTE alpha_val, color_val;
+ BYTE alpha[8];
+ BYTE r[4];
+ BYTE g[4];
+ BYTE b[4];
+
+ source = (const UINT64 *)(src + cur_block * 16);
+ alpha_block = source[0];
+ color_block = source[1];
+
+ alpha[0] = alpha_block & 0xff;
+ alpha[1] = (alpha_block >> 8) & 0xff;
+
+ if (alpha[0] > alpha[1])
+ {
+ for (i = 0; i < 6; ++i)
+ alpha[2 + i] = (((6 - i) * alpha[0]) + ((1 + i) * alpha[1])) / 7;
+ }
+ else if (alpha[0] <= alpha[1])
+ {
+ for (i = 0; i < 4; ++i)
+ alpha[2 + i] = (((4 - i) * alpha[0]) + ((1 + i) * alpha[1])) / 5;
+ alpha[6] = 0;
+ alpha[7] = 255;
+ }
+
+ color[0] = color_block & 0xffff;
+ color[1] = (color_block >> 16) & 0xffff;
+
+ for (i = 0; i < 2; ++i)
+ {
+ temp = (color[i] >> 11) * 255 + 16;
+ r[i] = (temp / 32 + temp) / 32;
+ temp = ((color[i] >> 5) & 0x3f) * 255 + 32;
+ g[i] = (temp / 64 + temp) / 64;
+ temp = (color[i] & 0x1f) * 255 + 16;
+ b[i] = (temp / 32 + temp) / 32;
+ }
+
+ for (i = 0; i < 2; ++i)
+ {
+ r[2 + i] = (2 * r[0 + i] + r[1 - i]) / 3;
+ g[2 + i] = (2 * g[0 + i] + g[1 - i]) / 3;
+ b[2 + i] = (2 * b[0 + i] + b[1 - i]) / 3;
+ }
+
+ color_index = (color_block >> 32) & 0xffffffff;
+ alpha_index = (alpha_block >> 16);
+
+ dest = (DWORD *)(dst + z_pos * dst_slice_pitch);
+
+ for (y = 0; y < 4; ++y)
+ {
+ if (y_pos + y >= height)
+ break;
+ for (x = 0; x < 4; ++x)
+ {
+ if (x_pos + x >= width)
+ break;
+
+ color_val = 0;
+ alpha_val = 0;
+ bgra = 0;
+
+ color_val = (color_index >> (y * 8));
+ color_val = (color_val >> (x * 2)) & 0x3;
+ alpha_lookup = (alpha_index >> (y * 12)) & 0xfff;
+ alpha_val = (alpha_lookup >> (x * 3)) & 0x7;
+ bgra = ((alpha[alpha_val] << 24) | (r[color_val] << 16) | (g[color_val] << 8) | b[color_val]);
+ dest[(y_pos + y) * width + (x_pos + x)] = bgra;
+ }
+ }
+}
+
+static void convert_dxt5_b8g8r8a8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
+ UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
+{
+ UINT64 current_block;
+ DWORD x, y, z;
+
+ current_block = 0;
+
+ for (z = 0; z < depth; ++z)
+ {
+ for (y = 0; y < height; y += 4)
+ {
+ for (x = 0; x < width; x += 4)
+ {
+ dxt5_decompress_block(src, dst, width, height, depth, x, y, z, dst_slice_pitch, current_block);
+ current_block++;
+ }
+ }
+ }
+}
+
+static void dxt3_decompress_block(const BYTE *src, BYTE *dst, UINT width, UINT height, UINT depth,
+ UINT x_pos, UINT y_pos, UINT z_pos, UINT dst_slice_pitch, UINT64 cur_block)
+{
+ UINT64 alpha_block, alpha_lookup, color_block, color_index;
+ const UINT64 *source;
+ DWORD *dest;
+ DWORD bgra;
+ DWORD temp;
+ DWORD i, x, y;
+ WORD color[2];
+ BYTE alpha_val, color_val;
+ BYTE r[4];
+ BYTE g[4];
+ BYTE b[4];
+
+ source = (const UINT64 *)(src + cur_block * 16);
+ alpha_block = source[0];
+ color_block = source[1];
+
+ color[0] = color_block & 0xffff;
+ color[1] = (color_block >> 16) & 0xffff;
+
+ for (i = 0; i < 2; ++i)
+ {
+ temp = (color[i] >> 11) * 255 + 16;
+ r[i] = (temp / 32 + temp) / 32;
+ temp = ((color[i] >> 5) & 0x3f) * 255 + 32;
+ g[i] = (temp / 64 + temp) / 64;
+ temp = (color[i] & 0x1f) * 255 + 16;
+ b[i] = (temp / 32 + temp) / 32;
+ }
+
+ for (i = 0; i < 2; ++i)
+ {
+ r[2 + i] = (2 * r[0 + i] + r[1 - i]) / 3;
+ g[2 + i] = (2 * g[0 + i] + g[1 - i]) / 3;
+ b[2 + i] = (2 * b[0 + i] + b[1 - i]) / 3;
+ }
+
+ color_index = (color_block >> 32) & 0xffffffff;
+ dest = (DWORD *)(dst + z_pos * dst_slice_pitch);
+
+ for (y = 0; y < 4; ++y)
+ {
+ if (y_pos + y >= height)
+ break;
+ for (x = 0; x < 4; ++x)
+ {
+ if (x_pos + x >= width)
+ break;
+
+ color_val = 0;
+ alpha_val = 0;
+ bgra = 0;
+
+ color_val = (color_index >> (y * 8));
+ color_val = (color_val >> (x * 2)) & 0x3;
+
+ alpha_lookup = (alpha_block >> (y * 16)) & 0xffff;
+ alpha_val = (alpha_lookup >> (x * 4)) & 0xf;
+ temp = alpha_val * 255 + 8;
+ alpha_val = (temp / 16 + temp) / 16;
+
+ bgra = ((alpha_val << 24) | (r[color_val] << 16) | (g[color_val] << 8) | b[color_val]);
+ dest[(y_pos + y) * width + (x_pos + x)] = bgra;
+ }
+ }
+}
+
+static void convert_dxt3_b8g8r8a8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
+ UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
+{
+ UINT64 current_block;
+ DWORD x, y, z;
+
+ current_block = 0;
+
+ for (z = 0; z < depth; ++z)
+ {
+ for (y = 0; y < height; y += 4)
+ {
+ for (x = 0; x < width; x += 4)
+ {
+ dxt3_decompress_block(src, dst, width, height, depth, x, y, z, dst_slice_pitch, current_block);
+ current_block++;
+ }
+ }
+ }
+}
+
+static void dxt1_decompress_block(const BYTE *src, BYTE *dst, UINT width, UINT height, UINT depth,
+ UINT x_pos, UINT y_pos, UINT z_pos, UINT dst_slice_pitch, UINT64 cur_block)
+{
+ UINT64 color_block, color_index;
+ const UINT64 *source;
+ DWORD *dest;
+ DWORD bgra;
+ DWORD temp;
+ DWORD i, x, y;
+ WORD color[2];
+ BYTE color_val;
+ BYTE alpha;
+ BYTE r[4];
+ BYTE g[4];
+ BYTE b[4];
+ BYTE use_alpha;
+
+ source = (const UINT64 *)(src + cur_block * 8);
+ color_block = source[0];
+
+ color[0] = color_block & 0xffff;
+ color[1] = (color_block >> 16) & 0xffff;
+
+ for (i = 0; i < 2; ++i)
+ {
+ temp = (color[i] >> 11) * 255 + 16;
+ r[i] = (temp / 32 + temp) / 32;
+ temp = ((color[i] >> 5) & 0x3f) * 255 + 32;
+ g[i] = (temp / 64 + temp) / 64;
+ temp = (color[i] & 0x1f) * 255 + 16;
+ b[i] = (temp / 32 + temp) / 32;
+ }
+
+ if (color[0] > color[1])
+ {
+ for (i = 0; i < 2; ++i)
+ {
+ r[2 + i] = (2 * r[0 + i] + r[1 - i]) / 3;
+ g[2 + i] = (2 * g[0 + i] + g[1 - i]) / 3;
+ b[2 + i] = (2 * b[0 + i] + b[1 - i]) / 3;
+ }
+ use_alpha = 0;
+ }
+ else if (color[0] <= color[1])
+ {
+ r[2] = (r[0] + r[1]) / 2;
+ g[2] = (g[0] + g[1]) / 2;
+ b[2] = (b[0] + b[1]) / 2;
+
+ r[3] = 0;
+ g[3] = 0;
+ b[3] = 0;
+
+ use_alpha = 1;
+ }
+
+ color_index = (color_block >> 32) & 0xffffffff;
+ dest = (DWORD *)(dst + z_pos * dst_slice_pitch);
+
+ for (y = 0; y < 4; ++y)
+ {
+ if (y_pos + y >= height)
+ break;
+ for (x = 0; x < 4; ++x)
+ {
+ if (x_pos + x >= width)
+ break;
+
+ color_val = 0;
+ bgra = 0;
+
+ color_val = (color_index >> (y * 8));
+ color_val = (color_val >> (x * 2)) & 0x3;
+ if (color_val == 3 && use_alpha == 1)
+ alpha = 0;
+ else
+ alpha = 255;
+
+ bgra = ((alpha << 24) | (r[color_val] << 16) | (g[color_val] << 8) | b[color_val]);
+ dest[(y_pos + y) * width + (x_pos + x)] = bgra;
+ }
+ }
+}
+
+static void convert_dxt1_b8g8r8a8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
+ UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
+{
+ UINT64 current_block;
+ DWORD x, y, z;
+
+ current_block = 0;
+
+ for (z = 0; z < depth; ++z)
+ {
+ for (y = 0; y < height; y += 4)
+ {
+ for (x = 0; x < width; x += 4)
+ {
+ dxt1_decompress_block(src, dst, width, height, depth, x, y, z, dst_slice_pitch, current_block);
+ current_block++;
+ }
+ }
+ }
+}
+
static void x8_d24_unorm_upload(const BYTE *src, BYTE *dst,
unsigned int src_row_pitch, unsigned int src_slice_pitch,
unsigned int dst_row_pitch, unsigned int dst_slice_pitch,
@@ -1118,27 +1419,27 @@ static const struct wined3d_format_texture_info format_texture_info[] =
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt1_b8g8r8a8_unorm},
{WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt3_b8g8r8a8_unorm},
{WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt3_b8g8r8a8_unorm},
{WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt5_b8g8r8a8_unorm},
{WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt5_b8g8r8a8_unorm},
{WINED3DFMT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
@@ -3394,17 +3695,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
* for dx9 GPUs support it, some do not, so not supporting DXTn volumes is OK for d3d9.
*
* Note that GL_NV_texture_compression_vtc adds this functionality to OpenGL, but the
- * block layout is not compatible with the one used by d3d. See volume_dxt5_test. */
- idx = get_format_idx(WINED3DFMT_DXT1);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT2);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT3);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT4);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT5);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ * block layout is not compatible with the one used by d3d. See volume_dxtn_test. */
idx = get_format_idx(WINED3DFMT_BC1_UNORM);
gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
idx = get_format_idx(WINED3DFMT_BC1_UNORM_SRGB);
--
2.7.4
June 22, 2018
[PATCH v2 0/2] wined3d: Add DXTn Volume Texture Support
by Connor McAdams
This patchset adds support for DXTn volume textures by using the CPU to
decompress and convert them into a format the GPU can handle. It only
decompresses DXTn volume textures, and leaves regular 2D DXTn textures
alone.
Connor McAdams (2):
wined3d: Add decompression functions for DXT1, DXT3, and DXT5
wined3d: Add new test for DXTn volume textures.
dlls/d3d9/tests/visual.c | 183 ++++++++++++++++++---------
dlls/wined3d/texture.c | 26 ++++
dlls/wined3d/utils.c | 323 ++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 456 insertions(+), 76 deletions(-)
--
2.7.4
June 22, 2018
Re: [PATCH 3/4] shell32/tests: Add tests for SHGetKnownFolderPath() flags.
by Fabian Maurer
While probably not very relevant, when doing something like
----------
SHSetKnownFolderPath(&FOLDERID_SavedGames, KF_FLAG_DONT_UNEXPAND,
NULL, new_path);
SHGetKnownFolderPath(&FOLDERID_SavedGames, KF_FLAG_DONT_UNEXPAND, 0,
&path2);
----------
then KF_FLAG_DONT_UNEXPAND still doesn't seem to do anything.I figured that's
where the flag was useful, but it is completely ignored.
Do we want a testcase for that too?
Regards,
Fabian Maurer
June 22, 2018
[PATCH v3] msvcrt: Use already existent oneexit_table functions for _onexit and _c_exit
by Fabian Maurer
For that to work, MSVCRT__register_onexit_function and
MSVCRT__execute_onexit_table have to available all the time,
not only when _MSVCR_VER>=140
tests based on code by Piotr Caban
v2:
Create exit_event2 in test function, so it exists in child process
v3:
Keep exitlock
Keep _MSVCR_VER>=140 functions _MSVCR_VER>=140
Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de>
---
dlls/msvcrt/exit.c | 195 ++++++++++++++++++-------------------
dlls/ucrtbase/tests/misc.c | 74 +++++++++++++-
2 files changed, 166 insertions(+), 103 deletions(-)
diff --git a/dlls/msvcrt/exit.c b/dlls/msvcrt/exit.c
index 7e1805569c4..602a80a0513 100644
--- a/dlls/msvcrt/exit.c
+++ b/dlls/msvcrt/exit.c
@@ -29,9 +29,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(msvcrt);
#define LOCK_EXIT _mlock(_EXIT_LOCK1)
#define UNLOCK_EXIT _munlock(_EXIT_LOCK1)
-static MSVCRT__onexit_t *MSVCRT_atexit_table = NULL;
-static int MSVCRT_atexit_table_size = 0;
-static int MSVCRT_atexit_registered = 0; /* Points to free slot */
static MSVCRT_purecall_handler purecall_handler = NULL;
typedef struct MSVCRT__onexit_table_t
@@ -41,6 +38,8 @@ typedef struct MSVCRT__onexit_table_t
MSVCRT__onexit_t *_end;
} MSVCRT__onexit_table_t;
+static MSVCRT__onexit_table_t MSVCRT_atexit_table;
+
typedef void (__stdcall *_tls_callback_type)(void*,ULONG,void*);
static _tls_callback_type tls_atexit_callback;
@@ -61,21 +60,97 @@ static int MSVCRT_error_mode = MSVCRT__OUT_TO_DEFAULT;
void (*CDECL _aexit_rtn)(int) = MSVCRT__exit;
+static int __MSVCRT__initialize_onexit_table(MSVCRT__onexit_table_t *table)
+{
+ if (!table)
+ return -1;
+
+ if (table->_first == table->_end)
+ table->_last = table->_end = table->_first = NULL;
+ return 0;
+}
+
+
+/* INTERNAL: register onexit function */
+static int __MSVCRT__register_onexit_function(MSVCRT__onexit_table_t *table, MSVCRT__onexit_t func)
+{
+ if (!table)
+ return -1;
+
+ EnterCriticalSection(&MSVCRT_onexit_cs);
+ if (!table->_first)
+ {
+ table->_first = MSVCRT_calloc(32, sizeof(void *));
+ if (!table->_first)
+ {
+ WARN("failed to allocate initial table.\n");
+ LeaveCriticalSection(&MSVCRT_onexit_cs);
+ return -1;
+ }
+ table->_last = table->_first;
+ table->_end = table->_first + 32;
+ }
+
+ /* grow if full */
+ if (table->_last == table->_end)
+ {
+ int len = table->_end - table->_first;
+ MSVCRT__onexit_t *tmp = MSVCRT_realloc(table->_first, 2 * len * sizeof(void *));
+ if (!tmp)
+ {
+ WARN("failed to grow table.\n");
+ LeaveCriticalSection(&MSVCRT_onexit_cs);
+ return -1;
+ }
+ table->_first = tmp;
+ table->_end = table->_first + 2 * len;
+ table->_last = table->_first + len;
+ }
+
+ *table->_last = func;
+ table->_last++;
+ LeaveCriticalSection(&MSVCRT_onexit_cs);
+ return 0;
+}
+
+/* INTERNAL: call onexit functions */
+static int __MSVCRT__execute_onexit_table(MSVCRT__onexit_table_t *table)
+{
+ MSVCRT__onexit_t *func;
+ MSVCRT__onexit_table_t copy;
+
+ if (!table)
+ return -1;
+
+ EnterCriticalSection(&MSVCRT_onexit_cs);
+ if (!table->_first || table->_first >= table->_last)
+ {
+ LeaveCriticalSection(&MSVCRT_onexit_cs);
+ return 0;
+ }
+ copy._first = table->_first;
+ copy._last = table->_last;
+ copy._end = table->_end;
+ memset(table, 0, sizeof(*table));
+ __MSVCRT__initialize_onexit_table(table);
+ LeaveCriticalSection(&MSVCRT_onexit_cs);
+
+ for (func = copy._last - 1; func >= copy._first; func--)
+ {
+ if (*func)
+ (*func)();
+ }
+
+ MSVCRT_free(copy._first);
+ return 0;
+}
+
/* INTERNAL: call atexit functions */
static void __MSVCRT__call_atexit(void)
{
/* Note: should only be called with the exit lock held */
- TRACE("%d atext functions to call\n", MSVCRT_atexit_registered);
if (tls_atexit_callback) tls_atexit_callback(NULL, DLL_PROCESS_DETACH, NULL);
- /* Last registered gets executed first */
- while (MSVCRT_atexit_registered > 0)
- {
- MSVCRT_atexit_registered--;
- TRACE("next is %p\n",MSVCRT_atexit_table[MSVCRT_atexit_registered]);
- if (MSVCRT_atexit_table[MSVCRT_atexit_registered])
- (*MSVCRT_atexit_table[MSVCRT_atexit_registered])();
- TRACE("returned\n");
- }
+ __MSVCRT__execute_onexit_table(&MSVCRT_atexit_table);
}
/*********************************************************************
@@ -292,25 +367,9 @@ MSVCRT__onexit_t CDECL MSVCRT__onexit(MSVCRT__onexit_t func)
return NULL;
LOCK_EXIT;
- if (MSVCRT_atexit_registered > MSVCRT_atexit_table_size - 1)
- {
- MSVCRT__onexit_t *newtable;
- TRACE("expanding table\n");
- newtable = MSVCRT_calloc(MSVCRT_atexit_table_size + 32, sizeof(void *));
- if (!newtable)
- {
- TRACE("failed!\n");
- UNLOCK_EXIT;
- return NULL;
- }
- memcpy (newtable, MSVCRT_atexit_table, MSVCRT_atexit_table_size*sizeof(void *));
- MSVCRT_atexit_table_size += 32;
- MSVCRT_free (MSVCRT_atexit_table);
- MSVCRT_atexit_table = newtable;
- }
- MSVCRT_atexit_table[MSVCRT_atexit_registered] = func;
- MSVCRT_atexit_registered++;
+ __MSVCRT__register_onexit_function(&MSVCRT_atexit_table, func);
UNLOCK_EXIT;
+
return func;
}
@@ -359,7 +418,6 @@ int CDECL MSVCRT__crt_atexit(void (*func)(void))
return MSVCRT__onexit((MSVCRT__onexit_t)func) == (MSVCRT__onexit_t)func ? 0 : -1;
}
-
/*********************************************************************
* _initialize_onexit_table (UCRTBASE.@)
*/
@@ -367,12 +425,7 @@ int CDECL MSVCRT__initialize_onexit_table(MSVCRT__onexit_table_t *table)
{
TRACE("(%p)\n", table);
- if (!table)
- return -1;
-
- if (table->_first == table->_end)
- table->_last = table->_end = table->_first = NULL;
- return 0;
+ return __MSVCRT__initialize_onexit_table(table);
}
/*********************************************************************
@@ -382,43 +435,7 @@ int CDECL MSVCRT__register_onexit_function(MSVCRT__onexit_table_t *table, MSVCRT
{
TRACE("(%p %p)\n", table, func);
- if (!table)
- return -1;
-
- EnterCriticalSection(&MSVCRT_onexit_cs);
- if (!table->_first)
- {
- table->_first = MSVCRT_calloc(32, sizeof(void *));
- if (!table->_first)
- {
- WARN("failed to allocate initial table.\n");
- LeaveCriticalSection(&MSVCRT_onexit_cs);
- return -1;
- }
- table->_last = table->_first;
- table->_end = table->_first + 32;
- }
-
- /* grow if full */
- if (table->_last == table->_end)
- {
- int len = table->_end - table->_first;
- MSVCRT__onexit_t *tmp = MSVCRT_realloc(table->_first, 2 * len * sizeof(void *));
- if (!tmp)
- {
- WARN("failed to grow table.\n");
- LeaveCriticalSection(&MSVCRT_onexit_cs);
- return -1;
- }
- table->_first = tmp;
- table->_end = table->_first + 2 * len;
- table->_last = table->_first + len;
- }
-
- *table->_last = func;
- table->_last++;
- LeaveCriticalSection(&MSVCRT_onexit_cs);
- return 0;
+ return __MSVCRT__register_onexit_function(table, func);
}
/*********************************************************************
@@ -426,35 +443,9 @@ int CDECL MSVCRT__register_onexit_function(MSVCRT__onexit_table_t *table, MSVCRT
*/
int CDECL MSVCRT__execute_onexit_table(MSVCRT__onexit_table_t *table)
{
- MSVCRT__onexit_t *func;
- MSVCRT__onexit_table_t copy;
-
TRACE("(%p)\n", table);
- if (!table)
- return -1;
-
- EnterCriticalSection(&MSVCRT_onexit_cs);
- if (!table->_first || table->_first >= table->_last)
- {
- LeaveCriticalSection(&MSVCRT_onexit_cs);
- return 0;
- }
- copy._first = table->_first;
- copy._last = table->_last;
- copy._end = table->_end;
- memset(table, 0, sizeof(*table));
- MSVCRT__initialize_onexit_table(table);
- LeaveCriticalSection(&MSVCRT_onexit_cs);
-
- for (func = copy._last - 1; func >= copy._first; func--)
- {
- if (*func)
- (*func)();
- }
-
- MSVCRT_free(copy._first);
- return 0;
+ return __MSVCRT__execute_onexit_table(table);
}
/*********************************************************************
diff --git a/dlls/ucrtbase/tests/misc.c b/dlls/ucrtbase/tests/misc.c
index 354fab1e940..ed5bb0589c8 100644
--- a/dlls/ucrtbase/tests/misc.c
+++ b/dlls/ucrtbase/tests/misc.c
@@ -125,6 +125,8 @@ static int (CDECL *p_fesetround)(int);
static void (CDECL *p___setusermatherr)(MSVCRT_matherr_func);
static int* (CDECL *p_errno)(void);
static char* (CDECL *p_asctime)(const struct tm *);
+static void (CDECL *p_exit)(int);
+static int (CDECL *p__crt_atexit)(void (CDECL*)(void));
static void test__initialize_onexit_table(void)
{
@@ -429,6 +431,8 @@ static BOOL init(void)
p___setusermatherr = (void*)GetProcAddress(module, "__setusermatherr");
p_errno = (void*)GetProcAddress(module, "_errno");
p_asctime = (void*)GetProcAddress(module, "asctime");
+ p__crt_atexit = (void*)GetProcAddress(module, "_crt_atexit");
+ p_exit = (void*)GetProcAddress(module, "exit");
return TRUE;
}
@@ -765,6 +769,70 @@ static void test_asctime(void)
ok(!strcmp(ret, "Thu Jan 1 00:00:00 1970\n"), "asctime returned %s\n", ret);
}
+static void test_exit(const char *argv0)
+{
+ HANDLE exit_event1, exit_event2;
+ PROCESS_INFORMATION proc;
+ STARTUPINFOA startup = {0};
+ char path[MAX_PATH];
+ DWORD ret;
+
+ exit_event1 = CreateEventA(NULL, FALSE, FALSE, "exit_event1");
+ exit_event2 = CreateEventA(NULL, FALSE, FALSE, "exit_event2");
+
+ sprintf(path, "%s misc exit", argv0);
+ startup.cb = sizeof(startup);
+ CreateProcessA(NULL, path, NULL, NULL, TRUE, 0, NULL, NULL, &startup, &proc);
+ winetest_wait_child_process(proc.hProcess);
+
+ ret = WaitForSingleObject(exit_event1, 0);
+ ok(ret == WAIT_OBJECT_0, "exit_event1 was not set (%x)\n", ret);
+
+ CloseHandle(exit_event1);
+ CloseHandle(exit_event2);
+}
+
+static void CDECL at_exit_func1(void)
+{
+ HANDLE exit_event1 = CreateEventA(NULL, FALSE, FALSE, "exit_event1");
+ HANDLE exit_event2 = CreateEventA(NULL, FALSE, FALSE, "exit_event2");
+ DWORD ret;
+
+ ok(exit_event1 != NULL, "CreateEvent failed: %d\n", GetLastError());
+ ok(exit_event2 != NULL, "CreateEvent failed: %d\n", GetLastError());
+
+ ret = WaitForSingleObject(exit_event2, 0);
+ ok(ret == WAIT_OBJECT_0, "exit_event2 was not set (%x)\n", ret);
+
+ SetEvent(exit_event1);
+ CloseHandle(exit_event1);
+ CloseHandle(exit_event2);
+}
+
+static void CDECL at_exit_func2(void)
+{
+ HANDLE exit_event1 = CreateEventA(NULL, FALSE, FALSE, "exit_event1");
+ HANDLE exit_event2 = CreateEventA(NULL, FALSE, FALSE, "exit_event2");
+ DWORD ret;
+
+ ok(exit_event1 != NULL, "CreateEvent failed: %d\n", GetLastError());
+ ok(exit_event2 != NULL, "CreateEvent failed: %d\n", GetLastError());
+
+ ret = WaitForSingleObject(exit_event1, 0);
+ ok(ret == WAIT_TIMEOUT, "exit_event1 should not be set (%x)\n", ret);
+
+ SetEvent(exit_event2);
+ CloseHandle(exit_event1);
+ CloseHandle(exit_event2);
+}
+
+static void test_call_exit(void)
+{
+ ok(!p__crt_atexit(at_exit_func1), "_crt_atexit failed\n");
+ ok(!p__crt_atexit(at_exit_func2), "_crt_atexit failed\n");
+ p_exit(0);
+}
+
START_TEST(misc)
{
int arg_c;
@@ -775,7 +843,10 @@ START_TEST(misc)
arg_c = winetest_get_mainargs(&arg_v);
if(arg_c == 3) {
- test__get_narrow_winmain_command_line(NULL);
+ if(!strcmp(arg_v[2], "cmd"))
+ test__get_narrow_winmain_command_line(NULL);
+ else if(!strcmp(arg_v[2], "exit"))
+ test_call_exit();
return;
}
@@ -791,4 +862,5 @@ START_TEST(misc)
test_isblank();
test_math_errors();
test_asctime();
+ test_exit(arg_v[0]);
}
--
2.18.0
June 22, 2018
Re: [PATCH v2] msvcrt: Use already existent oneexit_table functions for _onexit and _c_exit
by Fabian Maurer
> It's still needed to hold the exit lock. Older versions of msvcrt
were
> doing it (I didn't test if newer versions are still using this lock).
Thanks, I'll have an updated version soon. Though I don't see a
good way to write a test for this lock.
Regards,
Fabian Maurer
June 22, 2018
Re: [PATCH] mp3dmod: Support COM aggregation.
by Zebediah Figura
On 06/22/2018 01:22 PM, Jacek Caban wrote:
> Hi Zebediah,
>
> On 06/22/2018 08:06 PM, Zebediah Figura wrote:
>> -static HRESULT create_mp3_decoder(REFIID iid, void **obj)
>> +static HRESULT create_mp3_decoder(IUnknown *outer, REFIID iid, void **obj)
>> {
>> struct mp3_decoder *This;
>> int err;
>> @@ -424,15 +457,17 @@ static HRESULT create_mp3_decoder(REFIID iid, void **obj)
>> if (!(This = heap_alloc_zero(sizeof(*This))))
>> return E_OUTOFMEMORY;
>>
>> - This->IMediaObject_iface.lpVtbl = &IMediaObject_vtbl;
>> + This->IUnknown_inner.lpVtbl = &Unknown_vtbl;
>> + This->IMediaObject_iface.lpVtbl = &MediaObject_vtbl;
>> This->ref = 0;
>> + This->outer = outer ? outer : &This->IUnknown_inner;
>>
>> mpg123_init();
>> This->mh = mpg123_new(NULL, &err);
>> mpg123_open_feed(This->mh);
>> mpg123_format_none(This->mh);
>>
>> - return IMediaObject_QueryInterface(&This->IMediaObject_iface, iid, obj);
>> + return IUnknown_QueryInterface(&This->IUnknown_inner, iid, obj);
>
>
> This leaks in non-aggregated case if QueryInterface fails.
>
>
> Jacek
>
Thanks; I've sent an updated patch.
June 22, 2018
[PATCH v2] mp3dmod: Support COM aggregation.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/mp3dmod/mp3dmod.c | 80 ++++++++++++++++++++++++++++++++------------
dlls/mp3dmod/tests/mp3dmod.c | 57 +++++++++++++++++++++++++++++++
2 files changed, 116 insertions(+), 21 deletions(-)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c
index 4949780..90bcf66 100644
--- a/dlls/mp3dmod/mp3dmod.c
+++ b/dlls/mp3dmod/mp3dmod.c
@@ -43,7 +43,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(mp3dmod);
static HINSTANCE mp3dmod_instance;
struct mp3_decoder {
+ IUnknown IUnknown_inner;
IMediaObject IMediaObject_iface;
+ IUnknown *outer;
LONG ref;
mpg123_handle *mh;
DMO_MEDIA_TYPE outtype;
@@ -51,33 +53,35 @@ struct mp3_decoder {
REFERENCE_TIME timestamp;
};
-static inline struct mp3_decoder *impl_from_IMediaObject(IMediaObject *iface)
+static inline struct mp3_decoder *impl_from_IUnknown(IUnknown *iface)
{
- return CONTAINING_RECORD(iface, struct mp3_decoder, IMediaObject_iface);
+ return CONTAINING_RECORD(iface, struct mp3_decoder, IUnknown_inner);
}
-static HRESULT WINAPI MediaObject_QueryInterface(IMediaObject *iface, REFIID iid, void **ppv)
+static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID iid, void **obj)
{
- struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ struct mp3_decoder *This = impl_from_IUnknown(iface);
- TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), ppv);
+ TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);
- if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IMediaObject))
- *ppv = &This->IMediaObject_iface;
+ if (IsEqualGUID(iid, &IID_IUnknown))
+ *obj = &This->IUnknown_inner;
+ else if (IsEqualGUID(iid, &IID_IMediaObject))
+ *obj = &This->IMediaObject_iface;
else
{
FIXME("no interface for %s\n", debugstr_guid(iid));
- *ppv = NULL;
+ *obj = NULL;
return E_NOINTERFACE;
}
- IMediaObject_AddRef(iface);
+ IUnknown_AddRef((IUnknown *)*obj);
return S_OK;
}
-static ULONG WINAPI MediaObject_AddRef(IMediaObject *iface)
+static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
{
- struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ struct mp3_decoder *This = impl_from_IUnknown(iface);
ULONG refcount = InterlockedIncrement(&This->ref);
TRACE("(%p) AddRef from %d\n", This, refcount - 1);
@@ -85,9 +89,9 @@ static ULONG WINAPI MediaObject_AddRef(IMediaObject *iface)
return refcount;
}
-static ULONG WINAPI MediaObject_Release(IMediaObject *iface)
+static ULONG WINAPI Unknown_Release(IUnknown *iface)
{
- struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ struct mp3_decoder *This = impl_from_IUnknown(iface);
ULONG refcount = InterlockedDecrement(&This->ref);
TRACE("(%p) Release from %d\n", This, refcount + 1);
@@ -100,6 +104,35 @@ static ULONG WINAPI MediaObject_Release(IMediaObject *iface)
return refcount;
}
+static const IUnknownVtbl Unknown_vtbl = {
+ Unknown_QueryInterface,
+ Unknown_AddRef,
+ Unknown_Release,
+};
+
+static inline struct mp3_decoder *impl_from_IMediaObject(IMediaObject *iface)
+{
+ return CONTAINING_RECORD(iface, struct mp3_decoder, IMediaObject_iface);
+}
+
+static HRESULT WINAPI MediaObject_QueryInterface(IMediaObject *iface, REFIID iid, void **obj)
+{
+ struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ return IUnknown_QueryInterface(This->outer, iid, obj);
+}
+
+static ULONG WINAPI MediaObject_AddRef(IMediaObject *iface)
+{
+ struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ return IUnknown_AddRef(This->outer);
+}
+
+static ULONG WINAPI MediaObject_Release(IMediaObject *iface)
+{
+ struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ return IUnknown_Release(This->outer);
+}
+
static HRESULT WINAPI MediaObject_GetStreamCount(IMediaObject *iface, DWORD *input, DWORD *output)
{
FIXME("(%p)->(%p, %p) stub!\n", iface, input, output);
@@ -389,7 +422,7 @@ static HRESULT WINAPI MediaObject_Lock(IMediaObject *iface, LONG lock)
return E_NOTIMPL;
}
-static const IMediaObjectVtbl IMediaObject_vtbl = {
+static const IMediaObjectVtbl MediaObject_vtbl = {
MediaObject_QueryInterface,
MediaObject_AddRef,
MediaObject_Release,
@@ -416,23 +449,28 @@ static const IMediaObjectVtbl IMediaObject_vtbl = {
MediaObject_Lock,
};
-static HRESULT create_mp3_decoder(REFIID iid, void **obj)
+static HRESULT create_mp3_decoder(IUnknown *outer, REFIID iid, void **obj)
{
struct mp3_decoder *This;
+ HRESULT hr;
int err;
if (!(This = heap_alloc_zero(sizeof(*This))))
return E_OUTOFMEMORY;
- This->IMediaObject_iface.lpVtbl = &IMediaObject_vtbl;
- This->ref = 0;
+ This->IUnknown_inner.lpVtbl = &Unknown_vtbl;
+ This->IMediaObject_iface.lpVtbl = &MediaObject_vtbl;
+ This->ref = 1;
+ This->outer = outer ? outer : &This->IUnknown_inner;
mpg123_init();
This->mh = mpg123_new(NULL, &err);
mpg123_open_feed(This->mh);
mpg123_format_none(This->mh);
- return IMediaObject_QueryInterface(&This->IMediaObject_iface, iid, obj);
+ hr = IUnknown_QueryInterface(&This->IUnknown_inner, iid, obj);
+ IUnknown_Release(&This->IUnknown_inner);
+ return hr;
}
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void **obj)
@@ -466,13 +504,13 @@ static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown
{
TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj);
- if (outer)
+ if (outer && !IsEqualGUID(iid, &IID_IUnknown))
{
*obj = NULL;
- return CLASS_E_NOAGGREGATION;
+ return E_NOINTERFACE;
}
- return create_mp3_decoder(iid, obj);
+ return create_mp3_decoder(outer, iid, obj);
}
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock)
diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c
index 68c6b4d..75fd0e2 100644
--- a/dlls/mp3dmod/tests/mp3dmod.c
+++ b/dlls/mp3dmod/tests/mp3dmod.c
@@ -230,6 +230,62 @@ static void test_convert(void)
IMediaObject_Release(dmo);
}
+static const GUID IID_test_outer = {0xdeadbeef,0,0,{0,0,0,0,0,0,0,0x66}};
+
+static HRESULT WINAPI Outer_QueryInterface(IUnknown *iface, REFIID iid, void **obj)
+{
+ if (IsEqualGUID(iid, &IID_test_outer))
+ {
+ *obj = (IUnknown *)0xdeadbeef;
+ return S_OK;
+ }
+ ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI Outer_AddRef(IUnknown *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI Outer_Release(IUnknown *iface)
+{
+ return 1;
+}
+
+static IUnknownVtbl Outer_vtbl = {
+ Outer_QueryInterface,
+ Outer_AddRef,
+ Outer_Release,
+};
+
+static IUnknown Outer = { &Outer_vtbl };
+
+static void test_aggregation(void)
+{
+ IUnknown *unk, *unk2;
+ IMediaObject *dmo;
+ HRESULT hr;
+
+ hr = CoCreateInstance(&CLSID_CMP3DecMediaObject, &Outer, CLSCTX_INPROC_SERVER,
+ &IID_IUnknown, (void **)&unk);
+ ok(hr == S_OK, "got %#x\n", hr);
+
+ hr = IUnknown_QueryInterface(unk, &IID_IMediaObject, (void **)&dmo);
+ ok(hr == S_OK, "got %#x\n", hr);
+
+ hr = IMediaObject_QueryInterface(dmo, &IID_test_outer, (void **)&unk2);
+ ok(hr == S_OK, "got %#x\n", hr);
+ ok(unk2 == (IUnknown *)0xdeadbeef, "got unk %p\n", unk2);
+
+ IUnknown_Release(dmo);
+ IUnknown_Release(unk);
+
+ hr = CoCreateInstance(&CLSID_CMP3DecMediaObject, &Outer, CLSCTX_INPROC_SERVER,
+ &IID_IMediaObject, (void **)&unk);
+ ok(hr == E_NOINTERFACE, "got %#x\n", hr);
+}
+
START_TEST(mp3dmod)
{
IMediaObject *dmo;
@@ -247,6 +303,7 @@ START_TEST(mp3dmod)
IMediaObject_Release(dmo);
test_convert();
+ test_aggregation();
CoUninitialize();
}
--
2.7.4
June 22, 2018
[PATCH v3] user32: Always release menu item in EnableMenuItem
by Fabian Maurer
The menu must be release on all code-paths,
else the underlying lock will never be released.
Fixes bug 45355.
Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de>
---
dlls/user32/menu.c | 33 +++++++++++++++------------------
1 file changed, 15 insertions(+), 18 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 8c541cc4f91..ab1ae9bc1bd 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -3741,28 +3741,25 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
item->fState ^= (oldflags ^ wFlags) & (MF_GRAYED | MF_DISABLED);
/* If the close item in the system menu change update the close button */
- if ((item->wID == SC_CLOSE) && (oldflags != wFlags))
+ if ((item->wID == SC_CLOSE) && (oldflags != wFlags) && menu->hSysMenuOwner)
{
- if (menu->hSysMenuOwner)
- {
- RECT rc;
- POPUPMENU* parentMenu;
- HWND hwnd;
+ RECT rc;
+ POPUPMENU* parentMenu;
+ HWND hwnd;
- /* Get the parent menu to access*/
- parentMenu = grab_menu_ptr(menu->hSysMenuOwner);
- release_menu_ptr(menu);
- if (!parentMenu)
- return (UINT)-1;
+ /* Get the parent menu to access */
+ parentMenu = grab_menu_ptr(menu->hSysMenuOwner);
+ release_menu_ptr(menu);
+ if (!parentMenu)
+ return (UINT)-1;
- hwnd = parentMenu->hWnd;
- release_menu_ptr(parentMenu);
+ hwnd = parentMenu->hWnd;
+ release_menu_ptr(parentMenu);
- /* Refresh the frame to reflect the change */
- WIN_GetRectangles( hwnd, COORDS_CLIENT, &rc, NULL );
- rc.bottom = 0;
- RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
- }
+ /* Refresh the frame to reflect the change */
+ WIN_GetRectangles(hwnd, COORDS_CLIENT, &rc, NULL);
+ rc.bottom = 0;
+ RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
}
else
release_menu_ptr(menu);
--
2.18.0
June 22, 2018
Re: [PATCH] mp3dmod: Support COM aggregation.
by Jacek Caban
Hi Zebediah,
On 06/22/2018 08:06 PM, Zebediah Figura wrote:
> -static HRESULT create_mp3_decoder(REFIID iid, void **obj)
> +static HRESULT create_mp3_decoder(IUnknown *outer, REFIID iid, void **obj)
> {
> struct mp3_decoder *This;
> int err;
> @@ -424,15 +457,17 @@ static HRESULT create_mp3_decoder(REFIID iid, void **obj)
> if (!(This = heap_alloc_zero(sizeof(*This))))
> return E_OUTOFMEMORY;
>
> - This->IMediaObject_iface.lpVtbl = &IMediaObject_vtbl;
> + This->IUnknown_inner.lpVtbl = &Unknown_vtbl;
> + This->IMediaObject_iface.lpVtbl = &MediaObject_vtbl;
> This->ref = 0;
> + This->outer = outer ? outer : &This->IUnknown_inner;
>
> mpg123_init();
> This->mh = mpg123_new(NULL, &err);
> mpg123_open_feed(This->mh);
> mpg123_format_none(This->mh);
>
> - return IMediaObject_QueryInterface(&This->IMediaObject_iface, iid, obj);
> + return IUnknown_QueryInterface(&This->IUnknown_inner, iid, obj);
This leaks in non-aggregated case if QueryInterface fails.
Jacek
June 22, 2018
[PATCH] mp3dmod: Support COM aggregation.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/mp3dmod/mp3dmod.c | 75 ++++++++++++++++++++++++++++++++------------
dlls/mp3dmod/tests/mp3dmod.c | 57 +++++++++++++++++++++++++++++++++
2 files changed, 112 insertions(+), 20 deletions(-)
diff --git a/dlls/mp3dmod/mp3dmod.c b/dlls/mp3dmod/mp3dmod.c
index 4949780..4820c51 100644
--- a/dlls/mp3dmod/mp3dmod.c
+++ b/dlls/mp3dmod/mp3dmod.c
@@ -43,7 +43,9 @@ WINE_DEFAULT_DEBUG_CHANNEL(mp3dmod);
static HINSTANCE mp3dmod_instance;
struct mp3_decoder {
+ IUnknown IUnknown_inner;
IMediaObject IMediaObject_iface;
+ IUnknown *outer;
LONG ref;
mpg123_handle *mh;
DMO_MEDIA_TYPE outtype;
@@ -51,33 +53,35 @@ struct mp3_decoder {
REFERENCE_TIME timestamp;
};
-static inline struct mp3_decoder *impl_from_IMediaObject(IMediaObject *iface)
+static inline struct mp3_decoder *impl_from_IUnknown(IUnknown *iface)
{
- return CONTAINING_RECORD(iface, struct mp3_decoder, IMediaObject_iface);
+ return CONTAINING_RECORD(iface, struct mp3_decoder, IUnknown_inner);
}
-static HRESULT WINAPI MediaObject_QueryInterface(IMediaObject *iface, REFIID iid, void **ppv)
+static HRESULT WINAPI Unknown_QueryInterface(IUnknown *iface, REFIID iid, void **obj)
{
- struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ struct mp3_decoder *This = impl_from_IUnknown(iface);
- TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), ppv);
+ TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(iid), obj);
- if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IMediaObject))
- *ppv = &This->IMediaObject_iface;
+ if (IsEqualGUID(iid, &IID_IUnknown))
+ *obj = &This->IUnknown_inner;
+ else if (IsEqualGUID(iid, &IID_IMediaObject))
+ *obj = &This->IMediaObject_iface;
else
{
FIXME("no interface for %s\n", debugstr_guid(iid));
- *ppv = NULL;
+ *obj = NULL;
return E_NOINTERFACE;
}
- IMediaObject_AddRef(iface);
+ IUnknown_AddRef((IUnknown *)*obj);
return S_OK;
}
-static ULONG WINAPI MediaObject_AddRef(IMediaObject *iface)
+static ULONG WINAPI Unknown_AddRef(IUnknown *iface)
{
- struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ struct mp3_decoder *This = impl_from_IUnknown(iface);
ULONG refcount = InterlockedIncrement(&This->ref);
TRACE("(%p) AddRef from %d\n", This, refcount - 1);
@@ -85,9 +89,9 @@ static ULONG WINAPI MediaObject_AddRef(IMediaObject *iface)
return refcount;
}
-static ULONG WINAPI MediaObject_Release(IMediaObject *iface)
+static ULONG WINAPI Unknown_Release(IUnknown *iface)
{
- struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ struct mp3_decoder *This = impl_from_IUnknown(iface);
ULONG refcount = InterlockedDecrement(&This->ref);
TRACE("(%p) Release from %d\n", This, refcount + 1);
@@ -100,6 +104,35 @@ static ULONG WINAPI MediaObject_Release(IMediaObject *iface)
return refcount;
}
+static const IUnknownVtbl Unknown_vtbl = {
+ Unknown_QueryInterface,
+ Unknown_AddRef,
+ Unknown_Release,
+};
+
+static inline struct mp3_decoder *impl_from_IMediaObject(IMediaObject *iface)
+{
+ return CONTAINING_RECORD(iface, struct mp3_decoder, IMediaObject_iface);
+}
+
+static HRESULT WINAPI MediaObject_QueryInterface(IMediaObject *iface, REFIID iid, void **obj)
+{
+ struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ return IUnknown_QueryInterface(This->outer, iid, obj);
+}
+
+static ULONG WINAPI MediaObject_AddRef(IMediaObject *iface)
+{
+ struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ return IUnknown_AddRef(This->outer);
+}
+
+static ULONG WINAPI MediaObject_Release(IMediaObject *iface)
+{
+ struct mp3_decoder *This = impl_from_IMediaObject(iface);
+ return IUnknown_Release(This->outer);
+}
+
static HRESULT WINAPI MediaObject_GetStreamCount(IMediaObject *iface, DWORD *input, DWORD *output)
{
FIXME("(%p)->(%p, %p) stub!\n", iface, input, output);
@@ -389,7 +422,7 @@ static HRESULT WINAPI MediaObject_Lock(IMediaObject *iface, LONG lock)
return E_NOTIMPL;
}
-static const IMediaObjectVtbl IMediaObject_vtbl = {
+static const IMediaObjectVtbl MediaObject_vtbl = {
MediaObject_QueryInterface,
MediaObject_AddRef,
MediaObject_Release,
@@ -416,7 +449,7 @@ static const IMediaObjectVtbl IMediaObject_vtbl = {
MediaObject_Lock,
};
-static HRESULT create_mp3_decoder(REFIID iid, void **obj)
+static HRESULT create_mp3_decoder(IUnknown *outer, REFIID iid, void **obj)
{
struct mp3_decoder *This;
int err;
@@ -424,15 +457,17 @@ static HRESULT create_mp3_decoder(REFIID iid, void **obj)
if (!(This = heap_alloc_zero(sizeof(*This))))
return E_OUTOFMEMORY;
- This->IMediaObject_iface.lpVtbl = &IMediaObject_vtbl;
+ This->IUnknown_inner.lpVtbl = &Unknown_vtbl;
+ This->IMediaObject_iface.lpVtbl = &MediaObject_vtbl;
This->ref = 0;
+ This->outer = outer ? outer : &This->IUnknown_inner;
mpg123_init();
This->mh = mpg123_new(NULL, &err);
mpg123_open_feed(This->mh);
mpg123_format_none(This->mh);
- return IMediaObject_QueryInterface(&This->IMediaObject_iface, iid, obj);
+ return IUnknown_QueryInterface(&This->IUnknown_inner, iid, obj);
}
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID iid, void **obj)
@@ -466,13 +501,13 @@ static HRESULT WINAPI ClassFactory_CreateInstance(IClassFactory *iface, IUnknown
{
TRACE("(%p, %s, %p)\n", outer, debugstr_guid(iid), obj);
- if (outer)
+ if (outer && !IsEqualGUID(iid, &IID_IUnknown))
{
*obj = NULL;
- return CLASS_E_NOAGGREGATION;
+ return E_NOINTERFACE;
}
- return create_mp3_decoder(iid, obj);
+ return create_mp3_decoder(outer, iid, obj);
}
static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL lock)
diff --git a/dlls/mp3dmod/tests/mp3dmod.c b/dlls/mp3dmod/tests/mp3dmod.c
index 68c6b4d..75fd0e2 100644
--- a/dlls/mp3dmod/tests/mp3dmod.c
+++ b/dlls/mp3dmod/tests/mp3dmod.c
@@ -230,6 +230,62 @@ static void test_convert(void)
IMediaObject_Release(dmo);
}
+static const GUID IID_test_outer = {0xdeadbeef,0,0,{0,0,0,0,0,0,0,0x66}};
+
+static HRESULT WINAPI Outer_QueryInterface(IUnknown *iface, REFIID iid, void **obj)
+{
+ if (IsEqualGUID(iid, &IID_test_outer))
+ {
+ *obj = (IUnknown *)0xdeadbeef;
+ return S_OK;
+ }
+ ok(0, "unexpected call %s\n", wine_dbgstr_guid(iid));
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI Outer_AddRef(IUnknown *iface)
+{
+ return 2;
+}
+
+static ULONG WINAPI Outer_Release(IUnknown *iface)
+{
+ return 1;
+}
+
+static IUnknownVtbl Outer_vtbl = {
+ Outer_QueryInterface,
+ Outer_AddRef,
+ Outer_Release,
+};
+
+static IUnknown Outer = { &Outer_vtbl };
+
+static void test_aggregation(void)
+{
+ IUnknown *unk, *unk2;
+ IMediaObject *dmo;
+ HRESULT hr;
+
+ hr = CoCreateInstance(&CLSID_CMP3DecMediaObject, &Outer, CLSCTX_INPROC_SERVER,
+ &IID_IUnknown, (void **)&unk);
+ ok(hr == S_OK, "got %#x\n", hr);
+
+ hr = IUnknown_QueryInterface(unk, &IID_IMediaObject, (void **)&dmo);
+ ok(hr == S_OK, "got %#x\n", hr);
+
+ hr = IMediaObject_QueryInterface(dmo, &IID_test_outer, (void **)&unk2);
+ ok(hr == S_OK, "got %#x\n", hr);
+ ok(unk2 == (IUnknown *)0xdeadbeef, "got unk %p\n", unk2);
+
+ IUnknown_Release(dmo);
+ IUnknown_Release(unk);
+
+ hr = CoCreateInstance(&CLSID_CMP3DecMediaObject, &Outer, CLSCTX_INPROC_SERVER,
+ &IID_IMediaObject, (void **)&unk);
+ ok(hr == E_NOINTERFACE, "got %#x\n", hr);
+}
+
START_TEST(mp3dmod)
{
IMediaObject *dmo;
@@ -247,6 +303,7 @@ START_TEST(mp3dmod)
IMediaObject_Release(dmo);
test_convert();
+ test_aggregation();
CoUninitialize();
}
--
2.7.4
June 22, 2018
[PATCH] crypt32/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/crypt32/tests/base64.c | 10 ++--
dlls/crypt32/tests/cert.c | 2 +-
dlls/crypt32/tests/encode.c | 108 +++++++++++++++++++++-----------------------
dlls/crypt32/tests/main.c | 8 ++--
dlls/crypt32/tests/msg.c | 6 +--
dlls/crypt32/tests/oid.c | 6 +--
dlls/crypt32/tests/sip.c | 9 ++--
dlls/crypt32/tests/store.c | 6 +--
dlls/crypt32/tests/str.c | 17 +++----
9 files changed, 80 insertions(+), 92 deletions(-)
diff --git a/dlls/crypt32/tests/base64.c b/dlls/crypt32/tests/base64.c
index e127fc3891..633e6d1775 100644
--- a/dlls/crypt32/tests/base64.c
+++ b/dlls/crypt32/tests/base64.c
@@ -128,7 +128,7 @@ static void testBinaryToStringA(void)
ret = CryptBinaryToStringA(NULL, 0, 0, NULL, &strLen);
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
- for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
{
DWORD strLen = 0;
LPSTR str = NULL;
@@ -163,7 +163,7 @@ static void testBinaryToStringA(void)
CRYPT_STRING_BASE64X509CRLHEADER, tests[i].base64, X509_HEADER,
X509_TRAILER);
}
- for (i = 0; i < sizeof(testsNoCR) / sizeof(testsNoCR[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(testsNoCR); i++)
{
DWORD strLen = 0;
LPSTR str = NULL;
@@ -380,7 +380,7 @@ static void testStringToBinaryA(void)
ok(!ret && GetLastError() == ERROR_INVALID_DATA,
"Expected ERROR_INVALID_DATA, got ret=%d le=%u\n", ret, GetLastError());
/* Bad strings */
- for (i = 0; i < sizeof(badStrings) / sizeof(badStrings[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(badStrings); i++)
{
bufLen = 0;
ret = CryptStringToBinaryA(badStrings[i].str, 0, badStrings[i].format,
@@ -447,7 +447,7 @@ static void testStringToBinaryA(void)
ret, bufLen, buf[0]);
/* Good strings */
- for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
{
bufLen = 0;
/* Bogus length--oddly enough, that succeeds, even though it's not
@@ -504,7 +504,7 @@ static void testStringToBinaryA(void)
*/
}
/* And again, with no CR--decoding handles this automatically */
- for (i = 0; i < sizeof(testsNoCR) / sizeof(testsNoCR[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(testsNoCR); i++)
{
bufLen = 0;
/* Bogus length--oddly enough, that succeeds, even though it's not
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c
index e49b2a9798..bb0cc525e7 100644
--- a/dlls/crypt32/tests/cert.c
+++ b/dlls/crypt32/tests/cert.c
@@ -3177,7 +3177,7 @@ static void testCompareIntegerBlob(void)
DWORD i;
BOOL ret;
- for (i = 0; i < sizeof(intBlobs) / sizeof(intBlobs[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(intBlobs); i++)
{
ret = CertCompareIntegerBlob(&intBlobs[i].blob1, &intBlobs[i].blob2);
ok(ret == intBlobs[i].areEqual,
diff --git a/dlls/crypt32/tests/encode.c b/dlls/crypt32/tests/encode.c
index a4daec09c9..4a6626ab00 100644
--- a/dlls/crypt32/tests/encode.c
+++ b/dlls/crypt32/tests/encode.c
@@ -113,7 +113,7 @@ static void test_encodeInt(DWORD dwEncoding)
ok(!ret && GetLastError() == STATUS_ACCESS_VIOLATION,
"Expected STATUS_ACCESS_VIOLATION, got %08x\n", GetLastError());
}
- for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(ints); i++)
{
/* encode as normal integer */
ret = pCryptEncodeObjectEx(dwEncoding, X509_INTEGER, &ints[i].val, 0,
@@ -155,7 +155,7 @@ static void test_encodeInt(DWORD dwEncoding)
/* encode a couple bigger ints, just to show it's little-endian and leading
* sign bytes are dropped
*/
- for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(bigInts); i++)
{
blob.cbData = strlen((const char*)bigInts[i].val);
blob.pbData = (BYTE *)bigInts[i].val;
@@ -178,7 +178,7 @@ static void test_encodeInt(DWORD dwEncoding)
}
}
/* and, encode some uints */
- for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(bigUInts); i++)
{
blob.cbData = strlen((const char*)bigUInts[i].val);
blob.pbData = (BYTE*)bigUInts[i].val;
@@ -242,7 +242,7 @@ static void test_decodeInt(DWORD dwEncoding)
GetLastError() == OSS_PDU_MISMATCH /* Win9x */ ),
"Expected CRYPT_E_ASN1_BADTAG or OSS_PDU_MISMATCH, got %08x\n",
GetLastError());
- for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(ints); i++)
{
/* When the output buffer is NULL, this always succeeds */
SetLastError(0xdeadbeef);
@@ -264,7 +264,7 @@ static void test_decodeInt(DWORD dwEncoding)
LocalFree(buf);
}
}
- for (i = 0; i < sizeof(bigInts) / sizeof(bigInts[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(bigInts); i++)
{
ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_INTEGER,
bigInts[i].encoded, bigInts[i].encoded[1] + 2, 0, NULL, NULL,
@@ -289,7 +289,7 @@ static void test_decodeInt(DWORD dwEncoding)
LocalFree(buf);
}
}
- for (i = 0; i < sizeof(bigUInts) / sizeof(bigUInts[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(bigUInts); i++)
{
ret = pCryptDecodeObjectEx(dwEncoding, X509_MULTI_BYTE_UINT,
bigUInts[i].encoded, bigUInts[i].encoded[1] + 2, 0, NULL, NULL,
@@ -377,9 +377,9 @@ static void test_encodeEnumerated(DWORD dwEncoding)
{
DWORD i, j;
- for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(enumeratedTypes); i++)
{
- for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
+ for (j = 0; j < ARRAY_SIZE(enums); j++)
{
BOOL ret;
BYTE *buf = NULL;
@@ -410,9 +410,9 @@ static void test_decodeEnumerated(DWORD dwEncoding)
{
DWORD i, j;
- for (i = 0; i < sizeof(enumeratedTypes) / sizeof(enumeratedTypes[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(enumeratedTypes); i++)
{
- for (j = 0; j < sizeof(enums) / sizeof(enums[0]); j++)
+ for (j = 0; j < ARRAY_SIZE(enums); j++)
{
BOOL ret;
DWORD bufSize = sizeof(int);
@@ -563,7 +563,7 @@ static void test_encodeFiletime(DWORD dwEncoding)
{
DWORD i;
- for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(times); i++)
{
testTimeEncoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
testTimeEncoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
@@ -645,19 +645,19 @@ static void test_decodeFiletime(DWORD dwEncoding)
ok(!ret && GetLastError() == ERROR_MORE_DATA,
"Expected ERROR_MORE_DATA, got %d\n", GetLastError());
/* Normal tests */
- for (i = 0; i < sizeof(times) / sizeof(times[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(times); i++)
{
testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, ×[i]);
testTimeDecoding(dwEncoding, PKCS_UTC_TIME, ×[i]);
testTimeDecoding(dwEncoding, szOID_RSA_signingTime, ×[i]);
}
- for (i = 0; i < sizeof(otherTimes) / sizeof(otherTimes[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(otherTimes); i++)
{
testTimeDecoding(dwEncoding, X509_CHOICE_OF_TIME, &otherTimes[i]);
testTimeDecoding(dwEncoding, PKCS_UTC_TIME, &otherTimes[i]);
testTimeDecoding(dwEncoding, szOID_RSA_signingTime, &otherTimes[i]);
}
- for (i = 0; i < sizeof(bogusTimes) / sizeof(bogusTimes[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(bogusTimes); i++)
{
size = sizeof(ft1);
ret = pCryptDecodeObjectEx(dwEncoding, X509_CHOICE_OF_TIME,
@@ -861,7 +861,7 @@ static void test_encodeName(DWORD dwEncoding)
ok(!ret && GetLastError() == E_INVALIDARG,
"Expected E_INVALIDARG, got %08x\n", GetLastError());
/* Test a more complex name */
- rdn.cRDNAttr = sizeof(rdnAttrs) / sizeof(rdnAttrs[0]);
+ rdn.cRDNAttr = ARRAY_SIZE(rdnAttrs);
rdn.rgRDNAttr = rdnAttrs;
info.cRDN = 1;
info.rgRDN = &rdn;
@@ -1139,7 +1139,7 @@ static void test_decodeName(DWORD dwEncoding)
(BYTE *)commonName } },
};
- rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
+ rdn.cRDNAttr = ARRAY_SIZE(attrs);
rdn.rgRDNAttr = attrs;
compareNames(&info, (CERT_NAME_INFO *)buf);
LocalFree(buf);
@@ -1157,7 +1157,7 @@ static void test_decodeName(DWORD dwEncoding)
ok(ret, "CryptDecodeObjectEx failed: %08x\n", GetLastError());
if (ret)
{
- rdn.cRDNAttr = sizeof(decodedRdnAttrs) / sizeof(decodedRdnAttrs[0]);
+ rdn.cRDNAttr = ARRAY_SIZE(decodedRdnAttrs);
rdn.rgRDNAttr = decodedRdnAttrs;
compareNames(&info, (CERT_NAME_INFO *)buf);
LocalFree(buf);
@@ -1223,7 +1223,7 @@ static void test_decodeUnicodeName(DWORD dwEncoding)
{ lstrlenW(commonNameW) * sizeof(WCHAR), (BYTE *)commonNameW } },
};
- rdn.cRDNAttr = sizeof(attrs) / sizeof(attrs[0]);
+ rdn.cRDNAttr = ARRAY_SIZE(attrs);
rdn.rgRDNAttr = attrs;
compareNames(&info, (CERT_NAME_INFO *)buf);
LocalFree(buf);
@@ -1332,7 +1332,7 @@ static void test_encodeNameValue(DWORD dwEncoding)
"Unexpected encoding\n");
LocalFree(buf);
}
- for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(nameValues); i++)
{
ret = pCryptEncodeObjectEx(dwEncoding, X509_NAME_VALUE,
&nameValues[i].value, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
@@ -1370,7 +1370,7 @@ static void test_decodeNameValue(DWORD dwEncoding)
DWORD bufSize = 0;
BOOL ret;
- for (i = 0; i < sizeof(nameValues) / sizeof(nameValues[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(nameValues); i++)
{
ret = pCryptDecodeObjectEx(dwEncoding, X509_NAME_VALUE,
nameValues[i].encoded, nameValues[i].encoded[1] + 2,
@@ -1866,7 +1866,7 @@ static void test_encodeUnicodeNameValue(DWORD dwEncoding)
"Expected CRYPT_E_NOT_CHAR_STRING, got %08x\n", GetLastError());
/* More failure checking */
value.Value.cbData = 0;
- for (i = 0; i < sizeof(unicodeErrors) / sizeof(unicodeErrors[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(unicodeErrors); i++)
{
value.Value.pbData = (LPBYTE)unicodeErrors[i].str;
value.dwValueType = unicodeErrors[i].valueType;
@@ -1881,7 +1881,7 @@ static void test_encodeUnicodeNameValue(DWORD dwEncoding)
}
/* cbData can be zero if the string is NULL-terminated */
value.Value.cbData = 0;
- for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(unicodeResults); i++)
{
value.Value.pbData = (LPBYTE)unicodeResults[i].str;
value.dwValueType = unicodeResults[i].valueType;
@@ -1903,7 +1903,7 @@ static void test_encodeUnicodeNameValue(DWORD dwEncoding)
* rather than properly encoding it. Kept separate from the proper results,
* because the encoded forms won't decode to their original strings.
*/
- for (i = 0; i < sizeof(unicodeWeirdness) / sizeof(unicodeWeirdness[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(unicodeWeirdness); i++)
{
value.Value.pbData = (LPBYTE)unicodeWeirdness[i].str;
value.dwValueType = unicodeWeirdness[i].valueType;
@@ -1933,7 +1933,7 @@ static void test_decodeUnicodeNameValue(DWORD dwEncoding)
{
DWORD i;
- for (i = 0; i < sizeof(unicodeResults) / sizeof(unicodeResults[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(unicodeResults); i++)
{
BYTE *buf = NULL;
BOOL ret;
@@ -1991,7 +1991,7 @@ static void test_encodeOctets(DWORD dwEncoding)
}
};
- for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
{
BYTE *buf = NULL;
BOOL ret;
@@ -2065,7 +2065,7 @@ static void test_decodeOctets(DWORD dwEncoding)
}
};
- for (i = 0; i < sizeof(tests) / sizeof(tests[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
{
BYTE *buf = NULL;
BOOL ret;
@@ -2127,7 +2127,7 @@ static void test_encodeBits(DWORD dwEncoding)
{
DWORD i;
- for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(bits); i++)
{
CRYPT_BIT_BLOB blob;
BOOL ret;
@@ -2162,7 +2162,7 @@ static void test_decodeBits(DWORD dwEncoding)
DWORD bufSize = 0;
/* normal cases */
- for (i = 0; i < sizeof(bits) / sizeof(bits[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(bits); i++)
{
ret = pCryptDecodeObjectEx(dwEncoding, X509_BITS, bits[i].encoded,
bits[i].encoded[1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf,
@@ -2249,7 +2249,7 @@ static void test_encodeBasicConstraints(DWORD dwEncoding)
BYTE *buf = NULL;
/* First test with the simpler info2 */
- for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(constraints2); i++)
{
ret = pCryptEncodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
&constraints2[i].info, CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf,
@@ -2312,7 +2312,7 @@ static void test_decodeBasicConstraints(DWORD dwEncoding)
DWORD bufSize = 0;
/* First test with simpler info2 */
- for (i = 0; i < sizeof(constraints2) / sizeof(constraints2[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(constraints2); i++)
{
ret = pCryptDecodeObjectEx(dwEncoding, X509_BASIC_CONSTRAINTS2,
constraints2[i].encoded, constraints2[i].encoded[1] + 2,
@@ -2494,7 +2494,7 @@ static void test_encodeRsaPublicKey(DWORD dwEncoding)
"Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
/* Finally, all valid */
hdr->aiKeyAlg = CALG_RSA_KEYX;
- for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(rsaPubKeys); i++)
{
memcpy(toEncode + sizeof(BLOBHEADER) + sizeof(RSAPUBKEY),
rsaPubKeys[i].modulus, rsaPubKeys[i].modulusLen);
@@ -2540,7 +2540,7 @@ static void test_decodeRsaPublicKey(DWORD dwEncoding)
ok(!ret && GetLastError() == ERROR_FILE_NOT_FOUND,
"Expected ERROR_FILE_NOT_FOUND, got %08x\n", GetLastError());
/* Now try success cases */
- for (i = 0; i < sizeof(rsaPubKeys) / sizeof(rsaPubKeys[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(rsaPubKeys); i++)
{
bufSize = 0;
ret = pCryptDecodeObjectEx(dwEncoding, RSA_CSP_PUBLICKEYBLOB,
@@ -2590,7 +2590,7 @@ static const BYTE mixedSequence[] = { 0x30, 0x27, 0x17, 0x0d, 0x30, 0x35, 0x30,
static void test_encodeSequenceOfAny(DWORD dwEncoding)
{
- CRYPT_DER_BLOB blobs[sizeof(ints) / sizeof(ints[0])];
+ CRYPT_DER_BLOB blobs[ARRAY_SIZE(ints)];
CRYPT_SEQUENCE_OF_ANY seq;
DWORD i;
BOOL ret;
@@ -2598,12 +2598,12 @@ static void test_encodeSequenceOfAny(DWORD dwEncoding)
DWORD bufSize = 0;
/* Encode a homogeneous sequence */
- for (i = 0; i < sizeof(ints) / sizeof(ints[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(ints); i++)
{
blobs[i].cbData = ints[i].encoded[1] + 2;
blobs[i].pbData = (BYTE *)ints[i].encoded;
}
- seq.cValue = sizeof(ints) / sizeof(ints[0]);
+ seq.cValue = ARRAY_SIZE(ints);
seq.rgValue = blobs;
ret = pCryptEncodeObjectEx(dwEncoding, X509_SEQUENCE_OF_ANY, &seq,
@@ -2646,9 +2646,8 @@ static void test_decodeSequenceOfAny(DWORD dwEncoding)
CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
DWORD i;
- ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
- "Wrong elements %d\n", seq->cValue);
- for (i = 0; i < min(seq->cValue, sizeof(ints) / sizeof(ints[0])); i++)
+ ok(seq->cValue == ARRAY_SIZE(ints), "Wrong elements %d\n", seq->cValue);
+ for (i = 0; i < min(seq->cValue, ARRAY_SIZE(ints)); i++)
{
ok(seq->rgValue[i].cbData == ints[i].encoded[1] + 2,
"Expected %d bytes, got %d\n", ints[i].encoded[1] + 2,
@@ -2666,8 +2665,7 @@ static void test_decodeSequenceOfAny(DWORD dwEncoding)
{
CRYPT_SEQUENCE_OF_ANY *seq = (CRYPT_SEQUENCE_OF_ANY *)buf;
- ok(seq->cValue == sizeof(ints) / sizeof(ints[0]),
- "Wrong elements %d\n", seq->cValue);
+ ok(seq->cValue == ARRAY_SIZE(ints), "Wrong elements %d\n", seq->cValue);
/* Just check the first element since it's all that changed */
ok(seq->rgValue[0].cbData == times[0].encodedTime[1] + 2,
"Expected %d bytes, got %d\n", times[0].encodedTime[1] + 2,
@@ -2713,7 +2711,7 @@ static void test_encodeExtensions(DWORD dwEncoding)
{
DWORD i;
- for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
+ for (i = 0; i < ARRAY_SIZE(exts); i++)
{
BOOL ret;
BYTE *buf = NULL;
@@ -2737,7 +2735,7 @@ static void test_decodeExtensions(DWORD dwEncoding)
{
DWORD i;
- for (i = 0; i < sizeof(exts) / sizeof(exts[i]); i++)
+ for (i = 0; i < ARRAY_SIZE(exts); i++)
{
BOOL ret;
BYTE *buf = NULL;
@@ -2851,7 +2849,7 @@ static void test_encodePublicKeyInfo(DWORD dwEncoding)
{
DWORD i;
- for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(pubKeys); i++)
{
BOOL ret;
BYTE *buf = NULL;
@@ -2907,7 +2905,7 @@ static void test_decodePublicKeyInfo(DWORD dwEncoding)
BYTE *buf = NULL;
DWORD bufSize = 0;
- for (i = 0; i < sizeof(pubKeys) / sizeof(pubKeys[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(pubKeys); i++)
{
/* The NULL form decodes to the decoded member */
ret = pCryptDecodeObjectEx(dwEncoding, X509_PUBLIC_KEY_INFO,
@@ -3260,7 +3258,7 @@ static void test_decodeCertToBeSigned(DWORD dwEncoding)
* CRYPT_E_ASN1_BADTAG, because at a minimum a cert must have a non-zero
* serial number, an issuer, a subject, and a public key.
*/
- for (i = 0; i < sizeof(corruptCerts) / sizeof(corruptCerts[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(corruptCerts); i++)
{
ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_TO_BE_SIGNED,
corruptCerts[i], corruptCerts[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
@@ -4688,7 +4686,7 @@ static void test_decodeCRLToBeSigned(DWORD dwEncoding)
BYTE *buf = NULL;
DWORD size = 0, i;
- for (i = 0; i < sizeof(corruptCRLs) / sizeof(corruptCRLs[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(corruptCRLs); i++)
{
ret = pCryptDecodeObjectEx(dwEncoding, X509_CERT_CRL_TO_BE_SIGNED,
corruptCRLs[i], corruptCRLs[i][1] + 2, CRYPT_DECODE_ALLOC_FLAG, NULL,
@@ -4854,7 +4852,7 @@ static void test_encodeEnhancedKeyUsage(DWORD dwEncoding)
LocalFree(buf);
}
/* Test with a few usages */
- usage.cUsageIdentifier = sizeof(keyUsages) / sizeof(keyUsages[0]);
+ usage.cUsageIdentifier = ARRAY_SIZE(keyUsages);
usage.rgpszUsageIdentifier = (LPSTR *)keyUsages;
ret = pCryptEncodeObjectEx(dwEncoding, X509_ENHANCED_KEY_USAGE, &usage,
CRYPT_ENCODE_ALLOC_FLAG, NULL, &buf, &size);
@@ -4898,8 +4896,8 @@ static void test_decodeEnhancedKeyUsage(DWORD dwEncoding)
ok(size >= sizeof(CERT_ENHKEY_USAGE),
"Wrong size %d\n", size);
- ok(usage->cUsageIdentifier == sizeof(keyUsages) / sizeof(keyUsages[0]),
- "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
+ ok(usage->cUsageIdentifier == ARRAY_SIZE(keyUsages),
+ "Wrong CRL entries count %d\n", usage->cUsageIdentifier);
for (i = 0; i < usage->cUsageIdentifier; i++)
ok(!strcmp(usage->rgpszUsageIdentifier[i], keyUsages[i]),
"Expected OID %s, got %s\n", keyUsages[i],
@@ -6109,7 +6107,7 @@ static void test_decodePKCSContentInfo(DWORD dwEncoding)
"1.2.3", content_constructed_abcd + 8, 10 }
};
- for (i = 0; i < sizeof(tests)/sizeof(*tests); i++)
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
{
ret = pCryptDecodeObjectEx(dwEncoding, PKCS_CONTENT_INFO, tests[i].encoded,
tests[i].encoded_size, CRYPT_DECODE_ALLOC_FLAG, NULL, &buf, &size);
@@ -7397,9 +7395,7 @@ static void test_decodeNameConstraints(DWORD dwEncoding)
U(IPAddressWithMinSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
U(IPAddressWithMinMaxSubtree.Base).IPAddress.cbData = sizeof(encodedIPAddr);
U(IPAddressWithMinMaxSubtree.Base).IPAddress.pbData = (LPBYTE)encodedIPAddr;
- for (i = 0;
- i < sizeof(encodedNameConstraints) / sizeof(encodedNameConstraints[0]);
- i++)
+ for (i = 0; i < ARRAY_SIZE(encodedNameConstraints); i++)
{
DWORD size;
@@ -7749,7 +7745,7 @@ static void test_encodeCertPolicyMappings(DWORD dwEncoding)
DWORD size, i;
/* Each of the mapping OIDs is equivalent, so check with all of them */
- for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(mappingOids); i++)
{
memset(&info, 0, sizeof(info));
ret = pCryptEncodeObjectEx(dwEncoding, mappingOids[i], &info,
@@ -7814,7 +7810,7 @@ static void test_decodeCertPolicyMappings(DWORD dwEncoding)
BOOL ret;
/* Each of the mapping OIDs is equivalent, so check with all of them */
- for (i = 0; i < sizeof(mappingOids) / sizeof(mappingOids[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(mappingOids); i++)
{
ret = pCryptDecodeObjectEx(dwEncoding, mappingOids[i],
emptySequence, sizeof(emptySequence), CRYPT_DECODE_ALLOC_FLAG, NULL,
@@ -8525,7 +8521,7 @@ START_TEST(encode)
return;
}
- for (i = 0; i < sizeof(encodings) / sizeof(encodings[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(encodings); i++)
{
test_encodeInt(encodings[i]);
test_decodeInt(encodings[i]);
diff --git a/dlls/crypt32/tests/main.c b/dlls/crypt32/tests/main.c
index a0019b5869..11beff11c4 100644
--- a/dlls/crypt32/tests/main.c
+++ b/dlls/crypt32/tests/main.c
@@ -36,7 +36,7 @@ static void test_findAttribute(void)
BYTE blobbin[] = {0x02,0x01,0x01};
static CHAR oid[] = "1.2.3";
CRYPT_ATTR_BLOB blobs[] = { { sizeof blobbin, blobbin }, };
- CRYPT_ATTRIBUTE attr = { oid, sizeof(blobs) / sizeof(blobs[0]), blobs };
+ CRYPT_ATTRIBUTE attr = { oid, ARRAY_SIZE(blobs), blobs };
/* returns NULL, last error not set */
SetLastError(0xdeadbeef);
@@ -128,10 +128,8 @@ static void test_findRDNAttr(void)
CERT_RDN_ATTR attrs[] = {
{ oid, CERT_RDN_IA5_STRING, { sizeof bin, bin } },
};
- CERT_RDN rdns[] = {
- { sizeof(attrs) / sizeof(attrs[0]), attrs },
- };
- CERT_NAME_INFO nameInfo = { sizeof(rdns) / sizeof(rdns[0]), rdns };
+ CERT_RDN rdns[] = { { ARRAY_SIZE(attrs), attrs } };
+ CERT_NAME_INFO nameInfo = { ARRAY_SIZE(rdns), rdns };
if (0)
{
diff --git a/dlls/crypt32/tests/msg.c b/dlls/crypt32/tests/msg.c
index c2405335b9..b6921273ee 100644
--- a/dlls/crypt32/tests/msg.c
+++ b/dlls/crypt32/tests/msg.c
@@ -575,7 +575,7 @@ static CRYPT_DATA_BLOB b1[] = {
{ sizeof(u2), u2 },
{ sizeof(u2), u2 },
};
-static const struct update_accum a1 = { sizeof(b1) / sizeof(b1[0]), b1 };
+static const struct update_accum a1 = { ARRAY_SIZE(b1), b1 };
/* The updates of a definite-length encoded message */
static BYTE u3[] = { 0x30,0x13,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
0x07,0x01,0xa0,0x06,0x04,0x04 };
@@ -583,7 +583,7 @@ static CRYPT_DATA_BLOB b2[] = {
{ sizeof(u3), u3 },
{ sizeof(u2), u2 },
};
-static const struct update_accum a2 = { sizeof(b2) / sizeof(b2[0]), b2 };
+static const struct update_accum a2 = { ARRAY_SIZE(b2), b2 };
/* The updates of an indefinite-length encoded message */
static BYTE u4[] = { 0x30,0x80,0x06,0x09,0x2a,0x86,0x48,0x86,0xf7,0x0d,0x01,
0x07,0x01,0xa0,0x80,0x24,0x80 };
@@ -597,7 +597,7 @@ static CRYPT_DATA_BLOB b3[] = {
{ sizeof(u2), u2 },
{ sizeof(u6), u6 },
};
-static const struct update_accum a3 = { sizeof(b3) / sizeof(b3[0]), b3 };
+static const struct update_accum a3 = { ARRAY_SIZE(b3), b3 };
static void check_updates(LPCSTR header, const struct update_accum *expected,
const struct update_accum *got)
diff --git a/dlls/crypt32/tests/oid.c b/dlls/crypt32/tests/oid.c
index 8fc67b3353..9485764ed7 100644
--- a/dlls/crypt32/tests/oid.c
+++ b/dlls/crypt32/tests/oid.c
@@ -105,7 +105,7 @@ static void testOIDToAlgID(void)
alg = CertOIDToAlgId("1.2.3");
ok(!alg, "Expected failure, got %d\n", alg);
- for (i = 0; i < sizeof(oidToAlgID) / sizeof(oidToAlgID[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(oidToAlgID); i++)
{
alg = CertOIDToAlgId(oidToAlgID[i].oid);
ok(alg == oidToAlgID[i].algID || (oidToAlgID[i].altAlgID && alg == oidToAlgID[i].altAlgID),
@@ -123,7 +123,7 @@ static void testAlgIDToOID(void)
oid = CertAlgIdToOID(ALG_CLASS_SIGNATURE | ALG_TYPE_ANY | 80);
ok(!oid && GetLastError() == 0xdeadbeef,
"Didn't expect last error (%08x) to be set\n", GetLastError());
- for (i = 0; i < sizeof(algIDToOID) / sizeof(algIDToOID[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(algIDToOID); i++)
{
oid = CertAlgIdToOID(algIDToOID[i].algID);
/* Allow failure, not every version of Windows supports every algo */
@@ -423,7 +423,7 @@ static void test_registerDefaultOIDFunction(void)
DWORD type, size;
LPSTR ptr;
- size = sizeof(dllBuf) / sizeof(dllBuf[0]);
+ size = ARRAY_SIZE(dllBuf);
rc = RegQueryValueExA(key, dllA, NULL, &type, (LPBYTE)dllBuf, &size);
ok(rc == 0,
"Expected Dll value to exist, RegQueryValueExA failed: %d\n", rc);
diff --git a/dlls/crypt32/tests/sip.c b/dlls/crypt32/tests/sip.c
index e2ec2f411d..d8d6a87445 100644
--- a/dlls/crypt32/tests/sip.c
+++ b/dlls/crypt32/tests/sip.c
@@ -187,9 +187,8 @@ static void test_SIPRetrieveSubjectGUID(void)
ok (ret > 0, "expected GEVA(windir) to succeed, last error %d\n", GetLastError());
strcat(regeditPath, "\\");
strcat(regeditPath, regeditExe);
- MultiByteToWideChar( CP_ACP, 0, regeditPath,
- strlen(regeditPath)+1, regeditPathW,
- sizeof(regeditPathW)/sizeof(regeditPathW[0]) );
+ MultiByteToWideChar(CP_ACP, 0, regeditPath, strlen(regeditPath)+1, regeditPathW,
+ ARRAY_SIZE(regeditPathW));
SetLastError(0xdeadbeef);
memset(&subject, 1, sizeof(GUID));
@@ -221,9 +220,7 @@ static void test_SIPRetrieveSubjectGUID(void)
/* Now with an empty file */
GetTempPathA(sizeof(path), path);
GetTempFileNameA(path, "sip", 0 , tempfile);
- MultiByteToWideChar( CP_ACP, 0, tempfile,
- strlen(tempfile)+1, tempfileW,
- sizeof(tempfileW)/sizeof(tempfileW[0]) );
+ MultiByteToWideChar(CP_ACP, 0, tempfile, strlen(tempfile)+1, tempfileW, ARRAY_SIZE(tempfileW));
SetLastError(0xdeadbeef);
memset(&subject, 1, sizeof(GUID));
diff --git a/dlls/crypt32/tests/store.c b/dlls/crypt32/tests/store.c
index 47cd0b38cd..9915482277 100644
--- a/dlls/crypt32/tests/store.c
+++ b/dlls/crypt32/tests/store.c
@@ -385,7 +385,7 @@ static void testRegStoreSavedCerts(void)
BOOL ret;
DWORD res,i;
- for (i = 0; i < sizeof(reg_store_saved_certs) / sizeof(reg_store_saved_certs[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(reg_store_saved_certs); i++)
{
DWORD err;
@@ -2081,7 +2081,7 @@ static void testCertRegisterSystemStore(void)
const CERT_CONTEXT *cert, *cert2;
unsigned int i;
- for (i = 0; i < sizeof(reg_system_store_test_data) / sizeof(reg_system_store_test_data[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(reg_system_store_test_data); i++) {
cur_flag = reg_system_store_test_data[i].cert_store;
ret = CertRegisterSystemStore(WineTestW, cur_flag, NULL, NULL);
if (!ret)
@@ -2469,7 +2469,7 @@ static void delete_test_key(void)
RegQueryInfoKeyW(test_key, NULL, NULL, NULL, &num_subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL);
for (idx = num_subkeys; idx-- > 0;)
{
- subkey_name_len = sizeof(subkey_name)/sizeof(WCHAR);
+ subkey_name_len = ARRAY_SIZE(subkey_name);
RegEnumKeyExW(test_key, idx, subkey_name, &subkey_name_len, NULL, NULL, NULL, NULL);
RegDeleteKeyW(test_key, subkey_name);
}
diff --git a/dlls/crypt32/tests/str.c b/dlls/crypt32/tests/str.c
index 5245885503..d382c0e6b0 100644
--- a/dlls/crypt32/tests/str.c
+++ b/dlls/crypt32/tests/str.c
@@ -250,7 +250,7 @@ static void test_CertRDNValueToStrA(void)
ok(ret == 1 && GetLastError() == 0xdeadbeef, "Expected empty string\n");
ok(!buffer[0], "Expected empty string\n");
- for (i = 0; i < sizeof(attrs) / sizeof(attrs[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(attrs); i++)
{
ret = pCertRDNValueToStrA(attrs[i].dwValueType, &attrs[i].Value,
buffer, sizeof(buffer));
@@ -341,15 +341,13 @@ static void test_CertRDNValueToStrW(void)
SetLastError(0xdeadbeef);
ret = pCertRDNValueToStrW(0, &blob, NULL, 0);
ok(ret == 1 && GetLastError() == 0xdeadbeef, "Expected empty string\n");
- ret = pCertRDNValueToStrW(0, &blob, buffer,
- sizeof(buffer) / sizeof(buffer[0]));
+ ret = pCertRDNValueToStrW(0, &blob, buffer, ARRAY_SIZE(buffer));
ok(ret == 1 && GetLastError() == 0xdeadbeef, "Expected empty string\n");
ok(!buffer[0], "Expected empty string\n");
- for (i = 0; i < sizeof(attrs) / sizeof(attrs[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(attrs); i++)
{
- ret = pCertRDNValueToStrW(attrs[i].dwValueType, &attrs[i].Value,
- buffer, sizeof(buffer) / sizeof(buffer[0]));
+ ret = pCertRDNValueToStrW(attrs[i].dwValueType, &attrs[i].Value, buffer, ARRAY_SIZE(buffer));
todo_wine_if (attrs[i].todo)
{
ok(ret == lstrlenW(attrs[i].str) + 1,
@@ -550,8 +548,7 @@ static void test_NameToStrConversionW(PCERT_NAME_BLOB pName, DWORD dwStrType,
todo_wine_if (todo)
ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %d\n",
lstrlenW(expected) + 1, i);
- i = pCertNameToStrW(X509_ASN_ENCODING,pName, dwStrType, buffer,
- sizeof(buffer) / sizeof(buffer[0]));
+ i = pCertNameToStrW(X509_ASN_ENCODING,pName, dwStrType, buffer, ARRAY_SIZE(buffer));
todo_wine_if (todo)
ok(i == lstrlenW(expected) + 1, "Expected %d chars, got %d\n",
lstrlenW(expected) + 1, i);
@@ -795,7 +792,7 @@ static void test_CertStrToNameA(void)
&size, NULL);
ok(!ret && GetLastError() == ERROR_MORE_DATA,
"Expected ERROR_MORE_DATA, got %08x\n", GetLastError());
- for (i = 0; i < sizeof(namesA) / sizeof(namesA[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(namesA); i++)
{
size = sizeof(buf);
ret = pCertStrToNameA(X509_ASN_ENCODING, namesA[i].x500, 0, NULL, buf,
@@ -889,7 +886,7 @@ static void test_CertStrToNameW(void)
ok(!ret && GetLastError() == CRYPT_E_INVALID_X500_STRING,
"Expected CRYPT_E_INVALID_X500_STRING, got %08x\n", GetLastError());
ok(errorPtr && *errorPtr == '1', "Expected first error character was 1\n");
- for (i = 0; i < sizeof(namesW) / sizeof(namesW[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(namesW); i++)
{
size = sizeof(buf);
ret = pCertStrToNameW(X509_ASN_ENCODING, namesW[i].x500, 0, NULL, buf,
--
2.14.4
June 22, 2018
[PATCH] crypt32: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/crypt32/chain.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index dd3fc33db6..6e8076c66c 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -738,8 +738,7 @@ static BOOL url_matches(LPCWSTR constraint, LPCWSTR name,
/* Ignore any path or query portion of the URL. */
if (*authority_end)
{
- if (authority_end - name < sizeof(hostname_buf) /
- sizeof(hostname_buf[0]))
+ if (authority_end - name < ARRAY_SIZE(hostname_buf))
{
memcpy(hostname_buf, name,
(authority_end - name) * sizeof(WCHAR));
--
2.14.4
June 22, 2018
[PATCH] kernel32/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Only locale.c for now due to its size.
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/kernel32/tests/locale.c | 598 +++++++++++++++++++++----------------------
1 file changed, 287 insertions(+), 311 deletions(-)
diff --git a/dlls/kernel32/tests/locale.c b/dlls/kernel32/tests/locale.c
index 791f015766..06a7aa75e7 100644
--- a/dlls/kernel32/tests/locale.c
+++ b/dlls/kernel32/tests/locale.c
@@ -154,15 +154,14 @@ static void InitFunctionPointers(void)
(label), (received), (expected))
#define BUFFER_SIZE 128
-#define COUNTOF(x) (sizeof(x)/sizeof(x)[0])
#define STRINGSA(x,y) strcpy(input, x); strcpy(Expected, y); SetLastError(0xdeadbeef); buffer[0] = '\0'
#define EXPECT_LENA ok(ret == lstrlenA(Expected)+1, "Expected len %d, got %d\n", lstrlenA(Expected)+1, ret)
#define EXPECT_EQA ok(strncmp(buffer, Expected, strlen(Expected)) == 0, \
"Expected '%s', got '%s'\n", Expected, buffer)
-#define STRINGSW(x,y) MultiByteToWideChar(CP_ACP,0,x,-1,input,COUNTOF(input)); \
- MultiByteToWideChar(CP_ACP,0,y,-1,Expected,COUNTOF(Expected)); \
+#define STRINGSW(x,y) MultiByteToWideChar(CP_ACP,0,x,-1,input,ARRAY_SIZE(input)); \
+ MultiByteToWideChar(CP_ACP,0,y,-1,Expected,ARRAY_SIZE(Expected)); \
SetLastError(0xdeadbeef); buffer[0] = '\0'
#define EXPECT_LENW ok(ret == lstrlenW(Expected)+1, "Expected Len %d, got %d\n", lstrlenW(Expected)+1, ret)
#define EXPECT_EQW ok(strncmpW(buffer, Expected, strlenW(Expected)) == 0, "Bad conversion\n")
@@ -187,21 +186,21 @@ static void test_GetLocaleInfoA(void)
/* en and ar use SUBLANG_NEUTRAL, but GetLocaleInfo assume SUBLANG_DEFAULT
Same is true for zh on pre-Vista, but on Vista and higher GetLocaleInfo
assumes SUBLANG_NEUTRAL for zh */
- memset(expected, 0, COUNTOF(expected));
- len = GetLocaleInfoA(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), LOCALE_SLANGUAGE, expected, COUNTOF(expected));
+ memset(expected, 0, ARRAY_SIZE(expected));
+ len = GetLocaleInfoA(MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), LOCALE_SLANGUAGE, expected, ARRAY_SIZE(expected));
SetLastError(0xdeadbeef);
- memset(buffer, 0, COUNTOF(buffer));
- ret = GetLocaleInfoA(LANG_ENGLISH, LOCALE_SLANGUAGE, buffer, COUNTOF(buffer));
+ memset(buffer, 0, ARRAY_SIZE(buffer));
+ ret = GetLocaleInfoA(LANG_ENGLISH, LOCALE_SLANGUAGE, buffer, ARRAY_SIZE(buffer));
ok((ret == len) && !lstrcmpA(buffer, expected),
"got %d with '%s' (expected %d with '%s')\n",
ret, buffer, len, expected);
- memset(expected, 0, COUNTOF(expected));
- len = GetLocaleInfoA(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), LOCALE_SLANGUAGE, expected, COUNTOF(expected));
+ memset(expected, 0, ARRAY_SIZE(expected));
+ len = GetLocaleInfoA(MAKELANGID(LANG_ARABIC, SUBLANG_DEFAULT), LOCALE_SLANGUAGE, expected, ARRAY_SIZE(expected));
if (len) {
SetLastError(0xdeadbeef);
- memset(buffer, 0, COUNTOF(buffer));
- ret = GetLocaleInfoA(LANG_ARABIC, LOCALE_SLANGUAGE, buffer, COUNTOF(buffer));
+ memset(buffer, 0, ARRAY_SIZE(buffer));
+ ret = GetLocaleInfoA(LANG_ARABIC, LOCALE_SLANGUAGE, buffer, ARRAY_SIZE(buffer));
ok((ret == len) && !lstrcmpA(buffer, expected),
"got %d with '%s' (expected %d with '%s')\n",
ret, buffer, len, expected);
@@ -210,11 +209,11 @@ static void test_GetLocaleInfoA(void)
win_skip("LANG_ARABIC not installed\n");
/* SUBLANG_DEFAULT is required for mlang.dll, but optional for GetLocaleInfo */
- memset(expected, 0, COUNTOF(expected));
- len = GetLocaleInfoA(MAKELANGID(LANG_GERMAN, SUBLANG_DEFAULT), LOCALE_SLANGUAGE, expected, COUNTOF(expected));
+ memset(expected, 0, ARRAY_SIZE(expected));
+ len = GetLocaleInfoA(MAKELANGID(LANG_GERMAN, SUBLANG_DEFAULT), LOCALE_SLANGUAGE, expected, ARRAY_SIZE(expected));
SetLastError(0xdeadbeef);
- memset(buffer, 0, COUNTOF(buffer));
- ret = GetLocaleInfoA(LANG_GERMAN, LOCALE_SLANGUAGE, buffer, COUNTOF(buffer));
+ memset(buffer, 0, ARRAY_SIZE(buffer));
+ ret = GetLocaleInfoA(LANG_GERMAN, LOCALE_SLANGUAGE, buffer, ARRAY_SIZE(buffer));
ok((ret == len) && !lstrcmpA(buffer, expected),
"got %d with '%s' (expected %d with '%s')\n",
ret, buffer, len, expected);
@@ -224,19 +223,19 @@ static void test_GetLocaleInfoA(void)
* partially fill the buffer even if it is too short. See bug 637.
*/
SetLastError(0xdeadbeef);
- memset(buffer, 0, COUNTOF(buffer));
+ memset(buffer, 0, ARRAY_SIZE(buffer));
ret = GetLocaleInfoA(lcid, NUO|LOCALE_SDAYNAME1, buffer, 0);
ok(ret == 7 && !buffer[0], "Expected len=7, got %d\n", ret);
SetLastError(0xdeadbeef);
- memset(buffer, 0, COUNTOF(buffer));
+ memset(buffer, 0, ARRAY_SIZE(buffer));
ret = GetLocaleInfoA(lcid, NUO|LOCALE_SDAYNAME1, buffer, 3);
ok( !ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
ok(!strcmp(buffer, "Mon"), "Expected 'Mon', got '%s'\n", buffer);
SetLastError(0xdeadbeef);
- memset(buffer, 0, COUNTOF(buffer));
+ memset(buffer, 0, ARRAY_SIZE(buffer));
ret = GetLocaleInfoA(lcid, NUO|LOCALE_SDAYNAME1, buffer, 10);
ok(ret == 7, "Expected ret == 7, got %d, error %d\n", ret, GetLastError());
ok(!strcmp(buffer, "Monday"), "Expected 'Monday', got '%s'\n", buffer);
@@ -296,7 +295,7 @@ static void test_GetLocaleInfoW(void)
DWORD ret;
INT i;
- ret = GetLocaleInfoW(lcid_en, LOCALE_SMONTHNAME1, bufferW, COUNTOF(bufferW));
+ ret = GetLocaleInfoW(lcid_en, LOCALE_SMONTHNAME1, bufferW, ARRAY_SIZE(bufferW));
if (!ret) {
win_skip("GetLocaleInfoW() isn't implemented\n");
return;
@@ -306,7 +305,7 @@ static void test_GetLocaleInfoW(void)
ok(ret, "got %d\n", ret);
ok(val == lcid_en, "got 0x%08x\n", val);
- ret = GetLocaleInfoW(lcid_en_neut, LOCALE_SNAME, bufferW, COUNTOF(bufferW));
+ ret = GetLocaleInfoW(lcid_en_neut, LOCALE_SNAME, bufferW, ARRAY_SIZE(bufferW));
if (ret)
{
static const WCHAR slangW[] = {'E','n','g','l','i','s','h',' ','(','U','n','i','t','e','d',' ',
@@ -317,7 +316,7 @@ static void test_GetLocaleInfoW(void)
ok(!lstrcmpW(bufferW, enW), "got wrong name %s\n", wine_dbgstr_w(bufferW));
- ret = GetLocaleInfoW(lcid_en_neut, LOCALE_SCOUNTRY, bufferW, COUNTOF(bufferW));
+ ret = GetLocaleInfoW(lcid_en_neut, LOCALE_SCOUNTRY, bufferW, ARRAY_SIZE(bufferW));
ok(ret, "got %d\n", ret);
if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH) ||
(PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH))
@@ -327,7 +326,7 @@ static void test_GetLocaleInfoW(void)
else
ok(!lstrcmpW(statesW, bufferW), "got wrong name %s\n", wine_dbgstr_w(bufferW));
- ret = GetLocaleInfoW(lcid_en_neut, LOCALE_SLANGUAGE, bufferW, COUNTOF(bufferW));
+ ret = GetLocaleInfoW(lcid_en_neut, LOCALE_SLANGUAGE, bufferW, ARRAY_SIZE(bufferW));
ok(ret, "got %d\n", ret);
if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH) ||
(PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH))
@@ -353,7 +352,7 @@ static void test_GetLocaleInfoW(void)
wine_dbgstr_w(ptr->name), val, ptr->lcid);
/* now check LOCALE_SNAME */
- GetLocaleInfoW(lcid, LOCALE_SNAME, bufferW, COUNTOF(bufferW));
+ GetLocaleInfoW(lcid, LOCALE_SNAME, bufferW, ARRAY_SIZE(bufferW));
todo_wine_if (ptr->todo & 0x2)
ok(!lstrcmpW(bufferW, ptr->sname) ||
(*ptr->sname_broken && broken(!lstrcmpW(bufferW, ptr->sname_broken))),
@@ -364,13 +363,13 @@ static void test_GetLocaleInfoW(void)
else
win_skip("English neutral locale not supported\n");
- ret = GetLocaleInfoW(lcid_ru, LOCALE_SMONTHNAME1, bufferW, COUNTOF(bufferW));
+ ret = GetLocaleInfoW(lcid_ru, LOCALE_SMONTHNAME1, bufferW, ARRAY_SIZE(bufferW));
if (!ret) {
win_skip("LANG_RUSSIAN locale data unavailable\n");
return;
}
ret = GetLocaleInfoW(lcid_ru, LOCALE_SMONTHNAME1|LOCALE_RETURN_GENITIVE_NAMES,
- bufferW, COUNTOF(bufferW));
+ bufferW, ARRAY_SIZE(bufferW));
if (!ret) {
win_skip("LOCALE_RETURN_GENITIVE_NAMES isn't supported\n");
return;
@@ -380,7 +379,7 @@ static void test_GetLocaleInfoW(void)
bufferA[0] = 'a';
SetLastError(0xdeadbeef);
ret = GetLocaleInfoA(lcid_ru, LOCALE_SMONTHNAME1|LOCALE_RETURN_GENITIVE_NAMES,
- bufferA, COUNTOF(bufferA));
+ bufferA, ARRAY_SIZE(bufferA));
ok(ret == 0, "LOCALE_RETURN_GENITIVE_NAMES should fail with GetLocaleInfoA\n");
ok(bufferA[0] == 'a', "Expected buffer to be untouched\n");
ok(GetLastError() == ERROR_INVALID_FLAGS,
@@ -388,8 +387,7 @@ static void test_GetLocaleInfoW(void)
bufferW[0] = 'a';
SetLastError(0xdeadbeef);
- ret = GetLocaleInfoW(lcid_ru, LOCALE_RETURN_GENITIVE_NAMES,
- bufferW, COUNTOF(bufferW));
+ ret = GetLocaleInfoW(lcid_ru, LOCALE_RETURN_GENITIVE_NAMES, bufferW, ARRAY_SIZE(bufferW));
ok(ret == 0,
"LOCALE_RETURN_GENITIVE_NAMES itself doesn't return anything, got %d\n", ret);
ok(bufferW[0] == 'a', "Expected buffer to be untouched\n");
@@ -400,13 +398,12 @@ static void test_GetLocaleInfoW(void)
for (i = 0; i < 12; i++) {
bufferW[0] = 0;
ret = GetLocaleInfoW(lcid_ru, (LOCALE_SMONTHNAME1+i)|LOCALE_RETURN_GENITIVE_NAMES,
- bufferW, COUNTOF(bufferW));
+ bufferW, ARRAY_SIZE(bufferW));
ok(ret, "Expected non zero result\n");
ok(ret == lstrlenW(bufferW)+1, "Expected actual length, got %d, length %d\n",
ret, lstrlenW(bufferW));
buffer2W[0] = 0;
- ret = GetLocaleInfoW(lcid_ru, LOCALE_SMONTHNAME1+i,
- buffer2W, COUNTOF(buffer2W));
+ ret = GetLocaleInfoW(lcid_ru, LOCALE_SMONTHNAME1+i, buffer2W, ARRAY_SIZE(buffer2W));
ok(ret, "Expected non zero result\n");
ok(ret == lstrlenW(buffer2W)+1, "Expected actual length, got %d, length %d\n",
ret, lstrlenW(buffer2W));
@@ -417,13 +414,12 @@ static void test_GetLocaleInfoW(void)
/* for locale without genitive names nominative returned in both cases */
bufferW[0] = 0;
ret = GetLocaleInfoW(lcid_en, (LOCALE_SMONTHNAME1+i)|LOCALE_RETURN_GENITIVE_NAMES,
- bufferW, COUNTOF(bufferW));
+ bufferW, ARRAY_SIZE(bufferW));
ok(ret, "Expected non zero result\n");
ok(ret == lstrlenW(bufferW)+1, "Expected actual length, got %d, length %d\n",
ret, lstrlenW(bufferW));
buffer2W[0] = 0;
- ret = GetLocaleInfoW(lcid_en, LOCALE_SMONTHNAME1+i,
- buffer2W, COUNTOF(buffer2W));
+ ret = GetLocaleInfoW(lcid_en, LOCALE_SMONTHNAME1+i, buffer2W, ARRAY_SIZE(buffer2W));
ok(ret, "Expected non zero result\n");
ok(ret == lstrlenW(buffer2W)+1, "Expected actual length, got %d, length %d\n",
ret, lstrlenW(buffer2W));
@@ -443,7 +439,7 @@ static void test_GetTimeFormatA(void)
memset(&curtime, 2, sizeof(SYSTEMTIME));
STRINGSA("tt HH':'mm'@'ss", ""); /* Invalid time */
SetLastError(0xdeadbeef);
- ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
@@ -453,13 +449,13 @@ static void test_GetTimeFormatA(void)
curtime.wMilliseconds = 22;
STRINGSA("tt HH':'mm'@'ss", "AM 08:56(a)13"); /* Valid time */
SetLastError(0xdeadbeef);
- ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
/* MSDN: LOCALE_NOUSEROVERRIDE can't be specified with a format string */
SetLastError(0xdeadbeef);
- ret = GetTimeFormatA(lcid, NUO|TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, NUO|TIME_FORCE24HOURFORMAT, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
@@ -475,62 +471,62 @@ static void test_GetTimeFormatA(void)
EXPECT_LENA;
STRINGSA("", "8 AM"); /* TIME_NOMINUTESORSECONDS, default format */
- ret = GetTimeFormatA(lcid, NUO|TIME_NOMINUTESORSECONDS, &curtime, NULL, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, NUO|TIME_NOMINUTESORSECONDS, &curtime, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("m1s2m3s4", ""); /* TIME_NOMINUTESORSECONDS/complex format */
- ret = GetTimeFormatA(lcid, TIME_NOMINUTESORSECONDS, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, TIME_NOMINUTESORSECONDS, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret == strlen(buffer)+1, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
ok( !strcmp( buffer, "" ) || broken( !strcmp( buffer, "4" )), /* win9x */
"Expected '', got '%s'\n", buffer );
STRINGSA("", "8:56 AM"); /* TIME_NOSECONDS/Default format */
- ret = GetTimeFormatA(lcid, NUO|TIME_NOSECONDS, &curtime, NULL, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, NUO|TIME_NOSECONDS, &curtime, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("h:m:s tt", "8:56 AM"); /* TIME_NOSECONDS */
strcpy(Expected, "8:56 AM");
- ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("h.@:m.@:s.@:tt", "8.@:56AM"); /* Multiple delimiters */
- ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
ok( !strcmp( buffer, "8.@:56AM" ) || broken( !strcmp( buffer, "8.@:56.@:AM" )) /* win9x */,
"Expected '8.@:56AM', got '%s'\n", buffer );
STRINGSA("s1s2s3", ""); /* Duplicate tokens */
- ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, TIME_NOSECONDS, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret == strlen(buffer)+1, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
ok( !strcmp( buffer, "" ) || broken( !strcmp( buffer, "3" )), /* win9x */
"Expected '', got '%s'\n", buffer );
STRINGSA("t/tt", "A/AM"); /* AM time marker */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
curtime.wHour = 13;
STRINGSA("t/tt", "P/PM"); /* PM time marker */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("h1t2tt3m", "156"); /* TIME_NOTIMEMARKER: removes text around time marker token */
- ret = GetTimeFormatA(lcid, TIME_NOTIMEMARKER, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, TIME_NOTIMEMARKER, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("h:m:s tt", "13:56:13 PM"); /* TIME_FORCE24HOURFORMAT */
- ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("h:m:s", "13:56:13"); /* TIME_FORCE24HOURFORMAT doesn't add time marker */
- ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
@@ -538,18 +534,18 @@ static void test_GetTimeFormatA(void)
curtime.wMinute = 5;
curtime.wSecond = 3;
STRINGSA("h hh H HH m mm s ss t tt", "2 02 14 14 5 05 3 03 P PM"); /* 24 hrs, leading 0 */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
curtime.wHour = 0;
STRINGSA("h/H/hh/HH", "12/0/12/00"); /* "hh" and "HH" */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("h:m:s tt", "12:5:3 AM"); /* non-zero flags should fail with format, doesn't */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
@@ -565,7 +561,7 @@ static void test_GetTimeFormatA(void)
curtime.wMilliseconds = 22;
STRINGSA("h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS",
"8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS");
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
@@ -577,53 +573,53 @@ static void test_GetTimeFormatA(void)
STRINGSA("h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt'",
"8 h 8 H 08 HH 56 m 13 s A t AM tt"); /* "'" preserves tokens */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("'''", "'"); /* invalid quoted string */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
/* test that msdn suggested single quotation usage works as expected */
STRINGSA("''''", "'"); /* single quote mark */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("''HHHHHH", "08"); /* Normal use */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
/* and test for normal use of the single quotation mark */
STRINGSA("'''HHHHHH'", "'HHHHHH"); /* Normal use */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("'''HHHHHH", "'HHHHHH"); /* Odd use */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("'123'tt", ""); /* TIME_NOTIMEMARKER drops literals too */
- ret = GetTimeFormatA(lcid, TIME_NOTIMEMARKER, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, TIME_NOTIMEMARKER, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
curtime.wHour = 25;
STRINGSA("'123'tt", ""); /* Invalid time */
SetLastError(0xdeadbeef);
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
curtime.wHour = 12;
curtime.wMonth = 60; /* Invalid */
STRINGSA("h:m:s", "12:56:13"); /* Invalid date */
- ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetTimeFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
}
@@ -643,7 +639,7 @@ static void test_GetTimeFormatEx(void)
memset(&curtime, 2, sizeof(SYSTEMTIME));
STRINGSW("tt HH':'mm'@'ss", ""); /* Invalid time */
SetLastError(0xdeadbeef);
- ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
@@ -653,13 +649,13 @@ static void test_GetTimeFormatEx(void)
curtime.wMilliseconds = 22;
STRINGSW("tt HH':'mm'@'ss", "AM 08:56(a)13"); /* Valid time */
SetLastError(0xdeadbeef);
- ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
/* MSDN: LOCALE_NOUSEROVERRIDE can't be specified with a format string */
SetLastError(0xdeadbeef);
- ret = pGetTimeFormatEx(localeW, NUO|TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, NUO|TIME_FORCE24HOURFORMAT, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
@@ -675,58 +671,58 @@ static void test_GetTimeFormatEx(void)
EXPECT_LENW;
STRINGSW("", "8 AM"); /* TIME_NOMINUTESORSECONDS, default format */
- ret = pGetTimeFormatEx(localeW, NUO|TIME_NOMINUTESORSECONDS, &curtime, NULL, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, NUO|TIME_NOMINUTESORSECONDS, &curtime, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("m1s2m3s4", ""); /* TIME_NOMINUTESORSECONDS/complex format */
- ret = pGetTimeFormatEx(localeW, TIME_NOMINUTESORSECONDS, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, TIME_NOMINUTESORSECONDS, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret == strlenW(buffer)+1, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("", "8:56 AM"); /* TIME_NOSECONDS/Default format */
- ret = pGetTimeFormatEx(localeW, NUO|TIME_NOSECONDS, &curtime, NULL, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, NUO|TIME_NOSECONDS, &curtime, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("h:m:s tt", "8:56 AM"); /* TIME_NOSECONDS */
- ret = pGetTimeFormatEx(localeW, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, TIME_NOSECONDS, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("h.@:m.@:s.@:tt", "8.@:56AM"); /* Multiple delimiters */
- ret = pGetTimeFormatEx(localeW, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, TIME_NOSECONDS, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("s1s2s3", ""); /* Duplicate tokens */
- ret = pGetTimeFormatEx(localeW, TIME_NOSECONDS, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, TIME_NOSECONDS, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret == strlenW(buffer)+1, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("t/tt", "A/AM"); /* AM time marker */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
curtime.wHour = 13;
STRINGSW("t/tt", "P/PM"); /* PM time marker */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("h1t2tt3m", "156"); /* TIME_NOTIMEMARKER: removes text around time marker token */
- ret = pGetTimeFormatEx(localeW, TIME_NOTIMEMARKER, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, TIME_NOTIMEMARKER, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("h:m:s tt", "13:56:13 PM"); /* TIME_FORCE24HOURFORMAT */
- ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("h:m:s", "13:56:13"); /* TIME_FORCE24HOURFORMAT doesn't add time marker */
- ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, TIME_FORCE24HOURFORMAT, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
@@ -734,18 +730,18 @@ static void test_GetTimeFormatEx(void)
curtime.wMinute = 5;
curtime.wSecond = 3;
STRINGSW("h hh H HH m mm s ss t tt", "2 02 14 14 5 05 3 03 P PM"); /* 24 hrs, leading 0 */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
curtime.wHour = 0;
STRINGSW("h/H/hh/HH", "12/0/12/00"); /* "hh" and "HH" */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("h:m:s tt", "12:5:3 AM"); /* non-zero flags should fail with format, doesn't */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
@@ -761,7 +757,7 @@ static void test_GetTimeFormatEx(void)
curtime.wMilliseconds = 22;
STRINGSW("h:hh:hhh H:HH:HHH m:mm:mmm M:MM:MMM s:ss:sss S:SS:SSS",
"8:08:08 8:08:08 56:56:56 M:MM:MMM 13:13:13 S:SS:SSS");
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
@@ -773,53 +769,53 @@ static void test_GetTimeFormatEx(void)
STRINGSW("h 'h' H 'H' HH 'HH' m 'm' s 's' t 't' tt 'tt'",
"8 h 8 H 08 HH 56 m 13 s A t AM tt"); /* "'" preserves tokens */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("'''", "'"); /* invalid quoted string */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
/* test that msdn suggested single quotation usage works as expected */
STRINGSW("''''", "'"); /* single quote mark */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("''HHHHHH", "08"); /* Normal use */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
/* and test for normal use of the single quotation mark */
STRINGSW("'''HHHHHH'", "'HHHHHH"); /* Normal use */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("'''HHHHHH", "'HHHHHH"); /* Odd use */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("'123'tt", ""); /* TIME_NOTIMEMARKER drops literals too */
- ret = pGetTimeFormatEx(localeW, TIME_NOTIMEMARKER, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, TIME_NOTIMEMARKER, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
curtime.wHour = 25;
STRINGSW("'123'tt", ""); /* Invalid time */
SetLastError(0xdeadbeef);
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
curtime.wHour = 12;
curtime.wMonth = 60; /* Invalid */
STRINGSW("h:m:s", "12:56:13"); /* Invalid date */
- ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = pGetTimeFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
}
@@ -837,7 +833,7 @@ static void test_GetDateFormatA(void)
memset(&curtime, 2, sizeof(SYSTEMTIME)); /* Invalid time */
STRINGSA("ddd',' MMM dd yy","");
SetLastError(0xdeadbeef);
- ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
@@ -846,26 +842,26 @@ static void test_GetDateFormatA(void)
curtime.wDay = 4;
curtime.wDayOfWeek = 3;
STRINGSA("ddd',' MMM dd yy","Sat, May 04 02"); /* Simple case */
- ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
/* Same as above but with LOCALE_NOUSEROVERRIDE */
STRINGSA("ddd',' MMM dd yy",""); /* Simple case */
SetLastError(0xdeadbeef);
- ret = GetDateFormatA(lcid, NUO, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid, NUO, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
EXPECT_EQA;
STRINGSA("ddd',' MMM dd yy","Sat, May 04 02"); /* Format containing "'" */
- ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
curtime.wHour = 36; /* Invalid */
STRINGSA("ddd',' MMM dd ''''yy","Sat, May 04 '02"); /* Invalid time */
- ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
@@ -881,13 +877,13 @@ static void test_GetDateFormatA(void)
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
STRINGSA("ddd',' MMM dd ''''yy","5/4/2002"); /* Default to DATE_SHORTDATE */
- ret = GetDateFormatA(lcid, NUO, &curtime, NULL, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid, NUO, &curtime, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
if (strncmp(buffer, Expected, strlen(Expected)) && strncmp(buffer, "5/4/02", strlen(Expected)) != 0)
ok (0, "Expected '%s' or '5/4/02', got '%s'\n", Expected, buffer);
SetLastError(0xdeadbeef); buffer[0] = '\0'; /* DATE_LONGDATE */
- ret = GetDateFormatA(lcid, NUO|DATE_LONGDATE, &curtime, NULL, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid, NUO|DATE_LONGDATE, &curtime, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
ok(strcmp(buffer, "Saturday, May 04, 2002") == 0 ||
strcmp(buffer, "Saturday, May 4, 2002") == 0 /* Win 8 */,
@@ -897,7 +893,7 @@ static void test_GetDateFormatA(void)
/* NT4 returns ERROR_INVALID_FLAGS for DATE_YEARMONTH */
STRINGSA("ddd',' MMM dd ''''yy", ""); /* DATE_YEARMONTH */
SetLastError(0xdeadbeef);
- ret = GetDateFormatA(lcid, NUO|DATE_YEARMONTH, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid, NUO|DATE_YEARMONTH, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
EXPECT_EQA;
@@ -906,12 +902,12 @@ static void test_GetDateFormatA(void)
/* and return values */
STRINGSA("m/d/y", ""); /* Invalid flags */
SetLastError(0xdeadbeef);
- ret = GetDateFormatA(lcid, DATE_YEARMONTH|DATE_SHORTDATE|DATE_LONGDATE,
- &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid, DATE_YEARMONTH|DATE_SHORTDATE|DATE_LONGDATE, &curtime, input,
+ buffer, ARRAY_SIZE(buffer));
ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
- ret = GetDateFormatA(lcid_ru, 0, &curtime, "ddMMMM", buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, "ddMMMM", buffer, ARRAY_SIZE(buffer));
if (!ret)
{
win_skip("LANG_RUSSIAN locale data unavailable\n");
@@ -920,37 +916,37 @@ static void test_GetDateFormatA(void)
/* month part should be in genitive form */
strcpy(genitive_month, buffer + 2);
- ret = GetDateFormatA(lcid_ru, 0, &curtime, "MMMM", buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, "MMMM", buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
strcpy(month, buffer);
ok(strcmp(genitive_month, month) != 0, "Expected different month forms\n");
- ret = GetDateFormatA(lcid_ru, 0, &curtime, "ddd", buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, "ddd", buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
strcpy(short_day, buffer);
STRINGSA("dd MMMMddd dd", "");
sprintf(Expected, "04 %s%s 04", genitive_month, short_day);
- ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_EQA;
STRINGSA("MMMMddd dd", "");
sprintf(Expected, "%s%s 04", month, short_day);
- ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_EQA;
STRINGSA("MMMMddd", "");
sprintf(Expected, "%s%s", month, short_day);
- ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_EQA;
STRINGSA("MMMMdd", "");
sprintf(Expected, "%s04", genitive_month);
sprintf(Broken, "%s04", month);
- ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
ok(strncmp(buffer, Expected, strlen(Expected)) == 0 ||
broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */,
@@ -959,7 +955,7 @@ static void test_GetDateFormatA(void)
STRINGSA("MMMMdd ddd", "");
sprintf(Expected, "%s04 %s", genitive_month, short_day);
sprintf(Broken, "%s04 %s", month, short_day);
- ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
ok(strncmp(buffer, Expected, strlen(Expected)) == 0 ||
broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */,
@@ -967,14 +963,14 @@ static void test_GetDateFormatA(void)
STRINGSA("dd dddMMMM", "");
sprintf(Expected, "04 %s%s", short_day, month);
- ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_EQA;
STRINGSA("dd dddMMMM ddd MMMMdd", "");
sprintf(Expected, "04 %s%s %s %s04", short_day, month, short_day, genitive_month);
sprintf(Broken, "04 %s%s %s %s04", short_day, month, short_day, month);
- ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
ok(strncmp(buffer, Expected, strlen(Expected)) == 0 ||
broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */,
@@ -984,7 +980,7 @@ static void test_GetDateFormatA(void)
STRINGSA("ddd',' MMMM dd", "");
sprintf(Expected, "%s, %s 04", short_day, genitive_month);
sprintf(Broken, "%s, %s 04", short_day, month);
- ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatA(lcid_ru, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
ok(strncmp(buffer, Expected, strlen(Expected)) == 0 ||
broken(strncmp(buffer, Broken, strlen(Broken)) == 0) /* nt4 */,
@@ -1005,15 +1001,14 @@ static void test_GetDateFormatEx(void)
STRINGSW("",""); /* If flags are set, then format must be NULL */
SetLastError(0xdeadbeef);
- ret = pGetDateFormatEx(localeW, DATE_LONGDATE, NULL,
- input, buffer, COUNTOF(buffer), NULL);
+ ret = pGetDateFormatEx(localeW, DATE_LONGDATE, NULL, input, buffer, ARRAY_SIZE(buffer), NULL);
ok(!ret && GetLastError() == ERROR_INVALID_FLAGS,
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
EXPECT_EQW;
STRINGSW("",""); /* NULL buffer, len > 0 */
SetLastError(0xdeadbeef);
- ret = pGetDateFormatEx(localeW, 0, NULL, input, NULL, COUNTOF(buffer), NULL);
+ ret = pGetDateFormatEx(localeW, 0, NULL, input, NULL, ARRAY_SIZE(buffer), NULL);
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
@@ -1039,7 +1034,7 @@ static void test_GetDateFormatEx(void)
curtime.wSecond = 65535; /* Invalid */
curtime.wMilliseconds = 12345;
STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002"); /* Incorrect DOW and time */
- ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer), NULL);
+ ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer), NULL);
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
@@ -1052,7 +1047,7 @@ static void test_GetDateFormatEx(void)
curtime.wSecond = 65535; /* Invalid */
curtime.wMilliseconds = 12345;
STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002");
- ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer), emptyW); /* Use reserved arg */
+ ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer), emptyW); /* Use reserved arg */
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
@@ -1068,7 +1063,7 @@ static void test_GetDateFormatEx(void)
curtime.wMilliseconds = 0;
STRINGSW("dddd d MMMM yyyy","Monday 1 January 1601");
SetLastError(0xdeadbeef);
- ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer), NULL);
+ ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer), NULL);
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
@@ -1082,7 +1077,7 @@ static void test_GetDateFormatEx(void)
curtime.wMilliseconds = 999;
STRINGSW("dddd d MMMM yyyy","Friday 31 December 1600");
SetLastError(0xdeadbeef);
- ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, COUNTOF(buffer), NULL);
+ ret = pGetDateFormatEx(localeW, 0, &curtime, input, buffer, ARRAY_SIZE(buffer), NULL);
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
}
@@ -1095,8 +1090,7 @@ static void test_GetDateFormatW(void)
LCID lcid = MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT);
STRINGSW("",""); /* If flags is not zero then format must be NULL */
- ret = GetDateFormatW(LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, NULL,
- input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatW(LOCALE_SYSTEM_DEFAULT, DATE_LONGDATE, NULL, input, buffer, ARRAY_SIZE(buffer));
if (GetLastError() == ERROR_CALL_NOT_IMPLEMENTED)
{
win_skip("GetDateFormatW is not implemented\n");
@@ -1108,7 +1102,7 @@ static void test_GetDateFormatW(void)
STRINGSW("",""); /* NULL buffer, len > 0 */
SetLastError(0xdeadbeef);
- ret = GetDateFormatW (lcid, 0, NULL, input, NULL, COUNTOF(buffer));
+ ret = GetDateFormatW (lcid, 0, NULL, input, NULL, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
@@ -1126,7 +1120,7 @@ static void test_GetDateFormatW(void)
curtime.wSecond = 65535; /* Invalid */
curtime.wMilliseconds = 12345;
STRINGSW("dddd d MMMM yyyy","Wednesday 23 October 2002"); /* Incorrect DOW and time */
- ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
@@ -1142,7 +1136,7 @@ static void test_GetDateFormatW(void)
curtime.wMilliseconds = 0;
STRINGSW("dddd d MMMM yyyy","Monday 1 January 1601");
SetLastError(0xdeadbeef);
- ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
@@ -1156,7 +1150,7 @@ static void test_GetDateFormatW(void)
curtime.wMilliseconds = 999;
STRINGSW("dddd d MMMM yyyy","Friday 31 December 1600");
SetLastError(0xdeadbeef);
- ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, COUNTOF(buffer));
+ ret = GetDateFormatW (lcid, 0, &curtime, input, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
}
@@ -1181,37 +1175,37 @@ static void test_GetCurrencyFormatA(void)
STRINGSA("23",""); /* NULL output, length > 0 --> Error */
SetLastError(0xdeadbeef);
- ret = GetCurrencyFormatA(lcid, 0, input, NULL, NULL, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, NULL, NULL, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA("23,53",""); /* Invalid character --> Error */
SetLastError(0xdeadbeef);
- ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA("--",""); /* Double '-' --> Error */
SetLastError(0xdeadbeef);
- ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA("0-",""); /* Trailing '-' --> Error */
SetLastError(0xdeadbeef);
- ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA("0..",""); /* Double '.' --> Error */
SetLastError(0xdeadbeef);
- ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA(" 0.1",""); /* Leading space --> Error */
SetLastError(0xdeadbeef);
- ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
@@ -1223,39 +1217,39 @@ static void test_GetCurrencyFormatA(void)
STRINGSA("2353",""); /* Format and flags given --> Error */
SetLastError(0xdeadbeef);
- ret = GetCurrencyFormatA(lcid, NUO, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, NUO, input, &format, buffer, ARRAY_SIZE(buffer));
ok( !ret, "Expected ret == 0, got %d\n", ret);
ok( GetLastError() == ERROR_INVALID_FLAGS || GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
STRINGSA("2353",""); /* Invalid format --> Error */
SetLastError(0xdeadbeef);
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA("2353","$2,353.00"); /* Valid number */
- ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("-2353","($2,353.00)"); /* Valid negative number */
- ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("2353.1","$2,353.10"); /* Valid real number */
- ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("2353.111","$2,353.11"); /* Too many DP --> Truncated */
- ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("2353.119","$2,353.12"); /* Too many DP --> Rounded */
- ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
@@ -1269,151 +1263,151 @@ static void test_GetCurrencyFormatA(void)
format.lpCurrencySymbol = szDollar;
STRINGSA("2353","$2353"); /* No decimal or grouping chars expected */
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NumDigits = 1; /* 1 DP --> Expect decimal separator */
STRINGSA("2353","$2353.0");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.Grouping = 2; /* Group by 100's */
STRINGSA("2353","$23,53.0");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("235","$235.0"); /* Grouping of a positive number */
format.Grouping = 3;
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("-235","$-235.0"); /* Grouping of a negative number */
format.NegativeOrder = 2;
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.LeadingZero = 1; /* Always provide leading zero */
STRINGSA(".5","$0.5");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.PositiveOrder = CY_POS_RIGHT;
STRINGSA("1","1.0$");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.PositiveOrder = CY_POS_LEFT_SPACE;
STRINGSA("1","$ 1.0");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.PositiveOrder = CY_POS_RIGHT_SPACE;
STRINGSA("1","1.0 $");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 0;
STRINGSA("-1","($1.0)");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 1;
STRINGSA("-1","-$1.0");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 2;
STRINGSA("-1","$-1.0");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 3;
STRINGSA("-1","$1.0-");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 4;
STRINGSA("-1","(1.0$)");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 5;
STRINGSA("-1","-1.0$");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 6;
STRINGSA("-1","1.0-$");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 7;
STRINGSA("-1","1.0$-");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 8;
STRINGSA("-1","-1.0 $");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 9;
STRINGSA("-1","-$ 1.0");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 10;
STRINGSA("-1","1.0 $-");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 11;
STRINGSA("-1","$ 1.0-");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 12;
STRINGSA("-1","$ -1.0");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 13;
STRINGSA("-1","1.0- $");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 14;
STRINGSA("-1","($ 1.0)");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = 15;
STRINGSA("-1","(1.0 $)");
- ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetCurrencyFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
}
@@ -1437,37 +1431,37 @@ static void test_GetNumberFormatA(void)
STRINGSA("23",""); /* NULL output, length > 0 --> Error */
SetLastError(0xdeadbeef);
- ret = GetNumberFormatA(lcid, 0, input, NULL, NULL, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, NULL, NULL, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA("23,53",""); /* Invalid character --> Error */
SetLastError(0xdeadbeef);
- ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA("--",""); /* Double '-' --> Error */
SetLastError(0xdeadbeef);
- ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA("0-",""); /* Trailing '-' --> Error */
SetLastError(0xdeadbeef);
- ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA("0..",""); /* Double '.' --> Error */
SetLastError(0xdeadbeef);
- ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA(" 0.1",""); /* Leading space --> Error */
SetLastError(0xdeadbeef);
- ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
@@ -1479,44 +1473,44 @@ static void test_GetNumberFormatA(void)
STRINGSA("2353",""); /* Format and flags given --> Error */
SetLastError(0xdeadbeef);
- ret = GetNumberFormatA(lcid, NUO, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, NUO, input, &format, buffer, ARRAY_SIZE(buffer));
ok( !ret, "Expected ret == 0, got %d\n", ret);
ok( GetLastError() == ERROR_INVALID_FLAGS || GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
STRINGSA("2353",""); /* Invalid format --> Error */
SetLastError(0xdeadbeef);
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSA("2353","2,353.00"); /* Valid number */
- ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("-2353","-2,353.00"); /* Valid negative number */
- ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("-353","-353.00"); /* test for off by one error in grouping */
- ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("2353.1","2,353.10"); /* Valid real number */
- ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("2353.111","2,353.11"); /* Too many DP --> Truncated */
- ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("2353.119","2,353.12"); /* Too many DP --> Rounded */
- ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
@@ -1528,67 +1522,67 @@ static void test_GetNumberFormatA(void)
format.lpThousandSep = szComma;
STRINGSA("2353","2353"); /* No decimal or grouping chars expected */
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NumDigits = 1; /* 1 DP --> Expect decimal separator */
STRINGSA("2353","2353.0");
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.Grouping = 2; /* Group by 100's */
STRINGSA("2353","23,53.0");
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("235","235.0"); /* Grouping of a positive number */
format.Grouping = 3;
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
STRINGSA("-235","-235.0"); /* Grouping of a negative number */
format.NegativeOrder = NEG_LEFT;
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.LeadingZero = 1; /* Always provide leading zero */
STRINGSA(".5","0.5");
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = NEG_PARENS;
STRINGSA("-1","(1.0)");
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = NEG_LEFT;
STRINGSA("-1","-1.0");
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = NEG_LEFT_SPACE;
STRINGSA("-1","- 1.0");
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = NEG_RIGHT;
STRINGSA("-1","1.0-");
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
format.NegativeOrder = NEG_RIGHT_SPACE;
STRINGSA("-1","1.0 -");
- ret = GetNumberFormatA(lcid, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
@@ -1598,7 +1592,7 @@ static void test_GetNumberFormatA(void)
{
STRINGSA("-12345","-12 345,00"); /* Try French formatting */
Expected[3] = 160; /* Non breaking space */
- ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = GetNumberFormatA(lcid, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENA; EXPECT_EQA;
}
@@ -1622,32 +1616,32 @@ static void test_GetNumberFormatEx(void)
}
STRINGSW("23",""); /* NULL output, length > 0 --> Error */
- ret = pGetNumberFormatEx(enW, 0, input, NULL, NULL, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, NULL, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("23,53",""); /* Invalid character --> Error */
- ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("--",""); /* Double '-' --> Error */
- ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("0-",""); /* Trailing '-' --> Error */
- ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("0..",""); /* Double '.' --> Error */
- ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW(" 0.1",""); /* Leading space --> Error */
- ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
@@ -1657,50 +1651,50 @@ static void test_GetNumberFormatEx(void)
"Expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
STRINGSW("23",""); /* Bogus locale --> Error */
- ret = pGetNumberFormatEx(bogusW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(bogusW, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
memset(&format, 0, sizeof(format));
STRINGSW("2353",""); /* Format and flags given --> Error */
- ret = pGetNumberFormatEx(enW, NUO, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, NUO, input, &format, buffer, ARRAY_SIZE(buffer));
ok( !ret, "Expected ret == 0, got %d\n", ret);
ok( GetLastError() == ERROR_INVALID_FLAGS || GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_FLAGS, got %d\n", GetLastError());
STRINGSW("2353",""); /* Invalid format --> Error */
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok( !ret && GetLastError() == ERROR_INVALID_PARAMETER,
"Expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
STRINGSW("2353","2,353.00"); /* Valid number */
- ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("-2353","-2,353.00"); /* Valid negative number */
- ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("-353","-353.00"); /* test for off by one error in grouping */
- ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("2353.1","2,353.10"); /* Valid real number */
- ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("2353.111","2,353.11"); /* Too many DP --> Truncated */
- ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("2353.119","2,353.12"); /* Too many DP --> Rounded */
- ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
@@ -1712,67 +1706,67 @@ static void test_GetNumberFormatEx(void)
format.lpThousandSep = commaW;
STRINGSW("2353","2353"); /* No decimal or grouping chars expected */
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NumDigits = 1; /* 1 DP --> Expect decimal separator */
STRINGSW("2353","2353.0");
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.Grouping = 2; /* Group by 100's */
STRINGSW("2353","23,53.0");
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("235","235.0"); /* Grouping of a positive number */
format.Grouping = 3;
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
STRINGSW("-235","-235.0"); /* Grouping of a negative number */
format.NegativeOrder = NEG_LEFT;
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.LeadingZero = 1; /* Always provide leading zero */
STRINGSW(".5","0.5");
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NegativeOrder = NEG_PARENS;
STRINGSW("-1","(1.0)");
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NegativeOrder = NEG_LEFT;
STRINGSW("-1","-1.0");
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NegativeOrder = NEG_LEFT_SPACE;
STRINGSW("-1","- 1.0");
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NegativeOrder = NEG_RIGHT;
STRINGSW("-1","1.0-");
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
format.NegativeOrder = NEG_RIGHT_SPACE;
STRINGSW("-1","1.0 -");
- ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(enW, 0, input, &format, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
@@ -1780,7 +1774,7 @@ static void test_GetNumberFormatEx(void)
{
STRINGSW("-12345","-12 345,00"); /* Try French formatting */
Expected[3] = 160; /* Non breaking space */
- ret = pGetNumberFormatEx(frW, NUO, input, NULL, buffer, COUNTOF(buffer));
+ ret = pGetNumberFormatEx(frW, NUO, input, NULL, buffer, ARRAY_SIZE(buffer));
ok(ret, "Expected ret != 0, got %d, error %d\n", ret, GetLastError());
EXPECT_LENW; EXPECT_EQW;
}
@@ -1849,7 +1843,7 @@ static void test_CompareStringA(void)
char a[256];
LCID lcid = MAKELCID(MAKELANGID(LANG_FRENCH, SUBLANG_DEFAULT), SORT_DEFAULT);
- for (i = 0; i < sizeof(comparestringa_data)/sizeof(struct comparestringa_entry); i++)
+ for (i = 0; i < ARRAY_SIZE(comparestringa_data); i++)
{
const struct comparestringa_entry *entry = &comparestringa_data[i];
@@ -2194,11 +2188,11 @@ static void test_CompareStringEx(void)
return;
}
- for (i = 0; i < sizeof(comparestringex_tests)/sizeof(comparestringex_tests[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(comparestringex_tests); i++)
{
const struct comparestringex_test *e = &comparestringex_tests[i];
- MultiByteToWideChar(CP_ACP, 0, e->locale, -1, locale, sizeof(locale)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, e->locale, -1, locale, ARRAY_SIZE(locale));
ret = pCompareStringEx(locale, e->flags, e->first, -1, e->second, -1, NULL, NULL, 0);
todo_wine_if (e->todo)
ok(ret == e->ret || broken(ret == e->broken),
@@ -2258,7 +2252,7 @@ static void test_LCMapStringA(void)
"unexpected error code %d\n", GetLastError());
/* test invalid flag combinations */
- for (i = 0; i < sizeof(lcmap_invalid_flags)/sizeof(lcmap_invalid_flags[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(lcmap_invalid_flags); i++) {
lstrcpyA(buf, "foo");
SetLastError(0xdeadbeef);
ret = LCMapStringA(LOCALE_USER_DEFAULT, lcmap_invalid_flags[i],
@@ -2420,8 +2414,7 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
char *p_buf = (char *)buf, *p_buf2 = (char *)buf2;
/* LCMAP_LOWERCASE | LCMAP_UPPERCASE makes LCMAP_TITLECASE, so it's valid now. */
- ret = func_ptr(LCMAP_LOWERCASE | LCMAP_UPPERCASE,
- lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(LCMAP_LOWERCASE | LCMAP_UPPERCASE, lower_case, -1, buf, ARRAY_SIZE(buf));
todo_wine ok(ret == lstrlenW(title_case) + 1 || broken(!ret),
"%s ret %d, error %d, expected value %d\n", func_name,
ret, GetLastError(), lstrlenW(title_case) + 1);
@@ -2429,7 +2422,7 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
"Expected title case string\n");
/* test invalid flag combinations */
- for (i = 0; i < sizeof(lcmap_invalid_flags)/sizeof(lcmap_invalid_flags[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(lcmap_invalid_flags); i++) {
lstrcpyW(buf, fooW);
SetLastError(0xdeadbeef);
ret = func_ptr(lcmap_invalid_flags[i],
@@ -2442,22 +2435,19 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
}
/* test LCMAP_LOWERCASE */
- ret = func_ptr(LCMAP_LOWERCASE,
- upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(LCMAP_LOWERCASE, upper_case, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(upper_case) + 1, "%s ret %d, error %d, expected value %d\n", func_name,
ret, GetLastError(), lstrlenW(upper_case) + 1);
ok(!lstrcmpW(buf, lower_case), "%s string compare mismatch\n", func_name);
/* test LCMAP_UPPERCASE */
- ret = func_ptr(LCMAP_UPPERCASE,
- lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(LCMAP_UPPERCASE, lower_case, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(lower_case) + 1, "%s ret %d, error %d, expected value %d\n", func_name,
ret, GetLastError(), lstrlenW(lower_case) + 1);
ok(!lstrcmpW(buf, upper_case), "%s string compare mismatch\n", func_name);
/* test LCMAP_HIRAGANA */
- ret = func_ptr(LCMAP_HIRAGANA,
- japanese_text, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(LCMAP_HIRAGANA, japanese_text, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(hiragana_text) + 1, "%s ret %d, error %d, expected value %d\n", func_name,
ret, GetLastError(), lstrlenW(hiragana_text) + 1);
ok(!lstrcmpW(buf, hiragana_text), "%s string compare mismatch\n", func_name);
@@ -2471,15 +2461,13 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
"%s expected %04x, got %04x\n", func_name, 0x3095, buf2[0]);
/* test LCMAP_KATAKANA | LCMAP_LOWERCASE */
- ret = func_ptr(LCMAP_KATAKANA | LCMAP_LOWERCASE,
- japanese_text, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(LCMAP_KATAKANA | LCMAP_LOWERCASE, japanese_text, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(katakana_text) + 1, "%s ret %d, error %d, expected value %d\n", func_name,
ret, GetLastError(), lstrlenW(katakana_text) + 1);
ok(!lstrcmpW(buf, katakana_text), "%s string compare mismatch\n", func_name);
/* test LCMAP_FULLWIDTH */
- ret = func_ptr(LCMAP_FULLWIDTH,
- halfwidth_text, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(LCMAP_FULLWIDTH, halfwidth_text, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(japanese_text) + 1, "%s ret %d, error %d, expected value %d\n", func_name,
ret, GetLastError(), lstrlenW(japanese_text) + 1);
ok(!lstrcmpW(buf, japanese_text), "%s string compare mismatch\n", func_name);
@@ -2489,8 +2477,7 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
/* test LCMAP_FULLWIDTH | LCMAP_HIRAGANA
(half-width katakana is converted into full-width hiragana) */
- ret = func_ptr(LCMAP_FULLWIDTH | LCMAP_HIRAGANA,
- halfwidth_text, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(LCMAP_FULLWIDTH | LCMAP_HIRAGANA, halfwidth_text, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(hiragana_text) + 1, "%s ret %d, error %d, expected value %d\n", func_name,
ret, GetLastError(), lstrlenW(hiragana_text) + 1);
ok(!lstrcmpW(buf, hiragana_text), "%s string compare mismatch\n", func_name);
@@ -2499,8 +2486,7 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
ok(ret == ret2, "%s ret %d, expected value %d\n", func_name, ret, ret2);
/* test LCMAP_HALFWIDTH */
- ret = func_ptr(LCMAP_HALFWIDTH,
- japanese_text, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(LCMAP_HALFWIDTH, japanese_text, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(halfwidth_text) + 1, "%s ret %d, error %d, expected value %d\n", func_name,
ret, GetLastError(), lstrlenW(halfwidth_text) + 1);
ok(!lstrcmpW(buf, halfwidth_text), "%s string compare mismatch\n", func_name);
@@ -2525,15 +2511,13 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
/* LCMAP_UPPERCASE or LCMAP_LOWERCASE should accept src == dst */
lstrcpyW(buf, lower_case);
- ret = func_ptr(LCMAP_UPPERCASE,
- buf, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(LCMAP_UPPERCASE, buf, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(lower_case) + 1, "%s ret %d, error %d, expected value %d\n", func_name,
ret, GetLastError(), lstrlenW(lower_case) + 1);
ok(!lstrcmpW(buf, upper_case), "%s string compare mismatch\n", func_name);
lstrcpyW(buf, upper_case);
- ret = func_ptr(LCMAP_LOWERCASE,
- buf, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(LCMAP_LOWERCASE, buf, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(upper_case) + 1, "%s ret %d, error %d, expected value %d\n", func_name,
ret, GetLastError(), lstrlenW(lower_case) + 1);
ok(!lstrcmpW(buf, lower_case), "%s string compare mismatch\n", func_name);
@@ -2582,31 +2566,28 @@ static void test_lcmapstring_unicode(lcmapstring_wrapper func_ptr, const char *f
/* test NORM_IGNORENONSPACE */
lstrcpyW(buf, fooW);
- ret = func_ptr(NORM_IGNORENONSPACE,
- lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(NORM_IGNORENONSPACE, lower_case, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(lower_case) + 1, "%s func_ptr should return %d, ret = %d\n", func_name,
lstrlenW(lower_case) + 1, ret);
ok(!lstrcmpW(buf, lower_case), "%s string comparison mismatch\n", func_name);
/* test NORM_IGNORESYMBOLS */
lstrcpyW(buf, fooW);
- ret = func_ptr(NORM_IGNORESYMBOLS,
- lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(NORM_IGNORESYMBOLS, lower_case, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(symbols_stripped) + 1, "%s func_ptr should return %d, ret = %d\n", func_name,
lstrlenW(symbols_stripped) + 1, ret);
ok(!lstrcmpW(buf, symbols_stripped), "%s string comparison mismatch\n", func_name);
/* test NORM_IGNORESYMBOLS | NORM_IGNORENONSPACE */
lstrcpyW(buf, fooW);
- ret = func_ptr(NORM_IGNORESYMBOLS | NORM_IGNORENONSPACE,
- lower_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(NORM_IGNORESYMBOLS | NORM_IGNORENONSPACE, lower_case, -1, buf, ARRAY_SIZE(buf));
ok(ret == lstrlenW(symbols_stripped) + 1, "%s func_ptr should return %d, ret = %d\n", func_name,
lstrlenW(symbols_stripped) + 1, ret);
ok(!lstrcmpW(buf, symbols_stripped), "%s string comparison mismatch\n", func_name);
/* test srclen = 0 */
SetLastError(0xdeadbeef);
- ret = func_ptr(0, upper_case, 0, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = func_ptr(0, upper_case, 0, buf, ARRAY_SIZE(buf));
ok(!ret, "%s func_ptr should fail with srclen = 0\n", func_name);
ok(GetLastError() == ERROR_INVALID_PARAMETER,
"%s unexpected error code %d\n", func_name, GetLastError());
@@ -2625,7 +2606,7 @@ static void test_LCMapStringW(void)
trace("testing LCMapStringW\n");
SetLastError(0xdeadbeef);
- ret = LCMapStringW((LCID)-1, LCMAP_LOWERCASE, upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = LCMapStringW((LCID)-1, LCMAP_LOWERCASE, upper_case, -1, buf, ARRAY_SIZE(buf));
todo_wine {
ok(!ret, "LCMapStringW should fail with bad lcid\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "unexpected error code %d\n", GetLastError());
@@ -2654,7 +2635,7 @@ static void test_LCMapStringEx(void)
SetLastError(0xdeadbeef);
ret = pLCMapStringEx(invalidW, LCMAP_LOWERCASE,
- upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR), NULL, NULL, 0);
+ upper_case, -1, buf, ARRAY_SIZE(buf), NULL, NULL, 0);
todo_wine {
ok(!ret, "LCMapStringEx should fail with bad locale name\n");
ok(GetLastError() == ERROR_INVALID_PARAMETER, "unexpected error code %d\n", GetLastError());
@@ -2662,13 +2643,13 @@ static void test_LCMapStringEx(void)
/* test reserved parameters */
ret = pLCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_LOWERCASE,
- upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR), NULL, NULL, 1);
+ upper_case, -1, buf, ARRAY_SIZE(buf), NULL, NULL, 1);
ok(ret == lstrlenW(upper_case) + 1, "ret %d, error %d, expected value %d\n",
ret, GetLastError(), lstrlenW(upper_case) + 1);
ok(!lstrcmpW(buf, lower_case), "string compare mismatch\n");
ret = pLCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_LOWERCASE,
- upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR), NULL, (void*)1, 0);
+ upper_case, -1, buf, ARRAY_SIZE(buf), NULL, (void*)1, 0);
ok(ret == lstrlenW(upper_case) + 1, "ret %d, error %d, expected value %d\n",
ret, GetLastError(), lstrlenW(upper_case) + 1);
ok(!lstrcmpW(buf, lower_case), "string compare mismatch\n");
@@ -2676,7 +2657,7 @@ static void test_LCMapStringEx(void)
/* crashes on native */
if(0)
ret = pLCMapStringEx(LOCALE_NAME_USER_DEFAULT, LCMAP_LOWERCASE,
- upper_case, -1, buf, sizeof(buf)/sizeof(WCHAR), (void*)1, NULL, 0);
+ upper_case, -1, buf, ARRAY_SIZE(buf), (void*)1, NULL, 0);
test_lcmapstring_unicode(LCMapStringEx_wrapper, "LCMapStringEx:");
}
@@ -2779,7 +2760,7 @@ static void test_LocaleNameToLCID(void)
wine_dbgstr_w(ptr->name), lcid, ptr->lcid);
*buffer = 0;
- ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0);
+ ret = pLCIDToLocaleName(lcid, buffer, ARRAY_SIZE(buffer), 0);
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(ptr->name), ret);
ok(!lstrcmpW(ptr->sname, buffer), "%s: got wrong locale name %s\n",
wine_dbgstr_w(ptr->name), wine_dbgstr_w(buffer));
@@ -2791,12 +2772,13 @@ static void test_LocaleNameToLCID(void)
lcid = pLocaleNameToLCID(zhHantW, 0);
ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT),
"%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhHantW), lcid);
- ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0);
+ ret = pLCIDToLocaleName(lcid, buffer, ARRAY_SIZE(buffer), 0);
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHantW), ret);
ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n",
wine_dbgstr_w(zhHantW), wine_dbgstr_w(buffer));
/* check that 0x7c04 also works and is mapped to zh-HK */
- ret = pLCIDToLocaleName(MAKELANGID(LANG_CHINESE_TRADITIONAL, SUBLANG_CHINESE_TRADITIONAL), buffer, sizeof(buffer)/sizeof(WCHAR), 0);
+ ret = pLCIDToLocaleName(MAKELANGID(LANG_CHINESE_TRADITIONAL, SUBLANG_CHINESE_TRADITIONAL),
+ buffer, ARRAY_SIZE(buffer), 0);
todo_wine ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHantW), ret);
ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n",
wine_dbgstr_w(zhHantW), wine_dbgstr_w(buffer));
@@ -2805,7 +2787,7 @@ static void test_LocaleNameToLCID(void)
lcid = pLocaleNameToLCID(zhhantW, 0);
ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE, SUBLANG_CHINESE_HONGKONG), SORT_DEFAULT),
"%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhhantW), lcid);
- ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0);
+ ret = pLCIDToLocaleName(lcid, buffer, ARRAY_SIZE(buffer), 0);
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhhantW), ret);
ok(!lstrcmpW(zhhkW, buffer), "%s: got wrong locale name %s\n",
wine_dbgstr_w(zhhantW), wine_dbgstr_w(buffer));
@@ -2815,12 +2797,12 @@ static void test_LocaleNameToLCID(void)
/* check that LocaleNameToLCID actually returns 0x0804 */
ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT),
"%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhHansW), lcid);
- ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0);
+ ret = pLCIDToLocaleName(lcid, buffer, ARRAY_SIZE(buffer), 0);
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHansW), ret);
ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n",
wine_dbgstr_w(zhHansW), wine_dbgstr_w(buffer));
/* check that 0x0004 also works and is mapped to zh-CN */
- ret = pLCIDToLocaleName(MAKELANGID(LANG_CHINESE, SUBLANG_NEUTRAL), buffer, sizeof(buffer)/sizeof(WCHAR), 0);
+ ret = pLCIDToLocaleName(MAKELANGID(LANG_CHINESE, SUBLANG_NEUTRAL), buffer, ARRAY_SIZE(buffer), 0);
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhHansW), ret);
ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n",
wine_dbgstr_w(zhHansW), wine_dbgstr_w(buffer));
@@ -2829,7 +2811,7 @@ static void test_LocaleNameToLCID(void)
lcid = pLocaleNameToLCID(zhhansW, 0);
ok(lcid == MAKELCID(MAKELANGID(LANG_CHINESE_SIMPLIFIED, SUBLANG_CHINESE_SIMPLIFIED), SORT_DEFAULT),
"%s: got wrong lcid 0x%04x\n", wine_dbgstr_w(zhhansW), lcid);
- ret = pLCIDToLocaleName(lcid, buffer, sizeof(buffer)/sizeof(WCHAR), 0);
+ ret = pLCIDToLocaleName(lcid, buffer, ARRAY_SIZE(buffer), 0);
ok(ret > 0, "%s: got %d\n", wine_dbgstr_w(zhhansW), ret);
ok(!lstrcmpW(zhcnW, buffer), "%s: got wrong locale name %s\n",
wine_dbgstr_w(zhhansW), wine_dbgstr_w(buffer));
@@ -2938,24 +2920,24 @@ static void test_sorting(void)
/* 1. sort using lstrcmpA */
memcpy(buf, strings, sizeof(strings));
- qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string1);
- for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
+ qsort(buf, ARRAY_SIZE(strings), sizeof(strings[0]), compare_string1);
+ for (i = 0; i < ARRAY_SIZE(strings); i++)
{
ok(!strcmp(strings_sorted[i], str_buf[i]),
"qsort using lstrcmpA failed for element %d\n", i);
}
/* 2. sort using CompareStringA */
memcpy(buf, strings, sizeof(strings));
- qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string2);
- for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
+ qsort(buf, ARRAY_SIZE(strings), sizeof(strings[0]), compare_string2);
+ for (i = 0; i < ARRAY_SIZE(strings); i++)
{
ok(!strcmp(strings_sorted[i], str_buf[i]),
"qsort using CompareStringA failed for element %d\n", i);
}
/* 3. sort using sort keys */
memcpy(buf, strings, sizeof(strings));
- qsort(buf, sizeof(strings)/sizeof(strings[0]), sizeof(strings[0]), compare_string3);
- for (i = 0; i < sizeof(strings)/sizeof(strings[0]); i++)
+ qsort(buf, ARRAY_SIZE(strings), sizeof(strings[0]), compare_string3);
+ for (i = 0; i < ARRAY_SIZE(strings); i++)
{
ok(!strcmp(strings_sorted[i], str_buf[i]),
"qsort using sort keys failed for element %d\n", i);
@@ -3333,7 +3315,7 @@ static void test_FoldStringW(void)
}
/* Invalid flag combinations */
- for (i = 0; i < sizeof(badFlags)/sizeof(badFlags[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(badFlags); i++)
{
src[0] = dst[0] = '\0';
SetLastError(0);
@@ -3395,7 +3377,7 @@ static void test_FoldStringW(void)
'A','X', ret, dst[0], dst[1], GetLastError());
/* MAP_FOLDDIGITS */
- for (j = 0; j < sizeof(digitRanges)/sizeof(digitRanges[0]); j++)
+ for (j = 0; j < ARRAY_SIZE(digitRanges); j++)
{
/* Check everything before this range */
for (ch = prev_ch; ch < digitRanges[j]; ch++)
@@ -3447,14 +3429,12 @@ static void test_FoldStringW(void)
/* MAP_FOLDCZONE */
SetLastError(0);
ret = pFoldStringW(MAP_FOLDCZONE, foldczone_src, -1, dst, 256);
- ok(ret == sizeof(foldczone_dst)/sizeof(foldczone_dst[0]),
- "Got %d, error %d\n", ret, GetLastError());
+ ok(ret == ARRAY_SIZE(foldczone_dst), "Got %d, error %d\n", ret, GetLastError());
ok(!memcmp(dst, foldczone_dst, sizeof(foldczone_dst)),
"MAP_FOLDCZONE: Expanded incorrectly\n");
ret = pFoldStringW(MAP_FOLDCZONE|MAP_PRECOMPOSED, foldczone_todo_src, -1, dst, 256);
- todo_wine ok(ret == sizeof(foldczone_todo_dst)/sizeof(foldczone_todo_dst[0]),
- "Got %d, error %d\n", ret, GetLastError());
+ todo_wine ok(ret == ARRAY_SIZE(foldczone_todo_dst), "Got %d, error %d\n", ret, GetLastError());
todo_wine ok(!memcmp(dst, foldczone_todo_dst, sizeof(foldczone_todo_dst))
|| broken(!memcmp(dst, foldczone_todo_broken_dst, sizeof(foldczone_todo_broken_dst))),
"MAP_FOLDCZONE: Expanded incorrectly (%s)\n", wine_dbgstr_w(dst));
@@ -3464,8 +3444,7 @@ static void test_FoldStringW(void)
ret = pFoldStringW(MAP_EXPAND_LIGATURES, ligatures_src, -1, dst, 256);
/* NT 4.0 doesn't support MAP_EXPAND_LIGATURES */
if (!(ret == 0 && GetLastError() == ERROR_INVALID_FLAGS)) {
- ok(ret == sizeof(ligatures_dst)/sizeof(ligatures_dst[0]),
- "Got %d, error %d\n", ret, GetLastError());
+ ok(ret == ARRAY_SIZE(ligatures_dst), "Got %d, error %d\n", ret, GetLastError());
ok(!memcmp(dst, ligatures_dst, sizeof(ligatures_dst)),
"MAP_EXPAND_LIGATURES: Expanded incorrectly\n");
}
@@ -3866,7 +3845,7 @@ static void test_EnumTimeFormatsW(void)
date_fmt_bufW[0] = 0;
ret = EnumTimeFormatsW(enum_datetime_procW, lcid, 0);
ok(ret, "EnumTimeFormatsW(0) error %d\n", GetLastError());
- ret = GetLocaleInfoW(lcid, LOCALE_STIMEFORMAT, bufW, sizeof(bufW)/sizeof(bufW[0]));
+ ret = GetLocaleInfoW(lcid, LOCALE_STIMEFORMAT, bufW, ARRAY_SIZE(bufW));
ok(ret, "GetLocaleInfoW(LOCALE_STIMEFORMAT) error %d\n", GetLastError());
ok(!lstrcmpW(date_fmt_bufW, bufW), "expected \"%s\" got \"%s\"\n", wine_dbgstr_w(date_fmt_bufW),
wine_dbgstr_w(bufW));
@@ -3874,7 +3853,7 @@ static void test_EnumTimeFormatsW(void)
date_fmt_bufW[0] = 0;
ret = EnumTimeFormatsW(enum_datetime_procW, lcid, LOCALE_USE_CP_ACP);
ok(ret, "EnumTimeFormatsW(LOCALE_USE_CP_ACP) error %d\n", GetLastError());
- ret = GetLocaleInfoW(lcid, LOCALE_STIMEFORMAT, bufW, sizeof(bufW)/sizeof(bufW[0]));
+ ret = GetLocaleInfoW(lcid, LOCALE_STIMEFORMAT, bufW, ARRAY_SIZE(bufW));
ok(ret, "GetLocaleInfoW(LOCALE_STIMEFORMAT) error %d\n", GetLastError());
ok(!lstrcmpW(date_fmt_bufW, bufW), "expected \"%s\" got \"%s\"\n", wine_dbgstr_w(date_fmt_bufW),
wine_dbgstr_w(bufW));
@@ -3888,7 +3867,7 @@ static void test_EnumTimeFormatsW(void)
char buf[256];
ok(ret, "EnumTimeFormatsW(TIME_NOSECONDS) error %d\n", GetLastError());
- ret = GetLocaleInfoW(lcid, LOCALE_SSHORTTIME, bufW, sizeof(bufW)/sizeof(bufW[0]));
+ ret = GetLocaleInfoW(lcid, LOCALE_SSHORTTIME, bufW, ARRAY_SIZE(bufW));
ok(ret, "GetLocaleInfoW(LOCALE_SSHORTTIME) error %d\n", GetLastError());
ok(!lstrcmpW(date_fmt_bufW, bufW), "expected \"%s\" got \"%s\"\n", wine_dbgstr_w(date_fmt_bufW),
wine_dbgstr_w(bufW));
@@ -3903,7 +3882,7 @@ static void test_EnumTimeFormatsW(void)
GetLastError());
/* And it's not supported by GetLocaleInfoA either */
- ret = GetLocaleInfoA(lcid, LOCALE_SSHORTTIME, buf, sizeof(buf)/sizeof(buf[0]));
+ ret = GetLocaleInfoA(lcid, LOCALE_SSHORTTIME, buf, ARRAY_SIZE(buf));
ok(!ret && GetLastError() == ERROR_INVALID_FLAGS, "GetLocaleInfoA(LOCALE_SSHORTTIME) ret %d, error %d\n", ret,
GetLastError());
}
@@ -4241,28 +4220,25 @@ static void test_IdnToNameprepUnicode(void)
ok(err == test_data[1].err, "err = %d\n", err);
SetLastError(0xdeadbeef);
- ret = pIdnToNameprepUnicode(0, test_data[0].in, -1,
- buf, sizeof(buf)/sizeof(WCHAR));
+ ret = pIdnToNameprepUnicode(0, test_data[0].in, -1, buf, ARRAY_SIZE(buf));
err = GetLastError();
ok(ret == test_data[0].ret, "ret = %d\n", ret);
ok(err == 0xdeadbeef, "err = %d\n", err);
SetLastError(0xdeadbeef);
- ret = pIdnToNameprepUnicode(0, test_data[0].in, -2,
- buf, sizeof(buf)/sizeof(WCHAR));
+ ret = pIdnToNameprepUnicode(0, test_data[0].in, -2, buf, ARRAY_SIZE(buf));
err = GetLastError();
ok(ret == 0, "ret = %d\n", ret);
ok(err == ERROR_INVALID_PARAMETER, "err = %d\n", err);
SetLastError(0xdeadbeef);
- ret = pIdnToNameprepUnicode(0, test_data[0].in, 0,
- buf, sizeof(buf)/sizeof(WCHAR));
+ ret = pIdnToNameprepUnicode(0, test_data[0].in, 0, buf, ARRAY_SIZE(buf));
err = GetLastError();
ok(ret == 0, "ret = %d\n", ret);
ok(err == ERROR_INVALID_NAME, "err = %d\n", err);
ret = pIdnToNameprepUnicode(IDN_ALLOW_UNASSIGNED|IDN_USE_STD3_ASCII_RULES,
- test_data[0].in, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ test_data[0].in, -1, buf, ARRAY_SIZE(buf));
ok(ret == test_data[0].ret, "ret = %d\n", ret);
SetLastError(0xdeadbeef);
@@ -4278,11 +4254,11 @@ static void test_IdnToNameprepUnicode(void)
ok(err == ERROR_INVALID_FLAGS || err == ERROR_INVALID_PARAMETER /* Win8 */,
"err = %d\n", err);
- for (i=0; i<sizeof(test_data)/sizeof(*test_data); i++)
+ for (i=0; i<ARRAY_SIZE(test_data); i++)
{
SetLastError(0xdeadbeef);
- ret = pIdnToNameprepUnicode(test_data[i].flags, test_data[i].in,
- test_data[i].in_len, buf, sizeof(buf)/sizeof(WCHAR));
+ ret = pIdnToNameprepUnicode(test_data[i].flags, test_data[i].in, test_data[i].in_len,
+ buf, ARRAY_SIZE(buf));
err = GetLastError();
todo_wine_if (test_data[i].todo)
@@ -4355,7 +4331,7 @@ static void test_IdnToAscii(void)
return;
}
- for (i=0; i<sizeof(test_data)/sizeof(*test_data); i++)
+ for (i=0; i<ARRAY_SIZE(test_data); i++)
{
SetLastError(0xdeadbeef);
ret = pIdnToAscii(test_data[i].flags, test_data[i].in,
@@ -4427,7 +4403,7 @@ static void test_IdnToUnicode(void)
return;
}
- for (i=0; i<sizeof(test_data)/sizeof(*test_data); i++)
+ for (i=0; i<ARRAY_SIZE(test_data); i++)
{
ret = pIdnToUnicode(test_data[i].flags, test_data[i].in,
test_data[i].in_len, NULL, 0);
@@ -4456,7 +4432,7 @@ static void test_GetLocaleInfoEx(void)
return;
}
- ret = pGetLocaleInfoEx(enW, LOCALE_SNAME, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(enW, LOCALE_SNAME, bufferW, ARRAY_SIZE(bufferW));
ok(ret || broken(ret == 0) /* Vista */, "got %d\n", ret);
if (ret)
{
@@ -4479,31 +4455,31 @@ static void test_GetLocaleInfoEx(void)
ret = pGetLocaleInfoEx(enW, LOCALE_SNAME, NULL, 0);
ok(ret == 3 && GetLastError() == 0xdeadbeef, "got %d, %d\n", ret, GetLastError());
- ret = pGetLocaleInfoEx(enusW, LOCALE_SNAME, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(enusW, LOCALE_SNAME, bufferW, ARRAY_SIZE(bufferW));
ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret);
ok(!lstrcmpW(bufferW, enusW), "got %s\n", wine_dbgstr_w(bufferW));
- ret = pGetLocaleInfoEx(enW, LOCALE_SABBREVCTRYNAME, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(enW, LOCALE_SABBREVCTRYNAME, bufferW, ARRAY_SIZE(bufferW));
ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret);
ok(!lstrcmpW(bufferW, usaW), "got %s\n", wine_dbgstr_w(bufferW));
- ret = pGetLocaleInfoEx(enW, LOCALE_SABBREVLANGNAME, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(enW, LOCALE_SABBREVLANGNAME, bufferW, ARRAY_SIZE(bufferW));
ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret);
ok(!lstrcmpW(bufferW, enuW), "got %s\n", wine_dbgstr_w(bufferW));
- ret = pGetLocaleInfoEx(enusW, LOCALE_SPARENT, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(enusW, LOCALE_SPARENT, bufferW, ARRAY_SIZE(bufferW));
ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret);
ok(!lstrcmpW(bufferW, enW), "got %s\n", wine_dbgstr_w(bufferW));
- ret = pGetLocaleInfoEx(enW, LOCALE_SPARENT, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(enW, LOCALE_SPARENT, bufferW, ARRAY_SIZE(bufferW));
ok(ret == 1, "got %d\n", ret);
ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW));
- ret = pGetLocaleInfoEx(enW, LOCALE_SPARENT | LOCALE_NOUSEROVERRIDE, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(enW, LOCALE_SPARENT | LOCALE_NOUSEROVERRIDE, bufferW, ARRAY_SIZE(bufferW));
ok(ret == 1, "got %d\n", ret);
ok(!bufferW[0], "got %s\n", wine_dbgstr_w(bufferW));
- ret = pGetLocaleInfoEx(enW, LOCALE_SCOUNTRY, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(enW, LOCALE_SCOUNTRY, bufferW, ARRAY_SIZE(bufferW));
ok(ret == lstrlenW(bufferW)+1, "got %d\n", ret);
if ((PRIMARYLANGID(LANGIDFROMLCID(GetSystemDefaultLCID())) != LANG_ENGLISH) ||
(PRIMARYLANGID(LANGIDFROMLCID(GetThreadLocale())) != LANG_ENGLISH))
@@ -4515,7 +4491,7 @@ static void test_GetLocaleInfoEx(void)
bufferW[0] = 0;
SetLastError(0xdeadbeef);
- ret = pGetLocaleInfoEx(dummyW, LOCALE_SNAME, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(dummyW, LOCALE_SNAME, bufferW, ARRAY_SIZE(bufferW));
ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %d, error %d\n", ret, GetLastError());
while (*ptr->name)
@@ -4525,15 +4501,15 @@ static void test_GetLocaleInfoEx(void)
todo_wine_if (ptr->todo)
ok(val == ptr->lcid, "%s: got wrong lcid 0x%04x, expected 0x%04x\n", wine_dbgstr_w(ptr->name), val, ptr->lcid);
bufferW[0] = 0;
- ret = pGetLocaleInfoEx(ptr->name, LOCALE_SNAME, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(ptr->name, LOCALE_SNAME, bufferW, ARRAY_SIZE(bufferW));
ok(ret == lstrlenW(bufferW)+1, "%s: got ret value %d\n", wine_dbgstr_w(ptr->name), ret);
ok(!lstrcmpW(bufferW, ptr->name), "%s: got wrong LOCALE_SNAME %s\n", wine_dbgstr_w(ptr->name), wine_dbgstr_w(bufferW));
ptr++;
}
- ret = pGetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, bufferW, sizeof(bufferW)/sizeof(WCHAR));
+ ret = pGetLocaleInfoEx(LOCALE_NAME_USER_DEFAULT, LOCALE_SNAME, bufferW, ARRAY_SIZE(bufferW));
ok(ret && ret == lstrlenW(bufferW)+1, "got ret value %d\n", ret);
- ret = GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SNAME, buffer2, sizeof(buffer2)/sizeof(WCHAR));
+ ret = GetLocaleInfoW(GetUserDefaultLCID(), LOCALE_SNAME, buffer2, ARRAY_SIZE(buffer2));
ok(ret && ret == lstrlenW(buffer2)+1, "got ret value %d\n", ret);
ok(!lstrcmpW(bufferW, buffer2), "LOCALE_SNAMEs don't match %s %s\n", wine_dbgstr_w(bufferW), wine_dbgstr_w(buffer2));
}
@@ -5367,18 +5343,18 @@ static void test_FindNLSStringEx(void)
static struct test_data test_arr[] =
{
- { localeW, FIND_FROMSTART, en_simpsimpW, sizeof(en_simpsimpW)/sizeof(WCHAR)-1,
- en_simpW, sizeof(en_simpW)/sizeof(WCHAR)-1, 0, 0, 6, 0, FALSE},
- { localeW, FIND_FROMEND, en_simpsimpW, sizeof(en_simpsimpW)/sizeof(WCHAR)-1,
- en_simpW, sizeof(en_simpW)/sizeof(WCHAR)-1, 0, 6, 6, 0, FALSE},
- { localeW, FIND_STARTSWITH, en_simpsimpW, sizeof(en_simpsimpW)/sizeof(WCHAR)-1,
- en_simpW, sizeof(en_simpW)/sizeof(WCHAR)-1, 0, 0, 6, 0, FALSE},
- { localeW, FIND_ENDSWITH, en_simpsimpW, sizeof(en_simpsimpW)/sizeof(WCHAR)-1,
- en_simpW, sizeof(en_simpW)/sizeof(WCHAR)-1, 0, 6, 6, 0, FALSE},
- { localeW, FIND_FROMSTART, comb_s_accent1W, sizeof(comb_s_accent1W)/sizeof(WCHAR)-1,
- comb_s_accent2W, sizeof(comb_s_accent2W)/sizeof(WCHAR)-1, 0, 0, 6, 1, TRUE },
- { localeW, FIND_FROMSTART, comb_q_accent1W, sizeof(comb_q_accent1W)/sizeof(WCHAR)-1,
- comb_q_accent2W, sizeof(comb_q_accent2W)/sizeof(WCHAR)-1, 0, 0, 7, 1, FALSE },
+ { localeW, FIND_FROMSTART, en_simpsimpW, ARRAY_SIZE(en_simpsimpW)-1,
+ en_simpW, ARRAY_SIZE(en_simpW)-1, 0, 0, 6, 0, FALSE},
+ { localeW, FIND_FROMEND, en_simpsimpW, ARRAY_SIZE(en_simpsimpW)-1,
+ en_simpW, ARRAY_SIZE(en_simpW)-1, 0, 6, 6, 0, FALSE},
+ { localeW, FIND_STARTSWITH, en_simpsimpW, ARRAY_SIZE(en_simpsimpW)-1,
+ en_simpW, ARRAY_SIZE(en_simpW)-1, 0, 0, 6, 0, FALSE},
+ { localeW, FIND_ENDSWITH, en_simpsimpW, ARRAY_SIZE(en_simpsimpW)-1,
+ en_simpW, ARRAY_SIZE(en_simpW)-1, 0, 6, 6, 0, FALSE},
+ { localeW, FIND_FROMSTART, comb_s_accent1W, ARRAY_SIZE(comb_s_accent1W)-1,
+ comb_s_accent2W, ARRAY_SIZE(comb_s_accent2W)-1, 0, 0, 6, 1, TRUE },
+ { localeW, FIND_FROMSTART, comb_q_accent1W, ARRAY_SIZE(comb_q_accent1W)-1,
+ comb_q_accent2W, ARRAY_SIZE(comb_q_accent2W)-1, 0, 0, 7, 1, FALSE },
{ 0 }
};
struct test_data *ptest;
--
2.14.4
June 22, 2018
Re: [PATCH] wininet/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Sorry about this one, sent the wrong (old) patch out.
bye
michael
On 06/22/2018 07:02 PM, Michael Stefaniuc wrote:
> Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
> ---
> dlls/wininet/tests/ftp.c | 2 +-
> dlls/wininet/tests/http.c | 10 ++++-----
> dlls/wininet/tests/internet.c | 16 ++++++-------
> dlls/wininet/tests/url.c | 52 +++++++++++++++++++++----------------------
> dlls/wininet/tests/urlcache.c | 4 ++--
> 5 files changed, 42 insertions(+), 42 deletions(-)
>
> diff --git a/dlls/wininet/tests/ftp.c b/dlls/wininet/tests/ftp.c
> index d2118faded..6f50104f3b 100644
> --- a/dlls/wininet/tests/ftp.c
> +++ b/dlls/wininet/tests/ftp.c
> @@ -735,7 +735,7 @@ static void test_command(HINTERNET hFtp, HINTERNET hConnect)
> return;
> }
>
> - for (i = 0; i < sizeof(command_test) / sizeof(command_test[0]); i++)
> + for (i = 0; i < ARRAY_SIZE(command_test); i++)
> {
> SetLastError(0xdeadbeef);
> ret = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, command_test[i].cmd, 0, NULL);
> diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
> index 0524ddf3fd..ace8512399 100644
> --- a/dlls/wininet/tests/http.c
> +++ b/dlls/wininet/tests/http.c
> @@ -172,7 +172,7 @@ static BOOL (WINAPI *pInternetGetSecurityInfoByURLA)(LPSTR,PCCERT_CHAIN_CONTEXT*
> static int strcmp_wa(LPCWSTR strw, const char *stra)
> {
> WCHAR buf[512];
> - MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR));
> + MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
> return lstrcmpW(strw, buf);
> }
>
> @@ -4204,7 +4204,7 @@ static void test_http_status(int port)
> DWORD i, size;
> BOOL res;
>
> - for(i=0; i < sizeof(http_status_tests)/sizeof(*http_status_tests); i++) {
> + for(i = 0; i < ARRAY_SIZE(http_status_tests); i++) {
> send_buffer = http_status_tests[i].response_text;
>
> open_simple_request(&req, "localhost", port, NULL, "/send_from_buffer");
> @@ -6543,14 +6543,14 @@ static const struct notification async_send_request_ex_chunked_test[] =
> static const struct notification_data notification_data[] = {
> {
> async_send_request_ex_chunked_test,
> - sizeof(async_send_request_ex_chunked_test)/sizeof(async_send_request_ex_chunked_test[0]),
> + ARRAY_SIZE(async_send_request_ex_chunked_test),
> "GET",
> "test.winehq.org",
> "tests/data.php"
> },
> {
> async_send_request_ex_test,
> - sizeof(async_send_request_ex_test)/sizeof(async_send_request_ex_test[0]),
> + ARRAY_SIZE(async_send_request_ex_test),
> "POST",
> "test.winehq.org",
> "tests/post.php",
> @@ -6565,7 +6565,7 @@ static const struct notification_data notification_data[] = {
> },
> {
> async_send_request_ex_resolve_failure_test,
> - sizeof(async_send_request_ex_resolve_failure_test)/sizeof(async_send_request_ex_resolve_failure_test[0]),
> + ARRAY_SIZE(async_send_request_ex_resolve_failure_test),
> "GET",
> "brokenhost",
> "index.html",
> diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c
> index 39c698f5db..7889e40ea8 100644
> --- a/dlls/wininet/tests/internet.c
> +++ b/dlls/wininet/tests/internet.c
> @@ -629,7 +629,7 @@ static void test_cookie_url(void)
> ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
> "InternetGetCookeA failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
>
> - len = sizeof(bufw)/sizeof(*bufw);
> + len = ARRAY_SIZE(bufw);
> res = InternetGetCookieW(about_blankW, NULL, bufw, &len);
> ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
> "InternetGetCookeW failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
> @@ -639,7 +639,7 @@ static void test_cookie_url(void)
> ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
> "InternetGetCookeExA failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
>
> - len = sizeof(bufw)/sizeof(*bufw);
> + len = ARRAY_SIZE(bufw);
> res = pInternetGetCookieExW(about_blankW, NULL, bufw, &len, 0, NULL);
> ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
> "InternetGetCookeExW failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
> @@ -887,7 +887,7 @@ static void InternetTimeFromSystemTimeW_test(void)
>
> /* test too small buffer size */
> SetLastError(0xdeadbeef);
> - ret = pInternetTimeFromSystemTimeW( &time, INTERNET_RFC1123_FORMAT, string, sizeof(string)/sizeof(string[0]) );
> + ret = pInternetTimeFromSystemTimeW( &time, INTERNET_RFC1123_FORMAT, string, ARRAY_SIZE(string));
> error = GetLastError();
> ok( !ret, "InternetTimeFromSystemTimeW should have returned FALSE\n" );
> ok( error == ERROR_INSUFFICIENT_BUFFER,
> @@ -1084,7 +1084,7 @@ static void test_PrivacyGetSetZonePreferenceW(void)
> trace("template %u\n", old_template);
>
> if(old_template == PRIVACY_TEMPLATE_ADVANCED) {
> - pref_size = sizeof(pref)/sizeof(WCHAR);
> + pref_size = ARRAY_SIZE(pref);
> ret = pPrivacyGetZonePreferenceW(zone, type, &old_template, pref, &pref_size);
> ok(ret == 0, "expected ret == 0, got %u\n", ret);
> }
> @@ -1721,7 +1721,7 @@ static void test_InternetGetConnectedStateExW(void)
>
> flags = 0;
> buffer[0] = 0;
> - res = pInternetGetConnectedStateExW(&flags, buffer, sizeof(buffer) / sizeof(buffer[0]), 0);
> + res = pInternetGetConnectedStateExW(&flags, buffer, ARRAY_SIZE(buffer), 0);
> trace("Internet Connection: Flags 0x%02x - Name '%s'\n", flags, wine_dbgstr_w(buffer));
> todo_wine
> ok (flags & INTERNET_RAS_INSTALLED, "Missing RAS flag\n");
> @@ -1755,21 +1755,21 @@ todo_wine
> ok(!buffer[0], "Buffer must not change, got %02X\n", buffer[0]);
>
> buffer[0] = 0;
> - res = pInternetGetConnectedStateExW(NULL, buffer, sizeof(buffer) / sizeof(buffer[0]), 0);
> + res = pInternetGetConnectedStateExW(NULL, buffer, ARRAY_SIZE(buffer), 0);
> ok(res == TRUE, "Expected TRUE, got %d\n", res);
> sz = lstrlenW(buffer);
> ok(sz > 0, "Expected a connection name\n");
>
> buffer[0] = 0;
> flags = 0;
> - res = pInternetGetConnectedStateExW(&flags, buffer, sizeof(buffer) / sizeof(buffer[0]), 0);
> + res = pInternetGetConnectedStateExW(&flags, buffer, ARRAY_SIZE(buffer), 0);
> ok(res == TRUE, "Expected TRUE, got %d\n", res);
> ok(flags, "Expected at least one flag set\n");
> sz = lstrlenW(buffer);
> ok(sz > 0, "Expected a connection name\n");
>
> flags = 0;
> - res = pInternetGetConnectedStateExW(&flags, NULL, sizeof(buffer) / sizeof(buffer[0]), 0);
> + res = pInternetGetConnectedStateExW(&flags, NULL, ARRAY_SIZE(buffer), 0);
> ok(res == TRUE, "Expected TRUE, got %d\n", res);
> ok(flags, "Expected at least one flag set\n");
>
> diff --git a/dlls/wininet/tests/url.c b/dlls/wininet/tests/url.c
> index 0af58358eb..18c77b6647 100644
> --- a/dlls/wininet/tests/url.c
> +++ b/dlls/wininet/tests/url.c
> @@ -672,17 +672,17 @@ static void InternetCrackUrlW_test(void)
> memset(&comp, 0, sizeof comp);
> comp.dwStructSize = sizeof(comp);
> comp.lpszScheme = scheme;
> - comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
> + comp.dwSchemeLength = ARRAY_SIZE(scheme);
> comp.lpszHostName = host;
> - comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
> + comp.dwHostNameLength = ARRAY_SIZE(host);
> comp.lpszUserName = user;
> - comp.dwUserNameLength = sizeof(user)/sizeof(user[0]);
> + comp.dwUserNameLength = ARRAY_SIZE(user);
> comp.lpszPassword = pwd;
> - comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]);
> + comp.dwPasswordLength = ARRAY_SIZE(pwd);
> comp.lpszUrlPath = urlpart;
> - comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
> + comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
> comp.lpszExtraInfo = extra;
> - comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
> + comp.dwExtraInfoLength = ARRAY_SIZE(extra);
>
> SetLastError(0xdeadbeef);
> r = InternetCrackUrlW(NULL, 0, 0, &comp );
> @@ -721,9 +721,9 @@ static void InternetCrackUrlW_test(void)
> memset(&comp, 0, sizeof comp);
> comp.dwStructSize = sizeof comp;
> comp.lpszHostName = host;
> - comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
> + comp.dwHostNameLength = ARRAY_SIZE(host);
> comp.lpszUrlPath = urlpart;
> - comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
> + comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
>
> r = InternetCrackUrlW(url, 0, 0, &comp );
> ok( r, "failed to crack url\n");
> @@ -739,11 +739,11 @@ static void InternetCrackUrlW_test(void)
> memset(&comp, 0, sizeof comp);
> comp.dwStructSize = sizeof comp;
> comp.lpszHostName = host;
> - comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
> + comp.dwHostNameLength = ARRAY_SIZE(host);
> comp.lpszUrlPath = urlpart;
> - comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
> + comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
> comp.lpszExtraInfo = NULL;
> - comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
> + comp.dwExtraInfoLength = ARRAY_SIZE(extra);
>
> r = InternetCrackUrlW(url, 0, 0, &comp );
> ok( r, "failed to crack url\n");
> @@ -763,17 +763,17 @@ static void InternetCrackUrlW_test(void)
> memset(&comp, 0, sizeof(comp));
> comp.dwStructSize = sizeof(comp);
> comp.lpszScheme = scheme;
> - comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
> + comp.dwSchemeLength = ARRAY_SIZE(scheme);
> comp.lpszHostName = host;
> - comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
> + comp.dwHostNameLength = ARRAY_SIZE(host);
> comp.lpszUserName = user;
> - comp.dwUserNameLength = sizeof(user)/sizeof(user[0]);
> + comp.dwUserNameLength = ARRAY_SIZE(user);
> comp.lpszPassword = pwd;
> - comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]);
> + comp.dwPasswordLength = ARRAY_SIZE(pwd);
> comp.lpszUrlPath = urlpart;
> - comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
> + comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
> comp.lpszExtraInfo = extra;
> - comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
> + comp.dwExtraInfoLength = ARRAY_SIZE(extra);
>
> r = InternetCrackUrlW(url2, 0, 0, &comp);
> ok(!r, "InternetCrackUrl should have failed\n");
> @@ -791,17 +791,17 @@ static void InternetCrackUrlW_test(void)
> memset(&comp, 0, sizeof comp);
> comp.dwStructSize = sizeof comp;
> comp.lpszScheme = scheme;
> - comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
> + comp.dwSchemeLength = ARRAY_SIZE(scheme);
> comp.lpszHostName = host;
> - comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
> + comp.dwHostNameLength = ARRAY_SIZE(host);
> comp.lpszUserName = user;
> - comp.dwUserNameLength = sizeof(user)/sizeof(user[0]);
> + comp.dwUserNameLength = ARRAY_SIZE(user);
> comp.lpszPassword = pwd;
> - comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]);
> + comp.dwPasswordLength = ARRAY_SIZE(pwd);
> comp.lpszUrlPath = urlpart;
> - comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
> + comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
> comp.lpszExtraInfo = extra;
> - comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
> + comp.dwExtraInfoLength = ARRAY_SIZE(extra);
> r = InternetCrackUrlW(url3, 0, 0, &comp );
> ok( r, "InternetCrackUrlW failed unexpectedly\n");
> ok( host[0] == 'x', "host should be x.org\n");
> @@ -812,9 +812,9 @@ static void InternetCrackUrlW_test(void)
> memset(&comp, 0, sizeof(comp));
> comp.dwStructSize = sizeof(comp);
> comp.lpszHostName = host;
> - comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
> + comp.dwHostNameLength = ARRAY_SIZE(host);
> comp.lpszUrlPath = urlpart;
> - comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
> + comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
> r = InternetCrackUrlW(url3, 0, ICU_DECODE, &comp);
> todo_wine ok(r, "InternetCrackUrlW failed unexpectedly\n");
> todo_wine ok(!strcmp_wa(host, "x.org"), "host is %s, should be x.org\n", wine_dbgstr_w(host));
> @@ -1224,7 +1224,7 @@ START_TEST(url)
> return;
> }
>
> - for(i=0; i < sizeof(crack_url_tests)/sizeof(*crack_url_tests); i++)
> + for(i = 0; i < ARRAY_SIZE(crack_url_tests); i++)
> test_crack_url(crack_url_tests+i);
>
> test_long_url();
> diff --git a/dlls/wininet/tests/urlcache.c b/dlls/wininet/tests/urlcache.c
> index 310054b6a7..3799500489 100644
> --- a/dlls/wininet/tests/urlcache.c
> +++ b/dlls/wininet/tests/urlcache.c
> @@ -891,13 +891,13 @@ static void test_urlcacheW(void)
>
> if(ie10_cache) {
> if(!MultiByteToWideChar(CP_ACP, 0, urls[6].encoded_url, -1,
> - urls[6].url, sizeof(urls[6].url)/sizeof(WCHAR)))
> + urls[6].url, ARRAY_SIZE(urls[6].url)))
> urls[6].url[0] = 0;
>
> trace("converted url in test 6: %s\n", wine_dbgstr_w(urls[6].url));
> }
>
> - for(i=0; i<sizeof(urls)/sizeof(*urls); i++) {
> + for(i=0; i<ARRAY_SIZE(urls); i++) {
> INTERNET_CACHE_ENTRY_INFOA *entry_infoA;
> INTERNET_CACHE_ENTRY_INFOW *entry_infoW;
> DWORD size;
>
June 22, 2018
[PATCH] wininet/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/wininet/tests/ftp.c | 2 +-
dlls/wininet/tests/http.c | 10 ++++-----
dlls/wininet/tests/internet.c | 16 ++++++-------
dlls/wininet/tests/url.c | 52 +++++++++++++++++++++----------------------
dlls/wininet/tests/urlcache.c | 4 ++--
5 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/dlls/wininet/tests/ftp.c b/dlls/wininet/tests/ftp.c
index d2118faded..6f50104f3b 100644
--- a/dlls/wininet/tests/ftp.c
+++ b/dlls/wininet/tests/ftp.c
@@ -735,7 +735,7 @@ static void test_command(HINTERNET hFtp, HINTERNET hConnect)
return;
}
- for (i = 0; i < sizeof(command_test) / sizeof(command_test[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(command_test); i++)
{
SetLastError(0xdeadbeef);
ret = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, command_test[i].cmd, 0, NULL);
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index 0524ddf3fd..ace8512399 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -172,7 +172,7 @@ static BOOL (WINAPI *pInternetGetSecurityInfoByURLA)(LPSTR,PCCERT_CHAIN_CONTEXT*
static int strcmp_wa(LPCWSTR strw, const char *stra)
{
WCHAR buf[512];
- MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
return lstrcmpW(strw, buf);
}
@@ -4204,7 +4204,7 @@ static void test_http_status(int port)
DWORD i, size;
BOOL res;
- for(i=0; i < sizeof(http_status_tests)/sizeof(*http_status_tests); i++) {
+ for(i = 0; i < ARRAY_SIZE(http_status_tests); i++) {
send_buffer = http_status_tests[i].response_text;
open_simple_request(&req, "localhost", port, NULL, "/send_from_buffer");
@@ -6543,14 +6543,14 @@ static const struct notification async_send_request_ex_chunked_test[] =
static const struct notification_data notification_data[] = {
{
async_send_request_ex_chunked_test,
- sizeof(async_send_request_ex_chunked_test)/sizeof(async_send_request_ex_chunked_test[0]),
+ ARRAY_SIZE(async_send_request_ex_chunked_test),
"GET",
"test.winehq.org",
"tests/data.php"
},
{
async_send_request_ex_test,
- sizeof(async_send_request_ex_test)/sizeof(async_send_request_ex_test[0]),
+ ARRAY_SIZE(async_send_request_ex_test),
"POST",
"test.winehq.org",
"tests/post.php",
@@ -6565,7 +6565,7 @@ static const struct notification_data notification_data[] = {
},
{
async_send_request_ex_resolve_failure_test,
- sizeof(async_send_request_ex_resolve_failure_test)/sizeof(async_send_request_ex_resolve_failure_test[0]),
+ ARRAY_SIZE(async_send_request_ex_resolve_failure_test),
"GET",
"brokenhost",
"index.html",
diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c
index 39c698f5db..7889e40ea8 100644
--- a/dlls/wininet/tests/internet.c
+++ b/dlls/wininet/tests/internet.c
@@ -629,7 +629,7 @@ static void test_cookie_url(void)
ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
"InternetGetCookeA failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
- len = sizeof(bufw)/sizeof(*bufw);
+ len = ARRAY_SIZE(bufw);
res = InternetGetCookieW(about_blankW, NULL, bufw, &len);
ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
"InternetGetCookeW failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
@@ -639,7 +639,7 @@ static void test_cookie_url(void)
ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
"InternetGetCookeExA failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
- len = sizeof(bufw)/sizeof(*bufw);
+ len = ARRAY_SIZE(bufw);
res = pInternetGetCookieExW(about_blankW, NULL, bufw, &len, 0, NULL);
ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
"InternetGetCookeExW failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
@@ -887,7 +887,7 @@ static void InternetTimeFromSystemTimeW_test(void)
/* test too small buffer size */
SetLastError(0xdeadbeef);
- ret = pInternetTimeFromSystemTimeW( &time, INTERNET_RFC1123_FORMAT, string, sizeof(string)/sizeof(string[0]) );
+ ret = pInternetTimeFromSystemTimeW( &time, INTERNET_RFC1123_FORMAT, string, ARRAY_SIZE(string));
error = GetLastError();
ok( !ret, "InternetTimeFromSystemTimeW should have returned FALSE\n" );
ok( error == ERROR_INSUFFICIENT_BUFFER,
@@ -1084,7 +1084,7 @@ static void test_PrivacyGetSetZonePreferenceW(void)
trace("template %u\n", old_template);
if(old_template == PRIVACY_TEMPLATE_ADVANCED) {
- pref_size = sizeof(pref)/sizeof(WCHAR);
+ pref_size = ARRAY_SIZE(pref);
ret = pPrivacyGetZonePreferenceW(zone, type, &old_template, pref, &pref_size);
ok(ret == 0, "expected ret == 0, got %u\n", ret);
}
@@ -1721,7 +1721,7 @@ static void test_InternetGetConnectedStateExW(void)
flags = 0;
buffer[0] = 0;
- res = pInternetGetConnectedStateExW(&flags, buffer, sizeof(buffer) / sizeof(buffer[0]), 0);
+ res = pInternetGetConnectedStateExW(&flags, buffer, ARRAY_SIZE(buffer), 0);
trace("Internet Connection: Flags 0x%02x - Name '%s'\n", flags, wine_dbgstr_w(buffer));
todo_wine
ok (flags & INTERNET_RAS_INSTALLED, "Missing RAS flag\n");
@@ -1755,21 +1755,21 @@ todo_wine
ok(!buffer[0], "Buffer must not change, got %02X\n", buffer[0]);
buffer[0] = 0;
- res = pInternetGetConnectedStateExW(NULL, buffer, sizeof(buffer) / sizeof(buffer[0]), 0);
+ res = pInternetGetConnectedStateExW(NULL, buffer, ARRAY_SIZE(buffer), 0);
ok(res == TRUE, "Expected TRUE, got %d\n", res);
sz = lstrlenW(buffer);
ok(sz > 0, "Expected a connection name\n");
buffer[0] = 0;
flags = 0;
- res = pInternetGetConnectedStateExW(&flags, buffer, sizeof(buffer) / sizeof(buffer[0]), 0);
+ res = pInternetGetConnectedStateExW(&flags, buffer, ARRAY_SIZE(buffer), 0);
ok(res == TRUE, "Expected TRUE, got %d\n", res);
ok(flags, "Expected at least one flag set\n");
sz = lstrlenW(buffer);
ok(sz > 0, "Expected a connection name\n");
flags = 0;
- res = pInternetGetConnectedStateExW(&flags, NULL, sizeof(buffer) / sizeof(buffer[0]), 0);
+ res = pInternetGetConnectedStateExW(&flags, NULL, ARRAY_SIZE(buffer), 0);
ok(res == TRUE, "Expected TRUE, got %d\n", res);
ok(flags, "Expected at least one flag set\n");
diff --git a/dlls/wininet/tests/url.c b/dlls/wininet/tests/url.c
index 0af58358eb..18c77b6647 100644
--- a/dlls/wininet/tests/url.c
+++ b/dlls/wininet/tests/url.c
@@ -672,17 +672,17 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof comp);
comp.dwStructSize = sizeof(comp);
comp.lpszScheme = scheme;
- comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
+ comp.dwSchemeLength = ARRAY_SIZE(scheme);
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUserName = user;
- comp.dwUserNameLength = sizeof(user)/sizeof(user[0]);
+ comp.dwUserNameLength = ARRAY_SIZE(user);
comp.lpszPassword = pwd;
- comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]);
+ comp.dwPasswordLength = ARRAY_SIZE(pwd);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
comp.lpszExtraInfo = extra;
- comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
+ comp.dwExtraInfoLength = ARRAY_SIZE(extra);
SetLastError(0xdeadbeef);
r = InternetCrackUrlW(NULL, 0, 0, &comp );
@@ -721,9 +721,9 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof comp);
comp.dwStructSize = sizeof comp;
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
r = InternetCrackUrlW(url, 0, 0, &comp );
ok( r, "failed to crack url\n");
@@ -739,11 +739,11 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof comp);
comp.dwStructSize = sizeof comp;
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
comp.lpszExtraInfo = NULL;
- comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
+ comp.dwExtraInfoLength = ARRAY_SIZE(extra);
r = InternetCrackUrlW(url, 0, 0, &comp );
ok( r, "failed to crack url\n");
@@ -763,17 +763,17 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof(comp));
comp.dwStructSize = sizeof(comp);
comp.lpszScheme = scheme;
- comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
+ comp.dwSchemeLength = ARRAY_SIZE(scheme);
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUserName = user;
- comp.dwUserNameLength = sizeof(user)/sizeof(user[0]);
+ comp.dwUserNameLength = ARRAY_SIZE(user);
comp.lpszPassword = pwd;
- comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]);
+ comp.dwPasswordLength = ARRAY_SIZE(pwd);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
comp.lpszExtraInfo = extra;
- comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
+ comp.dwExtraInfoLength = ARRAY_SIZE(extra);
r = InternetCrackUrlW(url2, 0, 0, &comp);
ok(!r, "InternetCrackUrl should have failed\n");
@@ -791,17 +791,17 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof comp);
comp.dwStructSize = sizeof comp;
comp.lpszScheme = scheme;
- comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
+ comp.dwSchemeLength = ARRAY_SIZE(scheme);
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUserName = user;
- comp.dwUserNameLength = sizeof(user)/sizeof(user[0]);
+ comp.dwUserNameLength = ARRAY_SIZE(user);
comp.lpszPassword = pwd;
- comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]);
+ comp.dwPasswordLength = ARRAY_SIZE(pwd);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
comp.lpszExtraInfo = extra;
- comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
+ comp.dwExtraInfoLength = ARRAY_SIZE(extra);
r = InternetCrackUrlW(url3, 0, 0, &comp );
ok( r, "InternetCrackUrlW failed unexpectedly\n");
ok( host[0] == 'x', "host should be x.org\n");
@@ -812,9 +812,9 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof(comp));
comp.dwStructSize = sizeof(comp);
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
r = InternetCrackUrlW(url3, 0, ICU_DECODE, &comp);
todo_wine ok(r, "InternetCrackUrlW failed unexpectedly\n");
todo_wine ok(!strcmp_wa(host, "x.org"), "host is %s, should be x.org\n", wine_dbgstr_w(host));
@@ -1224,7 +1224,7 @@ START_TEST(url)
return;
}
- for(i=0; i < sizeof(crack_url_tests)/sizeof(*crack_url_tests); i++)
+ for(i = 0; i < ARRAY_SIZE(crack_url_tests); i++)
test_crack_url(crack_url_tests+i);
test_long_url();
diff --git a/dlls/wininet/tests/urlcache.c b/dlls/wininet/tests/urlcache.c
index 310054b6a7..3799500489 100644
--- a/dlls/wininet/tests/urlcache.c
+++ b/dlls/wininet/tests/urlcache.c
@@ -891,13 +891,13 @@ static void test_urlcacheW(void)
if(ie10_cache) {
if(!MultiByteToWideChar(CP_ACP, 0, urls[6].encoded_url, -1,
- urls[6].url, sizeof(urls[6].url)/sizeof(WCHAR)))
+ urls[6].url, ARRAY_SIZE(urls[6].url)))
urls[6].url[0] = 0;
trace("converted url in test 6: %s\n", wine_dbgstr_w(urls[6].url));
}
- for(i=0; i<sizeof(urls)/sizeof(*urls); i++) {
+ for(i=0; i<ARRAY_SIZE(urls); i++) {
INTERNET_CACHE_ENTRY_INFOA *entry_infoA;
INTERNET_CACHE_ENTRY_INFOW *entry_infoW;
DWORD size;
--
2.14.4
June 22, 2018
Re: [PATCH] fonts: Add clock images to Wingdings font.
by Alexandre Julliard
Dmitry Timoshkov <dmitry(a)baikal.ru> writes:
> Alexandre Julliard <julliard(a)winehq.org> wrote:
>
>> > Glyphs were copied from the Android Emoji font.
>>
>> As far as I can tell, this Android font is under the SIL Open Font
>> License, which is not LGPL-compatible.
>
> I had an impression that this font is part of the Android codebase
> which is under a BSD-like license.
>
> Perhaps you have a suggestion for the font with a compatible license?
I haven't looked if there are compatible fonts that include the needed
glyphs. The free font license situation is sadly almost as bad as the
free software one...
--
Alexandre Julliard
julliard(a)winehq.org
June 22, 2018
[PATCH] psapi/tests: Add todo_wine to a failing test.
by Zebediah Figura
This test was based on an implementation of K32EnumProcessModules() which was later rewritten.
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
dlls/psapi/tests/psapi_main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
index 0ff212c..ec74716 100644
--- a/dlls/psapi/tests/psapi_main.c
+++ b/dlls/psapi/tests/psapi_main.c
@@ -229,6 +229,7 @@ todo_wine
SetLastError(0xdeadbeef);
ret = pEnumProcessModules(pi.hProcess, &hMod, sizeof(HMODULE), &cbNeeded);
ok(!ret, "got %d\n", ret);
+todo_wine
ok(GetLastError() == ERROR_PARTIAL_COPY, "got error %u\n", GetLastError());
TerminateProcess(pi.hProcess, 0);
--
2.7.4
June 22, 2018
[PATCH] testbot: Avoid scalar(%hash) for compatibility with Perl 5.20.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
This is probably needed on the official TestBot!
I'm surprised we did not have the Engine or a script die already.
testbot/lib/WineTestBot/PatchUtils.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index f83df6087..b6ea54bcb 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -298,7 +298,7 @@ sub GetPatchImpact($;$$)
}
}
- $TestInfo->{UnitCount} = scalar(%{$TestInfo->{Units}});
+ $TestInfo->{UnitCount} = scalar(keys %{$TestInfo->{Units}});
if ($TestInfo->{UnitCount})
{
$Impacts->{ModuleCount}++;
--
2.17.1
June 22, 2018
[PATCH] testbot/WineRunTask: Show the Wine report filename in error messages.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 3f5a3ee8d..37c63b4b5 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -789,12 +789,12 @@ if ($TA->GetFile($RptFileName, "$TaskDir/$RptFileName"))
{
$NewStatus = 'boterror';
Error "Unable to open '$RptFileName' for reading: $!\n";
- LogTaskError("Unable to open the log file for reading: $!\n");
+ LogTaskError("Unable to open '$RptFileName' for reading: $!\n");
}
}
elsif (!defined $TAError)
{
- $TAError = "An error occurred while retrieving the test report: ". $TA->GetLastError();
+ $TAError = "An error occurred while retrieving $RptFileName: ". $TA->GetLastError();
}
$TA->Disconnect();
--
2.17.1
June 22, 2018
[PATCH 3/3] crypt32: Add oids for sha256ECDSA and sha384ECDSA.
by Nikolay Sivov
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/oid.c | 15 +++++++++++++++
dlls/crypt32/tests/oid.c | 2 +-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/crypt32/oid.c b/dlls/crypt32/oid.c
index 61b2cbc88e..c9b0b412cf 100644
--- a/dlls/crypt32/oid.c
+++ b/dlls/crypt32/oid.c
@@ -25,6 +25,7 @@
#define NONAMELESSUNION
#include "windef.h"
#include "winbase.h"
+#define CRYPT_OID_INFO_HAS_EXTRA_FIELDS
#include "wincrypt.h"
#include "winreg.h"
#include "winuser.h"
@@ -1080,6 +1081,8 @@ static const WCHAR sha384RSA[] = { 's','h','a','3','8','4','R','S','A',0 };
static const WCHAR sha512RSA[] = { 's','h','a','5','1','2','R','S','A',0 };
static const WCHAR mosaicUpdatedSig[] =
{ 'm','o','s','a','i','c','U','p','d','a','t','e','d','S','i','g',0 };
+static const WCHAR sha256ECDSA[] = { 's','h','a','2','5','6','E','C','D','S','A',0 };
+static const WCHAR sha384ECDSA[] = { 's','h','a','3','8','4','E','C','D','S','A',0 };
static const WCHAR CN[] = { 'C','N',0 };
static const WCHAR L[] = { 'L',0 };
static const WCHAR O[] = { 'O',0 };
@@ -1126,12 +1129,14 @@ static const DWORD dssSign[2] = { CALG_DSS_SIGN,
static const DWORD mosaicSign[2] = { CALG_DSS_SIGN,
CRYPT_OID_INHIBIT_SIGNATURE_FORMAT_FLAG |
CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG };
+static const DWORD ecdsaSign[2] = { CALG_OID_INFO_PARAMETERS, CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG };
static const CRYPT_DATA_BLOB rsaSignBlob = { sizeof(rsaSign),
(LPBYTE)&rsaSign };
static const CRYPT_DATA_BLOB dssSignBlob = { sizeof(dssSign),
(LPBYTE)dssSign };
static const CRYPT_DATA_BLOB mosaicSignBlob = { sizeof(mosaicSign),
(LPBYTE)mosaicSign };
+static const CRYPT_DATA_BLOB ecdsaSignBlob = { sizeof(ecdsaSign), (BYTE *)ecdsaSign };
static const DWORD ia5String[] = { CERT_RDN_IA5_STRING, 0 };
static const DWORD numericString[] = { CERT_RDN_NUMERIC_STRING, 0 };
@@ -1153,6 +1158,8 @@ static const struct OIDInfoConstructor {
UINT Algid;
LPCWSTR pwszName;
const CRYPT_DATA_BLOB *blob;
+ const WCHAR *pwszCNGAlgid;
+ const WCHAR *pwszCNGExtraAlgid;
} oidInfoConstructors[] = {
{ 1, szOID_OIWSEC_sha1, CALG_SHA1, sha1, NULL },
{ 1, szOID_OIWSEC_sha1, CALG_SHA1, sha, NULL },
@@ -1208,6 +1215,10 @@ static const struct OIDInfoConstructor {
{ 4, szOID_OIWSEC_dsaSHA1, CALG_SHA1, dsaSHA1, &dssSignBlob },
{ 4, szOID_INFOSEC_mosaicUpdatedSig, CALG_SHA1, mosaicUpdatedSig,
&mosaicSignBlob },
+ { 4, szOID_ECDSA_SHA256, CALG_OID_INFO_CNG_ONLY, sha256ECDSA, &ecdsaSignBlob,
+ BCRYPT_SHA256_ALGORITHM, CRYPT_OID_INFO_ECC_PARAMETERS_ALGORITHM },
+ { 4, szOID_ECDSA_SHA384, CALG_OID_INFO_CNG_ONLY, sha384ECDSA, &ecdsaSignBlob,
+ BCRYPT_SHA384_ALGORITHM, CRYPT_OID_INFO_ECC_PARAMETERS_ALGORITHM },
{ 5, szOID_COMMON_NAME, 0, CN, NULL },
{ 5, szOID_LOCALITY_NAME, 0, L, NULL },
@@ -1422,6 +1433,8 @@ static void init_oid_info(void)
info->info.ExtraInfo.pbData =
oidInfoConstructors[i].blob->pbData;
}
+ info->info.pwszCNGAlgid = oidInfoConstructors[i].pwszCNGAlgid;
+ info->info.pwszCNGExtraAlgid = oidInfoConstructors[i].pwszCNGExtraAlgid;
list_add_tail(&oidInfo, &info->entry);
}
}
@@ -1454,6 +1467,8 @@ static void init_oid_info(void)
info->info.ExtraInfo.pbData =
oidInfoConstructors[i].blob->pbData;
}
+ info->info.pwszCNGAlgid = oidInfoConstructors[i].pwszCNGAlgid;
+ info->info.pwszCNGExtraAlgid = oidInfoConstructors[i].pwszCNGExtraAlgid;
list_add_tail(&oidInfo, &info->entry);
}
}
diff --git a/dlls/crypt32/tests/oid.c b/dlls/crypt32/tests/oid.c
index 00a6d5461e..05822478cb 100644
--- a/dlls/crypt32/tests/oid.c
+++ b/dlls/crypt32/tests/oid.c
@@ -611,7 +611,7 @@ static void test_findOIDInfo(void)
wine_dbgstr_w(CRYPT_OID_INFO_ECC_PARAMETERS_ALGORITHM), wine_dbgstr_w(info->pwszCNGExtraAlgid));
}
else
- todo_wine win_skip("Host does not support ECDSA_SHA256, skipping test\n");
+ win_skip("Host does not support ECDSA_SHA256, skipping test\n");
}
START_TEST(oid)
--
2.17.1
June 22, 2018
[PATCH 2/3] crypt32/tests: Add a basic test for ecdsa oid.
by Nikolay Sivov
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/tests/oid.c | 31 +++++++++++++++++++++++++++++++
include/wincrypt.h | 15 +++++++++++++++
2 files changed, 46 insertions(+)
diff --git a/dlls/crypt32/tests/oid.c b/dlls/crypt32/tests/oid.c
index 0e1442334f..00a6d5461e 100644
--- a/dlls/crypt32/tests/oid.c
+++ b/dlls/crypt32/tests/oid.c
@@ -22,6 +22,7 @@
#include <windef.h>
#include <winbase.h>
#include <winerror.h>
+#define CRYPT_OID_INFO_HAS_EXTRA_FIELDS
#include <wincrypt.h>
#include <winreg.h>
@@ -543,8 +544,10 @@ static void test_enumOIDInfo(void)
static void test_findOIDInfo(void)
{
+ static WCHAR sha256ECDSA[] = { 's','h','a','2','5','6','E','C','D','S','A',0 };
static WCHAR sha1[] = { 's','h','a','1',0 };
static CHAR oid_rsa_md5[] = szOID_RSA_MD5, oid_sha256[] = szOID_NIST_sha256;
+ static CHAR oid_ecdsa_sha256[] = szOID_ECDSA_SHA256;
ALG_ID alg = CALG_SHA1;
ALG_ID algs[2] = { CALG_MD5, CALG_RSA_SIGN };
const struct oid_info
@@ -581,6 +584,34 @@ static void test_findOIDInfo(void)
"Unexpected Algid %d, expected %d\n", U(*info).Algid, test->algid);
}
}
+
+ info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, oid_ecdsa_sha256, 0);
+ if (info)
+ {
+ DWORD *data;
+
+ ok(info->cbSize == sizeof(*info), "Unexpected structure size %d.\n", info->cbSize);
+ ok(!strcmp(info->pszOID, oid_ecdsa_sha256), "Expected %s, got %s\n", oid_ecdsa_sha256, info->pszOID);
+ ok(!lstrcmpW(info->pwszName, sha256ECDSA), "Expected %s, got %s\n",
+ wine_dbgstr_w(sha256ECDSA), wine_dbgstr_w(info->pwszName));
+ ok(info->dwGroupId == CRYPT_SIGN_ALG_OID_GROUP_ID,
+ "Expected CRYPT_SIGN_ALG_OID_GROUP_ID, got %u\n", info->dwGroupId);
+ ok(U(*info).Algid == CALG_OID_INFO_CNG_ONLY,
+ "Expected CALG_OID_INFO_CNG_ONLY, got %d\n", U(*info).Algid);
+
+ data = (DWORD *)info->ExtraInfo.pbData;
+ ok(info->ExtraInfo.cbData == 8, "Expected 8, got %d\n", info->ExtraInfo.cbData);
+ ok(data[0] == CALG_OID_INFO_PARAMETERS, "Expected CALG_OID_INFO_PARAMETERS, got %x\n", data[0]);
+ ok(data[1] == CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG,
+ "Expected CRYPT_OID_NO_NULL_ALGORITHM_PARA_FLAG, got %x\n", data[1]);
+
+ ok(!lstrcmpW(info->pwszCNGAlgid, BCRYPT_SHA256_ALGORITHM), "Expected %s, got %s\n",
+ wine_dbgstr_w(BCRYPT_SHA256_ALGORITHM), wine_dbgstr_w(info->pwszCNGAlgid));
+ ok(!lstrcmpW(info->pwszCNGExtraAlgid, CRYPT_OID_INFO_ECC_PARAMETERS_ALGORITHM), "Expected %s, got %s\n",
+ wine_dbgstr_w(CRYPT_OID_INFO_ECC_PARAMETERS_ALGORITHM), wine_dbgstr_w(info->pwszCNGExtraAlgid));
+ }
+ else
+ todo_wine win_skip("Host does not support ECDSA_SHA256, skipping test\n");
}
START_TEST(oid)
diff --git a/include/wincrypt.h b/include/wincrypt.h
index a7c24e7831..373acacd26 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -1244,6 +1244,17 @@ typedef BOOL (WINAPI *PFN_CRYPT_ENUM_OID_FUNC)(DWORD dwEncodingType,
#define CRYPT_MATCH_ANY_ENCODING_TYPE 0xffffffff
+#define CALG_OID_INFO_CNG_ONLY 0xffffffff
+#define CALG_OID_INFO_PARAMETERS 0xfffffffe
+
+#define CRYPT_OID_INFO_HASH_PARAMETERS_ALGORITHM (const WCHAR []){'C','r','y','p','t','O','I','D','I','n','f','o','H','a','s','h','P','a','r','a','m','e','t','e','r','s',0}
+#define CRYPT_OID_INFO_ECC_PARAMETERS_ALGORITHM (const WCHAR []){'C','r','y','p','t','O','I','D','I','n','f','o','E','C','C','P','a','r','a','m','e','t','e','r','s',0}
+#define CRYPT_OID_INFO_MGF1_PARAMETERS_ALGORITHM (const WCHAR []){'C','r','y','p','t','O','I','D','I','n','f','o','M','g','f','1','P','a','r','a','m','e','t','e','r','s',0}
+#define CRYPT_OID_INFO_NO_SIGN_ALGORITHM (const WCHAR []){'C','r','y','p','t','O','I','D','I','n','f','o','N','o','S','i','g','n',0}
+#define CRYPT_OID_INFO_OAEP_PARAMETERS_ALGORITHM (const WCHAR []){'C','r','y','p','t','O','I','D','I','n','f','o','O','A','E','P','P','a','r','a','m','e','t','e','r','s',0}
+#define CRYPT_OID_INFO_ECC_WRAP_PARAMETERS_ALGORITHM (const WCHAR []){'C','r','y','p','t','O','I','D','I','n','f','o','E','C','C','W','r','a','p','P','a','r','a','m','e','t','e','r','s',0}
+#define CRYPT_OID_INFO_NO_PARAMETERS_ALGORITHM (const WCHAR []){'C','r','y','p','t','O','I','D','I','n','f','o','N','o','P','a','r','a','m','e','t','e','r','s',0}
+
typedef struct _CRYPT_OID_INFO {
DWORD cbSize;
LPCSTR pszOID;
@@ -1255,6 +1266,10 @@ typedef struct _CRYPT_OID_INFO {
DWORD dwLength;
} DUMMYUNIONNAME;
CRYPT_DATA_BLOB ExtraInfo;
+#ifdef CRYPT_OID_INFO_HAS_EXTRA_FIELDS
+ LPCWSTR pwszCNGAlgid;
+ LPCWSTR pwszCNGExtraAlgid;
+#endif
} CRYPT_OID_INFO, *PCRYPT_OID_INFO;
typedef const CRYPT_OID_INFO CCRYPT_OID_INFO, *PCCRYPT_OID_INFO;
--
2.17.1
June 22, 2018
[PATCH 1/3] crypt32/tests: Compact existing OID tests
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/tests/oid.c | 73 +++++++++++++++-------------------------
1 file changed, 27 insertions(+), 46 deletions(-)
diff --git a/dlls/crypt32/tests/oid.c b/dlls/crypt32/tests/oid.c
index 8fc67b3353..0e1442334f 100644
--- a/dlls/crypt32/tests/oid.c
+++ b/dlls/crypt32/tests/oid.c
@@ -547,58 +547,39 @@ static void test_findOIDInfo(void)
static CHAR oid_rsa_md5[] = szOID_RSA_MD5, oid_sha256[] = szOID_NIST_sha256;
ALG_ID alg = CALG_SHA1;
ALG_ID algs[2] = { CALG_MD5, CALG_RSA_SIGN };
+ const struct oid_info
+ {
+ DWORD key_type;
+ void *key;
+ const char *oid;
+ ALG_ID algid;
+ ALG_ID broken_algid;
+ } oid_test_info [] =
+ {
+ { CRYPT_OID_INFO_OID_KEY, oid_rsa_md5, szOID_RSA_MD5, CALG_MD5 },
+ { CRYPT_OID_INFO_NAME_KEY, sha1, szOID_OIWSEC_sha1, CALG_SHA1 },
+ { CRYPT_OID_INFO_ALGID_KEY, &alg, szOID_OIWSEC_sha1, CALG_SHA1 },
+ { CRYPT_OID_INFO_SIGN_KEY, algs, szOID_RSA_MD5RSA, CALG_MD5 },
+ { CRYPT_OID_INFO_OID_KEY, oid_sha256, szOID_NIST_sha256, CALG_SHA_256, -1 },
+ };
PCCRYPT_OID_INFO info;
-
- static const WCHAR sha256W[] = {'s','h','a','2','5','6',0};
+ int i;
info = CryptFindOIDInfo(0, NULL, 0);
ok(info == NULL, "Expected NULL\n");
- info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, oid_rsa_md5, 0);
- ok(info != NULL, "Expected to find szOID_RSA_MD5\n");
- if (info)
- {
- ok(!strcmp(info->pszOID, szOID_RSA_MD5), "Expected %s, got %s\n",
- szOID_RSA_MD5, info->pszOID);
- ok(U(*info).Algid == CALG_MD5, "Expected CALG_MD5, got %d\n",
- U(*info).Algid);
- }
- info = CryptFindOIDInfo(CRYPT_OID_INFO_NAME_KEY, sha1, 0);
- ok(info != NULL, "Expected to find sha1\n");
- if (info)
- {
- ok(!strcmp(info->pszOID, szOID_OIWSEC_sha1), "Expected %s, got %s\n",
- szOID_OIWSEC_sha1, info->pszOID);
- ok(U(*info).Algid == CALG_SHA1, "Expected CALG_SHA1, got %d\n",
- U(*info).Algid);
- }
- info = CryptFindOIDInfo(CRYPT_OID_INFO_ALGID_KEY, &alg, 0);
- ok(info != NULL, "Expected to find sha1\n");
- if (info)
- {
- ok(!strcmp(info->pszOID, szOID_OIWSEC_sha1), "Expected %s, got %s\n",
- szOID_OIWSEC_sha1, info->pszOID);
- ok(U(*info).Algid == CALG_SHA1, "Expected CALG_SHA1, got %d\n",
- U(*info).Algid);
- }
- info = CryptFindOIDInfo(CRYPT_OID_INFO_SIGN_KEY, algs, 0);
- ok(info != NULL, "Expected to find md5RSA\n");
- if (info)
- {
- ok(!strcmp(info->pszOID, szOID_RSA_MD5RSA), "Expected %s, got %s\n",
- szOID_RSA_MD5RSA, info->pszOID);
- ok(U(*info).Algid == CALG_MD5, "Expected CALG_MD5, got %d\n",
- U(*info).Algid);
- }
- info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, oid_sha256, 0);
- ok(info != NULL, "Expected to find szOID_RSA_MD5\n");
- if (info)
+ for (i = 0; i < ARRAY_SIZE(oid_test_info); i++)
{
- ok(!strcmp(info->pszOID, szOID_NIST_sha256), "Expected %s, got %s\n",
- szOID_NIST_sha256, info->pszOID);
- ok(!lstrcmpW(info->pwszName, sha256W), "pwszName = %s\n", wine_dbgstr_w(info->pwszName));
- ok(U(*info).Algid == CALG_SHA_256 || U(*info).Algid == -1,
- "Expected CALG_MD5 or -1, got %d\n", U(*info).Algid);
+ const struct oid_info *test = &oid_test_info[i];
+
+ info = CryptFindOIDInfo(test->key_type, test->key, 0);
+ ok(info != NULL, "Failed to find %s.\n", test->oid);
+ if (info)
+ {
+ ok(!strcmp(info->pszOID, test->oid), "Unexpected OID %s, expected %s\n", info->pszOID, test->oid);
+ ok(U(*info).Algid == test->algid || broken(U(*info).Algid == test->broken_algid),
+ "Unexpected Algid %d, expected %d\n", U(*info).Algid, test->algid);
+ }
}
}
--
2.17.1
June 22, 2018
[PATCH 4/4] shell32/tests: Remove empty element from known_folders[].
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/shell32/tests/shellpath.c | 17 ++++++-----------
1 file changed, 6 insertions(+), 11 deletions(-)
diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c
index a5784237b162..bac64e57a7b9 100644
--- a/dlls/shell32/tests/shellpath.c
+++ b/dlls/shell32/tests/shellpath.c
@@ -1306,10 +1306,9 @@ static const struct knownFolderDef known_folders[] = {
NULL,
0,
0),
- { 0 }
};
#undef KNOWN_FOLDER
-BOOL known_folder_found[ARRAY_SIZE(known_folders)-1];
+BOOL known_folder_found[ARRAY_SIZE(known_folders)];
static void test_parameters(void)
{
@@ -1873,9 +1872,6 @@ if (0) { /* crashes */
{
const KNOWNFOLDERID *folder_id = known_folders[i].folderId;
- if (!folder_id)
- continue;
-
path = NULL;
hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_DEFAULT, NULL, &path);
if (FAILED(hr))
@@ -1968,19 +1964,20 @@ static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId)
{
HRESULT hr;
- const struct knownFolderDef *known_folder = &known_folders[0];
int csidl, expectedCsidl, ret;
KNOWNFOLDER_DEFINITION kfd;
IKnownFolder *folder;
WCHAR sName[1024];
- BOOL *current_known_folder_found = &known_folder_found[0];
BOOL found = FALSE;
+ unsigned int i;
- while(known_folder->folderId != NULL)
+ for (i = 0; i < ARRAY_SIZE(known_folders); ++i)
{
+ const struct knownFolderDef *known_folder = &known_folders[i];
+
if(IsEqualGUID(known_folder->folderId, folderId))
{
- *current_known_folder_found = TRUE;
+ known_folder_found[i] = TRUE;
found = TRUE;
/* verify CSIDL */
if(!(known_folder->csidl & NO_CSIDL))
@@ -2032,8 +2029,6 @@ static void check_known_folder(IKnownFolderManager *mgr, KNOWNFOLDERID *folderId
break;
}
- known_folder++;
- current_known_folder_found++;
}
if(!found)
--
2.16.4
June 22, 2018
[PATCH 3/4] shell32/tests: Add tests for SHGetKnownFolderPath() flags.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/shell32/tests/shellpath.c | 41 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 40 insertions(+), 1 deletion(-)
diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c
index 736cd3b8caa3..a5784237b162 100644
--- a/dlls/shell32/tests/shellpath.c
+++ b/dlls/shell32/tests/shellpath.c
@@ -1842,8 +1842,9 @@ static void test_NonExistentPath(void)
static void test_SHGetFolderPathEx(void)
{
+ WCHAR buffer[MAX_PATH], *path, *path2;
+ unsigned int i;
HRESULT hr;
- WCHAR buffer[MAX_PATH], *path;
DWORD len;
if (!pSHGetKnownFolderPath || !pSHGetFolderPathEx)
@@ -1868,6 +1869,44 @@ if (0) { /* crashes */
ok(path != NULL, "expected path != NULL\n");
CoTaskMemFree(path);
+ for (i = 0; i < ARRAY_SIZE(known_folders); ++i)
+ {
+ const KNOWNFOLDERID *folder_id = known_folders[i].folderId;
+
+ if (!folder_id)
+ continue;
+
+ path = NULL;
+ hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_DEFAULT, NULL, &path);
+ if (FAILED(hr))
+ continue;
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path != NULL, "expected path != NULL\n");
+
+ path2 = NULL;
+ hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_SIMPLE_IDLIST, NULL, &path2);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path != NULL, "expected path != NULL\n");
+ ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n", wine_dbgstr_w(path), wine_dbgstr_w(path2));
+ CoTaskMemFree(path2);
+
+ path2 = NULL;
+ hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_DONT_UNEXPAND, NULL, &path2);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path2 != NULL, "expected path != NULL\n");
+ ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n", wine_dbgstr_w(path), wine_dbgstr_w(path2));
+ CoTaskMemFree(path2);
+
+ path2 = NULL;
+ hr = pSHGetKnownFolderPath(folder_id, KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_UNEXPAND, NULL, &path2);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path2 != NULL, "expected path != NULL\n");
+ ok(!lstrcmpiW(path, path2), "expected equal paths: %s, %s\n", wine_dbgstr_w(path), wine_dbgstr_w(path2));
+ CoTaskMemFree(path2);
+
+ CoTaskMemFree(path);
+ }
+
path = NULL;
hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path);
ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
--
2.16.4
June 22, 2018
[PATCH 2/4] shell32/tests: Reorder known_folders table definition.
by Józef Kucia
To use it in other tests.
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/shell32/tests/shellpath.c | 1170 ++++++++++++++++++++--------------------
1 file changed, 585 insertions(+), 585 deletions(-)
diff --git a/dlls/shell32/tests/shellpath.c b/dlls/shell32/tests/shellpath.c
index 505da2778e26..736cd3b8caa3 100644
--- a/dlls/shell32/tests/shellpath.c
+++ b/dlls/shell32/tests/shellpath.c
@@ -304,591 +304,6 @@ static const char *getFolderName(int folder)
}
}
-static void test_parameters(void)
-{
- LPITEMIDLIST pidl = NULL;
- char path[MAX_PATH];
- HRESULT hr;
-
- if (pSHGetFolderLocation)
- {
- /* check a bogus CSIDL: */
- pidl = NULL;
- hr = pSHGetFolderLocation(NULL, 0xeeee, NULL, 0, &pidl);
- ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
- if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
-
- /* check a bogus user token: */
- pidl = NULL;
- hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, (HANDLE)2, 0, &pidl);
- ok(hr == E_FAIL || hr == E_HANDLE, "got 0x%08x, expected E_FAIL or E_HANDLE\n", hr);
- if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
-
- /* a NULL pidl pointer crashes, so don't test it */
- }
-
- if (pSHGetSpecialFolderLocation)
- {
- if (0)
- /* crashes */
- SHGetSpecialFolderLocation(NULL, 0, NULL);
-
- hr = pSHGetSpecialFolderLocation(NULL, 0xeeee, &pidl);
- ok(hr == E_INVALIDARG, "got returned 0x%08x\n", hr);
- }
-
- if (pSHGetFolderPathA)
- {
- /* expect 2's a bogus handle, especially since we didn't open it */
- hr = pSHGetFolderPathA(NULL, CSIDL_DESKTOP, (HANDLE)2, SHGFP_TYPE_DEFAULT, path);
- ok(hr == E_FAIL || hr == E_HANDLE || /* Vista and 2k8 */
- broken(hr == S_OK), /* W2k and Me */ "got 0x%08x, expected E_FAIL\n", hr);
-
- hr = pSHGetFolderPathA(NULL, 0xeeee, NULL, SHGFP_TYPE_DEFAULT, path);
- ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
- }
-
- if (pSHGetSpecialFolderPathA)
- {
- BOOL ret;
-
- if (0)
- pSHGetSpecialFolderPathA(NULL, NULL, CSIDL_BITBUCKET, FALSE);
-
- /* odd but true: calling with a NULL path still succeeds if it's a real
- * dir (on some windows platform). on winME it generates exception.
- */
- ret = pSHGetSpecialFolderPathA(NULL, path, CSIDL_PROGRAMS, FALSE);
- ok(ret, "got %d\n", ret);
-
- ret = pSHGetSpecialFolderPathA(NULL, path, 0xeeee, FALSE);
- ok(!ret, "got %d\n", ret);
- }
-}
-
-/* Returns the folder's PIDL type, or 0xff if one can't be found. */
-static BYTE testSHGetFolderLocation(int folder)
-{
- LPITEMIDLIST pidl;
- HRESULT hr;
- BYTE ret = 0xff;
-
- /* treat absence of function as success */
- if (!pSHGetFolderLocation) return TRUE;
-
- pidl = NULL;
- hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
- if (hr == S_OK)
- {
- if (pidl)
- {
- LPITEMIDLIST pidlLast = pILFindLastID(pidl);
-
- ok(pidlLast != NULL, "%s: ILFindLastID failed\n",
- getFolderName(folder));
- if (pidlLast)
- ret = pidlLast->mkid.abID[0];
- IMalloc_Free(pMalloc, pidl);
- }
- }
- return ret;
-}
-
-/* Returns the folder's PIDL type, or 0xff if one can't be found. */
-static BYTE testSHGetSpecialFolderLocation(int folder)
-{
- LPITEMIDLIST pidl;
- HRESULT hr;
- BYTE ret = 0xff;
-
- /* treat absence of function as success */
- if (!pSHGetSpecialFolderLocation) return TRUE;
-
- pidl = NULL;
- hr = pSHGetSpecialFolderLocation(NULL, folder, &pidl);
- if (hr == S_OK)
- {
- if (pidl)
- {
- LPITEMIDLIST pidlLast = pILFindLastID(pidl);
-
- ok(pidlLast != NULL,
- "%s: ILFindLastID failed\n", getFolderName(folder));
- if (pidlLast)
- ret = pidlLast->mkid.abID[0];
- IMalloc_Free(pMalloc, pidl);
- }
- }
- return ret;
-}
-
-static void test_SHGetFolderPath(BOOL optional, int folder)
-{
- char path[MAX_PATH];
- HRESULT hr;
-
- if (!pSHGetFolderPathA) return;
-
- hr = pSHGetFolderPathA(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path);
- ok(hr == S_OK || optional,
- "SHGetFolderPathA(NULL, %s, NULL, SHGFP_TYPE_CURRENT, path) failed: 0x%08x\n", getFolderName(folder), hr);
-}
-
-static void test_SHGetSpecialFolderPath(BOOL optional, int folder)
-{
- char path[MAX_PATH];
- BOOL ret;
-
- if (!pSHGetSpecialFolderPathA) return;
-
- ret = pSHGetSpecialFolderPathA(NULL, path, folder, FALSE);
- if (ret && winetest_interactive)
- printf("%s: %s\n", getFolderName(folder), path);
- ok(ret || optional,
- "SHGetSpecialFolderPathA(NULL, path, %s, FALSE) failed\n",
- getFolderName(folder));
-}
-
-static void test_ShellValues(const struct shellExpectedValues testEntries[],
- int numEntries, BOOL optional)
-{
- int i;
-
- for (i = 0; i < numEntries; i++)
- {
- BYTE type;
- int j;
- BOOL foundTypeMatch = FALSE;
-
- if (pSHGetFolderLocation)
- {
- type = testSHGetFolderLocation(testEntries[i].folder);
- for (j = 0; !foundTypeMatch && j < testEntries[i].numTypes; j++)
- if (testEntries[i].types[j] == type)
- foundTypeMatch = TRUE;
- ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
- "%s has unexpected type %d (0x%02x)\n",
- getFolderName(testEntries[i].folder), type, type);
- }
- type = testSHGetSpecialFolderLocation(testEntries[i].folder);
- for (j = 0, foundTypeMatch = FALSE; !foundTypeMatch &&
- j < testEntries[i].numTypes; j++)
- if (testEntries[i].types[j] == type)
- foundTypeMatch = TRUE;
- ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
- "%s has unexpected type %d (0x%02x)\n",
- getFolderName(testEntries[i].folder), type, type);
- switch (type)
- {
- case PT_FOLDER:
- case PT_DRIVE:
- case PT_DRIVE2:
- case PT_IESPECIAL2:
- test_SHGetFolderPath(optional, testEntries[i].folder);
- test_SHGetSpecialFolderPath(optional, testEntries[i].folder);
- break;
- }
- }
-}
-
-/* Attempts to verify that the folder path corresponding to the folder CSIDL
- * value has the same value as the environment variable with name envVar.
- * Doesn't mind if SHGetSpecialFolderPath fails for folder or if envVar isn't
- * set in this environment; different OS and shell version behave differently.
- * However, if both are present, fails if envVar's value is not the same
- * (byte-for-byte) as what SHGetSpecialFolderPath returns.
- */
-static void matchSpecialFolderPathToEnv(int folder, const char *envVar)
-{
- char path[MAX_PATH];
-
- if (!pSHGetSpecialFolderPathA) return;
-
- if (pSHGetSpecialFolderPathA(NULL, path, folder, FALSE))
- {
- char *envVal = getenv(envVar);
-
- ok(!envVal || !lstrcmpiA(envVal, path),
- "%%%s%% does not match SHGetSpecialFolderPath:\n"
- "%%%s%% is %s\nSHGetSpecialFolderPath returns %s\n",
- envVar, envVar, envVal, path);
- }
-}
-
-/* Attempts to match the GUID returned by SHGetFolderLocation for folder with
- * GUID. Assumes the type of the returned PIDL is in fact a GUID, but doesn't
- * fail if it isn't--that check should already have been done.
- * Fails if the returned PIDL is a GUID whose value does not match guid.
- */
-static void matchGUID(int folder, const GUID *guid, const GUID *guid_alt)
-{
- LPITEMIDLIST pidl;
- HRESULT hr;
-
- if (!pSHGetFolderLocation) return;
- if (!guid) return;
-
- pidl = NULL;
- hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
- if (hr == S_OK)
- {
- LPITEMIDLIST pidlLast = pILFindLastID(pidl);
-
- if (pidlLast && (pidlLast->mkid.abID[0] == PT_SHELLEXT ||
- pidlLast->mkid.abID[0] == PT_GUID))
- {
- GUID *shellGuid = (GUID *)(pidlLast->mkid.abID + 2);
-
- if (!guid_alt)
- ok(IsEqualIID(shellGuid, guid),
- "%s: got GUID %s, expected %s\n", getFolderName(folder),
- wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid));
- else
- ok(IsEqualIID(shellGuid, guid) ||
- IsEqualIID(shellGuid, guid_alt),
- "%s: got GUID %s, expected %s or %s\n", getFolderName(folder),
- wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid), wine_dbgstr_guid(guid_alt));
- }
- IMalloc_Free(pMalloc, pidl);
- }
-}
-
-/* Checks the PIDL type of all the known values. */
-static void test_PidlTypes(void)
-{
- /* Desktop */
- test_SHGetFolderPath(FALSE, CSIDL_DESKTOP);
- test_SHGetSpecialFolderPath(FALSE, CSIDL_DESKTOP);
-
- test_ShellValues(requiredShellValues, ARRAY_SIZE(requiredShellValues), FALSE);
- test_ShellValues(optionalShellValues, ARRAY_SIZE(optionalShellValues), TRUE);
-}
-
-/* FIXME: Should be in shobjidl.idl */
-DEFINE_GUID(CLSID_NetworkExplorerFolder, 0xF02C1A0D, 0xBE21, 0x4350, 0x88, 0xB0, 0x73, 0x67, 0xFC, 0x96, 0xEF, 0x3C);
-DEFINE_GUID(_CLSID_Documents, 0xA8CDFF1C, 0x4878, 0x43be, 0xB5, 0xFD, 0xF8, 0x09, 0x1C, 0x1C, 0x60, 0xD0);
-
-/* Verifies various shell virtual folders have the correct well-known GUIDs. */
-static void test_GUIDs(void)
-{
- matchGUID(CSIDL_BITBUCKET, &CLSID_RecycleBin, NULL);
- matchGUID(CSIDL_CONTROLS, &CLSID_ControlPanel, NULL);
- matchGUID(CSIDL_DRIVES, &CLSID_MyComputer, NULL);
- matchGUID(CSIDL_INTERNET, &CLSID_Internet, NULL);
- matchGUID(CSIDL_NETWORK, &CLSID_NetworkPlaces, &CLSID_NetworkExplorerFolder); /* Vista and higher */
- matchGUID(CSIDL_PERSONAL, &CLSID_MyDocuments, &_CLSID_Documents /* win8 */);
- matchGUID(CSIDL_COMMON_DOCUMENTS, &CLSID_CommonDocuments, NULL);
- matchGUID(CSIDL_PRINTERS, &CLSID_Printers, NULL);
-}
-
-/* Verifies various shell paths match the environment variables to which they
- * correspond.
- */
-static void test_EnvVars(void)
-{
- matchSpecialFolderPathToEnv(CSIDL_PROGRAM_FILES, "ProgramFiles");
- matchSpecialFolderPathToEnv(CSIDL_APPDATA, "APPDATA");
- matchSpecialFolderPathToEnv(CSIDL_PROFILE, "USERPROFILE");
- matchSpecialFolderPathToEnv(CSIDL_WINDOWS, "SystemRoot");
- matchSpecialFolderPathToEnv(CSIDL_WINDOWS, "windir");
- matchSpecialFolderPathToEnv(CSIDL_PROGRAM_FILES_COMMON, "CommonProgramFiles");
- /* this is only set on Wine, but can't hurt to verify it: */
- matchSpecialFolderPathToEnv(CSIDL_SYSTEM, "winsysdir");
-}
-
-/* Loosely based on PathRemoveBackslashA from dlls/shlwapi/path.c */
-static BOOL myPathIsRootA(LPCSTR lpszPath)
-{
- if (lpszPath && *lpszPath &&
- lpszPath[1] == ':' && lpszPath[2] == '\\' && lpszPath[3] == '\0')
- return TRUE; /* X:\ */
- return FALSE;
-}
-static LPSTR myPathRemoveBackslashA( LPSTR lpszPath )
-{
- LPSTR szTemp = NULL;
-
- if(lpszPath)
- {
- szTemp = CharPrevA(lpszPath, lpszPath + strlen(lpszPath));
- if (!myPathIsRootA(lpszPath) && *szTemp == '\\')
- *szTemp = '\0';
- }
- return szTemp;
-}
-
-/* Verifies the shell path for CSIDL_WINDOWS matches the return from
- * GetWindowsDirectory. If SHGetSpecialFolderPath fails, no harm, no foul--not
- * every shell32 version supports CSIDL_WINDOWS.
- */
-static void testWinDir(void)
-{
- char windowsShellPath[MAX_PATH], windowsDir[MAX_PATH] = { 0 };
-
- if (!pSHGetSpecialFolderPathA) return;
-
- if (pSHGetSpecialFolderPathA(NULL, windowsShellPath, CSIDL_WINDOWS, FALSE))
- {
- myPathRemoveBackslashA(windowsShellPath);
- GetWindowsDirectoryA(windowsDir, sizeof(windowsDir));
- myPathRemoveBackslashA(windowsDir);
- ok(!lstrcmpiA(windowsDir, windowsShellPath),
- "GetWindowsDirectory returns %s SHGetSpecialFolderPath returns %s\n",
- windowsDir, windowsShellPath);
- }
-}
-
-/* Verifies the shell path for CSIDL_SYSTEM matches the return from
- * GetSystemDirectory. If SHGetSpecialFolderPath fails, no harm,
- * no foul--not every shell32 version supports CSIDL_SYSTEM.
- */
-static void testSystemDir(void)
-{
- char systemShellPath[MAX_PATH], systemDir[MAX_PATH], systemDirx86[MAX_PATH];
-
- if (!pSHGetSpecialFolderPathA) return;
-
- GetSystemDirectoryA(systemDir, sizeof(systemDir));
- myPathRemoveBackslashA(systemDir);
- if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEM, FALSE))
- {
- myPathRemoveBackslashA(systemShellPath);
- ok(!lstrcmpiA(systemDir, systemShellPath),
- "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
- systemDir, systemShellPath);
- }
-
- if (!pGetSystemWow64DirectoryA || !pGetSystemWow64DirectoryA(systemDirx86, sizeof(systemDirx86)))
- GetSystemDirectoryA(systemDirx86, sizeof(systemDirx86));
- myPathRemoveBackslashA(systemDirx86);
- if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEMX86, FALSE))
- {
- myPathRemoveBackslashA(systemShellPath);
- ok(!lstrcmpiA(systemDirx86, systemShellPath) || broken(!lstrcmpiA(systemDir, systemShellPath)),
- "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
- systemDir, systemShellPath);
- }
-}
-
-/* Globals used by subprocesses */
-static int myARGC;
-static char **myARGV;
-static char base[MAX_PATH];
-static char selfname[MAX_PATH];
-
-static BOOL init(void)
-{
- myARGC = winetest_get_mainargs(&myARGV);
- if (!GetCurrentDirectoryA(sizeof(base), base)) return FALSE;
- strcpy(selfname, myARGV[0]);
- return TRUE;
-}
-
-static void doChild(const char *arg)
-{
- char path[MAX_PATH];
- HRESULT hr;
-
- if (arg[0] == '1')
- {
- LPITEMIDLIST pidl;
- char *p;
-
- /* test what happens when CSIDL_FAVORITES is set to a nonexistent directory */
-
- /* test some failure cases first: */
- hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path);
- ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
- "SHGetFolderPath returned 0x%08x, expected 0x80070002\n", hr);
-
- pidl = NULL;
- hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, NULL, 0, &pidl);
- ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
- "SHGetFolderLocation returned 0x%08x\n", hr);
- if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
-
- ok(!pSHGetSpecialFolderPathA(NULL, path, CSIDL_FAVORITES, FALSE),
- "SHGetSpecialFolderPath succeeded, expected failure\n");
-
- pidl = NULL;
- hr = pSHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
- ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
- "SHGetFolderLocation returned 0x%08x\n", hr);
-
- if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
-
- /* now test success: */
- hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
- SHGFP_TYPE_CURRENT, path);
- ok (hr == S_OK, "got 0x%08x\n", hr);
- if (hr == S_OK)
- {
- BOOL ret;
-
- trace("CSIDL_FAVORITES was changed to %s\n", path);
- ret = CreateDirectoryA(path, NULL);
- ok(!ret, "expected failure with ERROR_ALREADY_EXISTS\n");
- if (!ret)
- ok(GetLastError() == ERROR_ALREADY_EXISTS,
- "got %d, expected ERROR_ALREADY_EXISTS\n", GetLastError());
-
- p = path + strlen(path);
- strcpy(p, "\\desktop.ini");
- DeleteFileA(path);
- *p = 0;
- SetFileAttributesA( path, FILE_ATTRIBUTE_NORMAL );
- ret = RemoveDirectoryA(path);
- ok( ret, "failed to remove %s error %u\n", path, GetLastError() );
- }
- }
- else if (arg[0] == '2')
- {
- /* make sure SHGetFolderPath still succeeds when the
- original value of CSIDL_FAVORITES is restored. */
- hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
- SHGFP_TYPE_CURRENT, path);
- ok(hr == S_OK, "SHGetFolderPath failed: 0x%08x\n", hr);
- }
-}
-
-/* Tests the return values from the various shell functions both with and
- * without the use of the CSIDL_FLAG_CREATE flag. This flag only appeared in
- * version 5 of the shell, so don't test unless it's at least version 5.
- * The test reads a value from the registry, modifies it, calls
- * SHGetFolderPath once with the CSIDL_FLAG_CREATE flag, and immediately
- * afterward without it. Then it restores the registry and deletes the folder
- * that was created.
- * One oddity with respect to restoration: shell32 caches somehow, so it needs
- * to be reloaded in order to see the correct (restored) value.
- * Some APIs unrelated to the ones under test may fail, but I expect they're
- * covered by other unit tests; I just print out something about failure to
- * help trace what's going on.
- */
-static void test_NonExistentPath(void)
-{
- static const char userShellFolders[] =
- "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
- char originalPath[MAX_PATH], modifiedPath[MAX_PATH];
- HKEY key;
-
- if (!pSHGetFolderPathA) return;
- if (!pSHGetFolderLocation) return;
- if (!pSHGetSpecialFolderPathA) return;
- if (!pSHGetSpecialFolderLocation) return;
- if (!pSHFileOperationA) return;
- if (shellVersion.dwMajorVersion < 5) return;
-
- if (!RegOpenKeyExA(HKEY_CURRENT_USER, userShellFolders, 0, KEY_ALL_ACCESS,
- &key))
- {
- DWORD len, type;
-
- len = sizeof(originalPath);
- if (!RegQueryValueExA(key, "Favorites", NULL, &type,
- (LPBYTE)&originalPath, &len))
- {
- size_t len = strlen(originalPath);
-
- memcpy(modifiedPath, originalPath, len);
- modifiedPath[len++] = '2';
- modifiedPath[len++] = '\0';
- trace("Changing CSIDL_FAVORITES to %s\n", modifiedPath);
- if (!RegSetValueExA(key, "Favorites", 0, type,
- (LPBYTE)modifiedPath, len))
- {
- char buffer[MAX_PATH+20];
- STARTUPINFOA startup;
- PROCESS_INFORMATION info;
-
- sprintf(buffer, "%s tests/shellpath.c 1", selfname);
- memset(&startup, 0, sizeof(startup));
- startup.cb = sizeof(startup);
- startup.dwFlags = STARTF_USESHOWWINDOW;
- startup.wShowWindow = SW_SHOWNORMAL;
- CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
- &startup, &info);
- winetest_wait_child_process( info.hProcess );
-
- /* restore original values: */
- trace("Restoring CSIDL_FAVORITES to %s\n", originalPath);
- RegSetValueExA(key, "Favorites", 0, type, (LPBYTE) originalPath,
- strlen(originalPath) + 1);
- RegFlushKey(key);
-
- sprintf(buffer, "%s tests/shellpath.c 2", selfname);
- memset(&startup, 0, sizeof(startup));
- startup.cb = sizeof(startup);
- startup.dwFlags = STARTF_USESHOWWINDOW;
- startup.wShowWindow = SW_SHOWNORMAL;
- CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
- &startup, &info);
- ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0,
- "child process termination\n");
- }
- }
- else skip("RegQueryValueExA(key, Favorites, ...) failed\n");
- if (key)
- RegCloseKey(key);
- }
- else skip("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n", userShellFolders);
-}
-
-static void test_SHGetFolderPathEx(void)
-{
- HRESULT hr;
- WCHAR buffer[MAX_PATH], *path;
- DWORD len;
-
- if (!pSHGetKnownFolderPath || !pSHGetFolderPathEx)
- {
- win_skip("SHGetKnownFolderPath or SHGetFolderPathEx not available\n");
- return;
- }
-
-if (0) { /* crashes */
- hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, NULL);
- ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
-}
- /* non-existent folder id */
- path = (void *)0xdeadbeef;
- hr = pSHGetKnownFolderPath(&IID_IOleObject, 0, NULL, &path);
- ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
- ok(path == NULL, "got %p\n", path);
-
- path = NULL;
- hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, KF_FLAG_DEFAULT_PATH, NULL, &path);
- ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
- ok(path != NULL, "expected path != NULL\n");
- CoTaskMemFree(path);
-
- path = NULL;
- hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path);
- ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
- ok(path != NULL, "expected path != NULL\n");
-
- hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, MAX_PATH);
- ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
- ok(!lstrcmpiW(path, buffer), "expected equal paths\n");
- len = lstrlenW(buffer);
- CoTaskMemFree(path);
-
- hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, 0);
- ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
-
-if (0) { /* crashes */
- hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, NULL, len + 1);
- ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
-
- hr = pSHGetFolderPathEx(NULL, 0, NULL, buffer, MAX_PATH);
- ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
-}
- hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len);
- ok(hr == E_NOT_SUFFICIENT_BUFFER, "expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hr);
-
- hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len + 1);
- ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
-}
-
/* Standard CSIDL values (and their flags) uses only two less-significant bytes */
#define NO_CSIDL 0x10000
#define WINE_ATTRIBUTES_OPTIONAL 0x20000
@@ -1896,6 +1311,591 @@ static const struct knownFolderDef known_folders[] = {
#undef KNOWN_FOLDER
BOOL known_folder_found[ARRAY_SIZE(known_folders)-1];
+static void test_parameters(void)
+{
+ LPITEMIDLIST pidl = NULL;
+ char path[MAX_PATH];
+ HRESULT hr;
+
+ if (pSHGetFolderLocation)
+ {
+ /* check a bogus CSIDL: */
+ pidl = NULL;
+ hr = pSHGetFolderLocation(NULL, 0xeeee, NULL, 0, &pidl);
+ ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
+ if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
+
+ /* check a bogus user token: */
+ pidl = NULL;
+ hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, (HANDLE)2, 0, &pidl);
+ ok(hr == E_FAIL || hr == E_HANDLE, "got 0x%08x, expected E_FAIL or E_HANDLE\n", hr);
+ if (hr == S_OK) IMalloc_Free(pMalloc, pidl);
+
+ /* a NULL pidl pointer crashes, so don't test it */
+ }
+
+ if (pSHGetSpecialFolderLocation)
+ {
+ if (0)
+ /* crashes */
+ SHGetSpecialFolderLocation(NULL, 0, NULL);
+
+ hr = pSHGetSpecialFolderLocation(NULL, 0xeeee, &pidl);
+ ok(hr == E_INVALIDARG, "got returned 0x%08x\n", hr);
+ }
+
+ if (pSHGetFolderPathA)
+ {
+ /* expect 2's a bogus handle, especially since we didn't open it */
+ hr = pSHGetFolderPathA(NULL, CSIDL_DESKTOP, (HANDLE)2, SHGFP_TYPE_DEFAULT, path);
+ ok(hr == E_FAIL || hr == E_HANDLE || /* Vista and 2k8 */
+ broken(hr == S_OK), /* W2k and Me */ "got 0x%08x, expected E_FAIL\n", hr);
+
+ hr = pSHGetFolderPathA(NULL, 0xeeee, NULL, SHGFP_TYPE_DEFAULT, path);
+ ok(hr == E_INVALIDARG, "got 0x%08x, expected E_INVALIDARG\n", hr);
+ }
+
+ if (pSHGetSpecialFolderPathA)
+ {
+ BOOL ret;
+
+ if (0)
+ pSHGetSpecialFolderPathA(NULL, NULL, CSIDL_BITBUCKET, FALSE);
+
+ /* odd but true: calling with a NULL path still succeeds if it's a real
+ * dir (on some windows platform). on winME it generates exception.
+ */
+ ret = pSHGetSpecialFolderPathA(NULL, path, CSIDL_PROGRAMS, FALSE);
+ ok(ret, "got %d\n", ret);
+
+ ret = pSHGetSpecialFolderPathA(NULL, path, 0xeeee, FALSE);
+ ok(!ret, "got %d\n", ret);
+ }
+}
+
+/* Returns the folder's PIDL type, or 0xff if one can't be found. */
+static BYTE testSHGetFolderLocation(int folder)
+{
+ LPITEMIDLIST pidl;
+ HRESULT hr;
+ BYTE ret = 0xff;
+
+ /* treat absence of function as success */
+ if (!pSHGetFolderLocation) return TRUE;
+
+ pidl = NULL;
+ hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
+ if (hr == S_OK)
+ {
+ if (pidl)
+ {
+ LPITEMIDLIST pidlLast = pILFindLastID(pidl);
+
+ ok(pidlLast != NULL, "%s: ILFindLastID failed\n",
+ getFolderName(folder));
+ if (pidlLast)
+ ret = pidlLast->mkid.abID[0];
+ IMalloc_Free(pMalloc, pidl);
+ }
+ }
+ return ret;
+}
+
+/* Returns the folder's PIDL type, or 0xff if one can't be found. */
+static BYTE testSHGetSpecialFolderLocation(int folder)
+{
+ LPITEMIDLIST pidl;
+ HRESULT hr;
+ BYTE ret = 0xff;
+
+ /* treat absence of function as success */
+ if (!pSHGetSpecialFolderLocation) return TRUE;
+
+ pidl = NULL;
+ hr = pSHGetSpecialFolderLocation(NULL, folder, &pidl);
+ if (hr == S_OK)
+ {
+ if (pidl)
+ {
+ LPITEMIDLIST pidlLast = pILFindLastID(pidl);
+
+ ok(pidlLast != NULL,
+ "%s: ILFindLastID failed\n", getFolderName(folder));
+ if (pidlLast)
+ ret = pidlLast->mkid.abID[0];
+ IMalloc_Free(pMalloc, pidl);
+ }
+ }
+ return ret;
+}
+
+static void test_SHGetFolderPath(BOOL optional, int folder)
+{
+ char path[MAX_PATH];
+ HRESULT hr;
+
+ if (!pSHGetFolderPathA) return;
+
+ hr = pSHGetFolderPathA(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path);
+ ok(hr == S_OK || optional,
+ "SHGetFolderPathA(NULL, %s, NULL, SHGFP_TYPE_CURRENT, path) failed: 0x%08x\n", getFolderName(folder), hr);
+}
+
+static void test_SHGetSpecialFolderPath(BOOL optional, int folder)
+{
+ char path[MAX_PATH];
+ BOOL ret;
+
+ if (!pSHGetSpecialFolderPathA) return;
+
+ ret = pSHGetSpecialFolderPathA(NULL, path, folder, FALSE);
+ if (ret && winetest_interactive)
+ printf("%s: %s\n", getFolderName(folder), path);
+ ok(ret || optional,
+ "SHGetSpecialFolderPathA(NULL, path, %s, FALSE) failed\n",
+ getFolderName(folder));
+}
+
+static void test_ShellValues(const struct shellExpectedValues testEntries[],
+ int numEntries, BOOL optional)
+{
+ int i;
+
+ for (i = 0; i < numEntries; i++)
+ {
+ BYTE type;
+ int j;
+ BOOL foundTypeMatch = FALSE;
+
+ if (pSHGetFolderLocation)
+ {
+ type = testSHGetFolderLocation(testEntries[i].folder);
+ for (j = 0; !foundTypeMatch && j < testEntries[i].numTypes; j++)
+ if (testEntries[i].types[j] == type)
+ foundTypeMatch = TRUE;
+ ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
+ "%s has unexpected type %d (0x%02x)\n",
+ getFolderName(testEntries[i].folder), type, type);
+ }
+ type = testSHGetSpecialFolderLocation(testEntries[i].folder);
+ for (j = 0, foundTypeMatch = FALSE; !foundTypeMatch &&
+ j < testEntries[i].numTypes; j++)
+ if (testEntries[i].types[j] == type)
+ foundTypeMatch = TRUE;
+ ok(foundTypeMatch || optional || broken(type == 0xff) /* Win9x */,
+ "%s has unexpected type %d (0x%02x)\n",
+ getFolderName(testEntries[i].folder), type, type);
+ switch (type)
+ {
+ case PT_FOLDER:
+ case PT_DRIVE:
+ case PT_DRIVE2:
+ case PT_IESPECIAL2:
+ test_SHGetFolderPath(optional, testEntries[i].folder);
+ test_SHGetSpecialFolderPath(optional, testEntries[i].folder);
+ break;
+ }
+ }
+}
+
+/* Attempts to verify that the folder path corresponding to the folder CSIDL
+ * value has the same value as the environment variable with name envVar.
+ * Doesn't mind if SHGetSpecialFolderPath fails for folder or if envVar isn't
+ * set in this environment; different OS and shell version behave differently.
+ * However, if both are present, fails if envVar's value is not the same
+ * (byte-for-byte) as what SHGetSpecialFolderPath returns.
+ */
+static void matchSpecialFolderPathToEnv(int folder, const char *envVar)
+{
+ char path[MAX_PATH];
+
+ if (!pSHGetSpecialFolderPathA) return;
+
+ if (pSHGetSpecialFolderPathA(NULL, path, folder, FALSE))
+ {
+ char *envVal = getenv(envVar);
+
+ ok(!envVal || !lstrcmpiA(envVal, path),
+ "%%%s%% does not match SHGetSpecialFolderPath:\n"
+ "%%%s%% is %s\nSHGetSpecialFolderPath returns %s\n",
+ envVar, envVar, envVal, path);
+ }
+}
+
+/* Attempts to match the GUID returned by SHGetFolderLocation for folder with
+ * GUID. Assumes the type of the returned PIDL is in fact a GUID, but doesn't
+ * fail if it isn't--that check should already have been done.
+ * Fails if the returned PIDL is a GUID whose value does not match guid.
+ */
+static void matchGUID(int folder, const GUID *guid, const GUID *guid_alt)
+{
+ LPITEMIDLIST pidl;
+ HRESULT hr;
+
+ if (!pSHGetFolderLocation) return;
+ if (!guid) return;
+
+ pidl = NULL;
+ hr = pSHGetFolderLocation(NULL, folder, NULL, 0, &pidl);
+ if (hr == S_OK)
+ {
+ LPITEMIDLIST pidlLast = pILFindLastID(pidl);
+
+ if (pidlLast && (pidlLast->mkid.abID[0] == PT_SHELLEXT ||
+ pidlLast->mkid.abID[0] == PT_GUID))
+ {
+ GUID *shellGuid = (GUID *)(pidlLast->mkid.abID + 2);
+
+ if (!guid_alt)
+ ok(IsEqualIID(shellGuid, guid),
+ "%s: got GUID %s, expected %s\n", getFolderName(folder),
+ wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid));
+ else
+ ok(IsEqualIID(shellGuid, guid) ||
+ IsEqualIID(shellGuid, guid_alt),
+ "%s: got GUID %s, expected %s or %s\n", getFolderName(folder),
+ wine_dbgstr_guid(shellGuid), wine_dbgstr_guid(guid), wine_dbgstr_guid(guid_alt));
+ }
+ IMalloc_Free(pMalloc, pidl);
+ }
+}
+
+/* Checks the PIDL type of all the known values. */
+static void test_PidlTypes(void)
+{
+ /* Desktop */
+ test_SHGetFolderPath(FALSE, CSIDL_DESKTOP);
+ test_SHGetSpecialFolderPath(FALSE, CSIDL_DESKTOP);
+
+ test_ShellValues(requiredShellValues, ARRAY_SIZE(requiredShellValues), FALSE);
+ test_ShellValues(optionalShellValues, ARRAY_SIZE(optionalShellValues), TRUE);
+}
+
+/* FIXME: Should be in shobjidl.idl */
+DEFINE_GUID(CLSID_NetworkExplorerFolder, 0xF02C1A0D, 0xBE21, 0x4350, 0x88, 0xB0, 0x73, 0x67, 0xFC, 0x96, 0xEF, 0x3C);
+DEFINE_GUID(_CLSID_Documents, 0xA8CDFF1C, 0x4878, 0x43be, 0xB5, 0xFD, 0xF8, 0x09, 0x1C, 0x1C, 0x60, 0xD0);
+
+/* Verifies various shell virtual folders have the correct well-known GUIDs. */
+static void test_GUIDs(void)
+{
+ matchGUID(CSIDL_BITBUCKET, &CLSID_RecycleBin, NULL);
+ matchGUID(CSIDL_CONTROLS, &CLSID_ControlPanel, NULL);
+ matchGUID(CSIDL_DRIVES, &CLSID_MyComputer, NULL);
+ matchGUID(CSIDL_INTERNET, &CLSID_Internet, NULL);
+ matchGUID(CSIDL_NETWORK, &CLSID_NetworkPlaces, &CLSID_NetworkExplorerFolder); /* Vista and higher */
+ matchGUID(CSIDL_PERSONAL, &CLSID_MyDocuments, &_CLSID_Documents /* win8 */);
+ matchGUID(CSIDL_COMMON_DOCUMENTS, &CLSID_CommonDocuments, NULL);
+ matchGUID(CSIDL_PRINTERS, &CLSID_Printers, NULL);
+}
+
+/* Verifies various shell paths match the environment variables to which they
+ * correspond.
+ */
+static void test_EnvVars(void)
+{
+ matchSpecialFolderPathToEnv(CSIDL_PROGRAM_FILES, "ProgramFiles");
+ matchSpecialFolderPathToEnv(CSIDL_APPDATA, "APPDATA");
+ matchSpecialFolderPathToEnv(CSIDL_PROFILE, "USERPROFILE");
+ matchSpecialFolderPathToEnv(CSIDL_WINDOWS, "SystemRoot");
+ matchSpecialFolderPathToEnv(CSIDL_WINDOWS, "windir");
+ matchSpecialFolderPathToEnv(CSIDL_PROGRAM_FILES_COMMON, "CommonProgramFiles");
+ /* this is only set on Wine, but can't hurt to verify it: */
+ matchSpecialFolderPathToEnv(CSIDL_SYSTEM, "winsysdir");
+}
+
+/* Loosely based on PathRemoveBackslashA from dlls/shlwapi/path.c */
+static BOOL myPathIsRootA(LPCSTR lpszPath)
+{
+ if (lpszPath && *lpszPath &&
+ lpszPath[1] == ':' && lpszPath[2] == '\\' && lpszPath[3] == '\0')
+ return TRUE; /* X:\ */
+ return FALSE;
+}
+static LPSTR myPathRemoveBackslashA( LPSTR lpszPath )
+{
+ LPSTR szTemp = NULL;
+
+ if(lpszPath)
+ {
+ szTemp = CharPrevA(lpszPath, lpszPath + strlen(lpszPath));
+ if (!myPathIsRootA(lpszPath) && *szTemp == '\\')
+ *szTemp = '\0';
+ }
+ return szTemp;
+}
+
+/* Verifies the shell path for CSIDL_WINDOWS matches the return from
+ * GetWindowsDirectory. If SHGetSpecialFolderPath fails, no harm, no foul--not
+ * every shell32 version supports CSIDL_WINDOWS.
+ */
+static void testWinDir(void)
+{
+ char windowsShellPath[MAX_PATH], windowsDir[MAX_PATH] = { 0 };
+
+ if (!pSHGetSpecialFolderPathA) return;
+
+ if (pSHGetSpecialFolderPathA(NULL, windowsShellPath, CSIDL_WINDOWS, FALSE))
+ {
+ myPathRemoveBackslashA(windowsShellPath);
+ GetWindowsDirectoryA(windowsDir, sizeof(windowsDir));
+ myPathRemoveBackslashA(windowsDir);
+ ok(!lstrcmpiA(windowsDir, windowsShellPath),
+ "GetWindowsDirectory returns %s SHGetSpecialFolderPath returns %s\n",
+ windowsDir, windowsShellPath);
+ }
+}
+
+/* Verifies the shell path for CSIDL_SYSTEM matches the return from
+ * GetSystemDirectory. If SHGetSpecialFolderPath fails, no harm,
+ * no foul--not every shell32 version supports CSIDL_SYSTEM.
+ */
+static void testSystemDir(void)
+{
+ char systemShellPath[MAX_PATH], systemDir[MAX_PATH], systemDirx86[MAX_PATH];
+
+ if (!pSHGetSpecialFolderPathA) return;
+
+ GetSystemDirectoryA(systemDir, sizeof(systemDir));
+ myPathRemoveBackslashA(systemDir);
+ if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEM, FALSE))
+ {
+ myPathRemoveBackslashA(systemShellPath);
+ ok(!lstrcmpiA(systemDir, systemShellPath),
+ "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
+ systemDir, systemShellPath);
+ }
+
+ if (!pGetSystemWow64DirectoryA || !pGetSystemWow64DirectoryA(systemDirx86, sizeof(systemDirx86)))
+ GetSystemDirectoryA(systemDirx86, sizeof(systemDirx86));
+ myPathRemoveBackslashA(systemDirx86);
+ if (pSHGetSpecialFolderPathA(NULL, systemShellPath, CSIDL_SYSTEMX86, FALSE))
+ {
+ myPathRemoveBackslashA(systemShellPath);
+ ok(!lstrcmpiA(systemDirx86, systemShellPath) || broken(!lstrcmpiA(systemDir, systemShellPath)),
+ "GetSystemDirectory returns %s SHGetSpecialFolderPath returns %s\n",
+ systemDir, systemShellPath);
+ }
+}
+
+/* Globals used by subprocesses */
+static int myARGC;
+static char **myARGV;
+static char base[MAX_PATH];
+static char selfname[MAX_PATH];
+
+static BOOL init(void)
+{
+ myARGC = winetest_get_mainargs(&myARGV);
+ if (!GetCurrentDirectoryA(sizeof(base), base)) return FALSE;
+ strcpy(selfname, myARGV[0]);
+ return TRUE;
+}
+
+static void doChild(const char *arg)
+{
+ char path[MAX_PATH];
+ HRESULT hr;
+
+ if (arg[0] == '1')
+ {
+ LPITEMIDLIST pidl;
+ char *p;
+
+ /* test what happens when CSIDL_FAVORITES is set to a nonexistent directory */
+
+ /* test some failure cases first: */
+ hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES, NULL, SHGFP_TYPE_CURRENT, path);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
+ "SHGetFolderPath returned 0x%08x, expected 0x80070002\n", hr);
+
+ pidl = NULL;
+ hr = pSHGetFolderLocation(NULL, CSIDL_FAVORITES, NULL, 0, &pidl);
+ ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
+ "SHGetFolderLocation returned 0x%08x\n", hr);
+ if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
+
+ ok(!pSHGetSpecialFolderPathA(NULL, path, CSIDL_FAVORITES, FALSE),
+ "SHGetSpecialFolderPath succeeded, expected failure\n");
+
+ pidl = NULL;
+ hr = pSHGetSpecialFolderLocation(NULL, CSIDL_FAVORITES, &pidl);
+ ok(hr == E_FAIL || hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND),
+ "SHGetFolderLocation returned 0x%08x\n", hr);
+
+ if (hr == S_OK && pidl) IMalloc_Free(pMalloc, pidl);
+
+ /* now test success: */
+ hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
+ SHGFP_TYPE_CURRENT, path);
+ ok (hr == S_OK, "got 0x%08x\n", hr);
+ if (hr == S_OK)
+ {
+ BOOL ret;
+
+ trace("CSIDL_FAVORITES was changed to %s\n", path);
+ ret = CreateDirectoryA(path, NULL);
+ ok(!ret, "expected failure with ERROR_ALREADY_EXISTS\n");
+ if (!ret)
+ ok(GetLastError() == ERROR_ALREADY_EXISTS,
+ "got %d, expected ERROR_ALREADY_EXISTS\n", GetLastError());
+
+ p = path + strlen(path);
+ strcpy(p, "\\desktop.ini");
+ DeleteFileA(path);
+ *p = 0;
+ SetFileAttributesA( path, FILE_ATTRIBUTE_NORMAL );
+ ret = RemoveDirectoryA(path);
+ ok( ret, "failed to remove %s error %u\n", path, GetLastError() );
+ }
+ }
+ else if (arg[0] == '2')
+ {
+ /* make sure SHGetFolderPath still succeeds when the
+ original value of CSIDL_FAVORITES is restored. */
+ hr = pSHGetFolderPathA(NULL, CSIDL_FAVORITES | CSIDL_FLAG_CREATE, NULL,
+ SHGFP_TYPE_CURRENT, path);
+ ok(hr == S_OK, "SHGetFolderPath failed: 0x%08x\n", hr);
+ }
+}
+
+/* Tests the return values from the various shell functions both with and
+ * without the use of the CSIDL_FLAG_CREATE flag. This flag only appeared in
+ * version 5 of the shell, so don't test unless it's at least version 5.
+ * The test reads a value from the registry, modifies it, calls
+ * SHGetFolderPath once with the CSIDL_FLAG_CREATE flag, and immediately
+ * afterward without it. Then it restores the registry and deletes the folder
+ * that was created.
+ * One oddity with respect to restoration: shell32 caches somehow, so it needs
+ * to be reloaded in order to see the correct (restored) value.
+ * Some APIs unrelated to the ones under test may fail, but I expect they're
+ * covered by other unit tests; I just print out something about failure to
+ * help trace what's going on.
+ */
+static void test_NonExistentPath(void)
+{
+ static const char userShellFolders[] =
+ "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\User Shell Folders";
+ char originalPath[MAX_PATH], modifiedPath[MAX_PATH];
+ HKEY key;
+
+ if (!pSHGetFolderPathA) return;
+ if (!pSHGetFolderLocation) return;
+ if (!pSHGetSpecialFolderPathA) return;
+ if (!pSHGetSpecialFolderLocation) return;
+ if (!pSHFileOperationA) return;
+ if (shellVersion.dwMajorVersion < 5) return;
+
+ if (!RegOpenKeyExA(HKEY_CURRENT_USER, userShellFolders, 0, KEY_ALL_ACCESS,
+ &key))
+ {
+ DWORD len, type;
+
+ len = sizeof(originalPath);
+ if (!RegQueryValueExA(key, "Favorites", NULL, &type,
+ (LPBYTE)&originalPath, &len))
+ {
+ size_t len = strlen(originalPath);
+
+ memcpy(modifiedPath, originalPath, len);
+ modifiedPath[len++] = '2';
+ modifiedPath[len++] = '\0';
+ trace("Changing CSIDL_FAVORITES to %s\n", modifiedPath);
+ if (!RegSetValueExA(key, "Favorites", 0, type,
+ (LPBYTE)modifiedPath, len))
+ {
+ char buffer[MAX_PATH+20];
+ STARTUPINFOA startup;
+ PROCESS_INFORMATION info;
+
+ sprintf(buffer, "%s tests/shellpath.c 1", selfname);
+ memset(&startup, 0, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_SHOWNORMAL;
+ CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
+ &startup, &info);
+ winetest_wait_child_process( info.hProcess );
+
+ /* restore original values: */
+ trace("Restoring CSIDL_FAVORITES to %s\n", originalPath);
+ RegSetValueExA(key, "Favorites", 0, type, (LPBYTE) originalPath,
+ strlen(originalPath) + 1);
+ RegFlushKey(key);
+
+ sprintf(buffer, "%s tests/shellpath.c 2", selfname);
+ memset(&startup, 0, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_SHOWNORMAL;
+ CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0L, NULL, NULL,
+ &startup, &info);
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0,
+ "child process termination\n");
+ }
+ }
+ else skip("RegQueryValueExA(key, Favorites, ...) failed\n");
+ if (key)
+ RegCloseKey(key);
+ }
+ else skip("RegOpenKeyExA(HKEY_CURRENT_USER, %s, ...) failed\n", userShellFolders);
+}
+
+static void test_SHGetFolderPathEx(void)
+{
+ HRESULT hr;
+ WCHAR buffer[MAX_PATH], *path;
+ DWORD len;
+
+ if (!pSHGetKnownFolderPath || !pSHGetFolderPathEx)
+ {
+ win_skip("SHGetKnownFolderPath or SHGetFolderPathEx not available\n");
+ return;
+ }
+
+if (0) { /* crashes */
+ hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, NULL);
+ ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
+}
+ /* non-existent folder id */
+ path = (void *)0xdeadbeef;
+ hr = pSHGetKnownFolderPath(&IID_IOleObject, 0, NULL, &path);
+ ok(hr == HRESULT_FROM_WIN32(ERROR_FILE_NOT_FOUND), "got 0x%08x\n", hr);
+ ok(path == NULL, "got %p\n", path);
+
+ path = NULL;
+ hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, KF_FLAG_DEFAULT_PATH, NULL, &path);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path != NULL, "expected path != NULL\n");
+ CoTaskMemFree(path);
+
+ path = NULL;
+ hr = pSHGetKnownFolderPath(&FOLDERID_Desktop, 0, NULL, &path);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(path != NULL, "expected path != NULL\n");
+
+ hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, MAX_PATH);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+ ok(!lstrcmpiW(path, buffer), "expected equal paths\n");
+ len = lstrlenW(buffer);
+ CoTaskMemFree(path);
+
+ hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, 0);
+ ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
+
+if (0) { /* crashes */
+ hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, NULL, len + 1);
+ ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
+
+ hr = pSHGetFolderPathEx(NULL, 0, NULL, buffer, MAX_PATH);
+ ok(hr == E_INVALIDARG, "expected E_INVALIDARG, got 0x%08x\n", hr);
+}
+ hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len);
+ ok(hr == E_NOT_SUFFICIENT_BUFFER, "expected E_NOT_SUFFICIENT_BUFFER, got 0x%08x\n", hr);
+
+ hr = pSHGetFolderPathEx(&FOLDERID_Desktop, 0, NULL, buffer, len + 1);
+ ok(hr == S_OK, "expected S_OK, got 0x%08x\n", hr);
+}
+
static BOOL is_in_strarray(const WCHAR *needle, const char *hay)
{
WCHAR wstr[MAX_PATH];
--
2.16.4
June 22, 2018
[PATCH 1/4] shell32: Accept more flags in SHGetKnownFolderPath().
by Józef Kucia
KF_FLAG_SIMPLE_IDLIST | KF_FLAG_DONT_UNEXPAND doesn't seem to influence
results returned by SHGetKnownFolderPath().
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/shell32/shellpath.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/shell32/shellpath.c b/dlls/shell32/shellpath.c
index a551e93aa8c7..de4bf7d566c1 100644
--- a/dlls/shell32/shellpath.c
+++ b/dlls/shell32/shellpath.c
@@ -4885,8 +4885,8 @@ HRESULT WINAPI SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, DWORD flags, HANDLE t
if (folder < 0)
return HRESULT_FROM_WIN32( ERROR_FILE_NOT_FOUND );
- if (flags & ~(KF_FLAG_CREATE|KF_FLAG_DONT_VERIFY|KF_FLAG_NO_ALIAS|
- KF_FLAG_INIT|KF_FLAG_DEFAULT_PATH))
+ if (flags & ~(KF_FLAG_CREATE|KF_FLAG_SIMPLE_IDLIST|KF_FLAG_DONT_UNEXPAND|
+ KF_FLAG_DONT_VERIFY|KF_FLAG_NO_ALIAS|KF_FLAG_INIT|KF_FLAG_DEFAULT_PATH))
{
FIXME("flags 0x%08x not supported\n", flags);
return E_INVALIDARG;
--
2.16.4
June 22, 2018
Re: [PATCH v2] user32: Always release menu item in EnableMenuItem
by Alexandre Julliard
Fabian Maurer <dark.shadow4(a)web.de> writes:
> @@ -3751,9 +3751,11 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
>
> /* Get the parent menu to access*/
> parentMenu = grab_menu_ptr(menu->hSysMenuOwner);
> - release_menu_ptr(menu);
> if (!parentMenu)
> + {
> + release_menu_ptr(menu);
> return (UINT)-1;
> + }
>
> hwnd = parentMenu->hWnd;
> release_menu_ptr(parentMenu);
> @@ -3764,8 +3766,7 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
> RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
> }
> }
> - else
> - release_menu_ptr(menu);
> + release_menu_ptr(menu);
You can't call RedrawWindow() while holding the lock.
--
Alexandre Julliard
julliard(a)winehq.org
June 22, 2018
Re: [PATCH] gdi32: Add a workaround for A->W text output with Symbol font encoding.
by Dmitry Timoshkov
Huw Davies <huw(a)codeweavers.com> wrote:
> Looks good. I've sent in a new version with a re-worded commit
> message that hopefully makes it clear that this isn't a work-around in
> Wine, but a work-around in Windows. I also fixed a grammar issue in
> an existing comment and took the opportunity to make the formatting
> more consistent.
Thanks Huw!
--
Dmitry.
June 22, 2018
Re: [PATCH] gdi32/tests: Test writing to the default palette.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 22, 2018
Re: [PATCH] winex11.drv: Move condition to the proper place.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 22, 2018
Re: [PATCH 1/1] wsdapi/tests: Add tests for MatchProbeEx.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 22, 2018
Re: [PATCH] gdi32: Add a workaround for A->W text output with Symbol font encoding.
by Huw Davies
On Fri, Jun 22, 2018 at 12:55:06PM +0800, Dmitry Timoshkov wrote:
> There are 2 ways to output Ansi text:
> 1. Call DrawTextA/ExtTextOutA, it uses font codepage for unicode translation.
> 2. hfont = CreateFont("Wingdings", SYMBOL_CHARSET);
> SendMessageA(hwnd, WM_SETFONT, hfont);
> SendMessageA(hwnd, WM_SETTEXT, textA);
> It uses current ANSI codepage for unicode translation.
>
> Currently #1 works correctly for Symbol fonts but #2 does not. This patch
> makes #2 work as well. Since this is a text drawing bug I don't see a way
> of adding a test case for this behaviour.
Looks good. I've sent in a new version with a re-worded commit
message that hopefully makes it clear that this isn't a work-around in
Wine, but a work-around in Windows. I also fixed a grammar issue in
an existing comment and took the opportunity to make the formatting
more consistent.
Huw.
June 22, 2018
Re: [PATCH] msvcp120: Add test for Concurrent_vector_Internal_compact.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
June 22, 2018
[PATCH] gdi32: For symbol fonts check whether the char has been converted to Unicode.
by Huw Davies
From: Dmitry Timoshkov <dmitry(a)baikal.ru>
This means that Unicode versions of text functions can use the result
of a A->W conversion under CP_ACP.
It's required so that the following will work:
hfont = CreateFont("Wingdings", SYMBOL_CHARSET);
SendMessageA(hwnd, WM_SETFONT, hfont);
SendMessageA(hwnd, WM_SETTEXT, textA);
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
---
dlls/gdi32/freetype.c | 57 ++++++++++++++++++++++++++++++++++++---------------
1 file changed, 41 insertions(+), 16 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 1293e08a73..b7e2413753 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -6303,24 +6303,47 @@ static FT_UInt get_GSUB_vert_glyph(const GdiFont *font, UINT glyph)
return GSUB_apply_feature(header, feature, glyph);
}
+static FT_UInt get_glyph_index_symbol(const GdiFont *font, UINT glyph)
+{
+ FT_UInt ret;
+
+ if (glyph < 0x100) glyph += 0xf000;
+ /* there are a number of old pre-Unicode "broken" TTFs, which
+ do have symbols at U+00XX instead of U+f0XX */
+ if (!(ret = pFT_Get_Char_Index(font->ft_face, glyph)))
+ ret = pFT_Get_Char_Index(font->ft_face, glyph - 0xf000);
+
+ return ret;
+}
+
static FT_UInt get_glyph_index(const GdiFont *font, UINT glyph)
{
- FT_UInt glyphId;
+ FT_UInt ret;
+ WCHAR wc;
+ char buf;
- if(font->ft_face->charmap->encoding == FT_ENCODING_NONE) {
- WCHAR wc = (WCHAR)glyph;
+ if (font->ft_face->charmap->encoding == FT_ENCODING_NONE)
+ {
BOOL default_used;
BOOL *default_used_pointer;
- FT_UInt ret;
- char buf;
+
default_used_pointer = NULL;
default_used = FALSE;
if (codepage_sets_default_used(font->codepage))
default_used_pointer = &default_used;
- if(!WideCharToMultiByte(font->codepage, 0, &wc, 1, &buf, sizeof(buf), NULL, default_used_pointer) || default_used)
+ wc = (WCHAR)glyph;
+ if (!WideCharToMultiByte(font->codepage, 0, &wc, 1, &buf, sizeof(buf), NULL, default_used_pointer) ||
+ default_used)
{
- if (font->codepage == CP_SYMBOL && wc < 0x100)
- ret = pFT_Get_Char_Index(font->ft_face, (unsigned char)wc);
+ if (font->codepage == CP_SYMBOL)
+ {
+ ret = get_glyph_index_symbol(font, glyph);
+ if (!ret)
+ {
+ if (WideCharToMultiByte(CP_ACP, 0, &wc, 1, &buf, 1, NULL, NULL))
+ ret = get_glyph_index_symbol(font, buf);
+ }
+ }
else
ret = 0;
}
@@ -6330,17 +6353,19 @@ static FT_UInt get_glyph_index(const GdiFont *font, UINT glyph)
return ret;
}
- if(font->ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
+ if (font->ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
{
- if (glyph < 0x100) glyph += 0xf000;
- /* there is a number of old pre-Unicode "broken" TTFs, which
- do have symbols at U+00XX instead of U+f0XX */
- if (!(glyphId = pFT_Get_Char_Index(font->ft_face, glyph)))
- glyphId = pFT_Get_Char_Index(font->ft_face, glyph-0xf000);
+ ret = get_glyph_index_symbol(font, glyph);
+ if (!ret)
+ {
+ wc = (WCHAR)glyph;
+ if (WideCharToMultiByte(CP_ACP, 0, &wc, 1, &buf, 1, NULL, NULL))
+ ret = get_glyph_index_symbol(font, (unsigned char)buf);
+ }
+ return ret;
}
- else glyphId = pFT_Get_Char_Index(font->ft_face, glyph);
- return glyphId;
+ return pFT_Get_Char_Index(font->ft_face, glyph);
}
/* helper for freetype_GetGlyphIndices */
--
2.16.2
June 22, 2018
[PATCH] msvcp120: Add test for Concurrent_vector_Internal_compact.
by Hua Meng
Signed-off-by: Hua meng <161220092(a)smail.nju.edu.cn>
---
dlls/msvcp120/tests/msvcp120.c | 102 ++++++++++++++++++++++++++++++++++++++++-
1 file changed, 101 insertions(+), 1 deletion(-)
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c
index aec66fb259..0ec9fbd3b1 100644
--- a/dlls/msvcp120/tests/msvcp120.c
+++ b/dlls/msvcp120/tests/msvcp120.c
@@ -27,6 +27,11 @@
DWORD expect_idx;
static int vector_alloc_count;
static int vector_elem_count;
+typedef struct blocks_to_free{
+ size_t first_block;
+ void *blocks[sizeof(void*)*8];
+ int size_check;
+}compact_block;
#define DEFINE_EXPECT(func) \
BOOL expect_ ## func, called_ ## func
@@ -115,6 +120,8 @@ static void * (WINAPI *call_thiscall_func3)( void *func, void *this, const void
const void *b );
static void * (WINAPI *call_thiscall_func4)( void *func, void *this, const void *a,
const void *b, const void *c );
+static void * (WINAPI *call_thiscall_func5)( void *func, void *this, const void *a,
+ const void *b, const void *c, const void *d );
static void * (WINAPI *call_thiscall_func6)( void *func, void *this, const void *a,
const void *b, const void *c, const void *d, const void *e );
@@ -131,6 +138,7 @@ static void init_thiscall_thunk(void)
call_thiscall_func2 = (void *)thunk;
call_thiscall_func3 = (void *)thunk;
call_thiscall_func4 = (void *)thunk;
+ call_thiscall_func5 = (void *)thunk;
call_thiscall_func6 = (void *)thunk;
}
@@ -140,6 +148,8 @@ static void init_thiscall_thunk(void)
(const void*)(b))
#define call_func4(func,_this,a,b,c) call_thiscall_func4(func,_this,(const void*)(a),\
(const void*)(b),(const void*)(c))
+#define call_func5(func,_this,a,b,c,d) call_thiscall_func5(func,_this,(const void*)(a),\
+ (const void*)(b),(const void*)(c),(const void*)(d))
#define call_func6(func,_this,a,b,c,d,e) call_thiscall_func6(func,_this,(const void*)(a),\
(const void*)(b),(const void*)(c),(const void*)(d),(const void*)(e))
#else
@@ -149,6 +159,7 @@ static void init_thiscall_thunk(void)
#define call_func2(func,_this,a) func(_this,a)
#define call_func3(func,_this,a,b) func(_this,a,b)
#define call_func4(func,_this,a,b,c) func(_this,a,b,c)
+#define call_func5(func,_this,a,b,c,d) func(_this,a,b,c,d)
#define call_func6(func,_this,a,b,c,d,e) func(_this,a,b,c,d,e)
#endif /* __i386__ */
@@ -404,6 +415,9 @@ static void (__thiscall *p_vector_base_v4__Internal_assign)(
void (__cdecl*)(void*, const void*, size_t), void (__cdecl*)(void*, const void*, size_t));
static void (__thiscall *p_vector_base_v4__Internal_swap)(
vector_base_v4*, const vector_base_v4*);
+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 HMODULE msvcp;
#define SETNOFAIL(x,y) x = (void*)GetProcAddress(msvcp,y)
@@ -552,6 +566,8 @@ static BOOL init(void)
"?_Internal_assign(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IEAAXAEBV123(a)_KP6AXPEAX1@ZP6AX2PEBX1(a)Z5@Z");
SET(p_vector_base_v4__Internal_swap,
"?_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");
} else {
SET(p_tr2_sys__File_size,
"?_File_size(a)sys@tr2(a)std@@YA_KPBD(a)Z");
@@ -669,6 +685,8 @@ static BOOL init(void)
"?_Internal_assign(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAEXABV123(a)IP6AXPAXI@ZP6AX1PBXI(a)Z4@Z");
SET(p_vector_base_v4__Internal_swap,
"?_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");
#else
SET(p__Thrd_current,
"_Thrd_current");
@@ -714,6 +732,9 @@ static BOOL init(void)
"?_Internal_assign(a)_Concurrent_vector_base_v4@details(a)Concurrency@@IAAXABV123(a)IP6AXPAXI@ZP6AX1PBXI(a)Z4@Z");
SET(p_vector_base_v4__Internal_swap,
"?_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");
+
#endif
}
SET(p__Thrd_equal,
@@ -2734,7 +2755,8 @@ static void test_vector_base_v4(void)
{
vector_base_v4 vector, v2;
size_t idx, size;
- int *data;
+ compact_block b;
+ int i, *data;
concurrent_vector_int_ctor(&vector);
@@ -2892,6 +2914,84 @@ static void test_vector_base_v4(void)
CHECK_CALLED(concurrent_vector_int_destroy);
concurrent_vector_int_dtor(&v2);
+ /* test for _Internal_compact */
+ concurrent_vector_int_ctor(&v2);
+ for(i=0; i<2; i++) {
+ 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 == 4, "v2.early_size got %ld expected 4\n", (long)v2.early_size);
+ memset(&b, 0xff, sizeof(b));
+ SET_EXPECT(concurrent_vector_int_alloc);
+ SET_EXPECT(concurrent_vector_int_copy);
+ SET_EXPECT(concurrent_vector_int_destroy);
+ data = call_func5(p_vector_base_v4__Internal_compact,
+ &v2, sizeof(int), &b, concurrent_vector_int_destroy,
+ concurrent_vector_int_copy);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ CHECK_CALLED(concurrent_vector_int_copy);
+ CHECK_CALLED(concurrent_vector_int_destroy);
+ ok(v2.first_block == 2, "v2.first_block got %ld expected 2\n", (long)v2.first_block);
+ ok(v2.early_size == 4,"v2.early_size got %ld expected 4\n", (long)v2.early_size);
+ ok(b.first_block == 1, "b.first_block got %ld expected 1\n", (long)b.first_block);
+ for(i=0; i<2; i++){
+ ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
+ free(b.blocks[i]);
+ vector_alloc_count--;
+ }
+ for(; i<ARRAY_SIZE(b.blocks); i++)
+ ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
+ ok(b.size_check == -1, "b.size_check = %x\n", b.size_check);
+
+ 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");
+ for(i=0; i<3; i++){
+ data = call_func3(p_vector_base_v4__Internal_push_back, &v2, sizeof(int), &idx);
+ ok(data != NULL, "_Internal_push_back returned NULL\n");
+ }
+ 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");
+ vector_elem_count += 5;
+ ok(v2.first_block == 2, "v2.first_block got %ld expected 2\n", (long)v2.first_block);
+ ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
+ memset(&b, 0xff, sizeof(b));
+ SET_EXPECT(concurrent_vector_int_alloc);
+ SET_EXPECT(concurrent_vector_int_copy);
+ SET_EXPECT(concurrent_vector_int_destroy);
+ data = call_func5(p_vector_base_v4__Internal_compact,
+ &v2, sizeof(int), &b, concurrent_vector_int_destroy,
+ concurrent_vector_int_copy);
+ CHECK_CALLED(concurrent_vector_int_alloc);
+ CHECK_CALLED(concurrent_vector_int_copy);
+ CHECK_CALLED(concurrent_vector_int_destroy);
+ ok(v2.first_block == 4, "v2.first_block got %ld expected 4\n", (long)v2.first_block);
+ ok(v2.early_size == 9, "v2.early_size got %ld expected 9\n", (long)v2.early_size);
+ ok(b.first_block == 2, "b.first_block got %ld expected 2\n", (long)b.first_block);
+ for(i=0; i<4; i++){
+ ok(b.blocks[i] != NULL, "b.blocks[%d] got NULL\n", i);
+ /* only b.blocks[0] and b.blocks[>=b.first_block] are used */
+ if(i == b.first_block-1) continue;
+ free(b.blocks[i]);
+ vector_alloc_count--;
+ }
+ for(; i<ARRAY_SIZE(b.blocks); i++)
+ ok(!b.blocks[i], "b.blocks[%d] != NULL\n", i);
+ SET_EXPECT(concurrent_vector_int_destroy);
+ size = (size_t)call_func2(p_vector_base_v4__Internal_clear,
+ &v2, concurrent_vector_int_destroy);
+ 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 22, 2018
Re: [PATCH] fonts: Add clock images to Wingdings font.
by Dmitry Timoshkov
Alexandre Julliard <julliard(a)winehq.org> wrote:
> > Glyphs were copied from the Android Emoji font.
>
> As far as I can tell, this Android font is under the SIL Open Font
> License, which is not LGPL-compatible.
I had an impression that this font is part of the Android codebase
which is under a BSD-like license.
Perhaps you have a suggestion for the font with a compatible license?
--
Dmitry.
June 22, 2018
Re: [PATCH] fonts: Add clock images to Wingdings font.
by Alexandre Julliard
Dmitry Timoshkov <dmitry(a)baikal.ru> writes:
> Glyphs were copied from the Android Emoji font.
As far as I can tell, this Android font is under the SIL Open Font
License, which is not LGPL-compatible.
--
Alexandre Julliard
julliard(a)winehq.org
June 22, 2018
Re: [PATCH 2/2] msi: Add support for re-caching package
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
June 22, 2018
Re: [PATCH 1/2] msi: Report error when cached installer has different version
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
June 22, 2018
Re: [PATCH] d2d1: Stop redefination on older compilers
by Alistair Leslie-Hughes
https://bugs.winehq.org/show_bug.cgi?id=44052
Comment #25
Regards
Alistair
________________________________
From: Henri Verbeet <hverbeet(a)gmail.com>
Sent: Friday, June 22, 2018 6:23:48 PM
To: Alistair Leslie-Hughes
Cc: wine-devel(a)winehq.org
Subject: Re: [PATCH] d2d1: Stop redefination on older compilers
On 22 June 2018 at 06:30, Alistair Leslie-Hughes
<leslie_alistair(a)hotmail.com> wrote:
> Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
> ---
> dlls/d2d1/d2d1_private.h | 3 ++-
> dlls/d2d1/tests/d2d1.c | 7 ++++---
> 2 files changed, 6 insertions(+), 4 deletions(-)
>
What are you trying to fix exactly?
June 22, 2018
[PATCH] fonts: Add clock images to Wingdings font.
by Dmitry Timoshkov
Glyphs were copied from the Android Emoji font.
wingding.ttf should be rebuilt in maintainer mode after applying this patch.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
fonts/wingding.sfd | 1903 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 1900 insertions(+), 3 deletions(-)
diff --git a/fonts/wingding.sfd b/fonts/wingding.sfd
index c46152b077..940b1d686c 100644
--- a/fonts/wingding.sfd
+++ b/fonts/wingding.sfd
@@ -47,12 +47,12 @@ LangName: 1033 "" "" "" "" "" "" "" "" "" "" "" "http://www.winehq.org" "" "This
Encoding: Symbol
UnicodeInterp: none
NameList: Adobe Glyph List
-DisplaySize: -48
+DisplaySize: -72
AntiAlias: 1
FitToEm: 1
-WinInfo: 0 29 12
+WinInfo: 0 25 9
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,1902 @@ LayerCount: 2
Fore
Refer: 34 63724 N 0 1 -1 0 1653 -173 2
EndChar
+
+StartChar: bullet
+Encoding: 183 8226 38
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 0,0,1
+ 1239 1538 1239 1538 1427 1430 c 128,-1,2
+ 1615 1322 1615 1322 1723 1133.5 c 128,-1,3
+ 1831 945 1831 945 1831 731 c 0,4,5
+ 1831 515 1831 515 1722 327.5 c 128,-1,6
+ 1613 140 1613 140 1425.5 32.5 c 128,-1,7
+ 1238 -75 1238 -75 1024 -75 c 0,8,9
+ 808 -75 808 -75 621 33 c 128,-1,10
+ 434 141 434 141 326 328 c 128,-1,11
+ 218 515 218 515 218 731 c 0,12,13
+ 218 945 218 945 325.5 1132.5 c 128,-1,14
+ 433 1320 433 1320 620.5 1429 c 128,-1,15
+ 808 1538 808 1538 1024 1538 c 0,0,1
+1024 3 m 0,16,17
+ 1220 3 1220 3 1389 101 c 128,-1,18
+ 1558 199 1558 199 1655.5 367.5 c 128,-1,19
+ 1753 536 1753 536 1753 731 c 0,20,21
+ 1753 927 1753 927 1655 1096 c 128,-1,22
+ 1557 1265 1557 1265 1388.5 1362.5 c 128,-1,23
+ 1220 1460 1220 1460 1024 1460 c 256,24,25
+ 828 1460 828 1460 659.5 1362 c 128,-1,26
+ 491 1264 491 1264 393.5 1095.5 c 128,-1,27
+ 296 927 296 927 296 731 c 256,28,29
+ 296 535 296 535 394 366.5 c 128,-1,30
+ 492 198 492 198 660.5 100.5 c 128,-1,31
+ 829 3 829 3 1024 3 c 0,16,17
+1285 1066 m 1,32,-1
+ 1129 796 l 1,33,34
+ 1148 766 1148 766 1148 731 c 0,35,36
+ 1148 680 1148 680 1112 644 c 128,-1,37
+ 1076 608 1076 608 1024 608 c 0,38,39
+ 973 608 973 608 937 644 c 128,-1,40
+ 901 680 901 680 901 731 c 0,41,42
+ 901 766 901 766 919 794.5 c 128,-1,43
+ 937 823 937 823 966 840 c 1,44,-1
+ 966 1396 l 1,45,-1
+ 1082 1396 l 1,46,-1
+ 1082 948 l 1,47,-1
+ 1184 1124 l 1,48,-1
+ 1285 1066 l 1,32,-1
+978 731 m 0,49,50
+ 978 716 978 716 990.5 700.5 c 128,-1,51
+ 1003 685 1003 685 1024 685 c 0,52,53
+ 1040 685 1040 685 1055.5 696.5 c 128,-1,54
+ 1071 708 1071 708 1071 731 c 0,55,56
+ 1071 751 1071 751 1057.5 764 c 128,-1,57
+ 1044 777 1044 777 1024 777 c 0,58,59
+ 1005 777 1005 777 991.5 764 c 128,-1,60
+ 978 751 978 751 978 731 c 0,49,50
+1654 777 m 0,61,62
+ 1674 777 1674 777 1687.5 764 c 128,-1,63
+ 1701 751 1701 751 1701 731 c 0,64,65
+ 1701 712 1701 712 1687.5 698.5 c 128,-1,66
+ 1674 685 1674 685 1654 685 c 0,67,68
+ 1635 685 1635 685 1621.5 698.5 c 128,-1,69
+ 1608 712 1608 712 1608 731 c 0,70,71
+ 1608 751 1608 751 1621.5 764 c 128,-1,72
+ 1635 777 1635 777 1654 777 c 0,61,62
+1570 1000 m 0,73,74
+ 1552 1000 1552 1000 1538 1013 c 128,-1,75
+ 1524 1026 1524 1026 1524 1046 c 0,76,77
+ 1524 1063 1524 1063 1536.5 1078 c 128,-1,78
+ 1549 1093 1549 1093 1569 1093 c 0,79,80
+ 1588 1093 1588 1093 1602 1080 c 128,-1,81
+ 1616 1067 1616 1067 1616 1047 c 0,82,83
+ 1616 1020 1616 1020 1594 1006 c 1,84,85
+ 1582 1000 1582 1000 1570 1000 c 0,73,74
+1386 1277 m 0,86,87
+ 1386 1256 1386 1256 1371.5 1243 c 128,-1,88
+ 1357 1230 1357 1230 1340 1230 c 0,89,90
+ 1319 1230 1319 1230 1306 1245 c 128,-1,91
+ 1293 1260 1293 1260 1293 1277 c 0,92,93
+ 1293 1297 1293 1297 1307.5 1310 c 128,-1,94
+ 1322 1323 1322 1323 1339 1323 c 0,95,96
+ 1358 1323 1358 1323 1372 1310 c 128,-1,97
+ 1386 1297 1386 1297 1386 1277 c 0,86,87
+709 1323 m 256,98,99
+ 727 1323 727 1323 741.5 1310.5 c 128,-1,100
+ 756 1298 756 1298 756 1277 c 0,101,102
+ 756 1259 756 1259 743 1244.5 c 128,-1,103
+ 730 1230 730 1230 709 1230 c 0,104,105
+ 692 1230 692 1230 677.5 1243 c 128,-1,106
+ 663 1256 663 1256 663 1277 c 0,107,108
+ 663 1297 663 1297 677 1310 c 128,-1,109
+ 691 1323 691 1323 709 1323 c 256,98,99
+525 1046 m 0,110,111
+ 525 1025 525 1025 510 1012.5 c 128,-1,112
+ 495 1000 495 1000 478 1000 c 0,113,114
+ 458 1000 458 1000 445 1014.5 c 128,-1,115
+ 432 1029 432 1029 432 1046 c 0,116,117
+ 432 1066 432 1066 446 1079.5 c 128,-1,118
+ 460 1093 460 1093 479 1093 c 256,119,120
+ 498 1093 498 1093 511.5 1079 c 128,-1,121
+ 525 1065 525 1065 525 1046 c 0,110,111
+394 777 m 256,122,123
+ 414 777 414 777 427.5 764 c 128,-1,124
+ 441 751 441 751 441 731 c 0,125,126
+ 441 712 441 712 427.5 698.5 c 128,-1,127
+ 414 685 414 685 394 685 c 256,128,129
+ 374 685 374 685 361 698.5 c 128,-1,130
+ 348 712 348 712 348 731 c 0,131,132
+ 348 751 348 751 361 764 c 128,-1,133
+ 374 777 374 777 394 777 c 256,122,123
+477 462 m 256,134,135
+ 496 462 496 462 510.5 449.5 c 128,-1,136
+ 525 437 525 437 525 416 c 0,137,138
+ 525 397 525 397 512 383.5 c 128,-1,139
+ 499 370 499 370 478 370 c 0,140,141
+ 460 370 460 370 446 383.5 c 128,-1,142
+ 432 397 432 397 432 417 c 256,143,144
+ 432 437 432 437 445 449.5 c 128,-1,145
+ 458 462 458 462 477 462 c 256,134,135
+756 185 m 0,146,147
+ 756 164 756 164 741.5 151.5 c 128,-1,148
+ 727 139 727 139 709 139 c 0,149,150
+ 689 139 689 139 676 153.5 c 128,-1,151
+ 663 168 663 168 663 185 c 0,152,153
+ 663 206 663 206 677.5 219 c 128,-1,154
+ 692 232 692 232 709 232 c 0,155,156
+ 721 232 721 232 733 226 c 1,157,158
+ 756 211 756 211 756 185 c 0,146,147
+1024 147 m 256,159,160
+ 1044 147 1044 147 1057.5 134 c 128,-1,161
+ 1071 121 1071 121 1071 101 c 256,162,163
+ 1071 81 1071 81 1057.5 67.5 c 128,-1,164
+ 1044 54 1044 54 1024 54 c 0,165,166
+ 1005 54 1005 54 991.5 67.5 c 128,-1,167
+ 978 81 978 81 978 101 c 256,168,169
+ 978 121 978 121 991 134 c 128,-1,170
+ 1004 147 1004 147 1024 147 c 256,159,160
+1339 232 m 0,171,172
+ 1357 232 1357 232 1371.5 219 c 128,-1,173
+ 1386 206 1386 206 1386 185 c 0,174,175
+ 1386 168 1386 168 1373 153.5 c 128,-1,176
+ 1360 139 1360 139 1339 139 c 0,177,178
+ 1322 139 1322 139 1307.5 152 c 128,-1,179
+ 1293 165 1293 165 1293 185 c 0,180,181
+ 1293 204 1293 204 1306.5 218 c 128,-1,182
+ 1320 232 1320 232 1339 232 c 0,171,172
+1616 415 m 0,183,184
+ 1616 394 1616 394 1601.5 382 c 128,-1,185
+ 1587 370 1587 370 1570 370 c 0,186,187
+ 1550 370 1550 370 1537 384.5 c 128,-1,188
+ 1524 399 1524 399 1524 416 c 0,189,190
+ 1524 436 1524 436 1537.5 449 c 128,-1,191
+ 1551 462 1551 462 1571 462 c 256,192,193
+ 1591 462 1591 462 1603.5 449.5 c 128,-1,194
+ 1616 437 1616 437 1616 415 c 0,183,184
+EndSplineSet
+EndChar
+
+StartChar: divide
+Encoding: 184 247 39
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 0,0,1
+ 1238 1538 1238 1538 1425.5 1430.5 c 128,-1,2
+ 1613 1323 1613 1323 1722 1135.5 c 128,-1,3
+ 1831 948 1831 948 1831 732 c 0,4,5
+ 1831 514 1831 514 1722 327 c 128,-1,6
+ 1613 140 1613 140 1425 32.5 c 128,-1,7
+ 1237 -75 1237 -75 1024 -75 c 0,8,9
+ 808 -75 808 -75 621 33 c 128,-1,10
+ 434 141 434 141 326 328 c 128,-1,11
+ 218 515 218 515 218 732 c 0,12,13
+ 218 948 218 948 326 1135 c 128,-1,14
+ 434 1322 434 1322 621 1430 c 128,-1,15
+ 808 1538 808 1538 1024 1538 c 0,0,1
+1024 2 m 0,16,17
+ 1219 2 1219 2 1387 98.5 c 128,-1,18
+ 1555 195 1555 195 1654 364.5 c 128,-1,19
+ 1753 534 1753 534 1753 732 c 0,20,21
+ 1753 928 1753 928 1655 1096.5 c 128,-1,22
+ 1557 1265 1557 1265 1388.5 1362.5 c 128,-1,23
+ 1220 1460 1220 1460 1024 1460 c 256,24,25
+ 828 1460 828 1460 659.5 1362 c 128,-1,26
+ 491 1264 491 1264 393.5 1095.5 c 128,-1,27
+ 296 927 296 927 296 732 c 0,28,29
+ 296 534 296 534 395.5 364.5 c 128,-1,30
+ 495 195 495 195 663 98.5 c 128,-1,31
+ 831 2 831 2 1024 2 c 0,16,17
+1359 992 m 1,32,-1
+ 1417 891 l 1,33,-1
+ 1147 735 l 1,34,-1
+ 1148 732 l 1,35,36
+ 1148 680 1148 680 1111.5 644 c 128,-1,37
+ 1075 608 1075 608 1024 608 c 256,38,39
+ 973 608 973 608 937 644 c 128,-1,40
+ 901 680 901 680 901 732 c 0,41,42
+ 901 767 901 767 919 795.5 c 128,-1,43
+ 937 824 937 824 966 839 c 1,44,-1
+ 966 1396 l 1,45,-1
+ 1082 1396 l 1,46,-1
+ 1082 839 l 1,47,-1
+ 1089 836 l 1,48,-1
+ 1359 992 l 1,32,-1
+1654 778 m 0,49,50
+ 1674 778 1674 778 1687.5 764.5 c 128,-1,51
+ 1701 751 1701 751 1701 732 c 0,52,53
+ 1701 712 1701 712 1687.5 698 c 128,-1,54
+ 1674 684 1674 684 1654 684 c 0,55,56
+ 1635 684 1635 684 1621.5 698 c 128,-1,57
+ 1608 712 1608 712 1608 732 c 0,58,59
+ 1608 751 1608 751 1621.5 764.5 c 128,-1,60
+ 1635 778 1635 778 1654 778 c 0,49,50
+756 185 m 0,61,62
+ 756 164 756 164 741.5 151.5 c 128,-1,63
+ 727 139 727 139 709 139 c 0,64,65
+ 689 139 689 139 676 153.5 c 128,-1,66
+ 663 168 663 168 663 186 c 0,67,68
+ 663 206 663 206 677.5 219 c 128,-1,69
+ 692 232 692 232 709 232 c 0,70,71
+ 729 232 729 232 742.5 218.5 c 128,-1,72
+ 756 205 756 205 756 185 c 0,61,62
+1024 684 m 0,73,74
+ 1043 684 1043 684 1057 698 c 128,-1,75
+ 1071 712 1071 712 1071 732 c 0,76,77
+ 1071 751 1071 751 1057.5 764.5 c 128,-1,78
+ 1044 778 1044 778 1024 778 c 0,79,80
+ 1005 778 1005 778 991.5 764.5 c 128,-1,81
+ 978 751 978 751 978 732 c 0,82,83
+ 978 712 978 712 992.5 698 c 128,-1,84
+ 1007 684 1007 684 1024 684 c 0,73,74
+394 778 m 256,85,86
+ 414 778 414 778 427.5 764.5 c 128,-1,87
+ 441 751 441 751 441 732 c 0,88,89
+ 441 712 441 712 428 698.5 c 128,-1,90
+ 415 685 415 685 396 685 c 0,91,92
+ 376 685 376 685 362 698.5 c 128,-1,93
+ 348 712 348 712 348 732 c 0,94,95
+ 348 751 348 751 361 764.5 c 128,-1,96
+ 374 778 374 778 394 778 c 256,85,86
+1339 232 m 0,97,98
+ 1357 232 1357 232 1371.5 219 c 128,-1,99
+ 1386 206 1386 206 1386 186 c 0,100,101
+ 1386 168 1386 168 1373 153.5 c 128,-1,102
+ 1360 139 1360 139 1339 139 c 0,103,104
+ 1322 139 1322 139 1307.5 152 c 128,-1,105
+ 1293 165 1293 165 1293 185 c 0,106,107
+ 1293 206 1293 206 1306.5 219 c 128,-1,108
+ 1320 232 1320 232 1339 232 c 0,97,98
+710 1323 m 0,109,110
+ 727 1323 727 1323 741.5 1310.5 c 128,-1,111
+ 756 1298 756 1298 756 1277 c 0,112,113
+ 756 1259 756 1259 743 1244.5 c 128,-1,114
+ 730 1230 730 1230 709 1230 c 0,115,116
+ 692 1230 692 1230 677.5 1243 c 128,-1,117
+ 663 1256 663 1256 663 1277 c 0,118,119
+ 663 1297 663 1297 677 1310 c 128,-1,120
+ 691 1323 691 1323 710 1323 c 0,109,110
+479 462 m 0,121,122
+ 496 462 496 462 510.5 450 c 128,-1,123
+ 525 438 525 438 525 417 c 0,124,125
+ 525 399 525 399 512 384 c 128,-1,126
+ 499 369 499 369 478 369 c 0,127,128
+ 460 369 460 369 446 382.5 c 128,-1,129
+ 432 396 432 396 432 417 c 0,130,131
+ 432 437 432 437 446.5 449.5 c 128,-1,132
+ 461 462 461 462 479 462 c 0,121,122
+1024 147 m 256,133,134
+ 1044 147 1044 147 1057.5 134 c 128,-1,135
+ 1071 121 1071 121 1071 101 c 0,136,137
+ 1071 82 1071 82 1057.5 68 c 128,-1,138
+ 1044 54 1044 54 1024 54 c 0,139,140
+ 1005 54 1005 54 991.5 68 c 128,-1,141
+ 978 82 978 82 978 101 c 0,142,143
+ 978 121 978 121 991 134 c 128,-1,144
+ 1004 147 1004 147 1024 147 c 256,133,134
+525 1046 m 256,145,146
+ 525 1025 525 1025 510.5 1012.5 c 128,-1,147
+ 496 1000 496 1000 478 1000 c 0,148,149
+ 458 1000 458 1000 445 1014.5 c 128,-1,150
+ 432 1029 432 1029 432 1046 c 0,151,152
+ 432 1066 432 1066 446.5 1079.5 c 128,-1,153
+ 461 1093 461 1093 479 1093 c 0,154,155
+ 498 1093 498 1093 511.5 1080 c 128,-1,156
+ 525 1067 525 1067 525 1046 c 256,145,146
+1293 1277 m 0,157,158
+ 1293 1297 1293 1297 1307.5 1310 c 128,-1,159
+ 1322 1323 1322 1323 1339 1323 c 0,160,161
+ 1359 1323 1359 1323 1372.5 1308.5 c 128,-1,162
+ 1386 1294 1386 1294 1386 1277 c 0,163,164
+ 1386 1256 1386 1256 1371.5 1243 c 128,-1,165
+ 1357 1230 1357 1230 1340 1230 c 0,166,167
+ 1322 1230 1322 1230 1307.5 1243 c 128,-1,168
+ 1293 1256 1293 1256 1293 1277 c 0,157,158
+1570 1000 m 0,169,170
+ 1551 1000 1551 1000 1537.5 1013 c 128,-1,171
+ 1524 1026 1524 1026 1524 1046 c 0,172,173
+ 1524 1064 1524 1064 1537 1078.5 c 128,-1,174
+ 1550 1093 1550 1093 1570 1093 c 0,175,176
+ 1587 1093 1587 1093 1601.5 1080.5 c 128,-1,177
+ 1616 1068 1616 1068 1616 1047 c 0,178,179
+ 1616 1020 1616 1020 1594 1006 c 1,180,181
+ 1582 1000 1582 1000 1570 1000 c 0,169,170
+1616 415 m 0,182,183
+ 1616 394 1616 394 1602 381.5 c 128,-1,184
+ 1588 369 1588 369 1571 369 c 0,185,186
+ 1550 369 1550 369 1537 384 c 128,-1,187
+ 1524 399 1524 399 1524 416 c 0,188,189
+ 1524 436 1524 436 1538 449 c 128,-1,190
+ 1552 462 1552 462 1570 462 c 0,191,192
+ 1582 462 1582 462 1594 456 c 1,193,194
+ 1616 442 1616 442 1616 415 c 0,182,183
+EndSplineSet
+EndChar
+
+StartChar: notequal
+Encoding: 185 8800 40
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 0,0,1
+ 1239 1538 1239 1538 1427 1430 c 128,-1,2
+ 1615 1322 1615 1322 1723 1133.5 c 128,-1,3
+ 1831 945 1831 945 1831 731 c 0,4,5
+ 1831 515 1831 515 1722 327.5 c 128,-1,6
+ 1613 140 1613 140 1425.5 32.5 c 128,-1,7
+ 1238 -75 1238 -75 1024 -75 c 0,8,9
+ 808 -75 808 -75 621 33 c 128,-1,10
+ 434 141 434 141 326 328 c 128,-1,11
+ 218 515 218 515 218 731 c 0,12,13
+ 218 945 218 945 325.5 1132.5 c 128,-1,14
+ 433 1320 433 1320 620.5 1429 c 128,-1,15
+ 808 1538 808 1538 1024 1538 c 0,0,1
+1024 3 m 0,16,17
+ 1220 3 1220 3 1388 100 c 128,-1,18
+ 1556 197 1556 197 1654.5 365.5 c 128,-1,19
+ 1753 534 1753 534 1753 731 c 0,20,21
+ 1753 927 1753 927 1655 1096 c 128,-1,22
+ 1557 1265 1557 1265 1388.5 1362.5 c 128,-1,23
+ 1220 1460 1220 1460 1024 1460 c 256,24,25
+ 828 1460 828 1460 659.5 1362 c 128,-1,26
+ 491 1264 491 1264 393.5 1095.5 c 128,-1,27
+ 296 927 296 927 296 731 c 0,28,29
+ 296 533 296 533 394.5 365 c 128,-1,30
+ 493 197 493 197 661 100 c 128,-1,31
+ 829 3 829 3 1024 3 c 0,16,17
+1082 840 m 1,32,33
+ 1115 822 1115 822 1133 789 c 1,34,-1
+ 1445 789 l 1,35,-1
+ 1445 673 l 1,36,-1
+ 1133 673 l 1,37,38
+ 1117 644 1117 644 1088 626 c 128,-1,39
+ 1059 608 1059 608 1024 608 c 0,40,41
+ 973 608 973 608 937 644 c 128,-1,42
+ 901 680 901 680 901 731 c 0,43,44
+ 901 767 901 767 919 795.5 c 128,-1,45
+ 937 824 937 824 966 840 c 1,46,-1
+ 966 1396 l 1,47,-1
+ 1082 1396 l 1,48,-1
+ 1082 840 l 1,32,33
+1024 685 m 0,49,50
+ 1044 685 1044 685 1057.5 698 c 128,-1,51
+ 1071 711 1071 711 1071 731 c 256,52,53
+ 1071 751 1071 751 1057.5 764.5 c 128,-1,54
+ 1044 778 1044 778 1024 778 c 256,55,56
+ 1004 778 1004 778 991 764.5 c 128,-1,57
+ 978 751 978 751 978 731 c 0,58,59
+ 978 712 978 712 990 698.5 c 128,-1,60
+ 1002 685 1002 685 1024 685 c 0,49,50
+1654 778 m 0,61,62
+ 1674 778 1674 778 1687.5 764.5 c 128,-1,63
+ 1701 751 1701 751 1701 731 c 256,64,65
+ 1701 711 1701 711 1687.5 698 c 128,-1,66
+ 1674 685 1674 685 1654 685 c 0,67,68
+ 1635 685 1635 685 1621.5 698 c 128,-1,69
+ 1608 711 1608 711 1608 731 c 256,70,71
+ 1608 751 1608 751 1621.5 764.5 c 128,-1,72
+ 1635 778 1635 778 1654 778 c 0,61,62
+1569 1000 m 0,73,74
+ 1551 1000 1551 1000 1537.5 1013 c 128,-1,75
+ 1524 1026 1524 1026 1524 1046 c 0,76,77
+ 1524 1064 1524 1064 1536.5 1078.5 c 128,-1,78
+ 1549 1093 1549 1093 1570 1093 c 0,79,80
+ 1587 1093 1587 1093 1601.5 1081 c 128,-1,81
+ 1616 1069 1616 1069 1616 1047 c 0,82,83
+ 1616 1026 1616 1026 1602.5 1013 c 128,-1,84
+ 1589 1000 1589 1000 1569 1000 c 0,73,74
+1293 1277 m 256,85,86
+ 1293 1297 1293 1297 1307.5 1310 c 128,-1,87
+ 1322 1323 1322 1323 1339 1323 c 0,88,89
+ 1359 1323 1359 1323 1372.5 1309.5 c 128,-1,90
+ 1386 1296 1386 1296 1386 1277 c 0,91,92
+ 1386 1257 1386 1257 1371.5 1244 c 128,-1,93
+ 1357 1231 1357 1231 1339 1231 c 0,94,95
+ 1320 1231 1320 1231 1306.5 1244 c 128,-1,96
+ 1293 1257 1293 1257 1293 1277 c 256,85,86
+710 1323 m 0,97,98
+ 728 1323 728 1323 742 1310.5 c 128,-1,99
+ 756 1298 756 1298 756 1277 c 0,100,101
+ 756 1260 756 1260 743 1245.5 c 128,-1,102
+ 730 1231 730 1231 709 1231 c 0,103,104
+ 692 1231 692 1231 677.5 1244 c 128,-1,105
+ 663 1257 663 1257 663 1277 c 0,106,107
+ 663 1296 663 1296 676 1309.5 c 128,-1,108
+ 689 1323 689 1323 710 1323 c 0,97,98
+525 1046 m 0,109,110
+ 525 1025 525 1025 510.5 1012.5 c 128,-1,111
+ 496 1000 496 1000 479 1000 c 0,112,113
+ 459 1000 459 1000 445.5 1014.5 c 128,-1,114
+ 432 1029 432 1029 432 1046 c 0,115,116
+ 432 1066 432 1066 446 1079.5 c 128,-1,117
+ 460 1093 460 1093 478 1093 c 0,118,119
+ 490 1093 490 1093 502 1087 c 1,120,121
+ 525 1072 525 1072 525 1046 c 0,109,110
+394 778 m 256,122,123
+ 414 778 414 778 427.5 764.5 c 128,-1,124
+ 441 751 441 751 441 731 c 256,125,126
+ 441 711 441 711 427.5 698 c 128,-1,127
+ 414 685 414 685 394 685 c 256,128,129
+ 374 685 374 685 361 698 c 128,-1,130
+ 348 711 348 711 348 731 c 256,131,132
+ 348 751 348 751 361 764.5 c 128,-1,133
+ 374 778 374 778 394 778 c 256,122,123
+479 462 m 0,134,135
+ 496 462 496 462 510.5 449.5 c 128,-1,136
+ 525 437 525 437 525 416 c 0,137,138
+ 525 399 525 399 512 384.5 c 128,-1,139
+ 499 370 499 370 478 370 c 0,140,141
+ 460 370 460 370 446 383.5 c 128,-1,142
+ 432 397 432 397 432 417 c 0,143,144
+ 432 436 432 436 445 449 c 128,-1,145
+ 458 462 458 462 479 462 c 0,134,135
+756 185 m 256,146,147
+ 756 164 756 164 741.5 151.5 c 128,-1,148
+ 727 139 727 139 709 139 c 0,149,150
+ 688 139 688 139 675.5 153.5 c 128,-1,151
+ 663 168 663 168 663 186 c 0,152,153
+ 663 206 663 206 678 219 c 128,-1,154
+ 693 232 693 232 710 232 c 0,155,156
+ 729 232 729 232 742.5 219 c 128,-1,157
+ 756 206 756 206 756 185 c 256,146,147
+1024 148 m 256,158,159
+ 1044 148 1044 148 1057.5 134.5 c 128,-1,160
+ 1071 121 1071 121 1071 101 c 256,161,162
+ 1071 81 1071 81 1057.5 68 c 128,-1,163
+ 1044 55 1044 55 1024 55 c 0,164,165
+ 1005 55 1005 55 991.5 68 c 128,-1,166
+ 978 81 978 81 978 101 c 256,167,168
+ 978 121 978 121 991 134.5 c 128,-1,169
+ 1004 148 1004 148 1024 148 c 256,158,159
+1339 232 m 0,170,171
+ 1356 232 1356 232 1371 219 c 128,-1,172
+ 1386 206 1386 206 1386 186 c 0,173,174
+ 1386 168 1386 168 1373.5 153.5 c 128,-1,175
+ 1361 139 1361 139 1339 139 c 0,176,177
+ 1322 139 1322 139 1307.5 152 c 128,-1,178
+ 1293 165 1293 165 1293 185 c 0,179,180
+ 1293 206 1293 206 1306.5 219 c 128,-1,181
+ 1320 232 1320 232 1339 232 c 0,170,171
+1616 415 m 0,182,183
+ 1616 394 1616 394 1601.5 382 c 128,-1,184
+ 1587 370 1587 370 1570 370 c 0,185,186
+ 1550 370 1550 370 1537 384.5 c 128,-1,187
+ 1524 399 1524 399 1524 416 c 0,188,189
+ 1524 436 1524 436 1538 449 c 128,-1,190
+ 1552 462 1552 462 1570 462 c 0,191,192
+ 1589 462 1589 462 1602.5 449.5 c 128,-1,193
+ 1616 437 1616 437 1616 415 c 0,182,183
+EndSplineSet
+EndChar
+
+StartChar: equivalence
+Encoding: 186 8801 41
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 0,0,1
+ 1239 1538 1239 1538 1427 1430 c 128,-1,2
+ 1615 1322 1615 1322 1723 1133.5 c 128,-1,3
+ 1831 945 1831 945 1831 731 c 0,4,5
+ 1831 515 1831 515 1722 327.5 c 128,-1,6
+ 1613 140 1613 140 1425.5 32.5 c 128,-1,7
+ 1238 -75 1238 -75 1024 -75 c 0,8,9
+ 808 -75 808 -75 621 33 c 128,-1,10
+ 434 141 434 141 326 328 c 128,-1,11
+ 218 515 218 515 218 731 c 0,12,13
+ 218 945 218 945 325.5 1132.5 c 128,-1,14
+ 433 1320 433 1320 620.5 1429 c 128,-1,15
+ 808 1538 808 1538 1024 1538 c 0,0,1
+1024 3 m 0,16,17
+ 1220 3 1220 3 1388 100 c 128,-1,18
+ 1556 197 1556 197 1654.5 365.5 c 128,-1,19
+ 1753 534 1753 534 1753 731 c 0,20,21
+ 1753 927 1753 927 1655 1096 c 128,-1,22
+ 1557 1265 1557 1265 1388.5 1362.5 c 128,-1,23
+ 1220 1460 1220 1460 1024 1460 c 256,24,25
+ 828 1460 828 1460 659.5 1362 c 128,-1,26
+ 491 1264 491 1264 393.5 1095.5 c 128,-1,27
+ 296 927 296 927 296 731 c 0,28,29
+ 296 533 296 533 394.5 365 c 128,-1,30
+ 493 197 493 197 661 100 c 128,-1,31
+ 829 3 829 3 1024 3 c 0,16,17
+1082 840 m 1,32,33
+ 1115 822 1115 822 1133 789 c 1,34,-1
+ 1445 789 l 1,35,-1
+ 1445 673 l 1,36,-1
+ 1133 673 l 1,37,38
+ 1117 644 1117 644 1088 626 c 128,-1,39
+ 1059 608 1059 608 1024 608 c 0,40,41
+ 973 608 973 608 937 644 c 128,-1,42
+ 901 680 901 680 901 731 c 0,43,44
+ 901 767 901 767 919 795.5 c 128,-1,45
+ 937 824 937 824 966 840 c 1,46,-1
+ 966 1396 l 1,47,-1
+ 1082 1396 l 1,48,-1
+ 1082 840 l 1,32,33
+1024 685 m 0,49,50
+ 1044 685 1044 685 1057.5 698 c 128,-1,51
+ 1071 711 1071 711 1071 731 c 256,52,53
+ 1071 751 1071 751 1057.5 764.5 c 128,-1,54
+ 1044 778 1044 778 1024 778 c 256,55,56
+ 1004 778 1004 778 991 764.5 c 128,-1,57
+ 978 751 978 751 978 731 c 0,58,59
+ 978 712 978 712 990 698.5 c 128,-1,60
+ 1002 685 1002 685 1024 685 c 0,49,50
+1654 778 m 0,61,62
+ 1674 778 1674 778 1687.5 764.5 c 128,-1,63
+ 1701 751 1701 751 1701 731 c 256,64,65
+ 1701 711 1701 711 1687.5 698 c 128,-1,66
+ 1674 685 1674 685 1654 685 c 0,67,68
+ 1635 685 1635 685 1621.5 698 c 128,-1,69
+ 1608 711 1608 711 1608 731 c 256,70,71
+ 1608 751 1608 751 1621.5 764.5 c 128,-1,72
+ 1635 778 1635 778 1654 778 c 0,61,62
+1569 1000 m 0,73,74
+ 1551 1000 1551 1000 1537.5 1013 c 128,-1,75
+ 1524 1026 1524 1026 1524 1046 c 0,76,77
+ 1524 1064 1524 1064 1536.5 1078.5 c 128,-1,78
+ 1549 1093 1549 1093 1570 1093 c 0,79,80
+ 1587 1093 1587 1093 1601.5 1081 c 128,-1,81
+ 1616 1069 1616 1069 1616 1047 c 0,82,83
+ 1616 1026 1616 1026 1602.5 1013 c 128,-1,84
+ 1589 1000 1589 1000 1569 1000 c 0,73,74
+1293 1277 m 256,85,86
+ 1293 1297 1293 1297 1307.5 1310 c 128,-1,87
+ 1322 1323 1322 1323 1339 1323 c 0,88,89
+ 1359 1323 1359 1323 1372.5 1309.5 c 128,-1,90
+ 1386 1296 1386 1296 1386 1277 c 0,91,92
+ 1386 1257 1386 1257 1371.5 1244 c 128,-1,93
+ 1357 1231 1357 1231 1339 1231 c 0,94,95
+ 1320 1231 1320 1231 1306.5 1244 c 128,-1,96
+ 1293 1257 1293 1257 1293 1277 c 256,85,86
+710 1323 m 0,97,98
+ 728 1323 728 1323 742 1310.5 c 128,-1,99
+ 756 1298 756 1298 756 1277 c 0,100,101
+ 756 1260 756 1260 743 1245.5 c 128,-1,102
+ 730 1231 730 1231 709 1231 c 0,103,104
+ 692 1231 692 1231 677.5 1244 c 128,-1,105
+ 663 1257 663 1257 663 1277 c 0,106,107
+ 663 1296 663 1296 676 1309.5 c 128,-1,108
+ 689 1323 689 1323 710 1323 c 0,97,98
+525 1046 m 0,109,110
+ 525 1025 525 1025 510.5 1012.5 c 128,-1,111
+ 496 1000 496 1000 479 1000 c 0,112,113
+ 459 1000 459 1000 445.5 1014.5 c 128,-1,114
+ 432 1029 432 1029 432 1046 c 0,115,116
+ 432 1066 432 1066 446 1079.5 c 128,-1,117
+ 460 1093 460 1093 478 1093 c 0,118,119
+ 490 1093 490 1093 502 1087 c 1,120,121
+ 525 1072 525 1072 525 1046 c 0,109,110
+394 778 m 256,122,123
+ 414 778 414 778 427.5 764.5 c 128,-1,124
+ 441 751 441 751 441 731 c 256,125,126
+ 441 711 441 711 427.5 698 c 128,-1,127
+ 414 685 414 685 394 685 c 256,128,129
+ 374 685 374 685 361 698 c 128,-1,130
+ 348 711 348 711 348 731 c 256,131,132
+ 348 751 348 751 361 764.5 c 128,-1,133
+ 374 778 374 778 394 778 c 256,122,123
+479 462 m 0,134,135
+ 496 462 496 462 510.5 449.5 c 128,-1,136
+ 525 437 525 437 525 416 c 0,137,138
+ 525 399 525 399 512 384.5 c 128,-1,139
+ 499 370 499 370 478 370 c 0,140,141
+ 460 370 460 370 446 383.5 c 128,-1,142
+ 432 397 432 397 432 417 c 0,143,144
+ 432 436 432 436 445 449 c 128,-1,145
+ 458 462 458 462 479 462 c 0,134,135
+756 185 m 256,146,147
+ 756 164 756 164 741.5 151.5 c 128,-1,148
+ 727 139 727 139 709 139 c 0,149,150
+ 688 139 688 139 675.5 153.5 c 128,-1,151
+ 663 168 663 168 663 186 c 0,152,153
+ 663 206 663 206 678 219 c 128,-1,154
+ 693 232 693 232 710 232 c 0,155,156
+ 729 232 729 232 742.5 219 c 128,-1,157
+ 756 206 756 206 756 185 c 256,146,147
+1024 148 m 256,158,159
+ 1044 148 1044 148 1057.5 134.5 c 128,-1,160
+ 1071 121 1071 121 1071 101 c 256,161,162
+ 1071 81 1071 81 1057.5 68 c 128,-1,163
+ 1044 55 1044 55 1024 55 c 0,164,165
+ 1005 55 1005 55 991.5 68 c 128,-1,166
+ 978 81 978 81 978 101 c 256,167,168
+ 978 121 978 121 991 134.5 c 128,-1,169
+ 1004 148 1004 148 1024 148 c 256,158,159
+1339 232 m 0,170,171
+ 1356 232 1356 232 1371 219 c 128,-1,172
+ 1386 206 1386 206 1386 186 c 0,173,174
+ 1386 168 1386 168 1373.5 153.5 c 128,-1,175
+ 1361 139 1361 139 1339 139 c 0,176,177
+ 1322 139 1322 139 1307.5 152 c 128,-1,178
+ 1293 165 1293 165 1293 185 c 0,179,180
+ 1293 206 1293 206 1306.5 219 c 128,-1,181
+ 1320 232 1320 232 1339 232 c 0,170,171
+1616 415 m 0,182,183
+ 1616 394 1616 394 1601.5 382 c 128,-1,184
+ 1587 370 1587 370 1570 370 c 0,185,186
+ 1550 370 1550 370 1537 384.5 c 128,-1,187
+ 1524 399 1524 399 1524 416 c 0,188,189
+ 1524 436 1524 436 1538 449 c 128,-1,190
+ 1552 462 1552 462 1570 462 c 0,191,192
+ 1589 462 1589 462 1602.5 449.5 c 128,-1,193
+ 1616 437 1616 437 1616 415 c 0,182,183
+EndSplineSet
+EndChar
+
+StartChar: approxequal
+Encoding: 187 8776 42
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 256,0,1
+ 1240 1538 1240 1538 1427.5 1429 c 128,-1,2
+ 1615 1320 1615 1320 1722.5 1132.5 c 128,-1,3
+ 1830 945 1830 945 1830 731 c 0,4,5
+ 1830 515 1830 515 1722 328 c 128,-1,6
+ 1614 141 1614 141 1427 33 c 128,-1,7
+ 1240 -75 1240 -75 1024 -75 c 256,8,9
+ 808 -75 808 -75 621 33 c 128,-1,10
+ 434 141 434 141 326 328 c 128,-1,11
+ 218 515 218 515 218 731 c 0,12,13
+ 218 945 218 945 325.5 1132.5 c 128,-1,14
+ 433 1320 433 1320 620.5 1429 c 128,-1,15
+ 808 1538 808 1538 1024 1538 c 256,0,1
+1024 3 m 0,16,17
+ 1220 3 1220 3 1388.5 100.5 c 128,-1,18
+ 1557 198 1557 198 1654.5 367 c 128,-1,19
+ 1752 536 1752 536 1752 731 c 0,20,21
+ 1752 927 1752 927 1655 1095 c 128,-1,22
+ 1558 1263 1558 1263 1389.5 1361.5 c 128,-1,23
+ 1221 1460 1221 1460 1024 1460 c 0,24,25
+ 826 1460 826 1460 658 1361.5 c 128,-1,26
+ 490 1263 490 1263 393 1095 c 128,-1,27
+ 296 927 296 927 296 731 c 256,28,29
+ 296 535 296 535 393.5 366.5 c 128,-1,30
+ 491 198 491 198 660 100.5 c 128,-1,31
+ 829 3 829 3 1024 3 c 0,16,17
+1147 731 m 0,32,33
+ 1147 695 1147 695 1128 666 c 1,34,-1
+ 1285 397 l 1,35,-1
+ 1184 338 l 1,36,-1
+ 1028 608 l 1,37,38
+ 974 608 974 608 937 643 c 128,-1,39
+ 900 678 900 678 900 731 c 0,40,41
+ 900 766 900 766 918.5 795 c 128,-1,42
+ 937 824 937 824 966 840 c 1,43,-1
+ 966 1396 l 1,44,-1
+ 1082 1396 l 1,45,-1
+ 1082 840 l 1,46,47
+ 1111 824 1111 824 1129 795 c 128,-1,48
+ 1147 766 1147 766 1147 731 c 0,32,33
+1024 685 m 256,49,50
+ 1044 685 1044 685 1057 698.5 c 128,-1,51
+ 1070 712 1070 712 1070 731 c 0,52,53
+ 1070 751 1070 751 1057 764.5 c 128,-1,54
+ 1044 778 1044 778 1024 778 c 256,55,56
+ 1004 778 1004 778 991 764 c 128,-1,57
+ 978 750 978 750 978 731 c 0,58,59
+ 978 711 978 711 991 698 c 128,-1,60
+ 1004 685 1004 685 1024 685 c 256,49,50
+1654 778 m 0,61,62
+ 1674 778 1674 778 1687 764.5 c 128,-1,63
+ 1700 751 1700 751 1700 731 c 256,64,65
+ 1700 711 1700 711 1687 698 c 128,-1,66
+ 1674 685 1674 685 1654 685 c 0,67,68
+ 1635 685 1635 685 1621.5 698 c 128,-1,69
+ 1608 711 1608 711 1608 731 c 256,70,71
+ 1608 751 1608 751 1621.5 764.5 c 128,-1,72
+ 1635 778 1635 778 1654 778 c 0,61,62
+1570 1000 m 0,73,74
+ 1551 1000 1551 1000 1537 1013.5 c 128,-1,75
+ 1523 1027 1523 1027 1523 1047 c 0,76,77
+ 1523 1064 1523 1064 1535.5 1078.5 c 128,-1,78
+ 1548 1093 1548 1093 1570 1093 c 0,79,80
+ 1587 1093 1587 1093 1601.5 1080 c 128,-1,81
+ 1616 1067 1616 1067 1616 1046 c 0,82,83
+ 1616 1026 1616 1026 1602 1013 c 128,-1,84
+ 1588 1000 1588 1000 1570 1000 c 0,73,74
+1385 1276 m 0,85,86
+ 1385 1255 1385 1255 1370.5 1242.5 c 128,-1,87
+ 1356 1230 1356 1230 1338 1230 c 0,88,89
+ 1318 1230 1318 1230 1305.5 1244.5 c 128,-1,90
+ 1293 1259 1293 1259 1293 1277 c 0,91,92
+ 1293 1297 1293 1297 1306.5 1310 c 128,-1,93
+ 1320 1323 1320 1323 1338 1323 c 0,94,95
+ 1359 1323 1359 1323 1372 1310.5 c 128,-1,96
+ 1385 1298 1385 1298 1385 1276 c 0,85,86
+709 1323 m 0,97,98
+ 728 1323 728 1323 741.5 1310 c 128,-1,99
+ 755 1297 755 1297 755 1277 c 0,100,101
+ 755 1258 755 1258 742 1244.5 c 128,-1,102
+ 729 1231 729 1231 709 1231 c 0,103,104
+ 690 1231 690 1231 676 1244.5 c 128,-1,105
+ 662 1258 662 1258 662 1278 c 0,106,107
+ 662 1297 662 1297 675 1310 c 128,-1,108
+ 688 1323 688 1323 709 1323 c 0,97,98
+524 1047 m 0,109,110
+ 524 1027 524 1027 510.5 1013.5 c 128,-1,111
+ 497 1000 497 1000 478 1000 c 0,112,113
+ 458 1000 458 1000 445 1014.5 c 128,-1,114
+ 432 1029 432 1029 432 1046 c 0,115,116
+ 432 1067 432 1067 445.5 1080 c 128,-1,117
+ 459 1093 459 1093 478 1093 c 0,118,119
+ 490 1093 490 1093 502 1087 c 1,120,121
+ 524 1073 524 1073 524 1047 c 0,109,110
+394 778 m 0,122,123
+ 413 778 413 778 426.5 764.5 c 128,-1,124
+ 440 751 440 751 440 731 c 256,125,126
+ 440 711 440 711 426.5 698 c 128,-1,127
+ 413 685 413 685 394 685 c 0,128,129
+ 374 685 374 685 360.5 698 c 128,-1,130
+ 347 711 347 711 347 731 c 256,131,132
+ 347 751 347 751 360.5 764.5 c 128,-1,133
+ 374 778 374 778 394 778 c 0,122,123
+479 462 m 0,134,135
+ 497 462 497 462 510.5 449 c 128,-1,136
+ 524 436 524 436 524 416 c 0,137,138
+ 524 399 524 399 511 384.5 c 128,-1,139
+ 498 370 498 370 478 370 c 0,140,141
+ 460 370 460 370 446 383 c 128,-1,142
+ 432 396 432 396 432 416 c 0,143,144
+ 432 435 432 435 445 448.5 c 128,-1,145
+ 458 462 458 462 479 462 c 0,134,135
+755 185 m 0,146,147
+ 755 165 755 165 741 152 c 128,-1,148
+ 727 139 727 139 709 139 c 0,149,150
+ 687 139 687 139 674.5 153.5 c 128,-1,151
+ 662 168 662 168 662 186 c 0,152,153
+ 662 207 662 207 676 219 c 128,-1,154
+ 690 231 690 231 708 231 c 0,155,156
+ 727 231 727 231 741 219 c 128,-1,157
+ 755 207 755 207 755 185 c 0,146,147
+1024 148 m 256,158,159
+ 1044 148 1044 148 1057 134 c 128,-1,160
+ 1070 120 1070 120 1070 101 c 0,161,162
+ 1070 81 1070 81 1057 68 c 128,-1,163
+ 1044 55 1044 55 1024 55 c 256,164,165
+ 1004 55 1004 55 991 68 c 128,-1,166
+ 978 81 978 81 978 101 c 0,167,168
+ 978 120 978 120 991 134 c 128,-1,169
+ 1004 148 1004 148 1024 148 c 256,158,159
+1340 231 m 0,170,171
+ 1357 231 1357 231 1371 219 c 128,-1,172
+ 1385 207 1385 207 1385 187 c 0,173,174
+ 1385 168 1385 168 1372.5 153.5 c 128,-1,175
+ 1360 139 1360 139 1339 139 c 0,176,177
+ 1320 139 1320 139 1306.5 152 c 128,-1,178
+ 1293 165 1293 165 1293 185 c 0,179,180
+ 1293 207 1293 207 1306.5 219 c 128,-1,181
+ 1320 231 1320 231 1340 231 c 0,170,171
+1616 416 m 0,182,183
+ 1616 396 1616 396 1601.5 383 c 128,-1,184
+ 1587 370 1587 370 1570 370 c 0,185,186
+ 1549 370 1549 370 1536 384 c 128,-1,187
+ 1523 398 1523 398 1523 415 c 0,188,189
+ 1523 435 1523 435 1537.5 448.5 c 128,-1,190
+ 1552 462 1552 462 1569 462 c 0,191,192
+ 1590 462 1590 462 1603 448.5 c 128,-1,193
+ 1616 435 1616 435 1616 416 c 0,182,183
+EndSplineSet
+EndChar
+
+StartChar: ellipsis
+Encoding: 188 8230 43
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 256,0,1
+ 1240 1538 1240 1538 1427.5 1429 c 128,-1,2
+ 1615 1320 1615 1320 1722.5 1132.5 c 128,-1,3
+ 1830 945 1830 945 1830 731 c 0,4,5
+ 1830 515 1830 515 1722 328 c 128,-1,6
+ 1614 141 1614 141 1427 33 c 128,-1,7
+ 1240 -75 1240 -75 1024 -75 c 256,8,9
+ 808 -75 808 -75 621 33 c 128,-1,10
+ 434 141 434 141 326 328 c 128,-1,11
+ 218 515 218 515 218 731 c 0,12,13
+ 218 945 218 945 325.5 1132.5 c 128,-1,14
+ 433 1320 433 1320 620.5 1429 c 128,-1,15
+ 808 1538 808 1538 1024 1538 c 256,0,1
+1024 3 m 256,16,17
+ 1222 3 1222 3 1390 101.5 c 128,-1,18
+ 1558 200 1558 200 1655 368 c 128,-1,19
+ 1752 536 1752 536 1752 731 c 0,20,21
+ 1752 927 1752 927 1655 1095 c 128,-1,22
+ 1558 1263 1558 1263 1389.5 1361.5 c 128,-1,23
+ 1221 1460 1221 1460 1024 1460 c 0,24,25
+ 826 1460 826 1460 658 1361.5 c 128,-1,26
+ 490 1263 490 1263 393 1095 c 128,-1,27
+ 296 927 296 927 296 731 c 0,28,29
+ 296 536 296 536 393 368 c 128,-1,30
+ 490 200 490 200 658 101.5 c 128,-1,31
+ 826 3 826 3 1024 3 c 256,16,17
+1082 840 m 1,32,33
+ 1111 824 1111 824 1129 795.5 c 128,-1,34
+ 1147 767 1147 767 1147 732 c 256,35,36
+ 1147 697 1147 697 1129 668 c 128,-1,37
+ 1111 639 1111 639 1082 623 c 1,38,-1
+ 1082 311 l 1,39,-1
+ 966 311 l 1,40,-1
+ 966 623 l 1,41,42
+ 937 639 937 639 918.5 667.5 c 128,-1,43
+ 900 696 900 696 900 732 c 0,44,45
+ 900 767 900 767 918.5 795.5 c 128,-1,46
+ 937 824 937 824 966 840 c 1,47,-1
+ 966 1396 l 1,48,-1
+ 1082 1396 l 1,49,-1
+ 1082 840 l 1,32,33
+1024 685 m 0,50,51
+ 1042 685 1042 685 1056 698 c 128,-1,52
+ 1070 711 1070 711 1070 731 c 0,53,54
+ 1070 750 1070 750 1056.5 764 c 128,-1,55
+ 1043 778 1043 778 1024 778 c 256,56,57
+ 1005 778 1005 778 991.5 764 c 128,-1,58
+ 978 750 978 750 978 731 c 0,59,60
+ 978 711 978 711 991.5 698 c 128,-1,61
+ 1005 685 1005 685 1024 685 c 0,50,51
+1654 778 m 0,62,63
+ 1674 778 1674 778 1687 764.5 c 128,-1,64
+ 1700 751 1700 751 1700 731 c 0,65,66
+ 1700 712 1700 712 1687 698.5 c 128,-1,67
+ 1674 685 1674 685 1654 685 c 0,68,69
+ 1635 685 1635 685 1621.5 698.5 c 128,-1,70
+ 1608 712 1608 712 1608 731 c 0,71,72
+ 1608 751 1608 751 1621.5 764.5 c 128,-1,73
+ 1635 778 1635 778 1654 778 c 0,62,63
+1570 1000 m 0,74,75
+ 1551 1000 1551 1000 1537 1013.5 c 128,-1,76
+ 1523 1027 1523 1027 1523 1047 c 0,77,78
+ 1523 1064 1523 1064 1536 1078.5 c 128,-1,79
+ 1549 1093 1549 1093 1570 1093 c 0,80,81
+ 1587 1093 1587 1093 1601.5 1080 c 128,-1,82
+ 1616 1067 1616 1067 1616 1046 c 0,83,84
+ 1616 1026 1616 1026 1602 1013 c 128,-1,85
+ 1588 1000 1588 1000 1570 1000 c 0,74,75
+1385 1276 m 0,86,87
+ 1385 1255 1385 1255 1370.5 1243 c 128,-1,88
+ 1356 1231 1356 1231 1339 1231 c 0,89,90
+ 1319 1231 1319 1231 1306 1245.5 c 128,-1,91
+ 1293 1260 1293 1260 1293 1277 c 0,92,93
+ 1293 1297 1293 1297 1306.5 1310.5 c 128,-1,94
+ 1320 1324 1320 1324 1340 1324 c 0,95,96
+ 1359 1324 1359 1324 1372 1311 c 128,-1,97
+ 1385 1298 1385 1298 1385 1276 c 0,86,87
+708 1324 m 0,98,99
+ 727 1324 727 1324 741 1310.5 c 128,-1,100
+ 755 1297 755 1297 755 1277 c 0,101,102
+ 755 1260 755 1260 742 1245.5 c 128,-1,103
+ 729 1231 729 1231 709 1231 c 0,104,105
+ 690 1231 690 1231 676 1244.5 c 128,-1,106
+ 662 1258 662 1258 662 1278 c 256,107,108
+ 662 1298 662 1298 676 1311 c 128,-1,109
+ 690 1324 690 1324 708 1324 c 0,98,99
+524 1047 m 0,110,111
+ 524 1027 524 1027 510.5 1013.5 c 128,-1,112
+ 497 1000 497 1000 478 1000 c 0,113,114
+ 458 1000 458 1000 445 1014.5 c 128,-1,115
+ 432 1029 432 1029 432 1046 c 0,116,117
+ 432 1066 432 1066 445.5 1079.5 c 128,-1,118
+ 459 1093 459 1093 478 1093 c 0,119,120
+ 490 1093 490 1093 502 1087 c 1,121,122
+ 524 1073 524 1073 524 1047 c 0,110,111
+394 778 m 0,123,124
+ 413 778 413 778 426.5 764.5 c 128,-1,125
+ 440 751 440 751 440 731 c 0,126,127
+ 440 712 440 712 426.5 698.5 c 128,-1,128
+ 413 685 413 685 394 685 c 0,129,130
+ 374 685 374 685 360.5 698.5 c 128,-1,131
+ 347 712 347 712 347 731 c 0,132,133
+ 347 751 347 751 360.5 764.5 c 128,-1,134
+ 374 778 374 778 394 778 c 0,123,124
+478 463 m 256,135,136
+ 497 463 497 463 510.5 449.5 c 128,-1,137
+ 524 436 524 436 524 416 c 0,138,139
+ 524 399 524 399 511 384.5 c 128,-1,140
+ 498 370 498 370 478 370 c 0,141,142
+ 460 370 460 370 446 383 c 128,-1,143
+ 432 396 432 396 432 416 c 0,144,145
+ 432 435 432 435 445.5 449 c 128,-1,146
+ 459 463 459 463 478 463 c 256,135,136
+755 185 m 0,147,148
+ 755 165 755 165 740.5 152 c 128,-1,149
+ 726 139 726 139 708 139 c 0,150,151
+ 688 139 688 139 675 153.5 c 128,-1,152
+ 662 168 662 168 662 185 c 0,153,154
+ 662 207 662 207 676.5 219.5 c 128,-1,155
+ 691 232 691 232 709 232 c 0,156,157
+ 728 232 728 232 741.5 218 c 128,-1,158
+ 755 204 755 204 755 185 c 0,147,148
+1024 147 m 256,159,160
+ 1044 147 1044 147 1057 134 c 128,-1,161
+ 1070 121 1070 121 1070 101 c 0,162,163
+ 1070 82 1070 82 1057 68.5 c 128,-1,164
+ 1044 55 1044 55 1024 55 c 256,165,166
+ 1004 55 1004 55 991 68.5 c 128,-1,167
+ 978 82 978 82 978 101 c 0,168,169
+ 978 121 978 121 991 134 c 128,-1,170
+ 1004 147 1004 147 1024 147 c 256,159,160
+1339 232 m 0,171,172
+ 1356 232 1356 232 1370.5 219.5 c 128,-1,173
+ 1385 207 1385 207 1385 186 c 0,174,175
+ 1385 167 1385 167 1372.5 153 c 128,-1,176
+ 1360 139 1360 139 1339 139 c 0,177,178
+ 1322 139 1322 139 1307.5 152 c 128,-1,179
+ 1293 165 1293 165 1293 185 c 0,180,181
+ 1293 204 1293 204 1306.5 218 c 128,-1,182
+ 1320 232 1320 232 1339 232 c 0,171,172
+1616 416 m 0,183,184
+ 1616 396 1616 396 1601.5 383 c 128,-1,185
+ 1587 370 1587 370 1570 370 c 0,186,187
+ 1549 370 1549 370 1536 384.5 c 128,-1,188
+ 1523 399 1523 399 1523 416 c 0,189,190
+ 1523 436 1523 436 1537 449.5 c 128,-1,191
+ 1551 463 1551 463 1570 463 c 256,192,193
+ 1589 463 1589 463 1602.5 449 c 128,-1,194
+ 1616 435 1616 435 1616 416 c 0,183,184
+EndSplineSet
+EndChar
+
+StartChar: uniF8E6
+Encoding: 189 63718 44
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 0,0,1
+ 1240 1538 1240 1538 1427 1430 c 128,-1,2
+ 1614 1322 1614 1322 1722 1135 c 128,-1,3
+ 1830 948 1830 948 1830 732 c 0,4,5
+ 1830 518 1830 518 1722.5 330.5 c 128,-1,6
+ 1615 143 1615 143 1427.5 34 c 128,-1,7
+ 1240 -75 1240 -75 1024 -75 c 0,8,9
+ 809 -75 809 -75 621 33 c 128,-1,10
+ 433 141 433 141 325 329.5 c 128,-1,11
+ 217 518 217 518 217 732 c 0,12,13
+ 217 948 217 948 326 1135.5 c 128,-1,14
+ 435 1323 435 1323 622.5 1430.5 c 128,-1,15
+ 810 1538 810 1538 1024 1538 c 0,0,1
+1024 3 m 256,16,17
+ 1220 3 1220 3 1389 101 c 128,-1,18
+ 1558 199 1558 199 1655.5 367.5 c 128,-1,19
+ 1753 536 1753 536 1753 732 c 256,20,21
+ 1753 928 1753 928 1655 1096.5 c 128,-1,22
+ 1557 1265 1557 1265 1388.5 1362.5 c 128,-1,23
+ 1220 1460 1220 1460 1024 1460 c 256,24,25
+ 828 1460 828 1460 659 1362 c 128,-1,26
+ 490 1264 490 1264 392.5 1095.5 c 128,-1,27
+ 295 927 295 927 295 732 c 0,28,29
+ 295 536 295 536 393 367 c 128,-1,30
+ 491 198 491 198 659.5 100.5 c 128,-1,31
+ 828 3 828 3 1024 3 c 256,16,17
+1082 840 m 1,32,33
+ 1111 824 1111 824 1129 795.5 c 128,-1,34
+ 1147 767 1147 767 1147 732 c 0,35,36
+ 1147 679 1147 679 1109.5 643.5 c 128,-1,37
+ 1072 608 1072 608 1020 608 c 1,38,-1
+ 864 339 l 1,39,-1
+ 763 397 l 1,40,-1
+ 919 666 l 1,41,42
+ 901 698 901 698 901 732 c 0,43,44
+ 901 767 901 767 919 795.5 c 128,-1,45
+ 937 824 937 824 966 840 c 1,46,-1
+ 966 1396 l 1,47,-1
+ 1082 1396 l 1,48,-1
+ 1082 840 l 1,32,33
+977 732 m 0,49,50
+ 977 714 977 714 990.5 699.5 c 128,-1,51
+ 1004 685 1004 685 1024 685 c 0,52,53
+ 1042 685 1042 685 1056.5 698.5 c 128,-1,54
+ 1071 712 1071 712 1071 732 c 0,55,56
+ 1071 747 1071 747 1059 762.5 c 128,-1,57
+ 1047 778 1047 778 1024 778 c 0,58,59
+ 1007 778 1007 778 992 766.5 c 128,-1,60
+ 977 755 977 755 977 732 c 0,49,50
+1654 778 m 256,61,62
+ 1674 778 1674 778 1687.5 764.5 c 128,-1,63
+ 1701 751 1701 751 1701 731 c 0,64,65
+ 1701 712 1701 712 1687.5 698.5 c 128,-1,66
+ 1674 685 1674 685 1654 685 c 256,67,68
+ 1634 685 1634 685 1620.5 698.5 c 128,-1,69
+ 1607 712 1607 712 1607 731 c 0,70,71
+ 1607 751 1607 751 1620.5 764.5 c 128,-1,72
+ 1634 778 1634 778 1654 778 c 256,61,62
+1569 1000 m 0,73,74
+ 1552 1000 1552 1000 1537.5 1013 c 128,-1,75
+ 1523 1026 1523 1026 1523 1046 c 0,76,77
+ 1523 1064 1523 1064 1536 1078.5 c 128,-1,78
+ 1549 1093 1549 1093 1569 1093 c 0,79,80
+ 1587 1093 1587 1093 1601.5 1080 c 128,-1,81
+ 1616 1067 1616 1067 1616 1047 c 0,82,83
+ 1616 1021 1616 1021 1593 1006 c 1,84,85
+ 1581 1000 1581 1000 1569 1000 c 0,73,74
+1385 1278 m 256,86,87
+ 1385 1258 1385 1258 1370.5 1244.5 c 128,-1,88
+ 1356 1231 1356 1231 1339 1231 c 0,89,90
+ 1318 1231 1318 1231 1305 1245.5 c 128,-1,91
+ 1292 1260 1292 1260 1292 1277 c 0,92,93
+ 1292 1297 1292 1297 1307 1310.5 c 128,-1,94
+ 1322 1324 1322 1324 1339 1324 c 0,95,96
+ 1358 1324 1358 1324 1371.5 1311 c 128,-1,97
+ 1385 1298 1385 1298 1385 1278 c 256,86,87
+708 1324 m 256,98,99
+ 725 1324 725 1324 740 1311 c 128,-1,100
+ 755 1298 755 1298 755 1278 c 0,101,102
+ 755 1260 755 1260 742 1245.5 c 128,-1,103
+ 729 1231 729 1231 709 1231 c 0,104,105
+ 690 1231 690 1231 676 1244.5 c 128,-1,106
+ 662 1258 662 1258 662 1278 c 256,107,108
+ 662 1298 662 1298 676.5 1311 c 128,-1,109
+ 691 1324 691 1324 708 1324 c 256,98,99
+524 1046 m 0,110,111
+ 524 1026 524 1026 510 1013 c 128,-1,112
+ 496 1000 496 1000 477 1000 c 0,113,114
+ 457 1000 457 1000 444 1014.5 c 128,-1,115
+ 431 1029 431 1029 431 1046 c 0,116,117
+ 431 1066 431 1066 446 1079.5 c 128,-1,118
+ 461 1093 461 1093 478 1093 c 0,119,120
+ 497 1093 497 1093 510.5 1080 c 128,-1,121
+ 524 1067 524 1067 524 1046 c 0,110,111
+393 778 m 0,122,123
+ 413 778 413 778 426.5 764.5 c 128,-1,124
+ 440 751 440 751 440 732 c 0,125,126
+ 440 712 440 712 426.5 698.5 c 128,-1,127
+ 413 685 413 685 393 685 c 0,128,129
+ 374 685 374 685 360.5 698.5 c 128,-1,130
+ 347 712 347 712 347 732 c 0,131,132
+ 347 751 347 751 360.5 764.5 c 128,-1,133
+ 374 778 374 778 393 778 c 0,122,123
+478 463 m 0,134,135
+ 495 463 495 463 509.5 450 c 128,-1,136
+ 524 437 524 437 524 416 c 0,137,138
+ 524 399 524 399 511 384.5 c 128,-1,139
+ 498 370 498 370 478 370 c 0,140,141
+ 460 370 460 370 445.5 383.5 c 128,-1,142
+ 431 397 431 397 431 417 c 256,143,144
+ 431 437 431 437 445.5 450 c 128,-1,145
+ 460 463 460 463 478 463 c 0,134,135
+755 185 m 0,146,147
+ 755 164 755 164 740 151.5 c 128,-1,148
+ 725 139 725 139 708 139 c 0,149,150
+ 687 139 687 139 674.5 153.5 c 128,-1,151
+ 662 168 662 168 662 185 c 0,152,153
+ 662 206 662 206 676.5 219 c 128,-1,154
+ 691 232 691 232 708 232 c 0,155,156
+ 720 232 720 232 732 226 c 1,157,158
+ 755 211 755 211 755 185 c 0,146,147
+1024 148 m 256,159,160
+ 1044 148 1044 148 1057 134.5 c 128,-1,161
+ 1070 121 1070 121 1070 101 c 0,162,163
+ 1070 82 1070 82 1057 68.5 c 128,-1,164
+ 1044 55 1044 55 1024 55 c 256,165,166
+ 1004 55 1004 55 990.5 68.5 c 128,-1,167
+ 977 82 977 82 977 101 c 0,168,169
+ 977 121 977 121 990.5 134.5 c 128,-1,170
+ 1004 148 1004 148 1024 148 c 256,159,160
+1339 232 m 0,171,172
+ 1356 232 1356 232 1370.5 219.5 c 128,-1,173
+ 1385 207 1385 207 1385 186 c 0,174,175
+ 1385 168 1385 168 1372.5 153.5 c 128,-1,176
+ 1360 139 1360 139 1339 139 c 0,177,178
+ 1322 139 1322 139 1307 152 c 128,-1,179
+ 1292 165 1292 165 1292 186 c 0,180,181
+ 1292 206 1292 206 1306.5 219 c 128,-1,182
+ 1321 232 1321 232 1339 232 c 0,171,172
+1616 416 m 0,183,184
+ 1616 396 1616 396 1601.5 383 c 128,-1,185
+ 1587 370 1587 370 1569 370 c 0,186,187
+ 1549 370 1549 370 1536 384.5 c 128,-1,188
+ 1523 399 1523 399 1523 416 c 0,189,190
+ 1523 437 1523 437 1537.5 450 c 128,-1,191
+ 1552 463 1552 463 1569 463 c 0,192,193
+ 1581 463 1581 463 1593 457 c 1,194,195
+ 1616 442 1616 442 1616 416 c 0,183,184
+EndSplineSet
+EndChar
+
+StartChar: uniF8E7
+Encoding: 190 63719 45
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 0,0,1
+ 1240 1538 1240 1538 1427 1430 c 128,-1,2
+ 1614 1322 1614 1322 1722 1135 c 128,-1,3
+ 1830 948 1830 948 1830 732 c 256,4,5
+ 1830 516 1830 516 1722 329 c 128,-1,6
+ 1614 142 1614 142 1427 34 c 128,-1,7
+ 1240 -74 1240 -74 1024 -74 c 0,8,9
+ 810 -74 810 -74 622.5 33.5 c 128,-1,10
+ 435 141 435 141 326 328.5 c 128,-1,11
+ 217 516 217 516 217 732 c 256,12,13
+ 217 948 217 948 326 1135.5 c 128,-1,14
+ 435 1323 435 1323 622.5 1430.5 c 128,-1,15
+ 810 1538 810 1538 1024 1538 c 0,0,1
+1024 4 m 256,16,17
+ 1220 4 1220 4 1388 101 c 128,-1,18
+ 1556 198 1556 198 1654.5 366.5 c 128,-1,19
+ 1753 535 1753 535 1753 732 c 0,20,21
+ 1753 930 1753 930 1654.5 1098 c 128,-1,22
+ 1556 1266 1556 1266 1388 1363 c 128,-1,23
+ 1220 1460 1220 1460 1024 1460 c 256,24,25
+ 828 1460 828 1460 660 1363 c 128,-1,26
+ 492 1266 492 1266 393.5 1097.5 c 128,-1,27
+ 295 929 295 929 295 732 c 0,28,29
+ 295 534 295 534 393.5 366.5 c 128,-1,30
+ 492 199 492 199 660 101.5 c 128,-1,31
+ 828 4 828 4 1024 4 c 256,16,17
+1082 841 m 1,32,33
+ 1111 824 1111 824 1129 795.5 c 128,-1,34
+ 1147 767 1147 767 1147 732 c 0,35,36
+ 1147 681 1147 681 1111 645 c 128,-1,37
+ 1075 609 1075 609 1024 609 c 0,38,39
+ 989 609 989 609 959 628 c 1,40,-1
+ 689 472 l 1,41,-1
+ 631 572 l 1,42,-1
+ 901 728 l 1,43,44
+ 901 805 901 805 966 841 c 1,45,-1
+ 966 1397 l 1,46,-1
+ 1082 1397 l 1,47,-1
+ 1082 841 l 1,32,33
+1071 732 m 256,48,49
+ 1071 752 1071 752 1056.5 765 c 128,-1,50
+ 1042 778 1042 778 1024 778 c 0,51,52
+ 1004 778 1004 778 990.5 765 c 128,-1,53
+ 977 752 977 752 977 732 c 256,54,55
+ 977 712 977 712 990.5 699 c 128,-1,56
+ 1004 686 1004 686 1024 686 c 0,57,58
+ 1042 686 1042 686 1056.5 699 c 128,-1,59
+ 1071 712 1071 712 1071 732 c 256,48,49
+1654 778 m 256,60,61
+ 1674 778 1674 778 1687.5 765 c 128,-1,62
+ 1701 752 1701 752 1701 732 c 256,63,64
+ 1701 712 1701 712 1687.5 699 c 128,-1,65
+ 1674 686 1674 686 1654 686 c 256,66,67
+ 1634 686 1634 686 1620.5 699 c 128,-1,68
+ 1607 712 1607 712 1607 732 c 256,69,70
+ 1607 752 1607 752 1620.5 765 c 128,-1,71
+ 1634 778 1634 778 1654 778 c 256,60,61
+1569 1001 m 0,72,73
+ 1552 1001 1552 1001 1537.5 1014 c 128,-1,74
+ 1523 1027 1523 1027 1523 1047 c 0,75,76
+ 1523 1065 1523 1065 1535.5 1079.5 c 128,-1,77
+ 1548 1094 1548 1094 1569 1094 c 0,78,79
+ 1587 1094 1587 1094 1601.5 1081 c 128,-1,80
+ 1616 1068 1616 1068 1616 1047 c 0,81,82
+ 1616 1028 1616 1028 1603 1014.5 c 128,-1,83
+ 1590 1001 1590 1001 1569 1001 c 0,72,73
+1385 1278 m 0,84,85
+ 1385 1257 1385 1257 1370.5 1244 c 128,-1,86
+ 1356 1231 1356 1231 1339 1231 c 0,87,88
+ 1317 1231 1317 1231 1304.5 1245.5 c 128,-1,89
+ 1292 1260 1292 1260 1292 1277 c 0,90,91
+ 1292 1297 1292 1297 1307 1310.5 c 128,-1,92
+ 1322 1324 1322 1324 1339 1324 c 0,93,94
+ 1358 1324 1358 1324 1371.5 1311 c 128,-1,95
+ 1385 1298 1385 1298 1385 1278 c 0,84,85
+708 1231 m 0,96,97
+ 691 1231 691 1231 676.5 1244.5 c 128,-1,98
+ 662 1258 662 1258 662 1279 c 0,99,100
+ 662 1296 662 1296 675 1310 c 128,-1,101
+ 688 1324 688 1324 708 1324 c 0,102,103
+ 726 1324 726 1324 740.5 1311 c 128,-1,104
+ 755 1298 755 1298 755 1278 c 0,105,106
+ 755 1257 755 1257 740.5 1244 c 128,-1,107
+ 726 1231 726 1231 708 1231 c 0,96,97
+524 1047 m 0,108,109
+ 524 1027 524 1027 509.5 1014 c 128,-1,110
+ 495 1001 495 1001 478 1001 c 0,111,112
+ 458 1001 458 1001 444.5 1015 c 128,-1,113
+ 431 1029 431 1029 431 1047 c 0,114,115
+ 431 1068 431 1068 445.5 1081 c 128,-1,116
+ 460 1094 460 1094 478 1094 c 0,117,118
+ 497 1094 497 1094 510.5 1080 c 128,-1,119
+ 524 1066 524 1066 524 1047 c 0,108,109
+393 778 m 0,120,121
+ 413 778 413 778 426.5 765 c 128,-1,122
+ 440 752 440 752 440 732 c 256,123,124
+ 440 712 440 712 426.5 699 c 128,-1,125
+ 413 686 413 686 393 686 c 0,126,127
+ 374 686 374 686 360.5 699 c 128,-1,128
+ 347 712 347 712 347 732 c 256,129,130
+ 347 752 347 752 360.5 765 c 128,-1,131
+ 374 778 374 778 393 778 c 0,120,121
+478 463 m 0,132,133
+ 496 463 496 463 510 450 c 128,-1,134
+ 524 437 524 437 524 417 c 0,135,136
+ 524 400 524 400 511.5 385 c 128,-1,137
+ 499 370 499 370 479 370 c 0,138,139
+ 460 370 460 370 445.5 383.5 c 128,-1,140
+ 431 397 431 397 431 417 c 0,141,142
+ 431 436 431 436 444.5 449.5 c 128,-1,143
+ 458 463 458 463 478 463 c 0,132,133
+755 186 m 0,144,145
+ 755 166 755 166 740.5 153 c 128,-1,146
+ 726 140 726 140 708 140 c 0,147,148
+ 688 140 688 140 675 154.5 c 128,-1,149
+ 662 169 662 169 662 186 c 0,150,151
+ 662 206 662 206 676 219 c 128,-1,152
+ 690 232 690 232 708 232 c 0,153,154
+ 729 232 729 232 742 218.5 c 128,-1,155
+ 755 205 755 205 755 186 c 0,144,145
+1024 148 m 256,156,157
+ 1044 148 1044 148 1057 134.5 c 128,-1,158
+ 1070 121 1070 121 1070 102 c 0,159,160
+ 1070 82 1070 82 1057 69 c 128,-1,161
+ 1044 56 1044 56 1024 56 c 256,162,163
+ 1004 56 1004 56 990.5 69 c 128,-1,164
+ 977 82 977 82 977 102 c 0,165,166
+ 977 121 977 121 990.5 134.5 c 128,-1,167
+ 1004 148 1004 148 1024 148 c 256,156,157
+1340 232 m 0,168,169
+ 1357 232 1357 232 1371 219.5 c 128,-1,170
+ 1385 207 1385 207 1385 186 c 0,171,172
+ 1385 169 1385 169 1372 154.5 c 128,-1,173
+ 1359 140 1359 140 1339 140 c 0,174,175
+ 1322 140 1322 140 1307 153 c 128,-1,176
+ 1292 166 1292 166 1292 187 c 0,177,178
+ 1292 207 1292 207 1307 219.5 c 128,-1,179
+ 1322 232 1322 232 1340 232 c 0,168,169
+1616 417 m 0,180,181
+ 1616 396 1616 396 1601.5 383 c 128,-1,182
+ 1587 370 1587 370 1568 370 c 0,183,184
+ 1547 370 1547 370 1535 385 c 128,-1,185
+ 1523 400 1523 400 1523 417 c 0,186,187
+ 1523 437 1523 437 1537.5 450 c 128,-1,188
+ 1552 463 1552 463 1569 463 c 0,189,190
+ 1590 463 1590 463 1603 449.5 c 128,-1,191
+ 1616 436 1616 436 1616 417 c 0,180,181
+EndSplineSet
+EndChar
+
+StartChar: carriagereturn
+Encoding: 191 8629 46
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 0,0,1
+ 1240 1538 1240 1538 1427.5 1429 c 128,-1,2
+ 1615 1320 1615 1320 1722.5 1132.5 c 128,-1,3
+ 1830 945 1830 945 1830 731 c 0,4,5
+ 1830 515 1830 515 1722 328 c 128,-1,6
+ 1614 141 1614 141 1427 33 c 128,-1,7
+ 1240 -75 1240 -75 1024 -75 c 0,8,9
+ 810 -75 810 -75 622.5 32.5 c 128,-1,10
+ 435 140 435 140 326 327.5 c 128,-1,11
+ 217 515 217 515 217 731 c 0,12,13
+ 217 946 217 946 325 1134 c 128,-1,14
+ 433 1322 433 1322 621.5 1430 c 128,-1,15
+ 810 1538 810 1538 1024 1538 c 0,0,1
+1024 3 m 256,16,17
+ 1220 3 1220 3 1389 101 c 128,-1,18
+ 1558 199 1558 199 1655.5 367.5 c 128,-1,19
+ 1753 536 1753 536 1753 731 c 0,20,21
+ 1753 927 1753 927 1655 1096 c 128,-1,22
+ 1557 1265 1557 1265 1388.5 1362.5 c 128,-1,23
+ 1220 1460 1220 1460 1024 1460 c 256,24,25
+ 828 1460 828 1460 659 1362 c 128,-1,26
+ 490 1264 490 1264 392.5 1095.5 c 128,-1,27
+ 295 927 295 927 295 731 c 256,28,29
+ 295 535 295 535 393 366.5 c 128,-1,30
+ 491 198 491 198 659.5 100.5 c 128,-1,31
+ 828 3 828 3 1024 3 c 256,16,17
+1082 840 m 1,32,33
+ 1111 824 1111 824 1129 795.5 c 128,-1,34
+ 1147 767 1147 767 1147 732 c 0,35,36
+ 1147 679 1147 679 1110 643.5 c 128,-1,37
+ 1073 608 1073 608 1024 608 c 0,38,39
+ 988 608 988 608 959.5 626.5 c 128,-1,40
+ 931 645 931 645 916 674 c 1,41,-1
+ 604 674 l 1,42,-1
+ 604 790 l 1,43,-1
+ 916 790 l 1,44,45
+ 933 822 933 822 966 840 c 1,46,-1
+ 966 1396 l 1,47,-1
+ 1082 1396 l 1,48,-1
+ 1082 840 l 1,32,33
+1024 685 m 0,49,50
+ 1041 685 1041 685 1056 698.5 c 128,-1,51
+ 1071 712 1071 712 1071 731 c 256,52,53
+ 1071 750 1071 750 1057 764 c 128,-1,54
+ 1043 778 1043 778 1024 778 c 0,55,56
+ 1004 778 1004 778 990.5 764.5 c 128,-1,57
+ 977 751 977 751 977 731 c 256,58,59
+ 977 711 977 711 991 698 c 128,-1,60
+ 1005 685 1005 685 1024 685 c 0,49,50
+1654 778 m 256,61,62
+ 1674 778 1674 778 1687.5 764.5 c 128,-1,63
+ 1701 751 1701 751 1701 731 c 0,64,65
+ 1701 712 1701 712 1687.5 698.5 c 128,-1,66
+ 1674 685 1674 685 1654 685 c 256,67,68
+ 1634 685 1634 685 1620.5 698.5 c 128,-1,69
+ 1607 712 1607 712 1607 731 c 0,70,71
+ 1607 751 1607 751 1620.5 764.5 c 128,-1,72
+ 1634 778 1634 778 1654 778 c 256,61,62
+1569 1000 m 0,73,74
+ 1552 1000 1552 1000 1537.5 1013 c 128,-1,75
+ 1523 1026 1523 1026 1523 1046 c 0,76,77
+ 1523 1064 1523 1064 1536 1078.5 c 128,-1,78
+ 1549 1093 1549 1093 1569 1093 c 0,79,80
+ 1587 1093 1587 1093 1601.5 1080 c 128,-1,81
+ 1616 1067 1616 1067 1616 1047 c 0,82,83
+ 1616 1021 1616 1021 1593 1006 c 1,84,85
+ 1581 1000 1581 1000 1569 1000 c 0,73,74
+1385 1278 m 256,86,87
+ 1385 1258 1385 1258 1370.5 1244.5 c 128,-1,88
+ 1356 1231 1356 1231 1339 1231 c 0,89,90
+ 1318 1231 1318 1231 1305 1245.5 c 128,-1,91
+ 1292 1260 1292 1260 1292 1277 c 0,92,93
+ 1292 1297 1292 1297 1306.5 1310.5 c 128,-1,94
+ 1321 1324 1321 1324 1339 1324 c 0,95,96
+ 1358 1324 1358 1324 1371.5 1311 c 128,-1,97
+ 1385 1298 1385 1298 1385 1278 c 256,86,87
+709 1231 m 0,98,99
+ 690 1231 690 1231 676 1244.5 c 128,-1,100
+ 662 1258 662 1258 662 1278 c 0,101,102
+ 662 1295 662 1295 675 1309.5 c 128,-1,103
+ 688 1324 688 1324 708 1324 c 0,104,105
+ 726 1324 726 1324 740.5 1311 c 128,-1,106
+ 755 1298 755 1298 755 1277 c 0,107,108
+ 755 1257 755 1257 741 1244 c 128,-1,109
+ 727 1231 727 1231 709 1231 c 0,98,99
+524 1046 m 0,110,111
+ 524 1026 524 1026 510 1013 c 128,-1,112
+ 496 1000 496 1000 477 1000 c 0,113,114
+ 457 1000 457 1000 444 1014.5 c 128,-1,115
+ 431 1029 431 1029 431 1046 c 0,116,117
+ 431 1066 431 1066 446 1079.5 c 128,-1,118
+ 461 1093 461 1093 478 1093 c 0,119,120
+ 497 1093 497 1093 510.5 1080 c 128,-1,121
+ 524 1067 524 1067 524 1046 c 0,110,111
+393 778 m 0,122,123
+ 413 778 413 778 426.5 764.5 c 128,-1,124
+ 440 751 440 751 440 732 c 0,125,126
+ 440 712 440 712 426.5 698.5 c 128,-1,127
+ 413 685 413 685 393 685 c 0,128,129
+ 374 685 374 685 360.5 698.5 c 128,-1,130
+ 347 712 347 712 347 732 c 0,131,132
+ 347 751 347 751 360.5 764.5 c 128,-1,133
+ 374 778 374 778 393 778 c 0,122,123
+478 463 m 0,134,135
+ 495 463 495 463 509.5 450 c 128,-1,136
+ 524 437 524 437 524 416 c 0,137,138
+ 524 399 524 399 511 384.5 c 128,-1,139
+ 498 370 498 370 478 370 c 0,140,141
+ 461 370 461 370 446 383 c 128,-1,142
+ 431 396 431 396 431 417 c 0,143,144
+ 431 437 431 437 445.5 450 c 128,-1,145
+ 460 463 460 463 478 463 c 0,134,135
+755 185 m 0,146,147
+ 755 165 755 165 740.5 152 c 128,-1,148
+ 726 139 726 139 709 139 c 0,149,150
+ 689 139 689 139 675.5 153.5 c 128,-1,151
+ 662 168 662 168 662 185 c 0,152,153
+ 662 206 662 206 676.5 219 c 128,-1,154
+ 691 232 691 232 708 232 c 0,155,156
+ 720 232 720 232 732 226 c 1,157,158
+ 755 211 755 211 755 185 c 0,146,147
+1024 148 m 256,159,160
+ 1044 148 1044 148 1057 134.5 c 128,-1,161
+ 1070 121 1070 121 1070 101 c 0,162,163
+ 1070 82 1070 82 1057 68.5 c 128,-1,164
+ 1044 55 1044 55 1024 55 c 256,165,166
+ 1004 55 1004 55 990.5 68.5 c 128,-1,167
+ 977 82 977 82 977 101 c 0,168,169
+ 977 121 977 121 990.5 134.5 c 128,-1,170
+ 1004 148 1004 148 1024 148 c 256,159,160
+1339 232 m 0,171,172
+ 1356 232 1356 232 1370.5 219 c 128,-1,173
+ 1385 206 1385 206 1385 185 c 0,174,175
+ 1385 167 1385 167 1371.5 153 c 128,-1,176
+ 1358 139 1358 139 1338 139 c 0,177,178
+ 1321 139 1321 139 1306.5 152.5 c 128,-1,179
+ 1292 166 1292 166 1292 186 c 256,180,181
+ 1292 206 1292 206 1306.5 219 c 128,-1,182
+ 1321 232 1321 232 1339 232 c 0,171,172
+1616 416 m 0,183,184
+ 1616 396 1616 396 1601.5 383 c 128,-1,185
+ 1587 370 1587 370 1569 370 c 0,186,187
+ 1549 370 1549 370 1536 384.5 c 128,-1,188
+ 1523 399 1523 399 1523 416 c 0,189,190
+ 1523 437 1523 437 1537.5 450 c 128,-1,191
+ 1552 463 1552 463 1569 463 c 0,192,193
+ 1581 463 1581 463 1593 457 c 1,194,195
+ 1616 442 1616 442 1616 416 c 0,183,184
+EndSplineSet
+EndChar
+
+StartChar: aleph
+Encoding: 192 8501 47
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 0,0,1
+ 1239 1538 1239 1538 1427 1430 c 128,-1,2
+ 1615 1322 1615 1322 1723 1133.5 c 128,-1,3
+ 1831 945 1831 945 1831 731 c 0,4,5
+ 1831 515 1831 515 1722 327.5 c 128,-1,6
+ 1613 140 1613 140 1425.5 32.5 c 128,-1,7
+ 1238 -75 1238 -75 1024 -75 c 256,8,9
+ 810 -75 810 -75 622.5 32.5 c 128,-1,10
+ 435 140 435 140 326 327.5 c 128,-1,11
+ 217 515 217 515 217 731 c 0,12,13
+ 217 946 217 946 325 1134 c 128,-1,14
+ 433 1322 433 1322 621.5 1430 c 128,-1,15
+ 810 1538 810 1538 1024 1538 c 0,0,1
+1024 3 m 256,16,17
+ 1220 3 1220 3 1389 101 c 128,-1,18
+ 1558 199 1558 199 1655.5 367.5 c 128,-1,19
+ 1753 536 1753 536 1753 731 c 0,20,21
+ 1753 927 1753 927 1655 1096 c 128,-1,22
+ 1557 1265 1557 1265 1388.5 1362.5 c 128,-1,23
+ 1220 1460 1220 1460 1024 1460 c 256,24,25
+ 828 1460 828 1460 659 1362 c 128,-1,26
+ 490 1264 490 1264 392.5 1095.5 c 128,-1,27
+ 295 927 295 927 295 731 c 256,28,29
+ 295 535 295 535 393 366.5 c 128,-1,30
+ 491 198 491 198 659.5 100.5 c 128,-1,31
+ 828 3 828 3 1024 3 c 256,16,17
+1082 839 m 1,32,33
+ 1111 824 1111 824 1129 795.5 c 128,-1,34
+ 1147 767 1147 767 1147 732 c 0,35,36
+ 1147 680 1147 680 1110.5 644 c 128,-1,37
+ 1074 608 1074 608 1024 608 c 0,38,39
+ 973 608 973 608 937 644 c 128,-1,40
+ 901 680 901 680 901 735 c 1,41,-1
+ 631 891 l 1,42,-1
+ 689 992 l 1,43,-1
+ 959 836 l 1,44,-1
+ 966 839 l 1,45,-1
+ 966 1396 l 1,46,-1
+ 1082 1396 l 1,47,-1
+ 1082 839 l 1,32,33
+1024 147 m 0,48,49
+ 1044 147 1044 147 1057.5 134 c 128,-1,50
+ 1071 121 1071 121 1071 101 c 0,51,52
+ 1071 82 1071 82 1057.5 68 c 128,-1,53
+ 1044 54 1044 54 1024 54 c 0,54,55
+ 1005 54 1005 54 991 68 c 128,-1,56
+ 977 82 977 82 977 101 c 0,57,58
+ 977 121 977 121 991 134 c 128,-1,59
+ 1005 147 1005 147 1024 147 c 0,48,49
+394 778 m 256,60,61
+ 414 778 414 778 427 764.5 c 128,-1,62
+ 440 751 440 751 440 731 c 0,63,64
+ 440 712 440 712 427 698.5 c 128,-1,65
+ 414 685 414 685 394 685 c 256,66,67
+ 374 685 374 685 360.5 698.5 c 128,-1,68
+ 347 712 347 712 347 731 c 0,69,70
+ 347 751 347 751 360.5 764.5 c 128,-1,71
+ 374 778 374 778 394 778 c 256,60,61
+525 1046 m 0,72,73
+ 525 1025 525 1025 510.5 1012.5 c 128,-1,74
+ 496 1000 496 1000 478 1000 c 0,75,76
+ 458 1000 458 1000 445 1014.5 c 128,-1,77
+ 432 1029 432 1029 432 1047 c 0,78,79
+ 432 1067 432 1067 446.5 1080 c 128,-1,80
+ 461 1093 461 1093 478 1093 c 0,81,82
+ 498 1093 498 1093 511.5 1078 c 128,-1,83
+ 525 1063 525 1063 525 1046 c 0,72,73
+478 463 m 0,84,85
+ 495 463 495 463 510 450.5 c 128,-1,86
+ 525 438 525 438 525 416 c 0,87,88
+ 525 399 525 399 512 384.5 c 128,-1,89
+ 499 370 499 370 478 370 c 0,90,91
+ 461 370 461 370 446.5 383 c 128,-1,92
+ 432 396 432 396 432 416 c 0,93,94
+ 432 435 432 435 445.5 449 c 128,-1,95
+ 459 463 459 463 478 463 c 0,84,85
+1024 685 m 0,96,97
+ 1042 685 1042 685 1056.5 698 c 128,-1,98
+ 1071 711 1071 711 1071 731 c 256,99,100
+ 1071 751 1071 751 1057.5 764 c 128,-1,101
+ 1044 777 1044 777 1024 777 c 256,102,103
+ 1004 777 1004 777 990.5 764 c 128,-1,104
+ 977 751 977 751 977 731 c 256,105,106
+ 977 711 977 711 991 698 c 128,-1,107
+ 1005 685 1005 685 1024 685 c 0,96,97
+755 186 m 0,108,109
+ 755 165 755 165 740.5 152 c 128,-1,110
+ 726 139 726 139 709 139 c 0,111,112
+ 688 139 688 139 675 153.5 c 128,-1,113
+ 662 168 662 168 662 185 c 0,114,115
+ 662 205 662 205 676.5 218.5 c 128,-1,116
+ 691 232 691 232 709 232 c 0,117,118
+ 728 232 728 232 741.5 219 c 128,-1,119
+ 755 206 755 206 755 186 c 0,108,109
+1570 1000 m 256,120,121
+ 1552 1000 1552 1000 1537.5 1013.5 c 128,-1,122
+ 1523 1027 1523 1027 1523 1047 c 0,123,124
+ 1523 1064 1523 1064 1536 1078.5 c 128,-1,125
+ 1549 1093 1549 1093 1570 1093 c 0,126,127
+ 1587 1093 1587 1093 1601.5 1079.5 c 128,-1,128
+ 1616 1066 1616 1066 1616 1046 c 256,129,130
+ 1616 1026 1616 1026 1602 1013 c 128,-1,131
+ 1588 1000 1588 1000 1570 1000 c 256,120,121
+1339 232 m 0,132,133
+ 1356 232 1356 232 1370.5 218.5 c 128,-1,134
+ 1385 205 1385 205 1385 185 c 0,135,136
+ 1385 168 1385 168 1372 153.5 c 128,-1,137
+ 1359 139 1359 139 1339 139 c 0,138,139
+ 1322 139 1322 139 1307 152 c 128,-1,140
+ 1292 165 1292 165 1292 186 c 0,141,142
+ 1292 206 1292 206 1306.5 219 c 128,-1,143
+ 1321 232 1321 232 1339 232 c 0,132,133
+708 1230 m 256,144,145
+ 691 1230 691 1230 676.5 1243.5 c 128,-1,146
+ 662 1257 662 1257 662 1277 c 0,147,148
+ 662 1294 662 1294 675.5 1308.5 c 128,-1,149
+ 689 1323 689 1323 709 1323 c 0,150,151
+ 726 1323 726 1323 740.5 1310 c 128,-1,152
+ 755 1297 755 1297 755 1276 c 0,153,154
+ 755 1256 755 1256 740 1243 c 128,-1,155
+ 725 1230 725 1230 708 1230 c 256,144,145
+1616 417 m 0,156,157
+ 1616 396 1616 396 1601.5 383 c 128,-1,158
+ 1587 370 1587 370 1570 370 c 0,159,160
+ 1549 370 1549 370 1536 384 c 128,-1,161
+ 1523 398 1523 398 1523 415 c 0,162,163
+ 1523 436 1523 436 1538 449 c 128,-1,164
+ 1553 462 1553 462 1571 462 c 0,165,166
+ 1590 462 1590 462 1603 449.5 c 128,-1,167
+ 1616 437 1616 437 1616 417 c 0,156,157
+1654 777 m 0,168,169
+ 1674 777 1674 777 1687.5 764 c 128,-1,170
+ 1701 751 1701 751 1701 731 c 0,171,172
+ 1701 712 1701 712 1687.5 698.5 c 128,-1,173
+ 1674 685 1674 685 1654 685 c 0,174,175
+ 1635 685 1635 685 1621.5 698.5 c 128,-1,176
+ 1608 712 1608 712 1608 731 c 0,177,178
+ 1608 751 1608 751 1621.5 764 c 128,-1,179
+ 1635 777 1635 777 1654 777 c 0,168,169
+1385 1277 m 256,180,181
+ 1385 1257 1385 1257 1370.5 1243.5 c 128,-1,182
+ 1356 1230 1356 1230 1339 1230 c 0,183,184
+ 1319 1230 1319 1230 1306 1245 c 128,-1,185
+ 1293 1260 1293 1260 1293 1277 c 0,186,187
+ 1293 1297 1293 1297 1307 1310 c 128,-1,188
+ 1321 1323 1321 1323 1338 1323 c 0,189,190
+ 1357 1323 1357 1323 1371 1310 c 128,-1,191
+ 1385 1297 1385 1297 1385 1277 c 256,180,181
+EndSplineSet
+EndChar
+
+StartChar: Ifraktur
+Encoding: 193 8465 48
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 256,0,1
+ 1238 1538 1238 1538 1425.5 1430.5 c 128,-1,2
+ 1613 1323 1613 1323 1722 1135.5 c 128,-1,3
+ 1831 948 1831 948 1831 732 c 256,4,5
+ 1831 516 1831 516 1722 328.5 c 128,-1,6
+ 1613 141 1613 141 1425.5 33.5 c 128,-1,7
+ 1238 -74 1238 -74 1024 -74 c 256,8,9
+ 810 -74 810 -74 622.5 33.5 c 128,-1,10
+ 435 141 435 141 326 328.5 c 128,-1,11
+ 217 516 217 516 217 732 c 256,12,13
+ 217 948 217 948 326 1135.5 c 128,-1,14
+ 435 1323 435 1323 622.5 1430.5 c 128,-1,15
+ 810 1538 810 1538 1024 1538 c 256,0,1
+1024 3 m 256,16,17
+ 1220 3 1220 3 1389 101 c 128,-1,18
+ 1558 199 1558 199 1655.5 367.5 c 128,-1,19
+ 1753 536 1753 536 1753 732 c 256,20,21
+ 1753 928 1753 928 1655 1097 c 128,-1,22
+ 1557 1266 1557 1266 1388.5 1363.5 c 128,-1,23
+ 1220 1461 1220 1461 1024 1461 c 256,24,25
+ 828 1461 828 1461 659 1363 c 128,-1,26
+ 490 1265 490 1265 392.5 1096.5 c 128,-1,27
+ 295 928 295 928 295 732 c 256,28,29
+ 295 536 295 536 393 367 c 128,-1,30
+ 491 198 491 198 659.5 100.5 c 128,-1,31
+ 828 3 828 3 1024 3 c 256,16,17
+1082 841 m 1,32,33
+ 1111 825 1111 825 1129 796 c 128,-1,34
+ 1147 767 1147 767 1147 732 c 0,35,36
+ 1147 681 1147 681 1111 645 c 128,-1,37
+ 1075 609 1075 609 1024 609 c 256,38,39
+ 973 609 973 609 937 645 c 128,-1,40
+ 901 681 901 681 901 732 c 0,41,42
+ 901 768 901 768 919 797 c 1,43,-1
+ 764 1067 l 1,44,-1
+ 865 1125 l 1,45,-1
+ 966 949 l 1,46,-1
+ 966 1397 l 1,47,-1
+ 1082 1397 l 1,48,-1
+ 1082 841 l 1,32,33
+1024 686 m 0,49,50
+ 1047 686 1047 686 1059 701 c 128,-1,51
+ 1071 716 1071 716 1071 732 c 0,52,53
+ 1071 751 1071 751 1057.5 765 c 128,-1,54
+ 1044 779 1044 779 1024 779 c 256,55,56
+ 1004 779 1004 779 990.5 765 c 128,-1,57
+ 977 751 977 751 977 732 c 0,58,59
+ 977 711 977 711 991 698.5 c 128,-1,60
+ 1005 686 1005 686 1024 686 c 0,49,50
+1654 779 m 0,61,62
+ 1674 779 1674 779 1687.5 765 c 128,-1,63
+ 1701 751 1701 751 1701 732 c 0,64,65
+ 1701 712 1701 712 1687.5 699 c 128,-1,66
+ 1674 686 1674 686 1654 686 c 0,67,68
+ 1635 686 1635 686 1621.5 699 c 128,-1,69
+ 1608 712 1608 712 1608 732 c 0,70,71
+ 1608 751 1608 751 1621.5 765 c 128,-1,72
+ 1635 779 1635 779 1654 779 c 0,61,62
+1570 1001 m 0,73,74
+ 1553 1001 1553 1001 1538 1014 c 128,-1,75
+ 1523 1027 1523 1027 1523 1048 c 0,76,77
+ 1523 1065 1523 1065 1536.5 1079 c 128,-1,78
+ 1550 1093 1550 1093 1571 1093 c 0,79,80
+ 1588 1093 1588 1093 1602 1080 c 128,-1,81
+ 1616 1067 1616 1067 1616 1047 c 256,82,83
+ 1616 1027 1616 1027 1602 1014 c 128,-1,84
+ 1588 1001 1588 1001 1570 1001 c 0,73,74
+1385 1278 m 256,85,86
+ 1385 1258 1385 1258 1371 1244.5 c 128,-1,87
+ 1357 1231 1357 1231 1338 1231 c 0,88,89
+ 1318 1231 1318 1231 1305.5 1246 c 128,-1,90
+ 1293 1261 1293 1261 1293 1278 c 0,91,92
+ 1293 1298 1293 1298 1307.5 1311 c 128,-1,93
+ 1322 1324 1322 1324 1339 1324 c 0,94,95
+ 1358 1324 1358 1324 1371.5 1311 c 128,-1,96
+ 1385 1298 1385 1298 1385 1278 c 256,85,86
+709 1324 m 0,97,98
+ 726 1324 726 1324 740.5 1310.5 c 128,-1,99
+ 755 1297 755 1297 755 1277 c 0,100,101
+ 755 1260 755 1260 743 1245.5 c 128,-1,102
+ 731 1231 731 1231 710 1231 c 0,103,104
+ 691 1231 691 1231 676.5 1244.5 c 128,-1,105
+ 662 1258 662 1258 662 1278 c 0,106,107
+ 662 1297 662 1297 675.5 1310.5 c 128,-1,108
+ 689 1324 689 1324 709 1324 c 0,97,98
+525 1047 m 0,109,110
+ 525 1026 525 1026 510.5 1013.5 c 128,-1,111
+ 496 1001 496 1001 478 1001 c 0,112,113
+ 458 1001 458 1001 445 1015.5 c 128,-1,114
+ 432 1030 432 1030 432 1047 c 0,115,116
+ 432 1068 432 1068 446 1080.5 c 128,-1,117
+ 460 1093 460 1093 477 1093 c 0,118,119
+ 497 1093 497 1093 511 1079.5 c 128,-1,120
+ 525 1066 525 1066 525 1047 c 0,109,110
+394 779 m 256,121,122
+ 414 779 414 779 427 765.5 c 128,-1,123
+ 440 752 440 752 440 732 c 256,124,125
+ 440 712 440 712 427 699 c 128,-1,126
+ 414 686 414 686 394 686 c 256,127,128
+ 374 686 374 686 360.5 699 c 128,-1,129
+ 347 712 347 712 347 732 c 256,130,131
+ 347 752 347 752 360.5 765.5 c 128,-1,132
+ 374 779 374 779 394 779 c 256,121,122
+478 463 m 256,133,134
+ 496 463 496 463 510.5 450.5 c 128,-1,135
+ 525 438 525 438 525 417 c 0,136,137
+ 525 400 525 400 512.5 385 c 128,-1,138
+ 500 370 500 370 479 370 c 0,139,140
+ 462 370 462 370 447 383 c 128,-1,141
+ 432 396 432 396 432 417 c 0,142,143
+ 432 437 432 437 446 450 c 128,-1,144
+ 460 463 460 463 478 463 c 256,133,134
+755 187 m 0,145,146
+ 755 166 755 166 740.5 153 c 128,-1,147
+ 726 140 726 140 709 140 c 0,148,149
+ 688 140 688 140 675 154 c 128,-1,150
+ 662 168 662 168 662 185 c 0,151,152
+ 662 206 662 206 676.5 219 c 128,-1,153
+ 691 232 691 232 708 232 c 0,154,155
+ 728 232 728 232 741.5 219.5 c 128,-1,156
+ 755 207 755 207 755 187 c 0,145,146
+1024 148 m 0,157,158
+ 1044 148 1044 148 1057.5 134.5 c 128,-1,159
+ 1071 121 1071 121 1071 102 c 0,160,161
+ 1071 82 1071 82 1058 69 c 128,-1,162
+ 1045 56 1045 56 1026 56 c 0,163,164
+ 1006 56 1006 56 991.5 69 c 128,-1,165
+ 977 82 977 82 977 102 c 0,166,167
+ 977 121 977 121 991 134.5 c 128,-1,168
+ 1005 148 1005 148 1024 148 c 0,157,158
+1339 232 m 0,169,170
+ 1356 232 1356 232 1370.5 219 c 128,-1,171
+ 1385 206 1385 206 1385 185 c 0,172,173
+ 1385 168 1385 168 1372 154 c 128,-1,174
+ 1359 140 1359 140 1339 140 c 0,175,176
+ 1322 140 1322 140 1307 153 c 128,-1,177
+ 1292 166 1292 166 1292 186 c 256,178,179
+ 1292 206 1292 206 1306.5 219 c 128,-1,180
+ 1321 232 1321 232 1339 232 c 0,169,170
+1616 417 m 256,181,182
+ 1616 397 1616 397 1601 383.5 c 128,-1,183
+ 1586 370 1586 370 1569 370 c 0,184,185
+ 1548 370 1548 370 1535.5 384.5 c 128,-1,186
+ 1523 399 1523 399 1523 416 c 0,187,188
+ 1523 436 1523 436 1538 449.5 c 128,-1,189
+ 1553 463 1553 463 1570 463 c 0,190,191
+ 1589 463 1589 463 1602.5 450 c 128,-1,192
+ 1616 437 1616 437 1616 417 c 256,181,182
+EndSplineSet
+EndChar
+
+StartChar: Rfraktur
+Encoding: 194 8476 49
+Width: 2048
+Flags: W
+LayerCount: 2
+Fore
+SplineSet
+1024 1538 m 0,0,1
+ 1239 1538 1239 1538 1427 1430 c 128,-1,2
+ 1615 1322 1615 1322 1723 1133.5 c 128,-1,3
+ 1831 945 1831 945 1831 731 c 0,4,5
+ 1831 516 1831 516 1723 328 c 128,-1,6
+ 1615 140 1615 140 1426.5 32 c 128,-1,7
+ 1238 -76 1238 -76 1024 -76 c 0,8,9
+ 809 -76 809 -76 621 32 c 128,-1,10
+ 433 140 433 140 325 328.5 c 128,-1,11
+ 217 517 217 517 217 731 c 0,12,13
+ 217 946 217 946 325 1134 c 128,-1,14
+ 433 1322 433 1322 621.5 1430 c 128,-1,15
+ 810 1538 810 1538 1024 1538 c 0,0,1
+1024 2 m 256,16,17
+ 1220 2 1220 2 1389 100 c 128,-1,18
+ 1558 198 1558 198 1655.5 366.5 c 128,-1,19
+ 1753 535 1753 535 1753 731 c 256,20,21
+ 1753 927 1753 927 1655 1096 c 128,-1,22
+ 1557 1265 1557 1265 1388.5 1362.5 c 128,-1,23
+ 1220 1460 1220 1460 1024 1460 c 256,24,25
+ 828 1460 828 1460 659 1362 c 128,-1,26
+ 490 1264 490 1264 392.5 1095.5 c 128,-1,27
+ 295 927 295 927 295 731 c 256,28,29
+ 295 535 295 535 393 366 c 128,-1,30
+ 491 197 491 197 659.5 99.5 c 128,-1,31
+ 828 2 828 2 1024 2 c 256,16,17
+1099 828 m 1,32,33
+ 1147 793 1147 793 1147 731 c 0,34,35
+ 1147 680 1147 680 1111 644 c 128,-1,36
+ 1075 608 1075 608 1024 608 c 256,37,38
+ 973 608 973 608 937 644 c 128,-1,39
+ 901 680 901 680 901 731 c 0,40,41
+ 901 791 901 791 949 828 c 1,42,-1
+ 949 1162 l 1,43,-1
+ 966 1162 l 1,44,-1
+ 966 1396 l 1,45,-1
+ 1082 1396 l 1,46,-1
+ 1082 1162 l 1,47,-1
+ 1099 1162 l 1,48,-1
+ 1099 828 l 1,32,33
+977 731 m 0,49,50
+ 977 713 977 713 991 698.5 c 128,-1,51
+ 1005 684 1005 684 1024 684 c 256,52,53
+ 1043 684 1043 684 1057 697 c 128,-1,54
+ 1071 710 1071 710 1071 731 c 0,55,56
+ 1071 750 1071 750 1057.5 763.5 c 128,-1,57
+ 1044 777 1044 777 1024 777 c 0,58,59
+ 1005 777 1005 777 991 764 c 128,-1,60
+ 977 751 977 751 977 731 c 0,49,50
+1654 777 m 0,61,62
+ 1674 777 1674 777 1687.5 764 c 128,-1,63
+ 1701 751 1701 751 1701 731 c 256,64,65
+ 1701 711 1701 711 1687.5 697.5 c 128,-1,66
+ 1674 684 1674 684 1654 684 c 0,67,68
+ 1635 684 1635 684 1621.5 697.5 c 128,-1,69
+ 1608 711 1608 711 1608 731 c 256,70,71
+ 1608 751 1608 751 1621.5 764 c 128,-1,72
+ 1635 777 1635 777 1654 777 c 0,61,62
+1569 999 m 256,73,74
+ 1552 999 1552 999 1537.5 1012.5 c 128,-1,75
+ 1523 1026 1523 1026 1523 1046 c 0,76,77
+ 1523 1063 1523 1063 1536.5 1077.5 c 128,-1,78
+ 1550 1092 1550 1092 1570 1092 c 0,79,80
+ 1587 1092 1587 1092 1601.5 1079 c 128,-1,81
+ 1616 1066 1616 1066 1616 1045 c 0,82,83
+ 1616 1025 1616 1025 1601 1012 c 128,-1,84
+ 1586 999 1586 999 1569 999 c 256,73,74
+1385 1277 m 0,85,86
+ 1385 1256 1385 1256 1370.5 1243 c 128,-1,87
+ 1356 1230 1356 1230 1339 1230 c 0,88,89
+ 1319 1230 1319 1230 1306 1244 c 128,-1,90
+ 1293 1258 1293 1258 1293 1276 c 0,91,92
+ 1293 1297 1293 1297 1307 1310 c 128,-1,93
+ 1321 1323 1321 1323 1338 1323 c 0,94,95
+ 1357 1323 1357 1323 1371 1310 c 128,-1,96
+ 1385 1297 1385 1297 1385 1277 c 0,85,86
+709 1323 m 0,97,98
+ 726 1323 726 1323 740.5 1310 c 128,-1,99
+ 755 1297 755 1297 755 1276 c 0,100,101
+ 755 1259 755 1259 741.5 1244.5 c 128,-1,102
+ 728 1230 728 1230 708 1230 c 0,103,104
+ 691 1230 691 1230 676.5 1243 c 128,-1,105
+ 662 1256 662 1256 662 1277 c 0,106,107
+ 662 1297 662 1297 676.5 1310 c 128,-1,108
+ 691 1323 691 1323 709 1323 c 0,97,98
+525 1045 m 0,109,110
+ 525 1024 525 1024 510.5 1011.5 c 128,-1,111
+ 496 999 496 999 479 999 c 0,112,113
+ 459 999 459 999 445.5 1013.5 c 128,-1,114
+ 432 1028 432 1028 432 1046 c 0,115,116
+ 432 1066 432 1066 446 1079 c 128,-1,117
+ 460 1092 460 1092 477 1092 c 0,118,119
+ 489 1092 489 1092 501 1086 c 1,120,121
+ 525 1071 525 1071 525 1045 c 0,109,110
+394 777 m 256,122,123
+ 414 777 414 777 427 764 c 128,-1,124
+ 440 751 440 751 440 731 c 256,125,126
+ 440 711 440 711 427 697.5 c 128,-1,127
+ 414 684 414 684 394 684 c 256,128,129
+ 374 684 374 684 360.5 697.5 c 128,-1,130
+ 347 711 347 711 347 731 c 256,131,132
+ 347 751 347 751 360.5 764 c 128,-1,133
+ 374 777 374 777 394 777 c 256,122,123
+478 462 m 256,134,135
+ 496 462 496 462 510.5 449.5 c 128,-1,136
+ 525 437 525 437 525 416 c 0,137,138
+ 525 399 525 399 511.5 384 c 128,-1,139
+ 498 369 498 369 477 369 c 0,140,141
+ 460 369 460 369 446 382 c 128,-1,142
+ 432 395 432 395 432 416 c 0,143,144
+ 432 436 432 436 446 449 c 128,-1,145
+ 460 462 460 462 478 462 c 256,134,135
+755 186 m 0,146,147
+ 755 165 755 165 740.5 151.5 c 128,-1,148
+ 726 138 726 138 709 138 c 0,149,150
+ 689 138 689 138 675.5 152.5 c 128,-1,151
+ 662 167 662 167 662 184 c 0,152,153
+ 662 205 662 205 676.5 218 c 128,-1,154
+ 691 231 691 231 708 231 c 0,155,156
+ 728 231 728 231 741.5 218.5 c 128,-1,157
+ 755 206 755 206 755 186 c 0,146,147
+1024 147 m 0,158,159
+ 1044 147 1044 147 1057.5 134 c 128,-1,160
+ 1071 121 1071 121 1071 101 c 256,161,162
+ 1071 81 1071 81 1057.5 67.5 c 128,-1,163
+ 1044 54 1044 54 1024 54 c 0,164,165
+ 1005 54 1005 54 991 67.5 c 128,-1,166
+ 977 81 977 81 977 101 c 256,167,168
+ 977 121 977 121 991 134 c 128,-1,169
+ 1005 147 1005 147 1024 147 c 0,158,159
+1339 231 m 256,170,171
+ 1356 231 1356 231 1370.5 217.5 c 128,-1,172
+ 1385 204 1385 204 1385 184 c 0,173,174
+ 1385 167 1385 167 1372 152.5 c 128,-1,175
+ 1359 138 1359 138 1338 138 c 0,176,177
+ 1321 138 1321 138 1306.5 151.5 c 128,-1,178
+ 1292 165 1292 165 1292 186 c 0,179,180
+ 1292 206 1292 206 1307 218.5 c 128,-1,181
+ 1322 231 1322 231 1339 231 c 256,170,171
+1616 416 m 256,182,183
+ 1616 396 1616 396 1601.5 382.5 c 128,-1,184
+ 1587 369 1587 369 1570 369 c 0,185,186
+ 1550 369 1550 369 1536.5 383.5 c 128,-1,187
+ 1523 398 1523 398 1523 415 c 0,188,189
+ 1523 435 1523 435 1538 448.5 c 128,-1,190
+ 1553 462 1553 462 1570 462 c 0,191,192
+ 1589 462 1589 462 1602.5 449 c 128,-1,193
+ 1616 436 1616 436 1616 416 c 256,182,183
+EndSplineSet
+EndChar
EndChars
EndSplineFont
--
2.16.3
June 22, 2018
Re: [PATCH] d2d1: Stop redefination on older compilers
by Henri Verbeet
On 22 June 2018 at 06:30, Alistair Leslie-Hughes
<leslie_alistair(a)hotmail.com> wrote:
> Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
> ---
> dlls/d2d1/d2d1_private.h | 3 ++-
> dlls/d2d1/tests/d2d1.c | 7 ++++---
> 2 files changed, 6 insertions(+), 4 deletions(-)
>
What are you trying to fix exactly?
June 22, 2018
[PATCH] gdi32: Add a workaround for A->W text output with Symbol font encoding.
by Dmitry Timoshkov
There are 2 ways to output Ansi text:
1. Call DrawTextA/ExtTextOutA, it uses font codepage for unicode translation.
2. hfont = CreateFont("Wingdings", SYMBOL_CHARSET);
SendMessageA(hwnd, WM_SETFONT, hfont);
SendMessageA(hwnd, WM_SETTEXT, textA);
It uses current ANSI codepage for unicode translation.
Currently #1 works correctly for Symbol fonts but #2 does not. This patch
makes #2 work as well. Since this is a text drawing bug I don't see a way
of adding a test case for this behaviour.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/gdi32/freetype.c | 48 +++++++++++++++++++++++++++++++++++-------------
1 file changed, 35 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 1293e08a73..ba1839af82 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -6303,24 +6303,44 @@ static FT_UInt get_GSUB_vert_glyph(const GdiFont *font, UINT glyph)
return GSUB_apply_feature(header, feature, glyph);
}
+static FT_UInt get_glyph_index_symbol(const GdiFont *font, UINT glyph)
+{
+ FT_UInt ret;
+
+ if (glyph < 0x100) glyph += 0xf000;
+ /* there is a number of old pre-Unicode "broken" TTFs, which
+ do have symbols at U+00XX instead of U+f0XX */
+ if (!(ret = pFT_Get_Char_Index(font->ft_face, glyph)))
+ ret = pFT_Get_Char_Index(font->ft_face, glyph - 0xf000);
+
+ return ret;
+}
+
static FT_UInt get_glyph_index(const GdiFont *font, UINT glyph)
{
- FT_UInt glyphId;
+ FT_UInt ret;
+ WCHAR wc;
+ char buf;
if(font->ft_face->charmap->encoding == FT_ENCODING_NONE) {
- WCHAR wc = (WCHAR)glyph;
BOOL default_used;
BOOL *default_used_pointer;
- FT_UInt ret;
- char buf;
default_used_pointer = NULL;
default_used = FALSE;
if (codepage_sets_default_used(font->codepage))
default_used_pointer = &default_used;
+ wc = (WCHAR)glyph;
if(!WideCharToMultiByte(font->codepage, 0, &wc, 1, &buf, sizeof(buf), NULL, default_used_pointer) || default_used)
{
- if (font->codepage == CP_SYMBOL && wc < 0x100)
- ret = pFT_Get_Char_Index(font->ft_face, (unsigned char)wc);
+ if (font->codepage == CP_SYMBOL)
+ {
+ ret = get_glyph_index_symbol(font, glyph);
+ if (!ret)
+ {
+ if (WideCharToMultiByte(CP_ACP, 0, &wc, 1, &buf, 1, NULL, NULL))
+ ret = get_glyph_index_symbol(font, buf);
+ }
+ }
else
ret = 0;
}
@@ -6332,15 +6352,17 @@ static FT_UInt get_glyph_index(const GdiFont *font, UINT glyph)
if(font->ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL)
{
- if (glyph < 0x100) glyph += 0xf000;
- /* there is a number of old pre-Unicode "broken" TTFs, which
- do have symbols at U+00XX instead of U+f0XX */
- if (!(glyphId = pFT_Get_Char_Index(font->ft_face, glyph)))
- glyphId = pFT_Get_Char_Index(font->ft_face, glyph-0xf000);
+ ret = get_glyph_index_symbol(font, glyph);
+ if (!ret)
+ {
+ wc = (WCHAR)glyph;
+ if (WideCharToMultiByte(CP_ACP, 0, &wc, 1, &buf, 1, NULL, NULL))
+ ret = get_glyph_index_symbol(font, (unsigned char)buf);
+ }
+ return ret;
}
- else glyphId = pFT_Get_Char_Index(font->ft_face, glyph);
- return glyphId;
+ return pFT_Get_Char_Index(font->ft_face, glyph);
}
/* helper for freetype_GetGlyphIndices */
--
2.16.3
June 22, 2018
[PATCH] d2d1: Stop redefination on older compilers
by Alistair Leslie-Hughes
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/d2d1/d2d1_private.h | 3 ++-
dlls/d2d1/tests/d2d1.c | 7 ++++---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/dlls/d2d1/d2d1_private.h b/dlls/d2d1/d2d1_private.h
index d754e85..2281eef 100644
--- a/dlls/d2d1/d2d1_private.h
+++ b/dlls/d2d1/d2d1_private.h
@@ -25,11 +25,12 @@
#include <assert.h>
#include <limits.h>
#define COBJMACROS
-#include "d2d1_1.h"
+
#ifdef D2D1_INIT_GUID
#include "initguid.h"
#endif
#include "dwrite_2.h"
+#include "d2d1_1.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0]))
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 26c81e6..e89d0e9 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -19,12 +19,13 @@
#define COBJMACROS
#include <limits.h>
#include <math.h>
-#include "d2d1_1.h"
-#include "wincrypt.h"
-#include "wine/test.h"
#include "initguid.h"
#include "dwrite.h"
+#include "d2d1_1.h"
#include "wincodec.h"
+#include "wincrypt.h"
+
+#include "wine/test.h"
struct resource_readback
{
--
1.9.1
June 22, 2018
[v2 PATCH] ntdll: Implement LdrRegisterDllNotification and LdrUnregisterDllNotification.
by Alistair Leslie-Hughes
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/ntdll/loader.c | 77 ++++++++++++++-
dlls/ntdll/tests/rtl.c | 261 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 334 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 3e00ec6..df206e8 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -40,6 +40,7 @@
#include "wine/library.h"
#include "wine/unicode.h"
#include "wine/debug.h"
+#include "wine/list.h"
#include "wine/server.h"
#include "ntdll_misc.h"
#include "ddk/wdm.h"
@@ -71,6 +72,15 @@ static BOOL imports_fixup_done = FALSE; /* set once the imports have been fixed
static BOOL process_detaching = FALSE; /* set on process detach to avoid deadlocks with thread detach */
static int free_lib_count; /* recursion depth of LdrUnloadDll calls */
+struct ldr_notification
+{
+ struct list entry;
+ PLDR_DLL_NOTIFICATION_FUNCTION callback;
+ void *context;
+};
+
+static struct list ldr_notifications = LIST_INIT( ldr_notifications );
+
static const char * const reason_names[] =
{
"PROCESS_DETACH",
@@ -342,6 +352,29 @@ static ULONG_PTR allocate_stub( const char *dll, const char *name )
static inline ULONG_PTR allocate_stub( const char *dll, const char *name ) { return 0xdeadbeef; }
#endif /* __i386__ */
+/* call ldr notifications */
+static void call_ldr_notifications( ULONG reason, LDR_MODULE *module )
+{
+ struct ldr_notification *notify, *notify_next;
+ LDR_DLL_NOTIFICATION_DATA data;
+
+ data.Loaded.Flags = 0;
+ data.Loaded.FullDllName = &module->FullDllName;
+ data.Loaded.BaseDllName = &module->BaseDllName;
+ data.Loaded.DllBase = module->BaseAddress;
+ data.Loaded.SizeOfImage = module->SizeOfImage;
+
+ LIST_FOR_EACH_ENTRY_SAFE( notify, notify_next, &ldr_notifications, struct ldr_notification, entry )
+ {
+ TRACE_(relay)("\1Call LDR notification callback (proc=%p,reason=%u,data=%p,context=%p)\n",
+ notify->callback, reason, &data, notify->context );
+
+ notify->callback(reason, &data, notify->context);
+
+ TRACE_(relay)("\1Ret LDR notification callback (proc=%p,reason=%u,data=%p,context=%p)\n",
+ notify->callback, reason, &data, notify->context );
+ }
+}
/*************************************************************************
* get_modref
@@ -1275,12 +1308,18 @@ static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved )
{
WINE_MODREF *prev = current_modref;
current_modref = wm;
+
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_LOADED, &wm->ldr );
status = MODULE_InitDLL( wm, DLL_PROCESS_ATTACH, lpReserved );
if (status == STATUS_SUCCESS)
+ {
wm->ldr.Flags |= LDR_PROCESS_ATTACHED;
+ }
else
{
MODULE_InitDLL( wm, DLL_PROCESS_DETACH, lpReserved );
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_UNLOADED, &wm->ldr );
+
/* point to the name so LdrInitializeThunk can print it */
last_failed_modref = wm;
WARN("Initialization of %s failed\n", debugstr_w(wm->ldr.BaseDllName.Buffer));
@@ -1353,6 +1392,7 @@ static void process_detach(void)
mod->Flags &= ~LDR_PROCESS_ATTACHED;
MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr),
DLL_PROCESS_DETACH, ULongToPtr(process_detaching) );
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_UNLOADED, mod );
/* Restart at head of WINE_MODREF list, as entries might have
been added and/or removed while performing the call ... */
@@ -1467,8 +1507,27 @@ NTSTATUS WINAPI LdrEnumerateLoadedModules( void *unknown, LDRENUMPROC callback,
NTSTATUS WINAPI LdrRegisterDllNotification(ULONG flags, PLDR_DLL_NOTIFICATION_FUNCTION callback,
void *context, void **cookie)
{
- FIXME( "(%04x, %p, %p, %p) stub\n", flags, callback, context, cookie );
- return STATUS_NOT_IMPLEMENTED;
+ struct ldr_notification *notify;
+
+ TRACE( "(%x, %p, %p, %p)\n", flags, callback, context, cookie );
+
+ if (!callback || !cookie)
+ return STATUS_INVALID_PARAMETER;
+
+ if (flags)
+ FIXME( "ignoring flags %x\n", flags );
+
+ notify = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*notify) );
+ if (!notify) return STATUS_NO_MEMORY;
+ notify->callback = callback;
+ notify->context = context;
+
+ RtlEnterCriticalSection( &loader_section );
+ list_add_tail( &ldr_notifications, ¬ify->entry );
+ RtlLeaveCriticalSection( &loader_section );
+
+ *cookie = notify;
+ return STATUS_SUCCESS;
}
/******************************************************************
@@ -1476,8 +1535,18 @@ NTSTATUS WINAPI LdrRegisterDllNotification(ULONG flags, PLDR_DLL_NOTIFICATION_FU
*/
NTSTATUS WINAPI LdrUnregisterDllNotification( void *cookie )
{
- FIXME( "(%p) stub\n", cookie );
- return STATUS_NOT_IMPLEMENTED;
+ struct ldr_notification *notify = cookie;
+
+ TRACE( "(%p)\n", cookie );
+
+ if (!notify) return STATUS_INVALID_PARAMETER;
+
+ RtlEnterCriticalSection( &loader_section );
+ list_remove( ¬ify->entry );
+ RtlLeaveCriticalSection( &loader_section );
+
+ RtlFreeHeap( GetProcessHeap(), 0, notify );
+ return STATUS_SUCCESS;
}
/******************************************************************
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index e202408..881bc1a 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -101,6 +101,8 @@ static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, U
static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *);
static NTSTATUS (WINAPI *pRtlMakeSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
static NTSTATUS (WINAPI *pRtlAbsoluteToSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PULONG);
+static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **);
+static NTSTATUS (WINAPI *pLdrUnregisterDllNotification)(void *);
static HMODULE hkernel32 = 0;
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
@@ -108,10 +110,15 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
#define LEN 16
static const char* src_src = "This is a test!"; /* 16 bytes long, incl NUL */
+static WCHAR ws2_32dllW[] = {'w','s','2','_','3','2','.','d','l','l',0};
+static WCHAR nsidllW[] = {'n','s','i','.','d','l','l',0};
+static WCHAR wintrustdllW[] = {'w','i','n','t','r','u','s','t','.','d','l','l',0};
+static WCHAR crypt32dllW[] = {'c','r','y','p','t','3','2','.','d','l','l',0};
static ULONG src_aligned_block[4];
static ULONG dest_aligned_block[32];
static const char *src = (const char*)src_aligned_block;
static char* dest = (char*)dest_aligned_block;
+const WCHAR *expected_dll = nsidllW;
static void InitFunctionPtrs(void)
{
@@ -157,6 +164,8 @@ static void InitFunctionPtrs(void)
pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules");
pRtlMakeSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlMakeSelfRelativeSD");
pRtlAbsoluteToSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlAbsoluteToSelfRelativeSD");
+ pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification");
+ pLdrUnregisterDllNotification = (void *)GetProcAddress(hntdll, "LdrUnregisterDllNotification");
}
hkernel32 = LoadLibraryA("kernel32.dll");
ok(hkernel32 != 0, "LoadLibrary failed\n");
@@ -2257,6 +2266,257 @@ static void test_RtlMakeSelfRelativeSD(void)
ok( status == STATUS_BAD_DESCRIPTOR_FORMAT, "got %08x\n", status );
}
+static DWORD (CALLBACK *orig_entry)(HMODULE,DWORD,LPVOID);
+static DWORD *dll_main_data;
+
+static inline void *get_rva( HMODULE module, DWORD va )
+{
+ return (void *)((char *)module + va);
+}
+
+static void CALLBACK ldr_notify_callback1(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ const IMAGE_IMPORT_DESCRIPTOR *imports;
+ const IMAGE_THUNK_DATA *import_list;
+ IMAGE_THUNK_DATA *thunk_list;
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+ ULONG size;
+ int i, j;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, expected_dll))
+ return;
+
+ ok(data->Loaded.Flags == 0, "Expected flags 0, got %x\n", data->Loaded.Flags);
+ ok(!lstrcmpiW(data->Loaded.BaseDllName->Buffer, expected_dll), "Expected %s, got %s\n",
+ wine_dbgstr_w(expected_dll), wine_dbgstr_w(data->Loaded.BaseDllName->Buffer));
+ ok(!!data->Loaded.DllBase, "Expected non zero base address\n");
+ ok(data->Loaded.SizeOfImage, "Expected non zero image size\n");
+
+ /* expect module to be last module listed in LdrData load order list */
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ ok(!lstrcmpiW(mod->BaseDllName.Buffer, expected_dll), "Expected %s, got %s\n",
+ wine_dbgstr_w(expected_dll), wine_dbgstr_w(mod->BaseDllName.Buffer));
+
+ /* show that imports have already been resolved */
+ imports = RtlImageDirectoryEntryToData(data->Loaded.DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
+ ok(!!imports, "Expected dll to have imports\n");
+
+ for (i = 0; imports[i].Name; i++)
+ {
+ thunk_list = get_rva(data->Loaded.DllBase, (DWORD)imports[i].FirstThunk);
+ if (imports[i].OriginalFirstThunk)
+ import_list = get_rva(data->Loaded.DllBase, (DWORD)imports[i].OriginalFirstThunk);
+ else
+ import_list = thunk_list;
+
+ for (j = 0; import_list[j].u1.Ordinal; j++)
+ {
+ ok(thunk_list[j].u1.AddressOfData > data->Loaded.SizeOfImage,
+ "Import has not been resolved: %p\n", (void*)thunk_list[j].u1.Function);
+ }
+ }
+}
+
+static void CALLBACK ldr_notify_callback2(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ *calls <<= 4;
+ *calls |= reason + 2;
+}
+
+static BOOL WINAPI fake_dll_main(HINSTANCE instance, DWORD reason, void* reserved)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 3;
+ }
+ else if (reason == DLL_PROCESS_DETACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 4;
+ }
+ return orig_entry(instance, reason, reserved);
+}
+
+static void CALLBACK ldr_notify_callback_dll_main(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ if (mod->BaseAddress != data->Loaded.DllBase)
+ return;
+
+ orig_entry = mod->EntryPoint;
+ mod->EntryPoint = fake_dll_main;
+ dll_main_data = calls;
+}
+
+static BOOL WINAPI fake_dll_main_fail(HINSTANCE instance, DWORD reason, void* reserved)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 3;
+ }
+ else if (reason == DLL_PROCESS_DETACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 4;
+ }
+ return FALSE;
+}
+
+static void CALLBACK ldr_notify_callback_fail(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ if (mod->BaseAddress != data->Loaded.DllBase)
+ return;
+
+ orig_entry = mod->EntryPoint;
+ mod->EntryPoint = fake_dll_main_fail;
+ dll_main_data = calls;
+}
+
+static void CALLBACK ldr_notify_callback_imports(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, crypt32dllW))
+ {
+ *calls <<= 4;
+ *calls |= 1;
+ }
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, wintrustdllW))
+ {
+ *calls <<= 4;
+ *calls |= 2;
+ }
+}
+
+static void test_LdrRegisterDllNotification(void)
+{
+ void *cookie, *cookie2;
+ NTSTATUS status;
+ HMODULE mod;
+ DWORD calls;
+
+ if (!pLdrRegisterDllNotification || !pLdrUnregisterDllNotification)
+ {
+ win_skip("Ldr(Un)RegisterDllNotification not available\n");
+ return;
+ }
+
+ mod = LoadLibraryW(expected_dll);
+ if(mod)
+ FreeLibrary(mod);
+ else
+ expected_dll = ws2_32dllW; /* XP Default */
+
+ /* generic test */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback1, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == LDR_DLL_NOTIFICATION_REASON_LOADED, "Expected LDR_DLL_NOTIFICATION_REASON_LOADED, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == LDR_DLL_NOTIFICATION_REASON_UNLOADED, "Expected LDR_DLL_NOTIFICATION_REASON_UNLOADED, got %x\n", calls);
+
+ /* test order of callbacks */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback2, &calls, &cookie2);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x13, "Expected order 0x13, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == 0x24, "Expected order 0x24, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie2);
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll main order */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_dll_main, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x13, "Expected order 0x13, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == 0x42, "Expected order 0x42, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll main order */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_fail, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!mod, "Expected library to fail loading\n");
+ ok(calls == 0x1342, "Expected order 0x1342, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll with dependencies */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_imports, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(wintrustdllW);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x12 || calls == 0x21, "got %x\n", calls);
+
+ FreeLibrary(mod);
+ pLdrUnregisterDllNotification(cookie);
+}
+
START_TEST(rtl)
{
InitFunctionPtrs();
@@ -2291,4 +2551,5 @@ START_TEST(rtl)
test_RtlLeaveCriticalSection();
test_LdrEnumerateLoadedModules();
test_RtlMakeSelfRelativeSD();
+ test_LdrRegisterDllNotification();
}
--
1.9.1
June 22, 2018
[PATCH 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..1e76d94 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 (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 macdrv_notify_activity(void)
+{
+ static IOPMAssertionID assertion;
+ IOPMAssertionDeclareUserActivity("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 21, 2018
[PATCH 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 21, 2018
[PATCH 2/4] dinput: Notify the desktop window when device input is received.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
The overall goal of this patchset is to avoid letting the system go to sleep
when a joystick is being used. On Windows, receiving input from a joystick
which is currently being read by dinput can be easily shown to reset the
system idle timer.
dlls/dinput/device.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dlls/dinput/device.c b/dlls/dinput/device.c
index 7b83a39..fc43fb5 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)
@@ -968,6 +970,8 @@ void queue_event(LPDIRECTINPUTDEVICE8A iface, int inst_id, DWORD data, DWORD tim
}
}
+ SendMessageW(GetDesktopWindow(), WM_WINE_NOTIFY_ACTIVITY, 0, 0);
+
This->queue_head = next_pos;
/* Send event if asked */
}
--
2.7.4
June 21, 2018
[PATCH 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 21, 2018
[PATCH 1/1] wsdapi/tests: Add tests for MatchProbeEx.
by Owen Rudge
Signed-off-by: Owen Rudge <orudge(a)codeweavers.com>
---
dlls/wsdapi/tests/discovery.c | 194
+++++++++++++++++++++++++++++++++++++++++-
1 file changed, 193 insertions(+), 1 deletion(-)
June 21, 2018
Re: [PATCH 1/2] ntdll/tests: Use the available ARRAY_SIZE() macro
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=39291
Your paranoid android.
=== w2008s64 (32 bit threadpool) ===
TestBot process got stuck or died unexpectedly
The previous 1 run(s) terminated abnormally
=== wvistau64 (32 bit info) ===
info.c:1792: Test failed: Expected STATUS_SUCCESS, got c0000022
0890:info: unhandled exception c0000005 at 00340000
=== wvistau64_zh_CN (32 bit info) ===
info.c:1792: Test failed: Expected STATUS_SUCCESS, got c0000022
0bb8:info: unhandled exception c0000005 at 00370000
=== wvistau64_fr (32 bit info) ===
info.c:1792: Test failed: Expected STATUS_SUCCESS, got c0000022
072c:info: unhandled exception c0000005 at 00340000
=== wvistau64_he (32 bit info) ===
info.c:1792: Test failed: Expected STATUS_SUCCESS, got c0000022
0bd8:info: unhandled exception c0000005 at 002C0000
=== w2008s64 (32 bit info) ===
info.c:1792: Test failed: Expected STATUS_SUCCESS, got c0000022
0870:info: unhandled exception c0000005 at 003D0000
=== w7u (32 bit info) ===
info.c:1792: Test failed: Expected STATUS_SUCCESS, got c0000022
=== w7pro64 (32 bit info) ===
info.c:1792: Test failed: Expected STATUS_SUCCESS, got c0000022
0af4:info: unhandled exception c0000005 at 00350000
=== w8 (32 bit info) ===
info.c:1792: Test failed: Expected STATUS_SUCCESS, got c0000022
0f84:info: unhandled exception c0000005 at 00310000
=== w864 (32 bit info) ===
info.c:1792: Test failed: Expected STATUS_SUCCESS, got c0000022
0d00:info: unhandled exception c0000005 at 00350000
=== w1064 (32 bit info) ===
info.c:1792: Test failed: Expected STATUS_SUCCESS, got c0000022
0db8:info: unhandled exception c0000005 at 002D0000
June 21, 2018
[PATCH 2/2] ntdll/tests: Avoid ARRAY_SIZE-like macros
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/ntdll/tests/large_int.c | 8 +++-----
dlls/ntdll/tests/rtl.c | 6 ++----
dlls/ntdll/tests/rtlstr.c | 31 +++++++++++--------------------
dlls/ntdll/tests/string.c | 24 ++++++++++--------------
4 files changed, 26 insertions(+), 43 deletions(-)
diff --git a/dlls/ntdll/tests/large_int.c b/dlls/ntdll/tests/large_int.c
index da7afa4f25..c980aebe5d 100644
--- a/dlls/ntdll/tests/large_int.c
+++ b/dlls/ntdll/tests/large_int.c
@@ -102,7 +102,6 @@ static const magic_divide_t magic_divide[] = {
{ ULL(0x74ae3b5f,0x1558c800), ULL(0x2f1e28fd,0x1b5cca00), 41, 0xabcde},
};
-#define NB_MAGIC_DIVIDE (sizeof(magic_divide)/sizeof(*magic_divide))
static void test_RtlExtendedMagicDivide(void)
@@ -110,7 +109,7 @@ static void test_RtlExtendedMagicDivide(void)
int i;
LONGLONG result;
- for (i = 0; i < NB_MAGIC_DIVIDE; i++) {
+ for (i = 0; i < ARRAY_SIZE(magic_divide); i++) {
result = pRtlExtendedMagicDivide(magic_divide[i].a, magic_divide[i].b, magic_divide[i].shift);
ok(result == magic_divide[i].result,
"call failed: RtlExtendedMagicDivide(0x%s, 0x%s, %d) has result 0x%s, expected 0x%s\n",
@@ -271,7 +270,6 @@ static const largeint2str_t largeint2str[] = {
{20, 0xdeadbeef, 0, 9, "-------------------------------------------------------------------", STATUS_INVALID_PARAMETER},
{-8, 07654321, 0, 12, "-------------------------------------------------------------------", STATUS_INVALID_PARAMETER},
};
-#define NB_LARGEINT2STR (sizeof(largeint2str)/sizeof(*largeint2str))
static void one_RtlInt64ToUnicodeString_test(int test_num, const largeint2str_t *largeint2str)
@@ -360,7 +358,7 @@ static void test_RtlInt64ToUnicodeString(void)
{
int test_num;
- for (test_num = 0; test_num < NB_LARGEINT2STR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(largeint2str); test_num++) {
one_RtlInt64ToUnicodeString_test(test_num, &largeint2str[test_num]);
} /* for */
}
@@ -405,7 +403,7 @@ static void test_RtlLargeIntegerToChar(void)
int test_num;
ULONGLONG value;
- for (test_num = 0; test_num < NB_LARGEINT2STR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(largeint2str); test_num++) {
one_RtlLargeIntegerToChar_test(test_num, &largeint2str[test_num]);
} /* for */
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index db3dc9ff4e..e202408caa 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -708,7 +708,6 @@ static const all_accesses_t all_accesses[] = {
{0xFEDCBA76, 0xC8C4B242, 1},
{0xC8C4B242, 0xFEDCBA76, 0},
};
-#define NB_ALL_ACCESSES (sizeof(all_accesses)/sizeof(*all_accesses))
static void test_RtlAreAllAccessesGranted(void)
@@ -722,7 +721,7 @@ static void test_RtlAreAllAccessesGranted(void)
return;
}
- for (test_num = 0; test_num < NB_ALL_ACCESSES; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(all_accesses); test_num++) {
result = pRtlAreAllAccessesGranted(all_accesses[test_num].GrantedAccess,
all_accesses[test_num].DesiredAccess);
ok(all_accesses[test_num].result == result,
@@ -751,7 +750,6 @@ static const any_accesses_t any_accesses[] = {
{0xFEDCBA76, 0x00040000, 1},
{0xFED8BA76, 0x00040000, 0},
};
-#define NB_ANY_ACCESSES (sizeof(any_accesses)/sizeof(*any_accesses))
static void test_RtlAreAnyAccessesGranted(void)
@@ -765,7 +763,7 @@ static void test_RtlAreAnyAccessesGranted(void)
return;
}
- for (test_num = 0; test_num < NB_ANY_ACCESSES; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(any_accesses); test_num++) {
result = pRtlAreAnyAccessesGranted(any_accesses[test_num].GrantedAccess,
any_accesses[test_num].DesiredAccess);
ok(any_accesses[test_num].result == result,
diff --git a/dlls/ntdll/tests/rtlstr.c b/dlls/ntdll/tests/rtlstr.c
index 53cc185939..8b948fa82a 100644
--- a/dlls/ntdll/tests/rtlstr.c
+++ b/dlls/ntdll/tests/rtlstr.c
@@ -406,7 +406,6 @@ static const dupl_ustr_t dupl_ustr[] = {
{ 3, 0, 2, 2, NULL, 40, 42, 42, NULL, 40, 42, 0, NULL, STATUS_INVALID_PARAMETER},
{ 3, 0, 0, 0, NULL, 40, 42, 42, NULL, 0, 2, 2, "", STATUS_SUCCESS},
};
-#define NB_DUPL_USTR (sizeof(dupl_ustr)/sizeof(*dupl_ustr))
static void test_RtlDuplicateUnicodeString(void)
@@ -429,7 +428,7 @@ static void test_RtlDuplicateUnicodeString(void)
return;
}
- for (test_num = 0; test_num < NB_DUPL_USTR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(dupl_ustr); test_num++) {
source_str.Length = dupl_ustr[test_num].source_Length;
source_str.MaximumLength = dupl_ustr[test_num].source_MaximumLength;
if (dupl_ustr[test_num].source_buf != NULL) {
@@ -776,7 +775,6 @@ static const ustr2astr_t ustr2astr[] = {
{ 0, 0, 12, NULL, 10, 10, 12, NULL, FALSE, 5, 0, 0, NULL, STATUS_BUFFER_OVERFLOW},
#endif
};
-#define NB_USTR2ASTR (sizeof(ustr2astr)/sizeof(*ustr2astr))
static void test_RtlUnicodeStringToAnsiString(void)
@@ -789,7 +787,7 @@ static void test_RtlUnicodeStringToAnsiString(void)
NTSTATUS result;
unsigned int test_num;
- for (test_num = 0; test_num < NB_USTR2ASTR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(ustr2astr); test_num++) {
ansi_str.Length = ustr2astr[test_num].ansi_Length;
ansi_str.MaximumLength = ustr2astr[test_num].ansi_MaximumLength;
if (ustr2astr[test_num].ansi_buf != NULL) {
@@ -852,7 +850,6 @@ static const app_asc2str_t app_asc2str[] = {
{ 5, 14, 15, NULL, NULL, 5, 14, 15, NULL, STATUS_SUCCESS},
{ 5, 12, 15, "Tst\0S01234abcde", "tr\0i", 7, 12, 15, "Tst\0Str234abcde", STATUS_SUCCESS},
};
-#define NB_APP_ASC2STR (sizeof(app_asc2str)/sizeof(*app_asc2str))
static void test_RtlAppendAsciizToString(void)
@@ -862,7 +859,7 @@ static void test_RtlAppendAsciizToString(void)
NTSTATUS result;
unsigned int test_num;
- for (test_num = 0; test_num < NB_APP_ASC2STR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(app_asc2str); test_num++) {
dest_str.Length = app_asc2str[test_num].dest_Length;
dest_str.MaximumLength = app_asc2str[test_num].dest_MaximumLength;
if (app_asc2str[test_num].dest_buf != NULL) {
@@ -922,7 +919,6 @@ static const app_str2str_t app_str2str[] = {
{ 5, 14, 15, NULL, 0, 0, 7, NULL, 5, 14, 15, NULL, STATUS_SUCCESS},
{ 5, 12, 15, "Tst\0S01234abcde", 4, 4, 7, "tr\0iZY", 9, 12, 15, "Tst\0Str\0i4abcde", STATUS_SUCCESS},
};
-#define NB_APP_STR2STR (sizeof(app_str2str)/sizeof(*app_str2str))
static void test_RtlAppendStringToString(void)
@@ -934,7 +930,7 @@ static void test_RtlAppendStringToString(void)
NTSTATUS result;
unsigned int test_num;
- for (test_num = 0; test_num < NB_APP_STR2STR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(app_str2str); test_num++) {
dest_str.Length = app_str2str[test_num].dest_Length;
dest_str.MaximumLength = app_str2str[test_num].dest_MaximumLength;
if (app_str2str[test_num].dest_buf != NULL) {
@@ -1005,7 +1001,6 @@ static const app_uni2str_t app_uni2str[] = {
{ 4, 14, 14, "Fake0123abcdef", "U\0stri\0", 10, 14, 14, "FakeU\0stri\0\0ef", STATUS_SUCCESS},
{ 6, 14, 16, "Te\0\0stabcdefghij", "St\0\0ri", 8, 14, 16, "Te\0\0stSt\0\0efghij", STATUS_SUCCESS},
};
-#define NB_APP_UNI2STR (sizeof(app_uni2str)/sizeof(*app_uni2str))
static void test_RtlAppendUnicodeToString(void)
@@ -1015,7 +1010,7 @@ static void test_RtlAppendUnicodeToString(void)
NTSTATUS result;
unsigned int test_num;
- for (test_num = 0; test_num < NB_APP_UNI2STR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(app_uni2str); test_num++) {
dest_str.Length = app_uni2str[test_num].dest_Length;
dest_str.MaximumLength = app_uni2str[test_num].dest_MaximumLength;
if (app_uni2str[test_num].dest_buf != NULL) {
@@ -1079,7 +1074,6 @@ static const app_ustr2str_t app_ustr2str[] = {
{ 4, 14, 14, NULL, 0, 0, 8, NULL, 4, 14, 14, NULL, STATUS_SUCCESS},
{ 6, 14, 16, "Te\0\0stabcdefghij", 6, 8, 8, "St\0\0riZY", 12, 14, 16, "Te\0\0stSt\0\0ri\0\0ij", STATUS_SUCCESS},
};
-#define NB_APP_USTR2STR (sizeof(app_ustr2str)/sizeof(*app_ustr2str))
static void test_RtlAppendUnicodeStringToString(void)
@@ -1091,7 +1085,7 @@ static void test_RtlAppendUnicodeStringToString(void)
NTSTATUS result;
unsigned int test_num;
- for (test_num = 0; test_num < NB_APP_USTR2STR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(app_ustr2str); test_num++) {
dest_str.Length = app_ustr2str[test_num].dest_Length;
dest_str.MaximumLength = app_ustr2str[test_num].dest_MaximumLength;
if (app_ustr2str[test_num].dest_buf != NULL) {
@@ -1189,7 +1183,6 @@ static const find_ch_in_ustr_t find_ch_in_ustr[] = {
{ 2, "abcdabcdabcdabcdabcdabcd", "abcd", 0, STATUS_NOT_FOUND},
{ 3, "abcdabcdabcdabcdabcdabcd", "abcd", 0, STATUS_NOT_FOUND},
};
-#define NB_FIND_CH_IN_USTR (sizeof(find_ch_in_ustr)/sizeof(*find_ch_in_ustr))
static void test_RtlFindCharInUnicodeString(void)
@@ -1209,7 +1202,7 @@ static void test_RtlFindCharInUnicodeString(void)
return;
}
- for (test_num = 0; test_num < NB_FIND_CH_IN_USTR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(find_ch_in_ustr); test_num++) {
if (find_ch_in_ustr[test_num].main_str != NULL) {
main_str.Length = strlen(find_ch_in_ustr[test_num].main_str) * sizeof(WCHAR);
main_str.MaximumLength = main_str.Length + sizeof(WCHAR);
@@ -1371,7 +1364,6 @@ static const str2int_t str2int[] = {
{-8, "0", 0, STATUS_INVALID_PARAMETER}, /* Negative base */
/* { 0, NULL, 0, STATUS_SUCCESS}, */ /* NULL as string */
};
-#define NB_STR2INT (sizeof(str2int)/sizeof(*str2int))
static void test_RtlUnicodeStringToInteger(void)
@@ -1382,7 +1374,7 @@ static void test_RtlUnicodeStringToInteger(void)
WCHAR *wstr;
UNICODE_STRING uni;
- for (test_num = 0; test_num < NB_STR2INT; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(str2int); test_num++) {
wstr = AtoW(str2int[test_num].str);
value = 0xdeadbeef;
pRtlInitUnicodeString(&uni, wstr);
@@ -1451,7 +1443,7 @@ static void test_RtlCharToInteger(void)
int value;
NTSTATUS result;
- for (test_num = 0; test_num < NB_STR2INT; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(str2int); test_num++) {
/* w2k skips a leading '\0' and processes the string after */
if (str2int[test_num].str[0] != '\0') {
value = 0xdeadbeef;
@@ -1600,7 +1592,6 @@ static const int2str_t int2str[] = {
{20, 0xdeadbeef, 0, 9, "-----------------------------------", STATUS_INVALID_PARAMETER}, /* ill. base */
{-8, 07654321, 0, 12, "-----------------------------------", STATUS_INVALID_PARAMETER}, /* neg. base */
};
-#define NB_INT2STR (sizeof(int2str)/sizeof(*int2str))
static void one_RtlIntegerToUnicodeString_test(int test_num, const int2str_t *int2str)
@@ -1673,7 +1664,7 @@ static void test_RtlIntegerToUnicodeString(void)
{
size_t test_num;
- for (test_num = 0; test_num < NB_INT2STR; test_num++)
+ for (test_num = 0; test_num < ARRAY_SIZE(int2str); test_num++)
one_RtlIntegerToUnicodeString_test(test_num, &int2str[test_num]);
}
@@ -1700,7 +1691,7 @@ static void test_RtlIntegerToChar(void)
NTSTATUS result;
size_t test_num;
- for (test_num = 0; test_num < NB_INT2STR; test_num++)
+ for (test_num = 0; test_num < ARRAY_SIZE(int2str); test_num++)
one_RtlIntegerToChar_test(test_num, &int2str[test_num]);
result = pRtlIntegerToChar(int2str[0].value, 20, int2str[0].MaximumLength, NULL);
diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c
index 407bc0ffec..708d6e7b65 100644
--- a/dlls/ntdll/tests/string.c
+++ b/dlls/ntdll/tests/string.c
@@ -212,7 +212,6 @@ static const ulong2str_t ulong2str[] = {
{36, 62193781, "111111\0------------------------------------------------------------", 0x77},
{37, 71270178, "111111\0------------------------------------------------------------", 0x77},
};
-#define NB_ULONG2STR (sizeof(ulong2str)/sizeof(*ulong2str))
static void one_itoa_test(int test_num, const ulong2str_t *ulong2str)
@@ -276,7 +275,7 @@ static void test_ulongtoa(void)
{
int test_num;
- for (test_num = 0; test_num < NB_ULONG2STR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(ulong2str); test_num++) {
if (ulong2str[test_num].mask & 0x01) {
one_itoa_test(test_num, &ulong2str[test_num]);
} /* if */
@@ -402,7 +401,7 @@ static void test_ulongtow(void)
int test_num;
LPWSTR result;
- for (test_num = 0; test_num < NB_ULONG2STR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(ulong2str); test_num++) {
if (ulong2str[test_num].mask & 0x10) {
one_itow_test(test_num, &ulong2str[test_num]);
} /* if */
@@ -588,7 +587,6 @@ static const ulonglong2str_t ulonglong2str[] = {
{37, 71270178, "111111\0------------------------------------------------------------", 0x33},
{99, ULL(0x2,0x3c9e468c), "111111\0------------------------------------------------------------", 0x33},
};
-#define NB_ULONGLONG2STR (sizeof(ulonglong2str)/sizeof(*ulonglong2str))
static void one_i64toa_test(int test_num, const ulonglong2str_t *ulonglong2str)
@@ -642,7 +640,7 @@ static void test_ulonglongtoa(void)
{
int test_num;
- for (test_num = 0; test_num < NB_ULONGLONG2STR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(ulonglong2str); test_num++) {
if (ulonglong2str[test_num].mask & 0x01) {
one_i64toa_test(test_num, &ulonglong2str[test_num]);
} /* if */
@@ -746,7 +744,7 @@ static void test_ulonglongtow(void)
int test_num;
LPWSTR result;
- for (test_num = 0; test_num < NB_ULONGLONG2STR; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(ulonglong2str); test_num++) {
if (ulonglong2str[test_num].mask & 0x10) {
one_i64tow_test(test_num, &ulonglong2str[test_num]);
} /* if */
@@ -885,7 +883,6 @@ static const str2long_t str2long[] = {
{ "", 0 }, /* empty string */
/* { NULL, 0 }, */ /* NULL as string */
};
-#define NB_STR2LONG (sizeof(str2long)/sizeof(*str2long))
static void test_wtoi(void)
@@ -894,7 +891,7 @@ static void test_wtoi(void)
UNICODE_STRING uni;
int result;
- for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(str2long); test_num++) {
pRtlCreateUnicodeStringFromAsciiz(&uni, str2long[test_num].str);
result = p_wtoi(uni.Buffer);
ok(result == str2long[test_num].value,
@@ -909,7 +906,7 @@ static void test_atoi(void)
int test_num;
int result;
- for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(str2long); test_num++) {
result = patoi(str2long[test_num].str);
ok(result == str2long[test_num].value,
"(test %d): call failed: _atoi(\"%s\") has result %d, expected: %d\n",
@@ -922,7 +919,7 @@ static void test_atol(void)
int test_num;
int result;
- for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(str2long); test_num++) {
result = patol(str2long[test_num].str);
ok(result == str2long[test_num].value,
"(test %d): call failed: _atol(\"%s\") has result %d, expected: %d\n",
@@ -936,7 +933,7 @@ static void test_wtol(void)
UNICODE_STRING uni;
LONG result;
- for (test_num = 0; test_num < NB_STR2LONG; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(str2long); test_num++) {
pRtlCreateUnicodeStringFromAsciiz(&uni, str2long[test_num].str);
result = p_wtol(uni.Buffer);
ok(result == str2long[test_num].value,
@@ -1068,7 +1065,6 @@ static const str2longlong_t str2longlong[] = {
{ "", 0 }, /* empty string */
/* { NULL, 0 }, */ /* NULL as string */
};
-#define NB_STR2LONGLONG (sizeof(str2longlong)/sizeof(*str2longlong))
static void test_atoi64(void)
@@ -1076,7 +1072,7 @@ static void test_atoi64(void)
int test_num;
LONGLONG result;
- for (test_num = 0; test_num < NB_STR2LONGLONG; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(str2longlong); test_num++) {
result = p_atoi64(str2longlong[test_num].str);
if (str2longlong[test_num].overflow)
ok(result == str2longlong[test_num].value ||
@@ -1100,7 +1096,7 @@ static void test_wtoi64(void)
UNICODE_STRING uni;
LONGLONG result;
- for (test_num = 0; test_num < NB_STR2LONGLONG; test_num++) {
+ for (test_num = 0; test_num < ARRAY_SIZE(str2longlong); test_num++) {
pRtlCreateUnicodeStringFromAsciiz(&uni, str2longlong[test_num].str);
result = p_wtoi64(uni.Buffer);
if (str2longlong[test_num].overflow)
--
2.14.4
June 21, 2018
[PATCH 1/2] ntdll/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/ntdll/tests/directory.c | 4 ++--
dlls/ntdll/tests/exception.c | 16 +++++++---------
dlls/ntdll/tests/file.c | 4 ++--
dlls/ntdll/tests/info.c | 2 +-
dlls/ntdll/tests/om.c | 6 +++---
dlls/ntdll/tests/pipe.c | 4 ++--
dlls/ntdll/tests/rtl.c | 6 +++---
dlls/ntdll/tests/rtlstr.c | 10 +++++-----
dlls/ntdll/tests/string.c | 2 +-
dlls/ntdll/tests/threadpool.c | 14 +++++++-------
10 files changed, 33 insertions(+), 35 deletions(-)
diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c
index f8f27f9d77..2c6170b8b4 100644
--- a/dlls/ntdll/tests/directory.c
+++ b/dlls/ntdll/tests/directory.c
@@ -74,8 +74,8 @@ static struct testfile_s {
{ 0, 0, FILE_ATTRIBUTE_DIRECTORY, {'.'}, ". directory" },
{ 0, 0, FILE_ATTRIBUTE_DIRECTORY, {'.','.'}, ".. directory" }
};
-static const int test_dir_count = sizeof(testfiles) / sizeof(testfiles[0]);
-static const int max_test_dir_size = sizeof(testfiles) / sizeof(testfiles[0]) + 5; /* size of above plus some for .. etc */
+static const int test_dir_count = ARRAY_SIZE(testfiles);
+static const int max_test_dir_size = ARRAY_SIZE(testfiles) + 5; /* size of above plus some for .. etc */
static const WCHAR dummyW[] = {'d','u','m','m','y',0};
static const WCHAR dotW[] = {'.',0};
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index e30cd593d7..5998f54b04 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -643,7 +643,7 @@ static void test_prot_fault(void)
{
unsigned int i;
- for (i = 0; i < sizeof(exceptions)/sizeof(exceptions[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(exceptions); i++)
{
if (is_wow64 && exceptions[i].wow64_broken && !strcmp( winetest_platform, "windows" ))
{
@@ -1734,7 +1734,7 @@ static void call_virtual_unwind( int testnum, const struct unwind_test *test )
for (j = 0; j < 16; j++)
{
- static const UINT nb_regs = sizeof(test->results[i].regs) / sizeof(test->results[i].regs[0]);
+ static const UINT nb_regs = ARRAY_SIZE(test->results[i].regs);
for (k = 0; k < nb_regs; k++)
{
@@ -1888,14 +1888,12 @@ static void test_virtual_unwind(void)
static const struct unwind_test tests[] =
{
- { function_0, sizeof(function_0), unwind_info_0,
- results_0, sizeof(results_0)/sizeof(results_0[0]) },
- { function_1, sizeof(function_1), unwind_info_1,
- results_1, sizeof(results_1)/sizeof(results_1[0]) }
+ { function_0, sizeof(function_0), unwind_info_0, results_0, ARRAY_SIZE(results_0) },
+ { function_1, sizeof(function_1), unwind_info_1, results_1, ARRAY_SIZE(results_1) }
};
unsigned int i;
- for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
call_virtual_unwind( i, &tests[i] );
}
@@ -2429,7 +2427,7 @@ static void test_prot_fault(void)
{
unsigned int i;
- for (i = 0; i < sizeof(exceptions)/sizeof(exceptions[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(exceptions); i++)
{
got_exception = 0;
run_exception_test(handler, &exceptions[i], &exceptions[i].code,
@@ -2567,7 +2565,7 @@ static void test_debug_registers(void)
HANDLE thread;
int i;
- for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(tests); i++)
{
memset(&ctx, 0, sizeof(ctx));
ctx.ContextFlags = CONTEXT_DEBUG_REGISTERS;
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index f88d16b449..d9d029b7f3 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -563,7 +563,7 @@ static void delete_file_test(void)
ok(0, "couldn't get temp dir\n");
return;
}
- if (ret + sizeof(testdirW)/sizeof(WCHAR)-1 + sizeof(subdirW)/sizeof(WCHAR)-1 >= MAX_PATH)
+ if (ret + ARRAY_SIZE(testdirW)-1 + ARRAY_SIZE(subdirW)-1 >= MAX_PATH)
{
ok(0, "MAX_PATH exceeded in constructing paths\n");
return;
@@ -3379,7 +3379,7 @@ static void test_NtCreateFile(void)
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
- for (i = 0; i < sizeof(td)/sizeof(td[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(td); i++)
{
status = pNtCreateFile(&handle, GENERIC_READ, &attr, &io, NULL,
td[i].attrib_in, FILE_SHARE_READ|FILE_SHARE_WRITE,
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 6c93c3cd58..4a2d9e6933 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -1613,7 +1613,7 @@ static void test_query_process_debug_flags(int argc, char **argv)
ok(!status, "NtQueryInformationProcess failed, status %#x.\n", status);
ok(debug_flags == TRUE, "Expected flag TRUE, got %x.\n", debug_flags);
- for (i = 0; i < sizeof(test_flags)/sizeof(test_flags[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(test_flags); i++)
{
DWORD expected_flags = !(test_flags[i] & DEBUG_ONLY_THIS_PROCESS);
sprintf(cmdline, "%s %s %s", argv[0], argv[1], "debuggee");
diff --git a/dlls/ntdll/tests/om.c b/dlls/ntdll/tests/om.c
index 43c5ee46d7..52b4a83968 100644
--- a/dlls/ntdll/tests/om.c
+++ b/dlls/ntdll/tests/om.c
@@ -650,7 +650,7 @@ static void test_name_limits(void)
/* named pipes */
memcpy( str.Buffer, pipeW, sizeof(pipeW) );
- for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(pipeW)/sizeof(WCHAR)] = 'a';
+ for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + ARRAY_SIZE(pipeW)] = 'a';
str.Length = 0;
attr.RootDirectory = 0;
attr.Attributes = OBJ_CASE_INSENSITIVE;
@@ -703,7 +703,7 @@ static void test_name_limits(void)
/* mailslots */
memcpy( str.Buffer, mailslotW, sizeof(mailslotW) );
- for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(mailslotW)/sizeof(WCHAR)] = 'a';
+ for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + ARRAY_SIZE(mailslotW)] = 'a';
str.Length = 0;
status = pNtCreateMailslotFile( &ret, GENERIC_ALL, &attr, &iosb, 0, 0, 0, NULL );
ok( status == STATUS_OBJECT_PATH_SYNTAX_BAD, "%u: NtCreateMailslotFile failed %x\n", str.Length, status );
@@ -744,7 +744,7 @@ static void test_name_limits(void)
/* registry keys */
memcpy( str.Buffer, registryW, sizeof(registryW) );
- for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + sizeof(registryW)/sizeof(WCHAR)] = 'a';
+ for (i = 0; i < 65536 / sizeof(WCHAR); i++) str.Buffer[i + ARRAY_SIZE(registryW)] = 'a';
str.Length = 0;
status = pNtCreateKey( &ret, GENERIC_ALL, &attr, 0, NULL, 0, NULL );
todo_wine
diff --git a/dlls/ntdll/tests/pipe.c b/dlls/ntdll/tests/pipe.c
index 2978274715..c8e6809423 100644
--- a/dlls/ntdll/tests/pipe.c
+++ b/dlls/ntdll/tests/pipe.c
@@ -230,8 +230,8 @@ static void test_create(void)
static const DWORD sharing[] = { FILE_SHARE_READ, FILE_SHARE_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE };
static const DWORD pipe_config[]= { 1, 0, 2 };
- for (j = 0; j < sizeof(sharing) / sizeof(DWORD); j++) {
- for (k = 0; k < sizeof(access) / sizeof(DWORD); k++) {
+ for (j = 0; j < ARRAY_SIZE(sharing); j++) {
+ for (k = 0; k < ARRAY_SIZE(access); k++) {
HANDLE hclient;
BOOL should_succeed = TRUE;
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index 2e3a7de75d..db3dc9ff4e 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -680,7 +680,7 @@ static void test_RtlRandom(void)
}
seed = 0;
- for (i = 0; i < sizeof(res) / sizeof(res[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(res); i++)
{
res[i] = pRtlRandom(&seed);
ok(seed != res[i], "%i: seed is same as res %x\n", i, seed);
@@ -1226,7 +1226,7 @@ static void test_RtlIpv4StringToAddress(void)
{ "::1", STATUS_INVALID_PARAMETER, 0, { -1 } },
{ ":1", STATUS_INVALID_PARAMETER, 0, { -1 } },
};
- const int testcount = sizeof(tests) / sizeof(tests[0]);
+ const int testcount = ARRAY_SIZE(tests);
int i;
if (!pRtlIpv4StringToAddressA)
@@ -1787,7 +1787,7 @@ static void test_RtlDecompressBuffer(void)
ok(final_size == 0xdeadbeef, "got wrong final_size %u\n", final_size);
/* regular tests for RtlDecompressBuffer */
- for (i = 0; i < sizeof(test_lznt) / sizeof(test_lznt[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(test_lznt); i++)
{
trace("Running test %d (compressed_size=%u, uncompressed_size=%u, status=0x%08x)\n",
i, test_lznt[i].compressed_size, test_lznt[i].uncompressed_size, test_lznt[i].status);
diff --git a/dlls/ntdll/tests/rtlstr.c b/dlls/ntdll/tests/rtlstr.c
index 7f889dfa0d..53cc185939 100644
--- a/dlls/ntdll/tests/rtlstr.c
+++ b/dlls/ntdll/tests/rtlstr.c
@@ -1769,7 +1769,7 @@ static void test_RtlIsTextUnicode(void)
be_unicode = HeapAlloc(GetProcessHeap(), 0, sizeof(unicode) + sizeof(WCHAR));
be_unicode[0] = 0xfffe;
- for (i = 0; i < sizeof(unicode)/sizeof(unicode[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(unicode); i++)
{
be_unicode[i + 1] = (unicode[i] >> 8) | ((unicode[i] & 0xff) << 8);
}
@@ -1791,7 +1791,7 @@ static void test_RtlIsTextUnicode(void)
be_unicode_no_controls = HeapAlloc(GetProcessHeap(), 0, sizeof(unicode) + sizeof(WCHAR));
ok(be_unicode_no_controls != NULL, "Expected HeapAlloc to succeed.\n");
be_unicode_no_controls[0] = 0xfffe;
- for (i = 0; i < sizeof(unicode_no_controls)/sizeof(unicode_no_controls[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(unicode_no_controls); i++)
be_unicode_no_controls[i + 1] = (unicode_no_controls[i] >> 8) | ((unicode_no_controls[i] & 0xff) << 8);
@@ -2093,7 +2093,7 @@ static void test_RtlUnicodeToUTF8N(void)
const WCHAR special_string[] = { 'X',0x80,0xd800,0 };
const unsigned char special_expected[] = { 'X',0xc2,0x80,0xef,0xbf,0xbd,0 };
unsigned int input_len;
- const unsigned int test_count = sizeof(unicode_to_utf8) / sizeof(unicode_to_utf8[0]);
+ const unsigned int test_count = ARRAY_SIZE(unicode_to_utf8);
unsigned int i;
if (!pRtlUnicodeToUTF8N)
@@ -2374,7 +2374,7 @@ static void unicode_expect_(const WCHAR *out_string, ULONG buflen, ULONG out_cha
ok_(__FILE__, line)(buffer[i] == out_string[i],
"buffer[%d] = 0x%x, expected 0x%x\n",
i, buffer[i], out_string[i]);
- for (; i < sizeof(buffer) / sizeof(WCHAR); i++)
+ for (; i < ARRAY_SIZE(buffer); i++)
ok_(__FILE__, line)(buffer[i] == 0x5555,
"buffer[%d] = 0x%x, expected 0x5555\n",
i, buffer[i]);
@@ -2396,7 +2396,7 @@ static void test_RtlUTF8ToUnicodeN(void)
const char special_string[] = { 'X',0xc2,0x80,0xF0,0x90,0x80,0x80,0 };
const WCHAR special_expected[] = { 'X',0x80,0xd800,0xdc00,0 };
unsigned int input_len;
- const unsigned int test_count = sizeof(utf8_to_unicode) / sizeof(utf8_to_unicode[0]);
+ const unsigned int test_count = ARRAY_SIZE(utf8_to_unicode);
unsigned int i;
if (!pRtlUTF8ToUnicodeN)
diff --git a/dlls/ntdll/tests/string.c b/dlls/ntdll/tests/string.c
index 8fca5d46d5..407bc0ffec 100644
--- a/dlls/ntdll/tests/string.c
+++ b/dlls/ntdll/tests/string.c
@@ -1258,7 +1258,7 @@ static void test_bsearch(void)
int *x, l, i, j;
/* just try all array sizes */
- for (j=1;j<sizeof(arr)/sizeof(arr[0]);j++) {
+ for (j=1;j<ARRAY_SIZE(arr);j++) {
for (i=0;i<j;i++) {
l = arr[i];
x = p_bsearch (&l, arr, j, sizeof(arr[0]), intcomparefunc);
diff --git a/dlls/ntdll/tests/threadpool.c b/dlls/ntdll/tests/threadpool.c
index af0b6673d3..3bd2d994ec 100644
--- a/dlls/ntdll/tests/threadpool.c
+++ b/dlls/ntdll/tests/threadpool.c
@@ -1824,7 +1824,7 @@ static void test_tp_multi_wait(void)
environment.Pool = pool;
/* create semaphores and corresponding wait objects */
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(semaphores); i++)
{
semaphores[i] = CreateSemaphoreW(NULL, 0, 1, NULL);
ok(semaphores[i] != NULL, "failed to create semaphore %i\n", i);
@@ -1838,7 +1838,7 @@ static void test_tp_multi_wait(void)
}
/* release all semaphores and wait for callback */
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(semaphores); i++)
{
multi_wait_info.result = 0;
ReleaseSemaphore(semaphores[i], 1, NULL);
@@ -1851,7 +1851,7 @@ static void test_tp_multi_wait(void)
}
/* repeat the same test in reverse order */
- for (i = sizeof(semaphores)/sizeof(semaphores[0]) - 1; i >= 0; i--)
+ for (i = ARRAY_SIZE(semaphores) - 1; i >= 0; i--)
{
multi_wait_info.result = 0;
ReleaseSemaphore(semaphores[i], 1, NULL);
@@ -1865,13 +1865,13 @@ static void test_tp_multi_wait(void)
/* test timeout of wait objects */
multi_wait_info.result = 0;
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(semaphores); i++)
{
when.QuadPart = (ULONGLONG)50 * -10000;
pTpSetWait(waits[i], semaphores[i], &when);
}
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(semaphores); i++)
{
result = WaitForSingleObject(semaphore, 150);
ok(result == WAIT_OBJECT_0, "WaitForSingleObject returned %u\n", result);
@@ -1880,14 +1880,14 @@ static void test_tp_multi_wait(void)
ok(multi_wait_info.result >> 16, "expected multi_wait_info.result >> 16 != 0\n");
/* destroy the wait objects and semaphores while waiting */
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(semaphores); i++)
{
pTpSetWait(waits[i], semaphores[i], NULL);
}
Sleep(50);
- for (i = 0; i < sizeof(semaphores)/sizeof(semaphores[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(semaphores); i++)
{
pTpReleaseWait(waits[i]);
NtClose(semaphores[i]);
--
2.14.4
June 21, 2018
[PATCH] wininet/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/wininet/tests/ftp.c | 2 +-
dlls/wininet/tests/http.c | 10 ++++-----
dlls/wininet/tests/internet.c | 16 ++++++-------
dlls/wininet/tests/url.c | 52 +++++++++++++++++++++----------------------
dlls/wininet/tests/urlcache.c | 4 ++--
5 files changed, 42 insertions(+), 42 deletions(-)
diff --git a/dlls/wininet/tests/ftp.c b/dlls/wininet/tests/ftp.c
index d2118faded..6f50104f3b 100644
--- a/dlls/wininet/tests/ftp.c
+++ b/dlls/wininet/tests/ftp.c
@@ -735,7 +735,7 @@ static void test_command(HINTERNET hFtp, HINTERNET hConnect)
return;
}
- for (i = 0; i < sizeof(command_test) / sizeof(command_test[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(command_test); i++)
{
SetLastError(0xdeadbeef);
ret = pFtpCommandA(hFtp, FALSE, FTP_TRANSFER_TYPE_ASCII, command_test[i].cmd, 0, NULL);
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index 0524ddf3fd..ace8512399 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -172,7 +172,7 @@ static BOOL (WINAPI *pInternetGetSecurityInfoByURLA)(LPSTR,PCCERT_CHAIN_CONTEXT*
static int strcmp_wa(LPCWSTR strw, const char *stra)
{
WCHAR buf[512];
- MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, sizeof(buf)/sizeof(WCHAR));
+ MultiByteToWideChar(CP_ACP, 0, stra, -1, buf, ARRAY_SIZE(buf));
return lstrcmpW(strw, buf);
}
@@ -4204,7 +4204,7 @@ static void test_http_status(int port)
DWORD i, size;
BOOL res;
- for(i=0; i < sizeof(http_status_tests)/sizeof(*http_status_tests); i++) {
+ for(i = 0; i < ARRAY_SIZE(http_status_tests); i++) {
send_buffer = http_status_tests[i].response_text;
open_simple_request(&req, "localhost", port, NULL, "/send_from_buffer");
@@ -6543,14 +6543,14 @@ static const struct notification async_send_request_ex_chunked_test[] =
static const struct notification_data notification_data[] = {
{
async_send_request_ex_chunked_test,
- sizeof(async_send_request_ex_chunked_test)/sizeof(async_send_request_ex_chunked_test[0]),
+ ARRAY_SIZE(async_send_request_ex_chunked_test),
"GET",
"test.winehq.org",
"tests/data.php"
},
{
async_send_request_ex_test,
- sizeof(async_send_request_ex_test)/sizeof(async_send_request_ex_test[0]),
+ ARRAY_SIZE(async_send_request_ex_test),
"POST",
"test.winehq.org",
"tests/post.php",
@@ -6565,7 +6565,7 @@ static const struct notification_data notification_data[] = {
},
{
async_send_request_ex_resolve_failure_test,
- sizeof(async_send_request_ex_resolve_failure_test)/sizeof(async_send_request_ex_resolve_failure_test[0]),
+ ARRAY_SIZE(async_send_request_ex_resolve_failure_test),
"GET",
"brokenhost",
"index.html",
diff --git a/dlls/wininet/tests/internet.c b/dlls/wininet/tests/internet.c
index 39c698f5db..7889e40ea8 100644
--- a/dlls/wininet/tests/internet.c
+++ b/dlls/wininet/tests/internet.c
@@ -629,7 +629,7 @@ static void test_cookie_url(void)
ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
"InternetGetCookeA failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
- len = sizeof(bufw)/sizeof(*bufw);
+ len = ARRAY_SIZE(bufw);
res = InternetGetCookieW(about_blankW, NULL, bufw, &len);
ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
"InternetGetCookeW failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
@@ -639,7 +639,7 @@ static void test_cookie_url(void)
ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
"InternetGetCookeExA failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
- len = sizeof(bufw)/sizeof(*bufw);
+ len = ARRAY_SIZE(bufw);
res = pInternetGetCookieExW(about_blankW, NULL, bufw, &len, 0, NULL);
ok(!res && GetLastError() == ERROR_INVALID_PARAMETER,
"InternetGetCookeExW failed: %u, expected ERROR_INVALID_PARAMETER\n", GetLastError());
@@ -887,7 +887,7 @@ static void InternetTimeFromSystemTimeW_test(void)
/* test too small buffer size */
SetLastError(0xdeadbeef);
- ret = pInternetTimeFromSystemTimeW( &time, INTERNET_RFC1123_FORMAT, string, sizeof(string)/sizeof(string[0]) );
+ ret = pInternetTimeFromSystemTimeW( &time, INTERNET_RFC1123_FORMAT, string, ARRAY_SIZE(string));
error = GetLastError();
ok( !ret, "InternetTimeFromSystemTimeW should have returned FALSE\n" );
ok( error == ERROR_INSUFFICIENT_BUFFER,
@@ -1084,7 +1084,7 @@ static void test_PrivacyGetSetZonePreferenceW(void)
trace("template %u\n", old_template);
if(old_template == PRIVACY_TEMPLATE_ADVANCED) {
- pref_size = sizeof(pref)/sizeof(WCHAR);
+ pref_size = ARRAY_SIZE(pref);
ret = pPrivacyGetZonePreferenceW(zone, type, &old_template, pref, &pref_size);
ok(ret == 0, "expected ret == 0, got %u\n", ret);
}
@@ -1721,7 +1721,7 @@ static void test_InternetGetConnectedStateExW(void)
flags = 0;
buffer[0] = 0;
- res = pInternetGetConnectedStateExW(&flags, buffer, sizeof(buffer) / sizeof(buffer[0]), 0);
+ res = pInternetGetConnectedStateExW(&flags, buffer, ARRAY_SIZE(buffer), 0);
trace("Internet Connection: Flags 0x%02x - Name '%s'\n", flags, wine_dbgstr_w(buffer));
todo_wine
ok (flags & INTERNET_RAS_INSTALLED, "Missing RAS flag\n");
@@ -1755,21 +1755,21 @@ todo_wine
ok(!buffer[0], "Buffer must not change, got %02X\n", buffer[0]);
buffer[0] = 0;
- res = pInternetGetConnectedStateExW(NULL, buffer, sizeof(buffer) / sizeof(buffer[0]), 0);
+ res = pInternetGetConnectedStateExW(NULL, buffer, ARRAY_SIZE(buffer), 0);
ok(res == TRUE, "Expected TRUE, got %d\n", res);
sz = lstrlenW(buffer);
ok(sz > 0, "Expected a connection name\n");
buffer[0] = 0;
flags = 0;
- res = pInternetGetConnectedStateExW(&flags, buffer, sizeof(buffer) / sizeof(buffer[0]), 0);
+ res = pInternetGetConnectedStateExW(&flags, buffer, ARRAY_SIZE(buffer), 0);
ok(res == TRUE, "Expected TRUE, got %d\n", res);
ok(flags, "Expected at least one flag set\n");
sz = lstrlenW(buffer);
ok(sz > 0, "Expected a connection name\n");
flags = 0;
- res = pInternetGetConnectedStateExW(&flags, NULL, sizeof(buffer) / sizeof(buffer[0]), 0);
+ res = pInternetGetConnectedStateExW(&flags, NULL, ARRAY_SIZE(buffer), 0);
ok(res == TRUE, "Expected TRUE, got %d\n", res);
ok(flags, "Expected at least one flag set\n");
diff --git a/dlls/wininet/tests/url.c b/dlls/wininet/tests/url.c
index 0af58358eb..18c77b6647 100644
--- a/dlls/wininet/tests/url.c
+++ b/dlls/wininet/tests/url.c
@@ -672,17 +672,17 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof comp);
comp.dwStructSize = sizeof(comp);
comp.lpszScheme = scheme;
- comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
+ comp.dwSchemeLength = ARRAY_SIZE(scheme);
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUserName = user;
- comp.dwUserNameLength = sizeof(user)/sizeof(user[0]);
+ comp.dwUserNameLength = ARRAY_SIZE(user);
comp.lpszPassword = pwd;
- comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]);
+ comp.dwPasswordLength = ARRAY_SIZE(pwd);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
comp.lpszExtraInfo = extra;
- comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
+ comp.dwExtraInfoLength = ARRAY_SIZE(extra);
SetLastError(0xdeadbeef);
r = InternetCrackUrlW(NULL, 0, 0, &comp );
@@ -721,9 +721,9 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof comp);
comp.dwStructSize = sizeof comp;
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
r = InternetCrackUrlW(url, 0, 0, &comp );
ok( r, "failed to crack url\n");
@@ -739,11 +739,11 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof comp);
comp.dwStructSize = sizeof comp;
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
comp.lpszExtraInfo = NULL;
- comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
+ comp.dwExtraInfoLength = ARRAY_SIZE(extra);
r = InternetCrackUrlW(url, 0, 0, &comp );
ok( r, "failed to crack url\n");
@@ -763,17 +763,17 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof(comp));
comp.dwStructSize = sizeof(comp);
comp.lpszScheme = scheme;
- comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
+ comp.dwSchemeLength = ARRAY_SIZE(scheme);
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUserName = user;
- comp.dwUserNameLength = sizeof(user)/sizeof(user[0]);
+ comp.dwUserNameLength = ARRAY_SIZE(user);
comp.lpszPassword = pwd;
- comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]);
+ comp.dwPasswordLength = ARRAY_SIZE(pwd);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
comp.lpszExtraInfo = extra;
- comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
+ comp.dwExtraInfoLength = ARRAY_SIZE(extra);
r = InternetCrackUrlW(url2, 0, 0, &comp);
ok(!r, "InternetCrackUrl should have failed\n");
@@ -791,17 +791,17 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof comp);
comp.dwStructSize = sizeof comp;
comp.lpszScheme = scheme;
- comp.dwSchemeLength = sizeof(scheme)/sizeof(scheme[0]);
+ comp.dwSchemeLength = ARRAY_SIZE(scheme);
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUserName = user;
- comp.dwUserNameLength = sizeof(user)/sizeof(user[0]);
+ comp.dwUserNameLength = ARRAY_SIZE(user);
comp.lpszPassword = pwd;
- comp.dwPasswordLength = sizeof(pwd)/sizeof(pwd[0]);
+ comp.dwPasswordLength = ARRAY_SIZE(pwd);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
comp.lpszExtraInfo = extra;
- comp.dwExtraInfoLength = sizeof(extra)/sizeof(extra[0]);
+ comp.dwExtraInfoLength = ARRAY_SIZE(extra);
r = InternetCrackUrlW(url3, 0, 0, &comp );
ok( r, "InternetCrackUrlW failed unexpectedly\n");
ok( host[0] == 'x', "host should be x.org\n");
@@ -812,9 +812,9 @@ static void InternetCrackUrlW_test(void)
memset(&comp, 0, sizeof(comp));
comp.dwStructSize = sizeof(comp);
comp.lpszHostName = host;
- comp.dwHostNameLength = sizeof(host)/sizeof(host[0]);
+ comp.dwHostNameLength = ARRAY_SIZE(host);
comp.lpszUrlPath = urlpart;
- comp.dwUrlPathLength = sizeof(urlpart)/sizeof(urlpart[0]);
+ comp.dwUrlPathLength = ARRAY_SIZE(urlpart);
r = InternetCrackUrlW(url3, 0, ICU_DECODE, &comp);
todo_wine ok(r, "InternetCrackUrlW failed unexpectedly\n");
todo_wine ok(!strcmp_wa(host, "x.org"), "host is %s, should be x.org\n", wine_dbgstr_w(host));
@@ -1224,7 +1224,7 @@ START_TEST(url)
return;
}
- for(i=0; i < sizeof(crack_url_tests)/sizeof(*crack_url_tests); i++)
+ for(i = 0; i < ARRAY_SIZE(crack_url_tests); i++)
test_crack_url(crack_url_tests+i);
test_long_url();
diff --git a/dlls/wininet/tests/urlcache.c b/dlls/wininet/tests/urlcache.c
index 310054b6a7..3799500489 100644
--- a/dlls/wininet/tests/urlcache.c
+++ b/dlls/wininet/tests/urlcache.c
@@ -891,13 +891,13 @@ static void test_urlcacheW(void)
if(ie10_cache) {
if(!MultiByteToWideChar(CP_ACP, 0, urls[6].encoded_url, -1,
- urls[6].url, sizeof(urls[6].url)/sizeof(WCHAR)))
+ urls[6].url, ARRAY_SIZE(urls[6].url)))
urls[6].url[0] = 0;
trace("converted url in test 6: %s\n", wine_dbgstr_w(urls[6].url));
}
- for(i=0; i<sizeof(urls)/sizeof(*urls); i++) {
+ for(i=0; i<ARRAY_SIZE(urls); i++) {
INTERNET_CACHE_ENTRY_INFOA *entry_infoA;
INTERNET_CACHE_ENTRY_INFOW *entry_infoW;
DWORD size;
--
2.14.4
June 21, 2018
[PATCH] appwiz.cpl: Support installing minor updates when installing addons
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/appwiz.cpl/addons.c | 5 +++++
1 file changed, 5 insertions(+)
June 21, 2018
Re: [PATCH 3/3] Add new test for DXTn volume textures.
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=39289
Your paranoid android.
=== w1064 (64 bit visual) ===
visual.c:8645: Test failed: Got unexpected color 0x00007580 for quad 2 (different colors).
June 21, 2018
[PATCH 3/3] Add new test for DXTn volume textures.
by Connor McAdams
To properly test the functionality of DXTn volume textures, I have added
new tests for DXT1, DXT3, and DXT5 replacing the old DXT5 test. I also
added a function to get the alpha values of pixels, although there may
have been a reason one wasn't included in the first place, it's the only
real way to make sure the alpha is behaving properly on the formats.
---
dlls/d3d9/tests/visual.c | 190 ++++++++++++++++++++++++++++++++---------------
1 file changed, 131 insertions(+), 59 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index b36c189..ec121b0 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -186,6 +186,31 @@ static void release_surface_readback(struct surface_readback *rb)
IDirect3DSurface9_Release(rb->surface);
}
+static DWORD getAlphaPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
+{
+ DWORD ret;
+ IDirect3DSurface9 *rt;
+ struct surface_readback rb;
+ HRESULT hr;
+
+ hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
+ if(FAILED(hr))
+ {
+ trace("Can't get the render target, hr %#x.\n", hr);
+ return 0xdeadbeed;
+ }
+
+ get_rt_readback(rt, &rb);
+ /* Remove the X channel for now. DirectX and OpenGL have different ideas how to treat it apparently, and it isn't
+ * really important for these tests
+ */
+ ret = get_readback_color(&rb, x, y) & 0xffffffff;
+ release_surface_readback(&rb);
+
+ IDirect3DSurface9_Release(rt);
+ return ret;
+}
+
static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
{
DWORD ret;
@@ -17741,22 +17766,39 @@ done:
DestroyWindow(window);
}
-static void volume_dxt5_test(void)
+static void volume_dxtn_test(void)
{
IDirect3DVolumeTexture9 *texture;
IDirect3DDevice9 *device;
D3DLOCKED_BOX box;
IDirect3D9 *d3d;
- unsigned int i;
+ unsigned int i, x;
ULONG refcount;
DWORD color;
HWND window;
HRESULT hr;
- static const char texture_data[] =
+ static const char dxt1_texture_data[] =
+ {
+ /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
+ 0x00, 0xF8, 0x00, 0xF8, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xE0, 0x07, 0xE0, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0x1F, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00
+ };
+ static const char dxt3_texture_data[] =
+ {
+ /* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. The red block goes from
+ * 15 to 0 on alpha level. */
+ 0xFF, 0xEE, 0xFF, 0xEE, 0xFF, 0xEE, 0xFF, 0xEE, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xDD, 0xFF, 0xDD, 0xFF, 0xDD, 0xFF, 0xDD, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xCC, 0xFF, 0xCC, 0xFF, 0xCC, 0xFF, 0xCC, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xFF, 0xBB, 0xFF, 0xBB, 0xFF, 0xBB, 0xFF, 0xBB, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
+ };
+ static const char dxt5_texture_data[] =
{
/* A 8x4x2 texture consisting of 4 4x4 blocks. The colors of the blocks are red, green, blue and white. */
- 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x80, 0x0D, 0xD8, 0x80, 0x0D, 0xD8, 0x00, 0xf8, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0xe0, 0x07, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00,
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00
@@ -17778,70 +17820,100 @@ static void volume_dxt5_test(void)
{{ 1.0f, -1.0f, 1.0f}, { 1.0f, 0.0f, 0.75f}},
{{ 1.0f, 1.0f, 1.0f}, { 1.0f, 1.0f, 0.75f}},
};
- static const DWORD expected_colors[] = {0x00ff0000, 0x0000ff00, 0x000000ff, 0x00ffffff};
-
- window = create_window();
- d3d = Direct3DCreate9(D3D_SDK_VERSION);
- ok(!!d3d, "Failed to create a D3D object.\n");
- if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
- D3DFMT_X8R8G8B8, 0, D3DRTYPE_VOLUMETEXTURE, D3DFMT_DXT5)))
+ static const DWORD expected_colors[3][8] = {
{
- skip("DXT5 volume textures are not supported, skipping test.\n");
- goto done;
- }
- if (!(device = create_device(d3d, window, window, TRUE)))
+ 0xFFFF0000, 0x00000000, 0xFF00FF00, 0xFF00FF00,
+ 0xFF0000FF, 0xFF0000FF, 0xFFFFFFFF, 0xFFFFFFFF,
+ },
{
- skip("Failed to create a D3D device, skipping tests.\n");
- goto done;
+ 0xFFFF0000, 0xEEFF0000, 0xFF00FF00, 0xDD00FF00,
+ 0xFF0000FF, 0xCC0000FF, 0xFFFFFFFF, 0xBBFFFFFF,
+ },
+ {
+ 0xFFFF0000, 0x00FF0000, 0xFF00FF00, 0xFF00FF00,
+ 0xFF0000FF, 0xFF0000FF, 0xFFFFFFFF, 0xFFFFFFFF
}
+ };
+ static const char *const dxtn[3] = {"DXT1", "DXT3", "DXT5"};
+ static const unsigned int fmt[3] = {D3DFMT_DXT1, D3DFMT_DXT3, D3DFMT_DXT5};
- hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, D3DFMT_DXT5,
- D3DPOOL_MANAGED, &texture, NULL);
- ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
+ for (x = 0; x < 3; x++)
+ {
+ window = create_window();
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create a D3D object.\n");
+ if (FAILED(IDirect3D9_CheckDeviceFormat(d3d, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL,
+ D3DFMT_A8B8G8R8, 0, D3DRTYPE_VOLUMETEXTURE, fmt[x])))
+ {
+ skip("%s volume textures are not supported, skipping test.\n", dxtn[x]);
+ continue;
+ }
+ if (!(device = create_device(d3d, window, window, TRUE)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ continue;
+ }
- hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
- ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
- memcpy(box.pBits, texture_data, sizeof(texture_data));
- hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
- ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_CreateVolumeTexture(device, 8, 4, 2, 1, 0, fmt[x],
+ D3DPOOL_MANAGED, &texture, NULL);
+ ok(SUCCEEDED(hr), "Failed to create volume texture, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
- ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
- ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
- ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
- ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
- ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
- hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
- ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
+ hr = IDirect3DVolumeTexture9_LockBox(texture, 0, &box, NULL, 0);
+ ok(SUCCEEDED(hr), "Failed to lock volume texture, hr %#x.\n", hr);
+ switch (x)
+ {
+ case 0:
+ memcpy(box.pBits, dxt1_texture_data, sizeof(dxt1_texture_data));
+ break;
+ case 1:
+ memcpy(box.pBits, dxt3_texture_data, sizeof(dxt3_texture_data));
+ break;
+ case 2:
+ memcpy(box.pBits, dxt5_texture_data, sizeof(dxt5_texture_data));
+ break;
+ }
+ hr = IDirect3DVolumeTexture9_UnlockBox(texture, 0);
+ ok(SUCCEEDED(hr), "Failed to unlock volume texture, hr %#x.\n", hr);
- hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
- ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
- hr = IDirect3DDevice9_BeginScene(device);
- ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
- hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
- ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
- hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
- ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
- hr = IDirect3DDevice9_EndScene(device);
- ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ | D3DFVF_TEX1 | D3DFVF_TEXCOORDSIZE3(0));
+ ok(SUCCEEDED(hr), "Failed to set FVF, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTexture(device, 0, (IDirect3DBaseTexture9 *)texture);
+ ok(SUCCEEDED(hr), "Failed to set texture, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TEXTURE);
+ ok(SUCCEEDED(hr), "Failed to set color arg, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 1, D3DTSS_COLOROP, D3DTOP_DISABLE);
+ ok(SUCCEEDED(hr), "Failed to set color op, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetSamplerState(device, 0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
+ ok(SUCCEEDED(hr), "Failed to set mag filter, hr %#x.\n", hr);
- for (i = 0; i < 4; i++)
- {
- color = getPixelColor(device, 80 + 160 * i, 240);
- ok (color_match(color, expected_colors[i], 1),
- "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[i], color, i);
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00ff00ff, 1.0f, 0);
+ ok(SUCCEEDED(hr), "Failed to clear, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(SUCCEEDED(hr), "Failed to begin scene, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[0], sizeof(*quads));
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, &quads[4], sizeof(*quads));
+ ok(SUCCEEDED(hr), "Failed to draw, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
+
+ for (i = 0; i < 8; i++)
+ {
+ color = getAlphaPixelColor(device, 40 + 80 * i, 240);
+ ok (color_match(color, expected_colors[x][i], 1),
+ "Expected color 0x%08x, got 0x%08x, case %u.\n", expected_colors[x][i], color, i);
+ }
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
+ IDirect3DVolumeTexture9_Release(texture);
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
}
- hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
- ok(SUCCEEDED(hr), "Failed to present, hr %#x.\n", hr);
- IDirect3DVolumeTexture9_Release(texture);
- refcount = IDirect3DDevice9_Release(device);
- ok(!refcount, "Device has %u references left.\n", refcount);
-done:
IDirect3D9_Release(d3d);
DestroyWindow(window);
}
@@ -24131,7 +24203,7 @@ START_TEST(visual)
zenable_test();
fog_special_test();
volume_srgb_test();
- volume_dxt5_test();
+ volume_dxtn_test();
add_dirty_rect_test();
multisampled_depth_buffer_test();
resz_test();
--
2.7.4
June 21, 2018
[PATCH 2/3] Add format change before upload for non-volume textures
by Connor McAdams
This patch keeps non-volume DXTn textures from being converted to
b8g8r8a8. I have tested it and it does work converting them all, but the
GPU can handle them normally. Volume textures are the only ones the
GPU handles incorrectly.
---
dlls/wined3d/texture.c | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index c316906..a998b9c 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -1948,6 +1948,32 @@ void wined3d_texture_upload_data(struct wined3d_texture *texture, unsigned int s
bo.addr += src_box->left * format->byte_count;
}
+ if (format->id == WINED3DFMT_DXT5 || format->id == WINED3DFMT_DXT4 ||
+ format->id == WINED3DFMT_DXT3 || format->id == WINED3DFMT_DXT2 ||
+ format->id == WINED3DFMT_DXT1)
+ {
+ if (target == GL_TEXTURE_3D)
+ {
+ struct wined3d_format temp;
+
+ f = *format;
+ temp.upload = f.upload;
+ format = &f;
+ format = wined3d_get_format(gl_info, WINED3DFMT_B8G8R8A8_UNORM, WINED3DUSAGE_TEXTURE);
+ f = *format;
+ f.upload = temp.upload;
+ f.conv_byte_count = 4;
+ format = &f;
+ texture->resource.format_flags &= ~WINED3DFMT_FLAG_BLOCKS;
+ }
+ else
+ {
+ f = *format;
+ f.upload = NULL;
+ format = &f;
+ }
+ }
+
if (format->upload)
{
unsigned int dst_row_pitch, dst_slice_pitch;
--
2.7.4
June 21, 2018
[PATCH 1/3] Add decompression functions for DXT1, DXT3, and DXT5
by Connor McAdams
This adds decompression functions for DXT1, DXT3, and DXT5 formats,
which covers all the possible DXT formats. These are used for
decompressing DXTn volume textures, and converting them to b8g8r8a8.
---
dlls/wined3d/utils.c | 321 ++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 305 insertions(+), 16 deletions(-)
diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c
index 937c1bc..ce1ccdf 100644
--- a/dlls/wined3d/utils.c
+++ b/dlls/wined3d/utils.c
@@ -840,6 +840,305 @@ static void convert_s8_uint_d24_float(const BYTE *src, BYTE *dst, UINT src_row_p
}
}
+static void dxt5_decompress_block(const BYTE *src, BYTE *dst, UINT width, UINT height, UINT depth,
+ unsigned int x_pos, unsigned int y_pos, unsigned int z_pos, UINT dst_slice_pitch, UINT64 cur_block)
+{
+ DWORD alpha_lookup;
+ DWORD bgra;
+ DWORD temp;
+ UINT64 alpha_block, alpha_index, color_block, color_index;
+ DWORD *Dest;
+ const UINT64 *Source;
+ unsigned short color[2];
+ unsigned int i, x, y;
+ unsigned char alpha_val, color_val;
+ unsigned char alpha[8];
+ unsigned char r[4];
+ unsigned char g[4];
+ unsigned char b[4];
+
+ Source = (const UINT64 *)(src + cur_block * 16);
+ alpha_block = Source[0];
+ color_block = Source[1];
+
+ alpha[0] = alpha_block & 0xFF;
+ alpha[1] = (alpha_block >> 8) & 0xFF;
+
+ /* Generate alpha lookup values */
+ if (alpha[0] > alpha[1])
+ {
+ for (i = 0; i < 6; i++)
+ alpha[2 + i] = (((6 - i) * alpha[0]) + ((1 + i) * alpha[1])) / 7;
+ }
+ else if (alpha[0] <= alpha[1])
+ {
+ for (i = 0; i < 4; i++)
+ alpha[2 + i] = (((4 - i) * alpha[0]) + ((1 + i) * alpha[1])) / 5;
+ alpha[6] = 0;
+ alpha[7] = 255;
+ }
+
+ /* Generate color lookup values */
+ color[0] = color_block & 0xFFFF;
+ color[1] = (color_block >> 16) & 0xFFFF;
+
+ for (i = 0; i < 2; i++)
+ {
+ temp = (color[i] >> 11) * 255 + 16;
+ r[i] = (temp / 32 + temp) / 32;
+ temp = ((color[i] >> 5) & 0x3F) * 255 + 32;
+ g[i] = (temp / 64 + temp) / 64;
+ temp = (color[i] & 0x1F) * 255 + 16;
+ b[i] = (temp / 32 + temp) / 32;
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ r[2 + i] = (2 * r[0 + i] + r[1 - i]) / 3;
+ g[2 + i] = (2 * g[0 + i] + g[1 - i]) / 3;
+ b[2 + i] = (2 * b[0 + i] + b[1 - i]) / 3;
+ }
+
+ color_index = (color_block >> 32) & 0xFFFFFFFF;
+ alpha_index = (alpha_block >> 16);
+
+ Dest = (DWORD *)(dst + z_pos * dst_slice_pitch);
+
+ for (y = 0; y < 4; y++) {
+ if (y_pos + y >= height)
+ break;
+ for (x = 0; x < 4; x++) {
+ if (x_pos + x >= width)
+ break;
+
+ color_val = 0;
+ alpha_val = 0;
+ bgra = 0;
+
+ color_val = (color_index >> (y * 8));
+ color_val = (color_val >> (x * 2)) & 0x3;
+ alpha_lookup = (alpha_index >> (y * 12)) & 0xFFF;
+ alpha_val = (alpha_lookup >> (x * 3)) & 0x7;
+ bgra = ((alpha[alpha_val] << 24) | (r[color_val] << 16) | (g[color_val] << 8) | b[color_val]);
+ Dest[(y_pos + y) * width + (x_pos + x)] = bgra;
+ }
+ }
+}
+
+static void convert_dxt5_b8g8r8a8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
+ UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
+{
+ UINT64 current_block;
+ unsigned int x, y, z;
+
+ current_block = 0;
+
+ for (z = 0; z < depth; z++)
+ {
+ for (y = 0; y < height; y += 4)
+ {
+ for (x = 0; x < width; x += 4)
+ {
+ dxt5_decompress_block(src, dst, width, height, depth, x, y, z, dst_slice_pitch, current_block);
+ current_block++;
+ }
+ }
+ }
+}
+
+static void dxt3_decompress_block(const BYTE *src, BYTE *dst, UINT width, UINT height, UINT depth,
+ unsigned int x_pos, unsigned int y_pos, unsigned int z_pos, UINT dst_slice_pitch, UINT64 cur_block)
+{
+ DWORD bgra;
+ DWORD temp;
+ UINT64 alpha_block, alpha_lookup, color_block, color_index;
+ DWORD *Dest;
+ const UINT64 *Source;
+ unsigned short color[2];
+ unsigned int i, x, y;
+ unsigned char alpha_val, color_val;
+ unsigned char r[4];
+ unsigned char g[4];
+ unsigned char b[4];
+
+ Source = (const UINT64 *)(src + cur_block * 16);
+ alpha_block = Source[0];
+ color_block = Source[1];
+
+ /* Generate color lookup values */
+ color[0] = color_block & 0xFFFF;
+ color[1] = (color_block >> 16) & 0xFFFF;
+
+ for (i = 0; i < 2; i++)
+ {
+ temp = (color[i] >> 11) * 255 + 16;
+ r[i] = (temp / 32 + temp) / 32;
+ temp = ((color[i] >> 5) & 0x3F) * 255 + 32;
+ g[i] = (temp / 64 + temp) / 64;
+ temp = (color[i] & 0x1F) * 255 + 16;
+ b[i] = (temp / 32 + temp) / 32;
+ }
+
+ for (i = 0; i < 2; i++)
+ {
+ r[2 + i] = (2 * r[0 + i] + r[1 - i]) / 3;
+ g[2 + i] = (2 * g[0 + i] + g[1 - i]) / 3;
+ b[2 + i] = (2 * b[0 + i] + b[1 - i]) / 3;
+ }
+
+ color_index = (color_block >> 32) & 0xFFFFFFFF;
+ Dest = (DWORD *)(dst + z_pos * dst_slice_pitch);
+
+ for (y = 0; y < 4; y++) {
+ if (y_pos + y >= height)
+ break;
+ for (x = 0; x < 4; x++) {
+ if (x_pos + x >= width)
+ break;
+
+ color_val = 0;
+ alpha_val = 0;
+ bgra = 0;
+
+ color_val = (color_index >> (y * 8));
+ color_val = (color_val >> (x * 2)) & 0x3;
+
+ alpha_lookup = (alpha_block >> (y * 16)) & 0xFFFF;
+ alpha_val = (alpha_lookup >> (x * 4)) & 0xF;
+ temp = alpha_val * 255 + 8;
+ alpha_val = (temp / 16 + temp) / 16;
+
+ bgra = ((alpha_val << 24) | (r[color_val] << 16) | (g[color_val] << 8) | b[color_val]);
+ Dest[(y_pos + y) * width + (x_pos + x)] = bgra;
+ }
+ }
+}
+
+static void convert_dxt3_b8g8r8a8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
+ UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
+{
+ UINT64 current_block;
+ unsigned int x, y, z;
+
+ current_block = 0;
+
+ for (z = 0; z < depth; z++)
+ {
+ for (y = 0; y < height; y += 4)
+ {
+ for (x = 0; x < width; x += 4)
+ {
+ dxt3_decompress_block(src, dst, width, height, depth, x, y, z, dst_slice_pitch, current_block);
+ current_block++;
+ }
+ }
+ }
+}
+
+static void dxt1_decompress_block(const BYTE *src, BYTE *dst, UINT width, UINT height, UINT depth,
+ unsigned int x_pos, unsigned int y_pos, unsigned int z_pos, UINT dst_slice_pitch, UINT64 cur_block)
+{
+ DWORD bgra;
+ DWORD temp;
+ UINT64 color_block, color_index;
+ DWORD *Dest;
+ const UINT64 *Source;
+ unsigned short color[2];
+ unsigned int i, x, y;
+ unsigned char color_val;
+ unsigned char alpha;
+ unsigned char r[4];
+ unsigned char g[4];
+ unsigned char b[4];
+ unsigned char use_alpha;
+
+ Source = (const UINT64 *)(src + cur_block * 8);
+ color_block = Source[0];
+
+ /* Generate color lookup values */
+ color[0] = color_block & 0xFFFF;
+ color[1] = (color_block >> 16) & 0xFFFF;
+
+ for (i = 0; i < 2; i++)
+ {
+ temp = (color[i] >> 11) * 255 + 16;
+ r[i] = (temp / 32 + temp) / 32;
+ temp = ((color[i] >> 5) & 0x3F) * 255 + 32;
+ g[i] = (temp / 64 + temp) / 64;
+ temp = (color[i] & 0x1F) * 255 + 16;
+ b[i] = (temp / 32 + temp) / 32;
+ }
+
+ if (color[0] > color[1])
+ {
+ for (i = 0; i < 2; i++)
+ {
+ r[2 + i] = (2 * r[0 + i] + r[1 - i]) / 3;
+ g[2 + i] = (2 * g[0 + i] + g[1 - i]) / 3;
+ b[2 + i] = (2 * b[0 + i] + b[1 - i]) / 3;
+ }
+ use_alpha = 0;
+ }
+ else if (color[0] <= color[1])
+ {
+ r[2] = (r[0] + r[1]) / 2;
+ g[2] = (g[0] + g[1]) / 2;
+ b[2] = (b[0] + b[1]) / 2;
+
+ r[3] = 0;
+ g[3] = 0;
+ b[3] = 0;
+
+ use_alpha = 1;
+ }
+
+ color_index = (color_block >> 32) & 0xFFFFFFFF;
+ Dest = (DWORD *)(dst + z_pos * dst_slice_pitch);
+
+ for (y = 0; y < 4; y++) {
+ if (y_pos + y >= height)
+ break;
+ for (x = 0; x < 4; x++) {
+ if (x_pos + x >= width)
+ break;
+
+ color_val = 0;
+ bgra = 0;
+
+ color_val = (color_index >> (y * 8));
+ color_val = (color_val >> (x * 2)) & 0x3;
+ if (color_val == 3 && use_alpha == 1)
+ alpha = 0;
+ else
+ alpha = 255;
+
+ bgra = ((alpha << 24) | (r[color_val] << 16) | (g[color_val] << 8) | b[color_val]);
+ Dest[(y_pos + y) * width + (x_pos + x)] = bgra;
+ }
+ }
+}
+
+static void convert_dxt1_b8g8r8a8_unorm(const BYTE *src, BYTE *dst, UINT src_row_pitch, UINT src_slice_pitch,
+ UINT dst_row_pitch, UINT dst_slice_pitch, UINT width, UINT height, UINT depth)
+{
+ UINT64 current_block;
+ unsigned int x, y, z;
+
+ current_block = 0;
+
+ for (z = 0; z < depth; z++)
+ {
+ for (y = 0; y < height; y += 4)
+ {
+ for (x = 0; x < width; x += 4)
+ {
+ dxt1_decompress_block(src, dst, width, height, depth, x, y, z, dst_slice_pitch, current_block);
+ current_block++;
+ }
+ }
+ }
+}
+
static void x8_d24_unorm_upload(const BYTE *src, BYTE *dst,
unsigned int src_row_pitch, unsigned int src_slice_pitch,
unsigned int dst_row_pitch, unsigned int dst_slice_pitch,
@@ -1118,27 +1417,27 @@ static const struct wined3d_format_texture_info format_texture_info[] =
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt1_b8g8r8a8_unorm},
{WINED3DFMT_DXT2, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt3_b8g8r8a8_unorm},
{WINED3DFMT_DXT3, GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt3_b8g8r8a8_unorm},
{WINED3DFMT_DXT4, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt5_b8g8r8a8_unorm},
{WINED3DFMT_DXT5, GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
| WINED3DFMT_FLAG_SRGB_READ | WINED3DFMT_FLAG_COMPRESSED,
- EXT_TEXTURE_COMPRESSION_S3TC, NULL},
+ EXT_TEXTURE_COMPRESSION_S3TC, convert_dxt5_b8g8r8a8_unorm},
{WINED3DFMT_BC1_UNORM, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT, 0,
GL_RGBA, GL_UNSIGNED_BYTE, 0,
WINED3DFMT_FLAG_TEXTURE | WINED3DFMT_FLAG_POSTPIXELSHADER_BLENDING | WINED3DFMT_FLAG_FILTERING
@@ -3394,17 +3693,7 @@ static void apply_format_fixups(struct wined3d_adapter *adapter, struct wined3d_
* for dx9 GPUs support it, some do not, so not supporting DXTn volumes is OK for d3d9.
*
* Note that GL_NV_texture_compression_vtc adds this functionality to OpenGL, but the
- * block layout is not compatible with the one used by d3d. See volume_dxt5_test. */
- idx = get_format_idx(WINED3DFMT_DXT1);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT2);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT3);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT4);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
- idx = get_format_idx(WINED3DFMT_DXT5);
- gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
+ * block layout is not compatible with the one used by d3d. See volume_dxtn_test. */
idx = get_format_idx(WINED3DFMT_BC1_UNORM);
gl_info->formats[idx].flags[WINED3D_GL_RES_TYPE_TEX_3D] &= ~WINED3DFMT_FLAG_TEXTURE;
idx = get_format_idx(WINED3DFMT_BC1_UNORM_SRGB);
--
2.7.4
June 21, 2018
[PATCH 0/3] Add DXTn 3D texture support.
by Connor McAdams
This patch series adds support for using DXTn volume textures, by
decompressing and converting them using the CPU. This fixes issues with games
such as Halo Online, and others mentioned in the bugzilla page here:
https://bugs.winehq.org/show_bug.cgi?id=39253
Let me know what needs changed or fixed, this is my first patch, so I assume
it wont be perfect. :)
Thanks,
Connor McAdams (Conmanx360 in IRC)
Connor McAdams (3):
Add decompression functions for DXT1, DXT3, and DXT5
Add format change before upload for non-volume textures
Add new test for DXTn volume textures.
dlls/d3d9/tests/visual.c | 190 +++++++++++++++++++---------
dlls/wined3d/texture.c | 26 ++++
dlls/wined3d/utils.c | 321 ++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 462 insertions(+), 75 deletions(-)
--
2.7.4
June 21, 2018
[PATCH 2/2] msi: Add support for re-caching package
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msi/action.c | 42 ++++++++++++++++++++++++++++++++++++++----
dlls/msi/msi.c | 27 +++++++++++++++++++++------
dlls/msi/msipriv.h | 4 +++-
dlls/msi/package.c | 14 ++++++++++++--
dlls/msi/tests/package.c | 6 +++---
5 files changed, 77 insertions(+), 16 deletions(-)
June 21, 2018
[PATCH 1/2] msi: Report error when cached installer has different version
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msi/package.c | 114
+++++++++++++++++++++++++----------------------
dlls/msi/tests/package.c | 6 +--
2 files changed, 63 insertions(+), 57 deletions(-)
June 21, 2018
[PATCH] winex11.drv: Move condition to the proper place.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
dlls/winex11.drv/event.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/event.c b/dlls/winex11.drv/event.c
index a0bfe052df..4aee41586f 100644
--- a/dlls/winex11.drv/event.c
+++ b/dlls/winex11.drv/event.c
@@ -1627,8 +1627,8 @@ static void EVENT_DropURLs( HWND hWnd, XClientMessageEvent *event )
PostMessageA( hWnd, WM_DROPFILES, (WPARAM)hDrop, 0L );
}
}
- if( p_data ) XFree(p_data);
}
+ if( p_data ) XFree(p_data);
}
--
2.17.1
June 21, 2018
[PATCH v2] comctl32/imagelist: fix ImageList_Read/Write.
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 | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index a08d60752e..eadbf134b4 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -80,9 +80,11 @@ struct _IMAGELIST
BOOL color_table_set;
LONG ref; /* reference count */
+ USHORT usVersion; /* keep stream version here */
};
#define IMAGELIST_MAGIC 0x53414D58
+#define IMAGELIST_VERSION 0x101
/* Header used by ImageList_Read() and ImageList_Write() */
#include "pshpack2.h"
@@ -806,6 +808,7 @@ ImageList_Create (INT cx, INT cy, UINT flags,
himl->clrFg = CLR_DEFAULT;
himl->clrBk = CLR_NONE;
himl->color_table_set = FALSE;
+ himl->usVersion = 0;
/* initialize overlay mask indices */
for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
@@ -2267,7 +2270,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 != IMAGELIST_VERSION &&
+ 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",
@@ -2277,6 +2282,9 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
if (!himl)
return NULL;
+ /* keep version from stream */
+ himl->usVersion = ilHead.usVersion;
+
if (!(image_bits = read_bitmap(pstm, image_info)))
{
WARN("failed to read bitmap from stream\n");
@@ -2296,23 +2304,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 != IMAGELIST_VERSION ? himl->cx : image_info->bmiHeader.biWidth);
+ int image_step = ilHead.usVersion != IMAGELIST_VERSION ? 1 : TILE_COUNT;
+ int mask_step = ilHead.usVersion != IMAGELIST_VERSION ? 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 21, 2018
[PATCH 7/7] ninput: Add RegisterOutputCallbackInteractionContext() stub.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/ninput/main.c | 13 +++++++++++++
dlls/ninput/ninput.spec | 2 +-
2 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/dlls/ninput/main.c b/dlls/ninput/main.c
index 01703749d087..5d2be62fec21 100644
--- a/dlls/ninput/main.c
+++ b/dlls/ninput/main.c
@@ -148,6 +148,19 @@ HRESULT WINAPI SetInteractionConfigurationInteractionContext(HINTERACTIONCONTEXT
return S_OK;
}
+HRESULT WINAPI RegisterOutputCallbackInteractionContext(HINTERACTIONCONTEXT handle,
+ INTERACTION_CONTEXT_OUTPUT_CALLBACK callback, void *data)
+{
+ struct interaction_context *context = context_from_handle(handle);
+
+ FIXME("context %p, callback %p, data %p: stub!.\n", context, callback, data);
+
+ if (!context)
+ return E_HANDLE;
+
+ return S_OK;
+}
+
HRESULT WINAPI ProcessInertiaInteractionContext(HINTERACTIONCONTEXT context)
{
FIXME("context %p: stub!\n", context);
diff --git a/dlls/ninput/ninput.spec b/dlls/ninput/ninput.spec
index 70d296cc597f..e2897872b683 100644
--- a/dlls/ninput/ninput.spec
+++ b/dlls/ninput/ninput.spec
@@ -12,7 +12,7 @@
@ stub ProcessBufferedPacketsInteractionContext
@ stdcall ProcessInertiaInteractionContext(ptr)
@ stub ProcessPointerFramesInteractionContext
-@ stub RegisterOutputCallbackInteractionContext
+@ stdcall RegisterOutputCallbackInteractionContext(ptr ptr ptr)
@ stub RemovePointerInteractionContext
@ stub ResetInteractionContext
@ stub SetCrossSlideParametersInteractionContext
--
2.16.4
June 21, 2018
[PATCH 6/7] ninput: Add SetInteractionConfigurationInteractionContext() stub.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/ninput/main.c | 17 +++++++++++++++++
dlls/ninput/ninput.spec | 2 +-
dlls/ninput/tests/ninput.c | 36 ++++++++++++++++++++++++++++++++++++
3 files changed, 54 insertions(+), 1 deletion(-)
diff --git a/dlls/ninput/main.c b/dlls/ninput/main.c
index 90f9e7e0c4ee..01703749d087 100644
--- a/dlls/ninput/main.c
+++ b/dlls/ninput/main.c
@@ -131,6 +131,23 @@ HRESULT WINAPI SetPropertyInteractionContext(HINTERACTIONCONTEXT handle,
}
}
+HRESULT WINAPI SetInteractionConfigurationInteractionContext(HINTERACTIONCONTEXT handle,
+ UINT32 count, const INTERACTION_CONTEXT_CONFIGURATION *configuration)
+{
+ struct interaction_context *context = context_from_handle(handle);
+
+ FIXME("context %p, count %u, configuration %p: stub!.\n", context, count, configuration);
+
+ if (!context)
+ return E_HANDLE;
+ if (!count)
+ return E_INVALIDARG;
+ if (!configuration)
+ return E_POINTER;
+
+ return S_OK;
+}
+
HRESULT WINAPI ProcessInertiaInteractionContext(HINTERACTIONCONTEXT context)
{
FIXME("context %p: stub!\n", context);
diff --git a/dlls/ninput/ninput.spec b/dlls/ninput/ninput.spec
index 166e3d1ec8c1..70d296cc597f 100644
--- a/dlls/ninput/ninput.spec
+++ b/dlls/ninput/ninput.spec
@@ -17,7 +17,7 @@
@ stub ResetInteractionContext
@ stub SetCrossSlideParametersInteractionContext
@ stub SetInertiaParameterInteractionContext
-@ stub SetInteractionConfigurationInteractionContext
+@ stdcall SetInteractionConfigurationInteractionContext(ptr long ptr)
@ stub SetMouseWheelParameterInteractionContext
@ stub SetPivotInteractionContext
@ stdcall SetPropertyInteractionContext(ptr long long)
diff --git a/dlls/ninput/tests/ninput.c b/dlls/ninput/tests/ninput.c
index 156e3e898366..7fd389378b01 100644
--- a/dlls/ninput/tests/ninput.c
+++ b/dlls/ninput/tests/ninput.c
@@ -82,8 +82,44 @@ static void test_properties(void)
ok(hr == S_OK, "Failed to destroy context, hr %#x.\n", hr);
}
+static void test_configuration(void)
+{
+ HINTERACTIONCONTEXT context;
+ HRESULT hr;
+
+ static const INTERACTION_CONTEXT_CONFIGURATION config[] =
+ {
+ {
+ INTERACTION_ID_MANIPULATION,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_X |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_Y |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_SCALING |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_INERTIA |
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_SCALING_INERTIA
+ },
+ };
+
+ hr = CreateInteractionContext(&context);
+ ok(hr == S_OK, "Failed to create context, hr %#x.\n", hr);
+
+ hr = SetInteractionConfigurationInteractionContext(NULL, 0, NULL);
+ ok(hr == E_HANDLE, "Got hr %#x.\n", hr);
+ hr = SetInteractionConfigurationInteractionContext(context, 0, NULL);
+ ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ hr = SetInteractionConfigurationInteractionContext(context, 1, NULL);
+ ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+
+ hr = SetInteractionConfigurationInteractionContext(context, ARRAY_SIZE(config), config);
+ ok(hr == S_OK, "Failed to set configuration, hr %#x.\n", hr);
+
+ hr = DestroyInteractionContext(context);
+ ok(hr == S_OK, "Failed to destroy context, hr %#x.\n", hr);
+}
+
START_TEST(ninput)
{
test_context();
test_properties();
+ test_configuration();
}
--
2.16.4
June 21, 2018
[PATCH 5/7] ninput: Implement SetPropertyInteractionContext().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/ninput/main.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++
dlls/ninput/ninput.spec | 4 ++--
dlls/ninput/tests/ninput.c | 48 +++++++++++++++++++++++++++++++++++++
3 files changed, 109 insertions(+), 2 deletions(-)
diff --git a/dlls/ninput/main.c b/dlls/ninput/main.c
index 932d159ab390..90f9e7e0c4ee 100644
--- a/dlls/ninput/main.c
+++ b/dlls/ninput/main.c
@@ -72,6 +72,65 @@ HRESULT WINAPI DestroyInteractionContext(HINTERACTIONCONTEXT handle)
return S_OK;
}
+HRESULT WINAPI GetPropertyInteractionContext(HINTERACTIONCONTEXT handle,
+ INTERACTION_CONTEXT_PROPERTY property, UINT32 *value)
+{
+ struct interaction_context *context = context_from_handle(handle);
+
+ TRACE("context %p, property %#x, value %p.\n", context, property, value);
+
+ if (!context)
+ return E_HANDLE;
+ if (!value)
+ return E_POINTER;
+
+ switch (property)
+ {
+ case INTERACTION_CONTEXT_PROPERTY_MEASUREMENT_UNITS:
+ case INTERACTION_CONTEXT_PROPERTY_INTERACTION_UI_FEEDBACK:
+ FIXME("Unhandled property %#x.\n", property);
+ *value = 0;
+ return E_NOTIMPL;
+
+ case INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS:
+ *value = context->filter_pointers;
+ return S_OK;
+
+ default:
+ WARN("Invalid property %#x.\n", property);
+ return E_INVALIDARG;
+ }
+}
+
+HRESULT WINAPI SetPropertyInteractionContext(HINTERACTIONCONTEXT handle,
+ INTERACTION_CONTEXT_PROPERTY property, UINT32 value)
+{
+ struct interaction_context *context = context_from_handle(handle);
+
+ TRACE("context %p, property %#x, value %#x.\n", context, property, value);
+
+ if (!context)
+ return E_HANDLE;
+
+ switch (property)
+ {
+ case INTERACTION_CONTEXT_PROPERTY_MEASUREMENT_UNITS:
+ case INTERACTION_CONTEXT_PROPERTY_INTERACTION_UI_FEEDBACK:
+ FIXME("Unhandled property %#x.\n", property);
+ return E_NOTIMPL;
+
+ case INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS:
+ if (value != FALSE && value != TRUE)
+ return E_INVALIDARG;
+ context->filter_pointers = value;
+ return S_OK;
+
+ default:
+ WARN("Invalid property %#x.\n", property);
+ return E_INVALIDARG;
+ }
+}
+
HRESULT WINAPI ProcessInertiaInteractionContext(HINTERACTIONCONTEXT context)
{
FIXME("context %p: stub!\n", context);
diff --git a/dlls/ninput/ninput.spec b/dlls/ninput/ninput.spec
index fe7c6b3c53b3..166e3d1ec8c1 100644
--- a/dlls/ninput/ninput.spec
+++ b/dlls/ninput/ninput.spec
@@ -7,7 +7,7 @@
@ stub GetInertiaParameterInteractionContext
@ stub GetInteractionConfigurationInteractionContext
@ stub GetMouseWheelParameterInteractionContext
-@ stub GetPropertyInteractionContext
+@ stdcall GetPropertyInteractionContext(ptr long ptr)
@ stub GetStateInteractionContext
@ stub ProcessBufferedPacketsInteractionContext
@ stdcall ProcessInertiaInteractionContext(ptr)
@@ -20,5 +20,5 @@
@ stub SetInteractionConfigurationInteractionContext
@ stub SetMouseWheelParameterInteractionContext
@ stub SetPivotInteractionContext
-@ stub SetPropertyInteractionContext
+@ stdcall SetPropertyInteractionContext(ptr long long)
@ stub StopInteractionContext
diff --git a/dlls/ninput/tests/ninput.c b/dlls/ninput/tests/ninput.c
index d894ab8a847a..156e3e898366 100644
--- a/dlls/ninput/tests/ninput.c
+++ b/dlls/ninput/tests/ninput.c
@@ -35,7 +35,55 @@ static void test_context(void)
ok(hr == E_HANDLE, "Got hr %#x.\n", hr);
}
+static void test_properties(void)
+{
+ HINTERACTIONCONTEXT context;
+ UINT32 value;
+ HRESULT hr;
+
+ hr = CreateInteractionContext(&context);
+ ok(hr == S_OK, "Failed to create context, hr %#x.\n", hr);
+
+ hr = GetPropertyInteractionContext(context, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, &value);
+ ok(hr == S_OK, "Failed to get property, hr %#x.\n", hr);
+ ok(value == TRUE, "Got unexpected value %#x.\n", value);
+
+ hr = SetPropertyInteractionContext(context, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, TRUE);
+ ok(hr == S_OK, "Failed to set property, hr %#x.\n", hr);
+ hr = GetPropertyInteractionContext(context, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, &value);
+ ok(hr == S_OK, "Failed to get property, hr %#x.\n", hr);
+ ok(value == TRUE, "Got unexpected value %#x.\n", value);
+
+ hr = SetPropertyInteractionContext(context, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, FALSE);
+ ok(hr == S_OK, "Failed to set property, hr %#x.\n", hr);
+ hr = GetPropertyInteractionContext(context, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, &value);
+ ok(hr == S_OK, "Failed to get property, hr %#x.\n", hr);
+ ok(value == FALSE, "Got unexpected value %#x.\n", value);
+
+ hr = SetPropertyInteractionContext(context, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, 2);
+ ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ hr = SetPropertyInteractionContext(context, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, 3);
+ ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+
+ hr = SetPropertyInteractionContext(context, 0xdeadbeef, 0);
+ ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+ hr = GetPropertyInteractionContext(context, 0xdeadbeef, &value);
+ ok(hr == E_INVALIDARG, "Got hr %#x.\n", hr);
+
+ hr = GetPropertyInteractionContext(context, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, NULL);
+ ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+
+ hr = SetPropertyInteractionContext(NULL, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, FALSE);
+ ok(hr == E_HANDLE, "Got hr %#x.\n", hr);
+ hr = GetPropertyInteractionContext(NULL, INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS, &value);
+ ok(hr == E_HANDLE, "Got hr %#x.\n", hr);
+
+ hr = DestroyInteractionContext(context);
+ ok(hr == S_OK, "Failed to destroy context, hr %#x.\n", hr);
+}
+
START_TEST(ninput)
{
test_context();
+ test_properties();
}
--
2.16.4
June 21, 2018
[PATCH 4/7] ninput: Add ProcessInertiaInteractionContext() stub.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/ninput/main.c | 6 ++++++
dlls/ninput/ninput.spec | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
diff --git a/dlls/ninput/main.c b/dlls/ninput/main.c
index 1aa3c4652b6e..932d159ab390 100644
--- a/dlls/ninput/main.c
+++ b/dlls/ninput/main.c
@@ -72,6 +72,12 @@ HRESULT WINAPI DestroyInteractionContext(HINTERACTIONCONTEXT handle)
return S_OK;
}
+HRESULT WINAPI ProcessInertiaInteractionContext(HINTERACTIONCONTEXT context)
+{
+ FIXME("context %p: stub!\n", context);
+ return E_NOTIMPL;
+}
+
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
{
TRACE("(%p, %d, %p)\n", inst, reason, reserved);
diff --git a/dlls/ninput/ninput.spec b/dlls/ninput/ninput.spec
index 0717cb1c2f47..fe7c6b3c53b3 100644
--- a/dlls/ninput/ninput.spec
+++ b/dlls/ninput/ninput.spec
@@ -10,7 +10,7 @@
@ stub GetPropertyInteractionContext
@ stub GetStateInteractionContext
@ stub ProcessBufferedPacketsInteractionContext
-@ stub ProcessInertiaInteractionContext
+@ stdcall ProcessInertiaInteractionContext(ptr)
@ stub ProcessPointerFramesInteractionContext
@ stub RegisterOutputCallbackInteractionContext
@ stub RemovePointerInteractionContext
--
2.16.4
June 21, 2018
[PATCH 3/7] ninput: Implement CreateInteractionContext().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
For bug 44720
---
configure | 1 +
configure.ac | 1 +
dlls/ninput/Makefile.in | 1 +
dlls/ninput/main.c | 53 ++++++++++++++++++++++++++++++++++++++++---
dlls/ninput/ninput.spec | 4 ++--
dlls/ninput/tests/Makefile.in | 4 ++++
dlls/ninput/tests/ninput.c | 41 +++++++++++++++++++++++++++++++++
7 files changed, 100 insertions(+), 5 deletions(-)
create mode 100644 dlls/ninput/tests/Makefile.in
create mode 100644 dlls/ninput/tests/ninput.c
diff --git a/configure b/configure
index bcb660d56982..26aa115002d9 100755
--- a/configure
+++ b/configure
@@ -19023,6 +19023,7 @@ wine_fn_config_makefile dlls/netprofm enable_netprofm
wine_fn_config_makefile dlls/netprofm/tests enable_tests
wine_fn_config_makefile dlls/newdev enable_newdev
wine_fn_config_makefile dlls/ninput enable_ninput
+wine_fn_config_makefile dlls/ninput/tests enable_tests
wine_fn_config_makefile dlls/normaliz enable_normaliz
wine_fn_config_makefile dlls/npmshtml enable_npmshtml
wine_fn_config_makefile dlls/npptools enable_npptools
diff --git a/configure.ac b/configure.ac
index 469fa8d72977..0f7e130c322e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3522,6 +3522,7 @@ WINE_CONFIG_MAKEFILE(dlls/netprofm)
WINE_CONFIG_MAKEFILE(dlls/netprofm/tests)
WINE_CONFIG_MAKEFILE(dlls/newdev)
WINE_CONFIG_MAKEFILE(dlls/ninput)
+WINE_CONFIG_MAKEFILE(dlls/ninput/tests)
WINE_CONFIG_MAKEFILE(dlls/normaliz)
WINE_CONFIG_MAKEFILE(dlls/npmshtml)
WINE_CONFIG_MAKEFILE(dlls/npptools)
diff --git a/dlls/ninput/Makefile.in b/dlls/ninput/Makefile.in
index 3d3cc7fe85e8..8f1039b73c86 100644
--- a/dlls/ninput/Makefile.in
+++ b/dlls/ninput/Makefile.in
@@ -1,4 +1,5 @@
MODULE = ninput.dll
+IMPORTLIB = ninput
C_SRCS = \
main.c
diff --git a/dlls/ninput/main.c b/dlls/ninput/main.c
index 0f23128cfe4d..1aa3c4652b6e 100644
--- a/dlls/ninput/main.c
+++ b/dlls/ninput/main.c
@@ -22,19 +22,66 @@
#include "windef.h"
#include "winbase.h"
#include "wine/debug.h"
+#include "wine/heap.h"
+
+#include "interactioncontext.h"
WINE_DEFAULT_DEBUG_CHANNEL(ninput);
-BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD reason, LPVOID lpv)
+struct interaction_context
+{
+ BOOL filter_pointers;
+};
+
+static struct interaction_context *context_from_handle(HINTERACTIONCONTEXT handle)
+{
+ return (struct interaction_context *)handle;
+}
+
+HRESULT WINAPI CreateInteractionContext(HINTERACTIONCONTEXT *handle)
+{
+ struct interaction_context *context;
+
+ TRACE("handle %p.\n", handle);
+
+ if (!handle)
+ return E_POINTER;
+
+ if (!(context = heap_alloc(sizeof(*context))))
+ return E_OUTOFMEMORY;
+
+ context->filter_pointers = TRUE;
+
+ TRACE("Created context %p.\n", context);
+
+ *handle = (HINTERACTIONCONTEXT)context;
+
+ return S_OK;
+}
+
+HRESULT WINAPI DestroyInteractionContext(HINTERACTIONCONTEXT handle)
+{
+ struct interaction_context *context = context_from_handle(handle);
+
+ TRACE("context %p.\n", context);
+
+ if (!context)
+ return E_HANDLE;
+
+ heap_free(context);
+ return S_OK;
+}
+
+BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, void *reserved)
{
- TRACE("(%p, %d, %p)\n", hInstDLL, reason, lpv);
+ TRACE("(%p, %d, %p)\n", inst, reason, reserved);
switch (reason)
{
case DLL_WINE_PREATTACH:
return FALSE; /* prefer native version */
case DLL_PROCESS_ATTACH:
- DisableThreadLibraryCalls(hInstDLL);
+ DisableThreadLibraryCalls(inst);
break;
}
return TRUE;
diff --git a/dlls/ninput/ninput.spec b/dlls/ninput/ninput.spec
index 372beb20eb15..0717cb1c2f47 100644
--- a/dlls/ninput/ninput.spec
+++ b/dlls/ninput/ninput.spec
@@ -1,8 +1,8 @@
@ stub DefaultInputHandler
@ stub AddPointerInteractionContext
@ stub BufferPointerPacketsInteractionContext
-@ stub CreateInteractionContext
-@ stub DestroyInteractionContext
+@ stdcall CreateInteractionContext(ptr)
+@ stdcall DestroyInteractionContext(ptr)
@ stub GetCrossSlideParameterInteractionContext
@ stub GetInertiaParameterInteractionContext
@ stub GetInteractionConfigurationInteractionContext
diff --git a/dlls/ninput/tests/Makefile.in b/dlls/ninput/tests/Makefile.in
new file mode 100644
index 000000000000..9c0b44fa17dc
--- /dev/null
+++ b/dlls/ninput/tests/Makefile.in
@@ -0,0 +1,4 @@
+TESTDLL = ninput.dll
+IMPORTS = ninput
+
+C_SRCS = ninput.c
diff --git a/dlls/ninput/tests/ninput.c b/dlls/ninput/tests/ninput.c
new file mode 100644
index 000000000000..d894ab8a847a
--- /dev/null
+++ b/dlls/ninput/tests/ninput.c
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2018 Józef Kucia
+ *
+ * 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 "interactioncontext.h"
+#include "wine/test.h"
+
+static void test_context(void)
+{
+ HINTERACTIONCONTEXT context;
+ HRESULT hr;
+
+ hr = CreateInteractionContext(&context);
+ ok(hr == S_OK, "Failed to create context, hr %#x.\n", hr);
+ hr = DestroyInteractionContext(context);
+ ok(hr == S_OK, "Failed to destroy context, hr %#x.\n", hr);
+
+ hr = CreateInteractionContext(NULL);
+ ok(hr == E_POINTER, "Got hr %#x.\n", hr);
+ hr = DestroyInteractionContext(NULL);
+ ok(hr == E_HANDLE, "Got hr %#x.\n", hr);
+}
+
+START_TEST(ninput)
+{
+ test_context();
+}
--
2.16.4
June 21, 2018
[PATCH 2/7] include: Add interactioncontext.h.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
include/Makefile.in | 1 +
include/interactioncontext.h | 195 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 196 insertions(+)
create mode 100644 include/interactioncontext.h
diff --git a/include/Makefile.in b/include/Makefile.in
index 78ab095d77e7..72a701090047 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -314,6 +314,7 @@ SOURCES = \
inputscope.idl \
inseng.idl \
inspectable.idl \
+ interactioncontext.h \
intshcut.h \
ipexport.h \
iphlpapi.h \
diff --git a/include/interactioncontext.h b/include/interactioncontext.h
new file mode 100644
index 000000000000..a643b626cd7e
--- /dev/null
+++ b/include/interactioncontext.h
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2018 Józef Kucia
+ *
+ * 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
+ */
+
+#ifndef INTERACTION_CONTEXT_H
+#define INTERACTION_CONTEXT_H
+
+#include <windows.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* defined(__cplusplus) */
+
+DECLARE_HANDLE(HINTERACTIONCONTEXT);
+
+typedef enum INTERACTION_CONTEXT_PROPERTY
+{
+ INTERACTION_CONTEXT_PROPERTY_MEASUREMENT_UNITS = 1,
+ INTERACTION_CONTEXT_PROPERTY_INTERACTION_UI_FEEDBACK = 2,
+ INTERACTION_CONTEXT_PROPERTY_FILTER_POINTERS = 3,
+ INTERACTION_CONTEXT_PROPERTY_MAX = 0xffffffff,
+} INTERACTION_CONTEXT_PROPERTY;
+
+typedef enum INTERACTION_ID
+{
+ INTERACTION_ID_NONE = 0,
+ INTERACTION_ID_MANIPULATION = 1,
+ INTERACTION_ID_TAP = 2,
+ INTERACTION_ID_SECONDARY_TAP = 3,
+ INTERACTION_ID_HOLD = 4,
+ INTERACTION_ID_DRAG = 5,
+ INTERACTION_ID_CROSS_SLIDE = 6,
+ INTERACTION_ID_MAX = 0xffffffff,
+} INTERACTION_ID;
+
+typedef enum INTERACTION_FLAGS
+{
+ INTERACTION_FLAG_NONE = 0x00000000,
+ INTERACTION_FLAG_BEGIN = 0x00000001,
+ INTERACTION_FLAG_END = 0x00000002,
+ INTERACTION_FLAG_CANCEL = 0x00000004,
+ INTERACTION_FLAG_INERTIA = 0x00000008,
+ INTERACTION_FLAG_MAX = 0xffffffff,
+} INTERACTION_FLAGS;
+
+typedef enum INTERACTION_CONFIGURATION_FLAGS
+{
+ INTERACTION_CONFIGURATION_FLAG_NONE = 0x00000000,
+
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION = 0x00000001,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_X = 0x00000002,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_Y = 0x00000004,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_ROTATION = 0x00000008,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_SCALING = 0x00000010,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_TRANSLATION_INERTIA = 0x00000020,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_ROTATION_INERTIA = 0x00000040,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_SCALING_INERTIA = 0x00000080,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_RAILS_X = 0x00000100,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_RAILS_Y = 0x00000200,
+ INTERACTION_CONFIGURATION_FLAG_MANIPULATION_EXACT = 0x00000400,
+
+ INTERACTION_CONFIGURATION_FLAG_TAP = 0x00000001,
+ INTERACTION_CONFIGURATION_FLAG_TAP_DOUBLE = 0x00000002,
+
+ INTERACTION_CONFIGURATION_FLAG_SECONDARY_TAP = 0x00000001,
+
+ INTERACTION_CONFIGURATION_FLAG_HOLD = 0x00000001,
+ INTERACTION_CONFIGURATION_FLAG_HOLD_MOUSE = 0x00000002,
+
+ INTERACTION_CONFIGURATION_FLAG_DRAG = 0x00000001,
+
+ INTERACTION_CONFIGURATION_FLAG_CROSS_SLIDE = 0x00000001,
+ INTERACTION_CONFIGURATION_FLAG_CROSS_SLIDE_HORIZONTAL = 0x00000002,
+ INTERACTION_CONFIGURATION_FLAG_CROSS_SLIDE_SELECT = 0x00000004,
+ INTERACTION_CONFIGURATION_FLAG_CROSS_SLIDE_SPEED_BUMP = 0x00000008,
+ INTERACTION_CONFIGURATION_FLAG_CROSS_SLIDE_REARRANGE = 0x00000010,
+ INTERACTION_CONFIGURATION_FLAG_CROSS_SLIDE_EXACT = 0x00000020,
+
+ INTERACTION_CONFIGURATION_FLAG_MAX = 0xffffffff,
+} INTERACTION_CONFIGURATION_FLAGS;
+
+typedef struct INTERACTION_CONTEXT_CONFIGURATION
+{
+ INTERACTION_ID interactionId;
+ INTERACTION_CONFIGURATION_FLAGS enable;
+
+} INTERACTION_CONTEXT_CONFIGURATION;
+
+typedef struct MANIPULATION_TRANSFORM
+{
+ float translationX;
+ float translationY;
+ float scale;
+ float expansion;
+ float rotation;
+} MANIPULATION_TRANSFORM;
+
+typedef struct MANIPULATION_VELOCITY
+{
+ float velocityX;
+ float velocityY;
+ float velocityExapnsion;
+ float velocityAngular;
+} MANIPULATION_VELOCITY;
+
+typedef enum MANIPULATION_RAILS_STATE
+{
+ MANIPULATION_RAILS_STATE_UNDECIDED = 0,
+ MANIPULATION_RAILS_STATE_FREE = 1,
+ MANIPULATION_RAILS_STATE_RAILED = 2,
+ MANIPULATION_RAILS_STATE_MAX = 0xffffffff,
+} MANIPULATION_RAILS_STATE;
+
+typedef struct INTERACTION_ARGUMENTS_MANIPULATION
+{
+ MANIPULATION_TRANSFORM delta;
+ MANIPULATION_TRANSFORM cumulative;
+ MANIPULATION_VELOCITY veolcity;
+ MANIPULATION_RAILS_STATE railsState;
+} INTERACTION_ARGUMENTS_MANIPULATION;
+
+typedef struct INTERACTION_ARGUMENTS_TAP
+{
+ UINT32 count;
+} INTERACTION_ARGUMENTS_TAP;
+
+typedef enum CROSS_SLIDE_FLAGS
+{
+ CROSS_SLIDE_FLAGS_NONE = 0x00000000,
+ CROSS_SLIDE_FLAGS_SELECT = 0x00000001,
+ CROSS_SLIDE_FLAGS_SPEED_BUMP = 0x00000002,
+ CROSS_SLIDE_FLAGS_REARRANGE = 0x00000004,
+ CROSS_SLIDE_FLAGS_MAX = 0xffffffff,
+} CROSS_SLIDE_FLAGS;
+
+typedef struct INTERACTION_ARGUMENTS_CROSS_SLIDE
+{
+ CROSS_SLIDE_FLAGS flags;
+} INTERACTION_ARGUMENTS_CROSS_SLIDE;
+
+typedef struct INTERACTION_CONTEXT_OUTPUT
+{
+ INTERACTION_ID interactionId;
+ INTERACTION_FLAGS interactionFlags;
+ POINTER_INPUT_TYPE inputType;
+ float x;
+ float y;
+ union
+ {
+ INTERACTION_ARGUMENTS_MANIPULATION manipulation;
+ INTERACTION_ARGUMENTS_TAP tap;
+ INTERACTION_ARGUMENTS_CROSS_SLIDE crossSlide;
+ } arguments;
+} INTERACTION_CONTEXT_OUTPUT;
+
+typedef void (CALLBACK *INTERACTION_CONTEXT_OUTPUT_CALLBACK)(void *data,
+ const INTERACTION_CONTEXT_OUTPUT *output);
+
+HRESULT WINAPI CreateInteractionContext(HINTERACTIONCONTEXT *context);
+HRESULT WINAPI DestroyInteractionContext(HINTERACTIONCONTEXT context);
+
+HRESULT WINAPI ProcessInertiaInteractionContext(HINTERACTIONCONTEXT context);
+
+HRESULT WINAPI RegisterOutputCallbackInteractionContext(HINTERACTIONCONTEXT context,
+ INTERACTION_CONTEXT_OUTPUT_CALLBACK callback, void *data);
+
+HRESULT WINAPI GetInteractionConfigurationInteractionContext(HINTERACTIONCONTEXT context,
+ UINT32 count, INTERACTION_CONTEXT_CONFIGURATION *configuration);
+HRESULT WINAPI SetInteractionConfigurationInteractionContext(HINTERACTIONCONTEXT context,
+ UINT32 count, const INTERACTION_CONTEXT_CONFIGURATION *configuration);
+
+HRESULT WINAPI GetPropertyInteractionContext(HINTERACTIONCONTEXT context,
+ INTERACTION_CONTEXT_PROPERTY proerty, UINT32 *value);
+HRESULT WINAPI SetPropertyInteractionContext(HINTERACTIONCONTEXT context,
+ INTERACTION_CONTEXT_PROPERTY property, UINT32 value);
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif /* defined(__cplusplus) */
+
+#endif
--
2.16.4
June 21, 2018
[PATCH 1/7] include: Add POINTER_INPUT_TYPE.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
include/winuser.h | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/include/winuser.h b/include/winuser.h
index f546a4a1f3da..ceaf82dcb528 100644
--- a/include/winuser.h
+++ b/include/winuser.h
@@ -3377,6 +3377,15 @@ typedef struct tagPOINTER_DEVICE_INFO {
WCHAR productString[POINTER_DEVICE_PRODUCT_STRING_MAX];
} POINTER_DEVICE_INFO;
+enum tagPOINTER_INPUT_TYPE
+{
+ PT_POINTER = 1,
+ PT_TOUCH = 2,
+ PT_PEN = 3,
+ PT_MOUSE = 4,
+};
+typedef DWORD POINTER_INPUT_TYPE;
+
#if defined(_WINGDI_) && !defined(NOGDI)
WINUSERAPI LONG WINAPI ChangeDisplaySettingsA(LPDEVMODEA,DWORD);
WINUSERAPI LONG WINAPI ChangeDisplaySettingsW(LPDEVMODEW,DWORD);
--
2.16.4
June 21, 2018
[PATCH] shell32/tests: Don't test CommandLineToArgv() in test_argify().
by Zebediah Figura
This is essentially redundant. We should have tests for all behaviours of
CommandLineToArgv() above; the purpose of test_argify() is to test how
ShellExecute() et al. parses its parameters, and to show that this is
different from CommandLineToArgv().
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/shell32/tests/shlexec.c | 167 +++++++++++++++----------------------------
1 file changed, 59 insertions(+), 108 deletions(-)
diff --git a/dlls/shell32/tests/shlexec.c b/dlls/shell32/tests/shlexec.c
index c67cc46..ab77fa1 100644
--- a/dlls/shell32/tests/shlexec.c
+++ b/dlls/shell32/tests/shlexec.c
@@ -1418,8 +1418,8 @@ typedef struct
const char* verb;
const char* params;
int todo;
- cmdline_tests_t cmd;
- cmdline_tests_t broken;
+ const char *cmd;
+ const char *broken;
} argify_tests_t;
static const argify_tests_t argify_tests[] =
@@ -1429,33 +1429,28 @@ static const argify_tests_t argify_tests[] =
* parameters string, including the trailing spaces, no matter what
* arguments have already been used.
*/
- {"Params232S", "p2 p3 p4 ", 0xc2,
- {" p2 p3 \"p2\" \"p2 p3 p4 \"",
- {"", "p2", "p3", "p2", "p2 p3 p4 ", NULL}, 0}},
+ {"Params232S", "p2 p3 p4 ", TRUE,
+ " p2 p3 \"p2\" \"p2 p3 p4 \""},
/* Unquoted argument references like %2 don't automatically quote their
* argument. Similarly, when they are quoted they don't escape the quotes
* that their argument may contain.
*/
- {"Params232S", "\"p two\" p3 p4 ", 0x3f3,
- {" p two p3 \"p two\" \"\"p two\" p3 p4 \"",
- {"", "p", "two", "p3", "p two", "p", "two p3 p4 ", NULL}, 0}},
+ {"Params232S", "\"p two\" p3 p4 ", TRUE,
+ " p two p3 \"p two\" \"\"p two\" p3 p4 \""},
/* Only single digits are supported so only %1 to %9. Shown here with %20
* because %10 is a pain.
*/
- {"Params20", "p", 0,
- {" \"p0\"",
- {"", "p0", NULL}, 0}},
+ {"Params20", "p", FALSE,
+ " \"p0\""},
/* Only (double-)quotes have a special meaning. */
- {"Params23456", "'p2 p3` p4\\ $even", 0x40,
- {" \"'p2\" \"p3`\" \"p4\\\" \"$even\" \"\"",
- {"", "'p2", "p3`", "p4\" $even \"", NULL}, 0}},
+ {"Params23456", "'p2 p3` p4\\ $even", FALSE,
+ " \"'p2\" \"p3`\" \"p4\\\" \"$even\" \"\""},
- {"Params23456", "p=2 p-3 p4\tp4\rp4\np4", 0x1c2,
- {" \"p=2\" \"p-3\" \"p4\tp4\rp4\np4\" \"\" \"\"",
- {"", "p=2", "p-3", "p4\tp4\rp4\np4", "", "", NULL}, 0}},
+ {"Params23456", "p=2 p-3 p4\tp4\rp4\np4", TRUE,
+ " \"p=2\" \"p-3\" \"p4\tp4\rp4\np4\" \"\" \"\""},
/* In unquoted strings, quotes are treated are a parameter separator just
* like spaces! However they can be doubled to get a literal quote.
@@ -1463,125 +1458,102 @@ static const argify_tests_t argify_tests[] =
* 2n quotes -> n quotes
* 2n+1 quotes -> n quotes and a parameter separator
*/
- {"Params23456789", "one\"quote \"p four\" one\"quote p7", 0xff3,
- {" \"one\" \"quote\" \"p four\" \"one\" \"quote\" \"p7\" \"\" \"\"",
- {"", "one", "quote", "p four", "one", "quote", "p7", "", "", NULL}, 0}},
+ {"Params23456789", "one\"quote \"p four\" one\"quote p7", TRUE,
+ " \"one\" \"quote\" \"p four\" \"one\" \"quote\" \"p7\" \"\" \"\""},
- {"Params23456789", "two\"\"quotes \"p three\" two\"\"quotes p5", 0xf2,
- {" \"two\"quotes\" \"p three\" \"two\"quotes\" \"p5\" \"\" \"\" \"\" \"\"",
- {"", "twoquotes p", "three twoquotes", "p5", "", "", "", "", NULL}, 0}},
+ {"Params23456789", "two\"\"quotes \"p three\" two\"\"quotes p5", TRUE,
+ " \"two\"quotes\" \"p three\" \"two\"quotes\" \"p5\" \"\" \"\" \"\" \"\""},
- {"Params23456789", "three\"\"\"quotes \"p four\" three\"\"\"quotes p6", 0xff3,
- {" \"three\"\" \"quotes\" \"p four\" \"three\"\" \"quotes\" \"p6\" \"\" \"\"",
- {"", "three\"", "quotes", "p four", "three\"", "quotes", "p6", "", "", NULL}, 0}},
+ {"Params23456789", "three\"\"\"quotes \"p four\" three\"\"\"quotes p6", TRUE,
+ " \"three\"\" \"quotes\" \"p four\" \"three\"\" \"quotes\" \"p6\" \"\" \"\""},
- {"Params23456789", "four\"\"\"\"quotes \"p three\" four\"\"\"\"quotes p5", 0xf3,
- {" \"four\"\"quotes\" \"p three\" \"four\"\"quotes\" \"p5\" \"\" \"\" \"\" \"\"",
- {"", "four\"quotes p", "three fourquotes p5 \"", "", "", "", NULL}, 0}},
+ {"Params23456789", "four\"\"\"\"quotes \"p three\" four\"\"\"\"quotes p5", TRUE,
+ " \"four\"\"quotes\" \"p three\" \"four\"\"quotes\" \"p5\" \"\" \"\" \"\" \"\""},
/* Quoted strings cannot be continued by tacking on a non space character
* either.
*/
- {"Params23456", "\"p two\"p3 \"p four\"p5 p6", 0x1f3,
- {" \"p two\" \"p3\" \"p four\" \"p5\" \"p6\"",
- {"", "p two", "p3", "p four", "p5", "p6", NULL}, 0}},
+ {"Params23456", "\"p two\"p3 \"p four\"p5 p6", TRUE,
+ " \"p two\" \"p3\" \"p four\" \"p5\" \"p6\""},
/* In quoted strings, the quotes are halved and an odd number closes the
* string. Specifically:
* 2n quotes -> n quotes
* 2n+1 quotes -> n quotes and closes the string and hence the parameter
*/
- {"Params23456789", "\"one q\"uote \"p four\" \"one q\"uote p7", 0xff3,
- {" \"one q\" \"uote\" \"p four\" \"one q\" \"uote\" \"p7\" \"\" \"\"",
- {"", "one q", "uote", "p four", "one q", "uote", "p7", "", "", NULL}, 0}},
+ {"Params23456789", "\"one q\"uote \"p four\" \"one q\"uote p7", TRUE,
+ " \"one q\" \"uote\" \"p four\" \"one q\" \"uote\" \"p7\" \"\" \"\""},
- {"Params23456789", "\"two \"\" quotes\" \"p three\" \"two \"\" quotes\" p5", 0x1ff3,
- {" \"two \" quotes\" \"p three\" \"two \" quotes\" \"p5\" \"\" \"\" \"\" \"\"",
- {"", "two ", "quotes p", "three two", " quotes", "p5", "", "", "", "", NULL}, 0}},
+ {"Params23456789", "\"two \"\" quotes\" \"p three\" \"two \"\" quotes\" p5", TRUE,
+ " \"two \" quotes\" \"p three\" \"two \" quotes\" \"p5\" \"\" \"\" \"\" \"\""},
- {"Params23456789", "\"three q\"\"\"uotes \"p four\" \"three q\"\"\"uotes p7", 0xff3,
- {" \"three q\"\" \"uotes\" \"p four\" \"three q\"\" \"uotes\" \"p7\" \"\" \"\"",
- {"", "three q\"", "uotes", "p four", "three q\"", "uotes", "p7", "", "", NULL}, 0}},
+ {"Params23456789", "\"three q\"\"\"uotes \"p four\" \"three q\"\"\"uotes p7", TRUE,
+ " \"three q\"\" \"uotes\" \"p four\" \"three q\"\" \"uotes\" \"p7\" \"\" \"\""},
- {"Params23456789", "\"four \"\"\"\" quotes\" \"p three\" \"four \"\"\"\" quotes\" p5", 0xff3,
- {" \"four \"\" quotes\" \"p three\" \"four \"\" quotes\" \"p5\" \"\" \"\" \"\" \"\"",
- {"", "four \"", "quotes p", "three four", "", "quotes p5 \"", "", "", "", NULL}, 0}},
+ {"Params23456789", "\"four \"\"\"\" quotes\" \"p three\" \"four \"\"\"\" quotes\" p5", TRUE,
+ " \"four \"\" quotes\" \"p three\" \"four \"\" quotes\" \"p5\" \"\" \"\" \"\" \"\""},
/* The quoted string rules also apply to consecutive quotes at the start
* of a parameter but don't count the opening quote!
*/
- {"Params23456789", "\"\"twoquotes \"p four\" \"\"twoquotes p7", 0xbf3,
- {" \"\" \"twoquotes\" \"p four\" \"\" \"twoquotes\" \"p7\" \"\" \"\"",
- {"", "", "twoquotes", "p four", "", "twoquotes", "p7", "", "", NULL}, 0}},
+ {"Params23456789", "\"\"twoquotes \"p four\" \"\"twoquotes p7", TRUE,
+ " \"\" \"twoquotes\" \"p four\" \"\" \"twoquotes\" \"p7\" \"\" \"\""},
- {"Params23456789", "\"\"\"three quotes\" \"p three\" \"\"\"three quotes\" p5", 0x6f3,
- {" \"\"three quotes\" \"p three\" \"\"three quotes\" \"p5\" \"\" \"\" \"\" \"\"",
- {"", "three", "quotes p", "three \"three", "quotes p5 \"", "", "", "", NULL}, 0}},
+ {"Params23456789", "\"\"\"three quotes\" \"p three\" \"\"\"three quotes\" p5", TRUE,
+ " \"\"three quotes\" \"p three\" \"\"three quotes\" \"p5\" \"\" \"\" \"\" \"\""},
- {"Params23456789", "\"\"\"\"fourquotes \"p four\" \"\"\"\"fourquotes p7", 0xbf3,
- {" \"\"\" \"fourquotes\" \"p four\" \"\"\" \"fourquotes\" \"p7\" \"\" \"\"",
- {"", "\"", "fourquotes", "p four", "\"", "fourquotes", "p7", "", "", NULL}, 0}},
+ {"Params23456789", "\"\"\"\"fourquotes \"p four\" \"\"\"\"fourquotes p7", TRUE,
+ " \"\"\" \"fourquotes\" \"p four\" \"\"\" \"fourquotes\" \"p7\" \"\" \"\""},
/* An unclosed quoted string gets lost! */
- {"Params23456", "p2 \"p3\" \"p4 is lost", 0x1c3,
- {" \"p2\" \"p3\" \"\" \"\" \"\"",
- {"", "p2", "p3", "", "", "", NULL}, 0},
- {" \"p2\" \"p3\" \"p3\" \"\" \"\"",
- {"", "p2", "p3", "p3", "", "", NULL}, 0}},
+ {"Params23456", "p2 \"p3\" \"p4 is lost", TRUE,
+ " \"p2\" \"p3\" \"\" \"\" \"\"",
+ " \"p2\" \"p3\" \"p3\" \"\" \"\""}, /* NT4/2k */
/* Backslashes have no special meaning even when preceding quotes. All
* they do is start an unquoted string.
*/
- {"Params23456", "\\\"p\\three \"pfour\\\" pfive", 0x73,
- {" \"\\\" \"p\\three\" \"pfour\\\" \"pfive\" \"\"",
- {"", "\" p\\three pfour\"", "pfive", "", NULL}, 0}},
+ {"Params23456", "\\\"p\\three \"pfour\\\" pfive", TRUE,
+ " \"\\\" \"p\\three\" \"pfour\\\" \"pfive\" \"\""},
/* Environment variables are left untouched. */
- {"Params23456", "%TMPDIR% %t %c", 0,
- {" \"%TMPDIR%\" \"%t\" \"%c\" \"\" \"\"",
- {"", "%TMPDIR%", "%t", "%c", "", "", NULL}, 0}},
+ {"Params23456", "%TMPDIR% %t %c", FALSE,
+ " \"%TMPDIR%\" \"%t\" \"%c\" \"\" \"\""},
/* %~2 is equivalent to %*. However %~3 and higher include the spaces
* before the parameter!
* (but not the previous parameter's closing quote fortunately)
*/
- {"Params2345Etc", "p2 p3 \"p4\" p5 p6 ", 0x3f3,
- {" ~2=\"p2 p3 \"p4\" p5 p6 \" ~3=\" p3 \"p4\" p5 p6 \" ~4=\" \"p4\" p5 p6 \" ~5= p5 p6 ",
- {"", "~2=p2 p3 p4 p5 p6 ", "~3= p3 p4 p5 p6 ", "~4= p4 p5 p6 ", "~5=", "p5", "p6", NULL}, 0}},
+ {"Params2345Etc", "p2 p3 \"p4\" p5 p6 ", TRUE,
+ " ~2=\"p2 p3 \"p4\" p5 p6 \" ~3=\" p3 \"p4\" p5 p6 \" ~4=\" \"p4\" p5 p6 \" ~5= p5 p6 "},
/* %~n works even if there is no nth parameter. */
- {"Params9Etc", "p2 p3 p4 p5 p6 p7 p8 ", 0x12,
- {" ~9=\" \"",
- {"", "~9= ", NULL}, 0}},
+ {"Params9Etc", "p2 p3 p4 p5 p6 p7 p8 ", TRUE,
+ " ~9=\" \""},
- {"Params9Etc", "p2 p3 p4 p5 p6 p7 ", 0x12,
- {" ~9=\"\"",
- {"", "~9=", NULL}, 0}},
+ {"Params9Etc", "p2 p3 p4 p5 p6 p7 ", TRUE,
+ " ~9=\"\""},
/* The %~n directives also transmit the tenth parameter and beyond. */
- {"Params9Etc", "p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 and beyond!", 0x12,
- {" ~9=\" p9 p10 p11 and beyond!\"",
- {"", "~9= p9 p10 p11 and beyond!", NULL}, 0}},
+ {"Params9Etc", "p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 and beyond!", TRUE,
+ " ~9=\" p9 p10 p11 and beyond!\""},
/* Bad formatting directives lose their % sign, except those followed by
* a tilde! Environment variables are not expanded but lose their % sign.
*/
- {"ParamsBad", "p2 p3 p4 p5", 0x12,
- {" \"% - %~ %~0 %~1 %~a %~* a b c TMPDIR\"",
- {"", "% - %~ %~0 %~1 %~a %~* a b c TMPDIR", NULL}, 0}},
+ {"ParamsBad", "p2 p3 p4 p5", TRUE,
+ " \"% - %~ %~0 %~1 %~a %~* a b c TMPDIR\""},
- {NULL, NULL, 0, {NULL, {NULL}, 0}}
+ {0}
};
static void test_argify(void)
{
- BOOL has_cl2a = TRUE;
char fileA[MAX_PATH], params[2*MAX_PATH+12];
INT_PTR rc;
const argify_tests_t* test;
- const cmdline_tests_t *bad;
+ const char *bad;
const char* cmd;
- unsigned i, count;
/* Test with a long parameter */
for (rc = 0; rc < MAX_PATH; rc++)
@@ -1614,21 +1586,11 @@ static void test_argify(void)
test = argify_tests;
while (test->params)
{
- bad = test->broken.cmd ? &test->broken : &test->cmd;
+ bad = test->broken ? test->broken : test->cmd;
- /* trace("***** verb='%s' params='%s'\n", test->verb, test->params); */
rc = shell_execute_ex(SEE_MASK_DOENVSUBST, test->verb, fileA, test->params, NULL, NULL);
okShell(rc > 32, "failed: rc=%lu\n", rc);
- count = 0;
- while (test->cmd.args[count])
- count++;
- /* +4 for the shlexec arguments, -1 because of the added ""
- * argument for the CommandLineToArgvW() tests.
- */
- todo_wine_if(test->todo & 0x1)
- okChildInt("argcA", 4 + count - 1);
-
cmd = getChildString("Child", "cmdlineA");
/* Our commands are such that the verb immediately precedes the
* part we are interested in.
@@ -1636,20 +1598,9 @@ static void test_argify(void)
if (cmd) cmd = strstr(cmd, test->verb);
if (cmd) cmd += strlen(test->verb);
if (!cmd) cmd = "(null)";
- todo_wine_if(test->todo & 0x2)
- okShell(!strcmp(cmd, test->cmd.cmd) || broken(!strcmp(cmd, bad->cmd)),
- "the cmdline is '%s' instead of '%s'\n", cmd, test->cmd.cmd);
-
- for (i = 0; i < count - 1; i++)
- {
- char argname[18];
- sprintf(argname, "argvA%d", 4 + i);
- todo_wine_if(test->todo & (1 << (i+4)))
- okChildStringBroken(argname, test->cmd.args[i+1], bad->args[i+1]);
- }
-
- if (has_cl2a)
- has_cl2a = test_one_cmdline(&(test->cmd));
+ todo_wine_if(test->todo)
+ okShell(!strcmp(cmd, test->cmd) || broken(!strcmp(cmd, bad)),
+ "expected '%s', got '%s'\n", cmd, test->cmd);
test++;
}
}
--
2.7.4
June 21, 2018
[PATCH] gdi32/tests: Test writing to the default palette.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
Mostly to rule out one proposed reason for the ddraw test failures on Windows.
dlls/gdi32/tests/palette.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/dlls/gdi32/tests/palette.c b/dlls/gdi32/tests/palette.c
index 045f530..0043f55 100644
--- a/dlls/gdi32/tests/palette.c
+++ b/dlls/gdi32/tests/palette.c
@@ -142,6 +142,15 @@ static void test_palette_entries(void)
ok(res == 1, "GetPaletteEntries should have returned 1 but returned %d\n", res);
ok( palEntry.peFlags == getEntryResult.peFlags, "palEntry.peFlags (%#x) != getEntryResult.peFlags (%#x)\n", palEntry.peFlags, getEntryResult.peFlags );
+
+ /* Try setting the system palette */
+ hpal = GetStockObject(DEFAULT_PALETTE);
+ res = SetPaletteEntries(hpal, 0, 1, &palEntry);
+ ok(!res, "SetPaletteEntries() should have failed\n");
+
+ res = GetPaletteEntries(hpal, 0, 1, &getEntryResult);
+ ok(res == 1, "GetPaletteEntries should have returned 1 but returned %d\n", res);
+ ok(memcmp(&palEntry, &getEntryResult, sizeof(PALETTEENTRY)), "entries should not match\n");
}
static void test_halftone_palette(void)
--
2.7.4
June 21, 2018
[PATCH] po: Update Finnish translation.
by Lauri Kenttä
Signed-off-by: Lauri Kenttä <lauri.kentta(a)gmail.com>
---
po/fi.po | 2 ++
1 file changed, 2 insertions(+)
diff --git a/po/fi.po b/po/fi.po
index 7e8bb62be9..abe62894f7 100644
--- a/po/fi.po
+++ b/po/fi.po
@@ -14743,6 +14743,8 @@ msgid ""
"A program on your system has crashed, but WineDbg was unable to attach to "
"the process to obtain a backtrace."
msgstr ""
+"Ohjelma koneellasi kaatui, mutta WineDbg ei pystynyt liittymään siihen eikä "
+"keräämään virheenjäljitystietoja (backtrace)."
#: winedbg.rc:41
msgid "(unidentified)"
--
2.17.1
June 21, 2018
[PATCH 4/4] testbot/web: Allow sumitting jobs to verify patches compile on Wine.
by Francois Gouget
For now the Wine VMs are unchecked by default since all they do is a
compilation check which is mostly redundant with the regular build step.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/Submit.pl | 43 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 42 insertions(+), 1 deletion(-)
diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl
index afebc722b..9fa252a11 100644
--- a/testbot/web/Submit.pl
+++ b/testbot/web/Submit.pl
@@ -244,10 +244,14 @@ sub GenerateFields($)
{
$VMs->AddFilter("Type", ["win64"]);
}
- else
+ elsif ($self->{FileType} eq "exe32")
{
$VMs->AddFilter("Type", ["win32", "win64"]);
}
+ else
+ {
+ $VMs->AddFilter("Type", ["win32", "win64", "wine"]);
+ }
if ($self->{ShowAll})
{
# All but the retired and deleted ones
@@ -272,6 +276,10 @@ sub GenerateFields($)
$Status = " [". $VM->Status ."]";
$Checked = undef;
}
+ elsif ($VM->Type eq "wine")
+ {
+ $Checked = undef;
+ }
if ($Checked and
($self->GetParam("Page") == 1 || $self->GetParam($FieldName)))
{
@@ -844,6 +852,39 @@ sub OnSubmit($)
}
}
+ if ($FileType eq "patchdlls")
+ {
+ my $Tasks;
+ my $VMs = CreateVMs();
+ $VMs->AddFilter("Type", ["wine"]);
+ my $SortedKeys = $VMs->SortKeysBySortOrder($VMs->GetKeys());
+ foreach my $VMKey (@$SortedKeys)
+ {
+ my $VM = $VMs->GetItem($VMKey);
+ my $FieldName = "vm_" . $self->CGI->escapeHTML($VMKey);
+ next if (!$self->GetParam($FieldName)); # skip unselected VMs
+
+ if (!$Tasks)
+ {
+ # First create the Wine test step
+ my $WineStep = $Steps->Add();
+ $WineStep->FileName($BaseName);
+ $WineStep->FileType($FileType);
+ $WineStep->InStaging(!1);
+ $WineStep->Type("build");
+ $WineStep->DebugLevel($self->GetParam("DebugLevel"));
+ $WineStep->ReportSuccessfulTests(defined($self->GetParam("ReportSuccessfulTests")));
+ $Tasks = $WineStep->Tasks;
+ }
+
+ # Then add a task for this VM
+ my $Task = $Tasks->Add();
+ $Task->VM($VM);
+ $Task->CmdLineArg("win32");
+ $Task->Timeout($WineReconfigTimeout);
+ }
+ }
+
# Now save it all (or whatever's left to save)
my ($ErrKey, $ErrProperty, $ErrMessage) = $Jobs->Save();
if (defined($ErrMessage))
--
2.17.1
June 21, 2018
[PATCH 3/4] testbot: Make sure the patches apply and compile in Wine.
by Francois Gouget
This adds the base infrastructure for later testing the patches on Wine.
This adds a "wine" VM type which applies to all VMs that can compile and
run Wine, regardless of the underlying operating system. Adapting to the
underlying operating system is thus the responsibility of the VM-side
scripts.
This also updates GetPatchImpacts() to detect non-Wine scripts (such as
TestBot patches) so the TestBot does not report them as bad patches
for failing to apply on top of Wine.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
Note: This requires updating the database with update37.sql, and
restarting the TestBot engine and web server.
testbot/bin/CheckForWinetestUpdate.pl | 47 ++-
testbot/bin/WineRunReconfig.pl | 36 +-
testbot/bin/WineRunWineTest.pl | 423 ++++++++++++++++++++
testbot/bin/build/WineReconfig.pl | 258 ++++++++++++
testbot/bin/build/WineTest.pl | 282 +++++++++++++
testbot/ddl/update37.sql | 4 +
testbot/ddl/winetestbot.sql | 2 +-
testbot/lib/WineTestBot/Config.pm | 9 +-
testbot/lib/WineTestBot/Engine/Scheduler.pm | 3 +-
testbot/lib/WineTestBot/PatchUtils.pm | 80 +++-
testbot/lib/WineTestBot/Patches.pm | 213 +++++-----
testbot/lib/WineTestBot/PendingPatchSets.pm | 14 +-
testbot/lib/WineTestBot/StepsTasks.pm | 2 +-
testbot/lib/WineTestBot/Tasks.pm | 5 +-
testbot/lib/WineTestBot/VMs.pm | 8 +-
15 files changed, 1234 insertions(+), 152 deletions(-)
create mode 100755 testbot/bin/WineRunWineTest.pl
create mode 100755 testbot/bin/build/WineReconfig.pl
create mode 100755 testbot/bin/build/WineTest.pl
create mode 100644 testbot/ddl/update37.sql
diff --git a/testbot/bin/CheckForWinetestUpdate.pl b/testbot/bin/CheckForWinetestUpdate.pl
index 80c57b9e1..74c59955f 100755
--- a/testbot/bin/CheckForWinetestUpdate.pl
+++ b/testbot/bin/CheckForWinetestUpdate.pl
@@ -63,7 +63,8 @@ my %WineTestUrls = (
64 => "http://test.winehq.org/builds/winetest64-latest.exe"
);
-my %TaskTypes = (build => 1, base32 => 1, winetest32 => 1, all64 => 1);
+my %TaskTypes = (build => 1, base32 => 1, winetest32 => 1, all64 => 1,
+ wine => 1);
my $Debug;
@@ -212,7 +213,7 @@ sub AddJob($$$)
my $Tasks = $NewStep->Tasks;
foreach my $VMKey (@{$VMs->SortKeysBySortOrder($VMs->GetKeys())})
{
- Debug(" $VMKey\n");
+ Debug(" $VMKey exe$Bits\n");
my $Task = $Tasks->Add();
$Task->VM($VMs->GetItem($VMKey));
$Task->Timeout($SuiteTimeout);
@@ -246,11 +247,23 @@ sub AddJob($$$)
return 1;
}
-sub AddReconfigJob()
+sub AddReconfigJob($)
{
- my $Remarks = "Update Wine to latest git";
+ my ($VMType) = @_;
+
+ my $Remarks = "Update the $VMType VMs";
Debug("Creating the '$Remarks' job\n");
+ my $VMs = CreateVMs();
+ $VMs->AddFilter("Type", [$VMType]);
+ $VMs->FilterEnabledRole();
+ if ($VMs->GetItemsCount() == 0)
+ {
+ # There is nothing to do
+ Debug(" Found no VM\n");
+ return 1;
+ }
+
# First create a new job
my $Jobs = CreateJobs();
my $NewJob = $Jobs->Add();
@@ -265,15 +278,16 @@ sub AddReconfigJob()
$NewStep->FileType("none");
$NewStep->InStaging(!1);
- # Add a task for the build VM
- my $VMs = CreateVMs();
- $VMs->AddFilter("Type", ["build"]);
- $VMs->AddFilter("Role", ["base"]);
- my $BuildVM = ${$VMs->GetItems()}[0];
- Debug(" ", $BuildVM->GetKey(), "\n");
- my $Task = $NewStep->Tasks->Add();
- $Task->VM($BuildVM);
- $Task->Timeout($ReconfigTimeout);
+ # And a task for each VM
+ my $SortedKeys = $VMs->SortKeysBySortOrder($VMs->GetKeys());
+ foreach my $VMKey (@$SortedKeys)
+ {
+ my $VM = $VMs->GetItem($VMKey);
+ Debug(" $VMKey $VMType reconfig\n");
+ my $Task = $NewStep->Tasks->Add();
+ $Task->VM($VM);
+ $Task->Timeout($ReconfigTimeout);
+ }
# Save it all
my ($ErrKey, $ErrProperty, $ErrMessage) = $Jobs->Save();
@@ -358,7 +372,8 @@ if (defined $Usage)
#
my $Rc = 0;
-if ($OptTypes{build} or $OptTypes{base32} or $OptTypes{winetest32})
+if ($OptTypes{build} or $OptTypes{base32} or $OptTypes{winetest32} or
+ $OptTypes{wine})
{
my ($Create, $LatestBaseName) = UpdateWineTest($OptCreate, 32);
if ($Create < 0)
@@ -370,9 +385,11 @@ if ($OptTypes{build} or $OptTypes{base32} or $OptTypes{winetest32})
# A new executable means there have been commits so update Wine. Create
# this job first purely to make the WineTestBot job queue look nice, and
# arbitrarily do it only for 32-bit executables to avoid redundant updates.
- $Rc = 1 if ($OptTypes{build} and !AddReconfigJob());
+ $Rc = 1 if ($OptTypes{build} and !AddReconfigJob("build"));
$Rc = 1 if ($OptTypes{base32} and !AddJob("base", $LatestBaseName, 32));
$Rc = 1 if ($OptTypes{winetest32} and !AddJob("", $LatestBaseName, 32));
+
+ $Rc = 1 if ($OptTypes{wine} and !AddReconfigJob("wine"));
}
}
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index 23b038a1f..e418e5bb9 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -5,7 +5,7 @@
# See the bin/build/Reconfig.pl script.
#
# Copyright 2009 Ge van Geldorp
-# Copyright 2013-2016 Francois Gouget
+# Copyright 2013-2018 Francois Gouget
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -312,9 +312,9 @@ sub FatalTAError($$)
# Check the VM and Step
#
-if ($VM->Type ne "build")
+if ($VM->Type ne "build" and $VM->Type ne "wine")
{
- FatalError("This is not a build VM! (" . $VM->Type . ")\n");
+ FatalError("This is neither a build nor a Wine VM! (" . $VM->Type . ")\n");
}
elsif (!$Debug and $VM->Status ne "running")
{
@@ -337,11 +337,12 @@ if ($Step->FileType ne "none")
# Use our own log so it can be used for reference
# even after another task has run.
-my $Script = "#!/bin/sh\n".
- "( set -x\n".
- " git pull &&\n".
- " ../bin/build/Reconfig.pl\n".
- ") >Reconfig.log 2>&1\n";
+my $Script = $VM->Type eq "wine" ? "WineReconfig.pl" : "Reconfig.pl";
+$Script = "#!/bin/sh\n".
+ "( set -x\n".
+ " git pull &&\n".
+ " ../bin/build/$Script\n".
+ ") >Reconfig.log 2>&1\n";
my $TA = $VM->GetAgent();
Debug(Elapsed($Start), " Sending the script: [$Script]\n");
if (!$TA->SendFileFromString($Script, "task", $TestAgent::SENDFILE_EXE))
@@ -410,16 +411,19 @@ elsif (!defined $TAError)
if ($NewStatus eq "completed")
{
use File::Copy;
- for my $Bitness ("32", "64")
+ if ($VM->Type eq "build")
{
- Debug(Elapsed($Start), " Retrieving the $Bitness bit TestLauncher to '$TaskDir/TestLauncher$Bitness.exe'\n");
- if ($TA->GetFile("../src/TestLauncher/TestLauncher$Bitness.exe", "$TaskDir/TestLauncher$Bitness.exe"))
+ for my $Bitness ("32", "64")
{
- copy "$TaskDir/TestLauncher$Bitness.exe", "$DataDir/latest/TestLauncher$Bitness.exe";
- }
- elsif (!defined $TAError)
- {
- $TAError = "An error occurred while retrieving the $Bitness bit TestLauncher: ". $TA->GetLastError();
+ Debug(Elapsed($Start), " Retrieving the $Bitness bit TestLauncher to '$TaskDir/TestLauncher$Bitness.exe'\n");
+ if ($TA->GetFile("../src/TestLauncher/TestLauncher$Bitness.exe", "$TaskDir/TestLauncher$Bitness.exe"))
+ {
+ copy "$TaskDir/TestLauncher$Bitness.exe", "$DataDir/latest/TestLauncher$Bitness.exe";
+ }
+ elsif (!defined $TAError)
+ {
+ $TAError = "An error occurred while retrieving the $Bitness bit TestLauncher: ". $TA->GetLastError();
+ }
}
}
diff --git a/testbot/bin/WineRunWineTest.pl b/testbot/bin/WineRunWineTest.pl
new file mode 100755
index 000000000..0aba7ecfc
--- /dev/null
+++ b/testbot/bin/WineRunWineTest.pl
@@ -0,0 +1,423 @@
+#!/usr/bin/perl -Tw
+# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+#
+# Makes sure the Wine patches compile.
+# See the bin/build/WineTest.pl script.
+#
+# Copyright 2018 Francois Gouget
+#
+# 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
+
+use strict;
+
+sub BEGIN
+{
+ if ($0 !~ m=^/=)
+ {
+ # Turn $0 into an absolute path so it can safely be used in @INC
+ require Cwd;
+ $0 = Cwd::cwd() . "/$0";
+ }
+ if ($0 =~ m=^(/.*)/[^/]+/[^/]+$=)
+ {
+ $::RootDir = $1;
+ unshift @INC, "$::RootDir/lib";
+ }
+}
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
+
+use WineTestBot::Config;
+use WineTestBot::Jobs;
+use WineTestBot::PatchUtils;
+use WineTestBot::VMs;
+use WineTestBot::Log;
+use WineTestBot::LogUtils;
+use WineTestBot::Engine::Notify;
+
+
+#
+# Logging and error handling helpers
+#
+
+my $Debug;
+sub Debug(@)
+{
+ print STDERR @_ if ($Debug);
+}
+
+my $LogOnly;
+sub Error(@)
+{
+ print STDERR "$Name0:error: ", @_ if (!$LogOnly);
+ LogMsg @_;
+}
+
+
+#
+# Setup and command line processing
+#
+
+$ENV{PATH} = "/usr/bin:/bin";
+delete $ENV{ENV};
+
+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, $StepNo, $TaskNo);
+while (@ARGV)
+{
+ 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);
+ }
+ elsif (!defined $StepNo)
+ {
+ $StepNo = ValidateNumber('step number', $Arg);
+ }
+ elsif (!defined $TaskNo)
+ {
+ $TaskNo = ValidateNumber('task number', $Arg);
+ }
+ else
+ {
+ Error "unexpected argument '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+}
+
+# Check parameters
+if (!defined $Usage)
+{
+ if (!defined $JobId || !defined $StepNo || !defined $TaskNo)
+ {
+ Error "you must specify the job id, step number and task number\n";
+ $Usage = 2;
+ }
+}
+if (defined $Usage)
+{
+ print "Usage: $Name0 [--debug] [--log-only] [--help] JobId StepNo TaskNo\n";
+ exit $Usage;
+}
+
+my $Job = CreateJobs()->GetItem($JobId);
+if (!defined $Job)
+{
+ Error "Job $JobId does not exist\n";
+ exit 1;
+}
+my $Step = $Job->Steps->GetItem($StepNo);
+if (!defined $Step)
+{
+ Error "Step $StepNo of job $JobId does not exist\n";
+ exit 1;
+}
+my $Task = $Step->Tasks->GetItem($TaskNo);
+if (!defined $Task)
+{
+ Error "Step $StepNo task $TaskNo of job $JobId does not exist\n";
+ exit 1;
+}
+my $TaskDir = $Task->CreateDir();
+my $VM = $Task->VM;
+
+
+my $Start = Time();
+LogMsg "Task $JobId/$StepNo/$TaskNo started\n";
+
+
+#
+# Error handling helpers
+#
+
+sub LogTaskError($)
+{
+ my ($ErrMessage) = @_;
+ Debug("$Name0:error: ", $ErrMessage);
+
+ if (open(my $ErrFile, ">>", "$TaskDir/err"))
+ {
+ print $ErrFile $ErrMessage;
+ close($ErrFile);
+ }
+ else
+ {
+ Error "Unable to open 'err' for writing: $!\n";
+ }
+}
+
+sub WrapUpAndExit($;$$)
+{
+ my ($Status, $Retry, $Timeout) = @_;
+ my $NewVMStatus = $Status eq 'queued' ? 'offline' : 'dirty';
+ my $VMResult = $Status eq "boterror" ? "boterror" :
+ $Status eq "queued" ? "error" :
+ $Timeout ? "timeout" : "";
+
+ my $TestFailures;
+ my $Tries = $Task->TestFailures || 0;
+ if ($Retry)
+ {
+ # This may be a transient error (e.g. a network glitch)
+ # so retry a few times to improve robustness
+ $Tries++;
+ if ($Task->CanRetry())
+ {
+ $Status = 'queued';
+ $TestFailures = $Tries;
+ }
+ else
+ {
+ LogTaskError("Giving up after $Tries run(s)\n");
+ }
+ }
+ elsif ($Tries >= 1)
+ {
+ LogTaskError("The previous $Tries run(s) terminated abnormally\n");
+ }
+
+ # Record result details that may be lost or overwritten by a later run
+ if ($VMResult)
+ {
+ $VMResult .= " $Tries $MaxTaskTries" if ($Retry);
+ $VM->RecordResult(undef, $VMResult);
+ }
+
+ # Update the Task and Job
+ $Task->Status($Status);
+ $Task->TestFailures($TestFailures);
+ if ($Status eq 'queued')
+ {
+ $Task->Started(undef);
+ $Task->Ended(undef);
+ # Leave the Task files around so they can be seen until the next run
+ }
+ else
+ {
+ $Task->Ended(time());
+ }
+ $Task->Save();
+ $Job->UpdateStatus();
+
+ # Get the up-to-date VM status and update it if nobody else changed it
+ $VM = CreateVMs()->GetItem($VM->GetKey());
+ if ($VM->Status eq 'running')
+ {
+ $VM->Status($NewVMStatus);
+ $VM->ChildDeadline(undef);
+ $VM->ChildPid(undef);
+ $VM->Save();
+ }
+
+ my $Result = $VM->Name .": ". $VM->Status ." Status: $Status Failures: ". (defined $TestFailures ? $TestFailures : "unset");
+ LogMsg "Task $JobId/$StepNo/$TaskNo done ($Result)\n";
+ Debug(Elapsed($Start), " Done. $Result\n");
+ exit($Status eq 'completed' ? 0 : 1);
+}
+
+sub FatalError($;$)
+{
+ my ($ErrMessage, $Retry) = @_;
+
+ LogMsg "$JobId/$StepNo/$TaskNo $ErrMessage";
+ LogTaskError($ErrMessage);
+
+ WrapUpAndExit('boterror', $Retry);
+}
+
+sub FatalTAError($$)
+{
+ my ($TA, $ErrMessage) = @_;
+ $ErrMessage .= ": ". $TA->GetLastError() if (defined $TA);
+
+ # A TestAgent operation failed, see if the VM is still accessible
+ my $IsPoweredOn = $VM->GetDomain()->IsPoweredOn();
+ if (!defined $IsPoweredOn)
+ {
+ # The VM host is not accessible anymore so mark the VM as offline and
+ # requeue the task. This does not count towards the task's tries limit
+ # since neither the VM nor the task are at fault.
+ Error("$ErrMessage\n");
+ WrapUpAndExit('queued');
+ }
+
+ my $Retry;
+ if ($IsPoweredOn)
+ {
+ LogMsg("$ErrMessage\n");
+ LogTaskError("$ErrMessage\n");
+ $ErrMessage = "The test VM has crashed, rebooted or lost connectivity (or the TestAgent server died)\n";
+ # Retry in case it was a temporary network glitch
+ $Retry = 1;
+ }
+ else
+ {
+ # Ignore the TestAgent error, it's irrelevant
+ $ErrMessage = "The test VM is powered off!\n";
+ }
+ FatalError($ErrMessage, $Retry);
+}
+
+
+#
+# Check the VM and Step
+#
+
+if ($VM->Type ne "wine")
+{
+ FatalError("This is not a Wine VM! (" . $VM->Type . ")\n");
+}
+elsif (!$Debug and $VM->Status ne "running")
+{
+ FatalError("The VM is not ready for use (" . $VM->Status . ")\n");
+}
+elsif (!$VM->GetDomain()->IsPoweredOn())
+{
+ FatalError("The VM is not powered on\n");
+}
+
+if ($Step->FileType ne "patchdlls")
+{
+ FatalError("Unexpected file type '". $Step->FileType ."' found\n");
+}
+
+
+#
+# Run the task
+#
+
+my $FileName = $Step->GetFullFileName();
+my $TA = $VM->GetAgent();
+Debug(Elapsed($Start), " Sending '$FileName'\n");
+if (!$TA->SendFile($FileName, "staging/patch.diff", 0))
+{
+ FatalTAError($TA, "Could not copy the patch to the VM");
+}
+my $Script = "#!/bin/sh\n".
+ "( set -x\n" .
+ " ../bin/build/WineTest.pl ". $Task->CmdLineArg ." build patch.diff\n".
+ ") >Task.log 2>&1\n";
+Debug(Elapsed($Start), " Sending the script: [$Script]\n");
+if (!$TA->SendFileFromString($Script, "task", $TestAgent::SENDFILE_EXE))
+{
+ FatalTAError($TA, "Could not send the task script to the VM");
+}
+
+Debug(Elapsed($Start), " Starting the script\n");
+my $Pid = $TA->Run(["./task"], 0);
+if (!$Pid)
+{
+ FatalTAError($TA, "Failed to start the task");
+}
+
+
+#
+# From that point on we want to at least try to grab the task
+# log before giving up
+#
+
+my ($NewStatus, $ErrMessage, $TAError, $TaskTimedOut);
+Debug(Elapsed($Start), " Waiting for the script (", $Task->Timeout, "s timeout)\n");
+if (!defined $TA->Wait($Pid, $Task->Timeout, 60))
+{
+ $ErrMessage = $TA->GetLastError();
+ if ($ErrMessage =~ /timed out waiting for the child process/)
+ {
+ $ErrMessage = "The task timed out\n";
+ $NewStatus = "badbuild";
+ $TaskTimedOut = 1;
+ }
+ else
+ {
+ $TAError = "An error occurred while waiting for the task to complete: $ErrMessage";
+ $ErrMessage = undef;
+ }
+}
+
+Debug(Elapsed($Start), " Retrieving 'Task.log'\n");
+if ($TA->GetFile("Task.log", "$TaskDir/log"))
+{
+ my $Result = ParseTaskLog("$TaskDir/log", "Task");
+ if ($Result eq "ok")
+ {
+ # We must have gotten the full log and the build did succeed.
+ # So forget any prior error.
+ $NewStatus = "completed";
+ $TAError = $ErrMessage = undef;
+ }
+ elsif ($Result eq "badpatch")
+ {
+ $NewStatus = "badpatch";
+ }
+ elsif ($Result =~ s/^nolog://)
+ {
+ FatalError("$Result\n", "retry");
+ }
+ else
+ {
+ # If the result line is missing we probably already have an error message
+ # that explains why.
+ $NewStatus = "badbuild";
+ }
+}
+elsif (!defined $TAError)
+{
+ $TAError = "An error occurred while retrieving the task log: ". $TA->GetLastError();
+}
+
+# Report the task errors even though they may have been caused by
+# TestAgent trouble.
+LogTaskError($ErrMessage) if (defined $ErrMessage);
+FatalTAError(undef, $TAError) if (defined $TAError);
+$TA->Disconnect();
+
+
+#
+# Wrap up
+#
+
+WrapUpAndExit($NewStatus, undef, $TaskTimedOut);
diff --git a/testbot/bin/build/WineReconfig.pl b/testbot/bin/build/WineReconfig.pl
new file mode 100755
index 000000000..b030051c6
--- /dev/null
+++ b/testbot/bin/build/WineReconfig.pl
@@ -0,0 +1,258 @@
+#!/usr/bin/perl -Tw
+# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+#
+# Updates the Wine source from Git and rebuilds it.
+#
+# Copyright 2018 Francois Gouget
+#
+# 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
+
+use strict;
+
+sub BEGIN
+{
+ if ($0 !~ m=^/=)
+ {
+ # Turn $0 into an absolute path so it can safely be used in @INC
+ require Cwd;
+ $0 = Cwd::cwd() . "/$0";
+ }
+ if ($0 =~ m=^(/.*)/[^/]+/[^/]+/[^/]+$=)
+ {
+ $::RootDir = $1;
+ unshift @INC, "$::RootDir/lib";
+ }
+ $::BuildEnv = 1;
+}
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
+
+use WineTestBot::Config;
+use WineTestBot::PatchUtils;
+
+
+#
+# Logging and error handling helpers
+#
+
+sub InfoMsg(@)
+{
+ print @_;
+}
+
+sub LogMsg(@)
+{
+ print "Reconfig: ", @_;
+}
+
+sub Error(@)
+{
+ print STDERR "$Name0:error: ", @_;
+}
+
+
+#
+# Build helpers
+#
+
+my $ncpus;
+sub CountCPUs()
+{
+ if (open(my $fh, "<", "/proc/cpuinfo"))
+ {
+ # Linux
+ map { $ncpus++ if (/^processor/); } <$fh>;
+ close($fh);
+ }
+ $ncpus ||= 1;
+}
+
+sub BuildTestAgentd()
+{
+ # If testagentd already exists it's likely already running
+ # so don't rebuild it.
+ if (! -x "$BinDir/build/testagentd")
+ {
+ InfoMsg "\nBuilding the native testagentd\n";
+ system("cd '$::RootDir/src/testagentd' && set -x && ".
+ "time make -j$ncpus build");
+ if ($? != 0)
+ {
+ LogMsg "Build testagentd failed\n";
+ return !1;
+ }
+ }
+
+ return 1;
+}
+
+sub GitPull($)
+{
+ my ($Targets) = @_;
+ return 1 if (!$Targets->{update});
+
+ InfoMsg "\nUpdating the Wine source\n";
+ system("cd '$DataDir/wine' && git pull");
+ if ($? != 0)
+ {
+ LogMsg "Git pull failed\n";
+ return !1;
+ }
+
+ my $ErrMessage = UpdateWineData("$DataDir/wine");
+ if ($ErrMessage)
+ {
+ LogMsg "$ErrMessage\n";
+ return !1;
+ }
+
+ return 1;
+}
+
+sub BuildWine($$$$)
+{
+ my ($Targets, $NoRm, $Build, $Extras) = @_;
+
+ return 1 if (!$Targets->{$Build});
+ mkdir "$DataDir/build-$Build" if (!-d "$DataDir/build-$Build");
+
+ # If $NoRm is not set, rebuild from scratch to make sure cruft will not
+ # accumulate
+ InfoMsg "\nRebuilding the $Build Wine\n";
+ system("cd '$DataDir/build-$Build' && set -x && ".
+ ($NoRm ? "" : "rm -rf * && ") .
+ "time ../wine/configure $Extras --disable-winetest && ".
+ "time make -j$ncpus");
+ if ($? != 0)
+ {
+ LogMsg "The $Build build failed\n";
+ return !1;
+ }
+
+ return 1;
+}
+
+
+#
+# Setup and command line processing
+#
+
+$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
+delete $ENV{ENV};
+
+my %AllTargets;
+map { $AllTargets{$_} = 1 } qw(update win32 wow32 wow64);
+
+my ($Usage, $TargetList, $NoRm);
+while (@ARGV)
+{
+ my $Arg = shift @ARGV;
+ if ($Arg eq "--no-rm")
+ {
+ $NoRm = 1;
+ }
+ elsif ($Arg =~ /^(?:-\?|-h|--help)$/)
+ {
+ $Usage = 0;
+ last;
+ }
+ elsif ($Arg =~ /^-/)
+ {
+ Error "unknown option '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+ elsif (!defined $TargetList)
+ {
+ $TargetList = $Arg;
+ }
+ else
+ {
+ Error "unexpected argument '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+}
+
+# Check and untaint parameters
+my $Targets;
+if (!defined $Usage)
+{
+ $TargetList = join(",", keys %AllTargets) if (!defined $TargetList);
+ foreach my $Target (split /,/, $TargetList)
+ {
+ if (!$AllTargets{$Target})
+ {
+ Error "invalid target name $Target\n";
+ $Usage = 2;
+ last;
+ }
+ $Targets->{$Target} = 1;
+ }
+}
+if (defined $Usage)
+{
+ if ($Usage)
+ {
+ Error "try '$Name0 --help' for more information\n";
+ exit $Usage;
+ }
+ print "Usage: $Name0 [--no-rm] [--help] [TARGETS]\n";
+ print "\n";
+ print "Performs all the tasks needed for the host to be ready to test new patches: update the Wine source and rebuild the Wine binaries.\n";
+ print "\n";
+ print "Where:\n";
+ print " TARGETS Is a comma-separated list of targets to process. By default all\n";
+ print " targets are processed.\n";
+ print " - update: Update Wine's source code.\n";
+ print " - win32: Rebuild the regular 32 bit Wine.\n";
+ print " - wow32: Rebuild the 32 bit WoW Wine.\n";
+ print " - wow64: Rebuild the 64 bit WoW Wine.\n";
+ print " --no-rm Don't rebuild from scratch.\n";
+ print " --help Shows this usage message.\n";
+ exit 0;
+}
+
+if (! -d "$DataDir/staging" and ! mkdir "$DataDir/staging")
+{
+ LogMsg "Unable to create '$DataDir/staging': $!\n";
+ exit(1);
+}
+
+if ($DataDir =~ /'/)
+{
+ LogMsg "The install path contains invalid characters\n";
+ exit(1);
+}
+
+
+#
+# Run the builds
+#
+
+CountCPUs();
+
+if (!BuildTestAgentd() ||
+ !GitPull($Targets) ||
+ !BuildWine($Targets, $NoRm, "win32", "") ||
+ !BuildWine($Targets, $NoRm, "wow64", "--enable-win64") ||
+ !BuildWine($Targets, $NoRm, "wow32", "--with-wine64='$DataDir/build-wow64'"))
+{
+ exit(1);
+}
+
+LogMsg "ok\n";
+exit;
diff --git a/testbot/bin/build/WineTest.pl b/testbot/bin/build/WineTest.pl
new file mode 100755
index 000000000..01396f9bf
--- /dev/null
+++ b/testbot/bin/build/WineTest.pl
@@ -0,0 +1,282 @@
+#!/usr/bin/perl
+# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+#
+# Applies the patch and rebuilds Wine.
+#
+# This script does not use tainting (-T) because its whole purpose is to run
+# arbitrary user-provided code anyway.
+#
+# Copyright 2018 Francois Gouget
+#
+# 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
+
+use warnings;
+use strict;
+
+sub BEGIN
+{
+ if ($0 !~ m=^/=)
+ {
+ # Turn $0 into an absolute path so it can safely be used in @INC
+ require Cwd;
+ $0 = Cwd::cwd() . "/$0";
+ }
+ if ($0 =~ m=^(/.*)/[^/]+/[^/]+/[^/]+$=)
+ {
+ $::RootDir = $1;
+ unshift @INC, "$::RootDir/lib";
+ }
+ $::BuildEnv = 1;
+}
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
+
+use WineTestBot::Config;
+use WineTestBot::PatchUtils;
+use WineTestBot::Utils;
+
+
+#
+# Logging and error handling helpers
+#
+
+sub InfoMsg(@)
+{
+ print @_;
+}
+
+sub LogMsg(@)
+{
+ print "Task: ", @_;
+}
+
+sub Error(@)
+{
+ print STDERR "$Name0:error: ", @_;
+}
+
+
+#
+# Build helpers
+#
+
+my $ncpus;
+sub CountCPUs()
+{
+ if (open(my $fh, "<", "/proc/cpuinfo"))
+ {
+ # Linux
+ map { $ncpus++ if (/^processor/); } <$fh>;
+ close($fh);
+ }
+ $ncpus ||= 1;
+}
+
+sub ApplyPatch($)
+{
+ my ($PatchFile) = @_;
+
+ InfoMsg "Applying patch\n";
+ system("cd '$DataDir/wine' && set -x && ".
+ "git apply --verbose ". ShQuote($PatchFile) ." && ".
+ "git add -A");
+ if ($? != 0)
+ {
+ LogMsg "Patch failed to apply\n";
+ return undef;
+ }
+
+ my $Impacts = GetPatchImpact($PatchFile, "nounits");
+ if ($Impacts->{Makefiles})
+ {
+ InfoMsg "\nRunning make_makefiles\n";
+ system("cd '$DataDir/wine' && set -x && ./tools/make_makefiles");
+ if ($? != 0)
+ {
+ LogMsg "make_makefiles failed\n";
+ return undef;
+ }
+ }
+
+ if ($Impacts->{Autoconf} && !$Impacts->{HasConfigure})
+ {
+ InfoMsg "\nRunning autoconf\n";
+ system("cd '$DataDir/wine' && set -x && autoconf");
+ if ($? != 0)
+ {
+ LogMsg "Autoconf failed\n";
+ return undef;
+ }
+ }
+
+ return $Impacts;
+}
+
+sub BuildWine($$)
+{
+ my ($Targets, $Build) = @_;
+
+ return 1 if (!$Targets->{$Build});
+
+ InfoMsg "\nRebuilding the $Build Wine\n";
+ system("cd '$DataDir/build-$Build' && set -x && ".
+ "time make -j$ncpus");
+ if ($? != 0)
+ {
+ LogMsg "The $Build build failed\n";
+ return !1;
+ }
+
+ return 1;
+}
+
+
+#
+# Setup and command line processing
+#
+
+$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
+delete $ENV{ENV};
+
+my %AllTargets;
+map { $AllTargets{$_} = 1 } qw(win32 wow32 wow64);
+
+my ($Usage, $TargetList, $Action, $FileName);
+while (@ARGV)
+{
+ my $Arg = shift @ARGV;
+ if ($Arg =~ /^(?:-\?|-h|--help)$/)
+ {
+ $Usage = 0;
+ last;
+ }
+ elsif ($Arg =~ /^-/)
+ {
+ Error "unknown option '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+ elsif (!defined $TargetList)
+ {
+ $TargetList = $Arg;
+ }
+ elsif (!defined $Action)
+ {
+ $Action = $Arg;
+ }
+ elsif (!defined $FileName)
+ {
+ if (IsValidFileName($Arg))
+ {
+ $FileName = "$DataDir/staging/$Arg";
+ if (!-r $FileName)
+ {
+ Error "'$Arg' is not readable\n";
+ $Usage = 2;
+ }
+ }
+ else
+ {
+ Error "invalid file name '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+ }
+ else
+ {
+ Error "unexpected argument '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+}
+
+# Check and untaint parameters
+my $Targets;
+if (!defined $Usage)
+{
+ if (defined $TargetList)
+ {
+ foreach my $Target (split /,/, $TargetList)
+ {
+ if (!$AllTargets{$Target})
+ {
+ Error "invalid target name $Target\n";
+ $Usage = 2;
+ }
+ $Targets->{$Target} = 1;
+ }
+ }
+ else
+ {
+ Error "specify at least one target\n";
+ $Usage = 2;
+ }
+
+ if (!defined $Action)
+ {
+ Error "you must specify the action to perform\n";
+ $Usage = 2;
+ }
+ elsif ($Action ne "build")
+ {
+ Error "invalid '$Action' action\n";
+ $Usage = 2;
+ }
+
+ if (!defined $FileName and $Action eq "build")
+ {
+ Error "you must provide a patch file\n";
+ $Usage = 2;
+ }
+}
+if (defined $Usage)
+{
+ print "Usage: $Name0 [--help] TARGETS build PATCH\n";
+ print "\n";
+ print "Applies the specified patch and rebuilds Wine.\n";
+ print "\n";
+ print "Where:\n";
+ print " TARGETS Is a comma-separated list of targets for the build.\n";
+ print " - win32: The regular 32 bit Wine build.\n";
+ print " - wow32: The 32 bit WoW Wine build.\n";
+ print " - wow64: The 64 bit WoW Wine build.\n";
+ print " build Verify that the patch compiles.\n";
+ print " PATCH Is the staging file containing the patch to test.\n";
+ print " --help Shows this usage message.\n";
+ exit $Usage;
+}
+
+if ($DataDir =~ /'/)
+{
+ LogMsg "The install path contains invalid characters\n";
+ exit(1);
+}
+
+
+#
+# Run the builds
+#
+
+CountCPUs();
+
+my $Impacts = ApplyPatch($FileName);
+exit(1) if (!$Impacts or
+ !BuildWine($Targets, "win32") or
+ !BuildWine($Targets, "wow64") or
+ !BuildWine($Targets, "wow32"));
+
+LogMsg "ok\n";
+exit;
diff --git a/testbot/ddl/update37.sql b/testbot/ddl/update37.sql
new file mode 100644
index 000000000..cfa50ce2e
--- /dev/null
+++ b/testbot/ddl/update37.sql
@@ -0,0 +1,4 @@
+USE winetestbot;
+
+ALTER TABLE VMs
+ MODIFY Type ENUM('win32', 'win64', 'build', 'wine') NOT NULL;
diff --git a/testbot/ddl/winetestbot.sql b/testbot/ddl/winetestbot.sql
index 1e7b1edd1..12b5dea1a 100644
--- a/testbot/ddl/winetestbot.sql
+++ b/testbot/ddl/winetestbot.sql
@@ -46,7 +46,7 @@ CREATE TABLE VMs
(
Name VARCHAR(20) NOT NULL,
SortOrder INT(3) NOT NULL,
- Type ENUM('win32', 'win64', 'build') NOT NULL,
+ Type ENUM('win32', 'win64', 'build', 'wine') NOT NULL,
Role ENUM('extra', 'base', 'winetest', 'retired', 'deleted') NOT NULL,
Status ENUM('dirty', 'reverting', 'sleeping', 'idle', 'running', 'off', 'offline', 'maintenance') NOT NULL,
Errors INT(2) NULL,
diff --git a/testbot/lib/WineTestBot/Config.pm b/testbot/lib/WineTestBot/Config.pm
index 66cb813ff..1ffff262f 100644
--- a/testbot/lib/WineTestBot/Config.pm
+++ b/testbot/lib/WineTestBot/Config.pm
@@ -31,7 +31,8 @@ use vars qw (@ISA @EXPORT @EXPORT_OK $UseSSL $LogDir $DataDir $BinDir
$MaxVMsWhenIdle $SleepAfterRevert $WaitForToolsInVM
$VMToolTimeout $MaxVMErrors $MaxTaskTries $AdminEMail $RobotEMail
$WinePatchToOverride $WinePatchCc $SuiteTimeout $SingleTimeout
- $BuildTimeout $ReconfigTimeout $TimeoutMargin $TagPrefix
+ $BuildTimeout $ReconfigTimeout $WineReconfigTimeout $TimeoutMargin
+ $TagPrefix
$MaxUnitSize $ProjectName $PatchesMailingList $LDAPServer
$LDAPBindDN $LDAPSearchBase $LDAPSearchFilter
$LDAPRealNameAttribute $LDAPEMailAttribute $AgentPort $Tunnel
@@ -45,7 +46,8 @@ require Exporter;
$MaxRunningVMs $MaxVMsWhenIdle $SleepAfterRevert $WaitForToolsInVM
$VMToolTimeout $MaxVMErrors $MaxTaskTries $AdminEMail
$RobotEMail $WinePatchToOverride $WinePatchCc $SuiteTimeout
- $SingleTimeout $BuildTimeout $ReconfigTimeout $TimeoutMargin
+ $SingleTimeout $BuildTimeout $ReconfigTimeout $WineReconfigTimeout
+ $TimeoutMargin
$TagPrefix $MaxUnitSize $ProjectName $PatchesMailingList
$LDAPServer $LDAPBindDN $LDAPSearchBase $LDAPSearchFilter
$LDAPRealNameAttribute $LDAPEMailAttribute $AgentPort $Tunnel
@@ -101,6 +103,9 @@ $BuildTimeout = 5 * 60;
# (in seconds). Note that this includes building the native Wine build tools,
# and the 32 and 64 bit test executables.
$ReconfigTimeout = (1 + 2 * 5) * 60;
+# How long to let a full Wine recompilation run before forcibly shutting it
+# down (in seconds).
+$WineReconfigTimeout = 20 * 60;
# How much to add to the task timeout to account for file transfers, etc.
$TimeoutMargin = 2 * 60;
# Maximum amount of traces for a test unit.
diff --git a/testbot/lib/WineTestBot/Engine/Scheduler.pm b/testbot/lib/WineTestBot/Engine/Scheduler.pm
index 159b10cf8..3ed86e28d 100644
--- a/testbot/lib/WineTestBot/Engine/Scheduler.pm
+++ b/testbot/lib/WineTestBot/Engine/Scheduler.pm
@@ -392,7 +392,8 @@ sub _CheckAndClassifyVMs()
20) + # extra
($VM->Type eq "build" ? 0 :
$VM->Type eq "win64" ? 1 :
- 2); # win32
+ $VM->Type eq "win32" ? 2 :
+ 3); # wine
}
# If a VM was in an inconsistent state, update the jobs status fields before
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index 3bf172125..1aeed6740 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -36,6 +36,22 @@ our @EXPORT = qw(GetPatchImpact UpdateWineData);
use WineTestBot::Config;
+# These paths are too generic to be proof that this is a Wine patch.
+my $AmbiguousPathsRe = join('|',
+ 'Makefile\.in$',
+ # aclocal.m4 gets special treatment
+ # configure gets special treatment
+ # configure.ac gets special treatment
+ 'include/Makefile\.in$',
+ 'include/config\.h\.in$',
+ 'po/',
+ 'tools/Makefile.in',
+ 'tools/config.guess',
+ 'tools/config.sub',
+ 'tools/install-sh',
+ 'tools/makedep.c',
+);
+
# Patches to these paths don't impact the Wine build. So ignore them.
my $IgnoredPathsRe = join('|',
'\.mailmap$',
@@ -53,6 +69,7 @@ my $IgnoredPathsRe = join('|',
'tools/winemaker/',
);
+
=pod
=over 12
@@ -75,6 +92,7 @@ sub UpdateWineData($)
}
my $_TimeStamp;
+my $_WineFiles;
my $_TestList;
=pod
@@ -83,7 +101,7 @@ my $_TestList;
=item C<_LoadWineFiles()>
Reads latest/winefiles.txt to build a per-module hashtable of the test unit
-files.
+files and a hashtable of all the Wine files.
=back
=cut
@@ -101,11 +119,13 @@ sub _LoadWineFiles()
$_TimeStamp = $MTime;
$_TestList = {};
+ $_WineFiles = {};
if (open(my $fh, "<", $FileName))
{
while (my $Line = <$fh>)
{
chomp $Line;
+ $_WineFiles->{$Line} = 1;
if ($Line =~ m~^\w+/([^/]+)/tests/([^/]+)$~)
{
@@ -121,11 +141,23 @@ sub _LoadWineFiles()
sub _HandleFile($$$)
{
- my ($Impacts, $Path, $Change) = @_;
+ my ($Impacts, $FilePath, $Change) = @_;
- if ($Path =~ m~^(dlls|programs)/([^/]+)/tests/([^/\s]+)$~)
+ if ($Change eq "new")
+ {
+ delete $Impacts->{DeletedFiles}->{$FilePath};
+ $Impacts->{NewFiles}->{$FilePath} = 1;
+ }
+ elsif ($Change eq "rm")
+ {
+ delete $Impacts->{NewFiles}->{$FilePath};
+ $Impacts->{DeletedFiles}->{$FilePath} = 1;
+ }
+
+ if ($FilePath =~ m~^(dlls|programs)/([^/]+)/tests/([^/\s]+)$~)
{
my ($Root, $Module, $File) = ($1, $2, $3);
+ $Impacts->{IsWinePatch} = 1;
$Impacts->{TestBuild} = 1;
my $Tests = $Impacts->{Tests};
@@ -163,8 +195,29 @@ sub _HandleFile($$$)
}
else
{
- # Figure out if this patch impacts the Wine build
- $Impacts->{WineBuild} = 1 if ($Path !~ /^(?:$IgnoredPathsRe)/);
+ my $WineFiles = $Impacts->{WineFiles} || $_WineFiles;
+ if ($WineFiles->{$FilePath})
+ {
+ if ($FilePath !~ /^(?:$AmbiguousPathsRe)/)
+ {
+ $Impacts->{IsWinePatch} = 1;
+ }
+ # Else this file exists in Wine but has a very common name so it may just
+ # as well belong to another repository. Still update WineBuild in case
+ # this patch really is for Wine.
+
+ if ($FilePath !~ /^(?:$IgnoredPathsRe)/)
+ {
+ $Impacts->{WineBuild} = 1;
+ }
+ # Else patches to this file don't impact the Wine build.
+ }
+ elsif ($FilePath =~ m~/Makefile.in$~ and $Change eq "new")
+ {
+ # 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;
+ }
}
}
@@ -195,6 +248,21 @@ sub GetPatchImpact($;$$)
if ($PastImpacts)
{
+ if ($PastImpacts->{WineBuild} or $PastImpacts->{TestBuild})
+ {
+ # Update the list of Wine files so we correctly recognize patchset parts
+ # that modify new Wine files.
+ my $WineFiles = $PastImpacts->{WineFiles} || $_WineFiles;
+ map { $Impacts->{WineFiles}->{$_} = 1 } keys %{$WineFiles};
+ map { $Impacts->{WineFiles}->{$_} = 1 } keys %{$PastImpacts->{NewFiles}};
+ map { delete $Impacts->{WineFiles}->{$_} } keys %{$PastImpacts->{DeletedFiles}};
+ }
+ else
+ {
+ $Impacts->{NewFiles} = $PastImpacts->{NewFiles};
+ $Impacts->{DeletedFiles} = $PastImpacts->{DeletedFiles};
+ }
+
foreach my $PastInfo (values %{$PastImpacts->{Tests}})
{
if ($PastInfo->{Files})
@@ -207,6 +275,7 @@ sub GetPatchImpact($;$$)
}
}
}
+
my ($Path, $Change);
while (my $Line = <$fh>)
{
@@ -221,6 +290,7 @@ sub GetPatchImpact($;$$)
elsif ($Line =~ m=^--- \w+/tools/make_makefiles$=)
{
$Impacts->{WineBuild} = $Impacts->{Makefiles} = 1;
+ $Impacts->{IsWinePatch} = 1;
}
elsif ($Line =~ m=^--- /dev/null$=)
{
diff --git a/testbot/lib/WineTestBot/Patches.pm b/testbot/lib/WineTestBot/Patches.pm
index 258aa2c19..03a0ebf16 100644
--- a/testbot/lib/WineTestBot/Patches.pm
+++ b/testbot/lib/WineTestBot/Patches.pm
@@ -135,32 +135,24 @@ sub Submit($$$)
my $PastImpacts;
$PastImpacts = GetPatchImpact($PatchFileName) if ($IsSet);
my $Impacts = GetPatchImpact("$DataDir/patches/" . $self->Id, undef, $PastImpacts);
- if (!$Impacts->{UnitCount})
- {
- $self->Disposition(($IsSet ? "Part" : "Patch") .
- " doesn't affect tests");
- return undef;
- }
- my $User;
- my $Users = CreateUsers();
- if (defined($self->FromEMail))
+ if (!$Impacts->{WineBuild} and !$Impacts->{TestBuild})
{
- $Users->AddFilter("EMail", [$self->FromEMail]);
- if (! $Users->IsEmpty())
+ if ($Impacts->{IsWinePatch})
{
- $User = @{$Users->GetItems()}[0];
+ $self->Disposition(($IsSet ? "Part does" : "Does")
+ ." not impact the Wine build");
}
- }
- if (! defined($User))
- {
- $User = GetBatchUser();
+ else
+ {
+ $self->Disposition(($IsSet ? "Part is not" : "Not") ." a Wine patch");
+ }
+ return undef;
}
# Create a new job for this patch
my $Jobs = CreateJobs();
my $NewJob = $Jobs->Add();
- $NewJob->User($User);
$NewJob->Priority(6);
my $PropertyDescriptor = $Jobs->GetPropertyDescriptorByName("Remarks");
my $Subject = $self->Subject;
@@ -171,84 +163,137 @@ sub Submit($$$)
$PropertyDescriptor->GetMaxLength()));
$NewJob->Patch($self);
- # Add build step to the job
- my $BuildStep = $NewJob->Steps->Add();
- $BuildStep->FileName("patch.diff");
- $BuildStep->FileType("patchdlls"); # This is irrelevant now
- $BuildStep->InStaging(!1);
- $BuildStep->Type("build");
- $BuildStep->DebugLevel(0);
-
- # Add build task
- my $VMs = CreateVMs();
- $VMs->AddFilter("Type", ["build"]);
- $VMs->AddFilter("Role", ["base"]);
- my $BuildVM = ${$VMs->GetItems()}[0];
- my $Task = $BuildStep->Tasks->Add();
- $Task->VM($BuildVM);
- $Task->Timeout($BuildTimeout);
-
- # Save the build step so the others can reference it.
- my ($ErrKey, $ErrProperty, $ErrMessage) = $Jobs->Save();
- if (defined($ErrMessage))
+ my $User;
+ my $Users = CreateUsers();
+ if (defined $self->FromEMail)
{
- $self->Disposition("Failed to submit build step");
- return $ErrMessage;
+ $Users->AddFilter("EMail", [$self->FromEMail]);
+ $User = @{$Users->GetItems()}[0] if (!$Users->IsEmpty());
}
+ $NewJob->User($User || GetBatchUser());
- # Stage the patch so it can be picked up by the job
- if (!link($PatchFileName, "$DataDir/staging/job". $NewJob->Id ."_patch.diff"))
+ my $BuildVMs = CreateVMs();
+ $BuildVMs->AddFilter("Type", ["build"]);
+ $BuildVMs->AddFilter("Role", ["base"]);
+ if ($Impacts->{UnitCount} and !$BuildVMs->IsEmpty())
{
- $self->Disposition("Failed to stage the patch file");
- return $!;
- }
+ # Create the Build Step
+ my $BuildStep = $NewJob->Steps->Add();
+ $BuildStep->FileName("patch.diff");
+ $BuildStep->FileType("patchdlls");
+ $BuildStep->InStaging(!1);
+ $BuildStep->Type("build");
+ $BuildStep->DebugLevel(0);
+
+ # Add build task
+ my $BuildVM = ${$BuildVMs->GetItems()}[0];
+ my $Task = $BuildStep->Tasks->Add();
+ $Task->VM($BuildVM);
+ $Task->Timeout($BuildTimeout);
+
+ # Save the build step so the others can reference it.
+ my ($ErrKey, $ErrProperty, $ErrMessage) = $Jobs->Save();
+ if (defined($ErrMessage))
+ {
+ $self->Disposition("Failed to submit build step");
+ return $ErrMessage;
+ }
- foreach my $Module (sort keys %{$Impacts->{Tests}})
- {
- my $TestInfo = $Impacts->{Tests}->{$Module};
- foreach my $Unit (sort keys %{$TestInfo->{Units}})
+ # Create steps for the Windows tests
+ foreach my $Module (sort keys %{$Impacts->{Tests}})
{
- # Add 32 and 64-bit tasks
- foreach my $Bits ("32", "64")
+ my $TestInfo = $Impacts->{Tests}->{$Module};
+ foreach my $Unit (sort keys %{$TestInfo->{Units}})
{
- $VMs = CreateVMs();
- $VMs->AddFilter("Type", $Bits eq "32" ? ["win32", "win64"] : ["win64"]);
- $VMs->AddFilter("Role", ["base"]);
- if (@{$VMs->GetKeys()})
+ foreach my $Bits ("32", "64")
{
- # Create the corresponding Step
- my $NewStep = $NewJob->Steps->Add();
- $NewStep->PreviousNo($BuildStep->No);
- my $FileName = $TestInfo->{ExeBase};
- $FileName .= "64" if ($Bits eq "64");
- $NewStep->FileName("$FileName.exe");
- $NewStep->FileType("exe$Bits");
- $NewStep->InStaging(!1);
-
- # And a task for each VM
- my $Tasks = $NewStep->Tasks;
- my $SortedKeys = $VMs->SortKeysBySortOrder($VMs->GetKeys());
- foreach my $VMKey (@$SortedKeys)
+ my $WinVMs = CreateVMs();
+ $WinVMs->AddFilter("Type", $Bits eq "32" ? ["win32", "win64"] : ["win64"]);
+ $WinVMs->AddFilter("Role", ["base"]);
+ if (!$WinVMs->IsEmpty())
{
- my $VM = $VMs->GetItem($VMKey);
- my $Task = $Tasks->Add();
- $Task->VM($VM);
- $Task->Timeout($SingleTimeout);
- $Task->CmdLineArg($Unit);
+ # Create one Step per (module, unit, bitness) combination
+ my $NewStep = $NewJob->Steps->Add();
+ $NewStep->PreviousNo($BuildStep->No);
+ my $FileName = $TestInfo->{ExeBase};
+ $FileName .= "64" if ($Bits eq "64");
+ $NewStep->FileName("$FileName.exe");
+ $NewStep->FileType("exe$Bits");
+ $NewStep->InStaging(!1);
+
+ # And a task for each VM
+ my $Tasks = $NewStep->Tasks;
+ my $SortedKeys = $WinVMs->SortKeysBySortOrder($WinVMs->GetKeys());
+ foreach my $VMKey (@$SortedKeys)
+ {
+ my $VM = $WinVMs->GetItem($VMKey);
+ my $Task = $Tasks->Add();
+ $Task->VM($VM);
+ $Task->Timeout($SingleTimeout);
+ $Task->CmdLineArg($Unit);
+ }
}
}
}
}
}
+ my $WineVMs = CreateVMs();
+ $WineVMs->AddFilter("Type", ["wine"]);
+ $WineVMs->AddFilter("Role", ["base"]);
+ if (!$WineVMs->IsEmpty())
+ {
+ # Add a Wine step to the job
+ my $NewStep = $NewJob->Steps->Add();
+ $NewStep->FileName("patch.diff");
+ $NewStep->FileType("patchdlls");
+ $NewStep->InStaging(!1);
+ $NewStep->DebugLevel(0);
+
+ # And a task for each VM
+ my $Tasks = $NewStep->Tasks;
+ my $SortedKeys = $WineVMs->SortKeysBySortOrder($WineVMs->GetKeys());
+ foreach my $VMKey (@$SortedKeys)
+ {
+ my $VM = $WineVMs->GetItem($VMKey);
+ my $Task = $Tasks->Add();
+ $Task->VM($VM);
+ # Only verify that the win32 version compiles
+ $Task->Timeout($WineReconfigTimeout);
+ $Task->CmdLineArg("win32");
+ }
+ }
+
+ if ($NewJob->Steps->IsEmpty())
+ {
+ # This may be a Wine patch but there is no suitable VM to test it!
+ if ($Impacts->{UnitCount})
+ {
+ $self->Disposition("No build or test VM!");
+ }
+ else
+ {
+ $self->Disposition(($IsSet ? "Part does" : "Does") ." not impact the ".
+ ($WineVMs->IsEmpty() ? "Windows " : "") ."tests");
+ }
+ return undef;
+ }
+
# Save it all
- ($ErrKey, $ErrProperty, $ErrMessage) = $Jobs->Save();
+ my ($ErrKey, $ErrProperty, $ErrMessage) = $Jobs->Save();
if (defined $ErrMessage)
{
$self->Disposition("Failed to submit job");
return $ErrMessage;
}
+ # Stage the patch so it can be picked up by the job
+ if (!link($PatchFileName, "$DataDir/staging/job". $NewJob->Id ."_patch.diff"))
+ {
+ $self->Disposition("Failed to stage the patch file");
+ return $!;
+ }
+
# Switch Status to staging to indicate we are done setting up the job
$NewJob->Status("staging");
($ErrKey, $ErrProperty, $ErrMessage) = $Jobs->Save();
@@ -348,27 +393,6 @@ sub IsPatch($$)
return !1;
}
-sub IsTestPatch($$)
-{
- my ($self, $Body) = @_;
-
- if (open(BODY, "<" . $Body->path))
- {
- my $Line;
- while (defined($Line = <BODY>))
- {
- if ($Line =~ m/^\+\+\+ .*\/(dlls|programs)\/[^\/]+\/tests\/[^\/\s]+/)
- {
- close BODY;
- return 1;
- }
- }
- close BODY;
- }
-
- return !1;
-}
-
=pod
=over 12
@@ -412,7 +436,6 @@ sub NewPatch($$$)
my $ErrMessage;
if (scalar(@PatchBodies) == 1)
{
- $Patch->AffectsTests($self->IsTestPatch($PatchBodies[0]));
my $Subject = $Patch->Subject;
$Subject =~ s/32\/64//;
$Subject =~ s/64\/32//;
diff --git a/testbot/lib/WineTestBot/PendingPatchSets.pm b/testbot/lib/WineTestBot/PendingPatchSets.pm
index bfd05e4a3..fc22a8687 100644
--- a/testbot/lib/WineTestBot/PendingPatchSets.pm
+++ b/testbot/lib/WineTestBot/PendingPatchSets.pm
@@ -248,8 +248,7 @@ sub NewSubmission($$)
if (! $Set->CheckSubsetComplete($PartNo))
{
- $Patch->Disposition($Patch->AffectsTests ? "Set not complete yet" :
- "Patch doesn't affect tests");
+ $Patch->Disposition("Set not complete yet");
}
else
{
@@ -260,16 +259,11 @@ sub NewSubmission($$)
my $Part = $Parts->GetItem($PartNo);
if (defined($Part))
{
- if ($Part->Patch->AffectsTests)
+ $ErrMessage = $Set->SubmitSubset($PartNo, $Part->Patch);
+ if (!defined $ErrMessage)
{
- $ErrMessage = $Set->SubmitSubset($PartNo, $Part->Patch);
+ (my $ErrProperty, $ErrMessage) = $Part->Patch->Save();
}
- else
- {
- $Part->Patch->Disposition("Patch doesn't affect tests");
- }
- my $ErrProperty;
- ($ErrProperty, $ErrMessage) = $Part->Patch->Save();
}
else
{
diff --git a/testbot/lib/WineTestBot/StepsTasks.pm b/testbot/lib/WineTestBot/StepsTasks.pm
index 84c5a005f..05854bca7 100644
--- a/testbot/lib/WineTestBot/StepsTasks.pm
+++ b/testbot/lib/WineTestBot/StepsTasks.pm
@@ -78,7 +78,7 @@ sub GetTitle($)
{
$Title .= "64 bit ";
}
- $Title .= $self->CmdLineArg;
+ $Title .= $self->CmdLineArg || "";
}
elsif ($self->Type eq "build")
{
diff --git a/testbot/lib/WineTestBot/Tasks.pm b/testbot/lib/WineTestBot/Tasks.pm
index afd4fb4d3..54ebf5360 100644
--- a/testbot/lib/WineTestBot/Tasks.pm
+++ b/testbot/lib/WineTestBot/Tasks.pm
@@ -177,8 +177,9 @@ sub Run($$)
my ($self, $Step) = @_;
my ($JobId, $StepNo, $TaskNo) = @{$self->GetMasterKey()};
- my $Script = $Step->Type eq "build" ? "Build" :
- $Step->Type eq "reconfig" ? "Reconfig" :
+ my $Script = $Step->Type eq "reconfig" ? "Reconfig" :
+ $self->VM->Type eq "wine" ? "WineTest" :
+ $Step->Type eq "build" ? "Build" :
"Task";
my $Args = ["$BinDir/${ProjectName}Run$Script.pl", "--log-only",
$JobId, $StepNo, $TaskNo];
diff --git a/testbot/lib/WineTestBot/VMs.pm b/testbot/lib/WineTestBot/VMs.pm
index 2f494cb81..cf7bd5ab7 100644
--- a/testbot/lib/WineTestBot/VMs.pm
+++ b/testbot/lib/WineTestBot/VMs.pm
@@ -306,10 +306,10 @@ sub Validate($)
{
my ($self) = @_;
- if ($self->Type ne "win32" && $self->Type ne "win64" &&
- ($self->Role eq "winetest" || $self->Role eq "extra"))
+ if ($self->Type !~ /^(?:win32|win64|wine)$/ and
+ $self->Role =~ /^(?:extra|winetest)$/)
{
- return ("Role", "Only win32 and win64 VMs can have a role of '" . $self->Role . "'");
+ return ("Role", "Only win32, win64 and wine VMs can have a role of '" . $self->Role . "'");
}
return $self->SUPER::Validate();
}
@@ -664,7 +664,7 @@ sub CreateItem($)
my @PropertyDescriptors = (
CreateBasicPropertyDescriptor("Name", "VM name", 1, 1, "A", 20),
CreateBasicPropertyDescriptor("SortOrder", "Display order", !1, 1, "N", 3),
- CreateEnumPropertyDescriptor("Type", "Type of VM", !1, 1, ['win32', 'win64', 'build']),
+ CreateEnumPropertyDescriptor("Type", "Type of VM", !1, 1, ['win32', 'win64', 'build', 'wine']),
CreateEnumPropertyDescriptor("Role", "VM Role", !1, 1, ['extra', 'base', 'winetest', 'retired', 'deleted']),
CreateEnumPropertyDescriptor("Status", "Current status", !1, 1, ['dirty', 'reverting', 'sleeping', 'idle', 'running', 'off', 'offline', 'maintenance']),
CreateBasicPropertyDescriptor("Errors", "Errors", !1, !1, "N", 2),
--
2.17.1
June 21, 2018
[PATCH 2/4] testbot/WineRun*: Improve the VM and Step validation.
by Francois Gouget
Check that the VM is of the expected type. Also the VM should always be
powered on (for powered off snapshots LibvirtTool.pl is responsible for
powering on the VM), even when debugging.
Move the Step validation next to the VM one.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunBuild.pl | 15 ++++++++++++---
testbot/bin/WineRunReconfig.pl | 15 ++++++++++++---
testbot/bin/WineRunTask.pl | 24 ++++++++++++++----------
3 files changed, 38 insertions(+), 16 deletions(-)
diff --git a/testbot/bin/WineRunBuild.pl b/testbot/bin/WineRunBuild.pl
index 60af32c73..ff04ded0c 100755
--- a/testbot/bin/WineRunBuild.pl
+++ b/testbot/bin/WineRunBuild.pl
@@ -309,18 +309,27 @@ sub FatalTAError($$)
#
-# Check the VM
+# Check the VM and Step
#
-if (!$Debug and $VM->Status ne "running")
+if ($VM->Type ne "build")
+{
+ FatalError("This is not a build VM! (" . $VM->Type . ")\n");
+}
+elsif (!$Debug and $VM->Status ne "running")
{
FatalError("The VM is not ready for use (" . $VM->Status . ")\n");
}
-elsif ($Debug and !$VM->GetDomain()->IsPoweredOn())
+elsif (!$VM->GetDomain()->IsPoweredOn())
{
FatalError("The VM is not powered on\n");
}
+if ($Step->FileType ne "patchdlls")
+{
+ FatalError("Unexpected file type '". $Step->FileType ."' found\n");
+}
+
#
# Figure out what to build
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index 2e338c975..23b038a1f 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -309,18 +309,27 @@ sub FatalTAError($$)
#
-# Check the VM
+# Check the VM and Step
#
-if (!$Debug and $VM->Status ne "running")
+if ($VM->Type ne "build")
+{
+ FatalError("This is not a build VM! (" . $VM->Type . ")\n");
+}
+elsif (!$Debug and $VM->Status ne "running")
{
FatalError("The VM is not ready for use (" . $VM->Status . ")\n");
}
-elsif ($Debug and !$VM->GetDomain()->IsPoweredOn())
+elsif (!$VM->GetDomain()->IsPoweredOn())
{
FatalError("The VM is not powered on\n");
}
+if ($Step->FileType ne "none")
+{
+ FatalError("Unexpected file type '". $Step->FileType ."' found\n");
+}
+
#
# Run the build
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 3f5a3ee8d..7604e73ad 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -364,18 +364,27 @@ sub FatalTAError($$;$)
#
-# Check the VM
+# Check the VM and Step
#
-if (!$Debug and $VM->Status ne "running")
+if ($VM->Type ne "win32" and $VM->Type ne "win64")
+{
+ FatalError("This is not a Windows VM! (" . $VM->Type . ")\n");
+}
+elsif (!$Debug and $VM->Status ne "running")
{
FatalError("The VM is not ready for use (" . $VM->Status . ")\n");
}
-elsif ($Debug and !$VM->GetDomain()->IsPoweredOn())
+elsif (!$VM->GetDomain()->IsPoweredOn())
{
FatalError("The VM is not powered on\n");
}
+if ($Step->FileType ne "exe32" and $Step->FileType ne "exe64")
+{
+ FatalError("Unexpected file type '". $Step->FileType ."' found\n");
+}
+
#
# Setup the VM
@@ -395,11 +404,6 @@ if (!$TA->SetTime())
}
}
-my $FileType = $Step->FileType;
-if ($FileType ne "exe32" && $FileType ne "exe64")
-{
- FatalError("Unexpected file type $FileType found\n");
-}
my $FileName = $Step->FileName;
Debug(Elapsed($Start), " Sending '". $Step->GetFullFileName() ."'\n");
if (!$TA->SendFile($Step->GetFullFileName(), $FileName, 0))
@@ -418,7 +422,7 @@ if ($Step->ReportSuccessfulTests)
my $IsWineTest = 1;
if ($Step->Type eq "single")
{
- my $TestLauncher = "TestLauncher" . ($FileType eq "exe64" ? "64" : "32") . ".exe";
+ my $TestLauncher = "TestLauncher" . ($Step->FileType eq "exe64" ? "64" : "32") . ".exe";
Debug(Elapsed($Start), " Sending 'latest/$TestLauncher'\n");
if (!$TA->SendFile("$DataDir/latest/$TestLauncher", $TestLauncher, 0))
{
@@ -450,7 +454,7 @@ elsif ($Step->Type eq "suite")
$Tag =~ s/[^a-zA-Z0-9]/-/g;
if ($VM->Type eq "win64")
{
- $Tag .= "-" . ($FileType eq "exe64" ? "64" : "32");
+ $Tag .= "-" . ($Step->FileType eq "exe64" ? "64" : "32");
}
if (defined($WebHostName))
{
--
2.17.1
June 21, 2018
[PATCH 1/4] testbot: Build the per-module test unit list from the list of Wine files.
by Francois Gouget
This also caches winefiles.txt so it is only reloaded when it changes.
Also stop generating and retrieving testlist.txt since it is not
needed anymore. If desired testlist.txt can be deleted for cleanup.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunReconfig.pl | 10 -----
testbot/lib/WineTestBot/PatchUtils.pm | 62 +++++++++++++--------------
2 files changed, 31 insertions(+), 41 deletions(-)
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index 2950799d5..2e338c975 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -414,16 +414,6 @@ if ($NewStatus eq "completed")
}
}
- Debug(Elapsed($Start), " Retrieving the updated test list '$TaskDir/testlist.txt'\n");
- if ($TA->GetFile("testlist.txt", "$TaskDir/testlist.txt"))
- {
- copy "$TaskDir/testlist.txt", "$DataDir/latest/testlist.txt";
- }
- elsif (!defined $TAError)
- {
- $TAError = "An error occurred while retrieving the test list: ". $TA->GetLastError();
- }
-
Debug(Elapsed($Start), " Retrieving the list of Wine files '$TaskDir/winefiles.txt'\n");
if ($TA->GetFile("latest/winefiles.txt", "$TaskDir/winefiles.txt"))
{
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index f83df6087..3bf172125 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -58,8 +58,8 @@ my $IgnoredPathsRe = join('|',
=item C<UpdateWineData()>
-Updates the summary information about the Wine source such as the list of
-tests (testlist.txt) and the full list of Wine files.
+Updates information about the Wine source, such as the list of Wine files,
+for use by the TestBot server.
=back
=cut
@@ -72,51 +72,51 @@ sub UpdateWineData($)
my $ErrMessage = `cd '$WineDir' && git ls-tree -r --name-only HEAD 2>&1 >'$DataDir/latest/winefiles.txt'`;
return $ErrMessage if ($? != 0);
-
- if (open(my $fh, ">", "$DataDir/testlist.txt"))
- {
- foreach my $TestFile (glob("$WineDir/*/*/tests/*.c"),
- glob("$WineDir/*/*/tests/*.spec"))
- {
- next if ($TestFile =~ m=/testlist\.c$=);
- $TestFile =~ s=^$WineDir/==;
- print $fh "$TestFile\n";
- }
- close($fh);
- return undef;
- }
-
- return "Could not open 'testlist.txt' for writing: $!";
}
+my $_TimeStamp;
+my $_TestList;
+
=pod
=over 12
-=item C<GetTestList()>
+=item C<_LoadWineFiles()>
-Returns a hashtable containing the list of the source files for a given module.
-This structure is built from the latest/testlist.txt file.
+Reads latest/winefiles.txt to build a per-module hashtable of the test unit
+files.
=back
=cut
-sub GetTestList()
+sub _LoadWineFiles()
{
- my $TestList = {};
- if (open(my $File, "<", "$DataDir/latest/testlist.txt"))
+ my $FileName = "$DataDir/latest/winefiles.txt";
+ my $MTime = (stat($FileName))[9] || 0;
+
+ if ($_TestList and $_TimeStamp == $MTime)
{
- while (my $TestFileName = <$File>)
+ # The file has not changed since we loaded it
+ return;
+ }
+
+ $_TimeStamp = $MTime;
+ $_TestList = {};
+ if (open(my $fh, "<", $FileName))
+ {
+ while (my $Line = <$fh>)
{
- chomp $TestFileName;
- if ($TestFileName =~ m~^\w+/([^/]+)/tests/([^/]+)$~)
+ chomp $Line;
+
+ if ($Line =~ m~^\w+/([^/]+)/tests/([^/]+)$~)
{
my ($Module, $File) = ($1, $2);
- $TestList->{$Module}->{$File} = 1;
+ next if ($File eq "testlist.c");
+ next if ($File !~ /\.(?:c|spec)$/);
+ $_TestList->{$Module}->{$File} = 1;
}
}
- close($File);
+ close($fh);
}
- return $TestList;
}
sub _HandleFile($$$)
@@ -154,8 +154,7 @@ sub _HandleFile($$$)
if (!$Tests->{$Module}->{Files})
{
- my $TestList = ( $Impacts->{TestList} ||= GetTestList() );
- foreach my $File (keys %{$TestList->{$Module}})
+ foreach my $File (keys %{$_TestList->{$Module}})
{
$Tests->{$Module}->{Files}->{$File} = 0; # not modified
}
@@ -192,6 +191,7 @@ sub GetPatchImpact($;$$)
NoUnits => $NoUnits,
Tests => {},
};
+ _LoadWineFiles();
if ($PastImpacts)
{
--
2.17.1
June 21, 2018
[PATCH 2/2] testbot/build: Add proper command line options to Build.pl and Reconfig.pl.
by Francois Gouget
This makes it much easier to test the scripts directly on the VM.
This also makes it possible to test one aspect of the scripts without
having to go through the whole process. In particular the --no-rm
Reconfig.pl option speeds up testing by avoiding rebuilding from
scratch.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/build/Build.pl | 175 +++++++++++++++++++++++-----------
testbot/bin/build/Reconfig.pl | 137 +++++++++++++++++++++++---
2 files changed, 241 insertions(+), 71 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index 17ae74ff5..4df107005 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -43,12 +43,19 @@ sub BEGIN
}
$::BuildEnv = 1;
}
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
use WineTestBot::Config;
use WineTestBot::PatchUtils;
use WineTestBot::Utils;
+#
+# Logging and error handling helpers
+#
+
sub InfoMsg(@)
{
print @_;
@@ -59,12 +66,16 @@ sub LogMsg(@)
print "Build: ", @_;
}
-sub FatalError(@)
+sub Error(@)
{
- print STDERR @_;
- exit 1;
+ print STDERR "$Name0:error: ", @_;
}
+
+#
+# Build helpers
+#
+
my $ncpus;
sub CountCPUs()
{
@@ -133,9 +144,11 @@ sub BuildNative()
return 1;
}
-sub BuildTestExecutables($$)
+sub BuildTestExecutables($$$)
{
- my ($Impacts, $Bits) = @_;
+ my ($Targets, $Impacts, $Bits) = @_;
+
+ return 1 if (!$Targets->{"exe$Bits"});
my (@BuildDirs, @TestExes);
foreach my $TestInfo (values %{$Impacts->{Tests}})
@@ -168,62 +181,113 @@ sub BuildTestExecutables($$)
return $Success;
}
+
+#
+# Setup and command line processing
+#
+
$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
-my ($PatchFile, $BitIndicators);
-if (@ARGV == 2)
-{
- ($PatchFile, $BitIndicators) = @ARGV;
-}
-else
-{
- # FIXME Remove support for the legacy parameters
- my ($_PatchType, $_BaseName);
- ($PatchFile, $_PatchType, $_BaseName, $BitIndicators) = @ARGV;
-}
-if (! $PatchFile || !$BitIndicators)
-{
- FatalError "Usage: Build.pl <patchfile> <bits>\n";
-}
-
-# Verify parameters
-if (!IsValidFileName($PatchFile))
-{
- FatalError "The patch filename '$PatchFile' contains invalid characters\n";
-}
-$PatchFile = "$DataDir/staging/$PatchFile";
-if (!-r $PatchFile)
-{
- FatalError "Patch file '$PatchFile' is not readable\n";
-}
+my %AllTargets;
+map { $AllTargets{$_} = 1 } qw(exe32 exe64);
-my ($Run32, $Run64);
-if ($BitIndicators =~ m/^([\d,]+)$/)
+my ($Usage, $PatchFile, $TargetList);
+my $IgnoreNext = 0; # FIXME Backward compatibility
+while (@ARGV)
{
- foreach my $BitsValue (split /,/, $1)
+ my $Arg = shift @ARGV;
+ if ($Arg =~ /^patch(?:dlls|programs)$/)
{
- if ($BitsValue eq "32")
- {
- $Run32 = 1;
- }
- elsif ($BitsValue eq "64")
+ $IgnoreNext ||= 1; # Ignore this legacy parameter
+ }
+ elsif ($IgnoreNext == 1)
+ {
+ $IgnoreNext = 2; # Ignore this legacy parameter
+ }
+ elsif ($Arg =~ /^(?:-\?|-h|--help)$/)
+ {
+ $Usage = 0;
+ last;
+ }
+ elsif ($Arg =~ /^-/)
+ {
+ Error "unknown option '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+ elsif (!defined $PatchFile)
+ {
+ if (IsValidFileName($Arg))
{
- $Run64 = 1;
+ $PatchFile = "$DataDir/staging/$Arg";
+ if (!-r $PatchFile)
+ {
+ Error "patch file '$Arg' is not readable\n";
+ $Usage = 2;
+ }
}
else
{
- FatalError "Invalid number of bits $BitsValue\n";
+ Error "the patch filename '$Arg' contains invalid characters\n";
+ $Usage = 2;
+ last;
}
}
- if (!$Run32 && !$Run64)
+ elsif (!defined $TargetList)
{
- FatalError "Specify at least one of 32 or 64 bits\n";
+ $TargetList = $Arg;
+ }
+ else
+ {
+ Error "unexpected argument '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+}
+
+# Check and untaint parameters
+my $Targets;
+if (!defined $Usage)
+{
+ if (!defined $PatchFile)
+ {
+ Error "you must specify a patch to apply\n";
+ $Usage = 2;
+ }
+
+ $TargetList = join(",", keys %AllTargets) if (!defined $TargetList);
+ foreach my $Target (split /,/, $TargetList)
+ {
+ $Target = "exe$1" if ($Target =~ /^(32|64)$/);
+ if (!$AllTargets{$Target})
+ {
+ Error "invalid target name $Target\n";
+ $Usage = 2;
+ last;
+ }
+ $Targets->{$Target} = 1;
}
}
-else
+if (defined $Usage)
{
- FatalError "Invalid number of bits $BitIndicators\n";
+ if ($Usage)
+ {
+ Error "try '$Name0 --help' for more information\n";
+ exit $Usage;
+ }
+ print "Usage: $Name0 [--help] PATCHFILE TARGETS\n";
+ print "\n";
+ print "Applies the specified patch and rebuilds the Wine test executables.\n";
+ print "\n";
+ print "Where:\n";
+ print " PATCHFILE Is the staging file containing the patch to build.\n";
+ print " TARGETS Is a comma-separated list of build targets. By default every\n";
+ print " target is run.\n";
+ print " - exe32: Rebuild the 32 bit Windows test executables.\n";
+ print " - exe64: Rebuild the 64 bit Windows test executables.\n";
+ print " --help Shows this usage message.\n";
+ exit 0;
}
if ($DataDir =~ /'/)
@@ -232,20 +296,19 @@ if ($DataDir =~ /'/)
exit(1);
}
-my $Impacts = ApplyPatch($PatchFile);
-exit(1) if (!$Impacts);
+
+#
+# Run the builds
+#
CountCPUs();
-if ($Impacts->{WineBuild} and !BuildNative())
-{
- exit(1);
-}
-if ($Run32 && !BuildTestExecutables($Impacts, 32))
-{
- exit(1);
-}
-if ($Run64 && !BuildTestExecutables($Impacts, 64))
+my $Impacts = ApplyPatch($PatchFile);
+
+if (!$Impacts or
+ ($Impacts->{WineBuild} and !BuildNative()) or
+ !BuildTestExecutables($Targets, $Impacts, 32) or
+ !BuildTestExecutables($Targets, $Impacts, 64))
{
exit(1);
}
diff --git a/testbot/bin/build/Reconfig.pl b/testbot/bin/build/Reconfig.pl
index 5ecbc2af3..450de0e83 100755
--- a/testbot/bin/build/Reconfig.pl
+++ b/testbot/bin/build/Reconfig.pl
@@ -38,12 +38,19 @@ sub BEGIN
unshift @INC, "$::RootDir/lib";
}
$::BuildEnv = 1;
- }
+}
+my $Name0 = $0;
+$Name0 =~ s+^.*/++;
+
use WineTestBot::Config;
use WineTestBot::PatchUtils;
+#
+# Logging and error handling helpers
+#
+
sub InfoMsg(@)
{
print @_;
@@ -54,6 +61,16 @@ sub LogMsg(@)
print "Reconfig: ", @_;
}
+sub Error(@)
+{
+ print STDERR "$Name0:error: ", @_;
+}
+
+
+#
+# Build helpers
+#
+
my $ncpus;
sub CountCPUs()
{
@@ -108,8 +125,11 @@ sub BuildTestLauncher()
return 1;
}
-sub GitPull()
+sub GitPull($)
{
+ my ($Targets) = @_;
+ return 1 if (!$Targets->{update});
+
InfoMsg "\nUpdating the Wine source\n";
system("cd '$DataDir/wine' && git pull");
if ($? != 0)
@@ -128,14 +148,17 @@ sub GitPull()
return 1;
}
-sub BuildNative()
+sub BuildNative($$)
{
+ my ($Targets, $NoRm) = @_;
+
+ return 1 if (!$Targets->{native});
mkdir "$DataDir/build-native" if (! -d "$DataDir/build-native");
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding native tools\n";
system("cd '$DataDir/build-native' && set -x && ".
- "rm -rf * && ".
+ ($NoRm ? "" : "rm -rf * && ") .
"time ../wine/configure --enable-win64 --without-x --without-freetype --disable-winetest && ".
"time make -j$ncpus __tooldeps__");
@@ -148,17 +171,18 @@ sub BuildNative()
return 1;
}
-sub BuildCross($)
+sub BuildCross($$$)
{
- my ($Bits) = @_;
+ my ($Targets, $NoRm, $Bits) = @_;
- my $Host = ($Bits == 64 ? "x86_64-w64-mingw32" : "i686-w64-mingw32");
- mkdir "$DataDir/build-mingw$Bits" if (! -d "$DataDir/build-mingw$Bits");
+ return 1 if (!$Targets->{"exe$Bits"});
+ mkdir "$DataDir/build-mingw$Bits" if (!-d "$DataDir/build-mingw$Bits");
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding the $Bits-bit test executables\n";
+ my $Host = ($Bits == 64 ? "x86_64-w64-mingw32" : "i686-w64-mingw32");
system("cd '$DataDir/build-mingw$Bits' && set -x && ".
- "rm -rf * && ".
+ ($NoRm ? "" : "rm -rf * && ") .
"time ../wine/configure --host=$Host --with-wine-tools=../build-native --without-x --without-freetype --disable-winetest && ".
"time make -j$ncpus buildtests");
if ($? != 0)
@@ -170,9 +194,87 @@ sub BuildCross($)
return 1;
}
+
+#
+# Setup and command line processing
+#
+
$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
+my %AllTargets;
+map { $AllTargets{$_} = 1 } qw(update native exe32 exe64);
+
+my ($Usage, $TargetList, $NoRm);
+while (@ARGV)
+{
+ my $Arg = shift @ARGV;
+ if ($Arg eq "--no-rm")
+ {
+ $NoRm = 1;
+ }
+ elsif ($Arg =~ /^(?:-\?|-h|--help)$/)
+ {
+ $Usage = 0;
+ last;
+ }
+ elsif ($Arg =~ /^-/)
+ {
+ Error "unknown option '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+ elsif (!defined $TargetList)
+ {
+ $TargetList = $Arg;
+ }
+ else
+ {
+ Error "unexpected argument '$Arg'\n";
+ $Usage = 2;
+ last;
+ }
+}
+
+# Check and untaint parameters
+my $Targets;
+if (!defined $Usage)
+{
+ $TargetList = join(",", keys %AllTargets) if (!defined $TargetList);
+ foreach my $Target (split /,/, $TargetList)
+ {
+ if (!$AllTargets{$Target})
+ {
+ Error "invalid target name $Target\n";
+ $Usage = 2;
+ last;
+ }
+ $Targets->{$Target} = 1;
+ }
+}
+if (defined $Usage)
+{
+ if ($Usage)
+ {
+ Error "try '$Name0 --help' for more information\n";
+ exit $Usage;
+ }
+ print "Usage: $Name0 [--no-rm] [--help] [TARGETS]\n";
+ print "\n";
+ print "Updates Wine to the latest version and recompiles it so the host is ready to build executables for the Windows tests.\n";
+ print "\n";
+ print "Where:\n";
+ print " TARGETS Is a comma-separated list of reconfiguration targets. By default\n";
+ print " every target is run.\n";
+ print " - update: Update Wine's source code.\n";
+ print " - native: Rebuild the native Wine tools.\n";
+ print " - exe32: Rebuild the 32 bit Windows test executables.\n";
+ print " - exe64: Rebuild the 64 bit Windows test executables.\n";
+ print " --no-rm Don't rebuild from scratch.\n";
+ print " --help Shows this usage message.\n";
+ exit 0;
+}
+
if ($DataDir =~ /'/)
{
LogMsg "The install path contains invalid characters\n";
@@ -184,14 +286,19 @@ if (! -d "$DataDir/staging" and ! mkdir "$DataDir/staging")
exit(1);
}
+
+#
+# Run the builds
+#
+
CountCPUs();
-if (!BuildTestAgentd() ||
- !BuildTestLauncher() ||
- !GitPull() ||
- !BuildNative() ||
- !BuildCross(32) ||
- !BuildCross(64))
+if (!BuildTestAgentd() or
+ !BuildTestLauncher() or
+ !GitPull($Targets) or
+ !BuildNative($Targets, $NoRm) or
+ !BuildCross($Targets, $NoRm, 32) or
+ !BuildCross($Targets, $NoRm, 64))
{
exit(1);
}
--
2.17.1
June 21, 2018
[PATCH 1/2] testbot/build: Quote the paths in the shell commands.
by Francois Gouget
Also check that $DataDir does not contain single quotes, thus ensuring
our simple quoting scheme works.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
A more absolutist approach would be to use ShQuote() everywhere which
would remove the single quote restriction. But that would compromise
readability. So this solution seems like a good compromise.
Also this is mostly cosmetic in the first place since the administrator
would presumably not put spaces, stars, dollar signs or single quotes in
the $DataDir path. Still I much prefer having proper quoting in my shell
scripts.
testbot/bin/build/Build.pl | 16 +++++++++++-----
testbot/bin/build/Reconfig.pl | 17 +++++++++++------
2 files changed, 22 insertions(+), 11 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index c23bb8780..17ae74ff5 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -82,7 +82,7 @@ sub ApplyPatch($)
my ($PatchFile) = @_;
InfoMsg "Applying patch\n";
- system("cd $DataDir/wine && set -x && ".
+ system("cd '$DataDir/wine' && set -x && ".
"git apply --verbose ". ShQuote($PatchFile) ." && ".
"git add -A");
if ($? != 0)
@@ -95,7 +95,7 @@ sub ApplyPatch($)
if ($Impacts->{Makefiles})
{
InfoMsg "\nRunning make_makefiles\n";
- system("cd $DataDir/wine && set -x && ./tools/make_makefiles");
+ system("cd '$DataDir/wine' && set -x && ./tools/make_makefiles");
if ($? != 0)
{
LogMsg "make_makefiles failed\n";
@@ -106,7 +106,7 @@ sub ApplyPatch($)
if ($Impacts->{Autoconf} && !$Impacts->{HasConfigure})
{
InfoMsg "\nRunning autoconf\n";
- system("cd $DataDir/wine && set -x && autoconf");
+ system("cd '$DataDir/wine' && set -x && autoconf");
if ($? != 0)
{
LogMsg "Autoconf failed\n";
@@ -122,7 +122,7 @@ sub BuildNative()
mkdir "$DataDir/build-native" if (! -d "$DataDir/build-native");
InfoMsg "\nRebuilding native tools\n";
- system("cd $DataDir/build-native && set -x && ".
+ system("cd '$DataDir/build-native' && set -x && ".
"time make -j$ncpus __tooldeps__");
if ($? != 0)
{
@@ -147,7 +147,7 @@ sub BuildTestExecutables($$)
}
InfoMsg "\nBuilding the $Bits-bit test executable(s)\n";
- system("cd $DataDir/build-mingw$Bits && set -x && ".
+ system("cd '$DataDir/build-mingw$Bits' && set -x && ".
"time make -j$ncpus ". join(" ", sort @BuildDirs));
if ($? != 0)
{
@@ -226,6 +226,12 @@ else
FatalError "Invalid number of bits $BitIndicators\n";
}
+if ($DataDir =~ /'/)
+{
+ LogMsg "The install path contains invalid characters\n";
+ exit(1);
+}
+
my $Impacts = ApplyPatch($PatchFile);
exit(1) if (!$Impacts);
diff --git a/testbot/bin/build/Reconfig.pl b/testbot/bin/build/Reconfig.pl
index 2da2f54a4..5ecbc2af3 100755
--- a/testbot/bin/build/Reconfig.pl
+++ b/testbot/bin/build/Reconfig.pl
@@ -73,7 +73,7 @@ sub BuildTestAgentd()
if (! -x "$BinDir/build/testagentd")
{
InfoMsg "\nBuilding the native testagentd\n";
- system("cd $::RootDir/src/testagentd && set -x && ".
+ system("cd '$::RootDir/src/testagentd' && set -x && ".
"time make -j$ncpus build");
if ($? != 0)
{
@@ -83,7 +83,7 @@ sub BuildTestAgentd()
}
InfoMsg "\nRebuilding the Windows TestAgentd\n";
- system("cd $::RootDir/src/testagentd && set -x && ".
+ system("cd '$::RootDir/src/testagentd' && set -x && ".
"time make -j$ncpus iso");
if ($? != 0)
{
@@ -97,7 +97,7 @@ sub BuildTestAgentd()
sub BuildTestLauncher()
{
InfoMsg "\nRebuilding TestLauncher\n";
- system("cd $::RootDir/src/TestLauncher && set -x && ".
+ system("cd '$::RootDir/src/TestLauncher' && set -x && ".
"time make -j$ncpus");
if ($? != 0)
{
@@ -111,7 +111,7 @@ sub BuildTestLauncher()
sub GitPull()
{
InfoMsg "\nUpdating the Wine source\n";
- system("cd $DataDir/wine && git pull");
+ system("cd '$DataDir/wine' && git pull");
if ($? != 0)
{
LogMsg "Git pull failed\n";
@@ -134,7 +134,7 @@ sub BuildNative()
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding native tools\n";
- system("cd $DataDir/build-native && set -x && ".
+ system("cd '$DataDir/build-native' && set -x && ".
"rm -rf * && ".
"time ../wine/configure --enable-win64 --without-x --without-freetype --disable-winetest && ".
"time make -j$ncpus __tooldeps__");
@@ -157,7 +157,7 @@ sub BuildCross($)
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding the $Bits-bit test executables\n";
- system("cd $DataDir/build-mingw$Bits && set -x && ".
+ system("cd '$DataDir/build-mingw$Bits' && set -x && ".
"rm -rf * && ".
"time ../wine/configure --host=$Host --with-wine-tools=../build-native --without-x --without-freetype --disable-winetest && ".
"time make -j$ncpus buildtests");
@@ -173,6 +173,11 @@ sub BuildCross($)
$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
+if ($DataDir =~ /'/)
+{
+ LogMsg "The install path contains invalid characters\n";
+ exit(1);
+}
if (! -d "$DataDir/staging" and ! mkdir "$DataDir/staging")
{
LogMsg "Unable to create '$DataDir/staging': $!\n";
--
2.17.1
June 21, 2018
[PATCH 3/3] testbot/WineRunTask: Rename the Windows test reports.
by Francois Gouget
Keep 'log' for the task log messages (such as the compilation log) and
store the actual (WineTest) test report in '.report' files.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
A coming patch will put the output of the batch file in the log file
(after I have checked that the TestBot VMs have the version of
TestAgentd where redirections work correctly).
testbot/bin/WineRunTask.pl | 16 ++++++++--------
testbot/web/JobDetails.pl | 9 ++++++---
2 files changed, 14 insertions(+), 11 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 7f92b8858..3f5a3ee8d 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -195,7 +195,7 @@ my $OldUMask = umask(002);
my $TaskDir = $Task->CreateDir();
umask($OldUMask);
my $VM = $Task->VM;
-my $RptFileName = $VM->Name . ".rpt";
+my $RptFileName = $Step->FileType .".report";
my $Start = Time();
@@ -292,13 +292,13 @@ sub WrapUpAndExit($;$$$)
if ($Step->Type eq 'suite' and $Status eq 'completed' and !$TimedOut)
{
# Keep the old report if the new one is missing
- if (-f "$TaskDir/log" and !-z "$TaskDir/log")
+ if (-f "$TaskDir/$RptFileName" and !-z "$TaskDir/$RptFileName")
{
# Update the reference VM suite results for WineSendLog.pl
my $LatestBaseName = join("", "$DataDir/latest/", $Task->VM->Name, "_",
$Step->FileType eq "exe64" ? "64" : "32");
unlink("$LatestBaseName.log");
- link("$TaskDir/log", "$LatestBaseName.log");
+ link("$TaskDir/$RptFileName", "$LatestBaseName.log");
unlink("$LatestBaseName.err");
if (-f "$TaskDir/err" and !-z "$TaskDir/err")
{
@@ -518,11 +518,11 @@ if (!defined $TA->Wait($Pid, $Timeout, $Keepalive))
}
my $TimedOut;
-Debug(Elapsed($Start), " Retrieving the report file to 'log'\n");
-if ($TA->GetFile($RptFileName, "$TaskDir/log"))
+Debug(Elapsed($Start), " Retrieving the report file to '$RptFileName'\n");
+if ($TA->GetFile($RptFileName, "$TaskDir/$RptFileName"))
{
- chmod 0664, "$TaskDir/log";
- if (open(my $LogFile, "<", "$TaskDir/log"))
+ chmod 0664, "$TaskDir/$RptFileName";
+ if (open(my $LogFile, "<", "$TaskDir/$RptFileName"))
{
# There is more than one test unit when running the full test suite so keep
# track of the current one. Note that for the TestBot we don't count or
@@ -788,7 +788,7 @@ if ($TA->GetFile($RptFileName, "$TaskDir/log"))
else
{
$NewStatus = 'boterror';
- Error "Unable to open 'log' for reading: $!\n";
+ Error "Unable to open '$RptFileName' for reading: $!\n";
LogTaskError("Unable to open the log file for reading: $!\n");
}
}
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 3add52b4c..a1a846ff9 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -280,9 +280,12 @@ sub GetHtmlLine($$$)
return (undef, $Line);
}
+my @MILogFiles = qw(exe32.report exe64.report log log.old);
my %MILogLabels = (
- "log" => "task log",
- "log.old" => "old logs",
+ "exe32.report" => "32 bit Windows report",
+ "exe64.report" => "64 bit Windows report",
+ "log" => "task log",
+ "log.old" => "old logs",
);
sub InitMoreInfo($)
@@ -298,7 +301,7 @@ sub InitMoreInfo($)
my $Value = $self->GetParam("f$Key");
my $TaskDir = $StepTask->GetTaskDir();
- foreach my $Log ("log", "log.old")
+ foreach my $Log (@MILogFiles)
{
if (!-f "$TaskDir/$Log" or -z "$TaskDir/$Log")
{
--
2.17.1
June 21, 2018
[PATCH 2/3] testbot/WineRunTask: Preserve the old WineTest report in case of timeout.
by Francois Gouget
If the task timed out the new report is likely quite incomplete and thus
would be a poor substitute for the existing reference WineTest report.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index ed190348b..7f92b8858 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -289,7 +289,7 @@ sub WrapUpAndExit($;$$$)
$VM->Save();
}
- if ($Status eq 'completed' and $Step->Type eq 'suite')
+ if ($Step->Type eq 'suite' and $Status eq 'completed' and !$TimedOut)
{
# Keep the old report if the new one is missing
if (-f "$TaskDir/log" and !-z "$TaskDir/log")
--
2.17.1
June 21, 2018
[PATCH 1/3] testbot/WineRunTask: Keep the old reference report if the new one is missing.
by Francois Gouget
The WineTest results usually don't change too much from one run to the
next so it's better to have a slightly out of date report than nothing
at all.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 21 ++++++++++++++-------
1 file changed, 14 insertions(+), 7 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index c4ca578e2..ed190348b 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -291,13 +291,20 @@ sub WrapUpAndExit($;$$$)
if ($Status eq 'completed' and $Step->Type eq 'suite')
{
- # Update the reference VM suite results for WineSendLog.pl
- my $LatestBaseName = join("", "$DataDir/latest/", $Task->VM->Name, "_",
- $Step->FileType eq "exe64" ? "64" : "32");
- unlink("$LatestBaseName.log");
- link("$TaskDir/log", "$LatestBaseName.log") if (-f "$TaskDir/log");
- unlink("$LatestBaseName.err");
- link("$TaskDir/err", "$LatestBaseName.err") if (-f "$TaskDir/err");
+ # Keep the old report if the new one is missing
+ if (-f "$TaskDir/log" and !-z "$TaskDir/log")
+ {
+ # Update the reference VM suite results for WineSendLog.pl
+ my $LatestBaseName = join("", "$DataDir/latest/", $Task->VM->Name, "_",
+ $Step->FileType eq "exe64" ? "64" : "32");
+ unlink("$LatestBaseName.log");
+ link("$TaskDir/log", "$LatestBaseName.log");
+ unlink("$LatestBaseName.err");
+ if (-f "$TaskDir/err" and !-z "$TaskDir/err")
+ {
+ link("$TaskDir/err", "$LatestBaseName.err");
+ }
+ }
}
my $Result = $VM->Name .": ". $VM->Status ." Status: $Status Failures: ". (defined $TestFailures ? $TestFailures : "unset");
--
2.17.1
June 21, 2018
[PATCH] testbot/WineRun*: Don't duplicate errors and factorize the log parsing.
by Francois Gouget
Move the task log parsing functions to LogUtils.pm so the WineRun*.pl
scripts can share them.
Also stop copying the 'Build: *' result lines from the log to the err
file. It's up to the GUI to present all the relevant lines when only
showing the log summary (which it does now).
Finally, there is nothing for the script to do if the patch fails to
apply. So even if we did not get the full log or the task timed out
somehow, the status of the task should be 'badpatch' and the other
errors don't matter.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunBuild.pl | 49 ++++++++----------
testbot/bin/WineRunReconfig.pl | 49 ++++++------------
testbot/lib/WineTestBot/LogUtils.pm | 77 +++++++++++++++++++++++++++++
3 files changed, 111 insertions(+), 64 deletions(-)
create mode 100644 testbot/lib/WineTestBot/LogUtils.pm
diff --git a/testbot/bin/WineRunBuild.pl b/testbot/bin/WineRunBuild.pl
index 1bc6cffbc..60af32c73 100755
--- a/testbot/bin/WineRunBuild.pl
+++ b/testbot/bin/WineRunBuild.pl
@@ -46,6 +46,7 @@ use WineTestBot::Jobs;
use WineTestBot::PatchUtils;
use WineTestBot::VMs;
use WineTestBot::Log;
+use WineTestBot::LogUtils;
use WineTestBot::Engine::Notify;
@@ -391,39 +392,29 @@ if (!defined $TA->Wait($Pid, $Task->Timeout, 60))
Debug(Elapsed($Start), " Retrieving 'Build.log'\n");
if ($TA->GetFile("Build.log", "$TaskDir/log"))
{
- if (open(my $LogFile, "<", "$TaskDir/log"))
+ my $Result = ParseTaskLog("$TaskDir/log", "Build");
+ if ($Result eq "ok")
{
- # Collect and analyze the 'Build:' status line(s)
- $ErrMessage ||= "";
- foreach my $Line (<$LogFile>)
- {
- chomp($Line);
- next if ($Line !~ /^Build: (.*)$/);
- if ($1 eq "ok")
- {
- # We must have gotten the full log and the build did succeed.
- # So forget any prior error.
- $NewStatus = "completed";
- $TAError = $ErrMessage = undef;
- }
- else
- {
- $NewStatus = ($1 eq "Patch failed to apply") ? "badpatch" : "badbuild";
- # Collect all the build errors (32 bit, 64 bit, etc)
- $ErrMessage .= "$1\n";
- }
- }
- close($LogFile);
-
- if (!defined $NewStatus)
- {
- $NewStatus = "badbuild";
- $ErrMessage = "Missing build status line\n";
- }
+ # We must have gotten the full log and the build did succeed.
+ # So forget any prior error.
+ $NewStatus = "completed";
+ $TAError = $ErrMessage = undef;
+ }
+ elsif ($Result eq "badpatch")
+ {
+ # This too is conclusive enough to ignore other errors.
+ $NewStatus = "badpatch";
+ $TAError = $ErrMessage = undef;
+ }
+ elsif ($Result =~ s/^nolog://)
+ {
+ FatalError("$Result\n", "retry");
}
else
{
- FatalError("Unable to open the build log for reading: $!\n", "retry");
+ # If the result line is missing we probably already have an error message
+ # that explains why.
+ $NewStatus = "badbuild";
}
}
elsif (!defined $TAError)
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index d04b78061..2950799d5 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -45,6 +45,7 @@ use WineTestBot::Config;
use WineTestBot::Jobs;
use WineTestBot::VMs;
use WineTestBot::Log;
+use WineTestBot::LogUtils;
use WineTestBot::Engine::Notify;
@@ -373,45 +374,23 @@ if (!defined $TA->Wait($Pid, $Task->Timeout, 60))
Debug(Elapsed($Start), " Retrieving 'Reconfig.log'\n");
if ($TA->GetFile("Reconfig.log", "$TaskDir/log"))
{
- if (open(my $LogFile, "<", "$TaskDir/log"))
+ my $Result = ParseTaskLog("$TaskDir/log", "Reconfig");
+ if ($Result eq "ok")
{
- # Collect and analyze the 'Reconfig:' status line(s).
- my $LogErrors;
- foreach my $Line (<$LogFile>)
- {
- chomp($Line);
- next if ($Line !~ /^Reconfig: (.*)$/);
- # Add the error message or an empty string for 'ok'
- $LogErrors = ($LogErrors || "") . ($1 ne "ok" ? "$1\n" : "");
- }
- close($LogFile);
-
- if (!defined $LogErrors)
- {
- if (!defined $ErrMessage)
- {
- $NewStatus = "badbuild";
- $ErrMessage = "Missing reconfig status line\n";
- }
- # otherwise $ErrMessage probably already explains why the reconfig
- # status line is missing
- }
- elsif ($LogErrors eq "")
- {
- # We must have gotten the full log and the build did succeed.
- # So forget any prior error.
- $NewStatus = "completed";
- $TAError = $ErrMessage = undef;
- }
- else
- {
- $NewStatus = "badbuild";
- $ErrMessage = $LogErrors . ($ErrMessage || "");
- }
+ # We must have gotten the full log and the build did succeed.
+ # So forget any prior error.
+ $NewStatus = "completed";
+ $TAError = $ErrMessage = undef;
+ }
+ elsif ($Result =~ s/^nolog://)
+ {
+ FatalError("$Result\n", "retry");
}
else
{
- FatalError("Unable to open the build log for reading: $!\n");
+ # We should not have badpatch errors and if the result line is missing we
+ # probably already have an error message that explains why.
+ $NewStatus = "badbuild";
}
}
elsif (!defined $TAError)
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
new file mode 100644
index 000000000..3e40fbc35
--- /dev/null
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -0,0 +1,77 @@
+# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
+# Copyright 2018 Francois Gouget
+#
+# 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
+
+use strict;
+
+package WineTestBot::LogUtils;
+
+=head1 NAME
+
+WineTestBot::LogUtils - Provides functions to parse task logs
+
+=cut
+
+
+use Exporter 'import';
+our @EXPORT = qw(ParseTaskLog);
+
+
+#
+# Task log parser
+#
+
+=pod
+=over 12
+
+=item C<ParseTaskLog()>
+
+Returns ok if the task was successful and an error code otherwise.
+
+=back
+=cut
+
+sub ParseTaskLog($$)
+{
+ my ($FileName, $ResultPrefix) = @_;
+
+ if (open(my $LogFile, "<", $FileName))
+ {
+ my $Result;
+ foreach my $Line (<$LogFile>)
+ {
+ chomp $Line;
+ if ($Line =~ /^$ResultPrefix: ok$/)
+ {
+ $Result ||= "ok";
+ }
+ elsif ($Line =~ /^$ResultPrefix: Patch failed to apply$/)
+ {
+ $Result = "badpatch";
+ last; # Should be the last and most specific message
+ }
+ elsif ($Line =~ /^$ResultPrefix: /)
+ {
+ $Result = "failed";
+ }
+ }
+ close($LogFile);
+ return $Result || "missing";
+ }
+ return "nolog:Unable to open the task log for reading: $!";
+}
+
+1;
--
2.17.1
June 21, 2018
[PATCH] testbot: VMs::FilterHypervisors() is not used anymore so remove it.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/VMs.pm | 7 -------
1 file changed, 7 deletions(-)
diff --git a/testbot/lib/WineTestBot/VMs.pm b/testbot/lib/WineTestBot/VMs.pm
index a29eebbba..2f494cb81 100644
--- a/testbot/lib/WineTestBot/VMs.pm
+++ b/testbot/lib/WineTestBot/VMs.pm
@@ -730,11 +730,4 @@ sub FilterEnabledStatus($)
$self->AddFilter("Status", ["dirty", "reverting", "sleeping", "idle", "running", "off", "offline"]);
}
-sub FilterHypervisors($$)
-{
- my ($self, $Hypervisors) = @_;
-
- $self->AddFilter("VirtURI", $Hypervisors);
-}
-
1;
--
2.17.1
June 21, 2018
[PATCH] testbot/web: Detect and highlight some more Git errors.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/JobDetails.pl | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 8cc354e84..410d18691 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -253,9 +253,12 @@ sub GetHtmlLine($$$)
$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 =~ /^error: patch failed:/ or
$Line =~ /^Makefile:[0-9]+: recipe for target .* failed$/ or
$Line =~ /^(?:Build|Reconfig|Task): (?!ok)/ or
# Typical perl errors
--
2.17.1
June 21, 2018
[PATCH 2/2] testbot/web: Prettify the log / error separator.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/JobDetails.pl | 7 ++++++-
testbot/web/WineTestBot.css | 14 ++++++++++++++
2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 1536e87cd..8cc354e84 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -495,7 +495,12 @@ sub GenerateBody($)
chomp $Line;
if ($ErrFirst)
{
- print "<hr>\n" if (!$LogFirst);
+ if (!$LogFirst)
+ {
+ print "<div class='HrTitle'>".
+ ($ErrName eq "err" ? "Other errors" : "Old errors") .
+ "<div class='HrLine'></div></div>\n";
+ }
print "<pre><code>";
$ErrFirst = 0;
}
diff --git a/testbot/web/WineTestBot.css b/testbot/web/WineTestBot.css
index 28ac1b1c2..593c38f44 100644
--- a/testbot/web/WineTestBot.css
+++ b/testbot/web/WineTestBot.css
@@ -317,6 +317,20 @@ h2
padding-bottom: 0.1em;
}
+.HrTitle {
+ margin-top: 0.5em;
+ display: flex;
+ align-items: center;
+ color: #a50d0d;
+}
+
+.HrLine {
+ border-top: 1px solid grey;
+ flex-grow: 1;
+ margin: 0 10px;
+ border-color: #a50d0d;
+}
+
details
{
font-style: italic;
--
2.17.1
June 21, 2018
[PATCH 1/2] testbot/web: Better present the logs and task errors.
by Francois Gouget
Add a horizontal ruler so the log / test report is always clearly
separated from the task error messages.
Avoid duplicating the code that shows the task errors.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/JobDetails.pl | 152 +++++++++++++++++---------------------
1 file changed, 67 insertions(+), 85 deletions(-)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 3add52b4c..1536e87cd 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -408,127 +408,109 @@ sub GenerateBody($)
my $LogName = $MoreInfo->{Full} || $MoreInfo->{Logs}->[0] || "log";
my $ErrName = $LogName eq "log.old" ? "err.old" : "err";
- if (open LOGFILE, "<", "$TaskDir/$LogName")
+ my ($EmptyDiag, $LogFirst);
+ if (open(my $LogFile, "<", "$TaskDir/$LogName"))
{
- my $HasLogEntries = !1;
- my $First = 1;
+ my $HasLogEntries;
my $CurrentDll = "";
my $PrintedDll = "";
- my $Line;
- while (defined($Line = <LOGFILE>))
+ $LogFirst = 1;
+ foreach my $Line (<$LogFile>)
{
$HasLogEntries = 1;
- chomp($Line);
+ chomp $Line;
if ($Line =~ m/^([^:]+):[^ ]+ start [^ ]+ -\s*$/)
{
$CurrentDll = $1;
}
my ($Highlight, $Plain) = $self->GetHtmlLine($MoreInfo->{Full}, $Line);
- if ($MoreInfo->{Full} || defined $Highlight)
+ next if (!$MoreInfo->{Full} and !defined $Highlight);
+
+ if ($PrintedDll ne $CurrentDll && !$MoreInfo->{Full})
+ {
+ print "</code></pre>" if (!$LogFirst);
+ print "<div class='LogDllName'>$CurrentDll:</div><pre><code>";
+ $PrintedDll = $CurrentDll;
+ $LogFirst = 0;
+ }
+ elsif ($LogFirst)
+ {
+ print "<pre><code>";
+ $LogFirst = 0;
+ }
+ if (!$MoreInfo->{Full} && $Line =~ m/^[^:]+:([^:]*)(?::[0-9a-f]+)? done \(258\)/)
+ {
+ my $Unit = $1 ne "" ? "$1: " : "";
+ print "${Unit}Timeout\n";
+ }
+ else
{
- if ($PrintedDll ne $CurrentDll && !$MoreInfo->{Full})
- {
- if ($First)
- {
- $First = !1;
- }
- else
- {
- print "</code></pre>";
- }
- print "<div class='LogDllName'>$CurrentDll:</div><pre><code>";
- $PrintedDll = $CurrentDll;
- }
- elsif ($First)
- {
- print "<pre><code>";
- $First = !1;
- }
- if (!$MoreInfo->{Full} && $Line =~ m/^[^:]+:([^:]*)(?::[0-9a-f]+)? done \(258\)/)
- {
- my $Unit = $1 ne "" ? "$1: " : "";
- print "${Unit}Timeout\n";
- }
- else
- {
- print(($Highlight || $Plain), "\n");
- }
+ print(($Highlight || $Plain), "\n");
}
}
- close LOGFILE;
+ close($LogFile);
- if (open ERRFILE, "<", "$TaskDir/$ErrName")
+ if (!$LogFirst)
{
- $CurrentDll = "*err*";
- while (defined($Line = <ERRFILE>))
+ print "</code></pre>\n";
+ }
+ elsif ($HasLogEntries)
+ {
+ # Here we know we did not show the full log since it was not empty,
+ # and yet we did not show anything to the user. But don't claim there
+ # is no failure if the error log is not empty.
+ if (-z "$TaskDir/$ErrName")
{
- $HasLogEntries = 1;
- chomp($Line);
- if ($PrintedDll ne $CurrentDll)
- {
- if ($First)
- {
- $First = !1;
- }
- else
- {
- print "</code></pre>\n";
- }
- print "<br><pre><code>";
- $PrintedDll = $CurrentDll;
- }
- print $self->escapeHTML($Line), "\n";
+ print "No ". ($StepTask->Type eq "single" ||
+ $StepTask->Type eq "suite" ? "test" : "build") .
+ " failures found";
+ $LogFirst = 0;
}
- close ERRFILE;
}
-
- if (! $First)
+ elsif ($StepTask->Status eq "canceled")
{
- print "</code></pre>\n";
+ $EmptyDiag = "<p>No log, task was canceled</p>\n";
+ }
+ elsif ($StepTask->Status eq "skipped")
+ {
+ $EmptyDiag = "<p>No log, task skipped</p>\n";
}
else
{
- print $HasLogEntries ? "No " .
- ($StepTask->Type eq "single" ||
- $StepTask->Type eq "suite" ? "test" : "build") .
- " failures found" : "Empty log";
+ print "Empty log";
+ $LogFirst = 0;
}
}
- elsif (open ERRFILE, "<", "$TaskDir/$ErrName")
+ else
+ {
+ print "No log". ($StepTask->Status =~ /^(?:queued|running)$/ ? " yet" : "");
+ $LogFirst = 0;
+ }
+
+ if (open(my $ErrFile, "<", "$TaskDir/$ErrName"))
{
- my $HasErrEntries = !1;
- my $Line;
- while (defined($Line = <ERRFILE>))
+ my $ErrFirst = 1;
+ foreach my $Line (<$ErrFile>)
{
- chomp($Line);
- if (! $HasErrEntries)
+ chomp $Line;
+ if ($ErrFirst)
{
+ print "<hr>\n" if (!$LogFirst);
print "<pre><code>";
- $HasErrEntries = 1;
+ $ErrFirst = 0;
}
print $self->escapeHTML($Line), "\n";
}
- if ($HasErrEntries)
+ close($ErrFile);
+
+ if (!$ErrFirst)
{
print "</code></pre>\n";
}
- else
+ elsif (defined $EmptyDiag)
{
- print "Empty log";
+ print $EmptyDiag;
}
- close ERRFILE;
- }
- elsif ($StepTask->Status eq "canceled")
- {
- print "<p>No log, task was canceled</p>\n";
- }
- elsif ($StepTask->Status eq "skipped")
- {
- print "<p>No log, task skipped</p>\n";
- }
- else
- {
- print "<p>No log available yet</p>\n";
}
}
print "</div>\n";
--
2.17.1
June 21, 2018
Re: [PATCH 2/2] msvcrt/tests: Use the available ARRAY_SIZE() macro
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
June 21, 2018
Re: [PATCH 1/2] msvcrt: Rename a macro to ARRAY_SIZE()
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
June 21, 2018
Re: [PATCH v8 5/9] ntdll: Return BIOS info from NtQuerySystemInformation on Linux
by Alex Henrie
On Wed, Jun 20, 2018 at 11:59 PM Marvin <testbot(a)winehq.org> wrote:
>
> 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=39269
>
> Your paranoid android.
>
>
> === wxppro (32 bit info) ===
> The task timed out
This is an intermittent failure which could not have been caused by
this patch's minor changes to the tests:
https://testbot.winehq.org/JobDetails.pl?Key=39279
-Alex
June 21, 2018
Re: [PATCH 1/2] iphlpapi: Use a standalone buffer in IcmpSendEcho().
by Huw Davies
On Thu, Jun 21, 2018 at 05:51:13PM +0800, Zhiyi Zhang wrote:
>
>
> On Thu 6 21 17:35, Huw Davies wrote:
> > On Fri, Jun 15, 2018 at 12:23:23PM +0800, Zhiyi Zhang wrote:
> >> Fix https://bugs.winehq.org/show_bug.cgi?id=43252
> >>
> >> The old implementation uses user provided buffer to receive
> >> packet data, which is alway not enough, causing data corruptions
> >> or incorrectly timeout.
> >>
> >> Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
> >> ---
> >> dlls/iphlpapi/icmp.c | 38 +++++++++++++++++++++++++++-------
> >> dlls/iphlpapi/tests/iphlpapi.c | 21 +++++++++++++++----
> >> 2 files changed, 47 insertions(+), 12 deletions(-)
> >>
> >> diff --git a/dlls/iphlpapi/icmp.c b/dlls/iphlpapi/icmp.c
> >> index ebc2f2b65c..7c91443598 100644
> >> --- a/dlls/iphlpapi/icmp.c
> >> +++ b/dlls/iphlpapi/icmp.c
> >> @@ -113,6 +113,9 @@ typedef struct {
> >> #define IP_OPTS_DEFAULT 1
> >> #define IP_OPTS_CUSTOM 2
> >>
> >> +#define MAXIPLEN 60
> >> +#define MAXICMPLEN 76
> >
> > Out of interest, how did you get to 76?
> >
>
> That was copied from https://github.com/iputils/iputils/blob/master/ping.c#L76
I guess it's for errors: 8 for the icmp header, 60 for the
original ip header, then 8 for the original icmp header. We probably
don't need all of that, but it doesn't hurt.
Huw.
June 21, 2018
Re: [PATCH 1/2] iphlpapi: Use a standalone buffer in IcmpSendEcho().
by Zhiyi Zhang
On Thu 6 21 17:35, Huw Davies wrote:
> On Fri, Jun 15, 2018 at 12:23:23PM +0800, Zhiyi Zhang wrote:
>> Fix https://bugs.winehq.org/show_bug.cgi?id=43252
>>
>> The old implementation uses user provided buffer to receive
>> packet data, which is alway not enough, causing data corruptions
>> or incorrectly timeout.
>>
>> Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
>> ---
>> dlls/iphlpapi/icmp.c | 38 +++++++++++++++++++++++++++-------
>> dlls/iphlpapi/tests/iphlpapi.c | 21 +++++++++++++++----
>> 2 files changed, 47 insertions(+), 12 deletions(-)
>>
>> diff --git a/dlls/iphlpapi/icmp.c b/dlls/iphlpapi/icmp.c
>> index ebc2f2b65c..7c91443598 100644
>> --- a/dlls/iphlpapi/icmp.c
>> +++ b/dlls/iphlpapi/icmp.c
>> @@ -113,6 +113,9 @@ typedef struct {
>> #define IP_OPTS_DEFAULT 1
>> #define IP_OPTS_CUSTOM 2
>>
>> +#define MAXIPLEN 60
>> +#define MAXICMPLEN 76
>
> Out of interest, how did you get to 76?
>
That was copied from https://github.com/iputils/iputils/blob/master/ping.c#L76
>> +
>> /* The sequence number is unique process wide, so that all threads
>> * have a distinct sequence number.
>> */
>> @@ -270,13 +273,14 @@ DWORD WINAPI IcmpSendEcho(
>> icmp_t* icp=(icmp_t*)IcmpHandle;
>> unsigned char* reqbuf;
>> int reqsize;
>> + unsigned char* repbuf;
>> + int repsize;
>>
>> struct icmp_echo_reply* ier;
>> struct ip* ip_header;
>> struct icmp* icmp_header;
>> char* endbuf;
>> int ip_header_len;
>> - int maxlen;
>> struct pollfd fdr;
>> DWORD send_time,recv_time;
>> struct sockaddr_in addr;
>> @@ -312,6 +316,16 @@ DWORD WINAPI IcmpSendEcho(
>> return 0;
>> }
>>
>> + /* max ip header + max icmp header and error data + reply size(max 65535 on Windows) */
>> + /* FIXME: request size of 65535 is not supported yet because max buffer size of raw socket on linux is 32767 */
>> + repsize=MAXIPLEN+MAXICMPLEN+(ReplySize&0xFFFF);
>> + repbuf=HeapAlloc(GetProcessHeap(), 0, repsize);
>> + if (reqbuf==NULL) {
>
> This should be repbuf.
>
>> + HeapFree(GetProcessHeap(), 0, reqbuf);
>> + SetLastError(ERROR_OUTOFMEMORY);
>> + return 0;
>> + }
>> +
>> icmp_header=(struct icmp*)reqbuf;
>> icmp_header->icmp_type=ICMP_ECHO;
>> icmp_header->icmp_code=0;
>> @@ -367,9 +381,7 @@ DWORD WINAPI IcmpSendEcho(
>> fdr.events = POLLIN;
>> addrlen=sizeof(addr);
>> ier=ReplyBuffer;
>> - ip_header=(struct ip *) ((char *) ReplyBuffer+sizeof(ICMP_ECHO_REPLY));
>> endbuf=(char *) ReplyBuffer+ReplySize;
>> - maxlen=ReplySize-sizeof(ICMP_ECHO_REPLY);
>>
>> /* Send the packet */
>> TRACE("Sending %d bytes (RequestSize=%d) to %s\n", reqsize, RequestSize, inet_ntoa(addr.sin_addr));
>> @@ -407,10 +419,11 @@ DWORD WINAPI IcmpSendEcho(
>> }
>>
>> /* Get the reply */
>> + ip_header=(struct ip*)repbuf;
>> ip_header_len=0; /* because gcc was complaining */
>> while (poll(&fdr,1,Timeout)>0) {
>> recv_time = GetTickCount();
>> - res=recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,&addrlen);
>> + res=recvfrom(icp->sid, (char*)repbuf, repsize, 0, (struct sockaddr*)&addr, &addrlen);
>> TRACE("received %d bytes from %s\n",res, inet_ntoa(addr.sin_addr));
>> ier->Status=IP_REQ_TIMED_OUT;
>>
>> @@ -508,6 +521,12 @@ DWORD WINAPI IcmpSendEcho(
>> else Timeout = 0;
>> continue;
>> } else {
>> + /* Check free space, should be large enough for an ICMP_ECHO_REPLY and remainning icmp data */
>> + if (endbuf-(char *)ier < sizeof(struct icmp_echo_reply)+(res-ip_header_len-ICMP_MINLEN)) {
>> + res=ier-(ICMP_ECHO_REPLY *)ReplyBuffer;
>> + SetLastError(IP_GENERAL_FAILURE);
>> + goto done;
>> + }
>> /* This is a reply to our packet */
>> memcpy(&ier->Address,&ip_header->ip_src,sizeof(IPAddr));
>> /* Status is already set */
>> @@ -515,7 +534,7 @@ DWORD WINAPI IcmpSendEcho(
>> ier->DataSize=res-ip_header_len-ICMP_MINLEN;
>> ier->Reserved=0;
>> ier->Data=endbuf-ier->DataSize;
>> - memmove(ier->Data,((char*)ip_header)+ip_header_len+ICMP_MINLEN,ier->DataSize);
>> + memcpy(ier->Data, ((char *)ip_header)+ip_header_len+ICMP_MINLEN, ier->DataSize);
>> ier->Options.Ttl=ip_header->ip_ttl;
>> ier->Options.Tos=ip_header->ip_tos;
>> ier->Options.Flags=ip_header->ip_off >> 13;
>> @@ -523,7 +542,7 @@ DWORD WINAPI IcmpSendEcho(
>> if (ier->Options.OptionsSize!=0) {
>> ier->Options.OptionsData=(unsigned char *) ier->Data-ier->Options.OptionsSize;
>> /* FIXME: We are supposed to rearrange the option's 'source route' data */
>> - memmove(ier->Options.OptionsData,((char*)ip_header)+ip_header_len,ier->Options.OptionsSize);
>> + memcpy(ier->Options.OptionsData, ((char *)ip_header)+ip_header_len, ier->Options.OptionsSize);
>> endbuf=(char*)ier->Options.OptionsData;
>> } else {
>> ier->Options.OptionsData=NULL;
>> @@ -531,9 +550,8 @@ DWORD WINAPI IcmpSendEcho(
>> }
>>
>> /* Prepare for the next packet */
>> + endbuf-=ier->DataSize;
>> ier++;
>> - ip_header=(struct ip*)(((char*)ip_header)+sizeof(ICMP_ECHO_REPLY));
>> - maxlen=endbuf-(char*)ip_header;
>>
>> /* Check out whether there is more but don't wait this time */
>> Timeout=0;
>> @@ -542,6 +560,10 @@ DWORD WINAPI IcmpSendEcho(
>> res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer;
>> if (res==0)
>> SetLastError(IP_REQ_TIMED_OUT);
>> + else
>> + SetLastError(NO_ERROR);
>
> This hunk looks like a separate change so should be a separate patch.
> Note, in general setting last error to NO_ERROR looks wrong, though it may
> be needed in this case.
>
> Huw.
>
June 21, 2018
[PATCH 2/2] vulkan-1/tests: Add tests.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
configure | 1 +
configure.ac | 1 +
dlls/vulkan-1/Makefile.in | 1 +
dlls/vulkan-1/tests/Makefile.in | 5 +++
dlls/vulkan-1/tests/vulkan.c | 92 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 100 insertions(+)
create mode 100644 dlls/vulkan-1/tests/Makefile.in
create mode 100644 dlls/vulkan-1/tests/vulkan.c
diff --git a/configure b/configure
index bcb660d56982..ddd6db152cc9 100755
--- a/configure
+++ b/configure
@@ -19222,6 +19222,7 @@ wine_fn_config_makefile dlls/vnetbios.vxd enable_win16
wine_fn_config_makefile dlls/vssapi enable_vssapi
wine_fn_config_makefile dlls/vtdapi.vxd enable_win16
wine_fn_config_makefile dlls/vulkan-1 enable_vulkan_1
+wine_fn_config_makefile dlls/vulkan-1/tests enable_tests
wine_fn_config_makefile dlls/vwin32.vxd enable_win16
wine_fn_config_makefile dlls/w32skrnl enable_win16
wine_fn_config_makefile dlls/w32sys.dll16 enable_win16
diff --git a/configure.ac b/configure.ac
index 469fa8d72977..68f7f146ca1f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3721,6 +3721,7 @@ WINE_CONFIG_MAKEFILE(dlls/vnetbios.vxd,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/vssapi)
WINE_CONFIG_MAKEFILE(dlls/vtdapi.vxd,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/vulkan-1)
+WINE_CONFIG_MAKEFILE(dlls/vulkan-1/tests)
WINE_CONFIG_MAKEFILE(dlls/vwin32.vxd,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/w32skrnl,enable_win16)
WINE_CONFIG_MAKEFILE(dlls/w32sys.dll16,enable_win16)
diff --git a/dlls/vulkan-1/Makefile.in b/dlls/vulkan-1/Makefile.in
index 4bb8cec41287..2abc54df0e41 100644
--- a/dlls/vulkan-1/Makefile.in
+++ b/dlls/vulkan-1/Makefile.in
@@ -1,5 +1,6 @@
MODULE = vulkan-1.dll
IMPORTS = winevulkan
+IMPORTLIB = vulkan-1
C_SRCS = \
vulkan.c
diff --git a/dlls/vulkan-1/tests/Makefile.in b/dlls/vulkan-1/tests/Makefile.in
new file mode 100644
index 000000000000..c9f9f0727c80
--- /dev/null
+++ b/dlls/vulkan-1/tests/Makefile.in
@@ -0,0 +1,5 @@
+TESTDLL = vulkan-1.dll
+IMPORTS = vulkan-1
+
+C_SRCS = \
+ vulkan.c
diff --git a/dlls/vulkan-1/tests/vulkan.c b/dlls/vulkan-1/tests/vulkan.c
new file mode 100644
index 000000000000..67da880fe470
--- /dev/null
+++ b/dlls/vulkan-1/tests/vulkan.c
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2018 Józef Kucia for CodeWeavers
+ *
+ * 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 "windows.h"
+#include "wine/heap.h"
+#include "wine/vulkan.h"
+#include "wine/test.h"
+
+static VkResult create_instance(uint32_t extension_count,
+ const char * const *enabled_extensions, VkInstance *vk_instance)
+{
+ VkInstanceCreateInfo create_info;
+
+ create_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
+ create_info.pNext = NULL;
+ create_info.flags = 0;
+ create_info.pApplicationInfo = NULL;
+ create_info.enabledLayerCount = 0;
+ create_info.ppEnabledLayerNames = NULL;
+ create_info.enabledExtensionCount = extension_count;
+ create_info.ppEnabledExtensionNames = enabled_extensions;
+
+ return vkCreateInstance(&create_info, NULL, vk_instance);
+}
+
+static void test_enumerate_physical_devices(void)
+{
+ VkPhysicalDevice *vk_physical_devices;
+ VkPhysicalDeviceProperties properties;
+ VkInstance vk_instance;
+ unsigned int i;
+ uint32_t count;
+ VkResult vr;
+
+ if ((vr = create_instance(0, NULL, &vk_instance)) < 0)
+ {
+ skip("Failed to create Vulkan instance, vr %d.\n", vr);
+ return;
+ }
+ ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
+
+ vr = vkEnumeratePhysicalDevices(vk_instance, &count, NULL);
+ ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
+ if (!count)
+ {
+ skip("No physical devices.\n");
+ vkDestroyInstance(vk_instance, NULL);
+ return;
+ }
+
+ trace("Got %u physical device(s).\n", count);
+ vk_physical_devices = heap_calloc(count, sizeof(*vk_physical_devices));
+ ok(!!vk_physical_devices, "Failed to allocate memory.\n");
+ vr = vkEnumeratePhysicalDevices(vk_instance, &count, vk_physical_devices);
+ ok(vr == VK_SUCCESS, "Got unexpected VkResult %d.\n", vr);
+
+ for (i = 0; i < count; ++i)
+ {
+ vkGetPhysicalDeviceProperties(vk_physical_devices[i], &properties);
+
+ trace("Device '%s', %#x:%#x, driver version %u.%u.%u (%#x), api version %u.%u.%u.\n",
+ properties.deviceName, properties.vendorID, properties.deviceID,
+ VK_VERSION_MAJOR(properties.driverVersion), VK_VERSION_MINOR(properties.driverVersion),
+ VK_VERSION_PATCH(properties.driverVersion), properties.driverVersion,
+ VK_VERSION_MAJOR(properties.apiVersion), VK_VERSION_MINOR(properties.apiVersion),
+ VK_VERSION_PATCH(properties.apiVersion));
+ }
+
+ heap_free(vk_physical_devices);
+
+ vkDestroyInstance(vk_instance, NULL);
+}
+
+START_TEST(vulkan)
+{
+ test_enumerate_physical_devices();
+}
--
2.16.4
June 21, 2018
[PATCH 1/2] wrc: Accept hyphens in identificators.
by Józef Kucia
It is a bit more permissive than it should be, hyphens should be allowed
in resource names, but not in filenames.
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
I need it to add tests for vulkan-1. I would like to add some tests for
structure conversion bugs.
---
tools/wrc/parser.l | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/wrc/parser.l b/tools/wrc/parser.l
index 32a231b5a2ea..0f46670288ce 100644
--- a/tools/wrc/parser.l
+++ b/tools/wrc/parser.l
@@ -402,7 +402,7 @@ static unsigned long xstrtoul(const char *nptr, char **endptr, int base)
0[oO][0-7]+[lL]? { parser_lval.num = xstrtoul(yytext+2, 0, 8);
return (yytext[yyleng-1] == 'L' || yytext[yyleng-1] == 'l') ? tLNUMBER : tNUMBER; }
-[A-Za-z_0-9./\\]+ {
+[A-Za-z_0-9./\\][A-Za-z_0-9./\\\-]* {
struct keyword *tok = iskeyword(yytext);
if(tok)
--
2.16.4
June 21, 2018
Re: [PATCH 1/2] iphlpapi: Use a standalone buffer in IcmpSendEcho().
by Huw Davies
On Fri, Jun 15, 2018 at 12:23:23PM +0800, Zhiyi Zhang wrote:
> Fix https://bugs.winehq.org/show_bug.cgi?id=43252
>
> The old implementation uses user provided buffer to receive
> packet data, which is alway not enough, causing data corruptions
> or incorrectly timeout.
>
> Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
> ---
> dlls/iphlpapi/icmp.c | 38 +++++++++++++++++++++++++++-------
> dlls/iphlpapi/tests/iphlpapi.c | 21 +++++++++++++++----
> 2 files changed, 47 insertions(+), 12 deletions(-)
>
> diff --git a/dlls/iphlpapi/icmp.c b/dlls/iphlpapi/icmp.c
> index ebc2f2b65c..7c91443598 100644
> --- a/dlls/iphlpapi/icmp.c
> +++ b/dlls/iphlpapi/icmp.c
> @@ -113,6 +113,9 @@ typedef struct {
> #define IP_OPTS_DEFAULT 1
> #define IP_OPTS_CUSTOM 2
>
> +#define MAXIPLEN 60
> +#define MAXICMPLEN 76
Out of interest, how did you get to 76?
> +
> /* The sequence number is unique process wide, so that all threads
> * have a distinct sequence number.
> */
> @@ -270,13 +273,14 @@ DWORD WINAPI IcmpSendEcho(
> icmp_t* icp=(icmp_t*)IcmpHandle;
> unsigned char* reqbuf;
> int reqsize;
> + unsigned char* repbuf;
> + int repsize;
>
> struct icmp_echo_reply* ier;
> struct ip* ip_header;
> struct icmp* icmp_header;
> char* endbuf;
> int ip_header_len;
> - int maxlen;
> struct pollfd fdr;
> DWORD send_time,recv_time;
> struct sockaddr_in addr;
> @@ -312,6 +316,16 @@ DWORD WINAPI IcmpSendEcho(
> return 0;
> }
>
> + /* max ip header + max icmp header and error data + reply size(max 65535 on Windows) */
> + /* FIXME: request size of 65535 is not supported yet because max buffer size of raw socket on linux is 32767 */
> + repsize=MAXIPLEN+MAXICMPLEN+(ReplySize&0xFFFF);
> + repbuf=HeapAlloc(GetProcessHeap(), 0, repsize);
> + if (reqbuf==NULL) {
This should be repbuf.
> + HeapFree(GetProcessHeap(), 0, reqbuf);
> + SetLastError(ERROR_OUTOFMEMORY);
> + return 0;
> + }
> +
> icmp_header=(struct icmp*)reqbuf;
> icmp_header->icmp_type=ICMP_ECHO;
> icmp_header->icmp_code=0;
> @@ -367,9 +381,7 @@ DWORD WINAPI IcmpSendEcho(
> fdr.events = POLLIN;
> addrlen=sizeof(addr);
> ier=ReplyBuffer;
> - ip_header=(struct ip *) ((char *) ReplyBuffer+sizeof(ICMP_ECHO_REPLY));
> endbuf=(char *) ReplyBuffer+ReplySize;
> - maxlen=ReplySize-sizeof(ICMP_ECHO_REPLY);
>
> /* Send the packet */
> TRACE("Sending %d bytes (RequestSize=%d) to %s\n", reqsize, RequestSize, inet_ntoa(addr.sin_addr));
> @@ -407,10 +419,11 @@ DWORD WINAPI IcmpSendEcho(
> }
>
> /* Get the reply */
> + ip_header=(struct ip*)repbuf;
> ip_header_len=0; /* because gcc was complaining */
> while (poll(&fdr,1,Timeout)>0) {
> recv_time = GetTickCount();
> - res=recvfrom(icp->sid, (char*)ip_header, maxlen, 0, (struct sockaddr*)&addr,&addrlen);
> + res=recvfrom(icp->sid, (char*)repbuf, repsize, 0, (struct sockaddr*)&addr, &addrlen);
> TRACE("received %d bytes from %s\n",res, inet_ntoa(addr.sin_addr));
> ier->Status=IP_REQ_TIMED_OUT;
>
> @@ -508,6 +521,12 @@ DWORD WINAPI IcmpSendEcho(
> else Timeout = 0;
> continue;
> } else {
> + /* Check free space, should be large enough for an ICMP_ECHO_REPLY and remainning icmp data */
> + if (endbuf-(char *)ier < sizeof(struct icmp_echo_reply)+(res-ip_header_len-ICMP_MINLEN)) {
> + res=ier-(ICMP_ECHO_REPLY *)ReplyBuffer;
> + SetLastError(IP_GENERAL_FAILURE);
> + goto done;
> + }
> /* This is a reply to our packet */
> memcpy(&ier->Address,&ip_header->ip_src,sizeof(IPAddr));
> /* Status is already set */
> @@ -515,7 +534,7 @@ DWORD WINAPI IcmpSendEcho(
> ier->DataSize=res-ip_header_len-ICMP_MINLEN;
> ier->Reserved=0;
> ier->Data=endbuf-ier->DataSize;
> - memmove(ier->Data,((char*)ip_header)+ip_header_len+ICMP_MINLEN,ier->DataSize);
> + memcpy(ier->Data, ((char *)ip_header)+ip_header_len+ICMP_MINLEN, ier->DataSize);
> ier->Options.Ttl=ip_header->ip_ttl;
> ier->Options.Tos=ip_header->ip_tos;
> ier->Options.Flags=ip_header->ip_off >> 13;
> @@ -523,7 +542,7 @@ DWORD WINAPI IcmpSendEcho(
> if (ier->Options.OptionsSize!=0) {
> ier->Options.OptionsData=(unsigned char *) ier->Data-ier->Options.OptionsSize;
> /* FIXME: We are supposed to rearrange the option's 'source route' data */
> - memmove(ier->Options.OptionsData,((char*)ip_header)+ip_header_len,ier->Options.OptionsSize);
> + memcpy(ier->Options.OptionsData, ((char *)ip_header)+ip_header_len, ier->Options.OptionsSize);
> endbuf=(char*)ier->Options.OptionsData;
> } else {
> ier->Options.OptionsData=NULL;
> @@ -531,9 +550,8 @@ DWORD WINAPI IcmpSendEcho(
> }
>
> /* Prepare for the next packet */
> + endbuf-=ier->DataSize;
> ier++;
> - ip_header=(struct ip*)(((char*)ip_header)+sizeof(ICMP_ECHO_REPLY));
> - maxlen=endbuf-(char*)ip_header;
>
> /* Check out whether there is more but don't wait this time */
> Timeout=0;
> @@ -542,6 +560,10 @@ DWORD WINAPI IcmpSendEcho(
> res=ier-(ICMP_ECHO_REPLY*)ReplyBuffer;
> if (res==0)
> SetLastError(IP_REQ_TIMED_OUT);
> + else
> + SetLastError(NO_ERROR);
This hunk looks like a separate change so should be a separate patch.
Note, in general setting last error to NO_ERROR looks wrong, though it may
be needed in this case.
Huw.
June 21, 2018
[PATCH] kernel32: Implement K32EnumDeviceDrivers and K32GetDeviceDriverBaseNameA (pt. 2)
by Anthony Lauzon
I noticed my submission yesterday was a little undercooked and since I have
spent some more time on it, I thought I'd try to submit a (hopefully)
proper patch to the list. This is a rough implementation of
K32EnumDeviceDrivers and K32GetDeviceDriverBaseNameA.
June 21, 2018
Re: [PATCH v2] user32: Always release menu item in EnableMenuItem
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 21, 2018
Re: [PATCH] oleaut32: Correct some comments.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
June 21, 2018
Re: [PATCH v8 5/9] ntdll: Return BIOS info from NtQuerySystemInformation on Linux
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=39269
Your paranoid android.
=== wxppro (32 bit info) ===
The task timed out
June 21, 2018
[PATCH] ntdll: Implement LdrRegisterDllNotification and LdrUnregisterDllNotification.
by Alistair Leslie-Hughes
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/ntdll/loader.c | 75 +++++++++++++-
dlls/ntdll/tests/rtl.c | 261 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 332 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 3e00ec6..cae9b25 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -40,6 +40,7 @@
#include "wine/library.h"
#include "wine/unicode.h"
#include "wine/debug.h"
+#include "wine/list.h"
#include "wine/server.h"
#include "ntdll_misc.h"
#include "ddk/wdm.h"
@@ -71,6 +72,13 @@ static BOOL imports_fixup_done = FALSE; /* set once the imports have been fixed
static BOOL process_detaching = FALSE; /* set on process detach to avoid deadlocks with thread detach */
static int free_lib_count; /* recursion depth of LdrUnloadDll calls */
+struct ldr_notification
+{
+ struct list entry;
+ PLDR_DLL_NOTIFICATION_FUNCTION callback;
+ void *context;
+};
+
static const char * const reason_names[] =
{
"PROCESS_DETACH",
@@ -342,6 +350,29 @@ static ULONG_PTR allocate_stub( const char *dll, const char *name )
static inline ULONG_PTR allocate_stub( const char *dll, const char *name ) { return 0xdeadbeef; }
#endif /* __i386__ */
+/* call ldr notifications */
+static void call_ldr_notifications( ULONG reason, LDR_MODULE *module )
+{
+ struct ldr_notification *notify, *notify_next;
+ LDR_DLL_NOTIFICATION_DATA data;
+
+ data.Loaded.Flags = 0;
+ data.Loaded.FullDllName = &module->FullDllName;
+ data.Loaded.BaseDllName = &module->BaseDllName;
+ data.Loaded.DllBase = module->BaseAddress;
+ data.Loaded.SizeOfImage = module->SizeOfImage;
+
+ LIST_FOR_EACH_ENTRY_SAFE( notify, notify_next, &ldr_notifications, struct ldr_notification, entry )
+ {
+ TRACE_(relay)("\1Call LDR notification callback (proc=%p,reason=%u,data=%p,context=%p)\n",
+ notify->callback, reason, &data, notify->context );
+
+ notify->callback(reason, &data, notify->context);
+
+ TRACE_(relay)("\1Ret LDR notification callback (proc=%p,reason=%u,data=%p,context=%p)\n",
+ notify->callback, reason, &data, notify->context );
+ }
+}
/*************************************************************************
* get_modref
@@ -1275,12 +1306,18 @@ static NTSTATUS process_attach( WINE_MODREF *wm, LPVOID lpReserved )
{
WINE_MODREF *prev = current_modref;
current_modref = wm;
+
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_LOADED, &wm->ldr );
status = MODULE_InitDLL( wm, DLL_PROCESS_ATTACH, lpReserved );
if (status == STATUS_SUCCESS)
+ {
wm->ldr.Flags |= LDR_PROCESS_ATTACHED;
+ }
else
{
MODULE_InitDLL( wm, DLL_PROCESS_DETACH, lpReserved );
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_UNLOADED, &wm->ldr );
+
/* point to the name so LdrInitializeThunk can print it */
last_failed_modref = wm;
WARN("Initialization of %s failed\n", debugstr_w(wm->ldr.BaseDllName.Buffer));
@@ -1353,6 +1390,7 @@ static void process_detach(void)
mod->Flags &= ~LDR_PROCESS_ATTACHED;
MODULE_InitDLL( CONTAINING_RECORD(mod, WINE_MODREF, ldr),
DLL_PROCESS_DETACH, ULongToPtr(process_detaching) );
+ call_ldr_notifications( LDR_DLL_NOTIFICATION_REASON_UNLOADED, mod );
/* Restart at head of WINE_MODREF list, as entries might have
been added and/or removed while performing the call ... */
@@ -1467,8 +1505,27 @@ NTSTATUS WINAPI LdrEnumerateLoadedModules( void *unknown, LDRENUMPROC callback,
NTSTATUS WINAPI LdrRegisterDllNotification(ULONG flags, PLDR_DLL_NOTIFICATION_FUNCTION callback,
void *context, void **cookie)
{
- FIXME( "(%04x, %p, %p, %p) stub\n", flags, callback, context, cookie );
- return STATUS_NOT_IMPLEMENTED;
+ struct ldr_notification *notify;
+
+ TRACE( "(%x, %p, %p, %p)\n", flags, callback, context, cookie );
+
+ if (!callback || !cookie)
+ return STATUS_INVALID_PARAMETER;
+
+ if (flags)
+ FIXME( "ignoring flags %x\n", flags );
+
+ notify = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(*notify) );
+ if (!notify) return STATUS_NO_MEMORY;
+ notify->callback = callback;
+ notify->context = context;
+
+ RtlEnterCriticalSection( &loader_section );
+ list_add_tail( &ldr_notifications, ¬ify->entry );
+ RtlLeaveCriticalSection( &loader_section );
+
+ *cookie = notify;
+ return STATUS_SUCCESS;
}
/******************************************************************
@@ -1476,8 +1533,18 @@ NTSTATUS WINAPI LdrRegisterDllNotification(ULONG flags, PLDR_DLL_NOTIFICATION_FU
*/
NTSTATUS WINAPI LdrUnregisterDllNotification( void *cookie )
{
- FIXME( "(%p) stub\n", cookie );
- return STATUS_NOT_IMPLEMENTED;
+ struct ldr_notification *notify = cookie;
+
+ TRACE( "(%p)\n", cookie );
+
+ if (!notify) return STATUS_INVALID_PARAMETER;
+
+ RtlEnterCriticalSection( &loader_section );
+ list_remove( ¬ify->entry );
+ RtlLeaveCriticalSection( &loader_section );
+
+ RtlFreeHeap( GetProcessHeap(), 0, notify );
+ return STATUS_SUCCESS;
}
/******************************************************************
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index 2e3a7de..1a9e313 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -101,6 +101,8 @@ static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, U
static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *);
static NTSTATUS (WINAPI *pRtlMakeSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
static NTSTATUS (WINAPI *pRtlAbsoluteToSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,PULONG);
+static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **);
+static NTSTATUS (WINAPI *pLdrUnregisterDllNotification)(void *);
static HMODULE hkernel32 = 0;
static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
@@ -108,10 +110,15 @@ static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL);
#define LEN 16
static const char* src_src = "This is a test!"; /* 16 bytes long, incl NUL */
+static WCHAR ws2_32dllW[] = {'w','s','2','_','3','2','.','d','l','l',0};
+static WCHAR nsidllW[] = {'n','s','i','.','d','l','l',0};
+static WCHAR wintrustdllW[] = {'w','i','n','t','r','u','s','t','.','d','l','l',0};
+static WCHAR crypt32dllW[] = {'c','r','y','p','t','3','2','.','d','l','l',0};
static ULONG src_aligned_block[4];
static ULONG dest_aligned_block[32];
static const char *src = (const char*)src_aligned_block;
static char* dest = (char*)dest_aligned_block;
+const WCHAR *expected_dll = nsidllW;
static void InitFunctionPtrs(void)
{
@@ -157,6 +164,8 @@ static void InitFunctionPtrs(void)
pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules");
pRtlMakeSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlMakeSelfRelativeSD");
pRtlAbsoluteToSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlAbsoluteToSelfRelativeSD");
+ pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification");
+ pLdrUnregisterDllNotification = (void *)GetProcAddress(hntdll, "LdrUnregisterDllNotification");
}
hkernel32 = LoadLibraryA("kernel32.dll");
ok(hkernel32 != 0, "LoadLibrary failed\n");
@@ -2259,6 +2268,257 @@ static void test_RtlMakeSelfRelativeSD(void)
ok( status == STATUS_BAD_DESCRIPTOR_FORMAT, "got %08x\n", status );
}
+static DWORD (CALLBACK *orig_entry)(HMODULE,DWORD,LPVOID);
+static DWORD *dll_main_data;
+
+static inline void *get_rva( HMODULE module, DWORD va )
+{
+ return (void *)((char *)module + va);
+}
+
+static void CALLBACK ldr_notify_callback1(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ const IMAGE_IMPORT_DESCRIPTOR *imports;
+ const IMAGE_THUNK_DATA *import_list;
+ IMAGE_THUNK_DATA *thunk_list;
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+ ULONG size;
+ int i, j;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, expected_dll))
+ return;
+
+ ok(data->Loaded.Flags == 0, "Expected flags 0, got %x\n", data->Loaded.Flags);
+ ok(!lstrcmpiW(data->Loaded.BaseDllName->Buffer, expected_dll), "Expected %s, got %s\n",
+ wine_dbgstr_w(expected_dll), wine_dbgstr_w(data->Loaded.BaseDllName->Buffer));
+ ok(!!data->Loaded.DllBase, "Expected non zero base address\n");
+ ok(data->Loaded.SizeOfImage, "Expected non zero image size\n");
+
+ /* expect module to be last module listed in LdrData load order list */
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ ok(!lstrcmpiW(mod->BaseDllName.Buffer, expected_dll), "Expected %s, got %s\n",
+ wine_dbgstr_w(expected_dll), wine_dbgstr_w(mod->BaseDllName.Buffer));
+
+ /* show that imports have already been resolved */
+ imports = RtlImageDirectoryEntryToData(data->Loaded.DllBase, TRUE, IMAGE_DIRECTORY_ENTRY_IMPORT, &size);
+ ok(!!imports, "Expected dll to have imports\n");
+
+ for (i = 0; imports[i].Name; i++)
+ {
+ thunk_list = get_rva(data->Loaded.DllBase, (DWORD)imports[i].FirstThunk);
+ if (imports[i].OriginalFirstThunk)
+ import_list = get_rva(data->Loaded.DllBase, (DWORD)imports[i].OriginalFirstThunk);
+ else
+ import_list = thunk_list;
+
+ for (j = 0; import_list[j].u1.Ordinal; j++)
+ {
+ ok(thunk_list[j].u1.AddressOfData > data->Loaded.SizeOfImage,
+ "Import has not been resolved: %p\n", (void*)thunk_list[j].u1.Function);
+ }
+ }
+}
+
+static void CALLBACK ldr_notify_callback2(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ *calls <<= 4;
+ *calls |= reason + 2;
+}
+
+static BOOL WINAPI fake_dll_main(HINSTANCE instance, DWORD reason, void* reserved)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 3;
+ }
+ else if (reason == DLL_PROCESS_DETACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 4;
+ }
+ return orig_entry(instance, reason, reserved);
+}
+
+static void CALLBACK ldr_notify_callback_dll_main(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ if (mod->BaseAddress != data->Loaded.DllBase)
+ return;
+
+ orig_entry = mod->EntryPoint;
+ mod->EntryPoint = fake_dll_main;
+ dll_main_data = calls;
+}
+
+static BOOL WINAPI fake_dll_main_fail(HINSTANCE instance, DWORD reason, void* reserved)
+{
+ if (reason == DLL_PROCESS_ATTACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 3;
+ }
+ else if (reason == DLL_PROCESS_DETACH)
+ {
+ *dll_main_data <<= 4;
+ *dll_main_data |= 4;
+ }
+ return FALSE;
+}
+
+static void CALLBACK ldr_notify_callback_fail(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+ LIST_ENTRY *mark;
+ LDR_MODULE *mod;
+
+ *calls <<= 4;
+ *calls |= reason;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ mark = &NtCurrentTeb()->Peb->LdrData->InMemoryOrderModuleList;
+ mod = CONTAINING_RECORD(mark->Blink, LDR_MODULE, InMemoryOrderModuleList);
+ ok(mod->BaseAddress == data->Loaded.DllBase, "Expected base address %p, got %p\n",
+ data->Loaded.DllBase, mod->BaseAddress);
+ if (mod->BaseAddress != data->Loaded.DllBase)
+ return;
+
+ orig_entry = mod->EntryPoint;
+ mod->EntryPoint = fake_dll_main_fail;
+ dll_main_data = calls;
+}
+
+static void CALLBACK ldr_notify_callback_imports(ULONG reason, LDR_DLL_NOTIFICATION_DATA *data, void *context)
+{
+ DWORD *calls = context;
+
+ if (reason != LDR_DLL_NOTIFICATION_REASON_LOADED)
+ return;
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, crypt32dllW))
+ {
+ *calls <<= 4;
+ *calls |= 1;
+ }
+
+ if (!lstrcmpiW(data->Loaded.BaseDllName->Buffer, wintrustdllW))
+ {
+ *calls <<= 4;
+ *calls |= 2;
+ }
+}
+
+static void test_LdrRegisterDllNotification(void)
+{
+ void *cookie, *cookie2;
+ NTSTATUS status;
+ HMODULE mod;
+ DWORD calls;
+
+ if (!pLdrRegisterDllNotification || !pLdrUnregisterDllNotification)
+ {
+ win_skip("Ldr(Un)RegisterDllNotification not available\n");
+ return;
+ }
+
+ mod = LoadLibraryW(expected_dll);
+ if(mod)
+ FreeLibrary(mod);
+ else
+ expected_dll = ws2_32dllW; /* XP Default */
+
+ /* generic test */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback1, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == LDR_DLL_NOTIFICATION_REASON_LOADED, "Expected LDR_DLL_NOTIFICATION_REASON_LOADED, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == LDR_DLL_NOTIFICATION_REASON_UNLOADED, "Expected LDR_DLL_NOTIFICATION_REASON_UNLOADED, got %x\n", calls);
+
+ /* test order of callbacks */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback2, &calls, &cookie2);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x13, "Expected order 0x13, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == 0x24, "Expected order 0x24, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie2);
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll main order */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_dll_main, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x13, "Expected order 0x13, got %x\n", calls);
+
+ calls = 0;
+ FreeLibrary(mod);
+ ok(calls == 0x42, "Expected order 0x42, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll main order */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_fail, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(expected_dll);
+ ok(!mod, "Expected library to fail loading\n");
+ ok(calls == 0x1342, "Expected order 0x1342, got %x\n", calls);
+
+ pLdrUnregisterDllNotification(cookie);
+
+ /* test dll with dependencies */
+ status = pLdrRegisterDllNotification(0, ldr_notify_callback_imports, &calls, &cookie);
+ ok(!status, "Expected STATUS_SUCCESS, got %08x\n", status);
+
+ calls = 0;
+ mod = LoadLibraryW(wintrustdllW);
+ ok(!!mod, "Failed to load library: %d\n", GetLastError());
+ ok(calls == 0x12 || calls == 0x21, "got %x\n", calls);
+
+ FreeLibrary(mod);
+ pLdrUnregisterDllNotification(cookie);
+}
+
START_TEST(rtl)
{
InitFunctionPtrs();
@@ -2293,4 +2553,5 @@ START_TEST(rtl)
test_RtlLeaveCriticalSection();
test_LdrEnumerateLoadedModules();
test_RtlMakeSelfRelativeSD();
+ test_LdrRegisterDllNotification();
}
--
1.9.1
June 21, 2018
[PATCH 5/5] ntdll: GetLogicalProcessorInformation report LPT_PC_SMT for SMT cores.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 5712e4cc1b..2ca9cd59b0 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1352,7 +1352,8 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
(*pdata)[i].Relationship = rel;
(*pdata)[i].ProcessorMask = mask;
- /* TODO: set processor core flags */
+ if (rel == RelationProcessorCore)
+ (*pdata)[i].u.ProcessorCore.Flags = count_bits(mask) > 1 ? LTP_PC_SMT : 0;
(*pdata)[i].u.Reserved[0] = 0;
(*pdata)[i].u.Reserved[1] = id;
*len = i+1;
--
2.14.4
June 21, 2018
[PATCH 4/5] ntdll: GetLogicalProcessorInformationEx report LTP_PC_SMT for SMT cores.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 27 +++++++++++++++------------
include/winnt.h | 2 ++
2 files changed, 17 insertions(+), 12 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index b16f320957..5712e4cc1b 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1309,6 +1309,17 @@ static DWORD log_proc_ex_size_plus(DWORD size)
return sizeof(LOGICAL_PROCESSOR_RELATIONSHIP) + sizeof(DWORD) + size;
}
+static DWORD count_bits(ULONG_PTR mask)
+{
+ DWORD count = 0;
+ while (mask > 0)
+ {
+ mask >>= 1;
+ count++;
+ }
+ return count;
+}
+
/* Store package and core information for a logical processor. Parsing of processor
* data may happen in multiple passes; the 'id' parameter is then used to locate
* previously stored data. The type of data stored in 'id' depends on 'rel':
@@ -1377,7 +1388,10 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
dataex->Relationship = rel;
dataex->Size = log_proc_ex_size_plus(sizeof(PROCESSOR_RELATIONSHIP));
- dataex->u.Processor.Flags = 0; /* TODO */
+ if (rel == RelationProcessorCore)
+ dataex->u.Processor.Flags = count_bits(mask) > 1 ? LTP_PC_SMT : 0;
+ else
+ dataex->u.Processor.Flags = 0;
dataex->u.Processor.EfficiencyClass = 0;
dataex->u.Processor.GroupCount = 1;
dataex->u.Processor.GroupMask[0].Mask = mask;
@@ -1520,17 +1534,6 @@ static inline BOOL logical_proc_info_add_group(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
}
#ifdef linux
-static DWORD count_bits(ULONG_PTR mask)
-{
- DWORD count = 0;
- while (mask > 0)
- {
- mask >>= 1;
- count++;
- }
- return count;
-}
-
/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */
static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, DWORD *max_len)
diff --git a/include/winnt.h b/include/winnt.h
index 54bf11dabd..862cc45291 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -5982,6 +5982,8 @@ typedef enum _LOGICAL_PROCESSOR_RELATIONSHIP
RelationAll = 0xffff
} LOGICAL_PROCESSOR_RELATIONSHIP;
+#define LTP_PC_SMT 0x1
+
typedef enum _PROCESSOR_CACHE_TYPE
{
CacheUnified,
--
2.14.4
June 21, 2018
[PATCH v2 3/5] ntdll: Report physical cores once with proper thread mask.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 48 +++++++++++++++++++++++++++++++++++++-----------
1 file changed, 37 insertions(+), 11 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 14e18dc6af..b16f320957 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1322,17 +1322,16 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
if (pdata) {
DWORD i;
- if(rel == RelationProcessorPackage){
- for(i=0; i<*len; i++)
+ for (i=0; i<*len; i++)
+ {
+ if (rel == RelationProcessorPackage && (*pdata)[i].Relationship == rel && (*pdata)[i].u.Reserved[1] == id)
{
- if ((*pdata)[i].Relationship!=rel || (*pdata)[i].u.Reserved[1]!=id)
- continue;
-
(*pdata)[i].ProcessorMask |= mask;
return TRUE;
}
- }else
- i = *len;
+ else if (rel == RelationProcessorCore && (*pdata)[i].Relationship == rel && (*pdata)[i].u.Reserved[1] == id)
+ return TRUE;
+ }
while(*len == *pmax_len)
{
@@ -1358,6 +1357,10 @@ static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
dataex->u.Processor.GroupMask[0].Mask |= mask;
return TRUE;
}
+ else if (rel == RelationProcessorCore && dataex->Relationship == rel && dataex->u.Processor.Reserved[1] == id)
+ {
+ return TRUE;
+ }
ofs += dataex->Size;
}
@@ -1554,6 +1557,9 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(i=beg; i<=end; i++)
{
+ DWORD phys_core = 0;
+ ULONG_PTR thread_mask = 0;
+
if(i > 8*sizeof(ULONG_PTR))
{
FIXME("skipping logical processor %d\n", i);
@@ -1574,15 +1580,35 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
return STATUS_NO_MEMORY;
}
- sprintf(name, core_info, i, "core_id");
+ /* Sysfs enumerates logical cores (and not physical cores), but Windows enumerates
+ * by physical core. Upon enumerating a logical core in sysfs, we register a physical
+ * core and all its logical cores. In order to not report physical cores multiple
+ * times, we pass a unique physical core ID to logical_proc_info_add_by_id and let
+ * that call figure out any duplication.
+ * Obtain a unique physical core ID from the first element of thread_siblings_list.
+ * This list provides logical cores sharing the same physical core. The IDs are based
+ * on kernel cpu core numbering as opposed to a hardware core ID like provided through
+ * 'core_id', so are suitable as a unique ID.
+ */
+ sprintf(name, core_info, i, "thread_siblings_list");
f = fopen(name, "r");
if(f)
{
- fscanf(f, "%u", &r);
+ fscanf(f, "%d%c", &phys_core, &op);
+ fclose(f);
+ }
+ else phys_core = i;
+
+ /* Mask of logical threads sharing same physical core in kernel core numbering. */
+ sprintf(name, core_info, i, "thread_siblings");
+ f = fopen(name, "r");
+ if(f)
+ {
+ fscanf(f, "%lx", &thread_mask);
fclose(f);
}
- else r = i;
- if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, r, (ULONG_PTR)1 << i))
+ else thread_mask = 1<<i;
+ if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, thread_mask))
{
fclose(fcpu_list);
return STATUS_NO_MEMORY;
--
2.14.4
June 21, 2018
[PATCH 2/5] ntdll: store core information by core on apple.
by Roderick Colenbrander
The id parameter can be used for core / package lookup. On Linux
we pass package or core values. On Mac, we use package for both.
Use a core identifier on Mac as well.
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index e6458b98f2..14e18dc6af 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1309,6 +1309,12 @@ static DWORD log_proc_ex_size_plus(DWORD size)
return sizeof(LOGICAL_PROCESSOR_RELATIONSHIP) + sizeof(DWORD) + size;
}
+/* Store package and core information for a logical processor. Parsing of processor
+ * data may happen in multiple passes; the 'id' parameter is then used to locate
+ * previously stored data. The type of data stored in 'id' depends on 'rel':
+ * - RelationProcessorPackage: package id ('CPU socket').
+ * - RelationProcessorCore: physical core number.
+ */
static inline BOOL logical_proc_info_add_by_id(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **pdataex, DWORD *len, DWORD *pmax_len,
LOGICAL_PROCESSOR_RELATIONSHIP rel, DWORD id, ULONG_PTR mask)
@@ -1805,6 +1811,7 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(p = 0; p < pkgs_no; ++p){
for(j = 0; j < cores_per_package && p * cores_per_package + j < cores_no; ++j){
ULONG_PTR mask = 0;
+ DWORD phys_core;
for(k = 0; k < lcpu_per_core; ++k)
mask |= (ULONG_PTR)1 << (j * lcpu_per_core + k);
@@ -1816,7 +1823,8 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
return STATUS_NO_MEMORY;
/* add new core */
- if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, p, mask))
+ phys_core = p * cores_per_package + j;
+ if(!logical_proc_info_add_by_id(data, dataex, &len, max_len, RelationProcessorCore, phys_core, mask))
return STATUS_NO_MEMORY;
for(i = 1; i < 5; ++i){
--
2.14.4
June 21, 2018
[PATCH 1/5] ntdll: Derive number of logical CPU cores from core mask.
by Roderick Colenbrander
Signed-off-by: Roderick Colenbrander <thunderbird2k(a)gmail.com>
---
dlls/ntdll/nt.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index dc0ce04f42..e6458b98f2 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -1511,6 +1511,17 @@ static inline BOOL logical_proc_info_add_group(SYSTEM_LOGICAL_PROCESSOR_INFORMAT
}
#ifdef linux
+static DWORD count_bits(ULONG_PTR mask)
+{
+ DWORD count = 0;
+ while (mask > 0)
+ {
+ mask >>= 1;
+ count++;
+ }
+ return count;
+}
+
/* for 'data', max_len is the array count. for 'dataex', max_len is in bytes */
static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **data,
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX **dataex, DWORD *max_len)
@@ -1643,7 +1654,6 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
for(i=0; i<len; i++){
if((*data)[i].Relationship == RelationProcessorCore){
all_cpus_mask |= (*data)[i].ProcessorMask;
- ++num_cpus;
}
}
}else{
@@ -1651,11 +1661,11 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *infoex = (SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX *)(((char *)*dataex) + i);
if(infoex->Relationship == RelationProcessorCore){
all_cpus_mask |= infoex->u.Processor.GroupMask[0].Mask;
- ++num_cpus;
}
i += infoex->Size;
}
}
+ num_cpus = count_bits(all_cpus_mask);
fnuma_list = fopen("/sys/devices/system/node/online", "r");
if(!fnuma_list)
--
2.14.4
June 21, 2018
[PATCH v2 0/5] ntdll: Improve logical core reporting on Linux and Mac.
by Roderick Colenbrander
Hi,
This is an updated version of the previous patchset with a few improvements
to unify some of the logic better across Linux and Mac.
The overall issue is that on Linux we report each logical core as a physical
core, so on SMT systems we report twice the number of cores. In addition we
don't properly report SMT capabilities.
The main issues are in the Linux sysfs code for parsing the CPU topology.
We use a common helper function (logical_proc_info_add_by_id) among Linux
and Mac. This is were some of the fixes need to be implemented for not
adding cores twice. (We do something similar in logical_proc_info_add_cache
in relation to parsing shared_cpu_map.)
However we use logical_proc_info_add_by_id in an inconsistent manner between
Linux and Mac code. On Linux we use different ID values (core and package),
but on Mac we re-use the package ID. The early patches rectify this and
thanks Andrew Eikum for helping to test this. The later patches fix the
Linux issues and then add proper SMT reporting flags.
Thanks,
Roderick
Roderick Colenbrander (5):
ntdll: Derive number of logical CPU cores from core mask.
ntdll: store core information by core on apple.
ntdll: Report physical cores once with proper thread mask.
ntdll: GetLogicalProcessorInformationEx report LTP_PC_SMT for SMT
cores.
ntdll: GetLogicalProcessorInformation report LPT_PC_SMT for SMT cores.
dlls/ntdll/nt.c | 75 +++++++++++++++++++++++++++++++++++++++++++++------------
include/winnt.h | 2 ++
2 files changed, 61 insertions(+), 16 deletions(-)
--
2.14.4
June 21, 2018
[PATCH v8 9/9] ntdll: Return chassis info from NtQuerySystemInformation on Linux
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/nt.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index e622912d8a..d9fc2e6108 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -108,6 +108,17 @@ struct smbios_board {
BYTE serial;
};
+struct smbios_chassis {
+ BYTE type;
+ BYTE length;
+ WORD handle;
+ BYTE vendor;
+ BYTE shape;
+ BYTE version;
+ BYTE serial;
+ BYTE asset_tag;
+};
+
#include "poppack.h"
/* Firmware table providers */
@@ -1945,12 +1956,15 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
size_t system_vendor_len, system_product_len, system_version_len, system_serial_len;
char board_vendor[128], board_product[128], board_version[128], board_serial[128];
size_t board_vendor_len, board_product_len, board_version_len, board_serial_len;
+ char chassis_vendor[128], chassis_version[128], chassis_serial[128], chassis_asset_tag[128];
+ size_t chassis_vendor_len, chassis_version_len, chassis_serial_len, chassis_asset_tag_len;
char *buffer = (char*)sfti->TableBuffer;
BYTE string_count;
struct smbios_prologue *prologue;
struct smbios_bios *bios;
struct smbios_system *system;
struct smbios_board *board;
+ struct smbios_chassis *chassis;
#define S(s) s, sizeof(s)
bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
@@ -1964,6 +1978,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
board_product_len = get_smbios_string("/sys/class/dmi/id/board_name", S(board_product));
board_version_len = get_smbios_string("/sys/class/dmi/id/board_version", S(board_version));
board_serial_len = get_smbios_string("/sys/class/dmi/id/board_serial", S(board_serial));
+ chassis_vendor_len = get_smbios_string("/sys/class/dmi/id/chassis_vendor", S(chassis_vendor));
+ chassis_version_len = get_smbios_string("/sys/class/dmi/id/chassis_version", S(chassis_version));
+ chassis_serial_len = get_smbios_string("/sys/class/dmi/id/chassis_serial", S(chassis_serial));
+ chassis_asset_tag_len = get_smbios_string("/sys/class/dmi/id/chassis_tag", S(chassis_asset_tag));
#undef S
*required_len = sizeof(struct smbios_prologue);
@@ -1978,6 +1996,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
*required_len += sizeof(struct smbios_board);
*required_len += max(board_vendor_len + board_product_len + board_version_len + board_serial_len + 5, 2);
+ *required_len += sizeof(struct smbios_chassis);
+ *required_len += max(chassis_vendor_len + chassis_version_len + chassis_serial_len +
+ chassis_asset_tag_len + 5, 2);
+
sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
@@ -2064,6 +2086,33 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
copy_smbios_string(&buffer, board_version, board_version_len);
copy_smbios_string(&buffer, board_serial, board_serial_len);
memset(buffer, 0, 1);
+ buffer++;
+ }
+ else
+ {
+ memset(buffer, 0, 2);
+ buffer += 2;
+ }
+
+ string_count = 0;
+ chassis = (struct smbios_chassis*)buffer;
+ chassis->type = 3;
+ chassis->length = sizeof(struct smbios_chassis);
+ chassis->handle = 0;
+ chassis->vendor = chassis_vendor_len ? ++string_count : 0;
+ chassis->shape = 0x2; /* unknown */
+ chassis->version = chassis_version_len ? ++string_count : 0;
+ chassis->serial = chassis_serial_len ? ++string_count : 0;
+ chassis->asset_tag = chassis_asset_tag_len ? ++string_count : 0;
+ buffer += sizeof(struct smbios_chassis);
+
+ if (string_count)
+ {
+ copy_smbios_string(&buffer, chassis_vendor, chassis_vendor_len);
+ copy_smbios_string(&buffer, chassis_version, chassis_version_len);
+ copy_smbios_string(&buffer, chassis_serial, chassis_serial_len);
+ copy_smbios_string(&buffer, chassis_asset_tag, chassis_asset_tag_len);
+ memset(buffer, 0, 1);
}
else
{
--
2.17.1
June 21, 2018
[PATCH v8 8/9] ntdll: Return board info from NtQuerySystemInformation on Linux
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/nt.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 5137b8e5dc..e622912d8a 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -98,6 +98,16 @@ struct smbios_system {
BYTE serial;
};
+struct smbios_board {
+ BYTE type;
+ BYTE length;
+ WORD handle;
+ BYTE vendor;
+ BYTE product;
+ BYTE version;
+ BYTE serial;
+};
+
#include "poppack.h"
/* Firmware table providers */
@@ -1933,11 +1943,14 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
size_t bios_vendor_len, bios_version_len, bios_date_len;
char system_vendor[128], system_product[128], system_version[128], system_serial[128];
size_t system_vendor_len, system_product_len, system_version_len, system_serial_len;
+ char board_vendor[128], board_product[128], board_version[128], board_serial[128];
+ size_t board_vendor_len, board_product_len, board_version_len, board_serial_len;
char *buffer = (char*)sfti->TableBuffer;
BYTE string_count;
struct smbios_prologue *prologue;
struct smbios_bios *bios;
struct smbios_system *system;
+ struct smbios_board *board;
#define S(s) s, sizeof(s)
bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
@@ -1947,6 +1960,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
system_product_len = get_smbios_string("/sys/class/dmi/id/product", S(system_product));
system_version_len = get_smbios_string("/sys/class/dmi/id/product_version", S(system_version));
system_serial_len = get_smbios_string("/sys/class/dmi/id/product_serial", S(system_serial));
+ board_vendor_len = get_smbios_string("/sys/class/dmi/id/board_vendor", S(board_vendor));
+ board_product_len = get_smbios_string("/sys/class/dmi/id/board_name", S(board_product));
+ board_version_len = get_smbios_string("/sys/class/dmi/id/board_version", S(board_version));
+ board_serial_len = get_smbios_string("/sys/class/dmi/id/board_serial", S(board_serial));
#undef S
*required_len = sizeof(struct smbios_prologue);
@@ -1958,6 +1975,9 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
*required_len += max(system_vendor_len + system_product_len + system_version_len +
system_serial_len + 5, 2);
+ *required_len += sizeof(struct smbios_board);
+ *required_len += max(board_vendor_len + board_product_len + board_version_len + board_serial_len + 5, 2);
+
sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
@@ -2018,6 +2038,32 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
copy_smbios_string(&buffer, system_version, system_version_len);
copy_smbios_string(&buffer, system_serial, system_serial_len);
memset(buffer, 0, 1);
+ buffer++;
+ }
+ else
+ {
+ memset(buffer, 0, 2);
+ buffer += 2;
+ }
+
+ string_count = 0;
+ board = (struct smbios_board*)buffer;
+ board->type = 2;
+ board->length = sizeof(struct smbios_board);
+ board->handle = 0;
+ board->vendor = board_vendor_len ? ++string_count : 0;
+ board->product = board_product_len ? ++string_count : 0;
+ board->version = board_version_len ? ++string_count : 0;
+ board->serial = board_serial_len ? ++string_count : 0;
+ buffer += sizeof(struct smbios_board);
+
+ if (string_count)
+ {
+ copy_smbios_string(&buffer, board_vendor, board_vendor_len);
+ copy_smbios_string(&buffer, board_product, board_product_len);
+ copy_smbios_string(&buffer, board_version, board_version_len);
+ copy_smbios_string(&buffer, board_serial, board_serial_len);
+ memset(buffer, 0, 1);
}
else
{
--
2.17.1
June 21, 2018
[PATCH v8 7/9] ntdll: Return system info from NtQuerySystemInformation on Linux
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/nt.c | 47 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 47 insertions(+)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index c46c3cd01d..5137b8e5dc 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -88,6 +88,16 @@ struct smbios_bios {
UINT64 characteristics;
};
+struct smbios_system {
+ BYTE type;
+ BYTE length;
+ WORD handle;
+ BYTE vendor;
+ BYTE product;
+ BYTE version;
+ BYTE serial;
+};
+
#include "poppack.h"
/* Firmware table providers */
@@ -1921,15 +1931,22 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
{
char bios_vendor[128], bios_version[128], bios_date[128];
size_t bios_vendor_len, bios_version_len, bios_date_len;
+ char system_vendor[128], system_product[128], system_version[128], system_serial[128];
+ size_t system_vendor_len, system_product_len, system_version_len, system_serial_len;
char *buffer = (char*)sfti->TableBuffer;
BYTE string_count;
struct smbios_prologue *prologue;
struct smbios_bios *bios;
+ struct smbios_system *system;
#define S(s) s, sizeof(s)
bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
bios_version_len = get_smbios_string("/sys/class/dmi/id/bios_version", S(bios_version));
bios_date_len = get_smbios_string("/sys/class/dmi/id/bios_date", S(bios_date));
+ system_vendor_len = get_smbios_string("/sys/class/dmi/id/sys_vendor", S(system_vendor));
+ system_product_len = get_smbios_string("/sys/class/dmi/id/product", S(system_product));
+ system_version_len = get_smbios_string("/sys/class/dmi/id/product_version", S(system_version));
+ system_serial_len = get_smbios_string("/sys/class/dmi/id/product_serial", S(system_serial));
#undef S
*required_len = sizeof(struct smbios_prologue);
@@ -1937,6 +1954,10 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
*required_len += sizeof(struct smbios_bios);
*required_len += max(bios_vendor_len + bios_version_len + bios_date_len + 4, 2);
+ *required_len += sizeof(struct smbios_system);
+ *required_len += max(system_vendor_len + system_product_len + system_version_len +
+ system_serial_len + 5, 2);
+
sfti->TableBufferLength = *required_len;
*required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
@@ -1971,6 +1992,32 @@ static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti
copy_smbios_string(&buffer, bios_version, bios_version_len);
copy_smbios_string(&buffer, bios_date, bios_date_len);
memset(buffer, 0, 1);
+ buffer++;
+ }
+ else
+ {
+ memset(buffer, 0, 2);
+ buffer += 2;
+ }
+
+ string_count = 0;
+ system = (struct smbios_system*)buffer;
+ system->type = 1;
+ system->length = sizeof(struct smbios_system);
+ system->handle = 0;
+ system->vendor = system_vendor_len ? ++string_count : 0;
+ system->product = system_product_len ? ++string_count : 0;
+ system->version = system_version_len ? ++string_count : 0;
+ system->serial = system_serial_len ? ++string_count : 0;
+ buffer += sizeof(struct smbios_system);
+
+ if (string_count)
+ {
+ copy_smbios_string(&buffer, system_vendor, system_vendor_len);
+ copy_smbios_string(&buffer, system_product, system_product_len);
+ copy_smbios_string(&buffer, system_version, system_version_len);
+ copy_smbios_string(&buffer, system_serial, system_serial_len);
+ memset(buffer, 0, 1);
}
else
{
--
2.17.1
June 21, 2018
[PATCH v8 6/9] kernel32: Connect GetSystemFirmwareTable to NtQuerySystemInformation
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/kernel32/cpu.c | 29 +++++++++++++++++++++++++++++
dlls/kernel32/process.c | 10 ----------
dlls/kernel32/tests/version.c | 2 +-
3 files changed, 30 insertions(+), 11 deletions(-)
diff --git a/dlls/kernel32/cpu.c b/dlls/kernel32/cpu.c
index ec1fd0f90d..8397fbe729 100644
--- a/dlls/kernel32/cpu.c
+++ b/dlls/kernel32/cpu.c
@@ -336,3 +336,32 @@ DWORD64 WINAPI GetEnabledXStateFeatures(void)
FIXME("\n");
return 0;
}
+
+/***********************************************************************
+ * GetSystemFirmwareTable (KERNEL32.@)
+ */
+UINT WINAPI GetSystemFirmwareTable(DWORD provider, DWORD id, void *buffer, DWORD size)
+{
+ ULONG buffer_size = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer) + size;
+ SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = HeapAlloc(GetProcessHeap(), 0, buffer_size);
+ NTSTATUS status;
+
+ if (!sfti)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return 0;
+ }
+
+ sfti->ProviderSignature = provider;
+ sfti->Action = SystemFirmwareTable_Get;
+ sfti->TableID = id;
+
+ status = NtQuerySystemInformation(SystemFirmwareTableInformation, sfti, buffer_size, &buffer_size);
+ buffer_size -= FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
+ if (buffer_size <= size)
+ memcpy(buffer, sfti->TableBuffer, buffer_size);
+
+ if (status) SetLastError(RtlNtStatusToDosError(status));
+ HeapFree(GetProcessHeap(), 0, sfti);
+ return buffer_size;
+}
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index ff56e9a692..6adf08d257 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -4126,16 +4126,6 @@ HRESULT WINAPI UnregisterApplicationRestart(void)
return S_OK;
}
-/***********************************************************************
- * GetSystemFirmwareTable (KERNEL32.@)
- */
-UINT WINAPI GetSystemFirmwareTable(DWORD provider, DWORD id, PVOID buffer, DWORD size)
-{
- FIXME("(%d %d %p %d):stub\n", provider, id, buffer, size);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return 0;
-}
-
struct proc_thread_attr
{
DWORD_PTR attr;
diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c
index 08e8f0fb58..e33ce9cd42 100644
--- a/dlls/kernel32/tests/version.c
+++ b/dlls/kernel32/tests/version.c
@@ -717,7 +717,7 @@ void test_GetSystemFirmwareTable(void)
pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &expected_len);
if (expected_len == 0) /* xp, 2003 */
{
- skip("SystemFirmwareTableInformation is not available\n");
+ win_skip("SystemFirmwareTableInformation is not available\n");
HeapFree(GetProcessHeap(), 0, sfti);
return;
}
--
2.17.1
June 21, 2018
[PATCH v8 5/9] ntdll: Return BIOS info from NtQuerySystemInformation on Linux
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/nt.c | 171 ++++++++++++++++++++++++++++++++++++++++
dlls/ntdll/tests/info.c | 11 ++-
2 files changed, 180 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index dc0ce04f42..c46c3cd01d 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -66,6 +66,35 @@
WINE_DEFAULT_DEBUG_CHANNEL(ntdll);
+#include "pshpack1.h"
+
+struct smbios_prologue {
+ BYTE calling_method;
+ BYTE major_version;
+ BYTE minor_version;
+ BYTE revision;
+ DWORD length;
+};
+
+struct smbios_bios {
+ BYTE type;
+ BYTE length;
+ WORD handle;
+ BYTE vendor;
+ BYTE version;
+ WORD start;
+ BYTE date;
+ BYTE size;
+ UINT64 characteristics;
+};
+
+#include "poppack.h"
+
+/* Firmware table providers */
+#define ACPI 0x41435049
+#define FIRM 0x4649524D
+#define RSMB 0x52534D42
+
/*
* Token
*/
@@ -1850,6 +1879,126 @@ static NTSTATUS create_logical_proc_info(SYSTEM_LOGICAL_PROCESSOR_INFORMATION **
}
#endif
+static inline void copy_smbios_string(char **buffer, char *s, size_t len)
+{
+ if (!len) return;
+ strcpy(*buffer, s);
+ *buffer += len + 1;
+}
+
+#ifdef linux
+
+static size_t get_smbios_string(const char *path, char *str, size_t size)
+{
+ FILE *file;
+ size_t len;
+
+ if (!(file = fopen(path, "r")))
+ return 0;
+
+ len = fread(str, 1, size - 1, file);
+ fclose(file);
+
+ if (len >= 1 && str[len - 1] == '\n')
+ {
+ str[len - 1] = 0;
+ len--;
+ }
+ else
+ {
+ str[len] = 0;
+ }
+
+ return len;
+}
+
+static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti,
+ ULONG available_len, ULONG *required_len)
+{
+ switch (sfti->ProviderSignature)
+ {
+ case RSMB:
+ {
+ char bios_vendor[128], bios_version[128], bios_date[128];
+ size_t bios_vendor_len, bios_version_len, bios_date_len;
+ char *buffer = (char*)sfti->TableBuffer;
+ BYTE string_count;
+ struct smbios_prologue *prologue;
+ struct smbios_bios *bios;
+
+#define S(s) s, sizeof(s)
+ bios_vendor_len = get_smbios_string("/sys/class/dmi/id/bios_vendor", S(bios_vendor));
+ bios_version_len = get_smbios_string("/sys/class/dmi/id/bios_version", S(bios_version));
+ bios_date_len = get_smbios_string("/sys/class/dmi/id/bios_date", S(bios_date));
+#undef S
+
+ *required_len = sizeof(struct smbios_prologue);
+
+ *required_len += sizeof(struct smbios_bios);
+ *required_len += max(bios_vendor_len + bios_version_len + bios_date_len + 4, 2);
+
+ sfti->TableBufferLength = *required_len;
+
+ *required_len += FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
+
+ if (available_len < *required_len)
+ return STATUS_BUFFER_TOO_SMALL;
+
+ prologue = (struct smbios_prologue*)buffer;
+ prologue->calling_method = 0;
+ prologue->major_version = 2;
+ prologue->minor_version = 0;
+ prologue->revision = 0;
+ prologue->length = sfti->TableBufferLength - sizeof(struct smbios_prologue);
+ buffer += sizeof(struct smbios_prologue);
+
+ string_count = 0;
+ bios = (struct smbios_bios*)buffer;
+ bios->type = 0;
+ bios->length = sizeof(struct smbios_bios);
+ bios->handle = 0;
+ bios->vendor = bios_vendor_len ? ++string_count : 0;
+ bios->version = bios_version_len ? ++string_count : 0;
+ bios->start = 0;
+ bios->date = bios_date_len ? ++string_count : 0;
+ bios->size = 0;
+ bios->characteristics = 0x4; /* not supported */
+ buffer += sizeof(struct smbios_bios);
+
+ if (string_count)
+ {
+ copy_smbios_string(&buffer, bios_vendor, bios_vendor_len);
+ copy_smbios_string(&buffer, bios_version, bios_version_len);
+ copy_smbios_string(&buffer, bios_date, bios_date_len);
+ memset(buffer, 0, 1);
+ }
+ else
+ {
+ memset(buffer, 0, 2);
+ }
+
+ return STATUS_SUCCESS;
+ }
+ default:
+ {
+ FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n");
+ return STATUS_NOT_IMPLEMENTED;
+ }
+ }
+}
+
+#else
+
+static inline NTSTATUS get_firmware_info(SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti,
+ ULONG available_len, ULONG *required_len)
+{
+ FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n");
+ sfti->TableBufferLength = 0;
+ return STATUS_NOT_IMPLEMENTED;
+}
+
+#endif
+
/******************************************************************************
* NtQuerySystemInformation [NTDLL.@]
* ZwQuerySystemInformation [NTDLL.@]
@@ -2359,6 +2508,28 @@ NTSTATUS WINAPI NtQuerySystemInformation(
else ret = STATUS_INFO_LENGTH_MISMATCH;
}
break;
+ case SystemFirmwareTableInformation:
+ {
+ SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = (SYSTEM_FIRMWARE_TABLE_INFORMATION*)SystemInformation;
+ len = FIELD_OFFSET(SYSTEM_FIRMWARE_TABLE_INFORMATION, TableBuffer);
+ if (Length < len)
+ {
+ ret = STATUS_INFO_LENGTH_MISMATCH;
+ break;
+ }
+
+ switch (sfti->Action)
+ {
+ case SystemFirmwareTable_Get:
+ ret = get_firmware_info(sfti, Length, &len);
+ break;
+ default:
+ len = 0;
+ ret = STATUS_NOT_IMPLEMENTED;
+ FIXME("info_class SYSTEM_FIRMWARE_TABLE_INFORMATION\n");
+ }
+ }
+ break;
default:
FIXME("(0x%08x,%p,0x%08x,%p) stub\n",
SystemInformationClass,SystemInformation,Length,ResultLength);
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 9e12a013cf..29af0e3d90 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -59,6 +59,12 @@ static DWORD one_before_last_pid = 0;
#define FIRM 0x4649524D
#define RSMB 0x52534D42
+#ifdef linux
+static const int firmware_todo = 0;
+#else
+static const int firmware_todo = 1;
+#endif
+
static BOOL InitFunctionPtrs(void)
{
/* All needed functions are NT based, so using GetModuleHandle is a good check */
@@ -842,12 +848,11 @@ static void test_query_firmware(void)
ok(!!sfti, "Failed to allocate memory\n");
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 15, &len1);
-todo_wine
ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* xp */,
"Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
if (len1 == 0) /* xp, 2003 */
{
- skip("SystemFirmwareTableInformation is not available\n");
+ win_skip("SystemFirmwareTableInformation is not available\n");
HeapFree(GetProcessHeap(), 0, sfti);
return;
}
@@ -862,6 +867,7 @@ todo_wine
sfti->TableID = 0;
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1);
+todo_wine_if(firmware_todo)
ok(status == STATUS_BUFFER_TOO_SMALL, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status);
ok(len1 >= 16, "Expected length >= 16, got %u\n", len1);
ok(sfti->TableBufferLength == len1 - 16, "Expected length %u, got %u\n", len1 - 16, sfti->TableBufferLength);
@@ -873,6 +879,7 @@ todo_wine
{
sfti->TableID = i;
status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, len1, &len2);
+todo_wine_if(firmware_todo)
ok(status == STATUS_SUCCESS, "Table %u: Expected STATUS_SUCCESS, got %08x\n", i, status);
ok(len2 == len1, "Table %u: Expected length %u, got %u\n", i, len1, len2);
ok(sfti->TableBufferLength == len1 - 16,
--
2.17.1
June 21, 2018
[PATCH v8 4/9] kernel32/tests: Add GetSystemFirmwareTable tests
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/kernel32/tests/version.c | 41 +++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
diff --git a/dlls/kernel32/tests/version.c b/dlls/kernel32/tests/version.c
index eb78a383d2..08e8f0fb58 100644
--- a/dlls/kernel32/tests/version.c
+++ b/dlls/kernel32/tests/version.c
@@ -26,11 +26,17 @@
#include "winternl.h"
static BOOL (WINAPI * pGetProductInfo)(DWORD, DWORD, DWORD, DWORD, DWORD *);
+static NTSTATUS (WINAPI * pNtQuerySystemInformation)(SYSTEM_INFORMATION_CLASS, void *, ULONG, ULONG *);
static NTSTATUS (WINAPI * pRtlGetVersion)(RTL_OSVERSIONINFOEXW *);
#define GET_PROC(func) \
p##func = (void *)GetProcAddress(hmod, #func);
+/* Firmware table providers */
+#define ACPI 0x41435049
+#define FIRM 0x4649524D
+#define RSMB 0x52534D42
+
static void init_function_pointers(void)
{
HMODULE hmod;
@@ -41,6 +47,7 @@ static void init_function_pointers(void)
hmod = GetModuleHandleA("ntdll.dll");
+ GET_PROC(NtQuerySystemInformation);
GET_PROC(RtlGetVersion);
}
@@ -697,6 +704,39 @@ static void test_VerifyVersionInfo(void)
ok(ret, "VerifyVersionInfoA failed with error %d\n", GetLastError());
}
+void test_GetSystemFirmwareTable(void)
+{
+ ULONG expected_len, i;
+ UINT len;
+ SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16);
+ UCHAR *smbios_table = NULL;
+
+ ok(!!sfti, "Failed to allocate memory\n");
+ sfti->ProviderSignature = RSMB;
+ sfti->Action = SystemFirmwareTable_Get;
+ pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &expected_len);
+ if (expected_len == 0) /* xp, 2003 */
+ {
+ skip("SystemFirmwareTableInformation is not available\n");
+ HeapFree(GetProcessHeap(), 0, sfti);
+ return;
+ }
+ sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, expected_len);
+ ok(!!sfti, "Failed to allocate memory\n");
+ pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, expected_len, &expected_len);
+
+ expected_len -= 16;
+ smbios_table = HeapAlloc(GetProcessHeap(), 0, expected_len);
+ for (i = 0; i < 100; i++)
+ {
+ len = GetSystemFirmwareTable(RSMB, i, smbios_table, expected_len);
+ ok(len == expected_len, "Table %u: Expected length %u, got %u\n", i, expected_len, len);
+ }
+
+ HeapFree(GetProcessHeap(), 0, sfti);
+ HeapFree(GetProcessHeap(), 0, smbios_table);
+}
+
START_TEST(version)
{
init_function_pointers();
@@ -704,4 +744,5 @@ START_TEST(version)
test_GetProductInfo();
test_GetVersionEx();
test_VerifyVersionInfo();
+ test_GetSystemFirmwareTable();
}
--
2.17.1
June 21, 2018
[PATCH v8 3/9] ntdll/tests: Add SystemFirmwareTableInformation tests
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/tests/info.c | 60 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index b18f0d39d9..9e12a013cf 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -54,6 +54,11 @@ static DWORD one_before_last_pid = 0;
} \
} while(0)
+/* Firmware table providers */
+#define ACPI 0x41435049
+#define FIRM 0x4649524D
+#define RSMB 0x52534D42
+
static BOOL InitFunctionPtrs(void)
{
/* All needed functions are NT based, so using GetModuleHandle is a good check */
@@ -826,6 +831,57 @@ static void test_query_logicalprocex(void)
}
}
+static void test_query_firmware(void)
+{
+ ULONG len1, len2;
+ NTSTATUS status;
+ SYSTEM_FIRMWARE_TABLE_INFORMATION *sfti;
+ int i;
+
+ sfti = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, 16);
+ ok(!!sfti, "Failed to allocate memory\n");
+
+ status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 15, &len1);
+todo_wine
+ ok(status == STATUS_INFO_LENGTH_MISMATCH || broken(status == STATUS_INVALID_INFO_CLASS) /* xp */,
+ "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+ if (len1 == 0) /* xp, 2003 */
+ {
+ skip("SystemFirmwareTableInformation is not available\n");
+ HeapFree(GetProcessHeap(), 0, sfti);
+ return;
+ }
+ ok(len1 == 16, "Expected length 16, got %u\n", len1);
+
+ status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1);
+ ok(status == STATUS_NOT_IMPLEMENTED, "Expected STATUS_NOT_IMPLEMENTED, got %08x\n", status);
+ ok(len1 == 0, "Expected length 0, got %u\n", len1);
+
+ sfti->ProviderSignature = RSMB;
+ sfti->Action = SystemFirmwareTable_Get;
+ sfti->TableID = 0;
+
+ status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, 16, &len1);
+ ok(status == STATUS_BUFFER_TOO_SMALL, "Expected STATUS_BUFFER_TOO_SMALL, got %08x\n", status);
+ ok(len1 >= 16, "Expected length >= 16, got %u\n", len1);
+ ok(sfti->TableBufferLength == len1 - 16, "Expected length %u, got %u\n", len1 - 16, sfti->TableBufferLength);
+
+ sfti = HeapReAlloc(GetProcessHeap(), 0, sfti, len1);
+ ok(!!sfti, "Failed to allocate memory\n");
+
+ for (i = 0; i < 100; i++)
+ {
+ sfti->TableID = i;
+ status = pNtQuerySystemInformation(SystemFirmwareTableInformation, sfti, len1, &len2);
+ ok(status == STATUS_SUCCESS, "Table %u: Expected STATUS_SUCCESS, got %08x\n", i, status);
+ ok(len2 == len1, "Table %u: Expected length %u, got %u\n", i, len1, len2);
+ ok(sfti->TableBufferLength == len1 - 16,
+ "Table %u: Expected length %u, got %u\n", i, len1 - 16, sfti->TableBufferLength);
+ }
+
+ HeapFree(GetProcessHeap(), 0, sfti);
+}
+
static void test_query_processor_power_info(void)
{
NTSTATUS status;
@@ -2271,6 +2327,10 @@ START_TEST(info)
trace("Starting test_process_debug_flags()\n");
test_query_process_debug_flags(argc, argv);
+ /* 0x4C SystemFirmwareTableInformation */
+ trace("Starting test_query_firmware()\n");
+ test_query_firmware();
+
/* belongs to its own file */
trace("Starting test_readvirtualmemory()\n");
test_readvirtualmemory();
--
2.17.1
June 21, 2018
[PATCH v8 2/9] include: Add SYSTEM_FIRMWARE_TABLE_INFORMATION to winternl.h
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
include/winternl.h | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/include/winternl.h b/include/winternl.h
index 58c475dfff..6e0bd987b6 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1579,6 +1579,23 @@ typedef struct _SYSTEM_TIME_ADJUSTMENT {
BOOLEAN TimeAdjustmentDisabled;
} SYSTEM_TIME_ADJUSTMENT, *PSYSTEM_TIME_ADJUSTMENT;
+typedef enum _SYSTEM_FIRMWARE_TABLE_ACTION
+{
+ SystemFirmwareTable_Enumerate = 0,
+ SystemFirmwareTable_Get = 1
+} SYSTEM_FIRMWARE_TABLE_ACTION, *PSYSTEM_FIRMWARE_TABLE_ACTION;
+
+/* System Information Class 0x4C */
+
+typedef struct _SYSTEM_FIRMWARE_TABLE_INFORMATION
+{
+ ULONG ProviderSignature;
+ SYSTEM_FIRMWARE_TABLE_ACTION Action;
+ ULONG TableID;
+ ULONG TableBufferLength;
+ UCHAR TableBuffer[1];
+} SYSTEM_FIRMWARE_TABLE_INFORMATION, *PSYSTEM_FIRMWARE_TABLE_INFORMATION;
+
typedef struct _TIME_FIELDS
{ CSHORT Year;
CSHORT Month;
--
2.17.1
June 21, 2018
[PATCH v8 1/9] ntdll/tests: Skip map protection tests when access is denied
by Alex Henrie
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/ntdll/tests/info.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 6c93c3cd58..b18f0d39d9 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -1789,6 +1789,10 @@ static void test_mapprotection(void)
}
ok( (status == STATUS_SUCCESS) || (status == STATUS_INVALID_INFO_CLASS), "Expected STATUS_SUCCESS, got %08x\n", status);
status = pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &flags, sizeof(flags) );
+ if (status == STATUS_ACCESS_DENIED) {
+ skip("Access to set ProcessExecuteFlags denied\n");
+ return;
+ }
ok( (status == STATUS_SUCCESS) || (status == STATUS_INVALID_INFO_CLASS), "Expected STATUS_SUCCESS, got %08x\n", status);
size.u.LowPart = 0x2000;
--
2.17.1
June 21, 2018
[PATCH] oleaut32: Correct some comments.
by Zebediah Figura
This corresponds to 652ec646ad3 affecting widl.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/oleaut32/typelib.c | 2 +-
dlls/oleaut32/typelib.h | 17 ++++++++---------
2 files changed, 9 insertions(+), 10 deletions(-)
diff --git a/dlls/oleaut32/typelib.c b/dlls/oleaut32/typelib.c
index 4ee6aa540d..9b1c782e8d 100644
--- a/dlls/oleaut32/typelib.c
+++ b/dlls/oleaut32/typelib.c
@@ -2675,7 +2675,7 @@ static ITypeInfoImpl * MSFT_DoTypeInfo(
ptiRet->typeattr.wMajorVerNum = LOWORD(tiBase.version);
ptiRet->typeattr.wMinorVerNum = HIWORD(tiBase.version);
ptiRet->typeattr.cImplTypes = tiBase.cImplTypes;
- ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft; /* FIXME: this is only the non inherited part */
+ ptiRet->typeattr.cbSizeVft = tiBase.cbSizeVft;
if (ptiRet->typeattr.typekind == TKIND_ALIAS) {
TYPEDESC tmp;
MSFT_GetTdesc(pcx, tiBase.datatype1, &tmp);
diff --git a/dlls/oleaut32/typelib.h b/dlls/oleaut32/typelib.h
index c404b3d311..7699a9a1f3 100644
--- a/dlls/oleaut32/typelib.h
+++ b/dlls/oleaut32/typelib.h
@@ -142,11 +142,11 @@ typedef struct tagMSFT_TypeInfoBase {
INT helpcontext; /* */
INT oCustData; /* offset in customer data table */
#ifdef WORDS_BIGENDIAN
- INT16 cbSizeVft; /* virtual table size, not including inherits */
+ INT16 cbSizeVft; /* virtual table size, including inherits */
INT16 cImplTypes; /* nr of implemented interfaces */
#else
INT16 cImplTypes; /* nr of implemented interfaces */
- INT16 cbSizeVft; /* virtual table size, not including inherits */
+ INT16 cbSizeVft; /* virtual table size, including inherits */
#endif
/*050*/ INT size; /* size in bytes, at least for structures */
/* FIXME: name of this field */
@@ -155,10 +155,8 @@ typedef struct tagMSFT_TypeInfoBase {
/* if coclass: offset in reftable */
/* if interface: reference to inherited if */
/* if module: offset to dllname in name table */
- INT datatype2; /* if 0x8000, entry above is valid */
- /* actually dunno */
- /* else it is zero? */
- /* if interface: inheritance level | no of inherited funcs */
+ INT datatype2; /* for interfaces: hiword is num of inherited funcs */
+ /* loword is num of inherited interfaces */
INT res18; /* always? 0 */
/*060*/ INT res19; /* always? -1 */
} MSFT_TypeInfoBase;
@@ -281,9 +279,10 @@ typedef struct {
to the typeinfo itself or to a member of
the typeinfo */
INT next_hash; /* offset to next name in the hash bucket */
- INT namelen; /* only lower 8 bits are valid,
- lower-middle 8 bits are unknown (flags?),
- upper 16 bits are hash code */
+ INT namelen; /* only lower 8 bits are valid */
+ /* 0x1000 if name is only used once as a variable name */
+ /* 0x2000 if name is a variable in an enumeration */
+ /* 0x3800 if name is typeinfo name */
} MSFT_NameIntro;
/* the custom data table directory has entries like this */
typedef struct {
--
2.17.0
June 21, 2018
K32EnumDeviceDrivers Patch
by Anthony Lauzon
Hi All,
I've been hacking away at K32EnumDeviceDrivers trying to get it to properly
handle calls, and have made some decent progress that maybe some of you who
are experts can finish. The reason why I am trying to implement
K32EnumDeviceDrivers is that Creative's E-MU Emulator X3 crashes when
trying to call it. I've managed to get the app one step closer to
launching with this K32EnumDeviceDrivers implementation, which does in fact
enumerate the devices, and am now stuck on a different error. I hope this
patch is of some utility to you all.
June 20, 2018
[PATCH 5/5] d3dx10: Turn some ERR() into WARN().
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
They can be triggered by the application and, indeed, some appeared in
the tests.
dlls/d3dx10_43/async.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/dlls/d3dx10_43/async.c b/dlls/d3dx10_43/async.c
index 1555a3d11e4..c7d80c9db46 100644
--- a/dlls/d3dx10_43/async.c
+++ b/dlls/d3dx10_43/async.c
@@ -115,7 +115,7 @@ static HRESULT WINAPI filedataloader_Load(ID3DX10DataLoader *iface)
CloseHandle(file);
if (!ret)
{
- ERR("Failed to read file contents.\n");
+ WARN("Failed to read file contents.\n");
HeapFree(GetProcessHeap(), 0, data);
return E_FAIL;
}
@@ -175,7 +175,7 @@ static HRESULT WINAPI resourcedataloader_Load(ID3DX10DataLoader *iface)
hglobal = LoadResource(loader->u.resource.module, loader->u.resource.rsrc);
if (!hglobal)
{
- ERR("Failed to load resource.\n");
+ WARN("Failed to load resource.\n");
return E_FAIL;
}
@@ -349,7 +349,7 @@ HRESULT WINAPI D3DX10CreateAsyncResourceLoaderA(HMODULE module, const char *reso
if (!(rsrc = FindResourceA(module, resource, (const char *)RT_RCDATA)))
{
- ERR("Failed to find resource.\n");
+ WARN("Failed to find resource.\n");
HeapFree(GetProcessHeap(), 0, object);
return D3DX10_ERR_INVALID_DATA;
}
@@ -381,7 +381,7 @@ HRESULT WINAPI D3DX10CreateAsyncResourceLoaderW(HMODULE module, const WCHAR *res
if (!(rsrc = FindResourceW(module, resource, (const WCHAR *)RT_RCDATA)))
{
- ERR("Failed to find resource.\n");
+ WARN("Failed to find resource.\n");
HeapFree(GetProcessHeap(), 0, object);
return D3DX10_ERR_INVALID_DATA;
}
--
2.16.4
June 20, 2018
[PATCH v2 resend 4/5] wined3d: Declare the correct number and type of fragment shader color outputs.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
dlls/wined3d/glsl_shader.c | 128 +++++++++++++++++++++++++++++++++++++++------
1 file changed, 111 insertions(+), 17 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index cd4780a6419..d5dc8be136a 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -3318,12 +3318,12 @@ static void shader_glsl_get_swizzle(const struct wined3d_shader_src_param *param
shader_glsl_swizzle_to_str(param->swizzle, fixup, mask, swizzle_str);
}
-static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, const char *src_param,
+static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *buffer, const char *arg,
enum wined3d_component_type dst_type, enum wined3d_component_type src_type)
{
if (dst_type == src_type)
{
- string_buffer_sprintf(dst_param, "%s", src_param);
+ string_buffer_sprintf(buffer, "%s", arg);
return;
}
@@ -3332,10 +3332,10 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
switch (dst_type)
{
case WINED3D_TYPE_INT:
- string_buffer_sprintf(dst_param, "floatBitsToInt(%s)", src_param);
+ string_buffer_sprintf(buffer, "floatBitsToInt(%s)", arg);
return;
case WINED3D_TYPE_UINT:
- string_buffer_sprintf(dst_param, "floatBitsToUint(%s)", src_param);
+ string_buffer_sprintf(buffer, "floatBitsToUint(%s)", arg);
return;
default:
break;
@@ -3344,18 +3344,18 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
if (src_type == WINED3D_TYPE_UINT && dst_type == WINED3D_TYPE_FLOAT)
{
- string_buffer_sprintf(dst_param, "uintBitsToFloat(%s)", src_param);
+ string_buffer_sprintf(buffer, "uintBitsToFloat(%s)", arg);
return;
}
if (src_type == WINED3D_TYPE_INT && dst_type == WINED3D_TYPE_FLOAT)
{
- string_buffer_sprintf(dst_param, "intBitsToFloat(%s)", src_param);
+ string_buffer_sprintf(buffer, "intBitsToFloat(%s)", arg);
return;
}
FIXME("Unhandled cast from %#x to %#x.\n", src_type, dst_type);
- string_buffer_sprintf(dst_param, "%s", src_param);
+ string_buffer_sprintf(buffer, "%s", arg);
}
/* From a given parameter token, generate the corresponding GLSL string.
@@ -7616,9 +7616,48 @@ static void shader_glsl_enable_extensions(struct wined3d_string_buffer *buffer,
shader_addline(buffer, "#extension GL_EXT_texture_array : enable\n");
}
+static void shader_glsl_generate_color_output(struct wined3d_string_buffer *buffer,
+ const struct wined3d_gl_info *gl_info, const struct wined3d_shader *shader,
+ struct wined3d_string_buffer_list *string_buffers)
+{
+ const struct wined3d_shader_signature *output_signature = &shader->output_signature;
+ struct wined3d_string_buffer *src, *assignment;
+ unsigned int i;
+
+ if (output_signature->element_count)
+ {
+ src = string_buffer_get(string_buffers);
+ assignment = string_buffer_get(string_buffers);
+ for (i = 0; i < output_signature->element_count; ++i)
+ {
+ const struct wined3d_shader_signature_element *output = &output_signature->elements[i];
+
+ /* register_idx is set to ~0u for non-color outputs. */
+ if (output->register_idx == ~0u)
+ continue;
+ shader_addline(buffer, "color_out%u = ", output->semantic_idx);
+ string_buffer_sprintf(src, "ps_out[%u]", output->semantic_idx);
+ shader_glsl_sprintf_cast(assignment, src->buffer, output->component_type, WINED3D_TYPE_FLOAT);
+ shader_addline(buffer, "%s;\n", assignment->buffer);
+ }
+ string_buffer_release(string_buffers, src);
+ string_buffer_release(string_buffers, assignment);
+ }
+ else
+ {
+ DWORD mask = shader->reg_maps.rt_mask;
+
+ while (mask)
+ {
+ i = wined3d_bit_scan(&mask);
+ shader_addline(buffer, "color_out%u = ps_out[%u];\n", i, i);
+ }
+ }
+}
+
static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_info,
struct wined3d_string_buffer *buffer, const struct wined3d_shader *shader,
- const struct ps_compile_args *args)
+ const struct ps_compile_args *args, struct wined3d_string_buffer_list *string_buffers)
{
const struct wined3d_shader_reg_maps *reg_maps = &shader->reg_maps;
@@ -7637,6 +7676,26 @@ static void shader_glsl_generate_ps_epilogue(const struct wined3d_gl_info *gl_in
if (reg_maps->sample_mask)
shader_addline(buffer, "gl_SampleMask[0] = floatBitsToInt(sample_mask);\n");
+
+ if (!needs_legacy_glsl_syntax(gl_info))
+ shader_glsl_generate_color_output(buffer, gl_info, shader, string_buffers);
+}
+
+static const char *shader_glsl_get_ps_output_format(enum wined3d_component_type component_type)
+{
+ static const char formats[][6] =
+ {
+ "", /* WINED3D_TYPE_UNKNOWN */
+ "uvec4", /* WINED3D_TYPE_UINT */
+ "ivec4", /* WINED3D_TYPE_INT */
+ "vec4", /* WINED3D_TYPE_FLOAT */
+ };
+ if (component_type < WINED3D_TYPE_UNKNOWN || component_type > WINED3D_TYPE_FLOAT)
+ {
+ WARN("Unexpected component_type %#x.\n", component_type);
+ return formats[WINED3D_TYPE_FLOAT];
+ }
+ return formats[component_type];
}
/* Context activation is done by the caller. */
@@ -7819,9 +7878,35 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
if (!needs_legacy_glsl_syntax(gl_info))
{
- if (shader_glsl_use_explicit_attrib_location(gl_info))
- shader_addline(buffer, "layout(location = 0) ");
- shader_addline(buffer, "out vec4 ps_out[%u];\n", gl_info->limits.buffers);
+ const struct wined3d_shader_signature *output_signature = &shader->output_signature;
+
+ shader_addline(buffer, "vec4 ps_out[%u];\n", gl_info->limits.buffers);
+ if (output_signature->element_count)
+ {
+ for (i = 0; i < output_signature->element_count; ++i)
+ {
+ const struct wined3d_shader_signature_element *output = &output_signature->elements[i];
+
+ if (output->register_idx == ~0u)
+ continue;
+ if (shader_glsl_use_explicit_attrib_location(gl_info))
+ shader_addline(buffer, "layout(location = %u) ", output->semantic_idx);
+ shader_addline(buffer, "out %s color_out%u;\n",
+ shader_glsl_get_ps_output_format(output->component_type), output->semantic_idx);
+ }
+ }
+ else
+ {
+ DWORD mask = reg_maps->rt_mask;
+
+ while (mask)
+ {
+ i = wined3d_bit_scan(&mask);
+ if (shader_glsl_use_explicit_attrib_location(gl_info))
+ shader_addline(buffer, "layout(location = %u) ", i);
+ shader_addline(buffer, "out vec4 color_out%u;\n", i);
+ }
+ }
}
if (shader->limits->constant_float + extra_constants_needed >= gl_info->limits.glsl_ps_float_constants)
@@ -7906,7 +7991,7 @@ static GLuint shader_glsl_generate_pshader(const struct wined3d_context *context
/* In SM4+ the shader epilogue is generated by the "ret" instruction. */
if (reg_maps->shader_version.major < 4)
- shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, args);
+ shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, args, string_buffers);
shader_addline(buffer, "}\n");
@@ -8403,7 +8488,7 @@ static void shader_glsl_generate_shader_epilogue(const struct wined3d_shader_con
switch (shader->reg_maps.shader_version.type)
{
case WINED3D_SHADER_TYPE_PIXEL:
- shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, priv->cur_ps_args);
+ shader_glsl_generate_ps_epilogue(gl_info, buffer, shader, priv->cur_ps_args, priv->string_buffers);
break;
case WINED3D_SHADER_TYPE_VERTEX:
shader_glsl_generate_vs_epilogue(gl_info, buffer, shader, priv->cur_vs_args);
@@ -9539,9 +9624,10 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
if (!needs_legacy_glsl_syntax(gl_info))
{
+ shader_addline(buffer, "vec4 ps_out[1];\n");
if (shader_glsl_use_explicit_attrib_location(gl_info))
shader_addline(buffer, "layout(location = 0) ");
- shader_addline(buffer, "out vec4 ps_out[1];\n");
+ shader_addline(buffer, "out vec4 color_out0;\n");
}
shader_addline(buffer, "vec4 tmp0, tmp1;\n");
@@ -9881,6 +9967,8 @@ static GLuint shader_glsl_generate_ffp_fragment_shader(struct shader_glsl_priv *
shader_glsl_generate_fog_code(buffer, gl_info, settings->fog);
shader_glsl_generate_alpha_test(buffer, gl_info, alpha_test_func);
+ if (!needs_legacy_glsl_syntax(gl_info))
+ shader_addline(buffer, "color_out0 = ps_out[0];\n");
shader_addline(buffer, "}\n");
@@ -10422,13 +10510,17 @@ static void set_glsl_shader_program(const struct wined3d_context *context, const
}
}
checkGLcall("glBindAttribLocation");
- string_buffer_release(&priv->string_buffers, tmp_name);
if (!needs_legacy_glsl_syntax(gl_info))
{
- GL_EXTCALL(glBindFragDataLocation(program_id, 0, "ps_out"));
- checkGLcall("glBindFragDataLocation");
+ for (i = 0; i < MAX_RENDER_TARGET_VIEWS; ++i)
+ {
+ string_buffer_sprintf(tmp_name, "color_out%u", i);
+ GL_EXTCALL(glBindFragDataLocation(program_id, i, tmp_name->buffer));
+ checkGLcall("glBindFragDataLocation");
+ }
}
+ string_buffer_release(&priv->string_buffers, tmp_name);
}
if (hshader)
@@ -12796,6 +12888,8 @@ static GLuint glsl_blitter_generate_program(struct wined3d_glsl_blitter *blitter
shader_glsl_add_version_declaration(buffer, gl_info);
shader_addline(buffer, "uniform sampler%s sampler;\n", tex_type);
declare_in_varying(gl_info, buffer, FALSE, "vec3 out_texcoord;\n");
+ /* TODO: Declare the out variable with the correct type (and put it in the
+ * blitter args). */
if (!needs_legacy_glsl_syntax(gl_info))
shader_addline(buffer, "out vec4 ps_out[1];\n");
--
2.16.4
June 20, 2018
[PATCH v2 3/5] wined3d: Mostly get rid of enum wined3d_data_type.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
v2-ish: Leave the enum around only for the semantic data type /
shader_dump_decl_usage().
dlls/wined3d/glsl_shader.c | 100 ++++++++++++++++++++---------------------
dlls/wined3d/shader.c | 45 +++++++++++++------
dlls/wined3d/shader_sm1.c | 14 +++---
dlls/wined3d/shader_sm4.c | 56 +++++++++++------------
dlls/wined3d/wined3d_private.h | 4 +-
5 files changed, 117 insertions(+), 102 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index f1f3020d53d..cd4780a6419 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -88,7 +88,7 @@ struct glsl_sample_function
struct wined3d_string_buffer *name;
unsigned int coord_mask;
unsigned int deriv_mask;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
BOOL output_single_component;
unsigned int offset_size;
};
@@ -2522,17 +2522,15 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
switch (reg_maps->resource_info[entry->resource_idx].data_type)
{
- case WINED3D_DATA_FLOAT:
- case WINED3D_DATA_UNORM:
- case WINED3D_DATA_SNORM:
+ case WINED3D_TYPE_FLOAT:
sampler_type_prefix = "";
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
sampler_type_prefix = "i";
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
sampler_type_prefix = "u";
break;
@@ -2640,19 +2638,17 @@ static void shader_generate_glsl_declarations(const struct wined3d_context *cont
switch (reg_maps->uav_resource_info[i].data_type)
{
- case WINED3D_DATA_FLOAT:
- case WINED3D_DATA_UNORM:
- case WINED3D_DATA_SNORM:
+ case WINED3D_TYPE_FLOAT:
image_type_prefix = "";
read_format = "r32f";
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
image_type_prefix = "i";
read_format = "r32i";
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
image_type_prefix = "u";
read_format = "r32ui";
break;
@@ -2848,7 +2844,7 @@ static void shader_glsl_fixup_scalar_register_variable(char *register_name,
/** Writes the GLSL variable name that corresponds to the register that the
* DX opcode parameter is trying to access */
static void shader_glsl_get_register_name(const struct wined3d_shader_register *reg,
- enum wined3d_data_type data_type, char *register_name, BOOL *is_color,
+ enum wined3d_component_type data_type, char *register_name, BOOL *is_color,
const struct wined3d_shader_instruction *ins)
{
/* oPos, oFog and oPts in D3D */
@@ -3084,16 +3080,16 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
case WINED3D_IMMCONST_SCALAR:
switch (data_type)
{
- case WINED3D_DATA_FLOAT:
+ case WINED3D_TYPE_FLOAT:
if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
sprintf(register_name, "uintBitsToFloat(%#xu)", reg->u.immconst_data[0]);
else
wined3d_ftoa(*(const float *)reg->u.immconst_data, register_name);
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
sprintf(register_name, "%#x", reg->u.immconst_data[0]);
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
sprintf(register_name, "%#xu", reg->u.immconst_data[0]);
break;
default:
@@ -3105,7 +3101,7 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
case WINED3D_IMMCONST_VEC4:
switch (data_type)
{
- case WINED3D_DATA_FLOAT:
+ case WINED3D_TYPE_FLOAT:
if (gl_info->supported[ARB_SHADER_BIT_ENCODING])
{
sprintf(register_name, "uintBitsToFloat(uvec4(%#xu, %#xu, %#xu, %#xu))",
@@ -3122,12 +3118,12 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
imm_str[0], imm_str[1], imm_str[2], imm_str[3]);
}
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
sprintf(register_name, "ivec4(%#x, %#x, %#x, %#x)",
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
sprintf(register_name, "uvec4(%#xu, %#xu, %#xu, %#xu)",
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
@@ -3323,22 +3319,22 @@ static void shader_glsl_get_swizzle(const struct wined3d_shader_src_param *param
}
static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, const char *src_param,
- enum wined3d_data_type dst_data_type, enum wined3d_data_type src_data_type)
+ enum wined3d_component_type dst_type, enum wined3d_component_type src_type)
{
- if (dst_data_type == src_data_type)
+ if (dst_type == src_type)
{
string_buffer_sprintf(dst_param, "%s", src_param);
return;
}
- if (src_data_type == WINED3D_DATA_FLOAT)
+ if (src_type == WINED3D_TYPE_FLOAT)
{
- switch (dst_data_type)
+ switch (dst_type)
{
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
string_buffer_sprintf(dst_param, "floatBitsToInt(%s)", src_param);
return;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
string_buffer_sprintf(dst_param, "floatBitsToUint(%s)", src_param);
return;
default:
@@ -3346,19 +3342,19 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
}
}
- if (src_data_type == WINED3D_DATA_UINT && dst_data_type == WINED3D_DATA_FLOAT)
+ if (src_type == WINED3D_TYPE_UINT && dst_type == WINED3D_TYPE_FLOAT)
{
string_buffer_sprintf(dst_param, "uintBitsToFloat(%s)", src_param);
return;
}
- if (src_data_type == WINED3D_DATA_INT && dst_data_type == WINED3D_DATA_FLOAT)
+ if (src_type == WINED3D_TYPE_INT && dst_type == WINED3D_TYPE_FLOAT)
{
string_buffer_sprintf(dst_param, "intBitsToFloat(%s)", src_param);
return;
}
- FIXME("Unhandled cast from %#x to %#x.\n", src_data_type, dst_data_type);
+ FIXME("Unhandled cast from %#x to %#x.\n", src_type, dst_type);
string_buffer_sprintf(dst_param, "%s", src_param);
}
@@ -3367,11 +3363,11 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
* caller needs this information as well. */
static void shader_glsl_add_src_param_ext(const struct wined3d_shader_instruction *ins,
const struct wined3d_shader_src_param *wined3d_src, DWORD mask, struct glsl_src_param *glsl_src,
- enum wined3d_data_type data_type)
+ enum wined3d_component_type data_type)
{
struct shader_glsl_ctx_priv *priv = ins->ctx->backend_data;
struct wined3d_string_buffer *reg_name = string_buffer_get(priv->string_buffers);
- enum wined3d_data_type param_data_type;
+ enum wined3d_component_type param_data_type;
BOOL is_color = FALSE;
char swizzle_str[6];
@@ -3396,10 +3392,10 @@ static void shader_glsl_add_src_param_ext(const struct wined3d_shader_instructio
case WINED3DSPR_PRIMID:
case WINED3DSPR_THREADGROUPID:
case WINED3DSPR_THREADID:
- param_data_type = WINED3D_DATA_INT;
+ param_data_type = WINED3D_TYPE_INT;
break;
default:
- param_data_type = WINED3D_DATA_FLOAT;
+ param_data_type = WINED3D_TYPE_FLOAT;
break;
}
@@ -3434,7 +3430,7 @@ static DWORD shader_glsl_add_dst_param(const struct wined3d_shader_instruction *
/* Append the destination part of the instruction to the buffer, return the effective write mask */
static DWORD shader_glsl_append_dst_ext(struct wined3d_string_buffer *buffer,
const struct wined3d_shader_instruction *ins, const struct wined3d_shader_dst_param *dst,
- enum wined3d_data_type data_type)
+ enum wined3d_component_type data_type)
{
struct glsl_dst_param glsl_dst;
DWORD mask;
@@ -3443,15 +3439,15 @@ static DWORD shader_glsl_append_dst_ext(struct wined3d_string_buffer *buffer,
{
switch (data_type)
{
- case WINED3D_DATA_FLOAT:
+ case WINED3D_TYPE_FLOAT:
shader_addline(buffer, "%s%s = %s(",
glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
shader_addline(buffer, "%s%s = %sintBitsToFloat(",
glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
shader_addline(buffer, "%s%s = %suintBitsToFloat(",
glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
break;
@@ -4013,7 +4009,7 @@ static void shader_glsl_udiv(const struct wined3d_shader_instruction *ins)
shader_glsl_add_src_param(ins, &ins->src[1], write_mask, &src1_param);
shader_addline(buffer, "%s %% %s);\n", src0_param.param_str, src1_param.param_str);
- shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], WINED3D_DATA_FLOAT);
+ shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], WINED3D_TYPE_FLOAT);
shader_addline(buffer, "tmp0%s);\n", dst_mask);
}
else
@@ -4291,7 +4287,7 @@ static void shader_glsl_bitwise_op(const struct wined3d_shader_instruction *ins)
dst.write_mask = ins->dst[0].write_mask & (WINED3DSP_WRITEMASK_0 << i);
if (tmp_dst && (write_mask = shader_glsl_get_write_mask(&dst, mask_char)))
shader_addline(buffer, "tmp0%s = %sBitsToFloat(", mask_char,
- dst.reg.data_type == WINED3D_DATA_INT ? "int" : "uint");
+ dst.reg.data_type == WINED3D_TYPE_INT ? "int" : "uint");
else if (!(write_mask = shader_glsl_append_dst_ext(buffer, ins, &dst, dst.reg.data_type)))
continue;
@@ -4305,7 +4301,7 @@ static void shader_glsl_bitwise_op(const struct wined3d_shader_instruction *ins)
if (tmp_dst)
{
- shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], WINED3D_DATA_FLOAT);
+ shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], WINED3D_TYPE_FLOAT);
shader_glsl_get_write_mask(&ins->dst[0], mask_char);
shader_addline(buffer, "tmp0%s);\n", mask_char);
}
@@ -5445,7 +5441,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
struct wined3d_string_buffer *buffer = ins->ctx->buffer;
enum wined3d_shader_resource_type resource_type;
struct wined3d_string_buffer *address;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
unsigned int resource_idx, stride;
const char *op, *resource;
DWORD coord_mask;
@@ -5461,7 +5457,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
return;
}
resource = "g";
- data_type = WINED3D_DATA_UINT;
+ data_type = WINED3D_TYPE_UINT;
coord_mask = 1;
stride = reg_maps->tgsm[resource_idx].stride;
}
@@ -5513,7 +5509,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
op = "atomicMax";
else
op = "imageAtomicMax";
- if (data_type != WINED3D_DATA_INT)
+ if (data_type != WINED3D_TYPE_INT)
{
FIXME("Unhandled opcode %#x for unsigned integers.\n", ins->handler_idx);
return;
@@ -5525,7 +5521,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
op = "atomicMin";
else
op = "imageAtomicMin";
- if (data_type != WINED3D_DATA_INT)
+ if (data_type != WINED3D_TYPE_INT)
{
FIXME("Unhandled opcode %#x for unsigned integers.\n", ins->handler_idx);
return;
@@ -5544,7 +5540,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
op = "atomicMax";
else
op = "imageAtomicMax";
- if (data_type != WINED3D_DATA_UINT)
+ if (data_type != WINED3D_TYPE_UINT)
{
FIXME("Unhandled opcode %#x for signed integers.\n", ins->handler_idx);
return;
@@ -5556,7 +5552,7 @@ static void shader_glsl_atomic(const struct wined3d_shader_instruction *ins)
op = "atomicMin";
else
op = "imageAtomicMin";
- if (data_type != WINED3D_DATA_UINT)
+ if (data_type != WINED3D_TYPE_UINT)
{
FIXME("Unhandled opcode %#x for signed integers.\n", ins->handler_idx);
return;
@@ -5640,7 +5636,7 @@ static void shader_glsl_ld_uav(const struct wined3d_shader_instruction *ins)
const struct wined3d_shader_version *version = ®_maps->shader_version;
enum wined3d_shader_resource_type resource_type;
struct glsl_src_param image_coord_param;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
DWORD coord_mask, write_mask;
unsigned int uav_idx;
char dst_swizzle[6];
@@ -5761,7 +5757,7 @@ static void shader_glsl_store_uav(const struct wined3d_shader_instruction *ins)
const struct wined3d_shader_version *version = ®_maps->shader_version;
struct glsl_src_param image_coord_param, image_data_param;
enum wined3d_shader_resource_type resource_type;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
unsigned int uav_idx;
DWORD coord_mask;
@@ -5951,7 +5947,7 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
enum wined3d_shader_resource_type resource_type;
enum wined3d_shader_register_type reg_type;
unsigned int resource_idx, bind_idx, i;
- enum wined3d_data_type dst_data_type;
+ enum wined3d_component_type dst_data_type;
struct glsl_src_param lod_param;
BOOL supports_mipmaps;
char dst_swizzle[6];
@@ -5959,7 +5955,7 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
dst_data_type = ins->dst[0].reg.data_type;
if (ins->flags == WINED3DSI_RESINFO_UINT)
- dst_data_type = WINED3D_DATA_UINT;
+ dst_data_type = WINED3D_TYPE_UINT;
else if (ins->flags)
FIXME("Unhandled flags %#x.\n", ins->flags);
@@ -5987,7 +5983,7 @@ static void shader_glsl_resinfo(const struct wined3d_shader_instruction *ins)
write_mask = shader_glsl_append_dst_ext(buffer, ins, &ins->dst[0], dst_data_type);
shader_glsl_get_swizzle(&ins->src[1], FALSE, write_mask, dst_swizzle);
- if (dst_data_type == WINED3D_DATA_UINT)
+ if (dst_data_type == WINED3D_TYPE_UINT)
shader_addline(buffer, "uvec4(");
else
shader_addline(buffer, "vec4(");
@@ -6040,21 +6036,21 @@ static void shader_glsl_sample_info(const struct wined3d_shader_instruction *ins
const struct wined3d_shader_dst_param *dst = ins->dst;
const struct wined3d_shader_src_param *src = ins->src;
enum wined3d_shader_resource_type resource_type;
- enum wined3d_data_type dst_data_type;
+ enum wined3d_component_type dst_data_type;
unsigned int resource_idx, bind_idx;
char dst_swizzle[6];
DWORD write_mask;
dst_data_type = dst->reg.data_type;
if (ins->flags == WINED3DSI_SAMPLE_INFO_UINT)
- dst_data_type = WINED3D_DATA_UINT;
+ dst_data_type = WINED3D_TYPE_UINT;
else if (ins->flags)
FIXME("Unhandled flags %#x.\n", ins->flags);
write_mask = shader_glsl_append_dst_ext(buffer, ins, dst, dst_data_type);
shader_glsl_get_swizzle(src, FALSE, write_mask, dst_swizzle);
- if (dst_data_type == WINED3D_DATA_UINT)
+ if (dst_data_type == WINED3D_TYPE_UINT)
shader_addline(buffer, "uvec4(");
else
shader_addline(buffer, "vec4(");
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 44879f8b7c4..7c6b1243d79 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -1030,6 +1030,23 @@ static HRESULT shader_scan_output_signature(struct wined3d_shader *shader)
return WINED3D_OK;
}
+static enum wined3d_component_type component_type_from_data_type(enum wined3d_data_type type)
+{
+ switch (type)
+ {
+ case WINED3D_DATA_FLOAT:
+ case WINED3D_DATA_UNORM:
+ case WINED3D_DATA_SNORM:
+ return WINED3D_TYPE_FLOAT;
+ case WINED3D_DATA_INT:
+ return WINED3D_TYPE_INT;
+ case WINED3D_DATA_UINT:
+ return WINED3D_TYPE_UINT;
+ }
+ ERR("Unexpected data type %u.\n", type);
+ return WINED3D_TYPE_FLOAT;
+}
+
/* Note that this does not count the loop register as an address register. */
static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD constf_size)
{
@@ -1128,7 +1145,8 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
break;
}
reg_maps->resource_info[reg_idx].type = semantic->resource_type;
- reg_maps->resource_info[reg_idx].data_type = semantic->resource_data_type;
+ reg_maps->resource_info[reg_idx].data_type =
+ component_type_from_data_type(semantic->resource_data_type);
break;
case WINED3DSPR_UAV:
@@ -1138,7 +1156,8 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
break;
}
reg_maps->uav_resource_info[reg_idx].type = semantic->resource_type;
- reg_maps->uav_resource_info[reg_idx].data_type = semantic->resource_data_type;
+ reg_maps->uav_resource_info[reg_idx].data_type =
+ component_type_from_data_type(semantic->resource_data_type);
if (ins.flags)
FIXME("Ignoring typed UAV flags %#x.\n", ins.flags);
break;
@@ -1270,7 +1289,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
break;
}
reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER;
- reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_UINT;
+ reg_maps->resource_info[reg_idx].data_type = WINED3D_TYPE_UINT;
reg_maps->resource_info[reg_idx].flags = WINED3D_VIEW_BUFFER_RAW;
}
else if (ins.handler_idx == WINED3DSIH_DCL_RESOURCE_STRUCTURED)
@@ -1282,7 +1301,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
break;
}
reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER;
- reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_UINT;
+ reg_maps->resource_info[reg_idx].data_type = WINED3D_TYPE_UINT;
reg_maps->resource_info[reg_idx].flags = 0;
reg_maps->resource_info[reg_idx].stride = ins.declaration.structured_resource.byte_stride / 4;
}
@@ -1356,7 +1375,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
if (ins.flags)
FIXME("Ignoring raw UAV flags %#x.\n", ins.flags);
reg_maps->uav_resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER;
- reg_maps->uav_resource_info[reg_idx].data_type = WINED3D_DATA_UINT;
+ reg_maps->uav_resource_info[reg_idx].data_type = WINED3D_TYPE_UINT;
reg_maps->uav_resource_info[reg_idx].flags = WINED3D_VIEW_BUFFER_RAW;
}
else if (ins.handler_idx == WINED3DSIH_DCL_UAV_STRUCTURED)
@@ -1370,7 +1389,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
if (ins.flags)
FIXME("Ignoring structured UAV flags %#x.\n", ins.flags);
reg_maps->uav_resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_BUFFER;
- reg_maps->uav_resource_info[reg_idx].data_type = WINED3D_DATA_UINT;
+ reg_maps->uav_resource_info[reg_idx].data_type = WINED3D_TYPE_UINT;
reg_maps->uav_resource_info[reg_idx].flags = 0;
reg_maps->uav_resource_info[reg_idx].stride = ins.declaration.structured_resource.byte_stride / 4;
}
@@ -1609,7 +1628,7 @@ static HRESULT shader_get_registers_used(struct wined3d_shader *shader, DWORD co
TRACE("Setting fake 2D resource for 1.x pixelshader.\n");
reg_maps->resource_info[reg_idx].type = WINED3D_SHADER_RESOURCE_TEXTURE_2D;
- reg_maps->resource_info[reg_idx].data_type = WINED3D_DATA_FLOAT;
+ reg_maps->resource_info[reg_idx].data_type = WINED3D_TYPE_FLOAT;
shader_record_sample(reg_maps, reg_idx, reg_idx, reg_idx);
/* texbem is only valid with < 1.4 pixel shaders */
@@ -2442,13 +2461,13 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
case WINED3D_IMMCONST_SCALAR:
switch (reg->data_type)
{
- case WINED3D_DATA_FLOAT:
+ case WINED3D_TYPE_FLOAT:
shader_addline(buffer, "%.8e", *(const float *)reg->u.immconst_data);
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
shader_addline(buffer, "%d", reg->u.immconst_data[0]);
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
shader_addline(buffer, "%u", reg->u.immconst_data[0]);
break;
default:
@@ -2460,17 +2479,17 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
case WINED3D_IMMCONST_VEC4:
switch (reg->data_type)
{
- case WINED3D_DATA_FLOAT:
+ case WINED3D_TYPE_FLOAT:
shader_addline(buffer, "%.8e, %.8e, %.8e, %.8e",
*(const float *)®->u.immconst_data[0], *(const float *)®->u.immconst_data[1],
*(const float *)®->u.immconst_data[2], *(const float *)®->u.immconst_data[3]);
break;
- case WINED3D_DATA_INT:
+ case WINED3D_TYPE_INT:
shader_addline(buffer, "%d, %d, %d, %d",
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
break;
- case WINED3D_DATA_UINT:
+ case WINED3D_TYPE_UINT:
shader_addline(buffer, "%u, %u, %u, %u",
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
diff --git a/dlls/wined3d/shader_sm1.c b/dlls/wined3d/shader_sm1.c
index 0c6bb933174..b57b67b8dcc 100644
--- a/dlls/wined3d/shader_sm1.c
+++ b/dlls/wined3d/shader_sm1.c
@@ -468,7 +468,7 @@ static void shader_parse_src_param(DWORD param, const struct wined3d_shader_src_
{
src->reg.type = ((param & WINED3D_SM1_REGISTER_TYPE_MASK) >> WINED3D_SM1_REGISTER_TYPE_SHIFT)
| ((param & WINED3D_SM1_REGISTER_TYPE_MASK2) >> WINED3D_SM1_REGISTER_TYPE_SHIFT2);
- src->reg.data_type = WINED3D_DATA_FLOAT;
+ src->reg.data_type = WINED3D_TYPE_FLOAT;
src->reg.idx[0].offset = param & WINED3D_SM1_REGISTER_NUMBER_MASK;
src->reg.idx[0].rel_addr = rel_addr;
src->reg.idx[1].offset = ~0U;
@@ -482,7 +482,7 @@ static void shader_parse_dst_param(DWORD param, const struct wined3d_shader_src_
{
dst->reg.type = ((param & WINED3D_SM1_REGISTER_TYPE_MASK) >> WINED3D_SM1_REGISTER_TYPE_SHIFT)
| ((param & WINED3D_SM1_REGISTER_TYPE_MASK2) >> WINED3D_SM1_REGISTER_TYPE_SHIFT2);
- dst->reg.data_type = WINED3D_DATA_FLOAT;
+ dst->reg.data_type = WINED3D_TYPE_FLOAT;
dst->reg.idx[0].offset = param & WINED3D_SM1_REGISTER_NUMBER_MASK;
dst->reg.idx[0].rel_addr = rel_addr;
dst->reg.idx[1].offset = ~0U;
@@ -645,12 +645,12 @@ static void shader_sm1_read_semantic(const DWORD **ptr, struct wined3d_shader_se
{
semantic->resource_type = resource_type_table[resource_type];
}
- semantic->resource_data_type = WINED3D_DATA_FLOAT;
+ semantic->resource_data_type = WINED3D_TYPE_FLOAT;
shader_parse_dst_param(dst_token, NULL, &semantic->reg);
}
static void shader_sm1_read_immconst(const DWORD **ptr, struct wined3d_shader_src_param *src_param,
- enum wined3d_immconst_type type, enum wined3d_data_type data_type)
+ enum wined3d_immconst_type type, enum wined3d_component_type data_type)
{
unsigned int count = type == WINED3D_IMMCONST_VEC4 ? 4 : 1;
src_param->reg.type = WINED3DSPR_IMMCONST;
@@ -761,17 +761,17 @@ static void shader_sm1_read_instruction(void *data, const DWORD **ptr, struct wi
else if (ins->handler_idx == WINED3DSIH_DEF)
{
shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr);
- shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_DATA_FLOAT);
+ shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_TYPE_FLOAT);
}
else if (ins->handler_idx == WINED3DSIH_DEFB)
{
shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr);
- shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_SCALAR, WINED3D_DATA_UINT);
+ shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_SCALAR, WINED3D_TYPE_UINT);
}
else if (ins->handler_idx == WINED3DSIH_DEFI)
{
shader_sm1_read_dst_param(priv, &p, &priv->dst_param, &priv->dst_rel_addr);
- shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_DATA_INT);
+ shader_sm1_read_immconst(&p, &priv->src_param[0], WINED3D_IMMCONST_VEC4, WINED3D_TYPE_INT);
}
else
{
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index acde7a56d1c..7508dda4e07 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -517,15 +517,15 @@ static const enum wined3d_data_type data_type_table[] =
};
static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
- enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param);
+ enum wined3d_component_type data_type, struct wined3d_shader_src_param *src_param);
static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
- enum wined3d_data_type data_type, struct wined3d_shader_dst_param *dst_param);
+ enum wined3d_component_type data_type, struct wined3d_shader_dst_param *dst_param);
static void shader_sm4_read_conditional_op(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &priv->src_param[0]);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &priv->src_param[0]);
ins->flags = (opcode_token & WINED3D_SM4_CONDITIONAL_NZ) ?
WINED3D_SHADER_CONDITIONAL_OP_NZ : WINED3D_SHADER_CONDITIONAL_OP_Z;
}
@@ -579,7 +579,7 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
ins->declaration.semantic.resource_type = resource_type_table[resource_type];
}
uav = opcode != WINED3D_SM4_OP_DCL_RESOURCE;
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.semantic.reg);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &ins->declaration.semantic.reg);
components = *tokens++;
if ((components & 0xfff0) != (components & 0xf) * 0x1110)
@@ -589,7 +589,7 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
if (!data_type || (data_type >= ARRAY_SIZE(data_type_table)))
{
FIXME("Unhandled data type %#x.\n", data_type);
- ins->declaration.semantic.resource_data_type = WINED3D_DATA_FLOAT;
+ ins->declaration.semantic.resource_data_type = WINED3D_TYPE_FLOAT;
}
else
{
@@ -604,7 +604,7 @@ static void shader_sm4_read_dcl_constant_buffer(struct wined3d_shader_instructio
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.src);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT, &ins->declaration.src);
if (opcode_token & WINED3D_SM4_INDEX_TYPE_MASK)
ins->flags |= WINED3DSI_INDEXED_DYNAMIC;
}
@@ -616,14 +616,14 @@ static void shader_sm4_read_dcl_sampler(struct wined3d_shader_instruction *ins,
ins->flags = (opcode_token & WINED3D_SM4_SAMPLER_MODE_MASK) >> WINED3D_SM4_SAMPLER_MODE_SHIFT;
if (ins->flags & ~WINED3D_SM4_SAMPLER_COMPARISON)
FIXME("Unhandled sampler mode %#x.\n", ins->flags);
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &ins->declaration.dst);
}
static void shader_sm4_read_dcl_index_range(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT,
&ins->declaration.index_range.first_register);
ins->declaration.index_range.last_register = *tokens;
}
@@ -680,14 +680,14 @@ static void shader_sm4_read_declaration_dst(struct wined3d_shader_instruction *i
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT, &ins->declaration.dst);
}
static void shader_sm4_read_declaration_register_semantic(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT,
&ins->declaration.register_semantic.reg);
ins->declaration.register_semantic.sysval_semantic = *tokens;
}
@@ -697,7 +697,7 @@ static void shader_sm4_read_dcl_input_ps(struct wined3d_shader_instruction *ins,
struct wined3d_sm4_data *priv)
{
ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT;
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT, &ins->declaration.dst);
}
static void shader_sm4_read_dcl_input_ps_siv(struct wined3d_shader_instruction *ins,
@@ -705,7 +705,7 @@ static void shader_sm4_read_dcl_input_ps_siv(struct wined3d_shader_instruction *
struct wined3d_sm4_data *priv)
{
ins->flags = (opcode_token & WINED3D_SM4_INTERPOLATION_MODE_MASK) >> WINED3D_SM4_INTERPOLATION_MODE_SHIFT;
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT,
&ins->declaration.register_semantic.reg);
ins->declaration.register_semantic.sysval_semantic = *tokens;
}
@@ -731,7 +731,7 @@ static void shader_sm5_read_fcall(struct wined3d_shader_instruction *ins,
struct wined3d_sm4_data *priv)
{
priv->src_param[0].reg.u.fp_body_idx = *tokens++;
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &priv->src_param[0]);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &priv->src_param[0]);
}
static void shader_sm5_read_dcl_function_body(struct wined3d_shader_instruction *ins,
@@ -812,7 +812,7 @@ static void shader_sm5_read_dcl_uav_raw(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &ins->declaration.dst);
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
}
@@ -820,7 +820,7 @@ static void shader_sm5_read_dcl_uav_structured(struct wined3d_shader_instruction
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT,
&ins->declaration.structured_resource.reg);
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
ins->declaration.structured_resource.byte_stride = *tokens;
@@ -832,7 +832,7 @@ static void shader_sm5_read_dcl_tgsm_raw(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT, &ins->declaration.tgsm_raw.reg);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT, &ins->declaration.tgsm_raw.reg);
ins->declaration.tgsm_raw.byte_count = *tokens;
if (ins->declaration.tgsm_raw.byte_count % 4)
FIXME("Byte count %u is not multiple of 4.\n", ins->declaration.tgsm_raw.byte_count);
@@ -842,7 +842,7 @@ static void shader_sm5_read_dcl_tgsm_structured(struct wined3d_shader_instructio
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_FLOAT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_FLOAT,
&ins->declaration.tgsm_structured.reg);
ins->declaration.tgsm_structured.byte_stride = *tokens++;
ins->declaration.tgsm_structured.structure_count = *tokens;
@@ -854,7 +854,7 @@ static void shader_sm5_read_dcl_resource_structured(struct wined3d_shader_instru
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT,
&ins->declaration.structured_resource.reg);
ins->declaration.structured_resource.byte_stride = *tokens;
if (ins->declaration.structured_resource.byte_stride % 4)
@@ -865,7 +865,7 @@ static void shader_sm5_read_dcl_resource_raw(struct wined3d_shader_instruction *
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_TYPE_UINT, &ins->declaration.dst);
}
static void shader_sm5_read_sync(struct wined3d_shader_instruction *ins,
@@ -1196,23 +1196,23 @@ static void map_register(const struct wined3d_sm4_data *priv, struct wined3d_sha
}
}
-static enum wined3d_data_type map_data_type(char t)
+static enum wined3d_component_type map_data_type(char t)
{
switch (t)
{
case 'f':
- return WINED3D_DATA_FLOAT;
+ return WINED3D_TYPE_FLOAT;
case 'i':
- return WINED3D_DATA_INT;
+ return WINED3D_TYPE_INT;
case 'u':
case 'O':
case 'R':
case 'S':
case 'U':
- return WINED3D_DATA_UINT;
+ return WINED3D_TYPE_UINT;
default:
ERR("Invalid data type '%c'.\n", t);
- return WINED3D_DATA_FLOAT;
+ return WINED3D_TYPE_FLOAT;
}
}
@@ -1376,7 +1376,7 @@ static BOOL shader_sm4_read_reg_idx(struct wined3d_sm4_data *priv, const DWORD *
reg_idx->offset = *(*ptr)++;
else
reg_idx->offset = 0;
- shader_sm4_read_src_param(priv, ptr, end, WINED3D_DATA_INT, rel_addr);
+ shader_sm4_read_src_param(priv, ptr, end, WINED3D_TYPE_INT, rel_addr);
}
else
{
@@ -1388,7 +1388,7 @@ static BOOL shader_sm4_read_reg_idx(struct wined3d_sm4_data *priv, const DWORD *
}
static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
- enum wined3d_data_type data_type, struct wined3d_shader_register *param,
+ enum wined3d_component_type data_type, struct wined3d_shader_register *param,
enum wined3d_shader_src_modifier *modifier)
{
enum wined3d_sm4_register_type register_type;
@@ -1520,7 +1520,7 @@ static BOOL shader_sm4_read_param(struct wined3d_sm4_data *priv, const DWORD **p
}
static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
- enum wined3d_data_type data_type, struct wined3d_shader_src_param *src_param)
+ enum wined3d_component_type data_type, struct wined3d_shader_src_param *src_param)
{
DWORD token;
@@ -1571,7 +1571,7 @@ static BOOL shader_sm4_read_src_param(struct wined3d_sm4_data *priv, const DWORD
}
static BOOL shader_sm4_read_dst_param(struct wined3d_sm4_data *priv, const DWORD **ptr, const DWORD *end,
- enum wined3d_data_type data_type, struct wined3d_shader_dst_param *dst_param)
+ enum wined3d_component_type data_type, struct wined3d_shader_dst_param *dst_param)
{
enum wined3d_shader_src_modifier modifier;
DWORD token;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b65288dc415..6aa1d497df1 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -933,7 +933,7 @@ struct wined3d_shader_version
struct wined3d_shader_resource_info
{
enum wined3d_shader_resource_type type;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
unsigned int flags;
unsigned int stride;
};
@@ -1071,7 +1071,7 @@ struct wined3d_shader_register_index
struct wined3d_shader_register
{
enum wined3d_shader_register_type type;
- enum wined3d_data_type data_type;
+ enum wined3d_component_type data_type;
struct wined3d_shader_register_index idx[2];
enum wined3d_immconst_type immconst_type;
union
--
2.16.4
June 20, 2018
[PATCH v2 2/5] wined3d: Get rid of unnecessary enum wined3d_data_type values.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
v2: Restore _UNORM and _SNORM for semantics / declarations.
dlls/wined3d/glsl_shader.c | 8 --------
dlls/wined3d/shader.c | 4 ----
dlls/wined3d/shader_sm4.c | 44 ++++++++++++++++++------------------------
dlls/wined3d/wined3d_private.h | 4 ----
4 files changed, 19 insertions(+), 41 deletions(-)
diff --git a/dlls/wined3d/glsl_shader.c b/dlls/wined3d/glsl_shader.c
index 86259ae4755..f1f3020d53d 100644
--- a/dlls/wined3d/glsl_shader.c
+++ b/dlls/wined3d/glsl_shader.c
@@ -3093,8 +3093,6 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
case WINED3D_DATA_INT:
sprintf(register_name, "%#x", reg->u.immconst_data[0]);
break;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
sprintf(register_name, "%#xu", reg->u.immconst_data[0]);
break;
@@ -3129,8 +3127,6 @@ static void shader_glsl_get_register_name(const struct wined3d_shader_register *
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
break;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
sprintf(register_name, "uvec4(%#xu, %#xu, %#xu, %#xu)",
reg->u.immconst_data[0], reg->u.immconst_data[1],
@@ -3342,8 +3338,6 @@ static void shader_glsl_sprintf_cast(struct wined3d_string_buffer *dst_param, co
case WINED3D_DATA_INT:
string_buffer_sprintf(dst_param, "floatBitsToInt(%s)", src_param);
return;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
string_buffer_sprintf(dst_param, "floatBitsToUint(%s)", src_param);
return;
@@ -3457,8 +3451,6 @@ static DWORD shader_glsl_append_dst_ext(struct wined3d_string_buffer *buffer,
shader_addline(buffer, "%s%s = %sintBitsToFloat(",
glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
break;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
shader_addline(buffer, "%s%s = %suintBitsToFloat(",
glsl_dst.reg_name, glsl_dst.mask_str, shift_glsl_tab[dst->shift]);
diff --git a/dlls/wined3d/shader.c b/dlls/wined3d/shader.c
index 20d4f0773dd..44879f8b7c4 100644
--- a/dlls/wined3d/shader.c
+++ b/dlls/wined3d/shader.c
@@ -2448,8 +2448,6 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
case WINED3D_DATA_INT:
shader_addline(buffer, "%d", reg->u.immconst_data[0]);
break;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
shader_addline(buffer, "%u", reg->u.immconst_data[0]);
break;
@@ -2472,8 +2470,6 @@ static void shader_dump_register(struct wined3d_string_buffer *buffer,
reg->u.immconst_data[0], reg->u.immconst_data[1],
reg->u.immconst_data[2], reg->u.immconst_data[3]);
break;
- case WINED3D_DATA_RESOURCE:
- case WINED3D_DATA_SAMPLER:
case WINED3D_DATA_UINT:
shader_addline(buffer, "%u, %u, %u, %u",
reg->u.immconst_data[0], reg->u.immconst_data[1],
diff --git a/dlls/wined3d/shader_sm4.c b/dlls/wined3d/shader_sm4.c
index b119e8feaa8..acde7a56d1c 100644
--- a/dlls/wined3d/shader_sm4.c
+++ b/dlls/wined3d/shader_sm4.c
@@ -565,8 +565,8 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
{
enum wined3d_sm4_resource_type resource_type;
enum wined3d_sm4_data_type data_type;
- enum wined3d_data_type reg_data_type;
DWORD components;
+ BOOL uav;
resource_type = (opcode_token & WINED3D_SM4_RESOURCE_TYPE_MASK) >> WINED3D_SM4_RESOURCE_TYPE_SHIFT;
if (!resource_type || (resource_type >= ARRAY_SIZE(resource_type_table)))
@@ -578,8 +578,8 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
{
ins->declaration.semantic.resource_type = resource_type_table[resource_type];
}
- reg_data_type = opcode == WINED3D_SM4_OP_DCL_RESOURCE ? WINED3D_DATA_RESOURCE : WINED3D_DATA_UAV;
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], reg_data_type, &ins->declaration.semantic.reg);
+ uav = opcode != WINED3D_SM4_OP_DCL_RESOURCE;
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.semantic.reg);
components = *tokens++;
if ((components & 0xfff0) != (components & 0xf) * 0x1110)
@@ -596,7 +596,7 @@ static void shader_sm4_read_dcl_resource(struct wined3d_shader_instruction *ins,
ins->declaration.semantic.resource_data_type = data_type_table[data_type];
}
- if (reg_data_type == WINED3D_DATA_UAV)
+ if (uav)
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
}
@@ -616,14 +616,14 @@ static void shader_sm4_read_dcl_sampler(struct wined3d_shader_instruction *ins,
ins->flags = (opcode_token & WINED3D_SM4_SAMPLER_MODE_MASK) >> WINED3D_SM4_SAMPLER_MODE_SHIFT;
if (ins->flags & ~WINED3D_SM4_SAMPLER_COMPARISON)
FIXME("Unhandled sampler mode %#x.\n", ins->flags);
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_SAMPLER, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
}
static void shader_sm4_read_dcl_index_range(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_OPAQUE,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
&ins->declaration.index_range.first_register);
ins->declaration.index_range.last_register = *tokens;
}
@@ -731,7 +731,7 @@ static void shader_sm5_read_fcall(struct wined3d_shader_instruction *ins,
struct wined3d_sm4_data *priv)
{
priv->src_param[0].reg.u.fp_body_idx = *tokens++;
- shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_OPAQUE, &priv->src_param[0]);
+ shader_sm4_read_src_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &priv->src_param[0]);
}
static void shader_sm5_read_dcl_function_body(struct wined3d_shader_instruction *ins,
@@ -812,7 +812,7 @@ static void shader_sm5_read_dcl_uav_raw(struct wined3d_shader_instruction *ins,
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UAV, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
}
@@ -820,7 +820,7 @@ static void shader_sm5_read_dcl_uav_structured(struct wined3d_shader_instruction
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UAV,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
&ins->declaration.structured_resource.reg);
ins->flags = (opcode_token & WINED3D_SM5_UAV_FLAGS_MASK) >> WINED3D_SM5_UAV_FLAGS_SHIFT;
ins->declaration.structured_resource.byte_stride = *tokens;
@@ -854,7 +854,7 @@ static void shader_sm5_read_dcl_resource_structured(struct wined3d_shader_instru
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_RESOURCE,
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT,
&ins->declaration.structured_resource.reg);
ins->declaration.structured_resource.byte_stride = *tokens;
if (ins->declaration.structured_resource.byte_stride % 4)
@@ -865,7 +865,7 @@ static void shader_sm5_read_dcl_resource_raw(struct wined3d_shader_instruction *
DWORD opcode, DWORD opcode_token, const DWORD *tokens, unsigned int token_count,
struct wined3d_sm4_data *priv)
{
- shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_RESOURCE, &ins->declaration.dst);
+ shader_sm4_read_dst_param(priv, &tokens, &tokens[token_count], WINED3D_DATA_UINT, &ins->declaration.dst);
}
static void shader_sm5_read_sync(struct wined3d_shader_instruction *ins,
@@ -875,15 +875,13 @@ static void shader_sm5_read_sync(struct wined3d_shader_instruction *ins,
ins->flags = (opcode_token & WINED3D_SM5_SYNC_FLAGS_MASK) >> WINED3D_SM5_SYNC_FLAGS_SHIFT;
}
-/*
- * f -> WINED3D_DATA_FLOAT
- * i -> WINED3D_DATA_INT
- * u -> WINED3D_DATA_UINT
- * O -> WINED3D_DATA_OPAQUE
- * R -> WINED3D_DATA_RESOURCE
- * S -> WINED3D_DATA_SAMPLER
- * U -> WINED3D_DATA_UAV
- */
+/* f -> FLOAT
+ * i -> INT
+ * u -> UINT
+ * O -> OPAQUE
+ * R -> RESOURCE
+ * S -> SAMPLER
+ * U -> UAV */
static const struct wined3d_sm4_opcode_info opcode_table[] =
{
{WINED3D_SM4_OP_ADD, WINED3DSIH_ADD, "f", "ff"},
@@ -1207,15 +1205,11 @@ static enum wined3d_data_type map_data_type(char t)
case 'i':
return WINED3D_DATA_INT;
case 'u':
- return WINED3D_DATA_UINT;
case 'O':
- return WINED3D_DATA_OPAQUE;
case 'R':
- return WINED3D_DATA_RESOURCE;
case 'S':
- return WINED3D_DATA_SAMPLER;
case 'U':
- return WINED3D_DATA_UAV;
+ return WINED3D_DATA_UINT;
default:
ERR("Invalid data type '%c'.\n", t);
return WINED3D_DATA_FLOAT;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 9aa70817f5d..b65288dc415 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -504,13 +504,9 @@ enum wined3d_data_type
{
WINED3D_DATA_FLOAT,
WINED3D_DATA_INT,
- WINED3D_DATA_RESOURCE,
- WINED3D_DATA_SAMPLER,
- WINED3D_DATA_UAV,
WINED3D_DATA_UINT,
WINED3D_DATA_UNORM,
WINED3D_DATA_SNORM,
- WINED3D_DATA_OPAQUE,
};
enum wined3d_immconst_type
--
2.16.4
June 20, 2018
[PATCH v2 1/5] d3dx9/tests: Add initial tests for ID3DXFont::DrawText().
by Matteo Bruni
From: Kieran Duggan <kieranduggan15(a)gmail.com>
Signed-off-by: Kieran Duggan <kieranduggan15(a)gmail.com>
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
v2: Add missing todo_wine.
dlls/d3dx9_36/tests/core.c | 84 +++++++++++++++++++++++++++++++++++-----------
1 file changed, 65 insertions(+), 19 deletions(-)
diff --git a/dlls/d3dx9_36/tests/core.c b/dlls/d3dx9_36/tests/core.c
index 75d33c1e0dc..91e458bbb88 100644
--- a/dlls/d3dx9_36/tests/core.c
+++ b/dlls/d3dx9_36/tests/core.c
@@ -305,23 +305,28 @@ static void test_ID3DXSprite(IDirect3DDevice9 *device)
static void test_ID3DXFont(IDirect3DDevice9 *device)
{
- D3DXFONT_DESCA desc;
- ID3DXFont *font;
- HRESULT hr;
- int ref;
- int i;
- static const struct {
- INT font_height;
- UINT expected_size;
- DWORD expected_levels;
- } texture_tests[] = {
+ static const WCHAR testW[] = {'t','e','s','t',0};
+ static const struct
+ {
+ int font_height;
+ unsigned int expected_size;
+ unsigned int expected_levels;
+ }
+ tests[] =
+ {
{ 6, 128, 4 },
{ 8, 128, 4 },
{ 10, 256, 5 },
{ 12, 256, 5 },
- { 72, 256, 8 }
+ { 72, 256, 8 },
};
-
+ const unsigned int size = ARRAY_SIZE(testW);
+ D3DXFONT_DESCA desc;
+ ID3DXSprite *sprite;
+ int ref, i, height;
+ ID3DXFont *font;
+ HRESULT hr;
+ RECT rect;
/* D3DXCreateFont */
ref = get_ref((IUnknown*)device);
@@ -463,8 +468,6 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
/* ID3DXFont_PreloadText */
hr = D3DXCreateFontA(device, 12, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
if(SUCCEEDED(hr)) {
- const WCHAR testW[] = {'t','e','s','t',0};
-
todo_wine {
hr = ID3DXFont_PreloadTextA(font, NULL, -1);
ok(hr == D3DERR_INVALIDCALL, "ID3DXFont_PreloadTextA returned %#x, expected %#x\n", hr, D3DERR_INVALIDCALL);
@@ -552,7 +555,8 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
check_release((IUnknown*)font, 0);
} else skip("Failed to create a ID3DXFont object\n");
- for(i = 0; i < ARRAY_SIZE(texture_tests); i++) {
+ for (i = 0; i < ARRAY_SIZE(tests); ++i)
+ {
HDC hdc;
DWORD ret;
HRESULT hr;
@@ -560,7 +564,8 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
char c = 'a';
IDirect3DTexture9 *texture;
- hr = D3DXCreateFontA(device, texture_tests[i].font_height, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
+ hr = D3DXCreateFontA(device, tests[i].font_height, 0, FW_DONTCARE, 0, FALSE, DEFAULT_CHARSET,
+ OUT_DEFAULT_PRECIS, DEFAULT_QUALITY, DEFAULT_PITCH, "Arial", &font);
if(FAILED(hr)) {
skip("Failed to create a ID3DXFont object\n");
continue;
@@ -578,17 +583,58 @@ static void test_ID3DXFont(IDirect3DDevice9 *device)
D3DSURFACE_DESC desc;
levels = IDirect3DTexture9_GetLevelCount(texture);
- ok(levels == texture_tests[i].expected_levels, "Got levels %u, expected %u\n", levels, texture_tests[i].expected_levels);
+ ok(levels == tests[i].expected_levels, "Got levels %u, expected %u\n",
+ levels, tests[i].expected_levels);
hr = IDirect3DTexture9_GetLevelDesc(texture, 0, &desc);
ok(hr == D3D_OK, "IDirect3DTexture9_GetLevelDesc failed\n");
ok(desc.Format == D3DFMT_A8R8G8B8, "Got format %#x, expected %#x\n", desc.Format, D3DFMT_A8R8G8B8);
ok(desc.Usage == 0, "Got usage %#x, expected %#x\n", desc.Usage, 0);
- ok(desc.Width == texture_tests[i].expected_size, "Got width %u, expected %u\n", desc.Width, texture_tests[i].expected_size);
- ok(desc.Height == texture_tests[i].expected_size, "Got height %u, expected %u\n", desc.Height, texture_tests[i].expected_size);
+ ok(desc.Width == tests[i].expected_size, "Got width %u, expected %u\n",
+ desc.Width, tests[i].expected_size);
+ ok(desc.Height == tests[i].expected_size, "Got height %u, expected %u\n",
+ desc.Height, tests[i].expected_size);
ok(desc.Pool == D3DPOOL_MANAGED, "Got pool %u, expected %u\n", desc.Pool, D3DPOOL_MANAGED);
IDirect3DTexture9_Release(texture);
}
+
+ /* ID3DXFontImpl_DrawText */
+ D3DXCreateSprite(device, &sprite);
+ SetRect(&rect, 0, 0, 640, 480);
+
+ IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xff000000, 1.0f, 0);
+
+ IDirect3DDevice9_BeginScene(device);
+ hr = ID3DXSprite_Begin(sprite, D3DXSPRITE_ALPHABLEND);
+ ok (hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+
+ todo_wine
+ {
+ height = ID3DXFont_DrawTextW(font, sprite, testW, -1, &rect, DT_TOP, 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_TOP, 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_RIGHT, 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect, DT_LEFT | DT_NOCLIP,
+ 0xffffffff);
+ ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ }
+
+ SetRect(&rect, 0, 0, 0, 0);
+ height = ID3DXFont_DrawTextW(font, sprite, testW, size, &rect,
+ DT_LEFT | DT_CALCRECT, 0xffffffff);
+ todo_wine ok(height == tests[i].font_height, "Got unexpected height %u.\n", height);
+ ok(!rect.left, "Got unexpected rect left %d.\n", rect.left);
+ ok(!rect.top, "Got unexpected rect top %d.\n", rect.top);
+ todo_wine ok(rect.right, "Got unexpected rect right %d.\n", rect.right);
+ todo_wine ok(rect.bottom == tests[i].font_height, "Got unexpected rect bottom %d.\n", rect.bottom);
+
+ hr = ID3DXSprite_End(sprite);
+ ok (hr == D3D_OK, "Got unexpected hr %#x.\n", hr);
+ IDirect3DDevice9_EndScene(device);
+ ID3DXSprite_Release(sprite);
+
ID3DXFont_Release(font);
}
}
--
2.16.4
June 20, 2018
[PATCH resend] winedbg: Suppress all message boxes if ShowCrashDialog is disabled.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
The only message box shown by this function is the aforementioned
'failed to attach to process' error, but in general the user probably
doesn't want any windows to be shown if ShowCrashDialog is disabled.
programs/winedbg/crashdlg.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/programs/winedbg/crashdlg.c b/programs/winedbg/crashdlg.c
index 5c913ff..a925378 100644
--- a/programs/winedbg/crashdlg.c
+++ b/programs/winedbg/crashdlg.c
@@ -34,13 +34,18 @@
static char *crash_log;
-int msgbox_res_id(HWND hwnd, UINT textId, UINT captionId, UINT uType)
+int msgbox_res_id(HWND hwnd, UINT textid, UINT captionid, UINT type)
{
- WCHAR caption[256];
- WCHAR text[256];
- LoadStringW(GetModuleHandleW(NULL), captionId, caption, ARRAY_SIZE(caption));
- LoadStringW(GetModuleHandleW(NULL), textId, text, ARRAY_SIZE(text));
- return MessageBoxW(hwnd, text, caption, uType);
+ if (DBG_IVAR(ShowCrashDialog))
+ {
+ WCHAR caption[256];
+ WCHAR text[256];
+ LoadStringW(GetModuleHandleW(NULL), captionid, caption, ARRAY_SIZE(caption));
+ LoadStringW(GetModuleHandleW(NULL), textid, text, ARRAY_SIZE(text));
+ return MessageBoxW(hwnd, text, caption, type);
+ }
+
+ return IDCANCEL;
}
static WCHAR *get_program_name(HANDLE hProcess)
--
2.7.4
June 20, 2018
[PATCH] wininet/tests: Use the correct array size in a notification_data test
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/wininet/tests/http.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wininet/tests/http.c b/dlls/wininet/tests/http.c
index 72121d8b77..0524ddf3fd 100644
--- a/dlls/wininet/tests/http.c
+++ b/dlls/wininet/tests/http.c
@@ -6558,7 +6558,7 @@ static const struct notification_data notification_data[] = {
},
{
async_send_request_ex_test2,
- sizeof(async_send_request_ex_test)/sizeof(async_send_request_ex_test[0]),
+ ARRAY_SIZE(async_send_request_ex_test2),
"POST",
"test.winehq.org",
"tests/post.php"
--
2.14.4
June 20, 2018
[PATCH 2/2] msvcrt/tests: Use the available ARRAY_SIZE() macro
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/msvcrt/tests/cpp.c | 6 +++---
dlls/msvcrt/tests/dir.c | 16 ++++++++--------
dlls/msvcrt/tests/file.c | 23 +++++++++++-----------
dlls/msvcrt/tests/locale.c | 6 +++---
dlls/msvcrt/tests/misc.c | 4 ++--
dlls/msvcrt/tests/printf.c | 4 ++--
dlls/msvcrt/tests/string.c | 48 +++++++++++++++++++++++-----------------------
7 files changed, 53 insertions(+), 54 deletions(-)
diff --git a/dlls/msvcrt/tests/cpp.c b/dlls/msvcrt/tests/cpp.c
index cf5e4c7d60..07b49ae755 100644
--- a/dlls/msvcrt/tests/cpp.c
+++ b/dlls/msvcrt/tests/cpp.c
@@ -1108,8 +1108,8 @@ static void test_demangle_datatype(void)
{ "?AV?$CDB_GEN_BIG_ENUM_FLAG(a)W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", "?AV?$CDB_GEN_BIG_ENUM_FLAG(a)W4CDB_WYSIWYG_BITS_ENUM@@$01@@@", FALSE},
/* { "?AV?$CDB_GEN_BIG_ENUM_FLAG(a)W4CDB_WYSIWYG_BITS_ENUM@@$011@@@", "?AV?$CDB_GEN_BIG_ENUM_FLAG(a)W4CDB_WYSIWYG_BITS_ENUM@@$011@@@",FALSE}, */
};
- int i, num_test = (sizeof(demangle)/sizeof(struct _demangle));
-
+ int i, num_test = ARRAY_SIZE(demangle);
+
for (i = 0; i < num_test; i++)
{
name = p__unDName(0, demangle[i].mangled, 0, pmalloc, pfree, 0x2800);
@@ -1326,7 +1326,7 @@ static void test_demangle(void)
/* 130 */ {"??_E?$TStrArray@$$BY0BAA(a)D$0BA@@@UAEPAXI(a)Z",
"public: virtual void * __thiscall TStrArray<char [256],16>::`vector deleting destructor'(unsigned int)"},
};
- int i, num_test = (sizeof(test)/sizeof(test[0]));
+ int i, num_test = ARRAY_SIZE(test);
char* name;
for (i = 0; i < num_test; i++)
diff --git a/dlls/msvcrt/tests/dir.c b/dlls/msvcrt/tests/dir.c
index a29d32b9d3..210cf3983c 100644
--- a/dlls/msvcrt/tests/dir.c
+++ b/dlls/msvcrt/tests/dir.c
@@ -97,7 +97,7 @@ static void test_makepath(void)
unsigned int i, n;
- for (i = 0; i < sizeof(makepath_cases)/sizeof(makepath_cases[0]); ++i)
+ for (i = 0; i < ARRAY_SIZE(makepath_cases); ++i)
{
const makepath_case* p = &makepath_cases[i];
@@ -253,7 +253,7 @@ static void test_makepath_s(void)
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
/* Test with the normal _makepath cases. */
- for (i = 0; i < sizeof(makepath_cases)/sizeof(makepath_cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(makepath_cases); i++)
{
const makepath_case *p = makepath_cases + i;
@@ -296,7 +296,7 @@ static void test_makepath_s(void)
}
/* Try insufficient length cases. */
- for (i = 0; i < sizeof(makepath_s_cases)/sizeof(makepath_s_cases[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(makepath_s_cases); i++)
{
const makepath_s_case *p = makepath_s_cases + i;
@@ -457,12 +457,12 @@ static void test_searchenv(void)
ok(path_len, "GetTempPath failed\n");
memcpy(path, tmppath, path_len);
- for(i=0; i<sizeof(dirs)/sizeof(*dirs); i++) {
+ for (i=0; i<ARRAY_SIZE(dirs); i++) {
strcpy(path+path_len, dirs[i]);
ok(!mkdir(path), "mkdir failed (dir = %s)\n", path);
}
- for(i=0; i<sizeof(files)/sizeof(*files); i++) {
+ for (i=0; i<ARRAY_SIZE(files); i++) {
strcpy(path+path_len, files[i]);
tmp_file = fopen(path, "wb");
ok(tmp_file != NULL, "fopen failed (file = %s)\n", path);
@@ -471,7 +471,7 @@ static void test_searchenv(void)
strcpy(env1, "TEST_PATH=");
strcpy(env2, "TEST_PATH=;");
- for(i=1; i<sizeof(dirs)/sizeof(*dirs); i++) {
+ for (i=1; i<ARRAY_SIZE(dirs); i++) {
strcat(env1, tmppath);
strcat(env1, dirs[i]);
strcat(env1, ";");
@@ -599,12 +599,12 @@ static void test_searchenv(void)
putenv("TEST_PATH=");
- for(i=sizeof(files)/sizeof(*files)-1; i>=0; i--) {
+ for (i=ARRAY_SIZE(files)-1; i>=0; i--) {
strcpy(path+path_len, files[i]);
ok(!remove(path), "remove failed (file = %s)\n", path);
}
- for(i=sizeof(dirs)/sizeof(*dirs)-1; i>=0; i--) {
+ for (i=ARRAY_SIZE(dirs)-1; i>=0; i--) {
strcpy(path+path_len, dirs[i]);
ok(!rmdir(path), "rmdir failed (dir = %s)\n", path);
}
diff --git a/dlls/msvcrt/tests/file.c b/dlls/msvcrt/tests/file.c
index 136ee1563e..fe62d5c385 100644
--- a/dlls/msvcrt/tests/file.c
+++ b/dlls/msvcrt/tests/file.c
@@ -144,7 +144,7 @@ static void test_fileops( void )
write (fd, outbuffer, sizeof (outbuffer));
close (fd);
- for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
+ for (bufmode=0; bufmode < ARRAY_SIZE(bufmodes); bufmode++)
{
fd = open ("fdopen.tst", O_RDONLY | O_BINARY);
file = fdopen (fd, "rb");
@@ -195,13 +195,13 @@ static void test_fileops( void )
}
fd = open ("fdopen.tst", O_RDONLY | O_TEXT);
file = fdopen (fd, "rt"); /* open in TEXT mode */
- ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) !=0,"fgetws failed unexpected\n");
- ok(fgetws(wbuffer,sizeof(wbuffer)/sizeof(wbuffer[0]),file) ==0,"fgetws didn't signal EOF\n");
+ ok(fgetws(wbuffer,ARRAY_SIZE(wbuffer),file) !=0,"fgetws failed unexpected\n");
+ ok(fgetws(wbuffer,ARRAY_SIZE(wbuffer),file) ==0,"fgetws didn't signal EOF\n");
ok(feof(file) !=0,"feof doesn't signal EOF\n");
rewind(file);
ok(fgetws(wbuffer,strlen(outbuffer),file) !=0,"fgetws failed unexpected\n");
ok(lstrlenW(wbuffer) == (lstrlenA(outbuffer) -1),"fgetws didn't read right size\n");
- ok(fgetws(wbuffer,sizeof(outbuffer)/sizeof(outbuffer[0]),file) !=0,"fgets failed unexpected\n");
+ ok(fgetws(wbuffer,ARRAY_SIZE(outbuffer),file) !=0,"fgets failed unexpected\n");
ok(lstrlenW(wbuffer) == 1,"fgets dropped chars\n");
fclose (file);
@@ -624,7 +624,7 @@ static void test_flsbuf( void )
static const int bufmodes[] = {_IOFBF,_IONBF};
tempf=_tempnam(".","wne");
- for (bufmode=0; bufmode < sizeof(bufmodes)/sizeof(bufmodes[0]); bufmode++)
+ for (bufmode=0; bufmode < ARRAY_SIZE(bufmodes); bufmode++)
{
tempfh = fopen(tempf,"wb");
setvbuf(tempfh,NULL,bufmodes[bufmode],2048);
@@ -878,8 +878,7 @@ static void test_fgetwc_locale(const char* text, const char* locale, int codepag
{
/* mbstowcs rejects invalid multibyte sequence,
so we use MultiByteToWideChar here. */
- ret = MultiByteToWideChar(codepage, 0, text, -1,
- wtextW, sizeof(wtextW)/sizeof(wtextW[0]));
+ ret = MultiByteToWideChar(codepage, 0, text, -1, wtextW, ARRAY_SIZE(wtextW));
ok(ret > 0, "MultiByteToWideChar failed\n");
}
else
@@ -910,7 +909,7 @@ static void test_fgetwc_locale(const char* text, const char* locale, int codepag
tempfh = fopen(tempfile, "rb");
ok(tempfh != NULL, "can't open tempfile\n");
- for (i = 0; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(wchar_text); i++)
{
ch = fgetwc(tempfh);
ok(ch == wchar_text[i], "got %04hx, expected %04x (cp%d[%d])\n", ch, wchar_text[i], codepage, i);
@@ -946,7 +945,7 @@ static void test_fgetwc_unicode(void)
tempfh = fopen(tempfile, "rt,ccs=unicode");
ok(tempfh != NULL, "can't open tempfile\n");
- for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
+ for (i = 1; i < ARRAY_SIZE(wchar_text); i++)
{
ch = fgetwc(tempfh);
ok(ch == wchar_text[i],
@@ -958,7 +957,7 @@ static void test_fgetwc_unicode(void)
tempfh = fopen(tempfile, "wb");
ok(tempfh != NULL, "can't open tempfile\n");
- ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, sizeof(wchar_text)/sizeof(wchar_text[0]),
+ ret = WideCharToMultiByte(CP_UTF8, 0, wchar_text, ARRAY_SIZE(wchar_text),
utf8_text, sizeof(utf8_text), NULL, NULL);
ok(ret > 0, "utf-8 conversion failed\n");
fwrite(utf8_text, sizeof(char), ret, tempfh);
@@ -966,7 +965,7 @@ static void test_fgetwc_unicode(void)
tempfh = fopen(tempfile, "rt, ccs=UTF-8");
ok(tempfh != NULL, "can't open tempfile\n");
- for (i = 1; i < sizeof(wchar_text)/sizeof(wchar_text[0]); i++)
+ for (i = 1; i < ARRAY_SIZE(wchar_text); i++)
{
ch = fgetwc(tempfh);
ok(ch == wchar_text[i],
@@ -2659,5 +2658,5 @@ START_TEST(file)
/* Wait for the (_P_NOWAIT) spawned processes to finish to make sure the report
* file contains lines in the correct order
*/
- WaitForMultipleObjects(sizeof(proc_handles)/sizeof(proc_handles[0]), proc_handles, TRUE, 5000);
+ WaitForMultipleObjects(ARRAY_SIZE(proc_handles), proc_handles, TRUE, 5000);
}
diff --git a/dlls/msvcrt/tests/locale.c b/dlls/msvcrt/tests/locale.c
index 024afc15b3..ff777599aa 100644
--- a/dlls/msvcrt/tests/locale.c
+++ b/dlls/msvcrt/tests/locale.c
@@ -643,7 +643,7 @@ static void test_crtGetStringTypeW(void)
return;
}
- for(i=0; i<sizeof(str)/sizeof(*str); i++) {
+ for(i=0; i<ARRAY_SIZE(str); i++) {
ret_crt = p__crtGetStringTypeW(0, CT_CTYPE1, str[i], 1, &out_crt);
ret = GetStringTypeW(CT_CTYPE1, str[i], 1, &out);
ok(ret == ret_crt, "%d) ret_crt = %d\n", i, (int)ret_crt);
@@ -708,7 +708,7 @@ static void test__Gettnames(void)
else
ok(size==0x164 || broken(size==0xb8), "structure size: %x\n", size);
- for (i = 0; i < sizeof(time_data)/sizeof(time_data[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(time_data); i++)
{
size = GetLocaleInfoA(MAKELCID(LANG_ENGLISH, SORT_DEFAULT),
time_data[i], buf, sizeof(buf));
@@ -722,7 +722,7 @@ static void test__Gettnames(void)
return;
ret = _Gettnames();
- for (i = 0; i < sizeof(time_data)/sizeof(time_data[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(time_data); i++)
{
size = GetLocaleInfoA(MAKELCID(LANG_GERMAN, SORT_DEFAULT),
time_data[i], buf, sizeof(buf));
diff --git a/dlls/msvcrt/tests/misc.c b/dlls/msvcrt/tests/misc.c
index 017ae7758a..c170d23225 100644
--- a/dlls/msvcrt/tests/misc.c
+++ b/dlls/msvcrt/tests/misc.c
@@ -164,7 +164,7 @@ static void test_I10_OUTPUT(void)
if (j != 12)
trace("sizeof(long double) = %d on this machine\n", j);
- for(i=0; i<sizeof(I10_OUTPUT_tests)/sizeof(I10_OUTPUT_test); i++) {
+ for(i=0; i<ARRAY_SIZE(I10_OUTPUT_tests); i++) {
memset(out.str, '#', sizeof(out.str));
if (sizeof(long double) == 12)
@@ -621,7 +621,7 @@ static void test__lfind_s(void)
}
key = 1234;
- num = sizeof(tests)/sizeof(tests[0]);
+ num = ARRAY_SIZE(tests);
errno = 0xdeadbeef;
found = p_lfind_s(NULL, tests, &num, sizeof(int), _lfind_s_comp, NULL);
diff --git a/dlls/msvcrt/tests/printf.c b/dlls/msvcrt/tests/printf.c
index 64658ce25f..80180ff8b2 100644
--- a/dlls/msvcrt/tests/printf.c
+++ b/dlls/msvcrt/tests/printf.c
@@ -841,7 +841,7 @@ static void test_snprintf (void)
const int bufsiz = sizeof buffer;
unsigned int i;
- for (i = 0; i < sizeof tests / sizeof tests[0]; i++) {
+ for (i = 0; i < ARRAY_SIZE(tests); i++) {
const char *fmt = tests[i].format;
const int expect = tests[i].expected;
const int n = _snprintf (buffer, bufsiz, fmt);
@@ -1215,7 +1215,7 @@ static void test_vsnwprintf(void)
wchar_t str[32];
char buf[32];
- ret = _vsnwprintf_wrapper( str, sizeof(str)/sizeof(str[0]), format, one, two, three );
+ ret = _vsnwprintf_wrapper( str, ARRAY_SIZE(str), format, one, two, three );
ok( ret == 11, "got %d expected 11\n", ret );
WideCharToMultiByte( CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL );
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c
index 07458d4474..744035a1b8 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -1014,7 +1014,7 @@ static void test_wcscpy_s(void)
return;
}
- ret = p_wcsncpy_s(NULL, 18, szLongText, sizeof(szLongText)/sizeof(WCHAR));
+ ret = p_wcsncpy_s(NULL, 18, szLongText, ARRAY_SIZE(szLongText));
ok(ret == EINVAL, "p_wcsncpy_s expect EINVAL got %d\n", ret);
szDest[0] = 'A';
@@ -1028,16 +1028,16 @@ static void test_wcscpy_s(void)
ok(szDest[0] == 0, "szDest[0] not 0\n");
szDest[0] = 'A';
- ret = p_wcsncpy_s(szDest, 0, szLongText, sizeof(szLongText)/sizeof(WCHAR));
+ ret = p_wcsncpy_s(szDest, 0, szLongText, ARRAY_SIZE(szLongText));
ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret);
ok(szDest[0] == 0 || ret == EINVAL, "szDest[0] not 0\n");
- ret = p_wcsncpy_s(szDest, 18, szLongText, sizeof(szLongText)/sizeof(WCHAR));
+ ret = p_wcsncpy_s(szDest, 18, szLongText, ARRAY_SIZE(szLongText));
ok(ret == 0, "expected 0 got %d\n", ret);
ok(lstrcmpW(szDest, szLongText) == 0, "szDest != szLongText\n");
szDest[0] = 'A';
- ret = p_wcsncpy_s(szDestShort, 8, szLongText, sizeof(szLongText)/sizeof(WCHAR));
+ ret = p_wcsncpy_s(szDestShort, 8, szLongText, ARRAY_SIZE(szLongText));
ok(ret == ERANGE || ret == EINVAL, "expected ERANGE/EINVAL got %d\n", ret);
ok(szDestShort[0] == 0, "szDestShort[0] not 0\n");
@@ -1065,7 +1065,7 @@ static void test__wcsupr_s(void)
static const WCHAR expectedString[] = {'M', 'I', 'X', 'E', 'D', 'L', 'O',
'W', 'E', 'R', 'U', 'P', 'P', 'E',
'R', 0};
- WCHAR testBuffer[2*sizeof(mixedString)/sizeof(WCHAR)];
+ WCHAR testBuffer[2*ARRAY_SIZE(mixedString)];
int ret;
if (!p_wcsupr_s)
@@ -1082,7 +1082,7 @@ static void test__wcsupr_s(void)
/* Test NULL input string and valid size. */
errno = EBADF;
- ret = p_wcsupr_s(NULL, sizeof(testBuffer)/sizeof(WCHAR));
+ ret = p_wcsupr_s(NULL, ARRAY_SIZE(testBuffer));
ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
@@ -1126,21 +1126,21 @@ static void test__wcsupr_s(void)
/* Test normal string uppercasing. */
wcscpy(testBuffer, mixedString);
- ret = p_wcsupr_s(testBuffer, sizeof(mixedString)/sizeof(WCHAR));
+ ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(mixedString));
ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret);
ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n");
/* Test uppercasing with a shorter buffer size count. */
wcscpy(testBuffer, mixedString);
errno = EBADF;
- ret = p_wcsupr_s(testBuffer, sizeof(mixedString)/sizeof(WCHAR) - 1);
+ ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(mixedString) - 1);
ok(ret == EINVAL, "Expected _wcsupr_s to fail with EINVAL, got %d\n", ret);
ok(errno == EINVAL, "Expected errno to be EINVAL, got %d\n", errno);
ok(testBuffer[0] == '\0', "Expected the first buffer character to be null\n");
/* Test uppercasing with a longer buffer size count. */
wcscpy(testBuffer, mixedString);
- ret = p_wcsupr_s(testBuffer, sizeof(testBuffer)/sizeof(WCHAR));
+ ret = p_wcsupr_s(testBuffer, ARRAY_SIZE(testBuffer));
ok(ret == 0, "Expected _wcsupr_s to succeed, got %d\n", ret);
ok(!wcscmp(testBuffer, expectedString), "Expected the string to be fully upper-case\n");
}
@@ -1152,7 +1152,7 @@ static void test__wcslwr_s(void)
static const WCHAR expectedString[] = {'m', 'i', 'x', 'e', 'd', 'l', 'o',
'w', 'e', 'r', 'u', 'p', 'p', 'e',
'r', 0};
- WCHAR buffer[2*sizeof(mixedString)/sizeof(WCHAR)];
+ WCHAR buffer[2*ARRAY_SIZE(mixedString)];
int ret;
if (!p_wcslwr_s)
@@ -1169,7 +1169,7 @@ static void test__wcslwr_s(void)
/* Test NULL input string and valid size. */
errno = EBADF;
- ret = p_wcslwr_s(NULL, sizeof(buffer)/sizeof(buffer[0]));
+ ret = p_wcslwr_s(NULL, ARRAY_SIZE(buffer));
ok(ret == EINVAL, "expected EINVAL, got %d\n", ret);
ok(errno == EINVAL, "expected errno EINVAL, got %d\n", errno);
@@ -1213,21 +1213,21 @@ static void test__wcslwr_s(void)
/* Test normal string uppercasing. */
wcscpy(buffer, mixedString);
- ret = p_wcslwr_s(buffer, sizeof(mixedString)/sizeof(WCHAR));
+ ret = p_wcslwr_s(buffer, ARRAY_SIZE(mixedString));
ok(ret == 0, "expected 0, got %d\n", ret);
ok(!wcscmp(buffer, expectedString), "expected lowercase\n");
/* Test uppercasing with a shorter buffer size count. */
wcscpy(buffer, mixedString);
errno = EBADF;
- ret = p_wcslwr_s(buffer, sizeof(mixedString)/sizeof(WCHAR) - 1);
+ ret = p_wcslwr_s(buffer, ARRAY_SIZE(mixedString) - 1);
ok(ret == EINVAL, "expected EINVAL, got %d\n", ret);
ok(errno == EINVAL, "expected errno to be EINVAL, got %d\n", errno);
ok(buffer[0] == '\0', "expected empty string\n");
/* Test uppercasing with a longer buffer size count. */
wcscpy(buffer, mixedString);
- ret = p_wcslwr_s(buffer, sizeof(buffer)/sizeof(WCHAR));
+ ret = p_wcslwr_s(buffer, ARRAY_SIZE(buffer));
ok(ret == 0, "expected 0, got %d\n", ret);
ok(!wcscmp(buffer, expectedString), "expected lowercase\n");
}
@@ -1243,7 +1243,7 @@ static void test_mbcjisjms(void)
unsigned int i, j;
int prev_cp = _getmbcp();
- for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(cp); i++)
{
_setmbcp(cp[i]);
for (j = 0; jisjms[j][0] != 0; j++)
@@ -1271,7 +1271,7 @@ static void test_mbcjmsjis(void)
unsigned int i, j;
int prev_cp = _getmbcp();
- for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(cp); i++)
{
_setmbcp(cp[i]);
for (j = 0; jmsjis[j][0] != 0; j++)
@@ -1298,7 +1298,7 @@ static void test_mbctohira(void)
unsigned int prev_cp = _getmbcp();
_setmbcp(_MB_CP_SBCS);
- for (i = 0; i < sizeof(mbchira_932)/sizeof(mbchira_932[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(mbchira_932); i++)
{
int ret, exp = mbchira_932[i][0];
ret = _mbctohira(mbchira_932[i][0]);
@@ -1306,7 +1306,7 @@ static void test_mbctohira(void)
}
_setmbcp(932);
- for (i = 0; i < sizeof(mbchira_932)/sizeof(mbchira_932[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(mbchira_932); i++)
{
unsigned int ret, exp;
ret = _mbctohira(mbchira_932[i][0]);
@@ -1327,7 +1327,7 @@ static void test_mbctokata(void)
unsigned int prev_cp = _getmbcp();
_setmbcp(_MB_CP_SBCS);
- for (i = 0; i < sizeof(mbckata_932)/sizeof(mbckata_932[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(mbckata_932); i++)
{
int ret, exp = mbckata_932[i][0];
ret = _mbctokata(mbckata_932[i][0]);
@@ -1335,7 +1335,7 @@ static void test_mbctokata(void)
}
_setmbcp(932);
- for (i = 0; i < sizeof(mbckata_932)/sizeof(mbckata_932[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(mbckata_932); i++)
{
unsigned int ret, exp;
ret = _mbctokata(mbckata_932[i][0]);
@@ -1356,7 +1356,7 @@ static void test_mbbtombc(void)
int i, j;
int prev_cp = _getmbcp();
- for (i = 0; i < sizeof(cp)/sizeof(cp[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(cp); i++)
{
_setmbcp(cp[i]);
for (j = 0; mbbmbc[j][0] != 0; j++)
@@ -1409,13 +1409,13 @@ static void test_ismbckata(void) {
unsigned int i;
_setmbcp(_MB_CP_SBCS);
- for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(tests); i++) {
ret = _ismbckata(tests[i].c);
ok(!ret, "expected 0, got %d for %04x\n", ret, tests[i].c);
}
_setmbcp(932);
- for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
+ for (i = 0; i < ARRAY_SIZE(tests); i++) {
ret = _ismbckata(tests[i].c);
ok(!!ret == tests[i].exp, "expected %d, got %d for %04x\n",
tests[i].exp, !!ret, tests[i].c);
@@ -2993,7 +2993,7 @@ static void test__wcstoi64(void)
ok(ures == 071, "ures != 071\n");
/* Test various unicode digits */
- for (i = 0; i < sizeof(zeros) / sizeof(zeros[0]); ++i) {
+ for (i = 0; i < ARRAY_SIZE(zeros); ++i) {
WCHAR tmp[] = {zeros[i] + 4, zeros[i], zeros[i] + 5, 0};
res = p_wcstoi64(tmp, NULL, 0);
ok(res == 405, "with zero = U+%04X: got %d, expected 405\n", zeros[i], (int)res);
--
2.14.4
June 20, 2018
[PATCH 1/2] msvcrt: Rename a macro to ARRAY_SIZE()
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/msvcrt/tests/string.c | 28 +++++++++++++---------------
1 file changed, 13 insertions(+), 15 deletions(-)
diff --git a/dlls/msvcrt/tests/string.c b/dlls/msvcrt/tests/string.c
index 2e963dc8ad..07458d4474 100644
--- a/dlls/msvcrt/tests/string.c
+++ b/dlls/msvcrt/tests/string.c
@@ -607,8 +607,6 @@ static void test_strcpy_s(void)
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
}
-#define NUMELMS(array) (sizeof(array)/sizeof((array)[0]))
-
#define okchars(dst, b0, b1, b2, b3, b4, b5, b6, b7) \
ok(dst[0] == b0 && dst[1] == b1 && dst[2] == b2 && dst[3] == b3 && \
dst[4] == b4 && dst[5] == b5 && dst[6] == b6 && dst[7] == b7, \
@@ -628,14 +626,14 @@ static void test_memcpy_s(void)
/* Normal */
memset(dest, 'X', sizeof(dest));
- ret = p_memcpy_s(dest, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ret = p_memcpy_s(dest, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
ok(ret == 0, "Copying a buffer into a big enough destination returned %d, expected 0\n", ret);
okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X', 'X');
/* Vary source size */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memcpy_s(dest, NUMELMS(dest), big, NUMELMS(big));
+ ret = p_memcpy_s(dest, ARRAY_SIZE(dest), big, ARRAY_SIZE(big));
ok(ret == ERANGE, "Copying a big buffer to a small destination returned %d, expected ERANGE\n", ret);
ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -643,7 +641,7 @@ static void test_memcpy_s(void)
/* Replace source with NULL */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memcpy_s(dest, NUMELMS(dest), NULL, NUMELMS(tiny));
+ ret = p_memcpy_s(dest, ARRAY_SIZE(dest), NULL, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Copying a NULL source buffer returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
okchars(dest, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -651,21 +649,21 @@ static void test_memcpy_s(void)
/* Vary dest size */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memcpy_s(dest, 0, tiny, NUMELMS(tiny));
+ ret = p_memcpy_s(dest, 0, tiny, ARRAY_SIZE(tiny));
ok(ret == ERANGE, "Copying into a destination of size 0 returned %d, expected ERANGE\n", ret);
ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
/* Replace dest with NULL */
errno = 0xdeadbeef;
- ret = p_memcpy_s(NULL, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ret = p_memcpy_s(NULL, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Copying a tiny buffer to a big NULL destination returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
/* Combinations */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memcpy_s(dest, 0, NULL, NUMELMS(tiny));
+ ret = p_memcpy_s(dest, 0, NULL, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Copying a NULL buffer into a destination of size 0 returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
@@ -684,20 +682,20 @@ static void test_memmove_s(void)
/* Normal */
memset(dest, 'X', sizeof(dest));
- ret = p_memmove_s(dest, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ret = p_memmove_s(dest, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
ok(ret == 0, "Moving a buffer into a big enough destination returned %d, expected 0\n", ret);
okchars(dest, tiny[0], tiny[1], tiny[2], tiny[3], tiny[4], tiny[5], 'X', 'X');
/* Overlapping */
memcpy(dest, big, sizeof(dest));
- ret = p_memmove_s(dest+1, NUMELMS(dest)-1, dest, NUMELMS(dest)-1);
+ ret = p_memmove_s(dest+1, ARRAY_SIZE(dest)-1, dest, ARRAY_SIZE(dest)-1);
ok(ret == 0, "Moving a buffer up one char returned %d, expected 0\n", ret);
okchars(dest, big[0], big[0], big[1], big[2], big[3], big[4], big[5], big[6]);
/* Vary source size */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memmove_s(dest, NUMELMS(dest), big, NUMELMS(big));
+ ret = p_memmove_s(dest, ARRAY_SIZE(dest), big, ARRAY_SIZE(big));
ok(ret == ERANGE, "Moving a big buffer to a small destination returned %d, expected ERANGE\n", ret);
ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
@@ -705,7 +703,7 @@ static void test_memmove_s(void)
/* Replace source with NULL */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memmove_s(dest, NUMELMS(dest), NULL, NUMELMS(tiny));
+ ret = p_memmove_s(dest, ARRAY_SIZE(dest), NULL, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Moving a NULL source buffer returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
@@ -713,21 +711,21 @@ static void test_memmove_s(void)
/* Vary dest size */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memmove_s(dest, 0, tiny, NUMELMS(tiny));
+ ret = p_memmove_s(dest, 0, tiny, ARRAY_SIZE(tiny));
ok(ret == ERANGE, "Moving into a destination of size 0 returned %d, expected ERANGE\n", ret);
ok(errno == ERANGE, "errno is %d, expected ERANGE\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
/* Replace dest with NULL */
errno = 0xdeadbeef;
- ret = p_memmove_s(NULL, NUMELMS(dest), tiny, NUMELMS(tiny));
+ ret = p_memmove_s(NULL, ARRAY_SIZE(dest), tiny, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Moving a tiny buffer to a big NULL destination returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
/* Combinations */
errno = 0xdeadbeef;
memset(dest, 'X', sizeof(dest));
- ret = p_memmove_s(dest, 0, NULL, NUMELMS(tiny));
+ ret = p_memmove_s(dest, 0, NULL, ARRAY_SIZE(tiny));
ok(ret == EINVAL, "Moving a NULL buffer into a destination of size 0 returned %d, expected EINVAL\n", ret);
ok(errno == EINVAL, "errno is %d, expected EINVAL\n", errno);
okchars(dest, 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X');
--
2.14.4
June 20, 2018
Re: [PATCH] user32: Always release menu item in EnableMenuItem
by Fabian Maurer
> It looks like it's enough to merge conditions to avoid
such repetition.
You're right, it looks a bit awkward. How about the
new version?
Regards,
Fabian Maurer
June 20, 2018
[PATCH v2] user32: Always release menu item in EnableMenuItem
by Fabian Maurer
The menu must be release on all code-paths,
else the underlying lock will never be released.
Fixes bug 45355.
Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de>
---
dlls/user32/menu.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 8c541cc4f91..570c6992cc9 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -3751,9 +3751,11 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
/* Get the parent menu to access*/
parentMenu = grab_menu_ptr(menu->hSysMenuOwner);
- release_menu_ptr(menu);
if (!parentMenu)
+ {
+ release_menu_ptr(menu);
return (UINT)-1;
+ }
hwnd = parentMenu->hWnd;
release_menu_ptr(parentMenu);
@@ -3764,8 +3766,7 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
}
}
- else
- release_menu_ptr(menu);
+ release_menu_ptr(menu);
return oldflags;
}
--
2.17.1
June 20, 2018
Re: [PATCH] user32: Always release menu item in EnableMenuItem
by Nikolay Sivov
On 6/20/2018 11:46 PM, Fabian Maurer wrote:
> The menu must be release on all code-paths,
> else the underlying lock will never be released.
>
> Fixes bug 45355.
>
> Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de>
> ---
> dlls/user32/menu.c | 3 +++
> 1 file changed, 3 insertions(+)
>
> diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
> index 8c541cc4f91..0b1133bbc41 100644
> --- a/dlls/user32/menu.c
> +++ b/dlls/user32/menu.c
> @@ -590,6 +590,7 @@ static POPUPMENU *find_menu_item(HMENU hmenu, UINT id, UINT flags, UINT *pos)
> POPUPMENU *menu;
>
> menu = grab_menu_ptr(hmenu);
> +
> if (!menu)
> return NULL;
>
> @@ -3763,6 +3764,8 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
> rc.bottom = 0;
> RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
> }
> + else
> + release_menu_ptr(menu);
> }
> else
> release_menu_ptr(menu);
>
It looks like it's enough to merge conditions to avoid such repetition.
June 20, 2018
Re: [PATCH v7 4/8] ntdll: Return BIOS info from NtQuerySystemInformation on Linux
by Alexandre Julliard
Alex Henrie <alexhenrie24(a)gmail.com> writes:
> The helper function doesn't need to support more than one buffer size,
> so passing the buffer size is redundant.
>
> I'd want to hear at least one more Wine developer's opinion before
> making a change.
It's indeed ugly to make that sort of assumption in the helper
function. Also you could return the resulting length instead of having
an out variable.
--
Alexandre Julliard
julliard(a)winehq.org
June 20, 2018
[PATCH] user32: Always release menu item in EnableMenuItem
by Fabian Maurer
The menu must be release on all code-paths,
else the underlying lock will never be released.
Fixes bug 45355.
Signed-off-by: Fabian Maurer <dark.shadow4(a)web.de>
---
dlls/user32/menu.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dlls/user32/menu.c b/dlls/user32/menu.c
index 8c541cc4f91..0b1133bbc41 100644
--- a/dlls/user32/menu.c
+++ b/dlls/user32/menu.c
@@ -590,6 +590,7 @@ static POPUPMENU *find_menu_item(HMENU hmenu, UINT id, UINT flags, UINT *pos)
POPUPMENU *menu;
menu = grab_menu_ptr(hmenu);
+
if (!menu)
return NULL;
@@ -3763,6 +3764,8 @@ BOOL WINAPI EnableMenuItem( HMENU hMenu, UINT id, UINT wFlags )
rc.bottom = 0;
RedrawWindow(hwnd, &rc, 0, RDW_FRAME | RDW_INVALIDATE | RDW_NOCHILDREN);
}
+ else
+ release_menu_ptr(menu);
}
else
release_menu_ptr(menu);
--
2.17.1
June 20, 2018
Re: [PATCH v3 2/2] gdiplus: Avoid calling GdipFillPath() with an empty path.
by Vincent Povirk
Signed-off-by: Vincent Povirk <vincent(a)codeweavers.com>
June 20, 2018
Re: [PATCH v3 1/2] gdiplus: Report error for brush_fill_path().
by Vincent Povirk
Signed-off-by: Vincent Povirk <vincent(a)codeweavers.com>
June 20, 2018
[PATCH 5/5] webservices: Send incremental string table updates with messages in the same session.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/channel.c | 31 +++++++++++++++++--------------
dlls/webservices/string.c | 18 +++++++++++++++++-
dlls/webservices/webservices_private.h | 3 +++
dlls/webservices/writer.c | 19 +++++++++++++++++++
4 files changed, 56 insertions(+), 15 deletions(-)
diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c
index 79d431f279..5963faf00d 100644
--- a/dlls/webservices/channel.c
+++ b/dlls/webservices/channel.c
@@ -1009,22 +1009,26 @@ static inline ULONG size_length( ULONG size )
return 5;
}
-static ULONG string_table_size( const WS_XML_DICTIONARY *dict )
+static ULONG string_table_size( const struct dictionary *dict )
{
ULONG i, size = 0;
- for (i = 0; i < dict->stringCount; i++)
- size += size_length( dict->strings[i].length ) + dict->strings[i].length;
+ for (i = 0; i < dict->dict.stringCount; i++)
+ {
+ if (dict->sequence[i] == dict->current_sequence)
+ size += size_length( dict->dict.strings[i].length ) + dict->dict.strings[i].length;
+ }
return size;
}
-static HRESULT send_string_table( SOCKET socket, const WS_XML_DICTIONARY *dict )
+static HRESULT send_string_table( SOCKET socket, const struct dictionary *dict )
{
ULONG i;
HRESULT hr;
- for (i = 0; i < dict->stringCount; i++)
+ for (i = 0; i < dict->dict.stringCount; i++)
{
- if ((hr = send_size( socket, dict->strings[i].length )) != S_OK) return hr;
- if ((hr = send_bytes( socket, dict->strings[i].bytes, dict->strings[i].length )) != S_OK) return hr;
+ if (dict->sequence[i] != dict->current_sequence) continue;
+ if ((hr = send_size( socket, dict->dict.strings[i].length )) != S_OK) return hr;
+ if ((hr = send_bytes( socket, dict->dict.strings[i].bytes, dict->dict.strings[i].length )) != S_OK) return hr;
}
return S_OK;
}
@@ -1154,13 +1158,13 @@ static HRESULT receive_preamble_ack( struct channel *channel )
static HRESULT send_sized_envelope( struct channel *channel, BYTE *data, ULONG len )
{
- ULONG table_size = string_table_size( &channel->dict_send.dict );
+ ULONG table_size = string_table_size( &channel->dict_send );
HRESULT hr;
if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_SIZED_ENVELOPE )) != S_OK) return hr;
if ((hr = send_size( channel->u.tcp.socket, size_length(table_size) + table_size + len )) != S_OK) return hr;
if ((hr = send_size( channel->u.tcp.socket, table_size )) != S_OK) return hr;
- if ((hr = send_string_table( channel->u.tcp.socket, &channel->dict_send.dict )) != S_OK) return hr;
+ if ((hr = send_string_table( channel->u.tcp.socket, &channel->dict_send )) != S_OK) return hr;
return send_bytes( channel->u.tcp.socket, data, len );
}
@@ -1285,11 +1289,8 @@ static HRESULT init_writer( struct channel *channel )
return WsSetOutput( channel->writer, &text.encoding, &buf.output, NULL, 0, NULL );
case WS_ENCODING_XML_BINARY_SESSION_1:
- clear_dict( &channel->dict_send );
- bin.staticDictionary = (WS_XML_DICTIONARY *)&dict_builtin_static.dict;
- bin.dynamicStringCallback = dict_cb;
- bin.dynamicStringCallbackState = &channel->dict_send;
- return WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL );
+ bin.staticDictionary = (WS_XML_DICTIONARY *)&dict_builtin_static.dict;
+ /* fall through */
case WS_ENCODING_XML_BINARY_1:
return WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL );
@@ -1307,6 +1308,8 @@ static HRESULT write_message( struct channel *channel, WS_MESSAGE *msg, const WS
if ((hr = writer_set_lookup( channel->writer, TRUE )) != S_OK) return hr;
if ((hr = WsWriteEnvelopeStart( msg, channel->writer, NULL, NULL, NULL )) != S_OK) return hr;
if ((hr = writer_set_lookup( channel->writer, FALSE )) != S_OK) return hr;
+ channel->dict_send.current_sequence++;
+ if ((hr = writer_set_dict_callback( channel->writer, dict_cb, &channel->dict_send )) != S_OK) return hr;
if ((hr = WsWriteBody( msg, desc, option, body, size, NULL )) != S_OK) return hr;
return WsWriteEnvelopeEnd( msg, NULL );
}
diff --git a/dlls/webservices/string.c b/dlls/webservices/string.c
index 18c55e3833..0bb77df946 100644
--- a/dlls/webservices/string.c
+++ b/dlls/webservices/string.c
@@ -91,7 +91,7 @@ int find_string( const struct dictionary *dict, const unsigned char *data, ULONG
static HRESULT grow_dict( struct dictionary *dict, ULONG size )
{
WS_XML_STRING *tmp;
- ULONG new_size, *tmp_sorted;
+ ULONG new_size, *tmp_sorted, *tmp_sequence;
assert( !dict->dict.isConst );
if (dict->size >= dict->dict.stringCount + size) return S_OK;
@@ -107,6 +107,14 @@ static HRESULT grow_dict( struct dictionary *dict, ULONG size )
dict->dict.strings = NULL;
return E_OUTOFMEMORY;
}
+ if (!(dict->sequence = heap_alloc( new_size * sizeof(*dict->sequence) )))
+ {
+ heap_free( dict->dict.strings );
+ dict->dict.strings = NULL;
+ heap_free( dict->sorted );
+ dict->sorted = NULL;
+ return E_OUTOFMEMORY;
+ }
dict->size = new_size;
return S_OK;
}
@@ -116,6 +124,8 @@ static HRESULT grow_dict( struct dictionary *dict, ULONG size )
dict->dict.strings = tmp;
if (!(tmp_sorted = heap_realloc( dict->sorted, new_size * sizeof(*tmp_sorted) ))) return E_OUTOFMEMORY;
dict->sorted = tmp_sorted;
+ if (!(tmp_sequence = heap_realloc( dict->sequence, new_size * sizeof(*tmp_sequence) ))) return E_OUTOFMEMORY;
+ dict->sequence = tmp_sequence;
dict->size = new_size;
return S_OK;
@@ -131,6 +141,9 @@ void clear_dict( struct dictionary *dict )
dict->dict.stringCount = 0;
heap_free( dict->sorted );
dict->sorted = NULL;
+ heap_free( dict->sequence );
+ dict->sequence = NULL;
+ dict->current_sequence = 0;
dict->size = 0;
}
@@ -149,6 +162,9 @@ HRESULT insert_string( struct dictionary *dict, unsigned char *data, ULONG len,
dict->dict.strings[id].dictionary = &dict->dict;
dict->dict.strings[id].id = id;
dict->dict.stringCount++;
+
+ dict->sequence[id] = dict->current_sequence;
+
if (ret_id) *ret_id = id;
return S_OK;
}
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index bfc3202a64..d981527bb2 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -43,6 +43,8 @@ struct dictionary
WS_XML_DICTIONARY dict;
ULONG *sorted;
ULONG size;
+ ULONG current_sequence;
+ ULONG *sequence;
};
struct dictionary dict_builtin DECLSPEC_HIDDEN;
const struct dictionary dict_builtin_static DECLSPEC_HIDDEN;
@@ -51,6 +53,7 @@ int find_string( const struct dictionary *, const unsigned char *, ULONG, ULONG
HRESULT insert_string( struct dictionary *, unsigned char *, ULONG, int, ULONG * ) DECLSPEC_HIDDEN;
void clear_dict( struct dictionary * ) DECLSPEC_HIDDEN;
HRESULT writer_set_lookup( WS_XML_WRITER *, BOOL ) DECLSPEC_HIDDEN;
+HRESULT writer_set_dict_callback( WS_XML_WRITER *, WS_DYNAMIC_STRING_CALLBACK, void * ) DECLSPEC_HIDDEN;
const char *debugstr_xmlstr( const WS_XML_STRING * ) DECLSPEC_HIDDEN;
WS_XML_STRING *alloc_xml_string( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index b3d130a52c..95d4caddb9 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -4866,3 +4866,22 @@ HRESULT writer_set_lookup( WS_XML_WRITER *handle, BOOL enable )
LeaveCriticalSection( &writer->cs );
return S_OK;
}
+
+HRESULT writer_set_dict_callback( WS_XML_WRITER *handle, WS_DYNAMIC_STRING_CALLBACK cb, void *state )
+{
+ struct writer *writer = (struct writer *)handle;
+
+ EnterCriticalSection( &writer->cs );
+
+ if (writer->magic != WRITER_MAGIC)
+ {
+ LeaveCriticalSection( &writer->cs );
+ return E_INVALIDARG;
+ }
+
+ writer->dict_cb = cb;
+ writer->dict_cb_state = state;
+
+ LeaveCriticalSection( &writer->cs );
+ return S_OK;
+}
--
2.11.0
June 20, 2018
[PATCH 4/5] webservices: Use the static dictionary only while writing the message header.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/channel.c | 30 ++++++++++++++----------------
dlls/webservices/webservices_private.h | 2 +-
dlls/webservices/writer.c | 4 ++--
3 files changed, 17 insertions(+), 19 deletions(-)
diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c
index 6c7c8affa3..79d431f279 100644
--- a/dlls/webservices/channel.c
+++ b/dlls/webservices/channel.c
@@ -967,15 +967,6 @@ static HRESULT connect_channel( struct channel *channel )
}
}
-static HRESULT write_message( WS_MESSAGE *handle, WS_XML_WRITER *writer, const WS_ELEMENT_DESCRIPTION *desc,
- WS_WRITE_OPTION option, const void *body, ULONG size )
-{
- HRESULT hr;
- if ((hr = WsWriteEnvelopeStart( handle, writer, NULL, NULL, NULL )) != S_OK) return hr;
- if ((hr = WsWriteBody( handle, desc, option, body, size, NULL )) != S_OK) return hr;
- return WsWriteEnvelopeEnd( handle, NULL );
-}
-
static HRESULT send_message_http( HINTERNET request, BYTE *data, ULONG len )
{
if (!WinHttpSendRequest( request, NULL, 0, data, len, len, 0 ))
@@ -1298,8 +1289,7 @@ static HRESULT init_writer( struct channel *channel )
bin.staticDictionary = (WS_XML_DICTIONARY *)&dict_builtin_static.dict;
bin.dynamicStringCallback = dict_cb;
bin.dynamicStringCallbackState = &channel->dict_send;
- if ((hr = WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL )) != S_OK) return hr;
- return writer_enable_lookup( channel->writer );
+ return WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL );
case WS_ENCODING_XML_BINARY_1:
return WsSetOutput( channel->writer, &bin.encoding, &buf.output, NULL, 0, NULL );
@@ -1310,6 +1300,17 @@ static HRESULT init_writer( struct channel *channel )
}
}
+static HRESULT write_message( struct channel *channel, WS_MESSAGE *msg, const WS_ELEMENT_DESCRIPTION *desc,
+ WS_WRITE_OPTION option, const void *body, ULONG size )
+{
+ HRESULT hr;
+ if ((hr = writer_set_lookup( channel->writer, TRUE )) != S_OK) return hr;
+ if ((hr = WsWriteEnvelopeStart( msg, channel->writer, NULL, NULL, NULL )) != S_OK) return hr;
+ if ((hr = writer_set_lookup( channel->writer, FALSE )) != S_OK) return hr;
+ if ((hr = WsWriteBody( msg, desc, option, body, size, NULL )) != S_OK) return hr;
+ return WsWriteEnvelopeEnd( msg, NULL );
+}
+
/**************************************************************************
* WsSendMessage [webservices.@]
*/
@@ -1339,8 +1340,7 @@ HRESULT WINAPI WsSendMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_MESS
if ((hr = message_set_action( msg, desc->action )) != S_OK) goto done;
if ((hr = init_writer( channel )) != S_OK) goto done;
- if ((hr = write_message( msg, channel->writer, desc->bodyElementDescription, option, body, size )) != S_OK)
- goto done;
+ if ((hr = write_message( channel, msg, desc->bodyElementDescription, option, body, size )) != S_OK) goto done;
hr = send_message( channel, msg );
done:
@@ -1380,13 +1380,11 @@ HRESULT WINAPI WsSendReplyMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS
if ((hr = message_set_request_id( msg, &req_id )) != S_OK) goto done;
if ((hr = init_writer( channel )) != S_OK) goto done;
- if ((hr = write_message( msg, channel->writer, desc->bodyElementDescription, option, body, size )) != S_OK)
- goto done;
+ if ((hr = write_message( channel, msg, desc->bodyElementDescription, option, body, size )) != S_OK) goto done;
hr = send_message( channel, msg );
done:
LeaveCriticalSection( &channel->cs );
- FIXME( "returning %08x\n", hr );
return hr;
}
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index cce49cce14..bfc3202a64 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -50,7 +50,7 @@ const struct dictionary dict_builtin_static DECLSPEC_HIDDEN;
int find_string( const struct dictionary *, const unsigned char *, ULONG, ULONG * ) DECLSPEC_HIDDEN;
HRESULT insert_string( struct dictionary *, unsigned char *, ULONG, int, ULONG * ) DECLSPEC_HIDDEN;
void clear_dict( struct dictionary * ) DECLSPEC_HIDDEN;
-HRESULT writer_enable_lookup( WS_XML_WRITER * ) DECLSPEC_HIDDEN;
+HRESULT writer_set_lookup( WS_XML_WRITER *, BOOL ) DECLSPEC_HIDDEN;
const char *debugstr_xmlstr( const WS_XML_STRING * ) DECLSPEC_HIDDEN;
WS_XML_STRING *alloc_xml_string( const unsigned char *, ULONG ) DECLSPEC_HIDDEN;
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index 33c1be70b5..b3d130a52c 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -4849,7 +4849,7 @@ done:
return hr;
}
-HRESULT writer_enable_lookup( WS_XML_WRITER *handle )
+HRESULT writer_set_lookup( WS_XML_WRITER *handle, BOOL enable )
{
struct writer *writer = (struct writer *)handle;
@@ -4861,7 +4861,7 @@ HRESULT writer_enable_lookup( WS_XML_WRITER *handle )
return E_INVALIDARG;
}
- writer->dict_do_lookup = TRUE;
+ writer->dict_do_lookup = enable;
LeaveCriticalSection( &writer->cs );
return S_OK;
--
2.11.0
June 20, 2018
[PATCH 3/5] webservices: Implement WsShutdownSessionChannel.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/channel.c | 98 +++++++++++++++++++++++++++++----------
dlls/webservices/tests/channel.c | 12 +++++
dlls/webservices/webservices.spec | 2 +-
include/webservices.h | 1 +
4 files changed, 87 insertions(+), 26 deletions(-)
diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c
index 685e13d99d..6c7c8affa3 100644
--- a/dlls/webservices/channel.c
+++ b/dlls/webservices/channel.c
@@ -193,6 +193,7 @@ enum session_state
{
SESSION_STATE_UNINITIALIZED,
SESSION_STATE_SETUP_COMPLETE,
+ SESSION_STATE_SHUTDOWN,
};
struct channel
@@ -664,6 +665,78 @@ HRESULT WINAPI WsOpenChannel( WS_CHANNEL *handle, const WS_ENDPOINT_ADDRESS *end
return hr;
}
+enum frame_record_type
+{
+ FRAME_RECORD_TYPE_VERSION,
+ FRAME_RECORD_TYPE_MODE,
+ FRAME_RECORD_TYPE_VIA,
+ FRAME_RECORD_TYPE_KNOWN_ENCODING,
+ FRAME_RECORD_TYPE_EXTENSIBLE_ENCODING,
+ FRAME_RECORD_TYPE_UNSIZED_ENVELOPE,
+ FRAME_RECORD_TYPE_SIZED_ENVELOPE,
+ FRAME_RECORD_TYPE_END,
+ FRAME_RECORD_TYPE_FAULT,
+ FRAME_RECORD_TYPE_UPGRADE_REQUEST,
+ FRAME_RECORD_TYPE_UPGRADE_RESPONSE,
+ FRAME_RECORD_TYPE_PREAMBLE_ACK,
+ FRAME_RECORD_TYPE_PREAMBLE_END,
+};
+
+static HRESULT send_byte( SOCKET socket, BYTE byte )
+{
+ int count = send( socket, (char *)&byte, 1, 0 );
+ if (count < 0) return HRESULT_FROM_WIN32( WSAGetLastError() );
+ if (count != 1) return WS_E_OTHER;
+ return S_OK;
+}
+
+static HRESULT shutdown_session( struct channel *channel )
+{
+ HRESULT hr;
+
+ if (channel->state != WS_CHANNEL_STATE_OPEN ||
+ (channel->type != WS_CHANNEL_TYPE_OUTPUT_SESSION &&
+ channel->type != WS_CHANNEL_TYPE_DUPLEX_SESSION) ||
+ channel->session_state >= SESSION_STATE_SHUTDOWN) return WS_E_INVALID_OPERATION;
+
+ switch (channel->binding)
+ {
+ case WS_TCP_CHANNEL_BINDING:
+ if ((hr = send_byte( channel->u.tcp.socket, FRAME_RECORD_TYPE_END )) != S_OK) return hr;
+ channel->session_state = SESSION_STATE_SHUTDOWN;
+ return S_OK;
+
+ default:
+ FIXME( "unhandled binding %u\n", channel->binding );
+ return E_NOTIMPL;
+ }
+}
+
+HRESULT WINAPI WsShutdownSessionChannel( WS_CHANNEL *handle, const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
+{
+ struct channel *channel = (struct channel *)handle;
+ HRESULT hr;
+
+ TRACE( "%p %p %p\n", handle, ctx, error );
+ if (error) FIXME( "ignoring error parameter\n" );
+ if (ctx) FIXME( "ignoring ctx parameter\n" );
+
+ if (!channel) return E_INVALIDARG;
+
+ EnterCriticalSection( &channel->cs );
+
+ if (channel->magic != CHANNEL_MAGIC)
+ {
+ LeaveCriticalSection( &channel->cs );
+ return E_INVALIDARG;
+ }
+
+ hr = shutdown_session( channel );
+
+ LeaveCriticalSection( &channel->cs );
+ return hr;
+}
+
static void close_channel( struct channel *channel )
{
reset_channel( channel );
@@ -913,14 +986,6 @@ static HRESULT send_message_http( HINTERNET request, BYTE *data, ULONG len )
return S_OK;
}
-static HRESULT send_byte( SOCKET socket, BYTE byte )
-{
- int count = send( socket, (char *)&byte, 1, 0 );
- if (count < 0) return HRESULT_FROM_WIN32( WSAGetLastError() );
- if (count != 1) return WS_E_OTHER;
- return S_OK;
-}
-
static HRESULT send_bytes( SOCKET socket, BYTE *bytes, int len )
{
int count = send( socket, (char *)bytes, len, 0 );
@@ -944,23 +1009,6 @@ static HRESULT send_size( SOCKET socket, ULONG size )
return E_INVALIDARG;
}
-enum frame_record_type
-{
- FRAME_RECORD_TYPE_VERSION,
- FRAME_RECORD_TYPE_MODE,
- FRAME_RECORD_TYPE_VIA,
- FRAME_RECORD_TYPE_KNOWN_ENCODING,
- FRAME_RECORD_TYPE_EXTENSIBLE_ENCODING,
- FRAME_RECORD_TYPE_UNSIZED_ENVELOPE,
- FRAME_RECORD_TYPE_SIZED_ENVELOPE,
- FRAME_RECORD_TYPE_END,
- FRAME_RECORD_TYPE_FAULT,
- FRAME_RECORD_TYPE_UPGRADE_REQUEST,
- FRAME_RECORD_TYPE_UPGRADE_RESPONSE,
- FRAME_RECORD_TYPE_PREAMBLE_ACK,
- FRAME_RECORD_TYPE_PREAMBLE_END,
-};
-
static inline ULONG size_length( ULONG size )
{
if (size < 0x80) return 1;
diff --git a/dlls/webservices/tests/channel.c b/dlls/webservices/tests/channel.c
index c995a08829..db17893138 100644
--- a/dlls/webservices/tests/channel.c
+++ b/dlls/webservices/tests/channel.c
@@ -496,6 +496,9 @@ static void test_message_read_write( const struct listener_info *info )
hr = WsOpenChannel( channel, &addr, NULL, NULL );
ok( hr == S_OK, "got %08x\n", hr );
+ hr = WsShutdownSessionChannel( channel, NULL, NULL );
+ ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
hr = WsCreateMessageForChannel( channel, NULL, 0, &msg, NULL );
ok( hr == S_OK, "got %08x\n", hr );
@@ -627,6 +630,9 @@ static void test_duplex_session( const struct listener_info *info )
hr = WsCreateChannel( info->type, info->binding, NULL, 0, NULL, &channel, NULL );
ok( hr == S_OK, "got %08x\n", hr );
+ hr = WsShutdownSessionChannel( channel, NULL, NULL );
+ ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
memset( &addr, 0, sizeof(addr) );
addr.url.length = wsprintfW( buf, fmt, info->port );
addr.url.chars = buf;
@@ -655,6 +661,12 @@ static void test_duplex_session( const struct listener_info *info )
err = WaitForSingleObject( info->wait, 3000 );
ok( err == WAIT_OBJECT_0, "wait failed %u\n", err );
+ hr = WsShutdownSessionChannel( channel, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsShutdownSessionChannel( channel, NULL, NULL );
+ ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
hr = WsCloseChannel( channel, NULL, NULL );
ok( hr == S_OK, "got %08x\n", hr );
diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec
index 55f3e2eaac..8ba34b4209 100644
--- a/dlls/webservices/webservices.spec
+++ b/dlls/webservices/webservices.spec
@@ -158,7 +158,7 @@
@ stdcall WsSetOutputToBuffer(ptr ptr ptr long ptr)
@ stdcall WsSetReaderPosition(ptr ptr ptr)
@ stdcall WsSetWriterPosition(ptr ptr ptr)
-@ stub WsShutdownSessionChannel
+@ stdcall WsShutdownSessionChannel(ptr ptr ptr)
@ stdcall WsSkipNode(ptr ptr)
@ stub WsStartReaderCanonicalization
@ stub WsStartWriterCanonicalization
diff --git a/include/webservices.h b/include/webservices.h
index 1f823ddc27..928819fc3d 100644
--- a/include/webservices.h
+++ b/include/webservices.h
@@ -1732,6 +1732,7 @@ HRESULT WINAPI WsSetOutputToBuffer(WS_XML_WRITER*, WS_XML_BUFFER*, const WS_XML_
ULONG, WS_ERROR*);
HRESULT WINAPI WsSetReaderPosition(WS_XML_READER*, const WS_XML_NODE_POSITION*, WS_ERROR*);
HRESULT WINAPI WsSetWriterPosition(WS_XML_WRITER*, const WS_XML_NODE_POSITION*, WS_ERROR*);
+HRESULT WINAPI WsShutdownSessionChannel(WS_CHANNEL*, const WS_ASYNC_CONTEXT*, WS_ERROR*);
HRESULT WINAPI WsSkipNode(WS_XML_READER*, WS_ERROR*);
HRESULT WINAPI WsWriteArray(WS_XML_WRITER*, const WS_XML_STRING*, const WS_XML_STRING*, WS_VALUE_TYPE,
const void*, ULONG, ULONG, ULONG, WS_ERROR*);
--
2.11.0
June 20, 2018
[PATCH 2/5] webservices: Avoid accessing the old user buffer in WsSetOutput/ToBuffer.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/writer.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/webservices/writer.c b/dlls/webservices/writer.c
index 9cba4e60a2..33c1be70b5 100644
--- a/dlls/webservices/writer.c
+++ b/dlls/webservices/writer.c
@@ -39,7 +39,7 @@ static const struct prop_desc writer_props[] =
{
{ sizeof(ULONG), FALSE }, /* WS_XML_WRITER_PROPERTY_MAX_DEPTH */
{ sizeof(BOOL), FALSE }, /* WS_XML_WRITER_PROPERTY_ALLOW_FRAGMENT */
- { sizeof(ULONG), FALSE }, /* WS_XML_READER_PROPERTY_MAX_ATTRIBUTES */
+ { sizeof(ULONG), FALSE }, /* WS_XML_WRITER_PROPERTY_MAX_ATTRIBUTES */
{ sizeof(BOOL), FALSE }, /* WS_XML_WRITER_PROPERTY_WRITE_DECLARATION */
{ sizeof(ULONG), FALSE }, /* WS_XML_WRITER_PROPERTY_INDENT */
{ sizeof(ULONG), FALSE }, /* WS_XML_WRITER_PROPERTY_BUFFER_TRIM_SIZE */
@@ -85,6 +85,7 @@ struct writer
WS_CHARSET output_charset;
WS_XML_WRITER_OUTPUT_TYPE output_type;
struct xmlbuf *output_buf;
+ BOOL output_buf_user;
WS_HEAP *output_heap;
const WS_XML_DICTIONARY *dict;
BOOL dict_do_lookup;
@@ -332,7 +333,7 @@ HRESULT WINAPI WsGetWriterProperty( WS_XML_WRITER *handle, WS_XML_WRITER_PROPERT
static void set_output_buffer( struct writer *writer, struct xmlbuf *xmlbuf )
{
/* free current buffer if it's ours */
- if (writer->output_buf && writer->output_buf->heap == writer->output_heap)
+ if (writer->output_buf && !writer->output_buf_user)
{
free_xmlbuf( writer->output_buf );
}
@@ -419,6 +420,7 @@ HRESULT WINAPI WsSetOutput( WS_XML_WRITER *handle, const WS_XML_WRITER_ENCODING
goto done;
}
set_output_buffer( writer, xmlbuf );
+ writer->output_buf_user = FALSE;
break;
}
default:
@@ -472,6 +474,7 @@ HRESULT WINAPI WsSetOutputToBuffer( WS_XML_WRITER *handle, WS_XML_BUFFER *buffer
writer->output_enc = xmlbuf->encoding;
writer->output_charset = xmlbuf->charset;
set_output_buffer( writer, xmlbuf );
+ writer->output_buf_user = TRUE;
if (!(node = alloc_node( WS_XML_NODE_TYPE_BOF ))) hr = E_OUTOFMEMORY;
else write_insert_bof( writer, node );
--
2.11.0
June 20, 2018
[PATCH 1/5] webservices: Avoid a warning from HeapDestroy.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/webservices/heap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/webservices/heap.c b/dlls/webservices/heap.c
index 5e1a273329..e44cf72e74 100644
--- a/dlls/webservices/heap.c
+++ b/dlls/webservices/heap.c
@@ -216,7 +216,7 @@ HRESULT WINAPI WsCreateHeap( SIZE_T max_size, SIZE_T trim_size, const WS_HEAP_PR
static void reset_heap( struct heap *heap )
{
- HeapDestroy( heap->handle );
+ if (heap->handle) HeapDestroy( heap->handle );
heap->handle = NULL;
heap->max_size = heap->allocated = 0;
}
--
2.11.0
June 20, 2018
Re: [PATCH 6/6] wined3d: Call wined3d_cs_emit_update_sub_resource() directly in buffer_init().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 5/6] wined3d: Use WINED3D_LOCATION_DISCARDED before initializing buffers with data.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 4/6] wined3d: Reduce nesting in texture2d_load_sysmem().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 2/6] wined3d: Initialize depth/stencil texture data.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 3/6] d3d9/tests: Add test for depth stencil initialization.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 1/6] d3d11: Introduce get_resource_properties() helper function.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
June 20, 2018
Re: [PATCH 2/3] crypt32: Implement decoding of X509_OBJECT_IDENTIFIER.
by Nikolay Sivov
On 06/20/2018 11:10 AM, Alistair Leslie-Hughes wrote:
> Hi Nikolay,
>
> Is there a reason why you didn't include tests in this series?
>
Patch doesn't mention how test blobs were generated, I'd like to find a
reproducible way to recreated them.
>
> Alistair.
>
>
> On 20/06/18 17:37, Nikolay Sivov wrote:
>> From: Michael Müller<michael(a)fds-team.de>
>>
>> Signed-off-by: Nikolay Sivov<nsivov(a)codeweavers.com>
>> ---
>> dlls/crypt32/decode.c | 45 +++++++++++++++++++++++++++++++++++++++++++
>> include/wincrypt.h | 15 +++++++++++++++
>> 2 files changed, 60 insertions(+)
>>
>> diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
>> index a61316016f..4f11d0d60f 100644
>> --- a/dlls/crypt32/decode.c
>> +++ b/dlls/crypt32/decode.c
>> @@ -5973,6 +5973,46 @@ BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
>> return ret;
>> }
>>
>> +static BOOL WINAPI CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType,
>> + LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
>> + CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
>> +{
>> + DWORD bytesNeeded = 0;
>> + BOOL ret;
>> +
>> + __TRY
>> + {
>> + ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
>> + NULL, &bytesNeeded, NULL);
>> + if (ret)
>> + {
>> + if (!pvStructInfo)
>> + *pcbStructInfo = bytesNeeded;
>> + else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
>> + {
>> + LPSTR *info;
>> +
>> + if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
>> + pvStructInfo = *(BYTE **)pvStructInfo;
>> +
>> + info = pvStructInfo;
>> + *info = (void *)((BYTE *)info + sizeof(*info));
>> + ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
>> + pvStructInfo, &bytesNeeded, NULL);
>> + if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
>> + CRYPT_FreeSpace(pDecodePara, info);
>> + }
>> + }
>> + }
>> + __EXCEPT_PAGE_FAULT
>> + {
>> + SetLastError(STATUS_ACCESS_VIOLATION);
>> + ret = FALSE;
>> + }
>> + __ENDTRY
>> + return ret;
>> +}
>> +
>> static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
>> LPCSTR lpszStructType)
>> {
>> @@ -6112,6 +6152,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
>> case LOWORD(CMS_SIGNER_INFO):
>> decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
>> break;
>> + case LOWORD(X509_OBJECT_IDENTIFIER):
>> + decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
>> + break;
>> }
>> }
>> else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
>> @@ -6166,6 +6209,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
>> decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
>> else if (!strcmp(lpszStructType, szOID_CTL))
>> decodeFunc = CRYPT_AsnDecodeCTL;
>> + else if (!strcmp(lpszStructType, szOID_ECC_PUBLIC_KEY))
>> + decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
>> return decodeFunc;
>> }
>>
>> diff --git a/include/wincrypt.h b/include/wincrypt.h
>> index 6e71fb902e..a7c24e7831 100644
>> --- a/include/wincrypt.h
>> +++ b/include/wincrypt.h
>> @@ -288,6 +288,11 @@ typedef struct _CERT_KEY_ATTRIBUTES_INFO {
>> PCERT_PRIVATE_KEY_VALIDITY pPrivateKeyUsagePeriod;
>> } CERT_KEY_ATTRIBUTES_INFO, *PCERT_KEY_ATTRIBUTES_INFO;
>>
>> +typedef struct _CERT_ECC_SIGNATURE {
>> + CRYPT_UINT_BLOB r;
>> + CRYPT_UINT_BLOB s;
>> +} CERT_ECC_SIGNATURE, *PCERT_ECC_SIGNATURE;
>> +
>> /* byte 0 */
>> #define CERT_DIGITAL_SIGNATURE_KEY_USAGE 0x80
>> #define CERT_NON_REPUDIATION_KEY_USAGE 0x40
>> @@ -2878,6 +2883,12 @@ typedef struct _CTL_FIND_SUBJECT_PARA
>> #define szOID_X957 "1.2.840.10040"
>> #define szOID_X957_DSA "1.2.840.10040.4.1"
>> #define szOID_X957_SHA1DSA "1.2.840.10040.4.3"
>> +#define szOID_ECC_PUBLIC_KEY "1.2.840.10045.2.1"
>> +#define szOID_ECC_CURVE_P256 "1.2.840.10045.3.1.7"
>> +#define szOID_ECDSA_SPECIFIED "1.2.840.10045.4.3"
>> +#define szOID_ECDSA_SHA256 "1.2.840.10045.4.3.2"
>> +#define szOID_ECDSA_SHA384 "1.2.840.10045.4.3.3"
>> +#define szOID_ECDSA_SHA512 "1.2.840.10045.4.3.4"
>> #define szOID_DS "2.5"
>> #define szOID_DSALG "2.5.8"
>> #define szOID_DSALG_CRPT "2.5.8.1"
>> @@ -2919,6 +2930,8 @@ typedef struct _CTL_FIND_SUBJECT_PARA
>> #define szOID_OIWDIR_SIGN "1.3.14.7.2.3"
>> #define szOID_OIWDIR_md2 "1.3.14.7.2.2.1"
>> #define szOID_OIWDIR_md2RSA "1.3.14.7.2.3.1"
>> +#define szOID_ECC_CURVE_P384 "1.3.132.0.34"
>> +#define szOID_ECC_CURVE_P521 "1.3.132.0.35"
>> #define szOID_INFOSEC "2.16.840.1.101.2.1"
>> #define szOID_INFOSEC_sdnsSignature "2.16.840.1.101.2.1.1.1"
>> #define szOID_INFOSEC_mosaicSignature "2.16.840.1.101.2.1.1.2"
>> @@ -3223,6 +3236,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
>> #define X509_PKIX_POLICY_QUALIFIER_USERNOTICE ((LPCSTR)46)
>> #define X509_DH_PUBLICKEY X509_MULTI_BYTE_UINT
>> #define X509_DH_PARAMETERS ((LPCSTR)47)
>> +#define X509_ECC_SIGNATURE ((LPCSTR)47)
>> #define PKCS_ATTRIBUTES ((LPCSTR)48)
>> #define PKCS_SORTED_CTL ((LPCSTR)49)
>> #define X942_DH_PARAMETERS ((LPCSTR)50)
>> @@ -3240,6 +3254,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
>> #define CMC_ADD_EXTENSIONS ((LPCSTR)62)
>> #define CMC_ADD_ATTRIBUTES ((LPCSTR)63)
>> #define X509_CERTIFICATE_TEMPLATE ((LPCSTR)64)
>> +#define X509_OBJECT_IDENTIFIER ((LPCSTR)73)
>> #define PKCS7_SIGNER_INFO ((LPCSTR)500)
>> #define CMS_SIGNER_INFO ((LPCSTR)501)
>>
>>
>>
>
June 20, 2018
Re: [PATCH 2/3] crypt32: Implement decoding of X509_OBJECT_IDENTIFIER.
by Alistair Leslie-Hughes
Hi Nikolay,
Is there a reason why you didn't include tests in this series?
Alistair.
On 20/06/18 17:37, Nikolay Sivov wrote:
From: Michael Müller <michael(a)fds-team.de><mailto:michael(a)fds-team.de>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com><mailto:nsivov(a)codeweavers.com>
---
dlls/crypt32/decode.c | 45 +++++++++++++++++++++++++++++++++++++++++++
include/wincrypt.h | 15 +++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index a61316016f..4f11d0d60f 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -5973,6 +5973,46 @@ BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
return ret;
}
+static BOOL WINAPI CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ DWORD bytesNeeded = 0;
+ BOOL ret;
+
+ __TRY
+ {
+ ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+ NULL, &bytesNeeded, NULL);
+ if (ret)
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ LPSTR *info;
+
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+
+ info = pvStructInfo;
+ *info = (void *)((BYTE *)info + sizeof(*info));
+ ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+ pvStructInfo, &bytesNeeded, NULL);
+ if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
+ CRYPT_FreeSpace(pDecodePara, info);
+ }
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
+ return ret;
+}
+
static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
LPCSTR lpszStructType)
{
@@ -6112,6 +6152,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(CMS_SIGNER_INFO):
decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
break;
+ case LOWORD(X509_OBJECT_IDENTIFIER):
+ decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
+ break;
}
}
else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
@@ -6166,6 +6209,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
else if (!strcmp(lpszStructType, szOID_CTL))
decodeFunc = CRYPT_AsnDecodeCTL;
+ else if (!strcmp(lpszStructType, szOID_ECC_PUBLIC_KEY))
+ decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
return decodeFunc;
}
diff --git a/include/wincrypt.h b/include/wincrypt.h
index 6e71fb902e..a7c24e7831 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -288,6 +288,11 @@ typedef struct _CERT_KEY_ATTRIBUTES_INFO {
PCERT_PRIVATE_KEY_VALIDITY pPrivateKeyUsagePeriod;
} CERT_KEY_ATTRIBUTES_INFO, *PCERT_KEY_ATTRIBUTES_INFO;
+typedef struct _CERT_ECC_SIGNATURE {
+ CRYPT_UINT_BLOB r;
+ CRYPT_UINT_BLOB s;
+} CERT_ECC_SIGNATURE, *PCERT_ECC_SIGNATURE;
+
/* byte 0 */
#define CERT_DIGITAL_SIGNATURE_KEY_USAGE 0x80
#define CERT_NON_REPUDIATION_KEY_USAGE 0x40
@@ -2878,6 +2883,12 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define szOID_X957 "1.2.840.10040"
#define szOID_X957_DSA "1.2.840.10040.4.1"
#define szOID_X957_SHA1DSA "1.2.840.10040.4.3"
+#define szOID_ECC_PUBLIC_KEY "1.2.840.10045.2.1"
+#define szOID_ECC_CURVE_P256 "1.2.840.10045.3.1.7"
+#define szOID_ECDSA_SPECIFIED "1.2.840.10045.4.3"
+#define szOID_ECDSA_SHA256 "1.2.840.10045.4.3.2"
+#define szOID_ECDSA_SHA384 "1.2.840.10045.4.3.3"
+#define szOID_ECDSA_SHA512 "1.2.840.10045.4.3.4"
#define szOID_DS "2.5"
#define szOID_DSALG "2.5.8"
#define szOID_DSALG_CRPT "2.5.8.1"
@@ -2919,6 +2930,8 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define szOID_OIWDIR_SIGN "1.3.14.7.2.3"
#define szOID_OIWDIR_md2 "1.3.14.7.2.2.1"
#define szOID_OIWDIR_md2RSA "1.3.14.7.2.3.1"
+#define szOID_ECC_CURVE_P384 "1.3.132.0.34"
+#define szOID_ECC_CURVE_P521 "1.3.132.0.35"
#define szOID_INFOSEC "2.16.840.1.101.2.1"
#define szOID_INFOSEC_sdnsSignature "2.16.840.1.101.2.1.1.1"
#define szOID_INFOSEC_mosaicSignature "2.16.840.1.101.2.1.1.2"
@@ -3223,6 +3236,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define X509_PKIX_POLICY_QUALIFIER_USERNOTICE ((LPCSTR)46)
#define X509_DH_PUBLICKEY X509_MULTI_BYTE_UINT
#define X509_DH_PARAMETERS ((LPCSTR)47)
+#define X509_ECC_SIGNATURE ((LPCSTR)47)
#define PKCS_ATTRIBUTES ((LPCSTR)48)
#define PKCS_SORTED_CTL ((LPCSTR)49)
#define X942_DH_PARAMETERS ((LPCSTR)50)
@@ -3240,6 +3254,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define CMC_ADD_EXTENSIONS ((LPCSTR)62)
#define CMC_ADD_ATTRIBUTES ((LPCSTR)63)
#define X509_CERTIFICATE_TEMPLATE ((LPCSTR)64)
+#define X509_OBJECT_IDENTIFIER ((LPCSTR)73)
#define PKCS7_SIGNER_INFO ((LPCSTR)500)
#define CMS_SIGNER_INFO ((LPCSTR)501)
June 20, 2018
Re: [PATCH] comctl32/imagelist: fix ImageList_Read/Write.
by Nikolay Sivov
On 06/16/2018 07:19 PM, Denis Malikov wrote:
> From: Denis Malikov <mdn40000(a)mail.ru>
> Date: Sat, 16 Jun 2018 16:35:45 +0700
> Subject: [PATCH] comctl32/imagelist: fix ImageList_Read/Write.
>
> Fix for versions x600 and x620 and pointer calculation for mixing image and mask bits.
>
> Tested on ReactOS 0.4.10 with *.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 | 59 +++++++++++++++++++++++++++--------------------
> 1 file changed, 34 insertions(+), 25 deletions(-)
>
> diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
> index a08d60752e..052d59f9e4 100644
> --- a/dlls/comctl32/imagelist.c
> +++ b/dlls/comctl32/imagelist.c
> @@ -59,7 +59,7 @@ struct _IMAGELIST
> INT cGrow; /* 0C: cGrow */
> INT cx; /* 10: cx */
> INT cy; /* 14: cy */
> - DWORD x4;
> + DWORD x4; /* hack for IL from stream. Keep version here */
> UINT flags; /* 1C: flags */
> COLORREF clrFg; /* 20: foreground color */
> COLORREF clrBk; /* 24: background color */
> @@ -83,6 +83,7 @@ struct _IMAGELIST
> };
The idea is to keep this structure binary compatible, that's why it
starts with a part with specific layout.
If you want to store source stream version, append a new field for that.
I actually like the idea of using
source stream format version to save the list back, it seems like a good
compromise.
>
> #define IMAGELIST_MAGIC 0x53414D58
> +#define IMAGELIST_VERSION 0x101
>
> /* Header used by ImageList_Read() and ImageList_Write() */
> #include "pshpack2.h"
> @@ -806,6 +807,7 @@ ImageList_Create (INT cx, INT cy, UINT flags,
> himl->clrFg = CLR_DEFAULT;
> himl->clrBk = CLR_NONE;
> himl->color_table_set = FALSE;
> + himl->x4 = 0;
>
> /* initialize overlay mask indices */
> for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
> @@ -2257,38 +2259,43 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
> BITMAPINFO *image_info = (BITMAPINFO *)image_buf;
> BITMAPINFO *mask_info = (BITMAPINFO *)mask_buf;
> void *image_bits, *mask_bits = NULL;
> - ILHEAD ilHead;
> - HIMAGELIST himl;
> + ILHEAD ilHead;
> + HIMAGELIST himl;
> unsigned int i;
>
> TRACE("%p\n", pstm);
>
> if (FAILED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL)))
> - return NULL;
> + return NULL;
> if (ilHead.usMagic != (('L' << 8) | 'I'))
> - return NULL;
> - if (ilHead.usVersion != 0x101) /* probably version? */
> - return NULL;
> + return NULL;
No need to reformat existing lines.
> + if (ilHead.usVersion != IMAGELIST_VERSION &&
> + ilHead.usVersion != 0x600 && /* XP/2003 version */
> + ilHead.usVersion != 0x620) /* Vista/7 version */
> + return NULL;
The question is if there's any format differences between 0x600 and
0x620, it was probably bumped for a reason.
>
> TRACE("cx %u, cy %u, flags 0x%04x, cCurImage %u, cMaxImage %u\n",
> ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
>
> himl = ImageList_Create(ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
> if (!himl)
> - return NULL;
> + return NULL;
> +
> + // keep version from stream
> + himl->x4 = ilHead.usVersion;
No cpp-style comments, please.
>
> @@ -3078,10 +3087,10 @@ BOOL WINAPI ImageList_Write(HIMAGELIST himl, IStream *pstm)
> TRACE("%p %p\n", himl, pstm);
>
> if (!is_valid(himl))
> - return FALSE;
> + return FALSE;
>
> ilHead.usMagic = (('L' << 8) | 'I');
> - ilHead.usVersion = 0x101;
> + ilHead.usVersion = himl->x4 > 0 ? himl->x4 : IMAGELIST_VERSION;
> ilHead.cCurImage = himl->cCurImage;
> ilHead.cMaxImage = himl->cMaxImage;
> ilHead.cGrow = himl->cGrow;
> @@ -3090,23 +3099,23 @@ BOOL WINAPI ImageList_Write(HIMAGELIST himl, IStream *pstm)
> ilHead.bkcolor = himl->clrBk;
> ilHead.flags = himl->flags;
> for(i = 0; i < 4; i++) {
> - ilHead.ovls[i] = himl->nOvlIdx[i];
> + ilHead.ovls[i] = himl->nOvlIdx[i];
> }
>
> TRACE("cx %u, cy %u, flags 0x04%x, cCurImage %u, cMaxImage %u\n",
> ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
>
> if(FAILED(IStream_Write(pstm, &ilHead, sizeof(ILHEAD), NULL)))
> - return FALSE;
> + return FALSE;
>
> /* write the bitmap */
> if(!_write_bitmap(himl->hbmImage, pstm))
> - return FALSE;
> + return FALSE;
>
> /* write the mask if we have one */
> if(himl->flags & ILC_MASK) {
> - if(!_write_bitmap(himl->hbmMask, pstm))
> - return FALSE;
> + if(!_write_bitmap(himl->hbmMask, pstm))
> + return FALSE;
> }
Doesn't this write in old format, with mismatching version field?
June 20, 2018
[PATCH 3/3] crypt32: Implement decoding of X509_ECC_SIGNATURE.
by Nikolay Sivov
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/decode.c | 32 ++++++++++++++++++++++++++++++++
1 file changed, 32 insertions(+)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 4f11d0d60f..080feeca0a 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -6013,6 +6013,35 @@ static BOOL WINAPI CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType,
return ret;
}
+static BOOL WINAPI CRYPT_AsnDecodeEccSignature(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ BOOL ret;
+ struct AsnDecodeSequenceItem items[] = {
+ { ASN_INTEGER, offsetof(CERT_ECC_SIGNATURE, r),
+ CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_UINT_BLOB), FALSE,
+ TRUE, offsetof(CERT_ECC_SIGNATURE, r.pbData), 0 },
+ { ASN_INTEGER, offsetof(CERT_ECC_SIGNATURE, s),
+ CRYPT_AsnDecodeUnsignedIntegerInternal, sizeof(CRYPT_UINT_BLOB), FALSE,
+ TRUE, offsetof(CERT_ECC_SIGNATURE, s.pbData), 0 },
+ };
+
+ __TRY
+ {
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
+ pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
+ pcbStructInfo, NULL, NULL);
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
+ return ret;
+}
+
static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
LPCSTR lpszStructType)
{
@@ -6155,6 +6184,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(X509_OBJECT_IDENTIFIER):
decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
break;
+ case LOWORD(X509_ECC_SIGNATURE):
+ decodeFunc = CRYPT_AsnDecodeEccSignature;
+ break;
}
}
else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
--
2.17.1
June 20, 2018
[PATCH 2/3] crypt32: Implement decoding of X509_OBJECT_IDENTIFIER.
by Nikolay Sivov
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/decode.c | 45 +++++++++++++++++++++++++++++++++++++++++++
include/wincrypt.h | 15 +++++++++++++++
2 files changed, 60 insertions(+)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index a61316016f..4f11d0d60f 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -5973,6 +5973,46 @@ BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
return ret;
}
+static BOOL WINAPI CRYPT_AsnDecodeObjectIdentifier(DWORD dwCertEncodingType,
+ LPCSTR lpszStructType, const BYTE *pbEncoded, DWORD cbEncoded, DWORD dwFlags,
+ CRYPT_DECODE_PARA *pDecodePara, void *pvStructInfo, DWORD *pcbStructInfo)
+{
+ DWORD bytesNeeded = 0;
+ BOOL ret;
+
+ __TRY
+ {
+ ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+ NULL, &bytesNeeded, NULL);
+ if (ret)
+ {
+ if (!pvStructInfo)
+ *pcbStructInfo = bytesNeeded;
+ else if ((ret = CRYPT_DecodeEnsureSpace(dwFlags, pDecodePara, pvStructInfo, pcbStructInfo, bytesNeeded)))
+ {
+ LPSTR *info;
+
+ if (dwFlags & CRYPT_DECODE_ALLOC_FLAG)
+ pvStructInfo = *(BYTE **)pvStructInfo;
+
+ info = pvStructInfo;
+ *info = (void *)((BYTE *)info + sizeof(*info));
+ ret = CRYPT_AsnDecodeOidInternal(pbEncoded, cbEncoded, dwFlags & ~CRYPT_DECODE_ALLOC_FLAG,
+ pvStructInfo, &bytesNeeded, NULL);
+ if (!ret && (dwFlags & CRYPT_DECODE_ALLOC_FLAG))
+ CRYPT_FreeSpace(pDecodePara, info);
+ }
+ }
+ }
+ __EXCEPT_PAGE_FAULT
+ {
+ SetLastError(STATUS_ACCESS_VIOLATION);
+ ret = FALSE;
+ }
+ __ENDTRY
+ return ret;
+}
+
static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
LPCSTR lpszStructType)
{
@@ -6112,6 +6152,9 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
case LOWORD(CMS_SIGNER_INFO):
decodeFunc = CRYPT_AsnDecodeCMSSignerInfo;
break;
+ case LOWORD(X509_OBJECT_IDENTIFIER):
+ decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
+ break;
}
}
else if (!strcmp(lpszStructType, szOID_CERT_EXTENSIONS))
@@ -6166,6 +6209,8 @@ static CryptDecodeObjectExFunc CRYPT_GetBuiltinDecoder(DWORD dwCertEncodingType,
decodeFunc = CRYPT_AsnDecodePolicyQualifierUserNotice;
else if (!strcmp(lpszStructType, szOID_CTL))
decodeFunc = CRYPT_AsnDecodeCTL;
+ else if (!strcmp(lpszStructType, szOID_ECC_PUBLIC_KEY))
+ decodeFunc = CRYPT_AsnDecodeObjectIdentifier;
return decodeFunc;
}
diff --git a/include/wincrypt.h b/include/wincrypt.h
index 6e71fb902e..a7c24e7831 100644
--- a/include/wincrypt.h
+++ b/include/wincrypt.h
@@ -288,6 +288,11 @@ typedef struct _CERT_KEY_ATTRIBUTES_INFO {
PCERT_PRIVATE_KEY_VALIDITY pPrivateKeyUsagePeriod;
} CERT_KEY_ATTRIBUTES_INFO, *PCERT_KEY_ATTRIBUTES_INFO;
+typedef struct _CERT_ECC_SIGNATURE {
+ CRYPT_UINT_BLOB r;
+ CRYPT_UINT_BLOB s;
+} CERT_ECC_SIGNATURE, *PCERT_ECC_SIGNATURE;
+
/* byte 0 */
#define CERT_DIGITAL_SIGNATURE_KEY_USAGE 0x80
#define CERT_NON_REPUDIATION_KEY_USAGE 0x40
@@ -2878,6 +2883,12 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define szOID_X957 "1.2.840.10040"
#define szOID_X957_DSA "1.2.840.10040.4.1"
#define szOID_X957_SHA1DSA "1.2.840.10040.4.3"
+#define szOID_ECC_PUBLIC_KEY "1.2.840.10045.2.1"
+#define szOID_ECC_CURVE_P256 "1.2.840.10045.3.1.7"
+#define szOID_ECDSA_SPECIFIED "1.2.840.10045.4.3"
+#define szOID_ECDSA_SHA256 "1.2.840.10045.4.3.2"
+#define szOID_ECDSA_SHA384 "1.2.840.10045.4.3.3"
+#define szOID_ECDSA_SHA512 "1.2.840.10045.4.3.4"
#define szOID_DS "2.5"
#define szOID_DSALG "2.5.8"
#define szOID_DSALG_CRPT "2.5.8.1"
@@ -2919,6 +2930,8 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define szOID_OIWDIR_SIGN "1.3.14.7.2.3"
#define szOID_OIWDIR_md2 "1.3.14.7.2.2.1"
#define szOID_OIWDIR_md2RSA "1.3.14.7.2.3.1"
+#define szOID_ECC_CURVE_P384 "1.3.132.0.34"
+#define szOID_ECC_CURVE_P521 "1.3.132.0.35"
#define szOID_INFOSEC "2.16.840.1.101.2.1"
#define szOID_INFOSEC_sdnsSignature "2.16.840.1.101.2.1.1.1"
#define szOID_INFOSEC_mosaicSignature "2.16.840.1.101.2.1.1.2"
@@ -3223,6 +3236,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define X509_PKIX_POLICY_QUALIFIER_USERNOTICE ((LPCSTR)46)
#define X509_DH_PUBLICKEY X509_MULTI_BYTE_UINT
#define X509_DH_PARAMETERS ((LPCSTR)47)
+#define X509_ECC_SIGNATURE ((LPCSTR)47)
#define PKCS_ATTRIBUTES ((LPCSTR)48)
#define PKCS_SORTED_CTL ((LPCSTR)49)
#define X942_DH_PARAMETERS ((LPCSTR)50)
@@ -3240,6 +3254,7 @@ typedef struct _CTL_FIND_SUBJECT_PARA
#define CMC_ADD_EXTENSIONS ((LPCSTR)62)
#define CMC_ADD_ATTRIBUTES ((LPCSTR)63)
#define X509_CERTIFICATE_TEMPLATE ((LPCSTR)64)
+#define X509_OBJECT_IDENTIFIER ((LPCSTR)73)
#define PKCS7_SIGNER_INFO ((LPCSTR)500)
#define CMS_SIGNER_INFO ((LPCSTR)501)
--
2.17.1
June 20, 2018
[PATCH 1/3] crypt32: Use ARRAY_SIZE macro.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/crypt32/cert.c | 3 +-
dlls/crypt32/chain.c | 20 ++---
dlls/crypt32/crypt32_private.h | 2 +
dlls/crypt32/decode.c | 89 +++++++++----------
dlls/crypt32/encode.c | 52 +++++------
dlls/crypt32/filestore.c | 3 +-
dlls/crypt32/msg.c | 2 +-
dlls/crypt32/object.c | 155 ++++++++++++---------------------
dlls/crypt32/oid.c | 9 +-
dlls/crypt32/regstore.c | 9 +-
dlls/crypt32/rootstore.c | 6 +-
dlls/crypt32/sip.c | 5 +-
dlls/crypt32/store.c | 7 +-
dlls/crypt32/str.c | 6 +-
14 files changed, 150 insertions(+), 218 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index a4b43ff155..83aac5d8f4 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -987,8 +987,7 @@ static BOOL container_matches_cert(PCCERT_CONTEXT pCert, LPCSTR container,
WCHAR containerW[MAX_PATH];
BOOL matches;
- MultiByteToWideChar(CP_ACP, 0, container, -1,
- containerW, sizeof(containerW) / sizeof(containerW[0]));
+ MultiByteToWideChar(CP_ACP, 0, container, -1, containerW, ARRAY_SIZE(containerW));
/* We make a copy of the CRYPT_KEY_PROV_INFO because the caller expects
* keyProvInfo->pwszContainerName to be NULL or a heap-allocated container
* name.
diff --git a/dlls/crypt32/chain.c b/dlls/crypt32/chain.c
index aab2e91583..dd3fc33db6 100644
--- a/dlls/crypt32/chain.c
+++ b/dlls/crypt32/chain.c
@@ -146,9 +146,9 @@ HCERTCHAINENGINE CRYPT_CreateChainEngine(HCERTSTORE root, DWORD system_store, co
worldStores[2] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, myW);
worldStores[3] = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0, system_store, trustW);
- CRYPT_AddStoresToCollection(engine->hWorld, sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
- CRYPT_AddStoresToCollection(engine->hWorld, config->cAdditionalStore, config->rghAdditionalStore);
- CRYPT_CloseStores(sizeof(worldStores) / sizeof(worldStores[0]), worldStores);
+ CRYPT_AddStoresToCollection(engine->hWorld, ARRAY_SIZE(worldStores), worldStores);
+ CRYPT_AddStoresToCollection(engine->hWorld, config->cAdditionalStore, config->rghAdditionalStore);
+ CRYPT_CloseStores(ARRAY_SIZE(worldStores), worldStores);
engine->dwFlags = config->dwFlags;
engine->dwUrlRetrievalTimeout = config->dwUrlRetrievalTimeout;
@@ -1688,11 +1688,9 @@ static LPCSTR filetime_to_str(const FILETIME *time)
if (!time) return "(null)";
- GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, dateFmt,
- sizeof(dateFmt) / sizeof(dateFmt[0]));
+ GetLocaleInfoA(LOCALE_SYSTEM_DEFAULT, LOCALE_SSHORTDATE, dateFmt, ARRAY_SIZE(dateFmt));
FileTimeToSystemTime(time, &sysTime);
- GetDateFormatA(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, date,
- sizeof(date) / sizeof(date[0]));
+ GetDateFormatA(LOCALE_SYSTEM_DEFAULT, 0, &sysTime, dateFmt, date, ARRAY_SIZE(date));
return wine_dbg_sprintf("%s", date);
}
@@ -3117,8 +3115,7 @@ static BOOL WINAPI verify_authenticode_policy(LPCSTR szPolicyOID,
};
/* Check whether the root is an MS test root */
- for (i = 0; !isMSTestRoot && i < sizeof(keyBlobs) / sizeof(keyBlobs[0]);
- i++)
+ for (i = 0; !isMSTestRoot && i < ARRAY_SIZE(keyBlobs); i++)
{
msPubKey.PublicKey.cbData = keyBlobs[i].cbData;
msPubKey.PublicKey.pbData = keyBlobs[i].pbData;
@@ -3408,7 +3405,7 @@ static BOOL match_dns_to_subject_dn(PCCERT_CONTEXT cert, LPCWSTR server_name)
end = dot ? dot : ptr + strlenW(ptr);
len = end - ptr;
- if (len >= sizeof(component) / sizeof(component[0]))
+ if (len >= ARRAY_SIZE(component))
{
WARN_(chain)("domain component %s too long\n",
debugstr_wn(ptr, len));
@@ -3690,8 +3687,7 @@ static BOOL WINAPI verify_ms_root_policy(LPCSTR szPolicyOID,
PCCERT_CONTEXT root =
rootChain->rgpElement[rootChain->cElement - 1]->pCertContext;
- for (i = 0; !isMSRoot && i < sizeof(keyBlobs) / sizeof(keyBlobs[0]);
- i++)
+ for (i = 0; !isMSRoot && i < ARRAY_SIZE(keyBlobs); i++)
{
msPubKey.PublicKey.cbData = keyBlobs[i].cbData;
msPubKey.PublicKey.pbData = keyBlobs[i].pbData;
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index 8b1b003a12..dbf6dca411 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -21,6 +21,8 @@
#include "wine/list.h"
+#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
+
/* a few asn.1 tags we need */
#define ASN_BOOL (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x01)
#define ASN_BITSTRING (ASN_UNIVERSAL | ASN_PRIMITIVE | 0x03)
diff --git a/dlls/crypt32/decode.c b/dlls/crypt32/decode.c
index 8b84388b12..a61316016f 100644
--- a/dlls/crypt32/decode.c
+++ b/dlls/crypt32/decode.c
@@ -890,7 +890,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertSignedContent(DWORD dwCertEncodingType,
if (dwFlags & CRYPT_DECODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
items[2].decodeFunc = CRYPT_AsnDecodeBitsInternal;
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -935,7 +935,7 @@ static BOOL CRYPT_AsnDecodeValidity(const BYTE *pbEncoded, DWORD cbEncoded,
CRYPT_AsnDecodeChoiceOfTimeInternal, sizeof(FILETIME), FALSE, FALSE, 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, NULL);
return ret;
@@ -1020,7 +1020,7 @@ static BOOL CRYPT_AsnDecodeCertInfo(DWORD dwCertEncodingType,
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
NULL, NULL);
if (ret && pvStructInfo)
@@ -1135,7 +1135,7 @@ static BOOL CRYPT_AsnDecodeCRLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
*pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo, pcbDecoded,
entry ? entry->SerialNumber.pbData : NULL);
if (ret && entry && !entry->SerialNumber.cbData)
@@ -1236,9 +1236,8 @@ static BOOL CRYPT_AsnDecodeCRLInfo(DWORD dwCertEncodingType,
TRACE("%p, %d, %08x, %p, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
- pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo, pcbStructInfo,
- NULL, NULL);
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags,
+ pDecodePara, pvStructInfo, pcbStructInfo, NULL, NULL);
TRACE("Returning %d (%08x)\n", ret, GetLastError());
return ret;
@@ -1433,7 +1432,7 @@ static BOOL CRYPT_AsnDecodeExtension(const BYTE *pbEncoded, DWORD cbEncoded,
if (ext)
TRACE("ext->pszObjId is %p\n", ext->pszObjId);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, ext, pcbStructInfo,
pcbDecoded, ext ? ext->pszObjId : NULL);
if (ext)
@@ -1871,7 +1870,7 @@ static BOOL CRYPT_AsnDecodeRdnAttr(const BYTE *pbEncoded, DWORD cbEncoded,
if (attr)
TRACE("attr->pszObjId is %p\n", attr->pszObjId);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
attr ? attr->pszObjId : NULL);
if (attr)
@@ -1968,7 +1967,7 @@ static BOOL CRYPT_AsnDecodeUnicodeRdnAttr(const BYTE *pbEncoded,
if (attr)
TRACE("attr->pszObjId is %p\n", attr->pszObjId);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, attr, pcbStructInfo, pcbDecoded,
attr ? attr->pszObjId : NULL);
if (attr)
@@ -2197,7 +2196,7 @@ static BOOL CRYPT_AsnDecodeCTLEntry(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags, entry,
*pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, entry, pcbStructInfo,
pcbDecoded, entry ? entry->SubjectIdentifier.pbData : NULL);
return ret;
@@ -2300,7 +2299,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCTL(DWORD dwCertEncodingType,
TRUE, TRUE, offsetof(CTL_INFO, rgExtension), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -2330,7 +2329,7 @@ static BOOL CRYPT_AsnDecodeSMIMECapability(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, capability ? capability->pszObjId : NULL);
TRACE("returning %d\n", ret);
@@ -2460,7 +2459,7 @@ static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, NULL, &bytesNeeded, pcbDecoded,
NULL);
if (ret)
@@ -2496,10 +2495,8 @@ static BOOL CRYPT_AsnDecodeNoticeReference(const BYTE *pbEncoded,
*(PCERT_POLICY_QUALIFIER_NOTICE_REFERENCE *)pvStructInfo;
noticeRef->pszOrganization = (LPSTR)((LPBYTE)noticeRef +
sizeof(CERT_POLICY_QUALIFIER_NOTICE_REFERENCE));
- ret = CRYPT_AsnDecodeSequence(items,
- sizeof(items) / sizeof(items[0]), pbEncoded, cbEncoded, dwFlags,
- NULL, noticeRef, &bytesNeeded, pcbDecoded,
- noticeRef->pszOrganization);
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items), pbEncoded, cbEncoded, dwFlags,
+ NULL, noticeRef, &bytesNeeded, pcbDecoded, noticeRef->pszOrganization);
}
}
TRACE("returning %d\n", ret);
@@ -2653,7 +2650,7 @@ static BOOL CRYPT_AsnDecodePolicyQualifierUserNoticeInternal(
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, notice ? notice->pNoticeReference : NULL);
TRACE("returning %d\n", ret);
@@ -2748,7 +2745,7 @@ static BOOL CRYPT_AsnDecodePKCSAttributeInternal(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, attr ? attr->pszObjId : NULL);
TRACE("returning %d\n", ret);
@@ -2866,7 +2863,7 @@ static BOOL CRYPT_AsnDecodeAlgorithmId(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, algo ? algo->pszObjId : NULL);
if (ret && pvStructInfo)
@@ -2893,7 +2890,7 @@ static BOOL CRYPT_AsnDecodePubKeyInfoInternal(const BYTE *pbEncoded,
};
PCERT_PUBLIC_KEY_INFO info = pvStructInfo;
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->Algorithm.Parameters.pbData : NULL);
return ret;
@@ -3150,7 +3147,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId(DWORD dwCertEncodingType,
offsetof(CERT_AUTHORITY_KEY_ID_INFO, CertSerialNumber.pbData), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -3187,7 +3184,7 @@ static BOOL WINAPI CRYPT_AsnDecodeAuthorityKeyId2(DWORD dwCertEncodingType,
AuthorityCertSerialNumber.pbData), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -3214,7 +3211,7 @@ static BOOL CRYPT_AsnDecodeAccessDescription(const BYTE *pbEncoded,
};
CERT_ACCESS_DESCRIPTION *descr = pvStructInfo;
- return CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ return CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, descr ? descr->pszAccessMethod : NULL);
}
@@ -3323,7 +3320,7 @@ static BOOL CRYPT_AsnDecodePKCSContentInfoInternal(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->pszObjId : NULL);
return ret;
@@ -3392,7 +3389,7 @@ BOOL CRYPT_AsnDecodePKCSDigestedData(const BYTE *pbEncoded, DWORD cbEncoded,
offsetof(CRYPT_DIGESTED_DATA, hash.pbData), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, digestedData, pcbDigestedData,
NULL, NULL);
return ret;
@@ -3531,7 +3528,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints(DWORD dwCertEncodingType,
offsetof(CERT_BASIC_CONSTRAINTS_INFO, rgSubtreesConstraint), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -3560,7 +3557,7 @@ static BOOL WINAPI CRYPT_AsnDecodeBasicConstraints2(DWORD dwCertEncodingType,
sizeof(struct PATH_LEN_CONSTRAINT), TRUE, FALSE, 0, 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -3592,7 +3589,7 @@ static BOOL CRYPT_AsnDecodePolicyQualifier(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, qualifier ? qualifier->pszPolicyQualifierId : NULL);
return ret;
@@ -3637,7 +3634,7 @@ static BOOL CRYPT_AsnDecodeCertPolicy(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->pszPolicyIdentifier : NULL);
return ret;
@@ -3694,7 +3691,7 @@ static BOOL CRYPT_AsnDecodeCertPolicyMapping(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, pvStructInfo ? *pcbStructInfo : 0);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, mapping ? mapping->pszIssuerDomainPolicy : NULL);
return ret;
@@ -3851,7 +3848,7 @@ static BOOL WINAPI CRYPT_AsnDecodeCertPolicyConstraints(
TRUE, FALSE, 0, 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -3890,7 +3887,7 @@ static BOOL WINAPI CRYPT_AsnDecodeRsaPubKey(DWORD dwCertEncodingType,
struct DECODED_RSA_PUB_KEY *decodedKey = NULL;
DWORD size = 0;
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
&size, NULL, NULL);
if (ret)
@@ -3998,7 +3995,7 @@ static BOOL WINAPI CRYPT_AsnDecodeRsaPrivKey(DWORD dwCertEncodingType,
struct DECODED_RSA_PRIV_KEY *decodedKey = NULL;
DWORD size = 0;
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, CRYPT_DECODE_ALLOC_FLAG, NULL, &decodedKey,
&size, NULL, NULL);
if (ret)
@@ -5242,7 +5239,7 @@ static BOOL CRYPT_AsnDecodeDistPoint(const BYTE *pbEncoded, DWORD cbEncoded,
CRL_DIST_POINT *point = pvStructInfo;
BOOL ret;
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, point ? point->DistPointName.u.FullName.rgAltEntry : NULL);
return ret;
@@ -5344,7 +5341,7 @@ static BOOL WINAPI CRYPT_AsnDecodeIssuingDistPoint(DWORD dwCertEncodingType,
fIndirectCRL), CRYPT_AsnDecodeBool, sizeof(BOOL), TRUE, FALSE, 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -5427,7 +5424,7 @@ static BOOL CRYPT_AsnDecodeSubtree(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, subtree ? subtree->Base.u.pwszURL : NULL);
if (pcbDecoded)
@@ -5508,7 +5505,7 @@ static BOOL WINAPI CRYPT_AsnDecodeNameConstraints(DWORD dwCertEncodingType,
offsetof(CERT_NAME_CONSTRAINTS_INFO, rgExcludedSubtree), 0 },
};
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, pvStructInfo,
pcbStructInfo, NULL, NULL);
}
@@ -5538,7 +5535,7 @@ static BOOL CRYPT_AsnDecodeIssuerSerialNumber(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, issuerSerial ? issuerSerial->Issuer.pbData : NULL);
if (ret && issuerSerial && !issuerSerial->SerialNumber.cbData)
@@ -5585,7 +5582,7 @@ static BOOL CRYPT_AsnDecodePKCSSignerInfoInternal(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->Issuer.pbData : NULL);
return ret;
@@ -5751,7 +5748,7 @@ static BOOL CRYPT_AsnDecodeCMSSignerInfoInternal(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->SignerId.u.KeyId.pbData : NULL);
return ret;
@@ -5851,7 +5848,7 @@ BOOL CRYPT_AsnDecodeCMSSignedInfo(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, signedInfo, pcbSignedInfo);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, signedInfo, pcbSignedInfo,
NULL, NULL);
TRACE("returning %d\n", ret);
@@ -5884,7 +5881,7 @@ static BOOL CRYPT_AsnDecodeRecipientInfo(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->RecipientId.u.IssuerSerialNumber.Issuer.pbData :
NULL);
@@ -5941,7 +5938,7 @@ static BOOL CRYPT_AsnDecodeEncryptedContentInfo(const BYTE *pbEncoded,
TRACE("%p, %d, %08x, %p, %d, %p\n", pbEncoded, cbEncoded, dwFlags,
pvStructInfo, *pcbStructInfo, pcbDecoded);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, NULL, pvStructInfo, pcbStructInfo,
pcbDecoded, info ? info->contentType : NULL);
TRACE("returning %d\n", ret);
@@ -5969,7 +5966,7 @@ BOOL CRYPT_AsnDecodePKCSEnvelopedData(const BYTE *pbEncoded, DWORD cbEncoded,
TRACE("%p, %d, %08x, %p, %p, %p\n", pbEncoded, cbEncoded, dwFlags,
pDecodePara, envelopedData, pcbEnvelopedData);
- ret = CRYPT_AsnDecodeSequence(items, sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnDecodeSequence(items, ARRAY_SIZE(items),
pbEncoded, cbEncoded, dwFlags, pDecodePara, envelopedData,
pcbEnvelopedData, NULL, NULL);
TRACE("returning %d\n", ret);
diff --git a/dlls/crypt32/encode.c b/dlls/crypt32/encode.c
index 6f9f595f4f..62d2bc91f7 100644
--- a/dlls/crypt32/encode.c
+++ b/dlls/crypt32/encode.c
@@ -372,7 +372,7 @@ static BOOL WINAPI CRYPT_AsnEncodeValidity(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
@@ -400,7 +400,7 @@ static BOOL WINAPI CRYPT_AsnEncodeAlgorithmIdWithNullParams(
else
items[1].pvStructInfo = &nullBlob;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
@@ -417,7 +417,7 @@ static BOOL WINAPI CRYPT_AsnEncodeAlgorithmId(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
@@ -439,7 +439,7 @@ static BOOL WINAPI CRYPT_AsnEncodePubKeyInfo(DWORD dwCertEncodingType,
TRACE("Encoding public key with OID %s\n",
debugstr_a(info->Algorithm.pszObjId));
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
__EXCEPT_PAGE_FAULT
@@ -469,7 +469,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCert(DWORD dwCertEncodingType,
if (dwFlags & CRYPT_ENCODE_NO_SIGNATURE_BYTE_REVERSAL_FLAG)
items[2].encodeFunc = CRYPT_AsnEncodeBits;
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
__EXCEPT_PAGE_FAULT
@@ -495,7 +495,7 @@ BOOL WINAPI CRYPT_AsnEncodePubKeyInfoNoNull(DWORD dwCertEncodingType,
TRACE("Encoding public key with OID %s\n",
debugstr_a(info->Algorithm.pszObjId));
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
@@ -1530,7 +1530,7 @@ static BOOL CRYPT_AsnEncodeCTLEntry(const CTL_ENTRY *entry,
BOOL ret;
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
- sizeof(items) / sizeof(items[0]), 0, NULL, pbEncoded, pcbEncoded);
+ ARRAY_SIZE(items), 0, NULL, pbEncoded, pcbEncoded);
return ret;
}
@@ -1679,7 +1679,7 @@ static BOOL CRYPT_AsnEncodeSMIMECapability(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
}
@@ -1822,7 +1822,7 @@ static BOOL WINAPI CRYPT_AsnEncodeNoticeReference(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
return ret;
}
@@ -1887,7 +1887,7 @@ static BOOL WINAPI CRYPT_AsnEncodePKCSAttribute(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded,
pcbEncoded);
}
}
@@ -1960,8 +1960,7 @@ BOOL CRYPT_AsnEncodePKCSDigestedData(const CRYPT_DIGESTED_DATA *digestedData,
{ &digestedData->hash, CRYPT_AsnEncodeOctets, 0 },
};
- return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
- sizeof(items) / sizeof(items[0]), 0, NULL, pvData, pcbData);
+ return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, ARRAY_SIZE(items), 0, NULL, pvData, pcbData);
}
static BOOL WINAPI CRYPT_AsnEncodePKCSContentInfo(DWORD dwCertEncodingType,
@@ -2708,8 +2707,7 @@ static BOOL CRYPT_AsnEncodeAccessDescription(
SetLastError(E_INVALIDARG);
return FALSE;
}
- return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
- sizeof(items) / sizeof(items[0]), 0, NULL, pbEncoded, pcbEncoded);
+ return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items, ARRAY_SIZE(items), 0, NULL, pbEncoded, pcbEncoded);
}
static BOOL WINAPI CRYPT_AsnEncodeAuthorityInfoAccess(DWORD dwCertEncodingType,
@@ -2877,8 +2875,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType,
items[0].pvStructInfo =
info->rgPolicyQualifier[i].pszPolicyQualifierId;
items[1].pvStructInfo = &info->rgPolicyQualifier[i].Qualifier;
- ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, ARRAY_SIZE(items),
dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, NULL, &size);
if (ret)
bytesNeeded += size;
@@ -2909,8 +2906,7 @@ static BOOL WINAPI CRYPT_AsnEncodeCertPolicyQualifiers(DWORD dwCertEncodingType,
items[1].pvStructInfo =
&info->rgPolicyQualifier[i].Qualifier;
size = bytesNeeded;
- ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]),
+ ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, ARRAY_SIZE(items),
dwFlags & ~CRYPT_ENCODE_ALLOC_FLAG, NULL, out, &size);
if (ret)
{
@@ -2942,8 +2938,7 @@ static BOOL CRYPT_AsnEncodeCertPolicy(DWORD dwCertEncodingType,
SetLastError(E_INVALIDARG);
return FALSE;
}
- ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, NULL, pbEncoded, pcbEncoded);
+ ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items, ARRAY_SIZE(items), dwFlags, NULL, pbEncoded, pcbEncoded);
return ret;
}
@@ -3026,8 +3021,7 @@ static BOOL CRYPT_AsnEncodeCertPolicyMapping(DWORD dwCertEncodingType,
SetLastError(E_INVALIDARG);
return FALSE;
}
- return CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, NULL, pbEncoded, pcbEncoded);
+ return CRYPT_AsnEncodeSequence(dwCertEncodingType, items, ARRAY_SIZE(items), dwFlags, NULL, pbEncoded, pcbEncoded);
}
static BOOL WINAPI CRYPT_AsnEncodeCertPolicyMappings(DWORD dwCertEncodingType,
@@ -3169,8 +3163,7 @@ static BOOL WINAPI CRYPT_AsnEncodeRsaPubKey(DWORD dwCertEncodingType,
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
- pcbEncoded);
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
}
__EXCEPT_PAGE_FAULT
@@ -4151,8 +4144,7 @@ static BOOL WINAPI CRYPT_AsnEncodeIssuerSerialNumber(
};
ret = CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
- pcbEncoded);
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded);
return ret;
}
@@ -4402,8 +4394,7 @@ static BOOL WINAPI CRYPT_AsnEncodeRecipientInfo(DWORD dwCertEncodingType,
};
return CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
- pcbEncoded);
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
static BOOL WINAPI CRYPT_AsnEncodeEncryptedContentInfo(DWORD dwCertEncodingType,
@@ -4421,8 +4412,7 @@ static BOOL WINAPI CRYPT_AsnEncodeEncryptedContentInfo(DWORD dwCertEncodingType,
};
return CRYPT_AsnEncodeSequence(dwCertEncodingType, items,
- sizeof(items) / sizeof(items[0]), dwFlags, pEncodePara, pbEncoded,
- pcbEncoded);
+ ARRAY_SIZE(items), dwFlags, pEncodePara, pbEncoded, pcbEncoded);
}
BOOL CRYPT_AsnEncodePKCSEnvelopedData(const CRYPT_ENVELOPED_DATA *envelopedData,
@@ -4439,7 +4429,7 @@ BOOL CRYPT_AsnEncodePKCSEnvelopedData(const CRYPT_ENVELOPED_DATA *envelopedData,
};
return CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
- sizeof(items) / sizeof(items[0]), 0, NULL, pvData, pcbData);
+ ARRAY_SIZE(items), 0, NULL, pvData, pcbData);
}
static CryptEncodeObjectExFunc CRYPT_GetBuiltinEncoder(DWORD dwCertEncodingType,
diff --git a/dlls/crypt32/filestore.c b/dlls/crypt32/filestore.c
index 0f7d8d5150..9c211e14b1 100644
--- a/dlls/crypt32/filestore.c
+++ b/dlls/crypt32/filestore.c
@@ -231,8 +231,7 @@ static WINECRYPT_CERTSTORE *CRYPT_CreateFileStore(DWORD dwFlags,
info->type = type;
info->dirty = FALSE;
provInfo.cbSize = sizeof(provInfo);
- provInfo.cStoreProvFunc = sizeof(fileProvFuncs) /
- sizeof(fileProvFuncs[0]);
+ provInfo.cStoreProvFunc = ARRAY_SIZE(fileProvFuncs);
provInfo.rgpvStoreProvFunc = fileProvFuncs;
provInfo.hStoreProv = info;
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
diff --git a/dlls/crypt32/msg.c b/dlls/crypt32/msg.c
index fd43a7baeb..005fbf2c1f 100644
--- a/dlls/crypt32/msg.c
+++ b/dlls/crypt32/msg.c
@@ -175,7 +175,7 @@ static BOOL CRYPT_EncodeDataContentInfoHeader(const CDataEncodeMsg *msg,
};
ret = CRYPT_AsnEncodeSequence(X509_ASN_ENCODING, items,
- sizeof(items) / sizeof(items[0]), CRYPT_ENCODE_ALLOC_FLAG, NULL,
+ ARRAY_SIZE(items), CRYPT_ENCODE_ALLOC_FLAG, NULL,
(LPBYTE)&header->pbData, &header->cbData);
if (ret)
{
diff --git a/dlls/crypt32/object.c b/dlls/crypt32/object.c
index 0320cfda1b..3dc28af0e9 100644
--- a/dlls/crypt32/object.c
+++ b/dlls/crypt32/object.c
@@ -929,8 +929,7 @@ static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType,
WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
DWORD bytesNeeded = sizeof(WCHAR);
- LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
- sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+ LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable));
if (!bits->cbData || bits->cbData > 2)
{
bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
@@ -959,26 +958,18 @@ static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- for (i = 0;
- i < sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]);
- i++)
- LoadStringW(hInstance, keyUsageByte0Map[i].id,
- keyUsageByte0Map[i].str, MAX_STRING_RESOURCE_LEN);
- for (i = 0;
- i < sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]);
- i++)
- LoadStringW(hInstance, keyUsageByte1Map[i].id,
- keyUsageByte1Map[i].str, MAX_STRING_RESOURCE_LEN);
+ for (i = 0; i < ARRAY_SIZE(keyUsageByte0Map); i++)
+ LoadStringW(hInstance, keyUsageByte0Map[i].id, keyUsageByte0Map[i].str, MAX_STRING_RESOURCE_LEN);
+ for (i = 0; i < ARRAY_SIZE(keyUsageByte1Map); i++)
+ LoadStringW(hInstance, keyUsageByte1Map[i].id, keyUsageByte1Map[i].str, MAX_STRING_RESOURCE_LEN);
stringsLoaded = TRUE;
}
- CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map,
- sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]),
- NULL, &bitStringLen, &first);
+ CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map, ARRAY_SIZE(keyUsageByte0Map),
+ NULL, &bitStringLen, &first);
bytesNeeded += bitStringLen;
if (bits->cbData == 2)
{
- CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map,
- sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]),
+ CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map, ARRAY_SIZE(keyUsageByte1Map),
NULL, &bitStringLen, &first);
bytesNeeded += bitStringLen;
}
@@ -1000,15 +991,13 @@ static BOOL WINAPI CRYPT_FormatKeyUsage(DWORD dwCertEncodingType,
bitStringLen = bytesNeeded;
first = TRUE;
- CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map,
- sizeof(keyUsageByte0Map) / sizeof(keyUsageByte0Map[0]),
+ CRYPT_FormatBits(bits->pbData[0], keyUsageByte0Map, ARRAY_SIZE(keyUsageByte0Map),
str, &bitStringLen, &first);
str += bitStringLen / sizeof(WCHAR) - 1;
if (bits->cbData == 2)
{
bitStringLen = bytesNeeded;
- CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map,
- sizeof(keyUsageByte1Map) / sizeof(keyUsageByte1Map[0]),
+ CRYPT_FormatBits(bits->pbData[1], keyUsageByte1Map, ARRAY_SIZE(keyUsageByte1Map),
str, &bitStringLen, &first);
str += bitStringLen / sizeof(WCHAR) - 1;
}
@@ -1070,15 +1059,10 @@ static BOOL WINAPI CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- LoadStringW(hInstance, IDS_SUBJECT_TYPE, subjectTypeHeader,
- sizeof(subjectTypeHeader) / sizeof(subjectTypeHeader[0]));
- LoadStringW(hInstance, IDS_SUBJECT_TYPE_CA, subjectTypeCA,
- sizeof(subjectTypeCA) / sizeof(subjectTypeCA[0]));
- LoadStringW(hInstance, IDS_SUBJECT_TYPE_END_CERT,
- subjectTypeEndCert,
- sizeof(subjectTypeEndCert) / sizeof(subjectTypeEndCert[0]));
- LoadStringW(hInstance, IDS_PATH_LENGTH, pathLengthHeader,
- sizeof(pathLengthHeader) / sizeof(pathLengthHeader[0]));
+ LoadStringW(hInstance, IDS_SUBJECT_TYPE, subjectTypeHeader, ARRAY_SIZE(subjectTypeHeader));
+ LoadStringW(hInstance, IDS_SUBJECT_TYPE_CA, subjectTypeCA, ARRAY_SIZE(subjectTypeCA));
+ LoadStringW(hInstance, IDS_SUBJECT_TYPE_END_CERT, subjectTypeEndCert, ARRAY_SIZE(subjectTypeEndCert));
+ LoadStringW(hInstance, IDS_PATH_LENGTH, pathLengthHeader, ARRAY_SIZE(pathLengthHeader));
stringsLoaded = TRUE;
}
bytesNeeded += strlenW(subjectTypeHeader) * sizeof(WCHAR);
@@ -1092,8 +1076,7 @@ static BOOL WINAPI CRYPT_FormatBasicConstraints2(DWORD dwCertEncodingType,
if (info->fPathLenConstraint)
sprintfW(pathLength, pathFmt, info->dwPathLenConstraint);
else
- LoadStringW(hInstance, IDS_PATH_LENGTH_NONE, pathLength,
- sizeof(pathLength) / sizeof(pathLength[0]));
+ LoadStringW(hInstance, IDS_PATH_LENGTH_NONE, pathLength, ARRAY_SIZE(pathLength));
bytesNeeded += strlenW(pathLength) * sizeof(WCHAR);
if (!pbFormat)
*pcbFormat = bytesNeeded;
@@ -1130,7 +1113,7 @@ static BOOL CRYPT_FormatHexStringWithPrefix(const CRYPT_DATA_BLOB *blob, int id,
DWORD bytesNeeded;
BOOL ret;
- LoadStringW(hInstance, id, buf, sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, id, buf, ARRAY_SIZE(buf));
CRYPT_FormatHexString(X509_ASN_ENCODING, 0, 0, NULL, NULL,
blob->pbData, blob->cbData, NULL, &bytesNeeded);
bytesNeeded += strlenW(buf) * sizeof(WCHAR);
@@ -1189,14 +1172,12 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel,
switch (entry->dwAltNameChoice)
{
case CERT_ALT_NAME_RFC822_NAME:
- LoadStringW(hInstance, IDS_ALT_NAME_RFC822_NAME, buf,
- sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_RFC822_NAME, buf, ARRAY_SIZE(buf));
bytesNeeded += strlenW(entry->u.pwszRfc822Name) * sizeof(WCHAR);
ret = TRUE;
break;
case CERT_ALT_NAME_DNS_NAME:
- LoadStringW(hInstance, IDS_ALT_NAME_DNS_NAME, buf,
- sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_DNS_NAME, buf, ARRAY_SIZE(buf));
bytesNeeded += strlenW(entry->u.pwszDNSName) * sizeof(WCHAR);
ret = TRUE;
break;
@@ -1208,8 +1189,7 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel,
strType |= CERT_NAME_STR_CRLF_FLAG;
directoryNameLen = cert_name_to_str_with_indent(X509_ASN_ENCODING,
indentLevel + 1, &entry->u.DirectoryName, strType, NULL, 0);
- LoadStringW(hInstance, IDS_ALT_NAME_DIRECTORY_NAME, buf,
- sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_DIRECTORY_NAME, buf, ARRAY_SIZE(buf));
bytesNeeded += (directoryNameLen - 1) * sizeof(WCHAR);
if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
bytesNeeded += strlenW(colonCrlf) * sizeof(WCHAR);
@@ -1219,8 +1199,7 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel,
break;
}
case CERT_ALT_NAME_URL:
- LoadStringW(hInstance, IDS_ALT_NAME_URL, buf,
- sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_URL, buf, ARRAY_SIZE(buf));
bytesNeeded += strlenW(entry->u.pwszURL) * sizeof(WCHAR);
ret = TRUE;
break;
@@ -1232,14 +1211,12 @@ static BOOL CRYPT_FormatAltNameEntry(DWORD dwFormatStrType, DWORD indentLevel,
static const WCHAR ipAddrFmt[] = { '%','d','.','%','d','.','%','d',
'.','%','d',0 };
- LoadStringW(hInstance, IDS_ALT_NAME_IP_ADDRESS, buf,
- sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_IP_ADDRESS, buf, ARRAY_SIZE(buf));
if (entry->u.IPAddress.cbData == 8)
{
if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
{
- LoadStringW(hInstance, IDS_ALT_NAME_MASK, mask,
- sizeof(mask) / sizeof(mask[0]));
+ LoadStringW(hInstance, IDS_ALT_NAME_MASK, mask, ARRAY_SIZE(mask));
bytesNeeded += strlenW(mask) * sizeof(WCHAR);
sprintfW(ipAddrBuf, ipAddrFmt,
entry->u.IPAddress.pbData[0],
@@ -1448,7 +1425,7 @@ static BOOL CRYPT_FormatCertIssuer(DWORD dwFormatStrType,
LPCWSTR sep;
BOOL ret;
- LoadStringW(hInstance, IDS_CERT_ISSUER, buf, sizeof(buf) / sizeof(buf[0]));
+ LoadStringW(hInstance, IDS_CERT_ISSUER, buf, ARRAY_SIZE(buf));
ret = CRYPT_FormatAltNameInfo(dwFormatStrType, 1, issuer, NULL,
&bytesNeeded);
bytesNeeded += strlenW(buf) * sizeof(WCHAR);
@@ -1652,8 +1629,7 @@ static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType,
{
WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
- LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
- sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+ LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable));
bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
if (!pbFormat)
*pcbFormat = bytesNeeded;
@@ -1680,18 +1656,12 @@ static BOOL WINAPI CRYPT_FormatAuthorityInfoAccess(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- LoadStringW(hInstance, IDS_AIA, aia,
- sizeof(aia) / sizeof(aia[0]));
- LoadStringW(hInstance, IDS_ACCESS_METHOD, accessMethod,
- sizeof(accessMethod) / sizeof(accessMethod[0]));
- LoadStringW(hInstance, IDS_ACCESS_METHOD_OCSP, ocsp,
- sizeof(ocsp) / sizeof(ocsp[0]));
- LoadStringW(hInstance, IDS_ACCESS_METHOD_CA_ISSUERS, caIssuers,
- sizeof(caIssuers) / sizeof(caIssuers[0]));
- LoadStringW(hInstance, IDS_ACCESS_METHOD_UNKNOWN, unknown,
- sizeof(unknown) / sizeof(unknown[0]));
- LoadStringW(hInstance, IDS_ACCESS_LOCATION, accessLocation,
- sizeof(accessLocation) / sizeof(accessLocation[0]));
+ LoadStringW(hInstance, IDS_AIA, aia, ARRAY_SIZE(aia));
+ LoadStringW(hInstance, IDS_ACCESS_METHOD, accessMethod, ARRAY_SIZE(accessMethod));
+ LoadStringW(hInstance, IDS_ACCESS_METHOD_OCSP, ocsp, ARRAY_SIZE(ocsp));
+ LoadStringW(hInstance, IDS_ACCESS_METHOD_CA_ISSUERS, caIssuers, ARRAY_SIZE(caIssuers));
+ LoadStringW(hInstance, IDS_ACCESS_METHOD_UNKNOWN, unknown, ARRAY_SIZE(unknown));
+ LoadStringW(hInstance, IDS_ACCESS_LOCATION, accessLocation, ARRAY_SIZE(accessLocation));
stringsLoaded = TRUE;
}
if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
@@ -1879,7 +1849,7 @@ static BOOL CRYPT_FormatReason(DWORD dwFormatStrType,
if (!stringsLoaded)
{
- for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(reason_map); i++)
LoadStringW(hInstance, reason_map[i].id, reason_map[i].reason,
MAX_STRING_RESOURCE_LEN);
stringsLoaded = TRUE;
@@ -1887,7 +1857,7 @@ static BOOL CRYPT_FormatReason(DWORD dwFormatStrType,
/* No need to check reasonFlags->cbData, we already know it's positive.
* Ignore any other bytes, as they're for undefined bits.
*/
- for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(reason_map); i++)
{
if (reasonFlags->pbData[0] & reason_map[i].reasonBit)
{
@@ -1909,14 +1879,13 @@ static BOOL CRYPT_FormatReason(DWORD dwFormatStrType,
else
{
*pcbStr = bytesNeeded;
- for (i = 0; i < sizeof(reason_map) / sizeof(reason_map[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(reason_map); i++)
{
if (reasonFlags->pbData[0] & reason_map[i].reasonBit)
{
strcpyW(str, reason_map[i].reason);
str += strlenW(reason_map[i].reason);
- if (i < sizeof(reason_map) / sizeof(reason_map[0]) - 1 &&
- numReasons)
+ if (i < ARRAY_SIZE(reason_map) - 1 && numReasons)
{
strcpyW(str, sep);
str += strlenW(sep);
@@ -1963,18 +1932,12 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- LoadStringW(hInstance, IDS_CRL_DIST_POINT, crlDistPoint,
- sizeof(crlDistPoint) / sizeof(crlDistPoint[0]));
- LoadStringW(hInstance, IDS_CRL_DIST_POINT_NAME, distPointName,
- sizeof(distPointName) / sizeof(distPointName[0]));
- LoadStringW(hInstance, IDS_CRL_DIST_POINT_FULL_NAME, fullName,
- sizeof(fullName) / sizeof(fullName[0]));
- LoadStringW(hInstance, IDS_CRL_DIST_POINT_RDN_NAME, rdnName,
- sizeof(rdnName) / sizeof(rdnName[0]));
- LoadStringW(hInstance, IDS_CRL_DIST_POINT_REASON, reason,
- sizeof(reason) / sizeof(reason[0]));
- LoadStringW(hInstance, IDS_CRL_DIST_POINT_ISSUER, issuer,
- sizeof(issuer) / sizeof(issuer[0]));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT, crlDistPoint, ARRAY_SIZE(crlDistPoint));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT_NAME, distPointName, ARRAY_SIZE(distPointName));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT_FULL_NAME, fullName, ARRAY_SIZE(fullName));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT_RDN_NAME, rdnName, ARRAY_SIZE(rdnName));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT_REASON, reason, ARRAY_SIZE(reason));
+ LoadStringW(hInstance, IDS_CRL_DIST_POINT_ISSUER, issuer, ARRAY_SIZE(issuer));
stringsLoaded = TRUE;
}
if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
@@ -2050,8 +2013,7 @@ static BOOL WINAPI CRYPT_FormatCRLDistPoints(DWORD dwCertEncodingType,
{
WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
- LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
- sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+ LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable));
bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
if (!pbFormat)
*pcbFormat = bytesNeeded;
@@ -2202,8 +2164,7 @@ static BOOL WINAPI CRYPT_FormatEnhancedKeyUsage(DWORD dwCertEncodingType,
sepLen = strlenW(commaSpace) * sizeof(WCHAR);
}
- LoadStringW(hInstance, IDS_USAGE_UNKNOWN, unknown,
- sizeof(unknown) / sizeof(unknown[0]));
+ LoadStringW(hInstance, IDS_USAGE_UNKNOWN, unknown, ARRAY_SIZE(unknown));
for (i = 0; i < usage->cUsageIdentifier; i++)
{
PCCRYPT_OID_INFO info = CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY,
@@ -2299,8 +2260,7 @@ static BOOL WINAPI CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType,
WCHAR infoNotAvailable[MAX_STRING_RESOURCE_LEN];
DWORD bytesNeeded = sizeof(WCHAR);
- LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable,
- sizeof(infoNotAvailable) / sizeof(infoNotAvailable[0]));
+ LoadStringW(hInstance, IDS_INFO_NOT_AVAILABLE, infoNotAvailable, ARRAY_SIZE(infoNotAvailable));
if (!bits->cbData || bits->cbData > 1)
{
bytesNeeded += strlenW(infoNotAvailable) * sizeof(WCHAR);
@@ -2329,15 +2289,13 @@ static BOOL WINAPI CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- for (i = 0; i < sizeof(netscapeCertTypeMap) /
- sizeof(netscapeCertTypeMap[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(netscapeCertTypeMap); i++)
LoadStringW(hInstance, netscapeCertTypeMap[i].id,
netscapeCertTypeMap[i].str, MAX_STRING_RESOURCE_LEN);
stringsLoaded = TRUE;
}
- CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap,
- sizeof(netscapeCertTypeMap) / sizeof(netscapeCertTypeMap[0]),
- NULL, &bitStringLen, &first);
+ CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap, ARRAY_SIZE(netscapeCertTypeMap),
+ NULL, &bitStringLen, &first);
bytesNeeded += bitStringLen;
bytesNeeded += 3 * sizeof(WCHAR); /* " (" + ")" */
CRYPT_FormatHexString(0, 0, 0, NULL, NULL, bits->pbData,
@@ -2357,9 +2315,8 @@ static BOOL WINAPI CRYPT_FormatNetscapeCertType(DWORD dwCertEncodingType,
bitStringLen = bytesNeeded;
first = TRUE;
- CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap,
- sizeof(netscapeCertTypeMap) / sizeof(netscapeCertTypeMap[0]),
- str, &bitStringLen, &first);
+ CRYPT_FormatBits(bits->pbData[0], netscapeCertTypeMap, ARRAY_SIZE(netscapeCertTypeMap),
+ str, &bitStringLen, &first);
str += bitStringLen / sizeof(WCHAR) - 1;
*str++ = ' ';
*str++ = '(';
@@ -2407,16 +2364,12 @@ static BOOL WINAPI CRYPT_FormatSpcFinancialCriteria(DWORD dwCertEncodingType,
if (!stringsLoaded)
{
- LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA, financialCriteria,
- sizeof(financialCriteria) / sizeof(financialCriteria[0]));
- LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_AVAILABLE, available,
- sizeof(available) / sizeof(available[0]));
- LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE,
- notAvailable, sizeof(notAvailable) / sizeof(notAvailable[0]));
- LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA,
- meetsCriteria, sizeof(meetsCriteria) / sizeof(meetsCriteria[0]));
- LoadStringW(hInstance, IDS_YES, yes, sizeof(yes) / sizeof(yes[0]));
- LoadStringW(hInstance, IDS_NO, no, sizeof(no) / sizeof(no[0]));
+ LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA, financialCriteria, ARRAY_SIZE(financialCriteria));
+ LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_AVAILABLE, available, ARRAY_SIZE(available));
+ LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_NOT_AVAILABLE, notAvailable, ARRAY_SIZE(notAvailable));
+ LoadStringW(hInstance, IDS_FINANCIAL_CRITERIA_MEETS_CRITERIA, meetsCriteria, ARRAY_SIZE(meetsCriteria));
+ LoadStringW(hInstance, IDS_YES, yes, ARRAY_SIZE(yes));
+ LoadStringW(hInstance, IDS_NO, no, ARRAY_SIZE(no));
stringsLoaded = TRUE;
}
if (dwFormatStrType & CRYPT_FORMAT_STR_MULTI_LINE)
diff --git a/dlls/crypt32/oid.c b/dlls/crypt32/oid.c
index 5a447d09ca..61b2cbc88e 100644
--- a/dlls/crypt32/oid.c
+++ b/dlls/crypt32/oid.c
@@ -69,7 +69,7 @@ static const WCHAR ADDRESSBOOK[] = {'A','D','D','R','E','S','S','B','O','O','K',
static const WCHAR TRUSTEDPUBLISHER[] = {'T','r','u','s','t','e','d','P','u','b','l','i','s','h','e','r',0};
static const WCHAR DISALLOWED[] = {'D','i','s','a','l','l','o','w','e','d',0};
static const LPCWSTR LocalizedKeys[] = {ROOT,MY,CA,ADDRESSBOOK,TRUSTEDPUBLISHER,DISALLOWED};
-static WCHAR LocalizedNames[sizeof(LocalizedKeys)/sizeof(LocalizedKeys[0])][256];
+static WCHAR LocalizedNames[ARRAY_SIZE(LocalizedKeys)][256];
static void free_function_sets(void)
{
@@ -1006,7 +1006,7 @@ static void oid_init_localizednames(void)
{
unsigned int i;
- for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
+ for(i = 0; i < ARRAY_SIZE(LocalizedKeys); i++)
{
LoadStringW(hInstance, IDS_LOCALIZEDNAME_ROOT+i, LocalizedNames[i], 256);
}
@@ -1019,7 +1019,7 @@ LPCWSTR WINAPI CryptFindLocalizedName(LPCWSTR pwszCryptName)
{
unsigned int i;
- for(i = 0; i < sizeof(LocalizedKeys)/sizeof(LPCWSTR); i++)
+ for(i = 0; i < ARRAY_SIZE(LocalizedKeys); i++)
{
if(!lstrcmpiW(LocalizedKeys[i], pwszCryptName))
{
@@ -1399,8 +1399,7 @@ static void init_oid_info(void)
DWORD i;
oid_init_localizednames();
- for (i = 0; i < sizeof(oidInfoConstructors) /
- sizeof(oidInfoConstructors[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(oidInfoConstructors); i++)
{
if (!IS_INTRESOURCE(oidInfoConstructors[i].pwszName))
{
diff --git a/dlls/crypt32/regstore.c b/dlls/crypt32/regstore.c
index 7678bab6aa..ce32a30f3b 100644
--- a/dlls/crypt32/regstore.c
+++ b/dlls/crypt32/regstore.c
@@ -71,7 +71,7 @@ static void CRYPT_RegReadSerializedFromReg(HKEY key, DWORD contextType,
WCHAR subKeyName[MAX_PATH];
do {
- DWORD size = sizeof(subKeyName) / sizeof(WCHAR);
+ DWORD size = ARRAY_SIZE(subKeyName);
rc = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL, NULL,
NULL);
@@ -163,7 +163,7 @@ static void CRYPT_RegReadFromReg(HKEY key, HCERTSTORE store)
CERT_STORE_CRL_CONTEXT_FLAG, CERT_STORE_CTL_CONTEXT_FLAG };
DWORD i;
- for (i = 0; i < sizeof(subKeys) / sizeof(subKeys[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(subKeys); i++)
{
HKEY hKey;
LONG rc;
@@ -255,7 +255,7 @@ static BOOL CRYPT_RegWriteToReg(WINE_REGSTOREINFO *store)
BOOL ret = TRUE;
DWORD i;
- for (i = 0; ret && i < sizeof(subKeys) / sizeof(subKeys[0]); i++)
+ for (i = 0; ret && i < ARRAY_SIZE(subKeys); i++)
{
HKEY key;
LONG rc = RegCreateKeyExW(store->key, subKeys[i], 0, NULL, 0,
@@ -561,8 +561,7 @@ WINECRYPT_CERTSTORE *CRYPT_RegOpenStore(HCRYPTPROV hCryptProv, DWORD dwFlags,
CRYPT_RegReadFromReg(regInfo->key, regInfo->memStore);
regInfo->dirty = FALSE;
provInfo.cbSize = sizeof(provInfo);
- provInfo.cStoreProvFunc = sizeof(regProvFuncs) /
- sizeof(regProvFuncs[0]);
+ provInfo.cStoreProvFunc = ARRAY_SIZE(regProvFuncs);
provInfo.rgpvStoreProvFunc = regProvFuncs;
provInfo.hStoreProv = regInfo;
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
diff --git a/dlls/crypt32/rootstore.c b/dlls/crypt32/rootstore.c
index 73d954f740..e7ed4e9bea 100644
--- a/dlls/crypt32/rootstore.c
+++ b/dlls/crypt32/rootstore.c
@@ -780,7 +780,7 @@ static void add_ms_root_certs(HCERTSTORE to)
TRACE("\n");
- for (i = 0; i < sizeof(msRootCerts) / sizeof(msRootCerts[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(msRootCerts); i++)
if (!CertAddEncodedCertificateToStore(to, X509_ASN_ENCODING,
msRootCerts[i].pb, msRootCerts[i].cb, CERT_STORE_ADD_NEW, NULL))
WARN("adding root cert %d failed: %08x\n", i, GetLastError());
@@ -830,9 +830,7 @@ static void read_trusted_roots_from_known_locations(HCERTSTORE store)
}
#endif
- for (i = 0; !ret &&
- i < sizeof(CRYPT_knownLocations) / sizeof(CRYPT_knownLocations[0]);
- i++)
+ for (i = 0; !ret && i < ARRAY_SIZE(CRYPT_knownLocations); i++)
ret = import_certs_from_path(CRYPT_knownLocations[i], from, TRUE);
check_and_store_certs(from, store);
}
diff --git a/dlls/crypt32/sip.c b/dlls/crypt32/sip.c
index b0c4692c1f..f51bceb460 100644
--- a/dlls/crypt32/sip.c
+++ b/dlls/crypt32/sip.c
@@ -28,6 +28,7 @@
#include "winnls.h"
#include "mssip.h"
#include "winuser.h"
+#include "crypt32_private.h"
#include "wine/debug.h"
#include "wine/list.h"
@@ -440,7 +441,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
WCHAR subKeyName[MAX_PATH];
do {
- size = sizeof(subKeyName) / sizeof(subKeyName[0]);
+ size = ARRAY_SIZE(subKeyName);
r = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL,
NULL, NULL);
if (r == ERROR_SUCCESS)
@@ -478,7 +479,7 @@ BOOL WINAPI CryptSIPRetrieveSubjectGuid
WCHAR subKeyName[MAX_PATH];
do {
- size = sizeof(subKeyName) / sizeof(subKeyName[0]);
+ size = ARRAY_SIZE(subKeyName);
r = RegEnumKeyExW(key, index++, subKeyName, &size, NULL, NULL,
NULL, NULL);
if (r == ERROR_SUCCESS)
diff --git a/dlls/crypt32/store.c b/dlls/crypt32/store.c
index bc4ebde5f6..2b8ea1d5d8 100644
--- a/dlls/crypt32/store.c
+++ b/dlls/crypt32/store.c
@@ -124,7 +124,7 @@ BOOL WINAPI I_CertUpdateStore(HCERTSTORE store1, HCERTSTORE store2, DWORD unk0,
/* Poor-man's resync: empty first store, then add everything from second
* store to it.
*/
- for (i = 0; i < sizeof(interfaces) / sizeof(interfaces[0]); i++)
+ for (i = 0; i < ARRAY_SIZE(interfaces); i++)
{
const void *context;
@@ -717,8 +717,7 @@ static WINECRYPT_CERTSTORE *CRYPT_MsgOpenStore(HCRYPTPROV hCryptProv,
CERT_STORE_PROV_INFO provInfo = { 0 };
provInfo.cbSize = sizeof(provInfo);
- provInfo.cStoreProvFunc = sizeof(msgProvFuncs) /
- sizeof(msgProvFuncs[0]);
+ provInfo.cStoreProvFunc = ARRAY_SIZE(msgProvFuncs);
provInfo.rgpvStoreProvFunc = msgProvFuncs;
provInfo.hStoreProv = CryptMsgDuplicate(msg);
store = CRYPT_ProvCreateStore(dwFlags, memStore, &provInfo);
@@ -1338,7 +1337,7 @@ BOOL WINAPI CertEnumSystemStore(DWORD dwFlags, void *pvSystemStoreLocationPara,
ret = TRUE;
do {
WCHAR name[MAX_PATH];
- DWORD size = sizeof(name) / sizeof(name[0]);
+ DWORD size = ARRAY_SIZE(name);
rc = RegEnumKeyExW(key, index++, name, &size, NULL, NULL, NULL,
NULL);
diff --git a/dlls/crypt32/str.c b/dlls/crypt32/str.c
index 1daf29f8a0..4843c4f5f1 100644
--- a/dlls/crypt32/str.c
+++ b/dlls/crypt32/str.c
@@ -26,6 +26,7 @@
#include "wincrypt.h"
#include "wine/debug.h"
#include "wine/unicode.h"
+#include "crypt32_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(crypt);
@@ -775,7 +776,7 @@ struct KeynameKeeper
static void CRYPT_InitializeKeynameKeeper(struct KeynameKeeper *keeper)
{
keeper->keyName = keeper->buf;
- keeper->keyLen = sizeof(keeper->buf) / sizeof(keeper->buf[0]);
+ keeper->keyLen = ARRAY_SIZE(keeper->buf);
}
static void CRYPT_FreeKeynameKeeper(struct KeynameKeeper *keeper)
@@ -1326,8 +1327,7 @@ DWORD WINAPI CertGetNameStringW(PCCERT_CONTEXT pCertContext, DWORD dwType,
{
PCERT_RDN_ATTR nameAttr = NULL;
- for (i = 0; !nameAttr && i < sizeof(simpleAttributeOIDs) /
- sizeof(simpleAttributeOIDs[0]); i++)
+ for (i = 0; !nameAttr && i < ARRAY_SIZE(simpleAttributeOIDs); i++)
nameAttr = CertFindRDNAttr(simpleAttributeOIDs[i], nameInfo);
if (nameAttr)
ret = CertRDNValueToStrW(nameAttr->dwValueType,
--
2.17.1
June 20, 2018
Re: [PATCH] comctl32/imagelist: fix ImageList_Read/Write.
by Zhiyi Zhang
Hi Denis,
Thanks for taking the time. I noticed a few issues with your patch.
1. Using C++ style comments.
2. Mixing style only changes, please separate them if you really
need to make style changes. Usually, I prefer not to touch the old
code simply for style changes.
3. Add a conformance test for the problem you intent to fix.
4. Add a version to patch mail subject.
You might want to read
https://wiki.winehq.org/Submitting_Patches
Regards,
Zhiyi
June 20, 2018
[PATCH v3 2/2] gdiplus: Avoid calling GdipFillPath() with an empty path.
by Zhiyi Zhang
There is no point filling an empty path. And an empty
path will cause SelectClipPath() used in brush_fill_path()
to return error.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdiplus/graphics.c | 3 +++
dlls/gdiplus/tests/graphics.c | 47 +++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index a793665683..2d23085e8a 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -4264,6 +4264,9 @@ GpStatus WINGDIPAPI GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath *p
if(graphics->busy)
return ObjectBusy;
+ if (!path->pathdata.Count)
+ return Ok;
+
if (graphics->image && graphics->image->type == ImageTypeMetafile)
return METAFILE_FillPath((GpMetafile*)graphics->image, brush, path);
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index ae75c0efc1..5eb0a8a4d0 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -1539,6 +1539,52 @@ static void test_GdipFillClosedCurveI(void)
ReleaseDC(hwnd, hdc);
}
+static void test_GdipFillPath(void)
+{
+ GpStatus status;
+ GpGraphics *graphics;
+ GpSolidFill *brush;
+ GpPath *path;
+ HDC hdc = GetDC(hwnd);
+
+ ok(hdc != NULL, "Expected HDC to be initialized\n");
+ status = GdipCreateFromHDC(hdc, &graphics);
+ expect(Ok, status);
+ ok(graphics != NULL, "Expected graphics to be initialized\n");
+ status = GdipCreateSolidFill((ARGB)0xffffffff, &brush);
+ expect(Ok, status);
+ ok(brush != NULL, "Expected brush to be initialized\n");
+ status = GdipCreatePath(FillModeAlternate, &path);
+ expect(Ok, status);
+ ok(path != NULL, "Expected path to be initialized\n");
+
+ /* Empty path */
+ GdipResetPath(path);
+ status = GdipFillPath(graphics, (GpBrush *)brush, path);
+ expect(Ok, status);
+
+ /* Not closed path */
+ GdipResetPath(path);
+ status = GdipAddPathLineI(path, 0, 0, 2, 2);
+ expect(Ok, status);
+ status = GdipAddPathLineI(path, 2, 2, 4, 0);
+ expect(Ok, status);
+ status = GdipFillPath(graphics, (GpBrush *)brush, path);
+ expect(Ok, status);
+
+ /* Closed path */
+ GdipResetPath(path);
+ status = GdipAddPathRectangle(path, 0, 0, 4, 4);
+ expect(Ok, status);
+ status = GdipFillPath(graphics, (GpBrush *)brush, path);
+ expect(Ok, status);
+
+ GdipDeletePath(path);
+ GdipDeleteBrush((GpBrush *)brush);
+ GdipDeleteGraphics(graphics);
+ ReleaseDC(hwnd, hdc);
+}
+
static void test_Get_Release_DC(void)
{
GpStatus status;
@@ -6795,6 +6841,7 @@ START_TEST(graphics)
test_GdipDrawImagePointsRect();
test_GdipFillClosedCurve();
test_GdipFillClosedCurveI();
+ test_GdipFillPath();
test_GdipDrawString();
test_GdipGetNearestColor();
test_GdipGetVisibleClipBounds();
--
2.17.1
June 20, 2018
[PATCH v3 1/2] gdiplus: Report error for brush_fill_path().
by Zhiyi Zhang
Operation should be skipped if SelectClipPath() returns any
error. And we should report unexpected error to the caller.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/gdiplus/graphics.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c
index 894e879233..a793665683 100644
--- a/dlls/gdiplus/graphics.c
+++ b/dlls/gdiplus/graphics.c
@@ -1050,8 +1050,9 @@ static BOOL brush_can_fill_path(GpBrush *brush, BOOL is_fill)
}
}
-static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
+static GpStatus brush_fill_path(GpGraphics *graphics, GpBrush *brush)
{
+ GpStatus status = Ok;
switch (brush->bt)
{
case BrushTypeSolidColor:
@@ -1064,13 +1065,19 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
RECT rc;
/* partially transparent fill */
- SelectClipPath(graphics->hdc, RGN_AND);
+ if (!SelectClipPath(graphics->hdc, RGN_AND))
+ {
+ status = GenericError;
+ DeleteObject(bmp);
+ break;
+ }
if (GetClipBox(graphics->hdc, &rc) != NULLREGION)
{
HDC hdc = CreateCompatibleDC(NULL);
if (!hdc)
{
+ status = OutOfMemory;
DeleteObject(bmp);
break;
}
@@ -1091,7 +1098,11 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
HBRUSH gdibrush, old_brush;
gdibrush = create_gdi_brush(brush);
- if (!gdibrush) return;
+ if (!gdibrush)
+ {
+ status = OutOfMemory;
+ break;
+ }
old_brush = SelectObject(graphics->hdc, gdibrush);
FillPath(graphics->hdc);
@@ -1100,6 +1111,8 @@ static void brush_fill_path(GpGraphics *graphics, GpBrush* brush)
break;
}
}
+
+ return status;
}
static BOOL brush_can_fill_pixels(GpBrush *brush)
@@ -4205,7 +4218,7 @@ static GpStatus GDI32_GdipFillPath(GpGraphics *graphics, GpBrush *brush, GpPath
if(retval == Ok)
{
EndPath(graphics->hdc);
- brush_fill_path(graphics, brush);
+ retval = brush_fill_path(graphics, brush);
}
gdi_transform_release(graphics);
@@ -4511,13 +4524,13 @@ static GpStatus GDI32_GdipFillRegion(GpGraphics* graphics, GpBrush* brush,
Rectangle(graphics->hdc, rc.left, rc.top, rc.right, rc.bottom);
EndPath(graphics->hdc);
- brush_fill_path(graphics, brush);
+ status = brush_fill_path(graphics, brush);
}
RestoreDC(graphics->hdc, save_state);
- return Ok;
+ return status;
}
static GpStatus SOFTWARE_GdipFillRegion(GpGraphics *graphics, GpBrush *brush,
--
2.17.1
June 20, 2018
[PATCH] comctl32/imagelist: fix ImageList_Read/Write.
by Denis Malikov
From: Denis Malikov <mdn40000(a)mail.ru>
Date: Sat, 16 Jun 2018 16:35:45 +0700
Subject: [PATCH] comctl32/imagelist: fix ImageList_Read/Write.
Fix pointer calculation for mixing image and mask bits for versions x600 and x620.
Tested with *.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 | 59 +++++++++++++++++++++++++++--------------------
1 file changed, 34 insertions(+), 25 deletions(-)
diff --git a/dlls/comctl32/imagelist.c b/dlls/comctl32/imagelist.c
index a08d60752e..052d59f9e4 100644
--- a/dlls/comctl32/imagelist.c
+++ b/dlls/comctl32/imagelist.c
@@ -59,7 +59,7 @@ struct _IMAGELIST
INT cGrow; /* 0C: cGrow */
INT cx; /* 10: cx */
INT cy; /* 14: cy */
- DWORD x4;
+ DWORD x4; /* hack for IL from stream. Keep version here */
UINT flags; /* 1C: flags */
COLORREF clrFg; /* 20: foreground color */
COLORREF clrBk; /* 24: background color */
@@ -83,6 +83,7 @@ struct _IMAGELIST
};
#define IMAGELIST_MAGIC 0x53414D58
+#define IMAGELIST_VERSION 0x101
/* Header used by ImageList_Read() and ImageList_Write() */
#include "pshpack2.h"
@@ -806,6 +807,7 @@ ImageList_Create (INT cx, INT cy, UINT flags,
himl->clrFg = CLR_DEFAULT;
himl->clrBk = CLR_NONE;
himl->color_table_set = FALSE;
+ himl->x4 = 0;
/* initialize overlay mask indices */
for (nCount = 0; nCount < MAX_OVERLAYIMAGE; nCount++)
@@ -2257,38 +2259,43 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
BITMAPINFO *image_info = (BITMAPINFO *)image_buf;
BITMAPINFO *mask_info = (BITMAPINFO *)mask_buf;
void *image_bits, *mask_bits = NULL;
- ILHEAD ilHead;
- HIMAGELIST himl;
+ ILHEAD ilHead;
+ HIMAGELIST himl;
unsigned int i;
TRACE("%p\n", pstm);
if (FAILED(IStream_Read (pstm, &ilHead, sizeof(ILHEAD), NULL)))
- return NULL;
+ return NULL;
if (ilHead.usMagic != (('L' << 8) | 'I'))
- return NULL;
- if (ilHead.usVersion != 0x101) /* probably version? */
- return NULL;
+ return NULL;
+ if (ilHead.usVersion != IMAGELIST_VERSION &&
+ 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",
ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
himl = ImageList_Create(ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
if (!himl)
- return NULL;
+ return NULL;
+
+ // keep version from stream
+ himl->x4 = ilHead.usVersion;
if (!(image_bits = read_bitmap(pstm, image_info)))
{
- WARN("failed to read bitmap from stream\n");
- return NULL;
+ WARN("failed to read bitmap from stream\n");
+ return NULL;
}
if (ilHead.flags & ILC_MASK)
{
if (!(mask_bits = read_bitmap(pstm, mask_info)))
{
WARN("failed to read mask bitmap from stream\n");
- return NULL;
- }
+ return NULL;
+ }
}
else mask_info = NULL;
@@ -2296,23 +2303,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 != IMAGELIST_VERSION ? himl->cx : image_info->bmiHeader.biWidth);
+ int image_step = ilHead.usVersion != IMAGELIST_VERSION ? 1 : TILE_COUNT;
+ int mask_step = ilHead.usVersion != IMAGELIST_VERSION ? 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
@@ -2333,7 +2342,7 @@ HIMAGELIST WINAPI ImageList_Read(IStream *pstm)
ImageList_SetBkColor(himl,ilHead.bkcolor);
for (i=0;i<4;i++)
- ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
+ ImageList_SetOverlayImage(himl,ilHead.ovls[i],i+1);
return himl;
}
@@ -3078,10 +3087,10 @@ BOOL WINAPI ImageList_Write(HIMAGELIST himl, IStream *pstm)
TRACE("%p %p\n", himl, pstm);
if (!is_valid(himl))
- return FALSE;
+ return FALSE;
ilHead.usMagic = (('L' << 8) | 'I');
- ilHead.usVersion = 0x101;
+ ilHead.usVersion = himl->x4 > 0 ? himl->x4 : IMAGELIST_VERSION;
ilHead.cCurImage = himl->cCurImage;
ilHead.cMaxImage = himl->cMaxImage;
ilHead.cGrow = himl->cGrow;
@@ -3090,23 +3099,23 @@ BOOL WINAPI ImageList_Write(HIMAGELIST himl, IStream *pstm)
ilHead.bkcolor = himl->clrBk;
ilHead.flags = himl->flags;
for(i = 0; i < 4; i++) {
- ilHead.ovls[i] = himl->nOvlIdx[i];
+ ilHead.ovls[i] = himl->nOvlIdx[i];
}
TRACE("cx %u, cy %u, flags 0x04%x, cCurImage %u, cMaxImage %u\n",
ilHead.cx, ilHead.cy, ilHead.flags, ilHead.cCurImage, ilHead.cMaxImage);
if(FAILED(IStream_Write(pstm, &ilHead, sizeof(ILHEAD), NULL)))
- return FALSE;
+ return FALSE;
/* write the bitmap */
if(!_write_bitmap(himl->hbmImage, pstm))
- return FALSE;
+ return FALSE;
/* write the mask if we have one */
if(himl->flags & ILC_MASK) {
- if(!_write_bitmap(himl->hbmMask, pstm))
- return FALSE;
+ if(!_write_bitmap(himl->hbmMask, pstm))
+ return FALSE;
}
return TRUE;
--
2.16.2.windows.1
June 20, 2018
[PATCH] wsdapi: Add a trailing '\n' to a WARN() message.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/wsdapi/network.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wsdapi/network.c b/dlls/wsdapi/network.c
index e124a5d90cf..c8f260c7653 100644
--- a/dlls/wsdapi/network.c
+++ b/dlls/wsdapi/network.c
@@ -540,7 +540,7 @@ static BOOL start_listening_on_all_addresses(IWSDiscoveryPublisherImpl *impl, UL
{
if (impl->num_thread_handles >= MAX_WSD_THREADS)
{
- WARN("Exceeded maximum number of supported listener threads; too many network interfaces.");
+ WARN("Exceeded maximum number of supported listener threads; too many network interfaces.\n");
goto cleanup;
}
--
2.17.1
June 20, 2018
[PATCH] winetest: Don't show dll=skipped messages for skipped tests.
by Francois Gouget
This spams the report when using WineTest to run a few tests.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
programs/winetest/main.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/programs/winetest/main.c b/programs/winetest/main.c
index bfac17bdf6e..b3c3c1c8502 100644
--- a/programs/winetest/main.c
+++ b/programs/winetest/main.c
@@ -902,7 +902,6 @@ extract_test_proc (HMODULE hModule, LPCSTR lpszType, LPSTR lpszName, LONG_PTR lP
if (test_filtered_out( lpszName, NULL ))
{
nr_of_skips++;
- xprintf (" %s=skipped\n", dllname);
return TRUE;
}
extract_test (&wine_tests[nr_of_files], tempdir, lpszName);
--
2.17.1
June 20, 2018
[PATCH 2/2] testbot/web: Highlight test failures and build errors on the job page.
by Francois Gouget
Show build errors in the log summary mode (like we already do for the
test failures).
Furthermore, when showing the full log, highlight the test failures and
build errors so they are easier to spot. This uses the same color
scheme as in the test.winehq.org website. Also make the boundaries
between the test units more visible by highlighting their start line.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/JobDetails.pl | 61 +++++++++++++++++++++++++++++++++----
testbot/web/WineTestBot.css | 5 +++
2 files changed, 60 insertions(+), 6 deletions(-)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index f829407eb..3add52b4c 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -228,6 +228,58 @@ sub GeneratePage($)
$self->SUPER::GeneratePage();
}
+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
+ # Build errors
+ $Line =~ /: error: / or
+ $Line =~ /^error: patch failed:/ 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 $Html = $Line;
+ $Html =~ s~^(.*\S)\s*\r?$~<span class='log-info'>$1</span>~;
+ return ($Html, $Line);
+ }
+
+ return (undef, $Line);
+}
+
my %MILogLabels = (
"log" => "task log",
"log.old" => "old logs",
@@ -371,11 +423,8 @@ sub GenerateBody($)
{
$CurrentDll = $1;
}
- if ($MoreInfo->{Full} ||
- $Line =~ m/: Test (?:failed|succeeded inside todo block): / ||
- $Line =~ m/Fatal: test '[^']+' does not exist/ ||
- $Line =~ m/ done \(258\)/ ||
- $Line =~ m/: unhandled exception [0-9a-fA-F]{8} at /)
+ my ($Highlight, $Plain) = $self->GetHtmlLine($MoreInfo->{Full}, $Line);
+ if ($MoreInfo->{Full} || defined $Highlight)
{
if ($PrintedDll ne $CurrentDll && !$MoreInfo->{Full})
{
@@ -402,7 +451,7 @@ sub GenerateBody($)
}
else
{
- print $self->escapeHTML($Line), "\n";
+ print(($Highlight || $Plain), "\n");
}
}
}
diff --git a/testbot/web/WineTestBot.css b/testbot/web/WineTestBot.css
index ebc622e34..28ac1b1c2 100644
--- a/testbot/web/WineTestBot.css
+++ b/testbot/web/WineTestBot.css
@@ -353,6 +353,11 @@ pre
.boterror { color: #e55600; }
.canceled { color: black; }
+.log-info { background-color: #d9ffcc; }
+.log-skip { color: blue; }
+.log-todo { color: #d08000; }
+.log-error { color: red; }
+
a.title { color:inherit; text-decoration: none; }
th.Record { text-align: center; }
--
2.17.1
June 20, 2018
[PATCH 1/2] testbot/web: Allow showing multiple job screenshots and logs.
by Francois Gouget
It's now possible to have the job details page show multiple
screenshots and multiple logs.
Once a screenshot / log is shown, the link can be clicked again to hide
it.
The code can also more easily be extended to handle more log files.
The code inserting the links is simpler too.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 2 +-
testbot/web/JobDetails.pl | 156 +++++++++++++++++++++++--------------
2 files changed, 97 insertions(+), 61 deletions(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 3d8113fd9..c4ca578e2 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -448,7 +448,7 @@ elsif ($Step->Type eq "suite")
if (defined($WebHostName))
{
my $StepTask = 100 * $StepNo + $TaskNo;
- $Script .= "-u \"http://$WebHostName/JobDetails.pl?Key=$JobId&scrshot_$StepTask=1#k$StepTask\"";
+ $Script .= "-u \"http://$WebHostName/JobDetails.pl?Key=$JobId&s$StepTask=1#k$StepTask\"";
}
my $Info = $VM->Description ? $VM->Description : "";
if ($VM->Details)
diff --git a/testbot/web/JobDetails.pl b/testbot/web/JobDetails.pl
index 70d8b5983..f829407eb 100644
--- a/testbot/web/JobDetails.pl
+++ b/testbot/web/JobDetails.pl
@@ -228,12 +228,95 @@ sub GeneratePage($)
$self->SUPER::GeneratePage();
}
+my %MILogLabels = (
+ "log" => "task log",
+ "log.old" => "old logs",
+);
+
+sub InitMoreInfo($)
+{
+ my ($self) = @_;
+
+ my $More = $self->{More} = {};
+ my $Keys = $self->SortKeys(undef, $self->{Collection}->GetKeys());
+ foreach my $Key (@$Keys)
+ {
+ my $StepTask = $self->{Collection}->GetItem($Key);
+ $More->{$Key}->{Screenshot} = $self->GetParam("s$Key");
+
+ my $Value = $self->GetParam("f$Key");
+ my $TaskDir = $StepTask->GetTaskDir();
+ foreach my $Log ("log", "log.old")
+ {
+ if (!-f "$TaskDir/$Log" or -z "$TaskDir/$Log")
+ {
+ my $Err = $Log;
+ next if ($Err !~ s/^log/err/ or !-f "$TaskDir/$Err" or -z "$TaskDir/$Err");
+ }
+ push @{$More->{$Key}->{Logs}}, $Log;
+
+ $More->{$Key}->{Full} = $Log if (uri_escape($Log) eq $Value);
+ }
+ $More->{$Key}->{Full} ||= "";
+ }
+}
+
+sub GenerateMoreInfoLink($$$;$)
+{
+ my ($self, $LinkKey, $Label, $Set, $Value) = @_;
+
+ my $Url = $ENV{"SCRIPT_NAME"} ."?Key=". uri_escape($self->{JobId});
+
+ my $Action = "Show";
+ foreach my $Key (sort keys %{$self->{More}})
+ {
+ my $MoreInfo = $self->{More}->{$Key};
+ if ($Key eq $LinkKey and $Set eq "Screenshot")
+ {
+ if (!$MoreInfo->{Screenshot})
+ {
+ $Url .= "&s$Key=1";
+ }
+ else
+ {
+ $Action = "Hide";
+ }
+ }
+ else
+ {
+ $Url .= "&s$Key=1" if ($MoreInfo->{Screenshot});
+ }
+
+ if ($Key eq $LinkKey and $Set eq "Full")
+ {
+ if ($MoreInfo->{Full} ne $Value)
+ {
+ $Url .= "&f$Key=". uri_escape($Value);
+ }
+ else
+ {
+ $Action = "Hide";
+ }
+ }
+ else
+ {
+ $Url .= "&f$Key=". uri_escape($MoreInfo->{Full}) if ($MoreInfo->{Full});
+ }
+ }
+ $Url .= "#k" . uri_escape($LinkKey);
+
+ print "<div class='TaskMoreInfoLink'><a href='",
+ $self->CGI->escapeHTML($Url), "'>$Action $Label</a></div>\n";
+}
+
sub GenerateBody($)
{
my ($self) = @_;
$self->SUPER::GenerateBody();
+ $self->InitMoreInfo();
+
print "<div class='Content'>\n";
my $Keys = $self->SortKeys(undef, $self->{Collection}->GetKeys());
foreach my $Key (@$Keys)
@@ -249,18 +332,11 @@ sub GenerateBody($)
$self->CGI->escapeHTML($VM->Details || "No details!"),
"</details>\n";
- my $FullLogParamName = "log_$Key";
- my $FullLog = $self->GetParam($FullLogParamName);
- $FullLog = "" if ($FullLog !~ /^[12]$/);
-
- my $ScreenshotParamName = "scrshot_$Key";
- my $Screenshot = $self->GetParam($ScreenshotParamName);
- $Screenshot = "" if ($Screenshot ne "1");
-
+ my $MoreInfo = $self->{More}->{$Key};
print "<div class='TaskMoreInfoLinks'>\n";
if (-r "$TaskDir/screenshot.png")
{
- if ($Screenshot)
+ if ($MoreInfo->{Screenshot})
{
my $URI = "/Screenshot.pl?JobKey=" . uri_escape($self->{JobId}) .
"&StepKey=" . uri_escape($StepTask->StepNo) .
@@ -268,59 +344,19 @@ sub GenerateBody($)
print "<div class='Screenshot'><img src='" .
$self->CGI->escapeHTML($URI) . "' alt='Screenshot' /></div>\n";
}
- else
- {
- my $URI = $ENV{"SCRIPT_NAME"} . "?Key=" . uri_escape($self->{JobId}) .
- "&$ScreenshotParamName=1";
- $URI .= "&$FullLogParamName=$FullLog";
- $URI .= "#k" . uri_escape($Key);
- print "<div class='TaskMoreInfoLink'><a href='" .
- $self->CGI->escapeHTML($URI) .
- "'>Show final screenshot</a></div>";
- print "\n";
- }
+ $self->GenerateMoreInfoLink($Key, "final screenshot", "Screenshot");
}
- my $LogName = "$TaskDir/log";
- my $ErrName = "$TaskDir/err";
- if (-r $LogName and $FullLog != "1")
- {
- my $URI = $ENV{"SCRIPT_NAME"} . "?Key=" . uri_escape($self->{JobId}) .
- "&$FullLogParamName=1";
- $URI .= "&$ScreenshotParamName=$Screenshot";
- $URI .= "#k" . uri_escape($Key);
- print "<div class='TaskMoreInfoLink'><a href='" .
- $self->CGI->escapeHTML($URI) .
- "'>Show full log</a></div>\n";
- }
- if ((-r $LogName or -r $ErrName) and $FullLog == "2")
+ foreach my $Log (@{$MoreInfo->{Logs}})
{
- my $URI = $ENV{"SCRIPT_NAME"} . "?Key=" . uri_escape($self->{JobId});
- $URI .= "&$ScreenshotParamName=$Screenshot";
- $URI .= "#k" . uri_escape($Key);
- print "<div class='TaskMoreInfoLink'><a href='" .
- $self->CGI->escapeHTML($URI) .
- "'>Show latest log</a></div>\n";
- }
- if ((-r "$LogName.old" or -r "$ErrName.old") and $FullLog != "2")
- {
- my $URI = $ENV{"SCRIPT_NAME"} . "?Key=" . uri_escape($self->{JobId}) .
- "&$FullLogParamName=2";
- $URI .= "&$ScreenshotParamName=$Screenshot";
- $URI .= "#k" . uri_escape($Key);
- print "<div class='TaskMoreInfoLink'><a href='" .
- $self->CGI->escapeHTML($URI) .
- "'>Show old logs</a></div>\n";
+ $self->GenerateMoreInfoLink($Key, $MILogLabels{$Log}, "Full", $Log);
}
print "</div>\n";
- if ($FullLog eq "2")
- {
- $LogName .= ".old";
- $ErrName .= ".old";
- }
+ my $LogName = $MoreInfo->{Full} || $MoreInfo->{Logs}->[0] || "log";
+ my $ErrName = $LogName eq "log.old" ? "err.old" : "err";
- if (open LOGFILE, "<$LogName")
+ if (open LOGFILE, "<", "$TaskDir/$LogName")
{
my $HasLogEntries = !1;
my $First = 1;
@@ -335,13 +371,13 @@ sub GenerateBody($)
{
$CurrentDll = $1;
}
- if ($FullLog ||
+ if ($MoreInfo->{Full} ||
$Line =~ m/: Test (?:failed|succeeded inside todo block): / ||
$Line =~ m/Fatal: test '[^']+' does not exist/ ||
$Line =~ m/ done \(258\)/ ||
$Line =~ m/: unhandled exception [0-9a-fA-F]{8} at /)
{
- if ($PrintedDll ne $CurrentDll && ! $FullLog)
+ if ($PrintedDll ne $CurrentDll && !$MoreInfo->{Full})
{
if ($First)
{
@@ -359,7 +395,7 @@ sub GenerateBody($)
print "<pre><code>";
$First = !1;
}
- if (! $FullLog && $Line =~ m/^[^:]+:([^:]*)(?::[0-9a-f]+)? done \(258\)/)
+ if (!$MoreInfo->{Full} && $Line =~ m/^[^:]+:([^:]*)(?::[0-9a-f]+)? done \(258\)/)
{
my $Unit = $1 ne "" ? "$1: " : "";
print "${Unit}Timeout\n";
@@ -372,7 +408,7 @@ sub GenerateBody($)
}
close LOGFILE;
- if (open ERRFILE, "<$ErrName")
+ if (open ERRFILE, "<", "$TaskDir/$ErrName")
{
$CurrentDll = "*err*";
while (defined($Line = <ERRFILE>))
@@ -409,7 +445,7 @@ sub GenerateBody($)
" failures found" : "Empty log";
}
}
- elsif (open ERRFILE, "<$ErrName")
+ elsif (open ERRFILE, "<", "$TaskDir/$ErrName")
{
my $HasErrEntries = !1;
my $Line;
--
2.17.1
June 20, 2018
[PATCH 4/4] testbot/build: Let the TestBot deal with logging.
by Francois Gouget
The Engine-side scripts (WineRun*.pl) already redirect stdout and
stderr to the appropriate log. So it does not make sense to delete that
log and then add new redirects for every command started from the
client scripts.
Remove FatalError() since it's not used in Reconfig.pl.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/build/Build.pl | 42 ++++++++------------------
testbot/bin/build/Reconfig.pl | 55 +++++++++++------------------------
2 files changed, 29 insertions(+), 68 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index e97995559..c23bb8780 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -49,27 +49,19 @@ use WineTestBot::PatchUtils;
use WineTestBot::Utils;
-my $LogFileName = "$LogDir/Build.log";
-
sub InfoMsg(@)
{
- my $OldUMask = umask(002);
- if (open(my $Log, ">>", $LogFileName))
- {
- print $Log @_;
- close($Log);
- }
- umask($OldUMask);
+ print @_;
}
sub LogMsg(@)
{
- InfoMsg "Build: ", @_;
+ print "Build: ", @_;
}
sub FatalError(@)
{
- LogMsg @_;
+ print STDERR @_;
exit 1;
}
@@ -90,10 +82,9 @@ sub ApplyPatch($)
my ($PatchFile) = @_;
InfoMsg "Applying patch\n";
- system("( cd $DataDir/wine && set -x && " .
- " git apply --verbose ". ShQuote($PatchFile) ." && ".
- " git add -A " .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/wine && set -x && ".
+ "git apply --verbose ". ShQuote($PatchFile) ." && ".
+ "git add -A");
if ($? != 0)
{
LogMsg "Patch failed to apply\n";
@@ -104,9 +95,7 @@ sub ApplyPatch($)
if ($Impacts->{Makefiles})
{
InfoMsg "\nRunning make_makefiles\n";
- system("( cd $DataDir/wine && set -x && " .
- " ./tools/make_makefiles " .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/wine && set -x && ./tools/make_makefiles");
if ($? != 0)
{
LogMsg "make_makefiles failed\n";
@@ -117,9 +106,7 @@ sub ApplyPatch($)
if ($Impacts->{Autoconf} && !$Impacts->{HasConfigure})
{
InfoMsg "\nRunning autoconf\n";
- system("( cd $DataDir/wine && set -x && " .
- " autoconf " .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/wine && set -x && autoconf");
if ($? != 0)
{
LogMsg "Autoconf failed\n";
@@ -135,9 +122,8 @@ sub BuildNative()
mkdir "$DataDir/build-native" if (! -d "$DataDir/build-native");
InfoMsg "\nRebuilding native tools\n";
- system("( cd $DataDir/build-native && set -x && " .
- " time make -j$ncpus __tooldeps__ " .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/build-native && set -x && ".
+ "time make -j$ncpus __tooldeps__");
if ($? != 0)
{
LogMsg "Rebuild of native tools failed\n";
@@ -161,9 +147,8 @@ sub BuildTestExecutables($$)
}
InfoMsg "\nBuilding the $Bits-bit test executable(s)\n";
- system("( cd $DataDir/build-mingw$Bits && set -x && " .
- " time make -j$ncpus ". join(" ", sort @BuildDirs) .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/build-mingw$Bits && set -x && ".
+ "time make -j$ncpus ". join(" ", sort @BuildDirs));
if ($? != 0)
{
LogMsg "Rebuild of $Bits-bit crossbuild failed\n";
@@ -186,9 +171,6 @@ sub BuildTestExecutables($$)
$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
-# Start with a clean logfile
-unlink($LogFileName);
-
my ($PatchFile, $BitIndicators);
if (@ARGV == 2)
{
diff --git a/testbot/bin/build/Reconfig.pl b/testbot/bin/build/Reconfig.pl
index c950d4974..2da2f54a4 100755
--- a/testbot/bin/build/Reconfig.pl
+++ b/testbot/bin/build/Reconfig.pl
@@ -43,28 +43,15 @@ sub BEGIN
use WineTestBot::Config;
use WineTestBot::PatchUtils;
-my $LogFileName = "$LogDir/Reconfig.log";
sub InfoMsg(@)
{
- my $OldUMask = umask(002);
- if (open(my $Log, ">>", $LogFileName))
- {
- print $Log @_;
- close($Log);
- }
- umask($OldUMask);
+ print @_;
}
sub LogMsg(@)
{
- InfoMsg "Reconfig: ", @_;
-}
-
-sub FatalError(@)
-{
- LogMsg @_;
- exit 1;
+ print "Reconfig: ", @_;
}
my $ncpus;
@@ -86,9 +73,8 @@ sub BuildTestAgentd()
if (! -x "$BinDir/build/testagentd")
{
InfoMsg "\nBuilding the native testagentd\n";
- system("( cd $::RootDir/src/testagentd && set -x && " .
- " time make -j$ncpus build " .
- ") >>$LogFileName 2>&1");
+ system("cd $::RootDir/src/testagentd && set -x && ".
+ "time make -j$ncpus build");
if ($? != 0)
{
LogMsg "Build testagentd failed\n";
@@ -97,9 +83,8 @@ sub BuildTestAgentd()
}
InfoMsg "\nRebuilding the Windows TestAgentd\n";
- system("( cd $::RootDir/src/testagentd && set -x && " .
- " time make -j$ncpus iso " .
- ") >>$LogFileName 2>&1");
+ system("cd $::RootDir/src/testagentd && set -x && ".
+ "time make -j$ncpus iso");
if ($? != 0)
{
LogMsg "Build winetestbot.iso failed\n";
@@ -112,9 +97,8 @@ sub BuildTestAgentd()
sub BuildTestLauncher()
{
InfoMsg "\nRebuilding TestLauncher\n";
- system("( cd $::RootDir/src/TestLauncher && set -x && " .
- " time make -j$ncpus" .
- ") >>$LogFileName 2>&1");
+ system("cd $::RootDir/src/TestLauncher && set -x && ".
+ "time make -j$ncpus");
if ($? != 0)
{
LogMsg "Build TestLauncher failed\n";
@@ -127,7 +111,7 @@ sub BuildTestLauncher()
sub GitPull()
{
InfoMsg "\nUpdating the Wine source\n";
- system("cd $DataDir/wine && git pull >>$LogFileName 2>&1");
+ system("cd $DataDir/wine && git pull");
if ($? != 0)
{
LogMsg "Git pull failed\n";
@@ -150,11 +134,10 @@ sub BuildNative()
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding native tools\n";
- system("( cd $DataDir/build-native && set -x && " .
- " rm -rf * && " .
- " time ../wine/configure --enable-win64 --without-x --without-freetype --disable-winetest && " .
- " time make -j$ncpus __tooldeps__ " .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/build-native && set -x && ".
+ "rm -rf * && ".
+ "time ../wine/configure --enable-win64 --without-x --without-freetype --disable-winetest && ".
+ "time make -j$ncpus __tooldeps__");
if ($? != 0)
{
@@ -174,11 +157,10 @@ sub BuildCross($)
# Rebuild from scratch to make sure cruft will not accumulate
InfoMsg "\nRebuilding the $Bits-bit test executables\n";
- system("( cd $DataDir/build-mingw$Bits && set -x && " .
- " rm -rf * && " .
- " time ../wine/configure --host=$Host --with-wine-tools=../build-native --without-x --without-freetype --disable-winetest && " .
- " time make -j$ncpus buildtests" .
- ") >>$LogFileName 2>&1");
+ system("cd $DataDir/build-mingw$Bits && set -x && ".
+ "rm -rf * && ".
+ "time ../wine/configure --host=$Host --with-wine-tools=../build-native --without-x --without-freetype --disable-winetest && ".
+ "time make -j$ncpus buildtests");
if ($? != 0)
{
LogMsg "Build cross ($Bits bits) failed\n";
@@ -191,9 +173,6 @@ sub BuildCross($)
$ENV{PATH} = "/usr/lib/ccache:/usr/bin:/bin";
delete $ENV{ENV};
-# Start with a clean logfile
-unlink($LogFileName);
-
if (! -d "$DataDir/staging" and ! mkdir "$DataDir/staging")
{
LogMsg "Unable to create '$DataDir/staging': $!\n";
--
2.17.1
June 20, 2018
[PATCH 3/4] testbot/Build: Don't use tainting and improve handling of the patch filename.
by Francois Gouget
Tainting is moot because the whole purpose of the script is to run
arbitrary user-provided code (in patch form).
Still validate the patch filename but use the standard IsValidFileName()
function (instead of the much stricter regular expression used so far)
so patches accepted by Submit.pl don't get rejected at this late stage.
However carefully quote the filename when building our shell command so
it does not fail if the filename contains a space (for instance).
Also note that in practice (so far) the patch filename is always called
patch.diff as this is hardcoded in WineRunBuild.pl. So this is all a
bit academic.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/build/Build.pl | 25 ++++++++++++++-----------
testbot/lib/WineTestBot/Utils.pm | 26 +++++++++++++++++++++++++-
2 files changed, 39 insertions(+), 12 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index 8318af12a..e97995559 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -1,10 +1,13 @@
-#!/usr/bin/perl -Tw
+#!/usr/bin/perl
# -*- Mode: Perl; perl-indent-level: 2; indent-tabs-mode: nil -*-
#
# Performs the 'build' task in the build machine. Specifically this applies a
# conformance test patch, rebuilds the impacted test and retrieves the
# resulting 32 and 64 bit binaries.
#
+# This script does not use tainting (-T) because its whole purpose is to run
+# arbitrary user-provided code anyway (in patch form).
+#
# Copyright 2009 Ge van Geldorp
# Copyright 2012-2014, 2017-2018 Francois Gouget
#
@@ -22,6 +25,7 @@
# License along with this library; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+use warnings;
use strict;
sub BEGIN
@@ -42,6 +46,8 @@ sub BEGIN
use WineTestBot::Config;
use WineTestBot::PatchUtils;
+use WineTestBot::Utils;
+
my $LogFileName = "$LogDir/Build.log";
@@ -85,7 +91,7 @@ sub ApplyPatch($)
InfoMsg "Applying patch\n";
system("( cd $DataDir/wine && set -x && " .
- " git apply --verbose $PatchFile && " .
+ " git apply --verbose ". ShQuote($PatchFile) ." && ".
" git add -A " .
") >>$LogFileName 2>&1");
if ($? != 0)
@@ -199,18 +205,15 @@ if (! $PatchFile || !$BitIndicators)
FatalError "Usage: Build.pl <patchfile> <bits>\n";
}
-# Untaint parameters
-if ($PatchFile =~ m/^([\w_.\-]+)$/)
+# Verify parameters
+if (!IsValidFileName($PatchFile))
{
- $PatchFile = "$DataDir/staging/$1";
- if (! -r $PatchFile)
- {
- FatalError "Patch file $PatchFile not readable\n";
- }
+ FatalError "The patch filename '$PatchFile' contains invalid characters\n";
}
-else
+$PatchFile = "$DataDir/staging/$PatchFile";
+if (!-r $PatchFile)
{
- FatalError "Invalid patch file $PatchFile\n";
+ FatalError "Patch file '$PatchFile' is not readable\n";
}
my ($Run32, $Run64);
diff --git a/testbot/lib/WineTestBot/Utils.pm b/testbot/lib/WineTestBot/Utils.pm
index 962e6ff67..111a56589 100644
--- a/testbot/lib/WineTestBot/Utils.pm
+++ b/testbot/lib/WineTestBot/Utils.pm
@@ -28,7 +28,8 @@ WineTestBot::Utils - Utility functions
use Exporter 'import';
our @EXPORT = qw(MakeSecureURL SecureConnection GenerateRandomString
OpenNewFile CreateNewFile CreateNewLink CreateNewDir
- DurationToString BuildEMailRecipient IsValidFileName);
+ DurationToString BuildEMailRecipient IsValidFileName
+ ShQuote);
use Fcntl;
@@ -196,4 +197,27 @@ sub IsValidFileName($)
return $FileName !~ m~[<>:"/\\|?*]~;
}
+=pod
+=over 12
+
+=item C<ShQuote()>
+
+Quotes strings so they can be used in shell commands.
+
+Note that this implies escaping '$'s and '`'s which may not be appropriate
+in another context.
+
+=back
+=cut
+
+sub ShQuote($)
+{
+ my ($Str)=@_;
+ $Str =~ s%\\%\\\\%g;
+ $Str =~ s%\$%\\\$%g;
+ $Str =~ s%\"%\\\"%g;
+ $Str =~ s%\`%\\\`%g;
+ return "\"$Str\"";
+}
+
1;
--
2.17.1
June 20, 2018
[PATCH 2/4] testbot/web: Reject filenames that are not valid Windows filenames.
by Francois Gouget
IsValidFileName() verifies that the filename is valid on both Windows
and Unix. This is necessary to ensure we will be able to upload the file
to the build and/or test VMs.
IsValidFileName() is defined in the Utils.pm module so it can be reused
where necessary.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/Utils.pm | 25 ++++++++++++++++++++++++-
testbot/web/Submit.pl | 4 ++--
2 files changed, 26 insertions(+), 3 deletions(-)
diff --git a/testbot/lib/WineTestBot/Utils.pm b/testbot/lib/WineTestBot/Utils.pm
index 8b0bfeb0c..962e6ff67 100644
--- a/testbot/lib/WineTestBot/Utils.pm
+++ b/testbot/lib/WineTestBot/Utils.pm
@@ -28,7 +28,7 @@ WineTestBot::Utils - Utility functions
use Exporter 'import';
our @EXPORT = qw(MakeSecureURL SecureConnection GenerateRandomString
OpenNewFile CreateNewFile CreateNewLink CreateNewDir
- DurationToString BuildEMailRecipient);
+ DurationToString BuildEMailRecipient IsValidFileName);
use Fcntl;
@@ -173,4 +173,27 @@ sub CreateNewDir($$)
}
}
+
+#
+# Shell helpers
+#
+
+=pod
+=over 12
+
+=item C<IsValidFileName()>
+
+Returns true if the filename is valid on Unix and Windows systems.
+
+This also ensures this is not a trick filename such as '../important/file'.
+
+=back
+=cut
+
+sub IsValidFileName($)
+{
+ my ($FileName) = @_;
+ return $FileName !~ m~[<>:"/\\|?*]~;
+}
+
1;
diff --git a/testbot/web/Submit.pl b/testbot/web/Submit.pl
index c16b99f1e..afebc722b 100644
--- a/testbot/web/Submit.pl
+++ b/testbot/web/Submit.pl
@@ -514,10 +514,10 @@ sub ValidateAndGetFileName($$)
$self->{ErrMessage} = "You must provide a file to test";
return undef;
}
- if ($FileName =~ m=[/\\]=)
+ if (!IsValidFileName($FileName))
{
$self->{ErrField} = $FieldName;
- $self->{ErrMessage} = "The filename is invalid";
+ $self->{ErrMessage} = "The filename contains invalid characters";
return undef;
}
my $PropertyDescriptor = CreateSteps()->GetPropertyDescriptorByName("FileName");
--
2.17.1
June 20, 2018
[PATCH 1/4] testbot: Add section headers and reorder the Utils.pm functions.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/Utils.pm | 100 +++++++++++++++++--------------
1 file changed, 54 insertions(+), 46 deletions(-)
diff --git a/testbot/lib/WineTestBot/Utils.pm b/testbot/lib/WineTestBot/Utils.pm
index 81a2eda39..8b0bfeb0c 100644
--- a/testbot/lib/WineTestBot/Utils.pm
+++ b/testbot/lib/WineTestBot/Utils.pm
@@ -35,6 +35,10 @@ use Fcntl;
use WineTestBot::Config;
+#
+# Web helpers
+#
+
sub MakeSecureURL($)
{
my ($URL) = @_;
@@ -53,6 +57,56 @@ sub SecureConnection()
return defined($ENV{"HTTPS"}) && $ENV{"HTTPS"} eq "on";
}
+sub DurationToString($;$)
+{
+ my ($Secs, $Raw) = @_;
+
+ return "n/a" if (!defined $Secs);
+
+ my @Parts;
+ if (!$Raw)
+ {
+ my $Mins = int($Secs / 60);
+ $Secs -= 60 * $Mins;
+ my $Hours = int($Mins / 60);
+ $Mins -= 60 * $Hours;
+ my $Days = int($Hours / 24);
+ $Hours -= 24 * $Days;
+ push @Parts, "${Days}d" if ($Days);
+ push @Parts, "${Hours}h" if ($Hours);
+ push @Parts, "${Mins}m" if ($Mins);
+ }
+ if (!@Parts or int($Secs) != 0)
+ {
+ push @Parts, (@Parts or int($Secs) == $Secs) ?
+ int($Secs) ."s" :
+ sprintf('%.1fs', $Secs);
+ }
+ return join(" ", @Parts);
+}
+
+sub BuildEMailRecipient($$)
+{
+ my ($EMailAddress, $Name) = @_;
+
+ if (! defined($EMailAddress))
+ {
+ return undef;
+ }
+ my $Recipient = "<" . $EMailAddress . ">";
+ if ($Name)
+ {
+ $Recipient .= " ($Name)";
+ }
+
+ return $Recipient;
+}
+
+
+#
+# Temporary file helpers
+#
+
sub GenerateRandomString($)
{
my ($Len) = @_;
@@ -119,50 +173,4 @@ sub CreateNewDir($$)
}
}
-sub DurationToString($;$)
-{
- my ($Secs, $Raw) = @_;
-
- return "n/a" if (!defined $Secs);
-
- my @Parts;
- if (!$Raw)
- {
- my $Mins = int($Secs / 60);
- $Secs -= 60 * $Mins;
- my $Hours = int($Mins / 60);
- $Mins -= 60 * $Hours;
- my $Days = int($Hours / 24);
- $Hours -= 24 * $Days;
- push @Parts, "${Days}d" if ($Days);
- push @Parts, "${Hours}h" if ($Hours);
- push @Parts, "${Mins}m" if ($Mins);
- }
- if (!@Parts or int($Secs) != 0)
- {
- push @Parts, (@Parts or int($Secs) == $Secs) ?
- int($Secs) ."s" :
- sprintf('%.1fs', $Secs);
- }
- return join(" ", @Parts);
-}
-
-sub BuildEMailRecipient($$)
-{
- my ($EMailAddress, $Name) = @_;
-
- if (! defined($EMailAddress))
- {
- return undef;
- }
- my $Recipient = "<" . $EMailAddress . ">";
- if ($Name)
- {
- $Recipient .= " ($Name)";
- }
-
- return $Recipient;
-}
-
-
1;
--
2.17.1
June 20, 2018
[PATCH] testbot/WineRunTask: Trace the effective timeout, with leeway.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunTask.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 4fd51d985..51b105b19 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -493,7 +493,7 @@ if (!$Pid)
my $NewStatus = 'completed';
my ($TaskFailures, $TaskTimedOut, $TAError, $PossibleCrash);
-Debug(Elapsed($Start), " Waiting for the script (", $Task->Timeout, "s timeout)\n");
+Debug(Elapsed($Start), " Waiting for the script (", $Timeout, "s timeout)\n");
if (!defined $TA->Wait($Pid, $Timeout, $Keepalive))
{
my $ErrMessage = $TA->GetLastError();
--
2.17.1
June 20, 2018
[PATCH] testbot: Retrieve the list of Wine files.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunReconfig.pl | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index fe69fc3b7..d04b78061 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -444,6 +444,16 @@ if ($NewStatus eq "completed")
{
$TAError = "An error occurred while retrieving the test list: ". $TA->GetLastError();
}
+
+ Debug(Elapsed($Start), " Retrieving the list of Wine files '$TaskDir/winefiles.txt'\n");
+ if ($TA->GetFile("latest/winefiles.txt", "$TaskDir/winefiles.txt"))
+ {
+ copy "$TaskDir/winefiles.txt", "$DataDir/latest/winefiles.txt";
+ }
+ elsif (!defined $TAError)
+ {
+ $TAError = "An error occurred while retrieving the list of Wine files: ". $TA->GetLastError();
+ }
}
$TA->Disconnect();
--
2.17.1
June 20, 2018
[PATCH] testbot/WineRun*: Rename the timeout WrapUpAndExit() parameter.
by Francois Gouget
It is a boolean indicating whether the task timed out, not the timeout
value in seconds.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineRunBuild.pl | 4 ++--
testbot/bin/WineRunReconfig.pl | 4 ++--
testbot/bin/WineRunTask.pl | 4 ++--
3 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/testbot/bin/WineRunBuild.pl b/testbot/bin/WineRunBuild.pl
index eab33bc08..1bc6cffbc 100755
--- a/testbot/bin/WineRunBuild.pl
+++ b/testbot/bin/WineRunBuild.pl
@@ -196,11 +196,11 @@ sub LogTaskError($)
sub WrapUpAndExit($;$$)
{
- my ($Status, $Retry, $Timeout) = @_;
+ my ($Status, $Retry, $TimedOut) = @_;
my $NewVMStatus = $Status eq 'queued' ? 'offline' : 'dirty';
my $VMResult = $Status eq "boterror" ? "boterror" :
$Status eq "queued" ? "error" :
- $Timeout ? "timeout" : "";
+ $TimedOut ? "timeout" : "";
my $TestFailures;
my $Tries = $Task->TestFailures || 0;
diff --git a/testbot/bin/WineRunReconfig.pl b/testbot/bin/WineRunReconfig.pl
index e7b447e92..fe69fc3b7 100755
--- a/testbot/bin/WineRunReconfig.pl
+++ b/testbot/bin/WineRunReconfig.pl
@@ -195,12 +195,12 @@ sub LogTaskError($)
sub WrapUpAndExit($;$$)
{
- my ($Status, $Retry, $Timeout) = @_;
+ my ($Status, $Retry, $TimedOut) = @_;
my $NewVMStatus = $Status eq 'queued' ? 'offline' :
$Status eq 'completed' ? 'idle' : 'dirty';
my $VMResult = $Status eq "boterror" ? "boterror" :
$Status eq "queued" ? "error" :
- $Timeout ? "timeout" : "";
+ $TimedOut ? "timeout" : "";
my $TestFailures;
my $Tries = $Task->TestFailures || 0;
diff --git a/testbot/bin/WineRunTask.pl b/testbot/bin/WineRunTask.pl
index 3b0ccbc4a..e10656ed8 100755
--- a/testbot/bin/WineRunTask.pl
+++ b/testbot/bin/WineRunTask.pl
@@ -226,11 +226,11 @@ sub LogTaskError($)
sub WrapUpAndExit($;$$$)
{
- my ($Status, $TestFailures, $Retry, $Timeout) = @_;
+ my ($Status, $TestFailures, $Retry, $TimedOut) = @_;
my $NewVMStatus = $Status eq 'queued' ? 'offline' : 'dirty';
my $VMResult = $Status eq "boterror" ? "boterror" :
$Status eq "queued" ? "error" :
- $Timeout ? "timeout" : "";
+ $TimedOut ? "timeout" : "";
Debug(Elapsed($Start), " Taking a screenshot\n");
TakeScreenshot($VM, "$TaskDir/screenshot.png");
--
2.17.1
June 20, 2018
[PATCH] testbot/build: Detect patches that impact more than the tests.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/build/Build.pl | 2 +-
testbot/lib/WineTestBot/PatchUtils.pm | 101 ++++++++++++++++----------
2 files changed, 64 insertions(+), 39 deletions(-)
diff --git a/testbot/bin/build/Build.pl b/testbot/bin/build/Build.pl
index 3fe0e14ea..8318af12a 100755
--- a/testbot/bin/build/Build.pl
+++ b/testbot/bin/build/Build.pl
@@ -246,7 +246,7 @@ exit(1) if (!$Impacts);
CountCPUs();
-if (!BuildNative())
+if ($Impacts->{WineBuild} and !BuildNative())
{
exit(1);
}
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index 6eb8e3cd8..f83df6087 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -36,6 +36,23 @@ our @EXPORT = qw(GetPatchImpact UpdateWineData);
use WineTestBot::Config;
+# Patches to these paths don't impact the Wine build. So ignore them.
+my $IgnoredPathsRe = join('|',
+ '\.mailmap$',
+ 'ANNOUNCE$',
+ 'AUTHORS$',
+ 'COPYING\.LIB$',
+ 'LICENSE\$',
+ 'LICENSE\.OLD$',
+ 'MAINTAINERS$',
+ 'README$',
+ 'VERSION$',
+ 'documentation/',
+ 'tools/c2man\.pl$',
+ 'tools/winapi/',
+ 'tools/winemaker/',
+);
+
=pod
=over 12
@@ -102,46 +119,54 @@ sub GetTestList()
return $TestList;
}
-sub _AddTest($$$)
+sub _HandleFile($$$)
{
my ($Impacts, $Path, $Change) = @_;
- return if ($Path !~ m~^(dlls|programs)/([^/]+)/tests/([^/\s]+)$~);
- my ($Root, $Module, $File) = ($1, $2, $3);
-
- my $Tests = $Impacts->{Tests};
- if (!$Tests->{$Module})
+ if ($Path =~ m~^(dlls|programs)/([^/]+)/tests/([^/\s]+)$~)
{
- my $ExeBase = ($Root eq "programs") ? "${Module}.exe_test" :
- "${Module}_test";
- $Tests->{$Module} = {
- "Module" => $Module,
- "Path" => "$Root/$Module/tests",
- "ExeBase" => $ExeBase,
- };
- }
+ my ($Root, $Module, $File) = ($1, $2, $3);
+ $Impacts->{TestBuild} = 1;
- # Assume makefile modifications may break the build but not the tests
- if ($File eq "Makefile.in")
- {
- if ($Change eq "new" or $Change eq "rm")
+ my $Tests = $Impacts->{Tests};
+ if (!$Tests->{$Module})
{
- # This adds / removes a directory
- $Impacts->{Makefiles} = 1;
+ my $ExeBase = ($Root eq "programs") ? "${Module}.exe_test" :
+ "${Module}_test";
+ $Tests->{$Module} = {
+ "Module" => $Module,
+ "Path" => "$Root/$Module/tests",
+ "ExeBase" => $ExeBase,
+ };
}
- return;
- }
- return if ($Impacts->{NoUnits});
- if (!$Tests->{$Module}->{Files})
- {
- my $TestList = ( $Impacts->{TestList} ||= GetTestList() );
- foreach my $File (keys %{$TestList->{$Module}})
+ # Assume makefile modifications may break the build but not the tests
+ if ($File eq "Makefile.in")
{
- $Tests->{$Module}->{Files}->{$File} = 0; # not modified
+ if ($Change eq "new" or $Change eq "rm")
+ {
+ # This adds / removes a directory
+ $Impacts->{Makefiles} = 1;
+ }
+ return;
}
+ return if ($Impacts->{NoUnits});
+
+ if (!$Tests->{$Module}->{Files})
+ {
+ my $TestList = ( $Impacts->{TestList} ||= GetTestList() );
+ foreach my $File (keys %{$TestList->{$Module}})
+ {
+ $Tests->{$Module}->{Files}->{$File} = 0; # not modified
+ }
+ }
+ $Tests->{$Module}->{Files}->{$File} = $Change;
+ }
+ else
+ {
+ # Figure out if this patch impacts the Wine build
+ $Impacts->{WineBuild} = 1 if ($Path !~ /^(?:$IgnoredPathsRe)/);
}
- $Tests->{$Module}->{Files}->{$File} = $Change;
}
=pod
@@ -176,8 +201,8 @@ sub GetPatchImpact($;$$)
{
foreach my $File (keys %{$PastInfo->{Files}})
{
- _AddTest($Impacts, "$PastInfo->{Path}/$File",
- $PastInfo->{Files}->{$File} eq "rm" ? "rm" : 0);
+ _HandleFile($Impacts, "$PastInfo->{Path}/$File",
+ $PastInfo->{Files}->{$File} eq "rm" ? "rm" : 0);
}
}
}
@@ -187,33 +212,33 @@ sub GetPatchImpact($;$$)
{
if ($Line =~ m=^--- \w+/(?:aclocal\.m4|configure\.ac)$=)
{
- $Impacts->{Autoconf} = 1;
+ $Impacts->{WineBuild} = $Impacts->{Autoconf} = 1;
}
elsif ($Line =~ m=^--- \w+/configure$=)
{
- $Impacts->{HasConfigure} = 1;
+ $Impacts->{WineBuild} = $Impacts->{HasConfigure} = 1;
}
elsif ($Line =~ m=^--- \w+/tools/make_makefiles$=)
{
- $Impacts->{Makefiles} = 1;
+ $Impacts->{WineBuild} = $Impacts->{Makefiles} = 1;
}
elsif ($Line =~ m=^--- /dev/null$=)
{
$Change = "new";
}
- elsif ($Line =~ m~^--- \w+/([^/]+/[^/]+/tests/[^/\s]+)$~)
+ elsif ($Line =~ m~^--- \w+/([^\s]+)$~)
{
$Path = $1;
}
elsif ($Line =~ m~^\+\+\+ /dev/null$~)
{
- _AddTest($Impacts, $Path, "rm") if (defined $Path);
+ _HandleFile($Impacts, $Path, "rm") if (defined $Path);
$Path = undef;
$Change = "";
}
- elsif ($Line =~ m~^\+\+\+ \w+/(\w+/[^/]+/tests/[^/\s]+)$~)
+ elsif ($Line =~ m~^\+\+\+ \w+/([^\s]+)$~)
{
- _AddTest($Impacts, $1, $Change || "modify");
+ _HandleFile($Impacts, $1, $Change || "modify");
$Path = undef;
$Change = "";
}
--
2.17.1
June 20, 2018
[PATCH] testbot: Adjust the reconfig timeout.
by Francois Gouget
$ReconfigTimeout was way overestimated, maybe reflecting a time when
either the TestBot or the Wine dependencies were causing too many files
to be rebuilt.
Note that $BuildTimeout is a bit large too: a patch touching a test
module and a core header would typically only require about 2.5
minutes. But in the unlikely event where that patch touched dozens of
test modules it may still be too short. So $BuildTimeout is left
unchanged.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/Config.pm | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/testbot/lib/WineTestBot/Config.pm b/testbot/lib/WineTestBot/Config.pm
index b7d633db6..66cb813ff 100644
--- a/testbot/lib/WineTestBot/Config.pm
+++ b/testbot/lib/WineTestBot/Config.pm
@@ -97,9 +97,10 @@ $SingleTimeout = 2 * 60;
# How long to let a regular build run before forcibly shutting it down
# (in seconds).
$BuildTimeout = 5 * 60;
-# How long to let a full recompilation run before forcibly shutting it down
-# (in seconds).
-$ReconfigTimeout = 45 * 60;
+# How long to let a reconfig task run before forcibly shutting it down
+# (in seconds). Note that this includes building the native Wine build tools,
+# and the 32 and 64 bit test executables.
+$ReconfigTimeout = (1 + 2 * 5) * 60;
# How much to add to the task timeout to account for file transfers, etc.
$TimeoutMargin = 2 * 60;
# Maximum amount of traces for a test unit.
--
2.17.1
June 20, 2018
[PATCH] testbot: Simplify a loop in PatchUtils::GetPatchImpact().
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/PatchUtils.pm | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/testbot/lib/WineTestBot/PatchUtils.pm b/testbot/lib/WineTestBot/PatchUtils.pm
index ec609d987..6eb8e3cd8 100644
--- a/testbot/lib/WineTestBot/PatchUtils.pm
+++ b/testbot/lib/WineTestBot/PatchUtils.pm
@@ -227,10 +227,8 @@ sub GetPatchImpact($;$$)
$Impacts->{ModuleCount} = 0;
$Impacts->{UnitCount} = 0;
- foreach my $Module (keys %{$Impacts->{Tests}})
+ foreach my $TestInfo (values %{$Impacts->{Tests}})
{
- my $TestInfo = $Impacts->{Tests}->{$Module};
-
# For each module, identify modifications to non-C files and helper dlls
my $AllUnits;
foreach my $File (keys %{$TestInfo->{Files}})
--
2.17.1
June 20, 2018
K32EnumDeviceDrivers
by Anthony Lauzon
Hi All,
I've been hacking away at K32EnumDeviceDrivers trying to get it to properly
handle calls, and have made some decent progress that maybe some of you who
are experts can finish. The reason why I am trying to implement
K32EnumDeviceDrivers is that Creative's Emulator X3 crashes when trying to
call it. I've managed to get the app one step closer to launching with
this K32EnumDeviceDrivers implementation, which does in fact enumerate the
devices, and am now stuck on a different error. I hope this patch is of
some utility to you all.
Anthony
June 19, 2018
[PATCH 2/2] winedbg: Suppress all message boxes if ShowCrashDialog is disabled.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
The only message box shown by this function is the aforementioned
'failed to attach to process' error, but in general the user probably
doesn't want any windows to be shown if ShowCrashDialog is disabled.
programs/winedbg/crashdlg.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/programs/winedbg/crashdlg.c b/programs/winedbg/crashdlg.c
index 4e02a4b..5eb3d27 100644
--- a/programs/winedbg/crashdlg.c
+++ b/programs/winedbg/crashdlg.c
@@ -34,13 +34,18 @@
static char *crash_log;
-int msgbox_res_id(HWND hwnd, UINT textId, UINT captionId, UINT uType)
+int msgbox_res_id(HWND hwnd, UINT textid, UINT captionid, UINT type)
{
- WCHAR caption[256];
- WCHAR text[256];
- LoadStringW(GetModuleHandleW(NULL), captionId, caption, sizeof(caption)/sizeof(caption[0]));
- LoadStringW(GetModuleHandleW(NULL), textId, text, sizeof(text)/sizeof(text[0]));
- return MessageBoxW(hwnd, text, caption, uType);
+ if (DBG_IVAR(ShowCrashDialog))
+ {
+ WCHAR caption[256];
+ WCHAR text[256];
+ LoadStringW(GetModuleHandleW(NULL), captionid, caption, ARRAY_SIZE(caption));
+ LoadStringW(GetModuleHandleW(NULL), textid, text, ARRAY_SIZE(text));
+ return MessageBoxW(hwnd, text, caption, type);
+ }
+
+ return IDCANCEL;
}
static WCHAR *get_program_name(HANDLE hProcess)
--
2.7.4
June 19, 2018
[PATCH 1/2] winedbg: Provide a more helpful error message when unable to attach to a process.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
If anyone has suggestions for better wording, feel free to speak.
programs/winedbg/winedbg.rc | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/programs/winedbg/winedbg.rc b/programs/winedbg/winedbg.rc
index 2cfaf9e..7ad7686 100644
--- a/programs/winedbg/winedbg.rc
+++ b/programs/winedbg/winedbg.rc
@@ -34,8 +34,9 @@ END
STRINGTABLE
BEGIN
- IDS_AUTO_CAPTION "Wine program crash"
- IDS_INVALID_PARAMS "Internal errors - invalid parameters received"
+ IDS_AUTO_CAPTION "Program Error"
+ IDS_INVALID_PARAMS "A program on your system has crashed, but WineDbg was \
+ unable to attach to the process to obtain a backtrace."
IDS_UNIDENTIFIED "(unidentified)"
IDS_TEXT_FILES, "Text files (*.txt)"
IDS_ALL_FILES, "All files (*.*)"
--
2.7.4
June 19, 2018
Re: [PATCH 3/6] d3d9/tests: Add test for depth stencil initialization.
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=39233
Your paranoid android.
=== w1064 (32 bit visual) ===
visual.c:8620: Test failed: Got unexpected color 0x00007580 for quad 2 (different colors).
June 19, 2018
[PATCH 6/6] wined3d: Call wined3d_cs_emit_update_sub_resource() directly in buffer_init().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 4b14d684e542..181be6bbe487 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1325,6 +1325,8 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
{
const struct wined3d_gl_info *gl_info = &device->adapter->gl_info;
const struct wined3d_format *format = wined3d_get_format(gl_info, format_id, usage);
+ struct wined3d_resource *resource = &buffer->resource;
+ struct wined3d_box box;
BOOL dynamic_buffer_ok;
HRESULT hr;
@@ -1346,7 +1348,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
return E_INVALIDARG;
}
- if (FAILED(hr = resource_init(&buffer->resource, device, WINED3D_RTYPE_BUFFER, format, WINED3D_MULTISAMPLE_NONE,
+ if (FAILED(hr = resource_init(resource, device, WINED3D_RTYPE_BUFFER, format, WINED3D_MULTISAMPLE_NONE,
0, usage, access, size, 1, 1, size, parent, parent_ops, &buffer_resource_ops)))
{
WARN("Failed to initialize resource, hr %#x.\n", hr);
@@ -1386,7 +1388,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
{
TRACE("Not creating a BO because the buffer is not GPU accessible.\n");
}
- else if (!dynamic_buffer_ok && (buffer->resource.usage & WINED3DUSAGE_DYNAMIC))
+ else if (!dynamic_buffer_ok && (resource->usage & WINED3DUSAGE_DYNAMIC))
{
TRACE("Not creating a BO because the buffer has dynamic usage and no GL support.\n");
}
@@ -1398,16 +1400,19 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
if (!(buffer->maps = heap_alloc(sizeof(*buffer->maps))))
{
ERR("Out of memory.\n");
- buffer_unload(&buffer->resource);
- resource_cleanup(&buffer->resource);
- wined3d_resource_wait_idle(&buffer->resource);
+ buffer_unload(resource);
+ resource_cleanup(resource);
+ wined3d_resource_wait_idle(resource);
return E_OUTOFMEMORY;
}
buffer->maps_size = 1;
if (data)
- wined3d_device_update_sub_resource(device, &buffer->resource,
- 0, NULL, data->data, data->row_pitch, data->slice_pitch, 0);
+ {
+ wined3d_box_set(&box, 0, 0, resource->size, 1, 0, 1);
+ wined3d_cs_emit_update_sub_resource(device->cs, resource,
+ 0, &box, data->data, data->row_pitch, data->slice_pitch);
+ }
return WINED3D_OK;
}
--
2.16.4
June 19, 2018
[PATCH 5/6] wined3d: Use WINED3D_LOCATION_DISCARDED before initializing buffers with data.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index e06d156c0b3f..4b14d684e542 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1354,7 +1354,7 @@ static HRESULT buffer_init(struct wined3d_buffer *buffer, struct wined3d_device
}
buffer->buffer_type_hint = buffer_type_hint_from_bind_flags(gl_info, bind_flags);
buffer->bind_flags = bind_flags;
- buffer->locations = WINED3D_LOCATION_SYSMEM;
+ buffer->locations = data ? WINED3D_LOCATION_DISCARDED : WINED3D_LOCATION_SYSMEM;
if (!wined3d_resource_allocate_sysmem(&buffer->resource))
return E_OUTOFMEMORY;
--
2.16.4
June 19, 2018
[PATCH 4/6] wined3d: Reduce nesting in texture2d_load_sysmem().
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/wined3d/surface.c | 24 ++++++++++--------------
1 file changed, 10 insertions(+), 14 deletions(-)
diff --git a/dlls/wined3d/surface.c b/dlls/wined3d/surface.c
index 521703314d0c..5502d055c263 100644
--- a/dlls/wined3d/surface.c
+++ b/dlls/wined3d/surface.c
@@ -198,7 +198,6 @@ static void texture2d_blt_fbo(const struct wined3d_device *device, struct wined3
else
wined3d_texture_prepare_location(dst_texture, dst_sub_resource_idx, context, dst_location);
-
if (src_location == WINED3D_LOCATION_DRAWABLE)
{
required_texture = src_texture;
@@ -1655,21 +1654,18 @@ BOOL texture2d_load_sysmem(struct wined3d_texture *texture, unsigned int sub_res
WINED3D_LOCATION_RB_RESOLVED, dst_location);
return TRUE;
}
- else
- {
- if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
- wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
- /* Download the sub-resource to system memory. */
- if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
- {
- wined3d_texture_bind_and_dirtify(texture, context,
- !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB));
- texture2d_download_data(texture, sub_resource_idx, context, dst_location);
- ++texture->download_count;
+ if (sub_resource->locations & (WINED3D_LOCATION_RB_MULTISAMPLE | WINED3D_LOCATION_RB_RESOLVED))
+ wined3d_texture_load_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
- return TRUE;
- }
+ /* Download the sub-resource to system memory. */
+ if (sub_resource->locations & (WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_TEXTURE_SRGB))
+ {
+ wined3d_texture_bind_and_dirtify(texture, context,
+ !(sub_resource->locations & WINED3D_LOCATION_TEXTURE_RGB));
+ texture2d_download_data(texture, sub_resource_idx, context, dst_location);
+ ++texture->download_count;
+ return TRUE;
}
if (!(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL)
--
2.16.4
June 19, 2018
[PATCH 3/6] d3d9/tests: Add test for depth stencil initialization.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
dlls/d3d9/tests/visual.c | 115 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 115 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 95982e051556..b36c1890392c 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -211,6 +211,34 @@ static DWORD getPixelColor(IDirect3DDevice9 *device, UINT x, UINT y)
return ret;
}
+#define check_rt_color(a, b) check_rt_color_(__LINE__, a, b)
+static void check_rt_color_(unsigned int line, IDirect3DSurface9 *rt, D3DCOLOR expected_color)
+{
+ struct surface_readback rb;
+ D3DSURFACE_DESC desc;
+ unsigned int x, y;
+ D3DCOLOR color;
+ HRESULT hr;
+
+ hr = IDirect3DSurface9_GetDesc(rt, &desc);
+ ok_(__FILE__, line)(hr == S_OK, "Failed to get surface desc, hr %#x.\n", hr);
+
+ get_rt_readback(rt, &rb);
+ for (y = 0; y < desc.Height; ++y)
+ {
+ for (x = 0; x < desc.Width; ++x)
+ {
+ color = get_readback_color(&rb, x, y) & 0x00ffffff;
+ if (color != expected_color)
+ break;
+ }
+ if (color != expected_color)
+ break;
+ }
+ release_surface_readback(&rb);
+ ok_(__FILE__, line)(color == 0x000000ff, "Got unexpected color 0x%08x.\n", color);
+}
+
static IDirect3DDevice9 *create_device(IDirect3D9 *d3d, HWND device_window, HWND focus_window, BOOL windowed)
{
D3DPRESENT_PARAMETERS present_parameters = {0};
@@ -21406,6 +21434,92 @@ done:
DestroyWindow(window);
}
+static void test_depth_stencil_init(void)
+{
+ IDirect3DDevice9 *device;
+ IDirect3DSurface9 *ds[2];
+ IDirect3DSurface9 *rt;
+ IDirect3D9 *d3d;
+ ULONG refcount;
+ unsigned int i;
+ HWND window;
+ HRESULT hr;
+
+ static const struct
+ {
+ struct vec3 position;
+ }
+ quad[] =
+ {
+ {{-1.0f, -1.0f, 0.0f}},
+ {{-1.0f, 1.0f, 0.0f}},
+ {{ 1.0f, -1.0f, 0.0f}},
+ {{ 1.0f, 1.0f, 0.0f}},
+ };
+
+ window = create_window();
+ d3d = Direct3DCreate9(D3D_SDK_VERSION);
+ ok(!!d3d, "Failed to create D3D object.\n");
+ if (!(device = create_device(d3d, window, window, TRUE)))
+ {
+ skip("Failed to create D3D device.\n");
+ goto done;
+ }
+
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_LIGHTING, FALSE);
+ ok(hr == S_OK, "Failed to set render state, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZENABLE, D3DZB_TRUE);
+ ok(hr == S_OK, "Failed to set render state, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_ZFUNC, D3DCMP_LESSEQUAL);
+ ok(hr == S_OK, "Failed to set render state, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1);
+ ok(hr == S_OK, "Failed to set color op, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetTextureStageState(device, 0, D3DTSS_COLORARG1, D3DTA_TFACTOR);
+ ok(hr == S_OK, "Failed to set color arg, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetFVF(device, D3DFVF_XYZ);
+ ok(hr == S_OK, "Failed to set FVF, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_CreateDepthStencilSurface(device, 640, 480, D3DFMT_D24S8, 0, 0, FALSE, &ds[0], NULL);
+ ok(hr == S_OK, "Failed to create depth stencil surface, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_GetDepthStencilSurface(device, &ds[1]);
+ ok(hr == S_OK, "Failed to get depth stencil surface, hr %#x.\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(ds); ++i)
+ {
+ hr = IDirect3DDevice9_SetDepthStencilSurface(device, ds[i]);
+ ok(hr == S_OK, "Failed to set depth stencil surface, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_Clear(device, 0, NULL, D3DCLEAR_TARGET, 0xffffffff, 0.0f, 0);
+ ok(hr == S_OK, "Failed to clear, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_BeginScene(device);
+ ok(hr == S_OK, "Failed to begin scene, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_SetRenderState(device, D3DRS_TEXTUREFACTOR, 0x000000ff);
+ ok(hr == S_OK, "Failed to set render state, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_DrawPrimitiveUP(device, D3DPT_TRIANGLESTRIP, 2, quad, sizeof(*quad));
+ ok(hr == S_OK, "Failed to draw, hr %#x.\n", hr);
+ hr = IDirect3DDevice9_EndScene(device);
+ ok(hr == S_OK, "Failed to end scene, hr %#x.\n", hr);
+
+ hr = IDirect3DDevice9_GetRenderTarget(device, 0, &rt);
+ ok(hr == S_OK, "Failed to get render target, hr %#x.\n", hr);
+ check_rt_color(rt, 0x000000ff);
+ IDirect3DSurface9_Release(rt);
+
+ hr = IDirect3DDevice9_Present(device, NULL, NULL, NULL, NULL);
+ ok(hr == D3D_OK, "Failed to present, hr %#x.\n", hr);
+
+ IDirect3DSurface9_Release(ds[i]);
+ }
+
+ refcount = IDirect3DDevice9_Release(device);
+ ok(!refcount, "Device has %u references left.\n", refcount);
+
+done:
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
+
static void test_texture_blending(void)
{
#define STATE_END() {0xffffffff, 0xffffffff}
@@ -24037,6 +24151,7 @@ START_TEST(visual)
test_flip();
test_uninitialized_varyings();
test_multisample_init();
+ test_depth_stencil_init();
test_texture_blending();
test_color_clamping();
test_line_antialiasing_blending();
--
2.16.4
June 19, 2018
[PATCH 2/6] wined3d: Initialize depth/stencil texture data.
by Józef Kucia
Signed-off-by: Józef Kucia <jkucia(a)codeweavers.com>
---
Fixes rendering glitches in Company of Heroes on radeonsi.
---
dlls/wined3d/texture.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 91c703c970fd..c316906a9576 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -2802,8 +2802,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
if (wined3d_texture_use_pbo(texture, gl_info))
texture->resource.map_binding = WINED3D_LOCATION_BUFFER;
- if ((desc->resource_type != WINED3D_RTYPE_TEXTURE_3D
- && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
+ if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D
|| !wined3d_texture_use_pbo(texture, gl_info))
{
if (!wined3d_resource_allocate_sysmem(&texture->resource))
@@ -2842,8 +2841,7 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
sub_resource = &texture->sub_resources[i];
sub_resource->locations = WINED3D_LOCATION_DISCARDED;
- if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D
- && !(texture->resource.usage & WINED3DUSAGE_DEPTHSTENCIL))
+ if (desc->resource_type != WINED3D_RTYPE_TEXTURE_3D)
{
wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_SYSMEM);
wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_SYSMEM);
--
2.16.4
June 19, 2018