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 vkd3d v3 1/5] vkd3d-shader: Implement an initial pass-through HLSL preprocessor.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 9, 2020
Dec. 9, 2020
[PATCH 2/2] wined3d: Use an sRGB fallback format for sRGB formats in wined3d_swapchain_vk_select_vk_format().
by Henri Verbeet
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50121
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/swapchain.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index ffffc18aa84..0c5a75ed02d 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -635,6 +635,22 @@ done:
return supported;
}
+static VkFormat get_swapchain_fallback_format(VkFormat vk_format)
+{
+ switch (vk_format)
+ {
+ case VK_FORMAT_R8G8B8A8_SRGB:
+ return VK_FORMAT_B8G8R8A8_SRGB;
+ case VK_FORMAT_R8G8B8A8_UNORM:
+ case VK_FORMAT_A2B10G10R10_UNORM_PACK32:
+ case VK_FORMAT_R16G16B16A16_SFLOAT:
+ return VK_FORMAT_B8G8R8A8_UNORM;
+ default:
+ WARN("Unhandled format %#x.\n", vk_format);
+ return VK_FORMAT_UNDEFINED;
+ }
+}
+
static VkFormat wined3d_swapchain_vk_select_vk_format(struct wined3d_swapchain_vk *swapchain_vk,
VkSurfaceKHR vk_surface)
{
@@ -684,7 +700,7 @@ static VkFormat wined3d_swapchain_vk_select_vk_format(struct wined3d_swapchain_v
if (i == format_count)
{
/* Try to create a swapchain with format conversion. */
- vk_format = VK_FORMAT_B8G8R8A8_UNORM;
+ vk_format = get_swapchain_fallback_format(vk_format);
WARN("Failed to find Vulkan swapchain format for %s.\n", debug_d3dformat(desc->backbuffer_format));
for (i = 0; i < format_count; ++i)
{
--
2.20.1
Dec. 9, 2020
[PATCH 1/2] wined3d: Ensure the last mip-level is at least large enough to hold a single compressed block.
by Henri Verbeet
This fixes a regression exposed by commit
ca0c3f770ae4fe4d535f59f2d54b4c0a531e800f, but probably originally introduced
by commit 3f7e5d647e40ce09292e7164eb5cc49ac77914cc.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48362
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/texture.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 6c9627d21f8..69f948c5fd2 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -3683,6 +3683,20 @@ static HRESULT wined3d_texture_init(struct wined3d_texture *texture, const struc
if (!offset)
return WINED3DERR_INVALIDCALL;
+ /* Ensure the last mip-level is at least large enough to hold a single
+ * compressed block. It is questionable how useful these mip-levels are to
+ * the application with "broken pitch" formats, but we want to avoid
+ * memory corruption when loading textures into WINED3D_LOCATION_SYSMEM. */
+ if (format->flags[WINED3D_GL_RES_TYPE_TEX_2D] & WINED3DFMT_FLAG_BROKEN_PITCH)
+ {
+ unsigned int min_size;
+
+ min_size = texture->sub_resources[level_count * layer_count - 1].offset + format->block_byte_count;
+ min_size = (min_size + (RESOURCE_ALIGNMENT - 1)) & ~(RESOURCE_ALIGNMENT - 1);
+ if (min_size > offset)
+ offset = min_size;
+ }
+
if (FAILED(hr = resource_init(&texture->resource, device, desc->resource_type, format,
desc->multisample_type, desc->multisample_quality, desc->usage, desc->bind_flags, desc->access,
desc->width, desc->height, desc->depth, offset, parent, parent_ops, &texture_resource_ops)))
--
2.20.1
Dec. 9, 2020
[PATCH] winegstreamer: Remove the color matrix setting for the other videoconvert as well.
by Zebediah Figura
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49535
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/winegstreamer/gstdemux.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index 77204bc55a2..9114e6610a3 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -1041,9 +1041,6 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct gstdemux *
goto out;
}
- /* Avoid expensive color matrix conversions. */
- gst_util_set_object_arg(G_OBJECT(vconv2), "matrix-mode", "none");
-
/* The bin takes ownership of these elements. */
gst_bin_add(GST_BIN(This->container), deinterlace);
gst_element_sync_state_with_parent(deinterlace);
--
2.29.2
Dec. 9, 2020
[PATCH v2 5/5] gdiplus/tests: Use wide-char string literals for test strings.
by Jeff Smith
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
v2: Fixed missing L prefix for a test string.
dlls/gdiplus/tests/font.c | 2 +-
dlls/gdiplus/tests/graphics.c | 24 +++++++++++-------------
2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/dlls/gdiplus/tests/font.c b/dlls/gdiplus/tests/font.c
index 0d7254f255e..32cd1ff2c4f 100644
--- a/dlls/gdiplus/tests/font.c
+++ b/dlls/gdiplus/tests/font.c
@@ -946,7 +946,7 @@ todo_wine
static void test_font_transform(void)
{
- static const WCHAR string[] = { 'A',0 };
+ static const WCHAR string[] = L"A";
GpStatus status;
HDC hdc;
LOGFONTA lf;
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index 9a09abcfc8b..2b1628f4e9c 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -2279,7 +2279,7 @@ static void test_GdipDrawString(void)
GpBrush *brush;
LOGFONTA logfont;
HDC hdc = GetDC( hwnd );
- static const WCHAR string[] = {'T','e','s','t',0};
+ static const WCHAR string[] = L"Test";
static const PointF positions[4] = {{0,0}, {1,1}, {2,2}, {3,3}};
GpMatrix *matrix;
@@ -3195,8 +3195,8 @@ static void test_string_functions(void)
GpBrush *brush;
ARGB color = 0xff000000;
HDC hdc = GetDC( hwnd );
- const WCHAR teststring[] = {'M','M',' ','M','\n','M',0};
- const WCHAR teststring2[] = {'j',0};
+ const WCHAR teststring[] = L"MM M\nM";
+ const WCHAR teststring2[] = L"j";
REAL char_width, char_height;
INT codepointsfitted, linesfilled;
GpStringFormat *format;
@@ -3743,7 +3743,7 @@ static void test_GdipMeasureString(void)
{ 200.0, 600.0, 1.0, UnitPixel },
{ 200.0, 600.0, 2.0, UnitPixel },
};
- static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
+ static const WCHAR string[] = L"1234567";
GpStatus status;
GpGraphics *graphics;
GpFontFamily *family;
@@ -4257,7 +4257,7 @@ static void test_pen_thickness(void)
*/
static void test_font_height_scaling(void)
{
- static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
+ static const WCHAR string[] = L"1234567";
HDC hdc;
GpStringFormat *format;
CharacterRange range = { 0, 7 };
@@ -4357,7 +4357,6 @@ static void test_font_height_scaling(void)
/* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
for (gfx_unit = 2; gfx_unit <= 6; gfx_unit++)
{
- static const WCHAR doubleW[2] = { 'W','W' };
RectF bounds_1, bounds_2;
REAL margin, margin_y, font_height;
int match;
@@ -4397,12 +4396,12 @@ todo_wine
/* bounds.width of 1 glyph: [margin]+[width]+[margin] */
set_rect_empty(&rect);
set_rect_empty(&bounds_1);
- status = GdipMeasureString(graphics, doubleW, 1, font, &rect, format, &bounds_1, NULL, NULL);
+ status = GdipMeasureString(graphics, L"W", 1, font, &rect, format, &bounds_1, NULL, NULL);
expect(Ok, status);
/* bounds.width of 2 identical glyphs: [margin]+[width]+[width]+[margin] */
set_rect_empty(&rect);
set_rect_empty(&bounds_2);
- status = GdipMeasureString(graphics, doubleW, 2, font, &rect, format, &bounds_2, NULL, NULL);
+ status = GdipMeasureString(graphics, L"WW", 2, font, &rect, format, &bounds_2, NULL, NULL);
expect(Ok, status);
/* margin = [bounds.width of 1] - [bounds.width of 2] / 2*/
@@ -4444,8 +4443,8 @@ cleanup:
static void test_measure_string(void)
{
- static const WCHAR string[] = { 'A','0','1',0 };
- static const WCHAR string2[] = { 'M',' ','M','M',0 };
+ static const WCHAR string[] = L"A01";
+ static const WCHAR string2[] = L"M MM";
HDC hdc;
GpStringFormat *format, *format_no_wrap;
CharacterRange range;
@@ -4915,7 +4914,6 @@ todo_wine
static void test_measured_extra_space(void)
{
- static const WCHAR string[2] = { 'W','W' };
GpStringFormat *format;
HDC hdc;
GpGraphics *graphics;
@@ -4959,12 +4957,12 @@ static void test_measured_extra_space(void)
/* bounds.width of 1 glyph: [margin]+[width]+[margin] */
set_rect_empty(&rect);
set_rect_empty(&bounds_1);
- status = GdipMeasureString(graphics, string, 1, font, &rect, format, &bounds_1, NULL, NULL);
+ status = GdipMeasureString(graphics, L"W", 1, font, &rect, format, &bounds_1, NULL, NULL);
expect(Ok, status);
/* bounds.width of 2 identical glyphs: [margin]+[width]+[width]+[margin] */
set_rect_empty(&rect);
set_rect_empty(&bounds_2);
- status = GdipMeasureString(graphics, string, 2, font, &rect, format, &bounds_2, NULL, NULL);
+ status = GdipMeasureString(graphics, L"WW", 2, font, &rect, format, &bounds_2, NULL, NULL);
expect(Ok, status);
/* margin = [bounds.width of 1] - [bounds.width of 2] / 2*/
--
2.23.0
Dec. 9, 2020
Re: [PATCH 5/5] gdiplus/tests: Use wide-char string literals for test strings.
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=83257
Your paranoid android.
=== build (build log) ===
../wine/dlls/gdiplus/tests/graphics.c:4447:36: error: wide character array initialized from non-wide string
Makefile:73658: recipe for target 'dlls/gdiplus/tests/graphics.cross.o' failed
Task: The exe32 Wine build failed
=== debiant (build log) ===
../wine/dlls/gdiplus/tests/graphics.c:4447:36: error: cannot initialize array of ‘short unsigned int’ from a string literal with type array of ‘char’
Task: The win32 Wine build failed
=== debiant (build log) ===
../wine/dlls/gdiplus/tests/graphics.c:4447:36: error: cannot initialize array of ‘short unsigned int’ from a string literal with type array of ‘char’
Task: The wow64 Wine build failed
Dec. 9, 2020
[PATCH 5/5] gdiplus/tests: Use wide-char string literals for test strings.
by Jeff Smith
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/gdiplus/tests/font.c | 2 +-
dlls/gdiplus/tests/graphics.c | 24 +++++++++++-------------
2 files changed, 12 insertions(+), 14 deletions(-)
diff --git a/dlls/gdiplus/tests/font.c b/dlls/gdiplus/tests/font.c
index 0d7254f255e..32cd1ff2c4f 100644
--- a/dlls/gdiplus/tests/font.c
+++ b/dlls/gdiplus/tests/font.c
@@ -946,7 +946,7 @@ todo_wine
static void test_font_transform(void)
{
- static const WCHAR string[] = { 'A',0 };
+ static const WCHAR string[] = L"A";
GpStatus status;
HDC hdc;
LOGFONTA lf;
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index 9a09abcfc8b..3c864c92e0a 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -2279,7 +2279,7 @@ static void test_GdipDrawString(void)
GpBrush *brush;
LOGFONTA logfont;
HDC hdc = GetDC( hwnd );
- static const WCHAR string[] = {'T','e','s','t',0};
+ static const WCHAR string[] = L"Test";
static const PointF positions[4] = {{0,0}, {1,1}, {2,2}, {3,3}};
GpMatrix *matrix;
@@ -3195,8 +3195,8 @@ static void test_string_functions(void)
GpBrush *brush;
ARGB color = 0xff000000;
HDC hdc = GetDC( hwnd );
- const WCHAR teststring[] = {'M','M',' ','M','\n','M',0};
- const WCHAR teststring2[] = {'j',0};
+ const WCHAR teststring[] = L"MM M\nM";
+ const WCHAR teststring2[] = L"j";
REAL char_width, char_height;
INT codepointsfitted, linesfilled;
GpStringFormat *format;
@@ -3743,7 +3743,7 @@ static void test_GdipMeasureString(void)
{ 200.0, 600.0, 1.0, UnitPixel },
{ 200.0, 600.0, 2.0, UnitPixel },
};
- static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
+ static const WCHAR string[] = L"1234567";
GpStatus status;
GpGraphics *graphics;
GpFontFamily *family;
@@ -4257,7 +4257,7 @@ static void test_pen_thickness(void)
*/
static void test_font_height_scaling(void)
{
- static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
+ static const WCHAR string[] = L"1234567";
HDC hdc;
GpStringFormat *format;
CharacterRange range = { 0, 7 };
@@ -4357,7 +4357,6 @@ static void test_font_height_scaling(void)
/* UnitPixel = 2, UnitPoint = 3, UnitInch = 4, UnitDocument = 5, UnitMillimeter = 6 */
for (gfx_unit = 2; gfx_unit <= 6; gfx_unit++)
{
- static const WCHAR doubleW[2] = { 'W','W' };
RectF bounds_1, bounds_2;
REAL margin, margin_y, font_height;
int match;
@@ -4397,12 +4396,12 @@ todo_wine
/* bounds.width of 1 glyph: [margin]+[width]+[margin] */
set_rect_empty(&rect);
set_rect_empty(&bounds_1);
- status = GdipMeasureString(graphics, doubleW, 1, font, &rect, format, &bounds_1, NULL, NULL);
+ status = GdipMeasureString(graphics, L"W", 1, font, &rect, format, &bounds_1, NULL, NULL);
expect(Ok, status);
/* bounds.width of 2 identical glyphs: [margin]+[width]+[width]+[margin] */
set_rect_empty(&rect);
set_rect_empty(&bounds_2);
- status = GdipMeasureString(graphics, doubleW, 2, font, &rect, format, &bounds_2, NULL, NULL);
+ status = GdipMeasureString(graphics, L"WW", 2, font, &rect, format, &bounds_2, NULL, NULL);
expect(Ok, status);
/* margin = [bounds.width of 1] - [bounds.width of 2] / 2*/
@@ -4444,8 +4443,8 @@ cleanup:
static void test_measure_string(void)
{
- static const WCHAR string[] = { 'A','0','1',0 };
- static const WCHAR string2[] = { 'M',' ','M','M',0 };
+ static const WCHAR string[] = L"A01";
+ static const WCHAR string2[] = "M MM";
HDC hdc;
GpStringFormat *format, *format_no_wrap;
CharacterRange range;
@@ -4915,7 +4914,6 @@ todo_wine
static void test_measured_extra_space(void)
{
- static const WCHAR string[2] = { 'W','W' };
GpStringFormat *format;
HDC hdc;
GpGraphics *graphics;
@@ -4959,12 +4957,12 @@ static void test_measured_extra_space(void)
/* bounds.width of 1 glyph: [margin]+[width]+[margin] */
set_rect_empty(&rect);
set_rect_empty(&bounds_1);
- status = GdipMeasureString(graphics, string, 1, font, &rect, format, &bounds_1, NULL, NULL);
+ status = GdipMeasureString(graphics, L"W", 1, font, &rect, format, &bounds_1, NULL, NULL);
expect(Ok, status);
/* bounds.width of 2 identical glyphs: [margin]+[width]+[width]+[margin] */
set_rect_empty(&rect);
set_rect_empty(&bounds_2);
- status = GdipMeasureString(graphics, string, 2, font, &rect, format, &bounds_2, NULL, NULL);
+ status = GdipMeasureString(graphics, L"WW", 2, font, &rect, format, &bounds_2, NULL, NULL);
expect(Ok, status);
/* margin = [bounds.width of 1] - [bounds.width of 2] / 2*/
--
2.23.0
Dec. 9, 2020
[PATCH 4/5] gdiplus/tests: Use wide-char string literal for metafile description.
by Jeff Smith
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/gdiplus/tests/metafile.c | 19 ++-----------------
1 file changed, 2 insertions(+), 17 deletions(-)
diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c
index eaad4acdc69..3ce7a16d61a 100644
--- a/dlls/gdiplus/tests/metafile.c
+++ b/dlls/gdiplus/tests/metafile.c
@@ -31,6 +31,8 @@
static BOOL save_metafiles;
static BOOL load_metafiles;
+static const WCHAR description[] = L"winetest";
+
typedef struct emfplus_record
{
DWORD record_type;
@@ -378,7 +380,6 @@ static void test_empty(void)
MetafileHeader header;
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
UINT limit_dpi;
hdc = CreateCompatibleDC(0);
@@ -626,7 +627,6 @@ static void test_getdc(void)
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
static const GpPointF dst_points_half[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
HBRUSH hbrush, holdbrush;
GpBitmap *bitmap;
ARGB color;
@@ -784,7 +784,6 @@ static void test_emfonly(void)
MetafileHeader header;
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
HBRUSH hbrush, holdbrush;
GpBitmap *bitmap;
ARGB color;
@@ -1081,7 +1080,6 @@ static void test_fillrect(void)
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
static const GpPointF dst_points_half[3] = {{0.0,0.0},{50.0,0.0},{0.0,50.0}};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
GpBitmap *bitmap;
ARGB color;
GpBrush *brush;
@@ -1194,7 +1192,6 @@ static void test_clear(void)
HENHMETAFILE hemf;
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{10.0,10.0},{20.0,10.0},{10.0,20.0}};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
GpBitmap *bitmap;
ARGB color;
@@ -1266,7 +1263,6 @@ static void test_nullframerect(void) {
GpMetafile *metafile;
GpGraphics *graphics;
HDC hdc, metafile_dc;
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
GpBrush *brush;
HBRUSH hbrush, holdbrush;
GpRectF bounds;
@@ -1459,7 +1455,6 @@ static void test_pagetransform(void)
HDC hdc;
static const GpRectF frame = {0.0, 0.0, 5.0, 5.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
GpBitmap *bitmap;
ARGB color;
GpBrush *brush;
@@ -1664,7 +1659,6 @@ static void test_worldtransform(void)
HDC hdc;
static const GpRectF frame = {0.0, 0.0, 5.0, 5.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
GpBitmap *bitmap;
ARGB color;
GpBrush *brush;
@@ -1921,7 +1915,6 @@ static void test_converttoemfplus(void)
GpStatus (WINAPI *pGdipConvertToEmfPlus)( const GpGraphics *graphics, GpMetafile *metafile, BOOL *succ,
EmfType emfType, const WCHAR *description, GpMetafile **outmetafile);
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
GpStatus stat;
GpMetafile *metafile, *metafile2 = NULL, *emhmeta;
GpGraphics *graphics;
@@ -2001,7 +1994,6 @@ static void test_frameunit(void)
GpGraphics *graphics;
HDC hdc;
static const GpRectF frame = {0.0, 0.0, 5.0, 5.0};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
GpUnit unit;
REAL dpix, dpiy;
GpRectF bounds;
@@ -2097,7 +2089,6 @@ static void test_containers(void)
HDC hdc;
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
GraphicsContainer state1, state2;
GpRectF srcrect, dstrect;
REAL dpix, dpiy;
@@ -2293,7 +2284,6 @@ static void test_clipping(void)
HDC hdc;
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{100.0,0.0},{0.0,100.0}};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
GraphicsState state;
hdc = CreateCompatibleDC(0);
@@ -2434,7 +2424,6 @@ static void test_gditransform(void)
MetafileHeader header;
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
static const GpPointF dst_points[3] = {{0.0,0.0},{40.0,0.0},{0.0,40.0}};
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
HBRUSH hbrush, holdbrush;
GpBitmap *bitmap;
ARGB color;
@@ -2561,7 +2550,6 @@ static const emfplus_record draw_image_metafile_records[] = {
static void test_drawimage(void)
{
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
static const GpPointF dst_points[3] = {{10.0,10.0},{85.0,15.0},{10.0,80.0}};
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
const ColorMatrix double_red = {{
@@ -2679,7 +2667,6 @@ static const emfplus_record properties_records[] = {
static void test_properties(void)
{
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
GpMetafile *metafile;
@@ -2757,7 +2744,6 @@ static const emfplus_record draw_path_records[] = {
static void test_drawpath(void)
{
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
GpMetafile *metafile;
@@ -2822,7 +2808,6 @@ static const emfplus_record fill_path_records[] = {
static void test_fillpath(void)
{
- static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
GpMetafile *metafile;
--
2.23.0
Dec. 9, 2020
[PATCH 3/5] gdiplus/tests: Use wide-char string literal for mimetype.
by Jeff Smith
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/gdiplus/tests/image.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index c1f3b126a79..2175c1748e0 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -537,7 +537,6 @@ static void test_SavingMultiPageTiff(void)
static const CHAR filename2A[] = "2.tif";
static const WCHAR filename1[] = L"1.tif";
static const WCHAR filename2[] = L"2.tif";
- static const WCHAR tiff_mimetype[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
params.Count = 1;
params.Parameter[0].Guid = EncoderSaveFlag;
@@ -549,7 +548,7 @@ static void test_SavingMultiPageTiff(void)
expect(Ok, stat);
stat = GdipCreateBitmapFromScan0(2 * WIDTH, 2 * HEIGHT, 0, PixelFormat24bppRGB, NULL, &bm2);
expect(Ok, stat);
- result = get_encoder_clsid(tiff_mimetype, &format, &tiff_clsid);
+ result = get_encoder_clsid(L"image/tiff", &format, &tiff_clsid);
ok(result, "getting TIFF encoding clsid failed");
if (!bm1 || !bm2 || !result)
--
2.23.0
Dec. 9, 2020
[PATCH 2/5] gdiplus/tests: Use wide-char string literals for file names.
by Jeff Smith
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/gdiplus/tests/font.c | 3 +--
dlls/gdiplus/tests/image.c | 13 ++++++-------
dlls/gdiplus/tests/metafile.c | 9 ++++-----
3 files changed, 11 insertions(+), 14 deletions(-)
diff --git a/dlls/gdiplus/tests/font.c b/dlls/gdiplus/tests/font.c
index 2fcdb3a37da..0d7254f255e 100644
--- a/dlls/gdiplus/tests/font.c
+++ b/dlls/gdiplus/tests/font.c
@@ -69,7 +69,6 @@ static void _delete_testfontfile(const WCHAR *filename, int line)
static void test_long_name(void)
{
WCHAR path[MAX_PATH];
- static const WCHAR path_longname[] = {'w','i','n','e','_','l','o','n','g','n','a','m','e','.','t','t','f',0};
GpStatus stat;
GpFontCollection *fonts;
INT num_families;
@@ -80,7 +79,7 @@ static void test_long_name(void)
stat = GdipNewPrivateFontCollection(&fonts);
ok(stat == Ok, "GdipNewPrivateFontCollection failed: %d\n", stat);
- create_testfontfile(path_longname, 1, path);
+ create_testfontfile(L"wine_longname.ttf", 1, path);
stat = GdipPrivateAddFontFile(fonts, path);
ok(stat == Ok, "GdipPrivateAddFontFile failed: %d\n", stat);
diff --git a/dlls/gdiplus/tests/image.c b/dlls/gdiplus/tests/image.c
index 93729650de8..c1f3b126a79 100644
--- a/dlls/gdiplus/tests/image.c
+++ b/dlls/gdiplus/tests/image.c
@@ -417,7 +417,6 @@ static void test_LoadingImages(void)
GpStatus stat;
GpBitmap *bm;
GpImage *img;
- static const WCHAR nonexistentW[] = {'n','o','n','e','x','i','s','t','e','n','t',0};
stat = GdipCreateBitmapFromFile(0, 0);
expect(InvalidParameter, stat);
@@ -428,7 +427,7 @@ static void test_LoadingImages(void)
ok(bm == (GpBitmap *)0xdeadbeef, "returned %p\n", bm);
bm = (GpBitmap *)0xdeadbeef;
- stat = GdipCreateBitmapFromFile(nonexistentW, &bm);
+ stat = GdipCreateBitmapFromFile(L"nonexistent", &bm);
todo_wine expect(InvalidParameter, stat);
ok(!bm, "returned %p\n", bm);
@@ -441,7 +440,7 @@ static void test_LoadingImages(void)
ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
img = (GpImage *)0xdeadbeef;
- stat = GdipLoadImageFromFile(nonexistentW, &img);
+ stat = GdipLoadImageFromFile(L"nonexistent", &img);
todo_wine expect(OutOfMemory, stat);
ok(!img, "returned %p\n", img);
@@ -454,7 +453,7 @@ static void test_LoadingImages(void)
ok(img == (GpImage *)0xdeadbeef, "returned %p\n", img);
img = (GpImage *)0xdeadbeef;
- stat = GdipLoadImageFromFileICM(nonexistentW, &img);
+ stat = GdipLoadImageFromFileICM(L"nonexistent", &img);
todo_wine expect(OutOfMemory, stat);
ok(!img, "returned %p\n", img);
}
@@ -469,7 +468,7 @@ static void test_SavingImages(void)
REAL w, h;
ImageCodecInfo *codecs;
static const CHAR filenameA[] = "a.bmp";
- static const WCHAR filename[] = { 'a','.','b','m','p',0 };
+ static const WCHAR filename[] = L"a.bmp";
codecs = NULL;
@@ -536,8 +535,8 @@ static void test_SavingMultiPageTiff(void)
UINT frame_count;
static const CHAR filename1A[] = "1.tif";
static const CHAR filename2A[] = "2.tif";
- static const WCHAR filename1[] = { '1','.','t','i','f',0 };
- static const WCHAR filename2[] = { '2','.','t','i','f',0 };
+ static const WCHAR filename1[] = L"1.tif";
+ static const WCHAR filename2[] = L"2.tif";
static const WCHAR tiff_mimetype[] = { 'i','m','a','g','e','/','t','i','f','f',0 };
params.Count = 1;
diff --git a/dlls/gdiplus/tests/metafile.c b/dlls/gdiplus/tests/metafile.c
index 33fff3f98cf..eaad4acdc69 100644
--- a/dlls/gdiplus/tests/metafile.c
+++ b/dlls/gdiplus/tests/metafile.c
@@ -2824,7 +2824,6 @@ static void test_fillpath(void)
{
static const WCHAR description[] = {'w','i','n','e','t','e','s','t',0};
static const GpRectF frame = {0.0, 0.0, 100.0, 100.0};
- static const WCHAR winetestemfW[] = {'w','i','n','e','t','e','s','t','.','e','m','f',0};
GpMetafile *metafile;
GpGraphics *graphics;
@@ -2870,7 +2869,7 @@ static void test_fillpath(void)
check_emfplus(hemf, fill_path_records, "fill path");
/* write to disk */
- DeleteEnhMetaFile(CopyEnhMetaFileW(hemf, winetestemfW));
+ DeleteEnhMetaFile(CopyEnhMetaFileW(hemf, L"winetest.emf"));
DeleteEnhMetaFile(hemf);
@@ -2878,15 +2877,15 @@ static void test_fillpath(void)
expect(Ok, stat);
/* should succeed when given path to an EMF */
- stat = GdipCreateMetafileFromWmfFile(winetestemfW, NULL, &metafile);
+ stat = GdipCreateMetafileFromWmfFile(L"winetest.emf", NULL, &metafile);
expect(Ok, stat);
stat = GdipDisposeImage((GpImage*)metafile);
expect(Ok, stat);
- DeleteFileW(winetestemfW);
+ DeleteFileW(L"winetest.emf");
- stat = GdipCreateMetafileFromWmfFile(winetestemfW, NULL, &metafile);
+ stat = GdipCreateMetafileFromWmfFile(L"winetest.emf", NULL, &metafile);
expect(GenericError, stat);
}
--
2.23.0
Dec. 9, 2020
[PATCH 1/5] gdiplus/tests: Use wide-char string literals for font names.
by Jeff Smith
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/gdiplus/tests/font.c | 43 ++++++++++++++++-------------------
dlls/gdiplus/tests/graphics.c | 15 ++++--------
2 files changed, 24 insertions(+), 34 deletions(-)
diff --git a/dlls/gdiplus/tests/font.c b/dlls/gdiplus/tests/font.c
index af90152aa26..2fcdb3a37da 100644
--- a/dlls/gdiplus/tests/font.c
+++ b/dlls/gdiplus/tests/font.c
@@ -30,11 +30,6 @@
#define expectf_(expected, got, precision) ok(fabs((expected) - (got)) <= (precision), "Expected %f, got %f\n", (expected), (got))
#define expectf(expected, got) expectf_((expected), (got), 0.001)
-static const WCHAR nonexistent[] = {'T','h','i','s','F','o','n','t','s','h','o','u','l','d','N','o','t','E','x','i','s','t','\0'};
-static const WCHAR MSSansSerif[] = {'M','S',' ','S','a','n','s',' ','S','e','r','i','f','\0'};
-static const WCHAR TimesNewRoman[] = {'T','i','m','e','s',' ','N','e','w',' ','R','o','m','a','n','\0'};
-static const WCHAR Tahoma[] = {'T','a','h','o','m','a',0};
-
static void set_rect_empty(RectF *rc)
{
rc->X = 0.0;
@@ -125,11 +120,11 @@ static void test_createfont(void)
REAL size;
WCHAR familyname[LF_FACESIZE];
- stat = GdipCreateFontFamilyFromName(nonexistent, NULL, &fontfamily);
+ stat = GdipCreateFontFamilyFromName(L"ThisFontShouldNotExist", NULL, &fontfamily);
expect (FontFamilyNotFound, stat);
stat = GdipDeleteFont(font);
expect (InvalidParameter, stat);
- stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
+ stat = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &fontfamily);
expect (Ok, stat);
stat = GdipCreateFont(fontfamily, 12, FontStyleRegular, UnitPoint, &font);
expect (Ok, stat);
@@ -142,7 +137,7 @@ static void test_createfont(void)
stat = GdipGetFamilyName(fontfamily2, familyname, 0);
expect(Ok, stat);
ok (fontfamily == fontfamily2, "Unexpected family instance.\n");
- ok (lstrcmpiW(Tahoma, familyname) == 0, "Expected Tahoma, got %s\n",
+ ok (lstrcmpiW(L"Tahoma", familyname) == 0, "Expected Tahoma, got %s\n",
wine_dbgstr_w(familyname));
stat = GdipDeleteFontFamily(fontfamily2);
expect(Ok, stat);
@@ -362,26 +357,26 @@ static void test_fontfamily (void)
GpStatus stat;
/* FontFamily cannot be NULL */
- stat = GdipCreateFontFamilyFromName (Tahoma , NULL, NULL);
+ stat = GdipCreateFontFamilyFromName (L"Tahoma" , NULL, NULL);
expect (InvalidParameter, stat);
/* FontFamily must be able to actually find the family.
* If it can't, any subsequent calls should fail.
*/
- stat = GdipCreateFontFamilyFromName (nonexistent, NULL, &family);
+ stat = GdipCreateFontFamilyFromName (L"ThisFontShouldNotExist", NULL, &family);
expect (FontFamilyNotFound, stat);
/* Bitmap fonts are not found */
- stat = GdipCreateFontFamilyFromName (MSSansSerif, NULL, &family);
+ stat = GdipCreateFontFamilyFromName (L"MS Sans Serif", NULL, &family);
expect (FontFamilyNotFound, stat);
if(stat == Ok) GdipDeleteFontFamily(family);
- stat = GdipCreateFontFamilyFromName (Tahoma, NULL, &family);
+ stat = GdipCreateFontFamilyFromName (L"Tahoma", NULL, &family);
expect (Ok, stat);
stat = GdipGetFamilyName (family, itsName, LANG_NEUTRAL);
expect (Ok, stat);
- expect (0, lstrcmpiW(itsName, Tahoma));
+ expect (0, lstrcmpiW(itsName, L"Tahoma"));
if (0)
{
@@ -398,7 +393,7 @@ static void test_fontfamily (void)
GdipDeleteFontFamily(family);
stat = GdipGetFamilyName(clonedFontFamily, itsName, LANG_NEUTRAL);
expect(Ok, stat);
- expect(0, lstrcmpiW(itsName, Tahoma));
+ expect(0, lstrcmpiW(itsName, L"Tahoma"));
GdipDeleteFontFamily(clonedFontFamily);
}
@@ -409,7 +404,7 @@ static void test_fontfamily_properties (void)
GpStatus stat;
UINT16 result = 0;
- stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &FontFamily);
+ stat = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &FontFamily);
expect(Ok, stat);
stat = GdipGetLineSpacing(FontFamily, FontStyleRegular, &result);
@@ -429,7 +424,7 @@ static void test_fontfamily_properties (void)
ok(result == 423, "Expected 423, got %d\n", result);
GdipDeleteFontFamily(FontFamily);
- stat = GdipCreateFontFamilyFromName(TimesNewRoman, NULL, &FontFamily);
+ stat = GdipCreateFontFamilyFromName(L"Times New Roman", NULL, &FontFamily);
if(stat == FontFamilyNotFound)
skip("Times New Roman not installed\n");
else
@@ -533,7 +528,7 @@ static void test_heightgivendpi(void)
REAL height;
Unit unit;
- stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &fontfamily);
+ stat = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &fontfamily);
expect(Ok, stat);
stat = GdipCreateFont(fontfamily, 30, FontStyleRegular, UnitPixel, &font);
@@ -734,7 +729,7 @@ static void test_font_metrics(void)
memset(&lf, 0, sizeof(lf));
/* Tahoma,-13 */
- lstrcpyW(lf.lfFaceName, Tahoma);
+ lstrcpyW(lf.lfFaceName, L"Tahoma");
lf.lfHeight = -13;
stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
expect(Ok, stat);
@@ -775,7 +770,7 @@ static void test_font_metrics(void)
GdipDeleteFont(font);
/* Tahoma,13 */
- lstrcpyW(lf.lfFaceName, Tahoma);
+ lstrcpyW(lf.lfFaceName, L"Tahoma");
lf.lfHeight = 13;
stat = GdipCreateFontFromLogfontW(hdc, &lf, &font);
expect(Ok, stat);
@@ -815,7 +810,7 @@ static void test_font_metrics(void)
GdipDeleteFont(font);
- stat = GdipCreateFontFamilyFromName(Tahoma, NULL, &family);
+ stat = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &family);
expect(Ok, stat);
/* Tahoma,13 */
@@ -892,7 +887,7 @@ static void test_font_substitution(void)
GdipDeleteFont(font);
GdipDeleteFontFamily(family);
- status = GdipCreateFontFamilyFromName(nonexistent, NULL, &family);
+ status = GdipCreateFontFamilyFromName(L"ThisFontShouldNotExist", NULL, &family);
ok(status == FontFamilyNotFound, "expected FontFamilyNotFound, got %d\n", status);
/* nonexistent fonts fallback to Arial, or something else if it's missing */
@@ -1364,13 +1359,13 @@ static void test_CloneFont(void)
expect(Ok, status);
ok(collection == collection2, "got %p\n", collection2);
- status = GdipCreateFontFamilyFromName(nonexistent, NULL, &family);
+ status = GdipCreateFontFamilyFromName(L"ThisFontShouldNotExist", NULL, &family);
expect(FontFamilyNotFound, status);
- status = GdipCreateFontFamilyFromName(nonexistent, collection, &family);
+ status = GdipCreateFontFamilyFromName(L"ThisFontShouldNotExist", collection, &family);
expect(FontFamilyNotFound, status);
- status = GdipCreateFontFamilyFromName(Tahoma, NULL, &family);
+ status = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &family);
expect(Ok, status);
ret = is_family_in_collection(collection, family);
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c
index d1022b1af5b..9a09abcfc8b 100644
--- a/dlls/gdiplus/tests/graphics.c
+++ b/dlls/gdiplus/tests/graphics.c
@@ -3195,7 +3195,6 @@ static void test_string_functions(void)
GpBrush *brush;
ARGB color = 0xff000000;
HDC hdc = GetDC( hwnd );
- const WCHAR fontname[] = {'T','a','h','o','m','a',0};
const WCHAR teststring[] = {'M','M',' ','M','\n','M',0};
const WCHAR teststring2[] = {'j',0};
REAL char_width, char_height;
@@ -3213,7 +3212,7 @@ static void test_string_functions(void)
expect(Ok, status);
ok(graphics != NULL, "Expected graphics to be initialized\n");
- status = GdipCreateFontFamilyFromName(fontname, NULL, &family);
+ status = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &family);
expect(Ok, status);
status = GdipCreateFont(family, 10.0, FontStyleRegular, UnitPixel, &font);
@@ -3744,7 +3743,6 @@ static void test_GdipMeasureString(void)
{ 200.0, 600.0, 1.0, UnitPixel },
{ 200.0, 600.0, 2.0, UnitPixel },
};
- static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
GpStatus status;
GpGraphics *graphics;
@@ -3761,7 +3759,7 @@ static void test_GdipMeasureString(void)
status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
expect(Ok, status);
- status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
+ status = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &family);
expect(Ok, status);
/* font size in pixels */
@@ -4259,7 +4257,6 @@ static void test_pen_thickness(void)
*/
static void test_font_height_scaling(void)
{
- static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
static const WCHAR string[] = { '1','2','3','4','5','6','7',0 };
HDC hdc;
GpStringFormat *format;
@@ -4281,7 +4278,7 @@ static void test_font_height_scaling(void)
status = GdipCreateRegion(®ion);
expect(Ok, status);
- status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
+ status = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &family);
expect(Ok, status);
hdc = CreateCompatibleDC(0);
@@ -4447,7 +4444,6 @@ cleanup:
static void test_measure_string(void)
{
- static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
static const WCHAR string[] = { 'A','0','1',0 };
static const WCHAR string2[] = { 'M',' ','M','M',0 };
HDC hdc;
@@ -4470,7 +4466,7 @@ static void test_measure_string(void)
status = GdipCreateRegion(®ion);
expect(Ok, status);
- status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
+ status = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &family);
expect(Ok, status);
hdc = CreateCompatibleDC(0);
@@ -4919,7 +4915,6 @@ todo_wine
static void test_measured_extra_space(void)
{
- static const WCHAR tahomaW[] = { 'T','a','h','o','m','a',0 };
static const WCHAR string[2] = { 'W','W' };
GpStringFormat *format;
HDC hdc;
@@ -4934,7 +4929,7 @@ static void test_measured_extra_space(void)
status = GdipCreateStringFormat(0, LANG_NEUTRAL, &format);
expect(Ok, status);
- status = GdipCreateFontFamilyFromName(tahomaW, NULL, &family);
+ status = GdipCreateFontFamilyFromName(L"Tahoma", NULL, &family);
expect(Ok, status);
hdc = CreateCompatibleDC(0);
status = GdipCreateFromHDC(hdc, &graphics);
--
2.23.0
Dec. 9, 2020
[PATCH] iphlpapi/tests: Skip Get[Icmp|Ip|Udp]StatisticsEx AF_INET6 tests on platforms where support is missing.
by Gijs Vermeulen
Signed-off-by: Gijs Vermeulen <gijsvrm(a)gmail.com>
---
dlls/iphlpapi/tests/iphlpapi.c | 105 +++++++++++++++++++--------------
1 file changed, 60 insertions(+), 45 deletions(-)
diff --git a/dlls/iphlpapi/tests/iphlpapi.c b/dlls/iphlpapi/tests/iphlpapi.c
index 6cbe725bada..203aefb9f69 100644
--- a/dlls/iphlpapi/tests/iphlpapi.c
+++ b/dlls/iphlpapi/tests/iphlpapi.c
@@ -579,16 +579,21 @@ static void testGetIcmpStatisticsEx(void)
}
apiReturn = GetIcmpStatisticsEx(&stats, AF_INET6);
- ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
- "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
- if (apiReturn == NO_ERROR && winetest_debug > 1)
+ if (!strcmp(winetest_platform, "wine") && apiReturn == ERROR_NOT_SUPPORTED)
+ skip("GetIcmpStatisticsEx(AF_INET6) not supported\n");
+ else
{
- INT i;
- trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" );
- trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
- trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
- for (i = 0; i < 256; i++)
- trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
+ ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
+ "GetIcmpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
+ if (apiReturn == NO_ERROR && winetest_debug > 1)
+ {
+ INT i;
+ trace( "ICMP IPv6 Ex stats: %8s %8s\n", "in", "out" );
+ trace( " dwMsgs: %8u %8u\n", stats.icmpInStats.dwMsgs, stats.icmpOutStats.dwMsgs );
+ trace( " dwErrors: %8u %8u\n", stats.icmpInStats.dwErrors, stats.icmpOutStats.dwErrors );
+ for (i = 0; i < 256; i++)
+ trace( " rgdwTypeCount[%3i]: %8u %8u\n", i, stats.icmpInStats.rgdwTypeCount[i], stats.icmpOutStats.rgdwTypeCount[i] );
+ }
}
}
@@ -636,34 +641,39 @@ static void testGetIpStatisticsEx(void)
}
apiReturn = GetIpStatisticsEx(&stats, AF_INET6);
- ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
- "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
- if (apiReturn == NO_ERROR && winetest_debug > 1)
+ if (!strcmp(winetest_platform, "wine") && apiReturn == ERROR_NOT_SUPPORTED)
+ skip("GetIpStatisticsEx(AF_INET6) not supported\n");
+ else
{
- trace( "IP IPv6 Ex stats:\n" );
- trace( " dwForwarding: %u\n", U(stats).dwForwarding );
- trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
- trace( " dwInReceives: %u\n", stats.dwInReceives );
- trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
- trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
- trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
- trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
- trace( " dwInDiscards: %u\n", stats.dwInDiscards );
- trace( " dwInDelivers: %u\n", stats.dwInDelivers );
- trace( " dwOutRequests: %u\n", stats.dwOutRequests );
- trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
- trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
- trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
- trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
- trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
- trace( " dwReasmOks: %u\n", stats.dwReasmOks );
- trace( " dwReasmFails: %u\n", stats.dwReasmFails );
- trace( " dwFragOks: %u\n", stats.dwFragOks );
- trace( " dwFragFails: %u\n", stats.dwFragFails );
- trace( " dwFragCreates: %u\n", stats.dwFragCreates );
- trace( " dwNumIf: %u\n", stats.dwNumIf );
- trace( " dwNumAddr: %u\n", stats.dwNumAddr );
- trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
+ ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
+ "GetIpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
+ if (apiReturn == NO_ERROR && winetest_debug > 1)
+ {
+ trace( "IP IPv6 Ex stats:\n" );
+ trace( " dwForwarding: %u\n", U(stats).dwForwarding );
+ trace( " dwDefaultTTL: %u\n", stats.dwDefaultTTL );
+ trace( " dwInReceives: %u\n", stats.dwInReceives );
+ trace( " dwInHdrErrors: %u\n", stats.dwInHdrErrors );
+ trace( " dwInAddrErrors: %u\n", stats.dwInAddrErrors );
+ trace( " dwForwDatagrams: %u\n", stats.dwForwDatagrams );
+ trace( " dwInUnknownProtos: %u\n", stats.dwInUnknownProtos );
+ trace( " dwInDiscards: %u\n", stats.dwInDiscards );
+ trace( " dwInDelivers: %u\n", stats.dwInDelivers );
+ trace( " dwOutRequests: %u\n", stats.dwOutRequests );
+ trace( " dwRoutingDiscards: %u\n", stats.dwRoutingDiscards );
+ trace( " dwOutDiscards: %u\n", stats.dwOutDiscards );
+ trace( " dwOutNoRoutes: %u\n", stats.dwOutNoRoutes );
+ trace( " dwReasmTimeout: %u\n", stats.dwReasmTimeout );
+ trace( " dwReasmReqds: %u\n", stats.dwReasmReqds );
+ trace( " dwReasmOks: %u\n", stats.dwReasmOks );
+ trace( " dwReasmFails: %u\n", stats.dwReasmFails );
+ trace( " dwFragOks: %u\n", stats.dwFragOks );
+ trace( " dwFragFails: %u\n", stats.dwFragFails );
+ trace( " dwFragCreates: %u\n", stats.dwFragCreates );
+ trace( " dwNumIf: %u\n", stats.dwNumIf );
+ trace( " dwNumAddr: %u\n", stats.dwNumAddr );
+ trace( " dwNumRoutes: %u\n", stats.dwNumRoutes );
+ }
}
}
@@ -752,16 +762,21 @@ static void testGetUdpStatisticsEx(void)
}
apiReturn = GetUdpStatisticsEx(&stats, AF_INET6);
- ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
- "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
- if (apiReturn == NO_ERROR && winetest_debug > 1)
+ if (!strcmp(winetest_platform, "wine") && apiReturn == ERROR_NOT_SUPPORTED)
+ skip("GetUdpStatisticsEx(AF_INET6) not supported\n");
+ else
{
- trace( "UDP IPv6 Ex stats:\n" );
- trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
- trace( " dwNoPorts: %u\n", stats.dwNoPorts );
- trace( " dwInErrors: %u\n", stats.dwInErrors );
- trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
- trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
+ ok(apiReturn == NO_ERROR || broken(apiReturn == ERROR_NOT_SUPPORTED),
+ "GetUdpStatisticsEx returned %d, expected NO_ERROR\n", apiReturn);
+ if (apiReturn == NO_ERROR && winetest_debug > 1)
+ {
+ trace( "UDP IPv6 Ex stats:\n" );
+ trace( " dwInDatagrams: %u\n", stats.dwInDatagrams );
+ trace( " dwNoPorts: %u\n", stats.dwNoPorts );
+ trace( " dwInErrors: %u\n", stats.dwInErrors );
+ trace( " dwOutDatagrams: %u\n", stats.dwOutDatagrams );
+ trace( " dwNumAddrs: %u\n", stats.dwNumAddrs );
+ }
}
}
--
2.29.2
Dec. 8, 2020
[PATCH] version/tests: Use wide-char string literals.
by Michael Stefaniuc
Constify some variables in that process.
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/version/tests/info.c | 35 ++++++++++++++---------------------
1 file changed, 14 insertions(+), 21 deletions(-)
diff --git a/dlls/version/tests/info.c b/dlls/version/tests/info.c
index 44e7511d8b1..f35af902f9b 100644
--- a/dlls/version/tests/info.c
+++ b/dlls/version/tests/info.c
@@ -292,19 +292,13 @@ static void test_32bit_win(void)
UINT uiLengthA, uiLengthW;
char mypathA[MAX_PATH];
WCHAR mypathW[MAX_PATH];
- char rootA[] = "\\";
- WCHAR rootW[] = { '\\', 0 };
- WCHAR emptyW[] = { 0 };
- char varfileinfoA[] = "\\VarFileInfo\\Translation";
- WCHAR varfileinfoW[] = { '\\','V','a','r','F','i','l','e','I','n','f','o',
- '\\','T','r','a','n','s','l','a','t','i','o','n', 0 };
- char WineVarFileInfoA[] = { 0x09, 0x04, 0xE4, 0x04 };
- char FileDescriptionA[] = "\\StringFileInfo\\040904E4\\FileDescription";
- WCHAR FileDescriptionW[] = { '\\','S','t','r','i','n','g','F','i','l','e','I','n','f','o',
- '\\','0','4','0','9','0','4','E','4',
- '\\','F','i','l','e','D','e','s','c','r','i','p','t','i','o','n', 0 };
- char WineFileDescriptionA[] = "FileDescription";
- WCHAR WineFileDescriptionW[] = { 'F','i','l','e','D','e','s','c','r','i','p','t','i','o','n', 0 };
+ const char varfileinfoA[] = "\\VarFileInfo\\Translation";
+ const WCHAR varfileinfoW[] = L"\\VarFileInfo\\Translation";
+ const char WineVarFileInfoA[] = { 0x09, 0x04, 0xE4, 0x04 };
+ const char FileDescriptionA[] = "\\StringFileInfo\\040904E4\\FileDescription";
+ const WCHAR FileDescriptionW[] = L"\\StringFileInfo\\040904E4\\FileDescription";
+ const char WineFileDescriptionA[] = "FileDescription";
+ const WCHAR WineFileDescriptionW[] = L"FileDescription";
BOOL is_unicode_enabled = TRUE;
/* A copy from dlls/version/info.c */
@@ -397,7 +391,7 @@ static void test_32bit_win(void)
/* Get the VS_FIXEDFILEINFO information, this must be the same for both A- and W-Calls */
- retA = VerQueryValueA( pVersionInfoA, rootA, (LPVOID *)&pBufA, &uiLengthA );
+ retA = VerQueryValueA( pVersionInfoA, "\\", (void **)&pBufA, &uiLengthA );
ok (retA, "VerQueryValueA failed: GetLastError = %u\n", GetLastError());
ok ( uiLengthA == sizeof(VS_FIXEDFILEINFO), "Size (%d) doesn't match the size of the VS_FIXEDFILEINFO struct\n", uiLengthA);
@@ -409,10 +403,10 @@ static void test_32bit_win(void)
ok (retW, "VerQueryValueW failed: GetLastError = %u\n", GetLastError());
}
- retW = VerQueryValueW( pVersionInfoW, emptyW, (LPVOID *)&pBufW, &uiLengthW );
+ retW = VerQueryValueW( pVersionInfoW, L"", (void **)&pBufW, &uiLengthW );
ok (retW, "VerQueryValueW failed: GetLastError = %u\n", GetLastError());
- retW = VerQueryValueW( pVersionInfoW, rootW, (LPVOID *)&pBufW, &uiLengthW );
+ retW = VerQueryValueW( pVersionInfoW, L"\\", (void **)&pBufW, &uiLengthW );
ok (retW, "VerQueryValueW failed: GetLastError = %u\n", GetLastError());
ok ( uiLengthW == sizeof(VS_FIXEDFILEINFO), "Size (%d) doesn't match the size of the VS_FIXEDFILEINFO struct\n", uiLengthW );
@@ -639,7 +633,6 @@ static void test_GetFileVersionInfoEx(void)
const LANGID lang = GetUserDefaultUILanguage();
const LANGID english = MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT);
const WORD unicode = 1200; /* = UNICODE */
- const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
const DWORD test_flags[] = {
0, FILE_VER_GET_LOCALISED, FILE_VER_GET_NEUTRAL,
FILE_VER_GET_LOCALISED | FILE_VER_GET_NEUTRAL,
@@ -658,13 +651,13 @@ static void test_GetFileVersionInfoEx(void)
return;
}
- size = GetFileVersionInfoSizeW(kernel32W, NULL);
+ size = GetFileVersionInfoSizeW(L"kernel32.dll", NULL);
ok(size, "GetFileVersionInfoSize(kernel32) error %u\n", GetLastError());
ver = HeapAlloc(GetProcessHeap(), 0, size);
assert(ver);
- ret = GetFileVersionInfoW(kernel32W, 0, size, ver);
+ ret = GetFileVersionInfoW(L"kernel32.dll", 0, size, ver);
ok(ret, "GetFileVersionInfo error %u\n", GetLastError());
ret = VerQueryValueA(ver, "\\VarFileInfo\\Translation", (void **)&p, &size);
@@ -694,13 +687,13 @@ static void test_GetFileVersionInfoEx(void)
for (i = 0; i < ARRAY_SIZE(test_flags); i++)
{
- size = pGetFileVersionInfoSizeExW(test_flags[i], kernel32W, NULL);
+ size = pGetFileVersionInfoSizeExW(test_flags[i], L"kernel32.dll", NULL);
ok(size, "[%u] GetFileVersionInfoSizeEx(kernel32) error %u\n", i, GetLastError());
ver = HeapAlloc(GetProcessHeap(), 0, size);
assert(ver);
- ret = pGetFileVersionInfoExW(test_flags[i], kernel32W, 0, size, ver);
+ ret = pGetFileVersionInfoExW(test_flags[i], L"kernel32.dll", 0, size, ver);
ok(ret, "[%u] GetFileVersionInfoEx error %u\n", i, GetLastError());
ret = VerQueryValueA(ver, "\\VarFileInfo\\Translation", (void **)&p, &size);
--
2.26.2
Dec. 8, 2020
[PATCH] shcore/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/shcore/tests/shcore.c | 46 +++++++++++++++++---------------------
1 file changed, 20 insertions(+), 26 deletions(-)
diff --git a/dlls/shcore/tests/shcore.c b/dlls/shcore/tests/shcore.c
index 2a8ebcc4686..a75bfd899eb 100644
--- a/dlls/shcore/tests/shcore.c
+++ b/dlls/shcore/tests/shcore.c
@@ -166,8 +166,6 @@ static void test_process_reference(void)
static void test_SHUnicodeToAnsi(void)
{
- static const WCHAR testW[] = {'t','e','s','t',0};
- static const WCHAR emptyW[] = { 0 };
char buff[16];
int ret;
@@ -186,32 +184,31 @@ static void test_SHUnicodeToAnsi(void)
buff[0] = 1;
strcpy(buff, "test");
- ret = pSHUnicodeToAnsi(emptyW, buff, 1);
+ ret = pSHUnicodeToAnsi(L"", buff, 1);
ok(ret == 1, "Unexpected return value %d.\n", ret);
ok(*buff == 0, "Unexpected buffer contents.\n");
buff[0] = 1;
- ret = pSHUnicodeToAnsi(testW, buff, 0);
+ ret = pSHUnicodeToAnsi(L"test", buff, 0);
ok(ret == 0, "Unexpected return value %d.\n", ret);
ok(buff[0] == 1, "Unexpected buffer contents.\n");
buff[0] = 1;
- ret = pSHUnicodeToAnsi(testW, buff, 1);
+ ret = pSHUnicodeToAnsi(L"test", buff, 1);
ok(ret == 1, "Unexpected return value %d.\n", ret);
ok(*buff == 0, "Unexpected buffer contents.\n");
- ret = pSHUnicodeToAnsi(testW, buff, 16);
+ ret = pSHUnicodeToAnsi(L"test", buff, 16);
ok(ret == 5, "Unexpected return value %d.\n", ret);
ok(!strcmp(buff, "test"), "Unexpected buffer contents.\n");
- ret = pSHUnicodeToAnsi(testW, buff, 2);
+ ret = pSHUnicodeToAnsi(L"test", buff, 2);
ok(ret == 2, "Unexpected return value %d.\n", ret);
ok(!strcmp(buff, "t"), "Unexpected buffer contents.\n");
}
static void test_SHAnsiToUnicode(void)
{
- static const WCHAR testW[] = {'t','e','s','t',0};
WCHAR buffW[16];
int ret;
@@ -246,7 +243,7 @@ static void test_SHAnsiToUnicode(void)
ret = pSHAnsiToUnicode("test", buffW, 16);
ok(ret == 5, "Unexpected return value %d.\n", ret);
- ok(!lstrcmpW(buffW, testW), "Unexpected buffer contents.\n");
+ ok(!lstrcmpW(buffW, L"test"), "Unexpected buffer contents.\n");
ret = pSHAnsiToUnicode("test", buffW, 2);
ok(ret == 2, "Unexpected return value %d.\n", ret);
@@ -294,43 +291,40 @@ static void test_SHAnsiToAnsi(void)
static void test_SHUnicodeToUnicode(void)
{
- static const WCHAR testW[] = {'t','e','s','t',0};
- static const WCHAR strW[] = {'a','b','c','d','e','f','g','h','i','k','l','m',0};
- static const WCHAR emptyW[] = { 0 };
WCHAR buff[16];
int ret;
ret = pSHUnicodeToUnicode(NULL, NULL, 0);
ok(ret == 0, "Unexpected return value %d.\n", ret);
- lstrcpyW(buff, strW);
- ret = pSHUnicodeToUnicode(testW, buff, 3);
+ lstrcpyW(buff, L"abcdefghiklm");
+ ret = pSHUnicodeToUnicode(L"test", buff, 3);
ok(ret == 0, "Unexpected return value %d.\n", ret);
- ok(!memcmp(buff, testW, 2 * sizeof(WCHAR)) && !buff[2], "Unexpected buffer contents.\n");
+ ok(!memcmp(buff, L"test", 2 * sizeof(WCHAR)) && !buff[2], "Unexpected buffer contents.\n");
ok(buff[3] == 'd', "Unexpected buffer contents.\n");
- lstrcpyW(buff, strW);
- ret = pSHUnicodeToUnicode(emptyW, buff, 3);
+ lstrcpyW(buff, L"abcdefghiklm");
+ ret = pSHUnicodeToUnicode(L"", buff, 3);
ok(ret == 1, "Unexpected return value %d.\n", ret);
ok(!*buff, "Unexpected buffer contents.\n");
ok(buff[3] == 'd', "Unexpected buffer contents.\n");
- lstrcpyW(buff, strW);
- ret = pSHUnicodeToUnicode(testW, buff, 4);
+ lstrcpyW(buff, L"abcdefghiklm");
+ ret = pSHUnicodeToUnicode(L"test", buff, 4);
ok(ret == 0, "Unexpected return value %d.\n", ret);
- ok(!memcmp(buff, testW, 3 * sizeof(WCHAR)) && !buff[3], "Unexpected buffer contents.\n");
+ ok(!memcmp(buff, L"test", 3 * sizeof(WCHAR)) && !buff[3], "Unexpected buffer contents.\n");
ok(buff[4] == 'e', "Unexpected buffer contents.\n");
- lstrcpyW(buff, strW);
- ret = pSHUnicodeToUnicode(testW, buff, 5);
+ lstrcpyW(buff, L"abcdefghiklm");
+ ret = pSHUnicodeToUnicode(L"test", buff, 5);
ok(ret == 5, "Unexpected return value %d.\n", ret);
- ok(!lstrcmpW(buff, testW), "Unexpected buffer contents.\n");
+ ok(!lstrcmpW(buff, L"test"), "Unexpected buffer contents.\n");
ok(buff[5] == 'f', "Unexpected buffer contents.\n");
- lstrcpyW(buff, strW);
- ret = pSHUnicodeToUnicode(testW, buff, 6);
+ lstrcpyW(buff, L"abcdefghiklm");
+ ret = pSHUnicodeToUnicode(L"test", buff, 6);
ok(ret == 5, "Unexpected return value %d.\n", ret);
- ok(!lstrcmpW(buff, testW), "Unexpected buffer contents.\n");
+ ok(!lstrcmpW(buff, L"test"), "Unexpected buffer contents.\n");
ok(buff[5] == 'f', "Unexpected buffer contents.\n");
}
--
2.26.2
Dec. 8, 2020
[PATCH] dnsapi/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/dnsapi/tests/record.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/dnsapi/tests/record.c b/dlls/dnsapi/tests/record.c
index 8d7b4974e83..c2f61b40843 100644
--- a/dlls/dnsapi/tests/record.c
+++ b/dlls/dnsapi/tests/record.c
@@ -28,8 +28,8 @@
#include "wine/test.h"
-static WCHAR name1[] = {'l','o','c','a','l','h','o','s','t',0};
-static WCHAR name2[] = {'L','O','C','A','L','H','O','S','T',0};
+static WCHAR name1[] = L"localhost";
+static WCHAR name2[] = L"LOCALHOST";
static DNS_RECORDW r1 = { NULL, name1, DNS_TYPE_A, sizeof(DNS_A_DATA), { 0 }, 1200, 0, { { 0xffffffff } } };
static DNS_RECORDW r2 = { NULL, name1, DNS_TYPE_A, sizeof(DNS_A_DATA), { 0 }, 1200, 0, { { 0xffffffff } } };
--
2.26.2
Dec. 8, 2020
[PATCH] cryptui/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/cryptui/tests/cryptui.c | 14 ++++----------
1 file changed, 4 insertions(+), 10 deletions(-)
diff --git a/dlls/cryptui/tests/cryptui.c b/dlls/cryptui/tests/cryptui.c
index bb1db929ba5..ea43f01962b 100644
--- a/dlls/cryptui/tests/cryptui.c
+++ b/dlls/cryptui/tests/cryptui.c
@@ -398,9 +398,8 @@ static void test_crypt_ui_wiz_import(void)
ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
if (ret)
{
- static const WCHAR CA[] = { 'C','A',0 };
HCERTSTORE ca = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
- CERT_SYSTEM_STORE_CURRENT_USER, CA);
+ CERT_SYSTEM_STORE_CURRENT_USER, L"CA");
if (ca)
{
@@ -422,10 +421,8 @@ static void test_crypt_ui_wiz_import(void)
ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
if (ret)
{
- static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s',
- 'B','o','o','k',0 };
HCERTSTORE addressBook = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
- CERT_SYSTEM_STORE_CURRENT_USER, AddressBook);
+ CERT_SYSTEM_STORE_CURRENT_USER, L"AddressBook");
if (addressBook)
{
@@ -476,10 +473,8 @@ static void test_crypt_ui_wiz_import(void)
ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
if (ret)
{
- static const WCHAR AddressBook[] = { 'A','d','d','r','e','s','s',
- 'B','o','o','k',0 };
HCERTSTORE addressBook = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
- CERT_SYSTEM_STORE_CURRENT_USER, AddressBook);
+ CERT_SYSTEM_STORE_CURRENT_USER, L"AddressBook");
if (addressBook)
{
@@ -499,9 +494,8 @@ static void test_crypt_ui_wiz_import(void)
ok(ret, "CryptUIWizImport failed: %08x\n", GetLastError());
if (ret)
{
- static const WCHAR CA[] = { 'C','A',0 };
HCERTSTORE ca = CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, 0,
- CERT_SYSTEM_STORE_CURRENT_USER, CA);
+ CERT_SYSTEM_STORE_CURRENT_USER, L"CA");
if (ca)
{
--
2.26.2
Dec. 8, 2020
[PATCH] scrrun/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/scrrun/tests/dictionary.c | 2 +-
dlls/scrrun/tests/filesystem.c | 77 +++++++++++++++++-----------------
2 files changed, 39 insertions(+), 40 deletions(-)
diff --git a/dlls/scrrun/tests/dictionary.c b/dlls/scrrun/tests/dictionary.c
index 12c41c3e401..4259bc71c8e 100644
--- a/dlls/scrrun/tests/dictionary.c
+++ b/dlls/scrrun/tests/dictionary.c
@@ -333,7 +333,7 @@ static void test_hash_value(void)
L"123",
L"A",
L"a",
- { 0 }
+ L""
};
static const int int_hash_tests[] = {
diff --git a/dlls/scrrun/tests/filesystem.c b/dlls/scrrun/tests/filesystem.c
index 5d64a0dcddb..5c55965ce88 100644
--- a/dlls/scrrun/tests/filesystem.c
+++ b/dlls/scrrun/tests/filesystem.c
@@ -44,7 +44,6 @@ static inline ULONG get_refcount(IUnknown *iface)
return IUnknown_Release(iface);
}
-static const WCHAR crlfW[] = {'\r','\n',0};
static const char utf16bom[] = {0xff,0xfe,0};
static const WCHAR testfileW[] = L"test.txt";
@@ -1572,7 +1571,7 @@ static void test_WriteLine(void)
len = MultiByteToWideChar(CP_ACP, 0, buffA, r, buffW, ARRAY_SIZE(buffW));
buffW[len] = 0;
lstrcpyW(buff2W, nameW);
- lstrcatW(buff2W, crlfW);
+ lstrcatW(buff2W, L"\r\n");
ok(!lstrcmpW(buff2W, buffW), "got %s, expected %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(buff2W));
CloseHandle(file);
DeleteFileW(nameW);
@@ -1596,7 +1595,7 @@ static void test_WriteLine(void)
buff2W[0] = 0xfeff;
buff2W[1] = 0;
lstrcatW(buff2W, nameW);
- lstrcatW(buff2W, crlfW);
+ lstrcatW(buff2W, L"\r\n");
ok(!lstrcmpW(buff2W, buffW), "got %s, expected %s\n", wine_dbgstr_w(buffW), wine_dbgstr_w(buff2W));
CloseHandle(file);
DeleteFileW(nameW);
@@ -1665,9 +1664,9 @@ static void test_ReadAll(void)
ok(hr == S_OK, "got 0x%08x\n", hr);
lstrcpyW(buffW, nameW);
- lstrcatW(buffW, crlfW);
+ lstrcatW(buffW, L"\r\n");
lstrcatW(buffW, secondlineW);
- lstrcatW(buffW, crlfW);
+ lstrcatW(buffW, L"\r\n");
str = NULL;
hr = ITextStream_ReadAll(stream, &str);
ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "got 0x%08x\n", hr);
@@ -1699,7 +1698,7 @@ static void test_ReadAll(void)
SysFreeString(str);
lstrcpyW(buffW, secondlineW);
- lstrcatW(buffW, crlfW);
+ lstrcatW(buffW, L"\r\n");
str = NULL;
hr = ITextStream_ReadAll(stream, &str);
ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "got 0x%08x\n", hr);
@@ -1810,9 +1809,9 @@ static void test_Read(void)
ok(hr == S_OK, "got 0x%08x\n", hr);
lstrcpyW(buffW, nameW);
- lstrcatW(buffW, crlfW);
+ lstrcatW(buffW, L"\r\n");
lstrcatW(buffW, secondlineW);
- lstrcatW(buffW, crlfW);
+ lstrcatW(buffW, L"\r\n");
str = NULL;
hr = ITextStream_Read(stream, 500, &str);
ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "got 0x%08x\n", hr);
@@ -1843,7 +1842,7 @@ static void test_Read(void)
SysFreeString(str);
lstrcpyW(buffW, secondlineW);
- lstrcatW(buffW, crlfW);
+ lstrcatW(buffW, L"\r\n");
str = NULL;
hr = ITextStream_Read(stream, 100, &str);
ok(hr == S_FALSE || broken(hr == S_OK) /* win2k */, "got 0x%08x\n", hr);
@@ -1856,9 +1855,9 @@ static void test_Read(void)
ok(hr == S_OK, "got 0x%08x\n", hr);
lstrcpyW(buffW, nameW);
- lstrcatW(buffW, crlfW);
+ lstrcatW(buffW, L"\r\n");
lstrcatW(buffW, secondlineW);
- lstrcatW(buffW, crlfW);
+ lstrcatW(buffW, L"\r\n");
str = NULL;
hr = ITextStream_Read(stream, 500, &str);
ok(hr == S_FALSE || broken(hr == S_OK) /* win2003 */, "got 0x%08x\n", hr);
@@ -2102,14 +2101,14 @@ struct driveexists_test {
* with the drive letter of a drive of this type. If such a drive does not exist,
* the test will be skipped. */
static const struct driveexists_test driveexiststestdata[] = {
- { {'N',':','\\',0}, DRIVE_NO_ROOT_DIR, VARIANT_FALSE },
- { {'R',':','\\',0}, DRIVE_REMOVABLE, VARIANT_TRUE },
- { {'F',':','\\',0}, DRIVE_FIXED, VARIANT_TRUE },
- { {'F',':',0}, DRIVE_FIXED, VARIANT_TRUE },
- { {'F','?',0}, DRIVE_FIXED, VARIANT_FALSE },
- { {'F',0}, DRIVE_FIXED, VARIANT_TRUE },
- { {'?',0}, -1, VARIANT_FALSE },
- { { 0 } }
+ { L"N:\\", DRIVE_NO_ROOT_DIR, VARIANT_FALSE },
+ { L"R:\\", DRIVE_REMOVABLE, VARIANT_TRUE },
+ { L"F:\\", DRIVE_FIXED, VARIANT_TRUE },
+ { L"F:", DRIVE_FIXED, VARIANT_TRUE },
+ { L"F?", DRIVE_FIXED, VARIANT_FALSE },
+ { L"F", DRIVE_FIXED, VARIANT_TRUE },
+ { L"?", -1, VARIANT_FALSE },
+ { L"" }
};
static void test_DriveExists(void)
@@ -2118,7 +2117,7 @@ static void test_DriveExists(void)
HRESULT hr;
VARIANT_BOOL ret;
BSTR drivespec;
- WCHAR root[] = {'?',':','\\',0};
+ WCHAR root[] = L"?:\\";
hr = IFileSystem3_DriveExists(fs3, NULL, NULL);
ok(hr == E_POINTER, "got 0x%08x\n", hr);
@@ -2175,14 +2174,14 @@ struct getdrivename_test {
};
static const struct getdrivename_test getdrivenametestdata[] = {
- { {'C',':','\\','1','.','t','s','t',0}, {'C',':',0} },
- { {'O',':','\\','1','.','t','s','t',0}, {'O',':',0} },
- { {'O',':',0}, {'O',':',0} },
- { {'o',':',0}, {'o',':',0} },
- { {'O','O',':',0} },
- { {':',0} },
- { {'O',0} },
- { { 0 } }
+ { L"C:\\1.tst", L"C:" },
+ { L"O:\\1.tst", L"O:" },
+ { L"O:", L"O:" },
+ { L"o:", L"o:" },
+ { L"OO:" },
+ { L":" },
+ { L"O" },
+ { L"" }
};
static void test_GetDriveName(void)
@@ -2225,7 +2224,7 @@ static void test_GetDrive(void)
HRESULT hr;
IDrive *drive_fixed, *drive;
BSTR dl_fixed, drivespec;
- WCHAR root[] = {'?',':','\\',0};
+ WCHAR root[] = L"?:\\";
drive = (void*)0xdeadbeef;
hr = IFileSystem3_GetDrive(fs3, NULL, NULL);
@@ -2266,12 +2265,12 @@ static void test_GetDrive(void)
{ {dl_upper,':',0}, S_OK, {dl_upper,0} },
{ {dl_upper,':','\\',0}, S_OK, {dl_upper,0} },
{ {dl_lower,':','\\',0}, S_OK, {dl_upper,0} },
- { {dl_upper,'\\',0}, E_INVALIDARG, { 0 } },
- { {dl_lower,'\\',0}, E_INVALIDARG, { 0 } },
- { {'$',':','\\',0}, E_INVALIDARG, { 0 } },
- { {'\\','h','o','s','t','\\','s','h','a','r','e',0}, E_INVALIDARG, { 0 } },
- { {'h','o','s','t','\\','s','h','a','r','e',0}, E_INVALIDARG, { 0 } },
- { { 0 } },
+ { {dl_upper,'\\',0 }, E_INVALIDARG, L""},
+ { {dl_lower,'\\',0 }, E_INVALIDARG, L""},
+ { L"$:\\", E_INVALIDARG, L"" },
+ { L"\\host\\share", E_INVALIDARG, L"" },
+ { L"host\\share", E_INVALIDARG, L"" },
+ { L"" },
};
struct getdrive_test *ptr = &testdata[0];
@@ -2349,10 +2348,10 @@ static const struct extension_test {
WCHAR path[20];
WCHAR ext[10];
} extension_tests[] = {
- { {'n','o','e','x','t',0}, {0} },
- { {'n','.','o','.','e','x','t',0}, {'e','x','t',0} },
- { {'n','.','o','.','e','X','t',0}, {'e','X','t',0} },
- { { 0 } }
+ { L"noext", L"" },
+ { L"n.o.ext", L"ext" },
+ { L"n.o.eXt", L"eXt" },
+ { L"" }
};
static void test_GetExtensionName(void)
--
2.26.2
Dec. 8, 2020
[PATCH] include: Fix broken defines in d3d9 headers
by Rafał Harabień
* rename D3DENUM_NO_WHQL_LEVEL to D3DENUM_WHQL_LEVEL
* remove D3DCAPS2_NO2DDURING3DSCENE
* remove D3DCAPS2_CANRENDERWINDOWED
Removed defines seems to have been copied from d3d8.h and according to
public docs do not exist in d3d9.
Signed-off-by: Rafał Harabień <rafalh92(a)outlook.com>
---
dlls/d3d9/tests/d3d9ex.c | 3 +--
dlls/d3d9/tests/device.c | 3 +--
include/d3d9.h | 2 +-
include/d3d9caps.h | 2 --
4 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/dlls/d3d9/tests/d3d9ex.c b/dlls/d3d9/tests/d3d9ex.c
index 462037b2e01..2afe73088c7 100644
--- a/dlls/d3d9/tests/d3d9ex.c
+++ b/dlls/d3d9/tests/d3d9ex.c
@@ -4020,8 +4020,7 @@ static void test_device_caps(void)
ok(!(caps.Caps & ~(D3DCAPS_OVERLAY | D3DCAPS_READ_SCANLINE)),
"Caps field has unexpected flags %#x.\n", caps.Caps);
- ok(!(caps.Caps2 & ~(D3DCAPS2_NO2DDURING3DSCENE | D3DCAPS2_FULLSCREENGAMMA
- | D3DCAPS2_CANRENDERWINDOWED | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED
+ ok(!(caps.Caps2 & ~(D3DCAPS2_FULLSCREENGAMMA | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED
| D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_CANAUTOGENMIPMAP
| D3DCAPS2_CANSHARERESOURCE)),
"Caps2 field has unexpected flags %#x.\n", caps.Caps2);
diff --git a/dlls/d3d9/tests/device.c b/dlls/d3d9/tests/device.c
index 2791e91a068..0343fade792 100644
--- a/dlls/d3d9/tests/device.c
+++ b/dlls/d3d9/tests/device.c
@@ -13172,8 +13172,7 @@ static void test_device_caps(void)
test_device_caps_adapter_group(&caps, adapter_idx, adapter_count);
ok(!(caps.Caps & ~D3DCAPS_READ_SCANLINE),
"Adapter %u: Caps field has unexpected flags %#x.\n", adapter_idx, caps.Caps);
- ok(!(caps.Caps2 & ~(D3DCAPS2_NO2DDURING3DSCENE | D3DCAPS2_FULLSCREENGAMMA
- | D3DCAPS2_CANRENDERWINDOWED | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED
+ ok(!(caps.Caps2 & ~(D3DCAPS2_FULLSCREENGAMMA | D3DCAPS2_CANCALIBRATEGAMMA | D3DCAPS2_RESERVED
| D3DCAPS2_CANMANAGERESOURCE | D3DCAPS2_DYNAMICTEXTURES | D3DCAPS2_CANAUTOGENMIPMAP
| D3DCAPS2_CANSHARERESOURCE)),
"Adapter %u: Caps2 field has unexpected flags %#x.\n", adapter_idx, caps.Caps2);
diff --git a/include/d3d9.h b/include/d3d9.h
index 3ebde4509af..d61461f0833 100644
--- a/include/d3d9.h
+++ b/include/d3d9.h
@@ -61,7 +61,7 @@
*/
#define D3D_SDK_VERSION 32
#define D3DADAPTER_DEFAULT 0
-#define D3DENUM_NO_WHQL_LEVEL __MSABI_LONG(0x00000002)
+#define D3DENUM_WHQL_LEVEL __MSABI_LONG(0x00000002)
#define D3DPRESENT_DONOTWAIT __MSABI_LONG(1)
#define D3DPRESENT_LINEAR_CONTENT __MSABI_LONG(2)
#define D3DPRESENT_BACK_BUFFERS_MAX __MSABI_LONG(3)
diff --git a/include/d3d9caps.h b/include/d3d9caps.h
index 1068a2c35a9..c62780b4a0a 100644
--- a/include/d3d9caps.h
+++ b/include/d3d9caps.h
@@ -258,9 +258,7 @@
#define D3DCAPS3_DXVAHD_LIMITED __MSABI_LONG(0x00000800)
#define D3DCAPS3_RESERVED __MSABI_LONG(0x8000001F)
-#define D3DCAPS2_NO2DDURING3DSCENE __MSABI_LONG(0x00000002)
#define D3DCAPS2_FULLSCREENGAMMA __MSABI_LONG(0x00020000)
-#define D3DCAPS2_CANRENDERWINDOWED __MSABI_LONG(0x00080000)
#define D3DCAPS2_CANCALIBRATEGAMMA __MSABI_LONG(0x00100000)
#define D3DCAPS2_RESERVED __MSABI_LONG(0x02000000)
#define D3DCAPS2_CANMANAGERESOURCE __MSABI_LONG(0x10000000)
--
2.25.1
Dec. 8, 2020
Re: [PATCH] ntdll: Only build Linux-specific functions on Linux
by Alexandre Julliard
Gerald Pfeifer <gerald(a)pfeifer.com> writes:
> logical_proc_info_add_by_id, logical_proc_info_add_cache,
> logical_proc_info_add_group, and logical_proc_info_add_numa_node
> are only useful and invoked on Linux, so disable their build
> elsewhere.
They are also used on macOS. A better fix would be to implement the
missing functionality for *BSD platforms.
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 8, 2020
[PATCH] dbghelp: Use WINELOADER environment variable from debuggee process in get_wine_loader_name.
by Jacek Caban
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49838
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/dbghelp/dbghelp_private.h | 2 +-
dlls/dbghelp/elf_module.c | 5 +----
dlls/dbghelp/macho_module.c | 7 +------
dlls/dbghelp/module.c | 35 +++++-----------------------------
4 files changed, 8 insertions(+), 41 deletions(-)
Dec. 8, 2020
[PATCH] winex11.drv: Avoid freezing when dropping from native into Wine application that shows modal dialog.
by Roman Pišl
https://bugs.winehq.org/show_bug.cgi?id=46522
Signed-off-by: Roman Pišl <rpisl(a)seznam.cz>
---
dlls/winex11.drv/window.c | 3 +++
dlls/winex11.drv/x11drv.h | 4 +++-
dlls/winex11.drv/xdnd.c | 17 +++++++++++++++++
3 files changed, 23 insertions(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/window.c b/dlls/winex11.drv/window.c
index f46cbfb088a..cdebd87823e 100644
--- a/dlls/winex11.drv/window.c
+++ b/dlls/winex11.drv/window.c
@@ -2791,6 +2791,9 @@ LRESULT CDECL X11DRV_WindowMessage( HWND hwnd, UINT msg, WPARAM wp, LPARAM lp )
return clip_cursor_notify( hwnd, (HWND)wp, (HWND)lp );
case WM_X11DRV_CLIP_CURSOR_REQUEST:
return clip_cursor_request( hwnd, (BOOL)wp, (BOOL)lp );
+ case WM_X11DRV_DROP_EVENT:
+ X11DRV_XDND_DropEventProcess( hwnd, (XClientMessageEvent*)lp );
+ return 0;
default:
FIXME( "got window msg %x hwnd %p wp %lx lp %lx\n", msg, hwnd, wp, lp );
return 0;
diff --git a/dlls/winex11.drv/x11drv.h b/dlls/winex11.drv/x11drv.h
index 45855976607..ae6901059ec 100644
--- a/dlls/winex11.drv/x11drv.h
+++ b/dlls/winex11.drv/x11drv.h
@@ -242,6 +242,7 @@ extern void IME_SetResultString(LPWSTR lpResult, DWORD dwResultlen) DECLSPEC_HID
extern void X11DRV_XDND_EnterEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
extern void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
+extern void X11DRV_XDND_DropEventProcess( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
extern void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
extern void X11DRV_XDND_LeaveEvent( HWND hWnd, XClientMessageEvent *event ) DECLSPEC_HIDDEN;
extern void X11DRV_CLIPBOARD_ImportSelection( Display *display, Window win, Atom selection,
@@ -539,7 +540,8 @@ enum x11drv_window_messages
WM_X11DRV_RESIZE_DESKTOP,
WM_X11DRV_SET_CURSOR,
WM_X11DRV_CLIP_CURSOR_NOTIFY,
- WM_X11DRV_CLIP_CURSOR_REQUEST
+ WM_X11DRV_CLIP_CURSOR_REQUEST,
+ WM_X11DRV_DROP_EVENT
};
/* _NET_WM_STATE properties that we keep track of */
diff --git a/dlls/winex11.drv/xdnd.c b/dlls/winex11.drv/xdnd.c
index 0cd2ad88924..7536f578d19 100644
--- a/dlls/winex11.drv/xdnd.c
+++ b/dlls/winex11.drv/xdnd.c
@@ -406,6 +406,22 @@ void X11DRV_XDND_PositionEvent( HWND hWnd, XClientMessageEvent *event )
* Handle an XdndDrop event.
*/
void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event )
+{
+ XClientMessageEvent *drop_event = HeapAlloc(GetProcessHeap(), 0, sizeof(*drop_event));
+ if (!drop_event)
+ return;
+
+ memcpy(drop_event, event, sizeof(*drop_event));
+ if (!PostMessageW(hWnd, WM_X11DRV_DROP_EVENT, 0, (LPARAM)drop_event))
+ HeapFree(GetProcessHeap(), 0, drop_event);
+}
+
+/**************************************************************************
+ * X11DRV_XDND_DropEventProcess
+ *
+ * Process an XdndDrop event.
+ */
+void X11DRV_XDND_DropEventProcess( HWND hWnd, XClientMessageEvent *event )
{
XClientMessageEvent e;
IDropTarget *dropTarget;
@@ -492,6 +508,7 @@ void X11DRV_XDND_DropEvent( HWND hWnd, XClientMessageEvent *event )
else
e.data.l[2] = None;
XSendEvent(event->display, event->data.l[0], False, NoEventMask, (XEvent*)&e);
+ HeapFree(GetProcessHeap(), 0, event);
}
/**************************************************************************
--
2.20.1
Dec. 8, 2020
Re: Re: ntdll:exception crashes some Windows 10
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=83236
Your paranoid android.
=== w2008s64 (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
=== w7u_2qxl (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
=== w7u_adm (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
=== w7u_el (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
=== w8 (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
=== w8adm (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
=== w864 (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
=== w1064v1507 (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
=== w1064v1809 (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
=== w1064 (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
=== w10pro64 (32 bit report) ===
ntdll:
exception.c:801: Test failed: (1) failed to set debug register 0 to 42424240, got 0
exception.c:803: Test failed: (1) failed to set debug register 2 to 126bb070, got 0
exception.c:804: Test failed: (1) failed to set debug register 3 to badbad0, got 0
exception.c:806: Test failed: (1) failed to set debug register 7 to ffff0115, got 0
Dec. 8, 2020
Re: ntdll:exception crashes some Windows 10
by Francois Gouget
On Tue, 8 Dec 2020, Paul Gofman wrote:
[...]
> Are you commenting out here in the cited code or (better) in dreg_handler?
I did the commenting in the cited code. I tried again in dreg_handler()
and that shows I can set Dr6 and Dr1 but none of the others (which makes
sense I guess).
Here's what I tested in patch form to avoid ambiguity:
commit f54d113590d1de43ec3ef6ff78369b9dc9d1bdb6
Author: Francois Gouget <fgouget(a)codeweavers.com>
Date: Tue Dec 8 17:58:39 2020 +0100
HACK ntdll:exception: Comment out most tests to avoid a crash.
* Uncommenting any of the C++ lines causes the
KERNEL_SECURITY_CHECK_FAILURE crash.
* All if (0) except one just skip irrelevant tests.
* The second dreg_handler test produces the same crashes. Ignore it
until the first one is fixed / diagnosed.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 5686e39ab9e..cd078d662c1 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -776,12 +776,12 @@ static DWORD dreg_handler( EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD
const struct dbgreg_test *test = *(const struct dbgreg_test **)(frame + 1);
context->Eip += 2; /* Skips the popl (%eax) */
- context->Dr0 = test->dr0;
+ //context->Dr0 = test->dr0;
context->Dr1 = test->dr1;
- context->Dr2 = test->dr2;
- context->Dr3 = test->dr3;
+ //context->Dr2 = test->dr2;
+ //context->Dr3 = test->dr3;
context->Dr6 = test->dr6;
- context->Dr7 = test->dr7;
+ //context->Dr7 = test->dr7;
return ExceptionContinueExecution;
}
@@ -989,13 +989,16 @@ static void test_exceptions(void)
run_exception_test(dreg_handler, &dreg_test, &segfault_code, sizeof(segfault_code), 0);
check_debug_registers(1, &dreg_test);
+ if (0) { /* causes crashes too but ignore for now */
dreg_test.dr0 = 0x42424242;
dreg_test.dr2 = 0x100f0fe7;
dreg_test.dr3 = 0x0abebabe;
dreg_test.dr7 = 0x115;
run_exception_test(dreg_handler, &dreg_test, &segfault_code, sizeof(segfault_code), 0);
check_debug_registers(2, &dreg_test);
+ }
+ if (0) {
/* test single stepping behavior */
got_exception = 0;
run_exception_test(single_step_handler, NULL, &single_stepcode, sizeof(single_stepcode), 0);
@@ -1052,6 +1055,7 @@ static void test_exceptions(void)
ctx.Dr7 = 0;
res = pNtSetContextThread( GetCurrentThread(), &ctx );
ok( res == STATUS_SUCCESS, "NtSetContextThread failed with %x\n", res );
+ }
}
static void test_debugger(void)
@@ -8189,8 +8193,11 @@ START_TEST(exception)
#ifdef __i386__
+ if (0) {
test_unwind();
+ }
test_exceptions();
+ if (0) {
test_rtlraiseexception();
test_debug_registers();
test_debug_service(1);
@@ -8201,6 +8208,7 @@ START_TEST(exception)
test_kiuserexceptiondispatcher();
test_extended_context();
test_copy_context();
+ }
#elif defined(__x86_64__)
@@ -8248,6 +8256,7 @@ START_TEST(exception)
#endif
+ if (0) {
test_debugger();
test_thread_context();
test_outputdebugstring(1, FALSE);
@@ -8264,5 +8273,6 @@ START_TEST(exception)
test_suspend_thread();
test_suspend_process();
test_unload_trace();
+ }
VirtualFree(code_mem, 0, MEM_RELEASE);
}
--
Francois Gouget <fgouget(a)codeweavers.com>
Dec. 8, 2020
[PATCH] kernel32/tests: Add some more tests for FILE_ATTRIBUTE_REPARSE_POINT.
by Zebediah Figura
Written while debugging <https://bugs.winehq.org/show_bug.cgi?id=49840>.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/kernel32/tests/volume.c | 31 +++++++++++++++++++++++++++++++
1 file changed, 31 insertions(+)
diff --git a/dlls/kernel32/tests/volume.c b/dlls/kernel32/tests/volume.c
index ead06764a11..5199a4992d8 100644
--- a/dlls/kernel32/tests/volume.c
+++ b/dlls/kernel32/tests/volume.c
@@ -1268,6 +1268,33 @@ static void test_mounted_folder(void)
HANDLE file;
DWORD size;
+ file = CreateFileA( "C:\\", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT, NULL );
+ ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
+
+ status = NtQueryInformationFile( file, &io, &info, sizeof(info), FileAttributeTagInformation );
+ ok(!status, "got status %#x\n", status);
+ ok(!(info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+ && (info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY), "got attributes %#x\n", info.FileAttributes);
+ ok(!info.ReparseTag, "got reparse tag %#x\n", info.ReparseTag);
+
+ CloseHandle( file );
+
+ file = CreateFileA( "C:\\", 0, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
+ OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
+ ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
+
+ status = NtQueryInformationFile( file, &io, &info, sizeof(info), FileAttributeTagInformation );
+ ok(!status, "got status %#x\n", status);
+ ok(!(info.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
+ && (info.FileAttributes & FILE_ATTRIBUTE_DIRECTORY), "got attributes %#x\n", info.FileAttributes);
+ ok(!info.ReparseTag, "got reparse tag %#x\n", info.ReparseTag);
+
+ CloseHandle( file );
+
+ ret = GetFileAttributesA( "C:\\" );
+ ok(!(ret & FILE_ATTRIBUTE_REPARSE_POINT) && (ret & FILE_ATTRIBUTE_DIRECTORY), "got attributes %#x\n", ret);
+
ret = CreateDirectoryA("C:\\winetest_mnt", NULL);
if (!ret && GetLastError() == ERROR_ACCESS_DENIED)
{
@@ -1324,6 +1351,10 @@ static void test_mounted_folder(void)
CloseHandle( file );
+ ret = GetFileAttributesA( "C:\\winetest_mnt" );
+ ok(ret != INVALID_FILE_ATTRIBUTES, "got error %u\n", GetLastError());
+ ok((ret & FILE_ATTRIBUTE_REPARSE_POINT) && (ret & FILE_ATTRIBUTE_DIRECTORY), "got attributes %#x\n", ret);
+
file = CreateFileA( "C:\\winetest_mnt\\windows", 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL );
ok(file != INVALID_HANDLE_VALUE, "got error %u\n", GetLastError());
--
2.29.2
Dec. 8, 2020
Re: ntdll:exception crashes some Windows 10
by Paul Gofman
On 12/8/20 17:39, Francois Gouget wrote:
> On Mon, 7 Dec 2020, Paul Gofman wrote:
>
>> On 12/7/20 17:07, Francois Gouget wrote:
> [...]
>>> dreg_test.dr0 = 0x42424240;
>>> dreg_test.dr2 = 0x126bb070;
>>> dreg_test.dr3 = 0x0badbad0;
>>> dreg_test.dr7 = 0xffff0115;
>>> run_exception_test(dreg_handler, &dreg_test, &segfault_code, sizeof(segfault_code), 0);
> [...]
>> While it looks like a definite VM bug, it is maybe interesting to know
>> for a start what exactly triggers the error. Is it possible to see if
>> disabling the setting of the debug registers in dreg_handler() above
>> (lines context->Dr<n> = test->dr<n>;) avoids the crash, and if yes,
>> which exactly register(s) setting trigger that.
> It does not matter which register is set (dr0, dr2, dr3 or dr7), Windows
> crashes with any of them. It's only if I comment all of them out that it
> does not crash :-(
>
>
Are you commenting out here in the cited code or (better) in dreg_handler?
Dec. 8, 2020
Re: ntdll:exception crashes some Windows 10
by Francois Gouget
On Mon, 7 Dec 2020, Paul Gofman wrote:
> On 12/7/20 17:07, Francois Gouget wrote:
[...]
> > dreg_test.dr0 = 0x42424240;
> > dreg_test.dr2 = 0x126bb070;
> > dreg_test.dr3 = 0x0badbad0;
> > dreg_test.dr7 = 0xffff0115;
> > run_exception_test(dreg_handler, &dreg_test, &segfault_code, sizeof(segfault_code), 0);
[...]
> While it looks like a definite VM bug, it is maybe interesting to know
> for a start what exactly triggers the error. Is it possible to see if
> disabling the setting of the debug registers in dreg_handler() above
> (lines context->Dr<n> = test->dr<n>;) avoids the crash, and if yes,
> which exactly register(s) setting trigger that.
It does not matter which register is set (dr0, dr2, dr3 or dr7), Windows
crashes with any of them. It's only if I comment all of them out that it
does not crash :-(
--
Francois Gouget <fgouget(a)codeweavers.com>
Dec. 8, 2020
Code freeze
by Alexandre Julliard
Folks,
As a reminder, we are now in the code freeze period towards 6.0. This
means that only small bug fixes can be accepted. As far as possible,
please mention the bug that you are fixing in the commit message.
Patches that are deemed too large or too risky will be marked
"deferred"; please resubmit them once 6.0 is out. Patches that don't
change the code, like test fixes or translation updates, can still be
accepted during the freeze.
Based on the experience of the previous years, I expect code freeze to
last approximately 5-6 weeks. I'm going to make a release candidate
every Friday until the final 6.0.
Thank you all for your help!
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 8, 2020
[PATCH 2/2] gdi32: Don't try to get glyph index when default char is 0.
by Rémi Bernon
Fixes a regression from 5bdc6e0fe64222d8d7d383616f5e230928af011a, this
is what the code was originally doing.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50175
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/gdi32/freetype.c | 2 +-
dlls/gdi32/tests/font.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dlls/gdi32/freetype.c b/dlls/gdi32/freetype.c
index 09c8251de8f..fffa3288503 100644
--- a/dlls/gdi32/freetype.c
+++ b/dlls/gdi32/freetype.c
@@ -2601,7 +2601,7 @@ static UINT CDECL freetype_get_default_glyph( struct gdi_font *font )
if ((pOS2 = pFT_Get_Sfnt_Table( ft_face, ft_sfnt_os2 )))
{
UINT glyph = pOS2->usDefaultChar;
- freetype_get_glyph_index( font, &glyph, TRUE );
+ if (glyph) freetype_get_glyph_index( font, &glyph, TRUE );
return glyph;
}
if (!pFT_Get_WinFNT_Header( ft_face, &winfnt )) return winfnt.default_char + winfnt.first_char;
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index cde83757c16..86ccddd05ea 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -1716,8 +1716,8 @@ static void test_GetGlyphIndices(void)
testtext[0] = 'T';
charcount = pGetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags);
ok(charcount == 5, "GetGlyphIndicesW count of glyphs should = 5 not %d\n", charcount);
- todo_wine ok(glyphs[0] == 0, "GetGlyphIndicesW for tmDefaultChar should be 0 not %04x\n", glyphs[0]);
- todo_wine ok(glyphs[4] == 0, "GetGlyphIndicesW should have returned 0 not %04x\n", glyphs[4]);
+ ok(glyphs[0] == 0, "GetGlyphIndicesW for tmDefaultChar should be 0 not %04x\n", glyphs[0]);
+ ok(glyphs[4] == 0, "GetGlyphIndicesW should have returned 0 not %04x\n", glyphs[4]);
DeleteObject(SelectObject(hdc, hOldFont));
ret = pRemoveFontMemResourceEx(rsrc);
--
2.29.2
Dec. 8, 2020
[PATCH 1/2] gdi32/tests: Test GetGlyphIndices with '\0' default and a glyph.
by Rémi Bernon
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50175
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/gdi32/tests/Makefile.in | 1 +
dlls/gdi32/tests/font.c | 112 +++++++++++++++++++++------------
dlls/gdi32/tests/resource.rc | 3 +
dlls/gdi32/tests/wine_nul.sfd | 113 ++++++++++++++++++++++++++++++++++
dlls/gdi32/tests/wine_nul.ttf | Bin 0 -> 1600 bytes
5 files changed, 190 insertions(+), 39 deletions(-)
create mode 100644 dlls/gdi32/tests/wine_nul.sfd
create mode 100644 dlls/gdi32/tests/wine_nul.ttf
diff --git a/dlls/gdi32/tests/Makefile.in b/dlls/gdi32/tests/Makefile.in
index 1eba8d13cef..876f6a376a2 100644
--- a/dlls/gdi32/tests/Makefile.in
+++ b/dlls/gdi32/tests/Makefile.in
@@ -24,6 +24,7 @@ FONT_SRCS = \
wine_langnames2.sfd \
wine_langnames3.sfd \
wine_longname.sfd \
+ wine_nul.sfd \
wine_test.sfd \
wine_ttfnames.sfd \
wine_ttfnames_bold.sfd \
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c
index 8b0c7b3dbcc..cde83757c16 100644
--- a/dlls/gdi32/tests/font.c
+++ b/dlls/gdi32/tests/font.c
@@ -1587,6 +1587,45 @@ static void test_text_extents(void)
ReleaseDC(NULL, hdc);
}
+static void free_font(void *font)
+{
+ UnmapViewOfFile(font);
+}
+
+static void *load_font(const char *font_name, DWORD *font_size)
+{
+ char file_name[MAX_PATH];
+ HANDLE file, mapping;
+ void *font;
+
+ if (font_name[1] == ':')
+ strcpy(file_name, font_name);
+ else
+ {
+ if (!GetWindowsDirectoryA(file_name, sizeof(file_name))) return NULL;
+ strcat(file_name, "\\fonts\\");
+ strcat(file_name, font_name);
+ }
+
+ file = CreateFileA(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
+ if (file == INVALID_HANDLE_VALUE) return NULL;
+
+ *font_size = GetFileSize(file, NULL);
+
+ mapping = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
+ if (!mapping)
+ {
+ CloseHandle(file);
+ return NULL;
+ }
+
+ font = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
+
+ CloseHandle(file);
+ CloseHandle(mapping);
+ return font;
+}
+
static void test_GetGlyphIndices(void)
{
HDC hdc;
@@ -1598,6 +1637,10 @@ static void test_GetGlyphIndices(void)
WORD glyphs[(sizeof(testtext)/2)-1];
TEXTMETRICA textm;
HFONT hOldFont;
+ HANDLE rsrc;
+ DWORD ret, font_size, num_fonts;
+ void *font;
+ char ttf_name[MAX_PATH];
if (!pGetGlyphIndicesW) {
win_skip("GetGlyphIndicesW not available on platform\n");
@@ -1653,6 +1696,36 @@ static void test_GetGlyphIndices(void)
ok(glyphs[0] == 0, "GetGlyphIndicesW for tmDefaultChar should be 0 not %04x\n", glyphs[0]);
ok(glyphs[4] == 0, "GetGlyphIndicesW should have returned 0 not %04x\n", glyphs[4]);
DeleteObject(SelectObject(hdc, hOldFont));
+
+ ret = write_ttf_file("wine_nul.ttf", ttf_name);
+ ok(ret, "Failed to create test font file.\n");
+ font = load_font(ttf_name, &font_size);
+ ok(font != NULL, "Failed to map font file.\n");
+ num_fonts = 0;
+ rsrc = pAddFontMemResourceEx(font, font_size, NULL, &num_fonts);
+ ok(ret != 0, "Failed to add resource, %d.\n", GetLastError());
+ ok(num_fonts == 1, "Unexpected number of fonts %u.\n", num_fonts);
+
+ memset(&lf, 0, sizeof(lf));
+ strcpy(lf.lfFaceName, "wine_nul");
+ lf.lfHeight = 20;
+ flags = 0;
+ hfont = CreateFontIndirectA(&lf);
+ hOldFont = SelectObject(hdc, hfont);
+ ok(GetTextMetricsA(hdc, &textm), "GetTextMetric failed\n");
+ testtext[0] = 'T';
+ charcount = pGetGlyphIndicesW(hdc, testtext, (sizeof(testtext)/2)-1, glyphs, flags);
+ ok(charcount == 5, "GetGlyphIndicesW count of glyphs should = 5 not %d\n", charcount);
+ todo_wine ok(glyphs[0] == 0, "GetGlyphIndicesW for tmDefaultChar should be 0 not %04x\n", glyphs[0]);
+ todo_wine ok(glyphs[4] == 0, "GetGlyphIndicesW should have returned 0 not %04x\n", glyphs[4]);
+ DeleteObject(SelectObject(hdc, hOldFont));
+
+ ret = pRemoveFontMemResourceEx(rsrc);
+ ok(ret, "RemoveFontMemResourceEx error %d\n", GetLastError());
+ free_font(font);
+ ret = DeleteFileA(ttf_name);
+ ok(ret, "Failed to delete font file, %d.\n", GetLastError());
+
}
static void test_GetKerningPairs(void)
@@ -5000,45 +5073,6 @@ static void test_CreateFontIndirectEx(void)
DeleteObject(hfont);
}
-static void free_font(void *font)
-{
- UnmapViewOfFile(font);
-}
-
-static void *load_font(const char *font_name, DWORD *font_size)
-{
- char file_name[MAX_PATH];
- HANDLE file, mapping;
- void *font;
-
- if (font_name[1] == ':')
- strcpy(file_name, font_name);
- else
- {
- if (!GetWindowsDirectoryA(file_name, sizeof(file_name))) return NULL;
- strcat(file_name, "\\fonts\\");
- strcat(file_name, font_name);
- }
-
- file = CreateFileA(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
- if (file == INVALID_HANDLE_VALUE) return NULL;
-
- *font_size = GetFileSize(file, NULL);
-
- mapping = CreateFileMappingA(file, NULL, PAGE_READONLY, 0, 0, NULL);
- if (!mapping)
- {
- CloseHandle(file);
- return NULL;
- }
-
- font = MapViewOfFile(mapping, FILE_MAP_READ, 0, 0, 0);
-
- CloseHandle(file);
- CloseHandle(mapping);
- return font;
-}
-
static void test_realization_info(const char *name, DWORD size, BOOL is_memory_resource)
{
struct font_realization_info info;
diff --git a/dlls/gdi32/tests/resource.rc b/dlls/gdi32/tests/resource.rc
index 6cbe789880b..784d8602a9a 100644
--- a/dlls/gdi32/tests/resource.rc
+++ b/dlls/gdi32/tests/resource.rc
@@ -46,3 +46,6 @@ wine_langnames2.ttf RCDATA wine_langnames2.ttf
/* @makedep: wine_langnames3.ttf */
wine_langnames3.ttf RCDATA wine_langnames3.ttf
+
+/* @makedep: wine_nul.ttf */
+wine_nul.ttf RCDATA wine_nul.ttf
diff --git a/dlls/gdi32/tests/wine_nul.sfd b/dlls/gdi32/tests/wine_nul.sfd
new file mode 100644
index 00000000000..c82180f1007
--- /dev/null
+++ b/dlls/gdi32/tests/wine_nul.sfd
@@ -0,0 +1,113 @@
+SplineFontDB: 3.2
+FontName: wine_nul
+FullName: wine_nul
+FamilyName: wine_nul
+Weight: Medium
+Copyright: Copyright (c) 2020 Remi Bernon for CodeWeavers
+Version: 001.000
+ItalicAngle: 0
+UnderlinePosition: -205
+UnderlineWidth: 102
+Ascent: 1638
+Descent: 410
+InvalidEm: 0
+sfntRevision: 0x00010000
+LayerCount: 2
+Layer: 0 1 "Back" 1
+Layer: 1 1 "Fore" 0
+XUID: [1021 905 592216984 1247726]
+FSType: 32767
+OS2Version: 2
+OS2_WeightWidthSlopeOnly: 0
+OS2_UseTypoMetrics: 1
+CreationTime: 1607427474
+ModificationTime: 1607428497
+PfmFamily: 17
+TTFWeight: 500
+TTFWidth: 5
+LineGap: 184
+VLineGap: 0
+Panose: 2 0 6 3 0 0 0 0 0 0
+OS2TypoAscent: 0
+OS2TypoAOffset: 1
+OS2TypoDescent: 0
+OS2TypoDOffset: 1
+OS2TypoLinegap: 184
+OS2WinAscent: 1638
+OS2WinAOffset: 0
+OS2WinDescent: 410
+OS2WinDOffset: 0
+HheadAscent: 0
+HheadAOffset: 1
+HheadDescent: 0
+HheadDOffset: 1
+OS2SubXSize: 1331
+OS2SubYSize: 1433
+OS2SubXOff: 0
+OS2SubYOff: 286
+OS2SupXSize: 1331
+OS2SupYSize: 1433
+OS2SupXOff: 0
+OS2SupYOff: 983
+OS2StrikeYSize: 102
+OS2StrikeYPos: 530
+OS2Vendor: 'Wine'
+OS2CodePages: 00000001.00000000
+OS2UnicodeRanges: 00000001.00000000.00000000.00000000
+MarkAttachClasses: 1
+DEI: 91125
+ShortTable: cvt 2
+ 68
+ 1297
+EndShort
+ShortTable: maxp 16
+ 1
+ 0
+ 4
+ 8
+ 2
+ 0
+ 0
+ 2
+ 0
+ 1
+ 1
+ 0
+ 64
+ 46
+ 0
+ 0
+EndShort
+LangName: 1033 "" "" "" "Wine : wine_nul : 4-11-2010"
+GaspTable: 1 65535 2 0
+Encoding: ISO8859-1
+UnicodeInterp: none
+NameList: Adobe Glyph List
+DisplaySize: -24
+AntiAlias: 1
+FitToEm: 1
+WinInfo: 0 76 22
+BeginPrivate: 0
+EndPrivate
+BeginChars: 256 1
+
+StartChar: uni0000
+Encoding: 0 0 0
+Width: 2048
+LayerCount: 2
+Fore
+SplineSet
+667 1485 m 5,0,-1
+ 1327 1485 l 1,1,-1
+ 1327 0 l 1,2,-1
+ 667 0 l 1,3,-1
+ 667 1485 l 5,0,-1
+601 1575 m 1,0,-1
+ 1405 1575 l 1,1,-1
+ 1405 -63 l 1,2,-1
+ 601 -63 l 1,3,-1
+ 601 1575 l 1,0,-1
+EndSplineSet
+EndChar
+EndChars
+EndSplineFont
diff --git a/dlls/gdi32/tests/wine_nul.ttf b/dlls/gdi32/tests/wine_nul.ttf
new file mode 100644
index 0000000000000000000000000000000000000000..89e5648fd92c15da6df08bb65cbf1f52add68638
GIT binary patch
literal 1600
zcmds1OKVd>6#nME60vF{Rz!nLwbBZ<y-7t>vXC(a)Z7goVn5yTpkn<miQ#5AcE5nZ?v
z+^7p5h+9Dr+J(4r;lc+(!G++$?%av)Eck5v=H6+kMf?HI<;<MtH|Lx?GY|k);xbH}
z9vC<}cw_qdF2L!aHoh;jcK~fzLpiGCLq~d(E2(a)pFfGAQvohxUnSYbY-{Fao?jn^eI
zb__7r(Qb`o$EwXHk>OB8bYyg*aNy;~JnahqO3};a<F79$>`$Z}MJifOMV=E&**l8m
z`uTM*?oob4xn;DH%OVY*@o~!0a`t=``@np~e#+9%mc180Hq~f<02p1>%2(a)rry|V?d
z-_YIzRVzt;O}7rOO3h-q+8TI2yLNTBu8$$pd}d#CIw?nCC(a)lwLoX+MmJPG~nivdz-
z3uiOXm<ur~QUtm^+*b`N3h(a)Q@rKa6y-==Y6xSH=!Fu1z`hkepR<+(71O1_87N^}Zy
z1w3&I;tqwyJ`#eNWti}ZFhkYzfa2OOMM*`(VL@`W_yq|3KOCIHY{?7$ta)&u>X`3>
za#Um97)t-^9Gqip<9SQ70~xj<Zy#e9Bj}kF=uJ&UEPPH*I`&Lz$~4Gg(o||&siz{2
z_?enw`#vZ8V(qal?XmWZA?G^8t+}Fo?EAxvHO<Bu#tD7e6fOk4Op<ZexcO@|ZFc;e
zv8TWHIi26s59cj?w9xw=oYK7DnY*uf9wI!}yon8%)x3qM*sOUQt>U2O9qP}jlVL3*
z{z+2E3$)^z<_)yqf#yx(a)z*Egz#EEI%h7{X0?@&LCepFD!1ZpT(a)1Vz+&>bj7_R<237
z0ZAN&hcZ1Rd+gEIXOvH=z_rFzq2y^9B4sfi_>2MlmFh&TG*Ya~uH06cbd#<;?3GJ0
z?bZB>FAJ5L?62g#Aul`b)#!hYTlfqf=G?$26}(czeuLZ~)p?p5%mag7zSQ74r2Qp!
zGl`|qp>{jEk>J-Il#*acP#0D1mh<3bw|6HJ-AOk=<5HAGIULt(a)m2~wk!4iBm)ao(;
z9A_0J7UsH%9(a)llL`3IW5t<3_v__w=CyD%aRzeFVFrF?k%4Sgc`%JRLps8u*Zlg4(a)f
M;Y=Gff4rB!0iiS2CjbBd
literal 0
HcmV?d00001
--
2.29.2
Dec. 8, 2020
[resend PATCH] kernelbase: Get language sort only when required in LCMapStringEx().
by Paul Gofman
Fixes very slow loading (a few minutes) of Warhammer 40000: Inquisitor - Martyr
after b780e5f5b1bd018629bfa31431e216c7579fe9aa.
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
The 'todo_wine' test in kernel32/tests/locale.c shows that LCMapStringEx should fail for
invalid locale but this should happen regardless of LCMAP_LINGUISTIC_CASING flag
and should probably be checked separately.
dlls/kernelbase/locale.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/kernelbase/locale.c b/dlls/kernelbase/locale.c
index 7218a159844..c60b796aa48 100644
--- a/dlls/kernelbase/locale.c
+++ b/dlls/kernelbase/locale.c
@@ -5205,7 +5205,7 @@ INT WINAPI DECLSPEC_HOTPATCH LCMapStringEx( const WCHAR *locale, DWORD flags, co
WCHAR *dst, int dstlen, NLSVERSIONINFO *version,
void *reserved, LPARAM handle )
{
- const struct sortguid *sortid;
+ const struct sortguid *sortid = NULL;
LPWSTR dst_ptr;
INT len;
@@ -5236,7 +5236,7 @@ INT WINAPI DECLSPEC_HOTPATCH LCMapStringEx( const WCHAR *locale, DWORD flags, co
if (!dstlen) dst = NULL;
- if (!(sortid = get_language_sort( locale )))
+ if (flags & LCMAP_LINGUISTIC_CASING && !(sortid = get_language_sort( locale )))
{
FIXME( "unknown locale %s\n", debugstr_w(locale) );
SetLastError( ERROR_INVALID_PARAMETER );
--
2.28.0
Dec. 8, 2020
[PATCH v2 6/6] user32: Remove code that queries monitor information from SetupAPI device properties.
by Zhiyi Zhang
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/sysparams.c | 156 ++--------------------------------------
1 file changed, 4 insertions(+), 152 deletions(-)
diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c
index 57b06b3fc94..35010f28176 100644
--- a/dlls/user32/sysparams.c
+++ b/dlls/user32/sysparams.c
@@ -102,25 +102,10 @@ DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID, 0xca085853, 0x16ce, 0x48aa, 0xb1
/* Wine specific monitor properties */
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
-DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3);
-DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCWORK, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 4);
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 5);
#define NULLDRV_DEFAULT_HMONITOR ((HMONITOR)(UINT_PTR)(0x10000 + 1))
-/* Cached monitor information */
-static MONITORINFOEXW *monitors;
-static UINT monitor_count;
-static FILETIME last_query_monitors_time;
-static CRITICAL_SECTION monitors_section;
-static CRITICAL_SECTION_DEBUG monitors_critsect_debug =
-{
- 0, 0, &monitors_section,
- { &monitors_critsect_debug.ProcessLocksList, &monitors_critsect_debug.ProcessLocksList },
- 0, 0, { (DWORD_PTR)(__FILE__ ": monitors_section") }
-};
-static CRITICAL_SECTION monitors_section = { &monitors_critsect_debug, -1 , 0, 0, 0, 0 };
-
static HDC display_dc;
static CRITICAL_SECTION display_dc_section;
static CRITICAL_SECTION_DEBUG critsect_debug =
@@ -144,7 +129,6 @@ static DPI_AWARENESS dpi_awareness;
static DPI_AWARENESS default_awareness = DPI_AWARENESS_UNAWARE;
static HKEY volatile_base_key;
-static HKEY video_key;
union sysparam_all_entry;
@@ -3776,100 +3760,8 @@ HMONITOR WINAPI MonitorFromWindow(HWND hWnd, DWORD dwFlags)
return MonitorFromRect( &rect, dwFlags );
}
-/* Return FALSE on failure and TRUE on success */
-static BOOL update_monitor_cache(void)
-{
- SP_DEVINFO_DATA device_data = {sizeof(device_data)};
- HDEVINFO devinfo = INVALID_HANDLE_VALUE;
- MONITORINFOEXW *monitor_array;
- FILETIME filetime = {0};
- DWORD device_count = 0;
- HANDLE mutex = NULL;
- DWORD state_flags;
- BOOL ret = FALSE;
- BOOL is_replica;
- DWORD i = 0, j;
- DWORD type;
-
- /* Update monitor cache from SetupAPI if it's outdated */
- if (!video_key && RegOpenKeyW( HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\VIDEO", &video_key ))
- return FALSE;
- if (RegQueryInfoKeyW( video_key, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, &filetime ))
- return FALSE;
- if (CompareFileTime( &filetime, &last_query_monitors_time ) < 1)
- return TRUE;
-
- mutex = get_display_device_init_mutex();
- EnterCriticalSection( &monitors_section );
- devinfo = SetupDiGetClassDevsW( &GUID_DEVCLASS_MONITOR, L"DISPLAY", NULL, DIGCF_PRESENT );
-
- while (SetupDiEnumDeviceInfo( devinfo, i++, &device_data ))
- {
- /* Inactive monitors don't get enumerated */
- if (!SetupDiGetDevicePropertyW( devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, &type,
- (BYTE *)&state_flags, sizeof(DWORD), NULL, 0 ))
- goto fail;
- if (state_flags & DISPLAY_DEVICE_ACTIVE)
- device_count++;
- }
-
- if (device_count && monitor_count < device_count)
- {
- monitor_array = heap_alloc( device_count * sizeof(*monitor_array) );
- if (!monitor_array)
- goto fail;
- heap_free( monitors );
- monitors = monitor_array;
- }
-
- for (i = 0, monitor_count = 0; SetupDiEnumDeviceInfo( devinfo, i, &device_data ); i++)
- {
- if (!SetupDiGetDevicePropertyW( devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, &type,
- (BYTE *)&state_flags, sizeof(DWORD), NULL, 0 ))
- goto fail;
- if (!(state_flags & DISPLAY_DEVICE_ACTIVE))
- continue;
- if (!SetupDiGetDevicePropertyW( devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, &type,
- (BYTE *)&monitors[monitor_count].rcMonitor, sizeof(RECT), NULL, 0 ))
- goto fail;
-
- /* Replicas in mirroring monitor sets don't get enumerated */
- is_replica = FALSE;
- for (j = 0; j < monitor_count; j++)
- {
- if (EqualRect(&monitors[j].rcMonitor, &monitors[monitor_count].rcMonitor))
- {
- is_replica = TRUE;
- break;
- }
- }
- if (is_replica)
- continue;
-
- if (!SetupDiGetDevicePropertyW( devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCWORK, &type,
- (BYTE *)&monitors[monitor_count].rcWork, sizeof(RECT), NULL, 0 ))
- goto fail;
- if (!SetupDiGetDevicePropertyW( devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, &type,
- (BYTE *)monitors[monitor_count].szDevice, CCHDEVICENAME * sizeof(WCHAR), NULL, 0))
- goto fail;
- monitors[monitor_count].dwFlags =
- !wcscmp( L"\\\\.\\DISPLAY1", monitors[monitor_count].szDevice ) ? MONITORINFOF_PRIMARY : 0;
-
- monitor_count++;
- }
-
- last_query_monitors_time = filetime;
- ret = TRUE;
-fail:
- SetupDiDestroyDeviceInfoList( devinfo );
- LeaveCriticalSection( &monitors_section );
- release_display_device_init_mutex( mutex );
- return ret;
-}
-
BOOL CDECL nulldrv_GetMonitorInfo( HMONITOR handle, MONITORINFO *info )
{
- UINT index = (UINT_PTR)handle - 1;
WCHAR adapter_name[CCHDEVICENAME];
TRACE("(%p, %p)\n", handle, info);
@@ -3907,29 +3799,8 @@ BOOL CDECL nulldrv_GetMonitorInfo( HMONITOR handle, MONITORINFO *info )
return TRUE;
}
- if (!update_monitor_cache())
- {
- SetLastError( ERROR_INVALID_MONITOR_HANDLE );
- return FALSE;
- }
-
- EnterCriticalSection( &monitors_section );
- if (index < monitor_count)
- {
- info->rcMonitor = monitors[index].rcMonitor;
- info->rcWork = monitors[index].rcWork;
- info->dwFlags = monitors[index].dwFlags;
- if (info->cbSize >= sizeof(MONITORINFOEXW))
- lstrcpyW( ((MONITORINFOEXW *)info)->szDevice, monitors[index].szDevice );
- LeaveCriticalSection( &monitors_section );
- return TRUE;
- }
- else
- {
- LeaveCriticalSection( &monitors_section );
- SetLastError( ERROR_INVALID_MONITOR_HANDLE );
- return FALSE;
- }
+ SetLastError( ERROR_INVALID_MONITOR_HANDLE );
+ return FALSE;
}
/***********************************************************************
@@ -4064,27 +3935,8 @@ BOOL CDECL nulldrv_EnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC pro
if (i)
return TRUE;
- if (update_monitor_cache())
- {
- while (TRUE)
- {
- EnterCriticalSection( &monitors_section );
- if (i >= monitor_count)
- {
- LeaveCriticalSection( &monitors_section );
- return TRUE;
- }
- monitor_rect = monitors[i].rcMonitor;
- LeaveCriticalSection( &monitors_section );
-
- if (!proc( (HMONITOR)(UINT_PTR)(i + 1), hdc, &monitor_rect, lp ))
- return FALSE;
-
- ++i;
- }
- }
-
- /* Fallback to report one monitor if using SetupAPI failed */
+ /* Fallback to report one monitor if wineserver calls failed */
+ ERR("Failed to enumerate monitors, reporting a 640x480 monitor.\n");
SetRect( &monitor_rect, 0, 0, 640, 480 );
if (!proc( NULLDRV_DEFAULT_HMONITOR, hdc, &monitor_rect, lp ))
return FALSE;
--
2.27.0
Dec. 8, 2020
[PATCH v2 5/6] winex11.drv: Query virtual screen and primary screen rectangles from the wineserver.
by Zhiyi Zhang
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/winex11.drv/display.c | 39 ++++++++++++++++----------------------
1 file changed, 16 insertions(+), 23 deletions(-)
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index fb12b158c17..3ff9bfea531 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -47,7 +47,6 @@ DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID, 0xca085853, 0x16ce, 0x48aa, 0xb1
/* Wine specific properties */
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_GPU_VULKAN_UUID, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5c, 2);
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
-DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3);
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 5);
static const WCHAR driver_date_dataW[] = {'D','r','i','v','e','r','D','a','t','e','D','a','t','a',0};
@@ -146,14 +145,11 @@ void release_display_device_init_mutex(HANDLE mutex)
static BOOL update_screen_cache(void)
{
RECT virtual_rect = {0}, primary_rect = {0}, monitor_rect;
- SP_DEVINFO_DATA device_data = {sizeof(device_data)};
- HDEVINFO devinfo = INVALID_HANDLE_VALUE;
FILETIME filetime = {0};
HANDLE mutex = NULL;
+ NTSTATUS status;
DWORD i = 0;
INT result;
- DWORD type;
- BOOL ret = FALSE;
EnterCriticalSection(&screen_section);
if ((!video_key && RegOpenKeyW(HKEY_LOCAL_MACHINE, video_keyW, &video_key))
@@ -169,15 +165,21 @@ static BOOL update_screen_cache(void)
mutex = get_display_device_init_mutex();
- devinfo = SetupDiGetClassDevsW(&GUID_DEVCLASS_MONITOR, displayW, NULL, DIGCF_PRESENT);
- if (devinfo == INVALID_HANDLE_VALUE)
- goto fail;
-
- while (SetupDiEnumDeviceInfo(devinfo, i++, &device_data))
+ while (TRUE)
{
- if (!SetupDiGetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, &type,
- (BYTE *)&monitor_rect, sizeof(monitor_rect), NULL, 0))
- goto fail;
+ SERVER_START_REQ(enum_monitor)
+ {
+ req->index = i++;
+ if (!(status = wine_server_call(req)))
+ {
+ SetRect(&monitor_rect, reply->monitor_rect.left, reply->monitor_rect.top,
+ reply->monitor_rect.right, reply->monitor_rect.bottom);
+ }
+ }
+ SERVER_END_REQ;
+
+ if (status)
+ break;
UnionRect(&virtual_rect, &virtual_rect, &monitor_rect);
if (i == 1)
@@ -189,13 +191,8 @@ static BOOL update_screen_cache(void)
primary_monitor_rect = primary_rect;
last_query_screen_time = filetime;
LeaveCriticalSection(&screen_section);
- ret = TRUE;
-fail:
- SetupDiDestroyDeviceInfoList(devinfo);
release_display_device_init_mutex(mutex);
- if (!ret)
- WARN("Update screen cache failed!\n");
- return ret;
+ return TRUE;
}
POINT virtual_screen_to_root(INT x, INT y)
@@ -621,10 +618,6 @@ static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *mo
if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, DEVPROP_TYPE_UINT32,
(const BYTE *)&monitor->state_flags, sizeof(monitor->state_flags), 0))
goto done;
- /* RcMonitor */
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY,
- (const BYTE *)&monitor->rc_monitor, sizeof(monitor->rc_monitor), 0))
- goto done;
/* Adapter name */
sprintfW(bufferW, adapter_name_fmtW, video_index + 1);
size = (strlenW(bufferW) + 1) * sizeof(WCHAR);
--
2.27.0
Dec. 8, 2020
[PATCH v2 4/6] winemac.drv: Store monitor information in the wineserver for EnumDisplayMonitors().
by Zhiyi Zhang
Fix a regression that Office 2016/365 has a 640x480 main window.
Office 2016/365 hooks NtOpenKeyEx() and prevents access to SetupAPI device properties.
After failed to query monitor information from SetupAPI, EnumDisplayMonitors() reports
a fallback monitor of size 640x480.
As to why store the monitor information in the wineserver, it seems that EnumDisplayMonitors()
reports monitors connected to current user logon session. For instance, EnumDisplayMonitors()
always report one monitor when called by services.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/winemac.drv/display.c | 65 ++++++++++++++++++++++++++++++--------
1 file changed, 51 insertions(+), 14 deletions(-)
diff --git a/dlls/winemac.drv/display.c b/dlls/winemac.drv/display.c
index 6706c88341c..2b672ffe74b 100644
--- a/dlls/winemac.drv/display.c
+++ b/dlls/winemac.drv/display.c
@@ -32,6 +32,7 @@
#include "setupapi.h"
#define WIN32_NO_STATUS
#include "winternl.h"
+#include "wine/server.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(display);
@@ -57,8 +58,6 @@ DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID, 0xca085853, 0x16ce, 0x48aa, 0xb1
/* Wine specific monitor properties */
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
-DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3);
-DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCWORK, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 4);
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 5);
static const char initial_mode_key[] = "Initial Display Mode";
@@ -1628,10 +1627,11 @@ static BOOL macdrv_init_monitor(HDEVINFO devinfo, const struct macdrv_monitor *m
int video_index, const LUID *gpu_luid, UINT output_id)
{
SP_DEVINFO_DATA device_data = {sizeof(SP_DEVINFO_DATA)};
+ RECT monitor_rect, work_rect;
WCHAR nameW[MAX_PATH];
WCHAR bufferW[MAX_PATH];
+ DWORD size;
HKEY hkey;
- RECT rect;
BOOL ret = FALSE;
/* Create GUID_DEVCLASS_MONITOR instance */
@@ -1666,22 +1666,35 @@ static BOOL macdrv_init_monitor(HDEVINFO devinfo, const struct macdrv_monitor *m
if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_STATEFLAGS, DEVPROP_TYPE_UINT32,
(const BYTE *)&monitor->state_flags, sizeof(monitor->state_flags), 0))
goto done;
- /* RcMonitor */
- rect = rect_from_cgrect(monitor->rc_monitor);
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY,
- (const BYTE *)&rect, sizeof(rect), 0))
- goto done;
- /* RcWork */
- rect = rect_from_cgrect(monitor->rc_work);
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCWORK, DEVPROP_TYPE_BINARY,
- (const BYTE *)&rect, sizeof(rect), 0))
- goto done;
/* Adapter name */
sprintfW(bufferW, adapter_name_fmtW, video_index + 1);
+ size = (lstrlenW(bufferW) + 1) * sizeof(WCHAR);
if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, DEVPROP_TYPE_STRING,
- (const BYTE *)bufferW, (lstrlenW(bufferW) + 1) * sizeof(WCHAR), 0))
+ (const BYTE *)bufferW, size, 0))
goto done;
+ /* EnumDisplayMonitors() doesn't enumerate mirrored replicas and inactive monitors */
+ if (monitor_index == 0 && monitor->state_flags & DISPLAY_DEVICE_ACTIVE)
+ {
+ SERVER_START_REQ(create_monitor)
+ {
+ monitor_rect = rect_from_cgrect(monitor->rc_monitor);
+ req->monitor_rect.top = monitor_rect.top;
+ req->monitor_rect.left = monitor_rect.left;
+ req->monitor_rect.right = monitor_rect.right;
+ req->monitor_rect.bottom = monitor_rect.bottom;
+ work_rect = rect_from_cgrect(monitor->rc_work);
+ req->work_rect.top = work_rect.top;
+ req->work_rect.left = work_rect.left;
+ req->work_rect.right = work_rect.right;
+ req->work_rect.bottom = work_rect.bottom;
+ wine_server_add_data(req, bufferW, size);
+ if (wine_server_call(req))
+ goto done;
+ }
+ SERVER_END_REQ;
+ }
+
ret = TRUE;
done:
if (!ret)
@@ -1693,7 +1706,9 @@ static void prepare_devices(HKEY video_hkey)
{
static const BOOL not_present = FALSE;
SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+ HMONITOR monitor = NULL;
HDEVINFO devinfo;
+ NTSTATUS status;
DWORD i = 0;
/* Remove all monitors */
@@ -1705,6 +1720,28 @@ static void prepare_devices(HKEY video_hkey)
}
SetupDiDestroyDeviceInfoList(devinfo);
+ while (TRUE)
+ {
+ SERVER_START_REQ(enum_monitor)
+ {
+ req->index = 0;
+ if (!(status = wine_server_call(req)))
+ monitor = wine_server_ptr_handle(reply->handle);
+ }
+ SERVER_END_REQ;
+
+ if (status)
+ break;
+
+ SERVER_START_REQ(destroy_monitor)
+ {
+ req->handle = wine_server_user_handle(monitor);
+ if (wine_server_call(req))
+ ERR("Failed to destroy monitor.\n");
+ }
+ SERVER_END_REQ;
+ }
+
/* Clean up old adapter keys for reinitialization */
RegDeleteTreeW(video_hkey, NULL);
--
2.27.0
Dec. 8, 2020
[PATCH v2 3/6] winex11.drv: Store monitor information in the wineserver for EnumDisplayMonitors().
by Zhiyi Zhang
Fix a regression that Office 2016/365 has a 640x480 main window.
Office 2016/365 hooks NtOpenKeyEx() and prevents access to SetupAPI device properties.
After failed to query monitor information from SetupAPI, EnumDisplayMonitors() reports
a fallback monitor of size 640x480.
As to why store the monitor information in the wineserver, it seems that EnumDisplayMonitors()
reports monitors connected to current user logon session. For instance, EnumDisplayMonitors()
always report one monitor when called by services.
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/sysparams.c | 53 +++++++++++++++
dlls/user32/tests/monitor.c | 1 -
dlls/winex11.drv/display.c | 54 +++++++++++++--
server/Makefile.in | 1 +
server/display.c | 131 ++++++++++++++++++++++++++++++++++++
server/protocol.def | 35 ++++++++++
server/user.h | 13 +++-
7 files changed, 280 insertions(+), 8 deletions(-)
create mode 100644 server/display.c
diff --git a/dlls/user32/sysparams.c b/dlls/user32/sysparams.c
index a620116053a..57b06b3fc94 100644
--- a/dlls/user32/sysparams.c
+++ b/dlls/user32/sysparams.c
@@ -46,6 +46,7 @@
#include "win.h"
#include "user_private.h"
#include "wine/gdi_driver.h"
+#include "wine/server.h"
#include "wine/asm.h"
#include "wine/debug.h"
@@ -3869,9 +3870,31 @@ fail:
BOOL CDECL nulldrv_GetMonitorInfo( HMONITOR handle, MONITORINFO *info )
{
UINT index = (UINT_PTR)handle - 1;
+ WCHAR adapter_name[CCHDEVICENAME];
TRACE("(%p, %p)\n", handle, info);
+ SERVER_START_REQ( get_monitor_info )
+ {
+ req->handle = wine_server_user_handle( handle );
+ wine_server_set_reply( req, adapter_name, sizeof(adapter_name) );
+ if (!wine_server_call( req ))
+ {
+ SetRect( &info->rcMonitor, reply->monitor_rect.left, reply->monitor_rect.top,
+ reply->monitor_rect.right, reply->monitor_rect.bottom );
+ SetRect( &info->rcWork, reply->work_rect.left, reply->work_rect.top,
+ reply->work_rect.right, reply->work_rect.bottom );
+ if (!IsRectEmpty( &info->rcMonitor ) && !info->rcMonitor.top && !info->rcMonitor.left)
+ info->dwFlags = MONITORINFOF_PRIMARY;
+ else
+ info->dwFlags = 0;
+ if (info->cbSize >= sizeof(MONITORINFOEXW))
+ lstrcpyW( ((MONITORINFOEXW *)info)->szDevice, adapter_name );
+ return TRUE;
+ }
+ }
+ SERVER_END_REQ;
+
/* Fallback to report one monitor */
if (handle == NULLDRV_DEFAULT_HMONITOR)
{
@@ -3885,7 +3908,10 @@ BOOL CDECL nulldrv_GetMonitorInfo( HMONITOR handle, MONITORINFO *info )
}
if (!update_monitor_cache())
+ {
+ SetLastError( ERROR_INVALID_MONITOR_HANDLE );
return FALSE;
+ }
EnterCriticalSection( &monitors_section );
if (index < monitor_count)
@@ -4006,11 +4032,38 @@ static BOOL CALLBACK enum_mon_callback( HMONITOR monitor, HDC hdc, LPRECT rect,
BOOL CDECL nulldrv_EnumDisplayMonitors( HDC hdc, RECT *rect, MONITORENUMPROC proc, LPARAM lp )
{
+ HMONITOR monitor = NULL;
RECT monitor_rect;
+ NTSTATUS status;
DWORD i = 0;
TRACE("(%p, %p, %p, 0x%lx)\n", hdc, rect, proc, lp);
+ while (TRUE)
+ {
+ SERVER_START_REQ( enum_monitor )
+ {
+ req->index = i;
+ if (!(status = wine_server_call( req )))
+ {
+ SetRect( &monitor_rect, reply->monitor_rect.left, reply->monitor_rect.top,
+ reply->monitor_rect.right, reply->monitor_rect.bottom );
+ monitor = wine_server_ptr_handle( reply->handle );
+ }
+ }
+ SERVER_END_REQ;
+
+ if (status)
+ break;
+
+ ++i;
+ if (!proc( monitor, hdc, &monitor_rect, lp ))
+ return FALSE;
+ }
+
+ if (i)
+ return TRUE;
+
if (update_monitor_cache())
{
while (TRUE)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index 5e4cc9d154f..9594ad700a7 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -1964,7 +1964,6 @@ static BOOL CALLBACK test_handle_proc(HMONITOR full_monitor, HDC hdc, LPRECT rec
monitor = (HMONITOR)((ULONG_PTR)full_monitor | ((ULONG_PTR)~0u << 16));
SetLastError(0xdeadbeef);
ret = GetMonitorInfoW(monitor, &monitor_info);
- todo_wine_if(((ULONG_PTR)full_monitor >> 16) == 0)
ok(ret, "GetMonitorInfoW failed, error %#x.\n", GetLastError());
monitor = (HMONITOR)((ULONG_PTR)full_monitor & 0xffff);
diff --git a/dlls/winex11.drv/display.c b/dlls/winex11.drv/display.c
index 0f61f9f7b2e..fb12b158c17 100644
--- a/dlls/winex11.drv/display.c
+++ b/dlls/winex11.drv/display.c
@@ -34,6 +34,7 @@
#define WIN32_NO_STATUS
#include "winternl.h"
#include "wine/debug.h"
+#include "wine/server.h"
#include "wine/unicode.h"
#include "x11drv.h"
@@ -47,7 +48,6 @@ DEFINE_DEVPROPKEY(DEVPROPKEY_MONITOR_OUTPUT_ID, 0xca085853, 0x16ce, 0x48aa, 0xb1
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_GPU_VULKAN_UUID, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5c, 2);
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_STATEFLAGS, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 2);
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCMONITOR, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 3);
-DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_RCWORK, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 4);
DEFINE_DEVPROPKEY(WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, 0x233a9ef3, 0xafc4, 0x4abd, 0xb5, 0x64, 0xc3, 0x2f, 0x21, 0xf1, 0x53, 0x5b, 5);
static const WCHAR driver_date_dataW[] = {'D','r','i','v','e','r','D','a','t','e','D','a','t','a',0};
@@ -586,6 +586,7 @@ static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *mo
{
SP_DEVINFO_DATA device_data = {sizeof(SP_DEVINFO_DATA)};
WCHAR bufferW[MAX_PATH];
+ DWORD size;
HKEY hkey;
BOOL ret = FALSE;
@@ -624,16 +625,33 @@ static BOOL X11DRV_InitMonitor(HDEVINFO devinfo, const struct x11drv_monitor *mo
if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCMONITOR, DEVPROP_TYPE_BINARY,
(const BYTE *)&monitor->rc_monitor, sizeof(monitor->rc_monitor), 0))
goto done;
- /* RcWork */
- if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_RCWORK, DEVPROP_TYPE_BINARY,
- (const BYTE *)&monitor->rc_work, sizeof(monitor->rc_work), 0))
- goto done;
/* Adapter name */
sprintfW(bufferW, adapter_name_fmtW, video_index + 1);
+ size = (strlenW(bufferW) + 1) * sizeof(WCHAR);
if (!SetupDiSetDevicePropertyW(devinfo, &device_data, &WINE_DEVPROPKEY_MONITOR_ADAPTERNAME, DEVPROP_TYPE_STRING,
- (const BYTE *)bufferW, (strlenW(bufferW) + 1) * sizeof(WCHAR), 0))
+ (const BYTE *)bufferW, size, 0))
goto done;
+ /* EnumDisplayMonitors() doesn't enumerate mirrored replicas and inactive monitors */
+ if (monitor_index == 0 && monitor->state_flags & DISPLAY_DEVICE_ACTIVE)
+ {
+ SERVER_START_REQ(create_monitor)
+ {
+ req->monitor_rect.top = monitor->rc_monitor.top;
+ req->monitor_rect.left = monitor->rc_monitor.left;
+ req->monitor_rect.right = monitor->rc_monitor.right;
+ req->monitor_rect.bottom = monitor->rc_monitor.bottom;
+ req->work_rect.top = monitor->rc_work.top;
+ req->work_rect.left = monitor->rc_work.left;
+ req->work_rect.right = monitor->rc_work.right;
+ req->work_rect.bottom = monitor->rc_work.bottom;
+ wine_server_add_data(req, bufferW, size);
+ if (wine_server_call(req))
+ goto done;
+ }
+ SERVER_END_REQ;
+ }
+
ret = TRUE;
done:
if (!ret)
@@ -645,7 +663,9 @@ static void prepare_devices(HKEY video_hkey)
{
static const BOOL not_present = FALSE;
SP_DEVINFO_DATA device_data = {sizeof(device_data)};
+ HMONITOR monitor = NULL;
HDEVINFO devinfo;
+ NTSTATUS status;
DWORD i = 0;
/* Remove all monitors */
@@ -657,6 +677,28 @@ static void prepare_devices(HKEY video_hkey)
}
SetupDiDestroyDeviceInfoList(devinfo);
+ while (TRUE)
+ {
+ SERVER_START_REQ(enum_monitor)
+ {
+ req->index = 0;
+ if (!(status = wine_server_call(req)))
+ monitor = wine_server_ptr_handle(reply->handle);
+ }
+ SERVER_END_REQ;
+
+ if (status)
+ break;
+
+ SERVER_START_REQ(destroy_monitor)
+ {
+ req->handle = wine_server_user_handle(monitor);
+ if (wine_server_call(req))
+ ERR("Failed to destroy monitor.\n");
+ }
+ SERVER_END_REQ;
+ }
+
/* Clean up old adapter keys for reinitialization */
RegDeleteTreeW(video_hkey, NULL);
diff --git a/server/Makefile.in b/server/Makefile.in
index 4264e3db108..8e05ebed510 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -10,6 +10,7 @@ C_SRCS = \
console.c \
debugger.c \
device.c \
+ display.c \
directory.c \
event.c \
fd.c \
diff --git a/server/display.c b/server/display.c
new file mode 100644
index 00000000000..8e1413a9529
--- /dev/null
+++ b/server/display.c
@@ -0,0 +1,131 @@
+/*
+ * Server-side display device management
+ *
+ * Copyright (C) 2020 Zhiyi Zhang 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 "config.h"
+
+#include <stdarg.h>
+
+#include "ntstatus.h"
+#define WIN32_NO_STATUS
+#include "winternl.h"
+
+#include "request.h"
+#include "user.h"
+
+static struct list monitor_list = LIST_INIT(monitor_list);
+
+/* retrieve a pointer to a monitor from its handle */
+static struct monitor *get_monitor( user_handle_t handle )
+{
+ struct monitor *monitor;
+
+ if (!(monitor = get_user_object( handle, USER_MONITOR )))
+ set_win32_error( ERROR_INVALID_MONITOR_HANDLE );
+ return monitor;
+}
+
+/* create a monitor */
+static struct monitor *create_monitor( const struct unicode_str *adapter_name,
+ const rectangle_t *monitor_rect,
+ const rectangle_t *work_rect)
+{
+ struct monitor *monitor;
+
+ if (!(monitor = mem_alloc( sizeof(*monitor) )))
+ goto failed;
+
+ if (!(monitor->adapter_name = memdup( adapter_name->str, adapter_name->len )))
+ goto failed;
+ monitor->adapter_name_len = adapter_name->len;
+
+ if (!(monitor->handle = alloc_user_handle( monitor, USER_MONITOR )))
+ goto failed;
+
+ monitor->monitor_rect = *monitor_rect;
+ monitor->work_rect = *work_rect;
+ list_add_tail( &monitor_list, &monitor->entry );
+ return monitor;
+
+failed:
+ if (monitor)
+ {
+ if (monitor->adapter_name)
+ free( monitor->adapter_name );
+ free( monitor );
+ }
+ set_error( STATUS_UNSUCCESSFUL );
+ return NULL;
+}
+
+/* create a monitor */
+DECL_HANDLER(create_monitor)
+{
+ struct unicode_str adapter_name;
+ struct monitor *monitor;
+
+ adapter_name = get_req_unicode_str();
+ if ((monitor = create_monitor( &adapter_name, &req->monitor_rect, &req->work_rect )))
+ reply->handle = monitor->handle;
+}
+
+/* get information about a monitor */
+DECL_HANDLER(get_monitor_info)
+{
+ struct monitor *monitor;
+
+ if (!(monitor = get_monitor( req->handle )))
+ return;
+
+ reply->monitor_rect = monitor->monitor_rect;
+ reply->work_rect = monitor->work_rect;
+ set_reply_data( monitor->adapter_name, min(monitor->adapter_name_len, get_reply_max_size()) );
+ return;
+}
+
+/* enumerate monitors */
+DECL_HANDLER(enum_monitor)
+{
+ struct monitor *monitor;
+ unsigned int index = 0;
+
+ LIST_FOR_EACH_ENTRY( monitor, &monitor_list, struct monitor, entry )
+ {
+ if (req->index > index++)
+ continue;
+
+ reply->handle = monitor->handle;
+ reply->monitor_rect = monitor->monitor_rect;
+ return;
+ }
+ set_error( STATUS_NO_MORE_ENTRIES );
+}
+
+/* destroy a monitor */
+DECL_HANDLER(destroy_monitor)
+{
+ struct monitor *monitor;
+
+ if (!(monitor = get_monitor( req->handle )))
+ return;
+
+ free_user_handle( monitor->handle );
+ list_remove( &monitor->entry );
+ free( monitor->adapter_name );
+ free( monitor );
+}
diff --git a/server/protocol.def b/server/protocol.def
index a3708f20705..25a1be73610 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -2659,6 +2659,41 @@ enum coords_relative
#define SET_USER_OBJECT_GET_FULL_NAME 2
+/* Create a monitor */
+(a)REQ(create_monitor)
+ rectangle_t monitor_rect; /* monitor rectangle */
+ rectangle_t work_rect; /* monitor work area rectangle */
+ VARARG(adapter,unicode_str); /* adapter name */
+(a)REPLY
+ user_handle_t handle; /* handle to the monitor */
+(a)END
+
+
+/* Get information about a monitor */
+(a)REQ(get_monitor_info)
+ user_handle_t handle; /* handle to the monitor */
+(a)REPLY
+ rectangle_t monitor_rect; /* monitor rectangle */
+ rectangle_t work_rect; /* monitor work area rectangle */
+ VARARG(adapter,unicode_str); /* adapter name */
+(a)END
+
+
+/* Enumerate monitors */
+(a)REQ(enum_monitor)
+ unsigned int index; /* current index */
+(a)REPLY
+ user_handle_t handle; /* handle to the monitor */
+ rectangle_t monitor_rect; /* monitor rectangle */
+(a)END
+
+
+/* Destroy a monitor */
+(a)REQ(destroy_monitor)
+ user_handle_t handle; /* handle to the monitor */
+(a)END
+
+
/* Register a hotkey */
@REQ(register_hotkey)
user_handle_t window; /* handle to the window */
diff --git a/server/user.h b/server/user.h
index 6267f3e2881..6d36f0239d9 100644
--- a/server/user.h
+++ b/server/user.h
@@ -36,7 +36,8 @@ enum user_object
{
USER_WINDOW = 1,
USER_HOOK,
- USER_CLIENT /* arbitrary client handle */
+ USER_CLIENT, /* arbitrary client handle */
+ USER_MONITOR
};
#define DESKTOP_ATOM ((atom_t)32769)
@@ -79,6 +80,16 @@ struct desktop
unsigned char keystate[256]; /* asynchronous key state */
};
+struct monitor
+{
+ user_handle_t handle; /* monitor handle */
+ struct list entry; /* entry in global monitor list */
+ rectangle_t monitor_rect; /* monitor rectangle */
+ rectangle_t work_rect; /* monitor work area rectangle */
+ WCHAR *adapter_name; /* adapter name */
+ data_size_t adapter_name_len; /* adapter name length */
+};
+
/* user handles functions */
extern user_handle_t alloc_user_handle( void *ptr, enum user_object type );
--
2.27.0
Dec. 8, 2020
[PATCH v2 2/6] user32/tests: Test that monitor enumeration is not affected by window stations and desktops.
by Zhiyi Zhang
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/tests/monitor.c | 52 ++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index 2ca6e9ece84..5e4cc9d154f 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -1510,10 +1510,21 @@ static BOOL CALLBACK test_EnumDisplayMonitors_invalid_handle_cb(HMONITOR monitor
return TRUE;
}
+static BOOL CALLBACK test_EnumDisplayMonitors_count(HMONITOR monitor, HDC hdc, LPRECT rect,
+ LPARAM lparam)
+{
+ INT *count = (INT *)lparam;
+ ++(*count);
+ return TRUE;
+}
+
static void test_EnumDisplayMonitors(void)
{
+ static const DWORD DESKTOP_ALL_ACCESS = 0x01ff;
+ HWINSTA winstation, old_winstation;
+ HDESK desktop, old_desktop;
+ INT count, old_count;
DWORD error;
- INT count;
BOOL ret;
ret = EnumDisplayMonitors(NULL, NULL, test_EnumDisplayMonitors_normal_cb, 0);
@@ -1534,6 +1545,45 @@ static void test_EnumDisplayMonitors(void)
else
ok(ret, "EnumDisplayMonitors failed.\n");
ok(error == 0xdeadbeef, "Expected error %#x, got %#x.\n", 0xdeadbeef, error);
+
+ /* Test that monitor enumeration is not affected by window stations and desktops */
+ old_winstation = GetProcessWindowStation();
+ old_desktop = GetThreadDesktop(GetCurrentThreadId());
+ old_count = GetSystemMetrics(SM_CMONITORS);
+
+ count = 0;
+ ret = EnumDisplayMonitors(NULL, NULL, test_EnumDisplayMonitors_count, (LPARAM)&count);
+ ok(ret, "EnumDisplayMonitors failed, error %#x.\n", GetLastError());
+ ok(count == old_count, "Expected %d, got %d.\n", old_count, count);
+
+ winstation = CreateWindowStationW(NULL, 0, WINSTA_ALL_ACCESS, NULL);
+ ok(!!winstation && winstation != old_winstation, "CreateWindowStationW failed, error %#x.\n", GetLastError());
+ ret = SetProcessWindowStation(winstation);
+ ok(ret, "SetProcessWindowStation failed, error %#x.\n", GetLastError());
+ ok(winstation == GetProcessWindowStation(), "Expected %p, got %p.\n", GetProcessWindowStation(), winstation);
+
+ desktop = CreateDesktopW(L"test_desktop", NULL, NULL, 0, DESKTOP_ALL_ACCESS, NULL);
+ ok(!!desktop && desktop != old_desktop, "CreateDesktopW failed, error %#x.\n", GetLastError());
+ ret = SetThreadDesktop(desktop);
+ ok(ret, "SetThreadDesktop failed, error %#x.\n", GetLastError());
+ ok(desktop == GetThreadDesktop(GetCurrentThreadId()), "Expected %p, got %p.\n",
+ GetThreadDesktop(GetCurrentThreadId()), desktop);
+
+ count = GetSystemMetrics(SM_CMONITORS);
+ ok(count == old_count, "Expected %d, got %d.\n", old_count, count);
+ count = 0;
+ ret = EnumDisplayMonitors(NULL, NULL, test_EnumDisplayMonitors_count, (LPARAM)&count);
+ ok(ret, "EnumDisplayMonitors failed, error %#x.\n", GetLastError());
+ ok(count == old_count, "Expected %d, got %d.\n", old_count, count);
+
+ ret = SetProcessWindowStation(old_winstation);
+ ok(ret, "SetProcessWindowStation failed, error %#x.\n", GetLastError());
+ ret = SetThreadDesktop(old_desktop);
+ ok(ret, "SetThreadDesktop failed, error %#x.\n", GetLastError());
+ ret = CloseDesktop(desktop);
+ ok(ret, "CloseDesktop failed, error %#x.\n", GetLastError());
+ ret = CloseWindowStation(winstation);
+ ok(ret, "CloseWindowStation failed, error %#x.\n", GetLastError());
}
static void test_QueryDisplayConfig_result(UINT32 flags,
--
2.27.0
Dec. 8, 2020
[PATCH v2 1/6] user32/tests: Test that monitor handles are user32 handles.
by Zhiyi Zhang
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/user32/tests/monitor.c | 81 +++++++++++++++++++++++++++++++++++++
1 file changed, 81 insertions(+)
diff --git a/dlls/user32/tests/monitor.c b/dlls/user32/tests/monitor.c
index c3f5d1eddcb..2ca6e9ece84 100644
--- a/dlls/user32/tests/monitor.c
+++ b/dlls/user32/tests/monitor.c
@@ -1862,6 +1862,86 @@ static void test_display_config(void)
test_DisplayConfigGetDeviceInfo();
}
+static BOOL CALLBACK test_handle_proc(HMONITOR full_monitor, HDC hdc, LPRECT rect, LPARAM lparam)
+{
+ MONITORINFO monitor_info = {sizeof(monitor_info)};
+ HMONITOR monitor;
+ BOOL ret;
+
+#ifdef _WIN64
+ if ((ULONG_PTR)full_monitor >> 32)
+ monitor = full_monitor;
+ else
+ monitor = (HMONITOR)((ULONG_PTR)full_monitor | ((ULONG_PTR)~0u << 32));
+ SetLastError(0xdeadbeef);
+ ret = GetMonitorInfoW(monitor, &monitor_info);
+ ok(ret, "GetMonitorInfoW failed, error %#x.\n", GetLastError());
+
+ monitor = (HMONITOR)((ULONG_PTR)full_monitor & 0xffffffff);
+ SetLastError(0xdeadbeef);
+ ret = GetMonitorInfoW(monitor, &monitor_info);
+ ok(ret, "GetMonitorInfoW failed, error %#x.\n", GetLastError());
+
+ monitor = (HMONITOR)(((ULONG_PTR)full_monitor & 0xffffffff) | ((ULONG_PTR)0x1234 << 32));
+ SetLastError(0xdeadbeef);
+ ret = GetMonitorInfoW(monitor, &monitor_info);
+ ok(ret, "GetMonitorInfoW failed, error %#x.\n", GetLastError());
+
+ monitor = (HMONITOR)((ULONG_PTR)full_monitor & 0xffff);
+ SetLastError(0xdeadbeef);
+ ret = GetMonitorInfoW(monitor, &monitor_info);
+ todo_wine ok(!ret, "GetMonitorInfoW succeeded.\n");
+ todo_wine ok(GetLastError() == ERROR_INVALID_MONITOR_HANDLE, "Expected error code %#x, got %#x.\n",
+ ERROR_INVALID_MONITOR_HANDLE, GetLastError());
+
+ monitor = (HMONITOR)(((ULONG_PTR)full_monitor & 0xffff) | ((ULONG_PTR)0x9876 << 16));
+ SetLastError(0xdeadbeef);
+ ret = GetMonitorInfoW(monitor, &monitor_info);
+ ok(!ret, "GetMonitorInfoW succeeded.\n");
+ ok(GetLastError() == ERROR_INVALID_MONITOR_HANDLE, "Expected error code %#x, got %#x.\n",
+ ERROR_INVALID_MONITOR_HANDLE, GetLastError());
+
+ monitor = (HMONITOR)(((ULONG_PTR)full_monitor & 0xffff) | ((ULONG_PTR)0x12345678 << 16));
+ SetLastError(0xdeadbeef);
+ ret = GetMonitorInfoW(monitor, &monitor_info);
+ ok(!ret, "GetMonitorInfoW succeeded.\n");
+ ok(GetLastError() == ERROR_INVALID_MONITOR_HANDLE, "Expected error code %#x, got %#x.\n",
+ ERROR_INVALID_MONITOR_HANDLE, GetLastError());
+#else
+ if ((ULONG_PTR)full_monitor >> 16)
+ monitor = full_monitor;
+ else
+ monitor = (HMONITOR)((ULONG_PTR)full_monitor | ((ULONG_PTR)~0u << 16));
+ SetLastError(0xdeadbeef);
+ ret = GetMonitorInfoW(monitor, &monitor_info);
+ todo_wine_if(((ULONG_PTR)full_monitor >> 16) == 0)
+ ok(ret, "GetMonitorInfoW failed, error %#x.\n", GetLastError());
+
+ monitor = (HMONITOR)((ULONG_PTR)full_monitor & 0xffff);
+ SetLastError(0xdeadbeef);
+ ret = GetMonitorInfoW(monitor, &monitor_info);
+ ok(ret, "GetMonitorInfoW failed, error %#x.\n", GetLastError());
+
+ monitor = (HMONITOR)(((ULONG_PTR)full_monitor & 0xffff) | ((ULONG_PTR)0x1234 << 16));
+ SetLastError(0xdeadbeef);
+ ret = GetMonitorInfoW(monitor, &monitor_info);
+ ok(!ret, "GetMonitorInfoW succeeded.\n");
+ ok(GetLastError() == ERROR_INVALID_MONITOR_HANDLE, "Expected error code %#x, got %#x.\n",
+ ERROR_INVALID_MONITOR_HANDLE, GetLastError());
+#endif
+
+ return TRUE;
+}
+
+static void test_handles(void)
+{
+ BOOL ret;
+
+ /* Test that monitor handles are user32 handles */
+ ret = EnumDisplayMonitors(NULL, NULL, test_handle_proc, 0);
+ ok(ret, "EnumDisplayMonitors failed, error %#x.\n", GetLastError());
+}
+
START_TEST(monitor)
{
init_function_pointers();
@@ -1871,4 +1951,5 @@ START_TEST(monitor)
test_monitors();
test_work_area();
test_display_config();
+ test_handles();
}
--
2.27.0
Dec. 8, 2020
[PATCH] iphlpapi: Fix copy-paste error.
by Chip Davis
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50274
Signed-off-by: Chip Davis <cdavis(a)codeweavers.com>
---
dlls/iphlpapi/ipstats.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/iphlpapi/ipstats.c b/dlls/iphlpapi/ipstats.c
index 0fa446c21a5a..36f90f2c3a83 100644
--- a/dlls/iphlpapi/ipstats.c
+++ b/dlls/iphlpapi/ipstats.c
@@ -2980,7 +2980,7 @@ DWORD build_tcp6_table( TCP_TABLE_CLASS class, void **tablep, BOOL order, HANDLE
row.dwLocalScopeId = find_ipv6_addr_scope( (const IN6_ADDR *)&row.ucLocalAddr, addr_scopes, addr_scopes_size );
memcpy( &row.ucRemoteAddr, &in->in6p_faddr.s6_addr, sizeof(row.ucRemoteAddr) );
row.dwRemotePort = in->inp_fport;
- row.dwLocalScopeId = find_ipv6_addr_scope( (const IN6_ADDR *)&row.ucRemoteAddr, addr_scopes, addr_scopes_size );
+ row.dwRemoteScopeId = find_ipv6_addr_scope( (const IN6_ADDR *)&row.ucRemoteAddr, addr_scopes, addr_scopes_size );
row.dwState = TCPStateToMIBState( tcp->t_state );
if (!match_class( class, row.dwState )) continue;
--
2.28.0
Dec. 8, 2020
[PATCH] conhost: Use QS_ALLINPUT to wait for input in main loop.
by Jacek Caban
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50014
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
programs/conhost/conhost.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Dec. 8, 2020
[PATCH] conhost: Fix handling selection boundries in copy_selection.
by Jacek Caban
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50052
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
programs/conhost/window.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
Dec. 7, 2020
Re: [PATCH] conhost: Fix handling selection boundries in copy_selection.
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=83202
Your paranoid android.
=== debiant (build log) ===
error: patch failed: programs/conhost/window.c:969
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: programs/conhost/window.c:969
Task: Patch failed to apply
Dec. 7, 2020
Re: [PATCH] ieframe/tests: Use wide-char string literals.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Dec. 7, 2020
Re: [PATCH] jscript/tests: Use wide-char string literals.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Dec. 7, 2020
[PATCH vkd3d] vkd3d: Fix misplaced parenthesis.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
libs/vkd3d/device.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index bef6477..a63fc92 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -417,7 +417,7 @@ static void vkd3d_init_debug_report(struct vkd3d_instance *instance)
callback_info.flags = VK_DEBUG_REPORT_ERROR_BIT_EXT | VK_DEBUG_REPORT_WARNING_BIT_EXT;
callback_info.pfnCallback = vkd3d_debug_report_callback;
callback_info.pUserData = NULL;
- if ((vr = VK_CALL(vkCreateDebugReportCallbackEXT(vk_instance, &callback_info, NULL, &callback)) < 0))
+ if ((vr = VK_CALL(vkCreateDebugReportCallbackEXT(vk_instance, &callback_info, NULL, &callback))) < 0)
{
WARN("Failed to create debug report callback, vr %d.\n", vr);
return;
--
2.28.0
Dec. 7, 2020
[PATCH] conhost: Fix handling selection boundries in copy_selection.
by Jacek Caban
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50052
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
programs/conhost/window.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
Dec. 7, 2020
Re: [PATCH vkd3d v3 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=83192
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. 7, 2020
Re: [PATCH vkd3d v3 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=83191
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. 7, 2020
Re: [PATCH vkd3d v3 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=83190
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. 7, 2020
Re: [PATCH vkd3d v3 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=83189
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. 7, 2020
Re: [PATCH vkd3d v3 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=83188
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. 7, 2020
TestBot news
by Francois Gouget
Summary:
* New w1064 VM with all Windows 10 fall releases.
* Rebuilt w7u VM with dual-screen and some languages.
* Cleaned up wvista VM.
* The cw-rx460 Linux results are back.
* The vm3 SSD died, will be replaced soon.
* Test PCI-passthrough VM on the development TestBot.
w1064
-----
This is essentially the same as the w10pro64 VM but with test
configurations for 1507, 1607, 1709, 1809, 1909 and the latest 2009.
The goal is to spread the testing load across two VM hosts. So w10pro64
will handle all (or most of) the languages, while w1064 will handle the
older Windows 10 releases and a few extra configurations like
dual-screen and test without elevated privileges (not yet present), etc.
I will try to update w10pro64 to the latest spring Windows releases
while I will keep adding fall releases to w1064. So they should each get
updated once a year.
w7u
---
I rebuilt this VM from scratch to get it on more recent QEMu virtual
hardware; and only kept the latest configuration.
Here is the base configuration summary:
[CPU:2*IvyBridge-IBRS RAM:2GB disk:scsi-unmap eth:e1000-metered snd:ich9
GPU:vga display:spice virtio:0.1.185 testagentd:1.8]
The most annoying part is getting Windows Update to work because the
servers now require SHA2 but Windows 7 does not support it out of the
box. So I had to find and manually install the right KB fix to get it
going. Then Windows Update ran out of memory so I installed another KB
fix so it would just take forever to install a measly ~160 updates.
So to summarize I installed SP1 manually, added KB4474419 to add SHA2
support, KB3050265 to prevent Windows Update from running out of memory,
KB2852386 to get winsxs disk cleanup options, and finally installed all
updates up to 2020-11-25.
Then I added a dual screen test configuration, a non-elevated privileges
configuration and a few European languages.
I avoided languages with tricky scripts because I was not sure if
Windows 7 would support them right (Vista does not). And I decided to
pick a set that does not overlap with the ones the Windows 10 VM is
already testing. Let me know if you need a different set of languages.
wvista
------
I flattened all the snapshots to only keep the latest version, that is
all updates up to 2014-04-21.
Note that Vista runs into the same Windows Update issue as Windows 7:
SHA2 support is required by the servers. But there's no way to get SHA2
support on Vista which means Vista has no Windows Update support at all.
I also tweaked the hardware configuration and updated the QEmu drivers.
[CPU:1*SandyBridge-IBRS RAM:2GB disk:scsi-unmap eth:e1000 snd:ac97
GPU:vga display:spice virtio:0.1.185 testagentd:1.8]
The new configuration seems to be working pretty well except for
test_driver4() in ntoskrnl.exe:ntoskrnl which crashes Vista. So I only
run WineTest without elevated privileges which forces a skip of that
test. But you can still run the tests with elevated privileges if you
manually submit a job.
cw-rx460 Linux results
----------------------
cw-rx460 is not a TestBot VM but does run WineTest daily and has the
advantage of running on real hardware. For a long time it failed to
reliably submit WineTest results. Now it works again (the issue was in
the wt-bot script).
vm3 SSD
-------
The SSD of the vm3 host died last week so I moved its VMs to vm1 and
vm4. That's part of why the TestBot was slow at the start of the week.
The other reasons are:
* The Debian VM which is bloated and which I'm working on updating with
a new libX11,
* The couple older Debian configurations which I removed.
* Too many VMs on vm1 (I moved some to vm4).
vm4's SSD is also on the brink of death according to smartctl so they'll
both get new and bigger SSDs soon.
PCI-passthrough
---------------
I also set up a new Windows 10 Pro VM on my development TestBot
environment and added a configuration with an RX550 graphics card to it
using PCI-passthrough.
That seems to be working [1] so far, by which I mostly mean that besides
actually running its TestBot tasks the graphics card has not locked up
and required a host reboot yet.
What's annoying is that this VM crashes when it runs ntdll:exception so
which prevents it from submitting its test results. That is however
totally unrelated to the RX550 since it also happens with QEmu's
built-in vga graphics card (a test configuration which has never seen
the RX550 in any shape or form).
Another thing that's missing is support for screenshots but I figure
that can come later (it would be great if someone wanted to tackle bug
44709).
There are many PCI-passthrough recipes online, but here's mine, just for
adding the passthrough to an existing Windows VM (i.e. it assumes you've
configured the host already):
* While still using QEmu's built-in vga card, install TightVNC (or
equivalent).
I prefer to avoid Windows' RDP because that uses a separate desktop
with its own graphics driver, changes the resolution, and disables
sound. All that means I wouldn't really know what's going on with the
actual graphics card.
* Then power off and virsh edit to:
- replace the <domain...> line with
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>
- add these lines before the closing </domain>
(in fact it's likely fine anywhere)
<qemu:commandline>
<qemu:arg value='-set'/>
<qemu:arg value='device.hostdev0.x-vga=on'/>
</qemu:commandline>
* Remove the Display (Spice), Video (VGA), Tablet (USB|Virtio), and
Sound (ich9) devices. Add the graphics card's two PCI devices (GPU +
audio).
* Boot up, connect using VNC, install the graphics driver, reboot again.
* All done.
[1] One side effect is that whenever the RX550 configuration powers up
it messes the colors of my desktop, as if it switched some palette.
Fortunately all I have to do is to switch the focus to another
window to fix it so I'm just putting up with it.
--
Francois Gouget <fgouget(a)codeweavers.com>
Dec. 7, 2020
[PATCH vkd3d v3 5/5] vkd3d-shader: Implement basic support for #if and #endif.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
v3: avoid YYerror which is only available since bison 3.6
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 116a7ed5..1b0d771d 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 0;
+ 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 0;
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. 7, 2020
[PATCH vkd3d v3 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 4d809b8f..116a7ed5 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 0;
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. 7, 2020
[PATCH vkd3d v3 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 89a4f606..4d809b8f 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. 7, 2020
[PATCH vkd3d v3 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 656ad674..89a4f606 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. 7, 2020
[PATCH vkd3d v3 1/5] vkd3d-shader: Implement an initial pass-through HLSL preprocessor.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
v3: add the generated flex/bison files to CLEANFILES; avoid a bison warning by
always setting the output file to preproc.tab.c; avoid YYEOF which is only
available since bison 3.6
.gitignore | 3 +
Makefile.am | 31 +++++++-
configure.ac | 6 ++
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, 265 insertions(+), 22 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..32c8777f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -108,6 +108,33 @@ 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 =
+
+libs/vkd3d-shader/preproc.yy.c: libs/vkd3d-shader/preproc.l
+ $(VKD3D_V_FLEX)$(FLEX) $(LFLAGS) -o $@ $<
+
+libs/vkd3d-shader/preproc.tab.c libs/vkd3d-shader/preproc.tab.h &: libs/vkd3d-shader/preproc.y
+ $(VKD3D_V_BISON)$(BISON) $(YFLAGS) -d -o libs/vkd3d-shader/preproc.tab.c $<
+
+BUILT_SOURCES += libs/vkd3d-shader/preproc.tab.h
+
+vkd3d_shader_yyfiles = \
+ libs/vkd3d-shader/preproc.tab.c \
+ libs/vkd3d-shader/preproc.tab.h \
+ libs/vkd3d-shader/preproc.yy.c
+
+CLEANFILES = $(vkd3d_shader_yyfiles)
+
+nodist_libvkd3d_shader_la_SOURCES = $(vkd3d_shader_yyfiles)
+
libvkd3d_shader_la_SOURCES = \
include/private/list.h \
include/private/rbtree.h \
@@ -122,7 +149,7 @@ libvkd3d_shader_la_SOURCES = \
libs/vkd3d-shader/vkd3d_shader.map \
libs/vkd3d-shader/vkd3d_shader_main.c \
libs/vkd3d-shader/vkd3d_shader_private.h
-libvkd3d_shader_la_CFLAGS = $(AM_CFLAGS) @SPIRV_TOOLS_CFLAGS@
+libvkd3d_shader_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libs/vkd3d-shader @SPIRV_TOOLS_CFLAGS@
libvkd3d_shader_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
libvkd3d_shader_la_LIBADD = libvkd3d-common.la @SPIRV_TOOLS_LIBS@
if HAVE_LD_VERSION_SCRIPT
@@ -173,7 +200,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..b7902b63 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,6 +30,12 @@ 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])
+AS_IF([test "$FLEX" = "none"], [AC_MSG_ERROR([no suitable flex found. Please install the 'flex' package.])])
+
+AC_CHECK_PROGS([BISON], [bison], [none])
+AS_IF([test "$BISON" = "none"], [AC_MSG_ERROR([no suitable bison found. Please install the 'bison' package.])])
+
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..656ad674
--- /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 0;
+ 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. 7, 2020
[PATCH] setupapi: Handle NULL source filename in build_filepathsW.
by Hans Leidekker
Source filename is NULL for files to be deleted.
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/setupapi/queue.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/setupapi/queue.c b/dlls/setupapi/queue.c
index 7ed66c298d3..dc718cc66fc 100644
--- a/dlls/setupapi/queue.c
+++ b/dlls/setupapi/queue.c
@@ -152,7 +152,7 @@ static BOOL build_filepathsW( const struct file_op *op, FILEPATHS_W *paths )
unsigned int src_len = 1, dst_len = 1;
WCHAR *source = (PWSTR)paths->Source, *target = (PWSTR)paths->Target;
- if (op->src_file[0] != '@')
+ if (!op->src_file || op->src_file[0] != '@')
{
if (op->media) src_len += lstrlenW(op->media->root) + 1;
if (op->src_path) src_len += lstrlenW(op->src_path) + 1;
@@ -174,7 +174,7 @@ static BOOL build_filepathsW( const struct file_op *op, FILEPATHS_W *paths )
paths->Target = target = HeapAlloc( GetProcessHeap(), 0, dst_len );
}
if (!source || !target) return FALSE;
- if (op->src_file[0] != '@')
+ if (!op->src_file || op->src_file[0] != '@')
concat_W( source, op->media ? op->media->root : NULL, op->src_path, op->src_file );
else
lstrcpyW( source, op->src_file );
--
2.20.1
Dec. 7, 2020
Re: ntdll:exception crashes some Windows 10
by Paul Gofman
On 12/7/20 17:07, Francois Gouget wrote:
> So I have a problem with ntdll:exception: it crashes the Windows 10 VM I
> set up on my development TestBot machine. I'd appreciate any insight you
> may have.
>
> The VM is Windows 10 Pro 64-bit [1] with all updates all the way to
> 2020-11-03. And the following exception.c lines cause it to crash:
>
> dreg_test.dr0 = 0x42424240;
> dreg_test.dr2 = 0x126bb070;
> dreg_test.dr3 = 0x0badbad0;
> dreg_test.dr7 = 0xffff0115;
> run_exception_test(dreg_handler, &dreg_test, &segfault_code, sizeof(segfault_code), 0);
>
> Same thing for the next dreg_handler test a few lines down.
> None of the TestBot's Windows 10 VMs crash when running that code :-(
>
> More data:
> * The crash is 100% reproducible.
>
> * I get a BSOD saying KERNEL_SECURITY_CHECK_FAILURE
>
> * Looking in the event log I found the following:
>
> The computer has rebooted from a bugcheck. The bugcheck was:
> 0x00000139 (0x0000000000000004, 0xffff9f019bff5010,
> 0xffff9f019bff4f68, 0x0000000000000000). A dump was saved in:
> C:\Windows\MEMORY.DMP. Report Id: fb52dedb-eb5e-4010-b0ac-d17284efc806.
>
> * 0x139 does match KERNEL_SECURITY_CHECK_FAILURE. If I understand
> correctly its type is 0x4, i.e. reserved, which is not very helpful.
> https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/bug-chec…
>
> * The online resources are really not helpful. They suggest to:
> - Check the memory (in a VM? did so anyway, found nothing)
> - Run chkdsk /f c: (nothing)
> - Run sfc /scannow (found nothing)
> - Get the latest drivers. I use the QEmu 0.1.185 drivers (stable
> branch, same as the TestBot).
> - Disable the hyper-v network adapter. I use an e1000e network card
> (like in the official TestBot).
>
> * I use qemu 1:5.0-14~bpo10+1, like vm4 which runs w10pro64.
>
> * I use the same hardware configuration as the TestBot except for the
> CPU (Haswell-noTSX-IBRS instead of IvyBridge-IBRS) and 4 cores instead
> of 3.
>
>
>
> [1] Installed from Win10_2009_English_x64.19042.iso
>
While it looks like a definite VM bug, it is maybe interesting to know
for a start what exactly triggers the error. Is it possible to see if
disabling the setting of the debug registers in dreg_handler() above
(lines context->Dr<n> = test->dr<n>;) avoids the crash, and if yes,
which exactly register(s) setting trigger that. That is, disable setting
all the registers, then check if setting dr7 alone still crashes it
(setting dr7 enables HW breakpoints), and if no, leave dr7 enabled and
enable the others one at a time to see which will trigger the crash.
Dec. 7, 2020
ntdll:exception crashes some Windows 10
by Francois Gouget
So I have a problem with ntdll:exception: it crashes the Windows 10 VM I
set up on my development TestBot machine. I'd appreciate any insight you
may have.
The VM is Windows 10 Pro 64-bit [1] with all updates all the way to
2020-11-03. And the following exception.c lines cause it to crash:
dreg_test.dr0 = 0x42424240;
dreg_test.dr2 = 0x126bb070;
dreg_test.dr3 = 0x0badbad0;
dreg_test.dr7 = 0xffff0115;
run_exception_test(dreg_handler, &dreg_test, &segfault_code, sizeof(segfault_code), 0);
Same thing for the next dreg_handler test a few lines down.
None of the TestBot's Windows 10 VMs crash when running that code :-(
More data:
* The crash is 100% reproducible.
* I get a BSOD saying KERNEL_SECURITY_CHECK_FAILURE
* Looking in the event log I found the following:
The computer has rebooted from a bugcheck. The bugcheck was:
0x00000139 (0x0000000000000004, 0xffff9f019bff5010,
0xffff9f019bff4f68, 0x0000000000000000). A dump was saved in:
C:\Windows\MEMORY.DMP. Report Id: fb52dedb-eb5e-4010-b0ac-d17284efc806.
* 0x139 does match KERNEL_SECURITY_CHECK_FAILURE. If I understand
correctly its type is 0x4, i.e. reserved, which is not very helpful.
https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/bug-chec…
* The online resources are really not helpful. They suggest to:
- Check the memory (in a VM? did so anyway, found nothing)
- Run chkdsk /f c: (nothing)
- Run sfc /scannow (found nothing)
- Get the latest drivers. I use the QEmu 0.1.185 drivers (stable
branch, same as the TestBot).
- Disable the hyper-v network adapter. I use an e1000e network card
(like in the official TestBot).
* I use qemu 1:5.0-14~bpo10+1, like vm4 which runs w10pro64.
* I use the same hardware configuration as the TestBot except for the
CPU (Haswell-noTSX-IBRS instead of IvyBridge-IBRS) and 4 cores instead
of 3.
[1] Installed from Win10_2009_English_x64.19042.iso
--
Francois Gouget <fgouget(a)codeweavers.com>
Dec. 7, 2020
Re: [PATCH] ntdll/tests: Add a broken result for Win7u in test_extended_context().
by Francois Gouget
On Mon, 7 Dec 2020, Paul Gofman wrote:
> Fixes test failures on w7u testbot machines.
Thank you!
That was a bit puzzling.
--
Francois Gouget <fgouget(a)codeweavers.com>
Dec. 7, 2020
[PATCH] ntdll/tests: Add a broken result for Win7u in test_extended_context().
by Paul Gofman
Fixes test failures on w7u testbot machines.
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/ntdll/tests/exception.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 89ffe98f0ad..5686e39ab9e 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -7675,9 +7675,10 @@ static void test_extended_context(void)
memset(&xs->YmmContext, 0xcc, sizeof(xs->YmmContext));
bret = GetThreadContext(thread, context);
ok(bret, "Got unexpected bret %#x, GetLastError() %u.\n", bret, GetLastError());
- ok(xs->Mask == (sizeof(void *) == 4 ? 4 : 0), "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask));
+ ok(xs->Mask == (sizeof(void *) == 4 ? 4 : 0) || broken(sizeof(void *) == 4 && !xs->Mask) /* Win7u */,
+ "Got unexpected Mask %s.\n", wine_dbgstr_longlong(xs->Mask));
for (i = 0; i < 16 * 4; ++i)
- ok(((ULONG *)&xs->YmmContext)[i] == (sizeof(void *) == 4 ? (i < 8 * 4 ? 0 : 0x48484848) : 0xcccccccc),
+ ok(((ULONG *)&xs->YmmContext)[i] == (xs->Mask ? (i < 8 * 4 ? 0 : 0x48484848) : 0xcccccccc),
"Got unexpected value %#x, i %u.\n", ((ULONG *)&xs->YmmContext)[i], i);
bret = ResumeThread(thread);
--
2.28.0
Dec. 7, 2020
[PATCH] ntdll: Restore non-volatile registers in call_user_exception_dispatcher() on x86_64.
by Paul Gofman
Required to correctly restore non-volatile registers during unwind.
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/ntdll/tests/exception.c | 58 ++++++++++++++++++++++++++++-----
dlls/ntdll/unix/signal_x86_64.c | 57 +++++++++++++++++++++++---------
2 files changed, 91 insertions(+), 24 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index 3451a7d6465..89ffe98f0ad 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -56,6 +56,7 @@ static void * (WINAPI *pRtlLocateExtendedFeature)(CONTEXT_EX *context_ex, ULO
static void * (WINAPI *pRtlLocateLegacyContext)(CONTEXT_EX *context_ex, ULONG *length);
static void (WINAPI *pRtlSetExtendedFeaturesMask)(CONTEXT_EX *context_ex, ULONG64 feature_mask);
static ULONG64 (WINAPI *pRtlGetExtendedFeaturesMask)(CONTEXT_EX *context_ex);
+static NTSTATUS (WINAPI *pNtRaiseException)(EXCEPTION_RECORD *rec, CONTEXT *context, BOOL first_chance);
static NTSTATUS (WINAPI *pNtReadVirtualMemory)(HANDLE, const void*, void*, SIZE_T, SIZE_T*);
static NTSTATUS (WINAPI *pNtTerminateProcess)(HANDLE handle, LONG exit_code);
static NTSTATUS (WINAPI *pNtQueryInformationProcess)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG);
@@ -1828,7 +1829,7 @@ static LONG WINAPI dbg_except_continue_vectored_handler(struct _EXCEPTION_POINTE
}
/* Use CDECL to leave arguments on stack. */
-void CDECL hook_KiUserExceptionDispatcher(EXCEPTION_RECORD *rec, CONTEXT *context)
+static void CDECL hook_KiUserExceptionDispatcher(EXCEPTION_RECORD *rec, CONTEXT *context)
{
trace("rec %p, context %p.\n", rec, context);
trace("context->Eip %#x, context->Esp %#x, ContextFlags %#x.\n",
@@ -3716,6 +3717,8 @@ static struct
}
test_kiuserexceptiondispatcher_regs;
+static ULONG64 test_kiuserexceptiondispatcher_saved_r12;
+
static DWORD dbg_except_continue_handler(EXCEPTION_RECORD *rec, EXCEPTION_REGISTRATION_RECORD *frame,
CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **dispatcher)
{
@@ -3738,6 +3741,13 @@ static LONG WINAPI dbg_except_continue_vectored_handler(struct _EXCEPTION_POINTE
trace("dbg_except_continue_vectored_handler, code %#x, Rip %#lx.\n", rec->ExceptionCode, context->Rip);
+ if (rec->ExceptionCode == 0xceadbeef)
+ {
+ ok(context->P1Home == (ULONG64)0xdeadbeeffeedcafe, "Got unexpected context->P1Home %#lx.\n", context->P1Home);
+ context->R12 = test_kiuserexceptiondispatcher_saved_r12;
+ return EXCEPTION_CONTINUE_EXECUTION;
+ }
+
ok(rec->ExceptionCode == 0x80000003, "Got unexpected exception code %#x.\n", rec->ExceptionCode);
got_exception = 1;
@@ -3752,7 +3762,7 @@ static LONG WINAPI dbg_except_continue_vectored_handler(struct _EXCEPTION_POINTE
return EXCEPTION_CONTINUE_EXECUTION;
}
-void WINAPI hook_KiUserExceptionDispatcher(EXCEPTION_RECORD *rec, CONTEXT *context)
+static void WINAPI hook_KiUserExceptionDispatcher(EXCEPTION_RECORD *rec, CONTEXT *context)
{
trace("rec %p, context %p.\n", rec, context);
trace("context->Rip %#lx, context->Rsp %#lx, ContextFlags %#lx.\n",
@@ -3760,7 +3770,7 @@ void WINAPI hook_KiUserExceptionDispatcher(EXCEPTION_RECORD *rec, CONTEXT *conte
hook_called = TRUE;
/* Broken on Win2008, probably rec offset in stack is different. */
- ok(rec->ExceptionCode == 0x80000003 || broken(!rec->ExceptionCode),
+ ok(rec->ExceptionCode == 0x80000003 || rec->ExceptionCode == 0xceadbeef || broken(!rec->ExceptionCode),
"Got unexpected ExceptionCode %#x.\n", rec->ExceptionCode);
hook_KiUserExceptionDispatcher_rip = (void *)context->Rip;
@@ -3810,15 +3820,15 @@ static void test_kiuserexceptiondispatcher(void)
0x48, 0x89, 0xe2, /* mov %rsp,%rdx */
0x48, 0x8d, 0x8c, 0x24, 0xf0, 0x04, 0x00, 0x00,
/* lea 0x4f0(%rsp),%rcx */
-
+ 0x4c, 0x89, 0x22, /* mov %r12,(%rdx) */
0xff, 0x14, 0x25,
- /* offset: 14 bytes */
+ /* offset: 17 bytes */
0x00, 0x00, 0x00, 0x00, /* callq *addr */ /* call hook implementation. */
0x48, 0x31, 0xc9, /* xor %rcx, %rcx */
0x48, 0x31, 0xd2, /* xor %rdx, %rdx */
0xff, 0x24, 0x25,
- /* offset: 27 bytes */
+ /* offset: 30 bytes */
0x00, 0x00, 0x00, 0x00, /* jmpq *addr */ /* jump to original function. */
};
@@ -3827,6 +3837,8 @@ static void test_kiuserexceptiondispatcher(void)
DWORD old_protect1, old_protect2;
EXCEPTION_RECORD record;
void *bpt_address;
+ CONTEXT ctx;
+ LONG pass;
BYTE *ptr;
BOOL ret;
@@ -3845,8 +3857,8 @@ static void test_kiuserexceptiondispatcher(void)
ok(((ULONG64)&pKiUserExceptionDispatcher & 0xffffffff) == ((ULONG64)&pKiUserExceptionDispatcher),
"Address is too long.\n");
- *(unsigned int *)(hook_trampoline + 14) = (unsigned int)(ULONG_PTR)&phook_KiUserExceptionDispatcher;
- *(unsigned int *)(hook_trampoline + 27) = (unsigned int)(ULONG_PTR)&pKiUserExceptionDispatcher;
+ *(unsigned int *)(hook_trampoline + 17) = (unsigned int)(ULONG_PTR)&phook_KiUserExceptionDispatcher;
+ *(unsigned int *)(hook_trampoline + 30) = (unsigned int)(ULONG_PTR)&pKiUserExceptionDispatcher;
ret = VirtualProtect(hook_trampoline, ARRAY_SIZE(hook_trampoline), PAGE_EXECUTE_READWRITE, &old_protect1);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
@@ -3954,6 +3966,35 @@ static void test_kiuserexceptiondispatcher(void)
NtCurrentTeb()->Peb->BeingDebugged = 0;
+ vectored_handler = AddVectoredExceptionHandler(TRUE, dbg_except_continue_vectored_handler);
+ pass = 0;
+ InterlockedIncrement(&pass);
+ pRtlCaptureContext(&ctx);
+ if (InterlockedIncrement(&pass) == 2) /* interlocked to prevent compiler from moving before capture */
+ {
+ memcpy(pKiUserExceptionDispatcher, patched_KiUserExceptionDispatcher_bytes,
+ sizeof(patched_KiUserExceptionDispatcher_bytes));
+ got_exception = 0;
+ hook_called = FALSE;
+
+ record.ExceptionCode = 0xceadbeef;
+ test_kiuserexceptiondispatcher_saved_r12 = ctx.R12;
+ ctx.R12 = (ULONG64)0xdeadbeeffeedcafe;
+
+#ifdef __GNUC__
+ /* Spoil r12 value to make sure it doesn't come from the current userspace registers. */
+ __asm__ volatile("movq $0xdeadcafe, %%r12" : : : "%r12");
+#endif
+ pNtRaiseException(&record, &ctx, TRUE);
+ ok(0, "Shouldn't be reached.\n");
+ }
+ else
+ {
+ ok(pass == 3, "Got unexpected pass %d.\n", pass);
+ }
+ ok(hook_called, "Hook was not called.\n");
+ RemoveVectoredExceptionHandler(vectored_handler);
+
ret = VirtualProtect(pKiUserExceptionDispatcher, sizeof(saved_KiUserExceptionDispatcher_bytes),
old_protect2, &old_protect2);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
@@ -8046,6 +8087,7 @@ START_TEST(exception)
X(NtQueryInformationThread);
X(NtSetInformationProcess);
X(NtSuspendProcess);
+ X(NtRaiseException);
X(NtResumeProcess);
X(RtlGetUnloadEventTrace);
X(RtlGetUnloadEventTraceEx);
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index 124032714c7..d049cc8b3f0 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -1551,6 +1551,34 @@ static void restore_context( const struct xcontext *xcontext, ucontext_t *sigcon
}
+/***********************************************************************
+ * set_nonvolatile_regs_from_context
+ *
+ * Set the non-volatile registers from CPU context.
+ */
+extern void WINAPI set_nonvolatile_regs_from_context( const CONTEXT *context );
+__ASM_GLOBAL_FUNC( set_nonvolatile_regs_from_context,
+ "movq 0xa0(%rcx),%rbp\n\t"
+ "movq 0x90(%rcx),%rbx\n\t"
+ "movq 0xa8(%rcx),%rsi\n\t"
+ "movq 0xb0(%rcx),%rdi\n\t"
+ "movq 0xd8(%rcx),%r12\n\t"
+ "movq 0xe0(%rcx),%r13\n\t"
+ "movq 0xe8(%rcx),%r14\n\t"
+ "movq 0xf0(%rcx),%r15\n\t"
+ "movdqa 0x200(%rcx),%xmm6\n\t"
+ "movdqa 0x210(%rcx),%xmm7\n\t"
+ "movdqa 0x220(%rcx),%xmm8\n\t"
+ "movdqa 0x230(%rcx),%xmm9\n\t"
+ "movdqa 0x240(%rcx),%xmm10\n\t"
+ "movdqa 0x250(%rcx),%xmm11\n\t"
+ "movdqa 0x260(%rcx),%xmm12\n\t"
+ "movdqa 0x270(%rcx),%xmm13\n\t"
+ "movdqa 0x280(%rcx),%xmm14\n\t"
+ "movdqa 0x290(%rcx),%xmm15\n\t"
+ "ret" );
+
+
/***********************************************************************
* set_full_cpu_context
*
@@ -2081,19 +2109,7 @@ __ASM_GLOBAL_FUNC( call_raise_user_exception_dispatcher,
/***********************************************************************
* call_user_exception_dispatcher
*/
-
-extern void WINAPI user_exception_dispatcher_trampoline( struct stack_layout *stack,
- void *pKiUserExceptionDispatcher );
-
-__ASM_GLOBAL_FUNC( user_exception_dispatcher_trampoline,
- "movq %rcx,%rsp\n\t"
- "movq 0x98(%rsp),%rcx\n\t" /* context->Rsp */
- "movq 0xa0(%rsp),%rbp\n\t"
- "movq 0xa8(%rsp),%rsi\n\t"
- "movq 0xb0(%rsp),%rdi\n\t"
- "jmpq *%rdx")
-
-void WINAPI do_call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *context,
+struct stack_layout * WINAPI setup_user_exception_dispatcher_stack( EXCEPTION_RECORD *rec, CONTEXT *context,
NTSTATUS (WINAPI *dispatcher)(EXCEPTION_RECORD*,CONTEXT*),
struct stack_layout *stack )
{
@@ -2127,8 +2143,7 @@ void WINAPI do_call_user_exception_dispatcher( EXCEPTION_RECORD *rec, CONTEXT *c
/* fix up instruction pointer in context for EXCEPTION_BREAKPOINT */
if (stack->rec.ExceptionCode == EXCEPTION_BREAKPOINT) stack->context.Rip--;
- amd64_thread_data()->syscall_frame = NULL;
- user_exception_dispatcher_trampoline( stack, dispatcher );
+ return stack;
}
__ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
@@ -2141,7 +2156,17 @@ __ASM_GLOBAL_FUNC( call_user_exception_dispatcher,
"1:\tsubq $0x5b0,%r9\n\t" /* sizeof(struct stack_layout) */
"cmpq %rsp,%r9\n\t"
"cmovbq %r9,%rsp\n\t"
- "jmp " __ASM_NAME("do_call_user_exception_dispatcher") "\n\t")
+ "pushq %r8\n\t"
+ "subq $0x20,%rsp\n\t"
+ "call " __ASM_NAME("setup_user_exception_dispatcher_stack") "\n\t"
+ "mov %rax,%rcx\n\t"
+ "call " __ASM_NAME("set_nonvolatile_regs_from_context") "\n\t"
+ "addq $0x20,%rsp\n\t"
+ "popq %r8\n\t"
+ "mov %rcx,%rsp\n\t"
+ "movq %gs:0x30,%rax\n\t"
+ "movq $0,0x328(%rax)\n\t" /* amd64_thread_data()->syscall_frame */
+ "jmpq *%r8")
/***********************************************************************
* is_privileged_instr
--
2.28.0
Dec. 7, 2020
[RFC PATCH 4/4] winex11.drv: Dump keysyms and translations for all keys.
by Giovanni Mascellani
Dump all we can see about the user keyboard, so that their +keyboard
logs can be used to fix layout tables.
Signed-off-by: Giovanni Mascellani <gmascellani(a)codeweavers.com>
---
dlls/winex11.drv/keyboard.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index fe4a29c4b06..281cd1b1b1a 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1477,6 +1477,19 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
for (i = 0; i < syms; i++) {
if (!(keysym = keycode_to_keysym (display, keyc, i))) continue;
ckey[keyc][i] = keysym_to_char(keysym);
+ if (TRACE_ON(keyboard))
+ {
+ char buf[32];
+ WCHAR bufW[32];
+ int len, lenW;
+ KeySym orig_keysym = keysym;
+ len = XkbTranslateKeySym(display, &keysym, 0, buf, sizeof(buf), NULL);
+ lenW = MultiByteToWideChar(CP_UNIXCP, 0, buf, len, bufW, ARRAY_SIZE(bufW));
+ if (lenW < ARRAY_SIZE(bufW))
+ bufW[lenW] = 0;
+ TRACE("keycode %u, index %d, orig_keysym 0x%04lx, keysym 0x%04lx, buf %s, bufW %s\n",
+ keyc, i, orig_keysym, keysym, debugstr_a(buf), debugstr_w(bufW));
+ }
}
}
--
2.29.2
Dec. 7, 2020
[RFC PATCH 3/4] winex11drv: Recognize the keyboard in a locale-independent way.
by Giovanni Mascellani
Try to recognize the keyboard comparing keysyms instead of converting
them to multibyte strings, which makes the process locale-dependent and
therefore more fragile.
Unfortunately this means that the layout tables might need to be
updated. However, this change is known to fix the recognitions of a few
keys in the French layout.
---
dlls/winex11.drv/keyboard.c | 64 ++++++++++++++++++-------------------
1 file changed, 31 insertions(+), 33 deletions(-)
This is the meaty patch in the series, and the one about which I would
especially like to gather some feedback. I believe the current
mechanism for detecting keys is broken, because sometimes it
translates keys to (locale-dependent) encodings, sometimes it just
use the last byte in the keysym. I believe the right space to run
the key detection algorithm is KeySym, because it is really meant to
indicate what label is written on the physical keys.
The full solution would be to just use keysyms, without touching them.
However, this would completely invalidate current layout tables.
Instead, my patch contains an intermediate solution: instead of the
keysym, use its last byte. I don't understand all the details of
the current matching filter, but I think current layout tables
should largely remain valid.
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index d9a6879ee04..fe4a29c4b06 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1417,6 +1417,35 @@ BOOL X11DRV_KeyEvent( HWND hwnd, XEvent *xev )
return TRUE;
}
+/* From the point of view of this function there are two types of
+ * keys: those for which the mapping to vkey and scancode depends on
+ * the keyboard layout (i.e., letters, numbers, punctuation) and those
+ * for which it doesn't (control keys); since this function is used to
+ * recognize the keyboard layout and map keysyms to vkeys and
+ * scancodes, we are only concerned about the first type, and map
+ * everything in the second type to zero.
+ */
+static char keysym_to_char( KeySym keysym )
+{
+ /* Dead keys */
+ if (0xfe50 <= keysym && keysym < 0xfed0)
+ return KEYBOARD_MapDeadKeysym( keysym );
+
+ /* Control keys (there is nothing allocated below 0xfc00, but I
+ take some margin in case something is added in the future) */
+ if (0xf000 <= keysym && keysym < 0x10000)
+ return 0;
+
+ /* XFree86 vendor keys */
+ if (0x10000000 <= keysym)
+ return 0;
+
+ /* "Normal" keys: return last octet, because our tables don't have
+ more than that; it would be better to extend the tables and
+ compare the whole keysym, but it's a lot of work... */
+ return keysym & 0xff;
+}
+
/**********************************************************************
* X11DRV_KEYBOARD_DetectLayout
*
@@ -1447,24 +1476,7 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
/* get data for keycode from X server */
for (i = 0; i < syms; i++) {
if (!(keysym = keycode_to_keysym (display, keyc, i))) continue;
- /* Allow both one-byte and two-byte national keysyms */
- if ((keysym < 0x8000) && (keysym != ' '))
- {
-#ifdef HAVE_XKB
- if (!use_xkb || !XkbTranslateKeySym(display, &keysym, 0, &ckey[keyc][i], 1, NULL))
-#endif
- {
- TRACE("XKB could not translate keysym %04lx\n", keysym);
- /* FIXME: query what keysym is used as Mode_switch, fill XKeyEvent
- * with appropriate ShiftMask and Mode_switch, use XLookupString
- * to get character in the local encoding.
- */
- ckey[keyc][i] = keysym & 0xFF;
- }
- }
- else {
- ckey[keyc][i] = KEYBOARD_MapDeadKeysym(keysym);
- }
+ ckey[keyc][i] = keysym_to_char(keysym);
}
}
@@ -1713,21 +1725,7 @@ void X11DRV_InitKeyboard( Display *display )
int maxlen=0,maxval=-1,ok;
for (i=0; i<syms; i++) {
keysym = keycode_to_keysym(display, keyc, i);
- if ((keysym<0x8000) && (keysym!=' '))
- {
-#ifdef HAVE_XKB
- if (!use_xkb || !XkbTranslateKeySym(display, &keysym, 0, &ckey[i], 1, NULL))
-#endif
- {
- /* FIXME: query what keysym is used as Mode_switch, fill XKeyEvent
- * with appropriate ShiftMask and Mode_switch, use XLookupString
- * to get character in the local encoding.
- */
- ckey[i] = (keysym <= 0x7F) ? keysym : 0;
- }
- } else {
- ckey[i] = KEYBOARD_MapDeadKeysym(keysym);
- }
+ ckey[i] = keysym_to_char(keysym);
}
/* find key with longest match streak */
for (keyn=0; keyn<MAIN_LEN; keyn++) {
--
2.29.2
Dec. 7, 2020
[RFC PATCH 2/4] winex11.drv: Do not pollute logs with misencoded bytes.
by Giovanni Mascellani
Signed-off-by: Giovanni Mascellani <gmascellani(a)codeweavers.com>
---
dlls/winex11.drv/keyboard.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index e92d2bf35f2..d9a6879ee04 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1506,7 +1506,7 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
char str[5];
for (i = 0; i < 4; i++) str[i] = ckey[keyc][i] ? ckey[keyc][i] : ' ';
str[4] = 0;
- TRACE_(key)("mismatch for keycode %u, got %s\n", keyc, str);
+ TRACE_(key)("mismatch for keycode %u, got %s\n", keyc, debugstr_a(str));
mismatch++;
score -= syms;
}
--
2.29.2
Dec. 7, 2020
[RFC PATCH 1/4] winex11.drv: Allow keyboard score to be negative.
by Giovanni Mascellani
Signed-off-by: Giovanni Mascellani <gmascellani(a)codeweavers.com>
---
dlls/winex11.drv/keyboard.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/winex11.drv/keyboard.c b/dlls/winex11.drv/keyboard.c
index 48da12c0292..e92d2bf35f2 100644
--- a/dlls/winex11.drv/keyboard.c
+++ b/dlls/winex11.drv/keyboard.c
@@ -1433,7 +1433,7 @@ X11DRV_KEYBOARD_DetectLayout( Display *display )
KeySym keysym = 0;
const char (*lkey)[MAIN_LEN][4];
unsigned max_seq = 0;
- int max_score = 0, ismatch = 0;
+ int max_score = INT_MIN, ismatch = 0;
char ckey[256][4];
syms = keysyms_per_keycode;
--
2.29.2
Dec. 7, 2020
[PATCH] sxs: Query context that contains the GUID in SxsLookupClrGuid().
by Nikolay Sivov
This restores pre-2cfc85dc55d403a7fcb885a62bb28f8d73498c2d logic;
activation/deactivation still happens, and user context in this case is
returned from FindActCtxSectionGuid().
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50139
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/sxs/sxs.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/sxs/sxs.c b/dlls/sxs/sxs.c
index 7150f55c33e..cd1d0f7bb56 100644
--- a/dlls/sxs/sxs.c
+++ b/dlls/sxs/sxs.c
@@ -135,14 +135,20 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff
if (flags & SXS_LOOKUP_CLR_GUID_FIND_SURROGATE)
{
- if ((retval = FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES, clsid, &guid_info)))
+ if ((retval = FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
+ ACTIVATION_CONTEXT_SECTION_CLR_SURROGATES, clsid, &guid_info)))
+ {
flags &= ~SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS;
+ }
}
if (!retval && (flags & SXS_LOOKUP_CLR_GUID_FIND_CLR_CLASS))
{
- if ((retval = FindActCtxSectionGuid(0, NULL, ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, clsid, &guid_info)))
+ if ((retval = FindActCtxSectionGuid(FIND_ACTCTX_SECTION_KEY_RETURN_HACTCTX, NULL,
+ ACTIVATION_CONTEXT_SECTION_COM_SERVER_REDIRECTION, clsid, &guid_info)))
+ {
flags &= ~SXS_LOOKUP_CLR_GUID_FIND_SURROGATE;
+ }
}
if (!retval)
@@ -151,7 +157,7 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff
goto out;
}
- retval = QueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, NULL, &guid_info.ulAssemblyRosterIndex,
+ retval = QueryActCtxW(0, guid_info.hActCtx, &guid_info.ulAssemblyRosterIndex,
AssemblyDetailedInformationInActivationContext, NULL, 0, &bytes_assembly_info);
if (!retval && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
{
@@ -159,7 +165,7 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff
}
assembly_info = heap_alloc(bytes_assembly_info);
- if (!(retval = QueryActCtxW(QUERY_ACTCTX_FLAG_USE_ACTIVE_ACTCTX, NULL, &guid_info.ulAssemblyRosterIndex,
+ if (!(retval = QueryActCtxW(0, guid_info.hActCtx, &guid_info.ulAssemblyRosterIndex,
AssemblyDetailedInformationInActivationContext, assembly_info,
bytes_assembly_info, &bytes_assembly_info)))
{
@@ -225,6 +231,7 @@ BOOL WINAPI SxsLookupClrGuid(DWORD flags, GUID *clsid, HANDLE actctx, void *buff
SetLastError(0);
out:
+ ReleaseActCtx(guid_info.hActCtx);
if (flags & SXS_LOOKUP_CLR_GUID_USE_ACTCTX)
DeactivateActCtx(0, cookie);
--
2.29.2
Dec. 7, 2020
[PATCH] ntdll: Only build Linux-specific functions on Linux
by Gerald Pfeifer
logical_proc_info_add_by_id, logical_proc_info_add_cache,
logical_proc_info_add_group, and logical_proc_info_add_numa_node
are only useful and invoked on Linux, so disable their build
elsewhere.
(Without this compilers will, rightfully, warn about unused functions.
GCC definitely does.)
Signed-off-by: Gerald Pfeifer <gerald(a)pfeifer.com>
---
dlls/ntdll/unix/system.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dlls/ntdll/unix/system.c b/dlls/ntdll/unix/system.c
index a889b2e020c..5130b4c18ba 100644
--- a/dlls/ntdll/unix/system.c
+++ b/dlls/ntdll/unix/system.c
@@ -506,6 +506,8 @@ void init_cpu_info(void)
cpu_info.Architecture, cpu_info.Level, cpu_info.Revision, cpu_info.FeatureSet );
}
+#ifdef linux
+
static BOOL grow_logical_proc_buf( SYSTEM_LOGICAL_PROCESSOR_INFORMATION **pdata, DWORD *max_len )
{
SYSTEM_LOGICAL_PROCESSOR_INFORMATION *new_data;
@@ -752,6 +754,8 @@ static BOOL logical_proc_info_add_group( SYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX
return TRUE;
}
+#endif
+
#ifdef linux
/* Helper function for counting bitmap values as commonly used by the Linux kernel
--
2.28.0
Dec. 6, 2020
Re: [PATCH] gameux/tests: Use wide-char string literals.
by Michael Stefaniuc
Pre-existing failures
https://test.winehq.org/data/842b38e29166a429d59331be40761335807c85d2/win10…
Probably not detected by the WTB as I've fixed one of the message en passant.
bye
michael
On 12/6/20 4:09 PM, Marvin wrote:
> 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=83160
>
> Your paranoid android.
>
>
> === w1064v1809 (32 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
> === w1064 (32 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
> === w10pro64 (32 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
> === w1064v1809 (64 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
> === w1064 (64 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
> === w1064_2qxl (64 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
> === w10pro64 (64 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
> === w10pro64_ar (64 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
> === w10pro64_he (64 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
> === w10pro64_ja (64 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
> === w10pro64_zh_CN (64 bit report) ===
>
> gameux:
> gamestatistics.c:215: Test failed: setting category title failed: Category0
> gamestatistics.c:216: Test failed: setting category title failed: Category1
> gamestatistics.c:217: Test failed: setting category title failed: Category2
> gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
> gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
> gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
> gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
> gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
> gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
> gamestatistics.c:268: Test failed: setting category title failed: Category0a
>
Dec. 6, 2020
[PATCH] Revert "winegstreamer: Avoid performing color matrix conversions in videoconvert."
by Zebediah Figura
This reverts commit fd25ba65e0eb9fedfb2cdfa2b7a4b16e0401dfdf.
The relevant commit breaks visual correctness in many applications, for the sake
of performance. As such I am rather inclined to revert it for 6.0, especially as
a full solution will probably involve a revert of this patch along with upstream
changes to GStreamer.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49535
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/winegstreamer/gstdemux.c | 3 ---
1 file changed, 3 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index e227ed9331d..77204bc55a2 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -1024,9 +1024,6 @@ static void init_new_decoded_pad(GstElement *bin, GstPad *pad, struct gstdemux *
goto out;
}
- /* Avoid expensive color matrix conversions. */
- gst_util_set_object_arg(G_OBJECT(vconv), "matrix-mode", "none");
-
/* GStreamer outputs RGB video top-down, but DirectShow expects bottom-up. */
if (!(flip = gst_element_factory_make("videoflip", NULL)))
{
--
2.29.2
Dec. 6, 2020
Re: [PATCH] gameux/tests: Use wide-char string literals.
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=83160
Your paranoid android.
=== w1064v1809 (32 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
=== w1064 (32 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
=== w10pro64 (32 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
=== w1064v1809 (64 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
=== w1064 (64 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
=== w1064_2qxl (64 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
=== w10pro64 (64 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
=== w10pro64_ar (64 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
=== w10pro64_he (64 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
=== w10pro64_ja (64 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
=== w10pro64_zh_CN (64 bit report) ===
gameux:
gamestatistics.c:215: Test failed: setting category title failed: Category0
gamestatistics.c:216: Test failed: setting category title failed: Category1
gamestatistics.c:217: Test failed: setting category title failed: Category2
gamestatistics.c:248: Test failed: setting statistic failed: name=Statistic00, value=Value00
gamestatistics.c:250: Test failed: setting statistic failed: name=Statistic01, value=Value01
gamestatistics.c:252: Test failed: setting statistic failed: name=Statistic10, value=Value10
gamestatistics.c:254: Test failed: setting statistic failed: name=Statistic11, value=Value11
gamestatistics.c:256: Test failed: setting statistic failed: name=Statistic20, value=Value20
gamestatistics.c:258: Test failed: setting statistic failed: name=Statistic21, value=Value21
gamestatistics.c:268: Test failed: setting category title failed: Category0a
Dec. 6, 2020
[PATCH] jscript/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/jscript/tests/jscript.c | 5 +----
dlls/jscript/tests/run.c | 29 +++++++++++++----------------
2 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c
index c1b83d47799..e96127fbc5e 100644
--- a/dlls/jscript/tests/jscript.c
+++ b/dlls/jscript/tests/jscript.c
@@ -828,9 +828,6 @@ static void test_jscript_uninitializing(void)
ULONG ref;
HRESULT hres;
- static const WCHAR script_textW[] =
- {'f','u','n','c','t','i','o','n',' ','f','(',')',' ','{','}',0};
-
script = create_jscript();
hres = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parse);
@@ -850,7 +847,7 @@ static void test_jscript_uninitializing(void)
test_state(script, SCRIPTSTATE_INITIALIZED);
- hres = IActiveScriptParse_ParseScriptText(parse, script_textW, NULL, NULL, NULL, 0, 1, 0x42, NULL, NULL);
+ hres = IActiveScriptParse_ParseScriptText(parse, L"function f() {}", NULL, NULL, NULL, 0, 1, 0x42, NULL, NULL);
ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
hres = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
diff --git a/dlls/jscript/tests/run.c b/dlls/jscript/tests/run.c
index 7cd0755497c..1deb460f715 100644
--- a/dlls/jscript/tests/run.c
+++ b/dlls/jscript/tests/run.c
@@ -2484,9 +2484,6 @@ static void test_isvisible(BOOL global_members)
IActiveScript *engine;
HRESULT hres;
- static const WCHAR script_textW[] =
- {'v','a','r',' ','v',' ','=',' ','t','e','s','t','V','a','l',';',0};
-
engine = create_script();
if(!engine)
return;
@@ -2519,12 +2516,12 @@ static void test_isvisible(BOOL global_members)
if(!global_members)
SET_EXPECT(GetItemInfo_testVal);
- hres = IActiveScriptParse_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ hres = IActiveScriptParse_ParseScriptText(parser, L"var v = testVal;", NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
if(!global_members)
CHECK_CALLED(GetItemInfo_testVal);
- hres = IActiveScriptParse_ParseScriptText(parser, script_textW, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ hres = IActiveScriptParse_ParseScriptText(parser, L"var v = testVal;", NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
IActiveScript_Release(engine);
@@ -3035,17 +3032,17 @@ static void run_bom_tests(void)
int i;
HRESULT hres;
struct bom_test bom_tests[] = {
- {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
- {{0xFEFF,'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
- {{'v',0xFEFF,'a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, JS_E_OUT_OF_MEMORY},
- {{'v','a','r',0xFEFF,' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
- {{'v','a','r',' ','a',' ','=',' ','1',';',' ',0xFEFF,'r','e','p','o','r','t','S','u','c','c','e','s','s','(',')',';','\0'}, S_OK},
- {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t',0xFEFF,'S','u','c','c','e','s','s','(',')',';','\0'}, JS_E_OUT_OF_MEMORY},
- {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s',0xFEFF,'(',')',';','\0'}, S_OK},
- {{'v','a','r',' ','a',' ','=',' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',0xFEFF,')',';','\0'}, S_OK},
- {{'v','a','r',' ','a',' ','=',0xFEFF,' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',0xFEFF,')',';','\0'}, S_OK},
- {{0xFEFF,'v','a','r',' ','a',' ','=',0xFEFF,0xFEFF,' ','1',';',' ','r','e','p','o','r','t','S','u','c','c','e','s','s','(',0xFEFF,')',';','\0'}, S_OK},
- {{0}}
+ {L"var a = 1; reportSuccess();", S_OK},
+ {L"\xfeffvar a = 1; reportSuccess();", S_OK},
+ {L"v\xfeff" "ar a = 1; reportSuccess();", JS_E_OUT_OF_MEMORY},
+ {L"var\xfeff a = 1; reportSuccess();", S_OK},
+ {L"var a = 1; \xfeffreportSuccess();", S_OK},
+ {L"var a = 1; report\xfeffSuccess();", JS_E_OUT_OF_MEMORY},
+ {L"var a = 1; reportSuccess\xfeff();", S_OK},
+ {L"var a = 1; reportSuccess(\xfeff);", S_OK},
+ {L"var a =\xfeff 1; reportSuccess(\xfeff);", S_OK},
+ {L"\xfeffvar a =\xfeff\xfeff 1; reportSuccess(\xfeff);", S_OK},
+ {L""}
};
engine_clsid = &CLSID_JScript;
--
2.26.2
Dec. 6, 2020
[PATCH] ieframe/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/ieframe/tests/intshcut.c | 12 ++++--------
dlls/ieframe/tests/webbrowser.c | 16 +++++-----------
2 files changed, 9 insertions(+), 19 deletions(-)
diff --git a/dlls/ieframe/tests/intshcut.c b/dlls/ieframe/tests/intshcut.c
index 803e7ec60e9..d2135d0ebb3 100644
--- a/dlls/ieframe/tests/intshcut.c
+++ b/dlls/ieframe/tests/intshcut.c
@@ -171,9 +171,7 @@ static void test_ReadAndWriteProperties(void)
IUniformResourceLocatorA *urlA;
IUniformResourceLocatorA *urlAFromFile;
WCHAR fileNameW[MAX_PATH];
-
- static const WCHAR shortcutW[] = {'t','e','s','t','s','h','o','r','t','c','u','t','.','u','r','l',0};
- WCHAR iconPath[] = {'f','i','l','e',':','/','/','/','C',':','/','a','r','b','i','t','r','a','r','y','/','i','c','o','n','/','p','a','t','h',0};
+ static WCHAR iconPath[] = L"file:///C:/arbitrary/icon/path";
char testurl[] = "http://some/bogus/url.html";
ps[0].ulKind = PRSPEC_PROPID;
@@ -183,7 +181,7 @@ static void test_ReadAndWriteProperties(void)
/* Make sure we have a valid temporary directory */
GetTempPathW(MAX_PATH, fileNameW);
- lstrcatW(fileNameW, shortcutW);
+ lstrcatW(fileNameW, L"testshortcut.url");
hr = CoCreateInstance(&CLSID_InternetShortcut, NULL, CLSCTX_ALL, &IID_IUniformResourceLocatorA, (void**)&urlA);
ok(hr == S_OK, "Could not create CLSID_InternetShortcut instance: %08x\n", hr);
@@ -208,7 +206,7 @@ static void test_ReadAndWriteProperties(void)
IPersistFile_Release(pf);
pv[0].vt = VT_LPWSTR;
- U(pv[0]).pwszVal = (void *) iconPath;
+ U(pv[0]).pwszVal = iconPath;
pv[1].vt = VT_I4;
U(pv[1]).lVal = iconIndex;
hr = urlA->lpVtbl->QueryInterface(urlA, &IID_IPropertySetStorage, (void **) &pPropSetStg);
@@ -326,10 +324,8 @@ static void test_Load(void)
HANDLE file;
HRESULT hres;
- static const WCHAR test_urlW[] = {'t','e','s','t','.','u','r','l',0};
-
GetTempPathW(MAX_PATH, file_path);
- lstrcatW(file_path, test_urlW);
+ lstrcatW(file_path, L"test.url");
for(test = load_tests; test < load_tests + ARRAY_SIZE(load_tests); test++) {
IPropertySetStorage *propsetstorage;
diff --git a/dlls/ieframe/tests/webbrowser.c b/dlls/ieframe/tests/webbrowser.c
index 9c2c393aafe..52d1f707357 100644
--- a/dlls/ieframe/tests/webbrowser.c
+++ b/dlls/ieframe/tests/webbrowser.c
@@ -160,8 +160,6 @@ DEFINE_EXPECT(GetExternal);
DEFINE_EXPECT(outer_QI_test);
DEFINE_EXPECT(Advise_OnClose);
-static const WCHAR wszItem[] = {'i','t','e','m',0};
-
static VARIANT_BOOL exvb;
static IWebBrowser2 *wb;
@@ -1268,7 +1266,7 @@ static HRESULT WINAPI InPlaceUIWindow_SetActiveObject(IOleInPlaceFrame *iface,
CHECK_EXPECT(UIWindow_SetActiveObject);
if(!test_close && !test_hide) {
ok(pActiveObject != NULL, "pActiveObject = NULL\n");
- ok(!lstrcmpW(pszObjName, wszItem), "unexpected pszObjName\n");
+ ok(!lstrcmpW(pszObjName, L"item"), "unexpected pszObjName\n");
} else {
ok(!pActiveObject, "pActiveObject != NULL\n");
ok(!pszObjName, "pszObjName != NULL\n");
@@ -1282,7 +1280,7 @@ static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
CHECK_EXPECT(Frame_SetActiveObject);
if(!test_close && !test_hide) {
ok(pActiveObject != NULL, "pActiveObject = NULL\n");
- ok(!lstrcmpW(pszObjName, wszItem), "unexpected pszObjName\n");
+ ok(!lstrcmpW(pszObjName, L"item"), "unexpected pszObjName\n");
} else {
ok(!pActiveObject, "pActiveObject != NULL\n");
ok(!pszObjName, "pszObjName != NULL\n");
@@ -1817,19 +1815,17 @@ static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam
static HWND create_container_window(void)
{
- static const WCHAR wszWebBrowserContainer[] =
- {'W','e','b','B','r','o','w','s','e','r','C','o','n','t','a','i','n','e','r',0};
static WNDCLASSEXW wndclass = {
sizeof(WNDCLASSEXW),
0,
wnd_proc,
0, 0, NULL, NULL, NULL, NULL, NULL,
- wszWebBrowserContainer,
+ L"WebBrowserContainer",
NULL
};
RegisterClassExW(&wndclass);
- return CreateWindowW(wszWebBrowserContainer, wszWebBrowserContainer,
+ return CreateWindowW(L"WebBrowserContainer", L"WebBrowserContainer",
WS_OVERLAPPEDWINDOW, 10, 10, 600, 600, NULL, NULL, NULL, NULL);
}
@@ -1942,9 +1938,7 @@ static void test_SetHostNames(IOleObject *oleobj)
{
HRESULT hres;
- static const WCHAR test_appW[] = {'t','e','s','t',' ','a','p','p',0};
-
- hres = IOleObject_SetHostNames(oleobj, test_appW, (void*)0xdeadbeef);
+ hres = IOleObject_SetHostNames(oleobj, L"test app", (void*)0xdeadbeef);
ok(hres == S_OK, "SetHostNames failed: %08x\n", hres);
}
--
2.26.2
Dec. 6, 2020
[PATCH] gameux/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/gameux/tests/gamestatistics.c | 101 +++++++++++++----------------
1 file changed, 44 insertions(+), 57 deletions(-)
diff --git a/dlls/gameux/tests/gamestatistics.c b/dlls/gameux/tests/gamestatistics.c
index 192a245e096..c29c6b44470 100644
--- a/dlls/gameux/tests/gamestatistics.c
+++ b/dlls/gameux/tests/gamestatistics.c
@@ -89,12 +89,6 @@ static void test_unregister_game(IGameExplorer *ge)
*/
static HRESULT _buildStatisticsFilePath(LPCGUID guidApplicationId, LPWSTR *lpStatisticsFile)
{
- static const WCHAR sBackslash[] = {'\\',0};
- static const WCHAR sStatisticsDir[] = {'\\','M','i','c','r','o','s','o','f','t',
- '\\','W','i','n','d','o','w','s','\\','G','a','m','e','E','x','p',
- 'l','o','r','e','r','\\','G','a','m','e','S','t','a','t','i','s',
- 't','i','c','s','\\',0};
- static const WCHAR sDotGamestats[] = {'.','g','a','m','e','s','t','a','t','s',0};
HRESULT hr;
WCHAR sGuid[49], sPath[MAX_PATH];
@@ -105,11 +99,11 @@ static HRESULT _buildStatisticsFilePath(LPCGUID guidApplicationId, LPWSTR *lpSta
if(SUCCEEDED(hr))
{
- lstrcatW(sPath, sStatisticsDir);
+ lstrcatW(sPath, L"\\Microsoft\\Windows\\GameExplorer\\GameStatistics\\");
lstrcatW(sPath, sGuid);
- lstrcatW(sPath, sBackslash);
+ lstrcatW(sPath, L"\\");
lstrcatW(sPath, sGuid);
- lstrcatW(sPath, sDotGamestats);
+ lstrcatW(sPath, L".gamestats");
*lpStatisticsFile = CoTaskMemAlloc((lstrlenW(sPath)+1)*sizeof(WCHAR));
if(!*lpStatisticsFile) hr = E_OUTOFMEMORY;
@@ -145,22 +139,6 @@ static BOOL _isFileExists(LPCWSTR lpFile)
static void test_gamestatisticsmgr( void )
{
static const GUID guidApplicationId = { 0x17A6558E, 0x60BE, 0x4078, { 0xB6, 0x6F, 0x9C, 0x3A, 0xDA, 0x2A, 0x32, 0xE6 } };
- static const WCHAR sCategory0[] = {'C','a','t','e','g','o','r','y','0',0};
- static const WCHAR sCategory1[] = {'C','a','t','e','g','o','r','y','1',0};
- static const WCHAR sCategory2[] = {'C','a','t','e','g','o','r','y','2',0};
- static const WCHAR sCategory0a[] = {'C','a','t','e','g','o','r','y','0','a',0};
- static const WCHAR sStatistic00[] = {'S','t','a','t','i','s','t','i','c','0','0',0};
- static const WCHAR sStatistic01[] = {'S','t','a','t','i','s','t','i','c','0','1',0};
- static const WCHAR sStatistic10[] = {'S','t','a','t','i','s','t','i','c','1','0',0};
- static const WCHAR sStatistic11[] = {'S','t','a','t','i','s','t','i','c','1','1',0};
- static const WCHAR sStatistic20[] = {'S','t','a','t','i','s','t','i','c','2','0',0};
- static const WCHAR sStatistic21[] = {'S','t','a','t','i','s','t','i','c','2','1',0};
- static const WCHAR sValue00[] = {'V','a','l','u','e','0','0',0};
- static const WCHAR sValue01[] = {'V','a','l','u','e','0','1',0};
- static const WCHAR sValue10[] = {'V','a','l','u','e','1','0',0};
- static const WCHAR sValue11[] = {'V','a','l','u','e','1','1',0};
- static const WCHAR sValue20[] = {'V','a','l','u','e','2','0',0};
- static const WCHAR sValue21[] = {'V','a','l','u','e','2','1',0};
HRESULT hr;
DWORD dwOpenResult;
@@ -221,7 +199,7 @@ static void test_gamestatisticsmgr( void )
hr = IGameStatistics_SetCategoryTitle(gs, wMaxCategories, NULL);
ok(hr==E_INVALIDARG, "setting category title invalid value: 0x%x\n", hr);
- hr = IGameStatistics_SetCategoryTitle(gs, wMaxCategories, sCategory0);
+ hr = IGameStatistics_SetCategoryTitle(gs, wMaxCategories, L"Category0");
ok(hr==E_INVALIDARG, "setting category title invalid value: 0x%x\n", hr);
/* check what happen if string is too long */
@@ -234,45 +212,51 @@ static void test_gamestatisticsmgr( void )
ok(hr==S_FALSE, "setting category title invalid result: 0x%x\n", hr);
CoTaskMemFree(sTooLongString);
- ok(IGameStatistics_SetCategoryTitle(gs, 0, sCategory0)==S_OK, "setting category title failed: %s\n", wine_dbgstr_w(sCategory0));
- ok(IGameStatistics_SetCategoryTitle(gs, 1, sCategory1)==S_OK, "setting category title failed: %s\n", wine_dbgstr_w(sCategory1));
- ok(IGameStatistics_SetCategoryTitle(gs, 2, sCategory2)==S_OK, "setting category title failed: %s\n", wine_dbgstr_w(sCategory1));
+ ok(IGameStatistics_SetCategoryTitle(gs, 0, L"Category0")==S_OK, "setting category title failed: Category0\n");
+ ok(IGameStatistics_SetCategoryTitle(gs, 1, L"Category1")==S_OK, "setting category title failed: Category1\n");
+ ok(IGameStatistics_SetCategoryTitle(gs, 2, L"Category2")==S_OK, "setting category title failed: Category2\n");
/* check what happen if any string is NULL */
- hr = IGameStatistics_SetStatistic(gs, 0, 0, NULL, sValue00);
+ hr = IGameStatistics_SetStatistic(gs, 0, 0, NULL, L"Value00");
ok(hr == S_FALSE, "setting statistic returned unexpected value: 0x%x)\n", hr);
- hr = IGameStatistics_SetStatistic(gs, 0, 0, sStatistic00, NULL);
+ hr = IGameStatistics_SetStatistic(gs, 0, 0, L"Statistic00", NULL);
ok(hr == S_OK, "setting statistic returned unexpected value: 0x%x)\n", hr);
/* check what happen if any string is too long */
sTooLongString = CoTaskMemAlloc(sizeof(WCHAR)*(uMaxNameLength+2));
memset(sTooLongString, 'a', sizeof(WCHAR)*(uMaxNameLength+1));
sTooLongString[uMaxNameLength+1]=0;
- hr = IGameStatistics_SetStatistic(gs, 0, 0, sTooLongString, sValue00);
+ hr = IGameStatistics_SetStatistic(gs, 0, 0, sTooLongString, L"Value00");
ok(hr == S_FALSE, "setting statistic returned unexpected value: 0x%x)\n", hr);
CoTaskMemFree(sTooLongString);
sTooLongString = CoTaskMemAlloc(sizeof(WCHAR)*(uMaxValueLength+2));
memset(sTooLongString, 'a', sizeof(WCHAR)*(uMaxValueLength+1));
sTooLongString[uMaxValueLength+1]=0;
- hr = IGameStatistics_SetStatistic(gs, 0, 0, sStatistic00, sTooLongString);
+ hr = IGameStatistics_SetStatistic(gs, 0, 0, L"Statistic00", sTooLongString);
ok(hr == S_FALSE, "setting statistic returned unexpected value: 0x%x)\n", hr);
CoTaskMemFree(sTooLongString);
/* check what happen on too big index of category or statistic */
- hr = IGameStatistics_SetStatistic(gs, wMaxCategories, 0, sStatistic00, sValue00);
+ hr = IGameStatistics_SetStatistic(gs, wMaxCategories, 0, L"Statistic00", L"Value00");
ok(hr == E_INVALIDARG, "setting statistic returned unexpected value: 0x%x)\n", hr);
- hr = IGameStatistics_SetStatistic(gs, 0, wMaxStatsPerCategory, sStatistic00, sValue00);
+ hr = IGameStatistics_SetStatistic(gs, 0, wMaxStatsPerCategory, L"Statistic00", L"Value00");
ok(hr == E_INVALIDARG, "setting statistic returned unexpected value: 0x%x)\n", hr);
- ok(IGameStatistics_SetStatistic(gs, 0, 0, sStatistic00, sValue00)==S_OK, "setting statistic failed: name=%s, value=%s\n", wine_dbgstr_w(sStatistic00), wine_dbgstr_w(sValue00));
- ok(IGameStatistics_SetStatistic(gs, 0, 1, sStatistic01, sValue01)==S_OK, "setting statistic failed: name=%s, value=%s\n", wine_dbgstr_w(sStatistic01), wine_dbgstr_w(sValue01));
- ok(IGameStatistics_SetStatistic(gs, 1, 0, sStatistic10, sValue10)==S_OK, "setting statistic failed: name=%s, value=%s\n", wine_dbgstr_w(sStatistic10), wine_dbgstr_w(sValue10));
- ok(IGameStatistics_SetStatistic(gs, 1, 1, sStatistic11, sValue11)==S_OK, "setting statistic failed: name=%s, value=%s\n", wine_dbgstr_w(sStatistic11), wine_dbgstr_w(sValue11));
- ok(IGameStatistics_SetStatistic(gs, 2, 0, sStatistic20, sValue20)==S_OK, "setting statistic failed: name=%s, value=%s\n", wine_dbgstr_w(sStatistic20), wine_dbgstr_w(sValue20));
- ok(IGameStatistics_SetStatistic(gs, 2, 1, sStatistic21, sValue21)==S_OK, "setting statistic failed: name=%s, value=%s\n", wine_dbgstr_w(sStatistic21), wine_dbgstr_w(sValue21));
+ ok(IGameStatistics_SetStatistic(gs, 0, 0, L"Statistic00", L"Value00")==S_OK,
+ "setting statistic failed: name=Statistic00, value=Value00\n");
+ ok(IGameStatistics_SetStatistic(gs, 0, 1, L"Statistic01", L"Value01")==S_OK,
+ "setting statistic failed: name=Statistic01, value=Value01\n");
+ ok(IGameStatistics_SetStatistic(gs, 1, 0, L"Statistic10", L"Value10")==S_OK,
+ "setting statistic failed: name=Statistic10, value=Value10\n");
+ ok(IGameStatistics_SetStatistic(gs, 1, 1, L"Statistic11", L"Value11")==S_OK,
+ "setting statistic failed: name=Statistic11, value=Value11\n");
+ ok(IGameStatistics_SetStatistic(gs, 2, 0, L"Statistic20", L"Value20")==S_OK,
+ "setting statistic failed: name=Statistic20, value=Value20\n");
+ ok(IGameStatistics_SetStatistic(gs, 2, 1, L"Statistic21", L"Value21")==S_OK,
+ "setting statistic failed: name=Statistic21, value=Value21\n");
ok(_isFileExists(lpStatisticsFile) == FALSE, "statistics file %s already exists\n", wine_dbgstr_w(lpStatisticsFile));
@@ -281,7 +265,7 @@ static void test_gamestatisticsmgr( void )
ok(_isFileExists(lpStatisticsFile) == TRUE, "statistics file %s does not exists\n", wine_dbgstr_w(lpStatisticsFile));
/* this value should not be stored in storage, we need it only to test is it not saved */
- ok(IGameStatistics_SetCategoryTitle(gs, 0, sCategory0a)==S_OK, "setting category title failed: %s\n", wine_dbgstr_w(sCategory0a));
+ ok(IGameStatistics_SetCategoryTitle(gs, 0, L"Category0a")==S_OK, "setting category title failed: Category0a\n");
hr = IGameStatistics_Release(gs);
ok(SUCCEEDED(hr), "releasing IGameStatistics returned error: 0x%08x\n", hr);
@@ -295,17 +279,20 @@ static void test_gamestatisticsmgr( void )
/* verify values with these which we stored before*/
hr = IGameStatistics_GetCategoryTitle(gs, 0, &lpName);
ok(hr == S_OK, "getting category title failed\n");
- ok(lstrcmpW(lpName, sCategory0)==0, "getting category title returned invalid string %s\n", wine_dbgstr_w(lpName));
+ ok(lstrcmpW(lpName, L"Category0")==0, "getting category title returned invalid string %s\n",
+ wine_dbgstr_w(lpName));
CoTaskMemFree(lpName);
hr = IGameStatistics_GetCategoryTitle(gs, 1, &lpName);
ok(hr == S_OK, "getting category title failed\n");
- ok(lstrcmpW(lpName, sCategory1)==0, "getting category title returned invalid string %s\n", wine_dbgstr_w(lpName));
+ ok(lstrcmpW(lpName, L"Category1")==0, "getting category title returned invalid string %s\n",
+ wine_dbgstr_w(lpName));
CoTaskMemFree(lpName);
hr = IGameStatistics_GetCategoryTitle(gs, 2, &lpName);
ok(hr == S_OK, "getting category title failed\n");
- ok(lstrcmpW(lpName, sCategory2)==0, "getting category title returned invalid string %s\n", wine_dbgstr_w(lpName));
+ ok(lstrcmpW(lpName, L"Category2")==0, "getting category title returned invalid string %s\n",
+ wine_dbgstr_w(lpName));
CoTaskMemFree(lpName);
/* check result if category doesn't exists */
@@ -316,43 +303,43 @@ static void test_gamestatisticsmgr( void )
hr = IGameStatistics_GetStatistic(gs, 0, 0, &lpName, &lpValue);
ok(hr == S_OK, "getting statistic failed\n");
- ok(lstrcmpW(lpName, sStatistic00)==0, "getting statistic returned invalid name\n");
- ok(lstrcmpW(lpValue, sValue00)==0, "getting statistic returned invalid value\n");
+ ok(lstrcmpW(lpName, L"Statistic00")==0, "getting statistic returned invalid name\n");
+ ok(lstrcmpW(lpValue, L"Value00")==0, "getting statistic returned invalid value\n");
CoTaskMemFree(lpName);
CoTaskMemFree(lpValue);
hr = IGameStatistics_GetStatistic(gs, 0, 1, &lpName, &lpValue);
ok(hr == S_OK, "getting statistic failed\n");
- ok(lstrcmpW(lpName, sStatistic01)==0, "getting statistic returned invalid name\n");
- ok(lstrcmpW(lpValue, sValue01)==0, "getting statistic returned invalid value\n");
+ ok(lstrcmpW(lpName, L"Statistic01")==0, "getting statistic returned invalid name\n");
+ ok(lstrcmpW(lpValue, L"Value01")==0, "getting statistic returned invalid value\n");
CoTaskMemFree(lpName);
CoTaskMemFree(lpValue);
hr = IGameStatistics_GetStatistic(gs, 1, 0, &lpName, &lpValue);
ok(hr == S_OK, "getting statistic failed\n");
- ok(lstrcmpW(lpName, sStatistic10)==0, "getting statistic returned invalid name\n");
- ok(lstrcmpW(lpValue, sValue10)==0, "getting statistic returned invalid value\n");
+ ok(lstrcmpW(lpName, L"Statistic10")==0, "getting statistic returned invalid name\n");
+ ok(lstrcmpW(lpValue, L"Value10")==0, "getting statistic returned invalid value\n");
CoTaskMemFree(lpName);
CoTaskMemFree(lpValue);
hr = IGameStatistics_GetStatistic(gs, 1, 1, &lpName, &lpValue);
ok(hr == S_OK, "getting statistic failed\n");
- ok(lstrcmpW(lpName, sStatistic11)==0, "getting statistic returned invalid name\n");
- ok(lstrcmpW(lpValue, sValue11)==0, "getting statistic returned invalid value\n");
+ ok(lstrcmpW(lpName, L"Statistic11")==0, "getting statistic returned invalid name\n");
+ ok(lstrcmpW(lpValue, L"Value11")==0, "getting statistic returned invalid value\n");
CoTaskMemFree(lpName);
CoTaskMemFree(lpValue);
hr = IGameStatistics_GetStatistic(gs, 2, 0, &lpName, &lpValue);
ok(hr == S_OK, "getting statistic failed\n");
- ok(lstrcmpW(lpName, sStatistic20)==0, "getting statistic returned invalid name\n");
- ok(lstrcmpW(lpValue, sValue20)==0, "getting statistic returned invalid value\n");
+ ok(lstrcmpW(lpName, L"Statistic20")==0, "getting statistic returned invalid name\n");
+ ok(lstrcmpW(lpValue, L"Value20")==0, "getting statistic returned invalid value\n");
CoTaskMemFree(lpName);
CoTaskMemFree(lpValue);
hr = IGameStatistics_GetStatistic(gs, 2, 1, &lpName, &lpValue);
ok(hr == S_OK, "getting statistic failed\n");
- ok(lstrcmpW(lpName, sStatistic21)==0, "getting statistic returned invalid name\n");
- ok(lstrcmpW(lpValue, sValue21)==0, "getting statistic returned invalid value\n");
+ ok(lstrcmpW(lpName, L"Statistic21")==0, "getting statistic returned invalid name\n");
+ ok(lstrcmpW(lpValue, L"Value21")==0, "getting statistic returned invalid value\n");
CoTaskMemFree(lpName);
CoTaskMemFree(lpValue);
--
2.26.2
Dec. 6, 2020
Re: FOSDEM 21 emulator devroom
by Marcus Meissner
Hi,
FOSDEM 2021 will be fully virtual... so no need for travel nor belgian beer hangovers ;)
Ciao, Marcus
On Sun, Dec 06, 2020 at 01:31:29PM +0300, Stefan Dösinger wrote:
> That sounds very interesting indeed! I was thinking of giving a talk about Hangover, Apple 32 bit etc last year but missed the registration deadline.
>
> I probably won't make it to FOSDEM physically this year, if there's even an in-person FOSDEM.
>
> > Am 06.12.2020 um 12:45 schrieb Austin English <austinenglish(a)gmail.com>:
> >
> >
> >
> > ---------- Forwarded message ---------
> > From: Mahmoud Abdelghany <blackbeard334(a)protonmail.com <mailto:blackbeard334(a)protonmail.com>>
> > Date: Thu, Dec 3, 2020 at 8:44 AM
> > Subject: FOSDEM 21 emulator devroom
> > To: press(a)winehq.org <mailto:press(a)winehq.org> <press(a)winehq.org <mailto:press(a)winehq.org>>
> > Cc: christophecreeten(a)hotmail.com <mailto:christophecreeten(a)hotmail.com> <christophecreeten(a)hotmail.com <mailto:christophecreeten(a)hotmail.com>>
> >
> >
> > Hey guys,
> >
> > We're hosting an emulator development room at FOSDEM 21, and were wondering if you guys would be interested in sharing some of your knowledge with the community.
> >
> > If the answer is yes :D, please let us know.
> >
> > You can find more info here:
> > https://github.com/blackbeard334/fosdem21-emulator-devroom-cfp <https://github.com/blackbeard334/fosdem21-emulator-devroom-cfp>
> >
> >
> > Regards,
> >
> > Christophe Creeten & Mahmoud Abdelghany
> >
> > Sent with ProtonMail Secure Email.
> >
> >
> > --
> > -Austin
> > GPG: 267B CC1F 053F 0749 (expires 2021/02/18)
>
Dec. 6, 2020
Re: FOSDEM 21 emulator devroom
by Stefan Dösinger
That sounds very interesting indeed! I was thinking of giving a talk about Hangover, Apple 32 bit etc last year but missed the registration deadline.
I probably won't make it to FOSDEM physically this year, if there's even an in-person FOSDEM.
> Am 06.12.2020 um 12:45 schrieb Austin English <austinenglish(a)gmail.com>:
>
>
>
> ---------- Forwarded message ---------
> From: Mahmoud Abdelghany <blackbeard334(a)protonmail.com <mailto:blackbeard334(a)protonmail.com>>
> Date: Thu, Dec 3, 2020 at 8:44 AM
> Subject: FOSDEM 21 emulator devroom
> To: press(a)winehq.org <mailto:press(a)winehq.org> <press(a)winehq.org <mailto:press(a)winehq.org>>
> Cc: christophecreeten(a)hotmail.com <mailto:christophecreeten(a)hotmail.com> <christophecreeten(a)hotmail.com <mailto:christophecreeten(a)hotmail.com>>
>
>
> Hey guys,
>
> We're hosting an emulator development room at FOSDEM 21, and were wondering if you guys would be interested in sharing some of your knowledge with the community.
>
> If the answer is yes :D, please let us know.
>
> You can find more info here:
> https://github.com/blackbeard334/fosdem21-emulator-devroom-cfp <https://github.com/blackbeard334/fosdem21-emulator-devroom-cfp>
>
>
> Regards,
>
> Christophe Creeten & Mahmoud Abdelghany
>
> Sent with ProtonMail Secure Email.
>
>
> --
> -Austin
> GPG: 267B CC1F 053F 0749 (expires 2021/02/18)
Dec. 6, 2020
Fwd: FOSDEM 21 emulator devroom
by Austin English
---------- Forwarded message ---------
From: Mahmoud Abdelghany <blackbeard334(a)protonmail.com>
Date: Thu, Dec 3, 2020 at 8:44 AM
Subject: FOSDEM 21 emulator devroom
To: press(a)winehq.org <press(a)winehq.org>
Cc: christophecreeten(a)hotmail.com <christophecreeten(a)hotmail.com>
Hey guys,
We're hosting an emulator development room at FOSDEM 21, and were wondering
if you guys would be interested in sharing some of your knowledge with the
community.
If the answer is yes :D, please let us know.
You can find more info here:
https://github.com/blackbeard334/fosdem21-emulator-devroom-cfp
Regards,
Christophe Creeten & Mahmoud Abdelghany
Sent with ProtonMail Secure Email.
--
-Austin
GPG: 267B CC1F 053F 0749 (expires 2021/02/18)
Dec. 6, 2020
[PATCH v3] odbccp32: Implement SQLWriteDSNToIni/W
by Alistair Leslie-Hughes
Wine-bug: https://bugs.winehq.org/show_bug.cgi?id=50150
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/odbccp32/odbccp32.c | 96 +++++++++++++++++++++++++++++++--
dlls/odbccp32/tests/misc.c | 108 +++++++++++++++++++++++++++++++++++++
2 files changed, 199 insertions(+), 5 deletions(-)
diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c
index 420f206b700..53ca70c0b9f 100644
--- a/dlls/odbccp32/odbccp32.c
+++ b/dlls/odbccp32/odbccp32.c
@@ -1691,16 +1691,102 @@ BOOL WINAPI SQLValidDSN(LPCSTR lpszDSN)
BOOL WINAPI SQLWriteDSNToIniW(LPCWSTR lpszDSN, LPCWSTR lpszDriver)
{
+ BOOL ret = FALSE;
+ HKEY hkey, hkeydriver;
+ WCHAR *filename = NULL;
+ DWORD size = 0, type;
+
+ TRACE("%s %s\n", debugstr_w(lpszDSN), debugstr_w(lpszDriver));
+
clear_errors();
- FIXME("%s %s\n", debugstr_w(lpszDSN), debugstr_w(lpszDriver));
- return TRUE;
+
+ if (!SQLValidDSNW(lpszDSN))
+ {
+ push_error(ODBC_ERROR_INVALID_DSN, odbc_error_invalid_dsn);
+ return FALSE;
+ }
+
+ /* It doesn't matter if we cannot find the driver, windows just writes a blank value. */
+ if ((ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey)) == ERROR_SUCCESS)
+ {
+ HKEY hkeydriver;
+
+ if ((ret = RegOpenKeyW(hkey, lpszDriver, &hkeydriver)) == ERROR_SUCCESS)
+ {
+ ret = RegGetValueW(hkeydriver, NULL, L"driver", RRF_RT_REG_SZ, &type, NULL, &size);
+ /* Windows ignores the fact the driver key is missing */
+ if(ret == ERROR_SUCCESS && type == REG_SZ && size)
+ {
+ filename = HeapAlloc(GetProcessHeap(), 0, size);
+ if(!filename)
+ {
+ RegCloseKey(hkeydriver);
+ RegCloseKey(hkey);
+ push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
+
+ return FALSE;
+ }
+ ret = RegGetValueW(hkeydriver, NULL, L"driver", RRF_RT_REG_SZ, &type, filename, &size);
+ }
+
+ RegCloseKey(hkeydriver);
+ }
+
+ RegCloseKey(hkey);
+ }
+
+ if (RegCreateKeyW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\ODBC\\ODBC.INI", &hkey) == ERROR_SUCCESS)
+ {
+ HKEY sources;
+
+ if (RegCreateKeyW(hkey, L"ODBC Data Sources", &sources) == ERROR_SUCCESS)
+ {
+ RegSetValueExW(sources, lpszDSN, 0, REG_SZ, (BYTE*)lpszDriver, (lstrlenW(lpszDriver)+1)*sizeof(WCHAR));
+ RegCloseKey(sources);
+ }
+
+ RegDeleteTreeW(hkey, lpszDSN);
+
+ if (RegCreateKeyW(hkey, lpszDSN, &hkeydriver) == ERROR_SUCCESS)
+ {
+ if (filename)
+ RegSetValueExW(sources, L"driver", 0, REG_SZ, (BYTE*)filename, (lstrlenW(filename)+1)*sizeof(WCHAR));
+ else
+ RegSetValueExW(sources, L"driver", 0, REG_SZ, (BYTE*)L"", sizeof(L""));
+
+ RegCloseKey(hkeydriver);
+ ret = TRUE;
+ }
+
+ RegCloseKey(hkey);
+ }
+
+ if (!ret)
+ push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed);
+
+ heap_free(filename);
+
+ return ret;
}
BOOL WINAPI SQLWriteDSNToIni(LPCSTR lpszDSN, LPCSTR lpszDriver)
{
- clear_errors();
- FIXME("%s %s\n", debugstr_a(lpszDSN), debugstr_a(lpszDriver));
- return TRUE;
+ BOOL ret = FALSE;
+ WCHAR *dsn, *driver;
+
+ TRACE("%s %s\n", debugstr_a(lpszDSN), debugstr_a(lpszDriver));
+
+ dsn = SQLInstall_strdup(lpszDSN);
+ driver = SQLInstall_strdup(lpszDriver);
+ if (dsn && driver)
+ ret = SQLWriteDSNToIniW(dsn, driver);
+ else
+ push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
+
+ heap_free(dsn);
+ heap_free(driver);
+
+ return ret;
}
BOOL WINAPI SQLWriteFileDSNW(LPCWSTR lpszFileName, LPCWSTR lpszAppName,
diff --git a/dlls/odbccp32/tests/misc.c b/dlls/odbccp32/tests/misc.c
index 0120504227d..f52dcee7acd 100644
--- a/dlls/odbccp32/tests/misc.c
+++ b/dlls/odbccp32/tests/misc.c
@@ -771,6 +771,113 @@ static void test_SQLConfigDataSource(void)
check_error(ODBC_ERROR_COMPONENT_NOT_FOUND);
}
+static void test_SQLWriteDSNToIni(void)
+{
+ BOOL ret;
+ char buffer[MAX_PATH];
+ char path[MAX_PATH];
+ DWORD type, size;
+
+ SQLSetConfigMode(ODBC_SYSTEM_DSN);
+
+ ret = SQLWriteDSNToIni("wine_dbs", "SQL Server");
+ if (!ret)
+ {
+ win_skip("Doesn't have permission to write a System DSN\n");
+ return;
+ }
+
+ if(ret)
+ {
+ HKEY hkey;
+ LONG res;
+
+ res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\ODBC\\ODBC.INI\\ODBC Data Sources", 0,
+ KEY_READ, &hkey);
+ ok(res == ERROR_SUCCESS, "RegOpenKeyExW failed\n");
+ if (res == ERROR_SUCCESS)
+ {
+ type = 0xdeadbeef;
+ size = MAX_PATH;
+
+ memset(buffer, 0, sizeof(buffer));
+ res = RegQueryValueExA(hkey, "wine_dbs", NULL, &type, (BYTE *)buffer, &size);
+ ok(res == ERROR_SUCCESS, "RegGetValueA failed\n");
+ ok(type == REG_SZ, "got %u\n", type);
+ ok(!strcmp(buffer, "SQL Server"), "incorrect string '%s'\n", buffer);
+
+ RegCloseKey(hkey);
+ }
+
+ res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\ODBC\\ODBC.INI\\wine_dbs", 0,
+ KEY_READ, &hkey);
+ ok(res == ERROR_SUCCESS, "RegOpenKeyExW failed\n");
+ if (res == ERROR_SUCCESS)
+ {
+ type = 0xdeadbeef;
+ size = MAX_PATH;
+
+ memset(path, 0, sizeof(path));
+ res = RegQueryValueExA(hkey, "driver", NULL, &type, (BYTE *)path, &size);
+ ok(res == ERROR_SUCCESS, "RegGetValueA failed\n");
+ ok(type == REG_SZ, "got %u\n", type);
+ /* WINE doesn't have a 'SQL Server' driver available */
+ todo_wine ok(strlen(path) != 0, "Invalid value\n");
+
+ RegCloseKey(hkey);
+ }
+
+ ret = SQLRemoveDSNFromIni("wine_dbs");
+ ok(ret, "got %d\n", ret);
+ }
+
+ /* Show that values are writen, even though an invalid driver was specified. */
+ ret = SQLWriteDSNToIni("wine_mis", "Missing Access Driver (*.mis)");
+ ok(ret, "got %d\n", ret);
+ if(ret)
+ {
+ HKEY hkey;
+ LONG res;
+
+ res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\ODBC\\ODBC.INI\\ODBC Data Sources", 0,
+ KEY_READ, &hkey);
+ ok(res == ERROR_SUCCESS, "RegOpenKeyExW failed\n");
+ if (res == ERROR_SUCCESS)
+ {
+ type = 0xdeadbeef;
+ size = MAX_PATH;
+
+ memset(buffer, 0, sizeof(buffer));
+ res = RegQueryValueExA(hkey, "wine_mis", NULL, &type, (BYTE *)buffer, &size);
+ ok(res == ERROR_SUCCESS, "RegGetValueA failed\n");
+ ok(type == REG_SZ, "got %u\n", type);
+ ok(!strcmp(buffer, "Missing Access Driver (*.mis)"), "incorrect string '%s'\n", buffer);
+
+ RegCloseKey(hkey);
+ }
+
+ res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, "Software\\ODBC\\ODBC.INI\\wine_mis", 0,
+ KEY_READ, &hkey);
+ ok(res == ERROR_SUCCESS, "RegOpenKeyExW failed\n");
+ if (res == ERROR_SUCCESS)
+ {
+ type = 0xdeadbeef;
+ size = MAX_PATH;
+
+ memset(path, 0, sizeof(path));
+ res = RegQueryValueExA(hkey, "driver", NULL, &type, (BYTE *)path, &size);
+ ok(res == ERROR_SUCCESS, "RegGetValueA failed\n");
+ ok(type == REG_SZ, "got %u\n", type);
+ ok(strlen(path) == 0, "Invalid value\n");
+
+ RegCloseKey(hkey);
+ }
+
+ ret = SQLRemoveDSNFromIni("wine_mis");
+ ok(ret, "got %d\n", ret);
+ }
+}
+
START_TEST(misc)
{
test_SQLConfigMode();
@@ -785,4 +892,5 @@ START_TEST(misc)
test_SQLValidDSN();
test_SQLValidDSNW();
test_SQLConfigDataSource();
+ test_SQLWriteDSNToIni();
}
--
2.29.2
Dec. 6, 2020
Re: Wine staging 5.19 release
by Zebediah Figura (she/her)
On 12/4/20 8:44 AM, Gerald Pfeifer wrote:
> On Sat, 24 Oct 2020, Gerald Pfeifer wrote:
>> Here is a patch on top (of the Wine Staging patchset) that is required.
>>
>> Can you please include that? Thank you!
>
> Thanks to (I believe Zebediah) for addressing those issues!
>
> I have to confess there is one snippet I missed. With the additional
> patch below Wine 5.22 + Staging patchset builds on FreeBSD 11 out of
> the box.
>
> Thank you for considering that; for now I'm carrying it as part of
> the FreeBSD emulators/wine-devel port.
Thanks for the report; this should hopefully be fixed by
2dc013940d2aae1b2e9de887d9ddb490e8a7a6fc.
>
> Gerald
>
>
> --- dlls/ntdll/unix/file.c.orig 2020-11-07 09:33:27.083812000 +0000
> +++ dlls/ntdll/unix/file.c 2020-11-07 09:53:55.641522000 +0000
> @@ -394,6 +394,18 @@
> #define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1)
> #endif
>
> +#ifdef HAVE_SYS_EXTATTR_H
> +static inline int xattr_valid_namespace( const char *name )
> +{
> + if (strncmp( XATTR_USER_PREFIX, name, XATTR_USER_PREFIX_LEN ) != 0)
> + {
> + errno = EPERM;
> + return 0;
> + }
> + return 1;
> +}
> +#endif
> +
> static int xattr_fremove( int filedes, const char *name )
> {
> #if defined(XATTR_ADDITIONAL_OPTIONS)
>
Dec. 6, 2020
[PATCH] kernelbase: Add rudimentary mui resource support to loader.c
by Craig Schulstad
Signed-off-by: Craig Schulstad <craigaschulstad(a)gmail.com>
---
dlls/kernelbase/loader.c | 169 +++++++++++++++++++++++++++++++++++++--
1 file changed, 164 insertions(+), 5 deletions(-)
diff --git a/dlls/kernelbase/loader.c b/dlls/kernelbase/loader.c
index fc9b0ce0083..0fbe9bcd9e8 100644
--- a/dlls/kernelbase/loader.c
+++ b/dlls/kernelbase/loader.c
@@ -48,6 +48,9 @@ struct exclusive_datafile
};
static struct list exclusive_datafile_list = LIST_INIT( exclusive_datafile_list );
+static WCHAR mui_locale[LOCALE_NAME_MAX_LENGTH];
+static BOOL locale_found = 0;
+static BOOL recursion_flag = 0;
/***********************************************************************
* Modules
@@ -1011,11 +1014,122 @@ BOOL WINAPI DECLSPEC_HOTPATCH EnumResourceTypesExW( HMODULE module, ENUMRESTYPEP
return ret;
}
+/***********************************************************************/
+/* get_mui - Acquire an MUI module for the associated resource */
+/***********************************************************************/
+
+HMODULE get_mui(HMODULE module)
+
+{
+
+ HMODULE mui_module = NULL;
+
+ WCHAR module_name[MAX_PATH], mui_name[MAX_PATH];
+
+ INT i, j, k, l;
+
+ /* Initialize the work strings */
+
+ for (i = 0; i < MAX_PATH; i++) {
+ module_name[i] = 0;
+ mui_name[i] = 0;
+ }
+
+ /* Note - the reference to the Windows file name for an "MUI" file has a structure such as */
+ /* "C:\Program Files\Application Directory\xx-XX\Application.exe.mui"; however, in testing */
+ /* out the usage of the "GetModuleFileNameW" function, it was determined that it works with */
+ /* a relative Linux file structure such as "xx-XX/Application.exe.mui". */
+
+ /* Acquire the base resource file name */
+
+ if (!(GetModuleFileNameW(module, module_name, MAX_PATH))) return module;
+
+ /* Stay with the original module reference if this file is not an executable file. */
+
+ if (!(wcsstr(module_name, L".exe"))) return module;
+
+ /* Acquire the locale name using LCIDToLocaleName. Since this function utilizes the FindResourceExW function, this */
+ /* sets up a recursive call to this function. In order to avoid a stack overflow condition that would be caused by */
+ /* repeated calls, a flag will be set on to return back to the FindResourceExW function without again calling the */
+ /* locale acquisition function. */
+
+ if (!(locale_found)) {
+
+ if (recursion_flag) return module;
+
+ recursion_flag = 1;
+
+ LCIDToLocaleName( GetUserDefaultLCID(), mui_locale, LOCALE_NAME_MAX_LENGTH, 0 );
+
+ recursion_flag = 0;
+
+ locale_found = 1;
+
+ }
+
+ /* Locate the position of the final backslash in the retrieved executable file. */
+
+ j = 0;
+
+ for (i = 0; i < MAX_PATH; i++) {
+
+ if (module_name[i] == 0) break;
+
+ if (module_name[i] == '\\') j = i;
+ }
+
+ /* Set up the work index that will be used to extract just the executable file from the fully qualified file name. */
+
+ k = 0;
+
+ for (i = 0; i < MAX_PATH; i++) {
+
+ if (module_name[i] == 0) break;
+
+ /* If work index "j" has been set to -1, then the file portion of the qualified name has been reached and will */
+ /* be copied to the "MUI" file reference. */
+
+ if (j < 0) {
+ mui_name[k] = module_name[i];
+ k++;
+ }
+
+ /* When the position of the final backslash has been reached, add the locale name as the folder/directory */
+ /* containing the "MUI" file and reset work index "j" to -1. */
+
+ if (i >= j && j > 0) {
+ for (l = 0; l < 5; l++) {
+ mui_name[k] = mui_locale[l];
+ k++;
+ }
+ mui_name[k] = '/';
+ k++;
+ j = -1;
+ }
+ }
+
+ /* Finally, append the literal ".mui" onto the file reference. */
+
+ wcscat(mui_name, L".mui");
+
+ /* Now, see if there is an associated "MUI" file and if so use its handle for the module handle. */
+
+ mui_module = LoadLibraryExW(mui_name, 0, 0);
+
+ if (mui_module) {
+ return mui_module;
+ } else {
+ return module;
+ }
+
+}
+
+/***********************************************************************/
+/* get_res_handle - Isolated call of the LdrFindResource function */
+/***********************************************************************/
+
+HRSRC get_res_handle(HMODULE module, LPCWSTR type, LPCWSTR name, WORD lang)
-/**********************************************************************
- * FindResourceExW (kernelbase.@)
- */
-HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceExW( HMODULE module, LPCWSTR type, LPCWSTR name, WORD lang )
{
NTSTATUS status;
UNICODE_STRING nameW, typeW;
@@ -1024,7 +1138,6 @@ HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceExW( HMODULE module, LPCWSTR type, LP
TRACE( "%p %s %s %04x\n", module, debugstr_w(type), debugstr_w(name), lang );
- if (!module) module = GetModuleHandleW( 0 );
nameW.Buffer = typeW.Buffer = NULL;
__TRY
@@ -1046,7 +1159,41 @@ HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceExW( HMODULE module, LPCWSTR type, LP
if (!IS_INTRESOURCE(nameW.Buffer)) HeapFree( GetProcessHeap(), 0, nameW.Buffer );
if (!IS_INTRESOURCE(typeW.Buffer)) HeapFree( GetProcessHeap(), 0, typeW.Buffer );
+
return (HRSRC)entry;
+
+}
+
+/**********************************************************************
+ * FindResourceExW (kernelbase.@)
+ */
+HRSRC WINAPI DECLSPEC_HOTPATCH FindResourceExW( HMODULE module, LPCWSTR type, LPCWSTR name, WORD lang )
+{
+
+ HRSRC rsrc;
+
+ TRACE( "%p %s %s %04x\n", module, debugstr_w(type), debugstr_w(name), lang );
+
+ if (!module) module = GetModuleHandleW( 0 );
+
+ rsrc = get_res_handle(module, type, name, lang);
+
+ if (rsrc) {
+
+ return rsrc;
+
+ } else {
+
+ /* If a resource retrieval failed using the initial module value, attempt to */
+ /* locate an associated MUI file and retry the resource retrieval. */
+
+ module = get_mui(module);
+
+ rsrc = get_res_handle(module, type, name, lang);
+
+ return rsrc;
+
+ }
}
@@ -1074,11 +1221,23 @@ BOOL WINAPI DECLSPEC_HOTPATCH FreeResource( HGLOBAL handle )
HGLOBAL WINAPI DECLSPEC_HOTPATCH LoadResource( HINSTANCE module, HRSRC rsrc )
{
void *ret;
+ HMODULE mui_module = NULL;
TRACE( "%p %p\n", module, rsrc );
if (!rsrc) return 0;
if (!module) module = GetModuleHandleW( 0 );
+
+
+ /* Only check for an MUI reference if the resource handle value is less than the module value, */
+ /* or if an MUI reference was found and the MUI reference and handle value are larger than the */
+ /* module value for the executable file. That is a signal that the resource handle is to be */
+ /* associated with the MUI file instead of the executable file. */
+
+ mui_module = get_mui(module);
+
+ if (((HMODULE)rsrc < module) || ((mui_module > module) && ((HMODULE)rsrc > mui_module))) module = mui_module;
+
if (!set_ntstatus( LdrAccessResource( module, (IMAGE_RESOURCE_DATA_ENTRY *)rsrc, &ret, NULL )))
return 0;
return ret;
--
2.17.1
Dec. 5, 2020
[PATCH] winegstreamer: Clean up a newly allocated buffer on error in bytestream_wrapper_pull().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/winegstreamer/media_source.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c
index d411bbd1de2..ffbf8041ed8 100644
--- a/dlls/winegstreamer/media_source.c
+++ b/dlls/winegstreamer/media_source.c
@@ -443,6 +443,7 @@ GstFlowReturn bytestream_wrapper_pull(GstPad *pad, GstObject *parent, guint64 of
{
struct media_source *source = gst_pad_get_element_private(pad);
IMFByteStream *byte_stream = source->byte_stream;
+ GstBuffer *new_buffer = NULL;
ULONG bytes_read;
GstMapInfo info;
BOOL is_eof;
@@ -463,7 +464,7 @@ GstFlowReturn bytestream_wrapper_pull(GstPad *pad, GstObject *parent, guint64 of
return GST_FLOW_EOS;
if (!(*buf))
- *buf = gst_buffer_new_and_alloc(len);
+ *buf = new_buffer = gst_buffer_new_and_alloc(len);
gst_buffer_map(*buf, &info, GST_MAP_WRITE);
hr = IMFByteStream_Read(byte_stream, info.data, len, &bytes_read);
gst_buffer_unmap(*buf, &info);
@@ -471,7 +472,11 @@ GstFlowReturn bytestream_wrapper_pull(GstPad *pad, GstObject *parent, guint64 of
gst_buffer_set_size(*buf, bytes_read);
if (FAILED(hr))
+ {
+ if (new_buffer)
+ gst_buffer_unref(new_buffer);
return GST_FLOW_ERROR;
+ }
return GST_FLOW_OK;
}
--
2.29.2
Dec. 5, 2020
[PATCH v2] msctf/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
v2: Missed to commit a line break.
dlls/msctf/tests/inputprocessor.c | 9 +++------
1 file changed, 3 insertions(+), 6 deletions(-)
diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c
index 1c97d2c5d1c..55a6ab6c34c 100644
--- a/dlls/msctf/tests/inputprocessor.c
+++ b/dlls/msctf/tests/inputprocessor.c
@@ -1112,9 +1112,6 @@ static void test_Register(void)
{
HRESULT hr;
- static const WCHAR szDesc[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',0};
- static const WCHAR szFile[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',' ','F','i','l','e',0};
-
hr = ITfInputProcessorProfiles_GetCurrentLanguage(g_ipp,&gLangid);
ok(SUCCEEDED(hr),"Unable to get current language id\n");
trace("Current Language %x\n",gLangid);
@@ -1124,7 +1121,8 @@ static void test_Register(void)
hr = ITfInputProcessorProfiles_Register(g_ipp, &CLSID_FakeService);
ok(SUCCEEDED(hr),"Unable to register text service(%x)\n",hr);
hr = ITfInputProcessorProfiles_AddLanguageProfile(g_ipp, &CLSID_FakeService, gLangid,
- &CLSID_FakeService, szDesc, ARRAY_SIZE(szDesc), szFile, ARRAY_SIZE(szFile), 1);
+ &CLSID_FakeService, L"Fake Wine Service", ARRAY_SIZE(L"Fake Wine Service"),
+ L"Fake Wine Service File", ARRAY_SIZE(L"Fake Wine Service File"), 1);
ok(SUCCEEDED(hr),"Unable to add Language Profile (%x)\n",hr);
}
@@ -2071,12 +2069,11 @@ static void test_InsertAtSelection(TfEditCookie ec, ITfContext *cxt)
HRESULT hr;
ITfInsertAtSelection *iis;
ITfRange *range=NULL;
- static const WCHAR txt[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
hr = ITfContext_QueryInterface(cxt, &IID_ITfInsertAtSelection , (LPVOID*)&iis);
ok(SUCCEEDED(hr),"Failed to get ITfInsertAtSelection interface\n");
test_ACP_InsertTextAtSelection = SINK_EXPECTED;
- hr = ITfInsertAtSelection_InsertTextAtSelection(iis, ec, 0, txt, 11, &range);
+ hr = ITfInsertAtSelection_InsertTextAtSelection(iis, ec, 0, L"Hello World", 11, &range);
ok(SUCCEEDED(hr),"ITfInsertAtSelection_InsertTextAtSelection failed %x\n",hr);
sink_check_ok(&test_ACP_InsertTextAtSelection,"InsertTextAtSelection");
ok(range != NULL,"No range returned\n");
--
2.26.2
Dec. 5, 2020
Re: Re: Wine staging 5.19 release
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=83152
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/ntdll/unix/file.c:394
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/ntdll/unix/file.c:394
Task: Patch failed to apply
Dec. 5, 2020
Wine staging 6.0rc1 release
by Alistair Leslie-Hughes
Binary packages for various distributions will be available from:
https://www.winehq.org/download
Summary since last release
* Rebased to current wine 6.0rc1 (740 patches are applied to wine vanilla)
Upstreamed (Either directly from staging or fixed with a similar patch).
* HACK: Switch between all selection streams on MF_SOURCE_READER_ANY_STREAM.
* msctf: Added ITfActiveLanguageProfileNotifySink support in ITfSource.
* winebuild: Call __wine_syscall_dispatcher through the fixed address.
* mf/topoloader: Add partial topology resolution tests.
* mf/topoloader: Move node connection responsibility to connection function.
* mf/topoloader: Implement source node to sink node branch resolver.
* mf/topoloader: Unstub IMFTopologyLoader::Load.
* winegstreamer: Implement ::SetInputType for audio conversion transform.
* winegstreamer: Implement ::SetOutputType for audio conversion transform.
* winegstreamer: Implement Get(Input/Output)CurrentType functions for
audio converter transform.
Added:
* [40262] Correct order of windows messages.
* [46070] Basemark Web 3.0 Desktop Launcher crashes.
Updated:
* msvcrt-Math_Precision
* mfplat-streaming-support
* ntdll-Junction_Points
* widl-winrt-support
Where can you help
* Run Steam/Battle.net/GOG/UPlay/Epic
* Test your favorite game.
* Test your favorite applications.
* Improve staging patches and get them accepted upstream.
As always, if you find a bug, please report it via
https://bugs.winehq.org
Best Regards
Alistair.
Dec. 5, 2020
Re: [PATCH] ntdll: Fix memchr implementation.
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=83142
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/msvcrt/string.c:2621
error: patch failed: dlls/ntdll/string.c:72
error: patch failed: dlls/ntdll/tests/string.c:65
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/msvcrt/string.c:2621
error: patch failed: dlls/ntdll/string.c:72
error: patch failed: dlls/ntdll/tests/string.c:65
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 17/17] winegstreamer: Implement Get(Input/Output)CurrentType functions for color converter 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=83139
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 16/17] winegstreamer: Semi-stub Get*Attributes functions for color converter 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=83138
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 15/17] winegstreamer: Implement ::Get(Input/Output)StreamInfo for color 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=83137
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 14/17] winegstreamer: Implement ::ProcessMessage for color conversion MFT.
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=83136
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 13/17] winegstreamer: Implement ::Process(Input/Output) for color 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=83135
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 12/17] winegstreamer: Implement ::SetOutputType for color 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=83134
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 11/17] winegstreamer: Implement ::GetOutputAvailableType for color 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=83133
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 10/17] winegstreamer: Implement ::SetInputType for color 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=83132
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 09/17] winegstreamer: Implement ::GetInputAvailableType for color 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=83131
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 08/17] winegstreamer: Register the color 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=83130
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH v2 07/17] winegstreamer: Introduce color 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=83129
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/audioconvert.c:18
error: patch failed: dlls/winegstreamer/audioconvert.c:38
error: patch failed: dlls/winegstreamer/audioconvert.c:295
error: patch failed: dlls/winegstreamer/audioconvert.c:87
error: patch failed: dlls/winegstreamer/audioconvert.c:495
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH 11/11] msvcrt: Remove separate long double math funtions.
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=83118
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/msvcrt/errno.c:126
error: patch failed: dlls/msvcrt/msvcrt.h:40
error: patch failed: dlls/msvcrt/exit.c:31
error: patch failed: dlls/msvcrt/msvcrt.h:40
error: patch failed: include/msvcrt/stdlib.h:230
error: patch failed: dlls/msvcrt/math.c:35
error: patch failed: dlls/msvcrt/msvcrt.h:283
error: patch failed: dlls/msvcrt/except_arm.c:21
error: patch failed: dlls/msvcrt/except_arm64.c:22
error: patch failed: dlls/msvcrt/except_i386.c:27
error: patch failed: dlls/msvcrt/except_x86_64.c:20
error: patch failed: dlls/msvcrt/msvcrt.h:283
error: patch failed: dlls/msvcrt/dir.c:21
error: patch failed: dlls/msvcrt/msvcrt.h:283
error: patch failed: dlls/msvcrt/file.c:3003
error: patch failed: dlls/msvcrt/msvcrt.h:283
error: patch failed: dlls/msvcrt/data.c:18
error: patch failed: dlls/msvcrt/exit.c:50
error: patch failed: dlls/msvcrt/file.c:27
error: patch failed: dlls/msvcrt/heap.c:847
error: patch failed: dlls/msvcrt/mbcs.c:2597
error: patch failed: dlls/msvcrt/misc.c:59
error: patch failed: dlls/msvcrt/msvcrt.h:283
error: patch failed: dlls/msvcrt/printf.h:966
error: patch failed: dlls/msvcrt/process.c:27
error: patch failed: dlls/msvcrt/string.c:1350
error: patch failed: dlls/msvcrt/time.c:666
error: patch failed: dlls/msvcrt/wcs.c:124
error: patch failed: dlls/msvcrt/dir.c:22
error: patch failed: dlls/msvcrt/exit.c:17
error: patch failed: dlls/msvcrt/mbcs.c:26
error: patch failed: dlls/msvcrt/msvcrt.h:296
error: patch failed: dlls/msvcrt/scanf.c:23
error: patch failed: include/msvcrt/mbctype.h:68
error: patch failed: include/msvcrt/mbstring.h:113
error: patch failed: dlls/msvcrt/locale.c:2052
error: patch failed: dlls/msvcrt/msvcrt.h:296
error: patch failed: include/msvcrt/locale.h:68
error: patch failed: dlls/msvcr120/msvcr120.spec:1391
error: patch failed: dlls/msvcrt/math.c:61
error: patch failed: dlls/ucrtbase/ucrtbase.spec:531
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/msvcrt/errno.c:126
error: patch failed: dlls/msvcrt/msvcrt.h:40
error: patch failed: dlls/msvcrt/exit.c:31
error: patch failed: dlls/msvcrt/msvcrt.h:40
error: patch failed: include/msvcrt/stdlib.h:230
error: patch failed: dlls/msvcrt/math.c:35
error: patch failed: dlls/msvcrt/msvcrt.h:283
error: patch failed: dlls/msvcrt/except_arm.c:21
error: patch failed: dlls/msvcrt/except_arm64.c:22
error: patch failed: dlls/msvcrt/except_i386.c:27
error: patch failed: dlls/msvcrt/except_x86_64.c:20
error: patch failed: dlls/msvcrt/msvcrt.h:283
error: patch failed: dlls/msvcrt/dir.c:21
error: patch failed: dlls/msvcrt/msvcrt.h:283
error: patch failed: dlls/msvcrt/file.c:3003
error: patch failed: dlls/msvcrt/msvcrt.h:283
error: patch failed: dlls/msvcrt/data.c:18
error: patch failed: dlls/msvcrt/exit.c:50
error: patch failed: dlls/msvcrt/file.c:27
error: patch failed: dlls/msvcrt/heap.c:847
error: patch failed: dlls/msvcrt/mbcs.c:2597
error: patch failed: dlls/msvcrt/misc.c:59
error: patch failed: dlls/msvcrt/msvcrt.h:283
error: patch failed: dlls/msvcrt/printf.h:966
error: patch failed: dlls/msvcrt/process.c:27
error: patch failed: dlls/msvcrt/string.c:1350
error: patch failed: dlls/msvcrt/time.c:666
error: patch failed: dlls/msvcrt/wcs.c:124
error: patch failed: dlls/msvcrt/dir.c:22
error: patch failed: dlls/msvcrt/exit.c:17
error: patch failed: dlls/msvcrt/mbcs.c:26
error: patch failed: dlls/msvcrt/msvcrt.h:296
error: patch failed: dlls/msvcrt/scanf.c:23
error: patch failed: include/msvcrt/mbctype.h:68
error: patch failed: include/msvcrt/mbstring.h:113
error: patch failed: dlls/msvcrt/locale.c:2052
error: patch failed: dlls/msvcrt/msvcrt.h:296
error: patch failed: include/msvcrt/locale.h:68
error: patch failed: dlls/msvcr120/msvcr120.spec:1391
error: patch failed: dlls/msvcrt/math.c:61
error: patch failed: dlls/ucrtbase/ucrtbase.spec:531
Task: Patch failed to apply
Dec. 4, 2020
Re: [PATCH] msctf/tests: Use wide-char string literals.
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=83145
Your paranoid android.
=== w1064 (32 bit report) ===
msctf:
inputprocessor.c:537: Test failed: Unexpected ThreadMgrEventSink_OnSetFocus sink
Dec. 4, 2020
[PATCH] oledlg/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/oledlg/tests/main.c | 22 +++++++++-------------
1 file changed, 9 insertions(+), 13 deletions(-)
diff --git a/dlls/oledlg/tests/main.c b/dlls/oledlg/tests/main.c
index 3bb384710b0..919cd008542 100644
--- a/dlls/oledlg/tests/main.c
+++ b/dlls/oledlg/tests/main.c
@@ -49,7 +49,6 @@ static ULONG WINAPI enumverbs_Release(IEnumOLEVERB *iface)
}
static int g_enumpos;
-static const WCHAR verbW[] = {'v','e','r','b',0};
static HRESULT WINAPI enumverbs_Next(IEnumOLEVERB *iface, ULONG count, OLEVERB *verbs, ULONG *fetched)
{
ok(count == 1, "got %u\n", count);
@@ -58,8 +57,8 @@ static HRESULT WINAPI enumverbs_Next(IEnumOLEVERB *iface, ULONG count, OLEVERB *
if (g_enumpos++ == 0) {
verbs->lVerb = 123;
- verbs->lpszVerbName = CoTaskMemAlloc(sizeof(verbW));
- lstrcpyW(verbs->lpszVerbName, verbW);
+ verbs->lpszVerbName = CoTaskMemAlloc(sizeof(L"verb"));
+ lstrcpyW(verbs->lpszVerbName, L"verb");
verbs->fuFlags = MF_ENABLED;
verbs->grfAttribs = OLEVERBATTRIB_ONCONTAINERMENU;
if (fetched) *fetched = 1;
@@ -207,14 +206,12 @@ static HRESULT WINAPI oleobject_GetUserClassID(IOleObject *iface, CLSID *clsid)
ok(0, "unexpected call\n");
return E_NOTIMPL;
}
-
-static const WCHAR testW[] = {'t','e','s','t',0};
static HRESULT WINAPI oleobject_GetUserType(IOleObject *iface, DWORD formoftype,
LPOLESTR *usertype)
{
ok(formoftype == USERCLASSTYPE_SHORT, "got %d\n", formoftype);
- *usertype = CoTaskMemAlloc(sizeof(testW));
- lstrcpyW(*usertype, testW);
+ *usertype = CoTaskMemAlloc(sizeof(L"test"));
+ lstrcpyW(*usertype, L"test");
return S_OK;
}
@@ -291,7 +288,6 @@ static IOleObject oleobject = { &oleobjectvtbl };
static void test_OleUIAddVerbMenu(void)
{
- static const WCHAR cadabraW[] = {'c','a','d','a','b','r','a',0};
HMENU hMenu, verbmenu;
MENUITEMINFOW info;
WCHAR buffW[50];
@@ -365,7 +361,7 @@ static void test_OleUIAddVerbMenu(void)
/* now without object */
verbmenu = (HMENU)0xdeadbeef;
- ret = OleUIAddVerbMenuW(NULL, testW, hMenu, 3, 42, 0, FALSE, 0, &verbmenu);
+ ret = OleUIAddVerbMenuW(NULL, L"test", hMenu, 3, 42, 0, FALSE, 0, &verbmenu);
ok(!ret, "got %d\n", ret);
ok(verbmenu == NULL, "got %p\n", verbmenu);
@@ -399,7 +395,7 @@ static void test_OleUIAddVerbMenu(void)
ok(ret, "got %d\n", ret);
/* Item string contains verb, usertype and localized string for 'Object' word,
exact format depends on localization. */
- ok(wcsstr(buffW, verbW) != NULL, "str %s\n", wine_dbgstr_w(buffW));
+ ok(wcsstr(buffW, L"verb") != NULL, "str %s\n", wine_dbgstr_w(buffW));
ok(info.fState == 0, "got state 0x%08x\n", info.fState);
ok(info.hSubMenu == NULL, "got submenu %p\n", info.hSubMenu);
@@ -445,13 +441,13 @@ static void test_OleUIAddVerbMenu(void)
info.fMask = MIIM_STRING|MIIM_STATE;
info.fState = MFS_ENABLED;
info.dwTypeData = buffW;
- lstrcpyW(buffW, cadabraW);
+ lstrcpyW(buffW, L"cadabra");
ret = SetMenuItemInfoW(hMenu, 0, TRUE, &info);
ok(ret, "got %d\n", ret);
buffW[0] = 0;
GetMenuStringW(hMenu, 0, buffW, ARRAY_SIZE(buffW), MF_BYPOSITION);
- ok(!lstrcmpW(buffW, cadabraW), "got %s\n", wine_dbgstr_w(buffW));
+ ok(!lstrcmpW(buffW, L"cadabra"), "got %s\n", wine_dbgstr_w(buffW));
verbmenu = NULL;
ret = OleUIAddVerbMenuW(NULL, NULL, hMenu, 0, 5, 10, TRUE, 3, &verbmenu);
@@ -466,7 +462,7 @@ static void test_OleUIAddVerbMenu(void)
info.cch = ARRAY_SIZE(buffW);
ret = GetMenuItemInfoW(hMenu, 0, TRUE, &info);
ok(ret, "got %d\n", ret);
- ok(lstrcmpW(buffW, cadabraW), "got %s\n", wine_dbgstr_w(buffW));
+ ok(lstrcmpW(buffW, L"cadabra"), "got %s\n", wine_dbgstr_w(buffW));
ok(info.fState == MF_GRAYED, "got state 0x%08x\n", info.fState);
count = GetMenuItemCount(hMenu);
--
2.26.2
Dec. 4, 2020
[PATCH] msctf/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/msctf/tests/inputprocessor.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/dlls/msctf/tests/inputprocessor.c b/dlls/msctf/tests/inputprocessor.c
index 1c97d2c5d1c..1a5f52aabf9 100644
--- a/dlls/msctf/tests/inputprocessor.c
+++ b/dlls/msctf/tests/inputprocessor.c
@@ -1112,9 +1112,6 @@ static void test_Register(void)
{
HRESULT hr;
- static const WCHAR szDesc[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',0};
- static const WCHAR szFile[] = {'F','a','k','e',' ','W','i','n','e',' ','S','e','r','v','i','c','e',' ','F','i','l','e',0};
-
hr = ITfInputProcessorProfiles_GetCurrentLanguage(g_ipp,&gLangid);
ok(SUCCEEDED(hr),"Unable to get current language id\n");
trace("Current Language %x\n",gLangid);
@@ -1124,7 +1121,7 @@ static void test_Register(void)
hr = ITfInputProcessorProfiles_Register(g_ipp, &CLSID_FakeService);
ok(SUCCEEDED(hr),"Unable to register text service(%x)\n",hr);
hr = ITfInputProcessorProfiles_AddLanguageProfile(g_ipp, &CLSID_FakeService, gLangid,
- &CLSID_FakeService, szDesc, ARRAY_SIZE(szDesc), szFile, ARRAY_SIZE(szFile), 1);
+ &CLSID_FakeService, L"Fake Wine Service", ARRAY_SIZE(L"Fake Wine Service"), L"Fake Wine Service File", ARRAY_SIZE(L"Fake Wine Service File"), 1);
ok(SUCCEEDED(hr),"Unable to add Language Profile (%x)\n",hr);
}
@@ -2071,12 +2068,11 @@ static void test_InsertAtSelection(TfEditCookie ec, ITfContext *cxt)
HRESULT hr;
ITfInsertAtSelection *iis;
ITfRange *range=NULL;
- static const WCHAR txt[] = {'H','e','l','l','o',' ','W','o','r','l','d',0};
hr = ITfContext_QueryInterface(cxt, &IID_ITfInsertAtSelection , (LPVOID*)&iis);
ok(SUCCEEDED(hr),"Failed to get ITfInsertAtSelection interface\n");
test_ACP_InsertTextAtSelection = SINK_EXPECTED;
- hr = ITfInsertAtSelection_InsertTextAtSelection(iis, ec, 0, txt, 11, &range);
+ hr = ITfInsertAtSelection_InsertTextAtSelection(iis, ec, 0, L"Hello World", 11, &range);
ok(SUCCEEDED(hr),"ITfInsertAtSelection_InsertTextAtSelection failed %x\n",hr);
sink_check_ok(&test_ACP_InsertTextAtSelection,"InsertTextAtSelection");
ok(range != NULL,"No range returned\n");
--
2.26.2
Dec. 4, 2020
[PATCH] msvfw32/tests: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/msvfw32/tests/msvfw.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/msvfw32/tests/msvfw.c b/dlls/msvfw32/tests/msvfw.c
index 2d85e26df19..def78f02e9d 100644
--- a/dlls/msvfw32/tests/msvfw.c
+++ b/dlls/msvfw32/tests/msvfw.c
@@ -401,7 +401,6 @@ static LRESULT CALLBACK enum_driver_proc(DWORD_PTR id, HDRVR driver, UINT msg,
static void test_ICInfo(void)
{
- static const WCHAR bogusW[] = {'b','o','g','u','s',0};
static const DWORD test_type = mmioFOURCC('w','i','n','e');
static const DWORD test_handler = mmioFOURCC('t','e','s','t');
DWORD i = 0, found = 0;
@@ -475,7 +474,7 @@ static void test_ICInfo(void)
ok(info.dwVersionICM == ICVERSION, "Got unexpected ICM version %#x.\n", info.dwVersionICM);
ok(!info.szName[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szName));
ok(!info.szDescription[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szDescription));
- ok(!lstrcmpW(info.szDriver, bogusW), "Got unexpected driver %s.\n", wine_dbgstr_w(info.szDriver));
+ ok(!lstrcmpW(info.szDriver, L"bogus"), "Got unexpected driver %s.\n", wine_dbgstr_w(info.szDriver));
/* Drivers installed after msvfw32 is loaded are not enumerated. */
todo_wine
@@ -503,7 +502,7 @@ todo_wine
ok(info.dwVersionICM == ICVERSION, "Got unexpected ICM version %#x.\n", info.dwVersionICM);
ok(!info.szName[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szName));
ok(!info.szDescription[0], "Got unexpected name %s.\n", wine_dbgstr_w(info.szDescription));
- ok(!lstrcmpW(info.szDriver, bogusW), "Got unexpected driver %s.\n", wine_dbgstr_w(info.szDriver));
+ ok(!lstrcmpW(info.szDriver, L"bogus"), "Got unexpected driver %s.\n", wine_dbgstr_w(info.szDriver));
/* Drivers installed after msvfw32 is loaded are not enumerated. */
todo_wine
--
2.26.2
Dec. 4, 2020
Re: [PATCH v2 2/2] odbccp32: Implement SQLWriteDSNToIni/W
by Alexandre Julliard
Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com> writes:
> + /* It doesn't matter if we cannot find the driver, windows just writes a blank value. */
> + if ((ret = RegOpenKeyW(HKEY_LOCAL_MACHINE, odbcini, &hkey)) == ERROR_SUCCESS)
> + {
> + HKEY hkeydriver;
> +
> + if ((ret = RegOpenKeyW(hkey, lpszDriver, &hkeydriver)) == ERROR_SUCCESS)
> + {
> + ret = RegGetValueW(hkeydriver, NULL, L"driver", RRF_RT_REG_SZ, &type, NULL, &size);
> + if(ret != ERROR_SUCCESS || type != REG_SZ)
> + {
> + RegCloseKey(hkey);
> + }
Did you mean to return an error here?
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 4, 2020
Re: [PATCH 2/3] include: Emit assembly function debug line info.
by Rémi Bernon
So this was breaking compilation on macOS. I could fix it, but is it
worth re-sending it? After 6.0 probably?
--
Rémi Bernon <rbernon(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 2/2] quartz/vmr9: Allow the aspect ratio parameters to be NULL in IVMRWindowlessControl::GetNativeVideoSize().
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 1/2] quartz/tests: Add some tests for VMR7 windowless video size.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 3/7] d3d9/tests: Skip pretransformed_varying_test() on 32-bit WARP.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 4/7] d3d9/tests: Accept new WARP test failure in test_updatetexture().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 2/7] wined3d: Allow forcing commands serialization in the CS thread.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 1/7] wined3d: Rename d3d_synchronous debug channel to d3d_sync.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 5/7] wined3d: Don't try to cleanup an invalid context.
by Matteo Bruni
On Fri, Dec 4, 2020 at 5:47 PM Henri Verbeet <hverbeet(a)gmail.com> wrote:
>
> On Thu, 3 Dec 2020 at 20:29, Matteo Bruni <mbruni(a)codeweavers.com> wrote:
> >
> > 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.
> >
> I don't think switching away from an invalid (i.e., one for which the
> DC was destroyed) context should generally fail.
>
> I didn't debug this, but from you description I gather there's an
> issue with the context_restore_gl_context() in
> wined3d_context_gl_cleanup(). It would be good to know what the
> *exact* issue is there, but perhaps wined3d_context_gl_cleanup()
> should call TlsSetValue(wined3d_context_tls_idx, NULL) before calling
> context_restore_gl_context(), so that if it does end up failing, we at
> least don't end up referencing a partially destroyed "old" context in
> wined3d_context_gl_set_current(). We do that in
> wined3d_context_gl_destroy() for similar reasons, but that doesn't
> help when wined3d_context_gl_cleanup() is called from
> wined3d_context_gl_set_current().
I'm not sure right now but IIRC it was something along those lines
i.e. referencing the context while it's being destroyed. I'll have
another look.
Dec. 4, 2020
Re: [PATCH 5/7] wined3d: Don't try to cleanup an invalid context.
by Henri Verbeet
On Thu, 3 Dec 2020 at 20:29, Matteo Bruni <mbruni(a)codeweavers.com> wrote:
>
> 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.
>
I don't think switching away from an invalid (i.e., one for which the
DC was destroyed) context should generally fail.
I didn't debug this, but from you description I gather there's an
issue with the context_restore_gl_context() in
wined3d_context_gl_cleanup(). It would be good to know what the
*exact* issue is there, but perhaps wined3d_context_gl_cleanup()
should call TlsSetValue(wined3d_context_tls_idx, NULL) before calling
context_restore_gl_context(), so that if it does end up failing, we at
least don't end up referencing a partially destroyed "old" context in
wined3d_context_gl_set_current(). We do that in
wined3d_context_gl_destroy() for similar reasons, but that doesn't
help when wined3d_context_gl_cleanup() is called from
wined3d_context_gl_set_current().
Dec. 4, 2020
[PATCH] ntdll: Fix memchr implementation.
by Piotr Caban
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50228
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcrt/string.c | 2 +-
dlls/ntdll/string.c | 2 +-
dlls/ntdll/tests/string.c | 21 +++++++++++++++++++++
3 files changed, 23 insertions(+), 2 deletions(-)
Dec. 4, 2020
[PATCH] dbghelp: Read process memory using target addresses, not debugger.
by Rémi Bernon
This fixes "wine winedbg --gdb winecfg" not working anymore.
There was a regression since f40195cd9206, but the environment read was
broken before.
Signed-off-by: Rémi Bernon <rbernon(a)codeweavers.com>
---
dlls/dbghelp/dbghelp.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c
index e38687412eb..00d7b61fbd8 100644
--- a/dlls/dbghelp/dbghelp.c
+++ b/dlls/dbghelp/dbghelp.c
@@ -311,8 +311,8 @@ static BOOL check_live_target(struct process* pcs)
{
PEB peb;
if (!ReadProcessMemory(pcs->handle, pbi.PebBaseAddress, &peb, sizeof(peb), NULL)) return FALSE;
- if (!ReadProcessMemory(pcs->handle, &peb.CloudFileFlags, &base, sizeof(base), NULL)) return FALSE;
- ReadProcessMemory(pcs->handle, &peb.ProcessParameters->Environment, &env, sizeof(env), NULL);
+ if (!ReadProcessMemory(pcs->handle, (char *)pbi.PebBaseAddress + FIELD_OFFSET(PEB, CloudFileFlags), &base, sizeof(base), NULL)) return FALSE;
+ ReadProcessMemory(pcs->handle, (char *)peb.ProcessParameters + FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment), &env, sizeof(env), NULL);
}
/* read debuggee environment block */
--
2.29.2
Dec. 4, 2020
[PATCH v2 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 3ae646f1ae2..9c845b270d2 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -479,16 +479,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. 4, 2020
[PATCH v2 16/17] winegstreamer: Semi-stub 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 a53cb8a099c..3ae646f1ae2 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);
}
@@ -170,9 +176,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,
@@ -186,9 +197,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)
@@ -653,6 +669,7 @@ HRESULT color_converter_create(REFIID riid, void **ret)
{
struct color_converter *object;
GstElement *videoconvert;
+ HRESULT hr;
TRACE("%s %p\n", debugstr_guid(riid), ret);
@@ -665,6 +682,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. 4, 2020
[PATCH v2 15/17] winegstreamer: Implement ::Get(Input/Output)StreamInfo for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2:
- Set MFT_OUTPUT_STREAM_WHOLE_SAMPLES on output stream info.
- Set cbSize.
---
dlls/winegstreamer/colorconvert.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index 8272beaac83..a53cb8a099c 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -138,16 +138,34 @@ 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;
+ /* TODO: this can be calculated using MFCalculateImageSize */
+ info->cbSize = 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 | MFT_OUTPUT_STREAM_WHOLE_SAMPLES;
+ info->cbAlignment = 0;
+ /* TODO: this can be calculated using MFCalculateImageSize */
+ info->cbSize = 0;
+
+ return S_OK;
}
static HRESULT WINAPI color_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
--
2.29.2
Dec. 4, 2020
[PATCH v2 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 4aa563ab0d9..8272beaac83 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -487,9 +487,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. 4, 2020
[PATCH v2 13/17] winegstreamer: Implement ::Process(Input/Output) for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2:
- Don't store intermediate elements in object structure.
= Reset 'inflight' when I/O types change.
= Cleanup redundant error logging.
- Address nits.
---
dlls/winegstreamer/colorconvert.c | 172 ++++++++++++++++++++++++++++--
1 file changed, 165 insertions(+), 7 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index c2665cbdacb..4aa563ab0d9 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, *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);
}
@@ -281,6 +284,9 @@ static HRESULT WINAPI color_converter_SetInputType(IMFTransform *iface, DWORD id
EnterCriticalSection(&converter->cs);
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
+
if (converter->input_type)
{
IMFMediaType_Release(converter->input_type);
@@ -312,14 +318,17 @@ 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);
return S_OK;
+ }
EnterCriticalSection(&converter->cs);
hr = S_OK;
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
if (!converter->input_type)
hr = MFCreateMediaType(&converter->input_type);
@@ -327,12 +336,18 @@ 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);
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;
@@ -359,6 +374,9 @@ static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD i
EnterCriticalSection(&converter->cs);
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
+
if (converter->output_type)
{
IMFMediaType_Release(converter->output_type);
@@ -390,14 +408,17 @@ 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);
return S_OK;
+ }
EnterCriticalSection(&converter->cs);
hr = S_OK;
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
if (!converter->output_type)
hr = MFCreateMediaType(&converter->output_type);
@@ -405,12 +426,18 @@ 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);
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;
@@ -467,15 +494,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, (%s)\n", 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;
}
@@ -513,6 +627,7 @@ static const IMFTransformVtbl color_converter_vtbl =
HRESULT color_converter_create(REFIID riid, void **ret)
{
struct color_converter *object;
+ GstElement *videoconvert;
TRACE("%s %p\n", debugstr_guid(riid), ret);
@@ -525,6 +640,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 (!(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), 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, videoconvert))
+ {
+ ERR("Failed to link appsrc to videoconvert\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
+ if (!gst_element_link(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. 4, 2020
[PATCH v2 12/17] winegstreamer: Implement ::SetOutputType for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2: Reorganize function to avoid having a conditionally initialized variable.
---
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 a7206408603..c2665cbdacb 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;
};
@@ -339,9 +340,80 @@ 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);
+ GUID major_type, subtype;
+ 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)
+ {
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ return S_OK;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (converter->output_type)
+ {
+ IMFMediaType_Release(converter->output_type);
+ converter->output_type = NULL;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return S_OK;
+ }
+
+ 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 (!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;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return hr;
}
static HRESULT WINAPI color_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
--
2.29.2
Dec. 4, 2020
[PATCH v2 11/17] winegstreamer: Implement ::GetOutputAvailableType for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2: Remove orphaned function.
---
dlls/winegstreamer/colorconvert.c | 38 +++++++++++++++++++++++++++++--
1 file changed, 36 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index a7660453766..a7206408603 100644
--- a/dlls/winegstreamer/colorconvert.c
+++ b/dlls/winegstreamer/colorconvert.c
@@ -220,9 +220,43 @@ static HRESULT WINAPI color_converter_GetInputAvailableType(IMFTransform *iface,
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. 4, 2020
[PATCH v2 10/17] winegstreamer: Implement ::SetInputType for color conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2: Reorganize function to avoid having a conditionally initialized variable.
---
dlls/winegstreamer/colorconvert.c | 82 ++++++++++++++++++++++++++++++-
1 file changed, 80 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/colorconvert.c b/dlls/winegstreamer/colorconvert.c
index 9a1d2880234..a7660453766 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,80 @@ 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);
+ GUID major_type, subtype;
+ 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)
+ {
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ return S_OK;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (converter->input_type)
+ {
+ IMFMediaType_Release(converter->input_type);
+ converter->input_type = NULL;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return S_OK;
+ }
+
+ 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 (!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;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return hr;
}
static HRESULT WINAPI color_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
@@ -341,6 +416,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. 4, 2020
[PATCH v2 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. 4, 2020
[PATCH v2 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 5ec408eea34..bab2ccce64c 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -454,6 +454,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;
@@ -481,13 +501,25 @@ mfts[] =
audio_converter_supported_types,
NULL
},
+ {
+ &CLSID_CColorConvertDMO,
+ &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. 4, 2020
[PATCH v2 07/17] winegstreamer: Introduce color conversion transform.
by Derek Lesho
Serves as a wrapper of videoconvert, and exposes the CColorConverterDMO MFT interface.
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2: Use existing CColorConverterDMO GUID instead of creating a custom one.
---
dlls/winegstreamer/Makefile.in | 1 +
dlls/winegstreamer/colorconvert.c | 302 +++++++++++++++++++
dlls/winegstreamer/gst_private.h | 1 +
dlls/winegstreamer/mfplat.c | 2 +
dlls/winegstreamer/winegstreamer_classes.idl | 6 +
include/wmcodecdsp.idl | 5 +
6 files changed, 317 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 b2b5b247dac..5ec408eea34 100644
--- a/dlls/winegstreamer/mfplat.c
+++ b/dlls/winegstreamer/mfplat.c
@@ -26,6 +26,7 @@
#include "gst_private.h"
#include "mfapi.h"
#include "mfidl.h"
+#include "wmcodecdsp.h"
#include "wine/debug.h"
#include "wine/heap.h"
@@ -417,6 +418,7 @@ class_objects[] =
{ &CLSID_VideoProcessorMFT, &video_processor_create },
{ &CLSID_GStreamerByteStreamHandler, &winegstreamer_stream_handler_create },
{ &CLSID_WINEAudioConverter, &audio_converter_create },
+ { &CLSID_CColorConvertDMO, &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 { }
diff --git a/include/wmcodecdsp.idl b/include/wmcodecdsp.idl
index 61381bee6d4..87305422332 100644
--- a/include/wmcodecdsp.idl
+++ b/include/wmcodecdsp.idl
@@ -30,3 +30,8 @@ coclass CMP3DecMediaObject {}
uuid(f447b69e-1884-4a7e-8055-346f74d6edb3)
]
coclass CResamplerMediaObject {}
+
+[
+ uuid(98230571-0087-4204-b020-3282538e57d3)
+]
+coclass CColorConvertDMO {}
--
2.29.2
Dec. 4, 2020
[PATCH v2 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>
---
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 4b9f4f92b9a..f22bcfe67e4 100644
--- a/dlls/winegstreamer/audioconvert.c
+++ b/dlls/winegstreamer/audioconvert.c
@@ -495,16 +495,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. 4, 2020
[PATCH v2 05/17] winegstreamer: Semi-stub 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 6f30902f38b..4b9f4f92b9a 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);
}
@@ -155,9 +161,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,
@@ -171,9 +182,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)
@@ -667,6 +683,7 @@ HRESULT audio_converter_create(REFIID riid, void **ret)
{
GstElement *audioconvert, *resampler;
struct audio_converter *object;
+ HRESULT hr;
TRACE("%s %p\n", debugstr_guid(riid), ret);
@@ -679,6 +696,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. 4, 2020
[PATCH v2 04/17] winegstreamer: Implement ::Get(Input/Output)StreamInfo for audio conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2:
- Set MFT_OUTPUT_STREAM_WHOLE_SAMPLES for consistency.
- Set cbSize.
---
dlls/winegstreamer/audioconvert.c | 26 ++++++++++++++++++++++----
1 file changed, 22 insertions(+), 4 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index 8537e87ade3..6f30902f38b 100644
--- a/dlls/winegstreamer/audioconvert.c
+++ b/dlls/winegstreamer/audioconvert.c
@@ -123,16 +123,34 @@ 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;
+ /* TODO: this can be calculated using MFCalculateImageSize */
+ info->cbSize = 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 | MFT_OUTPUT_STREAM_WHOLE_SAMPLES;
+ info->cbAlignment = 0;
+ /* TODO: this can be calculated using MFCalculateImageSize */
+ info->cbSize = 0;
+
+ return S_OK;
}
static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
--
2.29.2
Dec. 4, 2020
[PATCH v2 03/17] winegstreamer: Implement ::Process(Input/Output) for audio conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2:
- Don't store intermediate elements in object structure.
- Reset 'inflight' when I/O types change.
- Cleanup redundant error logging.
- Address nits.
---
dlls/winegstreamer/audioconvert.c | 188 ++++++++++++++++++++++++++++--
dlls/winegstreamer/gst_private.h | 1 +
dlls/winegstreamer/mfplat.c | 69 +++++++++++
3 files changed, 250 insertions(+), 8 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index a79ab616720..8537e87ade3 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, *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);
}
@@ -295,6 +298,9 @@ static HRESULT WINAPI audio_converter_SetInputType(IMFTransform *iface, DWORD id
EnterCriticalSection(&converter->cs);
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
+
if (converter->input_type)
{
IMFMediaType_Release(converter->input_type);
@@ -326,14 +332,17 @@ 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);
return S_OK;
+ }
EnterCriticalSection(&converter->cs);
hr = S_OK;
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
if (!converter->input_type)
hr = MFCreateMediaType(&converter->input_type);
@@ -341,12 +350,18 @@ 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);
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;
@@ -375,6 +390,9 @@ static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD i
EnterCriticalSection(&converter->cs);
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
+
if (converter->output_type)
{
IMFMediaType_Release(converter->output_type);
@@ -406,14 +424,17 @@ 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);
return S_OK;
+ }
EnterCriticalSection(&converter->cs);
hr = S_OK;
+ converter->inflight = FALSE;
+ gst_element_set_state(converter->container, GST_STATE_READY);
if (!converter->output_type)
hr = MFCreateMediaType(&converter->output_type);
@@ -421,12 +442,18 @@ 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);
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;
@@ -490,17 +517,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, (%s)\n", 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 =
@@ -535,6 +647,7 @@ static const IMFTransformVtbl audio_converter_vtbl =
HRESULT audio_converter_create(REFIID riid, void **ret)
{
+ GstElement *audioconvert, *resampler;
struct audio_converter *object;
TRACE("%s %p\n", debugstr_guid(riid), ret);
@@ -548,6 +661,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 (!(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), audioconvert);
+
+ if (!(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), 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, audioconvert))
+ {
+ ERR("Failed to link appsrc to audioconvert\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
+ if (!gst_element_link(audioconvert, resampler))
+ {
+ ERR("Failed to link audioconvert to resampler\n");
+ IMFTransform_Release(&object->IMFTransform_iface);
+ return E_FAIL;
+ }
+
+ if (!gst_element_link(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..b2b5b247dac 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. 4, 2020
[PATCH v2 02/17] winegstreamer: Implement ::SetOutputType for audio conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2: Reorganize function to avoid having a conditionally initialized variable.
---
dlls/winegstreamer/audioconvert.c | 78 ++++++++++++++++++++++++++++++-
1 file changed, 76 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index 4d8a4836bc6..a79ab616720 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;
};
@@ -353,9 +354,82 @@ 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)
+ {
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ return S_OK;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (converter->output_type)
+ {
+ IMFMediaType_Release(converter->output_type);
+ converter->output_type = NULL;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return S_OK;
+ }
+
+ 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 (!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;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return hr;
}
static HRESULT WINAPI audio_converter_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
--
2.29.2
Dec. 4, 2020
[PATCH v2 01/17] winegstreamer: Implement ::SetInputType for audio conversion transform.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
v2: Reorganize function to avoid having a conditionally initialized variable.
---
dlls/winegstreamer/audioconvert.c | 83 ++++++++++++++++++++++++++++++-
1 file changed, 81 insertions(+), 2 deletions(-)
diff --git a/dlls/winegstreamer/audioconvert.c b/dlls/winegstreamer/audioconvert.c
index 9499920347f..4d8a4836bc6 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,80 @@ 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);
+ GUID major_type, subtype;
+ GstCaps *input_caps;
+ DWORD unused;
+ 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)
+ {
+ if (flags & MFT_SET_TYPE_TEST_ONLY)
+ return S_OK;
+
+ EnterCriticalSection(&converter->cs);
+
+ if (converter->input_type)
+ {
+ IMFMediaType_Release(converter->input_type);
+ converter->input_type = NULL;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return S_OK;
+ }
+
+ 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 (!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;
+ }
+
+ LeaveCriticalSection(&converter->cs);
+
+ return hr;
}
static HRESULT WINAPI audio_converter_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
@@ -395,6 +471,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. 4, 2020
[PATCH 11/11] msvcrt: Remove separate long double math funtions.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcr120/msvcr120.spec | 50 ++++-----
dlls/msvcrt/math.c | 195 ------------------------------------
dlls/ucrtbase/ucrtbase.spec | 92 ++++++++---------
3 files changed, 71 insertions(+), 266 deletions(-)
Dec. 4, 2020
[PATCH 10/11] msvcrt: Use _configthreadlocale arguments definition from public header.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcrt/locale.c | 8 ++++----
dlls/msvcrt/msvcrt.h | 3 ---
include/msvcrt/locale.h | 12 ++++++++++++
3 files changed, 16 insertions(+), 7 deletions(-)
Dec. 4, 2020
[PATCH 09/11] msvcrt: Remove non-needed function declarations from msvcrt.h.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcrt/dir.c | 1 +
dlls/msvcrt/exit.c | 1 +
dlls/msvcrt/mbcs.c | 3 ++-
dlls/msvcrt/msvcrt.h | 48 ---------------------------------------
dlls/msvcrt/scanf.c | 1 +
include/msvcrt/mbctype.h | 1 +
include/msvcrt/mbstring.h | 1 +
7 files changed, 7 insertions(+), 49 deletions(-)
Dec. 4, 2020
[PATCH 08/11] msvcrt: Remove non-needed defines from msvcrt.h.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcrt/data.c | 5 +-
dlls/msvcrt/exit.c | 22 ++---
dlls/msvcrt/file.c | 212 +++++++++++++++++++++---------------------
dlls/msvcrt/heap.c | 4 +-
dlls/msvcrt/mbcs.c | 4 +-
dlls/msvcrt/misc.c | 4 +-
dlls/msvcrt/msvcrt.h | 72 --------------
dlls/msvcrt/printf.h | 2 +-
dlls/msvcrt/process.c | 57 ++++++------
dlls/msvcrt/string.c | 6 +-
dlls/msvcrt/time.c | 4 +-
dlls/msvcrt/wcs.c | 18 ++--
12 files changed, 169 insertions(+), 241 deletions(-)
Dec. 4, 2020
[PATCH 07/11] msvcrt: Use _stat64 definition from public header.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcrt/file.c | 4 ++--
dlls/msvcrt/msvcrt.h | 56 --------------------------------------------
2 files changed, 2 insertions(+), 58 deletions(-)
Dec. 4, 2020
[PATCH 06/11] msvcrt: Use _finddata_t definition from public header.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcrt/dir.c | 42 +++++++++++++--------
dlls/msvcrt/msvcrt.h | 88 --------------------------------------------
2 files changed, 27 insertions(+), 103 deletions(-)
Dec. 4, 2020
[PATCH 05/11] include: Add corecrt_io.h header.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
include/msvcrt/corecrt_io.h | 109 ++++++++++++++++++++++++++++++++++++
1 file changed, 109 insertions(+)
create mode 100644 include/msvcrt/corecrt_io.h
Dec. 4, 2020
[PATCH 04/11] msvcrt: Use _JUMP_BUFFER from public header.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcrt/except_arm.c | 3 +-
dlls/msvcrt/except_arm64.c | 3 +-
dlls/msvcrt/except_i386.c | 15 ++++---
dlls/msvcrt/except_x86_64.c | 3 +-
dlls/msvcrt/msvcrt.h | 86 -------------------------------------
5 files changed, 14 insertions(+), 96 deletions(-)
Dec. 4, 2020
[PATCH 03/11] msvcrt: Use _Dcomplex definition from public header.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcrt/math.c | 7 ++++---
dlls/msvcrt/msvcrt.h | 2 --
include/msvcrt/complex.h | 27 +++++++++++++++++++++++++++
3 files changed, 31 insertions(+), 5 deletions(-)
create mode 100644 include/msvcrt/complex.h
Dec. 4, 2020
[PATCH 02/11] msvcrt: Use _purecall_handler from public header.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcrt/exit.c | 8 ++++----
dlls/msvcrt/msvcrt.h | 1 -
include/msvcrt/stdlib.h | 4 ++++
3 files changed, 8 insertions(+), 5 deletions(-)
Dec. 4, 2020
[PATCH 01/11] msvcrt: Use _invalid_parameter_handler from public header.
by Piotr Caban
Signed-off-by: Piotr Caban <piotr(a)codeweavers.com>
---
dlls/msvcrt/errno.c | 18 +++++++++---------
dlls/msvcrt/msvcrt.h | 3 +--
2 files changed, 10 insertions(+), 11 deletions(-)
Dec. 4, 2020
Re: [PATCH] bcrypt: Add initial support for asymmetric keys in BCryptDecrypt().
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
Dec. 4, 2020
[PATCH 4/4] wined3d: Handle GL_APPLE_flush_buffer_range flushing in wined3d_context_gl_unmap_bo_address().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 27 ---------------------------
dlls/wined3d/context_gl.c | 9 +++++++++
2 files changed, 9 insertions(+), 27 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index c752b329a32..6ff6a5b6cd0 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -32,7 +32,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
#define WINED3D_BUFFER_HASDESC 0x01 /* A vertex description has been found. */
#define WINED3D_BUFFER_USE_BO 0x02 /* Use a buffer object for this buffer. */
#define WINED3D_BUFFER_PIN_SYSMEM 0x04 /* Keep a system memory copy for this buffer. */
-#define WINED3D_BUFFER_APPLESYNC 0x10 /* Using sync as in GL_APPLE_flush_buffer_range. */
#define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */
#define VB_RESETDECLCHANGE 1000 /* Reset the decl changecount after that number of draws */
@@ -160,8 +159,6 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu
list_remove(&buffer_gl->bo_user.entry);
wined3d_context_gl_destroy_bo(context_gl, &buffer_gl->bo);
buffer_gl->b.buffer_object = 0;
-
- buffer_gl->b.flags &= ~WINED3D_BUFFER_APPLESYNC;
}
/* Context activation is done by the caller. */
@@ -196,9 +193,6 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
return FALSE;
}
- if (!coherent && gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
- buffer_gl->b.flags |= WINED3D_BUFFER_APPLESYNC;
-
list_init(&buffer_gl->bo_user.entry);
list_add_head(&buffer_gl->bo.users, &buffer_gl->bo_user.entry);
buffer_gl->b.buffer_object = (uintptr_t)bo;
@@ -988,27 +982,6 @@ static HRESULT buffer_resource_sub_resource_unmap(struct wined3d_resource *resou
context = context_acquire(device, NULL, 0);
- if (buffer->flags & WINED3D_BUFFER_APPLESYNC)
- {
- struct wined3d_context_gl *context_gl;
- const struct wined3d_gl_info *gl_info;
- struct wined3d_buffer_gl *buffer_gl;
- unsigned int i;
-
- buffer_gl = wined3d_buffer_gl(buffer);
- context_gl = wined3d_context_gl(context);
- gl_info = context_gl->gl_info;
-
- wined3d_buffer_gl_bind(buffer_gl, context_gl);
- for (i = 0; i < range_count; ++i)
- {
- GL_EXTCALL(glFlushMappedBufferRangeAPPLE(buffer_gl->bo.binding,
- buffer->maps[i].offset, buffer->maps[i].size));
- checkGLcall("glFlushMappedBufferRangeAPPLE");
- }
- range_count = 0;
- }
-
addr.buffer_object = buffer->buffer_object;
addr.addr = 0;
wined3d_context_unmap_bo_address(context, &addr, range_count, buffer->maps);
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index f2f6185ecc6..ea12778e292 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2743,6 +2743,15 @@ void wined3d_context_gl_unmap_bo_address(struct wined3d_context_gl *context_gl,
(UINT_PTR)data->addr + ranges[i].offset, ranges[i].size));
}
}
+ else if (!bo->coherent && gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
+ {
+ for (i = 0; i < range_count; ++i)
+ {
+ GL_EXTCALL(glFlushMappedBufferRangeAPPLE(bo->binding,
+ (uintptr_t)data->addr + ranges[i].offset, ranges[i].size));
+ checkGLcall("glFlushMappedBufferRangeAPPLE");
+ }
+ }
GL_EXTCALL(glUnmapBuffer(bo->binding));
wined3d_context_gl_bind_bo(context_gl, bo->binding, 0);
--
2.20.1
Dec. 4, 2020
[PATCH 3/4] wined3d: Get rid of redundant DISCARD filtering.
by Henri Verbeet
Now that we handle DISCARD maps ourselves, this happens implicitly.
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/buffer.c | 24 ------------------------
1 file changed, 24 deletions(-)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index acedc1a183e..c752b329a32 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -32,7 +32,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(d3d);
#define WINED3D_BUFFER_HASDESC 0x01 /* A vertex description has been found. */
#define WINED3D_BUFFER_USE_BO 0x02 /* Use a buffer object for this buffer. */
#define WINED3D_BUFFER_PIN_SYSMEM 0x04 /* Keep a system memory copy for this buffer. */
-#define WINED3D_BUFFER_DISCARD 0x08 /* A DISCARD lock has occurred since the last preload. */
#define WINED3D_BUFFER_APPLESYNC 0x10 /* Using sync as in GL_APPLE_flush_buffer_range. */
#define VB_MAXDECLCHANGES 100 /* After that number of decl changes we stop converting */
@@ -714,11 +713,6 @@ void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer)
return buffer->resource.parent;
}
-static void buffer_mark_used(struct wined3d_buffer *buffer)
-{
- buffer->flags &= ~WINED3D_BUFFER_DISCARD;
-}
-
/* Context activation is done by the caller. */
void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *context,
const struct wined3d_state *state)
@@ -738,8 +732,6 @@ void wined3d_buffer_load(struct wined3d_buffer *buffer, struct wined3d_context *
WARN("Loading mapped buffer.\n");
}
- buffer_mark_used(buffer);
-
/* TODO: Make converting independent from VBOs */
if (!(buffer->flags & WINED3D_BUFFER_USE_BO))
{
@@ -921,16 +913,6 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
if (count == 1)
{
- /* Filter redundant WINED3D_MAP_DISCARD maps. The 3DMark2001
- * multitexture fill rate test seems to depend on this. When
- * we map a buffer with GL_MAP_INVALIDATE_BUFFER_BIT, the
- * driver is free to discard the previous contents of the
- * buffer. The r600g driver only does this when the buffer is
- * currently in use, while the proprietary NVIDIA driver
- * appears to do this unconditionally. */
- if (buffer->flags & WINED3D_BUFFER_DISCARD)
- flags &= ~WINED3D_MAP_DISCARD;
-
addr.buffer_object = buffer->buffer_object;
addr.addr = 0;
buffer->map_ptr = wined3d_context_map_bo_address(context, &addr, resource->size, flags);
@@ -962,9 +944,6 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
context_release(context);
}
-
- if (flags & WINED3D_MAP_DISCARD)
- buffer->flags |= WINED3D_BUFFER_DISCARD;
}
base = buffer->map_ptr ? buffer->map_ptr : resource->heap_memory;
@@ -1052,9 +1031,6 @@ void wined3d_buffer_copy(struct wined3d_buffer *dst_buffer, unsigned int dst_off
TRACE("dst_buffer %p, dst_offset %u, src_buffer %p, src_offset %u, size %u.\n",
dst_buffer, dst_offset, src_buffer, src_offset, size);
- buffer_mark_used(dst_buffer);
- buffer_mark_used(src_buffer);
-
dst_location = wined3d_buffer_get_memory(dst_buffer, &dst, dst_buffer->locations);
dst.addr += dst_offset;
--
2.20.1
Dec. 4, 2020
[PATCH 2/4] wined3d: Allocate a new bo for busy DISCARD maps.
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_gl.c | 2 +
dlls/wined3d/buffer.c | 26 ------------
dlls/wined3d/context_gl.c | 72 ++++++++++++++++++++++++++++------
dlls/wined3d/resource.c | 5 +--
dlls/wined3d/view.c | 25 +++++++++++-
dlls/wined3d/wined3d_private.h | 9 +++++
6 files changed, 95 insertions(+), 44 deletions(-)
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 4781622d530..b6be5854714 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4867,6 +4867,7 @@ static void adapter_gl_destroy_shader_resource_view(struct wined3d_shader_resour
* the refcount on a device that's in the process of being destroyed. */
if (swapchain_count)
wined3d_device_incref(device);
+ list_remove(&view_gl->bo_user.entry);
wined3d_shader_resource_view_cleanup(&view_gl->v);
wined3d_view_gl_destroy(device, &view_gl->gl_view, NULL, view_gl);
if (swapchain_count)
@@ -4913,6 +4914,7 @@ static void adapter_gl_destroy_unordered_access_view(struct wined3d_unordered_ac
* the refcount on a device that's in the process of being destroyed. */
if (swapchain_count)
wined3d_device_incref(device);
+ list_remove(&view_gl->bo_user.entry);
wined3d_unordered_access_view_cleanup(&view_gl->v);
wined3d_view_gl_destroy(device, &view_gl->gl_view, &view_gl->counter_bo, view_gl);
if (swapchain_count)
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index e179f202cb8..acedc1a183e 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -714,29 +714,6 @@ void * CDECL wined3d_buffer_get_parent(const struct wined3d_buffer *buffer)
return buffer->resource.parent;
}
-/* The caller provides a context and binds the buffer */
-static void wined3d_buffer_gl_sync_apple(struct wined3d_buffer_gl *buffer_gl,
- uint32_t flags, struct wined3d_context_gl *context_gl)
-{
- const struct wined3d_gl_info *gl_info = context_gl->gl_info;
- struct wined3d_bo_gl *bo = &buffer_gl->bo;
-
- /* No fencing needs to be done if the app promises not to overwrite
- * existing data. */
- if (flags & WINED3D_MAP_NOOVERWRITE)
- return;
-
- if (flags & WINED3D_MAP_DISCARD)
- {
- wined3d_buffer_gl_bind(buffer_gl, context_gl);
-
- GL_EXTCALL(glBufferData(bo->binding, buffer_gl->b.resource.size, NULL, bo->usage));
- checkGLcall("glBufferData");
- bo->command_fence_id = 0;
- return;
- }
-}
-
static void buffer_mark_used(struct wined3d_buffer *buffer)
{
buffer->flags &= ~WINED3D_BUFFER_DISCARD;
@@ -954,9 +931,6 @@ static HRESULT buffer_resource_sub_resource_map(struct wined3d_resource *resourc
if (buffer->flags & WINED3D_BUFFER_DISCARD)
flags &= ~WINED3D_MAP_DISCARD;
- if (buffer->flags & WINED3D_BUFFER_APPLESYNC)
- wined3d_buffer_gl_sync_apple(wined3d_buffer_gl(buffer), flags, wined3d_context_gl(context));
-
addr.buffer_object = buffer->buffer_object;
addr.addr = 0;
buffer->map_ptr = wined3d_context_map_bo_address(context, &addr, resource->size, flags);
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 305ca0507ff..f2f6185ecc6 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2650,20 +2650,39 @@ void wined3d_context_gl_submit_command_fence(struct wined3d_context_gl *context_
wined3d_context_gl_poll_fences(context_gl);
}
-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)
+static void *wined3d_bo_gl_map(struct wined3d_bo_gl *bo,
+ struct wined3d_context_gl *context_gl, size_t offset, 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;
+ struct wined3d_bo_user *bo_user;
+ struct wined3d_bo_gl tmp;
+ uint8_t *map_ptr;
- if (!(bo = (struct wined3d_bo_gl *)data->buffer_object))
- return data->addr;
-
- if (flags & (WINED3D_MAP_DISCARD | WINED3D_MAP_NOOVERWRITE))
+ if (flags & WINED3D_MAP_NOOVERWRITE)
goto map;
+ if ((flags & WINED3D_MAP_DISCARD) && bo->command_fence_id > device_gl->completed_fence_id)
+ {
+ if (wined3d_context_gl_create_bo(context_gl, bo->size,
+ bo->binding, bo->usage, bo->coherent, bo->flags, &tmp))
+ {
+ list_move_head(&tmp.users, &bo->users);
+ wined3d_context_gl_destroy_bo(context_gl, bo);
+ *bo = tmp;
+ list_init(&bo->users);
+ list_move_head(&bo->users, &tmp.users);
+ LIST_FOR_EACH_ENTRY(bo_user, &bo->users, struct wined3d_bo_user, entry)
+ {
+ bo_user->valid = false;
+ }
+
+ goto map;
+ }
+
+ ERR("Failed to create new buffer object.\n");
+ }
+
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);
@@ -2674,19 +2693,33 @@ map:
if (gl_info->supported[ARB_MAP_BUFFER_RANGE])
{
- memory = GL_EXTCALL(glMapBufferRange(bo->binding, (INT_PTR)data->addr,
- size, wined3d_resource_gl_map_flags(flags)));
+ map_ptr = GL_EXTCALL(glMapBufferRange(bo->binding, offset, size, wined3d_resource_gl_map_flags(flags)));
}
else
{
- memory = GL_EXTCALL(glMapBuffer(bo->binding, wined3d_resource_gl_legacy_map_flags(flags)));
- memory += (INT_PTR)data->addr;
+ map_ptr = GL_EXTCALL(glMapBuffer(bo->binding, wined3d_resource_gl_legacy_map_flags(flags)));
+ map_ptr += offset;
}
wined3d_context_gl_bind_bo(context_gl, bo->binding, 0);
checkGLcall("Map buffer object");
- return memory;
+ return map_ptr;
+}
+
+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_bo_gl *bo;
+ void *map_ptr;
+
+ if (!(bo = (struct wined3d_bo_gl *)data->buffer_object))
+ return data->addr;
+
+ if (!(map_ptr = wined3d_bo_gl_map(bo, context_gl, (uintptr_t)data->addr, size, flags)))
+ ERR("Failed to map bo.\n");
+
+ return map_ptr;
}
void wined3d_context_gl_unmap_bo_address(struct wined3d_context_gl *context_gl,
@@ -2821,8 +2854,11 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
TRACE("Created buffer object %u.\n", id);
bo->id = id;
+ bo->size = size;
bo->binding = binding;
bo->usage = usage;
+ bo->flags = flags;
+ bo->coherent = coherent;
list_init(&bo->users);
bo->command_fence_id = 0;
@@ -3698,6 +3734,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
const struct wined3d_state *state, unsigned int shader_mask)
{
struct wined3d_shader_sampler_map_entry *entry;
+ struct wined3d_shader_resource_view_gl *srv_gl;
struct wined3d_shader_resource_view *view;
struct wined3d_buffer_gl *buffer_gl;
struct wined3d_shader *shader;
@@ -3735,6 +3772,10 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
buffer_gl = wined3d_buffer_gl(buffer_from_resource(view->resource));
wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+
+ srv_gl = wined3d_shader_resource_view_gl(view);
+ if (!srv_gl->bo_user.valid)
+ wined3d_shader_resource_view_gl_update(srv_gl, context_gl);
}
else
{
@@ -3747,6 +3788,7 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
static void context_gl_load_unordered_access_resources(struct wined3d_context_gl *context_gl,
const struct wined3d_shader *shader, struct wined3d_unordered_access_view * const *views)
{
+ struct wined3d_unordered_access_view_gl *uav_gl;
struct wined3d_unordered_access_view *view;
struct wined3d_buffer_gl *buffer_gl;
struct wined3d_texture *texture;
@@ -3768,6 +3810,10 @@ static void context_gl_load_unordered_access_resources(struct wined3d_context_gl
wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
wined3d_unordered_access_view_invalidate_location(view, ~WINED3D_LOCATION_BUFFER);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+
+ uav_gl = wined3d_unordered_access_view_gl(view);
+ if (!uav_gl->bo_user.valid)
+ wined3d_unordered_access_view_gl_update(uav_gl, context_gl);
}
else
{
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c
index f6e233d8057..2b2088ab771 100644
--- a/dlls/wined3d/resource.c
+++ b/dlls/wined3d/resource.c
@@ -451,12 +451,9 @@ 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))
+ else
ret |= GL_MAP_UNSYNCHRONIZED_BIT;
- if (d3d_flags & WINED3D_MAP_DISCARD)
- ret |= GL_MAP_INVALIDATE_BUFFER_BIT;
-
return ret;
}
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index 1abbbac4fb4..f2c8ceab461 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -268,7 +268,8 @@ static void create_buffer_texture(struct wined3d_gl_view *view, struct wined3d_c
wined3d_buffer_load_location(&buffer_gl->b, &context_gl->c, WINED3D_LOCATION_BUFFER);
view->target = GL_TEXTURE_BUFFER;
- gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
+ if (!view->name)
+ gl_info->gl_ops.gl.p_glGenTextures(1, &view->name);
wined3d_context_gl_bind_texture(context_gl, GL_TEXTURE_BUFFER, view->name);
if (gl_info->supported[ARB_TEXTURE_BUFFER_RANGE])
@@ -916,6 +917,14 @@ void * CDECL wined3d_shader_resource_view_get_parent(const struct wined3d_shader
return view->parent;
}
+void wined3d_shader_resource_view_gl_update(struct wined3d_shader_resource_view_gl *srv_gl,
+ struct wined3d_context_gl *context_gl)
+{
+ create_buffer_view(&srv_gl->gl_view, &context_gl->c, &srv_gl->v.desc,
+ buffer_from_resource(srv_gl->v.resource), srv_gl->v.format);
+ srv_gl->bo_user.valid = true;
+}
+
static void wined3d_shader_resource_view_gl_cs_init(void *object)
{
struct wined3d_shader_resource_view_gl *view_gl = object;
@@ -936,6 +945,8 @@ static void wined3d_shader_resource_view_gl_cs_init(void *object)
context = context_acquire(resource->device, NULL, 0);
create_buffer_view(&view_gl->gl_view, context, desc, buffer, view_format);
+ view_gl->bo_user.valid = true;
+ list_add_head(&wined3d_buffer_gl(buffer)->bo.users, &view_gl->bo_user.entry);
context_release(context);
}
else
@@ -1006,6 +1017,7 @@ HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view
if (FAILED(hr = wined3d_shader_resource_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
return hr;
+ list_init(&view_gl->bo_user.entry);
wined3d_cs_init_object(resource->device->cs, wined3d_shader_resource_view_gl_cs_init, view_gl);
return hr;
@@ -1394,6 +1406,14 @@ void wined3d_unordered_access_view_copy_counter(struct wined3d_unordered_access_
wined3d_buffer_invalidate_location(buffer, ~dst_location);
}
+void wined3d_unordered_access_view_gl_update(struct wined3d_unordered_access_view_gl *uav_gl,
+ struct wined3d_context_gl *context_gl)
+{
+ create_buffer_view(&uav_gl->gl_view, &context_gl->c, &uav_gl->v.desc,
+ buffer_from_resource(uav_gl->v.resource), uav_gl->v.format);
+ uav_gl->bo_user.valid = true;
+}
+
static void wined3d_unordered_access_view_gl_cs_init(void *object)
{
struct wined3d_unordered_access_view_gl *view_gl = object;
@@ -1410,6 +1430,8 @@ static void wined3d_unordered_access_view_gl_cs_init(void *object)
context_gl = wined3d_context_gl(context_acquire(resource->device, NULL, 0));
create_buffer_view(&view_gl->gl_view, &context_gl->c, desc, buffer, view_gl->v.format);
+ view_gl->bo_user.valid = true;
+ list_add_head(&wined3d_buffer_gl(buffer)->bo.users, &view_gl->bo_user.entry);
if (desc->flags & (WINED3D_VIEW_BUFFER_COUNTER | WINED3D_VIEW_BUFFER_APPEND))
{
struct wined3d_bo_gl *bo = &view_gl->counter_bo;
@@ -1470,6 +1492,7 @@ HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_vi
if (FAILED(hr = wined3d_unordered_access_view_init(&view_gl->v, desc, resource, parent, parent_ops)))
return hr;
+ list_init(&view_gl->bo_user.entry);
wined3d_cs_init_object(resource->device->cs, wined3d_unordered_access_view_gl_cs_init, view_gl);
return hr;
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 67a55c4dedd..a82defbbe7f 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1572,9 +1572,12 @@ do { \
struct wined3d_bo_gl
{
GLuint id;
+ GLsizeiptr size;
GLenum binding;
GLenum usage;
+ GLbitfield flags;
+ bool coherent;
struct list users;
uint64_t command_fence_id;
};
@@ -5014,6 +5017,7 @@ void shader_resource_view_generate_mipmaps(struct wined3d_shader_resource_view *
struct wined3d_shader_resource_view_gl
{
struct wined3d_shader_resource_view v;
+ struct wined3d_bo_user bo_user;
struct wined3d_gl_view gl_view;
};
@@ -5028,6 +5032,8 @@ void wined3d_shader_resource_view_gl_bind(struct wined3d_shader_resource_view_gl
HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view_gl *view_gl,
const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+void wined3d_shader_resource_view_gl_update(struct wined3d_shader_resource_view_gl *srv_gl,
+ struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
struct wined3d_view_vk
{
@@ -5083,6 +5089,7 @@ void wined3d_unordered_access_view_set_counter(struct wined3d_unordered_access_v
struct wined3d_unordered_access_view_gl
{
struct wined3d_unordered_access_view v;
+ struct wined3d_bo_user bo_user;
struct wined3d_gl_view gl_view;
struct wined3d_bo_gl counter_bo;
};
@@ -5098,6 +5105,8 @@ void wined3d_unordered_access_view_gl_clear_uint(struct wined3d_unordered_access
HRESULT wined3d_unordered_access_view_gl_init(struct wined3d_unordered_access_view_gl *view_gl,
const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+void wined3d_unordered_access_view_gl_update(struct wined3d_unordered_access_view_gl *uav_gl,
+ struct wined3d_context_gl *context_gl) DECLSPEC_HIDDEN;
struct wined3d_unordered_access_view_vk
{
--
2.20.1
Dec. 4, 2020
[PATCH 1/4] wined3d: Use the "bo user" mechanism to invalidate existing bindings in wined3d_buffer_gl_destroy_buffer_object().
by Henri Verbeet
Signed-off-by: Henri Verbeet <hverbeet(a)codeweavers.com>
---
dlls/wined3d/adapter_vk.c | 6 ++---
dlls/wined3d/buffer.c | 47 +++++++++-------------------------
dlls/wined3d/context_gl.c | 20 ++++++++++++---
dlls/wined3d/state.c | 36 ++++++++++++++++++--------
dlls/wined3d/wined3d_private.h | 8 +++---
5 files changed, 62 insertions(+), 55 deletions(-)
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 3fb9e4ce4b4..3da1615b1b5 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -860,10 +860,10 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
{
struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
const struct wined3d_vk_info *vk_info;
- struct wined3d_bo_user_vk *bo_user_vk;
struct wined3d_device_vk *device_vk;
VkCommandBuffer vk_command_buffer;
VkBufferMemoryBarrier vk_barrier;
+ struct wined3d_bo_user *bo_user;
struct wined3d_bo_vk *bo, tmp;
VkMappedMemoryRange range;
void *map_ptr;
@@ -886,9 +886,9 @@ static void *adapter_vk_map_bo_address(struct wined3d_context *context,
*bo = tmp;
list_init(&bo->users);
list_move_head(&bo->users, &tmp.users);
- LIST_FOR_EACH_ENTRY(bo_user_vk, &bo->users, struct wined3d_bo_user_vk, entry)
+ LIST_FOR_EACH_ENTRY(bo_user, &bo->users, struct wined3d_bo_user, entry)
{
- bo_user_vk->valid = false;
+ bo_user->valid = false;
}
goto map;
diff --git a/dlls/wined3d/buffer.c b/dlls/wined3d/buffer.c
index 5dbc66449f4..e179f202cb8 100644
--- a/dlls/wined3d/buffer.c
+++ b/dlls/wined3d/buffer.c
@@ -143,47 +143,22 @@ static void wined3d_buffer_gl_destroy_buffer_object(struct wined3d_buffer_gl *bu
struct wined3d_context_gl *context_gl)
{
struct wined3d_resource *resource = &buffer_gl->b.resource;
- struct wined3d_buffer *buffer = &buffer_gl->b;
- struct wined3d_cs *cs = resource->device->cs;
if (!buffer_gl->b.buffer_object)
return;
- /* The stream source state handler might have read the memory of the
- * vertex buffer already and got the memory in the vbo which is not
- * valid any longer. Dirtify the stream source to force a reload. This
- * happens only once per changed vertexbuffer and should occur rather
- * rarely. */
- if (resource->bind_count)
- {
- if (resource->bind_flags & WINED3D_BIND_VERTEX_BUFFER)
- device_invalidate_state(resource->device, STATE_STREAMSRC);
- if (resource->bind_flags & WINED3D_BIND_INDEX_BUFFER
- && cs->state.index_buffer == buffer)
- device_invalidate_state(resource->device, STATE_INDEXBUFFER);
- if (resource->bind_flags & WINED3D_BIND_CONSTANT_BUFFER)
- {
- device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_VERTEX));
- device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_HULL));
- device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_DOMAIN));
- device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_GEOMETRY));
- device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_PIXEL));
- device_invalidate_state(resource->device, STATE_CONSTANT_BUFFER(WINED3D_SHADER_TYPE_COMPUTE));
- }
- if (resource->bind_flags & WINED3D_BIND_STREAM_OUTPUT)
- {
- device_invalidate_state(resource->device, STATE_STREAM_OUTPUT);
- if (context_gl->c.transform_feedback_active)
- {
- /* We have to make sure that transform feedback is not active
- * when deleting a potentially bound transform feedback buffer.
- * This may happen when the device is being destroyed. */
- WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer_gl);
- wined3d_context_gl_end_transform_feedback(context_gl);
- }
- }
+ if (context_gl->c.transform_feedback_active && resource->bind_count
+ && resource->bind_flags & WINED3D_BIND_STREAM_OUTPUT)
+ {
+ /* We have to make sure that transform feedback is not active
+ * when deleting a potentially bound transform feedback buffer.
+ * This may happen when the device is being destroyed. */
+ WARN("Deleting buffer object for buffer %p, disabling transform feedback.\n", buffer_gl);
+ wined3d_context_gl_end_transform_feedback(context_gl);
}
+ buffer_gl->bo_user.valid = false;
+ list_remove(&buffer_gl->bo_user.entry);
wined3d_context_gl_destroy_bo(context_gl, &buffer_gl->bo);
buffer_gl->b.buffer_object = 0;
@@ -225,6 +200,8 @@ static BOOL wined3d_buffer_gl_create_buffer_object(struct wined3d_buffer_gl *buf
if (!coherent && gl_info->supported[APPLE_FLUSH_BUFFER_RANGE])
buffer_gl->b.flags |= WINED3D_BUFFER_APPLESYNC;
+ list_init(&buffer_gl->bo_user.entry);
+ list_add_head(&buffer_gl->bo.users, &buffer_gl->bo_user.entry);
buffer_gl->b.buffer_object = (uintptr_t)bo;
buffer_invalidate_bo_range(&buffer_gl->b, 0, 0);
diff --git a/dlls/wined3d/context_gl.c b/dlls/wined3d/context_gl.c
index 406b325cda8..305ca0507ff 100644
--- a/dlls/wined3d/context_gl.c
+++ b/dlls/wined3d/context_gl.c
@@ -2823,6 +2823,7 @@ bool wined3d_context_gl_create_bo(struct wined3d_context_gl *context_gl, GLsizei
bo->id = id;
bo->binding = binding;
bo->usage = usage;
+ list_init(&bo->users);
bo->command_fence_id = 0;
return true;
@@ -3718,6 +3719,8 @@ static void context_gl_load_shader_resources(struct wined3d_context_gl *context_
buffer_gl = wined3d_buffer_gl(state->cb[i][j]);
wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ if (!buffer_gl->bo_user.valid)
+ device_invalidate_state(context_gl->c.device, STATE_CONSTANT_BUFFER(i));
}
for (j = 0; j < shader->reg_maps.sampler_map.count; ++j)
@@ -3793,6 +3796,8 @@ static void context_gl_load_stream_output_buffers(struct wined3d_context_gl *con
wined3d_buffer_load(&buffer_gl->b, &context_gl->c, state);
wined3d_buffer_invalidate_location(&buffer_gl->b, ~WINED3D_LOCATION_BUFFER);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
+ if (!buffer_gl->bo_user.valid)
+ device_invalidate_state(context_gl->c.device, STATE_STREAM_OUTPUT);
}
}
@@ -3848,7 +3853,10 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
e = &context->stream_info.elements[wined3d_bit_scan(&map)];
buffer_gl = wined3d_buffer_gl(state->streams[e->stream_idx].buffer);
- wined3d_buffer_load(&buffer_gl->b, context, state);
+ if (!buffer_gl->bo_user.valid)
+ device_invalidate_state(device, STATE_STREAMSRC);
+ else
+ wined3d_buffer_load(&buffer_gl->b, context, state);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
}
/* Loading the buffers above may have invalidated the stream info. */
@@ -3862,6 +3870,8 @@ static BOOL context_apply_draw_state(struct wined3d_context *context,
if (context->stream_info.all_vbo)
{
wined3d_buffer_load(&buffer_gl->b, context, state);
+ if (!buffer_gl->bo_user.valid)
+ device_invalidate_state(device, STATE_INDEXBUFFER);
wined3d_context_gl_reference_bo(context_gl, &buffer_gl->bo);
}
else
@@ -4989,6 +4999,7 @@ void wined3d_context_gl_load_tex_coords(const struct wined3d_context_gl *context
gl_info->gl_ops.gl.p_glTexCoordPointer(format_gl->vtx_format, format_gl->vtx_type, e->stride,
e->data.addr + state->load_base_vertex_index * e->stride);
gl_info->gl_ops.gl.p_glEnableClientState(GL_TEXTURE_COORD_ARRAY);
+ wined3d_buffer_gl(state->streams[e->stream_idx].buffer)->bo_user.valid = true;
}
else
{
@@ -5077,6 +5088,7 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte
checkGLcall("glVertexPointer(...)");
gl_info->gl_ops.gl.p_glEnableClientState(GL_VERTEX_ARRAY);
checkGLcall("glEnableClientState(GL_VERTEX_ARRAY)");
+ wined3d_buffer_gl(state->streams[e->stream_idx].buffer)->bo_user.valid = true;
}
/* Normals */
@@ -5100,7 +5112,7 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte
checkGLcall("glNormalPointer(...)");
gl_info->gl_ops.gl.p_glEnableClientState(GL_NORMAL_ARRAY);
checkGLcall("glEnableClientState(GL_NORMAL_ARRAY)");
-
+ wined3d_buffer_gl(state->streams[e->stream_idx].buffer)->bo_user.valid = true;
}
else
{
@@ -5130,7 +5142,7 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte
checkGLcall("glColorPointer(4, GL_UNSIGNED_BYTE, ...)");
gl_info->gl_ops.gl.p_glEnableClientState(GL_COLOR_ARRAY);
checkGLcall("glEnableClientState(GL_COLOR_ARRAY)");
-
+ wined3d_buffer_gl(state->streams[e->stream_idx].buffer)->bo_user.valid = true;
}
else
{
@@ -5199,6 +5211,7 @@ static void wined3d_context_gl_load_vertex_data(struct wined3d_context_gl *conte
}
gl_info->gl_ops.gl.p_glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT);
checkGLcall("glEnableClientState(GL_SECONDARY_COLOR_ARRAY_EXT)");
+ wined3d_buffer_gl(state->streams[e->stream_idx].buffer)->bo_user.valid = true;
}
else
{
@@ -5292,6 +5305,7 @@ static void wined3d_context_gl_load_numbered_arrays(struct wined3d_context_gl *c
format_gl = wined3d_format_gl(element->format);
stream = &state->streams[element->stream_idx];
+ wined3d_buffer_gl(stream->buffer)->bo_user.valid = true;
if ((stream->flags & WINED3DSTREAMSOURCE_INSTANCEDATA) && !context->instance_count)
context->instance_count = state->streams[0].frequency;
diff --git a/dlls/wined3d/state.c b/dlls/wined3d/state.c
index 71f7ac53a2f..e40c23daf03 100644
--- a/dlls/wined3d/state.c
+++ b/dlls/wined3d/state.c
@@ -4452,12 +4452,17 @@ static void indexbuffer(struct wined3d_context *context, const struct wined3d_st
{
const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
const struct wined3d_stream_info *stream_info = &context->stream_info;
- const struct wined3d_buffer *ib = state->index_buffer;
+ struct wined3d_buffer_gl *buffer_gl;
- if (!ib || !stream_info->all_vbo)
+ if (!state->index_buffer || !stream_info->all_vbo)
+ {
GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0));
- else
- GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, wined3d_buffer_gl_const(ib)->bo.id));
+ return;
+ }
+
+ buffer_gl = wined3d_buffer_gl(state->index_buffer);
+ GL_EXTCALL(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffer_gl->bo.id));
+ buffer_gl->bo_user.valid = true;
}
static void depth_clip(const struct wined3d_rasterizer_state *r, const struct wined3d_gl_info *gl_info)
@@ -4550,7 +4555,7 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state
{
const struct wined3d_gl_info *gl_info = wined3d_context_gl(context)->gl_info;
enum wined3d_shader_type shader_type;
- struct wined3d_buffer *buffer;
+ struct wined3d_buffer_gl *buffer_gl;
unsigned int i, base, count;
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
@@ -4563,8 +4568,15 @@ static void state_cb(struct wined3d_context *context, const struct wined3d_state
wined3d_gl_limits_get_uniform_block_range(&gl_info->limits, shader_type, &base, &count);
for (i = 0; i < count; ++i)
{
- buffer = state->cb[shader_type][i];
- GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, buffer ? wined3d_buffer_gl(buffer)->bo.id : 0));
+ if (!state->cb[shader_type][i])
+ {
+ GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, 0));
+ continue;
+ }
+
+ buffer_gl = wined3d_buffer_gl(state->cb[shader_type][i]);
+ GL_EXTCALL(glBindBufferBase(GL_UNIFORM_BUFFER, base + i, buffer_gl->bo.id));
+ buffer_gl->bo_user.valid = true;
}
checkGLcall("bind constant buffers");
}
@@ -4614,7 +4626,7 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
{
struct wined3d_context_gl *context_gl = wined3d_context_gl(context);
const struct wined3d_gl_info *gl_info = context_gl->gl_info;
- struct wined3d_buffer *buffer;
+ struct wined3d_buffer_gl *buffer_gl;
unsigned int offset, size, i;
TRACE("context %p, state %p, state_id %#x.\n", context, state, state_id);
@@ -4623,20 +4635,22 @@ static void state_so(struct wined3d_context *context, const struct wined3d_state
for (i = 0; i < ARRAY_SIZE(state->stream_output); ++i)
{
- if (!(buffer = state->stream_output[i].buffer))
+ if (!state->stream_output[i].buffer)
{
GL_EXTCALL(glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, i, 0));
continue;
}
+ buffer_gl = wined3d_buffer_gl(state->stream_output[i].buffer);
offset = state->stream_output[i].offset;
if (offset == ~0u)
{
FIXME("Appending to stream output buffers not implemented.\n");
offset = 0;
}
- size = buffer->resource.size - offset;
- GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, wined3d_buffer_gl(buffer)->bo.id, offset, size));
+ size = buffer_gl->b.resource.size - offset;
+ GL_EXTCALL(glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, i, buffer_gl->bo.id, offset, size));
+ buffer_gl->bo_user.valid = true;
}
checkGLcall("bind transform feedback buffers");
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 67caf98ead7..67a55c4dedd 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1575,6 +1575,7 @@ struct wined3d_bo_gl
GLenum binding;
GLenum usage;
+ struct list users;
uint64_t command_fence_id;
};
@@ -1583,7 +1584,7 @@ static inline GLuint wined3d_bo_gl_id(uintptr_t bo)
return bo ? ((struct wined3d_bo_gl *)bo)->id : 0;
}
-struct wined3d_bo_user_vk
+struct wined3d_bo_user
{
struct list entry;
bool valid;
@@ -4875,6 +4876,7 @@ struct wined3d_buffer_gl
struct wined3d_buffer b;
struct wined3d_bo_gl bo;
+ struct wined3d_bo_user bo_user;
};
static inline struct wined3d_buffer_gl *wined3d_buffer_gl(struct wined3d_buffer *buffer)
@@ -4898,7 +4900,7 @@ struct wined3d_buffer_vk
struct wined3d_buffer b;
struct wined3d_bo_vk bo;
- struct wined3d_bo_user_vk bo_user;
+ struct wined3d_bo_user bo_user;
VkDescriptorBufferInfo buffer_info;
};
@@ -5029,7 +5031,7 @@ HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view
struct wined3d_view_vk
{
- struct wined3d_bo_user_vk bo_user;
+ struct wined3d_bo_user bo_user;
union
{
VkBufferView vk_buffer_view;
--
2.20.1
Dec. 4, 2020
Re: Wine staging 5.19 release
by Gerald Pfeifer
On Sat, 24 Oct 2020, Gerald Pfeifer wrote:
> Here is a patch on top (of the Wine Staging patchset) that is required.
>
> Can you please include that? Thank you!
Thanks to (I believe Zebediah) for addressing those issues!
I have to confess there is one snippet I missed. With the additional
patch below Wine 5.22 + Staging patchset builds on FreeBSD 11 out of
the box.
Thank you for considering that; for now I'm carrying it as part of
the FreeBSD emulators/wine-devel port.
Gerald
--- dlls/ntdll/unix/file.c.orig 2020-11-07 09:33:27.083812000 +0000
+++ dlls/ntdll/unix/file.c 2020-11-07 09:53:55.641522000 +0000
@@ -394,6 +394,18 @@
#define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1)
#endif
+#ifdef HAVE_SYS_EXTATTR_H
+static inline int xattr_valid_namespace( const char *name )
+{
+ if (strncmp( XATTR_USER_PREFIX, name, XATTR_USER_PREFIX_LEN ) != 0)
+ {
+ errno = EPERM;
+ return 0;
+ }
+ return 1;
+}
+#endif
+
static int xattr_fremove( int filedes, const char *name )
{
#if defined(XATTR_ADDITIONAL_OPTIONS)
Dec. 4, 2020
[PATCH] bcrypt: Add initial support for asymmetric keys in BCryptDecrypt().
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/bcrypt/bcrypt_internal.h | 1 +
dlls/bcrypt/bcrypt_main.c | 22 ++++++++++++++++--
dlls/bcrypt/gnutls.c | 43 +++++++++++++++++++++++++++++++++++
dlls/bcrypt/macos.c | 8 +++++++
4 files changed, 72 insertions(+), 2 deletions(-)
diff --git a/dlls/bcrypt/bcrypt_internal.h b/dlls/bcrypt/bcrypt_internal.h
index e1777ed130b..eb136111509 100644
--- a/dlls/bcrypt/bcrypt_internal.h
+++ b/dlls/bcrypt/bcrypt_internal.h
@@ -206,6 +206,7 @@ struct key_funcs
void (CDECL *key_symmetric_destroy)( struct key * );
NTSTATUS (CDECL *key_asymmetric_init)( struct key * );
NTSTATUS (CDECL *key_asymmetric_generate)( struct key * );
+ NTSTATUS (CDECL *key_asymmetric_decrypt)( struct key *, UCHAR *, ULONG, UCHAR *, ULONG * );
NTSTATUS (CDECL *key_asymmetric_duplicate)( struct key *, struct key * );
NTSTATUS (CDECL *key_asymmetric_sign)( struct key *, void *, UCHAR *, ULONG, UCHAR *, ULONG, ULONG *, ULONG );
NTSTATUS (CDECL *key_asymmetric_verify)( struct key *, void *, UCHAR *, ULONG, UCHAR *, ULONG, DWORD );
diff --git a/dlls/bcrypt/bcrypt_main.c b/dlls/bcrypt/bcrypt_main.c
index 591c01c710c..a1423dcd836 100644
--- a/dlls/bcrypt/bcrypt_main.c
+++ b/dlls/bcrypt/bcrypt_main.c
@@ -1160,8 +1160,8 @@ static NTSTATUS key_encrypt( struct key *key, UCHAR *input, ULONG input_len, vo
return status;
}
-static NTSTATUS key_decrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
- ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
+static NTSTATUS key_symmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
+ ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
{
ULONG bytes_left = input_len;
UCHAR *buf, *src, *dst;
@@ -1240,6 +1240,24 @@ static NTSTATUS key_decrypt( struct key *key, UCHAR *input, ULONG input_len, voi
return status;
}
+static NTSTATUS key_asymmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len, UCHAR *output,
+ ULONG output_len, ULONG *ret_len )
+{
+ NTSTATUS status;
+
+ if (!(status = key_funcs->key_asymmetric_decrypt( key, input, input_len, output, &output_len )))
+ *ret_len = output_len;
+
+ return status;
+}
+
+static NTSTATUS key_decrypt( struct key *key, UCHAR *input, ULONG input_len, void *padding, UCHAR *iv,
+ ULONG iv_len, UCHAR *output, ULONG output_len, ULONG *ret_len, ULONG flags )
+{
+ return key_is_symmetric( key ) ? key_symmetric_decrypt( key, input, input_len, padding, iv, iv_len,
+ output, output_len, ret_len, flags ) : key_asymmetric_decrypt( key, input, input_len, output, output_len, ret_len );
+}
+
static NTSTATUS key_import_pair( struct algorithm *alg, const WCHAR *type, BCRYPT_KEY_HANDLE *ret_key, UCHAR *input,
ULONG input_len )
{
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 162ac9ea732..c065ac31fba 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -109,6 +109,7 @@ static int (*pgnutls_privkey_generate)(gnutls_privkey_t, gnutls_pk_algorithm_t,
static int (*pgnutls_privkey_import_rsa_raw)(gnutls_privkey_t, const gnutls_datum_t *, const gnutls_datum_t *,
const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *,
const gnutls_datum_t *, const gnutls_datum_t *, const gnutls_datum_t *);
+static int (*pgnutls_privkey_decrypt_data)(gnutls_privkey_t, unsigned int flags, const gnutls_datum_t *, gnutls_datum_t *);
/* Not present in gnutls version < 3.6.0 */
static int (*pgnutls_decode_rs_value)(const gnutls_datum_t *, gnutls_datum_t *, gnutls_datum_t *);
@@ -124,6 +125,7 @@ MAKE_FUNCPTR(gnutls_global_init);
MAKE_FUNCPTR(gnutls_global_set_log_function);
MAKE_FUNCPTR(gnutls_global_set_log_level);
MAKE_FUNCPTR(gnutls_perror);
+MAKE_FUNCPTR(gnutls_privkey_decrypt_data);
MAKE_FUNCPTR(gnutls_privkey_deinit);
MAKE_FUNCPTR(gnutls_privkey_import_dsa_raw);
MAKE_FUNCPTR(gnutls_privkey_init);
@@ -215,6 +217,12 @@ static int compat_gnutls_privkey_import_rsa_raw(gnutls_privkey_t key, const gnut
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
}
+static int compat_gnutls_privkey_decrypt_data(gnutls_privkey_t key, unsigned int flags, const gnutls_datum_t *cipher_text,
+ gnutls_datum_t *plain_text)
+{
+ return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
+}
+
static void gnutls_log( int level, const char *msg )
{
TRACE( "<%d> %s", level, msg );
@@ -341,6 +349,11 @@ static BOOL gnutls_initialize(void)
WARN("gnutls_privkey_import_rsa_raw not found\n");
pgnutls_privkey_import_rsa_raw = compat_gnutls_privkey_import_rsa_raw;
}
+ if (!(pgnutls_privkey_decrypt_data = dlsym( libgnutls_handle, "gnutls_privkey_decrypt_data" )))
+ {
+ WARN("gnutls_privkey_decrypt_data not found\n");
+ pgnutls_privkey_decrypt_data = compat_gnutls_privkey_decrypt_data;
+ }
if (TRACE_ON( bcrypt ))
{
@@ -1883,6 +1896,35 @@ static NTSTATUS CDECL key_asymmetric_duplicate( struct key *key_orig, struct key
return STATUS_SUCCESS;
}
+static NTSTATUS CDECL key_asymmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len,
+ UCHAR *output, ULONG *output_len )
+{
+ gnutls_datum_t e, d = { 0 };
+ NTSTATUS status = STATUS_SUCCESS;
+ int ret;
+
+ e.data = (unsigned char *)input;
+ e.size = input_len;
+
+ if ((ret = pgnutls_privkey_decrypt_data( key_data(key)->privkey, 0, &e, &d )))
+ {
+ pgnutls_perror( ret );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ if (*output_len >= d.size)
+ {
+ *output_len = d.size;
+ memcpy( output, d.data, *output_len );
+ }
+ else
+ status = STATUS_BUFFER_TOO_SMALL;
+
+ free( d.data );
+
+ return status;
+}
+
static const struct key_funcs key_funcs =
{
key_set_property,
@@ -1895,6 +1937,7 @@ static const struct key_funcs key_funcs =
key_symmetric_destroy,
key_asymmetric_init,
key_asymmetric_generate,
+ key_asymmetric_decrypt,
key_asymmetric_duplicate,
key_asymmetric_sign,
key_asymmetric_verify,
diff --git a/dlls/bcrypt/macos.c b/dlls/bcrypt/macos.c
index 57edc3e262b..44906519cef 100644
--- a/dlls/bcrypt/macos.c
+++ b/dlls/bcrypt/macos.c
@@ -271,6 +271,13 @@ static NTSTATUS CDECL key_asymmetric_duplicate( struct key *key_orig, struct key
return STATUS_NOT_IMPLEMENTED;
}
+static NTSTATUS CDECL key_asymmetric_decrypt( struct key *key, UCHAR *input, ULONG input_len,
+ UCHAR *output, ULONG *output_len )
+{
+ FIXME( "not implemented on Mac\n" );
+ return STATUS_NOT_IMPLEMENTED;
+}
+
static const struct key_funcs key_funcs =
{
key_set_property,
@@ -283,6 +290,7 @@ static const struct key_funcs key_funcs =
key_symmetric_destroy,
key_asymmetric_init,
key_asymmetric_generate,
+ key_asymmetric_decrypt,
key_asymmetric_duplicate,
key_asymmetric_sign,
key_asymmetric_verify,
--
2.29.2
Dec. 4, 2020
[PATCH 2/2] quartz/vmr9: Allow the aspect ratio parameters to be NULL in IVMRWindowlessControl::GetNativeVideoSize().
by Akihiro Sagawa
Please refer to the commit 45789e00dad69a2609b6a104b71731fe483428b0 which
fixes IVMRWindowlessControl9::GetNativeVideoSize().
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/quartz/tests/vmr7.c | 6 +++---
dlls/quartz/vmr9.c | 24 ++++++++++++------------
2 files changed, 15 insertions(+), 15 deletions(-)
Dec. 4, 2020
[PATCH 1/2] quartz/tests: Add some tests for VMR7 windowless video size.
by Akihiro Sagawa
This is a port of VMR9 commit fd159a356345d71d96d158e9a87bd8e4ec1a699d.
Signed-off-by: Akihiro Sagawa <sagawa.aki(a)gmail.com>
---
dlls/quartz/tests/vmr7.c | 134 ++++++++++++++++++++++++++++++++++++++-
1 file changed, 133 insertions(+), 1 deletion(-)
Dec. 4, 2020
Dec. 4, 2020
Re: [PATCH] localspl: Use wide-char string literals.
by Huw Davies
Signed-off-by: Huw Davies <huw(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH] ntdll/sec: Add RtlDefaultNpAcl stub.
by Biswapriyo Nath
Any comment on this patch to improve?
Dec. 4, 2020
Re: [PATCH vkd3d v2 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=83096
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. 4, 2020
Re: [PATCH vkd3d v2 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=83095
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. 4, 2020
Re: [PATCH vkd3d v2 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=83094
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. 4, 2020
Re: [PATCH vkd3d v2 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=83093
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. 4, 2020
Re: [PATCH vkd3d v2 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=83092
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. 4, 2020
[PATCH vkd3d v2 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. 4, 2020
[PATCH vkd3d v2 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. 4, 2020
[PATCH vkd3d v2 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. 4, 2020
[PATCH vkd3d v2 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. 4, 2020
[PATCH vkd3d v2 1/5] vkd3d-shader: Implement an initial pass-through HLSL preprocessor.
by Zebediah Figura
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
v2: quote some autoconf macros, use AS_IF, try to fix out-of-tree builds
.gitignore | 3 +
Makefile.am | 25 +++++-
configure.ac | 6 ++
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, 260 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..46eacbd9 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -108,6 +108,29 @@ 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 =
+
+libs/vkd3d-shader/preproc.yy.c: libs/vkd3d-shader/preproc.l
+ $(VKD3D_V_FLEX)$(FLEX) $(LFLAGS) -o $@ $<
+
+libs/vkd3d-shader/preproc.tab.c libs/vkd3d-shader/preproc.tab.h &: libs/vkd3d-shader/preproc.y
+ $(VKD3D_V_BISON)$(BISON) $(YFLAGS) -d -o $@ $<
+
+BUILT_SOURCES += libs/vkd3d-shader/preproc.tab.h
+
+nodist_libvkd3d_shader_la_SOURCES = \
+ libs/vkd3d-shader/preproc.tab.c \
+ libs/vkd3d-shader/preproc.tab.h \
+ libs/vkd3d-shader/preproc.yy.c
+
libvkd3d_shader_la_SOURCES = \
include/private/list.h \
include/private/rbtree.h \
@@ -122,7 +145,7 @@ libvkd3d_shader_la_SOURCES = \
libs/vkd3d-shader/vkd3d_shader.map \
libs/vkd3d-shader/vkd3d_shader_main.c \
libs/vkd3d-shader/vkd3d_shader_private.h
-libvkd3d_shader_la_CFLAGS = $(AM_CFLAGS) @SPIRV_TOOLS_CFLAGS@
+libvkd3d_shader_la_CFLAGS = $(AM_CFLAGS) -I$(srcdir)/libs/vkd3d-shader @SPIRV_TOOLS_CFLAGS@
libvkd3d_shader_la_LDFLAGS = $(AM_LDFLAGS) -version-info 1:0:0
libvkd3d_shader_la_LIBADD = libvkd3d-common.la @SPIRV_TOOLS_LIBS@
if HAVE_LD_VERSION_SCRIPT
diff --git a/configure.ac b/configure.ac
index 2f22b05f..b7902b63 100644
--- a/configure.ac
+++ b/configure.ac
@@ -30,6 +30,12 @@ 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])
+AS_IF([test "$FLEX" = "none"], [AC_MSG_ERROR([no suitable flex found. Please install the 'flex' package.])])
+
+AC_CHECK_PROGS([BISON], [bison], [none])
+AS_IF([test "$BISON" = "none"], [AC_MSG_ERROR([no suitable bison found. Please install the 'bison' package.])])
+
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. 4, 2020
Re: [PATCH 2/2] xmllite: Drop superfluous casts to self.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 1/2] xmllite: Use a string literal for an empty string.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH] mfplat: Zero-initialize the device manager object.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 07/17] winegstreamer: Introduce color conversion transform.
by Derek Lesho
On 12/3/20 10:40 PM, Zebediah Figura (she/her) wrote:
> On 12/3/20 3:55 PM, Derek Lesho wrote:
>> Serves as a wrapper of videoconvert, and roughly fills the roll of Windows' CColorConverterDMO.
> Why can't this be CColorConvertDMO?
Nothing specific, I don't think there's any fundamental differences here
to what a CColorConvertDMO implementation would like. While I haven't
tested any applications that manually use CColorConvertDMO, I don't
think we'd run into any problems with incompatibility if/when they come up.
Dec. 4, 2020
Re: [PATCH 03/17] winegstreamer: Implement ::Process(Input/Output) for audio conversion transform.
by Derek Lesho
On 12/3/20 10:26 PM, Zebediah Figura (she/her) wrote:
>
>> + g_signal_emit_by_name(converter->appsink, "pull-sample", &sample);
> I'm not fully familiar with mfplat, but this call may block, and it
> doesn't look like ProcessOutput() is supposed to. You probably want
> "try-pull-sample" instead.
Actually, with sync MFTs, ::ProcessOutput is blocking until a sample is
yielded or an error occurs. In MFT writing guides from Microsoft I've
seen, ::ProcessInput just buts the data in a buffer, and ::ProcessOutput
actually invokes the functionality of the transform. This should match
that behavior pretty closely.
Dec. 4, 2020
Re: [PATCH 07/17] winegstreamer: Introduce color conversion transform.
by Zebediah Figura (she/her)
On 12/3/20 3:55 PM, Derek Lesho wrote:
> Serves as a wrapper of videoconvert, and roughly fills the roll of Windows' CColorConverterDMO.
Why can't this be CColorConvertDMO?
>
> 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}};
> +
This can be const...
> 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 { }
>
Dec. 4, 2020
Re: [PATCH 06/17] winegstreamer: Implement Get(Input/Output)CurrentType functions for audio converter transform.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 05/17] winegstreamer: Implement Get*Attributes functions for audio converter transform.
by Zebediah Figura (she/her)
On 12/3/20 3:55 PM, Derek Lesho wrote:
> Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
> ---
> dlls/winegstreamer/audioconvert.c | 37 +++++++++++++++++++++++++++----
> 1 file changed, 33 insertions(+), 4 deletions(-)
>
The patch subject is mildly misleading, since you don't implement all
such functions...
> 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)))
>
Dec. 4, 2020
Re: [PATCH 04/17] winegstreamer: Implement ::Get(Input/Output)StreamInfo for audio conversion transform.
by Zebediah Figura (she/her)
On 12/3/20 3:55 PM, Derek Lesho wrote:
> 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;
> +
"info->cbSize" isn't set here; is that intentional?
> + 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;
Is it intentional to provide WHOLE_SAMPLES in GetInputStreamInfo() but
not (the equivalent flag) here?
> + info->cbSize = 0;
> + info->cbAlignment = 0;
> +
> + return S_OK;
> }
>
> static HRESULT WINAPI audio_converter_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
>
Dec. 4, 2020
Re: [PATCH 03/17] winegstreamer: Implement ::Process(Input/Output) for audio conversion transform.
by Zebediah Figura (she/her)
On 12/3/20 3:55 PM, Derek Lesho wrote:
> 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;
Both "resampler" and "audioconvert" can be local variables, I think.
> };
>
> 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);
Presumably you also want to reset "inflight" here...
>
> 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);
This is something of a style nitpick, but having variables that are
conditionally valid like this is often better avoided. Reorganizing the
function to be something more like
if (CLEAR)
{
if (TEST_ONLY)
return;
EnterCriticalSection();
// clear
LeaveCriticalSection();
return;
}
// validate
// convert to caps
if (TEST_ONLY)
return;
EnterCriticalSection();
// clear
LeaveCriticalSection();
might be more idiomatic.
> }
>
> 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);
...and here.
>
> 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));
Is there a point in tracing the numeric value as well?
> + 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);
I'm not fully familiar with mfplat, but this call may block, and it
doesn't look like ProcessOutput() is supposed to. You probably want
"try-pull-sample" instead.
> +
> + converter->inflight = FALSE;
Nitpick, but this looks like a spacing error.
> +
> + 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)
Please use consistent spacing around pointers.
> +{
> + 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)))
These parentheses are somewhat redundant...
> + {
> + 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;
> +}
>
Dec. 4, 2020
Re: [PATCH 02/17] winegstreamer: Implement ::SetOutputType for audio conversion transform.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
Dec. 4, 2020
Re: [PATCH 01/17] winegstreamer: Implement ::SetInputType for audio conversion transform.
by Zebediah Figura (she/her)
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
That said, I am only really qualified to review these patches for
general errors, and for usage of GStreamer; it strikes me as a good idea
for the Media Foundation maintainers to also review them, to ensure the
functions are doing what they are supposed to.
Dec. 4, 2020
[PATCH] mfplat: Zero-initialize the device manager object.
by Zebediah Figura
This fixes a crash for me when reallocating "handles", triggered by the mfplat tests.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/mfplat/main.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c
index e4cd1c397ad..54bd70a2fff 100644
--- a/dlls/mfplat/main.c
+++ b/dlls/mfplat/main.c
@@ -8911,14 +8911,12 @@ HRESULT WINAPI MFCreateDXGIDeviceManager(UINT *token, IMFDXGIDeviceManager **man
if (!token || !manager)
return E_POINTER;
- object = heap_alloc(sizeof(*object));
- if (!object)
+ if (!(object = heap_alloc_zero(sizeof(*object))))
return E_OUTOFMEMORY;
object->IMFDXGIDeviceManager_iface.lpVtbl = &dxgi_device_manager_vtbl;
object->refcount = 1;
object->token = GetTickCount();
- object->device = NULL;
InitializeCriticalSection(&object->cs);
InitializeConditionVariable(&object->lock);
--
2.29.2
Dec. 4, 2020
[PATCH] ntdll: Use wide-char string literals.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/ntdll/atom.c | 3 +-
dlls/ntdll/directory.c | 6 +-
dlls/ntdll/env.c | 138 +++++++++++++----------------------------
dlls/ntdll/loader.c | 107 +++++++++++---------------------
dlls/ntdll/loadorder.c | 24 +++----
dlls/ntdll/locale.c | 8 +--
dlls/ntdll/path.c | 15 ++---
dlls/ntdll/reg.c | 31 ++-------
dlls/ntdll/relay.c | 32 +++-------
dlls/ntdll/rtl.c | 6 +-
dlls/ntdll/rtlstr.c | 20 ++----
dlls/ntdll/sec.c | 7 +--
12 files changed, 123 insertions(+), 274 deletions(-)
diff --git a/dlls/ntdll/atom.c b/dlls/ntdll/atom.c
index fd1f17b6197..8facadbf8f6 100644
--- a/dlls/ntdll/atom.c
+++ b/dlls/ntdll/atom.c
@@ -102,11 +102,10 @@ NTSTATUS WINAPI RtlDeleteAtomFromAtomTable( RTL_ATOM_TABLE table, RTL_ATOM atom
*/
static ULONG integral_atom_name(WCHAR* buffer, ULONG len, RTL_ATOM atom)
{
- static const WCHAR fmt[] = {'#','%','u',0};
WCHAR tmp[16];
int ret;
- ret = swprintf( tmp, ARRAY_SIZE(tmp), fmt, atom );
+ ret = swprintf( tmp, ARRAY_SIZE(tmp), L"#%u", atom );
if (!len) return ret * sizeof(WCHAR);
if (len <= ret) ret = len - 1;
memcpy( buffer, tmp, ret * sizeof(WCHAR) );
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 39641e9d4d5..cfb4595d457 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -50,8 +50,6 @@ static BOOL show_dot_files;
*/
void init_directories(void)
{
- static const WCHAR WineW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e',0};
- static const WCHAR ShowDotFilesW[] = {'S','h','o','w','D','o','t','F','i','l','e','s',0};
char tmp[80];
HANDLE root, hkey;
DWORD dummy;
@@ -65,12 +63,12 @@ void init_directories(void)
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
- RtlInitUnicodeString( &nameW, WineW );
+ RtlInitUnicodeString( &nameW, L"Software\\Wine" );
/* @@ Wine registry key: HKCU\Software\Wine */
if (!NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr ))
{
- RtlInitUnicodeString( &nameW, ShowDotFilesW );
+ RtlInitUnicodeString( &nameW, L"ShowDotFiles" );
if (!NtQueryValueKey( hkey, &nameW, KeyValuePartialInformation, tmp, sizeof(tmp), &dummy ))
{
WCHAR *str = (WCHAR *)((KEY_VALUE_PARTIAL_INFORMATION *)tmp)->Data;
diff --git a/dlls/ntdll/env.c b/dlls/ntdll/env.c
index bf3fedcac67..5d1b6de5bba 100644
--- a/dlls/ntdll/env.c
+++ b/dlls/ntdll/env.c
@@ -33,7 +33,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(environ);
-static WCHAR empty[] = {0};
+static WCHAR empty[] = L"";
static const UNICODE_STRING empty_str = { 0, sizeof(empty), empty };
static const UNICODE_STRING null_str = { 0, 0, NULL };
@@ -76,7 +76,6 @@ static void set_env_var( WCHAR **env, const WCHAR *name, const WCHAR *val )
static void set_registry_variables( WCHAR **env, HANDLE hkey, ULONG type )
{
static const WCHAR pathW[] = {'P','A','T','H'};
- static const WCHAR sep[] = {';',0};
UNICODE_STRING env_name, env_value;
NTSTATUS status;
DWORD size;
@@ -114,7 +113,7 @@ static void set_registry_variables( WCHAR **env, HANDLE hkey, ULONG type )
!wcsnicmp( env_name.Buffer, pathW, ARRAY_SIZE( pathW )) &&
!RtlQueryEnvironmentVariable_U( *env, &env_name, &tmp ))
{
- RtlAppendUnicodeToString( &tmp, sep );
+ RtlAppendUnicodeToString( &tmp, L";" );
if (RtlAppendUnicodeStringToString( &tmp, &env_value )) continue;
RtlCopyUnicodeString( &env_value, &tmp );
}
@@ -137,16 +136,6 @@ static void set_registry_variables( WCHAR **env, HANDLE hkey, ULONG type )
*/
static BOOL set_registry_environment( WCHAR **env, BOOL first_time )
{
- static const WCHAR env_keyW[] = {'\\','R','e','g','i','s','t','r','y','\\',
- 'M','a','c','h','i','n','e','\\',
- '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','\\',
- 'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r','\\',
- 'E','n','v','i','r','o','n','m','e','n','t',0};
- static const WCHAR envW[] = {'E','n','v','i','r','o','n','m','e','n','t',0};
- static const WCHAR volatile_envW[] = {'V','o','l','a','t','i','l','e',' ','E','n','v','i','r','o','n','m','e','n','t',0};
-
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW;
HANDLE hkey;
@@ -154,7 +143,8 @@ static BOOL set_registry_environment( WCHAR **env, BOOL first_time )
/* first the system environment variables */
InitializeObjectAttributes( &attr, &nameW, 0, 0, NULL );
- RtlInitUnicodeString( &nameW, env_keyW );
+ RtlInitUnicodeString( &nameW, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\"
+ "Session Manager\\Environment" );
if (first_time && !NtOpenKey( &hkey, KEY_READ, &attr ))
{
set_registry_variables( env, hkey, REG_SZ );
@@ -165,7 +155,7 @@ static BOOL set_registry_environment( WCHAR **env, BOOL first_time )
/* then the ones for the current user */
if (RtlOpenCurrentUser( KEY_READ, &attr.RootDirectory ) != STATUS_SUCCESS) return ret;
- RtlInitUnicodeString( &nameW, envW );
+ RtlInitUnicodeString( &nameW, L"Environment" );
if (first_time && !NtOpenKey( &hkey, KEY_READ, &attr ))
{
set_registry_variables( env, hkey, REG_SZ );
@@ -173,7 +163,7 @@ static BOOL set_registry_environment( WCHAR **env, BOOL first_time )
NtClose( hkey );
}
- RtlInitUnicodeString( &nameW, volatile_envW );
+ RtlInitUnicodeString( &nameW, L"Volatile Environment" );
if (!NtOpenKey( &hkey, KEY_READ, &attr ))
{
set_registry_variables( env, hkey, REG_SZ );
@@ -237,26 +227,6 @@ static WCHAR *get_registry_value( WCHAR *env, HKEY hkey, const WCHAR *name )
*/
static void set_additional_environment( WCHAR **env )
{
- static const WCHAR profile_keyW[] = {'\\','R','e','g','i','s','t','r','y','\\',
- 'M','a','c','h','i','n','e','\\',
- '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','r','o','f','i','l','e','L','i','s','t',0};
- static const WCHAR computer_keyW[] = {'\\','R','e','g','i','s','t','r','y','\\',
- 'M','a','c','h','i','n','e','\\',
- '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','\\',
- 'C','o','m','p','u','t','e','r','N','a','m','e','\\',
- 'A','c','t','i','v','e','C','o','m','p','u','t','e','r','N','a','m','e',0};
- static const WCHAR computer_valueW[] = {'C','o','m','p','u','t','e','r','N','a','m','e',0};
- static const WCHAR public_valueW[] = {'P','u','b','l','i','c',0};
- static const WCHAR computernameW[] = {'C','O','M','P','U','T','E','R','N','A','M','E',0};
- static const WCHAR allusersW[] = {'A','L','L','U','S','E','R','S','P','R','O','F','I','L','E',0};
- static const WCHAR programdataW[] = {'P','r','o','g','r','a','m','D','a','t','a',0};
- static const WCHAR publicW[] = {'P','U','B','L','I','C',0};
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW;
WCHAR *val;
@@ -265,18 +235,19 @@ static void set_additional_environment( WCHAR **env )
/* set the user profile variables */
InitializeObjectAttributes( &attr, &nameW, 0, 0, NULL );
- RtlInitUnicodeString( &nameW, profile_keyW );
+ RtlInitUnicodeString( &nameW, L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\"
+ "CurrentVersion\\ProfileList" );
if (!NtOpenKey( &hkey, KEY_READ, &attr ))
{
- if ((val = get_registry_value( *env, hkey, programdataW )))
+ if ((val = get_registry_value( *env, hkey, L"ProgramData" )))
{
- set_env_var( env, allusersW, val );
- set_env_var( env, programdataW, val );
+ set_env_var( env, L"ALLUSERSPROFILE", val );
+ set_env_var( env, L"ProgramData", val );
RtlFreeHeap( GetProcessHeap(), 0, val );
}
- if ((val = get_registry_value( *env, hkey, public_valueW )))
+ if ((val = get_registry_value( *env, hkey, L"Public" )))
{
- set_env_var( env, publicW, val );
+ set_env_var( env, L"PUBLIC", val );
RtlFreeHeap( GetProcessHeap(), 0, val );
}
NtClose( hkey );
@@ -284,12 +255,13 @@ static void set_additional_environment( WCHAR **env )
/* set the computer name */
- RtlInitUnicodeString( &nameW, computer_keyW );
+ RtlInitUnicodeString( &nameW, L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\"
+ "ComputerName\\ActiveComputerName" );
if (!NtOpenKey( &hkey, KEY_READ, &attr ))
{
- if ((val = get_registry_value( *env, hkey, computer_valueW )))
+ if ((val = get_registry_value( *env, hkey, L"ComputerName" )))
{
- set_env_var( env, computernameW, val );
+ set_env_var( env, L"COMPUTERNAME", val );
RtlFreeHeap( GetProcessHeap(), 0, val );
}
NtClose( hkey );
@@ -304,25 +276,8 @@ static void set_additional_environment( WCHAR **env )
*/
static void set_wow64_environment( WCHAR **env )
{
- static WCHAR archW[] = {'P','R','O','C','E','S','S','O','R','_','A','R','C','H','I','T','E','C','T','U','R','E',0};
- static WCHAR arch6432W[] = {'P','R','O','C','E','S','S','O','R','_','A','R','C','H','I','T','E','W','6','4','3','2',0};
- static const WCHAR x86W[] = {'x','8','6',0};
- static const WCHAR versionW[] = {'\\','R','e','g','i','s','t','r','y','\\',
- 'M','a','c','h','i','n','e','\\',
- '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',0};
- static const WCHAR progdirW[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',0};
- static const WCHAR progdir86W[] = {'P','r','o','g','r','a','m','F','i','l','e','s','D','i','r',' ','(','x','8','6',')',0};
- static const WCHAR progfilesW[] = {'P','r','o','g','r','a','m','F','i','l','e','s',0};
- static const WCHAR progfiles86W[] = {'P','r','o','g','r','a','m','F','i','l','e','s','(','x','8','6',')',0};
- static const WCHAR progw6432W[] = {'P','r','o','g','r','a','m','W','6','4','3','2',0};
- static const WCHAR commondirW[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',0};
- static const WCHAR commondir86W[] = {'C','o','m','m','o','n','F','i','l','e','s','D','i','r',' ','(','x','8','6',')',0};
- static const WCHAR commonfilesW[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','F','i','l','e','s',0};
- static const WCHAR commonfiles86W[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','F','i','l','e','s','(','x','8','6',')',0};
- static const WCHAR commonw6432W[] = {'C','o','m','m','o','n','P','r','o','g','r','a','m','W','6','4','3','2',0};
+ static WCHAR archW[] = L"PROCESSOR_ARCHITECTURE";
+ static WCHAR arch6432W[] = L"PROCESSOR_ARCHITEW6432";
WCHAR buf[256];
UNICODE_STRING arch_strW = { sizeof(archW) - sizeof(WCHAR), sizeof(archW), archW };
@@ -363,42 +318,42 @@ static void set_wow64_environment( WCHAR **env )
if (is_wow64)
{
RtlSetEnvironmentVariable( env, &arch6432_strW, &valW );
- RtlInitUnicodeString( &nameW, x86W );
+ RtlInitUnicodeString( &nameW, L"x86" );
RtlSetEnvironmentVariable( env, &arch_strW, &nameW );
}
}
InitializeObjectAttributes( &attr, &nameW, 0, 0, NULL );
- RtlInitUnicodeString( &nameW, versionW );
+ RtlInitUnicodeString( &nameW, L"\\Registry\\Machine\\Software\\Microsoft\\Windows\\CurrentVersion" );
if (NtOpenKey( &hkey, KEY_READ | KEY_WOW64_64KEY, &attr )) return;
/* set the ProgramFiles variables */
- if ((val = get_registry_value( *env, hkey, progdirW )))
+ if ((val = get_registry_value( *env, hkey, L"ProgramFilesDir" )))
{
- if (is_win64 || is_wow64) set_env_var( env, progw6432W, val );
- if (is_win64 || !is_wow64) set_env_var( env, progfilesW, val );
+ if (is_win64 || is_wow64) set_env_var( env, L"ProgramW6432", val );
+ if (is_win64 || !is_wow64) set_env_var( env, L"ProgramFiles", val );
RtlFreeHeap( GetProcessHeap(), 0, val );
}
- if ((val = get_registry_value( *env, hkey, progdir86W )))
+ if ((val = get_registry_value( *env, hkey, L"ProgramFilesDir (x86)" )))
{
- if (is_win64 || is_wow64) set_env_var( env, progfiles86W, val );
- if (is_wow64) set_env_var( env, progfilesW, val );
+ if (is_win64 || is_wow64) set_env_var( env, L"ProgramFiles(x86)", val );
+ if (is_wow64) set_env_var( env, L"ProgramFiles", val );
RtlFreeHeap( GetProcessHeap(), 0, val );
}
/* set the CommonProgramFiles variables */
- if ((val = get_registry_value( *env, hkey, commondirW )))
+ if ((val = get_registry_value( *env, hkey, L"CommonFilesDir" )))
{
- if (is_win64 || is_wow64) set_env_var( env, commonw6432W, val );
- if (is_win64 || !is_wow64) set_env_var( env, commonfilesW, val );
+ if (is_win64 || is_wow64) set_env_var( env, L"CommonProgramW6432", val );
+ if (is_win64 || !is_wow64) set_env_var( env, L"CommonProgramFiles", val );
RtlFreeHeap( GetProcessHeap(), 0, val );
}
- if ((val = get_registry_value( *env, hkey, commondir86W )))
+ if ((val = get_registry_value( *env, hkey, L"CommonFilesDir (x86)" )))
{
- if (is_win64 || is_wow64) set_env_var( env, commonfiles86W, val );
- if (is_wow64) set_env_var( env, commonfilesW, val );
+ if (is_win64 || is_wow64) set_env_var( env, L"CommonProgramFiles(x86)", val );
+ if (is_wow64) set_env_var( env, L"CommonProgramFiles", val );
RtlFreeHeap( GetProcessHeap(), 0, val );
}
NtClose( hkey );
@@ -469,7 +424,6 @@ static inline BOOL is_path_prefix( const WCHAR *prefix, const WCHAR *path, const
*/
static void get_image_path( const WCHAR *name, UNICODE_STRING *path )
{
- static const WCHAR exeW[] = {'.','e','x','e',0};
WCHAR *load_path, *file_part, full_name[MAX_PATH];
DWORD len;
@@ -482,7 +436,7 @@ static void get_image_path( const WCHAR *name, UNICODE_STRING *path )
if (RtlDoesFileExists_U( full_name )) goto done;
if (len < (MAX_PATH - 4) * sizeof(WCHAR) && !wcschr( file_part, '.' ))
{
- wcscat( file_part, exeW );
+ wcscat( file_part, L".exe" );
if (RtlDoesFileExists_U( full_name )) goto done;
}
/* check for builtin path inside system directory */
@@ -495,7 +449,7 @@ static void get_image_path( const WCHAR *name, UNICODE_STRING *path )
else
{
RtlGetExePath( name, &load_path );
- len = RtlDosSearchPath_U( load_path, name, exeW, sizeof(full_name), full_name, &file_part );
+ len = RtlDosSearchPath_U( load_path, name, L".exe", sizeof(full_name), full_name, &file_part );
RtlReleasePath( load_path );
if (!len || len > sizeof(full_name))
{
@@ -504,7 +458,7 @@ static void get_image_path( const WCHAR *name, UNICODE_STRING *path )
if (wcslen( name ) >= MAX_PATH - 4 - len) goto failed;
wcscpy( full_name, system_dir );
wcscat( full_name, name );
- if (!wcschr( name, '.' )) wcscat( full_name, exeW );
+ if (!wcschr( name, '.' )) wcscat( full_name, L".exe" );
}
}
done:
@@ -1140,15 +1094,6 @@ static inline void get_unicode_string( UNICODE_STRING *str, WCHAR **src, UINT le
*/
static void run_wineboot( WCHAR **env )
{
- static const WCHAR wineboot_eventW[] = {'\\','K','e','r','n','e','l','O','b','j','e','c','t','s',
- '\\','_','_','w','i','n','e','b','o','o','t','_','e','v','e','n','t',0};
- static const WCHAR wineboot[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
- 's','y','s','t','e','m','3','2','\\',
- 'w','i','n','e','b','o','o','t','.','e','x','e',0};
- static const WCHAR cmdline[] = {'C',':','\\','w','i','n','d','o','w','s','\\',
- 's','y','s','t','e','m','3','2','\\',
- 'w','i','n','e','b','o','o','t','.','e','x','e',' ',
- '-','-','i','n','i','t',0};
UNICODE_STRING nameW, cmdlineW, dllpathW;
RTL_USER_PROCESS_PARAMETERS *params;
RTL_USER_PROCESS_INFORMATION info;
@@ -1160,7 +1105,7 @@ static void run_wineboot( WCHAR **env )
ULONG redir = 0;
int count = 1;
- RtlInitUnicodeString( &nameW, wineboot_eventW );
+ RtlInitUnicodeString( &nameW, L"\\KernelObjects\\__wineboot_event" );
InitializeObjectAttributes( &attr, &nameW, OBJ_OPENIF, 0, NULL );
status = NtCreateEvent( &handles[0], EVENT_ALL_ACCESS, &attr, NotificationEvent, 0 );
@@ -1170,17 +1115,18 @@ static void run_wineboot( WCHAR **env )
ERR( "failed to create wineboot event, expect trouble\n" );
return;
}
- LdrGetDllPath( wineboot + 4, LOAD_WITH_ALTERED_SEARCH_PATH, &load_path, &dummy );
- RtlInitUnicodeString( &nameW, wineboot + 4 );
+ LdrGetDllPath( L"C:\\windows\\system32\\wineboot.exe", LOAD_WITH_ALTERED_SEARCH_PATH,
+ &load_path, &dummy );
+ RtlInitUnicodeString( &nameW, L"C:\\windows\\system32\\wineboot.exe" );
RtlInitUnicodeString( &dllpathW, load_path );
- RtlInitUnicodeString( &cmdlineW, cmdline );
+ RtlInitUnicodeString( &cmdlineW, L"C:\\windows\\system32\\wineboot.exe --init" );
RtlCreateProcessParametersEx( ¶ms, &nameW, &dllpathW, NULL, &cmdlineW, *env, NULL, NULL,
NULL, NULL, PROCESS_PARAMS_FLAG_NORMALIZED );
params->hStdInput = 0;
params->hStdOutput = 0;
params->hStdError = NtCurrentTeb()->Peb->ProcessParameters->hStdError;
- RtlInitUnicodeString( &nameW, wineboot );
+ RtlInitUnicodeString( &nameW, L"\\??\\C:\\windows\\system32\\wineboot.exe" );
RtlWow64EnableFsRedirectionEx( TRUE, &redir );
status = RtlCreateUserProcess( &nameW, OBJ_CASE_INSENSITIVE, params,
NULL, NULL, 0, FALSE, 0, 0, &info );
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index ff5a175027c..45ad496fd64 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -63,23 +63,16 @@ void (FASTCALL *pBaseThreadInitThunk)(DWORD,LPTHREAD_START_ROUTINE,void *) = NUL
const struct unix_funcs *unix_funcs = NULL;
/* windows directory */
-const WCHAR windows_dir[] = {'C',':','\\','w','i','n','d','o','w','s',0};
+const WCHAR windows_dir[] = L"C:\\windows";
/* system directory with trailing backslash */
-const WCHAR system_dir[] = {'C',':','\\','w','i','n','d','o','w','s','\\',
- 's','y','s','t','e','m','3','2','\\',0};
-const WCHAR syswow64_dir[] = {'C',':','\\','w','i','n','d','o','w','s','\\',
- 's','y','s','w','o','w','6','4','\\',0};
+const WCHAR system_dir[] = L"C:\\windows\\system32\\";
+const WCHAR syswow64_dir[] = L"C:\\windows\\syswow64\\";
static const BOOL is_win64 = (sizeof(void *) > sizeof(int));
BOOL is_wow64 = FALSE;
/* system search path */
-static const WCHAR system_path[] =
- {'C',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m','3','2',';',
- 'C',':','\\','w','i','n','d','o','w','s','\\','s','y','s','t','e','m',';',
- 'C',':','\\','w','i','n','d','o','w','s',0};
-
-static const WCHAR dotW[] = {'.',0};
+static const WCHAR system_path[] = L"C:\\windows\\system32;C:\\windows\\system;C:\\windows";
static BOOL imports_fixup_done = FALSE; /* set once the imports have been fixed up, before attaching them */
static BOOL process_detaching = FALSE; /* set on process detach to avoid deadlocks with thread detach */
@@ -116,8 +109,6 @@ static const char * const reason_names[] =
"WINE_PREATTACH"
};
-static const WCHAR dllW[] = {'.','d','l','l',0};
-
struct file_id
{
BYTE ObjectId[16];
@@ -613,20 +604,21 @@ static FARPROC find_forwarded_export( HMODULE module, const char *forward, LPCWS
FARPROC proc = NULL;
if (!end) return NULL;
- if ((end - forward) * sizeof(WCHAR) > sizeof(buffer) - sizeof(dllW))
+ if ((end - forward) * sizeof(WCHAR) > sizeof(buffer) - sizeof(L".dll"))
{
- if (!(mod_name = RtlAllocateHeap( GetProcessHeap(), 0, (end - forward + sizeof(dllW)) * sizeof(WCHAR) )))
+ if (!(mod_name = RtlAllocateHeap( GetProcessHeap(), 0,
+ (end - forward + sizeof(L".dll")) * sizeof(WCHAR) )))
return NULL;
}
ascii_to_unicode( mod_name, forward, end - forward );
mod_name[end - forward] = 0;
if (!wcschr( mod_name, '.' ))
- memcpy( mod_name + (end - forward), dllW, sizeof(dllW) );
+ memcpy( mod_name + (end - forward), L".dll", sizeof(L".dll") );
if (!(wm = find_basename_module( mod_name )))
{
TRACE( "delay loading %s for '%s'\n", debugstr_w(mod_name), forward );
- if (load_dll( load_path, mod_name, dllW, 0, &wm ) == STATUS_SUCCESS &&
+ if (load_dll( load_path, mod_name, L".dll", 0, &wm ) == STATUS_SUCCESS &&
!(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
{
if (!imports_fixup_done && current_modref)
@@ -789,7 +781,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
{
ascii_to_unicode( buffer, name, len );
buffer[len] = 0;
- status = load_dll( load_path, buffer, dllW, 0, &wmImp );
+ status = load_dll( load_path, buffer, L".dll", 0, &wmImp );
}
else /* need to allocate a larger buffer */
{
@@ -797,7 +789,7 @@ static BOOL import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *descr, LP
if (!ptr) return FALSE;
ascii_to_unicode( ptr, name, len );
ptr[len] = 0;
- status = load_dll( load_path, ptr, dllW, 0, &wmImp );
+ status = load_dll( load_path, ptr, L".dll", 0, &wmImp );
RtlFreeHeap( GetProcessHeap(), 0, ptr );
}
@@ -930,8 +922,6 @@ static NTSTATUS create_module_activation_context( LDR_DATA_TABLE_ENTRY *module )
*/
static BOOL is_dll_native_subsystem( LDR_DATA_TABLE_ENTRY *mod, const IMAGE_NT_HEADERS *nt, LPCWSTR filename )
{
- static const WCHAR ntdllW[] = {'n','t','d','l','l','.','d','l','l',0};
- static const WCHAR kernel32W[] = {'k','e','r','n','e','l','3','2','.','d','l','l',0};
const IMAGE_IMPORT_DESCRIPTOR *imports;
DWORD i, size;
WCHAR buffer[16];
@@ -949,7 +939,7 @@ static BOOL is_dll_native_subsystem( LDR_DATA_TABLE_ENTRY *mod, const IMAGE_NT_H
DWORD len = strlen(name);
if (len * sizeof(WCHAR) >= sizeof(buffer)) continue;
ascii_to_unicode( buffer, name, len + 1 );
- if (!wcsicmp( buffer, ntdllW ) || !wcsicmp( buffer, kernel32W ))
+ if (!wcsicmp( buffer, L"ntdll.dll" ) || !wcsicmp( buffer, L"kernel32.dll" ))
{
TRACE( "%s imports %s, assuming not native\n", debugstr_w(filename), debugstr_w(buffer) );
return FALSE;
@@ -1067,7 +1057,6 @@ static void free_tls_slot( LDR_DATA_TABLE_ENTRY *mod )
*/
static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void **entry )
{
- static const WCHAR mscoreeW[] = {'m','s','c','o','r','e','e','.','d','l','l',0};
IMAGE_EXPORT_DIRECTORY *exports;
DWORD exp_size;
NTSTATUS status;
@@ -1082,7 +1071,7 @@ static NTSTATUS fixup_imports_ilonly( WINE_MODREF *wm, LPCWSTR load_path, void *
prev = current_modref;
current_modref = wm;
- if (!(status = load_dll( load_path, mscoreeW, NULL, 0, &imp ))) wm->deps[0] = imp;
+ if (!(status = load_dll( load_path, L"mscoree.dll", NULL, 0, &imp ))) wm->deps[0] = imp;
current_modref = prev;
if (status)
{
@@ -2099,8 +2088,6 @@ static inline WCHAR *append_path( WCHAR *p, const WCHAR *str, int len )
*/
static NTSTATUS get_dll_load_path( LPCWSTR module, LPCWSTR dll_dir, ULONG safe_mode, WCHAR **path )
{
- static const WCHAR pathW[] = {'P','A','T','H',0};
-
const WCHAR *mod_end = module;
UNICODE_STRING name, value;
WCHAR *p, *ret;
@@ -2112,7 +2099,7 @@ static NTSTATUS get_dll_load_path( LPCWSTR module, LPCWSTR dll_dir, ULONG safe_m
len += (mod_end - module) + 1;
}
- RtlInitUnicodeString( &name, pathW );
+ RtlInitUnicodeString( &name, L"PATH" );
value.Length = 0;
value.MaximumLength = 0;
value.Buffer = NULL;
@@ -2126,9 +2113,9 @@ static NTSTATUS get_dll_load_path( LPCWSTR module, LPCWSTR dll_dir, ULONG safe_m
p = append_path( p, module, mod_end - module );
if (dll_dir) p = append_path( p, dll_dir, -1 );
- else if (!safe_mode) p = append_path( p, dotW, -1 );
+ else if (!safe_mode) p = append_path( p, L".", -1 );
p = append_path( p, system_path, -1 );
- if (!dll_dir && safe_mode) p = append_path( p, dotW, -1 );
+ if (!dll_dir && safe_mode) p = append_path( p, L".", -1 );
value.Buffer = p;
value.MaximumLength = path_len;
@@ -2400,7 +2387,6 @@ static NTSTATUS load_builtin_dll( LPCWSTR load_path, const UNICODE_STRING *nt_na
static NTSTATUS find_actctx_dll( LPCWSTR libname, LPWSTR *fullname )
{
static const WCHAR winsxsW[] = {'\\','w','i','n','s','x','s','\\'};
- static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0};
ACTIVATION_CONTEXT_ASSEMBLY_DETAILED_INFORMATION *info;
ACTCTX_SECTION_KEYED_DATA data;
@@ -2446,7 +2432,7 @@ static NTSTATUS find_actctx_dll( LPCWSTR libname, LPWSTR *fullname )
len = wcslen( p );
if (!dirlen || len <= dirlen ||
RtlCompareUnicodeStrings( p, dirlen, info->lpAssemblyDirectoryName, dirlen, TRUE ) ||
- wcsicmp( p + dirlen, dotManifestW ))
+ wcsicmp( p + dirlen, L".manifest" ))
{
/* manifest name does not match directory name, so it's not a global
* windows/winsxs manifest; use the manifest directory name instead */
@@ -2794,7 +2780,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH LdrLoadDll(LPCWSTR path_name, DWORD flags,
RtlEnterCriticalSection( &loader_section );
if (!path_name) path_name = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
- nts = load_dll( path_name, libname->Buffer, dllW, flags, &wm );
+ nts = load_dll( path_name, libname->Buffer, L".dll", flags, &wm );
if (nts == STATUS_SUCCESS && !(wm->ldr.Flags & LDR_DONT_RESOLVE_REFS))
{
@@ -2828,7 +2814,7 @@ NTSTATUS WINAPI LdrGetDllHandle( LPCWSTR load_path, ULONG flags, const UNICODE_S
if (!load_path) load_path = NtCurrentTeb()->Peb->ProcessParameters->DllPath.Buffer;
- status = find_dll_file( load_path, name->Buffer, dllW, &nt_name, &wm, &module, &image_info, &id );
+ status = find_dll_file( load_path, name->Buffer, L".dll", &nt_name, &wm, &module, &image_info, &id );
if (wm) *base = wm->ldr.DllBase;
else
@@ -3574,20 +3560,6 @@ void WINAPI LdrInitializeThunk( CONTEXT *context, ULONG_PTR unknown2, ULONG_PTR
*/
static void load_global_options(void)
{
- static const WCHAR sessionW[] = {'M','a','c','h','i','n','e','\\',
- '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','\\',
- 'S','e','s','s','i','o','n',' ','M','a','n','a','g','e','r',0};
- static const WCHAR globalflagW[] = {'G','l','o','b','a','l','F','l','a','g',0};
- static const WCHAR safesearchW[] = {'S','a','f','e','P','r','o','c','e','s','s','S','e','a','r','c','h','M','o','d','e',0};
- static const WCHAR safedllmodeW[] = {'S','a','f','e','D','l','l','S','e','a','r','c','h','M','o','d','e',0};
- static const WCHAR critsectW[] = {'C','r','i','t','i','c','a','l','S','e','c','t','i','o','n','T','i','m','e','o','u','t',0};
- static const WCHAR heapresW[] = {'H','e','a','p','S','e','g','m','e','n','t','R','e','s','e','r','v','e',0};
- static const WCHAR heapcommitW[] = {'H','e','a','p','S','e','g','m','e','n','t','C','o','m','m','i','t',0};
- static const WCHAR decommittotalW[] = {'H','e','a','p','D','e','C','o','m','m','i','t','T','o','t','a','l','F','r','e','e','T','h','r','e','s','h','o','l','d',0};
- static const WCHAR decommitfreeW[] = {'H','e','a','p','D','e','C','o','m','m','i','t','F','r','e','e','B','l','o','c','k','T','h','r','e','s','h','o','l','d',0};
-
OBJECT_ATTRIBUTES attr;
UNICODE_STRING name_str;
HANDLE hkey;
@@ -3599,33 +3571,33 @@ static void load_global_options(void)
attr.Attributes = OBJ_CASE_INSENSITIVE;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
- RtlInitUnicodeString( &name_str, sessionW );
+ RtlInitUnicodeString( &name_str, L"Machine\\System\\CurrentControlSet\\Control\\Session Manager" );
if (!NtOpenKey( &hkey, KEY_QUERY_VALUE, &attr ))
{
- query_dword_option( hkey, globalflagW, &NtCurrentTeb()->Peb->NtGlobalFlag );
- query_dword_option( hkey, safesearchW, &path_safe_mode );
- query_dword_option( hkey, safedllmodeW, &dll_safe_mode );
+ query_dword_option( hkey, L"GlobalFlag", &NtCurrentTeb()->Peb->NtGlobalFlag );
+ query_dword_option( hkey, L"SafeProcessSearchMode", &path_safe_mode );
+ query_dword_option( hkey, L"SafeDllSearchMode", &dll_safe_mode );
- if (!query_dword_option( hkey, critsectW, &value ))
+ if (!query_dword_option( hkey, L"CriticalSectionTimeout", &value ))
NtCurrentTeb()->Peb->CriticalSectionTimeout.QuadPart = (ULONGLONG)value * -10000000;
- if (!query_dword_option( hkey, heapresW, &value ))
+ if (!query_dword_option( hkey, L"HeapSegmentReserve", &value ))
NtCurrentTeb()->Peb->HeapSegmentReserve = value;
- if (!query_dword_option( hkey, heapcommitW, &value ))
+ if (!query_dword_option( hkey, L"HeapSegmentCommit", &value ))
NtCurrentTeb()->Peb->HeapSegmentCommit = value;
- if (!query_dword_option( hkey, decommittotalW, &value ))
+ if (!query_dword_option( hkey, L"HeapDeCommitTotalFreeThreshold", &value ))
NtCurrentTeb()->Peb->HeapDeCommitTotalFreeThreshold = value;
- if (!query_dword_option( hkey, decommitfreeW, &value ))
+ if (!query_dword_option( hkey, L"HeapDeCommitFreeBlockThreshold", &value ))
NtCurrentTeb()->Peb->HeapDeCommitFreeBlockThreshold = value;
NtClose( hkey );
}
LdrQueryImageFileExecutionOptions( &NtCurrentTeb()->Peb->ProcessParameters->ImagePathName,
- globalflagW, REG_DWORD, &NtCurrentTeb()->Peb->NtGlobalFlag,
+ L"GlobalFlag", REG_DWORD, &NtCurrentTeb()->Peb->NtGlobalFlag,
sizeof(DWORD), NULL );
heap_set_debug_flags( GetProcessHeap() );
}
@@ -3918,21 +3890,17 @@ NTSTATUS WINAPI RtlSetSearchPathMode( ULONG flags )
*/
NTSTATUS WINAPI RtlGetExePath( PCWSTR name, PWSTR *path )
{
- static const WCHAR emptyW[1];
- const WCHAR *dlldir = dotW;
+ const WCHAR *dlldir = L".";
const WCHAR *module = NtCurrentTeb()->Peb->ProcessParameters->ImagePathName.Buffer;
/* same check as NeedCurrentDirectoryForExePathW */
if (!wcschr( name, '\\' ))
{
- static const WCHAR env_name[] = {'N','o','D','e','f','a','u','l','t','C','u','r','r','e','n','t',
- 'D','i','r','e','c','t','o','r','y','I','n',
- 'E','x','e','P','a','t','h',0};
UNICODE_STRING name, value = { 0 };
- RtlInitUnicodeString( &name, env_name );
+ RtlInitUnicodeString( &name, L"NoDefaultCurrentDirectoryInExePath" );
if (RtlQueryEnvironmentVariable_U( NULL, &name, &value ) != STATUS_VARIABLE_NOT_FOUND)
- dlldir = emptyW;
+ dlldir = L"";
}
return get_dll_load_path( module, dlldir, FALSE, path );
}
@@ -3995,12 +3963,6 @@ static void restart_winevdm( RTL_USER_PROCESS_PARAMETERS *params )
*/
static NTSTATUS process_init(void)
{
- static const WCHAR ntdllW[] = {'\\','?','?','\\','C',':','\\','w','i','n','d','o','w','s','\\',
- 's','y','s','t','e','m','3','2','\\',
- 'n','t','d','l','l','.','d','l','l',0};
- static const WCHAR kernel32W[] = {'C',':','\\','w','i','n','d','o','w','s','\\',
- 's','y','s','t','e','m','3','2','\\',
- 'k','e','r','n','e','l','3','2','.','d','l','l',0};
RTL_USER_PROCESS_PARAMETERS *params;
WINE_MODREF *wm;
NTSTATUS status;
@@ -4046,13 +4008,14 @@ static NTSTATUS process_init(void)
version_init();
/* setup the load callback and create ntdll modref */
- RtlInitUnicodeString( &nt_name, ntdllW );
+ RtlInitUnicodeString( &nt_name, L"\\??\\C:\\windows\\system32\\ntdll.dll" );
NtQueryVirtualMemory( GetCurrentProcess(), process_init, MemoryBasicInformation,
&meminfo, sizeof(meminfo), NULL );
status = build_builtin_module( params->DllPath.Buffer, &nt_name, meminfo.AllocationBase, 0, &wm );
assert( !status );
- if ((status = load_dll( params->DllPath.Buffer, kernel32W, NULL, 0, &wm )) != STATUS_SUCCESS)
+ if ((status = load_dll( params->DllPath.Buffer, L"C:\\windows\\system32\\kernel32.dll",
+ NULL, 0, &wm )) != STATUS_SUCCESS)
{
MESSAGE( "wine: could not load kernel32.dll, status %x\n", status );
NtTerminateProcess( GetCurrentProcess(), status );
diff --git a/dlls/ntdll/loadorder.c b/dlls/ntdll/loadorder.c
index c55806df2b8..e4aaf9dd74f 100644
--- a/dlls/ntdll/loadorder.c
+++ b/dlls/ntdll/loadorder.c
@@ -49,7 +49,7 @@ struct loadorder_list
module_loadorder_t *order;
};
-static const WCHAR separatorsW[] = {',',' ','\t',0};
+static const WCHAR separatorsW[] = L", \t";
static BOOL init_done;
static struct loadorder_list env_list;
@@ -89,10 +89,9 @@ static const WCHAR *get_basename( const WCHAR *name )
*/
static inline void remove_dll_ext( WCHAR *name )
{
- static const WCHAR dllW[] = {'.','d','l','l',0};
WCHAR *p = wcsrchr( name, '.' );
- if (p && !wcsicmp( p, dllW )) *p = 0;
+ if (p && !wcsicmp( p, L".dll" )) *p = 0;
}
@@ -224,7 +223,6 @@ static void add_load_order_set( WCHAR *entry )
*/
static void init_load_order(void)
{
- static const WCHAR winedlloverridesW[] = {'W','I','N','E','D','L','L','O','V','E','R','R','I','D','E','S',0};
WCHAR *entry, *next, *order;
SIZE_T len = 1024;
NTSTATUS status;
@@ -234,7 +232,7 @@ static void init_load_order(void)
for (;;)
{
order = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) );
- status = RtlQueryEnvironmentVariable( NULL, winedlloverridesW, wcslen(winedlloverridesW),
+ status = RtlQueryEnvironmentVariable( NULL, L"WINEDLLOVERRIDES", wcslen(L"WINEDLLOVERRIDES"),
order, len - 1, &len );
if (!status)
{
@@ -290,8 +288,6 @@ static inline enum loadorder get_env_load_order( const WCHAR *module )
*/
static HANDLE get_standard_key(void)
{
- static const WCHAR DllOverridesW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
- 'D','l','l','O','v','e','r','r','i','d','e','s',0};
static HANDLE std_key = (HANDLE)-1;
if (std_key == (HANDLE)-1)
@@ -307,7 +303,7 @@ static HANDLE get_standard_key(void)
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
- RtlInitUnicodeString( &nameW, DllOverridesW );
+ RtlInitUnicodeString( &nameW, L"Software\\Wine\\DllOverrides" );
/* @@ Wine registry key: HKCU\Software\Wine\DllOverrides */
if (NtOpenKey( &std_key, KEY_ALL_ACCESS, &attr )) std_key = 0;
@@ -328,20 +324,17 @@ static HANDLE get_app_key( const WCHAR *app_name )
UNICODE_STRING nameW;
HANDLE root;
WCHAR *str;
- static const WCHAR AppDefaultsW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e','\\',
- 'A','p','p','D','e','f','a','u','l','t','s','\\',0};
- static const WCHAR DllOverridesW[] = {'\\','D','l','l','O','v','e','r','r','i','d','e','s',0};
static HANDLE app_key = (HANDLE)-1;
if (app_key != (HANDLE)-1) return app_key;
str = RtlAllocateHeap( GetProcessHeap(), 0,
- sizeof(AppDefaultsW) + sizeof(DllOverridesW) +
+ sizeof(L"Software\\Wine\\AppDefaults\\") + sizeof(L"\\DllOverrides") +
wcslen(app_name) * sizeof(WCHAR) );
if (!str) return 0;
- wcscpy( str, AppDefaultsW );
+ wcscpy( str, L"Software\\Wine\\AppDefaults\\" );
wcscat( str, app_name );
- wcscat( str, DllOverridesW );
+ wcscat( str, L"\\DllOverrides" );
RtlOpenCurrentUser( KEY_ALL_ACCESS, &root );
attr.Length = sizeof(attr);
@@ -425,7 +418,6 @@ static enum loadorder get_load_order_value( HANDLE std_key, HANDLE app_key, cons
*/
enum loadorder get_load_order( const WCHAR *app_name, const UNICODE_STRING *nt_name )
{
- static const WCHAR nt_prefixW[] = {'\\','?','?','\\',0};
enum loadorder ret = LO_INVALID;
HANDLE std_key, app_key = 0;
const WCHAR *path = nt_name->Buffer;
@@ -435,7 +427,7 @@ enum loadorder get_load_order( const WCHAR *app_name, const UNICODE_STRING *nt_n
if (!init_done) init_load_order();
std_key = get_standard_key();
if (app_name) app_key = get_app_key( app_name );
- if (!wcsncmp( path, nt_prefixW, 4 )) path += 4;
+ if (!wcsncmp( path, L"\\??\\", 4 )) path += 4;
TRACE("looking for %s\n", debugstr_w(path));
diff --git a/dlls/ntdll/locale.c b/dlls/ntdll/locale.c
index e3cc0d183c4..3979f41089b 100644
--- a/dlls/ntdll/locale.c
+++ b/dlls/ntdll/locale.c
@@ -1269,8 +1269,6 @@ NTSTATUS WINAPI RtlLocaleNameToLcid( const WCHAR *name, LCID *lcid, ULONG flags
{
/* locale name format is: lang[-script][-country][_modifier] */
- static const WCHAR sepW[] = {'-','_',0};
-
const IMAGE_RESOURCE_DIRECTORY *resdir;
const IMAGE_RESOURCE_DIRECTORY_ENTRY *et;
LDR_RESOURCE_INFO info;
@@ -1291,16 +1289,16 @@ NTSTATUS WINAPI RtlLocaleNameToLcid( const WCHAR *name, LCID *lcid, ULONG flags
if (wcslen( name ) >= LOCALE_NAME_MAX_LENGTH) return STATUS_INVALID_PARAMETER_1;
wcscpy( lang, name );
- if ((p = wcspbrk( lang, sepW )) && *p == '-')
+ if ((p = wcspbrk( lang, L"-_" )) && *p == '-')
{
*p++ = 0;
country = p;
- if ((p = wcspbrk( p, sepW )) && *p == '-')
+ if ((p = wcspbrk( p, L"-_" )) && *p == '-')
{
*p++ = 0;
script = country;
country = p;
- p = wcspbrk( p, sepW );
+ p = wcspbrk( p, L"-_" );
}
if (p) *p = 0; /* FIXME: modifier is ignored */
/* second value can be script or country, check length to resolve the ambiguity */
diff --git a/dlls/ntdll/path.c b/dlls/ntdll/path.c
index 53470b4f357..86760f178e1 100644
--- a/dlls/ntdll/path.c
+++ b/dlls/ntdll/path.c
@@ -31,10 +31,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(file);
-static const WCHAR DeviceRootW[] = {'\\','\\','.','\\',0};
-static const WCHAR NTDosPrefixW[] = {'\\','?','?','\\',0};
-static const WCHAR UncPfxW[] = {'U','N','C','\\',0};
-
#define IS_SEPARATOR(ch) ((ch) == '\\' || (ch) == '/')
/***********************************************************************
@@ -69,7 +65,6 @@ DOS_PATHNAME_TYPE WINAPI RtlDetermineDosPathNameType_U( PCWSTR path )
*/
ULONG WINAPI RtlIsDosDeviceName_U( PCWSTR dos_name )
{
- static const WCHAR consoleW[] = {'\\','\\','.','\\','C','O','N',0};
static const WCHAR auxW[] = {'A','U','X'};
static const WCHAR comW[] = {'C','O','M'};
static const WCHAR conW[] = {'C','O','N'};
@@ -87,7 +82,7 @@ ULONG WINAPI RtlIsDosDeviceName_U( PCWSTR dos_name )
case UNC_PATH:
return 0;
case DEVICE_PATH:
- if (!wcsicmp( dos_name, consoleW ))
+ if (!wcsicmp( dos_name, L"\\\\.\\CON" ))
return MAKELONG( sizeof(conW), 4 * sizeof(WCHAR) ); /* 4 is length of \\.\ prefix */
return 0;
case ABSOLUTE_DRIVE_PATH:
@@ -207,12 +202,12 @@ NTSTATUS WINAPI RtlDosPathNameToNtPathName_U_WithStatus(const WCHAR *dos_path, U
return STATUS_NO_MEMORY;
}
- wcscpy(ntpath->Buffer, NTDosPrefixW);
+ wcscpy(ntpath->Buffer, L"\\??\\");
switch (RtlDetermineDosPathNameType_U(ptr))
{
case UNC_PATH: /* \\foo */
offset = 2;
- wcscat(ntpath->Buffer, UncPfxW);
+ wcscat(ntpath->Buffer, L"UNC\\");
break;
case DEVICE_PATH: /* \\.\foo */
offset = 4;
@@ -661,7 +656,7 @@ DWORD WINAPI RtlGetFullPathName_U(const WCHAR* name, ULONG size, WCHAR* buffer,
DWORD sz = LOWORD(dosdev); /* in bytes */
if (8 + sz + 2 > size) return sz + 10;
- wcscpy(buffer, DeviceRootW);
+ wcscpy(buffer, L"\\\\.\\");
memmove(buffer + 4, name + offset, sz);
buffer[4 + sz / sizeof(WCHAR)] = '\0';
/* file_part isn't set in this case */
@@ -874,7 +869,7 @@ NTSTATUS WINAPI RtlSetCurrentDirectory_U(const UNICODE_STRING* dir)
if (size && ptr[size - 1] != '\\') ptr[size++] = '\\';
/* convert \??\UNC\ path to \\ prefix */
- if (size >= 4 && !wcsnicmp(ptr, UncPfxW, 4))
+ if (size >= 4 && !wcsnicmp(ptr, L"UNC\\", 4))
{
ptr += 2;
size -= 2;
diff --git a/dlls/ntdll/reg.c b/dlls/ntdll/reg.c
index 5a54d7fee26..54f01049abf 100644
--- a/dlls/ntdll/reg.c
+++ b/dlls/ntdll/reg.c
@@ -402,49 +402,30 @@ static NTSTATUS RTL_KeyHandleCreateObject(ULONG RelativeTo, PCWSTR Path, POBJECT
PCWSTR base;
INT len;
- static const WCHAR empty[] = {0};
- static const WCHAR control[] = {'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e',
- '\\','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','\\',0};
-
- static const WCHAR devicemap[] = {'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\',
- 'H','a','r','d','w','a','r','e','\\','D','e','v','i','c','e','M','a','p','\\',0};
-
- static const WCHAR services[] = {'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\',
- 'S','y','s','t','e','m','\\','C','u','r','r','e','n','t','C','o','n','t','r','o','l','S','e','t','\\',
- 'S','e','r','v','i','c','e','s','\\',0};
-
- static const WCHAR user[] = {'\\','R','e','g','i','s','t','r','y','\\','U','s','e','r','\\',
- 'C','u','r','r','e','n','t','U','s','e','r','\\',0};
-
- static const WCHAR windows_nt[] = {'\\','R','e','g','i','s','t','r','y','\\','M','a','c','h','i','n','e','\\',
- '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','\\',0};
-
switch (RelativeTo & 0xff)
{
case RTL_REGISTRY_ABSOLUTE:
- base = empty;
+ base = L"";
break;
case RTL_REGISTRY_CONTROL:
- base = control;
+ base = L"\\Registry\\Machine\\System\\CurrentControlSet\\Control\\";
break;
case RTL_REGISTRY_DEVICEMAP:
- base = devicemap;
+ base = L"\\Registry\\Machine\\Hardware\\DeviceMap\\";
break;
case RTL_REGISTRY_SERVICES:
- base = services;
+ base = L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\";
break;
case RTL_REGISTRY_USER:
- base = user;
+ base = L"\\Registry\\User\\CurrentUser\\";
break;
case RTL_REGISTRY_WINDOWS_NT:
- base = windows_nt;
+ base = L"\\Registry\\Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion\\";
break;
default:
diff --git a/dlls/ntdll/relay.c b/dlls/ntdll/relay.c
index e1596312491..ee7d9951c59 100644
--- a/dlls/ntdll/relay.c
+++ b/dlls/ntdll/relay.c
@@ -167,17 +167,6 @@ static DWORD WINAPI init_debug_lists( RTL_RUN_ONCE *once, void *param, void **co
OBJECT_ATTRIBUTES attr;
UNICODE_STRING name;
HANDLE root, hkey;
- static const WCHAR configW[] = {'S','o','f','t','w','a','r','e','\\',
- 'W','i','n','e','\\',
- 'D','e','b','u','g',0};
- static const WCHAR RelayIncludeW[] = {'R','e','l','a','y','I','n','c','l','u','d','e',0};
- static const WCHAR RelayExcludeW[] = {'R','e','l','a','y','E','x','c','l','u','d','e',0};
- static const WCHAR SnoopIncludeW[] = {'S','n','o','o','p','I','n','c','l','u','d','e',0};
- static const WCHAR SnoopExcludeW[] = {'S','n','o','o','p','E','x','c','l','u','d','e',0};
- static const WCHAR RelayFromIncludeW[] = {'R','e','l','a','y','F','r','o','m','I','n','c','l','u','d','e',0};
- static const WCHAR RelayFromExcludeW[] = {'R','e','l','a','y','F','r','o','m','E','x','c','l','u','d','e',0};
- static const WCHAR SnoopFromIncludeW[] = {'S','n','o','o','p','F','r','o','m','I','n','c','l','u','d','e',0};
- static const WCHAR SnoopFromExcludeW[] = {'S','n','o','o','p','F','r','o','m','E','x','c','l','u','d','e',0};
RtlOpenCurrentUser( KEY_ALL_ACCESS, &root );
attr.Length = sizeof(attr);
@@ -186,21 +175,21 @@ static DWORD WINAPI init_debug_lists( RTL_RUN_ONCE *once, void *param, void **co
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
- RtlInitUnicodeString( &name, configW );
+ RtlInitUnicodeString( &name, L"Software\\Wine\\Debug" );
/* @@ Wine registry key: HKCU\Software\Wine\Debug */
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) hkey = 0;
NtClose( root );
if (!hkey) return TRUE;
- debug_relay_includelist = load_list( hkey, RelayIncludeW );
- debug_relay_excludelist = load_list( hkey, RelayExcludeW );
- debug_snoop_includelist = load_list( hkey, SnoopIncludeW );
- debug_snoop_excludelist = load_list( hkey, SnoopExcludeW );
- debug_from_relay_includelist = load_list( hkey, RelayFromIncludeW );
- debug_from_relay_excludelist = load_list( hkey, RelayFromExcludeW );
- debug_from_snoop_includelist = load_list( hkey, SnoopFromIncludeW );
- debug_from_snoop_excludelist = load_list( hkey, SnoopFromExcludeW );
+ debug_relay_includelist = load_list( hkey, L"RelayInclude" );
+ debug_relay_excludelist = load_list( hkey, L"RelayExclude" );
+ debug_snoop_includelist = load_list( hkey, L"SnoopInclude" );
+ debug_snoop_excludelist = load_list( hkey, L"SnoopExclude" );
+ debug_from_relay_includelist = load_list( hkey, L"RelayFromInclude" );
+ debug_from_relay_excludelist = load_list( hkey, L"RelayFromExclude" );
+ debug_from_snoop_includelist = load_list( hkey, L"SnoopFromInclude" );
+ debug_from_snoop_excludelist = load_list( hkey, L"SnoopFromExclude" );
NtClose( hkey );
return TRUE;
@@ -259,7 +248,6 @@ static BOOL check_relay_include( const WCHAR *module, int ordinal, const char *f
*/
static BOOL check_from_module( const WCHAR **includelist, const WCHAR **excludelist, const WCHAR *module )
{
- static const WCHAR dllW[] = {'.','d','l','l',0 };
const WCHAR **listitem;
BOOL show;
@@ -281,7 +269,7 @@ static BOOL check_from_module( const WCHAR **includelist, const WCHAR **excludel
if (!wcsicmp( *listitem, module )) return !show;
len = wcslen( *listitem );
- if (!wcsnicmp( *listitem, module, len ) && !wcsicmp( module + len, dllW ))
+ if (!wcsnicmp( *listitem, module, len ) && !wcsicmp( module + len, L".dll" ))
return !show;
}
return show;
diff --git a/dlls/ntdll/rtl.c b/dlls/ntdll/rtl.c
index 11dbc63a3b3..cf21c980a45 100644
--- a/dlls/ntdll/rtl.c
+++ b/dlls/ntdll/rtl.c
@@ -1314,8 +1314,6 @@ NTSTATUS WINAPI RtlIpv6StringToAddressA(const char *str, const char **terminator
NTSTATUS WINAPI RtlIpv4AddressToStringExW(const IN_ADDR *pin, USHORT port, LPWSTR buffer, PULONG psize)
{
WCHAR tmp_ip[32];
- static const WCHAR fmt_ip[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
- static const WCHAR fmt_port[] = {':','%','u',0};
ULONG needed;
if (!pin || !buffer || !psize)
@@ -1323,11 +1321,11 @@ NTSTATUS WINAPI RtlIpv4AddressToStringExW(const IN_ADDR *pin, USHORT port, LPWST
TRACE("(%p:0x%x, %d, %p, %p:%d)\n", pin, pin->S_un.S_addr, port, buffer, psize, *psize);
- needed = swprintf(tmp_ip, ARRAY_SIZE(tmp_ip), fmt_ip,
+ needed = swprintf(tmp_ip, ARRAY_SIZE(tmp_ip), L"%u.%u.%u.%u",
pin->S_un.S_un_b.s_b1, pin->S_un.S_un_b.s_b2,
pin->S_un.S_un_b.s_b3, pin->S_un.S_un_b.s_b4);
- if (port) needed += swprintf(tmp_ip + needed, ARRAY_SIZE(tmp_ip) - needed, fmt_port, ntohs(port));
+ if (port) needed += swprintf(tmp_ip + needed, ARRAY_SIZE(tmp_ip) - needed, L":%u", ntohs(port));
if (*psize > needed) {
*psize = needed + 1;
diff --git a/dlls/ntdll/rtlstr.c b/dlls/ntdll/rtlstr.c
index d8ff81b8050..90f32ceecf0 100644
--- a/dlls/ntdll/rtlstr.c
+++ b/dlls/ntdll/rtlstr.c
@@ -1160,8 +1160,6 @@ NTSTATUS WINAPI RtlFindCharInUnicodeString(
*/
BOOLEAN WINAPI RtlIsTextUnicode( LPCVOID buf, INT len, INT *pf )
{
- static const WCHAR std_control_chars[] = {'\r','\n','\t',' ',0x3000,0};
- static const WCHAR byterev_control_chars[] = {0x0d00,0x0a00,0x0900,0x2000,0};
const WCHAR *s = buf;
int i;
unsigned int flags = ~0U, out_flags = 0;
@@ -1225,7 +1223,7 @@ BOOLEAN WINAPI RtlIsTextUnicode( LPCVOID buf, INT len, INT *pf )
{
for (i = 0; i < len; i++)
{
- if (wcschr(std_control_chars, s[i]))
+ if (wcschr(L"\r\n\t \x3000", s[i]))
{
out_flags |= IS_TEXT_UNICODE_CONTROLS;
break;
@@ -1237,7 +1235,7 @@ BOOLEAN WINAPI RtlIsTextUnicode( LPCVOID buf, INT len, INT *pf )
{
for (i = 0; i < len; i++)
{
- if (wcschr(byterev_control_chars, s[i]))
+ if (wcschr(L"\x0d00\x0a00\x0900\x2000", s[i]))
{
out_flags |= IS_TEXT_UNICODE_REVERSE_CONTROLS;
break;
@@ -1684,11 +1682,6 @@ NTSTATUS WINAPI RtlGUIDFromString(PUNICODE_STRING str, GUID* guid)
*/
NTSTATUS WINAPI RtlStringFromGUID(const GUID* guid, UNICODE_STRING *str)
{
- static const WCHAR szFormat[] = { '{','%','0','8','l','X','-',
- '%','0','4','X','-', '%','0','4','X','-','%','0','2','X','%','0','2','X',
- '-', '%','0','2','X','%','0','2','X','%','0','2','X','%','0','2','X',
- '%','0','2','X','%','0','2','X','}','\0' };
-
TRACE("(%p,%p)\n", guid, str);
str->Length = GUID_STRING_LENGTH * sizeof(WCHAR);
@@ -1699,7 +1692,8 @@ NTSTATUS WINAPI RtlStringFromGUID(const GUID* guid, UNICODE_STRING *str)
str->Length = str->MaximumLength = 0;
return STATUS_NO_MEMORY;
}
- swprintf(str->Buffer, str->MaximumLength/sizeof(WCHAR), szFormat, guid->Data1, guid->Data2, guid->Data3,
+ swprintf(str->Buffer, str->MaximumLength/sizeof(WCHAR),
+ L"{%08lX-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}", guid->Data1, guid->Data2, guid->Data3,
guid->Data4[0], guid->Data4[1], guid->Data4[2], guid->Data4[3],
guid->Data4[4], guid->Data4[5], guid->Data4[6], guid->Data4[7]);
@@ -1739,7 +1733,6 @@ static UINT64 get_arg( int nr, struct format_message_args *args_data, BOOL is64
static NTSTATUS add_format( WCHAR **buffer, WCHAR *end, const WCHAR **src, int insert, BOOLEAN ansi,
struct format_message_args *args_data )
{
- static const WCHAR modifiers[] = {'0','1','2','3','4','5','6','7','8','9',' ','+','-','*','#','.',0};
const WCHAR *format = *src;
WCHAR *p, fmt[32];
ULONG_PTR args[5] = { 0 };
@@ -1757,7 +1750,7 @@ static NTSTATUS add_format( WCHAR **buffer, WCHAR *end, const WCHAR **src, int i
if (!end || end - format > ARRAY_SIZE(fmt) - 2) return STATUS_INVALID_PARAMETER;
*src = end + 1;
- while (wcschr( modifiers, *format ))
+ while (wcschr( L"0123456789 +-*#.", *format ))
{
if (*format == '*') stars++;
*p++ = *format++;
@@ -1829,7 +1822,6 @@ NTSTATUS WINAPI RtlFormatMessageEx( const WCHAR *src, ULONG width, BOOLEAN ignor
BOOLEAN ansi, BOOLEAN is_array, __ms_va_list *args,
WCHAR *buffer, ULONG size, ULONG *retsize, ULONG flags )
{
- static const WCHAR emptyW = 0;
static const WCHAR spaceW = ' ';
static const WCHAR crW = '\r';
static const WCHAR tabW = '\t';
@@ -1945,7 +1937,7 @@ NTSTATUS WINAPI RtlFormatMessageEx( const WCHAR *src, ULONG width, BOOLEAN ignor
}
}
- if ((status = add_chars( &buffer, end, &emptyW, 1 ))) return status;
+ if ((status = add_chars( &buffer, end, L"", 1 ))) return status;
*retsize = (buffer - start) * sizeof(WCHAR);
return STATUS_SUCCESS;
diff --git a/dlls/ntdll/sec.c b/dlls/ntdll/sec.c
index c0f962f0562..0d45bbf02aa 100644
--- a/dlls/ntdll/sec.c
+++ b/dlls/ntdll/sec.c
@@ -1617,21 +1617,20 @@ NTSTATUS WINAPI RtlConvertSidToUnicodeString(
PSID pSid,
BOOLEAN AllocateString)
{
- static const WCHAR formatW[] = {'-','%','u',0};
WCHAR buffer[2 + 10 + 10 + 10 * SID_MAX_SUB_AUTHORITIES];
WCHAR *p = buffer;
const SID *sid = pSid;
DWORD i, len;
*p++ = 'S';
- p += swprintf( p, ARRAY_SIZE(buffer) - (p - buffer), formatW, sid->Revision );
- p += swprintf( p, ARRAY_SIZE(buffer) - (p - buffer), formatW,
+ p += swprintf( p, ARRAY_SIZE(buffer) - (p - buffer), L"-%u", sid->Revision );
+ p += swprintf( p, ARRAY_SIZE(buffer) - (p - buffer), L"-%u",
MAKELONG( MAKEWORD( sid->IdentifierAuthority.Value[5],
sid->IdentifierAuthority.Value[4] ),
MAKEWORD( sid->IdentifierAuthority.Value[3],
sid->IdentifierAuthority.Value[2] )));
for (i = 0; i < sid->SubAuthorityCount; i++)
- p += swprintf( p, ARRAY_SIZE(buffer) - (p - buffer), formatW, sid->SubAuthority[i] );
+ p += swprintf( p, ARRAY_SIZE(buffer) - (p - buffer), L"-%u", sid->SubAuthority[i] );
len = (p + 1 - buffer) * sizeof(WCHAR);
--
2.26.2
Dec. 3, 2020
[PATCH] ntdll: Use wide-char string literals in version.c.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/ntdll/version.c | 177 ++++++++++++++++---------------------------
1 file changed, 64 insertions(+), 113 deletions(-)
diff --git a/dlls/ntdll/version.c b/dlls/ntdll/version.c
index 46715575225..740d8403f5e 100644
--- a/dlls/ntdll/version.c
+++ b/dlls/ntdll/version.c
@@ -66,20 +66,17 @@ static const RTL_OSVERSIONINFOEXW VersionData[NB_WINDOWS_VERSIONS] =
/* WIN20 FIXME: verify values */
{
sizeof(RTL_OSVERSIONINFOEXW), 2, 0, 0, VER_PLATFORM_WIN32s,
- {'W','i','n','3','2','s',' ','1','.','3',0},
- 0, 0, 0, 0, 0
+ L"Win32s 1.3", 0, 0, 0, 0, 0
},
/* WIN30 FIXME: verify values */
{
sizeof(RTL_OSVERSIONINFOEXW), 3, 0, 0, VER_PLATFORM_WIN32s,
- {'W','i','n','3','2','s',' ','1','.','3',0},
- 0, 0, 0, 0, 0
+ L"Win32s 1.3", 0, 0, 0, 0, 0
},
/* WIN31 */
{
sizeof(RTL_OSVERSIONINFOEXW), 3, 10, 0, VER_PLATFORM_WIN32s,
- {'W','i','n','3','2','s',' ','1','.','3',0},
- 0, 0, 0, 0, 0
+ L"Win32s 1.3", 0, 0, 0, 0, 0
},
/* WIN95 */
{
@@ -91,8 +88,7 @@ static const RTL_OSVERSIONINFOEXW VersionData[NB_WINDOWS_VERSIONS] =
* Win95a/b can be discerned via regkey SubVersionNumber
*/
sizeof(RTL_OSVERSIONINFOEXW), 4, 0, 0x40003B6, VER_PLATFORM_WIN32_WINDOWS,
- {0},
- 0, 0, 0, 0, 0
+ L"", 0, 0, 0, 0, 0
},
/* WIN98 (second edition) */
{
@@ -100,121 +96,111 @@ static const RTL_OSVERSIONINFOEXW VersionData[NB_WINDOWS_VERSIONS] =
* Win98SE: 4, 10, 0x40A08AE, " A " 4.10.2222
*/
sizeof(RTL_OSVERSIONINFOEXW), 4, 10, 0x40A08AE, VER_PLATFORM_WIN32_WINDOWS,
- {' ','A',' ',0},
- 0, 0, 0, 0, 0
+ L" A ", 0, 0, 0, 0, 0
},
/* WINME */
{
sizeof(RTL_OSVERSIONINFOEXW), 4, 90, 0x45A0BB8, VER_PLATFORM_WIN32_WINDOWS,
- {' ',0},
- 0, 0, 0, 0, 0
+ L" ", 0, 0, 0, 0, 0
},
/* NT351 */
{
sizeof(RTL_OSVERSIONINFOEXW), 3, 51, 0x421, VER_PLATFORM_WIN32_NT,
- {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','5',0},
- 5, 0, 0, VER_NT_WORKSTATION, 0
+ L"Service Pack 5", 5, 0, 0, VER_NT_WORKSTATION, 0
},
/* NT40 */
{
sizeof(RTL_OSVERSIONINFOEXW), 4, 0, 0x565, VER_PLATFORM_WIN32_NT,
- {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','6','a',0},
- 6, 0, 0, VER_NT_WORKSTATION, 0
+ L"Service Pack 6a", 6, 0, 0, VER_NT_WORKSTATION, 0
},
/* NT2K */
{
sizeof(RTL_OSVERSIONINFOEXW), 5, 0, 0x893, VER_PLATFORM_WIN32_NT,
- {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','4',0},
- 4, 0, 0, VER_NT_WORKSTATION, 30 /* FIXME: Great, a reserved field with a value! */
+ L"Service Pack 4", 4, 0, 0, VER_NT_WORKSTATION,
+ 30 /* FIXME: Great, a reserved field with a value! */
},
/* WINXP */
{
sizeof(RTL_OSVERSIONINFOEXW), 5, 1, 0xA28, VER_PLATFORM_WIN32_NT,
- {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','3',0},
- 3, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 30 /* FIXME: Great, a reserved field with a value! */
+ L"Service Pack 3", 3, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION,
+ 30 /* FIXME: Great, a reserved field with a value! */
},
/* WINXP64 */
{
sizeof(RTL_OSVERSIONINFOEXW), 5, 2, 0xECE, VER_PLATFORM_WIN32_NT,
- {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','2',0},
- 2, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
+ L"Service Pack 2", 2, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
},
/* WIN2K3 */
{
sizeof(RTL_OSVERSIONINFOEXW), 5, 2, 0xECE, VER_PLATFORM_WIN32_NT,
- {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','2',0},
- 2, 0, VER_SUITE_SINGLEUSERTS, VER_NT_SERVER, 0
+ L"Service Pack 2", 2, 0, VER_SUITE_SINGLEUSERTS, VER_NT_SERVER, 0
},
/* WINVISTA */
{
sizeof(RTL_OSVERSIONINFOEXW), 6, 0, 0x1772, VER_PLATFORM_WIN32_NT,
- {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','2',0},
- 2, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
+ L"Service Pack 2", 2, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
},
/* WIN2K8 */
{
sizeof(RTL_OSVERSIONINFOEXW), 6, 0, 0x1772, VER_PLATFORM_WIN32_NT,
- {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','2',0},
- 2, 0, VER_SUITE_SINGLEUSERTS, VER_NT_SERVER, 0
+ L"Service Pack 2", 2, 0, VER_SUITE_SINGLEUSERTS, VER_NT_SERVER, 0
},
/* WIN7 */
{
sizeof(RTL_OSVERSIONINFOEXW), 6, 1, 0x1DB1, VER_PLATFORM_WIN32_NT,
- {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','1',0},
- 1, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
+ L"Service Pack 1", 1, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
},
/* WIN2K8R2 */
{
sizeof(RTL_OSVERSIONINFOEXW), 6, 1, 0x1DB1, VER_PLATFORM_WIN32_NT,
- {'S','e','r','v','i','c','e',' ','P','a','c','k',' ','1',0},
- 1, 0, VER_SUITE_SINGLEUSERTS, VER_NT_SERVER, 0
+ L"Service Pack 1", 1, 0, VER_SUITE_SINGLEUSERTS, VER_NT_SERVER, 0
},
/* WIN8 */
{
sizeof(RTL_OSVERSIONINFOEXW), 6, 2, 0x23F0, VER_PLATFORM_WIN32_NT,
- {0}, 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
+ L"", 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
},
/* WIN81 */
{
sizeof(RTL_OSVERSIONINFOEXW), 6, 3, 0x2580, VER_PLATFORM_WIN32_NT,
- {0}, 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
+ L"", 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
},
/* WIN10 */
{
sizeof(RTL_OSVERSIONINFOEXW), 10, 0, 0x4563, VER_PLATFORM_WIN32_NT,
- {0}, 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
+ L"", 0, 0, VER_SUITE_SINGLEUSERTS, VER_NT_WORKSTATION, 0
},
};
static const struct { WCHAR name[12]; WINDOWS_VERSION ver; } version_names[] =
{
- { {'w','i','n','2','0',0}, WIN20 },
- { {'w','i','n','3','0',0}, WIN30 },
- { {'w','i','n','3','1',0}, WIN31 },
- { {'w','i','n','9','5',0}, WIN95 },
- { {'w','i','n','9','8',0}, WIN98 },
- { {'w','i','n','m','e',0}, WINME },
- { {'n','t','3','5','1',0}, NT351 },
- { {'n','t','4','0',0}, NT40 },
- { {'w','i','n','2','0','0','0',0}, NT2K },
- { {'w','i','n','2','k',0}, NT2K },
- { {'n','t','2','k',0}, NT2K },
- { {'n','t','2','0','0','0',0}, NT2K },
- { {'w','i','n','x','p',0}, WINXP },
- { {'w','i','n','x','p','6','4',0}, WINXP64 },
- { {'w','i','n','2','0','0','3',0}, WIN2K3 },
- { {'w','i','n','2','k','3',0}, WIN2K3 },
- { {'v','i','s','t','a',0}, WINVISTA },
- { {'w','i','n','v','i','s','t','a',0}, WINVISTA },
- { {'w','i','n','2','0','0','8',0}, WIN2K8 },
- { {'w','i','n','2','k','8',0}, WIN2K8 },
- { {'w','i','n','2','0','0','8','r','2',0}, WIN2K8R2 },
- { {'w','i','n','2','k','8','r','2',0}, WIN2K8R2 },
- { {'w','i','n','7',0}, WIN7 },
- { {'w','i','n','8',0}, WIN8 },
- { {'w','i','n','8','1',0}, WIN81 },
- { {'w','i','n','1','0',0}, WIN10 },
+ { L"win20", WIN20 },
+ { L"win30", WIN30 },
+ { L"win31", WIN31 },
+ { L"win95", WIN95 },
+ { L"win98", WIN98 },
+ { L"winme", WINME },
+ { L"nt351", NT351 },
+ { L"nt40", NT40 },
+ { L"win2000", NT2K },
+ { L"win2k", NT2K },
+ { L"nt2k", NT2K },
+ { L"nt2000", NT2K },
+ { L"winxp", WINXP },
+ { L"winxp64", WINXP64 },
+ { L"win2003", WIN2K3 },
+ { L"win2k3", WIN2K3 },
+ { L"vista", WINVISTA },
+ { L"winvista", WINVISTA },
+ { L"win2008", WIN2K8 },
+ { L"win2k8", WIN2K8 },
+ { L"win2008r2", WIN2K8R2 },
+ { L"win2k8r2", WIN2K8R2 },
+ { L"win7", WIN7 },
+ { L"win8", WIN8 },
+ { L"win81", WIN81 },
+ { L"win10", WIN10 },
};
@@ -229,29 +215,6 @@ static const RTL_OSVERSIONINFOEXW *current_version;
*/
static BOOL get_nt_registry_version( RTL_OSVERSIONINFOEXW *version )
{
- static const WCHAR version_keyW[] = {'M','a','c','h','i','n','e','\\',
- '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',0};
- static const WCHAR service_pack_keyW[] = {'M','a','c','h','i','n','e','\\',
- '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','\\',
- 'W','i','n','d','o','w','s',0};
- static const WCHAR product_keyW[] = {'M','a','c','h','i','n','e','\\',
- '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','o','d','u','c','t','O','p','t','i','o','n','s',0};
- static const WCHAR CurrentBuildNumberW[] = {'C','u','r','r','e','n','t','B','u','i','l','d','N','u','m','b','e','r',0};
- static const WCHAR CSDVersionW[] = {'C','S','D','V','e','r','s','i','o','n',0};
- static const WCHAR CurrentVersionW[] = {'C','u','r','r','e','n','t','V','e','r','s','i','o','n',0};
- static const WCHAR ProductTypeW[] = {'P','r','o','d','u','c','t','T','y','p','e',0};
- static const WCHAR WinNTW[] = {'W','i','n','N','T',0};
- static const WCHAR ServerNTW[] = {'S','e','r','v','e','r','N','T',0};
- static const WCHAR LanmanNTW[] = {'L','a','n','m','a','n','N','T',0};
-
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW, valueW;
HANDLE hkey, hkey2;
@@ -266,13 +229,13 @@ static BOOL get_nt_registry_version( RTL_OSVERSIONINFOEXW *version )
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
- RtlInitUnicodeString( &nameW, version_keyW );
+ RtlInitUnicodeString( &nameW, L"Machine\\Software\\Microsoft\\Windows NT\\CurrentVersion" );
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) return FALSE;
memset( version, 0, sizeof(*version) );
- RtlInitUnicodeString( &valueW, CurrentVersionW );
+ RtlInitUnicodeString( &valueW, L"CurrentVersion" );
if (!NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp)-1, &count ))
{
WCHAR *p, *str = (WCHAR *)info->Data;
@@ -293,7 +256,7 @@ static BOOL get_nt_registry_version( RTL_OSVERSIONINFOEXW *version )
/* get build number */
- RtlInitUnicodeString( &valueW, CurrentBuildNumberW );
+ RtlInitUnicodeString( &valueW, L"CurrentBuildNumber" );
if (!NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp)-1, &count ))
{
WCHAR *str = (WCHAR *)info->Data;
@@ -303,7 +266,7 @@ static BOOL get_nt_registry_version( RTL_OSVERSIONINFOEXW *version )
/* get version description */
- RtlInitUnicodeString( &valueW, CSDVersionW );
+ RtlInitUnicodeString( &valueW, L"CSDVersion" );
if (!NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp)-1, &count ))
{
DWORD len = min( info->DataLength, sizeof(version->szCSDVersion) - sizeof(WCHAR) );
@@ -313,10 +276,10 @@ static BOOL get_nt_registry_version( RTL_OSVERSIONINFOEXW *version )
/* get service pack version */
- RtlInitUnicodeString( &nameW, service_pack_keyW );
+ RtlInitUnicodeString( &nameW, L"Machine\\System\\CurrentControlSet\\Control\\Windows" );
if (!NtOpenKey( &hkey2, KEY_ALL_ACCESS, &attr ))
{
- RtlInitUnicodeString( &valueW, CSDVersionW );
+ RtlInitUnicodeString( &valueW, L"CSDVersion" );
if (!NtQueryValueKey( hkey2, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp), &count ))
{
if (info->DataLength >= sizeof(DWORD))
@@ -331,17 +294,17 @@ static BOOL get_nt_registry_version( RTL_OSVERSIONINFOEXW *version )
/* get product type */
- RtlInitUnicodeString( &nameW, product_keyW );
+ RtlInitUnicodeString( &nameW, L"Machine\\System\\CurrentControlSet\\Control\\ProductOptions" );
if (!NtOpenKey( &hkey2, KEY_ALL_ACCESS, &attr ))
{
- RtlInitUnicodeString( &valueW, ProductTypeW );
+ RtlInitUnicodeString( &valueW, L"ProductType" );
if (!NtQueryValueKey( hkey2, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp)-1, &count ))
{
WCHAR *str = (WCHAR *)info->Data;
str[info->DataLength / sizeof(WCHAR)] = 0;
- if (!wcsicmp( str, WinNTW )) version->wProductType = VER_NT_WORKSTATION;
- else if (!wcsicmp( str, LanmanNTW )) version->wProductType = VER_NT_DOMAIN_CONTROLLER;
- else if (!wcsicmp( str, ServerNTW )) version->wProductType = VER_NT_SERVER;
+ if (!wcsicmp( str, L"WinNT" )) version->wProductType = VER_NT_WORKSTATION;
+ else if (!wcsicmp( str, L"LanmanNT" )) version->wProductType = VER_NT_DOMAIN_CONTROLLER;
+ else if (!wcsicmp( str, L"ServerNT" )) version->wProductType = VER_NT_SERVER;
}
NtClose( hkey2 );
}
@@ -361,14 +324,6 @@ static BOOL get_nt_registry_version( RTL_OSVERSIONINFOEXW *version )
*/
static BOOL get_win9x_registry_version( RTL_OSVERSIONINFOEXW *version )
{
- static const WCHAR version_keyW[] = {'M','a','c','h','i','n','e','\\',
- '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',0};
- static const WCHAR VersionNumberW[] = {'V','e','r','s','i','o','n','N','u','m','b','e','r',0};
- static const WCHAR SubVersionNumberW[] = {'S','u','b','V','e','r','s','i','o','n','N','u','m','b','e','r',0};
-
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW, valueW;
HANDLE hkey;
@@ -383,13 +338,13 @@ static BOOL get_win9x_registry_version( RTL_OSVERSIONINFOEXW *version )
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
- RtlInitUnicodeString( &nameW, version_keyW );
+ RtlInitUnicodeString( &nameW, L"Machine\\Software\\Microsoft\\Windows\\CurrentVersion" );
if (NtOpenKey( &hkey, KEY_ALL_ACCESS, &attr )) return FALSE;
memset( version, 0, sizeof(*version) );
- RtlInitUnicodeString( &valueW, VersionNumberW );
+ RtlInitUnicodeString( &valueW, L"VersionNumber" );
if (!NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp)-1, &count ))
{
WCHAR *p, *str = (WCHAR *)info->Data;
@@ -417,7 +372,7 @@ static BOOL get_win9x_registry_version( RTL_OSVERSIONINFOEXW *version )
ret = TRUE;
version->dwPlatformId = VER_PLATFORM_WIN32_WINDOWS;
- RtlInitUnicodeString( &valueW, SubVersionNumberW );
+ RtlInitUnicodeString( &valueW, L"SubVersionNumber" );
if (!NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp)-1, &count ))
{
DWORD len = min( info->DataLength, sizeof(version->szCSDVersion) - sizeof(WCHAR) );
@@ -438,14 +393,12 @@ static BOOL get_win9x_registry_version( RTL_OSVERSIONINFOEXW *version )
*/
static BOOL parse_win_version( HANDLE hkey )
{
- static const WCHAR VersionW[] = {'V','e','r','s','i','o','n',0};
-
UNICODE_STRING valueW;
WCHAR *name, tmp[64];
KEY_VALUE_PARTIAL_INFORMATION *info = (KEY_VALUE_PARTIAL_INFORMATION *)tmp;
DWORD i, count;
- RtlInitUnicodeString( &valueW, VersionW );
+ RtlInitUnicodeString( &valueW, L"Version" );
if (NtQueryValueKey( hkey, &valueW, KeyValuePartialInformation, tmp, sizeof(tmp) - sizeof(WCHAR), &count ))
return FALSE;
@@ -470,8 +423,6 @@ static BOOL parse_win_version( HANDLE hkey )
*/
void version_init(void)
{
- static const WCHAR configW[] = {'S','o','f','t','w','a','r','e','\\','W','i','n','e',0};
- static const WCHAR appdefaultsW[] = {'A','p','p','D','e','f','a','u','l','t','s','\\',0};
OBJECT_ATTRIBUTES attr;
UNICODE_STRING nameW;
HANDLE root, hkey, config_key;
@@ -488,7 +439,7 @@ void version_init(void)
attr.Attributes = 0;
attr.SecurityDescriptor = NULL;
attr.SecurityQualityOfService = NULL;
- RtlInitUnicodeString( &nameW, configW );
+ RtlInitUnicodeString( &nameW, L"Software\\Wine" );
/* @@ Wine registry key: HKCU\Software\Wine */
if (NtOpenKey( &config_key, KEY_ALL_ACCESS, &attr )) config_key = 0;
@@ -500,7 +451,7 @@ void version_init(void)
if ((p = wcsrchr( appname, '/' ))) appname = p + 1;
if ((p = wcsrchr( appname, '\\' ))) appname = p + 1;
- wcscpy( appversion, appdefaultsW );
+ wcscpy( appversion, L"AppDefaults\\" );
wcscat( appversion, appname );
RtlInitUnicodeString( &nameW, appversion );
attr.RootDirectory = config_key;
--
2.26.2
Dec. 3, 2020
[PATCH 2/2] ntdll: Use wide-char string literals in actctx.c.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/ntdll/actctx.c | 532 ++++++++++++++++----------------------------
1 file changed, 194 insertions(+), 338 deletions(-)
diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c
index faccd21d4b1..5db464a383e 100644
--- a/dlls/ntdll/actctx.c
+++ b/dlls/ntdll/actctx.c
@@ -565,125 +565,25 @@ struct actctx_loader
static const xmlstr_t empty_xmlstr;
#ifdef __i386__
-static const WCHAR current_archW[] = {'x','8','6',0};
+static const WCHAR current_archW[] = L"x86";
#elif defined __x86_64__
-static const WCHAR current_archW[] = {'a','m','d','6','4',0};
+static const WCHAR current_archW[] = L"amd64";
#elif defined __arm__
-static const WCHAR current_archW[] = {'a','r','m',0};
+static const WCHAR current_archW[] = L"arm";
#elif defined __aarch64__
-static const WCHAR current_archW[] = {'a','r','m','6','4',0};
+static const WCHAR current_archW[] = L"arm64";
#else
-static const WCHAR current_archW[] = {'n','o','n','e',0};
+static const WCHAR current_archW[] = L"none";
#endif
-static const WCHAR asmv1W[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','a','s','m','.','v','1',0};
-static const WCHAR asmv2W[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','a','s','m','.','v','2',0};
-static const WCHAR asmv3W[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','a','s','m','.','v','3',0};
-static const WCHAR assemblyW[] = {'a','s','s','e','m','b','l','y',0};
-static const WCHAR assemblyIdentityW[] = {'a','s','s','e','m','b','l','y','I','d','e','n','t','i','t','y',0};
-static const WCHAR bindingRedirectW[] = {'b','i','n','d','i','n','g','R','e','d','i','r','e','c','t',0};
-static const WCHAR clrClassW[] = {'c','l','r','C','l','a','s','s',0};
-static const WCHAR clrSurrogateW[] = {'c','l','r','S','u','r','r','o','g','a','t','e',0};
-static const WCHAR comClassW[] = {'c','o','m','C','l','a','s','s',0};
-static const WCHAR comInterfaceExternalProxyStubW[] = {'c','o','m','I','n','t','e','r','f','a','c','e','E','x','t','e','r','n','a','l','P','r','o','x','y','S','t','u','b',0};
-static const WCHAR comInterfaceProxyStubW[] = {'c','o','m','I','n','t','e','r','f','a','c','e','P','r','o','x','y','S','t','u','b',0};
-static const WCHAR dependencyW[] = {'d','e','p','e','n','d','e','n','c','y',0};
-static const WCHAR dependentAssemblyW[] = {'d','e','p','e','n','d','e','n','t','A','s','s','e','m','b','l','y',0};
-static const WCHAR descriptionW[] = {'d','e','s','c','r','i','p','t','i','o','n',0};
-static const WCHAR fileW[] = {'f','i','l','e',0};
-static const WCHAR hashW[] = {'h','a','s','h',0};
-static const WCHAR noInheritW[] = {'n','o','I','n','h','e','r','i','t',0};
-static const WCHAR noInheritableW[] = {'n','o','I','n','h','e','r','i','t','a','b','l','e',0};
-static const WCHAR typelibW[] = {'t','y','p','e','l','i','b',0};
-static const WCHAR windowClassW[] = {'w','i','n','d','o','w','C','l','a','s','s',0};
-
-static const WCHAR clsidW[] = {'c','l','s','i','d',0};
-static const WCHAR hashalgW[] = {'h','a','s','h','a','l','g',0};
-static const WCHAR helpdirW[] = {'h','e','l','p','d','i','r',0};
-static const WCHAR iidW[] = {'i','i','d',0};
-static const WCHAR languageW[] = {'l','a','n','g','u','a','g','e',0};
-static const WCHAR manifestVersionW[] = {'m','a','n','i','f','e','s','t','V','e','r','s','i','o','n',0};
-static const WCHAR nameW[] = {'n','a','m','e',0};
-static const WCHAR neutralW[] = {'n','e','u','t','r','a','l',0};
-static const WCHAR newVersionW[] = {'n','e','w','V','e','r','s','i','o','n',0};
-static const WCHAR oldVersionW[] = {'o','l','d','V','e','r','s','i','o','n',0};
-static const WCHAR optionalW[] = {'o','p','t','i','o','n','a','l',0};
-static const WCHAR processorArchitectureW[] = {'p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e',0};
-static const WCHAR progidW[] = {'p','r','o','g','i','d',0};
-static const WCHAR publicKeyTokenW[] = {'p','u','b','l','i','c','K','e','y','T','o','k','e','n',0};
-static const WCHAR threadingmodelW[] = {'t','h','r','e','a','d','i','n','g','M','o','d','e','l',0};
-static const WCHAR tlbidW[] = {'t','l','b','i','d',0};
-static const WCHAR typeW[] = {'t','y','p','e',0};
-static const WCHAR versionW[] = {'v','e','r','s','i','o','n',0};
-static const WCHAR xmlnsW[] = {'x','m','l','n','s',0};
-static const WCHAR versionedW[] = {'v','e','r','s','i','o','n','e','d',0};
-static const WCHAR yesW[] = {'y','e','s',0};
-static const WCHAR noW[] = {'n','o',0};
-static const WCHAR restrictedW[] = {'R','E','S','T','R','I','C','T','E','D',0};
-static const WCHAR controlW[] = {'C','O','N','T','R','O','L',0};
-static const WCHAR hiddenW[] = {'H','I','D','D','E','N',0};
-static const WCHAR hasdiskimageW[] = {'H','A','S','D','I','S','K','I','M','A','G','E',0};
-static const WCHAR flagsW[] = {'f','l','a','g','s',0};
-static const WCHAR miscstatusW[] = {'m','i','s','c','S','t','a','t','u','s',0};
-static const WCHAR miscstatusiconW[] = {'m','i','s','c','S','t','a','t','u','s','I','c','o','n',0};
-static const WCHAR miscstatuscontentW[] = {'m','i','s','c','S','t','a','t','u','s','C','o','n','t','e','n','t',0};
-static const WCHAR miscstatusthumbnailW[] = {'m','i','s','c','S','t','a','t','u','s','T','h','u','m','b','n','a','i','l',0};
-static const WCHAR miscstatusdocprintW[] = {'m','i','s','c','S','t','a','t','u','s','D','o','c','P','r','i','n','t',0};
-static const WCHAR baseInterfaceW[] = {'b','a','s','e','I','n','t','e','r','f','a','c','e',0};
-static const WCHAR nummethodsW[] = {'n','u','m','M','e','t','h','o','d','s',0};
-static const WCHAR proxyStubClsid32W[] = {'p','r','o','x','y','S','t','u','b','C','l','s','i','d','3','2',0};
-static const WCHAR runtimeVersionW[] = {'r','u','n','t','i','m','e','V','e','r','s','i','o','n',0};
-static const WCHAR mscoreeW[] = {'M','S','C','O','R','E','E','.','D','L','L',0};
-static const WCHAR mscoree2W[] = {'m','s','c','o','r','e','e','.','d','l','l',0};
-
-static const WCHAR activatewhenvisibleW[] = {'a','c','t','i','v','a','t','e','w','h','e','n','v','i','s','i','b','l','e',0};
-static const WCHAR actslikebuttonW[] = {'a','c','t','s','l','i','k','e','b','u','t','t','o','n',0};
-static const WCHAR actslikelabelW[] = {'a','c','t','s','l','i','k','e','l','a','b','e','l',0};
-static const WCHAR alignableW[] = {'a','l','i','g','n','a','b','l','e',0};
-static const WCHAR alwaysrunW[] = {'a','l','w','a','y','s','r','u','n',0};
-static const WCHAR canlinkbyole1W[] = {'c','a','n','l','i','n','k','b','y','o','l','e','1',0};
-static const WCHAR cantlinkinsideW[] = {'c','a','n','t','l','i','n','k','i','n','s','i','d','e',0};
-static const WCHAR ignoreactivatewhenvisibleW[] = {'i','g','n','o','r','e','a','c','t','i','v','a','t','e','w','h','e','n','v','i','s','i','b','l','e',0};
-static const WCHAR imemodeW[] = {'i','m','e','m','o','d','e',0};
-static const WCHAR insertnotreplaceW[] = {'i','n','s','e','r','t','n','o','t','r','e','p','l','a','c','e',0};
-static const WCHAR insideoutW[] = {'i','n','s','i','d','e','o','u','t',0};
-static const WCHAR invisibleatruntimeW[] = {'i','n','v','i','s','i','b','l','e','a','t','r','u','n','t','i','m','e',0};
-static const WCHAR islinkobjectW[] = {'i','s','l','i','n','k','o','b','j','e','c','t',0};
-static const WCHAR nouiactivateW[] = {'n','o','u','i','a','c','t','i','v','a','t','e',0};
-static const WCHAR onlyiconicW[] = {'o','n','l','y','i','c','o','n','i','c',0};
-static const WCHAR recomposeonresizeW[] = {'r','e','c','o','m','p','o','s','e','o','n','r','e','s','i','z','e',0};
-static const WCHAR renderingisdeviceindependentW[] = {'r','e','n','d','e','r','i','n','g','i','s','d','e','v','i','c','e','i','n','d','e','p','e','n','d','e','n','t',0};
-static const WCHAR setclientsitefirstW[] = {'s','e','t','c','l','i','e','n','t','s','i','t','e','f','i','r','s','t',0};
-static const WCHAR simpleframeW[] = {'s','i','m','p','l','e','f','r','a','m','e',0};
-static const WCHAR staticW[] = {'s','t','a','t','i','c',0};
-static const WCHAR supportsmultilevelundoW[] = {'s','u','p','p','o','r','t','s','m','u','l','t','i','l','e','v','e','l','u','n','d','o',0};
-static const WCHAR wantstomenumergeW[] = {'w','a','n','t','s','t','o','m','e','n','u','m','e','r','g','e',0};
-
-static const WCHAR compatibilityW[] = {'c','o','m','p','a','t','i','b','i','l','i','t','y',0};
-static const WCHAR compatibilityNSW[] = {'u','r','n',':','s','c','h','e','m','a','s','-','m','i','c','r','o','s','o','f','t','-','c','o','m',':','c','o','m','p','a','t','i','b','i','l','i','t','y','.','v','1',0};
-static const WCHAR applicationW[] = {'a','p','p','l','i','c','a','t','i','o','n',0};
-static const WCHAR supportedOSW[] = {'s','u','p','p','o','r','t','e','d','O','S',0};
-static const WCHAR IdW[] = {'I','d',0};
-static const WCHAR requestedExecutionLevelW[] = {'r','e','q','u','e','s','t','e','d','E','x','e','c','u','t','i','o','n','L','e','v','e','l',0};
-static const WCHAR requestedPrivilegesW[] = {'r','e','q','u','e','s','t','e','d','P','r','i','v','i','l','e','g','e','s',0};
-static const WCHAR securityW[] = {'s','e','c','u','r','i','t','y',0};
-static const WCHAR trustInfoW[] = {'t','r','u','s','t','I','n','f','o',0};
-static const WCHAR windowsSettingsW[] = {'w','i','n','d','o','w','s','S','e','t','t','i','n','g','s',0};
-static const WCHAR autoElevateW[] = {'a','u','t','o','E','l','e','v','a','t','e',0};
-static const WCHAR disableThemingW[] = {'d','i','s','a','b','l','e','T','h','e','m','i','n','g',0};
-static const WCHAR disableWindowFilteringW[] = {'d','i','s','a','b','l','e','W','i','n','d','o','w','F','i','l','t','e','r','i','n','g',0};
-static const WCHAR windowsSettings2005NSW[] = {'h','t','t','p',':','/','/','s','c','h','e','m','a','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','S','M','I','/','2','0','0','5','/','W','i','n','d','o','w','s','S','e','t','t','i','n','g','s',0};
-static const WCHAR windowsSettings2011NSW[] = {'h','t','t','p',':','/','/','s','c','h','e','m','a','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','S','M','I','/','2','0','1','1','/','W','i','n','d','o','w','s','S','e','t','t','i','n','g','s',0};
-static const WCHAR windowsSettings2016NSW[] = {'h','t','t','p',':','/','/','s','c','h','e','m','a','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','S','M','I','/','2','0','1','6','/','W','i','n','d','o','w','s','S','e','t','t','i','n','g','s',0};
-static const WCHAR windowsSettings2017NSW[] = {'h','t','t','p',':','/','/','s','c','h','e','m','a','s','.','m','i','c','r','o','s','o','f','t','.','c','o','m','/','S','M','I','/','2','0','1','7','/','W','i','n','d','o','w','s','S','e','t','t','i','n','g','s',0};
-static const WCHAR dpiAwareW[] = {'d','p','i','A','w','a','r','e',0};
-static const WCHAR dpiAwarenessW[] = {'d','p','i','A','w','a','r','e','n','e','s','s',0};
-static const WCHAR gdiScalingW[] = {'g','d','i','S','c','a','l','i','n','g',0};
-static const WCHAR highResolutionScrollingAwareW[] = {'h','i','g','h','R','e','s','o','l','u','t','i','o','n','S','c','r','o','l','l','i','n','g','A','w','a','r','e',0};
-static const WCHAR longPathAwareW[] = {'l','o','n','g','P','a','t','h','A','w','a','r','e',0};
-static const WCHAR magicFutureSettingW[] = {'m','a','g','i','c','F','u','t','u','r','e','S','e','t','t','i','n','g',0};
-static const WCHAR printerDriverIsolationW[] = {'p','r','i','n','t','e','r','D','r','i','v','e','r','I','s','o','l','a','t','i','o','n',0};
-static const WCHAR ultraHighResolutionScrollingAwareW[] = {'u','l','t','r','a','H','i','g','h','R','e','s','o','l','u','t','i','o','n','S','c','r','o','l','l','i','n','g','A','w','a','r','e',0};
+static const WCHAR asmv1W[] = L"urn:schemas-microsoft-com:asm.v1";
+static const WCHAR asmv2W[] = L"urn:schemas-microsoft-com:asm.v2";
+static const WCHAR asmv3W[] = L"urn:schemas-microsoft-com:asm.v3";
+static const WCHAR compatibilityNSW[] = L"urn:schemas-microsoft-com:compatibility.v1";
+static const WCHAR windowsSettings2005NSW[] = L"http://schemas.microsoft.com/SMI/2005/WindowsSettings";
+static const WCHAR windowsSettings2011NSW[] = L"http://schemas.microsoft.com/SMI/2011/WindowsSettings";
+static const WCHAR windowsSettings2016NSW[] = L"http://schemas.microsoft.com/SMI/2016/WindowsSettings";
+static const WCHAR windowsSettings2017NSW[] = L"http://schemas.microsoft.com/SMI/2017/WindowsSettings";
struct olemisc_entry
{
@@ -693,35 +593,30 @@ struct olemisc_entry
static const struct olemisc_entry olemisc_values[] =
{
- { activatewhenvisibleW, OLEMISC_ACTIVATEWHENVISIBLE },
- { actslikebuttonW, OLEMISC_ACTSLIKEBUTTON },
- { actslikelabelW, OLEMISC_ACTSLIKELABEL },
- { alignableW, OLEMISC_ALIGNABLE },
- { alwaysrunW, OLEMISC_ALWAYSRUN },
- { canlinkbyole1W, OLEMISC_CANLINKBYOLE1 },
- { cantlinkinsideW, OLEMISC_CANTLINKINSIDE },
- { ignoreactivatewhenvisibleW, OLEMISC_IGNOREACTIVATEWHENVISIBLE },
- { imemodeW, OLEMISC_IMEMODE },
- { insertnotreplaceW, OLEMISC_INSERTNOTREPLACE },
- { insideoutW, OLEMISC_INSIDEOUT },
- { invisibleatruntimeW, OLEMISC_INVISIBLEATRUNTIME },
- { islinkobjectW, OLEMISC_ISLINKOBJECT },
- { nouiactivateW, OLEMISC_NOUIACTIVATE },
- { onlyiconicW, OLEMISC_ONLYICONIC },
- { recomposeonresizeW, OLEMISC_RECOMPOSEONRESIZE },
- { renderingisdeviceindependentW, OLEMISC_RENDERINGISDEVICEINDEPENDENT },
- { setclientsitefirstW, OLEMISC_SETCLIENTSITEFIRST },
- { simpleframeW, OLEMISC_SIMPLEFRAME },
- { staticW, OLEMISC_STATIC },
- { supportsmultilevelundoW, OLEMISC_SUPPORTSMULTILEVELUNDO },
- { wantstomenumergeW, OLEMISC_WANTSTOMENUMERGE }
+ { L"activatewhenvisible", OLEMISC_ACTIVATEWHENVISIBLE },
+ { L"actslikebutton", OLEMISC_ACTSLIKEBUTTON },
+ { L"actslikelabel", OLEMISC_ACTSLIKELABEL },
+ { L"alignable", OLEMISC_ALIGNABLE },
+ { L"alwaysrun", OLEMISC_ALWAYSRUN },
+ { L"canlinkbyole1", OLEMISC_CANLINKBYOLE1 },
+ { L"cantlinkinside", OLEMISC_CANTLINKINSIDE },
+ { L"ignoreactivatewhenvisible", OLEMISC_IGNOREACTIVATEWHENVISIBLE },
+ { L"imemode", OLEMISC_IMEMODE },
+ { L"insertnotreplace", OLEMISC_INSERTNOTREPLACE },
+ { L"insideout", OLEMISC_INSIDEOUT },
+ { L"invisibleatruntime", OLEMISC_INVISIBLEATRUNTIME },
+ { L"islinkobject", OLEMISC_ISLINKOBJECT },
+ { L"nouiactivate", OLEMISC_NOUIACTIVATE },
+ { L"onlyiconic", OLEMISC_ONLYICONIC },
+ { L"recomposeonresize", OLEMISC_RECOMPOSEONRESIZE },
+ { L"renderingisdeviceindependent", OLEMISC_RENDERINGISDEVICEINDEPENDENT },
+ { L"setclientsitefirst", OLEMISC_SETCLIENTSITEFIRST },
+ { L"simpleframe", OLEMISC_SIMPLEFRAME },
+ { L"static", OLEMISC_STATIC },
+ { L"supportsmultilevelundo", OLEMISC_SUPPORTSMULTILEVELUNDO },
+ { L"wantstomenumerge", OLEMISC_WANTSTOMENUMERGE }
};
-static const WCHAR xmlW[] = {'?','x','m','l',0};
-static const WCHAR dotManifestW[] = {'.','m','a','n','i','f','e','s','t',0};
-static const WCHAR version_formatW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
-static const WCHAR wildcardW[] = {'*',0};
-
static ACTIVATION_CONTEXT system_actctx = { ACTCTX_MAGIC, 1 };
static ACTIVATION_CONTEXT *process_actctx = &system_actctx;
@@ -1008,7 +903,7 @@ static BOOL is_matching_identity( const struct assembly_identity *id1,
if (id1->language && id2->language && !is_matching_string( id1->language, id2->language ))
{
- if (wcscmp( wildcardW, id1->language ) && wcscmp( wildcardW, id2->language ))
+ if (wcscmp( L"*", id1->language ) && wcscmp( L"*", id2->language ))
return FALSE;
}
if (id1->version.major != id2->version.major) return FALSE;
@@ -1078,14 +973,11 @@ static void free_depend_manifests(struct actctx_loader* acl)
static WCHAR *build_assembly_dir(struct assembly_identity* ai)
{
- static const WCHAR undW[] = {'_',0};
- static const WCHAR noneW[] = {'n','o','n','e',0};
- static const WCHAR mskeyW[] = {'d','e','a','d','b','e','e','f',0};
-
- const WCHAR *arch = ai->arch ? ai->arch : noneW;
- const WCHAR *key = ai->public_key ? ai->public_key : noneW;
- const WCHAR *lang = ai->language ? ai->language : noneW;
- const WCHAR *name = ai->name ? ai->name : noneW;
+ static const WCHAR mskeyW[] = L"deadbeef";
+ const WCHAR *arch = ai->arch ? ai->arch : L"none";
+ const WCHAR *key = ai->public_key ? ai->public_key : L"none";
+ const WCHAR *lang = ai->language ? ai->language : L"none";
+ const WCHAR *name = ai->name ? ai->name : L"none";
SIZE_T size = (wcslen(arch) + 1 + wcslen(name) + 1 + wcslen(key) + 24 + 1 +
wcslen(lang) + 1) * sizeof(WCHAR) + sizeof(mskeyW);
WCHAR *ret;
@@ -1093,16 +985,16 @@ static WCHAR *build_assembly_dir(struct assembly_identity* ai)
if (!(ret = RtlAllocateHeap( GetProcessHeap(), 0, size ))) return NULL;
wcscpy( ret, arch );
- wcscat( ret, undW );
+ wcscat( ret, L"_" );
wcscat( ret, name );
- wcscat( ret, undW );
+ wcscat( ret, L"_" );
wcscat( ret, key );
- wcscat( ret, undW );
- swprintf( ret + wcslen(ret), size - wcslen(ret), version_formatW,
+ wcscat( ret, L"_" );
+ swprintf( ret + wcslen(ret), size - wcslen(ret), L"%u.%u.%u.%u",
ai->version.major, ai->version.minor, ai->version.build, ai->version.revision );
- wcscat( ret, undW );
+ wcscat( ret, L"_" );
wcscat( ret, lang );
- wcscat( ret, undW );
+ wcscat( ret, L"_" );
wcscat( ret, mskeyW );
return ret;
}
@@ -1123,35 +1015,26 @@ static inline void append_string( WCHAR *buffer, const WCHAR *prefix, const WCHA
static WCHAR *build_assembly_id( const struct assembly_identity *ai )
{
- static const WCHAR archW[] =
- {',','p','r','o','c','e','s','s','o','r','A','r','c','h','i','t','e','c','t','u','r','e','=',0};
- static const WCHAR public_keyW[] =
- {',','p','u','b','l','i','c','K','e','y','T','o','k','e','n','=',0};
- static const WCHAR typeW[] =
- {',','t','y','p','e','=',0};
- static const WCHAR versionW[] =
- {',','v','e','r','s','i','o','n','=',0};
-
WCHAR version[64], *ret;
SIZE_T size = 0;
- swprintf( version, ARRAY_SIZE(version), version_formatW,
+ swprintf( version, ARRAY_SIZE(version), L"%u.%u.%u.%u",
ai->version.major, ai->version.minor, ai->version.build, ai->version.revision );
if (ai->name) size += wcslen(ai->name) * sizeof(WCHAR);
- if (ai->arch) size += wcslen(archW) + wcslen(ai->arch) + 2;
- if (ai->public_key) size += wcslen(public_keyW) + wcslen(ai->public_key) + 2;
- if (ai->type) size += wcslen(typeW) + wcslen(ai->type) + 2;
- size += wcslen(versionW) + wcslen(version) + 2;
+ if (ai->arch) size += wcslen(L",processorArchitecture=") + wcslen(ai->arch) + 2;
+ if (ai->public_key) size += wcslen(L",publicKeyToken=") + wcslen(ai->public_key) + 2;
+ if (ai->type) size += wcslen(L",type=") + wcslen(ai->type) + 2;
+ size += wcslen(L",version=") + wcslen(version) + 2;
if (!(ret = RtlAllocateHeap( GetProcessHeap(), 0, (size + 1) * sizeof(WCHAR) )))
return NULL;
if (ai->name) wcscpy( ret, ai->name );
else *ret = 0;
- append_string( ret, archW, ai->arch );
- append_string( ret, public_keyW, ai->public_key );
- append_string( ret, typeW, ai->type );
- append_string( ret, versionW, version );
+ append_string( ret, L",processorArchitecture=", ai->arch );
+ append_string( ret, L",publicKeyToken=", ai->public_key );
+ append_string( ret, L",type=", ai->type );
+ append_string( ret, L",version=", version );
return ret;
}
@@ -1222,15 +1105,15 @@ static BOOL set_error( xmlbuf_t *xmlbuf )
static BOOL is_xmlns_attr( const struct xml_attr *attr )
{
- const int len = wcslen( xmlnsW );
+ const int len = wcslen( L"xmlns" );
if (attr->name.len < len) return FALSE;
- if (wcsncmp( attr->name.ptr, xmlnsW, len )) return FALSE;
+ if (wcsncmp( attr->name.ptr, L"xmlns", len )) return FALSE;
return (attr->name.len == len || attr->name.ptr[len] == ':');
}
static void push_xmlns( xmlbuf_t *xmlbuf, const struct xml_attr *attr )
{
- const int len = wcslen( xmlnsW );
+ const int len = wcslen( L"xmlns" );
struct xml_attr *ns;
if (xmlbuf->ns_pos == MAX_NAMESPACES - 1)
@@ -1527,27 +1410,27 @@ static void parse_assembly_identity_elem(xmlbuf_t *xmlbuf, ACTIVATION_CONTEXT *a
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, nameW))
+ if (xml_attr_cmp(&attr, L"name"))
{
if (!(ai->name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, typeW))
+ else if (xml_attr_cmp(&attr, L"type"))
{
if (!(ai->type = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, versionW))
+ else if (xml_attr_cmp(&attr, L"version"))
{
if (!parse_version(&attr.value, &ai->version)) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, processorArchitectureW))
+ else if (xml_attr_cmp(&attr, L"processorArchitecture"))
{
if (!(ai->arch = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, publicKeyTokenW))
+ else if (xml_attr_cmp(&attr, L"publicKeyToken"))
{
if (!(ai->public_key = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, languageW))
+ else if (xml_attr_cmp(&attr, L"language"))
{
if (!(ai->language = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
@@ -1565,19 +1448,14 @@ static void parse_assembly_identity_elem(xmlbuf_t *xmlbuf, ACTIVATION_CONTEXT *a
static enum comclass_threadingmodel parse_com_class_threadingmodel(xmlstr_t *value)
{
- static const WCHAR apartW[] = {'A','p','a','r','t','m','e','n','t',0};
- static const WCHAR neutralW[] = {'N','e','u','t','r','a','l',0};
- static const WCHAR freeW[] = {'F','r','e','e',0};
- static const WCHAR bothW[] = {'B','o','t','h',0};
-
if (value->len == 0) return ThreadingModel_No;
- if (xmlstr_cmp(value, apartW))
+ if (xmlstr_cmp(value, L"Apartment"))
return ThreadingModel_Apartment;
- else if (xmlstr_cmp(value, freeW))
+ else if (xmlstr_cmp(value, L"Free"))
return ThreadingModel_Free;
- else if (xmlstr_cmp(value, bothW))
+ else if (xmlstr_cmp(value, L"Both"))
return ThreadingModel_Both;
- else if (xmlstr_cmp(value, neutralW))
+ else if (xmlstr_cmp(value, L"Neutral"))
return ThreadingModel_Neutral;
else
return ThreadingModel_No;
@@ -1686,43 +1564,43 @@ static void parse_com_class_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll, st
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, clsidW))
+ if (xml_attr_cmp(&attr, L"clsid"))
{
if (!(entity->u.comclass.clsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, progidW))
+ else if (xml_attr_cmp(&attr, L"progid"))
{
if (!(entity->u.comclass.progid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, tlbidW))
+ else if (xml_attr_cmp(&attr, L"tlbid"))
{
if (!(entity->u.comclass.tlbid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, threadingmodelW))
+ else if (xml_attr_cmp(&attr, L"threadingModel"))
{
entity->u.comclass.model = parse_com_class_threadingmodel(&attr.value);
}
- else if (xml_attr_cmp(&attr, miscstatusW))
+ else if (xml_attr_cmp(&attr, L"miscStatus"))
{
entity->u.comclass.miscstatus = parse_com_class_misc(&attr.value);
}
- else if (xml_attr_cmp(&attr, miscstatuscontentW))
+ else if (xml_attr_cmp(&attr, L"miscStatusContent"))
{
entity->u.comclass.miscstatuscontent = parse_com_class_misc(&attr.value);
}
- else if (xml_attr_cmp(&attr, miscstatusthumbnailW))
+ else if (xml_attr_cmp(&attr, L"miscStatusThumbnail"))
{
entity->u.comclass.miscstatusthumbnail = parse_com_class_misc(&attr.value);
}
- else if (xml_attr_cmp(&attr, miscstatusiconW))
+ else if (xml_attr_cmp(&attr, L"miscStatusIcon"))
{
entity->u.comclass.miscstatusicon = parse_com_class_misc(&attr.value);
}
- else if (xml_attr_cmp(&attr, miscstatusdocprintW))
+ else if (xml_attr_cmp(&attr, L"miscStatusDocPrint"))
{
entity->u.comclass.miscstatusdocprint = parse_com_class_misc(&attr.value);
}
- else if (xml_attr_cmp(&attr, descriptionW))
+ else if (xml_attr_cmp(&attr, L"description"))
{
/* not stored */
}
@@ -1740,7 +1618,7 @@ static void parse_com_class_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll, st
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (xml_elem_cmp(&elem, progidW, asmv1W))
+ if (xml_elem_cmp(&elem, L"progid", asmv1W))
{
parse_com_class_progid(xmlbuf, entity, &elem);
}
@@ -1818,34 +1696,34 @@ static void parse_cominterface_proxy_stub_elem( xmlbuf_t *xmlbuf, struct dll_red
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, iidW))
+ if (xml_attr_cmp(&attr, L"iid"))
{
if (!(entity->u.ifaceps.iid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, nameW))
+ else if (xml_attr_cmp(&attr, L"name"))
{
if (!(entity->u.ifaceps.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, baseInterfaceW))
+ else if (xml_attr_cmp(&attr, L"baseInterface"))
{
if (!(entity->u.ifaceps.base = xmlstrdupW(&attr.value))) set_error( xmlbuf );
entity->u.ifaceps.mask |= BaseIface;
}
- else if (xml_attr_cmp(&attr, nummethodsW))
+ else if (xml_attr_cmp(&attr, L"numMethods"))
{
if (!(parse_nummethods(&attr.value, entity))) set_error( xmlbuf );
entity->u.ifaceps.mask |= NumMethods;
}
- else if (xml_attr_cmp(&attr, tlbidW))
+ else if (xml_attr_cmp(&attr, L"tlbid"))
{
if (!(entity->u.ifaceps.tlib = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, proxyStubClsid32W))
+ else if (xml_attr_cmp(&attr, L"proxyStubClsid32"))
{
if (!(psclsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
/* not used */
- else if (xml_attr_cmp(&attr, threadingmodelW))
+ else if (xml_attr_cmp(&attr, L"threadingModel"))
{
}
else if (!is_xmlns_attr( &attr ))
@@ -1876,13 +1754,13 @@ static BOOL parse_typelib_flags(const xmlstr_t *value, struct entity *entity)
start = str;
while (*str != ',' && (i++ < value->len)) str++;
- if (!wcsnicmp(start, restrictedW, str-start))
+ if (!wcsnicmp(start, L"RESTRICTED", str-start))
*flags |= LIBFLAG_FRESTRICTED;
- else if (!wcsnicmp(start, controlW, str-start))
+ else if (!wcsnicmp(start, L"CONTROL", str-start))
*flags |= LIBFLAG_FCONTROL;
- else if (!wcsnicmp(start, hiddenW, str-start))
+ else if (!wcsnicmp(start, L"HIDDEN", str-start))
*flags |= LIBFLAG_FHIDDEN;
- else if (!wcsnicmp(start, hasdiskimageW, str-start))
+ else if (!wcsnicmp(start, L"HASDISKIMAGE", str-start))
*flags |= LIBFLAG_FHASDISKIMAGE;
else
{
@@ -1943,19 +1821,19 @@ static void parse_typelib_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll,
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, tlbidW))
+ if (xml_attr_cmp(&attr, L"tlbid"))
{
if (!(entity->u.typelib.tlbid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, versionW))
+ else if (xml_attr_cmp(&attr, L"version"))
{
if (!parse_typelib_version(&attr.value, entity)) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, helpdirW))
+ else if (xml_attr_cmp(&attr, L"helpdir"))
{
if (!(entity->u.typelib.helpdir = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, flagsW))
+ else if (xml_attr_cmp(&attr, L"flags"))
{
if (!parse_typelib_flags(&attr.value, entity)) set_error( xmlbuf );
}
@@ -1976,12 +1854,11 @@ static inline int aligned_string_len(int len)
static int get_assembly_version(struct assembly *assembly, WCHAR *ret)
{
- static const WCHAR fmtW[] = {'%','u','.','%','u','.','%','u','.','%','u',0};
struct assembly_version *ver = &assembly->id.version;
WCHAR buff[25];
if (!ret) ret = buff;
- return swprintf(ret, ARRAY_SIZE(buff), fmtW, ver->major, ver->minor, ver->build, ver->revision);
+ return swprintf(ret, ARRAY_SIZE(buff), L"%u.%u.%u.%u", ver->major, ver->minor, ver->build, ver->revision);
}
static void parse_window_class_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll,
@@ -2001,11 +1878,11 @@ static void parse_window_class_elem( xmlbuf_t *xmlbuf, struct dll_redirect *dll,
entity->u.class.versioned = TRUE;
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, versionedW))
+ if (xml_attr_cmp(&attr, L"versioned"))
{
- if (xmlstr_cmpi(&attr.value, noW))
+ if (xmlstr_cmpi(&attr.value, L"no"))
entity->u.class.versioned = FALSE;
- else if (!xmlstr_cmpi(&attr.value, yesW))
+ else if (!xmlstr_cmpi(&attr.value, L"yes"))
set_error( xmlbuf );
}
else if (!is_xmlns_attr( &attr ))
@@ -2035,11 +1912,11 @@ static void parse_binding_redirect_elem( xmlbuf_t *xmlbuf, const struct xml_elem
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, oldVersionW))
+ if (xml_attr_cmp(&attr, L"oldVersion"))
{
FIXME("Not stored yet %s\n", debugstr_xml_attr(&attr));
}
- else if (xml_attr_cmp(&attr, newVersionW))
+ else if (xml_attr_cmp(&attr, L"newVersion"))
{
FIXME("Not stored yet %s\n", debugstr_xml_attr(&attr));
}
@@ -2093,29 +1970,29 @@ static void parse_com_interface_external_proxy_stub_elem(xmlbuf_t *xmlbuf,
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, iidW))
+ if (xml_attr_cmp(&attr, L"iid"))
{
if (!(entity->u.ifaceps.iid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, nameW))
+ else if (xml_attr_cmp(&attr, L"name"))
{
if (!(entity->u.ifaceps.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, baseInterfaceW))
+ else if (xml_attr_cmp(&attr, L"baseInterface"))
{
if (!(entity->u.ifaceps.base = xmlstrdupW(&attr.value))) set_error( xmlbuf );
entity->u.ifaceps.mask |= BaseIface;
}
- else if (xml_attr_cmp(&attr, nummethodsW))
+ else if (xml_attr_cmp(&attr, L"numMethods"))
{
if (!(parse_nummethods(&attr.value, entity))) set_error( xmlbuf );
entity->u.ifaceps.mask |= NumMethods;
}
- else if (xml_attr_cmp(&attr, proxyStubClsid32W))
+ else if (xml_attr_cmp(&attr, L"proxyStubClsid32"))
{
if (!(entity->u.ifaceps.ps32 = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, tlbidW))
+ else if (xml_attr_cmp(&attr, L"tlbid"))
{
if (!(entity->u.ifaceps.tlib = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
@@ -2146,27 +2023,27 @@ static void parse_clr_class_elem( xmlbuf_t* xmlbuf, struct assembly* assembly,
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, nameW))
+ if (xml_attr_cmp(&attr, L"name"))
{
if (!(entity->u.comclass.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, clsidW))
+ else if (xml_attr_cmp(&attr, L"clsid"))
{
if (!(entity->u.comclass.clsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, progidW))
+ else if (xml_attr_cmp(&attr, L"progid"))
{
if (!(entity->u.comclass.progid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, tlbidW))
+ else if (xml_attr_cmp(&attr, L"tlbid"))
{
if (!(entity->u.comclass.tlbid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, threadingmodelW))
+ else if (xml_attr_cmp(&attr, L"threadingModel"))
{
entity->u.comclass.model = parse_com_class_threadingmodel(&attr.value);
}
- else if (xml_attr_cmp(&attr, runtimeVersionW))
+ else if (xml_attr_cmp(&attr, L"runtimeVersion"))
{
if (!(entity->u.comclass.version = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
@@ -2183,7 +2060,7 @@ static void parse_clr_class_elem( xmlbuf_t* xmlbuf, struct assembly* assembly,
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (xml_elem_cmp(&elem, progidW, asmv1W))
+ if (xml_elem_cmp(&elem, L"progid", asmv1W))
{
parse_com_class_progid(xmlbuf, entity, &elem);
}
@@ -2213,15 +2090,15 @@ static void parse_clr_surrogate_elem( xmlbuf_t *xmlbuf, struct assembly *assembl
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, nameW))
+ if (xml_attr_cmp(&attr, L"name"))
{
if (!(entity->u.clrsurrogate.name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, clsidW))
+ else if (xml_attr_cmp(&attr, L"clsid"))
{
if (!(entity->u.clrsurrogate.clsid = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, runtimeVersionW))
+ else if (xml_attr_cmp(&attr, L"runtimeVersion"))
{
if (!(entity->u.clrsurrogate.version = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
@@ -2248,11 +2125,8 @@ static void parse_dependent_assembly_elem( xmlbuf_t *xmlbuf, struct actctx_loade
while (next_xml_attr(xmlbuf, &attr, &end))
{
- static const WCHAR allowDelayedBindingW[] = {'a','l','l','o','w','D','e','l','a','y','e','d','B','i','n','d','i','n','g',0};
- static const WCHAR trueW[] = {'t','r','u','e',0};
-
- if (xml_attr_cmp(&attr, allowDelayedBindingW))
- ai.delayed = xmlstr_cmp(&attr.value, trueW);
+ if (xml_attr_cmp(&attr, L"allowDelayedBinding"))
+ ai.delayed = xmlstr_cmp(&attr.value, L"true");
else if (!is_xmlns_attr( &attr ))
WARN("unknown attr %s\n", debugstr_xml_attr(&attr));
}
@@ -2261,11 +2135,11 @@ static void parse_dependent_assembly_elem( xmlbuf_t *xmlbuf, struct actctx_loade
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (xml_elem_cmp(&elem, assemblyIdentityW, asmv1W))
+ if (xml_elem_cmp(&elem, L"assemblyIdentity", asmv1W))
{
parse_assembly_identity_elem(xmlbuf, acl->actctx, &ai, &elem);
/* store the newly found identity for later loading */
- if (ai.arch && !wcscmp(ai.arch, wildcardW))
+ if (ai.arch && !wcscmp(ai.arch, L"*"))
{
RtlFreeHeap( GetProcessHeap(), 0, ai.arch );
ai.arch = strdupW( current_archW );
@@ -2274,7 +2148,7 @@ static void parse_dependent_assembly_elem( xmlbuf_t *xmlbuf, struct actctx_loade
debugstr_w(ai.name), debugstr_version(&ai.version), debugstr_w(ai.arch) );
if (!add_dependent_assembly_id(acl, &ai)) set_error( xmlbuf );
}
- else if (xml_elem_cmp(&elem, bindingRedirectW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"bindingRedirect", asmv1W))
{
parse_binding_redirect_elem(xmlbuf, &elem);
}
@@ -2296,9 +2170,9 @@ static void parse_dependency_elem( xmlbuf_t *xmlbuf, struct actctx_loader *acl,
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, optionalW))
+ if (xml_attr_cmp(&attr, L"optional"))
{
- optional = xmlstr_cmpi( &attr.value, yesW );
+ optional = xmlstr_cmpi( &attr.value, L"yes" );
TRACE("optional=%s\n", debugstr_xmlstr(&attr.value));
}
else if (!is_xmlns_attr( &attr ))
@@ -2311,7 +2185,7 @@ static void parse_dependency_elem( xmlbuf_t *xmlbuf, struct actctx_loader *acl,
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (xml_elem_cmp(&elem, dependentAssemblyW, asmv1W))
+ if (xml_elem_cmp(&elem, L"dependentAssembly", asmv1W))
{
parse_dependent_assembly_elem(xmlbuf, acl, &elem, optional);
}
@@ -2355,19 +2229,18 @@ static void parse_file_elem( xmlbuf_t* xmlbuf, struct assembly* assembly,
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, nameW))
+ if (xml_attr_cmp(&attr, L"name"))
{
if (!(dll->name = xmlstrdupW(&attr.value))) set_error( xmlbuf );
TRACE("name=%s\n", debugstr_xmlstr(&attr.value));
}
- else if (xml_attr_cmp(&attr, hashW))
+ else if (xml_attr_cmp(&attr, L"hash"))
{
if (!(dll->hash = xmlstrdupW(&attr.value))) set_error( xmlbuf );
}
- else if (xml_attr_cmp(&attr, hashalgW))
+ else if (xml_attr_cmp(&attr, L"hashalg"))
{
- static const WCHAR sha1W[] = {'S','H','A','1',0};
- if (!xmlstr_cmpi(&attr.value, sha1W))
+ if (!xmlstr_cmpi(&attr.value, L"SHA1"))
FIXME("hashalg should be SHA1, got %s\n", debugstr_xmlstr(&attr.value));
}
else if (!is_xmlns_attr( &attr ))
@@ -2384,24 +2257,24 @@ static void parse_file_elem( xmlbuf_t* xmlbuf, struct assembly* assembly,
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (xml_elem_cmp(&elem, comClassW, asmv1W))
+ if (xml_elem_cmp(&elem, L"comClass", asmv1W))
{
parse_com_class_elem(xmlbuf, dll, acl, &elem);
}
- else if (xml_elem_cmp(&elem, comInterfaceProxyStubW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"comInterfaceProxyStub", asmv1W))
{
parse_cominterface_proxy_stub_elem(xmlbuf, dll, acl, &elem);
}
- else if (xml_elem_cmp(&elem, hashW, asmv2W))
+ else if (xml_elem_cmp(&elem, L"hash", asmv2W))
{
WARN("asmv2:hash (undocumented) not supported\n");
parse_unknown_elem(xmlbuf, &elem);
}
- else if (xml_elem_cmp(&elem, typelibW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"typelib", asmv1W))
{
parse_typelib_elem(xmlbuf, dll, acl, &elem);
}
- else if (xml_elem_cmp(&elem, windowClassW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"windowClass", asmv1W))
{
parse_window_class_elem(xmlbuf, dll, acl, &elem);
}
@@ -2421,7 +2294,7 @@ static void parse_supportedos_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, IdW))
+ if (xml_attr_cmp(&attr, L"Id"))
{
COMPATIBILITY_CONTEXT_ELEMENT *compat;
UNICODE_STRING str;
@@ -2460,7 +2333,7 @@ static void parse_compatibility_application_elem(xmlbuf_t *xmlbuf, struct assemb
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (xml_elem_cmp(&elem, supportedOSW, compatibilityNSW))
+ if (xml_elem_cmp(&elem, L"supportedOS", compatibilityNSW))
{
parse_supportedos_elem(xmlbuf, assembly, acl, &elem);
}
@@ -2479,7 +2352,7 @@ static void parse_compatibility_elem(xmlbuf_t *xmlbuf, struct assembly *assembly
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (xml_elem_cmp(&elem, applicationW, compatibilityNSW))
+ if (xml_elem_cmp(&elem, L"application", compatibilityNSW))
{
parse_compatibility_application_elem(xmlbuf, assembly, acl, &elem);
}
@@ -2534,17 +2407,17 @@ static void parse_windows_settings_elem( xmlbuf_t *xmlbuf, struct assembly *asse
while (next_xml_elem( xmlbuf, &elem, parent ))
{
- if (xml_elem_cmp( &elem, autoElevateW, windowsSettings2005NSW ) ||
- xml_elem_cmp( &elem, disableThemingW, windowsSettings2005NSW ) ||
- xml_elem_cmp( &elem, disableWindowFilteringW, windowsSettings2011NSW ) ||
- xml_elem_cmp( &elem, dpiAwareW, windowsSettings2005NSW ) ||
- xml_elem_cmp( &elem, dpiAwarenessW, windowsSettings2016NSW ) ||
- xml_elem_cmp( &elem, gdiScalingW, windowsSettings2017NSW ) ||
- xml_elem_cmp( &elem, highResolutionScrollingAwareW, windowsSettings2017NSW ) ||
- xml_elem_cmp( &elem, longPathAwareW, windowsSettings2016NSW ) ||
- xml_elem_cmp( &elem, magicFutureSettingW, windowsSettings2017NSW ) ||
- xml_elem_cmp( &elem, printerDriverIsolationW, windowsSettings2011NSW ) ||
- xml_elem_cmp( &elem, ultraHighResolutionScrollingAwareW, windowsSettings2017NSW ))
+ if (xml_elem_cmp( &elem, L"autoElevate", windowsSettings2005NSW ) ||
+ xml_elem_cmp( &elem, L"disableTheming", windowsSettings2005NSW ) ||
+ xml_elem_cmp( &elem, L"disableWindowFiltering", windowsSettings2011NSW ) ||
+ xml_elem_cmp( &elem, L"dpiAware", windowsSettings2005NSW ) ||
+ xml_elem_cmp( &elem, L"dpiAwareness", windowsSettings2016NSW ) ||
+ xml_elem_cmp( &elem, L"gdiScaling", windowsSettings2017NSW ) ||
+ xml_elem_cmp( &elem, L"highResolutionScrollingAware", windowsSettings2017NSW ) ||
+ xml_elem_cmp( &elem, L"longPathAware", windowsSettings2016NSW ) ||
+ xml_elem_cmp( &elem, L"magicFutureSetting", windowsSettings2017NSW ) ||
+ xml_elem_cmp( &elem, L"printerDriverIsolation", windowsSettings2011NSW ) ||
+ xml_elem_cmp( &elem, L"ultraHighResolutionScrollingAware", windowsSettings2017NSW ))
{
parse_settings_elem( xmlbuf, assembly, acl, &elem );
}
@@ -2563,7 +2436,7 @@ static void parse_application_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
while (next_xml_elem( xmlbuf, &elem, parent ))
{
- if (xml_elem_cmp( &elem, windowsSettingsW, asmv3W ))
+ if (xml_elem_cmp( &elem, L"windowsSettings", asmv3W ))
{
parse_windows_settings_elem( xmlbuf, assembly, acl, &elem );
}
@@ -2578,14 +2451,6 @@ static void parse_application_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
static void parse_requested_execution_level_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
struct actctx_loader *acl, const struct xml_elem *parent )
{
- static const WCHAR levelW[] = {'l','e','v','e','l',0};
- static const WCHAR asInvokerW[] = {'a','s','I','n','v','o','k','e','r',0};
- static const WCHAR requireAdministratorW[] = {'r','e','q','u','i','r','e','A','d','m','i','n','i','s','t','r','a','t','o','r',0};
- static const WCHAR highestAvailableW[] = {'h','i','g','h','e','s','t','A','v','a','i','l','a','b','l','e',0};
- static const WCHAR uiAccessW[] = {'u','i','A','c','c','e','s','s',0};
- static const WCHAR falseW[] = {'f','a','l','s','e',0};
- static const WCHAR trueW[] = {'t','r','u','e',0};
-
struct xml_elem elem;
struct xml_attr attr;
BOOL end = FALSE;
@@ -2595,22 +2460,22 @@ static void parse_requested_execution_level_elem( xmlbuf_t *xmlbuf, struct assem
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, levelW))
+ if (xml_attr_cmp(&attr, L"level"))
{
- if (xmlstr_cmpi(&attr.value, asInvokerW))
+ if (xmlstr_cmpi(&attr.value, L"asInvoker"))
assembly->run_level = ACTCTX_RUN_LEVEL_AS_INVOKER;
- else if (xmlstr_cmpi(&attr.value, highestAvailableW))
+ else if (xmlstr_cmpi(&attr.value, L"highestAvailable"))
assembly->run_level = ACTCTX_RUN_LEVEL_HIGHEST_AVAILABLE;
- else if (xmlstr_cmpi(&attr.value, requireAdministratorW))
+ else if (xmlstr_cmpi(&attr.value, L"requireAdministrator"))
assembly->run_level = ACTCTX_RUN_LEVEL_REQUIRE_ADMIN;
else
FIXME("unknown execution level: %s\n", debugstr_xmlstr(&attr.value));
}
- else if (xml_attr_cmp(&attr, uiAccessW))
+ else if (xml_attr_cmp(&attr, L"uiAccess"))
{
- if (xmlstr_cmpi(&attr.value, falseW))
+ if (xmlstr_cmpi(&attr.value, L"false"))
assembly->ui_access = FALSE;
- else if (xmlstr_cmpi(&attr.value, trueW))
+ else if (xmlstr_cmpi(&attr.value, L"true"))
assembly->ui_access = TRUE;
else
FIXME("unknown uiAccess value: %s\n", debugstr_xmlstr(&attr.value));
@@ -2635,7 +2500,7 @@ static void parse_requested_privileges_elem( xmlbuf_t *xmlbuf, struct assembly *
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (xml_elem_cmp(&elem, requestedExecutionLevelW, asmv1W))
+ if (xml_elem_cmp(&elem, L"requestedExecutionLevel", asmv1W))
{
parse_requested_execution_level_elem(xmlbuf, assembly, acl, &elem);
}
@@ -2654,7 +2519,7 @@ static void parse_security_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (xml_elem_cmp(&elem, requestedPrivilegesW, asmv1W))
+ if (xml_elem_cmp(&elem, L"requestedPrivileges", asmv1W))
{
parse_requested_privileges_elem(xmlbuf, assembly, acl, &elem);
}
@@ -2673,7 +2538,7 @@ static void parse_trust_info_elem( xmlbuf_t *xmlbuf, struct assembly *assembly,
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (xml_elem_cmp(&elem, securityW, asmv1W))
+ if (xml_elem_cmp(&elem, L"security", asmv1W))
{
parse_security_elem(xmlbuf, assembly, acl, &elem);
}
@@ -2697,10 +2562,9 @@ static void parse_assembly_elem( xmlbuf_t *xmlbuf, struct assembly* assembly,
while (next_xml_attr(xmlbuf, &attr, &end))
{
- if (xml_attr_cmp(&attr, manifestVersionW))
+ if (xml_attr_cmp(&attr, L"manifestVersion"))
{
- static const WCHAR v10W[] = {'1','.','0',0};
- if (!xmlstr_cmp(&attr.value, v10W))
+ if (!xmlstr_cmp(&attr.value, L"1.0"))
{
FIXME("wrong version %s\n", debugstr_xmlstr(&attr.value));
break;
@@ -2721,44 +2585,44 @@ static void parse_assembly_elem( xmlbuf_t *xmlbuf, struct assembly* assembly,
while (next_xml_elem(xmlbuf, &elem, parent))
{
- if (assembly->type == APPLICATION_MANIFEST && xml_elem_cmp(&elem, noInheritW, asmv1W))
+ if (assembly->type == APPLICATION_MANIFEST && xml_elem_cmp(&elem, L"noInherit", asmv1W))
{
parse_noinherit_elem(xmlbuf, &elem);
assembly->no_inherit = TRUE;
}
- else if (xml_elem_cmp(&elem, noInheritableW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"noInheritable", asmv1W))
{
parse_noinheritable_elem(xmlbuf, &elem);
}
- else if (xml_elem_cmp(&elem, descriptionW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"description", asmv1W))
{
parse_description_elem(xmlbuf, &elem);
}
- else if (xml_elem_cmp(&elem, comInterfaceExternalProxyStubW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"comInterfaceExternalProxyStub", asmv1W))
{
parse_com_interface_external_proxy_stub_elem(xmlbuf, assembly, acl, &elem);
}
- else if (xml_elem_cmp(&elem, dependencyW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"dependency", asmv1W))
{
parse_dependency_elem(xmlbuf, acl, &elem);
}
- else if (xml_elem_cmp(&elem, fileW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"file", asmv1W))
{
parse_file_elem(xmlbuf, assembly, acl, &elem);
}
- else if (xml_elem_cmp(&elem, clrClassW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"clrClass", asmv1W))
{
parse_clr_class_elem(xmlbuf, assembly, acl, &elem);
}
- else if (xml_elem_cmp(&elem, clrSurrogateW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"clrSurrogate", asmv1W))
{
parse_clr_surrogate_elem(xmlbuf, assembly, acl, &elem);
}
- else if (xml_elem_cmp(&elem, trustInfoW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"trustInfo", asmv1W))
{
parse_trust_info_elem(xmlbuf, assembly, acl, &elem);
}
- else if (xml_elem_cmp(&elem, assemblyIdentityW, asmv1W))
+ else if (xml_elem_cmp(&elem, L"assemblyIdentity", asmv1W))
{
parse_assembly_identity_elem(xmlbuf, acl->actctx, &assembly->id, &elem);
@@ -2787,11 +2651,11 @@ static void parse_assembly_elem( xmlbuf_t *xmlbuf, struct assembly* assembly,
}
}
}
- else if (xml_elem_cmp(&elem, compatibilityW, compatibilityNSW))
+ else if (xml_elem_cmp(&elem, L"compatibility", compatibilityNSW))
{
parse_compatibility_elem(xmlbuf, assembly, acl, &elem);
}
- else if (xml_elem_cmp(&elem, applicationW, asmv3W))
+ else if (xml_elem_cmp(&elem, L"application", asmv3W))
{
parse_application_elem(xmlbuf, assembly, acl, &elem);
}
@@ -2820,11 +2684,11 @@ static NTSTATUS parse_manifest_buffer( struct actctx_loader* acl, struct assembl
if (!next_xml_elem(xmlbuf, &elem, &parent)) return STATUS_SXS_CANT_GEN_ACTCTX;
- if (xmlstr_cmp(&elem.name, xmlW) &&
+ if (xmlstr_cmp(&elem.name, L"?xml") &&
(!parse_xml_header(xmlbuf) || !next_xml_elem(xmlbuf, &elem, &parent)))
return STATUS_SXS_CANT_GEN_ACTCTX;
- if (!xml_elem_cmp(&elem, assemblyW, asmv1W))
+ if (!xml_elem_cmp(&elem, L"assembly", asmv1W))
{
FIXME("root element is %s, not <assembly>\n", debugstr_xml_elem(&elem));
return STATUS_SXS_CANT_GEN_ACTCTX;
@@ -3080,7 +2944,6 @@ static NTSTATUS get_manifest_in_manifest_file( struct actctx_loader* acl, struct
static NTSTATUS get_manifest_in_associated_manifest( struct actctx_loader* acl, struct assembly_identity* ai,
LPCWSTR filename, LPCWSTR directory, HMODULE module, LPCWSTR resname )
{
- static const WCHAR fmtW[] = { '.','%','l','u',0 };
WCHAR *buffer;
NTSTATUS status;
UNICODE_STRING nameW;
@@ -3095,10 +2958,10 @@ static NTSTATUS get_manifest_in_associated_manifest( struct actctx_loader* acl,
{
UNICODE_STRING name;
- if (!(status = get_module_filename( module, &name, sizeof(dotManifestW) + 10*sizeof(WCHAR) )))
+ if (!(status = get_module_filename( module, &name, sizeof(L".manifest") + 10*sizeof(WCHAR) )))
{
- if (resid != 1) swprintf( name.Buffer + wcslen(name.Buffer), 10, fmtW, resid );
- wcscat( name.Buffer, dotManifestW );
+ if (resid != 1) swprintf( name.Buffer + wcslen(name.Buffer), 10, L".%lu", resid );
+ wcscat( name.Buffer, L".manifest" );
if (!RtlDosPathNameToNtPathName_U( name.Buffer, &nameW, NULL, NULL ))
status = STATUS_RESOURCE_DATA_NOT_FOUND;
RtlFreeUnicodeString( &name );
@@ -3108,11 +2971,11 @@ static NTSTATUS get_manifest_in_associated_manifest( struct actctx_loader* acl,
else
{
if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0,
- (wcslen(filename) + 10) * sizeof(WCHAR) + sizeof(dotManifestW) )))
+ (wcslen(filename) + 10) * sizeof(WCHAR) + sizeof(L".manifest") )))
return STATUS_NO_MEMORY;
wcscpy( buffer, filename );
- if (resid != 1) swprintf( buffer + wcslen(buffer), 10, fmtW, resid );
- wcscat( buffer, dotManifestW );
+ if (resid != 1) swprintf( buffer + wcslen(buffer), 10, L".%lu", resid );
+ wcscat( buffer, L".manifest" );
RtlInitUnicodeString( &nameW, buffer );
}
@@ -3128,9 +2991,7 @@ static NTSTATUS get_manifest_in_associated_manifest( struct actctx_loader* acl,
static WCHAR *lookup_manifest_file( HANDLE dir, struct assembly_identity *ai )
{
- static const WCHAR lookup_fmtW[] =
- {'%','s','_','%','s','_','%','s','_','%','u','.','%','u','.','*','.','*','_',
- '%','s','_','*','.','m','a','n','i','f','e','s','t',0};
+ static const WCHAR lookup_fmtW[] = L"%s_%s_%s_%u.%u.*.*_%s_*.manifest";
static const WCHAR wine_trailerW[] = {'d','e','a','d','b','e','e','f','.','m','a','n','i','f','e','s','t'};
WCHAR *lookup, *ret = NULL;
@@ -3140,7 +3001,7 @@ static WCHAR *lookup_manifest_file( HANDLE dir, struct assembly_identity *ai )
unsigned int data_pos = 0, data_len, len;
char buffer[8192];
- if (!lang || !wcsicmp( lang, neutralW )) lang = wildcardW;
+ if (!lang || !wcsicmp( lang, L"neutral" )) lang = L"*";
len = wcslen(ai->arch) + wcslen(ai->name) + wcslen(ai->public_key) + wcslen(lang) + 20 + ARRAY_SIZE(lookup_fmtW);
if (!(lookup = RtlAllocateHeap( GetProcessHeap(), 0, len * sizeof(WCHAR) ))) return NULL;
@@ -3217,17 +3078,14 @@ static NTSTATUS lookup_winsxs(struct actctx_loader* acl, struct assembly_identit
WCHAR *path, *file = NULL;
HANDLE handle;
- static const WCHAR manifest_dirW[] =
- {'\\','w','i','n','s','x','s','\\','m','a','n','i','f','e','s','t','s',0};
-
if (!ai->arch || !ai->name || !ai->public_key) return STATUS_NO_SUCH_FILE;
- if (!(path = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(manifest_dirW) +
+ if (!(path = RtlAllocateHeap( GetProcessHeap(), 0, sizeof(L"\\winsxs\\manifests") +
wcslen(windows_dir) * sizeof(WCHAR) )))
return STATUS_NO_MEMORY;
wcscpy( path, windows_dir );
- wcscat( path, manifest_dirW );
+ wcscat( path, L"\\winsxs\\manifests" );
if (!RtlDosPathNameToNtPathName_U( path, &path_us, NULL, NULL ))
{
@@ -3285,7 +3143,6 @@ static NTSTATUS lookup_winsxs(struct actctx_loader* acl, struct assembly_identit
static NTSTATUS lookup_assembly(struct actctx_loader* acl,
struct assembly_identity* ai)
{
- static const WCHAR dotDllW[] = {'.','d','l','l',0};
unsigned int i;
WCHAR *buffer, *p, *directory;
NTSTATUS status;
@@ -3305,7 +3162,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl,
nameW.Buffer = NULL;
if (!(buffer = RtlAllocateHeap( GetProcessHeap(), 0,
- (len + 2 * wcslen(ai->name) + 2) * sizeof(WCHAR) + sizeof(dotManifestW) )))
+ (len + 2 * wcslen(ai->name) + 2) * sizeof(WCHAR) + sizeof(L".manifest") )))
return STATUS_NO_MEMORY;
if (!(directory = build_assembly_dir( ai )))
@@ -3336,7 +3193,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl,
wcscpy( p, ai->name );
p += wcslen(p);
- wcscpy( p, dotDllW );
+ wcscpy( p, L".dll" );
if (RtlDosPathNameToNtPathName_U( buffer, &nameW, NULL, NULL ))
{
status = open_nt_file( &file, &nameW );
@@ -3351,7 +3208,7 @@ static NTSTATUS lookup_assembly(struct actctx_loader* acl,
RtlFreeUnicodeString( &nameW );
}
- wcscpy( p, dotManifestW );
+ wcscpy( p, L".manifest" );
if (RtlDosPathNameToNtPathName_U( buffer, &nameW, NULL, NULL ))
{
status = open_nt_file( &file, &nameW );
@@ -3684,7 +3541,6 @@ static NTSTATUS build_wndclass_section(ACTIVATION_CONTEXT* actctx, struct strsec
struct entity *entity = &dll->entities.base[k];
if (entity->kind == ACTIVATION_CONTEXT_SECTION_WINDOW_CLASS_REDIRECTION)
{
- static const WCHAR exclW[] = {'!',0};
ULONG versioned_len, module_len;
UNICODE_STRING str;
WCHAR *ptrW;
@@ -3733,7 +3589,7 @@ static NTSTATUS build_wndclass_section(ACTIVATION_CONTEXT* actctx, struct strsec
if (entity->u.class.versioned)
{
get_assembly_version(assembly, ptrW);
- wcscat(ptrW, exclW);
+ wcscat(ptrW, L"!");
wcscat(ptrW, entity->u.class.name);
}
else
@@ -4037,7 +3893,7 @@ static void get_comserver_datalen(const struct entity_array *entities, const str
*len += aligned_string_len(str_len*sizeof(WCHAR));
/* module name is forced to mscoree.dll, and stored two times with different case */
- *module_len += sizeof(mscoreeW) + sizeof(mscoree2W);
+ *module_len += sizeof(L"MSCOREE.DLL") + sizeof(L"mscoree.dll");
}
else
{
@@ -4076,7 +3932,7 @@ static void add_comserver_record(const struct guidsection_header *section, const
else
progid_len = 0;
- module_len = dll ? wcslen(dll->name)*sizeof(WCHAR) : wcslen(mscoreeW)*sizeof(WCHAR);
+ module_len = dll ? wcslen(dll->name)*sizeof(WCHAR) : wcslen(L"MSCOREE.DLL")*sizeof(WCHAR);
/* setup new index entry */
RtlInitUnicodeString(&str, entity->u.comclass.clsid);
@@ -4142,7 +3998,7 @@ static void add_comserver_record(const struct guidsection_header *section, const
clrdata->size = sizeof(*clrdata);
clrdata->res[0] = 0;
clrdata->res[1] = 2; /* FIXME: unknown field */
- clrdata->module_len = wcslen(mscoreeW)*sizeof(WCHAR);
+ clrdata->module_len = wcslen(L"MSCOREE.DLL")*sizeof(WCHAR);
clrdata->module_offset = *module_offset + data->name_len + sizeof(WCHAR);
clrdata->name_len = wcslen(entity->u.comclass.name)*sizeof(WCHAR);
clrdata->name_offset = clrdata->size;
@@ -4155,11 +4011,11 @@ static void add_comserver_record(const struct guidsection_header *section, const
/* module name */
ptrW = (WCHAR*)((BYTE*)section + clrdata->module_offset);
- memcpy(ptrW, mscoree2W, clrdata->module_len);
+ memcpy(ptrW, L"mscoree.dll", clrdata->module_len);
ptrW[clrdata->module_len/sizeof(WCHAR)] = 0;
ptrW = (WCHAR*)((BYTE*)section + data->name_offset);
- memcpy(ptrW, mscoreeW, data->name_len);
+ memcpy(ptrW, L"MSCOREE.DLL", data->name_len);
ptrW[data->name_len/sizeof(WCHAR)] = 0;
/* class name */
--
2.26.2
Dec. 3, 2020
[PATCH 1/2] ntdll: Print the correct debug string and not a random global variable.
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/ntdll/actctx.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/actctx.c b/dlls/ntdll/actctx.c
index b99d1655d22..faccd21d4b1 100644
--- a/dlls/ntdll/actctx.c
+++ b/dlls/ntdll/actctx.c
@@ -3533,7 +3533,7 @@ static struct string_index *find_string_index(const struct strsection_header *se
break;
}
else
- WARN("hash collision 0x%08x, %s, %s\n", hash, debugstr_us(name), debugstr_w(nameW));
+ WARN("hash collision 0x%08x, %s, %s\n", hash, debugstr_us(name), debugstr_us(&str));
}
iter++;
}
@@ -3794,7 +3794,7 @@ static NTSTATUS find_window_class(ACTIVATION_CONTEXT* actctx, const UNICODE_STRI
break;
}
else
- WARN("hash collision 0x%08x, %s, %s\n", hash, debugstr_us(name), debugstr_w(nameW));
+ WARN("hash collision 0x%08x, %s, %s\n", hash, debugstr_us(name), debugstr_us(&str));
}
iter++;
}
--
2.26.2
Dec. 3, 2020
Re: [PATCH 17/17] winegstreamer: Implement Get(Input/Output)CurrentType functions for color converter 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=83080
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 16/17] winegstreamer: Implement Get*Attributes functions for color converter 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=83079
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 15/17] winegstreamer: Implement ::Get(Input/Output)StreamInfo for color 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=83078
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 14/17] winegstreamer: Implement ::ProcessMessage for color conversion MFT.
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=83077
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 13/17] winegstreamer: Implement ::Process(Input/Output) for color 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=83076
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 12/17] winegstreamer: Implement ::SetOutputType for color 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=83075
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 11/17] winegstreamer: Implement ::GetOutputAvailableType for color 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=83074
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 10/17] winegstreamer: Implement ::SetInputType for color 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=83073
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 09/17] winegstreamer: Implement ::GetInputAvailableType for color 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=83072
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 08/17] winegstreamer: Register the color 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=83071
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
error: patch failed: dlls/winegstreamer/mfplat.c:455
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 07/17] winegstreamer: Introduce color 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=83070
Your paranoid android.
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
Task: Patch failed to apply
=== debiant (build log) ===
error: patch failed: dlls/winegstreamer/Makefile.in:7
error: patch failed: dlls/winegstreamer/gst_private.h:87
error: patch failed: dlls/winegstreamer/mfplat.c:407
error: patch failed: dlls/winegstreamer/winegstreamer_classes.idl:67
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 06/17] winegstreamer: Implement Get(Input/Output)CurrentType functions for audio converter 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=83069
Your paranoid android.
=== debiant (build log) ===
Task: Patch failed to apply
=== debiant (build log) ===
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 05/17] winegstreamer: Implement Get*Attributes functions for audio converter 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=83068
Your paranoid android.
=== debiant (build log) ===
Task: Patch failed to apply
=== debiant (build log) ===
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 04/17] winegstreamer: Implement ::Get(Input/Output)StreamInfo 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=83067
Your paranoid android.
=== debiant (build log) ===
Task: Patch failed to apply
=== debiant (build log) ===
Task: Patch failed to apply
Dec. 3, 2020
Re: [PATCH 03/17] winegstreamer: Implement ::Process(Input/Output) 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=83066
Your paranoid android.
=== debiant (build log) ===
Task: Patch failed to apply
=== debiant (build log) ===
Task: Patch failed to apply
Dec. 3, 2020