Compare commits

...

27 Commits

Author SHA1 Message Date
Alistair Leslie-Hughes
857466ad4c Release v10.2 2025-02-23 08:13:03 +11:00
Alistair Leslie-Hughes
4378292a65 Rebase against 4bd044dd32818166d42a9262411a1ae7ef42cc07. 2025-02-21 09:44:20 +11:00
Alistair Leslie-Hughes
c2e4c17811 Rebase against 94dc1f470cc7adfee75cb0718e953ca1954599ef. 2025-02-20 10:50:18 +11:00
Alistair Leslie-Hughes
34a7d5e858 Updated vkd3d-latest patchset 2025-02-20 07:22:00 +11:00
Alistair Leslie-Hughes
a4e8224bd8 Rebase against a46043015322bf8e6c78a74bd33300f3478767e3. 2025-02-19 09:43:59 +11:00
Alistair Leslie-Hughes
1b224000ac Added ws2_32-af_unix patchset 2025-02-18 13:57:31 +11:00
Alistair Leslie-Hughes
2b9cd3663b Updated vkd3d-latest patchset 2025-02-18 09:01:06 +11:00
Elizabeth Figura
4901d72e77 Rebase against 59720e7d1b88ed519569135542aa55145a2a6ff7. 2025-02-17 15:39:12 -06:00
Alistair Leslie-Hughes
735225dbaa Rebase against 17915f730267b2b50550636fb6928a6ace247ccd. 2025-02-13 21:20:46 +11:00
Alistair Leslie-Hughes
7042b486e2 Rebase against 7b8663e465e92fb2c1052fd8ad47f0dcbf37a83c. 2025-02-11 11:19:10 +11:00
Dean M Greer
4ef147fbe5 macOS.yml: fix-up action 2025-02-10 23:20:41 +00:00
Alistair Leslie-Hughes
7b9777c23e Release v10.1 2025-02-09 18:37:10 +11:00
Alistair Leslie-Hughes
aed0bcfb83 Rebase against a1dddd902f21e3a5057a40cb9848351f0cbcfd82. 2025-02-09 18:37:05 +11:00
Alistair Leslie-Hughes
22f5ea5e4f Rebase against a47a9f39d1e9d19a7931cdc254a9cd68c1ed6fef. 2025-02-07 10:29:46 +11:00
Alistair Leslie-Hughes
7f5729fc14 Updated vkd3d-latest patchset 2025-02-04 10:23:08 +11:00
Alistair Leslie-Hughes
7fda13a16d Rebase against 40b0ede26e317bb994bf0b85ea37c7dab074e9f1. 2025-02-04 10:22:36 +11:00
Alistair Leslie-Hughes
667ee8a4ff Added oleaut32_VarAdd patchset 2025-01-24 20:23:21 +11:00
Alistair Leslie-Hughes
b45a0aead3 Added d2d1_ID2D1GeometryGroup patchset 2025-01-24 10:29:21 +11:00
Alistair Leslie-Hughes
36483a9c11 Added shell32_enumerableobejct patchset 2025-01-24 09:10:08 +11:00
Alistair Leslie-Hughes
28834e80f8 Added richedit20-ImportDataObject patchset 2025-01-24 08:51:23 +11:00
Alistair Leslie-Hughes
49770c6bc6 Added mf_http_support patchset 2025-01-24 07:45:00 +11:00
Alistair Leslie-Hughes
93f5b4f6a0 Added vbscript_join patchset 2025-01-24 07:44:13 +11:00
Alistair Leslie-Hughes
e452a6cbdc Added vbscript-classes patchset 2025-01-24 07:43:33 +11:00
Alistair Leslie-Hughes
23ccc2eef1 Rebase against ff2de2a73b830a601cfe26aca5feeafb309fbff5. 2025-01-23 09:01:50 +11:00
Alistair Leslie-Hughes
18f976c338 Updated vkd3d-latest patchset 2025-01-23 08:14:29 +11:00
Alistair Leslie-Hughes
05bc4b822f Release v10.0 2025-01-22 07:26:21 +11:00
Alistair Leslie-Hughes
177488c071 Updated vkd3d-latest patchset 2025-01-22 07:09:50 +11:00
53 changed files with 8221 additions and 22167 deletions

View File

@@ -20,7 +20,6 @@ jobs:
bison \
gphoto2 \
gstreamer \
gcenx/wine/libinotify-kqueue \
mingw-w64 \
molten-vk \
sdl2
@@ -44,10 +43,11 @@ jobs:
cd wine
$GITHUB_WORKSPACE/staging/patchinstall.py DESTDIR=. --all
- name: Configure wine64
- name: Configure wine
env:
LDFLAGS: "-Wl,-rpath,/opt/X11/lib"
# Avoid weird linker errors with Xcode 10 and later
# We need to tell the linker to add brew & Xquarts to the rpath stack.
LDFLAGS: "-Wl,-rpath,/usr/local/lib -Wl,-rpath,/opt/X11/lib"
# Use an older deployment target to avoid new dyld behaviors.
MACOSX_DEPLOYMENT_TARGET: "10.14"
run: |
cd $GITHUB_WORKSPACE/wine

View File

