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
- 4 participants
- 84544 discussions
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/dssenh/main.c | 10 +++++++++-
dlls/dssenh/tests/dssenh.c | 24 ++++++++++++------------
2 files changed, 21 insertions(+), 13 deletions(-)
diff --git a/dlls/dssenh/main.c b/dlls/dssenh/main.c
index 66f3456d789..44912ed4989 100644
--- a/dlls/dssenh/main.c
+++ b/dlls/dssenh/main.c
@@ -1,5 +1,6 @@
/*
* Copyright 2008 Maarten Lankhorst
+ * Copyright 2020 Hans Leidekker for CodeWeavers
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -418,7 +419,14 @@ BOOL WINAPI CPDestroyHash( HCRYPTPROV hprov, HCRYPTHASH hhash )
BOOL WINAPI CPHashData( HCRYPTPROV hprov, HCRYPTHASH hhash, const BYTE *data, DWORD len, DWORD flags )
{
- return FALSE;
+ struct hash *hash = (struct hash *)hhash;
+
+ TRACE("%p, %p, %p, %u, %08x\n", (void *)hprov, (void *)hhash, data, len, flags );
+
+ if (hash->magic != MAGIC_HASH) return FALSE;
+
+ if (hash->finished || BCryptHashData( hash->handle, (UCHAR *)data, len, 0 )) return FALSE;
+ return TRUE;
}
BOOL WINAPI CPGetHashParam( HCRYPTPROV hprov, HCRYPTHASH hhash, DWORD param, BYTE *data, DWORD *len, DWORD flags )
diff --git a/dlls/dssenh/tests/dssenh.c b/dlls/dssenh/tests/dssenh.c
index f06cdd1433a..cc4650b2c83 100644
--- a/dlls/dssenh/tests/dssenh.c
+++ b/dlls/dssenh/tests/dssenh.c
@@ -449,15 +449,15 @@ static void test_hash(const struct hash_test *tests, int testLen)
ok(result, "Expected creation of a hash.\n");
result = CryptHashData(hHash, data, dataLen, 0);
+ ok(result, "Expected data to be added to hash.\n");
+
+ dataLen = sizeof(DWORD);
+ result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &dataLen, 0);
if (!result)
{
skip("skipping hash tests\n");
return;
}
- ok(result, "Expected data to be added to hash.\n");
-
- dataLen = sizeof(DWORD);
- result = CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE *)&hashLen, &dataLen, 0);
ok(result && (hashLen == tests[i].hashLen), "Expected %d hash len, got %d.Error: %x\n",
tests[i].hashLen, hashLen, GetLastError());
@@ -608,15 +608,15 @@ static void test_data_encryption(const struct encrypt_test *tests, int testLen)
ok(result, "Expected creation of a MD5 hash for key derivation.\n");
result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
+ ok(result, "Expected data to be added to hash for key derivation.\n");
+
+ /* Derive key */
+ result = CryptDeriveKey(hProv, tests[i].algid, hHash, tests[i].keyLength, &pKey);
if (!result)
{
skip("skipping encryption tests\n");
return;
}
- ok(result, "Expected data to be added to hash for key derivation.\n");
-
- /* Derive key */
- result = CryptDeriveKey(hProv, tests[i].algid, hHash, tests[i].keyLength, &pKey);
ok(result, "Expected a derived key.\n");
result = CryptDestroyHash(hHash);
@@ -698,15 +698,15 @@ static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
ok(result, "Expected creation of a MD5 hash for key derivation.\n");
result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
+ ok(result, "Expected data to be added to hash for key derivation.\n");
+
+ /* Derive a CALG_RC2 key, but could be any other encryption cipher */
+ result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &pKey);
if (!result)
{
skip("skipping ciper modes tests\n");
return;
}
- ok(result, "Expected data to be added to hash for key derivation.\n");
-
- /* Derive a CALG_RC2 key, but could be any other encryption cipher */
- result = CryptDeriveKey(hProv, CALG_RC2, hHash, 40 << 16, &pKey);
ok(result, "Expected a derived key.\n");
result = CryptDestroyHash(hHash);
--
2.28.0
1
0
Oct. 9, 2020
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/dssenh/main.c | 90 +++++++++++++++++++++++++++++++++++++-
dlls/dssenh/tests/dssenh.c | 18 ++++----
2 files changed, 97 insertions(+), 11 deletions(-)
diff --git a/dlls/dssenh/main.c b/dlls/dssenh/main.c
index 32c31a48a8d..66f3456d789 100644
--- a/dlls/dssenh/main.c
+++ b/dlls/dssenh/main.c
@@ -54,6 +54,17 @@ struct container
char name[MAX_PATH];
};
+#define MAGIC_HASH (('H' << 24) | ('A' << 16) | ('S' << 8) | 'H')
+struct hash
+{
+ DWORD magic;
+ BCRYPT_ALG_HANDLE alg_handle;
+ BCRYPT_HASH_HANDLE handle;
+ DWORD len;
+ UCHAR value[64];
+ BOOL finished;
+};
+
static const char dss_path_fmt[] = "Software\\Wine\\Crypto\\DSS\\%s";
static BOOL create_container_regkey( struct container *container, REGSAM sam, HKEY *hkey )
@@ -320,14 +331,89 @@ BOOL WINAPI CPExportKey( HCRYPTPROV hprov, HCRYPTKEY hkey, HCRYPTKEY hexpkey, DW
return FALSE;
}
+static struct hash *create_hash( ALG_ID algid )
+{
+ struct hash *ret;
+ const WCHAR *alg;
+ DWORD len;
+
+ switch (algid)
+ {
+ case CALG_MD5:
+ alg = BCRYPT_MD5_ALGORITHM;
+ len = 16;
+ break;
+
+ case CALG_SHA1:
+ alg = BCRYPT_SHA1_ALGORITHM;
+ len = 20;
+ break;
+
+ default:
+ FIXME( "unhandled algorithm %u\n", algid );
+ return 0;
+ }
+
+ if (!(ret = heap_alloc_zero( sizeof(*ret) ))) return 0;
+
+ ret->magic = MAGIC_HASH;
+ ret->len = len;
+ if (BCryptOpenAlgorithmProvider( &ret->alg_handle, alg, MS_PRIMITIVE_PROVIDER, 0 ))
+ {
+ heap_free( ret );
+ return 0;
+ }
+ if (BCryptCreateHash( ret->alg_handle, &ret->handle, NULL, 0, NULL, 0, 0 ))
+ {
+ BCryptCloseAlgorithmProvider( ret->alg_handle, 0 );
+ heap_free( ret );
+ return 0;
+ }
+ return ret;
+}
+
BOOL WINAPI CPCreateHash( HCRYPTPROV hprov, ALG_ID algid, HCRYPTKEY hkey, DWORD flags, HCRYPTHASH *ret_hash )
{
- return FALSE;
+ struct hash *hash;
+
+ TRACE( "%p, %08x, %p, %08x, %p\n", (void *)hprov, algid, (void *)hkey, flags, ret_hash );
+
+ switch (algid)
+ {
+ case CALG_MD5:
+ case CALG_SHA1:
+ break;
+
+ default:
+ FIXME( "algorithm %u not supported\n", algid );
+ SetLastError( NTE_BAD_ALGID );
+ return FALSE;
+ }
+
+ if (!(hash = create_hash( algid ))) return FALSE;
+
+ *ret_hash = (HCRYPTHASH)hash;
+ return TRUE;
}
BOOL WINAPI CPDestroyHash( HCRYPTPROV hprov, HCRYPTHASH hhash )
{
- return FALSE;
+ struct hash *hash = (struct hash *)hhash;
+
+ TRACE( "%p, %p\n", (void *)hprov, (void *)hhash);
+
+ if (hash->magic != MAGIC_HASH)
+ {
+ SetLastError( NTE_BAD_HASH );
+ return FALSE;
+ }
+
+ BCryptDestroyHash( hash->handle );
+ BCryptCloseAlgorithmProvider( hash->alg_handle, 0 );
+
+ hash->magic = 0;
+ heap_free( hash );
+ return TRUE;
}
BOOL WINAPI CPHashData( HCRYPTPROV hprov, HCRYPTHASH hhash, const BYTE *data, DWORD len, DWORD flags )
diff --git a/dlls/dssenh/tests/dssenh.c b/dlls/dssenh/tests/dssenh.c
index d549b985d6f..f06cdd1433a 100644
--- a/dlls/dssenh/tests/dssenh.c
+++ b/dlls/dssenh/tests/dssenh.c
@@ -446,14 +446,14 @@ static void test_hash(const struct hash_test *tests, int testLen)
/* test algid hash */
result = CryptCreateHash(hProv, tests[i].algid, 0, 0, &hHash);
+ ok(result, "Expected creation of a hash.\n");
+
+ result = CryptHashData(hHash, data, dataLen, 0);
if (!result)
{
skip("skipping hash tests\n");
return;
}
- ok(result, "Expected creation of a hash.\n");
-
- result = CryptHashData(hHash, data, dataLen, 0);
ok(result, "Expected data to be added to hash.\n");
dataLen = sizeof(DWORD);
@@ -605,14 +605,14 @@ static void test_data_encryption(const struct encrypt_test *tests, int testLen)
SetLastError(0xdeadbeef);
result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
+ ok(result, "Expected creation of a MD5 hash for key derivation.\n");
+
+ result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
if (!result)
{
skip("skipping encryption tests\n");
return;
}
- ok(result, "Expected creation of a MD5 hash for key derivation.\n");
-
- result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
ok(result, "Expected data to be added to hash for key derivation.\n");
/* Derive key */
@@ -695,14 +695,14 @@ static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
SetLastError(0xdeadbeef);
result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
+ ok(result, "Expected creation of a MD5 hash for key derivation.\n");
+
+ result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
if (!result)
{
skip("skipping ciper modes tests\n");
return;
}
- ok(result, "Expected creation of a MD5 hash for key derivation.\n");
-
- result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
ok(result, "Expected data to be added to hash for key derivation.\n");
/* Derive a CALG_RC2 key, but could be any other encryption cipher */
--
2.28.0
1
0
Oct. 9, 2020
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/dssenh/Makefile.in | 1 +
dlls/dssenh/main.c | 256 ++++++++++++++++++++++++++++++++++++-
dlls/dssenh/tests/dssenh.c | 42 ++++++
3 files changed, 297 insertions(+), 2 deletions(-)
diff --git a/dlls/dssenh/Makefile.in b/dlls/dssenh/Makefile.in
index 8015768f99b..67b0d6a141c 100644
--- a/dlls/dssenh/Makefile.in
+++ b/dlls/dssenh/Makefile.in
@@ -1,4 +1,5 @@
MODULE = dssenh.dll
+IMPORTS = bcrypt crypt32 advapi32
EXTRADLLFLAGS = -mno-cygwin
diff --git a/dlls/dssenh/main.c b/dlls/dssenh/main.c
index 5aa885c8b86..32c31a48a8d 100644
--- a/dlls/dssenh/main.c
+++ b/dlls/dssenh/main.c
@@ -22,23 +22,275 @@
#include "windef.h"
#include "winbase.h"
#include "wincrypt.h"
+#include "winreg.h"
+#include "bcrypt.h"
#include "objbase.h"
#include "rpcproxy.h"
#include "wine/debug.h"
+#include "wine/heap.h"
static HINSTANCE instance;
WINE_DEFAULT_DEBUG_CHANNEL(dssenh);
+#define MAGIC_KEY (('K' << 24) | ('E' << 16) | ('Y' << 8) | '0')
+struct key
+{
+ DWORD magic;
+ DWORD algid;
+ DWORD flags;
+ BCRYPT_ALG_HANDLE alg_handle;
+ BCRYPT_KEY_HANDLE handle;
+};
+
+#define MAGIC_CONTAINER (('C' << 24) | ('O' << 16) | ('N' << 8) | 'T')
+struct container
+{
+ DWORD magic;
+ DWORD flags;
+ struct key *exch_key;
+ struct key *sign_key;
+ char name[MAX_PATH];
+};
+
+static const char dss_path_fmt[] = "Software\\Wine\\Crypto\\DSS\\%s";
+
+static BOOL create_container_regkey( struct container *container, REGSAM sam, HKEY *hkey )
+{
+ char path[sizeof(dss_path_fmt) + MAX_PATH];
+ HKEY rootkey;
+
+ sprintf( path, dss_path_fmt, container->name );
+
+ if (container->flags & CRYPT_MACHINE_KEYSET)
+ rootkey = HKEY_LOCAL_MACHINE;
+ else
+ rootkey = HKEY_CURRENT_USER;
+
+ /* @@ Wine registry key: HKLM\Software\Wine\Crypto\DSS */
+ /* @@ Wine registry key: HKCU\Software\Wine\Crypto\DSS */
+ return !RegCreateKeyExA( rootkey, path, 0, NULL, REG_OPTION_NON_VOLATILE, sam, NULL, hkey, NULL );
+}
+
+static struct container *create_key_container( const char *name, DWORD flags )
+{
+ struct container *ret;
+
+ if (!(ret = heap_alloc_zero( sizeof(*ret) ))) return NULL;
+ ret->magic = MAGIC_CONTAINER;
+ ret->flags = flags;
+ if (name) strcpy( ret->name, name );
+
+ if (!(flags & CRYPT_VERIFYCONTEXT))
+ {
+ HKEY hkey;
+ if (create_container_regkey( ret, KEY_WRITE, &hkey )) RegCloseKey( hkey );
+ }
+ return ret;
+}
+
+static BOOL open_container_regkey( const char *name, DWORD flags, REGSAM access, HKEY *hkey )
+{
+ char path[sizeof(dss_path_fmt) + MAX_PATH];
+ HKEY rootkey;
+
+ sprintf( path, dss_path_fmt, name );
+
+ if (flags & CRYPT_MACHINE_KEYSET)
+ rootkey = HKEY_LOCAL_MACHINE;
+ else
+ rootkey = HKEY_CURRENT_USER;
+
+ /* @@ Wine registry key: HKLM\Software\Wine\Crypto\DSS */
+ /* @@ Wine registry key: HKCU\Software\Wine\Crypto\DSS */
+ return !RegOpenKeyExA( rootkey, path, 0, access, hkey );
+}
+
+static const WCHAR *map_keyspec_to_keypair_name( DWORD keyspec )
+{
+ const WCHAR *name;
+
+ switch (keyspec)
+ {
+ case AT_KEYEXCHANGE:
+ name = L"KeyExchangeKeyPair";
+ break;
+ case AT_SIGNATURE:
+ name = L"SignatureKeyPair";
+ break;
+ default:
+ ERR( "invalid key spec %u\n", keyspec );
+ return NULL;
+ }
+ return name;
+}
+
+static struct key *create_key( ALG_ID algid, DWORD flags )
+{
+ struct key *ret;
+ const WCHAR *alg;
+
+ switch (algid)
+ {
+ case AT_SIGNATURE:
+ case CALG_DSS_SIGN:
+ alg = BCRYPT_DSA_ALGORITHM;
+ break;
+
+ default:
+ FIXME( "unhandled algorithm %08x\n", algid );
+ return NULL;
+ }
+
+ if (!(ret = heap_alloc_zero( sizeof(*ret) ))) return NULL;
+
+ ret->magic = MAGIC_KEY;
+ ret->algid = algid;
+ ret->flags = flags;
+ if (BCryptOpenAlgorithmProvider( &ret->alg_handle, alg, MS_PRIMITIVE_PROVIDER, 0 ))
+ {
+ heap_free( ret );
+ return NULL;
+ }
+ return ret;
+}
+
+static void destroy_key( struct key *key )
+{
+ if (!key) return;
+ BCryptDestroyKey( key->handle );
+ BCryptCloseAlgorithmProvider( key->alg_handle, 0 );
+ key->magic = 0;
+ heap_free( key );
+}
+
+static struct key *import_key( DWORD keyspec, BYTE *data, DWORD len )
+{
+ struct key *ret;
+
+ if (!(ret = create_key( keyspec, 0 ))) return NULL;
+
+ if (BCryptImportKeyPair( ret->alg_handle, NULL, LEGACY_DSA_V2_PRIVATE_BLOB, &ret->handle, data, len, 0 ))
+ {
+ WARN( "failed to import key\n" );
+ destroy_key( ret );
+ return NULL;
+ }
+ return ret;
+}
+
+static struct key *read_key( HKEY hkey, DWORD keyspec, DWORD flags )
+{
+ const WCHAR *value;
+ DWORD type, len;
+ BYTE *data;
+ DATA_BLOB blob_in, blob_out;
+ struct key *ret = NULL;
+
+ if (!(value = map_keyspec_to_keypair_name( keyspec ))) return NULL;
+ if (RegQueryValueExW( hkey, value, 0, &type, NULL, &len )) return NULL;
+ if (!(data = heap_alloc( len ))) return NULL;
+
+ if (!RegQueryValueExW( hkey, value, 0, &type, data, &len ))
+ {
+ blob_in.pbData = data;
+ blob_in.cbData = len;
+ if (CryptUnprotectData( &blob_in, NULL, NULL, NULL, NULL, flags, &blob_out ))
+ {
+ ret = import_key( keyspec, blob_out.pbData, blob_out.cbData );
+ LocalFree( blob_out.pbData );
+ }
+ }
+
+ heap_free( data );
+ return ret;
+}
+
+static void destroy_container( struct container *container )
+{
+ if (!container) return;
+ destroy_key( container->exch_key );
+ destroy_key( container->sign_key );
+ container->magic = 0;
+ heap_free( container );
+}
+
+static struct container *read_key_container( const char *name, DWORD flags )
+{
+ DWORD protect_flags = (flags & CRYPT_MACHINE_KEYSET) ? CRYPTPROTECT_LOCAL_MACHINE : 0;
+ struct container *ret;
+ HKEY hkey;
+
+ if (!open_container_regkey( name, flags, KEY_READ, &hkey )) return NULL;
+
+ if ((ret = create_key_container( name, flags )))
+ {
+ ret->exch_key = read_key( hkey, AT_KEYEXCHANGE, protect_flags );
+ ret->sign_key = read_key( hkey, AT_SIGNATURE, protect_flags );
+ }
+
+ RegCloseKey( hkey );
+ return ret;
+}
+
BOOL WINAPI CPAcquireContext( HCRYPTPROV *ret_prov, LPSTR container, DWORD flags, PVTableProvStruc vtable )
{
- return FALSE;
+ struct container *ret;
+ char name[MAX_PATH];
+
+ TRACE( "%p, %s, %08x, %p\n", ret_prov, debugstr_a(container), flags, vtable );
+
+ if (container && *container)
+ {
+ if (lstrlenA( container ) >= sizeof(name)) return FALSE;
+ lstrcpyA( name, container );
+ }
+ else
+ {
+ DWORD len = sizeof(name);
+ if (!GetUserNameA( name, &len )) return FALSE;
+ }
+
+ switch (flags)
+ {
+ case 0:
+ ret = read_key_container( name, flags );
+ break;
+
+ case CRYPT_NEWKEYSET:
+ if ((ret = read_key_container( name, flags )))
+ {
+ heap_free( ret );
+ SetLastError( NTE_EXISTS );
+ return FALSE;
+ }
+ ret = create_key_container( name, flags );
+ break;
+
+ case CRYPT_VERIFYCONTEXT:
+ ret = create_key_container( "", flags );
+ break;
+
+ default:
+ FIXME( "unsupported flags %08x\n", flags );
+ return FALSE;
+ }
+
+ if (!ret) return FALSE;
+ *ret_prov = (HCRYPTPROV)ret;
+ return TRUE;
}
BOOL WINAPI CPReleaseContext( HCRYPTPROV hprov, DWORD flags )
{
- return FALSE;
+ struct container *container = (struct container *)hprov;
+
+ TRACE( "%p, %08x\n", (void *)hprov, flags );
+
+ if (container->magic != MAGIC_CONTAINER) return FALSE;
+ destroy_container( container );
+ return TRUE;
}
BOOL WINAPI CPGetProvParam( HCRYPTPROV hprov, DWORD param, BYTE *data, DWORD *len, DWORD flags )
diff --git a/dlls/dssenh/tests/dssenh.c b/dlls/dssenh/tests/dssenh.c
index c88fcd14661..d549b985d6f 100644
--- a/dlls/dssenh/tests/dssenh.c
+++ b/dlls/dssenh/tests/dssenh.c
@@ -323,6 +323,7 @@ static void test_keylength_array(HCRYPTPROV hProv,const struct keylength_test *t
static void test_keylength(void)
{
HCRYPTPROV hProv = 0;
+ HCRYPTKEY key;
BOOL result;
/* acquire base dss provider */
@@ -335,6 +336,17 @@ static void test_keylength(void)
}
ok(result, "Expected no errors.\n");
+ result = CryptGenKey(hProv, AT_SIGNATURE, 0, &key);
+ todo_wine ok(result, "Expected no errors.\n");
+ if (!result)
+ {
+ skip("skipping key length tests\n");
+ return;
+ }
+
+ result = CryptDestroyKey(key);
+ ok(result, "Expected no errors.\n");
+
/* perform keylength tests */
test_keylength_array(hProv, baseDSS_keylength, ARRAY_SIZE(baseDSS_keylength));
@@ -434,6 +446,11 @@ static void test_hash(const struct hash_test *tests, int testLen)
/* test algid hash */
result = CryptCreateHash(hProv, tests[i].algid, 0, 0, &hHash);
+ if (!result)
+ {
+ skip("skipping hash tests\n");
+ return;
+ }
ok(result, "Expected creation of a hash.\n");
result = CryptHashData(hHash, data, dataLen, 0);
@@ -588,6 +605,11 @@ static void test_data_encryption(const struct encrypt_test *tests, int testLen)
SetLastError(0xdeadbeef);
result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
+ if (!result)
+ {
+ skip("skipping encryption tests\n");
+ return;
+ }
ok(result, "Expected creation of a MD5 hash for key derivation.\n");
result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
@@ -673,6 +695,11 @@ static void test_cipher_modes(const struct ciphermode_test *tests, int testLen)
SetLastError(0xdeadbeef);
result = CryptCreateHash(hProv, CALG_MD5, 0, 0, &hHash);
+ if (!result)
+ {
+ skip("skipping ciper modes tests\n");
+ return;
+ }
ok(result, "Expected creation of a MD5 hash for key derivation.\n");
result = CryptHashData(hHash, (BYTE *)dataToHash, sizeof(dataToHash), 0);
@@ -831,6 +858,11 @@ static void test_signhash_array(HCRYPTPROV hProv, const struct signature_test *t
/* Get a private key of array specified ALG_ID */
result = CryptImportKey(hProv, tests[i].privateKey, tests[i].keyLen, 0, 0, &privKey);
+ if (!result)
+ {
+ skip("skipping sign tests\n");
+ return;
+ }
ok(result, "Failed to imported key, got %x\n", GetLastError());
/* Create hash object and add data for signature 1 */
@@ -1084,6 +1116,11 @@ static void test_keyExchange_baseDSS(HCRYPTPROV hProv, const struct keyExchange_
/* Generate key exchange keys for user1 and user2 */
result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey1);
+ if (!result)
+ {
+ skip("skipping key exchange tests\n");
+ return;
+ }
ok(!result && GetLastError() == NTE_BAD_ALGID,
"Expected NTE_BAD_ALGID, got %x\n", GetLastError());
@@ -1233,6 +1270,11 @@ static void test_keyExchange_dssDH(HCRYPTPROV hProv, const struct keyExchange_te
/* Generate key exchange keys for user1 and user2 */
result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey1);
+ if (!result)
+ {
+ skip("skipping key exchange tests\n");
+ return;
+ }
ok(result, "Failed to generate a key for user1, got %x\n", GetLastError());
result = CryptGenKey(hProv, tests[i].algid, 512 << 16 | CRYPT_PREGEN, &privKey2);
--
2.28.0
1
0
Oct. 9, 2020
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/comctl32/ipaddress.c | 7 +++---
dlls/comctl32/tests/ipaddress.c | 43 +++++++++++++++++++++++++++++++++
2 files changed, 47 insertions(+), 3 deletions(-)
diff --git a/dlls/comctl32/ipaddress.c b/dlls/comctl32/ipaddress.c
index 32816561e3d..82d47d4e576 100644
--- a/dlls/comctl32/ipaddress.c
+++ b/dlls/comctl32/ipaddress.c
@@ -354,7 +354,7 @@ static BOOL IPADDRESS_SetRange (IPADDRESS_INFO *infoPtr, int index, WORD range)
}
-static void IPADDRESS_ClearAddress (const IPADDRESS_INFO *infoPtr)
+static LRESULT IPADDRESS_ClearAddress (const IPADDRESS_INFO *infoPtr)
{
int i;
@@ -362,6 +362,8 @@ static void IPADDRESS_ClearAddress (const IPADDRESS_INFO *infoPtr)
for (i = 0; i < 4; i++)
SetWindowTextW (infoPtr->Part[i].EditHwnd, L"");
+
+ return 1;
}
@@ -614,8 +616,7 @@ IPADDRESS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
return 0;
case IPM_CLEARADDRESS:
- IPADDRESS_ClearAddress (infoPtr);
- break;
+ return IPADDRESS_ClearAddress (infoPtr);
case IPM_SETADDRESS:
return IPADDRESS_SetAddress (infoPtr, (DWORD)lParam);
diff --git a/dlls/comctl32/tests/ipaddress.c b/dlls/comctl32/tests/ipaddress.c
index c87d0f56641..9bb9dd63d71 100644
--- a/dlls/comctl32/tests/ipaddress.c
+++ b/dlls/comctl32/tests/ipaddress.c
@@ -144,6 +144,47 @@ static void test_WM_SETFOCUS(void)
DestroyWindow(hwnd);
}
+static void test_IPM_CLEARADDRESS(void)
+{
+ struct child_enum child_enum = { 0 };
+ char buff[16];
+ int i, ret;
+ HWND hwnd;
+
+ hwnd = create_ipaddress_control();
+ ok(!!hwnd, "Failed to create control.\n");
+
+ ret = SendMessageA(hwnd, IPM_SETADDRESS, 0, MAKEIPADDRESS(0, 1, 2, 3));
+ ok(ret == 1, "Unexpected return value %d.\n", ret);
+
+ EnumChildWindows(hwnd, test_child_enum_proc, (LPARAM)&child_enum);
+ ok(child_enum.count == 4, "Unexpected child count %u.\n", child_enum.count);
+
+ ret = SendMessageA(hwnd, IPM_SETADDRESS, 0, MAKEIPADDRESS(1, 2, 3, 4));
+ ok(ret == 1, "Unexpected return value %d.\n", ret);
+
+ ret = GetWindowTextA(hwnd, buff, ARRAY_SIZE(buff));
+ ok(ret == 7, "Unexpected return value %d.\n", ret);
+ ok(!strcmp(buff, "1.2.3.4"), "Unexpected address %s.\n", buff);
+
+ ret = SendMessageA(hwnd, IPM_CLEARADDRESS, 0, 0);
+ ok(ret, "Unexpected return value %d.\n", ret);
+
+ ret = GetWindowTextA(hwnd, buff, ARRAY_SIZE(buff));
+ ok(ret == 7, "Unexpected return value %d.\n", ret);
+ ok(!strcmp(buff, "0.0.0.0"), "Unexpected address %s.\n", buff);
+
+ for (i = 0; i < 4; ++i)
+ {
+ buff[0] = 1;
+ ret = GetWindowTextA(child_enum.fields[i], buff, ARRAY_SIZE(buff));
+ ok(ret == 0, "Unexpected return value %d.\n", ret);
+ ok(!*buff, "Unexpected field text %s.\n", buff);
+ }
+
+ DestroyWindow(hwnd);
+}
+
START_TEST(ipaddress)
{
ULONG_PTR cookie;
@@ -152,6 +193,7 @@ START_TEST(ipaddress)
test_get_set_text();
test_IPM_SETFOCUS();
test_WM_SETFOCUS();
+ test_IPM_CLEARADDRESS();
if (!load_v6_module(&cookie, &ctxt))
return;
@@ -159,6 +201,7 @@ START_TEST(ipaddress)
test_get_set_text();
test_IPM_SETFOCUS();
test_WM_SETFOCUS();
+ test_IPM_CLEARADDRESS();
unload_v6_module(cookie, ctxt);
}
--
2.28.0
1
1
Oct. 9, 2020
Signed-off-by: Myah Caron <qsniyg(a)protonmail.com>
---
Based on ReactOS's implementation (hence the first patch in this series).
dlls/ntoskrnl.exe/ntoskrnl.c | 10 ++++++++++
dlls/ntoskrnl.exe/ntoskrnl.exe.spec | 2 +-
dlls/ntoskrnl.exe/tests/driver.c | 4 ++++
include/ddk/wdm.h | 1 +
4 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.c b/dlls/ntoskrnl.exe/ntoskrnl.c
index 177816a2239..aea80c77fcd 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.c
+++ b/dlls/ntoskrnl.exe/ntoskrnl.c
@@ -2962,6 +2962,16 @@ BOOLEAN WINAPI PsIsSystemThread(PETHREAD thread)
}
+/***********************************************************************
+ * PsIsProcessBeingDebugged (NTOSKRNL.EXE.@)
+ */
+BOOLEAN WINAPI PsIsProcessBeingDebugged(PEPROCESS process)
+{
+ TRACE( "%p\n", process );
+ return !!PsGetProcessDebugPort( process );
+}
+
+
/***********************************************************************
* PsGetVersion (NTOSKRNL.EXE.@)
*/
diff --git a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
index 8ca0f652f1d..6ada30e1f21 100644
--- a/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
+++ b/dlls/ntoskrnl.exe/ntoskrnl.exe.spec
@@ -923,7 +923,7 @@
@ stdcall PsGetVersion(ptr ptr ptr ptr)
@ stdcall PsImpersonateClient(ptr ptr long long long)
@ extern PsInitialSystemProcess
-@ stub PsIsProcessBeingDebugged
+@ stdcall PsIsProcessBeingDebugged(ptr)
@ stdcall PsIsSystemThread(ptr)
@ stub PsIsThreadImpersonating
@ stub PsIsThreadTerminating
diff --git a/dlls/ntoskrnl.exe/tests/driver.c b/dlls/ntoskrnl.exe/tests/driver.c
index e712ecf2f84..3d76bdf6856 100644
--- a/dlls/ntoskrnl.exe/tests/driver.c
+++ b/dlls/ntoskrnl.exe/tests/driver.c
@@ -2106,9 +2106,13 @@ static void test_permanence(void)
static void test_debug(void)
{
PVOID debug_port;
+ BOOLEAN is_debugged;
debug_port = PsGetProcessDebugPort( PsGetCurrentProcess() );
ok(!debug_port, "got %p\n", debug_port);
+
+ is_debugged = PsIsProcessBeingDebugged( PsGetCurrentProcess() );
+ ok(!is_debugged, "got %d\n", is_debugged);
}
static NTSTATUS main_test(DEVICE_OBJECT *device, IRP *irp, IO_STACK_LOCATION *stack)
diff --git a/include/ddk/wdm.h b/include/ddk/wdm.h
index 40f1d9754c0..8c639b50320 100644
--- a/include/ddk/wdm.h
+++ b/include/ddk/wdm.h
@@ -1835,6 +1835,7 @@ HANDLE WINAPI PsGetCurrentThreadId(void);
HANDLE WINAPI PsGetProcessInheritedFromUniqueProcessId(PEPROCESS);
BOOLEAN WINAPI PsGetVersion(ULONG*,ULONG*,ULONG*,UNICODE_STRING*);
PVOID WINAPI PsGetProcessDebugPort(PEPROCESS process);
+BOOLEAN WINAPI PsIsProcessBeingDebugged(PEPROCESS process);
NTSTATUS WINAPI PsTerminateSystemThread(NTSTATUS);
#if defined(__x86_64__) || defined(__i386__)
--
2.28.0
1
0
[PATCH 2/2] dxgi: Update swapchain containing output after Alt+Enter was used to exit fullscreen.
by Zhiyi Zhang Oct. 9, 2020
by Zhiyi Zhang Oct. 9, 2020
Oct. 9, 2020
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
v2: Supersede 194122. Put a struct wined3d_swapchain_state_parent in d3d/dxgi swapchains.
struct wined3d_swapchain_state_parent is passed to wined3d_swapchain_create as a parameter
and not in struct wined3d_swapchain_desc because puttting it in there will make some
swapchain description struct conversion ugly. For example, wined3d_swapchain_desc_from_dxgi()
needs to take in account of whether it's a d3d11 or d3d12 swapchain and then set corresponding
wined3d_swapchain_state_parent unless we set the field outside of wined3d_swapchain_desc_from_dxgi(),
which doesn't seems nice also.
dlls/d3d8/d3d8_private.h | 1 +
dlls/d3d8/swapchain.c | 16 ++++++++--
dlls/d3d9/d3d9_private.h | 1 +
dlls/d3d9/swapchain.c | 16 ++++++++--
dlls/ddraw/ddraw.c | 16 ++++++++--
dlls/ddraw/ddraw_private.h | 1 +
dlls/dxgi/dxgi_private.h | 1 +
dlls/dxgi/swapchain.c | 57 ++++++++++++++++++++++++++++++++--
dlls/dxgi/tests/dxgi.c | 15 +++++----
dlls/wined3d/adapter_gl.c | 9 +++---
dlls/wined3d/adapter_vk.c | 10 +++---
dlls/wined3d/directx.c | 10 +++---
dlls/wined3d/swapchain.c | 52 ++++++++++++++++++++-----------
dlls/wined3d/wined3d.spec | 4 +--
dlls/wined3d/wined3d_private.h | 16 +++++++---
include/wine/wined3d.h | 20 ++++++++++--
16 files changed, 188 insertions(+), 57 deletions(-)
diff --git a/dlls/d3d8/d3d8_private.h b/dlls/d3d8/d3d8_private.h
index e98746a13bd..bb25be16de0 100644
--- a/dlls/d3d8/d3d8_private.h
+++ b/dlls/d3d8/d3d8_private.h
@@ -185,6 +185,7 @@ struct d3d8_swapchain
IDirect3DSwapChain8 IDirect3DSwapChain8_iface;
LONG refcount;
struct wined3d_swapchain *wined3d_swapchain;
+ struct wined3d_swapchain_state_parent state_parent;
IDirect3DDevice8 *parent_device;
unsigned int swap_interval;
};
diff --git a/dlls/d3d8/swapchain.c b/dlls/d3d8/swapchain.c
index f08a19ca238..78db4fcaf24 100644
--- a/dlls/d3d8/swapchain.c
+++ b/dlls/d3d8/swapchain.c
@@ -156,6 +156,17 @@ static const struct wined3d_parent_ops d3d8_swapchain_wined3d_parent_ops =
d3d8_swapchain_wined3d_object_released,
};
+static void CDECL d3d8_swapchain_windowed_state_changed(struct wined3d_swapchain_state_parent *parent,
+ BOOL windowed)
+{
+ TRACE("parent %p, windowed %d.\n", parent, windowed);
+}
+
+static const struct wined3d_swapchain_state_parent_ops d3d8_swapchain_state_parent_ops =
+{
+ d3d8_swapchain_windowed_state_changed,
+};
+
static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_device *device,
struct wined3d_swapchain_desc *desc, unsigned int swap_interval)
{
@@ -163,10 +174,11 @@ static HRESULT swapchain_init(struct d3d8_swapchain *swapchain, struct d3d8_devi
swapchain->refcount = 1;
swapchain->IDirect3DSwapChain8_iface.lpVtbl = &d3d8_swapchain_vtbl;
+ swapchain->state_parent.ops = &d3d8_swapchain_state_parent_ops;
swapchain->swap_interval = swap_interval;
- if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
- &d3d8_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain)))
+ if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, &swapchain->state_parent,
+ swapchain, &d3d8_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain)))
{
WARN("Failed to create wined3d swapchain, hr %#x.\n", hr);
return hr;
diff --git a/dlls/d3d9/d3d9_private.h b/dlls/d3d9/d3d9_private.h
index e78ce75a2f0..03ab10ad01b 100644
--- a/dlls/d3d9/d3d9_private.h
+++ b/dlls/d3d9/d3d9_private.h
@@ -162,6 +162,7 @@ struct d3d9_swapchain
IDirect3DSwapChain9Ex IDirect3DSwapChain9Ex_iface;
LONG refcount;
struct wined3d_swapchain *wined3d_swapchain;
+ struct wined3d_swapchain_state_parent state_parent;
IDirect3DDevice9Ex *parent_device;
unsigned int swap_interval;
};
diff --git a/dlls/d3d9/swapchain.c b/dlls/d3d9/swapchain.c
index 8d6cff982d3..0955b672c79 100644
--- a/dlls/d3d9/swapchain.c
+++ b/dlls/d3d9/swapchain.c
@@ -356,6 +356,17 @@ static const struct wined3d_parent_ops d3d9_swapchain_wined3d_parent_ops =
d3d9_swapchain_wined3d_object_released,
};
+static void CDECL d3d9_swapchain_windowed_state_changed(struct wined3d_swapchain_state_parent *parent,
+ BOOL windowed)
+{
+ TRACE("parent %p, windowed %d.\n", parent, windowed);
+}
+
+static const struct wined3d_swapchain_state_parent_ops d3d9_swapchain_state_parent_ops =
+{
+ d3d9_swapchain_windowed_state_changed,
+};
+
static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_device *device,
struct wined3d_swapchain_desc *desc, unsigned int swap_interval)
{
@@ -363,10 +374,11 @@ static HRESULT swapchain_init(struct d3d9_swapchain *swapchain, struct d3d9_devi
swapchain->refcount = 1;
swapchain->IDirect3DSwapChain9Ex_iface.lpVtbl = &d3d9_swapchain_vtbl;
+ swapchain->state_parent.ops = &d3d9_swapchain_state_parent_ops;
swapchain->swap_interval = swap_interval;
- if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
- &d3d9_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain)))
+ if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, &swapchain->state_parent,
+ swapchain, &d3d9_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain)))
{
WARN("Failed to create wined3d swapchain, hr %#x.\n", hr);
return hr;
diff --git a/dlls/ddraw/ddraw.c b/dlls/ddraw/ddraw.c
index c3c335d978e..11a16f8d535 100644
--- a/dlls/ddraw/ddraw.c
+++ b/dlls/ddraw/ddraw.c
@@ -80,6 +80,17 @@ const struct wined3d_parent_ops ddraw_null_wined3d_parent_ops =
ddraw_null_wined3d_object_destroyed,
};
+static void CDECL ddraw_swapchain_windowed_state_changed(struct wined3d_swapchain_state_parent *parent,
+ BOOL windowed)
+{
+ TRACE("parent %p, windowed %d.\n", parent, windowed);
+}
+
+static const struct wined3d_swapchain_state_parent_ops ddraw_swapchain_state_parent_ops =
+{
+ ddraw_swapchain_windowed_state_changed,
+};
+
static inline struct ddraw *impl_from_IDirectDraw(IDirectDraw *iface)
{
return CONTAINING_RECORD(iface, struct ddraw, IDirectDraw_iface);
@@ -577,7 +588,7 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, HWND window,
if (ddraw->flags & DDRAW_NO3D)
return wined3d_swapchain_create(ddraw->wined3d_device, &swapchain_desc,
- NULL, &ddraw_null_wined3d_parent_ops, wined3d_swapchain);
+ &ddraw->state_parent, NULL, &ddraw_null_wined3d_parent_ops, wined3d_swapchain);
if (!window || window == GetDesktopWindow())
{
@@ -605,7 +616,7 @@ static HRESULT ddraw_attach_d3d_device(struct ddraw *ddraw, HWND window,
* recursive loop until ram or emulated video memory is full. */
ddraw->flags |= DDRAW_D3D_INITIALIZED;
if (FAILED(hr = wined3d_swapchain_create(ddraw->wined3d_device, &swapchain_desc,
- NULL, &ddraw_null_wined3d_parent_ops, wined3d_swapchain)))
+ &ddraw->state_parent, NULL, &ddraw_null_wined3d_parent_ops, wined3d_swapchain)))
{
ddraw->flags &= ~DDRAW_D3D_INITIALIZED;
DestroyWindow(window);
@@ -5105,6 +5116,7 @@ HRESULT ddraw_init(struct ddraw *ddraw, DWORD flags, enum wined3d_device_type de
ddraw->IDirect3D3_iface.lpVtbl = &d3d3_vtbl;
ddraw->IDirect3D7_iface.lpVtbl = &d3d7_vtbl;
ddraw->device_parent.ops = &ddraw_wined3d_device_parent_ops;
+ ddraw->state_parent.ops = &ddraw_swapchain_state_parent_ops;
ddraw->numIfaces = 1;
ddraw->ref7 = 1;
diff --git a/dlls/ddraw/ddraw_private.h b/dlls/ddraw/ddraw_private.h
index 776f61e1024..6bbd62949ac 100644
--- a/dlls/ddraw/ddraw_private.h
+++ b/dlls/ddraw/ddraw_private.h
@@ -105,6 +105,7 @@ struct ddraw
struct wined3d_texture *wined3d_frontbuffer;
struct wined3d_texture *gdi_surface;
struct wined3d_swapchain *wined3d_swapchain;
+ struct wined3d_swapchain_state_parent state_parent;
HWND swapchain_window;
/* DirectDraw things, which are not handled by WineD3D */
diff --git a/dlls/dxgi/dxgi_private.h b/dlls/dxgi/dxgi_private.h
index e43ee59461c..acba3544e39 100644
--- a/dlls/dxgi/dxgi_private.h
+++ b/dlls/dxgi/dxgi_private.h
@@ -177,6 +177,7 @@ struct d3d11_swapchain
LONG refcount;
struct wined3d_private_store private_store;
struct wined3d_swapchain *wined3d_swapchain;
+ struct wined3d_swapchain_state_parent state_parent;
IWineDXGIDevice *device;
IDXGIFactory *factory;
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index 36beb84aa28..0f335a71cb7 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -811,6 +811,30 @@ static const struct wined3d_parent_ops d3d11_swapchain_wined3d_parent_ops =
d3d11_swapchain_wined3d_object_released,
};
+static inline struct d3d11_swapchain *d3d11_swapchain_from_wined3d_swapchain_state_parent(struct wined3d_swapchain_state_parent *parent)
+{
+ return CONTAINING_RECORD(parent, struct d3d11_swapchain, state_parent);
+}
+
+static void CDECL d3d11_swapchain_windowed_state_changed(struct wined3d_swapchain_state_parent *parent,
+ BOOL windowed)
+{
+ struct d3d11_swapchain *swapchain = d3d11_swapchain_from_wined3d_swapchain_state_parent(parent);
+
+ TRACE("parent %p, windowed %d.\n", parent, windowed);
+
+ if (windowed && swapchain->target)
+ {
+ IDXGIOutput_Release(swapchain->target);
+ swapchain->target = NULL;
+ }
+}
+
+static const struct wined3d_swapchain_state_parent_ops d3d11_swapchain_state_parent_ops =
+{
+ d3d11_swapchain_windowed_state_changed,
+};
+
HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_device *device,
struct wined3d_swapchain_desc *desc)
{
@@ -840,6 +864,7 @@ HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_devi
}
swapchain->IDXGISwapChain1_iface.lpVtbl = &d3d11_swapchain_vtbl;
+ swapchain->state_parent.ops = &d3d11_swapchain_state_parent_ops;
swapchain->refcount = 1;
wined3d_mutex_lock();
wined3d_private_store_init(&swapchain->private_store);
@@ -849,8 +874,8 @@ HRESULT d3d11_swapchain_init(struct d3d11_swapchain *swapchain, struct dxgi_devi
fullscreen = !desc->windowed;
desc->windowed = TRUE;
- if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, swapchain,
- &d3d11_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain)))
+ if (FAILED(hr = wined3d_swapchain_create(device->wined3d_device, desc, &swapchain->state_parent,
+ swapchain, &d3d11_swapchain_wined3d_parent_ops, &swapchain->wined3d_swapchain)))
{
WARN("Failed to create wined3d swapchain, hr %#x.\n", hr);
goto cleanup;
@@ -1037,6 +1062,7 @@ struct d3d12_swapchain
struct wined3d_private_store private_store;
struct wined3d_swapchain_state *state;
+ struct wined3d_swapchain_state_parent state_parent;
VkSwapchainKHR vk_swapchain;
VkSurfaceKHR vk_surface;
@@ -2938,6 +2964,30 @@ static BOOL init_vk_funcs(struct dxgi_vk_funcs *dxgi, VkInstance vk_instance, Vk
return TRUE;
}
+static inline struct d3d12_swapchain *d3d12_swapchain_from_wined3d_swapchain_state_parent(struct wined3d_swapchain_state_parent *parent)
+{
+ return CONTAINING_RECORD(parent, struct d3d12_swapchain, state_parent);
+}
+
+static void CDECL d3d12_swapchain_windowed_state_changed(struct wined3d_swapchain_state_parent *parent,
+ BOOL windowed)
+{
+ struct d3d12_swapchain *swapchain = d3d12_swapchain_from_wined3d_swapchain_state_parent(parent);
+
+ TRACE("parent %p, windowed %d.\n", parent, windowed);
+
+ if (windowed && swapchain->target)
+ {
+ IDXGIOutput_Release(swapchain->target);
+ swapchain->target = NULL;
+ }
+}
+
+static const struct wined3d_swapchain_state_parent_ops d3d12_swapchain_state_parent_ops =
+{
+ d3d12_swapchain_windowed_state_changed,
+};
+
static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGIFactory *factory,
ID3D12Device *device, ID3D12CommandQueue *queue, HWND window,
const DXGI_SWAP_CHAIN_DESC1 *swapchain_desc, const DXGI_SWAP_CHAIN_FULLSCREEN_DESC *fullscreen_desc)
@@ -2967,6 +3017,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
}
swapchain->IDXGISwapChain4_iface.lpVtbl = &d3d12_swapchain_vtbl;
+ swapchain->state_parent.ops = &d3d12_swapchain_state_parent_ops;
swapchain->refcount = 1;
swapchain->window = window;
@@ -3024,7 +3075,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
dxgi_factory = unsafe_impl_from_IDXGIFactory((IDXGIFactory *)factory);
if (FAILED(hr = wined3d_swapchain_state_create(&wined3d_desc, window, dxgi_factory->wined3d,
- &swapchain->state)))
+ &swapchain->state_parent, &swapchain->state)))
{
IDXGIOutput_Release(output);
return hr;
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index 2838a025e57..c6ece51f2a8 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -2431,7 +2431,7 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
flush_events();
hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, NULL);
ok(hr == S_OK, "GetFullscreenState failed, hr %#x.\n", hr);
- todo_wine_if(is_d3d12) ok(!fullscreen, "Expect swapchain not full screen.\n");
+ ok(!fullscreen, "Expect swapchain not full screen.\n");
/* Move the swapchain output window to the second output */
hr = IDXGIOutput_GetDesc(output2, &output_desc2);
@@ -2453,7 +2453,7 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
hr = IDXGIOutput_GetDesc(output2, &output_desc2);
ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
- todo_wine ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
+ ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
"Expect device name %s, got %s.\n", wine_dbgstr_w(output_desc2.DeviceName),
wine_dbgstr_w(output_desc.DeviceName));
IDXGIOutput_Release(output);
@@ -2465,7 +2465,7 @@ static void test_get_containing_output(IUnknown *device, BOOL is_d3d12)
ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
hr = IDXGIOutput_GetDesc(output2, &output_desc2);
ok(hr == S_OK, "GetDesc failed, hr %#x.\n", hr);
- todo_wine ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
+ ok(!lstrcmpW(output_desc.DeviceName, output_desc2.DeviceName),
"Expect device name %s, got %s.\n", wine_dbgstr_w(output_desc2.DeviceName),
wine_dbgstr_w(output_desc.DeviceName));
@@ -6148,7 +6148,6 @@ static void test_window_association(IUnknown *device, BOOL is_d3d12)
UINT flag;
BOOL expect_fullscreen;
BOOL broken_d3d10;
- BOOL todo_on_d3d12;
}
tests[] =
{
@@ -6162,15 +6161,15 @@ static void test_window_association(IUnknown *device, BOOL is_d3d12)
* - Posting them hangs the posting thread. Another thread that keeps
* sending input is needed to avoid the hang. The hang is not
* because of flush_events(). */
- {0, TRUE, FALSE, TRUE},
+ {0, TRUE},
{0, FALSE},
{DXGI_MWA_NO_WINDOW_CHANGES, FALSE},
{DXGI_MWA_NO_WINDOW_CHANGES, FALSE},
- {DXGI_MWA_NO_ALT_ENTER, FALSE, TRUE},
+ {DXGI_MWA_NO_ALT_ENTER},
{DXGI_MWA_NO_ALT_ENTER, FALSE},
- {DXGI_MWA_NO_PRINT_SCREEN, TRUE, FALSE, TRUE},
+ {DXGI_MWA_NO_PRINT_SCREEN, TRUE},
{DXGI_MWA_NO_PRINT_SCREEN, FALSE},
- {0, TRUE, FALSE, TRUE},
+ {0, TRUE},
{0, FALSE}
};
diff --git a/dlls/wined3d/adapter_gl.c b/dlls/wined3d/adapter_gl.c
index 5bf9d179e4d..140948beb6d 100644
--- a/dlls/wined3d/adapter_gl.c
+++ b/dlls/wined3d/adapter_gl.c
@@ -4590,19 +4590,20 @@ static void adapter_gl_copy_bo_address(struct wined3d_context *context,
wined3d_context_gl_copy_bo_address(wined3d_context_gl(context), dst, src, size);
}
-static HRESULT adapter_gl_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
+static HRESULT adapter_gl_create_swapchain(struct wined3d_device *device,
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
{
struct wined3d_swapchain_gl *swapchain_gl;
HRESULT hr;
- TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n",
- device, desc, parent, parent_ops, swapchain);
+ TRACE("device %p, desc %p, state_parent %p, parent %p, parent_ops %p, swapchain %p.\n",
+ device, desc, state_parent, parent, parent_ops, swapchain);
if (!(swapchain_gl = heap_alloc_zero(sizeof(*swapchain_gl))))
return E_OUTOFMEMORY;
- if (FAILED(hr = wined3d_swapchain_gl_init(swapchain_gl, device, desc, parent, parent_ops)))
+ if (FAILED(hr = wined3d_swapchain_gl_init(swapchain_gl, device, desc, state_parent, parent, parent_ops)))
{
WARN("Failed to initialise swapchain, hr %#x.\n", hr);
heap_free(swapchain_gl);
diff --git a/dlls/wined3d/adapter_vk.c b/dlls/wined3d/adapter_vk.c
index 5c219d45d3e..64850944040 100644
--- a/dlls/wined3d/adapter_vk.c
+++ b/dlls/wined3d/adapter_vk.c
@@ -1103,19 +1103,21 @@ static void adapter_vk_copy_bo_address(struct wined3d_context *context,
adapter_vk_unmap_bo_address(context, src, 0, NULL);
}
-static HRESULT adapter_vk_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
+static HRESULT adapter_vk_create_swapchain(struct wined3d_device *device,
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
{
struct wined3d_swapchain_vk *swapchain_vk;
HRESULT hr;
- TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n",
- device, desc, parent, parent_ops, swapchain);
+ TRACE("device %p, desc %p, state_parent %p, parent %p, parent_ops %p, swapchain %p.\n",
+ device, desc, state_parent, parent, parent_ops, swapchain);
if (!(swapchain_vk = heap_alloc_zero(sizeof(*swapchain_vk))))
return E_OUTOFMEMORY;
- if (FAILED(hr = wined3d_swapchain_vk_init(swapchain_vk, device, desc, parent, parent_ops)))
+ if (FAILED(hr = wined3d_swapchain_vk_init(swapchain_vk, device, desc, state_parent, parent,
+ parent_ops)))
{
WARN("Failed to initialise swapchain, hr %#x.\n", hr);
heap_free(swapchain_vk);
diff --git a/dlls/wined3d/directx.c b/dlls/wined3d/directx.c
index 0fa05a06be6..108a190bf61 100644
--- a/dlls/wined3d/directx.c
+++ b/dlls/wined3d/directx.c
@@ -2665,19 +2665,21 @@ static void adapter_no3d_copy_bo_address(struct wined3d_context *context,
memcpy(dst->addr, src->addr, size);
}
-static HRESULT adapter_no3d_create_swapchain(struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
+static HRESULT adapter_no3d_create_swapchain(struct wined3d_device *device,
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
{
struct wined3d_swapchain *swapchain_no3d;
HRESULT hr;
- TRACE("device %p, desc %p, parent %p, parent_ops %p, swapchain %p.\n",
- device, desc, parent, parent_ops, swapchain);
+ TRACE("device %p, desc %p, state_parent %p, parent %p, parent_ops %p, swapchain %p.\n",
+ device, desc, state_parent, parent, parent_ops, swapchain);
if (!(swapchain_no3d = heap_alloc_zero(sizeof(*swapchain_no3d))))
return E_OUTOFMEMORY;
- if (FAILED(hr = wined3d_swapchain_no3d_init(swapchain_no3d, device, desc, parent, parent_ops)))
+ if (FAILED(hr = wined3d_swapchain_no3d_init(swapchain_no3d, device, desc, state_parent, parent,
+ parent_ops)))
{
WARN("Failed to initialise swapchain, hr %#x.\n", hr);
heap_free(swapchain_no3d);
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index b35fb5af65a..f8214379971 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -1288,7 +1288,8 @@ static enum wined3d_format_id adapter_format_from_backbuffer_format(const struct
}
static HRESULT wined3d_swapchain_state_init(struct wined3d_swapchain_state *state,
- const struct wined3d_swapchain_desc *desc, HWND window, struct wined3d *wined3d)
+ const struct wined3d_swapchain_desc *desc, HWND window, struct wined3d *wined3d,
+ struct wined3d_swapchain_state_parent *parent)
{
HRESULT hr;
@@ -1319,6 +1320,7 @@ static HRESULT wined3d_swapchain_state_init(struct wined3d_swapchain_state *stat
GetWindowRect(window, &state->original_window_rect);
state->device_window = window;
+ state->parent = parent;
if (desc->flags & WINED3D_SWAPCHAIN_REGISTER_STATE)
wined3d_swapchain_state_register(state, wined3d);
@@ -1327,7 +1329,8 @@ static HRESULT wined3d_swapchain_state_init(struct wined3d_swapchain_state *stat
}
static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struct wined3d_device *device,
- struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
+ void *parent, const struct wined3d_parent_ops *parent_ops,
const struct wined3d_swapchain_ops *swapchain_ops)
{
struct wined3d_resource_desc texture_desc;
@@ -1353,7 +1356,7 @@ static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struc
FIXME("Unimplemented swap effect %#x.\n", desc->swap_effect);
window = desc->device_window ? desc->device_window : device->create_parms.focus_window;
- if (FAILED(hr = wined3d_swapchain_state_init(&swapchain->state, desc, window, device->wined3d)))
+ if (FAILED(hr = wined3d_swapchain_state_init(&swapchain->state, desc, window, device->wined3d, state_parent)))
{
ERR("Failed to initialise swapchain state, hr %#x.\n", hr);
goto err;
@@ -1568,23 +1571,27 @@ err:
}
HRESULT wined3d_swapchain_no3d_init(struct wined3d_swapchain *swapchain_no3d, struct wined3d_device *device,
- struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
+ void *parent, const struct wined3d_parent_ops *parent_ops)
{
- TRACE("swapchain_no3d %p, device %p, desc %p, parent %p, parent_ops %p.\n",
- swapchain_no3d, device, desc, parent, parent_ops);
+ TRACE("swapchain_no3d %p, device %p, desc %p, state_parent %p, parent %p, parent_ops %p.\n",
+ swapchain_no3d, device, desc, state_parent, parent, parent_ops);
- return wined3d_swapchain_init(swapchain_no3d, device, desc, parent, parent_ops, &swapchain_no3d_ops);
+ return wined3d_swapchain_init(swapchain_no3d, device, desc, state_parent, parent, parent_ops,
+ &swapchain_no3d_ops);
}
HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl, struct wined3d_device *device,
- struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
+ void *parent, const struct wined3d_parent_ops *parent_ops)
{
HRESULT hr;
- TRACE("swapchain_gl %p, device %p, desc %p, parent %p, parent_ops %p.\n",
- swapchain_gl, device, desc, parent, parent_ops);
+ TRACE("swapchain_gl %p, device %p, desc %p, state_parent %p, parent %p, parent_ops %p.\n",
+ swapchain_gl, device, desc, state_parent, parent, parent_ops);
- if (FAILED(hr = wined3d_swapchain_init(&swapchain_gl->s, device, desc, parent, parent_ops, &swapchain_gl_ops)))
+ if (FAILED(hr = wined3d_swapchain_init(&swapchain_gl->s, device, desc, state_parent, parent,
+ parent_ops, &swapchain_gl_ops)))
{
/* Cleanup any context that may have been created for the swapchain. */
wined3d_cs_destroy_object(device->cs, wined3d_swapchain_gl_destroy_object, swapchain_gl);
@@ -1595,14 +1602,16 @@ HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl, str
}
HRESULT wined3d_swapchain_vk_init(struct wined3d_swapchain_vk *swapchain_vk, struct wined3d_device *device,
- struct wined3d_swapchain_desc *desc, void *parent, const struct wined3d_parent_ops *parent_ops)
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
+ void *parent, const struct wined3d_parent_ops *parent_ops)
{
HRESULT hr;
TRACE("swapchain_vk %p, device %p, desc %p, parent %p, parent_ops %p.\n",
swapchain_vk, device, desc, parent, parent_ops);
- if (FAILED(hr = wined3d_swapchain_init(&swapchain_vk->s, device, desc, parent, parent_ops, &swapchain_vk_ops)))
+ if (FAILED(hr = wined3d_swapchain_init(&swapchain_vk->s, device, desc, state_parent, parent,
+ parent_ops, &swapchain_vk_ops)))
return hr;
if (swapchain_vk->s.win_handle == GetDesktopWindow())
@@ -1620,14 +1629,16 @@ HRESULT wined3d_swapchain_vk_init(struct wined3d_swapchain_vk *swapchain_vk, str
return hr;
}
-HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
- void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain)
+HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device,
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
+ void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_swapchain **swapchain)
{
struct wined3d_swapchain *object;
HRESULT hr;
if (FAILED(hr = device->adapter->adapter_ops->adapter_create_swapchain(device,
- desc, parent, parent_ops, &object)))
+ desc, state_parent, parent, parent_ops, &object)))
return hr;
if (desc->flags & WINED3D_SWAPCHAIN_IMPLICIT)
@@ -2175,6 +2186,7 @@ HRESULT CDECL wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_st
{
struct wined3d_display_mode actual_mode;
struct wined3d_output_desc output_desc;
+ BOOL windowed = state->desc.windowed;
HRESULT hr;
TRACE("state %p, swapchain_desc %p, mode %p.\n", state, swapchain_desc, mode);
@@ -2263,6 +2275,9 @@ HRESULT CDECL wined3d_swapchain_state_set_fullscreen(struct wined3d_swapchain_st
state->desc.output = swapchain_desc->output;
state->desc.windowed = swapchain_desc->windowed;
+ if (windowed != state->desc.windowed)
+ state->parent->ops->windowed_state_changed(state->parent, state->desc.windowed);
+
return WINED3D_OK;
}
@@ -2280,7 +2295,8 @@ void CDECL wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state
}
HRESULT CDECL wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc,
- HWND window, struct wined3d *wined3d, struct wined3d_swapchain_state **state)
+ HWND window, struct wined3d *wined3d, struct wined3d_swapchain_state_parent *state_parent,
+ struct wined3d_swapchain_state **state)
{
struct wined3d_swapchain_state *s;
HRESULT hr;
@@ -2290,7 +2306,7 @@ HRESULT CDECL wined3d_swapchain_state_create(const struct wined3d_swapchain_desc
if (!(s = heap_alloc_zero(sizeof(*s))))
return E_OUTOFMEMORY;
- if (FAILED(hr = wined3d_swapchain_state_init(s, desc, window, wined3d)))
+ if (FAILED(hr = wined3d_swapchain_state_init(s, desc, window, wined3d, state_parent)))
{
heap_free(s);
return hr;
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index 77b22b3c907..e4ff1161bce 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -271,7 +271,7 @@
@ cdecl wined3d_stateblock_set_vs_consts_f(ptr long long ptr)
@ cdecl wined3d_stateblock_set_vs_consts_i(ptr long long ptr)
-@ cdecl wined3d_swapchain_create(ptr ptr ptr ptr ptr)
+@ cdecl wined3d_swapchain_create(ptr ptr ptr ptr ptr ptr)
@ cdecl wined3d_swapchain_decref(ptr)
@ cdecl wined3d_swapchain_get_back_buffer(ptr long)
@ cdecl wined3d_swapchain_get_device(ptr)
@@ -289,7 +289,7 @@
@ cdecl wined3d_swapchain_set_palette(ptr ptr)
@ cdecl wined3d_swapchain_set_window(ptr ptr)
-@ cdecl wined3d_swapchain_state_create(ptr ptr ptr ptr)
+@ cdecl wined3d_swapchain_state_create(ptr ptr ptr ptr ptr)
@ cdecl wined3d_swapchain_state_destroy(ptr)
@ cdecl wined3d_swapchain_state_is_windowed(ptr)
@ cdecl wined3d_swapchain_state_resize_target(ptr ptr)
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index bbb0a60d7bb..4c2204cd86e 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3245,8 +3245,10 @@ struct wined3d_adapter_ops
unsigned int range_count, const struct wined3d_range *ranges);
void (*adapter_copy_bo_address)(struct wined3d_context *context,
const struct wined3d_bo_address *dst, const struct wined3d_bo_address *src, size_t size);
- HRESULT (*adapter_create_swapchain)(struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
- void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain);
+ HRESULT (*adapter_create_swapchain)(struct wined3d_device *device,
+ struct wined3d_swapchain_desc *desc,
+ struct wined3d_swapchain_state_parent *state_parent, void *parent,
+ const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain);
void (*adapter_destroy_swapchain)(struct wined3d_swapchain *swapchain);
HRESULT (*adapter_create_buffer)(struct wined3d_device *device, const struct wined3d_buffer_desc *desc,
const struct wined3d_sub_resource_data *data, void *parent, const struct wined3d_parent_ops *parent_ops,
@@ -5070,6 +5072,7 @@ void wined3d_unordered_access_view_vk_update(struct wined3d_unordered_access_vie
struct wined3d_swapchain_state
{
struct wined3d_swapchain_desc desc;
+ struct wined3d_swapchain_state_parent *parent;
struct wined3d_display_mode original_mode, d3d_mode;
RECT original_window_rect;
@@ -5128,7 +5131,8 @@ void swapchain_set_max_frame_latency(struct wined3d_swapchain *swapchain,
HRESULT wined3d_swapchain_no3d_init(struct wined3d_swapchain *swapchain_no3d,
struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
- void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+ struct wined3d_swapchain_state_parent *state_parent, void *parent,
+ const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
struct wined3d_swapchain_gl
{
@@ -5153,7 +5157,8 @@ HDC wined3d_swapchain_gl_get_backup_dc(struct wined3d_swapchain_gl *swapchain_gl
struct wined3d_context_gl *wined3d_swapchain_gl_get_context(struct wined3d_swapchain_gl *swapchain_gl) DECLSPEC_HIDDEN;
HRESULT wined3d_swapchain_gl_init(struct wined3d_swapchain_gl *swapchain_gl,
struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
- void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+ struct wined3d_swapchain_state_parent *state_parent, void *parent,
+ const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
struct wined3d_swapchain_vk
{
@@ -5179,7 +5184,8 @@ static inline struct wined3d_swapchain_vk *wined3d_swapchain_vk(struct wined3d_s
void wined3d_swapchain_vk_cleanup(struct wined3d_swapchain_vk *swapchain_vk) DECLSPEC_HIDDEN;
HRESULT wined3d_swapchain_vk_init(struct wined3d_swapchain_vk *swapchain_vk,
struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
- void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
+ struct wined3d_swapchain_state_parent *state_parent, void *parent,
+ const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
/*****************************************************************************
* Utility function prototypes
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 61ab0e90953..62ea3960118 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -2248,6 +2248,17 @@ struct wined3d_device_parent_ops
const struct wined3d_resource_desc *desc, DWORD texture_flags, struct wined3d_texture **texture);
};
+struct wined3d_swapchain_state_parent
+{
+ const struct wined3d_swapchain_state_parent_ops *ops;
+};
+
+struct wined3d_swapchain_state_parent_ops
+{
+ void (__cdecl *windowed_state_changed)(struct wined3d_swapchain_state_parent *state_parent,
+ BOOL windowed);
+};
+
struct wined3d_private_store
{
struct list content;
@@ -2774,8 +2785,10 @@ HRESULT __cdecl wined3d_stateblock_set_vs_consts_f(struct wined3d_stateblock *st
HRESULT __cdecl wined3d_stateblock_set_vs_consts_i(struct wined3d_stateblock *stateblock,
unsigned int start_idx, unsigned int count, const struct wined3d_ivec4 *constants);
-HRESULT __cdecl wined3d_swapchain_create(struct wined3d_device *device, struct wined3d_swapchain_desc *desc,
- void *parent, const struct wined3d_parent_ops *parent_ops, struct wined3d_swapchain **swapchain);
+HRESULT __cdecl wined3d_swapchain_create(struct wined3d_device *device,
+ struct wined3d_swapchain_desc *desc, struct wined3d_swapchain_state_parent *state_parent,
+ void *parent, const struct wined3d_parent_ops *parent_ops,
+ struct wined3d_swapchain **swapchain);
ULONG __cdecl wined3d_swapchain_decref(struct wined3d_swapchain *swapchain);
struct wined3d_texture * __cdecl wined3d_swapchain_get_back_buffer(const struct wined3d_swapchain *swapchain,
UINT backbuffer_idx);
@@ -2804,7 +2817,8 @@ void __cdecl wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain,
void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window);
HRESULT __cdecl wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc,
- HWND window, struct wined3d *wined3d, struct wined3d_swapchain_state **state);
+ HWND window, struct wined3d *wined3d, struct wined3d_swapchain_state_parent *state_parent,
+ struct wined3d_swapchain_state **state);
void __cdecl wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state);
BOOL __cdecl wined3d_swapchain_state_is_windowed(const struct wined3d_swapchain_state *state);
HRESULT __cdecl wined3d_swapchain_state_resize_target(struct wined3d_swapchain_state *state,
--
2.25.1
2
2
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
v2: Supersede 194121 and 194123. Make wined3d_swapchain_state_register/unregister
private in wined3d.
dlls/dxgi/swapchain.c | 32 +++++++++--
dlls/dxgi/tests/dxgi.c | 1 -
dlls/dxgi/utils.c | 2 +-
dlls/wined3d/swapchain.c | 19 +++----
dlls/wined3d/wined3d.spec | 2 +-
dlls/wined3d/wined3d_main.c | 99 +++++++++++++++++-----------------
dlls/wined3d/wined3d_private.h | 5 +-
include/wine/wined3d.h | 4 +-
8 files changed, 95 insertions(+), 69 deletions(-)
diff --git a/dlls/dxgi/swapchain.c b/dlls/dxgi/swapchain.c
index f3b74389d29..36beb84aa28 100644
--- a/dlls/dxgi/swapchain.c
+++ b/dlls/dxgi/swapchain.c
@@ -2272,18 +2272,37 @@ static HRESULT STDMETHODCALLTYPE d3d12_swapchain_GetFullscreenState(IDXGISwapCha
BOOL *fullscreen, IDXGIOutput **target)
{
struct d3d12_swapchain *swapchain = d3d12_swapchain_from_IDXGISwapChain4(iface);
+ BOOL windowed;
+ HRESULT hr;
TRACE("iface %p, fullscreen %p, target %p.\n", iface, fullscreen, target);
- if (fullscreen)
+ if (fullscreen || target)
{
wined3d_mutex_lock();
- *fullscreen = !wined3d_swapchain_state_is_windowed(swapchain->state);
+ windowed = wined3d_swapchain_state_is_windowed(swapchain->state);
wined3d_mutex_unlock();
}
- if (target && (*target = swapchain->target))
- IDXGIOutput_AddRef(*target);
+ if (fullscreen)
+ *fullscreen = !windowed;
+
+ if (target)
+ {
+ if (!windowed)
+ {
+ if (!swapchain->target && FAILED(hr = IDXGISwapChain4_GetContainingOutput(iface,
+ &swapchain->target)))
+ return hr;
+
+ *target = swapchain->target;
+ IDXGIOutput_AddRef(*target);
+ }
+ else
+ {
+ *target = NULL;
+ }
+ }
return S_OK;
}
@@ -2927,6 +2946,7 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
struct wined3d_swapchain_desc wined3d_desc;
VkWin32SurfaceCreateInfoKHR surface_desc;
VkPhysicalDevice vk_physical_device;
+ struct dxgi_factory *dxgi_factory;
VkFenceCreateInfo fence_desc;
uint32_t queue_family_index;
VkSurfaceKHR vk_surface;
@@ -3002,7 +3022,9 @@ static HRESULT d3d12_swapchain_init(struct d3d12_swapchain *swapchain, IWineDXGI
return hr;
}
- if (FAILED(hr = wined3d_swapchain_state_create(&wined3d_desc, window, &swapchain->state)))
+ dxgi_factory = unsafe_impl_from_IDXGIFactory((IDXGIFactory *)factory);
+ if (FAILED(hr = wined3d_swapchain_state_create(&wined3d_desc, window, dxgi_factory->wined3d,
+ &swapchain->state)))
{
IDXGIOutput_Release(output);
return hr;
diff --git a/dlls/dxgi/tests/dxgi.c b/dlls/dxgi/tests/dxgi.c
index f747e236f31..2838a025e57 100644
--- a/dlls/dxgi/tests/dxgi.c
+++ b/dlls/dxgi/tests/dxgi.c
@@ -6272,7 +6272,6 @@ static void test_window_association(IUnknown *device, BOOL is_d3d12)
output = NULL;
hr = IDXGISwapChain_GetFullscreenState(swapchain, &fullscreen, &output);
ok(hr == S_OK, "Test %u: Got unexpected hr %#x.\n", i, hr);
- todo_wine_if(is_d3d12 && tests[i].todo_on_d3d12)
ok(fullscreen == tests[i].expect_fullscreen
|| broken(tests[i].broken_d3d10 && fullscreen),
"Test %u: Got unexpected fullscreen %#x.\n", i, fullscreen);
diff --git a/dlls/dxgi/utils.c b/dlls/dxgi/utils.c
index 665413e4c62..af72f83b6b0 100644
--- a/dlls/dxgi/utils.c
+++ b/dlls/dxgi/utils.c
@@ -520,7 +520,7 @@ unsigned int wined3d_bind_flags_from_dxgi_usage(DXGI_USAGE dxgi_usage)
#define DXGI_WINED3D_SWAPCHAIN_FLAGS \
(WINED3D_SWAPCHAIN_USE_CLOSEST_MATCHING_MODE | WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT \
- | WINED3D_SWAPCHAIN_HOOK | WINED3D_SWAPCHAIN_RESTORE_WINDOW_STATE)
+ | WINED3D_SWAPCHAIN_REGISTER_STATE | WINED3D_SWAPCHAIN_RESTORE_WINDOW_STATE)
unsigned int dxgi_swapchain_flags_from_wined3d(unsigned int wined3d_flags)
{
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index d0d93417a18..b35fb5af65a 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -34,7 +34,7 @@ void wined3d_swapchain_cleanup(struct wined3d_swapchain *swapchain)
TRACE("Destroying swapchain %p.\n", swapchain);
- wined3d_unhook_swapchain(swapchain);
+ wined3d_swapchain_state_unregister(&swapchain->state);
wined3d_swapchain_set_gamma_ramp(swapchain, 0, &swapchain->orig_gamma);
/* Release the swapchain's draw buffers. Make sure swapchain->back_buffers[0]
@@ -1288,7 +1288,7 @@ static enum wined3d_format_id adapter_format_from_backbuffer_format(const struct
}
static HRESULT wined3d_swapchain_state_init(struct wined3d_swapchain_state *state,
- const struct wined3d_swapchain_desc *desc, HWND window)
+ const struct wined3d_swapchain_desc *desc, HWND window, struct wined3d *wined3d)
{
HRESULT hr;
@@ -1320,6 +1320,9 @@ static HRESULT wined3d_swapchain_state_init(struct wined3d_swapchain_state *stat
GetWindowRect(window, &state->original_window_rect);
state->device_window = window;
+ if (desc->flags & WINED3D_SWAPCHAIN_REGISTER_STATE)
+ wined3d_swapchain_state_register(state, wined3d);
+
return hr;
}
@@ -1350,7 +1353,7 @@ static HRESULT wined3d_swapchain_init(struct wined3d_swapchain *swapchain, struc
FIXME("Unimplemented swap effect %#x.\n", desc->swap_effect);
window = desc->device_window ? desc->device_window : device->create_parms.focus_window;
- if (FAILED(hr = wined3d_swapchain_state_init(&swapchain->state, desc, window)))
+ if (FAILED(hr = wined3d_swapchain_state_init(&swapchain->state, desc, window, device->wined3d)))
{
ERR("Failed to initialise swapchain state, hr %#x.\n", hr);
goto err;
@@ -1627,9 +1630,6 @@ HRESULT CDECL wined3d_swapchain_create(struct wined3d_device *device, struct win
desc, parent, parent_ops, &object)))
return hr;
- if (desc->flags & WINED3D_SWAPCHAIN_HOOK)
- wined3d_hook_swapchain(object);
-
if (desc->flags & WINED3D_SWAPCHAIN_IMPLICIT)
{
wined3d_mutex_lock();
@@ -2275,21 +2275,22 @@ BOOL CDECL wined3d_swapchain_state_is_windowed(const struct wined3d_swapchain_st
void CDECL wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state)
{
+ wined3d_swapchain_state_unregister(state);
heap_free(state);
}
HRESULT CDECL wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc,
- HWND window, struct wined3d_swapchain_state **state)
+ HWND window, struct wined3d *wined3d, struct wined3d_swapchain_state **state)
{
struct wined3d_swapchain_state *s;
HRESULT hr;
- TRACE("desc %p, window %p, state %p.\n", desc, window, state);
+ TRACE("desc %p, window %p, wined3d %p, state %p.\n", desc, window, wined3d, state);
if (!(s = heap_alloc_zero(sizeof(*s))))
return E_OUTOFMEMORY;
- if (FAILED(hr = wined3d_swapchain_state_init(s, desc, window)))
+ if (FAILED(hr = wined3d_swapchain_state_init(s, desc, window, wined3d)))
{
heap_free(s);
return hr;
diff --git a/dlls/wined3d/wined3d.spec b/dlls/wined3d/wined3d.spec
index d11e06d0c34..77b22b3c907 100644
--- a/dlls/wined3d/wined3d.spec
+++ b/dlls/wined3d/wined3d.spec
@@ -289,7 +289,7 @@
@ cdecl wined3d_swapchain_set_palette(ptr ptr)
@ cdecl wined3d_swapchain_set_window(ptr ptr)
-@ cdecl wined3d_swapchain_state_create(ptr ptr ptr)
+@ cdecl wined3d_swapchain_state_create(ptr ptr ptr ptr)
@ cdecl wined3d_swapchain_state_destroy(ptr)
@ cdecl wined3d_swapchain_state_is_windowed(ptr)
@ cdecl wined3d_swapchain_state_resize_target(ptr ptr)
diff --git a/dlls/wined3d/wined3d_main.c b/dlls/wined3d/wined3d_main.c
index c98aee18bdd..001b7dd1255 100644
--- a/dlls/wined3d/wined3d_main.c
+++ b/dlls/wined3d/wined3d_main.c
@@ -56,25 +56,26 @@ struct wined3d_window_hook
unsigned int count;
};
-struct wined3d_hooked_swapchain
+struct wined3d_registered_swapchain_state
{
- struct wined3d_swapchain *swapchain;
+ struct wined3d_swapchain_state *state;
+ struct wined3d *wined3d;
DWORD thread_id;
};
-struct wined3d_hook_table
+struct wined3d_swapchain_state_table
{
struct wined3d_window_hook *hooks;
SIZE_T hooks_size;
SIZE_T hook_count;
- struct wined3d_hooked_swapchain *swapchains;
- SIZE_T swapchains_size;
- SIZE_T swapchain_count;
+ struct wined3d_registered_swapchain_state *states;
+ SIZE_T states_size;
+ SIZE_T state_count;
};
static struct wined3d_wndproc_table wndproc_table;
-static struct wined3d_hook_table hook_table;
+static struct wined3d_swapchain_state_table swapchain_state_table;
static CRITICAL_SECTION wined3d_cs;
static CRITICAL_SECTION_DEBUG wined3d_cs_debug =
@@ -425,13 +426,13 @@ static BOOL wined3d_dll_destroy(HINSTANCE hInstDLL)
}
heap_free(wndproc_table.entries);
- heap_free(hook_table.swapchains);
- for (i = 0; i < hook_table.hook_count; ++i)
+ heap_free(swapchain_state_table.states);
+ for (i = 0; i < swapchain_state_table.hook_count; ++i)
{
- WARN("Leftover hook table entry %p.\n", &hook_table.hooks[i]);
- UnhookWindowsHookEx(hook_table.hooks[i].hook);
+ WARN("Leftover swapchain state hook %p.\n", &swapchain_state_table.hooks[i]);
+ UnhookWindowsHookEx(swapchain_state_table.hooks[i].hook);
}
- heap_free(hook_table.hooks);
+ heap_free(swapchain_state_table.hooks);
heap_free(wined3d_settings.logo);
UnregisterClassA(WINED3D_OPENGL_WINDOW_CLASS_NAME, hInstDLL);
@@ -573,8 +574,8 @@ static LRESULT CALLBACK wined3d_wndproc(HWND window, UINT message, WPARAM wparam
static LRESULT CALLBACK wined3d_hook_proc(int code, WPARAM wparam, LPARAM lparam)
{
+ struct wined3d_registered_swapchain_state *registered_state;
struct wined3d_swapchain_desc swapchain_desc;
- struct wined3d_swapchain *swapchain;
struct wined3d_wndproc *entry;
struct wined3d_output *output;
MSG *msg = (MSG *)lparam;
@@ -586,28 +587,28 @@ static LRESULT CALLBACK wined3d_hook_proc(int code, WPARAM wparam, LPARAM lparam
{
wined3d_wndproc_mutex_lock();
- for (i = 0; i < hook_table.swapchain_count; ++i)
+ for (i = 0; i < swapchain_state_table.state_count; ++i)
{
- swapchain = hook_table.swapchains[i].swapchain;
+ registered_state = &swapchain_state_table.states[i];
- if (swapchain->state.device_window != msg->hwnd)
+ if (registered_state->state->device_window != msg->hwnd)
continue;
- if ((entry = wined3d_find_wndproc(msg->hwnd, swapchain->device->wined3d))
+ if ((entry = wined3d_find_wndproc(msg->hwnd, registered_state->wined3d))
&& (entry->flags & (WINED3D_REGISTER_WINDOW_NO_WINDOW_CHANGES
| WINED3D_REGISTER_WINDOW_NO_ALT_ENTER)))
continue;
- wined3d_swapchain_get_desc(swapchain, &swapchain_desc);
+ swapchain_desc = registered_state->state->desc;
swapchain_desc.windowed = !swapchain_desc.windowed;
- if (!(output = wined3d_get_output_from_window(swapchain->device->wined3d,
- swapchain->state.device_window)))
+ if (!(output = wined3d_get_output_from_window(registered_state->wined3d,
+ registered_state->state->device_window)))
{
- ERR("Failed to get output from window %p.\n", swapchain->state.device_window);
+ ERR("Failed to get output from window %p.\n", registered_state->state->device_window);
break;
}
swapchain_desc.output = output;
- wined3d_swapchain_state_set_fullscreen(&swapchain->state, &swapchain_desc, NULL);
+ wined3d_swapchain_state_set_fullscreen(registered_state->state, &swapchain_desc, NULL);
wined3d_wndproc_mutex_unlock();
@@ -764,82 +765,84 @@ static struct wined3d_window_hook *wined3d_find_hook(DWORD thread_id)
{
unsigned int i;
- for (i = 0; i < hook_table.hook_count; ++i)
+ for (i = 0; i < swapchain_state_table.hook_count; ++i)
{
- if (hook_table.hooks[i].thread_id == thread_id)
- return &hook_table.hooks[i];
+ if (swapchain_state_table.hooks[i].thread_id == thread_id)
+ return &swapchain_state_table.hooks[i];
}
return NULL;
}
-void wined3d_hook_swapchain(struct wined3d_swapchain *swapchain)
+void wined3d_swapchain_state_register(struct wined3d_swapchain_state *state,
+ struct wined3d *wined3d)
{
- struct wined3d_hooked_swapchain *swapchain_entry;
+ struct wined3d_registered_swapchain_state *state_entry;
struct wined3d_window_hook *hook;
wined3d_wndproc_mutex_lock();
- if (!wined3d_array_reserve((void **)&hook_table.swapchains, &hook_table.swapchains_size,
- hook_table.swapchain_count + 1, sizeof(*swapchain_entry)))
+ if (!wined3d_array_reserve((void **)&swapchain_state_table.states, &swapchain_state_table.states_size,
+ swapchain_state_table.state_count + 1, sizeof(*state_entry)))
{
wined3d_wndproc_mutex_unlock();
return;
}
- swapchain_entry = &hook_table.swapchains[hook_table.swapchain_count++];
- swapchain_entry->swapchain = swapchain;
- swapchain_entry->thread_id = GetWindowThreadProcessId(swapchain->state.device_window, NULL);
+ state_entry = &swapchain_state_table.states[swapchain_state_table.state_count++];
+ state_entry->state = state;
+ state_entry->wined3d = wined3d;
+ state_entry->thread_id = GetWindowThreadProcessId(state->device_window, NULL);
- if ((hook = wined3d_find_hook(swapchain_entry->thread_id)))
+ if ((hook = wined3d_find_hook(state_entry->thread_id)))
{
++hook->count;
wined3d_wndproc_mutex_unlock();
return;
}
- if (!wined3d_array_reserve((void **)&hook_table.hooks, &hook_table.hooks_size,
- hook_table.hook_count + 1, sizeof(*hook)))
+ if (!wined3d_array_reserve((void **)&swapchain_state_table.hooks, &swapchain_state_table.hooks_size,
+ swapchain_state_table.hook_count + 1, sizeof(*hook)))
{
- --hook_table.swapchain_count;
+ --swapchain_state_table.state_count;
wined3d_wndproc_mutex_unlock();
return;
}
- hook = &hook_table.hooks[hook_table.hook_count++];
- hook->thread_id = swapchain_entry->thread_id;
+ hook = &swapchain_state_table.hooks[swapchain_state_table.hook_count++];
+ hook->thread_id = state_entry->thread_id;
hook->hook = SetWindowsHookExW(WH_GETMESSAGE, wined3d_hook_proc, 0, hook->thread_id);
hook->count = 1;
wined3d_wndproc_mutex_unlock();
}
-void wined3d_unhook_swapchain(struct wined3d_swapchain *swapchain)
+void wined3d_swapchain_state_unregister(struct wined3d_swapchain_state *state)
{
- struct wined3d_hooked_swapchain *swapchain_entry, *last_swapchain_entry;
+ struct wined3d_registered_swapchain_state *state_entry, *last_state_entry;
struct wined3d_window_hook *hook, *last_hook;
unsigned int i;
wined3d_wndproc_mutex_lock();
- for (i = 0; i < hook_table.swapchain_count; ++i)
+ for (i = 0; i < swapchain_state_table.state_count; ++i)
{
- swapchain_entry = &hook_table.swapchains[i];
+ state_entry = &swapchain_state_table.states[i];
- if (swapchain_entry->swapchain != swapchain)
+ if (state_entry->state != state)
continue;
- if ((hook = wined3d_find_hook(swapchain_entry->thread_id)) && !--hook->count)
+ if ((hook = wined3d_find_hook(state_entry->thread_id)) && !--hook->count)
{
UnhookWindowsHookEx(hook->hook);
- last_hook = &hook_table.hooks[--hook_table.hook_count];
+ last_hook = &swapchain_state_table.hooks[--swapchain_state_table.hook_count];
if (hook != last_hook)
*hook = *last_hook;
}
- last_swapchain_entry = &hook_table.swapchains[--hook_table.swapchain_count];
- if (swapchain_entry != last_swapchain_entry)
- *swapchain_entry = *last_swapchain_entry;
+ last_state_entry = &swapchain_state_table.states[--swapchain_state_table.state_count];
+ if (state_entry != last_state_entry)
+ *state_entry = *last_state_entry;
break;
}
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index d932f60fa95..bbb0a60d7bb 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -3522,9 +3522,7 @@ struct wined3d
};
BOOL wined3d_filter_messages(HWND window, BOOL filter) DECLSPEC_HIDDEN;
-void wined3d_hook_swapchain(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
HRESULT wined3d_init(struct wined3d *wined3d, DWORD flags) DECLSPEC_HIDDEN;
-void wined3d_unhook_swapchain(struct wined3d_swapchain *swapchain) DECLSPEC_HIDDEN;
void wined3d_unregister_window(HWND window) DECLSPEC_HIDDEN;
BOOL wined3d_get_app_name(char *app_name, unsigned int app_name_size) DECLSPEC_HIDDEN;
@@ -5082,10 +5080,13 @@ struct wined3d_swapchain_state
HWND device_window;
};
+void wined3d_swapchain_state_register(struct wined3d_swapchain_state *state,
+ struct wined3d *wined3d) DECLSPEC_HIDDEN;
void wined3d_swapchain_state_restore_from_fullscreen(struct wined3d_swapchain_state *state,
HWND window, const RECT *window_rect) DECLSPEC_HIDDEN;
HRESULT wined3d_swapchain_state_setup_fullscreen(struct wined3d_swapchain_state *state,
HWND window, int x, int y, int width, int height) DECLSPEC_HIDDEN;
+void wined3d_swapchain_state_unregister(struct wined3d_swapchain_state *state) DECLSPEC_HIDDEN;
struct wined3d_swapchain_ops
{
diff --git a/include/wine/wined3d.h b/include/wine/wined3d.h
index 238961006a0..61ab0e90953 100644
--- a/include/wine/wined3d.h
+++ b/include/wine/wined3d.h
@@ -904,7 +904,7 @@ enum wined3d_shader_type
#define WINED3D_SWAPCHAIN_RESTORE_WINDOW_RECT 0x00004000u
#define WINED3D_SWAPCHAIN_GDI_COMPATIBLE 0x00008000u
#define WINED3D_SWAPCHAIN_IMPLICIT 0x00010000u
-#define WINED3D_SWAPCHAIN_HOOK 0x00020000u
+#define WINED3D_SWAPCHAIN_REGISTER_STATE 0x00020000u
#define WINED3D_SWAPCHAIN_NO_WINDOW_CHANGES 0x00040000u
#define WINED3D_SWAPCHAIN_RESTORE_WINDOW_STATE 0x00080000u
@@ -2804,7 +2804,7 @@ void __cdecl wined3d_swapchain_set_palette(struct wined3d_swapchain *swapchain,
void __cdecl wined3d_swapchain_set_window(struct wined3d_swapchain *swapchain, HWND window);
HRESULT __cdecl wined3d_swapchain_state_create(const struct wined3d_swapchain_desc *desc,
- HWND window, struct wined3d_swapchain_state **state);
+ HWND window, struct wined3d *wined3d, struct wined3d_swapchain_state **state);
void __cdecl wined3d_swapchain_state_destroy(struct wined3d_swapchain_state *state);
BOOL __cdecl wined3d_swapchain_state_is_windowed(const struct wined3d_swapchain_state *state);
HRESULT __cdecl wined3d_swapchain_state_resize_target(struct wined3d_swapchain_state *state,
--
2.25.1
2
1
https://bugs.winehq.org/show_bug.cgi?id=49966
Signed-off-by: Louis Lenders <xerox.xerox2000x(a)gmail.com>
---
dlls/kernelbase/debug.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/kernelbase/debug.c b/dlls/kernelbase/debug.c
index 6acdf0f1ea..0382ea9f95 100644
--- a/dlls/kernelbase/debug.c
+++ b/dlls/kernelbase/debug.c
@@ -819,7 +819,7 @@ HRESULT WINAPI /* DECLSPEC_HOTPATCH */ WerRegisterRuntimeExceptionModule( const
HRESULT WINAPI /* DECLSPEC_HOTPATCH */ WerSetFlags( DWORD flags )
{
FIXME("(%d) stub\n", flags);
- return E_NOTIMPL;
+ return S_OK;
}
--
2.28.0
1
0
[PATCH vkd3d 1/3] vkd3d-shader: Pass the output pointer to vkd3d_shader_message_context_copy_messages().
by Zebediah Figura Oct. 9, 2020
by Zebediah Figura Oct. 9, 2020
Oct. 9, 2020
Signed-off-by: Zebediah Figura <zfigura(a)codeweavers.com>
---
libs/vkd3d-shader/dxbc.c | 4 ++--
libs/vkd3d-shader/vkd3d_shader_main.c | 20 +++++++++++++-------
libs/vkd3d-shader/vkd3d_shader_private.h | 3 ++-
3 files changed, 17 insertions(+), 10 deletions(-)
diff --git a/libs/vkd3d-shader/dxbc.c b/libs/vkd3d-shader/dxbc.c
index 93e7eaf5..3ddca1e9 100644
--- a/libs/vkd3d-shader/dxbc.c
+++ b/libs/vkd3d-shader/dxbc.c
@@ -2786,7 +2786,7 @@ int vkd3d_shader_parse_root_signature(const struct vkd3d_shader_code *dxbc,
ret = parse_dxbc(dxbc->code, dxbc->size, &message_context, rts0_handler, root_signature);
vkd3d_shader_message_context_trace_messages(&message_context);
- if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(&message_context)))
+ if (!vkd3d_shader_message_context_copy_messages(&message_context, messages))
ret = VKD3D_ERROR_OUT_OF_MEMORY;
vkd3d_shader_message_context_cleanup(&message_context);
@@ -3390,7 +3390,7 @@ int vkd3d_shader_serialize_root_signature(const struct vkd3d_shader_versioned_ro
done:
vkd3d_shader_message_context_trace_messages(&context.message_context);
- if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(&context.message_context)))
+ if (!vkd3d_shader_message_context_copy_messages(&context.message_context, messages))
ret = VKD3D_ERROR_OUT_OF_MEMORY;
vkd3d_shader_message_context_cleanup(&context.message_context);
return ret;
diff --git a/libs/vkd3d-shader/vkd3d_shader_main.c b/libs/vkd3d-shader/vkd3d_shader_main.c
index c2fe2c8e..d3d86ed7 100644
--- a/libs/vkd3d-shader/vkd3d_shader_main.c
+++ b/libs/vkd3d-shader/vkd3d_shader_main.c
@@ -140,14 +140,20 @@ void vkd3d_shader_message_context_trace_messages_(const struct vkd3d_shader_mess
vkd3d_string_buffer_trace_(&context->messages, function);
}
-char *vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_context *context)
+bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_context *context, char **out)
{
char *messages;
- if ((messages = vkd3d_malloc(context->messages.content_size + 1)))
- memcpy(messages, context->messages.buffer, context->messages.content_size + 1);
+ if (!out)
+ return true;
- return messages;
+ *out = NULL;
+
+ if (!(messages = vkd3d_malloc(context->messages.content_size + 1)))
+ return false;
+ memcpy(messages, context->messages.buffer, context->messages.content_size + 1);
+ *out = messages;
+ return true;
}
void vkd3d_shader_verror(struct vkd3d_shader_message_context *context,
@@ -842,7 +848,7 @@ int vkd3d_shader_scan(const struct vkd3d_shader_compile_info *compile_info, char
ret = scan_dxbc(compile_info, &message_context);
vkd3d_shader_message_context_trace_messages(&message_context);
- if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(&message_context)))
+ if (!vkd3d_shader_message_context_copy_messages(&message_context, messages))
ret = VKD3D_ERROR_OUT_OF_MEMORY;
vkd3d_shader_message_context_cleanup(&message_context);
return ret;
@@ -956,7 +962,7 @@ int vkd3d_shader_compile(const struct vkd3d_shader_compile_info *compile_info,
}
vkd3d_shader_message_context_trace_messages(&message_context);
- if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(&message_context)))
+ if (!vkd3d_shader_message_context_copy_messages(&message_context, messages))
ret = VKD3D_ERROR_OUT_OF_MEMORY;
vkd3d_shader_message_context_cleanup(&message_context);
return ret;
@@ -1046,7 +1052,7 @@ int vkd3d_shader_parse_input_signature(const struct vkd3d_shader_code *dxbc,
ret = shader_parse_input_signature(dxbc->code, dxbc->size, &message_context, signature);
vkd3d_shader_message_context_trace_messages(&message_context);
- if (messages && !(*messages = vkd3d_shader_message_context_copy_messages(&message_context)))
+ if (!vkd3d_shader_message_context_copy_messages(&message_context, messages))
ret = VKD3D_ERROR_OUT_OF_MEMORY;
vkd3d_shader_message_context_cleanup(&message_context);
diff --git a/libs/vkd3d-shader/vkd3d_shader_private.h b/libs/vkd3d-shader/vkd3d_shader_private.h
index f88ea69a..98b5fbc4 100644
--- a/libs/vkd3d-shader/vkd3d_shader_private.h
+++ b/libs/vkd3d-shader/vkd3d_shader_private.h
@@ -848,7 +848,8 @@ struct vkd3d_shader_message_context
};
void vkd3d_shader_message_context_cleanup(struct vkd3d_shader_message_context *context) DECLSPEC_HIDDEN;
-char *vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_context *context) DECLSPEC_HIDDEN;
+bool vkd3d_shader_message_context_copy_messages(struct vkd3d_shader_message_context *context,
+ char **out) DECLSPEC_HIDDEN;
bool vkd3d_shader_message_context_init(struct vkd3d_shader_message_context *context,
enum vkd3d_shader_log_level log_level, const char *source_name) DECLSPEC_HIDDEN;
void vkd3d_shader_message_context_trace_messages_(const struct vkd3d_shader_message_context *context,
--
2.28.0
1
2
Oct. 9, 2020
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/ntdll/thread.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/thread.c b/dlls/ntdll/thread.c
index cf6bddab0b4..95511391d34 100644
--- a/dlls/ntdll/thread.c
+++ b/dlls/ntdll/thread.c
@@ -392,7 +392,7 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsFree( ULONG index )
{
unsigned int chunk_index, idx;
FLS_INFO_CHUNK *chunk;
- TEB_FLS_DATA *fls;
+ LIST_ENTRY *entry;
lock_fls_data();
@@ -410,10 +410,15 @@ NTSTATUS WINAPI DECLSPEC_HOTPATCH RtlFlsFree( ULONG index )
return STATUS_INVALID_PARAMETER;
}
- if ((fls = NtCurrentTeb()->FlsSlots) && fls->fls_data_chunks[chunk_index])
+ for (entry = fls_data.fls_list_head.Flink; entry != &fls_data.fls_list_head; entry = entry->Flink)
{
- /* FIXME: call Fls callback */
- fls->fls_data_chunks[chunk_index][idx + 1] = NULL;
+ TEB_FLS_DATA *fls = CONTAINING_RECORD(entry, TEB_FLS_DATA, fls_list_entry);
+
+ if (fls->fls_data_chunks[chunk_index])
+ {
+ /* FIXME: call Fls callback */
+ fls->fls_data_chunks[chunk_index][idx + 1] = NULL;
+ }
}
--chunk->count;
--
2.26.2
2
2