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 2020
- 68 participants
- 931 messages
Re: [PATCH 02/17] winegstreamer: Implement ::SetOutputType for audio conversion transform.
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=83065
Your paranoid android.
=== debiant (build log) ===
Task: Patch failed to apply
=== debiant (build log) ===
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 01/17] winegstreamer: Implement ::SetInputType for audio conversion transform.
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=83064
Your paranoid android.
=== debiant (build log) ===
Task: Patch failed to apply
=== debiant (build log) ===
Task: Patch failed to apply
Dec. 3, 2020
[PATCH 17/17] winegstreamer: Implement Get(Input/Output)CurrentType functions for color converter transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/colorconvert.c | 58 ++++++++++++++++++++++++++++---
1 file changed, 54 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index 9e6ece796f3..c7b1fae393f 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -466,16 +466,66 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
static HRESULT WINAPI color_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
{
- FIXME("%p, %u, %p.\n", iface, id, type);
+ IMFMediaType *ret;
+ HRESULT hr;
- return E_NOTIMPL;
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %u, %p.\n", converter, id, type);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (FAILED(hr = MFCreateMediaType(&ret)))
+ return hr;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (converter->input_type)
+ hr = IMFMediaType_CopyAllItems(converter->input_type, (IMFAttributes *)ret);
+ else
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
+
+ LeaveCriticalSection(&converter->cs);
+
+ if (SUCCEEDED(hr))
+ *type = ret;
+ else
+ IMFMediaType_Release(ret);
+
+ return hr;
}
static HRESULT WINAPI color_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
{
- FIXME("%p, %u, %p.\n", iface, id, type);
+ IMFMediaType *ret;
+ HRESULT hr;
- return E_NOTIMPL;
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %u, %p.\n", converter, id, type);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (FAILED(hr = MFCreateMediaType(&ret)))
+ return hr;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (converter->output_type)
+ hr = IMFMediaType_CopyAllItems(converter->output_type, (IMFAttributes *)ret);
+ else
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
+
+ LeaveCriticalSection(&converter->cs);
+
+ if (SUCCEEDED(hr))
+ *type = ret;
+ else
+ IMFMediaType_Release(ret);
+
+ return hr;
}
static HRESULT WINAPI color_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
--
2.29.2
Dec. 3, 2020
[PATCH 16/17] winegstreamer: Implement Get*Attributes functions for color converter transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/colorconvert.c | 37 +++++++++++++++++++++++++++----
1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index 43b8dddeee7..9e6ece796f3 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -52,6 +52,8 @@ struct color_converter
{
IMFTransform IMFTransform_iface;
LONG refcount;
+ IMFAttributes *attributes;
+ IMFAttributes *output_attributes;
IMFMediaType *input_type;
IMFMediaType *output_type;
CRITICAL_SECTION cs;
@@ -102,6 +104,10 @@ static ULONG WINAPI color_converter_Release(IMFTransform *iface)
{
transform->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&transform->cs);
+ if (transform->attributes)
+ IMFAttributes_Release(transform->attributes);
+ if (transform->output_attributes)
+ IMFAttributes_Release(transform->output_attributes);
gst_object_unref(transform->container);
heap_free(transform);
}
@@ -167,9 +173,14 @@ static HRESULT WINAPI color_converter_GetOutputStreamInfo(IMFTransform *iface, D
static HRESULT WINAPI color_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
{
- FIXME("%p, %p.\n", iface, attributes);
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
- return E_NOTIMPL;
+ TRACE("%p, %p.\n", iface, attributes);
+
+ *attributes = converter->attributes;
+ IMFAttributes_AddRef(*attributes);
+
+ return S_OK;
}
static HRESULT WINAPI color_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
@@ -183,9 +194,14 @@ static HRESULT WINAPI color_converter_GetInputStreamAttributes(IMFTransform *ifa
static HRESULT WINAPI color_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
IMFAttributes **attributes)
{
- FIXME("%p, %u, %p.\n", iface, id, attributes);
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
- return E_NOTIMPL;
+ TRACE("%p, %u, %p.\n", iface, id, attributes);
+
+ *attributes = converter->output_attributes;
+ IMFAttributes_AddRef(*attributes);
+
+ return S_OK;
}
static HRESULT WINAPI color_converter_DeleteInputStream(IMFTransform *iface, DWORD id)
@@ -639,6 +655,7 @@ static const IMFTransformVtbl color_converter_vtbl =
HRESULT color_converter_create(REFIID riid, void **ret)
{
struct color_converter *object;
+ HRESULT hr;
TRACE("%s %p\n", debugstr_guid(riid), ret);
@@ -651,6 +668,18 @@ HRESULT color_converter_create(REFIID riid, void **ret)
InitializeCriticalSection(&object->cs);
object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": color_converter_lock");
+ if (FAILED(hr = MFCreateAttributes(&object->attributes, 0)))
+ {
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return hr;
+ }
+
+ if (FAILED(hr = MFCreateAttributes(&object->output_attributes, 0)))
+ {
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return hr;
+ }
+
object->container = gst_bin_new(NULL);
if (!(object->appsrc = gst_element_factory_make("appsrc", NULL)))
--
2.29.2
Dec. 3, 2020
[PATCH 15/17] winegstreamer: Implement ::Get(Input/Output)StreamInfo for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/colorconvert.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index c07ef22acc3..43b8dddeee7 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -138,16 +138,31 @@ static HRESULT WINAPI color_converter_GetStreamIDs(IMFTransform *iface, DWORD in
static HRESULT WINAPI color_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
{
- FIXME("%p %u %p.\n", iface, id, info);
+ TRACE("%p %u %p.\n", iface, id, info);
- return E_NOTIMPL;
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ info->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_DOES_NOT_ADDREF;
+ info->cbMaxLookahead = 0;
+ info->cbAlignment = 0;
+ info->hnsMaxLatency = 0;
+
+ return S_OK;
}
static HRESULT WINAPI color_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
{
- FIXME("%p %u %p.\n", iface, id, info);
+ TRACE("%p %u %p.\n", iface, id, info);
- return E_NOTIMPL;
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ info->dwFlags = MFT_OUTPUT_STREAM_PROVIDES_SAMPLES;
+ info->cbSize = 0;
+ info->cbAlignment = 0;
+
+ return S_OK;
}
static HRESULT WINAPI color_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
--
2.29.2
Dec. 3, 2020
[PATCH 14/17] winegstreamer: Implement ::ProcessMessage for color conversion MFT.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/colorconvert.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index b77f3358c52..c07ef22acc3 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -477,9 +477,16 @@ static HRESULT WINAPI color_converter_ProcessEvent(IMFTransform *iface, DWORD id
static HRESULT WINAPI color_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
{
- FIXME("%p, %u %lu.\n", iface, message, param);
+ TRACE("%p, %u %lu.\n", iface, message, param);
- return E_NOTIMPL;
+ switch(message)
+ {
+ case MFT_MESSAGE_NOTIFY_START_OF_STREAM:
+ return S_OK;
+ default:
+ FIXME("Unhandled message type %x.\n", message);
+ return E_NOTIMPL;
+ }
}
static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
--
2.29.2
Dec. 3, 2020
[PATCH 13/17] winegstreamer: Implement ::Process(Input/Output) for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/colorconvert.c | 159 +++++++++++++++++++++++++++++-
1 file changed, 154 insertions(+), 5 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index e7e84690738..b77f3358c52 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -55,6 +55,8 @@ struct color_converter
IMFMediaType *input_type;
IMFMediaType *output_type;
CRITICAL_SECTION cs;
+ BOOL inflight;
+ GstElement *container, *appsrc, *videoconvert, *appsink;
};
static struct color_converter *impl_color_converter_from_IMFTransform(IMFTransform *iface)
@@ -100,6 +102,7 @@ static ULONG WINAPI color_converter_Release(IMFTransform *iface)
{
transform->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&transform->cs);
+ gst_object_unref(transform->container);
heap_free(transform);
}
@@ -307,7 +310,8 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
if (!(input_caps = caps_from_mf_media_type(type)))
return MF_E_INVALIDTYPE;
- gst_caps_unref(input_caps);
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ gst_caps_unref(input_caps);
}
if (flags & MFT_SET_TYPE_TEST_ONLY)
@@ -316,6 +320,7 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
EnterCriticalSection(&converter->cs);
hr = S_OK;
+ gst_element_set_state(converter->container, GST_STATE_READY);
if (type)
{
@@ -325,6 +330,9 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
if (SUCCEEDED(hr))
hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
+ g_object_set(converter->appsrc, "caps", input_caps, NULL);
+ gst_caps_unref(input_caps);
+
if (FAILED(hr))
{
IMFMediaType_Release(converter->input_type);
@@ -337,6 +345,9 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
converter->input_type = NULL;
}
+ if (converter->input_type && converter->output_type)
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
+
LeaveCriticalSection(&converter->cs);
return hr;
@@ -379,7 +390,8 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
if (!(output_caps = caps_from_mf_media_type(type)))
return MF_E_INVALIDTYPE;
- gst_caps_unref(output_caps);
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ gst_caps_unref(output_caps);
}
if (flags & MFT_SET_TYPE_TEST_ONLY)
@@ -388,6 +400,7 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
EnterCriticalSection(&converter->cs);
hr = S_OK;
+ gst_element_set_state(converter->container, GST_STATE_READY);
if (type)
{
@@ -397,6 +410,9 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
if (SUCCEEDED(hr))
hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
+ g_object_set(converter->appsink, "caps", output_caps, NULL);
+ gst_caps_unref(output_caps);
+
if (FAILED(hr))
{
IMFMediaType_Release(converter->output_type);
@@ -409,6 +425,9 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
converter->output_type = NULL;
}
+ if (converter->input_type && converter->output_type)
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
+
LeaveCriticalSection(&converter->cs);
return hr;
@@ -465,15 +484,102 @@ static HRESULT WINAPI color_converter_ProcessMessage(IMFTransform *iface, MFT_ME
static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
{
- FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
+ GstBuffer *gst_buffer;
+ int ret;
- return E_NOTIMPL;
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %u, %p, %#x.\n", iface, id, sample, flags);
+
+ if (flags)
+ WARN("Unsupported flags %#x\n", flags);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (!converter->input_type || !converter->output_type)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+ }
+
+ if (converter->inflight)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_NOTACCEPTING;
+ }
+
+ if (!(gst_buffer = gst_buffer_from_mf_sample(sample)))
+ {
+ LeaveCriticalSection(&converter->cs);
+ return E_FAIL;
+ }
+
+ g_signal_emit_by_name(converter->appsrc, "push-buffer", gst_buffer, &ret);
+ gst_buffer_unref(gst_buffer);
+ if (ret != GST_FLOW_OK)
+ {
+ ERR("Couldn't push buffer ret = %d (%s)\n", ret, gst_flow_get_name(ret));
+ LeaveCriticalSection(&converter->cs);
+ return E_FAIL;
+ }
+
+ converter->inflight = TRUE;
+ LeaveCriticalSection(&converter->cs);
+
+ return S_OK;
}
static HRESULT WINAPI color_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
{
- FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
+ GstSample *sample;
+
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
+
+ if (flags)
+ WARN("Unsupported flags %#x\n", flags);
+
+ if (!count)
+ return S_OK;
+
+ if (count != 1)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (samples[0].dwStreamID != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (!converter->input_type || !converter->output_type)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+ }
+
+ if (!converter->inflight)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_TRANSFORM_NEED_MORE_INPUT;
+ }
+
+ g_signal_emit_by_name(converter->appsink, "pull-sample", &sample);
+
+ converter->inflight = FALSE;
+
+ samples[0].pSample = mf_sample_from_gst_buffer(gst_sample_get_buffer(sample));
+ gst_sample_unref(sample);
+ samples[0].dwStatus = S_OK;
+ samples[0].pEvents = NULL;
+ *status = 0;
+
+ LeaveCriticalSection(&converter->cs);
+
+ return S_OK;
return E_NOTIMPL;
}
@@ -523,6 +629,49 @@ HRESULT color_converter_create(REFIID riid, void **ret)
InitializeCriticalSection(&object->cs);
object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": color_converter_lock");
+ object->container = gst_bin_new(NULL);
+
+ if (!(object->appsrc = gst_element_factory_make("appsrc", NULL)))
+ {
+ ERR("Failed to create appsrc, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), object->appsrc);
+
+ if (!(object->videoconvert = gst_element_factory_make("videoconvert", NULL)))
+ {
+ ERR("Failed to create videoconvert, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), object->videoconvert);
+
+ if (!(object->appsink = gst_element_factory_make("appsink", NULL)))
+ {
+ ERR("Failed to create appsink, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), object->appsink);
+
+ if (!gst_element_link(object->appsrc, object->videoconvert))
+ {
+ ERR("Failed to link appsrc to videoconvert\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
+ if (!gst_element_link(object->videoconvert, object->appsink))
+ {
+ ERR("Failed to link videoconvert to appsink\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
*ret = &object->IMFTransform_iface;
return S_OK;
}
--
2.29.2
Dec. 3, 2020
[PATCH 12/17] winegstreamer: Implement ::SetOutputType for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/colorconvert.c | 70 ++++++++++++++++++++++++++++++-
1 file changed, 68 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index b80232e195b..e7e84690738 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -53,6 +53,7 @@ struct color_converter
IMFTransform IMFTransform_iface;
LONG refcount;
IMFMediaType *input_type;
+ IMFMediaType *output_type;
CRITICAL_SECTION cs;
};
@@ -343,9 +344,74 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
{
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
+ GstCaps *output_caps;
+ unsigned int i;
+ HRESULT hr;
- return E_NOTIMPL;
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (type)
+ {
+ GUID major_type, subtype;
+
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
+ return MF_E_INVALIDTYPE;
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
+ return MF_E_INVALIDTYPE;
+
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Video)))
+ return MF_E_INVALIDTYPE;
+
+ for (i = 0; i < ARRAY_SIZE(raw_types); i++)
+ {
+ if (IsEqualGUID(&subtype, raw_types[i]))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(raw_types))
+ return MF_E_INVALIDTYPE;
+
+ if (!(output_caps = caps_from_mf_media_type(type)))
+ return MF_E_INVALIDTYPE;
+
+ gst_caps_unref(output_caps);
+ }
+
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ return S_OK;
+
+ EnterCriticalSection(&converter->cs);
+
+ hr = S_OK;
+
+ if (type)
+ {
+ if (!converter->output_type)
+ hr = MFCreateMediaType(&converter->output_type);
+
+ if (SUCCEEDED(hr))
+ hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
+
+ if (FAILED(hr))
+ {
+ IMFMediaType_Release(converter->output_type);
+ converter->output_type = NULL;
+ }
+ }
+ else
+ {
+ IMFMediaType_Release(converter->output_type);
+ converter->output_type = NULL;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return hr;
}
static HRESULT WINAPI color_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
--
2.29.2
Dec. 3, 2020
[PATCH 11/17] winegstreamer: Implement ::GetOutputAvailableType for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/colorconvert.c | 48 +++++++++++++++++++++++++++++--
1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index 5dd48188147..b80232e195b 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -217,12 +217,56 @@ static HRESULT WINAPI color_converter_GetInputAvailableType(IMFTransform *iface,
return S_OK;
}
+static void copy_attr(IMFMediaType *target, IMFMediaType *source, const GUID *key)
+{
+ PROPVARIANT val;
+
+ if (SUCCEEDED(IMFAttributes_GetItem((IMFAttributes *)source, key, &val)))
+ {
+ IMFAttributes_SetItem((IMFAttributes* )target, key, &val);
+ }
+}
+
static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
IMFMediaType **type)
{
- FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
+ IMFMediaType *output_type;
+ HRESULT hr;
- return E_NOTIMPL;
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (index >= ARRAY_SIZE(raw_types))
+ return MF_E_NO_MORE_TYPES;
+
+ if (FAILED(hr = MFCreateMediaType(&output_type)))
+ return hr;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (!(converter->input_type))
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+ }
+
+ IMFMediaType_CopyAllItems(converter->input_type, (IMFAttributes *)output_type);
+
+ LeaveCriticalSection(&converter->cs);
+
+ if (FAILED(hr = IMFMediaType_SetGUID(output_type, &MF_MT_SUBTYPE, raw_types[index])))
+ {
+ IMFMediaType_Release(output_type);
+ return hr;
+ }
+
+ *type = output_type;
+
+ return S_OK;
}
static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
--
2.29.2
Dec. 3, 2020
[PATCH 10/17] winegstreamer: Implement ::SetInputType for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/colorconvert.c | 76 ++++++++++++++++++++++++++++++-
1 file changed, 74 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index 9a1d2880234..5dd48188147 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -52,6 +52,8 @@ struct color_converter
{
IMFTransform IMFTransform_iface;
LONG refcount;
+ IMFMediaType *input_type;
+ CRITICAL_SECTION cs;
};
static struct color_converter *impl_color_converter_from_IMFTransform(IMFTransform *iface)
@@ -95,6 +97,8 @@ static ULONG WINAPI color_converter_Release(IMFTransform *iface)
if (!refcount)
{
+ transform->cs.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&transform->cs);
heap_free(transform);
}
@@ -223,9 +227,74 @@ static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface
static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
{
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
+ GstCaps *input_caps;
+ unsigned int i;
+ HRESULT hr;
- return E_NOTIMPL;
+ struct color_converter *converter = impl_color_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (type)
+ {
+ GUID major_type, subtype;
+
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
+ return MF_E_INVALIDTYPE;
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
+ return MF_E_INVALIDTYPE;
+
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Video)))
+ return MF_E_INVALIDTYPE;
+
+ for (i = 0; i < ARRAY_SIZE(raw_types); i++)
+ {
+ if (IsEqualGUID(&subtype, raw_types[i]))
+ break;
+ }
+
+ if (i == ARRAY_SIZE(raw_types))
+ return MF_E_INVALIDTYPE;
+
+ if (!(input_caps = caps_from_mf_media_type(type)))
+ return MF_E_INVALIDTYPE;
+
+ gst_caps_unref(input_caps);
+ }
+
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ return S_OK;
+
+ EnterCriticalSection(&converter->cs);
+
+ hr = S_OK;
+
+ if (type)
+ {
+ if (!converter->input_type)
+ hr = MFCreateMediaType(&converter->input_type);
+
+ if (SUCCEEDED(hr))
+ hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
+
+ if (FAILED(hr))
+ {
+ IMFMediaType_Release(converter->input_type);
+ converter->input_type = NULL;
+ }
+ }
+ else
+ {
+ IMFMediaType_Release(converter->input_type);
+ converter->input_type = NULL;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return hr;
}
static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
@@ -341,6 +410,9 @@ HRESULT color_converter_create(REFIID riid, void **ret)
object->IMFTransform_iface.lpVtbl = &color_converter_vtbl;
object->refcount = 1;
+ InitializeCriticalSection(&object->cs);
+ object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": color_converter_lock");
+
*ret = &object->IMFTransform_iface;
return S_OK;
}
--
2.29.2
Dec. 3, 2020
[PATCH 09/17] winegstreamer: Implement ::GetInputAvailableType for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/colorconvert.c | 48 +++++++++++++++++++++++++++++--
1 file changed, 46 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index 8d0823fc0dc..9a1d2880234 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -30,6 +30,24 @@
WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+static const GUID *raw_types[] = {
+ &MFVideoFormat_RGB24,
+ &MFVideoFormat_RGB32,
+ &MFVideoFormat_RGB555,
+ &MFVideoFormat_RGB8,
+ &MFVideoFormat_AYUV,
+ &MFVideoFormat_I420,
+ &MFVideoFormat_IYUV,
+ &MFVideoFormat_NV11,
+ &MFVideoFormat_NV12,
+ &MFVideoFormat_UYVY,
+ &MFVideoFormat_v216,
+ &MFVideoFormat_v410,
+ &MFVideoFormat_YUY2,
+ &MFVideoFormat_YVYU,
+ &MFVideoFormat_YVYU,
+};
+
struct color_converter
{
IMFTransform IMFTransform_iface;
@@ -164,9 +182,35 @@ static HRESULT WINAPI color_converter_AddInputStreams(IMFTransform *iface, DWORD
static HRESULT WINAPI color_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
IMFMediaType **type)
{
- FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
+ IMFMediaType *ret;
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("%p, %u, %u, %p.\n", iface, id, index, type);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (index >= ARRAY_SIZE(raw_types))
+ return MF_E_NO_MORE_TYPES;
+
+ if (FAILED(hr = MFCreateMediaType(&ret)))
+ return hr;
+
+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_MAJOR_TYPE, &MFMediaType_Video)))
+ {
+ IMFMediaType_Release(ret);
+ return hr;
+ }
+
+ if (FAILED(hr = IMFMediaType_SetGUID(ret, &MF_MT_SUBTYPE, raw_types[index])))
+ {
+ IMFMediaType_Release(ret);
+ return hr;
+ }
+
+ *type = ret;
+
+ return S_OK;
}
static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
--
2.29.2
Dec. 3, 2020
[PATCH 08/17] winegstreamer: Register the color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/mfplat.c | 34 +++++++++++++++++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 288b79997cd..1b19c43d991 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -455,6 +455,26 @@ static const GUID *audio_converter_supported_types[] =
&MFAudioFormat_Float,
};
+static WCHAR color_converterW[] = {'C','o','l','o','r',' ','C','o','n','v','e','r','t','e','r',0};
+const GUID *color_converter_supported_types[] =
+{
+ &MFVideoFormat_RGB24,
+ &MFVideoFormat_RGB32,
+ &MFVideoFormat_RGB555,
+ &MFVideoFormat_RGB8,
+ &MFVideoFormat_AYUV,
+ &MFVideoFormat_I420,
+ &MFVideoFormat_IYUV,
+ &MFVideoFormat_NV11,
+ &MFVideoFormat_NV12,
+ &MFVideoFormat_UYVY,
+ &MFVideoFormat_v216,
+ &MFVideoFormat_v410,
+ &MFVideoFormat_YUY2,
+ &MFVideoFormat_YVYU,
+ &MFVideoFormat_YVYU,
+};
+
static const struct mft
{
const GUID *clsid;
@@ -482,13 +502,25 @@ mfts[] =
audio_converter_supported_types,
NULL
},
+ {
+ &CLSID_WINEColorConverter,
+ &MFT_CATEGORY_VIDEO_EFFECT,
+ color_converterW,
+ MFT_ENUM_FLAG_SYNCMFT,
+ &MFMediaType_Video,
+ ARRAY_SIZE(color_converter_supported_types),
+ color_converter_supported_types,
+ ARRAY_SIZE(color_converter_supported_types),
+ color_converter_supported_types,
+ NULL
+ },
};
HRESULT mfplat_DllRegisterServer(void)
{
unsigned int i, j;
HRESULT hr;
- MFT_REGISTER_TYPE_INFO input_types[2], output_types[2];
+ MFT_REGISTER_TYPE_INFO input_types[15], output_types[15];
for (i = 0; i < ARRAY_SIZE(mfts); i++)
{
--
2.29.2
Dec. 3, 2020
[PATCH 07/17] winegstreamer: Introduce color conversion transform.
by Derek Lesho
Serves as a wrapper of videoconvert, and roughly fills the roll of Windows' CColorConverterDMO.
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/Makefile.in | 1 +
dlls/winegstreamer/colorconvert.c | 302 +++++++++++++++++++
dlls/winegstreamer/gst_private.h | 1 +
dlls/winegstreamer/mfplat.c | 3 +
dlls/winegstreamer/winegstreamer_classes.idl | 6 +
5 files changed, 313 insertions(+)
create mode 100644 dlls/winegstreamer/colorconvert.c
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
index 0b3229160b9..5395d6fd501 100644
--- a/dlls/winegstreamer/Makefile.in
+++ b/dlls/winegstreamer/Makefile.in
@@ -7,6 +7,7 @@ PARENTSRC = ../strmbase
C_SRCS = \
audioconvert.c \
+ colorconvert.c \
filter.c \
gst_cbs.c \
gstdemux.c \
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
new file mode 100644
index 00000000000..8d0823fc0dc
--- /dev/null
+++ b/dlls/winegstreamer/colorconvert.c
@@ -0,0 +1,302 @@
+/* GStreamer Color Converter
+ *
+ * Copyright 2020 Derek Lesho
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include "gst_private.h"
+
+#include "mfapi.h"
+#include "mferror.h"
+#include "mfidl.h"
+
+#include "wine/debug.h"
+#include "wine/heap.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+
+struct color_converter
+{
+ IMFTransform IMFTransform_iface;
+ LONG refcount;
+};
+
+static struct color_converter *impl_color_converter_from_IMFTransform(IMFTransform *iface)
+{
+ return CONTAINING_RECORD(iface, struct color_converter, IMFTransform_iface);
+}
+
+static HRESULT WINAPI color_converter_QueryInterface(IMFTransform *iface, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+ if (IsEqualIID(riid, &IID_IMFTransform) ||
+ IsEqualIID(riid, &IID_IUnknown))
+ {
+ *obj = iface;
+ IMFTransform_AddRef(iface);
+ return S_OK;
+ }
+
+ WARN("Unsupported %s.\n", debugstr_guid(riid));
+ *obj = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI color_converter_AddRef(IMFTransform *iface)
+{
+ struct color_converter *transform = impl_color_converter_from_IMFTransform(iface);
+ ULONG refcount = InterlockedIncrement(&transform->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI color_converter_Release(IMFTransform *iface)
+{
+ struct color_converter *transform = impl_color_converter_from_IMFTransform(iface);
+ ULONG refcount = InterlockedDecrement(&transform->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ heap_free(transform);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI color_converter_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum,
+ DWORD *output_minimum, DWORD *output_maximum)
+{
+ TRACE("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum);
+
+ *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI color_converter_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs)
+{
+ TRACE("%p, %p, %p.\n", iface, inputs, outputs);
+
+ *inputs = *outputs = 1;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI color_converter_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
+ DWORD output_size, DWORD *outputs)
+{
+ TRACE("%p %u %p %u %p.\n", iface, input_size, inputs, output_size, outputs);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
+{
+ FIXME("%p %u %p.\n", iface, id, info);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
+{
+ FIXME("%p %u %p.\n", iface, id, info);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
+{
+ FIXME("%p, %p.\n", iface, attributes);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
+ IMFAttributes **attributes)
+{
+ FIXME("%p, %u, %p.\n", iface, id, attributes);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
+ IMFAttributes **attributes)
+{
+ FIXME("%p, %u, %p.\n", iface, id, attributes);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_DeleteInputStream(IMFTransform *iface, DWORD id)
+{
+ TRACE("%p, %u.\n", iface, id);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids)
+{
+ TRACE("%p, %u, %p.\n", iface, streams, ids);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
+ IMFMediaType **type)
+{
+ FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
+ IMFMediaType **type)
+{
+ FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
+{
+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
+{
+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
+{
+ FIXME("%p, %u, %p.\n", iface, id, type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
+{
+ FIXME("%p, %u, %p.\n", iface, id, type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
+{
+ FIXME("%p, %u, %p.\n", iface, id, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_GetOutputStatus(IMFTransform *iface, DWORD *flags)
+{
+ FIXME("%p, %p.\n", iface, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper)
+{
+ FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper));
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event)
+{
+ TRACE("%p, %u, %p.\n", iface, id, event);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
+{
+ FIXME("%p, %u %lu.\n", iface, message, param);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
+{
+ FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI color_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
+ MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
+{
+ FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
+
+ return E_NOTIMPL;
+}
+
+static const IMFTransformVtbl color_converter_vtbl =
+{
+ color_converter_QueryInterface,
+ color_converter_AddRef,
+ color_converter_Release,
+ color_converter_GetStreamLimits,
+ color_converter_GetStreamCount,
+ color_converter_GetStreamIDs,
+ color_converter_GetInputStreamInfo,
+ color_converter_GetOutputStreamInfo,
+ color_converter_GetAttributes,
+ color_converter_GetInputStreamAttributes,
+ color_converter_GetOutputStreamAttributes,
+ color_converter_DeleteInputStream,
+ color_converter_AddInputStreams,
+ color_converter_GetInputAvailableType,
+ color_converter_GetOutputAvailableType,
+ color_converter_SetInputType,
+ color_converter_SetOutputType,
+ color_converter_GetInputCurrentType,
+ color_converter_GetOutputCurrentType,
+ color_converter_GetInputStatus,
+ color_converter_GetOutputStatus,
+ color_converter_SetOutputBounds,
+ color_converter_ProcessEvent,
+ color_converter_ProcessMessage,
+ color_converter_ProcessInput,
+ color_converter_ProcessOutput,
+};
+
+HRESULT color_converter_create(REFIID riid, void **ret)
+{
+ struct color_converter *object;
+
+ TRACE("%s %p\n", debugstr_guid(riid), ret);
+
+ if (!(object = heap_alloc_zero(sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ object->IMFTransform_iface.lpVtbl = &color_converter_vtbl;
+ object->refcount = 1;
+
+ *ret = &object->IMFTransform_iface;
+ return S_OK;
+}
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 14b6a011ac2..075e0ce1f0f 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -87,5 +87,6 @@ GstBuffer *gst_buffer_from_mf_sample(IMFSample *in) DECLSPEC_HIDDEN;
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
+HRESULT color_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
#endif /* __GST_PRIVATE_INCLUDED__ */
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 883084b2d89..288b79997cd 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -407,6 +407,8 @@ static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a
static const GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}};
+static GUID CLSID_WINEColorConverter = {0x2be8b27f,0xcd60,0x4b8a,{0x95,0xae,0xd1,0x74,0xcc,0x5c,0xba,0xa7}};
+
static const struct class_object
{
const GUID *clsid;
@@ -417,6 +419,7 @@ class_objects[] =
{ &CLSID_VideoProcessorMFT, &video_processor_create },
{ &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
{ &CLSID_WINEAudioConverter, &audio_converter_create },
+ { &CLSID_WINEColorConverter, &color_converter_create },
};
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
index cf1fc69f38a..47c10a09cf0 100644
--- a/dlls/winegstreamer/winegstreamer_classes.idl
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
@@ -67,3 +67,9 @@ coclass GStreamerByteStreamHandler {}
uuid(6a170414-aad9-4693-b806-3a0c47c570d6)
]
coclass WINEAudioConverter { }
+
+[
+ threading(both),
+ uuid(2be8b27f-cd60-4b8a-95ae-d174cc5cbaa7)
+]
+coclass WINEColorConverter { }
--
2.29.2
Dec. 3, 2020
[PATCH 06/17] winegstreamer: Implement Get(Input/Output)CurrentType functions for audio converter transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v1(v6):
- Fix commit message.
- Fixed leak of media type in error path.
---
dlls/winegstreamer/audioconvert.c | 56 ++++++++++++++++++++++++++++---
1 file changed, 52 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index 556aba44fc9..e709c43ed5c 100644
--- a/dlls/winegstreamer/audioconvert.c
+++ b/dlls/winegstreamer/audioconvert.c
@@ -473,16 +473,64 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
{
- FIXME("%p, %u, %p.\n", iface, id, type);
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
+ IMFMediaType *ret;
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("%p, %u, %p.\n", converter, id, type);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (FAILED(hr = MFCreateMediaType(&ret)))
+ return hr;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (converter->input_type)
+ hr = IMFMediaType_CopyAllItems(converter->input_type, (IMFAttributes *)ret);
+ else
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
+
+ LeaveCriticalSection(&converter->cs);
+
+ if (SUCCEEDED(hr))
+ *type = ret;
+ else
+ IMFMediaType_Release(ret);
+
+ return hr;
}
static HRESULT WINAPI audio_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
{
- FIXME("%p, %u, %p.\n", iface, id, type);
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
+ IMFMediaType *ret;
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("%p, %u, %p.\n", converter, id, type);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (FAILED(hr = MFCreateMediaType(&ret)))
+ return hr;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (converter->output_type)
+ hr = IMFMediaType_CopyAllItems(converter->output_type, (IMFAttributes *)ret);
+ else
+ hr = MF_E_TRANSFORM_TYPE_NOT_SET;
+
+ LeaveCriticalSection(&converter->cs);
+
+ if (SUCCEEDED(hr))
+ *type = ret;
+ else
+ IMFMediaType_Release(ret);
+
+ return hr;
}
static HRESULT WINAPI audio_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
--
2.29.2
Dec. 3, 2020
[PATCH 05/17] winegstreamer: Implement Get*Attributes functions for audio converter transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/audioconvert.c | 37 +++++++++++++++++++++++++++----
1 file changed, 33 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index d204d9582ba..556aba44fc9 100644
--- a/dlls/winegstreamer/audioconvert.c
+++ b/dlls/winegstreamer/audioconvert.c
@@ -37,6 +37,8 @@ struct audio_converter
{
IMFTransform IMFTransform_iface;
LONG refcount;
+ IMFAttributes *attributes;
+ IMFAttributes *output_attributes;
IMFMediaType *input_type;
IMFMediaType *output_type;
CRITICAL_SECTION cs;
@@ -87,6 +89,10 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
{
transform->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&transform->cs);
+ if (transform->attributes)
+ IMFAttributes_Release(transform->attributes);
+ if (transform->output_attributes)
+ IMFAttributes_Release(transform->output_attributes);
gst_object_unref(transform->container);
heap_free(transform);
}
@@ -152,9 +158,14 @@ static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, D
static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
{
- FIXME("%p, %p.\n", iface, attributes);
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
- return E_NOTIMPL;
+ TRACE("%p, %p.\n", iface, attributes);
+
+ *attributes = converter->attributes;
+ IMFAttributes_AddRef(*attributes);
+
+ return S_OK;
}
static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
@@ -168,9 +179,14 @@ static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *ifa
static HRESULT WINAPI audio_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
IMFAttributes **attributes)
{
- FIXME("%p, %u, %p.\n", iface, id, attributes);
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
- return E_NOTIMPL;
+ TRACE("%p, %u, %p.\n", iface, id, attributes);
+
+ *attributes = converter->output_attributes;
+ IMFAttributes_AddRef(*attributes);
+
+ return S_OK;
}
static HRESULT WINAPI audio_converter_DeleteInputStream(IMFTransform *iface, DWORD id)
@@ -644,6 +660,7 @@ static const IMFTransformVtbl audio_converter_vtbl =
HRESULT audio_converter_create(REFIID riid, void **ret)
{
struct audio_converter *object;
+ HRESULT hr;
TRACE("%s %p\n", debugstr_guid(riid), ret);
@@ -656,6 +673,18 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
InitializeCriticalSection(&object->cs);
object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": audio_converter_lock");
+ if (FAILED(hr = MFCreateAttributes(&object->attributes, 0)))
+ {
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return hr;
+ }
+
+ if (FAILED(hr = MFCreateAttributes(&object->output_attributes, 0)))
+ {
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return hr;
+ }
+
object->container = gst_bin_new(NULL);
if (!(object->appsrc = gst_element_factory_make("appsrc", NULL)))
--
2.29.2
Dec. 3, 2020
[PATCH 04/17] winegstreamer: Implement ::Get(Input/Output)StreamInfo for audio conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v1(v6): Made naming and style of the two functions consistent.
---
dlls/winegstreamer/audioconvert.c | 23 +++++++++++++++++++----
1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index 631c57d6d55..d204d9582ba 100644
--- a/dlls/winegstreamer/audioconvert.c
+++ b/dlls/winegstreamer/audioconvert.c
@@ -123,16 +123,31 @@ static HRESULT WINAPI audio_converter_GetStreamIDs(IMFTransform *iface, DWORD in
static HRESULT WINAPI audio_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
{
- FIXME("%p %u %p.\n", iface, id, info);
+ TRACE("%p %u %p.\n", iface, id, info);
- return E_NOTIMPL;
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ info->dwFlags = MFT_INPUT_STREAM_WHOLE_SAMPLES | MFT_INPUT_STREAM_DOES_NOT_ADDREF;
+ info->cbMaxLookahead = 0;
+ info->cbAlignment = 0;
+ info->hnsMaxLatency = 0;
+
+ return S_OK;
}
static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
{
- FIXME("%p %u %p.\n", iface, id, info);
+ TRACE("%p %u %p.\n", iface, id, info);
- return E_NOTIMPL;
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ info->dwFlags = MFT_OUTPUT_STREAM_PROVIDES_SAMPLES;
+ info->cbSize = 0;
+ info->cbAlignment = 0;
+
+ return S_OK;
}
static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
--
2.29.2
Dec. 3, 2020
[PATCH 03/17] winegstreamer: Implement ::Process(Input/Output) for audio conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v1(v6):
- Move unused hr to later patch.
- Fix extra parentheses.
- Place converter declaration more consistently.
---
dlls/winegstreamer/audioconvert.c | 175 +++++++++++++++++++++++++++++-
dlls/winegstreamer/gst_private.h | 1 +
dlls/winegstreamer/mfplat.c | 69 ++++++++++++
3 files changed, 239 insertions(+), 6 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index 7fb0dee99f6..631c57d6d55 100644
--- a/dlls/winegstreamer/audioconvert.c
+++ b/dlls/winegstreamer/audioconvert.c
@@ -40,6 +40,8 @@ struct audio_converter
IMFMediaType *input_type;
IMFMediaType *output_type;
CRITICAL_SECTION cs;
+ BOOL inflight;
+ GstElement *container, *appsrc, *audioconvert, *resampler, *appsink;
};
static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface)
@@ -85,6 +87,7 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
{
transform->cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection(&transform->cs);
+ gst_object_unref(transform->container);
heap_free(transform);
}
@@ -311,7 +314,8 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
if (!(input_caps = caps_from_mf_media_type(type)))
return MF_E_INVALIDTYPE;
- gst_caps_unref(input_caps);
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ gst_caps_unref(input_caps);
}
if (flags & MFT_SET_TYPE_TEST_ONLY)
@@ -320,6 +324,7 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
EnterCriticalSection(&converter->cs);
hr = S_OK;
+ gst_element_set_state(converter->container, GST_STATE_READY);
if (type)
{
@@ -329,6 +334,9 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
if (SUCCEEDED(hr))
hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
+ g_object_set(converter->appsrc, "caps", input_caps, NULL);
+ gst_caps_unref(input_caps);
+
if (FAILED(hr))
{
IMFMediaType_Release(converter->input_type);
@@ -341,6 +349,9 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
converter->input_type = NULL;
}
+ if (converter->input_type && converter->output_type)
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
+
LeaveCriticalSection(&converter->cs);
return hr;
@@ -386,7 +397,8 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
if (!(output_caps = caps_from_mf_media_type(type)))
return MF_E_INVALIDTYPE;
- gst_caps_unref(output_caps);
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ gst_caps_unref(output_caps);
}
if (flags & MFT_SET_TYPE_TEST_ONLY)
@@ -395,6 +407,7 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
EnterCriticalSection(&converter->cs);
hr = S_OK;
+ gst_element_set_state(converter->container, GST_STATE_READY);
if (type)
{
@@ -404,6 +417,9 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
if (SUCCEEDED(hr))
hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
+ g_object_set(converter->appsink, "caps", output_caps, NULL);
+ gst_caps_unref(output_caps);
+
if (FAILED(hr))
{
IMFMediaType_Release(converter->output_type);
@@ -416,6 +432,9 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
converter->output_type = NULL;
}
+ if (converter->input_type && converter->output_type)
+ gst_element_set_state(converter->container, GST_STATE_PLAYING);
+
LeaveCriticalSection(&converter->cs);
return hr;
@@ -479,17 +498,102 @@ static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_ME
static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
{
- FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
+ GstBuffer *gst_buffer;
+ int ret;
- return E_NOTIMPL;
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %u, %p, %#x.\n", iface, id, sample, flags);
+
+ if (flags)
+ WARN("Unsupported flags %#x\n", flags);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (!converter->input_type || !converter->output_type)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+ }
+
+ if (converter->inflight)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_NOTACCEPTING;
+ }
+
+ if (!(gst_buffer = gst_buffer_from_mf_sample(sample)))
+ {
+ LeaveCriticalSection(&converter->cs);
+ return E_FAIL;
+ }
+
+ g_signal_emit_by_name(converter->appsrc, "push-buffer", gst_buffer, &ret);
+ gst_buffer_unref(gst_buffer);
+ if (ret != GST_FLOW_OK)
+ {
+ ERR("Couldn't push buffer ret = %d (%s)\n", ret, gst_flow_get_name(ret));
+ LeaveCriticalSection(&converter->cs);
+ return E_FAIL;
+ }
+
+ converter->inflight = TRUE;
+ LeaveCriticalSection(&converter->cs);
+
+ return S_OK;
}
static HRESULT WINAPI audio_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
{
- FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
+ GstSample *sample;
- return E_NOTIMPL;
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
+
+ if (flags)
+ WARN("Unsupported flags %#x\n", flags);
+
+ if (!count)
+ return S_OK;
+
+ if (count != 1)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (samples[0].dwStreamID != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (!converter->input_type || !converter->output_type)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+ }
+
+ if (!converter->inflight)
+ {
+ LeaveCriticalSection(&converter->cs);
+ return MF_E_TRANSFORM_NEED_MORE_INPUT;
+ }
+
+ g_signal_emit_by_name(converter->appsink, "pull-sample", &sample);
+
+ converter->inflight = FALSE;
+
+ samples[0].pSample = mf_sample_from_gst_buffer(gst_sample_get_buffer(sample));
+ gst_sample_unref(sample);
+ samples[0].dwStatus = S_OK;
+ samples[0].pEvents = NULL;
+ *status = 0;
+
+ LeaveCriticalSection(&converter->cs);
+
+ return S_OK;
}
static const IMFTransformVtbl audio_converter_vtbl =
@@ -537,6 +641,65 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
InitializeCriticalSection(&object->cs);
object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": audio_converter_lock");
+ object->container = gst_bin_new(NULL);
+
+ if (!(object->appsrc = gst_element_factory_make("appsrc", NULL)))
+ {
+ ERR("Failed to create appsrc, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), object->appsrc);
+
+ if (!(object->audioconvert = gst_element_factory_make("audioconvert", NULL)))
+ {
+ ERR("Failed to create audioconvert, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), object->audioconvert);
+
+ if (!(object->resampler = gst_element_factory_make("audioresample", NULL)))
+ {
+ ERR("Failed to create audioresample, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), object->resampler);
+
+ if (!(object->appsink = gst_element_factory_make("appsink", NULL)))
+ {
+ ERR("Failed to create appsink, are %u-bit Gstreamer \"base\" plugins installed?\n",
+ 8 * (int)sizeof(void *));
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+ gst_bin_add(GST_BIN(object->container), object->appsink);
+
+ if (!gst_element_link(object->appsrc, object->audioconvert))
+ {
+ ERR("Failed to link appsrc to audioconvert\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
+ if (!gst_element_link(object->audioconvert, object->resampler))
+ {
+ ERR("Failed to link audioconvert to resampler\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
+ if (!gst_element_link(object->resampler, object->appsink))
+ {
+ ERR("Failed to link resampler to appsink\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
*ret = &object->IMFTransform_iface;
return S_OK;
}
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 9518f721504..14b6a011ac2 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -82,6 +82,7 @@ HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HI
IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN;
GstCaps *caps_from_mf_media_type(IMFMediaType *type) DECLSPEC_HIDDEN;
IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN;
+GstBuffer *gst_buffer_from_mf_sample(IMFSample *in) DECLSPEC_HIDDEN;
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index f300988fc5c..883084b2d89 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -865,3 +865,72 @@ done:
return out;
}
+
+GstBuffer* gst_buffer_from_mf_sample(IMFSample *mf_sample)
+{
+ GstBuffer *out = gst_buffer_new();
+ IMFMediaBuffer *mf_buffer = NULL;
+ LONGLONG duration, time;
+ DWORD buffer_count;
+ unsigned int i;
+ HRESULT hr;
+
+ if (FAILED(hr = IMFSample_GetSampleDuration(mf_sample, &duration)))
+ goto fail;
+
+ if (FAILED(hr = IMFSample_GetSampleTime(mf_sample, &time)))
+ goto fail;
+
+ GST_BUFFER_DURATION(out) = duration;
+ GST_BUFFER_PTS(out) = time * 100;
+
+ if (FAILED(hr = IMFSample_GetBufferCount(mf_sample, &buffer_count)))
+ goto fail;
+
+ for (i = 0; i < buffer_count; i++)
+ {
+ DWORD buffer_size;
+ GstMapInfo map_info;
+ GstMemory *memory;
+ BYTE *buf_data;
+
+ if (FAILED(hr = IMFSample_GetBufferByIndex(mf_sample, i, &mf_buffer)))
+ goto fail;
+
+ if (FAILED(hr = IMFMediaBuffer_GetCurrentLength(mf_buffer, &buffer_size)))
+ goto fail;
+
+ memory = gst_allocator_alloc(NULL, buffer_size, NULL);
+ gst_memory_resize(memory, 0, buffer_size);
+
+ if (!(gst_memory_map(memory, &map_info, GST_MAP_WRITE)))
+ {
+ hr = E_FAIL;
+ goto fail;
+ }
+
+ if (FAILED(hr = IMFMediaBuffer_Lock(mf_buffer, &buf_data, NULL, NULL)))
+ goto fail;
+
+ memcpy(map_info.data, buf_data, buffer_size);
+
+ if (FAILED(hr = IMFMediaBuffer_Unlock(mf_buffer)))
+ goto fail;
+
+ gst_memory_unmap(memory, &map_info);
+
+ gst_buffer_append_memory(out, memory);
+
+ IMFMediaBuffer_Release(mf_buffer);
+ mf_buffer = NULL;
+ }
+
+ return out;
+
+fail:
+ ERR("Failed to copy IMFSample to GstBuffer, hr = %#x\n", hr);
+ if (mf_buffer)
+ IMFMediaBuffer_Release(mf_buffer);
+ gst_buffer_unref(out);
+ return NULL;
+}
--
2.29.2
Dec. 3, 2020
[PATCH 02/17] winegstreamer: Implement ::SetOutputType for audio conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/audioconvert.c | 73 ++++++++++++++++++++++++++++++-
1 file changed, 71 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index 8bfd28b1ef2..7fb0dee99f6 100644
--- a/dlls/winegstreamer/audioconvert.c
+++ b/dlls/winegstreamer/audioconvert.c
@@ -38,6 +38,7 @@ struct audio_converter
IMFTransform IMFTransform_iface;
LONG refcount;
IMFMediaType *input_type;
+ IMFMediaType *output_type;
CRITICAL_SECTION cs;
};
@@ -347,9 +348,77 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
{
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
+ GUID major_type, subtype;
+ GstCaps *output_caps;
+ DWORD unused;
+ HRESULT hr;
- return E_NOTIMPL;
+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (!converter->input_type)
+ return MF_E_TRANSFORM_TYPE_NOT_SET;
+
+ if (type)
+ {
+ /* validate the type */
+
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
+ return MF_E_INVALIDTYPE;
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
+ return MF_E_INVALIDTYPE;
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused)))
+ return MF_E_INVALIDTYPE;
+ if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused)))
+ return MF_E_INVALIDTYPE;
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused)))
+ return MF_E_INVALIDTYPE;
+
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Audio)))
+ return MF_E_INVALIDTYPE;
+
+ if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float))
+ return MF_E_INVALIDTYPE;
+
+ if (!(output_caps = caps_from_mf_media_type(type)))
+ return MF_E_INVALIDTYPE;
+
+ gst_caps_unref(output_caps);
+ }
+
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ return S_OK;
+
+ EnterCriticalSection(&converter->cs);
+
+ hr = S_OK;
+
+ if (type)
+ {
+ if (!converter->output_type)
+ hr = MFCreateMediaType(&converter->output_type);
+
+ if (SUCCEEDED(hr))
+ hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->output_type);
+
+ if (FAILED(hr))
+ {
+ IMFMediaType_Release(converter->output_type);
+ converter->output_type = NULL;
+ }
+ }
+ else if (converter->output_type)
+ {
+ IMFMediaType_Release(converter->output_type);
+ converter->output_type = NULL;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return hr;
}
static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
--
2.29.2
Dec. 3, 2020
[PATCH 01/17] winegstreamer: Implement ::SetInputType for audio conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/winegstreamer/audioconvert.c | 77 ++++++++++++++++++++++++++++++-
1 file changed, 75 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index 9499920347f..8bfd28b1ef2 100644
--- a/dlls/winegstreamer/audioconvert.c
+++ b/dlls/winegstreamer/audioconvert.c
@@ -18,6 +18,7 @@
*/
#include "config.h"
+#include <gst/gst.h>
#include "gst_private.h"
@@ -36,6 +37,8 @@ struct audio_converter
{
IMFTransform IMFTransform_iface;
LONG refcount;
+ IMFMediaType *input_type;
+ CRITICAL_SECTION cs;
};
static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface)
@@ -79,6 +82,8 @@ static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
if (!refcount)
{
+ transform->cs.DebugInfo->Spare[0] = 0;
+ DeleteCriticalSection(&transform->cs);
heap_free(transform);
}
@@ -270,9 +275,74 @@ fail:
static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
{
- FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
+ GstCaps *input_caps;
+ HRESULT hr;
- return E_NOTIMPL;
+ struct audio_converter *converter = impl_audio_converter_from_IMFTransform(iface);
+
+ TRACE("%p, %u, %p, %#x.\n", iface, id, type, flags);
+
+ if (id != 0)
+ return MF_E_INVALIDSTREAMNUMBER;
+
+ if (type)
+ {
+ GUID major_type, subtype;
+ DWORD unused;
+
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_MAJOR_TYPE, &major_type)))
+ return MF_E_INVALIDTYPE;
+ if (FAILED(IMFMediaType_GetGUID(type, &MF_MT_SUBTYPE, &subtype)))
+ return MF_E_INVALIDTYPE;
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &unused)))
+ return MF_E_INVALIDTYPE;
+ if (FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &unused)))
+ return MF_E_INVALIDTYPE;
+ if (IsEqualGUID(&subtype, &MFAudioFormat_PCM) && FAILED(IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_BITS_PER_SAMPLE, &unused)))
+ return MF_E_INVALIDTYPE;
+
+ if (!(IsEqualGUID(&major_type, &MFMediaType_Audio)))
+ return MF_E_INVALIDTYPE;
+
+ if (!IsEqualGUID(&subtype, &MFAudioFormat_PCM) && !IsEqualGUID(&subtype, &MFAudioFormat_Float))
+ return MF_E_INVALIDTYPE;
+
+ if (!(input_caps = caps_from_mf_media_type(type)))
+ return MF_E_INVALIDTYPE;
+
+ gst_caps_unref(input_caps);
+ }
+
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ return S_OK;
+
+ EnterCriticalSection(&converter->cs);
+
+ hr = S_OK;
+
+ if (type)
+ {
+ if (!converter->input_type)
+ hr = MFCreateMediaType(&converter->input_type);
+
+ if (SUCCEEDED(hr))
+ hr = IMFMediaType_CopyAllItems(type, (IMFAttributes *) converter->input_type);
+
+ if (FAILED(hr))
+ {
+ IMFMediaType_Release(converter->input_type);
+ converter->input_type = NULL;
+ }
+ }
+ else if (converter->input_type)
+ {
+ IMFMediaType_Release(converter->input_type);
+ converter->input_type = NULL;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return hr;
}
static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
@@ -395,6 +465,9 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
object->IMFTransform_iface.lpVtbl = &audio_converter_vtbl;
object->refcount = 1;
+ InitializeCriticalSection(&object->cs);
+ object->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": audio_converter_lock");
+
*ret = &object->IMFTransform_iface;
return S_OK;
}
--
2.29.2
Dec. 3, 2020
[PATCH 00/17] Final patches of the audio converter MFT + the color converter MFT.
by Derek Lesho
I know this is a lot of patches to send at once, but I'm hoping it's reasonable given
1) how similar patches 7-17 are to the audio converter patches.
2) how patches 1-2 were already signed off on, but didn't get applied due to a copyright notice messing up the merge
The reason I didn't split this into two patchsets is that the color converter also relies on gst_buffer_from_mf_sample, provided by patch 3.
With all these plus the two I sent earlier this week, media foundation video in Unreal Engine games works.
Derek Lesho (17):
winegstreamer: Implement ::SetInputType for audio conversion
transform.
winegstreamer: Implement ::SetOutputType for audio conversion
transform.
winegstreamer: Implement ::Process(Input/Output) for audio conversion
transform.
winegstreamer: Implement ::Get(Input/Output)StreamInfo for audio
conversion transform.
winegstreamer: Implement Get*Attributes functions for audio converter
transform.
winegstreamer: Implement Get(Input/Output)CurrentType functions for
audio converter transform.
winegstreamer: Introduce color conversion transform.
winegstreamer: Register the color conversion transform.
winegstreamer: Implement ::GetInputAvailableType for color conversion
transform.
winegstreamer: Implement ::SetInputType for color conversion
transform.
winegstreamer: Implement ::GetOutputAvailableType for color conversion
transform.
winegstreamer: Implement ::SetOutputType for color conversion
transform.
winegstreamer: Implement ::Process(Input/Output) for color conversion
transform.
winegstreamer: Implement ::ProcessMessage for color conversion MFT.
winegstreamer: Implement ::Get(Input/Output)StreamInfo for color
conversion transform.
winegstreamer: Implement Get*Attributes functions for color converter
transform.
winegstreamer: Implement Get(Input/Output)CurrentType functions for
color converter transform.
dlls/winegstreamer/Makefile.in | 1 +
dlls/winegstreamer/audioconvert.c | 437 ++++++++++-
dlls/winegstreamer/colorconvert.c | 778 +++++++++++++++++++
dlls/winegstreamer/gst_private.h | 2 +
dlls/winegstreamer/mfplat.c | 106 ++-
dlls/winegstreamer/winegstreamer_classes.idl | 6 +
6 files changed, 1309 insertions(+), 21 deletions(-)
create mode 100644 dlls/winegstreamer/colorconvert.c
--
2.29.2
Dec. 3, 2020
[PATCH 6/6] makedep: Use -fno-builtin for crt modules.
by Piotr Caban
From: Jacek Caban <jacek(a)codeweavers.com>
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
tools/makedep.c | 19 +++++++++++++------
1 file changed, 13 insertions(+), 6 deletions(-)
Dec. 3, 2020
[PATCH 5/6] msvcrt: Remove MSVCRT_ prefix from file.c functions.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/crtdll/crtdll.spec | 168 +++----
dlls/msvcr100/msvcr100.spec | 372 +++++++-------
dlls/msvcr110/msvcr110.spec | 372 +++++++-------
dlls/msvcr120/msvcr120.spec | 372 +++++++-------
dlls/msvcr70/msvcr70.spec | 236 ++++-----
dlls/msvcr71/msvcr71.spec | 236 ++++-----
dlls/msvcr80/msvcr80.spec | 372 +++++++-------
dlls/msvcr90/msvcr90.spec | 372 +++++++-------
dlls/msvcrt/errno.c | 9 +-
dlls/msvcrt/exit.c | 2 +-
dlls/msvcrt/file.c | 932 ++++++++++++++++++------------------
dlls/msvcrt/msvcrt.h | 14 -
dlls/msvcrt/msvcrt.spec | 308 ++++++------
dlls/msvcrt/process.c | 27 +-
dlls/msvcrt/scanf.h | 24 +-
dlls/msvcrtd/msvcrtd.spec | 230 ++++-----
dlls/ucrtbase/ucrtbase.spec | 616 ++++++++++++------------
include/msvcrt/io.h | 2 +-
include/msvcrt/stdio.h | 2 +
19 files changed, 2336 insertions(+), 2330 deletions(-)
Dec. 3, 2020
[PATCH 4/6] msvcrt: Remove MSVCRT_ prefix from dir.c functions.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/crtdll/crtdll.spec | 30 +++----
dlls/msvcr100/msvcr100.spec | 80 +++++++++---------
dlls/msvcr110/msvcr110.spec | 80 +++++++++---------
dlls/msvcr120/msvcr120.spec | 80 +++++++++---------
dlls/msvcr70/msvcr70.spec | 68 +++++++--------
dlls/msvcr71/msvcr71.spec | 68 +++++++--------
dlls/msvcr80/msvcr80.spec | 80 +++++++++---------
dlls/msvcr90/msvcr90.spec | 80 +++++++++---------
dlls/msvcrt/dir.c | 141 ++++++++++++++++---------------
dlls/msvcrt/file.c | 6 +-
dlls/msvcrt/msvcrt.h | 1 -
dlls/msvcrt/msvcrt.spec | 94 ++++++++++-----------
dlls/msvcrtd/msvcrtd.spec | 60 +++++++-------
dlls/ucrtbase/ucrtbase.spec | 160 ++++++++++++++++++------------------
14 files changed, 519 insertions(+), 509 deletions(-)
Dec. 3, 2020
[PATCH 3/6] msvcrt: Remove MSVCRT_ prefix from math.c functions.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/crtdll/crtdll.spec | 96 ++---
dlls/msvcr100/msvcr100.spec | 206 +++++-----
dlls/msvcr110/msvcr110.spec | 230 +++++------
dlls/msvcr120/msvcr120.spec | 420 ++++++++++----------
dlls/msvcr70/msvcr70.spec | 98 ++---
dlls/msvcr71/msvcr71.spec | 98 ++---
dlls/msvcr80/msvcr80.spec | 202 +++++-----
dlls/msvcr90/msvcr90.spec | 200 +++++-----
dlls/msvcrt/math.c | 634 +++++++++++++++---------------
dlls/msvcrt/msvcrt.h | 3 -
dlls/msvcrt/msvcrt.spec | 214 +++++-----
dlls/msvcrt/printf.h | 6 +-
dlls/msvcrt/string.c | 2 +-
dlls/msvcrtd/msvcrtd.spec | 96 ++---
dlls/ucrtbase/ucrtbase.spec | 750 ++++++++++++++++++------------------
include/msvcrt/math.h | 31 +-
16 files changed, 1649 insertions(+), 1637 deletions(-)
Dec. 3, 2020
[PATCH 2/6] msvcrt: Remove MSVCRT_ prefix from wcs.c functions.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/crtdll/crtdll.spec | 102 ++---
dlls/msvcr100/msvcr100.spec | 334 +++++++--------
dlls/msvcr110/msvcr110.spec | 334 +++++++--------
dlls/msvcr120/msvcr120.spec | 358 ++++++++--------
dlls/msvcr70/msvcr70.spec | 122 +++---
dlls/msvcr71/msvcr71.spec | 130 +++---
dlls/msvcr80/msvcr80.spec | 334 +++++++--------
dlls/msvcr90/msvcr90.spec | 334 +++++++--------
dlls/msvcrt/console.c | 2 +-
dlls/msvcrt/data.c | 16 +-
dlls/msvcrt/dir.c | 36 +-
dlls/msvcrt/environ.c | 16 +-
dlls/msvcrt/errno.c | 12 +-
dlls/msvcrt/exit.c | 6 +-
dlls/msvcrt/file.c | 28 +-
dlls/msvcrt/locale.c | 28 +-
dlls/msvcrt/main.c | 2 +-
dlls/msvcrt/math.c | 14 +-
dlls/msvcrt/mbcs.c | 20 +-
dlls/msvcrt/msvcrt.h | 32 --
dlls/msvcrt/msvcrt.spec | 316 +++++++-------
dlls/msvcrt/printf.h | 6 +-
dlls/msvcrt/process.c | 36 +-
dlls/msvcrt/scanf.h | 2 +-
dlls/msvcrt/string.c | 4 +-
dlls/msvcrt/time.c | 14 +-
dlls/msvcrt/undname.c | 2 +-
dlls/msvcrt/wcs.c | 683 +++++++++++++++----------------
dlls/msvcrtd/msvcrtd.spec | 108 ++---
dlls/ucrtbase/ucrtbase.spec | 452 ++++++++++----------
include/msvcrt/corecrt_wctype.h | 9 +
include/msvcrt/corecrt_wstdio.h | 5 +-
include/msvcrt/corecrt_wstdlib.h | 2 +
include/msvcrt/stdio.h | 10 +
34 files changed, 1949 insertions(+), 1960 deletions(-)
Dec. 3, 2020
[PATCH 1/6] msvcrt: Remove MSVCRT_ prefix from time.c functions.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/crtdll/crtdll.spec | 35 +++--
dlls/msvcr100/msvcr100.spec | 96 ++++++------
dlls/msvcr110/msvcr110.spec | 96 ++++++------
dlls/msvcr120/msvcr120.spec | 96 ++++++------
dlls/msvcr70/msvcr70.spec | 64 ++++----
dlls/msvcr71/msvcr71.spec | 63 ++++----
dlls/msvcr80/msvcr80.spec | 96 ++++++------
dlls/msvcr90/msvcr90.spec | 96 ++++++------
dlls/msvcrt/file.c | 3 +-
dlls/msvcrt/msvcrt.spec | 117 +++++++-------
dlls/msvcrt/time.c | 301 +++++++++++-------------------------
dlls/msvcrtd/msvcrtd.spec | 50 +++---
dlls/ucrtbase/ucrtbase.spec | 170 ++++++++++----------
13 files changed, 598 insertions(+), 685 deletions(-)
Dec. 3, 2020
Re: [PATCH] urlmon: Use wide-char string literals.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH v2 2/2] jscript: Clean up date formatting strings with era.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH v2 1/2] jscript: Use wide-char string literals.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH v4 08/12] winegstreamer: Implement ::SetOutputType for audio conversion transform.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH v4 07/12] winegstreamer: Implement ::SetInputType for audio conversion transform.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH v4 06/12] winegstreamer: Implement ::ProcessMessage for audio conversion MFT.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH 3/7] d3d9/tests: Skip pretransformed_varying_test() on 32-bit WARP.
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=83051
Your paranoid android.
=== w1064v1809 (32 bit report) ===
d3d9:
visual.c:22018: Test failed: Failed to update texture, hr 0x80004005, case 0, 9.
=== w1064 (32 bit report) ===
d3d9:
visual.c:22018: Test failed: Failed to update texture, hr 0x80004005, case 0, 9.
=== w10pro64 (32 bit report) ===
d3d9:
visual.c:22018: Test failed: Failed to update texture, hr 0x80004005, case 0, 9.
Dec. 3, 2020
Re: [PATCH v4 05/12] winegstreamer: Implement ::GetOutputAvailableType for audio conversion transform.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH v4 04/12] winegstreamer: Implement ::GetInputAvailableType for audio conversion transform.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH v5 03/12] winegstreamer: Register the audio conversion transform.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH v5 02/12] winegstreamer: Introduce audio conversion transform.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 3, 2020
[PATCH 7/7] winex11: Add an XRender format for X2R10G10B10.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
Fixes a number of crashes when running the X server at 30 bit depth on
AMD.
dlls/winex11.drv/xrender.c | 26 ++++++++++++++------------
1 file changed, 14 insertions(+), 12 deletions(-)
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index 3376cee517d..c5510f625c4 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -67,6 +67,7 @@ enum wxr_format
WXR_FORMAT_B8G8R8A8,
WXR_FORMAT_X8R8G8B8,
WXR_FORMAT_B8G8R8X8,
+ WXR_FORMAT_X2R10G10B10,
WXR_FORMAT_ROOT, /* placeholder for the format to use on the root window */
WXR_NB_FORMATS,
WXR_INVALID_FORMAT = WXR_NB_FORMATS
@@ -88,18 +89,19 @@ typedef struct wine_xrender_format_template
static const WineXRenderFormatTemplate wxr_formats_template[WXR_NB_FORMATS] =
{
/* Format depth alpha mask red mask green mask blue mask*/
-/* WXR_FORMAT_MONO */ { 1, 0, 0x01, 0, 0, 0, 0, 0, 0 },
-/* WXR_FORMAT_GRAY */ { 8, 0, 0xff, 0, 0, 0, 0, 0, 0 },
-/* WXR_FORMAT_X1R5G5B5 */ { 16, 0, 0, 10, 0x1f, 5, 0x1f, 0, 0x1f },
-/* WXR_FORMAT_X1B5G5R5 */ { 16, 0, 0, 0, 0x1f, 5, 0x1f, 10, 0x1f },
-/* WXR_FORMAT_R5G6B5 */ { 16, 0, 0, 11, 0x1f, 5, 0x3f, 0, 0x1f },
-/* WXR_FORMAT_B5G6R5 */ { 16, 0, 0, 0, 0x1f, 5, 0x3f, 11, 0x1f },
-/* WXR_FORMAT_R8G8B8 */ { 24, 0, 0, 16, 0xff, 8, 0xff, 0, 0xff },
-/* WXR_FORMAT_B8G8R8 */ { 24, 0, 0, 0, 0xff, 8, 0xff, 16, 0xff },
-/* WXR_FORMAT_A8R8G8B8 */ { 32, 24, 0xff, 16, 0xff, 8, 0xff, 0, 0xff },
-/* WXR_FORMAT_B8G8R8A8 */ { 32, 0, 0xff, 8, 0xff, 16, 0xff, 24, 0xff },
-/* WXR_FORMAT_X8R8G8B8 */ { 32, 0, 0, 16, 0xff, 8, 0xff, 0, 0xff },
-/* WXR_FORMAT_B8G8R8X8 */ { 32, 0, 0, 8, 0xff, 16, 0xff, 24, 0xff },
+/* WXR_FORMAT_MONO */ { 1, 0, 0x01, 0, 0, 0, 0, 0, 0 },
+/* WXR_FORMAT_GRAY */ { 8, 0, 0xff, 0, 0, 0, 0, 0, 0 },
+/* WXR_FORMAT_X1R5G5B5 */ { 16, 0, 0, 10, 0x1f, 5, 0x1f, 0, 0x1f },
+/* WXR_FORMAT_X1B5G5R5 */ { 16, 0, 0, 0, 0x1f, 5, 0x1f, 10, 0x1f },
+/* WXR_FORMAT_R5G6B5 */ { 16, 0, 0, 11, 0x1f, 5, 0x3f, 0, 0x1f },
+/* WXR_FORMAT_B5G6R5 */ { 16, 0, 0, 0, 0x1f, 5, 0x3f, 11, 0x1f },
+/* WXR_FORMAT_R8G8B8 */ { 24, 0, 0, 16, 0xff, 8, 0xff, 0, 0xff },
+/* WXR_FORMAT_B8G8R8 */ { 24, 0, 0, 0, 0xff, 8, 0xff, 16, 0xff },
+/* WXR_FORMAT_A8R8G8B8 */ { 32, 24, 0xff, 16, 0xff, 8, 0xff, 0, 0xff },
+/* WXR_FORMAT_B8G8R8A8 */ { 32, 0, 0xff, 8, 0xff, 16, 0xff, 24, 0xff },
+/* WXR_FORMAT_X8R8G8B8 */ { 32, 0, 0, 16, 0xff, 8, 0xff, 0, 0xff },
+/* WXR_FORMAT_B8G8R8X8 */ { 32, 0, 0, 8, 0xff, 16, 0xff, 24, 0xff },
+/* WXR_FORMAT_X2R10G10B10 */ { 30, 0, 0, 20, 0x3ff, 10, 0x3ff, 0, 0x3ff },
};
static enum wxr_format default_format = WXR_INVALID_FORMAT;
--
2.26.2
Dec. 3, 2020
[PATCH 6/7] wined3d: Don't use separate GL contexts for different swapchains.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
Try to avoid triggering a new Mesa slowpath introduced by Mesa commit
e7f3a8d6959c74f63c877dd8776fe519d54f946f.
dlls/wined3d/adapter_gl.c | 5 ++-
dlls/wined3d/context_gl.c | 27 ++++++++-----
dlls/wined3d/device.c | 41 +++++++++++++++++---
dlls/wined3d/swapchain.c | 70 ++++------------------------------
dlls/wined3d/wined3d_private.h | 14 +++----
5 files changed, 71 insertions(+), 86 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 4781622d530..7ea23f03937 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4560,8 +4560,11 @@ static HRESULT adapter_gl_init_3d(struct wined3d_device *device)
wined3d_cs_init_object(device->cs, wined3d_device_create_primary_opengl_context_cs, device);
wined3d_cs_finish(device->cs, WINED3D_CS_QUEUE_DEFAULT);
- if (!wined3d_swapchain_gl(device->swapchains[0])->context_count)
+ if (!device->context_count)
+ {
+ WARN("Initialization failed.\n");
return E_FAIL;
+ }
return WINED3D_OK;
}
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index f2129c580e7..d789beb0cc5 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -1254,9 +1254,11 @@ success:
static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context_gl)
{
- struct wined3d_swapchain_gl *swapchain_gl = wined3d_swapchain_gl(context_gl->c.swapchain);
+ struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
BOOL backup = FALSE;
+ TRACE("context_gl %p.\n", context_gl);
+
if (!wined3d_context_gl_set_pixel_format(context_gl))
{
WARN("Failed to set pixel format %d on device context %p.\n",
@@ -1271,23 +1273,21 @@ static BOOL wined3d_context_gl_set_gl_context(struct wined3d_context_gl *context
context_gl->valid = 0;
WARN("Trying fallback to the backup window.\n");
- /* FIXME: If the context is destroyed it's no longer associated with
- * a swapchain, so we can't use the swapchain to get a backup dc. To
- * make this work windowless contexts would need to be handled by the
- * device. */
- if (context_gl->c.destroyed || !swapchain_gl)
+ if (context_gl->c.destroyed || !device_gl)
{
FIXME("Unable to get backup dc for destroyed context %p.\n", context_gl);
wined3d_context_gl_set_current(NULL);
return FALSE;
}
- if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl)))
+ if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(device_gl)))
{
+ WARN("Failed to get a backup DC.\n");
wined3d_context_gl_set_current(NULL);
return FALSE;
}
+ TRACE("Using backup DC %p.\n", context_gl->dc);
context_gl->dc_is_private = TRUE;
context_gl->dc_has_format = FALSE;
@@ -1364,6 +1364,8 @@ static void wined3d_context_gl_cleanup(struct wined3d_context_gl *context_gl)
HDC restore_dc;
unsigned int i;
+ TRACE("context_gl %p.\n", context_gl);
+
restore_ctx = wglGetCurrentContext();
restore_dc = wglGetCurrentDC();
@@ -1993,7 +1995,7 @@ static BOOL wined3d_context_gl_create_wgl_ctx(struct wined3d_context_gl *context
context_gl->pixel_format, context_gl->dc);
wined3d_release_dc(context_gl->window, context_gl->dc);
- if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl)))
+ if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(wined3d_device_gl(device))))
{
ERR("Failed to retrieve the backup device context.\n");
return FALSE;
@@ -2069,7 +2071,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi
if (!context_gl->dc)
{
- if (!(context_gl->dc = wined3d_swapchain_gl_get_backup_dc(swapchain_gl)))
+ if (!(context_gl->dc = wined3d_device_gl_get_backup_dc(wined3d_device_gl(device))))
{
ERR("Failed to retrieve a device context.\n");
return E_FAIL;
@@ -2306,6 +2308,7 @@ void wined3d_context_gl_destroy(struct wined3d_context_gl *context_gl)
context_gl->c.destroy_delayed = 1;
/* FIXME: Get rid of a pointer to swapchain from wined3d_context. */
context_gl->c.swapchain = NULL;
+ context_gl->c.device = NULL;
return;
}
@@ -4075,6 +4078,12 @@ static void wined3d_context_gl_activate(struct wined3d_context_gl *context_gl,
struct wined3d_texture *texture, unsigned int sub_resource_idx)
{
wined3d_context_gl_enter(context_gl);
+ if (texture && texture->swapchain && texture->swapchain != context_gl->c.swapchain)
+ {
+ TRACE("Switching context_gl %p from swapchain %p to swapchain %p.\n",
+ context_gl, context_gl->c.swapchain, texture->swapchain);
+ context_gl->c.swapchain = texture->swapchain;
+ }
wined3d_context_gl_update_window(context_gl);
wined3d_context_gl_setup_target(context_gl, texture, sub_resource_idx);
if (!context_gl->valid)
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index cc40125ac95..a0e046d1614 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -994,7 +994,6 @@ static void device_init_swapchain_state(struct wined3d_device *device, struct wi
void wined3d_device_delete_opengl_contexts_cs(void *object)
{
- struct wined3d_swapchain_gl *swapchain_gl;
struct wined3d_device *device = object;
struct wined3d_context_gl *context_gl;
struct wined3d_device_gl *device_gl;
@@ -1018,10 +1017,15 @@ void wined3d_device_delete_opengl_contexts_cs(void *object)
while (device->context_count)
{
- if ((swapchain_gl = wined3d_swapchain_gl(device->contexts[0]->swapchain)))
- wined3d_swapchain_gl_destroy_contexts(swapchain_gl);
- else
- wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0]));
+ wined3d_context_gl_destroy(wined3d_context_gl(device->contexts[0]));
+ }
+
+ if (device_gl->backup_dc)
+ {
+ TRACE("Destroying backup wined3d window %p, dc %p.\n", device_gl->backup_wnd, device_gl->backup_dc);
+
+ wined3d_release_dc(device_gl->backup_wnd, device_gl->backup_dc);
+ DestroyWindow(device_gl->backup_wnd);
}
}
@@ -5617,6 +5621,33 @@ void CDECL wined3d_device_get_gamma_ramp(const struct wined3d_device *device,
wined3d_swapchain_get_gamma_ramp(swapchain, ramp);
}
+HDC wined3d_device_gl_get_backup_dc(struct wined3d_device_gl *device_gl)
+{
+ TRACE("device_gl %p.\n", device_gl);
+
+ if (!device_gl->backup_dc)
+ {
+ TRACE("Creating the backup window for device %p.\n", device_gl);
+
+ if (!(device_gl->backup_wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
+ WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL)))
+ {
+ ERR("Failed to create a window.\n");
+ return NULL;
+ }
+
+ if (!(device_gl->backup_dc = GetDC(device_gl->backup_wnd)))
+ {
+ ERR("Failed to get a DC.\n");
+ DestroyWindow(device_gl->backup_wnd);
+ device_gl->backup_wnd = NULL;
+ return NULL;
+ }
+ }
+
+ return device_gl->backup_dc;
+}
+
void device_resource_add(struct wined3d_device *device, struct wined3d_resource *resource)
{
TRACE("device %p, resource %p.\n", device, resource);
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index ffffc18aa84..6a8d8a64a01 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -89,7 +89,6 @@ void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain)
static void wined3d_swapchain_gl_destroy_object(void *object)
{
- wined3d_swapchain_gl_destroy_contexts(object);
}
void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl)
@@ -100,14 +99,6 @@ void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl)
wined3d_cs_destroy_object(cs, wined3d_swapchain_gl_destroy_object, swapchain_gl);
wined3d_cs_finish(cs, WINED3D_CS_QUEUE_DEFAULT);
-
- if (swapchain_gl->backup_dc)
- {
- TRACE("Destroying backup wined3d window %p, dc %p.\n", swapchain_gl->backup_wnd, swapchain_gl->backup_dc);
-
- wined3d_release_dc(swapchain_gl->backup_wnd, swapchain_gl->backup_dc);
- DestroyWindow(swapchain_gl->backup_wnd);
- }
}
static void wined3d_swapchain_vk_destroy_vulkan_swapchain(struct wined3d_swapchain_vk *swapchain_vk)
@@ -500,7 +491,6 @@ static void wined3d_swapchain_gl_rotate(struct wined3d_swapchain *swapchain, str
static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
const RECT *src_rect, const RECT *dst_rect, unsigned int swap_interval, DWORD flags)
{
- struct wined3d_swapchain_gl *swapchain_gl = wined3d_swapchain_gl(swapchain);
const struct wined3d_swapchain_desc *desc = &swapchain->state.desc;
struct wined3d_texture *back_buffer = swapchain->back_buffers[0];
const struct wined3d_gl_info *gl_info;
@@ -554,8 +544,11 @@ static void swapchain_gl_present(struct wined3d_swapchain *swapchain,
if (swapchain->render_to_fbo)
swapchain_blit(swapchain, context, src_rect, dst_rect);
- if (swapchain_gl->context_count > 1)
+ if (swapchain->device->context_count > 1)
+ {
+ TRACE("Multiple contexts, calling glFinish() to enforce ordering.\n");
gl_info->gl_ops.gl.p_glFinish();
+ }
/* call wglSwapBuffers through the gl table to avoid confusing the Steam overlay */
gl_info->gl_ops.wgl.p_wglSwapBuffers(context_gl->dc);
@@ -1692,72 +1685,25 @@ static struct wined3d_context_gl *wined3d_swapchain_gl_create_context(struct win
context_release(&context_gl->c);
- if (!wined3d_array_reserve((void **)&swapchain_gl->contexts, &swapchain_gl->contexts_size,
- swapchain_gl->context_count + 1, sizeof(*swapchain_gl->contexts)))
- {
- ERR("Failed to allocate new context array memory.\n");
- wined3d_context_gl_destroy(context_gl);
- return NULL;
- }
- swapchain_gl->contexts[swapchain_gl->context_count++] = context_gl;
-
return context_gl;
}
-void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl)
-{
- unsigned int i;
-
- for (i = 0; i < swapchain_gl->context_count; ++i)
- {
- wined3d_context_gl_destroy(swapchain_gl->contexts[i]);
- }
- heap_free(swapchain_gl->contexts);
- swapchain_gl->contexts_size = 0;
- swapchain_gl->context_count = 0;
- swapchain_gl->contexts = NULL;
-}
-
struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl)
{
+ struct wined3d_device *device = swapchain_gl->s.device;
DWORD tid = GetCurrentThreadId();
unsigned int i;
- for (i = 0; i < swapchain_gl->context_count; ++i)
+ for (i = 0; i < device->context_count; ++i)
{
- if (swapchain_gl->contexts[i]->tid == tid)
- return swapchain_gl->contexts[i];
+ if (wined3d_context_gl(device->contexts[i])->tid == tid)
+ return wined3d_context_gl(device->contexts[i]);
}
/* Create a new context for the thread. */
return wined3d_swapchain_gl_create_context(swapchain_gl);
}
-HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl)
-{
- if (!swapchain_gl->backup_dc)
- {
- TRACE("Creating the backup window for swapchain %p.\n", swapchain_gl);
-
- if (!(swapchain_gl->backup_wnd = CreateWindowA(WINED3D_OPENGL_WINDOW_CLASS_NAME, "WineD3D fake window",
- WS_OVERLAPPEDWINDOW, 10, 10, 10, 10, NULL, NULL, NULL, NULL)))
- {
- ERR("Failed to create a window.\n");
- return NULL;
- }
-
- if (!(swapchain_gl->backup_dc = GetDC(swapchain_gl->backup_wnd)))
- {
- ERR("Failed to get a DC.\n");
- DestroyWindow(swapchain_gl->backup_wnd);
- swapchain_gl->backup_wnd = NULL;
- return NULL;
- }
- }
-
- return swapchain_gl->backup_dc;
-}
-
void swapchain_update_draw_bindings(struct wined3d_swapchain *swapchain)
{
UINT i;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index cf8c345a678..cbb930200df 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3852,6 +3852,9 @@ struct wined3d_device_gl
uint64_t completed_fence_id;
uint64_t current_fence_id;
+
+ HWND backup_wnd;
+ HDC backup_dc;
};
static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device *device)
@@ -3859,6 +3862,8 @@ static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device
return CONTAINING_RECORD(device, struct wined3d_device_gl, d);
}
+HDC wined3d_device_gl_get_backup_dc(struct wined3d_device_gl *device_gl) DECLSPEC_HIDDEN;
+
struct wined3d_null_image_vk
{
VkImage vk_image;
@@ -5191,13 +5196,6 @@ HRESULT wined3d_swapchain_no3d_init(struct wined3d_swapchain *swapchain_no3d,
struct wined3d_swapchain_gl
{
struct wined3d_swapchain s;
-
- struct wined3d_context_gl **contexts;
- SIZE_T contexts_size;
- SIZE_T context_count;
-
- HDC backup_dc;
- HWND backup_wnd;
};
static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_swapchain *swapchain)
@@ -5206,8 +5204,6 @@ static inline struct wined3d_swapchain_gl *wined3d_swapchain_gl(struct wined3d_s
}
void wined3d_swapchain_gl_cleanup(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN;
-void wined3d_swapchain_gl_destroy_contexts(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN;
-HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN;
struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN;
HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl,
struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
--
2.26.2
Dec. 3, 2020
[PATCH 5/7] wined3d: Don't try to cleanup an invalid context.
by Matteo Bruni
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49817
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
In particular, if switching away from a destroyed context fails we
call wined3d_context_gl_set_current(NULL) which will attempt to clear
the current context again, recursively.
dlls/wined3d/context_gl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index eb0bd4a314f..f2129c580e7 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -1542,7 +1542,7 @@ BOOL wined3d_context_gl_set_current(struct wined3d_context_gl *context_gl)
return TRUE;
}
- if (old)
+ if (old && old->valid)
{
if (old->c.destroyed)
{
--
2.26.2
Dec. 3, 2020
[PATCH 4/7] d3d9/tests: Accept new WARP test failure in test_updatetexture().
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
dlls/d3d9/tests/visual.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 99896b8c624..40585d5257d 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -21754,7 +21754,7 @@ static void test_updatetexture(void)
UINT dst_width, dst_height;
UINT src_levels, dst_levels;
D3DFORMAT src_format, dst_format;
- BOOL broken;
+ BOOL broken_result, broken_updatetex;
}
tests[] =
{
@@ -21772,7 +21772,8 @@ static void test_updatetexture(void)
* one or something like that). */
/* {8, 8, 7, 7, 4, 2, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
{8, 8, 8, 8, 1, 4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 8 */
- {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, /* 9 */
+ /* For this one UpdateTexture() returns failure on WARP on > Win 10 1709. */
+ {4, 4, 8, 8, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE, TRUE}, /* 9 */
/* This one causes weird behavior on Windows (it probably writes out
* of the texture memory). */
/* {8, 8, 4, 4, 1, 1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FALSE}, */
@@ -22015,7 +22016,8 @@ static void test_updatetexture(void)
hr = IDirect3DDevice9_UpdateTexture(device, src, dst);
if (FAILED(hr))
{
- todo_wine ok(SUCCEEDED(hr), "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
+ todo_wine ok(SUCCEEDED(hr) || broken(tests[i].broken_updatetex),
+ "Failed to update texture, hr %#x, case %u, %u.\n", hr, t, i);
IDirect3DBaseTexture9_Release(src);
IDirect3DBaseTexture9_Release(dst);
continue;
@@ -22039,7 +22041,7 @@ static void test_updatetexture(void)
ok(SUCCEEDED(hr), "Failed to end scene, hr %#x.\n", hr);
color = getPixelColor(device, 320, 240);
- ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken)
+ ok (color_match(color, 0x007f7f00, 3) || broken(tests[i].broken_result)
|| broken(color == 0x00adbeef), /* WARP device often just breaks down. */
"Got unexpected color 0x%08x, case %u, %u.\n", color, t, i);
}
--
2.26.2
Dec. 3, 2020
[PATCH 3/7] d3d9/tests: Skip pretransformed_varying_test() on 32-bit WARP.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
dlls/d3d9/tests/visual.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/dlls/d3d9/tests/visual.c b/dlls/d3d9/tests/visual.c
index 504d276d6c5..99896b8c624 100644
--- a/dlls/d3d9/tests/visual.c
+++ b/dlls/d3d9/tests/visual.c
@@ -8150,6 +8150,7 @@ static void pretransformed_varying_test(void)
},
};
IDirect3DVertexDeclaration9 *decl;
+ D3DADAPTER_IDENTIFIER9 identifier;
IDirect3DDevice9 *device;
IDirect3D9 *d3d;
unsigned int i;
@@ -8177,6 +8178,18 @@ static void pretransformed_varying_test(void)
goto done;
}
+ hr = IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &identifier);
+ ok(SUCCEEDED(hr), "Failed to get adapter identifier, hr %#x.\n", hr);
+ if (adapter_is_warp(&identifier) && sizeof(UINT) == sizeof(UINT_PTR))
+ {
+ /* Apparently the "monster" vertex declaration used in this test
+ * overruns some stack buffer (DrawPrimitiveUP crashes with a
+ * 0xc0000409 exception) on 32-bit WARP since Win 10 1809. */
+ skip("Test crashes on recent 32-bit WARP.\n");
+ IDirect3DDevice9_Release(device);
+ goto done;
+ }
+
hr = IDirect3DDevice9_CreateVertexDeclaration(device, decl_elements, &decl);
ok(hr == D3D_OK, "IDirect3DDevice9_CreateVertexDeclaration returned %08x\n", hr);
hr = IDirect3DDevice9_SetVertexDeclaration(device, decl);
--
2.26.2
Dec. 3, 2020
[PATCH 2/7] wined3d: Allow forcing commands serialization in the CS thread.
by Matteo Bruni
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
This is useful, aside from testing, for applications using multiple
d3d devices from multiple threads (like e.g. MS Office 2013+) with
OpenGL drivers that aren't multithread-safe. At this moment Nouveau is
a known offender.
This supersedes patch 196948.
dlls/wined3d/cs.c | 20 +++++++++++++++++++-
dlls/wined3d/wined3d_main.c | 14 +++++++++++++-
dlls/wined3d/wined3d_private.h | 6 ++++++
3 files changed, 38 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/cs.c b/dlls/wined3d/cs.c
index 48b73a71fe4..0b9c5f70043 100644
--- a/dlls/wined3d/cs.c
+++ b/dlls/wined3d/cs.c
@@ -21,6 +21,7 @@
#include "wined3d_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_sync);
WINE_DECLARE_DEBUG_CHANNEL(fps);
#define WINED3D_INITIAL_CS_SIZE 4096
@@ -2866,6 +2867,18 @@ static void wined3d_cs_wait_event(struct wined3d_cs *cs)
WaitForSingleObject(cs->event, INFINITE);
}
+static void wined3d_cs_command_lock(const struct wined3d_cs *cs)
+{
+ if (cs->serialize_commands)
+ EnterCriticalSection(&wined3d_command_cs);
+}
+
+static void wined3d_cs_command_unlock(const struct wined3d_cs *cs)
+{
+ if (cs->serialize_commands)
+ LeaveCriticalSection(&wined3d_command_cs);
+}
+
static DWORD WINAPI wined3d_cs_run(void *ctx)
{
struct wined3d_cs_packet *packet;
@@ -2889,7 +2902,9 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
{
if (++poll == WINED3D_CS_QUERY_POLL_INTERVAL)
{
+ wined3d_cs_command_lock(cs);
poll_queries(cs);
+ wined3d_cs_command_unlock(cs);
poll = 0;
}
@@ -2920,7 +2935,9 @@ static DWORD WINAPI wined3d_cs_run(void *ctx)
break;
}
+ wined3d_cs_command_lock(cs);
wined3d_cs_op_handlers[opcode](cs, packet->data);
+ wined3d_cs_command_unlock(cs);
TRACE("%s executed.\n", debug_cs_op(opcode));
}
@@ -2945,6 +2962,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
cs->ops = &wined3d_cs_st_ops;
cs->device = device;
+ cs->serialize_commands = TRACE_ON(d3d_sync) || wined3d_settings.cs_multithreaded & WINED3D_CSMT_SERIALIZE;
state_init(&cs->state, d3d_info, WINED3D_STATE_NO_REF | WINED3D_STATE_INIT_DEFAULT);
@@ -2952,7 +2970,7 @@ struct wined3d_cs *wined3d_cs_create(struct wined3d_device *device)
if (!(cs->data = heap_alloc(cs->data_size)))
goto fail;
- if (wined3d_settings.cs_multithreaded
+ if (wined3d_settings.cs_multithreaded & WINED3D_CSMT_ENABLE
&& !RtlIsCriticalSectionLockedByThread(NtCurrentTeb()->Peb->LoaderLock))
{
cs->ops = &wined3d_cs_mt_ops;
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index e1ed86e80ed..7118d4b4b71 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -96,11 +96,21 @@ static CRITICAL_SECTION_DEBUG wined3d_wndproc_cs_debug =
};
static CRITICAL_SECTION wined3d_wndproc_cs = {&wined3d_wndproc_cs_debug, -1, 0, 0, 0, 0};
+CRITICAL_SECTION wined3d_command_cs;
+static CRITICAL_SECTION_DEBUG wined3d_command_cs_debug =
+{
+ 0, 0, &wined3d_command_cs,
+ {&wined3d_command_cs_debug.ProcessLocksList,
+ &wined3d_command_cs_debug.ProcessLocksList},
+ 0, 0, {(DWORD_PTR)(__FILE__ ": wined3d_command_cs")}
+};
+CRITICAL_SECTION wined3d_command_cs = {&wined3d_command_cs_debug, -1, 0, 0, 0, 0};
+
/* When updating default value here, make sure to update winecfg as well,
* where appropriate. */
struct wined3d_settings wined3d_settings =
{
- TRUE, /* Multithreaded CS by default. */
+ WINED3D_CSMT_ENABLE, /* Multithreaded CS by default. */
MAKEDWORD_VERSION(4, 4), /* Default to OpenGL 4.4 */
ORM_FBO, /* Use FBOs to do offscreen rendering */
PCI_VENDOR_NONE,/* PCI Vendor ID */
@@ -436,6 +446,8 @@ static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL)
heap_free(wined3d_settings.logo);
UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
+ DeleteCriticalSection(&wined3d_command_cs);
+
DeleteCriticalSection(&wined3d_wndproc_cs);
DeleteCriticalSection(&wined3d_cs);
return TRUE;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index b756c80ad8a..cf8c345a678 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -452,6 +452,9 @@ enum wined3d_shader_backend
WINED3D_SHADER_BACKEND_NONE,
};
+#define WINED3D_CSMT_ENABLE 0x00000001
+#define WINED3D_CSMT_SERIALIZE 0x00000002
+
/* NOTE: When adding fields to this structure, make sure to update the default
* values in wined3d_main.c as well. */
struct wined3d_settings
@@ -4670,6 +4673,7 @@ struct wined3d_cs
HMODULE wined3d_module;
HANDLE thread;
DWORD thread_id;
+ BOOL serialize_commands;
struct wined3d_cs_queue queue[WINED3D_CS_QUEUE_COUNT];
size_t data_size, start, end;
@@ -6353,4 +6357,6 @@ static inline void wined3d_context_gl_reference_bo(struct wined3d_context_gl *co
/* The WNDCLASS-Name for the fake window which we use to retrieve the GL capabilities */
#define WINED3D_OPENGL_WINDOW_CLASS_NAME "WineD3D_OpenGL"
+extern CRITICAL_SECTION wined3d_command_cs;
+
#endif
--
2.26.2
Dec. 3, 2020
[PATCH 1/7] wined3d: Rename d3d_synchronous debug channel to d3d_sync.
by Matteo Bruni
The old name exceeded the maximum size of 14 characters.
Signed-off-by: Matteo Bruni <mbruni(a)codeweavers.com>
---
This supersedes patch 196943.
dlls/wined3d/context_gl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 83c61834f5a..eb0bd4a314f 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -31,7 +31,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(d3d);
WINE_DECLARE_DEBUG_CHANNEL(d3d_perf);
-WINE_DECLARE_DEBUG_CHANNEL(d3d_synchronous);
+WINE_DECLARE_DEBUG_CHANNEL(d3d_sync);
#define WINED3D_MAX_FBO_ENTRIES 64
#define WINED3D_ALL_LAYERS (~0u)
@@ -2144,7 +2144,7 @@ HRESULT wined3d_context_gl_init(struct wined3d_context_gl *context_gl, struct wi
if (context_debug_output_enabled(gl_info))
{
GL_EXTCALL(glDebugMessageCallback(wined3d_debug_callback, context));
- if (TRACE_ON(d3d_synchronous))
+ if (TRACE_ON(d3d_sync))
gl_info->gl_ops.gl.p_glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
GL_EXTCALL(glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, NULL, GL_FALSE));
if (ERR_ON(d3d))
--
2.26.2
Dec. 3, 2020
Re: [PATCH] crypt32: Fix reading and writing CRYPT_KEY_PROV_INFO certificate property.
by Dmitry Timoshkov
Alexandre Julliard <julliard(a)winehq.org> wrote:
> >> > Is there anything that could be improved to make this patch accepted?
> >>
> >> It's fairly large, it would help if you could do this in smaller chunks
> >> somehow.
> >
> > The patch implements both serializer and deserializer of the CRYPT_KEY_PROV_INFO
> > property, and that can't be split without breaking too much. I can send the tests
> > separately though. Is that acceptable?
>
> That's a first step but it would be good to split further, the hard to
> review bits are not the tests.
Unfortunately I don't see a way to separate serializer and deserializer,
missing any of them would lead to major breakage. The tests are supposed
to verify the implemented functionality, perhaps that could mitigate
the patch size.
--
Dmitry.
Dec. 3, 2020
[PATCH v5 03/12] winegstreamer: Register the audio conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v5: Reword commit message.
---
dlls/winegstreamer/gst_private.h | 1 +
dlls/winegstreamer/main.c | 3 +-
dlls/winegstreamer/mfplat.c | 69 ++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 7889c996204..9518f721504 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -76,6 +76,7 @@ BOOL init_gstreamer(void) DECLSPEC_HIDDEN;
void start_dispatch_thread(void) DECLSPEC_HIDDEN;
extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN;
+extern HRESULT mfplat_DllRegisterServer(void) DECLSPEC_HIDDEN;
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN;
diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
index 4ca371d58bd..385c5550235 100644
--- a/dlls/winegstreamer/main.c
+++ b/dlls/winegstreamer/main.c
@@ -368,7 +368,8 @@ HRESULT WINAPI DllRegisterServer(void)
IFilterMapper2_RegisterFilter(mapper, &CLSID_WAVEParser, wave_parserW, NULL, NULL, NULL, ®_wave_parser);
IFilterMapper2_Release(mapper);
- return S_OK;
+
+ return mfplat_DllRegisterServer();
}
HRESULT WINAPI DllUnregisterServer(void)
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 095a9b81091..f300988fc5c 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -445,6 +445,75 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
return CLASS_E_CLASSNOTAVAILABLE;
}
+static WCHAR audio_converterW[] = {'A','u','d','i','o',' ','C','o','n','v','e','r','t','e','r',0};
+static const GUID *audio_converter_supported_types[] =
+{
+ &MFAudioFormat_PCM,
+ &MFAudioFormat_Float,
+};
+
+static const struct mft
+{
+ const GUID *clsid;
+ const GUID *category;
+ LPWSTR name;
+ const UINT32 flags;
+ const GUID *major_type;
+ const UINT32 input_types_count;
+ const GUID **input_types;
+ const UINT32 output_types_count;
+ const GUID **output_types;
+ IMFAttributes *attributes;
+}
+mfts[] =
+{
+ {
+ &CLSID_WINEAudioConverter,
+ &MFT_CATEGORY_AUDIO_EFFECT,
+ audio_converterW,
+ MFT_ENUM_FLAG_SYNCMFT,
+ &MFMediaType_Audio,
+ ARRAY_SIZE(audio_converter_supported_types),
+ audio_converter_supported_types,
+ ARRAY_SIZE(audio_converter_supported_types),
+ audio_converter_supported_types,
+ NULL
+ },
+};
+
+HRESULT mfplat_DllRegisterServer(void)
+{
+ unsigned int i, j;
+ HRESULT hr;
+ MFT_REGISTER_TYPE_INFO input_types[2], output_types[2];
+
+ for (i = 0; i < ARRAY_SIZE(mfts); i++)
+ {
+ const struct mft *cur = &mfts[i];
+
+ for (j = 0; j < cur->input_types_count; j++)
+ {
+ input_types[j].guidMajorType = *(cur->major_type);
+ input_types[j].guidSubtype = *(cur->input_types[j]);
+ }
+ for (j = 0; j < cur->output_types_count; j++)
+ {
+ output_types[j].guidMajorType = *(cur->major_type);
+ output_types[j].guidSubtype = *(cur->output_types[j]);
+ }
+
+ hr = MFTRegister(*(cur->clsid), *(cur->category), cur->name, cur->flags, cur->input_types_count,
+ input_types, cur->output_types_count, output_types, cur->attributes);
+
+ if (FAILED(hr))
+ {
+ FIXME("Failed to register MFT, hr %#x\n", hr);
+ return hr;
+ }
+ }
+ return S_OK;
+}
+
static const struct
{
const GUID *subtype;
--
2.29.2
Dec. 3, 2020
[PATCH v5 02/12] winegstreamer: Introduce audio conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v5: Add copyright notice.
---
dlls/winegstreamer/Makefile.in | 1 +
dlls/winegstreamer/audioconvert.c | 304 +++++++++++++++++++
dlls/winegstreamer/gst_private.h | 2 +
dlls/winegstreamer/mfplat.c | 3 +
dlls/winegstreamer/winegstreamer_classes.idl | 6 +
5 files changed, 316 insertions(+)
create mode 100644 dlls/winegstreamer/audioconvert.c
diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
index e578d194f7f..0b3229160b9 100644
--- a/dlls/winegstreamer/Makefile.in
+++ b/dlls/winegstreamer/Makefile.in
@@ -6,6 +6,7 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
PARENTSRC = ../strmbase
C_SRCS = \
+ audioconvert.c \
filter.c \
gst_cbs.c \
gstdemux.c \
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
new file mode 100644
index 00000000000..1c0fcf660c9
--- /dev/null
+++ b/dlls/winegstreamer/audioconvert.c
@@ -0,0 +1,304 @@
+/* GStreamer Audio Converter
+ *
+ * Copyright 2020 Derek Lesho
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include "gst_private.h"
+
+#include "mfapi.h"
+#include "mferror.h"
+#include "mfidl.h"
+#include "ks.h"
+#include "ksmedia.h"
+
+#include "wine/debug.h"
+#include "wine/heap.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
+
+struct audio_converter
+{
+ IMFTransform IMFTransform_iface;
+ LONG refcount;
+};
+
+static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface)
+{
+ return CONTAINING_RECORD(iface, struct audio_converter, IMFTransform_iface);
+}
+
+static HRESULT WINAPI audio_converter_QueryInterface(IMFTransform *iface, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+ if (IsEqualIID(riid, &IID_IMFTransform) ||
+ IsEqualIID(riid, &IID_IUnknown))
+ {
+ *obj = iface;
+ IMFTransform_AddRef(iface);
+ return S_OK;
+ }
+
+ WARN("Unsupported %s.\n", debugstr_guid(riid));
+ *obj = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI audio_converter_AddRef(IMFTransform *iface)
+{
+ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
+ ULONG refcount = InterlockedIncrement(&transform->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
+{
+ struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
+ ULONG refcount = InterlockedDecrement(&transform->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ heap_free(transform);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI audio_converter_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum,
+ DWORD *output_minimum, DWORD *output_maximum)
+{
+ TRACE("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum);
+
+ *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI audio_converter_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs)
+{
+ TRACE("%p, %p, %p.\n", iface, inputs, outputs);
+
+ *inputs = *outputs = 1;
+
+ return S_OK;
+}
+
+static HRESULT WINAPI audio_converter_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
+ DWORD output_size, DWORD *outputs)
+{
+ TRACE("%p %u %p %u %p.\n", iface, input_size, inputs, output_size, outputs);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
+{
+ FIXME("%p %u %p.\n", iface, id, info);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
+{
+ FIXME("%p %u %p.\n", iface, id, info);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
+{
+ FIXME("%p, %p.\n", iface, attributes);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
+ IMFAttributes **attributes)
+{
+ FIXME("%p, %u, %p.\n", iface, id, attributes);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
+ IMFAttributes **attributes)
+{
+ FIXME("%p, %u, %p.\n", iface, id, attributes);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_DeleteInputStream(IMFTransform *iface, DWORD id)
+{
+ TRACE("%p, %u.\n", iface, id);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids)
+{
+ TRACE("%p, %u, %p.\n", iface, streams, ids);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
+ IMFMediaType **type)
+{
+ FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
+ IMFMediaType **type)
+{
+ FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
+{
+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
+{
+ FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
+{
+ FIXME("%p, %u, %p.\n", iface, id, type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
+{
+ FIXME("%p, %u, %p.\n", iface, id, type);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
+{
+ FIXME("%p, %u, %p.\n", iface, id, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_GetOutputStatus(IMFTransform *iface, DWORD *flags)
+{
+ FIXME("%p, %p.\n", iface, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper)
+{
+ FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper));
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event)
+{
+ TRACE("%p, %u, %p.\n", iface, id, event);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
+{
+ FIXME("%p, %u %lu.\n", iface, message, param);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
+{
+ FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI audio_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
+ MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
+{
+ FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
+
+ return E_NOTIMPL;
+}
+
+static const IMFTransformVtbl audio_converter_vtbl =
+{
+ audio_converter_QueryInterface,
+ audio_converter_AddRef,
+ audio_converter_Release,
+ audio_converter_GetStreamLimits,
+ audio_converter_GetStreamCount,
+ audio_converter_GetStreamIDs,
+ audio_converter_GetInputStreamInfo,
+ audio_converter_GetOutputStreamInfo,
+ audio_converter_GetAttributes,
+ audio_converter_GetInputStreamAttributes,
+ audio_converter_GetOutputStreamAttributes,
+ audio_converter_DeleteInputStream,
+ audio_converter_AddInputStreams,
+ audio_converter_GetInputAvailableType,
+ audio_converter_GetOutputAvailableType,
+ audio_converter_SetInputType,
+ audio_converter_SetOutputType,
+ audio_converter_GetInputCurrentType,
+ audio_converter_GetOutputCurrentType,
+ audio_converter_GetInputStatus,
+ audio_converter_GetOutputStatus,
+ audio_converter_SetOutputBounds,
+ audio_converter_ProcessEvent,
+ audio_converter_ProcessMessage,
+ audio_converter_ProcessInput,
+ audio_converter_ProcessOutput,
+};
+
+HRESULT audio_converter_create(REFIID riid, void **ret)
+{
+ struct audio_converter *object;
+
+ TRACE("%s %p\n", debugstr_guid(riid), ret);
+
+ if (!(object = heap_alloc_zero(sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ object->IMFTransform_iface.lpVtbl = &audio_converter_vtbl;
+ object->refcount = 1;
+
+ *ret = &object->IMFTransform_iface;
+ return S_OK;
+}
diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
index 28e424439d8..7889c996204 100644
--- a/dlls/winegstreamer/gst_private.h
+++ b/dlls/winegstreamer/gst_private.h
@@ -84,4 +84,6 @@ IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN;
HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
+HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
+
#endif /* __GST_PRIVATE_INCLUDED__ */
diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
index 3a160d68093..095a9b81091 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -405,6 +405,8 @@ failed:
static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
+static const GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}};
+
static const struct class_object
{
const GUID *clsid;
@@ -414,6 +416,7 @@ class_objects[] =
{
{ &CLSID_VideoProcessorMFT, &video_processor_create },
{ &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
+ { &CLSID_WINEAudioConverter, &audio_converter_create },
};
HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
index 1dc4ba9a10b..cf1fc69f38a 100644
--- a/dlls/winegstreamer/winegstreamer_classes.idl
+++ b/dlls/winegstreamer/winegstreamer_classes.idl
@@ -61,3 +61,9 @@ coclass VideoProcessorMFT {}
uuid(317df618-5e5a-468a-9f15-d827a9a08162)
]
coclass GStreamerByteStreamHandler {}
+
+[
+ threading(both),
+ uuid(6a170414-aad9-4693-b806-3a0c47c570d6)
+]
+coclass WINEAudioConverter { }
--
2.29.2
Dec. 3, 2020
Re: [PATCH] crypt32: Fix reading and writing CRYPT_KEY_PROV_INFO certificate property.
by Alexandre Julliard
Dmitry Timoshkov <dmitry(a)baikal.ru> writes:
> Alexandre Julliard <julliard(a)winehq.org> wrote:
>
>> > Is there anything that could be improved to make this patch accepted?
>>
>> It's fairly large, it would help if you could do this in smaller chunks
>> somehow.
>
> The patch implements both serializer and deserializer of the CRYPT_KEY_PROV_INFO
> property, and that can't be split without breaking too much. I can send the tests
> separately though. Is that acceptable?
That's a first step but it would be good to split further, the hard to
review bits are not the tests.
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 3, 2020
[PATCH v3 2/2] crypt32/tests: Add some tests for CRYPT_KEY_PROV_INFO certificate property.
by Dmitry Timoshkov
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50024
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/crypt32/tests/cert.c | 96 +++++++++++++++++++++++++++++++++++++++
1 file changed, 96 insertions(+)
diff --git a/dlls/crypt32/tests/cert.c b/dlls/crypt32/tests/cert.c
index d9f839c72d..745770f009 100644
--- a/dlls/crypt32/tests/cert.c
+++ b/dlls/crypt32/tests/cert.c
@@ -4142,6 +4142,101 @@ static void testGetPublicKeyLength(void)
"Expected length 56, got %d\n", ret);
}
+static void testKeyProvInfo(void)
+{
+ static WCHAR containerW[] = L"Wine Test Container";
+ static WCHAR providerW[] = L"Hello World CSP";
+ static CRYPT_KEY_PROV_PARAM param[2] = { { 0x4444, (BYTE *)"param", 6, 0x5555 }, { 0x7777, (BYTE *)"param2", 7, 0x8888 } };
+ HCERTSTORE store;
+ const CERT_CONTEXT *cert;
+ CERT_NAME_BLOB name;
+ CRYPT_KEY_PROV_INFO *info, info2;
+ BOOL ret;
+ DWORD size;
+
+ store = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0,
+ CERT_SYSTEM_STORE_CURRENT_USER, "My");
+ ok(store != NULL, "CertOpenStore error %u\n", GetLastError());
+
+ cert = CertCreateCertificateContext(X509_ASN_ENCODING, selfSignedCert, sizeof(selfSignedCert));
+ ok(cert != NULL, "CertCreateCertificateContext error %#x\n", GetLastError());
+
+ info2.pwszContainerName = containerW;
+ info2.pwszProvName = providerW;
+ info2.dwProvType = 0x12345678;
+ info2.dwFlags = 0x87654321;
+ info2.cProvParam = ARRAY_SIZE(param);
+ info2.rgProvParam = param;
+ info2.dwKeySpec = 0x11223344;
+ ret = CertSetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, 0, &info2);
+ ok(ret, "CertSetCertificateContextProperty error %#x\n", GetLastError());
+
+ ret = CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
+ ok(ret, "CertGetCertificateContextProperty error %#x\n", GetLastError());
+ info = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, info, &size);
+ ok(ret, "CertGetCertificateContextProperty error %#x\n", GetLastError());
+ ok(!lstrcmpW(info->pwszContainerName, containerW), "got %s\n", wine_dbgstr_w(info->pwszContainerName));
+ ok(!lstrcmpW(info->pwszProvName, providerW), "got %s\n", wine_dbgstr_w(info->pwszProvName));
+ ok(info->dwProvType == 0x12345678, "got %#x\n", info->dwProvType);
+ ok(info->dwFlags == 0x87654321, "got %#x\n", info->dwFlags);
+ ok(info->dwKeySpec == 0x11223344, "got %#x\n", info->dwKeySpec);
+ ok(info->cProvParam == 2, "got %#x\n", info->cProvParam);
+ ok(info->rgProvParam != NULL, "got %p\n", info->rgProvParam);
+ ok(info->rgProvParam[0].dwParam == param[0].dwParam, "got %#x\n", info->rgProvParam[0].dwParam);
+ ok(info->rgProvParam[0].cbData == param[0].cbData, "got %#x\n", info->rgProvParam[0].cbData);
+ ok(!memcmp(info->rgProvParam[0].pbData, param[0].pbData, param[0].cbData), "param1 mismatch\n");
+ ok(info->rgProvParam[0].dwFlags == param[0].dwFlags, "got %#x\n", info->rgProvParam[1].dwFlags);
+ ok(info->rgProvParam[1].dwParam == param[1].dwParam, "got %#x\n", info->rgProvParam[1].dwParam);
+ ok(info->rgProvParam[1].cbData == param[1].cbData, "got %#x\n", info->rgProvParam[1].cbData);
+ ok(!memcmp(info->rgProvParam[1].pbData, param[1].pbData, param[1].cbData), "param2 mismatch\n");
+ ok(info->rgProvParam[1].dwFlags == param[1].dwFlags, "got %#x\n", info->rgProvParam[1].dwFlags);
+ HeapFree(GetProcessHeap(), 0, info);
+
+ ret = CertAddCertificateContextToStore(store, cert, CERT_STORE_ADD_NEW, NULL);
+ ok(ret, "CertAddCertificateContextToStore error %#x\n", GetLastError());
+
+ CertFreeCertificateContext(cert);
+ CertCloseStore(store, 0);
+
+ store = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, 0,
+ CERT_SYSTEM_STORE_CURRENT_USER | CERT_STORE_OPEN_EXISTING_FLAG, "My");
+ ok(store != NULL, "CertOpenStore error %u\n", GetLastError());
+
+ name.pbData = subjectName;
+ name.cbData = sizeof(subjectName);
+ cert = CertFindCertificateInStore(store, X509_ASN_ENCODING, 0, CERT_FIND_SUBJECT_NAME, &name, NULL);
+ ok(cert != NULL, "certificate should exist in My store\n");
+
+ ret = CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, NULL, &size);
+ ok(ret, "CertGetCertificateContextProperty error %#x\n", GetLastError());
+ info = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = CertGetCertificateContextProperty(cert, CERT_KEY_PROV_INFO_PROP_ID, info, &size);
+ ok(ret, "CertGetCertificateContextProperty error %#x\n", GetLastError());
+ ok(!lstrcmpW(info->pwszContainerName, containerW), "got %s\n", wine_dbgstr_w(info->pwszContainerName));
+ ok(!lstrcmpW(info->pwszProvName, providerW), "got %s\n", wine_dbgstr_w(info->pwszProvName));
+ ok(info->dwProvType == 0x12345678, "got %#x\n", info->dwProvType);
+ ok(info->dwFlags == 0x87654321, "got %#x\n", info->dwFlags);
+ ok(info->dwKeySpec == 0x11223344, "got %#x\n", info->dwKeySpec);
+ ok(info->cProvParam == 2, "got %#x\n", info->cProvParam);
+ ok(info->rgProvParam != NULL, "got %p\n", info->rgProvParam);
+ ok(info->rgProvParam[0].dwParam == param[0].dwParam, "got %#x\n", info->rgProvParam[0].dwParam);
+ ok(info->rgProvParam[0].cbData == param[0].cbData, "got %#x\n", info->rgProvParam[0].cbData);
+ ok(!memcmp(info->rgProvParam[0].pbData, param[0].pbData, param[0].cbData), "param1 mismatch\n");
+ ok(info->rgProvParam[0].dwFlags == param[0].dwFlags, "got %#x\n", info->rgProvParam[1].dwFlags);
+ ok(info->rgProvParam[1].dwParam == param[1].dwParam, "got %#x\n", info->rgProvParam[1].dwParam);
+ ok(info->rgProvParam[1].cbData == param[1].cbData, "got %#x\n", info->rgProvParam[1].cbData);
+ ok(!memcmp(info->rgProvParam[1].pbData, param[1].pbData, param[1].cbData), "param2 mismatch\n");
+ ok(info->rgProvParam[1].dwFlags == param[1].dwFlags, "got %#x\n", info->rgProvParam[1].dwFlags);
+ HeapFree(GetProcessHeap(), 0, info);
+
+ ret = CertDeleteCertificateFromStore(cert);
+ ok(ret, "CertDeleteCertificateFromStore error %#x\n", GetLastError());
+
+ CertFreeCertificateContext(cert);
+ CertCloseStore(store, 0);
+}
+
START_TEST(cert)
{
init_function_pointers();
@@ -4154,6 +4249,7 @@ START_TEST(cert)
testGetSubjectCert();
testGetIssuerCert();
testLinkCert();
+ testKeyProvInfo();
testCryptHashCert();
testCryptHashCert2();
--
2.29.2
Dec. 3, 2020
[PATCH v3 1/2] crypt32: Fix reading and writing CRYPT_KEY_PROV_INFO certificate property.
by Dmitry Timoshkov
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50024
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/crypt32/cert.c | 251 +++++++++++++--------------------
dlls/crypt32/crypt32_private.h | 8 --
dlls/crypt32/serialize.c | 187 +++++++++++++++++++++++-
3 files changed, 279 insertions(+), 167 deletions(-)
diff --git a/dlls/crypt32/cert.c b/dlls/crypt32/cert.c
index c0bec721fd..aad8fa047b 100644
--- a/dlls/crypt32/cert.c
+++ b/dlls/crypt32/cert.c
@@ -434,6 +434,84 @@ void CRYPT_ConvertKeyContext(const struct store_CERT_KEY_CONTEXT *src, CERT_KEY_
dst->dwKeySpec = src->dwKeySpec;
}
+/*
+ * Fix offsets in a continuous block of memory of CRYPT_KEY_PROV_INFO with
+ * its associated data.
+ */
+static void fix_KeyProvInfoProperty(CRYPT_KEY_PROV_INFO *info)
+{
+ BYTE *data;
+ DWORD i;
+
+ data = (BYTE *)(info + 1) + sizeof(CRYPT_KEY_PROV_PARAM) * info->cProvParam;
+
+ if (info->pwszContainerName)
+ {
+ info->pwszContainerName = (LPWSTR)data;
+ data += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR);
+ }
+
+ if (info->pwszProvName)
+ {
+ info->pwszProvName = (LPWSTR)data;
+ data += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
+ }
+
+ info->rgProvParam = info->cProvParam ? (CRYPT_KEY_PROV_PARAM *)(info + 1) : NULL;
+
+ for (i = 0; i < info->cProvParam; i++)
+ {
+ info->rgProvParam[i].pbData = info->rgProvParam[i].cbData ? data : NULL;
+ data += info->rgProvParam[i].cbData;
+ }
+}
+
+/*
+ * Copy to a continuous block of memory of CRYPT_KEY_PROV_INFO with
+ * its associated data.
+ */
+static void copy_KeyProvInfoProperty(const CRYPT_KEY_PROV_INFO *from, CRYPT_KEY_PROV_INFO *to)
+{
+ BYTE *data;
+ DWORD i;
+
+ data = (BYTE *)(to + 1) + sizeof(CRYPT_KEY_PROV_PARAM) * from->cProvParam;
+
+ if (from->pwszContainerName)
+ {
+ to->pwszContainerName = (LPWSTR)data;
+ lstrcpyW((LPWSTR)data, from->pwszContainerName);
+ data += (lstrlenW(from->pwszContainerName) + 1) * sizeof(WCHAR);
+ }
+ else
+ to->pwszContainerName = NULL;
+
+ if (from->pwszProvName)
+ {
+ to->pwszProvName = (LPWSTR)data;
+ lstrcpyW((LPWSTR)data, from->pwszProvName);
+ data += (lstrlenW(from->pwszProvName) + 1) * sizeof(WCHAR);
+ }
+ else
+ to->pwszProvName = NULL;
+
+ to->dwProvType = from->dwProvType;
+ to->dwFlags = from->dwFlags;
+ to->cProvParam = from->cProvParam;
+ to->rgProvParam = from->cProvParam ? (CRYPT_KEY_PROV_PARAM *)(to + 1) : NULL;
+ to->dwKeySpec = from->dwKeySpec;
+
+ for (i = 0; i < from->cProvParam; i++)
+ {
+ to->rgProvParam[i].dwParam = from->rgProvParam[i].dwParam;
+ to->rgProvParam[i].dwFlags = from->rgProvParam[i].dwFlags;
+ to->rgProvParam[i].cbData = from->rgProvParam[i].cbData;
+ to->rgProvParam[i].pbData = from->rgProvParam[i].cbData ? data : NULL;
+ memcpy(data, from->rgProvParam[i].pbData, from->rgProvParam[i].cbData);
+ data += from->rgProvParam[i].cbData;
+ }
+}
+
static BOOL CertContext_GetProperty(cert_t *cert, DWORD dwPropId,
void *pvData, DWORD *pcbData)
{
@@ -535,87 +613,6 @@ static BOOL CertContext_GetProperty(cert_t *cert, DWORD dwPropId,
return ret;
}
-/* 64-bit compatible layout, so that 64-bit crypt32 is able to read
- * the structure saved by 32-bit crypt32.
- */
-typedef struct
-{
- ULONG64 pwszContainerName;
- ULONG64 pwszProvName;
- DWORD dwProvType;
- DWORD dwFlags;
- DWORD cProvParam;
- ULONG64 rgProvParam;
- DWORD dwKeySpec;
-} store_CRYPT_KEY_PROV_INFO;
-
-typedef struct
-{
- DWORD dwParam;
- ULONG64 pbData;
- DWORD cbData;
- DWORD dwFlags;
-} store_CRYPT_KEY_PROV_PARAM;
-
-void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO buf)
-{
- CRYPT_KEY_PROV_INFO info;
- store_CRYPT_KEY_PROV_INFO *store = (store_CRYPT_KEY_PROV_INFO *)buf;
- BYTE *p = (BYTE *)(store + 1);
-
- if (store->pwszContainerName)
- {
- info.pwszContainerName = (LPWSTR)((BYTE *)store + store->pwszContainerName);
- p += (lstrlenW(info.pwszContainerName) + 1) * sizeof(WCHAR);
- }
- else
- info.pwszContainerName = NULL;
-
- if (store->pwszProvName)
- {
- info.pwszProvName = (LPWSTR)((BYTE *)store + store->pwszProvName);
- p += (lstrlenW(info.pwszProvName) + 1) * sizeof(WCHAR);
- }
- else
- info.pwszProvName = NULL;
-
- info.dwProvType = store->dwProvType;
- info.dwFlags = store->dwFlags;
- info.dwKeySpec = store->dwKeySpec;
- info.cProvParam = store->cProvParam;
-
- if (info.cProvParam)
- {
- DWORD i;
-
- info.rgProvParam = (CRYPT_KEY_PROV_PARAM *)p;
-
- for (i = 0; i < store->cProvParam; i++)
- {
- CRYPT_KEY_PROV_PARAM param;
- store_CRYPT_KEY_PROV_PARAM *store_param;
-
- store_param = (store_CRYPT_KEY_PROV_PARAM *)p;
- p += sizeof(*store_param);
-
- param.dwParam = store_param[i].dwParam;
- param.dwFlags = store_param[i].dwFlags;
- param.cbData = store_param[i].cbData;
- param.pbData = param.cbData ? p : NULL;
- p += store_param[i].cbData;
-
- memcpy(&info.rgProvParam[i], ¶m, sizeof(param));
- }
- }
- else
- info.rgProvParam = NULL;
-
- TRACE("%s,%s,%u,%08x,%u,%p,%u\n", debugstr_w(info.pwszContainerName), debugstr_w(info.pwszProvName),
- info.dwProvType, info.dwFlags, info.cProvParam, info.rgProvParam, info.dwKeySpec);
-
- *buf = info;
-}
-
BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
DWORD dwPropId, void *pvData, DWORD *pcbData)
{
@@ -649,10 +646,9 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
break;
}
case CERT_KEY_PROV_INFO_PROP_ID:
- ret = CertContext_GetProperty(cert, dwPropId, pvData,
- pcbData);
+ ret = CertContext_GetProperty(cert, dwPropId, pvData, pcbData);
if (ret && pvData)
- CRYPT_FixKeyProvInfoPointers(pvData);
+ fix_KeyProvInfoProperty(pvData);
break;
default:
ret = CertContext_GetProperty(cert, dwPropId, pvData,
@@ -663,69 +659,14 @@ BOOL WINAPI CertGetCertificateContextProperty(PCCERT_CONTEXT pCertContext,
return ret;
}
-/* Copies key provider info from from into to, where to is assumed to be a
- * contiguous buffer of memory large enough for from and all its associated
- * data, but whose pointers are uninitialized.
- * Upon return, to contains a contiguous copy of from, packed in the following
- * order:
- * - store_CRYPT_KEY_PROV_INFO
- * - pwszContainerName
- * - pwszProvName
- * - store_CRYPT_KEY_PROV_PARAM[0]
- * - store_CRYPT_KEY_PROV_PARAM[0].data
- * - ...
+/*
+ * Create a continuous block of memory for CRYPT_KEY_PROV_INFO with
+ * its associated data, and add it to the certificate properties.
*/
-static void CRYPT_CopyKeyProvInfo(store_CRYPT_KEY_PROV_INFO *to, const CRYPT_KEY_PROV_INFO *from)
+static BOOL CertContext_SetKeyProvInfoProperty(CONTEXT_PROPERTY_LIST *properties, const CRYPT_KEY_PROV_INFO *info)
{
- DWORD i;
- BYTE *p;
- store_CRYPT_KEY_PROV_PARAM *param;
-
- p = (BYTE *)(to + 1);
-
- if (from->pwszContainerName)
- {
- to->pwszContainerName = p - (BYTE *)to;
- lstrcpyW((LPWSTR)p, from->pwszContainerName);
- p += (lstrlenW(from->pwszContainerName) + 1) * sizeof(WCHAR);
- }
- else
- to->pwszContainerName = 0;
-
- if (from->pwszProvName)
- {
- to->pwszProvName = p - (BYTE *)to;
- lstrcpyW((LPWSTR)p, from->pwszProvName);
- p += (lstrlenW(from->pwszProvName) + 1) * sizeof(WCHAR);
- }
- else
- to->pwszProvName = 0;
-
- to->dwProvType = from->dwProvType;
- to->dwFlags = from->dwFlags;
- to->cProvParam = from->cProvParam;
- to->rgProvParam = 0;
- to->dwKeySpec = from->dwKeySpec;
-
- for (i = 0; i < to->cProvParam; i++)
- {
- param = (store_CRYPT_KEY_PROV_PARAM *)p;
- p += sizeof(*param);
-
- param->dwParam = from->rgProvParam[i].dwParam;
- param->pbData = 0;
- param->cbData = from->rgProvParam[i].cbData;
- param->dwFlags = from->rgProvParam[i].dwFlags;
- memcpy(p, from->rgProvParam[i].pbData, from->rgProvParam[i].cbData);
- p += from->rgProvParam[i].cbData;
- }
-}
-
-static BOOL CertContext_SetKeyProvInfoProperty(CONTEXT_PROPERTY_LIST *properties,
- const CRYPT_KEY_PROV_INFO *info)
-{
- BYTE *buf;
- DWORD size = sizeof(store_CRYPT_KEY_PROV_INFO), i;
+ CRYPT_KEY_PROV_INFO *prop;
+ DWORD size = sizeof(CRYPT_KEY_PROV_INFO), i;
BOOL ret;
if (info->pwszContainerName)
@@ -734,18 +675,20 @@ static BOOL CertContext_SetKeyProvInfoProperty(CONTEXT_PROPERTY_LIST *properties
size += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
for (i = 0; i < info->cProvParam; i++)
- size += sizeof(store_CRYPT_KEY_PROV_PARAM) + info->rgProvParam[i].cbData;
+ size += sizeof(CRYPT_KEY_PROV_PARAM) + info->rgProvParam[i].cbData;
- buf = CryptMemAlloc(size);
- if (buf)
+ prop = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!prop)
{
- CRYPT_CopyKeyProvInfo((store_CRYPT_KEY_PROV_INFO *)buf, info);
- ret = ContextPropertyList_SetProperty(properties,
- CERT_KEY_PROV_INFO_PROP_ID, buf, size);
- CryptMemFree(buf);
+ SetLastError(ERROR_OUTOFMEMORY);
+ return FALSE;
}
- else
- ret = FALSE;
+
+ copy_KeyProvInfoProperty(info, prop);
+
+ ret = ContextPropertyList_SetProperty(properties, CERT_KEY_PROV_INFO_PROP_ID, (const BYTE *)prop, size);
+ HeapFree(GetProcessHeap(), 0, prop);
+
return ret;
}
diff --git a/dlls/crypt32/crypt32_private.h b/dlls/crypt32/crypt32_private.h
index a4664ed85a..30cf4334de 100644
--- a/dlls/crypt32/crypt32_private.h
+++ b/dlls/crypt32/crypt32_private.h
@@ -370,14 +370,6 @@ BOOL CRYPT_ReadSerializedStoreFromFile(HANDLE file, HCERTSTORE store) DECLSPEC_H
BOOL CRYPT_ReadSerializedStoreFromBlob(const CRYPT_DATA_BLOB *blob,
HCERTSTORE store) DECLSPEC_HIDDEN;
-/* Fixes up the pointers in info, where info is assumed to be a
- * CRYPT_KEY_PROV_INFO, followed by its container name, provider name, and any
- * provider parameters, in a contiguous buffer, but where info's pointers are
- * assumed to be invalid. Upon return, info's pointers point to the
- * appropriate memory locations.
- */
-void CRYPT_FixKeyProvInfoPointers(PCRYPT_KEY_PROV_INFO info) DECLSPEC_HIDDEN;
-
struct store_CERT_KEY_CONTEXT
{
DWORD cbSize;
diff --git a/dlls/crypt32/serialize.c b/dlls/crypt32/serialize.c
index d5153deb10..8fa24370b6 100644
--- a/dlls/crypt32/serialize.c
+++ b/dlls/crypt32/serialize.c
@@ -36,6 +36,86 @@ typedef struct _WINE_CERT_PROP_HEADER
DWORD cb;
} WINE_CERT_PROP_HEADER;
+struct store_CRYPT_KEY_PROV_INFO
+{
+ DWORD pwszContainerName;
+ DWORD pwszProvName;
+ DWORD dwProvType;
+ DWORD dwFlags;
+ DWORD cProvParam;
+ DWORD rgProvParam;
+ DWORD dwKeySpec;
+};
+
+struct store_CRYPT_KEY_PROV_PARAM
+{
+ DWORD dwParam;
+ DWORD pbData;
+ DWORD cbData;
+ DWORD dwFlags;
+};
+
+static DWORD serialize_KeyProvInfoProperty(const CRYPT_KEY_PROV_INFO *info, struct store_CRYPT_KEY_PROV_INFO **ret)
+{
+ struct store_CRYPT_KEY_PROV_INFO *store;
+ struct store_CRYPT_KEY_PROV_PARAM *param;
+ DWORD size = sizeof(struct store_CRYPT_KEY_PROV_INFO), i;
+ BYTE *data;
+
+ if (info->pwszContainerName)
+ size += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR);
+ if (info->pwszProvName)
+ size += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
+
+ for (i = 0; i < info->cProvParam; i++)
+ size += sizeof(struct store_CRYPT_KEY_PROV_PARAM) + info->rgProvParam[i].cbData;
+
+ if (!ret) return size;
+
+ store = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!store) return 0;
+
+ param = (struct store_CRYPT_KEY_PROV_PARAM *)(store + 1);
+ data = (BYTE *)param + sizeof(struct store_CRYPT_KEY_PROV_PARAM) * info->cProvParam;
+
+ if (info->pwszContainerName)
+ {
+ store->pwszContainerName = data - (BYTE *)store;
+ lstrcpyW((LPWSTR)data, info->pwszContainerName);
+ data += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR);
+ }
+ else
+ store->pwszContainerName = 0;
+
+ if (info->pwszProvName)
+ {
+ store->pwszProvName = data - (BYTE *)store;
+ lstrcpyW((LPWSTR)data, info->pwszProvName);
+ data += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
+ }
+ else
+ store->pwszProvName = 0;
+
+ store->dwProvType = info->dwProvType;
+ store->dwFlags = info->dwFlags;
+ store->cProvParam = info->cProvParam;
+ store->rgProvParam = info->cProvParam ? (BYTE *)param - (BYTE *)store : 0;
+ store->dwKeySpec = info->dwKeySpec;
+
+ for (i = 0; i < info->cProvParam; i++)
+ {
+ param[i].dwParam = info->rgProvParam[i].dwParam;
+ param[i].dwFlags = info->rgProvParam[i].dwFlags;
+ param[i].cbData = info->rgProvParam[i].cbData;
+ param[i].pbData = param[i].cbData ? data - (BYTE *)store : 0;
+ memcpy(data, info->rgProvParam[i].pbData, info->rgProvParam[i].cbData);
+ data += info->rgProvParam[i].cbData;
+ }
+
+ *ret = store;
+ return size;
+}
+
static BOOL CRYPT_SerializeStoreElement(const void *context,
const BYTE *encodedContext, DWORD cbEncodedContext, DWORD contextPropID,
const WINE_CONTEXT_INTERFACE *contextInterface, DWORD dwFlags, BOOL omitHashes,
@@ -60,7 +140,16 @@ static BOOL CRYPT_SerializeStoreElement(const void *context,
ret = contextInterface->getProp(context, prop, NULL, &propSize);
if (ret)
+ {
+ if (prop == CERT_KEY_PROV_INFO_PROP_ID)
+ {
+ BYTE *info = CryptMemAlloc(propSize);
+ contextInterface->getProp(context, prop, info, &propSize);
+ propSize = serialize_KeyProvInfoProperty((const CRYPT_KEY_PROV_INFO *)info, NULL);
+ CryptMemFree(info);
+ }
bytesNeeded += sizeof(WINE_CERT_PROP_HEADER) + propSize;
+ }
}
} while (ret && prop != 0);
@@ -106,6 +195,14 @@ static BOOL CRYPT_SerializeStoreElement(const void *context,
&propSize);
if (ret)
{
+ if (prop == CERT_KEY_PROV_INFO_PROP_ID)
+ {
+ struct store_CRYPT_KEY_PROV_INFO *store;
+ propSize = serialize_KeyProvInfoProperty((const CRYPT_KEY_PROV_INFO *)buf, &store);
+ CryptMemFree(buf);
+ buf = (BYTE *)store;
+ }
+
hdr = (WINE_CERT_PROP_HEADER*)pbElement;
hdr->propID = prop;
hdr->unknown = 1;
@@ -215,6 +312,83 @@ static const WINE_CERT_PROP_HEADER *CRYPT_findPropID(const BYTE *buf,
return ret;
}
+static DWORD read_serialized_KeyProvInfoProperty(const struct store_CRYPT_KEY_PROV_INFO *store, CRYPT_KEY_PROV_INFO **ret)
+{
+ const struct store_CRYPT_KEY_PROV_PARAM *param;
+ CRYPT_KEY_PROV_INFO *info;
+ DWORD size = sizeof(CRYPT_KEY_PROV_INFO), i;
+ const BYTE *base;
+ BYTE *data;
+
+ base = (const BYTE *)store;
+ param = (const struct store_CRYPT_KEY_PROV_PARAM *)(base + store->rgProvParam);
+
+ if (store->pwszContainerName)
+ size += (lstrlenW((LPCWSTR)(base + store->pwszContainerName)) + 1) * sizeof(WCHAR);
+ if (store->pwszProvName)
+ size += (lstrlenW((LPCWSTR)(base + store->pwszProvName)) + 1) * sizeof(WCHAR);
+
+ for (i = 0; i < store->cProvParam; i++)
+ size += sizeof(CRYPT_KEY_PROV_PARAM) + param[i].cbData;
+
+ info = HeapAlloc(GetProcessHeap(), 0, size);
+ if (!info)
+ {
+ SetLastError(ERROR_OUTOFMEMORY);
+ return 0;
+ }
+
+ data = (BYTE *)(info + 1) + sizeof(CRYPT_KEY_PROV_PARAM) * store->cProvParam;
+
+ if (store->pwszContainerName)
+ {
+ info->pwszContainerName = (LPWSTR)data;
+ lstrcpyW(info->pwszContainerName, (LPCWSTR)((const BYTE *)store + store->pwszContainerName));
+ data += (lstrlenW(info->pwszContainerName) + 1) * sizeof(WCHAR);
+ }
+ else
+ info->pwszContainerName = NULL;
+
+ if (store->pwszProvName)
+ {
+ info->pwszProvName = (LPWSTR)data;
+ lstrcpyW(info->pwszProvName, (LPCWSTR)((const BYTE *)store + store->pwszProvName));
+ data += (lstrlenW(info->pwszProvName) + 1) * sizeof(WCHAR);
+ }
+ else
+ info->pwszProvName = NULL;
+
+ info->dwProvType = store->dwProvType;
+ info->dwFlags = store->dwFlags;
+ info->dwKeySpec = store->dwKeySpec;
+ info->cProvParam = store->cProvParam;
+
+ if (info->cProvParam)
+ {
+ DWORD i;
+
+ info->rgProvParam = (CRYPT_KEY_PROV_PARAM *)(info + 1);
+
+ for (i = 0; i < info->cProvParam; i++)
+ {
+ info->rgProvParam[i].dwParam = param[i].dwParam;
+ info->rgProvParam[i].dwFlags = param[i].dwFlags;
+ info->rgProvParam[i].cbData = param[i].cbData;
+ info->rgProvParam[i].pbData = param[i].cbData ? data : NULL;
+ memcpy(info->rgProvParam[i].pbData, base + param[i].pbData, param[i].cbData);
+ data += param[i].cbData;
+ }
+ }
+ else
+ info->rgProvParam = NULL;
+
+ TRACE("%s,%s,%u,%08x,%u,%p,%u\n", debugstr_w(info->pwszContainerName), debugstr_w(info->pwszProvName),
+ info->dwProvType, info->dwFlags, info->cProvParam, info->rgProvParam, info->dwKeySpec);
+
+ *ret = info;
+ return size;
+}
+
static BOOL CRYPT_ReadContextProp(
const WINE_CONTEXT_INTERFACE *contextInterface, const void *context,
const WINE_CERT_PROP_HEADER *hdr, const BYTE *pbElement, DWORD cbElement)
@@ -269,12 +443,15 @@ static BOOL CRYPT_ReadContextProp(
break;
case CERT_KEY_PROV_INFO_PROP_ID:
{
- PCRYPT_KEY_PROV_INFO info =
- (PCRYPT_KEY_PROV_INFO)pbElement;
+ CRYPT_KEY_PROV_INFO *info;
- CRYPT_FixKeyProvInfoPointers(info);
- ret = contextInterface->setProp(context,
- hdr->propID, 0, pbElement);
+ if (read_serialized_KeyProvInfoProperty((const struct store_CRYPT_KEY_PROV_INFO *)pbElement, &info))
+ {
+ ret = contextInterface->setProp(context, hdr->propID, 0, info);
+ CryptMemFree(info);
+ }
+ else
+ ret = FALSE;
break;
}
case CERT_KEY_CONTEXT_PROP_ID:
--
2.29.2
Dec. 3, 2020
Re: [PATCH v4 03/12] winegstreamer: Add MFT registration helper for gstreamer-backed MFTs.
by Zebediah Figura (she/her)
I'd go with something more like "register the audio converter MFT" for a
patch subject, since that's the functional change this patch achieves.
On 12/2/20 4:36 PM, Derek Lesho wrote:
> Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
> ---
> v4: Fix tracing of 'param' parameter for ::ProcessMessage.
> ---
> dlls/winegstreamer/gst_private.h | 1 +
> dlls/winegstreamer/main.c | 3 +-
> dlls/winegstreamer/mfplat.c | 69 ++++++++++++++++++++++++++++++++
> 3 files changed, 72 insertions(+), 1 deletion(-)
>
> diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
> index 7889c996204..9518f721504 100644
> --- a/dlls/winegstreamer/gst_private.h
> +++ b/dlls/winegstreamer/gst_private.h
> @@ -76,6 +76,7 @@ BOOL init_gstreamer(void) DECLSPEC_HIDDEN;
> void start_dispatch_thread(void) DECLSPEC_HIDDEN;
>
> extern HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj) DECLSPEC_HIDDEN;
> +extern HRESULT mfplat_DllRegisterServer(void) DECLSPEC_HIDDEN;
>
> HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
> IMFMediaType *mf_media_type_from_caps(const GstCaps *caps) DECLSPEC_HIDDEN;
> diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c
> index 4ca371d58bd..385c5550235 100644
> --- a/dlls/winegstreamer/main.c
> +++ b/dlls/winegstreamer/main.c
> @@ -368,7 +368,8 @@ HRESULT WINAPI DllRegisterServer(void)
> IFilterMapper2_RegisterFilter(mapper, &CLSID_WAVEParser, wave_parserW, NULL, NULL, NULL, ®_wave_parser);
>
> IFilterMapper2_Release(mapper);
> - return S_OK;
> +
> + return mfplat_DllRegisterServer();
> }
>
> HRESULT WINAPI DllUnregisterServer(void)
> diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
> index 095a9b81091..f300988fc5c 100644
> --- a/dlls/winegstreamer/mfplat.c
> +++ b/dlls/winegstreamer/mfplat.c
> @@ -445,6 +445,75 @@ HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
> return CLASS_E_CLASSNOTAVAILABLE;
> }
>
> +static WCHAR audio_converterW[] = {'A','u','d','i','o',' ','C','o','n','v','e','r','t','e','r',0};
> +static const GUID *audio_converter_supported_types[] =
> +{
> + &MFAudioFormat_PCM,
> + &MFAudioFormat_Float,
> +};
> +
> +static const struct mft
> +{
> + const GUID *clsid;
> + const GUID *category;
> + LPWSTR name;
> + const UINT32 flags;
> + const GUID *major_type;
> + const UINT32 input_types_count;
> + const GUID **input_types;
> + const UINT32 output_types_count;
> + const GUID **output_types;
> + IMFAttributes *attributes;
> +}
> +mfts[] =
> +{
> + {
> + &CLSID_WINEAudioConverter,
> + &MFT_CATEGORY_AUDIO_EFFECT,
> + audio_converterW,
> + MFT_ENUM_FLAG_SYNCMFT,
> + &MFMediaType_Audio,
> + ARRAY_SIZE(audio_converter_supported_types),
> + audio_converter_supported_types,
> + ARRAY_SIZE(audio_converter_supported_types),
> + audio_converter_supported_types,
> + NULL
> + },
> +};
> +
> +HRESULT mfplat_DllRegisterServer(void)
> +{
> + unsigned int i, j;
> + HRESULT hr;
> + MFT_REGISTER_TYPE_INFO input_types[2], output_types[2];
> +
> + for (i = 0; i < ARRAY_SIZE(mfts); i++)
> + {
> + const struct mft *cur = &mfts[i];
> +
> + for (j = 0; j < cur->input_types_count; j++)
> + {
> + input_types[j].guidMajorType = *(cur->major_type);
> + input_types[j].guidSubtype = *(cur->input_types[j]);
> + }
> + for (j = 0; j < cur->output_types_count; j++)
> + {
> + output_types[j].guidMajorType = *(cur->major_type);
> + output_types[j].guidSubtype = *(cur->output_types[j]);
> + }
> +
> + hr = MFTRegister(*(cur->clsid), *(cur->category), cur->name, cur->flags, cur->input_types_count,
> + input_types, cur->output_types_count, output_types, cur->attributes);
> +
> + if (FAILED(hr))
> + {
> + FIXME("Failed to register MFT, hr %#x\n", hr);
> + return hr;
> + }
> + }
> + return S_OK;
> +}
> +
> static const struct
> {
> const GUID *subtype;
>
Dec. 3, 2020
Re: [PATCH v4 02/12] winegstreamer: Introduce audio conversion transform.
by Zebediah Figura (she/her)
On 12/2/20 4:36 PM, Derek Lesho wrote:
> Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
> ---
> v4: Reorder patch not to touch MFT registration functionality.
> ---
> dlls/winegstreamer/Makefile.in | 1 +
> dlls/winegstreamer/audioconvert.c | 285 +++++++++++++++++++
> dlls/winegstreamer/gst_private.h | 2 +
> dlls/winegstreamer/mfplat.c | 3 +
> dlls/winegstreamer/winegstreamer_classes.idl | 6 +
> 5 files changed, 297 insertions(+)
> create mode 100644 dlls/winegstreamer/audioconvert.c
>
> diff --git a/dlls/winegstreamer/Makefile.in b/dlls/winegstreamer/Makefile.in
> index e578d194f7f..0b3229160b9 100644
> --- a/dlls/winegstreamer/Makefile.in
> +++ b/dlls/winegstreamer/Makefile.in
> @@ -6,6 +6,7 @@ EXTRALIBS = $(GSTREAMER_LIBS) $(PTHREAD_LIBS)
> PARENTSRC = ../strmbase
>
> C_SRCS = \
> + audioconvert.c \
> filter.c \
> gst_cbs.c \
> gstdemux.c \
> diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
> new file mode 100644
> index 00000000000..68f045a4558
> --- /dev/null
> +++ b/dlls/winegstreamer/audioconvert.c
> @@ -0,0 +1,285 @@
> +#include "config.h"
Sorry for missing this before, but you're missing a copyright header here.
I think the patch looks good to me otherwise.
> +
> +#include "gst_private.h"
> +
> +#include "mfapi.h"
> +#include "mferror.h"
> +#include "mfidl.h"
> +#include "ks.h"
> +#include "ksmedia.h"
> +
> +#include "wine/debug.h"
> +#include "wine/heap.h"
> +
> +WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
> +
> +struct audio_converter
> +{
> + IMFTransform IMFTransform_iface;
> + LONG refcount;
> +};
> +
> +static struct audio_converter *impl_audio_converter_from_IMFTransform(IMFTransform *iface)
> +{
> + return CONTAINING_RECORD(iface, struct audio_converter, IMFTransform_iface);
> +}
> +
> +static HRESULT WINAPI audio_converter_QueryInterface(IMFTransform *iface, REFIID riid, void **obj)
> +{
> + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
> +
> + if (IsEqualIID(riid, &IID_IMFTransform) ||
> + IsEqualIID(riid, &IID_IUnknown))
> + {
> + *obj = iface;
> + IMFTransform_AddRef(iface);
> + return S_OK;
> + }
> +
> + WARN("Unsupported %s.\n", debugstr_guid(riid));
> + *obj = NULL;
> + return E_NOINTERFACE;
> +}
> +
> +static ULONG WINAPI audio_converter_AddRef(IMFTransform *iface)
> +{
> + struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
> + ULONG refcount = InterlockedIncrement(&transform->refcount);
> +
> + TRACE("%p, refcount %u.\n", iface, refcount);
> +
> + return refcount;
> +}
> +
> +static ULONG WINAPI audio_converter_Release(IMFTransform *iface)
> +{
> + struct audio_converter *transform = impl_audio_converter_from_IMFTransform(iface);
> + ULONG refcount = InterlockedDecrement(&transform->refcount);
> +
> + TRACE("%p, refcount %u.\n", iface, refcount);
> +
> + if (!refcount)
> + {
> + heap_free(transform);
> + }
> +
> + return refcount;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, DWORD *input_maximum,
> + DWORD *output_minimum, DWORD *output_maximum)
> +{
> + TRACE("%p, %p, %p, %p, %p.\n", iface, input_minimum, input_maximum, output_minimum, output_maximum);
> +
> + *input_minimum = *input_maximum = *output_minimum = *output_maximum = 1;
> +
> + return S_OK;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs)
> +{
> + TRACE("%p, %p, %p.\n", iface, inputs, outputs);
> +
> + *inputs = *outputs = 1;
> +
> + return S_OK;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs,
> + DWORD output_size, DWORD *outputs)
> +{
> + TRACE("%p %u %p %u %p.\n", iface, input_size, inputs, output_size, outputs);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info)
> +{
> + FIXME("%p %u %p.\n", iface, id, info);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info)
> +{
> + FIXME("%p %u %p.\n", iface, id, info);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
> +{
> + FIXME("%p, %p.\n", iface, attributes);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetInputStreamAttributes(IMFTransform *iface, DWORD id,
> + IMFAttributes **attributes)
> +{
> + FIXME("%p, %u, %p.\n", iface, id, attributes);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetOutputStreamAttributes(IMFTransform *iface, DWORD id,
> + IMFAttributes **attributes)
> +{
> + FIXME("%p, %u, %p.\n", iface, id, attributes);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_DeleteInputStream(IMFTransform *iface, DWORD id)
> +{
> + TRACE("%p, %u.\n", iface, id);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids)
> +{
> + TRACE("%p, %u, %p.\n", iface, streams, ids);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
> + IMFMediaType **type)
> +{
> + FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index,
> + IMFMediaType **type)
> +{
> + FIXME("%p, %u, %u, %p.\n", iface, id, index, type);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
> +{
> + FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
> +{
> + FIXME("%p, %u, %p, %#x.\n", iface, id, type, flags);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
> +{
> + FIXME("%p, %u, %p.\n", iface, id, type);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
> +{
> + FIXME("%p, %u, %p.\n", iface, id, type);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags)
> +{
> + FIXME("%p, %u, %p.\n", iface, id, flags);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_GetOutputStatus(IMFTransform *iface, DWORD *flags)
> +{
> + FIXME("%p, %p.\n", iface, flags);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper)
> +{
> + FIXME("%p, %s, %s.\n", iface, wine_dbgstr_longlong(lower), wine_dbgstr_longlong(upper));
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event)
> +{
> + TRACE("%p, %u, %p.\n", iface, id, event);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param)
> +{
> + FIXME("%p, %u %lu.\n", iface, message, param);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags)
> +{
> + FIXME("%p, %u, %p, %#x.\n", iface, id, sample, flags);
> +
> + return E_NOTIMPL;
> +}
> +
> +static HRESULT WINAPI audio_converter_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count,
> + MFT_OUTPUT_DATA_BUFFER *samples, DWORD *status)
> +{
> + FIXME("%p, %#x, %u, %p, %p.\n", iface, flags, count, samples, status);
> +
> + return E_NOTIMPL;
> +}
> +
> +static const IMFTransformVtbl audio_converter_vtbl =
> +{
> + audio_converter_QueryInterface,
> + audio_converter_AddRef,
> + audio_converter_Release,
> + audio_converter_GetStreamLimits,
> + audio_converter_GetStreamCount,
> + audio_converter_GetStreamIDs,
> + audio_converter_GetInputStreamInfo,
> + audio_converter_GetOutputStreamInfo,
> + audio_converter_GetAttributes,
> + audio_converter_GetInputStreamAttributes,
> + audio_converter_GetOutputStreamAttributes,
> + audio_converter_DeleteInputStream,
> + audio_converter_AddInputStreams,
> + audio_converter_GetInputAvailableType,
> + audio_converter_GetOutputAvailableType,
> + audio_converter_SetInputType,
> + audio_converter_SetOutputType,
> + audio_converter_GetInputCurrentType,
> + audio_converter_GetOutputCurrentType,
> + audio_converter_GetInputStatus,
> + audio_converter_GetOutputStatus,
> + audio_converter_SetOutputBounds,
> + audio_converter_ProcessEvent,
> + audio_converter_ProcessMessage,
> + audio_converter_ProcessInput,
> + audio_converter_ProcessOutput,
> +};
> +
> +HRESULT audio_converter_create(REFIID riid, void **ret)
> +{
> + struct audio_converter *object;
> +
> + TRACE("%s %p\n", debugstr_guid(riid), ret);
> +
> + if (!(object = heap_alloc_zero(sizeof(*object))))
> + return E_OUTOFMEMORY;
> +
> + object->IMFTransform_iface.lpVtbl = &audio_converter_vtbl;
> + object->refcount = 1;
> +
> + *ret = &object->IMFTransform_iface;
> + return S_OK;
> +}
> diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h
> index 28e424439d8..7889c996204 100644
> --- a/dlls/winegstreamer/gst_private.h
> +++ b/dlls/winegstreamer/gst_private.h
> @@ -84,4 +84,6 @@ IMFSample *mf_sample_from_gst_buffer(GstBuffer *in) DECLSPEC_HIDDEN;
>
> HRESULT winegstreamer_stream_handler_create(REFIID riid, void **obj) DECLSPEC_HIDDEN;
>
> +HRESULT audio_converter_create(REFIID riid, void **ret) DECLSPEC_HIDDEN;
> +
> #endif /* __GST_PRIVATE_INCLUDED__ */
> diff --git a/dlls/winegstreamer/mfplat.c b/dlls/winegstreamer/mfplat.c
> index 3a160d68093..095a9b81091 100644
> --- a/dlls/winegstreamer/mfplat.c
> +++ b/dlls/winegstreamer/mfplat.c
> @@ -405,6 +405,8 @@ failed:
>
> static const GUID CLSID_GStreamerByteStreamHandler = {0x317df618, 0x5e5a, 0x468a, {0x9f, 0x15, 0xd8, 0x27, 0xa9, 0xa0, 0x81, 0x62}};
>
> +static const GUID CLSID_WINEAudioConverter = {0x6a170414,0xaad9,0x4693,{0xb8,0x06,0x3a,0x0c,0x47,0xc5,0x70,0xd6}};
> +
> static const struct class_object
> {
> const GUID *clsid;
> @@ -414,6 +416,7 @@ class_objects[] =
> {
> { &CLSID_VideoProcessorMFT, &video_processor_create },
> { &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
> + { &CLSID_WINEAudioConverter, &audio_converter_create },
> };
>
> HRESULT mfplat_get_class_object(REFCLSID rclsid, REFIID riid, void **obj)
> diff --git a/dlls/winegstreamer/winegstreamer_classes.idl b/dlls/winegstreamer/winegstreamer_classes.idl
> index 1dc4ba9a10b..cf1fc69f38a 100644
> --- a/dlls/winegstreamer/winegstreamer_classes.idl
> +++ b/dlls/winegstreamer/winegstreamer_classes.idl
> @@ -61,3 +61,9 @@ coclass VideoProcessorMFT {}
> uuid(317df618-5e5a-468a-9f15-d827a9a08162)
> ]
> coclass GStreamerByteStreamHandler {}
> +
> +[
> + threading(both),
> + uuid(6a170414-aad9-4693-b806-3a0c47c570d6)
> +]
> +coclass WINEAudioConverter { }
>
Dec. 3, 2020
Re: [PATCH v4 01/12] winegstreamer: Utilize gst_audio_info_to_caps for media type translation.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
Dec. 3, 2020
Re: [PATCH] crypt32: Fix reading and writing CRYPT_KEY_PROV_INFO certificate property.
by Dmitry Timoshkov
Alexandre Julliard <julliard(a)winehq.org> wrote:
> > Is there anything that could be improved to make this patch accepted?
>
> It's fairly large, it would help if you could do this in smaller chunks
> somehow.
The patch implements both serializer and deserializer of the CRYPT_KEY_PROV_INFO
property, and that can't be split without breaking too much. I can send the tests
separately though. Is that acceptable?
--
Dmitry.
Dec. 3, 2020
[PATCH 5/5] wined3d: Explicitly synchronise in wined3d_context_gl_map_bo_address().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 7 -------
dlls/wined3d/context_gl.c | 9 +++++++++
dlls/wined3d/resource.c | 4 ++--
3 files changed, 11 insertions(+), 9 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 7a4e48fd9c6..5dbc66449f4 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -741,7 +741,6 @@ void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer)
static void wined3d_buffer_gl_sync_apple(struct wined3d_buffer_gl *buffer_gl,
uint32_t flags, struct wined3d_context_gl *context_gl)
{
- struct wined3d_device_gl *device_gl = wined3d_device_gl(buffer_gl->b.resource.device);
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
struct wined3d_bo_gl *bo = &buffer_gl->bo;
@@ -759,12 +758,6 @@ static void wined3d_buffer_gl_sync_apple(struct wined3d_buffer_gl *buffer_gl,
bo->command_fence_id = 0;
return;
}
-
- TRACE("Synchronizing buffer %p.\n", buffer_gl);
-
- if (bo->command_fence_id == device_gl->current_fence_id)
- wined3d_context_gl_submit_command_fence(context_gl);
- wined3d_context_gl_wait_command_fence(context_gl, bo->command_fence_id);
}
static void buffer_mark_used(struct wined3d_buffer *buffer)
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 83c61834f5a..406b325cda8 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2653,6 +2653,7 @@ void wined3d_context_gl_submit_command_fence(struct wined3d_context_gl *context_
void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl,
const struct wined3d_bo_address *data, size_t size, uint32_t flags)
{
+ struct wined3d_device_gl *device_gl = wined3d_device_gl(context_gl->c.device);
const struct wined3d_gl_info *gl_info;
struct wined3d_bo_gl *bo;
BYTE *memory;
@@ -2660,6 +2661,14 @@ void *wined3d_context_gl_map_bo_address(struct wined3d_context_gl *context_gl,
if (!(bo = (struct wined3d_bo_gl *)data->buffer_object))
return data->addr;
+ if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+ goto map;
+
+ if (bo->command_fence_id == device_gl->current_fence_id)
+ wined3d_context_gl_submit_command_fence(context_gl);
+ wined3d_context_gl_wait_command_fence(context_gl, bo->command_fence_id);
+
+map:
gl_info = context_gl->gl_info;
wined3d_context_gl_bind_bo(context_gl, bo->binding, bo->id);
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index 97b8b68374d..f6e233d8057 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -451,11 +451,11 @@ GLbitfield wined3d_resource_gl_map_flags(DWORD d3d_flags)
ret |= GL_MAP_WRITE_BIT | GL_MAP_FLUSH_EXPLICIT_BIT;
if (d3d_flags & WINED3D_MAP_READ)
ret |= GL_MAP_READ_BIT;
+ else if (!(d3d_flags & WINED3D_MAP_DISCARD))
+ ret |= GL_MAP_UNSYNCHRONIZED_BIT;
if (d3d_flags & WINED3D_MAP_DISCARD)
ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
- if (d3d_flags & WINED3D_MAP_NOOVERWRITE)
- ret |= GL_MAP_UNSYNCHRONIZED_BIT;
return ret;
}
--
2.20.1
Dec. 3, 2020
[PATCH 4/5] wined3d: Reference the bo in wined3d_buffer_gl_upload_ranges().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 82051453ef1..7a4e48fd9c6 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -1412,6 +1412,7 @@ static void wined3d_buffer_gl_upload_ranges(struct wined3d_buffer *buffer, struc
GL_EXTCALL(glBufferSubData(buffer_gl->bo.binding,
range->offset, range->size, (BYTE *)data + range->offset - data_offset));
}
+ wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
checkGLcall("buffer upload");
}
--
2.20.1
Dec. 3, 2020
[PATCH 3/5] wined3d: Reference the bo in wined3d_texture_gl_download_data().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/texture.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 43d75eb8ce9..6c9627d21f8 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -2841,6 +2841,7 @@ static void wined3d_texture_gl_download_data(struct wined3d_context *context,
if (dst_bo)
{
GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
+ wined3d_context_gl_reference_bo(context_gl, dst_bo);
checkGLcall("glBindBuffer");
}
}
--
2.20.1
Dec. 3, 2020
[PATCH 2/5] wined3d: Reference the bo in wined3d_texture_gl_download_data_slow_path().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/texture.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 1cf4f7eb5ca..43d75eb8ce9 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -2501,7 +2501,7 @@ static void wined3d_texture_gl_upload_data(struct wined3d_context *context,
static void wined3d_texture_gl_download_data_slow_path(struct wined3d_texture_gl *texture_gl,
unsigned int sub_resource_idx, struct wined3d_context_gl *context_gl, const struct wined3d_bo_address *data)
{
- const struct wined3d_bo_gl *bo = (const struct wined3d_bo_gl *)data->buffer_object;
+ struct wined3d_bo_gl *bo = (struct wined3d_bo_gl *)data->buffer_object;
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
struct wined3d_texture_sub_resource *sub_resource;
unsigned int dst_row_pitch, dst_slice_pitch;
@@ -2721,6 +2721,7 @@ static void wined3d_texture_gl_download_data_slow_path(struct wined3d_texture_gl
if (bo)
{
GL_EXTCALL(glBindBuffer(GL_PIXEL_PACK_BUFFER, 0));
+ wined3d_context_gl_reference_bo(context_gl, bo);
checkGLcall("glBindBuffer");
}
--
2.20.1
Dec. 3, 2020
[PATCH 1/5] wined3d: Reference the bo in wined3d_texture_gl_upload_data().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/texture.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 1e410930a8b..1cf4f7eb5ca 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -2481,6 +2481,7 @@ static void wined3d_texture_gl_upload_data(struct wined3d_context *context,
if (bo.buffer_object)
{
GL_EXTCALL(glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0));
+ wined3d_context_gl_reference_bo(context_gl, (struct wined3d_bo_gl *)bo.buffer_object);
checkGLcall("glBindBuffer");
}
}
--
2.20.1
Dec. 3, 2020
Re: [PATCH] wined3d: Add NVIDIA GeForce GTX 1060 Mobile.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH] crypt32: Fix reading and writing CRYPT_KEY_PROV_INFO certificate property.
by Alexandre Julliard
Dmitry Timoshkov <dmitry(a)baikal.ru> writes:
> Is there anything that could be improved to make this patch accepted?
It's fairly large, it would help if you could do this in smaller chunks
somehow.
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 3, 2020
[PATCH v3 7/7] gdi32/tests: Test changing system default font smoothing.
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/gdi32/tests/dib.c | 45 ++++++++++++++++++++++++++++++++++--------
1 file changed, 37 insertions(+), 8 deletions(-)
diff --git a/dlls/gdi32/tests/dib.c b/dlls/gdi32/tests/dib.c
index d16cb0df5c0..8cd054f7183 100644
--- a/dlls/gdi32/tests/dib.c
+++ b/dlls/gdi32/tests/dib.c
@@ -3007,7 +3007,7 @@ static inline COLORREF aa_colorref( COLORREF dst, COLORREF text, BYTE glyph )
static const BYTE masks[8] = {0x80, 0x40, 0x20, 0x10, 0x08, 0x04, 0x02, 0x01};
-static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa )
+static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BYTE quality, BOOL expected_aa )
{
DWORD dib_size = get_dib_size(bmi), ret;
LOGFONTA lf;
@@ -3029,7 +3029,7 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa )
memset( &lf, 0, sizeof(lf) );
strcpy( lf.lfFaceName, "Tahoma" );
lf.lfHeight = 24;
- lf.lfQuality = aa ? ANTIALIASED_QUALITY : NONANTIALIASED_QUALITY;
+ lf.lfQuality = quality;
font = CreateFontIndirectA( &lf );
font = SelectObject( hdc, font );
@@ -3054,12 +3054,12 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa )
for(i = 0; i < dib_size; i++)
bits[i] = vals[i % 4];
- if (bmi->bmiHeader.biBitCount <= 8) aa = FALSE;
+ if (bmi->bmiHeader.biBitCount <= 8) expected_aa = FALSE;
text_color = GetTextColor( hdc );
for (i = 0; i < strlen(str); i++)
{
- DWORD ggo_flags = aa ? GGO_GRAY4_BITMAP : GGO_BITMAP;
+ DWORD ggo_flags = expected_aa ? GGO_GRAY4_BITMAP : GGO_BITMAP;
ret = GetGlyphOutlineA( hdc, str[i], ggo_flags, &gm, 0, NULL, &identity );
@@ -3075,7 +3075,7 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa )
if (!ret) continue;
- if (aa)
+ if (expected_aa)
{
stride = (gm.gmBlackBoxX + 3) & ~3;
@@ -3114,7 +3114,7 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa )
}
diy_hash = hash_dib( hdc, bmi, bits );
- ok( !strcmp( eto_hash, diy_hash ), "hash mismatch - aa %d\n", aa );
+ ok( !strcmp( eto_hash, diy_hash ), "hash mismatch - quality %#x, expected_aa %d\n", quality, expected_aa );
HeapFree( GetProcessHeap(), 0, diy_hash );
HeapFree( GetProcessHeap(), 0, eto_hash );
@@ -3125,14 +3125,43 @@ static void draw_text_2( HDC hdc, const BITMAPINFO *bmi, BYTE *bits, BOOL aa )
static void draw_text( HDC hdc, const BITMAPINFO *bmi, BYTE *bits )
{
- draw_text_2( hdc, bmi, bits, FALSE );
+ UINT smoothing, type;
+ BOOL ret;
+
+ draw_text_2( hdc, bmi, bits, NONANTIALIASED_QUALITY, FALSE );
+
+ ret = SystemParametersInfoA(SPI_GETFONTSMOOTHING, 0, &smoothing, 0);
+ ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError());
+
+ ret = SystemParametersInfoA(SPI_SETFONTSMOOTHING, 0, NULL, 0);
+ ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError());
+ draw_text_2( hdc, bmi, bits, DEFAULT_QUALITY, FALSE );
/* Rounding errors make these cases hard to test */
if ((bmi->bmiHeader.biCompression == BI_BITFIELDS && ((DWORD*)bmi->bmiColors)[0] == 0x3f000) ||
(bmi->bmiHeader.biBitCount == 16))
+ {
+ ret = SystemParametersInfoA(SPI_SETFONTSMOOTHING, smoothing, NULL, 0);
+ ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError());
return;
+ }
+
+ ret = SystemParametersInfoA(SPI_SETFONTSMOOTHING, 1, NULL, 0);
+ ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError());
+ ret = SystemParametersInfoA(SPI_GETFONTSMOOTHINGTYPE, 0, &type, 0);
+ ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError());
+ ret = SystemParametersInfoA(SPI_SETFONTSMOOTHINGTYPE, 0, (void *)FE_FONTSMOOTHINGSTANDARD, 0);
+ ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError());
+
+ draw_text_2( hdc, bmi, bits, DEFAULT_QUALITY, TRUE );
+
+ ret = SystemParametersInfoA(SPI_SETFONTSMOOTHINGTYPE, 0, (void *)(ULONG_PTR)type, 0);
+ ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError());
+
+ ret = SystemParametersInfoA(SPI_SETFONTSMOOTHING, smoothing, NULL, 0);
+ ok(ret, "SystemParametersInfoA failed, GetLastError() %u.\n", GetLastError());
- draw_text_2( hdc, bmi, bits, TRUE );
+ draw_text_2( hdc, bmi, bits, ANTIALIASED_QUALITY, TRUE );
}
static void test_simple_graphics(void)
--
2.28.0
Dec. 3, 2020
[PATCH v3 6/7] winex11.drv: Do not override AA flags in xrenderdrv_SelectFont().
by Paul Gofman
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=45857
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
v3:
- replaced [PATCH v2 4/6] winex11.drv: Do not set AA flags for font default AA in xrender backend,
so device aa_flags get correct value.
dlls/winex11.drv/xrender.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index dc3bed2bfa0..be6db468e3c 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -892,10 +892,10 @@ static HFONT CDECL xrenderdrv_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_fla
HFONT ret;
GetObjectW( hfont, sizeof(lfsz.lf), &lfsz.lf );
- if (!*aa_flags) *aa_flags = get_xft_aa_flags( &lfsz.lf );
ret = next->funcs->pSelectFont( next, hfont, aa_flags );
if (!ret) return 0;
+ if (!*aa_flags) *aa_flags = get_xft_aa_flags( &lfsz.lf );
switch (*aa_flags)
{
--
2.28.0
Dec. 3, 2020
[PATCH v3 5/7] gdi32: Update default font AA parameters on system parameters update.
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
v3:
- add default value for subpixel_orientation;
- don't take font_cs inside update_font_options().
dlls/gdi32/font.c | 28 ++++++++++++++++++++++++++++
1 file changed, 28 insertions(+)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 3ff6c6ef3f6..91703a85cb6 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -42,6 +42,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(font);
static HKEY wine_fonts_key;
static HKEY wine_fonts_cache_key;
+static HKEY volatile_parameters_key;
+static HANDLE volatile_parameters_changed_event;
struct font_physdev
{
@@ -98,6 +100,8 @@ static struct font_gamma_ramp font_gamma_ramp;
static void add_face_to_cache( struct gdi_font_face *face );
static void remove_face_from_cache( struct gdi_font_face *face );
+static void update_font_options(void);
+
static inline WCHAR facename_tolower( WCHAR c )
{
if (c >= 'A' && c <= 'Z') return c - 'A' + 'a';
@@ -3764,6 +3768,7 @@ static HFONT CDECL font_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
default:
if (!(*aa_flags = font->aa_flags))
{
+ update_font_options();
*aa_flags = lf.lfQuality == CLEARTYPE_QUALITY || lf.lfQuality == CLEARTYPE_NATURAL_QUALITY
? subpixel_orientation : font_smoothing;
}
@@ -3944,6 +3949,9 @@ static void init_font_options(void)
antialias_fakes = (wcschr(L"yYtT1", buffer[0]) != NULL);
}
+ font_smoothing = GGO_BITMAP;
+ subpixel_orientation = WINE_GGO_HRGB_BITMAP;
+
if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Control Panel\\Desktop", &key ))
{
RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Temporary System Parameters\\Control Panel\\Desktop",
@@ -3992,6 +4000,26 @@ static void init_font_options(void)
TRACE("gamma %d\n", font_gamma_ramp.gamma);
}
+/* font_cs must be held by the caller */
+static void update_font_options(void)
+{
+ if (!volatile_parameters_key)
+ {
+ if (RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Temporary System Parameters\\Control Panel\\Desktop",
+ &volatile_parameters_key ))
+ return;
+ volatile_parameters_changed_event = CreateEventA( NULL, FALSE, TRUE, NULL );
+ }
+ if (WaitForSingleObject( volatile_parameters_changed_event, 0 ) == WAIT_OBJECT_0)
+ {
+ if (RegNotifyChangeKeyValue( volatile_parameters_key, FALSE,
+ REG_NOTIFY_CHANGE_NAME | REG_NOTIFY_CHANGE_LAST_SET | REG_NOTIFY_THREAD_AGNOSTIC,
+ volatile_parameters_changed_event, TRUE))
+ ERR("Error registering registry change notification.\n");
+
+ init_font_options();
+ }
+}
static void FONT_LogFontAToW( const LOGFONTA *fontA, LPLOGFONTW fontW )
{
--
2.28.0
Dec. 3, 2020
[PATCH v3 4/7] gdi32: Consolidate aa_flags estimation in font_SelectFont().
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
v3:
- added patch.
dlls/gdi32/font.c | 32 +++++++++++++++-----------------
1 file changed, 15 insertions(+), 17 deletions(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index c952495f7da..3ff6c6ef3f6 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -3713,16 +3713,6 @@ static HFONT CDECL font_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
BOOL can_use_bitmap = !!(GetDeviceCaps( dc->hSelf, TEXTCAPS ) & TC_RA_ABLE);
GetObjectW( hfont, sizeof(lf), &lf );
- switch (lf.lfQuality)
- {
- case NONANTIALIASED_QUALITY:
- if (!*aa_flags) *aa_flags = GGO_BITMAP;
- break;
- case ANTIALIASED_QUALITY:
- if (!*aa_flags) *aa_flags = GGO_GRAY4_BITMAP;
- break;
- }
-
lf.lfWidth = abs(lf.lfWidth);
TRACE( "%s, h=%d, it=%d, weight=%d, PandF=%02x, charset=%d orient %d escapement %d\n",
@@ -3763,15 +3753,23 @@ static HFONT CDECL font_SelectFont( PHYSDEV dev, HFONT hfont, UINT *aa_flags )
if (font && !*aa_flags)
{
- *aa_flags = font->aa_flags;
- if (!*aa_flags)
+ switch (lf.lfQuality)
{
- if (lf.lfQuality == CLEARTYPE_QUALITY || lf.lfQuality == CLEARTYPE_NATURAL_QUALITY)
- *aa_flags = subpixel_orientation;
- else
- *aa_flags = font_smoothing;
+ case NONANTIALIASED_QUALITY:
+ *aa_flags = GGO_BITMAP;
+ break;
+ case ANTIALIASED_QUALITY:
+ *aa_flags = GGO_GRAY4_BITMAP;
+ break;
+ default:
+ if (!(*aa_flags = font->aa_flags))
+ {
+ *aa_flags = lf.lfQuality == CLEARTYPE_QUALITY || lf.lfQuality == CLEARTYPE_NATURAL_QUALITY
+ ? subpixel_orientation : font_smoothing;
+ }
+ *aa_flags = font_funcs->get_aa_flags( font, *aa_flags, antialias_fakes );
+ break;
}
- *aa_flags = font_funcs->get_aa_flags( font, *aa_flags, antialias_fakes );
}
TRACE( "%p %s %d aa %x\n", hfont, debugstr_w(lf.lfFaceName), lf.lfHeight, *aa_flags );
LeaveCriticalSection( &font_cs );
--
2.28.0
Dec. 3, 2020
[PATCH v3 3/7] gdi32: Handle Wine specific vertical orientations in init_font_options().
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/gdi32/font.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 9c24182c57e..c952495f7da 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -3936,7 +3936,7 @@ static DWORD get_key_value( HKEY key1, HKEY key2, const WCHAR *name, DWORD *valu
static void init_font_options(void)
{
HKEY key, volatile_key = NULL;
- DWORD i, type, size, val, gamma = 1400;
+ DWORD i, type, size, val, gamma = 1400, vertical = 0;
WCHAR buffer[20];
size = sizeof(buffer);
@@ -3950,16 +3950,18 @@ static void init_font_options(void)
{
RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Temporary System Parameters\\Control Panel\\Desktop",
&volatile_key );
- /* FIXME: handle vertical orientations even though Windows doesn't */
+
+ get_key_value( volatile_key, key, L"WineFontSmoothingVertical", &vertical );
+
if (!get_key_value( volatile_key, key, L"FontSmoothingOrientation", &val ))
{
switch (val)
{
case 0: /* FE_FONTSMOOTHINGORIENTATIONBGR */
- subpixel_orientation = WINE_GGO_HBGR_BITMAP;
+ subpixel_orientation = vertical ? WINE_GGO_VBGR_BITMAP : WINE_GGO_HBGR_BITMAP;
break;
case 1: /* FE_FONTSMOOTHINGORIENTATIONRGB */
- subpixel_orientation = WINE_GGO_HRGB_BITMAP;
+ subpixel_orientation = vertical ? WINE_GGO_VRGB_BITMAP : WINE_GGO_HRGB_BITMAP;
break;
}
}
--
2.28.0
Dec. 3, 2020
[PATCH v3 2/7] winex11.drv: Init font smoothing system default parameters in X11DRV_XRender_Init().
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
v3:
- use WineFontSmoothingVertical registry value name.
dlls/winex11.drv/xrender.c | 61 ++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/dlls/winex11.drv/xrender.c b/dlls/winex11.drv/xrender.c
index 3376cee517d..dc3bed2bfa0 100644
--- a/dlls/winex11.drv/xrender.c
+++ b/dlls/winex11.drv/xrender.c
@@ -32,6 +32,7 @@
#include "windef.h"
#include "winbase.h"
+#include "winreg.h"
#include "x11drv.h"
#include "winternl.h"
#include "wine/unicode.h"
@@ -314,6 +315,64 @@ static int load_xrender_formats(void)
return count;
}
+static void set_default_font_smoothing(void)
+{
+ DWORD smoothing_type, orientation, vertical;
+ BOOL smoothing;
+ HKEY sysparam_key;
+ char *value;
+
+ if ((value = XGetDefault( gdi_display, "Xft", "antialias" )))
+ {
+ TRACE( "got antialias '%s'.\n", value );
+ smoothing = !(tolower(value[0]) == 'f' || tolower(value[0]) == 'n' ||
+ value[0] == '0' || !_strnicmp( value, "off", -1 ));
+ SystemParametersInfoA(SPI_SETFONTSMOOTHING, smoothing, NULL, 0);
+ }
+ else
+ {
+ if (!SystemParametersInfoA(SPI_GETFONTSMOOTHING, 0, &smoothing, 0))
+ smoothing = FALSE;
+ }
+
+ if ((value = XGetDefault( gdi_display, "Xft", "rgba" )))
+ {
+ TRACE( "got rgba '%s'.\n", value );
+
+ vertical = 0;
+ orientation = smoothing_type = ~0u;
+ if (!strcmp( value, "rgb" ) || (vertical = !strcmp( value, "vrgb" )))
+ {
+ smoothing_type = FE_FONTSMOOTHINGCLEARTYPE;
+ orientation = FE_FONTSMOOTHINGORIENTATIONRGB;
+ }
+ else if (!strcmp( value, "bgr" ) || (vertical = !strcmp( value, "vbgr" )))
+ {
+ smoothing_type = FE_FONTSMOOTHINGCLEARTYPE;
+ orientation = FE_FONTSMOOTHINGORIENTATIONBGR;
+ }
+ else if (!strcmp( value, "none" ))
+ {
+ smoothing_type = FE_FONTSMOOTHINGSTANDARD;
+ }
+
+ if (smoothing)
+ {
+ if (smoothing_type != ~0u)
+ SystemParametersInfoA(SPI_SETFONTSMOOTHINGTYPE, 0, (void *)(ULONG_PTR)smoothing_type, 0);
+ if (orientation != ~0u)
+ SystemParametersInfoA(SPI_SETFONTSMOOTHINGORIENTATION, 0, (void *)(ULONG_PTR)orientation, 0);
+ }
+
+ if (smoothing_type != ~0u && !RegOpenKeyA( HKEY_CURRENT_USER,
+ "Software\\Wine\\Temporary System Parameters\\Control Panel\\Desktop", &sysparam_key ))
+ {
+ RegSetValueExA( sysparam_key, "WineFontSmoothingVertical", 0, REG_DWORD, (BYTE *)&vertical, sizeof(vertical) );
+ RegCloseKey( sysparam_key );
+ }
+ }
+}
+
/***********************************************************************
* X11DRV_XRender_Init
*
@@ -379,6 +438,8 @@ const struct gdi_dc_funcs *X11DRV_XRender_Init(void)
}
glyphsetCache[i-1].next = -1;
+ set_default_font_smoothing();
+
return &xrender_funcs;
}
--
2.28.0
Dec. 3, 2020
[PATCH v3 1/7] gdi32: Mind temporary system parameters in init_font_options().
by Paul Gofman
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/gdi32/font.c | 31 ++++++++++++++++++-------------
1 file changed, 18 insertions(+), 13 deletions(-)
diff --git a/dlls/gdi32/font.c b/dlls/gdi32/font.c
index 9fa0f45ec4b..9c24182c57e 100644
--- a/dlls/gdi32/font.c
+++ b/dlls/gdi32/font.c
@@ -3918,23 +3918,24 @@ const struct gdi_dc_funcs font_driver =
GDI_PRIORITY_FONT_DRV /* priority */
};
-static DWORD get_key_value( HKEY key, const WCHAR *name, DWORD *value )
+static DWORD get_key_value( HKEY key1, HKEY key2, const WCHAR *name, DWORD *value )
{
WCHAR buf[12];
DWORD count = sizeof(buf), type, err;
- err = RegQueryValueExW( key, name, NULL, &type, (BYTE *)buf, &count );
- if (!err)
- {
- if (type == REG_DWORD) memcpy( value, buf, sizeof(*value) );
- else *value = wcstol( buf, NULL, 10 );
- }
- return err;
+ if ((err = RegQueryValueExW( key1, name, NULL, &type, (BYTE *)buf, &count ))
+ && (err = RegQueryValueExW( key2, name, NULL, &type, (BYTE *)buf, &count )))
+ return err;
+
+ if (type == REG_DWORD) memcpy( value, buf, sizeof(*value) );
+ else *value = wcstol( buf, NULL, 10 );
+
+ return 0;
}
static void init_font_options(void)
{
- HKEY key;
+ HKEY key, volatile_key = NULL;
DWORD i, type, size, val, gamma = 1400;
WCHAR buffer[20];
@@ -3947,8 +3948,10 @@ static void init_font_options(void)
if (!RegOpenKeyW( HKEY_CURRENT_USER, L"Control Panel\\Desktop", &key ))
{
+ RegOpenKeyW( HKEY_CURRENT_USER, L"Software\\Wine\\Temporary System Parameters\\Control Panel\\Desktop",
+ &volatile_key );
/* FIXME: handle vertical orientations even though Windows doesn't */
- if (!get_key_value( key, L"FontSmoothingOrientation", &val ))
+ if (!get_key_value( volatile_key, key, L"FontSmoothingOrientation", &val ))
{
switch (val)
{
@@ -3960,18 +3963,20 @@ static void init_font_options(void)
break;
}
}
- if (!get_key_value( key, L"FontSmoothing", &val ) && val /* enabled */)
+ if (!get_key_value( volatile_key, key, L"FontSmoothing", &val ) && val /* enabled */)
{
- if (!get_key_value( key, L"FontSmoothingType", &val ) && val == 2 /* FE_FONTSMOOTHINGCLEARTYPE */)
+ if (!get_key_value( volatile_key, key, L"FontSmoothingType", &val ) && val == 2 /* FE_FONTSMOOTHINGCLEARTYPE */)
font_smoothing = subpixel_orientation;
else
font_smoothing = GGO_GRAY4_BITMAP;
}
- if (!get_key_value( key, L"FontSmoothingGamma", &val ) && val)
+ if (!get_key_value( volatile_key, key, L"FontSmoothingGamma", &val ) && val)
{
gamma = min( max( val, 1000 ), 2200 );
}
RegCloseKey( key );
+ if (volatile_key)
+ RegCloseKey( volatile_key );
}
/* Calibrating the difference between the registry value and the Wine gamma value.
--
2.28.0
Dec. 3, 2020
Re: [PATCH] bcrypt: Implement RSA key pair importing.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH] msi: Use a string literal for empty strings.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH 6/6] gdi32: Use FreeType as a fallback when loading font faces.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH 5/6] gdi32: Try to parse font props without FreeType.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH 4/6] gdi32: Try to parse font names without FreeType.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH 3/6] gdi32: Introduce new opentype font parsing helpers.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH 2/6] gdi32: Store ft_face font props on unix_face.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH 1/6] gdi32: Introduce struct unix_face as a ft_face wrapper.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
Dec. 3, 2020
[PATCH v2] crypt32: Add support for CRYPT_STRING_HEX to CryptBinaryToStringW.
by Dmitry Timoshkov
This is a resend, is there anything that could be improved to make this patch accepted?
v2: Use wide-char string literals.
Signed-off-by: Dmitry Timoshkov <dmitry(a)baikal.ru>
---
dlls/crypt32/base64.c | 79 ++++++++++++++++++++++++-
dlls/crypt32/tests/base64.c | 113 +++++++++++++++++++++++++++++++++++-
2 files changed, 189 insertions(+), 3 deletions(-)
diff --git a/dlls/crypt32/base64.c b/dlls/crypt32/base64.c
index 1fd4dc136e..bd9fdac122 100644
--- a/dlls/crypt32/base64.c
+++ b/dlls/crypt32/base64.c
@@ -460,7 +460,7 @@ static BOOL BinaryToBase64W(const BYTE *pbBinary,
return ret;
}
-static BOOL BinaryToHexW(const BYTE *bin, DWORD nbin, DWORD flags, LPWSTR str, DWORD *nstr)
+static BOOL BinaryToHexRawW(const BYTE *bin, DWORD nbin, DWORD flags, LPWSTR str, DWORD *nstr)
{
static const WCHAR hex[] = L"0123456789abcdef";
DWORD needed;
@@ -506,6 +506,79 @@ static BOOL BinaryToHexW(const BYTE *bin, DWORD nbin, DWORD flags, LPWSTR str, D
return TRUE;
}
+static BOOL binary_to_hexW(const BYTE *bin, DWORD nbin, DWORD flags, LPWSTR str, DWORD *nstr)
+{
+ static const WCHAR hex[] = L"0123456789abcdef";
+ DWORD needed, i;
+
+ needed = nbin * 3; /* spaces + terminating \0 */
+
+ if (flags & CRYPT_STRING_NOCR)
+ {
+ needed += (nbin + 7) / 16; /* space every 16 characters */
+ needed += 1; /* terminating \n */
+ }
+ else if (!(flags & CRYPT_STRING_NOCRLF))
+ {
+ needed += (nbin + 7) / 16; /* space every 16 characters */
+ needed += nbin / 16 + 1; /* LF every 16 characters + terminating \r */
+
+ if (nbin % 16)
+ needed += 1; /* terminating \n */
+ }
+
+ if (!str)
+ {
+ *nstr = needed;
+ return TRUE;
+ }
+
+ if (needed > *nstr)
+ {
+ SetLastError(ERROR_MORE_DATA);
+ return FALSE;
+ }
+
+ for (i = 0; i < nbin; i++)
+ {
+ *str++ = hex[(bin[i] >> 4) & 0xf];
+ *str++ = hex[bin[i] & 0xf];
+
+ if (i >= nbin - 1) break;
+
+ if (i && !(flags & CRYPT_STRING_NOCRLF))
+ {
+ if (i >= 15 && !((i + 1) % 16))
+ {
+ if (flags & CRYPT_STRING_NOCR)
+ *str++ = '\n';
+ else
+ {
+ *str++ = '\r';
+ *str++ = '\n';
+ }
+ continue;
+ }
+ else if (i >= 7 && !((i + 1) % 8))
+ *str++ = ' ';
+ }
+
+ *str++ = ' ';
+ }
+
+ if (flags & CRYPT_STRING_NOCR)
+ *str++ = '\n';
+ else if (!(flags & CRYPT_STRING_NOCRLF))
+ {
+ *str++ = '\r';
+ *str++ = '\n';
+ }
+
+ *str = 0;
+ *nstr = needed - 1;
+ return TRUE;
+}
+
BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary,
DWORD cbBinary, DWORD dwFlags, LPWSTR pszString, DWORD *pcchString)
{
@@ -537,9 +610,11 @@ BOOL WINAPI CryptBinaryToStringW(const BYTE *pbBinary,
encoder = BinaryToBase64W;
break;
case CRYPT_STRING_HEXRAW:
- encoder = BinaryToHexW;
+ encoder = BinaryToHexRawW;
break;
case CRYPT_STRING_HEX:
+ encoder = binary_to_hexW;
+ break;
case CRYPT_STRING_HEXASCII:
case CRYPT_STRING_HEXADDR:
case CRYPT_STRING_HEXASCIIADDR:
diff --git a/dlls/crypt32/tests/base64.c b/dlls/crypt32/tests/base64.c
index a48f0a5c44..a17267c702 100644
--- a/dlls/crypt32/tests/base64.c
+++ b/dlls/crypt32/tests/base64.c
@@ -236,12 +236,36 @@ static void encode_compare_base64_W(const BYTE *toEncode, DWORD toEncodeLen, DWO
heap_free(trailerW);
}
+static DWORD binary_to_hex_len(DWORD binary_len, DWORD flags)
+{
+ DWORD strLen2;
+
+ strLen2 = binary_len * 3; /* spaces + terminating \0 */
+
+ if (flags & CRYPT_STRING_NOCR)
+ {
+ strLen2 += (binary_len + 7) / 16; /* space every 16 characters */
+ strLen2 += 1; /* terminating \n */
+ }
+ else if (!(flags & CRYPT_STRING_NOCRLF))
+ {
+ strLen2 += (binary_len + 7) / 16; /* space every 16 characters */
+ strLen2 += binary_len / 16 + 1; /* LF every 16 characters + terminating \r */
+
+ if (binary_len % 16)
+ strLen2 += 1; /* terminating \n */
+ }
+
+ return strLen2;
+}
+
static void test_CryptBinaryToString(void)
{
static const DWORD flags[] = { 0, CRYPT_STRING_NOCR, CRYPT_STRING_NOCRLF };
+ static const DWORD sizes[] = { 3, 4, 7, 8, 12, 15, 16, 17, 256 };
static const WCHAR hexdig[] = L"0123456789abcdef";
BYTE input[256 * sizeof(WCHAR)];
- DWORD strLen, strLen2, i, j;
+ DWORD strLen, strLen2, i, j, k;
WCHAR *hex, *cmp, *ptr;
BOOL ret;
@@ -444,6 +468,93 @@ static void test_CryptBinaryToString(void)
heap_free(hex);
heap_free(cmp);
}
+
+ for (k = 0; k < ARRAY_SIZE(sizes); k++)
+ for (i = 0; i < ARRAY_SIZE(flags); i++)
+ {
+ strLen = 0;
+ ret = CryptBinaryToStringW(input, sizes[k], CRYPT_STRING_HEX | flags[i], NULL, &strLen);
+ ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError());
+ ok(strLen > 0, "Unexpected string length.\n");
+
+ strLen = ~0;
+ ret = CryptBinaryToStringW(input, sizes[k], CRYPT_STRING_HEX | flags[i], NULL, &strLen);
+ ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError());
+ strLen2 = binary_to_hex_len(sizes[k], CRYPT_STRING_HEX | flags[i]);
+ ok(strLen == strLen2, "%u: Expected length %d, got %d\n", i, strLen2, strLen);
+
+ hex = heap_alloc(strLen * sizeof(WCHAR) + 256);
+ memset(hex, 0xcc, strLen * sizeof(WCHAR));
+
+ ptr = cmp = heap_alloc(strLen * sizeof(WCHAR) + 256);
+ for (j = 0; j < sizes[k]; j++)
+ {
+ *ptr++ = hexdig[(input[j] >> 4) & 0xf];
+ *ptr++ = hexdig[input[j] & 0xf];
+
+ if (j >= sizes[k] - 1) break;
+
+ if (j && !(flags[i] & CRYPT_STRING_NOCRLF))
+ {
+
+ if (j >= 15 && !((j + 1) % 16))
+ {
+ if (flags[i] & CRYPT_STRING_NOCR)
+ {
+ *ptr++ = '\n';
+ }
+ else
+ {
+ *ptr++ = '\r';
+ *ptr++ = '\n';
+ }
+ continue;
+ }
+ else if (j >= 7 && !((j + 1) % 8))
+ *ptr++ = ' ';
+ }
+
+ *ptr++ = ' ';
+ }
+
+ if (flags[i] & CRYPT_STRING_NOCR)
+ {
+ *ptr++ = '\n';
+ }
+ else if (!(flags[i] & CRYPT_STRING_NOCRLF))
+ {
+ *ptr++ = '\r';
+ *ptr++ = '\n';
+ }
+ *ptr++ = 0;
+
+ ret = CryptBinaryToStringW(input, sizes[k], CRYPT_STRING_HEX | flags[i], hex, &strLen);
+ ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError());
+ strLen2--;
+ ok(strLen == strLen2, "%u: Expected length %d, got %d\n", i, strLen, strLen2);
+ ok(!memcmp(hex, cmp, strLen * sizeof(WCHAR)), "%u: got %s\n", i, wine_dbgstr_wn(hex, strLen));
+
+ /* adjusts size if buffer too big */
+ strLen *= 2;
+ ret = CryptBinaryToStringW(input, sizes[k], CRYPT_STRING_HEX | flags[i], hex, &strLen);
+ ok(ret, "CryptBinaryToStringW failed: %d\n", GetLastError());
+ ok(strLen == strLen2, "%u: Expected length %d, got %d\n", i, strLen, strLen2);
+
+ /* no writes if buffer too small */
+ strLen /= 2;
+ strLen2 /= 2;
+ memset(hex, 0xcc, strLen * sizeof(WCHAR));
+ memset(cmp, 0xcc, strLen * sizeof(WCHAR));
+ SetLastError(0xdeadbeef);
+ ret = CryptBinaryToStringW(input, sizes[k], CRYPT_STRING_HEX | flags[i], hex, &strLen);
+ ok(!ret && GetLastError() == ERROR_MORE_DATA,"Expected ERROR_MORE_DATA, got ret=%d le=%u\n",
+ ret, GetLastError());
+ ok(strLen == strLen2, "%u: Expected length %d, got %d\n", i, strLen, strLen2);
+ ok(!memcmp(hex, cmp, strLen * sizeof(WCHAR)), "%u: got %s\n", i, wine_dbgstr_wn(hex, strLen));
+
+ heap_free(hex);
+ heap_free(cmp);
+ }
}
static void decodeAndCompareBase64_A(LPCSTR toDecode, LPCSTR header,
--
2.29.2
Dec. 3, 2020
[PATCH v2 2/2] jscript: Clean up date formatting strings with era.
by Jeff Smith
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/jscript/date.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
diff --git a/dlls/jscript/date.c b/dlls/jscript/date.c
index 5ca23f199f3..efb97aa632e 100644
--- a/dlls/jscript/date.c
+++ b/dlls/jscript/date.c
@@ -441,7 +441,7 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset,
LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
- BOOL formatAD = TRUE;
+ const WCHAR *formatEra = L"";
WCHAR week[64], month[64];
WCHAR buf[192];
jsstr_t *date_jsstr;
@@ -466,7 +466,7 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset,
year = year_from_time(time);
if(year<0) {
- formatAD = FALSE;
+ formatEra = L" B.C.";
year = -year+1;
}
@@ -480,16 +480,16 @@ static inline HRESULT date_to_string(DOUBLE time, BOOL show_offset, int offset,
if(!show_offset)
swprintf(buf, ARRAY_SIZE(buf), L"%s %s %d %02d:%02d:%02d %d%s", week, month, day,
(int)hour_from_time(time), (int)min_from_time(time),
- (int)sec_from_time(time), year, formatAD?L"":L" B.C.");
+ (int)sec_from_time(time), year, formatEra);
else if(offset)
swprintf(buf, ARRAY_SIZE(buf), L"%s %s %d %02d:%02d:%02d UTC%c%02d%02d %d%s", week, month, day,
(int)hour_from_time(time), (int)min_from_time(time),
(int)sec_from_time(time), sign, offset/60, offset%60,
- year, formatAD?L"":L" B.C.");
+ year, formatEra);
else
swprintf(buf, ARRAY_SIZE(buf), L"%s %s %d %02d:%02d:%02d UTC %d%s", week, month, day,
(int)hour_from_time(time), (int)min_from_time(time),
- (int)sec_from_time(time), year, formatAD?L"":L" B.C.");
+ (int)sec_from_time(time), year, formatEra);
date_jsstr = jsstr_alloc(buf);
if(!date_jsstr)
@@ -638,7 +638,7 @@ static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsva
LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
- BOOL formatAD = TRUE;
+ const WCHAR *formatEra = L"";
WCHAR week[64], month[64];
WCHAR buf[192];
DateInstance *date;
@@ -666,15 +666,15 @@ static inline HRESULT create_utc_string(script_ctx_t *ctx, vdisp_t *jsthis, jsva
year = year_from_time(date->time);
if(year<0) {
- formatAD = FALSE;
+ formatEra = L" B.C.";
year = -year+1;
}
day = date_from_time(date->time);
swprintf(buf, ARRAY_SIZE(buf),
- formatAD ? L"%s, %d %s %d %02d:%02d:%02d UTC" : L"%s, %d %s %d B.C. %02d:%02d:%02d UTC",
- week, day, month, year, (int)hour_from_time(date->time), (int)min_from_time(date->time),
+ L"%s, %d %s %d%s %02d:%02d:%02d UTC", week, day, month, year, formatEra,
+ (int)hour_from_time(date->time), (int)min_from_time(date->time),
(int)sec_from_time(date->time));
date_str = jsstr_alloc(buf);
@@ -714,7 +714,7 @@ static HRESULT dateobj_to_date_string(DateInstance *date, jsval_t *r)
LOCALE_SABBREVMONTHNAME9, LOCALE_SABBREVMONTHNAME10,
LOCALE_SABBREVMONTHNAME11, LOCALE_SABBREVMONTHNAME12 };
- BOOL formatAD = TRUE;
+ const WCHAR *formatEra = L"";
WCHAR week[64], month[64];
WCHAR buf[192];
jsstr_t *date_str;
@@ -741,14 +741,13 @@ static HRESULT dateobj_to_date_string(DateInstance *date, jsval_t *r)
year = year_from_time(time);
if(year<0) {
- formatAD = FALSE;
+ formatEra = L" B.C.";
year = -year+1;
}
day = date_from_time(time);
- swprintf(buf, ARRAY_SIZE(buf), formatAD ? L"%s %s %d %d" : L"%s %s %d %d B.C.", week, month,
- day, year);
+ swprintf(buf, ARRAY_SIZE(buf), L"%s %s %d %d%s", week, month, day, year, formatEra);
date_str = jsstr_alloc(buf);
if(!date_str)
--
2.23.0
Dec. 3, 2020
[PATCH v2 1/2] jscript: Use wide-char string literals.
by Jeff Smith
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
v2 - Fix some logic errors and suboptimal code.
dlls/jscript/decode.c | 12 ++++++------
dlls/jscript/function.c | 19 +++++++++----------
dlls/jscript/jsutils.c | 6 +++---
dlls/jscript/parser.y | 4 +---
dlls/jscript/string.c | 4 +---
5 files changed, 20 insertions(+), 25 deletions(-)
diff --git a/dlls/jscript/decode.c b/dlls/jscript/decode.c
index 283aa2ed947..6a87d55e0e0 100644
--- a/dlls/jscript/decode.c
+++ b/dlls/jscript/decode.c
@@ -113,14 +113,14 @@ HRESULT decode_source(WCHAR *code)
const WCHAR *src = code;
WCHAR *dst = code;
- static const WCHAR decode_beginW[] = {'#','@','~','^'};
- static const WCHAR decode_endW[] = {'^','#','~','@'};
+ static const WCHAR decode_beginW[] = L"#@~^";
+ static const WCHAR decode_endW[] = L"^#~@";
while(*src) {
- if(!wcsncmp(src, decode_beginW, ARRAY_SIZE(decode_beginW))) {
+ if(!wcsncmp(src, decode_beginW, ARRAY_SIZE(decode_beginW)-1)) {
DWORD len, i, j=0, csum, s=0;
- src += ARRAY_SIZE(decode_beginW);
+ src += ARRAY_SIZE(decode_beginW) - 1;
if(!decode_dword(src, &len))
return JS_E_INVALID_CHAR;
@@ -165,9 +165,9 @@ HRESULT decode_source(WCHAR *code)
return JS_E_INVALID_CHAR;
src += 8;
- if(wcsncmp(src, decode_endW, ARRAY_SIZE(decode_endW)))
+ if(wcsncmp(src, decode_endW, ARRAY_SIZE(decode_endW)-1))
return JS_E_INVALID_CHAR;
- src += ARRAY_SIZE(decode_endW);
+ src += ARRAY_SIZE(decode_endW) - 1;
}else {
*dst++ = *src++;
}
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 9f6aa4b4ec6..7a6dd4b61f3 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -620,17 +620,16 @@ static HRESULT NativeFunction_toString(FunctionInstance *func, jsstr_t **ret)
jsstr_t *str;
WCHAR *ptr;
- static const WCHAR native_prefixW[] = {'\n','f','u','n','c','t','i','o','n',' '};
- static const WCHAR native_suffixW[] =
- {'(',')',' ','{','\n',' ',' ',' ',' ','[','n','a','t','i','v','e',' ','c','o','d','e',']','\n','}','\n'};
+ static const WCHAR native_prefixW[] = L"\nfunction ";
+ static const WCHAR native_suffixW[] = L"() {\n [native code]\n}\n";
name_len = function->name ? lstrlenW(function->name) : 0;
- str = jsstr_alloc_buf(ARRAY_SIZE(native_prefixW) + ARRAY_SIZE(native_suffixW) + name_len, &ptr);
+ str = jsstr_alloc_buf(ARRAY_SIZE(native_prefixW) + ARRAY_SIZE(native_suffixW) + name_len - 2, &ptr);
if(!str)
return E_OUTOFMEMORY;
memcpy(ptr, native_prefixW, sizeof(native_prefixW));
- ptr += ARRAY_SIZE(native_prefixW);
+ ptr += ARRAY_SIZE(native_prefixW) - 1;
memcpy(ptr, function->name, name_len*sizeof(WCHAR));
ptr += name_len;
memcpy(ptr, native_suffixW, sizeof(native_suffixW));
@@ -912,8 +911,8 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
int j = 0;
HRESULT hres = S_OK;
- static const WCHAR function_anonymousW[] = {'f','u','n','c','t','i','o','n',' ','a','n','o','n','y','m','o','u','s','('};
- static const WCHAR function_beginW[] = {')',' ','{','\n'};
+ static const WCHAR function_anonymousW[] = L"function anonymous(";
+ static const WCHAR function_beginW[] = L") {\n";
static const WCHAR function_endW[] = L"\n}";
if(argc) {
@@ -932,11 +931,11 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
}
if(SUCCEEDED(hres)) {
- len += ARRAY_SIZE(function_anonymousW) + ARRAY_SIZE(function_beginW) + ARRAY_SIZE(function_endW);
+ len += ARRAY_SIZE(function_anonymousW) + ARRAY_SIZE(function_beginW) + ARRAY_SIZE(function_endW) - 2;
str = heap_alloc(len*sizeof(WCHAR));
if(str) {
memcpy(str, function_anonymousW, sizeof(function_anonymousW));
- ptr = str + ARRAY_SIZE(function_anonymousW);
+ ptr = str + ARRAY_SIZE(function_anonymousW) - 1;
if(argc > 1) {
while(1) {
ptr += jsstr_flush(params[j], ptr);
@@ -947,7 +946,7 @@ static HRESULT construct_function(script_ctx_t *ctx, unsigned argc, jsval_t *arg
}
}
memcpy(ptr, function_beginW, sizeof(function_beginW));
- ptr += ARRAY_SIZE(function_beginW);
+ ptr += ARRAY_SIZE(function_beginW) - 1;
if(argc)
ptr += jsstr_flush(params[argc-1], ptr);
memcpy(ptr, function_endW, sizeof(function_endW));
diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c
index 56e8306ba21..a2ac53f64b9 100644
--- a/dlls/jscript/jsutils.c
+++ b/dlls/jscript/jsutils.c
@@ -494,7 +494,7 @@ static HRESULT str_to_number(jsstr_t *str, double *ret)
BOOL neg = FALSE;
DOUBLE d = 0.0;
- static const WCHAR infinityW[] = {'I','n','f','i','n','i','t','y'};
+ static const WCHAR infinityW[] = L"Infinity";
ptr = jsstr_flatten(str);
if(!ptr)
@@ -510,8 +510,8 @@ static HRESULT str_to_number(jsstr_t *str, double *ret)
ptr++;
}
- if(!wcsncmp(ptr, infinityW, ARRAY_SIZE(infinityW))) {
- ptr += ARRAY_SIZE(infinityW);
+ if(!wcsncmp(ptr, infinityW, ARRAY_SIZE(infinityW)-1)) {
+ ptr += ARRAY_SIZE(infinityW) - 1;
while(*ptr && iswspace(*ptr))
ptr++;
diff --git a/dlls/jscript/parser.y b/dlls/jscript/parser.y
index 6016be6cfd8..ba81668dbb3 100644
--- a/dlls/jscript/parser.y
+++ b/dlls/jscript/parser.y
@@ -1573,14 +1573,12 @@ HRESULT script_parse(script_ctx_t *ctx, struct _compiler_ctx_t *compiler, byteco
heap_pool_t *mark;
HRESULT hres;
- const WCHAR html_tagW[] = {'<','/','s','c','r','i','p','t','>',0};
-
parser_ctx = heap_alloc_zero(sizeof(parser_ctx_t));
if(!parser_ctx)
return E_OUTOFMEMORY;
parser_ctx->error_loc = -1;
- parser_ctx->is_html = delimiter && !wcsicmp(delimiter, html_tagW);
+ parser_ctx->is_html = delimiter && !wcsicmp(delimiter, L"</script>");
parser_ctx->begin = parser_ctx->ptr = code->source;
parser_ctx->end = parser_ctx->begin + lstrlenW(parser_ctx->begin);
diff --git a/dlls/jscript/string.c b/dlls/jscript/string.c
index 3dd40e6744f..a8bd77dc398 100644
--- a/dlls/jscript/string.c
+++ b/dlls/jscript/string.c
@@ -888,9 +888,7 @@ static HRESULT String_replace(script_ctx_t *ctx, vdisp_t *jsthis, WORD flags, un
if(FAILED(hres))
break;
}else {
- static const WCHAR undefinedW[] = {'u','n','d','e','f','i','n','e','d'};
-
- hres = strbuf_append(&ret, undefinedW, ARRAY_SIZE(undefinedW));
+ hres = strbuf_append(&ret, L"undefined", ARRAY_SIZE(L"undefined")-1);
if(FAILED(hres))
break;
}
--
2.23.0
Dec. 3, 2020
[PATCH] bcrypt: Implement RSA key pair importing.
by Nikolay Sivov
Requires libgnutls 3.7.0, that contains fixes for optional arguments handling
in gnutls_privkey_import_rsa_raw() to support BCRYPT_RSAPRIVATE_BLOB.
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/bcrypt/bcrypt_internal.h | 1 +
dlls/bcrypt/bcrypt_main.c | 21 ++++++++++++++++++++
dlls/bcrypt/gnutls.c | 36 ++++++++++++++++++++++++++++++++++-
dlls/bcrypt/macos.c | 9 ++++++++-
4 files changed, 65 insertions(+), 2 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h
index d5a54aad92b..e1777ed130b 100644
--- a/dlls/bcrypt/bcrypt_internal.h
+++ b/dlls/bcrypt/bcrypt_internal.h
@@ -214,6 +214,7 @@ struct key_funcs
NTSTATUS (CDECL *key_export_ecc)( struct key *, UCHAR *, ULONG, ULONG * );
NTSTATUS (CDECL *key_import_dsa_capi)( struct key *, UCHAR *, ULONG );
NTSTATUS (CDECL *key_import_ecc)( struct key *, UCHAR *, ULONG );
+ NTSTATUS (CDECL *key_import_rsa)( struct key *, UCHAR *, ULONG );
};
#endif /* __BCRYPT_INTERNAL_H */
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 1b7881d4910..591c01c710c 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -1331,6 +1331,27 @@ static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYP
size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
return key_asymmetric_create( (struct key **)ret_key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size );
}
+ else if (!wcscmp( type, BCRYPT_RSAPRIVATE_BLOB ))
+ {
+ BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)input;
+ ULONG size;
+
+ if (input_len < sizeof(*rsa_blob)) return STATUS_INVALID_PARAMETER;
+ if (alg->id != ALG_ID_RSA || rsa_blob->Magic != BCRYPT_RSAPRIVATE_MAGIC)
+ return STATUS_NOT_SUPPORTED;
+
+ size = sizeof(*rsa_blob) + rsa_blob->cbPublicExp + rsa_blob->cbModulus;
+ if ((status = key_asymmetric_create( &key, alg, rsa_blob->BitLength, (BYTE *)rsa_blob, size )))
+ return status;
+ if ((status = key_funcs->key_import_rsa( key, input, input_len )))
+ {
+ BCryptDestroyKey( key );
+ return status;
+ }
+
+ *ret_key = key;
+ return STATUS_SUCCESS;
+ }
else if (!wcscmp( type, BCRYPT_DSA_PUBLIC_BLOB ))
{
BCRYPT_DSA_KEY_BLOB *dsa_blob = (BCRYPT_DSA_KEY_BLOB *)input;
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 41df88ca8f6..162ac9ea732 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -1119,6 +1119,39 @@ static NTSTATUS CDECL key_import_ecc( struct key *key, UCHAR *buf, ULONG len )
return STATUS_SUCCESS;
}
+static NTSTATUS CDECL key_import_rsa( struct key *key, UCHAR *buf, ULONG len )
+{
+ BCRYPT_RSAKEY_BLOB *rsa_blob = (BCRYPT_RSAKEY_BLOB *)buf;
+ gnutls_datum_t m, e, p, q;
+ gnutls_privkey_t handle;
+ int ret;
+
+ if ((ret = pgnutls_privkey_init( &handle )))
+ {
+ pgnutls_perror( ret );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ e.data = (unsigned char *)(rsa_blob + 1);
+ e.size = rsa_blob->cbPublicExp;
+ m.data = e.data + e.size;
+ m.size = rsa_blob->cbModulus;
+ p.data = m.data + m.size;
+ p.size = rsa_blob->cbPrime1;
+ q.data = p.data + p.size;
+ q.size = rsa_blob->cbPrime2;
+
+ if ((ret = pgnutls_privkey_import_rsa_raw( handle, &m, &e, NULL, &p, &q, NULL, NULL, NULL )))
+ {
+ pgnutls_perror( ret );
+ pgnutls_privkey_deinit( handle );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ key_data(key)->privkey = handle;
+ return STATUS_SUCCESS;
+}
+
static NTSTATUS CDECL key_export_dsa_capi( struct key *key, UCHAR *buf, ULONG len, ULONG *ret_len )
{
BLOBHEADER *hdr;
@@ -1869,7 +1902,8 @@ static const struct key_funcs key_funcs =
key_export_dsa_capi,
key_export_ecc,
key_import_dsa_capi,
- key_import_ecc
+ key_import_ecc,
+ key_import_rsa
};
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
diff --git a/dlls/bcrypt/macos.c b/dlls/bcrypt/macos.c
index d8bba46ad5c..57edc3e262b 100644
--- a/dlls/bcrypt/macos.c
+++ b/dlls/bcrypt/macos.c
@@ -249,6 +249,12 @@ static NTSTATUS CDECL key_import_ecc( struct key *key, UCHAR *input, ULONG len )
return STATUS_NOT_IMPLEMENTED;
}
+static NTSTATUS CDECL key_import_rsa( struct key *key, UCHAR *input, ULONG len )
+{
+ FIXME( "not implemented on Mac\n" );
+ return STATUS_NOT_IMPLEMENTED;
+}
+
static NTSTATUS CDECL key_asymmetric_generate( struct key *key )
{
FIXME( "not implemented on Mac\n" );
@@ -284,7 +290,8 @@ static const struct key_funcs key_funcs =
key_export_dsa_capi,
key_export_ecc,
key_import_dsa_capi,
- key_import_ecc
+ key_import_ecc,
+ key_import_rsa
};
NTSTATUS CDECL __wine_init_unix_lib( HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out )
--
2.29.2
Dec. 3, 2020
Re: [PATCH] windowscodecs: Use wide-char string literals in struct initialization.
by Esme Povirk (they/them)
Signed-off-by: Esme Povirk <esme(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH] mscoree/tests: The comtest registry tests may require elevated privileges.
by Esme Povirk (they/them)
Signed-off-by: Esme Povirk <esme(a)codeweavers.com>
Dec. 3, 2020
Re: [PATCH vkd3d 5/5] vkd3d-shader: Implement basic support for #if and #endif.
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=83028
Your paranoid android.
=== debiant (build log) ===
error: patch failed: configure.ac:30
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: configure.ac:30
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH vkd3d 4/5] vkd3d-shader: Handle preprocessor parsing errors.
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=83027
Your paranoid android.
=== debiant (build log) ===
error: patch failed: configure.ac:30
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: configure.ac:30
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH vkd3d 3/5] vkd3d-shader: Preserve some tokens verbatim for HLSL.
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=83026
Your paranoid android.
=== debiant (build log) ===
error: patch failed: configure.ac:30
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: configure.ac:30
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH vkd3d 2/5] vkd3d-shader: Parse comments in the preprocessor.
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=83025
Your paranoid android.
=== debiant (build log) ===
error: patch failed: configure.ac:30
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: configure.ac:30
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH vkd3d 1/5] vkd3d-shader: Implement an initial pass-through HLSL preprocessor.
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=83024
Your paranoid android.
=== debiant (build log) ===
error: patch failed: configure.ac:30
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: configure.ac:30
Task: Patch failed to apply
Dec. 3, 2020
[PATCH vkd3d 5/5] vkd3d-shader: Implement basic support for #if and #endif.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
include/private/vkd3d_memory.h | 11 +++
libs/vkd3d-shader/preproc.h | 16 ++++
libs/vkd3d-shader/preproc.l | 94 ++++++++++++++++++--
libs/vkd3d-shader/preproc.y | 106 ++++++++++++++++++++++-
libs/vkd3d-shader/vkd3d_shader_main.c | 15 ++++
libs/vkd3d-shader/vkd3d_shader_private.h | 6 ++
tests/hlsl_d3d12.c | 2 +-
7 files changed, 242 insertions(+), 8 deletions(-)
diff --git a/include/private/vkd3d_memory.h b/include/private/vkd3d_memory.h
index df93abf5..bd56d30a 100644
--- a/include/private/vkd3d_memory.h
+++ b/include/private/vkd3d_memory.h
@@ -22,6 +22,7 @@
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
+#include <string.h>
#include "vkd3d_debug.h"
@@ -54,6 +55,16 @@ static inline void vkd3d_free(void *ptr)
free(ptr);
}
+static inline char *vkd3d_strdup(const char *string)
+{
+ size_t len = strlen(string) + 1;
+ char *ptr;
+
+ if ((ptr = vkd3d_malloc(len)))
+ memcpy(ptr, string, len);
+ return ptr;
+}
+
bool vkd3d_array_reserve(void **elements, size_t *capacity,
size_t element_count, size_t element_size) DECLSPEC_HIDDEN;
diff --git a/libs/vkd3d-shader/preproc.h b/libs/vkd3d-shader/preproc.h
index 769b8c23..29fbbd02 100644
--- a/libs/vkd3d-shader/preproc.h
+++ b/libs/vkd3d-shader/preproc.h
@@ -29,6 +29,12 @@ struct preproc_location
unsigned int first_line, first_column;
};
+struct preproc_if_state
+{
+ /* Are we currently in a "true" block? */
+ bool current_true;
+};
+
struct preproc_ctx
{
void *scanner;
@@ -38,7 +44,17 @@ struct preproc_ctx
unsigned int line, column;
const char *source_name;
+ struct preproc_if_state *if_stack;
+ size_t if_count, if_stack_size;
+
+ int current_directive;
+
+ bool last_was_newline;
+
bool error;
};
+void preproc_warning(struct preproc_ctx *ctx, const struct preproc_location *loc,
+ enum vkd3d_shader_error error, const char *format, ...) VKD3D_PRINTF_FUNC(4, 5) DECLSPEC_HIDDEN;
+
#endif
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l
index c0c6b13a..e9a5b14a 100644
--- a/libs/vkd3d-shader/preproc.l
+++ b/libs/vkd3d-shader/preproc.l
@@ -50,6 +50,7 @@ static void update_location(struct preproc_ctx *ctx);
%s C_COMMENT
%s CXX_COMMENT
+NEWLINE \r?\n
WS [ \t]
IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
@@ -57,10 +58,10 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
<INITIAL>"//" {yy_push_state(CXX_COMMENT, yyscanner);}
<INITIAL>"/*" {yy_push_state(C_COMMENT, yyscanner);}
-<CXX_COMMENT>\\\r?\n {}
+<CXX_COMMENT>\\{NEWLINE} {}
<CXX_COMMENT>\n {
yy_pop_state(yyscanner);
- return T_TEXT;
+ return T_NEWLINE;
}
<C_COMMENT>"*/" {yy_pop_state(yyscanner);}
<C_COMMENT,CXX_COMMENT><<EOF>> {yy_pop_state(yyscanner);}
@@ -68,13 +69,15 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
<INITIAL>{IDENTIFIER} {return T_TEXT;}
+ /* We have no use for floats, but shouldn't parse them as integers. */
+
<INITIAL>[0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[hHfF]? {return T_TEXT;}
<INITIAL>[0-9]+\.([eE][+-]?[0-9]+)?[hHfF]? {return T_TEXT;}
<INITIAL>[0-9]+([eE][+-]?[0-9]+)?[hHfF] {return T_TEXT;}
<INITIAL>[0-9]+[eE][+-]?[0-9]+ {return T_TEXT;}
-<INITIAL>0[xX][0-9a-fA-f]+[ul]{0,2} {return T_TEXT;}
-<INITIAL>0[0-7]*[ul]{0,2} {return T_TEXT;}
-<INITIAL>[1-9][0-9]*[ul]{0,2} {return T_TEXT;}
+<INITIAL>0[xX][0-9a-fA-f]+[ul]{0,2} {return T_INTEGER;}
+<INITIAL>0[0-7]*[ul]{0,2} {return T_INTEGER;}
+<INITIAL>[1-9][0-9]*[ul]{0,2} {return T_INTEGER;}
<INITIAL>"&&" {return T_TEXT;}
<INITIAL>"||" {return T_TEXT;}
@@ -87,6 +90,29 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
/* C strings (including escaped quotes). */
<INITIAL>\"([^"\\]|\\.)*\" {return T_TEXT;}
+<INITIAL>#{WS}*{IDENTIFIER} {
+ struct preproc_ctx *ctx = yyget_extra(yyscanner);
+ const char *p;
+
+ if (!ctx->last_was_newline)
+ return T_TEXT;
+
+ for (p = yytext + 1; strchr(" \t", *p); ++p)
+ ;
+
+ if (!strcmp(p, "endif"))
+ return T_ENDIF;
+ if (!strcmp(p, "if"))
+ return T_IF;
+
+ preproc_warning(ctx, yyget_lloc(yyscanner), VKD3D_SHADER_WARNING_PP_UNKNOWN_DIRECTIVE,
+ "Ignoring unknown directive \"%s\".", yytext);
+ return T_TEXT;
+ }
+
+<INITIAL>\\{NEWLINE} {}
+<INITIAL>{NEWLINE} {return T_NEWLINE;}
+
<INITIAL>{WS}+ {}
<INITIAL>. {return T_TEXT;}
@@ -114,6 +140,27 @@ static void update_location(struct preproc_ctx *ctx)
}
}
+static bool preproc_is_writing(struct preproc_ctx *ctx)
+{
+ if (!ctx->if_count)
+ return true;
+ return ctx->if_stack[ctx->if_count - 1].current_true;
+}
+
+static int return_token(int token, YYSTYPE *lval, const char *text)
+{
+ switch (token)
+ {
+ case T_INTEGER:
+ case T_TEXT:
+ if (!(lval->string = vkd3d_strdup(text)))
+ return PREPROC_YYerror;
+ break;
+ }
+
+ return token;
+}
+
int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
{
struct preproc_ctx *ctx = yyget_extra(scanner);
@@ -127,7 +174,32 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
return PREPROC_YYEOF;
text = yyget_text(scanner);
- TRACE("Parsing token %d, line %d, string %s.\n", token, lloc->first_line, debugstr_a(text));
+ lloc->filename = ctx->source_name;
+
+ if (ctx->last_was_newline)
+ {
+ switch (token)
+ {
+ case T_ENDIF:
+ case T_IF:
+ ctx->current_directive = token;
+ break;
+
+ default:
+ ctx->current_directive = 0;
+ }
+ }
+
+ ctx->last_was_newline = (token == T_NEWLINE);
+
+ TRACE("Parsing token %d, line %d, in directive %d, string %s.\n", token,
+ lloc->first_line, ctx->current_directive, debugstr_a(text));
+
+ if (!ctx->current_directive && !preproc_is_writing(ctx))
+ continue;
+
+ if (ctx->current_directive)
+ return return_token(token, lval, text);
vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text);
}
@@ -148,12 +220,22 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
yylex_init_extra(&ctx, &ctx.scanner);
top_buffer = yy_scan_bytes(compile_info->source.code, compile_info->source.size, ctx.scanner);
+ ctx.last_was_newline = true;
preproc_yyparse(ctx.scanner, &ctx);
yy_delete_buffer(top_buffer, ctx.scanner);
yylex_destroy(ctx.scanner);
+ if (ctx.if_count)
+ {
+ const struct preproc_location loc = {.filename = ctx.source_name};
+
+ preproc_warning(&ctx, &loc, VKD3D_SHADER_WARNING_PP_UNTERMINATED_IF, "Unterminated #if block.");
+ }
+
+ vkd3d_free(ctx.if_stack);
+
if (ctx.error)
{
WARN("Failed to preprocess.\n");
diff --git a/libs/vkd3d-shader/preproc.y b/libs/vkd3d-shader/preproc.y
index 88b855c6..4353d10c 100644
--- a/libs/vkd3d-shader/preproc.y
+++ b/libs/vkd3d-shader/preproc.y
@@ -72,11 +72,71 @@ static void preproc_error(struct preproc_ctx *ctx, const struct preproc_location
ctx->error = true;
}
+void preproc_warning(struct preproc_ctx *ctx, const struct preproc_location *loc,
+ enum vkd3d_shader_error error, const char *format, ...)
+{
+ va_list args;
+
+ set_location(ctx, loc);
+ va_start(args, format);
+ vkd3d_shader_vwarning(ctx->message_context, error, format, args);
+ va_end(args);
+}
+
static void yyerror(const YYLTYPE *loc, void *scanner, struct preproc_ctx *ctx, const char *string)
{
preproc_error(ctx, loc, VKD3D_SHADER_ERROR_PP_INVALID_SYNTAX, "%s", string);
}
+static bool preproc_was_writing(struct preproc_ctx *ctx)
+{
+ if (ctx->if_count < 2)
+ return true;
+ return ctx->if_stack[ctx->if_count - 2].current_true;
+}
+
+static bool preproc_push_if(struct preproc_ctx *ctx, bool condition)
+{
+ struct preproc_if_state *state;
+
+ if (!vkd3d_array_reserve((void **)&ctx->if_stack, &ctx->if_stack_size, ctx->if_count + 1, sizeof(*ctx->if_stack)))
+ return false;
+ state = &ctx->if_stack[ctx->if_count++];
+ state->current_true = condition && preproc_was_writing(ctx);
+ return true;
+}
+
+static int char_to_int(char c)
+{
+ if ('0' <= c && c <= '9')
+ return c - '0';
+ if ('A' <= c && c <= 'F')
+ return c - 'A' + 10;
+ if ('a' <= c && c <= 'f')
+ return c - 'a' + 10;
+ return -1;
+}
+
+static uint32_t preproc_parse_integer(const char *s)
+{
+ uint32_t base = 10, ret = 0;
+ int digit;
+
+ if (s[0] == '0')
+ {
+ base = 8;
+ if (s[1] == 'x' || s[1] == 'X')
+ {
+ base = 16;
+ s += 2;
+ }
+ }
+
+ while ((digit = char_to_int(*s++)) >= 0)
+ ret = ret * base + (uint32_t)digit;
+ return ret;
+}
+
}
%define api.location.type {struct preproc_location}
@@ -89,9 +149,53 @@ static void yyerror(const YYLTYPE *loc, void *scanner, struct preproc_ctx *ctx,
%parse-param {void *scanner}
%parse-param {struct preproc_ctx *ctx}
-%token T_TEXT
+%union
+{
+ char *string;
+ uint32_t integer;
+}
+
+%token <string> T_INTEGER
+%token <string> T_TEXT
+
+%token T_NEWLINE
+
+%token T_ENDIF "#endif"
+%token T_IF "#if"
+
+%type <integer> expr
%%
shader_text
: %empty
+ | shader_text directive
+ {
+ vkd3d_string_buffer_printf(&ctx->buffer, "\n");
+ }
+
+directive
+ : T_IF expr newline
+ {
+ if (!preproc_push_if(ctx, !!$2))
+ YYABORT;
+ }
+ | T_ENDIF newline
+ {
+ if (ctx->if_count)
+ --ctx->if_count;
+ else
+ preproc_warning(ctx, &@$, VKD3D_SHADER_WARNING_PP_INVALID_DIRECTIVE,
+ "Ignoring #endif without prior #if.");
+ }
+
+newline
+ : T_NEWLINE
+ | YYEOF
+
+expr
+ : T_INTEGER
+ {
+ $$ = preproc_parse_integer($1);
+ vkd3d_free($1);
+ }
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index eed0316c..ad456133 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -148,6 +148,21 @@ bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_cont
return true;
}
+void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context,
+ enum vkd3d_shader_error error, const char *format, va_list args)
+{
+ if (context->log_level < VKD3D_SHADER_LOG_WARNING)
+ return;
+
+ if (context->line)
+ vkd3d_string_buffer_printf(&context->messages, "%s:%u:%u: W%04u: ",
+ context->source_name, context->line, context->column, error);
+ else
+ vkd3d_string_buffer_printf(&context->messages, "%s: W%04u: ", context->source_name, error);
+ vkd3d_string_buffer_vprintf(&context->messages, format, args);
+ vkd3d_string_buffer_printf(&context->messages, "\n");
+}
+
void vkd3d_shader_verror(struct vkd3d_shader_message_context *context,
enum vkd3d_shader_error error, const char *format, va_list args)
{
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 5a022708..01a74ede 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -81,6 +81,10 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_RS_MIXED_DESCRIPTOR_RANGE_TYPES = 3004,
VKD3D_SHADER_ERROR_PP_INVALID_SYNTAX = 4000,
+
+ VKD3D_SHADER_WARNING_PP_INVALID_DIRECTIVE = 5001,
+ VKD3D_SHADER_WARNING_PP_UNKNOWN_DIRECTIVE = 5003,
+ VKD3D_SHADER_WARNING_PP_UNTERMINATED_IF = 5005,
};
enum VKD3D_SHADER_INSTRUCTION_HANDLER
@@ -867,6 +871,8 @@ void vkd3d_shader_error(struct vkd3d_shader_message_context *context, enum vkd3d
const char *format, ...) VKD3D_PRINTF_FUNC(3, 4) DECLSPEC_HIDDEN;
void vkd3d_shader_verror(struct vkd3d_shader_message_context *context,
enum vkd3d_shader_error error, const char *format, va_list args) DECLSPEC_HIDDEN;
+void vkd3d_shader_vwarning(struct vkd3d_shader_message_context *context,
+ enum vkd3d_shader_error error, const char *format, va_list args) DECLSPEC_HIDDEN;
int shader_extract_from_dxbc(const void *dxbc, size_t dxbc_length,
struct vkd3d_shader_message_context *message_context, struct vkd3d_shader_desc *desc) DECLSPEC_HIDDEN;
diff --git a/tests/hlsl_d3d12.c b/tests/hlsl_d3d12.c
index 61324fa9..77a7ea1a 100644
--- a/tests/hlsl_d3d12.c
+++ b/tests/hlsl_d3d12.c
@@ -414,7 +414,7 @@ static void test_preprocess(void)
hr = D3DPreprocess(test_include_top, strlen(test_include_top), NULL, NULL, &test_include_fail, &blob, &errors);
todo ok(hr == E_FAIL, "Got hr %#x.\n", hr);
todo ok(blob == (ID3D10Blob *)0xdeadbeef, "Expected no compiled shader blob.\n");
- todo ok(!!errors, "Expected non-NULL error blob.\n");
+ ok(!!errors, "Expected non-NULL error blob.\n");
if (errors)
{
if (vkd3d_test_state.debug_level)
--
2.29.2
Dec. 3, 2020
[PATCH vkd3d 4/5] vkd3d-shader: Handle preprocessor parsing errors.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
libs/vkd3d-shader/preproc.h | 11 +++++++
libs/vkd3d-shader/preproc.l | 39 +++++++++++++++++++++++-
libs/vkd3d-shader/preproc.y | 39 +++++++++++++++++++++++-
libs/vkd3d-shader/vkd3d_shader_private.h | 2 ++
4 files changed, 89 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/preproc.h b/libs/vkd3d-shader/preproc.h
index cbd93229..769b8c23 100644
--- a/libs/vkd3d-shader/preproc.h
+++ b/libs/vkd3d-shader/preproc.h
@@ -23,11 +23,22 @@
#include "vkd3d_shader_private.h"
+struct preproc_location
+{
+ const char *filename;
+ unsigned int first_line, first_column;
+};
+
struct preproc_ctx
{
void *scanner;
+ struct vkd3d_shader_message_context *message_context;
struct vkd3d_string_buffer buffer;
+ unsigned int line, column;
+ const char *source_name;
+
+ bool error;
};
#endif
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l
index f931292b..c0c6b13a 100644
--- a/libs/vkd3d-shader/preproc.l
+++ b/libs/vkd3d-shader/preproc.l
@@ -27,6 +27,10 @@
#define YY_DECL static int preproc_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner)
+static void update_location(struct preproc_ctx *ctx);
+
+#define YY_USER_ACTION update_location(yyget_extra(yyscanner));
+
%}
%option 8bit
@@ -88,6 +92,28 @@ IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
%%
+static void update_location(struct preproc_ctx *ctx)
+{
+ unsigned int i, leng = yyget_leng(ctx->scanner);
+ const char *text = yyget_text(ctx->scanner);
+
+ /* We want to do this here, rather than before calling yylex(), because
+ * some tokens are skipped by the lexer. */
+
+ yyget_lloc(ctx->scanner)->first_line = ctx->line;
+ yyget_lloc(ctx->scanner)->first_column = ctx->column;
+
+ for (i = 0; i < leng; ++i)
+ {
+ ++ctx->column;
+ if (text[i] == '\n')
+ {
+ ctx->column = 1;
+ ++ctx->line;
+ }
+ }
+}
+
int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
{
struct preproc_ctx *ctx = yyget_extra(scanner);
@@ -101,7 +127,7 @@ int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
return PREPROC_YYEOF;
text = yyget_text(scanner);
- TRACE("Parsing token %d, string %s.\n", token, debugstr_a(text));
+ TRACE("Parsing token %d, line %d, string %s.\n", token, lloc->first_line, debugstr_a(text));
vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text);
}
@@ -115,6 +141,10 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
void *output_code;
vkd3d_string_buffer_init(&ctx.buffer);
+ ctx.message_context = message_context;
+ ctx.source_name = compile_info->source_name ? compile_info->source_name : "<anonymous>";
+ ctx.line = 1;
+ ctx.column = 1;
yylex_init_extra(&ctx, &ctx.scanner);
top_buffer = yy_scan_bytes(compile_info->source.code, compile_info->source.size, ctx.scanner);
@@ -124,6 +154,13 @@ int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
yy_delete_buffer(top_buffer, ctx.scanner);
yylex_destroy(ctx.scanner);
+ if (ctx.error)
+ {
+ WARN("Failed to preprocess.\n");
+ vkd3d_string_buffer_cleanup(&ctx.buffer);
+ return VKD3D_ERROR_INVALID_SHADER;
+ }
+
if (!(output_code = vkd3d_malloc(ctx.buffer.content_size)))
{
vkd3d_string_buffer_cleanup(&ctx.buffer);
diff --git a/libs/vkd3d-shader/preproc.y b/libs/vkd3d-shader/preproc.y
index 92448f24..88b855c6 100644
--- a/libs/vkd3d-shader/preproc.y
+++ b/libs/vkd3d-shader/preproc.y
@@ -36,13 +36,50 @@ int preproc_yylex(PREPROC_YYSTYPE *yylval_param, PREPROC_YYLTYPE *yylloc_param,
%code
{
+#define YYLLOC_DEFAULT(cur, rhs, n) \
+ do \
+ { \
+ if (n) \
+ { \
+ (cur).filename = YYRHSLOC(rhs, 1).filename; \
+ (cur).first_line = YYRHSLOC(rhs, 1).first_line; \
+ (cur).first_column = YYRHSLOC(rhs, 1).first_column; \
+ } \
+ else \
+ { \
+ (cur).filename = YYRHSLOC(rhs, 0).filename; \
+ (cur).first_line = YYRHSLOC(rhs, 0).first_line; \
+ (cur).first_column = YYRHSLOC(rhs, 0).first_column; \
+ } \
+ } while (0)
+
+static void set_location(struct preproc_ctx *ctx, const struct preproc_location *loc)
+{
+ ctx->message_context->source_name = loc->filename;
+ ctx->message_context->line = loc->first_line;
+ ctx->message_context->column = loc->first_column;
+}
+
+static void preproc_error(struct preproc_ctx *ctx, const struct preproc_location *loc,
+ enum vkd3d_shader_error error, const char *format, ...)
+{
+ va_list args;
+
+ set_location(ctx, loc);
+ va_start(args, format);
+ vkd3d_shader_verror(ctx->message_context, error, format, args);
+ va_end(args);
+ ctx->error = true;
+}
+
static void yyerror(const YYLTYPE *loc, void *scanner, struct preproc_ctx *ctx, const char *string)
{
- FIXME("Error reporting is not implemented.\n");
+ preproc_error(ctx, loc, VKD3D_SHADER_ERROR_PP_INVALID_SYNTAX, "%s", string);
}
}
+%define api.location.type {struct preproc_location}
%define api.prefix {preproc_yy}
%define api.pure full
%define parse.error verbose
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 83038384..5a022708 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -79,6 +79,8 @@ enum vkd3d_shader_error
VKD3D_SHADER_ERROR_RS_INVALID_ROOT_PARAMETER_TYPE = 3002,
VKD3D_SHADER_ERROR_RS_INVALID_DESCRIPTOR_RANGE_TYPE = 3003,
VKD3D_SHADER_ERROR_RS_MIXED_DESCRIPTOR_RANGE_TYPES = 3004,
+
+ VKD3D_SHADER_ERROR_PP_INVALID_SYNTAX = 4000,
};
enum VKD3D_SHADER_INSTRUCTION_HANDLER
--
2.29.2
Dec. 3, 2020
[PATCH vkd3d 3/5] vkd3d-shader: Preserve some tokens verbatim for HLSL.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
libs/vkd3d-shader/preproc.l | 22 ++++++++++++++++++++++
tests/hlsl_d3d12.c | 15 +++++++++------
2 files changed, 31 insertions(+), 6 deletions(-)
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l
index 966c11b0..f931292b 100644
--- a/libs/vkd3d-shader/preproc.l
+++ b/libs/vkd3d-shader/preproc.l
@@ -47,6 +47,7 @@
%s CXX_COMMENT
WS [ \t]
+IDENTIFIER [A-Za-z_][A-Za-z0-9_]*
%%
@@ -61,6 +62,27 @@ WS [ \t]
<C_COMMENT,CXX_COMMENT><<EOF>> {yy_pop_state(yyscanner);}
<C_COMMENT,CXX_COMMENT>. {}
+<INITIAL>{IDENTIFIER} {return T_TEXT;}
+
+<INITIAL>[0-9]*\.[0-9]+([eE][+-]?[0-9]+)?[hHfF]? {return T_TEXT;}
+<INITIAL>[0-9]+\.([eE][+-]?[0-9]+)?[hHfF]? {return T_TEXT;}
+<INITIAL>[0-9]+([eE][+-]?[0-9]+)?[hHfF] {return T_TEXT;}
+<INITIAL>[0-9]+[eE][+-]?[0-9]+ {return T_TEXT;}
+<INITIAL>0[xX][0-9a-fA-f]+[ul]{0,2} {return T_TEXT;}
+<INITIAL>0[0-7]*[ul]{0,2} {return T_TEXT;}
+<INITIAL>[1-9][0-9]*[ul]{0,2} {return T_TEXT;}
+
+<INITIAL>"&&" {return T_TEXT;}
+<INITIAL>"||" {return T_TEXT;}
+<INITIAL>"++" {return T_TEXT;}
+<INITIAL>"--" {return T_TEXT;}
+<INITIAL>"<<"=? {return T_TEXT;}
+<INITIAL>">>"=? {return T_TEXT;}
+<INITIAL>[-+*/%&|^=><!]= {return T_TEXT;}
+
+ /* C strings (including escaped quotes). */
+<INITIAL>\"([^"\\]|\\.)*\" {return T_TEXT;}
+
<INITIAL>{WS}+ {}
<INITIAL>. {return T_TEXT;}
diff --git a/tests/hlsl_d3d12.c b/tests/hlsl_d3d12.c
index 787355ba..61324fa9 100644
--- a/tests/hlsl_d3d12.c
+++ b/tests/hlsl_d3d12.c
@@ -43,7 +43,7 @@ static void check_preprocess_(int line, const char *source, const D3D_SHADER_MAC
ok_(line)(vkd3d_memmem(code, size, present, strlen(present)),
"\"%s\" not found in preprocessed shader.\n", present);
if (absent)
- assert_that_(line)(!vkd3d_memmem(code, size, absent, strlen(absent)),
+ ok_(line)(!vkd3d_memmem(code, size, absent, strlen(absent)),
"\"%s\" found in preprocessed shader.\n", absent);
ID3D10Blob_Release(blob);
}
@@ -349,8 +349,10 @@ static void test_preprocess(void)
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
+ if (i == 43)
+ continue;
vkd3d_test_set_context("Source \"%s\"", tests[i].source);
- todo_if (i != 5 && i != 8 && i != 42)
+ todo_if (i <= 4 || (i >= 9 && i <= 14))
check_preprocess(tests[i].source, NULL, NULL, tests[i].present, tests[i].absent);
}
vkd3d_test_set_context(NULL);
@@ -361,10 +363,10 @@ static void test_preprocess(void)
macros[1].Definition = NULL;
todo check_preprocess("KEY", macros, NULL, "value", "KEY");
- todo check_preprocess("#undef KEY\nKEY", macros, NULL, "KEY", "value");
+ check_preprocess("#undef KEY\nKEY", macros, NULL, "KEY", "value");
macros[0].Name = NULL;
- todo check_preprocess("KEY", macros, NULL, "KEY", "value");
+ check_preprocess("KEY", macros, NULL, "KEY", "value");
macros[0].Name = "KEY";
macros[0].Definition = NULL;
@@ -376,7 +378,7 @@ static void test_preprocess(void)
macros[0].Name = "KEY(a)";
macros[0].Definition = "value";
- todo check_preprocess("KEY(a)", macros, NULL, "KEY", "value");
+ check_preprocess("KEY(a)", macros, NULL, "KEY", "value");
macros[0].Name = "KEY";
macros[0].Definition = "value1";
@@ -398,7 +400,8 @@ static void test_preprocess(void)
macros[1].Definition = "KEY2";
todo check_preprocess("KEY", macros, NULL, "value", NULL);
- todo check_preprocess(test_include_top, NULL, &test_include, "pass", "fail");
+ if (0)
+ todo check_preprocess(test_include_top, NULL, &test_include, "pass", "fail");
ok(!refcount_file1, "Got %d references to file1.\n", refcount_file1);
ok(!refcount_file2, "Got %d references to file1.\n", refcount_file2);
ok(!refcount_file3, "Got %d references to file1.\n", refcount_file3);
--
2.29.2
Dec. 3, 2020
[PATCH vkd3d 2/5] vkd3d-shader: Parse comments in the preprocessor.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
libs/vkd3d-shader/preproc.l | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l
index 1ae43a8d..966c11b0 100644
--- a/libs/vkd3d-shader/preproc.l
+++ b/libs/vkd3d-shader/preproc.l
@@ -36,16 +36,33 @@
%option never-interactive
%option noinput
%option nounput
+%option noyy_top_state
%option noyywrap
%option prefix="preproc_yy"
%option reentrant
+%option stack
+
+ /* Because these can both be terminated by EOF, we need states for them. */
+%s C_COMMENT
+%s CXX_COMMENT
WS [ \t]
%%
-{WS}+ {}
-. {return T_TEXT;}
+<INITIAL>"//" {yy_push_state(CXX_COMMENT, yyscanner);}
+<INITIAL>"/*" {yy_push_state(C_COMMENT, yyscanner);}
+<CXX_COMMENT>\\\r?\n {}
+<CXX_COMMENT>\n {
+ yy_pop_state(yyscanner);
+ return T_TEXT;
+ }
+<C_COMMENT>"*/" {yy_pop_state(yyscanner);}
+<C_COMMENT,CXX_COMMENT><<EOF>> {yy_pop_state(yyscanner);}
+<C_COMMENT,CXX_COMMENT>. {}
+
+<INITIAL>{WS}+ {}
+<INITIAL>. {return T_TEXT;}
%%
--
2.29.2
Dec. 3, 2020
[PATCH vkd3d 1/5] vkd3d-shader: Implement an initial pass-through HLSL preprocessor.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
.gitignore | 3 +
Makefile.am | 23 +++++-
configure.ac | 12 +++
libs/vkd3d-shader/preproc.h | 33 ++++++++
libs/vkd3d-shader/preproc.l | 99 ++++++++++++++++++++++++
libs/vkd3d-shader/preproc.y | 60 ++++++++++++++
libs/vkd3d-shader/vkd3d_shader_main.c | 16 +++-
libs/vkd3d-shader/vkd3d_shader_private.h | 8 ++
tests/hlsl_d3d12.c | 31 ++++----
9 files changed, 264 insertions(+), 21 deletions(-)
create mode 100644 libs/vkd3d-shader/preproc.h
create mode 100644 libs/vkd3d-shader/preproc.l
create mode 100644 libs/vkd3d-shader/preproc.y
diff --git a/.gitignore b/.gitignore
index 63a9ffc6..b6d29d19 100644
--- a/.gitignore
+++ b/.gitignore
@@ -19,7 +19,10 @@ vkd3d-*.tar.xz
*.log
*.o
*.pc
+*.tab.c
+*.tab.h
*.trs
+*.yy.c
*~
.deps
diff --git a/Makefile.am b/Makefile.am
index 5a6e4dc9..c1957450 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -108,6 +108,24 @@ libvkd3d_common_la_SOURCES = \
lib_LTLIBRARIES = libvkd3d-shader.la libvkd3d.la libvkd3d-utils.la
+VKD3D_V_FLEX = $(vkd3d_v_flex_(a)AM_V@)
+vkd3d_v_flex_ = $(vkd3d_v_flex_(a)AM_DEFAULT_V@)
+vkd3d_v_flex_0 = @echo " FLEX " $@;
+vkd3d_v_flex_1 =
+
+VKD3D_V_BISON = $(vkd3d_v_bison_(a)AM_V@)
+vkd3d_v_bison_ = $(vkd3d_v_bison_(a)AM_DEFAULT_V@)
+vkd3d_v_bison_0 = @echo " BISON " $@;
+vkd3d_v_bison_1 =
+
+CLEANFILES = libs/vkd3d-shader/preproc.yy.c
+libs/vkd3d-shader/preproc.yy.c: $(srcdir)/libs/vkd3d-shader/preproc.l
+ $(VKD3D_V_FLEX)$(FLEX) $(LFLAGS) -o $@ $<
+
+CLEANFILES += libs/vkd3d-shader/preproc.tab.c preproc.tab.h
+libs/vkd3d-shader/preproc.tab.c libs/vkd3d-shader/preproc.tab.h &: $(srcdir)/libs/vkd3d-shader/preproc.y
+ $(VKD3D_V_BISON)$(BISON) $(YFLAGS) -d -o $(srcdir)/libs/vkd3d-shader/preproc.tab.c $<
+
libvkd3d_shader_la_SOURCES = \
include/private/list.h \
include/private/rbtree.h \
@@ -117,6 +135,9 @@ libvkd3d_shader_la_SOURCES = \
include/vkd3d_shader.h \
libs/vkd3d-shader/checksum.c \
libs/vkd3d-shader/dxbc.c \
+ libs/vkd3d-shader/preproc.tab.c \
+ libs/vkd3d-shader/preproc.tab.h \
+ libs/vkd3d-shader/preproc.yy.c \
libs/vkd3d-shader/spirv.c \
libs/vkd3d-shader/trace.c \
libs/vkd3d-shader/vkd3d_shader.map \
@@ -173,7 +194,7 @@ EXTRA_DIST = ANNOUNCE LICENSE
pkgconfigdir = $(libdir)/pkgconfig
pkginclude_HEADERS = $(vkd3d_public_headers)
nodist_pkgconfig_DATA = libvkd3d.pc libvkd3d-shader.pc libvkd3d-utils.pc
-CLEANFILES = libvkd3d.pc libvkd3d-shader.pc libvkd3d-utils.pc
+CLEANFILES += libvkd3d.pc libvkd3d-shader.pc libvkd3d-utils.pc
EXTRA_DIST += \
libs/vkd3d/libvkd3d.pc.in \
libs/vkd3d-shader/libvkd3d-shader.pc.in \
diff --git a/configure.ac b/configure.ac
index 2f22b05f..e282b621 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,6 +30,18 @@ AC_PROG_MKDIR_P
VKD3D_PROG_WIDL(3, 20)
AS_IF([test "x$WIDL" = "xno"], [AC_MSG_WARN([widl is required to build header files.])])
+AC_CHECK_PROGS(FLEX,flex,none)
+if test "$FLEX" = "none"
+then
+ AC_MSG_ERROR([no suitable flex found. Please install the 'flex' package.])
+fi
+
+AC_CHECK_PROGS(BISON,bison,none)
+if test "$BISON" = "none"
+then
+ AC_MSG_ERROR([no suitable bison found. Please install the 'bison' package.])
+fi
+
DX_PS_FEATURE([OFF])
DX_INIT_DOXYGEN([vkd3d], [Doxyfile], [doc])
AC_CONFIG_FILES([Doxyfile])
diff --git a/libs/vkd3d-shader/preproc.h b/libs/vkd3d-shader/preproc.h
new file mode 100644
index 00000000..cbd93229
--- /dev/null
+++ b/libs/vkd3d-shader/preproc.h
@@ -0,0 +1,33 @@
+/*
+ * HLSL preprocessor
+ *
+ * Copyright 2020 Zebediah Figura for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#ifndef __VKD3D_SHADER_PREPROC_H
+#define __VKD3D_SHADER_PREPROC_H
+
+#include "vkd3d_shader_private.h"
+
+struct preproc_ctx
+{
+ void *scanner;
+
+ struct vkd3d_string_buffer buffer;
+};
+
+#endif
diff --git a/libs/vkd3d-shader/preproc.l b/libs/vkd3d-shader/preproc.l
new file mode 100644
index 00000000..1ae43a8d
--- /dev/null
+++ b/libs/vkd3d-shader/preproc.l
@@ -0,0 +1,99 @@
+/*
+ * HLSL preprocessor
+ *
+ * Copyright 2020 Zebediah Figura for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+%{
+
+#include "preproc.tab.h"
+
+#define YYSTYPE PREPROC_YYSTYPE
+#define YYLTYPE PREPROC_YYLTYPE
+
+#define YY_DECL static int preproc_lexer_lex(YYSTYPE *yylval_param, YYLTYPE *yylloc_param, yyscan_t yyscanner)
+
+%}
+
+%option 8bit
+%option bison-bridge
+%option bison-locations
+%option extra-type="struct preproc_ctx *"
+%option never-interactive
+%option noinput
+%option nounput
+%option noyywrap
+%option prefix="preproc_yy"
+%option reentrant
+
+WS [ \t]
+
+%%
+
+{WS}+ {}
+. {return T_TEXT;}
+
+%%
+
+int yylex(YYSTYPE *lval, YYLTYPE *lloc, yyscan_t scanner)
+{
+ struct preproc_ctx *ctx = yyget_extra(scanner);
+
+ for (;;)
+ {
+ const char *text;
+ int token;
+
+ if (!(token = preproc_lexer_lex(lval, lloc, scanner)))
+ return PREPROC_YYEOF;
+ text = yyget_text(scanner);
+
+ TRACE("Parsing token %d, string %s.\n", token, debugstr_a(text));
+
+ vkd3d_string_buffer_printf(&ctx->buffer, "%s ", text);
+ }
+}
+
+int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context)
+{
+ struct preproc_ctx ctx = {0};
+ YY_BUFFER_STATE top_buffer;
+ void *output_code;
+
+ vkd3d_string_buffer_init(&ctx.buffer);
+
+ yylex_init_extra(&ctx, &ctx.scanner);
+ top_buffer = yy_scan_bytes(compile_info->source.code, compile_info->source.size, ctx.scanner);
+
+ preproc_yyparse(ctx.scanner, &ctx);
+
+ yy_delete_buffer(top_buffer, ctx.scanner);
+ yylex_destroy(ctx.scanner);
+
+ if (!(output_code = vkd3d_malloc(ctx.buffer.content_size)))
+ {
+ vkd3d_string_buffer_cleanup(&ctx.buffer);
+ return VKD3D_ERROR_OUT_OF_MEMORY;
+ }
+ memcpy(output_code, ctx.buffer.buffer, ctx.buffer.content_size);
+ out->size = ctx.buffer.content_size;
+ out->code = output_code;
+ vkd3d_string_buffer_trace(&ctx.buffer);
+ vkd3d_string_buffer_cleanup(&ctx.buffer);
+ return VKD3D_OK;
+}
diff --git a/libs/vkd3d-shader/preproc.y b/libs/vkd3d-shader/preproc.y
new file mode 100644
index 00000000..92448f24
--- /dev/null
+++ b/libs/vkd3d-shader/preproc.y
@@ -0,0 +1,60 @@
+/*
+ * HLSL preprocessor
+ *
+ * Copyright 2020 Zebediah Figura for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+%code requires
+{
+
+#include "vkd3d_shader_private.h"
+#include "preproc.h"
+
+}
+
+%code provides
+{
+
+int preproc_yylex(PREPROC_YYSTYPE *yylval_param, PREPROC_YYLTYPE *yylloc_param, void *scanner);
+
+}
+
+%code
+{
+
+static void yyerror(const YYLTYPE *loc, void *scanner, struct preproc_ctx *ctx, const char *string)
+{
+ FIXME("Error reporting is not implemented.\n");
+}
+
+}
+
+%define api.prefix {preproc_yy}
+%define api.pure full
+%define parse.error verbose
+%expect 0
+%locations
+%lex-param {yyscan_t scanner}
+%parse-param {void *scanner}
+%parse-param {struct preproc_ctx *ctx}
+
+%token T_TEXT
+
+%%
+
+shader_text
+ : %empty
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index 1a029246..eed0316c 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -78,8 +78,7 @@ int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *
}
}
-static int VKD3D_PRINTF_FUNC(2, 3) vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer,
- const char *format, ...)
+int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer, const char *format, ...)
{
va_list args;
int ret;
@@ -91,7 +90,7 @@ static int VKD3D_PRINTF_FUNC(2, 3) vkd3d_string_buffer_printf(struct vkd3d_strin
return ret;
}
-static void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function)
+void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function)
{
const char *p, *q, *end = buffer->buffer + buffer->content_size;
@@ -1154,6 +1153,7 @@ const enum vkd3d_shader_target_type *vkd3d_shader_get_supported_target_types(
int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info,
struct vkd3d_shader_code *out, char **messages)
{
+ struct vkd3d_shader_message_context message_context;
int ret;
TRACE("compile_info %p, out %p, messages %p.\n", compile_info, out, messages);
@@ -1164,5 +1164,13 @@ int vkd3d_shader_preprocess(const struct vkd3d_shader_compile_info *compile_info
if ((ret = vkd3d_shader_validate_compile_info(compile_info, false)) < 0)
return ret;
- return VKD3D_ERROR_NOT_IMPLEMENTED;
+ vkd3d_shader_message_context_init(&message_context, compile_info->log_level, compile_info->source_name);
+
+ ret = preproc_lexer_parse(compile_info, out, &message_context);
+
+ vkd3d_shader_message_context_trace_messages(&message_context);
+ if (!vkd3d_shader_message_context_copy_messages(&message_context, messages))
+ ret = VKD3D_ERROR_OUT_OF_MEMORY;
+ vkd3d_shader_message_context_cleanup(&message_context);
+ return ret;
}
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index 5ae5724a..83038384 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -837,6 +837,11 @@ struct vkd3d_string_buffer
enum vkd3d_result vkd3d_dxbc_binary_to_text(void *data, struct vkd3d_shader_code *out) DECLSPEC_HIDDEN;
void vkd3d_string_buffer_cleanup(struct vkd3d_string_buffer *buffer) DECLSPEC_HIDDEN;
void vkd3d_string_buffer_init(struct vkd3d_string_buffer *buffer) DECLSPEC_HIDDEN;
+int vkd3d_string_buffer_printf(struct vkd3d_string_buffer *buffer,
+ const char *format, ...) VKD3D_PRINTF_FUNC(2, 3) DECLSPEC_HIDDEN;
+#define vkd3d_string_buffer_trace(buffer) \
+ vkd3d_string_buffer_trace_(buffer, __FUNCTION__)
+void vkd3d_string_buffer_trace_(const struct vkd3d_string_buffer *buffer, const char *function) DECLSPEC_HIDDEN;
int vkd3d_string_buffer_vprintf(struct vkd3d_string_buffer *buffer, const char *format, va_list args) DECLSPEC_HIDDEN;
struct vkd3d_shader_message_context
@@ -882,6 +887,9 @@ void vkd3d_dxbc_compiler_destroy(struct vkd3d_dxbc_compiler *compiler) DECLSPEC_
void vkd3d_compute_dxbc_checksum(const void *dxbc, size_t size, uint32_t checksum[4]) DECLSPEC_HIDDEN;
+int preproc_lexer_parse(const struct vkd3d_shader_compile_info *compile_info,
+ struct vkd3d_shader_code *out, struct vkd3d_shader_message_context *message_context) DECLSPEC_HIDDEN;
+
static inline enum vkd3d_shader_component_type vkd3d_component_type_from_data_type(
enum vkd3d_data_type data_type)
{
diff --git a/tests/hlsl_d3d12.c b/tests/hlsl_d3d12.c
index 4f4cc37f..787355ba 100644
--- a/tests/hlsl_d3d12.c
+++ b/tests/hlsl_d3d12.c
@@ -30,22 +30,20 @@ static void check_preprocess_(int line, const char *source, const D3D_SHADER_MAC
HRESULT hr;
hr = D3DPreprocess(source, strlen(source), NULL, macros, include, &blob, &errors);
- todo ok_(line)(hr == S_OK, "Failed to preprocess shader, hr %#x.\n", hr);
+ assert_that_(line)(hr == S_OK, "Failed to preprocess shader, hr %#x.\n", hr);
if (errors)
{
if (vkd3d_test_state.debug_level)
trace_(line)("%s\n", (char *)ID3D10Blob_GetBufferPointer(errors));
ID3D10Blob_Release(errors);
}
- if (hr != S_OK)
- return;
code = ID3D10Blob_GetBufferPointer(blob);
size = ID3D10Blob_GetBufferSize(blob);
if (present)
ok_(line)(vkd3d_memmem(code, size, present, strlen(present)),
"\"%s\" not found in preprocessed shader.\n", present);
if (absent)
- ok_(line)(!vkd3d_memmem(code, size, absent, strlen(absent)),
+ assert_that_(line)(!vkd3d_memmem(code, size, absent, strlen(absent)),
"\"%s\" found in preprocessed shader.\n", absent);
ID3D10Blob_Release(blob);
}
@@ -352,7 +350,8 @@ static void test_preprocess(void)
for (i = 0; i < ARRAY_SIZE(tests); ++i)
{
vkd3d_test_set_context("Source \"%s\"", tests[i].source);
- check_preprocess(tests[i].source, NULL, NULL, tests[i].present, tests[i].absent);
+ todo_if (i != 5 && i != 8 && i != 42)
+ check_preprocess(tests[i].source, NULL, NULL, tests[i].present, tests[i].absent);
}
vkd3d_test_set_context(NULL);
@@ -360,16 +359,16 @@ static void test_preprocess(void)
macros[0].Definition = "value";
macros[1].Name = NULL;
macros[1].Definition = NULL;
- check_preprocess("KEY", macros, NULL, "value", "KEY");
+ todo check_preprocess("KEY", macros, NULL, "value", "KEY");
- check_preprocess("#undef KEY\nKEY", macros, NULL, "KEY", "value");
+ todo check_preprocess("#undef KEY\nKEY", macros, NULL, "KEY", "value");
macros[0].Name = NULL;
- check_preprocess("KEY", macros, NULL, "KEY", "value");
+ todo check_preprocess("KEY", macros, NULL, "KEY", "value");
macros[0].Name = "KEY";
macros[0].Definition = NULL;
- check_preprocess("KEY", macros, NULL, NULL, "KEY");
+ todo check_preprocess("KEY", macros, NULL, NULL, "KEY");
macros[0].Name = "0";
macros[0].Definition = "value";
@@ -377,7 +376,7 @@ static void test_preprocess(void)
macros[0].Name = "KEY(a)";
macros[0].Definition = "value";
- check_preprocess("KEY(a)", macros, NULL, "KEY", "value");
+ todo check_preprocess("KEY(a)", macros, NULL, "KEY", "value");
macros[0].Name = "KEY";
macros[0].Definition = "value1";
@@ -385,33 +384,33 @@ static void test_preprocess(void)
macros[1].Definition = "value2";
macros[2].Name = NULL;
macros[2].Definition = NULL;
- check_preprocess("KEY", macros, NULL, "value2", NULL);
+ todo check_preprocess("KEY", macros, NULL, "value2", NULL);
macros[0].Name = "KEY";
macros[0].Definition = "KEY2";
macros[1].Name = "KEY2";
macros[1].Definition = "value";
- check_preprocess("KEY", macros, NULL, "value", NULL);
+ todo check_preprocess("KEY", macros, NULL, "value", NULL);
macros[0].Name = "KEY2";
macros[0].Definition = "value";
macros[1].Name = "KEY";
macros[1].Definition = "KEY2";
- check_preprocess("KEY", macros, NULL, "value", NULL);
+ todo check_preprocess("KEY", macros, NULL, "value", NULL);
- check_preprocess(test_include_top, NULL, &test_include, "pass", "fail");
+ todo check_preprocess(test_include_top, NULL, &test_include, "pass", "fail");
ok(!refcount_file1, "Got %d references to file1.\n", refcount_file1);
ok(!refcount_file2, "Got %d references to file1.\n", refcount_file2);
ok(!refcount_file3, "Got %d references to file1.\n", refcount_file3);
todo ok(include_count_file2 == 2, "file2 was included %u times.\n", include_count_file2);
/* Macro invocation spread across multiple files. */
- check_preprocess(test_include2_top, NULL, &test_include, "pass", NULL);
+ todo check_preprocess(test_include2_top, NULL, &test_include, "pass", NULL);
blob = errors = (ID3D10Blob *)0xdeadbeef;
hr = D3DPreprocess(test_include_top, strlen(test_include_top), NULL, NULL, &test_include_fail, &blob, &errors);
todo ok(hr == E_FAIL, "Got hr %#x.\n", hr);
- ok(blob == (ID3D10Blob *)0xdeadbeef, "Expected no compiled shader blob.\n");
+ todo ok(blob == (ID3D10Blob *)0xdeadbeef, "Expected no compiled shader blob.\n");
todo ok(!!errors, "Expected non-NULL error blob.\n");
if (errors)
{
--
2.29.2
Dec. 3, 2020
[PATCH] localspl: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/localspl/localmon.c | 90 +++++--------------
dlls/localspl/provider.c | 183 ++++++++++++++-------------------------
2 files changed, 89 insertions(+), 184 deletions(-)
diff --git a/dlls/localspl/localmon.c b/dlls/localspl/localmon.c
index e634a332536..19a74566503 100644
--- a/dlls/localspl/localmon.c
+++ b/dlls/localspl/localmon.c
@@ -78,52 +78,8 @@ typedef struct {
static struct list port_handles = LIST_INIT( port_handles );
static struct list xcv_handles = LIST_INIT( xcv_handles );
-/* ############################### */
-
-static const WCHAR cmd_AddPortW[] = {'A','d','d','P','o','r','t',0};
-static const WCHAR cmd_DeletePortW[] = {'D','e','l','e','t','e','P','o','r','t',0};
-static const WCHAR cmd_ConfigureLPTPortCommandOKW[] = {'C','o','n','f','i','g','u','r','e',
- 'L','P','T','P','o','r','t',
- 'C','o','m','m','a','n','d','O','K',0};
-
-static const WCHAR cmd_GetDefaultCommConfigW[] = {'G','e','t',
- 'D','e','f','a','u','l','t',
- 'C','o','m','m','C','o','n','f','i','g',0};
-
-static const WCHAR cmd_GetTransmissionRetryTimeoutW[] = {'G','e','t',
- 'T','r','a','n','s','m','i','s','s','i','o','n',
- 'R','e','t','r','y','T','i','m','e','o','u','t',0};
-
-static const WCHAR cmd_MonitorUIW[] = {'M','o','n','i','t','o','r','U','I',0};
-static const WCHAR cmd_PortIsValidW[] = {'P','o','r','t','I','s','V','a','l','i','d',0};
-static const WCHAR cmd_SetDefaultCommConfigW[] = {'S','e','t',
- 'D','e','f','a','u','l','t',
- 'C','o','m','m','C','o','n','f','i','g',0};
-
-static const WCHAR dllnameuiW[] = {'l','o','c','a','l','u','i','.','d','l','l',0};
-static const WCHAR emptyW[] = {0};
-static const WCHAR LocalPortW[] = {'L','o','c','a','l',' ','P','o','r','t',0};
-
-static const WCHAR portname_LPT[] = {'L','P','T',0};
-static const WCHAR portname_COM[] = {'C','O','M',0};
-static const WCHAR portname_FILE[] = {'F','I','L','E',':',0};
-static const WCHAR portname_CUPS[] = {'C','U','P','S',':',0};
-static const WCHAR portname_LPR[] = {'L','P','R',':',0};
-
-static const WCHAR TransmissionRetryTimeoutW[] = {'T','r','a','n','s','m','i','s','s','i','o','n',
- 'R','e','t','r','y','T','i','m','e','o','u','t',0};
-
-static const WCHAR WinNT_CV_PortsW[] = {'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s',' ','N','T','\\',
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'P','o','r','t','s',0};
-
-static const WCHAR WinNT_CV_WindowsW[] = {'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s',' ','N','T','\\',
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'W','i','n','d','o','w','s',0};
+static const WCHAR WinNT_CV_PortsW[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Ports";
+static const WCHAR WinNT_CV_WindowsW[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows";
/******************************************************************
@@ -279,13 +235,13 @@ static DWORD get_type_from_name(LPCWSTR name)
{
HANDLE hfile;
- if (!wcsncmp(name, portname_LPT, ARRAY_SIZE(portname_LPT) - 1))
+ if (!wcsncmp(name, L"LPT", ARRAY_SIZE(L"LPT") - 1))
return PORT_IS_LPT;
- if (!wcsncmp(name, portname_COM, ARRAY_SIZE(portname_COM) - 1))
+ if (!wcsncmp(name, L"COM", ARRAY_SIZE(L"COM") - 1))
return PORT_IS_COM;
- if (!lstrcmpW(name, portname_FILE))
+ if (!lstrcmpW(name, L"FILE:"))
return PORT_IS_FILE;
if (name[0] == '/')
@@ -294,10 +250,10 @@ static DWORD get_type_from_name(LPCWSTR name)
if (name[0] == '|')
return PORT_IS_PIPE;
- if (!wcsncmp(name, portname_CUPS, ARRAY_SIZE(portname_CUPS) - 1))
+ if (!wcsncmp(name, L"CUPS:", ARRAY_SIZE(L"CUPS:") - 1))
return PORT_IS_CUPS;
- if (!wcsncmp(name, portname_LPR, ARRAY_SIZE(portname_LPR) - 1))
+ if (!wcsncmp(name, L"LPR:", ARRAY_SIZE(L"LPR:") - 1))
return PORT_IS_LPR;
/* Must be a file or a directory. Does the file exist ? */
@@ -385,7 +341,7 @@ static BOOL WINAPI localmon_AddPortExW(LPWSTR pName, DWORD level, LPBYTE pBuffer
debugstr_w(pMonitorName), debugstr_w(pi ? pi->pName : NULL));
- if ((pMonitorName == NULL) || (lstrcmpiW(pMonitorName, LocalPortW) != 0 ) ||
+ if ((pMonitorName == NULL) || (lstrcmpiW(pMonitorName, L"Local Port") != 0 ) ||
(pi == NULL) || (pi->pName == NULL) || (pi->pName[0] == '\0') ) {
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
@@ -404,7 +360,7 @@ static BOOL WINAPI localmon_AddPortExW(LPWSTR pName, DWORD level, LPBYTE pBuffer
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- res = RegSetValueExW(hroot, pi->pName, 0, REG_SZ, (const BYTE *) emptyW, sizeof(emptyW));
+ res = RegSetValueExW(hroot, pi->pName, 0, REG_SZ, (const BYTE *) L"", sizeof(L""));
RegCloseKey(hroot);
}
if (res != ERROR_SUCCESS) SetLastError(ERROR_INVALID_PARAMETER);
@@ -605,7 +561,7 @@ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE
TRACE("(%p, %s, %p, %d, %p, %d, %p)\n", hXcv, debugstr_w(pszDataName),
pInputData, cbInputData, pOutputData, cbOutputData, pcbOutputNeeded);
- if (!lstrcmpW(pszDataName, cmd_AddPortW)) {
+ if (!lstrcmpW(pszDataName, L"AddPort")) {
TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData));
res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot);
if (res == ERROR_SUCCESS) {
@@ -614,7 +570,7 @@ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE
TRACE("=> %u\n", ERROR_ALREADY_EXISTS);
return ERROR_ALREADY_EXISTS;
}
- res = RegSetValueExW(hroot, (LPWSTR) pInputData, 0, REG_SZ, (const BYTE *) emptyW, sizeof(emptyW));
+ res = RegSetValueExW(hroot, (LPWSTR)pInputData, 0, REG_SZ, (const BYTE*)L"", sizeof(L""));
RegCloseKey(hroot);
}
TRACE("=> %u\n", res);
@@ -622,17 +578,17 @@ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE
}
- if (!lstrcmpW(pszDataName, cmd_ConfigureLPTPortCommandOKW)) {
+ if (!lstrcmpW(pszDataName, L"ConfigureLPTPortCommandOK")) {
TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData));
res = RegCreateKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_WindowsW, &hroot);
if (res == ERROR_SUCCESS) {
- res = RegSetValueExW(hroot, TransmissionRetryTimeoutW, 0, REG_SZ, pInputData, cbInputData);
+ res = RegSetValueExW(hroot, L"TransmissionRetryTimeout", 0, REG_SZ, pInputData, cbInputData);
RegCloseKey(hroot);
}
return res;
}
- if (!lstrcmpW(pszDataName, cmd_DeletePortW)) {
+ if (!lstrcmpW(pszDataName, L"DeletePort")) {
TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData));
res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_PortsW, &hroot);
if (res == ERROR_SUCCESS) {
@@ -644,7 +600,7 @@ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE
return ERROR_FILE_NOT_FOUND;
}
- if (!lstrcmpW(pszDataName, cmd_GetDefaultCommConfigW)) {
+ if (!lstrcmpW(pszDataName, L"GetDefaultCommConfig")) {
TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData));
*pcbOutputNeeded = cbOutputData;
res = GetDefaultCommConfigW((LPWSTR) pInputData, (LPCOMMCONFIG) pOutputData, pcbOutputNeeded);
@@ -652,7 +608,7 @@ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE
return res ? ERROR_SUCCESS : GetLastError();
}
- if (!lstrcmpW(pszDataName, cmd_GetTransmissionRetryTimeoutW)) {
+ if (!lstrcmpW(pszDataName, L"GetTransmissionRetryTimeout")) {
* pcbOutputNeeded = sizeof(DWORD);
if (cbOutputData >= sizeof(DWORD)) {
/* the w2k resource kit documented a default of 90, but that's wrong */
@@ -661,7 +617,7 @@ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE
res = RegOpenKeyW(HKEY_LOCAL_MACHINE, WinNT_CV_WindowsW, &hroot);
if (res == ERROR_SUCCESS) {
needed = sizeof(buffer) - sizeof(WCHAR);
- res = RegQueryValueExW(hroot, TransmissionRetryTimeoutW, NULL, NULL, (LPBYTE) buffer, &needed);
+ res = RegQueryValueExW(hroot, L"TransmissionRetryTimeout", NULL, NULL, (BYTE*)buffer, &needed);
if ((res == ERROR_SUCCESS) && (buffer[0])) {
*((LPDWORD) pOutputData) = wcstoul(buffer, NULL, 0);
}
@@ -673,16 +629,16 @@ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE
}
- if (!lstrcmpW(pszDataName, cmd_MonitorUIW)) {
- * pcbOutputNeeded = sizeof(dllnameuiW);
- if (cbOutputData >= sizeof(dllnameuiW)) {
- memcpy(pOutputData, dllnameuiW, sizeof(dllnameuiW));
+ if (!lstrcmpW(pszDataName, L"MonitorUI")) {
+ * pcbOutputNeeded = sizeof(L"localui.dll");
+ if (cbOutputData >= sizeof(L"localui.dll")) {
+ memcpy(pOutputData, L"localui.dll", sizeof(L"localui.dll"));
return ERROR_SUCCESS;
}
return ERROR_INSUFFICIENT_BUFFER;
}
- if (!lstrcmpW(pszDataName, cmd_PortIsValidW)) {
+ if (!lstrcmpW(pszDataName, L"PortIsValid")) {
TRACE("InputData (%d): %s\n", cbInputData, debugstr_w( (LPWSTR) pInputData));
res = get_type_from_name((LPCWSTR) pInputData);
TRACE("detected as %u\n", res);
@@ -694,7 +650,7 @@ static DWORD WINAPI localmon_XcvDataPort(HANDLE hXcv, LPCWSTR pszDataName, PBYTE
return GetLastError();
}
- if (!lstrcmpW(pszDataName, cmd_SetDefaultCommConfigW)) {
+ if (!lstrcmpW(pszDataName, L"SetDefaultCommConfig")) {
/* get the portname from the Handle */
ptr = wcschr(((xcv_t *)hXcv)->nameW, ' ');
if (ptr) {
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c
index 326313d8f0c..93a457ab0ba 100644
--- a/dlls/localspl/provider.c
+++ b/dlls/localspl/provider.c
@@ -101,78 +101,27 @@ static monitor_t * pm_localport;
static const PRINTPROVIDOR * pprovider = NULL;
-static const WCHAR backslashW[] = {'\\',0};
-static const WCHAR bs_ports_bsW[] = {'\\','P','o','r','t','s','\\',0};
-static const WCHAR configuration_fileW[] = {'C','o','n','f','i','g','u','r','a','t','i','o','n',' ','F','i','l','e',0};
-static const WCHAR datatypeW[] = {'D','a','t','a','t','y','p','e',0};
-static const WCHAR data_fileW[] = {'D','a','t','a',' ','F','i','l','e',0};
-static const WCHAR dependent_filesW[] = {'D','e','p','e','n','d','e','n','t',' ','F','i','l','e','s',0};
-static const WCHAR driverW[] = {'D','r','i','v','e','r',0};
-static const WCHAR emptyW[] = {0};
-static const WCHAR fmt_driversW[] = { 'S','y','s','t','e','m','\\',
- 'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
- 'c','o','n','t','r','o','l','\\',
- 'P','r','i','n','t','\\',
- 'E','n','v','i','r','o','n','m','e','n','t','s','\\',
- '%','s','\\','D','r','i','v','e','r','s','%','s',0 };
-static const WCHAR fmt_printprocessorsW[] = { 'S','y','s','t','e','m','\\',
- 'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
- 'C','o','n','t','r','o','l','\\',
- 'P','r','i','n','t','\\',
- 'E','n','v','i','r','o','n','m','e','n','t','s','\\','%','s','\\',
- 'P','r','i','n','t',' ','P','r','o','c','e','s','s','o','r','s',0 };
-static const WCHAR help_fileW[] = {'H','e','l','p',' ','F','i','l','e',0};
-static const WCHAR ia64_envnameW[] = {'W','i','n','d','o','w','s',' ','I','A','6','4',0};
-static const WCHAR ia64_subdirW[] = {'i','a','6','4',0};
-static const WCHAR localportW[] = {'L','o','c','a','l',' ','P','o','r','t',0};
-static const WCHAR monitorW[] = {'M','o','n','i','t','o','r',0};
-static const WCHAR monitorsW[] = {'S','y','s','t','e','m','\\',
- 'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
- 'C','o','n','t','r','o','l','\\',
- 'P','r','i','n','t','\\',
- 'M','o','n','i','t','o','r','s','\\',0};
-static const WCHAR monitorUIW[] = {'M','o','n','i','t','o','r','U','I',0};
-static const WCHAR previous_namesW[] = {'P','r','e','v','i','o','u','s',' ','N','a','m','e','s',0};
-static const WCHAR printersW[] = {'S','y','s','t','e','m','\\',
- 'C','u', 'r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
- 'C','o','n','t','r','o','l','\\',
- 'P','r','i','n','t','\\',
- 'P','r','i','n','t','e','r','s',0};
-static const WCHAR spoolW[] = {'\\','s','p','o','o','l',0};
-static const WCHAR driversW[] = {'\\','d','r','i','v','e','r','s','\\',0};
-static const WCHAR spoolprtprocsW[] = {'\\','s','p','o','o','l','\\','p','r','t','p','r','o','c','s','\\',0};
-static const WCHAR version0_regpathW[] = {'\\','V','e','r','s','i','o','n','-','0',0};
-static const WCHAR version0_subdirW[] = {'\\','0',0};
-static const WCHAR version3_regpathW[] = {'\\','V','e','r','s','i','o','n','-','3',0};
-static const WCHAR version3_subdirW[] = {'\\','3',0};
-static const WCHAR versionW[] = {'V','e','r','s','i','o','n',0};
-static const WCHAR win40_envnameW[] = {'W','i','n','d','o','w','s',' ','4','.','0',0};
-static const WCHAR win40_subdirW[] = {'w','i','n','4','0',0};
-static const WCHAR winnt_cv_portsW[] = {'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s',' ','N','T','\\',
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'P','o','r','t','s',0};
-static const WCHAR winprintW[] = {'w','i','n','p','r','i','n','t',0};
-static const WCHAR x64_envnameW[] = {'W','i','n','d','o','w','s',' ','x','6','4',0};
-static const WCHAR x64_subdirW[] = {'x','6','4',0};
-static const WCHAR x86_envnameW[] = {'W','i','n','d','o','w','s',' ','N','T',' ','x','8','6',0};
-static const WCHAR x86_subdirW[] = {'w','3','2','x','8','6',0};
-static const WCHAR XcvMonitorW[] = {',','X','c','v','M','o','n','i','t','o','r',' ',0};
-static const WCHAR XcvPortW[] = {',','X','c','v','P','o','r','t',' ',0};
-
-
-static const printenv_t env_ia64 = {ia64_envnameW, ia64_subdirW, 3,
- version3_regpathW, version3_subdirW};
-
-static const printenv_t env_x86 = {x86_envnameW, x86_subdirW, 3,
- version3_regpathW, version3_subdirW};
-
-static const printenv_t env_x64 = {x64_envnameW, x64_subdirW, 3,
- version3_regpathW, version3_subdirW};
-
-static const printenv_t env_win40 = {win40_envnameW, win40_subdirW, 0,
- version0_regpathW, version0_subdirW};
+static const WCHAR fmt_driversW[] =
+ L"System\\CurrentControlSet\\control\\Print\\Environments\\%s\\Drivers%s";
+static const WCHAR fmt_printprocessorsW[] =
+ L"System\\CurrentControlSet\\Control\\Print\\Environments\\%s\\Print Processors";
+static const WCHAR monitorsW[] = L"System\\CurrentControlSet\\Control\\Print\\Monitors\\";
+static const WCHAR printersW[] = L"System\\CurrentControlSet\\Control\\Print\\Printers";
+static const WCHAR winnt_cv_portsW[] = L"Software\\Microsoft\\Windows NT\\CurrentVersion\\Ports";
+static const WCHAR x86_envnameW[] = L"Windows NT x86";
+
+
+static const printenv_t env_ia64 = {L"Windows IA64", L"ia64", 3,
+ L"\\Version-3", L"\\3"};
+
+static const printenv_t env_x86 = {x86_envnameW, L"w32x86", 3,
+ L"\\Version-3", L"\\3"};
+
+static const printenv_t env_x64 = {L"Windows x64", L"x64", 3,
+ L"\\Version-3", L"\\3"};
+
+static const printenv_t env_win40 = {L"Windows 4.0", L"win40", 0,
+ L"\\Version-0", L"\\0"};
static const printenv_t * const all_printenv[] = {&env_x86, &env_x64, &env_ia64, &env_win40};
@@ -515,10 +464,10 @@ static monitor_t * monitor_load(LPCWSTR name, LPWSTR dllname)
/* Get the Driver from the Registry */
if (driver == NULL) {
DWORD namesize;
- if (RegQueryValueExW(hroot, driverW, NULL, NULL, NULL,
+ if (RegQueryValueExW(hroot, L"Driver", NULL, NULL, NULL,
&namesize) == ERROR_SUCCESS) {
driver = heap_alloc(namesize);
- RegQueryValueExW(hroot, driverW, NULL, NULL, (LPBYTE) driver, &namesize) ;
+ RegQueryValueExW(hroot, L"Driver", NULL, NULL, (BYTE*)driver, &namesize);
}
}
}
@@ -637,7 +586,7 @@ static monitor_t * monitor_load(LPCWSTR name, LPWSTR dllname)
}
}
cleanup:
- if ((pm_localport == NULL) && (pm != NULL) && (lstrcmpW(pm->name, localportW) == 0)) {
+ if ((pm_localport == NULL) && (pm != NULL) && (lstrcmpW(pm->name, L"Local Port") == 0)) {
pm->refcount++;
pm_localport = pm;
}
@@ -712,12 +661,12 @@ static monitor_t * monitor_loadui(monitor_t * pm)
/* query the userinterface-dllname from the Portmonitor */
/* building (",XcvMonitor %s",pm->name) not needed yet */
if (pm->monitor.pfnXcvOpenPort)
- res = pm->monitor.pfnXcvOpenPort(pm->hmon, emptyW, SERVER_ACCESS_ADMINISTER, &hXcv);
+ res = pm->monitor.pfnXcvOpenPort(pm->hmon, L"", SERVER_ACCESS_ADMINISTER, &hXcv);
else if (pm->old_XcvOpenPort)
- res = pm->old_XcvOpenPort(emptyW, SERVER_ACCESS_ADMINISTER, &hXcv);
+ res = pm->old_XcvOpenPort(L"", SERVER_ACCESS_ADMINISTER, &hXcv);
TRACE("got %u with %p\n", res, hXcv);
if (res) {
- res = pm->monitor.pfnXcvDataPort(hXcv, monitorUIW, NULL, 0, (BYTE *) buffer, sizeof(buffer), &len);
+ res = pm->monitor.pfnXcvDataPort(hXcv, L"MonitorUI", NULL, 0, (BYTE *) buffer, sizeof(buffer), &len);
TRACE("got %u with %s\n", res, debugstr_w(buffer));
if (res == ERROR_SUCCESS) pui = monitor_load(NULL, buffer);
pm->monitor.pfnXcvClosePort(hXcv);
@@ -750,12 +699,12 @@ static monitor_t * monitor_load_by_port(LPCWSTR portname)
if (RegQueryValueExW(hroot, portname, NULL, NULL, NULL, &len) == ERROR_SUCCESS) {
/* found the portname */
RegCloseKey(hroot);
- return monitor_load(localportW, NULL);
+ return monitor_load(L"Local Port", NULL);
}
RegCloseKey(hroot);
}
- len = MAX_PATH + lstrlenW(bs_ports_bsW) + lstrlenW(portname) + 1;
+ len = MAX_PATH + lstrlenW(L"\\Ports\\") + lstrlenW(portname) + 1;
buffer = heap_alloc(len * sizeof(WCHAR));
if (buffer == NULL) return NULL;
@@ -768,7 +717,7 @@ static monitor_t * monitor_load_by_port(LPCWSTR portname)
RegEnumKeyW(hroot, id, buffer, MAX_PATH);
TRACE("testing %s\n", debugstr_w(buffer));
len = lstrlenW(buffer);
- lstrcatW(buffer, bs_ports_bsW);
+ lstrcatW(buffer, L"\\Ports\\");
lstrcatW(buffer, portname);
if (RegOpenKeyW(hroot, buffer, &hport) == ERROR_SUCCESS) {
RegCloseKey(hport);
@@ -895,7 +844,7 @@ static DWORD get_local_monitors(DWORD level, LPBYTE pMonitors, DWORD cbBuf, LPDW
/* The Monitor must have a Driver-DLL */
if (RegOpenKeyExW(hroot, buffer, 0, KEY_READ, &hentry) == ERROR_SUCCESS) {
- if (RegQueryValueExW(hentry, driverW, NULL, NULL, (LPBYTE) dllname, &dllsize) == ERROR_SUCCESS) {
+ if (RegQueryValueExW(hentry, L"Driver", NULL, NULL, (BYTE*)dllname, &dllsize) == ERROR_SUCCESS) {
/* We found a valid DLL for this Monitor. */
TRACE("using Driver: %s\n", debugstr_w(dllname));
}
@@ -977,27 +926,27 @@ static DWORD get_local_printprocessors(LPWSTR regpathW, LPBYTE pPPInfo, DWORD cb
if (RegCreateKeyW(HKEY_LOCAL_MACHINE, regpathW, &hroot) == ERROR_SUCCESS) {
/* add "winprint" first */
numentries++;
- needed = sizeof(PRINTPROCESSOR_INFO_1W) + sizeof(winprintW);
+ needed = sizeof(PRINTPROCESSOR_INFO_1W) + sizeof(L"winprint");
if (pPPInfo && (cbBuf >= needed)){
ppi = (PPRINTPROCESSOR_INFO_1W) pPPInfo;
pPPInfo += sizeof(PRINTPROCESSOR_INFO_1W);
TRACE("%p: writing PRINTPROCESSOR_INFO_1W #%d\n", ppi, numentries);
ppi->pName = ptr;
- lstrcpyW(ptr, winprintW); /* Name of the Print Processor */
- ptr += ARRAY_SIZE(winprintW);
+ lstrcpyW(ptr, L"winprint"); /* Name of the Print Processor */
+ ptr += ARRAY_SIZE(L"winprint");
}
/* Scan all Printprocessor Keys */
while ((RegEnumKeyExW(hroot, index, buffer, &len, NULL, NULL, NULL, NULL) == ERROR_SUCCESS) &&
- (lstrcmpiW(buffer, winprintW) != 0)) {
+ (lstrcmpiW(buffer, L"winprint") != 0)) {
TRACE("PrintProcessor_%d: %s\n", numentries, debugstr_w(buffer));
dllsize = sizeof(dllname);
dllname[0] = '\0';
/* The Print Processor must have a Driver-DLL */
if (RegOpenKeyExW(hroot, buffer, 0, KEY_READ, &hentry) == ERROR_SUCCESS) {
- if (RegQueryValueExW(hentry, driverW, NULL, NULL, (LPBYTE) dllname, &dllsize) == ERROR_SUCCESS) {
+ if (RegQueryValueExW(hentry, L"Driver", NULL, NULL, (BYTE*)dllname, &dllsize) == ERROR_SUCCESS) {
/* We found a valid DLL for this Print Processor */
TRACE("using Driver: %s\n", debugstr_w(dllname));
}
@@ -1214,8 +1163,8 @@ static BOOL WINAPI fpGetPrinterDriverDirectory(LPWSTR pName, LPWSTR pEnvironment
/* GetSystemDirectoryW returns number of WCHAR including the '\0' */
needed = GetSystemDirectoryW(NULL, 0);
/* add the Size for the Subdirectories */
- needed += lstrlenW(spoolW);
- needed += lstrlenW(driversW);
+ needed += lstrlenW(L"\\spool");
+ needed += lstrlenW(L"\\drivers\\");
needed += lstrlenW(env->subdir);
needed *= sizeof(WCHAR); /* return-value is size in Bytes */
@@ -1234,9 +1183,9 @@ static BOOL WINAPI fpGetPrinterDriverDirectory(LPWSTR pName, LPWSTR pEnvironment
GetSystemDirectoryW( dir, cbBuf / sizeof(WCHAR) );
/* add the Subdirectories */
- lstrcatW( dir, spoolW );
+ lstrcatW( dir, L"\\spool" );
CreateDirectoryW( dir, NULL );
- lstrcatW( dir, driversW );
+ lstrcatW( dir, L"\\drivers\\" );
CreateDirectoryW( dir, NULL );
lstrcatW( dir, env->subdir );
CreateDirectoryW( dir, NULL );
@@ -1274,7 +1223,7 @@ static HMODULE driver_load(const printenv_t * env, LPWSTR dllname)
}
lstrcatW(fullname, env->versionsubdir);
- lstrcatW(fullname, backslashW);
+ lstrcatW(fullname, L"\\");
lstrcatW(fullname, dllname);
hui = LoadLibraryW(fullname);
@@ -1344,8 +1293,8 @@ static HANDLE printer_alloc_handle(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault)
printer = NULL;
}
if (printername) {
- len = ARRAY_SIZE(XcvMonitorW) - 1;
- if (wcsncmp(printername, XcvMonitorW, len) == 0) {
+ len = ARRAY_SIZE(L",XcvMonitor ") - 1;
+ if (wcsncmp(printername, L",XcvMonitor ", len) == 0) {
/* OpenPrinter(",XcvMonitor ", ...) detected */
TRACE(",XcvMonitor: %s\n", debugstr_w(&printername[len]));
printer->pm = monitor_load(&printername[len], NULL);
@@ -1358,8 +1307,8 @@ static HANDLE printer_alloc_handle(LPCWSTR name, LPPRINTER_DEFAULTSW pDefault)
}
else
{
- len = ARRAY_SIZE(XcvPortW) - 1;
- if (wcsncmp( printername, XcvPortW, len) == 0) {
+ len = ARRAY_SIZE(L",XcvPort ") - 1;
+ if (wcsncmp( printername, L",XcvPort ", len) == 0) {
/* OpenPrinter(",XcvPort ", ...) detected */
TRACE(",XcvPort: %s\n", debugstr_w(&printername[len]));
printer->pm = monitor_load_by_port(&printername[len]);
@@ -1475,17 +1424,17 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo
if (env == NULL) return FALSE; /* ERROR_INVALID_ENVIRONMENT */
/* fill the copy-data / get the driverdir */
- len = sizeof(apd.src) - sizeof(version3_subdirW) - sizeof(WCHAR);
+ len = sizeof(apd.src) - sizeof(L"\\3") - sizeof(WCHAR);
if (!fpGetPrinterDriverDirectory(NULL, (LPWSTR) env->envname, 1,
(LPBYTE) apd.src, len, &len)) {
/* Should never fail */
return FALSE;
}
memcpy(apd.dst, apd.src, len);
- lstrcatW(apd.src, backslashW);
+ lstrcatW(apd.src, L"\\");
apd.srclen = lstrlenW(apd.src);
lstrcatW(apd.dst, env->versionsubdir);
- lstrcatW(apd.dst, backslashW);
+ lstrcatW(apd.dst, L"\\");
apd.dstlen = lstrlenW(apd.dst);
apd.copyflags = dwFileCopyFlags;
apd.lazy = lazy;
@@ -1511,30 +1460,30 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo
RegCloseKey(hroot);
/* Verified with the Adobe PS Driver, that w2k does not use di.Version */
- RegSetValueExW(hdrv, versionW, 0, REG_DWORD, (const BYTE*) &env->driverversion,
+ RegSetValueExW(hdrv, L"Version", 0, REG_DWORD, (const BYTE*) &env->driverversion,
sizeof(DWORD));
file = get_file_part( di.pDriverPath );
- RegSetValueExW( hdrv, driverW, 0, REG_SZ, (LPBYTE)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
+ RegSetValueExW( hdrv, L"Driver", 0, REG_SZ, (BYTE*)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
apd_copyfile( di.pDriverPath, file, &apd );
file = get_file_part( di.pDataFile );
- RegSetValueExW( hdrv, data_fileW, 0, REG_SZ, (LPBYTE)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
+ RegSetValueExW( hdrv, L"Data File", 0, REG_SZ, (BYTE*)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
apd_copyfile( di.pDataFile, file, &apd );
file = get_file_part( di.pConfigFile );
- RegSetValueExW( hdrv, configuration_fileW, 0, REG_SZ, (LPBYTE)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
+ RegSetValueExW( hdrv, L"Configuration File", 0, REG_SZ, (BYTE*)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
apd_copyfile( di.pConfigFile, file, &apd );
/* settings for level 3 */
if (di.pHelpFile)
{
file = get_file_part( di.pHelpFile );
- RegSetValueExW( hdrv, help_fileW, 0, REG_SZ, (LPBYTE)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
+ RegSetValueExW( hdrv, L"Help File", 0, REG_SZ, (BYTE*)file, (lstrlenW( file ) + 1) * sizeof(WCHAR) );
apd_copyfile( di.pHelpFile, file, &apd );
}
else
- RegSetValueExW( hdrv, help_fileW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW) );
+ RegSetValueExW( hdrv, L"Help File", 0, REG_SZ, (const BYTE*)L"", sizeof(L"") );
if (di.pDependentFiles && *di.pDependentFiles)
{
@@ -1551,31 +1500,31 @@ static BOOL myAddPrinterDriverEx(DWORD level, LPBYTE pDriverInfo, DWORD dwFileCo
}
*reg_ptr = 0;
- RegSetValueExW( hdrv, dependent_filesW, 0, REG_MULTI_SZ, (LPBYTE)reg, (reg_ptr - reg + 1) * sizeof(WCHAR) );
+ RegSetValueExW( hdrv, L"Dependent Files", 0, REG_MULTI_SZ, (BYTE*)reg, (reg_ptr - reg + 1) * sizeof(WCHAR) );
HeapFree( GetProcessHeap(), 0, reg );
}
else
- RegSetValueExW(hdrv, dependent_filesW, 0, REG_MULTI_SZ, (const BYTE*)emptyW, sizeof(emptyW));
+ RegSetValueExW(hdrv, L"Dependent Files", 0, REG_MULTI_SZ, (const BYTE*)L"", sizeof(L""));
/* The language-Monitor was already copied by the caller to "%SystemRoot%\system32" */
if (di.pMonitorName)
- RegSetValueExW(hdrv, monitorW, 0, REG_SZ, (LPBYTE) di.pMonitorName,
+ RegSetValueExW(hdrv, L"Monitor", 0, REG_SZ, (BYTE*)di.pMonitorName,
(lstrlenW(di.pMonitorName)+1)* sizeof(WCHAR));
else
- RegSetValueExW(hdrv, monitorW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW));
+ RegSetValueExW(hdrv, L"Monitor", 0, REG_SZ, (const BYTE*)L"", sizeof(L""));
if (di.pDefaultDataType)
- RegSetValueExW(hdrv, datatypeW, 0, REG_SZ, (LPBYTE) di.pDefaultDataType,
+ RegSetValueExW(hdrv, L"Datatype", 0, REG_SZ, (BYTE*)di.pDefaultDataType,
(lstrlenW(di.pDefaultDataType)+1)* sizeof(WCHAR));
else
- RegSetValueExW(hdrv, datatypeW, 0, REG_SZ, (const BYTE*)emptyW, sizeof(emptyW));
+ RegSetValueExW(hdrv, L"Datatype", 0, REG_SZ, (const BYTE*)L"", sizeof(L""));
/* settings for level 4 */
if (di.pszzPreviousNames)
- RegSetValueExW(hdrv, previous_namesW, 0, REG_MULTI_SZ, (LPBYTE) di.pszzPreviousNames,
+ RegSetValueExW(hdrv, L"Previous Names", 0, REG_MULTI_SZ, (BYTE*)di.pszzPreviousNames,
multi_sz_lenW(di.pszzPreviousNames));
else
- RegSetValueExW(hdrv, previous_namesW, 0, REG_MULTI_SZ, (const BYTE*)emptyW, sizeof(emptyW));
+ RegSetValueExW(hdrv, L"Previous Names", 0, REG_MULTI_SZ, (const BYTE*)L"", sizeof(L""));
if (level > 5) TRACE("level %u for Driver %s is incomplete\n", level, debugstr_w(di.pName));
@@ -1669,7 +1618,7 @@ static BOOL WINAPI fpAddMonitor(LPWSTR pName, DWORD Level, LPBYTE pMonitors)
DWORD namesize = 0;
if ((disposition == REG_OPENED_EXISTING_KEY) &&
- (RegQueryValueExW(hentry, driverW, NULL, NULL, NULL,
+ (RegQueryValueExW(hentry, L"Driver", NULL, NULL, NULL,
&namesize) == ERROR_SUCCESS)) {
TRACE("monitor %s already exists\n", debugstr_w(mi2w->pName));
/* 9x use ERROR_ALREADY_EXISTS */
@@ -1679,7 +1628,7 @@ static BOOL WINAPI fpAddMonitor(LPWSTR pName, DWORD Level, LPBYTE pMonitors)
{
INT len;
len = (lstrlenW(mi2w->pDLLName) +1) * sizeof(WCHAR);
- res = (RegSetValueExW(hentry, driverW, 0, REG_SZ,
+ res = (RegSetValueExW(hentry, L"Driver", 0, REG_SZ,
(LPBYTE) mi2w->pDLLName, len) == ERROR_SUCCESS);
/* Load and initialize the monitor. SetLastError() is called on failure */
@@ -2437,7 +2386,7 @@ static BOOL WINAPI fpGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironmen
/* GetSystemDirectoryW returns number of WCHAR including the '\0' */
needed = GetSystemDirectoryW(NULL, 0);
/* add the Size for the Subdirectories */
- needed += lstrlenW(spoolprtprocsW);
+ needed += lstrlenW(L"\\spool\\prtprocs\\");
needed += lstrlenW(env->subdir);
needed *= sizeof(WCHAR); /* return-value is size in Bytes */
@@ -2450,7 +2399,7 @@ static BOOL WINAPI fpGetPrintProcessorDirectory(LPWSTR pName, LPWSTR pEnvironmen
GetSystemDirectoryW((LPWSTR) pPPInfo, cbBuf/sizeof(WCHAR));
/* add the Subdirectories */
- lstrcatW((LPWSTR) pPPInfo, spoolprtprocsW);
+ lstrcatW((LPWSTR) pPPInfo, L"\\spool\\prtprocs\\");
lstrcatW((LPWSTR) pPPInfo, env->subdir);
TRACE("==> %s\n", debugstr_w((LPWSTR) pPPInfo));
return TRUE;
--
2.26.2
Dec. 2, 2020
[PATCH] msi: Use a string literal for empty strings.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/msi/action.c | 6 +++---
dlls/msi/automation.c | 2 +-
dlls/msi/msi.c | 4 ++--
dlls/msi/source.c | 2 +-
4 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/msi/action.c b/dlls/msi/action.c
index ed1d0c8ffcc..cc5d56fdc2b 100644
--- a/dlls/msi/action.c
+++ b/dlls/msi/action.c
@@ -1269,7 +1269,7 @@ static UINT load_folder_persistence( MSIPACKAGE *package, MSIFOLDER *folder )
static UINT load_folder( MSIRECORD *row, LPVOID param )
{
MSIPACKAGE *package = param;
- static WCHAR szEmpty[] = {0};
+ static WCHAR szEmpty[] = L"";
LPWSTR p, tgt_short, tgt_long, src_short, src_long;
MSIFOLDER *folder;
@@ -5240,14 +5240,14 @@ static UINT ACTION_RegisterUser(MSIPACKAGE *package)
L"ProductID",
L"USERNAME",
L"COMPANYNAME",
- {0},
+ L"",
};
static const WCHAR szRegKeys[][80] =
{
L"ProductID",
L"RegOwner",
L"RegCompany",
- {0},
+ L"",
};
HKEY hkey = 0;
LPWSTR buffer, productid = NULL;
diff --git a/dlls/msi/automation.c b/dlls/msi/automation.c
index dc38436e682..80d6b8a66ba 100644
--- a/dlls/msi/automation.c
+++ b/dlls/msi/automation.c
@@ -781,7 +781,7 @@ static HRESULT summaryinfo_invoke(
DATE date;
LPWSTR str;
- static WCHAR szEmpty[] = {0};
+ static WCHAR szEmpty[] = L"";
hr = DispGetParam(pDispParams, 0, VT_I4, &varg0, puArgErr);
if (FAILED(hr)) return hr;
diff --git a/dlls/msi/msi.c b/dlls/msi/msi.c
index 0963c814211..c4c787da4e4 100644
--- a/dlls/msi/msi.c
+++ b/dlls/msi/msi.c
@@ -324,7 +324,7 @@ static UINT get_patch_product_codes( LPCWSTR szPatchPackage, WCHAR ***product_co
MSIHANDLE patch, info = 0;
UINT r, type;
DWORD size;
- static WCHAR empty[] = {0};
+ static WCHAR empty[] = L"";
WCHAR *codes = NULL;
r = MsiOpenDatabaseW( szPatchPackage, MSIDBOPEN_READONLY, &patch );
@@ -1096,7 +1096,7 @@ static WCHAR *reg_get_value( HKEY hkey, const WCHAR *name, DWORD *type )
static UINT MSI_GetProductInfo(LPCWSTR szProduct, LPCWSTR szAttribute,
awstring *szValue, LPDWORD pcchValueBuf)
{
- static WCHAR empty[] = {0};
+ static WCHAR empty[] = L"";
MSIINSTALLCONTEXT context = MSIINSTALLCONTEXT_USERUNMANAGED;
UINT r = ERROR_UNKNOWN_PROPERTY;
HKEY prodkey, userdata, source;
diff --git a/dlls/msi/source.c b/dlls/msi/source.c
index b4b3b54fe35..0eed436774a 100644
--- a/dlls/msi/source.c
+++ b/dlls/msi/source.c
@@ -585,7 +585,7 @@ UINT WINAPI MsiSourceListGetInfoW( LPCWSTR szProduct, LPCWSTR szUserSid,
0, 0, NULL, &size);
if (rc != ERROR_SUCCESS)
{
- static WCHAR szEmpty[] = {0};
+ static WCHAR szEmpty[] = L"";
rc = ERROR_SUCCESS;
source = NULL;
ptr = szEmpty;
--
2.26.2
Dec. 2, 2020
[PATCH] mapi32: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/mapi32/tests/prop.c | 10 +++++-----
dlls/mapi32/util.c | 20 ++++++--------------
2 files changed, 11 insertions(+), 19 deletions(-)
diff --git a/dlls/mapi32/tests/prop.c b/dlls/mapi32/tests/prop.c
index 5bbddb3809c..61ec5f16a9f 100644
--- a/dlls/mapi32/tests/prop.c
+++ b/dlls/mapi32/tests/prop.c
@@ -102,7 +102,7 @@ static ULONG ptTypes[] = {
static void test_PropCopyMore(void)
{
static char szHiA[] = "Hi!";
- static WCHAR szHiW[] = { 'H', 'i', '!', '\0' };
+ static WCHAR szHiW[] = L"Hi!";
SPropValue *lpDest = NULL, *lpSrc = NULL;
ULONG i;
SCODE scode;
@@ -182,7 +182,7 @@ static void test_PropCopyMore(void)
static void test_UlPropSize(void)
{
static char szHiA[] = "Hi!";
- static WCHAR szHiW[] = { 'H', 'i', '!', '\0' };
+ static WCHAR szHiW[] = L"Hi!";
LPSTR buffa[2];
LPWSTR buffw[2];
SBinary buffbin[2];
@@ -702,7 +702,7 @@ static void test_PpropFindProp(void)
static void test_ScCountProps(void)
{
static char szHiA[] = "Hi!";
- static WCHAR szHiW[] = { 'H', 'i', '!', '\0' };
+ static WCHAR szHiW[] = L"Hi!";
static const ULONG ULHILEN = 4; /* chars in szHiA/W incl. NUL */
LPSTR buffa[3];
LPWSTR buffw[3];
@@ -971,7 +971,7 @@ static void test_FBadRglpszA(void)
static void test_FBadRglpszW(void)
{
LPWSTR lpStrs[4];
- static WCHAR szString[] = { 'A',' ','S','t','r','i','n','g','\0' };
+ static WCHAR szString[] = L"A String";
BOOL bRet;
if (!pFBadRglpszW)
@@ -1063,7 +1063,7 @@ static void test_FBadRow(void)
static void test_FBadProp(void)
{
- static WCHAR szEmpty[] = { '\0' };
+ static WCHAR szEmpty[] = L"";
GUID iid;
ULONG pt, res;
SPropValue pv;
diff --git a/dlls/mapi32/util.c b/dlls/mapi32/util.c
index 7e324a0e650..8f0036e6873 100644
--- a/dlls/mapi32/util.c
+++ b/dlls/mapi32/util.c
@@ -966,8 +966,6 @@ static HMODULE mapi_ex_provider;
*/
static void load_mapi_provider(HKEY hkeyMail, LPCWSTR valueName, HMODULE *mapi_provider)
{
- static const WCHAR mapi32_dll[] = {'m','a','p','i','3','2','.','d','l','l',0 };
-
DWORD dwType, dwLen = 0;
LPWSTR dllPath;
@@ -982,7 +980,7 @@ static void load_mapi_provider(HKEY hkeyMail, LPCWSTR valueName, HMODULE *mapi_p
RegQueryValueExW(hkeyMail, valueName, NULL, NULL, (LPBYTE)dllPath, &dwLen);
/* Check that this value doesn't refer to mapi32.dll (eg, as Outlook does) */
- if (lstrcmpiW(dllPath, mapi32_dll) != 0)
+ if (lstrcmpiW(dllPath, L"mapi32.dll") != 0)
{
if (dwType == REG_EXPAND_SZ)
{
@@ -1022,13 +1020,7 @@ static void load_mapi_provider(HKEY hkeyMail, LPCWSTR valueName, HMODULE *mapi_p
*/
void load_mapi_providers(void)
{
- static const WCHAR regkey_mail[] = {
- 'S','o','f','t','w','a','r','e','\\','C','l','i','e','n','t','s','\\',
- 'M','a','i','l',0 };
-
- static const WCHAR regkey_dllpath[] = {'D','L','L','P','a','t','h',0 };
- static const WCHAR regkey_dllpath_ex[] = {'D','L','L','P','a','t','h','E','x',0 };
- static const WCHAR regkey_backslash[] = { '\\', 0 };
+ static const WCHAR regkey_mail[] = L"Software\\Clients\\Mail";
HKEY hkeyMail;
DWORD dwType, dwLen = 0;
@@ -1056,13 +1048,13 @@ void load_mapi_providers(void)
TRACE("appName: %s\n", debugstr_w(appName));
appKey = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * (lstrlenW(regkey_mail) +
- lstrlenW(regkey_backslash) + lstrlenW(appName) + 1));
+ lstrlenW(L"\\") + lstrlenW(appName) + 1));
if (!appKey)
goto cleanUp;
lstrcpyW(appKey, regkey_mail);
- lstrcatW(appKey, regkey_backslash);
+ lstrcatW(appKey, L"\\");
lstrcatW(appKey, appName);
RegCloseKey(hkeyMail);
@@ -1074,8 +1066,8 @@ void load_mapi_providers(void)
goto cleanUp;
/* Try to load the providers */
- load_mapi_provider(hkeyMail, regkey_dllpath, &mapi_provider);
- load_mapi_provider(hkeyMail, regkey_dllpath_ex, &mapi_ex_provider);
+ load_mapi_provider(hkeyMail, L"DLLPath", &mapi_provider);
+ load_mapi_provider(hkeyMail, L"DLLPathEx", &mapi_ex_provider);
/* Now try to load our function pointers */
ZeroMemory(&mapiFunctions, sizeof(mapiFunctions));
--
2.26.2
Dec. 2, 2020
[PATCH] regsvr32: Use a string literal for an empty string.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
programs/regsvr32/regsvr32.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/programs/regsvr32/regsvr32.c b/programs/regsvr32/regsvr32.c
index 885f0ff7833..ecfd95234dd 100644
--- a/programs/regsvr32/regsvr32.c
+++ b/programs/regsvr32/regsvr32.c
@@ -315,7 +315,7 @@ int __cdecl wmain(int argc, WCHAR* argv[])
BOOL Unregister = FALSE;
BOOL DllFound = FALSE;
WCHAR* wsCommandLine = NULL;
- WCHAR EmptyLine[1] = {0};
+ WCHAR EmptyLine[] = L"";
OleInitialize(NULL);
--
2.26.2
Dec. 2, 2020
[PATCH] oleaut32: Use a string literal for an empty string.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/oleaut32/vartype.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/oleaut32/vartype.c b/dlls/oleaut32/vartype.c
index 98b9762d896..6793de317ac 100644
--- a/dlls/oleaut32/vartype.c
+++ b/dlls/oleaut32/vartype.c
@@ -6469,7 +6469,7 @@ static BSTR VARIANT_BstrReplaceDecimal(const WCHAR * buff, LCID lcid, ULONG dwFl
{
WCHAR *p;
WCHAR numbuff[256];
- WCHAR empty[] = {'\0'};
+ WCHAR empty[] = L"";
NUMBERFMTW minFormat;
minFormat.NumDigits = 0;
--
2.26.2
Dec. 2, 2020
[PATCH 2/2] xmllite: Drop superfluous casts to self.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/xmllite/reader.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
index 4793b128bae..13d841eb94d 100644
--- a/dlls/xmllite/reader.c
+++ b/dlls/xmllite/reader.c
@@ -213,9 +213,9 @@ typedef struct
static WCHAR emptyW[] = L"";
static WCHAR xmlW[] = L"xml";
static WCHAR xmlnsW[] = L"xmlns";
-static const strval strval_empty = { (WCHAR *)emptyW, 0 };
-static const strval strval_xml = { (WCHAR *)xmlW, 3 };
-static const strval strval_xmlns = { (WCHAR *)xmlnsW, 5 };
+static const strval strval_empty = { emptyW, 0 };
+static const strval strval_xml = { xmlW, 3 };
+static const strval strval_xmlns = { xmlnsW, 5 };
struct reader_position
{
--
2.26.2
Dec. 2, 2020
[PATCH 1/2] xmllite: Use a string literal for an empty string.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/xmllite/reader.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
index a463934202a..4793b128bae 100644
--- a/dlls/xmllite/reader.c
+++ b/dlls/xmllite/reader.c
@@ -210,7 +210,7 @@ typedef struct
UINT start; /* input position where value starts */
} strval;
-static WCHAR emptyW[] = {0};
+static WCHAR emptyW[] = L"";
static WCHAR xmlW[] = L"xml";
static WCHAR xmlnsW[] = L"xmlns";
static const strval strval_empty = { (WCHAR *)emptyW, 0 };
--
2.26.2
Dec. 2, 2020
[PATCH] urlmon: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/urlmon/axinstall.c | 37 ++++++----------
dlls/urlmon/bindctx.c | 2 +-
dlls/urlmon/binding.c | 13 +++---
dlls/urlmon/bindprot.c | 8 +---
dlls/urlmon/file.c | 3 +-
dlls/urlmon/format.c | 2 +-
dlls/urlmon/http.c | 9 +---
dlls/urlmon/internet.c | 12 ++---
dlls/urlmon/mimefilter.c | 9 ++--
dlls/urlmon/sec_mgr.c | 93 ++++++++++++---------------------------
dlls/urlmon/session.c | 57 ++++++------------------
dlls/urlmon/umon.c | 8 +---
dlls/urlmon/uri.c | 40 ++++++-----------
dlls/urlmon/urlmon_main.c | 4 +-
14 files changed, 89 insertions(+), 208 deletions(-)
diff --git a/dlls/urlmon/axinstall.c b/dlls/urlmon/axinstall.c
index 3f10902ddd2..2a8c2c45760 100644
--- a/dlls/urlmon/axinstall.c
+++ b/dlls/urlmon/axinstall.c
@@ -30,12 +30,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-static const WCHAR ctxW[] = {'c','t','x',0};
-static const WCHAR cab_extW[] = {'.','c','a','b',0};
-static const WCHAR infW[] = {'i','n','f',0};
-static const WCHAR dllW[] = {'d','l','l',0};
-static const WCHAR ocxW[] = {'o','c','x',0};
-
enum install_type {
INSTALL_UNKNOWN,
INSTALL_DLL,
@@ -97,19 +91,19 @@ static HRESULT extract_cab_file(install_ctx_t *ctx)
/* NOTE: Assume that file_name contains ".cab" extension */
ptr = ctx->install_file+path_len+1+file_len-3;
- memcpy(ptr, infW, sizeof(infW));
+ memcpy(ptr, L"inf", sizeof(L"inf"));
if(file_exists(ctx->install_file)) {
ctx->install_type = INSTALL_INF;
return S_OK;
}
- memcpy(ptr, dllW, sizeof(dllW));
+ memcpy(ptr, L"dll", sizeof(L"dll"));
if(file_exists(ctx->install_file)) {
ctx->install_type = INSTALL_DLL;
return S_OK;
}
- memcpy(ptr, ocxW, sizeof(ocxW));
+ memcpy(ptr, L"ocx", sizeof(L"ocx"));
if(file_exists(ctx->install_file)) {
ctx->install_type = INSTALL_DLL;
return S_OK;
@@ -183,18 +177,16 @@ static HRESULT process_hook_section(install_ctx_t *ctx, const WCHAR *sect_name)
DWORD len;
HRESULT hres;
- static const WCHAR runW[] = {'r','u','n',0};
-
len = GetPrivateProfileStringW(sect_name, NULL, NULL, buf, ARRAY_SIZE(buf), ctx->install_file);
if(!len)
return S_OK;
for(key = buf; *key; key += lstrlenW(key)+1) {
- if(!wcsicmp(key, runW)) {
+ if(!wcsicmp(key, L"run")) {
WCHAR *cmd;
size_t size;
- len = GetPrivateProfileStringW(sect_name, runW, NULL, val, ARRAY_SIZE(val), ctx->install_file);
+ len = GetPrivateProfileStringW(sect_name, L"run", NULL, val, ARRAY_SIZE(val), ctx->install_file);
TRACE("Run %s\n", debugstr_w(val));
@@ -226,17 +218,14 @@ static HRESULT install_inf_file(install_ctx_t *ctx)
DWORD len;
HRESULT hres;
- static const WCHAR setup_hooksW[] = {'S','e','t','u','p',' ','H','o','o','k','s',0};
- static const WCHAR add_codeW[] = {'A','d','d','.','C','o','d','e',0};
-
- len = GetPrivateProfileStringW(setup_hooksW, NULL, NULL, buf, ARRAY_SIZE(buf), ctx->install_file);
+ len = GetPrivateProfileStringW(L"Setup Hooks", NULL, NULL, buf, ARRAY_SIZE(buf), ctx->install_file);
if(len) {
default_install = FALSE;
for(key = buf; *key; key += lstrlenW(key)+1) {
TRACE("[Setup Hooks] key: %s\n", debugstr_w(key));
- len = GetPrivateProfileStringW(setup_hooksW, key, NULL, sect_name, ARRAY_SIZE(sect_name),
+ len = GetPrivateProfileStringW(L"Setup Hooks", key, NULL, sect_name, ARRAY_SIZE(sect_name),
ctx->install_file);
if(!len) {
WARN("Could not get key value\n");
@@ -249,14 +238,14 @@ static HRESULT install_inf_file(install_ctx_t *ctx)
}
}
- len = GetPrivateProfileStringW(add_codeW, NULL, NULL, buf, ARRAY_SIZE(buf), ctx->install_file);
+ len = GetPrivateProfileStringW(L"Add.Code", NULL, NULL, buf, ARRAY_SIZE(buf), ctx->install_file);
if(len) {
default_install = FALSE;
for(key = buf; *key; key += lstrlenW(key)+1) {
TRACE("[Add.Code] key: %s\n", debugstr_w(key));
- len = GetPrivateProfileStringW(add_codeW, key, NULL, sect_name, ARRAY_SIZE(sect_name),
+ len = GetPrivateProfileStringW(L"Add.Code", key, NULL, sect_name, ARRAY_SIZE(sect_name),
ctx->install_file);
if(!len) {
WARN("Could not get key value\n");
@@ -354,7 +343,7 @@ static BOOL init_warning_dialog(HWND hwnd, install_ctx_t *ctx)
BSTR display_uri;
HRESULT hres;
- if(!SetPropW(hwnd, ctxW, ctx))
+ if(!SetPropW(hwnd, L"ctx", ctx))
return FALSE;
hres = IUri_GetDisplayUri(ctx->uri, &display_uri);
@@ -384,7 +373,7 @@ static INT_PTR WINAPI warning_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
case WM_COMMAND:
switch(wparam) {
case ID_AXINSTALL_INSTALL_BTN: {
- install_ctx_t *ctx = GetPropW(hwnd, ctxW);
+ install_ctx_t *ctx = GetPropW(hwnd, L"ctx");
if(ctx)
ctx->cancel = FALSE;
EndDialog(hwnd, 0);
@@ -395,7 +384,7 @@ static INT_PTR WINAPI warning_proc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lp
return FALSE;
}
case WM_TIMER:
- update_counter(GetPropW(hwnd, ctxW), hwnd);
+ update_counter(GetPropW(hwnd, L"ctx"), hwnd);
return TRUE;
}
@@ -460,7 +449,7 @@ static HRESULT install_file(install_ctx_t *ctx, const WCHAR *cache_file)
if(!ext)
ext = ptr;
- if(!wcsicmp(ext, cab_extW)) {
+ if(!wcsicmp(ext, L".cab")) {
hres = install_cab_file(ctx);
}else {
FIXME("Unsupported extension %s\n", debugstr_w(ext));
diff --git a/dlls/urlmon/bindctx.c b/dlls/urlmon/bindctx.c
index 61917518c09..406232467c3 100644
--- a/dlls/urlmon/bindctx.c
+++ b/dlls/urlmon/bindctx.c
@@ -23,7 +23,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-static WCHAR bscb_holderW[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
+static WCHAR bscb_holderW[] = L"_BSCB_Holder_";
extern IID IID_IBindStatusCallbackHolder;
diff --git a/dlls/urlmon/binding.c b/dlls/urlmon/binding.c
index e90d4daf346..d35052dfdf6 100644
--- a/dlls/urlmon/binding.c
+++ b/dlls/urlmon/binding.c
@@ -26,8 +26,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-static WCHAR cbinding_contextW[] = {'C','B','i','n','d','i','n','g',' ','C','o','n','t','e','x','t',0};
-static WCHAR bscb_holderW[] = { '_','B','S','C','B','_','H','o','l','d','e','r','_',0 };
+static WCHAR cbinding_contextW[] = L"CBinding Context";
+static WCHAR bscb_holderW[] = L"_BSCB_Holder_";
typedef struct {
IUnknown IUnknown_iface;
@@ -197,7 +197,6 @@ static LPWSTR get_mime_clsid(LPCWSTR mime, CLSID *clsid)
static const WCHAR mime_keyW[] =
{'M','I','M','E','\\','D','a','t','a','b','a','s','e','\\',
'C','o','n','t','e','n','t',' ','T','y','p','e','\\'};
- static const WCHAR clsidW[] = {'C','L','S','I','D',0};
len = lstrlenW(mime)+1;
key_name = heap_alloc(sizeof(mime_keyW) + len*sizeof(WCHAR));
@@ -213,7 +212,7 @@ static LPWSTR get_mime_clsid(LPCWSTR mime, CLSID *clsid)
size = 50*sizeof(WCHAR);
ret = heap_alloc(size);
- res = RegQueryValueExW(hkey, clsidW, NULL, &type, (LPBYTE)ret, &size);
+ res = RegQueryValueExW(hkey, L"CLSID", NULL, &type, (BYTE*)ret, &size);
RegCloseKey(hkey);
if(res != ERROR_SUCCESS) {
WARN("Could not get CLSID: %08x\n", res);
@@ -1239,13 +1238,11 @@ static HRESULT WINAPI InternetBindInfo_GetBindString(IInternetBindInfo *iface,
switch(ulStringType) {
case BINDSTRING_ACCEPT_MIMES: {
- static const WCHAR wszMimes[] = {'*','/','*',0};
-
if(!ppwzStr || !pcElFetched)
return E_INVALIDARG;
- ppwzStr[0] = CoTaskMemAlloc(sizeof(wszMimes));
- memcpy(ppwzStr[0], wszMimes, sizeof(wszMimes));
+ ppwzStr[0] = CoTaskMemAlloc(sizeof(L"*/*"));
+ memcpy(ppwzStr[0], L"*/*", sizeof(L"*/*"));
*pcElFetched = 1;
return S_OK;
}
diff --git a/dlls/urlmon/bindprot.c b/dlls/urlmon/bindprot.c
index e9c97e8a9db..2e58884b199 100644
--- a/dlls/urlmon/bindprot.c
+++ b/dlls/urlmon/bindprot.c
@@ -83,10 +83,6 @@ static LRESULT WINAPI notif_wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM
return DefWindowProcW(hwnd, msg, wParam, lParam);
}
-static const WCHAR wszURLMonikerNotificationWindow[] =
- {'U','R','L',' ','M','o','n','i','k','e','r',' ',
- 'N','o','t','i','f','i','c','a','t','i','o','n',' ','W','i','n','d','o','w',0};
-
static ATOM notif_wnd_class;
static BOOL WINAPI register_notif_wnd_class(INIT_ONCE *once, void *param, void **context)
@@ -94,7 +90,7 @@ static BOOL WINAPI register_notif_wnd_class(INIT_ONCE *once, void *param, void *
static WNDCLASSEXW wndclass = {
sizeof(wndclass), 0, notif_wnd_proc, 0, 0,
NULL, NULL, NULL, NULL, NULL,
- wszURLMonikerNotificationWindow, NULL
+ L"URL Moniker Notification Window", NULL
};
wndclass.hInstance = hProxyDll;
@@ -128,7 +124,7 @@ HWND get_notif_hwnd(void)
return NULL;
tls_data->notif_hwnd = CreateWindowExW(0, MAKEINTRESOURCEW(notif_wnd_class),
- wszURLMonikerNotificationWindow, 0, 0, 0, 0, 0, HWND_MESSAGE,
+ L"URL Moniker Notification Window", 0, 0, 0, 0, 0, HWND_MESSAGE,
NULL, hProxyDll, NULL);
if(tls_data->notif_hwnd)
tls_data->notif_hwnd_cnt++;
diff --git a/dlls/urlmon/file.c b/dlls/urlmon/file.c
index d634085b766..f2a8d983251 100644
--- a/dlls/urlmon/file.c
+++ b/dlls/urlmon/file.c
@@ -264,7 +264,6 @@ static HRESULT WINAPI FileProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUr
DWORD grfBINDF = 0;
DWORD scheme, size;
LPWSTR mime = NULL;
- WCHAR null_char = 0;
BSTR ext;
HRESULT hres;
@@ -301,7 +300,7 @@ static HRESULT WINAPI FileProtocol_StartEx(IInternetProtocolEx *iface, IUri *pUr
return S_OK;
}
- IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, &null_char);
+ IInternetProtocolSink_ReportProgress(pOIProtSink, BINDSTATUS_SENDINGREQUEST, L"");
size = 0;
hres = CoInternetParseIUri(pUri, PARSE_PATH_FROM_URL, 0, path, ARRAY_SIZE(path), &size, 0);
diff --git a/dlls/urlmon/format.c b/dlls/urlmon/format.c
index 6967c3b4f39..c9e528ce35a 100644
--- a/dlls/urlmon/format.c
+++ b/dlls/urlmon/format.c
@@ -21,7 +21,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-static WCHAR wszEnumFORMATETC[] = {'_','E','n','u','m','F','O','R','M','A','T','E','T','C','_',0};
+static WCHAR wszEnumFORMATETC[] = L"_EnumFORMATETC_";
typedef struct {
IEnumFORMATETC IEnumFORMATETC_iface;
diff --git a/dlls/urlmon/http.c b/dlls/urlmon/http.c
index cf7a0b78231..bee226bd474 100644
--- a/dlls/urlmon/http.c
+++ b/dlls/urlmon/http.c
@@ -65,8 +65,7 @@ static inline HttpProtocol *impl_from_IWinInetHttpInfo(IWinInetHttpInfo *iface)
return CONTAINING_RECORD(iface, HttpProtocol, IWinInetHttpInfo_iface);
}
-static const WCHAR default_headersW[] = {
- 'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',':',' ','g','z','i','p',',',' ','d','e','f','l','a','t','e',0};
+static const WCHAR default_headersW[] = L"Accept-Encoding: gzip, deflate";
static LPWSTR query_http_info(HttpProtocol *This, DWORD option)
{
@@ -512,9 +511,6 @@ static HRESULT HttpProtocol_start_downloading(Protocol *prot)
BOOL res;
HRESULT hres;
- static const WCHAR wszDefaultContentType[] =
- {'t','e','x','t','/','h','t','m','l',0};
-
if(!This->http_negotiate) {
WARN("Expected IHttpNegotiate pointer to be non-NULL\n");
return S_OK;
@@ -572,8 +568,7 @@ static HRESULT HttpProtocol_start_downloading(Protocol *prot)
WARN("HttpQueryInfo failed: %d\n", GetLastError());
IInternetProtocolSink_ReportProgress(This->base.protocol_sink,
(This->base.bindf & BINDF_FROMURLMON)
- ? BINDSTATUS_MIMETYPEAVAILABLE : BINDSTATUS_RAWMIMETYPE,
- wszDefaultContentType);
+ ? BINDSTATUS_MIMETYPEAVAILABLE : BINDSTATUS_RAWMIMETYPE, L"text/html");
}
content_length = query_http_info(This, HTTP_QUERY_CONTENT_LENGTH);
diff --git a/dlls/urlmon/internet.c b/dlls/urlmon/internet.c
index ed95c069e22..20a11be306e 100644
--- a/dlls/urlmon/internet.c
+++ b/dlls/urlmon/internet.c
@@ -26,11 +26,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
static const WCHAR feature_control_keyW[] =
- {'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\',
- 'I','n','t','e','r','n','e','t',' ','E','x','p','l','o','r','e','r','\\',
- 'M','a','i','n','\\',
- 'F','e','a','t','u','r','e','C','o','n','t','r','o','l',0};
+ L"Software\\Microsoft\\Internet Explorer\\Main\\FeatureControl";
static CRITICAL_SECTION process_features_cs;
static CRITICAL_SECTION_DEBUG process_features_cs_dbg =
@@ -489,8 +485,6 @@ static BOOL get_feature_from_reg(HKEY feature_control, LPCWSTR feature_name, LPC
HKEY feature;
DWORD res;
- static const WCHAR wildcardW[] = {'*',0};
-
res = RegOpenKeyW(feature_control, feature_name, &feature);
if(res != ERROR_SUCCESS)
return FALSE;
@@ -499,7 +493,7 @@ static BOOL get_feature_from_reg(HKEY feature_control, LPCWSTR feature_name, LPC
res = RegQueryValueExW(feature, process_name, NULL, &type, (BYTE*)&value, &size);
if(res != ERROR_SUCCESS || type != REG_DWORD) {
size = sizeof(DWORD);
- res = RegQueryValueExW(feature, wildcardW, NULL, &type, (BYTE*)&value, &size);
+ res = RegQueryValueExW(feature, L"*", NULL, &type, (BYTE*)&value, &size);
}
RegCloseKey(feature);
@@ -507,7 +501,7 @@ static BOOL get_feature_from_reg(HKEY feature_control, LPCWSTR feature_name, LPC
return FALSE;
if(type != REG_DWORD) {
- WARN("Unexpected registry value type %d (expected REG_DWORD) for %s\n", type, debugstr_w(wildcardW));
+ WARN("Unexpected registry value type %d (expected REG_DWORD) for %s\n", type, debugstr_w(L"*"));
return FALSE;
}
diff --git a/dlls/urlmon/mimefilter.c b/dlls/urlmon/mimefilter.c
index 44b9e92994a..6ee0da5b119 100644
--- a/dlls/urlmon/mimefilter.c
+++ b/dlls/urlmon/mimefilter.c
@@ -428,14 +428,12 @@ HRESULT find_mime_from_ext(const WCHAR *ext, WCHAR **ret)
WCHAR mime[64];
HKEY hkey;
- static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t',' ','T','y','p','e','\0'};
-
res = RegOpenKeyW(HKEY_CLASSES_ROOT, ext, &hkey);
if(res != ERROR_SUCCESS)
return HRESULT_FROM_WIN32(res);
size = sizeof(mime);
- res = RegQueryValueExW(hkey, content_typeW, NULL, NULL, (LPBYTE)mime, &size);
+ res = RegQueryValueExW(hkey, L"Content Type", NULL, NULL, (BYTE*)mime, &size);
RegCloseKey(hkey);
if(res != ERROR_SUCCESS)
return HRESULT_FROM_WIN32(res);
@@ -482,9 +480,8 @@ static HRESULT find_mime_from_url(const WCHAR *url, WCHAR **ret)
return hres;
}
-static const WCHAR text_plainW[] = {'t','e','x','t','/','p','l','a','i','n','\0'};
-static const WCHAR app_octetstreamW[] = {'a','p','p','l','i','c','a','t','i','o','n','/',
- 'o','c','t','e','t','-','s','t','r','e','a','m','\0'};
+static const WCHAR text_plainW[] = L"text/plain";
+static const WCHAR app_octetstreamW[] = L"application/octet-stream";
static const struct {
const WCHAR *mime;
diff --git a/dlls/urlmon/sec_mgr.c b/dlls/urlmon/sec_mgr.c
index af6cf212bd4..60672930ebc 100644
--- a/dlls/urlmon/sec_mgr.c
+++ b/dlls/urlmon/sec_mgr.c
@@ -33,35 +33,12 @@
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(urlmon);
-
-static const WCHAR currentlevelW[] = {'C','u','r','r','e','n','t','L','e','v','e','l',0};
-static const WCHAR descriptionW[] = {'D','e','s','c','r','i','p','t','i','o','n',0};
-static const WCHAR displaynameW[] = {'D','i','s','p','l','a','y','N','a','m','e',0};
-static const WCHAR fileW[] = {'f','i','l','e',0};
-static const WCHAR flagsW[] = {'F','l','a','g','s',0};
-static const WCHAR iconW[] = {'I','c','o','n',0};
-static const WCHAR minlevelW[] = {'M','i','n','L','e','v','e','l',0};
-static const WCHAR recommendedlevelW[] = {'R','e','c','o','m','m','e','n','d','e','d',
- 'L','e','v','e','l',0};
-static const WCHAR wszZonesKey[] = {'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\',
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
- 'Z','o','n','e','s','\\',0};
-static const WCHAR zone_map_keyW[] = {'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\',
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
- 'Z','o','n','e','M','a','p',0};
-static const WCHAR wszZoneMapDomainsKey[] = {'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\',
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
- 'Z','o','n','e','M','a','p','\\',
- 'D','o','m','a','i','n','s',0};
+static const WCHAR wszZonesKey[] =
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\Zones\\";
+static const WCHAR zone_map_keyW[] =
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap";
+static const WCHAR wszZoneMapDomainsKey[] =
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap\\Domains";
static inline BOOL is_drive_path(const WCHAR *path)
{
@@ -135,13 +112,7 @@ static HRESULT get_zone_from_reg(LPCWSTR schema, DWORD *zone)
HKEY hkey;
static const WCHAR wszZoneMapProtocolKey[] =
- {'S','o','f','t','w','a','r','e','\\',
- 'M','i','c','r','o','s','o','f','t','\\',
- 'W','i','n','d','o','w','s','\\',
- 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
- 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
- 'Z','o','n','e','M','a','p','\\',
- 'P','r','o','t','o','c','o','l','D','e','f','a','u','l','t','s',0};
+ L"Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\ZoneMap\\ProtocolDefaults";
res = RegOpenKeyW(HKEY_CURRENT_USER, wszZoneMapProtocolKey, &hkey);
if(res != ERROR_SUCCESS) {
@@ -262,8 +233,6 @@ static BOOL matches_domain_pattern(LPCWSTR pattern, LPCWSTR str, BOOL implicit_w
static BOOL get_zone_for_scheme(HKEY key, LPCWSTR schema, DWORD *zone)
{
- static const WCHAR wildcardW[] = {'*',0};
-
DWORD res;
DWORD size = sizeof(DWORD);
DWORD type;
@@ -278,12 +247,12 @@ static BOOL get_zone_for_scheme(HKEY key, LPCWSTR schema, DWORD *zone)
/* Try to get the zone for the wildcard scheme. */
size = sizeof(DWORD);
- res = RegQueryValueExW(key, wildcardW, NULL, &type, (BYTE*)zone, &size);
+ res = RegQueryValueExW(key, L"*", NULL, &type, (BYTE*)zone, &size);
if(res != ERROR_SUCCESS)
return FALSE;
if(type != REG_DWORD) {
- WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(wildcardW));
+ WARN("Unexpected value type %d for value %s, expected REG_DWORD\n", type, debugstr_w(L"*"));
return FALSE;
}
@@ -528,7 +497,7 @@ static HRESULT map_security_uri_to_zone(IUri *uri, DWORD *zone)
if(FAILED(hres))
return hres;
- if(!wcsicmp(scheme, fileW)) {
+ if(!wcsicmp(scheme, L"file")) {
BSTR path;
WCHAR *ptr, *path_start, root[20];
@@ -639,12 +608,10 @@ static HRESULT map_uri_to_zone(IUri *uri, DWORD *zone, IUri **ret_uri)
static HRESULT open_zone_key(HKEY parent_key, DWORD zone, HKEY *hkey)
{
- static const WCHAR wszFormat[] = {'%','s','%','u',0};
-
WCHAR key_name[ARRAY_SIZE(wszZonesKey) + 12];
DWORD res;
- wsprintfW(key_name, wszFormat, wszZonesKey, zone);
+ wsprintfW(key_name, L"%s%u", wszZonesKey, zone);
res = RegOpenKeyW(parent_key, key_name, hkey);
@@ -688,9 +655,7 @@ static HRESULT get_action_policy(DWORD zone, DWORD action, BYTE *policy, DWORD s
WCHAR action_str[16];
DWORD len = size;
- static const WCHAR formatW[] = {'%','X',0};
-
- wsprintfW(action_str, formatW, action);
+ wsprintfW(action_str, L"%X", action);
res = RegQueryValueExW(hkey, action_str, NULL, NULL, policy, &len);
if(res == ERROR_MORE_DATA) {
@@ -1425,13 +1390,13 @@ static HRESULT WINAPI ZoneMgrImpl_GetZoneAttributes(IInternetZoneManagerEx2* ifa
if (FAILED(hr))
TRACE("Zone %d not in HKLM\n", dwZone);
- get_string_from_reg(hcu, hklm, displaynameW, pZoneAttributes->szDisplayName, MAX_ZONE_PATH);
- get_string_from_reg(hcu, hklm, descriptionW, pZoneAttributes->szDescription, MAX_ZONE_DESCRIPTION);
- get_string_from_reg(hcu, hklm, iconW, pZoneAttributes->szIconPath, MAX_ZONE_PATH);
- get_dword_from_reg(hcu, hklm, minlevelW, &pZoneAttributes->dwTemplateMinLevel);
- get_dword_from_reg(hcu, hklm, currentlevelW, &pZoneAttributes->dwTemplateCurrentLevel);
- get_dword_from_reg(hcu, hklm, recommendedlevelW, &pZoneAttributes->dwTemplateRecommended);
- get_dword_from_reg(hcu, hklm, flagsW, &pZoneAttributes->dwFlags);
+ get_string_from_reg(hcu, hklm, L"DisplayName", pZoneAttributes->szDisplayName, MAX_ZONE_PATH);
+ get_string_from_reg(hcu, hklm, L"Description", pZoneAttributes->szDescription, MAX_ZONE_DESCRIPTION);
+ get_string_from_reg(hcu, hklm, L"Icon", pZoneAttributes->szIconPath, MAX_ZONE_PATH);
+ get_dword_from_reg(hcu, hklm, L"MinLevel", &pZoneAttributes->dwTemplateMinLevel);
+ get_dword_from_reg(hcu, hklm, L"CurrentLevel", &pZoneAttributes->dwTemplateCurrentLevel);
+ get_dword_from_reg(hcu, hklm, L"RecommendedLevel", &pZoneAttributes->dwTemplateRecommended);
+ get_dword_from_reg(hcu, hklm, L"Flags", &pZoneAttributes->dwFlags);
RegCloseKey(hklm);
RegCloseKey(hcu);
@@ -1459,25 +1424,25 @@ static HRESULT WINAPI ZoneMgrImpl_SetZoneAttributes(IInternetZoneManagerEx2* ifa
return S_OK; /* IE6 returned E_FAIL here */
/* cbSize is ignored */
- RegSetValueExW(hcu, displaynameW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szDisplayName,
+ RegSetValueExW(hcu, L"DisplayName", 0, REG_SZ, (BYTE*)pZoneAttributes->szDisplayName,
(lstrlenW(pZoneAttributes->szDisplayName)+1)* sizeof(WCHAR));
- RegSetValueExW(hcu, descriptionW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szDescription,
+ RegSetValueExW(hcu, L"Description", 0, REG_SZ, (BYTE*)pZoneAttributes->szDescription,
(lstrlenW(pZoneAttributes->szDescription)+1)* sizeof(WCHAR));
- RegSetValueExW(hcu, iconW, 0, REG_SZ, (LPBYTE) pZoneAttributes->szIconPath,
+ RegSetValueExW(hcu, L"Icon", 0, REG_SZ, (BYTE*)pZoneAttributes->szIconPath,
(lstrlenW(pZoneAttributes->szIconPath)+1)* sizeof(WCHAR));
- RegSetValueExW(hcu, minlevelW, 0, REG_DWORD,
+ RegSetValueExW(hcu, L"MinLevel", 0, REG_DWORD,
(const BYTE*) &pZoneAttributes->dwTemplateMinLevel, sizeof(DWORD));
- RegSetValueExW(hcu, currentlevelW, 0, REG_DWORD,
+ RegSetValueExW(hcu, L"CurrentLevel", 0, REG_DWORD,
(const BYTE*) &pZoneAttributes->dwTemplateCurrentLevel, sizeof(DWORD));
- RegSetValueExW(hcu, recommendedlevelW, 0, REG_DWORD,
+ RegSetValueExW(hcu, L"RecommendedLevel", 0, REG_DWORD,
(const BYTE*) &pZoneAttributes->dwTemplateRecommended, sizeof(DWORD));
- RegSetValueExW(hcu, flagsW, 0, REG_DWORD, (const BYTE*) &pZoneAttributes->dwFlags, sizeof(DWORD));
+ RegSetValueExW(hcu, L"Flags", 0, REG_DWORD, (const BYTE*) &pZoneAttributes->dwFlags, sizeof(DWORD));
RegCloseKey(hcu);
return S_OK;
@@ -2048,7 +2013,7 @@ HRESULT WINAPI CoInternetGetSecurityUrlEx(IUri *pUri, IUri **ppSecUri, PSUACTION
const WCHAR *tmp = ret_url;
/* Check and see if a "//" is after the scheme name. */
- tmp += ARRAY_SIZE(fileW);
+ tmp += ARRAY_SIZE(L"file");
if(*tmp != '/' || *(tmp+1) != '/')
hres = E_INVALIDARG;
}
@@ -2083,11 +2048,9 @@ BOOL WINAPI IsInternetESCEnabledLocal(void)
DWORD type, size, val;
HKEY zone_map;
- static const WCHAR iehardenW[] = {'I','E','H','a','r','d','e','n',0};
-
if(RegOpenKeyExW(HKEY_CURRENT_USER, zone_map_keyW, 0, KEY_QUERY_VALUE, &zone_map) == ERROR_SUCCESS) {
size = sizeof(DWORD);
- if(RegQueryValueExW(zone_map, iehardenW, NULL, &type, (BYTE*)&val, &size) == ERROR_SUCCESS)
+ if(RegQueryValueExW(zone_map, L"IEHarden", NULL, &type, (BYTE*)&val, &size) == ERROR_SUCCESS)
esc_enabled = type == REG_DWORD && val != 0;
RegCloseKey(zone_map);
}
diff --git a/dlls/urlmon/session.c b/dlls/urlmon/session.c
index 523511d2db7..5154bdb61f8 100644
--- a/dlls/urlmon/session.c
+++ b/dlls/urlmon/session.c
@@ -52,13 +52,6 @@ static CRITICAL_SECTION_DEBUG session_cs_dbg =
};
static CRITICAL_SECTION session_cs = { &session_cs_dbg, -1, 0, 0, 0, 0 };
-static const WCHAR internet_settings_keyW[] =
- {'S','O','F','T','W','A','R','E',
- '\\','M','i','c','r','o','s','o','f','t',
- '\\','W','i','n','d','o','w','s',
- '\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',
- '\\','I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s',0};
-
static name_space *find_name_space(LPCWSTR protocol)
{
name_space *iter;
@@ -82,7 +75,6 @@ static HRESULT get_protocol_cf(LPCWSTR schema, DWORD schema_len, CLSID *pclsid,
static const WCHAR wszProtocolsKey[] =
{'P','R','O','T','O','C','O','L','S','\\','H','a','n','d','l','e','r','\\'};
- static const WCHAR wszCLSID[] = {'C','L','S','I','D',0};
wszKey = heap_alloc(sizeof(wszProtocolsKey)+(schema_len+1)*sizeof(WCHAR));
memcpy(wszKey, wszProtocolsKey, sizeof(wszProtocolsKey));
@@ -96,7 +88,7 @@ static HRESULT get_protocol_cf(LPCWSTR schema, DWORD schema_len, CLSID *pclsid,
}
size = sizeof(str_clsid);
- res = RegQueryValueExW(hkey, wszCLSID, NULL, &type, (LPBYTE)str_clsid, &size);
+ res = RegQueryValueExW(hkey, L"CLSID", NULL, &type, (BYTE*)str_clsid, &size);
RegCloseKey(hkey);
if(res != ERROR_SUCCESS || type != REG_SZ) {
WARN("Could not get protocol CLSID res=%d\n", res);
@@ -249,10 +241,6 @@ HRESULT get_protocol_handler(IUri *uri, CLSID *clsid, IClassFactory **ret)
IInternetProtocol *get_mime_filter(LPCWSTR mime)
{
- static const WCHAR filtersW[] = {'P','r','o','t','o','c','o','l','s',
- '\\','F','i','l','t','e','r',0 };
- static const WCHAR CLSIDW[] = {'C','L','S','I','D',0};
-
IClassFactory *cf = NULL;
IInternetProtocol *ret;
mime_filter *iter;
@@ -283,7 +271,7 @@ IInternetProtocol *get_mime_filter(LPCWSTR mime)
return ret;
}
- res = RegOpenKeyW(HKEY_CLASSES_ROOT, filtersW, &hlist);
+ res = RegOpenKeyW(HKEY_CLASSES_ROOT, L"Protocols\\Filter", &hlist);
if(res != ERROR_SUCCESS) {
TRACE("Could not open MIME filters key\n");
return NULL;
@@ -295,7 +283,7 @@ IInternetProtocol *get_mime_filter(LPCWSTR mime)
return NULL;
size = sizeof(clsidw);
- res = RegQueryValueExW(hfilter, CLSIDW, NULL, &type, (LPBYTE)clsidw, &size);
+ res = RegQueryValueExW(hfilter, L"CLSID", NULL, &type, (BYTE*)clsidw, &size);
CloseHandle(hfilter);
if(res!=ERROR_SUCCESS || type!=REG_SZ) {
WARN("Could not get filter CLSID for %s\n", debugstr_w(mime));
@@ -505,13 +493,11 @@ static BOOL get_url_encoding(HKEY root, DWORD *encoding)
DWORD size = sizeof(DWORD), res, type;
HKEY hkey;
- static const WCHAR wszUrlEncoding[] = {'U','r','l','E','n','c','o','d','i','n','g',0};
-
- res = RegOpenKeyW(root, internet_settings_keyW, &hkey);
+ res = RegOpenKeyW(root, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Internet Settings", &hkey);
if(res != ERROR_SUCCESS)
return FALSE;
- res = RegQueryValueExW(hkey, wszUrlEncoding, NULL, &type, (LPBYTE)encoding, &size);
+ res = RegQueryValueExW(hkey, L"UrlEncoding", NULL, &type, (BYTE*)encoding, &size);
RegCloseKey(hkey);
return res == ERROR_SUCCESS;
@@ -529,39 +515,21 @@ static void ensure_useragent(void)
BOOL is_wow;
HKEY key;
- static const WCHAR formatW[] =
- {'M','o','z','i','l','l','a','/','4','.','0',
- ' ','(','c','o','m','p','a','t','i','b','l','e',';',
- ' ','M','S','I','E',' ','8','.','0',';',
- ' ','W','i','n','d','o','w','s',' ','%','s','%','d','.','%','d',';',
- ' ','%','s','T','r','i','d','e','n','t','/','5','.','0',0};
- static const WCHAR post_platform_keyW[] =
- {'S','O','F','T','W','A','R','E',
- '\\','M','i','c','r','o','s','o','f','t',
- '\\','W','i','n','d','o','w','s',
- '\\','C','u','r','r','e','n','t','V','e','r','s','i','o','n',
- '\\','I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s',
- '\\','5','.','0','\\','U','s','e','r',' ','A','g','e','n','t',
- '\\','P','o','s','t',' ','P','l','a','t','f','o','r','m',0};
- static const WCHAR ntW[] = {'N','T',' ',0};
- static const WCHAR win64W[] = {'W','i','n','6','4',';',' ','x','6','4',';',' ',0};
- static const WCHAR wow64W[] = {'W','O','W','6','4',';',' ',0};
- static const WCHAR emptyW[] = {0};
-
if(user_agent)
return;
GetVersionExW(&info);
- is_nt = info.dwPlatformId == VER_PLATFORM_WIN32_NT ? ntW : emptyW;
+ is_nt = info.dwPlatformId == VER_PLATFORM_WIN32_NT ? L"NT " : L"";
if(sizeof(void*) == 8)
- os_type = win64W;
+ os_type = L"Win64; x64; ";
else if(IsWow64Process(GetCurrentProcess(), &is_wow) && is_wow)
- os_type = wow64W;
+ os_type = L"WOW64; ";
else
- os_type = emptyW;
+ os_type = L"";
- swprintf(buf, ARRAY_SIZE(buf), formatW, is_nt, info.dwMajorVersion, info.dwMinorVersion, os_type);
+ swprintf(buf, ARRAY_SIZE(buf), L"Mozilla/4.0 (compatible; MSIE 8.0; Windows %s%d.%d; %sTrident/5.0",
+ is_nt, info.dwMajorVersion, info.dwMinorVersion, os_type);
len = lstrlenW(buf);
size = len+40;
@@ -571,7 +539,8 @@ static void ensure_useragent(void)
memcpy(ret, buf, len*sizeof(WCHAR));
- res = RegOpenKeyW(HKEY_LOCAL_MACHINE, post_platform_keyW, &key);
+ res = RegOpenKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\"
+ "Internet Settings\\5.0\\User Agent\\Post Platform", &key);
if(res == ERROR_SUCCESS) {
DWORD value_len;
diff --git a/dlls/urlmon/umon.c b/dlls/urlmon/umon.c
index 14273efee99..e51b2f07d26 100644
--- a/dlls/urlmon/umon.c
+++ b/dlls/urlmon/umon.c
@@ -858,10 +858,7 @@ HRESULT WINAPI URLDownloadToCacheFileW(LPUNKNOWN lpUnkCaller, LPCWSTR szURL, LPW
HRESULT hr;
LPWSTR ext;
- static WCHAR header[] = {
- 'H','T','T','P','/','1','.','0',' ','2','0','0',' ',
- 'O','K','\\','r','\\','n','\\','r','\\','n',0
- };
+ static WCHAR header[] = L"HTTP/1.0 200 OK\\r\\n\\r\\n";
TRACE("(%p, %s, %p, %d, %d, %p)\n", lpUnkCaller, debugstr_w(szURL),
szFileName, dwBufLength, dwReserved, pBSC);
@@ -932,11 +929,10 @@ HRESULT WINAPI HlinkSimpleNavigateToString( LPCWSTR szTarget,
if (grfHLNF == HLNF_OPENINNEWWINDOW)
{
SHELLEXECUTEINFOW sei;
- static const WCHAR openW[] = { 'o', 'p', 'e', 'n', 0 };
memset(&sei, 0, sizeof(sei));
sei.cbSize = sizeof(sei);
- sei.lpVerb = openW;
+ sei.lpVerb = L"open";
sei.nShow = SW_SHOWNORMAL;
sei.fMask = SEE_MASK_FLAG_NO_UI | SEE_MASK_NO_CONSOLE;
sei.lpFile = szTarget;
diff --git a/dlls/urlmon/uri.c b/dlls/urlmon/uri.c
index cf901dfd8b7..91247b689b8 100644
--- a/dlls/urlmon/uri.c
+++ b/dlls/urlmon/uri.c
@@ -699,8 +699,6 @@ static BSTR pre_process_uri(LPCWSTR uri) {
* address.
*/
static DWORD ui2ipv4(WCHAR *dest, UINT address) {
- static const WCHAR formatW[] =
- {'%','u','.','%','u','.','%','u','.','%','u',0};
DWORD ret = 0;
UCHAR digits[4];
@@ -711,22 +709,21 @@ static DWORD ui2ipv4(WCHAR *dest, UINT address) {
if(!dest) {
WCHAR tmp[16];
- ret = swprintf(tmp, ARRAY_SIZE(tmp), formatW, digits[0], digits[1], digits[2], digits[3]);
+ ret = swprintf(tmp, ARRAY_SIZE(tmp), L"%u.%u.%u.%u", digits[0], digits[1], digits[2], digits[3]);
} else
- ret = swprintf(dest, 16, formatW, digits[0], digits[1], digits[2], digits[3]);
+ ret = swprintf(dest, 16, L"%u.%u.%u.%u", digits[0], digits[1], digits[2], digits[3]);
return ret;
}
static DWORD ui2str(WCHAR *dest, UINT value) {
- static const WCHAR formatW[] = {'%','u',0};
DWORD ret = 0;
if(!dest) {
WCHAR tmp[11];
- ret = swprintf(tmp, ARRAY_SIZE(tmp), formatW, value);
+ ret = swprintf(tmp, ARRAY_SIZE(tmp), L"%u", value);
} else
- ret = swprintf(dest, 11, formatW, value);
+ ret = swprintf(dest, 11, L"%u", value);
return ret;
}
@@ -970,14 +967,11 @@ static BOOL parse_scheme_type(parse_data *data) {
* Returns TRUE if it was able to successfully parse the information.
*/
static BOOL parse_scheme(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD extras) {
- static const WCHAR fileW[] = {'f','i','l','e',0};
- static const WCHAR wildcardW[] = {'*',0};
-
/* First check to see if the uri could implicitly be a file path. */
if(is_implicit_file_path(*ptr)) {
if(flags & Uri_CREATE_ALLOW_IMPLICIT_FILE_SCHEME) {
- data->scheme = fileW;
- data->scheme_len = lstrlenW(fileW);
+ data->scheme = L"file";
+ data->scheme_len = lstrlenW(L"file");
data->has_implicit_scheme = TRUE;
TRACE("(%p %p %x): URI is an implicit file path.\n", ptr, data, flags);
@@ -996,8 +990,8 @@ static BOOL parse_scheme(const WCHAR **ptr, parse_data *data, DWORD flags, DWORD
* c) an invalid URI.
*/
if(flags & Uri_CREATE_ALLOW_IMPLICIT_WILDCARD_SCHEME) {
- data->scheme = wildcardW;
- data->scheme_len = lstrlenW(wildcardW);
+ data->scheme = L"*";
+ data->scheme_len = lstrlenW(L"*");
data->has_implicit_scheme = TRUE;
TRACE("(%p %p %x): URI is an implicit wildcard scheme.\n", ptr, data, flags);
@@ -1510,7 +1504,6 @@ static BOOL parse_authority(const WCHAR **ptr, parse_data *data, DWORD flags) {
/* Attempts to parse the path information of a hierarchical URI. */
static BOOL parse_path_hierarchical(const WCHAR **ptr, parse_data *data, DWORD flags) {
const WCHAR *start = *ptr;
- static const WCHAR slash[] = {'/',0};
const BOOL is_file = data->scheme_type == URL_SCHEME_FILE;
if(is_path_delim(data->scheme_type, **ptr)) {
@@ -1519,7 +1512,7 @@ static BOOL parse_path_hierarchical(const WCHAR **ptr, parse_data *data, DWORD f
data->path_len = 0;
} else if(!(flags & Uri_CREATE_NO_CANONICALIZE)) {
/* If the path component is empty, then a '/' is added. */
- data->path = slash;
+ data->path = L"/";
data->path_len = 1;
}
} else {
@@ -1972,14 +1965,12 @@ static BOOL canonicalize_userinfo(const parse_data *data, Uri *uri, DWORD flags,
*/
static BOOL canonicalize_reg_name(const parse_data *data, Uri *uri,
DWORD flags, BOOL computeOnly) {
- static const WCHAR localhostW[] =
- {'l','o','c','a','l','h','o','s','t',0};
const WCHAR *ptr;
const BOOL known_scheme = data->scheme_type != URL_SCHEME_UNKNOWN;
if(data->scheme_type == URL_SCHEME_FILE &&
- data->host_len == lstrlenW(localhostW)) {
- if(!StrCmpNIW(data->host, localhostW, data->host_len)) {
+ data->host_len == lstrlenW(L"localhost")) {
+ if(!StrCmpNIW(data->host, L"localhost", data->host_len)) {
uri->host_start = -1;
uri->host_len = 0;
uri->host_type = Uri_HOST_UNKNOWN;
@@ -3147,8 +3138,7 @@ static HRESULT validate_scheme_name(const UriBuilder *builder, parse_data *data,
ptr = builder->uri->canon_uri+builder->uri->scheme_start;
expected_len = builder->uri->scheme_len;
} else {
- static const WCHAR nullW[] = {0};
- ptr = nullW;
+ ptr = L"";
expected_len = 0;
}
@@ -3317,8 +3307,7 @@ static HRESULT validate_path(const UriBuilder *builder, parse_data *data, DWORD
ptr = builder->uri->canon_uri+builder->uri->path_start;
expected_len = builder->uri->path_len;
} else {
- static const WCHAR nullW[] = {0};
- ptr = nullW;
+ ptr = L"";
check_len = FALSE;
expected_len = -1;
}
@@ -6131,8 +6120,7 @@ static HRESULT combine_uri(Uri *base, Uri *relative, DWORD flags, IUri **result,
/* Just set the path as a '/' if the base didn't have
* one and if it's a hierarchical URI.
*/
- static const WCHAR slashW[] = {'/',0};
- data.path = slashW;
+ data.path = L"/";
data.path_len = 1;
}
diff --git a/dlls/urlmon/urlmon_main.c b/dlls/urlmon/urlmon_main.c
index 5d598830fdf..1af4d38ac81 100644
--- a/dlls/urlmon/urlmon_main.c
+++ b/dlls/urlmon/urlmon_main.c
@@ -453,9 +453,7 @@ static HRESULT register_inf(BOOL doregister)
HRESULT (WINAPI *pRegInstall)(HMODULE hm, LPCSTR pszSection, const STRTABLEA* pstTable);
HMODULE hAdvpack;
- static const WCHAR wszAdvpack[] = {'a','d','v','p','a','c','k','.','d','l','l',0};
-
- hAdvpack = LoadLibraryW(wszAdvpack);
+ hAdvpack = LoadLibraryW(L"advpack.dll");
pRegInstall = (void *)GetProcAddress(hAdvpack, "RegInstall");
return pRegInstall(hProxyDll, doregister ? "RegisterDll" : "UnregisterDll", NULL);
--
2.26.2
Dec. 2, 2020