Wine-Devel
Threads by month
- ----- 2026 -----
- 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
- 8 participants
- 84547 discussions
Signed-off-by: Myah Caron <qsniyg(a)protonmail.com>
---
Progressing towards fixing #49641. This patch alone doesn't fix the issue, but I'm not sure when I'll get to the next patch, so I'm sending this one in by itself for the moment.
dlls/sapi/tests/token.c | 253 ++++++++++++++++++++++++++++++++++++++++
dlls/sapi/token.c | 96 ++++++++++++++-
2 files changed, 345 insertions(+), 4 deletions(-)
diff --git a/dlls/sapi/tests/token.c b/dlls/sapi/tests/token.c
index 9f6689b83f..4d12ddb1c9 100644
--- a/dlls/sapi/tests/token.c
+++ b/dlls/sapi/tests/token.c
@@ -83,6 +83,254 @@ static void test_token_category(void)
ISpObjectTokenCategory_Release( cat );
}
+static void backup_speech(HKEY root)
+{
+ LONG res;
+ HKEY key;
+
+ res = RegDeleteTreeW( root, L"SOFTWARE\\Microsoft\\Speech_winetest" );
+ ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
+
+ res = RegCreateKeyW( root, L"SOFTWARE\\Microsoft\\Speech_winetest", &key );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+
+ RegCopyTreeW( root, L"SOFTWARE\\Microsoft\\Speech", key );
+ ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
+
+ RegCloseKey(key);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+}
+
+static void restore_speech(HKEY root, BOOL delete_backup)
+{
+ LONG res;
+ HKEY key;
+
+ res = RegDeleteTreeW( root, L"SOFTWARE\\Microsoft\\Speech" );
+ ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
+
+ res = RegCreateKeyW( root, L"SOFTWARE\\Microsoft\\Speech", &key );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+
+ RegCopyTreeW( root, L"SOFTWARE\\Microsoft\\Speech_winetest", key );
+ ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
+
+ RegCloseKey(key);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+
+ if (delete_backup) {
+ res = RegDeleteTreeW( root, L"SOFTWARE\\Microsoft\\Speech_winetest" );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ }
+}
+
+static void test_token_default_id(void)
+{
+ ISpObjectTokenCategory *cat;
+ HRESULT hr;
+ LONG res;
+ HKEY key;
+ LPWSTR token_id = NULL;
+ WCHAR regvalue[512];
+ WCHAR regvalue2[512];
+ DWORD regvalue_size = sizeof( regvalue );
+
+ hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
+ &IID_ISpObjectTokenCategory, (void **)&cat );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ token_id = (LPWSTR)0xdeadbeef;
+ hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
+ ok( hr == SPERR_UNINITIALIZED, "got %08x\n", hr );
+ ok( token_id == (LPWSTR)0xdeadbeef, "got %p\n", token_id );
+
+ hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, NULL );
+ ok( hr == SPERR_UNINITIALIZED, "got %08x\n", hr );
+
+ /* if missing, Get/SetDefaultTokenId should initialize HKEY_LOCAL_USER's
+ SOFTWARE\Microsoft\Speech\AudioOutput */
+ res = RegDeleteTreeW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
+ ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
+
+ hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ res = RegOpenKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput", 0, KEY_ALL_ACCESS, &key );
+ ok( res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
+
+ hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, NULL );
+ ok( hr == E_POINTER, "got %08x\n", hr );
+
+ res = RegOpenKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput", 0, KEY_ALL_ACCESS, &key );
+ ok( res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
+
+ token_id = (LPWSTR)0xdeadbeef;
+ hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
+
+ regvalue_size = sizeof( regvalue );
+ res = RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
+ L"DefaultTokenId", RRF_RT_REG_SZ, NULL, (LPVOID)®value, ®value_size);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ ok( !wcscmp(regvalue, token_id),
+ "GetDefaultTokenId (%s) should be equal to the DefaultTokenId key (%s)\n",
+ wine_dbgstr_w(token_id), wine_dbgstr_w(regvalue) );
+ CoTaskMemFree(token_id);
+
+ regvalue_size = sizeof( regvalue );
+ res = RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
+ L"DefaultTokenId", RRF_RT_REG_SZ, NULL, (LPVOID)®value, ®value_size);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ regvalue_size = sizeof( regvalue2 );
+ res = RegGetValueW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
+ L"DefaultdefaultTokenId", RRF_RT_REG_SZ, NULL, (LPVOID)®value2, ®value_size);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ ok( !wcscmp(regvalue, regvalue2),
+ "DefaultTokenId (%s) should be equal to the DefaultdefaultTokenId key (%s)\n",
+ wine_dbgstr_w(regvalue), wine_dbgstr_w(regvalue2) );
+
+ /* todo: test subkeys */
+
+ res = RegOpenKeyExW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput", 0, KEY_ALL_ACCESS, &key );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ wcscpy(regvalue, L"bogus");
+ regvalue_size = (wcslen(regvalue) + 1) * sizeof( WCHAR );
+ res = RegSetValueExW( key, L"DefaultTokenId", 0, REG_SZ, (const BYTE*)regvalue, regvalue_size);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ RegCloseKey(key);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+
+ token_id = (LPWSTR)0xdeadbeef;
+ hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
+ todo_wine ok( wcscmp(regvalue, token_id),
+ "GetDefaultTokenId (%s) should not be equal to the bogus DefaultTokenId key (%s)\n",
+ wine_dbgstr_w(token_id), wine_dbgstr_w(regvalue) );
+ CoTaskMemFree(token_id);
+
+ /* todo: add more tests for the resulting token_id */
+
+ restore_speech( HKEY_LOCAL_MACHINE, FALSE );
+ token_id = (LPWSTR)0xdeadbeef;
+ hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
+ todo_wine ok( hr == 0x800703fa, "got %08x\n", hr );
+ todo_wine ok( token_id == (LPWSTR)0xdeadbeef, "got %p\n", token_id );
+
+ ISpObjectTokenCategory_Release( cat );
+
+ hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
+ &IID_ISpObjectTokenCategory, (void **)&cat );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ res = RegDeleteTreeW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ res = RegDeleteTreeW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+
+ hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
+ todo_wine ok( hr == SPERR_NOT_FOUND, "got %08x\n", hr );
+
+ restore_speech( HKEY_CURRENT_USER, FALSE );
+
+ hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
+ todo_wine ok( hr == SPERR_NOT_FOUND, "got %08x\n", hr );
+
+ restore_speech( HKEY_LOCAL_MACHINE, FALSE );
+
+ hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ res = RegDeleteTreeW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
+ ok( res == ERROR_SUCCESS || res == ERROR_FILE_NOT_FOUND, "got %08x\n", res );
+ res = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput", 0, KEY_ALL_ACCESS, &key );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ wcscpy(regvalue, L"bogus");
+ regvalue_size = (wcslen(regvalue) + 1) * sizeof( WCHAR );
+ res = RegSetValueExW( key, L"DefaultdefaultTokenId", 0, REG_SZ, (const BYTE*)regvalue, regvalue_size);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ RegCloseKey(key);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+
+ token_id = (LPWSTR)0xdeadbeef;
+ hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
+ ok( hr == S_OK, "got %08x\n", hr );
+ ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
+ todo_wine ok( wcscmp(regvalue, token_id),
+ "GetDefaultTokenId (%s) should not be equal to the bogus DefaultdefaultTokenId key (%s)\n",
+ wine_dbgstr_w(token_id), wine_dbgstr_w(regvalue) );
+ CoTaskMemFree(token_id);
+
+ /* todo: test valid DefaultdefaultTokenId values */
+
+ ISpObjectTokenCategory_Release( cat );
+
+ res = RegDeleteTreeW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ res = RegOpenKeyExW( HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput", 0, KEY_ALL_ACCESS, &key );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ res = RegDeleteValueW( key, L"DefaultdefaultTokenId" );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ RegCloseKey(key);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+
+ hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
+ &IID_ISpObjectTokenCategory, (void **)&cat );
+ ok( hr == S_OK, "got %08x\n", hr );
+ hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ token_id = (LPWSTR)0xdeadbeef;
+ hr = ISpObjectTokenCategory_GetDefaultTokenId( cat, &token_id );
+ todo_wine ok( hr == S_OK, "got %08x\n", hr );
+ todo_wine ok( token_id != (LPWSTR)0xdeadbeef && token_id != NULL, "got %p\n", token_id );
+ if (token_id != (LPWSTR)0xdeadbeef)
+ CoTaskMemFree(token_id);
+
+ ISpObjectTokenCategory_Release( cat );
+ restore_speech( HKEY_LOCAL_MACHINE, FALSE );
+ hr = CoCreateInstance( &CLSID_SpObjectTokenCategory, NULL, CLSCTX_INPROC_SERVER,
+ &IID_ISpObjectTokenCategory, (void **)&cat );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = ISpObjectTokenCategory_SetDefaultTokenId( cat, NULL );
+ ok( hr == SPERR_UNINITIALIZED, "got %08x\n", hr );
+
+ hr = ISpObjectTokenCategory_SetId( cat, SPCAT_AUDIOOUT, FALSE );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = ISpObjectTokenCategory_SetDefaultTokenId( cat, NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+ wcscpy(regvalue, L"deadbeef");
+ hr = ISpObjectTokenCategory_SetDefaultTokenId( cat, regvalue );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ regvalue_size = sizeof( regvalue );
+ res = RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
+ L"DefaultTokenId", RRF_RT_REG_SZ, NULL, (LPVOID)®value, ®value_size);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ ok( !wcscmp(regvalue, L"deadbeef"),
+ "DefaultTokenId in registry (%s) should be equal to the set default token id (%s)\n",
+ wine_dbgstr_w(regvalue), wine_dbgstr_w(L"deadbeef") );
+
+ res = RegDeleteTreeW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput" );
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ wcscpy(regvalue, L"deadbeef");
+ hr = ISpObjectTokenCategory_SetDefaultTokenId( cat, regvalue );
+ ok( hr == S_OK, "got %08x\n", hr );
+ regvalue_size = sizeof( regvalue );
+ res = RegGetValueW( HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Speech\\AudioOutput",
+ L"DefaultTokenId", RRF_RT_REG_SZ, NULL, (LPVOID)®value, ®value_size);
+ ok( res == ERROR_SUCCESS, "got %08x\n", res );
+ ok( !wcscmp(regvalue, L"deadbeef"),
+ "GetDefaultTokenId (%s) should be equal to the set DefaultTokenId key (%s)\n",
+ wine_dbgstr_w(token_id), wine_dbgstr_w(L"deadbeef") );
+
+ ISpObjectTokenCategory_Release( cat );
+}
+
static void test_token_enum(void)
{
ISpObjectTokenEnumBuilder *token_enum;
@@ -121,6 +369,11 @@ START_TEST(token)
CoInitialize( NULL );
test_data_key();
test_token_category();
+ backup_speech( HKEY_LOCAL_MACHINE );
+ backup_speech( HKEY_CURRENT_USER );
+ test_token_default_id();
+ restore_speech( HKEY_CURRENT_USER, TRUE );
+ restore_speech( HKEY_LOCAL_MACHINE, TRUE );
test_token_enum();
CoUninitialize();
}
diff --git a/dlls/sapi/token.c b/dlls/sapi/token.c
index d2b70c95cf..78c5d2cdd5 100644
--- a/dlls/sapi/token.c
+++ b/dlls/sapi/token.c
@@ -232,6 +232,7 @@ struct token_category
LONG ref;
ISpRegDataKey *data_key;
+ WCHAR *subkey;
};
static struct token_category *impl_from_ISpObjectTokenCategory( ISpObjectTokenCategory *iface )
@@ -421,6 +422,8 @@ static HRESULT WINAPI token_category_SetId( ISpObjectTokenCategory *iface,
res = RegOpenKeyExW( root, subkey, 0, KEY_ALL_ACCESS, &key );
if (res) return SPERR_INVALID_REGISTRY_KEY;
+ This->subkey = _wcsdup(subkey);
+
hr = CoCreateInstance( &CLSID_SpDataKey, NULL, CLSCTX_ALL,
&IID_ISpRegDataKey, (void **)&This->data_key );
if (FAILED(hr)) goto fail;
@@ -479,18 +482,103 @@ fail:
return hr;
}
+static HRESULT get_user_speech_key( struct token_category *This, HKEY* key )
+{
+ LONG res;
+ WCHAR regvalue[512];
+ DWORD regvalue_size = sizeof( regvalue );
+
+ res = RegOpenKeyExW( HKEY_CURRENT_USER, This->subkey, 0, KEY_ALL_ACCESS, key );
+ if (res == ERROR_SUCCESS) {
+ return S_OK;
+ }
+
+ FIXME( "(%p): semi-stub\n", This );
+
+ res = RegCreateKeyW( HKEY_CURRENT_USER, This->subkey, key );
+ if (res != ERROR_SUCCESS) {
+ /* probably not the correct return value */
+ FIXME( "returning %08x\n", res );
+ return res;
+ }
+
+ res = RegGetValueW( HKEY_LOCAL_MACHINE, This->subkey, L"DefaultdefaultTokenId",
+ RRF_RT_REG_SZ, NULL, (LPVOID)®value, ®value_size);
+ if (res == ERROR_SUCCESS) {
+ RegSetValueExW( *key, L"DefaultTokenId", 0, REG_SZ, (const BYTE*)regvalue, regvalue_size);
+ }
+
+ return S_OK;
+}
+
static HRESULT WINAPI token_category_SetDefaultTokenId( ISpObjectTokenCategory *iface,
LPCWSTR id )
{
- FIXME( "stub\n" );
- return E_NOTIMPL;
+ struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
+ HRESULT hr;
+ LONG res;
+ HKEY key;
+
+ FIXME( "(%p)->(%s): semi-stub\n", iface, debugstr_w(id) );
+
+ if (!This->data_key)
+ return SPERR_UNINITIALIZED;
+
+ if (!id)
+ return E_INVALIDARG;
+
+ hr = get_user_speech_key( This, &key );
+ if (FAILED(hr)) return hr;
+
+ res = RegSetValueExW( key, L"DefaultTokenId", 0, REG_SZ, (const BYTE*)id,
+ wcslen( id) * sizeof( WCHAR ));
+ if (res != ERROR_SUCCESS) {
+ /* probably not the correct return value */
+ FIXME( "unable to set DefaultTokenId, returning S_FALSE\n" );
+ RegCloseKey( key );
+ return S_FALSE;
+ }
+
+ RegCloseKey( key );
+
+ return S_OK;
}
static HRESULT WINAPI token_category_GetDefaultTokenId( ISpObjectTokenCategory *iface,
LPWSTR *id )
{
- FIXME( "stub\n" );
- return E_NOTIMPL;
+ struct token_category *This = impl_from_ISpObjectTokenCategory( iface );
+ HRESULT hr;
+ LONG res;
+ HKEY key;
+ WCHAR regvalue[512];
+ DWORD regvalue_size = sizeof( regvalue );
+
+ FIXME( "(%p)->(%p): semi-stub\n", iface, id );
+
+ if (!This->data_key)
+ return SPERR_UNINITIALIZED;
+
+ if (!id)
+ return E_POINTER;
+
+ hr = get_user_speech_key( This, &key );
+ if (FAILED(hr)) return hr;
+
+ res = RegGetValueW( key, NULL, L"DefaultTokenId", RRF_RT_REG_SZ, NULL,
+ ®value, ®value_size);
+ if (res != ERROR_SUCCESS) {
+ FIXME( "DefaultTokenId is missing, returning S_FALSE\n" );
+ RegCloseKey( key );
+ return S_FALSE;
+ }
+
+ *id = CoTaskMemAlloc( regvalue_size );
+ wcscpy( *id, regvalue );
+
+ RegCloseKey( key );
+
+ return S_OK;
}
const struct ISpObjectTokenCategoryVtbl token_category_vtbl =
--
2.27.0
2
2
[PATCH] Revert "winegstreamer: Check for failure from gst_video_info_set_format()."
by Zebediah Figura Aug. 1, 2020
by Zebediah Figura Aug. 1, 2020
Aug. 1, 2020
This reverts commit ddd43e0a80bfd4c2e6f3ec650ed4b7d37890c46d.
This function returns void before 1.12.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49647
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/winegstreamer/gstdemux.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index fe5fe0e60df..e8f65a0e6ed 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -413,11 +413,7 @@ static GstCaps *amt_to_gst_caps_video(const AM_MEDIA_TYPE *mt)
return NULL;
}
- if (!gst_video_info_set_format(&info, format, vih->bmiHeader.biWidth, vih->bmiHeader.biHeight))
- {
- ERR("Failed to set format.\n");
- return NULL;
- }
+ gst_video_info_set_format(&info, format, vih->bmiHeader.biWidth, vih->bmiHeader.biHeight);
if ((caps = gst_video_info_to_caps(&info)))
{
/* Clear some fields that shouldn't prevent us from connecting. */
--
2.27.0
1
0
[PATCH] ws2_32: Avoid depending on system getservby(name|port) functions
by Alex Henrie Aug. 1, 2020
by Alex Henrie Aug. 1, 2020
Aug. 1, 2020
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
These functions are incredibly slow on Windows. To avoid timeouts, I had
to put the tests in protocol.c rather than the crowded sock.c.
---
configure.ac | 1 -
dlls/ws2_32/socket.c | 339 ++++++++++++++++++++++++---------
dlls/ws2_32/tests/protocol.c | 359 +++++++++++++++++++++++++++++++++++
dlls/ws2_32/tests/sock.c | 66 -------
4 files changed, 609 insertions(+), 156 deletions(-)
diff --git a/configure.ac b/configure.ac
index dea25b0c3f..2ad8552de7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2241,7 +2241,6 @@ AC_CHECK_FUNCS(\
getaddrinfo \
getnameinfo \
getnetbyname \
- getservbyport \
)
dnl Check for clock_gettime which may be in -lrt
diff --git a/dlls/ws2_32/socket.c b/dlls/ws2_32/socket.c
index eb21e4b4b3..2713be675a 100644
--- a/dlls/ws2_32/socket.c
+++ b/dlls/ws2_32/socket.c
@@ -649,7 +649,7 @@ static FARPROC blocking_hook = (FARPROC)WSA_DefaultBlockingHook;
static struct WS_hostent *WS_create_he(char *name, int aliases, int aliases_size, int addresses, int address_length);
static struct WS_hostent *WS_dup_he(const struct hostent* p_he);
static struct WS_protoent *WS_create_pe( const char *name, char **aliases, int prot );
-static struct WS_servent *WS_dup_se(const struct servent* p_se);
+static struct WS_servent *WS_create_se( const char *name, char **aliases, int port, const char *proto );
static int ws_protocol_info(SOCKET s, int unicode, WSAPROTOCOL_INFOW *buffer, int *size);
int WSAIOCTL_GetInterfaceCount(void);
@@ -1488,20 +1488,6 @@ static int convert_sockopt(INT *level, INT *optname)
/* ----------------------------------- Per-thread info (or per-process?) */
-static char *strdup_lower(const char *str)
-{
- int i;
- char *ret = HeapAlloc( GetProcessHeap(), 0, strlen(str) + 1 );
-
- if (ret)
- {
- for (i = 0; str[i]; i++) ret[i] = tolower(str[i]);
- ret[i] = 0;
- }
- else SetLastError(WSAENOBUFS);
- return ret;
-}
-
/* Utility: get the SO_RCVTIMEO or SO_SNDTIMEO socket option
* from an fd and return the value converted to milli seconds
* or 0 if there is an infinite time out */
@@ -6560,41 +6546,258 @@ struct WS_protoent* WINAPI WS_getprotobynumber(int number)
}
+static const struct
+{
+ unsigned short port;
+ const char *names[3];
+ const char *protos[2];
+}
+services[] =
+{
+ { 7, {"echo"}, {"tcp", "udp"} },
+ { 9, {"discard", "sink"}, {"tcp", "udp"} },
+ { 11, {"systat", "users"}, {"tcp", "udp"} },
+ { 13, {"daytime"}, {"tcp", "udp"} },
+ { 17, {"qotd", "quote"}, {"tcp", "udp"} },
+ { 19, {"chargen", "ttytst"}, {"tcp", "udp"} },
+ { 20, {"ftp-data"}, {"tcp"} },
+ { 21, {"ftp"}, {"tcp"} },
+ { 22, {"ssh"}, {"tcp"} },
+ { 23, {"telnet"}, {"tcp"} },
+ { 25, {"smtp", "mail"}, {"tcp"} },
+ { 37, {"time", "timserver"}, {"tcp", "udp"} },
+ { 39, {"rlp", "resource"}, {"udp"} },
+ { 42, {"nameserver", "name"}, {"tcp", "udp"} },
+ { 43, {"nicname", "whois"}, {"tcp"} },
+ { 53, {"domain"}, {"tcp", "udp"} },
+ { 67, {"bootps", "dhcps"}, {"udp"} },
+ { 68, {"bootpc", "dhcpc"}, {"udp"} },
+ { 69, {"tftp"}, {"udp"} },
+ { 70, {"gopher"}, {"tcp"} },
+ { 79, {"finger"}, {"tcp"} },
+ { 80, {"http", "www"}, {"tcp"} },
+ { 81, {"hosts2-ns"}, {"tcp", "udp"} },
+ { 88, {"kerberos", "krb5"}, {"tcp", "udp"} },
+ { 101, {"hostname", "hostnames"}, {"tcp"} },
+ { 102, {"iso-tsap"}, {"tcp"} },
+ { 107, {"rtelnet"}, {"tcp"} },
+ { 109, {"pop2", "postoffice"}, {"tcp"} },
+ { 110, {"pop3"}, {"tcp"} },
+ { 111, {"sunrpc", "rpcbind"}, {"tcp", "udp"} },
+ { 113, {"auth", "ident"}, {"tcp"} },
+ { 117, {"uucp-path"}, {"tcp"} },
+ { 118, {"sqlserv"}, {"tcp"} },
+ { 119, {"nntp", "usenet"}, {"tcp"} },
+ { 123, {"ntp"}, {"udp"} },
+ { 135, {"epmap", "loc-srv"}, {"tcp", "udp"} },
+ { 137, {"netbios-ns", "nbname"}, {"tcp", "udp"} },
+ { 138, {"netbios-dgm", "nbdatagram"}, {"udp"} },
+ { 139, {"netbios-ssn", "nbsession"}, {"tcp"} },
+ { 143, {"imap", "imap4"}, {"tcp"} },
+ { 150, {"sql-net"}, {"tcp"} },
+ { 156, {"sqlsrv"}, {"tcp"} },
+ { 158, {"pcmail-srv"}, {"tcp"} },
+ { 161, {"snmp"}, {"udp"} },
+ { 162, {"snmptrap", "snmp-trap"}, {"udp"} },
+ { 170, {"print-srv"}, {"tcp"} },
+ { 179, {"bgp"}, {"tcp"} },
+ { 194, {"irc"}, {"tcp"} },
+ { 213, {"ipx"}, {"udp"} },
+ { 322, {"rtsps"}, {"tcp", "udp"} },
+ { 349, {"mftp"}, {"tcp", "udp"} },
+ { 389, {"ldap"}, {"tcp"} },
+ { 443, {"https", "MCom"}, {"tcp", "udp"} },
+ { 445, {"microsoft-ds"}, {"tcp", "udp"} },
+ { 464, {"kpasswd"}, {"tcp", "udp"} },
+ { 500, {"isakmp", "ike"}, {"udp"} },
+ { 507, {"crs"}, {"tcp", "udp"} },
+ { 512, {"exec"}, {"tcp"} },
+ { 512, {"biff", "comsat"}, {"udp", "tcp"} },
+ { 513, {"login"}, {"tcp"} },
+ { 513, {"who", "whod"}, {"udp", "tcp"} },
+ { 514, {"cmd", "shell"}, {"tcp"} },
+ { 514, {"syslog"}, {"udp", "tcp"} },
+ { 515, {"printer", "spooler"}, {"tcp"} },
+ { 517, {"talk"}, {"udp"} },
+ { 518, {"ntalk"}, {"udp"} },
+ { 520, {"efs"}, {"tcp"} },
+ { 520, {"router", "route"}, {"udp", "tcp"} },
+ { 522, {"ulp"}, {"tcp", "udp"} },
+ { 525, {"timed", "timeserver"}, {"udp"} },
+ { 526, {"tempo", "newdate"}, {"tcp"} },
+ { 529, {"irc-serv"}, {"tcp", "udp"} },
+ { 530, {"courier", "rpc"}, {"tcp"} },
+ { 531, {"conference", "chat"}, {"tcp"} },
+ { 532, {"netnews", "readnews"}, {"tcp"} },
+ { 533, {"netwall"}, {"udp"} },
+ { 540, {"uucp", "uucpd"}, {"tcp"} },
+ { 543, {"klogin"}, {"tcp"} },
+ { 544, {"kshell", "krcmd"}, {"tcp"} },
+ { 546, {"dhcpv6-client"}, {"tcp", "udp"} },
+ { 547, {"dhcpv6-server"}, {"tcp", "udp"} },
+ { 548, {"afpovertcp"}, {"tcp", "udp"} },
+ { 550, {"new-rwho", "new-who"}, {"udp"} },
+ { 554, {"rtsp"}, {"tcp", "udp"} },
+ { 556, {"remotefs", "rfs"}, {"tcp"} },
+ { 560, {"rmonitor", "rmonitord"}, {"udp"} },
+ { 561, {"monitor"}, {"udp"} },
+ { 563, {"nntps", "snntp"}, {"tcp", "udp"} },
+ { 565, {"whoami"}, {"tcp", "udp"} },
+ { 568, {"ms-shuttle"}, {"tcp", "udp"} },
+ { 569, {"ms-rome"}, {"tcp", "udp"} },
+ { 593, {"http-rpc-epmap"}, {"tcp", "udp"} },
+ { 612, {"hmmp-ind"}, {"tcp", "udp"} },
+ { 613, {"hmmp-op"}, {"tcp", "udp"} },
+ { 636, {"ldaps", "sldap"}, {"tcp"} },
+ { 666, {"doom"}, {"tcp", "udp"} },
+ { 691, {"msexch-routing"}, {"tcp", "udp"} },
+ { 749, {"kerberos-adm"}, {"tcp", "udp"} },
+ { 750, {"kerberos-iv"}, {"udp"} },
+ { 800, {"mdbs_daemon"}, {"tcp", "udp"} },
+ { 989, {"ftps-data"}, {"tcp"} },
+ { 990, {"ftps"}, {"tcp"} },
+ { 992, {"telnets"}, {"tcp"} },
+ { 993, {"imaps"}, {"tcp"} },
+ { 994, {"ircs"}, {"tcp"} },
+ { 995, {"pop3s", "spop3"}, {"tcp", "udp"} },
+ { 1034, {"activesync"}, {"tcp"} },
+ { 1109, {"kpop"}, {"tcp"} },
+ { 1110, {"nfsd-status"}, {"tcp"} },
+ { 1110, {"nfsd-keepalive"}, {"udp"} },
+ { 1155, {"nfa"}, {"tcp", "udp"} },
+ { 1167, {"phone"}, {"udp"} },
+ { 1270, {"opsmgr"}, {"tcp", "udp"} },
+ { 1433, {"ms-sql-s"}, {"tcp", "udp"} },
+ { 1434, {"ms-sql-m"}, {"tcp", "udp"} },
+ { 1477, {"ms-sna-server"}, {"tcp", "udp"} },
+ { 1478, {"ms-sna-base"}, {"tcp", "udp"} },
+ { 1512, {"wins"}, {"tcp", "udp"} },
+ { 1524, {"ingreslock", "ingres"}, {"tcp"} },
+ { 1607, {"stt"}, {"tcp", "udp"} },
+ { 1701, {"l2tp"}, {"udp"} },
+ { 1711, {"pptconference"}, {"tcp", "udp"} },
+ { 1723, {"pptp"}, {"tcp"} },
+ { 1731, {"msiccp"}, {"tcp", "udp"} },
+ { 1745, {"remote-winsock"}, {"tcp", "udp"} },
+ { 1755, {"ms-streaming"}, {"tcp", "udp"} },
+ { 1801, {"msmq"}, {"tcp", "udp"} },
+ { 1812, {"radius"}, {"udp"} },
+ { 1813, {"radacct"}, {"udp"} },
+ { 1863, {"msnp"}, {"tcp", "udp"} },
+ { 1900, {"ssdp"}, {"tcp", "udp"} },
+ { 1944, {"close-combat"}, {"tcp", "udp"} },
+ { 2049, {"nfsd", "nfs"}, {"udp"} },
+ { 2053, {"knetd"}, {"tcp"} },
+ { 2106, {"mzap"}, {"tcp", "udp"} },
+ { 2177, {"qwave"}, {"tcp", "udp"} },
+ { 2234, {"directplay"}, {"tcp", "udp"} },
+ { 2382, {"ms-olap3"}, {"tcp", "udp"} },
+ { 2383, {"ms-olap4"}, {"tcp", "udp"} },
+ { 2393, {"ms-olap1"}, {"tcp", "udp"} },
+ { 2394, {"ms-olap2"}, {"tcp", "udp"} },
+ { 2460, {"ms-theater"}, {"tcp", "udp"} },
+ { 2504, {"wlbs"}, {"tcp", "udp"} },
+ { 2525, {"ms-v-worlds"}, {"tcp", "udp"} },
+ { 2701, {"sms-rcinfo"}, {"tcp", "udp"} },
+ { 2702, {"sms-xfer"}, {"tcp", "udp"} },
+ { 2703, {"sms-chat"}, {"tcp", "udp"} },
+ { 2704, {"sms-remctrl"}, {"tcp", "udp"} },
+ { 2725, {"msolap-ptp2"}, {"tcp", "udp"} },
+ { 2869, {"icslap"}, {"tcp", "udp"} },
+ { 3020, {"cifs"}, {"tcp", "udp"} },
+ { 3074, {"xbox"}, {"tcp", "udp"} },
+ { 3126, {"ms-dotnetster"}, {"tcp", "udp"} },
+ { 3132, {"ms-rule-engine"}, {"tcp", "udp"} },
+ { 3268, {"msft-gc"}, {"tcp", "udp"} },
+ { 3269, {"msft-gc-ssl"}, {"tcp", "udp"} },
+ { 3343, {"ms-cluster-net"}, {"tcp", "udp"} },
+ { 3389, {"ms-wbt-server"}, {"tcp", "udp"} },
+ { 3535, {"ms-la"}, {"tcp", "udp"} },
+ { 3540, {"pnrp-port"}, {"tcp", "udp"} },
+ { 3544, {"teredo"}, {"tcp", "udp"} },
+ { 3587, {"p2pgroup"}, {"tcp", "udp"} },
+ { 3702, {"ws-discovery", "upnp-discovery"}, {"udp", "tcp"} },
+ { 3776, {"dvcprov-port"}, {"tcp", "udp"} },
+ { 3847, {"msfw-control"}, {"tcp"} },
+ { 3882, {"msdts1"}, {"tcp"} },
+ { 3935, {"sdp-portmapper"}, {"tcp", "udp"} },
+ { 4350, {"net-device"}, {"tcp", "udp"} },
+ { 4500, {"ipsec-msft"}, {"tcp", "udp"} },
+ { 5355, {"llmnr"}, {"tcp", "udp"} },
+ { 5357, {"wsd"}, {"tcp"} },
+ { 5358, {"wsd"}, {"tcp"} },
+ { 5678, {"rrac"}, {"tcp", "udp"} },
+ { 5679, {"dccm"}, {"tcp", "udp"} },
+ { 5720, {"ms-licensing"}, {"tcp", "udp"} },
+ { 6073, {"directplay8"}, {"tcp", "udp"} },
+ { 9535, {"man"}, {"tcp"} },
+ { 9753, {"rasadv"}, {"tcp", "udp"} },
+ { 11320, {"imip-channels"}, {"tcp", "udp"} },
+ { 47624, {"directplaysrvr"}, {"tcp", "udp"} },
+};
+
/***********************************************************************
* getservbyname (WS2_32.55)
*/
struct WS_servent* WINAPI WS_getservbyname(const char *name, const char *proto)
{
struct WS_servent* retval = NULL;
- struct servent* serv;
- char *name_str;
- char *proto_str = NULL;
-
- if (!(name_str = strdup_lower(name))) return NULL;
-
- if (proto && *proto)
+ int i, j, k;
+ for (i = 0; i < ARRAY_SIZE(services); i++)
{
- if (!(proto_str = strdup_lower(proto)))
+ for (j = 0; services[i].names[j]; j++)
{
- HeapFree( GetProcessHeap(), 0, name_str );
- return NULL;
+ if (_strnicmp(services[i].names[j], name, -1) != 0) continue;
+ for (k = 0; k < ARRAY_SIZE(services[0].protos) && services[i].protos[k]; k++)
+ {
+ if (proto && _strnicmp(services[i].protos[k], proto, -1) != 0) continue;
+ retval = WS_create_se(services[i].names[0], (char **)services[i].names + 1,
+ services[i].port, services[i].protos[k]);
+ goto found;
+ }
+ break;
}
}
+ if (!retval)
+ {
+ WARN("service %s/%s not found\n", debugstr_a(name), debugstr_a(proto));
+ SetLastError(WSANO_DATA);
+ }
+found:
+ TRACE("%s/%s ret %p\n", debugstr_a(name), debugstr_a(proto), retval);
+ return retval;
+}
- EnterCriticalSection( &csWSgetXXXbyYYY );
- serv = getservbyname(name_str, proto_str);
- if( serv != NULL )
+/***********************************************************************
+ * getservbyport (WS2_32.56)
+ */
+struct WS_servent* WINAPI WS_getservbyport(int port, const char *proto)
+{
+ struct WS_servent* retval = NULL;
+ int i, j;
+ port = ntohs(port);
+ for (i = 0; i < ARRAY_SIZE(services); i++)
+ {
+ if (services[i].port != port) continue;
+ for (j = 0; j < ARRAY_SIZE(services[0].protos) && services[i].protos[j]; j++)
+ {
+ if (proto && _strnicmp(services[i].protos[j], proto, -1) != 0) continue;
+ retval = WS_create_se(services[i].names[0], (char **)services[i].names + 1,
+ services[i].port, services[i].protos[j]);
+ goto found;
+ }
+ }
+ if (!retval)
{
- retval = WS_dup_se(serv);
+ WARN("service %d/%s not found\n", port, debugstr_a(proto));
+ SetLastError(WSANO_DATA);
}
- else SetLastError(WSANO_DATA);
- LeaveCriticalSection( &csWSgetXXXbyYYY );
- HeapFree( GetProcessHeap(), 0, proto_str );
- HeapFree( GetProcessHeap(), 0, name_str );
- TRACE( "%s, %s ret %p\n", debugstr_a(name), debugstr_a(proto), retval );
+found:
+ TRACE("%d/%s ret %p\n", port, debugstr_a(proto), retval);
return retval;
}
+
/***********************************************************************
* freeaddrinfo (WS2_32.@)
*/
@@ -7285,32 +7488,6 @@ int WINAPI GetNameInfoW(const SOCKADDR *sa, WS_socklen_t salen, PWCHAR host,
return ret;
}
-/***********************************************************************
- * getservbyport (WS2_32.56)
- */
-struct WS_servent* WINAPI WS_getservbyport(int port, const char *proto)
-{
- struct WS_servent* retval = NULL;
-#ifdef HAVE_GETSERVBYPORT
- struct servent* serv;
- char *proto_str = NULL;
-
- if (proto && *proto)
- {
- if (!(proto_str = strdup_lower(proto))) return NULL;
- }
- EnterCriticalSection( &csWSgetXXXbyYYY );
- if( (serv = getservbyport(port, proto_str)) != NULL ) {
- retval = WS_dup_se(serv);
- }
- else SetLastError(WSANO_DATA);
- LeaveCriticalSection( &csWSgetXXXbyYYY );
- HeapFree( GetProcessHeap(), 0, proto_str );
-#endif
- TRACE("%d (i.e. port %d), %s ret %p\n", port, (int)ntohl(port), debugstr_a(proto), retval);
- return retval;
-}
-
/***********************************************************************
* gethostname (WS2_32.57)
@@ -7795,12 +7972,7 @@ INT WINAPI WSAUnhookBlockingHook(void)
/* ----------------------------------- end of API stuff */
-/* ----------------------------------- helper functions -
- *
- * TODO: Merge WS_dup_..() stuff into one function that
- * would operate with a generic structure containing internal
- * pointers (via a template of some kind).
- */
+/* ----------------------------------- helper functions */
static int list_size(char** l, int item_size)
{
@@ -7935,31 +8107,20 @@ static struct WS_protoent *WS_create_pe( const char *name, char **aliases, int p
/* ----- servent */
-static struct WS_servent *WS_dup_se(const struct servent* p_se)
+static struct WS_servent *WS_create_se( const char *name, char **aliases, int port, const char *proto )
{
- char *p;
- struct WS_servent *p_to;
-
- int size = (sizeof(*p_se) +
- strlen(p_se->s_proto) + 1 +
- strlen(p_se->s_name) + 1 +
- list_size(p_se->s_aliases, 0));
-
- if (!(p_to = check_buffer_se(size))) return NULL;
- p_to->s_port = p_se->s_port;
-
- p = (char *)(p_to + 1);
- p_to->s_name = p;
- strcpy(p, p_se->s_name);
- p += strlen(p) + 1;
-
- p_to->s_proto = p;
- strcpy(p, p_se->s_proto);
- p += strlen(p) + 1;
+ struct WS_servent *ret;
+ unsigned int size = sizeof(*ret) + strlen(name) + 1 + strlen(proto) + sizeof(char *) + list_size(aliases, 0);
- p_to->s_aliases = (char **)p;
- list_dup(p_se->s_aliases, p_to->s_aliases, 0);
- return p_to;
+ if (!(ret = check_buffer_se( size ))) return NULL;
+ ret->s_port = htons(port);
+ ret->s_name = (char *)(ret + 1);
+ ret->s_proto = (char *)ret->s_name + strlen(name) + 1;
+ strcpy( ret->s_name, name );
+ strcpy( ret->s_proto, proto );
+ ret->s_aliases = (char **)ret->s_proto + strlen(proto) / sizeof(char *) + 1;
+ list_dup( aliases, ret->s_aliases, 0 );
+ return ret;
}
diff --git a/dlls/ws2_32/tests/protocol.c b/dlls/ws2_32/tests/protocol.c
index d6e454a5fb..b230ac80c8 100644
--- a/dlls/ws2_32/tests/protocol.c
+++ b/dlls/ws2_32/tests/protocol.c
@@ -39,6 +39,13 @@
| XP1_SUPPORT_MULTIPOINT \
| XP1_IFS_HANDLES)
+#define PRIVATE_PORT_START 49152
+
+#define TEST_TIMEOUT 30 /* Seconds to wait before killing child threads
+ after server initialization, if something hangs */
+#define NUM_THREADS 3 /* Number of threads to run getservbyname */
+#define NUM_QUERIES 250 /* Number of getservbyname queries per thread */
+
static void test_service_flags(int family, int version, int socktype, int protocol, DWORD testflags)
{
DWORD expectedflags = 0;
@@ -290,6 +297,356 @@ static void test_getprotobynumber(void)
}
}
+struct service
+{
+ unsigned short port;
+ const char *names[2];
+ const char *protos[2];
+ enum { MISSING = 0x1, RENAMED = 0x2 } flags;
+};
+
+static const struct service services[] =
+{
+ { 7, {"echo"}, {"tcp", "udp"} },
+ { 9, {"discard", "sink"}, {"tcp", "udp"} },
+ { 11, {"systat", "users"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 13, {"daytime"}, {"tcp", "udp"} },
+ { 17, {"qotd", "quote"}, {"tcp", "udp"} },
+ { 19, {"chargen", "ttytst"}, {"tcp", "udp"} },
+ { 20, {"ftp-data"}, {"tcp"} },
+ { 21, {"ftp"}, {"tcp"} },
+ { 22, {"ssh"}, {"tcp"}, MISSING /* xp */ },
+ { 23, {"telnet"}, {"tcp"} },
+ { 25, {"smtp", "mail"}, {"tcp"} },
+ { 37, {"time", "timserver"}, {"tcp", "udp"} },
+ { 39, {"rlp", "resource"}, {"udp"} },
+ { 42, {"nameserver", "name"}, {"tcp", "udp"} },
+ { 43, {"nicname", "whois"}, {"tcp"} },
+ { 53, {"domain"}, {"tcp", "udp"} },
+ { 67, {"bootps", "dhcps"}, {"udp"} },
+ { 68, {"bootpc", "dhcpc"}, {"udp"} },
+ { 69, {"tftp"}, {"udp"} },
+ { 70, {"gopher"}, {"tcp"} },
+ { 79, {"finger"}, {"tcp"} },
+ { 80, {"http", "www"}, {"tcp"} },
+ { 81, {"hosts2-ns"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 88, {"kerberos", "krb5"}, {"tcp", "udp"} },
+ { 101, {"hostname", "hostnames"}, {"tcp"} },
+ { 102, {"iso-tsap"}, {"tcp"} },
+ { 107, {"rtelnet"}, {"tcp"} },
+ { 109, {"pop2", "postoffice"}, {"tcp"} },
+ { 110, {"pop3"}, {"tcp"} },
+ { 111, {"sunrpc", "rpcbind"}, {"tcp", "udp"} },
+ { 113, {"auth", "ident"}, {"tcp"} },
+ { 117, {"uucp-path"}, {"tcp"} },
+ { 118, {"sqlserv"}, {"tcp"}, MISSING /* xp */ },
+ { 119, {"nntp", "usenet"}, {"tcp"} },
+ { 123, {"ntp"}, {"udp"} },
+ { 135, {"epmap", "loc-srv"}, {"tcp", "udp"} },
+ { 137, {"netbios-ns", "nbname"}, {"tcp", "udp"} },
+ { 138, {"netbios-dgm", "nbdatagram"}, {"udp"} },
+ { 139, {"netbios-ssn", "nbsession"}, {"tcp"} },
+ { 143, {"imap", "imap4"}, {"tcp"} },
+ { 150, {"sql-net"}, {"tcp"}, MISSING /* xp */ },
+ { 156, {"sqlsrv"}, {"tcp"}, MISSING /* xp */ },
+ { 158, {"pcmail-srv"}, {"tcp"} },
+ { 161, {"snmp"}, {"udp"} },
+ { 162, {"snmptrap", "snmp-trap"}, {"udp"} },
+ { 170, {"print-srv"}, {"tcp"} },
+ { 179, {"bgp"}, {"tcp"} },
+ { 194, {"irc"}, {"tcp"} },
+ { 213, {"ipx"}, {"udp"} },
+ { 322, {"rtsps"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 349, {"mftp"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 389, {"ldap"}, {"tcp"} },
+ { 443, {"https", "MCom"}, {"tcp", "udp"} },
+ { 445, {"microsoft-ds"}, {"tcp", "udp"} },
+ { 464, {"kpasswd"}, {"tcp", "udp"} },
+ { 500, {"isakmp", "ike"}, {"udp"} },
+ { 507, {"crs"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 512, {"exec"}, {"tcp"} },
+ { 512, {"biff", "comsat"}, {"udp", "tcp"}, MISSING /* win10 */ },
+ { 513, {"login"}, {"tcp"} },
+ { 513, {"who", "whod"}, {"udp", "tcp"}, MISSING /* win10 */ },
+ { 514, {"cmd", "shell"}, {"tcp"} },
+ { 514, {"syslog"}, {"udp", "tcp"}, MISSING /* win10 */ },
+ { 515, {"printer", "spooler"}, {"tcp"} },
+ { 517, {"talk"}, {"udp"} },
+ { 518, {"ntalk"}, {"udp"} },
+ { 520, {"efs"}, {"tcp"} },
+ { 520, {"router", "route"}, {"udp", "tcp"}, MISSING /* win10 */ },
+ { 522, {"ulp"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 525, {"timed", "timeserver"}, {"udp"} },
+ { 526, {"tempo", "newdate"}, {"tcp"} },
+ { 529, {"irc-serv"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 530, {"courier", "rpc"}, {"tcp"} },
+ { 531, {"conference", "chat"}, {"tcp"} },
+ { 532, {"netnews", "readnews"}, {"tcp"} },
+ { 533, {"netwall"}, {"udp"} },
+ { 540, {"uucp", "uucpd"}, {"tcp"} },
+ { 543, {"klogin"}, {"tcp"} },
+ { 544, {"kshell", "krcmd"}, {"tcp"} },
+ { 546, {"dhcpv6-client"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 547, {"dhcpv6-server"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 548, {"afpovertcp"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 550, {"new-rwho", "new-who"}, {"udp"} },
+ { 554, {"rtsp"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 556, {"remotefs", "rfs"}, {"tcp"} },
+ { 560, {"rmonitor", "rmonitord"}, {"udp"} },
+ { 561, {"monitor"}, {"udp"} },
+ { 563, {"nntps", "snntp"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 565, {"whoami"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 568, {"ms-shuttle"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 569, {"ms-rome"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 593, {"http-rpc-epmap"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 612, {"hmmp-ind"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 613, {"hmmp-op"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 636, {"ldaps", "sldap"}, {"tcp"} },
+ { 666, {"doom"}, {"tcp", "udp"} },
+ { 691, {"msexch-routing"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 749, {"kerberos-adm"}, {"tcp", "udp"} },
+ { 750, {"kerberos-iv"}, {"udp"} },
+ { 800, {"mdbs_daemon"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 989, {"ftps-data"}, {"tcp"}, MISSING /* xp */ },
+ { 990, {"ftps"}, {"tcp"}, MISSING /* xp */ },
+ { 992, {"telnets"}, {"tcp"}, MISSING /* xp */ },
+ { 993, {"imaps"}, {"tcp"}, MISSING /* xp */ },
+ { 994, {"ircs"}, {"tcp"}, MISSING /* xp */ },
+ { 995, {"pop3s", "spop3"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1034, {"activesync"}, {"tcp"}, MISSING /* xp */ },
+ { 1109, {"kpop"}, {"tcp"} },
+ { 1110, {"nfsd-status"}, {"tcp"}, MISSING /* xp */ },
+ { 1110, {"nfsd-keepalive"}, {"udp"}, MISSING /* xp */ },
+ { 1155, {"nfa"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1167, {"phone"}, {"udp"} },
+ { 1270, {"opsmgr"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1433, {"ms-sql-s"}, {"tcp", "udp"} },
+ { 1434, {"ms-sql-m"}, {"tcp", "udp"} },
+ { 1477, {"ms-sna-server"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1478, {"ms-sna-base"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1512, {"wins"}, {"tcp", "udp"} },
+ { 1524, {"ingreslock", "ingres"}, {"tcp"} },
+ { 1607, {"stt"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1701, {"l2tp"}, {"udp"} },
+ { 1711, {"pptconference"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1723, {"pptp"}, {"tcp"} },
+ { 1731, {"msiccp"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1745, {"remote-winsock"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1755, {"ms-streaming"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1801, {"msmq"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1812, {"radius"}, {"udp"} },
+ { 1813, {"radacct"}, {"udp"} },
+ { 1863, {"msnp"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1900, {"ssdp"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 1944, {"close-combat"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2049, {"nfsd", "nfs"}, {"udp"} },
+ { 2053, {"knetd"}, {"tcp"} },
+ { 2106, {"mzap"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2177, {"qwave"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2234, {"directplay"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2382, {"ms-olap3"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2383, {"ms-olap4"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2393, {"ms-olap1"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2394, {"ms-olap2"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2460, {"ms-theater"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2504, {"wlbs"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2525, {"ms-v-worlds"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2701, {"sms-rcinfo"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2702, {"sms-xfer"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2703, {"sms-chat"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2704, {"sms-remctrl"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2725, {"msolap-ptp2"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 2869, {"icslap"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3020, {"cifs"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3074, {"xbox"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3126, {"ms-dotnetster"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3132, {"ms-rule-engine"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3268, {"msft-gc"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3269, {"msft-gc-ssl"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3343, {"ms-cluster-net"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3389, {"ms-wbt-server"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3535, {"ms-la"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3540, {"pnrp-port"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3544, {"teredo"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3587, {"p2pgroup"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3702, {"ws-discovery", "upnp-discovery"}, {"udp", "tcp"}, MISSING /* xp */ | RENAMED /* 2008 */ },
+ { 3776, {"dvcprov-port"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 3847, {"msfw-control"}, {"tcp"}, MISSING /* xp */ },
+ { 3882, {"msdts1"}, {"tcp"}, MISSING /* xp */ },
+ { 3935, {"sdp-portmapper"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 4350, {"net-device"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 4500, {"ipsec-msft"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 5355, {"llmnr"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 5357, {"wsd"}, {"tcp"}, MISSING /* xp */ },
+ { 5358, {"wsd"}, {"tcp"}, MISSING /* xp */ },
+ { 5678, {"rrac"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 5679, {"dccm"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 5720, {"ms-licensing"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 6073, {"directplay8"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 9535, {"man"}, {"tcp"} },
+ { 9753, {"rasadv"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 11320, {"imip-channels"}, {"tcp", "udp"}, MISSING /* xp */ },
+ { 47624, {"directplaysrvr"}, {"tcp", "udp"}, MISSING /* xp */ },
+};
+
+static const struct service *find_service(int port, const char *proto)
+{
+ int i, j;
+ for (i = 0; i < ARRAY_SIZE(services) && services[i].port <= port; i++)
+ {
+ if (services[i].port != port) continue;
+ for (j = 0; j < ARRAY_SIZE(services[0].protos) && services[i].protos[j]; j++)
+ {
+ if (!proto || _stricmp(proto, services[i].protos[j]) == 0)
+ return &services[i];
+ }
+ }
+ return NULL;
+}
+
+static DWORD WINAPI do_getservbyname(void *param)
+{
+ HANDLE *starttest = param;
+ int i, j, k, l;
+ struct servent *results[ARRAY_SIZE(services)];
+ char all_caps_name[16];
+
+ if (starttest)
+ {
+ ok(WaitForSingleObject(*starttest, TEST_TIMEOUT * 1000) != WAIT_TIMEOUT,
+ "test_getservbyname: timeout waiting for start signal\n");
+ }
+
+ /* ensure that necessary buffer resizes are completed */
+ for (i = 0; i < 2; i++)
+ results[i] = getservbyname(services[i].names[0], NULL);
+
+ for (i = 0; i < (starttest ? NUM_QUERIES / 2 : 1); i++)
+ {
+ for (j = 0; j < (starttest ? 2 : ARRAY_SIZE(services)); j++)
+ {
+ if (j > 0 && strcmp(services[j].names[0], services[j-1].names[0]) == 0) continue;
+ for (k = 0; k < ARRAY_SIZE(services[0].names) && services[j].names[k]; k++)
+ {
+ for (l = 0; services[j].names[k][l]; l++)
+ all_caps_name[l] = toupper(services[j].names[k][l]);
+ all_caps_name[l] = 0;
+ for (l = 0; l < ARRAY_SIZE(services[0].protos); l++)
+ {
+ results[j] = getservbyname(services[j].names[k], services[j].protos[l]);
+ ok(results[j] != NULL || broken(services[j].flags & MISSING),
+ "getservbyname could not retrieve information for %s/%s: %d\n",
+ services[j].names[k], wine_dbgstr_a(services[j].protos[l]), WSAGetLastError());
+ if (!results[j]) continue;
+ ok(ntohs(results[j]->s_port) == services[j].port,
+ "getservbyname returned the wrong port for %s/%s: %d\n",
+ services[j].names[k], wine_dbgstr_a(services[j].protos[l]), ntohs(results[j]->s_port));
+ ok(!strcmp(results[j]->s_proto, services[j].protos[l] ? services[j].protos[l] : services[j].protos[0]),
+ "getservbyname returned the wrong protocol for %s/%s: %s\n",
+ services[j].names[k], wine_dbgstr_a(services[j].protos[l]), results[j]->s_proto);
+ ok(!strcmp(results[j]->s_name, services[j].names[0]) ||
+ broken((services[j].flags & RENAMED) && !strcmp(results[j]->s_name, services[j].names[1])),
+ "getservbyname returned the wrong name for %s/%s: %s\n",
+ services[j].names[k], wine_dbgstr_a(services[j].protos[l]), results[j]->s_name);
+
+ results[j] = getservbyname(all_caps_name, services[j].protos[l]);
+ ok(ntohs(results[j]->s_port) == services[j].port,
+ "getservbyname returned the wrong port for %s/%s: %d\n",
+ all_caps_name, wine_dbgstr_a(services[j].protos[l]), ntohs(results[j]->s_port));
+ ok(!strcmp(results[j]->s_proto, services[j].protos[l] ? services[j].protos[l] : services[j].protos[0]),
+ "getservbyname returned the wrong protocol for %s/%s: %s\n",
+ all_caps_name, wine_dbgstr_a(services[j].protos[l]), results[j]->s_proto);
+ ok(!strcmp(results[j]->s_name, services[j].names[0]) ||
+ broken((services[j].flags & RENAMED) && !strcmp(results[j]->s_name, services[j].names[1])),
+ "getservbyname returned the wrong name for %s/%s: %s\n",
+ all_caps_name, wine_dbgstr_a(services[j].protos[l]), results[j]->s_name);
+ }
+ }
+ }
+ ok(results[0] == results[1],
+ "getservbyname: winsock resized servent buffer when not necessary\n");
+ }
+
+ return 0;
+}
+
+static void test_getservbyname(void)
+{
+ int i;
+ HANDLE starttest, thread[NUM_THREADS];
+ DWORD thread_id[NUM_THREADS];
+
+ /* test the complete list of service entries */
+ do_getservbyname(NULL);
+
+ /* test thread safety using just the first two service entries */
+ starttest = CreateEventA(NULL, 1, 0, "test_getservbyname_starttest");
+
+ /* create threads */
+ for (i = 0; i < NUM_THREADS; i++)
+ thread[i] = CreateThread(NULL, 0, do_getservbyname, &starttest, 0, &thread_id[i]);
+
+ /* signal threads to start */
+ SetEvent(starttest);
+
+ for (i = 0; i < NUM_THREADS; i++)
+ WaitForSingleObject(thread[i], TEST_TIMEOUT * 1000);
+}
+
+static void test_getservbyport(void)
+{
+ static const char *test_protos[] = { NULL, "tcp", "udp", "icmp", "Tcp", "udP" };
+ struct servent *ent;
+ const struct service *ref;
+ int i, j;
+
+ /* Testing all port/protocol combinations takes a very long time on Windows. To avoid timeouts,
+ * don't test the private port range and skip the tests for specific protocols if there is no
+ * defined service on a particular port for any protocol. */
+ for (i = 0; i <= PRIVATE_PORT_START; i++)
+ {
+ for (j = 0; j < ARRAY_SIZE(test_protos); j++)
+ {
+ ent = getservbyport(htons(i), test_protos[j]);
+ ref = find_service(i, test_protos[j]);
+
+ if (!ref)
+ {
+ ok(!ent, "Expected service %d/%s to be undefined, got %s\n",
+ i, wine_dbgstr_a(test_protos[j]), wine_dbgstr_a(ent ? ent->s_name : NULL));
+ if (!ent && j == 0) break;
+ continue;
+ }
+
+ ok((ent && ent->s_name && strcmp(ent->s_name, ref->names[0]) == 0) ||
+ broken((ref->flags & MISSING) && !ent) ||
+ broken((ref->flags & RENAMED) && ent && ent->s_name && strcmp(ent->s_name, ref->names[1]) == 0),
+ "Expected service %d/%s to be %s, got %s\n",
+ i, wine_dbgstr_a(test_protos[j]), wine_dbgstr_a(ref->names[0]),
+ wine_dbgstr_a(ent ? ent->s_name : NULL));
+
+ if (ref->names[1])
+ {
+ ok((ent && ent->s_aliases && ent->s_aliases[0] &&
+ strcmp(ent->s_aliases[0], ref->names[1]) == 0) ||
+ broken((ref->flags & MISSING) && !ent) ||
+ broken((ref->flags & RENAMED) && ent && ent->s_aliases && !ent->s_aliases[0]),
+ "Expected service %d/%s alias 0 to be %s, got %s\n",
+ i, wine_dbgstr_a(test_protos[j]), wine_dbgstr_a(ref->names[1]),
+ wine_dbgstr_a(ent && ent->s_aliases ? ent->s_aliases[0] : NULL));
+ }
+ else
+ {
+ ok((ent && ent->s_aliases && !ent->s_aliases[0]) ||
+ broken((ref->flags & MISSING) && !ent),
+ "Expected service %d/%s alias 0 to be undefined, got %s\n",
+ i, wine_dbgstr_a(test_protos[j]),
+ wine_dbgstr_a(ent && ent->s_aliases ? ent->s_aliases[0] : NULL));
+ }
+ }
+ }
+}
+
START_TEST( protocol )
{
WSADATA data;
@@ -301,4 +658,6 @@ START_TEST( protocol )
test_WSAEnumProtocolsW();
test_getprotobyname();
test_getprotobynumber();
+ test_getservbyname();
+ test_getservbyport();
}
diff --git a/dlls/ws2_32/tests/sock.c b/dlls/ws2_32/tests/sock.c
index b7a3fc4453..511fbf5f1d 100644
--- a/dlls/ws2_32/tests/sock.c
+++ b/dlls/ws2_32/tests/sock.c
@@ -45,9 +45,6 @@
#define NUM_UDP_PEERS 3 /* Number of UDP sockets to create and test > 1 */
-#define NUM_THREADS 3 /* Number of threads to run getservbyname */
-#define NUM_QUERIES 250 /* Number of getservbyname queries per thread */
-
#define SERVERIP "127.0.0.1" /* IP to bind to */
#define SERVERPORT 9374 /* Port number to bind to */
@@ -2401,68 +2398,6 @@ static void test_UDP(void)
}
}
-static DWORD WINAPI do_getservbyname( void *param )
-{
- struct {
- const char *name;
- const char *proto;
- int port;
- } serv[2] = { {"domain", "udp", 53}, {"telnet", "tcp", 23} };
-
- HANDLE *starttest = param;
- int i, j;
- struct servent *pserv[2];
-
- ok ( WaitForSingleObject ( *starttest, TEST_TIMEOUT * 1000 ) != WAIT_TIMEOUT,
- "test_getservbyname: timeout waiting for start signal\n" );
-
- /* ensure that necessary buffer resizes are completed */
- for ( j = 0; j < 2; j++) {
- pserv[j] = getservbyname ( serv[j].name, serv[j].proto );
- }
-
- for ( i = 0; i < NUM_QUERIES / 2; i++ ) {
- for ( j = 0; j < 2; j++ ) {
- pserv[j] = getservbyname ( serv[j].name, serv[j].proto );
- ok ( pserv[j] != NULL || broken(pserv[j] == NULL) /* win8, fixed in win81 */,
- "getservbyname could not retrieve information for %s: %d\n", serv[j].name, WSAGetLastError() );
- if ( !pserv[j] ) continue;
- ok ( pserv[j]->s_port == htons(serv[j].port),
- "getservbyname returned the wrong port for %s: %d\n", serv[j].name, ntohs(pserv[j]->s_port) );
- ok ( !strcmp ( pserv[j]->s_proto, serv[j].proto ),
- "getservbyname returned the wrong protocol for %s: %s\n", serv[j].name, pserv[j]->s_proto );
- ok ( !strcmp ( pserv[j]->s_name, serv[j].name ),
- "getservbyname returned the wrong name for %s: %s\n", serv[j].name, pserv[j]->s_name );
- }
-
- ok ( pserv[0] == pserv[1] || broken(pserv[0] != pserv[1]) /* win8, fixed in win81 */,
- "getservbyname: winsock resized servent buffer when not necessary\n" );
- }
-
- return 0;
-}
-
-static void test_getservbyname(void)
-{
- int i;
- HANDLE starttest, thread[NUM_THREADS];
- DWORD thread_id[NUM_THREADS];
-
- starttest = CreateEventA ( NULL, 1, 0, "test_getservbyname_starttest" );
-
- /* create threads */
- for ( i = 0; i < NUM_THREADS; i++ ) {
- thread[i] = CreateThread ( NULL, 0, do_getservbyname, &starttest, 0, &thread_id[i] );
- }
-
- /* signal threads to start */
- SetEvent ( starttest );
-
- for ( i = 0; i < NUM_THREADS; i++) {
- WaitForSingleObject ( thread[i], TEST_TIMEOUT * 1000 );
- }
-}
-
static void test_WSASocket(void)
{
SOCKET sock = INVALID_SOCKET;
@@ -11374,7 +11309,6 @@ START_TEST( sock )
test_UDP();
- test_getservbyname();
test_WSASocket();
test_WSADuplicateSocket();
test_WSAEnumNetworkEvents();
--
2.27.0
1
0
Aug. 1, 2020
Fixes: 8725564f68332c9129ca701de9b85799a00ddebf
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/quartz/tests/videorenderer.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index 9e6a618a36e..c2b6271021a 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -2733,6 +2733,7 @@ static void test_basic_video(void)
vih.bmiHeader.biWidth = 16;
vih.bmiHeader.biHeight = 16;
+ vih.bmiHeader.biSizeImage = 0;
hr = IFilterGraph2_ConnectDirect(graph, &source.source.pin.IPin_iface, pin, &req_mt);
ok(hr == S_OK, "Got hr %#x.\n", hr);
--
2.27.0
1
0
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/dxva2/Makefile.in | 3 +-
dlls/dxva2/dxva2.spec | 1 +
dlls/dxva2/dxvahd.c | 465 ++++++++++++++++++++++++++++++++++
dlls/dxva2/tests/Makefile.in | 3 +-
dlls/dxva2/tests/dxvahd.c | 293 ++++++++++++++++++++++
include/Makefile.in | 1 +
include/dxvahd.idl | 473 +++++++++++++++++++++++++++++++++++
7 files changed, 1237 insertions(+), 2 deletions(-)
create mode 100644 dlls/dxva2/dxvahd.c
create mode 100644 dlls/dxva2/tests/dxvahd.c
create mode 100644 include/dxvahd.idl
diff --git a/dlls/dxva2/Makefile.in b/dlls/dxva2/Makefile.in
index e3fc2fd6c3a..0248c7f20b0 100644
--- a/dlls/dxva2/Makefile.in
+++ b/dlls/dxva2/Makefile.in
@@ -5,4 +5,5 @@ IMPORTLIB = dxva2
EXTRADLLFLAGS = -mno-cygwin
C_SRCS = \
- main.c
+ main.c \
+ dxvahd.c
diff --git a/dlls/dxva2/dxva2.spec b/dlls/dxva2/dxva2.spec
index 024a972697d..ea7a98718b0 100644
--- a/dlls/dxva2/dxva2.spec
+++ b/dlls/dxva2/dxva2.spec
@@ -1,6 +1,7 @@
@ stdcall CapabilitiesRequestAndCapabilitiesReply(ptr ptr long)
@ stdcall DXVA2CreateDirect3DDeviceManager9(ptr ptr)
@ stdcall DXVA2CreateVideoService(ptr ptr ptr)
+@ stdcall DXVAHD_CreateDevice(ptr ptr long ptr ptr)
@ stdcall DegaussMonitor(ptr)
@ stdcall DestroyPhysicalMonitor(ptr)
@ stdcall DestroyPhysicalMonitors(long ptr)
diff --git a/dlls/dxva2/dxvahd.c b/dlls/dxva2/dxvahd.c
new file mode 100644
index 00000000000..7c197b9a2f8
--- /dev/null
+++ b/dlls/dxva2/dxvahd.c
@@ -0,0 +1,465 @@
+#define COBJMACROS
+
+#include "d3d9.h"
+#include "initguid.h"
+#include "dxvahd.h"
+
+#include "wine/debug.h"
+#include "wine/heap.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dxva2);
+
+
+static const D3DFORMAT output_formats[] = {
+ D3DFMT_R8G8B8
+};
+
+static const D3DFORMAT input_formats[] = {
+ MAKEFOURCC('N','V','1','2')
+};
+
+static const DXVAHD_VPCAPS video_processors[] = {
+ {{0x00000000,0x0000,0x0000,{0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00}}, 0, 0, 0, 0, 0}
+};
+
+static const DXVAHD_VPDEVCAPS dev_caps = {
+ DXVAHD_DEVICE_TYPE_HARDWARE,
+ 0, /* DeviceCaps */
+ 0, /* FeatureCaps */
+ 0, /* FilterCaps */
+ 0, /* InputFormatCaps */
+ D3DPOOL_DEFAULT,
+ ARRAY_SIZE(output_formats),
+ ARRAY_SIZE(input_formats),
+ ARRAY_SIZE(video_processors),
+ 1, /* MaxInputStreams */
+ 1 /* MaxStreamStates */
+};
+
+
+struct dxvahd_device
+{
+ IDXVAHD_Device IDXVAHD_Device_iface;
+ LONG refcount;
+ IDirect3DDevice9Ex *d3d_device;
+};
+
+struct dxvahd_vp
+{
+ IDXVAHD_VideoProcessor IDXVAHD_VideoProcessor_iface;
+ LONG refcount;
+ GUID guid;
+};
+
+
+/********************************************
+ * Utility functions
+ */
+
+static struct dxvahd_device *impl_from_IDXVAHD_Device(IDXVAHD_Device *iface)
+{
+ return CONTAINING_RECORD(iface, struct dxvahd_device, IDXVAHD_Device_iface);
+}
+
+static struct dxvahd_vp *impl_from_IDXVAHD_VideoProcessor(IDXVAHD_VideoProcessor *iface)
+{
+ return CONTAINING_RECORD(iface, struct dxvahd_vp, IDXVAHD_VideoProcessor_iface);
+}
+
+static const char *debug_dxvahd_bltstate(DXVAHD_BLT_STATE blt_state)
+{
+ switch (blt_state)
+ {
+#define STATE_TO_STR(e) case e: return #e
+ STATE_TO_STR(DXVAHD_BLT_STATE_TARGET_RECT);
+ STATE_TO_STR(DXVAHD_BLT_STATE_BACKGROUND_COLOR);
+ STATE_TO_STR(DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE);
+ STATE_TO_STR(DXVAHD_BLT_STATE_ALPHA_FILL);
+ STATE_TO_STR(DXVAHD_BLT_STATE_CONSTRICTION);
+ STATE_TO_STR(DXVAHD_BLT_STATE_PRIVATE);
+#undef STATE_TO_STR
+ default:
+ FIXME("Unrecognized blt state %#x.\n", blt_state);
+ return "unrecognized";
+ }
+}
+
+static const char *debug_dxvahd_streamstate(DXVAHD_STREAM_STATE stream_state)
+{
+ switch (stream_state)
+ {
+#define STATE_TO_STR(e) case e: return #e
+ STATE_TO_STR(DXVAHD_STREAM_STATE_D3DFORMAT);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_FRAME_FORMAT);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_OUTPUT_RATE);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_SOURCE_RECT);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_DESTINATION_RECT);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_ALPHA);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_PALETTE);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_LUMA_KEY);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_ASPECT_RATIO);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_BRIGHTNESS);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_CONTRAST);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_HUE);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_SATURATION);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_NOISE_REDUCTION);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_EDGE_ENHANCEMENT);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_FILTER_ANAMORPHIC_SCALING);
+ STATE_TO_STR(DXVAHD_STREAM_STATE_PRIVATE);
+#undef STATE_TO_STR
+ default:
+ FIXME("Unrecognized stream state %#x.\n", stream_state);
+ return "unrecognized";
+ }
+}
+
+static const char *debug_dxvahd_surface_type(DXVAHD_SURFACE_TYPE surface_type)
+{
+ switch (surface_type)
+ {
+#define SURFACE_TYPE_TO_STR(e) case e: return #e
+ SURFACE_TYPE_TO_STR(DXVAHD_SURFACE_TYPE_VIDEO_INPUT);
+ SURFACE_TYPE_TO_STR(DXVAHD_SURFACE_TYPE_VIDEO_INPUT_PRIVATE);
+ SURFACE_TYPE_TO_STR(DXVAHD_SURFACE_TYPE_VIDEO_OUTPUT);
+#undef SURFACE_TYPE_TO_STR
+ default:
+ FIXME("Unrecognized surface type %#x.\n", surface_type);
+ return "unrecognized";
+ }
+}
+
+static const char *debug_dxvahd_filter(DXVAHD_FILTER filter)
+{
+ switch (filter)
+ {
+#define FILTER_TO_STR(e) case e: return #e
+ FILTER_TO_STR(DXVAHD_FILTER_BRIGHTNESS);
+ FILTER_TO_STR(DXVAHD_FILTER_CONTRAST);
+ FILTER_TO_STR(DXVAHD_FILTER_HUE);
+ FILTER_TO_STR(DXVAHD_FILTER_SATURATION);
+ FILTER_TO_STR(DXVAHD_FILTER_NOISE_REDUCTION);
+ FILTER_TO_STR(DXVAHD_FILTER_EDGE_ENHANCEMENT);
+ FILTER_TO_STR(DXVAHD_FILTER_ANAMORPHIC_SCALING);
+#undef FILTER_TO_STR
+ default:
+ FIXME("Unrecognized surface type %#x.\n", filter);
+ return "unrecognized";
+ }
+}
+
+static const char *debug_dxvahd_device_usage(DXVAHD_DEVICE_USAGE usage)
+{
+ switch (usage)
+ {
+#define USAGE_TO_STR(e) case e: return #e
+ USAGE_TO_STR(DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL);
+ USAGE_TO_STR(DXVAHD_DEVICE_USAGE_OPTIMAL_SPEED);
+ USAGE_TO_STR(DXVAHD_DEVICE_USAGE_OPTIMAL_QUALITY);
+#undef USAGE_TO_STR
+ default:
+ FIXME("Unrecognized device usage %#x.\n", usage);
+ return "unrecognized";
+ }
+}
+
+
+/********************************************
+ * IDXVAHD_VideoProcessor functions
+ */
+
+static HRESULT WINAPI dxvahd_vp_QueryInterface(IDXVAHD_VideoProcessor *iface, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+ WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+ *obj = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI dxvahd_vp_AddRef(IDXVAHD_VideoProcessor *iface)
+{
+ struct dxvahd_vp *processor = impl_from_IDXVAHD_VideoProcessor(iface);
+ ULONG refcount = InterlockedIncrement(&processor->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI dxvahd_vp_Release(IDXVAHD_VideoProcessor *iface)
+{
+ struct dxvahd_vp *processor = impl_from_IDXVAHD_VideoProcessor(iface);
+ ULONG refcount = InterlockedDecrement(&processor->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ heap_free(processor);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI dxvahd_vp_SetVideoProcessBltState(IDXVAHD_VideoProcessor *iface,
+ DXVAHD_BLT_STATE State, UINT DataSize, const void *pData)
+{
+ FIXME("%p, %s, %u, %p.\n", iface, debug_dxvahd_bltstate(State), DataSize, pData);
+ return S_OK;
+}
+
+static HRESULT WINAPI dxvahd_vp_GetVideoProcessBltState(IDXVAHD_VideoProcessor *iface,
+ DXVAHD_BLT_STATE State, UINT DataSize, void *pData)
+{
+ FIXME("%p, %s, %u, %p.\n", iface, debug_dxvahd_bltstate(State), DataSize, pData);
+ return S_OK;
+}
+
+static HRESULT WINAPI dxvahd_vp_SetVideoProcessStreamState(IDXVAHD_VideoProcessor *iface,
+ UINT StreamNumber, DXVAHD_STREAM_STATE State, UINT DataSize, const void *pData)
+{
+ FIXME("%p, %u, %s, %u, %p.\n", iface, StreamNumber, debug_dxvahd_streamstate(State), DataSize, pData);
+ return S_OK;
+}
+
+static HRESULT WINAPI dxvahd_vp_GetVideoProcessStreamState(IDXVAHD_VideoProcessor *iface,
+ UINT StreamNumber, DXVAHD_STREAM_STATE State, UINT DataSize, void *pData)
+{
+ FIXME("%p, %u, %s, %u, %p.\n", iface, StreamNumber, debug_dxvahd_streamstate(State), DataSize, pData);
+ return S_OK;
+}
+
+static HRESULT WINAPI dxvahd_vp_VideoProcessBltHD(IDXVAHD_VideoProcessor *iface,
+ IDirect3DSurface9 *pOutputSurface, UINT OutputFrame, UINT StreamCount,
+ const DXVAHD_STREAM_DATA *pStreams)
+{
+ UINT i;
+
+ FIXME("%p, %p, %u, %u, %p.\n", iface, pOutputSurface, OutputFrame, StreamCount, pStreams);
+
+ for (i = 0; i < StreamCount; i++)
+ {
+ TRACE("stream[%d]: %d %u %u %u %u %p %p %p\n", i, pStreams[i].Enable, pStreams[i].OutputIndex,
+ pStreams[i].InputFrameOrField, pStreams[i].PastFrames, pStreams[i].FutureFrames,
+ pStreams[i].ppPastSurfaces, pStreams[i].pInputSurface, pStreams[i].ppFutureSurfaces);
+ }
+
+ return S_OK;
+}
+
+static const IDXVAHD_VideoProcessorVtbl dxvahd_vp_vtbl =
+{
+ dxvahd_vp_QueryInterface,
+ dxvahd_vp_AddRef,
+ dxvahd_vp_Release,
+ dxvahd_vp_SetVideoProcessBltState,
+ dxvahd_vp_GetVideoProcessBltState,
+ dxvahd_vp_SetVideoProcessStreamState,
+ dxvahd_vp_GetVideoProcessStreamState,
+ dxvahd_vp_VideoProcessBltHD,
+};
+
+
+/********************************************
+ * IDXVAHD_Device functions
+ */
+
+static HRESULT WINAPI dxvahd_device_QueryInterface(IDXVAHD_Device *iface, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+ WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+ *obj = NULL;
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI dxvahd_device_AddRef(IDXVAHD_Device *iface)
+{
+ struct dxvahd_device *dev = impl_from_IDXVAHD_Device(iface);
+ ULONG refcount = InterlockedIncrement(&dev->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI dxvahd_device_Release(IDXVAHD_Device *iface)
+{
+ struct dxvahd_device *dev = impl_from_IDXVAHD_Device(iface);
+ ULONG refcount = InterlockedDecrement(&dev->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ heap_free(dev);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI dxvahd_device_CreateVideoSurface(IDXVAHD_Device *iface, UINT width, UINT height,
+ D3DFORMAT format, D3DPOOL pool, DWORD usage, DXVAHD_SURFACE_TYPE type, UINT num_surfaces,
+ IDirect3DSurface9 **ppSurface, HANDLE *pSharedHandle)
+{
+ struct dxvahd_device *dev = impl_from_IDXVAHD_Device(iface);
+ UINT i;
+
+ FIXME("%p, %u, %u, %#x, %#x, %#x, %s, %u, %p, %p.\n", iface, width, height, format, pool, usage,
+ debug_dxvahd_surface_type(type), num_surfaces, ppSurface, pSharedHandle);
+
+ if (pool != dev_caps.InputPool || num_surfaces < 1)
+ return E_INVALIDARG;
+
+ // FIXME: Return error result (D3DERR_INVALIDCALL or E_INVALIDARG) on invalid format.
+ // The formats returned by GetVideoProcessor[Input|Output]Formats functions
+ // may not comprise the entire set of valid formats.
+
+ for (i = 0; i < num_surfaces; i++)
+ {
+ // TODO: Determine if CreateOffscreenPlainSurface is sufficient to the task,
+ // or if a separate implementation of IDirect3DSurface9 is warranted.
+ IDirect3DDevice9Ex_CreateOffscreenPlainSurface(dev->d3d_device, width, height, format, pool,
+ ppSurface + i, pSharedHandle);
+ TRACE("Created surface %d: %p.\n", i, ppSurface[i]);
+ }
+
+ return S_OK;
+}
+
+static HRESULT WINAPI dxvahd_device_GetVideoProcessorDeviceCaps(IDXVAHD_Device *iface,
+ DXVAHD_VPDEVCAPS *pCaps)
+{
+ FIXME("%p, %p.\n", iface, pCaps);
+
+ // TODO: use driver D3DDDICAPS_DXVAHD_GETVPDEVCAPS
+
+ memcpy(pCaps, &dev_caps, sizeof(dev_caps));
+
+ return S_OK;
+}
+
+static HRESULT WINAPI dxvahd_device_GetVideoProcessorOutputFormats(IDXVAHD_Device *iface, UINT count,
+ D3DFORMAT *pFormats)
+{
+ FIXME("%p, %u, %p.\n", iface, count, pFormats);
+
+ // TODO: use driver D3DDDICAPS_DXVAHD_GETVPOUTPUTFORMATS
+
+ if (count != dev_caps.OutputFormatCount)
+ return E_INVALIDARG;
+ memcpy(pFormats, output_formats, sizeof(output_formats));
+
+ return S_OK;
+}
+
+static HRESULT WINAPI dxvahd_device_GetVideoProcessorInputFormats(IDXVAHD_Device *iface, UINT count,
+ D3DFORMAT *pFormats)
+{
+ FIXME("%p, %u, %p.\n", iface, count, pFormats);
+
+ // TODO: use driver D3DDDICAPS_DXVAHD_GETVPINPUTFORMATS
+
+ if (count != dev_caps.InputFormatCount)
+ return E_INVALIDARG;
+ memcpy(pFormats, input_formats, sizeof(input_formats));
+
+ return S_OK;
+}
+
+static HRESULT WINAPI dxvahd_device_GetVideoProcessorCaps(IDXVAHD_Device *iface, UINT count,
+ DXVAHD_VPCAPS *pCaps)
+{
+ FIXME("%p, %u, %p.\n", iface, count, pCaps);
+
+ // TODO: use driver D3DDDICAPS_DXVAHD_GETVPCAPS
+
+ if (count != dev_caps.VideoProcessorCount)
+ return E_INVALIDARG;
+ memcpy(pCaps, video_processors, sizeof(video_processors));
+
+ return S_OK;
+}
+
+static HRESULT WINAPI dxvahd_device_GetVideoProcessorCustomRates(IDXVAHD_Device *iface,
+ const GUID *pVPGuid, UINT count, DXVAHD_CUSTOM_RATE_DATA *pRates)
+{
+ FIXME("%p, %s, %u, %p.\n", iface, debugstr_guid(pVPGuid), count, pRates);
+
+ // TODO: use driver D3DDDICAPS_DXVAHD_GETVPCUSTOMRATES
+
+ return (!!count) ? E_INVALIDARG : S_OK;
+}
+
+static HRESULT WINAPI dxvahd_device_GetVideoProcessorFilterRange(IDXVAHD_Device *iface,
+ DXVAHD_FILTER filter, DXVAHD_FILTER_RANGE_DATA *pRange)
+{
+ FIXME("%p, %s, %p.\n", iface, debug_dxvahd_filter(filter), pRange);
+
+ // TODO: use driver D3DDDICAPS_DXVAHD_GETVPFILTERRANGE
+
+ return E_INVALIDARG;
+}
+
+static HRESULT WINAPI dxvahd_device_CreateVideoProcessor(IDXVAHD_Device *iface, const GUID *pVPGuid,
+ IDXVAHD_VideoProcessor **ppVideoProcessor)
+{
+ struct dxvahd_vp *object;
+
+ FIXME("%p, %s, %p.\n", iface, debugstr_guid(pVPGuid), ppVideoProcessor);
+
+ // TODO: use driver function CreateVideoProcessor
+
+ if (!(object = heap_alloc_zero(sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ object->IDXVAHD_VideoProcessor_iface.lpVtbl = &dxvahd_vp_vtbl;
+ object->refcount = 1;
+ memcpy(&object->guid, pVPGuid, sizeof(*pVPGuid));
+
+ *ppVideoProcessor = &object->IDXVAHD_VideoProcessor_iface;
+
+ return S_OK;
+}
+
+static const IDXVAHD_DeviceVtbl dxvahd_device_vtbl =
+{
+ dxvahd_device_QueryInterface,
+ dxvahd_device_AddRef,
+ dxvahd_device_Release,
+ dxvahd_device_CreateVideoSurface,
+ dxvahd_device_GetVideoProcessorDeviceCaps,
+ dxvahd_device_GetVideoProcessorOutputFormats,
+ dxvahd_device_GetVideoProcessorInputFormats,
+ dxvahd_device_GetVideoProcessorCaps,
+ dxvahd_device_GetVideoProcessorCustomRates,
+ dxvahd_device_GetVideoProcessorFilterRange,
+ dxvahd_device_CreateVideoProcessor,
+};
+
+
+HRESULT WINAPI DXVAHD_CreateDevice(IDirect3DDevice9Ex *d3d_device, const DXVAHD_CONTENT_DESC *desc,
+ DXVAHD_DEVICE_USAGE usage, PDXVAHDSW_Plugin plugin, IDXVAHD_Device **device)
+{
+ struct dxvahd_device *object;
+
+ TRACE("%p, %p, %s, %p, %p.\n", d3d_device, desc, debug_dxvahd_device_usage(usage), plugin, device);
+
+ TRACE("Frame Format %d Input %ux%u @%.2f Output %ux%u @%.2f\n",
+ desc->InputFrameFormat, desc->InputWidth, desc->InputHeight,
+ (double)desc->InputFrameRate.Numerator / desc->InputFrameRate.Denominator,
+ desc->OutputWidth, desc->OutputHeight,
+ (double)desc->OutputFrameRate.Numerator / desc->OutputFrameRate.Denominator);
+
+ if (!(object = heap_alloc_zero(sizeof(*object))))
+ return E_OUTOFMEMORY;
+
+ object->IDXVAHD_Device_iface.lpVtbl = &dxvahd_device_vtbl;
+ object->refcount = 1;
+ object->d3d_device = d3d_device;
+
+ *device = &object->IDXVAHD_Device_iface;
+
+ return S_OK;
+}
diff --git a/dlls/dxva2/tests/Makefile.in b/dlls/dxva2/tests/Makefile.in
index c86c5ab42fc..b5d70cd94f7 100644
--- a/dlls/dxva2/tests/Makefile.in
+++ b/dlls/dxva2/tests/Makefile.in
@@ -2,4 +2,5 @@ TESTDLL = dxva2.dll
IMPORTS = dxva2 user32 d3d9
C_SRCS = \
- dxva2.c
+ dxva2.c \
+ dxvahd.c
diff --git a/dlls/dxva2/tests/dxvahd.c b/dlls/dxva2/tests/dxvahd.c
new file mode 100644
index 00000000000..e67350dfdb7
--- /dev/null
+++ b/dlls/dxva2/tests/dxvahd.c
@@ -0,0 +1,293 @@
+/*
+ * Copyright 2020 Jeff Smith
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#define COBJMACROS
+#include "initguid.h"
+#include "d3d9.h"
+#include "dxvahd.h"
+
+#include "wine/test.h"
+#include "wine/heap.h"
+
+IDirect3DDevice9Ex *d3d_device;
+
+static HWND create_window(void)
+{
+ RECT r = {0, 0, 640, 480};
+
+ AdjustWindowRect(&r, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
+
+ return CreateWindowA("static", "d3d9_test", WS_OVERLAPPEDWINDOW | WS_VISIBLE,
+ 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL);
+}
+
+static IDirect3DDevice9Ex *create_device(IDirect3D9Ex *d3d9, HWND focus_window)
+{
+ D3DPRESENT_PARAMETERS present_parameters = {0};
+ IDirect3DDevice9Ex *device = NULL;
+
+ present_parameters.BackBufferWidth = 640;
+ present_parameters.BackBufferHeight = 480;
+ present_parameters.BackBufferFormat = D3DFMT_A8R8G8B8;
+ present_parameters.SwapEffect = D3DSWAPEFFECT_DISCARD;
+ present_parameters.hDeviceWindow = focus_window;
+ present_parameters.Windowed = TRUE;
+ present_parameters.EnableAutoDepthStencil = TRUE;
+ present_parameters.AutoDepthStencilFormat = D3DFMT_D24S8;
+
+ IDirect3D9Ex_CreateDeviceEx(d3d9, D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, focus_window,
+ D3DCREATE_HARDWARE_VERTEXPROCESSING, &present_parameters, NULL, &device);
+
+ return device;
+}
+
+static void init_desc(DXVAHD_CONTENT_DESC *desc)
+{
+ desc->InputFrameFormat = DXVAHD_FRAME_FORMAT_PROGRESSIVE;
+ desc->InputFrameRate.Numerator = 30;
+ desc->InputFrameRate.Denominator = 1;
+ desc->InputWidth = 640;
+ desc->InputHeight = 480;
+ desc->OutputFrameRate.Numerator = 30;
+ desc->OutputFrameRate.Denominator = 1;
+ desc->OutputWidth = 640;
+ desc->OutputHeight = 480;
+}
+
+static void test_dxvahd_device(void)
+{
+ IDXVAHD_Device *device, *device2;
+ IDirect3DSurface9 *surfaces[2];
+ HRESULT hr;
+ DXVAHD_CONTENT_DESC desc = {0};
+ DXVAHD_VPDEVCAPS caps = {0};
+ D3DFORMAT *input_formats;
+ D3DFORMAT *output_formats;
+ DXVAHD_VPCAPS *vp_caps;
+ int i;
+
+ init_desc(&desc);
+ hr = DXVAHD_CreateDevice(d3d_device, &desc, DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &device);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ ok(!!device, "Failed to create DXVA-HD device.\n");
+
+ hr = IDXVAHD_Device_QueryInterface(device, &IID_IDXVAHD_Device, (void **)&device2);
+ ok(hr == E_NOINTERFACE, "IDXVAHD_Device::QueryInterface for IID_IDXVAHD_Device returned %08x, expected E_NOINTERFACE\n", hr);
+ ok(device2 == NULL, "QueryInterface returned interface %p, expected NULL\n", device2);
+
+ hr = IDXVAHD_Device_QueryInterface(device, &IID_IUnknown, (void **)&device2);
+ ok(hr == E_NOINTERFACE, "IDXVAHD_Device::QueryInterface for IID_IUnknown returned %08x, expected E_NOINTERFACE\n", hr);
+ ok(device2 == NULL, "QueryInterface returned interface %p, expected NULL\n", device2);
+
+
+ hr = IDXVAHD_Device_GetVideoProcessorDeviceCaps(device, &caps);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ output_formats = heap_alloc_zero(caps.OutputFormatCount * sizeof(*output_formats));
+ hr = IDXVAHD_Device_GetVideoProcessorOutputFormats(device, caps.OutputFormatCount, output_formats);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IDXVAHD_Device_GetVideoProcessorOutputFormats(device, caps.OutputFormatCount + 1, output_formats);
+ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ if (caps.OutputFormatCount >= 1)
+ {
+ hr = IDXVAHD_Device_GetVideoProcessorOutputFormats(device, caps.OutputFormatCount - 1, output_formats);
+ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ }
+
+ input_formats = heap_alloc_zero(caps.InputFormatCount * sizeof(*input_formats));
+ hr = IDXVAHD_Device_GetVideoProcessorInputFormats(device, caps.InputFormatCount, input_formats);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IDXVAHD_Device_GetVideoProcessorInputFormats(device, caps.InputFormatCount + 1, input_formats);
+ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ if (caps.InputFormatCount >= 1)
+ {
+ hr = IDXVAHD_Device_GetVideoProcessorInputFormats(device, caps.InputFormatCount - 1, input_formats);
+ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ }
+
+ vp_caps = heap_alloc_zero(caps.VideoProcessorCount * sizeof(*vp_caps));
+ hr = IDXVAHD_Device_GetVideoProcessorCaps(device, caps.VideoProcessorCount, vp_caps);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+ hr = IDXVAHD_Device_GetVideoProcessorCaps(device, caps.VideoProcessorCount + 1, vp_caps);
+ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ if (caps.VideoProcessorCount >= 1)
+ {
+ hr = IDXVAHD_Device_GetVideoProcessorCaps(device, caps.VideoProcessorCount - 1, vp_caps);
+ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ }
+
+
+ /* CreateVideoSurface: Try each input format */
+ for (i = 0; i < caps.InputFormatCount; i++)
+ {
+ hr = IDXVAHD_Device_CreateVideoSurface(device, 2, 2, input_formats[i], caps.InputPool, 0,
+ DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 1, surfaces, NULL);
+ ok(hr == S_OK, "Unexpected hr %#x for input format %#x.\n", hr, input_formats[i]);
+ IDirect3DSurface9_Release(surfaces[0]);
+ }
+
+ /* NOTE: some video surface formats besides those returned by
+ * GetVideoProcessor[Input|Output]Formats may be allowed by CreateVideoSurface. */
+
+ /* CreateVideoSurface: Invalid input format */
+ hr = IDXVAHD_Device_CreateVideoSurface(device, 2, 2, 0xdeadbeef, caps.InputPool, 0,
+ DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 1, surfaces, NULL);
+ todo_wine ok(hr == D3DERR_INVALIDCALL, "Unexpected hr %#x for input format %#x.\n", hr, 0xdeadbeef);
+
+ if (caps.InputFormatCount >= 1)
+ {
+ /* CreateVideoSurface: Request 0 surfaces */
+ hr = IDXVAHD_Device_CreateVideoSurface(device, 2, 2, input_formats[0], caps.InputPool, 0,
+ DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 0, surfaces, NULL);
+ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ /* CreateVideoSurface: Wrong pool */
+ hr = IDXVAHD_Device_CreateVideoSurface(device, 2, 2, input_formats[0], caps.InputPool + 1, 0,
+ DXVAHD_SURFACE_TYPE_VIDEO_INPUT, 1, surfaces, NULL);
+ ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ }
+
+
+ heap_free(output_formats);
+ heap_free(input_formats);
+ heap_free(vp_caps);
+ IDXVAHD_Device_Release(device);
+}
+
+static void test_dxvahd_processor(void)
+{
+ IDXVAHD_Device *device;
+ DXVAHD_CONTENT_DESC desc = {0};
+ DXVAHD_VPDEVCAPS caps = {0};
+ D3DFORMAT *input_formats;
+ DXVAHD_VPCAPS *vp_caps;
+ IDXVAHD_VideoProcessor *processor;
+ void *data = heap_alloc_zero(64);
+ HRESULT hr;
+ int i;
+
+ static struct {
+ DXVAHD_BLT_STATE state;
+ ULONG size;
+ } test_blt[] = {
+ {DXVAHD_BLT_STATE_TARGET_RECT, sizeof(DXVAHD_BLT_STATE_TARGET_RECT_DATA)},
+ {DXVAHD_BLT_STATE_BACKGROUND_COLOR, sizeof(DXVAHD_BLT_STATE_BACKGROUND_COLOR_DATA)},
+ {DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE, sizeof(DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA)},
+ {DXVAHD_BLT_STATE_ALPHA_FILL, sizeof(DXVAHD_BLT_STATE_ALPHA_FILL_DATA)},
+ {DXVAHD_BLT_STATE_CONSTRICTION, sizeof(DXVAHD_BLT_STATE_CONSTRICTION_DATA)},
+ };
+
+ static struct {
+ DXVAHD_STREAM_STATE state;
+ ULONG size;
+ } test_stream[] = {
+ {DXVAHD_STREAM_STATE_D3DFORMAT, sizeof(DXVAHD_STREAM_STATE_D3DFORMAT_DATA)},
+ {DXVAHD_STREAM_STATE_FRAME_FORMAT, sizeof(DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA)},
+ {DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE, sizeof(DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA)},
+ {DXVAHD_STREAM_STATE_OUTPUT_RATE, sizeof(DXVAHD_STREAM_STATE_OUTPUT_RATE_DATA)},
+ {DXVAHD_STREAM_STATE_SOURCE_RECT, sizeof(DXVAHD_STREAM_STATE_SOURCE_RECT_DATA)},
+ {DXVAHD_STREAM_STATE_DESTINATION_RECT, sizeof(DXVAHD_STREAM_STATE_DESTINATION_RECT_DATA)},
+ {DXVAHD_STREAM_STATE_ALPHA, sizeof(DXVAHD_STREAM_STATE_ALPHA_DATA)},
+ {DXVAHD_STREAM_STATE_PALETTE, sizeof(DXVAHD_STREAM_STATE_PALETTE_DATA)},
+ {DXVAHD_STREAM_STATE_LUMA_KEY, sizeof(DXVAHD_STREAM_STATE_LUMA_KEY_DATA)},
+ {DXVAHD_STREAM_STATE_ASPECT_RATIO, sizeof(DXVAHD_STREAM_STATE_ASPECT_RATIO_DATA)},
+ {DXVAHD_STREAM_STATE_FILTER_BRIGHTNESS, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)},
+ {DXVAHD_STREAM_STATE_FILTER_CONTRAST, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)},
+ {DXVAHD_STREAM_STATE_FILTER_HUE, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)},
+ {DXVAHD_STREAM_STATE_FILTER_SATURATION, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)},
+ {DXVAHD_STREAM_STATE_FILTER_NOISE_REDUCTION, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)},
+ {DXVAHD_STREAM_STATE_FILTER_EDGE_ENHANCEMENT, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)},
+ {DXVAHD_STREAM_STATE_FILTER_ANAMORPHIC_SCALING, sizeof(DXVAHD_STREAM_STATE_FILTER_DATA)},
+ };
+
+ init_desc(&desc);
+ DXVAHD_CreateDevice(d3d_device, &desc, DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &device);
+ IDXVAHD_Device_GetVideoProcessorDeviceCaps(device, &caps);
+ input_formats = heap_alloc_zero(caps.InputFormatCount * sizeof(*input_formats));
+ vp_caps = heap_alloc_zero(caps.VideoProcessorCount * sizeof(*vp_caps));
+ IDXVAHD_Device_GetVideoProcessorCaps(device, caps.VideoProcessorCount, vp_caps);
+
+ hr = IDXVAHD_Device_CreateVideoProcessor(device, &vp_caps[0].VPGuid, &processor);
+ ok(hr == S_OK, "Unexpected hr %#x.\n", hr);
+
+ for (i = 0; i < ARRAY_SIZE(test_blt); i++)
+ {
+ hr = IDXVAHD_VideoProcessor_GetVideoProcessBltState(processor, test_blt[i].state, test_blt[i].size, data);
+ ok(hr == S_OK, "Unexpected hr %#x for blt state %#x.\n", hr, test_blt[i].state);
+ /* Pass wrong data size for state */
+ hr = IDXVAHD_VideoProcessor_GetVideoProcessBltState(processor, test_blt[i].state, 64, data);
+ todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#x for blt state %#x.\n", hr, test_blt[i].state);
+ }
+
+ for (i = 0; i < ARRAY_SIZE(test_stream); i++)
+ {
+ hr = IDXVAHD_VideoProcessor_GetVideoProcessStreamState(processor, 0, test_stream[i].state, test_stream[i].size, data);
+ ok(hr == S_OK, "Unexpected hr %#x for stream state %#x.\n", hr, test_stream[i].state);
+ /* Pass wrong data size for state */
+ hr = IDXVAHD_VideoProcessor_GetVideoProcessStreamState(processor, 0, test_stream[i].state, 64, data);
+ todo_wine ok(hr == E_INVALIDARG, "Unexpected hr %#x for stream state %#x.\n", hr, test_stream[i].state);
+ }
+
+ IDXVAHD_VideoProcessor_Release(processor);
+
+ heap_free(data);
+ heap_free(input_formats);
+ heap_free(vp_caps);
+ IDXVAHD_Device_Release(device);
+}
+
+START_TEST(dxvahd)
+{
+ IDXVAHD_Device *device = NULL;
+ IDirect3D9Ex *d3d;
+ HWND window;
+ HRESULT hr;
+ DXVAHD_CONTENT_DESC desc = {0};
+
+ hr = Direct3DCreate9Ex(D3D_SDK_VERSION, &d3d);
+ if (hr != S_OK)
+ {
+ skip("Failed to create a D3D object, skipping tests.\n");
+ return;
+ }
+
+ window = create_window();
+
+ if (!(d3d_device = create_device(d3d, window)))
+ {
+ skip("Failed to create a D3D device, skipping tests.\n");
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+ }
+
+ init_desc(&desc);
+ hr = DXVAHD_CreateDevice(d3d_device, &desc, DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL, NULL, &device);
+ if (hr == E_NOINTERFACE)
+ {
+ skip("Device does not support DXVA-HD, skipping tests.\n");
+ goto done;
+ }
+ IDXVAHD_Device_Release(device);
+
+ test_dxvahd_device();
+ test_dxvahd_processor();
+
+done:
+ IDirect3DDevice9_Release(d3d_device);
+ IDirect3D9_Release(d3d);
+ DestroyWindow(window);
+}
diff --git a/include/Makefile.in b/include/Makefile.in
index 216adf0d7ae..f986ef42dd5 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -268,6 +268,7 @@ SOURCES = \
dxgitype.idl \
dxva.h \
dxva2api.idl \
+ dxvahd.idl \
dyngraph.idl \
endpointvolume.idl \
errorrep.h \
diff --git a/include/dxvahd.idl b/include/dxvahd.idl
new file mode 100644
index 00000000000..b6ed6b3217c
--- /dev/null
+++ b/include/dxvahd.idl
@@ -0,0 +1,473 @@
+/*
+ * Copyright 2020 Jeff Smith
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+import "unknwn.idl";
+
+cpp_quote("#if 0")
+interface IDirect3DDevice9Ex;
+interface IDirect3DSurface9;
+
+typedef DWORD D3DFORMAT;
+typedef DWORD D3DPOOL;
+typedef DWORD D3DCOLOR;
+cpp_quote("#endif")
+
+
+typedef enum _DXVAHD_FRAME_FORMAT
+{
+ DXVAHD_FRAME_FORMAT_PROGRESSIVE = 0,
+ DXVAHD_FRAME_FORMAT_INTERLACED_TOP_FIELD_FIRST = 1,
+ DXVAHD_FRAME_FORMAT_INTERLACED_BOTTOM_FIELD_FIRST = 2
+} DXVAHD_FRAME_FORMAT;
+
+typedef enum _DXVAHD_DEVICE_USAGE
+{
+ DXVAHD_DEVICE_USAGE_PLAYBACK_NORMAL = 0,
+ DXVAHD_DEVICE_USAGE_OPTIMAL_SPEED = 1,
+ DXVAHD_DEVICE_USAGE_OPTIMAL_QUALITY = 2
+} DXVAHD_DEVICE_USAGE;
+
+typedef enum _DXVAHD_FILTER
+{
+ DXVAHD_FILTER_BRIGHTNESS = 0,
+ DXVAHD_FILTER_CONTRAST = 1,
+ DXVAHD_FILTER_HUE = 2,
+ DXVAHD_FILTER_SATURATION = 3,
+ DXVAHD_FILTER_NOISE_REDUCTION = 4,
+ DXVAHD_FILTER_EDGE_ENHANCEMENT = 5,
+ DXVAHD_FILTER_ANAMORPHIC_SCALING = 6
+} DXVAHD_FILTER;
+
+typedef enum _DXVAHD_SURFACE_TYPE
+{
+ DXVAHD_SURFACE_TYPE_VIDEO_INPUT = 0,
+ DXVAHD_SURFACE_TYPE_VIDEO_INPUT_PRIVATE = 1,
+ DXVAHD_SURFACE_TYPE_VIDEO_OUTPUT = 2
+} DXVAHD_SURFACE_TYPE;
+
+typedef enum _DXVAHD_BLT_STATE
+{
+ DXVAHD_BLT_STATE_TARGET_RECT = 0,
+ DXVAHD_BLT_STATE_BACKGROUND_COLOR = 1,
+ DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE = 2,
+ DXVAHD_BLT_STATE_ALPHA_FILL = 3,
+ DXVAHD_BLT_STATE_CONSTRICTION = 4,
+ DXVAHD_BLT_STATE_PRIVATE = 1000
+} DXVAHD_BLT_STATE;
+
+typedef enum _DXVAHD_STREAM_STATE
+{
+ DXVAHD_STREAM_STATE_D3DFORMAT = 0,
+ DXVAHD_STREAM_STATE_FRAME_FORMAT = 1,
+ DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE = 2,
+ DXVAHD_STREAM_STATE_OUTPUT_RATE = 3,
+ DXVAHD_STREAM_STATE_SOURCE_RECT = 4,
+ DXVAHD_STREAM_STATE_DESTINATION_RECT = 5,
+ DXVAHD_STREAM_STATE_ALPHA = 6,
+ DXVAHD_STREAM_STATE_PALETTE = 7,
+ DXVAHD_STREAM_STATE_LUMA_KEY = 8,
+ DXVAHD_STREAM_STATE_ASPECT_RATIO = 9,
+ DXVAHD_STREAM_STATE_FILTER_BRIGHTNESS = 100,
+ DXVAHD_STREAM_STATE_FILTER_CONTRAST = 101,
+ DXVAHD_STREAM_STATE_FILTER_HUE = 102,
+ DXVAHD_STREAM_STATE_FILTER_SATURATION = 103,
+ DXVAHD_STREAM_STATE_FILTER_NOISE_REDUCTION = 104,
+ DXVAHD_STREAM_STATE_FILTER_EDGE_ENHANCEMENT = 105,
+ DXVAHD_STREAM_STATE_FILTER_ANAMORPHIC_SCALING = 106,
+ DXVAHD_STREAM_STATE_PRIVATE = 1000
+} DXVAHD_STREAM_STATE;
+
+typedef enum _DXVAHD_DEVICE_TYPE
+{
+ DXVAHD_DEVICE_TYPE_HARDWARE = 0,
+ DXVAHD_DEVICE_TYPE_SOFTWARE = 1,
+ DXVAHD_DEVICE_TYPE_REFERENCE = 2,
+ DXVAHD_DEVICE_TYPE_OTHER = 3
+} DXVAHD_DEVICE_TYPE;
+
+typedef enum _DXVAHD_DEVICE_CAPS
+{
+ DXVAHD_DEVICE_CAPS_LINEAR_SPACE = 0x01,
+ DXVAHD_DEVICE_CAPS_xvYCC = 0x02,
+ DXVAHD_DEVICE_CAPS_RGB_RANGE_CONVERSION = 0x04,
+ DXVAHD_DEVICE_CAPS_YCbCr_MATRIX_CONVERSION = 0x08
+ // Based on DDI, Windows 8.1 should support:
+ // ..._NOMINAL_RANGE = 0x10
+
+} DXVAHD_DEVICE_CAPS;
+
+typedef enum _DXVAHD_FEATURE_CAPS
+{
+ DXVAHD_FEATURE_CAPS_ALPHA_FILL = 0x01,
+ DXVAHD_FEATURE_CAPS_CONSTRICTION = 0x02,
+ DXVAHD_FEATURE_CAPS_LUMA_KEY = 0x04,
+ DXVAHD_FEATURE_CAPS_ALPHA_PALETTE = 0x08
+ // Based on DDI, Windows 8 should support:
+ // ..._ROTATION = 0x10
+} DXVAHD_FEATURE_CAPS;
+
+typedef enum _DXVAHD_FILTER_CAPS
+{
+ DXVAHD_FILTER_CAPS_BRIGHTNESS = 0x01,
+ DXVAHD_FILTER_CAPS_CONTRAST = 0x02,
+ DXVAHD_FILTER_CAPS_HUE = 0x04,
+ DXVAHD_FILTER_CAPS_SATURATION = 0x08,
+ DXVAHD_FILTER_CAPS_NOISE_REDUCTION = 0x10,
+ DXVAHD_FILTER_CAPS_EDGE_ENHANCEMENT = 0x20,
+ DXVAHD_FILTER_CAPS_ANAMORPHIC_SCALING = 0x40
+} DXVAHD_FILTER_CAPS;
+
+typedef enum _DXVAHD_INPUT_FORMAT_CAPS
+{
+ DXVAHD_INPUT_FORMAT_CAPS_RGB_INTERLACED = 0x01,
+ DXVAHD_INPUT_FORMAT_CAPS_RGB_PROCAMP = 0x02,
+ DXVAHD_INPUT_FORMAT_CAPS_RGB_LUMA_KEY = 0x04,
+ DXVAHD_INPUT_FORMAT_CAPS_PALETTE_INTERLACED = 0x08
+} DXVAHD_INPUT_FORMAT_CAPS;
+
+typedef enum _DXVAHD_ALPHA_FILL_MODE
+{
+ DXVAHD_ALPHA_FILL_MODE_OPAQUE = 0,
+ DXVAHD_ALPHA_FILL_MODE_BACKGROUND = 1,
+ DXVAHD_ALPHA_FILL_MODE_DESTINATION = 2,
+ DXVAHD_ALPHA_FILL_MODE_SOURCE_STREAM = 3
+} DXVAHD_ALPHA_FILL_MODE;
+
+typedef enum _DXVAHD_OUTPUT_RATE
+{
+ DXVAHD_OUTPUT_RATE_NORMAL = 0,
+ DXVAHD_OUTPUT_RATE_HALF = 1,
+ DXVAHD_OUTPUT_RATE_CUSTOM = 2
+} DXVAHD_OUTPUT_RATE;
+
+
+typedef struct _DXVAHD_RATIONAL
+{
+ UINT Numerator;
+ UINT Denominator;
+} DXVAHD_RATIONAL;
+
+typedef struct _DXVAHD_CONTENT_DESC
+{
+ DXVAHD_FRAME_FORMAT InputFrameFormat;
+ DXVAHD_RATIONAL InputFrameRate;
+ UINT InputWidth;
+ UINT InputHeight;
+ DXVAHD_RATIONAL OutputFrameRate;
+ UINT OutputWidth;
+ UINT OutputHeight;
+} DXVAHD_CONTENT_DESC;
+
+typedef struct _DXVAHD_VPCAPS
+{
+ GUID VPGuid;
+ UINT PastFrames;
+ UINT FutureFrames;
+ UINT ProcessorCaps;
+ UINT ITelecineCaps;
+ UINT CustomRateCount;
+} DXVAHD_VPCAPS;
+
+typedef struct _DXVAHD_CUSTOM_RATE_DATA
+{
+ DXVAHD_RATIONAL CustomRate;
+ UINT OutputFrames;
+ BOOL InputInterlaced;
+ UINT InputFramesOrFields;
+} DXVAHD_CUSTOM_RATE_DATA;
+
+typedef struct _DXVAHD_FILTER_RANGE_DATA
+{
+ INT Minimum;
+ INT Maximum;
+ INT Default;
+ FLOAT Multiplier;
+} DXVAHD_FILTER_RANGE_DATA;
+
+typedef struct _DXVAHD_VPDEVCAPS
+{
+ DXVAHD_DEVICE_TYPE DeviceType;
+ UINT DeviceCaps;
+ UINT FeatureCaps;
+ UINT FilterCaps;
+ UINT InputFormatCaps;
+ D3DPOOL InputPool;
+ UINT OutputFormatCount;
+ UINT InputFormatCount;
+ UINT VideoProcessorCount;
+ UINT MaxInputStreams;
+ UINT MaxStreamStates;
+} DXVAHD_VPDEVCAPS;
+
+typedef struct _DXVAHD_STREAM_DATA
+{
+ BOOL Enable;
+ UINT OutputIndex;
+ UINT InputFrameOrField;
+ UINT PastFrames;
+ UINT FutureFrames;
+ IDirect3DSurface9 **ppPastSurfaces;
+ IDirect3DSurface9 *pInputSurface;
+ IDirect3DSurface9 **ppFutureSurfaces;
+} DXVAHD_STREAM_DATA;
+
+typedef struct _DXVAHD_BLT_STATE_TARGET_RECT_DATA
+{
+ BOOL Enable;
+ RECT TargetRect;
+} DXVAHD_BLT_STATE_TARGET_RECT_DATA;
+
+typedef struct _DXVAHD_COLOR_RGBA
+{
+ FLOAT R;
+ FLOAT G;
+ FLOAT B;
+ FLOAT A;
+} DXVAHD_COLOR_RGBA;
+
+typedef struct _DXVAHD_COLOR_YCbCrA
+{
+ FLOAT Y;
+ FLOAT Cb;
+ FLOAT Cr;
+ FLOAT A;
+} DXVAHD_COLOR_YCbCrA;
+
+typedef union _DXVAHD_COLOR
+{
+ DXVAHD_COLOR_RGBA RGB;
+ DXVAHD_COLOR_YCbCrA YCbCr;
+} DXVAHD_COLOR;
+
+typedef struct _DXVAHD_BLT_STATE_BACKGROUND_COLOR_DATA
+{
+ BOOL YCbCr;
+ DXVAHD_COLOR BackgroundColor;
+} DXVAHD_BLT_STATE_BACKGROUND_COLOR_DATA;
+
+typedef struct _DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA
+{
+ union
+ {
+ struct
+ {
+ UINT Usage : 1;
+ UINT RGB_Range : 1;
+ UINT YCbCr_Matrix : 1;
+ UINT YCbCr_xvYCC : 1;
+ UINT Reserved : 28;
+ };
+ UINT Value;
+ };
+} DXVAHD_BLT_STATE_OUTPUT_COLOR_SPACE_DATA;
+
+typedef struct _DXVAHD_BLT_STATE_ALPHA_FILL_DATA
+{
+ DXVAHD_ALPHA_FILL_MODE Mode;
+ UINT StreamNumber;
+} DXVAHD_BLT_STATE_ALPHA_FILL_DATA;
+
+typedef struct _DXVAHD_BLT_STATE_CONSTRICTION_DATA
+{
+ BOOL Enable;
+ SIZE Size;
+} DXVAHD_BLT_STATE_CONSTRICTION_DATA;
+
+typedef struct _DXVAHD_BLT_STATE_PRIVATE_DATA
+{
+ GUID Guid;
+ UINT DataSize;
+ void *pData;
+} DXVAHD_BLT_STATE_PRIVATE_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_D3DFORMAT_DATA
+{
+ D3DFORMAT Format;
+} DXVAHD_STREAM_STATE_D3DFORMAT_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA
+{
+ DXVAHD_FRAME_FORMAT FrameFormat;
+} DXVAHD_STREAM_STATE_FRAME_FORMAT_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA
+{
+ union
+ {
+ struct
+ {
+ UINT Type : 1;
+ UINT RGB_Range : 1;
+ UINT YCbCr_Matrix : 1;
+ UINT YCbCr_xvYCC : 1;
+ UINT Reserved : 28;
+ };
+ UINT Value;
+ };
+} DXVAHD_STREAM_STATE_INPUT_COLOR_SPACE_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_OUTPUT_RATE_DATA
+{
+ BOOL RepeatFrame;
+ DXVAHD_OUTPUT_RATE OutputRate;
+ DXVAHD_RATIONAL CustomRate;
+} DXVAHD_STREAM_STATE_OUTPUT_RATE_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_SOURCE_RECT_DATA
+{
+ BOOL Enable;
+ RECT SourceRect;
+} DXVAHD_STREAM_STATE_SOURCE_RECT_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_DESTINATION_RECT_DATA
+{
+ BOOL Enable;
+ RECT DestinationRect;
+} DXVAHD_STREAM_STATE_DESTINATION_RECT_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_ALPHA_DATA
+{
+ BOOL Enable;
+ FLOAT Alpha;
+} DXVAHD_STREAM_STATE_ALPHA_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_PALETTE_DATA
+{
+ UINT Count;
+ D3DCOLOR *pEntries;
+} DXVAHD_STREAM_STATE_PALETTE_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_LUMA_KEY_DATA
+{
+ BOOL Enable;
+ FLOAT Lower;
+ FLOAT Upper;
+} DXVAHD_STREAM_STATE_LUMA_KEY_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_ASPECT_RATIO_DATA
+{
+ BOOL Enable;
+ DXVAHD_RATIONAL SourceAspectRatio;
+ DXVAHD_RATIONAL DestinationAspectRatio;
+} DXVAHD_STREAM_STATE_ASPECT_RATIO_DATA;
+
+typedef struct _DXVAHD_STREAM_STATE_FILTER_DATA
+{
+ BOOL Enable;
+ INT Level;
+} DXVAHD_STREAM_STATE_FILTER_DATA;
+
+
+// FIXME
+typedef void* PDXVAHDSW_Plugin;
+
+
+interface IDXVAHD_Device;
+interface IDXVAHD_VideoProcessor;
+
+cpp_quote("HRESULT WINAPI DXVAHD_CreateDevice(IDirect3DDevice9Ex *d3d_device, const DXVAHD_CONTENT_DESC *desc, DXVAHD_DEVICE_USAGE usage, PDXVAHDSW_Plugin plugin, IDXVAHD_Device **device);")
+
+/*****************************************************************************
+ * IDXVAHD_Device interface
+ */
+[
+ object,
+ uuid(95f12dfd-d77e-49be-815f-57d579634d6d),
+ local
+]
+interface IDXVAHD_Device : IUnknown
+{
+ HRESULT CreateVideoSurface(
+ [in] UINT width,
+ [in] UINT height,
+ [in] D3DFORMAT format,
+ [in] D3DPOOL pool,
+ [in] DWORD usage,
+ [in] DXVAHD_SURFACE_TYPE type,
+ [in] UINT num_surfaces,
+ [out] IDirect3DSurface9 **ppSurface,
+ [in, out] HANDLE *pSharedHandle);
+
+ HRESULT GetVideoProcessorDeviceCaps(
+ [out] DXVAHD_VPDEVCAPS *pCaps);
+
+ HRESULT GetVideoProcessorOutputFormats(
+ [in] UINT count,
+ [out] D3DFORMAT *pFormats);
+
+ HRESULT GetVideoProcessorInputFormats(
+ [in] UINT count,
+ [out] D3DFORMAT *pFormats);
+
+ HRESULT GetVideoProcessorCaps(
+ [in] UINT count,
+ [out] DXVAHD_VPCAPS *pCaps);
+
+ HRESULT GetVideoProcessorCustomRates(
+ [in] const GUID *pVPGuid,
+ [in] UINT count,
+ [out] DXVAHD_CUSTOM_RATE_DATA *pRates);
+
+ HRESULT GetVideoProcessorFilterRange(
+ [in] DXVAHD_FILTER filter,
+ [out] DXVAHD_FILTER_RANGE_DATA *pRange);
+
+ HRESULT CreateVideoProcessor(
+ [in] const GUID *pVPGuid,
+ [out] IDXVAHD_VideoProcessor **ppVideoProcessor);
+}
+
+
+/*****************************************************************************
+ * IDXVAHD_VideoProcessor interface
+ */
+[
+ object,
+ uuid(95f4edf4-6e03-4cd7-be1b-3075d665aa52),
+ local
+]
+interface IDXVAHD_VideoProcessor : IUnknown
+{
+ HRESULT SetVideoProcessBltState(
+ [in] DXVAHD_BLT_STATE State,
+ [in] UINT DataSize,
+ [in] const void *pData);
+
+ HRESULT GetVideoProcessBltState(
+ [in] DXVAHD_BLT_STATE State,
+ [in] UINT DataSize,
+ [out] void *pData);
+
+ HRESULT SetVideoProcessStreamState(
+ [in] UINT StreamNumber,
+ [in] DXVAHD_STREAM_STATE State,
+ [in] UINT DataSize,
+ [in] const void *pData);
+
+ HRESULT GetVideoProcessStreamState(
+ [in] UINT StreamNumber,
+ [in] DXVAHD_STREAM_STATE State,
+ [in] UINT DataSize,
+ [out] void *pData);
+
+ HRESULT VideoProcessBltHD(
+ [in, out] IDirect3DSurface9 *pOutputSurface,
+ [in] UINT OutputFrame,
+ [in] UINT StreamCount,
+ [in] const DXVAHD_STREAM_DATA *pStreams);
+}
--
2.23.0
3
3
RE: [PATCH 2/2] ntdll: Move InterlockedCompareExchange128 support to winnt.h.
by Puetz Kevin A July 31, 2020
by Puetz Kevin A July 31, 2020
July 31, 2020
> Oh, I see, I didn't know it's already broken on aarch64. FWIW, I just wanted
> to fix a warning on clang msvcrt target and while doing that, I generalized the
> solution. We can wait with that for aarch64 solution.
Though what I was waiting on was to find out whether or was my problem
or somebody else's (i.e. would it still be an issue on our eventual BSP).
Which is, at least a bit, independent of whether wine needs a solution in general.
I probably should have at filed the bug anyway 😊
> Depending on -latomic may be problematic in PE builds. If I read libatomic
Mingw should have a -latomic too, it's the underlying runtime for the C++11 atomics
(but it just contains the C-API out-of-line implementations to fall back on
when there aren't appropriate intrinsics).
> source right, libatomic resorts to using lock in this case (pthread_mutex_lock
> or equivalent, depending on host).
Yes, that's what it does, which seemed equivalent to what wine had previously done,
and was easy to drop in as a workaround.
> We could probably just add a variant of affected RtlInterlocked*SList* functions
> that would use critical section instead of interlocked operations.
Yep. Or do what I think MS actually did, and implement the Header8 layout for when
you can't use double-pointer compare-and-exchange. They need that anyway,
(though maybe not anymore) since original amd64 CPUs don't have cmpxchg16b either.
I don't know the details on SLIST_HEADER::Header8 (presumably the same, just with
fewer bits in some of the fields), and there doesn't seem to be a lot of MSDN documentation
But here's some references I've dug up that at least mention it existed for such cases...
And obviously the Header8 struct in wine and reactos came from somewhere...
https://docs.microsoft.com/en-us/windows/win32/sync/interlocked-singly-link…
https://devblogs.microsoft.com/oldnewthing/20110819-00/?p=9853
https://docs.microsoft.com/en-us/previous-versions/windows/desktop/legacy/m…
https://cbloomrants.blogspot.com/2010/05/05-29-10-lock-free-in-x64.html
> Thanks,
>
> Jacek
1
0
July 31, 2020
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
include/private/rbtree.h | 20 ++++++++++----------
1 file changed, 10 insertions(+), 10 deletions(-)
diff --git a/include/private/rbtree.h b/include/private/rbtree.h
index 7f44a0e..b4993da 100644
--- a/include/private/rbtree.h
+++ b/include/private/rbtree.h
@@ -127,33 +127,33 @@ static inline struct rb_entry *rb_postorder_next(struct rb_entry *iter)
}
/* iterate through the tree */
-#define rb_FOR_EACH(cursor, tree) \
+#define RB_FOR_EACH(cursor, tree) \
for ((cursor) = rb_head((tree)->root); (cursor); (cursor) = rb_next(cursor))
/* iterate through the tree using a tree entry */
-#define rb_FOR_EACH_ENTRY(elem, tree, type, field) \
- for ((elem) = rb_ENTRY_VALUE(rb_head((tree)->root), type, field); \
+#define RB_FOR_EACH_ENTRY(elem, tree, type, field) \
+ for ((elem) = RB_ENTRY_VALUE(rb_head((tree)->root), type, field); \
&(elem)->field; \
- (elem) = rb_ENTRY_VALUE(rb_next(&elem->field), type, field))
+ (elem) = RB_ENTRY_VALUE(rb_next(&elem->field), type, field))
/* iterate through the tree using using postorder, making it safe to free the entry */
-#define rb_FOR_EACH_DESTRUCTOR(cursor, cursor2, tree) \
+#define RB_FOR_EACH_DESTRUCTOR(cursor, cursor2, tree) \
for ((cursor) = rb_postorder_head((tree)->root); \
(cursor) && (((cursor2) = rb_postorder_next(cursor)) || 1); \
(cursor) = (cursor2))
/* iterate through the tree using a tree entry and postorder, making it safe to free the entry */
-#define rb_FOR_EACH_ENTRY_DESTRUCTOR(elem, elem2, tree, type, field) \
- for ((elem) = rb_ENTRY_VALUE(rb_postorder_head((tree)->root), type, field); \
+#define RB_FOR_EACH_ENTRY_DESTRUCTOR(elem, elem2, tree, type, field) \
+ for ((elem) = RB_ENTRY_VALUE(rb_postorder_head((tree)->root), type, field); \
&(elem)->field \
- && (((elem2) = rb_ENTRY_VALUE(rb_postorder_next(&(elem)->field), type, field)) || 1); \
+ && (((elem2) = RB_ENTRY_VALUE(rb_postorder_next(&(elem)->field), type, field)) || 1); \
(elem) = (elem2))
static inline void rb_postorder(struct rb_tree *tree, rb_traverse_func *callback, void *context)
{
struct rb_entry *iter, *next;
- rb_FOR_EACH_DESTRUCTOR(iter, next, tree) callback(iter, context);
+ RB_FOR_EACH_DESTRUCTOR(iter, next, tree) callback(iter, context);
}
static inline void rb_init(struct rb_tree *tree, rb_compare_func compare)
@@ -165,7 +165,7 @@ static inline void rb_init(struct rb_tree *tree, rb_compare_func compare)
static inline void rb_for_each_entry(struct rb_tree *tree, rb_traverse_func *callback, void *context)
{
struct rb_entry *iter;
- rb_FOR_EACH(iter, tree) callback(iter, context);
+ RB_FOR_EACH(iter, tree) callback(iter, context);
}
static inline void rb_clear(struct rb_tree *tree, rb_traverse_func *callback, void *context)
--
2.27.0
2
1
[PATCH 2/2] ntdll: Move InterlockedCompareExchange128 support to winnt.h.
by Jacek Caban July 31, 2020
by Jacek Caban July 31, 2020
July 31, 2020
Also properly declare intrinsic on msvc.
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
dlls/ntdll/rtl.c | 26 ++++----------------------
include/winnt.h | 32 ++++++++++++++++++++++++++++++++
2 files changed, 36 insertions(+), 22 deletions(-)
2
2
[PATCH v2] winevulkan: Avoid returning 0 for swapchain maxImageCount.
by Georg Lehmann July 31, 2020
by Georg Lehmann July 31, 2020
July 31, 2020
Many Windows games do not expect that maxImageCount can be set to 0.
A value of 0 means that there is no limit on the number of images.
Nvidia reports 8 on Windows, AMD 16.
Based on a patch by Józef Kucia.
Signed-off-by: Georg Lehmann <dadschoorse(a)gmail.com>
---
dlls/winevulkan/make_vulkan | 4 +--
dlls/winevulkan/vulkan.c | 47 ++++++++++++++++++++++++++++++++
dlls/winevulkan/vulkan_private.h | 1 +
dlls/winevulkan/vulkan_thunks.c | 8 ++----
dlls/winevulkan/vulkan_thunks.h | 4 +++
5 files changed, 56 insertions(+), 8 deletions(-)
diff --git a/dlls/winevulkan/make_vulkan b/dlls/winevulkan/make_vulkan
index fc0e2182dd..6a039bd268 100755
--- a/dlls/winevulkan/make_vulkan
+++ b/dlls/winevulkan/make_vulkan
@@ -183,12 +183,12 @@ FUNCTION_OVERRIDES = {
# VK_KHR_surface
"vkDestroySurfaceKHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
"vkGetPhysicalDeviceSurfaceSupportKHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
- "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
+ "vkGetPhysicalDeviceSurfaceCapabilitiesKHR" : {"dispatch" : True, "driver" : True, "thunk" : False, "private_thunk" : True},
"vkGetPhysicalDeviceSurfaceFormatsKHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
"vkGetPhysicalDeviceSurfacePresentModesKHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
# VK_KHR_get_surface_capabilities2
- "vkGetPhysicalDeviceSurfaceCapabilities2KHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
+ "vkGetPhysicalDeviceSurfaceCapabilities2KHR" : {"dispatch" : True, "driver" : True, "thunk" : False, "private_thunk" : True},
"vkGetPhysicalDeviceSurfaceFormats2KHR" : {"dispatch" : True, "driver" : True, "thunk" : True},
# VK_KHR_win32_surface
diff --git a/dlls/winevulkan/vulkan.c b/dlls/winevulkan/vulkan.c
index be614f1cef..5f8046f1ba 100644
--- a/dlls/winevulkan/vulkan.c
+++ b/dlls/winevulkan/vulkan.c
@@ -723,6 +723,8 @@ VkResult WINAPI wine_vkCreateInstance(const VkInstanceCreateInfo *create_info,
object->quirks |= WINEVULKAN_QUIRK_GET_DEVICE_PROC_ADDR;
}
+ object->quirks |= WINEVULKAN_QUIRK_ADJUST_MAX_IMAGE_COUNT;
+
*instance = object;
TRACE("Created instance %p (native instance %p).\n", object, object->instance);
return VK_SUCCESS;
@@ -1555,6 +1557,51 @@ void WINAPI wine_vkGetPrivateDataEXT(VkDevice device, VkObjectType object_type,
device->funcs.p_vkGetPrivateDataEXT(device->device, object_type, object_handle, private_data_slot, data);
}
+static inline void adjust_max_image_count(VkPhysicalDevice phys_dev, VkSurfaceCapabilitiesKHR* capabilities)
+{
+ /* Many Windows games, for example Strange Brigade, No Man's Sky, Path of Exile
+ * and World War Z, do not expect that maxImageCount can be set to 0.
+ * A value of 0 means that there is no limit on the number of images.
+ * Nvidia reports 8 on Windows, AMD 16.
+ * https://vulkan.gpuinfo.org/displayreport.php?id=9122#surface
+ * https://vulkan.gpuinfo.org/displayreport.php?id=9121#surface
+ */
+ if ((phys_dev->instance->quirks & WINEVULKAN_QUIRK_ADJUST_MAX_IMAGE_COUNT) && !capabilities->maxImageCount)
+ {
+ capabilities->maxImageCount = max(capabilities->minImageCount, 16);
+ }
+}
+
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice phys_dev,
+ VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *capabilities)
+{
+ VkResult res;
+
+ TRACE("%p, 0x%s, %p\n", phys_dev, wine_dbgstr_longlong(surface), capabilities);
+
+ res = thunk_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(phys_dev, surface, capabilities);
+
+ if (res == VK_SUCCESS)
+ adjust_max_image_count(phys_dev, capabilities);
+
+ return res;
+}
+
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice phys_dev,
+ const VkPhysicalDeviceSurfaceInfo2KHR *surface_info, VkSurfaceCapabilities2KHR *capabilities)
+{
+ VkResult res;
+
+ TRACE("%p, %p, %p\n", phys_dev, surface_info, capabilities);
+
+ res = thunk_vkGetPhysicalDeviceSurfaceCapabilities2KHR(phys_dev, surface_info, capabilities);
+
+ if (res == VK_SUCCESS)
+ adjust_max_image_count(phys_dev, &capabilities->surfaceCapabilities);
+
+ return res;
+}
+
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD reason, void *reserved)
{
TRACE("%p, %u, %p\n", hinst, reason, reserved);
diff --git a/dlls/winevulkan/vulkan_private.h b/dlls/winevulkan/vulkan_private.h
index 17072d2341..b048108f7a 100644
--- a/dlls/winevulkan/vulkan_private.h
+++ b/dlls/winevulkan/vulkan_private.h
@@ -38,6 +38,7 @@
#define VULKAN_ICD_MAGIC_VALUE 0x01CDC0DE
#define WINEVULKAN_QUIRK_GET_DEVICE_PROC_ADDR 0x00000001
+#define WINEVULKAN_QUIRK_ADJUST_MAX_IMAGE_COUNT 0x00000002
struct vulkan_func
{
diff --git a/dlls/winevulkan/vulkan_thunks.c b/dlls/winevulkan/vulkan_thunks.c
index fcefa6a767..4f75a4ec7c 100644
--- a/dlls/winevulkan/vulkan_thunks.c
+++ b/dlls/winevulkan/vulkan_thunks.c
@@ -4998,26 +4998,22 @@ static VkResult WINAPI wine_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesC
return physicalDevice->instance->funcs.p_vkGetPhysicalDeviceSupportedFramebufferMixedSamplesCombinationsNV(physicalDevice->phys_dev, pCombinationCount, pCombinations);
}
-VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities)
+VkResult thunk_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities)
{
#if defined(USE_STRUCT_CONVERSION)
VkResult result;
VkPhysicalDeviceSurfaceInfo2KHR_host pSurfaceInfo_host;
- TRACE("%p, %p, %p\n", physicalDevice, pSurfaceInfo, pSurfaceCapabilities);
-
convert_VkPhysicalDeviceSurfaceInfo2KHR_win_to_host(pSurfaceInfo, &pSurfaceInfo_host);
result = physicalDevice->instance->funcs.p_vkGetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice->phys_dev, &pSurfaceInfo_host, pSurfaceCapabilities);
return result;
#else
- TRACE("%p, %p, %p\n", physicalDevice, pSurfaceInfo, pSurfaceCapabilities);
return physicalDevice->instance->funcs.p_vkGetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice->phys_dev, pSurfaceInfo, pSurfaceCapabilities);
#endif
}
-VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
+VkResult thunk_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities)
{
- TRACE("%p, 0x%s, %p\n", physicalDevice, wine_dbgstr_longlong(surface), pSurfaceCapabilities);
return physicalDevice->instance->funcs.p_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physicalDevice->phys_dev, surface, pSurfaceCapabilities);
}
diff --git a/dlls/winevulkan/vulkan_thunks.h b/dlls/winevulkan/vulkan_thunks.h
index f2d650decf..d35e8c4269 100644
--- a/dlls/winevulkan/vulkan_thunks.h
+++ b/dlls/winevulkan/vulkan_thunks.h
@@ -42,6 +42,8 @@ VkResult WINAPI wine_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice
VkResult WINAPI wine_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties) DECLSPEC_HIDDEN;
void WINAPI wine_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties);
void WINAPI wine_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties) DECLSPEC_HIDDEN;
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities);
+VkResult WINAPI wine_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities);
void WINAPI wine_vkGetPrivateDataEXT(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t *pData) DECLSPEC_HIDDEN;
VkResult WINAPI wine_vkQueueSubmit(VkQueue queue, uint32_t submitCount, const VkSubmitInfo *pSubmits, VkFence fence);
VkResult WINAPI wine_vkSetPrivateDataEXT(VkDevice device, VkObjectType objectType, uint64_t objectHandle, VkPrivateDataSlotEXT privateDataSlot, uint64_t data) DECLSPEC_HIDDEN;
@@ -51,6 +53,8 @@ VkResult thunk_vkGetPhysicalDeviceImageFormatProperties2(VkPhysicalDevice physic
VkResult thunk_vkGetPhysicalDeviceImageFormatProperties2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceImageFormatInfo2 *pImageFormatInfo, VkImageFormatProperties2 *pImageFormatProperties) DECLSPEC_HIDDEN;
void thunk_vkGetPhysicalDeviceProperties2(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties) DECLSPEC_HIDDEN;
void thunk_vkGetPhysicalDeviceProperties2KHR(VkPhysicalDevice physicalDevice, VkPhysicalDeviceProperties2 *pProperties) DECLSPEC_HIDDEN;
+VkResult thunk_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice, const VkPhysicalDeviceSurfaceInfo2KHR *pSurfaceInfo, VkSurfaceCapabilities2KHR *pSurfaceCapabilities) DECLSPEC_HIDDEN;
+VkResult thunk_vkGetPhysicalDeviceSurfaceCapabilitiesKHR(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface, VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) DECLSPEC_HIDDEN;
typedef struct VkAcquireNextImageInfoKHR_host
{
--
2.28.0
3
2
[PATCH] configure: Use *-windows instead of *-windows-gnu as fallback cross compiler target.
by Jacek Caban July 31, 2020
by Jacek Caban July 31, 2020
July 31, 2020
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
This code path is used mostly when cross target can't be found, which
means that mingw is most likely not available. *windows-gnu targets,
however, require cross compiled libgcc (or compiler-rt), which is
roughly a part of mingw distro, so they will most likely not work
anyway. When using *-windows target (meaning msvc compatibility mode),
Wine is self sufficient and doesn't need any external cross compiled
bits. If someone has an unusual setup and wants the old behaviour, it's
probably good idea to explicitly specify CROSSTARGET anyway.
configure.ac | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
1
0