Wine-Devel
By thread
wine-devel@list.winehq.org
By month
Messages by month
- ----- 2026 -----
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2003 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2002 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2001 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
December 2019
- 73 participants
- 1394 messages
[PATCH vkd3d v3 3/5] vkd3d: Implement support for D3D12_FEATURE_D3D12_OPTIONS2.
by Conor McCarthy
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
---
include/vkd3d_d3d12.idl | 13 +++++++++++++
libs/vkd3d/device.c | 22 ++++++++++++++++++++++
libs/vkd3d/vkd3d_private.h | 1 +
3 files changed, 36 insertions(+)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl
index ec102a8..4c69454 100644
--- a/include/vkd3d_d3d12.idl
+++ b/include/vkd3d_d3d12.idl
@@ -177,6 +177,13 @@ typedef enum D3D12_FORMAT_SUPPORT2
D3D12_FORMAT_SUPPORT2_MULTIPLANE_OVERLAY = 0x00004000,
} D3D12_FORMAT_SUPPORT2;
+typedef enum D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER
+{
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED = 0x0,
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_1 = 0x1,
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_2 = 0x2,
+} D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER;
+
interface ID3D12Fence;
interface ID3D12RootSignature;
interface ID3D12Heap;
@@ -1627,6 +1634,12 @@ typedef struct D3D12_FEATURE_DATA_ARCHITECTURE1
BOOL IsolatedMMU;
} D3D12_FEATURE_DATA_ARCHITECTURE1;
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS2
+{
+ BOOL DepthBoundsTestSupported;
+ D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER ProgrammableSamplePositionsTier;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS2;
+
typedef enum D3D12_FEATURE
{
D3D12_FEATURE_D3D12_OPTIONS = 0,
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index dc8ca44..1063680 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1343,6 +1343,11 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
device->feature_options1.ExpandedComputeResourceStates = TRUE;
device->feature_options1.Int64ShaderOps = features->shaderInt64;
+ /* Depth bounds test is enabled in D3D12_DEPTH_STENCIL_DESC1, which is not supported. */
+ device->feature_options2.DepthBoundsTestSupported = FALSE;
+ /* d3d12_command_list_SetSamplePositions() is not implemented. */
+ device->feature_options2.ProgrammableSamplePositionsTier = D3D12_PROGRAMMABLE_SAMPLE_POSITIONS_TIER_NOT_SUPPORTED;
+
if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL))) < 0)
{
ERR("Failed to enumerate device extensions, vr %d.\n", vr);
@@ -2744,6 +2749,23 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *
return S_OK;
}
+ case D3D12_FEATURE_D3D12_OPTIONS2:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS2 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options2;
+
+ TRACE("Depth bounds test %#x.\n", data->DepthBoundsTestSupported);
+ TRACE("Programmable sample positions tier %#x.\n", data->ProgrammableSamplePositionsTier);
+ return S_OK;
+ }
+
default:
FIXME("Unhandled feature %#x.\n", feature);
return E_NOTIMPL;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 6c7ec4e..72a7913 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -1135,6 +1135,7 @@ struct d3d12_device
D3D12_FEATURE_DATA_D3D12_OPTIONS feature_options;
D3D12_FEATURE_DATA_D3D12_OPTIONS1 feature_options1;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS2 feature_options2;
struct vkd3d_vulkan_info vk_info;
--
2.24.0
Dec. 5, 2019
[PATCH vkd3d v3 2/5] vkd3d: Implement support for D3D12_FEATURE_ARCHITECTURE1.
by Conor McCarthy
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
---
include/vkd3d_d3d12.idl | 9 +++++++++
libs/vkd3d/device.c | 31 +++++++++++++++++++++++++++++++
2 files changed, 40 insertions(+)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl
index 5cfb229..ec102a8 100644
--- a/include/vkd3d_d3d12.idl
+++ b/include/vkd3d_d3d12.idl
@@ -1618,6 +1618,15 @@ typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS1
BOOL Int64ShaderOps;
} D3D12_FEATURE_DATA_D3D12_OPTIONS1;
+typedef struct D3D12_FEATURE_DATA_ARCHITECTURE1
+{
+ UINT NodeIndex;
+ BOOL TileBasedRenderer;
+ BOOL UMA;
+ BOOL CacheCoherentUMA;
+ BOOL IsolatedMMU;
+} D3D12_FEATURE_DATA_ARCHITECTURE1;
+
typedef enum D3D12_FEATURE
{
D3D12_FEATURE_D3D12_OPTIONS = 0,
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index 90044ac..dc8ca44 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -2713,6 +2713,37 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *
return S_OK;
}
+ case D3D12_FEATURE_ARCHITECTURE1:
+ {
+ D3D12_FEATURE_DATA_ARCHITECTURE1 *data = feature_data;
+ bool coherent;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ if (data->NodeIndex)
+ {
+ FIXME("Multi-adapter not supported.\n");
+ return E_INVALIDARG;
+ }
+
+ WARN("Assuming device does not support tile based rendering.\n");
+ data->TileBasedRenderer = FALSE;
+
+ data->UMA = d3d12_device_is_uma(device, &coherent);
+ data->CacheCoherentUMA = data->UMA ? coherent : FALSE;
+
+ WARN("Assuming device does not have an isolated memory management unit.\n");
+ data->IsolatedMMU = FALSE;
+
+ TRACE("Tile based renderer %#x, UMA %#x, cache coherent UMA %#x, isolated MMU %#x.\n",
+ data->TileBasedRenderer, data->UMA, data->CacheCoherentUMA, data->IsolatedMMU);
+ return S_OK;
+ }
+
default:
FIXME("Unhandled feature %#x.\n", feature);
return E_NOTIMPL;
--
2.24.0
Dec. 5, 2019
[PATCH vkd3d v3 1/5] vkd3d: Implement support for D3D12_FEATURE_D3D12_OPTIONS1.
by Conor McCarthy
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
---
include/vkd3d_d3d12.idl | 10 ++++++++++
libs/vkd3d/device.c | 28 ++++++++++++++++++++++++++++
libs/vkd3d/vkd3d_private.h | 1 +
3 files changed, 39 insertions(+)
diff --git a/include/vkd3d_d3d12.idl b/include/vkd3d_d3d12.idl
index ec8b83d..5cfb229 100644
--- a/include/vkd3d_d3d12.idl
+++ b/include/vkd3d_d3d12.idl
@@ -1608,6 +1608,16 @@ typedef struct D3D12_FEATURE_DATA_SHADER_MODEL
D3D_SHADER_MODEL HighestShaderModel;
} D3D12_FEATURE_DATA_SHADER_MODEL;
+typedef struct D3D12_FEATURE_DATA_D3D12_OPTIONS1
+{
+ BOOL WaveOps;
+ UINT WaveLaneCountMin;
+ UINT WaveLaneCountMax;
+ UINT TotalLaneCount;
+ BOOL ExpandedComputeResourceStates;
+ BOOL Int64ShaderOps;
+} D3D12_FEATURE_DATA_D3D12_OPTIONS1;
+
typedef enum D3D12_FEATURE
{
D3D12_FEATURE_D3D12_OPTIONS = 0,
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index fd593bc..90044ac 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -1336,6 +1336,13 @@ static HRESULT vkd3d_init_device_caps(struct d3d12_device *device,
device->feature_options.VPAndRTArrayIndexFromAnyShaderFeedingRasterizerSupportedWithoutGSEmulation = FALSE;
device->feature_options.ResourceHeapTier = D3D12_RESOURCE_HEAP_TIER_2;
+ device->feature_options1.WaveOps = FALSE;
+ device->feature_options1.WaveLaneCountMin = 0;
+ device->feature_options1.WaveLaneCountMax = 0;
+ device->feature_options1.TotalLaneCount = 0;
+ device->feature_options1.ExpandedComputeResourceStates = TRUE;
+ device->feature_options1.Int64ShaderOps = features->shaderInt64;
+
if ((vr = VK_CALL(vkEnumerateDeviceExtensionProperties(physical_device, NULL, &count, NULL))) < 0)
{
ERR("Failed to enumerate device extensions, vr %d.\n", vr);
@@ -2668,6 +2675,27 @@ static HRESULT STDMETHODCALLTYPE d3d12_device_CheckFeatureSupport(ID3D12Device *
return S_OK;
}
+ case D3D12_FEATURE_D3D12_OPTIONS1:
+ {
+ D3D12_FEATURE_DATA_D3D12_OPTIONS1 *data = feature_data;
+
+ if (feature_data_size != sizeof(*data))
+ {
+ WARN("Invalid size %u.\n", feature_data_size);
+ return E_INVALIDARG;
+ }
+
+ *data = device->feature_options1;
+
+ TRACE("Wave ops %#x.\n", data->WaveOps);
+ TRACE("Min wave lane count %#x.\n", data->WaveLaneCountMin);
+ TRACE("Max wave lane count %#x.\n", data->WaveLaneCountMax);
+ TRACE("Total lane count %#x.\n", data->TotalLaneCount);
+ TRACE("Expanded compute resource states %#x.\n", data->ExpandedComputeResourceStates);
+ TRACE("Int64 shader ops %#x.\n", data->Int64ShaderOps);
+ return S_OK;
+ }
+
case D3D12_FEATURE_ROOT_SIGNATURE:
{
D3D12_FEATURE_DATA_ROOT_SIGNATURE *data = feature_data;
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 28801ba..6c7ec4e 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -1134,6 +1134,7 @@ struct d3d12_device
PFN_vkd3d_memory_usage_callback pfn_memory_usage_callback;
D3D12_FEATURE_DATA_D3D12_OPTIONS feature_options;
+ D3D12_FEATURE_DATA_D3D12_OPTIONS1 feature_options1;
struct vkd3d_vulkan_info vk_info;
--
2.24.0
Dec. 5, 2019
[PATCH vkd3d v3 0/5] Add more features to CheckFeatureSupport().
by Conor McCarthy
Some games, e.g. Shadow of the Tomb Raider, do not check for success,
and if the feature check is unimplemented they will use uninitialised
data for the result.
Supersedes 174666.
Conor McCarthy (5):
vkd3d: Implement support for D3D12_FEATURE_D3D12_OPTIONS1.
vkd3d: Implement support for D3D12_FEATURE_ARCHITECTURE1.
vkd3d: Implement support for D3D12_FEATURE_D3D12_OPTIONS2.
vkd3d: Implement support for D3D12_FEATURE_SHADER_CACHE.
vkd3d: Implement support for D3D12_FEATURE_COMMAND_QUEUE_PRIORITY.
include/vkd3d_d3d12.idl | 53 ++++++++++++++++
libs/vkd3d/device.c | 126 +++++++++++++++++++++++++++++++++++++
libs/vkd3d/vkd3d_private.h | 2 +
3 files changed, 181 insertions(+)
--
2.24.0
Dec. 5, 2019
[PATCH 2/2] kernel32/tests: Add a basic test for PROC_THREAD_ATTRIBUTE_PARENT_PROCESS process creation attribute.
by Paul Gofman
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
dlls/kernel32/tests/process.c | 126 +++++++++++++++++++++++++++++++++-
1 file changed, 124 insertions(+), 2 deletions(-)
diff --git a/dlls/kernel32/tests/process.c b/dlls/kernel32/tests/process.c
index f181536e7a..a3118d11bf 100644
--- a/dlls/kernel32/tests/process.c
+++ b/dlls/kernel32/tests/process.c
@@ -36,6 +36,7 @@
#include "tlhelp32.h"
#include "wine/test.h"
+#include "wine/heap.h"
/* PROCESS_ALL_ACCESS in Vista+ PSDKs is incompatible with older Windows versions */
#define PROCESS_ALL_ACCESS_NT4 (PROCESS_ALL_ACCESS & ~0xf000)
@@ -3808,6 +3809,120 @@ static void test_ProcThreadAttributeList(void)
pDeleteProcThreadAttributeList(&list);
}
+/* level 0: Main test process
+ * level 1: Process created by level 0 process without handle inheritance
+ * level 2: Process created by level 1 process with handle inheritance and level 0
+ * process parent substitute. */
+void test_parent_process_attribute(unsigned int level, HANDLE read_pipe)
+{
+ PROCESS_BASIC_INFORMATION pbi;
+ char buffer[MAX_PATH + 64];
+ HANDLE write_pipe = NULL;
+ PROCESS_INFORMATION info;
+ SECURITY_ATTRIBUTES sa;
+ STARTUPINFOEXA si;
+ DWORD parent_id;
+ NTSTATUS status;
+ ULONG pbi_size;
+ HANDLE parent;
+ DWORD size;
+ BOOL ret;
+
+ struct
+ {
+ HANDLE parent;
+ DWORD parent_id;
+ }
+ parent_data;
+
+ if (!pInitializeProcThreadAttributeList)
+ {
+ win_skip("No support for ProcThreadAttributeList.\n");
+ return;
+ }
+
+ memset(&sa, 0, sizeof(sa));
+ sa.nLength = sizeof(sa);
+ sa.bInheritHandle = TRUE;
+
+ if (!level)
+ {
+ ret = CreatePipe(&read_pipe, &write_pipe, &sa, 0);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+ parent_data.parent = OpenProcess(PROCESS_CREATE_PROCESS | PROCESS_QUERY_INFORMATION, TRUE, GetCurrentProcessId());
+ parent_data.parent_id = GetCurrentProcessId();
+ }
+ else
+ {
+ status = NtQueryInformationProcess(GetCurrentProcess(), ProcessBasicInformation, &pbi, sizeof(pbi), &pbi_size);
+ ok(status == STATUS_SUCCESS, "Got unexpected status %#x.\n", status);
+ parent_id = pbi.InheritedFromUniqueProcessId;
+
+ memset(&parent_data, 0, sizeof(parent_data));
+ ret = ReadFile(read_pipe, &parent_data, sizeof(parent_data), &size, NULL);
+ todo_wine_if(level == 2) ok((level == 2 && ret) || (level == 1 && !ret && GetLastError() == ERROR_INVALID_HANDLE),
+ "Got unexpected ret %#x, level %u, GetLastError() %u.\n",
+ ret, level, GetLastError());
+ }
+
+ if (level == 2)
+ {
+ todo_wine ok(parent_id == parent_data.parent_id, "Got parent id %u, parent_data.parent_id %u.\n",
+ parent_id, parent_data.parent_id);
+ return;
+ }
+
+ memset(&si, 0, sizeof(si));
+ si.StartupInfo.cb = sizeof(si.StartupInfo);
+
+ if (level)
+ {
+ SIZE_T size;
+
+ ret = pInitializeProcThreadAttributeList(NULL, 1, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ si.lpAttributeList = heap_alloc(size);
+ ret = pInitializeProcThreadAttributeList(si.lpAttributeList, 1, 0, &size);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+ parent = OpenProcess(PROCESS_CREATE_PROCESS, FALSE, parent_id);
+
+ ret = pUpdateProcThreadAttribute(si.lpAttributeList, 0, PROC_THREAD_ATTRIBUTE_PARENT_PROCESS,
+ &parent, sizeof(parent), NULL, NULL);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+ }
+
+ sprintf(buffer, "\"%s\" tests/process.c parent %u %p", selfname, level + 1, read_pipe);
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, level == 1, level == 1 ? EXTENDED_STARTUPINFO_PRESENT : 0,
+ NULL, NULL, (STARTUPINFOA *)&si, &info);
+ ok(ret, "Got unexpected ret %#x, GetLastError() %u.\n", ret, GetLastError());
+
+ if (level)
+ {
+ pDeleteProcThreadAttributeList(si.lpAttributeList);
+ heap_free(si.lpAttributeList);
+ CloseHandle(parent);
+ }
+ else
+ {
+ ret = WriteFile(write_pipe, &parent_data, sizeof(parent_data), &size, NULL);
+ }
+
+ /* wait for child to terminate */
+ ok(WaitForSingleObject(info.hProcess, 30000) == WAIT_OBJECT_0, "Child process termination\n");
+ CloseHandle(info.hThread);
+ CloseHandle(info.hProcess);
+
+ if (!level)
+ {
+ CloseHandle(read_pipe);
+ CloseHandle(write_pipe);
+ CloseHandle(parent_data.parent);
+ }
+}
+
START_TEST(process)
{
HANDLE job;
@@ -3851,11 +3966,18 @@ START_TEST(process)
CloseHandle(info.hThread);
return;
}
+ else if (!strcmp(myARGV[2], "parent") && myARGC >= 5)
+ {
+ HANDLE h;
+
+ sscanf(myARGV[4], "%p", &h);
+ test_parent_process_attribute(atoi(myARGV[3]), h);
+ return;
+ }
ok(0, "Unexpected command %s\n", myARGV[2]);
return;
}
-
hproc = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, GetCurrentProcessId());
if (hproc)
{
@@ -3865,7 +3987,6 @@ START_TEST(process)
else
win_skip("PROCESS_QUERY_LIMITED_INFORMATION is not supported on this platform\n");
test_process_info(GetCurrentProcess());
-
test_TerminateProcess();
test_Startup();
test_CommandLine();
@@ -3919,4 +4040,5 @@ START_TEST(process)
test_jobInheritance(job);
test_BreakawayOk(job);
CloseHandle(job);
+ test_parent_process_attribute(0, NULL);
}
--
2.23.0
Dec. 5, 2019
[PATCH 1/2] include/winbase.h: Add STARTUPINFOEX structure definition.
by Paul Gofman
Signed-off-by: Paul Gofman <gofmanp(a)gmail.com>
---
include/winbase.h | 13 +++++++++++++
1 file changed, 13 insertions(+)
diff --git a/include/winbase.h b/include/winbase.h
index 2d01dcb606..71f7ea1586 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -1736,6 +1736,19 @@ typedef enum _PROC_THREAD_ATTRIBUTE_NUM
#define SYMBOLIC_LINK_FLAG_DIRECTORY (0x1)
#define VALID_SYMBOLIC_LINK_FLAGS SYMBOLIC_LINK_FLAG_DIRECTORY
+typedef struct _STARTUPINFOEXA{
+ STARTUPINFOA StartupInfo;
+ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
+} STARTUPINFOEXA, *LPSTARTUPINFOEXA;
+
+typedef struct _STARTUPINFOEXW{
+ STARTUPINFOW StartupInfo;
+ LPPROC_THREAD_ATTRIBUTE_LIST lpAttributeList;
+} STARTUPINFOEXW, *LPSTARTUPINFOEXW;
+
+DECL_WINELIB_TYPE_AW(STARTUPINFOEX)
+DECL_WINELIB_TYPE_AW(LPSTARTUPINFOEX)
+
typedef void *PUMS_CONTEXT;
typedef void *PUMS_COMPLETION_LIST;
typedef PRTL_UMS_SCHEDULER_ENTRY_POINT PUMS_SCHEDULER_ENTRY_POINT;
--
2.23.0
Dec. 5, 2019
Re: [wine-devel] Wine staging 4.21 release
by Olivier F. R. Dierick
Le mercredi 04 décembre 2019 à 14:56 -0800, Alan W. Irwin a écrit :
> On 2019-11-30 04:56-0000 Alistair Leslie-Hughes wrote:
>
> > Added:
> > * [47668] kernelbase: Improve stub for ReOpenFile and add small
> > test
> > * [48138] League of Legends 9.23: Crash after champ select
> > * [47970] Legends of Runeterra crashes at launch
> > * [40334] AION - Wine /Unhandled exception: page fault on read
> > access to
> > 0x00000000 in 64-bit code (0x0000000000000000).
> > * [48175] AION (64 bit) - crashes in crysystem.dll.CryFree() due to
> > high
> > memory pointers allocated
> > * [46568] 64-bit msxml6.dll from Microsoft Core XML Services 6.0
> > redist
> > package fails to load (Wine doesn't respect 44-bit user-mode VA
> > limitation from Windows < 8.1)
> >
> [...]
>
> Could you explain how these patch numbers in your report are related
> with each other?
>
Hello,
The numbers between brackets are winehq.org bugzilla bug numbers.
For example, in "[47668] kernelbase: Improve stub for ReOpenFile and
add small test", "47668" is the bug number that the patch "kernelbase:
Improve stub for ReOpenFile" is accommodating. The referenced bug can
be found at the URL: https://bugs.winehq.org/show_bug.cgi?id=47668
Regards.
--
        Olivier F. R. Dierick
        o.dierick(a)piezo-forte.be
Dec. 5, 2019
[PATCH] tests: Trace elapsed time when $WINETEST_TIME is set.
by Francois Gouget
This simplifies narrowing down where a test gets stuck or is slow if
it times out but prints few messages.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=48094
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
If this approach is acceptable I'll add support for it on the TestBot
and on the test.winehq.org site: allowing to set $WINETEST_TIME and
recognizing the modified failure lines.
include/wine/test.h | 72 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 55 insertions(+), 17 deletions(-)
diff --git a/include/wine/test.h b/include/wine/test.h
index aeb9a55dee2..dea94fa60f0 100644
--- a/include/wine/test.h
+++ b/include/wine/test.h
@@ -58,6 +58,9 @@
/* debug level */
extern int winetest_debug;
+/* trace timing information */
+extern int winetest_time;
+
/* running in interactive mode? */
extern int winetest_interactive;
@@ -216,6 +219,10 @@ extern const struct test winetest_testlist[];
/* debug level */
int winetest_debug = 1;
+/* trace timing information */
+int winetest_time = 0;
+DWORD winetest_start_time, winetest_last_time;
+
/* interactive mode? */
int winetest_interactive = 0;
@@ -304,11 +311,27 @@ void winetest_set_location( const char* file, int line )
data->current_line=line;
}
+const char *winetest_elapsed(void)
+{
+ DWORD now;
+ char *res;
+
+ if (!winetest_time)
+ return "";
+
+ now = GetTickCount();
+ winetest_last_time = now;
+ res = get_temp_buffer( 11 ); /* enough for a day */
+ sprintf( res, "%.3f", (now - winetest_start_time) / 1000.0);
+ release_temp_buffer( res, strlen(res) + 1 );
+ return res;
+}
+
void winetest_subtest( const char* name )
{
struct tls_data *data = get_tls_data();
- printf( "%s:%d: Subtest %s\n",
- data->current_file, data->current_line, name);
+ printf( "%s:%d:%s Subtest %s\n",
+ data->current_file, data->current_line, name, winetest_elapsed());
}
int broken( int condition )
@@ -334,8 +357,8 @@ int winetest_vok( int condition, const char *msg, __winetest_va_list args )
{
if (condition)
{
- printf( "%s:%d: Test succeeded inside todo block: ",
- data->current_file, data->current_line );
+ printf( "%s:%d:%s Test succeeded inside todo block: ",
+ data->current_file, data->current_line, winetest_elapsed() );
vprintf(msg, args);
InterlockedIncrement(&todo_failures);
return 0;
@@ -344,8 +367,8 @@ int winetest_vok( int condition, const char *msg, __winetest_va_list args )
{
if (winetest_debug > 0)
{
- printf( "%s:%d: Test marked todo: ",
- data->current_file, data->current_line );
+ printf( "%s:%d:%s Test marked todo: ",
+ data->current_file, data->current_line, winetest_elapsed() );
vprintf(msg, args);
}
InterlockedIncrement(&todo_successes);
@@ -356,17 +379,20 @@ int winetest_vok( int condition, const char *msg, __winetest_va_list args )
{
if (!condition)
{
- printf( "%s:%d: Test failed: ",
- data->current_file, data->current_line );
+ printf( "%s:%d:%s Test failed: ",
+ data->current_file, data->current_line, winetest_elapsed() );
vprintf(msg, args);
InterlockedIncrement(&failures);
return 0;
}
else
{
- if (winetest_report_success)
- printf( "%s:%d: Test succeeded\n",
- data->current_file, data->current_line);
+ if (winetest_report_success ||
+ (winetest_time && GetTickCount() >= winetest_last_time + 1000))
+ {
+ printf( "%s:%d:%s Test succeeded\n",
+ data->current_file, data->current_line, winetest_elapsed() );
+ }
InterlockedIncrement(&successes);
return 1;
}
@@ -389,7 +415,7 @@ void __winetest_cdecl winetest_trace( const char *msg, ... )
if (winetest_debug > 0)
{
- printf( "%s:%d: ", data->current_file, data->current_line );
+ printf( "%s:%d:%s ", data->current_file, data->current_line, winetest_elapsed() );
__winetest_va_start(valist, msg);
vprintf(msg, valist);
__winetest_va_end(valist);
@@ -400,7 +426,7 @@ void winetest_vskip( const char *msg, __winetest_va_list args )
{
struct tls_data *data = get_tls_data();
- printf( "%s:%d: Tests skipped: ", data->current_file, data->current_line );
+ printf( "%s:%d:%s Tests skipped: ", data->current_file, data->current_line, winetest_elapsed() );
vprintf(msg, args);
skipped++;
}
@@ -630,8 +656,8 @@ static int run_test( const char *name )
if (winetest_debug)
{
- printf( "%04x:%s: %d tests executed (%d marked as todo, %d %s), %d skipped.\n",
- GetCurrentProcessId(), test->name,
+ printf( "%04x:%s:%s %d tests executed (%d marked as todo, %d %s), %d skipped.\n",
+ GetCurrentProcessId(), test->name, winetest_elapsed(),
successes + failures + todo_successes + todo_failures,
todo_successes, failures + todo_failures,
(failures + todo_failures != 1) ? "failures" : "failure",
@@ -656,8 +682,8 @@ static LONG CALLBACK exc_filter( EXCEPTION_POINTERS *ptrs )
struct tls_data *data = get_tls_data();
if (data->current_file)
- printf( "%s:%d: this is the last test seen before the exception\n",
- data->current_file, data->current_line );
+ printf( "%s:%d:%s this is the last test seen before the exception\n",
+ data->current_file, data->current_line, winetest_elapsed() );
printf( "%04x:%s: unhandled exception %08x at %p\n",
GetCurrentProcessId(), current_test->name,
ptrs->ExceptionRecord->ExceptionCode, ptrs->ExceptionRecord->ExceptionAddress );
@@ -695,6 +721,18 @@ int main( int argc, char **argv )
if (GetEnvironmentVariableA( "WINETEST_DEBUG", p, sizeof(p) )) winetest_debug = atoi(p);
if (GetEnvironmentVariableA( "WINETEST_INTERACTIVE", p, sizeof(p) )) winetest_interactive = atoi(p);
if (GetEnvironmentVariableA( "WINETEST_REPORT_SUCCESS", p, sizeof(p) )) winetest_report_success = atoi(p);
+ if (GetEnvironmentVariableA( "WINETEST_TIME", p, sizeof(p) )) winetest_time = atoi(p);
+ if (GetEnvironmentVariableA( "WINETEST_START_TIME", p, sizeof(p) ))
+ winetest_start_time = atoi(p);
+ else
+ {
+ char time_str[11];
+ winetest_start_time = GetTickCount();
+ /* Export the test start time for child processes */
+ sprintf( time_str, "%u", winetest_start_time );
+ SetEnvironmentVariableA( "WINETEST_START_TIME", time_str );
+ }
+ winetest_last_time = winetest_start_time;
if (!strcmp( winetest_platform, "windows" )) SetUnhandledExceptionFilter( exc_filter );
if (!winetest_interactive) SetErrorMode( SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX );
--
2.20.1
Dec. 5, 2019
[PATCH] testbot/LogUtils: GetLogFileNames() should untaint the returned log names.
by Francois Gouget
Otherwise the caller may get an error when trying to use them for file
operations (such as unlink).
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/lib/WineTestBot/LogUtils.pm | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index 32bf0fa61..4a17857f8 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -634,13 +634,21 @@ sub GetLogFileNames($;$)
foreach my $FileName (glob("'$Dir/$Glob*'"))
{
my $LogName = basename($FileName);
- if ($LogName !~ s/\.err$// and $LogName !~ /\.report$/ and
- $LogName ne $Glob) # 'log' case
+ $LogName =~ s/\.err$//;
+ next if ($Seen{$LogName});
+ if ($LogName =~ /^([a-zA-Z0-9_]+\.report)$/)
+ {
+ $LogName = $1; # untaint
+ }
+ elsif ($LogName eq $Glob) # log and old_log cases
+ {
+ $LogName = $Glob; # untaint
+ }
+ else
{
# Not a valid log filename (where does this file come from?)
next;
}
- next if ($Seen{$LogName});
$Seen{$LogName} = 1;
if ((-f "$Dir/$LogName" and !-z "$Dir/$LogName") or
--
2.20.1
Dec. 5, 2019
[PATCH] testbot/WineSendLog: Errors are not new when missing reference reports.
by Francois Gouget
Build logs don't have reference logs so for them every error is new.
But test reports should have reference WineTest results and if not
reporting the errors as new would cause false positives. So default
to "not new" in that case.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/WineSendLog.pl | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/testbot/bin/WineSendLog.pl b/testbot/bin/WineSendLog.pl
index 721122edb..95cc036c9 100755
--- a/testbot/bin/WineSendLog.pl
+++ b/testbot/bin/WineSendLog.pl
@@ -291,8 +291,11 @@ EOF
my ($NewGroups, $NewErrors, $_NewIndices) = GetNewLogErrors($RefFileName, $LogErrors->{Groups}, $LogErrors->{Errors});
if (!$NewGroups)
{
- # There was no reference log (typical of build logs)
- # so every error is new
+ # Test reports should have reference WineTest results and if not
+ # reporting the errors as new would cause false positives.
+ next if ($LogName =~ /\.report$/);
+
+ # Build logs don't have reference logs so for them every error is new.
$NewGroups = $LogErrors->{Groups};
$NewErrors = $LogErrors->{Errors};
}
--
2.20.1
Dec. 5, 2019
[PATCH] testbot/Janitor: Fix extracting the VM name from reference report filenames.
by Francois Gouget
The log name part can contain underscores and uppercase letters when
testing locales.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/bin/Janitor.pl | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testbot/bin/Janitor.pl b/testbot/bin/Janitor.pl
index 537a0dc4a..c51637a19 100755
--- a/testbot/bin/Janitor.pl
+++ b/testbot/bin/Janitor.pl
@@ -308,7 +308,7 @@ if (opendir(my $dh, "$DataDir/latest"))
{
next if ($Entry eq "." or $Entry eq "..");
- if ($Entry =~ /^(.*)_[a-z0-9]+\.report(?:\.err)?$/)
+ if ($Entry =~ /^([a-zA-Z0-9_]+)_(?:exe|win|wow)(?:32|64)[a-zA-Z0-9_]*\.report(?:\.err)?$/)
{
# Keep the reference WineTest reports for all VMs even if they are
# retired or scheduled for deletion.
--
2.20.1
Dec. 5, 2019
Re: [PATCH] msxml3: all string passed to IXMLDOMDocument_load() need to be URL-unescaped
by Nikolay Sivov
Do we need to unescape if it's not a file:// url?I was hoping we could
find some IUri/path API flags to do what we need for us.
Another concern is path/url max lengths are used seemingly randomly, and
it's not a problem with your change, but with existing code.I think
asking for required length and allocating it is better.
> + /* Regular local path with some URL encoded characters. */
> + strcpy(path2, path);
> + n = strlen(path2);
> + path2[n-1] = '%';
> + path2[n] = '6';
> + path2[n+1] = 'C';
> + path2[n+2] = '\0'; /* C:\path\to\winetest.xm%6C */
> + test_doc_load_from_path(doc, path2);
Could you make this more readable? Maybe strcat-ing escaped file name as
string literal instead.
> + /* Regular local path with all URL encoded characters. */
> + percent_path = HeapAlloc(GetProcessHeap(), 0, 3*n + 1);
> + for (i = 0; i < n; i++)
> + {
> + static char hex_tab[] = "0123456789ABCDEF";
> + percent_path[3*i] = '%';
> + percent_path[3*i + 1] = hex_tab[path[i] >> 4];
> + percent_path[3*i + 2] = hex_tab[path[i] & 0xF];
> + }
> + percent_path[3*n] = '\0';
> + test_doc_load_from_path(doc, percent_path);
> + HeapFree(GetProcessHeap(), 0, percent_path);
Couple of cases would be enough, like you did earlier for "l" -> %6c,
and another one for " " -> %20. Space is actually not tested by this
patch, and that's what application is using. If you still want to encode
it entirely, please add a helper function.
Dec. 5, 2019
[PATCH vkd3d v3] vkd3d: Add a memory usage info callback optional extension.
by Conor McCarthy
Allows memory usage info to be sent to Wine DXGI.
Signed-off-by: Conor McCarthy <cmccarthy(a)codeweavers.com>
---
Supersedes 173692.
v3: Remove total memory from the function parameters.
---
include/vkd3d.h | 12 ++++++++++++
libs/vkd3d/command.c | 6 +++---
libs/vkd3d/device.c | 14 +++++++++++++-
libs/vkd3d/resource.c | 19 +++++++++++++------
libs/vkd3d/vkd3d_private.h | 20 ++++++++++++++++++++
5 files changed, 61 insertions(+), 10 deletions(-)
diff --git a/include/vkd3d.h b/include/vkd3d.h
index e2d9ec8..17c07d1 100644
--- a/include/vkd3d.h
+++ b/include/vkd3d.h
@@ -47,6 +47,7 @@ enum vkd3d_structure_type
/* 1.2 */
VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_EXTENSIONS_INFO,
VKD3D_STRUCTURE_TYPE_APPLICATION_INFO,
+ VKD3D_STRUCTURE_TYPE_OPTIONAL_DEVICE_CALLBACK_INFO,
VKD3D_FORCE_32_BIT_ENUM(VKD3D_STRUCTURE_TYPE),
};
@@ -129,6 +130,17 @@ struct vkd3d_optional_device_extensions_info
uint32_t extension_count;
};
+typedef void (STDMETHODCALLTYPE *PFN_vkd3d_memory_usage_callback)(IUnknown *adapter,
+ unsigned int non_local, INT64 change);
+
+struct vkd3d_optional_device_callback_info
+{
+ enum vkd3d_structure_type type;
+ const void *next;
+
+ PFN_vkd3d_memory_usage_callback pfn_memory_usage_callback;
+};
+
/* vkd3d_image_resource_create_info flags */
#define VKD3D_RESOURCE_INITIAL_STATE_TRANSITION 0x00000001
#define VKD3D_RESOURCE_PRESENT_STATE_TRANSITION 0x00000002
diff --git a/libs/vkd3d/command.c b/libs/vkd3d/command.c
index 75af27d..1b62f9a 100644
--- a/libs/vkd3d/command.c
+++ b/libs/vkd3d/command.c
@@ -1416,7 +1416,7 @@ static void vkd3d_buffer_destroy(struct vkd3d_buffer *buffer, struct d3d12_devic
{
const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
- VK_CALL(vkFreeMemory(device->vk_device, buffer->vk_memory, NULL));
+ vkd3d_free_device_memory(device, buffer->vk_memory_type, buffer->vk_memory_size, buffer->vk_memory);
VK_CALL(vkDestroyBuffer(device->vk_device, buffer->vk_buffer, NULL));
}
@@ -3232,8 +3232,8 @@ static HRESULT d3d12_command_list_allocate_transfer_buffer(struct d3d12_command_
if (FAILED(hr = vkd3d_create_buffer(device, &heap_properties, D3D12_HEAP_FLAG_NONE,
&buffer_desc, &buffer->vk_buffer)))
return hr;
- if (FAILED(hr = vkd3d_allocate_buffer_memory(device, buffer->vk_buffer,
- &heap_properties, D3D12_HEAP_FLAG_NONE, &buffer->vk_memory, NULL, NULL)))
+ if (FAILED(hr = vkd3d_allocate_buffer_memory(device, buffer->vk_buffer, &heap_properties,
+ D3D12_HEAP_FLAG_NONE, &buffer->vk_memory, &buffer->vk_memory_type, &buffer->vk_memory_size)))
{
VK_CALL(vkDestroyBuffer(device->vk_device, buffer->vk_buffer, NULL));
return hr;
diff --git a/libs/vkd3d/device.c b/libs/vkd3d/device.c
index e3bb2aa..fd593bc 100644
--- a/libs/vkd3d/device.c
+++ b/libs/vkd3d/device.c
@@ -3390,6 +3390,7 @@ struct d3d12_device *unsafe_impl_from_ID3D12Device(ID3D12Device *iface)
static HRESULT d3d12_device_init(struct d3d12_device *device,
struct vkd3d_instance *instance, const struct vkd3d_device_create_info *create_info)
{
+ const struct vkd3d_optional_device_callback_info *optional_callback;
const struct vkd3d_vk_device_procs *vk_procs;
HRESULT hr;
size_t i;
@@ -3407,6 +3408,17 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
device->vk_device = VK_NULL_HANDLE;
+ device->parent = create_info->parent;
+
+ device->pfn_memory_usage_callback = NULL;
+ optional_callback = vkd3d_find_struct(create_info->next, OPTIONAL_DEVICE_CALLBACK_INFO);
+ if (optional_callback)
+ {
+ device->pfn_memory_usage_callback = optional_callback->pfn_memory_usage_callback;
+ if (device->pfn_memory_usage_callback)
+ TRACE("Found memory callback function %p.\n", device->pfn_memory_usage_callback);
+ }
+
if (FAILED(hr = vkd3d_create_vk_device(device, create_info)))
goto out_free_instance;
@@ -3434,7 +3446,7 @@ static HRESULT d3d12_device_init(struct d3d12_device *device,
for (i = 0; i < ARRAY_SIZE(device->desc_mutex); ++i)
pthread_mutex_init(&device->desc_mutex[i], NULL);
- if ((device->parent = create_info->parent))
+ if (device->parent)
IUnknown_AddRef(device->parent);
return S_OK;
diff --git a/libs/vkd3d/resource.c b/libs/vkd3d/resource.c
index f40d986..f5fccfa 100644
--- a/libs/vkd3d/resource.c
+++ b/libs/vkd3d/resource.c
@@ -147,6 +147,8 @@ static HRESULT vkd3d_allocate_device_memory(struct d3d12_device *device,
if (vk_memory_type)
*vk_memory_type = allocate_info.memoryTypeIndex;
+ d3d12_device_update_memory_usage(device, allocate_info.memoryTypeIndex, allocate_info.allocationSize);
+
return S_OK;
}
@@ -161,6 +163,7 @@ HRESULT vkd3d_allocate_buffer_memory(struct d3d12_device *device, VkBuffer vk_bu
VkMemoryRequirements2 memory_requirements2;
VkMemoryRequirements *memory_requirements;
VkBufferMemoryRequirementsInfo2 info;
+ uint32_t type;
VkResult vr;
HRESULT hr;
@@ -196,16 +199,18 @@ HRESULT vkd3d_allocate_buffer_memory(struct d3d12_device *device, VkBuffer vk_bu
}
if (FAILED(hr = vkd3d_allocate_device_memory(device, heap_properties, heap_flags,
- memory_requirements, dedicated_allocation, vk_memory, vk_memory_type)))
+ memory_requirements, dedicated_allocation, vk_memory, &type)))
return hr;
if ((vr = VK_CALL(vkBindBufferMemory(device->vk_device, vk_buffer, *vk_memory, 0))) < 0)
{
WARN("Failed to bind memory, vr %d.\n", vr);
- VK_CALL(vkFreeMemory(device->vk_device, *vk_memory, NULL));
+ vkd3d_free_device_memory(device, type, memory_requirements->size, *vk_memory);
*vk_memory = VK_NULL_HANDLE;
}
+ if (vk_memory_type)
+ *vk_memory_type = type;
if (vk_memory_size)
*vk_memory_size = memory_requirements->size;
@@ -223,6 +228,7 @@ static HRESULT vkd3d_allocate_image_memory(struct d3d12_device *device, VkImage
VkMemoryRequirements2 memory_requirements2;
VkMemoryRequirements *memory_requirements;
VkImageMemoryRequirementsInfo2 info;
+ uint32_t type;
VkResult vr;
HRESULT hr;
@@ -258,17 +264,19 @@ static HRESULT vkd3d_allocate_image_memory(struct d3d12_device *device, VkImage
}
if (FAILED(hr = vkd3d_allocate_device_memory(device, heap_properties, heap_flags,
- memory_requirements, dedicated_allocation, vk_memory, vk_memory_type)))
+ memory_requirements, dedicated_allocation, vk_memory, &type)))
return hr;
if ((vr = VK_CALL(vkBindImageMemory(device->vk_device, vk_image, *vk_memory, 0))) < 0)
{
WARN("Failed to bind memory, vr %d.\n", vr);
- VK_CALL(vkFreeMemory(device->vk_device, *vk_memory, NULL));
+ vkd3d_free_device_memory(device, type, memory_requirements->size, *vk_memory);
*vk_memory = VK_NULL_HANDLE;
return hresult_from_vk_result(vr);
}
+ if (vk_memory_type)
+ *vk_memory_type = type;
if (vk_memory_size)
*vk_memory_size = memory_requirements->size;
@@ -318,13 +326,12 @@ static ULONG STDMETHODCALLTYPE d3d12_heap_AddRef(ID3D12Heap *iface)
static void d3d12_heap_destroy(struct d3d12_heap *heap)
{
struct d3d12_device *device = heap->device;
- const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
TRACE("Destroying heap %p.\n", heap);
vkd3d_private_store_destroy(&heap->private_store);
- VK_CALL(vkFreeMemory(device->vk_device, heap->vk_memory, NULL));
+ vkd3d_free_device_memory(device, heap->vk_memory_type, heap->desc.SizeInBytes, heap->vk_memory);
pthread_mutex_destroy(&heap->mutex);
diff --git a/libs/vkd3d/vkd3d_private.h b/libs/vkd3d/vkd3d_private.h
index 9ff6bba..28801ba 100644
--- a/libs/vkd3d/vkd3d_private.h
+++ b/libs/vkd3d/vkd3d_private.h
@@ -839,6 +839,8 @@ struct vkd3d_buffer
{
VkBuffer vk_buffer;
VkDeviceMemory vk_memory;
+ VkDeviceSize vk_memory_size;
+ uint32_t vk_memory_type;
};
/* ID3D12CommandAllocator */
@@ -1129,6 +1131,7 @@ struct d3d12_device
VkPipelineCache vk_pipeline_cache;
VkPhysicalDeviceMemoryProperties memory_properties;
+ PFN_vkd3d_memory_usage_callback pfn_memory_usage_callback;
D3D12_FEATURE_DATA_D3D12_OPTIONS feature_options;
@@ -1199,6 +1202,23 @@ static inline pthread_mutex_t *d3d12_device_get_descriptor_mutex(struct d3d12_de
return &device->desc_mutex[idx & (ARRAY_SIZE(device->desc_mutex) - 1)];
}
+static inline void d3d12_device_update_memory_usage(struct d3d12_device *device, uint32_t vk_memory_type, int64_t change)
+{
+ unsigned int non_local = !(device->memory_properties.memoryTypes[vk_memory_type].propertyFlags & VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+
+ if (device->pfn_memory_usage_callback)
+ device->pfn_memory_usage_callback(device->parent, non_local, change);
+}
+
+static inline void vkd3d_free_device_memory(struct d3d12_device *device,
+ uint32_t type, VkDeviceSize size, VkDeviceMemory vk_memory)
+{
+ const struct vkd3d_vk_device_procs *vk_procs = &device->vk_procs;
+
+ VK_CALL(vkFreeMemory(device->vk_device, vk_memory, NULL));
+ d3d12_device_update_memory_usage(device, type, -(int64_t)size);
+}
+
/* utils */
enum vkd3d_format_type
{
--
2.24.0
Dec. 5, 2019
[PATCH 3/3] bcrypt: Add more BCryptSignHash tests.
by Hans Leidekker
From: Derek Lesho <dlesho(a)codeweavers.com>
v2: Verify signature.
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/tests/bcrypt.c | 49 ++++++++++++++++++++++++++++++++++++++
1 file changed, 49 insertions(+)
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
index d125e0c89d..198acbf721 100644
--- a/dlls/bcrypt/tests/bcrypt.c
+++ b/dlls/bcrypt/tests/bcrypt.c
@@ -2049,6 +2049,9 @@ static void test_BCryptSignHash(void)
{
static UCHAR hash[] =
{0x7e,0xe3,0x74,0xe7,0xc5,0x0b,0x6b,0x70,0xdb,0xab,0x32,0x6d,0x1d,0x51,0xd6,0x74,0x79,0x8e,0x5b,0x4b};
+ static UCHAR hash_sha256[] =
+ {0x25,0x2f,0x10,0xc8,0x36,0x10,0xeb,0xca,0x1a,0x05,0x9c,0x0b,0xae,0x82,0x55,0xeb,0xa2,0xf9,0x5b,0xe4,
+ 0xd1,0xd7,0xbC,0xfA,0x89,0xd7,0x24,0x8a,0x82,0xd9,0xf1,0x11};
BCRYPT_PKCS1_PADDING_INFO pad;
BCRYPT_ALG_HANDLE alg;
BCRYPT_KEY_HANDLE key;
@@ -2056,6 +2059,8 @@ static void test_BCryptSignHash(void)
NTSTATUS ret;
ULONG len;
+ /* RSA */
+
ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
if (ret)
{
@@ -2087,6 +2092,14 @@ static void test_BCryptSignHash(void)
len = 0;
memset(sig, 0, sizeof(sig));
+
+ /* inference of padding info on RSA not supported */
+ ret = pBCryptSignHash(key, NULL, hash, sizeof(hash), sig, sizeof(sig), &len, 0);
+ ok(ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
+
+ ret = pBCryptSignHash(key, &pad, hash, sizeof(hash), sig, 0, &len, BCRYPT_PAD_PKCS1);
+ ok(ret == STATUS_BUFFER_TOO_SMALL, "got %08x\n", ret);
+
ret = pBCryptSignHash(key, &pad, hash, sizeof(hash), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
ok(!ret, "got %08x\n", ret);
ok(len == 64, "got %u\n", len);
@@ -2099,6 +2112,42 @@ static void test_BCryptSignHash(void)
ret = pBCryptCloseAlgorithmProvider(alg, 0);
ok(!ret, "got %08x\n", ret);
+
+ /* ECDSA */
+
+ ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_ECDSA_P256_ALGORITHM, NULL, 0);
+ if (ret)
+ {
+ win_skip("failed to open ECDSA provider: %08x\n", ret);
+ return;
+ }
+
+ ret = pBCryptGenerateKeyPair(alg, &key, 256, 0);
+ ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+
+ ret = pBCryptFinalizeKeyPair(key, 0);
+ ok(ret == STATUS_SUCCESS, "got %08x\n", ret);
+
+ memset(sig, 0, sizeof(sig));
+ len = 0;
+
+ /* automatically detects padding info */
+ ret = pBCryptSignHash(key, NULL, hash, sizeof(hash), sig, sizeof(sig), &len, 0);
+ ok (!ret, "got %08x\n", ret);
+ ok (len == 64, "got %u\n", len);
+
+ ret = pBCryptVerifySignature(key, NULL, hash, sizeof(hash), sig, len, 0);
+ ok(!ret, "got %08x\n", ret);
+
+ /* mismatch info (SHA-1 != SHA-256) */
+ ret = pBCryptSignHash(key, &pad, hash_sha256, sizeof(hash_sha256), sig, sizeof(sig), &len, BCRYPT_PAD_PKCS1);
+ ok (ret == STATUS_INVALID_PARAMETER, "got %08x\n", ret);
+
+ ret = pBCryptDestroyKey(key);
+ ok(!ret, "got %08x\n", ret);
+
+ ret = pBCryptCloseAlgorithmProvider(alg, 0);
+ ok(!ret, "got %08x\n", ret);
}
static void test_BCryptEnumAlgorithms(void)
--
2.20.1
Dec. 5, 2019
[PATCH 2/3] bcrypt: Handle SHA1 hash in key_asymmetric_verify.
by Hans Leidekker
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/gnutls.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index 379d76a32e..2f048d6c86 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -1064,6 +1064,7 @@ NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULO
/* only the hash size must match, not the actual hash function */
switch (hash_len)
{
+ case 20: hash_alg = GNUTLS_DIG_SHA1; break;
case 32: hash_alg = GNUTLS_DIG_SHA256; break;
case 48: hash_alg = GNUTLS_DIG_SHA384; break;
--
2.20.1
Dec. 5, 2019
[PATCH 1/3] bcrypt: Add support for signing hashes with ECDSA keys.
by Hans Leidekker
From: Derek Lesho <dlesho(a)codeweavers.com>
v2: Avoid goto within switch statement, formatting.
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
Signed-off-by: Hans Leidekker <hans(a)codeweavers.com>
---
dlls/bcrypt/gnutls.c | 147 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 130 insertions(+), 17 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index a6a07fff19..379d76a32e 100644
--- a/dlls/bcrypt/gnutls.c
+++ b/dlls/bcrypt/gnutls.c
@@ -92,6 +92,7 @@ MAKE_FUNCPTR(gnutls_cipher_decrypt2);
MAKE_FUNCPTR(gnutls_cipher_deinit);
MAKE_FUNCPTR(gnutls_cipher_encrypt2);
MAKE_FUNCPTR(gnutls_cipher_init);
+MAKE_FUNCPTR(gnutls_decode_rs_value);
MAKE_FUNCPTR(gnutls_global_deinit);
MAKE_FUNCPTR(gnutls_global_init);
MAKE_FUNCPTR(gnutls_global_set_log_function);
@@ -189,6 +190,7 @@ BOOL gnutls_initialize(void)
LOAD_FUNCPTR(gnutls_cipher_deinit)
LOAD_FUNCPTR(gnutls_cipher_encrypt2)
LOAD_FUNCPTR(gnutls_cipher_init)
+ LOAD_FUNCPTR(gnutls_decode_rs_value)
LOAD_FUNCPTR(gnutls_global_deinit)
LOAD_FUNCPTR(gnutls_global_init)
LOAD_FUNCPTR(gnutls_global_set_log_function)
@@ -711,6 +713,7 @@ NTSTATUS key_asymmetric_generate( struct key *key )
break;
case ALG_ID_ECDH_P256:
+ case ALG_ID_ECDSA_P256:
pk_alg = GNUTLS_PK_ECC; /* compatible with ECDSA and ECDH */
bitlen = GNUTLS_CURVE_TO_BITS( GNUTLS_ECC_CURVE_SECP256R1 );
break;
@@ -1029,6 +1032,17 @@ static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULO
}
}
+static gnutls_digest_algorithm_t get_digest_from_id( const WCHAR *alg_id )
+{
+ if (!strcmpW( alg_id, BCRYPT_SHA1_ALGORITHM )) return GNUTLS_DIG_SHA1;
+ if (!strcmpW( alg_id, BCRYPT_SHA256_ALGORITHM )) return GNUTLS_DIG_SHA256;
+ if (!strcmpW( alg_id, BCRYPT_SHA384_ALGORITHM )) return GNUTLS_DIG_SHA384;
+ if (!strcmpW( alg_id, BCRYPT_SHA512_ALGORITHM )) return GNUTLS_DIG_SHA512;
+ if (!strcmpW( alg_id, BCRYPT_MD2_ALGORITHM )) return GNUTLS_DIG_MD2;
+ if (!strcmpW( alg_id, BCRYPT_MD5_ALGORITHM )) return GNUTLS_DIG_MD5;
+ return -1;
+}
+
NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULONG hash_len, UCHAR *signature,
ULONG signature_len, DWORD flags )
{
@@ -1068,11 +1082,7 @@ NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULO
if (!(flags & BCRYPT_PAD_PKCS1) || !info) return STATUS_INVALID_PARAMETER;
if (!info->pszAlgId) return STATUS_INVALID_SIGNATURE;
- if (!strcmpW( info->pszAlgId, BCRYPT_SHA1_ALGORITHM )) hash_alg = GNUTLS_DIG_SHA1;
- else if (!strcmpW( info->pszAlgId, BCRYPT_SHA256_ALGORITHM )) hash_alg = GNUTLS_DIG_SHA256;
- else if (!strcmpW( info->pszAlgId, BCRYPT_SHA384_ALGORITHM )) hash_alg = GNUTLS_DIG_SHA384;
- else if (!strcmpW( info->pszAlgId, BCRYPT_SHA512_ALGORITHM )) hash_alg = GNUTLS_DIG_SHA512;
- else
+ if ((hash_alg = get_digest_from_id(info->pszAlgId)) == -1)
{
FIXME( "hash algorithm %s not supported\n", debugstr_w(info->pszAlgId) );
return STATUS_NOT_SUPPORTED;
@@ -1107,26 +1117,130 @@ NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULO
return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
}
+static unsigned int get_signature_length( enum alg_id id )
+{
+ switch (id)
+ {
+ case ALG_ID_ECDSA_P256: return 64;
+ case ALG_ID_ECDSA_P384: return 96;
+ default:
+ FIXME( "unhandled algorithm %u\n", id );
+ return 0;
+ }
+}
+
+NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature, UCHAR *output,
+ ULONG output_len, ULONG *ret_len )
+{
+ switch (type)
+ {
+ case ALG_ID_RSA:
+ case ALG_ID_RSA_SIGN:
+ {
+ if (output_len < signature.size) return STATUS_BUFFER_TOO_SMALL;
+ memcpy( output, signature.data, signature.size );
+ *ret_len = signature.size;
+ return STATUS_SUCCESS;
+ }
+ case ALG_ID_ECDSA_P256:
+ case ALG_ID_ECDSA_P384:
+ {
+ int err;
+ unsigned int pad_size, sig_len = get_signature_length( type );
+ gnutls_datum_t r, s; /* format as r||s */
+
+ if ((err = pgnutls_decode_rs_value( &signature, &r, &s )))
+ {
+ ERR( "failed to get R/S values from signature %u\n", err );
+ return 0;
+ }
+
+ if (output_len < sig_len) return STATUS_BUFFER_TOO_SMALL;
+
+ /* remove prepended zero byte */
+ if (r.size % 2)
+ {
+ r.size--;
+ r.data += 1;
+ }
+ if (s.size % 2)
+ {
+ s.size--;
+ s.data += 1;
+ }
+
+ if (r.size != s.size || r.size + s.size > sig_len)
+ {
+ ERR( "we didn't get a correct signature\n" );
+ return STATUS_INTERNAL_ERROR;
+ }
+
+ pad_size = (sig_len / 2) - s.size;
+ memset( output, 0, sig_len );
+
+ memcpy( output + pad_size, r.data, r.size );
+ memcpy( output + (sig_len / 2) + pad_size, s.data, s.size );
+
+ *ret_len = sig_len;
+ return STATUS_SUCCESS;
+ }
+ default:
+ return STATUS_INTERNAL_ERROR;
+ }
+}
+
NTSTATUS key_asymmetric_sign( struct key *key, void *padding, UCHAR *input, ULONG input_len, UCHAR *output,
ULONG output_len, ULONG *ret_len, ULONG flags )
{
BCRYPT_PKCS1_PADDING_INFO *pad = padding;
gnutls_datum_t hash, signature;
+ gnutls_digest_algorithm_t hash_alg;
+ NTSTATUS status;
int ret;
- if (key->alg_id != ALG_ID_RSA && key->alg_id != ALG_ID_RSA_SIGN)
+ if (key->alg_id == ALG_ID_ECDSA_P256 || key->alg_id == ALG_ID_ECDSA_P384)
{
- FIXME( "algorithm %u not supported\n", key->alg_id );
- return STATUS_NOT_IMPLEMENTED;
+ /* With ECDSA, we find the digest algorithm from the hash length, and verify it */
+ switch (input_len)
+ {
+ case 20: hash_alg = GNUTLS_DIG_SHA1; break;
+ case 32: hash_alg = GNUTLS_DIG_SHA256; break;
+ case 48: hash_alg = GNUTLS_DIG_SHA384; break;
+ case 64: hash_alg = GNUTLS_DIG_SHA512; break;
+
+ default:
+ FIXME( "hash size %u not yet supported\n", input_len );
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if (flags == BCRYPT_PAD_PKCS1 && pad && pad->pszAlgId && get_digest_from_id( pad->pszAlgId ) != hash_alg)
+ {
+ WARN( "incorrect hashing algorithm %s, expected %u\n", debugstr_w(pad->pszAlgId), hash_alg );
+ return STATUS_INVALID_PARAMETER;
+ }
}
- if (flags != BCRYPT_PAD_PKCS1)
+ else if (flags == BCRYPT_PAD_PKCS1)
{
- FIXME( "flags %08x not implemented\n", flags );
- return STATUS_NOT_IMPLEMENTED;
+ if (!pad || !pad->pszAlgId)
+ {
+ WARN( "padding info not found\n" );
+ return STATUS_INVALID_PARAMETER;
+ }
+
+ if ((hash_alg = get_digest_from_id( pad->pszAlgId )) == -1)
+ {
+ FIXME( "hash algorithm %s not recognized\n", debugstr_w(pad->pszAlgId) );
+ return STATUS_NOT_SUPPORTED;
+ }
+ }
+ else if (!flags)
+ {
+ WARN( "invalid flags %08x\n", flags );
+ return STATUS_INVALID_PARAMETER;
}
- if (!pad || !pad->pszAlgId || lstrcmpiW(pad->pszAlgId, BCRYPT_SHA1_ALGORITHM))
+ else
{
- FIXME( "%s padding not implemented\n", debugstr_w(pad ? pad->pszAlgId : NULL) );
+ FIXME( "flags %08x not implemented\n", flags );
return STATUS_NOT_IMPLEMENTED;
}
@@ -1143,17 +1257,16 @@ NTSTATUS key_asymmetric_sign( struct key *key, void *padding, UCHAR *input, ULON
signature.data = NULL;
signature.size = 0;
- if ((ret = pgnutls_privkey_sign_hash( key->u.a.handle, GNUTLS_DIG_SHA1, 0, &hash, &signature )))
+ if ((ret = pgnutls_privkey_sign_hash( key->u.a.handle, hash_alg, 0, &hash, &signature )))
{
pgnutls_perror( ret );
return STATUS_INTERNAL_ERROR;
}
- if (output_len >= signature.size) memcpy( output, signature.data, signature.size );
- *ret_len = signature.size;
+ status = format_gnutls_signature( key->alg_id, signature, output, output_len, ret_len );
free( signature.data );
- return STATUS_SUCCESS;
+ return status;
}
NTSTATUS key_destroy( struct key *key )
--
2.20.1
Dec. 5, 2019
[PATCH] testbot/LogUtils: Fix GetNewLogErrors() when there are no errors.
by Francois Gouget
Don't use $Groups if it is undefined.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
This fixes WineSendLog and thus the patch status and Marvin emails.
testbot/lib/WineTestBot/LogUtils.pm | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testbot/lib/WineTestBot/LogUtils.pm b/testbot/lib/WineTestBot/LogUtils.pm
index 51932965c..32bf0fa61 100644
--- a/testbot/lib/WineTestBot/LogUtils.pm
+++ b/testbot/lib/WineTestBot/LogUtils.pm
@@ -889,7 +889,7 @@ sub GetNewLogErrors($$$)
my ($RefFileName, $Groups, $Errors) = @_;
my (@NewGroups, %NewErrors, %NewIndices);
- return (\@NewGroups, \%NewErrors, \%NewIndices) if (!@$Groups);
+ return (\@NewGroups, \%NewErrors, \%NewIndices) if (!$Groups or !@$Groups);
my ($RefGroups, $RefErrors) = GetLogErrors($RefFileName);
return (undef, undef) if (!$RefGroups);
--
2.20.1
Dec. 5, 2019
[PATCH] testbot/web: Abuse the Status field to show more details about accounts.
by Francois Gouget
This allows quickly identifying accounts that have been approved but
where the user did not pick a password.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/WineTestBot.css | 8 ++++++
testbot/web/admin/UsersList.pl | 47 ++++++++++++++++++++++++++++++++++
2 files changed, 55 insertions(+)
diff --git a/testbot/web/WineTestBot.css b/testbot/web/WineTestBot.css
index 1456036c0..f58835583 100644
--- a/testbot/web/WineTestBot.css
+++ b/testbot/web/WineTestBot.css
@@ -387,6 +387,14 @@ pre
.boterror { color: #e55600; }
.canceled { color: black; }
+.userrequest { color: #e55600; }
+.userapproved { color: green; }
+.useradmin { color: black; }
+.userdevel { color: black; }
+.usernone { color: red; }
+.userdisabled { color: red; }
+.userdeleted { color: red; }
+
.log-info { background-color: #d9ffcc; }
.log-skip { color: blue; }
.log-todo { color: #d08000; }
diff --git a/testbot/web/admin/UsersList.pl b/testbot/web/admin/UsersList.pl
index f46949d24..279907041 100644
--- a/testbot/web/admin/UsersList.pl
+++ b/testbot/web/admin/UsersList.pl
@@ -25,6 +25,7 @@ package UsersListPage;
use ObjectModel::CGI::CollectionPage;
our @ISA = qw(ObjectModel::CGI::CollectionPage);
+use URI::Escape;
use WineTestBot::CGI::Sessions;
use WineTestBot::Config;
use WineTestBot::Users;
@@ -55,6 +56,52 @@ sub DisplayProperty($$$)
$PropertyName eq "Status" || $PropertyName eq "RealName";
}
+sub GenerateDataCell($$$$$)
+{
+ my ($self, $CollectionBlock, $Item, $PropertyDescriptor, $DetailsPage) = @_;
+
+ my $PropertyName = $PropertyDescriptor->GetName();
+ if ($PropertyName eq "Status")
+ {
+ my $Status = $Item->Status;
+ my ($Class, $Label);
+ if ($Status eq "disabled")
+ {
+ ($Class, $Label) = ('userdisabled', 'disabled');
+ }
+ elsif ($Status eq "deleted")
+ {
+ ($Class, $Label) = ('userdeleted', 'deleted');
+ }
+ elsif ($Item->WaitingForApproval())
+ {
+ ($Class, $Label) = ('userrequest', 'request');
+ }
+ elsif (!$Item->Activated())
+ {
+ ($Class, $Label) = ('userapproved', 'approved');
+ }
+ elsif ($Item->HasRole("admin"))
+ {
+ ($Class, $Label) = ('useradmin', 'admin');
+ }
+ elsif ($Item->HasRole("wine-devel"))
+ {
+ ($Class, $Label) = ('userdevel', 'wine-devel');
+ }
+ else
+ {
+ ($Class, $Label) = ('usernone', 'none');
+ }
+ print "<td><a href='/admin/UserDetails.pl?Key=", uri_escape($Item->GetKey()),
+ "'><span class='$Class'>$Label</span></a></td>";
+ }
+ else
+ {
+ $self->SUPER::GenerateDataCell($CollectionBlock, $Item, $PropertyDescriptor, $DetailsPage);
+ }
+}
+
sub GetActions($$)
{
my ($self, $CollectionBlock) = @_;
--
2.20.1
Dec. 5, 2019
[PATCH] testbot/web: Require filling the captcha on the feedback page.
by Francois Gouget
Spammers (or their bots) have taken to spamming the TestBot's
feedback page. As if that was going to egt them anywhere!
The captcha is only required for users who are not logged
in obviously.
Signed-off-by: Francois Gouget <fgouget(a)codeweavers.com>
---
testbot/web/Feedback.pl | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/testbot/web/Feedback.pl b/testbot/web/Feedback.pl
index 36f0a2b06..b43397fda 100644
--- a/testbot/web/Feedback.pl
+++ b/testbot/web/Feedback.pl
@@ -33,16 +33,21 @@ sub _initialize($$$)
{
my ($self, $Request, $RequiredRole) = @_;
+ my $Session = $self->GetCurrentSession();
my @PropertyDescriptors = (
CreateBasicPropertyDescriptor("Name", "Name", !1, !1, "A", 40),
CreateBasicPropertyDescriptor("EMail", "Email", !1, !1, "A", 40),
CreateBasicPropertyDescriptor("Remarks", "Remarks", !1, 1, "textarea", 1024),
);
+ if (!$Session and $RegistrationQ)
+ {
+ $self->GetParam("FeedA", "") if (!defined $self->GetParam("FeedA"));
+ push @PropertyDescriptors, CreateBasicPropertyDescriptor("FeedA", "Please demonstrate you are not a bot by answering this question: $RegistrationQ", !1, 1, "A", 40);
+ }
$self->SUPER::_initialize($Request, $RequiredRole, \@PropertyDescriptors);
- my $Session = $self->GetCurrentSession();
- if (defined($Session))
+ if ($Session)
{
# Provide default values
my $User = $Session->User;
@@ -79,6 +84,17 @@ sub OnSend($)
{
my ($self) = @_;
+ my $Session = $self->GetCurrentSession();
+ if (!$Session and $RegistrationQ)
+ {
+ my $FeedA = $self->GetParam("FeedA");
+ if ($FeedA !~ /$RegistrationARE/)
+ {
+ $self->{ErrMessage} = "Wrong 'captcha' answer. Please try again.";
+ $self->{ErrField} = "Captcha";
+ return !1;
+ }
+ }
if (! $self->Validate)
{
return !1;
--
2.20.1
Dec. 5, 2019
[PATCH 9/9] dwrite: Use IDWriteFactory7 for gdiinterop.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 4 +-
dlls/dwrite/gdiinterop.c | 162 +++++++++++++++++++----------------
dlls/dwrite/main.c | 8 +-
3 files changed, 93 insertions(+), 81 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 871f93b60b..c2aef6b77c 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -269,14 +269,14 @@ extern HRESULT create_fontfacereference(IDWriteFactory7 *factory, IDWriteFontFil
extern HRESULT factory_get_cached_fontface(IDWriteFactory7 *factory, IDWriteFontFile * const *files, UINT32 num_files,
DWRITE_FONT_SIMULATIONS simulations, struct list **cache, REFIID riid, void **obj) DECLSPEC_HIDDEN;
extern void factory_detach_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 *collection) DECLSPEC_HIDDEN;
-extern void factory_detach_gdiinterop(IDWriteFactory5*,IDWriteGdiInterop1*) DECLSPEC_HIDDEN;
+extern void factory_detach_gdiinterop(IDWriteFactory7 *factory, IDWriteGdiInterop1 *interop) DECLSPEC_HIDDEN;
extern struct fontfacecached *factory_cache_fontface(IDWriteFactory7 *factory, struct list *fontfaces,
IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
extern void get_logfont_from_font(IDWriteFont*,LOGFONTW*) DECLSPEC_HIDDEN;
extern void get_logfont_from_fontface(IDWriteFontFace*,LOGFONTW*) DECLSPEC_HIDDEN;
extern HRESULT get_fontsig_from_font(IDWriteFont*,FONTSIGNATURE*) DECLSPEC_HIDDEN;
extern HRESULT get_fontsig_from_fontface(IDWriteFontFace*,FONTSIGNATURE*) DECLSPEC_HIDDEN;
-extern HRESULT create_gdiinterop(IDWriteFactory5*,IDWriteGdiInterop1**) DECLSPEC_HIDDEN;
+extern HRESULT create_gdiinterop(IDWriteFactory7 *factory, IDWriteGdiInterop1 **interop) DECLSPEC_HIDDEN;
extern void fontface_detach_from_cache(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
extern void factory_lock(IDWriteFactory7 *factory) DECLSPEC_HIDDEN;
extern void factory_unlock(IDWriteFactory7 *factory) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/gdiinterop.c b/dlls/dwrite/gdiinterop.c
index 2e4a949286..7e88f7490c 100644
--- a/dlls/dwrite/gdiinterop.c
+++ b/dlls/dwrite/gdiinterop.c
@@ -38,12 +38,13 @@ struct dib_data {
int width;
};
-struct rendertarget {
+struct rendertarget
+{
IDWriteBitmapRenderTarget1 IDWriteBitmapRenderTarget1_iface;
ID2D1SimplifiedGeometrySink ID2D1SimplifiedGeometrySink_iface;
- LONG ref;
+ LONG refcount;
- IDWriteFactory5 *factory;
+ IDWriteFactory7 *factory;
DWRITE_TEXT_ANTIALIAS_MODE antialiasmode;
FLOAT ppdip;
DWRITE_MATRIX m;
@@ -52,11 +53,12 @@ struct rendertarget {
struct dib_data dib;
};
-struct gdiinterop {
+struct gdiinterop
+{
IDWriteGdiInterop1 IDWriteGdiInterop1_iface;
IDWriteFontFileLoader IDWriteFontFileLoader_iface;
- LONG ref;
- IDWriteFactory5 *factory;
+ LONG refcount;
+ IDWriteFactory7 *factory;
};
struct memresource_stream {
@@ -249,27 +251,29 @@ static HRESULT WINAPI rendertarget_QueryInterface(IDWriteBitmapRenderTarget1 *if
static ULONG WINAPI rendertarget_AddRef(IDWriteBitmapRenderTarget1 *iface)
{
- struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
- ULONG ref = InterlockedIncrement(&This->ref);
- TRACE("(%p)->(%d)\n", This, ref);
- return ref;
+ struct rendertarget *target = impl_from_IDWriteBitmapRenderTarget1(iface);
+ ULONG refcount = InterlockedIncrement(&target->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
}
static ULONG WINAPI rendertarget_Release(IDWriteBitmapRenderTarget1 *iface)
{
- struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
- ULONG ref = InterlockedDecrement(&This->ref);
+ struct rendertarget *target = impl_from_IDWriteBitmapRenderTarget1(iface);
+ ULONG refcount = InterlockedDecrement(&target->refcount);
- TRACE("(%p)->(%d)\n", This, ref);
+ TRACE("%p, refcount %u.\n", iface, refcount);
- if (!ref)
+ if (!refcount)
{
- IDWriteFactory5_Release(This->factory);
- DeleteDC(This->hdc);
- heap_free(This);
+ IDWriteFactory7_Release(target->factory);
+ DeleteDC(target->hdc);
+ heap_free(target);
}
- return ref;
+ return refcount;
}
static inline DWORD *get_pixel_ptr_32(struct dib_data *dib, int x, int y)
@@ -341,22 +345,22 @@ static HRESULT WINAPI rendertarget_DrawGlyphRun(IDWriteBitmapRenderTarget1 *ifac
DWRITE_GLYPH_RUN const *run, IDWriteRenderingParams *params, COLORREF color,
RECT *bbox_ret)
{
- struct rendertarget *This = impl_from_IDWriteBitmapRenderTarget1(iface);
+ struct rendertarget *target = impl_from_IDWriteBitmapRenderTarget1(iface);
IDWriteGlyphRunAnalysis *analysis;
DWRITE_RENDERING_MODE1 rendermode;
DWRITE_GRID_FIT_MODE gridfitmode;
DWRITE_TEXTURE_TYPE texturetype;
DWRITE_GLYPH_RUN scaled_run;
IDWriteFontFace3 *fontface;
- RECT target, bounds;
+ RECT target_rect, bounds;
HRESULT hr;
- TRACE("(%p)->(%.2f %.2f %d %p %p 0x%08x %p)\n", This, originX, originY,
+ TRACE("%p, %.8e, %.8e, %d, %p, %p, 0x%08x, %p.\n", iface, originX, originY,
measuring_mode, run, params, color, bbox_ret);
SetRectEmpty(bbox_ret);
- if (!This->dib.ptr)
+ if (!target->dib.ptr)
return S_OK;
if (!params)
@@ -367,18 +371,19 @@ static HRESULT WINAPI rendertarget_DrawGlyphRun(IDWriteBitmapRenderTarget1 *ifac
return hr;
}
- hr = IDWriteFontFace3_GetRecommendedRenderingMode(fontface, run->fontEmSize, This->ppdip * 96.0f,
- This->ppdip * 96.0f, NULL /* FIXME */, run->isSideways, DWRITE_OUTLINE_THRESHOLD_ALIASED, measuring_mode,
+ hr = IDWriteFontFace3_GetRecommendedRenderingMode(fontface, run->fontEmSize, target->ppdip * 96.0f,
+ target->ppdip * 96.0f, NULL /* FIXME */, run->isSideways, DWRITE_OUTLINE_THRESHOLD_ALIASED, measuring_mode,
params, &rendermode, &gridfitmode);
IDWriteFontFace3_Release(fontface);
if (FAILED(hr))
return hr;
- SetRect(&target, 0, 0, This->size.cx, This->size.cy);
+ SetRect(&target_rect, 0, 0, target->size.cx, target->size.cy);
- if (rendermode == DWRITE_RENDERING_MODE1_OUTLINE) {
+ if (rendermode == DWRITE_RENDERING_MODE1_OUTLINE)
+ {
static const XFORM identity = { 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f };
- const DWRITE_MATRIX *m = &This->m;
+ const DWRITE_MATRIX *m = &target->m;
XFORM xform;
/* target allows any transform to be set, filter it here */
@@ -397,40 +402,42 @@ static HRESULT WINAPI rendertarget_DrawGlyphRun(IDWriteBitmapRenderTarget1 *ifac
xform.eDx = m->m11 * originX + m->m21 * originY + m->dx;
xform.eDy = m->m12 * originX + m->m22 * originY + m->dy;
}
- SetWorldTransform(This->hdc, &xform);
+ SetWorldTransform(target->hdc, &xform);
- BeginPath(This->hdc);
+ BeginPath(target->hdc);
- hr = IDWriteFontFace_GetGlyphRunOutline(run->fontFace, run->fontEmSize * This->ppdip,
+ hr = IDWriteFontFace_GetGlyphRunOutline(run->fontFace, run->fontEmSize * target->ppdip,
run->glyphIndices, run->glyphAdvances, run->glyphOffsets, run->glyphCount,
- run->isSideways, run->bidiLevel & 1, &This->ID2D1SimplifiedGeometrySink_iface);
+ run->isSideways, run->bidiLevel & 1, &target->ID2D1SimplifiedGeometrySink_iface);
- EndPath(This->hdc);
+ EndPath(target->hdc);
- if (hr == S_OK) {
+ if (hr == S_OK)
+ {
HBRUSH brush = CreateSolidBrush(color);
- SelectObject(This->hdc, brush);
+ SelectObject(target->hdc, brush);
- FillPath(This->hdc);
+ FillPath(target->hdc);
/* FIXME: one way to get affected rectangle bounds is to use region fill */
if (bbox_ret)
- *bbox_ret = target;
+ *bbox_ret = target_rect;
DeleteObject(brush);
}
- SetWorldTransform(This->hdc, &identity);
+ SetWorldTransform(target->hdc, &identity);
return hr;
}
scaled_run = *run;
- scaled_run.fontEmSize *= This->ppdip;
- hr = IDWriteFactory5_CreateGlyphRunAnalysis(This->factory, &scaled_run, &This->m, rendermode, measuring_mode,
- gridfitmode, This->antialiasmode, originX, originY, &analysis);
- if (FAILED(hr)) {
+ scaled_run.fontEmSize *= target->ppdip;
+ hr = IDWriteFactory7_CreateGlyphRunAnalysis(target->factory, &scaled_run, &target->m, rendermode, measuring_mode,
+ gridfitmode, target->antialiasmode, originX, originY, &analysis);
+ if (FAILED(hr))
+ {
WARN("failed to create analysis instance, 0x%08x\n", hr);
return hr;
}
@@ -448,8 +455,9 @@ static HRESULT WINAPI rendertarget_DrawGlyphRun(IDWriteBitmapRenderTarget1 *ifac
texturetype = DWRITE_TEXTURE_CLEARTYPE_3x1;
}
- if (IntersectRect(&target, &target, &bounds)) {
- UINT32 size = (target.right - target.left) * (target.bottom - target.top);
+ if (IntersectRect(&target_rect, &target_rect, &bounds))
+ {
+ UINT32 size = (target_rect.right - target_rect.left) * (target_rect.bottom - target_rect.top);
BYTE *bitmap;
color = colorref_to_pixel_888(color);
@@ -461,15 +469,15 @@ static HRESULT WINAPI rendertarget_DrawGlyphRun(IDWriteBitmapRenderTarget1 *ifac
return E_OUTOFMEMORY;
}
- hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, texturetype, &target, bitmap, size);
+ hr = IDWriteGlyphRunAnalysis_CreateAlphaTexture(analysis, texturetype, &target_rect, bitmap, size);
if (hr == S_OK) {
/* blit to target dib */
if (texturetype == DWRITE_TEXTURE_ALIASED_1x1)
- blit_8(&This->dib, bitmap, &target, color);
+ blit_8(&target->dib, bitmap, &target_rect, color);
else
- blit_subpixel_888(&This->dib, This->size.cx, bitmap, &target, color);
+ blit_subpixel_888(&target->dib, target->size.cx, bitmap, &target_rect, color);
- if (bbox_ret) *bbox_ret = target;
+ if (bbox_ret) *bbox_ret = target_rect;
}
heap_free(bitmap);
@@ -584,7 +592,7 @@ static const IDWriteBitmapRenderTarget1Vtbl rendertargetvtbl = {
rendertarget_SetTextAntialiasMode
};
-static HRESULT create_rendertarget(IDWriteFactory5 *factory, HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget **ret)
+static HRESULT create_rendertarget(IDWriteFactory7 *factory, HDC hdc, UINT32 width, UINT32 height, IDWriteBitmapRenderTarget **ret)
{
struct rendertarget *target;
HRESULT hr;
@@ -596,7 +604,7 @@ static HRESULT create_rendertarget(IDWriteFactory5 *factory, HDC hdc, UINT32 wid
target->IDWriteBitmapRenderTarget1_iface.lpVtbl = &rendertargetvtbl;
target->ID2D1SimplifiedGeometrySink_iface.lpVtbl = &rendertargetsinkvtbl;
- target->ref = 1;
+ target->refcount = 1;
target->hdc = CreateCompatibleDC(hdc);
SetGraphicsMode(target->hdc, GM_ADVANCED);
@@ -610,7 +618,7 @@ static HRESULT create_rendertarget(IDWriteFactory5 *factory, HDC hdc, UINT32 wid
target->ppdip = GetDeviceCaps(target->hdc, LOGPIXELSX) / 96.0f;
target->antialiasmode = DWRITE_TEXT_ANTIALIAS_MODE_CLEARTYPE;
target->factory = factory;
- IDWriteFactory5_AddRef(factory);
+ IDWriteFactory7_AddRef(factory);
*ret = (IDWriteBitmapRenderTarget*)&target->IDWriteBitmapRenderTarget1_iface;
@@ -640,26 +648,29 @@ static HRESULT WINAPI gdiinterop_QueryInterface(IDWriteGdiInterop1 *iface, REFII
static ULONG WINAPI gdiinterop_AddRef(IDWriteGdiInterop1 *iface)
{
- struct gdiinterop *This = impl_from_IDWriteGdiInterop1(iface);
- LONG ref = InterlockedIncrement(&This->ref);
- TRACE("(%p)->(%d)\n", This, ref);
- return ref;
+ struct gdiinterop *interop = impl_from_IDWriteGdiInterop1(iface);
+ LONG refcount = InterlockedIncrement(&interop->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
}
static ULONG WINAPI gdiinterop_Release(IDWriteGdiInterop1 *iface)
{
- struct gdiinterop *This = impl_from_IDWriteGdiInterop1(iface);
- LONG ref = InterlockedDecrement(&This->ref);
+ struct gdiinterop *interop = impl_from_IDWriteGdiInterop1(iface);
+ LONG refcount = InterlockedDecrement(&interop->refcount);
- TRACE("(%p)->(%d)\n", This, ref);
+ TRACE("%p, refcount %u.\n", iface, refcount);
- if (!ref) {
- IDWriteFactory5_UnregisterFontFileLoader(This->factory, &This->IDWriteFontFileLoader_iface);
- factory_detach_gdiinterop(This->factory, iface);
- heap_free(This);
+ if (!refcount)
+ {
+ IDWriteFactory7_UnregisterFontFileLoader(interop->factory, &interop->IDWriteFontFileLoader_iface);
+ factory_detach_gdiinterop(interop->factory, iface);
+ heap_free(interop);
}
- return ref;
+ return refcount;
}
static HRESULT WINAPI gdiinterop_CreateFontFromLOGFONT(IDWriteGdiInterop1 *iface,
@@ -751,7 +762,7 @@ extern BOOL WINAPI GetFontFileData(DWORD instance_id, DWORD unknown, UINT64 offs
static HRESULT WINAPI gdiinterop_CreateFontFaceFromHdc(IDWriteGdiInterop1 *iface,
HDC hdc, IDWriteFontFace **fontface)
{
- struct gdiinterop *This = impl_from_IDWriteGdiInterop1(iface);
+ struct gdiinterop *interop = impl_from_IDWriteGdiInterop1(iface);
struct font_realization_info info;
struct font_fileinfo *fileinfo;
DWRITE_FONT_FILE_TYPE filetype;
@@ -762,7 +773,7 @@ static HRESULT WINAPI gdiinterop_CreateFontFaceFromHdc(IDWriteGdiInterop1 *iface
SIZE_T needed;
HRESULT hr;
- TRACE("(%p)->(%p %p)\n", This, hdc, fontface);
+ TRACE("%p, %p, %p.\n", iface, hdc, fontface);
*fontface = NULL;
@@ -793,10 +804,10 @@ static HRESULT WINAPI gdiinterop_CreateFontFaceFromHdc(IDWriteGdiInterop1 *iface
}
if (*fileinfo->path)
- hr = IDWriteFactory5_CreateFontFileReference(This->factory, fileinfo->path, &fileinfo->writetime, &file);
+ hr = IDWriteFactory7_CreateFontFileReference(interop->factory, fileinfo->path, &fileinfo->writetime, &file);
else
- hr = IDWriteFactory5_CreateCustomFontFileReference(This->factory, &info.instance_id, sizeof(info.instance_id),
- &This->IDWriteFontFileLoader_iface, &file);
+ hr = IDWriteFactory7_CreateCustomFontFileReference(interop->factory, &info.instance_id,
+ sizeof(info.instance_id), &interop->IDWriteFontFileLoader_iface, &file);
heap_free(fileinfo);
if (FAILED(hr))
@@ -807,7 +818,7 @@ static HRESULT WINAPI gdiinterop_CreateFontFaceFromHdc(IDWriteGdiInterop1 *iface
if (SUCCEEDED(hr)) {
if (is_supported)
/* Simulations flags values match DWRITE_FONT_SIMULATIONS */
- hr = IDWriteFactory5_CreateFontFace(This->factory, facetype, 1, &file, info.face_index,
+ hr = IDWriteFactory7_CreateFontFace(interop->factory, facetype, 1, &file, info.face_index,
info.simulations, fontface);
else
hr = DWRITE_E_FILEFORMAT;
@@ -828,14 +839,14 @@ static HRESULT WINAPI gdiinterop_CreateBitmapRenderTarget(IDWriteGdiInterop1 *if
static HRESULT WINAPI gdiinterop1_CreateFontFromLOGFONT(IDWriteGdiInterop1 *iface,
LOGFONTW const *logfont, IDWriteFontCollection *collection, IDWriteFont **font)
{
- struct gdiinterop *This = impl_from_IDWriteGdiInterop1(iface);
+ struct gdiinterop *interop = impl_from_IDWriteGdiInterop1(iface);
IDWriteFontFamily *family;
DWRITE_FONT_STYLE style;
BOOL exists = FALSE;
UINT32 index;
HRESULT hr;
- TRACE("(%p)->(%p %p %p)\n", This, logfont, collection, font);
+ TRACE("%p, %p, %p, %p.\n", iface, logfont, collection, font);
*font = NULL;
@@ -844,7 +855,7 @@ static HRESULT WINAPI gdiinterop1_CreateFontFromLOGFONT(IDWriteGdiInterop1 *ifac
if (collection)
IDWriteFontCollection_AddRef(collection);
else {
- hr = IDWriteFactory5_GetSystemFontCollection(This->factory, FALSE, (IDWriteFontCollection1**)&collection, FALSE);
+ hr = IDWriteFactory5_GetSystemFontCollection((IDWriteFactory5 *)interop->factory, FALSE, (IDWriteFontCollection1 **)&collection, FALSE);
if (FAILED(hr)) {
ERR("failed to get system font collection: 0x%08x.\n", hr);
return hr;
@@ -1089,7 +1100,7 @@ static const struct IDWriteFontFileLoaderVtbl memresourceloadervtbl = {
memresourceloader_CreateStreamFromKey,
};
-HRESULT create_gdiinterop(IDWriteFactory5 *factory, IDWriteGdiInterop1 **ret)
+HRESULT create_gdiinterop(IDWriteFactory7 *factory, IDWriteGdiInterop1 **ret)
{
struct gdiinterop *interop;
@@ -1100,9 +1111,10 @@ HRESULT create_gdiinterop(IDWriteFactory5 *factory, IDWriteGdiInterop1 **ret)
interop->IDWriteGdiInterop1_iface.lpVtbl = &gdiinteropvtbl;
interop->IDWriteFontFileLoader_iface.lpVtbl = &memresourceloadervtbl;
- interop->ref = 1;
- IDWriteFactory5_AddRef(interop->factory = factory);
- IDWriteFactory5_RegisterFontFileLoader(factory, &interop->IDWriteFontFileLoader_iface);
+ interop->refcount = 1;
+ interop->factory = factory;
+ IDWriteFactory7_AddRef(interop->factory);
+ IDWriteFactory7_RegisterFontFileLoader(factory, &interop->IDWriteFontFileLoader_iface);
*ret = &interop->IDWriteGdiInterop1_iface;
return S_OK;
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 73dafffd67..9c88ab6871 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -1157,7 +1157,7 @@ static HRESULT WINAPI dwritefactory_GetGdiInterop(IDWriteFactory7 *iface, IDWrit
if (factory->gdiinterop)
IDWriteGdiInterop1_AddRef(factory->gdiinterop);
else
- hr = create_gdiinterop((IDWriteFactory5 *)iface, &factory->gdiinterop);
+ hr = create_gdiinterop(iface, &factory->gdiinterop);
*gdi_interop = (IDWriteGdiInterop *)factory->gdiinterop;
@@ -1893,11 +1893,11 @@ void factory_detach_fontcollection(IDWriteFactory7 *iface, IDWriteFontCollection
IDWriteFactory7_Release(iface);
}
-void factory_detach_gdiinterop(IDWriteFactory5 *iface, IDWriteGdiInterop1 *interop)
+void factory_detach_gdiinterop(IDWriteFactory7 *iface, IDWriteGdiInterop1 *interop)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
factory->gdiinterop = NULL;
- IDWriteFactory5_Release(iface);
+ IDWriteFactory7_Release(iface);
}
HRESULT WINAPI DWriteCreateFactory(DWRITE_FACTORY_TYPE type, REFIID riid, IUnknown **ret)
--
2.24.0
Dec. 5, 2019
[PATCH 8/9] dwrite: Use IDWriteFactory7 for layout internally.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 5 +++--
dlls/dwrite/layout.c | 14 +++++++-------
dlls/dwrite/main.c | 6 +++---
3 files changed, 13 insertions(+), 12 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index ce693239cf..871f93b60b 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -128,7 +128,7 @@ static inline BOOL is_simulation_valid(DWRITE_FONT_SIMULATIONS simulations)
struct textlayout_desc
{
- IDWriteFactory5 *factory;
+ IDWriteFactory7 *factory;
const WCHAR *string;
UINT32 length;
IDWriteTextFormat *format;
@@ -231,7 +231,8 @@ extern HRESULT create_numbersubstitution(DWRITE_NUMBER_SUBSTITUTION_METHOD,const
extern HRESULT create_textformat(const WCHAR*,IDWriteFontCollection*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH,
FLOAT,const WCHAR*,IDWriteTextFormat**) DECLSPEC_HIDDEN;
extern HRESULT create_textlayout(const struct textlayout_desc*,IDWriteTextLayout**) DECLSPEC_HIDDEN;
-extern HRESULT create_trimmingsign(IDWriteFactory5*,IDWriteTextFormat*,IDWriteInlineObject**) DECLSPEC_HIDDEN;
+extern HRESULT create_trimmingsign(IDWriteFactory7 *factory, IDWriteTextFormat *format,
+ IDWriteInlineObject **sign) DECLSPEC_HIDDEN;
extern HRESULT create_typography(IDWriteTypography**) DECLSPEC_HIDDEN;
extern HRESULT create_localizedstrings(IDWriteLocalizedStrings**) DECLSPEC_HIDDEN;
extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const WCHAR*) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/layout.c b/dlls/dwrite/layout.c
index 6f166b03f7..b9321157a9 100644
--- a/dlls/dwrite/layout.c
+++ b/dlls/dwrite/layout.c
@@ -251,7 +251,7 @@ struct dwrite_textlayout
IDWriteTextAnalysisSource1 IDWriteTextAnalysisSource1_iface;
LONG refcount;
- IDWriteFactory5 *factory;
+ IDWriteFactory7 *factory;
WCHAR *str;
UINT32 len;
@@ -806,7 +806,7 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout)
struct layout_run *r;
HRESULT hr;
- if (FAILED(hr = IDWriteFactory5_GetSystemFontCollection(layout->factory, FALSE,
+ if (FAILED(hr = IDWriteFactory5_GetSystemFontCollection((IDWriteFactory5 *)layout->factory, FALSE,
(IDWriteFontCollection1 **)&sys_collection, FALSE))) {
WARN("Failed to get system collection, hr %#x.\n", hr);
return hr;
@@ -817,7 +817,7 @@ static HRESULT layout_resolve_fonts(struct dwrite_textlayout *layout)
IDWriteFontFallback_AddRef(fallback);
}
else {
- if (FAILED(hr = IDWriteFactory5_GetSystemFontFallback(layout->factory, &fallback))) {
+ if (FAILED(hr = IDWriteFactory7_GetSystemFontFallback(layout->factory, &fallback))) {
WARN("Failed to get system fallback, hr %#x.\n", hr);
goto fatal;
}
@@ -2843,7 +2843,7 @@ static ULONG WINAPI dwritetextlayout_Release(IDWriteTextLayout4 *iface)
if (!refcount)
{
- IDWriteFactory5_Release(layout->factory);
+ IDWriteFactory7_Release(layout->factory);
free_layout_ranges_list(layout);
free_layout_eruns(layout);
free_layout_runs(layout);
@@ -5204,7 +5204,7 @@ static HRESULT init_textlayout(const struct textlayout_desc *desc, struct dwrite
layout->transform = desc->transform ? *desc->transform : identity;
layout->factory = desc->factory;
- IDWriteFactory5_AddRef(layout->factory);
+ IDWriteFactory7_AddRef(layout->factory);
list_add_head(&layout->ranges, &range->entry);
list_add_head(&layout->strike_ranges, &strike->entry);
list_add_head(&layout->underline_ranges, &underline->entry);
@@ -5366,7 +5366,7 @@ static inline BOOL is_flow_direction_vert(DWRITE_FLOW_DIRECTION direction)
(direction == DWRITE_FLOW_DIRECTION_BOTTOM_TO_TOP);
}
-HRESULT create_trimmingsign(IDWriteFactory5 *factory, IDWriteTextFormat *format, IDWriteInlineObject **sign)
+HRESULT create_trimmingsign(IDWriteFactory7 *factory, IDWriteTextFormat *format, IDWriteInlineObject **sign)
{
static const WCHAR ellipsisW = 0x2026;
struct dwrite_trimmingsign *This;
@@ -5392,7 +5392,7 @@ HRESULT create_trimmingsign(IDWriteFactory5 *factory, IDWriteTextFormat *format,
This->IDWriteInlineObject_iface.lpVtbl = &dwritetrimmingsignvtbl;
This->ref = 1;
- hr = IDWriteFactory5_CreateTextLayout(factory, &ellipsisW, 1, format, 0.0f, 0.0f, &This->layout);
+ hr = IDWriteFactory7_CreateTextLayout(factory, &ellipsisW, 1, format, 0.0f, 0.0f, &This->layout);
if (FAILED(hr)) {
heap_free(This);
return hr;
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 448e94058b..73dafffd67 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -1171,7 +1171,7 @@ static HRESULT WINAPI dwritefactory_CreateTextLayout(IDWriteFactory7 *iface, WCH
TRACE("%p, %s:%u, %p, %.8e, %.8e, %p.\n", iface, debugstr_wn(string, length), length, format, max_width, max_height, layout);
- desc.factory = (IDWriteFactory5 *)iface;
+ desc.factory = iface;
desc.string = string;
desc.length = length;
desc.format = format;
@@ -1193,7 +1193,7 @@ static HRESULT WINAPI dwritefactory_CreateGdiCompatibleTextLayout(IDWriteFactory
TRACE("%p, %s:%u, %p, %.8e, %.8e, %.8e, %p, %d, %p.\n", iface, debugstr_wn(string, length), length, format,
max_width, max_height, pixels_per_dip, transform, use_gdi_natural, layout);
- desc.factory = (IDWriteFactory5 *)iface;
+ desc.factory = iface;
desc.string = string;
desc.length = length;
desc.format = format;
@@ -1211,7 +1211,7 @@ static HRESULT WINAPI dwritefactory_CreateEllipsisTrimmingSign(IDWriteFactory7 *
{
TRACE("%p, %p, %p.\n", iface, format, trimming_sign);
- return create_trimmingsign((IDWriteFactory5 *)iface, format, trimming_sign);
+ return create_trimmingsign(iface, format, trimming_sign);
}
static HRESULT WINAPI dwritefactory_CreateTextAnalyzer(IDWriteFactory7 *iface, IDWriteTextAnalyzer **analyzer)
--
2.24.0
Dec. 5, 2019
[PATCH 7/9] dwrite: Use IDWriteFactory7 for collections internally.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 12 +++++-----
dlls/dwrite/font.c | 44 +++++++++++++++++++-----------------
dlls/dwrite/main.c | 18 +++++++--------
3 files changed, 38 insertions(+), 36 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index ae9576d010..ce693239cf 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -238,15 +238,15 @@ extern HRESULT add_localizedstring(IDWriteLocalizedStrings*,const WCHAR*,const W
extern HRESULT clone_localizedstring(IDWriteLocalizedStrings *iface, IDWriteLocalizedStrings **strings) DECLSPEC_HIDDEN;
extern void set_en_localizedstring(IDWriteLocalizedStrings*,const WCHAR*) DECLSPEC_HIDDEN;
extern void sort_localizedstrings(IDWriteLocalizedStrings*) DECLSPEC_HIDDEN;
-extern HRESULT get_system_fontcollection(IDWriteFactory5*,IDWriteFontCollection1**) DECLSPEC_HIDDEN;
-extern HRESULT get_eudc_fontcollection(IDWriteFactory5 *factory, IDWriteFontCollection3 **collection) DECLSPEC_HIDDEN;
+extern HRESULT get_system_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection1 **collection) DECLSPEC_HIDDEN;
+extern HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 **collection) DECLSPEC_HIDDEN;
extern IDWriteTextAnalyzer *get_text_analyzer(void) DECLSPEC_HIDDEN;
extern HRESULT create_font_file(IDWriteFontFileLoader *loader, const void *reference_key, UINT32 key_size, IDWriteFontFile **font_file) DECLSPEC_HIDDEN;
extern void init_local_fontfile_loader(void) DECLSPEC_HIDDEN;
extern IDWriteFontFileLoader *get_local_fontfile_loader(void) DECLSPEC_HIDDEN;
extern HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_list,
IDWriteFontFace5 **fontface) DECLSPEC_HIDDEN;
-extern HRESULT create_font_collection(IDWriteFactory5 *factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system,
+extern HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system,
IDWriteFontCollection3 **collection) DECLSPEC_HIDDEN;
extern HRESULT create_glyphrunanalysis(const struct glyphrunanalysis_desc*,IDWriteGlyphRunAnalysis**) DECLSPEC_HIDDEN;
extern BOOL is_system_collection(IDWriteFontCollection*) DECLSPEC_HIDDEN;
@@ -265,9 +265,9 @@ extern HRESULT create_matching_font(IDWriteFontCollection*,const WCHAR*,DWRITE_F
extern HRESULT create_fontfacereference(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index,
DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 axis_values_count,
IDWriteFontFaceReference1 **reference) DECLSPEC_HIDDEN;
-extern HRESULT factory_get_cached_fontface(IDWriteFactory5*,IDWriteFontFile*const*,UINT32,DWRITE_FONT_SIMULATIONS,
- struct list**,REFIID,void**) DECLSPEC_HIDDEN;
-extern void factory_detach_fontcollection(IDWriteFactory5 *factory, IDWriteFontCollection3 *collection) DECLSPEC_HIDDEN;
+extern HRESULT factory_get_cached_fontface(IDWriteFactory7 *factory, IDWriteFontFile * const *files, UINT32 num_files,
+ DWRITE_FONT_SIMULATIONS simulations, struct list **cache, REFIID riid, void **obj) DECLSPEC_HIDDEN;
+extern void factory_detach_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 *collection) DECLSPEC_HIDDEN;
extern void factory_detach_gdiinterop(IDWriteFactory5*,IDWriteGdiInterop1*) DECLSPEC_HIDDEN;
extern struct fontfacecached *factory_cache_fontface(IDWriteFactory7 *factory, struct list *fontfaces,
IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index baf915bd17..ef09f8e2bf 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -119,7 +119,7 @@ struct dwrite_fontcollection
IDWriteFontCollection3 IDWriteFontCollection3_iface;
LONG refcount;
- IDWriteFactory5 *factory;
+ IDWriteFactory7 *factory;
struct dwrite_fontfamily_data **family_data;
size_t size;
size_t count;
@@ -1828,12 +1828,12 @@ static BOOL WINAPI dwritefont3_Equals(IDWriteFont3 *iface, IDWriteFont *font)
static HRESULT WINAPI dwritefont3_GetFontFaceReference(IDWriteFont3 *iface, IDWriteFontFaceReference **reference)
{
- struct dwrite_font *This = impl_from_IDWriteFont3(iface);
+ struct dwrite_font *font = impl_from_IDWriteFont3(iface);
- TRACE("(%p)->(%p)\n", This, reference);
+ TRACE("%p, %p.\n", iface, reference);
- return IDWriteFactory5_CreateFontFaceReference_(This->family->collection->factory, This->data->file,
- This->data->face_index, This->data->simulations, reference);
+ return IDWriteFactory5_CreateFontFaceReference_((IDWriteFactory5 *)font->family->collection->factory,
+ font->data->file, font->data->face_index, font->data->simulations, reference);
}
static BOOL WINAPI dwritefont3_HasCharacter(IDWriteFont3 *iface, UINT32 ch)
@@ -3970,7 +3970,7 @@ static void fontcollection_add_replacements(struct dwrite_fontcollection *collec
RegCloseKey(hkey);
}
-HRESULT create_font_collection(IDWriteFactory5 *factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system,
+HRESULT create_font_collection(IDWriteFactory7 *factory, IDWriteFontFileEnumerator *enumerator, BOOL is_system,
IDWriteFontCollection3 **ret)
{
struct fontfile_enum {
@@ -4126,7 +4126,7 @@ HRESULT create_font_collection(IDWriteFactory5 *factory, IDWriteFontFileEnumerat
fontcollection_add_replacements(collection);
collection->factory = factory;
- IDWriteFactory5_AddRef(factory);
+ IDWriteFactory7_AddRef(factory);
return hr;
}
@@ -4136,7 +4136,7 @@ struct system_fontfile_enumerator
IDWriteFontFileEnumerator IDWriteFontFileEnumerator_iface;
LONG ref;
- IDWriteFactory5 *factory;
+ IDWriteFactory7 *factory;
HKEY hkey;
int index;
@@ -4175,8 +4175,9 @@ static ULONG WINAPI systemfontfileenumerator_Release(IDWriteFontFileEnumerator *
struct system_fontfile_enumerator *enumerator = impl_from_IDWriteFontFileEnumerator(iface);
ULONG ref = InterlockedDecrement(&enumerator->ref);
- if (!ref) {
- IDWriteFactory5_Release(enumerator->factory);
+ if (!ref)
+ {
+ IDWriteFactory7_Release(enumerator->factory);
RegCloseKey(enumerator->hkey);
heap_free(enumerator->filename);
heap_free(enumerator);
@@ -4185,7 +4186,7 @@ static ULONG WINAPI systemfontfileenumerator_Release(IDWriteFontFileEnumerator *
return ref;
}
-static HRESULT create_local_file_reference(IDWriteFactory5 *factory, const WCHAR *filename, IDWriteFontFile **file)
+static HRESULT create_local_file_reference(IDWriteFactory7 *factory, const WCHAR *filename, IDWriteFontFile **file)
{
HRESULT hr;
@@ -4198,10 +4199,10 @@ static HRESULT create_local_file_reference(IDWriteFactory5 *factory, const WCHAR
strcatW(fullpathW, fontsW);
strcatW(fullpathW, filename);
- hr = IDWriteFactory5_CreateFontFileReference(factory, fullpathW, NULL, file);
+ hr = IDWriteFactory7_CreateFontFileReference(factory, fullpathW, NULL, file);
}
else
- hr = IDWriteFactory5_CreateFontFileReference(factory, filename, NULL, file);
+ hr = IDWriteFactory7_CreateFontFileReference(factory, filename, NULL, file);
return hr;
}
@@ -4283,7 +4284,7 @@ static const struct IDWriteFontFileEnumeratorVtbl systemfontfileenumeratorvtbl =
systemfontfileenumerator_GetCurrentFontFile
};
-static HRESULT create_system_fontfile_enumerator(IDWriteFactory5 *factory, IDWriteFontFileEnumerator **ret)
+static HRESULT create_system_fontfile_enumerator(IDWriteFactory7 *factory, IDWriteFontFileEnumerator **ret)
{
struct system_fontfile_enumerator *enumerator;
static const WCHAR fontslistW[] = {
@@ -4309,11 +4310,12 @@ static HRESULT create_system_fontfile_enumerator(IDWriteFactory5 *factory, IDWri
return E_OUTOFMEMORY;
}
- IDWriteFactory5_AddRef(factory);
+ IDWriteFactory7_AddRef(factory);
- if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, fontslistW, 0, GENERIC_READ, &enumerator->hkey)) {
+ if (RegOpenKeyExW(HKEY_LOCAL_MACHINE, fontslistW, 0, GENERIC_READ, &enumerator->hkey))
+ {
ERR("failed to open fonts list key\n");
- IDWriteFactory5_Release(factory);
+ IDWriteFactory7_Release(factory);
heap_free(enumerator->filename);
heap_free(enumerator);
return E_FAIL;
@@ -4324,7 +4326,7 @@ static HRESULT create_system_fontfile_enumerator(IDWriteFactory5 *factory, IDWri
return S_OK;
}
-HRESULT get_system_fontcollection(IDWriteFactory5 *factory, IDWriteFontCollection1 **collection)
+HRESULT get_system_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection1 **collection)
{
IDWriteFontFileEnumerator *enumerator;
HRESULT hr;
@@ -4341,7 +4343,7 @@ HRESULT get_system_fontcollection(IDWriteFactory5 *factory, IDWriteFontCollectio
return hr;
}
-static HRESULT eudc_collection_add_family(IDWriteFactory5 *factory, struct dwrite_fontcollection *collection,
+static HRESULT eudc_collection_add_family(IDWriteFactory7 *factory, struct dwrite_fontcollection *collection,
const WCHAR *keynameW, const WCHAR *pathW)
{
static const WCHAR defaultfontW[] = {'S','y','s','t','e','m','D','e','f','a','u','l','t','E','U','D','C','F','o','n','t',0};
@@ -4429,7 +4431,7 @@ static HRESULT eudc_collection_add_family(IDWriteFactory5 *factory, struct dwrit
return hr;
}
-HRESULT get_eudc_fontcollection(IDWriteFactory5 *factory, IDWriteFontCollection3 **ret)
+HRESULT get_eudc_fontcollection(IDWriteFactory7 *factory, IDWriteFontCollection3 **ret)
{
static const WCHAR eudckeyfmtW[] = {'E','U','D','C','\\','%','u',0};
struct dwrite_fontcollection *collection;
@@ -4457,7 +4459,7 @@ HRESULT get_eudc_fontcollection(IDWriteFactory5 *factory, IDWriteFontCollection3
*ret = &collection->IDWriteFontCollection3_iface;
collection->factory = factory;
- IDWriteFactory5_AddRef(factory);
+ IDWriteFactory7_AddRef(factory);
/* return empty collection if EUDC fonts are not configured */
sprintfW(eudckeypathW, eudckeyfmtW, GetACP());
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index a63af6c488..448e94058b 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -667,7 +667,7 @@ static IDWriteFontCollection1 *factory_get_system_collection(struct dwritefactor
return factory->system_collection;
}
- if (FAILED(hr = get_system_fontcollection((IDWriteFactory5 *)&factory->IDWriteFactory7_iface, &collection)))
+ if (FAILED(hr = get_system_fontcollection(&factory->IDWriteFactory7_iface, &collection)))
{
WARN("Failed to create system font collection, hr %#x.\n", hr);
return NULL;
@@ -757,7 +757,7 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontCollection(IDWriteFactory7 *
if (FAILED(hr))
return hr;
- hr = create_font_collection((IDWriteFactory5 *)iface, enumerator, FALSE, (IDWriteFontCollection3 **)collection);
+ hr = create_font_collection(iface, enumerator, FALSE, (IDWriteFontCollection3 **)collection);
IDWriteFontFileEnumerator_Release(enumerator);
return hr;
}
@@ -859,10 +859,10 @@ void factory_unlock(IDWriteFactory7 *iface)
LeaveCriticalSection(&factory->cs);
}
-HRESULT factory_get_cached_fontface(IDWriteFactory5 *iface, IDWriteFontFile * const *font_files, UINT32 index,
+HRESULT factory_get_cached_fontface(IDWriteFactory7 *iface, IDWriteFontFile * const *font_files, UINT32 index,
DWRITE_FONT_SIMULATIONS simulations, struct list **cached_list, REFIID riid, void **obj)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
struct fontfacecached *cached;
IDWriteFontFileLoader *loader;
struct list *fontfaces;
@@ -1001,7 +1001,7 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory7 *iface, DWRIT
goto failed;
}
- hr = factory_get_cached_fontface((IDWriteFactory5 *)iface, font_files, index, simulations, &fontfaces,
+ hr = factory_get_cached_fontface(iface, font_files, index, simulations, &fontfaces,
&IID_IDWriteFontFace, (void **)fontface);
if (hr != S_FALSE)
goto failed;
@@ -1290,7 +1290,7 @@ static HRESULT WINAPI dwritefactory1_GetEudcFontCollection(IDWriteFactory7 *ifac
else {
IDWriteFontCollection3 *eudc_collection;
- if (FAILED(hr = get_eudc_fontcollection((IDWriteFactory5 *)iface, &eudc_collection)))
+ if (FAILED(hr = get_eudc_fontcollection(iface, &eudc_collection)))
{
*collection = NULL;
WARN("Failed to get EUDC collection, hr %#x.\n", hr);
@@ -1885,12 +1885,12 @@ static void init_dwritefactory(struct dwritefactory *factory, DWRITE_FACTORY_TYP
factory->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": dwritefactory.lock");
}
-void factory_detach_fontcollection(IDWriteFactory5 *iface, IDWriteFontCollection3 *collection)
+void factory_detach_fontcollection(IDWriteFactory7 *iface, IDWriteFontCollection3 *collection)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
InterlockedCompareExchangePointer((void **)&factory->system_collection, NULL, collection);
InterlockedCompareExchangePointer((void **)&factory->eudc_collection, NULL, collection);
- IDWriteFactory5_Release(iface);
+ IDWriteFactory7_Release(iface);
}
void factory_detach_gdiinterop(IDWriteFactory5 *iface, IDWriteGdiInterop1 *interop)
--
2.24.0
Dec. 5, 2019
[PATCH 6/9] dwrite: Use IDWriteFactory7 for fontface reference object.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 2 +-
dlls/dwrite/font.c | 12 ++++++------
dlls/dwrite/main.c | 9 +++------
3 files changed, 10 insertions(+), 13 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 9447c59663..ae9576d010 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -262,7 +262,7 @@ extern void release_system_fontfallback(IDWriteFontFallback1 *fallback) DECLSPEC
extern HRESULT create_fontfallback_builder(IDWriteFactory5*,IDWriteFontFallbackBuilder**) DECLSPEC_HIDDEN;
extern HRESULT create_matching_font(IDWriteFontCollection*,const WCHAR*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH,
IDWriteFont**) DECLSPEC_HIDDEN;
-extern HRESULT create_fontfacereference(IDWriteFactory5 *factory, IDWriteFontFile *file, UINT32 face_index,
+extern HRESULT create_fontfacereference(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index,
DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 axis_values_count,
IDWriteFontFaceReference1 **reference) DECLSPEC_HIDDEN;
extern HRESULT factory_get_cached_fontface(IDWriteFactory5*,IDWriteFontFile*const*,UINT32,DWRITE_FONT_SIMULATIONS,
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index c9f1e885d5..baf915bd17 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -233,7 +233,7 @@ struct dwrite_fontfacereference
USHORT simulations;
DWRITE_FONT_AXIS_VALUE *axis_values;
UINT32 axis_values_count;
- IDWriteFactory5 *factory;
+ IDWriteFactory7 *factory;
};
struct dwrite_fontresource
@@ -6082,7 +6082,7 @@ static ULONG WINAPI fontfacereference_Release(IDWriteFontFaceReference1 *iface)
if (!refcount)
{
IDWriteFontFile_Release(reference->file);
- IDWriteFactory5_Release(reference->factory);
+ IDWriteFactory7_Release(reference->factory);
heap_free(reference->axis_values);
heap_free(reference);
}
@@ -6116,7 +6116,7 @@ static HRESULT WINAPI fontfacereference_CreateFontFaceWithSimulations(IDWriteFon
if (FAILED(hr))
return hr;
- hr = IDWriteFactory5_CreateFontFace(reference->factory, face_type, 1, &reference->file, reference->index,
+ hr = IDWriteFactory7_CreateFontFace(reference->factory, face_type, 1, &reference->file, reference->index,
simulations, &fontface);
if (SUCCEEDED(hr))
{
@@ -6182,7 +6182,7 @@ static HRESULT WINAPI fontfacereference_GetFontFile(IDWriteFontFaceReference1 *i
if (FAILED(hr))
return hr;
- hr = IDWriteFactory5_CreateCustomFontFileReference(reference->factory, key, key_size, loader, file);
+ hr = IDWriteFactory7_CreateCustomFontFileReference(reference->factory, key, key_size, loader, file);
IDWriteFontFileLoader_Release(loader);
return hr;
@@ -6295,7 +6295,7 @@ static const IDWriteFontFaceReference1Vtbl fontfacereferencevtbl =
fontfacereference1_GetFontAxisValues,
};
-HRESULT create_fontfacereference(IDWriteFactory5 *factory, IDWriteFontFile *file, UINT32 index,
+HRESULT create_fontfacereference(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 index,
DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 axis_values_count,
IDWriteFontFaceReference1 **ret)
{
@@ -6314,7 +6314,7 @@ HRESULT create_fontfacereference(IDWriteFactory5 *factory, IDWriteFontFile *file
object->refcount = 1;
object->factory = factory;
- IDWriteFactory5_AddRef(object->factory);
+ IDWriteFactory7_AddRef(object->factory);
object->file = file;
IDWriteFontFile_AddRef(object->file);
object->index = index;
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 5f30b8e4f4..a63af6c488 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -1443,8 +1443,7 @@ static HRESULT WINAPI dwritefactory3_CreateFontFaceReference_(IDWriteFactory7 *i
{
TRACE("%p, %p, %u, %x, %p.\n", iface, file, index, simulations, reference);
- return create_fontfacereference((IDWriteFactory5 *)iface, file, index, simulations, NULL, 0,
- (IDWriteFontFaceReference1 **)reference);
+ return create_fontfacereference(iface, file, index, simulations, NULL, 0, (IDWriteFontFaceReference1 **)reference);
}
static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory7 *iface, WCHAR const *path,
@@ -1463,8 +1462,7 @@ static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory7 *if
return hr;
}
- hr = create_fontfacereference((IDWriteFactory5 *)iface, file, index, simulations, NULL, 0,
- (IDWriteFontFaceReference1 **)reference);
+ hr = create_fontfacereference(iface, file, index, simulations, NULL, 0, (IDWriteFontFaceReference1 **)reference);
IDWriteFontFile_Release(file);
return hr;
}
@@ -1664,8 +1662,7 @@ static HRESULT WINAPI dwritefactory6_CreateFontFaceReference(IDWriteFactory7 *if
TRACE("%p, %p, %u, %#x, %p, %u, %p.\n", iface, file, face_index, simulations, axis_values, axis_values_count,
reference);
- return create_fontfacereference((IDWriteFactory5 *)iface, file, face_index, simulations, axis_values,
- axis_values_count, reference);
+ return create_fontfacereference(iface, file, face_index, simulations, axis_values, axis_values_count, reference);
}
static HRESULT WINAPI dwritefactory6_CreateFontResource(IDWriteFactory7 *iface, IDWriteFontFile *file,
--
2.24.0
Dec. 5, 2019
[PATCH 5/9] dwrite: Add newer CreateFontFaceReference() variant.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 5 +++--
dlls/dwrite/font.c | 26 +++++++++++++++++++++-----
dlls/dwrite/main.c | 19 ++++++++++++-------
dlls/dwrite/tests/font.c | 25 +++++++++++++++++++------
4 files changed, 55 insertions(+), 20 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 1598bb6aee..9447c59663 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -262,8 +262,9 @@ extern void release_system_fontfallback(IDWriteFontFallback1 *fallback) DECLSPEC
extern HRESULT create_fontfallback_builder(IDWriteFactory5*,IDWriteFontFallbackBuilder**) DECLSPEC_HIDDEN;
extern HRESULT create_matching_font(IDWriteFontCollection*,const WCHAR*,DWRITE_FONT_WEIGHT,DWRITE_FONT_STYLE,DWRITE_FONT_STRETCH,
IDWriteFont**) DECLSPEC_HIDDEN;
-extern HRESULT create_fontfacereference(IDWriteFactory5*,IDWriteFontFile*,UINT32,DWRITE_FONT_SIMULATIONS,
- IDWriteFontFaceReference**) DECLSPEC_HIDDEN;
+extern HRESULT create_fontfacereference(IDWriteFactory5 *factory, IDWriteFontFile *file, UINT32 face_index,
+ DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 axis_values_count,
+ IDWriteFontFaceReference1 **reference) DECLSPEC_HIDDEN;
extern HRESULT factory_get_cached_fontface(IDWriteFactory5*,IDWriteFontFile*const*,UINT32,DWRITE_FONT_SIMULATIONS,
struct list**,REFIID,void**) DECLSPEC_HIDDEN;
extern void factory_detach_fontcollection(IDWriteFactory5 *factory, IDWriteFontCollection3 *collection) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 8045bce870..c9f1e885d5 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -231,6 +231,8 @@ struct dwrite_fontfacereference
IDWriteFontFile *file;
UINT32 index;
USHORT simulations;
+ DWRITE_FONT_AXIS_VALUE *axis_values;
+ UINT32 axis_values_count;
IDWriteFactory5 *factory;
};
@@ -6081,6 +6083,7 @@ static ULONG WINAPI fontfacereference_Release(IDWriteFontFaceReference1 *iface)
{
IDWriteFontFile_Release(reference->file);
IDWriteFactory5_Release(reference->factory);
+ heap_free(reference->axis_values);
heap_free(reference);
}
@@ -6253,9 +6256,11 @@ static HRESULT WINAPI fontfacereference1_CreateFontFace(IDWriteFontFaceReference
static UINT32 WINAPI fontfacereference1_GetFontAxisValueCount(IDWriteFontFaceReference1 *iface)
{
- FIXME("%p.\n", iface);
+ struct dwrite_fontfacereference *reference = impl_from_IDWriteFontFaceReference1(iface);
- return 0;
+ TRACE("%p.\n", iface);
+
+ return reference->axis_values_count;
}
static HRESULT WINAPI fontfacereference1_GetFontAxisValues(IDWriteFontFaceReference1 *iface,
@@ -6291,7 +6296,8 @@ static const IDWriteFontFaceReference1Vtbl fontfacereferencevtbl =
};
HRESULT create_fontfacereference(IDWriteFactory5 *factory, IDWriteFontFile *file, UINT32 index,
- DWRITE_FONT_SIMULATIONS simulations, IDWriteFontFaceReference **ret)
+ DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 axis_values_count,
+ IDWriteFontFaceReference1 **ret)
{
struct dwrite_fontfacereference *object;
@@ -6300,7 +6306,7 @@ HRESULT create_fontfacereference(IDWriteFactory5 *factory, IDWriteFontFile *file
if (!is_simulation_valid(simulations))
return E_INVALIDARG;
- object = heap_alloc(sizeof(*object));
+ object = heap_alloc_zero(sizeof(*object));
if (!object)
return E_OUTOFMEMORY;
@@ -6313,8 +6319,18 @@ HRESULT create_fontfacereference(IDWriteFactory5 *factory, IDWriteFontFile *file
IDWriteFontFile_AddRef(object->file);
object->index = index;
object->simulations = simulations;
+ if (axis_values_count)
+ {
+ if (!(object->axis_values = heap_alloc(axis_values_count * sizeof(*axis_values))))
+ {
+ IDWriteFontFaceReference1_Release(&object->IDWriteFontFaceReference1_iface);
+ return E_OUTOFMEMORY;
+ }
+ memcpy(object->axis_values, axis_values, axis_values_count * sizeof(*axis_values));
+ object->axis_values_count = axis_values_count;
+ }
- *ret = (IDWriteFontFaceReference *)&object->IDWriteFontFaceReference1_iface;
+ *ret = &object->IDWriteFontFaceReference1_iface;
return S_OK;
}
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index e4b76823ff..5f30b8e4f4 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -1443,7 +1443,8 @@ static HRESULT WINAPI dwritefactory3_CreateFontFaceReference_(IDWriteFactory7 *i
{
TRACE("%p, %p, %u, %x, %p.\n", iface, file, index, simulations, reference);
- return create_fontfacereference((IDWriteFactory5 *)iface, file, index, simulations, reference);
+ return create_fontfacereference((IDWriteFactory5 *)iface, file, index, simulations, NULL, 0,
+ (IDWriteFontFaceReference1 **)reference);
}
static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory7 *iface, WCHAR const *path,
@@ -1455,13 +1456,15 @@ static HRESULT WINAPI dwritefactory3_CreateFontFaceReference(IDWriteFactory7 *if
TRACE("%p, %s, %p, %u, %#x, %p.\n", iface, debugstr_w(path), writetime, index, simulations, reference);
- hr = IDWriteFactory5_CreateFontFileReference((IDWriteFactory5 *)iface, path, writetime, &file);
- if (FAILED(hr)) {
+ hr = IDWriteFactory7_CreateFontFileReference(iface, path, writetime, &file);
+ if (FAILED(hr))
+ {
*reference = NULL;
return hr;
}
- hr = IDWriteFactory5_CreateFontFaceReference_((IDWriteFactory5 *)iface, file, index, simulations, reference);
+ hr = create_fontfacereference((IDWriteFactory5 *)iface, file, index, simulations, NULL, 0,
+ (IDWriteFontFaceReference1 **)reference);
IDWriteFontFile_Release(file);
return hr;
}
@@ -1656,11 +1659,13 @@ static HRESULT WINAPI dwritefactory5_UnpackFontFile(IDWriteFactory7 *iface, DWRI
static HRESULT WINAPI dwritefactory6_CreateFontFaceReference(IDWriteFactory7 *iface, IDWriteFontFile *file,
UINT32 face_index, DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values,
- UINT32 num_axis, IDWriteFontFaceReference1 **ref)
+ UINT32 axis_values_count, IDWriteFontFaceReference1 **reference)
{
- FIXME("%p, %p, %u, %#x, %p, %u, %p.\n", iface, file, face_index, simulations, axis_values, num_axis, ref);
+ TRACE("%p, %p, %u, %#x, %p, %u, %p.\n", iface, file, face_index, simulations, axis_values, axis_values_count,
+ reference);
- return E_NOTIMPL;
+ return create_fontfacereference((IDWriteFactory5 *)iface, file, face_index, simulations, axis_values,
+ axis_values_count, reference);
}
static HRESULT WINAPI dwritefactory6_CreateFontResource(IDWriteFactory7 *iface, IDWriteFontFile *file,
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 83d6be4449..5ab01465b7 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -9239,6 +9239,7 @@ static void test_font_resource(void)
IDWriteFontFaceReference1 *reference, *reference2;
IDWriteFontResource *resource, *resource2;
IDWriteFontFile *fontfile, *fontfile2;
+ DWRITE_FONT_AXIS_VALUE axis_value;
IDWriteFontFace5 *fontface5;
IDWriteFontFace *fontface;
IDWriteFactory6 *factory;
@@ -9274,22 +9275,34 @@ static void test_font_resource(void)
index = IDWriteFontResource_GetFontFaceIndex(resource);
ok(!index, "Unexpected index %u.\n", index);
+ /* Specify axis value, font has no variations. */
+ axis_value.axisTag = DWRITE_FONT_AXIS_TAG_WEIGHT;
+ axis_value.value = 400.0f;
+ hr = IDWriteFontResource_CreateFontFaceReference(resource, DWRITE_FONT_SIMULATIONS_NONE, &axis_value, 1, &reference);
+ ok(hr == S_OK, "Failed to create reference object, hr %#x.\n", hr);
+
+ count = IDWriteFontFaceReference1_GetFontAxisValueCount(reference);
+ ok(count == 1, "Unexpected axis value count.\n");
+
+ IDWriteFontFaceReference1_Release(reference);
+
+ hr = IDWriteFactory6_CreateFontFaceReference(factory, fontfile, 0, DWRITE_FONT_SIMULATIONS_NONE, &axis_value, 1,
+ &reference);
+ count = IDWriteFontFaceReference1_GetFontAxisValueCount(reference);
+ ok(count == 1, "Unexpected axis value count.\n");
+ IDWriteFontFaceReference1_Release(reference);
+
EXPECT_REF(resource, 1);
hr = IDWriteFontResource_CreateFontFaceReference(resource, DWRITE_FONT_SIMULATIONS_NONE, NULL, 0, &reference);
-todo_wine
ok(hr == S_OK, "Failed to create reference object, hr %#x.\n", hr);
EXPECT_REF(resource, 1);
hr = IDWriteFontResource_CreateFontFaceReference(resource, DWRITE_FONT_SIMULATIONS_NONE, NULL, 0, &reference2);
-todo_wine
ok(hr == S_OK, "Failed to create reference object, hr %#x.\n", hr);
-
-if (SUCCEEDED(hr))
-{
ok(reference != reference2, "Unexpected reference instance.\n");
IDWriteFontFaceReference1_Release(reference2);
IDWriteFontFaceReference1_Release(reference);
-}
+
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace5, (void **)&fontface5);
ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
--
2.24.0
Dec. 5, 2019
[PATCH 4/9] dwrite: Implement GetFontResource() for fontface.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/font.c | 6 ++++--
dlls/dwrite/tests/font.c | 13 ++-----------
2 files changed, 6 insertions(+), 13 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 8c58d7561a..8045bce870 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -1435,9 +1435,11 @@ static BOOL WINAPI dwritefontface5_HasVariations(IDWriteFontFace5 *iface)
static HRESULT WINAPI dwritefontface5_GetFontResource(IDWriteFontFace5 *iface, IDWriteFontResource **resource)
{
- FIXME("%p, %p: stub\n", iface, resource);
+ struct dwrite_fontface *fontface = impl_from_IDWriteFontFace5(iface);
- return E_NOTIMPL;
+ TRACE("%p, %p.\n", iface, resource);
+
+ return IDWriteFactory7_CreateFontResource(fontface->factory, fontface->files[0], fontface->index, resource);
}
static const IDWriteFontFace5Vtbl dwritefontfacevtbl =
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index d06b2f555a..83d6be4449 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -9294,28 +9294,19 @@ if (SUCCEEDED(hr))
ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
hr = IDWriteFontFace5_GetFontResource(fontface5, &resource2);
-todo_wine
ok(hr == S_OK, "Failed to get font resource, hr %#x.\n", hr);
-
-if (SUCCEEDED(hr))
-{
ok(resource != resource2, "Unexpected resource instance.\n");
IDWriteFontResource_Release(resource);
-}
+
hr = IDWriteFontFace5_GetFontResource(fontface5, &resource);
-todo_wine
ok(hr == S_OK, "Failed to get font resource, hr %#x.\n", hr);
-
-if (SUCCEEDED(hr))
-{
ok(resource != resource2, "Unexpected resource instance.\n");
EXPECT_REF(resource, 1);
IDWriteFontResource_Release(resource);
IDWriteFontResource_Release(resource2);
-}
+
IDWriteFontFace5_Release(fontface5);
- IDWriteFontResource_Release(resource);
IDWriteFontFile_Release(fontfile);
IDWriteFontFace_Release(fontface);
--
2.24.0
Dec. 5, 2019