Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenkernel.c
Go to the documentation of this file.
00001 /* 00002 * 00003 * COPYRIGHT: See COPYING in the top level directory 00004 * PROJECT: ReactOS Multimedia 00005 * FILE: dll/win32/mmdrv/kernel.c 00006 * PURPOSE: Multimedia User Mode Driver (kernel interface) 00007 * PROGRAMMER: Andrew Greenwood 00008 * UPDATE HISTORY: 00009 * Jan 14, 2007: Created 00010 */ 00011 00012 #include <mmdrv.h> 00013 00014 /* 00015 Devices that we provide access to follow a standard naming convention. 00016 The first wave output, for example, appears as \Device\WaveOut0 00017 00018 I'm not entirely certain how drivers find a free name to use, or why 00019 we need to strip the leading \Device from it when opening, but hey... 00020 */ 00021 00022 MMRESULT 00023 CobbleDeviceName( 00024 DeviceType device_type, 00025 UINT device_id, 00026 PWCHAR out_device_name) 00027 { 00028 WCHAR base_device_name[MAX_DEVICE_NAME_LENGTH]; 00029 00030 /* Work out the base name from the device type */ 00031 00032 switch ( device_type ) 00033 { 00034 case WaveOutDevice : 00035 wsprintf(base_device_name, L"%ls", WAVE_OUT_DEVICE_NAME); 00036 break; 00037 00038 case WaveInDevice : 00039 wsprintf(base_device_name, L"%ls", WAVE_IN_DEVICE_NAME); 00040 break; 00041 00042 case MidiOutDevice : 00043 wsprintf(base_device_name, L"%ls", MIDI_OUT_DEVICE_NAME); 00044 break; 00045 00046 case MidiInDevice : 00047 wsprintf(base_device_name, L"%ls", MIDI_IN_DEVICE_NAME); 00048 break; 00049 00050 case AuxDevice : 00051 wsprintf(base_device_name, L"%ls", AUX_DEVICE_NAME); 00052 break; 00053 00054 default : 00055 return MMSYSERR_BADDEVICEID; 00056 }; 00057 00058 /* Now append the device number, removing the leading \Device */ 00059 00060 wsprintf(out_device_name, 00061 L"\\\\.%ls%d", 00062 base_device_name + strlen("\\Device"), 00063 device_id); 00064 00065 return MMSYSERR_NOERROR; 00066 } 00067 00068 00069 /* 00070 Takes a device type (eg: WaveOutDevice), a device ID, desired access and 00071 a pointer to a location that will store the handle of the opened "file" if 00072 the function succeeds. 00073 00074 The device type and ID are converted into a device name using the above 00075 function. 00076 */ 00077 00078 MMRESULT 00079 OpenKernelDevice( 00080 DeviceType device_type, 00081 UINT device_id, 00082 DWORD access, 00083 HANDLE* handle) 00084 { 00085 MMRESULT result; 00086 WCHAR device_name[MAX_DEVICE_NAME_LENGTH]; 00087 DWORD open_flags = 0; 00088 00089 ASSERT(handle); 00090 00091 /* Glue the base device name and the ID together */ 00092 00093 result = CobbleDeviceName(device_type, device_id, device_name); 00094 00095 DPRINT("Opening kernel device %ls\n", device_name); 00096 00097 if ( result != MMSYSERR_NOERROR ) 00098 return result; 00099 00100 /* We want overlapped I/O when writing */ 00101 00102 if ( access != GENERIC_READ ) 00103 open_flags = FILE_FLAG_OVERLAPPED; 00104 00105 /* Now try opening... */ 00106 00107 *handle = CreateFile(device_name, 00108 access, 00109 FILE_SHARE_WRITE, 00110 NULL, 00111 OPEN_EXISTING, 00112 open_flags, 00113 NULL); 00114 00115 if ( *handle == INVALID_HANDLE_VALUE ) 00116 return ErrorToMmResult(GetLastError()); 00117 00118 return MMSYSERR_NOERROR; 00119 } 00120 00121 00122 /* 00123 Just an alias for the benefit of having a pair of functions ;) 00124 */ 00125 00126 void 00127 CloseKernelDevice(HANDLE device_handle) 00128 { 00129 CloseHandle(device_handle); 00130 } 00131 00132 00133 MMRESULT 00134 SetDeviceData( 00135 HANDLE device_handle, 00136 DWORD ioctl, 00137 PBYTE input_buffer, 00138 DWORD buffer_size) 00139 { 00140 DPRINT("SetDeviceData\n"); 00141 /* TODO */ 00142 return 0; 00143 } 00144 00145 00146 MMRESULT 00147 GetDeviceData( 00148 HANDLE device_handle, 00149 DWORD ioctl, 00150 PBYTE output_buffer, 00151 DWORD buffer_size) 00152 { 00153 OVERLAPPED overlap; 00154 DWORD bytes_returned; 00155 BOOL success; 00156 DWORD transfer; 00157 00158 DPRINT("GetDeviceData\n"); 00159 00160 memset(&overlap, 0, sizeof(overlap)); 00161 00162 overlap.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL); 00163 00164 if ( ! overlap.hEvent ) 00165 return MMSYSERR_NOMEM; 00166 00167 success = DeviceIoControl(device_handle, 00168 ioctl, 00169 NULL, 00170 0, 00171 output_buffer, 00172 buffer_size, 00173 &bytes_returned, 00174 &overlap); 00175 00176 if ( ! success ) 00177 { 00178 if ( GetLastError() == ERROR_IO_PENDING ) 00179 { 00180 if ( ! GetOverlappedResult(device_handle, &overlap, &transfer, TRUE) ) 00181 { 00182 CloseHandle(overlap.hEvent); 00183 return ErrorToMmResult(GetLastError()); 00184 } 00185 } 00186 else 00187 { 00188 CloseHandle(overlap.hEvent); 00189 return ErrorToMmResult(GetLastError()); 00190 } 00191 } 00192 00193 while ( TRUE ) 00194 { 00195 SetEvent(overlap.hEvent); 00196 00197 if ( WaitForSingleObjectEx(overlap.hEvent, 0, TRUE) != WAIT_IO_COMPLETION ) 00198 { 00199 break; 00200 } 00201 } 00202 00203 CloseHandle(overlap.hEvent); 00204 00205 return MMSYSERR_NOERROR; 00206 } Generated on Sat May 26 2012 04:23:16 for ReactOS by
1.7.6.1
|