[PATCH 1/5] qasf/tests: Add more ASF Reader filter tests.

Rémi Bernon wine at gitlab.winehq.org
Mon May 23 07:07:43 CDT 2022


From: Rémi Bernon <rbernon at codeweavers.com>

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
---
 dlls/qasf/tests/Makefile.in |   4 +-
 dlls/qasf/tests/asfreader.c | 234 +++++++++++++++++++++++++++++++++++-
 dlls/qasf/tests/resource.rc |  24 ++++
 dlls/qasf/tests/test.wmv    | Bin 0 -> 45663 bytes
 4 files changed, 257 insertions(+), 5 deletions(-)
 create mode 100644 dlls/qasf/tests/resource.rc
 create mode 100644 dlls/qasf/tests/test.wmv

diff --git a/dlls/qasf/tests/Makefile.in b/dlls/qasf/tests/Makefile.in
index 4b8d40671fb..e68b97c0408 100644
--- a/dlls/qasf/tests/Makefile.in
+++ b/dlls/qasf/tests/Makefile.in
@@ -1,6 +1,8 @@
 TESTDLL   = qasf.dll
-IMPORTS   = strmbase dmoguids strmiids uuid msdmo ole32
+IMPORTS   = strmbase dmoguids strmiids uuid wmvcore msdmo ole32
 
 C_SRCS = \
 	asfreader.c \
 	dmowrapper.c
+
+RC_SRCS = resource.rc
diff --git a/dlls/qasf/tests/asfreader.c b/dlls/qasf/tests/asfreader.c
index f4f8b9e2e19..a2b56ee29de 100644
--- a/dlls/qasf/tests/asfreader.c
+++ b/dlls/qasf/tests/asfreader.c
@@ -22,17 +22,19 @@
 #define COBJMACROS
 
 #include "dshow.h"
+#include "mediaobj.h"
+#include "propsys.h"
+#include "dvdmedia.h"
 #include "wine/strmbase.h"
 #include "wine/test.h"
 
 #include "initguid.h"
+#include "wmsdk.h"
+#include "wmcodecdsp.h"
 
+DEFINE_GUID(WMMEDIASUBTYPE_WMV1,0x31564d57,0x0000,0x0010,0x80,0x00,0x00,0xaa,0x00,0x38,0x9b,0x71);
 static const GUID testguid = {0x22222222, 0x2222, 0x2222, {0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22}};
 
-DEFINE_GUID(IID_IWMHeaderInfo,      0x96406bda, 0x2b2b, 0x11d3, 0xb3, 0x6b, 0x00, 0xc0, 0x4f, 0x61, 0x08, 0xff);
-DEFINE_GUID(IID_IWMReaderAdvanced,  0x96406bea, 0x2b2b, 0x11d3, 0xb3, 0x6b, 0x00, 0xc0, 0x4f, 0x61, 0x08, 0xff);
-DEFINE_GUID(IID_IWMReaderAdvanced2, 0xae14a945, 0xb90c, 0x4d0d, 0x91, 0x27, 0x80, 0xd6, 0x65, 0xf7, 0xd7, 0x3e);
-
 static IBaseFilter *create_asf_reader(void)
 {
     IBaseFilter *filter = NULL;
@@ -45,6 +47,31 @@ static IBaseFilter *create_asf_reader(void)
     return filter;
 }
 
+static WCHAR *load_resource(const WCHAR *name)
+{
+    static WCHAR pathW[MAX_PATH];
+    DWORD written;
+    HANDLE file;
+    HRSRC res;
+    void *ptr;
+
+    GetTempPathW(ARRAY_SIZE(pathW), pathW);
+    wcscat(pathW, name);
+
+    file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0);
+    ok(file != INVALID_HANDLE_VALUE, "Failed to create file %s, error %lu.\n",
+            wine_dbgstr_w(pathW), GetLastError());
+
+    res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
+    ok(!!res, "Failed to load resource, error %lu.\n", GetLastError());
+    ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
+    WriteFile(file, ptr, SizeofResource( GetModuleHandleA(NULL), res), &written, NULL);
+    ok(written == SizeofResource(GetModuleHandleA(NULL), res), "Failed to write resource.\n");
+    CloseHandle(file);
+
+    return pathW;
+}
+
 static ULONG get_refcount(void *iface)
 {
     IUnknown *unknown = iface;
@@ -183,8 +210,147 @@ static void test_aggregation(void)
     ok(outer_ref == 1, "Got unexpected refcount %ld.\n", outer_ref);
 }
 
