Author: janderwald Date: Wed Mar 25 22:14:04 2009 New Revision: 40238
URL: http://svn.reactos.org/svn/reactos?rev=40238&view=rev Log: - Export KsNullDriverUnload - Stop the audio stream at PASSIVE_LEVEL - Refactor sysaudio code to make it less complex and remove code which is not used - Add a few comments
Modified: trunk/reactos/drivers/ksfilter/ks/ks.spec trunk/reactos/drivers/ksfilter/ks/misc.c trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c trunk/reactos/drivers/wdm/audio/sysaudio/control.c trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c trunk/reactos/drivers/wdm/audio/sysaudio/main.c trunk/reactos/drivers/wdm/audio/sysaudio/pin.c trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h
Modified: trunk/reactos/drivers/ksfilter/ks/ks.spec URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/ks.spec... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/ks.spec [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/ks.spec [iso-8859-1] Wed Mar 25 22:14:04 2009 @@ -98,7 +98,7 @@ @ stdcall KsFreeObjectCreateItem(ptr ptr) @ stdcall KsFreeObjectCreateItemsByContext(ptr ptr) @ stdcall KsLoadResource(ptr long ptr long ptr ptr) -; KsNullDriverUnload@4 +@ stdcall KsNullDriverUnload(ptr) @ stdcall KsPinDataIntersectionEx(ptr ptr ptr long ptr long ptr ptr) @ stdcall KsQueryDevicePnpObject(ptr) @ stdcall KsRecalculateStackDepth(ptr long)
Modified: trunk/reactos/drivers/ksfilter/ks/misc.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/ksfilter/ks/misc.c?... ============================================================================== --- trunk/reactos/drivers/ksfilter/ks/misc.c [iso-8859-1] (original) +++ trunk/reactos/drivers/ksfilter/ks/misc.c [iso-8859-1] Wed Mar 25 22:14:04 2009 @@ -165,7 +165,7 @@ /* @unimplemented */ -VOID +KSDDKAPI VOID NTAPI KsNullDriverUnload( IN PDRIVER_OBJECT DriverObject) {
Modified: trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/backpln/p... ============================================================================== --- trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/backpln/portcls/pin_wavecyclic.c [iso-8859-1] Wed Mar 25 22:14:04 2009 @@ -16,6 +16,7 @@ KSSTATE State; PKSDATAFORMAT Format; KSPIN_CONNECT * ConnectDetails; + KDPC Dpc;
PVOID CommonBuffer; ULONG CommonBufferSize; @@ -183,6 +184,42 @@ UpdateCommonBuffer(This, Position); }
+VOID +NTAPI +StopStreamWorkerRoutine( + IN PDEVICE_OBJECT DeviceObject, + IN PVOID Context) +{ + IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)Context; + + DPRINT1("Stopping %u Irql %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue), KeGetCurrentIrql()); + + This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); + This->State = KSSTATE_STOP; +} + +VOID +NTAPI +StopStreamRoutine( + IN PKDPC Dpc, + IN PVOID DeferredContext, + IN PVOID SystemArgument1, + IN PVOID SystemArgument2) +{ + IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)DeferredContext; + PIO_WORKITEM WorkItem; + + if (This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue)) + return; + + WorkItem = IoAllocateWorkItem(GetDeviceObject(This->Port)); + if (!WorkItem) + return; + + IoQueueWorkItem(WorkItem, StopStreamWorkerRoutine, DelayedWorkQueue, (PVOID)This); +} + +
static VOID @@ -194,32 +231,18 @@ NTSTATUS Status; PUCHAR Buffer; ULONG BufferSize; - IPortPinWaveCyclicImpl * This = (IPortPinWaveCyclicImpl*)CONTAINING_RECORD(iface, IPortPinWaveCyclicImpl, lpVtblServiceSink);
Status = This->IrpQueue->lpVtbl->GetMapping(This->IrpQueue, &Buffer, &BufferSize); if (!NT_SUCCESS(Status)) { - if (!This->IrpQueue->lpVtbl->CancelBuffers(This->IrpQueue)) - { - /* there is an active dpc pending - * wait untill this dpc is done, in order to complete the remaining irps - */ - return; - } - DPRINT1("Stopping %u\n", This->IrpQueue->lpVtbl->NumMappings(This->IrpQueue)); - - This->Stream->lpVtbl->SetState(This->Stream, KSSTATE_STOP); - This->State = KSSTATE_STOP; + KeInsertQueueDpc(&This->Dpc, NULL, NULL); return; }
- if (KeGetCurrentIrql() == DISPATCH_LEVEL) - return; -
Status = This->Stream->lpVtbl->GetPosition(This->Stream, &Position); - DPRINT("Position %u BufferSize %u ActiveIrpOffset %u\n", Position, This->CommonBufferSize, BufferSize); + DPRINT1("Position %u Buffer %p BufferSize %u ActiveIrpOffset %u\n", Position, Buffer, This->CommonBufferSize, BufferSize);
if (Position < This->CommonBufferOffset) { @@ -836,6 +859,7 @@ This->KsPinDescriptor = KsPinDescriptor; This->ConnectDetails = ConnectDetails; This->Miniport = GetWaveCyclicMiniport(Port); + KeInitializeDpc(&This->Dpc, StopStreamRoutine, (PVOID)This);
DeviceObject = GetDeviceObject(Port);
@@ -904,7 +928,7 @@ This->CommonBuffer = This->DmaChannel->lpVtbl->SystemAddress(This->DmaChannel); This->Capture = Capture;
- //Status = This->Stream->lpVtbl->SetNotificationFreq(This->Stream, 10, &This->FrameSize); + Status = This->Stream->lpVtbl->SetNotificationFreq(This->Stream, 10, &This->FrameSize);
return STATUS_SUCCESS; }
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/control.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/control.c [iso-8859-1] Wed Mar 25 22:14:04 2009 @@ -67,8 +67,6 @@ IN ULONG DeviceNumber, PSYSAUDIODEVEXT DeviceExtension) { - PSYSAUDIO_CLIENT_HANDELS Index; - ULONG Count; PSYSAUDIO_CLIENT ClientInfo; PKSAUDIO_DEVICE_ENTRY Entry; PKSOBJECT_CREATE_ITEM CreateItem; @@ -83,66 +81,26 @@ return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); }
+ /* get client context */ + ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context; + + /* sanity check */ + ASSERT(ClientInfo); + + /* check for valid device index */ + if (DeviceNumber >= ClientInfo->NumDevices) + { + /* invalid device index */ + return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); + } + /* get device context */ Entry = GetListEntry(&DeviceExtension->KsAudioDeviceList, DeviceNumber); ASSERT(Entry != NULL);
- /* get client context */ - ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context; - /* does the client already use a device */ - if (!ClientInfo->NumDevices) - { - /* first device to be openend */ - ClientInfo->Devs = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS)); - if (!ClientInfo->Devs) - { - /* no memory */ - return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); - } - - ClientInfo->NumDevices = 1; - ClientInfo->Devs[0].DeviceId = DeviceNumber; - ClientInfo->Devs[0].ClientHandles = NULL; - ClientInfo->Devs[0].ClientHandlesCount = 0; - /* increase usage count */ - Entry->NumberOfClients++; - return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); - } - - /* check if device has already been openend */ - for(Count = 0; Count < ClientInfo->NumDevices; Count++) - { - if (ClientInfo->Devs[Count].DeviceId == DeviceNumber) - { - /* device has already been opened */ - return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); - } - } - /* new device to be openend */ - Index = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS) * (ClientInfo->NumDevices + 1)); - if (!Index) - { - /* no memory */ - return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0); - } - - if (ClientInfo->NumDevices) - { - /* copy device count array */ - RtlMoveMemory(Index, ClientInfo->Devs, ClientInfo->NumDevices * sizeof(SYSAUDIO_CLIENT_HANDELS)); - } - - Index[ClientInfo->NumDevices].DeviceId = DeviceNumber; - Index[ClientInfo->NumDevices].ClientHandlesCount = 0; - Index[ClientInfo->NumDevices].ClientHandles = NULL; - /* increase usage count */ Entry->NumberOfClients++;
- ExFreePool(ClientInfo->Devs); - - ClientInfo->Devs = Index; - ClientInfo->NumDevices++; return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); }
@@ -362,7 +320,7 @@
if (WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].MaxPinInstanceCount == 1) { - /* store the pin handle there is the pin can only be instantiated once*/ + /* store the pin handle there if the pin can only be instantiated once*/ WorkerContext->Entry->Pins[WorkerContext->PinConnect->PinId].PinHandle = RealPinHandle; }
@@ -955,8 +913,7 @@ PSYSAUDIODEVEXT DeviceExtension; PKSAUDIO_DEVICE_ENTRY Entry; PSYSAUDIO_INSTANCE_INFO InstanceInfo; - PSYSAUDIO_CLIENT ClientInfo; - ULONG Count, BytesReturned; + ULONG BytesReturned; PKSOBJECT_CREATE_ITEM CreateItem; UNICODE_STRING GuidString;
@@ -1034,7 +991,7 @@ if (IoStack->Parameters.DeviceIoControl.OutputBufferLength < sizeof(ULONG)) { /* too small buffer */ - return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(KSCOMPONENTID)); + return SetIrpIoStatus(Irp, STATUS_BUFFER_TOO_SMALL, sizeof(ULONG)); }
if (Property->Flags & KSPROPERTY_TYPE_SET) @@ -1042,23 +999,6 @@ Index = (PULONG)Irp->UserBuffer; return SysAudioOpenVirtualDevice(Irp, *Index, DeviceExtension); } - else if (Property->Flags & KSPROPERTY_TYPE_GET) - { - Index = (PULONG)Irp->UserBuffer; - /* get client context */ - ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context; - ASSERT(ClientInfo); - /* does the client already use a device */ - if (!ClientInfo->NumDevices) - { - /* no device open */ - return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); - } - /* store last opened device number */ - *Index = ClientInfo->Devs[ClientInfo->NumDevices-1].DeviceId; - /* found no device with that device index open */ - return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(ULONG)); - } } else if (Property->Id == KSPROPERTY_SYSAUDIO_INSTANCE_INFO) { @@ -1074,28 +1014,6 @@ if (Property->Flags & KSPROPERTY_TYPE_SET) { return SysAudioOpenVirtualDevice(Irp, InstanceInfo->DeviceNumber, DeviceExtension); - } - else if (Property->Flags & KSPROPERTY_TYPE_GET) - { - /* get client context */ - ClientInfo = (PSYSAUDIO_CLIENT)CreateItem->Context; - ASSERT(ClientInfo); - /* does the client already use a device */ - if (!ClientInfo->NumDevices) - { - /* no device open */ - return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); - } - for(Count = 0; Count < ClientInfo->NumDevices; Count++) - { - if (ClientInfo->Devs[Count].DeviceId == InstanceInfo->DeviceNumber) - { - /* specified device is open */ - return SetIrpIoStatus(Irp, STATUS_SUCCESS, 0); - } - } - /* found no device with that device index open */ - return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0); } } else if (Property->Id == (ULONG)-1)
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/deviface.c [iso-8859-1] Wed Mar 25 22:14:04 2009 @@ -178,7 +178,7 @@ DeviceEntry = ExAllocatePool(NonPagedPool, sizeof(KSAUDIO_DEVICE_ENTRY)); if (!DeviceEntry) { - DPRINT1("No Mem\n"); + return STATUS_INSUFFICIENT_RESOURCES; }
@@ -188,14 +188,12 @@ DeviceEntry->DeviceName.Buffer = ExAllocatePool(NonPagedPool, DeviceEntry->DeviceName.MaximumLength); if (!DeviceEntry->DeviceName.Buffer) { - DPRINT1("No Mem\n"); ExFreePool(DeviceEntry); return STATUS_INSUFFICIENT_RESOURCES; }
if (!NT_SUCCESS(RtlAppendUnicodeToString(&DeviceEntry->DeviceName, L"\??\"))) { - DPRINT1("No Mem\n"); ExFreePool(DeviceEntry->DeviceName.Buffer); ExFreePool(DeviceEntry); return STATUS_INSUFFICIENT_RESOURCES; @@ -203,14 +201,11 @@
if (!NT_SUCCESS(RtlAppendUnicodeStringToString(&DeviceEntry->DeviceName, Event->SymbolicLinkName))) { - DPRINT1("No Mem\n"); ExFreePool(DeviceEntry->DeviceName.Buffer); ExFreePool(DeviceEntry); return STATUS_INSUFFICIENT_RESOURCES; }
- DPRINT1("Sym %wZ\n", &DeviceEntry->DeviceName); - Status = OpenDevice(&DeviceEntry->DeviceName, &DeviceEntry->Handle, &DeviceEntry->FileObject); if (!NT_SUCCESS(Status)) { @@ -231,24 +226,12 @@
return Status; } - else if (IsEqualGUIDAligned(&Event->Event, - &GUID_DEVICE_INTERFACE_REMOVAL)) + else { DPRINT1("Remove interface to audio device!\n"); - ///FIXME - /// + UNIMPLEMENTED return STATUS_SUCCESS; } - else - { - UNICODE_STRING EventName, InterfaceGuid; - - RtlStringFromGUID(&Event->Event, &EventName); - RtlStringFromGUID(&Event->InterfaceClassGuid, &InterfaceGuid); - DPRINT1("Unknown event: Event %wZ GUID %wZ\n", &EventName, &InterfaceGuid); - return STATUS_SUCCESS; - } - }
NTSTATUS
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/dispatcher.c [iso-8859-1] Wed Mar 25 22:14:04 2009 @@ -24,17 +24,13 @@ { PIO_STACK_LOCATION IoStack;
- //DPRINT("Dispatch_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); - IoStack = IoGetCurrentIrpStackLocation(Irp); if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_PROPERTY) { return SysAudioHandleProperty(DeviceObject, Irp); }
- DPRINT1("Dispatch_fnDeviceIoControl Unhandeled %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode); - DbgBreakPoint(); - + /* unsupported request */ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -47,8 +43,7 @@ PDEVICE_OBJECT DeviceObject, PIRP Irp) { - DPRINT1("Dispatch_fnRead called DeviceObject %p Irp %p\n", DeviceObject); - + /* unsupported request */ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -61,8 +56,7 @@ PDEVICE_OBJECT DeviceObject, PIRP Irp) { - DPRINT1("Dispatch_fnWrite called DeviceObject %p Irp %p\n", DeviceObject); - + /* unsupported request */ Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -75,9 +69,6 @@ PDEVICE_OBJECT DeviceObject, PIRP Irp) { - DPRINT1("Dispatch_fnFlush called DeviceObject %p Irp %p\n", DeviceObject); - //FIXME - // cleanup resources Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); @@ -127,8 +118,9 @@ } else { - /* this is pin which can only be instantiated once - * so we just need to release the reference count on that pin */ + /* this is a pin which can only be instantiated once + * so we just need to release the reference count on that pin + */ Entry->Pins[Client->Devs[Index].ClientHandles[SubIndex].PinId].References--;
DispatchContext = (PDISPATCH_CONTEXT)Client->Devs[Index].ClientHandles[SubIndex].DispatchContext; @@ -274,6 +266,8 @@ PKSOBJECT_CREATE_ITEM CreateItem; PIO_STACK_LOCATION IoStatus; LPWSTR Buffer; + PSYSAUDIODEVEXT DeviceExtension; + ULONG Index;
static LPWSTR KS_NAME_PIN = L"{146F1A80-4791-11D0-A5D6-28DB04C10000}";
@@ -300,16 +294,55 @@ /* allocate create item */ CreateItem = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM)); if (!CreateItem) + { + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; + }
Client = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT)); if (!Client) { ExFreePool(CreateItem); + + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); return STATUS_INSUFFICIENT_RESOURCES; } - /* initialize client struct */ - RtlZeroMemory(Client, sizeof(SYSAUDIO_CLIENT)); + + /* get device extension */ + DeviceExtension = (PSYSAUDIODEVEXT) DeviceObject->DeviceExtension; + + Client->NumDevices = DeviceExtension->NumberOfKsAudioDevices; + /* has sysaudio found any devices */ + if (Client->NumDevices) + { + Client->Devs = ExAllocatePool(NonPagedPool, sizeof(SYSAUDIO_CLIENT_HANDELS) * Client->NumDevices); + if (!Client->Devs) + { + ExFreePool(CreateItem); + ExFreePool(Client); + Irp->IoStatus.Information = 0; + Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; + IoCompleteRequest(Irp, IO_NO_INCREMENT); + return STATUS_INSUFFICIENT_RESOURCES; + } + } + else + { + /* no devices yet available */ + Client->Devs = NULL; + } + + /* Initialize devs array */ + for(Index = 0; Index < Client->NumDevices; Index++) + { + Client->Devs[Index].DeviceId = Index; + Client->Devs[Index].ClientHandles = NULL; + Client->Devs[Index].ClientHandlesCount = 0; + }
/* zero create struct */ RtlZeroMemory(CreateItem, sizeof(KSOBJECT_CREATE_ITEM));
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/main.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/main.c [iso-8859-1] Wed Mar 25 22:14:04 2009 @@ -46,27 +46,33 @@ UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\DosDevices\sysaudio"); SYSAUDIODEVEXT *DeviceExtension;
+ /* Get current irp stack */ IrpStack = IoGetCurrentIrpStackLocation(Irp);
- DPRINT("SysAudio_Pnp called for func %x\n", IrpStack->MinorFunction); - + /* Fetch the device extension */ DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension; + ASSERT(DeviceExtension);
if (IrpStack->MinorFunction == IRP_MN_REMOVE_DEVICE) { + /* Unregister the echo cancel hook */ if (DeviceExtension->EchoCancelNotificationEntry) IoUnregisterPlugPlayNotification(DeviceExtension->EchoCancelNotificationEntry);
+ /* Unregister the ks audio hook */ if (DeviceExtension->KsAudioNotificationEntry) IoUnregisterPlugPlayNotification(DeviceExtension->KsAudioNotificationEntry);
+ /* Destroy our symbolic link */ IoDeleteSymbolicLink(&SymlinkName); } else if (IrpStack->MinorFunction == IRP_MN_QUERY_PNP_DEVICE_STATE) { + /* Sysaudio can not be disabled */ Irp->IoStatus.Information |= PNP_DEVICE_NOT_DISABLEABLE; }
+ /* Perform default pnp actions */ return KsDefaultDispatchPnp(DeviceObject, Irp); }
@@ -79,13 +85,12 @@ UNICODE_STRING DeviceName = RTL_CONSTANT_STRING(L"\Device\sysaudio"); UNICODE_STRING SymlinkName = RTL_CONSTANT_STRING(L"\DosDevices\sysaudio"); PDEVICE_OBJECT DeviceObject; - //PDEVICE_OBJECT NextDeviceObject; SYSAUDIODEVEXT *DeviceExtension;
DPRINT1("SysAudio_InstallDevice called\n");
- /* create the device */ + /* Create the device */ Status = IoCreateDevice(DriverObject, sizeof(SYSAUDIODEVEXT), &DeviceName, @@ -94,19 +99,19 @@ FALSE, &DeviceObject);
- /* check for success */ + /* Check for success */ if (!NT_SUCCESS(Status)) { DPRINT("Failed to create \Device\sysaudio !\n"); return Status; }
- /* register device interfaces */ + /* Register device interfaces */ Status = SysAudioRegisterDeviceInterfaces(DeviceObject); if (!NT_SUCCESS(Status)) { - /* failed to register - * create a hack interface + /* Failed to register + * Create a hack interface */ Status = IoCreateSymbolicLink(&SymlinkName, &DeviceName); if (!NT_SUCCESS(Status)) @@ -116,15 +121,18 @@ return Status; } } - + /* Acquire device extension */ DeviceExtension = (SYSAUDIODEVEXT*)DeviceObject->DeviceExtension; - /* initialize device extension */ + /* Initialize device extension */ RtlZeroMemory(DeviceExtension, sizeof(SYSAUDIODEVEXT));
+ /* Initialize the mutex */ KeInitializeMutex(&DeviceExtension->Mutex, 0); - //DeviceExtension->PhysicalDeviceObject = PhysicalDeviceObject; + + /* Initialize the ks audio device list */ InitializeListHead(&DeviceExtension->KsAudioDeviceList);
+ /* Allocate kernel streaming device header */ Status = SysAudioAllocateDeviceHeader(DeviceExtension); if (!NT_SUCCESS(Status)) { @@ -132,6 +140,7 @@ goto cleanup; }
+ /* Register device notification hooks */ Status = SysAudioRegisterNotifications(DriverObject, DeviceObject); if (!NT_SUCCESS(Status)) @@ -140,6 +149,7 @@ goto cleanup; }
+ /* Load kmixer */ Status = SysAudioOpenKMixer(DeviceExtension); if (!NT_SUCCESS(Status)) { @@ -152,7 +162,7 @@ /* clear initializing flag */ DeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
- DPRINT("Device SysAudio_InstallDevice result %x\n", Status); + /* Done */ return STATUS_SUCCESS;
cleanup: @@ -168,22 +178,30 @@ return Status; }
-NTSTATUS NTAPI +NTSTATUS +NTAPI DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { DPRINT1("System audio graph builder (sysaudio) started\n");
+ /* Let ks handle these */ KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE); KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE); KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE); KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
+ /* Let ks handle these */ DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp; + + /* Use provided ks unload function */ + DriverObject->DriverUnload = KsNullDriverUnload; + + /* Sysaudio needs to do work on pnp, so handle it */ DriverObject->MajorFunction[IRP_MJ_PNP] = SysAudio_Pnp; - DriverObject->DriverUnload = SysAudio_Unload; - + + /* Call our initialization function */ return SysAudio_InstallDevice(DriverObject); }
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/pin.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/pin.c [iso-8859-1] Wed Mar 25 22:14:04 2009 @@ -27,13 +27,19 @@ ULONG BytesReturned; PIO_STACK_LOCATION IoStack;
- DPRINT1("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); - + DPRINT("Pin_fnDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject); + + /* Get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp);
+ /* The dispatch context is stored in the FsContext2 member */ Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2; + + /* Sanity check */ ASSERT(Context); - + ASSERT(Context->FileObject != NULL); + + /* Re-dispatch the request to the real target pin */ Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode, IoStack->Parameters.DeviceIoControl.Type3InputBuffer, IoStack->Parameters.DeviceIoControl.InputBufferLength, @@ -41,46 +47,18 @@ IoStack->Parameters.DeviceIoControl.OutputBufferLength, &BytesReturned);
- DPRINT1("Status %x\n", Status); - + /* Save status and information */ Irp->IoStatus.Information = BytesReturned; Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* Complete the irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* Done */ return Status; }
NTSTATUS NTAPI Pin_fnRead( - PDEVICE_OBJECT DeviceObject, - PIRP Irp) -{ - DPRINT1("Pin_fnRead called DeviceObject %p Irp %p\n", DeviceObject); - - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; -} - -NTSTATUS -NTAPI -PinWriteCompletionRoutine( - IN PDEVICE_OBJECT DeviceObject, - IN PIRP Irp, - IN PVOID Context) -{ - PIRP CIrp = (PIRP)Context; - - CIrp->IoStatus.Status = STATUS_SUCCESS; - CIrp->IoStatus.Information = 0; - IoCompleteRequest(CIrp, IO_NO_INCREMENT); - return STATUS_SUCCESS; -} - -NTSTATUS -NTAPI -Pin_fnWrite( PDEVICE_OBJECT DeviceObject, PIRP Irp) { @@ -89,23 +67,83 @@ ULONG BytesReturned; NTSTATUS Status;
- DPRINT1("Pin_fnWrite called DeviceObject %p Irp %p\n", DeviceObject); - + /* Get current stack location */ IoStack = IoGetCurrentIrpStackLocation(Irp);
+ /* The dispatch context is stored in the FsContext2 member */ Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2; + + /* Sanity check */ ASSERT(Context); - - Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, + ASSERT(Context->FileObject != NULL); + + /* Re-dispatch the request to the real target pin */ + Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_READ_STREAM, MmGetMdlVirtualAddress(Irp->MdlAddress), - IoStack->Parameters.Write.Length, + IoStack->Parameters.Read.Length, NULL, 0, &BytesReturned);
- Irp->IoStatus.Information = BytesReturned; + if (Context->hMixerPin && Context->MixerFileObject) + { + // FIXME + // call kmixer to convert stream + UNIMPLEMENTED + } + + /* Save status and information */ Irp->IoStatus.Status = Status; - IoCompleteRequest(Irp, IO_NO_INCREMENT); + Irp->IoStatus.Information = 0; + /* Complete the irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* Done */ + return Status; +} + +NTSTATUS +NTAPI +Pin_fnWrite( + PDEVICE_OBJECT DeviceObject, + PIRP Irp) +{ + PDISPATCH_CONTEXT Context; + PIO_STACK_LOCATION IoStack; + ULONG BytesReturned; + NTSTATUS Status; + + /* Get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* The dispatch context is stored in the FsContext2 member */ + Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2; + + /* Sanity check */ + ASSERT(Context); + ASSERT(Context->FileObject != NULL); + + if (Context->hMixerPin && Context->MixerFileObject) + { + // FIXME + // call kmixer to convert stream + UNIMPLEMENTED + } + + + /* Re-dispatch the request to the real target pin */ + Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM, + MmGetMdlVirtualAddress(Irp->MdlAddress), + IoStack->Parameters.Read.Length, + NULL, + 0, + &BytesReturned); + + /* Save status and information */ + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + /* Complete the irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* Done */ return Status; }
@@ -115,12 +153,59 @@ PDEVICE_OBJECT DeviceObject, PIRP Irp) { - DPRINT1("Pin_fnFlush called DeviceObject %p Irp %p\n", DeviceObject); - - Irp->IoStatus.Status = STATUS_UNSUCCESSFUL; - Irp->IoStatus.Information = 0; - IoCompleteRequest(Irp, IO_NO_INCREMENT); - return STATUS_UNSUCCESSFUL; + PDISPATCH_CONTEXT Context; + PIO_STACK_LOCATION IoStack; + PDEVICE_OBJECT PinDeviceObject; + PIRP PinIrp; + IO_STATUS_BLOCK IoStatus; + KEVENT Event; + NTSTATUS Status = STATUS_UNSUCCESSFUL; + + /* Get current stack location */ + IoStack = IoGetCurrentIrpStackLocation(Irp); + + /* The dispatch context is stored in the FsContext2 member */ + Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2; + + /* Sanity check */ + ASSERT(Context); + ASSERT(Context->FileObject != NULL); + + /* Get Pin's device object */ + PinDeviceObject = IoGetRelatedDeviceObject(Context->FileObject); + + /* Initialize notification event */ + KeInitializeEvent(&Event, NotificationEvent, FALSE); + + /* build target irp */ + PinIrp = IoBuildSynchronousFsdRequest(IRP_MJ_FLUSH_BUFFERS, PinDeviceObject, NULL, 0, NULL, &Event, &IoStatus); + if (PinIrp) + { + + /* Get the next stack location */ + IoStack = IoGetNextIrpStackLocation(PinIrp); + /* The file object must be present in the irp as it contains the KSOBJECT_HEADER */ + IoStack->FileObject = Context->FileObject; + + /* call the driver */ + Status = IoCallDriver(PinDeviceObject, PinIrp); + /* Has request already completed ? */ + if (Status == STATUS_PENDING) + { + /* Wait untill the request has completed */ + KeWaitForSingleObject(&Event, UserRequest, KernelMode, FALSE, NULL); + /* Update status */ + Status = IoStatus.Status; + } + } + + /* store status */ + Irp->IoStatus.Status = Status; + Irp->IoStatus.Information = 0; + /* Complete the irp */ + IoCompleteRequest(Irp, IO_NO_INCREMENT); + /* Done */ + return Status; }
NTSTATUS
Modified: trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/wdm/audio/sysaudio/... ============================================================================== --- trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] (original) +++ trunk/reactos/drivers/wdm/audio/sysaudio/sysaudio.h [iso-8859-1] Wed Mar 25 22:14:04 2009 @@ -3,84 +3,93 @@
typedef struct { - BOOL bHandle; - ULONG PinId; - HANDLE hPin; - HANDLE hMixer; - PVOID DispatchContext; + BOOL bHandle; // indicates if an audio pin can be instantated more than once + ULONG PinId; // specifies the pin id + HANDLE hPin; // handle to audio irp pin + HANDLE hMixer; // handle to mixer pin + PVOID DispatchContext; // pointer to dispatch context }SYSAUDIO_PIN_HANDLE, *PSYSAUDIO_PIN_HANDLE;
typedef struct { - ULONG DeviceId; - ULONG ClientHandlesCount; - PSYSAUDIO_PIN_HANDLE ClientHandles; - + ULONG DeviceId; //specifies the device id + ULONG ClientHandlesCount; // number of client handles + PSYSAUDIO_PIN_HANDLE ClientHandles; // array of client handles }SYSAUDIO_CLIENT_HANDELS, *PSYSAUDIO_CLIENT_HANDELS;
typedef struct { - ULONG NumDevices; - PSYSAUDIO_CLIENT_HANDELS Devs; + ULONG NumDevices; // number of devices in Devs array + PSYSAUDIO_CLIENT_HANDELS Devs; // array of client handles
}SYSAUDIO_CLIENT, *PSYSAUDIO_CLIENT;
typedef struct { - ULONG MaxPinInstanceCount; - HANDLE PinHandle; - ULONG References; - KSPIN_DATAFLOW DataFlow; - KSPIN_COMMUNICATION Communication; + ULONG MaxPinInstanceCount; // maximum times a audio irp pin can be instantiated + HANDLE PinHandle; // handle to audio irp pin + ULONG References; // number of clients having a reference to this audio irp pin + KSPIN_DATAFLOW DataFlow; // specifies data flow + KSPIN_COMMUNICATION Communication; // pin type }PIN_INFO;
typedef struct { - LIST_ENTRY Entry; - HANDLE Handle; - PFILE_OBJECT FileObject; - UNICODE_STRING DeviceName; - ULONG NumberOfClients; + LIST_ENTRY Entry; // device entry for KsAudioDeviceList + HANDLE Handle; // handle to audio device + PFILE_OBJECT FileObject; // file object for audio device + UNICODE_STRING DeviceName; // symbolic link of audio device + ULONG NumberOfClients; // number of clients referenced audio device
- ULONG NumberOfPins; - PIN_INFO * Pins; + ULONG NumberOfPins; // number of pins of audio device + PIN_INFO * Pins; // array of PIN_INFO
- ULONG NumWaveOutPin; - ULONG NumWaveInPin; + ULONG NumWaveOutPin; // number of wave out pins + ULONG NumWaveInPin; // number of wave in pins
}KSAUDIO_DEVICE_ENTRY, *PKSAUDIO_DEVICE_ENTRY;
+typedef struct +{ + KSDEVICE_HEADER KsDeviceHeader; // ks streaming header - must always be first item in device extension + PDEVICE_OBJECT PhysicalDeviceObject; // pdo + PDEVICE_OBJECT NextDeviceObject; // lower device object + ULONG NumberOfKsAudioDevices; // number of audio devices + + LIST_ENTRY KsAudioDeviceList; // audio device list + PVOID KsAudioNotificationEntry; // ks audio notification hook + PVOID EchoCancelNotificationEntry; // ks echo cancel notification hook + KMUTEX Mutex; // audio device list mutex + + PFILE_OBJECT KMixerFileObject; // mixer file object + HANDLE KMixerHandle; // mixer file handle + +}SYSAUDIODEVEXT, *PSYSAUDIODEVEXT; + +// struct DISPATCH_CONTEXT +// +// This structure is used to dispatch read / write / device io requests +// It is stored in the file object FsContext2 member +// Note: FsContext member is reserved for ks object header
typedef struct { - KSDEVICE_HEADER KsDeviceHeader; - PDEVICE_OBJECT PhysicalDeviceObject; - PDEVICE_OBJECT NextDeviceObject; - ULONG NumberOfKsAudioDevices; + HANDLE Handle; // audio irp pin handle + PFILE_OBJECT FileObject; // audio irp pin file object + ULONG PinId; // pin id of device + PKSAUDIO_DEVICE_ENTRY AudioEntry; // pointer to audio device entry
- LIST_ENTRY KsAudioDeviceList; - PVOID KsAudioNotificationEntry; - PVOID EchoCancelNotificationEntry; - KMUTEX Mutex; - - PFILE_OBJECT KMixerFileObject; - HANDLE KMixerHandle; - -}SYSAUDIODEVEXT, *PSYSAUDIODEVEXT; - -typedef struct -{ - HANDLE Handle; - PFILE_OBJECT FileObject; - ULONG PinId; - PKSAUDIO_DEVICE_ENTRY AudioEntry; - - HANDLE hMixerPin; - PFILE_OBJECT MixerFileObject; + HANDLE hMixerPin; // handle to mixer pin + PFILE_OBJECT MixerFileObject; // mixer file object }DISPATCH_CONTEXT, *PDISPATCH_CONTEXT;
+// struct PIN_WORKER_CONTEXT +// +// This structure holds all information required +// to create audio irp pin, mixer pin and virtual sysaudio pin +// typedef struct { PIRP Irp;