@@ -0,0 +1,267 @@
From e4d55d451648b67c9269241efce8eee63faf70a4 Mon Sep 17 00:00:00 2001
From: Philipp Knechtges <philipp-dev@knechtges.com>
Date: Fri, 13 Sep 2024 11:16:44 +0200
Subject: [PATCH] d2d1: Add tests for drawing ID2D1GeometryGroup
The functionality to draw ID2D1GeometryGroup is currently missing.
Nothing is drawn. This causes the blank pages in the bug below.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51139
---
dlls/d2d1/tests/d2d1.c | 219 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 219 insertions(+)
diff --git a/dlls/d2d1/tests/d2d1.c b/dlls/d2d1/tests/d2d1.c
index 40bcf5079b8..41b36ef0dd5 100644
--- a/dlls/d2d1/tests/d2d1.c
+++ b/dlls/d2d1/tests/d2d1.c
@@ -7061,6 +7061,7 @@ static void test_gradient(BOOL d3d11)
static void test_draw_geometry(BOOL d3d11)
{
ID2D1TransformedGeometry *transformed_geometry[4];
+ ID2D1GeometryGroup *geometry_group;
ID2D1RectangleGeometry *rect_geometry[2];
D2D1_POINT_2F point = {0.0f, 0.0f};
D2D1_ROUNDED_RECT rounded_rect;
@@ -7970,6 +7971,117 @@ static void test_draw_geometry(BOOL d3d11)
hr = ID2D1PathGeometry_Open(geometry, &sink);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ set_point(&point, -0.402914f, 0.915514f);
+ ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
+ quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
+ quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
+ quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
+ quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
+ quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
+ quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
+ quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
+ quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
+ quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
+ quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
+ quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
+ quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
+ ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
+
+ hr = ID2D1GeometrySink_Close(sink);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ID2D1GeometrySink_Release(sink);
+
+ set_matrix_identity(&matrix);
+ translate_matrix(&matrix, 40.0f, 160.0f);
+ scale_matrix(&matrix, 20.0f, 80.0f);
+ hr = ID2D1Factory_CreateTransformedGeometry(factory,
+ (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ set_matrix_identity(&matrix);
+ translate_matrix(&matrix, 160.0f, 640.0f);
+ scale_matrix(&matrix, 40.0f, 160.0f);
+ rotate_matrix(&matrix, M_PI / -5.0f);
+ hr = ID2D1Factory_CreateTransformedGeometry(factory,
+ (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ID2D1PathGeometry_Release(geometry);
+
+ set_matrix_identity(&matrix);
+ scale_matrix(&matrix, 0.5f, 1.0f);
+ translate_matrix(&matrix, -80.0f, 0.0f);
+ hr = ID2D1Factory_CreateTransformedGeometry(factory,
+ (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ set_matrix_identity(&matrix);
+ rotate_matrix(&matrix, M_PI / 2.0f);
+ translate_matrix(&matrix, 80.0f, -320.0f);
+ scale_matrix(&matrix, 2.0f, 0.25f);
+ hr = ID2D1Factory_CreateTransformedGeometry(factory,
+ (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ hr = ID2D1Factory_CreateGeometryGroup(factory, D2D1_FILL_MODE_WINDING,
+ (ID2D1Geometry**) &transformed_geometry, 4, &geometry_group);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ID2D1TransformedGeometry_Release(transformed_geometry[3]);
+ ID2D1TransformedGeometry_Release(transformed_geometry[2]);
+ ID2D1TransformedGeometry_Release(transformed_geometry[1]);
+ ID2D1TransformedGeometry_Release(transformed_geometry[0]);
+
+ ID2D1RenderTarget_BeginDraw(rt);
+ ID2D1RenderTarget_Clear(rt, &color);
+ ID2D1RenderTarget_DrawGeometry(rt, (ID2D1Geometry *)geometry_group, (ID2D1Brush *)brush, 10.0f, NULL);
+ hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ID2D1GeometryGroup_Release(geometry_group);
+
+ match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 256,
+ "iTANiwEagQEkeSp0LnIWAhZyFAYUchQGFHIUBhRyFAYUchQGFHIUBhRyFAYUchQGFHIUBhRyFAYU"
+ "cxQFFHMUBRRzFAUUcxQFFHMUBRRzFAUUcxQFFHMUBRRzFAUUcxQFFHQUBBR0FAQUdBQDFHUUAxR1"
+ "FAMUdRQDFHUUAxR1FQIUdhQCFHYUAhR2FAIUdhQCFHYUAhR2FAIUdhQBFHgoeCh4KHkmeiZ7JHwk"
+ "fSJ+In8ggAEfggEeggEdhAEchQEbhQEahwEZhwEYiQEXiQEWigEWigEWigEWiwEViwEViwEViwEV"
+ "igEXiQEXiQEXiQEYhwEZhgEbgwEefyR5KXQvbxgEGG4VBxhtMnAudCp6IoMBGOMu");
+ ok(match, "Figure does not match.\n");
+ match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 512,
+ "xpcBB7QCEqkCG6ACJJgCLI8CNYcCHgMc/gEeDBr4AR4UGPIBHR0W7AEdIxbmAR0pFt8BHTAV2gEd"
+ "MBrWARwuIdMBGiwi1gEYKiPZARYoJNwBFiQk4AEWHyWxAQQvFhsltgEKKBYWJrwBECBOwQEXF0rI"
+ "ARwOSM4Ba9UBYeABRf0BOIoCMZECLJYCKJoCJ5wCJp0CJJ8CIqICH6QCHagCGa4CFLoCB/yUAQAA");
+ ok(match, "Figure does not match.\n");
+ match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 512,
+ "yWQBnQEEmQEHlgELkwENkAEQjgETiwEVigEXhwEZhgEahQEcgwEdggEfgAEgfyF+I30jfCR8JXom"
+ "eid4KHgodxQCFHYUAhR1FAMUdBUEFHMUBRRyFQUUchQHFHEUBxRwFAgUcBQJFG4UChRuFAoUbRUL"
+ "FGwUDBRsFAwUbBQNFGwUDBRsFAwUbRQMFGwUDBRsFAwUbRQLFWwUDBRtFAsUbRQLFG0VCxRtFAsU"
+ "bRQLFG4UCxRtFAsUbhQKFG4UCxRuFAoUbhQKFG4VCRRvFAoUbhQKFG8UCRRvFAoUbxQJFG8UCRRw"
+ "FAgVbxQJFHAUCBRwFAgUcBUIFHAUCBRwFAgUcRQHFHEUBxRyFAYUchQGFHMUBRRzFAUUdBQEFHQU"
+ "BBR1FAQUdBQEFHUUAxR1FAMUdhQCFHYUAhR2FQEUdxQBFHcpeCh4KHkneSd6JnoneiZ7JXwkfSN+"
+ "In8hgAEggQEfgwEdhAEdhAEchQEbhgEahwEZiAEYGAFwGBYCcRcUBHEXEgZyFhEHchcOCXMWDAtz"
+ "FgsMdBYIDnQWBhB1FgQQdhYCEnYqdyl3KXcpeCd5J3kneSd5JnomeyR8JHwkfCN9I30ifiF/IX4h"
+ "fyF/IH8ggAEgfyCAASCAAR+AAR+BAR6CAR6BAR6CAR2CAR2DARyEARuEARuFARqGARmGARiKARSR"
+ "AQqhYwAA");
+ ok(match, "Figure does not match.\n");
+ match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 1024,
+ "ytABA7gCCbICD60CFKkCF6cCGqMCHqACIZ0CJJoCJpgCKZUCFgIUkgIWBBWPAhYHFI4CFQoUjAIV"
+ "DBSKAhUNFYgCFQ8UhwIVERSFAhUTFIMCFRQVgQIUFxSAAhQZFP4BFBoV/AEUHBT7ARQeFPkBFB8V"
+ "9wEUIRT2ARQjFPQBFSMV8gEVJRTxARUnFPABFCgV7gEUKhTtARQsFOwBFCwV7AEULBTsARUsFOwB"
+ "FSsV7AEULBTtARQsFO0BFCsU7QEVKxTtARUqFe0BFSoU7gEUKxTuARQqFe4BFCoU7wEUKhTuARUp"
+ "FO8BFSkU7wEVKBXvARUoFPABFCkU8AEUKBTxARQoFPEBFCcV8QEUJxTxARUnFPEBFSYU8gEVJhTy"
+ "ARUlFfIBFSUU8wEUJRXzARQlFPQBFCUU9AEUJBT1ARQkFPUBFCMU9gEUIhT2ARUhFPcBFSAU+AEV"
+ "HxT5ARUeFPoBFR4U+gEVHRT7ARUcFPwBFRsU/QEVGhT+ARUZFP8BFBkUgAIUGBSBAhQXFIICFBcU"
+ "ggIUFhSDAhQVFIQCFBQUhQIUExSGAhQSFIcCFBIUhwIUERSIAhUPFIkCFg0UigIXCxSNAhYJFI8C"
+ "FggUkAIXBRSSAhcDFJQCFwEUlgIrlwIpmgImnAIkngIjnwIhoQIfowIepAIcpgIbpgIaqAIZqAIZ"
+ "qAIYKwP7ARgnBf0BGCMI/QEZHgz+ARgbD/8BGBcSgAIYEhaAAhoNGIICGggcgwIaBB+DAjyEAjyF"
+ "AjqGAjmIAjiIAiECFIkCFAIIBBSKAhQNFIsCFAwUjAIUCxSNAhQKFI4CFAkUjwIUBxWQAhQGFZEC"
+ "FAUVkQIUBRWRAhQFFZECFQMVkwIUAxWTAhQDFZMCFAIVlAIVARWVAiqVAimWAimWAiiYAiaZAiaZ"
+ "AiWaAiScAiKdAiGeAh+hAhyjAhmuAg3GxgEA");
+ ok(match, "Figure does not match.\n");
+
+ hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1PathGeometry_Open(geometry, &sink);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
set_point(&point, 20.0f, 80.0f);
ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
quadratic_to(sink, 20.0f, 160.0f, 60.0f, 160.0f);
@@ -8011,6 +8123,7 @@ static void test_draw_geometry(BOOL d3d11)
static void test_fill_geometry(BOOL d3d11)
{
ID2D1TransformedGeometry *transformed_geometry[4];
+ ID2D1GeometryGroup *geometry_group;
ID2D1RectangleGeometry *rect_geometry[2];
D2D1_POINT_2F point = {0.0f, 0.0f};
D2D1_ROUNDED_RECT rounded_rect;
@@ -8728,6 +8841,112 @@ static void test_fill_geometry(BOOL d3d11)
hr = ID2D1PathGeometry_Open(geometry, &sink);
ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ set_point(&point, -0.402914f, 0.915514f);
+ ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_FILLED);
+ quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
+ quadratic_to(sink, 0.008350f, 0.693614f, -0.052343f, 0.448886f);
+ quadratic_to(sink, -0.154236f, 0.246072f, -0.279229f, 0.025343f);
+ quadratic_to(sink, -0.370064f, -0.588586f, -0.383029f, -0.924114f);
+ quadratic_to(sink, -0.295479f, -0.958764f, -0.017086f, -0.988400f);
+ quadratic_to(sink, 0.208836f, -0.954157f, 0.272200f, -0.924114f);
+ quadratic_to(sink, 0.295614f, -0.569071f, 0.230143f, 0.022886f);
+ quadratic_to(sink, 0.101664f, 0.220643f, 0.012057f, 0.451571f);
+ quadratic_to(sink, -0.028764f, 0.709014f, 0.104029f, 0.833943f);
+ quadratic_to(sink, 0.319414f, 0.913057f, 0.403229f, 0.942628f);
+ quadratic_to(sink, 0.317721f, 1.023450f, -0.017086f, 1.021771f);
+ quadratic_to(sink, -0.310843f, 1.007472f, -0.402914f, 0.915514f);
+ ID2D1GeometrySink_EndFigure(sink, D2D1_FIGURE_END_CLOSED);
+
+ hr = ID2D1GeometrySink_Close(sink);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ID2D1GeometrySink_Release(sink);
+
+ set_matrix_identity(&matrix);
+ translate_matrix(&matrix, 40.0f, 160.0f);
+ scale_matrix(&matrix, 20.0f, 80.0f);
+ hr = ID2D1Factory_CreateTransformedGeometry(factory,
+ (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[0]);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ set_matrix_identity(&matrix);
+ translate_matrix(&matrix, 160.0f, 640.0f);
+ scale_matrix(&matrix, 40.0f, 160.0f);
+ rotate_matrix(&matrix, M_PI / -5.0f);
+ hr = ID2D1Factory_CreateTransformedGeometry(factory,
+ (ID2D1Geometry *)geometry, &matrix, &transformed_geometry[1]);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ID2D1PathGeometry_Release(geometry);
+
+ set_matrix_identity(&matrix);
+ scale_matrix(&matrix, 0.5f, 1.0f);
+ translate_matrix(&matrix, -80.0f, 0.0f);
+ hr = ID2D1Factory_CreateTransformedGeometry(factory,
+ (ID2D1Geometry *)transformed_geometry[1], &matrix, &transformed_geometry[2]);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ set_matrix_identity(&matrix);
+ rotate_matrix(&matrix, M_PI / 2.0f);
+ translate_matrix(&matrix, 80.0f, -320.0f);
+ scale_matrix(&matrix, 2.0f, 0.25f);
+ hr = ID2D1Factory_CreateTransformedGeometry(factory,
+ (ID2D1Geometry *)transformed_geometry[2], &matrix, &transformed_geometry[3]);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
+ hr = ID2D1Factory_CreateGeometryGroup(factory, D2D1_FILL_MODE_WINDING,
+ (ID2D1Geometry**) &transformed_geometry, 4, &geometry_group);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ID2D1TransformedGeometry_Release(transformed_geometry[3]);
+ ID2D1TransformedGeometry_Release(transformed_geometry[2]);
+ ID2D1TransformedGeometry_Release(transformed_geometry[1]);
+ ID2D1TransformedGeometry_Release(transformed_geometry[0]);
+
+ ID2D1RenderTarget_BeginDraw(rt);
+ ID2D1RenderTarget_Clear(rt, &color);
+ ID2D1RenderTarget_FillGeometry(rt, (ID2D1Geometry *)geometry_group, (ID2D1Brush *)brush, NULL);
+ hr = ID2D1RenderTarget_EndDraw(rt, NULL, NULL);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ ID2D1GeometryGroup_Release(geometry_group);
+
+ match = compare_figure(&ctx, 0, 0, 160, 160, 0xff652e89, 32,
+ "zzIBlwEOjQEXiAEahgEahgEahgEahgEahgEahgEahgEahgEahgEahgEahwEZhwEZhwEZhwEZhwEZ"
+ "hwEZhwEZhwEZhwEZhwEZiAEYiAEYiAEXiQEXiQEXiQEXiQEXiQEXigEWigEWigEWigEWigEWigEW"
+ "igEVjAEUjAEUjAEUjQESjgESjwEQkAEQkQEOkgENlAEMlAELlgEKlwEImAEImQEHmQEGmwEFmwEE"
+ "nQEDnQECngECngECngECnwEBnwEBnwEBnwEBngEDnQEDnQEDnQEEmwEFmgEHmQEHlwELkQERjAEX"
+ "hgEdhAEfgwEchwEWjwEMqTEA");
+ ok(match, "Figure does not match.\n");
+ match = compare_figure(&ctx, 160, 0, 320, 160, 0xff652e89, 32,
+ "h58BBrUCD6wCGKQCIJsCKZMCMIwCNoUCPf8BQ/kBSPQBTu0BTu4BTfEBSfUBRfkBQf0BPYECOYUC"
+ "NIoCMI4CK+UBAS0W/AEHIweQAgsZBpcCEAwIngIepAIZqQIWrAITsAIRswIOtQIMuAIJuwIHwAIB"
+ "ypwB");
+ ok(match, "Figure does not match.\n");
+ match = compare_figure(&ctx, 0, 160, 160, 320, 0xff652e89, 32,
+ "wW4DnAEEmwEFmgEHmAEIlwEKlQELlAEMkwEOkQEPkAEQkAERjgESjgESjQEUjAEUiwEWigEWiQEX"
+ "iQEYhwEZhwEZhgEbhQEbhAEchAEdggEeggEeggEfgAEggAEggAEhgAEggAEggQEggAEggAEggQEf"
+ "gQEggQEfgQEfggEfgQEfgQEfggEfgQEfggEeggEfggEeggEeggEegwEeggEegwEdgwEegwEdgwEd"
+ "hAEchAEdhAEchAEchAEdhAEchAEchQEbhQEbhgEahgEahwEZhwEZiAEYiAEYiQEYiAEYiQEXiQEX"
+ "igEWigEWiwEViwEVjAEUjAEUjAEUjQETjQETjgESjgETjgESjwERkAEQkgEOkwENlAEMlQELlgEK"
+ "lwEJmAEJmAEImQEHmgEGmwEFnAEEnQEEnQEDnQEDngECngEDngECngECnwECngECnwECngECngED"
+ "ngECEgGLAQMQAosBAw4EjAEDCwWNAQQJBo0BBQYIjQEHAgqNARKOARKPARCQARCQARCQAQ+RAQ6S"
+ "AQ6SAQ2TAQ2SAQ2TAQ2TAQyTAQyUAQyTAQyUAQuVAQuUAQuVAQqWAQmWAQqWAQmXAQiXAQiYAQeY"
+ "AQeZAQWbAQSDZwAA");
+ ok(match, "Figure does not match.\n");
+ match = compare_figure(&ctx, 160, 160, 320, 320, 0xff652e89, 32,
+ "g90BBLkCCLYCC7ICDrACEa0CFKoCF6cCGqQCHKMCHqECIJ8CIpwCJJsCJpkCKJcCKZYCK5QCLZIC"
+ "L5ACMI8CMo0CNIsCNYoCN4gCOYcCOYYCO4QCPYICPoECQIACQYACQIECQIACQIECQIECQIECP4IC"
+ "P4ICP4ECP4ICP4ICPoMCPoMCPoMCPYQCPYMCPYQCPYQCPYQCPIUCPIUCPIUCO4YCO4YCOoYCO4YC"
+ "OocCOocCOocCOYgCOYgCOIkCOIkCN4oCNosCNYwCNI0CM44CMo4CM44CMo8CMZACMJECL5ICLpMC"
+ "LZQCLJUCK5YCK5YCKpcCKZgCKJkCJ5oCJpsCJpsCJZwCJJ4CIqACIKICH6MCHaUCG6cCGakCF6wC"
+ "Fa0CE68CEbECD7MCDrQCDLYCCrgCCbkCB7sCBrsCBbwCBbwCBL0CBL0CBL0CBL0CA70CBL0CBL0C"
+ "BLwCBSUBlgIFIQSXAgYbCJcCBxcKmQIIEQ6ZAgoMEJoCDQUTnAIknAIjnQIingIhnwIgoAIfoQIe"
+ "ogIdowIcpAIbpQIapQIZpgIZpgIZpwIYpwIXqAIXqAIXqQIVqgIVqgIUqwITrQISrQIRrgIQsAIO"
+ "sQIMswILtQIIhs4B");
+ ok(match, "Figure does not match.\n");
+
+ hr = ID2D1Factory_CreatePathGeometry(factory, &geometry);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+ hr = ID2D1PathGeometry_Open(geometry, &sink);
+ ok(hr == S_OK, "Got unexpected hr %#lx.\n", hr);
+
set_point(&point, -0.402914f, 0.915514f);
ID2D1GeometrySink_BeginFigure(sink, point, D2D1_FIGURE_BEGIN_HOLLOW);
quadratic_to(sink, -0.310379f, 0.882571f, -0.116057f, 0.824000f);
--
2.45.2

View File

@@ -0,0 +1,279 @@
From be0fbef50483da8fe3fd0c4b74469d15a5c9f1ea Mon Sep 17 00:00:00 2001
From: Philipp Knechtges <philipp-dev@knechtges.com>
Date: Fri, 13 Sep 2024 16:37:31 +0200
Subject: [PATCH] d2d1: Implement drawing for ID2D1GeometryGroup
Drawing of ID2D1GeometryGroup was so far unimplemented and resulted in
blank drawing buffers. This partially fixes the rendering issues mentioned
in the bug below.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=51139
---
dlls/d2d1/geometry.c | 236 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 235 insertions(+), 1 deletion(-)
diff --git a/dlls/d2d1/geometry.c b/dlls/d2d1/geometry.c
index 3da3ad2e65b..93925408077 100644
--- a/dlls/d2d1/geometry.c
+++ b/dlls/d2d1/geometry.c
@@ -5497,8 +5497,13 @@ static const struct ID2D1GeometryGroupVtbl d2d_geometry_group_vtbl =
HRESULT d2d_geometry_group_init(struct d2d_geometry *geometry, ID2D1Factory *factory,
D2D1_FILL_MODE fill_mode, ID2D1Geometry **geometries, unsigned int geometry_count)
{
- unsigned int i;
+ unsigned int i, j;
+ struct d2d_geometry *other_geom;
+ D2D_MATRIX_3X2_F g, gplain;
+ size_t f_vertex_count, f_face_count, f_bezier_vertex_count, f_arc_vertex_count;
+ size_t o_vertex_count, o_face_count, o_bezier_count, o_bezier_face_count, o_arc_count, o_arc_face_count;
+ FIXME("Ignoring fill_mode=%#x!\n", fill_mode);
d2d_geometry_init(geometry, factory, &identity, (ID2D1GeometryVtbl *)&d2d_geometry_group_vtbl);
if (!(geometry->u.group.src_geometries = calloc(geometry_count, sizeof(*geometries))))
@@ -5507,13 +5512,242 @@ HRESULT d2d_geometry_group_init(struct d2d_geometry *geometry, ID2D1Factory *fac
return E_OUTOFMEMORY;
}
+ geometry->fill.vertex_count = 0;
+ geometry->fill.face_count = 0;
+ geometry->fill.bezier_vertex_count = 0;
+ geometry->fill.arc_vertex_count = 0;
+ geometry->outline.vertex_count = 0;
+ geometry->outline.face_count = 0;
+ geometry->outline.bezier_count = 0;
+ geometry->outline.bezier_face_count = 0;
+ geometry->outline.arc_count = 0;
+ geometry->outline.arc_face_count = 0;
for (i = 0; i < geometry_count; ++i)
{
ID2D1Geometry_AddRef(geometry->u.group.src_geometries[i] = geometries[i]);
+ other_geom = unsafe_impl_from_ID2D1Geometry(geometries[i]);
+ geometry->fill.vertex_count += other_geom->fill.vertex_count;
+ geometry->fill.face_count += other_geom->fill.face_count;
+ geometry->fill.bezier_vertex_count += other_geom->fill.bezier_vertex_count;
+ geometry->fill.arc_vertex_count += other_geom->fill.arc_vertex_count;
+ geometry->outline.vertex_count += other_geom->outline.vertex_count;
+ geometry->outline.face_count += other_geom->outline.face_count;
+ geometry->outline.bezier_count += other_geom->outline.bezier_count;
+ geometry->outline.bezier_face_count += other_geom->outline.bezier_face_count;
+ geometry->outline.arc_count += other_geom->outline.arc_count;
+ geometry->outline.arc_face_count += other_geom->outline.arc_face_count;
}
geometry->u.group.geometry_count = geometry_count;
geometry->u.group.fill_mode = fill_mode;
+ if (!(geometry->fill.vertices = calloc(geometry->fill.vertex_count, sizeof(D2D1_POINT_2F))))
+ {
+ for (i = 0; i < geometry->u.group.geometry_count; ++i)
+ ID2D1Geometry_Release(geometry->u.group.src_geometries[i]);
+ d2d_geometry_cleanup(geometry);
+ return E_OUTOFMEMORY;
+ }
+ if (!(geometry->fill.faces = calloc(geometry->fill.face_count, sizeof(struct d2d_face))))
+ {
+ for (i = 0; i < geometry->u.group.geometry_count; ++i)
+ ID2D1Geometry_Release(geometry->u.group.src_geometries[i]);
+ d2d_geometry_cleanup(geometry);
+ return E_OUTOFMEMORY;
+ }
+ geometry->fill.faces_size = geometry->fill.face_count;
+ if (!(geometry->fill.bezier_vertices = calloc(geometry->fill.bezier_vertex_count, sizeof(struct d2d_curve_vertex))))
+ {
+ for (i = 0; i < geometry->u.group.geometry_count; ++i)
+ ID2D1Geometry_Release(geometry->u.group.src_geometries[i]);
+ d2d_geometry_cleanup(geometry);
+ return E_OUTOFMEMORY;
+ }
+ geometry->fill.bezier_vertices_size = geometry->fill.bezier_vertex_count;
+ if (!(geometry->fill.arc_vertices = calloc(geometry->fill.arc_vertex_count, sizeof(struct d2d_curve_vertex))))
+ {
+ for (i = 0; i < geometry->u.group.geometry_count; ++i)
+ ID2D1Geometry_Release(geometry->u.group.src_geometries[i]);
+ d2d_geometry_cleanup(geometry);
+ return E_OUTOFMEMORY;
+ }
+ geometry->fill.arc_vertices_size = geometry->fill.arc_vertex_count;
+ if (!(geometry->outline.vertices = calloc(geometry->outline.vertex_count, sizeof(struct d2d_outline_vertex))))
+ {
+ for (i = 0; i < geometry->u.group.geometry_count; ++i)
+ ID2D1Geometry_Release(geometry->u.group.src_geometries[i]);
+ d2d_geometry_cleanup(geometry);
+ return E_OUTOFMEMORY;
+ }
+ geometry->outline.vertices_size = geometry->outline.vertex_count;
+ if (!(geometry->outline.faces = calloc(geometry->outline.face_count, sizeof(struct d2d_face))))
+ {
+ for (i = 0; i < geometry->u.group.geometry_count; ++i)
+ ID2D1Geometry_Release(geometry->u.group.src_geometries[i]);
+ d2d_geometry_cleanup(geometry);
+ return E_OUTOFMEMORY;
+ }
+ geometry->outline.faces_size = geometry->outline.face_count;
+ if (!(geometry->outline.beziers = calloc(geometry->outline.bezier_count, sizeof(struct d2d_curve_outline_vertex))))
+ {
+ for (i = 0; i < geometry->u.group.geometry_count; ++i)
+ ID2D1Geometry_Release(geometry->u.group.src_geometries[i]);
+ d2d_geometry_cleanup(geometry);
+ return E_OUTOFMEMORY;
+ }
+ geometry->outline.beziers_size = geometry->outline.bezier_count;
+ if (!(geometry->outline.bezier_faces = calloc(geometry->outline.bezier_face_count, sizeof(struct d2d_face))))
+ {
+ for (i = 0; i < geometry->u.group.geometry_count; ++i)
+ ID2D1Geometry_Release(geometry->u.group.src_geometries[i]);
+ d2d_geometry_cleanup(geometry);
+ return E_OUTOFMEMORY;
+ }
+ geometry->outline.bezier_faces_size = geometry->outline.bezier_face_count;
+ if (!(geometry->outline.arcs = calloc(geometry->outline.arc_count, sizeof(struct d2d_curve_outline_vertex))))
+ {
+ for (i = 0; i < geometry->u.group.geometry_count; ++i)
+ ID2D1Geometry_Release(geometry->u.group.src_geometries[i]);
+ d2d_geometry_cleanup(geometry);
+ return E_OUTOFMEMORY;
+ }
+ geometry->outline.arcs_size = geometry->outline.arc_count;
+ if (!(geometry->outline.arc_faces = calloc(geometry->outline.arc_face_count, sizeof(struct d2d_face))))
+ {
+ for (i = 0; i < geometry->u.group.geometry_count; ++i)
+ ID2D1Geometry_Release(geometry->u.group.src_geometries[i]);
+ d2d_geometry_cleanup(geometry);
+ return E_OUTOFMEMORY;
+ }
+ geometry->outline.arc_faces_size = geometry->outline.arc_face_count;
+
+ f_vertex_count = 0;
+ f_face_count = 0;
+ f_bezier_vertex_count = 0;
+ f_arc_vertex_count = 0;
+ o_vertex_count = 0;
+ o_face_count = 0;
+ o_bezier_count = 0;
+ o_bezier_face_count = 0;
+ o_arc_count = 0;
+ o_arc_face_count = 0;
+ for (i = 0; i < geometry_count; ++i)
+ {
+ other_geom = unsafe_impl_from_ID2D1Geometry(geometries[i]);
+ g = other_geom->transform;
+ gplain = g;
+ gplain.dx = 0.0f;
+ gplain.dy = 0.0f;
+
+ for (j = 0; j < other_geom->fill.vertex_count; ++j) {
+ d2d_point_transform(&geometry->fill.vertices[j+f_vertex_count], &g,
+ other_geom->fill.vertices[j].x, other_geom->fill.vertices[j].y);
+ }
+ for (j = 0; j < other_geom->fill.face_count; ++j) {
+ geometry->fill.faces[f_face_count+j].v[0] = other_geom->fill.faces[j].v[0]
+ + (UINT16) f_vertex_count;
+ geometry->fill.faces[f_face_count+j].v[1] = other_geom->fill.faces[j].v[1]
+ + (UINT16) f_vertex_count;
+ geometry->fill.faces[f_face_count+j].v[2] = other_geom->fill.faces[j].v[2]
+ + (UINT16) f_vertex_count;
+ }
+ f_vertex_count += other_geom->fill.vertex_count;
+ f_face_count += other_geom->fill.face_count;
+
+ for (j = 0; j < other_geom->fill.bezier_vertex_count; ++j) {
+ d2d_point_transform(&geometry->fill.bezier_vertices[j+f_bezier_vertex_count].position,
+ &g, other_geom->fill.bezier_vertices[j].position.x,
+ other_geom->fill.bezier_vertices[j].position.y);
+ geometry->fill.bezier_vertices[j+f_bezier_vertex_count].texcoord
+ = other_geom->fill.bezier_vertices[j].texcoord;
+ }
+ f_bezier_vertex_count += other_geom->fill.bezier_vertex_count;
+
+ for (j = 0; j < other_geom->fill.arc_vertex_count; ++j) {
+ d2d_point_transform(&geometry->fill.arc_vertices[j+f_arc_vertex_count].position,
+ &g, other_geom->fill.arc_vertices[j].position.x,
+ other_geom->fill.arc_vertices[j].position.y);
+ geometry->fill.arc_vertices[j+f_arc_vertex_count].texcoord
+ = other_geom->fill.arc_vertices[j].texcoord;
+
+ }
+ f_arc_vertex_count += other_geom->fill.arc_vertex_count;
+
+ for (j = 0; j < other_geom->outline.vertex_count; ++j) {
+ d2d_point_transform(&geometry->outline.vertices[j+o_vertex_count].position, &g,
+ other_geom->outline.vertices[j].position.x, other_geom->outline.vertices[j].position.y);
+ d2d_point_transform(&geometry->outline.vertices[j+o_vertex_count].prev, &gplain,
+ other_geom->outline.vertices[j].prev.x, other_geom->outline.vertices[j].prev.y);
+ d2d_point_normalise(&geometry->outline.vertices[j+o_vertex_count].prev);
+ d2d_point_transform(&geometry->outline.vertices[j+o_vertex_count].next, &gplain,
+ other_geom->outline.vertices[j].next.x, other_geom->outline.vertices[j].next.y);
+ d2d_point_normalise(&geometry->outline.vertices[j+o_vertex_count].next);
+ }
+ for (j = 0; j < other_geom->outline.face_count; ++j) {
+ geometry->outline.faces[o_face_count+j].v[0] = other_geom->outline.faces[j].v[0]
+ + (UINT16) o_vertex_count;
+ geometry->outline.faces[o_face_count+j].v[1] = other_geom->outline.faces[j].v[1]
+ + (UINT16) o_vertex_count;
+ geometry->outline.faces[o_face_count+j].v[2] = other_geom->outline.faces[j].v[2]
+ + (UINT16) o_vertex_count;
+ }
+ o_vertex_count += other_geom->outline.vertex_count;
+ o_face_count += other_geom->outline.face_count;
+
+ for (j = 0; j < other_geom->outline.bezier_count; ++j) {
+ d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].position, &g,
+ other_geom->outline.beziers[j].position.x, other_geom->outline.beziers[j].position.y);
+ d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].prev, &gplain,
+ other_geom->outline.beziers[j].prev.x, other_geom->outline.beziers[j].prev.y);
+ d2d_point_normalise(&geometry->outline.beziers[j+o_bezier_count].prev);
+ d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].next, &gplain,
+ other_geom->outline.beziers[j].next.x, other_geom->outline.beziers[j].next.y);
+ d2d_point_normalise(&geometry->outline.beziers[j+o_bezier_count].next);
+ d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].p0, &g,
+ other_geom->outline.beziers[j].p0.x, other_geom->outline.beziers[j].p0.y);
+ d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].p1, &g,
+ other_geom->outline.beziers[j].p1.x, other_geom->outline.beziers[j].p1.y);
+ d2d_point_transform(&geometry->outline.beziers[j+o_bezier_count].p2, &g,
+ other_geom->outline.beziers[j].p2.x, other_geom->outline.beziers[j].p2.y);
+ }
+ for (j = 0; j < other_geom->outline.bezier_face_count; ++j) {
+ geometry->outline.bezier_faces[o_bezier_face_count+j].v[0]
+ = other_geom->outline.bezier_faces[j].v[0] + (UINT16) o_bezier_count;
+ geometry->outline.bezier_faces[o_bezier_face_count+j].v[1]
+ = other_geom->outline.bezier_faces[j].v[1] + (UINT16) o_bezier_count;
+ geometry->outline.bezier_faces[o_bezier_face_count+j].v[2]
+ = other_geom->outline.bezier_faces[j].v[2] + (UINT16) o_bezier_count;
+ }
+ o_bezier_count += other_geom->outline.bezier_count;
+ o_bezier_face_count += other_geom->outline.bezier_face_count;
+
+ for (j = 0; j < other_geom->outline.arc_count; ++j) {
+ d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].position, &g,
+ other_geom->outline.arcs[j].position.x, other_geom->outline.arcs[j].position.y);
+ d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].prev, &gplain,
+ other_geom->outline.arcs[j].prev.x, other_geom->outline.arcs[j].prev.y);
+ d2d_point_normalise(&geometry->outline.arcs[j+o_arc_count].prev);
+ d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].next, &gplain,
+ other_geom->outline.arcs[j].next.x, other_geom->outline.arcs[j].next.y);
+ d2d_point_normalise(&geometry->outline.arcs[j+o_arc_count].next);
+ d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].p0, &g,
+ other_geom->outline.arcs[j].p0.x, other_geom->outline.arcs[j].p0.y);
+ d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].p1, &g,
+ other_geom->outline.arcs[j].p1.x, other_geom->outline.arcs[j].p1.y);
+ d2d_point_transform(&geometry->outline.arcs[j+o_arc_count].p2, &g,
+ other_geom->outline.arcs[j].p2.x, other_geom->outline.arcs[j].p2.y);
+ }
+ for (j = 0; j < other_geom->outline.arc_face_count; ++j) {
+ geometry->outline.arc_faces[o_arc_face_count+j].v[0]
+ = other_geom->outline.arc_faces[j].v[0] + (UINT16) o_arc_count;
+ geometry->outline.arc_faces[o_arc_face_count+j].v[1]
+ = other_geom->outline.arc_faces[j].v[1] + (UINT16) o_arc_count;
+ geometry->outline.arc_faces[o_arc_face_count+j].v[2]
+ = other_geom->outline.arc_faces[j].v[2] + (UINT16) o_arc_count;
+ }
+ o_arc_count += other_geom->outline.arc_count;
+ o_arc_face_count += other_geom->outline.arc_face_count;
+ }
+
return S_OK;
}
--
2.45.2

