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