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] wtsapi32: Make WTSRegisterSessionNotificationEx's return consistant with WTSRegisterSessionNotification.
by Patrick Hibbs
No point in these returning different values, considering one is a superset of the other.
Fix as per Zebediah Figura's bug comment (#12).
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47433
Signed-off-by: Patrick Hibbs <hibbsncc1701(a)gmail.com>
---
dlls/wtsapi32/wtsapi32.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wtsapi32/wtsapi32.c b/dlls/wtsapi32/wtsapi32.c
index c2b817a6ed..026e7f4369 100644
--- a/dlls/wtsapi32/wtsapi32.c
+++ b/dlls/wtsapi32/wtsapi32.c
@@ -385,7 +385,7 @@ BOOL WINAPI WTSRegisterSessionNotification(HWND hWnd, DWORD dwFlags)
BOOL WINAPI WTSRegisterSessionNotificationEx(HANDLE hServer, HWND hWnd, DWORD dwFlags)
{
FIXME("Stub %p %p 0x%08x\n", hServer, hWnd, dwFlags);
- return FALSE;
+ return TRUE;
}
--
2.24.0
Dec. 7, 2019
Re: [PATCH v3 3/3] xmllite: Expand test for any unparsed data at end of XML.
by Jeff Smith
On Fri, Dec 6, 2019 at 4:19 PM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>
> On 12/7/19 12:24 AM, Jeff Smith wrote:
> > On Fri, Dec 6, 2019 at 11:16 AM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
> >> On 12/5/19 10:53 PM, Jeff Smith wrote:
> >>> @@ -2662,7 +2663,7 @@ static HRESULT reader_parse_nextnode(xmlreader *reader)
> >>> hr = reader_parse_misc(reader);
> >>> if (hr != S_FALSE) return hr;
> >>>
> >>> - if (*reader_get_ptr(reader))
> >>> + if (buffer->cur*sizeof(WCHAR) < buffer->written)
> >>> {
> >>> WARN("found garbage in the end of XML\n");
> >>> return WC_E_SYNTAX;
> > Hi Nikolay,
> >
> >> That means we don't have enough data,
> > How do you figure that?
> >
> >> it's another change not backed by tests
> > This fixes two tests, and does not break any others.
> >
> >> and potentially depending on current read-ahead buffer size/filled level.
> > I'm pretty sure reader_parse_misc would have read at least one byte
> > ahead, which is all that is required for this to trigger, though I
> > could double-check that.
> > However, to your point made in the patch 2 of the set about not
> > exposing the buffer at this level, I will also consider this something
> > that potentially needs to be handled elsewhere.
> My point is that we should always hit this single invalid syntax/garbage
> at the end condition that we already have,
That garbage-at-the-end condition, as it exists, is explicitly NOT
triggered by a null character, but it should.
So what we have here currently is not sufficient.
While there may be cases that my patch does not cover, based on
existing test cases, it is an improvement.
> instead of doing fixups for specific node types.
On Windows, the context in which the null character is encountered is
significant.
For instance, if any character other than '<' is encountered at the
end of a whitespace sequence, it raises the syntax error without
returning a Whitespace node.
So we need to catch the invalid character and interrupt before a
Whitespace node is returned.
Dec. 7, 2019
[PATCH] wineqtdecoder: Fix macos compile error
by Alistair Leslie-Hughes
Regression of 498179b4482026091bf7376c0d2ac9a036e7ca0e
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/wineqtdecoder/qtsplitter.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index 5b1e82ebc9b..956dd0a7d0d 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -285,7 +285,7 @@ static HRESULT qt_splitter_start_stream(struct strmbase_filter *iface, REFERENCE
QTSplitter *filter = impl_from_strmbase_filter(iface);
HRESULT hr = VFW_E_NOT_CONNECTED, pin_hr;
- EnterCriticalSection(&This->csReceive);
+ EnterCriticalSection(&filter->csReceive);
if (filter->pVideo_Pin)
pin_hr = BaseOutputPinImpl_Active(&filter->pVideo_Pin->pin);
@@ -297,7 +297,7 @@ static HRESULT qt_splitter_start_stream(struct strmbase_filter *iface, REFERENCE
hr = pin_hr;
SetEvent(filter->runEvent);
- LeaveCriticalSection(&This->csReceive);
+ LeaveCriticalSection(&filter->csReceive);
return hr;
}
@@ -306,10 +306,10 @@ static HRESULT qt_splitter_cleanup_stream(struct strmbase_filter *iface)
{
QTSplitter *filter = impl_from_strmbase_filter(iface);
- EnterCriticalSection(&This->csReceive);
+ EnterCriticalSection(&filter->csReceive);
IAsyncReader_BeginFlush(filter->pInputPin.pReader);
IAsyncReader_EndFlush(filter->pInputPin.pReader);
- LeaveCriticalSection(&This->csReceive);
+ LeaveCriticalSection(&filter->csReceive);
return S_OK;
}
@@ -1170,8 +1170,6 @@ static HRESULT WINAPI QTOutPin_QueryInterface(IPin *iface, REFIID riid, void **p
*ppv = iface;
else if (IsEqualIID(riid, &IID_IPin))
*ppv = iface;
- else if (IsEqualIID(riid, &IID_IMediaSeeking))
- *ppv = &This->sourceSeeking.IMediaSeeking_iface;
else if (IsEqualIID(riid, &IID_IQualityControl))
*ppv = &This->IQualityControl_iface;
--
2.24.0
Dec. 7, 2019
Re: [PATCH 6/6] strmbase: Get rid of the "vtbl" argument to strmbase_source_init().
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61549
Your paranoid android.
=== w1064v1809_he (32 bit report) ===
quartz:
videorenderer.c:928: Test failed: Thread should block in Receive().
Dec. 7, 2019
[PATCH] bcrypt: Add fallback when gnutls_decode_rs_value isn't present.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
I overlooked the fact that wine won't compile on systems where gnutls headers are too old.
---
dlls/bcrypt/gnutls.c | 15 +++++++++++++--
1 file changed, 13 insertions(+), 2 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 1c31b5625f..868f898bbb 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -86,13 +86,15 @@ static int (*pgnutls_privkey_export_rsa_raw)(gnutls_privkey_t, gnutls_datum_t *,
gnutls_datum_t *);
static int (*pgnutls_privkey_generate)(gnutls_privkey_t, gnutls_pk_algorithm_t, unsigned int, unsigned int);
+/* Not present in gnutls version < 3.6.0 */
+static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
+
static void *libgnutls_handle;
#define MAKE_FUNCPTR(f) static typeof(f) * p##f
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);
@@ -164,6 +166,11 @@ static int compat_gnutls_privkey_generate(gnutls_privkey_t key, gnutls_pk_algori
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
}
+static int compat_gnutls_decode_rs_value(const gnutls_datum_t * sig_value, gnutls_datum_t * r, gnutls_datum_t * s)
+{
+ return GNUTLS_E_INTERNAL_ERROR;
+}
+
static void gnutls_log( int level, const char *msg )
{
TRACE( "<%d> %s", level, msg );
@@ -190,7 +197,6 @@ 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)
@@ -259,6 +265,11 @@ BOOL gnutls_initialize(void)
WARN("gnutls_privkey_generate not found\n");
pgnutls_privkey_generate = compat_gnutls_privkey_generate;
}
+ if (!(pgnutls_decode_rs_value = wine_dlsym( libgnutls_handle, "gnutls_decode_rs_value", NULL, 0 )))
+ {
+ WARN("gnutls_decode_rs_value not found\n");
+ pgnutls_decode_rs_value = compat_gnutls_decode_rs_value;
+ }
if (TRACE_ON( bcrypt ))
{
--
2.24.0
Dec. 7, 2019
[PATCH 6/6] strmbase: Get rid of the "vtbl" argument to strmbase_source_init().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avico.c | 24 +---------------
dlls/qcap/avimux.c | 24 +---------------
dlls/qcap/smartteefilter.c | 48 ++-----------------------------
dlls/qcap/vfwcapture.c | 25 +---------------
dlls/qedit/samplegrabber.c | 24 +---------------
dlls/quartz/filesource.c | 26 +----------------
dlls/quartz/tests/videorenderer.c | 24 +---------------
dlls/quartz/tests/vmr7.c | 24 +---------------
dlls/quartz/tests/vmr9.c | 24 +---------------
dlls/strmbase/pin.c | 38 ++++++++++++++++++------
dlls/strmbase/transform.c | 26 +----------------
dlls/winegstreamer/gstdemux.c | 25 +---------------
dlls/wineqtdecoder/qtsplitter.c | 25 +---------------
include/wine/strmbase.h | 10 +------
14 files changed, 44 insertions(+), 323 deletions(-)
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c
index 9365c437b4f..debe6bca386 100644
--- a/dlls/qcap/avico.c
+++ b/dlls/qcap/avico.c
@@ -473,27 +473,6 @@ static const struct strmbase_sink_ops sink_ops =
.pfnReceive = AVICompressorIn_Receive,
};
-static const IPinVtbl AVICompressorOutputPinVtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static HRESULT source_get_media_type(struct strmbase_pin *base, unsigned int iPosition, AM_MEDIA_TYPE *amt)
{
AVICompressor *This = impl_from_strmbase_filter(base->filter);
@@ -564,8 +543,7 @@ IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr)
strmbase_sink_init(&compressor->sink, &AVICompressorInputPinVtbl,
&compressor->filter, sink_name, &sink_ops, NULL);
- strmbase_source_init(&compressor->source, &AVICompressorOutputPinVtbl,
- &compressor->filter, source_name, &source_ops);
+ strmbase_source_init(&compressor->source, &compressor->filter, source_name, &source_ops);
*phr = S_OK;
return &compressor->filter.IUnknown_inner;
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index 677e79ef68f..c344ab47266 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1217,27 +1217,6 @@ static const struct strmbase_source_ops source_ops =
.pfnDecideAllocator = AviMuxOut_DecideAllocator,
};
-static const IPinVtbl AviMuxOut_PinVtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static inline AviMux* impl_from_out_IQualityControl(IQualityControl *iface)
{
return CONTAINING_RECORD(iface, AviMux, IQualityControl_iface);
@@ -1923,8 +1902,7 @@ IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr)
info.dir = PINDIR_OUTPUT;
info.pFilter = &avimux->filter.IBaseFilter_iface;
lstrcpyW(info.achName, output_name);
- strmbase_source_init(&avimux->source, &AviMuxOut_PinVtbl, &avimux->filter,
- output_name, &source_ops);
+ strmbase_source_init(&avimux->source, &avimux->filter, output_name, &source_ops);
avimux->IQualityControl_iface.lpVtbl = &AviMuxOut_QualityControlVtbl;
avimux->cur_stream = 0;
avimux->cur_time = 0;
diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c
index 7762ec1e500..929929632f1 100644
--- a/dlls/qcap/smartteefilter.c
+++ b/dlls/qcap/smartteefilter.c
@@ -275,27 +275,6 @@ static const struct strmbase_sink_ops sink_ops =
.pfnReceive = SmartTeeFilterInput_Receive,
};
-static const IPinVtbl SmartTeeFilterCaptureVtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static HRESULT capture_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
{
FIXME("(%p) stub\n", base);
@@ -339,27 +318,6 @@ static const struct strmbase_source_ops capture_ops =
.pfnDecideAllocator = SmartTeeFilterCapture_DecideAllocator,
};
-static const IPinVtbl SmartTeeFilterPreviewVtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static HRESULT preview_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
{
FIXME("(%p) stub\n", base);
@@ -410,10 +368,8 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_source_init(&object->capture, &SmartTeeFilterCaptureVtbl,
- &object->filter, captureW, &capture_ops);
- strmbase_source_init(&object->preview, &SmartTeeFilterPreviewVtbl,
- &object->filter, previewW, &preview_ops);
+ strmbase_source_init(&object->capture, &object->filter, captureW, &capture_ops);
+ strmbase_source_init(&object->preview, &object->filter, previewW, &preview_ops);
*phr = S_OK;
return &object->filter.IUnknown_inner;
diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c
index e7522ea9b36..2185053ecd0 100644
--- a/dlls/qcap/vfwcapture.c
+++ b/dlls/qcap/vfwcapture.c
@@ -559,28 +559,6 @@ static const struct strmbase_source_ops source_ops =
.pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
};
-static const IPinVtbl VfwPin_Vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr)
{
static const WCHAR source_name[] = {'O','u','t','p','u','t',0};
@@ -599,8 +577,7 @@ IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr)
object->IPersistPropertyBag_iface.lpVtbl = &IPersistPropertyBag_VTable;
object->init = FALSE;
- strmbase_source_init(&object->source, &VfwPin_Vtbl, &object->filter,
- source_name, &source_ops);
+ strmbase_source_init(&object->source, &object->filter, source_name, &source_ops);
object->IKsPropertySet_iface.lpVtbl = &IKsPropertySet_VTable;
diff --git a/dlls/qedit/samplegrabber.c b/dlls/qedit/samplegrabber.c
index 019af5c35de..f8d90a5c0df 100644
--- a/dlls/qedit/samplegrabber.c
+++ b/dlls/qedit/samplegrabber.c
@@ -660,28 +660,6 @@ static const struct strmbase_source_ops source_ops =
.pfnAttemptConnection = sample_grabber_source_AttemptConnection,
};
-static const IPinVtbl source_vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment,
-};
-
HRESULT SampleGrabber_create(IUnknown *outer, void **out)
{
SG_Impl* obj = NULL;
@@ -700,7 +678,7 @@ HRESULT SampleGrabber_create(IUnknown *outer, void **out)
obj->IMemInputPin_iface.lpVtbl = &IMemInputPin_VTable;
strmbase_sink_init(&obj->sink, &sink_vtbl, &obj->filter, L"In", &sink_ops, NULL);
- strmbase_source_init(&obj->source, &source_vtbl, &obj->filter, L"Out", &source_ops);
+ strmbase_source_init(&obj->source, &obj->filter, L"Out", &source_ops);
obj->mtype.majortype = GUID_NULL;
obj->mtype.subtype = MEDIASUBTYPE_None;
diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c
index e841391e83a..fb8adb4a3fb 100644
--- a/dlls/quartz/filesource.c
+++ b/dlls/quartz/filesource.c
@@ -77,7 +77,6 @@ typedef struct AsyncReader
HANDLE *handle_list;
} AsyncReader;
-static const IPinVtbl FileAsyncReaderPin_Vtbl;
static const struct strmbase_source_ops source_ops;
static inline AsyncReader *impl_from_strmbase_filter(struct strmbase_filter *iface)
@@ -468,8 +467,7 @@ static HRESULT WINAPI FileSource_Load(IFileSourceFilter * iface, LPCOLESTR pszFi
return HRESULT_FROM_WIN32(GetLastError());
}
- strmbase_source_init(&This->source, &FileAsyncReaderPin_Vtbl, &This->filter,
- wszOutputPinName, &source_ops);
+ strmbase_source_init(&This->source, &This->filter, wszOutputPinName, &source_ops);
BaseFilterImpl_IncrementPinVersion(&This->filter);
This->file = hFile;
@@ -594,28 +592,6 @@ static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, vo
return S_OK;
}
-static const IPinVtbl FileAsyncReaderPin_Vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
/* Function called as a helper to IPin_Connect */
/* specific AM_MEDIA_TYPE - it cannot be NULL */
/* this differs from standard OutputPin_AttemptConnection only in that it
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index d4d9622b415..00a9041a8b4 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -521,28 +521,6 @@ static const struct strmbase_filter_ops testfilter_ops =
.filter_destroy = testfilter_destroy,
};
-static const IPinVtbl testsource_vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment,
-};
-
static HRESULT testsource_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
{
return S_OK;
@@ -579,7 +557,7 @@ static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
- strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
+ strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops);
}
static void test_allocator(IMemInputPin *input)
diff --git a/dlls/quartz/tests/vmr7.c b/dlls/quartz/tests/vmr7.c
index 008c84ab30f..dae86bd3fa9 100644
--- a/dlls/quartz/tests/vmr7.c
+++ b/dlls/quartz/tests/vmr7.c
@@ -881,28 +881,6 @@ static const struct strmbase_filter_ops testfilter_ops =
.filter_destroy = testfilter_destroy,
};
-static const IPinVtbl testsource_vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment,
-};
-
static HRESULT testsource_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
{
return S_OK;
@@ -939,7 +917,7 @@ static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
- strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
+ strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops);
}
static void test_allocator(IMemInputPin *input)
diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c
index fd6901d2117..5ece5c6f7bb 100644
--- a/dlls/quartz/tests/vmr9.c
+++ b/dlls/quartz/tests/vmr9.c
@@ -885,28 +885,6 @@ static const struct strmbase_filter_ops testfilter_ops =
.filter_destroy = testfilter_destroy,
};
-static const IPinVtbl testsource_vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment,
-};
-
static HRESULT testsource_query_accept(struct strmbase_pin *iface, const AM_MEDIA_TYPE *mt)
{
return S_OK;
@@ -943,7 +921,7 @@ static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
- strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
+ strmbase_source_init(&filter->source, &filter->filter, L"", &testsource_ops);
}
static void test_allocator(IMemInputPin *input)
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c
index bdc827c6f60..bcac22eb3c4 100644
--- a/dlls/strmbase/pin.c
+++ b/dlls/strmbase/pin.c
@@ -284,7 +284,7 @@ static inline struct strmbase_source *impl_source_from_IPin( IPin *iface )
return CONTAINING_RECORD(iface, struct strmbase_source, pin.IPin_iface);
}
-HRESULT WINAPI BaseOutputPinImpl_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
+static HRESULT WINAPI source_Connect(IPin *iface, IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{
HRESULT hr;
struct strmbase_source *This = impl_source_from_IPin(iface);
@@ -375,13 +375,13 @@ HRESULT WINAPI BaseOutputPinImpl_Connect(IPin * iface, IPin * pReceivePin, const
return hr;
}
-HRESULT WINAPI BaseOutputPinImpl_ReceiveConnection(IPin *iface, IPin *pin, const AM_MEDIA_TYPE *pmt)
+static HRESULT WINAPI source_ReceiveConnection(IPin *iface, IPin *pin, const AM_MEDIA_TYPE *pmt)
{
ERR("(%p)->(%p, %p) incoming connection on an output pin!\n", iface, pin, pmt);
return E_UNEXPECTED;
}
-HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin * iface)
+static HRESULT WINAPI source_Disconnect(IPin *iface)
{
HRESULT hr;
struct strmbase_source *This = impl_source_from_IPin(iface);
@@ -418,7 +418,7 @@ HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin * iface)
return hr;
}
-HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin * iface)
+static HRESULT WINAPI source_EndOfStream(IPin *iface)
{
TRACE("(%p)->()\n", iface);
@@ -427,7 +427,7 @@ HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin * iface)
return E_UNEXPECTED;
}
-HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin * iface)
+static HRESULT WINAPI source_BeginFlush(IPin *iface)
{
TRACE("(%p)->()\n", iface);
@@ -436,7 +436,7 @@ HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin * iface)
return E_UNEXPECTED;
}
-HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin * iface)
+static HRESULT WINAPI source_EndFlush(IPin *iface)
{
TRACE("(%p)->()\n", iface);
@@ -445,6 +445,28 @@ HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin * iface)
return E_UNEXPECTED;
}
+static const IPinVtbl source_vtbl =
+{
+ BasePinImpl_QueryInterface,
+ BasePinImpl_AddRef,
+ BasePinImpl_Release,
+ source_Connect,
+ source_ReceiveConnection,
+ source_Disconnect,
+ BasePinImpl_ConnectedTo,
+ BasePinImpl_ConnectionMediaType,
+ BasePinImpl_QueryPinInfo,
+ BasePinImpl_QueryDirection,
+ BasePinImpl_QueryId,
+ BasePinImpl_QueryAccept,
+ BasePinImpl_EnumMediaTypes,
+ BasePinImpl_QueryInternalConnections,
+ source_EndOfStream,
+ source_BeginFlush,
+ source_EndFlush,
+ BasePinImpl_NewSegment,
+};
+
HRESULT WINAPI BaseOutputPinImpl_GetDeliveryBuffer(struct strmbase_source *This,
IMediaSample **ppSample, REFERENCE_TIME *tStart, REFERENCE_TIME *tStop, DWORD dwFlags)
{
@@ -595,11 +617,11 @@ HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(struct strmbase_source *This,
return hr;
}
-void strmbase_source_init(struct strmbase_source *pin, const IPinVtbl *vtbl, struct strmbase_filter *filter,
+void strmbase_source_init(struct strmbase_source *pin, struct strmbase_filter *filter,
const WCHAR *name, const struct strmbase_source_ops *func_table)
{
memset(pin, 0, sizeof(*pin));
- pin->pin.IPin_iface.lpVtbl = vtbl;
+ pin->pin.IPin_iface.lpVtbl = &source_vtbl;
pin->pin.filter = filter;
pin->pin.dir = PINDIR_OUTPUT;
lstrcpyW(pin->pin.name, name);
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 5c079d38e76..7a79f709055 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -27,7 +27,6 @@ static const WCHAR wcsInputPinName[] = {'I','n',0};
static const WCHAR wcsOutputPinName[] = {'O','u','t',0};
static const IPinVtbl TransformFilter_InputPin_Vtbl;
-static const IPinVtbl TransformFilter_OutputPin_Vtbl;
static inline TransformFilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
{
@@ -338,8 +337,7 @@ static HRESULT strmbase_transform_init(IUnknown *outer, const CLSID *clsid,
strmbase_sink_init(&filter->sink, &TransformFilter_InputPin_Vtbl, &filter->filter,
wcsInputPinName, &sink_ops, NULL);
- strmbase_source_init(&filter->source, &TransformFilter_OutputPin_Vtbl, &filter->filter,
- wcsOutputPinName, &source_ops);
+ strmbase_source_init(&filter->source, &filter->filter, wcsOutputPinName, &source_ops);
filter->source_IQualityControl_iface.lpVtbl = &source_qc_vtbl;
filter->seekthru_unk = NULL;
@@ -503,25 +501,3 @@ static const IPinVtbl TransformFilter_InputPin_Vtbl =
TransformFilter_InputPin_EndFlush,
TransformFilter_InputPin_NewSegment
};
-
-static const IPinVtbl TransformFilter_OutputPin_Vtbl =
-{
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 04fb54915c6..e7d0313d7ce 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -97,7 +97,6 @@ const char* media_quark_string = "media-sample";
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 IQualityControlVtbl GSTOutPin_QualityControl_Vtbl;
@@ -1836,27 +1835,6 @@ static void free_source_pin(struct gstdemux_source *pin)
heap_free(pin);
}
-static const IPinVtbl GST_OutputPin_Vtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static const struct strmbase_source_ops source_ops =
{
.base.pin_query_interface = source_query_interface,
@@ -1879,8 +1857,7 @@ static struct gstdemux_source *create_pin(struct gstdemux *filter, const WCHAR *
if (!(pin = heap_alloc_zero(sizeof(*pin))))
return NULL;
- strmbase_source_init(&pin->pin, &GST_OutputPin_Vtbl, &filter->filter, name,
- &source_ops);
+ strmbase_source_init(&pin->pin, &filter->filter, name, &source_ops);
pin->caps_event = CreateEventW(NULL, FALSE, FALSE, NULL);
pin->segment = gst_segment_new();
gst_segment_init(pin->segment, GST_FORMAT_TIME);
diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index 2b05eefa8f4..03100c7a93e 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -171,7 +171,6 @@ typedef struct QTSplitter {
HANDLE splitterThread;
} QTSplitter;
-static const IPinVtbl QT_OutputPin_Vtbl;
static const IPinVtbl QT_InputPin_Vtbl;
static const IBaseFilterVtbl QT_Vtbl;
static const IMediaSeekingVtbl QT_Seeking_Vtbl;
@@ -1211,27 +1210,6 @@ static HRESULT WINAPI QTOutPin_DecideAllocator(struct strmbase_source *iface,
return hr;
}
-static const IPinVtbl QT_OutputPin_Vtbl = {
- BasePinImpl_QueryInterface,
- BasePinImpl_AddRef,
- BasePinImpl_Release,
- BaseOutputPinImpl_Connect,
- BaseOutputPinImpl_ReceiveConnection,
- BaseOutputPinImpl_Disconnect,
- BasePinImpl_ConnectedTo,
- BasePinImpl_ConnectionMediaType,
- BasePinImpl_QueryPinInfo,
- BasePinImpl_QueryDirection,
- BasePinImpl_QueryId,
- BasePinImpl_QueryAccept,
- BasePinImpl_EnumMediaTypes,
- BasePinImpl_QueryInternalConnections,
- BaseOutputPinImpl_EndOfStream,
- BaseOutputPinImpl_BeginFlush,
- BaseOutputPinImpl_EndFlush,
- BasePinImpl_NewSegment
-};
-
static inline QTOutPin *impl_from_IQualityControl( IQualityControl *iface )
{
return CONTAINING_RECORD(iface, QTOutPin, IQualityControl_iface);
@@ -1304,8 +1282,7 @@ static HRESULT QT_AddPin(QTSplitter *filter, const WCHAR *name,
else
filter->pAudio_Pin = pin;
- strmbase_source_init(&pin->pin, &QT_OutputPin_Vtbl, &filter->filter, name,
- &source_ops);
+ strmbase_source_init(&pin->pin, &filter->filter, name, &source_ops);
pin->pmt = CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE));
CopyMediaType(pin->pmt, mt);
pin->IQualityControl_iface.lpVtbl = &QTOutPin_QualityControl_Vtbl;
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 75eac504209..c3699f19253 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -113,14 +113,6 @@ HRESULT WINAPI BasePinImpl_EnumMediaTypes(IPin * iface, IEnumMediaTypes ** ppEnu
HRESULT WINAPI BasePinImpl_QueryInternalConnections(IPin * iface, IPin ** apPin, ULONG * cPin);
HRESULT WINAPI BasePinImpl_NewSegment(IPin * iface, REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate);
-/* Base Output Pin */
-HRESULT WINAPI BaseOutputPinImpl_Connect(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
-HRESULT WINAPI BaseOutputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt);
-HRESULT WINAPI BaseOutputPinImpl_Disconnect(IPin * iface);
-HRESULT WINAPI BaseOutputPinImpl_EndOfStream(IPin * iface);
-HRESULT WINAPI BaseOutputPinImpl_BeginFlush(IPin * iface);
-HRESULT WINAPI BaseOutputPinImpl_EndFlush(IPin * iface);
-
HRESULT WINAPI BaseOutputPinImpl_GetDeliveryBuffer(struct strmbase_source *pin,
IMediaSample **sample, REFERENCE_TIME *start, REFERENCE_TIME *stop, DWORD flags);
HRESULT WINAPI BaseOutputPinImpl_Active(struct strmbase_source *pin);
@@ -130,7 +122,7 @@ HRESULT WINAPI BaseOutputPinImpl_DecideAllocator(struct strmbase_source *pin, IM
HRESULT WINAPI BaseOutputPinImpl_AttemptConnection(struct strmbase_source *pin, IPin *peer, const AM_MEDIA_TYPE *mt);
void strmbase_source_cleanup(struct strmbase_source *pin);
-void strmbase_source_init(struct strmbase_source *pin, const IPinVtbl *vtbl, struct strmbase_filter *filter,
+void strmbase_source_init(struct strmbase_source *pin, struct strmbase_filter *filter,
const WCHAR *name, const struct strmbase_source_ops *func_table);
/* Base Input Pin */
--
2.23.0
Dec. 7, 2019
[PATCH 5/6] qcap/avimux: Use BaseOutputPinImpl_Connect().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avimux.c | 58 +++++++++++++++++-----------------------------
1 file changed, 21 insertions(+), 37 deletions(-)
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index d2f29dbbeb0..677e79ef68f 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1132,19 +1132,35 @@ static HRESULT source_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYP
return S_OK;
}
-static HRESULT WINAPI AviMuxOut_AttemptConnection(struct strmbase_source *base,
+static HRESULT WINAPI AviMuxOut_AttemptConnection(struct strmbase_source *iface,
IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{
+ AviMux *filter = impl_from_source_pin(&iface->pin);
PIN_DIRECTION dir;
+ unsigned int i;
HRESULT hr;
- TRACE("(%p)->(%p AM_MEDIA_TYPE(%p))\n", base, pReceivePin, pmt);
-
hr = IPin_QueryDirection(pReceivePin, &dir);
if(hr==S_OK && dir!=PINDIR_INPUT)
return VFW_E_INVALID_DIRECTION;
- return BaseOutputPinImpl_AttemptConnection(base, pReceivePin, pmt);
+ if (FAILED(hr = BaseOutputPinImpl_AttemptConnection(iface, pReceivePin, pmt)))
+ return hr;
+
+ for (i = 0; i < filter->input_pin_no; ++i)
+ {
+ if (!filter->in[i]->pin.pin.peer)
+ continue;
+
+ hr = IFilterGraph_Reconnect(filter->filter.filterInfo.pGraph, &filter->in[i]->pin.pin.IPin_iface);
+ if (FAILED(hr))
+ {
+ IPin_Disconnect(&iface->pin.IPin_iface);
+ break;
+ }
+ }
+
+ return hr;
}
static HRESULT source_get_media_type(struct strmbase_pin *base, unsigned int iPosition, AM_MEDIA_TYPE *amt)
@@ -1201,43 +1217,11 @@ static const struct strmbase_source_ops source_ops =
.pfnDecideAllocator = AviMuxOut_DecideAllocator,
};
-static inline AviMux *impl_from_out_IPin(IPin *iface)
-{
- return CONTAINING_RECORD(iface, AviMux, source.pin.IPin_iface);
-}
-
-static HRESULT WINAPI AviMuxOut_Connect(IPin *iface,
- IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
-{
- AviMux *This = impl_from_out_IPin(iface);
- HRESULT hr;
- int i;
-
- TRACE("(%p)->(%p AM_MEDIA_TYPE(%p))\n", This, pReceivePin, pmt);
-
- hr = BaseOutputPinImpl_Connect(iface, pReceivePin, pmt);
- if(FAILED(hr))
- return hr;
-
- for(i=0; i<This->input_pin_no; i++) {
- if(!This->in[i]->pin.pin.peer)
- continue;
-
- hr = IFilterGraph_Reconnect(This->filter.filterInfo.pGraph, &This->in[i]->pin.pin.IPin_iface);
- if(FAILED(hr)) {
- BaseOutputPinImpl_Disconnect(iface);
- break;
- }
- }
-
- return hr;
-}
-
static const IPinVtbl AviMuxOut_PinVtbl = {
BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
- AviMuxOut_Connect,
+ BaseOutputPinImpl_Connect,
BaseOutputPinImpl_ReceiveConnection,
BaseOutputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
--
2.23.0
Dec. 7, 2019
[PATCH 4/6] qcap/avimux: Use BaseOutputPinImpl_Disconnect().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avimux.c | 17 +----------------
1 file changed, 1 insertion(+), 16 deletions(-)
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index 645f0b7d5e4..d2f29dbbeb0 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1230,21 +1230,6 @@ static HRESULT WINAPI AviMuxOut_Connect(IPin *iface,
}
}
- if(hr == S_OK)
- IBaseFilter_AddRef(&This->filter.IBaseFilter_iface);
- return hr;
-}
-
-static HRESULT WINAPI AviMuxOut_Disconnect(IPin *iface)
-{
- AviMux *This = impl_from_out_IPin(iface);
- HRESULT hr;
-
- TRACE("(%p)\n", This);
-
- hr = BaseOutputPinImpl_Disconnect(iface);
- if(hr == S_OK)
- IBaseFilter_Release(&This->filter.IBaseFilter_iface);
return hr;
}
@@ -1254,7 +1239,7 @@ static const IPinVtbl AviMuxOut_PinVtbl = {
BasePinImpl_Release,
AviMuxOut_Connect,
BaseOutputPinImpl_ReceiveConnection,
- AviMuxOut_Disconnect,
+ BaseOutputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
--
2.23.0
Dec. 7, 2019
[PATCH 3/6] qcap/avimux: Use BasePinImpl_QueryInterface().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avimux.c | 94 +++++++++++++++++++++++-----------------------
1 file changed, 46 insertions(+), 48 deletions(-)
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index dc28104c80a..645f0b7d5e4 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1108,6 +1108,24 @@ static const ISpecifyPropertyPagesVtbl SpecifyPropertyPagesVtbl = {
SpecifyPropertyPages_GetPages
};
+static inline AviMux *impl_from_source_pin(struct strmbase_pin *iface)
+{
+ return CONTAINING_RECORD(iface, AviMux, source.pin);
+}
+
+static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
+{
+ AviMux *filter = impl_from_source_pin(iface);
+
+ if (IsEqualGUID(iid, &IID_IQualityControl))
+ *out = &filter->IQualityControl_iface;
+ else
+ return E_NOINTERFACE;
+
+ IUnknown_AddRef((IUnknown *)*out);
+ return S_OK;
+}
+
static HRESULT source_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
{
FIXME("(%p) stub\n", base);
@@ -1176,6 +1194,7 @@ static HRESULT WINAPI AviMuxOut_DecideAllocator(struct strmbase_source *base,
static const struct strmbase_source_ops source_ops =
{
+ .base.pin_query_interface = source_query_interface,
.base.pin_query_accept = source_query_accept,
.base.pin_get_media_type = source_get_media_type,
.pfnAttemptConnection = AviMuxOut_AttemptConnection,
@@ -1187,26 +1206,6 @@ static inline AviMux *impl_from_out_IPin(IPin *iface)
return CONTAINING_RECORD(iface, AviMux, source.pin.IPin_iface);
}
-static HRESULT WINAPI AviMuxOut_QueryInterface(IPin *iface, REFIID riid, void **ppv)
-{
- AviMux *This = impl_from_out_IPin(iface);
-
- TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
-
- if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPin))
- *ppv = iface;
- else if(IsEqualIID(riid, &IID_IQualityControl))
- *ppv = &This->IQualityControl_iface;
- else {
- FIXME("no interface for %s\n", debugstr_guid(riid));
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- IUnknown_AddRef((IUnknown*)*ppv);
- return S_OK;
-}
-
static HRESULT WINAPI AviMuxOut_Connect(IPin *iface,
IPin *pReceivePin, const AM_MEDIA_TYPE *pmt)
{
@@ -1250,7 +1249,7 @@ static HRESULT WINAPI AviMuxOut_Disconnect(IPin *iface)
}
static const IPinVtbl AviMuxOut_PinVtbl = {
- AviMuxOut_QueryInterface,
+ BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
AviMuxOut_Connect,
@@ -1321,6 +1320,30 @@ static const IQualityControlVtbl AviMuxOut_QualityControlVtbl = {
AviMuxOut_QualityControl_SetSink
};
+static inline AviMuxIn *impl_sink_from_strmbase_pin(struct strmbase_pin *iface)
+{
+ return CONTAINING_RECORD(iface, AviMuxIn, pin.pin.IPin_iface);
+}
+
+static HRESULT sink_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
+{
+ AviMuxIn *pin = impl_sink_from_strmbase_pin(iface);
+
+ if (IsEqualGUID(iid, &IID_IAMStreamControl))
+ *out = &pin->IAMStreamControl_iface;
+ else if (IsEqualGUID(iid, &IID_IMemInputPin))
+ *out = &pin->pin.IMemInputPin_iface;
+ else if (IsEqualGUID(iid, &IID_IPropertyBag))
+ *out = &pin->IPropertyBag_iface;
+ else if (IsEqualGUID(iid, &IID_IQualityControl))
+ *out = &pin->IQualityControl_iface;
+ else
+ return E_NOINTERFACE;
+
+ IUnknown_AddRef((IUnknown *)*out);
+ return S_OK;
+}
+
static HRESULT sink_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *pmt)
{
if(IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio) &&
@@ -1441,6 +1464,7 @@ static HRESULT WINAPI AviMuxIn_Receive(struct strmbase_sink *base, IMediaSample
static const struct strmbase_sink_ops sink_ops =
{
+ .base.pin_query_interface = sink_query_interface,
.base.pin_query_accept = sink_query_accept,
.base.pin_get_media_type = strmbase_pin_get_media_type,
.pfnReceive = AviMuxIn_Receive,
@@ -1457,32 +1481,6 @@ static inline AviMuxIn* AviMuxIn_from_IPin(IPin *iface)
return CONTAINING_RECORD(iface, AviMuxIn, pin.pin.IPin_iface);
}
-static HRESULT WINAPI AviMuxIn_QueryInterface(IPin *iface, REFIID riid, void **ppv)
-{
- AviMuxIn *avimuxin = AviMuxIn_from_IPin(iface);
-
- TRACE("pin %p, riid %s, ppv %p.\n", avimuxin, debugstr_guid(riid), ppv);
-
- if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IPin))
- *ppv = &avimuxin->pin.pin.IPin_iface;
- else if(IsEqualIID(riid, &IID_IAMStreamControl))
- *ppv = &avimuxin->IAMStreamControl_iface;
- else if(IsEqualIID(riid, &IID_IMemInputPin))
- *ppv = &avimuxin->pin.IMemInputPin_iface;
- else if(IsEqualIID(riid, &IID_IPropertyBag))
- *ppv = &avimuxin->IPropertyBag_iface;
- else if(IsEqualIID(riid, &IID_IQualityControl))
- *ppv = &avimuxin->IQualityControl_iface;
- else {
- FIXME("no interface for %s\n", debugstr_guid(riid));
- *ppv = NULL;
- return E_NOINTERFACE;
- }
-
- IUnknown_AddRef((IUnknown*)*ppv);
- return S_OK;
-}
-
static HRESULT WINAPI AviMuxIn_ReceiveConnection(IPin *iface,
IPin *pConnector, const AM_MEDIA_TYPE *pmt)
{
@@ -1576,7 +1574,7 @@ static HRESULT WINAPI AviMuxIn_Disconnect(IPin *iface)
}
static const IPinVtbl AviMuxIn_PinVtbl = {
- AviMuxIn_QueryInterface,
+ BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseInputPinImpl_Connect,
--
2.23.0
Dec. 7, 2019
[PATCH 2/6] wineqtdecoder: Use BasePinImpl_QueryInterface().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/wineqtdecoder/qtsplitter.c | 45 ++++++++++-----------------------
1 file changed, 13 insertions(+), 32 deletions(-)
diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index 5b1e82ebc9b..2b05eefa8f4 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -1140,15 +1140,7 @@ static const IPinVtbl QT_InputPin_Vtbl = {
QTInPin_NewSegment
};
-/*
- * Output Pin
- */
-static inline QTOutPin *impl_QTOutPin_from_IPin( IPin *iface )
-{
- return CONTAINING_RECORD(iface, QTOutPin, pin.pin.IPin_iface);
-}
-
-static inline QTOutPin *impl_sink_from_strmbase_pin(struct strmbase_pin *iface)
+static inline QTOutPin *impl_source_from_strmbase_pin(struct strmbase_pin *iface)
{
return CONTAINING_RECORD(iface, QTOutPin, pin.pin);
}
@@ -1158,30 +1150,19 @@ static inline QTOutPin *impl_QTOutPin_from_BaseOutputPin(struct strmbase_source
return CONTAINING_RECORD(iface, QTOutPin, pin);
}
-static HRESULT WINAPI QTOutPin_QueryInterface(IPin *iface, REFIID riid, void **ppv)
+static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
{
- QTOutPin *This = impl_QTOutPin_from_IPin(iface);
-
- TRACE("(%s, %p)\n", debugstr_guid(riid), ppv);
-
- *ppv = NULL;
+ QTOutPin *pin = impl_source_from_strmbase_pin(&iface->IPin_iface);
- if (IsEqualIID(riid, &IID_IUnknown))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IPin))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IMediaSeeking))
- *ppv = &This->sourceSeeking.IMediaSeeking_iface;
- else if (IsEqualIID(riid, &IID_IQualityControl))
- *ppv = &This->IQualityControl_iface;
+ if (IsEqualGUID(iid, &IID_IMediaSeeking))
+ *out = &pin->sourceSeeking.IMediaSeeking_iface;
+ else if (IsEqualGUID(iid, &IID_IQualityControl))
+ *out = &pin->IQualityControl_iface;
+ else
+ return E_NOINTERFACE;
- if (*ppv)
- {
- IUnknown_AddRef((IUnknown *)(*ppv));
- return S_OK;
- }
- FIXME("No interface for %s!\n", debugstr_guid(riid));
- return E_NOINTERFACE;
+ IUnknown_AddRef((IUnknown *)*out);
+ return S_OK;
}
static HRESULT source_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
@@ -1192,7 +1173,7 @@ static HRESULT source_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYP
static HRESULT source_get_media_type(struct strmbase_pin *iface, unsigned int iPosition, AM_MEDIA_TYPE *pmt)
{
- QTOutPin *This = impl_sink_from_strmbase_pin(iface);
+ QTOutPin *This = impl_source_from_strmbase_pin(iface);
if (iPosition > 0)
return VFW_S_NO_MORE_ITEMS;
@@ -1231,7 +1212,7 @@ static HRESULT WINAPI QTOutPin_DecideAllocator(struct strmbase_source *iface,
}
static const IPinVtbl QT_OutputPin_Vtbl = {
- QTOutPin_QueryInterface,
+ BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseOutputPinImpl_Connect,
--
2.23.0
Dec. 7, 2019
[PATCH 1/6] winegstreamer: Use BasePinImpl_QueryInterface().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/winegstreamer/gstdemux.c | 63 ++++++++---------------------------
1 file changed, 13 insertions(+), 50 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 78c8e38701a..04fb54915c6 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -1735,29 +1735,19 @@ static inline struct gstdemux_source *impl_source_from_IPin(IPin *iface)
return CONTAINING_RECORD(iface, struct gstdemux_source, pin.pin.IPin_iface);
}
-static HRESULT WINAPI GSTOutPin_QueryInterface(IPin *iface, REFIID riid, void **ppv)
+static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
{
- struct gstdemux_source *This = impl_source_from_IPin(iface);
+ struct gstdemux_source *pin = impl_source_from_IPin(&iface->IPin_iface);
- TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), ppv);
-
- *ppv = NULL;
-
- if (IsEqualIID(riid, &IID_IUnknown))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IPin))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IMediaSeeking))
- *ppv = &This->seek;
- else if (IsEqualIID(riid, &IID_IQualityControl))
- *ppv = &This->IQualityControl_iface;
+ if (IsEqualGUID(iid, &IID_IMediaSeeking))
+ *out = &pin->seek.IMediaSeeking_iface;
+ else if (IsEqualGUID(iid, &IID_IQualityControl))
+ *out = &pin->IQualityControl_iface;
+ else
+ return E_NOINTERFACE;
- if (*ppv) {
- IUnknown_AddRef((IUnknown *)(*ppv));
- return S_OK;
- }
- FIXME("No interface for %s!\n", debugstr_guid(riid));
- return E_NOINTERFACE;
+ IUnknown_AddRef((IUnknown *)*out);
+ return S_OK;
}
static HRESULT source_query_accept(struct strmbase_pin *base, const AM_MEDIA_TYPE *amt)
@@ -1847,7 +1837,7 @@ static void free_source_pin(struct gstdemux_source *pin)
}
static const IPinVtbl GST_OutputPin_Vtbl = {
- GSTOutPin_QueryInterface,
+ BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseOutputPinImpl_Connect,
@@ -1869,6 +1859,7 @@ static const IPinVtbl GST_OutputPin_Vtbl = {
static const struct strmbase_source_ops source_ops =
{
+ .base.pin_query_interface = source_query_interface,
.base.pin_query_accept = source_query_accept,
.base.pin_get_media_type = source_get_media_type,
.pfnAttemptConnection = BaseOutputPinImpl_AttemptConnection,
@@ -2071,36 +2062,8 @@ static HRESULT WINAPI GSTInPin_NewSegment(IPin *iface, REFERENCE_TIME start,
return S_OK;
}
-static HRESULT WINAPI GSTInPin_QueryInterface(IPin * iface, REFIID riid, LPVOID * ppv)
-{
- struct gstdemux *filter = impl_from_sink_IPin(iface);
-
- TRACE("filter %p, riid %s, ppv %p.\n", filter, debugstr_guid(riid), ppv);
-
- *ppv = NULL;
-
- if (IsEqualIID(riid, &IID_IUnknown))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IPin))
- *ppv = iface;
- else if (IsEqualIID(riid, &IID_IMediaSeeking))
- {
- return IBaseFilter_QueryInterface(&filter->filter.IBaseFilter_iface, &IID_IMediaSeeking, ppv);
- }
-
- if (*ppv)
- {
- IUnknown_AddRef((IUnknown *)(*ppv));
- return S_OK;
- }
-
- FIXME("No interface for %s!\n", debugstr_guid(riid));
-
- return E_NOINTERFACE;
-}
-
static const IPinVtbl GST_InputPin_Vtbl = {
- GSTInPin_QueryInterface,
+ BasePinImpl_QueryInterface,
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseInputPinImpl_Connect,
--
2.23.0
Dec. 7, 2019
Re: [PATCH v3 3/3] xmllite: Expand test for any unparsed data at end of XML.
by Nikolay Sivov
On 12/7/19 12:24 AM, Jeff Smith wrote:
> On Fri, Dec 6, 2019 at 11:16 AM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>> On 12/5/19 10:53 PM, Jeff Smith wrote:
>>> @@ -2662,7 +2663,7 @@ static HRESULT reader_parse_nextnode(xmlreader *reader)
>>> hr = reader_parse_misc(reader);
>>> if (hr != S_FALSE) return hr;
>>>
>>> - if (*reader_get_ptr(reader))
>>> + if (buffer->cur*sizeof(WCHAR) < buffer->written)
>>> {
>>> WARN("found garbage in the end of XML\n");
>>> return WC_E_SYNTAX;
> Hi Nikolay,
>
>> That means we don't have enough data,
> How do you figure that?
>
>> it's another change not backed by tests
> This fixes two tests, and does not break any others.
>
>> and potentially depending on current read-ahead buffer size/filled level.
> I'm pretty sure reader_parse_misc would have read at least one byte
> ahead, which is all that is required for this to trigger, though I
> could double-check that.
> However, to your point made in the patch 2 of the set about not
> exposing the buffer at this level, I will also consider this something
> that potentially needs to be handled elsewhere.
My point is that we should always hit this single invalid syntax/garbage
at the end condition that we already have,
instead of doing fixups for specific node types.
>
> Regards,
> Jeff
Dec. 6, 2019
[PATCH 3/3] kernel32/tests: Test invalid parent handle in test_parent_process_attribute().
by Paul Gofman
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
dlls/kernel32/tests/process.c | 87 ++++++++++++++++++++++++++++++++++-
1 file changed, 86 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 6d7a9a74c3..b8df8b8dce 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -3825,7 +3825,8 @@ static void test_ProcThreadAttributeList(void)
/* level 0: Main test process
* level 1: Process created by level 0 process without handle inheritance
* level 2: Process created by level 1 process with handle inheritance and level 0
- * process parent substitute. */
+ * process parent substitute.
+ * level 255: Process created by level 1 process during invalid parent handles testing. */
void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
{
PROCESS_BASIC_INFORMATION pbi;
@@ -3848,6 +3849,9 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
}
parent_data;
+ if (level == 255)
+ return;
+
if (!pInitializeProcThreadAttributeList)
{
win_skip("No support for ProcThreadAttributeList.\n");
@@ -3891,11 +3895,92 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
if (level)
{
+ HANDLE handle;
SIZE_T size;
ret = pInitializeProcThreadAttributeList(NULL, 1, 0, &size);
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+ sprintf(buffer, "\"%s\" tests/process.c parent %u %p %p", selfname, 255, read_pipe, NULL);
+
+#if 0
+ /* Crashes on some Windows installations, otherwise successfully creates process. */
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ CloseHandle(info.hThread);
+ CloseHandle(info.hProcess);
+#endif
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = INVALID_HANDLE_VALUE;
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ /* Broken on w7u/w8. */
+ ok((!ret && GetLastError() == ERROR_INVALID_HANDLE) || broken(ret),
+ "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ if (ret)
+ {
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ CloseHandle(info.hThread);
+ CloseHandle(info.hProcess);
+ }
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = (HANDLE)0xdeadbeef;
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = NULL;
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = GetCurrentProcess();
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ /* Broken on w7u/w8. */
+ ok((!ret && GetLastError() == ERROR_INVALID_HANDLE) || broken(ret),
+ "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ if (ret)
+ {
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ CloseHandle(info.hThread);
+ CloseHandle(info.hProcess);
+ }
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
si.lpAttributeList = heap_alloc(size);
ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
--
2.23.0
Dec. 6, 2019
[PATCH 2/3] ntdll: Support creating processes with specified parent.
by Paul Gofman
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47817
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
dlls/kernel32/tests/process.c | 4 ++--
dlls/ntdll/process.c | 11 +++++++++--
include/wine/server_protocol.h | 4 +++-
server/process.c | 30 ++++++++++++++++++++++++------
server/protocol.def | 1 +
server/request.h | 17 +++++++++--------
server/trace.c | 3 ++-
7 files changed, 50 insertions(+), 20 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 3efbfa2402..6d7a9a74c3 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -3874,14 +3874,14 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
memset(&parent_data, 0, sizeof(parent_data));
ret = ReadFile(read_pipe, &parent_data, sizeof(parent_data), &size, NULL);
- todo_wine_if(level == 2) ok((level == 2 && ret) || (level == 1 && !ret && GetLastError() == ERROR_INVALID_HANDLE),
+ ok((level == 2 && ret) || (level == 1 && !ret && GetLastError() == ERROR_INVALID_HANDLE),
"Got unexpected ret %#x, level %u, GetLastError() %u.\n",
ret, level, GetLastError());
}
if (level == 2)
{
- todo_wine ok(parent_id == parent_data.parent_id, "Got parent id %u, parent_data.parent_id %u.\n",
+ ok(parent_id == parent_data.parent_id, "Got parent id %u, parent_data.parent_id %u.\n",
parent_id, parent_data.parent_id);
return;
}
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index 52d7ea429e..5d75a27e97 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -1667,8 +1667,14 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
RtlNormalizeProcessParams( params );
- TRACE( "%s image %s cmdline %s\n", debugstr_us( path ),
- debugstr_us( ¶ms->ImagePathName ), debugstr_us( ¶ms->CommandLine ));
+ TRACE( "%s image %s cmdline %s, parent %p.\n", debugstr_us( path ),
+ debugstr_us( ¶ms->ImagePathName ), debugstr_us( ¶ms->CommandLine ), parent);
+
+ if (parent == INVALID_HANDLE_VALUE)
+ {
+ memset(info, 0, sizeof(*info));
+ return STATUS_INVALID_HANDLE;
+ }
if ((status = get_pe_file_info( path, attributes, &file_handle, &pe_info )))
{
@@ -1709,6 +1715,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
SERVER_START_REQ( new_process )
{
+ req->parent_process = wine_server_obj_handle(parent);
req->inherit_all = inherit;
req->create_flags = params->DebugFlags; /* hack: creation flags stored in DebugFlags for now */
req->socket_fd = socketfd[1];
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index aaa5fd2e33..98ecd98b08 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -769,6 +769,7 @@ struct rawinput_device
struct new_process_request
{
struct request_header __header;
+ obj_handle_t parent_process;
int inherit_all;
unsigned int create_flags;
int socket_fd;
@@ -779,6 +780,7 @@ struct new_process_request
/* VARARG(objattr,object_attributes); */
/* VARARG(info,startup_info,info_size); */
/* VARARG(env,unicode_str); */
+ char __pad_44[4];
};
struct new_process_reply
{
@@ -6702,6 +6704,6 @@ union generic_reply
struct resume_process_reply resume_process_reply;
};
-#define SERVER_PROTOCOL_VERSION 593
+#define SERVER_PROTOCOL_VERSION 594
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/process.c b/server/process.c
index 16bb5d57e7..195f54fa79 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1117,6 +1117,7 @@ DECL_HANDLER(new_process)
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
struct process *process = NULL;
struct process *parent = current->process;
+ struct thread *parent_thread = current;
int socket_fd = thread_get_inflight_fd( current, req->socket_fd );
if (socket_fd == -1)
@@ -1148,11 +1149,26 @@ DECL_HANDLER(new_process)
return;
}
+ if (req->parent_process)
+ {
+ if (!(parent = get_process_from_handle( req->parent_process, PROCESS_CREATE_PROCESS)))
+ {
+ set_error(STATUS_INVALID_HANDLE);
+ close(socket_fd);
+ return;
+ }
+ parent_thread = get_process_first_thread(parent);
+ }
+
if (parent->job && (req->create_flags & CREATE_BREAKAWAY_FROM_JOB) &&
!(parent->job->limit_flags & (JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)))
{
set_error( STATUS_ACCESS_DENIED );
close( socket_fd );
+
+ if (req->parent_process)
+ release_object(parent);
+
return;
}
@@ -1222,7 +1238,7 @@ DECL_HANDLER(new_process)
}
/* connect to the window station */
- connect_process_winstation( process, current );
+ connect_process_winstation( process, parent_thread );
/* set the process console */
if (!(req->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)))
@@ -1231,7 +1247,7 @@ DECL_HANDLER(new_process)
* like if hConOut and hConIn are console handles, then they should be on the same
* physical console
*/
- inherit_console( current, process, req->inherit_all ? info->data->hstdin : 0 );
+ inherit_console( parent_thread, process, req->inherit_all ? info->data->hstdin : 0 );
}
if (!req->inherit_all && !(req->create_flags & CREATE_NEW_CONSOLE))
@@ -1246,16 +1262,15 @@ DECL_HANDLER(new_process)
if (get_error() == STATUS_INVALID_HANDLE ||
get_error() == STATUS_OBJECT_TYPE_MISMATCH) clear_error();
}
-
/* attach to the debugger if requested */
if (req->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
{
set_process_debugger( process, current );
process->debug_children = !(req->create_flags & DEBUG_ONLY_THIS_PROCESS);
}
- else if (parent->debugger && parent->debug_children)
+ else if (current->process->debugger && current->process->debug_children)
{
- set_process_debugger( process, parent->debugger );
+ set_process_debugger( process, current->process->debugger );
/* debug_children is set to 1 by default */
}
@@ -1265,9 +1280,12 @@ DECL_HANDLER(new_process)
info->process = (struct process *)grab_object( process );
reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
reply->pid = get_process_id( process );
- reply->handle = alloc_handle_no_access_check( parent, process, req->access, objattr->attributes );
+ reply->handle = alloc_handle_no_access_check( current->process, process, req->access, objattr->attributes );
done:
+ if (req->parent_process)
+ release_object(parent);
+
if (process) release_object( process );
release_object( info );
}
diff --git a/server/protocol.def b/server/protocol.def
index 1cb1fea602..7f9ec3a149 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -783,6 +783,7 @@ struct rawinput_device
/* Create a new process from the context of the parent */
@REQ(new_process)
+ obj_handle_t parent_process; /* parent process */
int inherit_all; /* inherit all handles from parent */
unsigned int create_flags; /* creation flags */
int socket_fd; /* file descriptor for process socket */
diff --git a/server/request.h b/server/request.h
index 90a3180a6c..9f36bcb711 100644
--- a/server/request.h
+++ b/server/request.h
@@ -745,14 +745,15 @@ C_ASSERT( sizeof(unsigned char) == 1 );
C_ASSERT( sizeof(unsigned int) == 4 );
C_ASSERT( sizeof(unsigned short) == 2 );
C_ASSERT( sizeof(user_handle_t) == 4 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 12 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 16 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 20 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 24 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 28 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 32 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 36 );
-C_ASSERT( sizeof(struct new_process_request) == 40 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, parent_process) == 12 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 16 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 20 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 24 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 28 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 32 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 36 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 40 );
+C_ASSERT( sizeof(struct new_process_request) == 48 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, info) == 8 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, pid) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, handle) == 16 );
diff --git a/server/trace.c b/server/trace.c
index 411369a4f6..026aba9c50 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1243,7 +1243,8 @@ typedef void (*dump_func)( const void *req );
static void dump_new_process_request( const struct new_process_request *req )
{
- fprintf( stderr, " inherit_all=%d", req->inherit_all );
+ fprintf( stderr, " parent_process=%04x", req->parent_process );
+ fprintf( stderr, ", inherit_all=%d", req->inherit_all );
fprintf( stderr, ", create_flags=%08x", req->create_flags );
fprintf( stderr, ", socket_fd=%d", req->socket_fd );
fprintf( stderr, ", exe_file=%04x", req->exe_file );
--
2.23.0
Dec. 6, 2019
[PATCH 1/3] kernelbase: Support PROC_THREAD_ATTRIBUTE_PARENT_PROCESS in CreateProcessInternalW().
by Paul Gofman
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
dlls/kernelbase/process.c | 85 ++++++++++++++++++++++++++-------------
1 file changed, 56 insertions(+), 29 deletions(-)
diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c
index 90ea299416..ec034aa75d 100644
--- a/dlls/kernelbase/process.c
+++ b/dlls/kernelbase/process.c
@@ -244,7 +244,7 @@ static RTL_USER_PROCESS_PARAMETERS *create_process_params( const WCHAR *filename
*/
static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES *tsa,
BOOL inherit, DWORD flags, RTL_USER_PROCESS_PARAMETERS *params,
- RTL_USER_PROCESS_INFORMATION *info )
+ RTL_USER_PROCESS_INFORMATION *info, HANDLE parent )
{
NTSTATUS status;
UNICODE_STRING nameW;
@@ -257,7 +257,7 @@ static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES
status = RtlCreateUserProcess( &nameW, OBJ_CASE_INSENSITIVE, params,
psa ? psa->lpSecurityDescriptor : NULL,
tsa ? tsa->lpSecurityDescriptor : NULL,
- 0, inherit, 0, 0, info );
+ parent, inherit, 0, 0, info );
RtlFreeUnicodeString( &nameW );
}
return status;
@@ -288,7 +288,7 @@ static NTSTATUS create_vdm_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE
winevdm, params->ImagePathName.Buffer, params->CommandLine.Buffer );
RtlInitUnicodeString( ¶ms->ImagePathName, winevdm );
RtlInitUnicodeString( ¶ms->CommandLine, newcmdline );
- status = create_nt_process( psa, tsa, inherit, flags, params, info );
+ status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL );
HeapFree( GetProcessHeap(), 0, newcmdline );
return status;
}
@@ -316,7 +316,7 @@ static NTSTATUS create_cmd_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE
swprintf( newcmdline, len, L"%s /s/c \"%s\"", comspec, params->CommandLine.Buffer );
RtlInitUnicodeString( ¶ms->ImagePathName, comspec );
RtlInitUnicodeString( ¶ms->CommandLine, newcmdline );
- status = create_nt_process( psa, tsa, inherit, flags, params, info );
+ status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL );
RtlFreeHeap( GetProcessHeap(), 0, newcmdline );
return status;
}
@@ -368,7 +368,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW( HANDLE token, const WCHAR *a
inherit, flags, env, cur_dir, startup_info, info, NULL );
}
-
/**********************************************************************
* CreateProcessInternalA (kernelbase.@)
*/
@@ -382,7 +381,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalA( HANDLE token, const char *
BOOL ret = FALSE;
WCHAR *app_nameW = NULL, *cmd_lineW = NULL, *cur_dirW = NULL;
UNICODE_STRING desktopW, titleW;
- STARTUPINFOW infoW;
+ STARTUPINFOEXW infoW;
desktopW.Buffer = NULL;
titleW.Buffer = NULL;
@@ -393,12 +392,15 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalA( HANDLE token, const char *
if (startup_info->lpDesktop) RtlCreateUnicodeStringFromAsciiz( &desktopW, startup_info->lpDesktop );
if (startup_info->lpTitle) RtlCreateUnicodeStringFromAsciiz( &titleW, startup_info->lpTitle );
- memcpy( &infoW, startup_info, sizeof(infoW) );
- infoW.lpDesktop = desktopW.Buffer;
- infoW.lpTitle = titleW.Buffer;
+ memcpy( &infoW.StartupInfo, startup_info, sizeof(infoW.StartupInfo) );
+ infoW.StartupInfo.lpDesktop = desktopW.Buffer;
+ infoW.StartupInfo.lpTitle = titleW.Buffer;
+
+ if (flags & EXTENDED_STARTUPINFO_PRESENT)
+ infoW.lpAttributeList = ((STARTUPINFOEXW *)startup_info)->lpAttributeList;
ret = CreateProcessInternalW( token, app_nameW, cmd_lineW, process_attr, thread_attr,
- inherit, flags, env, cur_dirW, &infoW, info, new_token );
+ inherit, flags, env, cur_dirW, (STARTUPINFOW *)&infoW, info, new_token );
done:
RtlFreeHeap( GetProcessHeap(), 0, app_nameW );
RtlFreeHeap( GetProcessHeap(), 0, cmd_lineW );
@@ -408,6 +410,22 @@ done:
return ret;
}
+struct proc_thread_attr
+{
+ DWORD_PTR attr;
+ SIZE_T size;
+ void *value;
+};
+
+struct _PROC_THREAD_ATTRIBUTE_LIST
+{
+ DWORD mask; /* bitmask of items in list */
+ DWORD size; /* max number of items in list */
+ DWORD count; /* number of items in list */
+ DWORD pad;
+ DWORD_PTR unk;
+ struct proc_thread_attr attrs[1];
+};
/**********************************************************************
* CreateProcessInternalW (kernelbase.@)
@@ -423,6 +441,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
WCHAR *p, *tidy_cmdline = cmd_line;
RTL_USER_PROCESS_PARAMETERS *params = NULL;
RTL_USER_PROCESS_INFORMATION rtl_info;
+ HANDLE parent = NULL;
NTSTATUS status;
/* Process the AppName and/or CmdLine to get module name and path */
@@ -473,7 +492,33 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
goto done;
}
- status = create_nt_process( process_attr, thread_attr, inherit, flags, params, &rtl_info );
+ if (flags & EXTENDED_STARTUPINFO_PRESENT)
+ {
+ struct _PROC_THREAD_ATTRIBUTE_LIST *attrs =
+ (struct _PROC_THREAD_ATTRIBUTE_LIST *)((STARTUPINFOEXW *)startup_info)->lpAttributeList;
+ unsigned int i;
+
+ if (attrs)
+ {
+ for (i = 0; i < attrs->count; ++i)
+ {
+ switch(attrs->attrs[i].attr)
+ {
+ case PROC_THREAD_ATTRIBUTE_PARENT_PROCESS:
+ parent = *(HANDLE *)attrs->attrs[i].value;
+ TRACE("PROC_THREAD_ATTRIBUTE_PARENT_PROCESS parent %p.\n", parent);
+ if (!parent)
+ parent = INVALID_HANDLE_VALUE;
+ break;
+ default:
+ FIXME("Unsupported attribute %#lx.\n", attrs->attrs[i].attr);
+ break;
+ }
+ }
+ }
+ }
+
+ status = create_nt_process( process_attr, thread_attr, inherit, flags, params, &rtl_info, parent );
switch (status)
{
case STATUS_SUCCESS:
@@ -1301,24 +1346,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW( LPCWSTR name, LPCWSTR val
* Process/thread attribute lists
***********************************************************************/
-
-struct proc_thread_attr
-{
- DWORD_PTR attr;
- SIZE_T size;
- void *value;
-};
-
-struct _PROC_THREAD_ATTRIBUTE_LIST
-{
- DWORD mask; /* bitmask of items in list */
- DWORD size; /* max number of items in list */
- DWORD count; /* number of items in list */
- DWORD pad;
- DWORD_PTR unk;
- struct proc_thread_attr attrs[1];
-};
-
/***********************************************************************
* InitializeProcThreadAttributeList (kernelbase.@)
*/
--
2.23.0
Dec. 6, 2019
Re: [PATCH v3 3/3] xmllite: Expand test for any unparsed data at end of XML.
by Jeff Smith
On Fri, Dec 6, 2019 at 11:16 AM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>
> On 12/5/19 10:53 PM, Jeff Smith wrote:
> > @@ -2662,7 +2663,7 @@ static HRESULT reader_parse_nextnode(xmlreader *reader)
> > hr = reader_parse_misc(reader);
> > if (hr != S_FALSE) return hr;
> >
> > - if (*reader_get_ptr(reader))
> > + if (buffer->cur*sizeof(WCHAR) < buffer->written)
> > {
> > WARN("found garbage in the end of XML\n");
> > return WC_E_SYNTAX;
Hi Nikolay,
> That means we don't have enough data,
How do you figure that?
> it's another change not backed by tests
This fixes two tests, and does not break any others.
> and potentially depending on current read-ahead buffer size/filled level.
I'm pretty sure reader_parse_misc would have read at least one byte
ahead, which is all that is required for this to trigger, though I
could double-check that.
However, to your point made in the patch 2 of the set about not
exposing the buffer at this level, I will also consider this something
that potentially needs to be handled elsewhere.
Regards,
Jeff
Dec. 6, 2019
Re: [PATCH v3 2/3] xmllite: Whitespace node not returned when followed by invalid character.
by Jeff Smith
On Fri, Dec 6, 2019 at 11:13 AM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>
> On 12/5/19 10:53 PM, Jeff Smith wrote:
> > Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
> > ---
> > dlls/xmllite/reader.c | 12 ++++++++++--
> > dlls/xmllite/tests/reader.c | 2 --
> > 2 files changed, 10 insertions(+), 4 deletions(-)
> >
> > diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
> > index eddc4d8eec..79e5c2253a 100644
> > --- a/dlls/xmllite/reader.c
> > +++ b/dlls/xmllite/reader.c
> > @@ -1113,8 +1113,8 @@ static inline UINT reader_get_cur(xmlreader *reader)
> > static inline WCHAR *reader_get_ptr(xmlreader *reader)
> > {
> > encoded_buffer *buffer = &reader->input->buffer->utf16;
> > - WCHAR *ptr = (WCHAR*)buffer->data + buffer->cur;
> > - if (!*ptr) reader_more(reader);
> > + if (buffer->cur*sizeof(WCHAR) >= buffer->written)
> > + reader_more(reader);
> > return (WCHAR*)buffer->data + buffer->cur;
> > }
Hi Nikolay,
> Why do you need to change that? It's used everywhere.
Since the test is fixed even without this, I will probably take this
chunk out of this patch set.
> >
> > @@ -1714,8 +1714,16 @@ static HRESULT reader_parse_whitespace(xmlreader *reader)
> > {
> > strval value;
> > UINT start;
> > + const encoded_buffer *buffer = &reader->input->buffer->utf16;
> >
> > reader_skipspaces(reader);
> > +
> > + /* Do NOT return Whitespace node if followed by a character other than '<'.
> > + * The reader_skipspaces call should have already read in the character. */
> > + if (buffer->cur*sizeof(WCHAR) < buffer->written &&
> > + *reader_get_ptr2(reader, buffer->cur) != '<')
> > + return WC_E_SYNTAX;
> > +
> Buffer access should not be exposed like that.
OK, I will try to improve where that is handled. Though that could
potentially entail changing more things that are used everywhere.
Regards,
Jeff
Dec. 6, 2019
Winter is coming
by Alexandre Julliard
Folks,
As you are probably aware, we are now entering the code freeze season.
The plan is to start the code freeze after the next release, i.e. one
week from today. So if there are things you want to see in Wine 5.0, now
is the last moment to submit them...
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 6, 2019
[PATCH 3/3] wined3d: Unload resources in wined3d_device_uninit_3d().
by Henri Verbeet
Instead of in wined3d_device_delete_opengl_contexts_cs(), which is specific to
the GL backend.
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/device.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 90c08876505..0ae841d4e35 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -939,7 +939,6 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi
void wined3d_device_delete_opengl_contexts_cs(void *object)
{
- struct wined3d_resource *resource, *cursor;
struct wined3d_swapchain_gl *swapchain_gl;
struct wined3d_device *device = object;
struct wined3d_context_gl *context_gl;
@@ -949,12 +948,6 @@ void wined3d_device_delete_opengl_contexts_cs(void *object)
device_gl = wined3d_device_gl(device);
- LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
- {
- TRACE("Unloading resource %p.\n", resource);
- wined3d_cs_emit_unload_resource(device->cs, resource);
- }
-
LIST_FOR_EACH_ENTRY(shader, &device->shaders, struct wined3d_shader, shader_list_entry)
{
device->shader_backend->shader_destroy(shader);
@@ -1106,6 +1099,7 @@ static void device_free_sampler(struct wine_rb_entry *entry, void *context)
void wined3d_device_uninit_3d(struct wined3d_device *device)
{
BOOL no3d = device->wined3d->flags & WINED3D_NO3D;
+ struct wined3d_resource *resource, *cursor;
struct wined3d_rendertarget_view *view;
struct wined3d_texture *texture;
unsigned int i;
@@ -1145,6 +1139,12 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
wine_rb_clear(&device->samplers, device_free_sampler, NULL);
+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ TRACE("Unloading resource %p.\n", resource);
+ wined3d_cs_emit_unload_resource(device->cs, resource);
+ }
+
device->adapter->adapter_ops->adapter_uninit_3d(device);
device->d3d_initialized = FALSE;
@@ -5298,6 +5298,12 @@ HRESULT CDECL wined3d_device_reset(struct wined3d_device *device,
wined3d_cs_emit_reset_state(device->cs);
state_cleanup(&device->state);
+ LIST_FOR_EACH_ENTRY_SAFE(resource, cursor, &device->resources, struct wined3d_resource, resource_list_entry)
+ {
+ TRACE("Unloading resource %p.\n", resource);
+ wined3d_cs_emit_unload_resource(device->cs, resource);
+ }
+
if (device->d3d_initialized)
device->adapter->adapter_ops->adapter_uninit_3d(device);
--
2.11.0
Dec. 6, 2019
[PATCH 2/3] wined3d: Unload texture resources through texture ops.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 57 +-----------
dlls/wined3d/device.c | 3 +-
dlls/wined3d/texture.c | 200 +++++++++++++++++++++++++----------------
dlls/wined3d/wined3d_private.h | 3 +-
4 files changed, 125 insertions(+), 138 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 3408439660f..a8a8e93c0b2 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4746,61 +4746,6 @@ static HRESULT adapter_gl_create_texture(struct wined3d_device *device,
return hr;
}
-static void wined3d_texture_gl_destroy_object(void *object)
-{
- struct wined3d_renderbuffer_entry *entry, *entry2;
- struct wined3d_texture_gl *texture_gl = object;
- struct wined3d_context *context = NULL;
- const struct wined3d_gl_info *gl_info;
- struct wined3d_device *device;
- unsigned int sub_count, i;
- GLuint buffer_object;
-
- TRACE("texture_gl %p.\n", texture_gl);
-
- sub_count = texture_gl->t.level_count * texture_gl->t.layer_count;
- for (i = 0; i < sub_count; ++i)
- {
- if (!(buffer_object = texture_gl->t.sub_resources[i].buffer_object))
- continue;
-
- TRACE("Deleting buffer object %u.\n", buffer_object);
-
- if (!context)
- {
- context = context_acquire(texture_gl->t.resource.device, NULL, 0);
- gl_info = wined3d_context_gl(context)->gl_info;
- }
-
- GL_EXTCALL(glDeleteBuffers(1, &buffer_object));
- }
-
- if (!list_empty(&texture_gl->renderbuffers))
- {
- device = texture_gl->t.resource.device;
- if (!context)
- {
- context = context_acquire(device, NULL, 0);
- gl_info = wined3d_context_gl(context)->gl_info;
- }
-
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers, struct wined3d_renderbuffer_entry, entry)
- {
- TRACE("Deleting renderbuffer %u.\n", entry->id);
- context_gl_resource_released(device, entry->id, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
- heap_free(entry);
- }
- }
-
- if (context)
- context_release(context);
-
- wined3d_texture_gl_unload_texture(texture_gl);
-
- heap_free(texture_gl);
-}
-
static void adapter_gl_destroy_texture(struct wined3d_texture *texture)
{
struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture);
@@ -4820,7 +4765,7 @@ static void adapter_gl_destroy_texture(struct wined3d_texture *texture)
texture->resource.parent_ops->wined3d_object_destroyed(texture->resource.parent);
wined3d_texture_cleanup(&texture_gl->t);
- wined3d_cs_destroy_object(device->cs, wined3d_texture_gl_destroy_object, texture_gl);
+ wined3d_cs_destroy_object(device->cs, heap_free, texture_gl);
if (swapchain_count)
wined3d_device_decref(device);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index 98559e4f6c6..90c08876505 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -1146,6 +1146,7 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
wine_rb_clear(&device->samplers, device_free_sampler, NULL);
device->adapter->adapter_ops->adapter_uninit_3d(device);
+ device->d3d_initialized = FALSE;
if ((view = device->fb.depth_stencil))
{
@@ -1170,8 +1171,6 @@ void wined3d_device_uninit_3d(struct wined3d_device *device)
heap_free(device->swapchains);
device->swapchains = NULL;
-
- device->d3d_initialized = FALSE;
}
/* Enables thread safety in the wined3d device and its resources. Called by DirectDraw
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 1c315a1dd77..7c9c8298519 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -636,51 +636,6 @@ static void wined3d_texture_gl_allocate_immutable_storage(struct wined3d_texture
checkGLcall("allocate immutable storage");
}
-void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl)
-{
- struct wined3d_device *device = texture_gl->t.resource.device;
- const struct wined3d_gl_info *gl_info = NULL;
- struct wined3d_context *context = NULL;
-
- if (texture_gl->t.resource.bind_count)
- device_invalidate_state(device, STATE_SAMPLER(texture_gl->t.sampler));
-
- if (texture_gl->texture_rgb.name || texture_gl->texture_srgb.name
- || texture_gl->rb_multisample || texture_gl->rb_resolved)
- {
- context = context_acquire(device, NULL, 0);
- gl_info = wined3d_context_gl(context)->gl_info;
- }
-
- if (texture_gl->texture_rgb.name)
- gltexture_delete(device, gl_info, &texture_gl->texture_rgb);
-
- if (texture_gl->texture_srgb.name)
- gltexture_delete(device, gl_info, &texture_gl->texture_srgb);
-
- if (texture_gl->rb_multisample)
- {
- TRACE("Deleting multisample renderbuffer %u.\n", texture_gl->rb_multisample);
- context_gl_resource_released(device, texture_gl->rb_multisample, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_multisample);
- texture_gl->rb_multisample = 0;
- }
-
- if (texture_gl->rb_resolved)
- {
- TRACE("Deleting resolved renderbuffer %u.\n", texture_gl->rb_resolved);
- context_gl_resource_released(device, texture_gl->rb_resolved, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_resolved);
- texture_gl->rb_resolved = 0;
- }
-
- if (context) context_release(context);
-
- wined3d_texture_set_dirty(&texture_gl->t);
-
- resource_unload(&texture_gl->t.resource);
-}
-
void wined3d_texture_sub_resources_destroyed(struct wined3d_texture *texture)
{
unsigned int sub_count = texture->level_count * texture->layer_count;
@@ -1119,12 +1074,14 @@ ULONG CDECL wined3d_texture_incref(struct wined3d_texture *texture)
static void wined3d_texture_destroy_object(void *object)
{
struct wined3d_texture *texture = object;
+ struct wined3d_resource *resource;
struct wined3d_dc_info *dc_info;
unsigned int sub_count;
unsigned int i;
TRACE("texture %p.\n", texture);
+ resource = &texture->resource;
sub_count = texture->level_count * texture->layer_count;
if ((dc_info = texture->dc_info))
@@ -1156,12 +1113,14 @@ static void wined3d_texture_destroy_object(void *object)
}
heap_free(texture->overlay_info);
}
+
+ resource->resource_ops->resource_unload(resource);
}
void wined3d_texture_cleanup(struct wined3d_texture *texture)
{
- resource_cleanup(&texture->resource);
wined3d_cs_destroy_object(texture->resource.device->cs, wined3d_texture_destroy_object, texture);
+ resource_cleanup(&texture->resource);
}
static void wined3d_texture_cleanup_sync(struct wined3d_texture *texture)
@@ -1789,6 +1748,12 @@ BOOL wined3d_texture_prepare_location(struct wined3d_texture *texture,
return texture->texture_ops->texture_prepare_location(texture, sub_resource_idx, context, location);
}
+static void wined3d_texture_unload_location(struct wined3d_texture *texture,
+ struct wined3d_context *context, unsigned int location)
+{
+ texture->texture_ops->texture_unload_location(texture, context, location);
+}
+
static struct wined3d_texture_sub_resource *wined3d_texture_get_sub_resource(struct wined3d_texture *texture,
unsigned int sub_resource_idx)
{
@@ -2903,10 +2868,79 @@ static BOOL wined3d_texture_gl_load_location(struct wined3d_texture *texture,
}
}
+static void wined3d_texture_gl_unload_location(struct wined3d_texture *texture,
+ struct wined3d_context *context, unsigned int location)
+{
+ struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture);
+ struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
+ struct wined3d_renderbuffer_entry *entry, *entry2;
+ unsigned int i, sub_count;
+
+ TRACE("texture %p, context %p, location %s.\n", texture, context, wined3d_debug_location(location));
+
+ switch (location)
+ {
+ case WINED3D_LOCATION_BUFFER:
+ sub_count = texture->level_count * texture->layer_count;
+ for (i = 0; i < sub_count; ++i)
+ {
+ if (texture_gl->t.sub_resources[i].buffer_object)
+ wined3d_texture_remove_buffer_object(&texture_gl->t, i, context_gl->gl_info);
+ }
+ break;
+
+ case WINED3D_LOCATION_TEXTURE_RGB:
+ if (texture_gl->texture_rgb.name)
+ gltexture_delete(texture_gl->t.resource.device, context_gl->gl_info, &texture_gl->texture_rgb);
+ break;
+
+ case WINED3D_LOCATION_TEXTURE_SRGB:
+ if (texture_gl->texture_srgb.name)
+ gltexture_delete(texture_gl->t.resource.device, context_gl->gl_info, &texture_gl->texture_srgb);
+ break;
+
+ case WINED3D_LOCATION_RB_MULTISAMPLE:
+ if (texture_gl->rb_multisample)
+ {
+ TRACE("Deleting multisample renderbuffer %u.\n", texture_gl->rb_multisample);
+ context_gl_resource_released(texture_gl->t.resource.device, texture_gl->rb_multisample, TRUE);
+ context_gl->gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_multisample);
+ texture_gl->rb_multisample = 0;
+ }
+ break;
+
+ case WINED3D_LOCATION_RB_RESOLVED:
+ LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers,
+ struct wined3d_renderbuffer_entry, entry)
+ {
+ context_gl_resource_released(texture_gl->t.resource.device, entry->id, TRUE);
+ context_gl->gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
+ list_remove(&entry->entry);
+ heap_free(entry);
+ }
+ list_init(&texture_gl->renderbuffers);
+ texture_gl->current_renderbuffer = NULL;
+
+ if (texture_gl->rb_resolved)
+ {
+ TRACE("Deleting resolved renderbuffer %u.\n", texture_gl->rb_resolved);
+ context_gl_resource_released(texture_gl->t.resource.device, texture_gl->rb_resolved, TRUE);
+ context_gl->gl_info->fbo_ops.glDeleteRenderbuffers(1, &texture_gl->rb_resolved);
+ texture_gl->rb_resolved = 0;
+ }
+ break;
+
+ default:
+ ERR("Unhandled location %s.\n", wined3d_debug_location(location));
+ break;
+ }
+}
+
static const struct wined3d_texture_ops texture_gl_ops =
{
wined3d_texture_gl_prepare_location,
wined3d_texture_gl_load_location,
+ wined3d_texture_gl_unload_location,
wined3d_texture_gl_upload_data,
wined3d_texture_gl_download_data,
};
@@ -2936,65 +2970,59 @@ static void texture_resource_preload(struct wined3d_resource *resource)
context_release(context);
}
-static void wined3d_texture_gl_unload(struct wined3d_resource *resource)
+static void texture_resource_unload(struct wined3d_resource *resource)
{
- struct wined3d_texture_gl *texture_gl = wined3d_texture_gl(texture_from_resource(resource));
- UINT sub_count = texture_gl->t.level_count * texture_gl->t.layer_count;
- struct wined3d_renderbuffer_entry *entry, *entry2;
+ struct wined3d_texture *texture = texture_from_resource(resource);
struct wined3d_device *device = resource->device;
unsigned int location = resource->map_binding;
- const struct wined3d_gl_info *gl_info;
struct wined3d_context *context;
- UINT i;
+ unsigned int sub_count, i;
+
+ TRACE("resource %p.\n", resource);
- TRACE("texture_gl %p.\n", texture_gl);
+ /* D3D is not initialised, so no GPU locations should currently exist.
+ * Moreover, we may not be able to acquire a valid context. */
+ if (!device->d3d_initialized)
+ return;
context = context_acquire(device, NULL, 0);
- gl_info = wined3d_context_gl(context)->gl_info;
if (location == WINED3D_LOCATION_BUFFER)
location = WINED3D_LOCATION_SYSMEM;
+ sub_count = texture->level_count * texture->layer_count;
for (i = 0; i < sub_count; ++i)
{
- struct wined3d_texture_sub_resource *sub_resource = &texture_gl->t.sub_resources[i];
-
if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
- && wined3d_texture_load_location(&texture_gl->t, i, context, location))
+ && wined3d_texture_load_location(texture, i, context, location))
{
- wined3d_texture_invalidate_location(&texture_gl->t, i, ~location);
+ wined3d_texture_invalidate_location(texture, i, ~location);
}
else
{
- /* We should only get here on device reset/teardown for implicit
- * resources. */
- if (resource->access & WINED3D_RESOURCE_ACCESS_CPU
- || resource->type != WINED3D_RTYPE_TEXTURE_2D)
+ if (resource->access & WINED3D_RESOURCE_ACCESS_CPU)
ERR("Discarding %s %p sub-resource %u with resource access %s.\n",
debug_d3dresourcetype(resource->type), resource, i,
wined3d_debug_resource_access(resource->access));
- wined3d_texture_validate_location(&texture_gl->t, i, WINED3D_LOCATION_DISCARDED);
- wined3d_texture_invalidate_location(&texture_gl->t, i, ~WINED3D_LOCATION_DISCARDED);
+ wined3d_texture_validate_location(texture, i, WINED3D_LOCATION_DISCARDED);
+ wined3d_texture_invalidate_location(texture, i, ~WINED3D_LOCATION_DISCARDED);
}
-
- if (sub_resource->buffer_object)
- wined3d_texture_remove_buffer_object(&texture_gl->t, i, gl_info);
}
- LIST_FOR_EACH_ENTRY_SAFE(entry, entry2, &texture_gl->renderbuffers, struct wined3d_renderbuffer_entry, entry)
- {
- context_gl_resource_released(device, entry->id, TRUE);
- gl_info->fbo_ops.glDeleteRenderbuffers(1, &entry->id);
- list_remove(&entry->entry);
- heap_free(entry);
- }
- list_init(&texture_gl->renderbuffers);
- texture_gl->current_renderbuffer = NULL;
+ wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_BUFFER);
+ wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_TEXTURE_RGB);
+ wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_TEXTURE_SRGB);
+ wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_RB_MULTISAMPLE);
+ wined3d_texture_unload_location(texture, context, WINED3D_LOCATION_RB_RESOLVED);
context_release(context);
- wined3d_texture_force_reload(&texture_gl->t);
- wined3d_texture_gl_unload_texture(texture_gl);
+ wined3d_texture_force_reload(texture);
+ if (texture->resource.bind_count)
+ device_invalidate_state(device, STATE_SAMPLER(texture->sampler));
+ wined3d_texture_set_dirty(texture);
+
+ resource_unload(&texture->resource);
}
static HRESULT texture_resource_sub_resource_map(struct wined3d_resource *resource, unsigned int sub_resource_idx,
@@ -3177,7 +3205,7 @@ static const struct wined3d_resource_ops texture_resource_ops =
texture_resource_incref,
texture_resource_decref,
texture_resource_preload,
- wined3d_texture_gl_unload,
+ texture_resource_unload,
texture_resource_sub_resource_map,
texture_resource_sub_resource_unmap,
};
@@ -4088,10 +4116,17 @@ static BOOL wined3d_texture_no3d_load_location(struct wined3d_texture *texture,
return FALSE;
}
+static void wined3d_texture_no3d_unload_location(struct wined3d_texture *texture,
+ struct wined3d_context *context, unsigned int location)
+{
+ TRACE("texture %p, context %p, location %s.\n", texture, context, wined3d_debug_location(location));
+}
+
static const struct wined3d_texture_ops wined3d_texture_no3d_ops =
{
wined3d_texture_no3d_prepare_location,
wined3d_texture_no3d_load_location,
+ wined3d_texture_no3d_unload_location,
wined3d_texture_no3d_upload_data,
wined3d_texture_no3d_download_data,
};
@@ -4158,10 +4193,17 @@ static BOOL wined3d_texture_vk_load_location(struct wined3d_texture *texture,
return FALSE;
}
+static void wined3d_texture_vk_unload_location(struct wined3d_texture *texture,
+ struct wined3d_context *context, unsigned int location)
+{
+ FIXME("texture %p, context %p, location %s.\n", texture, context, wined3d_debug_location(location));
+}
+
static const struct wined3d_texture_ops wined3d_texture_vk_ops =
{
wined3d_texture_vk_prepare_location,
wined3d_texture_vk_load_location,
+ wined3d_texture_vk_unload_location,
wined3d_texture_vk_upload_data,
wined3d_texture_vk_download_data,
};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 7d3b709a974..8f9ad1ce856 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3470,6 +3470,8 @@ struct wined3d_texture_ops
struct wined3d_context *context, unsigned int location);
BOOL (*texture_load_location)(struct wined3d_texture *texture, unsigned int sub_resource_idx,
struct wined3d_context *context, unsigned int location);
+ void (*texture_unload_location)(struct wined3d_texture *texture,
+ struct wined3d_context *context, unsigned int location);
void (*texture_upload_data)(struct wined3d_context *context, const struct wined3d_const_bo_address *src_bo_addr,
const struct wined3d_format *src_format, const struct wined3d_box *src_box, unsigned int src_row_pitch,
unsigned int src_slice_pitch, struct wined3d_texture *dst_texture, unsigned int dst_sub_resource_idx,
@@ -3745,7 +3747,6 @@ void wined3d_texture_gl_prepare_texture(struct wined3d_texture_gl *texture_gl,
void wined3d_texture_gl_set_compatible_renderbuffer(struct wined3d_texture_gl *texture_gl,
struct wined3d_context_gl *context_gl, unsigned int level,
const struct wined3d_rendertarget_info *rt) DECLSPEC_HIDDEN;
-void wined3d_texture_gl_unload_texture(struct wined3d_texture_gl *texture_gl) DECLSPEC_HIDDEN;
struct wined3d_texture_vk
{
--
2.11.0
Dec. 6, 2019
[PATCH 1/3] wined3d: Unload buffer resources through buffer ops.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 17 +-----------
dlls/wined3d/buffer.c | 59 +++++++++++++++++++++++++++++++++++++-----
dlls/wined3d/wined3d_private.h | 4 +--
3 files changed, 55 insertions(+), 25 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index eb9965723a2..3408439660f 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4699,21 +4699,6 @@ static HRESULT adapter_gl_create_buffer(struct wined3d_device *device,
return hr;
}
-static void wined3d_buffer_gl_destroy_object(void *object)
-{
- struct wined3d_buffer_gl *buffer_gl = object;
- struct wined3d_context *context;
-
- if (buffer_gl->b.buffer_object)
- {
- context = context_acquire(buffer_gl->b.resource.device, NULL, 0);
- wined3d_buffer_gl_destroy_buffer_object(buffer_gl, wined3d_context_gl(context));
- context_release(context);
- }
-
- heap_free(buffer_gl);
-}
-
static void adapter_gl_destroy_buffer(struct wined3d_buffer *buffer)
{
struct wined3d_buffer_gl *buffer_gl = wined3d_buffer_gl(buffer);
@@ -4729,7 +4714,7 @@ static void adapter_gl_destroy_buffer(struct wined3d_buffer *buffer)
if (swapchain_count)
wined3d_device_incref(device);
wined3d_buffer_cleanup(&buffer_gl->b);
- wined3d_cs_destroy_object(device->cs, wined3d_buffer_gl_destroy_object, buffer_gl);
+ wined3d_cs_destroy_object(device->cs, heap_free, buffer_gl);
if (swapchain_count)
wined3d_device_decref(device);
}
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 95fcdff7ef0..89dab8ebfdd 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -139,7 +139,7 @@ static void wined3d_buffer_gl_bind(struct wined3d_buffer_gl *buffer_gl, struct w
}
/* Context activation is done by the caller. */
-void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *buffer_gl,
+static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *buffer_gl,
struct wined3d_context_gl *context_gl)
{
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
@@ -602,6 +602,12 @@ static BOOL wined3d_buffer_prepare_location(struct wined3d_buffer *buffer,
return buffer->buffer_ops->buffer_prepare_location(buffer, context, location);
}
+static void wined3d_buffer_unload_location(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, unsigned int location)
+{
+ buffer->buffer_ops->buffer_unload_location(buffer, context, location);
+}
+
BOOL wined3d_buffer_load_location(struct wined3d_buffer *buffer,
struct wined3d_context *context, DWORD location)
{
@@ -699,7 +705,7 @@ DWORD wined3d_buffer_get_memory(struct wined3d_buffer *buffer,
return 0;
}
-static void buffer_unload(struct wined3d_resource *resource)
+static void buffer_resource_unload(struct wined3d_resource *resource)
{
struct wined3d_buffer *buffer = buffer_from_resource(resource);
@@ -713,7 +719,7 @@ static void buffer_unload(struct wined3d_resource *resource)
wined3d_buffer_load_location(buffer, context, WINED3D_LOCATION_SYSMEM);
wined3d_buffer_invalidate_location(buffer, WINED3D_LOCATION_BUFFER);
- wined3d_buffer_gl_destroy_buffer_object(wined3d_buffer_gl(buffer), wined3d_context_gl(context));
+ wined3d_buffer_unload_location(buffer, context, WINED3D_LOCATION_BUFFER);
buffer_clear_dirty_areas(buffer);
context_release(context);
@@ -731,21 +737,28 @@ static void buffer_unload(struct wined3d_resource *resource)
static void wined3d_buffer_drop_bo(struct wined3d_buffer *buffer)
{
buffer->flags &= ~WINED3D_BUFFER_USE_BO;
- buffer_unload(&buffer->resource);
+ buffer_resource_unload(&buffer->resource);
}
static void wined3d_buffer_destroy_object(void *object)
{
struct wined3d_buffer *buffer = object;
+ struct wined3d_context *context;
+ if (buffer->buffer_object)
+ {
+ context = context_acquire(buffer->resource.device, NULL, 0);
+ wined3d_buffer_unload_location(buffer, context, WINED3D_LOCATION_BUFFER);
+ context_release(context);
+ }
heap_free(buffer->conversion_map);
heap_free(buffer->maps);
}
void wined3d_buffer_cleanup(struct wined3d_buffer *buffer)
{
- resource_cleanup(&buffer->resource);
wined3d_cs_destroy_object(buffer->resource.device->cs, wined3d_buffer_destroy_object, buffer);
+ resource_cleanup(&buffer->resource);
}
ULONG CDECL wined3d_buffer_decref(struct wined3d_buffer *buffer)
@@ -1264,7 +1277,7 @@ static const struct wined3d_resource_ops buffer_resource_ops =
buffer_resource_incref,
buffer_resource_decref,
buffer_resource_preload,
- buffer_unload,
+ buffer_resource_unload,
buffer_resource_sub_resource_map,
buffer_resource_sub_resource_unmap,
};
@@ -1382,7 +1395,7 @@ static HRESULT wined3d_buffer_init(struct wined3d_buffer *buffer, struct wined3d
if (!(buffer->maps = heap_alloc(sizeof(*buffer->maps))))
{
ERR("Out of memory.\n");
- buffer_unload(resource);
+ buffer_resource_unload(resource);
resource_cleanup(resource);
wined3d_resource_wait_idle(resource);
return E_OUTOFMEMORY;
@@ -1406,6 +1419,12 @@ static BOOL wined3d_buffer_no3d_prepare_location(struct wined3d_buffer *buffer,
return FALSE;
}
+static void wined3d_buffer_no3d_unload_location(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, unsigned int location)
+{
+ TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
+}
+
static void wined3d_buffer_no3d_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context,
const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges)
{
@@ -1421,6 +1440,7 @@ static void wined3d_buffer_no3d_download_ranges(struct wined3d_buffer *buffer, s
static const struct wined3d_buffer_ops wined3d_buffer_no3d_ops =
{
wined3d_buffer_no3d_prepare_location,
+ wined3d_buffer_no3d_unload_location,
wined3d_buffer_no3d_upload_ranges,
wined3d_buffer_no3d_download_ranges,
};
@@ -1463,6 +1483,23 @@ static BOOL wined3d_buffer_gl_prepare_location(struct wined3d_buffer *buffer,
}
}
+static void wined3d_buffer_gl_unload_location(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, unsigned int location)
+{
+ TRACE("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
+
+ switch (location)
+ {
+ case WINED3D_LOCATION_BUFFER:
+ wined3d_buffer_gl_destroy_buffer_object(wined3d_buffer_gl(buffer), wined3d_context_gl(context));
+ break;
+
+ default:
+ ERR("Unhandled location %s.\n", wined3d_debug_location(location));
+ break;
+ }
+}
+
/* Context activation is done by the caller. */
static void wined3d_buffer_gl_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context,
const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges)
@@ -1506,6 +1543,7 @@ static void wined3d_buffer_gl_download_ranges(struct wined3d_buffer *buffer, str
static const struct wined3d_buffer_ops wined3d_buffer_gl_ops =
{
wined3d_buffer_gl_prepare_location,
+ wined3d_buffer_gl_unload_location,
wined3d_buffer_gl_upload_ranges,
wined3d_buffer_gl_download_ranges,
};
@@ -1542,6 +1580,12 @@ static BOOL wined3d_buffer_vk_prepare_location(struct wined3d_buffer *buffer,
}
}
+static void wined3d_buffer_vk_unload_location(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, unsigned int location)
+{
+ FIXME("buffer %p, context %p, location %s.\n", buffer, context, wined3d_debug_location(location));
+}
+
static void wined3d_buffer_vk_upload_ranges(struct wined3d_buffer *buffer, struct wined3d_context *context,
const void *data, unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges)
{
@@ -1557,6 +1601,7 @@ static void wined3d_buffer_vk_download_ranges(struct wined3d_buffer *buffer, str
static const struct wined3d_buffer_ops wined3d_buffer_vk_ops =
{
wined3d_buffer_vk_prepare_location,
+ wined3d_buffer_vk_unload_location,
wined3d_buffer_vk_upload_ranges,
wined3d_buffer_vk_download_ranges,
};
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 0fc633ad4a5..7d3b709a974 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -4120,6 +4120,8 @@ struct wined3d_buffer_ops
{
BOOL (*buffer_prepare_location)(struct wined3d_buffer *buffer,
struct wined3d_context *context, unsigned int location);
+ void (*buffer_unload_location)(struct wined3d_buffer *buffer,
+ struct wined3d_context *context, unsigned int location);
void (*buffer_upload_ranges)(struct wined3d_buffer *buffer, struct wined3d_context *context, const void *data,
unsigned int data_offset, unsigned int range_count, const struct wined3d_map_range *ranges);
void (*buffer_download_ranges)(struct wined3d_buffer *buffer, struct wined3d_context *context, void *data,
@@ -4187,8 +4189,6 @@ static inline struct wined3d_buffer_gl *wined3d_buffer_gl(struct wined3d_buffer
GLenum wined3d_buffer_gl_binding_from_bind_flags(const struct wined3d_gl_info *gl_info,
uint32_t bind_flags) DECLSPEC_HIDDEN;
-void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *buffer_gl,
- struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
HRESULT wined3d_buffer_gl_init(struct wined3d_buffer_gl *buffer_gl, struct wined3d_device *device,
const struct wined3d_buffer_desc *desc, const struct wined3d_sub_resource_data *data,
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
--
2.11.0
Dec. 6, 2019
Re: [PATCH vkd3d] vkd3d: Remove redundant GetCopyableFootprints() resource size alignment checks.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 6, 2019
[PATCH vkd3d 6/6] vkd3d-shader: Handle VKD3DSPR_GSINSTID in vkd3d_dxbc_compiler_get_register_name().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index 40280eb..3d88be9 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -2500,6 +2500,9 @@ static bool vkd3d_dxbc_compiler_get_register_name(char *buffer, unsigned int buf
case VKD3DSPR_JOININSTID:
snprintf(buffer, buffer_size, "vJoinInstanceId");
break;
+ case VKD3DSPR_GSINSTID:
+ snprintf(buffer, buffer_size, "vGSInstanceID");
+ break;
case VKD3DSPR_PATCHCONST:
snprintf(buffer, buffer_size, "vpc%u", idx);
break;
--
2.11.0
Dec. 6, 2019
[PATCH vkd3d 5/6] vkd3d-shader: Avoid declaring outputs multiple times with incompatible types.
by Henri Verbeet
This would cause CoreValidation-Shader-InterfaceTypeMismatch validation
errors from Wine's test_shader_interstage_interface() d3d11 test. This
reverts parts of commits 1eb7eca411f71d8dec7cfae5c58c1dff9626a7e0 and
04ec461fb4224e126d271760123bb6d756c06582.
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
libs/vkd3d-shader/spirv.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/libs/vkd3d-shader/spirv.c b/libs/vkd3d-shader/spirv.c
index a949e4a..40280eb 100644
--- a/libs/vkd3d-shader/spirv.c
+++ b/libs/vkd3d-shader/spirv.c
@@ -4438,8 +4438,13 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
{
use_private_variable = true;
write_mask = VKD3DSP_WRITEMASK_ALL;
+ entry = rb_get(&compiler->symbol_table, ®_symbol);
}
}
+ else if (!use_private_variable && (entry = rb_get(&compiler->symbol_table, ®_symbol)))
+ {
+ id = RB_ENTRY_VALUE(entry, const struct vkd3d_symbol, entry)->id;
+ }
else
{
if (builtin)
@@ -4487,15 +4492,15 @@ static void vkd3d_dxbc_compiler_emit_output(struct vkd3d_dxbc_compiler *compiler
vkd3d_spirv_build_op_decorate(builder, id, SpvDecorationPatch, NULL, 0);
vkd3d_dxbc_compiler_decorate_xfb_output(compiler, id, output_component_count, signature_element);
-
- compiler->output_info[signature_idx].id = id;
- compiler->output_info[signature_idx].component_type = component_type;
}
+ compiler->output_info[signature_idx].id = id;
+ compiler->output_info[signature_idx].component_type = component_type;
+
if (use_private_variable)
storage_class = SpvStorageClassPrivate;
- if ((entry = rb_get(&compiler->symbol_table, ®_symbol)))
+ if (entry)
var_id = RB_ENTRY_VALUE(entry, const struct vkd3d_symbol, entry)->id;
else if (!use_private_variable)
var_id = id;
--
2.11.0
Dec. 6, 2019
[PATCH vkd3d 4/6] vkd3d-shader: Handle normalised types in vkd3d_component_type_from_data_type().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 940cb76..100d515 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -838,6 +838,8 @@ static inline enum vkd3d_component_type vkd3d_component_type_from_data_type(
switch (data_type)
{
case VKD3D_DATA_FLOAT:
+ case VKD3D_DATA_UNORM:
+ case VKD3D_DATA_SNORM:
return VKD3D_TYPE_FLOAT;
case VKD3D_DATA_UINT:
return VKD3D_TYPE_UINT;
--
2.11.0
Dec. 6, 2019