Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenmmixer.c
Go to the documentation of this file.
00001 /* 00002 * COPYRIGHT: See COPYING in the top level directory 00003 * PROJECT: ReactOS Kernel Streaming 00004 * FILE: drivers/wdm/audio/legacy/wdmaud/mmixer.c 00005 * PURPOSE: WDM Legacy Mixer 00006 * PROGRAMMER: Johannes Anderwald 00007 */ 00008 00009 #include "wdmaud.h" 00010 00011 00012 PVOID Alloc(ULONG NumBytes); 00013 MIXER_STATUS Close(HANDLE hDevice); 00014 VOID Free(PVOID Block); 00015 VOID Copy(PVOID Src, PVOID Dst, ULONG NumBytes); 00016 MIXER_STATUS Open(IN LPWSTR DevicePath, OUT PHANDLE hDevice); 00017 MIXER_STATUS Control(IN HANDLE hMixer, IN ULONG dwIoControlCode, IN PVOID lpInBuffer, IN ULONG nInBufferSize, OUT PVOID lpOutBuffer, ULONG nOutBufferSize, PULONG lpBytesReturned); 00018 MIXER_STATUS Enum(IN PVOID EnumContext, IN ULONG DeviceIndex, OUT LPWSTR * DeviceName, OUT PHANDLE OutHandle, OUT PHANDLE OutKey); 00019 MIXER_STATUS OpenKey(IN HANDLE hKey, IN LPWSTR SubKey, IN ULONG DesiredAccess, OUT PHANDLE OutKey); 00020 MIXER_STATUS CloseKey(IN HANDLE hKey); 00021 MIXER_STATUS QueryKeyValue(IN HANDLE hKey, IN LPWSTR KeyName, OUT PVOID * ResultBuffer, OUT PULONG ResultLength, OUT PULONG KeyType); 00022 PVOID AllocEventData(IN ULONG ExtraSize); 00023 VOID FreeEventData(IN PVOID EventData); 00024 00025 MIXER_CONTEXT MixerContext = 00026 { 00027 sizeof(MIXER_CONTEXT), 00028 NULL, 00029 Alloc, 00030 Control, 00031 Free, 00032 Open, 00033 Close, 00034 Copy, 00035 OpenKey, 00036 QueryKeyValue, 00037 CloseKey, 00038 AllocEventData, 00039 FreeEventData 00040 }; 00041 00042 GUID CategoryGuid = {STATIC_KSCATEGORY_AUDIO}; 00043 00044 MIXER_STATUS 00045 QueryKeyValue( 00046 IN HANDLE hKey, 00047 IN LPWSTR lpKeyName, 00048 OUT PVOID * ResultBuffer, 00049 OUT PULONG ResultLength, 00050 OUT PULONG KeyType) 00051 { 00052 NTSTATUS Status; 00053 UNICODE_STRING KeyName; 00054 ULONG Length; 00055 PKEY_VALUE_PARTIAL_INFORMATION PartialInformation; 00056 00057 /* initialize key name */ 00058 RtlInitUnicodeString(&KeyName, lpKeyName); 00059 00060 /* now query MatchingDeviceId key */ 00061 Status = ZwQueryValueKey(hKey, &KeyName, KeyValuePartialInformation, NULL, 0, &Length); 00062 00063 /* check for success */ 00064 if (Status != STATUS_BUFFER_TOO_SMALL) 00065 return MM_STATUS_UNSUCCESSFUL; 00066 00067 /* allocate a buffer for key data */ 00068 PartialInformation = AllocateItem(NonPagedPool, Length); 00069 00070 if (!PartialInformation) 00071 return MM_STATUS_NO_MEMORY; 00072 00073 00074 /* now query MatchingDeviceId key */ 00075 Status = ZwQueryValueKey(hKey, &KeyName, KeyValuePartialInformation, PartialInformation, Length, &Length); 00076 00077 /* check for success */ 00078 if (!NT_SUCCESS(Status)) 00079 { 00080 FreeItem(PartialInformation); 00081 return MM_STATUS_UNSUCCESSFUL; 00082 } 00083 00084 if (KeyType) 00085 { 00086 /* return key type */ 00087 *KeyType = PartialInformation->Type; 00088 } 00089 00090 if (ResultLength) 00091 { 00092 /* return data length */ 00093 *ResultLength = PartialInformation->DataLength; 00094 } 00095 00096 *ResultBuffer = AllocateItem(NonPagedPool, PartialInformation->DataLength); 00097 if (!*ResultBuffer) 00098 { 00099 /* not enough memory */ 00100 FreeItem(PartialInformation); 00101 return MM_STATUS_NO_MEMORY; 00102 } 00103 00104 /* copy key value */ 00105 RtlMoveMemory(*ResultBuffer, PartialInformation->Data, PartialInformation->DataLength); 00106 00107 /* free key info */ 00108 FreeItem(PartialInformation); 00109 00110 return MM_STATUS_SUCCESS; 00111 } 00112 00113 MIXER_STATUS 00114 OpenKey( 00115 IN HANDLE hKey, 00116 IN LPWSTR lpSubKeyName, 00117 IN ULONG DesiredAccess, 00118 OUT PHANDLE OutKey) 00119 { 00120 OBJECT_ATTRIBUTES ObjectAttributes; 00121 UNICODE_STRING SubKeyName; 00122 NTSTATUS Status; 00123 00124 /* initialize sub key name */ 00125 RtlInitUnicodeString(&SubKeyName, lpSubKeyName); 00126 00127 /* initialize key attributes */ 00128 InitializeObjectAttributes(&ObjectAttributes, &SubKeyName, OBJ_CASE_INSENSITIVE | OBJ_OPENIF, hKey, NULL); 00129 00130 /* open the key */ 00131 Status = ZwOpenKey(OutKey, DesiredAccess, &ObjectAttributes); 00132 00133 if (NT_SUCCESS(Status)) 00134 return MM_STATUS_SUCCESS; 00135 else 00136 return MM_STATUS_UNSUCCESSFUL; 00137 } 00138 00139 MIXER_STATUS 00140 CloseKey( 00141 IN HANDLE hKey) 00142 { 00143 if (ZwClose(hKey) == STATUS_SUCCESS) 00144 return MM_STATUS_SUCCESS; 00145 else 00146 return MM_STATUS_UNSUCCESSFUL; 00147 } 00148 00149 00150 PVOID Alloc(ULONG NumBytes) 00151 { 00152 return AllocateItem(NonPagedPool, NumBytes); 00153 } 00154 00155 MIXER_STATUS 00156 Close(HANDLE hDevice) 00157 { 00158 if (ZwClose(hDevice) == STATUS_SUCCESS) 00159 return MM_STATUS_SUCCESS; 00160 else 00161 return MM_STATUS_UNSUCCESSFUL; 00162 } 00163 00164 VOID 00165 Free(PVOID Block) 00166 { 00167 FreeItem(Block); 00168 } 00169 00170 VOID 00171 Copy(PVOID Src, PVOID Dst, ULONG NumBytes) 00172 { 00173 RtlMoveMemory(Src, Dst, NumBytes); 00174 } 00175 00176 MIXER_STATUS 00177 Open( 00178 IN LPWSTR DevicePath, 00179 OUT PHANDLE hDevice) 00180 { 00181 if (WdmAudOpenSysAudioDevice(DevicePath, hDevice) == STATUS_SUCCESS) 00182 return MM_STATUS_SUCCESS; 00183 else 00184 return MM_STATUS_UNSUCCESSFUL; 00185 } 00186 00187 MIXER_STATUS 00188 Control( 00189 IN HANDLE hMixer, 00190 IN ULONG dwIoControlCode, 00191 IN PVOID lpInBuffer, 00192 IN ULONG nInBufferSize, 00193 OUT PVOID lpOutBuffer, 00194 ULONG nOutBufferSize, 00195 PULONG lpBytesReturned) 00196 { 00197 NTSTATUS Status; 00198 PFILE_OBJECT FileObject; 00199 00200 /* get file object */ 00201 Status = ObReferenceObjectByHandle(hMixer, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); 00202 if (!NT_SUCCESS(Status)) 00203 { 00204 DPRINT("failed to reference %p with %lx\n", hMixer, Status); 00205 return MM_STATUS_UNSUCCESSFUL; 00206 } 00207 00208 /* perform request */ 00209 Status = KsSynchronousIoControlDevice(FileObject, KernelMode, dwIoControlCode, lpInBuffer, nInBufferSize, lpOutBuffer, nOutBufferSize, lpBytesReturned); 00210 00211 /* release object reference */ 00212 ObDereferenceObject(FileObject); 00213 00214 if (Status == STATUS_MORE_ENTRIES || Status == STATUS_BUFFER_OVERFLOW || Status == STATUS_BUFFER_TOO_SMALL) 00215 { 00216 /* more data is available */ 00217 return MM_STATUS_MORE_ENTRIES; 00218 } 00219 else if (Status == STATUS_SUCCESS) 00220 { 00221 /* operation succeeded */ 00222 return MM_STATUS_SUCCESS; 00223 } 00224 else 00225 { 00226 DPRINT("Failed with %lx\n", Status); 00227 return MM_STATUS_UNSUCCESSFUL; 00228 } 00229 } 00230 00231 MIXER_STATUS 00232 Enum( 00233 IN PVOID EnumContext, 00234 IN ULONG DeviceIndex, 00235 OUT LPWSTR * DeviceName, 00236 OUT PHANDLE OutHandle, 00237 OUT PHANDLE OutKey) 00238 { 00239 PDEVICE_OBJECT DeviceObject; 00240 ULONG DeviceCount; 00241 NTSTATUS Status; 00242 UNICODE_STRING KeyName; 00243 00244 /* get enumeration context */ 00245 DeviceObject = (PDEVICE_OBJECT)EnumContext; 00246 00247 /* get device count */ 00248 DeviceCount = GetSysAudioDeviceCount(DeviceObject); 00249 00250 if (DeviceIndex >= DeviceCount) 00251 { 00252 /* no more devices */ 00253 return MM_STATUS_NO_MORE_DEVICES; 00254 } 00255 00256 /* get device name */ 00257 Status = GetSysAudioDevicePnpName(DeviceObject, DeviceIndex, DeviceName); 00258 00259 if (!NT_SUCCESS(Status)) 00260 { 00261 /* failed to retrieve device name */ 00262 return MM_STATUS_UNSUCCESSFUL; 00263 } 00264 00265 /* intialize key name */ 00266 RtlInitUnicodeString(&KeyName, *DeviceName); 00267 00268 /* open device interface key */ 00269 Status = IoOpenDeviceInterfaceRegistryKey(&KeyName, GENERIC_READ | GENERIC_WRITE, OutKey); 00270 #if 0 00271 if (!NT_SUCCESS(Status)) 00272 { 00273 /* failed to open key */ 00274 DPRINT("IoOpenDeviceInterfaceRegistryKey failed with %lx\n", Status); 00275 FreeItem(*DeviceName); 00276 return MM_STATUS_UNSUCCESSFUL; 00277 } 00278 #endif 00279 00280 /* open device handle */ 00281 Status = OpenDevice(*DeviceName, OutHandle, NULL); 00282 if (!NT_SUCCESS(Status)) 00283 { 00284 /* failed to open device */ 00285 return MM_STATUS_UNSUCCESSFUL; 00286 } 00287 00288 return MM_STATUS_SUCCESS; 00289 } 00290 00291 PVOID 00292 AllocEventData( 00293 IN ULONG ExtraSize) 00294 { 00295 PKSEVENTDATA Data = (PKSEVENTDATA)AllocateItem(NonPagedPool, sizeof(KSEVENTDATA) + ExtraSize); 00296 if (!Data) 00297 return NULL; 00298 00299 Data->EventObject.Event = AllocateItem(NonPagedPool, sizeof(KEVENT)); 00300 if (!Data->EventHandle.Event) 00301 { 00302 FreeItem(Data); 00303 return NULL; 00304 } 00305 00306 KeInitializeEvent(Data->EventObject.Event, NotificationEvent, FALSE); 00307 00308 Data->NotificationType = KSEVENTF_EVENT_HANDLE; 00309 return Data; 00310 } 00311 00312 VOID 00313 FreeEventData(IN PVOID EventData) 00314 { 00315 PKSEVENTDATA Data = (PKSEVENTDATA)EventData; 00316 00317 FreeItem(Data->EventHandle.Event); 00318 FreeItem(Data); 00319 } 00320 00321 VOID 00322 CALLBACK 00323 EventCallback( 00324 IN PVOID MixerEventContext, 00325 IN HANDLE hMixer, 00326 IN ULONG NotificationType, 00327 IN ULONG Value) 00328 { 00329 PWDMAUD_CLIENT ClientInfo; 00330 PEVENT_ENTRY Entry; 00331 ULONG Index; 00332 00333 /* get client context */ 00334 ClientInfo = (PWDMAUD_CLIENT)MixerEventContext; 00335 00336 /* now search for the mixer which originated the request */ 00337 for(Index = 0; Index < ClientInfo->NumPins; Index++) 00338 { 00339 if (ClientInfo->hPins[Index].Handle == hMixer && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE) 00340 { 00341 if (ClientInfo->hPins[Index].NotifyEvent) 00342 { 00343 /* allocate event entry */ 00344 Entry = AllocateItem(NonPagedPool, sizeof(EVENT_ENTRY)); 00345 if (!Entry) 00346 { 00347 /* no memory */ 00348 break; 00349 } 00350 00351 /* setup event entry */ 00352 Entry->NotificationType = NotificationType; 00353 Entry->Value = Value; 00354 Entry->hMixer = hMixer; 00355 00356 /* insert entry */ 00357 InsertTailList(&ClientInfo->MixerEventList, &Entry->Entry); 00358 00359 /* now notify the client */ 00360 KeSetEvent(ClientInfo->hPins[Index].NotifyEvent, 0, FALSE); 00361 } 00362 /* done */ 00363 break; 00364 } 00365 } 00366 } 00367 00368 00369 NTSTATUS 00370 WdmAudMixerInitialize( 00371 IN PDEVICE_OBJECT DeviceObject) 00372 { 00373 MIXER_STATUS Status; 00374 00375 /* initialize the mixer library */ 00376 Status = MMixerInitialize(&MixerContext, Enum, (PVOID)DeviceObject); 00377 00378 if (Status != MM_STATUS_SUCCESS) 00379 { 00380 /* failed to initialize mmixer library */ 00381 DPRINT("MMixerInitialize failed with %lx\n", Status); 00382 } 00383 00384 return Status; 00385 } 00386 00387 NTSTATUS 00388 WdmAudMixerCapabilities( 00389 IN PDEVICE_OBJECT DeviceObject, 00390 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00391 IN PWDMAUD_CLIENT ClientInfo, 00392 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension) 00393 { 00394 if (MMixerGetCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.MixCaps) == MM_STATUS_SUCCESS) 00395 return STATUS_SUCCESS; 00396 00397 return STATUS_INVALID_PARAMETER; 00398 } 00399 00400 NTSTATUS 00401 WdmAudControlOpenMixer( 00402 IN PDEVICE_OBJECT DeviceObject, 00403 IN PIRP Irp, 00404 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00405 IN PWDMAUD_CLIENT ClientInfo) 00406 { 00407 HANDLE hMixer; 00408 PWDMAUD_HANDLE Handles; 00409 //PWDMAUD_DEVICE_EXTENSION DeviceExtension; 00410 NTSTATUS Status; 00411 PKEVENT EventObject = NULL; 00412 00413 DPRINT("WdmAudControlOpenMixer\n"); 00414 00415 //DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 00416 00417 if (DeviceInfo->u.hNotifyEvent) 00418 { 00419 Status = ObReferenceObjectByHandle(DeviceInfo->u.hNotifyEvent, EVENT_MODIFY_STATE, ExEventObjectType, UserMode, (LPVOID*)&EventObject, NULL); 00420 00421 if (!NT_SUCCESS(Status)) 00422 { 00423 DPRINT1("Invalid notify event passed %p from client %p\n", DeviceInfo->u.hNotifyEvent, ClientInfo); 00424 DbgBreakPoint(); 00425 return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); 00426 } 00427 } 00428 00429 if (MMixerOpen(&MixerContext, DeviceInfo->DeviceIndex, ClientInfo, EventCallback, &hMixer) != MM_STATUS_SUCCESS) 00430 { 00431 ObDereferenceObject(EventObject); 00432 DPRINT1("Failed to open mixer\n"); 00433 return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); 00434 } 00435 00436 00437 Handles = AllocateItem(NonPagedPool, sizeof(WDMAUD_HANDLE) * (ClientInfo->NumPins+1)); 00438 00439 if (Handles) 00440 { 00441 if (ClientInfo->NumPins) 00442 { 00443 RtlMoveMemory(Handles, ClientInfo->hPins, sizeof(WDMAUD_HANDLE) * ClientInfo->NumPins); 00444 FreeItem(ClientInfo->hPins); 00445 } 00446 00447 ClientInfo->hPins = Handles; 00448 ClientInfo->hPins[ClientInfo->NumPins].Handle = hMixer; 00449 ClientInfo->hPins[ClientInfo->NumPins].Type = MIXER_DEVICE_TYPE; 00450 ClientInfo->hPins[ClientInfo->NumPins].NotifyEvent = EventObject; 00451 ClientInfo->NumPins++; 00452 } 00453 else 00454 { 00455 ObDereferenceObject(EventObject); 00456 return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); 00457 } 00458 00459 DeviceInfo->hDevice = hMixer; 00460 00461 return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); 00462 } 00463 00464 NTSTATUS 00465 NTAPI 00466 WdmAudGetControlDetails( 00467 IN PDEVICE_OBJECT DeviceObject, 00468 IN PIRP Irp, 00469 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00470 IN PWDMAUD_CLIENT ClientInfo) 00471 { 00472 MIXER_STATUS Status; 00473 00474 /* clear hmixer type flag */ 00475 DeviceInfo->Flags &= ~MIXER_OBJECTF_HMIXER; 00476 00477 /* query mmixer library */ 00478 Status = MMixerGetControlDetails(&MixerContext, DeviceInfo->hDevice, DeviceInfo->DeviceIndex, DeviceInfo->Flags, &DeviceInfo->u.MixDetails); 00479 00480 if (Status == MM_STATUS_SUCCESS) 00481 return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); 00482 else 00483 return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); 00484 } 00485 00486 NTSTATUS 00487 NTAPI 00488 WdmAudGetLineInfo( 00489 IN PDEVICE_OBJECT DeviceObject, 00490 IN PIRP Irp, 00491 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00492 IN PWDMAUD_CLIENT ClientInfo) 00493 { 00494 MIXER_STATUS Status; 00495 00496 /* clear hmixer type flag */ 00497 DeviceInfo->Flags &= ~MIXER_OBJECTF_HMIXER; 00498 00499 /* query mixer library */ 00500 Status = MMixerGetLineInfo(&MixerContext, DeviceInfo->hDevice, DeviceInfo->DeviceIndex, DeviceInfo->Flags, &DeviceInfo->u.MixLine); 00501 00502 if (Status == MM_STATUS_SUCCESS) 00503 return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); 00504 else 00505 return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); 00506 } 00507 00508 NTSTATUS 00509 NTAPI 00510 WdmAudGetLineControls( 00511 IN PDEVICE_OBJECT DeviceObject, 00512 IN PIRP Irp, 00513 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00514 IN PWDMAUD_CLIENT ClientInfo) 00515 { 00516 MIXER_STATUS Status; 00517 00518 /* clear hmixer type flag */ 00519 DeviceInfo->Flags &= ~MIXER_OBJECTF_HMIXER; 00520 00521 /* query mixer library */ 00522 Status = MMixerGetLineControls(&MixerContext, DeviceInfo->hDevice, DeviceInfo->DeviceIndex, DeviceInfo->Flags, &DeviceInfo->u.MixControls); 00523 00524 if (Status == MM_STATUS_SUCCESS) 00525 return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); 00526 else 00527 return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); 00528 00529 00530 } 00531 00532 NTSTATUS 00533 NTAPI 00534 WdmAudSetControlDetails( 00535 IN PDEVICE_OBJECT DeviceObject, 00536 IN PIRP Irp, 00537 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00538 IN PWDMAUD_CLIENT ClientInfo) 00539 { 00540 MIXER_STATUS Status; 00541 00542 /* clear hmixer type flag */ 00543 DeviceInfo->Flags &= ~MIXER_OBJECTF_HMIXER; 00544 00545 /* query mixer library */ 00546 Status = MMixerSetControlDetails(&MixerContext, DeviceInfo->hDevice, DeviceInfo->DeviceIndex, DeviceInfo->Flags, &DeviceInfo->u.MixDetails); 00547 00548 if (Status == MM_STATUS_SUCCESS) 00549 return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); 00550 else 00551 return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); 00552 } 00553 00554 NTSTATUS 00555 NTAPI 00556 WdmAudGetMixerEvent( 00557 IN PDEVICE_OBJECT DeviceObject, 00558 IN PIRP Irp, 00559 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00560 IN PWDMAUD_CLIENT ClientInfo) 00561 { 00562 PLIST_ENTRY Entry; 00563 PEVENT_ENTRY EventEntry; 00564 00565 /* enumerate event list and check if there is a new event */ 00566 Entry = ClientInfo->MixerEventList.Flink; 00567 00568 while(Entry != &ClientInfo->MixerEventList) 00569 { 00570 /* grab event entry */ 00571 EventEntry = (PEVENT_ENTRY)CONTAINING_RECORD(Entry, EVENT_ENTRY, Entry); 00572 00573 if (EventEntry->hMixer == DeviceInfo->hDevice) 00574 { 00575 /* found an entry */ 00576 DeviceInfo->u.MixerEvent.hMixer = EventEntry->hMixer; 00577 DeviceInfo->u.MixerEvent.NotificationType = EventEntry->NotificationType; 00578 DeviceInfo->u.MixerEvent.Value = EventEntry->Value; 00579 00580 /* remove entry from list */ 00581 RemoveEntryList(&EventEntry->Entry); 00582 00583 /* free event entry */ 00584 FreeItem(EventEntry); 00585 00586 /* done */ 00587 return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); 00588 } 00589 00590 /* move to next */ 00591 Entry = Entry->Flink; 00592 } 00593 00594 /* no event entry available */ 00595 return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, sizeof(WDMAUD_DEVICE_INFO)); 00596 } 00597 00598 ULONG 00599 WdmAudGetMixerDeviceCount() 00600 { 00601 return MMixerGetCount(&MixerContext); 00602 } 00603 00604 ULONG 00605 WdmAudGetWaveInDeviceCount() 00606 { 00607 return MMixerGetWaveInCount(&MixerContext); 00608 } 00609 00610 ULONG 00611 WdmAudGetWaveOutDeviceCount() 00612 { 00613 return MMixerGetWaveOutCount(&MixerContext); 00614 } 00615 00616 ULONG 00617 WdmAudGetMidiInDeviceCount() 00618 { 00619 return MMixerGetMidiInCount(&MixerContext); 00620 } 00621 00622 ULONG 00623 WdmAudGetMidiOutDeviceCount() 00624 { 00625 return MMixerGetWaveOutCount(&MixerContext); 00626 } 00627 00628 NTSTATUS 00629 WdmAudGetPnpNameByIndexAndType( 00630 IN ULONG DeviceIndex, 00631 IN SOUND_DEVICE_TYPE DeviceType, 00632 OUT LPWSTR *DevicePath) 00633 { 00634 if (DeviceType == WAVE_IN_DEVICE_TYPE || DeviceType == WAVE_OUT_DEVICE_TYPE) 00635 { 00636 if (MMixerGetWaveDevicePath(&MixerContext, DeviceType == WAVE_IN_DEVICE_TYPE, DeviceIndex, DevicePath) == MM_STATUS_SUCCESS) 00637 return STATUS_SUCCESS; 00638 else 00639 return STATUS_UNSUCCESSFUL; 00640 } 00641 else if (DeviceType == MIDI_IN_DEVICE_TYPE || DeviceType == MIDI_OUT_DEVICE_TYPE) 00642 { 00643 if (MMixerGetMidiDevicePath(&MixerContext, DeviceType == MIDI_IN_DEVICE_TYPE, DeviceIndex, DevicePath) == MM_STATUS_SUCCESS) 00644 return STATUS_SUCCESS; 00645 else 00646 return STATUS_UNSUCCESSFUL; 00647 } 00648 else if (DeviceType == MIXER_DEVICE_TYPE) 00649 { 00650 UNIMPLEMENTED; 00651 } 00652 00653 return STATUS_UNSUCCESSFUL; 00654 } 00655 00656 NTSTATUS 00657 WdmAudWaveCapabilities( 00658 IN PDEVICE_OBJECT DeviceObject, 00659 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00660 IN PWDMAUD_CLIENT ClientInfo, 00661 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension) 00662 { 00663 MIXER_STATUS Status = MM_STATUS_UNSUCCESSFUL; 00664 00665 if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE) 00666 { 00667 /* get capabilities */ 00668 Status = MMixerWaveInCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.WaveInCaps); 00669 } 00670 else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE) 00671 { 00672 /* get capabilities */ 00673 Status = MMixerWaveOutCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.WaveOutCaps); 00674 } 00675 00676 if (Status == MM_STATUS_SUCCESS) 00677 return STATUS_SUCCESS; 00678 else 00679 return Status; 00680 } 00681 00682 NTSTATUS 00683 WdmAudMidiCapabilities( 00684 IN PDEVICE_OBJECT DeviceObject, 00685 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00686 IN PWDMAUD_CLIENT ClientInfo, 00687 IN PWDMAUD_DEVICE_EXTENSION DeviceExtension) 00688 { 00689 MIXER_STATUS Status = MM_STATUS_UNSUCCESSFUL; 00690 00691 if (DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE) 00692 { 00693 /* get capabilities */ 00694 Status = MMixerMidiInCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.MidiInCaps); 00695 } 00696 else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE) 00697 { 00698 /* get capabilities */ 00699 Status = MMixerMidiOutCapabilities(&MixerContext, DeviceInfo->DeviceIndex, &DeviceInfo->u.MidiOutCaps); 00700 } 00701 00702 if (Status == MM_STATUS_SUCCESS) 00703 return STATUS_SUCCESS; 00704 else 00705 return STATUS_UNSUCCESSFUL; 00706 } 00707 00708 00709 MIXER_STATUS 00710 CreatePinCallback( 00711 IN PVOID Ctx, 00712 IN ULONG VirtualDeviceId, 00713 IN ULONG PinId, 00714 IN HANDLE hFilter, 00715 IN PKSPIN_CONNECT PinConnect, 00716 IN ACCESS_MASK DesiredAccess, 00717 OUT PHANDLE PinHandle) 00718 { 00719 ULONG BytesReturned; 00720 SYSAUDIO_INSTANCE_INFO InstanceInfo; 00721 NTSTATUS Status; 00722 ULONG FreeIndex; 00723 PPIN_CREATE_CONTEXT Context = (PPIN_CREATE_CONTEXT)Ctx; 00724 00725 /* setup property request */ 00726 InstanceInfo.Property.Set = KSPROPSETID_Sysaudio; 00727 InstanceInfo.Property.Id = KSPROPERTY_SYSAUDIO_INSTANCE_INFO; 00728 InstanceInfo.Property.Flags = KSPROPERTY_TYPE_SET; 00729 InstanceInfo.Flags = 0; 00730 InstanceInfo.DeviceNumber = VirtualDeviceId; 00731 00732 /* attach to virtual device */ 00733 Status = KsSynchronousIoControlDevice(Context->DeviceExtension->FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&InstanceInfo, sizeof(SYSAUDIO_INSTANCE_INFO), NULL, 0, &BytesReturned); 00734 00735 if (!NT_SUCCESS(Status)) 00736 return MM_STATUS_UNSUCCESSFUL; 00737 00738 /* close existing pin */ 00739 FreeIndex = ClosePin(Context->ClientInfo, VirtualDeviceId, PinId, Context->DeviceType); 00740 00741 /* now create the pin */ 00742 Status = KsCreatePin(Context->DeviceExtension->hSysAudio, PinConnect, DesiredAccess, PinHandle); 00743 00744 /* check for success */ 00745 if (!NT_SUCCESS(Status)) 00746 return MM_STATUS_UNSUCCESSFUL; 00747 00748 /* store the handle */ 00749 Status = InsertPinHandle(Context->ClientInfo, VirtualDeviceId, PinId, Context->DeviceType, *PinHandle, FreeIndex); 00750 if (!NT_SUCCESS(Status)) 00751 { 00752 /* failed to insert handle */ 00753 ZwClose(*PinHandle); 00754 return MM_STATUS_UNSUCCESSFUL; 00755 } 00756 00757 return MM_STATUS_SUCCESS; 00758 } 00759 00760 NTSTATUS 00761 WdmAudControlOpenWave( 00762 IN PDEVICE_OBJECT DeviceObject, 00763 IN PIRP Irp, 00764 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00765 IN PWDMAUD_CLIENT ClientInfo) 00766 { 00767 MIXER_STATUS Status; 00768 PIN_CREATE_CONTEXT Context; 00769 00770 Context.ClientInfo = ClientInfo; 00771 Context.DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 00772 Context.DeviceType = DeviceInfo->DeviceType; 00773 00774 Status = MMixerOpenWave(&MixerContext, DeviceInfo->DeviceIndex, DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE, &DeviceInfo->u.WaveFormatEx, CreatePinCallback, &Context, &DeviceInfo->hDevice); 00775 00776 if (Status == MM_STATUS_SUCCESS) 00777 return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); 00778 else 00779 return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO)); 00780 } 00781 00782 NTSTATUS 00783 WdmAudControlOpenMidi( 00784 IN PDEVICE_OBJECT DeviceObject, 00785 IN PIRP Irp, 00786 IN PWDMAUD_DEVICE_INFO DeviceInfo, 00787 IN PWDMAUD_CLIENT ClientInfo) 00788 { 00789 MIXER_STATUS Status; 00790 PIN_CREATE_CONTEXT Context; 00791 00792 Context.ClientInfo = ClientInfo; 00793 Context.DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 00794 Context.DeviceType = DeviceInfo->DeviceType; 00795 00796 Status = MMixerOpenMidi(&MixerContext, DeviceInfo->DeviceIndex, DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE, CreatePinCallback, &Context, &DeviceInfo->hDevice); 00797 00798 if (Status == MM_STATUS_SUCCESS) 00799 return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO)); 00800 else 00801 return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO)); 00802 } 00803 Generated on Sun May 27 2012 04:26:52 for ReactOS by
1.7.6.1
|