Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
December 2019
- 73 participants
- 1394 messages
Re: [PATCH 1/5] wined3d: Introduce wined3d_device_apply_stateblock().
by Matteo Bruni
On Sat, Dec 7, 2019 at 5:11 PM Zebediah Figura <z.figura12(a)gmail.com> wrote:
>
> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> ---
> dlls/wined3d/device.c | 93 +++++++++++++++++++++++++++++++++++++++
> dlls/wined3d/wined3d.spec | 1 +
> include/wine/wined3d.h | 1 +
> 3 files changed, 95 insertions(+)
>
> diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
> index 0ae841d4e35..50029dfbec2 100644
> --- a/dlls/wined3d/device.c
> +++ b/dlls/wined3d/device.c
> @@ -3829,6 +3829,99 @@ struct wined3d_texture * CDECL wined3d_device_get_texture(const struct wined3d_d
> return device->state.textures[stage];
> }
>
> +void CDECL wined3d_device_apply_stateblock(struct wined3d_device *device,
> + struct wined3d_stateblock *stateblock)
> +{
> + const struct wined3d_d3d_info *d3d_info = &stateblock->device->adapter->d3d_info;
> + const struct wined3d_stateblock_state *state = &stateblock->stateblock_state;
> + unsigned int i, j;
> +
> + TRACE("device %p, stateblock %p.\n", device, stateblock);
> +
> + wined3d_stateblock_init_contained_states(stateblock);
> +
> + wined3d_device_set_vertex_shader(device, state->vs);
> + wined3d_device_set_pixel_shader(device, state->ps);
Can we make use of the stateblock flags to only update the changed
states instead of all of them?
> + for (i = 0; i < d3d_info->limits.vs_uniform_count; ++i)
> + wined3d_device_set_vs_consts_f(device, i, 1, &state->vs_consts_f[i]);
Either only update the changed constants or set all of them in one go, IMO.
Somewhat related, I have a few patches optimizing / improving our
handling of those flags but I don't expect them to be ready before
code freeze (and I don't want to conflict with your patches,
especially now).
Dec. 10, 2019
[PATCH] winecfg: Avoid an unneeded strlen() call.
by Francois Gouget
Note that szLinkTarget is an array field and thus cannot be NULL.
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
programs/winecfg/theme.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/programs/winecfg/theme.c b/programs/winecfg/theme.c
index 66d23448f6f..dffe1861e82 100644
--- a/programs/winecfg/theme.c
+++ b/programs/winecfg/theme.c
@@ -842,7 +842,7 @@ static void on_shell_folder_selection_changed(HWND hDlg, LPNMLISTVIEW lpnm) {
if (lpnm->uNewState & LVIS_SELECTED) {
psfiSelected = (struct ShellFolderInfo *)lpnm->lParam;
EnableWindow(GetDlgItem(hDlg, IDC_LINK_SFPATH), 1);
- if (strlen(psfiSelected->szLinkTarget)) {
+ if (*psfiSelected->szLinkTarget) {
WCHAR *link;
CheckDlgButton(hDlg, IDC_LINK_SFPATH, BST_CHECKED);
EnableWindow(GetDlgItem(hDlg, IDC_EDIT_SFPATH), 1);
--
2.20.1
Dec. 10, 2019
Re: [PATCH v2 3/6] d3d9: Use wined3d_stateblock_get_state() in d3d9_device_GetRenderState().
by Matteo Bruni
On Tue, Dec 10, 2019 at 9:34 AM Matteo Bruni <matteo.mystral(a)gmail.com> wrote:
>
> On Thu, Nov 28, 2019 at 6:54 AM Zebediah Figura <z.figura12(a)gmail.com> wrote:
> >
> > Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> > ---
> > dlls/d3d9/device.c | 4 +++-
> > 1 file changed, 3 insertions(+), 1 deletion(-)
> >
> > diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
> > index 2d66c569938..51b7f4d6f59 100644
> > --- a/dlls/d3d9/device.c
> > +++ b/dlls/d3d9/device.c
> > @@ -2329,6 +2329,7 @@ static HRESULT WINAPI d3d9_device_GetRenderState(IDirect3DDevice9Ex *iface,
> > D3DRENDERSTATETYPE state, DWORD *value)
> > {
> > struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
> > + const struct wined3d_stateblock_state *device_state;
> > struct wined3d_color factor;
> >
> > TRACE("iface %p, state %#x, value %p.\n", iface, state, value);
> > @@ -2344,7 +2345,8 @@ static HRESULT WINAPI d3d9_device_GetRenderState(IDirect3DDevice9Ex *iface,
> > }
> >
> > wined3d_mutex_lock();
> > - *value = wined3d_device_get_render_state(device->wined3d_device, state);
> > + device_state = wined3d_stateblock_get_state(device->state);
> > + *value = device_state->rs[state];
> > wined3d_mutex_unlock();
> >
> > return D3D_OK;
>
> Just a couple of comments WRT potential future improvements. Obviously
> they apply to the other d3d* versions too.
>
> The state for the stateblock isn't going to change from underneath so
> it could be stored in the d3d9 device once and for all instead of
> getting it from wined3d every time it's needed. It doesn't matter a
> lot I guess (and it's certainly not urgent anyway), especially for
> those Get*() methods, but it would be one less inter-module function
> call per API call.
I guess it was just one comment, after all...
Dec. 10, 2019
Re: [PATCH v2 3/6] d3d9: Use wined3d_stateblock_get_state() in d3d9_device_GetRenderState().
by Matteo Bruni
On Thu, Nov 28, 2019 at 6:54 AM Zebediah Figura <z.figura12(a)gmail.com> wrote:
>
> Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
> ---
> dlls/d3d9/device.c | 4 +++-
> 1 file changed, 3 insertions(+), 1 deletion(-)
>
> diff --git a/dlls/d3d9/device.c b/dlls/d3d9/device.c
> index 2d66c569938..51b7f4d6f59 100644
> --- a/dlls/d3d9/device.c
> +++ b/dlls/d3d9/device.c
> @@ -2329,6 +2329,7 @@ static HRESULT WINAPI d3d9_device_GetRenderState(IDirect3DDevice9Ex *iface,
> D3DRENDERSTATETYPE state, DWORD *value)
> {
> struct d3d9_device *device = impl_from_IDirect3DDevice9Ex(iface);
> + const struct wined3d_stateblock_state *device_state;
> struct wined3d_color factor;
>
> TRACE("iface %p, state %#x, value %p.\n", iface, state, value);
> @@ -2344,7 +2345,8 @@ static HRESULT WINAPI d3d9_device_GetRenderState(IDirect3DDevice9Ex *iface,
> }
>
> wined3d_mutex_lock();
> - *value = wined3d_device_get_render_state(device->wined3d_device, state);
> + device_state = wined3d_stateblock_get_state(device->state);
> + *value = device_state->rs[state];
> wined3d_mutex_unlock();
>
> return D3D_OK;
Just a couple of comments WRT potential future improvements. Obviously
they apply to the other d3d* versions too.
The state for the stateblock isn't going to change from underneath so
it could be stored in the d3d9 device once and for all instead of
getting it from wined3d every time it's needed. It doesn't matter a
lot I guess (and it's certainly not urgent anyway), especially for
those Get*() methods, but it would be one less inter-module function
call per API call.
Dec. 10, 2019
[PATCH] ws2_32/tests: Fix the spelling of a couple of ok() messages.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/ws2_32/tests/sock.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index e4b57cfddae..cd97aae4bb8 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -6611,7 +6611,7 @@ static void test_WSASendMsg(void)
ok(!ret, "WSASendMsg should have worked\n");
ok(GetLastError() == 0 || broken(GetLastError() == 0xdeadbeef) /* Win <= 2008 */,
"Expected 0, got %d\n", GetLastError());
- ok(bytesSent == iovec[0].len, "incorret bytes sent, expected %d, sent %d\n",
+ ok(bytesSent == iovec[0].len, "incorrect bytes sent, expected %d, sent %d\n",
iovec[0].len, bytesSent);
/* receive data */
@@ -6639,7 +6639,7 @@ static void test_WSASendMsg(void)
SetLastError(0xdeadbeef);
ret = pWSASendMsg(sock, &msg, 0, &bytesSent, NULL, NULL);
ok(!ret, "WSASendMsg should have worked\n");
- ok(bytesSent == iovec[0].len + iovec[1].len, "incorret bytes sent, expected %d, sent %d\n",
+ ok(bytesSent == iovec[0].len + iovec[1].len, "incorrect bytes sent, expected %d, sent %d\n",
iovec[0].len + iovec[1].len, bytesSent);
ok(GetLastError() == 0 || broken(GetLastError() == 0xdeadbeef) /* Win <= 2008 */,
"Expected 0, got %d\n", GetLastError());
--
2.20.1
Dec. 10, 2019
[PATCH] winedbg: Fix the spelling of various messages and the README.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
programs/winedbg/README | 2 +-
programs/winedbg/gdbproxy.c | 4 ++--
programs/winedbg/types.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/programs/winedbg/README b/programs/winedbg/README
index e824a1c88ce..66b3953bd22 100644
--- a/programs/winedbg/README
+++ b/programs/winedbg/README
@@ -1,4 +1,4 @@
- This is the core of the Wine debugger. The reverse assember
+ This is the core of the Wine debugger. The reverse assembler
was stolen from Mach more or less intact. It turns out that there are
two variables that are set differently if you are reverse assembling
16 bit code, and on the whole it seems to work.
diff --git a/programs/winedbg/gdbproxy.c b/programs/winedbg/gdbproxy.c
index 85ebc882a62..052e73b2ad6 100644
--- a/programs/winedbg/gdbproxy.c
+++ b/programs/winedbg/gdbproxy.c
@@ -569,7 +569,7 @@ static void wait_for_debuggee(struct gdb_context* gdbctx)
{
if (check_for_interrupt(gdbctx)) {
if (!DebugBreakProcess(gdbctx->process->handle)) {
- ERR("Failed to break into debugee\n");
+ ERR("Failed to break into debuggee\n");
break;
}
WaitForDebugEvent(&de, INFINITE);
@@ -624,7 +624,7 @@ static void get_process_info(struct gdb_context* gdbctx, char* buffer, size_t le
case ABOVE_NORMAL_PRIORITY_CLASS: strcat(buffer, ", above normal priority"); break;
#endif
#ifdef BELOW_NORMAL_PRIORITY_CLASS
- case BELOW_NORMAL_PRIORITY_CLASS: strcat(buffer, ", below normal priotity"); break;
+ case BELOW_NORMAL_PRIORITY_CLASS: strcat(buffer, ", below normal priority"); break;
#endif
case HIGH_PRIORITY_CLASS: strcat(buffer, ", high priority"); break;
case IDLE_PRIORITY_CLASS: strcat(buffer, ", idle priority"); break;
diff --git a/programs/winedbg/types.c b/programs/winedbg/types.c
index 696a9fd48a5..019554ad1be 100644
--- a/programs/winedbg/types.c
+++ b/programs/winedbg/types.c
@@ -168,7 +168,7 @@ BOOL types_store_value(struct dbg_lvalue* lvalue_to, const struct dbg_lvalue* lv
if (!types_get_info(&lvalue_to->type, TI_GET_LENGTH, &size)) return FALSE;
if (sizeof(val) < size)
{
- dbg_printf("Unsufficient size\n");
+ dbg_printf("Insufficient size\n");
return FALSE;
}
/* FIXME: should support floats as well */
--
2.20.1
Dec. 10, 2019
[PATCH] qcap/tests: Avoid an unneeded lstrlenW() call.
by Francois Gouget
Note that achName is an array field and thus cannot be NULL.
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/qcap/tests/smartteefilter.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/qcap/tests/smartteefilter.c b/dlls/qcap/tests/smartteefilter.c
index 4eac344d537..014c6ee2d13 100644
--- a/dlls/qcap/tests/smartteefilter.c
+++ b/dlls/qcap/tests/smartteefilter.c
@@ -2078,7 +2078,7 @@ static void test_smart_tee_filter(void)
if (FAILED(hr))
goto end;
- ok(lstrlenW(filterInfo.achName) == 0,
+ ok(!*filterInfo.achName,
"filter's name is meant to be empty but it's %s\n", wine_dbgstr_w(filterInfo.achName));
hr = IBaseFilter_EnumPins(smartTeeFilter, &enumPins);
--
2.20.1
Dec. 10, 2019
[PATCH] msvcrt/tests: Avoid an unneeded strlen() call.
by Francois Gouget
Note that buf is an array and thus cannot be NULL.
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
I used the buf[0] == 0 form to match the buf[0] == 'X' test a few lines
up. I'm fine with replacing it with a !*buf too.
dlls/msvcrt/tests/misc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/msvcrt/tests/misc.c b/dlls/msvcrt/tests/misc.c
index c59464f82d6..7e2a7e40690 100644
--- a/dlls/msvcrt/tests/misc.c
+++ b/dlls/msvcrt/tests/misc.c
@@ -211,7 +211,7 @@ static void test_strerror_s(void)
memset(buf, 'X', sizeof(buf));
ret = pstrerror_s(buf, 1, 0);
ok(ret == 0, "Expected strerror_s to return 0, got %d\n", ret);
- ok(strlen(buf) == 0, "Expected output buffer to be null terminated\n");
+ ok(buf[0] == 0, "Expected output buffer to be null terminated\n");
memset(buf, 'X', sizeof(buf));
ret = pstrerror_s(buf, 2, 0);
--
2.20.1
Dec. 10, 2019
[PATCH] riched32/tests: Avoid an unneeded strlen() call.
by Francois Gouget
Note that buffer is an array and thus cannot be NULL.
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/riched32/tests/editor.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/riched32/tests/editor.c b/dlls/riched32/tests/editor.c
index 0d55b7cd6ed..950c175bbbe 100644
--- a/dlls/riched32/tests/editor.c
+++ b/dlls/riched32/tests/editor.c
@@ -293,7 +293,7 @@ static void test_EM_STREAMIN(void)
result = SendMessageA(hwndRichEdit, WM_GETTEXT, 1024, (LPARAM)buffer);
ok (result == 0,
"EM_STREAMIN: Test 3 returned %ld, expected 0\n", result);
- ok (strlen(buffer) == 0,
+ ok (!*buffer,
"EM_STREAMIN: Test 3 set wrong text: Result: %s\n",buffer);
ok(es.dwError == -16, "EM_STREAMIN: Test 0 set error %d, expected %d\n", es.dwError, -16);
--
2.20.1
Dec. 10, 2019
[PATCH] msado15: Fix the name of the GetString() delimiter parameters.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/msado15/recordset.c | 6 +++---
include/msado15_backcompat.idl | 4 ++--
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/msado15/recordset.c b/dlls/msado15/recordset.c
index 52282c7e827..84adec406f4 100644
--- a/dlls/msado15/recordset.c
+++ b/dlls/msado15/recordset.c
@@ -526,11 +526,11 @@ static HRESULT WINAPI recordset_get_StayInSync( _Recordset *iface, VARIANT_BOOL
}
static HRESULT WINAPI recordset_GetString( _Recordset *iface, StringFormatEnum string_format, LONG num_rows,
- BSTR column_delimeter, BSTR row_delimeter, BSTR null_expr,
+ BSTR column_delimiter, BSTR row_delimiter, BSTR null_expr,
BSTR *ret_string )
{
- FIXME( "%p, %u, %d, %s, %s, %s, %p\n", iface, string_format, num_rows, debugstr_w(column_delimeter),
- debugstr_w(row_delimeter), debugstr_w(null_expr), ret_string );
+ FIXME( "%p, %u, %d, %s, %s, %s, %p\n", iface, string_format, num_rows, debugstr_w(column_delimiter),
+ debugstr_w(row_delimiter), debugstr_w(null_expr), ret_string );
return E_NOTIMPL;
}
diff --git a/include/msado15_backcompat.idl b/include/msado15_backcompat.idl
index a1d5e28038b..e4a847ab859 100644
--- a/include/msado15_backcompat.idl
+++ b/include/msado15_backcompat.idl
@@ -1068,8 +1068,8 @@ interface Recordset20 : Recordset15
HRESULT GetString(
[in, defaultvalue(adClipString)] StringFormatEnum string_format,
[in, defaultvalue(-1)] LONG num_rows,
- [in, optional] BSTR column_delimeter,
- [in, optional] BSTR row_delimeter,
+ [in, optional] BSTR column_delimiter,
+ [in, optional] BSTR row_delimiter,
[in, optional] BSTR null_expr,
[out, retval] BSTR *ret_string);
--
2.20.1
Dec. 10, 2019
[PATCH] jscript: Fix the spelling of a couple of comments.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/jscript/jsutils.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/jsutils.c b/dlls/jscript/jsutils.c
index a36c9c1e5b9..af465300e72 100644
--- a/dlls/jscript/jsutils.c
+++ b/dlls/jscript/jsutils.c
@@ -672,13 +672,13 @@ static INT32 double_to_int32(double number)
* after rounding; if the exponent is > 83 then no bits of precision can be
* left in the low 32-bit range of the result (IEEE-754 doubles have 52 bits
* of fractional precision).
- * Note this case handles 0, -0, and all infinte, NaN, & denormal value. */
+ * Note this case handles 0, -0, and all infinite, NaN & denormal values. */
if(exp < 0 || exp > 83)
return 0;
/* Select the appropriate 32-bits from the floating point mantissa. If the
* exponent is 52 then the bits we need to select are already aligned to the
- * lowest bits of the 64-bit integer representation of tghe number, no need
+ * lowest bits of the 64-bit integer representation of the number, no need
* to shift. If the exponent is greater than 52 we need to shift the value
* left by (exp - 52), if the value is less than 52 we need to shift right
* accordingly. */
--
2.20.1
Dec. 10, 2019
[PATCH] msxml3/tests: Avoid an unneeded lstrlenW() call.
by Francois Gouget
This being a test we have to assume IXMLElement_get_text() could return
a NULL string.
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/msxml3/tests/xmldoc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/msxml3/tests/xmldoc.c b/dlls/msxml3/tests/xmldoc.c
index 359297f592f..693af195717 100644
--- a/dlls/msxml3/tests/xmldoc.c
+++ b/dlls/msxml3/tests/xmldoc.c
@@ -972,7 +972,7 @@ static void test_xmlelem(void)
hr = IXMLElement_get_text(element, &str);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
- ok(lstrlenW(str) == 0, "Expected empty text\n");
+ ok(str && !*str, "Expected empty text\n");
SysFreeString(str);
/* put_text with an ELEMENT */
--
2.20.1
Dec. 10, 2019
[PATCH] kernelbase/tests: Avoid an uneeded lstrlenW() call.
by Francois Gouget
Note that path_outW is an array and thus cannot be NULL.
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/kernelbase/tests/path.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/kernelbase/tests/path.c b/dlls/kernelbase/tests/path.c
index 93303bafc34..d77eaebd913 100644
--- a/dlls/kernelbase/tests/path.c
+++ b/dlls/kernelbase/tests/path.c
@@ -1110,7 +1110,7 @@ static void test_PathCchCanonicalize(void)
hr = pPathCchCanonicalize(path_outW, ARRAY_SIZE(path_outW), path_inW);
ok(hr == HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE), "expect hr %#x, got %#x %s\n",
HRESULT_FROM_WIN32(ERROR_FILENAME_EXCED_RANGE), hr, wine_dbgstr_w(path_outW));
- ok(lstrlenW(path_outW) == 0, "got %d\n", lstrlenW(path_outW));
+ ok(!*path_outW, "got %d\n", lstrlenW(path_outW));
path_inW[0] = 'C';
path_inW[1] = ':';
--
2.20.1
Dec. 10, 2019
[PATCH] dmloader: Fix the spelling of a TRACE() message and a comment.
by Francois Gouget
Signed-off-by: Francois Gouget <fgouget(a)free.fr>
---
dlls/dmloader/loader.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/dmloader/loader.c b/dlls/dmloader/loader.c
index 9048c02dfc7..60dd6f844b9 100644
--- a/dlls/dmloader/loader.c
+++ b/dlls/dmloader/loader.c
@@ -168,7 +168,7 @@ static struct cache_entry *find_cache_object(IDirectMusicLoaderImpl *This, DMUS_
struct cache_entry *existing;
/*
- * The Object is looked for the the following order.
+ * The Object is looked up in the following order.
* 1. DMUS_OBJ_OBJECT
* 2. DMUS_OBJ_STREAM
* 3. DMUS_OBJ_MEMORY
@@ -682,7 +682,7 @@ static HRESULT WINAPI IDirectMusicLoaderImpl_CacheObject(IDirectMusicLoader8 *if
entry = find_cache_object(This, &desc);
if (entry) {
if ((entry->Desc.dwValidData & DMUS_OBJ_LOADED) && entry->pObject) {
- TRACE("Object already laoded.\n");
+ TRACE("Object already loaded.\n");
return S_FALSE;
}
--
2.20.1
Dec. 10, 2019
Re: [PATCH v3 5/5] strmbase/renderer: Use base sink connection methods.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61758
Your paranoid android.
=== debian10 (32 bit report) ===
quartz:
vmr7.c:1395: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:1394: Test succeeded inside todo block: Got hr 0x1.
=== debian10 (32 bit Chinese:China report) ===
quartz:
vmr7.c:1395: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:1394: Test succeeded inside todo block: Got hr 0x1.
=== debian10 (32 bit WoW report) ===
quartz:
vmr7.c:1395: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:1394: Test succeeded inside todo block: Got hr 0x1.
=== debian10 (64 bit WoW report) ===
quartz:
vmr7.c:1395: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:904: Test failed: Got hr 0x80040227.
vmr9.c:1318: Test failed: Got hr 0x80040227 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1324: Test failed: Got hr 0x1.
vmr9.c:1394: Test succeeded inside todo block: Got hr 0x1.
Dec. 10, 2019
[PATCH v3 5/5] strmbase/renderer: Use base sink connection methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/vmr9.c | 8 +++--
dlls/strmbase/renderer.c | 63 ++++++++++++++--------------------------
2 files changed, 26 insertions(+), 45 deletions(-)
diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c
index a9b90b322dd..a3391870a76 100644
--- a/dlls/quartz/vmr9.c
+++ b/dlls/quartz/vmr9.c
@@ -356,7 +356,7 @@ static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force)
HRESULT hr;
TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow);
- if (This->num_surfaces || !This->renderer.sink.pin.peer)
+ if (This->num_surfaces)
return S_OK;
if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow)
@@ -410,7 +410,8 @@ static void vmr_start_stream(struct strmbase_renderer *iface)
TRACE("(%p)\n", This);
- VMR9_maybe_init(This, TRUE);
+ if (This->renderer.sink.pin.peer)
+ VMR9_maybe_init(This, TRUE);
IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie);
SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
This->source_rect.left,
@@ -1760,7 +1761,8 @@ static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowles
EnterCriticalSection(&This->renderer.filter.csFilter);
This->hWndClippingWindow = hwnd;
- VMR9_maybe_init(This, FALSE);
+ if (This->renderer.sink.pin.peer)
+ VMR9_maybe_init(This, FALSE);
if (!hwnd)
IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie);
LeaveCriticalSection(&This->renderer.filter.csFilter);
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index 7d8dbdfa936..7b9736ccfb2 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -40,46 +40,6 @@ static inline struct strmbase_renderer *impl_from_IPin(IPin *iface)
return CONTAINING_RECORD(iface, struct strmbase_renderer, sink.pin.IPin_iface);
}
-static HRESULT WINAPI BaseRenderer_InputPin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
-{
- struct strmbase_renderer *filter = impl_from_IPin(iface);
- HRESULT hr;
-
- TRACE("iface %p, peer %p, mt %p.\n", iface, peer, mt);
- strmbase_dump_media_type(mt);
-
- EnterCriticalSection(&filter->filter.csFilter);
- hr = BaseInputPinImpl_ReceiveConnection(iface, peer, mt);
- if (SUCCEEDED(hr))
- {
- if (filter->pFuncsTable->renderer_connect)
- hr = filter->pFuncsTable->renderer_connect(filter, mt);
- }
- LeaveCriticalSection(&filter->filter.csFilter);
-
- return hr;
-}
-
-static HRESULT WINAPI BaseRenderer_InputPin_Disconnect(IPin * iface)
-{
- struct strmbase_renderer *filter = impl_from_IPin(iface);
- HRESULT hr;
-
- TRACE("iface %p.\n", iface);
-
- EnterCriticalSection(&filter->filter.csFilter);
- hr = BaseInputPinImpl_Disconnect(iface);
- if (SUCCEEDED(hr))
- {
- if (filter->pFuncsTable->pfnBreakConnect)
- hr = filter->pFuncsTable->pfnBreakConnect(filter);
- }
- BaseRendererImpl_ClearPendingSample(filter);
- LeaveCriticalSection(&filter->filter.csFilter);
-
- return hr;
-}
-
static HRESULT WINAPI BaseRenderer_InputPin_EndOfStream(IPin * iface)
{
struct strmbase_renderer *filter = impl_from_IPin(iface);
@@ -157,8 +117,8 @@ static const IPinVtbl BaseRenderer_InputPin_Vtbl =
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseInputPinImpl_Connect,
- BaseRenderer_InputPin_ReceiveConnection,
- BaseRenderer_InputPin_Disconnect,
+ BaseInputPinImpl_ReceiveConnection,
+ BaseInputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
@@ -312,12 +272,31 @@ static HRESULT WINAPI BaseRenderer_Receive(struct strmbase_sink *pin, IMediaSamp
return BaseRendererImpl_Receive(filter, sample);
}
+static HRESULT sink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
+{
+ struct strmbase_renderer *filter = impl_from_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->renderer_connect)
+ return filter->pFuncsTable->renderer_connect(filter, mt);
+ return S_OK;
+}
+
+static void sink_disconnect(struct strmbase_sink *iface)
+{
+ struct strmbase_renderer *filter = impl_from_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->pfnBreakConnect)
+ filter->pFuncsTable->pfnBreakConnect(filter);
+}
+
static const struct strmbase_sink_ops sink_ops =
{
.base.pin_query_accept = sink_query_accept,
.base.pin_query_interface = sink_query_interface,
.base.pin_get_media_type = strmbase_pin_get_media_type,
.pfnReceive = BaseRenderer_Receive,
+ .sink_connect = sink_connect,
+ .sink_disconnect = sink_disconnect,
};
void strmbase_renderer_cleanup(struct strmbase_renderer *filter)
--
2.24.0
Dec. 10, 2019
[PATCH v3 4/5] strmbase/transform: Use base sink connection methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/strmbase/transform.c | 56 +++++++++++++++------------------------
1 file changed, 21 insertions(+), 35 deletions(-)
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index bf74ad0f491..993e30202bc 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -212,12 +212,31 @@ static HRESULT sink_query_interface(struct strmbase_pin *iface, REFIID iid, void
return S_OK;
}
+static HRESULT sink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
+{
+ TransformFilter *filter = impl_from_sink_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->transform_connect_sink)
+ return filter->pFuncsTable->transform_connect_sink(filter, mt);
+ return S_OK;
+}
+
+static void sink_disconnect(struct strmbase_sink *iface)
+{
+ TransformFilter *filter = impl_from_sink_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->pfnBreakConnect)
+ filter->pFuncsTable->pfnBreakConnect(filter, PINDIR_INPUT);
+}
+
static const struct strmbase_sink_ops sink_ops =
{
.base.pin_query_accept = sink_query_accept,
.base.pin_get_media_type = strmbase_pin_get_media_type,
.base.pin_query_interface = sink_query_interface,
.pfnReceive = TransformFilter_Input_Receive,
+ .sink_connect = sink_connect,
+ .sink_disconnect = sink_disconnect,
};
static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
@@ -397,39 +416,6 @@ static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface)
return VFW_E_NOT_CONNECTED;
}
-static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
-{
- TransformFilter *pTransform = impl_from_sink_IPin(iface);
- HRESULT hr = S_OK;
-
- TRACE("(%p)->(%p, %p)\n", iface, pReceivePin, pmt);
- strmbase_dump_media_type(pmt);
-
- if (pTransform->pFuncsTable->transform_connect_sink)
- hr = pTransform->pFuncsTable->transform_connect_sink(pTransform, pmt);
-
- if (SUCCEEDED(hr))
- {
- hr = BaseInputPinImpl_ReceiveConnection(iface, pReceivePin, pmt);
- if (FAILED(hr) && pTransform->pFuncsTable->pfnBreakConnect)
- pTransform->pFuncsTable->pfnBreakConnect(pTransform, PINDIR_INPUT);
- }
-
- return hr;
-}
-
-static HRESULT WINAPI TransformFilter_InputPin_Disconnect(IPin * iface)
-{
- TransformFilter *pTransform = impl_from_sink_IPin(iface);
-
- TRACE("(%p)->()\n", iface);
-
- if (pTransform->pFuncsTable->pfnBreakConnect)
- pTransform->pFuncsTable->pfnBreakConnect(pTransform, PINDIR_INPUT);
-
- return BaseInputPinImpl_Disconnect(iface);
-}
-
static HRESULT WINAPI TransformFilter_InputPin_BeginFlush(IPin * iface)
{
TransformFilter *pTransform = impl_from_sink_IPin(iface);
@@ -483,8 +469,8 @@ static const IPinVtbl TransformFilter_InputPin_Vtbl =
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseInputPinImpl_Connect,
- TransformFilter_InputPin_ReceiveConnection,
- TransformFilter_InputPin_Disconnect,
+ BaseInputPinImpl_ReceiveConnection,
+ BaseInputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
--
2.24.0
Dec. 10, 2019
[PATCH v3 3/5] strmbase: Add callbacks for sink (dis)connection.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avico.c | 4 +--
dlls/qcap/avimux.c | 4 +--
dlls/qcap/smartteefilter.c | 2 +-
dlls/qedit/samplegrabber.c | 2 +-
dlls/strmbase/pin.c | 56 +++++++++++++++++++++-----------------
dlls/strmbase/renderer.c | 2 +-
dlls/strmbase/transform.c | 2 +-
include/wine/strmbase.h | 9 +++---
8 files changed, 44 insertions(+), 37 deletions(-)
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c
index debe6bca386..f822d4e4616 100644
--- a/dlls/qcap/avico.c
+++ b/dlls/qcap/avico.c
@@ -291,7 +291,7 @@ static HRESULT WINAPI AVICompressorIn_ReceiveConnection(IPin *iface,
hres = fill_format_info(This, (VIDEOINFOHEADER*)pmt->pbFormat);
if(FAILED(hres))
- BasePinImpl_Disconnect(iface);
+ BaseInputPinImpl_Disconnect(iface);
return hres;
}
@@ -302,7 +302,7 @@ static HRESULT WINAPI AVICompressorIn_Disconnect(IPin *iface)
TRACE("(%p)\n", This);
- hres = BasePinImpl_Disconnect(iface);
+ hres = BaseInputPinImpl_Disconnect(iface);
if(FAILED(hres))
return hres;
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index c344ab47266..63e98e8877b 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1469,7 +1469,7 @@ static HRESULT WINAPI AviMuxIn_ReceiveConnection(IPin *iface,
if(SUCCEEDED(hr))
hr = IMemAllocator_Commit(avimuxin->samples_allocator);
if(FAILED(hr)) {
- BasePinImpl_Disconnect(iface);
+ BaseInputPinImpl_Disconnect(iface);
return hr;
}
@@ -1497,7 +1497,7 @@ static HRESULT WINAPI AviMuxIn_Disconnect(IPin *iface)
TRACE("pin %p.\n", avimuxin);
- hr = BasePinImpl_Disconnect(iface);
+ hr = BaseInputPinImpl_Disconnect(iface);
if(FAILED(hr))
return hr;
diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c
index 929929632f1..e1fcea55f91 100644
--- a/dlls/qcap/smartteefilter.c
+++ b/dlls/qcap/smartteefilter.c
@@ -87,7 +87,7 @@ static const IPinVtbl SmartTeeFilterInputVtbl = {
BasePinImpl_Release,
BaseInputPinImpl_Connect,
BaseInputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
+ BaseInputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
diff --git a/dlls/qedit/samplegrabber.c b/dlls/qedit/samplegrabber.c
index f8d90a5c0df..c65ab9caa70 100644
--- a/dlls/qedit/samplegrabber.c
+++ b/dlls/qedit/samplegrabber.c
@@ -523,7 +523,7 @@ static const IPinVtbl sink_vtbl =
BasePinImpl_Release,
BaseInputPinImpl_Connect,
SampleGrabber_In_IPin_ReceiveConnection,
- BasePinImpl_Disconnect,
+ BaseInputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c
index bcac22eb3c4..5255a6c7b0b 100644
--- a/dlls/strmbase/pin.c
+++ b/dlls/strmbase/pin.c
@@ -119,31 +119,6 @@ ULONG WINAPI BasePinImpl_Release(IPin *iface)
return IBaseFilter_Release(&pin->filter->IBaseFilter_iface);
}
-HRESULT WINAPI BasePinImpl_Disconnect(IPin * iface)
-{
- struct strmbase_pin *This = impl_from_IPin(iface);
- HRESULT hr;
-
- TRACE("(%p)->()\n", This);
-
- EnterCriticalSection(&This->filter->csFilter);
- {
- if (This->peer)
- {
- IPin_Release(This->peer);
- This->peer = NULL;
- FreeMediaType(&This->mt);
- ZeroMemory(&This->mt, sizeof(This->mt));
- hr = S_OK;
- }
- else
- hr = S_FALSE;
- }
- LeaveCriticalSection(&This->filter->csFilter);
-
- return hr;
-}
-
HRESULT WINAPI BasePinImpl_ConnectedTo(IPin * iface, IPin ** ppPin)
{
struct strmbase_pin *This = impl_from_IPin(iface);
@@ -685,6 +660,9 @@ HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceiveP
}
}
+ if (SUCCEEDED(hr) && This->pFuncsTable->sink_connect)
+ hr = This->pFuncsTable->sink_connect(This, pReceivePin, pmt);
+
if (SUCCEEDED(hr))
{
CopyMediaType(&This->pin.mt, pmt);
@@ -697,6 +675,34 @@ HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceiveP
return hr;
}
+HRESULT WINAPI BaseInputPinImpl_Disconnect(IPin *iface)
+{
+ struct strmbase_sink *pin = impl_sink_from_IPin(iface);
+ HRESULT hr;
+
+ TRACE("pin %p.\n", pin);
+
+ EnterCriticalSection(&pin->pin.filter->csFilter);
+
+ if (pin->pin.peer)
+ {
+ if (pin->pFuncsTable->sink_disconnect)
+ pin->pFuncsTable->sink_disconnect(pin);
+
+ IPin_Release(pin->pin.peer);
+ pin->pin.peer = NULL;
+ FreeMediaType(&pin->pin.mt);
+ memset(&pin->pin.mt, 0, sizeof(AM_MEDIA_TYPE));
+ hr = S_OK;
+ }
+ else
+ hr = S_FALSE;
+
+ LeaveCriticalSection(&pin->pin.filter->csFilter);
+
+ return hr;
+}
+
static HRESULT deliver_endofstream(IPin* pin, LPVOID unused)
{
return IPin_EndOfStream( pin );
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index cedcd9a62a0..7d8dbdfa936 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -68,7 +68,7 @@ static HRESULT WINAPI BaseRenderer_InputPin_Disconnect(IPin * iface)
TRACE("iface %p.\n", iface);
EnterCriticalSection(&filter->filter.csFilter);
- hr = BasePinImpl_Disconnect(iface);
+ hr = BaseInputPinImpl_Disconnect(iface);
if (SUCCEEDED(hr))
{
if (filter->pFuncsTable->pfnBreakConnect)
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 30ed0006cb1..bf74ad0f491 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -427,7 +427,7 @@ static HRESULT WINAPI TransformFilter_InputPin_Disconnect(IPin * iface)
if (pTransform->pFuncsTable->pfnBreakConnect)
pTransform->pFuncsTable->pfnBreakConnect(pTransform, PINDIR_INPUT);
- return BasePinImpl_Disconnect(iface);
+ return BaseInputPinImpl_Disconnect(iface);
}
static HRESULT WINAPI TransformFilter_InputPin_BeginFlush(IPin * iface)
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 461214cf082..83ad2e0bd6e 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -91,9 +91,10 @@ typedef HRESULT (WINAPI *BaseInputPin_Receive)(struct strmbase_sink *This, IMedi
struct strmbase_sink_ops
{
- BasePinFuncTable base;
- /* Optional */
- BaseInputPin_Receive pfnReceive;
+ BasePinFuncTable base;
+ BaseInputPin_Receive pfnReceive;
+ HRESULT (*sink_connect)(struct strmbase_sink *pin, IPin *peer, const AM_MEDIA_TYPE *mt);
+ void (*sink_disconnect)(struct strmbase_sink *pin);
};
/* Base Pin */
@@ -102,7 +103,7 @@ LONG WINAPI BasePinImpl_GetMediaTypeVersion(struct strmbase_pin *pin);
HRESULT WINAPI BasePinImpl_QueryInterface(IPin *iface, REFIID iid, void **out);
ULONG WINAPI BasePinImpl_AddRef(IPin *iface);
ULONG WINAPI BasePinImpl_Release(IPin *iface);
-HRESULT WINAPI BasePinImpl_Disconnect(IPin * iface);
+HRESULT WINAPI BaseInputPinImpl_Disconnect(IPin * iface);
HRESULT WINAPI BasePinImpl_ConnectedTo(IPin * iface, IPin ** ppPin);
HRESULT WINAPI BasePinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt);
HRESULT WINAPI BasePinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo);
--
2.24.0
Dec. 10, 2019
[PATCH v3 2/5] strmbase: Pass an AM_MEDIA_TYPE pointer to CompleteConnect().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/dsoundrender.c | 13 +++-----
dlls/quartz/vmr9.c | 65 +++++++++++++++++++-------------------
dlls/strmbase/renderer.c | 4 +--
include/wine/strmbase.h | 3 +-
4 files changed, 39 insertions(+), 46 deletions(-)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c
index cad210a8762..6fd49dac9b5 100644
--- a/dlls/quartz/dsoundrender.c
+++ b/dlls/quartz/dsoundrender.c
@@ -413,18 +413,13 @@ static void dsound_render_start_stream(struct strmbase_renderer *iface)
}
}
-static HRESULT WINAPI DSoundRender_CompleteConnect(struct strmbase_renderer *iface, IPin *pReceivePin)
+static HRESULT dsound_render_connect(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt)
{
DSoundRenderImpl *This = impl_from_strmbase_renderer(iface);
- const AM_MEDIA_TYPE *pmt = &This->renderer.sink.pin.mt;
+ const WAVEFORMATEX *format = (WAVEFORMATEX *)mt->pbFormat;
HRESULT hr = S_OK;
- WAVEFORMATEX *format;
DSBUFFERDESC buf_desc;
- TRACE("(%p)->(%p)\n", This, pReceivePin);
-
- format = (WAVEFORMATEX*)pmt->pbFormat;
-
This->buf_size = format->nAvgBytesPerSec;
memset(&buf_desc,0,sizeof(DSBUFFERDESC));
@@ -433,7 +428,7 @@ static HRESULT WINAPI DSoundRender_CompleteConnect(struct strmbase_renderer *ifa
DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS |
DSBCAPS_GETCURRENTPOSITION2;
buf_desc.dwBufferBytes = This->buf_size;
- buf_desc.lpwfxFormat = format;
+ buf_desc.lpwfxFormat = (WAVEFORMATEX *)format;
hr = IDirectSound8_CreateSoundBuffer(This->dsound, &buf_desc, &This->dsbuffer, NULL);
This->writepos = This->buf_size;
if (FAILED(hr))
@@ -539,7 +534,7 @@ static const struct strmbase_renderer_ops renderer_ops =
.renderer_stop_stream = dsound_render_stop_stream,
.pfnShouldDrawSampleNow = DSoundRender_ShouldDrawSampleNow,
.pfnPrepareReceive = DSoundRender_PrepareReceive,
- .pfnCompleteConnect = DSoundRender_CompleteConnect,
+ .renderer_connect = dsound_render_connect,
.pfnBreakConnect = DSoundRender_BreakConnect,
.pfnEndOfStream = DSoundRender_EndOfStream,
.pfnEndFlush = DSoundRender_EndFlush,
diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c
index 60c19e00191..a9b90b322dd 100644
--- a/dlls/quartz/vmr9.c
+++ b/dlls/quartz/vmr9.c
@@ -331,38 +331,20 @@ static HRESULT WINAPI VMR9_DoRenderSample(struct strmbase_renderer *iface, IMedi
return hr;
}
-static HRESULT WINAPI VMR9_CheckMediaType(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *pmt)
+static HRESULT WINAPI VMR9_CheckMediaType(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt)
{
- struct quartz_vmr *This = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
+ const VIDEOINFOHEADER *vih;
- if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat)
+ if (!IsEqualIID(&mt->majortype, &MEDIATYPE_Video) || !mt->pbFormat)
return S_FALSE;
- /* Ignore subtype, test for bicompression instead */
- if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
- {
- VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
+ if (!IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo)
+ && !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo2))
+ return S_FALSE;
- This->bmiheader = format->bmiHeader;
- This->VideoWidth = format->bmiHeader.biWidth;
- This->VideoHeight = format->bmiHeader.biHeight;
- SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight);
- }
- else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
- {
- VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat;
+ vih = (VIDEOINFOHEADER *)mt->pbFormat;
- This->bmiheader = format->bmiHeader;
- This->VideoWidth = format->bmiHeader.biWidth;
- This->VideoHeight = format->bmiHeader.biHeight;
- SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight);
- }
- else
- {
- ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
- return S_FALSE;
- }
- if (This->bmiheader.biCompression != BI_RGB)
+ if (vih->bmiHeader.biCompression != BI_RGB)
return S_FALSE;
return S_OK;
}
@@ -461,16 +443,33 @@ static HRESULT WINAPI VMR9_ShouldDrawSampleNow(struct strmbase_renderer *iface,
return S_FALSE;
}
-static HRESULT WINAPI VMR9_CompleteConnect(struct strmbase_renderer *This, IPin *pReceivePin)
+static HRESULT vmr_connect(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt)
{
- struct quartz_vmr *pVMR9 = impl_from_IBaseFilter(&This->filter.IBaseFilter_iface);
+ struct quartz_vmr *filter = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
HRESULT hr;
- TRACE("(%p)\n", This);
+ if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
+ {
+ VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)mt->pbFormat;
+
+ filter->bmiheader = format->bmiHeader;
+ filter->VideoWidth = format->bmiHeader.biWidth;
+ filter->VideoHeight = format->bmiHeader.biHeight;
+ SetRect(&filter->source_rect, 0, 0, filter->VideoWidth, filter->VideoHeight);
+ }
+ else if (IsEqualIID(&mt->formattype, &FORMAT_VideoInfo2))
+ {
+ VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)mt->pbFormat;
+
+ filter->bmiheader = format->bmiHeader;
+ filter->VideoWidth = format->bmiHeader.biWidth;
+ filter->VideoHeight = format->bmiHeader.biHeight;
+ SetRect(&filter->source_rect, 0, 0, filter->VideoWidth, filter->VideoHeight);
+ }
- if (pVMR9->mode ||
- SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&pVMR9->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
- hr = VMR9_maybe_init(pVMR9, FALSE);
+ if (filter->mode
+ || SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&filter->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
+ hr = VMR9_maybe_init(filter, FALSE);
return hr;
}
@@ -576,7 +575,7 @@ static const struct strmbase_renderer_ops renderer_ops =
.renderer_start_stream = vmr_start_stream,
.renderer_stop_stream = vmr_stop_stream,
.pfnShouldDrawSampleNow = VMR9_ShouldDrawSampleNow,
- .pfnCompleteConnect = VMR9_CompleteConnect,
+ .renderer_connect = vmr_connect,
.pfnBreakConnect = VMR9_BreakConnect,
.renderer_destroy = vmr_destroy,
.renderer_query_interface = vmr_query_interface,
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index d592ab034e6..cedcd9a62a0 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -52,8 +52,8 @@ static HRESULT WINAPI BaseRenderer_InputPin_ReceiveConnection(IPin *iface, IPin
hr = BaseInputPinImpl_ReceiveConnection(iface, peer, mt);
if (SUCCEEDED(hr))
{
- if (filter->pFuncsTable->pfnCompleteConnect)
- hr = filter->pFuncsTable->pfnCompleteConnect(filter, peer);
+ if (filter->pFuncsTable->renderer_connect)
+ hr = filter->pFuncsTable->renderer_connect(filter, mt);
}
LeaveCriticalSection(&filter->filter.csFilter);
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 7e3b38b49d5..461214cf082 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -523,7 +523,6 @@ typedef HRESULT (WINAPI *BaseRenderer_EndOfStream)(struct strmbase_renderer *ifa
typedef HRESULT (WINAPI *BaseRenderer_BeginFlush) (struct strmbase_renderer *iface);
typedef HRESULT (WINAPI *BaseRenderer_EndFlush) (struct strmbase_renderer *iface);
typedef HRESULT (WINAPI *BaseRenderer_BreakConnect) (struct strmbase_renderer *iface);
-typedef HRESULT (WINAPI *BaseRenderer_CompleteConnect) (struct strmbase_renderer *iface, IPin *peer);
struct strmbase_renderer_ops
{
@@ -534,7 +533,7 @@ struct strmbase_renderer_ops
void (*renderer_stop_stream)(struct strmbase_renderer *iface);
BaseRenderer_ShouldDrawSampleNow pfnShouldDrawSampleNow;
BaseRenderer_PrepareReceive pfnPrepareReceive;
- BaseRenderer_CompleteConnect pfnCompleteConnect;
+ HRESULT (*renderer_connect)(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt);
BaseRenderer_BreakConnect pfnBreakConnect;
BaseRenderer_EndOfStream pfnEndOfStream;
BaseRenderer_EndFlush pfnEndFlush;
--
2.24.0
Dec. 10, 2019
[PATCH v3 1/5] strmbase: Combine the SetMediaType() and CompleteConnect() callbacks.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/acmwrapper.c | 115 +++++++-----------------
dlls/quartz/avidec.c | 37 ++------
dlls/strmbase/transform.c | 7 +-
dlls/winegstreamer/gsttffilter.c | 146 +++++++++++--------------------
dlls/wineqtdecoder/qtvdecoder.c | 25 ++----
include/wine/strmbase.h | 5 +-
6 files changed, 103 insertions(+), 232 deletions(-)
diff --git a/dlls/quartz/acmwrapper.c b/dlls/quartz/acmwrapper.c
index 8eea6ab147d..33d9debe5cd 100644
--- a/dlls/quartz/acmwrapper.c
+++ b/dlls/quartz/acmwrapper.c
@@ -40,7 +40,6 @@ typedef struct ACMWrapperImpl
TransformFilter tf;
HACMSTREAM has;
- LPWAVEFORMATEX pWfIn;
LPWAVEFORMATEX pWfOut;
LONGLONG lasttime_real;
@@ -224,85 +223,43 @@ error:
return hr;
}
-static HRESULT WINAPI ACMWrapper_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
+static BOOL is_audio_subtype(const GUID *guid)
{
- ACMWrapperImpl* This = impl_from_TransformFilter(tf);
- MMRESULT res;
-
- TRACE("(%p)->(%i %p)\n", This, dir, pmt);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
- /* Check root (GUID w/o FOURCC) */
- if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio)) &&
- (!memcmp(((const char *)&pmt->subtype)+4, ((const char *)&MEDIATYPE_Audio)+4, sizeof(GUID)-4)) &&
- (IsEqualIID(&pmt->formattype, &FORMAT_WaveFormatEx)))
- {
- HACMSTREAM drv;
- WAVEFORMATEX *wfx = (WAVEFORMATEX*)pmt->pbFormat;
- AM_MEDIA_TYPE* outpmt = &This->tf.pmt;
-
- if (!wfx || wfx->wFormatTag == WAVE_FORMAT_PCM || wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
- return VFW_E_TYPE_NOT_ACCEPTED;
- FreeMediaType(outpmt);
-
- This->pWfIn = (LPWAVEFORMATEX)pmt->pbFormat;
-
- /* HACK */
- /* TRACE("ALIGN = %d\n", pACMWrapper->pWfIn->nBlockAlign); */
- /* pACMWrapper->pWfIn->nBlockAlign = 1; */
-
- /* Set output audio data to PCM */
- CopyMediaType(outpmt, pmt);
- outpmt->subtype.Data1 = WAVE_FORMAT_PCM;
- This->pWfOut = (WAVEFORMATEX*)outpmt->pbFormat;
- This->pWfOut->wFormatTag = WAVE_FORMAT_PCM;
- This->pWfOut->wBitsPerSample = 16;
- This->pWfOut->nBlockAlign = This->pWfOut->wBitsPerSample * This->pWfOut->nChannels / 8;
- This->pWfOut->cbSize = 0;
- This->pWfOut->nAvgBytesPerSec = This->pWfOut->nChannels * This->pWfOut->nSamplesPerSec
- * (This->pWfOut->wBitsPerSample/8);
-
- if (!(res = acmStreamOpen(&drv, NULL, This->pWfIn, This->pWfOut, NULL, 0, 0, 0)))
- {
- This->has = drv;
-
- TRACE("Connection accepted\n");
- return S_OK;
- }
- else
- FIXME("acmStreamOpen returned %d\n", res);
- FreeMediaType(outpmt);
- TRACE("Unable to find a suitable ACM decompressor\n");
- }
-
- TRACE("Connection refused\n");
- return VFW_E_TYPE_NOT_ACCEPTED;
+ return !memcmp(&guid->Data2, &MEDIATYPE_Audio.Data2, sizeof(GUID) - sizeof(int));
}
-static HRESULT WINAPI ACMWrapper_CompleteConnect(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
+static HRESULT acm_wrapper_connect_sink(TransformFilter *iface, const AM_MEDIA_TYPE *mt)
{
- ACMWrapperImpl* This = impl_from_TransformFilter(tf);
- MMRESULT res;
+ ACMWrapperImpl *filter = impl_from_TransformFilter(iface);
+ const WAVEFORMATEX *wfx = (WAVEFORMATEX *)mt->pbFormat;
HACMSTREAM drv;
+ MMRESULT res;
- TRACE("(%p)\n", This);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
- if (!(res = acmStreamOpen(&drv, NULL, This->pWfIn, This->pWfOut, NULL, 0, 0, 0)))
+ if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio) || !is_audio_subtype(&mt->subtype)
+ || !IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx) || !wfx
+ || wfx->wFormatTag == WAVE_FORMAT_PCM || wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ CopyMediaType(&filter->tf.pmt, mt);
+ filter->tf.pmt.subtype.Data1 = WAVE_FORMAT_PCM;
+ filter->pWfOut = (WAVEFORMATEX *)filter->tf.pmt.pbFormat;
+ filter->pWfOut->wFormatTag = WAVE_FORMAT_PCM;
+ filter->pWfOut->wBitsPerSample = 16;
+ filter->pWfOut->nBlockAlign = filter->pWfOut->wBitsPerSample * filter->pWfOut->nChannels / 8;
+ filter->pWfOut->cbSize = 0;
+ filter->pWfOut->nAvgBytesPerSec = filter->pWfOut->nChannels * filter->pWfOut->nSamplesPerSec
+ * (filter->pWfOut->wBitsPerSample / 8);
+
+ if ((res = acmStreamOpen(&drv, NULL, (WAVEFORMATEX *)wfx, filter->pWfOut, NULL, 0, 0, 0)))
{
- This->has = drv;
-
- TRACE("Connection accepted\n");
- return S_OK;
+ ERR("Failed to open stream, error %u.\n", res);
+ FreeMediaType(&filter->tf.pmt);
+ return VFW_E_TYPE_NOT_ACCEPTED;
}
- FIXME("acmStreamOpen returned %d\n", res);
- TRACE("Unable to find a suitable ACM decompressor\n");
- return VFW_E_TYPE_NOT_ACCEPTED;
+ filter->has = drv;
+
+ return S_OK;
}
static HRESULT WINAPI ACMWrapper_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir)
@@ -341,18 +298,10 @@ static HRESULT WINAPI ACMWrapper_DecideBufferSize(TransformFilter *tf, IMemAlloc
}
static const TransformFilterFuncTable ACMWrapper_FuncsTable = {
- ACMWrapper_DecideBufferSize,
- NULL,
- ACMWrapper_Receive,
- NULL,
- NULL,
- ACMWrapper_SetMediaType,
- ACMWrapper_CompleteConnect,
- ACMWrapper_BreakConnect,
- NULL,
- NULL,
- NULL,
- NULL
+ .pfnDecideBufferSize = ACMWrapper_DecideBufferSize,
+ .pfnReceive = ACMWrapper_Receive,
+ .transform_connect_sink = acm_wrapper_connect_sink,
+ .pfnBreakConnect = ACMWrapper_BreakConnect,
};
HRESULT ACMWrapper_create(IUnknown *outer, void **out)
diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c
index 32969a34730..abed957fa6d 100644
--- a/dlls/quartz/avidec.c
+++ b/dlls/quartz/avidec.c
@@ -210,16 +210,11 @@ static HRESULT WINAPI AVIDec_StopStreaming(TransformFilter* pTransformFilter)
return S_OK;
}
-static HRESULT WINAPI AVIDec_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
+static HRESULT avi_dec_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *pmt)
{
AVIDecImpl* This = impl_from_TransformFilter(tf);
HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
- TRACE("(%p)->(%p)\n", This, pmt);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
/* Check root (GUID w/o FOURCC) */
if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) &&
(!memcmp(((const char *)&pmt->subtype)+4, ((const char *)&MEDIATYPE_Video)+4, sizeof(GUID)-4)))
@@ -310,15 +305,6 @@ failed:
return hr;
}
-static HRESULT WINAPI AVIDec_CompleteConnect(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- AVIDecImpl* This = impl_from_TransformFilter(tf);
-
- TRACE("(%p)\n", This);
-
- return S_OK;
-}
-
static HRESULT WINAPI AVIDec_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir)
{
AVIDecImpl *This = impl_from_TransformFilter(tf);
@@ -357,19 +343,14 @@ static HRESULT WINAPI AVIDec_DecideBufferSize(TransformFilter *tf, IMemAllocator
}
static const TransformFilterFuncTable AVIDec_FuncsTable = {
- AVIDec_DecideBufferSize,
- AVIDec_StartStreaming,
- AVIDec_Receive,
- AVIDec_StopStreaming,
- NULL,
- AVIDec_SetMediaType,
- AVIDec_CompleteConnect,
- AVIDec_BreakConnect,
- NULL,
- NULL,
- AVIDec_EndFlush,
- NULL,
- AVIDec_NotifyDrop
+ .pfnDecideBufferSize = AVIDec_DecideBufferSize,
+ .pfnStartStreaming = AVIDec_StartStreaming,
+ .pfnReceive = AVIDec_Receive,
+ .pfnStopStreaming = AVIDec_StopStreaming,
+ .transform_connect_sink = avi_dec_connect_sink,
+ .pfnBreakConnect = AVIDec_BreakConnect,
+ .pfnEndFlush = AVIDec_EndFlush,
+ .pfnNotify = AVIDec_NotifyDrop,
};
HRESULT AVIDec_create(IUnknown *outer, void **out)
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 7a79f709055..30ed0006cb1 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -405,11 +405,8 @@ static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, I
TRACE("(%p)->(%p, %p)\n", iface, pReceivePin, pmt);
strmbase_dump_media_type(pmt);
- if (pTransform->pFuncsTable->pfnSetMediaType)
- hr = pTransform->pFuncsTable->pfnSetMediaType(pTransform, PINDIR_INPUT, pmt);
-
- if (SUCCEEDED(hr) && pTransform->pFuncsTable->pfnCompleteConnect)
- hr = pTransform->pFuncsTable->pfnCompleteConnect(pTransform, PINDIR_INPUT, pReceivePin);
+ if (pTransform->pFuncsTable->transform_connect_sink)
+ hr = pTransform->pFuncsTable->transform_connect_sink(pTransform, pmt);
if (SUCCEEDED(hr))
{
diff --git a/dlls/winegstreamer/gsttffilter.c b/dlls/winegstreamer/gsttffilter.c
index ee1851dfdc6..d44a6ae33a6 100644
--- a/dlls/winegstreamer/gsttffilter.c
+++ b/dlls/winegstreamer/gsttffilter.c
@@ -516,7 +516,7 @@ static HRESULT WINAPI Gstreamer_Mp3_QueryConnect(TransformFilter *iface, const A
return S_OK;
}
-static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT mp3_decoder_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -525,13 +525,8 @@ static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECT
HRESULT hr;
int layer;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_Mp3_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return VFW_E_TYPE_NOT_ACCEPTED;
@@ -588,26 +583,19 @@ static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECT
return hr;
}
-static HRESULT WINAPI Gstreamer_Mp3_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- TRACE("%p 0x%x %p\n", tf, dir, pin);
- return S_OK;
-}
-
static const TransformFilterFuncTable Gstreamer_Mp3_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_Mp3_QueryConnect,
- Gstreamer_Mp3_SetMediaType,
- Gstreamer_Mp3_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_Mp3_QueryConnect,
+ .transform_connect_sink = mp3_decoder_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *punkouter, HRESULT *phr)
@@ -664,13 +652,7 @@ static HRESULT WINAPI Gstreamer_YUV_QueryConnect(TransformFilter *iface, const A
}
}
-static HRESULT WINAPI Gstreamer_YUV_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- TRACE("%p 0x%x %p\n", tf, dir, pin);
- return S_OK;
-}
-
-static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT yuv_to_rgb_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -679,13 +661,8 @@ static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DI
int avgtime;
LONG width, height;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@@ -738,19 +715,18 @@ static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DI
}
static const TransformFilterFuncTable Gstreamer_YUV2RGB_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_YUV_QueryConnect,
- Gstreamer_YUV2RGB_SetMediaType,
- Gstreamer_YUV_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_YUV_QueryConnect,
+ .transform_connect_sink = yuv_to_rgb_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *punkouter, HRESULT *phr)
@@ -772,7 +748,7 @@ IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *punkouter, HRESULT *phr)
return obj;
}
-static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT yuv_to_argb_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -781,13 +757,8 @@ static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_D
int avgtime;
LONG width, height;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@@ -840,19 +811,18 @@ static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_D
}
static const TransformFilterFuncTable Gstreamer_YUV2ARGB_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_YUV_QueryConnect,
- Gstreamer_YUV2ARGB_SetMediaType,
- Gstreamer_YUV_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_YUV_QueryConnect,
+ .transform_connect_sink = yuv_to_argb_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_YUV2ARGB_create(IUnknown *punkouter, HRESULT *phr)
@@ -886,13 +856,7 @@ static HRESULT WINAPI Gstreamer_AudioConvert_QueryConnect(TransformFilter *iface
return S_OK;
}
-static HRESULT WINAPI Gstreamer_AudioConvert_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- TRACE("%p 0x%x %p\n", tf, dir, pin);
- return S_OK;
-}
-
-static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT audio_converter_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -905,13 +869,8 @@ static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, P
BOOL inisfloat = FALSE;
int indepth;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_AudioConvert_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@@ -972,19 +931,18 @@ static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, P
}
static const TransformFilterFuncTable Gstreamer_AudioConvert_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_AudioConvert_QueryConnect,
- Gstreamer_AudioConvert_SetMediaType,
- Gstreamer_AudioConvert_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_AudioConvert_QueryConnect,
+ .transform_connect_sink = audio_converter_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_AudioConvert_create(IUnknown *punkouter, HRESULT *phr)
diff --git a/dlls/wineqtdecoder/qtvdecoder.c b/dlls/wineqtdecoder/qtvdecoder.c
index 3da0738aecb..4be654e5a10 100644
--- a/dlls/wineqtdecoder/qtvdecoder.c
+++ b/dlls/wineqtdecoder/qtvdecoder.c
@@ -336,7 +336,7 @@ static HRESULT WINAPI QTVDecoder_StopStreaming(TransformFilter* pTransformFilter
return S_OK;
}
-static HRESULT WINAPI QTVDecoder_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
+static HRESULT video_decoder_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *pmt)
{
QTVDecoderImpl* This = impl_from_TransformFilter(tf);
HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
@@ -344,11 +344,6 @@ static HRESULT WINAPI QTVDecoder_SetMediaType(TransformFilter *tf, PIN_DIRECTION
AM_MEDIA_TYPE *outpmt = &This->tf.pmt;
CFNumberRef n = NULL;
- TRACE("(%p)->(%p)\n", This, pmt);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
FreeMediaType(outpmt);
CopyMediaType(outpmt, pmt);
@@ -502,18 +497,12 @@ static HRESULT WINAPI QTVDecoder_DecideBufferSize(TransformFilter *tf, IMemAlloc
}
static const TransformFilterFuncTable QTVDecoder_FuncsTable = {
- QTVDecoder_DecideBufferSize,
- QTVDecoder_StartStreaming,
- QTVDecoder_Receive,
- QTVDecoder_StopStreaming,
- NULL,
- QTVDecoder_SetMediaType,
- NULL,
- QTVDecoder_BreakConnect,
- NULL,
- NULL,
- NULL,
- NULL
+ .pfnDecideBufferSize = QTVDecoder_DecideBufferSize,
+ .pfnStartStreaming = QTVDecoder_StartStreaming,
+ .pfnReceive = QTVDecoder_Receive,
+ .pfnStopStreaming = QTVDecoder_StopStreaming,
+ .transform_connect_sink = video_decoder_connect_sink,
+ .pfnBreakConnect = QTVDecoder_BreakConnect,
};
IUnknown * CALLBACK QTVDecoder_create(IUnknown *outer, HRESULT* phr)
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index c3699f19253..7e3b38b49d5 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -197,9 +197,7 @@ typedef HRESULT (WINAPI *TransformFilter_DecideBufferSize) (TransformFilter *ifa
typedef HRESULT (WINAPI *TransformFilter_StartStreaming) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_StopStreaming) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_Receive) (TransformFilter* iface, IMediaSample* pIn);
-typedef HRESULT (WINAPI *TransformFilter_CompleteConnect) (TransformFilter *iface, PIN_DIRECTION dir, IPin *pPin);
typedef HRESULT (WINAPI *TransformFilter_BreakConnect) (TransformFilter *iface, PIN_DIRECTION dir);
-typedef HRESULT (WINAPI *TransformFilter_SetMediaType) (TransformFilter *iface, PIN_DIRECTION dir, const AM_MEDIA_TYPE *pMediaType);
typedef HRESULT (WINAPI *TransformFilter_CheckInputType) (TransformFilter *iface, const AM_MEDIA_TYPE *pMediaType);
typedef HRESULT (WINAPI *TransformFilter_EndOfStream) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_BeginFlush) (TransformFilter *iface);
@@ -216,8 +214,7 @@ typedef struct TransformFilterFuncTable {
TransformFilter_Receive pfnReceive;
TransformFilter_StopStreaming pfnStopStreaming;
TransformFilter_CheckInputType pfnCheckInputType;
- TransformFilter_SetMediaType pfnSetMediaType;
- TransformFilter_CompleteConnect pfnCompleteConnect;
+ HRESULT (*transform_connect_sink)(TransformFilter *filter, const AM_MEDIA_TYPE *mt);
TransformFilter_BreakConnect pfnBreakConnect;
TransformFilter_EndOfStream pfnEndOfStream;
TransformFilter_BeginFlush pfnBeginFlush;
--
2.24.0
Dec. 10, 2019
Re: [PATCH v2 5/5] strmbase/renderer: Use base sink connection methods.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61749
Your paranoid android.
=== debian10 (build log) ===
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The win32 build failed
=== debian10 (build log) ===
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The wow64 build failed
Dec. 10, 2019
Re: [PATCH v2 4/5] strmbase/transform: Use base sink connection methods.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61748
Your paranoid android.
=== debian10 (build log) ===
/home/winetest/tools/testbot/var/wine-win32/dlls/strmbase/../../../wine/dlls/strmbase/renderer.c:71: undefined reference to `BasePinImpl_Disconnect'
collect2: error: ld returned 1 exit status
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The win32 build failed
=== debian10 (build log) ===
/home/winetest/tools/testbot/var/wine-wow64/dlls/strmbase/../../../wine/dlls/strmbase/renderer.c:71: undefined reference to `BasePinImpl_Disconnect'
collect2: error: ld returned 1 exit status
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The wow64 build failed
Dec. 10, 2019
Re: [PATCH v2 3/5] strmbase: Add callbacks for sink (dis)connection.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61747
Your paranoid android.
=== debian10 (build log) ===
/home/winetest/tools/testbot/var/wine-win32/dlls/strmbase/../../../wine/dlls/strmbase/renderer.c:71: undefined reference to `BasePinImpl_Disconnect'
collect2: error: ld returned 1 exit status
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The win32 build failed
=== debian10 (build log) ===
/home/winetest/tools/testbot/var/wine-wow64/dlls/strmbase/../../../wine/dlls/strmbase/renderer.c:71: undefined reference to `BasePinImpl_Disconnect'
collect2: error: ld returned 1 exit status
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The wow64 build failed
Dec. 10, 2019
[PATCH v2 5/5] strmbase/renderer: Use base sink connection methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/vmr9.c | 8 +++--
dlls/strmbase/renderer.c | 63 ++++++++++++++--------------------------
2 files changed, 26 insertions(+), 45 deletions(-)
diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c
index a9b90b322dd..a3391870a76 100644
--- a/dlls/quartz/vmr9.c
+++ b/dlls/quartz/vmr9.c
@@ -356,7 +356,7 @@ static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force)
HRESULT hr;
TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow);
- if (This->num_surfaces || !This->renderer.sink.pin.peer)
+ if (This->num_surfaces)
return S_OK;
if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow)
@@ -410,7 +410,8 @@ static void vmr_start_stream(struct strmbase_renderer *iface)
TRACE("(%p)\n", This);
- VMR9_maybe_init(This, TRUE);
+ if (This->renderer.sink.pin.peer)
+ VMR9_maybe_init(This, TRUE);
IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie);
SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
This->source_rect.left,
@@ -1760,7 +1761,8 @@ static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowles
EnterCriticalSection(&This->renderer.filter.csFilter);
This->hWndClippingWindow = hwnd;
- VMR9_maybe_init(This, FALSE);
+ if (This->renderer.sink.pin.peer)
+ VMR9_maybe_init(This, FALSE);
if (!hwnd)
IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie);
LeaveCriticalSection(&This->renderer.filter.csFilter);
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index cedcd9a62a0..7b9736ccfb2 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -40,46 +40,6 @@ static inline struct strmbase_renderer *impl_from_IPin(IPin *iface)
return CONTAINING_RECORD(iface, struct strmbase_renderer, sink.pin.IPin_iface);
}
-static HRESULT WINAPI BaseRenderer_InputPin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
-{
- struct strmbase_renderer *filter = impl_from_IPin(iface);
- HRESULT hr;
-
- TRACE("iface %p, peer %p, mt %p.\n", iface, peer, mt);
- strmbase_dump_media_type(mt);
-
- EnterCriticalSection(&filter->filter.csFilter);
- hr = BaseInputPinImpl_ReceiveConnection(iface, peer, mt);
- if (SUCCEEDED(hr))
- {
- if (filter->pFuncsTable->renderer_connect)
- hr = filter->pFuncsTable->renderer_connect(filter, mt);
- }
- LeaveCriticalSection(&filter->filter.csFilter);
-
- return hr;
-}
-
-static HRESULT WINAPI BaseRenderer_InputPin_Disconnect(IPin * iface)
-{
- struct strmbase_renderer *filter = impl_from_IPin(iface);
- HRESULT hr;
-
- TRACE("iface %p.\n", iface);
-
- EnterCriticalSection(&filter->filter.csFilter);
- hr = BasePinImpl_Disconnect(iface);
- if (SUCCEEDED(hr))
- {
- if (filter->pFuncsTable->pfnBreakConnect)
- hr = filter->pFuncsTable->pfnBreakConnect(filter);
- }
- BaseRendererImpl_ClearPendingSample(filter);
- LeaveCriticalSection(&filter->filter.csFilter);
-
- return hr;
-}
-
static HRESULT WINAPI BaseRenderer_InputPin_EndOfStream(IPin * iface)
{
struct strmbase_renderer *filter = impl_from_IPin(iface);
@@ -157,8 +117,8 @@ static const IPinVtbl BaseRenderer_InputPin_Vtbl =
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseInputPinImpl_Connect,
- BaseRenderer_InputPin_ReceiveConnection,
- BaseRenderer_InputPin_Disconnect,
+ BaseInputPinImpl_ReceiveConnection,
+ BaseInputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
@@ -312,12 +272,31 @@ static HRESULT WINAPI BaseRenderer_Receive(struct strmbase_sink *pin, IMediaSamp
return BaseRendererImpl_Receive(filter, sample);
}
+static HRESULT sink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
+{
+ struct strmbase_renderer *filter = impl_from_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->renderer_connect)
+ return filter->pFuncsTable->renderer_connect(filter, mt);
+ return S_OK;
+}
+
+static void sink_disconnect(struct strmbase_sink *iface)
+{
+ struct strmbase_renderer *filter = impl_from_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->pfnBreakConnect)
+ filter->pFuncsTable->pfnBreakConnect(filter);
+}
+
static const struct strmbase_sink_ops sink_ops =
{
.base.pin_query_accept = sink_query_accept,
.base.pin_query_interface = sink_query_interface,
.base.pin_get_media_type = strmbase_pin_get_media_type,
.pfnReceive = BaseRenderer_Receive,
+ .sink_connect = sink_connect,
+ .sink_disconnect = sink_disconnect,
};
void strmbase_renderer_cleanup(struct strmbase_renderer *filter)
--
2.24.0
Dec. 10, 2019
[PATCH v2 4/5] strmbase/transform: Use base sink connection methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/strmbase/transform.c | 56 +++++++++++++++------------------------
1 file changed, 21 insertions(+), 35 deletions(-)
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 30ed0006cb1..993e30202bc 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -212,12 +212,31 @@ static HRESULT sink_query_interface(struct strmbase_pin *iface, REFIID iid, void
return S_OK;
}
+static HRESULT sink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
+{
+ TransformFilter *filter = impl_from_sink_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->transform_connect_sink)
+ return filter->pFuncsTable->transform_connect_sink(filter, mt);
+ return S_OK;
+}
+
+static void sink_disconnect(struct strmbase_sink *iface)
+{
+ TransformFilter *filter = impl_from_sink_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->pfnBreakConnect)
+ filter->pFuncsTable->pfnBreakConnect(filter, PINDIR_INPUT);
+}
+
static const struct strmbase_sink_ops sink_ops =
{
.base.pin_query_accept = sink_query_accept,
.base.pin_get_media_type = strmbase_pin_get_media_type,
.base.pin_query_interface = sink_query_interface,
.pfnReceive = TransformFilter_Input_Receive,
+ .sink_connect = sink_connect,
+ .sink_disconnect = sink_disconnect,
};
static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
@@ -397,39 +416,6 @@ static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface)
return VFW_E_NOT_CONNECTED;
}
-static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
-{
- TransformFilter *pTransform = impl_from_sink_IPin(iface);
- HRESULT hr = S_OK;
-
- TRACE("(%p)->(%p, %p)\n", iface, pReceivePin, pmt);
- strmbase_dump_media_type(pmt);
-
- if (pTransform->pFuncsTable->transform_connect_sink)
- hr = pTransform->pFuncsTable->transform_connect_sink(pTransform, pmt);
-
- if (SUCCEEDED(hr))
- {
- hr = BaseInputPinImpl_ReceiveConnection(iface, pReceivePin, pmt);
- if (FAILED(hr) && pTransform->pFuncsTable->pfnBreakConnect)
- pTransform->pFuncsTable->pfnBreakConnect(pTransform, PINDIR_INPUT);
- }
-
- return hr;
-}
-
-static HRESULT WINAPI TransformFilter_InputPin_Disconnect(IPin * iface)
-{
- TransformFilter *pTransform = impl_from_sink_IPin(iface);
-
- TRACE("(%p)->()\n", iface);
-
- if (pTransform->pFuncsTable->pfnBreakConnect)
- pTransform->pFuncsTable->pfnBreakConnect(pTransform, PINDIR_INPUT);
-
- return BasePinImpl_Disconnect(iface);
-}
-
static HRESULT WINAPI TransformFilter_InputPin_BeginFlush(IPin * iface)
{
TransformFilter *pTransform = impl_from_sink_IPin(iface);
@@ -483,8 +469,8 @@ static const IPinVtbl TransformFilter_InputPin_Vtbl =
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseInputPinImpl_Connect,
- TransformFilter_InputPin_ReceiveConnection,
- TransformFilter_InputPin_Disconnect,
+ BaseInputPinImpl_ReceiveConnection,
+ BaseInputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
--
2.24.0
Dec. 10, 2019
[PATCH v2 3/5] strmbase: Add callbacks for sink (dis)connection.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avico.c | 4 +--
dlls/qcap/avimux.c | 4 +--
dlls/qcap/smartteefilter.c | 2 +-
dlls/strmbase/pin.c | 56 +++++++++++++++++++++-----------------
include/wine/strmbase.h | 9 +++---
5 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c
index debe6bca386..f822d4e4616 100644
--- a/dlls/qcap/avico.c
+++ b/dlls/qcap/avico.c
@@ -291,7 +291,7 @@ static HRESULT WINAPI AVICompressorIn_ReceiveConnection(IPin *iface,
hres = fill_format_info(This, (VIDEOINFOHEADER*)pmt->pbFormat);
if(FAILED(hres))
- BasePinImpl_Disconnect(iface);
+ BaseInputPinImpl_Disconnect(iface);
return hres;
}
@@ -302,7 +302,7 @@ static HRESULT WINAPI AVICompressorIn_Disconnect(IPin *iface)
TRACE("(%p)\n", This);
- hres = BasePinImpl_Disconnect(iface);
+ hres = BaseInputPinImpl_Disconnect(iface);
if(FAILED(hres))
return hres;
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index c344ab47266..63e98e8877b 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1469,7 +1469,7 @@ static HRESULT WINAPI AviMuxIn_ReceiveConnection(IPin *iface,
if(SUCCEEDED(hr))
hr = IMemAllocator_Commit(avimuxin->samples_allocator);
if(FAILED(hr)) {
- BasePinImpl_Disconnect(iface);
+ BaseInputPinImpl_Disconnect(iface);
return hr;
}
@@ -1497,7 +1497,7 @@ static HRESULT WINAPI AviMuxIn_Disconnect(IPin *iface)
TRACE("pin %p.\n", avimuxin);
- hr = BasePinImpl_Disconnect(iface);
+ hr = BaseInputPinImpl_Disconnect(iface);
if(FAILED(hr))
return hr;
diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c
index 929929632f1..e1fcea55f91 100644
--- a/dlls/qcap/smartteefilter.c
+++ b/dlls/qcap/smartteefilter.c
@@ -87,7 +87,7 @@ static const IPinVtbl SmartTeeFilterInputVtbl = {
BasePinImpl_Release,
BaseInputPinImpl_Connect,
BaseInputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
+ BaseInputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c
index bcac22eb3c4..5255a6c7b0b 100644
--- a/dlls/strmbase/pin.c
+++ b/dlls/strmbase/pin.c
@@ -119,31 +119,6 @@ ULONG WINAPI BasePinImpl_Release(IPin *iface)
return IBaseFilter_Release(&pin->filter->IBaseFilter_iface);
}
-HRESULT WINAPI BasePinImpl_Disconnect(IPin * iface)
-{
- struct strmbase_pin *This = impl_from_IPin(iface);
- HRESULT hr;
-
- TRACE("(%p)->()\n", This);
-
- EnterCriticalSection(&This->filter->csFilter);
- {
- if (This->peer)
- {
- IPin_Release(This->peer);
- This->peer = NULL;
- FreeMediaType(&This->mt);
- ZeroMemory(&This->mt, sizeof(This->mt));
- hr = S_OK;
- }
- else
- hr = S_FALSE;
- }
- LeaveCriticalSection(&This->filter->csFilter);
-
- return hr;
-}
-
HRESULT WINAPI BasePinImpl_ConnectedTo(IPin * iface, IPin ** ppPin)
{
struct strmbase_pin *This = impl_from_IPin(iface);
@@ -685,6 +660,9 @@ HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceiveP
}
}
+ if (SUCCEEDED(hr) && This->pFuncsTable->sink_connect)
+ hr = This->pFuncsTable->sink_connect(This, pReceivePin, pmt);
+
if (SUCCEEDED(hr))
{
CopyMediaType(&This->pin.mt, pmt);
@@ -697,6 +675,34 @@ HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceiveP
return hr;
}
+HRESULT WINAPI BaseInputPinImpl_Disconnect(IPin *iface)
+{
+ struct strmbase_sink *pin = impl_sink_from_IPin(iface);
+ HRESULT hr;
+
+ TRACE("pin %p.\n", pin);
+
+ EnterCriticalSection(&pin->pin.filter->csFilter);
+
+ if (pin->pin.peer)
+ {
+ if (pin->pFuncsTable->sink_disconnect)
+ pin->pFuncsTable->sink_disconnect(pin);
+
+ IPin_Release(pin->pin.peer);
+ pin->pin.peer = NULL;
+ FreeMediaType(&pin->pin.mt);
+ memset(&pin->pin.mt, 0, sizeof(AM_MEDIA_TYPE));
+ hr = S_OK;
+ }
+ else
+ hr = S_FALSE;
+
+ LeaveCriticalSection(&pin->pin.filter->csFilter);
+
+ return hr;
+}
+
static HRESULT deliver_endofstream(IPin* pin, LPVOID unused)
{
return IPin_EndOfStream( pin );
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 461214cf082..83ad2e0bd6e 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -91,9 +91,10 @@ typedef HRESULT (WINAPI *BaseInputPin_Receive)(struct strmbase_sink *This, IMedi
struct strmbase_sink_ops
{
- BasePinFuncTable base;
- /* Optional */
- BaseInputPin_Receive pfnReceive;
+ BasePinFuncTable base;
+ BaseInputPin_Receive pfnReceive;
+ HRESULT (*sink_connect)(struct strmbase_sink *pin, IPin *peer, const AM_MEDIA_TYPE *mt);
+ void (*sink_disconnect)(struct strmbase_sink *pin);
};
/* Base Pin */
@@ -102,7 +103,7 @@ LONG WINAPI BasePinImpl_GetMediaTypeVersion(struct strmbase_pin *pin);
HRESULT WINAPI BasePinImpl_QueryInterface(IPin *iface, REFIID iid, void **out);
ULONG WINAPI BasePinImpl_AddRef(IPin *iface);
ULONG WINAPI BasePinImpl_Release(IPin *iface);
-HRESULT WINAPI BasePinImpl_Disconnect(IPin * iface);
+HRESULT WINAPI BaseInputPinImpl_Disconnect(IPin * iface);
HRESULT WINAPI BasePinImpl_ConnectedTo(IPin * iface, IPin ** ppPin);
HRESULT WINAPI BasePinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt);
HRESULT WINAPI BasePinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo);
--
2.24.0
Dec. 10, 2019
[PATCH v2 2/5] strmbase: Pass an AM_MEDIA_TYPE pointer to CompleteConnect().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/dsoundrender.c | 13 +++-----
dlls/quartz/vmr9.c | 65 +++++++++++++++++++-------------------
dlls/strmbase/renderer.c | 4 +--
include/wine/strmbase.h | 3 +-
4 files changed, 39 insertions(+), 46 deletions(-)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c
index ca1e60de61d..b21ba40cb51 100644
--- a/dlls/quartz/dsoundrender.c
+++ b/dlls/quartz/dsoundrender.c
@@ -397,18 +397,13 @@ static void dsound_render_start_stream(struct strmbase_renderer *iface)
}
}
-static HRESULT WINAPI DSoundRender_CompleteConnect(struct strmbase_renderer *iface, IPin *pReceivePin)
+static HRESULT dsound_render_connect(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt)
{
DSoundRenderImpl *This = impl_from_strmbase_renderer(iface);
- const AM_MEDIA_TYPE *pmt = &This->renderer.sink.pin.mt;
+ const WAVEFORMATEX *format = (WAVEFORMATEX *)mt->pbFormat;
HRESULT hr = S_OK;
- WAVEFORMATEX *format;
DSBUFFERDESC buf_desc;
- TRACE("(%p)->(%p)\n", This, pReceivePin);
-
- format = (WAVEFORMATEX*)pmt->pbFormat;
-
This->buf_size = format->nAvgBytesPerSec;
memset(&buf_desc,0,sizeof(DSBUFFERDESC));
@@ -417,7 +412,7 @@ static HRESULT WINAPI DSoundRender_CompleteConnect(struct strmbase_renderer *ifa
DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS |
DSBCAPS_GETCURRENTPOSITION2;
buf_desc.dwBufferBytes = This->buf_size;
- buf_desc.lpwfxFormat = format;
+ buf_desc.lpwfxFormat = (WAVEFORMATEX *)format;
hr = IDirectSound8_CreateSoundBuffer(This->dsound, &buf_desc, &This->dsbuffer, NULL);
This->writepos = This->buf_size;
if (FAILED(hr))
@@ -523,7 +518,7 @@ static const struct strmbase_renderer_ops renderer_ops =
.renderer_stop_stream = dsound_render_stop_stream,
.pfnShouldDrawSampleNow = DSoundRender_ShouldDrawSampleNow,
.pfnPrepareReceive = DSoundRender_PrepareReceive,
- .pfnCompleteConnect = DSoundRender_CompleteConnect,
+ .renderer_connect = dsound_render_connect,
.pfnBreakConnect = DSoundRender_BreakConnect,
.pfnEndOfStream = DSoundRender_EndOfStream,
.pfnEndFlush = DSoundRender_EndFlush,
diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c
index 60c19e00191..a9b90b322dd 100644
--- a/dlls/quartz/vmr9.c
+++ b/dlls/quartz/vmr9.c
@@ -331,38 +331,20 @@ static HRESULT WINAPI VMR9_DoRenderSample(struct strmbase_renderer *iface, IMedi
return hr;
}
-static HRESULT WINAPI VMR9_CheckMediaType(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *pmt)
+static HRESULT WINAPI VMR9_CheckMediaType(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt)
{
- struct quartz_vmr *This = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
+ const VIDEOINFOHEADER *vih;
- if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat)
+ if (!IsEqualIID(&mt->majortype, &MEDIATYPE_Video) || !mt->pbFormat)
return S_FALSE;
- /* Ignore subtype, test for bicompression instead */
- if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
- {
- VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
+ if (!IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo)
+ && !IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo2))
+ return S_FALSE;
- This->bmiheader = format->bmiHeader;
- This->VideoWidth = format->bmiHeader.biWidth;
- This->VideoHeight = format->bmiHeader.biHeight;
- SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight);
- }
- else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
- {
- VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat;
+ vih = (VIDEOINFOHEADER *)mt->pbFormat;
- This->bmiheader = format->bmiHeader;
- This->VideoWidth = format->bmiHeader.biWidth;
- This->VideoHeight = format->bmiHeader.biHeight;
- SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight);
- }
- else
- {
- ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
- return S_FALSE;
- }
- if (This->bmiheader.biCompression != BI_RGB)
+ if (vih->bmiHeader.biCompression != BI_RGB)
return S_FALSE;
return S_OK;
}
@@ -461,16 +443,33 @@ static HRESULT WINAPI VMR9_ShouldDrawSampleNow(struct strmbase_renderer *iface,
return S_FALSE;
}
-static HRESULT WINAPI VMR9_CompleteConnect(struct strmbase_renderer *This, IPin *pReceivePin)
+static HRESULT vmr_connect(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt)
{
- struct quartz_vmr *pVMR9 = impl_from_IBaseFilter(&This->filter.IBaseFilter_iface);
+ struct quartz_vmr *filter = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
HRESULT hr;
- TRACE("(%p)\n", This);
+ if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
+ {
+ VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)mt->pbFormat;
+
+ filter->bmiheader = format->bmiHeader;
+ filter->VideoWidth = format->bmiHeader.biWidth;
+ filter->VideoHeight = format->bmiHeader.biHeight;
+ SetRect(&filter->source_rect, 0, 0, filter->VideoWidth, filter->VideoHeight);
+ }
+ else if (IsEqualIID(&mt->formattype, &FORMAT_VideoInfo2))
+ {
+ VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)mt->pbFormat;
+
+ filter->bmiheader = format->bmiHeader;
+ filter->VideoWidth = format->bmiHeader.biWidth;
+ filter->VideoHeight = format->bmiHeader.biHeight;
+ SetRect(&filter->source_rect, 0, 0, filter->VideoWidth, filter->VideoHeight);
+ }
- if (pVMR9->mode ||
- SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&pVMR9->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
- hr = VMR9_maybe_init(pVMR9, FALSE);
+ if (filter->mode
+ || SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&filter->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
+ hr = VMR9_maybe_init(filter, FALSE);
return hr;
}
@@ -576,7 +575,7 @@ static const struct strmbase_renderer_ops renderer_ops =
.renderer_start_stream = vmr_start_stream,
.renderer_stop_stream = vmr_stop_stream,
.pfnShouldDrawSampleNow = VMR9_ShouldDrawSampleNow,
- .pfnCompleteConnect = VMR9_CompleteConnect,
+ .renderer_connect = vmr_connect,
.pfnBreakConnect = VMR9_BreakConnect,
.renderer_destroy = vmr_destroy,
.renderer_query_interface = vmr_query_interface,
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index d592ab034e6..cedcd9a62a0 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -52,8 +52,8 @@ static HRESULT WINAPI BaseRenderer_InputPin_ReceiveConnection(IPin *iface, IPin
hr = BaseInputPinImpl_ReceiveConnection(iface, peer, mt);
if (SUCCEEDED(hr))
{
- if (filter->pFuncsTable->pfnCompleteConnect)
- hr = filter->pFuncsTable->pfnCompleteConnect(filter, peer);
+ if (filter->pFuncsTable->renderer_connect)
+ hr = filter->pFuncsTable->renderer_connect(filter, mt);
}
LeaveCriticalSection(&filter->filter.csFilter);
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 7e3b38b49d5..461214cf082 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -523,7 +523,6 @@ typedef HRESULT (WINAPI *BaseRenderer_EndOfStream)(struct strmbase_renderer *ifa
typedef HRESULT (WINAPI *BaseRenderer_BeginFlush) (struct strmbase_renderer *iface);
typedef HRESULT (WINAPI *BaseRenderer_EndFlush) (struct strmbase_renderer *iface);
typedef HRESULT (WINAPI *BaseRenderer_BreakConnect) (struct strmbase_renderer *iface);
-typedef HRESULT (WINAPI *BaseRenderer_CompleteConnect) (struct strmbase_renderer *iface, IPin *peer);
struct strmbase_renderer_ops
{
@@ -534,7 +533,7 @@ struct strmbase_renderer_ops
void (*renderer_stop_stream)(struct strmbase_renderer *iface);
BaseRenderer_ShouldDrawSampleNow pfnShouldDrawSampleNow;
BaseRenderer_PrepareReceive pfnPrepareReceive;
- BaseRenderer_CompleteConnect pfnCompleteConnect;
+ HRESULT (*renderer_connect)(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt);
BaseRenderer_BreakConnect pfnBreakConnect;
BaseRenderer_EndOfStream pfnEndOfStream;
BaseRenderer_EndFlush pfnEndFlush;
--
2.24.0
Dec. 10, 2019
[PATCH v2 1/5] strmbase: Combine the SetMediaType() and CompleteConnect() callbacks.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/acmwrapper.c | 115 +++++++-----------------
dlls/quartz/avidec.c | 37 ++------
dlls/strmbase/transform.c | 7 +-
dlls/winegstreamer/gsttffilter.c | 146 +++++++++++--------------------
dlls/wineqtdecoder/qtvdecoder.c | 25 ++----
include/wine/strmbase.h | 5 +-
6 files changed, 103 insertions(+), 232 deletions(-)
diff --git a/dlls/quartz/acmwrapper.c b/dlls/quartz/acmwrapper.c
index 8eea6ab147d..33d9debe5cd 100644
--- a/dlls/quartz/acmwrapper.c
+++ b/dlls/quartz/acmwrapper.c
@@ -40,7 +40,6 @@ typedef struct ACMWrapperImpl
TransformFilter tf;
HACMSTREAM has;
- LPWAVEFORMATEX pWfIn;
LPWAVEFORMATEX pWfOut;
LONGLONG lasttime_real;
@@ -224,85 +223,43 @@ error:
return hr;
}
-static HRESULT WINAPI ACMWrapper_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
+static BOOL is_audio_subtype(const GUID *guid)
{
- ACMWrapperImpl* This = impl_from_TransformFilter(tf);
- MMRESULT res;
-
- TRACE("(%p)->(%i %p)\n", This, dir, pmt);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
- /* Check root (GUID w/o FOURCC) */
- if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio)) &&
- (!memcmp(((const char *)&pmt->subtype)+4, ((const char *)&MEDIATYPE_Audio)+4, sizeof(GUID)-4)) &&
- (IsEqualIID(&pmt->formattype, &FORMAT_WaveFormatEx)))
- {
- HACMSTREAM drv;
- WAVEFORMATEX *wfx = (WAVEFORMATEX*)pmt->pbFormat;
- AM_MEDIA_TYPE* outpmt = &This->tf.pmt;
-
- if (!wfx || wfx->wFormatTag == WAVE_FORMAT_PCM || wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
- return VFW_E_TYPE_NOT_ACCEPTED;
- FreeMediaType(outpmt);
-
- This->pWfIn = (LPWAVEFORMATEX)pmt->pbFormat;
-
- /* HACK */
- /* TRACE("ALIGN = %d\n", pACMWrapper->pWfIn->nBlockAlign); */
- /* pACMWrapper->pWfIn->nBlockAlign = 1; */
-
- /* Set output audio data to PCM */
- CopyMediaType(outpmt, pmt);
- outpmt->subtype.Data1 = WAVE_FORMAT_PCM;
- This->pWfOut = (WAVEFORMATEX*)outpmt->pbFormat;
- This->pWfOut->wFormatTag = WAVE_FORMAT_PCM;
- This->pWfOut->wBitsPerSample = 16;
- This->pWfOut->nBlockAlign = This->pWfOut->wBitsPerSample * This->pWfOut->nChannels / 8;
- This->pWfOut->cbSize = 0;
- This->pWfOut->nAvgBytesPerSec = This->pWfOut->nChannels * This->pWfOut->nSamplesPerSec
- * (This->pWfOut->wBitsPerSample/8);
-
- if (!(res = acmStreamOpen(&drv, NULL, This->pWfIn, This->pWfOut, NULL, 0, 0, 0)))
- {
- This->has = drv;
-
- TRACE("Connection accepted\n");
- return S_OK;
- }
- else
- FIXME("acmStreamOpen returned %d\n", res);
- FreeMediaType(outpmt);
- TRACE("Unable to find a suitable ACM decompressor\n");
- }
-
- TRACE("Connection refused\n");
- return VFW_E_TYPE_NOT_ACCEPTED;
+ return !memcmp(&guid->Data2, &MEDIATYPE_Audio.Data2, sizeof(GUID) - sizeof(int));
}
-static HRESULT WINAPI ACMWrapper_CompleteConnect(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
+static HRESULT acm_wrapper_connect_sink(TransformFilter *iface, const AM_MEDIA_TYPE *mt)
{
- ACMWrapperImpl* This = impl_from_TransformFilter(tf);
- MMRESULT res;
+ ACMWrapperImpl *filter = impl_from_TransformFilter(iface);
+ const WAVEFORMATEX *wfx = (WAVEFORMATEX *)mt->pbFormat;
HACMSTREAM drv;
+ MMRESULT res;
- TRACE("(%p)\n", This);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
- if (!(res = acmStreamOpen(&drv, NULL, This->pWfIn, This->pWfOut, NULL, 0, 0, 0)))
+ if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio) || !is_audio_subtype(&mt->subtype)
+ || !IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx) || !wfx
+ || wfx->wFormatTag == WAVE_FORMAT_PCM || wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ CopyMediaType(&filter->tf.pmt, mt);
+ filter->tf.pmt.subtype.Data1 = WAVE_FORMAT_PCM;
+ filter->pWfOut = (WAVEFORMATEX *)filter->tf.pmt.pbFormat;
+ filter->pWfOut->wFormatTag = WAVE_FORMAT_PCM;
+ filter->pWfOut->wBitsPerSample = 16;
+ filter->pWfOut->nBlockAlign = filter->pWfOut->wBitsPerSample * filter->pWfOut->nChannels / 8;
+ filter->pWfOut->cbSize = 0;
+ filter->pWfOut->nAvgBytesPerSec = filter->pWfOut->nChannels * filter->pWfOut->nSamplesPerSec
+ * (filter->pWfOut->wBitsPerSample / 8);
+
+ if ((res = acmStreamOpen(&drv, NULL, (WAVEFORMATEX *)wfx, filter->pWfOut, NULL, 0, 0, 0)))
{
- This->has = drv;
-
- TRACE("Connection accepted\n");
- return S_OK;
+ ERR("Failed to open stream, error %u.\n", res);
+ FreeMediaType(&filter->tf.pmt);
+ return VFW_E_TYPE_NOT_ACCEPTED;
}
- FIXME("acmStreamOpen returned %d\n", res);
- TRACE("Unable to find a suitable ACM decompressor\n");
- return VFW_E_TYPE_NOT_ACCEPTED;
+ filter->has = drv;
+
+ return S_OK;
}
static HRESULT WINAPI ACMWrapper_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir)
@@ -341,18 +298,10 @@ static HRESULT WINAPI ACMWrapper_DecideBufferSize(TransformFilter *tf, IMemAlloc
}
static const TransformFilterFuncTable ACMWrapper_FuncsTable = {
- ACMWrapper_DecideBufferSize,
- NULL,
- ACMWrapper_Receive,
- NULL,
- NULL,
- ACMWrapper_SetMediaType,
- ACMWrapper_CompleteConnect,
- ACMWrapper_BreakConnect,
- NULL,
- NULL,
- NULL,
- NULL
+ .pfnDecideBufferSize = ACMWrapper_DecideBufferSize,
+ .pfnReceive = ACMWrapper_Receive,
+ .transform_connect_sink = acm_wrapper_connect_sink,
+ .pfnBreakConnect = ACMWrapper_BreakConnect,
};
HRESULT ACMWrapper_create(IUnknown *outer, void **out)
diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c
index 32969a34730..abed957fa6d 100644
--- a/dlls/quartz/avidec.c
+++ b/dlls/quartz/avidec.c
@@ -210,16 +210,11 @@ static HRESULT WINAPI AVIDec_StopStreaming(TransformFilter* pTransformFilter)
return S_OK;
}
-static HRESULT WINAPI AVIDec_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
+static HRESULT avi_dec_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *pmt)
{
AVIDecImpl* This = impl_from_TransformFilter(tf);
HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
- TRACE("(%p)->(%p)\n", This, pmt);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
/* Check root (GUID w/o FOURCC) */
if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) &&
(!memcmp(((const char *)&pmt->subtype)+4, ((const char *)&MEDIATYPE_Video)+4, sizeof(GUID)-4)))
@@ -310,15 +305,6 @@ failed:
return hr;
}
-static HRESULT WINAPI AVIDec_CompleteConnect(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- AVIDecImpl* This = impl_from_TransformFilter(tf);
-
- TRACE("(%p)\n", This);
-
- return S_OK;
-}
-
static HRESULT WINAPI AVIDec_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir)
{
AVIDecImpl *This = impl_from_TransformFilter(tf);
@@ -357,19 +343,14 @@ static HRESULT WINAPI AVIDec_DecideBufferSize(TransformFilter *tf, IMemAllocator
}
static const TransformFilterFuncTable AVIDec_FuncsTable = {
- AVIDec_DecideBufferSize,
- AVIDec_StartStreaming,
- AVIDec_Receive,
- AVIDec_StopStreaming,
- NULL,
- AVIDec_SetMediaType,
- AVIDec_CompleteConnect,
- AVIDec_BreakConnect,
- NULL,
- NULL,
- AVIDec_EndFlush,
- NULL,
- AVIDec_NotifyDrop
+ .pfnDecideBufferSize = AVIDec_DecideBufferSize,
+ .pfnStartStreaming = AVIDec_StartStreaming,
+ .pfnReceive = AVIDec_Receive,
+ .pfnStopStreaming = AVIDec_StopStreaming,
+ .transform_connect_sink = avi_dec_connect_sink,
+ .pfnBreakConnect = AVIDec_BreakConnect,
+ .pfnEndFlush = AVIDec_EndFlush,
+ .pfnNotify = AVIDec_NotifyDrop,
};
HRESULT AVIDec_create(IUnknown *outer, void **out)
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 7a79f709055..30ed0006cb1 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -405,11 +405,8 @@ static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, I
TRACE("(%p)->(%p, %p)\n", iface, pReceivePin, pmt);
strmbase_dump_media_type(pmt);
- if (pTransform->pFuncsTable->pfnSetMediaType)
- hr = pTransform->pFuncsTable->pfnSetMediaType(pTransform, PINDIR_INPUT, pmt);
-
- if (SUCCEEDED(hr) && pTransform->pFuncsTable->pfnCompleteConnect)
- hr = pTransform->pFuncsTable->pfnCompleteConnect(pTransform, PINDIR_INPUT, pReceivePin);
+ if (pTransform->pFuncsTable->transform_connect_sink)
+ hr = pTransform->pFuncsTable->transform_connect_sink(pTransform, pmt);
if (SUCCEEDED(hr))
{
diff --git a/dlls/winegstreamer/gsttffilter.c b/dlls/winegstreamer/gsttffilter.c
index ee1851dfdc6..d44a6ae33a6 100644
--- a/dlls/winegstreamer/gsttffilter.c
+++ b/dlls/winegstreamer/gsttffilter.c
@@ -516,7 +516,7 @@ static HRESULT WINAPI Gstreamer_Mp3_QueryConnect(TransformFilter *iface, const A
return S_OK;
}
-static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT mp3_decoder_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -525,13 +525,8 @@ static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECT
HRESULT hr;
int layer;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_Mp3_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return VFW_E_TYPE_NOT_ACCEPTED;
@@ -588,26 +583,19 @@ static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECT
return hr;
}
-static HRESULT WINAPI Gstreamer_Mp3_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- TRACE("%p 0x%x %p\n", tf, dir, pin);
- return S_OK;
-}
-
static const TransformFilterFuncTable Gstreamer_Mp3_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_Mp3_QueryConnect,
- Gstreamer_Mp3_SetMediaType,
- Gstreamer_Mp3_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_Mp3_QueryConnect,
+ .transform_connect_sink = mp3_decoder_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *punkouter, HRESULT *phr)
@@ -664,13 +652,7 @@ static HRESULT WINAPI Gstreamer_YUV_QueryConnect(TransformFilter *iface, const A
}
}
-static HRESULT WINAPI Gstreamer_YUV_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- TRACE("%p 0x%x %p\n", tf, dir, pin);
- return S_OK;
-}
-
-static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT yuv_to_rgb_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -679,13 +661,8 @@ static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DI
int avgtime;
LONG width, height;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@@ -738,19 +715,18 @@ static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DI
}
static const TransformFilterFuncTable Gstreamer_YUV2RGB_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_YUV_QueryConnect,
- Gstreamer_YUV2RGB_SetMediaType,
- Gstreamer_YUV_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_YUV_QueryConnect,
+ .transform_connect_sink = yuv_to_rgb_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *punkouter, HRESULT *phr)
@@ -772,7 +748,7 @@ IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *punkouter, HRESULT *phr)
return obj;
}
-static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT yuv_to_argb_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -781,13 +757,8 @@ static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_D
int avgtime;
LONG width, height;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@@ -840,19 +811,18 @@ static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_D
}
static const TransformFilterFuncTable Gstreamer_YUV2ARGB_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_YUV_QueryConnect,
- Gstreamer_YUV2ARGB_SetMediaType,
- Gstreamer_YUV_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_YUV_QueryConnect,
+ .transform_connect_sink = yuv_to_argb_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_YUV2ARGB_create(IUnknown *punkouter, HRESULT *phr)
@@ -886,13 +856,7 @@ static HRESULT WINAPI Gstreamer_AudioConvert_QueryConnect(TransformFilter *iface
return S_OK;
}
-static HRESULT WINAPI Gstreamer_AudioConvert_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- TRACE("%p 0x%x %p\n", tf, dir, pin);
- return S_OK;
-}
-
-static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT audio_converter_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -905,13 +869,8 @@ static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, P
BOOL inisfloat = FALSE;
int indepth;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_AudioConvert_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@@ -972,19 +931,18 @@ static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, P
}
static const TransformFilterFuncTable Gstreamer_AudioConvert_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_AudioConvert_QueryConnect,
- Gstreamer_AudioConvert_SetMediaType,
- Gstreamer_AudioConvert_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_AudioConvert_QueryConnect,
+ .transform_connect_sink = audio_converter_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_AudioConvert_create(IUnknown *punkouter, HRESULT *phr)
diff --git a/dlls/wineqtdecoder/qtvdecoder.c b/dlls/wineqtdecoder/qtvdecoder.c
index 3da0738aecb..4be654e5a10 100644
--- a/dlls/wineqtdecoder/qtvdecoder.c
+++ b/dlls/wineqtdecoder/qtvdecoder.c
@@ -336,7 +336,7 @@ static HRESULT WINAPI QTVDecoder_StopStreaming(TransformFilter* pTransformFilter
return S_OK;
}
-static HRESULT WINAPI QTVDecoder_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
+static HRESULT video_decoder_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *pmt)
{
QTVDecoderImpl* This = impl_from_TransformFilter(tf);
HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
@@ -344,11 +344,6 @@ static HRESULT WINAPI QTVDecoder_SetMediaType(TransformFilter *tf, PIN_DIRECTION
AM_MEDIA_TYPE *outpmt = &This->tf.pmt;
CFNumberRef n = NULL;
- TRACE("(%p)->(%p)\n", This, pmt);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
FreeMediaType(outpmt);
CopyMediaType(outpmt, pmt);
@@ -502,18 +497,12 @@ static HRESULT WINAPI QTVDecoder_DecideBufferSize(TransformFilter *tf, IMemAlloc
}
static const TransformFilterFuncTable QTVDecoder_FuncsTable = {
- QTVDecoder_DecideBufferSize,
- QTVDecoder_StartStreaming,
- QTVDecoder_Receive,
- QTVDecoder_StopStreaming,
- NULL,
- QTVDecoder_SetMediaType,
- NULL,
- QTVDecoder_BreakConnect,
- NULL,
- NULL,
- NULL,
- NULL
+ .pfnDecideBufferSize = QTVDecoder_DecideBufferSize,
+ .pfnStartStreaming = QTVDecoder_StartStreaming,
+ .pfnReceive = QTVDecoder_Receive,
+ .pfnStopStreaming = QTVDecoder_StopStreaming,
+ .transform_connect_sink = video_decoder_connect_sink,
+ .pfnBreakConnect = QTVDecoder_BreakConnect,
};
IUnknown * CALLBACK QTVDecoder_create(IUnknown *outer, HRESULT* phr)
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index c3699f19253..7e3b38b49d5 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -197,9 +197,7 @@ typedef HRESULT (WINAPI *TransformFilter_DecideBufferSize) (TransformFilter *ifa
typedef HRESULT (WINAPI *TransformFilter_StartStreaming) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_StopStreaming) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_Receive) (TransformFilter* iface, IMediaSample* pIn);
-typedef HRESULT (WINAPI *TransformFilter_CompleteConnect) (TransformFilter *iface, PIN_DIRECTION dir, IPin *pPin);
typedef HRESULT (WINAPI *TransformFilter_BreakConnect) (TransformFilter *iface, PIN_DIRECTION dir);
-typedef HRESULT (WINAPI *TransformFilter_SetMediaType) (TransformFilter *iface, PIN_DIRECTION dir, const AM_MEDIA_TYPE *pMediaType);
typedef HRESULT (WINAPI *TransformFilter_CheckInputType) (TransformFilter *iface, const AM_MEDIA_TYPE *pMediaType);
typedef HRESULT (WINAPI *TransformFilter_EndOfStream) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_BeginFlush) (TransformFilter *iface);
@@ -216,8 +214,7 @@ typedef struct TransformFilterFuncTable {
TransformFilter_Receive pfnReceive;
TransformFilter_StopStreaming pfnStopStreaming;
TransformFilter_CheckInputType pfnCheckInputType;
- TransformFilter_SetMediaType pfnSetMediaType;
- TransformFilter_CompleteConnect pfnCompleteConnect;
+ HRESULT (*transform_connect_sink)(TransformFilter *filter, const AM_MEDIA_TYPE *mt);
TransformFilter_BreakConnect pfnBreakConnect;
TransformFilter_EndOfStream pfnEndOfStream;
TransformFilter_BeginFlush pfnBeginFlush;
--
2.24.0
Dec. 10, 2019
Re: [PATCH 5/5] strmbase/renderer: Use base sink connection methods.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61744
Your paranoid android.
=== debian10 (build log) ===
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The win32 build failed
=== debian10 (build log) ===
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The wow64 build failed
Dec. 10, 2019
Re: [PATCH 4/5] strmbase/transform: Use base sink connection methods.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61743
Your paranoid android.
=== debian10 (build log) ===
/home/winetest/tools/testbot/var/wine-win32/dlls/strmbase/../../../wine/dlls/strmbase/renderer.c:71: undefined reference to `BasePinImpl_Disconnect'
collect2: error: ld returned 1 exit status
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The win32 build failed
=== debian10 (build log) ===
/home/winetest/tools/testbot/var/wine-wow64/dlls/strmbase/../../../wine/dlls/strmbase/renderer.c:71: undefined reference to `BasePinImpl_Disconnect'
collect2: error: ld returned 1 exit status
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The wow64 build failed
Dec. 10, 2019
Re: [PATCH 3/5] strmbase: Add callbacks for sink (dis)connection.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61742
Your paranoid android.
=== debian10 (build log) ===
/home/winetest/tools/testbot/var/wine-win32/dlls/strmbase/../../../wine/dlls/strmbase/renderer.c:71: undefined reference to `BasePinImpl_Disconnect'
collect2: error: ld returned 1 exit status
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The win32 build failed
=== debian10 (build log) ===
/home/winetest/tools/testbot/var/wine-wow64/dlls/strmbase/../../../wine/dlls/strmbase/renderer.c:71: undefined reference to `BasePinImpl_Disconnect'
collect2: error: ld returned 1 exit status
../../../wine/dlls/qedit/samplegrabber.c:526:5: error: ‘BasePinImpl_Disconnect’ undeclared here (not in a function); did you mean ‘BaseInputPinImpl_Disconnect’?
Task: The wow64 build failed
Dec. 10, 2019
Re: [PATCH 2/5] strmbase: Pass an AM_MEDIA_TYPE pointer to CompleteConnect().
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61741
Your paranoid android.
=== debian10 (32 bit report) ===
quartz:
vmr7.c:724: Test failed: Got hr 0x1 for subtype {00000000-0000-0000-0000-000000000000}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr7.c:729: Test succeeded inside todo block: Got hr 0x1.
vmr7.c:1300: Test succeeded inside todo block: Got hr 0x8004022a.
vmr7.c:1317: Test failed: Got hr 0x8004022a.
vmr7.c:1319: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb8b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1345: Test succeeded inside todo block: Got hr 0x8004022a.
vmr7.c:1362: Test failed: Got hr 0x8004022a.
vmr7.c:1365: Test failed: Got hr 0x80040209.
vmr7.c:1366: Test failed: Got peer 00000000.
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0044b97d).
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr9.c:730: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:733: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1338: Test succeeded inside todo block: Got hr 0x8004022a.
vmr9.c:1346: Test succeeded inside todo block: Got hr 0x8004022a.
vmr9.c:1363: Test failed: Got hr 0x8004022a.
vmr9.c:1366: Test failed: Got hr 0x80040209.
vmr9.c:1367: Test failed: Got peer 00000000.
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004585bd).
Report errors:
quartz:vmr7 crashed (c0000005)
quartz:vmr9 crashed (c0000005)
=== debian10 (32 bit Chinese:China report) ===
quartz:
vmr7.c:724: Test failed: Got hr 0x1 for subtype {00000000-0000-0000-0000-000000000000}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr7.c:729: Test succeeded inside todo block: Got hr 0x1.
vmr7.c:1300: Test succeeded inside todo block: Got hr 0x8004022a.
vmr7.c:1317: Test failed: Got hr 0x8004022a.
vmr7.c:1319: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb8b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1345: Test succeeded inside todo block: Got hr 0x8004022a.
vmr7.c:1362: Test failed: Got hr 0x8004022a.
vmr7.c:1365: Test failed: Got hr 0x80040209.
vmr7.c:1366: Test failed: Got peer 00000000.
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0044b97d).
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr9.c:730: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:733: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1338: Test succeeded inside todo block: Got hr 0x8004022a.
vmr9.c:1346: Test succeeded inside todo block: Got hr 0x8004022a.
vmr9.c:1363: Test failed: Got hr 0x8004022a.
vmr9.c:1366: Test failed: Got hr 0x80040209.
vmr9.c:1367: Test failed: Got peer 00000000.
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004585bd).
Report errors:
quartz:vmr7 crashed (c0000005)
quartz:vmr9 crashed (c0000005)
=== debian10 (32 bit WoW report) ===
quartz:
vmr7.c:724: Test failed: Got hr 0x1 for subtype {00000000-0000-0000-0000-000000000000}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr7.c:729: Test succeeded inside todo block: Got hr 0x1.
vmr7.c:1300: Test succeeded inside todo block: Got hr 0x8004022a.
vmr7.c:1317: Test failed: Got hr 0x8004022a.
vmr7.c:1319: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb8b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1345: Test succeeded inside todo block: Got hr 0x8004022a.
vmr7.c:1362: Test failed: Got hr 0x8004022a.
vmr7.c:1365: Test failed: Got hr 0x80040209.
vmr7.c:1366: Test failed: Got peer 00000000.
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0044b97d).
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr9.c:730: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:733: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1338: Test succeeded inside todo block: Got hr 0x8004022a.
vmr9.c:1346: Test succeeded inside todo block: Got hr 0x8004022a.
vmr9.c:1363: Test failed: Got hr 0x8004022a.
vmr9.c:1366: Test failed: Got hr 0x80040209.
vmr9.c:1367: Test failed: Got peer 00000000.
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004585bd).
Report errors:
quartz:vmr7 crashed (c0000005)
quartz:vmr9 crashed (c0000005)
=== debian10 (64 bit WoW report) ===
quartz:
vmr7.c:724: Test failed: Got hr 0x1 for subtype {00000000-0000-0000-0000-000000000000}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr7.c:724: Test failed: Got hr 0x1 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr7.c:729: Test succeeded inside todo block: Got hr 0x1.
vmr7.c:1300: Test succeeded inside todo block: Got hr 0x8004022a.
vmr7.c:1317: Test failed: Got hr 0x8004022a.
vmr7.c:1319: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1327: Test failed: Got hr 0x8004022a for subtype {e436eb8b-524f-11ce-9f53-0020af0ba770}.
vmr7.c:1330: Test failed: Got hr 0x1.
vmr7.c:1345: Test succeeded inside todo block: Got hr 0x8004022a.
vmr7.c:1362: Test failed: Got hr 0x8004022a.
vmr7.c:1365: Test failed: Got hr 0x80040209.
vmr7.c:1366: Test failed: Got peer 00000000.
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x0044b97d).
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770}.
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770}.
vmr9.c:725: Test failed: Got hr 0x1 for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770}.
vmr9.c:730: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:733: Test succeeded inside todo block: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7c-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7b-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7d-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 15.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 16.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 24.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1318: Test failed: Got hr 0x8004022a for subtype {e436eb7e-524f-11ce-9f53-0020af0ba770} and bpp 32.
vmr9.c:1322: Test failed: Got hr 0x1.
vmr9.c:1338: Test succeeded inside todo block: Got hr 0x8004022a.
vmr9.c:1346: Test succeeded inside todo block: Got hr 0x8004022a.
vmr9.c:1363: Test failed: Got hr 0x8004022a.
vmr9.c:1366: Test failed: Got hr 0x80040209.
vmr9.c:1367: Test failed: Got peer 00000000.
Unhandled exception: page fault on read access to 0x00000000 in 32-bit code (0x004585bd).
Report errors:
quartz:vmr7 crashed (c0000005)
quartz:vmr9 crashed (c0000005)
Dec. 10, 2019
[PATCH 5/5] strmbase/renderer: Use base sink connection methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/vmr9.c | 8 +++--
dlls/strmbase/renderer.c | 63 ++++++++++++++--------------------------
2 files changed, 26 insertions(+), 45 deletions(-)
diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c
index 0177f7e36fa..bdba8f3a7e3 100644
--- a/dlls/quartz/vmr9.c
+++ b/dlls/quartz/vmr9.c
@@ -356,7 +356,7 @@ static HRESULT VMR9_maybe_init(struct quartz_vmr *This, BOOL force)
HRESULT hr;
TRACE("my mode: %u, my window: %p, my last window: %p\n", This->mode, This->baseControlWindow.baseWindow.hWnd, This->hWndClippingWindow);
- if (This->num_surfaces || !This->renderer.sink.pin.peer)
+ if (This->num_surfaces)
return S_OK;
if (This->mode == VMR9Mode_Windowless && !This->hWndClippingWindow)
@@ -410,7 +410,8 @@ static void vmr_start_stream(struct strmbase_renderer *iface)
TRACE("(%p)\n", This);
- VMR9_maybe_init(This, TRUE);
+ if (This->renderer.sink.pin.peer)
+ VMR9_maybe_init(This, TRUE);
IVMRImagePresenter9_StartPresenting(This->presenter, This->cookie);
SetWindowPos(This->baseControlWindow.baseWindow.hWnd, NULL,
This->source_rect.left,
@@ -1760,7 +1761,8 @@ static HRESULT WINAPI VMR9WindowlessControl_SetVideoClippingWindow(IVMRWindowles
EnterCriticalSection(&This->renderer.filter.csFilter);
This->hWndClippingWindow = hwnd;
- VMR9_maybe_init(This, FALSE);
+ if (This->renderer.sink.pin.peer)
+ VMR9_maybe_init(This, FALSE);
if (!hwnd)
IVMRSurfaceAllocatorEx9_TerminateDevice(This->allocator, This->cookie);
LeaveCriticalSection(&This->renderer.filter.csFilter);
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index cedcd9a62a0..7b9736ccfb2 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -40,46 +40,6 @@ static inline struct strmbase_renderer *impl_from_IPin(IPin *iface)
return CONTAINING_RECORD(iface, struct strmbase_renderer, sink.pin.IPin_iface);
}
-static HRESULT WINAPI BaseRenderer_InputPin_ReceiveConnection(IPin *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
-{
- struct strmbase_renderer *filter = impl_from_IPin(iface);
- HRESULT hr;
-
- TRACE("iface %p, peer %p, mt %p.\n", iface, peer, mt);
- strmbase_dump_media_type(mt);
-
- EnterCriticalSection(&filter->filter.csFilter);
- hr = BaseInputPinImpl_ReceiveConnection(iface, peer, mt);
- if (SUCCEEDED(hr))
- {
- if (filter->pFuncsTable->renderer_connect)
- hr = filter->pFuncsTable->renderer_connect(filter, mt);
- }
- LeaveCriticalSection(&filter->filter.csFilter);
-
- return hr;
-}
-
-static HRESULT WINAPI BaseRenderer_InputPin_Disconnect(IPin * iface)
-{
- struct strmbase_renderer *filter = impl_from_IPin(iface);
- HRESULT hr;
-
- TRACE("iface %p.\n", iface);
-
- EnterCriticalSection(&filter->filter.csFilter);
- hr = BasePinImpl_Disconnect(iface);
- if (SUCCEEDED(hr))
- {
- if (filter->pFuncsTable->pfnBreakConnect)
- hr = filter->pFuncsTable->pfnBreakConnect(filter);
- }
- BaseRendererImpl_ClearPendingSample(filter);
- LeaveCriticalSection(&filter->filter.csFilter);
-
- return hr;
-}
-
static HRESULT WINAPI BaseRenderer_InputPin_EndOfStream(IPin * iface)
{
struct strmbase_renderer *filter = impl_from_IPin(iface);
@@ -157,8 +117,8 @@ static const IPinVtbl BaseRenderer_InputPin_Vtbl =
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseInputPinImpl_Connect,
- BaseRenderer_InputPin_ReceiveConnection,
- BaseRenderer_InputPin_Disconnect,
+ BaseInputPinImpl_ReceiveConnection,
+ BaseInputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
@@ -312,12 +272,31 @@ static HRESULT WINAPI BaseRenderer_Receive(struct strmbase_sink *pin, IMediaSamp
return BaseRendererImpl_Receive(filter, sample);
}
+static HRESULT sink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
+{
+ struct strmbase_renderer *filter = impl_from_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->renderer_connect)
+ return filter->pFuncsTable->renderer_connect(filter, mt);
+ return S_OK;
+}
+
+static void sink_disconnect(struct strmbase_sink *iface)
+{
+ struct strmbase_renderer *filter = impl_from_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->pfnBreakConnect)
+ filter->pFuncsTable->pfnBreakConnect(filter);
+}
+
static const struct strmbase_sink_ops sink_ops =
{
.base.pin_query_accept = sink_query_accept,
.base.pin_query_interface = sink_query_interface,
.base.pin_get_media_type = strmbase_pin_get_media_type,
.pfnReceive = BaseRenderer_Receive,
+ .sink_connect = sink_connect,
+ .sink_disconnect = sink_disconnect,
};
void strmbase_renderer_cleanup(struct strmbase_renderer *filter)
--
2.24.0
Dec. 10, 2019
[PATCH 4/5] strmbase/transform: Use base sink connection methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/strmbase/transform.c | 56 +++++++++++++++------------------------
1 file changed, 21 insertions(+), 35 deletions(-)
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 30ed0006cb1..993e30202bc 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -212,12 +212,31 @@ static HRESULT sink_query_interface(struct strmbase_pin *iface, REFIID iid, void
return S_OK;
}
+static HRESULT sink_connect(struct strmbase_sink *iface, IPin *peer, const AM_MEDIA_TYPE *mt)
+{
+ TransformFilter *filter = impl_from_sink_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->transform_connect_sink)
+ return filter->pFuncsTable->transform_connect_sink(filter, mt);
+ return S_OK;
+}
+
+static void sink_disconnect(struct strmbase_sink *iface)
+{
+ TransformFilter *filter = impl_from_sink_IPin(&iface->pin.IPin_iface);
+
+ if (filter->pFuncsTable->pfnBreakConnect)
+ filter->pFuncsTable->pfnBreakConnect(filter, PINDIR_INPUT);
+}
+
static const struct strmbase_sink_ops sink_ops =
{
.base.pin_query_accept = sink_query_accept,
.base.pin_get_media_type = strmbase_pin_get_media_type,
.base.pin_query_interface = sink_query_interface,
.pfnReceive = TransformFilter_Input_Receive,
+ .sink_connect = sink_connect,
+ .sink_disconnect = sink_disconnect,
};
static HRESULT source_query_interface(struct strmbase_pin *iface, REFIID iid, void **out)
@@ -397,39 +416,6 @@ static HRESULT WINAPI TransformFilter_InputPin_EndOfStream(IPin * iface)
return VFW_E_NOT_CONNECTED;
}
-static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, IPin * pReceivePin, const AM_MEDIA_TYPE * pmt)
-{
- TransformFilter *pTransform = impl_from_sink_IPin(iface);
- HRESULT hr = S_OK;
-
- TRACE("(%p)->(%p, %p)\n", iface, pReceivePin, pmt);
- strmbase_dump_media_type(pmt);
-
- if (pTransform->pFuncsTable->transform_connect_sink)
- hr = pTransform->pFuncsTable->transform_connect_sink(pTransform, pmt);
-
- if (SUCCEEDED(hr))
- {
- hr = BaseInputPinImpl_ReceiveConnection(iface, pReceivePin, pmt);
- if (FAILED(hr) && pTransform->pFuncsTable->pfnBreakConnect)
- pTransform->pFuncsTable->pfnBreakConnect(pTransform, PINDIR_INPUT);
- }
-
- return hr;
-}
-
-static HRESULT WINAPI TransformFilter_InputPin_Disconnect(IPin * iface)
-{
- TransformFilter *pTransform = impl_from_sink_IPin(iface);
-
- TRACE("(%p)->()\n", iface);
-
- if (pTransform->pFuncsTable->pfnBreakConnect)
- pTransform->pFuncsTable->pfnBreakConnect(pTransform, PINDIR_INPUT);
-
- return BasePinImpl_Disconnect(iface);
-}
-
static HRESULT WINAPI TransformFilter_InputPin_BeginFlush(IPin * iface)
{
TransformFilter *pTransform = impl_from_sink_IPin(iface);
@@ -483,8 +469,8 @@ static const IPinVtbl TransformFilter_InputPin_Vtbl =
BasePinImpl_AddRef,
BasePinImpl_Release,
BaseInputPinImpl_Connect,
- TransformFilter_InputPin_ReceiveConnection,
- TransformFilter_InputPin_Disconnect,
+ BaseInputPinImpl_ReceiveConnection,
+ BaseInputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
--
2.24.0
Dec. 10, 2019
[PATCH 3/5] strmbase: Add callbacks for sink (dis)connection.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avico.c | 4 +--
dlls/qcap/avimux.c | 4 +--
dlls/qcap/smartteefilter.c | 2 +-
dlls/strmbase/pin.c | 56 +++++++++++++++++++++-----------------
include/wine/strmbase.h | 9 +++---
5 files changed, 41 insertions(+), 34 deletions(-)
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c
index debe6bca386..f822d4e4616 100644
--- a/dlls/qcap/avico.c
+++ b/dlls/qcap/avico.c
@@ -291,7 +291,7 @@ static HRESULT WINAPI AVICompressorIn_ReceiveConnection(IPin *iface,
hres = fill_format_info(This, (VIDEOINFOHEADER*)pmt->pbFormat);
if(FAILED(hres))
- BasePinImpl_Disconnect(iface);
+ BaseInputPinImpl_Disconnect(iface);
return hres;
}
@@ -302,7 +302,7 @@ static HRESULT WINAPI AVICompressorIn_Disconnect(IPin *iface)
TRACE("(%p)\n", This);
- hres = BasePinImpl_Disconnect(iface);
+ hres = BaseInputPinImpl_Disconnect(iface);
if(FAILED(hres))
return hres;
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index c344ab47266..63e98e8877b 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -1469,7 +1469,7 @@ static HRESULT WINAPI AviMuxIn_ReceiveConnection(IPin *iface,
if(SUCCEEDED(hr))
hr = IMemAllocator_Commit(avimuxin->samples_allocator);
if(FAILED(hr)) {
- BasePinImpl_Disconnect(iface);
+ BaseInputPinImpl_Disconnect(iface);
return hr;
}
@@ -1497,7 +1497,7 @@ static HRESULT WINAPI AviMuxIn_Disconnect(IPin *iface)
TRACE("pin %p.\n", avimuxin);
- hr = BasePinImpl_Disconnect(iface);
+ hr = BaseInputPinImpl_Disconnect(iface);
if(FAILED(hr))
return hr;
diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c
index 929929632f1..e1fcea55f91 100644
--- a/dlls/qcap/smartteefilter.c
+++ b/dlls/qcap/smartteefilter.c
@@ -87,7 +87,7 @@ static const IPinVtbl SmartTeeFilterInputVtbl = {
BasePinImpl_Release,
BaseInputPinImpl_Connect,
BaseInputPinImpl_ReceiveConnection,
- BasePinImpl_Disconnect,
+ BaseInputPinImpl_Disconnect,
BasePinImpl_ConnectedTo,
BasePinImpl_ConnectionMediaType,
BasePinImpl_QueryPinInfo,
diff --git a/dlls/strmbase/pin.c b/dlls/strmbase/pin.c
index bcac22eb3c4..5255a6c7b0b 100644
--- a/dlls/strmbase/pin.c
+++ b/dlls/strmbase/pin.c
@@ -119,31 +119,6 @@ ULONG WINAPI BasePinImpl_Release(IPin *iface)
return IBaseFilter_Release(&pin->filter->IBaseFilter_iface);
}
-HRESULT WINAPI BasePinImpl_Disconnect(IPin * iface)
-{
- struct strmbase_pin *This = impl_from_IPin(iface);
- HRESULT hr;
-
- TRACE("(%p)->()\n", This);
-
- EnterCriticalSection(&This->filter->csFilter);
- {
- if (This->peer)
- {
- IPin_Release(This->peer);
- This->peer = NULL;
- FreeMediaType(&This->mt);
- ZeroMemory(&This->mt, sizeof(This->mt));
- hr = S_OK;
- }
- else
- hr = S_FALSE;
- }
- LeaveCriticalSection(&This->filter->csFilter);
-
- return hr;
-}
-
HRESULT WINAPI BasePinImpl_ConnectedTo(IPin * iface, IPin ** ppPin)
{
struct strmbase_pin *This = impl_from_IPin(iface);
@@ -685,6 +660,9 @@ HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceiveP
}
}
+ if (SUCCEEDED(hr) && This->pFuncsTable->sink_connect)
+ hr = This->pFuncsTable->sink_connect(This, pReceivePin, pmt);
+
if (SUCCEEDED(hr))
{
CopyMediaType(&This->pin.mt, pmt);
@@ -697,6 +675,34 @@ HRESULT WINAPI BaseInputPinImpl_ReceiveConnection(IPin * iface, IPin * pReceiveP
return hr;
}
+HRESULT WINAPI BaseInputPinImpl_Disconnect(IPin *iface)
+{
+ struct strmbase_sink *pin = impl_sink_from_IPin(iface);
+ HRESULT hr;
+
+ TRACE("pin %p.\n", pin);
+
+ EnterCriticalSection(&pin->pin.filter->csFilter);
+
+ if (pin->pin.peer)
+ {
+ if (pin->pFuncsTable->sink_disconnect)
+ pin->pFuncsTable->sink_disconnect(pin);
+
+ IPin_Release(pin->pin.peer);
+ pin->pin.peer = NULL;
+ FreeMediaType(&pin->pin.mt);
+ memset(&pin->pin.mt, 0, sizeof(AM_MEDIA_TYPE));
+ hr = S_OK;
+ }
+ else
+ hr = S_FALSE;
+
+ LeaveCriticalSection(&pin->pin.filter->csFilter);
+
+ return hr;
+}
+
static HRESULT deliver_endofstream(IPin* pin, LPVOID unused)
{
return IPin_EndOfStream( pin );
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 461214cf082..83ad2e0bd6e 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -91,9 +91,10 @@ typedef HRESULT (WINAPI *BaseInputPin_Receive)(struct strmbase_sink *This, IMedi
struct strmbase_sink_ops
{
- BasePinFuncTable base;
- /* Optional */
- BaseInputPin_Receive pfnReceive;
+ BasePinFuncTable base;
+ BaseInputPin_Receive pfnReceive;
+ HRESULT (*sink_connect)(struct strmbase_sink *pin, IPin *peer, const AM_MEDIA_TYPE *mt);
+ void (*sink_disconnect)(struct strmbase_sink *pin);
};
/* Base Pin */
@@ -102,7 +103,7 @@ LONG WINAPI BasePinImpl_GetMediaTypeVersion(struct strmbase_pin *pin);
HRESULT WINAPI BasePinImpl_QueryInterface(IPin *iface, REFIID iid, void **out);
ULONG WINAPI BasePinImpl_AddRef(IPin *iface);
ULONG WINAPI BasePinImpl_Release(IPin *iface);
-HRESULT WINAPI BasePinImpl_Disconnect(IPin * iface);
+HRESULT WINAPI BaseInputPinImpl_Disconnect(IPin * iface);
HRESULT WINAPI BasePinImpl_ConnectedTo(IPin * iface, IPin ** ppPin);
HRESULT WINAPI BasePinImpl_ConnectionMediaType(IPin * iface, AM_MEDIA_TYPE * pmt);
HRESULT WINAPI BasePinImpl_QueryPinInfo(IPin * iface, PIN_INFO * pInfo);
--
2.24.0
Dec. 10, 2019
[PATCH 2/5] strmbase: Pass an AM_MEDIA_TYPE pointer to CompleteConnect().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/dsoundrender.c | 13 +++-------
dlls/quartz/vmr9.c | 53 +++++++++++++++++++-------------------
dlls/strmbase/renderer.c | 4 +--
include/wine/strmbase.h | 3 +--
4 files changed, 33 insertions(+), 40 deletions(-)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c
index ca1e60de61d..b21ba40cb51 100644
--- a/dlls/quartz/dsoundrender.c
+++ b/dlls/quartz/dsoundrender.c
@@ -397,18 +397,13 @@ static void dsound_render_start_stream(struct strmbase_renderer *iface)
}
}
-static HRESULT WINAPI DSoundRender_CompleteConnect(struct strmbase_renderer *iface, IPin *pReceivePin)
+static HRESULT dsound_render_connect(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt)
{
DSoundRenderImpl *This = impl_from_strmbase_renderer(iface);
- const AM_MEDIA_TYPE *pmt = &This->renderer.sink.pin.mt;
+ const WAVEFORMATEX *format = (WAVEFORMATEX *)mt->pbFormat;
HRESULT hr = S_OK;
- WAVEFORMATEX *format;
DSBUFFERDESC buf_desc;
- TRACE("(%p)->(%p)\n", This, pReceivePin);
-
- format = (WAVEFORMATEX*)pmt->pbFormat;
-
This->buf_size = format->nAvgBytesPerSec;
memset(&buf_desc,0,sizeof(DSBUFFERDESC));
@@ -417,7 +412,7 @@ static HRESULT WINAPI DSoundRender_CompleteConnect(struct strmbase_renderer *ifa
DSBCAPS_CTRLFREQUENCY | DSBCAPS_GLOBALFOCUS |
DSBCAPS_GETCURRENTPOSITION2;
buf_desc.dwBufferBytes = This->buf_size;
- buf_desc.lpwfxFormat = format;
+ buf_desc.lpwfxFormat = (WAVEFORMATEX *)format;
hr = IDirectSound8_CreateSoundBuffer(This->dsound, &buf_desc, &This->dsbuffer, NULL);
This->writepos = This->buf_size;
if (FAILED(hr))
@@ -523,7 +518,7 @@ static const struct strmbase_renderer_ops renderer_ops =
.renderer_stop_stream = dsound_render_stop_stream,
.pfnShouldDrawSampleNow = DSoundRender_ShouldDrawSampleNow,
.pfnPrepareReceive = DSoundRender_PrepareReceive,
- .pfnCompleteConnect = DSoundRender_CompleteConnect,
+ .renderer_connect = dsound_render_connect,
.pfnBreakConnect = DSoundRender_BreakConnect,
.pfnEndOfStream = DSoundRender_EndOfStream,
.pfnEndFlush = DSoundRender_EndFlush,
diff --git a/dlls/quartz/vmr9.c b/dlls/quartz/vmr9.c
index 60c19e00191..0177f7e36fa 100644
--- a/dlls/quartz/vmr9.c
+++ b/dlls/quartz/vmr9.c
@@ -338,26 +338,8 @@ static HRESULT WINAPI VMR9_CheckMediaType(struct strmbase_renderer *iface, const
if (!IsEqualIID(&pmt->majortype, &MEDIATYPE_Video) || !pmt->pbFormat)
return S_FALSE;
- /* Ignore subtype, test for bicompression instead */
- if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo))
- {
- VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)pmt->pbFormat;
-
- This->bmiheader = format->bmiHeader;
- This->VideoWidth = format->bmiHeader.biWidth;
- This->VideoHeight = format->bmiHeader.biHeight;
- SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight);
- }
- else if (IsEqualIID(&pmt->formattype, &FORMAT_VideoInfo2))
- {
- VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)pmt->pbFormat;
-
- This->bmiheader = format->bmiHeader;
- This->VideoWidth = format->bmiHeader.biWidth;
- This->VideoHeight = format->bmiHeader.biHeight;
- SetRect(&This->source_rect, 0, 0, This->VideoWidth, This->VideoHeight);
- }
- else
+ if (!IsEqualGUID(&pmt->formattype, &FORMAT_VideoInfo)
+ && !IsEqualGUID(&pmt->formattype, &FORMAT_VideoInfo2))
{
ERR("Format type %s not supported\n", debugstr_guid(&pmt->formattype));
return S_FALSE;
@@ -461,16 +443,33 @@ static HRESULT WINAPI VMR9_ShouldDrawSampleNow(struct strmbase_renderer *iface,
return S_FALSE;
}
-static HRESULT WINAPI VMR9_CompleteConnect(struct strmbase_renderer *This, IPin *pReceivePin)
+static HRESULT vmr_connect(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt)
{
- struct quartz_vmr *pVMR9 = impl_from_IBaseFilter(&This->filter.IBaseFilter_iface);
+ struct quartz_vmr *filter = impl_from_IBaseFilter(&iface->filter.IBaseFilter_iface);
HRESULT hr;
- TRACE("(%p)\n", This);
+ if (IsEqualGUID(&mt->formattype, &FORMAT_VideoInfo))
+ {
+ VIDEOINFOHEADER *format = (VIDEOINFOHEADER *)mt->pbFormat;
+
+ filter->bmiheader = format->bmiHeader;
+ filter->VideoWidth = format->bmiHeader.biWidth;
+ filter->VideoHeight = format->bmiHeader.biHeight;
+ SetRect(&filter->source_rect, 0, 0, filter->VideoWidth, filter->VideoHeight);
+ }
+ else if (IsEqualIID(&mt->formattype, &FORMAT_VideoInfo2))
+ {
+ VIDEOINFOHEADER2 *format = (VIDEOINFOHEADER2 *)mt->pbFormat;
+
+ filter->bmiheader = format->bmiHeader;
+ filter->VideoWidth = format->bmiHeader.biWidth;
+ filter->VideoHeight = format->bmiHeader.biHeight;
+ SetRect(&filter->source_rect, 0, 0, filter->VideoWidth, filter->VideoHeight);
+ }
- if (pVMR9->mode ||
- SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&pVMR9->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
- hr = VMR9_maybe_init(pVMR9, FALSE);
+ if (filter->mode
+ || SUCCEEDED(hr = IVMRFilterConfig9_SetRenderingMode(&filter->IVMRFilterConfig9_iface, VMR9Mode_Windowed)))
+ hr = VMR9_maybe_init(filter, FALSE);
return hr;
}
@@ -576,7 +575,7 @@ static const struct strmbase_renderer_ops renderer_ops =
.renderer_start_stream = vmr_start_stream,
.renderer_stop_stream = vmr_stop_stream,
.pfnShouldDrawSampleNow = VMR9_ShouldDrawSampleNow,
- .pfnCompleteConnect = VMR9_CompleteConnect,
+ .renderer_connect = vmr_connect,
.pfnBreakConnect = VMR9_BreakConnect,
.renderer_destroy = vmr_destroy,
.renderer_query_interface = vmr_query_interface,
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index d592ab034e6..cedcd9a62a0 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -52,8 +52,8 @@ static HRESULT WINAPI BaseRenderer_InputPin_ReceiveConnection(IPin *iface, IPin
hr = BaseInputPinImpl_ReceiveConnection(iface, peer, mt);
if (SUCCEEDED(hr))
{
- if (filter->pFuncsTable->pfnCompleteConnect)
- hr = filter->pFuncsTable->pfnCompleteConnect(filter, peer);
+ if (filter->pFuncsTable->renderer_connect)
+ hr = filter->pFuncsTable->renderer_connect(filter, mt);
}
LeaveCriticalSection(&filter->filter.csFilter);
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 7e3b38b49d5..461214cf082 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -523,7 +523,6 @@ typedef HRESULT (WINAPI *BaseRenderer_EndOfStream)(struct strmbase_renderer *ifa
typedef HRESULT (WINAPI *BaseRenderer_BeginFlush) (struct strmbase_renderer *iface);
typedef HRESULT (WINAPI *BaseRenderer_EndFlush) (struct strmbase_renderer *iface);
typedef HRESULT (WINAPI *BaseRenderer_BreakConnect) (struct strmbase_renderer *iface);
-typedef HRESULT (WINAPI *BaseRenderer_CompleteConnect) (struct strmbase_renderer *iface, IPin *peer);
struct strmbase_renderer_ops
{
@@ -534,7 +533,7 @@ struct strmbase_renderer_ops
void (*renderer_stop_stream)(struct strmbase_renderer *iface);
BaseRenderer_ShouldDrawSampleNow pfnShouldDrawSampleNow;
BaseRenderer_PrepareReceive pfnPrepareReceive;
- BaseRenderer_CompleteConnect pfnCompleteConnect;
+ HRESULT (*renderer_connect)(struct strmbase_renderer *iface, const AM_MEDIA_TYPE *mt);
BaseRenderer_BreakConnect pfnBreakConnect;
BaseRenderer_EndOfStream pfnEndOfStream;
BaseRenderer_EndFlush pfnEndFlush;
--
2.24.0
Dec. 10, 2019
[PATCH 1/5] strmbase: Combine the SetMediaType() and CompleteConnect() callbacks.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/acmwrapper.c | 115 +++++++-----------------
dlls/quartz/avidec.c | 37 ++------
dlls/strmbase/transform.c | 7 +-
dlls/winegstreamer/gsttffilter.c | 146 +++++++++++--------------------
dlls/wineqtdecoder/qtvdecoder.c | 25 ++----
include/wine/strmbase.h | 5 +-
6 files changed, 103 insertions(+), 232 deletions(-)
diff --git a/dlls/quartz/acmwrapper.c b/dlls/quartz/acmwrapper.c
index 8eea6ab147d..33d9debe5cd 100644
--- a/dlls/quartz/acmwrapper.c
+++ b/dlls/quartz/acmwrapper.c
@@ -40,7 +40,6 @@ typedef struct ACMWrapperImpl
TransformFilter tf;
HACMSTREAM has;
- LPWAVEFORMATEX pWfIn;
LPWAVEFORMATEX pWfOut;
LONGLONG lasttime_real;
@@ -224,85 +223,43 @@ error:
return hr;
}
-static HRESULT WINAPI ACMWrapper_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
+static BOOL is_audio_subtype(const GUID *guid)
{
- ACMWrapperImpl* This = impl_from_TransformFilter(tf);
- MMRESULT res;
-
- TRACE("(%p)->(%i %p)\n", This, dir, pmt);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
- /* Check root (GUID w/o FOURCC) */
- if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Audio)) &&
- (!memcmp(((const char *)&pmt->subtype)+4, ((const char *)&MEDIATYPE_Audio)+4, sizeof(GUID)-4)) &&
- (IsEqualIID(&pmt->formattype, &FORMAT_WaveFormatEx)))
- {
- HACMSTREAM drv;
- WAVEFORMATEX *wfx = (WAVEFORMATEX*)pmt->pbFormat;
- AM_MEDIA_TYPE* outpmt = &This->tf.pmt;
-
- if (!wfx || wfx->wFormatTag == WAVE_FORMAT_PCM || wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
- return VFW_E_TYPE_NOT_ACCEPTED;
- FreeMediaType(outpmt);
-
- This->pWfIn = (LPWAVEFORMATEX)pmt->pbFormat;
-
- /* HACK */
- /* TRACE("ALIGN = %d\n", pACMWrapper->pWfIn->nBlockAlign); */
- /* pACMWrapper->pWfIn->nBlockAlign = 1; */
-
- /* Set output audio data to PCM */
- CopyMediaType(outpmt, pmt);
- outpmt->subtype.Data1 = WAVE_FORMAT_PCM;
- This->pWfOut = (WAVEFORMATEX*)outpmt->pbFormat;
- This->pWfOut->wFormatTag = WAVE_FORMAT_PCM;
- This->pWfOut->wBitsPerSample = 16;
- This->pWfOut->nBlockAlign = This->pWfOut->wBitsPerSample * This->pWfOut->nChannels / 8;
- This->pWfOut->cbSize = 0;
- This->pWfOut->nAvgBytesPerSec = This->pWfOut->nChannels * This->pWfOut->nSamplesPerSec
- * (This->pWfOut->wBitsPerSample/8);
-
- if (!(res = acmStreamOpen(&drv, NULL, This->pWfIn, This->pWfOut, NULL, 0, 0, 0)))
- {
- This->has = drv;
-
- TRACE("Connection accepted\n");
- return S_OK;
- }
- else
- FIXME("acmStreamOpen returned %d\n", res);
- FreeMediaType(outpmt);
- TRACE("Unable to find a suitable ACM decompressor\n");
- }
-
- TRACE("Connection refused\n");
- return VFW_E_TYPE_NOT_ACCEPTED;
+ return !memcmp(&guid->Data2, &MEDIATYPE_Audio.Data2, sizeof(GUID) - sizeof(int));
}
-static HRESULT WINAPI ACMWrapper_CompleteConnect(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
+static HRESULT acm_wrapper_connect_sink(TransformFilter *iface, const AM_MEDIA_TYPE *mt)
{
- ACMWrapperImpl* This = impl_from_TransformFilter(tf);
- MMRESULT res;
+ ACMWrapperImpl *filter = impl_from_TransformFilter(iface);
+ const WAVEFORMATEX *wfx = (WAVEFORMATEX *)mt->pbFormat;
HACMSTREAM drv;
+ MMRESULT res;
- TRACE("(%p)\n", This);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
- if (!(res = acmStreamOpen(&drv, NULL, This->pWfIn, This->pWfOut, NULL, 0, 0, 0)))
+ if (!IsEqualGUID(&mt->majortype, &MEDIATYPE_Audio) || !is_audio_subtype(&mt->subtype)
+ || !IsEqualGUID(&mt->formattype, &FORMAT_WaveFormatEx) || !wfx
+ || wfx->wFormatTag == WAVE_FORMAT_PCM || wfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE)
+ return VFW_E_TYPE_NOT_ACCEPTED;
+
+ CopyMediaType(&filter->tf.pmt, mt);
+ filter->tf.pmt.subtype.Data1 = WAVE_FORMAT_PCM;
+ filter->pWfOut = (WAVEFORMATEX *)filter->tf.pmt.pbFormat;
+ filter->pWfOut->wFormatTag = WAVE_FORMAT_PCM;
+ filter->pWfOut->wBitsPerSample = 16;
+ filter->pWfOut->nBlockAlign = filter->pWfOut->wBitsPerSample * filter->pWfOut->nChannels / 8;
+ filter->pWfOut->cbSize = 0;
+ filter->pWfOut->nAvgBytesPerSec = filter->pWfOut->nChannels * filter->pWfOut->nSamplesPerSec
+ * (filter->pWfOut->wBitsPerSample / 8);
+
+ if ((res = acmStreamOpen(&drv, NULL, (WAVEFORMATEX *)wfx, filter->pWfOut, NULL, 0, 0, 0)))
{
- This->has = drv;
-
- TRACE("Connection accepted\n");
- return S_OK;
+ ERR("Failed to open stream, error %u.\n", res);
+ FreeMediaType(&filter->tf.pmt);
+ return VFW_E_TYPE_NOT_ACCEPTED;
}
- FIXME("acmStreamOpen returned %d\n", res);
- TRACE("Unable to find a suitable ACM decompressor\n");
- return VFW_E_TYPE_NOT_ACCEPTED;
+ filter->has = drv;
+
+ return S_OK;
}
static HRESULT WINAPI ACMWrapper_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir)
@@ -341,18 +298,10 @@ static HRESULT WINAPI ACMWrapper_DecideBufferSize(TransformFilter *tf, IMemAlloc
}
static const TransformFilterFuncTable ACMWrapper_FuncsTable = {
- ACMWrapper_DecideBufferSize,
- NULL,
- ACMWrapper_Receive,
- NULL,
- NULL,
- ACMWrapper_SetMediaType,
- ACMWrapper_CompleteConnect,
- ACMWrapper_BreakConnect,
- NULL,
- NULL,
- NULL,
- NULL
+ .pfnDecideBufferSize = ACMWrapper_DecideBufferSize,
+ .pfnReceive = ACMWrapper_Receive,
+ .transform_connect_sink = acm_wrapper_connect_sink,
+ .pfnBreakConnect = ACMWrapper_BreakConnect,
};
HRESULT ACMWrapper_create(IUnknown *outer, void **out)
diff --git a/dlls/quartz/avidec.c b/dlls/quartz/avidec.c
index 32969a34730..abed957fa6d 100644
--- a/dlls/quartz/avidec.c
+++ b/dlls/quartz/avidec.c
@@ -210,16 +210,11 @@ static HRESULT WINAPI AVIDec_StopStreaming(TransformFilter* pTransformFilter)
return S_OK;
}
-static HRESULT WINAPI AVIDec_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
+static HRESULT avi_dec_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *pmt)
{
AVIDecImpl* This = impl_from_TransformFilter(tf);
HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
- TRACE("(%p)->(%p)\n", This, pmt);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
/* Check root (GUID w/o FOURCC) */
if ((IsEqualIID(&pmt->majortype, &MEDIATYPE_Video)) &&
(!memcmp(((const char *)&pmt->subtype)+4, ((const char *)&MEDIATYPE_Video)+4, sizeof(GUID)-4)))
@@ -310,15 +305,6 @@ failed:
return hr;
}
-static HRESULT WINAPI AVIDec_CompleteConnect(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- AVIDecImpl* This = impl_from_TransformFilter(tf);
-
- TRACE("(%p)\n", This);
-
- return S_OK;
-}
-
static HRESULT WINAPI AVIDec_BreakConnect(TransformFilter *tf, PIN_DIRECTION dir)
{
AVIDecImpl *This = impl_from_TransformFilter(tf);
@@ -357,19 +343,14 @@ static HRESULT WINAPI AVIDec_DecideBufferSize(TransformFilter *tf, IMemAllocator
}
static const TransformFilterFuncTable AVIDec_FuncsTable = {
- AVIDec_DecideBufferSize,
- AVIDec_StartStreaming,
- AVIDec_Receive,
- AVIDec_StopStreaming,
- NULL,
- AVIDec_SetMediaType,
- AVIDec_CompleteConnect,
- AVIDec_BreakConnect,
- NULL,
- NULL,
- AVIDec_EndFlush,
- NULL,
- AVIDec_NotifyDrop
+ .pfnDecideBufferSize = AVIDec_DecideBufferSize,
+ .pfnStartStreaming = AVIDec_StartStreaming,
+ .pfnReceive = AVIDec_Receive,
+ .pfnStopStreaming = AVIDec_StopStreaming,
+ .transform_connect_sink = avi_dec_connect_sink,
+ .pfnBreakConnect = AVIDec_BreakConnect,
+ .pfnEndFlush = AVIDec_EndFlush,
+ .pfnNotify = AVIDec_NotifyDrop,
};
HRESULT AVIDec_create(IUnknown *outer, void **out)
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 7a79f709055..30ed0006cb1 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -405,11 +405,8 @@ static HRESULT WINAPI TransformFilter_InputPin_ReceiveConnection(IPin * iface, I
TRACE("(%p)->(%p, %p)\n", iface, pReceivePin, pmt);
strmbase_dump_media_type(pmt);
- if (pTransform->pFuncsTable->pfnSetMediaType)
- hr = pTransform->pFuncsTable->pfnSetMediaType(pTransform, PINDIR_INPUT, pmt);
-
- if (SUCCEEDED(hr) && pTransform->pFuncsTable->pfnCompleteConnect)
- hr = pTransform->pFuncsTable->pfnCompleteConnect(pTransform, PINDIR_INPUT, pReceivePin);
+ if (pTransform->pFuncsTable->transform_connect_sink)
+ hr = pTransform->pFuncsTable->transform_connect_sink(pTransform, pmt);
if (SUCCEEDED(hr))
{
diff --git a/dlls/winegstreamer/gsttffilter.c b/dlls/winegstreamer/gsttffilter.c
index ee1851dfdc6..d44a6ae33a6 100644
--- a/dlls/winegstreamer/gsttffilter.c
+++ b/dlls/winegstreamer/gsttffilter.c
@@ -516,7 +516,7 @@ static HRESULT WINAPI Gstreamer_Mp3_QueryConnect(TransformFilter *iface, const A
return S_OK;
}
-static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT mp3_decoder_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -525,13 +525,8 @@ static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECT
HRESULT hr;
int layer;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_Mp3_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return VFW_E_TYPE_NOT_ACCEPTED;
@@ -588,26 +583,19 @@ static HRESULT WINAPI Gstreamer_Mp3_SetMediaType(TransformFilter *tf, PIN_DIRECT
return hr;
}
-static HRESULT WINAPI Gstreamer_Mp3_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- TRACE("%p 0x%x %p\n", tf, dir, pin);
- return S_OK;
-}
-
static const TransformFilterFuncTable Gstreamer_Mp3_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_Mp3_QueryConnect,
- Gstreamer_Mp3_SetMediaType,
- Gstreamer_Mp3_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_Mp3_QueryConnect,
+ .transform_connect_sink = mp3_decoder_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_Mp3_create(IUnknown *punkouter, HRESULT *phr)
@@ -664,13 +652,7 @@ static HRESULT WINAPI Gstreamer_YUV_QueryConnect(TransformFilter *iface, const A
}
}
-static HRESULT WINAPI Gstreamer_YUV_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- TRACE("%p 0x%x %p\n", tf, dir, pin);
- return S_OK;
-}
-
-static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT yuv_to_rgb_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -679,13 +661,8 @@ static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DI
int avgtime;
LONG width, height;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@@ -738,19 +715,18 @@ static HRESULT WINAPI Gstreamer_YUV2RGB_SetMediaType(TransformFilter *tf, PIN_DI
}
static const TransformFilterFuncTable Gstreamer_YUV2RGB_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_YUV_QueryConnect,
- Gstreamer_YUV2RGB_SetMediaType,
- Gstreamer_YUV_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_YUV_QueryConnect,
+ .transform_connect_sink = yuv_to_rgb_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *punkouter, HRESULT *phr)
@@ -772,7 +748,7 @@ IUnknown * CALLBACK Gstreamer_YUV2RGB_create(IUnknown *punkouter, HRESULT *phr)
return obj;
}
-static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT yuv_to_argb_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -781,13 +757,8 @@ static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_D
int avgtime;
LONG width, height;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_YUV_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@@ -840,19 +811,18 @@ static HRESULT WINAPI Gstreamer_YUV2ARGB_SetMediaType(TransformFilter *tf, PIN_D
}
static const TransformFilterFuncTable Gstreamer_YUV2ARGB_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_YUV_QueryConnect,
- Gstreamer_YUV2ARGB_SetMediaType,
- Gstreamer_YUV_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_YUV_QueryConnect,
+ .transform_connect_sink = yuv_to_argb_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_YUV2ARGB_create(IUnknown *punkouter, HRESULT *phr)
@@ -886,13 +856,7 @@ static HRESULT WINAPI Gstreamer_AudioConvert_QueryConnect(TransformFilter *iface
return S_OK;
}
-static HRESULT WINAPI Gstreamer_AudioConvert_ConnectInput(TransformFilter *tf, PIN_DIRECTION dir, IPin *pin)
-{
- TRACE("%p 0x%x %p\n", tf, dir, pin);
- return S_OK;
-}
-
-static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE *amt)
+static HRESULT audio_converter_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *amt)
{
GstTfImpl *This = (GstTfImpl*)tf;
GstCaps *capsin, *capsout;
@@ -905,13 +869,8 @@ static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, P
BOOL inisfloat = FALSE;
int indepth;
- TRACE("%p 0x%x %p\n", This, dir, amt);
-
mark_wine_thread();
- if (dir != PINDIR_INPUT)
- return S_OK;
-
if (Gstreamer_AudioConvert_QueryConnect(&This->tf, amt) == S_FALSE || !amt->pbFormat)
return E_FAIL;
@@ -972,19 +931,18 @@ static HRESULT WINAPI Gstreamer_AudioConvert_SetMediaType(TransformFilter *tf, P
}
static const TransformFilterFuncTable Gstreamer_AudioConvert_vtbl = {
- Gstreamer_transform_DecideBufferSize,
- Gstreamer_transform_ProcessBegin,
- Gstreamer_transform_ProcessData,
- Gstreamer_transform_ProcessEnd,
- Gstreamer_AudioConvert_QueryConnect,
- Gstreamer_AudioConvert_SetMediaType,
- Gstreamer_AudioConvert_ConnectInput,
- Gstreamer_transform_Cleanup,
- Gstreamer_transform_EndOfStream,
- Gstreamer_transform_BeginFlush,
- Gstreamer_transform_EndFlush,
- Gstreamer_transform_NewSegment,
- Gstreamer_transform_QOS
+ .pfnDecideBufferSize = Gstreamer_transform_DecideBufferSize,
+ .pfnStartStreaming = Gstreamer_transform_ProcessBegin,
+ .pfnReceive = Gstreamer_transform_ProcessData,
+ .pfnStopStreaming = Gstreamer_transform_ProcessEnd,
+ .pfnCheckInputType = Gstreamer_AudioConvert_QueryConnect,
+ .transform_connect_sink = audio_converter_connect_sink,
+ .pfnBreakConnect = Gstreamer_transform_Cleanup,
+ .pfnEndOfStream = Gstreamer_transform_EndOfStream,
+ .pfnBeginFlush = Gstreamer_transform_BeginFlush,
+ .pfnEndFlush = Gstreamer_transform_EndFlush,
+ .pfnNewSegment = Gstreamer_transform_NewSegment,
+ .pfnNotify = Gstreamer_transform_QOS,
};
IUnknown * CALLBACK Gstreamer_AudioConvert_create(IUnknown *punkouter, HRESULT *phr)
diff --git a/dlls/wineqtdecoder/qtvdecoder.c b/dlls/wineqtdecoder/qtvdecoder.c
index 3da0738aecb..4be654e5a10 100644
--- a/dlls/wineqtdecoder/qtvdecoder.c
+++ b/dlls/wineqtdecoder/qtvdecoder.c
@@ -336,7 +336,7 @@ static HRESULT WINAPI QTVDecoder_StopStreaming(TransformFilter* pTransformFilter
return S_OK;
}
-static HRESULT WINAPI QTVDecoder_SetMediaType(TransformFilter *tf, PIN_DIRECTION dir, const AM_MEDIA_TYPE * pmt)
+static HRESULT video_decoder_connect_sink(TransformFilter *tf, const AM_MEDIA_TYPE *pmt)
{
QTVDecoderImpl* This = impl_from_TransformFilter(tf);
HRESULT hr = VFW_E_TYPE_NOT_ACCEPTED;
@@ -344,11 +344,6 @@ static HRESULT WINAPI QTVDecoder_SetMediaType(TransformFilter *tf, PIN_DIRECTION
AM_MEDIA_TYPE *outpmt = &This->tf.pmt;
CFNumberRef n = NULL;
- TRACE("(%p)->(%p)\n", This, pmt);
-
- if (dir != PINDIR_INPUT)
- return S_OK;
-
FreeMediaType(outpmt);
CopyMediaType(outpmt, pmt);
@@ -502,18 +497,12 @@ static HRESULT WINAPI QTVDecoder_DecideBufferSize(TransformFilter *tf, IMemAlloc
}
static const TransformFilterFuncTable QTVDecoder_FuncsTable = {
- QTVDecoder_DecideBufferSize,
- QTVDecoder_StartStreaming,
- QTVDecoder_Receive,
- QTVDecoder_StopStreaming,
- NULL,
- QTVDecoder_SetMediaType,
- NULL,
- QTVDecoder_BreakConnect,
- NULL,
- NULL,
- NULL,
- NULL
+ .pfnDecideBufferSize = QTVDecoder_DecideBufferSize,
+ .pfnStartStreaming = QTVDecoder_StartStreaming,
+ .pfnReceive = QTVDecoder_Receive,
+ .pfnStopStreaming = QTVDecoder_StopStreaming,
+ .transform_connect_sink = video_decoder_connect_sink,
+ .pfnBreakConnect = QTVDecoder_BreakConnect,
};
IUnknown * CALLBACK QTVDecoder_create(IUnknown *outer, HRESULT* phr)
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index c3699f19253..7e3b38b49d5 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -197,9 +197,7 @@ typedef HRESULT (WINAPI *TransformFilter_DecideBufferSize) (TransformFilter *ifa
typedef HRESULT (WINAPI *TransformFilter_StartStreaming) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_StopStreaming) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_Receive) (TransformFilter* iface, IMediaSample* pIn);
-typedef HRESULT (WINAPI *TransformFilter_CompleteConnect) (TransformFilter *iface, PIN_DIRECTION dir, IPin *pPin);
typedef HRESULT (WINAPI *TransformFilter_BreakConnect) (TransformFilter *iface, PIN_DIRECTION dir);
-typedef HRESULT (WINAPI *TransformFilter_SetMediaType) (TransformFilter *iface, PIN_DIRECTION dir, const AM_MEDIA_TYPE *pMediaType);
typedef HRESULT (WINAPI *TransformFilter_CheckInputType) (TransformFilter *iface, const AM_MEDIA_TYPE *pMediaType);
typedef HRESULT (WINAPI *TransformFilter_EndOfStream) (TransformFilter *iface);
typedef HRESULT (WINAPI *TransformFilter_BeginFlush) (TransformFilter *iface);
@@ -216,8 +214,7 @@ typedef struct TransformFilterFuncTable {
TransformFilter_Receive pfnReceive;
TransformFilter_StopStreaming pfnStopStreaming;
TransformFilter_CheckInputType pfnCheckInputType;
- TransformFilter_SetMediaType pfnSetMediaType;
- TransformFilter_CompleteConnect pfnCompleteConnect;
+ HRESULT (*transform_connect_sink)(TransformFilter *filter, const AM_MEDIA_TYPE *mt);
TransformFilter_BreakConnect pfnBreakConnect;
TransformFilter_EndOfStream pfnEndOfStream;
TransformFilter_BeginFlush pfnBeginFlush;
--
2.24.0
Dec. 10, 2019
Re: [PATCH v2 3/4] kernel32/tests: Test invalid parent handle in test_parent_process_attribute().
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61719
Your paranoid android.
=== w1064v1507 (32 bit report) ===
Report errors:
kernel32:process is missing some failure messages
Dec. 10, 2019
[PATCH] dmband: Get rid of the redundant debugstr_DMUS_OBJECTDESC()
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/dmband/dmutils.c | 29 ++---------------------------
1 file changed, 2 insertions(+), 27 deletions(-)
diff --git a/dlls/dmband/dmutils.c b/dlls/dmband/dmutils.c
index a1dc7e28a5..af24054bf4 100644
--- a/dlls/dmband/dmutils.c
+++ b/dlls/dmband/dmutils.c
@@ -122,31 +122,6 @@ static const char *debugstr_dmversion (const DMUS_VERSION *version) {
HIWORD(version->dwVersionLS), LOWORD(version->dwVersionLS));
}
-/* dump whole DMUS_OBJECTDESC struct */
-static const char *debugstr_DMUS_OBJECTDESC (LPDMUS_OBJECTDESC pDesc) {
- if (pDesc) {
- char buffer[1024] = "", *ptr = &buffer[0];
-
- ptr += sprintf(ptr, "DMUS_OBJECTDESC (%p):\n", pDesc);
- ptr += sprintf(ptr, " - dwSize = 0x%08X\n", pDesc->dwSize);
- ptr += sprintf(ptr, " - dwValidData = 0x%08X ( %s)\n", pDesc->dwValidData, debugstr_DMUS_OBJ_FLAGS (pDesc->dwValidData));
- if (pDesc->dwValidData & DMUS_OBJ_CLASS) ptr += sprintf(ptr, " - guidClass = %s\n", debugstr_dmguid(&pDesc->guidClass));
- if (pDesc->dwValidData & DMUS_OBJ_OBJECT) ptr += sprintf(ptr, " - guidObject = %s\n", debugstr_guid(&pDesc->guidObject));
- if (pDesc->dwValidData & DMUS_OBJ_DATE) ptr += sprintf(ptr, " - ftDate = %s\n", debugstr_filetime (&pDesc->ftDate));
- if (pDesc->dwValidData & DMUS_OBJ_VERSION) ptr += sprintf(ptr, " - vVersion = %s\n", debugstr_dmversion(&pDesc->vVersion));
- if (pDesc->dwValidData & DMUS_OBJ_NAME) ptr += sprintf(ptr, " - wszName = %s\n", debugstr_w(pDesc->wszName));
- if (pDesc->dwValidData & DMUS_OBJ_CATEGORY) ptr += sprintf(ptr, " - wszCategory = %s\n", debugstr_w(pDesc->wszCategory));
- if (pDesc->dwValidData & DMUS_OBJ_FILENAME) ptr += sprintf(ptr, " - wszFileName = %s\n", debugstr_w(pDesc->wszFileName));
- if (pDesc->dwValidData & DMUS_OBJ_MEMORY) ptr += sprintf(ptr, " - llMemLength = 0x%s - pbMemData = %p\n",
- wine_dbgstr_longlong(pDesc->llMemLength), pDesc->pbMemData);
- if (pDesc->dwValidData & DMUS_OBJ_STREAM) ptr += sprintf(ptr, " - pStream = %p\n", pDesc->pStream);
-
- return wine_dbg_sprintf("%s", buffer);
- } else {
- return "(NULL)";
- }
-}
-
HRESULT IDirectMusicUtils_IPersistStream_ParseDescGeneric (DMUS_PRIVATE_CHUNK* pChunk, IStream* pStm, LPDMUS_OBJECTDESC pDesc) {
switch (pChunk->fccID) {
@@ -303,7 +278,7 @@ HRESULT IDirectMusicUtils_IPersistStream_ParseReference (LPPERSISTSTREAM iface,
TRACE_(dmfile)("** DM Reference Begin of Load ***\n");
TRACE_(dmfile)("With Desc:\n");
- debugstr_DMUS_OBJECTDESC(&ref_desc);
+ debug_DMUS_OBJECTDESC(&ref_desc);
{
LPDIRECTMUSICGETLOADER pGetLoader = NULL;
@@ -521,7 +496,7 @@ void debug_DMUS_OBJECTDESC (LPDMUS_OBJECTDESC pDesc) {
if (pDesc->dwValidData & DMUS_OBJ_NAME) TRACE(" - wszName = %s\n", debugstr_w(pDesc->wszName));
if (pDesc->dwValidData & DMUS_OBJ_CLASS) TRACE(" - guidClass = %s\n", debugstr_dmguid(&pDesc->guidClass));
if (pDesc->dwValidData & DMUS_OBJ_OBJECT) TRACE(" - guidObject = %s\n", debugstr_guid(&pDesc->guidObject));
- if (pDesc->dwValidData & DMUS_OBJ_DATE) TRACE(" - ftDate = FIXME\n");
+ if (pDesc->dwValidData & DMUS_OBJ_DATE) TRACE(" - ftDate = %s\n", debugstr_filetime(&pDesc->ftDate));
if (pDesc->dwValidData & DMUS_OBJ_VERSION) TRACE(" - vVersion = %s\n", debugstr_dmversion(&pDesc->vVersion));
if (pDesc->dwValidData & DMUS_OBJ_CATEGORY) TRACE(" - wszCategory = %s\n", debugstr_w(pDesc->wszCategory));
if (pDesc->dwValidData & DMUS_OBJ_FILENAME) TRACE(" - wszFileName = %s\n", debugstr_w(pDesc->wszFileName));
--
2.23.0
Dec. 9, 2019
[PATCH] dmloader: Remove commented out dead code
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
There's no debugstr_DMUS_OBJECTDESC() any longer in dmloader.
dlls/dmloader/container.c | 19 -------------------
1 file changed, 19 deletions(-)
diff --git a/dlls/dmloader/container.c b/dlls/dmloader/container.c
index bac52111ac..39b105a159 100644
--- a/dlls/dmloader/container.c
+++ b/dlls/dmloader/container.c
@@ -640,25 +640,6 @@ static HRESULT WINAPI IPersistStreamImpl_Load(IPersistStream *iface, IStream *pS
IDirectMusicLoader_Release (pLoader); /* release loader */
-#if 0
- /* DEBUG: dumps whole container object tree: */
- if (TRACE_ON(dmloader)) {
- int r = 0;
- LPWINE_CONTAINER_ENTRY tmpEntry;
- struct list *listEntry;
-
- TRACE("*** IDirectMusicContainer (%p) ***\n", This->ContainerVtbl);
- TRACE(" - Objects:\n");
- LIST_FOR_EACH (listEntry, This->pContainedObjects) {
- tmpEntry = LIST_ENTRY( listEntry, WINE_CONTAINER_ENTRY, entry );
- TRACE(" - Object[%i]:\n", r);
- TRACE(" - wszAlias: %s\n", debugstr_w(tmpEntry->wszAlias));
- TRACE(" - Object descriptor:\n%s\n", debugstr_DMUS_OBJECTDESC(&tmpEntry->Desc));
- r++;
- }
- }
-#endif
-
return result;
}
--
2.23.0
Dec. 9, 2019
[PATCH] dmband: Add partial implementation of Band track GetParam/SetParam
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/dmband/bandtrack.c | 57 +++++++++++++++++++++++++++++++-------
dlls/dmband/tests/dmband.c | 22 ++++++++++++---
2 files changed, 65 insertions(+), 14 deletions(-)
diff --git a/dlls/dmband/bandtrack.c b/dlls/dmband/bandtrack.c
index a0305bdb28..14d2c7a571 100644
--- a/dlls/dmband/bandtrack.c
+++ b/dlls/dmband/bandtrack.c
@@ -132,20 +132,57 @@ static HRESULT WINAPI band_track_Play(IDirectMusicTrack8 *iface, void *state_dat
return S_OK;
}
-static HRESULT WINAPI band_track_GetParam(IDirectMusicTrack8 *iface, REFGUID rguidType,
- MUSIC_TIME mtTime, MUSIC_TIME *pmtNext, void *pParam)
+static HRESULT WINAPI band_track_GetParam(IDirectMusicTrack8 *iface, REFGUID type, MUSIC_TIME time,
+ MUSIC_TIME *next, void *param)
{
- IDirectMusicBandTrack *This = impl_from_IDirectMusicTrack8(iface);
- FIXME("(%p, %s, %d, %p, %p): stub\n", This, debugstr_dmguid(rguidType), mtTime, pmtNext, pParam);
- return S_OK;
+ IDirectMusicBandTrack *This = impl_from_IDirectMusicTrack8(iface);
+
+ TRACE("(%p, %s, %d, %p, %p)\n", This, debugstr_dmguid(type), time, next, param);
+
+ if (!type)
+ return E_POINTER;
+ if (!IsEqualGUID(type, &GUID_BandParam))
+ return DMUS_E_GET_UNSUPPORTED;
+
+ FIXME("GUID_BandParam not handled yet\n");
+
+ return S_OK;
}
-static HRESULT WINAPI band_track_SetParam(IDirectMusicTrack8 *iface, REFGUID rguidType,
- MUSIC_TIME mtTime, void *pParam)
+static HRESULT WINAPI band_track_SetParam(IDirectMusicTrack8 *iface, REFGUID type, MUSIC_TIME time,
+ void *param)
{
- IDirectMusicBandTrack *This = impl_from_IDirectMusicTrack8(iface);
- FIXME("(%p, %s, %d, %p): stub\n", This, debugstr_dmguid(rguidType), mtTime, pParam);
- return S_OK;
+ IDirectMusicBandTrack *This = impl_from_IDirectMusicTrack8(iface);
+
+ TRACE("(%p, %s, %d, %p)\n", This, debugstr_dmguid(type), time, param);
+
+ if (!type)
+ return E_POINTER;
+ if (FAILED(IDirectMusicTrack8_IsParamSupported(iface, type)))
+ return DMUS_E_TYPE_UNSUPPORTED;
+
+ if (IsEqualGUID(type, &GUID_BandParam))
+ FIXME("GUID_BandParam not handled yet\n");
+ else if (IsEqualGUID(type, &GUID_Clear_All_Bands))
+ FIXME("GUID_Clear_All_Bands not handled yet\n");
+ else if (IsEqualGUID(type, &GUID_ConnectToDLSCollection))
+ FIXME("GUID_ConnectToDLSCollection not handled yet\n");
+ else if (IsEqualGUID(type, &GUID_Disable_Auto_Download))
+ FIXME("GUID_Disable_Auto_Download not handled yet\n");
+ else if (IsEqualGUID(type, &GUID_Download))
+ FIXME("GUID_Download not handled yet\n");
+ else if (IsEqualGUID(type, &GUID_DownloadToAudioPath))
+ FIXME("GUID_DownloadToAudioPath not handled yet\n");
+ else if (IsEqualGUID(type, &GUID_Enable_Auto_Download))
+ FIXME("GUID_Enable_Auto_Download not handled yet\n");
+ else if (IsEqualGUID(type, &GUID_IDirectMusicBand))
+ FIXME("GUID_IDirectMusicBand not handled yet\n");
+ else if (IsEqualGUID(type, &GUID_StandardMIDIFile))
+ FIXME("GUID_StandardMIDIFile not handled yet\n");
+ else if (IsEqualGUID(type, &GUID_UnloadFromAudioPath))
+ FIXME("GUID_UnloadFromAudioPath not handled yet\n");
+
+ return S_OK;
}
static HRESULT WINAPI band_track_IsParamSupported(IDirectMusicTrack8 *iface, REFGUID rguidType)
diff --git a/dlls/dmband/tests/dmband.c b/dlls/dmband/tests/dmband.c
index 459d00ed1d..dce8a47ba4 100644
--- a/dlls/dmband/tests/dmband.c
+++ b/dlls/dmband/tests/dmband.c
@@ -180,6 +180,7 @@ static void test_bandtrack(void)
IPersistStream *ps;
CLSID class;
ULARGE_INTEGER size;
+ char buf[64] = { 0 };
HRESULT hr;
#define X(guid) &guid, #guid
const struct {
@@ -233,26 +234,39 @@ static void test_bandtrack(void)
}
hr = IDirectMusicTrack8_EndPlay(dmt8, NULL);
ok(hr == S_OK, "IDirectMusicTrack8_EndPlay failed: %08x\n", hr);
- todo_wine {
hr = IDirectMusicTrack8_Play(dmt8, NULL, 0, 0, 0, 0, NULL, NULL, 0);
+ todo_wine
ok(hr == DMUS_S_END, "IDirectMusicTrack8_Play failed: %08x\n", hr);
hr = IDirectMusicTrack8_GetParam(dmt8, NULL, 0, NULL, NULL);
ok(hr == E_POINTER, "IDirectMusicTrack8_GetParam failed: %08x\n", hr);
hr = IDirectMusicTrack8_SetParam(dmt8, NULL, 0, NULL);
ok(hr == E_POINTER, "IDirectMusicTrack8_SetParam failed: %08x\n", hr);
- }
hr = IDirectMusicTrack8_IsParamSupported(dmt8, NULL);
ok(hr == E_POINTER, "IDirectMusicTrack8_IsParamSupported failed: %08x\n", hr);
for (i = 0; i < ARRAY_SIZE(param_types); i++) {
hr = IDirectMusicTrack8_IsParamSupported(dmt8, param_types[i].type);
- if (param_types[i].supported)
+ if (param_types[i].supported) {
ok(hr == S_OK, "IsParamSupported(%s) failed: %08x, expected S_OK\n",
param_types[i].name, hr);
- else
+ hr = IDirectMusicTrack8_GetParam(dmt8, param_types[i].type, 0, NULL, buf);
+ if (param_types[i].type != &GUID_BandParam)
+ ok(hr == DMUS_E_GET_UNSUPPORTED,
+ "GetParam(%s) failed: %08x, expected DMUS_E_GET_UNSUPPORTED\n",
+ param_types[i].name, hr);
+ } else {
ok(hr == DMUS_E_TYPE_UNSUPPORTED,
"IsParamSupported(%s) failed: %08x, expected DMUS_E_TYPE_UNSUPPORTED\n",
param_types[i].name, hr);
+ hr = IDirectMusicTrack8_GetParam(dmt8, param_types[i].type, 0, NULL, buf);
+ ok(hr == DMUS_E_GET_UNSUPPORTED,
+ "GetParam(%s) failed: %08x, expected DMUS_E_GET_UNSUPPORTED\n",
+ param_types[i].name, hr);
+ hr = IDirectMusicTrack8_SetParam(dmt8, param_types[i].type, 0, buf);
+ ok(hr == DMUS_E_TYPE_UNSUPPORTED,
+ "SetParam(%s) failed: %08x, expected DMUS_E_TYPE_UNSUPPORTED\n",
+ param_types[i].name, hr);
+ }
}
hr = IDirectMusicTrack8_AddNotificationType(dmt8, NULL);
--
2.23.0
Dec. 9, 2019
Re: [PATCH v2 2/4] ntdll: Support creating processes with specified parent.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61718
Your paranoid android.
=== w1064v1507 (32 bit report) ===
Report errors:
kernel32:process is missing some failure messages
Dec. 9, 2019
[PATCH v2 4/4] kernel32/tests: Test std handle inheritance in test_parent_process_attribute().
by Paul Gofman
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
v2:
- added test.
dlls/kernel32/tests/process.c | 55 ++++++++++++++++++++++++++++-------
1 file changed, 45 insertions(+), 10 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 4b18b70882..7ca38c63e9 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -92,6 +92,7 @@ static SIZE_T (WINAPI *pGetLargePageMinimum)(void);
static BOOL (WINAPI *pInitializeProcThreadAttributeList)(struct _PROC_THREAD_ATTRIBUTE_LIST*, DWORD, DWORD, SIZE_T*);
static BOOL (WINAPI *pUpdateProcThreadAttribute)(struct _PROC_THREAD_ATTRIBUTE_LIST*, DWORD, DWORD_PTR, void *,SIZE_T,void*,SIZE_T*);
static void (WINAPI *pDeleteProcThreadAttributeList)(struct _PROC_THREAD_ATTRIBUTE_LIST*);
+static DWORD (WINAPI *pGetFinalPathNameByHandleA)(HANDLE, LPSTR, DWORD, DWORD);
/* ############################### */
static char base[MAX_PATH];
@@ -259,6 +260,7 @@ static BOOL init(void)
pInitializeProcThreadAttributeList = (void *)GetProcAddress(hkernel32, "InitializeProcThreadAttributeList");
pUpdateProcThreadAttribute = (void *)GetProcAddress(hkernel32, "UpdateProcThreadAttribute");
pDeleteProcThreadAttributeList = (void *)GetProcAddress(hkernel32, "DeleteProcThreadAttributeList");
+ pGetFinalPathNameByHandleA = (void *)GetProcAddress(hkernel32, "GetFinalPathNameByHandleA");
return TRUE;
}
@@ -3827,7 +3829,7 @@ static void test_ProcThreadAttributeList(void)
* level 2: Process created by level 1 process with handle inheritance and level 0
* process parent substitute.
* level 255: Process created by level 1 process during invalid parent handles testing. */
-void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
+void test_parent_process_attribute(unsigned int level, HANDLE read_pipe, HANDLE creator_stdhandle)
{
PROCESS_BASIC_INFORMATION pbi;
char buffer[MAX_PATH + 64];
@@ -3837,7 +3839,9 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
STARTUPINFOEXA si;
DWORD parent_id;
NTSTATUS status;
+ DWORD exit_code;
ULONG pbi_size;
+ HANDLE hstderr;
HANDLE parent;
DWORD size;
BOOL ret;
@@ -3885,8 +3889,24 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
if (level == 2)
{
+ char file_path[MAX_PATH];
+
ok(parent_id == parent_data.parent_id, "Got parent id %u, parent_data.parent_id %u.\n",
parent_id, parent_data.parent_id);
+
+ GetStartupInfoA(&si.StartupInfo);
+ hstderr = si.StartupInfo.hStdError;
+
+ /* On Windows, std handle values are copied from creator process but seems not to be inherited from it.
+ * Some operation on such handle may sometimes succeed, but various way of quering information
+ * from such handle suggest that the handle refers to some other object.
+ * Windows seem to just keep the handle value, even for invalid handle. It does not always work exacly
+ * like that in Wine now due to special handling of console handles in kernelbase/process.c:create_process_params()
+ * and initialization in dlls/msvcrt: msvcrt_init_io(). */
+ ok(hstderr == creator_stdhandle, "Unexpected hstderr %p, creator_hstdhandle %p.\n",
+ hstderr, creator_stdhandle);
+ size = pGetFinalPathNameByHandleA(hstderr, file_path, sizeof(file_path), FILE_NAME_NORMALIZED);
+ ok(!size, "Got unexpected size %u.\n", size);
return;
}
@@ -3902,7 +3922,7 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
- sprintf(buffer, "\"%s\" tests/process.c parent %u %p", selfname, 255, read_pipe);
+ sprintf(buffer, "\"%s\" tests/process.c parent %u %p %p", selfname, 255, read_pipe, NULL);
#if 0
/* Crashes on some Windows installations, otherwise successfully creates process. */
@@ -3990,9 +4010,17 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
&parent, sizeof(parent), NULL, NULL);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+ hstderr = CreateFileA("stderr_1.tmp", GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa,
+ CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE, NULL);
+ ok(hstderr != INVALID_HANDLE_VALUE, "Could not create file, GetLastError() %u.\n", GetLastError());
+ si.StartupInfo.dwFlags = STARTF_USESTDHANDLES;
+ si.StartupInfo.hStdError = hstderr;
+ si.StartupInfo.hStdOutput = creator_stdhandle;
}
- sprintf(buffer, "\"%s\" tests/process.c parent %u %p", selfname, level + 1, read_pipe);
+ sprintf(buffer, "\"%s\" tests/process.c parent %u %p %p", selfname, level + 1, read_pipe,
+ level ? hstderr : GetStdHandle(STD_OUTPUT_HANDLE));
ret = CreateProcessA(NULL, buffer, NULL, NULL, level == 1, level == 1 ? EXTENDED_STARTUPINFO_PRESENT : 0,
NULL, NULL, (STARTUPINFOA *)&si, &info);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
@@ -4010,10 +4038,16 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
/* wait for child to terminate */
ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ GetExitCodeProcess(info.hProcess, &exit_code);
+ ok(!exit_code, "Child test failed, exit_code %#x.\n", exit_code);
+
CloseHandle(info.hThread);
CloseHandle(info.hProcess);
-
- if (!level)
+ if (level)
+ {
+ CloseHandle(hstderr);
+ }
+ else
{
CloseHandle(read_pipe);
CloseHandle(write_pipe);
@@ -4064,12 +4098,13 @@ START_TEST(process)
CloseHandle(info.hThread);
return;
}
- else if (!strcmp(myARGV[2], "parent") && myARGC >= 5)
+ else if (!strcmp(myARGV[2], "parent") && myARGC >= 6)
{
- HANDLE h;
+ HANDLE h1, h2;
- sscanf(myARGV[4], "%p", &h);
- test_parent_process_attribute(atoi(myARGV[3]), h);
+ sscanf(myARGV[4], "%p", &h1);
+ sscanf(myARGV[5], "%p", &h2);
+ test_parent_process_attribute(atoi(myARGV[3]), h1, h2);
return;
}
@@ -4138,5 +4173,5 @@ START_TEST(process)
test_jobInheritance(job);
test_BreakawayOk(job);
CloseHandle(job);
- test_parent_process_attribute(0, NULL);
+ test_parent_process_attribute(0, NULL, NULL);
}
--
2.23.0
Dec. 9, 2019
[PATCH v2 3/4] kernel32/tests: Test invalid parent handle in test_parent_process_attribute().
by Paul Gofman
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
v2:
- no changes.
dlls/kernel32/tests/process.c | 87 ++++++++++++++++++++++++++++++++++-
1 file changed, 86 insertions(+), 1 deletion(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 6d7a9a74c3..4b18b70882 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -3825,7 +3825,8 @@ static void test_ProcThreadAttributeList(void)
/* level 0: Main test process
* level 1: Process created by level 0 process without handle inheritance
* level 2: Process created by level 1 process with handle inheritance and level 0
- * process parent substitute. */
+ * process parent substitute.
+ * level 255: Process created by level 1 process during invalid parent handles testing. */
void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
{
PROCESS_BASIC_INFORMATION pbi;
@@ -3848,6 +3849,9 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
}
parent_data;
+ if (level == 255)
+ return;
+
if (!pInitializeProcThreadAttributeList)
{
win_skip("No support for ProcThreadAttributeList.\n");
@@ -3891,11 +3895,92 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
if (level)
{
+ HANDLE handle;
SIZE_T size;
ret = pInitializeProcThreadAttributeList(NULL, 1, 0, &size);
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
"Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+ sprintf(buffer, "\"%s\" tests/process.c parent %u %p", selfname, 255, read_pipe);
+
+#if 0
+ /* Crashes on some Windows installations, otherwise successfully creates process. */
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ CloseHandle(info.hThread);
+ CloseHandle(info.hProcess);
+#endif
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = INVALID_HANDLE_VALUE;
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ /* Broken on w7u/w8. */
+ ok((!ret && GetLastError() == ERROR_INVALID_HANDLE) || broken(ret),
+ "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ if (ret)
+ {
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ CloseHandle(info.hThread);
+ CloseHandle(info.hProcess);
+ }
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = (HANDLE)0xdeadbeef;
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = NULL;
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ ok(!ret && GetLastError() == ERROR_INVALID_HANDLE, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ handle = GetCurrentProcess();
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &handle, sizeof(handle), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, TRUE, EXTENDED_STARTUPINFO_PRESENT,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ /* Broken on w7u/w8. */
+ ok((!ret && GetLastError() == ERROR_INVALID_HANDLE) || broken(ret),
+ "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ if (ret)
+ {
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ CloseHandle(info.hThread);
+ CloseHandle(info.hProcess);
+ }
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+
si.lpAttributeList = heap_alloc(size);
ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
--
2.23.0
Dec. 9, 2019
[PATCH v2 2/4] ntdll: Support creating processes with specified parent.
by Paul Gofman
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=47817
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
v2:
- don't use arbitrary thread as parent.
dlls/kernel32/tests/process.c | 4 ++--
dlls/ntdll/process.c | 11 +++++++++--
include/wine/server_protocol.h | 4 +++-
server/console.c | 32 ++++++++++++++++----------------
server/process.c | 30 ++++++++++++++++++++++++------
server/process.h | 3 ++-
server/protocol.def | 1 +
server/request.h | 17 +++++++++--------
server/trace.c | 3 ++-
server/user.h | 3 ++-
server/winstation.c | 24 ++++++++++++++++--------
11 files changed, 86 insertions(+), 46 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index 3efbfa2402..6d7a9a74c3 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -3874,14 +3874,14 @@ void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
memset(&parent_data, 0, sizeof(parent_data));
ret = ReadFile(read_pipe, &parent_data, sizeof(parent_data), &size, NULL);
- todo_wine_if(level == 2) ok((level == 2 && ret) || (level == 1 && !ret && GetLastError() == ERROR_INVALID_HANDLE),
+ ok((level == 2 && ret) || (level == 1 && !ret && GetLastError() == ERROR_INVALID_HANDLE),
"Got unexpected ret %#x, level %u, GetLastError() %u.\n",
ret, level, GetLastError());
}
if (level == 2)
{
- todo_wine ok(parent_id == parent_data.parent_id, "Got parent id %u, parent_data.parent_id %u.\n",
+ ok(parent_id == parent_data.parent_id, "Got parent id %u, parent_data.parent_id %u.\n",
parent_id, parent_data.parent_id);
return;
}
diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index 52d7ea429e..5d75a27e97 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -1667,8 +1667,14 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
RtlNormalizeProcessParams( params );
- TRACE( "%s image %s cmdline %s\n", debugstr_us( path ),
- debugstr_us( ¶ms->ImagePathName ), debugstr_us( ¶ms->CommandLine ));
+ TRACE( "%s image %s cmdline %s, parent %p.\n", debugstr_us( path ),
+ debugstr_us( ¶ms->ImagePathName ), debugstr_us( ¶ms->CommandLine ), parent);
+
+ if (parent == INVALID_HANDLE_VALUE)
+ {
+ memset(info, 0, sizeof(*info));
+ return STATUS_INVALID_HANDLE;
+ }
if ((status = get_pe_file_info( path, attributes, &file_handle, &pe_info )))
{
@@ -1709,6 +1715,7 @@ NTSTATUS WINAPI RtlCreateUserProcess( UNICODE_STRING *path, ULONG attributes,
SERVER_START_REQ( new_process )
{
+ req->parent_process = wine_server_obj_handle(parent);
req->inherit_all = inherit;
req->create_flags = params->DebugFlags; /* hack: creation flags stored in DebugFlags for now */
req->socket_fd = socketfd[1];
diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h
index aaa5fd2e33..98ecd98b08 100644
--- a/include/wine/server_protocol.h
+++ b/include/wine/server_protocol.h
@@ -769,6 +769,7 @@ struct rawinput_device
struct new_process_request
{
struct request_header __header;
+ obj_handle_t parent_process;
int inherit_all;
unsigned int create_flags;
int socket_fd;
@@ -779,6 +780,7 @@ struct new_process_request
/* VARARG(objattr,object_attributes); */
/* VARARG(info,startup_info,info_size); */
/* VARARG(env,unicode_str); */
+ char __pad_44[4];
};
struct new_process_reply
{
@@ -6702,6 +6704,6 @@ union generic_reply
struct resume_process_reply resume_process_reply;
};
-#define SERVER_PROTOCOL_VERSION 593
+#define SERVER_PROTOCOL_VERSION 594
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
diff --git a/server/console.c b/server/console.c
index 59f8843a75..691a0bf05a 100644
--- a/server/console.c
+++ b/server/console.c
@@ -504,37 +504,37 @@ int free_console( struct process *process )
* 2/ parent is a renderer which launches process, and process should attach to the console
* rendered by parent
*/
-void inherit_console(struct thread *parent_thread, struct process *process, obj_handle_t hconin)
+void inherit_console(struct thread *parent_thread, struct process *parent, struct process *process,
+ obj_handle_t hconin)
{
int done = 0;
- struct process* parent = parent_thread->process;
/* if parent is a renderer, then attach current process to its console
* a bit hacky....
*/
- if (hconin)
+ if (hconin && parent_thread)
{
- struct console_input* console;
+ struct console_input *console;
/* FIXME: should we check some access rights ? */
- if ((console = (struct console_input*)get_handle_obj( parent, hconin,
- 0, &console_input_ops )))
- {
+ if ((console = (struct console_input *)get_handle_obj( parent, hconin,
+ 0, &console_input_ops )))
+ {
if (console->renderer == parent_thread)
- {
- process->console = (struct console_input*)grab_object( console );
- process->console->num_proc++;
- done = 1;
- }
- release_object( console );
- }
+ {
+ process->console = (struct console_input*)grab_object( console );
+ process->console->num_proc++;
+ done = 1;
+ }
+ release_object( console );
+ }
else clear_error(); /* ignore error */
}
/* otherwise, if parent has a console, attach child to this console */
if (!done && parent->console)
{
- process->console = (struct console_input*)grab_object( parent->console );
- process->console->num_proc++;
+ process->console = (struct console_input*)grab_object( parent->console );
+ process->console->num_proc++;
}
}
diff --git a/server/process.c b/server/process.c
index 16bb5d57e7..00ea45b068 100644
--- a/server/process.c
+++ b/server/process.c
@@ -1117,6 +1117,7 @@ DECL_HANDLER(new_process)
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
struct process *process = NULL;
struct process *parent = current->process;
+ struct thread *parent_thread = current;
int socket_fd = thread_get_inflight_fd( current, req->socket_fd );
if (socket_fd == -1)
@@ -1148,11 +1149,26 @@ DECL_HANDLER(new_process)
return;
}
+ if (req->parent_process)
+ {
+ if (!(parent = get_process_from_handle( req->parent_process, PROCESS_CREATE_PROCESS)))
+ {
+ set_error(STATUS_INVALID_HANDLE);
+ close(socket_fd);
+ return;
+ }
+ parent_thread = NULL;
+ }
+
if (parent->job && (req->create_flags & CREATE_BREAKAWAY_FROM_JOB) &&
!(parent->job->limit_flags & (JOB_OBJECT_LIMIT_BREAKAWAY_OK | JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK)))
{
set_error( STATUS_ACCESS_DENIED );
close( socket_fd );
+
+ if (req->parent_process)
+ release_object(parent);
+
return;
}
@@ -1222,7 +1238,7 @@ DECL_HANDLER(new_process)
}
/* connect to the window station */
- connect_process_winstation( process, current );
+ connect_process_winstation( process, parent_thread, parent );
/* set the process console */
if (!(req->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE)))
@@ -1231,7 +1247,7 @@ DECL_HANDLER(new_process)
* like if hConOut and hConIn are console handles, then they should be on the same
* physical console
*/
- inherit_console( current, process, req->inherit_all ? info->data->hstdin : 0 );
+ inherit_console( parent_thread, parent, process, req->inherit_all ? info->data->hstdin : 0 );
}
if (!req->inherit_all && !(req->create_flags & CREATE_NEW_CONSOLE))
@@ -1246,16 +1262,15 @@ DECL_HANDLER(new_process)
if (get_error() == STATUS_INVALID_HANDLE ||
get_error() == STATUS_OBJECT_TYPE_MISMATCH) clear_error();
}
-
/* attach to the debugger if requested */
if (req->create_flags & (DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS))
{
set_process_debugger( process, current );
process->debug_children = !(req->create_flags & DEBUG_ONLY_THIS_PROCESS);
}
- else if (parent->debugger && parent->debug_children)
+ else if (current->process->debugger && current->process->debug_children)
{
- set_process_debugger( process, parent->debugger );
+ set_process_debugger( process, current->process->debugger );
/* debug_children is set to 1 by default */
}
@@ -1265,9 +1280,12 @@ DECL_HANDLER(new_process)
info->process = (struct process *)grab_object( process );
reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
reply->pid = get_process_id( process );
- reply->handle = alloc_handle_no_access_check( parent, process, req->access, objattr->attributes );
+ reply->handle = alloc_handle_no_access_check( current->process, process, req->access, objattr->attributes );
done:
+ if (req->parent_process)
+ release_object(parent);
+
if (process) release_object( process );
release_object( info );
}
diff --git a/server/process.h b/server/process.h
index 20ff6beda6..d8453eeaf2 100644
--- a/server/process.h
+++ b/server/process.h
@@ -141,7 +141,8 @@ extern struct process_snapshot *process_snap( int *count );
extern void enum_processes( int (*cb)(struct process*, void*), void *user);
/* console functions */
-extern void inherit_console(struct thread *parent_thread, struct process *process, obj_handle_t hconin);
+extern void inherit_console(struct thread *parent_thread, struct process *parent,
+ struct process *process, obj_handle_t hconin);
extern int free_console( struct process *process );
extern struct thread *console_get_renderer( struct console_input *console );
diff --git a/server/protocol.def b/server/protocol.def
index 1cb1fea602..7f9ec3a149 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -783,6 +783,7 @@ struct rawinput_device
/* Create a new process from the context of the parent */
@REQ(new_process)
+ obj_handle_t parent_process; /* parent process */
int inherit_all; /* inherit all handles from parent */
unsigned int create_flags; /* creation flags */
int socket_fd; /* file descriptor for process socket */
diff --git a/server/request.h b/server/request.h
index 90a3180a6c..9f36bcb711 100644
--- a/server/request.h
+++ b/server/request.h
@@ -745,14 +745,15 @@ C_ASSERT( sizeof(unsigned char) == 1 );
C_ASSERT( sizeof(unsigned int) == 4 );
C_ASSERT( sizeof(unsigned short) == 2 );
C_ASSERT( sizeof(user_handle_t) == 4 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 12 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 16 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 20 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 24 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 28 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 32 );
-C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 36 );
-C_ASSERT( sizeof(struct new_process_request) == 40 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, parent_process) == 12 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 16 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 20 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 24 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 28 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 32 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 36 );
+C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 40 );
+C_ASSERT( sizeof(struct new_process_request) == 48 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, info) == 8 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, pid) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, handle) == 16 );
diff --git a/server/trace.c b/server/trace.c
index 411369a4f6..026aba9c50 100644
--- a/server/trace.c
+++ b/server/trace.c
@@ -1243,7 +1243,8 @@ typedef void (*dump_func)( const void *req );
static void dump_new_process_request( const struct new_process_request *req )
{
- fprintf( stderr, " inherit_all=%d", req->inherit_all );
+ fprintf( stderr, " parent_process=%04x", req->parent_process );
+ fprintf( stderr, ", inherit_all=%d", req->inherit_all );
fprintf( stderr, ", create_flags=%08x", req->create_flags );
fprintf( stderr, ", socket_fd=%d", req->socket_fd );
fprintf( stderr, ", exe_file=%04x", req->exe_file );
diff --git a/server/user.h b/server/user.h
index eb1b7ce1e4..35184d8780 100644
--- a/server/user.h
+++ b/server/user.h
@@ -183,7 +183,8 @@ extern client_ptr_t get_class_client_ptr( struct window_class *class );
extern struct desktop *get_desktop_obj( struct process *process, obj_handle_t handle, unsigned int access );
extern struct winstation *get_process_winstation( struct process *process, unsigned int access );
extern struct desktop *get_thread_desktop( struct thread *thread, unsigned int access );
-extern void connect_process_winstation( struct process *process, struct thread *parent );
+extern void connect_process_winstation( struct process *process, struct thread *parent_thread,
+ struct process *parent_process );
extern void set_process_default_desktop( struct process *process, struct desktop *desktop,
obj_handle_t handle );
extern void close_process_desktop( struct process *process );
diff --git a/server/winstation.c b/server/winstation.c
index a09ca03e3b..f7932a9dc6 100644
--- a/server/winstation.c
+++ b/server/winstation.c
@@ -372,7 +372,8 @@ void set_process_default_desktop( struct process *process, struct desktop *deskt
}
/* connect a process to its window station */
-void connect_process_winstation( struct process *process, struct thread *parent )
+void connect_process_winstation( struct process *process, struct thread *parent_thread,
+ struct process *parent_process)
{
struct winstation *winstation = NULL;
struct desktop *desktop = NULL;
@@ -383,9 +384,9 @@ void connect_process_winstation( struct process *process, struct thread *parent
{
winstation = (struct winstation *)get_handle_obj( process, handle, 0, &winstation_ops );
}
- else if (parent && parent->process->winstation)
+ else if (parent_process->winstation)
{
- handle = duplicate_handle( parent->process, parent->process->winstation,
+ handle = duplicate_handle( parent_process, parent_process->winstation,
process, 0, 0, DUP_HANDLE_SAME_ACCESS );
winstation = (struct winstation *)get_handle_obj( process, handle, 0, &winstation_ops );
}
@@ -397,14 +398,21 @@ void connect_process_winstation( struct process *process, struct thread *parent
desktop = get_desktop_obj( process, handle, 0 );
if (!desktop || desktop->winstation != winstation) goto done;
}
- else if (parent && parent->desktop)
+ else
{
- desktop = get_desktop_obj( parent->process, parent->desktop, 0 );
+ if (parent_thread && parent_thread->desktop)
+ handle = parent_thread->desktop;
+ else if (parent_process->desktop)
+ handle = parent_process->desktop;
+ else
+ goto done;
+
+ desktop = get_desktop_obj( parent_process, handle, 0 );
+
if (!desktop || desktop->winstation != winstation) goto done;
- handle = duplicate_handle( parent->process, parent->desktop,
- process, 0, 0, DUP_HANDLE_SAME_ACCESS );
- }
+ handle = duplicate_handle( parent_process, handle, process, 0, 0, DUP_HANDLE_SAME_ACCESS );
+ }
if (handle) set_process_default_desktop( process, desktop, handle );
done:
--
2.23.0
Dec. 9, 2019
[PATCH v2 1/4] kernelbase: Support PROC_THREAD_ATTRIBUTE_PARENT_PROCESS in CreateProcessInternalW().
by Paul Gofman
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
v2:
- don't use INVALID_HANDLE_VALUE to return an error on zero parent.
dlls/kernelbase/process.c | 88 ++++++++++++++++++++++++++-------------
1 file changed, 59 insertions(+), 29 deletions(-)
diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c
index 90ea299416..d6106eb5f6 100644
--- a/dlls/kernelbase/process.c
+++ b/dlls/kernelbase/process.c
@@ -244,7 +244,7 @@ static RTL_USER_PROCESS_PARAMETERS *create_process_params( const WCHAR *filename
*/
static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES *tsa,
BOOL inherit, DWORD flags, RTL_USER_PROCESS_PARAMETERS *params,
- RTL_USER_PROCESS_INFORMATION *info )
+ RTL_USER_PROCESS_INFORMATION *info, HANDLE parent )
{
NTSTATUS status;
UNICODE_STRING nameW;
@@ -257,7 +257,7 @@ static NTSTATUS create_nt_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTES
status = RtlCreateUserProcess( &nameW, OBJ_CASE_INSENSITIVE, params,
psa ? psa->lpSecurityDescriptor : NULL,
tsa ? tsa->lpSecurityDescriptor : NULL,
- 0, inherit, 0, 0, info );
+ parent, inherit, 0, 0, info );
RtlFreeUnicodeString( &nameW );
}
return status;
@@ -288,7 +288,7 @@ static NTSTATUS create_vdm_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE
winevdm, params->ImagePathName.Buffer, params->CommandLine.Buffer );
RtlInitUnicodeString( ¶ms->ImagePathName, winevdm );
RtlInitUnicodeString( ¶ms->CommandLine, newcmdline );
- status = create_nt_process( psa, tsa, inherit, flags, params, info );
+ status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL );
HeapFree( GetProcessHeap(), 0, newcmdline );
return status;
}
@@ -316,7 +316,7 @@ static NTSTATUS create_cmd_process( SECURITY_ATTRIBUTES *psa, SECURITY_ATTRIBUTE
swprintf( newcmdline, len, L"%s /s/c \"%s\"", comspec, params->CommandLine.Buffer );
RtlInitUnicodeString( ¶ms->ImagePathName, comspec );
RtlInitUnicodeString( ¶ms->CommandLine, newcmdline );
- status = create_nt_process( psa, tsa, inherit, flags, params, info );
+ status = create_nt_process( psa, tsa, inherit, flags, params, info, NULL );
RtlFreeHeap( GetProcessHeap(), 0, newcmdline );
return status;
}
@@ -368,7 +368,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessAsUserW( HANDLE token, const WCHAR *a
inherit, flags, env, cur_dir, startup_info, info, NULL );
}
-
/**********************************************************************
* CreateProcessInternalA (kernelbase.@)
*/
@@ -382,7 +381,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalA( HANDLE token, const char *
BOOL ret = FALSE;
WCHAR *app_nameW = NULL, *cmd_lineW = NULL, *cur_dirW = NULL;
UNICODE_STRING desktopW, titleW;
- STARTUPINFOW infoW;
+ STARTUPINFOEXW infoW;
desktopW.Buffer = NULL;
titleW.Buffer = NULL;
@@ -393,12 +392,15 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalA( HANDLE token, const char *
if (startup_info->lpDesktop) RtlCreateUnicodeStringFromAsciiz( &desktopW, startup_info->lpDesktop );
if (startup_info->lpTitle) RtlCreateUnicodeStringFromAsciiz( &titleW, startup_info->lpTitle );
- memcpy( &infoW, startup_info, sizeof(infoW) );
- infoW.lpDesktop = desktopW.Buffer;
- infoW.lpTitle = titleW.Buffer;
+ memcpy( &infoW.StartupInfo, startup_info, sizeof(infoW.StartupInfo) );
+ infoW.StartupInfo.lpDesktop = desktopW.Buffer;
+ infoW.StartupInfo.lpTitle = titleW.Buffer;
+
+ if (flags & EXTENDED_STARTUPINFO_PRESENT)
+ infoW.lpAttributeList = ((STARTUPINFOEXW *)startup_info)->lpAttributeList;
ret = CreateProcessInternalW( token, app_nameW, cmd_lineW, process_attr, thread_attr,
- inherit, flags, env, cur_dirW, &infoW, info, new_token );
+ inherit, flags, env, cur_dirW, (STARTUPINFOW *)&infoW, info, new_token );
done:
RtlFreeHeap( GetProcessHeap(), 0, app_nameW );
RtlFreeHeap( GetProcessHeap(), 0, cmd_lineW );
@@ -408,6 +410,22 @@ done:
return ret;
}
+struct proc_thread_attr
+{
+ DWORD_PTR attr;
+ SIZE_T size;
+ void *value;
+};
+
+struct _PROC_THREAD_ATTRIBUTE_LIST
+{
+ DWORD mask; /* bitmask of items in list */
+ DWORD size; /* max number of items in list */
+ DWORD count; /* number of items in list */
+ DWORD pad;
+ DWORD_PTR unk;
+ struct proc_thread_attr attrs[1];
+};
/**********************************************************************
* CreateProcessInternalW (kernelbase.@)
@@ -423,6 +441,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
WCHAR *p, *tidy_cmdline = cmd_line;
RTL_USER_PROCESS_PARAMETERS *params = NULL;
RTL_USER_PROCESS_INFORMATION rtl_info;
+ HANDLE parent = NULL;
NTSTATUS status;
/* Process the AppName and/or CmdLine to get module name and path */
@@ -473,7 +492,36 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR
goto done;
}
- status = create_nt_process( process_attr, thread_attr, inherit, flags, params, &rtl_info );
+ if (flags & EXTENDED_STARTUPINFO_PRESENT)
+ {
+ struct _PROC_THREAD_ATTRIBUTE_LIST *attrs =
+ (struct _PROC_THREAD_ATTRIBUTE_LIST *)((STARTUPINFOEXW *)startup_info)->lpAttributeList;
+ unsigned int i;
+
+ if (attrs)
+ {
+ for (i = 0; i < attrs->count; ++i)
+ {
+ switch(attrs->attrs[i].attr)
+ {
+ case PROC_THREAD_ATTRIBUTE_PARENT_PROCESS:
+ parent = *(HANDLE *)attrs->attrs[i].value;
+ TRACE("PROC_THREAD_ATTRIBUTE_PARENT_PROCESS parent %p.\n", parent);
+ if (!parent)
+ {
+ status = STATUS_INVALID_HANDLE;
+ goto done;
+ }
+ break;
+ default:
+ FIXME("Unsupported attribute %#lx.\n", attrs->attrs[i].attr);
+ break;
+ }
+ }
+ }
+ }
+
+ status = create_nt_process( process_attr, thread_attr, inherit, flags, params, &rtl_info, parent );
switch (status)
{
case STATUS_SUCCESS:
@@ -1301,24 +1349,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetEnvironmentVariableW( LPCWSTR name, LPCWSTR val
* Process/thread attribute lists
***********************************************************************/
-
-struct proc_thread_attr
-{
- DWORD_PTR attr;
- SIZE_T size;
- void *value;
-};
-
-struct _PROC_THREAD_ATTRIBUTE_LIST
-{
- DWORD mask; /* bitmask of items in list */
- DWORD size; /* max number of items in list */
- DWORD count; /* number of items in list */
- DWORD pad;
- DWORD_PTR unk;
- struct proc_thread_attr attrs[1];
-};
-
/***********************************************************************
* InitializeProcThreadAttributeList (kernelbase.@)
*/
--
2.23.0
Dec. 9, 2019
[PATCH] msado15: Print the debug strings and not the pointers to them
by Michael Stefaniuc
Signed-off-by: Michael Stefaniuc <mstefani(a)winehq.org>
---
dlls/msado15/connection.c | 2 +-
dlls/msado15/stream.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/msado15/connection.c b/dlls/msado15/connection.c
index f33bc89a1a..ec8f907322 100644
--- a/dlls/msado15/connection.c
+++ b/dlls/msado15/connection.c
@@ -186,7 +186,7 @@ static HRESULT WINAPI connection_RollbackTrans( _Connection *iface )
static HRESULT WINAPI connection_Open( _Connection *iface, BSTR connect_str, BSTR userid, BSTR password,
LONG options )
{
- FIXME( "%p, %s, %s, %p, %08x\n", iface, debugstr_w(connect_str), debugstr_w(userid),
+ FIXME( "%p, %s, %s, %s, %08x\n", iface, debugstr_w(connect_str), debugstr_w(userid),
debugstr_w(password), options );
return E_NOTIMPL;
}
diff --git a/dlls/msado15/stream.c b/dlls/msado15/stream.c
index 8e88b9aa65..0755a199e0 100644
--- a/dlls/msado15/stream.c
+++ b/dlls/msado15/stream.c
@@ -258,7 +258,7 @@ static HRESULT WINAPI stream_ReadText( _Stream *iface, LONG len, BSTR *ret )
static HRESULT WINAPI stream_WriteText( _Stream *iface, BSTR data, StreamWriteEnum options )
{
- FIXME( "%p, %p, %u\n", iface, debugstr_w(data), options );
+ FIXME( "%p, %s, %u\n", iface, debugstr_w(data), options );
return E_NOTIMPL;
}
--
2.23.0
Dec. 9, 2019
[PATCH v2] po: Update Ukrainian translation.
by Andrey Gusev
v2: Added missing '\n' trailing.
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
po/uk.po | 446 ++++++++++++++-----------------------------------------
1 file changed, 111 insertions(+), 335 deletions(-)
diff --git a/po/uk.po b/po/uk.po
index abf9c5e48d..693be57c13 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: Wine\n"
"Report-Msgid-Bugs-To: https://bugs.winehq.org\n"
"POT-Creation-Date: N/A\n"
-"PO-Revision-Date: 2018-12-12 15:58+0200\n"
+"PO-Revision-Date: 2019-12-09 22:24+0200\n"
"Last-Translator: Andrey Gusev <andrey.goosev(a)gmail.com>\n"
"Language-Team: Ukrainian\n"
"Language: uk\n"
@@ -6830,535 +6830,387 @@ msgstr "Відсилання пошти"
#: mferror.mc:249 mferror.mc:256
msgid "Begin request has already been made.\n"
-msgstr ""
+msgstr "Запит вже зроблено.\n"
#: mferror.mc:599
-#, fuzzy
-#| msgid "Already initialized.\n"
msgid "Sink has not been finalized.\n"
-msgstr "Вже ініціалізовано.\n"
+msgstr "Вихід не було завершено.\n"
#: mferror.mc:32
-#, fuzzy
-#| msgid "Installation platform not supported.\n"
msgid "Media Foundation platform is not initialized.\n"
-msgstr "Платформа встановлення не підтримується.\n"
+msgstr "Платформа Media Foundation не ініціалізована.\n"
#: mferror.mc:39
msgid "Buffer is too small.\n"
-msgstr ""
+msgstr "Розмір буфера занадто малий.\n"
#: mferror.mc:46
-#, fuzzy
-#| msgid "Invalid query syntax.\n"
msgid "Invalid request.\n"
-msgstr "Невірний синтаксис запиту.\n"
+msgstr "Невірний запит.\n"
#: mferror.mc:53
-#, fuzzy
-#| msgid "Invalid segment number.\n"
msgid "Invalid stream number.\n"
-msgstr "Невірний номер сегмента.\n"
+msgstr "Невірний номер потоку.\n"
#: mferror.mc:60
-#, fuzzy
-#| msgid "Invalid data type.\n"
msgid "Invalid media type.\n"
msgstr "Невірний тип даних.\n"
#: mferror.mc:67
-#, fuzzy
-#| msgid "Request not accepted.\n"
msgid "No more input is accepted.\n"
-msgstr "Запит не прийнято.\n"
+msgstr "Введення даних більше не приймається.\n"
#: mferror.mc:74
-#, fuzzy
-#| msgid "Already initialized.\n"
msgid "Object is not initialized.\n"
-msgstr "Вже ініціалізовано.\n"
+msgstr "Об'єкт не ініціалізований.\n"
#: mferror.mc:81
-#, fuzzy
-#| msgid "Request not supported.\n"
msgid "Representation is not supported.\n"
-msgstr "Запит не підтримується.\n"
+msgstr "Представлення не підтримується.\n"
#: mferror.mc:88
msgid "No more types in the list of suggested media types.\n"
-msgstr ""
+msgstr "Більше типів даних у запропонованому списку немає.\n"
#: mferror.mc:95
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported service.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримувана служба.\n"
#: mferror.mc:102
-#, fuzzy
-#| msgid "Unexpected network error.\n"
msgid "Unexpected error.\n"
-msgstr "Неочікувана помилка мережі.\n"
+msgstr "Неочікувана помилка.\n"
#: mferror.mc:116
-#, fuzzy
-#| msgid "Invalid time.\n"
msgid "Invalid type.\n"
-msgstr "Невірний час.\n"
+msgstr "Невірний тип.\n"
#: mferror.mc:123
-#, fuzzy
-#| msgid "Invalid number format."
msgid "Invalid file format.\n"
-msgstr "Невірний числовий формат."
+msgstr "Невірний формат файлу.\n"
#: mferror.mc:137
-#, fuzzy
-#| msgid "Invalid time.\n"
msgid "Invalid timestamp.\n"
-msgstr "Невірний час.\n"
+msgstr "Невірна мітка часу.\n"
#: mferror.mc:144
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported scheme.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримувана схема.\n"
#: mferror.mc:151
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported bytestream type.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуваний тип потоку даних.\n"
#: mferror.mc:158
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported time format.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуваний формат часу.\n"
#: mferror.mc:165
msgid "Timestamp is not set for the sample.\n"
-msgstr ""
+msgstr "Часова позначка для зразка не встановлена.\n"
#: mferror.mc:172
msgid "No duration set for the sample.\n"
-msgstr ""
+msgstr "Тривалість для вибірки не встановлена.\n"
#: mferror.mc:179
-#, fuzzy
-#| msgid "Invalid data.\n"
msgid "Invalid stream data.\n"
-msgstr "Невірні дані.\n"
+msgstr "Невірні дані потоку.\n"
#: mferror.mc:186
-#, fuzzy
-#| msgid "Help not available."
msgid "Realtime support is not available.\n"
-msgstr "Довідка недоступна."
+msgstr "Підтримка в режимі реального часу недоступна.\n"
#: mferror.mc:193
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported rate.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуваний темп.\n"
#: mferror.mc:200
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported thinning.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуване проріджування.\n"
#: mferror.mc:207
-#, fuzzy
-#| msgid "Request not supported.\n"
msgid "Reversing is not supported.\n"
-msgstr "Запит не підтримується.\n"
+msgstr "Реверс не підтримується.\n"
#: mferror.mc:214
-#, fuzzy
-#| msgid "Unsupported name syntax.\n"
msgid "Unsupported rate transition.\n"
-msgstr "Непідтримуваний синтаксис імені.\n"
+msgstr "Зміна швидкості не підтримується.\n"
#: mferror.mc:221
msgid "Rate change was preempted.\n"
-msgstr ""
+msgstr "Перешкоджання зміни швидкості.\n"
#: mferror.mc:228
-#, fuzzy
-#| msgid "Sector not found.\n"
msgid "Object or value wasn't found.\n"
-msgstr "Сектор не знайдено.\n"
+msgstr "Об'єкт або значення не знайдено.\n"
#: mferror.mc:235
-#, fuzzy
-#| msgid "Help not available."
msgid "Value is not available.\n"
-msgstr "Довідка недоступна."
+msgstr "Значення недоступне.\n"
#: mferror.mc:242
-#, fuzzy
-#| msgid "Help not available."
msgid "Clock is not available.\n"
-msgstr "Довідка недоступна."
+msgstr "Годинник недоступний.\n"
#: mferror.mc:263
-#, fuzzy
-#| msgid "Request not supported.\n"
msgid "Multiple subscribers are not supported.\n"
-msgstr "Запит не підтримується.\n"
+msgstr "Підтримка декількох користувачів не надається.\n"
#: mferror.mc:270
-#, fuzzy
-#| msgid "The driver was not enabled."
msgid "The timer was orphaned.\n"
-msgstr "Драйвер не підключений."
+msgstr ""
#: mferror.mc:277
msgid "State transition is pending.\n"
-msgstr ""
+msgstr "Очікується зміна стану.\n"
#: mferror.mc:284
-#, fuzzy
-#| msgid "Unsupported name syntax.\n"
msgid "Unsupported state transition.\n"
-msgstr "Непідтримуваний синтаксис імені.\n"
+msgstr "Непідтримувана зміна стану.\n"
#: mferror.mc:291
-#, fuzzy
-#| msgid "An internal error has occurred.\n"
msgid "Unrecoverable error occurred.\n"
-msgstr "Виникла внутрішня помилка.\n"
+msgstr "Виникла критична помилка.\n"
#: mferror.mc:298
msgid "Sample has too many buffers.\n"
-msgstr ""
+msgstr "Зразок має занадто багато буферів.\n"
#: mferror.mc:305
-#, fuzzy
-#| msgid "Temporary directory not writable.\n"
msgid "Sample is not writable.\n"
-msgstr "Тимчасова тека недоступна для запису.\n"
+msgstr "Неможливо записати зразок.\n"
#: mferror.mc:312
-#, fuzzy
-#| msgid "Path is invalid.\n"
msgid "Key is invalid.\n"
-msgstr "Невірний шлях.\n"
+msgstr "Невірний ключ.\n"
#: mferror.mc:319
-#, fuzzy
-#| msgid "Bad network response.\n"
msgid "Bad startup version.\n"
-msgstr "Погана відповідь мережі.\n"
+msgstr "Некоректна версія під час запуску.\n"
#: mferror.mc:326
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported caption.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуваний підпис.\n"
#: mferror.mc:333
-#, fuzzy
-#| msgid "Invalid Option"
msgid "Invalid position.\n"
-msgstr "Невірний параметр"
+msgstr "Невірна позиція.\n"
#: mferror.mc:340
-#, fuzzy
-#| msgid "File not found.\n"
msgid "Attribute is not found.\n"
-msgstr "Файл не знайдено.\n"
+msgstr "Атрибут не знайдено.\n"
#: mferror.mc:347
-#, fuzzy
-#| msgid "Hook type not allowed.\n"
msgid "Property type is not allowed.\n"
-msgstr "Недозволений тип гачка.\n"
+msgstr "Недозволений тип властивості.\n"
#: mferror.mc:354
-#, fuzzy
-#| msgid "Request not supported.\n"
msgid "Property type is not supported.\n"
-msgstr "Запит не підтримується.\n"
+msgstr "Тип властивості не підтримується.\n"
#: mferror.mc:361
-#, fuzzy
-#| msgid "Directory is not empty.\n"
msgid "Property is empty.\n"
-msgstr "Каталог не порожній.\n"
+msgstr "Властивість порожня.\n"
#: mferror.mc:368
-#, fuzzy
-#| msgid "Directory is not empty.\n"
msgid "Property is not empty.\n"
-msgstr "Каталог не порожній.\n"
+msgstr "Властивість не порожня.\n"
#: mferror.mc:375
-#, fuzzy
-#| msgid "Hook type not allowed.\n"
msgid "Vector property is not allowed.\n"
-msgstr "Недозволений тип гачка.\n"
+msgstr "Недозволена векторна властивість.\n"
#: mferror.mc:382
msgid "Vector property is required.\n"
-msgstr ""
+msgstr "Потребується векторна властивість.\n"
#: mferror.mc:389
-#, fuzzy
-#| msgid "Operation canceled by user.\n"
msgid "Operation was cancelled.\n"
-msgstr "Операція скасована користувачем.\n"
+msgstr "Операція була скасована.\n"
#: mferror.mc:396
-#, fuzzy
-#| msgid "Server not disabled.\n"
msgid "Bytestream is not seekable.\n"
-msgstr "Сервер не вимкнений.\n"
+msgstr "Потік не є послідовним.\n"
#: mferror.mc:403
msgid "Platform is disabled in safe mode.\n"
-msgstr ""
+msgstr "Платформа відключена в безпечному режимі.\n"
#: mferror.mc:410
-#, fuzzy
-#| msgid "Cannot create.\n"
msgid "Cannot parse bytestream.\n"
-msgstr "Неможливо створити.\n"
+msgstr "Неможливо розібрати потік даних.\n"
#: mferror.mc:417
msgid "Mutually exclusive flags passed to source resolver.\n"
-msgstr ""
+msgstr "Конфліктні прапори передані до вихідної резолюції.\n"
#: mferror.mc:424
-#, fuzzy
-#| msgid "Unknown interface.\n"
msgid "Unknown bytestream length.\n"
-msgstr "Невідомий інтерфейс.\n"
+msgstr "Невідома довжина потоку.\n"
#: mferror.mc:431
-#, fuzzy
-#| msgid "Invalid index.\n"
msgid "Invalid work queue index.\n"
-msgstr "Невірний індекс.\n"
+msgstr "Невірний індекс черги завдань.\n"
#: mferror.mc:438
-#, fuzzy
-#| msgid "No more data available.\n"
msgid "No events available.\n"
-msgstr "Даних більше немає.\n"
+msgstr "Подій немає.\n"
#: mferror.mc:445
-#, fuzzy
-#| msgid "Unsupported name syntax.\n"
msgid "Invalid media source state transition.\n"
-msgstr "Непідтримуваний синтаксис імені.\n"
+msgstr "Невірна зміна стану джерела медіа.\n"
#: mferror.mc:452
-#, fuzzy
-#| msgid "Registry has been recovered.\n"
msgid "End of media stream has been reached.\n"
-msgstr "Реєстр відновлено.\n"
+msgstr "Досягнуто кінця медіапотоку.\n"
#: mferror.mc:459
msgid "Shutdown() was called.\n"
-msgstr ""
+msgstr "Було викликано Shutdown().\n"
#: mferror.mc:466
-#, fuzzy
-#| msgid "Registry has been recovered.\n"
msgid "Media stream has no duration set.\n"
-msgstr "Реєстр відновлено.\n"
+msgstr "Тривалості для медіапотоку не встановлено.\n"
#: mferror.mc:473
msgid "Media format was recognized but is invalid.\n"
-msgstr ""
+msgstr "Формат медіа був розпізнаний, але він невірний.\n"
#: mferror.mc:480
-#, fuzzy
-#| msgid "Property set not found.\n"
msgid "Property wasn't found.\n"
-msgstr "Набір властивостей не знайдено.\n"
+msgstr "Властивість не знайдено.\n"
#: mferror.mc:487
-#, fuzzy
-#| msgid "Directory is not empty.\n"
msgid "Property is read-only.\n"
-msgstr "Каталог не порожній.\n"
+msgstr "Властивість лише для читання.\n"
#: mferror.mc:494
-#, fuzzy
-#| msgid "Hook type not allowed.\n"
msgid "Property is not allowed.\n"
-msgstr "Недозволений тип гачка.\n"
+msgstr "Недозволена властивість.\n"
#: mferror.mc:501
-#, fuzzy
-#| msgid "Resource in use.\n"
msgid "Media source is not started.\n"
-msgstr "Ресурс використовується.\n"
+msgstr "Джерело медіа не запускається.\n"
#: mferror.mc:508
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported media format.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуваний формат медіа.\n"
#: mferror.mc:515
-#, fuzzy
-#| msgid "Resource in use.\n"
msgid "Media source is in wrong state.\n"
-msgstr "Ресурс використовується.\n"
+msgstr "Невірний стан джерела медіа.\n"
#: mferror.mc:522
-#, fuzzy
-#| msgid "No data detected.\n"
msgid "No media streams were selected.\n"
-msgstr "Даних не виявлено.\n"
+msgstr "Не вибрано потоків медіа.\n"
#: mferror.mc:529
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported media source characteristics.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримувані характеристики джерела медіа.\n"
#: mferror.mc:536
msgid "Stream sink was removed.\n"
-msgstr ""
+msgstr "Вихід потоку даних видалено.\n"
#: mferror.mc:543
msgid "Stream sinks are out of sync.\n"
-msgstr ""
+msgstr "Потік даних не синхронізується.\n"
#: mferror.mc:550
-#, fuzzy
-#| msgid "Registry has been recovered.\n"
msgid "Media sink stream sinks set is fixed.\n"
-msgstr "Реєстр відновлено.\n"
+msgstr "Запис виходу потоку даних медіавиходу неможливо змінити.\n"
#: mferror.mc:557
-#, fuzzy
-#| msgid "Domain already exists.\n"
msgid "Stream sink already exists.\n"
-msgstr "Домен вже існує.\n"
+msgstr "Вихід потоку даних вже існує.\n"
#: mferror.mc:564
-#, fuzzy
-#| msgid "Operation canceled by user.\n"
msgid "Sample allocation was canceled.\n"
-msgstr "Операція скасована користувачем.\n"
+msgstr "Виділення зразка було перервано.\n"
#: mferror.mc:571
-#, fuzzy
-#| msgid "Directory is not empty.\n"
msgid "Sample allocator is empty.\n"
-msgstr "Каталог не порожній.\n"
+msgstr "Розподільник зразків порожній.\n"
#: mferror.mc:578
-#, fuzzy
-#| msgid "Class already exists.\n"
msgid "Sink was already stopped.\n"
-msgstr "Клас вже існує.\n"
+msgstr "Вихід вже було припинино.\n"
#: mferror.mc:585
msgid "Bitrate was unknown for ASF file sink.\n"
-msgstr ""
+msgstr "Невідомий бітрейт для виводу файлу ASF.\n"
#: mferror.mc:592
-#, fuzzy
-#| msgid "No data detected.\n"
msgid "No streams were selected for the sink.\n"
-msgstr "Даних не виявлено.\n"
+msgstr "Для виводу не вибрано потоків даних.\n"
#: mferror.mc:606
-#, fuzzy
-#| msgid "File name is too long.\n"
msgid "Metadata was too long.\n"
-msgstr "Ім'я файлу занадто довге.\n"
+msgstr "Метадані були занадто довгими.\n"
#: mferror.mc:613
msgid "No samples were processed by the sink.\n"
-msgstr ""
+msgstr "Жодні зразки не оброблялися результатами.\n"
#: mferror.mc:620
msgid "Sink was not provided with required headers.\n"
-msgstr ""
+msgstr "Вихідні дані не були забезпечені необхідними заголовками.\n"
#: mferror.mc:627
-#, fuzzy
-#| msgid "Connection invalid.\n"
msgid "Optional node is invalid.\n"
-msgstr "Невірне з'єднання.\n"
+msgstr "Необов’язковий вузол невірний.\n"
#: mferror.mc:634
-#, fuzzy
-#| msgid "Cannot find the printer."
msgid "Cannot find decryptor.\n"
-msgstr "Не вдалось знайти принтер."
+msgstr "Модуль розшифровки не знайдено.\n"
#: mferror.mc:641
-#, fuzzy
-#| msgid "Module not found.\n"
msgid "Codec was not found.\n"
-msgstr "Модуль не знайдено.\n"
+msgstr "Кодек не було знайдено.\n"
#: mferror.mc:648
msgid "Cannot connect topology nodes.\n"
-msgstr ""
+msgstr "Не вдалося підключити топологічні вузли.\n"
#: mferror.mc:655
-#, fuzzy
-#| msgid "Request not supported.\n"
msgid "Topology request is not supported.\n"
-msgstr "Запит не підтримується.\n"
+msgstr "Запит на топологію не підтримується.\n"
#: mferror.mc:662
-#, fuzzy
-#| msgid "Invalid oplock message received.\n"
msgid "Invalid topology time attributes.\n"
-msgstr "Отримане невірне oplock-повідомлення.\n"
+msgstr "Невірні атрибути часу топології.\n"
#: mferror.mc:669
msgid "Found loops in topology.\n"
-msgstr ""
+msgstr "Знайдені петлі в топології.\n"
#: mferror.mc:676
-#, fuzzy
-#| msgid "Installation source is missing.\n"
msgid "Presentation descriptor is missing.\n"
-msgstr "Джерело встановлення втрачене.\n"
+msgstr "Дескриптор презентації відсутній.\n"
#: mferror.mc:683
-#, fuzzy
-#| msgid "Index is missing.\n"
msgid "Stream descriptor is missing.\n"
-msgstr "Індекс загублений.\n"
+msgstr "Дескриптор потоку відсутній.\n"
#: mferror.mc:690
-#, fuzzy
-#| msgid "The device is not connected.\n"
msgid "Stream descriptor is not selected.\n"
-msgstr "Пристрій не під'єднаний.\n"
+msgstr "Дескриптор потоку не вибраний.\n"
#: mferror.mc:697
-#, fuzzy
-#| msgid "Index is missing.\n"
msgid "Source is missing.\n"
-msgstr "Індекс загублений.\n"
+msgstr "Джерело відсутнє.\n"
#: mferror.mc:704
msgid "Topology loader does not support sink activates.\n"
-msgstr ""
+msgstr "Завантажувач топології не підтримує вихідний сигнал.\n"
#: mferror.mc:711
msgid "Clock has no time source set.\n"
-msgstr ""
+msgstr "У годинника немає призначеного джерела часу.\n"
#: mferror.mc:718
-#, fuzzy
-#| msgid "Class already exists.\n"
msgid "Clock state was already set.\n"
-msgstr "Клас вже існує.\n"
+msgstr "Статус годинника вже встановлено.\n"
#: mpr.rc:35 wininet.rc:37
msgid "Enter Network Password"
@@ -9718,16 +9570,12 @@ msgid "Cape Verde Daylight Time"
msgstr ""
#: tzres.rc:74
-#, fuzzy
-#| msgid "Central European"
msgid "Central European Standard Time"
-msgstr "Центральноєвропейський"
+msgstr ""
#: tzres.rc:75
-#, fuzzy
-#| msgid "Central European"
msgid "Central European Daylight Time"
-msgstr "Центральноєвропейський"
+msgstr ""
#: tzres.rc:140
msgid "Morocco Standard Time"
@@ -9738,16 +9586,12 @@ msgid "Morocco Daylight Time"
msgstr ""
#: tzres.rc:72
-#, fuzzy
-#| msgid "Central European"
msgid "Central Europe Standard Time"
-msgstr "Центральноєвропейський"
+msgstr ""
#: tzres.rc:73
-#, fuzzy
-#| msgid "Central European"
msgid "Central Europe Daylight Time"
-msgstr "Центральноєвропейський"
+msgstr ""
#: tzres.rc:118
msgid "Iran Standard Time"
@@ -9782,10 +9626,8 @@ msgid "Mountain Daylight Time (Mexico)"
msgstr ""
#: tzres.rc:106
-#, fuzzy
-#| msgid "&Standard bar"
msgid "GMT Standard Time"
-msgstr "&Стандартна панель"
+msgstr ""
#: tzres.rc:107
msgid "GMT Daylight Time"
@@ -9956,10 +9798,8 @@ msgid "India Daylight Time"
msgstr ""
#: tzres.rc:112
-#, fuzzy
-#| msgid "&Standard bar"
msgid "GTB Standard Time"
-msgstr "&Стандартна панель"
+msgstr ""
#: tzres.rc:113
msgid "GTB Daylight Time"
@@ -10278,10 +10118,8 @@ msgid "Paraguay Daylight Time"
msgstr ""
#: tzres.rc:84
-#, fuzzy
-#| msgid "Date and time"
msgid "Dateline Standard Time"
-msgstr "Дата та час"
+msgstr ""
#: tzres.rc:85
msgid "Dateline Daylight Time"
@@ -10368,16 +10206,12 @@ msgid "Greenland Daylight Time"
msgstr ""
#: tzres.rc:92
-#, fuzzy
-#| msgid "Date and time"
msgid "Easter Island Standard Time"
-msgstr "Дата та час"
+msgstr ""
#: tzres.rc:93
-#, fuzzy
-#| msgid "Date and time"
msgid "Easter Island Daylight Time"
-msgstr "Дата та час"
+msgstr ""
#: tzres.rc:96
msgid "Egypt Standard Time"
@@ -10428,10 +10262,8 @@ msgid "E. Africa Daylight Time"
msgstr ""
#: tzres.rc:102
-#, fuzzy
-#| msgid "&Standard bar"
msgid "FLE Standard Time"
-msgstr "&Стандартна панель"
+msgstr ""
#: tzres.rc:103
msgid "FLE Daylight Time"
@@ -11249,10 +11081,6 @@ msgstr ""
"використовувати їх одночасно."
#: winmm.rc:128
-#, fuzzy
-#| msgid ""
-#| "The specified MIDI port is already in use. Wait until it is free; then "
-#| "try again."
msgid ""
"The specified MIDI port is already in use. Wait until it is free, and then "
"try again."
@@ -11273,10 +11101,6 @@ msgid "An error occurred with the specified port."
msgstr "Сталася помилка зі вказаним портом."
#: winmm.rc:133
-#, fuzzy
-#| msgid ""
-#| "All multimedia timers are being used by other applications. Quit one of "
-#| "these applications; then, try again."
msgid ""
"All multimedia timers are being used by other applications. Quit one of "
"these applications, and then try again."
@@ -15428,7 +15252,7 @@ msgstr "Переглядач звичайних метафайлів"
#: view.rc:50
msgid "Metafiles (*.wmf, *.emf)"
-msgstr ""
+msgstr "Метафайли (*.wmf, *.emf)"
#: wineboot.rc:31
msgid "Waiting for Program"
@@ -15596,16 +15420,12 @@ msgid "Drive configuration"
msgstr "Налаштування привода"
#: winecfg.rc:233
-#, fuzzy
-#| msgid ""
-#| "Failed to connect to the mount manager, the drive configuration cannot be "
-#| "edited."
msgid ""
"Failed to connect to the mount manager; the drive configuration cannot be "
"edited."
msgstr ""
-"Неможливо з'єднатися з менеджером монтування, конфігурація дисків не буде "
-"редагуватися."
+"Неможливо з'єднатися з менеджером монтування, конфігурацію дисків не можна "
+"редагувати."
#: winecfg.rc:236
msgid "A&dd..."
@@ -15891,19 +15711,13 @@ msgid "System drive"
msgstr "Системний диск"
#: winecfg.rc:76
-#, fuzzy
-#| msgid ""
-#| "Are you sure you want to delete drive C?\n"
-#| "\n"
-#| "Most Windows applications expect drive C to exist, and will die messily "
-#| "if it doesn't. If you proceed remember to recreate it!"
msgid ""
"Are you sure you want to delete drive C?\n"
"\n"
"Most Windows applications expect drive C to exist, and will die messily if "
"it doesn't. If you proceed, remember to recreate it!"
msgstr ""
-"Справді видалити диск C?\n"
+"Ви впевнені, що хочете видалити диск C?\n"
"\n"
"Більшість Windows-програм перестануть працювати без диску C. Якщо ви все ж "
"вирішили видалити диск, не забудьте створити новий!"
@@ -16979,10 +16793,8 @@ msgid "Text documents (*.txt)"
msgstr "Текстові документи (*.txt)"
#: wordpad.rc:149
-#, fuzzy
-#| msgid "Unicode text document (*.txt)"
msgid "Unicode text documents (*.txt)"
-msgstr "Текстовий документ Юнікод (*.txt)"
+msgstr "Текстові документи Юнікод (*.txt)"
#: wordpad.rc:150
msgid "Rich text format (*.rtf)"
@@ -17183,42 +16995,6 @@ msgid "D"
msgstr "Д"
#: xcopy.rc:81
-#, fuzzy
-#| msgid ""
-#| "XCOPY - Copies source files or directory trees to a destination.\n"
-#| "\n"
-#| "Syntax:\n"
-#| "XCOPY source [destination] [/I] [/S] [/Q] [/F] [/L] [/W] [/T] [/N] [/U]\n"
-#| "\t [/R] [/H] [/C] [/P] [/A] [/M] [/E] [/D] [/Y] [/-Y]\n"
-#| "\n"
-#| "Where:\n"
-#| "\n"
-#| "[/I] Assume directory if destination does not exist and copying two or\n"
-#| "\tmore files.\n"
-#| "[/S] Copy directories and subdirectories.\n"
-#| "[/E] Copy directories and subdirectories, including any empty ones.\n"
-#| "[/Q] Do not list names during copy, that is be quiet.\n"
-#| "[/F] Show full source and destination names during copy.\n"
-#| "[/L] Simulate operation, showing names which would be copied.\n"
-#| "[/W] Prompts before beginning the copy operation.\n"
-#| "[/T] Creates empty directory structure but does not copy files.\n"
-#| "[/Y] Suppress prompting when overwriting files.\n"
-#| "[/-Y] Enable prompting when overwriting files.\n"
-#| "[/P] Prompts on each source file before copying.\n"
-#| "[/N] Copy using short names.\n"
-#| "[/U] Copy only files which already exist in destination.\n"
-#| "[/R] Overwrite any read only files.\n"
-#| "[/H] Include hidden and system files in the copy.\n"
-#| "[/C] Continue even if an error occurs during the copy.\n"
-#| "[/A] Only copy files with archive attribute set.\n"
-#| "[/M] Only copy files with archive attribute set, removes the\n"
-#| "\tarchive attribute.\n"
-#| "[/K] Copy file attributes, without this attributes are not preserved.\n"
-#| "[/D | /D:m-d-y] Copy new files or those modified after the supplied "
-#| "date.\n"
-#| "\t\tIf no date is supplied, only copy if destination is older\n"
-#| "\t\tthan source.\n"
-#| "\n"
msgid ""
"XCOPY - Copies source files or directory trees to a destination.\n"
"\n"
--
2.23.0
Dec. 9, 2019
Re: [PATCH] po: Update Ukrainian translation.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61708
Your paranoid android.
=== debian10 (build log) ===
Task: The win32 build failed
=== debian10 (build log) ===
Task: The wow64 build failed
Dec. 9, 2019
[PATCH] po: Update Ukrainian translation.
by Andrey Gusev
Signed-off-by: Andrey Gusev <andrey.goosev(a)gmail.com>
---
po/uk.po | 446 ++++++++++++++-----------------------------------------
1 file changed, 111 insertions(+), 335 deletions(-)
diff --git a/po/uk.po b/po/uk.po
index abf9c5e48d..0fc5b2a7ea 100644
--- a/po/uk.po
+++ b/po/uk.po
@@ -5,7 +5,7 @@ msgstr ""
"Project-Id-Version: Wine\n"
"Report-Msgid-Bugs-To: https://bugs.winehq.org\n"
"POT-Creation-Date: N/A\n"
-"PO-Revision-Date: 2018-12-12 15:58+0200\n"
+"PO-Revision-Date: 2019-12-09 22:03+0200\n"
"Last-Translator: Andrey Gusev <andrey.goosev(a)gmail.com>\n"
"Language-Team: Ukrainian\n"
"Language: uk\n"
@@ -6830,535 +6830,387 @@ msgstr "Відсилання пошти"
#: mferror.mc:249 mferror.mc:256
msgid "Begin request has already been made.\n"
-msgstr ""
+msgstr "Запит вже зроблено.\n"
#: mferror.mc:599
-#, fuzzy
-#| msgid "Already initialized.\n"
msgid "Sink has not been finalized.\n"
-msgstr "Вже ініціалізовано.\n"
+msgstr "Вихід не було завершено.\n"
#: mferror.mc:32
-#, fuzzy
-#| msgid "Installation platform not supported.\n"
msgid "Media Foundation platform is not initialized.\n"
-msgstr "Платформа встановлення не підтримується.\n"
+msgstr "Платформа Media Foundation не ініціалізована.\n"
#: mferror.mc:39
msgid "Buffer is too small.\n"
-msgstr ""
+msgstr "Розмір буфера занадто малий.\n"
#: mferror.mc:46
-#, fuzzy
-#| msgid "Invalid query syntax.\n"
msgid "Invalid request.\n"
-msgstr "Невірний синтаксис запиту.\n"
+msgstr "Невірний запит.\n"
#: mferror.mc:53
-#, fuzzy
-#| msgid "Invalid segment number.\n"
msgid "Invalid stream number.\n"
-msgstr "Невірний номер сегмента.\n"
+msgstr "Невірний номер потоку.\n"
#: mferror.mc:60
-#, fuzzy
-#| msgid "Invalid data type.\n"
msgid "Invalid media type.\n"
msgstr "Невірний тип даних.\n"
#: mferror.mc:67
-#, fuzzy
-#| msgid "Request not accepted.\n"
msgid "No more input is accepted.\n"
-msgstr "Запит не прийнято.\n"
+msgstr "Введення даних більше не приймається.\n"
#: mferror.mc:74
-#, fuzzy
-#| msgid "Already initialized.\n"
msgid "Object is not initialized.\n"
-msgstr "Вже ініціалізовано.\n"
+msgstr "Об'єкт не ініціалізований.\n"
#: mferror.mc:81
-#, fuzzy
-#| msgid "Request not supported.\n"
msgid "Representation is not supported.\n"
-msgstr "Запит не підтримується.\n"
+msgstr "Представлення не підтримується.\n"
#: mferror.mc:88
msgid "No more types in the list of suggested media types.\n"
-msgstr ""
+msgstr "Більше типів даних у запропонованому списку немає.\n"
#: mferror.mc:95
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported service.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримувана служба.\n"
#: mferror.mc:102
-#, fuzzy
-#| msgid "Unexpected network error.\n"
msgid "Unexpected error.\n"
-msgstr "Неочікувана помилка мережі.\n"
+msgstr "Неочікувана помилка.\n"
#: mferror.mc:116
-#, fuzzy
-#| msgid "Invalid time.\n"
msgid "Invalid type.\n"
-msgstr "Невірний час.\n"
+msgstr "Невірний тип.\n"
#: mferror.mc:123
-#, fuzzy
-#| msgid "Invalid number format."
msgid "Invalid file format.\n"
-msgstr "Невірний числовий формат."
+msgstr "Невірний формат файлу."
#: mferror.mc:137
-#, fuzzy
-#| msgid "Invalid time.\n"
msgid "Invalid timestamp.\n"
-msgstr "Невірний час.\n"
+msgstr "Невірна мітка часу.\n"
#: mferror.mc:144
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported scheme.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримувана схема.\n"
#: mferror.mc:151
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported bytestream type.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуваний тип потоку даних.\n"
#: mferror.mc:158
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported time format.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуваний формат часу.\n"
#: mferror.mc:165
msgid "Timestamp is not set for the sample.\n"
-msgstr ""
+msgstr "Часова позначка для зразка не встановлена.\n"
#: mferror.mc:172
msgid "No duration set for the sample.\n"
-msgstr ""
+msgstr "Тривалість для вибірки не встановлена.\n"
#: mferror.mc:179
-#, fuzzy
-#| msgid "Invalid data.\n"
msgid "Invalid stream data.\n"
-msgstr "Невірні дані.\n"
+msgstr "Невірні дані потоку.\n"
#: mferror.mc:186
-#, fuzzy
-#| msgid "Help not available."
msgid "Realtime support is not available.\n"
-msgstr "Довідка недоступна."
+msgstr "Підтримка в режимі реального часу недоступна.\n"
#: mferror.mc:193
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported rate.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуваний темп.\n"
#: mferror.mc:200
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported thinning.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуване проріджування.\n"
#: mferror.mc:207
-#, fuzzy
-#| msgid "Request not supported.\n"
msgid "Reversing is not supported.\n"
-msgstr "Запит не підтримується.\n"
+msgstr "Реверс не підтримується.\n"
#: mferror.mc:214
-#, fuzzy
-#| msgid "Unsupported name syntax.\n"
msgid "Unsupported rate transition.\n"
-msgstr "Непідтримуваний синтаксис імені.\n"
+msgstr "Зміна швидкості не підтримується.\n"
#: mferror.mc:221
msgid "Rate change was preempted.\n"
-msgstr ""
+msgstr "Перешкоджання зміни швидкості.\n"
#: mferror.mc:228
-#, fuzzy
-#| msgid "Sector not found.\n"
msgid "Object or value wasn't found.\n"
-msgstr "Сектор не знайдено.\n"
+msgstr "Об'єкт або значення не знайдено.\n"
#: mferror.mc:235
-#, fuzzy
-#| msgid "Help not available."
msgid "Value is not available.\n"
-msgstr "Довідка недоступна."
+msgstr "Значення недоступне."
#: mferror.mc:242
-#, fuzzy
-#| msgid "Help not available."
msgid "Clock is not available.\n"
-msgstr "Довідка недоступна."
+msgstr "Годинник недоступний.\n"
#: mferror.mc:263
-#, fuzzy
-#| msgid "Request not supported.\n"
msgid "Multiple subscribers are not supported.\n"
-msgstr "Запит не підтримується.\n"
+msgstr "Підтримка декількох користувачів не надається.\n"
#: mferror.mc:270
-#, fuzzy
-#| msgid "The driver was not enabled."
msgid "The timer was orphaned.\n"
-msgstr "Драйвер не підключений."
+msgstr ""
#: mferror.mc:277
msgid "State transition is pending.\n"
-msgstr ""
+msgstr "Очікується зміна стану.\n"
#: mferror.mc:284
-#, fuzzy
-#| msgid "Unsupported name syntax.\n"
msgid "Unsupported state transition.\n"
-msgstr "Непідтримуваний синтаксис імені.\n"
+msgstr "Непідтримувана зміна стану.\n"
#: mferror.mc:291
-#, fuzzy
-#| msgid "An internal error has occurred.\n"
msgid "Unrecoverable error occurred.\n"
-msgstr "Виникла внутрішня помилка.\n"
+msgstr "Виникла критична помилка.\n"
#: mferror.mc:298
msgid "Sample has too many buffers.\n"
-msgstr ""
+msgstr "Зразок має занадто багато буферів.\n"
#: mferror.mc:305
-#, fuzzy
-#| msgid "Temporary directory not writable.\n"
msgid "Sample is not writable.\n"
-msgstr "Тимчасова тека недоступна для запису.\n"
+msgstr "Неможливо записати зразок.\n"
#: mferror.mc:312
-#, fuzzy
-#| msgid "Path is invalid.\n"
msgid "Key is invalid.\n"
-msgstr "Невірний шлях.\n"
+msgstr "Невірний ключ.\n"
#: mferror.mc:319
-#, fuzzy
-#| msgid "Bad network response.\n"
msgid "Bad startup version.\n"
-msgstr "Погана відповідь мережі.\n"
+msgstr "Некоректна версія під час запуску.\n"
#: mferror.mc:326
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported caption.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуваний підпис.\n"
#: mferror.mc:333
-#, fuzzy
-#| msgid "Invalid Option"
msgid "Invalid position.\n"
-msgstr "Невірний параметр"
+msgstr "Невірна позиція.\n"
#: mferror.mc:340
-#, fuzzy
-#| msgid "File not found.\n"
msgid "Attribute is not found.\n"
-msgstr "Файл не знайдено.\n"
+msgstr "Атрибут не знайдено.\n"
#: mferror.mc:347
-#, fuzzy
-#| msgid "Hook type not allowed.\n"
msgid "Property type is not allowed.\n"
-msgstr "Недозволений тип гачка.\n"
+msgstr "Недозволений тип властивості.\n"
#: mferror.mc:354
-#, fuzzy
-#| msgid "Request not supported.\n"
msgid "Property type is not supported.\n"
-msgstr "Запит не підтримується.\n"
+msgstr "Тип властивості не підтримується.\n"
#: mferror.mc:361
-#, fuzzy
-#| msgid "Directory is not empty.\n"
msgid "Property is empty.\n"
-msgstr "Каталог не порожній.\n"
+msgstr "Властивість порожня.\n"
#: mferror.mc:368
-#, fuzzy
-#| msgid "Directory is not empty.\n"
msgid "Property is not empty.\n"
-msgstr "Каталог не порожній.\n"
+msgstr "Властивість не порожня.\n"
#: mferror.mc:375
-#, fuzzy
-#| msgid "Hook type not allowed.\n"
msgid "Vector property is not allowed.\n"
-msgstr "Недозволений тип гачка.\n"
+msgstr "Недозволена векторна властивість.\n"
#: mferror.mc:382
msgid "Vector property is required.\n"
-msgstr ""
+msgstr "Потребується векторна властивість.\n"
#: mferror.mc:389
-#, fuzzy
-#| msgid "Operation canceled by user.\n"
msgid "Operation was cancelled.\n"
-msgstr "Операція скасована користувачем.\n"
+msgstr "Операція була скасована.\n"
#: mferror.mc:396
-#, fuzzy
-#| msgid "Server not disabled.\n"
msgid "Bytestream is not seekable.\n"
-msgstr "Сервер не вимкнений.\n"
+msgstr "Потік не є послідовним.\n"
#: mferror.mc:403
msgid "Platform is disabled in safe mode.\n"
-msgstr ""
+msgstr "Платформа відключена в безпечному режимі.\n"
#: mferror.mc:410
-#, fuzzy
-#| msgid "Cannot create.\n"
msgid "Cannot parse bytestream.\n"
-msgstr "Неможливо створити.\n"
+msgstr "Неможливо розібрати потік даних.\n"
#: mferror.mc:417
msgid "Mutually exclusive flags passed to source resolver.\n"
-msgstr ""
+msgstr "Конфліктні прапори передані до вихідної резолюції.\n"
#: mferror.mc:424
-#, fuzzy
-#| msgid "Unknown interface.\n"
msgid "Unknown bytestream length.\n"
-msgstr "Невідомий інтерфейс.\n"
+msgstr "Невідома довжина потоку.\n"
#: mferror.mc:431
-#, fuzzy
-#| msgid "Invalid index.\n"
msgid "Invalid work queue index.\n"
-msgstr "Невірний індекс.\n"
+msgstr "Невірний індекс черги завдань.\n"
#: mferror.mc:438
-#, fuzzy
-#| msgid "No more data available.\n"
msgid "No events available.\n"
-msgstr "Даних більше немає.\n"
+msgstr "Подій немає.\n"
#: mferror.mc:445
-#, fuzzy
-#| msgid "Unsupported name syntax.\n"
msgid "Invalid media source state transition.\n"
-msgstr "Непідтримуваний синтаксис імені.\n"
+msgstr "Невірна зміна стану джерела медіа.\n"
#: mferror.mc:452
-#, fuzzy
-#| msgid "Registry has been recovered.\n"
msgid "End of media stream has been reached.\n"
-msgstr "Реєстр відновлено.\n"
+msgstr "Досягнуто кінця медіапотоку.\n"
#: mferror.mc:459
msgid "Shutdown() was called.\n"
-msgstr ""
+msgstr "Було викликано Shutdown().\n"
#: mferror.mc:466
-#, fuzzy
-#| msgid "Registry has been recovered.\n"
msgid "Media stream has no duration set.\n"
-msgstr "Реєстр відновлено.\n"
+msgstr "Тривалості для медіапотоку не встановлено.\n"
#: mferror.mc:473
msgid "Media format was recognized but is invalid.\n"
-msgstr ""
+msgstr "Формат медіа був розпізнаний, але він невірний.\n"
#: mferror.mc:480
-#, fuzzy
-#| msgid "Property set not found.\n"
msgid "Property wasn't found.\n"
-msgstr "Набір властивостей не знайдено.\n"
+msgstr "Властивість не знайдено.\n"
#: mferror.mc:487
-#, fuzzy
-#| msgid "Directory is not empty.\n"
msgid "Property is read-only.\n"
-msgstr "Каталог не порожній.\n"
+msgstr "Властивість лише для читання.\n"
#: mferror.mc:494
-#, fuzzy
-#| msgid "Hook type not allowed.\n"
msgid "Property is not allowed.\n"
-msgstr "Недозволений тип гачка.\n"
+msgstr "Недозволена властивість.\n"
#: mferror.mc:501
-#, fuzzy
-#| msgid "Resource in use.\n"
msgid "Media source is not started.\n"
-msgstr "Ресурс використовується.\n"
+msgstr "Джерело медіа не запускається.\n"
#: mferror.mc:508
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported media format.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримуваний формат медіа.\n"
#: mferror.mc:515
-#, fuzzy
-#| msgid "Resource in use.\n"
msgid "Media source is in wrong state.\n"
-msgstr "Ресурс використовується.\n"
+msgstr "Невірний стан джерела медіа.\n"
#: mferror.mc:522
-#, fuzzy
-#| msgid "No data detected.\n"
msgid "No media streams were selected.\n"
-msgstr "Даних не виявлено.\n"
+msgstr "Не вибрано потоків медіа.\n"
#: mferror.mc:529
-#, fuzzy
-#| msgid "Unsupported type.\n"
msgid "Unsupported media source characteristics.\n"
-msgstr "Непідтримуваний тип.\n"
+msgstr "Непідтримувані характеристики джерела медіа.\n"
#: mferror.mc:536
msgid "Stream sink was removed.\n"
-msgstr ""
+msgstr "Вихід потоку даних видалено.\n"
#: mferror.mc:543
msgid "Stream sinks are out of sync.\n"
-msgstr ""
+msgstr "Потік даних не синхронізується.\n"
#: mferror.mc:550
-#, fuzzy
-#| msgid "Registry has been recovered.\n"
msgid "Media sink stream sinks set is fixed.\n"
-msgstr "Реєстр відновлено.\n"
+msgstr "Запис виходу потоку даних медіавиходу неможливо змінити.\n"
#: mferror.mc:557
-#, fuzzy
-#| msgid "Domain already exists.\n"
msgid "Stream sink already exists.\n"
-msgstr "Домен вже існує.\n"
+msgstr "Вихід потоку даних вже існує.\n"
#: mferror.mc:564
-#, fuzzy
-#| msgid "Operation canceled by user.\n"
msgid "Sample allocation was canceled.\n"
-msgstr "Операція скасована користувачем.\n"
+msgstr "Виділення зразка було перервано.\n"
#: mferror.mc:571
-#, fuzzy
-#| msgid "Directory is not empty.\n"
msgid "Sample allocator is empty.\n"
-msgstr "Каталог не порожній.\n"
+msgstr "Розподільник зразків порожній.\n"
#: mferror.mc:578
-#, fuzzy
-#| msgid "Class already exists.\n"
msgid "Sink was already stopped.\n"
-msgstr "Клас вже існує.\n"
+msgstr "Вихід вже було припинино.\n"
#: mferror.mc:585
msgid "Bitrate was unknown for ASF file sink.\n"
-msgstr ""
+msgstr "Невідомий бітрейт для виводу файлу ASF.\n"
#: mferror.mc:592
-#, fuzzy
-#| msgid "No data detected.\n"
msgid "No streams were selected for the sink.\n"
-msgstr "Даних не виявлено.\n"
+msgstr "Для виводу не вибрано потоків даних.\n"
#: mferror.mc:606
-#, fuzzy
-#| msgid "File name is too long.\n"
msgid "Metadata was too long.\n"
-msgstr "Ім'я файлу занадто довге.\n"
+msgstr "Метадані були занадто довгими.\n"
#: mferror.mc:613
msgid "No samples were processed by the sink.\n"
-msgstr ""
+msgstr "Жодні зразки не оброблялися результатами.\n"
#: mferror.mc:620
msgid "Sink was not provided with required headers.\n"
-msgstr ""
+msgstr "Вихідні дані не були забезпечені необхідними заголовками.\n"
#: mferror.mc:627
-#, fuzzy
-#| msgid "Connection invalid.\n"
msgid "Optional node is invalid.\n"
-msgstr "Невірне з'єднання.\n"
+msgstr "Необов’язковий вузол невірний.\n"
#: mferror.mc:634
-#, fuzzy
-#| msgid "Cannot find the printer."
msgid "Cannot find decryptor.\n"
-msgstr "Не вдалось знайти принтер."
+msgstr "Модуль розшифровки не знайдено.\n"
#: mferror.mc:641
-#, fuzzy
-#| msgid "Module not found.\n"
msgid "Codec was not found.\n"
-msgstr "Модуль не знайдено.\n"
+msgstr "Кодек не було знайдено.\n"
#: mferror.mc:648
msgid "Cannot connect topology nodes.\n"
-msgstr ""
+msgstr "Не вдалося підключити топологічні вузли.\n"
#: mferror.mc:655
-#, fuzzy
-#| msgid "Request not supported.\n"
msgid "Topology request is not supported.\n"
-msgstr "Запит не підтримується.\n"
+msgstr "Запит на топологію не підтримується.\n"
#: mferror.mc:662
-#, fuzzy
-#| msgid "Invalid oplock message received.\n"
msgid "Invalid topology time attributes.\n"
-msgstr "Отримане невірне oplock-повідомлення.\n"
+msgstr "Невірні атрибути часу топології.\n"
#: mferror.mc:669
msgid "Found loops in topology.\n"
-msgstr ""
+msgstr "Знайдені петлі в топології.\n"
#: mferror.mc:676
-#, fuzzy
-#| msgid "Installation source is missing.\n"
msgid "Presentation descriptor is missing.\n"
-msgstr "Джерело встановлення втрачене.\n"
+msgstr "Дескриптор презентації відсутній.\n"
#: mferror.mc:683
-#, fuzzy
-#| msgid "Index is missing.\n"
msgid "Stream descriptor is missing.\n"
-msgstr "Індекс загублений.\n"
+msgstr "Дескриптор потоку відсутній.\n"
#: mferror.mc:690
-#, fuzzy
-#| msgid "The device is not connected.\n"
msgid "Stream descriptor is not selected.\n"
-msgstr "Пристрій не під'єднаний.\n"
+msgstr "Дескриптор потоку не вибраний.\n"
#: mferror.mc:697
-#, fuzzy
-#| msgid "Index is missing.\n"
msgid "Source is missing.\n"
-msgstr "Індекс загублений.\n"
+msgstr "Джерело відсутнє.\n"
#: mferror.mc:704
msgid "Topology loader does not support sink activates.\n"
-msgstr ""
+msgstr "Завантажувач топології не підтримує вихідний сигнал.\n"
#: mferror.mc:711
msgid "Clock has no time source set.\n"
-msgstr ""
+msgstr "У годинника немає призначеного джерела часу.\n"
#: mferror.mc:718
-#, fuzzy
-#| msgid "Class already exists.\n"
msgid "Clock state was already set.\n"
-msgstr "Клас вже існує.\n"
+msgstr "Статус годинника вже встановлено.\n"
#: mpr.rc:35 wininet.rc:37
msgid "Enter Network Password"
@@ -9718,16 +9570,12 @@ msgid "Cape Verde Daylight Time"
msgstr ""
#: tzres.rc:74
-#, fuzzy
-#| msgid "Central European"
msgid "Central European Standard Time"
-msgstr "Центральноєвропейський"
+msgstr ""
#: tzres.rc:75
-#, fuzzy
-#| msgid "Central European"
msgid "Central European Daylight Time"
-msgstr "Центральноєвропейський"
+msgstr ""
#: tzres.rc:140
msgid "Morocco Standard Time"
@@ -9738,16 +9586,12 @@ msgid "Morocco Daylight Time"
msgstr ""
#: tzres.rc:72
-#, fuzzy
-#| msgid "Central European"
msgid "Central Europe Standard Time"
-msgstr "Центральноєвропейський"
+msgstr ""
#: tzres.rc:73
-#, fuzzy
-#| msgid "Central European"
msgid "Central Europe Daylight Time"
-msgstr "Центральноєвропейський"
+msgstr ""
#: tzres.rc:118
msgid "Iran Standard Time"
@@ -9782,10 +9626,8 @@ msgid "Mountain Daylight Time (Mexico)"
msgstr ""
#: tzres.rc:106
-#, fuzzy
-#| msgid "&Standard bar"
msgid "GMT Standard Time"
-msgstr "&Стандартна панель"
+msgstr ""
#: tzres.rc:107
msgid "GMT Daylight Time"
@@ -9956,10 +9798,8 @@ msgid "India Daylight Time"
msgstr ""
#: tzres.rc:112
-#, fuzzy
-#| msgid "&Standard bar"
msgid "GTB Standard Time"
-msgstr "&Стандартна панель"
+msgstr ""
#: tzres.rc:113
msgid "GTB Daylight Time"
@@ -10278,10 +10118,8 @@ msgid "Paraguay Daylight Time"
msgstr ""
#: tzres.rc:84
-#, fuzzy
-#| msgid "Date and time"
msgid "Dateline Standard Time"
-msgstr "Дата та час"
+msgstr ""
#: tzres.rc:85
msgid "Dateline Daylight Time"
@@ -10368,16 +10206,12 @@ msgid "Greenland Daylight Time"
msgstr ""
#: tzres.rc:92
-#, fuzzy
-#| msgid "Date and time"
msgid "Easter Island Standard Time"
-msgstr "Дата та час"
+msgstr ""
#: tzres.rc:93
-#, fuzzy
-#| msgid "Date and time"
msgid "Easter Island Daylight Time"
-msgstr "Дата та час"
+msgstr ""
#: tzres.rc:96
msgid "Egypt Standard Time"
@@ -10428,10 +10262,8 @@ msgid "E. Africa Daylight Time"
msgstr ""
#: tzres.rc:102
-#, fuzzy
-#| msgid "&Standard bar"
msgid "FLE Standard Time"
-msgstr "&Стандартна панель"
+msgstr ""
#: tzres.rc:103
msgid "FLE Daylight Time"
@@ -11249,10 +11081,6 @@ msgstr ""
"використовувати їх одночасно."
#: winmm.rc:128
-#, fuzzy
-#| msgid ""
-#| "The specified MIDI port is already in use. Wait until it is free; then "
-#| "try again."
msgid ""
"The specified MIDI port is already in use. Wait until it is free, and then "
"try again."
@@ -11273,10 +11101,6 @@ msgid "An error occurred with the specified port."
msgstr "Сталася помилка зі вказаним портом."
#: winmm.rc:133
-#, fuzzy
-#| msgid ""
-#| "All multimedia timers are being used by other applications. Quit one of "
-#| "these applications; then, try again."
msgid ""
"All multimedia timers are being used by other applications. Quit one of "
"these applications, and then try again."
@@ -15428,7 +15252,7 @@ msgstr "Переглядач звичайних метафайлів"
#: view.rc:50
msgid "Metafiles (*.wmf, *.emf)"
-msgstr ""
+msgstr "Метафайли (*.wmf, *.emf)"
#: wineboot.rc:31
msgid "Waiting for Program"
@@ -15596,16 +15420,12 @@ msgid "Drive configuration"
msgstr "Налаштування привода"
#: winecfg.rc:233
-#, fuzzy
-#| msgid ""
-#| "Failed to connect to the mount manager, the drive configuration cannot be "
-#| "edited."
msgid ""
"Failed to connect to the mount manager; the drive configuration cannot be "
"edited."
msgstr ""
-"Неможливо з'єднатися з менеджером монтування, конфігурація дисків не буде "
-"редагуватися."
+"Неможливо з'єднатися з менеджером монтування, конфігурацію дисків не можна "
+"редагувати."
#: winecfg.rc:236
msgid "A&dd..."
@@ -15891,19 +15711,13 @@ msgid "System drive"
msgstr "Системний диск"
#: winecfg.rc:76
-#, fuzzy
-#| msgid ""
-#| "Are you sure you want to delete drive C?\n"
-#| "\n"
-#| "Most Windows applications expect drive C to exist, and will die messily "
-#| "if it doesn't. If you proceed remember to recreate it!"
msgid ""
"Are you sure you want to delete drive C?\n"
"\n"
"Most Windows applications expect drive C to exist, and will die messily if "
"it doesn't. If you proceed, remember to recreate it!"
msgstr ""
-"Справді видалити диск C?\n"
+"Ви впевнені, що хочете видалити диск C?\n"
"\n"
"Більшість Windows-програм перестануть працювати без диску C. Якщо ви все ж "
"вирішили видалити диск, не забудьте створити новий!"
@@ -16979,10 +16793,8 @@ msgid "Text documents (*.txt)"
msgstr "Текстові документи (*.txt)"
#: wordpad.rc:149
-#, fuzzy
-#| msgid "Unicode text document (*.txt)"
msgid "Unicode text documents (*.txt)"
-msgstr "Текстовий документ Юнікод (*.txt)"
+msgstr "Текстові документи Юнікод (*.txt)"
#: wordpad.rc:150
msgid "Rich text format (*.rtf)"
@@ -17183,42 +16995,6 @@ msgid "D"
msgstr "Д"
#: xcopy.rc:81
-#, fuzzy
-#| msgid ""
-#| "XCOPY - Copies source files or directory trees to a destination.\n"
-#| "\n"
-#| "Syntax:\n"
-#| "XCOPY source [destination] [/I] [/S] [/Q] [/F] [/L] [/W] [/T] [/N] [/U]\n"
-#| "\t [/R] [/H] [/C] [/P] [/A] [/M] [/E] [/D] [/Y] [/-Y]\n"
-#| "\n"
-#| "Where:\n"
-#| "\n"
-#| "[/I] Assume directory if destination does not exist and copying two or\n"
-#| "\tmore files.\n"
-#| "[/S] Copy directories and subdirectories.\n"
-#| "[/E] Copy directories and subdirectories, including any empty ones.\n"
-#| "[/Q] Do not list names during copy, that is be quiet.\n"
-#| "[/F] Show full source and destination names during copy.\n"
-#| "[/L] Simulate operation, showing names which would be copied.\n"
-#| "[/W] Prompts before beginning the copy operation.\n"
-#| "[/T] Creates empty directory structure but does not copy files.\n"
-#| "[/Y] Suppress prompting when overwriting files.\n"
-#| "[/-Y] Enable prompting when overwriting files.\n"
-#| "[/P] Prompts on each source file before copying.\n"
-#| "[/N] Copy using short names.\n"
-#| "[/U] Copy only files which already exist in destination.\n"
-#| "[/R] Overwrite any read only files.\n"
-#| "[/H] Include hidden and system files in the copy.\n"
-#| "[/C] Continue even if an error occurs during the copy.\n"
-#| "[/A] Only copy files with archive attribute set.\n"
-#| "[/M] Only copy files with archive attribute set, removes the\n"
-#| "\tarchive attribute.\n"
-#| "[/K] Copy file attributes, without this attributes are not preserved.\n"
-#| "[/D | /D:m-d-y] Copy new files or those modified after the supplied "
-#| "date.\n"
-#| "\t\tIf no date is supplied, only copy if destination is older\n"
-#| "\t\tthan source.\n"
-#| "\n"
msgid ""
"XCOPY - Copies source files or directory trees to a destination.\n"
"\n"
--
2.23.0
Dec. 9, 2019
Re: [PATCH 2/3] ntdll: Support creating processes with specified parent.
by Alexandre Julliard
Paul Gofman <gofmanp(a)gmail.com> writes:
> @@ -1148,11 +1149,26 @@ DECL_HANDLER(new_process)
> return;
> }
>
> + if (req->parent_process)
> + {
> + if (!(parent = get_process_from_handle( req->parent_process, PROCESS_CREATE_PROCESS)))
> + {
> + set_error(STATUS_INVALID_HANDLE);
> + close(socket_fd);
> + return;
> + }
> + parent_thread = get_process_first_thread(parent);
Picking the first thread seems arbitrary. This probably needs some more
restructuring.
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 9, 2019
Re: [PATCH 1/3] kernelbase: Support PROC_THREAD_ATTRIBUTE_PARENT_PROCESS in CreateProcessInternalW().
by Alexandre Julliard
Paul Gofman <gofmanp(a)gmail.com> writes:
> + case PROC_THREAD_ATTRIBUTE_PARENT_PROCESS:
> + parent = *(HANDLE *)attrs->attrs[i].value;
> + TRACE("PROC_THREAD_ATTRIBUTE_PARENT_PROCESS parent %p.\n", parent);
> + if (!parent)
> + parent = INVALID_HANDLE_VALUE;
Using INVALID_HANDLE_VALUE for a process handle is probably not a good
idea, especially since that's the same as GetCurrentProcess().
--
Alexandre Julliard
julliard(a)winehq.org
Dec. 9, 2019
Re: [PATCH 1/2] comctl32: Preserve custom colors between subitems. (v2)
by Nikolay Sivov
I think I mentioned this last time, maybe not, but this needs more tests
for all aspects and custom draw stages, to make sure we don't break
something else with this change.
Dec. 9, 2019
[PATCH 10/10] jscript/tests: Add initial tests for the script TypeInfo.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/jscript/tests/jscript.c | 362 +++++++++++++++++++++++++++++++++++
1 file changed, 362 insertions(+)
diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c
index 0904374..5aaf7ef 100644
--- a/dlls/jscript/tests/jscript.c
+++ b/dlls/jscript/tests/jscript.c
@@ -33,6 +33,8 @@
#define IActiveScriptParse_Release IActiveScriptParse64_Release
#define IActiveScriptParse_InitNew IActiveScriptParse64_InitNew
#define IActiveScriptParse_ParseScriptText IActiveScriptParse64_ParseScriptText
+#define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_64_Release
+#define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_64_ParseProcedureText
#else
@@ -40,10 +42,13 @@
#define IActiveScriptParse_Release IActiveScriptParse32_Release
#define IActiveScriptParse_InitNew IActiveScriptParse32_InitNew
#define IActiveScriptParse_ParseScriptText IActiveScriptParse32_ParseScriptText
+#define IActiveScriptParseProcedure2_Release IActiveScriptParseProcedure2_32_Release
+#define IActiveScriptParseProcedure2_ParseProcedureText IActiveScriptParseProcedure2_32_ParseProcedureText
#endif
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+DEFINE_GUID(IID_IScriptTypeInfo, 0xc59c6b12, 0xf6c1, 0x11cf, 0x88,0x35, 0x00,0xa0,0xc9,0x11,0xe8,0xb2);
static const CLSID CLSID_JScript =
{0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
@@ -274,6 +279,20 @@ static IDispatchEx *get_script_dispatch(IActiveScript *script)
return dispex;
}
+static void parse_script(IActiveScriptParse *parser, const WCHAR *src)
+{
+ HRESULT hres;
+
+ SET_EXPECT(OnEnterScript);
+ SET_EXPECT(OnLeaveScript);
+
+ hres = IActiveScriptParse_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+
+ CHECK_CALLED(OnEnterScript);
+ CHECK_CALLED(OnLeaveScript);
+}
+
#define get_disp_id(a,b,c,d) _get_disp_id(__LINE__,a,b,c,d)
static void _get_disp_id(unsigned line, IDispatchEx *dispex, const WCHAR *name, HRESULT exhr, DISPID *id)
{
@@ -907,6 +926,347 @@ static void test_code_persistence(void)
CHECK_CALLED(OnStateChange_CLOSED);
}
+static void test_typeinfo(const WCHAR *parse_func_name)
+{
+ static struct
+ {
+ const WCHAR *name;
+ UINT num_args;
+ } func[] =
+ {
+ { L"emptyfn", 0 },
+ { L"voidfn", 0 },
+ { L"math", 2 },
+ { L"foobar", 1 },
+ { L"C", 0 },
+ { L"funcvar", 2 },
+ { L"f1", 1 },
+ { L"f2", 1 }
+ };
+ static struct
+ {
+ const WCHAR *name;
+ } var[] =
+ {
+ { L"global_var" },
+ { L"uninit" },
+ { L"obj" }
+ };
+ const WCHAR *source = L""
+ "var global_var = 42;\n"
+
+ "function emptyfn() { }\n"
+ "function voidfn() { return void(0); }\n"
+ "function math(x, y) { return x - y; }\n"
+ "function foobar(x) { return \"foobar\"; }\n"
+
+ "function C() {\n"
+ " this.x;\n"
+ " this.strret = function() { return \"ret\"; }\n"
+ "}\n"
+
+ "var uninit;\n"
+ "var obj = new C();\n"
+
+ "var funcvar = function(x, y) { return x * y; };\n"
+ "var native_func = decodeURI;\n"
+
+ "(function() {\n"
+ " f1 = function infuncexpr(x) { return 1; }\n"
+ " f2 = function infuncexpr(x) { return 2; }\n"
+ "})();\n";
+ UINT expected_funcs_cnt = parse_func_name ? 0 : ARRAY_SIZE(func);
+ UINT expected_vars_cnt = parse_func_name ? 0 : ARRAY_SIZE(var);
+
+ ITypeInfo *typeinfo, *typeinfo2;
+ ITypeComp *typecomp, *typecomp2;
+ IActiveScriptParse *parser;
+ IActiveScript *script;
+ FUNCDESC *funcdesc;
+ VARDESC *vardesc;
+ IDispatchEx *disp;
+ DESCKIND desckind;
+ BINDPTR bindptr;
+ MEMBERID memid;
+ TYPEATTR *attr;
+ UINT index;
+ HRESULT hr;
+ WCHAR str[64], *names = str;
+ int i;
+
+ if (parse_func_name)
+ trace("Testing TypeInfo for function %s...\n", wine_dbgstr_w(parse_func_name));
+ else
+ trace("Testing TypeInfo for script dispatch...\n");
+
+ script = create_jscript();
+
+ hr = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hr == S_OK, "Could not get IActiveScriptParse iface: %08x\n", hr);
+
+ SET_EXPECT(GetLCID);
+ hr = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+ ok(hr == S_OK, "SetScriptSite failed: %08x\n", hr);
+ CHECK_CALLED(GetLCID);
+
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ hr = IActiveScriptParse_InitNew(parser);
+ ok(hr == S_OK, "InitNew failed: %08x\n", hr);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+
+ SET_EXPECT(OnStateChange_CONNECTED);
+ hr = IActiveScript_SetScriptState(script, SCRIPTSTATE_CONNECTED);
+ ok(hr == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hr);
+ CHECK_CALLED(OnStateChange_CONNECTED);
+
+ if (parse_func_name)
+ {
+ IActiveScriptParseProcedure2 *parse_proc;
+ IDispatch *proc_disp;
+
+ hr = IActiveScript_QueryInterface(script, &IID_IActiveScriptParseProcedure2, (void**)&parse_proc);
+ ok(hr == S_OK, "Could not get IActiveScriptParse: %08x\n", hr);
+
+ hr = IActiveScriptParseProcedure2_ParseProcedureText(parse_proc, source, NULL, L"", NULL,
+ NULL, NULL, 0, 0, SCRIPTPROC_IMPLICIT_THIS | SCRIPTPROC_IMPLICIT_PARENTS, &proc_disp);
+ ok(hr == S_OK, "ParseProcedureText failed: %08x\n", hr);
+ IActiveScriptParseProcedure2_Release(parse_proc);
+
+ hr = IDispatch_QueryInterface(proc_disp, &IID_IDispatchEx, (void**)&disp);
+ ok(hr == S_OK, "Could not get IDispatchEx: %08x\n", hr);
+ IDispatch_Release(proc_disp);
+ }
+ else
+ {
+ parse_script(parser, source);
+ disp = get_script_dispatch(script);
+ }
+
+ hr = IDispatchEx_QueryInterface(disp, &IID_ITypeInfo, (void**)&typeinfo);
+ ok(hr == E_NOINTERFACE, "QueryInterface(IID_ITypeInfo) returned: %08x\n", hr);
+ hr = IDispatchEx_GetTypeInfo(disp, 1, LOCALE_USER_DEFAULT, &typeinfo);
+ ok(hr == DISP_E_BADINDEX, "GetTypeInfo returned: %08x\n", hr);
+ hr = IDispatchEx_GetTypeInfo(disp, 0, LOCALE_USER_DEFAULT, &typeinfo);
+ ok(hr == S_OK, "GetTypeInfo failed: %08x\n", hr);
+ hr = IDispatchEx_GetTypeInfo(disp, 0, LOCALE_USER_DEFAULT, &typeinfo2);
+ ok(hr == S_OK, "GetTypeInfo failed: %08x\n", hr);
+ ok(typeinfo != typeinfo2, "TypeInfo was not supposed to be shared.\n");
+ ITypeInfo_Release(typeinfo2);
+
+ hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
+ ok(hr == S_OK, "GetTypeAttr failed: %08x\n", hr);
+ ok(IsEqualGUID(&attr->guid, &IID_IScriptTypeInfo), "Unexpected GUID %s\n", wine_dbgstr_guid(&attr->guid));
+ ok(attr->lcid == LOCALE_USER_DEFAULT, "Unexpected LCID %u\n", attr->lcid);
+ ok(attr->memidConstructor == MEMBERID_NIL, "Unexpected constructor memid %u\n", attr->memidConstructor);
+ ok(attr->memidDestructor == MEMBERID_NIL, "Unexpected destructor memid %u\n", attr->memidDestructor);
+ ok(attr->cbSizeInstance == 4, "Unexpected cbSizeInstance %u\n", attr->cbSizeInstance);
+ ok(attr->typekind == TKIND_DISPATCH, "Unexpected typekind %u\n", attr->typekind);
+ ok(attr->cFuncs == expected_funcs_cnt, "Unexpected cFuncs %u\n", attr->cFuncs);
+ ok(attr->cVars == expected_vars_cnt, "Unexpected cVars %u\n", attr->cVars);
+ ok(attr->cImplTypes == 1, "Unexpected cImplTypes %u\n", attr->cImplTypes);
+ ok(attr->cbSizeVft == sizeof(IDispatchVtbl), "Unexpected cbSizeVft %u\n", attr->cbSizeVft);
+ ok(attr->cbAlignment == 4, "Unexpected cbAlignment %u\n", attr->cbAlignment);
+ ok(attr->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "Unexpected wTypeFlags 0x%x\n", attr->wTypeFlags);
+ ok(attr->tdescAlias.vt == VT_EMPTY, "Unexpected tdescAlias.vt %d\n", attr->tdescAlias.vt);
+ ok(attr->idldescType.wIDLFlags == IDLFLAG_NONE, "Unexpected idldescType.wIDLFlags 0x%x\n", attr->idldescType.wIDLFlags);
+ ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
+
+ /* GetIDsOfNames looks into the inherited types as well */
+ wcscpy(str, L"queryinterface");
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, NULL, 1, &memid);
+ ok(hr == E_INVALIDARG, "GetIDsOfNames returned: %08x\n", hr);
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 1, NULL);
+ ok(hr == E_INVALIDARG, "GetIDsOfNames returned: %08x\n", hr);
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 0, &memid);
+ ok(hr == E_INVALIDARG, "GetIDsOfNames returned: %08x\n", hr);
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 1, &memid);
+ ok(hr == S_OK, "GetIDsOfNames failed: %08x\n", hr);
+ ok(!lstrcmpW(str, L"queryinterface"), "Unexpected string %s\n", wine_dbgstr_w(str));
+ if (expected_funcs_cnt)
+ {
+ wcscpy(str, L"Math");
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 1, &memid);
+ ok(hr == S_OK, "GetIDsOfNames failed: %08x\n", hr);
+ ok(!lstrcmpW(str, L"Math"), "Unexpected string %s\n", wine_dbgstr_w(str));
+ }
+
+ /* Check variable descriptions */
+ hr = ITypeInfo_GetVarDesc(typeinfo, 0, NULL);
+ ok(hr == E_INVALIDARG, "GetVarDesc returned: %08x\n", hr);
+ hr = ITypeInfo_GetVarDesc(typeinfo, 1337, &vardesc);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetVarDesc returned: %08x\n", hr);
+ for (i = 0; i < expected_vars_cnt; i++)
+ {
+ hr = ITypeInfo_GetVarDesc(typeinfo, i, &vardesc);
+ ok(hr == S_OK, "GetVarDesc(%u) failed: %08x\n", i, hr);
+ ok(vardesc->memid <= 0xFFFF, "[%u] Unexpected memid 0x%x\n", i, vardesc->memid);
+ ok(vardesc->lpstrSchema == NULL, "[%u] Unexpected lpstrSchema %p\n", i, vardesc->lpstrSchema);
+ ok(vardesc->oInst == 0, "[%u] Unexpected oInst %u\n", i, vardesc->oInst);
+ ok(vardesc->varkind == VAR_DISPATCH, "[%u] Unexpected varkind %d\n", i, vardesc->varkind);
+ ok(vardesc->wVarFlags == 0, "[%u] Unexpected wVarFlags 0x%x\n", i, vardesc->wVarFlags);
+ ok(vardesc->elemdescVar.tdesc.vt == VT_VARIANT,
+ "[%u] Unexpected variable type vt %d (expected %d)\n", i, vardesc->elemdescVar.tdesc.vt, 0);
+ ok(vardesc->elemdescVar.paramdesc.pparamdescex == NULL,
+ "[%u] Unexpected variable type pparamdescex %p\n", i, vardesc->elemdescVar.paramdesc.pparamdescex);
+ ok(vardesc->elemdescVar.paramdesc.wParamFlags == PARAMFLAG_NONE,
+ "[%u] Unexpected variable type wParamFlags 0x%x\n", i, vardesc->elemdescVar.paramdesc.wParamFlags);
+ ITypeInfo_ReleaseVarDesc(typeinfo, vardesc);
+ }
+
+ /* Check function descriptions */
+ hr = ITypeInfo_GetFuncDesc(typeinfo, 0, NULL);
+ ok(hr == E_INVALIDARG, "GetFuncDesc returned: %08x\n", hr);
+ hr = ITypeInfo_GetFuncDesc(typeinfo, 1337, &funcdesc);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetFuncDesc returned: %08x\n", hr);
+ for (i = 0; i < expected_funcs_cnt; i++)
+ {
+ hr = ITypeInfo_GetFuncDesc(typeinfo, i, &funcdesc);
+ ok(hr == S_OK, "GetFuncDesc(%u) failed: %08x\n", i, hr);
+ ok(funcdesc->memid <= 0xFFFF, "[%u] Unexpected memid 0x%x\n", i, funcdesc->memid);
+ ok(funcdesc->lprgscode == NULL, "[%u] Unexpected lprgscode %p\n", i, funcdesc->lprgscode);
+ ok(func[i].num_args ? (funcdesc->lprgelemdescParam != NULL) : (funcdesc->lprgelemdescParam == NULL),
+ "[%u] Unexpected lprgelemdescParam %p\n", i, funcdesc->lprgelemdescParam);
+ ok(funcdesc->funckind == FUNC_DISPATCH, "[%u] Unexpected funckind %u\n", i, funcdesc->funckind);
+ ok(funcdesc->invkind == INVOKE_FUNC, "[%u] Unexpected invkind %u\n", i, funcdesc->invkind);
+ ok(funcdesc->callconv == CC_STDCALL, "[%u] Unexpected callconv %u\n", i, funcdesc->callconv);
+ ok(funcdesc->cParams == func[i].num_args, "[%u] Unexpected cParams %d (expected %d)\n",
+ i, funcdesc->cParams, func[i].num_args);
+ ok(funcdesc->cParamsOpt == 0, "[%u] Unexpected cParamsOpt %d\n", i, funcdesc->cParamsOpt);
+ ok(funcdesc->cScodes == 0, "[%u] Unexpected cScodes %d\n", i, funcdesc->cScodes);
+ ok(funcdesc->wFuncFlags == 0, "[%u] Unexpected wFuncFlags 0x%x\n", i, funcdesc->wFuncFlags);
+ ok(funcdesc->elemdescFunc.tdesc.vt == VT_VARIANT,
+ "[%u] Unexpected return type vt %d\n", i, funcdesc->elemdescFunc.tdesc.vt);
+ ok(funcdesc->elemdescFunc.paramdesc.pparamdescex == NULL,
+ "[%u] Unexpected return type pparamdescex %p\n", i, funcdesc->elemdescFunc.paramdesc.pparamdescex);
+ ok(funcdesc->elemdescFunc.paramdesc.wParamFlags == PARAMFLAG_NONE,
+ "[%u] Unexpected return type wParamFlags 0x%x\n", i, funcdesc->elemdescFunc.paramdesc.wParamFlags);
+ if (funcdesc->lprgelemdescParam)
+ for (index = 0; index < funcdesc->cParams; index++)
+ {
+ ok(funcdesc->lprgelemdescParam[index].tdesc.vt == VT_VARIANT,
+ "[%u] Unexpected parameter %u vt %d\n", i, index, funcdesc->lprgelemdescParam[index].tdesc.vt);
+ ok(funcdesc->lprgelemdescParam[index].paramdesc.pparamdescex == NULL,
+ "[%u] Unexpected parameter %u pparamdescex %p\n", i, index, funcdesc->lprgelemdescParam[index].paramdesc.pparamdescex);
+ ok(funcdesc->lprgelemdescParam[index].paramdesc.wParamFlags == PARAMFLAG_NONE,
+ "[%u] Unexpected parameter %u wParamFlags 0x%x\n", i, index, funcdesc->lprgelemdescParam[index].paramdesc.wParamFlags);
+ }
+ ITypeInfo_ReleaseFuncDesc(typeinfo, funcdesc);
+ }
+
+ /* Test TypeComp Binds */
+ hr = ITypeInfo_QueryInterface(typeinfo, &IID_ITypeComp, (void**)&typecomp);
+ ok(hr == S_OK, "QueryInterface(IID_ITypeComp) failed: %08x\n", hr);
+ hr = ITypeInfo_GetTypeComp(typeinfo, NULL);
+ ok(hr == E_INVALIDARG, "GetTypeComp returned: %08x\n", hr);
+ hr = ITypeInfo_GetTypeComp(typeinfo, &typecomp2);
+ ok(hr == S_OK, "GetTypeComp failed: %08x\n", hr);
+ ok(typecomp == typecomp2, "QueryInterface(IID_ITypeComp) and GetTypeComp returned different TypeComps\n");
+ ITypeComp_Release(typecomp2);
+ wcscpy(str, L"not_found");
+ hr = ITypeComp_Bind(typecomp, NULL, 0, 0, &typeinfo2, &desckind, &bindptr);
+ ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, NULL, &desckind, &bindptr);
+ ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, NULL, &bindptr);
+ ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, NULL);
+ ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_NONE, "Unexpected desckind %u\n", desckind);
+ wcscpy(str, L"addRef");
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_FUNCDESC, "Unexpected desckind %u\n", desckind);
+ ok(!lstrcmpW(str, L"addRef"), "Unexpected string %s\n", wine_dbgstr_w(str));
+ ITypeInfo_ReleaseFuncDesc(typeinfo2, bindptr.lpfuncdesc);
+ ITypeInfo_Release(typeinfo2);
+ for (i = 0; i < expected_vars_cnt; i++)
+ {
+ wcscpy(str, var[i].name);
+ hr = ITypeComp_Bind(typecomp, str, 0, INVOKE_PROPERTYGET, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_VARDESC, "Unexpected desckind %u\n", desckind);
+ ITypeInfo_ReleaseVarDesc(typeinfo2, bindptr.lpvardesc);
+ ITypeInfo_Release(typeinfo2);
+ }
+ for (i = 0; i < expected_funcs_cnt; i++)
+ {
+ wcscpy(str, func[i].name);
+ hr = ITypeComp_Bind(typecomp, str, 0, INVOKE_FUNC, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_FUNCDESC, "Unexpected desckind %u\n", desckind);
+ ITypeInfo_ReleaseFuncDesc(typeinfo2, bindptr.lpfuncdesc);
+ ITypeInfo_Release(typeinfo2);
+ }
+ wcscpy(str, L"JScriptTypeInfo");
+ hr = ITypeComp_BindType(typecomp, NULL, 0, &typeinfo2, &typecomp2);
+ ok(hr == E_INVALIDARG, "BindType returned: %08x\n", hr);
+ hr = ITypeComp_BindType(typecomp, str, 0, NULL, &typecomp2);
+ ok(hr == E_INVALIDARG, "BindType returned: %08x\n", hr);
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, NULL);
+ ok(hr == E_INVALIDARG, "BindType returned: %08x\n", hr);
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, &typecomp2);
+ ok(hr == S_OK, "BindType failed: %08x\n", hr);
+ ok(!typeinfo2, "Unexpected TypeInfo %p (expected null)\n", typeinfo2);
+ ok(!typecomp2, "Unexpected TypeComp %p (expected null)\n", typecomp2);
+ wcscpy(str, L"C");
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, &typecomp2);
+ ok(hr == S_OK, "BindType failed: %08x\n", hr);
+ ok(!typeinfo2, "Unexpected TypeInfo %p (expected null)\n", typeinfo2);
+ ok(!typecomp2, "Unexpected TypeComp %p (expected null)\n", typecomp2);
+ wcscpy(str, L"IDispatch");
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, &typecomp2);
+ ok(hr == S_OK, "BindType failed: %08x\n", hr);
+ ok(!typeinfo2, "Unexpected TypeInfo %p (expected null)\n", typeinfo2);
+ ok(!typecomp2, "Unexpected TypeComp %p (expected null)\n", typecomp2);
+ ITypeComp_Release(typecomp);
+
+ /* Updating the script won't update the typeinfo obtained before,
+ but it will be reflected in any typeinfo obtained afterwards. */
+ if (!parse_func_name)
+ {
+ parse_script(parser, L""
+ "var new_var;\n"
+ "function new_func() { }\n");
+
+ hr = IDispatchEx_GetTypeInfo(disp, 0, LOCALE_USER_DEFAULT, &typeinfo2);
+ ok(hr == S_OK, "GetTypeInfo failed: %08x\n", hr);
+ hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
+ ok(hr == S_OK, "GetTypeAttr failed: %08x\n", hr);
+ ok(attr->cFuncs == expected_funcs_cnt, "Unexpected cFuncs %u\n", attr->cFuncs);
+ ok(attr->cVars == expected_vars_cnt, "Unexpected cVars %u\n", attr->cVars);
+ ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
+ hr = ITypeInfo_GetTypeAttr(typeinfo2, &attr);
+ ok(hr == S_OK, "GetTypeAttr failed: %08x\n", hr);
+ ok(attr->cFuncs == expected_funcs_cnt + 1, "Unexpected cFuncs %u\n", attr->cFuncs);
+ ok(attr->cVars == expected_vars_cnt + 1, "Unexpected cVars %u\n", attr->cVars);
+ ITypeInfo_ReleaseTypeAttr(typeinfo2, attr);
+ ITypeInfo_Release(typeinfo2);
+
+ /* Adding an identifier that differs only in case gives an error
+ when retrieving the TypeInfo, even though it is valid jscript. */
+ parse_script(parser, L"var NEW_FUNC;\n");
+ hr = IDispatchEx_GetTypeInfo(disp, 0, LOCALE_USER_DEFAULT, &typeinfo2);
+ ok(hr == TYPE_E_AMBIGUOUSNAME, "GetTypeInfo returned: %08x\n", hr);
+ }
+
+ ITypeInfo_Release(typeinfo);
+ IDispatchEx_Release(disp);
+ IActiveScriptParse_Release(parser);
+
+ SET_EXPECT(OnStateChange_DISCONNECTED);
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ SET_EXPECT(OnStateChange_CLOSED);
+ hr = IActiveScript_Close(script);
+ ok(hr == S_OK, "Close failed: %08x\n", hr);
+ CHECK_CALLED(OnStateChange_DISCONNECTED);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+ CHECK_CALLED(OnStateChange_CLOSED);
+
+ IActiveScript_Release(script);
+}
+
static BOOL check_jscript(void)
{
IActiveScriptProperty *script_prop;
@@ -931,6 +1291,8 @@ START_TEST(jscript)
test_jscript_uninitializing();
test_aggregation();
test_code_persistence();
+ test_typeinfo(NULL);
+ test_typeinfo(L"some_func_name");
trace("Testing JScriptEncode object...\n");
engine_clsid = &CLSID_JScriptEncode;
--
2.21.0
Dec. 9, 2019
[PATCH 09/10] jscript: Implement ScriptTypeComp_BindType.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/jscript/dispex.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 6f0768e..3226fb8 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -1073,10 +1073,25 @@ static HRESULT WINAPI ScriptTypeComp_BindType(ITypeComp *iface, LPOLESTR szName,
ITypeInfo **ppTInfo, ITypeComp **ppTComp)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeComp(iface);
+ ITypeInfo *disp_typeinfo;
+ ITypeComp *disp_typecomp;
+ HRESULT hr;
- FIXME("(%p)->(%s %08x %p %p)\n", This, debugstr_w(szName), lHashVal, ppTInfo, ppTComp);
+ TRACE("(%p)->(%s %08x %p %p)\n", This, debugstr_w(szName), lHashVal, ppTInfo, ppTComp);
- return E_NOTIMPL;
+ if (!szName || !ppTInfo || !ppTComp)
+ return E_INVALIDARG;
+
+ /* Look into the inherited IDispatch */
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ hr = ITypeInfo_GetTypeComp(disp_typeinfo, &disp_typecomp);
+ if (FAILED(hr)) return hr;
+
+ hr = ITypeComp_BindType(disp_typecomp, szName, lHashVal, ppTInfo, ppTComp);
+ ITypeComp_Release(disp_typecomp);
+ return hr;
}
static const ITypeCompVtbl ScriptTypeCompVtbl = {
--
2.21.0
Dec. 9, 2019
[PATCH 08/10] jscript: Implement ScriptTypeComp_Bind.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/jscript/dispex.c | 49 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 3769874..6f0768e 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -1017,11 +1017,56 @@ static HRESULT WINAPI ScriptTypeComp_Bind(ITypeComp *iface, LPOLESTR szName, ULO
ITypeInfo **ppTInfo, DESCKIND *pDescKind, BINDPTR *pBindPtr)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeComp(iface);
+ UINT flags = wFlags ? wFlags : ~0;
+ ITypeInfo *disp_typeinfo;
+ ITypeComp *disp_typecomp;
+ HRESULT hr;
+ UINT i;
- FIXME("(%p)->(%s %08x %d %p %p %p)\n", This, debugstr_w(szName), lHashVal,
+ TRACE("(%p)->(%s %08x %d %p %p %p)\n", This, debugstr_w(szName), lHashVal,
wFlags, ppTInfo, pDescKind, pBindPtr);
- return E_NOTIMPL;
+ if (!szName || !ppTInfo || !pDescKind || !pBindPtr)
+ return E_INVALIDARG;
+
+ for (i = 0; i < This->num_funcs; i++)
+ {
+ if (wcsicmp(szName, This->funcs[i].prop->name)) continue;
+ if (!(flags & INVOKE_FUNC)) return TYPE_E_TYPEMISMATCH;
+
+ hr = ITypeInfo_GetFuncDesc(&This->ITypeInfo_iface, i, &pBindPtr->lpfuncdesc);
+ if (FAILED(hr)) return hr;
+
+ *pDescKind = DESCKIND_FUNCDESC;
+ *ppTInfo = &This->ITypeInfo_iface;
+ ITypeInfo_AddRef(*ppTInfo);
+ return S_OK;
+ }
+
+ for (i = 0; i < This->num_vars; i++)
+ {
+ if (wcsicmp(szName, This->vars[i]->name)) continue;
+ if (!(flags & INVOKE_PROPERTYGET)) return TYPE_E_TYPEMISMATCH;
+
+ hr = ITypeInfo_GetVarDesc(&This->ITypeInfo_iface, i, &pBindPtr->lpvardesc);
+ if (FAILED(hr)) return hr;
+
+ *pDescKind = DESCKIND_VARDESC;
+ *ppTInfo = &This->ITypeInfo_iface;
+ ITypeInfo_AddRef(*ppTInfo);
+ return S_OK;
+ }
+
+ /* Look into the inherited IDispatch */
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ hr = ITypeInfo_GetTypeComp(disp_typeinfo, &disp_typecomp);
+ if (FAILED(hr)) return hr;
+
+ hr = ITypeComp_Bind(disp_typecomp, szName, lHashVal, wFlags, ppTInfo, pDescKind, pBindPtr);
+ ITypeComp_Release(disp_typecomp);
+ return hr;
}
static HRESULT WINAPI ScriptTypeComp_BindType(ITypeComp *iface, LPOLESTR szName, ULONG lHashVal,
--
2.21.0
Dec. 9, 2019
[PATCH 07/10] jscript: Implement ScriptTypeInfo_GetTypeComp.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/jscript/dispex.c | 64 +++++++++++++++++++++++++++++++++++++++++--
1 file changed, 62 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index f7a1a51..3769874 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -613,6 +613,7 @@ struct typeinfo_func {
typedef struct {
ITypeInfo ITypeInfo_iface;
+ ITypeComp ITypeComp_iface;
LONG ref;
UINT num_funcs;
@@ -628,12 +629,19 @@ static inline ScriptTypeInfo *ScriptTypeInfo_from_ITypeInfo(ITypeInfo *iface)
return CONTAINING_RECORD(iface, ScriptTypeInfo, ITypeInfo_iface);
}
+static inline ScriptTypeInfo *ScriptTypeInfo_from_ITypeComp(ITypeComp *iface)
+{
+ return CONTAINING_RECORD(iface, ScriptTypeInfo, ITypeComp_iface);
+}
+
static HRESULT WINAPI ScriptTypeInfo_QueryInterface(ITypeInfo *iface, REFIID riid, void **ppv)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ITypeInfo, riid))
*ppv = &This->ITypeInfo_iface;
+ else if (IsEqualGUID(&IID_ITypeComp, riid))
+ *ppv = &This->ITypeComp_iface;
else
{
WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
@@ -711,9 +719,13 @@ static HRESULT WINAPI ScriptTypeInfo_GetTypeComp(ITypeInfo *iface, ITypeComp **p
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
- FIXME("(%p)->(%p)\n", This, ppTComp);
+ TRACE("(%p)->(%p)\n", This, ppTComp);
- return E_NOTIMPL;
+ if (!ppTComp) return E_INVALIDARG;
+
+ *ppTComp = &This->ITypeComp_iface;
+ ITypeInfo_AddRef(iface);
+ return S_OK;
}
static HRESULT WINAPI ScriptTypeInfo_GetFuncDesc(ITypeInfo *iface, UINT index, FUNCDESC **ppFuncDesc)
@@ -983,6 +995,53 @@ static const ITypeInfoVtbl ScriptTypeInfoVtbl = {
ScriptTypeInfo_ReleaseVarDesc
};
+static HRESULT WINAPI ScriptTypeComp_QueryInterface(ITypeComp *iface, REFIID riid, void **ppv)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeComp(iface);
+ return ITypeInfo_QueryInterface(&This->ITypeInfo_iface, riid, ppv);
+}
+
+static ULONG WINAPI ScriptTypeComp_AddRef(ITypeComp *iface)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeComp(iface);
+ return ITypeInfo_AddRef(&This->ITypeInfo_iface);
+}
+
+static ULONG WINAPI ScriptTypeComp_Release(ITypeComp *iface)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeComp(iface);
+ return ITypeInfo_Release(&This->ITypeInfo_iface);
+}
+
+static HRESULT WINAPI ScriptTypeComp_Bind(ITypeComp *iface, LPOLESTR szName, ULONG lHashVal, WORD wFlags,
+ ITypeInfo **ppTInfo, DESCKIND *pDescKind, BINDPTR *pBindPtr)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeComp(iface);
+
+ FIXME("(%p)->(%s %08x %d %p %p %p)\n", This, debugstr_w(szName), lHashVal,
+ wFlags, ppTInfo, pDescKind, pBindPtr);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeComp_BindType(ITypeComp *iface, LPOLESTR szName, ULONG lHashVal,
+ ITypeInfo **ppTInfo, ITypeComp **ppTComp)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeComp(iface);
+
+ FIXME("(%p)->(%s %08x %p %p)\n", This, debugstr_w(szName), lHashVal, ppTInfo, ppTComp);
+
+ return E_NOTIMPL;
+}
+
+static const ITypeCompVtbl ScriptTypeCompVtbl = {
+ ScriptTypeComp_QueryInterface,
+ ScriptTypeComp_AddRef,
+ ScriptTypeComp_Release,
+ ScriptTypeComp_Bind,
+ ScriptTypeComp_BindType
+};
+
static inline jsdisp_t *impl_from_IDispatchEx(IDispatchEx *iface)
{
return CONTAINING_RECORD(iface, jsdisp_t, IDispatchEx_iface);
@@ -1085,6 +1144,7 @@ static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LC
return E_OUTOFMEMORY;
typeinfo->ITypeInfo_iface.lpVtbl = &ScriptTypeInfoVtbl;
+ typeinfo->ITypeComp_iface.lpVtbl = &ScriptTypeCompVtbl;
typeinfo->ref = 1;
typeinfo->num_vars = num_vars;
typeinfo->num_funcs = num_funcs;
--
2.21.0
Dec. 9, 2019
[PATCH 06/10] jscript: Implement ScriptTypeInfo_GetIDsOfNames.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/jscript/dispex.c | 51 +++++++++++++++++++++++++++++++++++--
dlls/jscript/jscript.h | 1 +
dlls/jscript/jscript_main.c | 25 ++++++++++++++++++
3 files changed, 75 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 5f252fb..f7a1a51 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -802,10 +802,57 @@ static HRESULT WINAPI ScriptTypeInfo_GetIDsOfNames(ITypeInfo *iface, LPOLESTR *r
MEMBERID *pMemId)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ ITypeInfo *disp_typeinfo;
+ const WCHAR *name;
+ HRESULT hr = S_OK;
+ int i, j, arg;
- FIXME("(%p)->(%p %u %p)\n", This, rgszNames, cNames, pMemId);
+ TRACE("(%p)->(%p %u %p)\n", This, rgszNames, cNames, pMemId);
- return E_NOTIMPL;
+ if (!rgszNames || !cNames || !pMemId) return E_INVALIDARG;
+
+ for (i = 0; i < cNames; i++) pMemId[i] = MEMBERID_NIL;
+ name = rgszNames[0];
+
+ for (i = 0; i < This->num_funcs; i++)
+ {
+ struct typeinfo_func *func = &This->funcs[i];
+ unsigned num_args;
+ BSTR *args;
+
+ if (wcsicmp(name, func->prop->name)) continue;
+ pMemId[0] = prop_to_id(This->jsdisp, func->prop);
+
+ args = get_source_function_params(func->disp, &num_args);
+
+ for (j = 1; j < cNames; j++)
+ {
+ name = rgszNames[j];
+ for (arg = num_args; --arg >= 0;)
+ if (!wcsicmp(name, args[arg]))
+ break;
+ if (arg >= 0)
+ pMemId[j] = arg;
+ else
+ hr = DISP_E_UNKNOWNNAME;
+ }
+ return hr;
+ }
+
+ for (i = 0; i < This->num_vars; i++)
+ {
+ dispex_prop_t *var = This->vars[i];
+
+ if (wcsicmp(name, var->name)) continue;
+ pMemId[0] = prop_to_id(This->jsdisp, var);
+ return S_OK;
+ }
+
+ /* Look into the inherited IDispatch */
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ return ITypeInfo_GetIDsOfNames(disp_typeinfo, rgszNames, cNames, pMemId);
}
static HRESULT WINAPI ScriptTypeInfo_Invoke(ITypeInfo *iface, PVOID pvInstance, MEMBERID memid, WORD wFlags,
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 09ecfb4..6066772 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -87,6 +87,7 @@ static inline LPWSTR heap_strdupW(LPCWSTR str)
typedef struct jsdisp_t jsdisp_t;
extern HINSTANCE jscript_hinstance DECLSPEC_HIDDEN;
+HRESULT get_dispatch_typeinfo(ITypeInfo**) DECLSPEC_HIDDEN;
#define PROPF_ARGMASK 0x00ff
#define PROPF_METHOD 0x0100
diff --git a/dlls/jscript/jscript_main.c b/dlls/jscript/jscript_main.c
index 9f9f412..532cdf9 100644
--- a/dlls/jscript/jscript_main.c
+++ b/dlls/jscript/jscript_main.c
@@ -37,6 +37,30 @@ LONG module_ref = 0;
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
HINSTANCE jscript_hinstance;
+static ITypeInfo *dispatch_typeinfo;
+
+HRESULT get_dispatch_typeinfo(ITypeInfo **out)
+{
+ ITypeInfo *typeinfo;
+ ITypeLib *typelib;
+ HRESULT hr;
+
+ if (!dispatch_typeinfo)
+ {
+ hr = LoadRegTypeLib(&IID_StdOle, STDOLE_MAJORVERNUM, STDOLE_MINORVERNUM, STDOLE_LCID, &typelib);
+ if (FAILED(hr)) return hr;
+
+ hr = ITypeLib_GetTypeInfoOfGuid(typelib, &IID_IDispatch, &typeinfo);
+ ITypeLib_Release(typelib);
+ if (FAILED(hr)) return hr;
+
+ if (InterlockedCompareExchangePointer((void**)&dispatch_typeinfo, typeinfo, NULL))
+ ITypeInfo_Release(typeinfo);
+ }
+
+ *out = dispatch_typeinfo;
+ return S_OK;
+}
static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
{
@@ -145,6 +169,7 @@ BOOL WINAPI DllMain(HINSTANCE hInstDLL, DWORD fdwReason, LPVOID lpv)
break;
case DLL_PROCESS_DETACH:
if (lpv) break;
+ if (dispatch_typeinfo) ITypeInfo_Release(dispatch_typeinfo);
free_strings();
}
--
2.21.0
Dec. 9, 2019
[PATCH 05/10] jscript: Implement ScriptTypeInfo_GetVarDesc.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/jscript/dispex.c | 20 +++++++++++++++++---
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index e58b285..5f252fb 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -752,10 +752,22 @@ static HRESULT WINAPI ScriptTypeInfo_GetFuncDesc(ITypeInfo *iface, UINT index, F
static HRESULT WINAPI ScriptTypeInfo_GetVarDesc(ITypeInfo *iface, UINT index, VARDESC **ppVarDesc)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ VARDESC *desc;
- FIXME("(%p)->(%u %p)\n", This, index, ppVarDesc);
+ TRACE("(%p)->(%u %p)\n", This, index, ppVarDesc);
- return E_NOTIMPL;
+ if (!ppVarDesc) return E_INVALIDARG;
+ if (index >= This->num_vars) return TYPE_E_ELEMENTNOTFOUND;
+
+ desc = heap_alloc_zero(sizeof(*desc));
+ if (!desc) return E_OUTOFMEMORY;
+
+ desc->memid = prop_to_id(This->jsdisp, This->vars[index]);
+ desc->varkind = VAR_DISPATCH;
+ desc->elemdescVar.tdesc.vt = VT_VARIANT;
+
+ *ppVarDesc = desc;
+ return S_OK;
}
static HRESULT WINAPI ScriptTypeInfo_GetNames(ITypeInfo *iface, MEMBERID memid, BSTR *rgBstrNames,
@@ -894,7 +906,9 @@ static void WINAPI ScriptTypeInfo_ReleaseVarDesc(ITypeInfo *iface, VARDESC *pVar
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
- FIXME("(%p)->(%p)\n", This, pVarDesc);
+ TRACE("(%p)->(%p)\n", This, pVarDesc);
+
+ heap_free(pVarDesc);
}
static const ITypeInfoVtbl ScriptTypeInfoVtbl = {
--
2.21.0
Dec. 9, 2019
[PATCH 04/10] jscript: Implement ScriptTypeInfo_GetFuncDesc.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/jscript/dispex.c | 32 +++++++++++++++++++++++++++++---
dlls/jscript/function.c | 8 ++++++++
dlls/jscript/jscript.h | 1 +
3 files changed, 38 insertions(+), 3 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 8c1fc45..e58b285 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -719,10 +719,34 @@ static HRESULT WINAPI ScriptTypeInfo_GetTypeComp(ITypeInfo *iface, ITypeComp **p
static HRESULT WINAPI ScriptTypeInfo_GetFuncDesc(ITypeInfo *iface, UINT index, FUNCDESC **ppFuncDesc)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ struct typeinfo_func *func;
+ unsigned num_args, i;
+ FUNCDESC *desc;
- FIXME("(%p)->(%u %p)\n", This, index, ppFuncDesc);
+ TRACE("(%p)->(%u %p)\n", This, index, ppFuncDesc);
- return E_NOTIMPL;
+ if (!ppFuncDesc) return E_INVALIDARG;
+ if (index >= This->num_funcs) return TYPE_E_ELEMENTNOTFOUND;
+ func = &This->funcs[index];
+ get_source_function_params(func->disp, &num_args);
+
+ /* Store the parameter array after the FUNCDESC structure */
+ desc = heap_alloc_zero(sizeof(*desc) + sizeof(ELEMDESC) * num_args);
+ if (!desc) return E_OUTOFMEMORY;
+
+ desc->memid = prop_to_id(This->jsdisp, func->prop);
+ desc->funckind = FUNC_DISPATCH;
+ desc->invkind = INVOKE_FUNC;
+ desc->callconv = CC_STDCALL;
+ desc->cParams = num_args;
+ desc->elemdescFunc.tdesc.vt = VT_VARIANT;
+
+ if (num_args) desc->lprgelemdescParam = (ELEMDESC*)(desc + 1);
+ for (i = 0; i < num_args; i++)
+ desc->lprgelemdescParam[i].tdesc.vt = VT_VARIANT;
+
+ *ppFuncDesc = desc;
+ return S_OK;
}
static HRESULT WINAPI ScriptTypeInfo_GetVarDesc(ITypeInfo *iface, UINT index, VARDESC **ppVarDesc)
@@ -861,7 +885,9 @@ static void WINAPI ScriptTypeInfo_ReleaseFuncDesc(ITypeInfo *iface, FUNCDESC *pF
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
- FIXME("(%p)->(%p)\n", This, pFuncDesc);
+ TRACE("(%p)->(%p)\n", This, pFuncDesc);
+
+ heap_free(pFuncDesc);
}
static void WINAPI ScriptTypeInfo_ReleaseVarDesc(ITypeInfo *iface, VARDESC *pVarDesc)
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 98d1259..c2d058b 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -808,6 +808,14 @@ BOOL is_source_function(jsdisp_t *jsdisp)
return function_from_jsdisp(jsdisp)->vtbl == &InterpretedFunctionVtbl;
}
+BSTR *get_source_function_params(jsdisp_t *jsdisp, unsigned *param_cnt)
+{
+ InterpretedFunction *func = (InterpretedFunction*)function_from_jsdisp(jsdisp);
+
+ *param_cnt = func->func_code->param_cnt;
+ return func->func_code->params;
+}
+
static HRESULT BindFunction_call(script_ctx_t *ctx, FunctionInstance *func, IDispatch *this_obj, unsigned flags,
unsigned argc, jsval_t *argv, jsval_t *r)
{
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 91923f8..09ecfb4 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -304,6 +304,7 @@ HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,cons
HRESULT create_builtin_constructor(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
BOOL is_source_function(jsdisp_t*) DECLSPEC_HIDDEN;
+BSTR *get_source_function_params(jsdisp_t*,unsigned*) DECLSPEC_HIDDEN;
HRESULT Function_invoke(jsdisp_t*,IDispatch*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
HRESULT Function_value(script_ctx_t*,vdisp_t*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
--
2.21.0
Dec. 9, 2019
[PATCH 03/10] jscript: Implement ScriptTypeInfo_GetTypeAttr.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/jscript/dispex.c | 36 +++++++++++++++++++++++++++++++-----
1 file changed, 31 insertions(+), 5 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 5710fdd..8c1fc45 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -24,6 +24,8 @@
WINE_DEFAULT_DEBUG_CHANNEL(jscript);
+static const GUID GUID_JScriptTypeInfo = {0xc59c6b12,0xf6c1,0x11cf,{0x88,0x35,0x00,0xa0,0xc9,0x11,0xe8,0xb2}};
+
#define FDEX_VERSION_MASK 0xf0000000
#define GOLDEN_RATIO 0x9E3779B9U
@@ -677,10 +679,32 @@ static ULONG WINAPI ScriptTypeInfo_Release(ITypeInfo *iface)
static HRESULT WINAPI ScriptTypeInfo_GetTypeAttr(ITypeInfo *iface, TYPEATTR **ppTypeAttr)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
-
- FIXME("(%p)->(%p)\n", This, ppTypeAttr);
-
- return E_NOTIMPL;
+ TYPEATTR *attr;
+
+ TRACE("(%p)->(%p)\n", This, ppTypeAttr);
+
+ if (!ppTypeAttr) return E_INVALIDARG;
+
+ attr = heap_alloc_zero(sizeof(*attr));
+ if (!attr) return E_OUTOFMEMORY;
+
+ attr->guid = GUID_JScriptTypeInfo;
+ attr->lcid = LOCALE_USER_DEFAULT;
+ attr->memidConstructor = MEMBERID_NIL;
+ attr->memidDestructor = MEMBERID_NIL;
+ attr->cbSizeInstance = 4;
+ attr->typekind = TKIND_DISPATCH;
+ attr->cFuncs = This->num_funcs;
+ attr->cVars = This->num_vars;
+ attr->cImplTypes = 1;
+ attr->cbSizeVft = sizeof(IDispatchVtbl);
+ attr->cbAlignment = 4;
+ attr->wTypeFlags = TYPEFLAG_FDISPATCHABLE;
+ attr->wMajorVerNum = JSCRIPT_MAJOR_VERSION;
+ attr->wMinorVerNum = JSCRIPT_MINOR_VERSION;
+
+ *ppTypeAttr = attr;
+ return S_OK;
}
static HRESULT WINAPI ScriptTypeInfo_GetTypeComp(ITypeInfo *iface, ITypeComp **ppTComp)
@@ -828,7 +852,9 @@ static void WINAPI ScriptTypeInfo_ReleaseTypeAttr(ITypeInfo *iface, TYPEATTR *pT
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
- FIXME("(%p)->(%p)\n", This, pTypeAttr);
+ TRACE("(%p)->(%p)\n", This, pTypeAttr);
+
+ heap_free(pTypeAttr);
}
static void WINAPI ScriptTypeInfo_ReleaseFuncDesc(ITypeInfo *iface, FUNCDESC *pFuncDesc)
--
2.21.0
Dec. 9, 2019
[PATCH 02/10] jscript: Store the necessary function and variable info in the TypeInfo.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/jscript/dispex.c | 109 ++++++++++++++++++++++++++++++++++++++++
dlls/jscript/function.c | 5 ++
dlls/jscript/jscript.h | 1 +
3 files changed, 115 insertions(+)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 92e9b96..5710fdd 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -70,6 +70,20 @@ static inline dispex_prop_t *get_prop(jsdisp_t *This, DISPID id)
return This->props+id;
}
+static inline BOOL is_function_prop(dispex_prop_t *prop)
+{
+ BOOL ret = FALSE;
+
+ if (is_object_instance(prop->u.val))
+ {
+ jsdisp_t *jsdisp = iface_to_jsdisp(get_object(prop->u.val));
+
+ if (jsdisp) ret = is_class(jsdisp, JSCLASS_FUNCTION);
+ jsdisp_release(jsdisp);
+ }
+ return ret;
+}
+
static DWORD get_flags(jsdisp_t *This, dispex_prop_t *prop)
{
if(prop->type == PROP_PROTREF) {
@@ -590,9 +604,21 @@ static HRESULT fill_protrefs(jsdisp_t *This)
return S_OK;
}
+struct typeinfo_func {
+ dispex_prop_t *prop;
+ jsdisp_t *disp;
+};
+
typedef struct {
ITypeInfo ITypeInfo_iface;
LONG ref;
+
+ UINT num_funcs;
+ UINT num_vars;
+ struct typeinfo_func *funcs;
+ dispex_prop_t **vars;
+
+ jsdisp_t *jsdisp;
} ScriptTypeInfo;
static inline ScriptTypeInfo *ScriptTypeInfo_from_ITypeInfo(ITypeInfo *iface)
@@ -632,11 +658,17 @@ static ULONG WINAPI ScriptTypeInfo_Release(ITypeInfo *iface)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
LONG ref = InterlockedDecrement(&This->ref);
+ UINT i;
TRACE("(%p) ref=%d\n", This, ref);
if (!ref)
{
+ for (i = This->num_funcs; i--;)
+ IDispatchEx_Release(&This->funcs[i].disp->IDispatchEx_iface);
+ IDispatchEx_Release(&This->jsdisp->IDispatchEx_iface);
+ heap_free(This->funcs);
+ heap_free(This->vars);
heap_free(This);
}
return ref;
@@ -897,17 +929,94 @@ static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LC
ITypeInfo **ppTInfo)
{
jsdisp_t *This = impl_from_IDispatchEx(iface);
+ dispex_prop_t *prop, *cur, *end, **typevar;
+ UINT num_funcs = 0, num_vars = 0;
+ struct typeinfo_func *typefunc;
ScriptTypeInfo *typeinfo;
+ jsdisp_t *fn;
+ unsigned pos;
TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
if (iTInfo != 0) return DISP_E_BADINDEX;
+ for (prop = This->props, end = prop + This->prop_cnt; prop != end; prop++)
+ {
+ if (!prop->name || prop->type != PROP_JSVAL || !(prop->flags & PROPF_ENUMERABLE))
+ continue;
+
+ /* If two identifiers differ only by case, the TypeInfo fails */
+ pos = This->props[get_props_idx(This, prop->hash)].bucket_head;
+ while (pos)
+ {
+ cur = This->props + pos;
+
+ if (prop->hash == cur->hash && prop != cur &&
+ cur->type == PROP_JSVAL && (cur->flags & PROPF_ENUMERABLE) &&
+ !wcsicmp(prop->name, cur->name))
+ {
+ return TYPE_E_AMBIGUOUSNAME;
+ }
+ pos = cur->bucket_next;
+ }
+
+ if (is_function_prop(prop))
+ {
+ fn = impl_from_IDispatchEx((IDispatchEx*)get_object(prop->u.val));
+ if (is_source_function(fn)) num_funcs++;
+ }
+ else num_vars++;
+ }
+
if (!(typeinfo = heap_alloc(sizeof(*typeinfo))))
return E_OUTOFMEMORY;
typeinfo->ITypeInfo_iface.lpVtbl = &ScriptTypeInfoVtbl;
typeinfo->ref = 1;
+ typeinfo->num_vars = num_vars;
+ typeinfo->num_funcs = num_funcs;
+ typeinfo->jsdisp = This;
+
+ typeinfo->funcs = heap_alloc(sizeof(*typeinfo->funcs) * num_funcs);
+ if (!typeinfo->funcs)
+ {
+ heap_free(typeinfo);
+ return E_OUTOFMEMORY;
+ }
+
+ typeinfo->vars = heap_alloc(sizeof(*typeinfo->vars) * num_vars);
+ if (!typeinfo->vars)
+ {
+ heap_free(typeinfo->funcs);
+ heap_free(typeinfo);
+ return E_OUTOFMEMORY;
+ }
+
+ typefunc = typeinfo->funcs;
+ typevar = typeinfo->vars;
+ for (prop = This->props; prop != end; prop++)
+ {
+ if (!prop->name || prop->type != PROP_JSVAL || !(prop->flags & PROPF_ENUMERABLE))
+ continue;
+
+ if (is_function_prop(prop))
+ {
+ fn = impl_from_IDispatchEx((IDispatchEx*)get_object(prop->u.val));
+ if (!is_source_function(fn)) continue;
+
+ typefunc->prop = prop;
+ typefunc->disp = fn;
+ typefunc++;
+
+ /* The function's object may be deleted, so keep it alive */
+ IDispatchEx_AddRef(&fn->IDispatchEx_iface);
+ }
+ else
+ *typevar++ = prop;
+ }
+
+ /* Keep a ref to the props and their names */
+ IDispatchEx_AddRef(&This->IDispatchEx_iface);
*ppTInfo = &typeinfo->ITypeInfo_iface;
return S_OK;
diff --git a/dlls/jscript/function.c b/dlls/jscript/function.c
index 7a44f50..98d1259 100644
--- a/dlls/jscript/function.c
+++ b/dlls/jscript/function.c
@@ -803,6 +803,11 @@ HRESULT create_source_function(script_ctx_t *ctx, bytecode_t *code, function_cod
return S_OK;
}
+BOOL is_source_function(jsdisp_t *jsdisp)
+{
+ return function_from_jsdisp(jsdisp)->vtbl == &InterpretedFunctionVtbl;
+}
+
static HRESULT BindFunction_call(script_ctx_t *ctx, FunctionInstance *func, IDispatch *this_obj, unsigned flags,
unsigned argc, jsval_t *argv, jsval_t *r)
{
diff --git a/dlls/jscript/jscript.h b/dlls/jscript/jscript.h
index 5d635b7..91923f8 100644
--- a/dlls/jscript/jscript.h
+++ b/dlls/jscript/jscript.h
@@ -303,6 +303,7 @@ HRESULT create_builtin_function(script_ctx_t*,builtin_invoke_t,const WCHAR*,cons
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
HRESULT create_builtin_constructor(script_ctx_t*,builtin_invoke_t,const WCHAR*,const builtin_info_t*,DWORD,
jsdisp_t*,jsdisp_t**) DECLSPEC_HIDDEN;
+BOOL is_source_function(jsdisp_t*) DECLSPEC_HIDDEN;
HRESULT Function_invoke(jsdisp_t*,IDispatch*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
HRESULT Function_value(script_ctx_t*,vdisp_t*,WORD,unsigned,jsval_t*,jsval_t*) DECLSPEC_HIDDEN;
--
2.21.0
Dec. 9, 2019
[PATCH 01/10] jscript: Add script TypeInfo stub.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
v2: Get rid of special case for global script dispatch. However, source
functions are still treated specially, and native/builtin ones ignored
(so that patch has been kept).
Tests added to verify both of these behaviors.
dlls/jscript/dispex.c | 264 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 262 insertions(+), 2 deletions(-)
diff --git a/dlls/jscript/dispex.c b/dlls/jscript/dispex.c
index 463fd2f..92e9b96 100644
--- a/dlls/jscript/dispex.c
+++ b/dlls/jscript/dispex.c
@@ -590,6 +590,254 @@ static HRESULT fill_protrefs(jsdisp_t *This)
return S_OK;
}
+typedef struct {
+ ITypeInfo ITypeInfo_iface;
+ LONG ref;
+} ScriptTypeInfo;
+
+static inline ScriptTypeInfo *ScriptTypeInfo_from_ITypeInfo(ITypeInfo *iface)
+{
+ return CONTAINING_RECORD(iface, ScriptTypeInfo, ITypeInfo_iface);
+}
+
+static HRESULT WINAPI ScriptTypeInfo_QueryInterface(ITypeInfo *iface, REFIID riid, void **ppv)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ if (IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_ITypeInfo, riid))
+ *ppv = &This->ITypeInfo_iface;
+ else
+ {
+ WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+ *ppv = NULL;
+ return E_NOINTERFACE;
+ }
+
+ TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
+ IUnknown_AddRef((IUnknown*)*ppv);
+ return S_OK;
+}
+
+static ULONG WINAPI ScriptTypeInfo_AddRef(ITypeInfo *iface)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ LONG ref = InterlockedIncrement(&This->ref);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ return ref;
+}
+
+static ULONG WINAPI ScriptTypeInfo_Release(ITypeInfo *iface)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ LONG ref = InterlockedDecrement(&This->ref);
+
+ TRACE("(%p) ref=%d\n", This, ref);
+
+ if (!ref)
+ {
+ heap_free(This);
+ }
+ return ref;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetTypeAttr(ITypeInfo *iface, TYPEATTR **ppTypeAttr)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%p)\n", This, ppTypeAttr);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetTypeComp(ITypeInfo *iface, ITypeComp **ppTComp)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%p)\n", This, ppTComp);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetFuncDesc(ITypeInfo *iface, UINT index, FUNCDESC **ppFuncDesc)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%u %p)\n", This, index, ppFuncDesc);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetVarDesc(ITypeInfo *iface, UINT index, VARDESC **ppVarDesc)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%u %p)\n", This, index, ppVarDesc);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetNames(ITypeInfo *iface, MEMBERID memid, BSTR *rgBstrNames,
+ UINT cMaxNames, UINT *pcNames)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%d %p %u %p)\n", This, memid, rgBstrNames, cMaxNames, pcNames);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetRefTypeOfImplType(ITypeInfo *iface, UINT index, HREFTYPE *pRefType)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%u %p)\n", This, index, pRefType);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetImplTypeFlags(ITypeInfo *iface, UINT index, INT *pImplTypeFlags)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%u %p)\n", This, index, pImplTypeFlags);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetIDsOfNames(ITypeInfo *iface, LPOLESTR *rgszNames, UINT cNames,
+ MEMBERID *pMemId)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%p %u %p)\n", This, rgszNames, cNames, pMemId);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_Invoke(ITypeInfo *iface, PVOID pvInstance, MEMBERID memid, WORD wFlags,
+ DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%p %d %d %p %p %p %p)\n", This, pvInstance, memid, wFlags,
+ pDispParams, pVarResult, pExcepInfo, puArgErr);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetDocumentation(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrName,
+ BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%d %p %p %p %p)\n", This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetDllEntry(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind,
+ BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%d %d %p %p %p)\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetRefTypeInfo(ITypeInfo *iface, HREFTYPE hRefType, ITypeInfo **ppTInfo)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%x %p)\n", This, hRefType, ppTInfo);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_AddressOfMember(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%d %d %p)\n", This, memid, invKind, ppv);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_CreateInstance(ITypeInfo *iface, IUnknown *pUnkOuter, REFIID riid, PVOID *ppvObj)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%p %s %p)\n", This, pUnkOuter, debugstr_guid(riid), ppvObj);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetMops(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrMops)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%d %p)\n", This, memid, pBstrMops);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ScriptTypeInfo_GetContainingTypeLib(ITypeInfo *iface, ITypeLib **ppTLib, UINT *pIndex)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%p %p)\n", This, ppTLib, pIndex);
+
+ return E_NOTIMPL;
+}
+
+static void WINAPI ScriptTypeInfo_ReleaseTypeAttr(ITypeInfo *iface, TYPEATTR *pTypeAttr)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%p)\n", This, pTypeAttr);
+}
+
+static void WINAPI ScriptTypeInfo_ReleaseFuncDesc(ITypeInfo *iface, FUNCDESC *pFuncDesc)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%p)\n", This, pFuncDesc);
+}
+
+static void WINAPI ScriptTypeInfo_ReleaseVarDesc(ITypeInfo *iface, VARDESC *pVarDesc)
+{
+ ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+
+ FIXME("(%p)->(%p)\n", This, pVarDesc);
+}
+
+static const ITypeInfoVtbl ScriptTypeInfoVtbl = {
+ ScriptTypeInfo_QueryInterface,
+ ScriptTypeInfo_AddRef,
+ ScriptTypeInfo_Release,
+ ScriptTypeInfo_GetTypeAttr,
+ ScriptTypeInfo_GetTypeComp,
+ ScriptTypeInfo_GetFuncDesc,
+ ScriptTypeInfo_GetVarDesc,
+ ScriptTypeInfo_GetNames,
+ ScriptTypeInfo_GetRefTypeOfImplType,
+ ScriptTypeInfo_GetImplTypeFlags,
+ ScriptTypeInfo_GetIDsOfNames,
+ ScriptTypeInfo_Invoke,
+ ScriptTypeInfo_GetDocumentation,
+ ScriptTypeInfo_GetDllEntry,
+ ScriptTypeInfo_GetRefTypeInfo,
+ ScriptTypeInfo_AddressOfMember,
+ ScriptTypeInfo_CreateInstance,
+ ScriptTypeInfo_GetMops,
+ ScriptTypeInfo_GetContainingTypeLib,
+ ScriptTypeInfo_ReleaseTypeAttr,
+ ScriptTypeInfo_ReleaseFuncDesc,
+ ScriptTypeInfo_ReleaseVarDesc
+};
+
static inline jsdisp_t *impl_from_IDispatchEx(IDispatchEx *iface)
{
return CONTAINING_RECORD(iface, jsdisp_t, IDispatchEx_iface);
@@ -649,8 +897,20 @@ static HRESULT WINAPI DispatchEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LC
ITypeInfo **ppTInfo)
{
jsdisp_t *This = impl_from_IDispatchEx(iface);
- FIXME("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
- return E_NOTIMPL;
+ ScriptTypeInfo *typeinfo;
+
+ TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
+
+ if (iTInfo != 0) return DISP_E_BADINDEX;
+
+ if (!(typeinfo = heap_alloc(sizeof(*typeinfo))))
+ return E_OUTOFMEMORY;
+
+ typeinfo->ITypeInfo_iface.lpVtbl = &ScriptTypeInfoVtbl;
+ typeinfo->ref = 1;
+
+ *ppTInfo = &typeinfo->ITypeInfo_iface;
+ return S_OK;
}
static HRESULT WINAPI DispatchEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
--
2.21.0
Dec. 9, 2019
Re: [PATCH 2/2] comctl32: Fixed rebar behaviour when there's capture and no drag
by Vijay Kiran Kamuju
Hi Andrew,
On Monday, December 9, 2019, Andrej Shadura <andrew(a)shadura.me> wrote:
> Hi again,
>
> On Mon, 9 Dec 2019 at 16:48, Andrej Shadura <bugzilla(a)tut.by> wrote:
> > On Mon, 9 Dec 2019 at 16:20, Vijay Kiran Kamuju <infyquest(a)gmail.com>
> wrote:
> > > From: Andrew Shadura <bugzilla(a)tut.by>
>
> I forgot one thing. Could you please also replace "Fixed" (past tense)
> to "Fix"? My commit message style from 11 years ago was worse than it
> is now :D
>
> > First of all, if you’re going to drive this patch to being accepted,
>
> This is an initial attempt to resubmit for review the age-old patch,
which is left untouched. It's working in staging for the last few months
and release freeze is coming up. This the time to revive the old bug fixes
which are working. I will update and resend tomorrow if there are new
comments.
Also, thank you for picking this up! Unfortunately, I’m afraid,
> there’s not much I can help with it since it’s been such a long time
> and I’ve forgotten what I still knew 11 years ago about WinAPI :)
>
> I am waiting for reviewer's comment. If tests are needed then what kind of
are needed.
---
Cheers,
Vijay
> --
> Cheers,
> Andrej
>
Dec. 9, 2019
Re: [PATCH 2/2] comctl32: Fixed rebar behaviour when there's capture and no drag
by Andrej Shadura
Hi again,
On Mon, 9 Dec 2019 at 16:48, Andrej Shadura <bugzilla(a)tut.by> wrote:
> On Mon, 9 Dec 2019 at 16:20, Vijay Kiran Kamuju <infyquest(a)gmail.com> wrote:
> > From: Andrew Shadura <bugzilla(a)tut.by>
I forgot one thing. Could you please also replace "Fixed" (past tense)
to "Fix"? My commit message style from 11 years ago was worse than it
is now :D
> First of all, if you’re going to drive this patch to being accepted,
Also, thank you for picking this up! Unfortunately, I’m afraid,
there’s not much I can help with it since it’s been such a long time
and I’ve forgotten what I still knew 11 years ago about WinAPI :)
--
Cheers,
Andrej
Dec. 9, 2019
[PATCH] ntoskrnl.exe: Avoid infinite recursion loading drivers.
by Chip Davis
Aside from the fact that both ntoskrnl and hal are already loaded and
resolved, ntoskrnl and hal have a cyclic dependency on each other.
This results in infinite recursion attempting to relocate both modules.
Signed-off-by: Chip Davis <cdavis(a)codeweavers.com>
---
dlls/ntoskrnl.exe/ntoskrnl.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 4c196bc1c98..3f457461fff 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -3515,6 +3515,9 @@ static HMODULE load_driver_module( const WCHAR *name )
char *name = (char *)module + imports[i].Name;
WCHAR buffer[32], *p = buffer;
+ /* avoid infinite recursion - don't do this for this module (ntoskrnl) or hal.dll */
+ if (!strcmp( name, "ntoskrnl.exe" ) || !strcmp( name, "hal.dll" ))
+ continue;
while (p < buffer + 32) if (!(*p++ = *name++)) break;
if (p <= buffer + 32) FreeLibrary( load_driver_module( buffer ) );
}
--
2.24.0
Dec. 9, 2019
Re: [PATCH 2/2] comctl32: Fixed rebar behaviour when there's capture and no drag
by Andrej Shadura
Hi Vijay,
On Mon, 9 Dec 2019 at 16:20, Vijay Kiran Kamuju <infyquest(a)gmail.com> wrote:
> From: Andrew Shadura <bugzilla(a)tut.by>
First of all, if you’re going to drive this patch to being accepted,
please use my new address:
From: Andrej Shadura <andrew(a)shadura.me>
> Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=14750
> From: Andrew Shadura <bugzilla(a)tut.by>
> Signed-off-by: Vijay Kiran Kamuju <infyquest(a)gmail.com>
Similarly:
Signed-off-by: Andrej Shadura <andrew(a)shadura.me>
Other than that, I remember the reason it wasn’t accepted was that I
didn’t provide any tests. I came up with this code by reverse
engineering how Proteus behaved on Wine and on Windows, but I couldn’t
find any reference or a reason for it to expect things this way, so I
gave up.
Have you figured this out? Because I’m afraid this patch won’t be
accepted as it is now.
--
Cheers,
Andrej
Dec. 9, 2019
Re: [PATCH] kernel32: return S_OK in RegisterApplicationRecoveryCallback stub (resend)
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61686
Your paranoid android.
=== debian10 (32 bit report) ===
kernel32:
comm.c:918: Test failed: OutQueue should not be empty
=== debian10 (32 bit WoW report) ===
kernel32:
debugger: Timeout
Dec. 9, 2019
Re: [PATCH 03/14] vbscript/tests: Add tests for the script TypeInfo's TypeComp binds.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Dec. 9, 2019
Re: [PATCH 02/14] vbscript: Implement ScriptTypeComp_BindType.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Dec. 9, 2019
Re: [PATCH 01/14] vbscript: Implement ScriptTypeComp_Bind.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Dec. 9, 2019
Re: [PATCH] vbscript: Don't free procs allocated in the heap pool.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
Dec. 9, 2019
[PATCH] kernel32: return S_OK in RegisterApplicationRecoveryCallback stub (resend)
by Louis Lenders
rebased patch against current git (to make testbot happier)
https://bugs.winehq.org/show_bug.cgi?id=43817
Signed-off-by: Louis Lenders <xerox.xerox2000x(a)gmail.com>
---
dlls/kernel32/process.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c
index 779c13cb54..1984aa0701 100644
--- a/dlls/kernel32/process.c
+++ b/dlls/kernel32/process.c
@@ -902,9 +902,8 @@ HRESULT WINAPI ApplicationRecoveryInProgress(PBOOL canceled)
*/
HRESULT WINAPI RegisterApplicationRecoveryCallback(APPLICATION_RECOVERY_CALLBACK callback, PVOID param, DWORD pingint, DWORD flags)
{
- FIXME("%p, %p, %d, %d: stub\n", callback, param, pingint, flags);
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- return E_FAIL;
+ FIXME("%p, %p, %d, %d: stub, faking success\n", callback, param, pingint, flags);
+ return S_OK;
}
/***********************************************************************
--
2.24.0
Dec. 9, 2019
Re: [PATCH 2/2] mshtml: Support loading Gecko from global location.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61683
Your paranoid android.
=== debian10 (32 bit report) ===
mshtml:
htmllocation.c:346: Test failed: FILE: IPersistMoniker_Load failed: 0x800c0005
=== debian10 (32 bit Chinese:China report) ===
mshtml:
htmllocation.c:346: Test failed: FILE: IPersistMoniker_Load failed: 0x800c0005
=== debian10 (32 bit WoW report) ===
mshtml:
htmllocation.c:346: Test failed: FILE: IPersistMoniker_Load failed: 0x800c0005
=== debian10 (64 bit WoW report) ===
mshtml:
htmllocation.c:346: Test failed: FILE: IPersistMoniker_Load failed: 0x800c0005
Dec. 9, 2019
Re: [PATCH 1/2] mshtml: Refactor Gecko loading code.
by Marvin
Hi,
While running your changed tests, I think I found new failures.
Being a bot and all I'm not very good at pattern recognition, so I might be
wrong, but could you please double-check?
Full results can be found at:
https://testbot.winehq.org/JobDetails.pl?Key=61682
Your paranoid android.
=== debian10 (32 bit report) ===
mshtml:
htmllocation.c:346: Test failed: FILE: IPersistMoniker_Load failed: 0x800c0005
=== debian10 (32 bit Chinese:China report) ===
mshtml:
htmllocation.c:346: Test failed: FILE: IPersistMoniker_Load failed: 0x800c0005
=== debian10 (32 bit WoW report) ===
mshtml:
htmllocation.c:346: Test failed: FILE: IPersistMoniker_Load failed: 0x800c0005
=== debian10 (64 bit WoW report) ===
mshtml:
htmllocation.c:346: Test failed: FILE: IPersistMoniker_Load failed: 0x800c0005
Dec. 9, 2019
[PATCH 2/2] comctl32: Fixed rebar behaviour when there's capture and no drag
by Vijay Kiran Kamuju
From: Andrew Shadura <bugzilla(a)tut.by>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=14750
From: Andrew Shadura <bugzilla(a)tut.by>
Signed-off-by: Vijay Kiran Kamuju <infyquest(a)gmail.com>
---
dlls/comctl32/rebar.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/dlls/comctl32/rebar.c b/dlls/comctl32/rebar.c
index 6bca2f1818..92384ec506 100644
--- a/dlls/comctl32/rebar.c
+++ b/dlls/comctl32/rebar.c
@@ -3120,7 +3120,15 @@ REBAR_MouseMove (REBAR_INFO *infoPtr, LPARAM lParam)
int yPtMove = (infoPtr->dwStyle & CCS_VERT ? ptMove.x : ptMove.y);
if (GetCapture() != infoPtr->hwndSelf)
- ERR("We are dragging but haven't got capture?!?\n");
+ {
+ if (infoPtr->fStatus & BEGIN_DRAG_ISSUED)
+ {
+ REBAR_Notify_NMREBAR (infoPtr, infoPtr->iGrabbedBand, RBN_ENDDRAG);
+ infoPtr->fStatus &= ~BEGIN_DRAG_ISSUED;
+ }
+ infoPtr->iGrabbedBand = -1;
+ return 0;
+ }
band = REBAR_GetBand(infoPtr, infoPtr->iGrabbedBand);
--
2.21.0
Dec. 9, 2019
[PATCH 1/2] comctl32: Preserve custom colors between subitems. (v2)
by Vijay Kiran Kamuju
From: Michael Müller <michael(a)fds-team.de>
From: Michael Müller <michael(a)fds-team.de>
Signed-off-by: Vijay Kiran Kamuju <infyquest(a)gmail.com>
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=38941
---
dlls/comctl32/listview.c | 20 +++++++++-----------
dlls/comctl32/tests/listview.c | 23 ++++++++++++++++++++---
2 files changed, 29 insertions(+), 14 deletions(-)
diff --git a/dlls/comctl32/listview.c b/dlls/comctl32/listview.c
index eb42526f57..4799920e3a 100644
--- a/dlls/comctl32/listview.c
+++ b/dlls/comctl32/listview.c
@@ -1065,7 +1065,7 @@ static void prepaint_setup (const LISTVIEW_INFO *infoPtr, HDC hdc, NMLVCUSTOMDRA
COLORREF backcolor, textcolor;
/* apparently, for selected items, we have to override the returned values */
- if (!SubItem)
+ if (!SubItem || (infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
{
if (lpnmlvcd->nmcd.uItemState & CDIS_SELECTED)
{
@@ -4791,6 +4791,7 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, ITERAT
while (iterator_next(subitems))
{
DWORD subitemstage = CDRF_DODEFAULT;
+ NMLVCUSTOMDRAW temp_nmlvcd;
/* We need to query for each subitem, item's data (subitem == 0) is already here at this point */
if (subitems->nItem)
@@ -4817,19 +4818,16 @@ static BOOL LISTVIEW_DrawItem(LISTVIEW_INFO *infoPtr, HDC hdc, INT nItem, ITERAT
if (cdsubitemmode & CDRF_NOTIFYSUBITEMDRAW)
subitemstage = notify_customdraw(infoPtr, CDDS_SUBITEM | CDDS_ITEMPREPAINT, &nmlvcd);
- else
- {
- nmlvcd.clrTextBk = infoPtr->clrTextBk;
- nmlvcd.clrText = infoPtr->clrText;
- }
- if (subitems->nItem == 0 || (cdmode & CDRF_NOTIFYITEMDRAW))
- prepaint_setup(infoPtr, hdc, &nmlvcd, FALSE);
- else if (!(infoPtr->dwLvExStyle & LVS_EX_FULLROWSELECT))
- prepaint_setup(infoPtr, hdc, &nmlvcd, TRUE);
+ /*
+ * A selection should neither affect the colors in the post paint notification nor
+ * affect the colors of the next drawn subitem. Copy the structure to prevent this.
+ */
+ temp_nmlvcd = nmlvcd;
+ prepaint_setup(infoPtr, hdc, &temp_nmlvcd, subitems->nItem);
if (!(subitemstage & CDRF_SKIPDEFAULT))
- LISTVIEW_DrawItemPart(infoPtr, &lvItem, &nmlvcd, &pos);
+ LISTVIEW_DrawItemPart(infoPtr, &lvItem, &temp_nmlvcd, &pos);
if (subitemstage & CDRF_NOTIFYPOSTPAINT)
subitemstage = notify_customdraw(infoPtr, CDDS_SUBITEM | CDDS_ITEMPOSTPAINT, &nmlvcd);
diff --git a/dlls/comctl32/tests/listview.c b/dlls/comctl32/tests/listview.c
index 87f644abd1..57cb227189 100644
--- a/dlls/comctl32/tests/listview.c
+++ b/dlls/comctl32/tests/listview.c
@@ -1938,12 +1938,16 @@ static LRESULT WINAPI cd_wndproc(HWND hwnd, UINT message, WPARAM wParam, LPARAM
clr = GetBkColor(nmlvcd->nmcd.hdc);
ok(nmlvcd->clrTextBk == CLR_DEFAULT, "got 0x%x\n", nmlvcd->clrTextBk);
ok(nmlvcd->clrText == RGB(0, 255, 0), "got 0x%x\n", nmlvcd->clrText);
- todo_wine_if(nmlvcd->iSubItem)
- ok(clr == c0ffee, "clr=%.8x\n", clr);
+ if (!(GetWindowLongW(nmhdr->hwndFrom, GWL_STYLE) & LVS_SHOWSELALWAYS))
+ {
+ todo_wine_if(nmlvcd->iSubItem)
+ ok(clr == c0ffee, "clr=%.8x\n", clr);
+ }
return CDRF_NOTIFYPOSTPAINT;
case CDDS_ITEMPOSTPAINT | CDDS_SUBITEM:
clr = GetBkColor(nmlvcd->nmcd.hdc);
- todo_wine ok(clr == c0ffee, "clr=%.8x\n", clr);
+ if (!(GetWindowLongW(nmhdr->hwndFrom, GWL_STYLE) & LVS_SHOWSELALWAYS))
+ todo_wine ok(clr == c0ffee, "clr=%.8x\n", clr);
ok(nmlvcd->clrTextBk == CLR_DEFAULT, "got 0x%x\n", nmlvcd->clrTextBk);
ok(nmlvcd->clrText == RGB(0, 255, 0), "got 0x%x\n", nmlvcd->clrText);
return CDRF_DODEFAULT;
@@ -1959,6 +1963,7 @@ static void test_customdraw(void)
{
HWND hwnd;
WNDPROC oldwndproc;
+ LVITEMA item;
hwnd = create_listview_control(LVS_REPORT);
@@ -1978,6 +1983,18 @@ static void test_customdraw(void)
UpdateWindow(hwnd);
ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_report_cd_seq, "parent customdraw, LVS_REPORT", FALSE);
+ /* check colors when item is selected */
+ SetWindowLongW(hwnd, GWL_STYLE, GetWindowLongW(hwnd, GWL_STYLE) | LVS_SHOWSELALWAYS);
+ item.mask = LVIF_STATE;
+ item.stateMask = LVIS_SELECTED;
+ item.state = LVIS_SELECTED;
+ SendMessageA(hwnd, LVM_SETITEMSTATE, 0, (LPARAM)&item);
+
+ flush_sequences(sequences, NUM_MSG_SEQUENCES);
+ InvalidateRect(hwnd, NULL, TRUE);
+ UpdateWindow(hwnd);
+ ok_sequence(sequences, PARENT_CD_SEQ_INDEX, parent_report_cd_seq, "parent customdraw, LVS_REPORT, selection", FALSE);
+
DestroyWindow(hwnd);
hwnd = create_listview_control(LVS_LIST);
--
2.21.0
Dec. 9, 2019
[PATCH 2/2] mshtml: Support loading Gecko from global location.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/mshtml/Makefile.in | 2 ++
dlls/mshtml/nsembed.c | 70 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 72 insertions(+)
Dec. 9, 2019
[PATCH 1/2] mshtml: Refactor Gecko loading code.
by Jacek Caban
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/mshtml/nsembed.c | 271 ++++++++++++++++++++----------------------
1 file changed, 132 insertions(+), 139 deletions(-)
Dec. 9, 2019
Re: [PATCH 02/10] jscript: Store the necessary function and variable info in the script TypeInfo.
by Gabriel Ivăncescu
On 12/9/19 5:24 PM, Gabriel Ivăncescu wrote:
> On 12/9/19 4:56 PM, Jacek Caban wrote:
>> On 12/9/19 3:01 PM, Gabriel Ivăncescu wrote:
>>> +BOOL is_source_function(jsdisp_t *jsdisp)
>>> +{
>>> + return function_from_jsdisp(jsdisp)->vtbl ==
>>> &InterpretedFunctionVtbl;
>>> +}
>>
>>
>> I'm not sure about that, are native functions really not treated as
>> functions? It should be easy to test with something like:
>>
>> var native_func = decodeURI;
>>
>>
>> Thanks,
>>
>> Jacek
>>
>
> Ok, I'll see about the tests, but I was actually more worried about how
> to get the args and their names for native functions (didn't know how).
Looks like indeed native functions are completely ignored: they don't
show up as variables, either.
So do I keep this patch it as-is?
Dec. 9, 2019
[PATCH 14/14] vbscript/tests: Add more tests for the script TypeInfo.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/vbscript/tests/vbscript.c | 126 ++++++++++++++++++++++++++++++++-
1 file changed, 125 insertions(+), 1 deletion(-)
diff --git a/dlls/vbscript/tests/vbscript.c b/dlls/vbscript/tests/vbscript.c
index ad3ccf3..f0b75ad 100644
--- a/dlls/vbscript/tests/vbscript.c
+++ b/dlls/vbscript/tests/vbscript.c
@@ -893,12 +893,16 @@ static void test_script_typeinfo(void)
FUNCDESC *funcdesc;
VARDESC *vardesc;
DESCKIND desckind;
+ INT implTypeFlags;
+ UINT count, index;
+ HREFTYPE reftype;
BINDPTR bindptr;
MEMBERID memid;
TYPEATTR *attr;
- UINT index;
HRESULT hr;
WCHAR str[64], *names = str;
+ BSTR bstr, bstrs[5];
+ void *obj;
int i;
vbscript = create_vbscript();
@@ -961,6 +965,20 @@ static void test_script_typeinfo(void)
ok(typeinfo != typeinfo2, "TypeInfo was not supposed to be shared.\n");
ITypeInfo_Release(typeinfo2);
+ obj = (void*)0xdeadbeef;
+ hr = ITypeInfo_CreateInstance(typeinfo, NULL, NULL, NULL);
+ ok(hr == E_INVALIDARG, "CreateInstance returned: %08x\n", hr);
+ hr = ITypeInfo_CreateInstance(typeinfo, NULL, NULL, &obj);
+ ok(hr == TYPE_E_BADMODULEKIND, "CreateInstance returned: %08x\n", hr);
+ hr = ITypeInfo_CreateInstance(typeinfo, NULL, &IID_IDispatch, &obj);
+ ok(hr == TYPE_E_BADMODULEKIND, "CreateInstance returned: %08x\n", hr);
+ ok(!obj, "Unexpected non-null obj %p.\n", obj);
+
+ hr = ITypeInfo_GetDocumentation(typeinfo, MEMBERID_NIL, &bstr, NULL, NULL, NULL);
+ ok(hr == S_OK, "GetDocumentation(MEMBERID_NIL) failed: %08x\n", hr);
+ ok(!lstrcmpW(bstr, L"VBScriptTypeInfo"), "Unexpected TypeInfo name %s\n", wine_dbgstr_w(bstr));
+ SysFreeString(bstr);
+
hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
ok(hr == S_OK, "GetTypeAttr failed: %08x\n", hr);
ok(IsEqualGUID(&attr->guid, &IID_IScriptTypeInfo), "Unexpected GUID %s\n", wine_dbgstr_guid(&attr->guid));
@@ -979,6 +997,45 @@ static void test_script_typeinfo(void)
ok(attr->idldescType.wIDLFlags == IDLFLAG_NONE, "Unexpected idldescType.wIDLFlags 0x%x\n", attr->idldescType.wIDLFlags);
ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
+ /* The type inherits from IDispatch */
+ hr = ITypeInfo_GetImplTypeFlags(typeinfo, 0, NULL);
+ ok(hr == E_INVALIDARG, "GetImplTypeFlags returned: %08x\n", hr);
+ hr = ITypeInfo_GetImplTypeFlags(typeinfo, 1, &implTypeFlags);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetImplTypeFlags returned: %08x\n", hr);
+ hr = ITypeInfo_GetImplTypeFlags(typeinfo, -1, &implTypeFlags);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetImplTypeFlags returned: %08x\n", hr);
+ hr = ITypeInfo_GetImplTypeFlags(typeinfo, 0, &implTypeFlags);
+ ok(hr == S_OK, "GetImplTypeFlags failed: %08x\n", hr);
+ ok(implTypeFlags == 0, "Unexpected implTypeFlags 0x%x\n", implTypeFlags);
+
+ hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, 0, NULL);
+ ok(hr == E_INVALIDARG, "GetRefTypeOfImplType returned: %08x\n", hr);
+ hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, 1, &reftype);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetRefTypeOfImplType returned: %08x\n", hr);
+ hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, -1, &reftype);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetRefTypeOfImplType failed: %08x\n", hr);
+ hr = ITypeInfo_GetRefTypeOfImplType(typeinfo, 0, &reftype);
+ ok(hr == S_OK, "GetRefTypeOfImplType failed: %08x\n", hr);
+ ok(reftype == 1, "Unexpected reftype %d\n", reftype);
+
+ hr = ITypeInfo_GetRefTypeInfo(typeinfo, reftype, NULL);
+ ok(hr == E_INVALIDARG, "GetRefTypeInfo returned: %08x\n", hr);
+ hr = ITypeInfo_GetRefTypeInfo(typeinfo, -1, &typeinfo2);
+ ok(hr == E_INVALIDARG, "GetRefTypeInfo returned: %08x\n", hr);
+ hr = ITypeInfo_GetRefTypeInfo(typeinfo, 4, &typeinfo2);
+ ok(hr == E_FAIL, "GetRefTypeInfo returned: %08x\n", hr);
+ hr = ITypeInfo_GetRefTypeInfo(typeinfo, 0, &typeinfo2);
+ ok(hr == S_OK, "GetRefTypeInfo failed: %08x\n", hr);
+ ok(typeinfo == typeinfo2, "Unexpected TypeInfo %p (expected %p)\n", typeinfo2, typeinfo);
+ ITypeInfo_Release(typeinfo2);
+ hr = ITypeInfo_GetRefTypeInfo(typeinfo, reftype, &typeinfo2);
+ ok(hr == S_OK, "GetRefTypeInfo failed: %08x\n", hr);
+ hr = ITypeInfo_GetDocumentation(typeinfo2, MEMBERID_NIL, &bstr, NULL, NULL, NULL);
+ ok(hr == S_OK, "GetDocumentation(MEMBERID_NIL) failed: %08x\n", hr);
+ ok(!lstrcmpW(bstr, L"IDispatch"), "Unexpected TypeInfo name %s\n", wine_dbgstr_w(bstr));
+ ITypeInfo_Release(typeinfo2);
+ SysFreeString(bstr);
+
/* GetIDsOfNames looks into the inherited types as well */
wcscpy(str, L"queryinterface");
hr = ITypeInfo_GetIDsOfNames(typeinfo, NULL, 1, &memid);
@@ -998,6 +1055,53 @@ static void test_script_typeinfo(void)
ok(hr == S_OK, "GetIDsOfNames failed: %08x\n", hr);
ok(!lstrcmpW(str, L"SUBtract"), "Unexpected string %s\n", wine_dbgstr_w(str));
+ hr = ITypeInfo_GetNames(typeinfo, memid, NULL, 1, &count);
+ ok(hr == E_INVALIDARG, "GetNames returned: %08x\n", hr);
+ hr = ITypeInfo_GetNames(typeinfo, memid, bstrs, 1, NULL);
+ ok(hr == E_INVALIDARG, "GetNames returned: %08x\n", hr);
+ hr = ITypeInfo_GetNames(typeinfo, memid, bstrs, 0, &count);
+ ok(hr == S_OK, "GetNames failed: %08x\n", hr);
+ ok(count == 0, "Unexpected count %u\n", count);
+ hr = ITypeInfo_GetNames(typeinfo, memid, bstrs, ARRAY_SIZE(bstrs), &count);
+ ok(hr == S_OK, "GetNames failed: %08x\n", hr);
+ ok(count == 3, "Unexpected count %u\n", count);
+ ok(!lstrcmpW(bstrs[0], L"subtract"), "Unexpected function name %s\n", wine_dbgstr_w(bstrs[0]));
+ ok(!lstrcmpW(bstrs[1], L"x"), "Unexpected function first param name %s\n", wine_dbgstr_w(bstrs[1]));
+ ok(!lstrcmpW(bstrs[2], L"y"), "Unexpected function second param name %s\n", wine_dbgstr_w(bstrs[2]));
+ for (i = 0; i < count; i++) SysFreeString(bstrs[i]);
+
+ hr = ITypeInfo_GetMops(typeinfo, memid, NULL);
+ ok(hr == E_INVALIDARG, "GetMops returned: %08x\n", hr);
+ hr = ITypeInfo_GetMops(typeinfo, memid, &bstr);
+ ok(hr == S_OK, "GetMops failed: %08x\n", hr);
+ ok(!bstr, "Unexpected non-null string %s\n", wine_dbgstr_w(bstr));
+ hr = ITypeInfo_GetMops(typeinfo, MEMBERID_NIL, &bstr);
+ ok(hr == S_OK, "GetMops failed: %08x\n", hr);
+ ok(!bstr, "Unexpected non-null string %s\n", wine_dbgstr_w(bstr));
+
+ /* These always fail */
+ obj = (void*)0xdeadbeef;
+ hr = ITypeInfo_AddressOfMember(typeinfo, memid, INVOKE_FUNC, NULL);
+ ok(hr == E_INVALIDARG, "AddressOfMember returned: %08x\n", hr);
+ hr = ITypeInfo_AddressOfMember(typeinfo, memid, INVOKE_FUNC, &obj);
+ ok(hr == TYPE_E_BADMODULEKIND, "AddressOfMember returned: %08x\n", hr);
+ ok(!obj, "Unexpected non-null obj %p.\n", obj);
+ bstr = (BSTR)0xdeadbeef;
+ hr = ITypeInfo_GetDllEntry(typeinfo, memid, INVOKE_FUNC, &bstr, NULL, NULL);
+ ok(hr == TYPE_E_BADMODULEKIND, "GetDllEntry returned: %08x\n", hr);
+ ok(!bstr, "Unexpected non-null str %p.\n", bstr);
+ wcscpy(str, L"Invoke");
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 1, &memid);
+ ok(hr == S_OK, "GetIDsOfNames failed: %08x\n", hr);
+ obj = (void*)0xdeadbeef;
+ hr = ITypeInfo_AddressOfMember(typeinfo, memid, INVOKE_FUNC, &obj);
+ ok(hr == TYPE_E_BADMODULEKIND, "AddressOfMember returned: %08x\n", hr);
+ ok(!obj, "Unexpected non-null obj %p.\n", obj);
+ bstr = (BSTR)0xdeadbeef;
+ hr = ITypeInfo_GetDllEntry(typeinfo, memid, INVOKE_FUNC, &bstr, NULL, NULL);
+ ok(hr == TYPE_E_BADMODULEKIND, "GetDllEntry returned: %08x\n", hr);
+ ok(!bstr, "Unexpected non-null str %p.\n", bstr);
+
/* Check variable descriptions */
hr = ITypeInfo_GetVarDesc(typeinfo, 0, NULL);
ok(hr == E_INVALIDARG, "GetVarDesc returned: %08x\n", hr);
@@ -1007,6 +1111,12 @@ static void test_script_typeinfo(void)
{
hr = ITypeInfo_GetVarDesc(typeinfo, i, &vardesc);
ok(hr == S_OK, "GetVarDesc(%u) failed: %08x\n", i, hr);
+ hr = ITypeInfo_GetDocumentation(typeinfo, vardesc->memid, &bstr, &bstrs[0], NULL, NULL);
+ ok(hr == S_OK, "[%u] GetDocumentation failed: %08x\n", i, hr);
+ ok(!lstrcmpW(bstr, var[i].name), "[%u] Unexpected variable name %s (expected %s)\n",
+ i, wine_dbgstr_w(bstr), wine_dbgstr_w(var[i].name));
+ ok(!bstrs[0], "[%u] Unexpected doc string %s\n", i, wine_dbgstr_w(bstrs[0]));
+ SysFreeString(bstr);
ok(vardesc->lpstrSchema == NULL, "[%u] Unexpected lpstrSchema %p\n", i, vardesc->lpstrSchema);
ok(vardesc->oInst == 0, "[%u] Unexpected oInst %u\n", i, vardesc->oInst);
ok(vardesc->varkind == VAR_DISPATCH, "[%u] Unexpected varkind %d\n", i, vardesc->varkind);
@@ -1029,6 +1139,12 @@ static void test_script_typeinfo(void)
{
hr = ITypeInfo_GetFuncDesc(typeinfo, i, &funcdesc);
ok(hr == S_OK, "GetFuncDesc(%u) failed: %08x\n", i, hr);
+ hr = ITypeInfo_GetDocumentation(typeinfo, funcdesc->memid, &bstr, &bstrs[0], NULL, NULL);
+ ok(hr == S_OK, "[%u] GetDocumentation failed: %08x\n", i, hr);
+ ok(!lstrcmpW(bstr, func[i].name), "[%u] Unexpected function name %s (expected %s)\n",
+ i, wine_dbgstr_w(bstr), wine_dbgstr_w(func[i].name));
+ ok(!bstrs[0], "[%u] Unexpected doc string %s\n", i, wine_dbgstr_w(bstrs[0]));
+ SysFreeString(bstr);
ok(funcdesc->lprgscode == NULL, "[%u] Unexpected lprgscode %p\n", i, funcdesc->lprgscode);
ok(func[i].num_args ? (funcdesc->lprgelemdescParam != NULL) : (funcdesc->lprgelemdescParam == NULL),
"[%u] Unexpected lprgelemdescParam %p\n", i, funcdesc->lprgelemdescParam);
@@ -1159,6 +1275,14 @@ static void test_script_typeinfo(void)
ok(attr->cFuncs == ARRAY_SIZE(func) + 1, "Unexpected cFuncs %u\n", attr->cFuncs);
ok(attr->cVars == ARRAY_SIZE(var) + 1, "Unexpected cVars %u\n", attr->cVars);
ITypeInfo_ReleaseTypeAttr(typeinfo2, attr);
+ hr = ITypeInfo_GetVarDesc(typeinfo2, ARRAY_SIZE(var), &vardesc);
+ ok(hr == S_OK, "GetVarDesc failed: %08x\n", hr);
+ hr = ITypeInfo_GetDocumentation(typeinfo2, vardesc->memid, &bstr, &bstrs[0], NULL, NULL);
+ ok(hr == S_OK, "GetDocumentation failed: %08x\n", hr);
+ ok(!lstrcmpW(bstr, L"new_var"), "Unexpected variable name %s\n", wine_dbgstr_w(bstr));
+ ok(!bstrs[0], "Unexpected doc string %s\n", wine_dbgstr_w(bstrs[0]));
+ ITypeInfo_ReleaseVarDesc(typeinfo2, vardesc);
+ SysFreeString(bstr);
hr = ITypeInfo_GetFuncDesc(typeinfo, 0, &funcdesc);
ok(hr == S_OK, "GetFuncDesc failed: %08x\n", hr);
ok(funcdesc->cParams == 0, "Unexpected cParams %d\n", funcdesc->cParams);
--
2.21.0
Dec. 9, 2019
[PATCH 13/14] vbscript: Implement ScriptTypeInfo_GetMops.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/vbscript/vbdisp.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 0ea785c..4601ef5 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -1027,10 +1027,23 @@ static HRESULT WINAPI ScriptTypeInfo_CreateInstance(ITypeInfo *iface, IUnknown *
static HRESULT WINAPI ScriptTypeInfo_GetMops(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrMops)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ ITypeInfo *disp_typeinfo;
+ HRESULT hr;
- FIXME("(%p)->(%d %p)\n", This, memid, pBstrMops);
+ TRACE("(%p)->(%d %p)\n", This, memid, pBstrMops);
- return E_NOTIMPL;
+ if (!pBstrMops) return E_INVALIDARG;
+
+ if (get_memid_type(This, memid) == memid_inherited)
+ {
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ return ITypeInfo_GetMops(disp_typeinfo, memid, pBstrMops);
+ }
+
+ *pBstrMops = NULL;
+ return S_OK;
}
static HRESULT WINAPI ScriptTypeInfo_GetContainingTypeLib(ITypeInfo *iface, ITypeLib **ppTLib, UINT *pIndex)
--
2.21.0
Dec. 9, 2019
[PATCH 12/14] vbscript: Implement ScriptTypeInfo_CreateInstance.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/vbscript/vbdisp.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 447700f..0ea785c 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -1016,9 +1016,12 @@ static HRESULT WINAPI ScriptTypeInfo_CreateInstance(ITypeInfo *iface, IUnknown *
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
- FIXME("(%p)->(%p %s %p)\n", This, pUnkOuter, debugstr_guid(riid), ppvObj);
+ TRACE("(%p)->(%p %s %p)\n", This, pUnkOuter, debugstr_guid(riid), ppvObj);
- return E_NOTIMPL;
+ if (!ppvObj) return E_INVALIDARG;
+
+ *ppvObj = NULL;
+ return TYPE_E_BADMODULEKIND;
}
static HRESULT WINAPI ScriptTypeInfo_GetMops(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrMops)
--
2.21.0
Dec. 9, 2019
[PATCH 11/14] vbscript: Implement ScriptTypeInfo_AddressOfMember.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/vbscript/vbdisp.c | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 9f34f78..447700f 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -994,10 +994,22 @@ static HRESULT WINAPI ScriptTypeInfo_GetRefTypeInfo(ITypeInfo *iface, HREFTYPE h
static HRESULT WINAPI ScriptTypeInfo_AddressOfMember(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ ITypeInfo *disp_typeinfo;
+ HRESULT hr;
- FIXME("(%p)->(%d %d %p)\n", This, memid, invKind, ppv);
+ TRACE("(%p)->(%d %d %p)\n", This, memid, invKind, ppv);
- return E_NOTIMPL;
+ if (!ppv) return E_INVALIDARG;
+ *ppv = NULL;
+
+ if (get_memid_type(This, memid) == memid_inherited)
+ {
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ return ITypeInfo_AddressOfMember(disp_typeinfo, memid, invKind, ppv);
+ }
+ return TYPE_E_BADMODULEKIND;
}
static HRESULT WINAPI ScriptTypeInfo_CreateInstance(ITypeInfo *iface, IUnknown *pUnkOuter, REFIID riid, PVOID *ppvObj)
--
2.21.0
Dec. 9, 2019
[PATCH 10/14] vbscript: Implement ScriptTypeInfo_GetDllEntry.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/vbscript/vbdisp.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 5044115..9f34f78 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -950,10 +950,23 @@ static HRESULT WINAPI ScriptTypeInfo_GetDllEntry(ITypeInfo *iface, MEMBERID memi
BSTR *pBstrDllName, BSTR *pBstrName, WORD *pwOrdinal)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ ITypeInfo *disp_typeinfo;
+ HRESULT hr;
- FIXME("(%p)->(%d %d %p %p %p)\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
+ TRACE("(%p)->(%d %d %p %p %p)\n", This, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
- return E_NOTIMPL;
+ if (pBstrDllName) *pBstrDllName = NULL;
+ if (pBstrName) *pBstrName = NULL;
+ if (pwOrdinal) *pwOrdinal = 0;
+
+ if (get_memid_type(This, memid) == memid_inherited)
+ {
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ return ITypeInfo_GetDllEntry(disp_typeinfo, memid, invKind, pBstrDllName, pBstrName, pwOrdinal);
+ }
+ return TYPE_E_BADMODULEKIND;
}
static HRESULT WINAPI ScriptTypeInfo_GetRefTypeInfo(ITypeInfo *iface, HREFTYPE hRefType, ITypeInfo **ppTInfo)
--
2.21.0
Dec. 9, 2019
[PATCH 09/14] vbscript: Implement ScriptTypeInfo_GetDocumentation.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
The DocString is not localized because it's not part of the DLL's resources
in Windows, either.
dlls/vbscript/vbdisp.c | 45 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 43 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 242010d..5044115 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -899,10 +899,51 @@ static HRESULT WINAPI ScriptTypeInfo_GetDocumentation(ITypeInfo *iface, MEMBERID
BSTR *pBstrDocString, DWORD *pdwHelpContext, BSTR *pBstrHelpFile)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ enum memid_type memid_type = get_memid_type(This, memid);
+ ITypeInfo *disp_typeinfo;
+ HRESULT hr;
- FIXME("(%p)->(%d %p %p %p %p)\n", This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
+ TRACE("(%p)->(%d %p %p %p %p)\n", This, memid, pBstrName, pBstrDocString, pdwHelpContext, pBstrHelpFile);
- return E_NOTIMPL;
+ if (pBstrDocString) *pBstrDocString = NULL;
+ if (pdwHelpContext) *pdwHelpContext = 0;
+ if (pBstrHelpFile) *pBstrHelpFile = NULL;
+
+ if (memid == MEMBERID_NIL)
+ {
+ if (pBstrName && !(*pBstrName = SysAllocString(L"VBScriptTypeInfo")))
+ return STG_E_INSUFFICIENTMEMORY;
+ if (pBstrDocString &&
+ !(*pBstrDocString = SysAllocString(L"Visual Basic Scripting Type Info")))
+ {
+ if (pBstrName) SysFreeString(*pBstrName);
+ return STG_E_INSUFFICIENTMEMORY;
+ }
+ return S_OK;
+ }
+ if (memid_type == memid_invalid) return TYPE_E_ELEMENTNOTFOUND;
+ if (memid_type == memid_inherited)
+ {
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ return ITypeInfo_GetDocumentation(disp_typeinfo, memid, pBstrName, pBstrDocString,
+ pdwHelpContext, pBstrHelpFile);
+ }
+
+ if (pBstrName)
+ {
+ const WCHAR *name;
+
+ if (memid_type == memid_func)
+ name = This->funcs[This->func_memid_map[memid & ~DISPID_FUNCTION_MASK]].func->name;
+ else
+ name = This->disp->global_vars[memid - 1]->name;
+
+ *pBstrName = SysAllocString(name);
+ if (!*pBstrName) return STG_E_INSUFFICIENTMEMORY;
+ }
+ return S_OK;
}
static HRESULT WINAPI ScriptTypeInfo_GetDllEntry(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind,
--
2.21.0
Dec. 9, 2019
[PATCH 08/14] vbscript: Implement ScriptTypeInfo_Invoke.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/vbscript/vbdisp.c | 26 ++++++++++++++++++++++++--
1 file changed, 24 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index a74b0ba..242010d 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -866,11 +866,33 @@ static HRESULT WINAPI ScriptTypeInfo_Invoke(ITypeInfo *iface, PVOID pvInstance,
DISPPARAMS *pDispParams, VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ enum memid_type memid_type = get_memid_type(This, memid);
+ ITypeInfo *disp_typeinfo;
+ IDispatch *disp;
+ HRESULT hr;
- FIXME("(%p)->(%p %d %d %p %p %p %p)\n", This, pvInstance, memid, wFlags,
+ TRACE("(%p)->(%p %d %d %p %p %p %p)\n", This, pvInstance, memid, wFlags,
pDispParams, pVarResult, pExcepInfo, puArgErr);
- return E_NOTIMPL;
+ if (!pvInstance) return E_INVALIDARG;
+ if (memid_type == memid_invalid) return TYPE_E_ELEMENTNOTFOUND;
+ if (memid_type == memid_inherited)
+ {
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ return ITypeInfo_Invoke(disp_typeinfo, pvInstance, memid, wFlags, pDispParams,
+ pVarResult, pExcepInfo, puArgErr);
+ }
+
+ hr = IUnknown_QueryInterface((IUnknown*)pvInstance, &IID_IDispatch, (void**)&disp);
+ if (FAILED(hr)) return hr;
+
+ hr = IDispatch_Invoke(disp, memid, &IID_NULL, LOCALE_USER_DEFAULT, wFlags,
+ pDispParams, pVarResult, pExcepInfo, puArgErr);
+ IDispatch_Release(disp);
+
+ return hr;
}
static HRESULT WINAPI ScriptTypeInfo_GetDocumentation(ITypeInfo *iface, MEMBERID memid, BSTR *pBstrName,
--
2.21.0
Dec. 9, 2019
[PATCH 07/14] vbscript: Implement ScriptTypeInfo_GetImplTypeFlags.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/vbscript/vbdisp.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index db94478..a74b0ba 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -802,9 +802,13 @@ static HRESULT WINAPI ScriptTypeInfo_GetImplTypeFlags(ITypeInfo *iface, UINT ind
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
- FIXME("(%p)->(%u %p)\n", This, index, pImplTypeFlags);
+ TRACE("(%p)->(%u %p)\n", This, index, pImplTypeFlags);
- return E_NOTIMPL;
+ if (!pImplTypeFlags) return E_INVALIDARG;
+ if (index != 0) return TYPE_E_ELEMENTNOTFOUND;
+
+ *pImplTypeFlags = 0;
+ return S_OK;
}
static HRESULT WINAPI ScriptTypeInfo_GetIDsOfNames(ITypeInfo *iface, LPOLESTR *rgszNames, UINT cNames,
--
2.21.0
Dec. 9, 2019
[PATCH 06/14] vbscript: Implement ScriptTypeInfo_GetRefTypeInfo.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
The hRefType value is taken from wine's oleaut32 source and verified on
Windows (and on tests).
dlls/vbscript/vbdisp.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index d14a2f6..db94478 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -892,10 +892,23 @@ static HRESULT WINAPI ScriptTypeInfo_GetDllEntry(ITypeInfo *iface, MEMBERID memi
static HRESULT WINAPI ScriptTypeInfo_GetRefTypeInfo(ITypeInfo *iface, HREFTYPE hRefType, ITypeInfo **ppTInfo)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ HRESULT hr;
- FIXME("(%p)->(%x %p)\n", This, hRefType, ppTInfo);
+ TRACE("(%p)->(%x %p)\n", This, hRefType, ppTInfo);
- return E_NOTIMPL;
+ if (!ppTInfo || (INT)hRefType < 0) return E_INVALIDARG;
+
+ if (hRefType & ~3) return E_FAIL;
+ if (hRefType & 1)
+ {
+ hr = get_dispatch_typeinfo(ppTInfo);
+ if (FAILED(hr)) return hr;
+ }
+ else
+ *ppTInfo = iface;
+
+ ITypeInfo_AddRef(*ppTInfo);
+ return S_OK;
}
static HRESULT WINAPI ScriptTypeInfo_AddressOfMember(ITypeInfo *iface, MEMBERID memid, INVOKEKIND invKind, PVOID *ppv)
--
2.21.0
Dec. 9, 2019
[PATCH 05/14] vbscript: Implement ScriptTypeInfo_GetRefTypeOfImplType.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
The return value matches Windows and makes sense for GetRefTypeInfo.
dlls/vbscript/vbdisp.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 5d43c43..d14a2f6 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -788,9 +788,14 @@ static HRESULT WINAPI ScriptTypeInfo_GetRefTypeOfImplType(ITypeInfo *iface, UINT
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
- FIXME("(%p)->(%u %p)\n", This, index, pRefType);
+ TRACE("(%p)->(%u %p)\n", This, index, pRefType);
- return E_NOTIMPL;
+ /* We only inherit from IDispatch */
+ if (!pRefType) return E_INVALIDARG;
+ if (index != 0) return TYPE_E_ELEMENTNOTFOUND;
+
+ *pRefType = 1;
+ return S_OK;
}
static HRESULT WINAPI ScriptTypeInfo_GetImplTypeFlags(ITypeInfo *iface, UINT index, INT *pImplTypeFlags)
--
2.21.0
Dec. 9, 2019
[PATCH 04/14] vbscript: Implement ScriptTypeInfo_GetNames.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
We need to map the member IDs to the variables and functions. Functions
can be replaced or skipped (if private) so we have to keep a map for them.
dlls/vbscript/vbdisp.c | 92 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 89 insertions(+), 3 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index e27ce22..5d43c43 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -539,6 +539,9 @@ typedef struct {
ITypeComp ITypeComp_iface;
LONG ref;
+ UINT func_memid_map_cnt;
+ UINT *func_memid_map;
+
UINT num_vars;
UINT num_funcs;
struct typeinfo_func *funcs;
@@ -546,6 +549,30 @@ typedef struct {
ScriptDisp *disp;
} ScriptTypeInfo;
+enum memid_type {
+ memid_invalid,
+ memid_inherited,
+ memid_func,
+ memid_var
+};
+
+static inline enum memid_type get_memid_type(const ScriptTypeInfo *typeinfo, MEMBERID memid)
+{
+ if (memid <= 0) return memid_invalid;
+ if (memid & DISPID_FUNCTION_MASK)
+ {
+ memid &= ~DISPID_FUNCTION_MASK;
+ if (memid >= typeinfo->func_memid_map_cnt)
+ return memid_inherited;
+ if (typeinfo->func_memid_map[memid] == ~0)
+ return memid_invalid;
+ return memid_func;
+ }
+ if (memid > typeinfo->num_vars)
+ return memid_inherited;
+ return memid_var;
+}
+
static inline ScriptTypeInfo *ScriptTypeInfo_from_ITypeInfo(ITypeInfo *iface)
{
return CONTAINING_RECORD(iface, ScriptTypeInfo, ITypeInfo_iface);
@@ -600,6 +627,7 @@ static ULONG WINAPI ScriptTypeInfo_Release(ITypeInfo *iface)
release_vbscode(This->funcs[i].func->code_ctx);
IDispatchEx_Release(&This->disp->IDispatchEx_iface);
+ heap_free(This->func_memid_map);
heap_free(This->funcs);
heap_free(This);
}
@@ -707,10 +735,53 @@ static HRESULT WINAPI ScriptTypeInfo_GetNames(ITypeInfo *iface, MEMBERID memid,
UINT cMaxNames, UINT *pcNames)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeInfo(iface);
+ enum memid_type memid_type = get_memid_type(This, memid);
+ ITypeInfo *disp_typeinfo;
+ HRESULT hr;
+ UINT i = 0;
- FIXME("(%p)->(%d %p %u %p)\n", This, memid, rgBstrNames, cMaxNames, pcNames);
+ TRACE("(%p)->(%d %p %u %p)\n", This, memid, rgBstrNames, cMaxNames, pcNames);
- return E_NOTIMPL;
+ if (!rgBstrNames || !pcNames) return E_INVALIDARG;
+ if (memid_type == memid_invalid) return TYPE_E_ELEMENTNOTFOUND;
+ if (memid_type == memid_inherited)
+ {
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ return ITypeInfo_GetNames(disp_typeinfo, memid, rgBstrNames, cMaxNames, pcNames);
+ }
+
+ *pcNames = 0;
+ if (!cMaxNames) return S_OK;
+
+ if (memid_type == memid_func)
+ {
+ UINT index = This->func_memid_map[memid & ~DISPID_FUNCTION_MASK];
+ UINT num = min(cMaxNames, This->funcs[index].func->arg_cnt + 1);
+ arg_desc_t *args = This->funcs[index].func->args;
+
+ rgBstrNames[0] = SysAllocString(This->funcs[index].func->name);
+ if (!rgBstrNames[0]) return E_OUTOFMEMORY;
+
+ for (i = 1; i < num; i++)
+ {
+ if (!(rgBstrNames[i] = SysAllocString(args[i - 1].name)))
+ {
+ do SysFreeString(rgBstrNames[--i]); while (i);
+ return E_OUTOFMEMORY;
+ }
+ }
+ }
+ else
+ {
+ rgBstrNames[0] = SysAllocString(This->disp->global_vars[memid - 1]->name);
+ if (!rgBstrNames[0]) return E_OUTOFMEMORY;
+ i++;
+ }
+
+ *pcNames = i;
+ return S_OK;
}
static HRESULT WINAPI ScriptTypeInfo_GetRefTypeOfImplType(ITypeInfo *iface, UINT index, HREFTYPE *pRefType)
@@ -1119,21 +1190,36 @@ static HRESULT WINAPI ScriptDisp_GetTypeInfo(IDispatchEx *iface, UINT iTInfo, LC
type_info->ref = 1;
type_info->num_funcs = num_funcs;
type_info->num_vars = This->global_vars_cnt;
+ type_info->func_memid_map_cnt = This->global_funcs_cnt + 1;
type_info->disp = This;
+ type_info->func_memid_map = heap_alloc(sizeof(*type_info->func_memid_map) * type_info->func_memid_map_cnt);
+ if(!type_info->func_memid_map)
+ {
+ heap_free(type_info);
+ return E_OUTOFMEMORY;
+ }
+
type_info->funcs = heap_alloc(sizeof(*type_info->funcs) * num_funcs);
if(!type_info->funcs)
{
+ heap_free(type_info->func_memid_map);
heap_free(type_info);
return E_OUTOFMEMORY;
}
+ type_info->func_memid_map[0] = ~0;
for(j = 0, i = 0; i < This->global_funcs_cnt; i++)
{
- if(!This->global_funcs[i]->is_public) continue;
+ if(!This->global_funcs[i]->is_public)
+ {
+ type_info->func_memid_map[i + 1] = ~0;
+ continue;
+ }
type_info->funcs[j].memid = i + 1 + DISPID_FUNCTION_MASK;
type_info->funcs[j].func = This->global_funcs[i];
+ type_info->func_memid_map[i + 1] = j;
grab_vbscode(This->global_funcs[i]->code_ctx);
j++;
}
--
2.21.0
Dec. 9, 2019
[PATCH 03/14] vbscript/tests: Add tests for the script TypeInfo's TypeComp binds.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/vbscript/tests/vbscript.c | 59 ++++++++++++++++++++++++++++++++++
1 file changed, 59 insertions(+)
diff --git a/dlls/vbscript/tests/vbscript.c b/dlls/vbscript/tests/vbscript.c
index 1d246c5..ad3ccf3 100644
--- a/dlls/vbscript/tests/vbscript.c
+++ b/dlls/vbscript/tests/vbscript.c
@@ -1077,6 +1077,65 @@ static void test_script_typeinfo(void)
ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, NULL);
ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
+
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_NONE, "Unexpected desckind %u\n", desckind);
+ wcscpy(str, L"GLOBAL_VAR");
+ hr = ITypeComp_Bind(typecomp, str, 0, INVOKE_FUNC, &typeinfo2, &desckind, &bindptr);
+ ok(hr == TYPE_E_TYPEMISMATCH, "Bind returned: %08x\n", hr);
+ ok(!lstrcmpW(str, L"GLOBAL_VAR"), "Unexpected string %s\n", wine_dbgstr_w(str));
+ wcscpy(str, L"C");
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_NONE, "Unexpected desckind %u\n", desckind);
+ wcscpy(str, L"addRef");
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_FUNCDESC, "Unexpected desckind %u\n", desckind);
+ ok(!lstrcmpW(str, L"addRef"), "Unexpected string %s\n", wine_dbgstr_w(str));
+ ITypeInfo_ReleaseFuncDesc(typeinfo2, bindptr.lpfuncdesc);
+ ITypeInfo_Release(typeinfo2);
+ for (i = 0; i < ARRAY_SIZE(var); i++)
+ {
+ wcscpy(str, var[i].name);
+ hr = ITypeComp_Bind(typecomp, str, 0, INVOKE_PROPERTYGET, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_VARDESC, "Unexpected desckind %u\n", desckind);
+ ITypeInfo_ReleaseVarDesc(typeinfo2, bindptr.lpvardesc);
+ ITypeInfo_Release(typeinfo2);
+ }
+ for (i = 0; i < ARRAY_SIZE(func); i++)
+ {
+ wcscpy(str, func[i].name);
+ hr = ITypeComp_Bind(typecomp, str, 0, INVOKE_FUNC, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_FUNCDESC, "Unexpected desckind %u\n", desckind);
+ ITypeInfo_ReleaseFuncDesc(typeinfo2, bindptr.lpfuncdesc);
+ ITypeInfo_Release(typeinfo2);
+ }
+ wcscpy(str, L"VBScriptTypeInfo");
+ hr = ITypeComp_BindType(typecomp, NULL, 0, &typeinfo2, &typecomp2);
+ ok(hr == E_INVALIDARG, "BindType returned: %08x\n", hr);
+ hr = ITypeComp_BindType(typecomp, str, 0, NULL, &typecomp2);
+ ok(hr == E_INVALIDARG, "BindType returned: %08x\n", hr);
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, NULL);
+ ok(hr == E_INVALIDARG, "BindType returned: %08x\n", hr);
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, &typecomp2);
+ ok(hr == S_OK, "BindType failed: %08x\n", hr);
+ ok(!typeinfo2, "Unexpected TypeInfo %p (expected null)\n", typeinfo2);
+ ok(!typecomp2, "Unexpected TypeComp %p (expected null)\n", typecomp2);
+ wcscpy(str, L"C");
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, &typecomp2);
+ ok(hr == S_OK, "BindType failed: %08x\n", hr);
+ ok(!typeinfo2, "Unexpected TypeInfo %p (expected null)\n", typeinfo2);
+ ok(!typecomp2, "Unexpected TypeComp %p (expected null)\n", typecomp2);
+ wcscpy(str, L"IDispatch");
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, &typecomp2);
+ ok(hr == S_OK, "BindType failed: %08x\n", hr);
+ ok(!typeinfo2, "Unexpected TypeInfo %p (expected null)\n", typeinfo2);
+ ok(!typecomp2, "Unexpected TypeComp %p (expected null)\n", typecomp2);
+
ITypeComp_Release(typecomp);
/* Updating the script won't update the typeinfo obtained before,
--
2.21.0
Dec. 9, 2019
[PATCH 02/14] vbscript: Implement ScriptTypeComp_BindType.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/vbscript/vbdisp.c | 21 +++++++++++++++++++--
1 file changed, 19 insertions(+), 2 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 0a4f681..e27ce22 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -988,8 +988,25 @@ static HRESULT WINAPI ScriptTypeComp_BindType(ITypeComp *iface, LPOLESTR szName,
ITypeInfo **ppTInfo, ITypeComp **ppTComp)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeComp(iface);
- FIXME("(%p)->(%s %08x %p %p)\n", This, debugstr_w(szName), lHashVal, ppTInfo, ppTComp);
- return E_NOTIMPL;
+ ITypeInfo *disp_typeinfo;
+ ITypeComp *disp_typecomp;
+ HRESULT hr;
+
+ TRACE("(%p)->(%s %08x %p %p)\n", This, debugstr_w(szName), lHashVal, ppTInfo, ppTComp);
+
+ if (!szName || !ppTInfo || !ppTComp)
+ return E_INVALIDARG;
+
+ /* Look into the inherited IDispatch */
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ hr = ITypeInfo_GetTypeComp(disp_typeinfo, &disp_typecomp);
+ if (FAILED(hr)) return hr;
+
+ hr = ITypeComp_BindType(disp_typecomp, szName, lHashVal, ppTInfo, ppTComp);
+ ITypeComp_Release(disp_typecomp);
+ return hr;
}
static const ITypeCompVtbl ScriptTypeCompVtbl = {
--
2.21.0
Dec. 9, 2019
[PATCH 01/14] vbscript: Implement ScriptTypeComp_Bind.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/vbscript/tests/vbscript.c | 4 ---
dlls/vbscript/vbdisp.c | 51 ++++++++++++++++++++++++++++++++--
2 files changed, 49 insertions(+), 6 deletions(-)
diff --git a/dlls/vbscript/tests/vbscript.c b/dlls/vbscript/tests/vbscript.c
index 0c3acd0..1d246c5 100644
--- a/dlls/vbscript/tests/vbscript.c
+++ b/dlls/vbscript/tests/vbscript.c
@@ -1070,16 +1070,12 @@ static void test_script_typeinfo(void)
ITypeComp_Release(typecomp2);
wcscpy(str, L"not_found");
hr = ITypeComp_Bind(typecomp, NULL, 0, 0, &typeinfo2, &desckind, &bindptr);
- todo_wine
ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
hr = ITypeComp_Bind(typecomp, str, 0, 0, NULL, &desckind, &bindptr);
- todo_wine
ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, NULL, &bindptr);
- todo_wine
ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, NULL);
- todo_wine
ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
ITypeComp_Release(typecomp);
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 2e59051..0a4f681 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -932,9 +932,56 @@ static HRESULT WINAPI ScriptTypeComp_Bind(ITypeComp *iface, LPOLESTR szName, ULO
ITypeInfo **ppTInfo, DESCKIND *pDescKind, BINDPTR *pBindPtr)
{
ScriptTypeInfo *This = ScriptTypeInfo_from_ITypeComp(iface);
- FIXME("(%p)->(%s %08x %d %p %p %p)\n", This, debugstr_w(szName), lHashVal,
+ UINT flags = wFlags ? wFlags : ~0;
+ ITypeInfo *disp_typeinfo;
+ ITypeComp *disp_typecomp;
+ HRESULT hr;
+ UINT i;
+
+ TRACE("(%p)->(%s %08x %d %p %p %p)\n", This, debugstr_w(szName), lHashVal,
wFlags, ppTInfo, pDescKind, pBindPtr);
- return E_NOTIMPL;
+
+ if (!szName || !ppTInfo || !pDescKind || !pBindPtr)
+ return E_INVALIDARG;
+
+ for (i = 0; i < This->num_funcs; i++)
+ {
+ if (wcsicmp(szName, This->funcs[i].func->name)) continue;
+ if (!(flags & INVOKE_FUNC)) return TYPE_E_TYPEMISMATCH;
+
+ hr = ITypeInfo_GetFuncDesc(&This->ITypeInfo_iface, i, &pBindPtr->lpfuncdesc);
+ if (FAILED(hr)) return hr;
+
+ *pDescKind = DESCKIND_FUNCDESC;
+ *ppTInfo = &This->ITypeInfo_iface;
+ ITypeInfo_AddRef(*ppTInfo);
+ return S_OK;
+ }
+
+ for (i = 0; i < This->num_vars; i++)
+ {
+ if (wcsicmp(szName, This->disp->global_vars[i]->name)) continue;
+ if (!(flags & INVOKE_PROPERTYGET)) return TYPE_E_TYPEMISMATCH;
+
+ hr = ITypeInfo_GetVarDesc(&This->ITypeInfo_iface, i, &pBindPtr->lpvardesc);
+ if (FAILED(hr)) return hr;
+
+ *pDescKind = DESCKIND_VARDESC;
+ *ppTInfo = &This->ITypeInfo_iface;
+ ITypeInfo_AddRef(*ppTInfo);
+ return S_OK;
+ }
+
+ /* Look into the inherited IDispatch */
+ hr = get_dispatch_typeinfo(&disp_typeinfo);
+ if (FAILED(hr)) return hr;
+
+ hr = ITypeInfo_GetTypeComp(disp_typeinfo, &disp_typecomp);
+ if (FAILED(hr)) return hr;
+
+ hr = ITypeComp_Bind(disp_typecomp, szName, lHashVal, wFlags, ppTInfo, pDescKind, pBindPtr);
+ ITypeComp_Release(disp_typecomp);
+ return hr;
}
static HRESULT WINAPI ScriptTypeComp_BindType(ITypeComp *iface, LPOLESTR szName, ULONG lHashVal,
--
2.21.0
Dec. 9, 2019
[PATCH] vbscript: Don't free procs allocated in the heap pool.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
As far as I can see, these procs are allocated in compiler.c into the
vbscode's heap pool, and freeing them with heap_free is obviously wrong.
dlls/vbscript/vbdisp.c | 7 -------
1 file changed, 7 deletions(-)
diff --git a/dlls/vbscript/vbdisp.c b/dlls/vbscript/vbdisp.c
index 2e59051..47ecc15 100644
--- a/dlls/vbscript/vbdisp.c
+++ b/dlls/vbscript/vbdisp.c
@@ -1002,13 +1002,6 @@ static ULONG WINAPI ScriptDisp_Release(IDispatchEx *iface)
if(!ref) {
assert(!This->ctx);
- while (This->procs)
- {
- class_desc_t *class_desc = This->procs;
- This->procs = class_desc->next;
- heap_free(class_desc);
- }
-
for (i = 0; i < This->global_vars_cnt; i++)
release_dynamic_var(This->global_vars[i]);
--
2.21.0
Dec. 9, 2019
Re: [PATCH 01/10] jscript: Add script TypeInfo stub.
by Gabriel Ivăncescu
On 12/9/19 4:54 PM, Jacek Caban wrote:
> Hi Gabriel,
>
> On 12/9/19 3:01 PM, Gabriel Ivăncescu wrote:
>> +
>> + if (This == This->ctx->global)
>> + return create_script_typeinfo(This, ppTInfo);
>
>
> That's not pretty. However, do you depend on jsdisp_t being a script
> dispatch anywhere? It seems to me that this could be just a generic
> implementation (although that would need some tests).
>
>
> Thanks,
>
> Jacek
>
Right, I wanted to keep it similar to vbscript. I'll look into adding
some tests for it.
But just in case tests show that it applies only to script dispatch,
would this current approach work? (i.e. should I resend it?)
Dec. 9, 2019
Re: [PATCH 02/10] jscript: Store the necessary function and variable info in the script TypeInfo.
by Gabriel Ivăncescu
On 12/9/19 4:56 PM, Jacek Caban wrote:
> On 12/9/19 3:01 PM, Gabriel Ivăncescu wrote:
>> +BOOL is_source_function(jsdisp_t *jsdisp)
>> +{
>> + return function_from_jsdisp(jsdisp)->vtbl ==
>> &InterpretedFunctionVtbl;
>> +}
>
>
> I'm not sure about that, are native functions really not treated as
> functions? It should be easy to test with something like:
>
> var native_func = decodeURI;
>
>
> Thanks,
>
> Jacek
>
Ok, I'll see about the tests, but I was actually more worried about how
to get the args and their names for native functions (didn't know how).
Dec. 9, 2019
Re: [PATCH 02/10] jscript: Store the necessary function and variable info in the script TypeInfo.
by Jacek Caban
On 12/9/19 3:01 PM, Gabriel Ivăncescu wrote:
> +BOOL is_source_function(jsdisp_t *jsdisp)
> +{
> + return function_from_jsdisp(jsdisp)->vtbl == &InterpretedFunctionVtbl;
> +}
I'm not sure about that, are native functions really not treated as
functions? It should be easy to test with something like:
var native_func = decodeURI;
Thanks,
Jacek
Dec. 9, 2019
Re: [PATCH 01/10] jscript: Add script TypeInfo stub.
by Jacek Caban
Hi Gabriel,
On 12/9/19 3:01 PM, Gabriel Ivăncescu wrote:
> +
> + if (This == This->ctx->global)
> + return create_script_typeinfo(This, ppTInfo);
That's not pretty. However, do you depend on jsdisp_t being a script
dispatch anywhere? It seems to me that this could be just a generic
implementation (although that would need some tests).
Thanks,
Jacek
Dec. 9, 2019
[PATCH 10/10] jscript/tests: Add initial tests for the script TypeInfo.
by Gabriel Ivăncescu
Signed-off-by: Gabriel Ivăncescu <gabrielopcode(a)gmail.com>
---
dlls/jscript/tests/jscript.c | 325 +++++++++++++++++++++++++++++++++++
1 file changed, 325 insertions(+)
diff --git a/dlls/jscript/tests/jscript.c b/dlls/jscript/tests/jscript.c
index 0904374..fa03ee3 100644
--- a/dlls/jscript/tests/jscript.c
+++ b/dlls/jscript/tests/jscript.c
@@ -44,6 +44,7 @@
#endif
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
+DEFINE_GUID(IID_IScriptTypeInfo, 0xc59c6b12, 0xf6c1, 0x11cf, 0x88,0x35, 0x00,0xa0,0xc9,0x11,0xe8,0xb2);
static const CLSID CLSID_JScript =
{0xf414c260,0x6ac0,0x11cf,{0xb6,0xd1,0x00,0xaa,0x00,0xbb,0xbb,0x58}};
@@ -274,6 +275,20 @@ static IDispatchEx *get_script_dispatch(IActiveScript *script)
return dispex;
}
+static void parse_script(IActiveScriptParse *parser, const WCHAR *src)
+{
+ HRESULT hres;
+
+ SET_EXPECT(OnEnterScript);
+ SET_EXPECT(OnLeaveScript);
+
+ hres = IActiveScriptParse_ParseScriptText(parser, src, NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
+ ok(hres == S_OK, "ParseScriptText failed: %08x\n", hres);
+
+ CHECK_CALLED(OnEnterScript);
+ CHECK_CALLED(OnLeaveScript);
+}
+
#define get_disp_id(a,b,c,d) _get_disp_id(__LINE__,a,b,c,d)
static void _get_disp_id(unsigned line, IDispatchEx *dispex, const WCHAR *name, HRESULT exhr, DISPID *id)
{
@@ -907,6 +922,315 @@ static void test_code_persistence(void)
CHECK_CALLED(OnStateChange_CLOSED);
}
+static void test_script_typeinfo(void)
+{
+ static struct
+ {
+ const WCHAR *name;
+ UINT num_args;
+ } func[] =
+ {
+ { L"emptyfn", 0 },
+ { L"voidfn", 0 },
+ { L"math", 2 },
+ { L"foobar", 1 },
+ { L"C", 0 },
+ { L"funcvar", 2 },
+ { L"f1", 1 },
+ { L"f2", 1 }
+ };
+ static struct
+ {
+ const WCHAR *name;
+ } var[] =
+ {
+ { L"global_var" },
+ { L"uninit" },
+ { L"obj" }
+ };
+ ITypeInfo *typeinfo, *typeinfo2;
+ ITypeComp *typecomp, *typecomp2;
+ IActiveScriptParse *parser;
+ IDispatchEx *script_disp;
+ IActiveScript *script;
+ FUNCDESC *funcdesc;
+ VARDESC *vardesc;
+ DESCKIND desckind;
+ BINDPTR bindptr;
+ MEMBERID memid;
+ TYPEATTR *attr;
+ UINT index;
+ HRESULT hr;
+ WCHAR str[64], *names = str;
+ int i;
+
+ script = create_jscript();
+
+ hr = IActiveScript_QueryInterface(script, &IID_IActiveScriptParse, (void**)&parser);
+ ok(hr == S_OK, "Could not get IActiveScriptParse iface: %08x\n", hr);
+
+ SET_EXPECT(GetLCID);
+ hr = IActiveScript_SetScriptSite(script, &ActiveScriptSite);
+ ok(hr == S_OK, "SetScriptSite failed: %08x\n", hr);
+ CHECK_CALLED(GetLCID);
+
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ hr = IActiveScriptParse_InitNew(parser);
+ ok(hr == S_OK, "InitNew failed: %08x\n", hr);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+
+ SET_EXPECT(OnStateChange_CONNECTED);
+ hr = IActiveScript_SetScriptState(script, SCRIPTSTATE_CONNECTED);
+ ok(hr == S_OK, "SetScriptState(SCRIPTSTATE_CONNECTED) failed: %08x\n", hr);
+ CHECK_CALLED(OnStateChange_CONNECTED);
+
+ parse_script(parser, L""
+ "var global_var = 42;\n"
+
+ "function emptyfn() { }\n"
+ "function voidfn() { return void(0); }\n"
+ "function math(x, y) { return x - y; }\n"
+ "function foobar(x) { return \"foobar\"; }\n"
+
+ "function C() {\n"
+ " this.x;\n"
+ " this.strret = function() { return \"ret\"; }\n"
+ "}\n"
+
+ "var uninit;\n"
+ "var obj = new C();\n"
+
+ "var funcvar = function(x, y) { return x * y; };\n"
+
+ "(function() {\n"
+ " f1 = function infuncexpr(x) { return 1; }\n"
+ " f2 = function infuncexpr(x) { return 2; }\n"
+ "})();\n");
+
+ script_disp = get_script_dispatch(script);
+ hr = IDispatchEx_QueryInterface(script_disp, &IID_ITypeInfo, (void**)&typeinfo);
+ ok(hr == E_NOINTERFACE, "QueryInterface(IID_ITypeInfo) returned: %08x\n", hr);
+ hr = IDispatchEx_GetTypeInfo(script_disp, 1, LOCALE_USER_DEFAULT, &typeinfo);
+ ok(hr == DISP_E_BADINDEX, "GetTypeInfo returned: %08x\n", hr);
+ hr = IDispatchEx_GetTypeInfo(script_disp, 0, LOCALE_USER_DEFAULT, &typeinfo);
+ ok(hr == S_OK, "GetTypeInfo failed: %08x\n", hr);
+ hr = IDispatchEx_GetTypeInfo(script_disp, 0, LOCALE_USER_DEFAULT, &typeinfo2);
+ ok(hr == S_OK, "GetTypeInfo failed: %08x\n", hr);
+ ok(typeinfo != typeinfo2, "TypeInfo was not supposed to be shared.\n");
+ ITypeInfo_Release(typeinfo2);
+
+ hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
+ ok(hr == S_OK, "GetTypeAttr failed: %08x\n", hr);
+ ok(IsEqualGUID(&attr->guid, &IID_IScriptTypeInfo), "Unexpected GUID %s\n", wine_dbgstr_guid(&attr->guid));
+ ok(attr->lcid == LOCALE_USER_DEFAULT, "Unexpected LCID %u\n", attr->lcid);
+ ok(attr->memidConstructor == MEMBERID_NIL, "Unexpected constructor memid %u\n", attr->memidConstructor);
+ ok(attr->memidDestructor == MEMBERID_NIL, "Unexpected destructor memid %u\n", attr->memidDestructor);
+ ok(attr->cbSizeInstance == 4, "Unexpected cbSizeInstance %u\n", attr->cbSizeInstance);
+ ok(attr->typekind == TKIND_DISPATCH, "Unexpected typekind %u\n", attr->typekind);
+ ok(attr->cFuncs == ARRAY_SIZE(func), "Unexpected cFuncs %u\n", attr->cFuncs);
+ ok(attr->cVars == ARRAY_SIZE(var), "Unexpected cVars %u\n", attr->cVars);
+ ok(attr->cImplTypes == 1, "Unexpected cImplTypes %u\n", attr->cImplTypes);
+ ok(attr->cbSizeVft == sizeof(IDispatchVtbl), "Unexpected cbSizeVft %u\n", attr->cbSizeVft);
+ ok(attr->cbAlignment == 4, "Unexpected cbAlignment %u\n", attr->cbAlignment);
+ ok(attr->wTypeFlags == TYPEFLAG_FDISPATCHABLE, "Unexpected wTypeFlags 0x%x\n", attr->wTypeFlags);
+ ok(attr->tdescAlias.vt == VT_EMPTY, "Unexpected tdescAlias.vt %d\n", attr->tdescAlias.vt);
+ ok(attr->idldescType.wIDLFlags == IDLFLAG_NONE, "Unexpected idldescType.wIDLFlags 0x%x\n", attr->idldescType.wIDLFlags);
+ ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
+
+ /* GetIDsOfNames looks into the inherited types as well */
+ wcscpy(str, L"queryinterface");
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, NULL, 1, &memid);
+ ok(hr == E_INVALIDARG, "GetIDsOfNames returned: %08x\n", hr);
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 1, NULL);
+ ok(hr == E_INVALIDARG, "GetIDsOfNames returned: %08x\n", hr);
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 0, &memid);
+ ok(hr == E_INVALIDARG, "GetIDsOfNames returned: %08x\n", hr);
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 1, &memid);
+ ok(hr == S_OK, "GetIDsOfNames failed: %08x\n", hr);
+ ok(!lstrcmpW(str, L"queryinterface"), "Unexpected string %s\n", wine_dbgstr_w(str));
+ wcscpy(str, L"Math");
+ hr = ITypeInfo_GetIDsOfNames(typeinfo, &names, 1, &memid);
+ ok(hr == S_OK, "GetIDsOfNames failed: %08x\n", hr);
+ ok(!lstrcmpW(str, L"Math"), "Unexpected string %s\n", wine_dbgstr_w(str));
+
+ /* Check variable descriptions */
+ hr = ITypeInfo_GetVarDesc(typeinfo, 0, NULL);
+ ok(hr == E_INVALIDARG, "GetVarDesc returned: %08x\n", hr);
+ hr = ITypeInfo_GetVarDesc(typeinfo, 1337, &vardesc);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetVarDesc returned: %08x\n", hr);
+ for (i = 0; i < ARRAY_SIZE(var); i++)
+ {
+ hr = ITypeInfo_GetVarDesc(typeinfo, i, &vardesc);
+ ok(hr == S_OK, "GetVarDesc(%u) failed: %08x\n", i, hr);
+ ok(vardesc->memid <= 0xFFFF, "[%u] Unexpected memid 0x%x\n", i, vardesc->memid);
+ ok(vardesc->lpstrSchema == NULL, "[%u] Unexpected lpstrSchema %p\n", i, vardesc->lpstrSchema);
+ ok(vardesc->oInst == 0, "[%u] Unexpected oInst %u\n", i, vardesc->oInst);
+ ok(vardesc->varkind == VAR_DISPATCH, "[%u] Unexpected varkind %d\n", i, vardesc->varkind);
+ ok(vardesc->wVarFlags == 0, "[%u] Unexpected wVarFlags 0x%x\n", i, vardesc->wVarFlags);
+ ok(vardesc->elemdescVar.tdesc.vt == VT_VARIANT,
+ "[%u] Unexpected variable type vt %d (expected %d)\n", i, vardesc->elemdescVar.tdesc.vt, 0);
+ ok(vardesc->elemdescVar.paramdesc.pparamdescex == NULL,
+ "[%u] Unexpected variable type pparamdescex %p\n", i, vardesc->elemdescVar.paramdesc.pparamdescex);
+ ok(vardesc->elemdescVar.paramdesc.wParamFlags == PARAMFLAG_NONE,
+ "[%u] Unexpected variable type wParamFlags 0x%x\n", i, vardesc->elemdescVar.paramdesc.wParamFlags);
+ ITypeInfo_ReleaseVarDesc(typeinfo, vardesc);
+ }
+
+ /* Check function descriptions */
+ hr = ITypeInfo_GetFuncDesc(typeinfo, 0, NULL);
+ ok(hr == E_INVALIDARG, "GetFuncDesc returned: %08x\n", hr);
+ hr = ITypeInfo_GetFuncDesc(typeinfo, 1337, &funcdesc);
+ ok(hr == TYPE_E_ELEMENTNOTFOUND, "GetFuncDesc returned: %08x\n", hr);
+ for (i = 0; i < ARRAY_SIZE(func); i++)
+ {
+ hr = ITypeInfo_GetFuncDesc(typeinfo, i, &funcdesc);
+ ok(hr == S_OK, "GetFuncDesc(%u) failed: %08x\n", i, hr);
+ ok(funcdesc->memid <= 0xFFFF, "[%u] Unexpected memid 0x%x\n", i, funcdesc->memid);
+ ok(funcdesc->lprgscode == NULL, "[%u] Unexpected lprgscode %p\n", i, funcdesc->lprgscode);
+ ok(func[i].num_args ? (funcdesc->lprgelemdescParam != NULL) : (funcdesc->lprgelemdescParam == NULL),
+ "[%u] Unexpected lprgelemdescParam %p\n", i, funcdesc->lprgelemdescParam);
+ ok(funcdesc->funckind == FUNC_DISPATCH, "[%u] Unexpected funckind %u\n", i, funcdesc->funckind);
+ ok(funcdesc->invkind == INVOKE_FUNC, "[%u] Unexpected invkind %u\n", i, funcdesc->invkind);
+ ok(funcdesc->callconv == CC_STDCALL, "[%u] Unexpected callconv %u\n", i, funcdesc->callconv);
+ ok(funcdesc->cParams == func[i].num_args, "[%u] Unexpected cParams %d (expected %d)\n",
+ i, funcdesc->cParams, func[i].num_args);
+ ok(funcdesc->cParamsOpt == 0, "[%u] Unexpected cParamsOpt %d\n", i, funcdesc->cParamsOpt);
+ ok(funcdesc->cScodes == 0, "[%u] Unexpected cScodes %d\n", i, funcdesc->cScodes);
+ ok(funcdesc->wFuncFlags == 0, "[%u] Unexpected wFuncFlags 0x%x\n", i, funcdesc->wFuncFlags);
+ ok(funcdesc->elemdescFunc.tdesc.vt == VT_VARIANT,
+ "[%u] Unexpected return type vt %d\n", i, funcdesc->elemdescFunc.tdesc.vt);
+ ok(funcdesc->elemdescFunc.paramdesc.pparamdescex == NULL,
+ "[%u] Unexpected return type pparamdescex %p\n", i, funcdesc->elemdescFunc.paramdesc.pparamdescex);
+ ok(funcdesc->elemdescFunc.paramdesc.wParamFlags == PARAMFLAG_NONE,
+ "[%u] Unexpected return type wParamFlags 0x%x\n", i, funcdesc->elemdescFunc.paramdesc.wParamFlags);
+ if (funcdesc->lprgelemdescParam)
+ for (index = 0; index < funcdesc->cParams; index++)
+ {
+ ok(funcdesc->lprgelemdescParam[index].tdesc.vt == VT_VARIANT,
+ "[%u] Unexpected parameter %u vt %d\n", i, index, funcdesc->lprgelemdescParam[index].tdesc.vt);
+ ok(funcdesc->lprgelemdescParam[index].paramdesc.pparamdescex == NULL,
+ "[%u] Unexpected parameter %u pparamdescex %p\n", i, index, funcdesc->lprgelemdescParam[index].paramdesc.pparamdescex);
+ ok(funcdesc->lprgelemdescParam[index].paramdesc.wParamFlags == PARAMFLAG_NONE,
+ "[%u] Unexpected parameter %u wParamFlags 0x%x\n", i, index, funcdesc->lprgelemdescParam[index].paramdesc.wParamFlags);
+ }
+ ITypeInfo_ReleaseFuncDesc(typeinfo, funcdesc);
+ }
+
+ /* Test TypeComp Binds */
+ hr = ITypeInfo_QueryInterface(typeinfo, &IID_ITypeComp, (void**)&typecomp);
+ ok(hr == S_OK, "QueryInterface(IID_ITypeComp) failed: %08x\n", hr);
+ hr = ITypeInfo_GetTypeComp(typeinfo, NULL);
+ ok(hr == E_INVALIDARG, "GetTypeComp returned: %08x\n", hr);
+ hr = ITypeInfo_GetTypeComp(typeinfo, &typecomp2);
+ ok(hr == S_OK, "GetTypeComp failed: %08x\n", hr);
+ ok(typecomp == typecomp2, "QueryInterface(IID_ITypeComp) and GetTypeComp returned different TypeComps\n");
+ ITypeComp_Release(typecomp2);
+ wcscpy(str, L"not_found");
+ hr = ITypeComp_Bind(typecomp, NULL, 0, 0, &typeinfo2, &desckind, &bindptr);
+ ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, NULL, &desckind, &bindptr);
+ ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, NULL, &bindptr);
+ ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, NULL);
+ ok(hr == E_INVALIDARG, "Bind returned: %08x\n", hr);
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_NONE, "Unexpected desckind %u\n", desckind);
+ wcscpy(str, L"GLOBAL_VAR");
+ hr = ITypeComp_Bind(typecomp, str, 0, INVOKE_FUNC, &typeinfo2, &desckind, &bindptr);
+ ok(hr == TYPE_E_TYPEMISMATCH, "Bind returned: %08x\n", hr);
+ ok(!lstrcmpW(str, L"GLOBAL_VAR"), "Unexpected string %s\n", wine_dbgstr_w(str));
+ wcscpy(str, L"addRef");
+ hr = ITypeComp_Bind(typecomp, str, 0, 0, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_FUNCDESC, "Unexpected desckind %u\n", desckind);
+ ok(!lstrcmpW(str, L"addRef"), "Unexpected string %s\n", wine_dbgstr_w(str));
+ ITypeInfo_ReleaseFuncDesc(typeinfo2, bindptr.lpfuncdesc);
+ ITypeInfo_Release(typeinfo2);
+ for (i = 0; i < ARRAY_SIZE(var); i++)
+ {
+ wcscpy(str, var[i].name);
+ hr = ITypeComp_Bind(typecomp, str, 0, INVOKE_PROPERTYGET, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_VARDESC, "Unexpected desckind %u\n", desckind);
+ ITypeInfo_ReleaseVarDesc(typeinfo2, bindptr.lpvardesc);
+ ITypeInfo_Release(typeinfo2);
+ }
+ for (i = 0; i < ARRAY_SIZE(func); i++)
+ {
+ wcscpy(str, func[i].name);
+ hr = ITypeComp_Bind(typecomp, str, 0, INVOKE_FUNC, &typeinfo2, &desckind, &bindptr);
+ ok(hr == S_OK, "Bind failed: %08x\n", hr);
+ ok(desckind == DESCKIND_FUNCDESC, "Unexpected desckind %u\n", desckind);
+ ITypeInfo_ReleaseFuncDesc(typeinfo2, bindptr.lpfuncdesc);
+ ITypeInfo_Release(typeinfo2);
+ }
+ wcscpy(str, L"JScriptTypeInfo");
+ hr = ITypeComp_BindType(typecomp, NULL, 0, &typeinfo2, &typecomp2);
+ ok(hr == E_INVALIDARG, "BindType returned: %08x\n", hr);
+ hr = ITypeComp_BindType(typecomp, str, 0, NULL, &typecomp2);
+ ok(hr == E_INVALIDARG, "BindType returned: %08x\n", hr);
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, NULL);
+ ok(hr == E_INVALIDARG, "BindType returned: %08x\n", hr);
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, &typecomp2);
+ ok(hr == S_OK, "BindType failed: %08x\n", hr);
+ ok(!typeinfo2, "Unexpected TypeInfo %p (expected null)\n", typeinfo2);
+ ok(!typecomp2, "Unexpected TypeComp %p (expected null)\n", typecomp2);
+ wcscpy(str, L"C");
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, &typecomp2);
+ ok(hr == S_OK, "BindType failed: %08x\n", hr);
+ ok(!typeinfo2, "Unexpected TypeInfo %p (expected null)\n", typeinfo2);
+ ok(!typecomp2, "Unexpected TypeComp %p (expected null)\n", typecomp2);
+ wcscpy(str, L"IDispatch");
+ hr = ITypeComp_BindType(typecomp, str, 0, &typeinfo2, &typecomp2);
+ ok(hr == S_OK, "BindType failed: %08x\n", hr);
+ ok(!typeinfo2, "Unexpected TypeInfo %p (expected null)\n", typeinfo2);
+ ok(!typecomp2, "Unexpected TypeComp %p (expected null)\n", typecomp2);
+ ITypeComp_Release(typecomp);
+
+ /* Updating the script won't update the typeinfo obtained before,
+ but it will be reflected in any typeinfo obtained afterwards. */
+ parse_script(parser, L""
+ "var new_var;\n"
+ "function new_func() { }\n");
+
+ hr = IDispatchEx_GetTypeInfo(script_disp, 0, LOCALE_USER_DEFAULT, &typeinfo2);
+ ok(hr == S_OK, "GetTypeInfo failed: %08x\n", hr);
+ hr = ITypeInfo_GetTypeAttr(typeinfo, &attr);
+ ok(hr == S_OK, "GetTypeAttr failed: %08x\n", hr);
+ ok(attr->cFuncs == ARRAY_SIZE(func), "Unexpected cFuncs %u\n", attr->cFuncs);
+ ok(attr->cVars == ARRAY_SIZE(var), "Unexpected cVars %u\n", attr->cVars);
+ ITypeInfo_ReleaseTypeAttr(typeinfo, attr);
+ hr = ITypeInfo_GetTypeAttr(typeinfo2, &attr);
+ ok(hr == S_OK, "GetTypeAttr failed: %08x\n", hr);
+ ok(attr->cFuncs == ARRAY_SIZE(func) + 1, "Unexpected cFuncs %u\n", attr->cFuncs);
+ ok(attr->cVars == ARRAY_SIZE(var) + 1, "Unexpected cVars %u\n", attr->cVars);
+ ITypeInfo_ReleaseTypeAttr(typeinfo2, attr);
+ ITypeInfo_Release(typeinfo2);
+ ITypeInfo_Release(typeinfo);
+
+ /* Adding an identifier that differs only in case gives an error
+ when retrieving the TypeInfo, even though it is valid jscript. */
+ parse_script(parser, L"var NEW_FUNC;\n");
+ hr = IDispatchEx_GetTypeInfo(script_disp, 0, LOCALE_USER_DEFAULT, &typeinfo);
+ ok(hr == TYPE_E_AMBIGUOUSNAME, "GetTypeInfo returned: %08x\n", hr);
+
+ IDispatchEx_Release(script_disp);
+ IActiveScriptParse_Release(parser);
+
+ SET_EXPECT(OnStateChange_DISCONNECTED);
+ SET_EXPECT(OnStateChange_INITIALIZED);
+ SET_EXPECT(OnStateChange_CLOSED);
+ hr = IActiveScript_Close(script);
+ ok(hr == S_OK, "Close failed: %08x\n", hr);
+ CHECK_CALLED(OnStateChange_DISCONNECTED);
+ CHECK_CALLED(OnStateChange_INITIALIZED);
+ CHECK_CALLED(OnStateChange_CLOSED);
+
+ IActiveScript_Release(script);
+}
+
static BOOL check_jscript(void)
{
IActiveScriptProperty *script_prop;
@@ -931,6 +1255,7 @@ START_TEST(jscript)
test_jscript_uninitializing();
test_aggregation();
test_code_persistence();
+ test_script_typeinfo();
trace("Testing JScriptEncode object...\n");
engine_clsid = &CLSID_JScriptEncode;
--
2.21.0
Dec. 9, 2019