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

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

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