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
December 2019
- 73 participants
- 1394 messages
[PATCH 3/9] dwrite: Use IDWriteFactory7 internall for fontfaces.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 10 +++++-----
dlls/dwrite/font.c | 11 ++++++-----
dlls/dwrite/main.c | 14 +++++++-------
3 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index a5d946c385..1598bb6aee 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -154,7 +154,7 @@ struct glyphrunanalysis_desc
struct fontface_desc
{
- IDWriteFactory5 *factory;
+ IDWriteFactory7 *factory;
DWRITE_FONT_FACE_TYPE face_type;
IDWriteFontFile * const *files;
IDWriteFontFileStream *stream;
@@ -193,7 +193,7 @@ struct dwrite_fontface
UINT32 file_count;
UINT32 index;
- IDWriteFactory5 *factory;
+ IDWriteFactory7 *factory;
struct fontfacecached *cached;
USHORT simulations;
@@ -268,7 +268,7 @@ extern HRESULT factory_get_cached_fontface(IDWriteFactory5*,IDWriteFontFile*cons
struct list**,REFIID,void**) DECLSPEC_HIDDEN;
extern void factory_detach_fontcollection(IDWriteFactory5 *factory, IDWriteFontCollection3 *collection) DECLSPEC_HIDDEN;
extern void factory_detach_gdiinterop(IDWriteFactory5*,IDWriteGdiInterop1*) DECLSPEC_HIDDEN;
-extern struct fontfacecached *factory_cache_fontface(IDWriteFactory5 *factory, struct list *fontfaces,
+extern struct fontfacecached *factory_cache_fontface(IDWriteFactory7 *factory, struct list *fontfaces,
IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
extern void get_logfont_from_font(IDWriteFont*,LOGFONTW*) DECLSPEC_HIDDEN;
extern void get_logfont_from_fontface(IDWriteFontFace*,LOGFONTW*) DECLSPEC_HIDDEN;
@@ -276,8 +276,8 @@ extern HRESULT get_fontsig_from_font(IDWriteFont*,FONTSIGNATURE*) DECLSPEC_HIDDE
extern HRESULT get_fontsig_from_fontface(IDWriteFontFace*,FONTSIGNATURE*) DECLSPEC_HIDDEN;
extern HRESULT create_gdiinterop(IDWriteFactory5*,IDWriteGdiInterop1**) DECLSPEC_HIDDEN;
extern void fontface_detach_from_cache(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
-extern void factory_lock(IDWriteFactory5*) DECLSPEC_HIDDEN;
-extern void factory_unlock(IDWriteFactory5*) DECLSPEC_HIDDEN;
+extern void factory_lock(IDWriteFactory7 *factory) DECLSPEC_HIDDEN;
+extern void factory_unlock(IDWriteFactory7 *factory) DECLSPEC_HIDDEN;
extern HRESULT create_inmemory_fileloader(IDWriteFontFileLoader**) DECLSPEC_HIDDEN;
extern HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index,
IDWriteFontResource **resource) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index bfe32d5fd9..8c58d7561a 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -551,7 +551,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
freetype_notify_cacheremove(iface);
- IDWriteFactory5_Release(fontface->factory);
+ IDWriteFactory7_Release(fontface->factory);
heap_free(fontface);
}
@@ -1518,7 +1518,7 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace5
if (FAILED(hr = get_filestream_from_file(data->file, &desc.stream)))
return hr;
- desc.factory = font->family->collection->factory;
+ desc.factory = (IDWriteFactory7 *)font->family->collection->factory;
desc.face_type = data->face_type;
desc.files = &data->file;
desc.files_number = 1;
@@ -4051,7 +4051,7 @@ HRESULT create_font_collection(IDWriteFactory5 *factory, IDWriteFontFileEnumerat
WCHAR familyW[255];
UINT32 index;
- desc.factory = factory;
+ desc.factory = (IDWriteFactory7 *)factory;
desc.face_type = face_type;
desc.files = &file;
desc.stream = stream;
@@ -4394,7 +4394,7 @@ static HRESULT eudc_collection_add_family(IDWriteFactory5 *factory, struct dwrit
struct fontface_desc desc;
/* alloc and init new font data structure */
- desc.factory = factory;
+ desc.factory = (IDWriteFactory7 *)factory;
desc.face_type = face_type;
desc.index = i;
desc.files = &file;
@@ -4660,7 +4660,8 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
fontface->colr.exists = TRUE;
fontface->index = desc->index;
fontface->simulations = desc->simulations;
- IDWriteFactory5_AddRef(fontface->factory = desc->factory);
+ fontface->factory = desc->factory;
+ IDWriteFactory7_AddRef(fontface->factory);
for (i = 0; i < fontface->file_count; i++) {
fontface->files[i] = desc->files[i];
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 1c1fabdb7d..e4b76823ff 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -847,15 +847,15 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory
return create_font_file(loader, reference_key, key_size, font_file);
}
-void factory_lock(IDWriteFactory5 *iface)
+void factory_lock(IDWriteFactory7 *iface)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
EnterCriticalSection(&factory->cs);
}
-void factory_unlock(IDWriteFactory5 *iface)
+void factory_unlock(IDWriteFactory7 *iface)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
LeaveCriticalSection(&factory->cs);
}
@@ -935,10 +935,10 @@ HRESULT factory_get_cached_fontface(IDWriteFactory5 *iface, IDWriteFontFile * co
return *obj ? S_OK : S_FALSE;
}
-struct fontfacecached *factory_cache_fontface(IDWriteFactory5 *iface, struct list *fontfaces,
+struct fontfacecached *factory_cache_fontface(IDWriteFactory7 *iface, struct list *fontfaces,
IDWriteFontFace5 *fontface)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
struct fontfacecached *cached;
/* new cache entry */
@@ -1006,7 +1006,7 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory7 *iface, DWRIT
if (hr != S_FALSE)
goto failed;
- desc.factory = (IDWriteFactory5 *)iface;
+ desc.factory = iface;
desc.face_type = req_facetype;
desc.files = font_files;
desc.stream = stream;
--
2.24.0
Dec. 5, 2019
[PATCH 2/9] dwrite: Respond to IDWriteFontFace5 queries.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/font.c | 7 ++++---
dlls/dwrite/tests/font.c | 17 ++++++++++-------
2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 8788181303..bfe32d5fd9 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -474,7 +474,8 @@ static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace5 *iface, REF
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
- if (IsEqualIID(riid, &IID_IDWriteFontFace4) ||
+ if (IsEqualIID(riid, &IID_IDWriteFontFace5) ||
+ IsEqualIID(riid, &IID_IDWriteFontFace4) ||
IsEqualIID(riid, &IID_IDWriteFontFace3) ||
IsEqualIID(riid, &IID_IDWriteFontFace2) ||
IsEqualIID(riid, &IID_IDWriteFontFace1) ||
@@ -1425,7 +1426,7 @@ static HRESULT WINAPI dwritefontface5_GetFontAxisValues(IDWriteFontFace5 *iface,
return E_NOTIMPL;
}
-static BOOL WINAPI dwritefontface5_HasVariantions(IDWriteFontFace5 *iface)
+static BOOL WINAPI dwritefontface5_HasVariations(IDWriteFontFace5 *iface)
{
FIXME("%p: stub\n", iface);
@@ -1496,7 +1497,7 @@ static const IDWriteFontFace5Vtbl dwritefontfacevtbl =
dwritefontface4_ReleaseGlyphImageData,
dwritefontface5_GetFontAxisValueCount,
dwritefontface5_GetFontAxisValues,
- dwritefontface5_HasVariantions,
+ dwritefontface5_HasVariations,
dwritefontface5_GetFontResource,
};
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index f0266cb751..d06b2f555a 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -9291,25 +9291,28 @@ if (SUCCEEDED(hr))
IDWriteFontFaceReference1_Release(reference);
}
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace5, (void **)&fontface5);
-todo_wine
ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
- if (FAILED(hr))
- return;
-
hr = IDWriteFontFace5_GetFontResource(fontface5, &resource2);
+todo_wine
ok(hr == S_OK, "Failed to get font resource, hr %#x.\n", hr);
+
+if (SUCCEEDED(hr))
+{
ok(resource != resource2, "Unexpected resource instance.\n");
IDWriteFontResource_Release(resource);
-
+}
hr = IDWriteFontFace5_GetFontResource(fontface5, &resource);
+todo_wine
ok(hr == S_OK, "Failed to get font resource, hr %#x.\n", hr);
+
+if (SUCCEEDED(hr))
+{
ok(resource != resource2, "Unexpected resource instance.\n");
EXPECT_REF(resource, 1);
-
IDWriteFontResource_Release(resource);
IDWriteFontResource_Release(resource2);
-
+}
IDWriteFontFace5_Release(fontface5);
IDWriteFontResource_Release(resource);
--
2.24.0
Dec. 5, 2019
[PATCH 1/9] dwrite: Add partial implementation for IDWriteFontResource.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 2 +
dlls/dwrite/font.c | 217 +++++++++++++++++++++++++++++++++++
dlls/dwrite/main.c | 4 +-
dlls/dwrite/tests/font.c | 22 ++--
4 files changed, 233 insertions(+), 12 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 7898403dd9..a5d946c385 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -279,6 +279,8 @@ extern void fontface_detach_from_cache(IDWriteFontFace5 *fontface) DECLSPEC_HIDD
extern void factory_lock(IDWriteFactory5*) DECLSPEC_HIDDEN;
extern void factory_unlock(IDWriteFactory5*) DECLSPEC_HIDDEN;
extern HRESULT create_inmemory_fileloader(IDWriteFontFileLoader**) DECLSPEC_HIDDEN;
+extern HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index,
+ IDWriteFontResource **resource) DECLSPEC_HIDDEN;
struct dwrite_fontface;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 1bf88d6b17..8788181303 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -234,6 +234,16 @@ struct dwrite_fontfacereference
IDWriteFactory5 *factory;
};
+struct dwrite_fontresource
+{
+ IDWriteFontResource IDWriteFontResource_iface;
+ LONG refcount;
+
+ IDWriteFontFile *file;
+ UINT32 face_index;
+ IDWriteFactory7 *factory;
+};
+
static void dwrite_grab_font_table(void *context, UINT32 table, const BYTE **data, UINT32 *size, void **data_context)
{
struct dwrite_fontface *fontface = context;
@@ -325,6 +335,11 @@ static inline struct dwrite_fontfacereference *impl_from_IDWriteFontFaceReferenc
return CONTAINING_RECORD(iface, struct dwrite_fontfacereference, IDWriteFontFaceReference1_iface);
}
+static struct dwrite_fontresource *impl_from_IDWriteFontResource(IDWriteFontResource *iface)
+{
+ return CONTAINING_RECORD(iface, struct dwrite_fontresource, IDWriteFontResource_iface);
+}
+
static HRESULT get_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *metrics)
{
static const DWRITE_GLYPH_METRICS nil;
@@ -6555,3 +6570,205 @@ HRESULT create_inmemory_fileloader(IDWriteFontFileLoader **ret)
return S_OK;
}
+
+static HRESULT WINAPI dwritefontresource_QueryInterface(IDWriteFontResource *iface, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+ if (IsEqualIID(riid, &IID_IDWriteFontResource) ||
+ IsEqualIID(riid, &IID_IUnknown))
+ {
+ *obj = iface;
+ IDWriteFontResource_AddRef(iface);
+ return S_OK;
+ }
+
+ WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI dwritefontresource_AddRef(IDWriteFontResource *iface)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+ ULONG refcount = InterlockedIncrement(&resource->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI dwritefontresource_Release(IDWriteFontResource *iface)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+ ULONG refcount = InterlockedDecrement(&resource->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDWriteFactory7_Release(resource->factory);
+ IDWriteFontFile_Release(resource->file);
+ heap_free(resource);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI dwritefontresource_GetFontFile(IDWriteFontResource *iface, IDWriteFontFile **fontfile)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+
+ TRACE("%p, %p.\n", iface, fontfile);
+
+ *fontfile = resource->file;
+ IDWriteFontFile_AddRef(*fontfile);
+
+ return S_OK;
+}
+
+static UINT32 WINAPI dwritefontresource_GetFontFaceIndex(IDWriteFontResource *iface)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+
+ TRACE("%p.\n", iface);
+
+ return resource->face_index;
+}
+
+static UINT32 WINAPI dwritefontresource_GetFontAxisCount(IDWriteFontResource *iface)
+{
+ FIXME("%p.\n", iface);
+
+ return 0;
+}
+
+static HRESULT WINAPI dwritefontresource_GetDefaultFontAxisValues(IDWriteFontResource *iface,
+ DWRITE_FONT_AXIS_VALUE const *values, UINT32 num_values)
+{
+ FIXME("%p, %p, %u.\n", iface, values, num_values);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI dwritefontresource_GetFontAxisRanges(IDWriteFontResource *iface,
+ DWRITE_FONT_AXIS_RANGE const *ranges, UINT32 num_ranges)
+{
+ FIXME("%p, %p, %u.\n", iface, ranges, num_ranges);
+
+ return E_NOTIMPL;
+}
+
+static DWRITE_FONT_AXIS_ATTRIBUTES WINAPI dwritefontresource_GetFontAxisAttributes(IDWriteFontResource *iface,
+ UINT32 axis)
+{
+ FIXME("%p, %u.\n", iface, axis);
+
+ return DWRITE_FONT_AXIS_ATTRIBUTES_NONE;
+}
+
+static HRESULT WINAPI dwritefontresource_GetAxisNames(IDWriteFontResource *iface, UINT32 axis,
+ IDWriteLocalizedStrings **names)
+{
+ FIXME("%p, %u, %p.\n", iface, axis, names);
+
+ return E_NOTIMPL;
+}
+
+static UINT32 WINAPI dwritefontresource_GetAxisValueNameCount(IDWriteFontResource *iface, UINT32 axis)
+{
+ FIXME("%p, %u.\n", iface, axis);
+
+ return 0;
+}
+
+static HRESULT WINAPI dwritefontresource_GetAxisValueNames(IDWriteFontResource *iface, UINT32 axis,
+ UINT32 axis_value, DWRITE_FONT_AXIS_RANGE *axis_range, IDWriteLocalizedStrings **names)
+{
+ FIXME("%p, %u, %u, %p, %p.\n", iface, axis, axis_value, axis_range, names);
+
+ return E_NOTIMPL;
+}
+
+static BOOL WINAPI dwritefontresource_HasVariations(IDWriteFontResource *iface)
+{
+ FIXME("%p.\n", iface);
+
+ return FALSE;
+}
+
+static HRESULT WINAPI dwritefontresource_CreateFontFace(IDWriteFontResource *iface,
+ DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 num_values,
+ IDWriteFontFace5 **fontface)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+ IDWriteFontFaceReference1 *reference;
+ HRESULT hr;
+
+ TRACE("%p, %#x, %p, %u, %p.\n", iface, simulations, axis_values, num_values, fontface);
+
+ hr = IDWriteFactory7_CreateFontFaceReference(resource->factory, resource->file, resource->face_index,
+ simulations, axis_values, num_values, &reference);
+ if (SUCCEEDED(hr))
+ {
+ hr = IDWriteFontFaceReference1_CreateFontFace(reference, fontface);
+ IDWriteFontFaceReference1_Release(reference);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI dwritefontresource_CreateFontFaceReference(IDWriteFontResource *iface,
+ DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 num_values,
+ IDWriteFontFaceReference1 **reference)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+
+ TRACE("%p, %#x, %p, %u, %p.\n", iface, simulations, axis_values, num_values, reference);
+
+ return IDWriteFactory7_CreateFontFaceReference(resource->factory, resource->file, resource->face_index,
+ simulations, axis_values, num_values, reference);
+}
+
+static const IDWriteFontResourceVtbl fontresourcevtbl =
+{
+ dwritefontresource_QueryInterface,
+ dwritefontresource_AddRef,
+ dwritefontresource_Release,
+ dwritefontresource_GetFontFile,
+ dwritefontresource_GetFontFaceIndex,
+ dwritefontresource_GetFontAxisCount,
+ dwritefontresource_GetDefaultFontAxisValues,
+ dwritefontresource_GetFontAxisRanges,
+ dwritefontresource_GetFontAxisAttributes,
+ dwritefontresource_GetAxisNames,
+ dwritefontresource_GetAxisValueNameCount,
+ dwritefontresource_GetAxisValueNames,
+ dwritefontresource_HasVariations,
+ dwritefontresource_CreateFontFace,
+ dwritefontresource_CreateFontFaceReference,
+};
+
+HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index,
+ IDWriteFontResource **ret)
+{
+ struct dwrite_fontresource *resource;
+
+ *ret = NULL;
+
+ resource = heap_alloc_zero(sizeof(*resource));
+ if (!resource)
+ return E_OUTOFMEMORY;
+
+ resource->IDWriteFontResource_iface.lpVtbl = &fontresourcevtbl;
+ resource->refcount = 1;
+ resource->face_index = face_index;
+ resource->file = file;
+ IDWriteFontFile_AddRef(resource->file);
+ resource->factory = factory;
+ IDWriteFactory7_AddRef(resource->factory);
+
+ *ret = &resource->IDWriteFontResource_iface;
+
+ return S_OK;
+}
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 033a664dcf..1c1fabdb7d 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -1666,9 +1666,9 @@ static HRESULT WINAPI dwritefactory6_CreateFontFaceReference(IDWriteFactory7 *if
static HRESULT WINAPI dwritefactory6_CreateFontResource(IDWriteFactory7 *iface, IDWriteFontFile *file,
UINT32 face_index, IDWriteFontResource **resource)
{
- FIXME("%p, %p, %u, %p.\n", iface, file, face_index, resource);
+ TRACE("%p, %p, %u, %p.\n", iface, file, face_index, resource);
- return E_NOTIMPL;
+ return create_font_resource(iface, file, face_index, resource);
}
static HRESULT WINAPI dwritefactory6_GetSystemFontSet(IDWriteFactory7 *iface, BOOL include_downloadable,
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 58f2af6e7a..f0266cb751 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -9259,17 +9259,8 @@ static void test_font_resource(void)
ok(hr == S_OK, "Failed to get file object, hr %#x.\n", hr);
hr = IDWriteFactory6_CreateFontResource(factory, fontfile, 0, &resource);
-todo_wine
ok(hr == S_OK, "Failed to create font resource, hr %#x.\n", hr);
- if (FAILED(hr))
- {
- IDWriteFactory6_Release(factory);
- IDWriteFontFile_Release(fontfile);
- IDWriteFontFace_Release(fontface);
- return;
- }
-
hr = IDWriteFactory6_CreateFontResource(factory, fontfile, 0, &resource2);
ok(hr == S_OK, "Failed to create font resource, hr %#x.\n", hr);
ok(resource != resource2, "Unexpected instance.\n");
@@ -9283,18 +9274,29 @@ todo_wine
index = IDWriteFontResource_GetFontFaceIndex(resource);
ok(!index, "Unexpected index %u.\n", index);
+ EXPECT_REF(resource, 1);
hr = IDWriteFontResource_CreateFontFaceReference(resource, DWRITE_FONT_SIMULATIONS_NONE, NULL, 0, &reference);
+todo_wine
ok(hr == S_OK, "Failed to create reference object, hr %#x.\n", hr);
+ EXPECT_REF(resource, 1);
hr = IDWriteFontResource_CreateFontFaceReference(resource, DWRITE_FONT_SIMULATIONS_NONE, NULL, 0, &reference2);
+todo_wine
ok(hr == S_OK, "Failed to create reference object, hr %#x.\n", hr);
+
+if (SUCCEEDED(hr))
+{
ok(reference != reference2, "Unexpected reference instance.\n");
IDWriteFontFaceReference1_Release(reference2);
IDWriteFontFaceReference1_Release(reference);
-
+}
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace5, (void **)&fontface5);
+todo_wine
ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
+ if (FAILED(hr))
+ return;
+
hr = IDWriteFontFace5_GetFontResource(fontface5, &resource2);
ok(hr == S_OK, "Failed to get font resource, hr %#x.\n", hr);
ok(resource != resource2, "Unexpected resource instance.\n");
--
2.24.0
Dec. 5, 2019
mscoree: fix an error in string access
by Rafał Mużyło
mscoree: fix an error in string access
If parsed_config.private_path is an empty string, wine is doing a Bad
Thing. It shouldn't.
Signed-off-by: Rafał Mużyło <galtgendo(a)o2.pl>
Dec. 5, 2019
[PATCH 4/4] strmbase: Get rid of the "vtbl" parameter to strmbase_filter_init().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/audiorecord.c | 20 +-----------
dlls/qcap/avico.c | 20 +-----------
dlls/qcap/avimux.c | 20 +-----------
dlls/qcap/smartteefilter.c | 20 +-----------
dlls/qcap/vfwcapture.c | 21 +-----------
dlls/qedit/samplegrabber.c | 21 +-----------
dlls/quartz/dsoundrender.c | 12 +++----
dlls/quartz/filesource.c | 21 +-----------
dlls/quartz/tests/videorenderer.c | 21 +-----------
dlls/quartz/tests/vmr7.c | 21 +-----------
dlls/quartz/tests/vmr9.c | 21 +-----------
dlls/strmbase/filter.c | 53 +++++++++++++++++++++----------
dlls/strmbase/renderer.c | 21 +-----------
dlls/strmbase/transform.c | 22 +------------
dlls/winegstreamer/gstdemux.c | 27 +++-------------
dlls/wineqtdecoder/qtsplitter.c | 20 +-----------
include/wine/strmbase.h | 18 +----------
17 files changed, 60 insertions(+), 319 deletions(-)
diff --git a/dlls/qcap/audiorecord.c b/dlls/qcap/audiorecord.c
index 0262bc5bd8f..3c15734e894 100644
--- a/dlls/qcap/audiorecord.c
+++ b/dlls/qcap/audiorecord.c
@@ -49,24 +49,6 @@ static inline AudioRecord *impl_from_IPersistPropertyBag(IPersistPropertyBag *if
return CONTAINING_RECORD(iface, AudioRecord, IPersistPropertyBag_iface);
}
-static const IBaseFilterVtbl AudioRecordVtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static struct strmbase_pin *audio_record_get_pin(struct strmbase_filter *iface, unsigned int index)
{
FIXME("iface %p, index %u, stub!\n", iface, index);
@@ -186,7 +168,7 @@ IUnknown* WINAPI QCAP_createAudioCaptureFilter(IUnknown *outer, HRESULT *phr)
memset(This, 0, sizeof(*This));
This->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
- strmbase_filter_init(&This->filter, &AudioRecordVtbl, outer, &CLSID_AudioRecord, &filter_ops);
+ strmbase_filter_init(&This->filter, outer, &CLSID_AudioRecord, &filter_ops);
*phr = S_OK;
return &This->filter.IUnknown_inner;
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c
index f65f33fe442..9365c437b4f 100644
--- a/dlls/qcap/avico.c
+++ b/dlls/qcap/avico.c
@@ -111,24 +111,6 @@ static HRESULT fill_format_info(AVICompressor *This, VIDEOINFOHEADER *src_videoi
return S_OK;
}
-static const IBaseFilterVtbl AVICompressorVtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo,
-};
-
static struct strmbase_pin *avi_compressor_get_pin(struct strmbase_filter *iface, unsigned int index)
{
AVICompressor *filter = impl_from_strmbase_filter(iface);
@@ -576,7 +558,7 @@ IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&compressor->filter, &AVICompressorVtbl, outer, &CLSID_AVICo, &filter_ops);
+ strmbase_filter_init(&compressor->filter, outer, &CLSID_AVICo, &filter_ops);
compressor->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index a7a9ac7ceda..dc28104c80a 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -672,24 +672,6 @@ static const struct strmbase_filter_ops filter_ops =
.filter_cleanup_stream = avi_mux_cleanup_stream,
};
-static const IBaseFilterVtbl AviMuxVtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static inline AviMux* impl_from_IConfigAviMux(IConfigAviMux *iface)
{
return CONTAINING_RECORD(iface, AviMux, IConfigAviMux_iface);
@@ -1964,7 +1946,7 @@ IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&avimux->filter, &AviMuxVtbl, outer, &CLSID_AviDest, &filter_ops);
+ strmbase_filter_init(&avimux->filter, outer, &CLSID_AviDest, &filter_ops);
avimux->IConfigAviMux_iface.lpVtbl = &ConfigAviMuxVtbl;
avimux->IConfigInterleaving_iface.lpVtbl = &ConfigInterleavingVtbl;
avimux->IMediaSeeking_iface.lpVtbl = &MediaSeekingVtbl;
diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c
index f63a43de50c..7762ec1e500 100644
--- a/dlls/qcap/smartteefilter.c
+++ b/dlls/qcap/smartteefilter.c
@@ -51,24 +51,6 @@ static inline SmartTeeFilter *impl_from_strmbase_pin(struct strmbase_pin *pin)
return impl_from_strmbase_filter(pin->filter);
}
-static const IBaseFilterVtbl SmartTeeFilterVtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static struct strmbase_pin *smart_tee_get_pin(struct strmbase_filter *iface, unsigned int index)
{
SmartTeeFilter *filter = impl_from_strmbase_filter(iface);
@@ -417,7 +399,7 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
}
memset(object, 0, sizeof(*object));
- strmbase_filter_init(&object->filter, &SmartTeeFilterVtbl, outer, &CLSID_SmartTee, &filter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_SmartTee, &filter_ops);
strmbase_sink_init(&object->sink, &SmartTeeFilterInputVtbl, &object->filter, inputW, &sink_ops, NULL);
hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
&IID_IMemAllocator, (void **)&object->sink.pAllocator);
diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c
index 0f8beb0f495..e7522ea9b36 100644
--- a/dlls/qcap/vfwcapture.c
+++ b/dlls/qcap/vfwcapture.c
@@ -167,25 +167,6 @@ static const struct strmbase_filter_ops filter_ops =
.filter_cleanup_stream = vfw_capture_cleanup_stream,
};
-static const IBaseFilterVtbl VfwCapture_Vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
/* AMStreamConfig interface, we only need to implement {G,S}etFormat */
static HRESULT WINAPI AMStreamConfig_QueryInterface(IAMStreamConfig *iface, REFIID iid, void **out)
{
@@ -611,7 +592,7 @@ IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&object->filter, &VfwCapture_Vtbl, outer, &CLSID_VfwCapture, &filter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_VfwCapture, &filter_ops);
object->IAMStreamConfig_iface.lpVtbl = &IAMStreamConfig_VTable;
object->IAMVideoProcAmp_iface.lpVtbl = &IAMVideoProcAmp_VTable;
diff --git a/dlls/qedit/samplegrabber.c b/dlls/qedit/samplegrabber.c
index af05966c140..019af5c35de 100644
--- a/dlls/qedit/samplegrabber.c
+++ b/dlls/qedit/samplegrabber.c
@@ -489,25 +489,6 @@ SampleGrabber_In_IPin_ReceiveConnection(IPin *iface, IPin *connector, const AM_M
return S_OK;
}
-static const IBaseFilterVtbl IBaseFilter_VTable =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo,
-};
-
static const ISampleGrabberVtbl ISampleGrabber_VTable =
{
SampleGrabber_ISampleGrabber_QueryInterface,
@@ -714,7 +695,7 @@ HRESULT SampleGrabber_create(IUnknown *outer, void **out)
}
ZeroMemory(obj, sizeof(SG_Impl));
- strmbase_filter_init(&obj->filter, &IBaseFilter_VTable, outer, &CLSID_SampleGrabber, &filter_ops);
+ strmbase_filter_init(&obj->filter, outer, &CLSID_SampleGrabber, &filter_ops);
obj->ISampleGrabber_iface.lpVtbl = &ISampleGrabber_VTable;
obj->IMemInputPin_iface.lpVtbl = &IMemInputPin_VTable;
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c
index a2c7ca94a62..cad210a8762 100644
--- a/dlls/quartz/dsoundrender.c
+++ b/dlls/quartz/dsoundrender.c
@@ -555,7 +555,7 @@ static HRESULT WINAPI Basicaudio_QueryInterface(IBasicAudio *iface,
TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj);
- return BaseFilterImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
+ return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppvObj);
}
static ULONG WINAPI Basicaudio_AddRef(IBasicAudio *iface) {
@@ -563,7 +563,7 @@ static ULONG WINAPI Basicaudio_AddRef(IBasicAudio *iface) {
TRACE("(%p/%p)->()\n", This, iface);
- return BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
+ return IUnknown_AddRef(This->renderer.filter.outer_unk);
}
static ULONG WINAPI Basicaudio_Release(IBasicAudio *iface) {
@@ -571,7 +571,7 @@ static ULONG WINAPI Basicaudio_Release(IBasicAudio *iface) {
TRACE("(%p/%p)->()\n", This, iface);
- return BaseFilterImpl_Release(&This->renderer.filter.IBaseFilter_iface);
+ return IUnknown_Release(This->renderer.filter.outer_unk);
}
HRESULT WINAPI basic_audio_GetTypeInfoCount(IBasicAudio *iface, UINT *count)
@@ -708,7 +708,7 @@ static HRESULT WINAPI AMDirectSound_QueryInterface(IAMDirectSound *iface,
TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj);
- return BaseFilterImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
+ return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppvObj);
}
static ULONG WINAPI AMDirectSound_AddRef(IAMDirectSound *iface)
@@ -717,7 +717,7 @@ static ULONG WINAPI AMDirectSound_AddRef(IAMDirectSound *iface)
TRACE("(%p/%p)->()\n", This, iface);
- return BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
+ return IUnknown_AddRef(This->renderer.filter.outer_unk);
}
static ULONG WINAPI AMDirectSound_Release(IAMDirectSound *iface)
@@ -726,7 +726,7 @@ static ULONG WINAPI AMDirectSound_Release(IAMDirectSound *iface)
TRACE("(%p/%p)->()\n", This, iface);
- return BaseFilterImpl_Release(&This->renderer.filter.IBaseFilter_iface);
+ return IUnknown_Release(This->renderer.filter.outer_unk);
}
/*** IAMDirectSound methods ***/
diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c
index 1c17980f58c..e0d45730aec 100644
--- a/dlls/quartz/filesource.c
+++ b/dlls/quartz/filesource.c
@@ -412,7 +412,7 @@ HRESULT AsyncReader_create(IUnknown *outer, void **out)
if (!pAsyncRead)
return E_OUTOFMEMORY;
- strmbase_filter_init(&pAsyncRead->filter, &AsyncReader_Vtbl, outer, &CLSID_AsyncReader, &filter_ops);
+ strmbase_filter_init(&pAsyncRead->filter, outer, &CLSID_AsyncReader, &filter_ops);
pAsyncRead->IFileSourceFilter_iface.lpVtbl = &FileSource_Vtbl;
@@ -428,25 +428,6 @@ HRESULT AsyncReader_create(IUnknown *outer, void **out)
return S_OK;
}
-static const IBaseFilterVtbl AsyncReader_Vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static HRESULT WINAPI FileSource_QueryInterface(IFileSourceFilter * iface, REFIID riid, LPVOID * ppv)
{
AsyncReader *This = impl_from_IFileSourceFilter(iface);
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index d3810598682..6f9e47b9dc4 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -495,25 +495,6 @@ struct testfilter
struct strmbase_source source;
};
-static const IBaseFilterVtbl testfilter_vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo,
-};
-
static inline struct testfilter *impl_from_BaseFilter(struct strmbase_filter *iface)
{
return CONTAINING_RECORD(iface, struct testfilter, filter);
@@ -597,7 +578,7 @@ static const struct strmbase_source_ops testsource_ops =
static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
- strmbase_filter_init(&filter->filter, &testfilter_vtbl, NULL, &clsid, &testfilter_ops);
+ strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
}
diff --git a/dlls/quartz/tests/vmr7.c b/dlls/quartz/tests/vmr7.c
index 01d9ad10fa4..b8fd3f53cef 100644
--- a/dlls/quartz/tests/vmr7.c
+++ b/dlls/quartz/tests/vmr7.c
@@ -855,25 +855,6 @@ struct testfilter
struct strmbase_source source;
};
-static const IBaseFilterVtbl testfilter_vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo,
-};
-
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
{
return CONTAINING_RECORD(iface, struct testfilter, filter);
@@ -957,7 +938,7 @@ static const struct strmbase_source_ops testsource_ops =
static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
- strmbase_filter_init(&filter->filter, &testfilter_vtbl, NULL, &clsid, &testfilter_ops);
+ strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
}
diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c
index 9379fa11e48..18971495753 100644
--- a/dlls/quartz/tests/vmr9.c
+++ b/dlls/quartz/tests/vmr9.c
@@ -859,25 +859,6 @@ struct testfilter
struct strmbase_source source;
};
-static const IBaseFilterVtbl testfilter_vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo,
-};
-
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
{
return CONTAINING_RECORD(iface, struct testfilter, filter);
@@ -961,7 +942,7 @@ static const struct strmbase_source_ops testsource_ops =
static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
- strmbase_filter_init(&filter->filter, &testfilter_vtbl, NULL, &clsid, &testfilter_ops);
+ strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
}
diff --git a/dlls/strmbase/filter.c b/dlls/strmbase/filter.c
index f90f760a49e..53307884c4d 100644
--- a/dlls/strmbase/filter.c
+++ b/dlls/strmbase/filter.c
@@ -271,25 +271,25 @@ static inline struct strmbase_filter *impl_from_IBaseFilter(IBaseFilter *iface)
return CONTAINING_RECORD(iface, struct strmbase_filter, IBaseFilter_iface);
}
-HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter *iface, REFIID iid, void **out)
+static HRESULT WINAPI filter_QueryInterface(IBaseFilter *iface, REFIID iid, void **out)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
return IUnknown_QueryInterface(filter->outer_unk, iid, out);
}
-ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter *iface)
+static ULONG WINAPI filter_AddRef(IBaseFilter *iface)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
return IUnknown_AddRef(filter->outer_unk);
}
-ULONG WINAPI BaseFilterImpl_Release(IBaseFilter *iface)
+static ULONG WINAPI filter_Release(IBaseFilter *iface)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
return IUnknown_Release(filter->outer_unk);
}
-HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid)
+static HRESULT WINAPI filter_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
TRACE("(%p)->(%p)\n", This, pClsid);
@@ -299,7 +299,7 @@ HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid)
return S_OK;
}
-HRESULT WINAPI BaseFilterImpl_Stop(IBaseFilter *iface)
+static HRESULT WINAPI filter_Stop(IBaseFilter *iface)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
HRESULT hr = S_OK;
@@ -320,7 +320,7 @@ HRESULT WINAPI BaseFilterImpl_Stop(IBaseFilter *iface)
return hr;
}
-HRESULT WINAPI BaseFilterImpl_Pause(IBaseFilter *iface)
+static HRESULT WINAPI filter_Pause(IBaseFilter *iface)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
HRESULT hr = S_OK;
@@ -341,7 +341,7 @@ HRESULT WINAPI BaseFilterImpl_Pause(IBaseFilter *iface)
return hr;
}
-HRESULT WINAPI BaseFilterImpl_Run(IBaseFilter *iface, REFERENCE_TIME start)
+static HRESULT WINAPI filter_Run(IBaseFilter *iface, REFERENCE_TIME start)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
HRESULT hr = S_OK;
@@ -362,7 +362,7 @@ HRESULT WINAPI BaseFilterImpl_Run(IBaseFilter *iface, REFERENCE_TIME start)
return hr;
}
-HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter *iface, DWORD timeout, FILTER_STATE *state)
+static HRESULT WINAPI filter_GetState(IBaseFilter *iface, DWORD timeout, FILTER_STATE *state)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
HRESULT hr = S_OK;
@@ -380,7 +380,7 @@ HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter *iface, DWORD timeout, FILTER
return hr;
}
-HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
+static HRESULT WINAPI filter_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
TRACE("(%p)->(%p)\n", This, pClock);
@@ -398,7 +398,7 @@ HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock
return S_OK;
}
-HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
+static HRESULT WINAPI filter_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
TRACE("(%p)->(%p)\n", This, ppClock);
@@ -414,7 +414,7 @@ HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock
return S_OK;
}
-HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter *iface, IEnumPins **enum_pins)
+static HRESULT WINAPI filter_EnumPins(IBaseFilter *iface, IEnumPins **enum_pins)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
@@ -423,7 +423,7 @@ HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter *iface, IEnumPins **enum_pins
return enum_pins_create(filter, enum_pins);
}
-HRESULT WINAPI BaseFilterImpl_FindPin(IBaseFilter *iface, const WCHAR *id, IPin **ret)
+static HRESULT WINAPI filter_FindPin(IBaseFilter *iface, const WCHAR *id, IPin **ret)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
struct strmbase_pin *pin;
@@ -443,7 +443,7 @@ HRESULT WINAPI BaseFilterImpl_FindPin(IBaseFilter *iface, const WCHAR *id, IPin
return VFW_E_NOT_FOUND;
}
-HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
+static HRESULT WINAPI filter_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
TRACE("(%p)->(%p)\n", This, pInfo);
@@ -457,7 +457,7 @@ HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *
return S_OK;
}
-HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName )
+static HRESULT WINAPI filter_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, const WCHAR *pName)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
@@ -476,23 +476,42 @@ HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph
return S_OK;
}
-HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
+static HRESULT WINAPI filter_QueryVendorInfo(IBaseFilter *iface, WCHAR **pVendorInfo)
{
TRACE("(%p)->(%p)\n", iface, pVendorInfo);
return E_NOTIMPL;
}
+static const IBaseFilterVtbl filter_vtbl =
+{
+ filter_QueryInterface,
+ filter_AddRef,
+ filter_Release,
+ filter_GetClassID,
+ filter_Stop,
+ filter_Pause,
+ filter_Run,
+ filter_GetState,
+ filter_SetSyncSource,
+ filter_GetSyncSource,
+ filter_EnumPins,
+ filter_FindPin,
+ filter_QueryFilterInfo,
+ filter_JoinFilterGraph,
+ filter_QueryVendorInfo,
+};
+
VOID WINAPI BaseFilterImpl_IncrementPinVersion(struct strmbase_filter *filter)
{
InterlockedIncrement(&filter->pin_version);
}
-void strmbase_filter_init(struct strmbase_filter *filter, const IBaseFilterVtbl *vtbl, IUnknown *outer,
+void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer,
const CLSID *clsid, const struct strmbase_filter_ops *ops)
{
memset(filter, 0, sizeof(*filter));
- filter->IBaseFilter_iface.lpVtbl = vtbl;
+ filter->IBaseFilter_iface.lpVtbl = &filter_vtbl;
filter->IUnknown_inner.lpVtbl = &filter_inner_vtbl;
filter->outer_unk = outer ? outer : &filter->IUnknown_inner;
filter->refcount = 1;
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index cacbb90e591..d592ab034e6 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -448,25 +448,6 @@ HRESULT WINAPI BaseRendererImpl_Receive(struct strmbase_renderer *This, IMediaSa
return hr;
}
-static const IBaseFilterVtbl strmbase_renderer_vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
HRESULT WINAPI BaseRendererImpl_ClearPendingSample(struct strmbase_renderer *iface)
{
if (iface->pMediaSample)
@@ -483,7 +464,7 @@ HRESULT WINAPI strmbase_renderer_init(struct strmbase_renderer *filter, IUnknown
HRESULT hr;
memset(filter, 0, sizeof(*filter));
- strmbase_filter_init(&filter->filter, &strmbase_renderer_vtbl, outer, clsid, &filter_ops);
+ strmbase_filter_init(&filter->filter, outer, clsid, &filter_ops);
filter->pFuncsTable = ops;
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 9e2582a0dbf..5c079d38e76 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -246,26 +246,6 @@ static const struct strmbase_source_ops source_ops =
.pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
};
-
-static const IBaseFilterVtbl transform_vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static TransformFilter *impl_from_source_IQualityControl(IQualityControl *iface)
{
return CONTAINING_RECORD(iface, TransformFilter, source_IQualityControl_iface);
@@ -346,7 +326,7 @@ static HRESULT strmbase_transform_init(IUnknown *outer, const CLSID *clsid,
ISeekingPassThru *passthru;
HRESULT hr;
- strmbase_filter_init(&filter->filter, &transform_vtbl, outer, clsid, &filter_ops);
+ strmbase_filter_init(&filter->filter, outer, clsid, &filter_ops);
InitializeCriticalSection(&filter->csReceive);
filter->csReceive.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": TransformFilter.csReceive");
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index e024d271974..78c8e38701a 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -99,7 +99,6 @@ static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
static const IMediaSeekingVtbl GST_Seeking_Vtbl;
static const IPinVtbl GST_OutputPin_Vtbl;
static const IPinVtbl GST_InputPin_Vtbl;
-static const IBaseFilterVtbl GST_Vtbl;
static const IQualityControlVtbl GSTOutPin_QualityControl_Vtbl;
static struct gstdemux_source *create_pin(struct gstdemux *filter, const WCHAR *name);
@@ -1438,7 +1437,7 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&object->filter, &GST_Vtbl, outer, &CLSID_Gstreamer_Splitter, &filter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_Gstreamer_Splitter, &filter_ops);
object->no_more_pads_event = CreateEventW(NULL, FALSE, FALSE, NULL);
object->sink.dir = PINDIR_INPUT;
@@ -1453,24 +1452,6 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
return &object->filter.IUnknown_inner;
}
-static const IBaseFilterVtbl GST_Vtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static struct gstdemux *impl_from_IAMStreamSelect(IAMStreamSelect *iface)
{
return CONTAINING_RECORD(iface, struct gstdemux, IAMStreamSelect_iface);
@@ -2383,7 +2364,7 @@ IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&object->filter, &GST_Vtbl, outer, &CLSID_WAVEParser, &filter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_WAVEParser, &filter_ops);
object->sink.dir = PINDIR_INPUT;
object->sink.filter = &object->filter;
@@ -2489,7 +2470,7 @@ IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&object->filter, &GST_Vtbl, outer, &CLSID_AviSplitter, &filter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_AviSplitter, &filter_ops);
object->no_more_pads_event = CreateEventW(NULL, FALSE, FALSE, NULL);
object->sink.dir = PINDIR_INPUT;
@@ -2627,7 +2608,7 @@ IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&object->filter, &GST_Vtbl, outer, &CLSID_MPEG1Splitter, &mpeg_splitter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_MPEG1Splitter, &mpeg_splitter_ops);
object->IAMStreamSelect_iface.lpVtbl = &stream_select_vtbl;
object->duration_event = CreateEventW(NULL, FALSE, FALSE, NULL);
diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index 28ea36785a8..5b1e82ebc9b 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -357,7 +357,7 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *outer, HRESULT *phr)
}
ZeroMemory(This,sizeof(*This));
- strmbase_filter_init(&This->filter, &QT_Vtbl, outer, &CLSID_QTSplitter, &filter_ops);
+ strmbase_filter_init(&This->filter, outer, &CLSID_QTSplitter, &filter_ops);
InitializeCriticalSection(&This->csReceive);
This->csReceive.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": QTSplitter.csReceive");
@@ -721,24 +721,6 @@ audio_error:
return hr;
}
-static const IBaseFilterVtbl QT_Vtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static void free_source_pin(QTOutPin *pin)
{
if (pin->pin.pin.peer)
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 7949e6670a5..75eac504209 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -176,25 +176,9 @@ struct strmbase_filter_ops
HRESULT (*filter_wait_state)(struct strmbase_filter *iface, DWORD timeout);
};
-HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv);
-ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter * iface);
-ULONG WINAPI BaseFilterImpl_Release(IBaseFilter * iface);
-HRESULT WINAPI BaseFilterImpl_Stop(IBaseFilter *iface);
-HRESULT WINAPI BaseFilterImpl_Pause(IBaseFilter *iface);
-HRESULT WINAPI BaseFilterImpl_Run(IBaseFilter *iface, REFERENCE_TIME start);
-HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid);
-HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState );
-HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock);
-HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock);
-HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum);
-HRESULT WINAPI BaseFilterImpl_FindPin(IBaseFilter *iface, const WCHAR *id, IPin **pin);
-HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo);
-HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName );
-HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo);
-
VOID WINAPI BaseFilterImpl_IncrementPinVersion(struct strmbase_filter *filter);
-void strmbase_filter_init(struct strmbase_filter *filter, const IBaseFilterVtbl *vtbl, IUnknown *outer,
+void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer,
const CLSID *clsid, const struct strmbase_filter_ops *func_table);
void strmbase_filter_cleanup(struct strmbase_filter *filter);
--
2.23.0
Dec. 5, 2019
[PATCH 3/4] qcap: Rework v4l2 state change logic.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/capture.h | 7 +-
dlls/qcap/v4l.c | 166 +++++++++++++----------------------------
dlls/qcap/vfwcapture.c | 60 ++++++++-------
3 files changed, 89 insertions(+), 144 deletions(-)
diff --git a/dlls/qcap/capture.h b/dlls/qcap/capture.h
index 6433f37d88f..7d2be332488 100644
--- a/dlls/qcap/capture.h
+++ b/dlls/qcap/capture.h
@@ -31,8 +31,9 @@ HRESULT qcap_driver_get_format(const Capture *, AM_MEDIA_TYPE *) DECLSPEC_HIDDEN
HRESULT qcap_driver_get_prop_range(Capture*,VideoProcAmpProperty,LONG*,LONG*,LONG*,LONG*,LONG*) DECLSPEC_HIDDEN;
HRESULT qcap_driver_get_prop(Capture*,VideoProcAmpProperty,LONG*,LONG*) DECLSPEC_HIDDEN;
HRESULT qcap_driver_set_prop(Capture*,VideoProcAmpProperty,LONG,LONG) DECLSPEC_HIDDEN;
-HRESULT qcap_driver_run(Capture*,FILTER_STATE*) DECLSPEC_HIDDEN;
-HRESULT qcap_driver_pause(Capture*,FILTER_STATE*) DECLSPEC_HIDDEN;
-HRESULT qcap_driver_stop(Capture*,FILTER_STATE*) DECLSPEC_HIDDEN;
+void qcap_driver_init_stream(Capture *device) DECLSPEC_HIDDEN;
+void qcap_driver_start_stream(Capture *device) DECLSPEC_HIDDEN;
+void qcap_driver_stop_stream(Capture *device) DECLSPEC_HIDDEN;
+void qcap_driver_cleanup_stream(Capture *device) DECLSPEC_HIDDEN;
#endif /* __QCAP_CAPTURE_H__ */
diff --git a/dlls/qcap/v4l.c b/dlls/qcap/v4l.c
index a203e91e52b..75121fd8518 100644
--- a/dlls/qcap/v4l.c
+++ b/dlls/qcap/v4l.c
@@ -99,13 +99,11 @@ struct _Capture
UINT width, height, bitDepth, fps, outputwidth, outputheight;
BOOL swresize;
- CRITICAL_SECTION CritSect;
-
struct strmbase_source *pin;
int fd, mmap;
- BOOL iscommitted, stopped;
+ FILTER_STATE state;
- HANDLE thread;
+ HANDLE thread, run_event;
};
static int xioctl(int fd, int request, void * arg)
@@ -125,8 +123,6 @@ HRESULT qcap_driver_destroy(Capture *capBox)
if( capBox->fd != -1 )
video_close(capBox->fd);
- capBox->CritSect.DebugInfo->Spare[0] = 0;
- DeleteCriticalSection(&capBox->CritSect);
CoTaskMemFree(capBox);
return S_OK;
}
@@ -389,16 +385,14 @@ static DWORD WINAPI ReadThread(LPVOID lParam)
if (!(image_data = heap_alloc(image_size)))
{
ERR("Failed to allocate memory.\n");
- capBox->thread = 0;
- capBox->stopped = TRUE;
return 0;
}
- while (1)
+ while (capBox->state != State_Stopped)
{
- EnterCriticalSection(&capBox->CritSect);
- if (capBox->stopped)
- break;
+ if (capBox->state == State_Paused)
+ WaitForSingleObject(capBox->run_event, INFINITE);
+
hr = BaseOutputPinImpl_GetDeliveryBuffer(capBox->pin, &pSample, NULL, NULL, 0);
if (SUCCEEDED(hr))
{
@@ -432,124 +426,66 @@ static DWORD WINAPI ReadThread(LPVOID lParam)
if (FAILED(hr) && hr != VFW_E_NOT_CONNECTED)
{
TRACE("Return %x, stop IFilterGraph\n", hr);
- capBox->thread = 0;
- capBox->stopped = TRUE;
break;
}
- LeaveCriticalSection(&capBox->CritSect);
}
- LeaveCriticalSection(&capBox->CritSect);
heap_free(image_data);
return 0;
}
-HRESULT qcap_driver_run(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_init_stream(Capture *device)
{
- HANDLE thread;
+ ALLOCATOR_PROPERTIES req_props, ret_props;
HRESULT hr;
- TRACE("%p -> (%p)\n", capBox, state);
-
- if (*state == State_Running) return S_OK;
-
- EnterCriticalSection(&capBox->CritSect);
+ req_props.cBuffers = 3;
+ if (!device->swresize)
+ req_props.cbBuffer = device->width * device->height;
+ else
+ req_props.cbBuffer = device->outputwidth * device->outputheight;
+ req_props.cbBuffer = (req_props.cbBuffer * device->bitDepth) / 8;
+ req_props.cbAlign = 1;
+ req_props.cbPrefix = 0;
- capBox->stopped = FALSE;
+ hr = IMemAllocator_SetProperties(device->pin->pAllocator, &req_props, &ret_props);
+ if (FAILED(hr))
+ ERR("Failed to set allocator properties (buffer size %u), hr %#x.\n", req_props.cbBuffer, hr);
- if (*state == State_Stopped && capBox->pin->pin.peer)
+ if (SUCCEEDED(hr))
{
- *state = State_Running;
- if (!capBox->iscommitted)
- {
- ALLOCATOR_PROPERTIES ap, actual;
-
- capBox->iscommitted = TRUE;
-
- ap.cBuffers = 3;
- if (!capBox->swresize)
- ap.cbBuffer = capBox->width * capBox->height;
- else
- ap.cbBuffer = capBox->outputwidth * capBox->outputheight;
- ap.cbBuffer = (ap.cbBuffer * capBox->bitDepth) / 8;
- ap.cbAlign = 1;
- ap.cbPrefix = 0;
-
- hr = IMemAllocator_SetProperties(capBox->pin->pAllocator, &ap, &actual);
-
- if (SUCCEEDED(hr))
- hr = IMemAllocator_Commit(capBox->pin->pAllocator);
-
- TRACE("Committing allocator: %x\n", hr);
- }
-
- thread = CreateThread(NULL, 0, ReadThread, capBox, 0, NULL);
- if (thread)
- {
- capBox->thread = thread;
- SetThreadPriority(thread, THREAD_PRIORITY_LOWEST);
- LeaveCriticalSection(&capBox->CritSect);
- return S_OK;
- }
- ERR("Creating thread failed.. %u\n", GetLastError());
- LeaveCriticalSection(&capBox->CritSect);
- return E_FAIL;
+ if (FAILED(hr = IMemAllocator_Commit(device->pin->pAllocator)))
+ ERR("Failed to commit allocator, hr %#x.\n", hr);
}
- ResumeThread(capBox->thread);
- *state = State_Running;
- LeaveCriticalSection(&capBox->CritSect);
- return S_OK;
+ device->state = State_Paused;
+ device->thread = CreateThread(NULL, 0, ReadThread, device, 0, NULL);
}
-HRESULT qcap_driver_pause(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_start_stream(Capture *device)
{
- TRACE("%p -> (%p)\n", capBox, state);
-
- if (*state == State_Paused)
- return S_OK;
- if (*state == State_Stopped)
- qcap_driver_run(capBox, state);
-
- EnterCriticalSection(&capBox->CritSect);
- *state = State_Paused;
- SuspendThread(capBox->thread);
- LeaveCriticalSection(&capBox->CritSect);
-
- return S_OK;
+ device->state = State_Running;
+ SetEvent(device->run_event);
}
-HRESULT qcap_driver_stop(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_stop_stream(Capture *device)
{
- TRACE("%p -> (%p)\n", capBox, state);
-
- if (*state == State_Stopped)
- return S_OK;
-
- EnterCriticalSection(&capBox->CritSect);
-
- if (capBox->thread)
- {
- if (*state == State_Paused)
- ResumeThread(capBox->thread);
- capBox->stopped = TRUE;
- capBox->thread = 0;
- if (capBox->iscommitted)
- {
- HRESULT hr;
-
- capBox->iscommitted = FALSE;
-
- hr = IMemAllocator_Decommit(capBox->pin->pAllocator);
+ device->state = State_Paused;
+ ResetEvent(device->run_event);
+}
- if (hr != S_OK && hr != VFW_E_NOT_COMMITTED)
- WARN("Decommitting allocator: %x\n", hr);
- }
- }
+void qcap_driver_cleanup_stream(Capture *device)
+{
+ HRESULT hr;
- *state = State_Stopped;
- LeaveCriticalSection(&capBox->CritSect);
- return S_OK;
+ device->state = State_Stopped;
+ WaitForSingleObject(device->thread, INFINITE);
+ CloseHandle(device->thread);
+ device->thread = NULL;
+
+ hr = IMemAllocator_Decommit(device->pin->pAllocator);
+ if (hr != S_OK && hr != VFW_E_NOT_COMMITTED)
+ ERR("Failed to decommit allocator, hr %#x.\n", hr);
}
Capture *qcap_driver_init(struct strmbase_source *pin, USHORT card)
@@ -566,9 +502,6 @@ Capture *qcap_driver_init(struct strmbase_source *pin, USHORT card)
if (!(device = CoTaskMemAlloc(sizeof(*device))))
return NULL;
- InitializeCriticalSection(&device->CritSect);
- device->CritSect.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": Capture.CritSect");
-
sprintf(path, "/dev/video%i", card);
TRACE("Opening device %s.\n", path);
#ifdef O_CLOEXEC
@@ -635,8 +568,8 @@ Capture *qcap_driver_init(struct strmbase_source *pin, USHORT card)
device->bitDepth = 24;
device->pin = pin;
device->fps = 3;
- device->stopped = FALSE;
- device->iscommitted = FALSE;
+ device->state = State_Stopped;
+ device->run_event = CreateEventW(NULL, TRUE, FALSE, NULL);
TRACE("Format: %d bpp - %dx%d.\n", device->bitDepth, device->width, device->height);
@@ -701,17 +634,22 @@ HRESULT qcap_driver_set_prop(Capture *capBox, VideoProcAmpProperty Property,
FAIL_WITH_ERR;
}
-HRESULT qcap_driver_run(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_init_stream(Capture *device)
+{
+ FAIL_WITH_ERR;
+}
+
+void qcap_driver_start_stream(Capture *device)
{
FAIL_WITH_ERR;
}
-HRESULT qcap_driver_pause(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_stop_stream(Capture *device)
{
FAIL_WITH_ERR;
}
-HRESULT qcap_driver_stop(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_cleanup_stream(Capture *device)
{
FAIL_WITH_ERR;
}
diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c
index 2b60e542eba..0f8beb0f495 100644
--- a/dlls/qcap/vfwcapture.c
+++ b/dlls/qcap/vfwcapture.c
@@ -62,11 +62,6 @@ static inline VfwCapture *impl_from_strmbase_filter(struct strmbase_filter *ifac
return CONTAINING_RECORD(iface, VfwCapture, filter);
}
-static inline VfwCapture *impl_from_IBaseFilter(IBaseFilter *iface)
-{
- return CONTAINING_RECORD(iface, VfwCapture, filter.IBaseFilter_iface);
-}
-
static inline VfwCapture *impl_from_IAMStreamConfig(IAMStreamConfig *iface)
{
return CONTAINING_RECORD(iface, VfwCapture, IAMStreamConfig_iface);
@@ -99,7 +94,7 @@ static void vfw_capture_destroy(struct strmbase_filter *iface)
if (filter->init)
{
if (filter->filter.state != State_Stopped)
- qcap_driver_stop(filter->driver_info, &filter->filter.state);
+ qcap_driver_stop_stream(filter->driver_info);
qcap_driver_destroy(filter->driver_info);
}
@@ -129,47 +124,58 @@ static HRESULT vfw_capture_query_interface(struct strmbase_filter *iface, REFIID
return S_OK;
}
-static const struct strmbase_filter_ops filter_ops =
+static HRESULT vfw_capture_init_stream(struct strmbase_filter *iface)
{
- .filter_get_pin = vfw_capture_get_pin,
- .filter_destroy = vfw_capture_destroy,
- .filter_query_interface = vfw_capture_query_interface,
-};
+ VfwCapture *filter = impl_from_strmbase_filter(iface);
-/** IMediaFilter methods **/
+ qcap_driver_init_stream(filter->driver_info);
+ return VFW_S_CANT_CUE;
+}
-static HRESULT WINAPI VfwCapture_Stop(IBaseFilter * iface)
+static HRESULT vfw_capture_start_stream(struct strmbase_filter *iface, REFERENCE_TIME time)
{
- VfwCapture *This = impl_from_IBaseFilter(iface);
+ VfwCapture *filter = impl_from_strmbase_filter(iface);
- TRACE("()\n");
- return qcap_driver_stop(This->driver_info, &This->filter.state);
+ qcap_driver_start_stream(filter->driver_info);
+ return S_OK;
}
-static HRESULT WINAPI VfwCapture_Pause(IBaseFilter * iface)
+static HRESULT vfw_capture_stop_stream(struct strmbase_filter *iface)
{
- VfwCapture *This = impl_from_IBaseFilter(iface);
+ VfwCapture *filter = impl_from_strmbase_filter(iface);
- TRACE("()\n");
- return qcap_driver_pause(This->driver_info, &This->filter.state);
+ qcap_driver_stop_stream(filter->driver_info);
+ return VFW_S_CANT_CUE;
}
-static HRESULT WINAPI VfwCapture_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
+static HRESULT vfw_capture_cleanup_stream(struct strmbase_filter *iface)
{
- VfwCapture *This = impl_from_IBaseFilter(iface);
- TRACE("(%s)\n", wine_dbgstr_longlong(tStart));
- return qcap_driver_run(This->driver_info, &This->filter.state);
+ VfwCapture *filter = impl_from_strmbase_filter(iface);
+
+ qcap_driver_cleanup_stream(filter->driver_info);
+ return S_OK;
}
+static const struct strmbase_filter_ops filter_ops =
+{
+ .filter_get_pin = vfw_capture_get_pin,
+ .filter_destroy = vfw_capture_destroy,
+ .filter_query_interface = vfw_capture_query_interface,
+ .filter_init_stream = vfw_capture_init_stream,
+ .filter_start_stream = vfw_capture_start_stream,
+ .filter_stop_stream = vfw_capture_stop_stream,
+ .filter_cleanup_stream = vfw_capture_cleanup_stream,
+};
+
static const IBaseFilterVtbl VfwCapture_Vtbl =
{
BaseFilterImpl_QueryInterface,
BaseFilterImpl_AddRef,
BaseFilterImpl_Release,
BaseFilterImpl_GetClassID,
- VfwCapture_Stop,
- VfwCapture_Pause,
- VfwCapture_Run,
+ BaseFilterImpl_Stop,
+ BaseFilterImpl_Pause,
+ BaseFilterImpl_Run,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
--
2.23.0
Dec. 5, 2019
[PATCH 2/4] qcap/avimux: Use strmbase filter state change methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avimux.c | 58 +++++++++++++---------------------------------
1 file changed, 16 insertions(+), 42 deletions(-)
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index 1995358ac2f..a7a9ac7ceda 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -167,19 +167,6 @@ static HRESULT avi_mux_query_interface(struct strmbase_filter *iface, REFIID iid
return S_OK;
}
-static const struct strmbase_filter_ops filter_ops =
-{
- .filter_get_pin = avi_mux_get_pin,
- .filter_destroy = avi_mux_destroy,
- .filter_query_interface = avi_mux_query_interface,
-};
-
-static inline AviMux* impl_from_IBaseFilter(IBaseFilter *iface)
-{
- struct strmbase_filter *filter = CONTAINING_RECORD(iface, struct strmbase_filter, IBaseFilter_iface);
- return impl_from_strmbase_filter(filter);
-}
-
static HRESULT out_flush(AviMux *This)
{
ULONG written;
@@ -420,17 +407,12 @@ static HRESULT queue_sample(AviMux *avimux, AviMuxIn *avimuxin, IMediaSample *sa
return flush_queue(avimux, avimuxin, FALSE);
}
-static HRESULT WINAPI AviMux_Stop(IBaseFilter *iface)
+static HRESULT avi_mux_cleanup_stream(struct strmbase_filter *iface)
{
- AviMux *This = impl_from_IBaseFilter(iface);
+ AviMux *This = impl_from_strmbase_filter(iface);
HRESULT hr;
int i;
- TRACE("(%p)\n", This);
-
- if(This->filter.state == State_Stopped)
- return S_OK;
-
if (This->stream)
{
AVIEXTHEADER dmlh;
@@ -559,36 +541,20 @@ static HRESULT WINAPI AviMux_Stop(IBaseFilter *iface)
This->stream = NULL;
}
- This->filter.state = State_Stopped;
return S_OK;
}
-static HRESULT WINAPI AviMux_Pause(IBaseFilter *iface)
+static HRESULT avi_mux_init_stream(struct strmbase_filter *iface)
{
- AviMux *This = impl_from_IBaseFilter(iface);
- FIXME("(%p)\n", This);
- return E_NOTIMPL;
-}
-
-static HRESULT WINAPI AviMux_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
-{
- AviMux *This = impl_from_IBaseFilter(iface);
+ AviMux *This = impl_from_strmbase_filter(iface);
HRESULT hr;
int i, stream_id;
- TRACE("(%p)->(%s)\n", This, wine_dbgstr_longlong(tStart));
-
- if(This->filter.state == State_Running)
- return S_OK;
-
if(This->mode != INTERLEAVE_FULL) {
FIXME("mode not supported (%d)\n", This->mode);
return E_NOTIMPL;
}
- if(tStart)
- FIXME("tStart parameter ignored\n");
-
for(i=0; i<This->input_pin_no; i++) {
IMediaSeeking *ms;
LONGLONG cur, stop;
@@ -694,18 +660,26 @@ static HRESULT WINAPI AviMux_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
This->avih.dwWidth = ((BITMAPINFOHEADER*)This->in[0]->strf->data)->biWidth;
This->avih.dwHeight = ((BITMAPINFOHEADER*)This->in[0]->strf->data)->biHeight;
- This->filter.state = State_Running;
return S_OK;
}
+static const struct strmbase_filter_ops filter_ops =
+{
+ .filter_get_pin = avi_mux_get_pin,
+ .filter_destroy = avi_mux_destroy,
+ .filter_query_interface = avi_mux_query_interface,
+ .filter_init_stream = avi_mux_init_stream,
+ .filter_cleanup_stream = avi_mux_cleanup_stream,
+};
+
static const IBaseFilterVtbl AviMuxVtbl = {
BaseFilterImpl_QueryInterface,
BaseFilterImpl_AddRef,
BaseFilterImpl_Release,
BaseFilterImpl_GetClassID,
- AviMux_Stop,
- AviMux_Pause,
- AviMux_Run,
+ BaseFilterImpl_Stop,
+ BaseFilterImpl_Pause,
+ BaseFilterImpl_Run,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
--
2.23.0
Dec. 5, 2019
[PATCH 1/4] qcap/avico: Use strmbase filter state change methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avico.c | 81 +++++++++++++++--------------------------
dlls/qcap/tests/avico.c | 8 ++--
2 files changed, 33 insertions(+), 56 deletions(-)
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c
index f0f60ae4394..f65f33fe442 100644
--- a/dlls/qcap/avico.c
+++ b/dlls/qcap/avico.c
@@ -56,12 +56,6 @@ static inline AVICompressor *impl_from_strmbase_filter(struct strmbase_filter *f
return CONTAINING_RECORD(filter, AVICompressor, filter);
}
-static inline AVICompressor *impl_from_IBaseFilter(IBaseFilter *iface)
-{
- struct strmbase_filter *filter = CONTAINING_RECORD(iface, struct strmbase_filter, IBaseFilter_iface);
- return impl_from_strmbase_filter(filter);
-}
-
static inline AVICompressor *impl_from_strmbase_pin(struct strmbase_pin *pin)
{
return impl_from_strmbase_filter(pin->filter);
@@ -117,57 +111,14 @@ static HRESULT fill_format_info(AVICompressor *This, VIDEOINFOHEADER *src_videoi
return S_OK;
}
-static HRESULT WINAPI AVICompressor_Stop(IBaseFilter *iface)
-{
- AVICompressor *This = impl_from_IBaseFilter(iface);
-
- TRACE("(%p)\n", This);
-
- if(This->filter.state == State_Stopped)
- return S_OK;
-
- ICCompressEnd(This->hic);
- This->filter.state = State_Stopped;
- return S_OK;
-}
-
-static HRESULT WINAPI AVICompressor_Pause(IBaseFilter *iface)
-{
- AVICompressor *This = impl_from_IBaseFilter(iface);
- FIXME("(%p)\n", This);
- return E_NOTIMPL;
-}
-
-static HRESULT WINAPI AVICompressor_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
-{
- AVICompressor *This = impl_from_IBaseFilter(iface);
- HRESULT hres;
-
- TRACE("(%p)->(%s)\n", This, wine_dbgstr_longlong(tStart));
-
- if(This->filter.state == State_Running)
- return S_OK;
-
- if (This->source.pAllocator && FAILED(hres = IMemAllocator_Commit(This->source.pAllocator)))
- {
- FIXME("Commit failed: %08x\n", hres);
- return hres;
- }
-
- This->frame_cnt = 0;
-
- This->filter.state = State_Running;
- return S_OK;
-}
-
static const IBaseFilterVtbl AVICompressorVtbl = {
BaseFilterImpl_QueryInterface,
BaseFilterImpl_AddRef,
BaseFilterImpl_Release,
BaseFilterImpl_GetClassID,
- AVICompressor_Stop,
- AVICompressor_Pause,
- AVICompressor_Run,
+ BaseFilterImpl_Stop,
+ BaseFilterImpl_Pause,
+ BaseFilterImpl_Run,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
@@ -215,11 +166,37 @@ static HRESULT avi_compressor_query_interface(struct strmbase_filter *iface, REF
return S_OK;
}
+static HRESULT avi_compressor_init_stream(struct strmbase_filter *iface)
+{
+ AVICompressor *filter = impl_from_strmbase_filter(iface);
+ HRESULT hr;
+
+ if (filter->source.pAllocator && FAILED(hr = IMemAllocator_Commit(filter->source.pAllocator)))
+ {
+ ERR("Failed to commit allocator, hr %#x.\n", hr);
+ return hr;
+ }
+
+ filter->frame_cnt = 0;
+
+ return S_OK;
+}
+
+static HRESULT avi_compressor_cleanup_stream(struct strmbase_filter *iface)
+{
+ AVICompressor *filter = impl_from_strmbase_filter(iface);
+
+ ICCompressEnd(filter->hic);
+ return S_OK;
+}
+
static const struct strmbase_filter_ops filter_ops =
{
.filter_get_pin = avi_compressor_get_pin,
.filter_destroy = avi_compressor_destroy,
.filter_query_interface = avi_compressor_query_interface,
+ .filter_init_stream = avi_compressor_init_stream,
+ .filter_cleanup_stream = avi_compressor_cleanup_stream,
};
static AVICompressor *impl_from_IPersistPropertyBag(IPersistPropertyBag *iface)
diff --git a/dlls/qcap/tests/avico.c b/dlls/qcap/tests/avico.c
index 5c6d4aa54f4..b4f52f10210 100644
--- a/dlls/qcap/tests/avico.c
+++ b/dlls/qcap/tests/avico.c
@@ -665,11 +665,11 @@ static void test_unconnected_filter_state(IBaseFilter *filter)
ok(state == State_Stopped, "Got state %u.\n", state);
hr = IBaseFilter_Pause(filter);
- todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IBaseFilter_GetState(filter, 0, &state);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(state == State_Paused, "Got state %u.\n", state);
+ ok(state == State_Paused, "Got state %u.\n", state);
hr = IBaseFilter_Run(filter, 0);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -679,11 +679,11 @@ static void test_unconnected_filter_state(IBaseFilter *filter)
ok(state == State_Running, "Got state %u.\n", state);
hr = IBaseFilter_Pause(filter);
- todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IBaseFilter_GetState(filter, 0, &state);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(state == State_Paused, "Got state %u.\n", state);
+ ok(state == State_Paused, "Got state %u.\n", state);
hr = IBaseFilter_Stop(filter);
ok(hr == S_OK, "Got hr %#x.\n", hr);
--
2.23.0
Dec. 5, 2019
[PATCH v3 resend] odbccp32: Implement SQLConfigDataSource/W
by Alistair Leslie-Hughes
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/odbccp32/odbccp32.c | 121 +++++++++++++++++++++++++++++++--------
1 file changed, 97 insertions(+), 24 deletions(-)
diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c
index a09d6571f3..c842872fa6 100644
--- a/dlls/odbccp32/odbccp32.c
+++ b/dlls/odbccp32/odbccp32.c
@@ -68,6 +68,9 @@ static const WCHAR odbc_error_load_lib_failed[] = {'L','o','a','d',' ','L','i','
static const WCHAR odbc_error_request_failed[] = {'R','e','q','u','e','s','t',' ','F','a','i','l','e','d',0};
static const WCHAR odbc_error_invalid_keyword[] = {'I','n','v','a','l','i','d',' ','k','e','y','w','o','r','d',' ','v','a','l','u','e',0};
+static BOOL (WINAPI *pConfigDSN)(HWND hwnd, WORD request, const char *driver, const char *attr);
+static BOOL (WINAPI *pConfigDSNW)(HWND hwnd, WORD request, const WCHAR *driver, const WCHAR *attr);
+
/* Push an error onto the error stack, taking care of ranges etc. */
static void push_error(int code, LPCWSTR msg)
{
@@ -219,30 +222,6 @@ static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_leng
return success;
}
-BOOL WINAPI SQLConfigDataSourceW(HWND hwndParent, WORD fRequest,
- LPCWSTR lpszDriver, LPCWSTR lpszAttributes)
-{
- LPCWSTR p;
-
- clear_errors();
- FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_w(lpszDriver),
- debugstr_w(lpszAttributes));
-
- for (p = lpszAttributes; *p; p += lstrlenW(p) + 1)
- FIXME("%s\n", debugstr_w(p));
-
- return TRUE;
-}
-
-BOOL WINAPI SQLConfigDataSource(HWND hwndParent, WORD fRequest,
- LPCSTR lpszDriver, LPCSTR lpszAttributes)
-{
- FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_a(lpszDriver),
- debugstr_a(lpszAttributes));
- clear_errors();
- return TRUE;
-}
-
static HMODULE load_config_driver(const WCHAR *driver)
{
static WCHAR reg_driver[] = {'d','r','i','v','e','r',0};
@@ -359,6 +338,100 @@ fail:
return FALSE;
}
+BOOL WINAPI SQLConfigDataSourceW(HWND hwnd, WORD request, LPCWSTR driver, LPCWSTR attributes)
+{
+ HMODULE mod;
+ BOOL ret = FALSE;
+
+ TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_w(driver), debugstr_w(attributes));
+ if (TRACE_ON(odbc))
+ {
+ const WCHAR *p;
+ for (p = attributes; *p; p += lstrlenW(p) + 1)
+ TRACE("%s\n", debugstr_w(p));
+ }
+
+ clear_errors();
+
+ mod = load_config_driver(driver);
+ if (!mod)
+ return FALSE;
+
+ pConfigDSNW = (void*)GetProcAddress(mod, "ConfigDSNW");
+ if(pConfigDSNW)
+ ret = pConfigDSNW(hwnd, request, driver, attributes);
+ else
+ ERR("Failed to find ConfigDSNW\n");
+
+ if (!ret)
+ push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed);
+
+ FreeLibrary(mod);
+
+ return ret;
+}
+
+BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attributes)
+{
+ HMODULE mod;
+ BOOL ret = FALSE;
+ WCHAR *driverW;
+
+ TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_a(driver), debugstr_a(attributes));
+
+ if (TRACE_ON(odbc))
+ {
+ const char *p;
+ for (p = attributes; *p; p += lstrlenA(p) + 1)
+ TRACE("%s\n", debugstr_a(p));
+ }
+
+ clear_errors();
+
+ driverW = heap_strdupAtoW(driver);
+ if (!driverW)
+ {
+ push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
+ return FALSE;
+ }
+
+ mod = load_config_driver(driverW);
+ if (!mod)
+ {
+ heap_free(driverW);
+ return FALSE;
+ }
+
+ pConfigDSN = (void*)GetProcAddress(mod, "ConfigDSN");
+ if (pConfigDSN)
+ {
+ TRACE("Calling ConfigDSN\n");
+ ret = pConfigDSN(hwnd, request, driver, attributes);
+ }
+ else
+ {
+ pConfigDSNW = (void*)GetProcAddress(mod, "ConfigDSNW");
+ if (pConfigDSNW)
+ {
+ WCHAR *attr = NULL;
+ TRACE("Calling ConfigDSNW\n");
+
+ attr = SQLInstall_strdup_multi(attributes);
+ if(attr)
+ ret = pConfigDSNW(hwnd, request, driverW, attr);
+ heap_free(attr);
+ }
+ }
+
+ if (!ret)
+ push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed);
+
+ heap_free(driverW);
+ FreeLibrary(mod);
+
+ return ret;
+}
+
BOOL WINAPI SQLConfigDriverW(HWND hwnd, WORD request, LPCWSTR driver,
LPCWSTR args, LPWSTR msg, WORD msgmax, WORD *msgout)
{
--
2.17.1
Dec. 4, 2019
Re: [wine-devel] Wine staging 4.21 release
by Alan W. Irwin
On 2019-11-30 04:56-0000 Alistair Leslie-Hughes wrote:
> Binary packages for various distributions will be available from:
> https://www.winehq.org/download
>
> Summary since last release
> * Rebased to current wine 4.21 (833 patches are applied to wine vanilla)
>
> Upstreamed (Either directly from staging or fixed with a similar patch).
> * none
>
> Added:
> * [47668] kernelbase: Improve stub for ReOpenFile and add small test
> * [48138] League of Legends 9.23: Crash after champ select
> * [47970] Legends of Runeterra crashes at launch
> * [40334] AION - Wine /Unhandled exception: page fault on read access to
> 0x00000000 in 64-bit code (0x0000000000000000).
> * [48175] AION (64 bit) - crashes in crysystem.dll.CryFree() due to high
> memory pointers allocated
> * [46568] 64-bit msxml6.dll from Microsoft Core XML Services 6.0 redist
> package fails to load (Wine doesn't respect 44-bit user-mode VA
> limitation from Windows < 8.1)
>
> Updated:
> * d3d9-Direct3DShaderValidatorCreate9
> * winecfg-Staging
[...]
Hi Alistair:
Could you explain how these patch numbers in your report are related with each other?
For example, my initial assumption was the rebased patch number should
be equal to the corresponding number in the last report plus the added
patches in this report less the upstreamed patches in this report, i.e.,
r = r_old + a - u
where r and r_old are the current and last reported rebased patch numbers and a and u
are the current added and upstreamed patch numbers.
But looking at the last several reports that formula predicts
incorrect results with the rebased patch number changing in what looks
like a completely arbitrary way from report to report compared to the
prediction. So it appears the above formula is incorrect and/or
incomplete.
Could you let me know what the correct formula is for predicting the
rebased patch number from report to report (which helps to evaluate
the reliability of the staging patch number statistics that you
present), and if that formula depends on information (my guess is it
is the number of patches in staging that have just been deleted by the
staging maintainers because they judge those patches to not be
worthwhile) that you currently do not include in your reports, could
you include that important information in your following reports?
TIA.
Alan
__________________________
Alan W. Irwin
Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net) the Time
Ephemerides project (timeephem.sf.net) PLplot scientific plotting
software package (plplot.org) the libLASi project
(unifont.org/lasi) the Loads of Linux Links project (loll.sf.net)
and the Linux Brochure Project (lbproject.sf.net)
__________________________
Linux-powered Science
__________________________
Dec. 4, 2019
[PATCH 2/2] bcrypt: Add more BCryptSignHash tests.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/bcrypt/tests/bcrypt.c | 47 +++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
index d125e0c89d..8e495438df 100644
--- a/dlls/bcrypt/tests/bcrypt.c
+++ b/dlls/bcrypt/tests/bcrypt.c
@@ -2048,7 +2048,9 @@ static BYTE rsapublic[] =
static void test_BCryptSignHash(void)
{
static UCHAR hash[] =
- {0x7e,0xe3,0x74,0xe7,0xc5,0x0b,0x6b,0x70,0xdb,0xab,0x32,0x6d,0x1d,0x51,0xd6,0x74,0x79,0x8e,0x5b,0x4b};
+ {0x04,0xD6,0xAC,0x44,0x02,0xA9,0x2A,0x36,0x78,0x0B,0xC7,0x79,0xC8,0xEC,0x71,0x34,0x49,0xFB,0x92,0x2F};
+ static UCHAR hash_sha256[] =
+ {0x25,0x2F,0x10,0xC8,0x36,0x10,0xEB,0xCA,0x1A,0x05,0x9C,0x0B,0xAE,0x82,0x55,0xEB,0xA2,0xF9,0x5B,0xE4,0xD1,0xD7,0xBC,0xFA,0x89,0xD7,0x24,0x8A,0x82,0xD9,0xF1,0x11};
BCRYPT_PKCS1_PADDING_INFO pad;
BCRYPT_ALG_HANDLE alg;
BCRYPT_KEY_HANDLE key;
@@ -2056,6 +2058,8 @@ static void test_BCryptSignHash(void)
NTSTATUS ret;
ULONG len;
+ /* RSA */
+
ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
if (ret)
{
@@ -2087,6 +2091,14 @@ static void test_BCryptSignHash(void)
len = 0;
memset(sig, 0, sizeof(sig));
+
+ /* inference of padding info on RSA not supported */
+ ret = pBCryptSignHash(key, NULL, hash, sizeof(hash), sig, sizeof(sig), &len, 0);
+ ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
+
+ ret = pBCryptSignHash(key, &pad, hash, sizeof(hash), sig, 0, &len, BCRYPT_PAD_PKCS1);
+ ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
+
ret = pBCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
ok(!ret, "got %08x\n", ret);
ok(len == 64, "got %u\n", len);
@@ -2099,6 +2111,39 @@ static void test_BCryptSignHash(void)
ret = pBCryptCloseAlgorithmProvider(alg, 0);
ok(!ret, "got %08x\n", ret);
+
+ /* ECDSA */
+
+ ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0);
+ if (ret)
+ {
+ win_skip("failed to open ECDSA provider: %08x\n", ret);
+ return;
+ }
+
+ ret = pBCryptGenerateKeyPair(alg, &key, 256, 0);
+ ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+
+ ret = pBCryptFinalizeKeyPair(key, 0);
+ ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+
+ memset(sig, 0, sizeof(sig));
+ len = 0;
+
+ /* automatically detects padding info */
+ ret = pBCryptSignHash(key, NULL, hash, sizeof(hash), sig, sizeof(sig), &len, 0);
+ ok (!ret, "got %08x\n", ret);
+ ok (len == 64, "got %u\n", len);
+
+ /* mismatch info (SHA-1 != SHA-256) */
+ ret = pBCryptSignHash(key, &pad, hash_sha256, sizeof(hash_sha256), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
+ ok (ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
+
+ ret = pBCryptDestroyKey(key);
+ ok(!ret, "got %08x\n", ret);
+
+ ret = pBCryptCloseAlgorithmProvider(alg, 0);
+ ok(!ret, "got %08x\n", ret);
}
static void test_BCryptEnumAlgorithms(void)
--
2.24.0
Dec. 4, 2019
[PATCH 1/2] bcrypt: Add support for signing hashes with ECDSA keys.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/bcrypt/gnutls.c | 150 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 133 insertions(+), 17 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index a6a07fff19..fe16e8c435 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -92,6 +92,7 @@ MAKE_FUNCPTR(gnutls_cipher_decrypt2);
MAKE_FUNCPTR(gnutls_cipher_deinit);
MAKE_FUNCPTR(gnutls_cipher_encrypt2);
MAKE_FUNCPTR(gnutls_cipher_init);
+MAKE_FUNCPTR(gnutls_decode_rs_value);
MAKE_FUNCPTR(gnutls_global_deinit);
MAKE_FUNCPTR(gnutls_global_init);
MAKE_FUNCPTR(gnutls_global_set_log_function);
@@ -189,6 +190,7 @@ BOOL gnutls_initialize(void)
LOAD_FUNCPTR(gnutls_cipher_deinit)
LOAD_FUNCPTR(gnutls_cipher_encrypt2)
LOAD_FUNCPTR(gnutls_cipher_init)
+ LOAD_FUNCPTR(gnutls_decode_rs_value)
LOAD_FUNCPTR(gnutls_global_deinit)
LOAD_FUNCPTR(gnutls_global_init)
LOAD_FUNCPTR(gnutls_global_set_log_function)
@@ -711,6 +713,7 @@ NTSTATUS key_asymmetric_generate( struct key *key )
break;
case ALG_ID_ECDH_P256:
+ case ALG_ID_ECDSA_P256:
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
break;
@@ -1029,6 +1032,23 @@ static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULO
}
}
+gnutls_digest_algorithm_t get_digest_from_id(LPCWSTR alg_id)
+{
+ if (!lstrcmpiW(alg_id, BCRYPT_SHA1_ALGORITHM))
+ return GNUTLS_DIG_SHA1;
+ if (!lstrcmpiW(alg_id, BCRYPT_SHA256_ALGORITHM))
+ return GNUTLS_DIG_SHA256;
+ if (!lstrcmpiW(alg_id, BCRYPT_SHA384_ALGORITHM))
+ return GNUTLS_DIG_SHA384;
+ if (!lstrcmpiW(alg_id, BCRYPT_SHA512_ALGORITHM))
+ return GNUTLS_DIG_SHA512;
+ if (!lstrcmpiW(alg_id, BCRYPT_MD2_ALGORITHM))
+ return GNUTLS_DIG_MD2;
+ if (!lstrcmpiW(alg_id, BCRYPT_MD5_ALGORITHM))
+ return GNUTLS_DIG_MD5;
+ return -1;
+}
+
NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULONG hash_len, UCHAR *signature,
ULONG signature_len, DWORD flags )
{
@@ -1068,11 +1088,7 @@ NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULO
if (!(flags & BCRYPT_PAD_PKCS1) || !info) return STATUS_INVALID_PARAMETER;
if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
- if (!strcmpW( info->pszAlgId, BCRYPT_SHA1_ALGORITHM )) hash_alg = GNUTLS_DIG_SHA1;
- else if (!strcmpW( info->pszAlgId, BCRYPT_SHA256_ALGORITHM )) hash_alg = GNUTLS_DIG_SHA256;
- else if (!strcmpW( info->pszAlgId, BCRYPT_SHA384_ALGORITHM )) hash_alg = GNUTLS_DIG_SHA384;
- else if (!strcmpW( info->pszAlgId, BCRYPT_SHA512_ALGORITHM )) hash_alg = GNUTLS_DIG_SHA512;
- else
+ if ((hash_alg = get_digest_from_id(info->pszAlgId)) == -1)
{
FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
return STATUS_NOT_SUPPORTED;
@@ -1107,26 +1123,127 @@ NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULO
return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
}
+NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature, UCHAR *output,
+ ULONG output_len, ULONG *ret_len)
+{
+ int err;
+ unsigned int sig_len;
+
+ switch (type)
+ {
+ case ALG_ID_RSA:
+ case ALG_ID_RSA_SIGN:
+ {
+ /* RSA */
+ if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
+ memcpy(output, signature.data, signature.size);
+ *ret_len = signature.size;
+ return STATUS_SUCCESS;
+ }
+ case ALG_ID_ECDSA_P256:
+ sig_len = 64;
+ goto ecc;
+ case ALG_ID_ECDSA_P384:
+ sig_len = 96;
+ ecc:
+ {
+ /* ECDSA, format as r||s */
+ gnutls_datum_t r,s;
+ unsigned int pad_size;
+
+ if ((err = pgnutls_decode_rs_value(&signature, &r, &s)))
+ {
+ ERR( "failed to get R/S values from signature %u\n", err );
+ return 0;
+ }
+
+ if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
+
+ /* remove prepended zero byte */
+ if (r.size % 2)
+ {
+ r.size--;
+ r.data+=1;
+ }
+ if (s.size % 2)
+ {
+ s.size--;
+ s.data+=1;
+ }
+
+ if (r.size != s.size || r.size + s.size > sig_len)
+ {
+ ERR( "we didn't get a correct signature\n" );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ pad_size = (sig_len / 2) - s.size;
+ memset(output, 0, sig_len);
+
+ memcpy(output + pad_size, r.data, r.size);
+ memcpy(output + (sig_len / 2) + pad_size, s.data, s.size);
+
+ *ret_len = sig_len;
+ return STATUS_SUCCESS;
+ }
+ default:
+ return STATUS_INTERNAL_ERROR;
+ }
+}
+
NTSTATUS key_asymmetric_sign( struct key *key, void *padding, UCHAR *input, ULONG input_len, UCHAR *output,
ULONG output_len, ULONG *ret_len, ULONG flags )
{
BCRYPT_PKCS1_PADDING_INFO *pad = padding;
gnutls_datum_t hash, signature;
+ gnutls_digest_algorithm_t hash_alg;
+ NTSTATUS status;
int ret;
- if (key->alg_id != ALG_ID_RSA && key->alg_id != ALG_ID_RSA_SIGN)
+ if (key->alg_id == ALG_ID_ECDSA_P256 || key->alg_id == ALG_ID_ECDSA_P384)
{
- FIXME( "algorithm %u not supported\n", key->alg_id );
- return STATUS_NOT_IMPLEMENTED;
+ /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
+ switch (input_len)
+ {
+ case 20: hash_alg = GNUTLS_DIG_SHA1; break;
+ case 32: hash_alg = GNUTLS_DIG_SHA256; break;
+ case 48: hash_alg = GNUTLS_DIG_SHA384; break;
+ case 64: hash_alg = GNUTLS_DIG_SHA512; break;
+
+ default:
+ FIXME( "hash size %u not yet supported\n", input_len );
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (flags == BCRYPT_PAD_PKCS1 && pad && pad->pszAlgId &&
+ get_digest_from_id(pad->pszAlgId) != hash_alg)
+ {
+ WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
+ return STATUS_INVALID_PARAMETER;
+ }
}
- if (flags != BCRYPT_PAD_PKCS1)
+ else if (flags == BCRYPT_PAD_PKCS1)
{
- FIXME( "flags %08x not implemented\n", flags );
- return STATUS_NOT_IMPLEMENTED;
+ if (!pad || !pad->pszAlgId)
+ {
+ WARN( "padding info not found\n" );
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if ((hash_alg = get_digest_from_id(pad->pszAlgId)) == -1)
+ {
+ FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
+ return STATUS_NOT_SUPPORTED;
+ }
+ }
+ else if (!flags)
+ {
+ WARN( "invalid flags %08x\n", flags );
+ return STATUS_INVALID_PARAMETER;
}
- if (!pad || !pad->pszAlgId || lstrcmpiW(pad->pszAlgId, BCRYPT_SHA1_ALGORITHM))
+ else
{
- FIXME( "%s padding not implemented\n", debugstr_w(pad ? pad->pszAlgId : NULL) );
+ FIXME( "flags %08x not implemented\n", flags );
return STATUS_NOT_IMPLEMENTED;
}
@@ -1143,17 +1260,16 @@ NTSTATUS key_asymmetric_sign( struct key *key, void *padding, UCHAR *input, ULON
signature.data = NULL;
signature.size = 0;
- if ((ret = pgnutls_privkey_sign_hash( key->u.a.handle, GNUTLS_DIG_SHA1, 0, &hash, &signature )))
+ if ((ret = pgnutls_privkey_sign_hash( key->u.a.handle, hash_alg, 0, &hash, &signature )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
- if (output_len >= signature.size) memcpy( output, signature.data, signature.size );
- *ret_len = signature.size;
+ status = format_gnutls_signature(key->alg_id, signature, output, output_len, ret_len);
free( signature.data );
- return STATUS_SUCCESS;
+ return status;
}
NTSTATUS key_destroy( struct key *key )
--
2.24.0
Dec. 4, 2019
Re: [wine-devel] Wine staging 4.21 release
by Alan W. Irwin
On 2019-11-30 04:56-0000 Alistair Leslie-Hughes wrote:
> Binary packages for various distributions will be available from:
> https://www.winehq.org/download
>
> Summary since last release
> * Rebased to current wine 4.21 (833 patches are applied to wine vanilla)
>
> Upstreamed (Either directly from staging or fixed with a similar patch).
> * none
>
> Added:
> * [47668] kernelbase: Improve stub for ReOpenFile and add small test
> * [48138] League of Legends 9.23: Crash after champ select
> * [47970] Legends of Runeterra crashes at launch
> * [40334] AION - Wine /Unhandled exception: page fault on read access to
> 0x00000000 in 64-bit code (0x0000000000000000).
> * [48175] AION (64 bit) - crashes in crysystem.dll.CryFree() due to high
> memory pointers allocated
> * [46568] 64-bit msxml6.dll from Microsoft Core XML Services 6.0 redist
> package fails to load (Wine doesn't respect 44-bit user-mode VA
> limitation from Windows < 8.1)
>
> Updated:
> * d3d9-Direct3DShaderValidatorCreate9
> * winecfg-Staging
>
> Where can you help
> * Run Steam/Battle.net/GOG/UPlay/Epic
> * Test your favorite game.
> * Test your favorite applications.
> * Improve staging patches and get them accepted upstream.
>
> As always, if you find a bug, please report it via
> https://bugs.winehq.org
>
Hi Alistair:
Could you explain how these patch numbers are related with each other?
For example, my initial assumption was the rebased patch number should
be equal to the corresponding number in the last report plus the added
patches in this report less the upstreamed patches in this report, i.e.,
r = r_old + a - u
where r and r_old are the current and last reported rebased numbers and a and u
are the current added and upstreamed patch numbers.
But looking at the last several reports that formula predicts
incorrect results with the rebased patch number changing in what looks
like a completely arbitrary way from report to report compared to the
prediction. So it appears the above formula is incorrect and/or
incomplete.
Could you let me know what the correct formula is for predicting the
rebased patch number from report to report (which helps to evaluate
the reliability of the staging patch number statistics that you
present), and if that formula depends on information (my guess is it
is the number of patches in staging that have just been deleted by the
staging maintainers because they judge those patches to not be
worthwhile) that you currently do not include in your reports, could
you include that important information in your following reports?
Alan
__________________________
Alan W. Irwin
Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net) the Time
Ephemerides project (timeephem.sf.net) PLplot scientific plotting
software package (plplot.org) the libLASi project
(unifont.org/lasi) the Loads of Linux Links project (loll.sf.net)
and the Linux Brochure Project (lbproject.sf.net)
__________________________
Linux-powered Science
__________________________
Dec. 4, 2019
Re: [PATCH 2/2] xmllite: Return syntax error on nul character in the stream.
by Nikolay Sivov
On 12/5/19 12:30 AM, Jeff Smith wrote:
> On Wed, Dec 4, 2019 at 2:04 PM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>> I don't think it makes sense to test for null explicitly. Any invalid
>> char for given context would be a syntax error.
> Hi Nikolay,
>
> I agree that it should work that way. However, the tests show that it
> does not. My belief is that the stream is being treated as a string,
> so when a null character encountered, it is treating as marking the
> end of the stream, even though it may actually be a part of the
> stream. My patch makes sure that condition is being covered, at least
> for the cases that are being tested.
Putting explicit null checks here and there just to fix some tests is
not worth it in my opinion.
Instead it should be a part of character range checks, as we do now.
E.g. while on whitespace,
hitting 0 char would mean you're done with whitespace node, and whatever
node is allowed or expected next
should handle it.
>
> Thanks,
> Jeff
Dec. 4, 2019
Re: [PATCH 2/2] xmllite: Return syntax error on nul character in the stream.
by Jeff Smith
On Wed, Dec 4, 2019 at 2:04 PM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>
> I don't think it makes sense to test for null explicitly. Any invalid
> char for given context would be a syntax error.
Hi Nikolay,
I agree that it should work that way. However, the tests show that it
does not. My belief is that the stream is being treated as a string,
so when a null character encountered, it is treating as marking the
end of the stream, even though it may actually be a part of the
stream. My patch makes sure that condition is being covered, at least
for the cases that are being tested.
Thanks,
Jeff
Dec. 4, 2019
Re: [PATCH 1/2] include: Don't use the printf format attribute when compiling against msvcrt and not cross-compiling.
by Zebediah Figura
On 12/4/19 12:36 PM, Chip Davis wrote:
> December 4, 2019 12:28 PM, "Zebediah Figura" <z.figura12(a)gmail.com> wrote:
>
>> diff --git a/include/wine/debug.h b/include/wine/debug.h
>> index 1c312e9322..81c32e1816 100644
>> --- a/include/wine/debug.h
>> +++ b/include/wine/debug.h
>> @@ -92,7 +92,11 @@ struct __wine_debug_channel
>> #define __WINE_DBG_LOG(args...) \
>> wine_dbg_log( __dbcl, __dbch, __FUNCTION__, args); } } while(0)
>>
>> +#if !defined(__WINE_USE_MSVCRT) || defined(__MINGW32__)
>> #define __WINE_PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args)))
>> +#else
>> +#define __WINE_PRINTF_ATTR(fmt,args)
>> +#endif
>
> Consider using '__attribute__((format(ms_printf)))' instead. That shouldn't warn on %I, but would still give us the benefits of GCC/Clang's warning. Note that Clang does not yet support that form. I have a patch to fix that, but I need to get it upstream.
At least on gcc 9.2 ms_printf is only recognized for mingw targets. The
documentation implies this as well: "On MinGW targets, ms_printf,
ms_scanf, and ms_strftime are also present." [1]
[1]
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-F…
>
>>
>> #ifdef WINE_NO_TRACE_MSGS
>
>
> Chip
>
Dec. 4, 2019
Re: [PATCH 2/2] xmllite: Return syntax error on nul character in the stream.
by Nikolay Sivov
I don't think it makes sense to test for null explicitly. Any invalid
char for given context would be a syntax error.
Dec. 4, 2019
[PATCH 2/2] xmllite: Return syntax error on nul character in the stream.
by Jeff Smith
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/xmllite/reader.c | 11 +++++++++++
dlls/xmllite/tests/reader.c | 4 ----
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
index eddc4d8eec..c8083f63be 100644
--- a/dlls/xmllite/reader.c
+++ b/dlls/xmllite/reader.c
@@ -1696,6 +1696,14 @@ static HRESULT reader_parse_pi(xmlreader *reader)
return S_OK;
}
+/* Determine if we are encountering a nul character within the stream */
+static BOOL reader_at_nul(xmlreader *reader)
+{
+ encoded_buffer *buffer = &reader->input->buffer->utf16;
+ return (buffer->cur*sizeof(WCHAR) < buffer->written &&
+ *((WCHAR*)buffer->data + buffer->cur) == 0);
+}
+
/* This one is used to parse significant whitespace nodes, like in Misc production */
static HRESULT reader_parse_whitespace(xmlreader *reader)
{
@@ -1716,6 +1724,7 @@ static HRESULT reader_parse_whitespace(xmlreader *reader)
UINT start;
reader_skipspaces(reader);
+ if (reader_at_nul(reader)) return WC_E_SYNTAX;
if (is_reader_pending(reader)) return S_OK;
start = reader->resume[XmlReadResume_Body];
@@ -1766,6 +1775,8 @@ static HRESULT reader_parse_misc(xmlreader *reader)
hr = reader_parse_comment(reader);
else if (!reader_cmp(reader, piW))
hr = reader_parse_pi(reader);
+ else if (reader_at_nul(reader))
+ return WC_E_SYNTAX;
else
break;
diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c
index 88b9103e1e..7ad548d081 100644
--- a/dlls/xmllite/tests/reader.c
+++ b/dlls/xmllite/tests/reader.c
@@ -1051,7 +1051,6 @@ static void test_read_nul(void)
type = -1;
hr = IXmlReader_Read(reader, &type);
-todo_wine
ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
@@ -1064,10 +1063,8 @@ todo_wine
type = -1;
hr = IXmlReader_Read(reader, &type);
-todo_wine {
ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
-}
stream = create_stream_on_data(xml_comment, sizeof(xml_comment));
hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
@@ -1079,7 +1076,6 @@ todo_wine {
type = -1;
hr = IXmlReader_Read(reader, &type);
-todo_wine
ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
--
2.23.0
Dec. 4, 2019
[PATCH 1/2] xmllite/tests: Extract nul-character test from XML declaration test.
by Jeff Smith
The comments in the XML declaration test suggest that it is supposed to
be to checking for failure when no element follows the XML declaration.
However, the error being tested for is due to a nul character in the
input stream.
Create a separate test for nul-character errors, and fix the XML
declaration test accordingly.
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/xmllite/tests/reader.c | 83 +++++++++++++++++++++++++++++--------
1 file changed, 66 insertions(+), 17 deletions(-)
diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c
index 41adad1598..88b9103e1e 100644
--- a/dlls/xmllite/tests/reader.c
+++ b/dlls/xmllite/tests/reader.c
@@ -863,7 +863,6 @@ static void test_read_xmldeclaration(void)
{ {'s','t','a','n','d','a','l','o','n','e',0}, {'y','e','s',0} }
};
IXmlReader *reader;
- IStream *stream;
HRESULT hr;
XmlNodeType type;
UINT count = 0, len, i;
@@ -873,10 +872,7 @@ static void test_read_xmldeclaration(void)
hr = CreateXmlReader(&IID_IXmlReader, (LPVOID*)&reader, NULL);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
- stream = create_stream_on_data(xmldecl_full, sizeof(xmldecl_full));
-
- hr = IXmlReader_SetInput(reader, (IUnknown*)stream);
- ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+ set_input_string(reader, xmldecl_full);
hr = IXmlReader_GetAttributeCount(reader, &count);
ok(hr == S_OK, "got %08x\n", hr);
@@ -968,19 +964,19 @@ static void test_read_xmldeclaration(void)
type = XmlNodeType_XmlDeclaration;
hr = IXmlReader_Read(reader, &type);
- /* newer versions return syntax error here cause document is incomplete,
- it makes more sense than invalid char error */
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(type == XmlNodeType_Whitespace, "expected XmlNodeType_Whitespace, got %s\n", type_to_str(type));
+
+ type = XmlNodeType_Whitespace;
+ hr = IXmlReader_Read(reader, &type);
todo_wine {
- ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "got 0x%08x\n", hr);
+ ok(hr == WC_E_ROOTELEMENT, "got %08x\n", hr);
ok(type == XmlNodeType_None, "got %d\n", type);
+ TEST_READER_STATE(reader, XmlReadState_Error);
}
- IStream_Release(stream);
/* test short variant */
- stream = create_stream_on_data(xmldecl_short, sizeof(xmldecl_short));
-
- hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
- ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
+ set_input_string(reader, xmldecl_short);
read_node(reader, XmlNodeType_XmlDeclaration);
TEST_READER_POSITION2(reader, 1, 3, ~0u, 21);
@@ -1027,14 +1023,66 @@ todo_wine {
type = -1;
hr = IXmlReader_Read(reader, &type);
-todo_wine
- ok(hr == WC_E_SYNTAX || hr == WC_E_XMLCHARACTER /* XP */, "expected WC_E_SYNTAX, got %08x\n", hr);
+ ok(hr == S_FALSE, "expected S_FALSE, got %08x\n", hr);
ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
- TEST_READER_POSITION(reader, 1, 41);
+
+ IXmlReader_Release(reader);
+}
+
+static void test_read_nul(void)
+{
+ static const char xml_empty[] = "<a/>";
+ static const char xml_ws[] = "<a/> ";
+ static const char xml_comment[] = "<a/><!-- comment -->";
+ IXmlReader *reader;
+ XmlNodeType type;
+ IStream *stream;
+ HRESULT hr;
+
+ hr = CreateXmlReader(&IID_IXmlReader, (LPVOID*)&reader, NULL);
+ ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+
+ stream = create_stream_on_data(xml_empty, sizeof(xml_empty));
+ hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
+ ok(hr == S_OK, "got %08x\n", hr);
+ IStream_Release(stream);
+
+ read_node(reader, XmlNodeType_Element);
+
+ type = -1;
+ hr = IXmlReader_Read(reader, &type);
todo_wine
- TEST_READER_STATE(reader, XmlReadState_Error);
+ ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
+ ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
+ stream = create_stream_on_data(xml_ws, sizeof(xml_ws));
+ hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
+ ok(hr == S_OK, "got %08x\n", hr);
IStream_Release(stream);
+
+ read_node(reader, XmlNodeType_Element);
+
+ type = -1;
+ hr = IXmlReader_Read(reader, &type);
+todo_wine {
+ ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
+ ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
+}
+
+ stream = create_stream_on_data(xml_comment, sizeof(xml_comment));
+ hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
+ ok(hr == S_OK, "got %08x\n", hr);
+ IStream_Release(stream);
+
+ read_node(reader, XmlNodeType_Element);
+ read_node(reader, XmlNodeType_Comment);
+
+ type = -1;
+ hr = IXmlReader_Read(reader, &type);
+todo_wine
+ ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
+ ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
+
IXmlReader_Release(reader);
}
@@ -2672,6 +2720,7 @@ START_TEST(reader)
test_read_pending();
test_readvaluechunk();
test_read_xmldeclaration();
+ test_read_nul();
test_reader_properties();
test_prefix();
test_namespaceuri();
--
2.23.0
Dec. 4, 2019
Re: [PATCH 1/2] include: Don't use the printf format attribute when compiling against msvcrt and not cross-compiling.
by Chip Davis
December 4, 2019 12:28 PM, "Zebediah Figura" <z.figura12(a)gmail.com> wrote:
> diff --git a/include/wine/debug.h b/include/wine/debug.h
> index 1c312e9322..81c32e1816 100644
> --- a/include/wine/debug.h
> +++ b/include/wine/debug.h
> @@ -92,7 +92,11 @@ struct __wine_debug_channel
> #define __WINE_DBG_LOG(args...) \
> wine_dbg_log( __dbcl, __dbch, __FUNCTION__, args); } } while(0)
>
> +#if !defined(__WINE_USE_MSVCRT) || defined(__MINGW32__)
> #define __WINE_PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args)))
> +#else
> +#define __WINE_PRINTF_ATTR(fmt,args)
> +#endif
Consider using '__attribute__((format(ms_printf)))' instead. That shouldn't warn on %I, but would still give us the benefits of GCC/Clang's warning. Note that Clang does not yet support that form. I have a patch to fix that, but I need to get it upstream.
>
> #ifdef WINE_NO_TRACE_MSGS
Chip
Dec. 4, 2019
[PATCH 2/2] mapi32: Use the %I length modifier to print pointer-size integers.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/mapi32/imalloc.c | 4 ++--
dlls/mapi32/mapi32_main.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/mapi32/imalloc.c b/dlls/mapi32/imalloc.c
index 3e95a6c7cd..561df1a60a 100644
--- a/dlls/mapi32/imalloc.c
+++ b/dlls/mapi32/imalloc.c
@@ -114,7 +114,7 @@ static ULONG WINAPI IMAPIMalloc_fnRelease(LPMALLOC iface)
*/
static LPVOID WINAPI IMAPIMalloc_fnAlloc(LPMALLOC iface, SIZE_T cb)
{
- TRACE("(%p)->(%ld)\n", iface, cb);
+ TRACE("(%p)->(%Id)\n", iface, cb);
return LocalAlloc(LMEM_FIXED, cb);
}
@@ -124,7 +124,7 @@ static LPVOID WINAPI IMAPIMalloc_fnAlloc(LPMALLOC iface, SIZE_T cb)
*/
static LPVOID WINAPI IMAPIMalloc_fnRealloc(LPMALLOC iface, LPVOID pv, SIZE_T cb)
{
- TRACE("(%p)->(%p, %ld)\n", iface, pv, cb);
+ TRACE("(%p)->(%p, %Id)\n", iface, pv, cb);
if (!pv)
return LocalAlloc(LMEM_FIXED, cb);
diff --git a/dlls/mapi32/mapi32_main.c b/dlls/mapi32/mapi32_main.c
index 0dcc811c24..ac83062679 100644
--- a/dlls/mapi32/mapi32_main.c
+++ b/dlls/mapi32/mapi32_main.c
@@ -129,7 +129,7 @@ HRESULT WINAPI MAPIInitialize(LPVOID init)
ULONG WINAPI MAPILogon(ULONG_PTR uiparam, LPSTR profile, LPSTR password,
FLAGS flags, ULONG reserved, LPLHANDLE session)
{
- TRACE("(0x%08lx %s %p 0x%08x 0x%08x %p)\n", uiparam,
+ TRACE("(0x%08Ix %s %p 0x%08x 0x%08x %p)\n", uiparam,
debugstr_a(profile), password, flags, reserved, session);
if (mapiFunctions.MAPILogon)
@@ -149,7 +149,7 @@ ULONG WINAPI MAPILogon(ULONG_PTR uiparam, LPSTR profile, LPSTR password,
ULONG WINAPI MAPILogoff(LHANDLE session, ULONG_PTR uiparam, FLAGS flags,
ULONG reserved )
{
- TRACE("(0x%08lx 0x%08lx 0x%08x 0x%08x)\n", session,
+ TRACE("(0x%08Ix 0x%08Ix 0x%08x 0x%08x)\n", session,
uiparam, flags, reserved);
if (mapiFunctions.MAPILogoff)
@@ -167,7 +167,7 @@ ULONG WINAPI MAPILogoff(LHANDLE session, ULONG_PTR uiparam, FLAGS flags,
HRESULT WINAPI MAPILogonEx(ULONG_PTR uiparam, LPWSTR profile,
LPWSTR password, ULONG flags, LPMAPISESSION *session)
{
- TRACE("(0x%08lx %s %p 0x%08x %p)\n", uiparam,
+ TRACE("(0x%08Ix %s %p 0x%08x %p)\n", uiparam,
debugstr_w(profile), password, flags, session);
if (mapiFunctions.MAPILogonEx)
--
2.24.0
Dec. 4, 2019
[PATCH 1/2] include: Don't use the printf format attribute when compiling against msvcrt and not cross-compiling.
by Zebediah Figura
Since it will spit out bogus warnings in the case we use Microsoft-specific
extensions.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
include/wine/debug.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/wine/debug.h b/include/wine/debug.h
index 1c312e9322..81c32e1816 100644
--- a/include/wine/debug.h
+++ b/include/wine/debug.h
@@ -92,7 +92,11 @@ struct __wine_debug_channel
#define __WINE_DBG_LOG(args...) \
wine_dbg_log( __dbcl, __dbch, __FUNCTION__, args); } } while(0)
+#if !defined(__WINE_USE_MSVCRT) || defined(__MINGW32__)
#define __WINE_PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args)))
+#else
+#define __WINE_PRINTF_ATTR(fmt,args)
+#endif
#ifdef WINE_NO_TRACE_MSGS
--
2.24.0
Dec. 4, 2019
Re: LONG_PTR and friends
by Zebediah Figura
On 12/4/19 11:28 AM, Jacek Caban wrote:
> Hi Zebediah,
>
> On 11/26/19 7:48 PM, Zebediah Figura wrote:
>> * Both builtin and native msvcrt always support %I, but it's
>> nonstandard and it spits out warnings when you try to use it when not
>> compiling with mingw.
>
>
> I'd say that it looks like a nice solution. Since the warning is
> obviously bogus, I wonder if we should just skip format attribute in
> debug.h when __WINE_USE_MSVCRT is defined and we're not using a cross
> compiler.
Sure, makes sense. I'll try a patch along these lines.
>
>
>> * We could also cast to (void *), or cast to a 64-bit type and use
>> wine_dbgstr_longlong(), though this has the unfortunate side effect of
>> forcing us to trace in hexadecimal.
>
>
> It's not related to your original problem, but for PE builds (modules
> using -mno-cygwin to be precise), compatibility is not an issue so there
> is no reason for using wine_dbgstr_longlong(). I think we should
> consider using %ll* instead.
That would be nice, especially for places where it'd be more readable to
have decimal traces than hexadecimal. I guess we'd run into warnings
when the "long" type is used, but if we skip the format attribute as
above we won't have anything to worry about.
(Related question: why don't we just always define __int64 to "long long"?)
>
>
> Thanks,
>
> Jacek
>
>
Dec. 4, 2019
[PATCH] msxml3: all string passed to IXMLDOMDocument_load() need to be URL-unescaped
by Damjan Jovanovic
msxml3 allows URL escape sequences even for C:\ style paths.
eg. C:\Program%20Files\...
Signed-off-by: Damjan Jovanovic <damjan.jov(a)gmail.com>
---
dlls/msxml3/bsc.c | 8 ++++++--
dlls/msxml3/tests/domdoc.c | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 2 deletions(-)
Dec. 4, 2019
Re: LONG_PTR and friends
by Jacek Caban
Hi Zebediah,
On 11/26/19 7:48 PM, Zebediah Figura wrote:
> * Both builtin and native msvcrt always support %I, but it's
> nonstandard and it spits out warnings when you try to use it when not
> compiling with mingw.
I'd say that it looks like a nice solution. Since the warning is
obviously bogus, I wonder if we should just skip format attribute in
debug.h when __WINE_USE_MSVCRT is defined and we're not using a cross
compiler.
> * We could also cast to (void *), or cast to a 64-bit type and use
> wine_dbgstr_longlong(), though this has the unfortunate side effect of
> forcing us to trace in hexadecimal.
It's not related to your original problem, but for PE builds (modules
using -mno-cygwin to be precise), compatibility is not an issue so there
is no reason for using wine_dbgstr_longlong(). I think we should
consider using %ll* instead.
Thanks,
Jacek
Dec. 4, 2019