[PATCH 3/3] dmusic: Create the list of available system ports at the beginning and use it to enumerate ports.

Christian Costa titan.costa at gmail.com
Sun Sep 16 13:24:10 CDT 2012


--

In next patches this list will be used to create ports.
There will be 3 differents constructors for midi in, midi out and synth ports.
---
 dlls/dmusic/dmusic.c         |  175 +++++++++++++++++++++++++-----------------
 dlls/dmusic/dmusic_private.h |   10 ++
 dlls/dmusic/port.c           |    5 +
 3 files changed, 115 insertions(+), 75 deletions(-)

diff --git a/dlls/dmusic/dmusic.c b/dlls/dmusic/dmusic.c
index 3bc4901..bb1eb96 100644
--- a/dlls/dmusic/dmusic.c
+++ b/dlls/dmusic/dmusic.c
@@ -74,6 +74,7 @@ static ULONG WINAPI IDirectMusic8Impl_Release(LPDIRECTMUSIC8 iface)
     TRACE("(%p)->(): new ref = %u\n", This, ref);
 
     if (!ref) {
+        HeapFree(GetProcessHeap(), 0, This->system_ports);
         HeapFree(GetProcessHeap(), 0, This->ppPorts);
         HeapFree(GetProcessHeap(), 0, This);
     }
@@ -87,85 +88,18 @@ static ULONG WINAPI IDirectMusic8Impl_Release(LPDIRECTMUSIC8 iface)
 static HRESULT WINAPI IDirectMusic8Impl_EnumPort(LPDIRECTMUSIC8 iface, DWORD index, LPDMUS_PORTCAPS port_caps)
 {
     IDirectMusic8Impl *This = impl_from_IDirectMusic8(iface);
-    ULONG nb_midi_out;
-    ULONG nb_midi_in;
-    const WCHAR emulated[] = {' ','[','E','m','u','l','a','t','e','d',']',0};
 
     TRACE("(%p, %d, %p)\n", This, index, port_caps);
 
     if (!port_caps)
         return E_POINTER;
 
-    /* NOTE: It seems some native versions get the rest of devices through dmusic32.EnumLegacyDevices...*sigh*...which is undocumented */
-
-    /* NOTE: Should we enum wave devices ? Native does not seem to */
-
-    /* Fill common port caps for winmm ports */
-    port_caps->dwType = DMUS_PORT_WINMM_DRIVER;
-    port_caps->dwMemorySize = 0;
-    port_caps->dwMaxChannelGroups = 1;
-    port_caps->dwMaxVoices = 0;
-    port_caps->dwMaxAudioChannels = 0;
-    port_caps->dwEffectFlags = DMUS_EFFECT_NONE;
-    /* Fake port GUID */
-    port_caps->guidPort = IID_IUnknown;
-    port_caps->guidPort.Data1 = index + 1;
-
-    nb_midi_out = midiOutGetNumDevs();
-
-    if (index == 0)
-    {
-        MIDIOUTCAPSW caps;
-        midiOutGetDevCapsW(MIDI_MAPPER, &caps, sizeof(caps));
-        strcpyW(port_caps->wszDescription, caps.szPname);
-        strcatW(port_caps->wszDescription, emulated);
-        port_caps->dwFlags = DMUS_PC_SHAREABLE;
-        port_caps->dwClass = DMUS_PC_OUTPUTCLASS;
-        TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
-        return S_OK;
-    }
-
-    if (index < (nb_midi_out + 1))
-    {
-        MIDIOUTCAPSW caps;
-        midiOutGetDevCapsW(index - 1, &caps, sizeof(caps));
-        strcpyW(port_caps->wszDescription, caps.szPname);
-        strcatW(port_caps->wszDescription, emulated);
-        port_caps->dwFlags = DMUS_PC_SHAREABLE | DMUS_PC_EXTERNAL;
-        port_caps->dwClass = DMUS_PC_OUTPUTCLASS;
-        TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
-        return S_OK;
-    }
-
-    nb_midi_in = midiInGetNumDevs();
-
-    if (index < (nb_midi_in + nb_midi_out + 1))
-    {
-        MIDIINCAPSW caps;
-        midiInGetDevCapsW(index - nb_midi_out - 1, &caps, sizeof(caps));
-        strcpyW(port_caps->wszDescription, caps.szPname);
-        strcatW(port_caps->wszDescription, emulated);
-        port_caps->dwFlags = DMUS_PC_EXTERNAL;
-        port_caps->dwClass = DMUS_PC_INPUTCLASS;
-        TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
-        return S_OK;
-    }
+    if (index >= This->nb_system_ports)
+        return S_FALSE;
 
-    if (index == (nb_midi_in + nb_midi_out + 1))
-    {
-        IDirectMusicSynth8* synth = NULL;
-        HRESULT hr;
-        hr = CoCreateInstance(&CLSID_DirectMusicSynth, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicSynth8, (void**)&synth);
-        if (SUCCEEDED(hr))
-            hr = IDirectMusicSynth8_GetPortCaps(synth, port_caps);
-        if (SUCCEEDED(hr))
-            TRACE("Enumerating port: %s\n", debugstr_w(port_caps->wszDescription));
-        if (synth)
-            IDirectMusicSynth8_Release(synth);
-        return hr;
-    }
+    *port_caps = This->system_ports[index].caps;
 
-    return S_FALSE;
+    return S_OK;
 }
 
 static HRESULT WINAPI IDirectMusic8Impl_CreateMusicBuffer(LPDIRECTMUSIC8 iface, LPDMUS_BUFFERDESC buffer_desc, LPDIRECTMUSICBUFFER* buffer, LPUNKNOWN unkouter)
