reactos/dll/win32/mmdrv/kernel.c

212 lines
4.8 KiB
C
Raw Normal View History

/*
*
* COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS Multimedia
* FILE: dll/win32/mmdrv/kernel.c
* PURPOSE: Multimedia User Mode Driver (kernel interface)
* PROGRAMMER: Andrew Greenwood
* UPDATE HISTORY:
* Jan 14, 2007: Created
*/
#include "mmdrv.h"
#include <winuser.h>
#define NDEBUG
#include <debug.h>
/*
Devices that we provide access to follow a standard naming convention.
The first wave output, for example, appears as \Device\WaveOut0
I'm not entirely certain how drivers find a free name to use, or why
we need to strip the leading \Device from it when opening, but hey...
*/
MMRESULT
CobbleDeviceName(
DeviceType device_type,
Merge from amd64 branch: [SPIDER] 44002 Fix 64 bit build. (Samuel Serapión) [PAINT] 43858 Fix 64 bit warnings. (Samuel Serapión) [RAPPS] 43906 Fix 64 bit build. (Samuel Serapión) [SNDREC32] 44389 Fix 64 bit build. (Samuel Serapión) [TFTP] 41097 Fix pointer to DWORD cast. (Timo Kreuzer) [COMCTL32] 36172 Build as unicode. (Samuel Serapión) [USERMGR] 41098 Fix 2 POINTER<->DWORD casts. (Timo Kreuzer) [d3d9] 38149 Fix pointer<->ULONG cast. (Timo Kreuzer) 43839 Fix 64 bit Build. (Samuel Serapión) [DSOUND] 40753 Make DSDRIVERDESC.dnDevNode a DWORD_PTR and DSPROPERTY.InstanceId a ULONG_PTR. (Timo Kreuzer) [LSASRV] 44037 Fix 64 bit Build. (Samuel Serapión) [MMDRV] 40125 Fix 64bit build. (Samuel Serapión) [MSGINA] 40993 fix 64bit build (Timo Kreuzer) [NETSHELL] 41001 Don't cast the 1st parameter of InterlockedExchange to volatile void **, but to void ** (Timo Kreuzer) [OPENGL32] 36502 No need to assert an offset thats only used in i386 specific code. (Samuel Serapión) [POWRPROF] 41044 Don't cast NULL to DWORD. (Timo Kreuzer) 43860 Don't cast NULL to an integer type. (Samuel Serapión) [PSAPI] 38150 Fix a cast (Timo Kreuzer) [SHELL32] 38355 Use Get/SetWindowLongPtr (Samuel Serapión) 41047 Get rid of deprecated LargeInteger functions and use native int64 math instead. (Timo Kreuzer) 41048 DialogProc returns INT_PTR and not BOOL. Don't cast a pointer to LONG. Use INT_PTR instead of int for pointer math. (Timo Kreuzer) 41049 Change return type of OpenMRUListW and CreateMRUListW to HANDLE, add a comment that CREATEMRULISTW is already defined differently in explorer_new/undoc.h (Timo Kreuzer) 44601 Fix a prototype. Convert RtlLargeInteger to native int64. Fixes 64bit built. (Timo Kreuzer) [WDMAUD.DRV] 41101 Don't cast DWORD to PVOID, use UlongToPtr instead. (Timo Kreuzer) [WS2_32] 35777 fix ws2_32 spec file (Timo kreuzer) 44044 Fix ws2_32 64bit build (1 of 2) (Samuel Serapión) 44045 Fix ws2_32 64bit build (2 of 2) (Samuel Serapión) [WS2_32_NEW] 44389 Fix 64 bit built. (Samuel Serapión) svn path=/trunk/; revision=44602
2009-12-15 15:16:01 +00:00
UINT device_id,
PWCHAR out_device_name)
{
WCHAR base_device_name[MAX_DEVICE_NAME_LENGTH];
/* Work out the base name from the device type */
switch ( device_type )
{
case WaveOutDevice :
wsprintf(base_device_name, L"%ls", WAVE_OUT_DEVICE_NAME);
break;
case WaveInDevice :
wsprintf(base_device_name, L"%ls", WAVE_IN_DEVICE_NAME);
break;
case MidiOutDevice :
wsprintf(base_device_name, L"%ls", MIDI_OUT_DEVICE_NAME);
break;
case MidiInDevice :
wsprintf(base_device_name, L"%ls", MIDI_IN_DEVICE_NAME);
break;
case AuxDevice :
wsprintf(base_device_name, L"%ls", AUX_DEVICE_NAME);
break;
default :
return MMSYSERR_BADDEVICEID;
};
/* Now append the device number, removing the leading \Device */
wsprintf(out_device_name,
L"\\\\.%ls%d",
base_device_name + strlen("\\Device"),
device_id);
return MMSYSERR_NOERROR;
}
/*
Takes a device type (eg: WaveOutDevice), a device ID, desired access and
a pointer to a location that will store the handle of the opened "file" if
the function succeeds.
The device type and ID are converted into a device name using the above
function.
*/
MMRESULT
OpenKernelDevice(
DeviceType device_type,
Merge from amd64 branch: [SPIDER] 44002 Fix 64 bit build. (Samuel Serapión) [PAINT] 43858 Fix 64 bit warnings. (Samuel Serapión) [RAPPS] 43906 Fix 64 bit build. (Samuel Serapión) [SNDREC32] 44389 Fix 64 bit build. (Samuel Serapión) [TFTP] 41097 Fix pointer to DWORD cast. (Timo Kreuzer) [COMCTL32] 36172 Build as unicode. (Samuel Serapión) [USERMGR] 41098 Fix 2 POINTER<->DWORD casts. (Timo Kreuzer) [d3d9] 38149 Fix pointer<->ULONG cast. (Timo Kreuzer) 43839 Fix 64 bit Build. (Samuel Serapión) [DSOUND] 40753 Make DSDRIVERDESC.dnDevNode a DWORD_PTR and DSPROPERTY.InstanceId a ULONG_PTR. (Timo Kreuzer) [LSASRV] 44037 Fix 64 bit Build. (Samuel Serapión) [MMDRV] 40125 Fix 64bit build. (Samuel Serapión) [MSGINA] 40993 fix 64bit build (Timo Kreuzer) [NETSHELL] 41001 Don't cast the 1st parameter of InterlockedExchange to volatile void **, but to void ** (Timo Kreuzer) [OPENGL32] 36502 No need to assert an offset thats only used in i386 specific code. (Samuel Serapión) [POWRPROF] 41044 Don't cast NULL to DWORD. (Timo Kreuzer) 43860 Don't cast NULL to an integer type. (Samuel Serapión) [PSAPI] 38150 Fix a cast (Timo Kreuzer) [SHELL32] 38355 Use Get/SetWindowLongPtr (Samuel Serapión) 41047 Get rid of deprecated LargeInteger functions and use native int64 math instead. (Timo Kreuzer) 41048 DialogProc returns INT_PTR and not BOOL. Don't cast a pointer to LONG. Use INT_PTR instead of int for pointer math. (Timo Kreuzer) 41049 Change return type of OpenMRUListW and CreateMRUListW to HANDLE, add a comment that CREATEMRULISTW is already defined differently in explorer_new/undoc.h (Timo Kreuzer) 44601 Fix a prototype. Convert RtlLargeInteger to native int64. Fixes 64bit built. (Timo Kreuzer) [WDMAUD.DRV] 41101 Don't cast DWORD to PVOID, use UlongToPtr instead. (Timo Kreuzer) [WS2_32] 35777 fix ws2_32 spec file (Timo kreuzer) 44044 Fix ws2_32 64bit build (1 of 2) (Samuel Serapión) 44045 Fix ws2_32 64bit build (2 of 2) (Samuel Serapión) [WS2_32_NEW] 44389 Fix 64 bit built. (Samuel Serapión) svn path=/trunk/; revision=44602
2009-12-15 15:16:01 +00:00
UINT device_id,
DWORD access,
HANDLE* handle)
{
MMRESULT result;
WCHAR device_name[MAX_DEVICE_NAME_LENGTH];
DWORD open_flags = 0;
ASSERT(handle);
/* Glue the base device name and the ID together */
result = CobbleDeviceName(device_type, device_id, device_name);
DPRINT("Opening kernel device %ls\n", device_name);
if ( result != MMSYSERR_NOERROR )
return result;
/* We want overlapped I/O when writing */
if ( access != GENERIC_READ )
open_flags = FILE_FLAG_OVERLAPPED;
/* Now try opening... */
*handle = CreateFile(device_name,
access,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
open_flags,
NULL);
if ( *handle == INVALID_HANDLE_VALUE )
return ErrorToMmResult(GetLastError());
return MMSYSERR_NOERROR;
}
/*
Just an alias for the benefit of having a pair of functions ;)
*/
void
CloseKernelDevice(HANDLE device_handle)
{
CloseHandle(device_handle);
}
MMRESULT
SetDeviceData(
HANDLE device_handle,
DWORD ioctl,
PBYTE input_buffer,
DWORD buffer_size)
{
DPRINT("SetDeviceData\n");
/* TODO */
return 0;
}
MMRESULT
GetDeviceData(
HANDLE device_handle,
DWORD ioctl,
PBYTE output_buffer,
DWORD buffer_size)
{
OVERLAPPED overlap;
DWORD bytes_returned;
BOOL success;
DWORD transfer;
DPRINT("GetDeviceData\n");
memset(&overlap, 0, sizeof(overlap));
overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
if ( ! overlap.hEvent )
return MMSYSERR_NOMEM;
success = DeviceIoControl(device_handle,
ioctl,
NULL,
0,
output_buffer,
buffer_size,
&bytes_returned,
&overlap);
if ( ! success )
{
if ( GetLastError() == ERROR_IO_PENDING )
{
if ( ! GetOverlappedResult(device_handle, &overlap, &transfer, TRUE) )
{
CloseHandle(overlap.hEvent);
return ErrorToMmResult(GetLastError());
}
}
else
{
CloseHandle(overlap.hEvent);
return ErrorToMmResult(GetLastError());
}
}
while ( TRUE )
{
SetEvent(overlap.hEvent);
if ( WaitForSingleObjectEx(overlap.hEvent, 0, TRUE) != WAIT_IO_COMPLETION )
{
break;
}
}
CloseHandle(overlap.hEvent);
return MMSYSERR_NOERROR;
}