ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

kernel.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.