Wine-Devel
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- 8 participants
- 84547 discussions
Dec. 8, 2021
Signed-off-by: Paul Gofman <pgofman(a)codeweavers.com>
---
dlls/psapi/tests/psapi_main.c | 156 ++++++++++++++++++++++++++++------
1 file changed, 128 insertions(+), 28 deletions(-)
diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c
index c4a740310a4..e383168fde1 100644
--- a/dlls/psapi/tests/psapi_main.c
+++ b/dlls/psapi/tests/psapi_main.c
@@ -55,7 +55,7 @@ static BOOL init_func_ptrs(void)
return TRUE;
}
-static HANDLE hpSR, hpQI, hpVR, hpQV;
+static HANDLE hpSR, hpQI, hpVR, hpQV, hp_vm_op;
static const HANDLE hBad = (HANDLE)0xdeadbeef;
static void test_EnumProcesses(void)
@@ -693,14 +693,65 @@ static void test_GetModuleBaseName(void)
"szModPath=\"%s\" szModBaseName=\"%s\"\n", szModPath, szModBaseName);
}
+static PSAPI_WS_WATCH_INFORMATION wswi[4096];
+
+static void ws_get_watches(void)
+{
+ BOOL ret;
+
+ SetLastError(0xdeadbeef);
+ ret = GetWsChanges(hpQI, wswi, sizeof(wswi));
+ ok(ret == 1, "Got unexpected ret %u, error %u.\n", ret, GetLastError());
+}
+
+#define ws_watch_check_page(a, b, c, d) ws_watch_check_page_(__LINE__, a, b, c, d)
+static void ws_watch_check_page_(unsigned int line, void *addr, void *pc_start, void *pc_end, BOOL expect)
+{
+ static const ULONG_PTR mask = ~(ULONG_PTR)0xfff;
+ unsigned int i;
+
+ for(i = 0; wswi[i].FaultingVa; i++)
+ {
+ if (((ULONG_PTR)wswi[i].FaultingVa & mask) == ((ULONG_PTR)addr & mask))
+ {
+ ok_(__FILE__, line)(expect, "Got unexpected FaultingVa %p.\n", wswi[i].FaultingVa);
+ if (expect)
+ {
+ ok_(__FILE__, line)((void *)wswi[i].FaultingVa == addr, "Got unexpected addr %p, expected %p.\n",
+ (void *)wswi[i].FaultingVa, addr);
+ }
+ ok_(__FILE__, line)(wswi[i].FaultingPc >= pc_start && wswi[i].FaultingPc < pc_end,
+ "Got unexpected FaultingPc %p, start %p.\n", wswi[i].FaultingPc, pc_start);
+ return;
+ }
+ }
+ ok_(__FILE__, line)(!expect, "Page not found.\n");
+}
+
static void test_ws_functions(void)
{
- PSAPI_WS_WATCH_INFORMATION wswi[4096];
+ static const BOOL is_win32 = sizeof(void *) == sizeof(int);
+ static const unsigned int page_count = 16;
+ void *kernel_start, *kernel_end;
+ unsigned int value;
HANDLE ws_handle;
- char *addr;
unsigned int i;
+ HANDLE file;
+ DWORD size;
+ char *addr;
BOOL ret;
+ if (is_win32)
+ {
+ kernel_start = (void *)0x80000000;
+ kernel_end = (void *)0xffffffff;
+ }
+ else
+ {
+ kernel_start = (void *)0xffff000000000000;
+ kernel_end = (void *)0xffffffffffffffff;
+ }
+
ws_handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_SET_QUOTA |
PROCESS_SET_INFORMATION, FALSE, GetCurrentProcessId());
ok(!!ws_handle, "got error %u\n", GetLastError());
@@ -717,6 +768,10 @@ static void test_ws_functions(void)
ret = EmptyWorkingSet(ws_handle);
ok(ret == 1, "failed with %d\n", GetLastError());
+ addr = VirtualAlloc(NULL, page_count * 0x1000, MEM_COMMIT, PAGE_READWRITE);
+ ok(!!addr, "VirtualAlloc failed, error %u.\n", GetLastError());
+ addr[0x1002] = 0;
+
SetLastError( 0xdeadbeef );
ret = InitializeProcessForWsWatch( NULL );
todo_wine ok( !ret, "InitializeProcessForWsWatch succeeded\n" );
@@ -732,35 +787,77 @@ static void test_ws_functions(void)
SetLastError(0xdeadbeef);
ret = InitializeProcessForWsWatch(ws_handle);
ok(ret == 1, "failed with %d\n", GetLastError());
-
- addr = VirtualAlloc(NULL, 1, MEM_COMMIT, PAGE_READWRITE);
- if(!addr)
+
+ ret = GetWsChanges(hpQI, wswi, sizeof(wswi));
+ todo_wine ok(ret == 1 || (!ret && GetLastError() == ERROR_NO_MORE_ITEMS), "failed with %d\n", GetLastError());
+ if (!ret && GetLastError() != ERROR_NO_MORE_ITEMS)
return;
- *addr = 0; /* make sure it's paged in (needed on wow64) */
- if(!VirtualLock(addr, 1))
- {
- trace("locking failed (error=%d) - skipping test\n", GetLastError());
- goto free_page;
- }
+ file = CreateFileA("test.tmp", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL);
+ ok(file != INVALID_HANDLE_VALUE, "CreateFile failed, GetLastError() %u.\n", GetLastError());
+ ws_get_watches();
+
+ ws_watch_check_page(addr + 0x1003, test_ws_functions, (char *)test_ws_functions + 0x10000, FALSE);
+
+ *addr = 0;
+ addr[0x1002] = 0;
+ value = addr[0x2fff];
+ ok(!value, "Got unexpected value %#x.\n", value);
+
+ ret = ReadProcessMemory(hpVR, addr + 0x3002, &value, sizeof(value), NULL);
+ ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError());
+ ret = WriteProcessMemory(hp_vm_op, addr + 0x4000, &value, 1, NULL);
+ ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError());
+
+ ret = WriteFile(file, addr + 0x5000, 1, &size, NULL);
+ ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError());
+
+ ret = ReadFile(file, addr + 0x6002, 2, &size, NULL);
+ ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError());
+ ok(!size, "Got unexpected size %u.\n", size);
+
+ ws_get_watches();
+ ws_watch_check_page(addr + 1, test_ws_functions, (char *)test_ws_functions + 0x10000, TRUE);
+ /* Faulted before InitializeProcessForWsWatch(). */
+ ws_watch_check_page(addr + 0x1003, NULL, NULL, FALSE);
+ ws_watch_check_page(addr + 0x2fff, test_ws_functions, (char *)test_ws_functions + 0x10000, TRUE);
+ ws_watch_check_page(addr + (is_win32 ? 0x3003 : 0x3005), kernel_start, kernel_end, !wow64);
+ ws_watch_check_page(addr + 0x4001, kernel_start, kernel_end, !wow64);
+ ws_watch_check_page(addr + 0x5001, kernel_start, kernel_end, !wow64);
+ ws_watch_check_page(addr + 0x6003, kernel_start, kernel_end, !wow64);
+ for (i = 7; i < page_count; ++i)
+ ws_watch_check_page(addr + 0x1000 * i, NULL, NULL, FALSE);
+
+ ret = VirtualFree(addr, page_count * 0x1000, MEM_DECOMMIT);
+ ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError());
+
+ addr = VirtualAlloc(addr, page_count * 0x1000, MEM_COMMIT, PAGE_READWRITE);
+ ok(!!addr, "VirtualAlloc failed, error %u.\n", GetLastError());
+
+ *addr = 0;
+ addr[0x1000] = 1;
+ ws_get_watches();
+ ws_watch_check_page(addr + 1, test_ws_functions, (char *)test_ws_functions + 0x10000, TRUE);
+ ws_watch_check_page(addr + 0x1001, test_ws_functions, (char *)test_ws_functions + 0x10000, TRUE);
+ for (i = 2; i < page_count; ++i)
+ ws_watch_check_page(addr + 0x1000 * i, NULL, NULL, FALSE);
+
+ ret = VirtualLock(addr, 1);
+ ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError());
+
+ ret = EmptyWorkingSet(ws_handle);
+ ok(ret, "Got unexpected ret %u, error %u.\n", ret, GetLastError());
+ *addr = 0;
+ addr[0x1000] = 1;
+ ws_get_watches();
+ ws_watch_check_page(addr, NULL, NULL, FALSE);
+ ws_watch_check_page(addr + 0x1001, test_ws_functions, (char *)test_ws_functions + 0x10000, TRUE);
+ for (i = 2; i < page_count; ++i)
+ ws_watch_check_page(addr + 0x1000 * i, NULL, NULL, FALSE);
- SetLastError(0xdeadbeef);
- ret = GetWsChanges(hpQI, wswi, sizeof(wswi));
- todo_wine ok(ret == 1, "failed with %d\n", GetLastError());
- if(ret == 1)
- {
- for(i = 0; wswi[i].FaultingVa; i++)
- if(((ULONG_PTR)wswi[i].FaultingVa & ~0xfffL) == (ULONG_PTR)addr)
- {
- todo_wine ok(ret == 1, "GetWsChanges found our page\n");
- goto free_page;
- }
-
- todo_wine ok(0, "GetWsChanges didn't find our page\n");
- }
-
-free_page:
VirtualFree(addr, 0, MEM_RELEASE);
+ CloseHandle(file);
+ DeleteFileA("test.tmp");
}
static void check_QueryWorkingSetEx(PVOID addr, const char *desc, DWORD expected_valid,
@@ -859,6 +956,9 @@ START_TEST(psapi_main)
if (pIsWow64Process)
IsWow64Process(GetCurrentProcess(), &wow64);
+ hp_vm_op = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, pid);
+ ok(!!hp_vm_op, "got error %u\n", GetLastError());
+
hpSR = OpenProcess(STANDARD_RIGHTS_REQUIRED, FALSE, pid);
ok(!!hpSR, "got error %u\n", GetLastError());
hpQI = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
--
2.33.1
2
1
https://bugs.winehq.org/show_bug.cgi?id=52173
Signed-off-by: Louis Lenders <xerox.xerox2000x(a)gmail.com>
---
dlls/wsdapi/discovery.c | 7 +++++
dlls/wsdapi/wsdapi.spec | 2 +-
include/wsddisco.idl | 60 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 68 insertions(+), 1 deletion(-)
diff --git a/dlls/wsdapi/discovery.c b/dlls/wsdapi/discovery.c
index fcbdfef2ab2..502e5f016e6 100644
--- a/dlls/wsdapi/discovery.c
+++ b/dlls/wsdapi/discovery.c
@@ -470,3 +470,10 @@ HRESULT WINAPI WSDCreateDiscoveryPublisher(IWSDXMLContext *pContext, IWSDiscover
return S_OK;
}
+
+HRESULT WINAPI WSDCreateDiscoveryProvider(IWSDXMLContext *context, IWSDiscoveryProvider **provider)
+{
+ FIXME("(%p, %p) stub\n", context, provider);
+
+ return E_NOTIMPL;
+}
\ No newline at end of file
diff --git a/dlls/wsdapi/wsdapi.spec b/dlls/wsdapi/wsdapi.spec
index 95ee072a1cf..d7465458dd5 100644
--- a/dlls/wsdapi/wsdapi.spec
+++ b/dlls/wsdapi/wsdapi.spec
@@ -15,7 +15,7 @@
@ stub WSDCreateDeviceProxy
@ stub WSDCreateDeviceProxyAdvanced
@ stub WSDCreateDiscoveryProvider2
-@ stub WSDCreateDiscoveryProvider
+@ stdcall WSDCreateDiscoveryProvider(ptr ptr)
@ stub WSDCreateDiscoveryPublisher2
@ stdcall WSDCreateDiscoveryPublisher(ptr ptr)
@ stub WSDCreateHttpAddress
diff --git a/include/wsddisco.idl b/include/wsddisco.idl
index 50d2198cea7..74bb3e250c1 100644
--- a/include/wsddisco.idl
+++ b/include/wsddisco.idl
@@ -24,6 +24,9 @@ interface IWSDScopeMatchingRule;
interface IWSDiscoveryPublisherNotify;
interface IWSDiscoveryPublisher;
interface IWSDXMLContext;
+interface IWSDiscoveryProvider;
+interface IWSDiscoveryProviderNotify;
+interface IWSDiscoveredService;
[
uuid(fcafe424-fef5-481a-bd9f-33ce0574256f),
@@ -38,6 +41,62 @@ interface IWSDScopeMatchingRule : IUnknown
HRESULT MatchScopes([in] LPCWSTR pszScope1, [in] LPCWSTR pszScope2, [out] BOOL *pfMatch);
}
+[
+uuid(73ee3ced-b6e6-4329-a546-3e8ad46563d2),
+object,
+local,
+restricted,
+pointer_default(unique)
+]
+interface IWSDiscoveryProviderNotify : IUnknown
+{
+ HRESULT Add([in] IWSDiscoveredService *service);
+ HRESULT Remove([in] IWSDiscoveredService *service);
+ HRESULT SearchFailed([in] HRESULT hr,[in, optional] LPCWSTR tag);
+ HRESULT SearchComplete([in, optional] LPCWSTR tag);
+}
+
+[
+uuid(4bad8a3b-b374-4420-9632-aac945b374aa),
+object,
+local,
+restricted,
+pointer_default(unique)
+]
+interface IWSDiscoveredService : IUnknown
+{
+ HRESULT GetEndpointReference([out] WSD_ENDPOINT_REFERENCE **endpoint_reference);
+ HRESULT GetTypes([out] WSD_NAME_LIST **types_list);
+ HRESULT GetScopes([out] WSD_URI_LIST **scopes_list);
+ HRESULT GetXAddrs([out] WSD_URI_LIST **x_addrs_list);
+ HRESULT GetMetadataVersion([out] ULONGLONG *metadata_version);
+ HRESULT GetExtendedDiscoXML([out] WSDXML_ELEMENT **header_any,[out] WSDXML_ELEMENT **body_any);
+ HRESULT GetProbeResolveTag([out] LPCWSTR *tag);
+ HRESULT GetRemoteTransportAddress([out] LPCWSTR *remote_transport_address);
+ HRESULT GetLocalTransportAddress([out] LPCWSTR *local_transport_address);
+ HRESULT GetLocalInterfaceGUID([out] GUID *guid);
+ HRESULT GetInstanceId([out] ULONGLONG *instance_id);
+}
+
+[
+uuid (8ffc8e55-f0eb-480f-88b7-b435dd281d45),
+object,
+local,
+restricted,
+pointer_default(unique)
+]
+interface IWSDiscoveryProvider : IUnknown
+{
+ HRESULT SetAddressFamily([in] DWORD address_family);
+ HRESULT Attach([in] IWSDiscoveryProviderNotify *sink);
+ HRESULT Detach(void);
+ HRESULT SearchById([in] LPCWSTR id,[in, optional] LPCWSTR tag);
+ HRESULT SearchByAddress([in] LPCWSTR address,[in, optional] LPCWSTR tag);
+ HRESULT SearchByType([in, optional] const WSD_NAME_LIST *types_list, \
+ [in, optional] const WSD_URI_LIST *scopes_list,[in, optional] LPCWSTR match_by,[in, optional] LPCWSTR tag);
+ HRESULT GetXMLContext([out] IWSDXMLContext **context);
+}
+
[
uuid(e67651b0-337a-4b3c-9758-733388568251),
object,
@@ -104,4 +163,5 @@ interface IWSDiscoveryPublisher : IUnknown
HRESULT GetXMLContext([out] IWSDXMLContext **ppContext);
}
+cpp_quote("HRESULT WINAPI WSDCreateDiscoveryProvider(IWSDXMLContext *context, IWSDiscoveryProvider **provider);")
cpp_quote("HRESULT WINAPI WSDCreateDiscoveryPublisher(IWSDXMLContext* pContext, IWSDiscoveryPublisher **ppPublisher);")
--
2.34.1
2
1
Dec. 8, 2021
Signed-off-by: Jactry Zeng <jzeng(a)codeweavers.com>
---
dlls/msxml3/main.c | 11 ++++++
dlls/msxml3/tests/domdoc.c | 80 +++++++++++++++++++++++++++++---------
2 files changed, 73 insertions(+), 18 deletions(-)
diff --git a/dlls/msxml3/main.c b/dlls/msxml3/main.c
index ba8d3b2e21b..2a97f2637f1 100644
--- a/dlls/msxml3/main.c
+++ b/dlls/msxml3/main.c
@@ -202,6 +202,16 @@ done:
return len;
}
+static int gbk_to_utf8(unsigned char *out, int *outlen, const unsigned char *in, int *inlen)
+{
+ return to_utf8(936, out, outlen, in, inlen);
+}
+
+static int utf8_to_gbk(unsigned char *out, int *outlen, const unsigned char *in, int *inlen)
+{
+ return from_utf8(936, out, outlen, in, inlen);
+}
+
static int win1250_to_utf8(unsigned char *out, int *outlen, const unsigned char *in, int *inlen)
{
return to_utf8(1250, out, outlen, in, inlen);
@@ -300,6 +310,7 @@ static void init_char_encoders(void)
xmlCharEncodingOutputFunc output;
} encoder[] =
{
+ { "gbk", gbk_to_utf8, utf8_to_gbk },
{ "windows-1250", win1250_to_utf8, utf8_to_win1250 },
{ "windows-1251", win1251_to_utf8, utf8_to_win1251 },
{ "windows-1252", win1252_to_utf8, utf8_to_win1252 },
diff --git a/dlls/msxml3/tests/domdoc.c b/dlls/msxml3/tests/domdoc.c
index 70e2da89a2f..e931c683fb8 100644
--- a/dlls/msxml3/tests/domdoc.c
+++ b/dlls/msxml3/tests/domdoc.c
@@ -781,6 +781,20 @@ static const char complete7[] = {
"</root>"
};
+#define DECL_GBK \
+"<?xml version=\"1.0\" encoding=\"gbk\"?>"
+
+static const char gbkxml[] =
+DECL_GBK
+"<open></open>";
+
+#define DECL_WIN_936 \
+"<?xml version=\"1.0\" encoding=\"Windows-936\"?>"
+
+static const char win936xml[] =
+DECL_WIN_936
+"<open></open>";
+
#define DECL_WIN_1252 \
"<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"
@@ -10506,7 +10520,10 @@ static void write_to_file(const char *name, const char *data)
CloseHandle(hfile);
}
-static void test_doc_load_from_path(IXMLDOMDocument *doc, const char *path)
+#define TEST_DOC_LOAD_FROM_PATH(doc,path,expected_hr, expected_ret) \
+ _test_doc_load_from_path(doc, path, expected_hr, expected_ret, __LINE__)
+static void _test_doc_load_from_path(IXMLDOMDocument *doc, const char *path,
+ HRESULT expected_hr, VARIANT_BOOL expected_ret, int line)
{
IXMLDOMDocument *doc2;
IXMLDOMElement *elem;
@@ -10520,29 +10537,32 @@ static void test_doc_load_from_path(IXMLDOMDocument *doc, const char *path)
V_VT(&src) = VT_BSTR;
V_BSTR(&src) = url;
hr = IXMLDOMDocument_load(doc, src, &b);
- ok(hr == S_OK, "Failed to load document, %#x.\n", hr);
- ok(b == VARIANT_TRUE, "got %d\n", b);
+ ok_(__FILE__, line)(hr == expected_hr, "Failed to load document, %#x.\n", hr);
+ ok_(__FILE__, line)(b == expected_ret, "got %d\n", b);
V_VT(&src) = VT_BSTR | VT_BYREF;
V_BSTRREF(&src) = &url;
hr = IXMLDOMDocument_load(doc, src, &b);
- ok(hr == S_OK, "Failed to load document, %#x.\n", hr);
- ok(b == VARIANT_TRUE, "got %d\n", b);
+ ok_(__FILE__, line)(hr == expected_hr, "Failed to load document, %#x.\n", hr);
+ ok_(__FILE__, line)(b == expected_ret, "got %d\n", b);
+
+ if (expected_hr != S_OK)
+ return;
url = NULL;
hr = IXMLDOMDocument_get_url(doc, &url);
- ok(hr == S_OK, "Failed to get document url, hr %#x.\n", hr);
+ ok_(__FILE__, line)(hr == S_OK, "Failed to get document url, hr %#x.\n", hr);
hr = IXMLDOMDocument_get_documentElement(doc, &elem);
- ok(hr == S_OK, "got 0x%08x\n", hr);
+ ok_(__FILE__, line)(hr == S_OK, "got 0x%08x\n", hr);
/* Create another instance for the same document, check url */
hr = IXMLDOMElement_get_ownerDocument(elem, &doc2);
- ok(hr == S_OK, "Failed to get owner document, hr %#x.\n", hr);
+ ok_(__FILE__, line)(hr == S_OK, "Failed to get owner document, hr %#x.\n", hr);
hr = IXMLDOMDocument_get_url(doc2, &url2);
- ok(hr == S_OK, "Failed to get document url, hr %#x.\n", hr);
- ok(!lstrcmpW(url, url2), "Unexpected url %s.\n", wine_dbgstr_w(url2));
+ ok_(__FILE__, line)(hr == S_OK, "Failed to get document url, hr %#x.\n", hr);
+ ok_(__FILE__, line)(!lstrcmpW(url, url2), "Unexpected url %s.\n", wine_dbgstr_w(url2));
IXMLDOMDocument_Release(doc2);
IXMLDOMElement_Release(elem);
@@ -10574,6 +10594,18 @@ static void test_load(void)
HRESULT hr;
void* ptr;
int n;
+ struct encoding_test
+ {
+ const char *xml;
+ HRESULT expected_hr;
+ VARIANT_BOOL expected_ret;
+ } encoding_tests[] =
+ {
+ { gbkxml, S_OK, VARIANT_TRUE },
+ { win1252xml, S_OK, VARIANT_TRUE },
+ { win936xml, S_FALSE, VARIANT_FALSE },
+ };
+
GetTempPathA(MAX_PATH, path);
strcat(path, "winetest.xml");
@@ -10593,23 +10625,23 @@ static void test_load(void)
/* "file://" url */
strcpy(path2, "file://");
strcat(path2, path);
- test_doc_load_from_path(doc, path2);
+ TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
/* file:// url, forward slashes */
url_forward_slash(path2);
- test_doc_load_from_path(doc, path2);
+ TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
/* "file:/" url */
strcpy(path2, "file:/");
strcat(path2, path);
- test_doc_load_from_path(doc, path);
+ TEST_DOC_LOAD_FROM_PATH(doc, path, S_OK, VARIANT_TRUE);
/* file:/ with forward slashes. */
url_forward_slash(path2);
- test_doc_load_from_path(doc, path2);
+ TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
/* Regular local path. */
- test_doc_load_from_path(doc, path);
+ TEST_DOC_LOAD_FROM_PATH(doc, path, S_OK, VARIANT_TRUE);
/* load from a path: VT_BSTR|VT_BYREF, null ptr */
V_VT(&src) = VT_BSTR | VT_BYREF;
@@ -10627,16 +10659,16 @@ static void test_load(void)
strcpy(path2, path);
n = strlen(path2);
strcpy(&path2[n-1], "%6C"); /* C:\path\to\winetest.xm%6C */
- test_doc_load_from_path(doc, path2);
+ TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
/* Both spaces and %20s work. */
GetTempPathA(MAX_PATH, path2);
strcat(path2, "wine test.xml");
write_to_file(path2, win1252xml);
- test_doc_load_from_path(doc, path2);
+ TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
GetTempPathA(MAX_PATH, path2);
strcat(path2, "wine%20test.xml");
- test_doc_load_from_path(doc, path2);
+ TEST_DOC_LOAD_FROM_PATH(doc, path2, S_OK, VARIANT_TRUE);
DeleteFileA(path2);
DeleteFileA(path);
@@ -10771,6 +10803,18 @@ static void test_load(void)
IXMLDOMDocument_Release(doc);
+ /* Encoding tests. */
+ for (n = 0; n < ARRAY_SIZE(encoding_tests); n++)
+ {
+ GetTempPathA(MAX_PATH, path);
+ strcat(path, "codepage_test.xml");
+ write_to_file(path, encoding_tests[n].xml);
+ doc = create_document(&IID_IXMLDOMDocument);
+ TEST_DOC_LOAD_FROM_PATH(doc, path, encoding_tests[n].expected_hr, encoding_tests[n].expected_ret);
+ DeleteFileA(path);
+ IXMLDOMDocument_Release(doc);
+ }
+
free_bstrs();
}
--
2.33.0
2
1
[PATCH] ntdll: Remove a special case for EP not in executable section in map_image_into_view().
by Paul Gofman Dec. 8, 2021
by Paul Gofman Dec. 8, 2021
Dec. 8, 2021
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 Dec. 8, 2021
by Alex Henrie Dec. 8, 2021
Dec. 8, 2021
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
Dec. 8, 2021
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
Dec. 8, 2021
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