- Remove obsolete code
[reactos.git] / reactos / drivers / wdm / audio / sysaudio / pin.c
index 977733f..e6d88ea 100644 (file)
@@ -6,14 +6,6 @@
  * PROGRAMMER:      Johannes Anderwald
  */
 
-#include <ntifs.h>
-#include <ntddk.h>
-#include <portcls.h>
-#include <ks.h>
-#include <ksmedia.h>
-#include <math.h>
-#define YDEBUG
-#include <debug.h>
 #include "sysaudio.h"
 
 NTSTATUS
@@ -25,55 +17,51 @@ Pin_fnDeviceIoControl(
     PDISPATCH_CONTEXT Context;
     NTSTATUS Status;
     ULONG BytesReturned;
+    PFILE_OBJECT FileObject;
     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);
 
-    Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
+    /* The dispatch context is stored in the FsContext member */
+    Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
+
+    /* Sanity check */
     ASSERT(Context);
 
-    Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode,
+    /* acquire real pin file object */
+    Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = Status;
+        /* Complete the irp */
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
+    }
+
+    /* Re-dispatch the request to the real target pin */
+    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IoStack->Parameters.DeviceIoControl.IoControlCode,
                                           IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
                                           IoStack->Parameters.DeviceIoControl.InputBufferLength,
                                           Irp->UserBuffer,
                                           IoStack->Parameters.DeviceIoControl.OutputBufferLength,
                                           &BytesReturned);
+    /* release file object */
+    ObDereferenceObject(FileObject);
 
-    DPRINT1("Status %x\n", Status);
-
+    /* Save status and information */
     Irp->IoStatus.Information = BytesReturned;
     Irp->IoStatus.Status = Status;
+    /* 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);
-
-    return STATUS_SUCCESS;
-}
-
-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
@@ -83,38 +71,53 @@ Pin_fnWrite(
 {
     PDISPATCH_CONTEXT Context;
     PIO_STACK_LOCATION IoStack;
-    ULONG BytesReturned;
+    PFILE_OBJECT FileObject;
     NTSTATUS Status;
+    ULONG Length;
 
-    DPRINT1("Pin_fnWrite called DeviceObject %p Irp %p\n", DeviceObject);
-
+    /* Get current stack location */
     IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext2;
-    ASSERT(Context);
+    Length = IoStack->Parameters.Write.Length;
 
-    Status = KsSynchronousIoControlDevice(Context->FileObject, KernelMode, IOCTL_KS_WRITE_STREAM,
-                                          IoStack->Parameters.DeviceIoControl.Type3InputBuffer,
-                                          IoStack->Parameters.DeviceIoControl.InputBufferLength,
-                                          Irp->UserBuffer,
-                                          IoStack->Parameters.DeviceIoControl.OutputBufferLength,
-                                          &BytesReturned);
+    /* The dispatch context is stored in the FsContext member */
+    Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
 
-    Irp->IoStatus.Information = BytesReturned;
-    Irp->IoStatus.Status = Status;
-    IoCompleteRequest(Irp, IO_NO_INCREMENT);
-    return Status;
-}
-
-NTSTATUS
-NTAPI
-Pin_fnFlush(
-    PDEVICE_OBJECT DeviceObject,
-    PIRP Irp)
-{
-    DPRINT1("Pin_fnFlush called DeviceObject %p Irp %p\n", DeviceObject);
+    /* Sanity check */
+    ASSERT(Context);
 
-    return STATUS_SUCCESS;
+    if (Context->hMixerPin)
+    {
+        // FIXME
+        // call kmixer to convert stream
+        UNIMPLEMENTED
+    }
+
+    /* acquire real pin file object */
+    Status = ObReferenceObjectByHandle(Context->Handle, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("failed\n");
+        Irp->IoStatus.Information = 0;
+        Irp->IoStatus.Status = Status;
+        /* Complete the irp */
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
+    }
+
+    /* skip current irp location */
+    IoSkipCurrentIrpStackLocation(Irp);
+
+    /* get next stack location */
+    IoStack = IoGetNextIrpStackLocation(Irp);
+    /* store file object of next device object */
+    IoStack->FileObject = FileObject;
+    IoStack->MajorFunction = IRP_MJ_DEVICE_CONTROL;
+    IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM; //FIXME
+    IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
+
+    /* now call the driver */
+    return IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
 }
 
 NTSTATUS
