mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Updated dmime-PChannel-range patchset
This commit is contained in:
parent
c8e3795e69
commit
5905340060
@ -1,45 +0,0 @@
|
||||
From 6a4d40b86f94703f8c37264739fffc4885507ebf Mon Sep 17 00:00:00 2001
|
||||
From: Alistair Leslie-Hughes <leslie_alistair@hotmail.com>
|
||||
Date: Tue, 17 Sep 2019 16:21:22 +1000
|
||||
Subject: [PATCH] dmime: Ensure Channels are in range before assignment.
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=17766
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=24740
|
||||
---
|
||||
dlls/dmime/performance.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c
|
||||
index 6e4dae6be7..3bbbb3b853 100644
|
||||
--- a/dlls/dmime/performance.c
|
||||
+++ b/dlls/dmime/performance.c
|
||||
@@ -34,7 +34,7 @@ typedef struct IDirectMusicPerformance8Impl {
|
||||
float fMasterTempo;
|
||||
long lMasterVolume;
|
||||
/* performance channels */
|
||||
- DMUSIC_PRIVATE_PCHANNEL PChannel[32];
|
||||
+ DMUSIC_PRIVATE_PCHANNEL PChannel[256];
|
||||
/* IDirectMusicPerformance8Impl fields */
|
||||
IDirectMusicAudioPath *pDefaultPath;
|
||||
HANDLE hNotification;
|
||||
@@ -624,6 +624,9 @@ static HRESULT WINAPI IDirectMusicPerformance8Impl_AssignPChannelBlock(IDirectMu
|
||||
FIXME("(%p, %d, %p, %d): semi-stub\n", This, dwBlockNum, pPort, dwGroup-1);
|
||||
if (NULL == pPort) return E_POINTER;
|
||||
|
||||
+ if (dwBlockNum > ARRAY_SIZE(This->PChannel))
|
||||
+ return S_FALSE;
|
||||
+
|
||||
range = 16 * dwBlockNum;
|
||||
j = 0;
|
||||
for (i = range; i < range+16; i++) {
|
||||
@@ -633,7 +636,6 @@ static HRESULT WINAPI IDirectMusicPerformance8Impl_AssignPChannelBlock(IDirectMu
|
||||
This->PChannel[i].channel = j; /* FIXME: should this be assigned? */
|
||||
j++;
|
||||
}
|
||||
- /*if (dwGroup > 2) return S_FALSE;*/
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,208 @@
|
||||
From a6c2b72782900c1c66852a8f936886e8df194ab2 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Stefaniuc <mstefani@winehq.org>
|
||||
Date: Thu, 19 Dec 2019 23:20:18 +0100
|
||||
Subject: [PATCH 1/3] dmime: Use a rbtree to store the PChannels of a
|
||||
performance
|
||||
|
||||
The PChannel id is a 32bit, potentially random identifier and not an
|
||||
array index.
|
||||
Fixes also the handling of channel group "dwGroup" 0. As it is invalid
|
||||
it is used to mark uninitialized PChannels.
|
||||
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=17766
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=24740
|
||||
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=31562
|
||||
|
||||
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org>
|
||||
---
|
||||
dlls/dmime/performance.c | 109 +++++++++++++++++++++++++++------------
|
||||
1 file changed, 75 insertions(+), 34 deletions(-)
|
||||
|
||||
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c
|
||||
index 615a3f8b14..2124c1fe35 100644
|
||||
--- a/dlls/dmime/performance.c
|
||||
+++ b/dlls/dmime/performance.c
|
||||
@@ -19,10 +19,18 @@
|
||||
*/
|
||||
|
||||
#include "dmime_private.h"
|
||||
+#include "wine/heap.h"
|
||||
+#include "wine/rbtree.h"
|
||||
#include "dmobject.h"
|
||||
|
||||
WINE_DEFAULT_DEBUG_CHANNEL(dmime);
|
||||
|
||||
+struct pchannel_block {
|
||||
+ DWORD block_num; /* Block 0 is PChannels 0-15, Block 1 is PChannels 16-31, etc */
|
||||
+ DMUSIC_PRIVATE_PCHANNEL pchannel[16];
|
||||
+ struct wine_rb_entry entry;
|
||||
+};
|
||||
+
|
||||
typedef struct IDirectMusicPerformance8Impl {
|
||||
IDirectMusicPerformance8 IDirectMusicPerformance8_iface;
|
||||
LONG ref;
|
||||
@@ -35,7 +43,7 @@ typedef struct IDirectMusicPerformance8Impl {
|
||||
float fMasterTempo;
|
||||
long lMasterVolume;
|
||||
/* performance channels */
|
||||
- DMUSIC_PRIVATE_PCHANNEL PChannel[32];
|
||||
+ struct wine_rb_tree pchannels;
|
||||
/* IDirectMusicPerformance8Impl fields */
|
||||
IDirectMusicAudioPath *pDefaultPath;
|
||||
HANDLE hNotification;
|
||||
@@ -192,6 +200,49 @@ static BOOL PostMessageToProcessMsgThread(IDirectMusicPerformance8Impl* This, UI
|
||||
return PostThreadMessageA(This->procThreadId, iMsg, 0, 0);
|
||||
}
|
||||
|
||||
+static int pchannel_block_compare(const void *key, const struct wine_rb_entry *entry)
|
||||
+{
|
||||
+ const struct pchannel_block *b = WINE_RB_ENTRY_VALUE(entry, const struct pchannel_block, entry);
|
||||
+
|
||||
+ return *(DWORD *)key - b->block_num;
|
||||
+}
|
||||
+
|
||||
+static void pchannel_block_free(struct wine_rb_entry *entry, void *context)
|
||||
+{
|
||||
+ struct pchannel_block *b = WINE_RB_ENTRY_VALUE(entry, struct pchannel_block, entry);
|
||||
+
|
||||
+ heap_free(b);
|
||||
+}
|
||||
+
|
||||
+static struct pchannel_block *pchannel_block_set(struct wine_rb_tree *tree, DWORD block_num,
|
||||
+ IDirectMusicPort *port, DWORD group, BOOL only_set_new)
|
||||
+{
|
||||
+ struct pchannel_block *block;
|
||||
+ struct wine_rb_entry *entry;
|
||||
+ unsigned int i;
|
||||
+
|
||||
+ entry = wine_rb_get(tree, &block_num);
|
||||
+ if (entry) {
|
||||
+ block = WINE_RB_ENTRY_VALUE(entry, struct pchannel_block, entry);
|
||||
+ if (only_set_new)
|
||||
+ return block;
|
||||
+ } else {
|
||||
+ if (!(block = heap_alloc(sizeof(*block))))
|
||||
+ return NULL;
|
||||
+ block->block_num = block_num;
|
||||
+ }
|
||||
+
|
||||
+ for (i = 0; i < 16; ++i) {
|
||||
+ block->pchannel[i].port = port;
|
||||
+ block->pchannel[i].group = group;
|
||||
+ block->pchannel[i].channel = i;
|
||||
+ }
|
||||
+ if (!entry)
|
||||
+ wine_rb_put(tree, &block->block_num, &block->entry);
|
||||
+
|
||||
+ return block;
|
||||
+}
|
||||
+
|
||||
static inline IDirectMusicPerformance8Impl *impl_from_IDirectMusicPerformance8(IDirectMusicPerformance8 *iface)
|
||||
{
|
||||
return CONTAINING_RECORD(iface, IDirectMusicPerformance8Impl, IDirectMusicPerformance8_iface);
|
||||
@@ -236,6 +287,7 @@ static ULONG WINAPI IDirectMusicPerformance8Impl_Release(IDirectMusicPerformance
|
||||
TRACE("(%p): ReleaseRef to %d\n", This, ref);
|
||||
|
||||
if (ref == 0) {
|
||||
+ wine_rb_destroy(&This->pchannels, pchannel_block_free, NULL);
|
||||
This->safe.DebugInfo->Spare[0] = 0;
|
||||
DeleteCriticalSection(&This->safe);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
@@ -579,7 +631,6 @@ static HRESULT WINAPI IDirectMusicPerformance8Impl_AddPort(IDirectMusicPerforman
|
||||
GUID port_guid;
|
||||
IDirectMusicPort* pDefaultPort = NULL;
|
||||
DMUS_PORTPARAMS params;
|
||||
- int i, j;
|
||||
hr = IDirectMusic8_GetDefaultPort(This->dmusic, &port_guid);
|
||||
if (FAILED(hr)) return hr;
|
||||
ZeroMemory(¶ms, sizeof(params));
|
||||
@@ -591,15 +642,7 @@ static HRESULT WINAPI IDirectMusicPerformance8Impl_AddPort(IDirectMusicPerforman
|
||||
if (FAILED(hr)) return hr;
|
||||
hr = IDirectMusicPort_Activate(pDefaultPort, TRUE);
|
||||
if (FAILED(hr)) { IDirectMusicPort_Release(pDefaultPort); return hr; }
|
||||
- j = 0;
|
||||
- for (i = 0; i < 16; ++i) {
|
||||
- if (NULL == This->PChannel[i].port) {
|
||||
- This->PChannel[i].port = pPort;
|
||||
- This->PChannel[i].group = 0;
|
||||
- This->PChannel[i].channel = j; /* FIXME: should this be assigned? */
|
||||
- j++;
|
||||
- }
|
||||
- }
|
||||
+ IDirectMusicPerformance8_AssignPChannelBlock(iface, 0, pDefaultPort, 1);
|
||||
} else {
|
||||
IDirectMusicPort_AddRef(pPort);
|
||||
}
|
||||
@@ -621,41 +664,38 @@ static HRESULT WINAPI IDirectMusicPerformance8Impl_RemovePort(IDirectMusicPerfor
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirectMusicPerformance8Impl_AssignPChannelBlock(IDirectMusicPerformance8 *iface,
|
||||
- DWORD dwBlockNum, IDirectMusicPort *pPort, DWORD dwGroup)
|
||||
+ DWORD block_num, IDirectMusicPort *port, DWORD group)
|
||||
{
|
||||
- IDirectMusicPerformance8Impl *This = impl_from_IDirectMusicPerformance8(iface);
|
||||
- int i, j, range /* min value in range */;
|
||||
-
|
||||
- FIXME("(%p, %d, %p, %d): semi-stub\n", This, dwBlockNum, pPort, dwGroup-1);
|
||||
- if (NULL == pPort) return E_POINTER;
|
||||
-
|
||||
- range = 16 * dwBlockNum;
|
||||
- j = 0;
|
||||
- for (i = range; i < range+16; i++) {
|
||||
- /*TRACE("Setting PChannel[%i] to port %p, group %ld, MIDI port %i\n", i, pPort, dwGroup-1, j); */
|
||||
- This->PChannel[i].port = pPort;
|
||||
- This->PChannel[i].group = dwGroup - 1; /* first index is always zero */
|
||||
- This->PChannel[i].channel = j; /* FIXME: should this be assigned? */
|
||||
- j++;
|
||||
- }
|
||||
- /*if (dwGroup > 2) return S_FALSE;*/
|
||||
+ IDirectMusicPerformance8Impl *This = impl_from_IDirectMusicPerformance8(iface);
|
||||
|
||||
- return S_OK;
|
||||
+ FIXME("(%p, %d, %p, %d): semi-stub\n", This, block_num, port, group);
|
||||
+
|
||||
+ if (!port)
|
||||
+ return E_POINTER;
|
||||
+ if (block_num > MAXDWORD / 16)
|
||||
+ return E_INVALIDARG;
|
||||
+
|
||||
+ pchannel_block_set(&This->pchannels, block_num, port, group, FALSE);
|
||||
+
|
||||
+ return S_OK;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirectMusicPerformance8Impl_AssignPChannel(IDirectMusicPerformance8 *iface,
|
||||
- DWORD PChannel, IDirectMusicPort *port, DWORD group, DWORD MChannel)
|
||||
+ DWORD pchannel, IDirectMusicPort *port, DWORD group, DWORD channel)
|
||||
{
|
||||
IDirectMusicPerformance8Impl *This = impl_from_IDirectMusicPerformance8(iface);
|
||||
+ struct pchannel_block *block;
|
||||
|
||||
- TRACE("(%p)->(%d, %p, %d, %d)\n", This, PChannel, port, group, MChannel);
|
||||
+ FIXME("(%p)->(%d, %p, %d, %d) semi-stub\n", This, pchannel, port, group, channel);
|
||||
|
||||
if (!port)
|
||||
return E_POINTER;
|
||||
|
||||
- This->PChannel[PChannel].port = port;
|
||||
- This->PChannel[PChannel].group = group;
|
||||
- This->PChannel[PChannel].channel = MChannel;
|
||||
+ block = pchannel_block_set(&This->pchannels, pchannel / 16, port, 0, TRUE);
|
||||
+ if (block) {
|
||||
+ block->pchannel[pchannel % 16].group = group;
|
||||
+ block->pchannel[pchannel % 16].channel = channel;
|
||||
+ }
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1211,6 +1251,7 @@ HRESULT WINAPI create_dmperformance(REFIID lpcGUID, void **ppobj)
|
||||
obj->pDefaultPath = NULL;
|
||||
InitializeCriticalSection(&obj->safe);
|
||||
obj->safe.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": IDirectMusicPerformance8Impl*->safe");
|
||||
+ wine_rb_init(&obj->pchannels, pchannel_block_compare);
|
||||
|
||||
obj->rtLatencyTime = 100; /* 100 ms TO FIX */
|
||||
obj->dwBumperLength = 50; /* 50 ms default */
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,173 @@
|
||||
From bc158e53fb1df19ee8029c899bf2801f4a99ef33 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Stefaniuc <mstefani@winehq.org>
|
||||
Date: Thu, 19 Dec 2019 23:20:19 +0100
|
||||
Subject: [PATCH 2/3] dmime/tests: Add PChannel tests
|
||||
|
||||
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org>
|
||||
---
|
||||
dlls/dmime/tests/performance.c | 126 ++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 124 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/dlls/dmime/tests/performance.c b/dlls/dmime/tests/performance.c
|
||||
index 1d17e5200e..4c340252aa 100644
|
||||
--- a/dlls/dmime/tests/performance.c
|
||||
+++ b/dlls/dmime/tests/performance.c
|
||||
@@ -100,10 +100,18 @@ static HRESULT test_InitAudio(void)
|
||||
return hr;
|
||||
|
||||
port = NULL;
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(performance, 128, &port, NULL, NULL);
|
||||
+ todo_wine ok(hr == E_INVALIDARG, "PChannelInfo failed, got %08x\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(performance, 127, &port, NULL, NULL);
|
||||
+ ok(hr == S_OK, "PChannelInfo failed, got %08x\n", hr);
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(performance, 0, &port, NULL, NULL);
|
||||
- ok(hr == S_OK, "Failed to call PChannelInfo (%x)\n", hr);
|
||||
+ ok(hr == S_OK, "PChannelInfo failed, got %08x\n", hr);
|
||||
ok(port != NULL, "IDirectMusicPort not set\n");
|
||||
- if (hr == S_OK && port != NULL)
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannel(performance, 0, port, 0, 0);
|
||||
+ todo_wine ok(hr == DMUS_E_AUDIOPATHS_IN_USE, "AssignPChannel failed (%08x)\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannelBlock(performance, 0, port, 0);
|
||||
+ todo_wine ok(hr == DMUS_E_AUDIOPATHS_IN_USE, "AssignPChannelBlock failed (%08x)\n", hr);
|
||||
+ if (port)
|
||||
IDirectMusicPort_Release(port);
|
||||
|
||||
hr = IDirectMusicPerformance8_GetDefaultAudioPath(performance, &path);
|
||||
@@ -120,6 +128,8 @@ static HRESULT test_InitAudio(void)
|
||||
create_performance(&performance, NULL, NULL, FALSE);
|
||||
hr = IDirectMusicPerformance8_InitAudio(performance, NULL, NULL, NULL, 0, 64, 0, NULL);
|
||||
ok(hr == S_OK, "InitAudio failed: %08x\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(performance, 0, &port, NULL, NULL);
|
||||
+ todo_wine ok(hr == E_INVALIDARG, "PChannelInfo failed, got %08x\n", hr);
|
||||
destroy_performance(performance, NULL, NULL);
|
||||
|
||||
/* Refcounts for auto generated dmusic and dsound */
|
||||
@@ -322,6 +332,117 @@ static void test_createport(void)
|
||||
IDirectMusicPerformance_Release(perf);
|
||||
}
|
||||
|
||||
+static void test_pchannel(void)
|
||||
+{
|
||||
+ IDirectMusicPerformance8 *perf;
|
||||
+ IDirectMusicPort *port = NULL, *port2;
|
||||
+ DWORD channel, group;
|
||||
+ unsigned int i;
|
||||
+ HRESULT hr;
|
||||
+
|
||||
+ create_performance(&perf, NULL, NULL, FALSE);
|
||||
+ hr = IDirectMusicPerformance8_Init(perf, NULL, NULL, NULL);
|
||||
+ ok(hr == S_OK, "Init failed: %08x\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, 0, &port, NULL, NULL);
|
||||
+ todo_wine ok(hr == E_INVALIDARG && !port, "PChannelInfo failed, got %08x, %p\n", hr, port);
|
||||
+
|
||||
+ /* Add default port. Sets PChannels 0-15 to the corresponding channels in group 1 */
|
||||
+ hr = IDirectMusicPerformance8_AddPort(perf, NULL);
|
||||
+ ok(hr == S_OK, "AddPort of default port failed: %08x\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, 0, NULL, NULL, NULL);
|
||||
+ ok(hr == S_OK, "PChannelInfo failed, got %08x\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, 0, &port, NULL, NULL);
|
||||
+ ok(hr == S_OK && port, "PChannelInfo failed, got %08x, %p\n", hr, port);
|
||||
+ for (i = 1; i < 16; i++) {
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, i, &port2, &group, &channel);
|
||||
+ todo_wine ok(hr == S_OK && port == port2 && group == 1 && channel == i,
|
||||
+ "PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
+ IDirectMusicPort_Release(port2);
|
||||
+ }
|
||||
+
|
||||
+ /* Unset PChannels fail to retrieve */
|
||||
+ todo_wine {
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, 16, &port2, NULL, NULL);
|
||||
+ ok(hr == E_INVALIDARG, "PChannelInfo failed, got %08x, %p\n", hr, port);
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, MAXDWORD - 16, &port2, NULL, NULL);
|
||||
+ ok(hr == E_INVALIDARG, "PChannelInfo failed, got %08x, %p\n", hr, port);
|
||||
+ }
|
||||
+
|
||||
+ /* Channel group 0 can be set just fine */
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannel(perf, 0, port, 0, 0);
|
||||
+ ok(hr == S_OK, "AssignPChannel failed, got %08x\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannelBlock(perf, 0, port, 0);
|
||||
+ ok(hr == S_OK, "AssignPChannelBlock failed, got %08x\n", hr);
|
||||
+ for (i = 1; i < 16; i++) {
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, i, &port2, &group, &channel);
|
||||
+ todo_wine ok(hr == S_OK && port == port2 && group == 0 && channel == i,
|
||||
+ "PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
+ IDirectMusicPort_Release(port2);
|
||||
+ }
|
||||
+
|
||||
+ /* Last PChannel Block can be set only individually but not read */
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannel(perf, MAXDWORD, port, 0, 3);
|
||||
+ ok(hr == S_OK, "AssignPChannel failed, got %08x\n", hr);
|
||||
+ port2 = (IDirectMusicPort *)0xdeadbeef;
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, MAXDWORD, &port2, NULL, NULL);
|
||||
+ todo_wine ok(hr == E_INVALIDARG && port2 == (IDirectMusicPort *)0xdeadbeef,
|
||||
+ "PChannelInfo failed, got %08x, %p\n", hr, port2);
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannelBlock(perf, MAXDWORD, port, 0);
|
||||
+ ok(hr == E_INVALIDARG, "AssignPChannelBlock failed, got %08x\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannelBlock(perf, MAXDWORD / 16, port, 1);
|
||||
+ todo_wine ok(hr == E_INVALIDARG, "AssignPChannelBlock failed, got %08x\n", hr);
|
||||
+ for (i = MAXDWORD - 15; i < MAXDWORD; i++) {
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannel(perf, i, port, 0, 0);
|
||||
+ ok(hr == S_OK, "AssignPChannel failed, got %08x\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, i, &port2, NULL, NULL);
|
||||
+ todo_wine ok(hr == E_INVALIDARG && port2 == (IDirectMusicPort *)0xdeadbeef,
|
||||
+ "PChannelInfo failed, got %08x, %p\n", hr, port2);
|
||||
+ }
|
||||
+
|
||||
+ /* Second to last PChannel Block can be set only individually and read */
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannelBlock(perf, MAXDWORD / 16 - 1, port, 1);
|
||||
+ todo_wine ok(hr == E_INVALIDARG, "AssignPChannelBlock failed, got %08x\n", hr);
|
||||
+ for (i = MAXDWORD - 31; i < MAXDWORD - 15; i++) {
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannel(perf, i, port, 1, 7);
|
||||
+ ok(hr == S_OK, "AssignPChannel failed, got %08x\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, i, &port2, &group, &channel);
|
||||
+ todo_wine ok(hr == S_OK && port2 == port && group == 1 && channel == 7,
|
||||
+ "PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
+ IDirectMusicPort_Release(port2);
|
||||
+ }
|
||||
+
|
||||
+ /* Third to last PChannel Block behaves normal */
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannelBlock(perf, MAXDWORD / 16 - 2, port, 0);
|
||||
+ ok(hr == S_OK, "AssignPChannelBlock failed, got %08x\n", hr);
|
||||
+ for (i = MAXDWORD - 47; i < MAXDWORD - 31; i++) {
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, i, &port2, &group, &channel);
|
||||
+ todo_wine ok(hr == S_OK && port2 == port && group == 0 && channel == i % 16,
|
||||
+ "PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
+ IDirectMusicPort_Release(port2);
|
||||
+ }
|
||||
+
|
||||
+ /* One PChannel set in a Block, rest is initialized too */
|
||||
+ hr = IDirectMusicPerformance8_AssignPChannel(perf, 4711, port, 1, 13);
|
||||
+ ok(hr == S_OK, "AssignPChannel failed, got %08x\n", hr);
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, 4711, &port2, &group, &channel);
|
||||
+ todo_wine ok(hr == S_OK && port2 == port && group == 1 && channel == 13,
|
||||
+ "PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
+ IDirectMusicPort_Release(port2);
|
||||
+ group = channel = 0xdeadbeef;
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, 4712, &port2, &group, &channel);
|
||||
+ todo_wine ok(hr == S_OK && port2 == port && group == 0 && channel == 8,
|
||||
+ "PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
+ IDirectMusicPort_Release(port2);
|
||||
+ group = channel = 0xdeadbeef;
|
||||
+ hr = IDirectMusicPerformance8_PChannelInfo(perf, 4719, &port2, &group, &channel);
|
||||
+ todo_wine ok(hr == S_OK && port2 == port && group == 0 && channel == 15,
|
||||
+ "PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
+ IDirectMusicPort_Release(port2);
|
||||
+
|
||||
+ IDirectMusicPort_Release(port);
|
||||
+ destroy_performance(perf, NULL, NULL);
|
||||
+}
|
||||
+
|
||||
static void test_COM(void)
|
||||
{
|
||||
IDirectMusicPerformance *dmp = (IDirectMusicPerformance*)0xdeadbeef;
|
||||
@@ -504,6 +625,7 @@ START_TEST( performance )
|
||||
|
||||
test_COM();
|
||||
test_createport();
|
||||
+ test_pchannel();
|
||||
test_notification_type();
|
||||
|
||||
CoUninitialize();
|
||||
--
|
||||
2.17.1
|
||||
|
@ -0,0 +1,174 @@
|
||||
From a649a14676b8b57019021021f9b1c3474c88f129 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Stefaniuc <mstefani@winehq.org>
|
||||
Date: Thu, 19 Dec 2019 23:20:20 +0100
|
||||
Subject: [PATCH 3/3] dmime: Implement IDirectMusicPerformance8_PChannelInfo()
|
||||
|
||||
NOT FOR THE FREEZE ==> DEFER
|
||||
|
||||
Not needed for the bugs referenced in patch 1 but to validate the tests
|
||||
from patch 2.
|
||||
|
||||
Signed-off-by: Michael Stefaniuc <mstefani@winehq.org>
|
||||
---
|
||||
dlls/dmime/performance.c | 31 ++++++++++++++++++++++---------
|
||||
dlls/dmime/tests/performance.c | 24 +++++++++++-------------
|
||||
2 files changed, 33 insertions(+), 22 deletions(-)
|
||||
|
||||
diff --git a/dlls/dmime/performance.c b/dlls/dmime/performance.c
|
||||
index 2124c1fe35..9f489f5e36 100644
|
||||
--- a/dlls/dmime/performance.c
|
||||
+++ b/dlls/dmime/performance.c
|
||||
@@ -701,18 +701,29 @@ static HRESULT WINAPI IDirectMusicPerformance8Impl_AssignPChannel(IDirectMusicPe
|
||||
}
|
||||
|
||||
static HRESULT WINAPI IDirectMusicPerformance8Impl_PChannelInfo(IDirectMusicPerformance8 *iface,
|
||||
- DWORD PChannel, IDirectMusicPort **port, DWORD *group, DWORD *MChannel)
|
||||
+ DWORD pchannel, IDirectMusicPort **port, DWORD *group, DWORD *channel)
|
||||
{
|
||||
IDirectMusicPerformance8Impl *This = impl_from_IDirectMusicPerformance8(iface);
|
||||
- DMUS_PORTPARAMS8 port_params;
|
||||
- GUID default_port;
|
||||
+ struct pchannel_block *block;
|
||||
+ struct wine_rb_entry *entry;
|
||||
+ DWORD block_num = pchannel / 16;
|
||||
+ unsigned int index = pchannel % 16;
|
||||
|
||||
- FIXME("(%p)->(%d, %p, %p, %p): stub\n", This, PChannel, port, group, MChannel);
|
||||
+ TRACE("(%p)->(%d, %p, %p, %p)\n", This, pchannel, port, group, channel);
|
||||
|
||||
- port_params.dwSize = sizeof(DMUS_PORTPARAMS8);
|
||||
- port_params.dwValidParams = 0;
|
||||
- IDirectMusic8_GetDefaultPort(This->dmusic, &default_port);
|
||||
- IDirectMusic8_CreatePort(This->dmusic, &default_port, &port_params, port, NULL);
|
||||
+ entry = wine_rb_get(&This->pchannels, &block_num);
|
||||
+ if (!entry)
|
||||
+ return E_INVALIDARG;
|
||||
+ block = WINE_RB_ENTRY_VALUE(entry, struct pchannel_block, entry);
|
||||
+
|
||||
+ if (port) {
|
||||
+ *port = block->pchannel[index].port;
|
||||
+ IDirectMusicPort_AddRef(*port);
|
||||
+ }
|
||||
+ if (group)
|
||||
+ *group = block->pchannel[index].group;
|
||||
+ if (channel)
|
||||
+ *channel = block->pchannel[index].channel;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1102,7 +1113,9 @@ static HRESULT WINAPI IDirectMusicPerformance8Impl_CreateStandardAudioPath(IDire
|
||||
return E_INVALIDARG;
|
||||
}
|
||||
|
||||
- /* FIXME: Should we create one secondary buffer for each PChannel? */
|
||||
+ /* FIXME: Create a proper port with enough dwGroups for the PChannels */
|
||||
+ IDirectMusicPerformance8_AddPort(iface, NULL);
|
||||
+
|
||||
hr = IDirectSound_CreateSoundBuffer(This->dsound, &desc, &buffer, NULL);
|
||||
if (FAILED(hr))
|
||||
return DSERR_BUFFERLOST;
|
||||
diff --git a/dlls/dmime/tests/performance.c b/dlls/dmime/tests/performance.c
|
||||
index 4c340252aa..adc20224c0 100644
|
||||
--- a/dlls/dmime/tests/performance.c
|
||||
+++ b/dlls/dmime/tests/performance.c
|
||||
@@ -101,9 +101,9 @@ static HRESULT test_InitAudio(void)
|
||||
|
||||
port = NULL;
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(performance, 128, &port, NULL, NULL);
|
||||
- todo_wine ok(hr == E_INVALIDARG, "PChannelInfo failed, got %08x\n", hr);
|
||||
+ ok(hr == E_INVALIDARG, "PChannelInfo failed, got %08x\n", hr);
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(performance, 127, &port, NULL, NULL);
|
||||
- ok(hr == S_OK, "PChannelInfo failed, got %08x\n", hr);
|
||||
+ todo_wine ok(hr == S_OK, "PChannelInfo failed, got %08x\n", hr);
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(performance, 0, &port, NULL, NULL);
|
||||
ok(hr == S_OK, "PChannelInfo failed, got %08x\n", hr);
|
||||
ok(port != NULL, "IDirectMusicPort not set\n");
|
||||
@@ -129,7 +129,7 @@ static HRESULT test_InitAudio(void)
|
||||
hr = IDirectMusicPerformance8_InitAudio(performance, NULL, NULL, NULL, 0, 64, 0, NULL);
|
||||
ok(hr == S_OK, "InitAudio failed: %08x\n", hr);
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(performance, 0, &port, NULL, NULL);
|
||||
- todo_wine ok(hr == E_INVALIDARG, "PChannelInfo failed, got %08x\n", hr);
|
||||
+ ok(hr == E_INVALIDARG, "PChannelInfo failed, got %08x\n", hr);
|
||||
destroy_performance(performance, NULL, NULL);
|
||||
|
||||
/* Refcounts for auto generated dmusic and dsound */
|
||||
@@ -344,7 +344,7 @@ static void test_pchannel(void)
|
||||
hr = IDirectMusicPerformance8_Init(perf, NULL, NULL, NULL);
|
||||
ok(hr == S_OK, "Init failed: %08x\n", hr);
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(perf, 0, &port, NULL, NULL);
|
||||
- todo_wine ok(hr == E_INVALIDARG && !port, "PChannelInfo failed, got %08x, %p\n", hr, port);
|
||||
+ ok(hr == E_INVALIDARG && !port, "PChannelInfo failed, got %08x, %p\n", hr, port);
|
||||
|
||||
/* Add default port. Sets PChannels 0-15 to the corresponding channels in group 1 */
|
||||
hr = IDirectMusicPerformance8_AddPort(perf, NULL);
|
||||
@@ -355,18 +355,16 @@ static void test_pchannel(void)
|
||||
ok(hr == S_OK && port, "PChannelInfo failed, got %08x, %p\n", hr, port);
|
||||
for (i = 1; i < 16; i++) {
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(perf, i, &port2, &group, &channel);
|
||||
- todo_wine ok(hr == S_OK && port == port2 && group == 1 && channel == i,
|
||||
+ ok(hr == S_OK && port == port2 && group == 1 && channel == i,
|
||||
"PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
IDirectMusicPort_Release(port2);
|
||||
}
|
||||
|
||||
/* Unset PChannels fail to retrieve */
|
||||
- todo_wine {
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(perf, 16, &port2, NULL, NULL);
|
||||
ok(hr == E_INVALIDARG, "PChannelInfo failed, got %08x, %p\n", hr, port);
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(perf, MAXDWORD - 16, &port2, NULL, NULL);
|
||||
ok(hr == E_INVALIDARG, "PChannelInfo failed, got %08x, %p\n", hr, port);
|
||||
- }
|
||||
|
||||
/* Channel group 0 can be set just fine */
|
||||
hr = IDirectMusicPerformance8_AssignPChannel(perf, 0, port, 0, 0);
|
||||
@@ -375,7 +373,7 @@ static void test_pchannel(void)
|
||||
ok(hr == S_OK, "AssignPChannelBlock failed, got %08x\n", hr);
|
||||
for (i = 1; i < 16; i++) {
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(perf, i, &port2, &group, &channel);
|
||||
- todo_wine ok(hr == S_OK && port == port2 && group == 0 && channel == i,
|
||||
+ ok(hr == S_OK && port == port2 && group == 0 && channel == i,
|
||||
"PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
IDirectMusicPort_Release(port2);
|
||||
}
|
||||
@@ -406,7 +404,7 @@ static void test_pchannel(void)
|
||||
hr = IDirectMusicPerformance8_AssignPChannel(perf, i, port, 1, 7);
|
||||
ok(hr == S_OK, "AssignPChannel failed, got %08x\n", hr);
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(perf, i, &port2, &group, &channel);
|
||||
- todo_wine ok(hr == S_OK && port2 == port && group == 1 && channel == 7,
|
||||
+ ok(hr == S_OK && port2 == port && group == 1 && channel == 7,
|
||||
"PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
IDirectMusicPort_Release(port2);
|
||||
}
|
||||
@@ -416,7 +414,7 @@ static void test_pchannel(void)
|
||||
ok(hr == S_OK, "AssignPChannelBlock failed, got %08x\n", hr);
|
||||
for (i = MAXDWORD - 47; i < MAXDWORD - 31; i++) {
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(perf, i, &port2, &group, &channel);
|
||||
- todo_wine ok(hr == S_OK && port2 == port && group == 0 && channel == i % 16,
|
||||
+ ok(hr == S_OK && port2 == port && group == 0 && channel == i % 16,
|
||||
"PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
IDirectMusicPort_Release(port2);
|
||||
}
|
||||
@@ -425,17 +423,17 @@ static void test_pchannel(void)
|
||||
hr = IDirectMusicPerformance8_AssignPChannel(perf, 4711, port, 1, 13);
|
||||
ok(hr == S_OK, "AssignPChannel failed, got %08x\n", hr);
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(perf, 4711, &port2, &group, &channel);
|
||||
- todo_wine ok(hr == S_OK && port2 == port && group == 1 && channel == 13,
|
||||
+ ok(hr == S_OK && port2 == port && group == 1 && channel == 13,
|
||||
"PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
IDirectMusicPort_Release(port2);
|
||||
group = channel = 0xdeadbeef;
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(perf, 4712, &port2, &group, &channel);
|
||||
- todo_wine ok(hr == S_OK && port2 == port && group == 0 && channel == 8,
|
||||
+ ok(hr == S_OK && port2 == port && group == 0 && channel == 8,
|
||||
"PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
IDirectMusicPort_Release(port2);
|
||||
group = channel = 0xdeadbeef;
|
||||
hr = IDirectMusicPerformance8_PChannelInfo(perf, 4719, &port2, &group, &channel);
|
||||
- todo_wine ok(hr == S_OK && port2 == port && group == 0 && channel == 15,
|
||||
+ ok(hr == S_OK && port2 == port && group == 0 && channel == 15,
|
||||
"PChannelInfo failed, got %08x, %p, %u, %u\n", hr, port2, group, channel);
|
||||
IDirectMusicPort_Release(port2);
|
||||
|
||||
--
|
||||
2.17.1
|
||||
|
@ -1,2 +1,3 @@
|
||||
Fixes: [17766] Empire Earth crashes on start without native directmusic
|
||||
Fixes: [24740] Trinklet Supreme crashes on startup
|
||||
Fixes: [31562] Stop crash when using lithtech game engine.
|
||||
|
@ -3166,14 +3166,19 @@ fi
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#17766] Empire Earth crashes on start without native directmusic
|
||||
# | * [#24740] Trinklet Supreme crashes on startup
|
||||
# | * [#31562] Stop crash when using lithtech game engine.
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/dmime/performance.c
|
||||
# | * dlls/dmime/performance.c, dlls/dmime/tests/performance.c
|
||||
# |
|
||||
if test "$enable_dmime_PChannel_range" -eq 1; then
|
||||
patch_apply dmime-PChannel-range/0001-dmime-Ensure-Channels-are-in-range-before-assignment.patch
|
||||
patch_apply dmime-PChannel-range/0001-dmime-Use-a-rbtree-to-store-the-PChannels-of-a-perfo.patch
|
||||
patch_apply dmime-PChannel-range/0002-dmime-tests-Add-PChannel-tests.patch
|
||||
patch_apply dmime-PChannel-range/0003-dmime-Implement-IDirectMusicPerformance8_PChannelInf.patch
|
||||
(
|
||||
printf '%s\n' '+ { "Alistair Leslie-Hughes", "dmime: Ensure Channels are in range before assignment.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Stefaniuc", "dmime: Use a rbtree to store the PChannels of a performance.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Stefaniuc", "dmime/tests: Add PChannel tests.", 1 },';
|
||||
printf '%s\n' '+ { "Michael Stefaniuc", "dmime: Implement IDirectMusicPerformance8_PChannelInfo().", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user