Wine-devel
Threads by month
- ----- 2026 -----
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
December 2021
- 85 participants
- 585 discussions
[PATCH] ntdll: Remove a special case for EP not in executable section in map_image_into_view().
by Paul Gofman 08 Dec '21
by Paul Gofman 08 Dec '21
08 Dec '21
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
It is a very old hack and testing shows that there is no special case on Windows for entry
point being inside the section without execute flag. My guess is that maybe this
was introduced before 'force_exec_prot' (NtSetInformationProcess(ProcessExecuteFlags) or
IMAGE_DLLCHARACTERISTICS_NX_COMPAT were properly supported.
dlls/kernel32/tests/loader.c | 18 +++++++++++-------
dlls/ntdll/unix/virtual.c | 5 -----
2 files changed, 11 insertions(+), 12 deletions(-)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c
index 4f1b11338a6..308cf1a44a0 100644
--- a/dlls/kernel32/tests/loader.c
+++ b/dlls/kernel32/tests/loader.c
@@ -1967,12 +1967,6 @@ static void test_section_access(void)
nt_header.OptionalHeader.FileAlignment = 0x200;
nt_header.OptionalHeader.SizeOfImage = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER) + page_size;
nt_header.OptionalHeader.SizeOfHeaders = sizeof(dos_header) + sizeof(nt_header) + sizeof(IMAGE_SECTION_HEADER);
- SetLastError(0xdeadbeef);
- ret = WriteFile(hfile, &nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL);
- ok(ret, "WriteFile error %d\n", GetLastError());
- SetLastError(0xdeadbeef);
- ret = WriteFile(hfile, &nt_header.OptionalHeader, sizeof(IMAGE_OPTIONAL_HEADER), &dummy, NULL);
- ok(ret, "WriteFile error %d\n", GetLastError());
section.SizeOfRawData = sizeof(section_data);
section.PointerToRawData = nt_header.OptionalHeader.FileAlignment;
@@ -1980,6 +1974,16 @@ static void test_section_access(void)
section.Misc.VirtualSize = section.SizeOfRawData;
section.Characteristics = td[i].scn_file_access;
SetLastError(0xdeadbeef);
+
+ nt_header.OptionalHeader.AddressOfEntryPoint = section.VirtualAddress;
+
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, &nt_header, sizeof(DWORD) + sizeof(IMAGE_FILE_HEADER), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+ SetLastError(0xdeadbeef);
+ ret = WriteFile(hfile, &nt_header.OptionalHeader, sizeof(IMAGE_OPTIONAL_HEADER), &dummy, NULL);
+ ok(ret, "WriteFile error %d\n", GetLastError());
+
ret = WriteFile(hfile, §ion, sizeof(section), &dummy, NULL);
ok(ret, "WriteFile error %d\n", GetLastError());
@@ -1997,7 +2001,7 @@ static void test_section_access(void)
CloseHandle(hfile);
SetLastError(0xdeadbeef);
- hlib = LoadLibraryA(dll_name);
+ hlib = LoadLibraryExA(dll_name, NULL, DONT_RESOLVE_DLL_REFERENCES);
ok(hlib != 0, "LoadLibrary error %d\n", GetLastError());
SetLastError(0xdeadbeef);
diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c
index 5873a3e2335..dfd61546597 100644
--- a/dlls/ntdll/unix/virtual.c
+++ b/dlls/ntdll/unix/virtual.c
@@ -2409,11 +2409,6 @@ static NTSTATUS map_image_into_view( struct file_view *view, const WCHAR *filena
if (sec->Characteristics & IMAGE_SCN_MEM_WRITE) vprot |= VPROT_WRITECOPY;
if (sec->Characteristics & IMAGE_SCN_MEM_EXECUTE) vprot |= VPROT_EXEC;
- /* Dumb game crack lets the AOEP point into a data section. Adjust. */
- if ((nt->OptionalHeader.AddressOfEntryPoint >= sec->VirtualAddress) &&
- (nt->OptionalHeader.AddressOfEntryPoint < sec->VirtualAddress + size))
- vprot |= VPROT_EXEC;
-
if (!set_vprot( view, ptr + sec->VirtualAddress, size, vprot ) && (vprot & VPROT_EXEC))
ERR( "failed to set %08x protection on %s section %.8s, noexec filesystem?\n",
sec->Characteristics, debugstr_w(filename), sec->Name );
--
2.33.1
1
0
[PATCH] msvcp120/tests: Check handle validity in test_thrd, not handle equality
by Alex Henrie 08 Dec '21
by Alex Henrie 08 Dec '21
08 Dec '21
Fixes an intermittent testbot failure.
Signed-off-by: Alex Henrie <alexhenrie24(a)gmail.com>
---
dlls/msvcp120/tests/msvcp120.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/dlls/msvcp120/tests/msvcp120.c b/dlls/msvcp120/tests/msvcp120.c
index 495ee9dd6fb..6bc636c4b1f 100644
--- a/dlls/msvcp120/tests/msvcp120.c
+++ b/dlls/msvcp120/tests/msvcp120.c
@@ -2093,8 +2093,9 @@ static void test_thrd(void)
tb = p__Thrd_current();
ok(ta.id == tb.id, "got a %d b %d\n", ta.id, tb.id);
ok(ta.id == GetCurrentThreadId(), "expected %d, got %d\n", GetCurrentThreadId(), ta.id);
- /* these can be different if new threads are created at same time */
- ok(ta.hnd == tb.hnd, "got a %p b %p\n", ta.hnd, tb.hnd);
+ /* the handles can be different if new threads are created at same time */
+ ok(ta.hnd != NULL, "handle a is NULL\n");
+ ok(tb.hnd != NULL, "handle b is NULL\n");
ok(!CloseHandle(ta.hnd), "handle %p not closed\n", ta.hnd);
ok(!CloseHandle(tb.hnd), "handle %p not closed\n", tb.hnd);
--
2.34.1
2
1
The following series supercedes previous (v3) which has been partially
applied (contains non applied patches of (v3), plus a couple of
improvements)
This serie:
- improves WineDbg parsing (no more bison warnings)
- module scoping (in the form module!name) now allows wildcards in module
part
- get/set on integers is fully supported (even on bitfields, including
integral conversions)
- get/set on floats is fully supported (including float/double conversions)
- WineDbg now can access types from debuggee in its own expressions, as
well as pointer types to debuggee's type, even if the debuggee doesn't
provide them
- type definition can be explored (extending print command with type
eg. 'p HANDLE' gives 'typedef HANDLE => void*')
- implements DbgHelp.SymEnumTypeFromName(W)
- fixes a couple of bugs
A+
---
Eric Pouech (19):
programs/winedbg: let type_print_hex use dbg_lgint_t as its parameter type
programs/winedbg: rename print_longlong into print_sdecimal (to mimic print_hex)
programs/winedbg: revamp dbg_lvalue structure and add helpers for init
programs/winedbg: add bitfield capability to dbg_lvalue
programs/winedbg: move bitfield extraction to extract_lgint
dbghelp: in SymGetTypeInfo(), return the correct basetype for enums
programs/winedbg: add helper to compare types and use it to detect wrong assigments
programs/winedbg: add helper to transfer memory between lvalues
programs/winedbg: correctly store integers into a bitfield
programs/winedbg: remove fetch_float() method from CPU backends
programs/winedbg: implement proper assignements of floating point numbers
programs/winedbg: move C++ identifier detection in the lexer
programs/winedbg: move module scoping inside lexer
dbghelp: implement SymEnumTypesByName(W)
programs/winedbg: cache pointer type:s
programs/winedbg: move type lookup at parsing time for cast operation
programs/winedbg: added 'print type <TYPE>' command
programs/winedbg: only call HeapFree on rightfully obtained buffers
programs/winedbg: remove FORCE_DEREF expressions
dlls/dbghelp/dbghelp.spec | 4 +-
dlls/dbghelp/type.c | 119 ++++++++-
include/dbghelp.h | 2 +
programs/winedbg/be_arm.c | 18 --
programs/winedbg/be_arm64.c | 18 --
programs/winedbg/be_cpu.h | 3 -
programs/winedbg/be_i386.c | 18 --
programs/winedbg/be_x86_64.c | 18 --
programs/winedbg/break.c | 4 +-
programs/winedbg/dbg.y | 78 +++---
programs/winedbg/debug.l | 12 +-
programs/winedbg/debugger.h | 69 ++---
programs/winedbg/expr.c | 139 ++--------
programs/winedbg/expr.h | 1 -
programs/winedbg/memory.c | 161 +++++++++--
programs/winedbg/stack.c | 4 +-
programs/winedbg/symbol.c | 21 +-
programs/winedbg/types.c | 499 +++++++++++++++++++++++++----------
programs/winedbg/winedbg.c | 9 +-
19 files changed, 734 insertions(+), 463 deletions(-)
1
19
This fixes LLVM ASAN an the ASAN then works as expected with Wine.
Would something like this be acceptable for upstream?
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=50993
Signed-off-by: Roman Pišl <rpisl(a)seznam.cz>
---
dlls/ntdll/string.c | 98 ++++++++++++++++++++++-----------------------
1 file changed, 49 insertions(+), 49 deletions(-)
diff --git a/dlls/ntdll/string.c b/dlls/ntdll/string.c
index 0fa83821d21..7370bf3631b 100644
--- a/dlls/ntdll/string.c
+++ b/dlls/ntdll/string.c
@@ -69,7 +69,7 @@ static const unsigned short ctypes[257] =
/*********************************************************************
* memchr (NTDLL.@)
*/
-void * __cdecl memchr( const void *ptr, int c, size_t n )
+void * __cdecl DECLSPEC_HOTPATCH memchr( const void *ptr, int c, size_t n )
{
const unsigned char *p = ptr;
@@ -81,7 +81,7 @@ void * __cdecl memchr( const void *ptr, int c, size_t n )
/*********************************************************************
* memcmp (NTDLL.@)
*/
-int __cdecl memcmp( const void *ptr1, const void *ptr2, size_t n )
+int __cdecl DECLSPEC_HOTPATCH memcmp( const void *ptr1, const void *ptr2, size_t n )
{
const unsigned char *p1, *p2;
@@ -100,7 +100,7 @@ int __cdecl memcmp( const void *ptr1, const void *ptr2, size_t n )
* NOTES
* Behaves like memmove.
*/
-void * __cdecl memcpy( void *dst, const void *src, size_t n )
+void * __cdecl DECLSPEC_HOTPATCH memcpy( void *dst, const void *src, size_t n )
{
volatile unsigned char *d = dst; /* avoid gcc optimizations */
const unsigned char *s = src;
@@ -122,7 +122,7 @@ void * __cdecl memcpy( void *dst, const void *src, size_t n )
/*********************************************************************
* memmove (NTDLL.@)
*/
-void * __cdecl memmove( void *dst, const void *src, size_t n )
+void * __cdecl DECLSPEC_HOTPATCH memmove( void *dst, const void *src, size_t n )
{
volatile unsigned char *d = dst; /* avoid gcc optimizations */
const unsigned char *s = src;
@@ -157,7 +157,7 @@ static inline void memset_aligned_32( unsigned char *d, uint64_t v, size_t n )
/*********************************************************************
* memset (NTDLL.@)
*/
-void *__cdecl memset( void *dst, int c, size_t n )
+void *__cdecl DECLSPEC_HOTPATCH memset( void *dst, int c, size_t n )
{
typedef uint64_t DECLSPEC_ALIGN(1) unaligned_ui64;
typedef uint32_t DECLSPEC_ALIGN(1) unaligned_ui32;
@@ -214,7 +214,7 @@ void *__cdecl memset( void *dst, int c, size_t n )
/*********************************************************************
* strcat (NTDLL.@)
*/
-char * __cdecl strcat( char *dst, const char *src )
+char * __cdecl DECLSPEC_HOTPATCH strcat( char *dst, const char *src )
{
char *d = dst;
while (*d) d++;
@@ -226,7 +226,7 @@ char * __cdecl strcat( char *dst, const char *src )
/*********************************************************************
* strchr (NTDLL.@)
*/
-char * __cdecl strchr( const char *str, int c )
+char * __cdecl DECLSPEC_HOTPATCH strchr( const char *str, int c )
{
do { if (*str == (char)c) return (char *)(ULONG_PTR)str; } while (*str++);
return NULL;
@@ -236,7 +236,7 @@ char * __cdecl strchr( const char *str, int c )
/*********************************************************************
* strcmp (NTDLL.@)
*/
-int __cdecl strcmp( const char *str1, const char *str2 )
+int __cdecl DECLSPEC_HOTPATCH strcmp( const char *str1, const char *str2 )
{
while (*str1 && *str1 == *str2) { str1++; str2++; }
if ((unsigned char)*str1 > (unsigned char)*str2) return 1;
@@ -248,7 +248,7 @@ int __cdecl strcmp( const char *str1, const char *str2 )
/*********************************************************************
* strcpy (NTDLL.@)
*/
-char * __cdecl strcpy( char *dst, const char *src )
+char * __cdecl DECLSPEC_HOTPATCH strcpy( char *dst, const char *src )
{
char *d = dst;
while ((*d++ = *src++));
@@ -259,7 +259,7 @@ char * __cdecl strcpy( char *dst, const char *src )
/*********************************************************************
* strcspn (NTDLL.@)
*/
-size_t __cdecl strcspn( const char *str, const char *reject )
+size_t __cdecl DECLSPEC_HOTPATCH strcspn( const char *str, const char *reject )
{
const char *ptr;
for (ptr = str; *ptr; ptr++) if (strchr( reject, *ptr )) break;
@@ -270,7 +270,7 @@ size_t __cdecl strcspn( const char *str, const char *reject )
/*********************************************************************
* strlen (NTDLL.@)
*/
-size_t __cdecl strlen( const char *str )
+size_t __cdecl DECLSPEC_HOTPATCH strlen( const char *str )
{
const char *s = str;
while (*s) s++;
@@ -281,7 +281,7 @@ size_t __cdecl strlen( const char *str )
/*********************************************************************
* strncat (NTDLL.@)
*/
-char * __cdecl strncat( char *dst, const char *src, size_t len )
+char * __cdecl DECLSPEC_HOTPATCH strncat( char *dst, const char *src, size_t len )
{
char *d = dst;
while (*d) d++;
@@ -294,7 +294,7 @@ char * __cdecl strncat( char *dst, const char *src, size_t len )
/*********************************************************************
* strncmp (NTDLL.@)
*/
-int __cdecl strncmp( const char *str1, const char *str2, size_t len )
+int __cdecl DECLSPEC_HOTPATCH strncmp( const char *str1, const char *str2, size_t len )
{
if (!len) return 0;
while (--len && *str1 && *str1 == *str2) { str1++; str2++; }
@@ -306,7 +306,7 @@ int __cdecl strncmp( const char *str1, const char *str2, size_t len )
* strncpy (NTDLL.@)
*/
#undef strncpy
-char * __cdecl strncpy( char *dst, const char *src, size_t len )
+char * __cdecl DECLSPEC_HOTPATCH strncpy( char *dst, const char *src, size_t len )
{
char *d;
for (d = dst; len && *src; d++, src++, len--) *d = *src;
@@ -318,7 +318,7 @@ char * __cdecl strncpy( char *dst, const char *src, size_t len )
/*********************************************************************
* strnlen (NTDLL.@)
*/
-size_t __cdecl strnlen( const char *str, size_t len )
+size_t __cdecl DECLSPEC_HOTPATCH strnlen( const char *str, size_t len )
{
const char *s = str;
for (s = str; len && *s; s++, len--) ;
@@ -329,7 +329,7 @@ size_t __cdecl strnlen( const char *str, size_t len )
/*********************************************************************
* strpbrk (NTDLL.@)
*/
-char * __cdecl strpbrk( const char *str, const char *accept )
+char * __cdecl DECLSPEC_HOTPATCH strpbrk( const char *str, const char *accept )
{
for ( ; *str; str++) if (strchr( accept, *str )) return (char *)(ULONG_PTR)str;
return NULL;
@@ -339,7 +339,7 @@ char * __cdecl strpbrk( const char *str, const char *accept )
/*********************************************************************
* strrchr (NTDLL.@)
*/
-char * __cdecl strrchr( const char *str, int c )
+char * __cdecl DECLSPEC_HOTPATCH strrchr( const char *str, int c )
{
char *ret = NULL;
do { if (*str == (char)c) ret = (char *)(ULONG_PTR)str; } while (*str++);
@@ -350,7 +350,7 @@ char * __cdecl strrchr( const char *str, int c )
/*********************************************************************
* strspn (NTDLL.@)
*/
-size_t __cdecl strspn( const char *str, const char *accept )
+size_t __cdecl DECLSPEC_HOTPATCH strspn( const char *str, const char *accept )
{
const char *ptr;
for (ptr = str; *ptr; ptr++) if (!strchr( accept, *ptr )) break;
@@ -361,7 +361,7 @@ size_t __cdecl strspn( const char *str, const char *accept )
/*********************************************************************
* strstr (NTDLL.@)
*/
-char * __cdecl strstr( const char *str, const char *sub )
+char * __cdecl DECLSPEC_HOTPATCH strstr( const char *str, const char *sub )
{
while (*str)
{
@@ -377,7 +377,7 @@ char * __cdecl strstr( const char *str, const char *sub )
/*********************************************************************
* _memccpy (NTDLL.@)
*/
-void * __cdecl _memccpy( void *dst, const void *src, int c, size_t n )
+void * __cdecl DECLSPEC_HOTPATCH _memccpy( void *dst, const void *src, int c, size_t n )
{
unsigned char *d = dst;
const unsigned char *s = src;
@@ -389,7 +389,7 @@ void * __cdecl _memccpy( void *dst, const void *src, int c, size_t n )
/*********************************************************************
* tolower (NTDLL.@)
*/
-int __cdecl tolower( int c )
+int __cdecl DECLSPEC_HOTPATCH tolower( int c )
{
return (char)c >= 'A' && (char)c <= 'Z' ? c - 'A' + 'a' : c;
}
@@ -413,7 +413,7 @@ int __cdecl tolower( int c )
* Any Nul characters in s1 or s2 are ignored. This function always
* compares up to len bytes or the first place where s1 and s2 differ.
*/
-int __cdecl _memicmp( const void *str1, const void *str2, size_t len )
+int __cdecl DECLSPEC_HOTPATCH _memicmp( const void *str1, const void *str2, size_t len )
{
const unsigned char *s1 = str1, *s2 = str2;
int ret = 0;
@@ -430,7 +430,7 @@ int __cdecl _memicmp( const void *str1, const void *str2, size_t len )
/*********************************************************************
* _strnicmp (NTDLL.@)
*/
-int __cdecl _strnicmp( LPCSTR str1, LPCSTR str2, size_t n )
+int __cdecl DECLSPEC_HOTPATCH _strnicmp( LPCSTR str1, LPCSTR str2, size_t n )
{
int l1, l2;
@@ -455,7 +455,7 @@ int __cdecl _strnicmp( LPCSTR str1, LPCSTR str2, size_t n )
* _stricmp (NTDLL.@)
* _strcmpi (NTDLL.@)
*/
-int __cdecl _stricmp( LPCSTR str1, LPCSTR str2 )
+int __cdecl DECLSPEC_HOTPATCH _stricmp( LPCSTR str1, LPCSTR str2 )
{
return _strnicmp( str1, str2, -1 );
}
@@ -473,7 +473,7 @@ int __cdecl _stricmp( LPCSTR str1, LPCSTR str2 )
* str. There is no error return, if str is NULL or invalid, this
* function will crash.
*/
-LPSTR __cdecl _strupr( LPSTR str )
+LPSTR __cdecl DECLSPEC_HOTPATCH _strupr( LPSTR str )
{
LPSTR ret = str;
for ( ; *str; str++) *str = RtlUpperChar(*str);
@@ -493,7 +493,7 @@ LPSTR __cdecl _strupr( LPSTR str )
* str. There is no error return, if str is NULL or invalid, this
* function will crash.
*/
-LPSTR __cdecl _strlwr( LPSTR str )
+LPSTR __cdecl DECLSPEC_HOTPATCH _strlwr( LPSTR str )
{
LPSTR ret = str;
for ( ; *str; str++) *str = tolower(*str);
@@ -504,7 +504,7 @@ LPSTR __cdecl _strlwr( LPSTR str )
/*********************************************************************
* toupper (NTDLL.@)
*/
-int __cdecl toupper( int c )
+int __cdecl DECLSPEC_HOTPATCH toupper( int c )
{
char str[2], *p = str;
WCHAR wc;
@@ -523,7 +523,7 @@ int __cdecl toupper( int c )
/*********************************************************************
* isalnum (NTDLL.@)
*/
-int __cdecl isalnum( int c )
+int __cdecl DECLSPEC_HOTPATCH isalnum( int c )
{
return ctypes[c + 1] & (C1_LOWER | C1_UPPER | C1_DIGIT);
}
@@ -532,7 +532,7 @@ int __cdecl isalnum( int c )
/*********************************************************************
* isalpha (NTDLL.@)
*/
-int __cdecl isalpha( int c )
+int __cdecl DECLSPEC_HOTPATCH isalpha( int c )
{
return ctypes[c + 1] & (C1_LOWER | C1_UPPER);
}
@@ -541,7 +541,7 @@ int __cdecl isalpha( int c )
/*********************************************************************
* iscntrl (NTDLL.@)
*/
-int __cdecl iscntrl( int c )
+int __cdecl DECLSPEC_HOTPATCH iscntrl( int c )
{
return ctypes[c + 1] & C1_CNTRL;
}
@@ -550,7 +550,7 @@ int __cdecl iscntrl( int c )
/*********************************************************************
* isdigit (NTDLL.@)
*/
-int __cdecl isdigit( int c )
+int __cdecl DECLSPEC_HOTPATCH isdigit( int c )
{
return ctypes[c + 1] & C1_DIGIT;
}
@@ -559,7 +559,7 @@ int __cdecl isdigit( int c )
/*********************************************************************
* isgraph (NTDLL.@)
*/
-int __cdecl isgraph( int c )
+int __cdecl DECLSPEC_HOTPATCH isgraph( int c )
{
return ctypes[c + 1] & (C1_LOWER | C1_UPPER | C1_DIGIT | C1_PUNCT);
}
@@ -568,7 +568,7 @@ int __cdecl isgraph( int c )
/*********************************************************************
* islower (NTDLL.@)
*/
-int __cdecl islower( int c )
+int __cdecl DECLSPEC_HOTPATCH islower( int c )
{
return ctypes[c + 1] & C1_LOWER;
}
@@ -577,7 +577,7 @@ int __cdecl islower( int c )
/*********************************************************************
* isprint (NTDLL.@)
*/
-int __cdecl isprint( int c )
+int __cdecl DECLSPEC_HOTPATCH isprint( int c )
{
return ctypes[c + 1] & (C1_LOWER | C1_UPPER | C1_DIGIT | C1_PUNCT | C1_BLANK);
}
@@ -586,7 +586,7 @@ int __cdecl isprint( int c )
/*********************************************************************
* ispunct (NTDLL.@)
*/
-int __cdecl ispunct( int c )
+int __cdecl DECLSPEC_HOTPATCH ispunct( int c )
{
return ctypes[c + 1] & C1_PUNCT;
}
@@ -595,7 +595,7 @@ int __cdecl ispunct( int c )
/*********************************************************************
* isspace (NTDLL.@)
*/
-int __cdecl isspace( int c )
+int __cdecl DECLSPEC_HOTPATCH isspace( int c )
{
return ctypes[c + 1] & C1_SPACE;
}
@@ -604,7 +604,7 @@ int __cdecl isspace( int c )
/*********************************************************************
* isupper (NTDLL.@)
*/
-int __cdecl isupper( int c )
+int __cdecl DECLSPEC_HOTPATCH isupper( int c )
{
return ctypes[c + 1] & C1_UPPER;
}
@@ -613,7 +613,7 @@ int __cdecl isupper( int c )
/*********************************************************************
* isxdigit (NTDLL.@)
*/
-int __cdecl isxdigit( int c )
+int __cdecl DECLSPEC_HOTPATCH isxdigit( int c )
{
return ctypes[c + 1] & C1_XDIGIT;
}
@@ -684,7 +684,7 @@ static int char_to_int( char c )
/*********************************************************************
* strtol (NTDLL.@)
*/
-__msvcrt_long __cdecl strtol( const char *s, char **end, int base )
+__msvcrt_long __cdecl DECLSPEC_HOTPATCH strtol( const char *s, char **end, int base )
{
BOOL negative = FALSE, empty = TRUE;
LONG ret = 0;
@@ -731,7 +731,7 @@ __msvcrt_long __cdecl strtol( const char *s, char **end, int base )
/*********************************************************************
* strtoul (NTDLL.@)
*/
-__msvcrt_ulong __cdecl strtoul( const char *s, char **end, int base )
+__msvcrt_ulong __cdecl DECLSPEC_HOTPATCH strtoul( const char *s, char **end, int base )
{
BOOL negative = FALSE, empty = TRUE;
ULONG ret = 0;
@@ -786,7 +786,7 @@ __msvcrt_ulong __cdecl strtoul( const char *s, char **end, int base )
* - Does not check if radix is in the range of 2 to 36.
* - If str is NULL it crashes, as the native function does.
*/
-char * __cdecl _ultoa( __msvcrt_ulong value, char *str, int radix )
+char * __cdecl DECLSPEC_HOTPATCH _ultoa( __msvcrt_ulong value, char *str, int radix )
{
char buffer[33];
char *pos;
@@ -825,7 +825,7 @@ char * __cdecl _ultoa( __msvcrt_ulong value, char *str, int radix )
* - Does not check if radix is in the range of 2 to 36.
* - If str is NULL it crashes, as the native function does.
*/
-char * __cdecl _ltoa( __msvcrt_long value, char *str, int radix )
+char * __cdecl DECLSPEC_HOTPATCH _ltoa( __msvcrt_long value, char *str, int radix )
{
ULONG val;
int negative;
@@ -878,7 +878,7 @@ char * __cdecl _ltoa( __msvcrt_long value, char *str, int radix )
* - Does not check if radix is in the range of 2 to 36.
* - If str is NULL it crashes, as the native function does.
*/
-char * __cdecl _itoa(
+char * __cdecl DECLSPEC_HOTPATCH _itoa(
int value, /* [I] Value to be converted */
char *str, /* [O] Destination for the converted value */
int radix) /* [I] Number base for conversion */
@@ -901,7 +901,7 @@ char * __cdecl _itoa(
* - Does not check if radix is in the range of 2 to 36.
* - If str is NULL it crashes, as the native function does.
*/
-char * __cdecl _ui64toa(
+char * __cdecl DECLSPEC_HOTPATCH _ui64toa(
ULONGLONG value, /* [I] Value to be converted */
char *str, /* [O] Destination for the converted value */
int radix) /* [I] Number base for conversion */
@@ -952,7 +952,7 @@ char * __cdecl _ui64toa(
* The native msvcrt _i64toa function and our ntdll _i64toa function
* do not have this bug.
*/
-char * __cdecl _i64toa(
+char * __cdecl DECLSPEC_HOTPATCH _i64toa(
LONGLONG value, /* [I] Value to be converted */
char *str, /* [O] Destination for the converted value */
int radix) /* [I] Number base for conversion */
@@ -1011,7 +1011,7 @@ char * __cdecl _i64toa(
* - No check is made for value overflow, only the lower 64 bits are assigned.
* - If str is NULL it crashes, as the native function does.
*/
-LONGLONG __cdecl _atoi64( const char *str )
+LONGLONG __cdecl DECLSPEC_HOTPATCH _atoi64( const char *str )
{
ULONGLONG RunningTotal = 0;
BOOL bMinus = FALSE;
@@ -1039,7 +1039,7 @@ LONGLONG __cdecl _atoi64( const char *str )
/*********************************************************************
* atoi (NTDLL.@)
*/
-int __cdecl atoi( const char *nptr )
+int __cdecl DECLSPEC_HOTPATCH atoi( const char *nptr )
{
return _atoi64( nptr );
}
@@ -1048,7 +1048,7 @@ int __cdecl atoi( const char *nptr )
/*********************************************************************
* atol (NTDLL.@)
*/
-__msvcrt_long __cdecl atol( const char *nptr )
+__msvcrt_long __cdecl DECLSPEC_HOTPATCH atol( const char *nptr )
{
return _atoi64( nptr );
}
@@ -1528,7 +1528,7 @@ int WINAPIV sscanf( const char *str, const char *format, ... )
* RETURNS
* Nothing.
*/
-void __cdecl _splitpath(const char* inpath, char * drv, char * dir,
+void __cdecl DECLSPEC_HOTPATCH _splitpath(const char* inpath, char * drv, char * dir,
char* fname, char * ext )
{
const char *p, *end;
--
2.30.2
2
2
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/Makefile.in | 1 +
dlls/dwrite/dwrite_private.h | 23 +--
dlls/dwrite/font.c | 149 +++++++++-----
dlls/dwrite/freetype.c | 362 ++++++++++++++++++-----------------
dlls/dwrite/main.c | 8 +-
dlls/dwrite/unixlib.h | 113 +++++++++++
6 files changed, 407 insertions(+), 249 deletions(-)
create mode 100644 dlls/dwrite/unixlib.h
diff --git a/dlls/dwrite/Makefile.in b/dlls/dwrite/Makefile.in
index 8b612989386..1c1611f8e16 100644
--- a/dlls/dwrite/Makefile.in
+++ b/dlls/dwrite/Makefile.in
@@ -1,5 +1,6 @@
MODULE = dwrite.dll
IMPORTLIB = dwrite
+UNIXLIB = dwrite.so
IMPORTS = user32 gdi32 advapi32
EXTRAINCL = $(FREETYPE_CFLAGS)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index f83372acc9e..dd346191662 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -223,8 +223,7 @@ extern HRESULT opentype_cmap_get_unicode_ranges(const struct dwrite_cmap *cmap,
DWRITE_UNICODE_RANGE *ranges, unsigned int *count) DECLSPEC_HIDDEN;
struct dwrite_fontface;
-typedef void * font_object_handle;
-typedef font_object_handle (*p_dwrite_fontface_get_font_object)(struct dwrite_fontface *fontface);
+typedef UINT64 (*p_dwrite_fontface_get_font_object)(struct dwrite_fontface *fontface);
struct dwrite_fontface
{
@@ -238,7 +237,7 @@ struct dwrite_fontface
IDWriteFactory7 *factory;
struct fontfacecached *cached;
- font_object_handle font_object;
+ UINT64 font_object;
void *data_context;
p_dwrite_fontface_get_font_object get_font_object;
struct
@@ -717,22 +716,4 @@ extern HRESULT shape_check_typographic_feature(struct scriptshaping_context *con
struct font_data_context;
extern HMODULE dwrite_module DECLSPEC_HIDDEN;
-struct font_backend_funcs
-{
- font_object_handle (CDECL *create_font_object)(const void *data_ptr, UINT64 data_size, unsigned int index);
- void (CDECL *release_font_object)(font_object_handle object);
- int (CDECL *get_glyph_outline)(font_object_handle object, float emsize, unsigned int simulations, UINT16 glyph,
- struct dwrite_outline *outline);
- UINT16 (CDECL *get_glyph_count)(font_object_handle object);
- INT32 (CDECL *get_glyph_advance)(font_object_handle object, float em_size, UINT16 glyph,
- DWRITE_MEASURING_MODE measuring_mode, BOOL *has_contours);
- void (CDECL *get_glyph_bbox)(font_object_handle object, struct dwrite_glyphbitmap *bitmap_desc);
- BOOL (CDECL *get_glyph_bitmap)(font_object_handle object, struct dwrite_glyphbitmap *bitmap_desc);
- void (CDECL *get_design_glyph_metrics)(font_object_handle object, UINT16 upem, UINT16 ascent, unsigned int simulations,
- UINT16 glyph, DWRITE_GLYPH_METRICS *metrics);
-};
-
-extern void init_font_backend(void) DECLSPEC_HIDDEN;
-extern void release_font_backend(void) DECLSPEC_HIDDEN;
-
extern void dwrite_fontface_get_glyph_bbox(IDWriteFontFace *fontface, struct dwrite_glyphbitmap *bitmap) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index cb4f856524c..22fb3369bc7 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -26,6 +26,7 @@
#define COBJMACROS
#include "dwrite_private.h"
+#include "unixlib.h"
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
WINE_DECLARE_DEBUG_CHANNEL(dwrite_file);
@@ -45,8 +46,6 @@ static const FLOAT RECOMMENDED_OUTLINE_AA_THRESHOLD = 100.0f;
static const FLOAT RECOMMENDED_OUTLINE_A_THRESHOLD = 350.0f;
static const FLOAT RECOMMENDED_NATURAL_PPEM = 20.0f;
-static const struct font_backend_funcs *font_funcs;
-
struct cache_key
{
float size;
@@ -59,7 +58,7 @@ struct cache_entry
struct wine_rb_entry entry;
struct list mru;
struct cache_key key;
- float advance;
+ int advance;
RECT bbox;
BYTE *bitmap;
unsigned int bitmap_size;
@@ -117,19 +116,28 @@ static struct cache_entry * fontface_get_cache_entry(struct dwrite_fontface *fon
return entry;
}
-static float fontface_get_glyph_advance(struct dwrite_fontface *fontface, float fontsize, unsigned short glyph,
+static int fontface_get_glyph_advance(struct dwrite_fontface *fontface, float fontsize, unsigned short glyph,
unsigned short mode, BOOL *has_contours)
{
struct cache_key key = { .size = fontsize, .glyph = glyph, .mode = mode };
+ struct get_glyph_advance_params params;
struct cache_entry *entry;
- BOOL value;
+ unsigned int value;
if (!(entry = fontface_get_cache_entry(fontface, 0, &key)))
- return 0.0f;
+ return 0;
if (!entry->has_advance)
{
- entry->advance = font_funcs->get_glyph_advance(fontface->get_font_object(fontface), fontsize, glyph, mode, &value);
+ params.object = fontface->get_font_object(fontface);
+ params.glyph = glyph;
+ params.mode = mode;
+ params.emsize = fontsize;
+ params.advance = &entry->advance;
+ params.has_contours = &value;
+
+ UNIX_CALL(get_glyph_advance, ¶ms);
+
entry->has_contours = !!value;
entry->has_advance = 1;
}
@@ -142,24 +150,31 @@ void dwrite_fontface_get_glyph_bbox(IDWriteFontFace *iface, struct dwrite_glyphb
{
struct cache_key key = { .size = bitmap->emsize, .glyph = bitmap->glyph, .mode = DWRITE_MEASURING_MODE_NATURAL };
struct dwrite_fontface *fontface = unsafe_impl_from_IDWriteFontFace(iface);
+ struct get_glyph_bbox_params params;
struct cache_entry *entry;
+ params.object = fontface->get_font_object(fontface);
+ params.simulations = bitmap->simulations;
+ params.glyph = bitmap->glyph;
+ params.emsize = bitmap->emsize;
+ params.m = bitmap->m ? *bitmap->m : identity;
+
EnterCriticalSection(&fontface->cs);
/* For now bypass cache for transformed cases. */
if (bitmap->m && memcmp(bitmap->m, &identity, sizeof(*bitmap->m)))
{
- font_funcs->get_glyph_bbox(fontface->get_font_object(fontface), bitmap);
+ params.bbox = &bitmap->bbox;
+ UNIX_CALL(get_glyph_bbox, ¶ms);
}
else if ((entry = fontface_get_cache_entry(fontface, 0, &key)))
{
- if (entry->has_bbox)
- bitmap->bbox = entry->bbox;
- else
+ if (!entry->has_bbox)
{
- font_funcs->get_glyph_bbox(fontface->get_font_object(fontface), bitmap);
- entry->bbox = bitmap->bbox;
+ params.bbox = &entry->bbox;
+ UNIX_CALL(get_glyph_bbox, ¶ms);
entry->has_bbox = 1;
}
+ bitmap->bbox = entry->bbox;
}
LeaveCriticalSection(&fontface->cs);
}
@@ -170,22 +185,34 @@ static unsigned int get_glyph_bitmap_pitch(DWRITE_RENDERING_MODE1 rendering_mode
}
static HRESULT dwrite_fontface_get_glyph_bitmap(struct dwrite_fontface *fontface, DWRITE_RENDERING_MODE rendering_mode,
- BOOL *is_1bpp, struct dwrite_glyphbitmap *bitmap)
+ unsigned int *is_1bpp, struct dwrite_glyphbitmap *bitmap)
{
struct cache_key key = { .size = bitmap->emsize, .glyph = bitmap->glyph, .mode = DWRITE_MEASURING_MODE_NATURAL };
+ struct get_glyph_bitmap_params params;
const RECT *bbox = &bitmap->bbox;
+ unsigned int bitmap_size, _1bpp;
struct cache_entry *entry;
- unsigned int bitmap_size;
HRESULT hr = S_OK;
bitmap_size = get_glyph_bitmap_pitch(rendering_mode, bbox->right - bbox->left) *
(bbox->bottom - bbox->top);
+ params.object = fontface->get_font_object(fontface);
+ params.simulations = fontface->simulations;
+ params.glyph = bitmap->glyph;
+ params.mode = rendering_mode;
+ params.emsize = bitmap->emsize;
+ params.m = bitmap->m ? *bitmap->m : identity;
+ params.bbox = bitmap->bbox;
+ params.pitch = bitmap->pitch;
+ params.bitmap = bitmap->buf;
+ params.is_1bpp = is_1bpp;
+
EnterCriticalSection(&fontface->cs);
/* For now bypass cache for transformed cases. */
- if (bitmap->m && memcmp(bitmap->m, &identity, sizeof(*bitmap->m)))
+ if (memcmp(¶ms.m, &identity, sizeof(params.m)))
{
- *is_1bpp = font_funcs->get_glyph_bitmap(fontface->get_font_object(fontface), bitmap);
+ UNIX_CALL(get_glyph_bitmap, ¶ms);
}
else if ((entry = fontface_get_cache_entry(fontface, bitmap_size, &key)))
{
@@ -195,10 +222,13 @@ static HRESULT dwrite_fontface_get_glyph_bitmap(struct dwrite_fontface *fontface
}
else
{
- entry->is_1bpp = font_funcs->get_glyph_bitmap(fontface->get_font_object(fontface), bitmap);
+ params.is_1bpp = &_1bpp;
+ UNIX_CALL(get_glyph_bitmap, ¶ms);
+
entry->bitmap_size = bitmap_size;
if ((entry->bitmap = malloc(entry->bitmap_size)))
memcpy(entry->bitmap, bitmap->buf, entry->bitmap_size);
+ entry->is_1bpp = !!_1bpp;
entry->has_bitmap = 1;
}
*is_1bpp = entry->is_1bpp;
@@ -797,6 +827,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
{
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
ULONG refcount = InterlockedDecrement(&fontface->refcount);
+ struct release_font_object_params params = { fontface->font_object };
TRACE("%p, refcount %u.\n", iface, refcount);
@@ -837,7 +868,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
for (i = 0; i < ARRAY_SIZE(fontface->glyphs); i++)
free(fontface->glyphs[i]);
- font_funcs->release_font_object(fontface->font_object);
+ UNIX_CALL(release_font_object, ¶ms);
if (fontface->stream)
{
IDWriteFontFileStream_ReleaseFileFragment(fontface->stream, fontface->data_context);
@@ -924,16 +955,24 @@ static void WINAPI dwritefontface_GetMetrics(IDWriteFontFace5 *iface, DWRITE_FON
static UINT16 WINAPI dwritefontface_GetGlyphCount(IDWriteFontFace5 *iface)
{
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+ struct get_glyph_count_params params;
+ unsigned int count;
TRACE("%p.\n", iface);
- return font_funcs->get_glyph_count(fontface->get_font_object(fontface));
+ params.object = fontface->get_font_object(fontface);
+ params.count = &count;
+ UNIX_CALL(get_glyph_count, ¶ms);
+
+ return count;
}
static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *iface,
UINT16 const *glyphs, UINT32 glyph_count, DWRITE_GLYPH_METRICS *ret, BOOL is_sideways)
{
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
+ struct get_design_glyph_metrics_params params;
+ DWRITE_GLYPH_METRICS metrics;
HRESULT hr = S_OK;
unsigned int i;
@@ -945,16 +984,20 @@ static HRESULT WINAPI dwritefontface_GetDesignGlyphMetrics(IDWriteFontFace5 *ifa
if (is_sideways)
FIXME("sideways metrics are not supported.\n");
+ params.object = fontface->get_font_object(fontface);
+ params.simulations = fontface->simulations;
+ params.upem = fontface->metrics.designUnitsPerEm;
+ params.ascent = fontface->typo_metrics.ascent;
+ params.metrics = &metrics;
+
EnterCriticalSection(&fontface->cs);
for (i = 0; i < glyph_count; ++i)
{
- DWRITE_GLYPH_METRICS metrics;
if (get_cached_glyph_metrics(fontface, glyphs[i], &metrics) != S_OK)
{
- font_funcs->get_design_glyph_metrics(fontface->get_font_object(fontface),
- fontface->metrics.designUnitsPerEm, fontface->typo_metrics.ascent,
- fontface->simulations, glyphs[i], &metrics);
+ params.glyph = glyphs[i];
+ UNIX_CALL(get_design_glyph_metrics, ¶ms);
if (FAILED(hr = set_cached_glyph_metrics(fontface, glyphs[i], &metrics))) break;
}
ret[i] = metrics;
@@ -1024,12 +1067,13 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface,
struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
D2D1_POINT_2F *origins, baseline_origin = { 0 };
struct dwrite_outline outline, outline_size;
+ struct get_glyph_outline_params params;
D2D1_BEZIER_SEGMENT segment;
D2D1_POINT_2F point;
DWRITE_GLYPH_RUN run;
unsigned int i, j, p;
+ NTSTATUS status;
HRESULT hr;
- int ret;
TRACE("%p, %.8e, %p, %p, %p, %u, %d, %d, %p.\n", iface, emSize, glyphs, advances, offsets,
count, is_sideways, is_rtl, sink);
@@ -1063,28 +1107,35 @@ static HRESULT WINAPI dwritefontface_GetGlyphRunOutline(IDWriteFontFace5 *iface,
memset(&outline_size, 0, sizeof(outline_size));
memset(&outline, 0, sizeof(outline));
+ params.object = fontface->get_font_object(fontface);
+ params.simulations = fontface->simulations;
+ params.emsize = emSize;
+
for (i = 0; i < count; ++i)
{
outline.tags.count = outline.points.count = 0;
EnterCriticalSection(&fontface->cs);
- if (!(ret = font_funcs->get_glyph_outline(fontface->get_font_object(fontface), emSize, fontface->simulations,
- glyphs[i], &outline_size)))
+
+ params.glyph = glyphs[i];
+ params.outline = &outline_size;
+
+ if (!(status = UNIX_CALL(get_glyph_outline, ¶ms)))
{
dwrite_array_reserve((void **)&outline.tags.values, &outline.tags.size, outline_size.tags.count,
sizeof(*outline.tags.values));
dwrite_array_reserve((void **)&outline.points.values, &outline.points.size, outline_size.points.count,
sizeof(*outline.points.values));
- if ((ret = font_funcs->get_glyph_outline(fontface->get_font_object(fontface), emSize, fontface->simulations,
- glyphs[i], &outline)))
+ params.outline = &outline;
+ if ((status = UNIX_CALL(get_glyph_outline, ¶ms)))
{
WARN("Failed to get glyph outline for glyph %u.\n", glyphs[i]);
}
}
LeaveCriticalSection(&fontface->cs);
- if (ret)
+ if (status)
continue;
for (j = 0, p = 0; j < outline.tags.count; ++j)
@@ -5239,26 +5290,37 @@ HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_ke
return S_OK;
}
-static font_object_handle dwrite_fontface_get_font_object(struct dwrite_fontface *fontface)
+static UINT64 dwrite_fontface_get_font_object(struct dwrite_fontface *fontface)
{
- font_object_handle font_object;
+ struct create_font_object_params create_params;
+ struct release_font_object_params release_params;
+ UINT64 font_object, size;
const void *data_ptr;
void *data_context;
- UINT64 size;
if (!fontface->font_object && SUCCEEDED(IDWriteFontFileStream_GetFileSize(fontface->stream, &size)))
{
if (SUCCEEDED(IDWriteFontFileStream_ReadFileFragment(fontface->stream, &data_ptr, 0, size, &data_context)))
{
- if (!(font_object = font_funcs->create_font_object(data_ptr, size, fontface->index)))
+ create_params.data = data_ptr;
+ create_params.size = size;
+ create_params.index = fontface->index;
+ create_params.object = &font_object;
+
+ UNIX_CALL(create_font_object, &create_params);
+
+ if (!font_object)
{
WARN("Backend failed to create font object.\n");
IDWriteFontFileStream_ReleaseFileFragment(fontface->stream, data_context);
- return NULL;
+ return 0;
}
- if (InterlockedCompareExchangePointer((void **)&fontface->font_object, font_object, NULL))
- font_funcs->release_font_object(font_object);
+ if (InterlockedCompareExchange64((LONGLONG *)&fontface->font_object, font_object, 0))
+ {
+ release_params.object = font_object;
+ UNIX_CALL(release_font_object, &release_params);
+ }
}
}
@@ -5997,7 +6059,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis)
{
BYTE *src = glyph_bitmap.buf, *dst;
int x, y, width, height;
- BOOL is_1bpp;
+ unsigned int is_1bpp;
glyph_bitmap.glyph = analysis->run.glyphIndices[i];
dwrite_fontface_get_glyph_bbox(analysis->run.fontFace, &glyph_bitmap);
@@ -6010,6 +6072,7 @@ static HRESULT glyphrunanalysis_render(struct dwrite_glyphrunanalysis *analysis)
glyph_bitmap.pitch = get_glyph_bitmap_pitch(analysis->rendering_mode, width);
memset(src, 0, height * glyph_bitmap.pitch);
+
if (FAILED(dwrite_fontface_get_glyph_bitmap(fontface, analysis->rendering_mode, &is_1bpp, &glyph_bitmap)))
{
WARN("Failed to render glyph[%u] = %#x.\n", i, glyph_bitmap.glyph);
@@ -8140,13 +8203,3 @@ HRESULT create_fontset_builder(IDWriteFactory7 *factory, IDWriteFontSetBuilder2
return S_OK;
}
-
-void init_font_backend(void)
-{
- __wine_init_unix_lib(dwrite_module, DLL_PROCESS_ATTACH, NULL, &font_funcs);
-}
-
-void release_font_backend(void)
-{
- __wine_init_unix_lib(dwrite_module, DLL_PROCESS_DETACH, NULL, NULL);
-}
diff --git a/dlls/dwrite/freetype.c b/dlls/dwrite/freetype.c
index daaff6a3f8c..05b04c36e29 100644
--- a/dlls/dwrite/freetype.c
+++ b/dlls/dwrite/freetype.c
@@ -40,6 +40,7 @@
#define WIN32_NO_STATUS
#include "windef.h"
#include "wine/debug.h"
+#include "unixlib.h"
#include "dwrite_private.h"
@@ -88,6 +89,8 @@ MAKE_FUNCPTR(FT_Set_Pixel_Sizes);
#undef MAKE_FUNCPTR
static FT_Error (*pFT_Outline_EmboldenXY)(FT_Outline *, FT_Pos, FT_Pos);
+#define FaceFromObject(o) ((FT_Face)(ULONG_PTR)(o))
+
static FT_Size freetype_set_face_size(FT_Face face, FT_UInt emsize)
{
FT_Size size;
@@ -110,7 +113,7 @@ static BOOL freetype_glyph_has_contours(FT_Face face)
return face->glyph->format == FT_GLYPH_FORMAT_OUTLINE && face->glyph->outline.n_contours;
}
-static BOOL init_freetype(void)
+static NTSTATUS process_attach(void *args)
{
FT_Version_t FT_Version;
@@ -118,7 +121,7 @@ static BOOL init_freetype(void)
if (!ft_handle)
{
WINE_MESSAGE("Wine cannot find the FreeType font library.\n");
- return FALSE;
+ return STATUS_DLL_NOT_FOUND;
}
#define LOAD_FUNCPTR(f) if((p##f = dlsym(ft_handle, #f)) == NULL){WARN("Can't find symbol %s\n", #f); goto sym_not_found;}
@@ -153,72 +156,89 @@ static BOOL init_freetype(void)
#undef LOAD_FUNCPTR
pFT_Outline_EmboldenXY = dlsym(ft_handle, "FT_Outline_EmboldenXY");
- if (pFT_Init_FreeType(&library) != 0) {
+ if (pFT_Init_FreeType(&library) != 0)
+ {
ERR("Can't init FreeType library\n");
- dlclose(ft_handle);
+ dlclose(ft_handle);
ft_handle = NULL;
- return FALSE;
+ return STATUS_UNSUCCESSFUL;
}
pFT_Library_Version(library, &FT_Version.major, &FT_Version.minor, &FT_Version.patch);
TRACE("FreeType version is %d.%d.%d\n", FT_Version.major, FT_Version.minor, FT_Version.patch);
- return TRUE;
+ return STATUS_SUCCESS;
sym_not_found:
WINE_MESSAGE("Wine cannot find certain functions that it needs from FreeType library.\n");
dlclose(ft_handle);
ft_handle = NULL;
- return FALSE;
+ return STATUS_UNSUCCESSFUL;
}
-static font_object_handle CDECL freetype_create_font_object(const void *data_ptr, UINT64 data_size, unsigned int index)
+static NTSTATUS process_detach(void *args)
{
+ pFT_Done_FreeType(library);
+ return STATUS_SUCCESS;
+}
+
+static NTSTATUS create_font_object(void *args)
+{
+ struct create_font_object_params *params = args;
FT_Face face = NULL;
FT_Error fterror;
- fterror = pFT_New_Memory_Face(library, data_ptr, data_size, index, &face);
+ fterror = pFT_New_Memory_Face(library, params->data, params->size, params->index, &face);
if (fterror != FT_Err_Ok)
+ {
WARN("Failed to create a face object, error %d.\n", fterror);
+ return STATUS_UNSUCCESSFUL;
+ }
+
+ *params->object = (ULONG_PTR)face;
- return face;
+ return STATUS_SUCCESS;
}
-static void CDECL freetype_release_font_object(font_object_handle object)
+static NTSTATUS release_font_object(void *args)
{
- pFT_Done_Face(object);
+ struct release_font_object_params *params = args;
+ pFT_Done_Face(FaceFromObject(params->object));
+ return STATUS_SUCCESS;
}
-static void CDECL freetype_get_design_glyph_metrics(font_object_handle object, UINT16 upem, UINT16 ascent,
- unsigned int simulations, UINT16 glyph, DWRITE_GLYPH_METRICS *ret)
+static NTSTATUS get_design_glyph_metrics(void *args)
{
- FT_Face face = object;
+ struct get_design_glyph_metrics_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
FT_Size size;
- if (!(size = freetype_set_face_size(face, upem)))
- return;
+ if (!(size = freetype_set_face_size(face, params->upem)))
+ return STATUS_UNSUCCESSFUL;
- if (!pFT_Load_Glyph(face, glyph, FT_LOAD_NO_SCALE))
+ if (!pFT_Load_Glyph(face, params->glyph, FT_LOAD_NO_SCALE))
{
FT_Glyph_Metrics *metrics = &face->glyph->metrics;
- ret->leftSideBearing = metrics->horiBearingX;
- ret->advanceWidth = metrics->horiAdvance;
- ret->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
+ params->metrics->leftSideBearing = metrics->horiBearingX;
+ params->metrics->advanceWidth = metrics->horiAdvance;
+ params->metrics->rightSideBearing = metrics->horiAdvance - metrics->horiBearingX - metrics->width;
- ret->advanceHeight = metrics->vertAdvance;
- ret->verticalOriginY = ascent;
- ret->topSideBearing = ascent - metrics->horiBearingY;
- ret->bottomSideBearing = metrics->vertAdvance - metrics->height - ret->topSideBearing;
+ params->metrics->advanceHeight = metrics->vertAdvance;
+ params->metrics->verticalOriginY = params->ascent;
+ params->metrics->topSideBearing = params->ascent - metrics->horiBearingY;
+ params->metrics->bottomSideBearing = metrics->vertAdvance - metrics->height - params->metrics->topSideBearing;
/* Adjust in case of bold simulation, glyphs without contours are ignored. */
- if (simulations & DWRITE_FONT_SIMULATIONS_BOLD && freetype_glyph_has_contours(face))
+ if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD && freetype_glyph_has_contours(face))
{
- if (ret->advanceWidth)
- ret->advanceWidth += (upem + 49) / 50;
+ if (params->metrics->advanceWidth)
+ params->metrics->advanceWidth += (params->upem + 49) / 50;
}
}
pFT_Done_Size(size);
+
+ return STATUS_SUCCESS;
}
struct decompose_context
@@ -425,52 +445,55 @@ static void embolden_glyph(FT_Glyph glyph, FLOAT emsize)
embolden_glyph_outline(&outline_glyph->outline, emsize);
}
-static int CDECL freetype_get_glyph_outline(font_object_handle object, float emsize, unsigned int simulations,
- UINT16 glyph, struct dwrite_outline *outline)
+static NTSTATUS get_glyph_outline(void *args)
{
- FT_Face face = object;
+ struct get_glyph_outline_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
FT_Size size;
- int ret = 0;
- if (!(size = freetype_set_face_size(face, emsize)))
- return 0;
+ if (!(size = freetype_set_face_size(face, params->emsize)))
+ return STATUS_UNSUCCESSFUL;
- if (!pFT_Load_Glyph(face, glyph, FT_LOAD_NO_BITMAP))
+ if (!pFT_Load_Glyph(face, params->glyph, FT_LOAD_NO_BITMAP))
{
FT_Outline *ft_outline = &face->glyph->outline;
FT_Matrix m;
- if (outline->points.values)
+ if (params->outline->points.values)
{
- if (simulations & DWRITE_FONT_SIMULATIONS_BOLD)
- embolden_glyph_outline(ft_outline, emsize);
+ if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
+ embolden_glyph_outline(ft_outline, params->emsize);
m.xx = 1 << 16;
- m.xy = simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0;
+ m.xy = params->simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE ? (1 << 16) / 3 : 0;
m.yx = 0;
m.yy = -(1 << 16); /* flip Y axis */
pFT_Outline_Transform(ft_outline, &m);
- ret = decompose_outline(ft_outline, outline);
+ decompose_outline(ft_outline, params->outline);
}
else
{
/* Intentionally overestimate numbers to keep it simple. */
- outline->points.count = ft_outline->n_points * 3;
- outline->tags.count = ft_outline->n_points + ft_outline->n_contours * 2;
+ params->outline->points.count = ft_outline->n_points * 3;
+ params->outline->tags.count = ft_outline->n_points + ft_outline->n_contours * 2;
}
}
pFT_Done_Size(size);
- return ret;
+ return STATUS_SUCCESS;
}
-static UINT16 CDECL freetype_get_glyph_count(font_object_handle object)
+static NTSTATUS get_glyph_count(void *args)
{
- FT_Face face = object;
- return face ? face->num_glyphs : 0;
+ struct get_glyph_count_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
+
+ *params->count = face ? face->num_glyphs : 0;
+
+ return STATUS_SUCCESS;
}
static inline void ft_matrix_from_dwrite_matrix(const DWRITE_MATRIX *m, FT_Matrix *ft_matrix)
@@ -481,9 +504,9 @@ static inline void ft_matrix_from_dwrite_matrix(const DWRITE_MATRIX *m, FT_Matri
ft_matrix->yy = m->m22 * 0x10000;
}
-static BOOL get_glyph_transform(struct dwrite_glyphbitmap *bitmap, FT_Matrix *ret)
+static BOOL get_glyph_transform(unsigned int simulations, const DWRITE_MATRIX *m, FT_Matrix *ret)
{
- FT_Matrix m;
+ FT_Matrix ftm;
ret->xx = 1 << 16;
ret->xy = 0;
@@ -492,53 +515,53 @@ static BOOL get_glyph_transform(struct dwrite_glyphbitmap *bitmap, FT_Matrix *re
/* Some fonts provide mostly bitmaps and very few outlines, for example for .notdef.
Disable transform if that's the case. */
- if (!bitmap->m && !bitmap->simulations)
+ if (!memcmp(m, &identity, sizeof(*m)) && !simulations)
return FALSE;
- if (bitmap->simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE) {
- m.xx = 1 << 16;
- m.xy = (1 << 16) / 3;
- m.yx = 0;
- m.yy = 1 << 16;
- pFT_Matrix_Multiply(&m, ret);
+ if (simulations & DWRITE_FONT_SIMULATIONS_OBLIQUE)
+ {
+ ftm.xx = 1 << 16;
+ ftm.xy = (1 << 16) / 3;
+ ftm.yx = 0;
+ ftm.yy = 1 << 16;
+ pFT_Matrix_Multiply(&ftm, ret);
}
- if (bitmap->m) {
- ft_matrix_from_dwrite_matrix(bitmap->m, &m);
- pFT_Matrix_Multiply(&m, ret);
- }
+ ft_matrix_from_dwrite_matrix(m, &ftm);
+ pFT_Matrix_Multiply(&ftm, ret);
return TRUE;
}
-static void CDECL freetype_get_glyph_bbox(font_object_handle object, struct dwrite_glyphbitmap *bitmap)
+static NTSTATUS get_glyph_bbox(void *args)
{
- FT_Face face = object;
+ struct get_glyph_bbox_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
FT_Glyph glyph = NULL;
FT_BBox bbox = { 0 };
BOOL needs_transform;
FT_Matrix m;
FT_Size size;
- SetRectEmpty(&bitmap->bbox);
+ SetRectEmpty(params->bbox);
- if (!(size = freetype_set_face_size(face, bitmap->emsize)))
- return;
+ if (!(size = freetype_set_face_size(face, params->emsize)))
+ return STATUS_UNSUCCESSFUL;
- needs_transform = FT_IS_SCALABLE(face) && get_glyph_transform(bitmap, &m);
+ needs_transform = FT_IS_SCALABLE(face) && get_glyph_transform(params->simulations, ¶ms->m, &m);
- if (pFT_Load_Glyph(face, bitmap->glyph, needs_transform ? FT_LOAD_NO_BITMAP : 0))
+ if (pFT_Load_Glyph(face, params->glyph, needs_transform ? FT_LOAD_NO_BITMAP : 0))
{
- WARN("Failed to load glyph %u.\n", bitmap->glyph);
+ WARN("Failed to load glyph %u.\n", params->glyph);
pFT_Done_Size(size);
- return;
+ return STATUS_UNSUCCESSFUL;
}
pFT_Get_Glyph(face->glyph, &glyph);
if (needs_transform)
{
- if (bitmap->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
- embolden_glyph(glyph, bitmap->emsize);
+ if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
+ embolden_glyph(glyph, params->emsize);
/* Includes oblique and user transform. */
pFT_Glyph_Transform(glyph, &m, NULL);
@@ -549,15 +572,19 @@ static void CDECL freetype_get_glyph_bbox(font_object_handle object, struct dwri
pFT_Done_Size(size);
/* flip Y axis */
- SetRect(&bitmap->bbox, bbox.xMin, -bbox.yMax, bbox.xMax, -bbox.yMin);
+ SetRect(params->bbox, bbox.xMin, -bbox.yMax, bbox.xMax, -bbox.yMin);
+
+ return STATUS_SUCCESS;
}
-static BOOL freetype_get_aliased_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_Glyph glyph)
+static NTSTATUS freetype_get_aliased_glyph_bitmap(struct get_glyph_bitmap_params *params, FT_Glyph glyph)
{
- const RECT *bbox = &bitmap->bbox;
+ const RECT *bbox = ¶ms->bbox;
int width = bbox->right - bbox->left;
int height = bbox->bottom - bbox->top;
+ *params->is_1bpp = 1;
+
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
const FT_Outline *src = &outline->outline;
@@ -566,9 +593,9 @@ static BOOL freetype_get_aliased_glyph_bitmap(struct dwrite_glyphbitmap *bitmap,
ft_bitmap.width = width;
ft_bitmap.rows = height;
- ft_bitmap.pitch = bitmap->pitch;
+ ft_bitmap.pitch = params->pitch;
ft_bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
- ft_bitmap.buffer = bitmap->buf;
+ ft_bitmap.buffer = params->bitmap;
/* Note: FreeType will only set 'black' bits for us. */
if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
@@ -580,28 +607,29 @@ static BOOL freetype_get_aliased_glyph_bitmap(struct dwrite_glyphbitmap *bitmap,
}
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
- BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
- int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
+ BYTE *src = ft_bitmap->buffer, *dst = params->bitmap;
+ int w = min(params->pitch, (ft_bitmap->width + 7) >> 3);
int h = min(height, ft_bitmap->rows);
while (h--) {
memcpy(dst, src, w);
src += ft_bitmap->pitch;
- dst += bitmap->pitch;
+ dst += params->pitch;
}
}
else
FIXME("format %x not handled\n", glyph->format);
- return TRUE;
+ return STATUS_SUCCESS;
}
-static BOOL freetype_get_aa_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_Glyph glyph)
+static NTSTATUS freetype_get_aa_glyph_bitmap(struct get_glyph_bitmap_params *params, FT_Glyph glyph)
{
- const RECT *bbox = &bitmap->bbox;
+ const RECT *bbox = ¶ms->bbox;
int width = bbox->right - bbox->left;
int height = bbox->bottom - bbox->top;
- BOOL ret = FALSE;
+
+ *params->is_1bpp = 0;
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
FT_OutlineGlyph outline = (FT_OutlineGlyph)glyph;
@@ -611,9 +639,9 @@ static BOOL freetype_get_aa_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_G
ft_bitmap.width = width;
ft_bitmap.rows = height;
- ft_bitmap.pitch = bitmap->pitch;
+ ft_bitmap.pitch = params->pitch;
ft_bitmap.pixel_mode = FT_PIXEL_MODE_GRAY;
- ft_bitmap.buffer = bitmap->buf;
+ ft_bitmap.buffer = params->bitmap;
/* Note: FreeType will only set 'black' bits for us. */
if (pFT_Outline_New(library, src->n_points, src->n_contours, ©) == 0) {
@@ -625,55 +653,61 @@ static BOOL freetype_get_aa_glyph_bitmap(struct dwrite_glyphbitmap *bitmap, FT_G
}
else if (glyph->format == FT_GLYPH_FORMAT_BITMAP) {
FT_Bitmap *ft_bitmap = &((FT_BitmapGlyph)glyph)->bitmap;
- BYTE *src = ft_bitmap->buffer, *dst = bitmap->buf;
- int w = min(bitmap->pitch, (ft_bitmap->width + 7) >> 3);
+ BYTE *src = ft_bitmap->buffer, *dst = params->bitmap;
+ int w = min(params->pitch, (ft_bitmap->width + 7) >> 3);
int h = min(height, ft_bitmap->rows);
while (h--) {
memcpy(dst, src, w);
src += ft_bitmap->pitch;
- dst += bitmap->pitch;
+ dst += params->pitch;
}
- ret = TRUE;
+ *params->is_1bpp = 1;
}
else
+ {
FIXME("format %x not handled\n", glyph->format);
+ return STATUS_NOT_IMPLEMENTED;
+ }
- return ret;
+ return STATUS_SUCCESS;
}
-static BOOL CDECL freetype_get_glyph_bitmap(font_object_handle object, struct dwrite_glyphbitmap *bitmap)
+static NTSTATUS get_glyph_bitmap(void *args)
{
- FT_Face face = object;
+ struct get_glyph_bitmap_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
BOOL needs_transform;
BOOL ret = FALSE;
FT_Glyph glyph;
FT_Size size;
FT_Matrix m;
- if (!(size = freetype_set_face_size(face, bitmap->emsize)))
- return FALSE;
+ *params->is_1bpp = 0;
- needs_transform = FT_IS_SCALABLE(face) && get_glyph_transform(bitmap, &m);
+ if (!(size = freetype_set_face_size(face, params->emsize)))
+ return STATUS_UNSUCCESSFUL;
- if (!pFT_Load_Glyph(face, bitmap->glyph, needs_transform ? FT_LOAD_NO_BITMAP : 0))
+ needs_transform = FT_IS_SCALABLE(face) && get_glyph_transform(params->simulations, ¶ms->m, &m);
+
+ if (!pFT_Load_Glyph(face, params->glyph, needs_transform ? FT_LOAD_NO_BITMAP : 0))
{
pFT_Get_Glyph(face->glyph, &glyph);
if (needs_transform)
{
- if (bitmap->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
- embolden_glyph(glyph, bitmap->emsize);
+ if (params->simulations & DWRITE_FONT_SIMULATIONS_BOLD)
+ embolden_glyph(glyph, params->emsize);
/* Includes oblique and user transform. */
pFT_Glyph_Transform(glyph, &m, NULL);
}
- if (bitmap->aliased)
- ret = freetype_get_aliased_glyph_bitmap(bitmap, glyph);
+ if (params->mode == DWRITE_RENDERING_MODE1_ALIASED)
+ ret = freetype_get_aliased_glyph_bitmap(params, glyph);
else
- ret = freetype_get_aa_glyph_bitmap(bitmap, glyph);
+ ret = freetype_get_aa_glyph_bitmap(params, glyph);
pFT_Done_Glyph(glyph);
}
@@ -683,128 +717,100 @@ static BOOL CDECL freetype_get_glyph_bitmap(font_object_handle object, struct dw
return ret;
}
-static INT32 CDECL freetype_get_glyph_advance(font_object_handle object, float emsize, UINT16 glyph,
- DWRITE_MEASURING_MODE mode, BOOL *has_contours)
+static NTSTATUS get_glyph_advance(void *args)
{
- FT_Face face = object;
- INT32 advance = 0;
+ struct get_glyph_advance_params *params = args;
+ FT_Face face = FaceFromObject(params->object);
FT_Size size;
- *has_contours = FALSE;
+ *params->advance = 0;
+ *params->has_contours = FALSE;
- if (!(size = freetype_set_face_size(face, emsize)))
- return 0;
+ if (!(size = freetype_set_face_size(face, params->emsize)))
+ return STATUS_UNSUCCESSFUL;
- if (!pFT_Load_Glyph(face, glyph, mode == DWRITE_MEASURING_MODE_NATURAL ? FT_LOAD_NO_HINTING : 0))
+ if (!pFT_Load_Glyph(face, params->glyph, params->mode == DWRITE_MEASURING_MODE_NATURAL ? FT_LOAD_NO_HINTING : 0))
{
- advance = face->glyph->advance.x >> 6;
- *has_contours = freetype_glyph_has_contours(face);
+ *params->advance = face->glyph->advance.x >> 6;
+ *params->has_contours = freetype_glyph_has_contours(face);
}
pFT_Done_Size(size);
- return advance;
-}
-
-const static struct font_backend_funcs freetype_funcs =
-{
- freetype_create_font_object,
- freetype_release_font_object,
- freetype_get_glyph_outline,
- freetype_get_glyph_count,
- freetype_get_glyph_advance,
- freetype_get_glyph_bbox,
- freetype_get_glyph_bitmap,
- freetype_get_design_glyph_metrics,
-};
-
-static NTSTATUS init_freetype_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
-{
- if (!init_freetype()) return STATUS_DLL_NOT_FOUND;
- *(const struct font_backend_funcs **)ptr_out = &freetype_funcs;
- return STATUS_SUCCESS;
-}
-
-static NTSTATUS release_freetype_lib(void)
-{
- pFT_Done_FreeType(library);
return STATUS_SUCCESS;
}
#else /* HAVE_FREETYPE */
-static font_object_handle CDECL null_create_font_object(const void *data_ptr, UINT64 data_size, unsigned int index)
+static NTSTATUS process_attach(void *args)
{
- return NULL;
+ return STATUS_NOT_IMPLEMENTED;
}
-static void CDECL null_release_font_object(font_object_handle object)
+static NTSTATUS process_detach(void *args)
{
+ return STATUS_NOT_IMPLEMENTED;
}
-static int CDECL null_get_glyph_outline(font_object_handle object, float emSize, unsigned int simulations,
- UINT16 glyph, struct dwrite_outline *outline)
+static NTSTATUS create_font_object(void *args)
{
- return 1;
+ return STATUS_NOT_IMPLEMENTED;
}
-static UINT16 CDECL null_get_glyph_count(font_object_handle object)
+static NTSTATUS release_font_object(void *args)
{
- return 0;
+ return STATUS_NOT_IMPLEMENTED;
}
-static INT32 CDECL null_get_glyph_advance(font_object_handle object, float emsize, UINT16 glyph,
- DWRITE_MEASURING_MODE mode, BOOL *has_contours)
+static NTSTATUS get_glyph_outline(void *args)
{
- *has_contours = FALSE;
- return 0;
+ return STATUS_NOT_IMPLEMENTED;
}
-static void CDECL null_get_glyph_bbox(font_object_handle object, struct dwrite_glyphbitmap *bitmap)
+static NTSTATUS get_glyph_count(void *args)
{
- SetRectEmpty(&bitmap->bbox);
+ return STATUS_NOT_IMPLEMENTED;
}
-static BOOL CDECL null_get_glyph_bitmap(font_object_handle object, struct dwrite_glyphbitmap *bitmap)
+static NTSTATUS get_glyph_advance(void *args)
{
- return FALSE;
-}
+ struct get_glyph_advance_params *params = args;
-static void CDECL null_get_design_glyph_metrics(font_object_handle object, UINT16 upem, UINT16 ascent, unsigned int simulations,
- UINT16 glyph, DWRITE_GLYPH_METRICS *metrics)
-{
+ *params->has_contours = 0;
+ *params->advance = 0;
+
+ return STATUS_NOT_IMPLEMENTED;
}
-const static struct font_backend_funcs null_funcs =
+static NTSTATUS get_glyph_bbox(void *args)
{
- null_create_font_object,
- null_release_font_object,
- null_get_glyph_outline,
- null_get_glyph_count,
- null_get_glyph_advance,
- null_get_glyph_bbox,
- null_get_glyph_bitmap,
- null_get_design_glyph_metrics,
-};
+ struct get_glyph_bbox *params = args;
+ SetRectEmpty(params->bbox);
+ return STATUS_NOT_IMPLEMENTED;
+}
-static NTSTATUS init_freetype_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
+static NTSTATUS get_glyph_bitmap(void *args)
{
- *(const struct font_backend_funcs **)ptr_out = &null_funcs;
- return STATUS_DLL_NOT_FOUND;
+ return STATUS_NOT_IMPLEMENTED;
}
-static NTSTATUS release_freetype_lib(void)
+static NTSTATUS get_design_glyph_metrics(void *args)
{
- return STATUS_DLL_NOT_FOUND;
+ return STATUS_NOT_IMPLEMENTED;
}
#endif /* HAVE_FREETYPE */
-NTSTATUS CDECL __wine_init_unix_lib(HMODULE module, DWORD reason, const void *ptr_in, void *ptr_out)
-{
- if (reason == DLL_PROCESS_ATTACH)
- return init_freetype_lib(module, reason, ptr_in, ptr_out);
- else if (reason == DLL_PROCESS_DETACH)
- return release_freetype_lib();
- return STATUS_SUCCESS;
-}
+const unixlib_entry_t __wine_unix_call_funcs[] =
+{
+ process_attach,
+ process_detach,
+ create_font_object,
+ release_font_object,
+ get_glyph_outline,
+ get_glyph_count,
+ get_glyph_advance,
+ get_glyph_bbox,
+ get_glyph_bitmap,
+ get_design_glyph_metrics,
+};
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index d0dd4dd99e9..b21eba0c50a 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -30,11 +30,13 @@
#include "initguid.h"
#include "dwrite_private.h"
+#include "unixlib.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(dwrite);
HMODULE dwrite_module = 0;
+unixlib_handle_t unixlib_handle = 0;
static IDWriteFactory7 *shared_factory;
static void release_shared_factory(IDWriteFactory7 *factory);
@@ -45,13 +47,15 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD reason, LPVOID reserved)
case DLL_PROCESS_ATTACH:
dwrite_module = hinstDLL;
DisableThreadLibraryCalls( hinstDLL );
- init_font_backend();
+ if (!NtQueryVirtualMemory(GetCurrentProcess(), hinstDLL, MemoryWineUnixFuncs,
+ &unixlib_handle, sizeof(unixlib_handle), NULL))
+ UNIX_CALL(process_attach, NULL);
init_local_fontfile_loader();
break;
case DLL_PROCESS_DETACH:
if (reserved) break;
release_shared_factory(shared_factory);
- release_font_backend();
+ if (unixlib_handle) UNIX_CALL(process_detach, NULL);
}
return TRUE;
}
diff --git a/dlls/dwrite/unixlib.h b/dlls/dwrite/unixlib.h
new file mode 100644
index 00000000000..533c3168b99
--- /dev/null
+++ b/dlls/dwrite/unixlib.h
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2021 Nikolay Sivov for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include <stdarg.h>
+#include "windef.h"
+#include "winternl.h"
+#include "dwrite.h"
+#include "wine/unixlib.h"
+
+struct create_font_object_params
+{
+ const void *data;
+ UINT64 size;
+ unsigned int index;
+ UINT64 *object;
+};
+
+struct release_font_object_params
+{
+ UINT64 object;
+};
+
+struct get_glyph_outline_params
+{
+ UINT64 object;
+ unsigned int simulations;
+ unsigned int glyph;
+ float emsize;
+ struct dwrite_outline *outline;
+};
+
+struct get_glyph_count_params
+{
+ UINT64 object;
+ unsigned int *count;
+};
+
+struct get_glyph_advance_params
+{
+ UINT64 object;
+ unsigned int glyph;
+ unsigned int mode;
+ float emsize;
+ int *advance;
+ unsigned int *has_contours;
+};
+
+struct get_glyph_bbox_params
+{
+ UINT64 object;
+ unsigned int simulations;
+ unsigned int glyph;
+ float emsize;
+ DWRITE_MATRIX m;
+ RECT *bbox;
+};
+
+struct get_glyph_bitmap_params
+{
+ UINT64 object;
+ unsigned int simulations;
+ unsigned int glyph;
+ unsigned int mode;
+ float emsize;
+ DWRITE_MATRIX m;
+ RECT bbox;
+ int pitch;
+ BYTE *bitmap;
+ unsigned int *is_1bpp;
+};
+
+struct get_design_glyph_metrics_params
+{
+ UINT64 object;
+ unsigned int simulations;
+ unsigned int glyph;
+ unsigned int upem;
+ unsigned int ascent;
+ DWRITE_GLYPH_METRICS *metrics;
+};
+
+enum font_backend_funcs
+{
+ unix_process_attach,
+ unix_process_detach,
+ unix_create_font_object,
+ unix_release_font_object,
+ unix_get_glyph_outline,
+ unix_get_glyph_count,
+ unix_get_glyph_advance,
+ unix_get_glyph_bbox,
+ unix_get_glyph_bitmap,
+ unix_get_design_glyph_metrics,
+};
+
+extern unixlib_handle_t unixlib_handle DECLSPEC_HIDDEN;
+
+#define UNIX_CALL( func, params ) __wine_unix_call( unixlib_handle, unix_ ## func, params )
--
2.33.0
1
4
It is not very clear to me what the desicion was regarding these
two patches so they have been resent.
The following patches introduce the FIXME_ONCE macro
which suppresses repeated FIXMEs into WARNings. The current
FIXME macro tends to be insufficient in cases where
a developer wishes to suppresses fixmes other than the first.
The first patch is the implementation while the second
demonstrates how this could be useful.
It is based on the vkd3d version.
v2: Fix programming mistakes, fixed a test and some formating
v3: Fixed a programming error(s), dropped all patches except two
v4: Fixed more programming errors(s)
David Kahurani (2):
include/wine: suppress subsequent FIXMEs into WARNINGs
dlls/ntdll: Use FIXME_ONCE
dlls/ntdll/unix/system.c | 8 +++-----
include/wine/debug.h | 30 ++++++++++++++++++++++++++++++
2 files changed, 33 insertions(+), 5 deletions(-)
--
2.25.1
1
2
08 Dec '21
Signed-off-by: Jacek Caban <jacek(a)codeweavers.com>
---
In this context, Vulkan driver is not dependent on DC.
dlls/d3d12/d3d12_main.c | 6 +-----
dlls/dxgi/swapchain.c | 6 +-----
dlls/user32/driver.c | 2 ++
dlls/win32u/dibdrv/dc.c | 2 --
dlls/win32u/driver.c | 18 ++++++++++++------
dlls/win32u/emfdrv.c | 1 -
dlls/win32u/font.c | 1 -
dlls/win32u/path.c | 1 -
dlls/win32u/vulkan.c | 15 +++------------
dlls/win32u/win32u.spec | 2 +-
dlls/win32u/win32u_private.h | 2 +-
dlls/win32u/wrappers.c | 4 ++--
dlls/wined3d/adapter_vk.c | 5 +----
dlls/winemac.drv/gdi.c | 2 +-
dlls/winemac.drv/macdrv.h | 2 +-
dlls/winemac.drv/vulkan.c | 11 ++---------
dlls/wineps.drv/init.c | 1 -
dlls/winevulkan/loader.c | 5 +----
dlls/winevulkan/make_vulkan | 2 +-
dlls/winex11.drv/init.c | 13 +++----------
dlls/winex11.drv/xrender.c | 1 -
include/wine/gdi_driver.h | 7 ++++---
include/wine/vulkan_driver.h | 2 +-
23 files changed, 38 insertions(+), 73 deletions(-)
4
5
Signed-off-by: Zhiyi Zhang <zzhang(a)codeweavers.com>
---
dlls/comctl32/propsheet.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/comctl32/propsheet.c b/dlls/comctl32/propsheet.c
index 9309250f65a..82c0a3cc576 100644
--- a/dlls/comctl32/propsheet.c
+++ b/dlls/comctl32/propsheet.c
@@ -1289,7 +1289,7 @@ static LRESULT CALLBACK PROPSHEET_ThemedSubclassProc(HWND hwnd, UINT msg, WPARAM
/* Using FillRect() to draw background could introduce a tiling effect if the destination
* rectangle is larger than the pattern brush size, which is usually 10x600. This bug is
* visible on property sheet pages if system DPI is set to 192. However, the same bug also
- * exists on XP and explains why vista+ don't use gradient tab body backgound anymore */
+ * exists on XP and explains why vista+ don't use gradient tab body background anymore */
hdc = (HDC)wp;
GetViewportOrgEx(hdc, &org);
SetBrushOrgEx(hdc, org.x, org.y, &old_org);
--
2.32.0
1
0
[RFC PATCH v3 resend 1/5] include: Define fast fail codes and the __fastfail() intrinsic.
by Jinoh Kang 07 Dec '21
by Jinoh Kang 07 Dec '21
07 Dec '21
Signed-off-by: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
---
include/winnt.h | 116 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 116 insertions(+)
diff --git a/include/winnt.h b/include/winnt.h
index 2ab74ab123c..fd17c3464cd 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -915,6 +915,122 @@ NTSYSAPI PSLIST_ENTRY WINAPI RtlInterlockedPushEntrySList(PSLIST_HEADER, PSLIST_
NTSYSAPI WORD WINAPI RtlQueryDepthSList(PSLIST_HEADER);
+/* Fast fail (__fastfail) codes */
+
+#define FAST_FAIL_LEGACY_GS_VIOLATION 0
+#define FAST_FAIL_VTGUARD_CHECK_FAILURE 1
+#define FAST_FAIL_STACK_COOKIE_CHECK_FAILURE 2
+#define FAST_FAIL_CORRUPT_LIST_ENTRY 3
+#define FAST_FAIL_INCORRECT_STACK 4
+#define FAST_FAIL_INVALID_ARG 5
+#define FAST_FAIL_GS_COOKIE_INIT 6
+#define FAST_FAIL_FATAL_APP_EXIT 7
+#define FAST_FAIL_RANGE_CHECK_FAILURE 8
+#define FAST_FAIL_UNSAFE_REGISTRY_ACCESS 9
+#define FAST_FAIL_GUARD_ICALL_CHECK_FAILURE 10
+#define FAST_FAIL_GUARD_WRITE_CHECK_FAILURE 11
+#define FAST_FAIL_INVALID_FIBER_SWITCH 12
+#define FAST_FAIL_INVALID_SET_OF_CONTEXT 13
+#define FAST_FAIL_INVALID_REFERENCE_COUNT 14
+#define FAST_FAIL_INVALID_JUMP_BUFFER 18
+#define FAST_FAIL_MRDATA_MODIFIED 19
+#define FAST_FAIL_CERTIFICATION_FAILURE 20
+#define FAST_FAIL_INVALID_EXCEPTION_CHAIN 21
+#define FAST_FAIL_CRYPTO_LIBRARY 22
+#define FAST_FAIL_INVALID_CALL_IN_DLL_CALLOUT 23
+#define FAST_FAIL_INVALID_IMAGE_BASE 24
+#define FAST_FAIL_DLOAD_PROTECTION_FAILURE 25
+#define FAST_FAIL_UNSAFE_EXTENSION_CALL 26
+#define FAST_FAIL_DEPRECATED_SERVICE_INVOKED 27
+#define FAST_FAIL_INVALID_BUFFER_ACCESS 28
+#define FAST_FAIL_INVALID_BALANCED_TREE 29
+#define FAST_FAIL_INVALID_NEXT_THREAD 30
+#define FAST_FAIL_GUARD_ICALL_CHECK_SUPPRESSED 31
+#define FAST_FAIL_APCS_DISABLED 32
+#define FAST_FAIL_INVALID_IDLE_STATE 33
+#define FAST_FAIL_MRDATA_PROTECTION_FAILURE 34
+#define FAST_FAIL_UNEXPECTED_HEAP_EXCEPTION 35
+#define FAST_FAIL_INVALID_LOCK_STATE 36
+#define FAST_FAIL_GUARD_JUMPTABLE 37
+#define FAST_FAIL_INVALID_LONGJUMP_TARGET 38
+#define FAST_FAIL_INVALID_DISPATCH_CONTEXT 39
+#define FAST_FAIL_INVALID_THREAD 40
+#define FAST_FAIL_INVALID_SYSCALL_NUMBER 41
+#define FAST_FAIL_INVALID_FILE_OPERATION 42
+#define FAST_FAIL_LPAC_ACCESS_DENIED 43
+#define FAST_FAIL_GUARD_SS_FAILURE 44
+#define FAST_FAIL_LOADER_CONTINUITY_FAILURE 45
+#define FAST_FAIL_GUARD_EXPORT_SUPPRESSION_FAILURE 46
+#define FAST_FAIL_INVALID_CONTROL_STACK 47
+#define FAST_FAIL_SET_CONTEXT_DENIED 48
+#define FAST_FAIL_INVALID_IAT 49
+#define FAST_FAIL_HEAP_METADATA_CORRUPTION 50
+#define FAST_FAIL_PAYLOAD_RESTRICTION_VIOLATION 51
+#define FAST_FAIL_LOW_LABEL_ACCESS_DENIED 52
+#define FAST_FAIL_ENCLAVE_CALL_FAILURE 53
+#define FAST_FAIL_UNHANDLED_LSS_EXCEPTON 54
+#define FAST_FAIL_ADMINLESS_ACCESS_DENIED 55
+#define FAST_FAIL_UNEXPECTED_CALL 56
+#define FAST_FAIL_CONTROL_INVALID_RETURN_ADDRESS 57
+#define FAST_FAIL_UNEXPECTED_HOST_BEHAVIOR 58
+#define FAST_FAIL_FLAGS_CORRUPTION 59
+#define FAST_FAIL_VEH_CORRUPTION 60
+#define FAST_FAIL_ETW_CORRUPTION 61
+#define FAST_FAIL_RIO_ABORT 62
+#define FAST_FAIL_INVALID_PFN 63
+#define FAST_FAIL_GUARD_ICALL_CHECK_FAILURE_XFG 64
+#define FAST_FAIL_CAST_GUARD 65
+#define FAST_FAIL_HOST_VISIBILITY_CHANGE 66
+#define FAST_FAIL_KERNEL_CET_SHADOW_STACK_ASSIST 67
+#define FAST_FAIL_PATCH_CALLBACK_FAILED 68
+#define FAST_FAIL_NTDLL_PATCH_FAILED 69
+#define FAST_FAIL_INVALID_FLS_DATA 70
+#define FAST_FAIL_INVALID_FAST_FAIL_CODE 0xFFFFFFFF
+
+#if defined(__GNUC__)
+#if defined(__x86_64__)
+static FORCEINLINE DECLSPEC_NORETURN void __fastfail(unsigned int code)
+{
+ register ULONGLONG val __asm__("rcx") = code;
+ __asm__ __volatile__( "int $0x29" :: "r" (val) : "memory" );
+#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)))
+ __builtin_unreachable();
+#endif
+}
+#elif defined(__i386__)
+static FORCEINLINE DECLSPEC_NORETURN void __fastfail(unsigned int code)
+{
+ register ULONG val __asm__("ecx") = code;
+ __asm__ __volatile__( "int $0x29" :: "r" (val) : "memory" );
+#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)))
+ __builtin_unreachable();
+#endif
+}
+#elif defined(__aarch64__)
+static FORCEINLINE DECLSPEC_NORETURN void __fastfail(unsigned int code)
+{
+ register ULONGLONG val __asm__("x0") = code;
+ __asm__ __volatile__( "brk #0xf003" :: "r" (val) : "memory" );
+#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)))
+ __builtin_unreachable();
+#endif
+}
+#elif defined(__arm__)
+static FORCEINLINE DECLSPEC_NORETURN void __fastfail(unsigned int code)
+{
+ register ULONG val __asm__("r0") = code;
+ __asm__ __volatile__( "udf #0xfb" :: "r" (val) : "memory" );
+#if defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 5)))
+ __builtin_unreachable();
+#endif
+}
+#endif /* __x86_64__ */
+#elif defined(_MSC_VER) && (_MSC_VER >= 1610)
+DECLSPEC_NORETURN void __fastfail(unsigned int);
+#pragma intrinsic(__fastfail)
+#endif /* __GNUC__ */
+
+
/* Heap flags */
#define HEAP_NO_SERIALIZE 0x00000001
--
2.31.1
2
5
__fastfail() is used by the Visual C++ runtime and Windows system
libraries to signal that the in-process state is corrupted and
unrecoverable.
If __fastfail() is invoked, the NT kernel raises a second-chance
non-continuable exception STATUS_STACK_BUFFER_OVERRUN. This quickly
terminates the process, bypassing all in-process exception handlers
(since they all rely on the potentially corrupted process state).
Signed-off-by: Jinoh Kang <jinoh.kang.kr(a)gmail.com>
---
dlls/ntdll/tests/exception.c | 1 -
dlls/ntdll/unix/signal_arm.c | 14 ++++++++++++--
dlls/ntdll/unix/signal_arm64.c | 11 +++++++++++
dlls/ntdll/unix/signal_i386.c | 7 +++++++
dlls/ntdll/unix/signal_x86_64.c | 7 +++++++
5 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/dlls/ntdll/tests/exception.c b/dlls/ntdll/tests/exception.c
index c0d3ae19a51..14b1396dbc2 100644
--- a/dlls/ntdll/tests/exception.c
+++ b/dlls/ntdll/tests/exception.c
@@ -8429,7 +8429,6 @@ static void subtest_fastfail(unsigned int code)
} while (de.dwDebugEventCode != EXIT_PROCESS_DEBUG_EVENT);
- todo_wine
ok(had_ff || broken(had_se) /* Win7 */, "fast fail did not occur\n");
wait_child_process( pi.hProcess );
diff --git a/dlls/ntdll/unix/signal_arm.c b/dlls/ntdll/unix/signal_arm.c
index dbc2770f72e..1816e210644 100644
--- a/dlls/ntdll/unix/signal_arm.c
+++ b/dlls/ntdll/unix/signal_arm.c
@@ -809,13 +809,23 @@ static void segv_handler( int signal, siginfo_t *siginfo, void *sigcontext )
switch (get_trap_code(signal, context))
{
case TRAP_ARM_PRIVINFLT: /* Invalid opcode exception */
- if (*(WORD *)PC_sig(context) == 0xdefe) /* breakpoint */
+ switch (*(WORD *)PC_sig(context))
{
+ case 0xdefb: /* __fastfail */
+ rec.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
+ rec.ExceptionFlags = EH_NONCONTINUABLE;
+ rec.NumberParameters = 1;
+ rec.ExceptionInformation[0] = REGn_sig(0, context);
+ setup_exception( context, &rec, FALSE );
+ return;
+ case 0xdefe: /* breakpoint */
rec.ExceptionCode = EXCEPTION_BREAKPOINT;
rec.NumberParameters = 1;
break;
+ default:
+ rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
+ break;
}
- rec.ExceptionCode = EXCEPTION_ILLEGAL_INSTRUCTION;
break;
case TRAP_ARM_PAGEFLT: /* Page fault */
rec.NumberParameters = 2;
diff --git a/dlls/ntdll/unix/signal_arm64.c b/dlls/ntdll/unix/signal_arm64.c
index ef70d4df44b..fe80732c03d 100644
--- a/dlls/ntdll/unix/signal_arm64.c
+++ b/dlls/ntdll/unix/signal_arm64.c
@@ -905,6 +905,17 @@ static void bus_handler( int signal, siginfo_t *siginfo, void *sigcontext )
static void trap_handler( int signal, siginfo_t *siginfo, void *sigcontext )
{
EXCEPTION_RECORD rec = { 0 };
+ ucontext_t *context = sigcontext;
+
+ if ((get_fault_esr( context ) & 0xfe00ffffU) == 0xf200f003U)
+ {
+ rec.ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
+ rec.ExceptionFlags = EH_NONCONTINUABLE;
+ rec.NumberParameters = 1;
+ rec.ExceptionInformation[0] = REGn_sig( 0, context );
+ setup_exception( sigcontext, &rec, FALSE );
+ return;
+ }
switch (siginfo->si_code)
{
diff --git a/dlls/ntdll/unix/signal_i386.c b/dlls/ntdll/unix/signal_i386.c
index e18aed2c222..6d448b99223 100644
--- a/dlls/ntdll/unix/signal_i386.c
+++ b/dlls/ntdll/unix/signal_i386.c
@@ -1660,6 +1660,13 @@ static BOOL handle_interrupt( unsigned int interrupt, ucontext_t *sigcontext, vo
switch(interrupt)
{
+ case 0x29:
+ rec->ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
+ rec->ExceptionFlags = EH_NONCONTINUABLE;
+ rec->NumberParameters = 1;
+ rec->ExceptionInformation[0] = context->Ecx;
+ setup_raise_exception( sigcontext, stack, rec, xcontext, FALSE );
+ return TRUE;
case 0x2d:
if (!is_wow64)
{
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c
index ff4a40c7933..39bf1bcc835 100644
--- a/dlls/ntdll/unix/signal_x86_64.c
+++ b/dlls/ntdll/unix/signal_x86_64.c
@@ -2441,6 +2441,13 @@ static inline BOOL handle_interrupt( ucontext_t *sigcontext, EXCEPTION_RECORD *r
switch (ERROR_sig(sigcontext) >> 3)
{
+ case 0x29:
+ rec->ExceptionCode = STATUS_STACK_BUFFER_OVERRUN;
+ rec->ExceptionFlags = EH_NONCONTINUABLE;
+ rec->NumberParameters = 1;
+ rec->ExceptionInformation[0] = context->Rcx;
+ setup_raise_exception( sigcontext, rec, xcontext, FALSE );
+ return TRUE;
case 0x2c:
rec->ExceptionCode = STATUS_ASSERTION_FAILURE;
break;
--
2.31.1
2
1