View File

@@ -0,0 +1,3 @@
Fixes: [51139] d2d1: Implement drawing of ID2D1GeometryGroup
# MR https://gitlab.winehq.org/wine/wine/-/merge_requests/6492

View File

@@ -0,0 +1,24 @@
From 252a1d6bb99c83ce8a0289fbd1f4fe135e2c55cd Mon Sep 17 00:00:00 2001
From: Torge Matthies <tmatthies@codeweavers.com>
Date: Fri, 25 Oct 2024 13:19:02 +0200
Subject: [PATCH] include: Add MFNETSOURCE_STATISTICS_SERVICE definition.
---
include/mfidl.idl | 1 +
1 file changed, 1 insertion(+)
diff --git a/include/mfidl.idl b/include/mfidl.idl
index 666af53c6e3..a8c5af05e68 100644
--- a/include/mfidl.idl
+++ b/include/mfidl.idl
@@ -1626,6 +1626,7 @@ cpp_quote("EXTERN_GUID(MR_STREAM_VOLUME_SERVICE, 0xf8b5fa2f, 0x32ef, 0x46f5, 0xb
cpp_quote("EXTERN_GUID(MR_AUDIO_POLICY_SERVICE, 0x911fd737, 0x6775, 0x4ab0, 0xa6, 0x14, 0x29, 0x78, 0x62, 0xfd, 0xac, 0x88);")
cpp_quote("EXTERN_GUID(MF_PROPERTY_HANDLER_SERVICE, 0xa3face02, 0x32b8, 0x41dd, 0x90, 0xe7, 0x5f, 0xef, 0x7c, 0x89, 0x91, 0xb5);")
cpp_quote("EXTERN_GUID(MF_WORKQUEUE_SERVICES, 0x8e37d489, 0x41e0, 0x413a, 0x90, 0x68, 0x28, 0x7c, 0x88, 0x6d, 0x8d, 0xda);")
+cpp_quote("EXTERN_GUID(MFNETSOURCE_STATISTICS_SERVICE, 0x3cb1f275, 0x0505, 0x4c5d, 0xae, 0x71, 0x0a, 0x55, 0x63, 0x44, 0xef, 0xa1);")
cpp_quote("EXTERN_GUID(MF_PROGRESSIVE_CODING_CONTENT, 0x8f020eea, 0x1508, 0x471f, 0x9d, 0xa6, 0x50, 0x7d, 0x7c, 0xfa, 0x40, 0xdb);")
cpp_quote("EXTERN_GUID(MF_NALU_LENGTH_SET, 0xa7911d53, 0x12a4, 0x4965, 0xae, 0x70, 0x6e, 0xad, 0xd6, 0xff, 0x05, 0x51);")
--
2.45.2

View File

@@ -0,0 +1,383 @@
From 0d4a7cf6b9bb3a57a098762113ca1750c43a810e Mon Sep 17 00:00:00 2001
From: Torge Matthies <tmatthies@codeweavers.com>
Date: Fri, 25 Oct 2024 10:47:30 +0200
Subject: [PATCH] mf/tests: Add network bytestream tests.
---
dlls/mf/tests/mf.c | 347 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 347 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index d0f1f1cf0a4..61daaf35741 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -4726,6 +4726,7 @@ static void test_evr(void)
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ if (!sink) return;
check_interface(sink, &IID_IMFMediaSinkPreroll, TRUE);
check_interface(sink, &IID_IMFVideoRenderer, TRUE);
@@ -6803,6 +6804,351 @@ static void test_media_session_Close(void)
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
}
+static void test_network_bytestream(void)
+{
+ static const WCHAR *URL = L"http://test.winehq.org/tests/test.mp3";
+ static const WCHAR *EFFECTIVE_URL = L"http://test.winehq.org:80/tests/test.mp3";
+ static const WCHAR *CONTENT_TYPE = L"audio/mpeg";
+ static const BYTE LAST_MODIFIED_TIME[] = { 0x00, 0x3b, 0x4b, 0xbf, 0x05, 0x80, 0xd8, 0x01 };
+
+ IMFSourceResolver *resolver;
+ IUnknown *object = NULL, *bs = NULL;
+ MF_OBJECT_TYPE obj_type;
+ HRESULT hr;
+ void *ptr;
+
+ hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
+ ok(hr == S_OK, "Startup failure, hr %#lx.\n", hr);
+
+ hr = MFCreateSourceResolver(&resolver);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ if (object) IUnknown_Release(object);
+
+ obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
+ object = NULL;
+ hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://nonexistent.url/file.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type, &object);
+ todo_wine
+ ok(hr == NS_E_SERVER_NOT_FOUND, "Got hr %#lx.\n", hr);
+ ok(obj_type == MF_OBJECT_INVALID, "Unexpected obj_type %#x.\n", obj_type);
+ if (object) IUnknown_Release(object);
+
+ obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
+ object = NULL;
+ hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type, &object);
+ todo_wine
+ ok(hr == NS_E_FILE_NOT_FOUND, "Got hr %#lx.\n", hr);
+ todo_wine
+ ok(obj_type == MF_OBJECT_INVALID, "Unexpected obj_type %#x.\n", obj_type);
+ if (object) IUnknown_Release(object);
+
+ obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
+ object = NULL;
+ hr = IMFSourceResolver_CreateObjectFromURL(resolver, URL, MF_RESOLUTION_BYTESTREAM, NULL, &obj_type, &object);
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ ok(obj_type == MF_OBJECT_BYTESTREAM, "Unexpected obj_type %#x.\n", obj_type);
+
+ ptr = NULL;
+ hr = IUnknown_QueryInterface(object, &IID_IMFAttributes, &ptr);
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ ok(ptr != NULL, "Got NULL ptr.\n");
+ if (SUCCEEDED(hr) && ptr)
+ {
+ IMFAttributes *attr = ptr;
+ UINT32 count = 0;
+ PROPVARIANT var;
+ GUID key = {0};
+
+ hr = IMFAttributes_GetCount(attr, &count);
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+ todo_wine
+ ok(count == 3, "count = %u\n", count);
+
+ PropVariantInit(&var);
+
+ hr = IMFAttributes_GetItemByIndex(attr, 0, &key, &var);
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+ ok(IsEqualGUID(&key, &MF_BYTESTREAM_EFFECTIVE_URL), "Got key %s\n", debugstr_guid(&key));
+ ok(var.vt == VT_LPWSTR, "Got type %d\n", var.vt);
+ todo_wine
+ ok(!lstrcmpW(var.pwszVal, EFFECTIVE_URL), "Got value %s\n", var.pszVal);
+ memset(&key, 0, sizeof(key));
+ PropVariantClear(&var);
+
+ hr = IMFAttributes_GetItemByIndex(attr, 1, &key, &var);
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+ ok(IsEqualGUID(&key, &MF_BYTESTREAM_CONTENT_TYPE), "Got key %s\n", debugstr_guid(&key));
+ ok(var.vt == VT_LPWSTR, "Got type %d\n", var.vt);
+ todo_wine
+ ok(!lstrcmpW(var.pwszVal, CONTENT_TYPE), "Got value %s\n", var.pszVal);
+ memset(&key, 0, sizeof(key));
+ PropVariantClear(&var);
+
+ hr = IMFAttributes_GetItemByIndex(attr, 2, &key, &var);
+ todo_wine
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+ todo_wine
+ ok(IsEqualGUID(&key, &MF_BYTESTREAM_LAST_MODIFIED_TIME), "Got key %s\n", debugstr_guid(&key));
+ todo_wine
+ ok(var.vt == (VT_VECTOR | VT_I1 | VT_NULL), "Got type %d\n", var.vt);
+ todo_wine
+ ok(var.blob.cbSize == sizeof(LAST_MODIFIED_TIME), "Got size %lu\n", var.blob.cbSize);
+ todo_wine
+ ok(var.blob.pBlobData != NULL, "Got NULL value\n");
+ if (var.blob.cbSize == sizeof(LAST_MODIFIED_TIME) && var.blob.pBlobData)
+ ok(!memcmp(var.blob.pBlobData, LAST_MODIFIED_TIME, sizeof(LAST_MODIFIED_TIME)), "Got wrong value\n");
+ memset(&key, 0, sizeof(key));
+ PropVariantClear(&var);
+
+ hr = IMFAttributes_GetItemByIndex(attr, 3, &key, &var);
+ ok(hr == E_INVALIDARG, "Got hr %#lx\n", hr);
+ ok(IsEqualGUID(&key, &GUID_NULL), "Got key %s\n", debugstr_guid(&key));
+ ok(var.vt == VT_EMPTY, "Got type %d\n", var.vt);
+ memset(&key, 0, sizeof(key));
+ PropVariantClear(&var);
+
+ IUnknown_Release((IUnknown *)ptr);
+ }
+
+ ptr = NULL;
+ hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamCacheControl, &ptr);
+ todo_wine
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ todo_wine
+ ok(ptr != NULL, "Got NULL ptr.\n");
+ if (SUCCEEDED(hr) && ptr)
+ {
+ IMFByteStreamCacheControl *ctrl = ptr;
+ HRESULT hr;
+
+ hr = IMFByteStreamCacheControl_StopBackgroundTransfer(ctrl);
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+
+ IMFByteStreamCacheControl_Release(ctrl);
+ }
+
+ ptr = NULL;
+ hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamBuffering, &ptr);
+ todo_wine
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ todo_wine
+ ok(ptr != NULL, "Got NULL ptr.\n");
+ if (SUCCEEDED(hr) && ptr)
+ {
+ MFBYTESTREAM_BUFFERING_PARAMS params = {0};
+ IMFByteStreamBuffering *buffering = ptr;
+ MF_LEAKY_BUCKET_PAIR bucket = {0};
+ HRESULT hr;
+
+ hr = IMFByteStreamBuffering_StopBuffering(buffering);
+ ok(hr == S_FALSE, "Got hr %#lx\n", hr);
+
+ hr = IMFByteStreamBuffering_EnableBuffering(buffering, FALSE);
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+
+ hr = IMFByteStreamBuffering_EnableBuffering(buffering, TRUE);
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+
+ hr = IMFByteStreamBuffering_StopBuffering(buffering);
+ ok(hr == S_OK || hr == S_FALSE, "Got hr %#lx\n", hr);
+
+ hr = IMFByteStreamBuffering_SetBufferingParams(buffering, NULL);
+ ok(hr == E_INVALIDARG, "Got hr %#lx\n", hr);
+
+ params.cbTotalFileSize = -1;
+ params.cbPlayableDataSize = -1;
+ params.prgBuckets = NULL;
+ params.cBuckets = 0;
+ params.qwNetBufferingTime = 0;
+ params.qwExtraBufferingTimeDuringSeek = 0;
+ params.qwPlayDuration = 0;
+ params.dRate = 1.0f;
+ hr = IMFByteStreamBuffering_SetBufferingParams(buffering, &params);
+ todo_wine
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+
+ params.cBuckets = 1;
+ hr = IMFByteStreamBuffering_SetBufferingParams(buffering, &params);
+ ok(hr == E_INVALIDARG, "Got hr %#lx\n", hr);
+
+ params.prgBuckets = &bucket;
+ bucket.dwBitrate = 0;
+ bucket.msBufferWindow = 0;
+ hr = IMFByteStreamBuffering_SetBufferingParams(buffering, &params);
+ todo_wine
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+
+ params.cbTotalFileSize = 0xdeadbeef;
+ params.cbPlayableDataSize = 0xdeadbeef;
+ bucket.dwBitrate = 0xdeadbeef;
+ bucket.msBufferWindow = 0xdeadbeef;
+ params.qwNetBufferingTime = 0xdeadbeef;
+ params.qwExtraBufferingTimeDuringSeek = 0xdeadbeef;
+ params.qwPlayDuration = 0xdeadbeef;
+ params.dRate = 12345.0f;
+ hr = IMFByteStreamBuffering_SetBufferingParams(buffering, &params);
+ todo_wine
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+
+ hr = IMFByteStreamBuffering_EnableBuffering(buffering, TRUE);
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+
+ IMFByteStreamBuffering_Release(buffering);
+ }
+
+ ptr = NULL;
+ hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamTimeSeek, &ptr);
+ todo_wine
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ todo_wine
+ ok(ptr != NULL, "Got NULL ptr.\n");
+ if (SUCCEEDED(hr) && ptr)
+ {
+ QWORD start_time = 0xdeadbeef, stop_time = 0xdeadbef0, duration = 0xdeadbef1;
+ IMFByteStreamTimeSeek *seek = ptr;
+ BOOL b = 0xdeadbeef;
+ HRESULT hr;
+
+ hr = IMFByteStreamTimeSeek_GetTimeSeekResult(seek, NULL, NULL, NULL);
+ ok(hr == E_INVALIDARG, "Got hr %#lx\n", hr);
+
+ hr = IMFByteStreamTimeSeek_GetTimeSeekResult(seek, &start_time, &stop_time, &duration);
+ ok(hr == MF_E_INVALIDREQUEST, "Got hr %#lx\n", hr);
+ ok(start_time == 0, "start_time = %I64u\n", start_time);
+ ok(stop_time == 0, "stop_time = %I64u\n", stop_time);
+ ok(duration == 0, "duration = %I64u\n", duration);
+
+ hr = IMFByteStreamTimeSeek_IsTimeSeekSupported(seek, NULL);
+ ok(hr == S_FALSE, "Got hr %#lx\n", hr);
+
+ hr = IMFByteStreamTimeSeek_IsTimeSeekSupported(seek, &b);
+ ok(hr == S_FALSE, "Got hr %#lx\n", hr);
+ ok(!b, "supported = %x\n", b);
+
+ hr = IMFByteStreamTimeSeek_TimeSeek(seek, 0);
+ ok(hr == MF_E_INVALIDREQUEST, "Got hr %#lx\n", hr);
+
+ hr = IMFByteStreamTimeSeek_GetTimeSeekResult(seek, &start_time, &stop_time, &duration);
+ ok(hr == MF_E_INVALIDREQUEST, "Got hr %#lx\n", hr);
+ ok(start_time == 0, "start_time = %I64u\n", start_time);
+ ok(stop_time == 0, "stop_time = %I64u\n", stop_time);
+ ok(duration == 0, "duration = %I64u\n", duration);
+
+ IMFByteStreamTimeSeek_Release(seek);
+ }
+
+ {
+ BYTE *tmp = malloc(8192);
+ ULONG read = 0, written = 0;
+ QWORD len = 0;
+
+ hr = IMFByteStream_SetLength((IMFByteStream*)object, 1000);
+ ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
+
+ hr = IMFByteStream_SetCurrentPosition((IMFByteStream*)object, 1000);
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+
+ hr = IMFByteStream_Read((IMFByteStream*)object, tmp, 8192, &read);
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ ok(read == 3365, "read = %lu\n", read);
+
+ hr = IMFByteStream_SetCurrentPosition((IMFByteStream*)object, 1000);
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+
+ hr = IMFByteStream_Write((IMFByteStream*)object, tmp, 1000, &written);
+ ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
+ ok(written == 0, "written = %lu\n", written);
+
+ free(tmp);
+
+ hr = IMFByteStream_GetLength((IMFByteStream*)object, &len);
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+ ok(len != 0, "len = %I64u\n", len);
+
+ hr = IMFByteStream_Flush((IMFByteStream*)object);
+ todo_wine
+ ok(hr == S_OK, "Got hr %#lx\n", hr);
+ }
+
+ ptr = NULL;
+ hr = MFGetService(object, &MFNETSOURCE_STATISTICS_SERVICE, &IID_IPropertyStore, &ptr);
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ ok(ptr != NULL, "Got NULL ptr.\n");
+ if (SUCCEEDED(hr) && ptr)
+ {
+ IPropertyStore *pstore = ptr;
+ DWORD count = 0;
+
+ ptr = NULL;
+ hr = IUnknown_QueryInterface(object, &IID_IPropertyStore, &ptr);
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ ok(ptr == (void *)pstore, "Got different IPropertyStore: %p != %p.\n", ptr, pstore);
+ IPropertyStore_Release((IPropertyStore *)ptr);
+
+ hr = IPropertyStore_GetCount(pstore, &count);
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ ok(count == 0, "Got count %lu.\n", count);
+
+ IPropertyStore_Release(pstore);
+ }
+
+ ptr = NULL;
+ hr = IUnknown_QueryInterface(object, &IID_IMFMediaEventGenerator, &ptr);
+ todo_wine
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+ todo_wine
+ ok(ptr != NULL, "Got NULL ptr.\n");
+ if (SUCCEEDED(hr) && ptr)
+ {
+ IMFMediaEvent *evt = (void *)(DWORD_PTR)0xdeadbeef;
+ BOOL seen_caps_changed = FALSE, buffering = FALSE;
+ IMFMediaEventGenerator *gen = ptr;
+ MediaEventType type;
+ HRESULT hr;
+
+ while (SUCCEEDED(hr = IMFMediaEventGenerator_GetEvent(gen, MF_EVENT_FLAG_NO_WAIT, &evt)))
+ {
+ type = (MediaEventType)0xdeadbeef;
+ hr = IMFMediaEvent_GetType(evt, &type);
+ ok(hr == S_OK, "Got hr %#lx.\n", hr);
+
+ if (type == MEByteStreamCharacteristicsChanged)
+ {
+ ok(!seen_caps_changed, "got multiple MEByteStreamCharacteristicsChanged events\n");
+ seen_caps_changed = TRUE;
+ }
+ else if (type == MEBufferingStarted)
+ {
+ ok(!buffering, "got MEBufferingStopped without MEBufferingStarted\n");
+ buffering = TRUE;
+ }
+ else if (type == MEBufferingStopped)
+ buffering = FALSE;
+ else
+ ok(0, "Unexpected event type %#lx\n", type);
+
+ IMFMediaEvent_Release(evt);
+ }
+ ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Got hr %#lx.\n", hr);
+
+ IMFMediaEventGenerator_Release(gen);
+ }
+
+ obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
+ bs = NULL;
+ hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, (void *)object, NULL, MF_RESOLUTION_MEDIASOURCE, NULL, &obj_type, &bs);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(obj_type == MF_OBJECT_MEDIASOURCE, "Unexpected obj_type %#x.\n", obj_type);
+
+ if (bs) IUnknown_Release(bs);
+ if (object) IUnknown_Release(object);
+
+ IMFSourceResolver_Release(resolver);
+
+ hr = MFShutdown();
+ ok(hr == S_OK, "Shutdown failure, hr %#lx.\n", hr);
+}
+
START_TEST(mf)
{
init_functions();
@@ -6838,5 +7184,6 @@ START_TEST(mf)
test_media_session_Start();
test_MFEnumDeviceSources();
test_media_session_Close();
+ test_network_bytestream();
test_media_session_source_shutdown();
}
--
2.45.2

