Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenlegacy.c
Go to the documentation of this file.
00001 /* 00002 * PROJECT: ReactOS Sound System 00003 * LICENSE: GPL - See COPYING in the top level directory 00004 * FILE: dll/win32/wdmaud.drv/wdmaud.c 00005 * 00006 * PURPOSE: WDM Audio Driver (User-mode part) 00007 * PROGRAMMERS: Andrew Greenwood (silverblade@reactos.org) 00008 Johannes Anderwald 00009 * 00010 * NOTES: Looking for wodMessage & co? You won't find them here. Try 00011 * the MME Buddy library, which is where these routines are 00012 * actually implemented. 00013 * 00014 */ 00015 00016 #include "wdmaud.h" 00017 00018 #define KERNEL_DEVICE_NAME L"\\\\.\\wdmaud" 00019 00020 HANDLE KernelHandle = INVALID_HANDLE_VALUE; 00021 DWORD OpenCount = 0; 00022 00023 DWORD 00024 WINAPI 00025 MixerEventThreadRoutine( 00026 LPVOID Parameter) 00027 { 00028 HANDLE WaitObjects[2]; 00029 DWORD dwResult; 00030 MMRESULT Result; 00031 WDMAUD_DEVICE_INFO DeviceInfo; 00032 PSOUND_DEVICE_INSTANCE Instance = (PSOUND_DEVICE_INSTANCE)Parameter; 00033 00034 /* setup wait objects */ 00035 WaitObjects[0] = Instance->hNotifyEvent; 00036 WaitObjects[1] = Instance->hStopEvent; 00037 00038 /* zero device info */ 00039 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00040 00041 DeviceInfo.hDevice = Instance->Handle; 00042 DeviceInfo.DeviceType = MIXER_DEVICE_TYPE; 00043 00044 do 00045 { 00046 dwResult = WaitForMultipleObjects(2, WaitObjects, FALSE, INFINITE); 00047 00048 if (dwResult == WAIT_OBJECT_0 + 1) 00049 { 00050 /* stop event was signalled */ 00051 break; 00052 } 00053 00054 do 00055 { 00056 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00057 IOCTL_GET_MIXER_EVENT, 00058 (LPVOID) &DeviceInfo, 00059 sizeof(WDMAUD_DEVICE_INFO), 00060 (LPVOID) &DeviceInfo, 00061 sizeof(WDMAUD_DEVICE_INFO), 00062 NULL); 00063 00064 if (Result == MMSYSERR_NOERROR) 00065 { 00066 DriverCallback(Instance->WinMM.ClientCallback, 00067 HIWORD(Instance->WinMM.Flags), 00068 Instance->WinMM.Handle, 00069 DeviceInfo.u.MixerEvent.NotificationType, 00070 Instance->WinMM.ClientCallbackInstanceData, 00071 (DWORD_PTR)DeviceInfo.u.MixerEvent.Value, 00072 0); 00073 } 00074 }while(Result == MMSYSERR_NOERROR); 00075 }while(TRUE); 00076 00077 /* done */ 00078 return 0; 00079 } 00080 00081 MMRESULT 00082 WdmAudCleanupByLegacy() 00083 { 00084 if (KernelHandle != INVALID_HANDLE_VALUE) 00085 { 00086 CloseHandle(KernelHandle); 00087 KernelHandle = INVALID_HANDLE_VALUE; 00088 } 00089 00090 return MMSYSERR_NOERROR; 00091 } 00092 00093 MMRESULT 00094 WdmAudGetNumWdmDevsByLegacy( 00095 IN MMDEVICE_TYPE DeviceType, 00096 OUT DWORD* DeviceCount) 00097 { 00098 MMRESULT Result; 00099 WDMAUD_DEVICE_INFO DeviceInfo; 00100 00101 VALIDATE_MMSYS_PARAMETER( KernelHandle != INVALID_HANDLE_VALUE ); 00102 VALIDATE_MMSYS_PARAMETER( IS_VALID_SOUND_DEVICE_TYPE(DeviceType) ); 00103 VALIDATE_MMSYS_PARAMETER( DeviceCount ); 00104 00105 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00106 DeviceInfo.DeviceType = DeviceType; 00107 00108 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00109 IOCTL_GETNUMDEVS_TYPE, 00110 (LPVOID) &DeviceInfo, 00111 sizeof(WDMAUD_DEVICE_INFO), 00112 (LPVOID) &DeviceInfo, 00113 sizeof(WDMAUD_DEVICE_INFO), 00114 NULL); 00115 00116 if ( ! MMSUCCESS( Result ) ) 00117 { 00118 SND_ERR(L"Call to IOCTL_GETNUMDEVS_TYPE failed\n"); 00119 *DeviceCount = 0; 00120 return TranslateInternalMmResult(Result); 00121 } 00122 00123 *DeviceCount = DeviceInfo.DeviceCount; 00124 00125 return MMSYSERR_NOERROR; 00126 } 00127 00128 MMRESULT 00129 WdmAudGetCapabilitiesByLegacy( 00130 IN PSOUND_DEVICE SoundDevice, 00131 IN DWORD DeviceId, 00132 OUT PVOID Capabilities, 00133 IN DWORD CapabilitiesSize) 00134 { 00135 MMRESULT Result; 00136 MMDEVICE_TYPE DeviceType; 00137 WDMAUD_DEVICE_INFO DeviceInfo; 00138 00139 SND_ASSERT( SoundDevice ); 00140 SND_ASSERT( Capabilities ); 00141 00142 Result = GetSoundDeviceType(SoundDevice, &DeviceType); 00143 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00144 00145 if ( ! MMSUCCESS(Result) ) 00146 return Result; 00147 00148 SND_TRACE(L"WDMAUD - GetWdmDeviceCapabilities DeviceType %u DeviceId %u\n", DeviceType, DeviceId); 00149 00150 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00151 DeviceInfo.DeviceType = DeviceType; 00152 DeviceInfo.DeviceIndex = DeviceId; 00153 00154 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00155 IOCTL_GETCAPABILITIES, 00156 (LPVOID) &DeviceInfo, 00157 sizeof(WDMAUD_DEVICE_INFO), 00158 (LPVOID) &DeviceInfo, 00159 sizeof(WDMAUD_DEVICE_INFO), 00160 NULL); 00161 00162 if ( ! MMSUCCESS(Result) ) 00163 { 00164 return TranslateInternalMmResult(Result); 00165 } 00166 00167 /* This is pretty much a big hack right now */ 00168 switch ( DeviceType ) 00169 { 00170 case MIXER_DEVICE_TYPE: 00171 { 00172 LPMIXERCAPSW MixerCaps = (LPMIXERCAPSW) Capabilities; 00173 00174 DeviceInfo.u.MixCaps.szPname[MAXPNAMELEN-1] = L'\0'; 00175 CopyWideString(MixerCaps->szPname, DeviceInfo.u.MixCaps.szPname); 00176 00177 MixerCaps->cDestinations = DeviceInfo.u.MixCaps.cDestinations; 00178 MixerCaps->fdwSupport = DeviceInfo.u.MixCaps.fdwSupport; 00179 MixerCaps->vDriverVersion = DeviceInfo.u.MixCaps.vDriverVersion; 00180 MixerCaps->wMid = DeviceInfo.u.MixCaps.wMid; 00181 MixerCaps->wPid = DeviceInfo.u.MixCaps.wPid; 00182 break; 00183 } 00184 case WAVE_OUT_DEVICE_TYPE : 00185 { 00186 LPWAVEOUTCAPSW WaveOutCaps = (LPWAVEOUTCAPSW) Capabilities; 00187 00188 DeviceInfo.u.WaveOutCaps.szPname[MAXPNAMELEN-1] = L'\0'; 00189 WaveOutCaps->wMid = DeviceInfo.u.WaveOutCaps.wMid; 00190 WaveOutCaps->wPid = DeviceInfo.u.WaveOutCaps.wPid; 00191 00192 WaveOutCaps->vDriverVersion = DeviceInfo.u.WaveOutCaps.vDriverVersion; 00193 CopyWideString(WaveOutCaps->szPname, DeviceInfo.u.WaveOutCaps.szPname); 00194 00195 WaveOutCaps->dwFormats = DeviceInfo.u.WaveOutCaps.dwFormats; 00196 WaveOutCaps->wChannels = DeviceInfo.u.WaveOutCaps.wChannels; 00197 WaveOutCaps->dwSupport = DeviceInfo.u.WaveOutCaps.dwSupport; 00198 break; 00199 } 00200 case WAVE_IN_DEVICE_TYPE : 00201 { 00202 LPWAVEINCAPSW WaveInCaps = (LPWAVEINCAPSW) Capabilities; 00203 00204 DeviceInfo.u.WaveInCaps.szPname[MAXPNAMELEN-1] = L'\0'; 00205 00206 WaveInCaps->wMid = DeviceInfo.u.WaveInCaps.wMid; 00207 WaveInCaps->wPid = DeviceInfo.u.WaveInCaps.wPid; 00208 00209 WaveInCaps->vDriverVersion = DeviceInfo.u.WaveInCaps.vDriverVersion; 00210 CopyWideString(WaveInCaps->szPname, DeviceInfo.u.WaveInCaps.szPname); 00211 00212 WaveInCaps->dwFormats = DeviceInfo.u.WaveInCaps.dwFormats; 00213 WaveInCaps->wChannels = DeviceInfo.u.WaveInCaps.wChannels; 00214 WaveInCaps->wReserved1 = 0; 00215 break; 00216 } 00217 case MIDI_IN_DEVICE_TYPE : 00218 { 00219 LPMIDIINCAPSW MidiInCaps = (LPMIDIINCAPSW)Capabilities; 00220 00221 DeviceInfo.u.MidiInCaps.szPname[MAXPNAMELEN-1] = L'\0'; 00222 00223 MidiInCaps->vDriverVersion = DeviceInfo.u.MidiInCaps.vDriverVersion; 00224 MidiInCaps->wMid = DeviceInfo.u.MidiInCaps.wMid; 00225 MidiInCaps->wPid = DeviceInfo.u.MidiInCaps.wPid; 00226 MidiInCaps->dwSupport = DeviceInfo.u.MidiInCaps.dwSupport; 00227 00228 CopyWideString(MidiInCaps->szPname, DeviceInfo.u.MidiInCaps.szPname); 00229 break; 00230 } 00231 case MIDI_OUT_DEVICE_TYPE : 00232 { 00233 LPMIDIOUTCAPSW MidiOutCaps = (LPMIDIOUTCAPSW)Capabilities; 00234 00235 DeviceInfo.u.MidiOutCaps.szPname[MAXPNAMELEN-1] = L'\0'; 00236 00237 MidiOutCaps->vDriverVersion = DeviceInfo.u.MidiOutCaps.vDriverVersion; 00238 MidiOutCaps->wMid = DeviceInfo.u.MidiOutCaps.wMid; 00239 MidiOutCaps->wPid = DeviceInfo.u.MidiOutCaps.wPid; 00240 MidiOutCaps->dwSupport = DeviceInfo.u.MidiOutCaps.dwSupport; 00241 00242 CopyWideString(MidiOutCaps->szPname, DeviceInfo.u.MidiOutCaps.szPname); 00243 break; 00244 } 00245 } 00246 00247 return MMSYSERR_NOERROR; 00248 } 00249 00250 MMRESULT 00251 WdmAudOpenSoundDeviceByLegacy( 00252 IN PSOUND_DEVICE SoundDevice, 00253 OUT PVOID *Handle) 00254 { 00255 /* Only open this if it's not already open */ 00256 if ( KernelHandle == INVALID_HANDLE_VALUE ) 00257 { 00258 SND_TRACE(L"Opening wdmaud device\n"); 00259 KernelHandle = CreateFileW(KERNEL_DEVICE_NAME, 00260 GENERIC_READ | GENERIC_WRITE, 00261 0, 00262 NULL, 00263 OPEN_EXISTING, 00264 FILE_FLAG_OVERLAPPED, 00265 NULL); 00266 } 00267 00268 if ( KernelHandle == INVALID_HANDLE_VALUE ) 00269 return MMSYSERR_ERROR; 00270 00271 ++ OpenCount; 00272 00273 return MMSYSERR_NOERROR; 00274 } 00275 00276 MMRESULT 00277 WdmAudCloseSoundDeviceByLegacy( 00278 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, 00279 IN PVOID Handle) 00280 { 00281 WDMAUD_DEVICE_INFO DeviceInfo; 00282 MMRESULT Result; 00283 MMDEVICE_TYPE DeviceType; 00284 PSOUND_DEVICE SoundDevice; 00285 00286 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); 00287 00288 if ( ! MMSUCCESS(Result) ) 00289 { 00290 return TranslateInternalMmResult(Result); 00291 } 00292 00293 if ( OpenCount == 0 ) 00294 { 00295 return MMSYSERR_NOERROR; 00296 } 00297 00298 SND_ASSERT( KernelHandle != INVALID_HANDLE_VALUE ); 00299 00300 Result = GetSoundDeviceType(SoundDevice, &DeviceType); 00301 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00302 00303 if (SoundDeviceInstance->Handle != (PVOID)KernelHandle) 00304 { 00305 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00306 00307 DeviceInfo.DeviceType = DeviceType; 00308 DeviceInfo.hDevice = SoundDeviceInstance->Handle; 00309 00310 /* First stop the stream */ 00311 if (DeviceType != MIXER_DEVICE_TYPE) 00312 { 00313 DeviceInfo.u.State = KSSTATE_PAUSE; 00314 SyncOverlappedDeviceIoControl(KernelHandle, 00315 IOCTL_SETDEVICE_STATE, 00316 (LPVOID) &DeviceInfo, 00317 sizeof(WDMAUD_DEVICE_INFO), 00318 (LPVOID) &DeviceInfo, 00319 sizeof(WDMAUD_DEVICE_INFO), 00320 NULL); 00321 00322 DeviceInfo.u.State = KSSTATE_ACQUIRE; 00323 SyncOverlappedDeviceIoControl(KernelHandle, 00324 IOCTL_SETDEVICE_STATE, 00325 (LPVOID) &DeviceInfo, 00326 sizeof(WDMAUD_DEVICE_INFO), 00327 (LPVOID) &DeviceInfo, 00328 sizeof(WDMAUD_DEVICE_INFO), 00329 NULL); 00330 00331 00332 DeviceInfo.u.State = KSSTATE_STOP; 00333 SyncOverlappedDeviceIoControl(KernelHandle, 00334 IOCTL_SETDEVICE_STATE, 00335 (LPVOID) &DeviceInfo, 00336 sizeof(WDMAUD_DEVICE_INFO), 00337 (LPVOID) &DeviceInfo, 00338 sizeof(WDMAUD_DEVICE_INFO), 00339 NULL); 00340 } 00341 00342 SyncOverlappedDeviceIoControl(KernelHandle, 00343 IOCTL_CLOSE_WDMAUD, 00344 (LPVOID) &DeviceInfo, 00345 sizeof(WDMAUD_DEVICE_INFO), 00346 (LPVOID) &DeviceInfo, 00347 sizeof(WDMAUD_DEVICE_INFO), 00348 NULL); 00349 } 00350 00351 if (DeviceType == MIXER_DEVICE_TYPE) 00352 { 00353 SetEvent(SoundDeviceInstance->hStopEvent); 00354 CloseHandle(SoundDeviceInstance->hStopEvent); 00355 CloseHandle(SoundDeviceInstance->hNotifyEvent); 00356 } 00357 00358 --OpenCount; 00359 00360 if ( OpenCount < 1 ) 00361 { 00362 CloseHandle(KernelHandle); 00363 KernelHandle = INVALID_HANDLE_VALUE; 00364 } 00365 00366 return MMSYSERR_NOERROR; 00367 } 00368 00369 MMRESULT 00370 WdmAudSetMixerDeviceFormatByLegacy( 00371 IN PSOUND_DEVICE_INSTANCE Instance, 00372 IN DWORD DeviceId, 00373 IN PWAVEFORMATEX WaveFormat, 00374 IN DWORD WaveFormatSize) 00375 { 00376 MMRESULT Result; 00377 WDMAUD_DEVICE_INFO DeviceInfo; 00378 HANDLE hThread; 00379 00380 Instance->hNotifyEvent = CreateEventW(NULL, FALSE, FALSE, NULL); 00381 if ( ! Instance->hNotifyEvent ) 00382 return MMSYSERR_NOMEM; 00383 00384 if (Instance->Handle != NULL) 00385 { 00386 /* device is already open */ 00387 return MMSYSERR_NOERROR; 00388 } 00389 00390 Instance->hStopEvent = CreateEventW(NULL, FALSE, FALSE, NULL); 00391 if ( ! Instance->hStopEvent ) 00392 return MMSYSERR_NOMEM; 00393 00394 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00395 DeviceInfo.DeviceType = MIXER_DEVICE_TYPE; 00396 DeviceInfo.DeviceIndex = DeviceId; 00397 DeviceInfo.u.hNotifyEvent = Instance->hNotifyEvent; 00398 00399 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00400 IOCTL_OPEN_WDMAUD, 00401 (LPVOID) &DeviceInfo, 00402 sizeof(WDMAUD_DEVICE_INFO), 00403 (LPVOID) &DeviceInfo, 00404 sizeof(WDMAUD_DEVICE_INFO), 00405 NULL); 00406 00407 if ( ! MMSUCCESS(Result) ) 00408 { 00409 CloseHandle(Instance->hNotifyEvent); 00410 CloseHandle(Instance->hStopEvent); 00411 return TranslateInternalMmResult(Result); 00412 } 00413 00414 hThread = CreateThread(NULL, 0, MixerEventThreadRoutine, (LPVOID)Instance, 0, NULL); 00415 if ( hThread ) 00416 { 00417 CloseHandle(hThread); 00418 } 00419 00420 /* Store sound device handle instance handle */ 00421 Instance->Handle = (PVOID)DeviceInfo.hDevice; 00422 00423 return MMSYSERR_NOERROR; 00424 } 00425 00426 MMRESULT 00427 WdmAudSetWaveDeviceFormatByLegacy( 00428 IN PSOUND_DEVICE_INSTANCE Instance, 00429 IN DWORD DeviceId, 00430 IN PWAVEFORMATEX WaveFormat, 00431 IN DWORD WaveFormatSize) 00432 { 00433 MMRESULT Result; 00434 PSOUND_DEVICE SoundDevice; 00435 PVOID Identifier; 00436 WDMAUD_DEVICE_INFO DeviceInfo; 00437 MMDEVICE_TYPE DeviceType; 00438 00439 Result = GetSoundDeviceFromInstance(Instance, &SoundDevice); 00440 00441 if ( ! MMSUCCESS(Result) ) 00442 { 00443 return TranslateInternalMmResult(Result); 00444 } 00445 00446 Result = GetSoundDeviceIdentifier(SoundDevice, &Identifier); 00447 00448 if ( ! MMSUCCESS(Result) ) 00449 { 00450 return TranslateInternalMmResult(Result); 00451 } 00452 00453 if (Instance->Handle != NULL) 00454 { 00455 /* device is already open */ 00456 return MMSYSERR_NOERROR; 00457 } 00458 00459 Result = GetSoundDeviceType(SoundDevice, &DeviceType); 00460 00461 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00462 00463 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00464 DeviceInfo.DeviceType = DeviceType; 00465 DeviceInfo.DeviceIndex = DeviceId; 00466 DeviceInfo.u.WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); //WaveFormat->cbSize; 00467 DeviceInfo.u.WaveFormatEx.wFormatTag = WaveFormat->wFormatTag; 00468 #ifdef USERMODE_MIXER 00469 DeviceInfo.u.WaveFormatEx.nChannels = 2; 00470 DeviceInfo.u.WaveFormatEx.nSamplesPerSec = 44100; 00471 DeviceInfo.u.WaveFormatEx.nBlockAlign = 4; 00472 DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = 176400; 00473 DeviceInfo.u.WaveFormatEx.wBitsPerSample = 16; 00474 #else 00475 DeviceInfo.u.WaveFormatEx.nChannels = WaveFormat->nChannels; 00476 DeviceInfo.u.WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec; 00477 DeviceInfo.u.WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign; 00478 DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec; 00479 DeviceInfo.u.WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels); 00480 #endif 00481 00482 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00483 IOCTL_OPEN_WDMAUD, 00484 (LPVOID) &DeviceInfo, 00485 sizeof(WDMAUD_DEVICE_INFO), 00486 (LPVOID) &DeviceInfo, 00487 sizeof(WDMAUD_DEVICE_INFO), 00488 NULL); 00489 00490 if ( ! MMSUCCESS(Result) ) 00491 { 00492 return TranslateInternalMmResult(Result); 00493 } 00494 00495 if (WaveFormatSize >= sizeof(WAVEFORMAT)) 00496 { 00497 /* Store format */ 00498 Instance->WaveFormatEx.wFormatTag = WaveFormat->wFormatTag; 00499 Instance->WaveFormatEx.nChannels = WaveFormat->nChannels; 00500 Instance->WaveFormatEx.nSamplesPerSec = WaveFormat->nSamplesPerSec; 00501 Instance->WaveFormatEx.nBlockAlign = WaveFormat->nBlockAlign; 00502 Instance->WaveFormatEx.nAvgBytesPerSec = WaveFormat->nAvgBytesPerSec; 00503 } 00504 00505 /* store details */ 00506 Instance->WaveFormatEx.cbSize = sizeof(WAVEFORMATEX); 00507 Instance->WaveFormatEx.wBitsPerSample = (DeviceInfo.u.WaveFormatEx.nAvgBytesPerSec * 8) / (DeviceInfo.u.WaveFormatEx.nSamplesPerSec * DeviceInfo.u.WaveFormatEx.nChannels); 00508 00509 /* Store sound device handle instance handle */ 00510 Instance->Handle = (PVOID)DeviceInfo.hDevice; 00511 00512 /* Now determine framing requirements */ 00513 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00514 IOCTL_GETFRAMESIZE, 00515 (LPVOID) &DeviceInfo, 00516 sizeof(WDMAUD_DEVICE_INFO), 00517 (LPVOID) &DeviceInfo, 00518 sizeof(WDMAUD_DEVICE_INFO), 00519 NULL); 00520 00521 if ( MMSUCCESS(Result) ) 00522 { 00523 if (DeviceInfo.u.FrameSize) 00524 { 00525 Instance->FrameSize = DeviceInfo.u.FrameSize * 2; 00526 Instance->BufferCount = WaveFormat->nAvgBytesPerSec / Instance->FrameSize; 00527 SND_TRACE(L"FrameSize %u BufferCount %u\n", Instance->FrameSize, Instance->BufferCount); 00528 } 00529 } 00530 else 00531 { 00532 // use a default of 100 buffers 00533 Instance->BufferCount = 100; 00534 } 00535 00536 /* Now acquire resources */ 00537 DeviceInfo.u.State = KSSTATE_ACQUIRE; 00538 SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); 00539 00540 /* pause the pin */ 00541 DeviceInfo.u.State = KSSTATE_PAUSE; 00542 SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); 00543 00544 /* start the pin */ 00545 DeviceInfo.u.State = KSSTATE_RUN; 00546 SyncOverlappedDeviceIoControl(KernelHandle, IOCTL_SETDEVICE_STATE, (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPVOID) &DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), NULL); 00547 00548 00549 return MMSYSERR_NOERROR; 00550 } 00551 00552 VOID 00553 CALLBACK 00554 LegacyCompletionRoutine( 00555 IN DWORD dwErrorCode, 00556 IN DWORD dwNumberOfBytesTransferred, 00557 IN LPOVERLAPPED lpOverlapped) 00558 { 00559 PSOUND_OVERLAPPED Overlap; 00560 PWDMAUD_DEVICE_INFO DeviceInfo; 00561 00562 Overlap = (PSOUND_OVERLAPPED)lpOverlapped; 00563 DeviceInfo = (PWDMAUD_DEVICE_INFO)Overlap->CompletionContext; 00564 00565 /* Call mmebuddy overlap routine */ 00566 Overlap->OriginalCompletionRoutine(dwErrorCode, DeviceInfo->Header.DataUsed, lpOverlapped); 00567 00568 HeapFree(GetProcessHeap(), 0, DeviceInfo); 00569 } 00570 00571 MMRESULT 00572 WdmAudCommitWaveBufferByLegacy( 00573 IN PSOUND_DEVICE_INSTANCE SoundDeviceInstance, 00574 IN PVOID OffsetPtr, 00575 IN DWORD Length, 00576 IN PSOUND_OVERLAPPED Overlap, 00577 IN LPOVERLAPPED_COMPLETION_ROUTINE CompletionRoutine) 00578 { 00579 HANDLE Handle; 00580 MMRESULT Result; 00581 PWDMAUD_DEVICE_INFO DeviceInfo; 00582 PSOUND_DEVICE SoundDevice; 00583 MMDEVICE_TYPE DeviceType; 00584 BOOL Ret; 00585 00586 VALIDATE_MMSYS_PARAMETER( SoundDeviceInstance ); 00587 VALIDATE_MMSYS_PARAMETER( OffsetPtr ); 00588 VALIDATE_MMSYS_PARAMETER( Overlap ); 00589 VALIDATE_MMSYS_PARAMETER( CompletionRoutine ); 00590 00591 GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); 00592 SND_ASSERT(Handle); 00593 00594 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); 00595 00596 if ( ! MMSUCCESS(Result) ) 00597 { 00598 return TranslateInternalMmResult(Result); 00599 } 00600 00601 Result = GetSoundDeviceType(SoundDevice, &DeviceType); 00602 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00603 00604 DeviceInfo = (PWDMAUD_DEVICE_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WDMAUD_DEVICE_INFO)); 00605 if (!DeviceInfo) 00606 { 00607 // no memory 00608 return MMSYSERR_NOMEM; 00609 } 00610 00611 DeviceInfo->Header.FrameExtent = Length; 00612 if (DeviceType == WAVE_OUT_DEVICE_TYPE) 00613 { 00614 DeviceInfo->Header.DataUsed = Length; 00615 } 00616 DeviceInfo->Header.Data = OffsetPtr; 00617 DeviceInfo->Header.Size = sizeof(WDMAUD_DEVICE_INFO); 00618 DeviceInfo->Header.PresentationTime.Numerator = 1; 00619 DeviceInfo->Header.PresentationTime.Denominator = 1; 00620 DeviceInfo->hDevice = Handle; 00621 DeviceInfo->DeviceType = DeviceType; 00622 00623 00624 // create completion event 00625 Overlap->Standard.hEvent = Handle = CreateEventW(NULL, FALSE, FALSE, NULL); 00626 if (Overlap->Standard.hEvent == NULL) 00627 { 00628 // no memory 00629 return MMSYSERR_NOMEM; 00630 } 00631 00632 Overlap->OriginalCompletionRoutine = CompletionRoutine; 00633 Overlap->CompletionContext = (PVOID)DeviceInfo; 00634 00635 if (DeviceType == WAVE_OUT_DEVICE_TYPE) 00636 { 00637 Ret = WriteFileEx(KernelHandle, DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, LegacyCompletionRoutine); 00638 if (Ret) 00639 WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE); 00640 } 00641 else if (DeviceType == WAVE_IN_DEVICE_TYPE) 00642 { 00643 Ret = ReadFileEx(KernelHandle, DeviceInfo, sizeof(WDMAUD_DEVICE_INFO), (LPOVERLAPPED)Overlap, LegacyCompletionRoutine); 00644 if (Ret) 00645 WaitForSingleObjectEx (KernelHandle, INFINITE, TRUE); 00646 } 00647 00648 // close event handle 00649 CloseHandle(Handle); 00650 00651 return MMSYSERR_NOERROR; 00652 } 00653 00654 MMRESULT 00655 WdmAudSetWaveStateByLegacy( 00656 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, 00657 IN BOOL bStart) 00658 { 00659 MMRESULT Result; 00660 PSOUND_DEVICE SoundDevice; 00661 WDMAUD_DEVICE_INFO DeviceInfo; 00662 MMDEVICE_TYPE DeviceType; 00663 HANDLE Handle; 00664 00665 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); 00666 00667 if ( ! MMSUCCESS(Result) ) 00668 { 00669 return TranslateInternalMmResult(Result); 00670 } 00671 00672 Result = GetSoundDeviceType(SoundDevice, &DeviceType); 00673 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00674 00675 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); 00676 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00677 00678 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00679 DeviceInfo.hDevice = Handle; 00680 DeviceInfo.DeviceType = DeviceType; 00681 00682 if (bStart) 00683 DeviceInfo.u.State = KSSTATE_RUN; 00684 else 00685 DeviceInfo.u.State = KSSTATE_PAUSE; 00686 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00687 IOCTL_SETDEVICE_STATE, 00688 (LPVOID) &DeviceInfo, 00689 sizeof(WDMAUD_DEVICE_INFO), 00690 (LPVOID) &DeviceInfo, 00691 sizeof(WDMAUD_DEVICE_INFO), 00692 NULL); 00693 00694 return Result; 00695 } 00696 00697 MMRESULT 00698 WdmAudGetDeviceInterfaceStringByLegacy( 00699 IN MMDEVICE_TYPE DeviceType, 00700 IN DWORD DeviceId, 00701 IN LPWSTR Interface, 00702 IN DWORD InterfaceLength, 00703 OUT DWORD * InterfaceSize) 00704 { 00705 WDMAUD_DEVICE_INFO DeviceInfo; 00706 MMRESULT Result; 00707 00708 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00709 DeviceInfo.DeviceType = DeviceType; 00710 DeviceInfo.DeviceIndex = DeviceId; 00711 00712 00713 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00714 IOCTL_QUERYDEVICEINTERFACESTRING, 00715 (LPVOID) &DeviceInfo, 00716 sizeof(WDMAUD_DEVICE_INFO), 00717 (LPVOID) &DeviceInfo, 00718 sizeof(WDMAUD_DEVICE_INFO), 00719 NULL); 00720 00721 00722 if ( ! MMSUCCESS(Result) ) 00723 { 00724 return TranslateInternalMmResult(Result); 00725 } 00726 00727 00728 if (!Interface) 00729 { 00730 SND_ASSERT(InterfaceSize); 00731 00732 *InterfaceSize = DeviceInfo.u.Interface.DeviceInterfaceStringSize; 00733 return MMSYSERR_NOERROR; 00734 } 00735 00736 if (InterfaceLength < DeviceInfo.u.Interface.DeviceInterfaceStringSize) 00737 { 00738 /* buffer is too small */ 00739 return MMSYSERR_MOREDATA; 00740 } 00741 00742 DeviceInfo.u.Interface.DeviceInterfaceStringSize = InterfaceLength; 00743 DeviceInfo.u.Interface.DeviceInterfaceString = Interface; 00744 00745 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00746 IOCTL_QUERYDEVICEINTERFACESTRING, 00747 (LPVOID) &DeviceInfo, 00748 sizeof(WDMAUD_DEVICE_INFO), 00749 (LPVOID) &DeviceInfo, 00750 sizeof(WDMAUD_DEVICE_INFO), 00751 NULL); 00752 00753 if ( MMSUCCESS(Result) && InterfaceLength > 2) 00754 { 00755 Interface[1] = L'\\'; 00756 Interface[InterfaceLength-1] = L'\0'; 00757 } 00758 00759 return Result; 00760 } 00761 00762 MMRESULT 00763 WdmAudGetWavePositionByLegacy( 00764 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, 00765 IN MMTIME* Time) 00766 { 00767 MMRESULT Result; 00768 PSOUND_DEVICE SoundDevice; 00769 WDMAUD_DEVICE_INFO DeviceInfo; 00770 MMDEVICE_TYPE DeviceType; 00771 HANDLE Handle; 00772 00773 Result = GetSoundDeviceFromInstance(SoundDeviceInstance, &SoundDevice); 00774 00775 if ( ! MMSUCCESS(Result) ) 00776 { 00777 return TranslateInternalMmResult(Result); 00778 } 00779 00780 Result = GetSoundDeviceType(SoundDevice, &DeviceType); 00781 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00782 00783 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); 00784 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00785 00786 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00787 DeviceInfo.hDevice = Handle; 00788 DeviceInfo.DeviceType = DeviceType; 00789 00790 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00791 IOCTL_OPEN_WDMAUD, 00792 (LPVOID) &DeviceInfo, 00793 sizeof(WDMAUD_DEVICE_INFO), 00794 (LPVOID) &DeviceInfo, 00795 sizeof(WDMAUD_DEVICE_INFO), 00796 NULL); 00797 00798 if ( ! MMSUCCESS(Result) ) 00799 { 00800 return TranslateInternalMmResult(Result); 00801 } 00802 00803 Time->wType = TIME_BYTES; 00804 Time->u.cb = (DWORD)DeviceInfo.u.Position; 00805 00806 return MMSYSERR_NOERROR; 00807 } 00808 00809 00810 MMRESULT 00811 WdmAudResetStreamByLegacy( 00812 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, 00813 IN MMDEVICE_TYPE DeviceType, 00814 IN BOOLEAN bStartReset) 00815 { 00816 MMRESULT Result; 00817 HANDLE Handle; 00818 WDMAUD_DEVICE_INFO DeviceInfo; 00819 00820 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); 00821 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00822 00823 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00824 DeviceInfo.hDevice = Handle; 00825 DeviceInfo.DeviceType = DeviceType; 00826 DeviceInfo.u.ResetStream = (bStartReset ? KSRESET_BEGIN : KSRESET_END); 00827 00828 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00829 IOCTL_RESET_STREAM, 00830 (LPVOID) &DeviceInfo, 00831 sizeof(WDMAUD_DEVICE_INFO), 00832 (LPVOID) &DeviceInfo, 00833 sizeof(WDMAUD_DEVICE_INFO), 00834 NULL); 00835 return Result; 00836 } 00837 00838 MMRESULT 00839 WdmAudQueryMixerInfoByLegacy( 00840 IN struct _SOUND_DEVICE_INSTANCE* SoundDeviceInstance, 00841 IN DWORD DeviceId, 00842 IN UINT uMsg, 00843 IN LPVOID Parameter, 00844 IN DWORD Flags) 00845 { 00846 MMRESULT Result; 00847 WDMAUD_DEVICE_INFO DeviceInfo; 00848 HANDLE Handle; 00849 DWORD IoControlCode; 00850 LPMIXERLINEW MixLine; 00851 LPMIXERLINECONTROLSW MixControls; 00852 LPMIXERCONTROLDETAILS MixDetails; 00853 00854 SND_TRACE(L"uMsg %x Flags %x\n", uMsg, Flags); 00855 00856 Result = GetSoundDeviceInstanceHandle(SoundDeviceInstance, &Handle); 00857 SND_ASSERT( Result == MMSYSERR_NOERROR ); 00858 00859 ZeroMemory(&DeviceInfo, sizeof(WDMAUD_DEVICE_INFO)); 00860 DeviceInfo.hDevice = Handle; 00861 DeviceInfo.DeviceIndex = DeviceId; 00862 DeviceInfo.DeviceType = MIXER_DEVICE_TYPE; 00863 DeviceInfo.Flags = Flags; 00864 00865 MixLine = (LPMIXERLINEW)Parameter; 00866 MixControls = (LPMIXERLINECONTROLSW)Parameter; 00867 MixDetails = (LPMIXERCONTROLDETAILS)Parameter; 00868 00869 switch(uMsg) 00870 { 00871 case MXDM_GETLINEINFO: 00872 RtlCopyMemory(&DeviceInfo.u.MixLine, MixLine, sizeof(MIXERLINEW)); 00873 IoControlCode = IOCTL_GETLINEINFO; 00874 break; 00875 case MXDM_GETLINECONTROLS: 00876 RtlCopyMemory(&DeviceInfo.u.MixControls, MixControls, sizeof(MIXERLINECONTROLSW)); 00877 IoControlCode = IOCTL_GETLINECONTROLS; 00878 break; 00879 case MXDM_SETCONTROLDETAILS: 00880 RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS)); 00881 IoControlCode = IOCTL_SETCONTROLDETAILS; 00882 break; 00883 case MXDM_GETCONTROLDETAILS: 00884 RtlCopyMemory(&DeviceInfo.u.MixDetails, MixDetails, sizeof(MIXERCONTROLDETAILS)); 00885 IoControlCode = IOCTL_GETCONTROLDETAILS; 00886 break; 00887 default: 00888 SND_ASSERT(0); 00889 return MMSYSERR_NOTSUPPORTED; 00890 } 00891 00892 Result = SyncOverlappedDeviceIoControl(KernelHandle, 00893 IoControlCode, 00894 (LPVOID) &DeviceInfo, 00895 sizeof(WDMAUD_DEVICE_INFO), 00896 (LPVOID) &DeviceInfo, 00897 sizeof(WDMAUD_DEVICE_INFO), 00898 NULL); 00899 00900 if ( ! MMSUCCESS(Result) ) 00901 { 00902 return Result; 00903 } 00904 00905 switch(uMsg) 00906 { 00907 case MXDM_GETLINEINFO: 00908 { 00909 RtlCopyMemory(MixLine, &DeviceInfo.u.MixLine, sizeof(MIXERLINEW)); 00910 break; 00911 } 00912 } 00913 00914 return Result; 00915 } Generated on Thu May 24 2012 04:27:22 for ReactOS by
1.7.6.1
|