- Use KsProbeStreamIrp in wdmaud to probe user buffers
- Remove a few hacks which were required to pass down irps to portcls
[PORTCLS]
- Check if there is an automation table
[SYSAUDIO]
- Release file object of pin to prevent reference leak
--
- Audio stack now reacts faster as it now longer copies audio buffers in kernel mode and instead locks down the user buffers. In addition it uses less memory to do the same work.


svn path=/trunk/; revision=43321
This commit is contained in:
Johannes Anderwald 2009-10-07 10:41:34 +00:00
parent c959b785e7
commit 5cb9dffd80
9 changed files with 126 additions and 307 deletions

View file

@ -113,6 +113,10 @@ CIrpQueue::AddMapping(
if (!Buffer) if (!Buffer)
{ {
if (!Irp->MdlAddress)
{
// ioctl from KsStudio
// Wdmaud already probes buffers, therefore no need to probe it again
// probe the stream irp // probe the stream irp
Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0); Status = KsProbeStreamIrp(Irp, KSSTREAM_WRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK | KSPROBE_ALLOWFORMATCHANGE | KSPROBE_SYSTEMADDRESS, 0);
@ -122,16 +126,19 @@ CIrpQueue::AddMapping(
DPRINT1("KsProbeStreamIrp failed with %x\n", Status); DPRINT1("KsProbeStreamIrp failed with %x\n", Status);
return Status; return Status;
} }
}
// get the stream header // get the stream header
Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer; Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
PC_ASSERT(Header); PC_ASSERT(Header);
PC_ASSERT(Irp->MdlAddress); PC_ASSERT(Irp->MdlAddress);
DPRINT("Size %u DataUsed %u FrameExtent %u SizeHeader %u\n", Header->Size, Header->DataUsed, Header->FrameExtent, sizeof(KSSTREAM_HEADER));
if (Irp->RequestorMode != KernelMode) if (Irp->RequestorMode != KernelMode)
{ {
// use allocated mdl // use allocated mdl
Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority); Header->Data = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
PC_ASSERT(Header->Data);
} }
} }
else else
@ -227,7 +234,12 @@ CIrpQueue::GetMapping(
PC_ASSERT(StreamHeader); PC_ASSERT(StreamHeader);
// store buffersize // store buffersize
if (StreamHeader->DataUsed)
*BufferSize = StreamHeader->DataUsed - Offset; *BufferSize = StreamHeader->DataUsed - Offset;
else
*BufferSize = StreamHeader->FrameExtent - Offset;
PC_ASSERT(*BufferSize);
// store buffer // store buffer
*Buffer = &((PUCHAR)StreamHeader->Data)[Offset]; *Buffer = &((PUCHAR)StreamHeader->Data)[Offset];
@ -243,8 +255,8 @@ NTAPI
CIrpQueue::UpdateMapping( CIrpQueue::UpdateMapping(
IN ULONG BytesWritten) IN ULONG BytesWritten)
{ {
//PIO_STACK_LOCATION IoStack;
PKSSTREAM_HEADER StreamHeader; PKSSTREAM_HEADER StreamHeader;
ULONG Size;
if (!m_Irp) if (!m_Irp)
{ {
@ -252,16 +264,8 @@ CIrpQueue::UpdateMapping(
return; return;
} }
#if 0
// get current irp stack location
IoStack = IoGetCurrentIrpStackLocation(m_Irp);
// get stream header // get stream header
StreamHeader = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
#else
// HACK get stream header
StreamHeader = (PKSSTREAM_HEADER)m_Irp->Tail.Overlay.DriverContext[2]; StreamHeader = (PKSSTREAM_HEADER)m_Irp->Tail.Overlay.DriverContext[2];
#endif
// sanity check // sanity check
// ASSERT(StreamHeader); // ASSERT(StreamHeader);
@ -272,7 +276,14 @@ CIrpQueue::UpdateMapping(
// decrement available data counter // decrement available data counter
m_NumDataAvailable -= BytesWritten; m_NumDataAvailable -= BytesWritten;
if (m_CurrentOffset >= StreamHeader->DataUsed) if (StreamHeader->DataUsed)
Size = StreamHeader->DataUsed;
else
Size = StreamHeader->FrameExtent;
PC_ASSERT(Size);
if (m_CurrentOffset >= Size)
{ {
// irp has been processed completly // irp has been processed completly
m_Irp->IoStatus.Status = STATUS_SUCCESS; m_Irp->IoStatus.Status = STATUS_SUCCESS;
@ -280,14 +291,14 @@ CIrpQueue::UpdateMapping(
// frame extend contains the original request size, DataUsed contains the real buffer size // frame extend contains the original request size, DataUsed contains the real buffer size
//is different when kmixer performs channel conversion, upsampling etc //is different when kmixer performs channel conversion, upsampling etc
m_Irp->IoStatus.Information = StreamHeader->FrameExtent; m_Irp->IoStatus.Information = Size;
if (m_Irp->RequestorMode == KernelMode) PC_ASSERT_IRQL(DISPATCH_LEVEL);
{ MmUnlockPages(m_Irp->MdlAddress);
// HACK - WDMAUD should pass PKSSTREAM_HEADERs IoFreeMdl(m_Irp->MdlAddress);
ExFreePool(StreamHeader->Data); m_Irp->MdlAddress = NULL;
ExFreePool(StreamHeader); ExFreePool(m_Irp->AssociatedIrp.SystemBuffer);
} m_Irp->AssociatedIrp.SystemBuffer = NULL;
// complete the request // complete the request
IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT); IoCompleteRequest(m_Irp, IO_SOUND_INCREMENT);
@ -439,9 +450,6 @@ CIrpQueue::ReleaseMappingWithTag(
Irp->IoStatus.Information = StreamHeader->FrameExtent; Irp->IoStatus.Information = StreamHeader->FrameExtent;
// free stream data, no tag as wdmaud.drv does it atm
ExFreePool(StreamHeader->Data);
// free stream header, no tag as wdmaud.drv allocates it atm // free stream header, no tag as wdmaud.drv allocates it atm
ExFreePool(StreamHeader); ExFreePool(StreamHeader);

View file

@ -578,7 +578,7 @@ CPortPinWaveCyclic::HandleKsStream(
{ {
InterlockedIncrement((PLONG)&m_TotalPackets); InterlockedIncrement((PLONG)&m_TotalPackets);
DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u Pre %u Post %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData()); DPRINT("IPortPinWaveCyclic_HandleKsStream entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData());
m_IrpQueue->AddMapping(NULL, 0, Irp); m_IrpQueue->AddMapping(NULL, 0, Irp);
@ -730,6 +730,8 @@ CPortPinWaveCyclic::Close(
{ {
PCLOSESTREAM_CONTEXT Ctx; PCLOSESTREAM_CONTEXT Ctx;
DPRINT1("CPortPinWaveCyclic::Close entered\n");
if (m_Stream) if (m_Stream)
{ {
// allocate a close context // allocate a close context
@ -828,27 +830,7 @@ CPortPinWaveCyclic::FastRead(
OUT PIO_STATUS_BLOCK StatusBlock, OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject) IN PDEVICE_OBJECT DeviceObject)
{ {
NTSTATUS Status; return KsDispatchFastReadFailure(FileObject, FileOffset, Length, Wait, LockKey, Buffer, StatusBlock, DeviceObject);
PCONTEXT_WRITE Packet;
PIRP Irp;
// HACK to be removed
DPRINT("CPortPinWaveCyclic::FastRead entered\n");
Packet = (PCONTEXT_WRITE)Buffer;
Irp = Packet->Irp;
StatusBlock->Status = STATUS_PENDING;
Status = m_IrpQueue->AddMapping((PUCHAR)Buffer, Length, Irp);
if (!NT_SUCCESS(Status))
return FALSE;
StatusBlock->Status = STATUS_PENDING;
return TRUE;
} }
@ -864,27 +846,7 @@ CPortPinWaveCyclic::FastWrite(
OUT PIO_STATUS_BLOCK StatusBlock, OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject) IN PDEVICE_OBJECT DeviceObject)
{ {
NTSTATUS Status; return KsDispatchFastReadFailure(FileObject, FileOffset, Length, Wait, LockKey, Buffer, StatusBlock, DeviceObject);
PCONTEXT_WRITE Packet;
PIRP Irp;
// HACK to be removed
InterlockedIncrement((PLONG)&m_TotalPackets);
DPRINT("CPortPinWaveCyclic::FastWrite entered Total %u State %x MinData %u\n", m_TotalPackets, m_State, m_IrpQueue->NumData());
Packet = (PCONTEXT_WRITE)Buffer;
Irp = Packet->Irp;
Status = m_IrpQueue->AddMapping((PUCHAR)Buffer, Length, Irp);
if (!NT_SUCCESS(Status))
return FALSE;
StatusBlock->Status = STATUS_PENDING;
return TRUE;
} }

View file

@ -722,7 +722,6 @@ CPortPinWaveRT::FastDeviceIoControl(
OUT PIO_STATUS_BLOCK StatusBlock, OUT PIO_STATUS_BLOCK StatusBlock,
IN PDEVICE_OBJECT DeviceObject) IN PDEVICE_OBJECT DeviceObject)
{ {
UNIMPLEMENTED
return FALSE; return FALSE;
} }

View file

@ -353,12 +353,6 @@ typedef struct
} PCLASS_DEVICE_EXTENSION, *PPCLASS_DEVICE_EXTENSION; } PCLASS_DEVICE_EXTENSION, *PPCLASS_DEVICE_EXTENSION;
typedef struct
{
KSSTREAM_HEADER Header;
PIRP Irp;
}CONTEXT_WRITE, *PCONTEXT_WRITE;
typedef struct typedef struct
{ {
PVOID Pin; PVOID Pin;

View file

@ -90,6 +90,13 @@ PcHandlePropertyWithTable(
Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
if (!Node->AutomationTable)
{
// request is out of bounds
Irp->IoStatus.Information = 0;
return STATUS_INVALID_PARAMETER;
}
PC_ASSERT(Node->AutomationTable); PC_ASSERT(Node->AutomationTable);
PC_ASSERT(Node->AutomationTable->PropertyCount); PC_ASSERT(Node->AutomationTable->PropertyCount);
PC_ASSERT(Node->AutomationTable->PropertyItemSize); PC_ASSERT(Node->AutomationTable->PropertyItemSize);
@ -126,6 +133,13 @@ PcHandlePropertyWithTable(
Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize)); Node = (PPCNODE_DESCRIPTOR)((ULONG_PTR)SubDeviceDescriptor->DeviceDescriptor->Nodes + (Property->NodeId * SubDeviceDescriptor->DeviceDescriptor->NodeSize));
if (!Node->AutomationTable)
{
// request is out of bounds
Irp->IoStatus.Information = 0;
return STATUS_INVALID_PARAMETER;
}
PC_ASSERT(Node->AutomationTable); PC_ASSERT(Node->AutomationTable);
PC_ASSERT(Node->AutomationTable->PropertyCount); PC_ASSERT(Node->AutomationTable->PropertyCount);
PC_ASSERT(Node->AutomationTable->PropertyItemSize); PC_ASSERT(Node->AutomationTable->PropertyItemSize);

View file

@ -266,7 +266,6 @@ WdmAudDeviceControl(
return WdmAudSetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo); return WdmAudSetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
case IOCTL_GETCONTROLDETAILS: case IOCTL_GETCONTROLDETAILS:
return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo); return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
case IOCTL_GETPOS: case IOCTL_GETPOS:
case IOCTL_GETDEVID: case IOCTL_GETDEVID:
case IOCTL_GETVOLUME: case IOCTL_GETVOLUME:
@ -279,206 +278,93 @@ WdmAudDeviceControl(
return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0); return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0);
} }
NTSTATUS
NTAPI
WdmAudWriteCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP LowerIrp,
IN PVOID Context)
{
//PIRP Irp;
ASSERT(LowerIrp->PendingReturned == FALSE);
/* get original irp */
//Irp = (PIRP)Context;
/* save status */
//Irp->IoStatus.Status = LowerIrp->IoStatus.Status;
//Irp->IoStatus.Information = LowerIrp->IoStatus.Information;
/* complete request */
//IoCompleteRequest(Irp, IO_SOUND_INCREMENT);
/* return success to free irp */
return STATUS_SUCCESS;
}
NTSTATUS NTSTATUS
NTAPI NTAPI
WdmAudWrite( WdmAudReadWrite(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp) IN PIRP Irp)
{ {
PIO_STACK_LOCATION IoStack; NTSTATUS Status;
PWDMAUD_DEVICE_INFO DeviceInfo; PWDMAUD_DEVICE_INFO DeviceInfo;
PWDMAUD_CLIENT ClientInfo;
NTSTATUS Status = STATUS_SUCCESS;
PUCHAR Buffer;
PFILE_OBJECT FileObject; PFILE_OBJECT FileObject;
PIO_STACK_LOCATION IoStack;
ULONG Length;
PMDL Mdl; PMDL Mdl;
//PIRP LowerIrp;
PCONTEXT_WRITE Packet;
PVOID SystemBuffer;
//LARGE_INTEGER Offset;
IO_STATUS_BLOCK IoStatusBlock;
/* get current irp stack location */
IoStack = IoGetCurrentIrpStackLocation(Irp); IoStack = IoGetCurrentIrpStackLocation(Irp);
//DPRINT("WdmAudWrite entered\n"); /* store the input buffer in UserBuffer - as KsProbeStreamIrp operates on IRP_MJ_DEVICE_CONTROL */
Irp->UserBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
if (IoStack->Parameters.Write.Length < sizeof(WDMAUD_DEVICE_INFO)) /* sanity check */
ASSERT(Irp->UserBuffer);
/* get the length of the request length */
Length = IoStack->Parameters.Write.Length;
/* store outputbuffer length */
IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
/* store mdl address */
Mdl = Irp->MdlAddress;
/* remove mdladdress as KsProbeStreamIrp will interprete it as an already probed audio buffer */
Irp->MdlAddress = NULL;
/* check for success */
if (IoStack->MajorFunction == IRP_MJ_WRITE)
{ {
/* invalid parameter */ /* probe the write stream irp */
DPRINT1("Input buffer too small size %u expected %u\n", IoStack->Parameters.Write.Length, sizeof(WDMAUD_DEVICE_INFO)); Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0); }
else
{
/* probe the read stream irp */
Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMREAD | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
} }
DeviceInfo = (PWDMAUD_DEVICE_INFO)MmGetMdlVirtualAddress(Irp->MdlAddress); /* now free the mdl */
IoFreeMdl(Mdl);
if (!NT_SUCCESS(Status))
{
DPRINT1("KsProbeStreamIrp failed with Status %x\n", Status);
return SetIrpIoStatus(Irp, Status, 0);
}
/* get device info */
DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;
ASSERT(DeviceInfo);
/* now get sysaudio file object */
Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL); Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
if (!NT_SUCCESS(Status)) if (!NT_SUCCESS(Status))
{ {
DPRINT1("Invalid buffer handle %x\n", DeviceInfo->hDevice); DPRINT1("Invalid pin handle %x\n", DeviceInfo->hDevice);
return SetIrpIoStatus(Irp, Status, 0); return SetIrpIoStatus(Irp, Status, 0);
} }
/* skip current irp stack location */
//DPRINT("DeviceInfo %p %p %p\n", DeviceInfo, Irp->MdlAddress->StartVa, Irp->MdlAddress->MappedSystemVa); IoSkipCurrentIrpStackLocation(Irp);
if (DeviceInfo->DeviceType < MIN_SOUND_DEVICE_TYPE || DeviceInfo->DeviceType > MAX_SOUND_DEVICE_TYPE)
{
/* invalid parameter */
DPRINT1("Error: device type not set\n");
ObDereferenceObject(FileObject);
return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
}
if (!IoStack->FileObject)
{
/* file object parameter */
DPRINT1("Error: file object is not attached\n");
ObDereferenceObject(FileObject);
return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
}
ClientInfo = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext;
/* setup stream context */
Packet = (PCONTEXT_WRITE)ExAllocatePool(NonPagedPool, sizeof(CONTEXT_WRITE));
if (!Packet)
{
/* no memory */
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
}
Packet->Header.FrameExtent = DeviceInfo->Header.FrameExtent;
Packet->Header.DataUsed = DeviceInfo->Header.DataUsed;
Packet->Header.Size = sizeof(KSSTREAM_HEADER);
Packet->Header.PresentationTime.Numerator = 1;
Packet->Header.PresentationTime.Denominator = 1;
Packet->Irp = Irp;
Buffer = ExAllocatePool(NonPagedPool, DeviceInfo->Header.DataUsed);
if (!Buffer)
{
/* no memory */
ExFreePool(Packet);
ObDereferenceObject(FileObject);
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
}
Packet->Header.Data = Buffer;
Mdl = IoAllocateMdl(DeviceInfo->Header.Data, DeviceInfo->Header.DataUsed, FALSE, FALSE, FALSE);
if (!Mdl)
{
/* no memory */
ExFreePool(Packet);
ObDereferenceObject(FileObject);
ExFreePool(Buffer);
return SetIrpIoStatus(Irp, STATUS_NO_MEMORY, 0);
}
_SEH2_TRY
{
MmProbeAndLockPages(Mdl, UserMode, IoReadAccess);
}
_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
{
/* Exception, get the error code */
Status = _SEH2_GetExceptionCode();
}
_SEH2_END;
if (!NT_SUCCESS(Status))
{
DPRINT1("Invalid buffer supplied\n");
ExFreePool(Buffer);
ExFreePool(Packet);
IoFreeMdl(Mdl);
ObDereferenceObject(FileObject);
return SetIrpIoStatus(Irp, Status, 0);
}
SystemBuffer = MmGetSystemAddressForMdlSafe(Mdl, NormalPagePriority );
if (!SystemBuffer)
{
DPRINT1("Invalid buffer supplied\n");
ExFreePool(Buffer);
ExFreePool(Packet);
IoFreeMdl(Mdl);
ObDereferenceObject(FileObject);
return SetIrpIoStatus(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
}
RtlMoveMemory(Buffer, SystemBuffer, DeviceInfo->Header.DataUsed);
MmUnlockPages(Mdl);
IoFreeMdl(Mdl);
#if 1
KsStreamIo(FileObject, NULL, NULL, NULL, NULL, 0, &IoStatusBlock, Packet, sizeof(CONTEXT_WRITE), KSSTREAM_WRITE, UserMode);
/* dereference file object */
ObDereferenceObject(FileObject);
return IoStatusBlock.Status;
#else
Offset.QuadPart = 0L;
/* now build the irp */
LowerIrp = IoBuildAsynchronousFsdRequest (IRP_MJ_WRITE,
IoGetRelatedDeviceObject(FileObject),
Packet,
sizeof(KSSTREAM_HEADER),
&Offset,
NULL);
if (!LowerIrp)
{
/* failed to create an associated irp */
ExFreePool(Buffer);
ExFreePool(Packet);
ObDereferenceObject(FileObject);
return SetIrpIoStatus(Irp, STATUS_INSUFFICIENT_RESOURCES, 0);
}
/* get next stack location */ /* get next stack location */
IoStack = IoGetNextIrpStackLocation(LowerIrp); IoStack = IoGetNextIrpStackLocation(Irp);
/* attach file object */ /* attach file object */
IoStack->FileObject = FileObject; IoStack->FileObject = FileObject;
IoStack->Parameters.Write.Length = sizeof(KSSTREAM_HEADER);
/* set a completion routine */ IoStack->MajorFunction = IRP_MJ_WRITE;
IoSetCompletionRoutine(LowerIrp, WdmAudWriteCompletion, (PVOID)Irp, TRUE, TRUE, TRUE);
/* mark irp as pending */ /* mark irp as pending */
//IoMarkIrpPending(Irp); IoMarkIrpPending(Irp);
Irp->IoStatus.Information = DeviceInfo->BufferSize;
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
DPRINT1("Wrote %u\n", DeviceInfo->BufferSize);
/* call the driver */ /* call the driver */
Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), LowerIrp); Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
/* dereference file object */ /* dereference file object */
ObDereferenceObject(FileObject); ObDereferenceObject(FileObject);
return STATUS_SUCCESS; return Status;
#endif
} }

View file

@ -244,14 +244,14 @@ DriverEntry(
Driver->DriverUnload = WdmAudUnload; Driver->DriverUnload = WdmAudUnload;
Driver->MajorFunction[IRP_MJ_CREATE] = WdmAudCreate; Driver->MajorFunction[IRP_MJ_CREATE] = WdmAudCreate;
Driver->MajorFunction[IRP_MJ_CLOSE] = WdmAudClose; Driver->MajorFunction[IRP_MJ_CLOSE] = WdmAudClose;
Driver->MajorFunction[IRP_MJ_PNP] = WdmAudPnp; Driver->MajorFunction[IRP_MJ_PNP] = WdmAudPnp;
Driver->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp; Driver->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
Driver->MajorFunction[IRP_MJ_CLEANUP] = WdmAudCleanup; Driver->MajorFunction[IRP_MJ_CLEANUP] = WdmAudCleanup;
Driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WdmAudDeviceControl; Driver->MajorFunction[IRP_MJ_DEVICE_CONTROL] = WdmAudDeviceControl;
Driver->MajorFunction[IRP_MJ_WRITE] = WdmAudWrite; Driver->MajorFunction[IRP_MJ_WRITE] = WdmAudReadWrite;
Driver->MajorFunction[IRP_MJ_READ] = WdmAudReadWrite;
Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower; Driver->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
return WdmAudInstallDevice(Driver); return WdmAudInstallDevice(Driver);

View file

@ -118,12 +118,6 @@ typedef struct
}WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION; }WDMAUD_DEVICE_EXTENSION, *PWDMAUD_DEVICE_EXTENSION;
typedef struct
{
KSSTREAM_HEADER Header;
PIRP Irp;
}CONTEXT_WRITE, *PCONTEXT_WRITE;
NTSTATUS NTSTATUS
NTAPI NTAPI
OpenWavePin( OpenWavePin(
@ -155,6 +149,12 @@ WdmAudDeviceControl(
IN PDEVICE_OBJECT DeviceObject, IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp); IN PIRP Irp);
NTSTATUS
NTAPI
WdmAudReadWrite(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp);
NTSTATUS NTSTATUS
NTAPI NTAPI
WdmAudWrite( WdmAudWrite(

View file

@ -115,9 +115,16 @@ Pin_fnWrite(
IoStack->MajorFunction = IRP_MJ_DEVICE_CONTROL; IoStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM; //FIXME IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM; //FIXME
IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length; IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
ASSERT(Irp->AssociatedIrp.SystemBuffer);
/* now call the driver */ /* now call the driver */
return IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp); Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
/* dereference file object */
ObDereferenceObject(FileObject);
return Status;
} }
NTSTATUS NTSTATUS
@ -151,57 +158,6 @@ Pin_fnClose(
return STATUS_SUCCESS; return STATUS_SUCCESS;
} }
BOOLEAN
NTAPI
Pin_fnFastWrite(
PFILE_OBJECT FileObject,
PLARGE_INTEGER FileOffset,
ULONG Length,
BOOLEAN Wait,
ULONG LockKey,
PVOID Buffer,
PIO_STATUS_BLOCK IoStatus,
PDEVICE_OBJECT DeviceObject)
{
PDISPATCH_CONTEXT Context;
PFILE_OBJECT RealFileObject;
NTSTATUS Status;
DPRINT("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
Context = (PDISPATCH_CONTEXT)FileObject->FsContext;
if (Context->hMixerPin)
{
Status = ObReferenceObjectByHandle(Context->hMixerPin, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&RealFileObject, NULL);
if (NT_SUCCESS(Status))
{
Status = KsStreamIo(RealFileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, UserMode);
ObDereferenceObject(RealFileObject);
}
if (!NT_SUCCESS(Status))
{
DPRINT1("Mixing stream failed with %lx\n", Status);
DbgBreakPoint();
return FALSE;
}
}
Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&RealFileObject, NULL);
if (!NT_SUCCESS(Status))
return FALSE;
Status = KsStreamIo(RealFileObject, NULL, NULL, NULL, NULL, 0, IoStatus, Buffer, Length, KSSTREAM_WRITE, UserMode);
ObDereferenceObject(RealFileObject);
if (NT_SUCCESS(Status))
return TRUE;
else
return FALSE;
}
static KSDISPATCH_TABLE PinTable = static KSDISPATCH_TABLE PinTable =
{ {
Pin_fnDeviceIoControl, Pin_fnDeviceIoControl,
@ -213,7 +169,7 @@ static KSDISPATCH_TABLE PinTable =
KsDispatchInvalidDeviceRequest, KsDispatchInvalidDeviceRequest,
KsDispatchFastIoDeviceControlFailure, KsDispatchFastIoDeviceControlFailure,
KsDispatchFastReadFailure, KsDispatchFastReadFailure,
Pin_fnFastWrite, KsDispatchFastWriteFailure,
}; };
NTSTATUS NTSTATUS