View File

@@ -0,0 +1,346 @@
From 68227ee19646a7c98f1b1e6eed72a7a6a2a21fc1 Mon Sep 17 00:00:00 2001
From: Torge Matthies <tmatthies@codeweavers.com>
Date: Fri, 25 Oct 2024 10:47:31 +0200
Subject: [PATCH] mf: Implement and use HttpSchemePlugin.
---
dlls/mf/main.c | 2 ++
dlls/mf/mf.idl | 6 ++++++
dlls/mf/mf.rgs | 16 ++++++++++++++--
dlls/mf/mf_private.h | 1 +
dlls/mf/scheme_handler.c | 33 +++++++++++++++++++++++++++++++++
dlls/mf/tests/mf.c | 38 ++++----------------------------------
dlls/mfplat/mfplat.spec | 3 +++
dlls/mfplat/network.c | 5 +++++
8 files changed, 68 insertions(+), 36 deletions(-)
diff --git a/dlls/mf/main.c b/dlls/mf/main.c
index e74a4ae8e4c..120343a1be2 100644
--- a/dlls/mf/main.c
+++ b/dlls/mf/main.c
@@ -549,6 +549,7 @@ static const IClassFactoryVtbl class_factory_vtbl =
};
static struct class_factory file_scheme_handler_factory = { { &class_factory_vtbl }, file_scheme_handler_construct };
+static struct class_factory http_scheme_handler_factory = { { &class_factory_vtbl }, http_scheme_handler_construct };
static struct class_factory urlmon_scheme_handler_factory = { { &class_factory_vtbl }, urlmon_scheme_handler_construct };
static const struct class_object
@@ -559,6 +560,7 @@ static const struct class_object
class_objects[] =
{
{ &CLSID_FileSchemePlugin, &file_scheme_handler_factory.IClassFactory_iface },
+ { &CLSID_HttpSchemePlugin, &http_scheme_handler_factory.IClassFactory_iface },
{ &CLSID_UrlmonSchemePlugin, &urlmon_scheme_handler_factory.IClassFactory_iface },
};
diff --git a/dlls/mf/mf.idl b/dlls/mf/mf.idl
index 4f5ef36c965..ca05a991ca9 100644
--- a/dlls/mf/mf.idl
+++ b/dlls/mf/mf.idl
@@ -25,6 +25,12 @@
]
coclass FileSchemePlugin { }
+[
+ threading(both),
+ uuid(44cb442b-9da9-49df-b3fd-023777b16e50)
+]
+coclass HttpSchemePlugin {}
+
[
threading(both),
uuid(9ec4b4f9-3029-45ad-947b-344de2a249e2)
diff --git a/dlls/mf/mf.rgs b/dlls/mf/mf.rgs
index f06576baccb..778b07e65ed 100644
--- a/dlls/mf/mf.rgs
+++ b/dlls/mf/mf.rgs
@@ -14,11 +14,23 @@ HKLM
}
'http:'
{
- val '{9ec4b4f9-3029-45ad-947b-344de2a249e2}' = s 'Urlmon Scheme Handler'
+ val '{44cb442b-9da9-49df-b3fd-023777b16e50}' = s 'Http Scheme Handler'
}
'https:'
{
- val '{9ec4b4f9-3029-45ad-947b-344de2a249e2}' = s 'Urlmon Scheme Handler'
+ val '{44cb442b-9da9-49df-b3fd-023777b16e50}' = s 'Http Scheme Handler'
+ }
+ 'httpd:'
+ {
+ val '{44cb442b-9da9-49df-b3fd-023777b16e50}' = s 'Http Scheme Handler'
+ }
+ 'httpsd:'
+ {
+ val '{44cb442b-9da9-49df-b3fd-023777b16e50}' = s 'Http Scheme Handler'
+ }
+ 'mms:'
+ {
+ val '{44cb442b-9da9-49df-b3fd-023777b16e50}' = s 'Http Scheme Handler'
}
}
}
diff --git a/dlls/mf/mf_private.h b/dlls/mf/mf_private.h
index 1f2ef17a8c9..adb35e14194 100644
--- a/dlls/mf/mf_private.h
+++ b/dlls/mf/mf_private.h
@@ -114,6 +114,7 @@ static inline const char *debugstr_propvar(const PROPVARIANT *v)
}
extern HRESULT file_scheme_handler_construct(REFIID riid, void **obj);
+extern HRESULT http_scheme_handler_construct(REFIID riid, void **obj);
extern HRESULT urlmon_scheme_handler_construct(REFIID riid, void **obj);
extern BOOL mf_is_sample_copier_transform(IMFTransform *transform);
diff --git a/dlls/mf/scheme_handler.c b/dlls/mf/scheme_handler.c
index 7e92748aeb9..3cd16319b2a 100644
--- a/dlls/mf/scheme_handler.c
+++ b/dlls/mf/scheme_handler.c
@@ -483,6 +483,39 @@ HRESULT file_scheme_handler_construct(REFIID riid, void **obj)
return hr;
}
+WINAPI HRESULT __wine_create_http_bytestream(const WCHAR *url, void **out);
+
+static HRESULT http_stream_create(const WCHAR *url, DWORD flags, IMFByteStream **out)
+{
+ if (flags & MF_RESOLUTION_WRITE)
+ return E_INVALIDARG;
+
+ return __wine_create_http_bytestream(url, (void **)out);
+}
+
+HRESULT http_scheme_handler_construct(REFIID riid, void **obj)
+{
+ struct scheme_handler *handler;
+ HRESULT hr;
+
+ TRACE("%s, %p.\n", debugstr_guid(riid), obj);
+
+ if (!(handler = calloc(1, sizeof(*handler))))
+ return E_OUTOFMEMORY;
+
+ handler->IMFSchemeHandler_iface.lpVtbl = &scheme_handler_vtbl;
+ handler->IMFAsyncCallback_iface.lpVtbl = &scheme_handler_callback_vtbl;
+ handler->refcount = 1;
+ list_init(&handler->results);
+ InitializeCriticalSection(&handler->cs);
+ handler->create_stream = http_stream_create;
+
+ hr = IMFSchemeHandler_QueryInterface(&handler->IMFSchemeHandler_iface, riid, obj);
+ IMFSchemeHandler_Release(&handler->IMFSchemeHandler_iface);
+
+ return hr;
+}
+
static HRESULT urlmon_stream_create(const WCHAR *url, DWORD flags, IMFByteStream **out)
{
IMFAttributes *attributes;
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 61daaf35741..39dfe3ca1b2 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -5384,7 +5384,6 @@ static void test_scheme_resolvers(void)
for (i = 0; i < ARRAY_SIZE(urls); i++)
{
hr = IMFSourceResolver_CreateObjectFromURL(resolver, urls[i], MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine_if(i >= 2)
ok(hr == S_OK, "got hr %#lx\n", hr);
if (hr != S_OK)
continue;
@@ -5408,7 +5407,6 @@ static void test_scheme_resolvers(void)
hr = IMFAttributes_GetItem(attributes, &MF_BYTESTREAM_CONTENT_TYPE, NULL);
ok(hr == S_OK, "got hr %#lx\n", hr);
hr = IMFAttributes_GetItem(attributes, &MF_BYTESTREAM_LAST_MODIFIED_TIME, NULL);
- todo_wine
ok(hr == S_OK, "got hr %#lx\n", hr);
IMFAttributes_Release(attributes);
@@ -5416,8 +5414,7 @@ static void test_scheme_resolvers(void)
ok(hr == S_OK, "got hr %#lx\n", hr);
hr = IMFByteStream_GetCapabilities(byte_stream, &caps);
ok(hr == S_OK, "got hr %#lx\n", hr);
- todo_wine
- ok(caps == (expect_caps | MFBYTESTREAM_IS_PARTIALLY_DOWNLOADED)
+ ok(caps == expect_caps || caps == (expect_caps | MFBYTESTREAM_IS_PARTIALLY_DOWNLOADED)
|| caps == (expect_caps | MFBYTESTREAM_DOES_NOT_USE_NETWORK),
"got caps %#lx\n", caps);
hr = IMFByteStream_GetLength(byte_stream, &length);
@@ -5436,35 +5433,25 @@ static void test_scheme_resolvers(void)
ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got hr %#lx\n", hr);
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://test.winehq.bla/tests/test.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine
ok(hr == NS_E_SERVER_NOT_FOUND, "got hr %#lx\n", hr);
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"https://test.winehq.bla/tests/test.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine
ok(hr == WININET_E_NAME_NOT_RESOLVED, "got hr %#lx\n", hr);
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"httpd://test.winehq.bla/tests/test.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine
ok(hr == WININET_E_NAME_NOT_RESOLVED, "got hr %#lx\n", hr);
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"httpsd://test.winehq.bla/tests/test.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine
ok(hr == WININET_E_NAME_NOT_RESOLVED, "got hr %#lx\n", hr);
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"mms://test.winehq.bla/tests/test.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine
ok(hr == WININET_E_NAME_NOT_RESOLVED, "got hr %#lx\n", hr);
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine
ok(hr == NS_E_FILE_NOT_FOUND, "got hr %#lx\n", hr);
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"https://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine
ok(hr == NS_E_FILE_NOT_FOUND, "got hr %#lx\n", hr);
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"httpd://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine
ok(hr == NS_E_FILE_NOT_FOUND, "got hr %#lx\n", hr);
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"httpsd://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine
ok(hr == NS_E_FILE_NOT_FOUND, "got hr %#lx\n", hr);
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"mms://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &type, &object);
- todo_wine
ok(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE, "got hr %#lx\n", hr);
IMFSourceResolver_Release(resolver);
@@ -6828,7 +6815,6 @@ static void test_network_bytestream(void)
obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
object = NULL;
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://nonexistent.url/file.mp4", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type, &object);
- todo_wine
ok(hr == NS_E_SERVER_NOT_FOUND, "Got hr %#lx.\n", hr);
ok(obj_type == MF_OBJECT_INVALID, "Unexpected obj_type %#x.\n", obj_type);
if (object) IUnknown_Release(object);
@@ -6836,9 +6822,7 @@ static void test_network_bytestream(void)
obj_type = (MF_OBJECT_TYPE)0xdeadbeef;
object = NULL;
hr = IMFSourceResolver_CreateObjectFromURL(resolver, L"http://test.winehq.org/tests/invalid.mp3", MF_RESOLUTION_BYTESTREAM, NULL, &obj_type, &object);
- todo_wine
ok(hr == NS_E_FILE_NOT_FOUND, "Got hr %#lx.\n", hr);
- todo_wine
ok(obj_type == MF_OBJECT_INVALID, "Unexpected obj_type %#x.\n", obj_type);
if (object) IUnknown_Release(object);
@@ -6861,7 +6845,6 @@ static void test_network_bytestream(void)
hr = IMFAttributes_GetCount(attr, &count);
ok(hr == S_OK, "Got hr %#lx\n", hr);
- todo_wine
ok(count == 3, "count = %u\n", count);
PropVariantInit(&var);
@@ -6870,7 +6853,6 @@ static void test_network_bytestream(void)
ok(hr == S_OK, "Got hr %#lx\n", hr);
ok(IsEqualGUID(&key, &MF_BYTESTREAM_EFFECTIVE_URL), "Got key %s\n", debugstr_guid(&key));
ok(var.vt == VT_LPWSTR, "Got type %d\n", var.vt);
- todo_wine
ok(!lstrcmpW(var.pwszVal, EFFECTIVE_URL), "Got value %s\n", var.pszVal);
memset(&key, 0, sizeof(key));
PropVariantClear(&var);
@@ -6879,21 +6861,15 @@ static void test_network_bytestream(void)
ok(hr == S_OK, "Got hr %#lx\n", hr);
ok(IsEqualGUID(&key, &MF_BYTESTREAM_CONTENT_TYPE), "Got key %s\n", debugstr_guid(&key));
ok(var.vt == VT_LPWSTR, "Got type %d\n", var.vt);
- todo_wine
ok(!lstrcmpW(var.pwszVal, CONTENT_TYPE), "Got value %s\n", var.pszVal);
memset(&key, 0, sizeof(key));
PropVariantClear(&var);
hr = IMFAttributes_GetItemByIndex(attr, 2, &key, &var);
- todo_wine
ok(hr == S_OK, "Got hr %#lx\n", hr);
- todo_wine
ok(IsEqualGUID(&key, &MF_BYTESTREAM_LAST_MODIFIED_TIME), "Got key %s\n", debugstr_guid(&key));
- todo_wine
ok(var.vt == (VT_VECTOR | VT_I1 | VT_NULL), "Got type %d\n", var.vt);
- todo_wine
ok(var.blob.cbSize == sizeof(LAST_MODIFIED_TIME), "Got size %lu\n", var.blob.cbSize);
- todo_wine
ok(var.blob.pBlobData != NULL, "Got NULL value\n");
if (var.blob.cbSize == sizeof(LAST_MODIFIED_TIME) && var.blob.pBlobData)
ok(!memcmp(var.blob.pBlobData, LAST_MODIFIED_TIME, sizeof(LAST_MODIFIED_TIME)), "Got wrong value\n");
@@ -6912,9 +6888,7 @@ static void test_network_bytestream(void)
ptr = NULL;
hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamCacheControl, &ptr);
- todo_wine
ok(hr == S_OK, "Got hr %#lx.\n", hr);
- todo_wine
ok(ptr != NULL, "Got NULL ptr.\n");
if (SUCCEEDED(hr) && ptr)
{
@@ -6929,9 +6903,7 @@ static void test_network_bytestream(void)
ptr = NULL;
hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamBuffering, &ptr);
- todo_wine
ok(hr == S_OK, "Got hr %#lx.\n", hr);
- todo_wine
ok(ptr != NULL, "Got NULL ptr.\n");
if (SUCCEEDED(hr) && ptr)
{
@@ -6998,9 +6970,7 @@ static void test_network_bytestream(void)
ptr = NULL;
hr = IUnknown_QueryInterface(object, &IID_IMFByteStreamTimeSeek, &ptr);
- todo_wine
ok(hr == S_OK, "Got hr %#lx.\n", hr);
- todo_wine
ok(ptr != NULL, "Got NULL ptr.\n");
if (SUCCEEDED(hr) && ptr)
{
@@ -7059,6 +7029,9 @@ static void test_network_bytestream(void)
ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
ok(written == 0, "written = %lu\n", written);
+ hr = IMFByteStream_BeginWrite((IMFByteStream*)object, tmp, 1000, (void *)(DWORD_PTR)0xdeadbeef, NULL);
+ ok(hr == E_NOTIMPL, "Got hr %#lx.\n", hr);
+
free(tmp);
hr = IMFByteStream_GetLength((IMFByteStream*)object, &len);
@@ -7066,7 +7039,6 @@ static void test_network_bytestream(void)
ok(len != 0, "len = %I64u\n", len);
hr = IMFByteStream_Flush((IMFByteStream*)object);
- todo_wine
ok(hr == S_OK, "Got hr %#lx\n", hr);
}
@@ -7094,9 +7066,7 @@ static void test_network_bytestream(void)
ptr = NULL;
hr = IUnknown_QueryInterface(object, &IID_IMFMediaEventGenerator, &ptr);
- todo_wine
ok(hr == S_OK, "Got hr %#lx.\n", hr);
- todo_wine
ok(ptr != NULL, "Got NULL ptr.\n");
if (SUCCEEDED(hr) && ptr)
{
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec
index 7b356f9f457..f55f49b7e8c 100644
--- a/dlls/mfplat/mfplat.spec
+++ b/dlls/mfplat/mfplat.spec
@@ -181,3 +181,6 @@
@ stdcall -ret64 MFllMulDiv(int64 int64 int64 int64)
@ stub PropVariantFromStream
@ stub PropVariantToStream
+
+# Wine extension
+@ stdcall __wine_create_http_bytestream(wstr ptr)
diff --git a/dlls/mfplat/network.c b/dlls/mfplat/network.c
index d9a2981f5a7..2369dbf31fd 100644
--- a/dlls/mfplat/network.c
+++ b/dlls/mfplat/network.c
@@ -2012,3 +2012,8 @@ error:
hr = MF_E_UNSUPPORTED_BYTESTREAM_TYPE;
return hr;
}
+
+WINAPI HRESULT __wine_create_http_bytestream(const WCHAR *url, void **out)
+{
+ return create_http_bytestream(url, out);
+}
--
2.45.2

View File

@@ -0,0 +1,5 @@
Fixes: [52769] mf: Add HTTP/HTTPS IMFByteStream implementation.
# MR https://gitlab.winehq.org/wine/wine/-/merge_requests/6733
# Game: The good life.

View File

@@ -1,4 +1,4 @@
From c4694f8dfffa56648976c1a05bb4788262a8677b Mon Sep 17 00:00:00 2001
From 5bcc58b53dd99c5d6d85141d5658a5d7e98d8253 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?R=C3=A9mi=20Bernon?= <rbernon@codeweavers.com>
Date: Tue, 8 Sep 2020 18:43:52 +0200
Subject: [PATCH] msxml3: Implement FreeThreadedXMLHTTP60.
@@ -27,10 +27,10 @@ index 7e59a223143..5044c4e2c79 100644
SOURCES = \
diff --git a/dlls/msxml3/factory.c b/dlls/msxml3/factory.c
index 218ba87c4a8..ed14bd63a87 100644
index e35839db2a3..0e2482d61be 100644
--- a/dlls/msxml3/factory.c
+++ b/dlls/msxml3/factory.c
@@ -281,6 +281,7 @@ static HRESULT DOMClassFactory_Create(const GUID *clsid, REFIID riid, void **ppv
@@ -279,6 +279,7 @@ static HRESULT DOMClassFactory_Create(const GUID *clsid, REFIID riid, void **ppv
static ClassFactory xmldoccf = { { &ClassFactoryVtbl }, XMLDocument_create };
static ClassFactory httpreqcf = { { &ClassFactoryVtbl }, XMLHTTPRequest_create };
@@ -38,7 +38,7 @@ index 218ba87c4a8..ed14bd63a87 100644
static ClassFactory serverhttp = { { &ClassFactoryVtbl }, ServerXMLHTTP_create };
static ClassFactory xsltemplatecf = { { &ClassFactoryVtbl }, XSLTemplate_create };
static ClassFactory mxnsmanagercf = { {&ClassFactoryVtbl }, MXNamespaceManager_create };
@@ -342,6 +343,10 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
@@ -340,6 +341,10 @@ HRESULT WINAPI DllGetClassObject( REFCLSID rclsid, REFIID riid, void **ppv )
{
cf = &httpreqcf.IClassFactory_iface;
}
@@ -50,7 +50,7 @@ index 218ba87c4a8..ed14bd63a87 100644
IsEqualCLSID( rclsid, &CLSID_ServerXMLHTTP30 ) ||
IsEqualCLSID( rclsid, &CLSID_ServerXMLHTTP40 ) ||
diff --git a/dlls/msxml3/httprequest.c b/dlls/msxml3/httprequest.c
index 6e4ab4c6519..412958a2a40 100644
index 90be57ebabf..15a591c90be 100644
--- a/dlls/msxml3/httprequest.c
+++ b/dlls/msxml3/httprequest.c
@@ -37,10 +37,12 @@
@@ -65,9 +65,9 @@ index 6e4ab4c6519..412958a2a40 100644
-WINE_DEFAULT_DEBUG_CHANNEL(msxml);
+WINE_DEFAULT_DEBUG_CHANNEL(xmlhttp);
static const WCHAR colspaceW[] = {':',' ',0};
static const WCHAR crlfW[] = {'\r','\n',0};
@@ -2054,6 +2056,468 @@ static const struct IServerXMLHTTPRequestVtbl ServerXMLHTTPRequestVtbl =
static const DWORD safety_supported_options =
INTERFACESAFE_FOR_UNTRUSTED_CALLER |
@@ -2044,6 +2046,468 @@ static const struct IServerXMLHTTPRequestVtbl ServerXMLHTTPRequestVtbl =
ServerXMLHTTPRequest_setOption
};
@@ -536,7 +536,7 @@ index 6e4ab4c6519..412958a2a40 100644
static void init_httprequest(httprequest *req)
{
req->IXMLHTTPRequest_iface.lpVtbl = &XMLHTTPRequestVtbl;
@@ -2103,6 +2567,35 @@ HRESULT XMLHTTPRequest_create(void **obj)
@@ -2093,6 +2557,35 @@ HRESULT XMLHTTPRequest_create(void **obj)
return S_OK;
}
@@ -573,7 +573,7 @@ index 6e4ab4c6519..412958a2a40 100644
{
serverhttp *req;
diff --git a/dlls/msxml3/msxml_private.h b/dlls/msxml3/msxml_private.h
index 54f54995c76..6188414c5ce 100644
index ea492bc6b36..c2827563884 100644
--- a/dlls/msxml3/msxml_private.h
+++ b/dlls/msxml3/msxml_private.h
@@ -343,6 +343,7 @@ extern HRESULT XMLDocument_create(void**);
@@ -1061,7 +1061,7 @@ index 7214d23c5dc..320a7e04fa3 100644
/*
* Note that because of a #define in msxml2.h, we end up initializing
diff --git a/include/msxml6.idl b/include/msxml6.idl
index 7396826a1f6..b2d8bd3b337 100644
index bf7e0905057..a02f7b2db14 100644
--- a/include/msxml6.idl
+++ b/include/msxml6.idl
@@ -1715,17 +1715,6 @@ interface ISAXDeclHandler : IUnknown
@@ -1101,5 +1101,5 @@ index 7396826a1f6..b2d8bd3b337 100644
helpstring("XML DOM Document 6.0"),
progid("Msxml2.DOMDocument.6.0"),
--
2.43.0
2.47.2

View File

@@ -1,4 +1,4 @@
From e93243e7863c239a1e4b2d91cb12dcd2cb373b36 Mon Sep 17 00:00:00 2001
From 15c10643fa18d1159af85df3132ae3c2228d4488 Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sat, 30 May 2015 02:23:15 +0200
Subject: [PATCH] ntdll: Add support for hiding wine version information from
@@ -10,7 +10,7 @@ Subject: [PATCH] ntdll: Add support for hiding wine version information from
2 files changed, 103 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c
index 9dcb475c148..9e61c38d773 100644
index a292ba30774..60c72ffbb89 100644
--- a/dlls/ntdll/loader.c
+++ b/dlls/ntdll/loader.c
@@ -88,6 +88,9 @@ const WCHAR system_dir[] = L"C:\\windows\\system32\\";
@@ -32,7 +32,7 @@ index 9dcb475c148..9e61c38d773 100644
struct ldr_notification
{
struct list entry;
@@ -2022,6 +2027,96 @@ NTSTATUS WINAPI LdrUnlockLoaderLock( ULONG flags, ULONG_PTR magic )
@@ -2012,6 +2017,96 @@ NTSTATUS WINAPI LdrUnlockLoaderLock( ULONG flags, ULONG_PTR magic )
}
@@ -129,16 +129,16 @@ index 9dcb475c148..9e61c38d773 100644
/******************************************************************
* LdrGetProcedureAddress (NTDLL.@)
*/
@@ -2042,7 +2137,7 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, const ANSI_STRING *name,
@@ -2032,7 +2127,7 @@ NTSTATUS WINAPI LdrGetProcedureAddress(HMODULE module, const ANSI_STRING *name,
{
void *proc = name ? find_named_export( module, exports, exp_size, name->Buffer, -1, NULL )
: find_ordinal_export( module, exports, exp_size, ord - exports->Base, NULL );
void *proc = name ? find_named_export( module, exports, exp_size, name->Buffer, -1, NULL, NULL )
: find_ordinal_export( module, exports, exp_size, ord - exports->Base, NULL, NULL );
- if (proc)
+ if (proc && !is_hidden_export( proc ))
{
*address = proc;
ret = STATUS_SUCCESS;
@@ -2304,6 +2399,8 @@ static void build_ntdll_module(void)
@@ -2294,6 +2389,8 @@ static void build_ntdll_module(void)
wm->ldr.Flags &= ~LDR_DONT_RESOLVE_REFS;
node_ntdll = wm->ldr.DdagNode;
if (TRACE_ON(relay)) RELAY_SetupDLL( module );
@@ -164,5 +164,5 @@ index fb5fb311646..a342cbf7d26 100644
static inline void ascii_to_unicode( WCHAR *dst, const char *src, size_t len )
{
--
2.45.2
2.47.2

View File

@@ -1,4 +1,4 @@
From e062c6f139f716fe0e95a26e5016aa4f94087146 Mon Sep 17 00:00:00 2001
From db45e866f5d465e7da2e283e0fa97594fff7d6e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Sun, 17 Jan 2016 00:50:50 +0100
Subject: [PATCH] ntdll/tests: Add basic tests for RtlQueryPackageIdentity.
@@ -20,10 +20,10 @@ index 3742968c415..084469a2820 100644
SOURCES = \
atom.c \
diff --git a/dlls/ntdll/tests/rtl.c b/dlls/ntdll/tests/rtl.c
index d013848c07a..f239575d13e 100644
index eaee2768c6a..544744dd8e6 100644
--- a/dlls/ntdll/tests/rtl.c
+++ b/dlls/ntdll/tests/rtl.c
@@ -37,6 +37,9 @@
@@ -38,6 +38,9 @@
#include "wine/test.h"
#include "wine/asm.h"
#include "wine/rbtree.h"
@@ -33,9 +33,9 @@ index d013848c07a..f239575d13e 100644
#ifndef __WINE_WINTERNL_H
@@ -105,6 +108,9 @@ static BOOL (WINAPI *pRtlIsCriticalSectionLockedByThread)(CRITICAL_SECTION
static NTSTATUS (WINAPI *pRtlInitializeCriticalSectionEx)(CRITICAL_SECTION *, ULONG, ULONG);
static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char *);
@@ -118,6 +121,9 @@ static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char *);
static void * (WINAPI *pRtlLookupElementGenericTable)(PRTL_GENERIC_TABLE, void *);
static ULONG (WINAPI *pRtlNumberGenericTableElements)(PRTL_GENERIC_TABLE);
static NTSTATUS (WINAPI *pLdrEnumerateLoadedModules)(void *, void *, void *);
+static NTSTATUS (WINAPI *pRtlQueryPackageIdentity)(HANDLE, WCHAR*, SIZE_T*, WCHAR*, SIZE_T*, BOOLEAN*);
+static NTSTATUS (WINAPI *pRtlMakeSelfRelativeSD)(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
@@ -43,9 +43,9 @@ index d013848c07a..f239575d13e 100644
static NTSTATUS (WINAPI *pLdrRegisterDllNotification)(ULONG, PLDR_DLL_NOTIFICATION_FUNCTION, void *, void **);
static NTSTATUS (WINAPI *pLdrUnregisterDllNotification)(void *);
static VOID (WINAPI *pRtlGetDeviceFamilyInfoEnum)(ULONGLONG *,DWORD *,DWORD *);
@@ -152,6 +158,9 @@ static void InitFunctionPtrs(void)
pRtlInitializeCriticalSectionEx = (void *)GetProcAddress(hntdll, "RtlInitializeCriticalSectionEx");
pRtlFindExportedRoutineByName = (void *)GetProcAddress(hntdll, "RtlFindExportedRoutineByName");
@@ -185,6 +191,9 @@ static void InitFunctionPtrs(void)
pRtlLookupElementGenericTable = (void *)GetProcAddress(hntdll, "RtlLookupElementGenericTable");
pRtlNumberGenericTableElements = (void *)GetProcAddress(hntdll, "RtlNumberGenericTableElements");
pLdrEnumerateLoadedModules = (void *)GetProcAddress(hntdll, "LdrEnumerateLoadedModules");
+ pRtlQueryPackageIdentity = (void *)GetProcAddress(hntdll, "RtlQueryPackageIdentity");
+ pRtlMakeSelfRelativeSD = (void *)GetProcAddress(hntdll, "RtlMakeSelfRelativeSD");
@@ -53,7 +53,7 @@ index d013848c07a..f239575d13e 100644
pLdrRegisterDllNotification = (void *)GetProcAddress(hntdll, "LdrRegisterDllNotification");
pLdrUnregisterDllNotification = (void *)GetProcAddress(hntdll, "LdrUnregisterDllNotification");
pRtlGetDeviceFamilyInfoEnum = (void *)GetProcAddress(hntdll, "RtlGetDeviceFamilyInfoEnum");
@@ -3714,6 +3723,76 @@ static void test_RtlFirstFreeAce(void)
@@ -3756,6 +3765,76 @@ static void test_RtlFirstFreeAce(void)
HeapFree(GetProcessHeap(), 0, acl);
}
@@ -130,7 +130,7 @@ index d013848c07a..f239575d13e 100644
static void test_RtlInitializeSid(void)
{
SID_IDENTIFIER_AUTHORITY sid_ident = { SECURITY_NT_AUTHORITY };
@@ -3970,6 +4049,7 @@ START_TEST(rtl)
@@ -5189,6 +5268,7 @@ START_TEST(rtl)
test_RtlInitializeCriticalSectionEx();
test_RtlLeaveCriticalSection();
test_LdrEnumerateLoadedModules();
@@ -139,5 +139,5 @@ index d013848c07a..f239575d13e 100644
test_LdrRegisterDllNotification();
test_DbgPrint();
--
2.45.2
2.47.2

View File

@@ -1,166 +0,0 @@
From 1e6c40cf8a92d7873f1689d64936cd4dfd32f246 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Thu, 21 Apr 2016 14:40:58 +0800
Subject: [PATCH] oleaut32: OleLoadPicture should create a DIB section for a
being loaded bitmap. (v3)
Application in the bug 39474 depends on this (GetObject/bmBits should not be
NULL, otherwise it crashes).
---
dlls/oleaut32/olepicture.c | 65 +++++++++++++-------------------
dlls/oleaut32/tests/olepicture.c | 2 +-
2 files changed, 27 insertions(+), 40 deletions(-)
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c
index 8df0c22b6cf..b41668a4aeb 100644
--- a/dlls/oleaut32/olepicture.c
+++ b/dlls/oleaut32/olepicture.c
@@ -983,23 +983,16 @@ static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG xr
{
BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf;
BITMAPINFO *bi = (BITMAPINFO*)(bfh+1);
- HDC hdcref;
+ void *bits;
+ BITMAP bmp;
- /* Does not matter whether this is a coreheader or not, we only use
- * components which are in both
- */
- hdcref = GetDC(0);
- This->desc.bmp.hbitmap = CreateDIBitmap(
- hdcref,
- &(bi->bmiHeader),
- CBM_INIT,
- xbuf+bfh->bfOffBits,
- bi,
- DIB_RGB_COLORS
- );
- ReleaseDC(0, hdcref);
+ This->desc.bmp.hbitmap = CreateDIBSection(0, bi, DIB_RGB_COLORS, &bits, NULL, 0);
if (This->desc.bmp.hbitmap == 0)
return E_FAIL;
+
+ GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bmp), &bmp);
+ memcpy(bits, xbuf + bfh->bfOffBits, bmp.bmHeight * bmp.bmWidthBytes);
+
This->desc.picType = PICTYPE_BITMAP;
OLEPictureImpl_SetBitmap(This);
return S_OK;
@@ -1009,10 +1002,9 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
{
HRESULT hr;
BITMAPINFOHEADER bih;
- HDC hdcref;
UINT width, height;
UINT stride, buffersize;
- LPBYTE bits=NULL;
+ BYTE *bits, *mask = NULL;
WICRect rc;
IWICBitmapSource *real_source;
UINT x, y;
@@ -1040,34 +1032,28 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
stride = 4 * width;
buffersize = stride * height;
- bits = malloc(buffersize);
- if (!bits)
+ mask = malloc(buffersize);
+ if (!mask)
{
hr = E_OUTOFMEMORY;
goto end;
}
+ This->desc.bmp.hbitmap = CreateDIBSection(0, (BITMAPINFO*)&bih, DIB_RGB_COLORS, (void **)&bits, NULL, 0);
+ if (This->desc.bmp.hbitmap == 0)
+ {
+ hr = E_FAIL;
+ goto end;
+ }
+
rc.X = 0;
rc.Y = 0;
rc.Width = width;
rc.Height = height;
hr = IWICBitmapSource_CopyPixels(real_source, &rc, stride, buffersize, bits);
if (FAILED(hr))
- goto end;
-
- hdcref = GetDC(0);
- This->desc.bmp.hbitmap = CreateDIBitmap(
- hdcref,
- &bih,
- CBM_INIT,
- bits,
- (BITMAPINFO*)&bih,
- DIB_RGB_COLORS);
-
- if (This->desc.bmp.hbitmap == 0)
{
- hr = E_FAIL;
- ReleaseDC(0, hdcref);
+ DeleteObject(This->desc.bmp.hbitmap);
goto end;
}
@@ -1081,23 +1067,25 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
if((*pixel & 0x80000000) == 0)
{
has_alpha = TRUE;
- *pixel = black;
+ *(DWORD *)(mask + stride * y + 4 * x) = black;
}
else
- *pixel = white;
+ *(DWORD *)(mask + stride * y + 4 * x) = white;
}
}
if (has_alpha)
{
- HDC hdcBmp, hdcXor, hdcMask;
+ HDC hdcref, hdcBmp, hdcXor, hdcMask;
HBITMAP hbmoldBmp, hbmoldXor, hbmoldMask;
+ hdcref = GetDC(0);
+
This->hbmXor = CreateDIBitmap(
hdcref,
&bih,
CBM_INIT,
- bits,
+ mask,
(BITMAPINFO*)&bih,
DIB_RGB_COLORS
);
@@ -1122,12 +1110,11 @@ static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSour
DeleteDC(hdcBmp);
DeleteDC(hdcXor);
DeleteDC(hdcMask);
+ ReleaseDC(0, hdcref);
}
- ReleaseDC(0, hdcref);
-
end:
- free(bits);
+ free(mask);
IWICBitmapSource_Release(real_source);
return hr;
}
diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c
index 02d53404e32..98d081b745e 100644
--- a/dlls/oleaut32/tests/olepicture.c
+++ b/dlls/oleaut32/tests/olepicture.c
@@ -239,7 +239,7 @@ test_pic_with_stream(LPSTREAM stream, unsigned int imgsize)
{
BITMAP bmp;
GetObjectA(UlongToHandle(handle), sizeof(BITMAP), &bmp);
- todo_wine ok(bmp.bmBits != 0, "not a dib\n");
+ ok(bmp.bmBits != 0, "not a dib\n");
}
width = 0;
--
2.40.1

View File

@@ -1,93 +0,0 @@
From e72c3ef9b52c3b5b099907c017206f168cff419f Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 5 Apr 2017 12:03:19 +0800
Subject: [PATCH] oleaut32: Make OleLoadPicture load DIBs using WIC decoder.
CreateDIBSection doesn't support RLE compressed bitmaps.
This patch fixes a regression with displaying images in a Wix based
installer.
---
dlls/oleaut32/olepicture.c | 21 +--------------------
dlls/oleaut32/tests/olepicture.c | 12 +++++++++++-
2 files changed, 12 insertions(+), 21 deletions(-)
diff --git a/dlls/oleaut32/olepicture.c b/dlls/oleaut32/olepicture.c
index 22a34d6e380..37c3983ed21 100644
--- a/dlls/oleaut32/olepicture.c
+++ b/dlls/oleaut32/olepicture.c
@@ -979,25 +979,6 @@ static HRESULT WINAPI OLEPictureImpl_IsDirty(
return E_NOTIMPL;
}
-static HRESULT OLEPictureImpl_LoadDIB(OLEPictureImpl *This, BYTE *xbuf, ULONG xread)
-{
- BITMAPFILEHEADER *bfh = (BITMAPFILEHEADER*)xbuf;
- BITMAPINFO *bi = (BITMAPINFO*)(bfh+1);
- void *bits;
- BITMAP bmp;
-
- This->desc.bmp.hbitmap = CreateDIBSection(0, bi, DIB_RGB_COLORS, &bits, NULL, 0);
- if (This->desc.bmp.hbitmap == 0)
- return E_FAIL;
-
- GetObjectA(This->desc.u.bmp.hbitmap, sizeof(bmp), &bmp);
- memcpy(bits, xbuf + bfh->bfOffBits, bmp.bmHeight * bmp.bmWidthBytes);
-
- This->desc.picType = PICTYPE_BITMAP;
- OLEPictureImpl_SetBitmap(This);
- return S_OK;
-}
-
static HRESULT OLEPictureImpl_LoadWICSource(OLEPictureImpl *This, IWICBitmapSource *src)
{
HRESULT hr;
@@ -1478,7 +1459,7 @@ static HRESULT WINAPI OLEPictureImpl_Load(IPersistStream* iface, IStream *pStm)
hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICJpegDecoder, xbuf, xread);
break;
case BITMAP_FORMAT_BMP: /* Bitmap */
- hr = OLEPictureImpl_LoadDIB(This, xbuf, xread);
+ hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICBmpDecoder, xbuf, xread);
break;
case BITMAP_FORMAT_PNG: /* PNG */
hr = OLEPictureImpl_LoadWICDecoder(This, &CLSID_WICPngDecoder, xbuf, xread);
diff --git a/dlls/oleaut32/tests/olepicture.c b/dlls/oleaut32/tests/olepicture.c
index fa7e8009cbd..a1c3ccf20c3 100644
--- a/dlls/oleaut32/tests/olepicture.c
+++ b/dlls/oleaut32/tests/olepicture.c
@@ -97,7 +97,7 @@ static const unsigned char pngimage[285] = {
0xe7,0x00,0x00,0x00,0x00,0x49,0x45,0x4e,0x44,0xae,0x42,0x60,0x82
};
-/* 1x1 pixel bmp */
+/* 1bpp BI_RGB 1x1 pixel bmp */
static const unsigned char bmpimage[66] = {
0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,
@@ -106,6 +106,15 @@ static const unsigned char bmpimage[66] = {
0x00,0x00
};
+/* 8bpp BI_RLE8 1x1 pixel bmp */
+static const unsigned char bmpimage_rle8[] = {
+0x42,0x4d,0x42,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3e,0x00,0x00,0x00,0x28,0x00,
+0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x08,0x00,0x01,0x00,
+0x00,0x00,0x04,0x00,0x00,0x00,0x12,0x0b,0x00,0x00,0x12,0x0b,0x00,0x00,0x02,0x00,
+0x00,0x00,0x02,0x00,0x00,0x00,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0x00,0x00,0x01,
+0x00,0x00
+};
+
/* 2x2 pixel gif */
static const unsigned char gif4pixel[42] = {
0x47,0x49,0x46,0x38,0x37,0x61,0x02,0x00,0x02,0x00,0xa1,0x00,0x00,0x00,0x00,0x00,
@@ -1492,6 +1501,7 @@ START_TEST(olepicture)
test_pic(gifimage, sizeof(gifimage));
test_pic(jpgimage, sizeof(jpgimage));
test_pic(bmpimage, sizeof(bmpimage));
+ test_pic(bmpimage_rle8, sizeof(bmpimage_rle8));
test_pic(gif4pixel, sizeof(gif4pixel));
/* FIXME: No PNG support in Windows... */
if (0) test_pic(pngimage, sizeof(pngimage));
--
2.40.1

View File

@@ -1 +0,0 @@
Fixes: [39474] Create DIB section in OleLoadPicture

View File

@@ -0,0 +1,26 @@
From e27947e6cd77f408bf8586456b19c1ff2e41eea4 Mon Sep 17 00:00:00 2001
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
Date: Fri, 24 Jan 2025 20:15:24 +1100
Subject: [PATCH] oleaut32: VarAnd use VT_I4 when converting VT_BSTR
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=56280
---
dlls/oleaut32/variant.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/oleaut32/variant.c b/dlls/oleaut32/variant.c
index bb1e83e9b7e..ba6db0adf62 100644
--- a/dlls/oleaut32/variant.c
+++ b/dlls/oleaut32/variant.c
@@ -3114,7 +3114,7 @@ HRESULT WINAPI VarAnd(LPVARIANT left, LPVARIANT right, LPVARIANT result)
hres = VariantChangeType(&varLeft,&varLeft,
VARIANT_LOCALBOOL, VT_BOOL);
if (SUCCEEDED(hres) && V_VT(&varLeft) != resvt)
- hres = VariantChangeType(&varLeft,&varLeft,0,resvt);
+ hres = VariantChangeType(&varLeft,&varLeft,0, VT_I4);
if (FAILED(hres)) goto VarAnd_Exit;
}
--
2.45.2

View File

@@ -0,0 +1,2 @@
Fixes: [56280] oleaut32: VarAnd use VT_I4 when converting VT_BSTR

View File

@@ -0,0 +1,489 @@
From 852060d5a6f4b665482898855924608c3c995eed Mon Sep 17 00:00:00 2001
From: Damjan Jovanovic <damjan.jov@gmail.com>
Date: Mon, 6 Jan 2025 16:22:52 +1100
Subject: [PATCH] riched20: Implement IRichEditOle::ImportDataObject
---
dlls/riched20/richole.c | 67 ++++++-
dlls/riched20/tests/richole.c | 361 ++++++++++++++++++++++++++++++++++
2 files changed, 426 insertions(+), 2 deletions(-)
diff --git a/dlls/riched20/richole.c b/dlls/riched20/richole.c
index 51ae41d2fe7..5771c97cd77 100644
--- a/dlls/riched20/richole.c
+++ b/dlls/riched20/richole.c
@@ -1345,13 +1345,76 @@ IRichEditOle_fnHandsOffStorage(IRichEditOle *iface, LONG iob)
return E_NOTIMPL;
}
+static HRESULT import_dataobject(struct text_services *services, LPDATAOBJECT lpdataobj, CLIPFORMAT cf)
+{
+ HRESULT hr;
+ IDataObject *dataobject;
+ FORMATETC fmtetc;
+ STGMEDIUM medium;
+
+ if (lpdataobj != NULL)
+ dataobject = lpdataobj;
+ else
+ {
+ hr = OleGetClipboard(&dataobject);
+ if (FAILED(hr))
+ return hr;
+ }
+
+ fmtetc.cfFormat = cf;
+ fmtetc.ptd = NULL;
+ fmtetc.dwAspect = DVASPECT_CONTENT;
+ fmtetc.lindex = -1;
+ fmtetc.tymed = TYMED_HGLOBAL;
+ hr = IDataObject_GetData(dataobject, &fmtetc, &medium);
+ if (SUCCEEDED(hr))
+ {
+ void *text = GlobalLock(medium.hGlobal);
+ if (text != NULL)
+ {
+ SETTEXTEX settextex;
+ settextex.flags = ST_KEEPUNDO | ST_SELECTION;
+ settextex.codepage = CP_ACP;
+ if (cf == CF_UNICODETEXT)
+ settextex.codepage = CP_UNICODE;
+ hr = ITextServices_TxSendMessage(&services->ITextServices_iface, EM_SETTEXTEX, (WPARAM)&settextex, (LPARAM)text, NULL);
+ GlobalUnlock(medium.hGlobal);
+ }
+ else
+ hr = E_OUTOFMEMORY;
+ ReleaseStgMedium(&medium);
+ }
+
+ if (lpdataobj == NULL)
+ IDataObject_Release(dataobject);
+ return hr;
+}
+
static HRESULT WINAPI
IRichEditOle_fnImportDataObject(IRichEditOle *iface, LPDATAOBJECT lpdataobj,
CLIPFORMAT cf, HGLOBAL hMetaPict)
{
+ CLIPFORMAT cfRTF;
+ HRESULT hr;
struct text_services *services = impl_from_IRichEditOle( iface );
- FIXME("stub %p\n", services);
- return E_NOTIMPL;
+ TRACE("(%p, %p, %hu, %p)\n", services, lpdataobj, cf, hMetaPict);
+
+ cfRTF = RegisterClipboardFormatA("Rich Text Format");
+ if (cf == cfRTF)
+ hr = import_dataobject(services, lpdataobj, cf);
+ else if (cf == CF_TEXT || cf == CF_UNICODETEXT)
+ hr = import_dataobject(services, lpdataobj, cf);
+ else if (cf == 0)
+ {
+ hr = import_dataobject(services, lpdataobj, cfRTF);
+ if (hr == DV_E_FORMATETC)
+ hr = import_dataobject(services, lpdataobj, CF_UNICODETEXT);
+ if (hr == DV_E_FORMATETC)
+ hr = import_dataobject(services, lpdataobj, CF_TEXT);
+ }
+ else
+ hr = DV_E_FORMATETC;
+ return hr;
}
static HRESULT WINAPI
diff --git a/dlls/riched20/tests/richole.c b/dlls/riched20/tests/richole.c
index fb5177b83e9..1365acfdda5 100644
--- a/dlls/riched20/tests/richole.c
+++ b/dlls/riched20/tests/richole.c
@@ -33,6 +33,7 @@
#include <tom.h>
#include <imm.h>
#include <textserv.h>
+#include <ntuser.h>
#include <wine/test.h>
#define EXPECT_TODO_WINE 0x80000000UL
@@ -604,6 +605,304 @@ static HRESULT testoleobj_Create( struct testoleobj **objptr )
return S_OK;
}
+struct reole_dataobject
+{
+ IDataObject IDataObject_iface;
+ LONG ref;
+
+ struct format_entry **entries;
+ DWORD entry_count;
+};
+
+struct reole_fmt_iterator
+{
+ IEnumFORMATETC IEnumFORMATETC_iface;
+ LONG ref;
+
+ struct reole_dataobject *dataobject;
+ DWORD current_entry;
+};
+
+static inline struct reole_fmt_iterator *impl_from_IEnumFORMATETC(IEnumFORMATETC *iface)
+{
+ return CONTAINING_RECORD(iface, struct reole_fmt_iterator, IEnumFORMATETC_iface);
+}
+
+static inline struct reole_dataobject *impl_from_IDataObject(IDataObject *iface)
+{
+ return CONTAINING_RECORD(iface, struct reole_dataobject, IDataObject_iface);
+}
+
+static HRESULT STDMETHODCALLTYPE reole_fmt_iterator_QueryInterface(IEnumFORMATETC *iface, REFIID iid, void **obj)
+{
+ struct reole_fmt_iterator *This = impl_from_IEnumFORMATETC(iface);
+
+ if (IsEqualIID(iid, &IID_IUnknown) || IsEqualIID(iid, &IID_IEnumFORMATETC))
+ {
+ IEnumFORMATETC_AddRef(&This->IEnumFORMATETC_iface);
+ *obj = &This->IEnumFORMATETC_iface;
+ return S_OK;
+ }
+ *obj = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE reole_fmt_iterator_AddRef(IEnumFORMATETC *iface)
+{
+ struct reole_fmt_iterator *This = impl_from_IEnumFORMATETC(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+ return ref;
+}
+
+static ULONG STDMETHODCALLTYPE reole_fmt_iterator_Release(IEnumFORMATETC *iface)
+{
+ struct reole_fmt_iterator *This = impl_from_IEnumFORMATETC(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+
+ if (!ref)
+ {
+ IDataObject_Release(&This->dataobject->IDataObject_iface);
+ free(This);
+ }
+ return ref;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_fmt_iterator_Next(IEnumFORMATETC *iface, ULONG count, FORMATETC *formats, ULONG *ret)
+{
+ struct reole_fmt_iterator *This = impl_from_IEnumFORMATETC(iface);
+ UINT i;
+
+ for (i = 0; i < count && (This->current_entry + i) < This->dataobject->entry_count; i++)
+ {
+ formats[i].cfFormat = This->dataobject->entries[This->current_entry + i]->format;
+ formats[i].ptd = NULL;
+ formats[i].dwAspect = DVASPECT_CONTENT;
+ formats[i].lindex = -1;
+ formats[i].tymed = TYMED_HGLOBAL;
+ }
+
+ This->current_entry += i;
+ if (ret) *ret = i;
+ return (i == count) ? S_OK : S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_fmt_iterator_Skip(IEnumFORMATETC *iface, ULONG count)
+{
+ struct reole_fmt_iterator *This = impl_from_IEnumFORMATETC(iface);
+
+ if (This->current_entry + count < This->dataobject->entry_count)
+ {
+ This->current_entry += count;
+ return S_OK;
+ }
+ else
+ {
+ This->current_entry = This->dataobject->entry_count;
+ return S_FALSE;
+ }
+}
+
+static HRESULT STDMETHODCALLTYPE reole_fmt_iterator_Reset(IEnumFORMATETC *iface)
+{
+ struct reole_fmt_iterator *This = impl_from_IEnumFORMATETC(iface);
+ This->current_entry = 0;
+ return S_OK;
+}
+
+static HRESULT reole_fmt_iterator_Create(struct reole_dataobject *dataobject, struct reole_fmt_iterator **iterator);
+
+static HRESULT STDMETHODCALLTYPE reole_fmt_iterator_Clone(IEnumFORMATETC *iface, IEnumFORMATETC **out)
+{
+ HRESULT hr;
+ struct reole_fmt_iterator *cloned;
+ struct reole_fmt_iterator *This = impl_from_IEnumFORMATETC(iface);
+ hr = reole_fmt_iterator_Create(This->dataobject, &cloned);
+ if (SUCCEEDED(hr))
+ {
+ cloned->current_entry = This->current_entry;
+ *out = &cloned->IEnumFORMATETC_iface;
+ }
+ return hr;
+}
+
+static const IEnumFORMATETCVtbl reole_fmt_iterator_vtbl =
+{
+ reole_fmt_iterator_QueryInterface,
+ reole_fmt_iterator_AddRef,
+ reole_fmt_iterator_Release,
+ reole_fmt_iterator_Next,
+ reole_fmt_iterator_Skip,
+ reole_fmt_iterator_Reset,
+ reole_fmt_iterator_Clone,
+};
+
+static HRESULT reole_fmt_iterator_Create(struct reole_dataobject *dataobject, struct reole_fmt_iterator **iterator)
+{
+ struct reole_fmt_iterator *it;
+ if (!(it = calloc(sizeof(struct reole_fmt_iterator), 1))) return E_OUTOFMEMORY;
+ it->IEnumFORMATETC_iface.lpVtbl = &reole_fmt_iterator_vtbl;
+ it->ref = 1;
+ it->dataobject = dataobject;
+ IDataObject_AddRef(&dataobject->IDataObject_iface);
+ it->current_entry = 0;
+ *iterator = it;
+ return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_dataobject_QueryInterface(IDataObject *iface, REFIID riid, void **obj)
+{
+ if (IsEqualGUID(riid, &IID_IUnknown) || IsEqualGUID(riid, &IID_IDataObject)) {
+ IDataObject_AddRef(iface);
+ *obj = iface;
+ return S_OK;
+ }
+ *obj = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE reole_dataobject_AddRef(IDataObject *iface)
+{
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ ULONG ref = InterlockedIncrement(&This->ref);
+ return ref;
+}
+
+static ULONG STDMETHODCALLTYPE reole_dataobject_Release(IDataObject *iface)
+{
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ ULONG ref = InterlockedDecrement(&This->ref);
+ if (!ref) free(This);
+ return ref;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_dataobject_GetData(IDataObject *iface, FORMATETC *format, STGMEDIUM *medium)
+{
+ UINT i;
+ HRESULT hr;
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ if (FAILED(hr = IDataObject_QueryGetData(iface, format))) return hr;
+ for (i = 0; i < This->entry_count; i++)
+ {
+ if (format->cfFormat == This->entries[i]->format)
+ {
+ medium->tymed = TYMED_HGLOBAL;
+ medium->hGlobal = GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT, This->entries[i]->size);
+ if (medium->hGlobal == NULL) return E_OUTOFMEMORY;
+ memcpy(GlobalLock(medium->hGlobal), This->entries[i]->data, This->entries[i]->size);
+ GlobalUnlock(medium->hGlobal);
+ medium->pUnkForRelease = 0;
+ return S_OK;
+ }
+ }
+ return DATA_E_FORMATETC;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_dataobject_GetDataHere(IDataObject *iface, FORMATETC *format, STGMEDIUM *medium)
+{
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ trace("this %p, format %p, medium %p stub!\n", This, format, medium);
+ return DATA_E_FORMATETC;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_dataobject_QueryGetData(IDataObject *iface, FORMATETC *format)
+{
+ UINT i;
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ if (format->tymed && !(format->tymed & TYMED_HGLOBAL))
+ {
+ trace("only HGLOBAL medium types supported right now\n");
+ return DV_E_TYMED;
+ }
+ for (i = 0; i < This->entry_count; i++)
+ {
+ if (format->cfFormat == This->entries[i]->format)
+ return S_OK;
+ }
+ return DV_E_FORMATETC;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_dataobject_GetCanonicalFormatEtc(IDataObject *iface, FORMATETC *format, FORMATETC *out)
+{
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ trace("this %p, format %p, out %p stub!\n", This, format, out);
+ out->ptd = NULL;
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_dataobject_SetData(IDataObject *iface, FORMATETC *format, STGMEDIUM *medium, BOOL release)
+{
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ trace("this %p, format %p, medium %p, release %u stub!\n", This, format, medium, release);
+ return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_dataobject_EnumFormatEtc(IDataObject *iface, DWORD direction, IEnumFORMATETC **out)
+{
+ HRESULT hr;
+ struct reole_fmt_iterator *it;
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ if (direction != DATADIR_GET)
+ {
+ trace("only the get direction is implemented\n");
+ return E_NOTIMPL;
+ }
+ hr = reole_fmt_iterator_Create(This, &it);
+ if (SUCCEEDED(hr))
+ *out = &it->IEnumFORMATETC_iface;
+ return hr;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_dataobject_DAdvise(IDataObject *iface, FORMATETC *format, DWORD flags,
+ IAdviseSink *sink, DWORD *connection)
+{
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ trace("dataobject %p, format %p, flags %#lx, sink %p, connection %p stub!\n",
+ This, format, flags, sink, connection);
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_dataobject_DUnadvise(IDataObject *iface, DWORD connection)
+{
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ trace("this %p, connection %lu stub!\n", This, connection);
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+static HRESULT STDMETHODCALLTYPE reole_dataobject_EnumDAdvise(IDataObject *iface, IEnumSTATDATA **advise)
+{
+ struct reole_dataobject *This = impl_from_IDataObject(iface);
+ trace("this %p, advise %p stub!\n", This, advise);
+ return OLE_E_ADVISENOTSUPPORTED;
+}
+
+static IDataObjectVtbl reole_dataobject_vtbl =
+{
+ reole_dataobject_QueryInterface,
+ reole_dataobject_AddRef,
+ reole_dataobject_Release,
+ reole_dataobject_GetData,
+ reole_dataobject_GetDataHere,
+ reole_dataobject_QueryGetData,
+ reole_dataobject_GetCanonicalFormatEtc,
+ reole_dataobject_SetData,
+ reole_dataobject_EnumFormatEtc,
+ reole_dataobject_DAdvise,
+ reole_dataobject_DUnadvise,
+ reole_dataobject_EnumDAdvise,
+};
+
+static HRESULT reole_dataobject_Create(struct reole_dataobject **dataobject, struct format_entry **entries, DWORD entry_count)
+{
+ struct reole_dataobject *This;
+ if (!(This = calloc(sizeof(struct reole_dataobject), 1))) return E_OUTOFMEMORY;
+ This->IDataObject_iface.lpVtbl = &reole_dataobject_vtbl;
+ This->ref = 1;
+ This->entries = entries;
+ This->entry_count = entry_count;
+ *dataobject = This;
+ return S_OK;
+}
+
static HMODULE hmoduleRichEdit;
DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
@@ -5035,6 +5334,67 @@ static void test_clipboard(void)
ITextRange_Release(range);
}
+static struct format_entry* alloc_format_entry(UINT format, UINT size, const char *data)
+{
+ struct format_entry *entry = calloc(1, sizeof(struct format_entry) + size);
+ if (entry == NULL)
+ return NULL;
+ entry->format = format;
+ entry->size = size;
+ memcpy(&entry->data, data, size);
+ return entry;
+}
+
+static void test_import_data(void)
+{
+ static const char text_abc[] = "abc";
+ IRichEditOle *reole = NULL;
+ ITextDocument *doc = NULL;
+ ITextSelection *selection;
+ HRESULT hr;
+ HWND hwnd;
+ char buffer[1024] = "";
+ struct format_entry *text_entry;
+ struct reole_dataobject *dataobject;
+
+ text_entry = alloc_format_entry(CF_TEXT, 3, "cd");
+ ok(text_entry != NULL, "failed to create text_entry\n");
+ hr = reole_dataobject_Create(&dataobject, &text_entry, 1);
+ ok(hr == S_OK, "reole_dataobject_Create failed\n");
+ create_interfaces(&hwnd, &reole, &doc, &selection);
+
+ /* Test our IDataObject */
+ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)"");
+ hr = IRichEditOle_ImportDataObject(reole, &dataobject->IDataObject_iface, 0, NULL);
+ ok(hr == S_OK, "got hr 0x%08lx\n", hr);
+ SendMessageA(hwnd, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(strcmp(buffer, "cd") == 0, "text shouldn't be %s", buffer);
+
+ /* Try import CF_BITMAP which doesn't exist in our IDataObject */
+ hr = IRichEditOle_ImportDataObject(reole, &dataobject->IDataObject_iface, CF_BITMAP, NULL);
+ ok(hr == DV_E_FORMATETC, "got hr 0x%08lx\n", hr);
+
+ /* When IDataObject is NULL, IRichEditOle::ImportDataObject() will import from the clipboard */
+ SendMessageA(hwnd, WM_SETTEXT, 0, (LPARAM)text_abc);
+ hr = ITextSelection_SetStart(selection, 0);
+ ok(SUCCEEDED(hr), "got hr 0x%08lx\n", hr);
+ hr = ITextSelection_SetEnd(selection, 3);
+ ok(SUCCEEDED(hr), "got hr 0x%08lx\n", hr);
+ hr = ITextSelection_Copy(selection, NULL);
+ ok(hr == S_OK, "couldn't copy to clipboard: 0x%08lx\n", hr);
+ hr = ITextSelection_SetEnd(selection, 0);
+ ok(SUCCEEDED(hr), "got hr 0x%08lx\n", hr);
+ hr = IRichEditOle_ImportDataObject(reole, NULL, 0, NULL);
+ ok(hr == S_OK, "got 0x%08lx\n", hr);
+ memset(buffer, 0, ARRAY_SIZE(buffer));
+ SendMessageA(hwnd, WM_GETTEXT, ARRAY_SIZE(buffer), (LPARAM)buffer);
+ ok(strcmp(buffer, "abcabc") == 0, "text shouldn't be %s", buffer);
+
+ release_interfaces(&hwnd, &reole, &doc, &selection);
+ IDataObject_Release(&dataobject->IDataObject_iface);
+ free(text_entry);
+}
+
static void subtest_undo(const char *dummy_text)
{
static const char *text_seq[] = {
@@ -5606,6 +5966,7 @@ START_TEST(richole)
test_MoveEnd_story();
test_character_movement();
test_clipboard();
+ test_import_data();
test_undo();
test_undo_control();
test_freeze();
--
2.45.2

View File

@@ -0,0 +1 @@
Fixes: [26302] richedit20: Implement IRichEditOle::ImportDataObject

View File

@@ -1,4 +1,4 @@
From a3f14d043f05ff7cfaf00bc548d02f32dd85cc8f Mon Sep 17 00:00:00 2001
From 1569189e4213b5df68680c56e18f397873bc19aa Mon Sep 17 00:00:00 2001
From: Sebastian Lackner <sebastian@fds-team.de>
Date: Sun, 15 Mar 2015 01:05:48 +0100
Subject: [PATCH] server: Fix handling of GetMessage after previous PeekMessage
@@ -15,10 +15,10 @@ Changes in v3:
2 files changed, 65 insertions(+), 17 deletions(-)
diff --git a/dlls/user32/tests/msg.c b/dlls/user32/tests/msg.c
index 398bb0a69ed..2aec627604c 100644
index 9282896262e..d4749a1eb57 100644
--- a/dlls/user32/tests/msg.c
+++ b/dlls/user32/tests/msg.c
@@ -14353,13 +14353,10 @@ static void test_PeekMessage3(void)
@@ -14478,13 +14478,10 @@ static void test_PeekMessage3(void)
ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
PostMessageA(hwnd, WM_USER, 0, 0);
ret = PeekMessageA(&msg, hwnd, 0, 0, PM_NOREMOVE);
@@ -32,7 +32,7 @@ index 398bb0a69ed..2aec627604c 100644
ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
ret = PeekMessageA(&msg, hwnd, 0, 0, 0);
ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
@@ -14369,10 +14366,8 @@ static void test_PeekMessage3(void)
@@ -14494,10 +14491,8 @@ static void test_PeekMessage3(void)
ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
PostMessageA(hwnd, WM_USER, 0, 0);
ret = PeekMessageA(&msg, hwnd, 0, 0, PM_REMOVE);
@@ -43,7 +43,7 @@ index 398bb0a69ed..2aec627604c 100644
ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
ret = PeekMessageA(&msg, hwnd, 0, 0, 0);
ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
@@ -14384,10 +14379,11 @@ static void test_PeekMessage3(void)
@@ -14509,10 +14504,11 @@ static void test_PeekMessage3(void)
ok(msg.message == WM_TIMER, "msg.message = %u instead of WM_TIMER\n", msg.message);
PostMessageA(hwnd, WM_USER, 0, 0);
ret = GetMessageA(&msg, hwnd, 0, 0);
@@ -57,7 +57,7 @@ index 398bb0a69ed..2aec627604c 100644
ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
ret = PeekMessageA(&msg, hwnd, 0, 0, 0);
ok(!ret, "expected PeekMessage to return FALSE, got %u\n", ret);
@@ -14415,14 +14411,32 @@ static void test_PeekMessage3(void)
@@ -14540,14 +14536,32 @@ static void test_PeekMessage3(void)
ret = GetMessageA(&msg, hwnd, 0, 0);
ok(ret && msg.message == WM_USER, "msg.message = %u instead of WM_USER\n", msg.message);
ret = GetMessageA(&msg, hwnd, 0, 0);
@@ -93,10 +93,10 @@ index 398bb0a69ed..2aec627604c 100644
* because both messages are in the same queue. */
diff --git a/server/queue.c b/server/queue.c
index 4f58b795b7e..3fa5c05214e 100644
index 520659d377c..2d23fb0def8 100644
--- a/server/queue.c
+++ b/server/queue.c
@@ -143,6 +143,7 @@ struct msg_queue
@@ -133,6 +133,7 @@ struct msg_queue
timeout_t last_get_msg; /* time of last get message call */
int keystate_lock; /* owns an input keystate lock */
const queue_shm_t *shared; /* queue in session shared memory */
@@ -104,7 +104,7 @@ index 4f58b795b7e..3fa5c05214e 100644
};
struct hotkey
@@ -309,6 +310,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
@@ -312,6 +313,7 @@ static struct msg_queue *create_msg_queue( struct thread *thread, struct thread_
queue->hooks = NULL;
queue->last_get_msg = current_time;
queue->keystate_lock = 0;
@@ -112,7 +112,7 @@ index 4f58b795b7e..3fa5c05214e 100644
list_init( &queue->send_result );
list_init( &queue->callback_result );
list_init( &queue->pending_timers );
@@ -725,13 +727,21 @@ static inline struct msg_queue *get_current_queue(void)
@@ -792,13 +794,21 @@ static inline struct msg_queue *get_current_queue(void)
}
/* get a (pseudo-)unique id to tag hardware messages */
@@ -132,10 +132,10 @@ index 4f58b795b7e..3fa5c05214e 100644
+ return id;
+}
+
/* try to merge a WM_MOUSEMOVE message with the last in the list; return 1 if successful */
static int merge_mousemove( struct thread_input *input, const struct message *msg )
/* lookup an already queued mouse message that matches the message, window and type */
static struct message *find_mouse_message( struct thread_input *input, const struct message *msg )
{
@@ -1042,7 +1052,7 @@ static int match_window( user_handle_t win, user_handle_t msg_win )
@@ -1144,7 +1154,7 @@ static int match_window( user_handle_t win, user_handle_t msg_win )
}
/* retrieve a posted message */
@@ -144,7 +144,7 @@ index 4f58b795b7e..3fa5c05214e 100644
unsigned int first, unsigned int last, unsigned int flags,
struct get_message_reply *reply )
{
@@ -1053,6 +1063,7 @@ static int get_posted_message( struct msg_queue *queue, user_handle_t win,
@@ -1155,6 +1165,7 @@ static int get_posted_message( struct msg_queue *queue, user_handle_t win,
{
if (!match_window( win, msg->win )) continue;
if (!check_msg_filter( msg->msg, first, last )) continue;
@@ -152,15 +152,15 @@ index 4f58b795b7e..3fa5c05214e 100644
goto found; /* found one */
}
return 0;
@@ -1676,6 +1687,7 @@ found:
@@ -1835,6 +1846,7 @@ found:
msg->msg = WM_HOTKEY;
msg->wparam = hotkey->id;
msg->lparam = ((hotkey->vkey & 0xffff) << 16) | modifiers;
+ msg->unique_id = get_unique_post_id();
+ msg->unique_id = get_unique_hw_id();
free( msg->data );
msg->data = NULL;
@@ -2646,7 +2658,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
@@ -2821,7 +2833,7 @@ static int get_hardware_message( struct thread *thread, unsigned int hw_id, user
}
/* now we can return it */
@@ -169,7 +169,7 @@ index 4f58b795b7e..3fa5c05214e 100644
reply->type = MSG_HARDWARE;
reply->win = win;
reply->msg = msg_code;
@@ -2753,6 +2765,7 @@ void post_message( user_handle_t win, unsigned int message, lparam_t wparam, lpa
@@ -2928,6 +2940,7 @@ void post_message( user_handle_t win, unsigned int message, lparam_t wparam, lpa
msg->result = NULL;
msg->data = NULL;
msg->data_size = 0;
@@ -177,7 +177,7 @@ index 4f58b795b7e..3fa5c05214e 100644
get_message_defaults( thread->queue, &msg->x, &msg->y, &msg->time );
@@ -3070,6 +3083,7 @@ DECL_HANDLER(send_message)
@@ -3245,6 +3258,7 @@ DECL_HANDLER(send_message)
set_queue_bits( recv_queue, QS_SENDMESSAGE );
break;
case MSG_POSTED:
@@ -185,7 +185,7 @@ index 4f58b795b7e..3fa5c05214e 100644
list_add_tail( &recv_queue->msg_list[POST_MESSAGE], &msg->entry );
set_queue_bits( recv_queue, QS_POSTMESSAGE|QS_ALLPOSTMESSAGE );
if (msg->msg == WM_HOTKEY)
@@ -3202,12 +3216,12 @@ DECL_HANDLER(get_message)
@@ -3379,12 +3393,12 @@ DECL_HANDLER(get_message)
/* then check for posted messages */
if ((filter & QS_POSTMESSAGE) &&
@@ -200,7 +200,7 @@ index 4f58b795b7e..3fa5c05214e 100644
return;
/* only check for quit messages if not posted messages pending */
@@ -3218,7 +3232,7 @@ DECL_HANDLER(get_message)
@@ -3395,7 +3409,7 @@ DECL_HANDLER(get_message)
if ((filter & QS_INPUT) &&
filter_contains_hw_range( req->get_first, req->get_last ) &&
get_hardware_message( current, req->hw_id, get_win, req->get_first, req->get_last, req->flags, reply ))
@@ -209,7 +209,7 @@ index 4f58b795b7e..3fa5c05214e 100644
/* now check for WM_PAINT */
if ((filter & QS_PAINT) &&
@@ -3231,7 +3245,7 @@ DECL_HANDLER(get_message)
@@ -3408,7 +3422,7 @@ DECL_HANDLER(get_message)
reply->wparam = 0;
reply->lparam = 0;
get_message_defaults( queue, &reply->x, &reply->y, &reply->time );
@@ -218,7 +218,7 @@ index 4f58b795b7e..3fa5c05214e 100644
}
/* now check for timer */
@@ -3247,9 +3261,19 @@ DECL_HANDLER(get_message)
@@ -3424,9 +3438,19 @@ DECL_HANDLER(get_message)
get_message_defaults( queue, &reply->x, &reply->y, &reply->time );
if (!(req->flags & PM_NOYIELD) && current->process->idle_event)
set_event( current->process->idle_event );
@@ -239,7 +239,7 @@ index 4f58b795b7e..3fa5c05214e 100644
if (get_win == -1 && current->process->idle_event) set_event( current->process->idle_event );
SHARED_WRITE_BEGIN( queue_shm, queue_shm_t )
@@ -3260,6 +3284,13 @@ DECL_HANDLER(get_message)
@@ -3437,6 +3461,13 @@ DECL_HANDLER(get_message)
SHARED_WRITE_END;
set_error( STATUS_PENDING ); /* FIXME */
@@ -253,7 +253,7 @@ index 4f58b795b7e..3fa5c05214e 100644
}
@@ -3277,7 +3308,10 @@ DECL_HANDLER(reply_message)
@@ -3454,7 +3485,10 @@ DECL_HANDLER(reply_message)
DECL_HANDLER(accept_hardware_message)
{
if (current->queue)
@@ -265,5 +265,5 @@ index 4f58b795b7e..3fa5c05214e 100644
set_error( STATUS_ACCESS_DENIED );
}
--
2.43.0
2.47.2

Some files were not shown because too many files have changed in this diff Show More