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

control.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/deviface.c
00005  * PURPOSE:         System Audio graph builder
00006  * PROGRAMMER:      Andrew Greenwood
00007  *                  Johannes Anderwald
00008  */
00009 #include "wdmaud.h"
00010 
00011 const GUID KSPROPSETID_Sysaudio                 = {0xCBE3FAA0L, 0xCC75, 0x11D0, {0xB4, 0x65, 0x00, 0x00, 0x1A, 0x18, 0x18, 0xE6}};
00012 
00013 NTSTATUS
00014 WdmAudControlOpen(
00015     IN  PDEVICE_OBJECT DeviceObject,
00016     IN  PIRP Irp,
00017     IN  PWDMAUD_DEVICE_INFO DeviceInfo,
00018     IN  PWDMAUD_CLIENT ClientInfo)
00019 {
00020     if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
00021     {
00022         return WdmAudControlOpenMixer(DeviceObject, Irp, DeviceInfo, ClientInfo);
00023     }
00024 
00025     if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
00026     {
00027         return WdmAudControlOpenWave(DeviceObject, Irp, DeviceInfo, ClientInfo);
00028     }
00029 
00030     if (DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE || DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE)
00031     {
00032         return WdmAudControlOpenMidi(DeviceObject, Irp, DeviceInfo, ClientInfo);
00033     }
00034 
00035 
00036     return SetIrpIoStatus(Irp, STATUS_NOT_SUPPORTED, sizeof(WDMAUD_DEVICE_INFO));
00037 }
00038 
00039 NTSTATUS
00040 WdmAudControlDeviceType(
00041     IN  PDEVICE_OBJECT DeviceObject,
00042     IN  PIRP Irp,
00043     IN  PWDMAUD_DEVICE_INFO DeviceInfo,
00044     IN  PWDMAUD_CLIENT ClientInfo)
00045 {
00046     ULONG Result = 0;
00047     NTSTATUS Status = STATUS_SUCCESS;
00048     //PWDMAUD_DEVICE_EXTENSION DeviceExtension;
00049 
00050     //DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00051 
00052     if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
00053     {
00054         Result = WdmAudGetMixerDeviceCount();
00055     }
00056     else if (DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
00057     {
00058         Result = WdmAudGetWaveInDeviceCount();
00059     }
00060     else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE)
00061     {
00062         Result = WdmAudGetWaveOutDeviceCount();
00063     }
00064     else if (DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE)
00065     {
00066         Result = WdmAudGetMidiInDeviceCount();
00067     }
00068     else if (DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE)
00069     {
00070         Result = WdmAudGetMidiOutDeviceCount();
00071     }
00072 
00073 
00074     /* store result count */
00075     DeviceInfo->DeviceCount = Result;
00076 
00077     DPRINT("WdmAudControlDeviceType Status %x Devices %u\n", Status, DeviceInfo->DeviceCount);
00078     return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
00079 }
00080 
00081 NTSTATUS
00082 WdmAudControlDeviceState(
00083     IN  PDEVICE_OBJECT DeviceObject,
00084     IN  PIRP Irp,
00085     IN  PWDMAUD_DEVICE_INFO DeviceInfo,
00086     IN  PWDMAUD_CLIENT ClientInfo)
00087 {
00088     KSPROPERTY Property;
00089     KSSTATE State;
00090     NTSTATUS Status;
00091     ULONG BytesReturned;
00092     PFILE_OBJECT FileObject;
00093 
00094     DPRINT("WdmAudControlDeviceState\n");
00095 
00096     Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
00097     if (!NT_SUCCESS(Status))
00098     {
00099         DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
00100         return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
00101     }
00102 
00103     Property.Set = KSPROPSETID_Connection;
00104     Property.Id = KSPROPERTY_CONNECTION_STATE;
00105     Property.Flags = KSPROPERTY_TYPE_SET;
00106 
00107     State = DeviceInfo->u.State;
00108 
00109     Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&State, sizeof(KSSTATE), &BytesReturned);
00110 
00111     ObDereferenceObject(FileObject);
00112 
00113     DPRINT("WdmAudControlDeviceState Status %x\n", Status);
00114     return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
00115 }
00116 
00117 NTSTATUS
00118 WdmAudCapabilities(
00119     IN  PDEVICE_OBJECT DeviceObject,
00120     IN  PIRP Irp,
00121     IN  PWDMAUD_DEVICE_INFO DeviceInfo,
00122     IN  PWDMAUD_CLIENT ClientInfo)
00123 {
00124     PWDMAUD_DEVICE_EXTENSION DeviceExtension;
00125     NTSTATUS Status = STATUS_UNSUCCESSFUL;
00126 
00127     DPRINT("WdmAudCapabilities entered\n");
00128 
00129     DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00130 
00131     if (DeviceInfo->DeviceType == MIXER_DEVICE_TYPE)
00132     {
00133         Status = WdmAudMixerCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
00134     }
00135     else if (DeviceInfo->DeviceType == WAVE_IN_DEVICE_TYPE || DeviceInfo->DeviceType == WAVE_OUT_DEVICE_TYPE)
00136     {
00137         Status = WdmAudWaveCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
00138     }
00139     else if (DeviceInfo->DeviceType == MIDI_IN_DEVICE_TYPE || DeviceInfo->DeviceType == MIDI_OUT_DEVICE_TYPE)
00140     {
00141         Status = WdmAudMidiCapabilities(DeviceObject, DeviceInfo, ClientInfo, DeviceExtension);
00142     }
00143 
00144     return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
00145 }
00146 
00147 NTSTATUS
00148 NTAPI
00149 WdmAudIoctlClose(
00150     IN  PDEVICE_OBJECT DeviceObject,
00151     IN  PIRP Irp,
00152     IN  PWDMAUD_DEVICE_INFO DeviceInfo,
00153     IN  PWDMAUD_CLIENT ClientInfo)
00154 {
00155     ULONG Index;
00156 
00157     for(Index = 0; Index < ClientInfo->NumPins; Index++)
00158     {
00159         if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type != MIXER_DEVICE_TYPE)
00160         {
00161             DPRINT1("Closing device %p\n", DeviceInfo->hDevice);
00162             ZwClose(DeviceInfo->hDevice);
00163             ClientInfo->hPins[Index].Handle = NULL;
00164             SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
00165             return STATUS_SUCCESS;
00166         }
00167         else if (ClientInfo->hPins[Index].Handle == DeviceInfo->hDevice && ClientInfo->hPins[Index].Type == MIXER_DEVICE_TYPE)
00168         {
00169             if (ClientInfo->hPins[Index].NotifyEvent)
00170             {
00171                 ObDereferenceObject(ClientInfo->hPins[Index].NotifyEvent);
00172                 ClientInfo->hPins[Index].NotifyEvent = NULL;
00173             }
00174         }
00175     }
00176 
00177     SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, sizeof(WDMAUD_DEVICE_INFO));
00178     return STATUS_INVALID_PARAMETER;
00179 }
00180 
00181 NTSTATUS
00182 NTAPI
00183 WdmAudFrameSize(
00184     IN  PDEVICE_OBJECT DeviceObject,
00185     IN  PIRP Irp,
00186     IN  PWDMAUD_DEVICE_INFO DeviceInfo,
00187     IN  PWDMAUD_CLIENT ClientInfo)
00188 {
00189     PFILE_OBJECT FileObject;
00190     KSPROPERTY Property;
00191     ULONG BytesReturned;
00192     KSALLOCATOR_FRAMING Framing;
00193     NTSTATUS Status;
00194 
00195     /* Get sysaudio pin file object */
00196     Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
00197     if (!NT_SUCCESS(Status))
00198     {
00199         DPRINT1("Invalid buffer handle %p\n", DeviceInfo->hDevice);
00200         return SetIrpIoStatus(Irp, Status, 0);
00201     }
00202 
00203     /* Setup get framing request */
00204     Property.Id = KSPROPERTY_CONNECTION_ALLOCATORFRAMING;
00205     Property.Flags = KSPROPERTY_TYPE_GET;
00206     Property.Set = KSPROPSETID_Connection;
00207 
00208     Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_PROPERTY, (PVOID)&Property, sizeof(KSPROPERTY), (PVOID)&Framing, sizeof(KSALLOCATOR_FRAMING), &BytesReturned);
00209     /* Did we succeed */
00210     if (NT_SUCCESS(Status))
00211     {
00212         /* Store framesize */
00213         DeviceInfo->u.FrameSize = Framing.FrameSize;
00214     }
00215 
00216     /* Release file object */
00217     ObDereferenceObject(FileObject);
00218 
00219     return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
00220 
00221 }
00222 
00223 NTSTATUS
00224 NTAPI
00225 WdmAudGetDeviceInterface(
00226     IN  PDEVICE_OBJECT DeviceObject,
00227     IN  PIRP Irp,
00228     IN  PWDMAUD_DEVICE_INFO DeviceInfo)
00229 {
00230     //PWDMAUD_DEVICE_EXTENSION DeviceExtension;
00231     NTSTATUS Status;
00232     LPWSTR Device;
00233     ULONG Size, Length;
00234 
00235     /* get device extension */
00236     //DeviceExtension = (PWDMAUD_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
00237 
00238     /* get device interface string input length */
00239     Size = DeviceInfo->u.Interface.DeviceInterfaceStringSize;
00240 
00241    /* get mixer info */
00242    Status = WdmAudGetPnpNameByIndexAndType(DeviceInfo->DeviceIndex, DeviceInfo->DeviceType, &Device);
00243 
00244    /* check for success */
00245    if (!NT_SUCCESS(Status))
00246    {
00247         /* invalid device id */
00248         return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
00249    }
00250 
00251    /* calculate length */
00252    Length = (wcslen(Device)+1) * sizeof(WCHAR);
00253 
00254     if (!Size)
00255     {
00256         /* store device interface size */
00257         DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
00258     }
00259     else if (Size < Length)
00260     {
00261         /* buffer too small */
00262         DeviceInfo->u.Interface.DeviceInterfaceStringSize = Length;
00263         return SetIrpIoStatus(Irp, STATUS_BUFFER_OVERFLOW, sizeof(WDMAUD_DEVICE_INFO));
00264     }
00265     else
00266     {
00267         //FIXME SEH
00268         RtlMoveMemory(DeviceInfo->u.Interface.DeviceInterfaceString, Device, Length);
00269     }
00270 
00271     FreeItem(Device);
00272     return SetIrpIoStatus(Irp, STATUS_SUCCESS, sizeof(WDMAUD_DEVICE_INFO));
00273 }
00274 
00275 NTSTATUS
00276 NTAPI
00277 WdmAudResetStream(
00278     IN  PDEVICE_OBJECT DeviceObject,
00279     IN  PIRP Irp,
00280     IN  PWDMAUD_DEVICE_INFO DeviceInfo)
00281 {
00282     KSRESET ResetStream;
00283     NTSTATUS Status;
00284     ULONG BytesReturned;
00285     PFILE_OBJECT FileObject;
00286 
00287     DPRINT("WdmAudResetStream\n");
00288 
00289     Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_READ | GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
00290     if (!NT_SUCCESS(Status))
00291     {
00292         DPRINT1("Error: invalid device handle provided %p Type %x\n", DeviceInfo->hDevice, DeviceInfo->DeviceType);
00293         return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
00294     }
00295 
00296     ResetStream = DeviceInfo->u.ResetStream;
00297     ASSERT(ResetStream == KSRESET_BEGIN || ResetStream == KSRESET_END);
00298 
00299     Status = KsSynchronousIoControlDevice(FileObject, KernelMode, IOCTL_KS_RESET_STATE, (PVOID)&ResetStream, sizeof(KSRESET), NULL, 0, &BytesReturned);
00300 
00301     ObDereferenceObject(FileObject);
00302 
00303     DPRINT("WdmAudResetStream Status %x\n", Status);
00304     return SetIrpIoStatus(Irp, Status, sizeof(WDMAUD_DEVICE_INFO));
00305 }
00306 
00307 NTSTATUS
00308 NTAPI
00309 WdmAudDeviceControl(
00310     IN  PDEVICE_OBJECT DeviceObject,
00311     IN  PIRP Irp)
00312 {
00313     PIO_STACK_LOCATION IoStack;
00314     PWDMAUD_DEVICE_INFO DeviceInfo;
00315     PWDMAUD_CLIENT ClientInfo;
00316 
00317     IoStack = IoGetCurrentIrpStackLocation(Irp);
00318 
00319     DPRINT("WdmAudDeviceControl entered\n");
00320 
00321     if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(WDMAUD_DEVICE_INFO))
00322     {
00323         /* invalid parameter */
00324         DPRINT1("Input buffer too small size %u expected %u\n", IoStack->Parameters.DeviceIoControl.InputBufferLength, sizeof(WDMAUD_DEVICE_INFO));
00325         return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
00326     }
00327 
00328     DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;
00329 
00330     if (DeviceInfo->DeviceType < MIN_SOUND_DEVICE_TYPE || DeviceInfo->DeviceType > MAX_SOUND_DEVICE_TYPE)
00331     {
00332         /* invalid parameter */
00333         DPRINT1("Error: device type not set\n");
00334         return SetIrpIoStatus(Irp, STATUS_INVALID_PARAMETER, 0);
00335     }
00336 
00337     if (!IoStack->FileObject || !IoStack->FileObject->FsContext)
00338     {
00339         /* file object parameter */
00340         DPRINT1("Error: file object is not attached\n");
00341         return SetIrpIoStatus(Irp, STATUS_UNSUCCESSFUL, 0);
00342     }
00343     ClientInfo = (PWDMAUD_CLIENT)IoStack->FileObject->FsContext;
00344 
00345     DPRINT("WdmAudDeviceControl entered\n");
00346 
00347     switch(IoStack->Parameters.DeviceIoControl.IoControlCode)
00348     {
00349         case IOCTL_OPEN_WDMAUD:
00350             return WdmAudControlOpen(DeviceObject, Irp, DeviceInfo, ClientInfo);
00351         case IOCTL_GETNUMDEVS_TYPE:
00352             return WdmAudControlDeviceType(DeviceObject, Irp, DeviceInfo, ClientInfo);
00353         case IOCTL_SETDEVICE_STATE:
00354             return WdmAudControlDeviceState(DeviceObject, Irp, DeviceInfo, ClientInfo);
00355         case IOCTL_GETCAPABILITIES:
00356             return WdmAudCapabilities(DeviceObject, Irp, DeviceInfo, ClientInfo);
00357         case IOCTL_CLOSE_WDMAUD:
00358             return WdmAudIoctlClose(DeviceObject, Irp, DeviceInfo, ClientInfo);
00359         case IOCTL_GETFRAMESIZE:
00360             return WdmAudFrameSize(DeviceObject, Irp, DeviceInfo, ClientInfo);
00361         case IOCTL_GETLINEINFO:
00362             return WdmAudGetLineInfo(DeviceObject, Irp, DeviceInfo, ClientInfo);
00363         case IOCTL_GETLINECONTROLS:
00364             return WdmAudGetLineControls(DeviceObject, Irp, DeviceInfo, ClientInfo);
00365         case IOCTL_SETCONTROLDETAILS:
00366             return WdmAudSetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
00367         case IOCTL_GETCONTROLDETAILS:
00368             return WdmAudGetControlDetails(DeviceObject, Irp, DeviceInfo, ClientInfo);
00369         case IOCTL_QUERYDEVICEINTERFACESTRING:
00370             return WdmAudGetDeviceInterface(DeviceObject, Irp, DeviceInfo);
00371         case IOCTL_GET_MIXER_EVENT:
00372             return WdmAudGetMixerEvent(DeviceObject, Irp, DeviceInfo, ClientInfo);
00373         case IOCTL_RESET_STREAM:
00374             return WdmAudResetStream(DeviceObject, Irp, DeviceInfo);
00375         case IOCTL_GETPOS:
00376         case IOCTL_GETDEVID:
00377         case IOCTL_GETVOLUME:
00378         case IOCTL_SETVOLUME:
00379 
00380            DPRINT1("Unhandeled %x\n", IoStack->Parameters.DeviceIoControl.IoControlCode);
00381            break;
00382     }
00383 
00384     return SetIrpIoStatus(Irp, STATUS_NOT_IMPLEMENTED, 0);
00385 }
00386 
00387 NTSTATUS
00388 NTAPI
00389 IoCompletion (
00390     PDEVICE_OBJECT DeviceObject,
00391     PIRP Irp,
00392     PVOID Ctx)
00393 {
00394     PKSSTREAM_HEADER Header;
00395     ULONG Length = 0;
00396     PMDL Mdl, NextMdl;
00397     PWDMAUD_COMPLETION_CONTEXT Context = (PWDMAUD_COMPLETION_CONTEXT)Ctx;
00398 
00399     /* get stream header */
00400     Header = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
00401 
00402     /* sanity check */
00403     ASSERT(Header);
00404 
00405     /* time to free all allocated mdls */
00406     Mdl = Irp->MdlAddress;
00407 
00408     while(Mdl)
00409     {
00410         /* get next mdl */
00411         NextMdl = Mdl->Next;
00412 
00413         /* unlock pages */
00414         MmUnlockPages(Mdl);
00415 
00416         /* grab next mdl */
00417         Mdl = NextMdl;
00418     }
00419 
00420     /* clear mdl list */
00421     Irp->MdlAddress = NULL;
00422 
00423    /* check if mdl is locked */
00424     if (Context->Mdl->MdlFlags & MDL_PAGES_LOCKED)
00425     {
00426         /* unlock pages */
00427         MmUnlockPages(Context->Mdl);
00428     }
00429 
00430     /* now free the mdl */
00431     IoFreeMdl(Context->Mdl);
00432 
00433     DPRINT("IoCompletion Irp %p IoStatus %lx Information %lx Length %lu\n", Irp, Irp->IoStatus.Status, Irp->IoStatus.Information, Length);
00434 
00435     if (!NT_SUCCESS(Irp->IoStatus.Status))
00436     {
00437         /* failed */
00438         Irp->IoStatus.Information = 0;
00439     }
00440 
00441     /* free context */
00442     FreeItem(Context);
00443 
00444     return STATUS_SUCCESS;
00445 }
00446 
00447 NTSTATUS
00448 NTAPI
00449 WdmAudReadWrite(
00450     IN  PDEVICE_OBJECT DeviceObject,
00451     IN  PIRP Irp)
00452 {
00453     NTSTATUS Status;
00454     PWDMAUD_DEVICE_INFO DeviceInfo;
00455     PFILE_OBJECT FileObject;
00456     PIO_STACK_LOCATION IoStack;
00457     ULONG Length;
00458     PMDL Mdl;
00459     BOOLEAN Read = TRUE;
00460     PWDMAUD_COMPLETION_CONTEXT Context;
00461 
00462     /* allocate completion context */
00463     Context = AllocateItem(NonPagedPool, sizeof(WDMAUD_COMPLETION_CONTEXT));
00464 
00465     if (!Context)
00466     {
00467         /* not enough memory */
00468         Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
00469         IoCompleteRequest(Irp, IO_NO_INCREMENT);
00470 
00471         /* done */
00472         return STATUS_INSUFFICIENT_RESOURCES;
00473     }
00474 
00475     /* get current irp stack location */
00476     IoStack = IoGetCurrentIrpStackLocation(Irp);
00477 
00478     /* store the input buffer in UserBuffer - as KsProbeStreamIrp operates on IRP_MJ_DEVICE_CONTROL */
00479     Irp->UserBuffer = MmGetMdlVirtualAddress(Irp->MdlAddress);
00480 
00481     /* sanity check */
00482     ASSERT(Irp->UserBuffer);
00483 
00484     /* get the length of the request length */
00485     Length = IoStack->Parameters.Write.Length;
00486 
00487     /* store outputbuffer length */
00488     IoStack->Parameters.DeviceIoControl.OutputBufferLength = Length;
00489 
00490     /* setup context */
00491     Context->Length = Length;
00492     Context->Function = (IoStack->MajorFunction == IRP_MJ_WRITE ? IOCTL_KS_WRITE_STREAM : IOCTL_KS_READ_STREAM);
00493     Context->Mdl = Irp->MdlAddress;
00494 
00495     /* store mdl address */
00496     Mdl = Irp->MdlAddress;
00497 
00498     /* remove mdladdress as KsProbeStreamIrp will interprete it as an already probed audio buffer */
00499     Irp->MdlAddress = NULL;
00500 
00501     /* check for success */
00502 
00503     if (IoStack->MajorFunction == IRP_MJ_WRITE)
00504     {
00505         /* probe the write stream irp */
00506         Read = FALSE;
00507         Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMWRITE | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
00508     }
00509     else
00510     {
00511         /* probe the read stream irp */
00512         Status = KsProbeStreamIrp(Irp, KSPROBE_STREAMREAD | KSPROBE_ALLOCATEMDL | KSPROBE_PROBEANDLOCK, Length);
00513     }
00514 
00515     if (!NT_SUCCESS(Status))
00516     {
00517         DPRINT1("KsProbeStreamIrp failed with Status %x Cancel %u\n", Status, Irp->Cancel);
00518         Irp->MdlAddress = Mdl;
00519         return SetIrpIoStatus(Irp, Status, 0);
00520     }
00521 
00522     /* get device info */
00523     DeviceInfo = (PWDMAUD_DEVICE_INFO)Irp->AssociatedIrp.SystemBuffer;
00524     ASSERT(DeviceInfo);
00525 
00526     /* now get sysaudio file object */
00527     Status = ObReferenceObjectByHandle(DeviceInfo->hDevice, GENERIC_WRITE, IoFileObjectType, KernelMode, (PVOID*)&FileObject, NULL);
00528     if (!NT_SUCCESS(Status))
00529     {
00530         DPRINT1("Invalid pin handle %p\n", DeviceInfo->hDevice);
00531         return SetIrpIoStatus(Irp, Status, 0);
00532     }
00533 
00534     /* skip current irp stack location */
00535     IoSkipCurrentIrpStackLocation(Irp);
00536 
00537     /* get next stack location */
00538     IoStack = IoGetNextIrpStackLocation(Irp);
00539 
00540     if (Read)
00541     {
00542         IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_READ_STREAM;
00543     }
00544     else
00545     {
00546         IoStack->Parameters.DeviceIoControl.IoControlCode = IOCTL_KS_WRITE_STREAM;
00547     }
00548 
00549     /* attach file object */
00550     IoStack->FileObject = FileObject;
00551     IoStack->Parameters.Write.Length = Length;
00552     IoStack->MajorFunction = IRP_MJ_WRITE;
00553 
00554     IoSetCompletionRoutine(Irp, IoCompletion, (PVOID)Context, TRUE, TRUE, TRUE);
00555 
00556 
00557     /* mark irp as pending */
00558 //    IoMarkIrpPending(Irp);
00559     /* call the driver */
00560     Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
00561 
00562     /* dereference file object */
00563     ObDereferenceObject(FileObject);
00564 
00565     return Status;
00566 }

Generated on Sun May 27 2012 04:16:33 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.