+static inline BOOL compare_media_types(const AM_MEDIA_TYPE *a, const AM_MEDIA_TYPE *b)
+{
+    return !memcmp(a, b, offsetof(AM_MEDIA_TYPE, pbFormat))
+            && !memcmp(a->pbFormat, b->pbFormat, a->cbFormat);
+}
+
+static inline void check_pin(IPin *pin, IBaseFilter *expect_filter, PIN_DIRECTION expect_dir,
+        const WCHAR *expect_name, const WCHAR *expect_id, AM_MEDIA_TYPE *expect_mt, UINT expect_mt_count)
+{
+    IEnumMediaTypes *enum_mt;
+    AM_MEDIA_TYPE *mt;
+    PIN_INFO info;
+    HRESULT hr;
+    WCHAR *id;
+    UINT i;
+
+    hr = IPin_QueryPinInfo(pin, &info);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    ok(info.pFilter == expect_filter, "Got filter %p\n", info.pFilter);
+    ok(info.dir == expect_dir, "Got dir %u\n", info.dir);
+    todo_wine
+    ok(!wcscmp(info.achName, expect_name), "Got name %s\n", wine_dbgstr_w(info.achName));
+    IBaseFilter_Release(info.pFilter);
+
+    hr = IPin_QueryId(pin, &id);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    todo_wine
+    ok(!wcscmp(id, expect_id), "Got id %s\n", wine_dbgstr_w(id));
+    CoTaskMemFree(id);
+
+    hr = IPin_EnumMediaTypes(pin, &enum_mt);
+    todo_wine
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    if (hr != S_OK) goto skip_enum_mt;
+    hr = IEnumMediaTypes_Next(enum_mt, 1, &mt, NULL);
+    for (i = 0; hr == S_OK; hr = IEnumMediaTypes_Next(enum_mt, 1, &mt, NULL), i++)
+    {
+        if (i < expect_mt_count)
+        {
+            todo_wine
+            ok(compare_media_types(mt, expect_mt + i), "Media type %u didn't match.\n", i);
+        }
+        FreeMediaType(mt);
+        CoTaskMemFree(mt);
+    }
+    todo_wine
+    ok(i == expect_mt_count, "Got %u types\n", i);
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    IEnumMediaTypes_Release(enum_mt);
+
+skip_enum_mt:
+    check_interface(pin, &IID_IPin, TRUE);
+    check_interface(pin, &IID_IUnknown, TRUE);
+    todo_wine
+    check_interface(pin, &IID_IMediaSeeking, TRUE);
+    todo_wine
+    check_interface(pin, &IID_IQualityControl, TRUE);
+    check_interface(pin, &IID_IServiceProvider, FALSE);
+    check_interface(pin, &IID_IWMStreamConfig, FALSE);
+}
+
 static void test_filesourcefilter(void)
 {
+    static const MSAUDIO1WAVEFORMAT msaudio1_format =
+    {
+        .wfx.wFormatTag = WAVE_FORMAT_MSAUDIO1,
+        .wfx.nChannels = 1,
+        .wfx.nSamplesPerSec = 44100,
+        .wfx.nBlockAlign = 743,
+        .wfx.nAvgBytesPerSec = 16000,
+        .wfx.wBitsPerSample = 16,
+        .wfx.cbSize = sizeof(MSAUDIO1WAVEFORMAT) - sizeof(WAVEFORMATEX),
+        .wEncodeOptions = 1,
+    };
+    static const VIDEOINFOHEADER2 wmv1_info2 =
+    {
+        .rcSource = {0, 0, 64, 48},
+        .rcTarget = {0, 0, 64, 48},
+        .dwBitRate = 189464,
+        .dwPictAspectRatioX = 64,
+        .dwPictAspectRatioY = 48,
+        .bmiHeader =
+        {
+            .biSize = sizeof(BITMAPINFOHEADER),
+            .biWidth = 64,
+            .biHeight = 48,
+            .biPlanes = 1,
+            .biBitCount = 24,
+            .biCompression = MAKEFOURCC('W','M','V','1'),
+            .biSizeImage = 64 * 48 * 3,
+        },
+    };
+    static const VIDEOINFOHEADER wmv1_info =
+    {
+        .rcSource = {0, 0, 64, 48},
+        .rcTarget = {0, 0, 64, 48},
+        .dwBitRate = 189464,
+        .bmiHeader =
+        {
+            .biSize = sizeof(BITMAPINFOHEADER),
+            .biWidth = 64,
+            .biHeight = 48,
+            .biPlanes = 1,
+            .biBitCount = 24,
+            .biCompression = MAKEFOURCC('W','M','V','1'),
+            .biSizeImage = 64 * 48 * 3,
+        },
+    };
+    AM_MEDIA_TYPE audio_mt[] =
+    {
+        {
+            .majortype = MEDIATYPE_Audio,
+            .subtype = MEDIASUBTYPE_MSAUDIO1,
+            .bFixedSizeSamples = TRUE,
+            .lSampleSize = 743,
+            .formattype = FORMAT_WaveFormatEx,
+            .cbFormat = sizeof(MSAUDIO1WAVEFORMAT),
+            .pbFormat = (BYTE *)&msaudio1_format,
+        },
+    };
+    AM_MEDIA_TYPE video_mt[] =
+    {
+        {
+            .majortype = MEDIATYPE_Video,
+            .subtype = WMMEDIASUBTYPE_WMV1,
+            .formattype = FORMAT_VideoInfo2,
+            .bTemporalCompression = TRUE,
+            .cbFormat = sizeof(VIDEOINFOHEADER2),
+            .pbFormat = (BYTE *)&wmv1_info2,
+        },
+        {
+            .majortype = MEDIATYPE_Video,
+            .subtype = WMMEDIASUBTYPE_WMV1,
+            .formattype = FORMAT_VideoInfo,
+            .bTemporalCompression = TRUE,
+            .cbFormat = sizeof(VIDEOINFOHEADER),
+            .pbFormat = (BYTE *)&wmv1_info,
+        },
+    };
+
+    const WCHAR *filename = load_resource(L"test.wmv");
     IBaseFilter *filter = create_asf_reader();
     IFileSourceFilter *filesource;
     IFilterGraph2 *graph;
@@ -289,6 +455,66 @@ static void test_filesourcefilter(void)
     ok(type.pbFormat == ptr, "Got format block %p.\n", type.pbFormat);
     CoTaskMemFree(olepath);
 
+    hr = IFileSourceFilter_Load(filesource, filename, NULL);
+    ok(hr == E_FAIL, "Got hr %#lx.\n", hr);
+
+    ref = IFilterGraph2_Release(graph);
+    ok(!ref, "Got outstanding refcount %ld.\n", ref);
+    IBaseFilter_Release(filter);
+    ref = IFileSourceFilter_Release(filesource);
+    ok(!ref, "Got outstanding refcount %ld.\n", ref);
+
+
+    filter = create_asf_reader();
+    hr = IBaseFilter_QueryInterface(filter, &IID_IFileSourceFilter, (void **)&filesource);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    hr = IFileSourceFilter_Load(filesource, filename, NULL);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+
+    hr = CoCreateInstance(&CLSID_FilterGraph, NULL, CLSCTX_INPROC_SERVER,
+            &IID_IFilterGraph2, (void **)&graph);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    hr = IFilterGraph2_AddFilter(graph, filter, NULL);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+
+    olepath = (void *)0xdeadbeef;
+    memset(&type, 0x22, sizeof(type));
+    hr = IFileSourceFilter_GetCurFile(filesource, &olepath, &type);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    ok(!wcscmp(olepath, filename), "Got file %s.\n", wine_dbgstr_w(olepath));
+    ok(IsEqualGUID(&type.majortype, &MEDIATYPE_NULL), "Got majortype %s.\n",
+            wine_dbgstr_guid(&type.majortype));
+    ok(IsEqualGUID(&type.subtype, &MEDIASUBTYPE_NULL), "Got subtype %s.\n",
+            wine_dbgstr_guid(&type.subtype));
+    ok(type.bFixedSizeSamples == 0x22222222, "Got fixed size %d.\n", type.bFixedSizeSamples);
+    ok(type.bTemporalCompression == 0x22222222, "Got temporal compression %d.\n", type.bTemporalCompression);
+    ok(!type.lSampleSize, "Got sample size %lu.\n", type.lSampleSize);
+    ok(IsEqualGUID(&type.formattype, &testguid), "Got format type %s.\n", wine_dbgstr_guid(&type.formattype));
+    ok(!type.pUnk, "Got pUnk %p.\n", type.pUnk);
+    ok(!type.cbFormat, "Got format size %lu.\n", type.cbFormat);
+    ok(type.pbFormat == ptr, "Got format block %p.\n", type.pbFormat);
+    CoTaskMemFree(olepath);
+
+    hr = IBaseFilter_EnumPins(filter, &enumpins);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+
+    hr = IEnumPins_Next(enumpins, 1, pins, NULL);
+    todo_wine
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    if (hr != S_OK) goto skip_pins;
+    check_pin(pins[0], filter, PINDIR_OUTPUT, L"Raw Video 0", L"Raw Video 0", video_mt, ARRAY_SIZE(video_mt));
+    IPin_Release(pins[0]);
+
+    hr = IEnumPins_Next(enumpins, 1, pins, NULL);
+    ok(hr == S_OK, "Got hr %#lx.\n", hr);
+    check_pin(pins[0], filter, PINDIR_OUTPUT, L"Raw Audio 1", L"Raw Audio 1", audio_mt, ARRAY_SIZE(audio_mt));
+    IPin_Release(pins[0]);
+
+    hr = IEnumPins_Next(enumpins, 1, pins, NULL);
+skip_pins:
+    ok(hr == S_FALSE, "Got hr %#lx.\n", hr);
+    IEnumPins_Release(enumpins);
+
     ref = IFilterGraph2_Release(graph);
     ok(!ref, "Got outstanding refcount %ld.\n", ref);
     IBaseFilter_Release(filter);
diff --git a/dlls/qasf/tests/resource.rc b/dlls/qasf/tests/resource.rc
new file mode 100644
index 00000000000..2d2e480312b
--- /dev/null
+++ b/dlls/qasf/tests/resource.rc
@@ -0,0 +1,24 @@
+/*
+ * Resource file for qasf tests.
+ *
+ * Copyright 2022 Rémi Bernon for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "windef.h"
+
+/* @makedep: test.wmv */
+test.wmv RCDATA test.wmv
diff --git a/dlls/qasf/tests/test.wmv b/dlls/qasf/tests/test.wmv
new file mode 100644
index 0000000000000000000000000000000000000000..fa953771cd31213ec24bef9000127125047e0623
GIT binary patch
literal 45663
zcmeI5dsq|47Qkn+KuCBb#DJ(M0TB=sL9IrL5KuHwMMUwzqsF&b at C7O=)lEPJA4pY1
zxr$LiQBlzg1<`8a3yZfx at lm9xDHgHTT55fu7P&LKB<Ab=`dz)f{iDeauq0<EyL(Q~
zFEeN6WY*jD#Ny0Z)i(QYfkR;0)%YtcKov8zg{(adhc}EoSZ$N}Jy2PS#?72V at BEML
zloK5y(*MSt<GY}B$5Z8C8v;Mn_=q9??_i0y0N|65=rR72KvPgkoSou@&vTDH&rYfq
z05-MP4p(6LeOhh?=Ak_gue4q~7QIxOHv7<q;jczjVHqy?s1S4o1TaC50zo2J0A_;e
zAPGc(sc0Jq=7UL89kltcH79q}l;qdcvhUT}<g at _gmme2~&%iH61p;?45sU`?Krp(h
z>FC%q&>7}|*<c(xYZ7%n{49~G?EprhYghtife(Nfc!9xS5Zd|xZ}bDeXY7WuGCe)z
z)N24x{oLjB=;&&j!Ztuoi5cz*CcYL$>Ob$OH=yG`Wn>^h&+t)M?&uPcfjgc;U=Jpa
zp5Oyqkl=Ua_ZJY~v0suG*Q$R3;a{CUyJ>2*&H59_T}m27+QZnP2j=JxzXbruAOypU
z(A(<|Kr at R^y&Vw1W>zx`U7;l6>owhdYHar9BZCss=lCtbCGdB0`t39YOF;rMoDWsU
zgwlWo%qS@~C at p89a}N5QEB8M}z2rYOTIYmNfjlhsHD$C3APrv|(xMri7yD^5YezT$
z#DS_Go+Z8V{j|IP(cKfr>`Sj}98|vXXwTVCJYU*13S)v&)2}xQ7sS4>IXrZ3byQ32
z?x8b_Z^VCab7#Bwe8zn1UZ=~qeIvLP6Fkvo<?{BtFEpY|(1T^JAvB_Gz at Nn-p+>Y9
zNw^{;If^6}07*_Gi6uai8YHojA;|+I;h{QCW=LYAgc_&*NMeg63y`EMmeeANi;~bd
zry+?SI*yAgk`&7b&Ct2PpSYtTG<}3<mzac_o=?#(ClXbjfFzyq%l9LR0H6a7M-ppP
z2b~LDh6r6oJ(6%`9T&zybwv5V-)fvHPz3z$eQ at Dpi!WkE`hJ at 7th{IS_Y>2OTx+UU
zRLf=mXm at +#Rjo+cs2;5LX+8DwmFmTqThRlWjtoeh{p-!jid743E(}gfY*M>gW#)W7
zwDzj=?6YZ~q?%-(S43S(DxKbZHn)2I;21Ht+`IeqH<24(zC3&7tC{}u-Bpvrh&EZj
zyUnkDJG*MvsV8MkgC6a at yY<@>nE`h@|G4SJ#aH**eu>`p(~lFHPA$K2a^9WN3uTu|
zFSKub(do_LhB2*o`vyd(l(Z#0x%RBW?qKwux!LI7s$mbO)V#`h>R-^tqn_+}GKKn$
z3+5CEUAKnkjt%;QhvvQC^T&lH`GenS|F<$#6ZURJPWyeV2>_wU?_*6&Q#Sa1e`#5z
zC at x&QP_r<x(8_~t?Pu+^Wa)=eOTqZg&$If3a&GS67d@#z{MjeN*18H^Q^D#q<voo$
ze3*0ig4gi;E_P>MGibpHtW+zMYh)dw4;{UNqa?x~rFL$nZTYrc#>Tm-k3Y(Jo at KuL
z+R2DoQ>(xkB?|fBMRoh!z0G6ALq3Ol>crA)c4K&=<hwkR;<v&OqA=8Yj>7;|j^hzg
zmm~Qwv_u}bE<vPxc3{Msp<60yVQIaj(+a7b)7(Y1Tu%LBj$D+!)4{yIrO>2RI!hHN
z7V~G=yK`DLSFV?uT at Fjg=XO8oDfO@~st-{{)I!gO?0k!^Yoev at orjmaoVQrgVTv>C
zm8Pq<uAcH`wq2`jp7k%%`c6a~5Gc<|>Lp{{-DK|jX3pMr at p9>&^IN!bGU#0R!WLPf
z({=}c)q>{0i&vFq)~C2<GLtNJv^dR{c`kN%aO?8CUimN#zg*m}r9{5ZqpwSy_lmHL
zxQ2t@{Uj1yw;SG?WO`uHmFc0~YzeUXTIxS!UAw2IW%;Hl at 5|5oabz-nMRIx5>Kv9k
zyinIYFnNe_K{X4hkc%vRSSqyNU(4l1CC%|JA^T3qGHDnNLcS^$%lWXI)ZA^Mw{Vn#
z2vMt2MQX{Iw5?`aQsriW3NlwPf9(|0C57DE`NVX$fuSYjurim)6S7=<CYNlH976Vq
z*)}N4a&8x7 at mRsNrgG3DZgyJw)UOwKu9I&jWrqn68%XwEtx=gABhn>J<lgSEMP^?~
zzFMOeeldALinW+8AG40Qe<mvWhV7UkSIcYsZV{ka9%RYw2UM~`<u=P)^U4zwI_-%2
zHpk8Msc@{NBA{?z>#BwqzVepJ)v<|NXVxrQx9P)#%YDlD-+a_1ac5;;Xa3r*DH4~l
zc?-PF9ATxh(Sc2n`-yX6v($7x|D{rMh{*UzRnyHJK4)uwn_5cbZA&iOHSS+M*|{+{
zSX)$kN!b^rvIE;IcF*2wP2AWT`D!?CkenPL)AX?9_F?x(HD!|z`p<Dc6jxzeYPY?9
zzs0?nb!(#c#eRD>EutVa*Zt_p?}8I|xb>HW%PfC+l$&;cY{IyOqP<n>A$t<a5AohK
zM=XB)(*eHiRS%B0lq<C7PY!f0_mw0mlO6c#i2 at hFM{+gaDyU{~WKd0Tyj768@>cMj
zJ1yxFdyr at CZ))#n1~;ZEijugp$ka?&C9kUOA0>9oTxmUM{zLJ;f)ra;AQ^Q2UVQ4X
zI%|O&-+zwlf%aj&1l%Iwq?zTrH_bb`^`Pzb<V9H^@>2YY*P|z&^c<HH(;As=azEPZ
zv9r6P$UVaGaRl48-C=w~#mMWu#W8ctL~Lho_j6$L5Vomzpdif$6gw0-NCdUK^GzR&
zOydvycILYAg%|xE<^_2#D=4;y&fQZLX||fQ{4O5u%E$*ELB-1oEW*YJT9xrXczdoP
zS-4rJTUq>R)6Cj~T3Pna%be(=Ja`YaF+(ST0k`8!$d-5e^kQl;7Wg|@0MdSsJIRZX
z-<yNrPb)Vp at o6V94ooph3n&2K#14x=y61v)78NN|;Yae at 55`});iWPDM1zX0T3QS$
zCeO>_B>x at Uow-KF0`F!4Nc%nB<|4l*KyW}i3&kQGorD8=ECdP4Cfy-^Q4y-7EZ`ga
zjOir2n~9lPe-jHp+V3$7=X5NX>R7lzu~3MIrShFDRuWf99$6<MUWLGSjrIQ~c3>`(
zu>hJDz-<6#;h~NNJS{;7k0w?)c%)e{%RUBwmJq5q0NRuSCU9h&$G|KAX}`xT2$0`X
zeI!i6pDa}T(a#Qz{}zG_78 at Upia+}6vE{t_EPMgjs+k(t=5k(TV1{MXF?tI?+V3%2
zzFM|ec$kJ}VX7VrW;u6=-vFDuD1on89~-^p7y}rZ1t9JBn1yLt79fXW0n65DWh`2T
zr^+``d>o`>5 at 9P(f~Jb^lDr4onPDnJ^A1KI$knlMLdOCv!z`T9W5F!fk6j9QaJq_k
zZgQG29b*9lvjDWvu~4sN0ZZPap!mZk7O-ki0OF7Gujm6}kRIuQ<jGB8R{}>kQNn&Y
z%Fn=z$f(0u0HV>Yj)5)~%1xvvKxi3ep(~O#v*-?%g)o^{gp%^IN%kXV9*}VzgR_7f
zeefd|a4w<;@_Qy1k;z45auJza#J?yP5r5V&#ds}%;tx)&M_<&*I*8^!=%xpExkB{1
zT%IPayvt}zD+MrPS_aqMU=#`qqra?Yjz at kYkl(*eOvS-S$0W#7Js at xl(tu)+X-o{l
zxQ`)P0P-lm#}gjQk>6ACIOOYOd$lqaT at N=H`}O$nBs2l#pq1kc0uHVv4bec1PDX73
zXrp7HO2-1t2WH{A9t##Wng9(*HZKQ`<v9!sM(s8RsXP?uSa_mk0ZZPkC~*AI4?|Oi
z;tv`t{ER>?OEaq&&8eGl?hs#s0P`~pJqGDNj8b8+6NZJ#^X-cKo}T`ovBE6)=&|qy
zvEVhhg-P&b+{Q310EIdhf^;m<d|(!)=&^v?g~8IwS_THgbOoc=3fk&en5$!f<^!{k
zNwLr|E#65JP=msZM<9R+GmPGG4A1}&udhY-kv3~tfSq-+3at!F-lHh!{3|6I>Iy^o
zS2S=KuG4yOc|uLVb~K(f9yl`NSqA7^Mz0dI$H-6tNTU`c77ZL`;YU3dEKq_wUS(}Q
z;62J<65Ng6bqvk`@-7q$IRA=^hIE<yD<=Pn$-iRqubBL+_vlqKRo~SDDE>hCS8XW#
zIEm&z=y(Qqxw at dHN1O8QX_CyVK>1f0fc?Op>2eudkHhE{f?cUD7tX)xkNjRQ|B8-F
zFc4BbAaD$lhhmVuOblZ5zGILEfZZq{aQ;;k at _Twhkd8|*3rqA^@Z|cj&!F!H#*)NS
zOXj<Q2I&q)trT?7v7pegKsOkeg#tYm;J{Yi1k^5EBbl)&qxKm?RUUTNv2aMs0_>ra
z)oNu}@@_>zt-o7_2D^5n^>^uJ2V-?j5363h)9h^2#4JWlj0Lm&m7zM9@#+N~F)Y;d
z$15#DEV|jjEZ}Tk?K+FBoHxWXz$Pz~#A_*&k!ZX=W2l-#k&Xpt<o9&wK{q>?1#dkT
zTvs21ze?Du*$Y6Mh*=lWP(8wU^@2`17D9C_(A_P}!pC|nK+l!LO_ELC0H|Fs)flhM
z7|jjS0?=8<!XhmTSn?-}0_R^nf(y|~*RfzVi|&YFxHeL7QFliAl@(EX|1|prTI#(?
z1JpeqGJqMTj~T62uqVcd3P5tTaIr*`46|@bkA+Zv*`zl_GfAkHh(JZ`JW|Tc2pX;5
z7^33PMaRN9EerBqlnm!&Jw!4lCyU9+Vsf&WoGd0M3x6y!<xf}u#UGql|EnncP@?${
zI^M@!F5Jv$Z_KLd9ffYp`UAS>x8HU!;MUyDkm+(6V$Z{9b%L&#AZq<90s7jxUjCIc
zwF3iTk9KH*$S{wtUIlL}p~jyN5^pD%yD*6-M(aF=s5o?^{2u3D`69okCqd{K9kVb}
zj|J7hGu89q*DAE+RTA)&$Mt4zL}-W}VZ1s)cO47UbS%&@I%Z)p#R7d3LO7@$7NeUG
zF3*DZq&#4}He)n5Obfu?Iu_PxS-_J2y(p;luhycQ8y-X7|DcDtFjo8CVwI7$_qJvr
z`u;g at JFpnf+}qPIUCWrYf*u$kYWm}Z7AqDVlVBEV^;jt0eV6<fiPmF~fg`m9lZ<H0
zZex(TLr)zG^*R>la0Ige&{A0R_X16iPrI$@SBRR0fq<9w5rcw3x`R<G1^eh&U?IP!
z!f at DEC-czCSagVj`RJ#|$B4TcF9}HI%>w<HroyNl$v~BdUOE;cv at BrBdlUsqZ;uT`
z_kT_RYglx2gE5NLVMJtX?t6#z72uICMKGATji-USk}<0V`(a?H at MF0aBNiQ!U=}v$
zu~58fC94#$$=6C^v^TTvs4;tuVd at UObu8@Fu|S6;n1u>G7B&Zb%-V(8g*FuoW=5q9
z(;bXjE4dHF0?s<DLViDvFiqLu`~9V5m7=(C at j}hQ#6l|%wzZ$N*OH|lN-YKBJ3r6r
z6Uw={gJ1Nd{_tm?3|s3ebWH`T)0Fo#>hNLC;R{~F^Sjucea)Z+C$LhjP_B`6h(2`m
z3XYNpf0Wv}nYQKIb{QMzsy_ZG=XsX-@@pp}YE7*IXOt-9hZoiDbN4on6%Y9w?x_<?
zv)PT|iIVT~Op4zMLx{pq>p2bsR5^}EL|u;L!_X3W;JO5n^4WnAYld#AsD-8Vl1?k6
zc208_)p9xYi#c*p`c4P){+2?MR_QENoLJ1CVeigq*<86^YIZp+A)nj*q^H!wzNkJ#
z$z&ZeS%?4UtV0xk*u;)7KZ+s{caSRg8HeWFse9jI;<#{6Lir)yo92kckAFJAx4r7Y
z at s@Ih_Wa3#&gH(6BxSM#Up-OaBKSzI=352T42}${368f4QdiyzzH_G~U1AUNto=>x
z{mkITR7Ft|R~DI?39IB)wf&>Sj+ra12hD#d-dB)f%L*ie&fkkq9ad*8aO3;WaXrvJ
zte1dWB%Cy}eD|h#N4Fldy`H=%3q)RuU-5eM<ddG`a$;H|vrX<tdp&k`R}{HNI6jVG
z+qOH5Z>ac-k`h_;SO{)}A5e|3G8}z6Ro!~&yGmVJTj%O{ll`V;lsLW7i?jQi#->B6
z-vs4r)IRrHMqlOpv*5(%O$ln(6hTU_Wj|*xoaE5x=<&~aZ-OTh2fq2m(chwa(hn)m
zs()>nJ3tfGt4tLn1?_Ih=Cc70@<_AB=xQ=u0$OZb(b5{-RBTnqcJQs$N+KMfnO;6<
zweUmrdH|?#egINTqDbq=>8j!0Kz2*xGzTQ!Jl%PP`j9N=s%h1#&n8FPO>5usN$R=C
z5s_C4+VhgyVunPIjhgQM`Ow;D8{-pSPrum`LKgQ}aVF`6=h_!9mlaf0`hT*%ch!Vq
z8`b<L>zDS3*s#a3wDj<zRkIpi&d*%Gbaib>>6mUxr-U|(ksFST4Xul^NUC}1IqzKW
z0^Y7I!JL(j+=z8nu4%5H1zp%<mQ99^MgKX{y$6H1b4~J{4@!C;9G at n<Zt7$!HT?iO
z*~&UaNKI5O9CB0$OV&vsadnY<b23DuLNc&q+Ne>S3?J{h?VSYErXKIJJ$}@nUR$g(
zCJ6IRF)4w6O<w`_ry60rHrNy7_iuC4u$U=~1sDr37GNyESb(trV}bX#K$bZeaJ;G7
nCgUkkeo2H}nf3>VAh&I&_CT~nvC1D7oHC43x~Q!s+CuPe!fZnO

literal 0
HcmV?d00001

-- 
GitLab


https://gitlab.winehq.org/wine/wine/-/merge_requests/116



More information about the wine-devel mailing list