- 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:
Johannes Anderwald 2009-10-31 14:53:06 +00:00
parent 9a5b0ce12b
commit e65de6eda6
18 changed files with 4609 additions and 0 deletions

View 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);
}

View 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;
}

View 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;
}

View 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;
}

View 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);
}

View 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;
}

View 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()

View 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>

View 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);
}

View 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;
}

View 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

View 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;
}

View 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;
}

View 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;
}

View file

@ -0,0 +1,16 @@
#ifndef RESOURCE_H__
#define RESOURCE_H__
#define IDS_PRIMARY_PLAYBACK_DEVICE 100
#define IDS_PRIMARY_RECORD_DEVICE 101
#endif

View 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;
}

View 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;
}

View 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>