mirror of
https://github.com/reactos/reactos.git
synced 2024-11-01 12:26:32 +00:00
133 lines
3.8 KiB
C
133 lines
3.8 KiB
C
/*
|
|
* PROJECT: ReactOS Sound System "MME Buddy" Library
|
|
* LICENSE: GPL - See COPYING in the top level directory
|
|
* FILE: lib/drivers/sound/mmebuddy/kernel.c
|
|
*
|
|
* PURPOSE: Routines assisting with device I/O between user-mode and
|
|
* kernel-mode.
|
|
*
|
|
* PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org)
|
|
*/
|
|
|
|
#include "precomp.h"
|
|
|
|
/*
|
|
Wraps around CreateFile in order to provide a simpler interface tailored
|
|
towards sound driver support code. This simply takes a device path and
|
|
opens the device in either read-only mode, or read/write mode (depending on
|
|
the ReadOnly parameter).
|
|
|
|
If the device is opened in read/write mode, it is opened for overlapped I/O.
|
|
*/
|
|
MMRESULT
|
|
OpenKernelSoundDeviceByName(
|
|
IN PWSTR DevicePath,
|
|
IN BOOLEAN ReadOnly,
|
|
OUT PHANDLE Handle)
|
|
{
|
|
DWORD AccessRights;
|
|
|
|
VALIDATE_MMSYS_PARAMETER( DevicePath );
|
|
VALIDATE_MMSYS_PARAMETER( Handle );
|
|
|
|
AccessRights = ReadOnly ? GENERIC_READ : GENERIC_READ | GENERIC_WRITE;
|
|
|
|
SND_TRACE(L"OpenKernelSoundDeviceByName: %wS\n", DevicePath);
|
|
*Handle = CreateFile(DevicePath,
|
|
AccessRights,
|
|
FILE_SHARE_WRITE, /* FIXME? Should be read also? */
|
|
NULL,
|
|
OPEN_EXISTING,
|
|
ReadOnly ? 0 : FILE_FLAG_OVERLAPPED,
|
|
NULL);
|
|
|
|
if ( *Handle == INVALID_HANDLE_VALUE )
|
|
{
|
|
SND_ERR(L"CreateFile filed - winerror %d\n", GetLastError());
|
|
return Win32ErrorToMmResult(GetLastError());
|
|
}
|
|
|
|
return MMSYSERR_NOERROR;
|
|
}
|
|
|
|
|
|
/*
|
|
Just a wrapped around CloseHandle.
|
|
*/
|
|
MMRESULT
|
|
CloseKernelSoundDevice(
|
|
IN HANDLE Handle)
|
|
{
|
|
VALIDATE_MMSYS_PARAMETER( Handle );
|
|
|
|
CloseHandle(Handle);
|
|
|
|
return MMSYSERR_NOERROR;
|
|
}
|
|
|
|
/*
|
|
This is a wrapper around DeviceIoControl which provides control over
|
|
instantiated sound devices. It waits for I/O to complete (since an
|
|
instantiated sound device is opened in overlapped mode, this is necessary).
|
|
*/
|
|
MMRESULT
|
|
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 Win32ErrorToMmResult(GetLastError());
|
|
|
|
/* Talk to the device */
|
|
IoResult = DeviceIoControl(Handle,
|
|
IoControlCode,
|
|
InBuffer,
|
|
InBufferSize,
|
|
OutBuffer,
|
|
OutBufferSize,
|
|
NULL,
|
|
&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 Win32ErrorToMmResult(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 Win32ErrorToMmResult(GetLastError());
|
|
|
|
SND_TRACE(L"Transferred %d bytes in Sync overlapped I/O\n", Transferred);
|
|
|
|
if ( BytesTransferred )
|
|
*BytesTransferred = Transferred;
|
|
|
|
return MMSYSERR_NOERROR;
|
|
}
|