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
20 Devices that we provide access to follow a standard naming convention.
21 The first wave output, for example, appears as \Device\WaveOut0
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...
29 DeviceType device_type
,
31 PWCHAR out_device_name
)
33 WCHAR base_device_name
[MAX_DEVICE_NAME_LENGTH
];
35 /* Work out the base name from the device type */
37 switch ( device_type
)
40 wsprintf(base_device_name
, L
"%ls", WAVE_OUT_DEVICE_NAME
);
44 wsprintf(base_device_name
, L
"%ls", WAVE_IN_DEVICE_NAME
);
48 wsprintf(base_device_name
, L
"%ls", MIDI_OUT_DEVICE_NAME
);
52 wsprintf(base_device_name
, L
"%ls", MIDI_IN_DEVICE_NAME
);
56 wsprintf(base_device_name
, L
"%ls", AUX_DEVICE_NAME
);
60 return MMSYSERR_BADDEVICEID
;
63 /* Now append the device number, removing the leading \Device */
65 wsprintf(out_device_name
,
67 base_device_name
+ strlen("\\Device"),
70 return MMSYSERR_NOERROR
;
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.
79 The device type and ID are converted into a device name using the above
85 DeviceType device_type
,
91 WCHAR device_name
[MAX_DEVICE_NAME_LENGTH
];
96 /* Glue the base device name and the ID together */
98 result
= CobbleDeviceName(device_type
, device_id
, device_name
);
100 DPRINT("Opening kernel device %ls\n", device_name
);
102 if ( result
!= MMSYSERR_NOERROR
)
105 /* We want overlapped I/O when writing */
107 if ( access
!= GENERIC_READ
)
108 open_flags
= FILE_FLAG_OVERLAPPED
;
110 /* Now try opening... */
112 *handle
= CreateFile(device_name
,
120 if ( *handle
== INVALID_HANDLE_VALUE
)
121 return ErrorToMmResult(GetLastError());
123 return MMSYSERR_NOERROR
;
128 Just an alias for the benefit of having a pair of functions ;)
132 CloseKernelDevice(HANDLE device_handle
)
134 CloseHandle(device_handle
);
140 HANDLE device_handle
,
145 DPRINT("SetDeviceData\n");
153 HANDLE device_handle
,
159 DWORD bytes_returned
;
163 DPRINT("GetDeviceData\n");
165 memset(&overlap
, 0, sizeof(overlap
));
167 overlap
.hEvent
= CreateEvent(NULL
, FALSE
, FALSE
, NULL
);
169 if ( ! overlap
.hEvent
)
170 return MMSYSERR_NOMEM
;
172 success
= DeviceIoControl(device_handle
,
183 if ( GetLastError() == ERROR_IO_PENDING
)
185 if ( ! GetOverlappedResult(device_handle
, &overlap
, &transfer
, TRUE
) )
187 CloseHandle(overlap
.hEvent
);
188 return ErrorToMmResult(GetLastError());
193 CloseHandle(overlap
.hEvent
);
194 return ErrorToMmResult(GetLastError());
200 SetEvent(overlap
.hEvent
);
202 if ( WaitForSingleObjectEx(overlap
.hEvent
, 0, TRUE
) != WAIT_IO_COMPLETION
)
208 CloseHandle(overlap
.hEvent
);
210 return MMSYSERR_NOERROR
;