mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 21:05:43 +00:00
- Start rewrite of DirectSound
- Implemented DirectSoundEnumerateA, DirectSoundEnumerateW, DirectSoundCaptureEnumerateA, DirectSoundCaptureEnumerateW, GetDeviceID - Partly implemented IDirectSound8 / IDirectSoundCapture8, IDirectSoundCaptureBuffer, primary / secondary IDirectSoundBuffer8 interfaces - DllRegisterServer / DllUnregisterServer are taken from Wine DSound implementation (John K. Hohm) - Currently only one primary + secondary buffer are supported for playback - Mixing of IDirectSoundBuffer is not implemented - Capture mode isnt yet supported - Vlc now can use dsound for playback, though stutters in low quality streams are present - Dsound is not yet added to build untill it has stabilized more svn path=/trunk/; revision=43874
This commit is contained in:
parent
9a5b0ce12b
commit
e65de6eda6
18 changed files with 4609 additions and 0 deletions
296
reactos/dll/directx/dsound_new/capture.c
Normal file
296
reactos/dll/directx/dsound_new/capture.c
Normal file
|
@ -0,0 +1,296 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/capture.c
|
||||
* PURPOSE: Implement IDirectSoundCapture
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IDirectSoundCaptureVtbl *lpVtbl;
|
||||
LONG ref;
|
||||
GUID DeviceGUID;
|
||||
BOOL bInitialized;
|
||||
LPFILTERINFO Filter;
|
||||
}CDirectSoundCaptureImpl, *LPCDirectSoundCaptureImpl;
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
CDirectSoundCapture_fnQueryInterface(
|
||||
LPDIRECTSOUNDCAPTURE8 iface,
|
||||
REFIID riid,
|
||||
LPVOID * ppobj)
|
||||
{
|
||||
LPOLESTR pStr;
|
||||
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
|
||||
|
||||
/* check if the interface is supported */
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IDirectSoundCapture))
|
||||
{
|
||||
*ppobj = (LPVOID)&This->lpVtbl;
|
||||
InterlockedIncrement(&This->ref);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* unsupported interface */
|
||||
if (SUCCEEDED(StringFromIID(riid, &pStr)))
|
||||
{
|
||||
DPRINT("No Interface for class %s\n", pStr);
|
||||
CoTaskMemFree(pStr);
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
CDirectSoundCapture_fnAddRef(
|
||||
LPDIRECTSOUNDCAPTURE8 iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
|
||||
|
||||
/* increment reference count */
|
||||
ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
CDirectSoundCapture_fnRelease(
|
||||
LPDIRECTSOUNDCAPTURE8 iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
|
||||
|
||||
/* release reference count */
|
||||
ref = InterlockedDecrement(&(This->ref));
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
CDirectSoundCapture_fnCreateCaptureBuffer(
|
||||
LPDIRECTSOUNDCAPTURE8 iface,
|
||||
LPCDSCBUFFERDESC lpcDSBufferDesc,
|
||||
LPDIRECTSOUNDCAPTUREBUFFER *ppDSCBuffer,
|
||||
LPUNKNOWN pUnkOuter)
|
||||
{
|
||||
HRESULT hResult;
|
||||
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
|
||||
|
||||
if (!This->bInitialized)
|
||||
{
|
||||
/* object not yet initialized */
|
||||
return DSERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!lpcDSBufferDesc || !ppDSCBuffer || pUnkOuter != NULL)
|
||||
{
|
||||
DPRINT("Invalid parameter %p %p %p\n", lpcDSBufferDesc, ppDSCBuffer, pUnkOuter);
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* check buffer description */
|
||||
if ((lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC) && lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC1)) || lpcDSBufferDesc->dwReserved != 0)
|
||||
{
|
||||
DPRINT("Invalid buffer description size %u expected %u dwReserved %u\n", lpcDSBufferDesc->dwSize, sizeof(DSBUFFERDESC1), lpcDSBufferDesc->dwReserved);
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(lpcDSBufferDesc->lpwfxFormat);
|
||||
|
||||
if (lpcDSBufferDesc->lpwfxFormat)
|
||||
{
|
||||
DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u NBlockAlign %u wBitsPerSample %u cbSize %u\n",
|
||||
This, lpcDSBufferDesc->lpwfxFormat->wFormatTag, lpcDSBufferDesc->lpwfxFormat->nChannels, lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec, lpcDSBufferDesc->lpwfxFormat->nAvgBytesPerSec, lpcDSBufferDesc->lpwfxFormat->nBlockAlign, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample, lpcDSBufferDesc->lpwfxFormat->cbSize);
|
||||
}
|
||||
|
||||
hResult = NewDirectSoundCaptureBuffer((LPDIRECTSOUNDCAPTUREBUFFER8*)ppDSCBuffer, This->Filter, lpcDSBufferDesc);
|
||||
return hResult;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
CDirectSoundCapture_fnGetCaps(
|
||||
LPDIRECTSOUNDCAPTURE8 iface,
|
||||
LPDSCCAPS pDSCCaps)
|
||||
{
|
||||
WAVEINCAPSW Caps;
|
||||
MMRESULT Result;
|
||||
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
|
||||
|
||||
if (!This->bInitialized)
|
||||
{
|
||||
/* object not yet initialized */
|
||||
return DSERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!pDSCCaps || pDSCCaps->dwSize != sizeof(DSCCAPS))
|
||||
{
|
||||
/* invalid param */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* We are certified ;) */
|
||||
pDSCCaps->dwFlags = DSCCAPS_CERTIFIED;
|
||||
|
||||
Result = waveInGetDevCapsW(This->Filter->MappedId[0], &Caps, sizeof(WAVEINCAPSW));
|
||||
if (Result != MMSYSERR_NOERROR)
|
||||
{
|
||||
/* failed */
|
||||
DPRINT("waveInGetDevCapsW for device %u failed with %x\n", This->Filter->MappedId[0], Result);
|
||||
return DSERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
pDSCCaps->dwFormats = Caps.dwFormats;
|
||||
pDSCCaps->dwChannels = Caps.wChannels;
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
CDirectSoundCapture_fnInitialize(
|
||||
LPDIRECTSOUNDCAPTURE8 iface,
|
||||
LPCGUID pcGuidDevice)
|
||||
{
|
||||
GUID DeviceGuid;
|
||||
LPOLESTR pGuidStr;
|
||||
HRESULT hr;
|
||||
LPCDirectSoundCaptureImpl This = (LPCDirectSoundCaptureImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureImpl, lpVtbl);
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(RootInfo);
|
||||
|
||||
if (This->bInitialized)
|
||||
{
|
||||
/* object has already been initialized */
|
||||
return DSERR_ALREADYINITIALIZED;
|
||||
}
|
||||
|
||||
/* fixme mutual exlucsion */
|
||||
|
||||
if (pcGuidDevice == NULL || IsEqualGUID(pcGuidDevice, &GUID_NULL))
|
||||
{
|
||||
/* use default playback device id */
|
||||
pcGuidDevice = &DSDEVID_DefaultCapture;
|
||||
}
|
||||
|
||||
/* now verify the guid */
|
||||
if (GetDeviceID(pcGuidDevice, &DeviceGuid) != DS_OK)
|
||||
{
|
||||
if (SUCCEEDED(StringFromIID(pcGuidDevice, &pGuidStr)))
|
||||
{
|
||||
DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr);
|
||||
CoTaskMemFree(pGuidStr);
|
||||
}
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
hr = FindDeviceByGuid(&DeviceGuid, &This->Filter);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
This->bInitialized = TRUE;
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
DPRINT("Failed to find device\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
static IDirectSoundCaptureVtbl vt_DirectSoundCapture =
|
||||
{
|
||||
/* IUnknown methods */
|
||||
CDirectSoundCapture_fnQueryInterface,
|
||||
CDirectSoundCapture_fnAddRef,
|
||||
CDirectSoundCapture_fnRelease,
|
||||
CDirectSoundCapture_fnCreateCaptureBuffer,
|
||||
CDirectSoundCapture_fnGetCaps,
|
||||
CDirectSoundCapture_fnInitialize
|
||||
};
|
||||
|
||||
HRESULT
|
||||
InternalDirectSoundCaptureCreate(
|
||||
LPCGUID lpcGUID,
|
||||
LPDIRECTSOUNDCAPTURE8 *ppDS,
|
||||
IUnknown *pUnkOuter)
|
||||
{
|
||||
LPCDirectSoundCaptureImpl This;
|
||||
HRESULT hr;
|
||||
|
||||
if (!ppDS || pUnkOuter != NULL)
|
||||
{
|
||||
/* invalid parameter passed */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* allocate CDirectSoundCaptureImpl struct */
|
||||
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundCaptureImpl));
|
||||
if (!This)
|
||||
{
|
||||
/* not enough memory */
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* initialize IDirectSoundCapture object */
|
||||
This->ref = 1;
|
||||
This->lpVtbl = &vt_DirectSoundCapture;
|
||||
|
||||
|
||||
/* initialize direct sound interface */
|
||||
hr = IDirectSoundCapture_Initialize((LPDIRECTSOUNDCAPTURE8)&This->lpVtbl, lpcGUID);
|
||||
|
||||
/* check for success */
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
/* failed */
|
||||
DPRINT("Failed to initialize DirectSoundCapture object with %x\n", hr);
|
||||
IDirectSoundCapture_Release((LPDIRECTSOUND8)&This->lpVtbl);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* store result */
|
||||
*ppDS = (LPDIRECTSOUNDCAPTURE8)&This->lpVtbl;
|
||||
DPRINT("DirectSoundCapture object %p\n", *ppDS);
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DirectSoundCaptureCreate(
|
||||
LPCGUID lpcGUID,
|
||||
LPDIRECTSOUNDCAPTURE *ppDSC,
|
||||
LPUNKNOWN pUnkOuter)
|
||||
{
|
||||
return InternalDirectSoundCaptureCreate(lpcGUID, (LPDIRECTSOUNDCAPTURE8*)ppDSC, pUnkOuter);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DirectSoundCaptureCreate8(
|
||||
LPCGUID lpcGUID,
|
||||
LPDIRECTSOUNDCAPTURE8 *ppDSC8,
|
||||
LPUNKNOWN pUnkOuter)
|
||||
{
|
||||
return InternalDirectSoundCaptureCreate(lpcGUID, ppDSC8, pUnkOuter);
|
||||
}
|
331
reactos/dll/directx/dsound_new/capturebuffer.c
Normal file
331
reactos/dll/directx/dsound_new/capturebuffer.c
Normal file
|
@ -0,0 +1,331 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/capturebuffer.c
|
||||
* PURPOSE: IDirectSoundCaptureBuffer8 implementation
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
const GUID KSINTERFACESETID_Standard = {0x1A8766A0L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||
const GUID KSMEDIUMSETID_Standard = {0x4747B320L, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||
const GUID KSDATAFORMAT_TYPE_AUDIO = {0x73647561L, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
|
||||
const GUID KSDATAFORMAT_SPECIFIER_WAVEFORMATEX = {0x05589f81L, 0xc356, 0x11ce, {0xbf, 0x01, 0x00, 0xaa, 0x00, 0x55, 0x59, 0x5a}};
|
||||
const GUID KSPROPSETID_Connection = {0x1D58C920L, 0xAC9B, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IDirectSoundCaptureBuffer8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
LPFILTERINFO Filter;
|
||||
HANDLE hPin;
|
||||
PUCHAR Buffer;
|
||||
DWORD BufferSize;
|
||||
LPWAVEFORMATEX Format;
|
||||
KSSTATE State;
|
||||
|
||||
|
||||
}CDirectSoundCaptureBufferImpl, *LPCDirectSoundCaptureBufferImpl;
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_QueryInterface(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
IN REFIID riid,
|
||||
LPVOID* ppobj)
|
||||
{
|
||||
LPOLESTR pStr;
|
||||
LPCDirectSoundCaptureBufferImpl This = (LPCDirectSoundCaptureBufferImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureBufferImpl, lpVtbl);
|
||||
|
||||
/* check if requested interface is supported */
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IDirectSoundCaptureBuffer) ||
|
||||
IsEqualIID(riid, &IID_IDirectSoundCaptureBuffer8))
|
||||
{
|
||||
*ppobj = (LPVOID)&This->lpVtbl;
|
||||
InterlockedIncrement(&This->ref);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
/* interface not supported */
|
||||
if (SUCCEEDED(StringFromIID(riid, &pStr)))
|
||||
{
|
||||
DPRINT("No Interface for class %s\n", pStr);
|
||||
CoTaskMemFree(pStr);
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_AddRef(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCDirectSoundCaptureBufferImpl This = (LPCDirectSoundCaptureBufferImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureBufferImpl, lpVtbl);
|
||||
|
||||
/* increment reference count */
|
||||
ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
return ref;
|
||||
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_Release(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCDirectSoundCaptureBufferImpl This = (LPCDirectSoundCaptureBufferImpl)CONTAINING_RECORD(iface, CDirectSoundCaptureBufferImpl, lpVtbl);
|
||||
|
||||
/* release reference count */
|
||||
ref = InterlockedDecrement(&(This->ref));
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
/* free capture buffer */
|
||||
HeapFree(GetProcessHeap(), 0, This->Buffer);
|
||||
HeapFree(GetProcessHeap(), 0, This->Format);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_GetCaps(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
LPDSCBCAPS lpDSCBCaps )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_GetCurrentPosition(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
LPDWORD lpdwCapturePosition,
|
||||
LPDWORD lpdwReadPosition)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_GetFormat(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
LPWAVEFORMATEX lpwfxFormat,
|
||||
DWORD dwSizeAllocated,
|
||||
LPDWORD lpdwSizeWritten)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_GetStatus(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
LPDWORD lpdwStatus )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_Initialize(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
LPDIRECTSOUNDCAPTURE lpDSC,
|
||||
LPCDSCBUFFERDESC lpcDSCBDesc)
|
||||
{
|
||||
/* capture buffer is already initialized */
|
||||
return DSERR_ALREADYINITIALIZED;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_Lock(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
DWORD dwReadCusor,
|
||||
DWORD dwReadBytes,
|
||||
LPVOID* lplpvAudioPtr1,
|
||||
LPDWORD lpdwAudioBytes1,
|
||||
LPVOID* lplpvAudioPtr2,
|
||||
LPDWORD lpdwAudioBytes2,
|
||||
DWORD dwFlags )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_Start(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
DWORD dwFlags )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_Unlock(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
LPVOID lpvAudioPtr1,
|
||||
DWORD dwAudioBytes1,
|
||||
LPVOID lpvAudioPtr2,
|
||||
DWORD dwAudioBytes2 )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_GetObjectInPath(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
REFGUID rguidObject,
|
||||
DWORD dwIndex,
|
||||
REFGUID rguidInterface,
|
||||
LPVOID* ppObject )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSoundCaptureBufferImpl_GetFXStatus(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 iface,
|
||||
DWORD dwFXCount,
|
||||
LPDWORD pdwFXStatus )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
|
||||
static IDirectSoundCaptureBuffer8Vtbl vt_DirectSoundCaptureBuffer8 =
|
||||
{
|
||||
/* IUnknown methods */
|
||||
IDirectSoundCaptureBufferImpl_QueryInterface,
|
||||
IDirectSoundCaptureBufferImpl_AddRef,
|
||||
IDirectSoundCaptureBufferImpl_Release,
|
||||
|
||||
/* IDirectSoundCaptureBuffer methods */
|
||||
IDirectSoundCaptureBufferImpl_GetCaps,
|
||||
IDirectSoundCaptureBufferImpl_GetCurrentPosition,
|
||||
IDirectSoundCaptureBufferImpl_GetFormat,
|
||||
IDirectSoundCaptureBufferImpl_GetStatus,
|
||||
IDirectSoundCaptureBufferImpl_Initialize,
|
||||
IDirectSoundCaptureBufferImpl_Lock,
|
||||
IDirectSoundCaptureBufferImpl_Start,
|
||||
IDirectSoundCaptureBufferImpl_Stop,
|
||||
IDirectSoundCaptureBufferImpl_Unlock,
|
||||
|
||||
/* IDirectSoundCaptureBuffer methods */
|
||||
IDirectSoundCaptureBufferImpl_GetObjectInPath,
|
||||
IDirectSoundCaptureBufferImpl_GetFXStatus
|
||||
};
|
||||
|
||||
|
||||
HRESULT
|
||||
NewDirectSoundCaptureBuffer(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 *OutBuffer,
|
||||
LPFILTERINFO Filter,
|
||||
LPCDSCBUFFERDESC lpcDSBufferDesc)
|
||||
{
|
||||
DWORD FormatSize;
|
||||
ULONG DeviceId = 0, PinId;
|
||||
DWORD Result = ERROR_SUCCESS;
|
||||
|
||||
LPCDirectSoundCaptureBufferImpl This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundCaptureBufferImpl));
|
||||
|
||||
if (!This)
|
||||
{
|
||||
/* not enough memory */
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* calculate format size */
|
||||
FormatSize = sizeof(WAVEFORMATEX) + lpcDSBufferDesc->lpwfxFormat->cbSize;
|
||||
/* allocate format struct */
|
||||
This->Format = HeapAlloc(GetProcessHeap(), 0, FormatSize);
|
||||
if (!This->Format)
|
||||
{
|
||||
/* not enough memory */
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(lpcDSBufferDesc->dwBufferBytes);
|
||||
|
||||
/* allocate capture buffer */
|
||||
This->Buffer = HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc->dwBufferBytes);
|
||||
if (!This->Buffer)
|
||||
{
|
||||
/* not enough memory */
|
||||
HeapFree(GetProcessHeap(), 0, This->Format);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* store buffer size */
|
||||
This->BufferSize = lpcDSBufferDesc->dwBufferBytes;
|
||||
ASSERT(lpcDSBufferDesc->lpwfxFormat->cbSize == 0);
|
||||
|
||||
do
|
||||
{
|
||||
/* try all available recording pins on that filter */
|
||||
PinId = GetPinIdFromFilter(Filter, TRUE, DeviceId);
|
||||
DPRINT("PinId %u DeviceId %u\n", PinId, DeviceId);
|
||||
|
||||
if (PinId == ULONG_MAX)
|
||||
break;
|
||||
|
||||
Result = OpenPin(Filter->hFilter, PinId, lpcDSBufferDesc->lpwfxFormat, &This->hPin, TRUE);
|
||||
if (Result == ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
DeviceId++;
|
||||
}while(TRUE);
|
||||
|
||||
if (Result != ERROR_SUCCESS)
|
||||
{
|
||||
/* failed to instantiate the capture pin */
|
||||
HeapFree(GetProcessHeap(), 0, This->Buffer);
|
||||
HeapFree(GetProcessHeap(), 0, This->Format);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* initialize capture buffer */
|
||||
This->ref = 1;
|
||||
This->lpVtbl = &vt_DirectSoundCaptureBuffer8;
|
||||
This->Filter = Filter;
|
||||
This->State = KSSTATE_STOP;
|
||||
|
||||
*OutBuffer = (LPDIRECTSOUNDCAPTUREBUFFER8)&This->lpVtbl;
|
||||
return DS_OK;
|
||||
}
|
141
reactos/dll/directx/dsound_new/classfactory.c
Normal file
141
reactos/dll/directx/dsound_new/classfactory.c
Normal file
|
@ -0,0 +1,141 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/classfactory.c
|
||||
* PURPOSE: IClassFactory implementation
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const IClassFactoryVtbl *lpVtbl;
|
||||
LONG ref;
|
||||
CLSID *rclsid;
|
||||
LPFNCREATEINSTANCE lpfnCI;
|
||||
const IID * riidInst;
|
||||
} IClassFactoryImpl;
|
||||
|
||||
|
||||
static
|
||||
HRESULT
|
||||
WINAPI
|
||||
IClassFactory_fnQueryInterface(
|
||||
LPCLASSFACTORY iface,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObj)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
|
||||
*ppvObj = NULL;
|
||||
|
||||
/* check requested interface */
|
||||
if(IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IClassFactory))
|
||||
{
|
||||
*ppvObj = This;
|
||||
InterlockedIncrement(&This->ref);
|
||||
return S_OK;
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static
|
||||
ULONG
|
||||
WINAPI
|
||||
IClassFactory_fnAddRef(
|
||||
LPCLASSFACTORY iface)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
|
||||
/* increment reference count */
|
||||
ULONG refCount = InterlockedIncrement(&This->ref);
|
||||
|
||||
return refCount;
|
||||
}
|
||||
|
||||
static
|
||||
ULONG
|
||||
WINAPI
|
||||
IClassFactory_fnRelease(
|
||||
LPCLASSFACTORY iface)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
ULONG refCount = InterlockedDecrement(&This->ref);
|
||||
|
||||
/* decrement reference count */
|
||||
if (!refCount)
|
||||
{
|
||||
/* free class factory */
|
||||
CoTaskMemFree(This);
|
||||
return 0;
|
||||
}
|
||||
return refCount;
|
||||
}
|
||||
|
||||
static
|
||||
HRESULT
|
||||
WINAPI
|
||||
IClassFactory_fnCreateInstance(
|
||||
LPCLASSFACTORY iface,
|
||||
LPUNKNOWN pUnkOuter,
|
||||
REFIID riid,
|
||||
LPVOID *ppvObject)
|
||||
{
|
||||
IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
|
||||
*ppvObject = NULL;
|
||||
|
||||
if ( This->riidInst==NULL || IsEqualCLSID(riid, This->riidInst) || IsEqualCLSID(riid, &IID_IUnknown) )
|
||||
{
|
||||
/* instantiate object */
|
||||
return This->lpfnCI(pUnkOuter, riid, ppvObject);
|
||||
}
|
||||
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
static
|
||||
HRESULT
|
||||
WINAPI IClassFactory_fnLockServer(
|
||||
LPCLASSFACTORY iface,
|
||||
BOOL fLock)
|
||||
{
|
||||
//IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
|
||||
return E_NOTIMPL;
|
||||
}
|
||||
|
||||
|
||||
static const IClassFactoryVtbl dclfvt =
|
||||
{
|
||||
IClassFactory_fnQueryInterface,
|
||||
IClassFactory_fnAddRef,
|
||||
IClassFactory_fnRelease,
|
||||
IClassFactory_fnCreateInstance,
|
||||
IClassFactory_fnLockServer
|
||||
};
|
||||
|
||||
|
||||
IClassFactory *
|
||||
IClassFactory_fnConstructor(
|
||||
LPFNCREATEINSTANCE lpfnCI,
|
||||
PLONG pcRefDll,
|
||||
REFIID riidInst)
|
||||
{
|
||||
IClassFactoryImpl* lpclf;
|
||||
|
||||
lpclf = CoTaskMemAlloc(sizeof(IClassFactoryImpl));
|
||||
lpclf->ref = 1;
|
||||
lpclf->lpVtbl = &dclfvt;
|
||||
lpclf->lpfnCI = lpfnCI;
|
||||
|
||||
if (pcRefDll)
|
||||
InterlockedIncrement(pcRefDll);
|
||||
lpclf->riidInst = riidInst;
|
||||
|
||||
return (LPCLASSFACTORY)lpclf;
|
||||
}
|
||||
|
||||
|
498
reactos/dll/directx/dsound_new/devicelist.c
Normal file
498
reactos/dll/directx/dsound_new/devicelist.c
Normal file
|
@ -0,0 +1,498 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/devicelist.c
|
||||
* PURPOSE: Enumeration of audio devices
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
ULONG
|
||||
GetPinIdFromFilter(
|
||||
LPFILTERINFO Filter,
|
||||
BOOL bCapture,
|
||||
ULONG Offset)
|
||||
{
|
||||
ULONG Index;
|
||||
|
||||
for(Index = Offset; Index < Filter->PinCount; Index++)
|
||||
{
|
||||
if (Filter->Pin[Index] == PIN_TYPE_PLAYBACK && !bCapture)
|
||||
return Index;
|
||||
|
||||
if (Filter->Pin[Index] == PIN_TYPE_RECORDING && bCapture)
|
||||
return Index;
|
||||
}
|
||||
return ULONG_MAX;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
OpenDeviceList(
|
||||
IN LPGUID InterfaceGuid,
|
||||
OUT HDEVINFO * OutHandle)
|
||||
{
|
||||
HDEVINFO DeviceHandle;
|
||||
|
||||
DeviceHandle = SetupDiGetClassDevs(InterfaceGuid,
|
||||
NULL,
|
||||
NULL,
|
||||
DIGCF_DEVICEINTERFACE); //DIGCF_PRESENT
|
||||
|
||||
/* check for success */
|
||||
if (DeviceHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
/* failed to create device list */
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
/* store result */
|
||||
*OutHandle = DeviceHandle;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
BOOL
|
||||
CloseDeviceList(
|
||||
HDEVINFO Handle)
|
||||
{
|
||||
return SetupDiDestroyDeviceInfoList(Handle);
|
||||
}
|
||||
|
||||
BOOL
|
||||
GetDeviceListInterfaces(
|
||||
HDEVINFO DeviceHandle,
|
||||
IN LPGUID InterfaceGuid,
|
||||
LPFILTERINFO *OutPath)
|
||||
{
|
||||
ULONG Length, Index = 0;
|
||||
SP_DEVICE_INTERFACE_DATA InterfaceData;
|
||||
PSP_DEVICE_INTERFACE_DETAIL_DATA_W DetailData;
|
||||
SP_DEVINFO_DATA DeviceData;
|
||||
LPFILTERINFO LastDevice = NULL, RootDevice = NULL, CurDevice;
|
||||
BOOL Result;
|
||||
|
||||
|
||||
do
|
||||
{
|
||||
InterfaceData.cbSize = sizeof(InterfaceData);
|
||||
InterfaceData.Reserved = 0;
|
||||
|
||||
/* query device interface */
|
||||
Result = SetupDiEnumDeviceInterfaces(DeviceHandle,
|
||||
NULL,
|
||||
InterfaceGuid,
|
||||
Index,
|
||||
&InterfaceData);
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
/* failed */
|
||||
DPRINT("SetupDiEnumDeviceInterfaces Index %u failed with %lx\n", Index, GetLastError());
|
||||
break;
|
||||
}
|
||||
|
||||
/* allocate device interface struct */
|
||||
Length = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W) + MAX_PATH * sizeof(WCHAR);
|
||||
DetailData = (PSP_DEVICE_INTERFACE_DETAIL_DATA_W)HeapAlloc(GetProcessHeap(),
|
||||
HEAP_ZERO_MEMORY,
|
||||
Length);
|
||||
|
||||
if (!DetailData)
|
||||
{
|
||||
/* insufficient memory */
|
||||
break;
|
||||
}
|
||||
|
||||
/* initialize device interface detail struct */
|
||||
DetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA_W);
|
||||
|
||||
DeviceData.cbSize = sizeof(DeviceData);
|
||||
DeviceData.Reserved = 0;
|
||||
|
||||
Result = SetupDiGetDeviceInterfaceDetailW(DeviceHandle,
|
||||
&InterfaceData,
|
||||
DetailData,
|
||||
Length,
|
||||
NULL,
|
||||
&DeviceData);
|
||||
|
||||
if (!Result)
|
||||
{
|
||||
/* failed */
|
||||
DPRINT("SetupDiGetDeviceInterfaceDetail failed with %x\n", GetLastError());
|
||||
HeapFree(GetProcessHeap(), 0, DetailData);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* allocate device path struct */
|
||||
CurDevice = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(FILTERINFO));
|
||||
if (!CurDevice)
|
||||
{
|
||||
/* no memory */
|
||||
HeapFree(GetProcessHeap(), 0, DetailData);
|
||||
break;
|
||||
}
|
||||
|
||||
/* store device path */
|
||||
CopyMemory(&CurDevice->DeviceData, &DeviceData, sizeof(SP_DEVINFO_DATA));
|
||||
wcscpy(CurDevice->DevicePath, DetailData->DevicePath);
|
||||
CurDevice->MappedId[0] = ULONG_MAX;
|
||||
CurDevice->MappedId[1] = ULONG_MAX;
|
||||
|
||||
DPRINT("DevicePath %S\n", CurDevice->DevicePath);
|
||||
|
||||
if (!RootDevice)
|
||||
RootDevice = CurDevice;
|
||||
|
||||
if (LastDevice)
|
||||
{
|
||||
LastDevice->lpNext = CurDevice;
|
||||
}
|
||||
|
||||
/* set as last device */
|
||||
LastDevice = CurDevice;
|
||||
|
||||
/* free device interface struct */
|
||||
HeapFree(GetProcessHeap(), 0, DetailData);
|
||||
|
||||
/* increment device interface index */
|
||||
Index++;
|
||||
}while(TRUE);
|
||||
|
||||
/* store result */
|
||||
*OutPath = RootDevice;
|
||||
|
||||
if (!RootDevice)
|
||||
return FALSE;
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DWORD
|
||||
OpenDeviceKey(
|
||||
HDEVINFO Handle,
|
||||
PSP_DEVINFO_DATA FILTERINFOData,
|
||||
DWORD KeyType,
|
||||
REGSAM DesiredAccess,
|
||||
OUT HKEY * OutKey)
|
||||
{
|
||||
HKEY hKey;
|
||||
|
||||
/* try open device registry key */
|
||||
hKey = SetupDiOpenDevRegKey(Handle, FILTERINFOData, DICS_FLAG_CONFIGSPECIFIC, 0, KeyType, DesiredAccess);
|
||||
|
||||
if (hKey == INVALID_HANDLE_VALUE)
|
||||
return GetLastError();
|
||||
|
||||
/* store result */
|
||||
*OutKey = hKey;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
VOID
|
||||
FindAudioFilterPins(
|
||||
LPFILTERINFO CurInfo,
|
||||
OUT PULONG WaveInPins,
|
||||
OUT PULONG WaveOutPins)
|
||||
{
|
||||
ULONG Index;
|
||||
KSPIN_COMMUNICATION Communication;
|
||||
KSPIN_DATAFLOW DataFlow;
|
||||
|
||||
*WaveInPins = 0;
|
||||
*WaveOutPins = 0;
|
||||
|
||||
/* traverse all pins */
|
||||
for(Index = 0; Index < CurInfo->PinCount; Index++)
|
||||
{
|
||||
if (GetFilterPinCommunication(CurInfo->hFilter, Index, &Communication) == ERROR_SUCCESS &&
|
||||
GetFilterPinDataFlow(CurInfo->hFilter, Index, &DataFlow) == ERROR_SUCCESS)
|
||||
{
|
||||
if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_IN)
|
||||
{
|
||||
/* found a wave out device */
|
||||
CurInfo->Pin[Index] = PIN_TYPE_PLAYBACK;
|
||||
(*WaveOutPins)++;
|
||||
}
|
||||
else if (Communication == KSPIN_COMMUNICATION_SINK && DataFlow == KSPIN_DATAFLOW_OUT)
|
||||
{
|
||||
/* found a wave in device */
|
||||
CurInfo->Pin[Index] = PIN_TYPE_RECORDING;
|
||||
(*WaveInPins)++;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bridge pin / topology pin etc */
|
||||
CurInfo->Pin[Index] = PIN_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* bridge pin / topology pin etc */
|
||||
CurInfo->Pin[Index] = PIN_TYPE_NONE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOL
|
||||
FindWinMMDeviceIndex(
|
||||
LPFILTERINFO CurInfo,
|
||||
BOOL bRecord)
|
||||
{
|
||||
ULONG DeviceCount, Index;
|
||||
WCHAR Buffer[MAX_PATH];
|
||||
DWORD Size, dwResult;
|
||||
|
||||
if (bRecord)
|
||||
DeviceCount = waveInGetNumDevs();
|
||||
else
|
||||
DeviceCount = waveOutGetNumDevs();
|
||||
|
||||
/* sanity check */
|
||||
//ASSERT(DeviceCount);
|
||||
|
||||
for(Index = 0; Index < DeviceCount; Index++)
|
||||
{
|
||||
Size = 0;
|
||||
|
||||
/* query device interface size */
|
||||
if (bRecord)
|
||||
dwResult = waveInMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&Size, 0);
|
||||
else
|
||||
dwResult = waveOutMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACESIZE, (DWORD_PTR)&Size, 0);
|
||||
|
||||
if (dwResult != MMSYSERR_NOERROR)
|
||||
{
|
||||
DPRINT("Failed DRV_QUERYDEVICEINTERFACESIZE with %lx bRecord %u Index %u\n", dwResult, bRecord, Index);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(Size < MAX_PATH);
|
||||
|
||||
/* now get the device interface string */
|
||||
if (bRecord)
|
||||
dwResult = waveInMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)Buffer, MAX_PATH);
|
||||
else
|
||||
dwResult = waveOutMessage(UlongToHandle(Index), DRV_QUERYDEVICEINTERFACE, (DWORD_PTR)Buffer, MAX_PATH);
|
||||
|
||||
if (dwResult != MMSYSERR_NOERROR)
|
||||
{
|
||||
DPRINT("Failed DRV_QUERYDEVICEINTERFACE with %lx bRecord %u Index %u\n", dwResult, bRecord, Index);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!wcsicmp(CurInfo->DevicePath, Buffer))
|
||||
{
|
||||
if (bRecord)
|
||||
CurInfo->MappedId[0] = Index;
|
||||
else
|
||||
CurInfo->MappedId[1] = Index;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
DPRINT1("Failed to find device %ws bRecord %u Count %u\n", CurInfo->DevicePath, bRecord, DeviceCount);
|
||||
|
||||
// HACK
|
||||
if (bRecord)
|
||||
CurInfo->MappedId[0] = 0;
|
||||
else
|
||||
CurInfo->MappedId[1] = 0;
|
||||
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
EnumerateAudioFilter(
|
||||
LPFILTERINFO CurInfo,
|
||||
OUT PULONG WaveInCount,
|
||||
OUT PULONG WaveOutCount)
|
||||
{
|
||||
DWORD Status;
|
||||
ULONG PinCount, WaveInPins, WaveOutPins;
|
||||
|
||||
/* first step open filter */
|
||||
Status = OpenFilter((LPCWSTR)CurInfo->DevicePath, &CurInfo->hFilter);
|
||||
if (Status != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT("Failed to open filter with %lx Path %ws\n", Status, CurInfo->DevicePath);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* get filter pin count */
|
||||
Status = GetFilterPinCount(CurInfo->hFilter, &PinCount);
|
||||
if (Status != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT("Failed to get pin count with %lx\n", Status);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(PinCount);
|
||||
|
||||
/* store pin count */
|
||||
CurInfo->PinCount = PinCount;
|
||||
|
||||
/* now allocate an pin array */
|
||||
CurInfo->Pin = HeapAlloc(GetProcessHeap(), 0, PinCount * sizeof(ULONG));
|
||||
if (!CurInfo->Pin)
|
||||
{
|
||||
/* no memory */
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
/* no try to find playback / recording pins */
|
||||
FindAudioFilterPins(CurInfo, &WaveInPins, &WaveOutPins);
|
||||
|
||||
DPRINT("WaveInPins %u WaveOutPins %u %S\n", WaveInPins, WaveOutPins, CurInfo->DevicePath);
|
||||
|
||||
if (WaveOutPins)
|
||||
{
|
||||
/* create a unique guid for this playback device */
|
||||
if (FindWinMMDeviceIndex(CurInfo, TRUE))
|
||||
{
|
||||
(*WaveOutCount)++;
|
||||
INIT_GUID(CurInfo->DeviceGuid[0], 0xbd6dd71a, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + *WaveInCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (WaveInPins)
|
||||
{
|
||||
if (FindWinMMDeviceIndex(CurInfo, FALSE))
|
||||
{
|
||||
/* create a unique guid for this record device */
|
||||
(*WaveInCount)++;
|
||||
INIT_GUID(CurInfo->DeviceGuid[1], 0xbd6dd71b, 0x3deb, 0x11d1, 0xb1, 0x71, 0x00, 0xc0, 0x4f, 0xc2, 0x00, 0x00 + *WaveOutCount);
|
||||
}
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
EnumAudioDeviceInterfaces(
|
||||
LPFILTERINFO *OutRootInfo)
|
||||
{
|
||||
HDEVINFO hList;
|
||||
DWORD Status;
|
||||
HRESULT hResult;
|
||||
ULONG WaveOutCount, WaveInCount;
|
||||
GUID AudioDeviceGuid = {STATIC_KSCATEGORY_AUDIO};
|
||||
LPFILTERINFO RootInfo = NULL, CurInfo;
|
||||
|
||||
/* try open the device list */
|
||||
Status = OpenDeviceList(&AudioDeviceGuid, &hList);
|
||||
|
||||
if (Status != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT1("OpenDeviceList failed with %lx\n", Status);
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
if (!GetDeviceListInterfaces(hList, &AudioDeviceGuid, &RootInfo))
|
||||
{
|
||||
DPRINT1("No devices found\n");
|
||||
CloseDeviceList(hList);
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(RootInfo);
|
||||
|
||||
CurInfo = RootInfo;
|
||||
|
||||
WaveOutCount = 0;
|
||||
WaveInCount = 0;
|
||||
|
||||
/* now check all audio filters */
|
||||
while(CurInfo)
|
||||
{
|
||||
/* now check details of the audio filter */
|
||||
hResult = EnumerateAudioFilter(CurInfo, &WaveInCount, &WaveOutCount);
|
||||
|
||||
if (hResult != S_OK)
|
||||
{
|
||||
DPRINT1("EnumerateAudioFilter failed with %lx\n", Status);
|
||||
break;
|
||||
}
|
||||
|
||||
/* move to next filter */
|
||||
CurInfo = CurInfo->lpNext;
|
||||
}
|
||||
|
||||
/* close device list */
|
||||
CloseDeviceList(hList);
|
||||
|
||||
/* store result */
|
||||
*OutRootInfo = RootInfo;
|
||||
|
||||
/* done */
|
||||
return hResult;
|
||||
}
|
||||
|
||||
BOOL
|
||||
FindDeviceByMappedId(
|
||||
IN ULONG DeviceID,
|
||||
LPFILTERINFO *Filter,
|
||||
BOOL bPlayback)
|
||||
{
|
||||
LPFILTERINFO CurInfo;
|
||||
if (!RootInfo)
|
||||
return FALSE;
|
||||
|
||||
/* get first entry */
|
||||
CurInfo = RootInfo;
|
||||
|
||||
while(CurInfo)
|
||||
{
|
||||
if ((bPlayback && CurInfo->MappedId[1] == DeviceID) ||
|
||||
(!bPlayback && CurInfo->MappedId[0] == DeviceID))
|
||||
{
|
||||
/* found filter */
|
||||
*Filter = CurInfo;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CurInfo = CurInfo->lpNext;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOL
|
||||
FindDeviceByGuid(
|
||||
LPCGUID pGuidSrc,
|
||||
LPFILTERINFO *Filter)
|
||||
{
|
||||
LPFILTERINFO CurInfo;
|
||||
if (!RootInfo)
|
||||
return FALSE;
|
||||
|
||||
/* get first entry */
|
||||
CurInfo = RootInfo;
|
||||
|
||||
while(CurInfo)
|
||||
{
|
||||
if (IsEqualGUID(&CurInfo->DeviceGuid[0], pGuidSrc) ||
|
||||
IsEqualGUID(&CurInfo->DeviceGuid[1], pGuidSrc))
|
||||
{
|
||||
/* found filter */
|
||||
*Filter = CurInfo;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
CurInfo = CurInfo->lpNext;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
389
reactos/dll/directx/dsound_new/directsound.c
Normal file
389
reactos/dll/directx/dsound_new/directsound.c
Normal file
|
@ -0,0 +1,389 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/directsound.c
|
||||
* PURPOSE: Handles IDirectSound interface
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IDirectSound8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
GUID DeviceGUID;
|
||||
BOOL bInitialized;
|
||||
DWORD dwLevel;
|
||||
LPFILTERINFO Filter;
|
||||
LPDIRECTSOUNDBUFFER8 PrimaryBuffer;
|
||||
|
||||
|
||||
}CDirectSoundImpl, *LPCDirectSoundImpl;
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSound8_fnQueryInterface(
|
||||
LPDIRECTSOUND8 iface,
|
||||
REFIID riid,
|
||||
LPVOID * ppobj)
|
||||
{
|
||||
LPOLESTR pStr;
|
||||
LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl);
|
||||
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IDirectSound) ||
|
||||
IsEqualIID(riid, &IID_IDirectSound8))
|
||||
{
|
||||
*ppobj = (LPVOID)&This->lpVtbl;
|
||||
InterlockedIncrement(&This->ref);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(StringFromIID(riid, &pStr)))
|
||||
{
|
||||
DPRINT("No Interface for class %s\n", pStr);
|
||||
CoTaskMemFree(pStr);
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
IDirectSound8_fnAddRef(
|
||||
LPDIRECTSOUND8 iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl);
|
||||
|
||||
ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
IDirectSound8_fnRelease(
|
||||
LPDIRECTSOUND8 iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl);
|
||||
|
||||
ref = InterlockedDecrement(&(This->ref));
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSound8_fnCreateSoundBuffer(
|
||||
LPDIRECTSOUND8 iface,
|
||||
LPCDSBUFFERDESC lpcDSBufferDesc,
|
||||
LPLPDIRECTSOUNDBUFFER lplpDirectSoundBuffer,
|
||||
IUnknown FAR* pUnkOuter)
|
||||
{
|
||||
HRESULT hResult;
|
||||
LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl);
|
||||
|
||||
if (!This->bInitialized)
|
||||
{
|
||||
/* object not yet initialized */
|
||||
return DSERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
if (!lpcDSBufferDesc || !lplpDirectSoundBuffer || pUnkOuter != NULL)
|
||||
{
|
||||
DPRINT("Invalid parameter %p %p %p\n", lpcDSBufferDesc, lplpDirectSoundBuffer, pUnkOuter);
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* check buffer description */
|
||||
if ((lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC) && lpcDSBufferDesc->dwSize != sizeof(DSBUFFERDESC1)) || lpcDSBufferDesc->dwReserved != 0)
|
||||
{
|
||||
DPRINT("Invalid buffer description size %u expected %u dwReserved %u\n", lpcDSBufferDesc->dwSize, sizeof(DSBUFFERDESC1), lpcDSBufferDesc->dwReserved);
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
DPRINT("This %p dwFlags %x dwBufferBytes %u lpwfxFormat %p dwSize %u\n", This, lpcDSBufferDesc->dwFlags, lpcDSBufferDesc->dwBufferBytes, lpcDSBufferDesc->lpwfxFormat, lpcDSBufferDesc->dwSize);
|
||||
|
||||
if (lpcDSBufferDesc->dwFlags & DSBCAPS_PRIMARYBUFFER)
|
||||
{
|
||||
if (lpcDSBufferDesc->lpwfxFormat != NULL)
|
||||
{
|
||||
/* format must be null for primary sound buffer */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
if (This->PrimaryBuffer)
|
||||
{
|
||||
/* primary buffer already exists */
|
||||
IDirectSoundBuffer8_AddRef(This->PrimaryBuffer);
|
||||
*lplpDirectSoundBuffer = (LPDIRECTSOUNDBUFFER)This->PrimaryBuffer;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
hResult = NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel);
|
||||
if (SUCCEEDED(hResult))
|
||||
{
|
||||
/* store primary buffer */
|
||||
This->PrimaryBuffer = (LPDIRECTSOUNDBUFFER8)*lplpDirectSoundBuffer;
|
||||
}
|
||||
return hResult;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (lpcDSBufferDesc->lpwfxFormat == NULL)
|
||||
{
|
||||
/* format must not be null */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
if (!This->PrimaryBuffer)
|
||||
{
|
||||
hResult = NewPrimarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel);
|
||||
if (SUCCEEDED(hResult))
|
||||
{
|
||||
/* store primary buffer */
|
||||
This->PrimaryBuffer = (LPDIRECTSOUNDBUFFER8)*lplpDirectSoundBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Failed to create primary buffer with %x\n", hResult);
|
||||
return hResult;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
ASSERT(This->PrimaryBuffer);
|
||||
|
||||
DPRINT("This %p wFormatTag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u NBlockAlign %u wBitsPerSample %u cbSize %u\n",
|
||||
This, lpcDSBufferDesc->lpwfxFormat->wFormatTag, lpcDSBufferDesc->lpwfxFormat->nChannels, lpcDSBufferDesc->lpwfxFormat->nSamplesPerSec, lpcDSBufferDesc->lpwfxFormat->nAvgBytesPerSec, lpcDSBufferDesc->lpwfxFormat->nBlockAlign, lpcDSBufferDesc->lpwfxFormat->wBitsPerSample, lpcDSBufferDesc->lpwfxFormat->cbSize);
|
||||
|
||||
hResult = NewSecondarySoundBuffer((LPLPDIRECTSOUNDBUFFER8)lplpDirectSoundBuffer, This->Filter, This->dwLevel, lpcDSBufferDesc, This->PrimaryBuffer);
|
||||
return hResult;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSound8_fnGetCaps(
|
||||
LPDIRECTSOUND8 iface,
|
||||
LPDSCAPS lpDSCaps)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return DSERR_GENERIC;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSound8_fnDuplicateSoundBuffer(
|
||||
LPDIRECTSOUND8 iface,
|
||||
LPDIRECTSOUNDBUFFER lpDsbOriginal,
|
||||
LPLPDIRECTSOUNDBUFFER lplpDsbDuplicate)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSound8_fnSetCooperativeLevel(
|
||||
LPDIRECTSOUND8 iface,
|
||||
HWND hwnd,
|
||||
DWORD dwLevel)
|
||||
{
|
||||
LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl);
|
||||
|
||||
if (!This->bInitialized)
|
||||
{
|
||||
/* object not yet initialized */
|
||||
return DSERR_UNINITIALIZED;
|
||||
}
|
||||
|
||||
/* store cooperation level */
|
||||
This->dwLevel = dwLevel;
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSound8_fnCompact(
|
||||
LPDIRECTSOUND8 iface)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSound8_fnGetSpeakerConfig(
|
||||
LPDIRECTSOUND8 iface,
|
||||
LPDWORD pdwSpeakerConfig)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSound8_fnSetSpeakerConfig(
|
||||
LPDIRECTSOUND8 iface,
|
||||
DWORD dwSpeakerConfig)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSound8_fnInitialize(
|
||||
LPDIRECTSOUND8 iface,
|
||||
LPCGUID pcGuidDevice)
|
||||
{
|
||||
GUID DeviceGuid;
|
||||
LPOLESTR pGuidStr;
|
||||
HRESULT hr;
|
||||
LPCDirectSoundImpl This = (LPCDirectSoundImpl)CONTAINING_RECORD(iface, CDirectSoundImpl, lpVtbl);
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(RootInfo);
|
||||
|
||||
if (This->bInitialized)
|
||||
{
|
||||
/* object has already been initialized */
|
||||
return DSERR_ALREADYINITIALIZED;
|
||||
}
|
||||
|
||||
/* fixme mutual exlucsion */
|
||||
|
||||
if (pcGuidDevice == NULL || IsEqualGUID(pcGuidDevice, &GUID_NULL))
|
||||
{
|
||||
/* use default playback device id */
|
||||
pcGuidDevice = &DSDEVID_DefaultPlayback;
|
||||
}
|
||||
|
||||
/* now verify the guid */
|
||||
if (GetDeviceID(pcGuidDevice, &DeviceGuid) != DS_OK)
|
||||
{
|
||||
if (SUCCEEDED(StringFromIID(pcGuidDevice, &pGuidStr)))
|
||||
{
|
||||
DPRINT("IDirectSound8_fnInitialize: Unknown GUID %ws\n", pGuidStr);
|
||||
CoTaskMemFree(pGuidStr);
|
||||
}
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
hr = FindDeviceByGuid(&DeviceGuid, &This->Filter);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
This->bInitialized = TRUE;
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
DPRINT("Failed to find device\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
IDirectSound8_fnVerifyCertification(
|
||||
LPDIRECTSOUND8 iface,
|
||||
LPDWORD pdwCertified)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return DS_CERTIFIED;
|
||||
}
|
||||
|
||||
static IDirectSound8Vtbl vt_DirectSound8 =
|
||||
{
|
||||
/* IUnknown methods */
|
||||
IDirectSound8_fnQueryInterface,
|
||||
IDirectSound8_fnAddRef,
|
||||
IDirectSound8_fnRelease,
|
||||
/* IDirectSound methods */
|
||||
IDirectSound8_fnCreateSoundBuffer,
|
||||
IDirectSound8_fnGetCaps,
|
||||
IDirectSound8_fnDuplicateSoundBuffer,
|
||||
IDirectSound8_fnSetCooperativeLevel,
|
||||
IDirectSound8_fnCompact,
|
||||
IDirectSound8_fnGetSpeakerConfig,
|
||||
IDirectSound8_fnSetSpeakerConfig,
|
||||
IDirectSound8_fnInitialize,
|
||||
/* IDirectSound8 methods */
|
||||
IDirectSound8_fnVerifyCertification
|
||||
};
|
||||
|
||||
HRESULT
|
||||
InternalDirectSoundCreate(
|
||||
LPCGUID lpcGUID,
|
||||
LPDIRECTSOUND8 *ppDS,
|
||||
IUnknown *pUnkOuter)
|
||||
{
|
||||
LPCDirectSoundImpl This;
|
||||
HRESULT hr;
|
||||
|
||||
if (!ppDS || pUnkOuter != NULL)
|
||||
{
|
||||
/* invalid parameter passed */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* allocate CDirectSoundImpl struct */
|
||||
This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundImpl));
|
||||
if (!This)
|
||||
{
|
||||
/* not enough memory */
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* initialize IDirectSound object */
|
||||
This->ref = 1;
|
||||
This->lpVtbl = &vt_DirectSound8;
|
||||
|
||||
|
||||
/* initialize direct sound interface */
|
||||
hr = IDirectSound8_Initialize((LPDIRECTSOUND8)&This->lpVtbl, lpcGUID);
|
||||
|
||||
/* check for success */
|
||||
if (!SUCCEEDED(hr))
|
||||
{
|
||||
/* failed */
|
||||
DPRINT("Failed to initialize DirectSound object with %x\n", hr);
|
||||
IDirectSound8_Release((LPDIRECTSOUND8)&This->lpVtbl);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/* store result */
|
||||
*ppDS = (LPDIRECTSOUND8)&This->lpVtbl;
|
||||
DPRINT("DirectSound object %p\n", *ppDS);
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DirectSoundCreate(
|
||||
LPCGUID lpcGUID,
|
||||
LPDIRECTSOUND *ppDS,
|
||||
IUnknown *pUnkOuter)
|
||||
{
|
||||
return InternalDirectSoundCreate(lpcGUID, (LPDIRECTSOUND8*)ppDS, pUnkOuter);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DirectSoundCreate8(
|
||||
LPCGUID lpcGUID,
|
||||
LPDIRECTSOUND8 *ppDS,
|
||||
IUnknown *pUnkOuter)
|
||||
{
|
||||
return InternalDirectSoundCreate(lpcGUID, ppDS, pUnkOuter);
|
||||
}
|
180
reactos/dll/directx/dsound_new/dsound.c
Normal file
180
reactos/dll/directx/dsound_new/dsound.c
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/dsound.c
|
||||
* PURPOSE: Handles DSound initialization
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
HINSTANCE dsound_hInstance;
|
||||
LPFILTERINFO RootInfo = NULL;
|
||||
|
||||
static INTERFACE_TABLE InterfaceTable[] =
|
||||
{
|
||||
{
|
||||
&CLSID_DirectSoundPrivate,
|
||||
NewKsPropertySet
|
||||
},
|
||||
{
|
||||
NULL,
|
||||
NULL
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DllCanUnloadNow()
|
||||
{
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
GetDeviceID(LPCGUID pGuidSrc, LPGUID pGuidDest)
|
||||
{
|
||||
ULONG DeviceID = ULONG_MAX, Flags;
|
||||
MMRESULT Result;
|
||||
LPFILTERINFO Filter;
|
||||
|
||||
if (!pGuidSrc || !pGuidDest)
|
||||
{
|
||||
/* invalid param */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(!IsEqualGUID(pGuidSrc, &GUID_NULL));
|
||||
|
||||
if (IsEqualGUID(&DSDEVID_DefaultPlayback, pGuidSrc) ||
|
||||
IsEqualGUID(&DSDEVID_DefaultVoicePlayback, pGuidSrc))
|
||||
{
|
||||
Result = waveOutMessage(UlongToHandle(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&DeviceID, (DWORD_PTR)&Flags);
|
||||
if (Result != MMSYSERR_NOERROR || DeviceID == ULONG_MAX)
|
||||
{
|
||||
/* hack */
|
||||
DPRINT1("Failed to get DRVM_MAPPER_PREFERRED_GET, using device 0\n");
|
||||
DeviceID = 0;
|
||||
}
|
||||
|
||||
if (!FindDeviceByMappedId(DeviceID, &Filter, TRUE))
|
||||
{
|
||||
/* device not found */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* copy device guid */
|
||||
RtlMoveMemory(pGuidDest, &Filter->DeviceGuid[1], sizeof(GUID));
|
||||
return DS_OK;
|
||||
}
|
||||
else if (IsEqualGUID(&DSDEVID_DefaultCapture, pGuidSrc) ||
|
||||
IsEqualGUID(&DSDEVID_DefaultVoiceCapture, pGuidSrc))
|
||||
{
|
||||
Result = waveInMessage(UlongToHandle(WAVE_MAPPER), DRVM_MAPPER_PREFERRED_GET, (DWORD_PTR)&DeviceID, (DWORD_PTR)&Flags);
|
||||
if (Result != MMSYSERR_NOERROR || DeviceID == ULONG_MAX)
|
||||
{
|
||||
/* hack */
|
||||
DPRINT1("Failed to get DRVM_MAPPER_PREFERRED_GET, for record using device 0\n");
|
||||
DeviceID = 0;
|
||||
}
|
||||
|
||||
if (!FindDeviceByMappedId(DeviceID, &Filter, FALSE))
|
||||
{
|
||||
/* device not found */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* copy device guid */
|
||||
RtlMoveMemory(pGuidDest, &Filter->DeviceGuid[0], sizeof(GUID));
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
if (!FindDeviceByGuid(pGuidSrc, &Filter))
|
||||
{
|
||||
/* unknown guid */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* done */
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DllGetClassObject(
|
||||
REFCLSID rclsid,
|
||||
REFIID riid,
|
||||
LPVOID* ppv
|
||||
)
|
||||
{
|
||||
LPOLESTR pStr, pStr2;
|
||||
UINT i;
|
||||
HRESULT hres = E_OUTOFMEMORY;
|
||||
IClassFactory * pcf = NULL;
|
||||
|
||||
if (!ppv)
|
||||
return E_INVALIDARG;
|
||||
|
||||
*ppv = NULL;
|
||||
|
||||
for (i = 0; InterfaceTable[i].riid; i++)
|
||||
{
|
||||
if (IsEqualIID(InterfaceTable[i].riid, rclsid))
|
||||
{
|
||||
pcf = IClassFactory_fnConstructor(InterfaceTable[i].lpfnCI, NULL, NULL);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!pcf)
|
||||
{
|
||||
StringFromIID(rclsid, &pStr);
|
||||
StringFromIID(riid, &pStr2);
|
||||
DPRINT("No Class Available for %ws IID %ws\n", pStr, pStr2);
|
||||
CoTaskMemFree(pStr);
|
||||
CoTaskMemFree(pStr2);
|
||||
ASSERT(0);
|
||||
return CLASS_E_CLASSNOTAVAILABLE;
|
||||
}
|
||||
|
||||
hres = IClassFactory_QueryInterface(pcf, riid, ppv);
|
||||
IClassFactory_Release(pcf);
|
||||
|
||||
return hres;
|
||||
}
|
||||
|
||||
|
||||
|
||||
BOOL
|
||||
WINAPI
|
||||
DllMain(
|
||||
HINSTANCE hInstDLL,
|
||||
DWORD fdwReason,
|
||||
LPVOID lpvReserved)
|
||||
{
|
||||
switch (fdwReason)
|
||||
{
|
||||
case DLL_PROCESS_ATTACH:
|
||||
dsound_hInstance = hInstDLL;
|
||||
#if 0
|
||||
DPRINT("NumDevs %u\n", waveOutGetNumDevs());
|
||||
if (EnumAudioDeviceInterfaces(&RootInfo) != S_OK)
|
||||
{
|
||||
DPRINT("EnumAudioDeviceInterfaces failed\n");
|
||||
RootInfo = NULL;
|
||||
}
|
||||
DPRINT1("EnumAudioDeviceInterfaces %p %u\n", RootInfo, waveOutGetNumDevs());
|
||||
#endif
|
||||
DisableThreadLibraryCalls(dsound_hInstance);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
14
reactos/dll/directx/dsound_new/dsound.spec
Normal file
14
reactos/dll/directx/dsound_new/dsound.spec
Normal file
|
@ -0,0 +1,14 @@
|
|||
1 stdcall DirectSoundCreate(ptr ptr ptr)
|
||||
2 stdcall DirectSoundEnumerateA(ptr ptr)
|
||||
3 stdcall DirectSoundEnumerateW(ptr ptr)
|
||||
6 stdcall DirectSoundCaptureCreate(ptr ptr ptr)
|
||||
7 stdcall DirectSoundCaptureEnumerateA(ptr ptr)
|
||||
8 stdcall DirectSoundCaptureEnumerateW(ptr ptr)
|
||||
9 stdcall GetDeviceID(ptr ptr)
|
||||
10 stdcall DirectSoundFullDuplexCreate(ptr ptr ptr ptr long long ptr ptr ptr ptr)
|
||||
11 stdcall DirectSoundCreate8(ptr ptr ptr)
|
||||
12 stdcall DirectSoundCaptureCreate8(ptr ptr ptr)
|
||||
@ stdcall -private DllCanUnloadNow()
|
||||
@ stdcall -private DllGetClassObject(ptr ptr ptr)
|
||||
@ stdcall -private DllRegisterServer()
|
||||
@ stdcall -private DllUnregisterServer()
|
31
reactos/dll/directx/dsound_new/dsound_new.rbuild
Normal file
31
reactos/dll/directx/dsound_new/dsound_new.rbuild
Normal file
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd">
|
||||
<module name="dsound" type="win32dll" baseaddress="${BASEADDRESS_DSOUND}" installbase="system32" installname="dsound.dll" crt="msvcrt">
|
||||
<autoregister infsection="OleControlDlls" type="DllRegisterServer" />
|
||||
<importlibrary definition="dsound.spec" />
|
||||
<include base="dsound">.</include>
|
||||
<library>uuid</library>
|
||||
<library>ntdll</library>
|
||||
<library>kernel32</library>
|
||||
<library>user32</library>
|
||||
<library>advapi32</library>
|
||||
<library>ole32</library>
|
||||
<library>winmm</library>
|
||||
<library>dxguid</library>
|
||||
<library>setupapi</library>
|
||||
<library>ksuser</library>
|
||||
<file>capture.c</file>
|
||||
<file>capturebuffer.c</file>
|
||||
<file>classfactory.c</file>
|
||||
<file>devicelist.c</file>
|
||||
<file>directsound.c</file>
|
||||
<file>dsound.c</file>
|
||||
<file>enum.c</file>
|
||||
<file>misc.c</file>
|
||||
<file>primary.c</file>
|
||||
<file>property.c</file>
|
||||
<file>regsvr.c</file>
|
||||
<file>secondary.c</file>
|
||||
<file>stubs.c</file>
|
||||
<file>version.rc</file>
|
||||
</module>
|
229
reactos/dll/directx/dsound_new/enum.c
Normal file
229
reactos/dll/directx/dsound_new/enum.c
Normal file
|
@ -0,0 +1,229 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/enum.c
|
||||
* PURPOSE: Handles DSound device enumeration
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
VOID
|
||||
LoadResourceString(
|
||||
UINT ResourceId,
|
||||
LPVOID Buffer,
|
||||
UINT ccount,
|
||||
LPVOID DefaultString,
|
||||
BOOL bUnicode)
|
||||
{
|
||||
if (bUnicode)
|
||||
{
|
||||
/* load localized string */
|
||||
if (!LoadStringW(dsound_hInstance, ResourceId, (LPWSTR)Buffer, ccount))
|
||||
{
|
||||
/* default device name */
|
||||
wcscpy((LPWSTR)Buffer, (LPWSTR)DefaultString);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* load localized string */
|
||||
if (!LoadStringA(dsound_hInstance, ResourceId, (LPSTR)Buffer, ccount))
|
||||
{
|
||||
/* default device name */
|
||||
strcpy((LPSTR)Buffer, (LPSTR)DefaultString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BOOL
|
||||
DoDSoundCallback(
|
||||
LPDSENUMCALLBACKA lpDSEnumCallbackA,
|
||||
LPDSENUMCALLBACKW lpDSEnumCallbackW,
|
||||
LPGUID DeviceGuid,
|
||||
UINT ResourceId,
|
||||
LPWSTR ProductName,
|
||||
LPWSTR DriverName,
|
||||
LPVOID lpContext)
|
||||
{
|
||||
WCHAR Buffer[200] = {0};
|
||||
char DriverNameA[200];
|
||||
|
||||
static LPWSTR SoundDriverW = L"Primary Sound Driver";
|
||||
static LPWSTR SoundDriverA = L"Primary Sound Driver";
|
||||
|
||||
if (lpDSEnumCallbackW)
|
||||
{
|
||||
if (ResourceId)
|
||||
{
|
||||
/* load resource string */
|
||||
Buffer[0] = 0;
|
||||
LoadResourceString(ResourceId, (LPVOID)Buffer, sizeof(Buffer)/sizeof(WCHAR), (LPVOID)SoundDriverW, TRUE);
|
||||
Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = '\0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use passed string */
|
||||
ASSERT(ProductName);
|
||||
wcscpy(Buffer, ProductName);
|
||||
}
|
||||
|
||||
/* perform callback */
|
||||
return lpDSEnumCallbackW(DeviceGuid, Buffer, DriverName, lpContext);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ResourceId)
|
||||
{
|
||||
/* load resource string */
|
||||
Buffer[0] = 0;
|
||||
LoadResourceString(ResourceId, (LPVOID)Buffer, sizeof(Buffer)/sizeof(char), (LPVOID)SoundDriverA, FALSE);
|
||||
Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use passed string */
|
||||
Buffer[0] = 0;
|
||||
WideCharToMultiByte(CP_ACP, 0, ProductName, -1, (LPSTR)Buffer, sizeof(Buffer) / sizeof(char), NULL, NULL);
|
||||
Buffer[(sizeof(Buffer)/sizeof(WCHAR))-1] = 0;
|
||||
}
|
||||
|
||||
DriverNameA[0] = 0;
|
||||
WideCharToMultiByte(CP_ACP, 0, ProductName, -1, DriverNameA, sizeof(DriverNameA) / sizeof(char), NULL, NULL);
|
||||
|
||||
return lpDSEnumCallbackA(DeviceGuid, (LPSTR)Buffer, DriverNameA, lpContext);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
DSoundEnumerate(
|
||||
LPDSENUMCALLBACKA lpDSEnumCallbackA,
|
||||
LPDSENUMCALLBACKW lpDSEnumCallbackW,
|
||||
LPVOID lpContext,
|
||||
BOOL bPlayback)
|
||||
{
|
||||
ULONG ResourceId;
|
||||
BOOL bResult;
|
||||
LPFILTERINFO CurInfo;
|
||||
WAVEOUTCAPSW WaveOutCaps;
|
||||
WAVEINCAPSW WaveInCaps;
|
||||
|
||||
if (!RootInfo)
|
||||
{
|
||||
EnumAudioDeviceInterfaces(&RootInfo);
|
||||
}
|
||||
|
||||
if (lpDSEnumCallbackA == NULL && lpDSEnumCallbackW == NULL)
|
||||
{
|
||||
DPRINT("No callback\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
if (bPlayback)
|
||||
{
|
||||
/* use resource id of playback string */
|
||||
ResourceId = IDS_PRIMARY_PLAYBACK_DEVICE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use resource id of playback string */
|
||||
ResourceId = IDS_PRIMARY_RECORD_DEVICE;
|
||||
}
|
||||
|
||||
if (RootInfo)
|
||||
{
|
||||
/* perform first callback */
|
||||
bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, NULL, ResourceId, NULL, L"", lpContext);
|
||||
if (!bResult)
|
||||
{
|
||||
/* callback asked as to stop */
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
/* now iterate through all devices */
|
||||
CurInfo = RootInfo;
|
||||
|
||||
do
|
||||
{
|
||||
if (bPlayback && !IsEqualGUID(&CurInfo->DeviceGuid[1], &GUID_NULL))
|
||||
{
|
||||
RtlZeroMemory(&WaveOutCaps, sizeof(WAVEOUTCAPSW));
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(CurInfo->MappedId[1] != ULONG_MAX);
|
||||
|
||||
/* get wave out caps */
|
||||
waveOutGetDevCapsW((UINT_PTR)CurInfo->MappedId[1], &WaveOutCaps, sizeof(WAVEOUTCAPSW));
|
||||
WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0';
|
||||
|
||||
bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, &CurInfo->DeviceGuid[1], 0, WaveOutCaps.szPname, L"" /* FIXME */, lpContext);
|
||||
if (!bResult)
|
||||
{
|
||||
/* callback asked as to stop */
|
||||
return DS_OK;
|
||||
}
|
||||
}
|
||||
else if (!bPlayback && !IsEqualGUID(&CurInfo->DeviceGuid[0], &GUID_NULL))
|
||||
{
|
||||
RtlZeroMemory(&WaveInCaps, sizeof(WAVEINCAPSW));
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(CurInfo->MappedId[1] != ULONG_MAX);
|
||||
|
||||
/* get wave in caps */
|
||||
waveInGetDevCapsW((UINT_PTR)CurInfo->MappedId[0], &WaveInCaps, sizeof(WAVEINCAPSW));
|
||||
WaveInCaps.szPname[MAXPNAMELEN-1] = L'\0';
|
||||
|
||||
bResult = DoDSoundCallback(lpDSEnumCallbackA, lpDSEnumCallbackW, &CurInfo->DeviceGuid[0], 0, WaveInCaps.szPname, L"" /* FIXME */, lpContext);
|
||||
if (!bResult)
|
||||
{
|
||||
/* callback asked as to stop */
|
||||
return DS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
/* move to next entry */
|
||||
CurInfo = CurInfo->lpNext;
|
||||
}while(CurInfo);
|
||||
}
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DirectSoundEnumerateA(
|
||||
LPDSENUMCALLBACKA lpDSEnumCallback,
|
||||
LPVOID lpContext)
|
||||
{
|
||||
return DSoundEnumerate(lpDSEnumCallback, NULL, lpContext, TRUE);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DirectSoundEnumerateW(
|
||||
LPDSENUMCALLBACKW lpDSEnumCallback,
|
||||
LPVOID lpContext )
|
||||
{
|
||||
return DSoundEnumerate(NULL, lpDSEnumCallback, lpContext, TRUE);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DirectSoundCaptureEnumerateA(
|
||||
LPDSENUMCALLBACKA lpDSEnumCallback,
|
||||
LPVOID lpContext)
|
||||
{
|
||||
return DSoundEnumerate(lpDSEnumCallback, NULL, lpContext, FALSE);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DirectSoundCaptureEnumerateW(
|
||||
LPDSENUMCALLBACKW lpDSEnumCallback,
|
||||
LPVOID lpContext)
|
||||
{
|
||||
return DSoundEnumerate(NULL, lpDSEnumCallback, lpContext, FALSE);
|
||||
}
|
316
reactos/dll/directx/dsound_new/misc.c
Normal file
316
reactos/dll/directx/dsound_new/misc.c
Normal file
|
@ -0,0 +1,316 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/misc.c
|
||||
* PURPOSE: Misc support routines
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
const GUID KSPROPSETID_Pin = {0x8C134960L, 0x51AD, 0x11CF, {0x87, 0x8A, 0x94, 0xF8, 0x01, 0xC1, 0x00, 0x00}};
|
||||
const GUID KSPROPSETID_Topology = {0x720D4AC0L, 0x7533, 0x11D0, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
|
||||
const GUID KSPROPSETID_Audio = {0x45FFAAA0L, 0x6E1B, 0x11D0, {0xBC, 0xF2, 0x44, 0x45, 0x53, 0x54, 0x00, 0x00}};
|
||||
|
||||
DWORD
|
||||
OpenPin(
|
||||
HANDLE hFilter,
|
||||
ULONG PinId,
|
||||
LPWAVEFORMATEX WaveFormatEx,
|
||||
PHANDLE hPin,
|
||||
BOOL bLoop)
|
||||
{
|
||||
DWORD Size, Result;
|
||||
PKSPIN_CONNECT PinConnect;
|
||||
PKSDATAFORMAT_WAVEFORMATEX DataFormat;
|
||||
|
||||
/* calculate request size */
|
||||
Size = sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX);
|
||||
|
||||
PinConnect = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, Size);
|
||||
if (!PinConnect)
|
||||
{
|
||||
/* not enough memory */
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
/* build pin request */
|
||||
PinConnect->Interface.Set = KSINTERFACESETID_Standard;
|
||||
|
||||
if (bLoop)
|
||||
PinConnect->Interface.Id = KSINTERFACE_STANDARD_LOOPED_STREAMING;
|
||||
else
|
||||
PinConnect->Interface.Id = KSINTERFACE_STANDARD_STREAMING;
|
||||
|
||||
PinConnect->Interface.Flags = 0;
|
||||
PinConnect->Medium.Set = KSMEDIUMSETID_Standard;
|
||||
PinConnect->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
|
||||
PinConnect->Medium.Flags = 0;
|
||||
PinConnect->PinToHandle = NULL;
|
||||
PinConnect->PinId = PinId;
|
||||
PinConnect->Priority.PriorityClass = KSPRIORITY_NORMAL;
|
||||
PinConnect->Priority.PrioritySubClass = 1;
|
||||
|
||||
DataFormat = (PKSDATAFORMAT_WAVEFORMATEX) (PinConnect + 1);
|
||||
|
||||
/* initialize data format */
|
||||
DataFormat->WaveFormatEx.wFormatTag = WaveFormatEx->wFormatTag;
|
||||
DataFormat->WaveFormatEx.nChannels = WaveFormatEx->nChannels;
|
||||
DataFormat->WaveFormatEx.nSamplesPerSec = WaveFormatEx->nSamplesPerSec;
|
||||
DataFormat->WaveFormatEx.nBlockAlign = WaveFormatEx->nBlockAlign;
|
||||
DataFormat->WaveFormatEx.nAvgBytesPerSec = WaveFormatEx->nAvgBytesPerSec;
|
||||
DataFormat->WaveFormatEx.wBitsPerSample = WaveFormatEx->wBitsPerSample;
|
||||
DataFormat->WaveFormatEx.cbSize = 0;
|
||||
DataFormat->DataFormat.FormatSize = sizeof(KSDATAFORMAT) + sizeof(WAVEFORMATEX);
|
||||
DataFormat->DataFormat.Flags = 0;
|
||||
DataFormat->DataFormat.Reserved = 0;
|
||||
DataFormat->DataFormat.MajorFormat = KSDATAFORMAT_TYPE_AUDIO;
|
||||
|
||||
DataFormat->DataFormat.SubFormat = KSDATAFORMAT_SUBTYPE_PCM;
|
||||
DataFormat->DataFormat.Specifier = KSDATAFORMAT_SPECIFIER_WAVEFORMATEX;
|
||||
DataFormat->DataFormat.SampleSize = 4;
|
||||
|
||||
Result = KsCreatePin(hFilter, PinConnect, GENERIC_READ | GENERIC_WRITE, hPin);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, PinConnect);
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
||||
DWORD
|
||||
OpenFilter(
|
||||
IN LPCWSTR lpFileName,
|
||||
IN PHANDLE OutHandle)
|
||||
{
|
||||
HANDLE Handle;
|
||||
|
||||
/* open the filter */
|
||||
Handle = CreateFileW(lpFileName, GENERIC_WRITE | GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);
|
||||
|
||||
/* check for success */
|
||||
if (Handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DPRINT("Failed to open Filter %ws\n", lpFileName);
|
||||
return GetLastError();
|
||||
}
|
||||
|
||||
*OutHandle = Handle;
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD
|
||||
SyncOverlappedDeviceIoControl(
|
||||
IN HANDLE Handle,
|
||||
IN DWORD IoControlCode,
|
||||
IN LPVOID InBuffer,
|
||||
IN DWORD InBufferSize,
|
||||
OUT LPVOID OutBuffer,
|
||||
IN DWORD OutBufferSize,
|
||||
OUT LPDWORD BytesTransferred OPTIONAL)
|
||||
{
|
||||
OVERLAPPED Overlapped;
|
||||
BOOLEAN IoResult;
|
||||
DWORD Transferred;
|
||||
|
||||
/* Overlapped I/O is done here - this is used for waiting for completion */
|
||||
ZeroMemory(&Overlapped, sizeof(OVERLAPPED));
|
||||
Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
if (!Overlapped.hEvent)
|
||||
return GetLastError();
|
||||
|
||||
/* Talk to the device */
|
||||
IoResult = DeviceIoControl(Handle,
|
||||
IoControlCode,
|
||||
InBuffer,
|
||||
InBufferSize,
|
||||
OutBuffer,
|
||||
OutBufferSize,
|
||||
BytesTransferred,
|
||||
&Overlapped);
|
||||
|
||||
/* If failure occurs, make sure it's not just due to the overlapped I/O */
|
||||
if (!IoResult)
|
||||
{
|
||||
if ( GetLastError() != ERROR_IO_PENDING )
|
||||
{
|
||||
CloseHandle(Overlapped.hEvent);
|
||||
return GetLastError();
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait for the I/O to complete */
|
||||
IoResult = GetOverlappedResult(Handle,
|
||||
&Overlapped,
|
||||
&Transferred,
|
||||
TRUE);
|
||||
|
||||
/* Don't need this any more */
|
||||
CloseHandle(Overlapped.hEvent);
|
||||
|
||||
if (!IoResult)
|
||||
return GetLastError();
|
||||
|
||||
if ( BytesTransferred )
|
||||
*BytesTransferred = Transferred;
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD
|
||||
GetFilterPinCount(
|
||||
IN HANDLE hFilter,
|
||||
OUT PULONG NumPins)
|
||||
{
|
||||
KSPROPERTY Pin;
|
||||
|
||||
*NumPins = 0;
|
||||
|
||||
/* setup the pin request */
|
||||
Pin.Flags = KSPROPERTY_TYPE_GET;
|
||||
Pin.Set = KSPROPSETID_Pin;
|
||||
Pin.Id = KSPROPERTY_PIN_CTYPES;
|
||||
|
||||
/* query the device */
|
||||
return SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Pin, sizeof(KSPROPERTY), (PVOID)NumPins, sizeof(ULONG), NULL);
|
||||
}
|
||||
|
||||
DWORD
|
||||
GetFilterNodeProperty(
|
||||
IN HANDLE hFilter,
|
||||
IN ULONG PropertyId,
|
||||
OUT PKSMULTIPLE_ITEM *OutMultipleItem)
|
||||
{
|
||||
DWORD Status, BytesReturned;
|
||||
PKSMULTIPLE_ITEM MultipleItem;
|
||||
KSPROPERTY Property;
|
||||
|
||||
/* setup query request */
|
||||
Property.Id = PropertyId;
|
||||
Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
Property.Set = KSPROPSETID_Topology;
|
||||
|
||||
/* query the size */
|
||||
Status = SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSPROPERTY), NULL, 0, &BytesReturned);
|
||||
|
||||
if (Status != ERROR_MORE_DATA)
|
||||
{
|
||||
/* failed */
|
||||
DPRINT("Failed to query PropertyId %lu ErrorCode %lx\n", PropertyId, Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
MultipleItem = HeapAlloc(GetProcessHeap(), 0, BytesReturned);
|
||||
if (!MultipleItem)
|
||||
{
|
||||
/* not enough memory */
|
||||
DPRINT("Failed to allocate %u Bytes\n", BytesReturned);
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* retrieve data ranges */
|
||||
Status = SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSP_PIN), (LPVOID)MultipleItem, BytesReturned, &BytesReturned);
|
||||
|
||||
|
||||
if (Status != ERROR_SUCCESS)
|
||||
{
|
||||
/* failed to get data ranges */
|
||||
DPRINT("SyncOverlappedDeviceIoControl failed with %lx\n", Status);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, MultipleItem);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* save result */
|
||||
*OutMultipleItem = MultipleItem;
|
||||
return Status;
|
||||
|
||||
}
|
||||
|
||||
DWORD
|
||||
GetFilterPinCommunication(
|
||||
IN HANDLE hFilter,
|
||||
IN ULONG PinId,
|
||||
OUT PKSPIN_COMMUNICATION Communication)
|
||||
{
|
||||
KSP_PIN Property;
|
||||
|
||||
Property.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
Property.Property.Set = KSPROPSETID_Pin;
|
||||
Property.Property.Id = KSPROPERTY_PIN_COMMUNICATION;
|
||||
Property.PinId = PinId;
|
||||
Property.Reserved = 0;
|
||||
|
||||
return SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSP_PIN), (LPVOID)Communication, sizeof(KSPIN_COMMUNICATION), NULL);
|
||||
}
|
||||
|
||||
DWORD
|
||||
GetFilterPinDataFlow(
|
||||
IN HANDLE hFilter,
|
||||
IN ULONG PinId,
|
||||
OUT PKSPIN_DATAFLOW DataFlow)
|
||||
{
|
||||
KSP_PIN Property;
|
||||
|
||||
Property.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
Property.Property.Set = KSPROPSETID_Pin;
|
||||
Property.Property.Id = KSPROPERTY_PIN_DATAFLOW;
|
||||
Property.PinId = PinId;
|
||||
Property.Reserved = 0;
|
||||
|
||||
return SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSP_PIN), (LPVOID)DataFlow, sizeof(KSPIN_DATAFLOW), NULL);
|
||||
}
|
||||
|
||||
DWORD
|
||||
GetFilterPinDataRanges(
|
||||
IN HANDLE hFilter,
|
||||
IN ULONG PinId,
|
||||
IN OUT PKSMULTIPLE_ITEM * OutMultipleItem)
|
||||
{
|
||||
KSP_PIN Property;
|
||||
ULONG BytesReturned = 0;
|
||||
DWORD Status;
|
||||
PKSMULTIPLE_ITEM MultipleItem;
|
||||
|
||||
/* prepare request */
|
||||
Property.Reserved = 0;
|
||||
Property.PinId = PinId;
|
||||
Property.Property.Set = KSPROPSETID_Pin;
|
||||
Property.Property.Id = KSPROPERTY_PIN_DATARANGES;
|
||||
Property.Property.Flags = KSPROPERTY_TYPE_GET;
|
||||
|
||||
/* retrieve size of data ranges buffer */
|
||||
Status = SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSP_PIN), NULL, 0, &BytesReturned);
|
||||
|
||||
if (Status != ERROR_MORE_DATA)
|
||||
{
|
||||
DPRINT("SyncOverlappedDeviceIoControl failed with %lx\n", Status);
|
||||
return Status;
|
||||
}
|
||||
|
||||
MultipleItem = HeapAlloc(GetProcessHeap(), 0, BytesReturned);
|
||||
if (!MultipleItem)
|
||||
{
|
||||
/* not enough memory */
|
||||
DPRINT("Failed to allocate %u Bytes\n", BytesReturned);
|
||||
return ERROR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* retrieve data ranges */
|
||||
Status = SyncOverlappedDeviceIoControl(hFilter, IOCTL_KS_PROPERTY, (LPVOID)&Property, sizeof(KSP_PIN), (LPVOID)MultipleItem, BytesReturned, &BytesReturned);
|
||||
|
||||
|
||||
if (Status != ERROR_SUCCESS)
|
||||
{
|
||||
/* failed to get data ranges */
|
||||
DPRINT("SyncOverlappedDeviceIoControl failed with %lx\n", Status);
|
||||
|
||||
HeapFree(GetProcessHeap(), 0, MultipleItem);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* save result */
|
||||
*OutMultipleItem = MultipleItem;
|
||||
return Status;
|
||||
}
|
209
reactos/dll/directx/dsound_new/precomp.h
Normal file
209
reactos/dll/directx/dsound_new/precomp.h
Normal file
|
@ -0,0 +1,209 @@
|
|||
#ifndef PRECOMP_H__
|
||||
#define PRECOMP_H__
|
||||
|
||||
#define COBJMACROS
|
||||
#define NONAMELESSUNION
|
||||
#define NONAMELESSSTRUCT
|
||||
|
||||
#include <windows.h>
|
||||
#include <setupapi.h>
|
||||
#include <mmddk.h>
|
||||
#include <objbase.h>
|
||||
#include <olectl.h>
|
||||
#include <unknwn.h>
|
||||
#include <dsound.h>
|
||||
#include <dsconf.h>
|
||||
#include <vfwmsgs.h>
|
||||
#include <setupapi.h>
|
||||
#define YDEBUG
|
||||
#include <debug.h>
|
||||
#include <ks.h>
|
||||
#include <ksmedia.h>
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "resource.h"
|
||||
|
||||
|
||||
/* factory method */
|
||||
typedef HRESULT (CALLBACK *LPFNCREATEINSTANCE)(IUnknown* pUnkOuter, REFIID riid, LPVOID* ppvObject);
|
||||
|
||||
/* factory table */
|
||||
typedef struct
|
||||
{
|
||||
REFIID riid;
|
||||
LPFNCREATEINSTANCE lpfnCI;
|
||||
} INTERFACE_TABLE;
|
||||
|
||||
|
||||
typedef struct tagFILTERINFO
|
||||
{
|
||||
SP_DEVINFO_DATA DeviceData;
|
||||
WCHAR DevicePath[MAX_PATH];
|
||||
HANDLE hFilter;
|
||||
ULONG PinCount;
|
||||
PULONG Pin;
|
||||
GUID DeviceGuid[2];
|
||||
ULONG MappedId[2];
|
||||
|
||||
struct tagFILTERINFO *lpNext;
|
||||
}FILTERINFO, *LPFILTERINFO;
|
||||
|
||||
#define INIT_GUID(guid, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
|
||||
guid.Data1 = l; guid.Data2 = w1; guid.Data3 = w2; \
|
||||
guid.Data4[0] = b1; guid.Data4[1] = b2; guid.Data4[2] = b3; \
|
||||
guid.Data4[3] = b4; guid.Data4[4] = b5; guid.Data4[5] = b6; \
|
||||
guid.Data4[6] = b7; guid.Data4[7] = b8;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
PIN_TYPE_NONE = 0,
|
||||
PIN_TYPE_PLAYBACK = 1,
|
||||
PIN_TYPE_RECORDING = 2
|
||||
}PIN_TYPE;
|
||||
|
||||
/* globals */
|
||||
extern HINSTANCE dsound_hInstance;
|
||||
extern LPFILTERINFO RootInfo;
|
||||
|
||||
/* classfactory.c */
|
||||
|
||||
IClassFactory *
|
||||
IClassFactory_fnConstructor(
|
||||
LPFNCREATEINSTANCE lpfnCI,
|
||||
PLONG pcRefDll,
|
||||
REFIID riidInst);
|
||||
|
||||
|
||||
/* devicelist.c */
|
||||
|
||||
HRESULT
|
||||
EnumAudioDeviceInterfaces(
|
||||
LPFILTERINFO *OutRootInfo);
|
||||
|
||||
BOOL
|
||||
FindDeviceByGuid(
|
||||
LPCGUID pGuidSrc,
|
||||
LPFILTERINFO *Filter);
|
||||
|
||||
BOOL
|
||||
FindDeviceByMappedId(
|
||||
IN ULONG DeviceID,
|
||||
LPFILTERINFO *Filter,
|
||||
BOOL bPlayback);
|
||||
|
||||
ULONG
|
||||
GetPinIdFromFilter(
|
||||
LPFILTERINFO Filter,
|
||||
BOOL bCapture,
|
||||
ULONG Offset);
|
||||
|
||||
|
||||
/* misc.c */
|
||||
|
||||
DWORD
|
||||
SyncOverlappedDeviceIoControl(
|
||||
IN HANDLE Handle,
|
||||
IN DWORD IoControlCode,
|
||||
IN LPVOID InBuffer,
|
||||
IN DWORD InBufferSize,
|
||||
OUT LPVOID OutBuffer,
|
||||
IN DWORD OutBufferSize,
|
||||
OUT LPDWORD BytesTransferred OPTIONAL);
|
||||
|
||||
DWORD
|
||||
PrimaryDirectSoundBuffer_Write(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPVOID Buffer,
|
||||
DWORD BufferSize);
|
||||
|
||||
|
||||
DWORD
|
||||
OpenPin(
|
||||
HANDLE hFilter,
|
||||
ULONG PinId,
|
||||
LPWAVEFORMATEX WaveFormatEx,
|
||||
PHANDLE hPin,
|
||||
BOOL bLoop);
|
||||
|
||||
DWORD
|
||||
OpenFilter(
|
||||
IN LPCWSTR lpFileName,
|
||||
IN PHANDLE OutHandle);
|
||||
|
||||
DWORD
|
||||
GetFilterPinCount(
|
||||
IN HANDLE hFilter,
|
||||
OUT PULONG NumPins);
|
||||
|
||||
DWORD
|
||||
GetFilterPinCommunication(
|
||||
IN HANDLE hFilter,
|
||||
IN ULONG PinId,
|
||||
OUT PKSPIN_COMMUNICATION Communication);
|
||||
|
||||
DWORD
|
||||
GetFilterPinDataFlow(
|
||||
IN HANDLE hFilter,
|
||||
IN ULONG PinId,
|
||||
OUT PKSPIN_DATAFLOW DataFlow);
|
||||
|
||||
/* primary.c */
|
||||
|
||||
HRESULT
|
||||
PrimaryDirectSoundBuffer_GetPosition(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDWORD pdwCurrentPlayCursor,
|
||||
LPDWORD pdwCurrentWriteCursor);
|
||||
|
||||
VOID
|
||||
PrimaryDirectSoundBuffer_SetState(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
KSSTATE State);
|
||||
|
||||
HRESULT
|
||||
NewPrimarySoundBuffer(
|
||||
LPDIRECTSOUNDBUFFER8 *OutBuffer,
|
||||
LPFILTERINFO Filter,
|
||||
DWORD dwLevel);
|
||||
|
||||
HRESULT
|
||||
PrimaryDirectSoundBuffer_SetFormat(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPWAVEFORMATEX pcfxFormat,
|
||||
BOOL bLooped);
|
||||
|
||||
VOID
|
||||
PrimaryDirectSoundBuffer_AcquireLock(
|
||||
LPDIRECTSOUNDBUFFER8 iface);
|
||||
|
||||
VOID
|
||||
PrimaryDirectSoundBuffer_ReleaseLock(
|
||||
LPDIRECTSOUNDBUFFER8 iface);
|
||||
|
||||
/* secondary.c */
|
||||
|
||||
HRESULT
|
||||
NewSecondarySoundBuffer(
|
||||
LPDIRECTSOUNDBUFFER8 *OutBuffer,
|
||||
LPFILTERINFO Filter,
|
||||
DWORD dwLevel,
|
||||
LPCDSBUFFERDESC lpcDSBufferDesc,
|
||||
LPDIRECTSOUNDBUFFER8 PrimaryBuffer);
|
||||
|
||||
/* property.c */
|
||||
HRESULT
|
||||
CALLBACK
|
||||
NewKsPropertySet(
|
||||
IUnknown* pUnkOuter,
|
||||
REFIID riid,
|
||||
LPVOID* ppvObject);
|
||||
|
||||
/* capturebuffer.c */
|
||||
HRESULT
|
||||
NewDirectSoundCaptureBuffer(
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 *OutBuffer,
|
||||
LPFILTERINFO Filter,
|
||||
LPCDSCBUFFERDESC lpcDSBufferDesc);
|
||||
|
||||
#endif
|
595
reactos/dll/directx/dsound_new/primary.c
Normal file
595
reactos/dll/directx/dsound_new/primary.c
Normal file
|
@ -0,0 +1,595 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/primary.c
|
||||
* PURPOSE: Primary IDirectSoundBuffer8 implementation
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const IDirectSoundBuffer8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
LPFILTERINFO Filter;
|
||||
DWORD dwLevel;
|
||||
WAVEFORMATEX Format;
|
||||
HANDLE hPin;
|
||||
CRITICAL_SECTION Lock;
|
||||
KSSTATE State;
|
||||
}CDirectSoundBuffer, *LPCDirectSoundBuffer;
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnQueryInterface(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
IN REFIID riid,
|
||||
LPVOID* ppobj)
|
||||
{
|
||||
LPOLESTR pStr;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IDirectSoundBuffer) ||
|
||||
IsEqualIID(riid, &IID_IDirectSoundBuffer8))
|
||||
{
|
||||
*ppobj = (LPVOID)&This->lpVtbl;
|
||||
InterlockedIncrement(&This->ref);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(StringFromIID(riid, &pStr)))
|
||||
{
|
||||
DPRINT("No Interface for class %s\n", pStr);
|
||||
CoTaskMemFree(pStr);
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnAddRef(
|
||||
LPDIRECTSOUNDBUFFER8 iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
return ref;
|
||||
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnRelease(
|
||||
LPDIRECTSOUNDBUFFER8 iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
ref = InterlockedDecrement(&(This->ref));
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetCaps(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDSBCAPS pDSBufferCaps)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDWORD pdwCurrentPlayCursor,
|
||||
LPDWORD pdwCurrentWriteCursor)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetFormat(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPWAVEFORMATEX pwfxFormat,
|
||||
DWORD dwSizeAllocated,
|
||||
LPDWORD pdwSizeWritten)
|
||||
{
|
||||
DWORD FormatSize;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
FormatSize = sizeof(WAVEFORMATEX) + This->Format.cbSize;
|
||||
|
||||
if (!pwfxFormat && !pdwSizeWritten)
|
||||
{
|
||||
/* invalid parameter */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
if (!pwfxFormat)
|
||||
{
|
||||
/* return required format size */
|
||||
*pdwSizeWritten = FormatSize;
|
||||
return DS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dwSizeAllocated >= FormatSize)
|
||||
{
|
||||
/* copy format */
|
||||
CopyMemory(pwfxFormat, &This->Format, FormatSize);
|
||||
|
||||
if (pdwSizeWritten)
|
||||
*pdwSizeWritten = FormatSize;
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
/* buffer too small */
|
||||
if (pdwSizeWritten)
|
||||
*pdwSizeWritten = 0;
|
||||
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetVolume(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPLONG plVolume)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetPan(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPLONG plPan)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetFrequency(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDWORD pdwFrequency)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetStatus(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDWORD pdwStatus)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnInitialize(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDIRECTSOUND pDirectSound,
|
||||
LPCDSBUFFERDESC pcDSBufferDesc)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnLock(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwOffset,
|
||||
DWORD dwBytes,
|
||||
LPVOID *ppvAudioPtr1,
|
||||
LPDWORD pdwAudioBytes1,
|
||||
LPVOID *ppvAudioPtr2,
|
||||
LPDWORD pdwAudioBytes2,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnPlay(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwReserved1,
|
||||
DWORD dwPriority,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwNewPosition)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetFormat(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPCWAVEFORMATEX pcfxFormat)
|
||||
{
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
if (This->dwLevel == DSSCL_NORMAL)
|
||||
{
|
||||
/* can't change format with this level */
|
||||
return DSERR_PRIOLEVELNEEDED;
|
||||
}
|
||||
|
||||
ASSERT(pcfxFormat->cbSize == 0);
|
||||
|
||||
|
||||
DPRINT("This %p Format: Tag %x nChannels %u nSamplesPerSec %u nAvgBytesPerSec %u nBlockAlign %u wBitsPerSample %u cbSize %u\n", This,
|
||||
pcfxFormat->wFormatTag, pcfxFormat->nChannels, pcfxFormat->nSamplesPerSec, pcfxFormat->nAvgBytesPerSec, pcfxFormat->nBlockAlign, pcfxFormat->wBitsPerSample, pcfxFormat->cbSize);
|
||||
|
||||
CopyMemory(&This->Format, pcfxFormat, sizeof(WAVEFORMATEX));
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetVolume(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LONG lVolume)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetPan(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LONG lPan)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetFrequency(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwFrequency)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnStop(
|
||||
LPDIRECTSOUNDBUFFER8 iface)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnUnlock(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPVOID pvAudioPtr1,
|
||||
DWORD dwAudioBytes1,
|
||||
LPVOID pvAudioPtr2,
|
||||
DWORD dwAudioBytes2)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnRestore(
|
||||
LPDIRECTSOUNDBUFFER8 iface)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetFX(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwEffectsCount,
|
||||
LPDSEFFECTDESC pDSFXDesc,
|
||||
LPDWORD pdwResultCodes)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnAcquireResources(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwFlags,
|
||||
DWORD dwEffectsCount,
|
||||
LPDWORD pdwResultCodes)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
REFGUID rguidObject,
|
||||
DWORD dwIndex,
|
||||
REFGUID rguidInterface,
|
||||
LPVOID *ppObject)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8 =
|
||||
{
|
||||
/* IUnknown methods */
|
||||
PrimaryDirectSoundBuffer8Impl_fnQueryInterface,
|
||||
PrimaryDirectSoundBuffer8Impl_fnAddRef,
|
||||
PrimaryDirectSoundBuffer8Impl_fnRelease,
|
||||
/* IDirectSoundBuffer methods */
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetCaps,
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetCurrentPosition,
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetFormat,
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetVolume,
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetPan,
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetFrequency,
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetStatus,
|
||||
PrimaryDirectSoundBuffer8Impl_fnInitialize,
|
||||
PrimaryDirectSoundBuffer8Impl_fnLock,
|
||||
PrimaryDirectSoundBuffer8Impl_fnPlay,
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetCurrentPosition,
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetFormat,
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetVolume,
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetPan,
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetFrequency,
|
||||
PrimaryDirectSoundBuffer8Impl_fnStop,
|
||||
PrimaryDirectSoundBuffer8Impl_fnUnlock,
|
||||
PrimaryDirectSoundBuffer8Impl_fnRestore,
|
||||
/* IDirectSoundBuffer8 methods */
|
||||
PrimaryDirectSoundBuffer8Impl_fnSetFX,
|
||||
PrimaryDirectSoundBuffer8Impl_fnAcquireResources,
|
||||
PrimaryDirectSoundBuffer8Impl_fnGetObjectInPath
|
||||
};
|
||||
|
||||
DWORD
|
||||
PrimaryDirectSoundBuffer_Write(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPVOID Buffer,
|
||||
DWORD BufferSize)
|
||||
{
|
||||
KSSTREAM_HEADER Header;
|
||||
DWORD Result, BytesTransferred;
|
||||
OVERLAPPED Overlapped;
|
||||
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
ZeroMemory(&Overlapped, sizeof(OVERLAPPED));
|
||||
Overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||
|
||||
|
||||
ASSERT(This->hPin);
|
||||
ZeroMemory(&Header, sizeof(KSSTREAM_HEADER));
|
||||
|
||||
Header.FrameExtent = BufferSize;
|
||||
Header.DataUsed = BufferSize;
|
||||
Header.Data = Buffer;
|
||||
Header.Size = sizeof(KSSTREAM_HEADER);
|
||||
Header.PresentationTime.Numerator = 1;
|
||||
Header.PresentationTime.Denominator = 1;
|
||||
|
||||
Result = DeviceIoControl(This->hPin, IOCTL_KS_WRITE_STREAM, NULL, 0, &Header, sizeof(KSSTREAM_HEADER), &BytesTransferred, &Overlapped);
|
||||
|
||||
if (Result != ERROR_SUCCESS)
|
||||
return 0;
|
||||
|
||||
return BytesTransferred;
|
||||
}
|
||||
|
||||
VOID
|
||||
PrimaryDirectSoundBuffer_SetState(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
KSSTATE State)
|
||||
{
|
||||
KSPROPERTY Property;
|
||||
DWORD Result, BytesTransferred;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
if (This->State == State)
|
||||
return;
|
||||
|
||||
Property.Set = KSPROPSETID_Connection;
|
||||
Property.Id = KSPROPERTY_CONNECTION_STATE;
|
||||
Property.Flags = KSPROPERTY_TYPE_SET;
|
||||
|
||||
Result = SyncOverlappedDeviceIoControl(This->hPin, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesTransferred);
|
||||
if (Result == ERROR_SUCCESS)
|
||||
{
|
||||
This->State = State;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
PrimaryDirectSoundBuffer_GetPosition(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDWORD pdwCurrentPlayCursor,
|
||||
LPDWORD pdwCurrentWriteCursor)
|
||||
{
|
||||
KSAUDIO_POSITION Position;
|
||||
KSPROPERTY Request;
|
||||
DWORD Result;
|
||||
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
if (!This->hPin)
|
||||
{
|
||||
if (pdwCurrentPlayCursor)
|
||||
*pdwCurrentPlayCursor = 0;
|
||||
|
||||
if (pdwCurrentWriteCursor)
|
||||
*pdwCurrentWriteCursor = 0;
|
||||
|
||||
DPRINT("No Audio Pin\n");
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
/* setup audio position property request */
|
||||
Request.Id = KSPROPERTY_AUDIO_POSITION;
|
||||
Request.Set = KSPROPSETID_Audio;
|
||||
Request.Flags = KSPROPERTY_TYPE_GET;
|
||||
|
||||
|
||||
Result = SyncOverlappedDeviceIoControl(This->hPin, IOCTL_KS_PROPERTY, (PVOID)&Request, sizeof(KSPROPERTY), (PVOID)&Position, sizeof(KSAUDIO_POSITION), NULL);
|
||||
|
||||
if (Result != ERROR_SUCCESS)
|
||||
{
|
||||
DPRINT("GetPosition failed with %x\n", Result);
|
||||
return DSERR_UNSUPPORTED;
|
||||
}
|
||||
|
||||
//DPRINT("Play %I64u Write %I64u \n", Position.PlayOffset, Position.WriteOffset);
|
||||
|
||||
if (pdwCurrentPlayCursor)
|
||||
*pdwCurrentPlayCursor = (DWORD)Position.PlayOffset;
|
||||
|
||||
if (pdwCurrentWriteCursor)
|
||||
*pdwCurrentWriteCursor = (DWORD)Position.WriteOffset;
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
PrimaryDirectSoundBuffer_SetFormat(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPWAVEFORMATEX pcfxFormat,
|
||||
BOOL bLooped)
|
||||
{
|
||||
ULONG PinId, DeviceId = 0, Result;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
if (This->hPin)
|
||||
{
|
||||
/* fixme change format */
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
/* try all available recording pins on that filter */
|
||||
PinId = GetPinIdFromFilter(This->Filter, FALSE, DeviceId);
|
||||
DPRINT("PinId %u DeviceId %u\n", PinId, DeviceId);
|
||||
|
||||
if (PinId == ULONG_MAX)
|
||||
break;
|
||||
|
||||
Result = OpenPin(This->Filter->hFilter, PinId, (LPWAVEFORMATEX)pcfxFormat, &This->hPin, bLooped);
|
||||
DPRINT("PinId %u Result %u\n", PinId, Result);
|
||||
if (Result == ERROR_SUCCESS)
|
||||
break;
|
||||
|
||||
This->hPin = NULL;
|
||||
DeviceId++;
|
||||
}while(TRUE);
|
||||
|
||||
if (!This->hPin)
|
||||
{
|
||||
DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat failed\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
DPRINT("PrimaryDirectSoundBuffer8Impl_fnSetFormat success\n");
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
VOID
|
||||
PrimaryDirectSoundBuffer_AcquireLock(
|
||||
LPDIRECTSOUNDBUFFER8 iface)
|
||||
{
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
EnterCriticalSection(&This->Lock);
|
||||
|
||||
|
||||
}
|
||||
|
||||
VOID
|
||||
PrimaryDirectSoundBuffer_ReleaseLock(
|
||||
LPDIRECTSOUNDBUFFER8 iface)
|
||||
{
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
LeaveCriticalSection(&This->Lock);
|
||||
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
NewPrimarySoundBuffer(
|
||||
LPDIRECTSOUNDBUFFER8 *OutBuffer,
|
||||
LPFILTERINFO Filter,
|
||||
DWORD dwLevel)
|
||||
{
|
||||
LPCDirectSoundBuffer This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundBuffer));
|
||||
|
||||
if (!This)
|
||||
{
|
||||
/* not enough memory */
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
This->ref = 1;
|
||||
This->lpVtbl = &vt_DirectSoundBuffer8;
|
||||
This->Filter = Filter;
|
||||
This->dwLevel = dwLevel;
|
||||
This->hPin = NULL;
|
||||
|
||||
InitializeCriticalSection(&This->Lock);
|
||||
|
||||
*OutBuffer = (LPDIRECTSOUNDBUFFER8)&This->lpVtbl;
|
||||
return DS_OK;
|
||||
}
|
||||
|
273
reactos/dll/directx/dsound_new/property.c
Normal file
273
reactos/dll/directx/dsound_new/property.c
Normal file
|
@ -0,0 +1,273 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/secondary.c
|
||||
* PURPOSE: Secondary IDirectSoundBuffer8 implementation
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
IKsPropertySetVtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
}CKsPropertySetImpl, *LPCKsPropertySetImpl;
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
KSPropertySetImpl_fnQueryInterface(
|
||||
LPKSPROPERTYSET iface,
|
||||
REFIID riid,
|
||||
LPVOID * ppobj)
|
||||
{
|
||||
LPOLESTR pStr;
|
||||
LPCKsPropertySetImpl This = (LPCKsPropertySetImpl)CONTAINING_RECORD(iface, CKsPropertySetImpl, lpVtbl);
|
||||
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IKsPropertySet))
|
||||
{
|
||||
*ppobj = (LPVOID)&This->lpVtbl;
|
||||
InterlockedIncrement(&This->ref);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(StringFromIID(riid, &pStr)))
|
||||
{
|
||||
DPRINT("No Interface for riid %s\n", pStr);
|
||||
CoTaskMemFree(pStr);
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
KSPropertySetImpl_fnAddRef(
|
||||
LPKSPROPERTYSET iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCKsPropertySetImpl This = (LPCKsPropertySetImpl)CONTAINING_RECORD(iface, CKsPropertySetImpl, lpVtbl);
|
||||
|
||||
ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
KSPropertySetImpl_fnRelease(
|
||||
LPKSPROPERTYSET iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCKsPropertySetImpl This = (LPCKsPropertySetImpl)CONTAINING_RECORD(iface, CKsPropertySetImpl, lpVtbl);
|
||||
|
||||
ref = InterlockedDecrement(&(This->ref));
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
KSPropertySetImpl_Get(
|
||||
LPKSPROPERTYSET iface,
|
||||
REFGUID guidPropSet,
|
||||
ULONG dwPropID,
|
||||
LPVOID pInstanceData,
|
||||
ULONG cbInstanceData,
|
||||
LPVOID pPropData,
|
||||
ULONG cbPropData,
|
||||
PULONG pcbReturned )
|
||||
{
|
||||
LPOLESTR pStr;
|
||||
//HRESULT hr;
|
||||
MMRESULT Result;
|
||||
WAVEINCAPSW CapsIn;
|
||||
WAVEOUTCAPSW CapsOut;
|
||||
|
||||
GUID DeviceGuid;
|
||||
LPFILTERINFO Filter = NULL;
|
||||
PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA Desc;
|
||||
|
||||
StringFromIID(guidPropSet, &pStr);
|
||||
|
||||
//DPRINT("Requested Property %ws dwPropID %u pInstanceData %p cbInstanceData %u pPropData %p cbPropData %u pcbReturned %p\n",
|
||||
// pStr, dwPropID, pInstanceData, cbInstanceData, pPropData, cbPropData, pcbReturned);
|
||||
CoTaskMemFree(pStr);
|
||||
|
||||
if (!IsEqualGUID(guidPropSet, &DSPROPSETID_DirectSoundDevice))
|
||||
{
|
||||
/* unsupported property set */
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (dwPropID == DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1)
|
||||
{
|
||||
if (cbPropData < sizeof(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA))
|
||||
{
|
||||
/* invalid parameter */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
Desc = (PDSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA)pPropData;
|
||||
|
||||
if (IsEqualGUID(&Desc->DeviceId, &GUID_NULL))
|
||||
{
|
||||
if (Desc->DataFlow == DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE)
|
||||
{
|
||||
DPRINT("Using default capture guid\n");
|
||||
CopyMemory(&DeviceGuid, &DSDEVID_DefaultCapture, sizeof(GUID));
|
||||
}
|
||||
else
|
||||
{
|
||||
DPRINT("Using default capture guid\n");
|
||||
CopyMemory(&DeviceGuid, &DSDEVID_DefaultPlayback, sizeof(GUID));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* use provided guid */
|
||||
CopyMemory(&DeviceGuid, &Desc->DeviceId, sizeof(GUID));
|
||||
}
|
||||
|
||||
if (GetDeviceID(&DeviceGuid, &Desc->DeviceId) != DS_OK)
|
||||
{
|
||||
DPRINT("Unknown device guid\n");
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(FindDeviceByGuid(&Desc->DeviceId, &Filter));
|
||||
ASSERT(Filter != NULL);
|
||||
|
||||
/* fill in description */
|
||||
if (IsEqualGUID(&Desc->DeviceId, &Filter->DeviceGuid[0]))
|
||||
{
|
||||
/* capture device */
|
||||
Desc->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_CAPTURE;
|
||||
Desc->WaveDeviceId = Filter->MappedId[0];
|
||||
|
||||
Result = waveInGetDevCapsW(Filter->MappedId[0], &CapsIn, sizeof(WAVEINCAPSW));
|
||||
if (Result != MMSYSERR_NOERROR)
|
||||
{
|
||||
CapsIn.szPname[0] = 0;
|
||||
DPRINT("waveInGetDevCaps Device %u failed with %x\n", Filter->MappedId[0], Result);
|
||||
}
|
||||
|
||||
CapsIn.szPname[MAXPNAMELEN-1] = 0;
|
||||
wcscpy(Desc->DescriptionW, CapsIn.szPname);
|
||||
WideCharToMultiByte(CP_ACP, 0, CapsIn.szPname, -1, Desc->DescriptionA, sizeof(Desc->DescriptionA), NULL, NULL);
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
/* render device */
|
||||
Desc->DataFlow = DIRECTSOUNDDEVICE_DATAFLOW_RENDER;
|
||||
Desc->WaveDeviceId = Filter->MappedId[1];
|
||||
|
||||
Result = waveOutGetDevCapsW(Filter->MappedId[1], &CapsOut, sizeof(WAVEOUTCAPSW));
|
||||
if (Result != MMSYSERR_NOERROR)
|
||||
{
|
||||
CapsOut.szPname[0] = 0;
|
||||
DPRINT("waveOutGetDevCaps Device %u failed with %x\n", Filter->MappedId[1], Result);
|
||||
}
|
||||
|
||||
CapsOut.szPname[MAXPNAMELEN-1] = 0;
|
||||
wcscpy(Desc->DescriptionW, CapsOut.szPname);
|
||||
WideCharToMultiByte(CP_ACP, 0, CapsOut.szPname, -1, Desc->DescriptionA, sizeof(Desc->DescriptionA), NULL, NULL);
|
||||
}
|
||||
|
||||
/* ReactOS doesnt support vxd or emulated */
|
||||
Desc->Type = DIRECTSOUNDDEVICE_TYPE_WDM;
|
||||
Desc->ModuleA[0] = 0;
|
||||
Desc->ModuleW[0] = 0;
|
||||
|
||||
*pcbReturned = sizeof(DSPROPERTY_DIRECTSOUNDDEVICE_DESCRIPTION_1_DATA);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
|
||||
UNIMPLEMENTED
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
KSPropertySetImpl_Set(
|
||||
LPKSPROPERTYSET iface,
|
||||
REFGUID guidPropSet,
|
||||
ULONG dwPropID,
|
||||
LPVOID pInstanceData,
|
||||
ULONG cbInstanceData,
|
||||
LPVOID pPropData,
|
||||
ULONG cbPropData )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
KSPropertySetImpl_QuerySupport(
|
||||
LPKSPROPERTYSET iface,
|
||||
REFGUID guidPropSet,
|
||||
ULONG dwPropID,
|
||||
PULONG pTypeSupport )
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return E_PROP_ID_UNSUPPORTED;
|
||||
}
|
||||
|
||||
static IKsPropertySetVtbl vt_KsPropertySet =
|
||||
{
|
||||
/* IUnknown methods */
|
||||
KSPropertySetImpl_fnQueryInterface,
|
||||
KSPropertySetImpl_fnAddRef,
|
||||
KSPropertySetImpl_fnRelease,
|
||||
/* IKsPropertySet methods */
|
||||
KSPropertySetImpl_Get,
|
||||
KSPropertySetImpl_Set,
|
||||
KSPropertySetImpl_QuerySupport
|
||||
};
|
||||
|
||||
HRESULT
|
||||
CALLBACK
|
||||
NewKsPropertySet(
|
||||
IUnknown* pUnkOuter,
|
||||
REFIID riid,
|
||||
LPVOID* ppvObject)
|
||||
{
|
||||
LPOLESTR pStr;
|
||||
LPCKsPropertySetImpl This;
|
||||
|
||||
/* check requested interface */
|
||||
if (!IsEqualIID(riid, &IID_IUnknown) && !IsEqualIID(riid, &IID_IKsPropertySet))
|
||||
{
|
||||
*ppvObject = 0;
|
||||
StringFromIID(riid, &pStr);
|
||||
DPRINT("KsPropertySet does not support Interface %ws\n", pStr);
|
||||
CoTaskMemFree(pStr);
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
/* allocate object */
|
||||
This = HeapAlloc(GetProcessHeap(), 0, sizeof(CKsPropertySetImpl));
|
||||
if (!This)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
/* initialize object */
|
||||
This->ref = 1;
|
||||
This->lpVtbl = &vt_KsPropertySet;
|
||||
*ppvObject = (LPVOID)&This->lpVtbl;
|
||||
|
||||
return S_OK;
|
||||
}
|
511
reactos/dll/directx/dsound_new/regsvr.c
Normal file
511
reactos/dll/directx/dsound_new/regsvr.c
Normal file
|
@ -0,0 +1,511 @@
|
|||
/*
|
||||
* self-registerable dll functions for dsound.dll
|
||||
*
|
||||
* Copyright (C) 2003 John K. Hohm
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
static LSTATUS (WINAPI *pRegDeleteTreeW)(HKEY,LPCWSTR);
|
||||
static LSTATUS (WINAPI *pRegDeleteTreeA)(HKEY,LPCSTR);
|
||||
|
||||
/*
|
||||
* Near the bottom of this file are the exported DllRegisterServer and
|
||||
* DllUnregisterServer, which make all this worthwhile.
|
||||
*/
|
||||
|
||||
/***********************************************************************
|
||||
* interface for self-registering
|
||||
*/
|
||||
struct regsvr_interface
|
||||
{
|
||||
IID const *iid; /* NULL for end of list */
|
||||
LPCSTR name; /* can be NULL to omit */
|
||||
IID const *base_iid; /* can be NULL to omit */
|
||||
int num_methods; /* can be <0 to omit */
|
||||
CLSID const *ps_clsid; /* can be NULL to omit */
|
||||
CLSID const *ps_clsid32; /* can be NULL to omit */
|
||||
};
|
||||
|
||||
static HRESULT register_interfaces(struct regsvr_interface const *list);
|
||||
static HRESULT unregister_interfaces(struct regsvr_interface const *list);
|
||||
|
||||
struct regsvr_coclass
|
||||
{
|
||||
CLSID const *clsid; /* NULL for end of list */
|
||||
LPCSTR name; /* can be NULL to omit */
|
||||
LPCSTR ips; /* can be NULL to omit */
|
||||
LPCSTR ips32; /* can be NULL to omit */
|
||||
LPCSTR ips32_tmodel; /* can be NULL to omit */
|
||||
LPCSTR progid; /* can be NULL to omit */
|
||||
LPCSTR viprogid; /* can be NULL to omit */
|
||||
LPCSTR progid_extra; /* can be NULL to omit */
|
||||
};
|
||||
|
||||
static HRESULT register_coclasses(struct regsvr_coclass const *list);
|
||||
static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
|
||||
|
||||
/***********************************************************************
|
||||
* static string constants
|
||||
*/
|
||||
static WCHAR const interface_keyname[10] = {
|
||||
'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
|
||||
static WCHAR const base_ifa_keyname[14] = {
|
||||
'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
|
||||
'e', 0 };
|
||||
static WCHAR const num_methods_keyname[11] = {
|
||||
'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
|
||||
static WCHAR const ps_clsid_keyname[15] = {
|
||||
'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
|
||||
'i', 'd', 0 };
|
||||
static WCHAR const ps_clsid32_keyname[17] = {
|
||||
'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
|
||||
'i', 'd', '3', '2', 0 };
|
||||
static WCHAR const clsid_keyname[6] = {
|
||||
'C', 'L', 'S', 'I', 'D', 0 };
|
||||
static WCHAR const curver_keyname[7] = {
|
||||
'C', 'u', 'r', 'V', 'e', 'r', 0 };
|
||||
static WCHAR const ips_keyname[13] = {
|
||||
'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
|
||||
0 };
|
||||
static WCHAR const ips32_keyname[15] = {
|
||||
'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
|
||||
'3', '2', 0 };
|
||||
static WCHAR const progid_keyname[7] = {
|
||||
'P', 'r', 'o', 'g', 'I', 'D', 0 };
|
||||
static WCHAR const viprogid_keyname[25] = {
|
||||
'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
|
||||
'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
|
||||
0 };
|
||||
static char const tmodel_valuename[] = "ThreadingModel";
|
||||
|
||||
/***********************************************************************
|
||||
* static helper functions
|
||||
*/
|
||||
static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
|
||||
static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
|
||||
WCHAR const *value);
|
||||
static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
|
||||
char const *value);
|
||||
static LONG register_progid(WCHAR const *clsid,
|
||||
char const *progid, char const *curver_progid,
|
||||
char const *name, char const *extra);
|
||||
|
||||
/***********************************************************************
|
||||
* register_interfaces
|
||||
*/
|
||||
static HRESULT register_interfaces(struct regsvr_interface const *list)
|
||||
{
|
||||
LONG res = ERROR_SUCCESS;
|
||||
HKEY interface_key;
|
||||
|
||||
res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_return;
|
||||
|
||||
for (; res == ERROR_SUCCESS && list->iid; ++list) {
|
||||
WCHAR buf[39];
|
||||
HKEY iid_key;
|
||||
|
||||
StringFromGUID2(list->iid, buf, 39);
|
||||
res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_close_interface_key;
|
||||
|
||||
if (list->name) {
|
||||
res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
|
||||
(CONST BYTE*)(list->name),
|
||||
strlen(list->name) + 1);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
if (list->base_iid) {
|
||||
res = register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
if (0 <= list->num_methods) {
|
||||
static WCHAR const fmt[3] = { '%', 'd', 0 };
|
||||
HKEY key;
|
||||
|
||||
res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
|
||||
swprintf(buf, fmt, list->num_methods);
|
||||
res = RegSetValueExW(key, NULL, 0, REG_SZ,
|
||||
(CONST BYTE*)buf,
|
||||
(lstrlenW(buf) + 1) * sizeof(WCHAR));
|
||||
RegCloseKey(key);
|
||||
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
if (list->ps_clsid) {
|
||||
res = register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
if (list->ps_clsid32) {
|
||||
res = register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
|
||||
if (res != ERROR_SUCCESS) goto error_close_iid_key;
|
||||
}
|
||||
|
||||
error_close_iid_key:
|
||||
RegCloseKey(iid_key);
|
||||
}
|
||||
|
||||
error_close_interface_key:
|
||||
RegCloseKey(interface_key);
|
||||
error_return:
|
||||
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* unregister_interfaces
|
||||
*/
|
||||
static HRESULT unregister_interfaces(struct regsvr_interface const *list)
|
||||
{
|
||||
LONG res = ERROR_SUCCESS;
|
||||
HKEY interface_key;
|
||||
|
||||
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
|
||||
KEY_READ | KEY_WRITE, &interface_key);
|
||||
if (res == ERROR_FILE_NOT_FOUND) return S_OK;
|
||||
if (res != ERROR_SUCCESS) goto error_return;
|
||||
|
||||
for (; res == ERROR_SUCCESS && list->iid; ++list) {
|
||||
WCHAR buf[39];
|
||||
|
||||
StringFromGUID2(list->iid, buf, 39);
|
||||
res = pRegDeleteTreeW(interface_key, buf);
|
||||
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
RegCloseKey(interface_key);
|
||||
error_return:
|
||||
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* register_coclasses
|
||||
*/
|
||||
static HRESULT register_coclasses(struct regsvr_coclass const *list)
|
||||
{
|
||||
LONG res = ERROR_SUCCESS;
|
||||
HKEY coclass_key;
|
||||
|
||||
res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_return;
|
||||
|
||||
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
|
||||
WCHAR buf[39];
|
||||
HKEY clsid_key;
|
||||
|
||||
StringFromGUID2(list->clsid, buf, 39);
|
||||
res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
|
||||
|
||||
if (list->name) {
|
||||
res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
|
||||
(CONST BYTE*)(list->name),
|
||||
strlen(list->name) + 1);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
}
|
||||
|
||||
if (list->ips) {
|
||||
res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
}
|
||||
|
||||
if (list->ips32) {
|
||||
HKEY ips32_key;
|
||||
|
||||
res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL,
|
||||
&ips32_key, NULL);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
|
||||
res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
|
||||
(CONST BYTE*)list->ips32,
|
||||
lstrlenA(list->ips32) + 1);
|
||||
if (res == ERROR_SUCCESS && list->ips32_tmodel)
|
||||
res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
|
||||
(CONST BYTE*)list->ips32_tmodel,
|
||||
strlen(list->ips32_tmodel) + 1);
|
||||
RegCloseKey(ips32_key);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
}
|
||||
|
||||
if (list->progid) {
|
||||
res = register_key_defvalueA(clsid_key, progid_keyname,
|
||||
list->progid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
|
||||
res = register_progid(buf, list->progid, NULL,
|
||||
list->name, list->progid_extra);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
}
|
||||
|
||||
if (list->viprogid) {
|
||||
res = register_key_defvalueA(clsid_key, viprogid_keyname,
|
||||
list->viprogid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
|
||||
res = register_progid(buf, list->viprogid, list->progid,
|
||||
list->name, list->progid_extra);
|
||||
if (res != ERROR_SUCCESS) goto error_close_clsid_key;
|
||||
}
|
||||
|
||||
error_close_clsid_key:
|
||||
RegCloseKey(clsid_key);
|
||||
}
|
||||
|
||||
error_close_coclass_key:
|
||||
RegCloseKey(coclass_key);
|
||||
error_return:
|
||||
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* unregister_coclasses
|
||||
*/
|
||||
static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
|
||||
{
|
||||
LONG res = ERROR_SUCCESS;
|
||||
HKEY coclass_key;
|
||||
|
||||
res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
|
||||
KEY_READ | KEY_WRITE, &coclass_key);
|
||||
if (res == ERROR_FILE_NOT_FOUND) return S_OK;
|
||||
if (res != ERROR_SUCCESS) goto error_return;
|
||||
|
||||
for (; res == ERROR_SUCCESS && list->clsid; ++list) {
|
||||
WCHAR buf[39];
|
||||
|
||||
StringFromGUID2(list->clsid, buf, 39);
|
||||
res = pRegDeleteTreeW(coclass_key, buf);
|
||||
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
|
||||
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
|
||||
|
||||
if (list->progid) {
|
||||
res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->progid);
|
||||
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
|
||||
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
|
||||
}
|
||||
|
||||
if (list->viprogid) {
|
||||
res = pRegDeleteTreeA(HKEY_CLASSES_ROOT, list->viprogid);
|
||||
if (res == ERROR_FILE_NOT_FOUND) res = ERROR_SUCCESS;
|
||||
if (res != ERROR_SUCCESS) goto error_close_coclass_key;
|
||||
}
|
||||
}
|
||||
|
||||
error_close_coclass_key:
|
||||
RegCloseKey(coclass_key);
|
||||
error_return:
|
||||
return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* regsvr_key_guid
|
||||
*/
|
||||
static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
|
||||
{
|
||||
WCHAR buf[39];
|
||||
|
||||
StringFromGUID2(guid, buf, 39);
|
||||
return register_key_defvalueW(base, name, buf);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* regsvr_key_defvalueW
|
||||
*/
|
||||
static LONG register_key_defvalueW(
|
||||
HKEY base,
|
||||
WCHAR const *name,
|
||||
WCHAR const *value)
|
||||
{
|
||||
LONG res;
|
||||
HKEY key;
|
||||
|
||||
res = RegCreateKeyExW(base, name, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &key, NULL);
|
||||
if (res != ERROR_SUCCESS) return res;
|
||||
res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
|
||||
(lstrlenW(value) + 1) * sizeof(WCHAR));
|
||||
RegCloseKey(key);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* regsvr_key_defvalueA
|
||||
*/
|
||||
static LONG register_key_defvalueA(
|
||||
HKEY base,
|
||||
WCHAR const *name,
|
||||
char const *value)
|
||||
{
|
||||
LONG res;
|
||||
HKEY key;
|
||||
|
||||
res = RegCreateKeyExW(base, name, 0, NULL, 0,
|
||||
KEY_READ | KEY_WRITE, NULL, &key, NULL);
|
||||
if (res != ERROR_SUCCESS) return res;
|
||||
res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
|
||||
lstrlenA(value) + 1);
|
||||
RegCloseKey(key);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* regsvr_progid
|
||||
*/
|
||||
static LONG register_progid(
|
||||
WCHAR const *clsid,
|
||||
char const *progid,
|
||||
char const *curver_progid,
|
||||
char const *name,
|
||||
char const *extra)
|
||||
{
|
||||
LONG res;
|
||||
HKEY progid_key;
|
||||
|
||||
res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
|
||||
NULL, 0, KEY_READ | KEY_WRITE, NULL,
|
||||
&progid_key, NULL);
|
||||
if (res != ERROR_SUCCESS) return res;
|
||||
|
||||
if (name) {
|
||||
res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
|
||||
(CONST BYTE*)name, strlen(name) + 1);
|
||||
if (res != ERROR_SUCCESS) goto error_close_progid_key;
|
||||
}
|
||||
|
||||
if (clsid) {
|
||||
res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_progid_key;
|
||||
}
|
||||
|
||||
if (curver_progid) {
|
||||
res = register_key_defvalueA(progid_key, curver_keyname,
|
||||
curver_progid);
|
||||
if (res != ERROR_SUCCESS) goto error_close_progid_key;
|
||||
}
|
||||
|
||||
if (extra) {
|
||||
HKEY extra_key;
|
||||
|
||||
res = RegCreateKeyExA(progid_key, extra, 0,
|
||||
NULL, 0, KEY_READ | KEY_WRITE, NULL,
|
||||
&extra_key, NULL);
|
||||
if (res == ERROR_SUCCESS)
|
||||
RegCloseKey(extra_key);
|
||||
}
|
||||
|
||||
error_close_progid_key:
|
||||
RegCloseKey(progid_key);
|
||||
return res;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* coclass list
|
||||
*/
|
||||
static GUID const CLSID_DirectSoundBufferConfig = {
|
||||
0xB2F586D4, 0x5558, 0x49D1, {0xA0,0x7B,0x32,0x49,0xDB,0xBB,0x33,0xC2} };
|
||||
|
||||
static struct regsvr_coclass const coclass_list[] = {
|
||||
{ &CLSID_DirectSound,
|
||||
"DirectSound Object",
|
||||
NULL,
|
||||
"dsound.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_DirectSound8,
|
||||
"DirectSound 8.0 Object",
|
||||
NULL,
|
||||
"dsound.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_DirectSoundBufferConfig,
|
||||
"DirectSoundBufferConfig Object",
|
||||
NULL,
|
||||
"dsound.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_DirectSoundCapture,
|
||||
"DirectSoundCapture Object",
|
||||
NULL,
|
||||
"dsound.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_DirectSoundCapture8,
|
||||
"DirectSoundCapture 8.0 Object",
|
||||
NULL,
|
||||
"dsound.dll",
|
||||
"Both"
|
||||
},
|
||||
{ &CLSID_DirectSoundFullDuplex,
|
||||
"DirectSoundFullDuplex Object",
|
||||
NULL,
|
||||
"dsound.dll",
|
||||
"Both"
|
||||
},
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* interface list
|
||||
*/
|
||||
|
||||
static struct regsvr_interface const interface_list[] = {
|
||||
{ NULL } /* list terminator */
|
||||
};
|
||||
|
||||
/***********************************************************************
|
||||
* DllRegisterServer (DSOUND.@)
|
||||
*/
|
||||
HRESULT WINAPI DllRegisterServer(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
hr = register_coclasses(coclass_list);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = register_interfaces(interface_list);
|
||||
return hr;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllUnregisterServer (DSOUND.@)
|
||||
*/
|
||||
HRESULT WINAPI DllUnregisterServer(void)
|
||||
{
|
||||
HRESULT hr;
|
||||
|
||||
HMODULE advapi32 = GetModuleHandleA("advapi32");
|
||||
if (!advapi32) return E_FAIL;
|
||||
pRegDeleteTreeA = (void *) GetProcAddress(advapi32, "RegDeleteTreeA");
|
||||
pRegDeleteTreeW = (void *) GetProcAddress(advapi32, "RegDeleteTreeW");
|
||||
if (!pRegDeleteTreeA || !pRegDeleteTreeW) return E_FAIL;
|
||||
|
||||
hr = unregister_coclasses(coclass_list);
|
||||
if (SUCCEEDED(hr))
|
||||
hr = unregister_interfaces(interface_list);
|
||||
return hr;
|
||||
}
|
16
reactos/dll/directx/dsound_new/resource.h
Normal file
16
reactos/dll/directx/dsound_new/resource.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef RESOURCE_H__
|
||||
#define RESOURCE_H__
|
||||
|
||||
#define IDS_PRIMARY_PLAYBACK_DEVICE 100
|
||||
#define IDS_PRIMARY_RECORD_DEVICE 101
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
537
reactos/dll/directx/dsound_new/secondary.c
Normal file
537
reactos/dll/directx/dsound_new/secondary.c
Normal file
|
@ -0,0 +1,537 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/secondary.c
|
||||
* PURPOSE: Secondary IDirectSoundBuffer8 implementation
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
const IDirectSoundBuffer8Vtbl *lpVtbl;
|
||||
LONG ref;
|
||||
|
||||
LPFILTERINFO Filter;
|
||||
DWORD dwLevel;
|
||||
LPWAVEFORMATEX Format;
|
||||
PUCHAR Buffer;
|
||||
DWORD BufferSize;
|
||||
KSSTATE State;
|
||||
DWORD Flags;
|
||||
DWORD Position;
|
||||
DWORD PlayPosition;
|
||||
|
||||
LPDIRECTSOUNDBUFFER8 PrimaryBuffer;
|
||||
|
||||
|
||||
}CDirectSoundBuffer, *LPCDirectSoundBuffer;
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnQueryInterface(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
IN REFIID riid,
|
||||
LPVOID* ppobj)
|
||||
{
|
||||
LPOLESTR pStr;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
if (IsEqualIID(riid, &IID_IUnknown) ||
|
||||
IsEqualIID(riid, &IID_IDirectSoundBuffer) ||
|
||||
IsEqualIID(riid, &IID_IDirectSoundBuffer8))
|
||||
{
|
||||
*ppobj = (LPVOID)&This->lpVtbl;
|
||||
InterlockedIncrement(&This->ref);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
if (SUCCEEDED(StringFromIID(riid, &pStr)))
|
||||
{
|
||||
DPRINT("No Interface for class %s\n", pStr);
|
||||
CoTaskMemFree(pStr);
|
||||
}
|
||||
return E_NOINTERFACE;
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnAddRef(
|
||||
LPDIRECTSOUNDBUFFER8 iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
ref = InterlockedIncrement(&This->ref);
|
||||
|
||||
return ref;
|
||||
|
||||
}
|
||||
|
||||
ULONG
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnRelease(
|
||||
LPDIRECTSOUNDBUFFER8 iface)
|
||||
{
|
||||
ULONG ref;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
ref = InterlockedDecrement(&(This->ref));
|
||||
|
||||
if (!ref)
|
||||
{
|
||||
HeapFree(GetProcessHeap(), 0, This->Buffer);
|
||||
HeapFree(GetProcessHeap(), 0, This->Format);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
}
|
||||
|
||||
return ref;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetCaps(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDSBCAPS pDSBufferCaps)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDWORD pdwCurrentPlayCursor,
|
||||
LPDWORD pdwCurrentWriteCursor)
|
||||
{
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
//DPRINT("SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition This %p Play %p Write %p\n", This, pdwCurrentPlayCursor, pdwCurrentWriteCursor);
|
||||
|
||||
return PrimaryDirectSoundBuffer_GetPosition(This->PrimaryBuffer, pdwCurrentPlayCursor, pdwCurrentWriteCursor);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetFormat(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPWAVEFORMATEX pwfxFormat,
|
||||
DWORD dwSizeAllocated,
|
||||
LPDWORD pdwSizeWritten)
|
||||
{
|
||||
DWORD FormatSize;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
FormatSize = sizeof(WAVEFORMATEX) + This->Format->cbSize;
|
||||
|
||||
if (!pwfxFormat && !pdwSizeWritten)
|
||||
{
|
||||
/* invalid parameter */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
if (!pwfxFormat)
|
||||
{
|
||||
/* return required format size */
|
||||
*pdwSizeWritten = FormatSize;
|
||||
return DS_OK;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dwSizeAllocated >= FormatSize)
|
||||
{
|
||||
/* copy format */
|
||||
CopyMemory(pwfxFormat, This->Format, FormatSize);
|
||||
|
||||
if (pdwSizeWritten)
|
||||
*pdwSizeWritten = FormatSize;
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
/* buffer too small */
|
||||
if (pdwSizeWritten)
|
||||
*pdwSizeWritten = 0;
|
||||
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetVolume(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPLONG plVolume)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetPan(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPLONG plPan)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetFrequency(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDWORD pdwFrequency)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetStatus(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDWORD pdwStatus)
|
||||
{
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
if (!pdwStatus)
|
||||
{
|
||||
/* invalid parameter */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
*pdwStatus = 0;
|
||||
if (This->State == KSSTATE_RUN || This->State == KSSTATE_ACQUIRE)
|
||||
{
|
||||
/* buffer is playing */
|
||||
*pdwStatus |= DSBSTATUS_PLAYING;
|
||||
if (This->Flags & DSBPLAY_LOOPING)
|
||||
*pdwStatus |= DSBSTATUS_LOOPING;
|
||||
}
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnInitialize(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPDIRECTSOUND pDirectSound,
|
||||
LPCDSBUFFERDESC pcDSBufferDesc)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnLock(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwOffset,
|
||||
DWORD dwBytes,
|
||||
LPVOID *ppvAudioPtr1,
|
||||
LPDWORD pdwAudioBytes1,
|
||||
LPVOID *ppvAudioPtr2,
|
||||
LPDWORD pdwAudioBytes2,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
DPRINT("This %p dwOffset %u dwBytes %u ppvAudioPtr1 %p pdwAudioBytes1 %p ppvAudioPtr2 %p pdwAudioBytes2 %p dwFlags %x This->BufferSize %u\n",
|
||||
This, dwOffset, dwBytes, ppvAudioPtr1, pdwAudioBytes1, ppvAudioPtr2, pdwAudioBytes2, dwFlags, This->BufferSize);
|
||||
|
||||
if (dwFlags == DSBLOCK_ENTIREBUFFER)
|
||||
{
|
||||
*ppvAudioPtr1 = (LPVOID)This->Buffer;
|
||||
*pdwAudioBytes1 = This->BufferSize;
|
||||
if (ppvAudioPtr2)
|
||||
*ppvAudioPtr2 = NULL;
|
||||
if (pdwAudioBytes2)
|
||||
*pdwAudioBytes2 = 0;
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
else if (dwFlags & DSBLOCK_FROMWRITECURSOR)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_UNSUPPORTED;
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(dwOffset < This->BufferSize);
|
||||
ASSERT(dwBytes < This->BufferSize);
|
||||
ASSERT(dwBytes + dwOffset <= This->BufferSize);
|
||||
|
||||
*ppvAudioPtr1 = This->Buffer + dwOffset;
|
||||
*pdwAudioBytes1 = dwBytes;
|
||||
if (ppvAudioPtr2)
|
||||
*ppvAudioPtr2 = NULL;
|
||||
if (pdwAudioBytes2)
|
||||
*pdwAudioBytes2 = 0;
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnPlay(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwReserved1,
|
||||
DWORD dwPriority,
|
||||
DWORD dwFlags)
|
||||
{
|
||||
HRESULT hResult;
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
if (dwReserved1 != 0)
|
||||
{
|
||||
/* must be zero */
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
DPRINT("SecondaryDirectSoundBuffer8Impl_fnPlay dwPriority %x dwFlags %x\n", dwPriority, dwFlags);
|
||||
hResult = PrimaryDirectSoundBuffer_SetFormat(This->PrimaryBuffer, This->Format, (dwFlags & DSBPLAY_LOOPING));
|
||||
|
||||
DPRINT("Result %x\n", hResult);
|
||||
if (!SUCCEEDED(hResult))
|
||||
{
|
||||
/* failed */
|
||||
return hResult;
|
||||
}
|
||||
|
||||
PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_RUN);
|
||||
|
||||
|
||||
PrimaryDirectSoundBuffer_AcquireLock(This->PrimaryBuffer);
|
||||
|
||||
PrimaryDirectSoundBuffer_Write(This->PrimaryBuffer, This->Buffer, This->BufferSize);
|
||||
|
||||
PrimaryDirectSoundBuffer_ReleaseLock(This->PrimaryBuffer);
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwNewPosition)
|
||||
{
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
DPRINT("Setting position %u\n", dwNewPosition);
|
||||
This->Position = dwNewPosition;
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetFormat(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPCWAVEFORMATEX pcfxFormat)
|
||||
{
|
||||
return DSERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetVolume(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LONG lVolume)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetPan(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LONG lPan)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetFrequency(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwFrequency)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnStop(
|
||||
LPDIRECTSOUNDBUFFER8 iface)
|
||||
{
|
||||
LPCDirectSoundBuffer This = (LPCDirectSoundBuffer)CONTAINING_RECORD(iface, CDirectSoundBuffer, lpVtbl);
|
||||
|
||||
PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_PAUSE);
|
||||
PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_ACQUIRE);
|
||||
PrimaryDirectSoundBuffer_SetState(This->PrimaryBuffer, KSSTATE_STOP);
|
||||
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnUnlock(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
LPVOID pvAudioPtr1,
|
||||
DWORD dwAudioBytes1,
|
||||
LPVOID pvAudioPtr2,
|
||||
DWORD dwAudioBytes2)
|
||||
{
|
||||
//DPRINT("SecondaryDirectSoundBuffer8Impl_fnUnlock pvAudioPtr1 %p dwAudioBytes1 %u pvAudioPtr2 %p dwAudioBytes2 %u Unimplemented\n");
|
||||
return DS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnRestore(
|
||||
LPDIRECTSOUNDBUFFER8 iface)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetFX(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwEffectsCount,
|
||||
LPDSEFFECTDESC pDSFXDesc,
|
||||
LPDWORD pdwResultCodes)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnAcquireResources(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
DWORD dwFlags,
|
||||
DWORD dwEffectsCount,
|
||||
LPDWORD pdwResultCodes)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath(
|
||||
LPDIRECTSOUNDBUFFER8 iface,
|
||||
REFGUID rguidObject,
|
||||
DWORD dwIndex,
|
||||
REFGUID rguidInterface,
|
||||
LPVOID *ppObject)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
||||
static IDirectSoundBuffer8Vtbl vt_DirectSoundBuffer8 =
|
||||
{
|
||||
/* IUnknown methods */
|
||||
SecondaryDirectSoundBuffer8Impl_fnQueryInterface,
|
||||
SecondaryDirectSoundBuffer8Impl_fnAddRef,
|
||||
SecondaryDirectSoundBuffer8Impl_fnRelease,
|
||||
/* IDirectSoundBuffer methods */
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetCaps,
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetCurrentPosition,
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetFormat,
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetVolume,
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetPan,
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetFrequency,
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetStatus,
|
||||
SecondaryDirectSoundBuffer8Impl_fnInitialize,
|
||||
SecondaryDirectSoundBuffer8Impl_fnLock,
|
||||
SecondaryDirectSoundBuffer8Impl_fnPlay,
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetCurrentPosition,
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetFormat,
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetVolume,
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetPan,
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetFrequency,
|
||||
SecondaryDirectSoundBuffer8Impl_fnStop,
|
||||
SecondaryDirectSoundBuffer8Impl_fnUnlock,
|
||||
SecondaryDirectSoundBuffer8Impl_fnRestore,
|
||||
/* IDirectSoundBuffer8 methods */
|
||||
SecondaryDirectSoundBuffer8Impl_fnSetFX,
|
||||
SecondaryDirectSoundBuffer8Impl_fnAcquireResources,
|
||||
SecondaryDirectSoundBuffer8Impl_fnGetObjectInPath
|
||||
};
|
||||
|
||||
HRESULT
|
||||
NewSecondarySoundBuffer(
|
||||
LPDIRECTSOUNDBUFFER8 *OutBuffer,
|
||||
LPFILTERINFO Filter,
|
||||
DWORD dwLevel,
|
||||
LPCDSBUFFERDESC lpcDSBufferDesc,
|
||||
LPDIRECTSOUNDBUFFER8 PrimaryBuffer)
|
||||
{
|
||||
ULONG FormatSize;
|
||||
LPCDirectSoundBuffer This = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CDirectSoundBuffer));
|
||||
|
||||
if (!This)
|
||||
{
|
||||
/* not enough memory */
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
FormatSize = sizeof(WAVEFORMATEX) + lpcDSBufferDesc->lpwfxFormat->cbSize;
|
||||
|
||||
This->Format = HeapAlloc(GetProcessHeap(), 0, FormatSize);
|
||||
if (!This->Format)
|
||||
{
|
||||
/* not enough memory */
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
ASSERT(lpcDSBufferDesc->dwBufferBytes);
|
||||
|
||||
/* allocate sound buffer */
|
||||
This->Buffer = HeapAlloc(GetProcessHeap(), 0, lpcDSBufferDesc->dwBufferBytes);
|
||||
if (!This->Buffer)
|
||||
{
|
||||
/* not enough memory */
|
||||
HeapFree(GetProcessHeap(), 0, This->Format);
|
||||
HeapFree(GetProcessHeap(), 0, This);
|
||||
return DSERR_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
|
||||
This->ref = 1;
|
||||
This->lpVtbl = &vt_DirectSoundBuffer8;
|
||||
This->Filter = Filter;
|
||||
This->dwLevel = dwLevel;
|
||||
This->State = KSSTATE_STOP;
|
||||
This->Flags = 0;
|
||||
This->Position = 0;
|
||||
This->BufferSize = lpcDSBufferDesc->dwBufferBytes;
|
||||
This->PrimaryBuffer = PrimaryBuffer;
|
||||
|
||||
CopyMemory(This->Format, lpcDSBufferDesc->lpwfxFormat, FormatSize);
|
||||
|
||||
*OutBuffer = (LPDIRECTSOUNDBUFFER8)&This->lpVtbl;
|
||||
return DS_OK;
|
||||
}
|
||||
|
29
reactos/dll/directx/dsound_new/stubs.c
Normal file
29
reactos/dll/directx/dsound_new/stubs.c
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Configuration of network devices
|
||||
* FILE: dll/directx/dsound_new/stubs.c
|
||||
* PURPOSE: DSound stubs
|
||||
*
|
||||
* PROGRAMMERS: Johannes Anderwald (janderwald@reactos.org)
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
HRESULT
|
||||
WINAPI
|
||||
DirectSoundFullDuplexCreate(
|
||||
LPCGUID pcGuidCaptureDevice,
|
||||
LPCGUID pcGuidRenderDevice,
|
||||
LPCDSCBUFFERDESC pcDSCBufferDesc,
|
||||
LPCDSBUFFERDESC pcDSBufferDesc,
|
||||
HWND hWnd,
|
||||
DWORD dwLevel,
|
||||
LPDIRECTSOUNDFULLDUPLEX *ppDSFD,
|
||||
LPDIRECTSOUNDCAPTUREBUFFER8 *ppDSCBuffer8,
|
||||
LPDIRECTSOUNDBUFFER8 *ppDSBuffer8,
|
||||
LPUNKNOWN pUnkOuter)
|
||||
{
|
||||
UNIMPLEMENTED
|
||||
return DSERR_INVALIDPARAM;
|
||||
}
|
||||
|
14
reactos/dll/directx/dsound_new/version.rc
Normal file
14
reactos/dll/directx/dsound_new/version.rc
Normal file
|
@ -0,0 +1,14 @@
|
|||
#include <windows.h>
|
||||
#include "shlobj.h"
|
||||
#include "resource.h"
|
||||
|
||||
LANGUAGE LANG_NEUTRAL, SUBLANG_NEUTRAL
|
||||
|
||||
#define REACTOS_VERSION_DLL
|
||||
#define REACTOS_STR_FILE_DESCRIPTION "DirectSound\0"
|
||||
#define REACTOS_STR_INTERNAL_NAME "dsound.dll\0"
|
||||
#define REACTOS_STR_ORIGINAL_FILENAME "dsound.dll\0"
|
||||
#define REACTOS_STR_PRODUCT_VERSION "5.3.1.904\0"
|
||||
#define REACTOS_STR_FILE_VERSION "5.3.1.904\0"
|
||||
|
||||
#include <reactos/version.rc>
|
Loading…
Add table
Add a link
Reference in a new issue