@@ -222,7 +156,7 @@ static HRESULT WINAPI IDirectMusic8Impl_CreatePort(LPDIRECTMUSIC8 iface, REFCLSI
 
 	for (i = 0; S_FALSE != IDirectMusic8Impl_EnumPort(iface, i, &PortCaps); i++) {
 		if (IsEqualCLSID (request_port, &PortCaps.guidPort)) {
-			hr = DMUSIC_CreateDirectMusicPortImpl(&IID_IDirectMusicPort, (LPVOID*) &pNewPort, (LPUNKNOWN) This, pPortParams, &PortCaps);
+			hr = DMUSIC_CreateDirectMusicPortImpl(&IID_IDirectMusicPort, (LPVOID*) &pNewPort, (LPUNKNOWN) This, pPortParams, &PortCaps, 0);
 			if (FAILED(hr)) {
 			  *ppPort = NULL;
 			  return hr;
@@ -370,6 +304,101 @@ static const IDirectMusic8Vtbl DirectMusic8_Vtbl = {
     IDirectMusic8Impl_SetExternalMasterClock
 };
 
+static void create_system_ports_list(IDirectMusic8Impl* object)
+{
+    port_info * port;
+    const WCHAR emulated[] = {' ','[','E','m','u','l','a','t','e','d',']',0};
+    ULONG nb_ports;
+    ULONG nb_midi_out;
+    ULONG nb_midi_in;
+    MIDIOUTCAPSW caps_out;
+    MIDIINCAPSW caps_in;
+    IDirectMusicSynth8* synth;
+    HRESULT hr;
+    int i;
+
+    TRACE("(%p)\n", object);
+
+    /* NOTE:
+       - it seems some native versions get the rest of devices through dmusic32.EnumLegacyDevices...*sigh*...which is undocumented
+       - should we enum wave devices ? Native does not seem to
+    */
+
+    nb_midi_out = midiOutGetNumDevs();
+    nb_midi_in = midiInGetNumDevs();
+    nb_ports = 1 /* midi mapper */ + nb_midi_out + nb_midi_in + 1 /* synth port */;
+
+    port = object->system_ports = HeapAlloc(GetProcessHeap(), 0, nb_ports * sizeof(port_info));
+    if (!object->system_ports)
+        return;
+
+    /* Fill common port caps for all winmm ports */
+    for (i = 0; i < (nb_ports - 1 /* synth port*/); i++)
+    {
+        object->system_ports[i].caps.dwSize = sizeof(DMUS_PORTCAPS);
+        object->system_ports[i].caps.dwType = DMUS_PORT_WINMM_DRIVER;
+        object->system_ports[i].caps.dwMemorySize = 0;
+        object->system_ports[i].caps.dwMaxChannelGroups = 1;
+        object->system_ports[i].caps.dwMaxVoices = 0;
+        object->system_ports[i].caps.dwMaxAudioChannels = 0;
+        object->system_ports[i].caps.dwEffectFlags = DMUS_EFFECT_NONE;
+        /* Fake port GUID */
+        object->system_ports[i].caps.guidPort = IID_IUnknown;
+        object->system_ports[i].caps.guidPort.Data1 = i + 1;
+    }
+
+    /* Fill midi mapper port info */
+    port->device = MIDI_MAPPER;
+    port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
+    midiOutGetDevCapsW(MIDI_MAPPER, &caps_out, sizeof(caps_out));
+    strcpyW(port->caps.wszDescription, caps_out.szPname);
+    strcatW(port->caps.wszDescription, emulated);
+    port->caps.dwFlags = DMUS_PC_SHAREABLE;
+    port->caps.dwClass = DMUS_PC_OUTPUTCLASS;
+    port++;
+
+    /* Fill midi out port info */
+    for (i = 0; i < nb_midi_out; i++)
+    {
+        port->device = i;
+        port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
+        midiOutGetDevCapsW(i, &caps_out, sizeof(caps_out));
+        strcpyW(port->caps.wszDescription, caps_in.szPname);
+        strcatW(port->caps.wszDescription, emulated);
+        port->caps.dwFlags = DMUS_PC_SHAREABLE | DMUS_PC_EXTERNAL;
+        port->caps.dwClass = DMUS_PC_OUTPUTCLASS;
+        port++;
+    }
+
+    /* Fill midi in port info */
+    for (i = 0; i < nb_midi_in; i++)
+    {
+        port->device = i;
+        port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
+        midiInGetDevCapsW(i, &caps_in, sizeof(caps_in));
+        strcpyW(port->caps.wszDescription, caps_in.szPname);
+        strcatW(port->caps.wszDescription, emulated);
+        port->caps.dwFlags = DMUS_PC_EXTERNAL;
+        port->caps.dwClass = DMUS_PC_INPUTCLASS;
+        port++;
+    }
+
+    /* Fill synth port info */
+    port->create = DMUSIC_CreateDirectMusicPortImpl; /* FIXME: The same for all ports for now */
+    hr = CoCreateInstance(&CLSID_DirectMusicSynth, NULL, CLSCTX_INPROC_SERVER, &IID_IDirectMusicSynth8, (void**)&synth);
+    if (SUCCEEDED(hr))
+    {
+        hr = IDirectMusicSynth8_GetPortCaps(synth, &port->caps);
+        IDirectMusicSynth8_Release(synth);
+    }
+    else
+    {
+        nb_ports--;
+    }
+
+    object->nb_system_ports = nb_ports;
+}
+
 /* For ClassFactory */
 HRESULT WINAPI DMUSIC_CreateDirectMusicImpl(LPCGUID riid, LPVOID* ret_iface, LPUNKNOWN unkouter)
 {
@@ -402,5 +431,7 @@ HRESULT WINAPI DMUSIC_CreateDirectMusicImpl(LPCGUID riid, LPVOID* ret_iface, LPU
         return ret;
     }
 
+    create_system_ports_list(dmusic);
+
     return S_OK;
 }
diff --git a/dlls/dmusic/dmusic_private.h b/dlls/dmusic/dmusic_private.h
index 0572a82..a1430ef 100644
--- a/dlls/dmusic/dmusic_private.h
+++ b/dlls/dmusic/dmusic_private.h
@@ -72,6 +72,12 @@ typedef struct DMUSIC_PRIVATE_CHANNEL_GROUP_ {
 	DMUSIC_PRIVATE_MCHANNEL channel[16]; /* 16 channels in a group */
 } DMUSIC_PRIVATE_CHANNEL_GROUP, *LPDMUSIC_PRIVATE_CHANNEL_GROUP;
 
+typedef struct port_info {
+    DMUS_PORTCAPS caps;
+    HRESULT (*create)(LPCGUID guid, LPVOID *object, LPUNKNOWN unkouter, LPDMUS_PORTPARAMS port_params, LPDMUS_PORTCAPS port_caps, DWORD device);
+    ULONG device;
+} port_info;
+
 
 /*****************************************************************************
  * ClassFactory
@@ -100,6 +106,8 @@ struct IDirectMusic8Impl {
     IReferenceClockImpl* pMasterClock;
     IDirectMusicPort** ppPorts;
     int nrofports;
+    port_info* system_ports;
+    int nb_system_ports;
 };
 
 /*****************************************************************************
@@ -161,7 +169,7 @@ struct IDirectMusicPortImpl {
 };
 
 /** Internal factory */
-extern HRESULT DMUSIC_CreateDirectMusicPortImpl (LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps) DECLSPEC_HIDDEN;
+extern HRESULT DMUSIC_CreateDirectMusicPortImpl(LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps, DWORD device) DECLSPEC_HIDDEN;
 
 /*****************************************************************************
  * IReferenceClockImpl implementation structure
diff --git a/dlls/dmusic/port.c b/dlls/dmusic/port.c
index 7e1f5e1..2530fb9 100644
--- a/dlls/dmusic/port.c
+++ b/dlls/dmusic/port.c
@@ -473,12 +473,13 @@ static const IDirectMusicThruVtbl DirectMusicThru_Vtbl = {
 	IDirectMusicThruImpl_ThruChannel
 };
 
-HRESULT DMUSIC_CreateDirectMusicPortImpl (LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps) {
+HRESULT DMUSIC_CreateDirectMusicPortImpl(LPCGUID lpcGUID, LPVOID *ppobj, LPUNKNOWN pUnkOuter, LPDMUS_PORTPARAMS pPortParams, LPDMUS_PORTCAPS pPortCaps, DWORD device)
+{
 	IDirectMusicPortImpl *obj;
 	HRESULT hr = E_FAIL;
 	UINT j;
 
-	TRACE("(%p,%p,%p)\n", lpcGUID, ppobj, pUnkOuter);
+	TRACE("(%p,%p,%p,%d)\n", lpcGUID, ppobj, pUnkOuter, device);
 
 	obj = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirectMusicPortImpl));
 	if (NULL == obj) {




More information about the wine-patches mailing list