ReactOS  0.4.14-dev-831-gef8c9239
kernel.c
Go to the documentation of this file.
1 /*
2  *
3  * COPYRIGHT: See COPYING in the top level directory
4  * PROJECT: ReactOS Multimedia
5  * FILE: dll/win32/mmdrv/kernel.c
6  * PURPOSE: Multimedia User Mode Driver (kernel interface)
7  * PROGRAMMER: Andrew Greenwood
8  * UPDATE HISTORY:
9  * Jan 14, 2007: Created
10  */
11 
12 #include "mmdrv.h"
13 
14 #include <winuser.h>
15 
16 #define NDEBUG
17 #include <debug.h>
18 
19 /*
20  Devices that we provide access to follow a standard naming convention.
21  The first wave output, for example, appears as \Device\WaveOut0
22 
23  I'm not entirely certain how drivers find a free name to use, or why
24  we need to strip the leading \Device from it when opening, but hey...
25 */
26 
30  UINT device_id,
31  PWCHAR out_device_name)
32 {
33  WCHAR base_device_name[MAX_DEVICE_NAME_LENGTH];
34 
35  /* Work out the base name from the device type */
36 
37  switch ( device_type )
38  {
39  case WaveOutDevice :
40  wsprintf(base_device_name, L"%ls", WAVE_OUT_DEVICE_NAME);
41  break;
42 
43  case WaveInDevice :
44  wsprintf(base_device_name, L"%ls", WAVE_IN_DEVICE_NAME);
45  break;
46 
47  case MidiOutDevice :
48  wsprintf(base_device_name, L"%ls", MIDI_OUT_DEVICE_NAME);
49  break;
50 
51  case MidiInDevice :
52  wsprintf(base_device_name, L"%ls", MIDI_IN_DEVICE_NAME);
53  break;
54 
55  case AuxDevice :
56  wsprintf(base_device_name, L"%ls", AUX_DEVICE_NAME);
57  break;
58 
59  default :
60  return MMSYSERR_BADDEVICEID;
61  };
62 
63  /* Now append the device number, removing the leading \Device */
64 
65  wsprintf(out_device_name,
66  L"\\\\.%ls%d",
67  base_device_name + strlen("\\Device"),
68  device_id);
69 
70  return MMSYSERR_NOERROR;
71 }
72 
73 
74 /*
75  Takes a device type (eg: WaveOutDevice), a device ID, desired access and
76  a pointer to a location that will store the handle of the opened "file" if
77  the function succeeds.
78 
79  The device type and ID are converted into a device name using the above
80  function.
81 */
82 
86  UINT device_id,
87  DWORD access,
88  HANDLE* handle)
89 {
92  DWORD open_flags = 0;
93 
94  ASSERT(handle);
95 
96  /* Glue the base device name and the ID together */
97 
99 
100  DPRINT("Opening kernel device %ls\n", device_name);
101 
102  if ( result != MMSYSERR_NOERROR )
103  return result;
104 
105  /* We want overlapped I/O when writing */
106 
107  if ( access != GENERIC_READ )
108  open_flags = FILE_FLAG_OVERLAPPED;
109 
110  /* Now try opening... */
111 
113  access,
115  NULL,
117  open_flags,
118  NULL);
119 
120  if ( *handle == INVALID_HANDLE_VALUE )
121  return ErrorToMmResult(GetLastError());
122 
123  return MMSYSERR_NOERROR;
124 }
125 
126 
127 /*
128  Just an alias for the benefit of having a pair of functions ;)
129 */
130 
131 void
132 CloseKernelDevice(HANDLE device_handle)
133 {
134  CloseHandle(device_handle);
135 }
136 
137 
138 MMRESULT
140  HANDLE device_handle,
141  DWORD ioctl,
144 {
145  DPRINT("SetDeviceData\n");
146  /* TODO */
147  return 0;
148 }
149 
150 
151 MMRESULT
153  HANDLE device_handle,
154  DWORD ioctl,
157 {
158  OVERLAPPED overlap;
159  DWORD bytes_returned;
160  BOOL success;
161  DWORD transfer;
162 
163  DPRINT("GetDeviceData\n");
164 
165  memset(&overlap, 0, sizeof(overlap));
166 
167  overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
168 
169  if ( ! overlap.hEvent )
170  return MMSYSERR_NOMEM;
171 
172  success = DeviceIoControl(device_handle,
173  ioctl,
174  NULL,
175  0,
177  buffer_size,
178  &bytes_returned,
179  &overlap);
180 
181  if ( ! success )
182  {
183  if ( GetLastError() == ERROR_IO_PENDING )
184  {
185  if ( ! GetOverlappedResult(device_handle, &overlap, &transfer, TRUE) )
186  {
187  CloseHandle(overlap.hEvent);
188  return ErrorToMmResult(GetLastError());
189  }
190  }
191  else
192  {
193  CloseHandle(overlap.hEvent);
194  return ErrorToMmResult(GetLastError());
195  }
196  }
197 
198  while ( TRUE )
199  {
200  SetEvent(overlap.hEvent);
201 
202  if ( WaitForSingleObjectEx(overlap.hEvent, 0, TRUE) != WAIT_IO_COMPLETION )
203  {
204  break;
205  }
206  }
207 
208  CloseHandle(overlap.hEvent);
209 
210  return MMSYSERR_NOERROR;
211 }
#define CreateEvent
Definition: winbase.h:3582
DWORD WINAPI WaitForSingleObjectEx(IN HANDLE hHandle, IN DWORD dwMilliseconds, IN BOOL bAlertable)
Definition: synch.c:94
#define TRUE
Definition: types.h:120
#define CloseHandle
Definition: compat.h:406
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
BOOL WINAPI GetOverlappedResult(IN HANDLE hFile, IN LPOVERLAPPED lpOverlapped, OUT LPDWORD lpNumberOfBytesTransferred, IN BOOL bWait)
Definition: iocompl.c:204
DeviceType
Definition: mmdrv.h:41
#define WAVE_IN_DEVICE_NAME
Definition: mmdef.h:29
device_type
static const WCHAR device_name[]
Definition: btrfs.c:61
void CloseKernelDevice(HANDLE device_handle)
Definition: kernel.c:132
#define INVALID_HANDLE_VALUE
Definition: compat.h:399
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1059
UINT MMRESULT
Definition: mmsystem.h:962
#define MIDI_IN_DEVICE_NAME
Definition: mmdef.h:34
uint16_t * PWCHAR
Definition: typedefs.h:54
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define WAVE_OUT_DEVICE_NAME
Definition: mmdef.h:31
MMRESULT GetDeviceData(HANDLE device_handle, DWORD ioctl, PBYTE output_buffer, DWORD buffer_size)
Definition: kernel.c:152
#define MMSYSERR_NOMEM
Definition: mmsystem.h:103
unsigned int BOOL
Definition: ntddk_ex.h:94
#define ioctl
Definition: wintirpc.h:60
#define AUX_DEVICE_NAME
Definition: mmdef.h:39
static void buffer_size(GLcontext *ctx, GLuint *width, GLuint *height)
Definition: swimpl.c:927
HANDLE hEvent
Definition: winbase.h:792
smooth NULL
Definition: ftsmooth.c:416
void DPRINT(...)
Definition: polytest.cpp:61
#define WAIT_IO_COMPLETION
Definition: winbase.h:392
#define OPEN_EXISTING
Definition: compat.h:434
#define MMSYSERR_NOERROR
Definition: mmsystem.h:96
__wchar_t WCHAR
Definition: xmlstorage.h:180
MMRESULT OpenKernelDevice(DeviceType device_type, UINT device_id, DWORD access, HANDLE *handle)
Definition: kernel.c:84
unsigned long DWORD
Definition: ntddk_ex.h:95
#define success(from, fromstr, to, tostr)
ASSERT((InvokeOnSuccess||InvokeOnError||InvokeOnCancel) ?(CompletionRoutine !=NULL) :TRUE)
MMRESULT ErrorToMmResult(UINT error_code)
Definition: common.c:22
static const WCHAR L[]
Definition: oid.c:1250
#define MMSYSERR_BADDEVICEID
Definition: mmsystem.h:98
#define GENERIC_READ
Definition: compat.h:124
BOOL WINAPI DeviceIoControl(IN HANDLE hDevice, IN DWORD dwIoControlCode, IN LPVOID lpInBuffer OPTIONAL, IN DWORD nInBufferSize OPTIONAL, OUT LPVOID lpOutBuffer OPTIONAL, IN DWORD nOutBufferSize OPTIONAL, OUT LPDWORD lpBytesReturned OPTIONAL, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: deviceio.c:136
IN OUT PVCB OUT PDIRENT OUT PBCB IN BOOLEAN CreateFile
Definition: fatprocs.h:904
#define MIDI_OUT_DEVICE_NAME
Definition: mmdef.h:36
GLuint GLint GLboolean GLint GLenum access
Definition: glext.h:7866
unsigned int UINT
Definition: ndis.h:50
MMRESULT SetDeviceData(HANDLE device_handle, DWORD ioctl, PBYTE input_buffer, DWORD buffer_size)
Definition: kernel.c:139
MMRESULT CobbleDeviceName(DeviceType device_type, UINT device_id, PWCHAR out_device_name)
Definition: kernel.c:28
#define FILE_FLAG_OVERLAPPED
Definition: disk.h:46
#define wsprintf
Definition: winuser.h:5840
GLuint64EXT * result
Definition: glext.h:11304
#define memset(x, y, z)
Definition: compat.h:39
BYTE * PBYTE
Definition: pedump.c:66
#define MAX_DEVICE_NAME_LENGTH
Definition: mmdrv.h:29