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
9 * Jan 14, 2007: Created
15 Devices that we provide access to follow a standard naming convention.
16 The first wave output, for example, appears as \Device\WaveOut0
18 I'm not entirely certain how drivers find a free name to use, or why
19 we need to strip the leading \Device from it when opening, but hey...
24 DeviceType device_type
,
26 PWCHAR out_device_name
)
28 WCHAR base_device_name
[MAX_DEVICE_NAME_LENGTH
];
30 /* Work out the base name from the device type */
32 switch ( device_type
)
35 wsprintf(base_device_name
, L
"%ls", WAVE_OUT_DEVICE_NAME
);
39 wsprintf(base_device_name
, L
"%ls", WAVE_IN_DEVICE_NAME
);
43 wsprintf(base_device_name
, L
"%ls", MIDI_OUT_DEVICE_NAME
);
47 wsprintf(base_device_name
, L
"%ls", MIDI_IN_DEVICE_NAME
);
51 wsprintf(base_device_name
, L
"%ls", AUX_DEVICE_NAME
);
55 return MMSYSERR_BADDEVICEID
;
58 /* Now append the device number, removing the leading \Device */
60 wsprintf(out_device_name
,
62 base_device_name
+ strlen("\\Device"),
65 return MMSYSERR_NOERROR
;
70 Takes a device type (eg: WaveOutDevice), a device ID, desired access and
71 a pointer to a location that will store the handle of the opened "file" if
72 the function succeeds.
74 The device type and ID are converted into a device name using the above
80 DeviceType device_type
,
86 WCHAR device_name
[MAX_DEVICE_NAME_LENGTH
];
91 /* Glue the base device name and the ID together */
93 result
= CobbleDeviceName(device_type
, device_id
, device_name
);
95 DPRINT("Opening kernel device %ls\n", device_name
);
97 if ( result
!= MMSYSERR_NOERROR
)
100 /* We want overlapped I/O when writing */
102 if ( access
!= GENERIC_READ
)
103 open_flags
= FILE_FLAG_OVERLAPPED
;
105 /* Now try opening... */
107 *handle
= CreateFile(device_name
,
115 if ( *handle
== INVALID_HANDLE_VALUE
)
116 return ErrorToMmResult(GetLastError());
118 return MMSYSERR_NOERROR
;
123 Just an alias for the benefit of having a pair of functions ;)
127 CloseKernelDevice(HANDLE device_handle
)
129 CloseHandle(device_handle
);
135 HANDLE device_handle
,
140 DPRINT("SetDeviceData\n");
148 HANDLE device_handle
,
154 DWORD bytes_returned
;
158 DPRINT("GetDeviceData\n");
160 memset(&overlap
, 0, sizeof(overlap
));
162 overlap
.hEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
164 if ( ! overlap
.hEvent
)
165 return MMSYSERR_NOMEM
;
167 success
= DeviceIoControl(device_handle
,
178 if ( GetLastError() == ERROR_IO_PENDING
)
180 if ( ! GetOverlappedResult(device_handle
, &overlap
, &transfer
, TRUE
) )
182 CloseHandle(overlap
.hEvent
);
183 return ErrorToMmResult(GetLastError());
188 CloseHandle(overlap
.hEvent
);
189 return ErrorToMmResult(GetLastError());
195 SetEvent(overlap
.hEvent
);
197 if ( WaitForSingleObjectEx(overlap
.hEvent
, 0, TRUE
) != WAIT_IO_COMPLETION
)
203 CloseHandle(overlap
.hEvent
);
205 return MMSYSERR_NOERROR
;