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
[PATCH 3/9] dwrite: Use IDWriteFactory7 internall for fontfaces.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 10 +++++-----
dlls/dwrite/font.c | 11 ++++++-----
dlls/dwrite/main.c | 14 +++++++-------
3 files changed, 18 insertions(+), 17 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index a5d946c385..1598bb6aee 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -154,7 +154,7 @@ struct glyphrunanalysis_desc
struct fontface_desc
{
- IDWriteFactory5 *factory;
+ IDWriteFactory7 *factory;
DWRITE_FONT_FACE_TYPE face_type;
IDWriteFontFile * const *files;
IDWriteFontFileStream *stream;
@@ -193,7 +193,7 @@ struct dwrite_fontface
UINT32 file_count;
UINT32 index;
- IDWriteFactory5 *factory;
+ IDWriteFactory7 *factory;
struct fontfacecached *cached;
USHORT simulations;
@@ -268,7 +268,7 @@ extern HRESULT factory_get_cached_fontface(IDWriteFactory5*,IDWriteFontFile*cons
struct list**,REFIID,void**) DECLSPEC_HIDDEN;
extern void factory_detach_fontcollection(IDWriteFactory5 *factory, IDWriteFontCollection3 *collection) DECLSPEC_HIDDEN;
extern void factory_detach_gdiinterop(IDWriteFactory5*,IDWriteGdiInterop1*) DECLSPEC_HIDDEN;
-extern struct fontfacecached *factory_cache_fontface(IDWriteFactory5 *factory, struct list *fontfaces,
+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;
@@ -276,8 +276,8 @@ extern HRESULT get_fontsig_from_font(IDWriteFont*,FONTSIGNATURE*) DECLSPEC_HIDDE
extern HRESULT get_fontsig_from_fontface(IDWriteFontFace*,FONTSIGNATURE*) DECLSPEC_HIDDEN;
extern HRESULT create_gdiinterop(IDWriteFactory5*,IDWriteGdiInterop1**) DECLSPEC_HIDDEN;
extern void fontface_detach_from_cache(IDWriteFontFace5 *fontface) DECLSPEC_HIDDEN;
-extern void factory_lock(IDWriteFactory5*) DECLSPEC_HIDDEN;
-extern void factory_unlock(IDWriteFactory5*) DECLSPEC_HIDDEN;
+extern void factory_lock(IDWriteFactory7 *factory) DECLSPEC_HIDDEN;
+extern void factory_unlock(IDWriteFactory7 *factory) DECLSPEC_HIDDEN;
extern HRESULT create_inmemory_fileloader(IDWriteFontFileLoader**) DECLSPEC_HIDDEN;
extern HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index,
IDWriteFontResource **resource) DECLSPEC_HIDDEN;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index bfe32d5fd9..8c58d7561a 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -551,7 +551,7 @@ static ULONG WINAPI dwritefontface_Release(IDWriteFontFace5 *iface)
freetype_notify_cacheremove(iface);
- IDWriteFactory5_Release(fontface->factory);
+ IDWriteFactory7_Release(fontface->factory);
heap_free(fontface);
}
@@ -1518,7 +1518,7 @@ static HRESULT get_fontface_from_font(struct dwrite_font *font, IDWriteFontFace5
if (FAILED(hr = get_filestream_from_file(data->file, &desc.stream)))
return hr;
- desc.factory = font->family->collection->factory;
+ desc.factory = (IDWriteFactory7 *)font->family->collection->factory;
desc.face_type = data->face_type;
desc.files = &data->file;
desc.files_number = 1;
@@ -4051,7 +4051,7 @@ HRESULT create_font_collection(IDWriteFactory5 *factory, IDWriteFontFileEnumerat
WCHAR familyW[255];
UINT32 index;
- desc.factory = factory;
+ desc.factory = (IDWriteFactory7 *)factory;
desc.face_type = face_type;
desc.files = &file;
desc.stream = stream;
@@ -4394,7 +4394,7 @@ static HRESULT eudc_collection_add_family(IDWriteFactory5 *factory, struct dwrit
struct fontface_desc desc;
/* alloc and init new font data structure */
- desc.factory = factory;
+ desc.factory = (IDWriteFactory7 *)factory;
desc.face_type = face_type;
desc.index = i;
desc.files = &file;
@@ -4660,7 +4660,8 @@ HRESULT create_fontface(const struct fontface_desc *desc, struct list *cached_li
fontface->colr.exists = TRUE;
fontface->index = desc->index;
fontface->simulations = desc->simulations;
- IDWriteFactory5_AddRef(fontface->factory = desc->factory);
+ fontface->factory = desc->factory;
+ IDWriteFactory7_AddRef(fontface->factory);
for (i = 0; i < fontface->file_count; i++) {
fontface->files[i] = desc->files[i];
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 1c1fabdb7d..e4b76823ff 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -847,15 +847,15 @@ static HRESULT WINAPI dwritefactory_CreateCustomFontFileReference(IDWriteFactory
return create_font_file(loader, reference_key, key_size, font_file);
}
-void factory_lock(IDWriteFactory5 *iface)
+void factory_lock(IDWriteFactory7 *iface)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
EnterCriticalSection(&factory->cs);
}
-void factory_unlock(IDWriteFactory5 *iface)
+void factory_unlock(IDWriteFactory7 *iface)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
LeaveCriticalSection(&factory->cs);
}
@@ -935,10 +935,10 @@ HRESULT factory_get_cached_fontface(IDWriteFactory5 *iface, IDWriteFontFile * co
return *obj ? S_OK : S_FALSE;
}
-struct fontfacecached *factory_cache_fontface(IDWriteFactory5 *iface, struct list *fontfaces,
+struct fontfacecached *factory_cache_fontface(IDWriteFactory7 *iface, struct list *fontfaces,
IDWriteFontFace5 *fontface)
{
- struct dwritefactory *factory = impl_from_IDWriteFactory7((IDWriteFactory7 *)iface);
+ struct dwritefactory *factory = impl_from_IDWriteFactory7(iface);
struct fontfacecached *cached;
/* new cache entry */
@@ -1006,7 +1006,7 @@ static HRESULT WINAPI dwritefactory_CreateFontFace(IDWriteFactory7 *iface, DWRIT
if (hr != S_FALSE)
goto failed;
- desc.factory = (IDWriteFactory5 *)iface;
+ desc.factory = iface;
desc.face_type = req_facetype;
desc.files = font_files;
desc.stream = stream;
--
2.24.0
Dec. 5, 2019
[PATCH 2/9] dwrite: Respond to IDWriteFontFace5 queries.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/font.c | 7 ++++---
dlls/dwrite/tests/font.c | 17 ++++++++++-------
2 files changed, 14 insertions(+), 10 deletions(-)
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 8788181303..bfe32d5fd9 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -474,7 +474,8 @@ static HRESULT WINAPI dwritefontface_QueryInterface(IDWriteFontFace5 *iface, REF
TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
- if (IsEqualIID(riid, &IID_IDWriteFontFace4) ||
+ if (IsEqualIID(riid, &IID_IDWriteFontFace5) ||
+ IsEqualIID(riid, &IID_IDWriteFontFace4) ||
IsEqualIID(riid, &IID_IDWriteFontFace3) ||
IsEqualIID(riid, &IID_IDWriteFontFace2) ||
IsEqualIID(riid, &IID_IDWriteFontFace1) ||
@@ -1425,7 +1426,7 @@ static HRESULT WINAPI dwritefontface5_GetFontAxisValues(IDWriteFontFace5 *iface,
return E_NOTIMPL;
}
-static BOOL WINAPI dwritefontface5_HasVariantions(IDWriteFontFace5 *iface)
+static BOOL WINAPI dwritefontface5_HasVariations(IDWriteFontFace5 *iface)
{
FIXME("%p: stub\n", iface);
@@ -1496,7 +1497,7 @@ static const IDWriteFontFace5Vtbl dwritefontfacevtbl =
dwritefontface4_ReleaseGlyphImageData,
dwritefontface5_GetFontAxisValueCount,
dwritefontface5_GetFontAxisValues,
- dwritefontface5_HasVariantions,
+ dwritefontface5_HasVariations,
dwritefontface5_GetFontResource,
};
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index f0266cb751..d06b2f555a 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -9291,25 +9291,28 @@ if (SUCCEEDED(hr))
IDWriteFontFaceReference1_Release(reference);
}
hr = IDWriteFontFace_QueryInterface(fontface, &IID_IDWriteFontFace5, (void **)&fontface5);
-todo_wine
ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
- if (FAILED(hr))
- return;
-
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);
--
2.24.0
Dec. 5, 2019
[PATCH 1/9] dwrite: Add partial implementation for IDWriteFontResource.
by Nikolay Sivov
Signed-off-by: Nikolay Sivov <nsivov(a)codeweavers.com>
---
dlls/dwrite/dwrite_private.h | 2 +
dlls/dwrite/font.c | 217 +++++++++++++++++++++++++++++++++++
dlls/dwrite/main.c | 4 +-
dlls/dwrite/tests/font.c | 22 ++--
4 files changed, 233 insertions(+), 12 deletions(-)
diff --git a/dlls/dwrite/dwrite_private.h b/dlls/dwrite/dwrite_private.h
index 7898403dd9..a5d946c385 100644
--- a/dlls/dwrite/dwrite_private.h
+++ b/dlls/dwrite/dwrite_private.h
@@ -279,6 +279,8 @@ extern void fontface_detach_from_cache(IDWriteFontFace5 *fontface) DECLSPEC_HIDD
extern void factory_lock(IDWriteFactory5*) DECLSPEC_HIDDEN;
extern void factory_unlock(IDWriteFactory5*) DECLSPEC_HIDDEN;
extern HRESULT create_inmemory_fileloader(IDWriteFontFileLoader**) DECLSPEC_HIDDEN;
+extern HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index,
+ IDWriteFontResource **resource) DECLSPEC_HIDDEN;
struct dwrite_fontface;
diff --git a/dlls/dwrite/font.c b/dlls/dwrite/font.c
index 1bf88d6b17..8788181303 100644
--- a/dlls/dwrite/font.c
+++ b/dlls/dwrite/font.c
@@ -234,6 +234,16 @@ struct dwrite_fontfacereference
IDWriteFactory5 *factory;
};
+struct dwrite_fontresource
+{
+ IDWriteFontResource IDWriteFontResource_iface;
+ LONG refcount;
+
+ IDWriteFontFile *file;
+ UINT32 face_index;
+ IDWriteFactory7 *factory;
+};
+
static void dwrite_grab_font_table(void *context, UINT32 table, const BYTE **data, UINT32 *size, void **data_context)
{
struct dwrite_fontface *fontface = context;
@@ -325,6 +335,11 @@ static inline struct dwrite_fontfacereference *impl_from_IDWriteFontFaceReferenc
return CONTAINING_RECORD(iface, struct dwrite_fontfacereference, IDWriteFontFaceReference1_iface);
}
+static struct dwrite_fontresource *impl_from_IDWriteFontResource(IDWriteFontResource *iface)
+{
+ return CONTAINING_RECORD(iface, struct dwrite_fontresource, IDWriteFontResource_iface);
+}
+
static HRESULT get_cached_glyph_metrics(struct dwrite_fontface *fontface, UINT16 glyph, DWRITE_GLYPH_METRICS *metrics)
{
static const DWRITE_GLYPH_METRICS nil;
@@ -6555,3 +6570,205 @@ HRESULT create_inmemory_fileloader(IDWriteFontFileLoader **ret)
return S_OK;
}
+
+static HRESULT WINAPI dwritefontresource_QueryInterface(IDWriteFontResource *iface, REFIID riid, void **obj)
+{
+ TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj);
+
+ if (IsEqualIID(riid, &IID_IDWriteFontResource) ||
+ IsEqualIID(riid, &IID_IUnknown))
+ {
+ *obj = iface;
+ IDWriteFontResource_AddRef(iface);
+ return S_OK;
+ }
+
+ WARN("Unsupported interface %s.\n", debugstr_guid(riid));
+
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI dwritefontresource_AddRef(IDWriteFontResource *iface)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+ ULONG refcount = InterlockedIncrement(&resource->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ return refcount;
+}
+
+static ULONG WINAPI dwritefontresource_Release(IDWriteFontResource *iface)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+ ULONG refcount = InterlockedDecrement(&resource->refcount);
+
+ TRACE("%p, refcount %u.\n", iface, refcount);
+
+ if (!refcount)
+ {
+ IDWriteFactory7_Release(resource->factory);
+ IDWriteFontFile_Release(resource->file);
+ heap_free(resource);
+ }
+
+ return refcount;
+}
+
+static HRESULT WINAPI dwritefontresource_GetFontFile(IDWriteFontResource *iface, IDWriteFontFile **fontfile)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+
+ TRACE("%p, %p.\n", iface, fontfile);
+
+ *fontfile = resource->file;
+ IDWriteFontFile_AddRef(*fontfile);
+
+ return S_OK;
+}
+
+static UINT32 WINAPI dwritefontresource_GetFontFaceIndex(IDWriteFontResource *iface)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+
+ TRACE("%p.\n", iface);
+
+ return resource->face_index;
+}
+
+static UINT32 WINAPI dwritefontresource_GetFontAxisCount(IDWriteFontResource *iface)
+{
+ FIXME("%p.\n", iface);
+
+ return 0;
+}
+
+static HRESULT WINAPI dwritefontresource_GetDefaultFontAxisValues(IDWriteFontResource *iface,
+ DWRITE_FONT_AXIS_VALUE const *values, UINT32 num_values)
+{
+ FIXME("%p, %p, %u.\n", iface, values, num_values);
+
+ return E_NOTIMPL;
+}
+
+static HRESULT WINAPI dwritefontresource_GetFontAxisRanges(IDWriteFontResource *iface,
+ DWRITE_FONT_AXIS_RANGE const *ranges, UINT32 num_ranges)
+{
+ FIXME("%p, %p, %u.\n", iface, ranges, num_ranges);
+
+ return E_NOTIMPL;
+}
+
+static DWRITE_FONT_AXIS_ATTRIBUTES WINAPI dwritefontresource_GetFontAxisAttributes(IDWriteFontResource *iface,
+ UINT32 axis)
+{
+ FIXME("%p, %u.\n", iface, axis);
+
+ return DWRITE_FONT_AXIS_ATTRIBUTES_NONE;
+}
+
+static HRESULT WINAPI dwritefontresource_GetAxisNames(IDWriteFontResource *iface, UINT32 axis,
+ IDWriteLocalizedStrings **names)
+{
+ FIXME("%p, %u, %p.\n", iface, axis, names);
+
+ return E_NOTIMPL;
+}
+
+static UINT32 WINAPI dwritefontresource_GetAxisValueNameCount(IDWriteFontResource *iface, UINT32 axis)
+{
+ FIXME("%p, %u.\n", iface, axis);
+
+ return 0;
+}
+
+static HRESULT WINAPI dwritefontresource_GetAxisValueNames(IDWriteFontResource *iface, UINT32 axis,
+ UINT32 axis_value, DWRITE_FONT_AXIS_RANGE *axis_range, IDWriteLocalizedStrings **names)
+{
+ FIXME("%p, %u, %u, %p, %p.\n", iface, axis, axis_value, axis_range, names);
+
+ return E_NOTIMPL;
+}
+
+static BOOL WINAPI dwritefontresource_HasVariations(IDWriteFontResource *iface)
+{
+ FIXME("%p.\n", iface);
+
+ return FALSE;
+}
+
+static HRESULT WINAPI dwritefontresource_CreateFontFace(IDWriteFontResource *iface,
+ DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 num_values,
+ IDWriteFontFace5 **fontface)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+ IDWriteFontFaceReference1 *reference;
+ HRESULT hr;
+
+ TRACE("%p, %#x, %p, %u, %p.\n", iface, simulations, axis_values, num_values, fontface);
+
+ hr = IDWriteFactory7_CreateFontFaceReference(resource->factory, resource->file, resource->face_index,
+ simulations, axis_values, num_values, &reference);
+ if (SUCCEEDED(hr))
+ {
+ hr = IDWriteFontFaceReference1_CreateFontFace(reference, fontface);
+ IDWriteFontFaceReference1_Release(reference);
+ }
+
+ return hr;
+}
+
+static HRESULT WINAPI dwritefontresource_CreateFontFaceReference(IDWriteFontResource *iface,
+ DWRITE_FONT_SIMULATIONS simulations, DWRITE_FONT_AXIS_VALUE const *axis_values, UINT32 num_values,
+ IDWriteFontFaceReference1 **reference)
+{
+ struct dwrite_fontresource *resource = impl_from_IDWriteFontResource(iface);
+
+ TRACE("%p, %#x, %p, %u, %p.\n", iface, simulations, axis_values, num_values, reference);
+
+ return IDWriteFactory7_CreateFontFaceReference(resource->factory, resource->file, resource->face_index,
+ simulations, axis_values, num_values, reference);
+}
+
+static const IDWriteFontResourceVtbl fontresourcevtbl =
+{
+ dwritefontresource_QueryInterface,
+ dwritefontresource_AddRef,
+ dwritefontresource_Release,
+ dwritefontresource_GetFontFile,
+ dwritefontresource_GetFontFaceIndex,
+ dwritefontresource_GetFontAxisCount,
+ dwritefontresource_GetDefaultFontAxisValues,
+ dwritefontresource_GetFontAxisRanges,
+ dwritefontresource_GetFontAxisAttributes,
+ dwritefontresource_GetAxisNames,
+ dwritefontresource_GetAxisValueNameCount,
+ dwritefontresource_GetAxisValueNames,
+ dwritefontresource_HasVariations,
+ dwritefontresource_CreateFontFace,
+ dwritefontresource_CreateFontFaceReference,
+};
+
+HRESULT create_font_resource(IDWriteFactory7 *factory, IDWriteFontFile *file, UINT32 face_index,
+ IDWriteFontResource **ret)
+{
+ struct dwrite_fontresource *resource;
+
+ *ret = NULL;
+
+ resource = heap_alloc_zero(sizeof(*resource));
+ if (!resource)
+ return E_OUTOFMEMORY;
+
+ resource->IDWriteFontResource_iface.lpVtbl = &fontresourcevtbl;
+ resource->refcount = 1;
+ resource->face_index = face_index;
+ resource->file = file;
+ IDWriteFontFile_AddRef(resource->file);
+ resource->factory = factory;
+ IDWriteFactory7_AddRef(resource->factory);
+
+ *ret = &resource->IDWriteFontResource_iface;
+
+ return S_OK;
+}
diff --git a/dlls/dwrite/main.c b/dlls/dwrite/main.c
index 033a664dcf..1c1fabdb7d 100644
--- a/dlls/dwrite/main.c
+++ b/dlls/dwrite/main.c
@@ -1666,9 +1666,9 @@ static HRESULT WINAPI dwritefactory6_CreateFontFaceReference(IDWriteFactory7 *if
static HRESULT WINAPI dwritefactory6_CreateFontResource(IDWriteFactory7 *iface, IDWriteFontFile *file,
UINT32 face_index, IDWriteFontResource **resource)
{
- FIXME("%p, %p, %u, %p.\n", iface, file, face_index, resource);
+ TRACE("%p, %p, %u, %p.\n", iface, file, face_index, resource);
- return E_NOTIMPL;
+ return create_font_resource(iface, file, face_index, resource);
}
static HRESULT WINAPI dwritefactory6_GetSystemFontSet(IDWriteFactory7 *iface, BOOL include_downloadable,
diff --git a/dlls/dwrite/tests/font.c b/dlls/dwrite/tests/font.c
index 58f2af6e7a..f0266cb751 100644
--- a/dlls/dwrite/tests/font.c
+++ b/dlls/dwrite/tests/font.c
@@ -9259,17 +9259,8 @@ static void test_font_resource(void)
ok(hr == S_OK, "Failed to get file object, hr %#x.\n", hr);
hr = IDWriteFactory6_CreateFontResource(factory, fontfile, 0, &resource);
-todo_wine
ok(hr == S_OK, "Failed to create font resource, hr %#x.\n", hr);
- if (FAILED(hr))
- {
- IDWriteFactory6_Release(factory);
- IDWriteFontFile_Release(fontfile);
- IDWriteFontFace_Release(fontface);
- return;
- }
-
hr = IDWriteFactory6_CreateFontResource(factory, fontfile, 0, &resource2);
ok(hr == S_OK, "Failed to create font resource, hr %#x.\n", hr);
ok(resource != resource2, "Unexpected instance.\n");
@@ -9283,18 +9274,29 @@ todo_wine
index = IDWriteFontResource_GetFontFaceIndex(resource);
ok(!index, "Unexpected index %u.\n", index);
+ 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);
+todo_wine
ok(hr == S_OK, "Failed to get interface, hr %#x.\n", hr);
+ if (FAILED(hr))
+ return;
+
hr = IDWriteFontFace5_GetFontResource(fontface5, &resource2);
ok(hr == S_OK, "Failed to get font resource, hr %#x.\n", hr);
ok(resource != resource2, "Unexpected resource instance.\n");
--
2.24.0
Dec. 5, 2019
mscoree: fix an error in string access
by Rafał Mużyło
mscoree: fix an error in string access
If parsed_config.private_path is an empty string, wine is doing a Bad
Thing. It shouldn't.
Signed-off-by: Rafał Mużyło <galtgendo(a)o2.pl>
Dec. 5, 2019
[PATCH 4/4] strmbase: Get rid of the "vtbl" parameter to strmbase_filter_init().
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/audiorecord.c | 20 +-----------
dlls/qcap/avico.c | 20 +-----------
dlls/qcap/avimux.c | 20 +-----------
dlls/qcap/smartteefilter.c | 20 +-----------
dlls/qcap/vfwcapture.c | 21 +-----------
dlls/qedit/samplegrabber.c | 21 +-----------
dlls/quartz/dsoundrender.c | 12 +++----
dlls/quartz/filesource.c | 21 +-----------
dlls/quartz/tests/videorenderer.c | 21 +-----------
dlls/quartz/tests/vmr7.c | 21 +-----------
dlls/quartz/tests/vmr9.c | 21 +-----------
dlls/strmbase/filter.c | 53 +++++++++++++++++++++----------
dlls/strmbase/renderer.c | 21 +-----------
dlls/strmbase/transform.c | 22 +------------
dlls/winegstreamer/gstdemux.c | 27 +++-------------
dlls/wineqtdecoder/qtsplitter.c | 20 +-----------
include/wine/strmbase.h | 18 +----------
17 files changed, 60 insertions(+), 319 deletions(-)
diff --git a/dlls/qcap/audiorecord.c b/dlls/qcap/audiorecord.c
index 0262bc5bd8f..3c15734e894 100644
--- a/dlls/qcap/audiorecord.c
+++ b/dlls/qcap/audiorecord.c
@@ -49,24 +49,6 @@ static inline AudioRecord *impl_from_IPersistPropertyBag(IPersistPropertyBag *if
return CONTAINING_RECORD(iface, AudioRecord, IPersistPropertyBag_iface);
}
-static const IBaseFilterVtbl AudioRecordVtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static struct strmbase_pin *audio_record_get_pin(struct strmbase_filter *iface, unsigned int index)
{
FIXME("iface %p, index %u, stub!\n", iface, index);
@@ -186,7 +168,7 @@ IUnknown* WINAPI QCAP_createAudioCaptureFilter(IUnknown *outer, HRESULT *phr)
memset(This, 0, sizeof(*This));
This->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
- strmbase_filter_init(&This->filter, &AudioRecordVtbl, outer, &CLSID_AudioRecord, &filter_ops);
+ strmbase_filter_init(&This->filter, outer, &CLSID_AudioRecord, &filter_ops);
*phr = S_OK;
return &This->filter.IUnknown_inner;
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c
index f65f33fe442..9365c437b4f 100644
--- a/dlls/qcap/avico.c
+++ b/dlls/qcap/avico.c
@@ -111,24 +111,6 @@ static HRESULT fill_format_info(AVICompressor *This, VIDEOINFOHEADER *src_videoi
return S_OK;
}
-static const IBaseFilterVtbl AVICompressorVtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo,
-};
-
static struct strmbase_pin *avi_compressor_get_pin(struct strmbase_filter *iface, unsigned int index)
{
AVICompressor *filter = impl_from_strmbase_filter(iface);
@@ -576,7 +558,7 @@ IUnknown* WINAPI QCAP_createAVICompressor(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&compressor->filter, &AVICompressorVtbl, outer, &CLSID_AVICo, &filter_ops);
+ strmbase_filter_init(&compressor->filter, outer, &CLSID_AVICo, &filter_ops);
compressor->IPersistPropertyBag_iface.lpVtbl = &PersistPropertyBagVtbl;
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index a7a9ac7ceda..dc28104c80a 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -672,24 +672,6 @@ static const struct strmbase_filter_ops filter_ops =
.filter_cleanup_stream = avi_mux_cleanup_stream,
};
-static const IBaseFilterVtbl AviMuxVtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static inline AviMux* impl_from_IConfigAviMux(IConfigAviMux *iface)
{
return CONTAINING_RECORD(iface, AviMux, IConfigAviMux_iface);
@@ -1964,7 +1946,7 @@ IUnknown * WINAPI QCAP_createAVIMux(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&avimux->filter, &AviMuxVtbl, outer, &CLSID_AviDest, &filter_ops);
+ strmbase_filter_init(&avimux->filter, outer, &CLSID_AviDest, &filter_ops);
avimux->IConfigAviMux_iface.lpVtbl = &ConfigAviMuxVtbl;
avimux->IConfigInterleaving_iface.lpVtbl = &ConfigInterleavingVtbl;
avimux->IMediaSeeking_iface.lpVtbl = &MediaSeekingVtbl;
diff --git a/dlls/qcap/smartteefilter.c b/dlls/qcap/smartteefilter.c
index f63a43de50c..7762ec1e500 100644
--- a/dlls/qcap/smartteefilter.c
+++ b/dlls/qcap/smartteefilter.c
@@ -51,24 +51,6 @@ static inline SmartTeeFilter *impl_from_strmbase_pin(struct strmbase_pin *pin)
return impl_from_strmbase_filter(pin->filter);
}
-static const IBaseFilterVtbl SmartTeeFilterVtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static struct strmbase_pin *smart_tee_get_pin(struct strmbase_filter *iface, unsigned int index)
{
SmartTeeFilter *filter = impl_from_strmbase_filter(iface);
@@ -417,7 +399,7 @@ IUnknown* WINAPI QCAP_createSmartTeeFilter(IUnknown *outer, HRESULT *phr)
}
memset(object, 0, sizeof(*object));
- strmbase_filter_init(&object->filter, &SmartTeeFilterVtbl, outer, &CLSID_SmartTee, &filter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_SmartTee, &filter_ops);
strmbase_sink_init(&object->sink, &SmartTeeFilterInputVtbl, &object->filter, inputW, &sink_ops, NULL);
hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER,
&IID_IMemAllocator, (void **)&object->sink.pAllocator);
diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c
index 0f8beb0f495..e7522ea9b36 100644
--- a/dlls/qcap/vfwcapture.c
+++ b/dlls/qcap/vfwcapture.c
@@ -167,25 +167,6 @@ static const struct strmbase_filter_ops filter_ops =
.filter_cleanup_stream = vfw_capture_cleanup_stream,
};
-static const IBaseFilterVtbl VfwCapture_Vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
/* AMStreamConfig interface, we only need to implement {G,S}etFormat */
static HRESULT WINAPI AMStreamConfig_QueryInterface(IAMStreamConfig *iface, REFIID iid, void **out)
{
@@ -611,7 +592,7 @@ IUnknown * WINAPI QCAP_createVFWCaptureFilter(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&object->filter, &VfwCapture_Vtbl, outer, &CLSID_VfwCapture, &filter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_VfwCapture, &filter_ops);
object->IAMStreamConfig_iface.lpVtbl = &IAMStreamConfig_VTable;
object->IAMVideoProcAmp_iface.lpVtbl = &IAMVideoProcAmp_VTable;
diff --git a/dlls/qedit/samplegrabber.c b/dlls/qedit/samplegrabber.c
index af05966c140..019af5c35de 100644
--- a/dlls/qedit/samplegrabber.c
+++ b/dlls/qedit/samplegrabber.c
@@ -489,25 +489,6 @@ SampleGrabber_In_IPin_ReceiveConnection(IPin *iface, IPin *connector, const AM_M
return S_OK;
}
-static const IBaseFilterVtbl IBaseFilter_VTable =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo,
-};
-
static const ISampleGrabberVtbl ISampleGrabber_VTable =
{
SampleGrabber_ISampleGrabber_QueryInterface,
@@ -714,7 +695,7 @@ HRESULT SampleGrabber_create(IUnknown *outer, void **out)
}
ZeroMemory(obj, sizeof(SG_Impl));
- strmbase_filter_init(&obj->filter, &IBaseFilter_VTable, outer, &CLSID_SampleGrabber, &filter_ops);
+ strmbase_filter_init(&obj->filter, outer, &CLSID_SampleGrabber, &filter_ops);
obj->ISampleGrabber_iface.lpVtbl = &ISampleGrabber_VTable;
obj->IMemInputPin_iface.lpVtbl = &IMemInputPin_VTable;
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c
index a2c7ca94a62..cad210a8762 100644
--- a/dlls/quartz/dsoundrender.c
+++ b/dlls/quartz/dsoundrender.c
@@ -555,7 +555,7 @@ static HRESULT WINAPI Basicaudio_QueryInterface(IBasicAudio *iface,
TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj);
- return BaseFilterImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
+ return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppvObj);
}
static ULONG WINAPI Basicaudio_AddRef(IBasicAudio *iface) {
@@ -563,7 +563,7 @@ static ULONG WINAPI Basicaudio_AddRef(IBasicAudio *iface) {
TRACE("(%p/%p)->()\n", This, iface);
- return BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
+ return IUnknown_AddRef(This->renderer.filter.outer_unk);
}
static ULONG WINAPI Basicaudio_Release(IBasicAudio *iface) {
@@ -571,7 +571,7 @@ static ULONG WINAPI Basicaudio_Release(IBasicAudio *iface) {
TRACE("(%p/%p)->()\n", This, iface);
- return BaseFilterImpl_Release(&This->renderer.filter.IBaseFilter_iface);
+ return IUnknown_Release(This->renderer.filter.outer_unk);
}
HRESULT WINAPI basic_audio_GetTypeInfoCount(IBasicAudio *iface, UINT *count)
@@ -708,7 +708,7 @@ static HRESULT WINAPI AMDirectSound_QueryInterface(IAMDirectSound *iface,
TRACE("(%p/%p)->(%s, %p)\n", This, iface, debugstr_guid(riid), ppvObj);
- return BaseFilterImpl_QueryInterface(&This->renderer.filter.IBaseFilter_iface, riid, ppvObj);
+ return IUnknown_QueryInterface(This->renderer.filter.outer_unk, riid, ppvObj);
}
static ULONG WINAPI AMDirectSound_AddRef(IAMDirectSound *iface)
@@ -717,7 +717,7 @@ static ULONG WINAPI AMDirectSound_AddRef(IAMDirectSound *iface)
TRACE("(%p/%p)->()\n", This, iface);
- return BaseFilterImpl_AddRef(&This->renderer.filter.IBaseFilter_iface);
+ return IUnknown_AddRef(This->renderer.filter.outer_unk);
}
static ULONG WINAPI AMDirectSound_Release(IAMDirectSound *iface)
@@ -726,7 +726,7 @@ static ULONG WINAPI AMDirectSound_Release(IAMDirectSound *iface)
TRACE("(%p/%p)->()\n", This, iface);
- return BaseFilterImpl_Release(&This->renderer.filter.IBaseFilter_iface);
+ return IUnknown_Release(This->renderer.filter.outer_unk);
}
/*** IAMDirectSound methods ***/
diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c
index 1c17980f58c..e0d45730aec 100644
--- a/dlls/quartz/filesource.c
+++ b/dlls/quartz/filesource.c
@@ -412,7 +412,7 @@ HRESULT AsyncReader_create(IUnknown *outer, void **out)
if (!pAsyncRead)
return E_OUTOFMEMORY;
- strmbase_filter_init(&pAsyncRead->filter, &AsyncReader_Vtbl, outer, &CLSID_AsyncReader, &filter_ops);
+ strmbase_filter_init(&pAsyncRead->filter, outer, &CLSID_AsyncReader, &filter_ops);
pAsyncRead->IFileSourceFilter_iface.lpVtbl = &FileSource_Vtbl;
@@ -428,25 +428,6 @@ HRESULT AsyncReader_create(IUnknown *outer, void **out)
return S_OK;
}
-static const IBaseFilterVtbl AsyncReader_Vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static HRESULT WINAPI FileSource_QueryInterface(IFileSourceFilter * iface, REFIID riid, LPVOID * ppv)
{
AsyncReader *This = impl_from_IFileSourceFilter(iface);
diff --git a/dlls/quartz/tests/videorenderer.c b/dlls/quartz/tests/videorenderer.c
index d3810598682..6f9e47b9dc4 100644
--- a/dlls/quartz/tests/videorenderer.c
+++ b/dlls/quartz/tests/videorenderer.c
@@ -495,25 +495,6 @@ struct testfilter
struct strmbase_source source;
};
-static const IBaseFilterVtbl testfilter_vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo,
-};
-
static inline struct testfilter *impl_from_BaseFilter(struct strmbase_filter *iface)
{
return CONTAINING_RECORD(iface, struct testfilter, filter);
@@ -597,7 +578,7 @@ static const struct strmbase_source_ops testsource_ops =
static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
- strmbase_filter_init(&filter->filter, &testfilter_vtbl, NULL, &clsid, &testfilter_ops);
+ strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
}
diff --git a/dlls/quartz/tests/vmr7.c b/dlls/quartz/tests/vmr7.c
index 01d9ad10fa4..b8fd3f53cef 100644
--- a/dlls/quartz/tests/vmr7.c
+++ b/dlls/quartz/tests/vmr7.c
@@ -855,25 +855,6 @@ struct testfilter
struct strmbase_source source;
};
-static const IBaseFilterVtbl testfilter_vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo,
-};
-
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
{
return CONTAINING_RECORD(iface, struct testfilter, filter);
@@ -957,7 +938,7 @@ static const struct strmbase_source_ops testsource_ops =
static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
- strmbase_filter_init(&filter->filter, &testfilter_vtbl, NULL, &clsid, &testfilter_ops);
+ strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
}
diff --git a/dlls/quartz/tests/vmr9.c b/dlls/quartz/tests/vmr9.c
index 9379fa11e48..18971495753 100644
--- a/dlls/quartz/tests/vmr9.c
+++ b/dlls/quartz/tests/vmr9.c
@@ -859,25 +859,6 @@ struct testfilter
struct strmbase_source source;
};
-static const IBaseFilterVtbl testfilter_vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo,
-};
-
static inline struct testfilter *impl_from_strmbase_filter(struct strmbase_filter *iface)
{
return CONTAINING_RECORD(iface, struct testfilter, filter);
@@ -961,7 +942,7 @@ static const struct strmbase_source_ops testsource_ops =
static void testfilter_init(struct testfilter *filter)
{
static const GUID clsid = {0xabacab};
- strmbase_filter_init(&filter->filter, &testfilter_vtbl, NULL, &clsid, &testfilter_ops);
+ strmbase_filter_init(&filter->filter, NULL, &clsid, &testfilter_ops);
strmbase_source_init(&filter->source, &testsource_vtbl, &filter->filter, L"", &testsource_ops);
}
diff --git a/dlls/strmbase/filter.c b/dlls/strmbase/filter.c
index f90f760a49e..53307884c4d 100644
--- a/dlls/strmbase/filter.c
+++ b/dlls/strmbase/filter.c
@@ -271,25 +271,25 @@ static inline struct strmbase_filter *impl_from_IBaseFilter(IBaseFilter *iface)
return CONTAINING_RECORD(iface, struct strmbase_filter, IBaseFilter_iface);
}
-HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter *iface, REFIID iid, void **out)
+static HRESULT WINAPI filter_QueryInterface(IBaseFilter *iface, REFIID iid, void **out)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
return IUnknown_QueryInterface(filter->outer_unk, iid, out);
}
-ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter *iface)
+static ULONG WINAPI filter_AddRef(IBaseFilter *iface)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
return IUnknown_AddRef(filter->outer_unk);
}
-ULONG WINAPI BaseFilterImpl_Release(IBaseFilter *iface)
+static ULONG WINAPI filter_Release(IBaseFilter *iface)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
return IUnknown_Release(filter->outer_unk);
}
-HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid)
+static HRESULT WINAPI filter_GetClassID(IBaseFilter * iface, CLSID * pClsid)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
TRACE("(%p)->(%p)\n", This, pClsid);
@@ -299,7 +299,7 @@ HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid)
return S_OK;
}
-HRESULT WINAPI BaseFilterImpl_Stop(IBaseFilter *iface)
+static HRESULT WINAPI filter_Stop(IBaseFilter *iface)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
HRESULT hr = S_OK;
@@ -320,7 +320,7 @@ HRESULT WINAPI BaseFilterImpl_Stop(IBaseFilter *iface)
return hr;
}
-HRESULT WINAPI BaseFilterImpl_Pause(IBaseFilter *iface)
+static HRESULT WINAPI filter_Pause(IBaseFilter *iface)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
HRESULT hr = S_OK;
@@ -341,7 +341,7 @@ HRESULT WINAPI BaseFilterImpl_Pause(IBaseFilter *iface)
return hr;
}
-HRESULT WINAPI BaseFilterImpl_Run(IBaseFilter *iface, REFERENCE_TIME start)
+static HRESULT WINAPI filter_Run(IBaseFilter *iface, REFERENCE_TIME start)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
HRESULT hr = S_OK;
@@ -362,7 +362,7 @@ HRESULT WINAPI BaseFilterImpl_Run(IBaseFilter *iface, REFERENCE_TIME start)
return hr;
}
-HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter *iface, DWORD timeout, FILTER_STATE *state)
+static HRESULT WINAPI filter_GetState(IBaseFilter *iface, DWORD timeout, FILTER_STATE *state)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
HRESULT hr = S_OK;
@@ -380,7 +380,7 @@ HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter *iface, DWORD timeout, FILTER
return hr;
}
-HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
+static HRESULT WINAPI filter_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
TRACE("(%p)->(%p)\n", This, pClock);
@@ -398,7 +398,7 @@ HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock
return S_OK;
}
-HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock)
+static HRESULT WINAPI filter_GetSyncSource(IBaseFilter *iface, IReferenceClock **ppClock)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
TRACE("(%p)->(%p)\n", This, ppClock);
@@ -414,7 +414,7 @@ HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock
return S_OK;
}
-HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter *iface, IEnumPins **enum_pins)
+static HRESULT WINAPI filter_EnumPins(IBaseFilter *iface, IEnumPins **enum_pins)
{
struct strmbase_filter *filter = impl_from_IBaseFilter(iface);
@@ -423,7 +423,7 @@ HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter *iface, IEnumPins **enum_pins
return enum_pins_create(filter, enum_pins);
}
-HRESULT WINAPI BaseFilterImpl_FindPin(IBaseFilter *iface, const WCHAR *id, IPin **ret)
+static HRESULT WINAPI filter_FindPin(IBaseFilter *iface, const WCHAR *id, IPin **ret)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
struct strmbase_pin *pin;
@@ -443,7 +443,7 @@ HRESULT WINAPI BaseFilterImpl_FindPin(IBaseFilter *iface, const WCHAR *id, IPin
return VFW_E_NOT_FOUND;
}
-HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo)
+static HRESULT WINAPI filter_QueryFilterInfo(IBaseFilter *iface, FILTER_INFO *pInfo)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
TRACE("(%p)->(%p)\n", This, pInfo);
@@ -457,7 +457,7 @@ HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *
return S_OK;
}
-HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName )
+static HRESULT WINAPI filter_JoinFilterGraph(IBaseFilter *iface, IFilterGraph *pGraph, const WCHAR *pName)
{
struct strmbase_filter *This = impl_from_IBaseFilter(iface);
@@ -476,23 +476,42 @@ HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph
return S_OK;
}
-HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo)
+static HRESULT WINAPI filter_QueryVendorInfo(IBaseFilter *iface, WCHAR **pVendorInfo)
{
TRACE("(%p)->(%p)\n", iface, pVendorInfo);
return E_NOTIMPL;
}
+static const IBaseFilterVtbl filter_vtbl =
+{
+ filter_QueryInterface,
+ filter_AddRef,
+ filter_Release,
+ filter_GetClassID,
+ filter_Stop,
+ filter_Pause,
+ filter_Run,
+ filter_GetState,
+ filter_SetSyncSource,
+ filter_GetSyncSource,
+ filter_EnumPins,
+ filter_FindPin,
+ filter_QueryFilterInfo,
+ filter_JoinFilterGraph,
+ filter_QueryVendorInfo,
+};
+
VOID WINAPI BaseFilterImpl_IncrementPinVersion(struct strmbase_filter *filter)
{
InterlockedIncrement(&filter->pin_version);
}
-void strmbase_filter_init(struct strmbase_filter *filter, const IBaseFilterVtbl *vtbl, IUnknown *outer,
+void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer,
const CLSID *clsid, const struct strmbase_filter_ops *ops)
{
memset(filter, 0, sizeof(*filter));
- filter->IBaseFilter_iface.lpVtbl = vtbl;
+ filter->IBaseFilter_iface.lpVtbl = &filter_vtbl;
filter->IUnknown_inner.lpVtbl = &filter_inner_vtbl;
filter->outer_unk = outer ? outer : &filter->IUnknown_inner;
filter->refcount = 1;
diff --git a/dlls/strmbase/renderer.c b/dlls/strmbase/renderer.c
index cacbb90e591..d592ab034e6 100644
--- a/dlls/strmbase/renderer.c
+++ b/dlls/strmbase/renderer.c
@@ -448,25 +448,6 @@ HRESULT WINAPI BaseRendererImpl_Receive(struct strmbase_renderer *This, IMediaSa
return hr;
}
-static const IBaseFilterVtbl strmbase_renderer_vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
HRESULT WINAPI BaseRendererImpl_ClearPendingSample(struct strmbase_renderer *iface)
{
if (iface->pMediaSample)
@@ -483,7 +464,7 @@ HRESULT WINAPI strmbase_renderer_init(struct strmbase_renderer *filter, IUnknown
HRESULT hr;
memset(filter, 0, sizeof(*filter));
- strmbase_filter_init(&filter->filter, &strmbase_renderer_vtbl, outer, clsid, &filter_ops);
+ strmbase_filter_init(&filter->filter, outer, clsid, &filter_ops);
filter->pFuncsTable = ops;
diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index 9e2582a0dbf..5c079d38e76 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -246,26 +246,6 @@ static const struct strmbase_source_ops source_ops =
.pfnDecideAllocator = BaseOutputPinImpl_DecideAllocator,
};
-
-static const IBaseFilterVtbl transform_vtbl =
-{
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static TransformFilter *impl_from_source_IQualityControl(IQualityControl *iface)
{
return CONTAINING_RECORD(iface, TransformFilter, source_IQualityControl_iface);
@@ -346,7 +326,7 @@ static HRESULT strmbase_transform_init(IUnknown *outer, const CLSID *clsid,
ISeekingPassThru *passthru;
HRESULT hr;
- strmbase_filter_init(&filter->filter, &transform_vtbl, outer, clsid, &filter_ops);
+ strmbase_filter_init(&filter->filter, outer, clsid, &filter_ops);
InitializeCriticalSection(&filter->csReceive);
filter->csReceive.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": TransformFilter.csReceive");
diff --git a/dlls/winegstreamer/gstdemux.c b/dlls/winegstreamer/gstdemux.c
index e024d271974..78c8e38701a 100644
--- a/dlls/winegstreamer/gstdemux.c
+++ b/dlls/winegstreamer/gstdemux.c
@@ -99,7 +99,6 @@ static const WCHAR wcsInputPinName[] = {'i','n','p','u','t',' ','p','i','n',0};
static const IMediaSeekingVtbl GST_Seeking_Vtbl;
static const IPinVtbl GST_OutputPin_Vtbl;
static const IPinVtbl GST_InputPin_Vtbl;
-static const IBaseFilterVtbl GST_Vtbl;
static const IQualityControlVtbl GSTOutPin_QualityControl_Vtbl;
static struct gstdemux_source *create_pin(struct gstdemux *filter, const WCHAR *name);
@@ -1438,7 +1437,7 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&object->filter, &GST_Vtbl, outer, &CLSID_Gstreamer_Splitter, &filter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_Gstreamer_Splitter, &filter_ops);
object->no_more_pads_event = CreateEventW(NULL, FALSE, FALSE, NULL);
object->sink.dir = PINDIR_INPUT;
@@ -1453,24 +1452,6 @@ IUnknown * CALLBACK Gstreamer_Splitter_create(IUnknown *outer, HRESULT *phr)
return &object->filter.IUnknown_inner;
}
-static const IBaseFilterVtbl GST_Vtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static struct gstdemux *impl_from_IAMStreamSelect(IAMStreamSelect *iface)
{
return CONTAINING_RECORD(iface, struct gstdemux, IAMStreamSelect_iface);
@@ -2383,7 +2364,7 @@ IUnknown * CALLBACK wave_parser_create(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&object->filter, &GST_Vtbl, outer, &CLSID_WAVEParser, &filter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_WAVEParser, &filter_ops);
object->sink.dir = PINDIR_INPUT;
object->sink.filter = &object->filter;
@@ -2489,7 +2470,7 @@ IUnknown * CALLBACK avi_splitter_create(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&object->filter, &GST_Vtbl, outer, &CLSID_AviSplitter, &filter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_AviSplitter, &filter_ops);
object->no_more_pads_event = CreateEventW(NULL, FALSE, FALSE, NULL);
object->sink.dir = PINDIR_INPUT;
@@ -2627,7 +2608,7 @@ IUnknown * CALLBACK mpeg_splitter_create(IUnknown *outer, HRESULT *phr)
return NULL;
}
- strmbase_filter_init(&object->filter, &GST_Vtbl, outer, &CLSID_MPEG1Splitter, &mpeg_splitter_ops);
+ strmbase_filter_init(&object->filter, outer, &CLSID_MPEG1Splitter, &mpeg_splitter_ops);
object->IAMStreamSelect_iface.lpVtbl = &stream_select_vtbl;
object->duration_event = CreateEventW(NULL, FALSE, FALSE, NULL);
diff --git a/dlls/wineqtdecoder/qtsplitter.c b/dlls/wineqtdecoder/qtsplitter.c
index 28ea36785a8..5b1e82ebc9b 100644
--- a/dlls/wineqtdecoder/qtsplitter.c
+++ b/dlls/wineqtdecoder/qtsplitter.c
@@ -357,7 +357,7 @@ IUnknown * CALLBACK QTSplitter_create(IUnknown *outer, HRESULT *phr)
}
ZeroMemory(This,sizeof(*This));
- strmbase_filter_init(&This->filter, &QT_Vtbl, outer, &CLSID_QTSplitter, &filter_ops);
+ strmbase_filter_init(&This->filter, outer, &CLSID_QTSplitter, &filter_ops);
InitializeCriticalSection(&This->csReceive);
This->csReceive.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__": QTSplitter.csReceive");
@@ -721,24 +721,6 @@ audio_error:
return hr;
}
-static const IBaseFilterVtbl QT_Vtbl = {
- BaseFilterImpl_QueryInterface,
- BaseFilterImpl_AddRef,
- BaseFilterImpl_Release,
- BaseFilterImpl_GetClassID,
- BaseFilterImpl_Stop,
- BaseFilterImpl_Pause,
- BaseFilterImpl_Run,
- BaseFilterImpl_GetState,
- BaseFilterImpl_SetSyncSource,
- BaseFilterImpl_GetSyncSource,
- BaseFilterImpl_EnumPins,
- BaseFilterImpl_FindPin,
- BaseFilterImpl_QueryFilterInfo,
- BaseFilterImpl_JoinFilterGraph,
- BaseFilterImpl_QueryVendorInfo
-};
-
static void free_source_pin(QTOutPin *pin)
{
if (pin->pin.pin.peer)
diff --git a/include/wine/strmbase.h b/include/wine/strmbase.h
index 7949e6670a5..75eac504209 100644
--- a/include/wine/strmbase.h
+++ b/include/wine/strmbase.h
@@ -176,25 +176,9 @@ struct strmbase_filter_ops
HRESULT (*filter_wait_state)(struct strmbase_filter *iface, DWORD timeout);
};
-HRESULT WINAPI BaseFilterImpl_QueryInterface(IBaseFilter * iface, REFIID riid, LPVOID * ppv);
-ULONG WINAPI BaseFilterImpl_AddRef(IBaseFilter * iface);
-ULONG WINAPI BaseFilterImpl_Release(IBaseFilter * iface);
-HRESULT WINAPI BaseFilterImpl_Stop(IBaseFilter *iface);
-HRESULT WINAPI BaseFilterImpl_Pause(IBaseFilter *iface);
-HRESULT WINAPI BaseFilterImpl_Run(IBaseFilter *iface, REFERENCE_TIME start);
-HRESULT WINAPI BaseFilterImpl_GetClassID(IBaseFilter * iface, CLSID * pClsid);
-HRESULT WINAPI BaseFilterImpl_GetState(IBaseFilter * iface, DWORD dwMilliSecsTimeout, FILTER_STATE *pState );
-HRESULT WINAPI BaseFilterImpl_SetSyncSource(IBaseFilter * iface, IReferenceClock *pClock);
-HRESULT WINAPI BaseFilterImpl_GetSyncSource(IBaseFilter * iface, IReferenceClock **ppClock);
-HRESULT WINAPI BaseFilterImpl_EnumPins(IBaseFilter * iface, IEnumPins **ppEnum);
-HRESULT WINAPI BaseFilterImpl_FindPin(IBaseFilter *iface, const WCHAR *id, IPin **pin);
-HRESULT WINAPI BaseFilterImpl_QueryFilterInfo(IBaseFilter * iface, FILTER_INFO *pInfo);
-HRESULT WINAPI BaseFilterImpl_JoinFilterGraph(IBaseFilter * iface, IFilterGraph *pGraph, LPCWSTR pName );
-HRESULT WINAPI BaseFilterImpl_QueryVendorInfo(IBaseFilter * iface, LPWSTR *pVendorInfo);
-
VOID WINAPI BaseFilterImpl_IncrementPinVersion(struct strmbase_filter *filter);
-void strmbase_filter_init(struct strmbase_filter *filter, const IBaseFilterVtbl *vtbl, IUnknown *outer,
+void strmbase_filter_init(struct strmbase_filter *filter, IUnknown *outer,
const CLSID *clsid, const struct strmbase_filter_ops *func_table);
void strmbase_filter_cleanup(struct strmbase_filter *filter);
--
2.23.0
Dec. 5, 2019
[PATCH 3/4] qcap: Rework v4l2 state change logic.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/capture.h | 7 +-
dlls/qcap/v4l.c | 166 +++++++++++++----------------------------
dlls/qcap/vfwcapture.c | 60 ++++++++-------
3 files changed, 89 insertions(+), 144 deletions(-)
diff --git a/dlls/qcap/capture.h b/dlls/qcap/capture.h
index 6433f37d88f..7d2be332488 100644
--- a/dlls/qcap/capture.h
+++ b/dlls/qcap/capture.h
@@ -31,8 +31,9 @@ HRESULT qcap_driver_get_format(const Capture *, AM_MEDIA_TYPE *) DECLSPEC_HIDDEN
HRESULT qcap_driver_get_prop_range(Capture*,VideoProcAmpProperty,LONG*,LONG*,LONG*,LONG*,LONG*) DECLSPEC_HIDDEN;
HRESULT qcap_driver_get_prop(Capture*,VideoProcAmpProperty,LONG*,LONG*) DECLSPEC_HIDDEN;
HRESULT qcap_driver_set_prop(Capture*,VideoProcAmpProperty,LONG,LONG) DECLSPEC_HIDDEN;
-HRESULT qcap_driver_run(Capture*,FILTER_STATE*) DECLSPEC_HIDDEN;
-HRESULT qcap_driver_pause(Capture*,FILTER_STATE*) DECLSPEC_HIDDEN;
-HRESULT qcap_driver_stop(Capture*,FILTER_STATE*) DECLSPEC_HIDDEN;
+void qcap_driver_init_stream(Capture *device) DECLSPEC_HIDDEN;
+void qcap_driver_start_stream(Capture *device) DECLSPEC_HIDDEN;
+void qcap_driver_stop_stream(Capture *device) DECLSPEC_HIDDEN;
+void qcap_driver_cleanup_stream(Capture *device) DECLSPEC_HIDDEN;
#endif /* __QCAP_CAPTURE_H__ */
diff --git a/dlls/qcap/v4l.c b/dlls/qcap/v4l.c
index a203e91e52b..75121fd8518 100644
--- a/dlls/qcap/v4l.c
+++ b/dlls/qcap/v4l.c
@@ -99,13 +99,11 @@ struct _Capture
UINT width, height, bitDepth, fps, outputwidth, outputheight;
BOOL swresize;
- CRITICAL_SECTION CritSect;
-
struct strmbase_source *pin;
int fd, mmap;
- BOOL iscommitted, stopped;
+ FILTER_STATE state;
- HANDLE thread;
+ HANDLE thread, run_event;
};
static int xioctl(int fd, int request, void * arg)
@@ -125,8 +123,6 @@ HRESULT qcap_driver_destroy(Capture *capBox)
if( capBox->fd != -1 )
video_close(capBox->fd);
- capBox->CritSect.DebugInfo->Spare[0] = 0;
- DeleteCriticalSection(&capBox->CritSect);
CoTaskMemFree(capBox);
return S_OK;
}
@@ -389,16 +385,14 @@ static DWORD WINAPI ReadThread(LPVOID lParam)
if (!(image_data = heap_alloc(image_size)))
{
ERR("Failed to allocate memory.\n");
- capBox->thread = 0;
- capBox->stopped = TRUE;
return 0;
}
- while (1)
+ while (capBox->state != State_Stopped)
{
- EnterCriticalSection(&capBox->CritSect);
- if (capBox->stopped)
- break;
+ if (capBox->state == State_Paused)
+ WaitForSingleObject(capBox->run_event, INFINITE);
+
hr = BaseOutputPinImpl_GetDeliveryBuffer(capBox->pin, &pSample, NULL, NULL, 0);
if (SUCCEEDED(hr))
{
@@ -432,124 +426,66 @@ static DWORD WINAPI ReadThread(LPVOID lParam)
if (FAILED(hr) && hr != VFW_E_NOT_CONNECTED)
{
TRACE("Return %x, stop IFilterGraph\n", hr);
- capBox->thread = 0;
- capBox->stopped = TRUE;
break;
}
- LeaveCriticalSection(&capBox->CritSect);
}
- LeaveCriticalSection(&capBox->CritSect);
heap_free(image_data);
return 0;
}
-HRESULT qcap_driver_run(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_init_stream(Capture *device)
{
- HANDLE thread;
+ ALLOCATOR_PROPERTIES req_props, ret_props;
HRESULT hr;
- TRACE("%p -> (%p)\n", capBox, state);
-
- if (*state == State_Running) return S_OK;
-
- EnterCriticalSection(&capBox->CritSect);
+ req_props.cBuffers = 3;
+ if (!device->swresize)
+ req_props.cbBuffer = device->width * device->height;
+ else
+ req_props.cbBuffer = device->outputwidth * device->outputheight;
+ req_props.cbBuffer = (req_props.cbBuffer * device->bitDepth) / 8;
+ req_props.cbAlign = 1;
+ req_props.cbPrefix = 0;
- capBox->stopped = FALSE;
+ hr = IMemAllocator_SetProperties(device->pin->pAllocator, &req_props, &ret_props);
+ if (FAILED(hr))
+ ERR("Failed to set allocator properties (buffer size %u), hr %#x.\n", req_props.cbBuffer, hr);
- if (*state == State_Stopped && capBox->pin->pin.peer)
+ if (SUCCEEDED(hr))
{
- *state = State_Running;
- if (!capBox->iscommitted)
- {
- ALLOCATOR_PROPERTIES ap, actual;
-
- capBox->iscommitted = TRUE;
-
- ap.cBuffers = 3;
- if (!capBox->swresize)
- ap.cbBuffer = capBox->width * capBox->height;
- else
- ap.cbBuffer = capBox->outputwidth * capBox->outputheight;
- ap.cbBuffer = (ap.cbBuffer * capBox->bitDepth) / 8;
- ap.cbAlign = 1;
- ap.cbPrefix = 0;
-
- hr = IMemAllocator_SetProperties(capBox->pin->pAllocator, &ap, &actual);
-
- if (SUCCEEDED(hr))
- hr = IMemAllocator_Commit(capBox->pin->pAllocator);
-
- TRACE("Committing allocator: %x\n", hr);
- }
-
- thread = CreateThread(NULL, 0, ReadThread, capBox, 0, NULL);
- if (thread)
- {
- capBox->thread = thread;
- SetThreadPriority(thread, THREAD_PRIORITY_LOWEST);
- LeaveCriticalSection(&capBox->CritSect);
- return S_OK;
- }
- ERR("Creating thread failed.. %u\n", GetLastError());
- LeaveCriticalSection(&capBox->CritSect);
- return E_FAIL;
+ if (FAILED(hr = IMemAllocator_Commit(device->pin->pAllocator)))
+ ERR("Failed to commit allocator, hr %#x.\n", hr);
}
- ResumeThread(capBox->thread);
- *state = State_Running;
- LeaveCriticalSection(&capBox->CritSect);
- return S_OK;
+ device->state = State_Paused;
+ device->thread = CreateThread(NULL, 0, ReadThread, device, 0, NULL);
}
-HRESULT qcap_driver_pause(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_start_stream(Capture *device)
{
- TRACE("%p -> (%p)\n", capBox, state);
-
- if (*state == State_Paused)
- return S_OK;
- if (*state == State_Stopped)
- qcap_driver_run(capBox, state);
-
- EnterCriticalSection(&capBox->CritSect);
- *state = State_Paused;
- SuspendThread(capBox->thread);
- LeaveCriticalSection(&capBox->CritSect);
-
- return S_OK;
+ device->state = State_Running;
+ SetEvent(device->run_event);
}
-HRESULT qcap_driver_stop(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_stop_stream(Capture *device)
{
- TRACE("%p -> (%p)\n", capBox, state);
-
- if (*state == State_Stopped)
- return S_OK;
-
- EnterCriticalSection(&capBox->CritSect);
-
- if (capBox->thread)
- {
- if (*state == State_Paused)
- ResumeThread(capBox->thread);
- capBox->stopped = TRUE;
- capBox->thread = 0;
- if (capBox->iscommitted)
- {
- HRESULT hr;
-
- capBox->iscommitted = FALSE;
-
- hr = IMemAllocator_Decommit(capBox->pin->pAllocator);
+ device->state = State_Paused;
+ ResetEvent(device->run_event);
+}
- if (hr != S_OK && hr != VFW_E_NOT_COMMITTED)
- WARN("Decommitting allocator: %x\n", hr);
- }
- }
+void qcap_driver_cleanup_stream(Capture *device)
+{
+ HRESULT hr;
- *state = State_Stopped;
- LeaveCriticalSection(&capBox->CritSect);
- return S_OK;
+ device->state = State_Stopped;
+ WaitForSingleObject(device->thread, INFINITE);
+ CloseHandle(device->thread);
+ device->thread = NULL;
+
+ hr = IMemAllocator_Decommit(device->pin->pAllocator);
+ if (hr != S_OK && hr != VFW_E_NOT_COMMITTED)
+ ERR("Failed to decommit allocator, hr %#x.\n", hr);
}
Capture *qcap_driver_init(struct strmbase_source *pin, USHORT card)
@@ -566,9 +502,6 @@ Capture *qcap_driver_init(struct strmbase_source *pin, USHORT card)
if (!(device = CoTaskMemAlloc(sizeof(*device))))
return NULL;
- InitializeCriticalSection(&device->CritSect);
- device->CritSect.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": Capture.CritSect");
-
sprintf(path, "/dev/video%i", card);
TRACE("Opening device %s.\n", path);
#ifdef O_CLOEXEC
@@ -635,8 +568,8 @@ Capture *qcap_driver_init(struct strmbase_source *pin, USHORT card)
device->bitDepth = 24;
device->pin = pin;
device->fps = 3;
- device->stopped = FALSE;
- device->iscommitted = FALSE;
+ device->state = State_Stopped;
+ device->run_event = CreateEventW(NULL, TRUE, FALSE, NULL);
TRACE("Format: %d bpp - %dx%d.\n", device->bitDepth, device->width, device->height);
@@ -701,17 +634,22 @@ HRESULT qcap_driver_set_prop(Capture *capBox, VideoProcAmpProperty Property,
FAIL_WITH_ERR;
}
-HRESULT qcap_driver_run(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_init_stream(Capture *device)
+{
+ FAIL_WITH_ERR;
+}
+
+void qcap_driver_start_stream(Capture *device)
{
FAIL_WITH_ERR;
}
-HRESULT qcap_driver_pause(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_stop_stream(Capture *device)
{
FAIL_WITH_ERR;
}
-HRESULT qcap_driver_stop(Capture *capBox, FILTER_STATE *state)
+void qcap_driver_cleanup_stream(Capture *device)
{
FAIL_WITH_ERR;
}
diff --git a/dlls/qcap/vfwcapture.c b/dlls/qcap/vfwcapture.c
index 2b60e542eba..0f8beb0f495 100644
--- a/dlls/qcap/vfwcapture.c
+++ b/dlls/qcap/vfwcapture.c
@@ -62,11 +62,6 @@ static inline VfwCapture *impl_from_strmbase_filter(struct strmbase_filter *ifac
return CONTAINING_RECORD(iface, VfwCapture, filter);
}
-static inline VfwCapture *impl_from_IBaseFilter(IBaseFilter *iface)
-{
- return CONTAINING_RECORD(iface, VfwCapture, filter.IBaseFilter_iface);
-}
-
static inline VfwCapture *impl_from_IAMStreamConfig(IAMStreamConfig *iface)
{
return CONTAINING_RECORD(iface, VfwCapture, IAMStreamConfig_iface);
@@ -99,7 +94,7 @@ static void vfw_capture_destroy(struct strmbase_filter *iface)
if (filter->init)
{
if (filter->filter.state != State_Stopped)
- qcap_driver_stop(filter->driver_info, &filter->filter.state);
+ qcap_driver_stop_stream(filter->driver_info);
qcap_driver_destroy(filter->driver_info);
}
@@ -129,47 +124,58 @@ static HRESULT vfw_capture_query_interface(struct strmbase_filter *iface, REFIID
return S_OK;
}
-static const struct strmbase_filter_ops filter_ops =
+static HRESULT vfw_capture_init_stream(struct strmbase_filter *iface)
{
- .filter_get_pin = vfw_capture_get_pin,
- .filter_destroy = vfw_capture_destroy,
- .filter_query_interface = vfw_capture_query_interface,
-};
+ VfwCapture *filter = impl_from_strmbase_filter(iface);
-/** IMediaFilter methods **/
+ qcap_driver_init_stream(filter->driver_info);
+ return VFW_S_CANT_CUE;
+}
-static HRESULT WINAPI VfwCapture_Stop(IBaseFilter * iface)
+static HRESULT vfw_capture_start_stream(struct strmbase_filter *iface, REFERENCE_TIME time)
{
- VfwCapture *This = impl_from_IBaseFilter(iface);
+ VfwCapture *filter = impl_from_strmbase_filter(iface);
- TRACE("()\n");
- return qcap_driver_stop(This->driver_info, &This->filter.state);
+ qcap_driver_start_stream(filter->driver_info);
+ return S_OK;
}
-static HRESULT WINAPI VfwCapture_Pause(IBaseFilter * iface)
+static HRESULT vfw_capture_stop_stream(struct strmbase_filter *iface)
{
- VfwCapture *This = impl_from_IBaseFilter(iface);
+ VfwCapture *filter = impl_from_strmbase_filter(iface);
- TRACE("()\n");
- return qcap_driver_pause(This->driver_info, &This->filter.state);
+ qcap_driver_stop_stream(filter->driver_info);
+ return VFW_S_CANT_CUE;
}
-static HRESULT WINAPI VfwCapture_Run(IBaseFilter * iface, REFERENCE_TIME tStart)
+static HRESULT vfw_capture_cleanup_stream(struct strmbase_filter *iface)
{
- VfwCapture *This = impl_from_IBaseFilter(iface);
- TRACE("(%s)\n", wine_dbgstr_longlong(tStart));
- return qcap_driver_run(This->driver_info, &This->filter.state);
+ VfwCapture *filter = impl_from_strmbase_filter(iface);
+
+ qcap_driver_cleanup_stream(filter->driver_info);
+ return S_OK;
}
+static const struct strmbase_filter_ops filter_ops =
+{
+ .filter_get_pin = vfw_capture_get_pin,
+ .filter_destroy = vfw_capture_destroy,
+ .filter_query_interface = vfw_capture_query_interface,
+ .filter_init_stream = vfw_capture_init_stream,
+ .filter_start_stream = vfw_capture_start_stream,
+ .filter_stop_stream = vfw_capture_stop_stream,
+ .filter_cleanup_stream = vfw_capture_cleanup_stream,
+};
+
static const IBaseFilterVtbl VfwCapture_Vtbl =
{
BaseFilterImpl_QueryInterface,
BaseFilterImpl_AddRef,
BaseFilterImpl_Release,
BaseFilterImpl_GetClassID,
- VfwCapture_Stop,
- VfwCapture_Pause,
- VfwCapture_Run,
+ BaseFilterImpl_Stop,
+ BaseFilterImpl_Pause,
+ BaseFilterImpl_Run,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
--
2.23.0
Dec. 5, 2019
[PATCH 2/4] qcap/avimux: Use strmbase filter state change methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avimux.c | 58 +++++++++++++---------------------------------
1 file changed, 16 insertions(+), 42 deletions(-)
diff --git a/dlls/qcap/avimux.c b/dlls/qcap/avimux.c
index 1995358ac2f..a7a9ac7ceda 100644
--- a/dlls/qcap/avimux.c
+++ b/dlls/qcap/avimux.c
@@ -167,19 +167,6 @@ static HRESULT avi_mux_query_interface(struct strmbase_filter *iface, REFIID iid
return S_OK;
}
-static const struct strmbase_filter_ops filter_ops =
-{
- .filter_get_pin = avi_mux_get_pin,
- .filter_destroy = avi_mux_destroy,
- .filter_query_interface = avi_mux_query_interface,
-};
-
-static inline AviMux* impl_from_IBaseFilter(IBaseFilter *iface)
-{
- struct strmbase_filter *filter = CONTAINING_RECORD(iface, struct strmbase_filter, IBaseFilter_iface);
- return impl_from_strmbase_filter(filter);
-}
-
static HRESULT out_flush(AviMux *This)
{
ULONG written;
@@ -420,17 +407,12 @@ static HRESULT queue_sample(AviMux *avimux, AviMuxIn *avimuxin, IMediaSample *sa
return flush_queue(avimux, avimuxin, FALSE);
}
-static HRESULT WINAPI AviMux_Stop(IBaseFilter *iface)
+static HRESULT avi_mux_cleanup_stream(struct strmbase_filter *iface)
{
- AviMux *This = impl_from_IBaseFilter(iface);
+ AviMux *This = impl_from_strmbase_filter(iface);
HRESULT hr;
int i;
- TRACE("(%p)\n", This);
-
- if(This->filter.state == State_Stopped)
- return S_OK;
-
if (This->stream)
{
AVIEXTHEADER dmlh;
@@ -559,36 +541,20 @@ static HRESULT WINAPI AviMux_Stop(IBaseFilter *iface)
This->stream = NULL;
}
- This->filter.state = State_Stopped;
return S_OK;
}
-static HRESULT WINAPI AviMux_Pause(IBaseFilter *iface)
+static HRESULT avi_mux_init_stream(struct strmbase_filter *iface)
{
- AviMux *This = impl_from_IBaseFilter(iface);
- FIXME("(%p)\n", This);
- return E_NOTIMPL;
-}
-
-static HRESULT WINAPI AviMux_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
-{
- AviMux *This = impl_from_IBaseFilter(iface);
+ AviMux *This = impl_from_strmbase_filter(iface);
HRESULT hr;
int i, stream_id;
- TRACE("(%p)->(%s)\n", This, wine_dbgstr_longlong(tStart));
-
- if(This->filter.state == State_Running)
- return S_OK;
-
if(This->mode != INTERLEAVE_FULL) {
FIXME("mode not supported (%d)\n", This->mode);
return E_NOTIMPL;
}
- if(tStart)
- FIXME("tStart parameter ignored\n");
-
for(i=0; i<This->input_pin_no; i++) {
IMediaSeeking *ms;
LONGLONG cur, stop;
@@ -694,18 +660,26 @@ static HRESULT WINAPI AviMux_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
This->avih.dwWidth = ((BITMAPINFOHEADER*)This->in[0]->strf->data)->biWidth;
This->avih.dwHeight = ((BITMAPINFOHEADER*)This->in[0]->strf->data)->biHeight;
- This->filter.state = State_Running;
return S_OK;
}
+static const struct strmbase_filter_ops filter_ops =
+{
+ .filter_get_pin = avi_mux_get_pin,
+ .filter_destroy = avi_mux_destroy,
+ .filter_query_interface = avi_mux_query_interface,
+ .filter_init_stream = avi_mux_init_stream,
+ .filter_cleanup_stream = avi_mux_cleanup_stream,
+};
+
static const IBaseFilterVtbl AviMuxVtbl = {
BaseFilterImpl_QueryInterface,
BaseFilterImpl_AddRef,
BaseFilterImpl_Release,
BaseFilterImpl_GetClassID,
- AviMux_Stop,
- AviMux_Pause,
- AviMux_Run,
+ BaseFilterImpl_Stop,
+ BaseFilterImpl_Pause,
+ BaseFilterImpl_Run,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
--
2.23.0
Dec. 5, 2019
[PATCH 1/4] qcap/avico: Use strmbase filter state change methods.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/qcap/avico.c | 81 +++++++++++++++--------------------------
dlls/qcap/tests/avico.c | 8 ++--
2 files changed, 33 insertions(+), 56 deletions(-)
diff --git a/dlls/qcap/avico.c b/dlls/qcap/avico.c
index f0f60ae4394..f65f33fe442 100644
--- a/dlls/qcap/avico.c
+++ b/dlls/qcap/avico.c
@@ -56,12 +56,6 @@ static inline AVICompressor *impl_from_strmbase_filter(struct strmbase_filter *f
return CONTAINING_RECORD(filter, AVICompressor, filter);
}
-static inline AVICompressor *impl_from_IBaseFilter(IBaseFilter *iface)
-{
- struct strmbase_filter *filter = CONTAINING_RECORD(iface, struct strmbase_filter, IBaseFilter_iface);
- return impl_from_strmbase_filter(filter);
-}
-
static inline AVICompressor *impl_from_strmbase_pin(struct strmbase_pin *pin)
{
return impl_from_strmbase_filter(pin->filter);
@@ -117,57 +111,14 @@ static HRESULT fill_format_info(AVICompressor *This, VIDEOINFOHEADER *src_videoi
return S_OK;
}
-static HRESULT WINAPI AVICompressor_Stop(IBaseFilter *iface)
-{
- AVICompressor *This = impl_from_IBaseFilter(iface);
-
- TRACE("(%p)\n", This);
-
- if(This->filter.state == State_Stopped)
- return S_OK;
-
- ICCompressEnd(This->hic);
- This->filter.state = State_Stopped;
- return S_OK;
-}
-
-static HRESULT WINAPI AVICompressor_Pause(IBaseFilter *iface)
-{
- AVICompressor *This = impl_from_IBaseFilter(iface);
- FIXME("(%p)\n", This);
- return E_NOTIMPL;
-}
-
-static HRESULT WINAPI AVICompressor_Run(IBaseFilter *iface, REFERENCE_TIME tStart)
-{
- AVICompressor *This = impl_from_IBaseFilter(iface);
- HRESULT hres;
-
- TRACE("(%p)->(%s)\n", This, wine_dbgstr_longlong(tStart));
-
- if(This->filter.state == State_Running)
- return S_OK;
-
- if (This->source.pAllocator && FAILED(hres = IMemAllocator_Commit(This->source.pAllocator)))
- {
- FIXME("Commit failed: %08x\n", hres);
- return hres;
- }
-
- This->frame_cnt = 0;
-
- This->filter.state = State_Running;
- return S_OK;
-}
-
static const IBaseFilterVtbl AVICompressorVtbl = {
BaseFilterImpl_QueryInterface,
BaseFilterImpl_AddRef,
BaseFilterImpl_Release,
BaseFilterImpl_GetClassID,
- AVICompressor_Stop,
- AVICompressor_Pause,
- AVICompressor_Run,
+ BaseFilterImpl_Stop,
+ BaseFilterImpl_Pause,
+ BaseFilterImpl_Run,
BaseFilterImpl_GetState,
BaseFilterImpl_SetSyncSource,
BaseFilterImpl_GetSyncSource,
@@ -215,11 +166,37 @@ static HRESULT avi_compressor_query_interface(struct strmbase_filter *iface, REF
return S_OK;
}
+static HRESULT avi_compressor_init_stream(struct strmbase_filter *iface)
+{
+ AVICompressor *filter = impl_from_strmbase_filter(iface);
+ HRESULT hr;
+
+ if (filter->source.pAllocator && FAILED(hr = IMemAllocator_Commit(filter->source.pAllocator)))
+ {
+ ERR("Failed to commit allocator, hr %#x.\n", hr);
+ return hr;
+ }
+
+ filter->frame_cnt = 0;
+
+ return S_OK;
+}
+
+static HRESULT avi_compressor_cleanup_stream(struct strmbase_filter *iface)
+{
+ AVICompressor *filter = impl_from_strmbase_filter(iface);
+
+ ICCompressEnd(filter->hic);
+ return S_OK;
+}
+
static const struct strmbase_filter_ops filter_ops =
{
.filter_get_pin = avi_compressor_get_pin,
.filter_destroy = avi_compressor_destroy,
.filter_query_interface = avi_compressor_query_interface,
+ .filter_init_stream = avi_compressor_init_stream,
+ .filter_cleanup_stream = avi_compressor_cleanup_stream,
};
static AVICompressor *impl_from_IPersistPropertyBag(IPersistPropertyBag *iface)
diff --git a/dlls/qcap/tests/avico.c b/dlls/qcap/tests/avico.c
index 5c6d4aa54f4..b4f52f10210 100644
--- a/dlls/qcap/tests/avico.c
+++ b/dlls/qcap/tests/avico.c
@@ -665,11 +665,11 @@ static void test_unconnected_filter_state(IBaseFilter *filter)
ok(state == State_Stopped, "Got state %u.\n", state);
hr = IBaseFilter_Pause(filter);
- todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IBaseFilter_GetState(filter, 0, &state);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(state == State_Paused, "Got state %u.\n", state);
+ ok(state == State_Paused, "Got state %u.\n", state);
hr = IBaseFilter_Run(filter, 0);
ok(hr == S_OK, "Got hr %#x.\n", hr);
@@ -679,11 +679,11 @@ static void test_unconnected_filter_state(IBaseFilter *filter)
ok(state == State_Running, "Got state %u.\n", state);
hr = IBaseFilter_Pause(filter);
- todo_wine ok(hr == S_OK, "Got hr %#x.\n", hr);
+ ok(hr == S_OK, "Got hr %#x.\n", hr);
hr = IBaseFilter_GetState(filter, 0, &state);
ok(hr == S_OK, "Got hr %#x.\n", hr);
- todo_wine ok(state == State_Paused, "Got state %u.\n", state);
+ ok(state == State_Paused, "Got state %u.\n", state);
hr = IBaseFilter_Stop(filter);
ok(hr == S_OK, "Got hr %#x.\n", hr);
--
2.23.0
Dec. 5, 2019
[PATCH v3 resend] odbccp32: Implement SQLConfigDataSource/W
by Alistair Leslie-Hughes
Signed-off-by: Alistair Leslie-Hughes <leslie_alistair(a)hotmail.com>
---
dlls/odbccp32/odbccp32.c | 121 +++++++++++++++++++++++++++++++--------
1 file changed, 97 insertions(+), 24 deletions(-)
diff --git a/dlls/odbccp32/odbccp32.c b/dlls/odbccp32/odbccp32.c
index a09d6571f3..c842872fa6 100644
--- a/dlls/odbccp32/odbccp32.c
+++ b/dlls/odbccp32/odbccp32.c
@@ -68,6 +68,9 @@ static const WCHAR odbc_error_load_lib_failed[] = {'L','o','a','d',' ','L','i','
static const WCHAR odbc_error_request_failed[] = {'R','e','q','u','e','s','t',' ','F','a','i','l','e','d',0};
static const WCHAR odbc_error_invalid_keyword[] = {'I','n','v','a','l','i','d',' ','k','e','y','w','o','r','d',' ','v','a','l','u','e',0};
+static BOOL (WINAPI *pConfigDSN)(HWND hwnd, WORD request, const char *driver, const char *attr);
+static BOOL (WINAPI *pConfigDSNW)(HWND hwnd, WORD request, const WCHAR *driver, const WCHAR *attr);
+
/* Push an error onto the error stack, taking care of ranges etc. */
static void push_error(int code, LPCWSTR msg)
{
@@ -219,30 +222,6 @@ static BOOL SQLInstall_narrow(int mode, LPSTR buffer, LPCWSTR str, WORD str_leng
return success;
}
-BOOL WINAPI SQLConfigDataSourceW(HWND hwndParent, WORD fRequest,
- LPCWSTR lpszDriver, LPCWSTR lpszAttributes)
-{
- LPCWSTR p;
-
- clear_errors();
- FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_w(lpszDriver),
- debugstr_w(lpszAttributes));
-
- for (p = lpszAttributes; *p; p += lstrlenW(p) + 1)
- FIXME("%s\n", debugstr_w(p));
-
- return TRUE;
-}
-
-BOOL WINAPI SQLConfigDataSource(HWND hwndParent, WORD fRequest,
- LPCSTR lpszDriver, LPCSTR lpszAttributes)
-{
- FIXME("%p %d %s %s\n", hwndParent, fRequest, debugstr_a(lpszDriver),
- debugstr_a(lpszAttributes));
- clear_errors();
- return TRUE;
-}
-
static HMODULE load_config_driver(const WCHAR *driver)
{
static WCHAR reg_driver[] = {'d','r','i','v','e','r',0};
@@ -359,6 +338,100 @@ fail:
return FALSE;
}
+BOOL WINAPI SQLConfigDataSourceW(HWND hwnd, WORD request, LPCWSTR driver, LPCWSTR attributes)
+{
+ HMODULE mod;
+ BOOL ret = FALSE;
+
+ TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_w(driver), debugstr_w(attributes));
+ if (TRACE_ON(odbc))
+ {
+ const WCHAR *p;
+ for (p = attributes; *p; p += lstrlenW(p) + 1)
+ TRACE("%s\n", debugstr_w(p));
+ }
+
+ clear_errors();
+
+ mod = load_config_driver(driver);
+ if (!mod)
+ return FALSE;
+
+ pConfigDSNW = (void*)GetProcAddress(mod, "ConfigDSNW");
+ if(pConfigDSNW)
+ ret = pConfigDSNW(hwnd, request, driver, attributes);
+ else
+ ERR("Failed to find ConfigDSNW\n");
+
+ if (!ret)
+ push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed);
+
+ FreeLibrary(mod);
+
+ return ret;
+}
+
+BOOL WINAPI SQLConfigDataSource(HWND hwnd, WORD request, LPCSTR driver, LPCSTR attributes)
+{
+ HMODULE mod;
+ BOOL ret = FALSE;
+ WCHAR *driverW;
+
+ TRACE("%p, %d, %s, %s\n", hwnd, request, debugstr_a(driver), debugstr_a(attributes));
+
+ if (TRACE_ON(odbc))
+ {
+ const char *p;
+ for (p = attributes; *p; p += lstrlenA(p) + 1)
+ TRACE("%s\n", debugstr_a(p));
+ }
+
+ clear_errors();
+
+ driverW = heap_strdupAtoW(driver);
+ if (!driverW)
+ {
+ push_error(ODBC_ERROR_OUT_OF_MEM, odbc_error_out_of_mem);
+ return FALSE;
+ }
+
+ mod = load_config_driver(driverW);
+ if (!mod)
+ {
+ heap_free(driverW);
+ return FALSE;
+ }
+
+ pConfigDSN = (void*)GetProcAddress(mod, "ConfigDSN");
+ if (pConfigDSN)
+ {
+ TRACE("Calling ConfigDSN\n");
+ ret = pConfigDSN(hwnd, request, driver, attributes);
+ }
+ else
+ {
+ pConfigDSNW = (void*)GetProcAddress(mod, "ConfigDSNW");
+ if (pConfigDSNW)
+ {
+ WCHAR *attr = NULL;
+ TRACE("Calling ConfigDSNW\n");
+
+ attr = SQLInstall_strdup_multi(attributes);
+ if(attr)
+ ret = pConfigDSNW(hwnd, request, driverW, attr);
+ heap_free(attr);
+ }
+ }
+
+ if (!ret)
+ push_error(ODBC_ERROR_REQUEST_FAILED, odbc_error_request_failed);
+
+ heap_free(driverW);
+ FreeLibrary(mod);
+
+ return ret;
+}
+
BOOL WINAPI SQLConfigDriverW(HWND hwnd, WORD request, LPCWSTR driver,
LPCWSTR args, LPWSTR msg, WORD msgmax, WORD *msgout)
{
--
2.17.1
Dec. 4, 2019
Re: [wine-devel] Wine staging 4.21 release
by Alan W. Irwin
On 2019-11-30 04:56-0000 Alistair Leslie-Hughes wrote:
> Binary packages for various distributions will be available from:
> https://www.winehq.org/download
>
> Summary since last release
> * Rebased to current wine 4.21 (833 patches are applied to wine vanilla)
>
> Upstreamed (Either directly from staging or fixed with a similar patch).
> * none
>
> 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)
>
> Updated:
> * d3d9-Direct3DShaderValidatorCreate9
> * winecfg-Staging
[...]
Hi Alistair:
Could you explain how these patch numbers in your report are related with each other?
For example, my initial assumption was the rebased patch number should
be equal to the corresponding number in the last report plus the added
patches in this report less the upstreamed patches in this report, i.e.,
r = r_old + a - u
where r and r_old are the current and last reported rebased patch numbers and a and u
are the current added and upstreamed patch numbers.
But looking at the last several reports that formula predicts
incorrect results with the rebased patch number changing in what looks
like a completely arbitrary way from report to report compared to the
prediction. So it appears the above formula is incorrect and/or
incomplete.
Could you let me know what the correct formula is for predicting the
rebased patch number from report to report (which helps to evaluate
the reliability of the staging patch number statistics that you
present), and if that formula depends on information (my guess is it
is the number of patches in staging that have just been deleted by the
staging maintainers because they judge those patches to not be
worthwhile) that you currently do not include in your reports, could
you include that important information in your following reports?
TIA.
Alan
__________________________
Alan W. Irwin
Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net) the Time
Ephemerides project (timeephem.sf.net) PLplot scientific plotting
software package (plplot.org) the libLASi project
(unifont.org/lasi) the Loads of Linux Links project (loll.sf.net)
and the Linux Brochure Project (lbproject.sf.net)
__________________________
Linux-powered Science
__________________________
Dec. 4, 2019
[PATCH 2/2] bcrypt: Add more BCryptSignHash tests.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/bcrypt/tests/bcrypt.c | 47 +++++++++++++++++++++++++++++++++++++-
1 file changed, 46 insertions(+), 1 deletion(-)
diff --git a/dlls/bcrypt/tests/bcrypt.c b/dlls/bcrypt/tests/bcrypt.c
index d125e0c89d..8e495438df 100644
--- a/dlls/bcrypt/tests/bcrypt.c
+++ b/dlls/bcrypt/tests/bcrypt.c
@@ -2048,7 +2048,9 @@ static BYTE rsapublic[] =
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};
+ {0x04,0xD6,0xAC,0x44,0x02,0xA9,0x2A,0x36,0x78,0x0B,0xC7,0x79,0xC8,0xEC,0x71,0x34,0x49,0xFB,0x92,0x2F};
+ 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 +2058,8 @@ static void test_BCryptSignHash(void)
NTSTATUS ret;
ULONG len;
+ /* RSA */
+
ret = pBCryptOpenAlgorithmProvider(&alg, BCRYPT_RSA_ALGORITHM, NULL, 0);
if (ret)
{
@@ -2087,6 +2091,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 +2111,39 @@ 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);
+
+ /* 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.24.0
Dec. 4, 2019
[PATCH 1/2] bcrypt: Add support for signing hashes with ECDSA keys.
by Derek Lesho
Signed-off-by: Derek Lesho <dlesho(a)codeweavers.com>
---
dlls/bcrypt/gnutls.c | 150 ++++++++++++++++++++++++++++++++++++++-----
1 file changed, 133 insertions(+), 17 deletions(-)
diff --git a/dlls/bcrypt/gnutls.c b/dlls/bcrypt/gnutls.c
index a6a07fff19..fe16e8c435 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,23 @@ static NTSTATUS prepare_gnutls_signature( struct key *key, UCHAR *signature, ULO
}
}
+gnutls_digest_algorithm_t get_digest_from_id(LPCWSTR alg_id)
+{
+ if (!lstrcmpiW(alg_id, BCRYPT_SHA1_ALGORITHM))
+ return GNUTLS_DIG_SHA1;
+ if (!lstrcmpiW(alg_id, BCRYPT_SHA256_ALGORITHM))
+ return GNUTLS_DIG_SHA256;
+ if (!lstrcmpiW(alg_id, BCRYPT_SHA384_ALGORITHM))
+ return GNUTLS_DIG_SHA384;
+ if (!lstrcmpiW(alg_id, BCRYPT_SHA512_ALGORITHM))
+ return GNUTLS_DIG_SHA512;
+ if (!lstrcmpiW(alg_id, BCRYPT_MD2_ALGORITHM))
+ return GNUTLS_DIG_MD2;
+ if (!lstrcmpiW(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 +1088,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 +1123,127 @@ NTSTATUS key_asymmetric_verify( struct key *key, void *padding, UCHAR *hash, ULO
return (ret < 0) ? STATUS_INVALID_SIGNATURE : STATUS_SUCCESS;
}
+NTSTATUS format_gnutls_signature( enum alg_id type, gnutls_datum_t signature, UCHAR *output,
+ ULONG output_len, ULONG *ret_len)
+{
+ int err;
+ unsigned int sig_len;
+
+ switch (type)
+ {
+ case ALG_ID_RSA:
+ case ALG_ID_RSA_SIGN:
+ {
+ /* RSA */
+ 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:
+ sig_len = 64;
+ goto ecc;
+ case ALG_ID_ECDSA_P384:
+ sig_len = 96;
+ ecc:
+ {
+ /* ECDSA, format as r||s */
+ gnutls_datum_t r,s;
+ unsigned int pad_size;
+
+ 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 +1260,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.24.0
Dec. 4, 2019
Re: [wine-devel] Wine staging 4.21 release
by Alan W. Irwin
On 2019-11-30 04:56-0000 Alistair Leslie-Hughes wrote:
> Binary packages for various distributions will be available from:
> https://www.winehq.org/download
>
> Summary since last release
> * Rebased to current wine 4.21 (833 patches are applied to wine vanilla)
>
> Upstreamed (Either directly from staging or fixed with a similar patch).
> * none
>
> 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)
>
> Updated:
> * d3d9-Direct3DShaderValidatorCreate9
> * winecfg-Staging
>
> Where can you help
> * Run Steam/Battle.net/GOG/UPlay/Epic
> * Test your favorite game.
> * Test your favorite applications.
> * Improve staging patches and get them accepted upstream.
>
> As always, if you find a bug, please report it via
> https://bugs.winehq.org
>
Hi Alistair:
Could you explain how these patch numbers are related with each other?
For example, my initial assumption was the rebased patch number should
be equal to the corresponding number in the last report plus the added
patches in this report less the upstreamed patches in this report, i.e.,
r = r_old + a - u
where r and r_old are the current and last reported rebased numbers and a and u
are the current added and upstreamed patch numbers.
But looking at the last several reports that formula predicts
incorrect results with the rebased patch number changing in what looks
like a completely arbitrary way from report to report compared to the
prediction. So it appears the above formula is incorrect and/or
incomplete.
Could you let me know what the correct formula is for predicting the
rebased patch number from report to report (which helps to evaluate
the reliability of the staging patch number statistics that you
present), and if that formula depends on information (my guess is it
is the number of patches in staging that have just been deleted by the
staging maintainers because they judge those patches to not be
worthwhile) that you currently do not include in your reports, could
you include that important information in your following reports?
Alan
__________________________
Alan W. Irwin
Programming affiliations with the FreeEOS equation-of-state
implementation for stellar interiors (freeeos.sf.net) the Time
Ephemerides project (timeephem.sf.net) PLplot scientific plotting
software package (plplot.org) the libLASi project
(unifont.org/lasi) the Loads of Linux Links project (loll.sf.net)
and the Linux Brochure Project (lbproject.sf.net)
__________________________
Linux-powered Science
__________________________
Dec. 4, 2019
Re: [PATCH 2/2] xmllite: Return syntax error on nul character in the stream.
by Nikolay Sivov
On 12/5/19 12:30 AM, Jeff Smith wrote:
> On Wed, Dec 4, 2019 at 2:04 PM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>> I don't think it makes sense to test for null explicitly. Any invalid
>> char for given context would be a syntax error.
> Hi Nikolay,
>
> I agree that it should work that way. However, the tests show that it
> does not. My belief is that the stream is being treated as a string,
> so when a null character encountered, it is treating as marking the
> end of the stream, even though it may actually be a part of the
> stream. My patch makes sure that condition is being covered, at least
> for the cases that are being tested.
Putting explicit null checks here and there just to fix some tests is
not worth it in my opinion.
Instead it should be a part of character range checks, as we do now.
E.g. while on whitespace,
hitting 0 char would mean you're done with whitespace node, and whatever
node is allowed or expected next
should handle it.
>
> Thanks,
> Jeff
Dec. 4, 2019
Re: [PATCH 2/2] xmllite: Return syntax error on nul character in the stream.
by Jeff Smith
On Wed, Dec 4, 2019 at 2:04 PM Nikolay Sivov <nsivov(a)codeweavers.com> wrote:
>
> I don't think it makes sense to test for null explicitly. Any invalid
> char for given context would be a syntax error.
Hi Nikolay,
I agree that it should work that way. However, the tests show that it
does not. My belief is that the stream is being treated as a string,
so when a null character encountered, it is treating as marking the
end of the stream, even though it may actually be a part of the
stream. My patch makes sure that condition is being covered, at least
for the cases that are being tested.
Thanks,
Jeff
Dec. 4, 2019
Re: [PATCH 1/2] include: Don't use the printf format attribute when compiling against msvcrt and not cross-compiling.
by Zebediah Figura
On 12/4/19 12:36 PM, Chip Davis wrote:
> December 4, 2019 12:28 PM, "Zebediah Figura" <z.figura12(a)gmail.com> wrote:
>
>> diff --git a/include/wine/debug.h b/include/wine/debug.h
>> index 1c312e9322..81c32e1816 100644
>> --- a/include/wine/debug.h
>> +++ b/include/wine/debug.h
>> @@ -92,7 +92,11 @@ struct __wine_debug_channel
>> #define __WINE_DBG_LOG(args...) \
>> wine_dbg_log( __dbcl, __dbch, __FUNCTION__, args); } } while(0)
>>
>> +#if !defined(__WINE_USE_MSVCRT) || defined(__MINGW32__)
>> #define __WINE_PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args)))
>> +#else
>> +#define __WINE_PRINTF_ATTR(fmt,args)
>> +#endif
>
> Consider using '__attribute__((format(ms_printf)))' instead. That shouldn't warn on %I, but would still give us the benefits of GCC/Clang's warning. Note that Clang does not yet support that form. I have a patch to fix that, but I need to get it upstream.
At least on gcc 9.2 ms_printf is only recognized for mingw targets. The
documentation implies this as well: "On MinGW targets, ms_printf,
ms_scanf, and ms_strftime are also present." [1]
[1]
https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#Common-F…
>
>>
>> #ifdef WINE_NO_TRACE_MSGS
>
>
> Chip
>
Dec. 4, 2019
Re: [PATCH 2/2] xmllite: Return syntax error on nul character in the stream.
by Nikolay Sivov
I don't think it makes sense to test for null explicitly. Any invalid
char for given context would be a syntax error.
Dec. 4, 2019
[PATCH 2/2] xmllite: Return syntax error on nul character in the stream.
by Jeff Smith
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/xmllite/reader.c | 11 +++++++++++
dlls/xmllite/tests/reader.c | 4 ----
2 files changed, 11 insertions(+), 4 deletions(-)
diff --git a/dlls/xmllite/reader.c b/dlls/xmllite/reader.c
index eddc4d8eec..c8083f63be 100644
--- a/dlls/xmllite/reader.c
+++ b/dlls/xmllite/reader.c
@@ -1696,6 +1696,14 @@ static HRESULT reader_parse_pi(xmlreader *reader)
return S_OK;
}
+/* Determine if we are encountering a nul character within the stream */
+static BOOL reader_at_nul(xmlreader *reader)
+{
+ encoded_buffer *buffer = &reader->input->buffer->utf16;
+ return (buffer->cur*sizeof(WCHAR) < buffer->written &&
+ *((WCHAR*)buffer->data + buffer->cur) == 0);
+}
+
/* This one is used to parse significant whitespace nodes, like in Misc production */
static HRESULT reader_parse_whitespace(xmlreader *reader)
{
@@ -1716,6 +1724,7 @@ static HRESULT reader_parse_whitespace(xmlreader *reader)
UINT start;
reader_skipspaces(reader);
+ if (reader_at_nul(reader)) return WC_E_SYNTAX;
if (is_reader_pending(reader)) return S_OK;
start = reader->resume[XmlReadResume_Body];
@@ -1766,6 +1775,8 @@ static HRESULT reader_parse_misc(xmlreader *reader)
hr = reader_parse_comment(reader);
else if (!reader_cmp(reader, piW))
hr = reader_parse_pi(reader);
+ else if (reader_at_nul(reader))
+ return WC_E_SYNTAX;
else
break;
diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c
index 88b9103e1e..7ad548d081 100644
--- a/dlls/xmllite/tests/reader.c
+++ b/dlls/xmllite/tests/reader.c
@@ -1051,7 +1051,6 @@ static void test_read_nul(void)
type = -1;
hr = IXmlReader_Read(reader, &type);
-todo_wine
ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
@@ -1064,10 +1063,8 @@ todo_wine
type = -1;
hr = IXmlReader_Read(reader, &type);
-todo_wine {
ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
-}
stream = create_stream_on_data(xml_comment, sizeof(xml_comment));
hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
@@ -1079,7 +1076,6 @@ todo_wine {
type = -1;
hr = IXmlReader_Read(reader, &type);
-todo_wine
ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
--
2.23.0
Dec. 4, 2019
[PATCH 1/2] xmllite/tests: Extract nul-character test from XML declaration test.
by Jeff Smith
The comments in the XML declaration test suggest that it is supposed to
be to checking for failure when no element follows the XML declaration.
However, the error being tested for is due to a nul character in the
input stream.
Create a separate test for nul-character errors, and fix the XML
declaration test accordingly.
Signed-off-by: Jeff Smith <whydoubt(a)gmail.com>
---
dlls/xmllite/tests/reader.c | 83 +++++++++++++++++++++++++++++--------
1 file changed, 66 insertions(+), 17 deletions(-)
diff --git a/dlls/xmllite/tests/reader.c b/dlls/xmllite/tests/reader.c
index 41adad1598..88b9103e1e 100644
--- a/dlls/xmllite/tests/reader.c
+++ b/dlls/xmllite/tests/reader.c
@@ -863,7 +863,6 @@ static void test_read_xmldeclaration(void)
{ {'s','t','a','n','d','a','l','o','n','e',0}, {'y','e','s',0} }
};
IXmlReader *reader;
- IStream *stream;
HRESULT hr;
XmlNodeType type;
UINT count = 0, len, i;
@@ -873,10 +872,7 @@ static void test_read_xmldeclaration(void)
hr = CreateXmlReader(&IID_IXmlReader, (LPVOID*)&reader, NULL);
ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
- stream = create_stream_on_data(xmldecl_full, sizeof(xmldecl_full));
-
- hr = IXmlReader_SetInput(reader, (IUnknown*)stream);
- ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+ set_input_string(reader, xmldecl_full);
hr = IXmlReader_GetAttributeCount(reader, &count);
ok(hr == S_OK, "got %08x\n", hr);
@@ -968,19 +964,19 @@ static void test_read_xmldeclaration(void)
type = XmlNodeType_XmlDeclaration;
hr = IXmlReader_Read(reader, &type);
- /* newer versions return syntax error here cause document is incomplete,
- it makes more sense than invalid char error */
+ ok(hr == S_OK, "got %08x\n", hr);
+ ok(type == XmlNodeType_Whitespace, "expected XmlNodeType_Whitespace, got %s\n", type_to_str(type));
+
+ type = XmlNodeType_Whitespace;
+ hr = IXmlReader_Read(reader, &type);
todo_wine {
- ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "got 0x%08x\n", hr);
+ ok(hr == WC_E_ROOTELEMENT, "got %08x\n", hr);
ok(type == XmlNodeType_None, "got %d\n", type);
+ TEST_READER_STATE(reader, XmlReadState_Error);
}
- IStream_Release(stream);
/* test short variant */
- stream = create_stream_on_data(xmldecl_short, sizeof(xmldecl_short));
-
- hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
- ok(hr == S_OK, "expected S_OK, got %08x\n", hr);
+ set_input_string(reader, xmldecl_short);
read_node(reader, XmlNodeType_XmlDeclaration);
TEST_READER_POSITION2(reader, 1, 3, ~0u, 21);
@@ -1027,14 +1023,66 @@ todo_wine {
type = -1;
hr = IXmlReader_Read(reader, &type);
-todo_wine
- ok(hr == WC_E_SYNTAX || hr == WC_E_XMLCHARACTER /* XP */, "expected WC_E_SYNTAX, got %08x\n", hr);
+ ok(hr == S_FALSE, "expected S_FALSE, got %08x\n", hr);
ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
- TEST_READER_POSITION(reader, 1, 41);
+
+ IXmlReader_Release(reader);
+}
+
+static void test_read_nul(void)
+{
+ static const char xml_empty[] = "<a/>";
+ static const char xml_ws[] = "<a/> ";
+ static const char xml_comment[] = "<a/><!-- comment -->";
+ IXmlReader *reader;
+ XmlNodeType type;
+ IStream *stream;
+ HRESULT hr;
+
+ hr = CreateXmlReader(&IID_IXmlReader, (LPVOID*)&reader, NULL);
+ ok(hr == S_OK, "Expected S_OK, got %08x\n", hr);
+
+ stream = create_stream_on_data(xml_empty, sizeof(xml_empty));
+ hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
+ ok(hr == S_OK, "got %08x\n", hr);
+ IStream_Release(stream);
+
+ read_node(reader, XmlNodeType_Element);
+
+ type = -1;
+ hr = IXmlReader_Read(reader, &type);
todo_wine
- TEST_READER_STATE(reader, XmlReadState_Error);
+ ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
+ ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
+ stream = create_stream_on_data(xml_ws, sizeof(xml_ws));
+ hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
+ ok(hr == S_OK, "got %08x\n", hr);
IStream_Release(stream);
+
+ read_node(reader, XmlNodeType_Element);
+
+ type = -1;
+ hr = IXmlReader_Read(reader, &type);
+todo_wine {
+ ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
+ ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
+}
+
+ stream = create_stream_on_data(xml_comment, sizeof(xml_comment));
+ hr = IXmlReader_SetInput(reader, (IUnknown *)stream);
+ ok(hr == S_OK, "got %08x\n", hr);
+ IStream_Release(stream);
+
+ read_node(reader, XmlNodeType_Element);
+ read_node(reader, XmlNodeType_Comment);
+
+ type = -1;
+ hr = IXmlReader_Read(reader, &type);
+todo_wine
+ ok(hr == WC_E_SYNTAX || broken(hr == WC_E_XMLCHARACTER), "expected WC_E_SYNTAX, got 0x%08x\n", hr);
+ ok(type == XmlNodeType_None, "expected XmlNodeType_None, got %s\n", type_to_str(type));
+
IXmlReader_Release(reader);
}
@@ -2672,6 +2720,7 @@ START_TEST(reader)
test_read_pending();
test_readvaluechunk();
test_read_xmldeclaration();
+ test_read_nul();
test_reader_properties();
test_prefix();
test_namespaceuri();
--
2.23.0
Dec. 4, 2019
Re: [PATCH 1/2] include: Don't use the printf format attribute when compiling against msvcrt and not cross-compiling.
by Chip Davis
December 4, 2019 12:28 PM, "Zebediah Figura" <z.figura12(a)gmail.com> wrote:
> diff --git a/include/wine/debug.h b/include/wine/debug.h
> index 1c312e9322..81c32e1816 100644
> --- a/include/wine/debug.h
> +++ b/include/wine/debug.h
> @@ -92,7 +92,11 @@ struct __wine_debug_channel
> #define __WINE_DBG_LOG(args...) \
> wine_dbg_log( __dbcl, __dbch, __FUNCTION__, args); } } while(0)
>
> +#if !defined(__WINE_USE_MSVCRT) || defined(__MINGW32__)
> #define __WINE_PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args)))
> +#else
> +#define __WINE_PRINTF_ATTR(fmt,args)
> +#endif
Consider using '__attribute__((format(ms_printf)))' instead. That shouldn't warn on %I, but would still give us the benefits of GCC/Clang's warning. Note that Clang does not yet support that form. I have a patch to fix that, but I need to get it upstream.
>
> #ifdef WINE_NO_TRACE_MSGS
Chip
Dec. 4, 2019
[PATCH 2/2] mapi32: Use the %I length modifier to print pointer-size integers.
by Zebediah Figura
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
dlls/mapi32/imalloc.c | 4 ++--
dlls/mapi32/mapi32_main.c | 6 +++---
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/dlls/mapi32/imalloc.c b/dlls/mapi32/imalloc.c
index 3e95a6c7cd..561df1a60a 100644
--- a/dlls/mapi32/imalloc.c
+++ b/dlls/mapi32/imalloc.c
@@ -114,7 +114,7 @@ static ULONG WINAPI IMAPIMalloc_fnRelease(LPMALLOC iface)
*/
static LPVOID WINAPI IMAPIMalloc_fnAlloc(LPMALLOC iface, SIZE_T cb)
{
- TRACE("(%p)->(%ld)\n", iface, cb);
+ TRACE("(%p)->(%Id)\n", iface, cb);
return LocalAlloc(LMEM_FIXED, cb);
}
@@ -124,7 +124,7 @@ static LPVOID WINAPI IMAPIMalloc_fnAlloc(LPMALLOC iface, SIZE_T cb)
*/
static LPVOID WINAPI IMAPIMalloc_fnRealloc(LPMALLOC iface, LPVOID pv, SIZE_T cb)
{
- TRACE("(%p)->(%p, %ld)\n", iface, pv, cb);
+ TRACE("(%p)->(%p, %Id)\n", iface, pv, cb);
if (!pv)
return LocalAlloc(LMEM_FIXED, cb);
diff --git a/dlls/mapi32/mapi32_main.c b/dlls/mapi32/mapi32_main.c
index 0dcc811c24..ac83062679 100644
--- a/dlls/mapi32/mapi32_main.c
+++ b/dlls/mapi32/mapi32_main.c
@@ -129,7 +129,7 @@ HRESULT WINAPI MAPIInitialize(LPVOID init)
ULONG WINAPI MAPILogon(ULONG_PTR uiparam, LPSTR profile, LPSTR password,
FLAGS flags, ULONG reserved, LPLHANDLE session)
{
- TRACE("(0x%08lx %s %p 0x%08x 0x%08x %p)\n", uiparam,
+ TRACE("(0x%08Ix %s %p 0x%08x 0x%08x %p)\n", uiparam,
debugstr_a(profile), password, flags, reserved, session);
if (mapiFunctions.MAPILogon)
@@ -149,7 +149,7 @@ ULONG WINAPI MAPILogon(ULONG_PTR uiparam, LPSTR profile, LPSTR password,
ULONG WINAPI MAPILogoff(LHANDLE session, ULONG_PTR uiparam, FLAGS flags,
ULONG reserved )
{
- TRACE("(0x%08lx 0x%08lx 0x%08x 0x%08x)\n", session,
+ TRACE("(0x%08Ix 0x%08Ix 0x%08x 0x%08x)\n", session,
uiparam, flags, reserved);
if (mapiFunctions.MAPILogoff)
@@ -167,7 +167,7 @@ ULONG WINAPI MAPILogoff(LHANDLE session, ULONG_PTR uiparam, FLAGS flags,
HRESULT WINAPI MAPILogonEx(ULONG_PTR uiparam, LPWSTR profile,
LPWSTR password, ULONG flags, LPMAPISESSION *session)
{
- TRACE("(0x%08lx %s %p 0x%08x %p)\n", uiparam,
+ TRACE("(0x%08Ix %s %p 0x%08x %p)\n", uiparam,
debugstr_w(profile), password, flags, session);
if (mapiFunctions.MAPILogonEx)
--
2.24.0
Dec. 4, 2019
[PATCH 1/2] include: Don't use the printf format attribute when compiling against msvcrt and not cross-compiling.
by Zebediah Figura
Since it will spit out bogus warnings in the case we use Microsoft-specific
extensions.
Signed-off-by: Zebediah Figura <z.figura12(a)gmail.com>
---
include/wine/debug.h | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/include/wine/debug.h b/include/wine/debug.h
index 1c312e9322..81c32e1816 100644
--- a/include/wine/debug.h
+++ b/include/wine/debug.h
@@ -92,7 +92,11 @@ struct __wine_debug_channel
#define __WINE_DBG_LOG(args...) \
wine_dbg_log( __dbcl, __dbch, __FUNCTION__, args); } } while(0)
+#if !defined(__WINE_USE_MSVCRT) || defined(__MINGW32__)
#define __WINE_PRINTF_ATTR(fmt,args) __attribute__((format (printf,fmt,args)))
+#else
+#define __WINE_PRINTF_ATTR(fmt,args)
+#endif
#ifdef WINE_NO_TRACE_MSGS
--
2.24.0
Dec. 4, 2019
Re: LONG_PTR and friends
by Zebediah Figura
On 12/4/19 11:28 AM, Jacek Caban wrote:
> Hi Zebediah,
>
> On 11/26/19 7:48 PM, Zebediah Figura wrote:
>> * Both builtin and native msvcrt always support %I, but it's
>> nonstandard and it spits out warnings when you try to use it when not
>> compiling with mingw.
>
>
> I'd say that it looks like a nice solution. Since the warning is
> obviously bogus, I wonder if we should just skip format attribute in
> debug.h when __WINE_USE_MSVCRT is defined and we're not using a cross
> compiler.
Sure, makes sense. I'll try a patch along these lines.
>
>
>> * We could also cast to (void *), or cast to a 64-bit type and use
>> wine_dbgstr_longlong(), though this has the unfortunate side effect of
>> forcing us to trace in hexadecimal.
>
>
> It's not related to your original problem, but for PE builds (modules
> using -mno-cygwin to be precise), compatibility is not an issue so there
> is no reason for using wine_dbgstr_longlong(). I think we should
> consider using %ll* instead.
That would be nice, especially for places where it'd be more readable to
have decimal traces than hexadecimal. I guess we'd run into warnings
when the "long" type is used, but if we skip the format attribute as
above we won't have anything to worry about.
(Related question: why don't we just always define __int64 to "long long"?)
>
>
> Thanks,
>
> Jacek
>
>
Dec. 4, 2019
[PATCH] msxml3: all string passed to IXMLDOMDocument_load() need to be URL-unescaped
by Damjan Jovanovic
msxml3 allows URL escape sequences even for C:\ style paths.
eg. C:\Program%20Files\...
Signed-off-by: Damjan Jovanovic <damjan.jov(a)gmail.com>
---
dlls/msxml3/bsc.c | 8 ++++++--
dlls/msxml3/tests/domdoc.c | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 43 insertions(+), 2 deletions(-)
Dec. 4, 2019
Re: LONG_PTR and friends
by Jacek Caban
Hi Zebediah,
On 11/26/19 7:48 PM, Zebediah Figura wrote:
> * Both builtin and native msvcrt always support %I, but it's
> nonstandard and it spits out warnings when you try to use it when not
> compiling with mingw.
I'd say that it looks like a nice solution. Since the warning is
obviously bogus, I wonder if we should just skip format attribute in
debug.h when __WINE_USE_MSVCRT is defined and we're not using a cross
compiler.
> * We could also cast to (void *), or cast to a 64-bit type and use
> wine_dbgstr_longlong(), though this has the unfortunate side effect of
> forcing us to trace in hexadecimal.
It's not related to your original problem, but for PE builds (modules
using -mno-cygwin to be precise), compatibility is not an issue so there
is no reason for using wine_dbgstr_longlong(). I think we should
consider using %ll* instead.
Thanks,
Jacek
Dec. 4, 2019