@@ -123,59 +126,34 @@ Pin_fnClose(
     PDEVICE_OBJECT DeviceObject,
     PIRP Irp)
 {
-    DPRINT1("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
-
-
-    return STATUS_SUCCESS;
-}
+    PDISPATCH_CONTEXT Context;
+    PIO_STACK_LOCATION IoStack;
 
-NTSTATUS
-NTAPI
-Pin_fnQuerySecurity(
-    PDEVICE_OBJECT DeviceObject,
-    PIRP Irp)
-{
-    DPRINT1("Pin_fnQuerySecurity called DeviceObject %p Irp %p\n", DeviceObject);
+    DPRINT("Pin_fnClose called DeviceObject %p Irp %p\n", DeviceObject);
 
+    /* Get current stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
 
-    return STATUS_SUCCESS;
-}
+    /* The dispatch context is stored in the FsContext member */
+    Context = (PDISPATCH_CONTEXT)IoStack->FileObject->FsContext;
 
-NTSTATUS
-NTAPI
-Pin_fnSetSecurity(
-    PDEVICE_OBJECT DeviceObject,
-    PIRP Irp)
-{
+    if (Context->Handle)
+    {
+        ZwClose(Context->Handle);
+    }
+    ZwClose(Context->hMixerPin);
 
-    DPRINT1("Pin_fnSetSecurity called DeviceObject %p Irp %p\n", DeviceObject);
+    ExFreePool(Context);
 
+    Irp->IoStatus.Status = STATUS_SUCCESS;
+    Irp->IoStatus.Information = 0;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return STATUS_SUCCESS;
 }
 
 BOOLEAN
 NTAPI
-Pin_fnFastDeviceIoControl(
-    PFILE_OBJECT FileObject,
-    BOOLEAN Wait,
-    PVOID InputBuffer,
-    ULONG InputBufferLength,
-    PVOID OutputBuffer,
-    ULONG OutputBufferLength,
-    ULONG IoControlCode,
-    PIO_STATUS_BLOCK IoStatus,
-    PDEVICE_OBJECT DeviceObject)
-{
-    DPRINT1("Pin_fnFastDeviceIoControl called DeviceObject %p Irp %p\n", DeviceObject);
-
-
-    return FALSE;
-}
-
-
-BOOLEAN
-NTAPI
-Pin_fnFastRead(
+Pin_fnFastWrite(
     PFILE_OBJECT FileObject,
     PLARGE_INTEGER FileOffset,
     ULONG Length,
@@ -185,51 +163,340 @@ Pin_fnFastRead(
     PIO_STATUS_BLOCK IoStatus,
     PDEVICE_OBJECT DeviceObject)
 {
-    DPRINT1("Pin_fnFastRead called DeviceObject %p Irp %p\n", DeviceObject);
+    PDISPATCH_CONTEXT Context;
+    PFILE_OBJECT RealFileObject;
+    NTSTATUS Status;
 
-    return FALSE;
+    DPRINT("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
 
-}
+    Context = (PDISPATCH_CONTEXT)FileObject->FsContext;
 
-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)
-{
-    DPRINT1("Pin_fnFastWrite called DeviceObject %p Irp %p\n", DeviceObject);
+    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);
+        }
 
-    return FALSE;
+        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 =
 {
     Pin_fnDeviceIoControl,
-    Pin_fnRead,
+    KsDispatchInvalidDeviceRequest,
     Pin_fnWrite,
-    Pin_fnFlush,
+    KsDispatchInvalidDeviceRequest,
     Pin_fnClose,
-    Pin_fnQuerySecurity,
-    Pin_fnSetSecurity,
-    Pin_fnFastDeviceIoControl,
-    Pin_fnFastRead,
+    KsDispatchInvalidDeviceRequest,
+    KsDispatchInvalidDeviceRequest,
+    KsDispatchFastIoDeviceControlFailure,
+    KsDispatchFastReadFailure,
     Pin_fnFastWrite,
 };
 
 NTSTATUS
-CreateDispatcher(
-    IN PIRP Irp)
+SetMixerInputOutputFormat(
+    IN PFILE_OBJECT FileObject,
+    IN PKSDATAFORMAT InputFormat,
+    IN PKSDATAFORMAT OutputFormat)
 {
+    KSP_PIN PinRequest;
+    ULONG BytesReturned;
     NTSTATUS Status;
-    KSOBJECT_HEADER ObjectHeader;
+
+    /* re-using pin */
+    PinRequest.Property.Set = KSPROPSETID_Connection;
+    PinRequest.Property.Flags = KSPROPERTY_TYPE_SET;
+    PinRequest.Property.Id = KSPROPERTY_CONNECTION_DATAFORMAT;
+
+    /* set the input format */
+    PinRequest.PinId = 0;
+    DPRINT("InputFormat %p Size %u WaveFormatSize %u DataFormat %u WaveEx %u\n", InputFormat, InputFormat->FormatSize, sizeof(KSDATAFORMAT_WAVEFORMATEX), sizeof(KSDATAFORMAT), sizeof(WAVEFORMATEX));
+    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY,
+                                          (PVOID)&PinRequest,
+                                           sizeof(KSP_PIN),
+                                          (PVOID)InputFormat,
+                                           InputFormat->FormatSize,
+                                          &BytesReturned);
+    if (!NT_SUCCESS(Status))
+        return Status;
+
+    /* set the the output format */
+    PinRequest.PinId = 1;
+    DPRINT("OutputFormat %p Size %u WaveFormatSize %u DataFormat %u WaveEx %u\n", OutputFormat, OutputFormat->FormatSize, sizeof(KSDATAFORMAT_WAVEFORMATEX), sizeof(KSDATAFORMAT), sizeof(WAVEFORMATEX));
+    Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY,
+                                          (PVOID)&PinRequest,
+                                           sizeof(KSP_PIN),
+                                          (PVOID)OutputFormat,
+                                           OutputFormat->FormatSize,
+                                          &BytesReturned);
+    return Status;
+}
+
+
+NTSTATUS
+CreateMixerPinAndSetFormat(
+    IN HANDLE KMixerHandle,
+    IN KSPIN_CONNECT *PinConnect,
+    IN PKSDATAFORMAT InputFormat,
+    IN PKSDATAFORMAT OutputFormat,
+    OUT PHANDLE MixerPinHandle)
+{
+    NTSTATUS Status;
+    HANDLE PinHandle;
+    PFILE_OBJECT FileObject;
+
+    Status = KsCreatePin(KMixerHandle, PinConnect, GENERIC_READ | GENERIC_WRITE, &PinHandle);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to create Mixer Pin with %x\n", Status);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    Status = ObReferenceObjectByHandle(PinHandle,
+                                       GENERIC_READ | GENERIC_WRITE, 
+                                       IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
+
+    if (!NT_SUCCESS(Status))
+    {
+        DPRINT1("Failed to get file object with %x\n", Status);
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    Status = SetMixerInputOutputFormat(FileObject, InputFormat, OutputFormat);
+    if (!NT_SUCCESS(Status))
+    {
+        ObDereferenceObject(FileObject);
+        ZwClose(PinHandle);
+    }
+
+    ObDereferenceObject(FileObject);
+
+    *MixerPinHandle = PinHandle;
+     return Status;
+}
+
+
+NTSTATUS
+NTAPI
+InstantiatePins(
+    IN PKSAUDIO_DEVICE_ENTRY DeviceEntry,
+    IN PKSPIN_CONNECT Connect,
+    IN PDISPATCH_CONTEXT DispatchContext,
+    IN PSYSAUDIODEVEXT DeviceExtension)
+{
+    NTSTATUS Status;
+    HANDLE RealPinHandle;
+    PKSDATAFORMAT_WAVEFORMATEX InputFormat;
+    PKSDATAFORMAT_WAVEFORMATEX OutputFormat = NULL;
+    PKSPIN_CONNECT MixerPinConnect = NULL;
+    KSPIN_CINSTANCES PinInstances;
+
+    DPRINT("InstantiatePins entered\n");
+
+    /* query instance count */
+    Status = GetPinInstanceCount(DeviceEntry, &PinInstances, Connect);
+    if (!NT_SUCCESS(Status))
+    {
+        /* failed to query instance count */
+        return Status;
+    }
+
+    /* can be the pin be instantiated */
+    if (PinInstances.PossibleCount == 0)
+    {
+        /* caller wanted to open an instance-less pin */
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* has the maximum instance count been exceeded */
+    if (PinInstances.CurrentCount == PinInstances.PossibleCount)
+    {
+        /* FIXME pin already exists
+         * and kmixer infrastructure is not implemented
+         */
+        return STATUS_UNSUCCESSFUL;
+    }
+
+    /* Fetch input format */
+    InputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(Connect + 1);
+
+    /* Let's try to create the audio irp pin */
+    Status = KsCreatePin(DeviceEntry->Handle, Connect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
+
+    if (!NT_SUCCESS(Status))
+    {
+        /* the audio irp pin didnt accept the input format
+         * let's compute a compatible format
+         */
+        MixerPinConnect = ExAllocatePool(NonPagedPool, sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX));
+        if (!MixerPinConnect)
+        {
+            /* not enough memory */
+            return STATUS_INSUFFICIENT_RESOURCES;
+        }
+
+        /* Zero pin connect */
+        RtlZeroMemory(MixerPinConnect, sizeof(KSPIN_CONNECT) + sizeof(KSDATAFORMAT_WAVEFORMATEX));
+
+        /* Copy initial connect details */
+        RtlMoveMemory(MixerPinConnect, Connect, sizeof(KSPIN_CONNECT));
+
+
+        OutputFormat = (PKSDATAFORMAT_WAVEFORMATEX)(MixerPinConnect + 1);
+
+        Status = ComputeCompatibleFormat(DeviceEntry, Connect->PinId, InputFormat, OutputFormat);
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("ComputeCompatibleFormat failed with %x\n", Status);
+            ExFreePool(MixerPinConnect);
+            return Status;
+        }
+
+        /* Retry with Mixer format */
+        Status = KsCreatePin(DeviceEntry->Handle, MixerPinConnect, GENERIC_READ | GENERIC_WRITE, &RealPinHandle);
+        if (!NT_SUCCESS(Status))
+        {
+           /* This should not fail */
+            DPRINT1("KsCreatePin failed with %x\n", Status);
+            DPRINT1(" InputFormat: SampleRate %u Bits %u Channels %u\n", InputFormat->WaveFormatEx.nSamplesPerSec, InputFormat->WaveFormatEx.wBitsPerSample, InputFormat->WaveFormatEx.nChannels);
+            DPRINT1("OutputFormat: SampleRate %u Bits %u Channels %u\n", OutputFormat->WaveFormatEx.nSamplesPerSec, OutputFormat->WaveFormatEx.wBitsPerSample, OutputFormat->WaveFormatEx.nChannels);
+
+            ExFreePool(MixerPinConnect);
+            return Status;
+        }
+    }
+
+    DeviceEntry->Pins[Connect->PinId].References = 0;
+
+    /* initialize dispatch context */
+    DispatchContext->Handle = RealPinHandle;
+    DispatchContext->PinId = Connect->PinId;
+    DispatchContext->AudioEntry = DeviceEntry;
+
+
+    /* Do we need to transform the audio stream */
+    if (OutputFormat != NULL)
+    {
+        /* Now create the mixer pin */
+        Status = CreateMixerPinAndSetFormat(DeviceExtension->KMixerHandle,
+                                            MixerPinConnect,
+                                            (PKSDATAFORMAT)InputFormat,
+                                            (PKSDATAFORMAT)OutputFormat,
+                                            &DispatchContext->hMixerPin);
+
+        /* check for success */
+        if (!NT_SUCCESS(Status))
+        {
+            DPRINT1("Failed to create Mixer Pin with %x\n", Status);
+            ExFreePool(MixerPinConnect);
+        }
+    }
+    /* done */
+    return Status;
+}
+
+NTSTATUS
+NTAPI
+DispatchCreateSysAudioPin(
+    IN PDEVICE_OBJECT DeviceObject,
+    IN PIRP Irp)
+{
+    NTSTATUS Status = STATUS_SUCCESS;
+    PIO_STACK_LOCATION IoStack;
+    PKSAUDIO_DEVICE_ENTRY DeviceEntry;
+    PKSPIN_CONNECT Connect = NULL;
+    PDISPATCH_CONTEXT DispatchContext;
+
+    DPRINT("DispatchCreateSysAudioPin entered\n");
+
+    /* get current stack location */
+    IoStack = IoGetCurrentIrpStackLocation(Irp);
+
+    /* sanity checks */
+    ASSERT(IoStack->FileObject);
+    ASSERT(IoStack->FileObject->RelatedFileObject);
+    ASSERT(IoStack->FileObject->RelatedFileObject->FsContext);
+
+    /* get current attached virtual device */
+    DeviceEntry = (PKSAUDIO_DEVICE_ENTRY)IoStack->FileObject->RelatedFileObject->FsContext;
+
+    /* now validate pin connect request */
+    Status = KsValidateConnectRequest(Irp, DeviceEntry->PinDescriptorsCount, DeviceEntry->PinDescriptors, &Connect);
+
+    /* check for success */
+    if (!NT_SUCCESS(Status))
+    {
+        /* failed */
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
+    }
+
+    /* allocate dispatch context */
+    DispatchContext = ExAllocatePool(NonPagedPool, sizeof(DISPATCH_CONTEXT));
+    if (!DispatchContext)
+    {
+        /* failed */
+        Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return STATUS_INSUFFICIENT_RESOURCES;
+    }
+
+    /* zero dispatch context */
+    RtlZeroMemory(DispatchContext, sizeof(DISPATCH_CONTEXT));
 
     /* allocate object header */
-    Status = KsAllocateObjectHeader(&ObjectHeader, 0, NULL, Irp, &PinTable);
+    Status = KsAllocateObjectHeader(&DispatchContext->ObjectHeader, 0, NULL, Irp, &PinTable);
+    if (!NT_SUCCESS(Status))
+    {
+        /* failed */
+        ExFreePool(DispatchContext);
+        Irp->IoStatus.Status = Status;
+        IoCompleteRequest(Irp, IO_NO_INCREMENT);
+        return Status;
+    }
+
+    /* now instantiate the pins */
+    Status = InstantiatePins(DeviceEntry, Connect, DispatchContext, (PSYSAUDIODEVEXT)DeviceObject->DeviceExtension);
+    if (!NT_SUCCESS(Status))
+    {
+        /* failed */
+        KsFreeObjectHeader(DispatchContext->ObjectHeader);
+        ExFreePool(DispatchContext);
+    }
+    else
+    {
+        /* store dispatch context */
+        IoStack->FileObject->FsContext = (PVOID)DispatchContext;
+    }
+
+
+    /* FIXME create items for clocks / allocators */
+    Irp->IoStatus.Status = Status;
+    IoCompleteRequest(Irp, IO_NO_INCREMENT);
     return Status;
 }