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

irp.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/ksfilter/ks/factory.c
00005  * PURPOSE:         KS Allocator functions
00006  * PROGRAMMER:      Johannes Anderwald
00007  */
00008 
00009 
00010 #include "priv.h"
00011 
00012 /*
00013     @implemented
00014 */
00015 KSDDKAPI
00016 NTSTATUS
00017 NTAPI
00018 KsDispatchQuerySecurity(
00019     IN PDEVICE_OBJECT DeviceObject,
00020     IN PIRP Irp)
00021 {
00022     PKSOBJECT_CREATE_ITEM CreateItem;
00023     PIO_STACK_LOCATION IoStack;
00024     NTSTATUS Status;
00025     ULONG Length;
00026 
00027     /* get current irp stack */
00028     IoStack = IoGetCurrentIrpStackLocation(Irp);
00029 
00030     /* get create item */
00031     CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
00032 
00033     if (!CreateItem || !CreateItem->SecurityDescriptor)
00034     {
00035         /* no create item */
00036         Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT;
00037         CompleteRequest(Irp, IO_NO_INCREMENT);
00038         return STATUS_NO_SECURITY_ON_OBJECT;
00039     }
00040 
00041 
00042     /* get input length */
00043     Length = IoStack->Parameters.QuerySecurity.Length;
00044 
00045     /* clone the security descriptor */
00046     Status = SeQuerySecurityDescriptorInfo(&IoStack->Parameters.QuerySecurity.SecurityInformation, (PSECURITY_DESCRIPTOR)Irp->UserBuffer, &Length, &CreateItem->SecurityDescriptor);
00047 
00048     DPRINT("SeQuerySecurityDescriptorInfo Status %x\n", Status);
00049     /* store result */
00050     Irp->IoStatus.Status = Status;
00051     Irp->IoStatus.Information = Length;
00052 
00053     CompleteRequest(Irp, IO_NO_INCREMENT);
00054     return Status;
00055 }
00056 
00057 /*
00058     @implemented
00059 */
00060 KSDDKAPI
00061 NTSTATUS
00062 NTAPI
00063 KsDispatchSetSecurity(
00064     IN PDEVICE_OBJECT DeviceObject,
00065     IN PIRP Irp)
00066 {
00067     PKSOBJECT_CREATE_ITEM CreateItem;
00068     PIO_STACK_LOCATION IoStack;
00069     PGENERIC_MAPPING Mapping;
00070     PSECURITY_DESCRIPTOR Descriptor;
00071     NTSTATUS Status;
00072 
00073     /* get current irp stack */
00074     IoStack = IoGetCurrentIrpStackLocation(Irp);
00075 
00076     /* get create item */
00077     CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
00078 
00079     if (!CreateItem || !CreateItem->SecurityDescriptor)
00080     {
00081         /* no create item */
00082         Irp->IoStatus.Status = STATUS_NO_SECURITY_ON_OBJECT;
00083         CompleteRequest(Irp, IO_NO_INCREMENT);
00084         return STATUS_NO_SECURITY_ON_OBJECT;
00085     }
00086 
00087     /* backup old descriptor */
00088     Descriptor = CreateItem->SecurityDescriptor;
00089 
00090     /* get generic mapping */
00091     Mapping = IoGetFileObjectGenericMapping();
00092 
00093     /* change security descriptor */
00094     Status = SeSetSecurityDescriptorInfo(NULL, /*FIXME */
00095                                          &IoStack->Parameters.SetSecurity.SecurityInformation,
00096                                          IoStack->Parameters.SetSecurity.SecurityDescriptor,
00097                                          &CreateItem->SecurityDescriptor,
00098                                          NonPagedPool,
00099                                          Mapping);
00100 
00101     if (NT_SUCCESS(Status))
00102     {
00103         /* free old descriptor */
00104         FreeItem(Descriptor);
00105 
00106        /* mark create item as changed */
00107        CreateItem->Flags |= KSCREATE_ITEM_SECURITYCHANGED;
00108     }
00109 
00110     /* store result */
00111     Irp->IoStatus.Status = Status;
00112     CompleteRequest(Irp, IO_NO_INCREMENT);
00113 
00114     return Status;
00115 }
00116 
00117 /*
00118     @unimplemented
00119 */
00120 KSDDKAPI
00121 NTSTATUS
00122 NTAPI
00123 KsDispatchSpecificMethod(
00124     IN  PIRP Irp,
00125     IN  PFNKSHANDLER Handler)
00126 {
00127     UNIMPLEMENTED;
00128     return STATUS_UNSUCCESSFUL;
00129 }
00130 
00131 
00132 /*
00133     @implemented
00134 */
00135 KSDDKAPI
00136 NTSTATUS
00137 NTAPI
00138 KsReadFile(
00139     IN  PFILE_OBJECT FileObject,
00140     IN  PKEVENT Event OPTIONAL,
00141     IN  PVOID PortContext OPTIONAL,
00142     OUT PIO_STATUS_BLOCK IoStatusBlock,
00143     OUT PVOID Buffer,
00144     IN  ULONG Length,
00145     IN  ULONG Key OPTIONAL,
00146     IN  KPROCESSOR_MODE RequestorMode)
00147 {
00148     PDEVICE_OBJECT DeviceObject;
00149     PIRP Irp;
00150     NTSTATUS Status;
00151     BOOLEAN Result;
00152     KEVENT LocalEvent;
00153 
00154     if (Event)
00155     {
00156         /* make sure event is reset */
00157         KeClearEvent(Event);
00158     }
00159 
00160     if (RequestorMode == UserMode)
00161     {
00162         /* probe the user buffer */
00163         _SEH2_TRY
00164         {
00165             ProbeForWrite(Buffer, Length, sizeof(UCHAR));
00166             Status = STATUS_SUCCESS;
00167         }
00168         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00169         {
00170             /* Exception, get the error code */
00171             Status = _SEH2_GetExceptionCode();
00172         }
00173         _SEH2_END;
00174 
00175          if (!NT_SUCCESS(Status))
00176          {
00177              DPRINT1("Invalid user buffer provided\n");
00178              return Status;
00179          }
00180     }
00181 
00182     /* get corresponding device object */
00183     DeviceObject = IoGetRelatedDeviceObject(FileObject);
00184 
00185     /* fast-io read is only available for kernel mode clients */
00186     if (RequestorMode == KernelMode && ExGetPreviousMode() == KernelMode &&
00187         DeviceObject->DriverObject->FastIoDispatch->FastIoRead)
00188     {
00189         /* call fast io write */
00190         Result = DeviceObject->DriverObject->FastIoDispatch->FastIoRead(FileObject, &FileObject->CurrentByteOffset, Length, TRUE, Key, Buffer, IoStatusBlock, DeviceObject);
00191 
00192         if (Result && NT_SUCCESS(IoStatusBlock->Status))
00193         {
00194             /* request was handeled and succeeded */
00195             return STATUS_SUCCESS;
00196         }
00197     }
00198 
00199     /* do the slow way */
00200     if (!Event)
00201     {
00202         /* initialize temp event */
00203         KeInitializeEvent(&LocalEvent, NotificationEvent, FALSE);
00204         Event = &LocalEvent;
00205     }
00206 
00207     /* build the irp packet */
00208     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_READ, DeviceObject, Buffer, Length, &FileObject->CurrentByteOffset, Event, IoStatusBlock);
00209     if (!Irp)
00210     {
00211         /* not enough resources */
00212         return STATUS_INSUFFICIENT_RESOURCES;
00213     }
00214 
00215     /* send the packet */
00216     Status = IoCallDriver(DeviceObject, Irp);
00217 
00218     if (Status == STATUS_PENDING)
00219     {
00220         /* operation is pending, is sync file object */
00221         if (FileObject->Flags & FO_SYNCHRONOUS_IO)
00222         {
00223             /* it is so wait */
00224             KeWaitForSingleObject(Event, Executive, RequestorMode, FALSE, NULL);
00225             Status = IoStatusBlock->Status;
00226         }
00227     }
00228     /* return result */
00229     return Status;
00230 }
00231 
00232 /*
00233     @implemented
00234 */
00235 KSDDKAPI
00236 NTSTATUS
00237 NTAPI
00238 KsWriteFile(
00239     IN  PFILE_OBJECT FileObject,
00240     IN  PKEVENT Event OPTIONAL,
00241     IN  PVOID PortContext OPTIONAL,
00242     OUT PIO_STATUS_BLOCK IoStatusBlock,
00243     IN  PVOID Buffer,
00244     IN  ULONG Length,
00245     IN  ULONG Key OPTIONAL,
00246     IN  KPROCESSOR_MODE RequestorMode)
00247 {
00248     PDEVICE_OBJECT DeviceObject;
00249     PIRP Irp;
00250     NTSTATUS Status;
00251     BOOLEAN Result;
00252     KEVENT LocalEvent;
00253 
00254     if (Event)
00255     {
00256         /* make sure event is reset */
00257         KeClearEvent(Event);
00258     }
00259 
00260     if (RequestorMode == UserMode)
00261     {
00262         /* probe the user buffer */
00263         _SEH2_TRY
00264         {
00265             ProbeForRead(Buffer, Length, sizeof(UCHAR));
00266             Status = STATUS_SUCCESS;
00267         }
00268         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00269         {
00270             /* Exception, get the error code */
00271             Status = _SEH2_GetExceptionCode();
00272         }
00273         _SEH2_END;
00274 
00275          if (!NT_SUCCESS(Status))
00276          {
00277              DPRINT1("Invalid user buffer provided\n");
00278              return Status;
00279          }
00280     }
00281 
00282     /* get corresponding device object */
00283     DeviceObject = IoGetRelatedDeviceObject(FileObject);
00284 
00285     /* fast-io write is only available for kernel mode clients */
00286     if (RequestorMode == KernelMode && ExGetPreviousMode() == KernelMode &&
00287         DeviceObject->DriverObject->FastIoDispatch->FastIoWrite)
00288     {
00289         /* call fast io write */
00290         Result = DeviceObject->DriverObject->FastIoDispatch->FastIoWrite(FileObject, &FileObject->CurrentByteOffset, Length, TRUE, Key, Buffer, IoStatusBlock, DeviceObject);
00291 
00292         if (Result && NT_SUCCESS(IoStatusBlock->Status))
00293         {
00294             /* request was handeled and succeeded */
00295             return STATUS_SUCCESS;
00296         }
00297     }
00298 
00299     /* do the slow way */
00300     if (!Event)
00301     {
00302         /* initialize temp event */
00303         KeInitializeEvent(&LocalEvent, NotificationEvent, FALSE);
00304         Event = &LocalEvent;
00305     }
00306 
00307     /* build the irp packet */
00308     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_WRITE, DeviceObject, Buffer, Length, &FileObject->CurrentByteOffset, Event, IoStatusBlock);
00309     if (!Irp)
00310     {
00311         /* not enough resources */
00312         return STATUS_INSUFFICIENT_RESOURCES;
00313     }
00314 
00315     /* send the packet */
00316     Status = IoCallDriver(DeviceObject, Irp);
00317 
00318     if (Status == STATUS_PENDING)
00319     {
00320         /* operation is pending, is sync file object */
00321         if (FileObject->Flags & FO_SYNCHRONOUS_IO)
00322         {
00323             /* it is so wait */
00324             KeWaitForSingleObject(Event, Executive, RequestorMode, FALSE, NULL);
00325             Status = IoStatusBlock->Status;
00326         }
00327     }
00328     /* return result */
00329     return Status;
00330 }
00331 
00332 /*
00333     @implemented
00334 */
00335 KSDDKAPI
00336 NTSTATUS
00337 NTAPI
00338 KsQueryInformationFile(
00339     IN  PFILE_OBJECT FileObject,
00340     OUT PVOID FileInformation,
00341     IN  ULONG Length,
00342     IN  FILE_INFORMATION_CLASS FileInformationClass)
00343 {
00344     PDEVICE_OBJECT DeviceObject;
00345     PFAST_IO_DISPATCH FastIoDispatch;
00346     PIRP Irp;
00347     PIO_STACK_LOCATION IoStack;
00348     IO_STATUS_BLOCK IoStatus;
00349     KEVENT Event;
00350     LARGE_INTEGER Offset;
00351     IO_STATUS_BLOCK StatusBlock;
00352     NTSTATUS Status;
00353 
00354     /* get related file object */
00355     DeviceObject = IoGetRelatedDeviceObject(FileObject);
00356 
00357     /* get fast i/o table */
00358     FastIoDispatch = DeviceObject->DriverObject->FastIoDispatch;
00359 
00360     /* is there a fast table */
00361     if (FastIoDispatch)
00362     {
00363         /* check the class */
00364         if (FileInformationClass == FileBasicInformation)
00365         {
00366             /* use FastIoQueryBasicInfo routine */
00367             if (FastIoDispatch->FastIoQueryBasicInfo)
00368             {
00369                 return FastIoDispatch->FastIoQueryBasicInfo(FileObject, TRUE, (PFILE_BASIC_INFORMATION)FileInformation, &IoStatus, DeviceObject);
00370             }
00371         }
00372         else if (FileInformationClass == FileStandardInformation)
00373         {
00374             /* use FastIoQueryBasicInfo routine */
00375             if (FastIoDispatch->FastIoQueryBasicInfo)
00376             {
00377                 return FastIoDispatch->FastIoQueryStandardInfo(FileObject, TRUE, (PFILE_STANDARD_INFORMATION)FileInformation, &IoStatus, DeviceObject);
00378             }
00379         }
00380     }
00381     /* clear event */
00382     KeClearEvent(&FileObject->Event);
00383 
00384     /* initialize event */
00385     KeInitializeEvent(&Event, NotificationEvent, FALSE);
00386 
00387     /* set offset to zero */
00388     Offset.QuadPart = 0L;
00389 
00390     /* build the request */
00391     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_INFORMATION, IoGetRelatedDeviceObject(FileObject), NULL, 0, &Offset, &Event, &StatusBlock);
00392 
00393     if (!Irp)
00394         return STATUS_INSUFFICIENT_RESOURCES;
00395 
00396     /* get next stack location */
00397     IoStack = IoGetNextIrpStackLocation(Irp);
00398 
00399     /* setup parameters */
00400     IoStack->Parameters.QueryFile.FileInformationClass = FileInformationClass;
00401     IoStack->Parameters.QueryFile.Length = Length;
00402     Irp->AssociatedIrp.SystemBuffer = FileInformation;
00403 
00404 
00405     /* call the driver */
00406     Status = IoCallDriver(IoGetRelatedDeviceObject(FileObject), Irp);
00407 
00408     if (Status == STATUS_PENDING)
00409     {
00410         /* wait for the operation to complete */
00411         KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
00412 
00413        /* is object sync */
00414        if (FileObject->Flags & FO_SYNCHRONOUS_IO)
00415            Status = FileObject->FinalStatus;
00416        else
00417            Status = StatusBlock.Status;
00418     }
00419 
00420     /* done */
00421     return Status;
00422 }
00423 
00424 /*
00425     @implemented
00426 */
00427 KSDDKAPI
00428 NTSTATUS
00429 NTAPI
00430 KsSetInformationFile(
00431     IN  PFILE_OBJECT FileObject,
00432     IN  PVOID FileInformation,
00433     IN  ULONG Length,
00434     IN  FILE_INFORMATION_CLASS FileInformationClass)
00435 {
00436     PIO_STACK_LOCATION IoStack;
00437     PDEVICE_OBJECT DeviceObject;
00438     PIRP Irp;
00439     PVOID Buffer;
00440     KEVENT Event;
00441     LARGE_INTEGER Offset;
00442     IO_STATUS_BLOCK IoStatus;
00443     NTSTATUS Status;
00444 
00445     /* get related device object */
00446     DeviceObject = IoGetRelatedDeviceObject(FileObject);
00447 
00448     /* copy file information */
00449     Buffer = AllocateItem(NonPagedPool, Length);
00450     if (!Buffer)
00451         return STATUS_INSUFFICIENT_RESOURCES;
00452 
00453     _SEH2_TRY
00454     {
00455         ProbeForRead(Buffer, Length, sizeof(UCHAR));
00456         RtlMoveMemory(Buffer, FileInformation, Length);
00457         Status = STATUS_SUCCESS;
00458     }
00459     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00460     {
00461         /* Exception, get the error code */
00462         Status = _SEH2_GetExceptionCode();
00463     }
00464     _SEH2_END;
00465 
00466     if (!NT_SUCCESS(Status))
00467     {
00468         /* invalid user buffer */
00469         FreeItem(Buffer);
00470         return Status;
00471     }
00472 
00473     /* initialize the event */
00474     KeInitializeEvent(&Event, SynchronizationEvent, FALSE);
00475 
00476     /* zero offset */
00477     Offset.QuadPart = 0LL;
00478 
00479     /* build the irp */
00480     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_SET_INFORMATION, DeviceObject, NULL, 0, &Offset, &Event, &IoStatus);
00481 
00482     if (!Irp)
00483     {
00484         /* failed to allocate irp */
00485         FreeItem(Buffer);
00486         return STATUS_INSUFFICIENT_RESOURCES;
00487     }
00488 
00489     /* get next stack location */
00490     IoStack = IoGetNextIrpStackLocation(Irp);
00491 
00492     /* set irp parameters */
00493     IoStack->Parameters.SetFile.FileInformationClass = FileInformationClass;
00494     IoStack->Parameters.SetFile.Length = Length;
00495     IoStack->Parameters.SetFile.FileObject = FileObject;
00496     Irp->AssociatedIrp.SystemBuffer = Buffer;
00497     Irp->UserBuffer = FileInformation;
00498 
00499     /* dispatch the irp */
00500     Status = IoCallDriver(DeviceObject, Irp);
00501 
00502     if (Status == STATUS_PENDING)
00503     {
00504         /* wait untill the operation has completed */
00505         KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
00506         /* is a sync file object */
00507         if (FileObject->Flags & FO_SYNCHRONOUS_IO)
00508             Status = FileObject->FinalStatus;
00509         else
00510             Status = IoStatus.Status;
00511     }
00512     /* done */
00513     return Status;
00514 }
00515 
00516 /*
00517     @implemented
00518 */
00519 KSDDKAPI
00520 NTSTATUS
00521 NTAPI
00522 KsStreamIo(
00523     IN  PFILE_OBJECT FileObject,
00524     IN  PKEVENT Event OPTIONAL,
00525     IN  PVOID PortContext OPTIONAL,
00526     IN  PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
00527     IN  PVOID CompletionContext OPTIONAL,
00528     IN  KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL,
00529     OUT PIO_STATUS_BLOCK IoStatusBlock,
00530     IN  OUT PVOID StreamHeaders,
00531     IN  ULONG Length,
00532     IN  ULONG Flags,
00533     IN  KPROCESSOR_MODE RequestorMode)
00534 {
00535     PIRP Irp;
00536     PIO_STACK_LOCATION IoStack;
00537     PDEVICE_OBJECT DeviceObject;
00538     NTSTATUS Status;
00539     LARGE_INTEGER Offset;
00540     PKSIOBJECT_HEADER ObjectHeader;
00541     BOOLEAN Ret;
00542 
00543     /* get related device object */
00544     DeviceObject = IoGetRelatedDeviceObject(FileObject);
00545     /* sanity check */
00546     ASSERT(DeviceObject != NULL);
00547 
00548     /* is there a event provided */
00549     if (Event)
00550     {
00551         /* reset event */
00552         KeClearEvent(Event);
00553     }
00554 
00555     if (RequestorMode || ExGetPreviousMode() == KernelMode)
00556     {
00557         /* requestor is from kernel land */
00558         ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext2;
00559 
00560         if (ObjectHeader)
00561         {
00562             /* there is a object header */
00563             if (Flags == KSSTREAM_READ)
00564             {
00565                 /* is fast read supported */
00566                 if (ObjectHeader->DispatchTable.FastRead)
00567                 {
00568                     /* call fast read dispatch routine */
00569                     Ret = ObjectHeader->DispatchTable.FastRead(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject);
00570 
00571                     if (Ret)
00572                     {
00573                         /* the request was handeled */
00574                         return IoStatusBlock->Status;
00575                     }
00576                 }
00577             }
00578             else if (Flags == KSSTREAM_WRITE)
00579             {
00580                 /* is fast write supported */
00581                 if (ObjectHeader->DispatchTable.FastWrite)
00582                 {
00583                     /* call fast write dispatch routine */
00584                     Ret = ObjectHeader->DispatchTable.FastWrite(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject);
00585 
00586                     if (Ret)
00587                     {
00588                         /* the request was handeled */
00589                         return IoStatusBlock->Status;
00590                     }
00591                 }
00592             }
00593         }
00594     }
00595 
00596     /* clear file object event */
00597     KeClearEvent(&FileObject->Event);
00598 
00599     /* set the offset to zero */
00600     Offset.QuadPart = 0LL;
00601 
00602     /* now build the irp */
00603     Irp = IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL,
00604                                        DeviceObject, (PVOID)StreamHeaders, Length, &Offset, Event, IoStatusBlock);
00605     if (!Irp)
00606     {
00607         /* not enough memory */
00608         return STATUS_INSUFFICIENT_RESOURCES;
00609     }
00610 
00611     /* setup irp parameters */
00612     Irp->RequestorMode = RequestorMode;
00613     Irp->Overlay.AsynchronousParameters.UserApcContext = PortContext;
00614     Irp->Tail.Overlay.OriginalFileObject = FileObject;
00615     Irp->UserBuffer = StreamHeaders;
00616 
00617     /* get next irp stack location */
00618     IoStack = IoGetNextIrpStackLocation(Irp);
00619     /* setup stack parameters */
00620     IoStack->FileObject = FileObject;
00621     IoStack->Parameters.DeviceIoControl.InputBufferLength = Length;
00622     IoStack->Parameters.DeviceIoControl.Type3InputBuffer = StreamHeaders;
00623     IoStack->Parameters.DeviceIoControl.IoControlCode = (Flags == KSSTREAM_READ ? IOCTL_KS_READ_STREAM : IOCTL_KS_WRITE_STREAM);
00624 
00625     if (CompletionRoutine)
00626     {
00627         /* setup completion routine for async processing */
00628         IoSetCompletionRoutine(Irp, CompletionRoutine, CompletionContext, (CompletionInvocationFlags & KsInvokeOnSuccess), (CompletionInvocationFlags & KsInvokeOnError), (CompletionInvocationFlags & KsInvokeOnCancel));
00629     }
00630 
00631     /* now call the driver */
00632     Status = IoCallDriver(DeviceObject, Irp);
00633     /* done */
00634     return Status;
00635 }
00636 
00637 /*
00638     @implemented
00639 */
00640 KSDDKAPI
00641 NTSTATUS
00642 NTAPI
00643 KsProbeStreamIrp(
00644     IN  PIRP Irp,
00645     IN  ULONG ProbeFlags,
00646     IN  ULONG HeaderSize)
00647 {
00648     PMDL Mdl;
00649     PVOID Buffer;
00650     LOCK_OPERATION Operation;
00651     NTSTATUS Status = STATUS_SUCCESS;
00652     PKSSTREAM_HEADER StreamHeader;
00653     PIO_STACK_LOCATION IoStack;
00654     ULONG Length;
00655     //BOOLEAN AllocateMdl = FALSE;
00656 
00657     /* get current irp stack */
00658     IoStack = IoGetCurrentIrpStackLocation(Irp);
00659 
00660     Length = IoStack->Parameters.DeviceIoControl.OutputBufferLength;
00661 
00662     if (Irp->RequestorMode == KernelMode || Irp->AssociatedIrp.SystemBuffer)
00663     {
00664         if (Irp->RequestorMode == KernelMode)
00665         {
00666             /* no need to allocate stream header */
00667             Irp->AssociatedIrp.SystemBuffer = Irp->UserBuffer;
00668         }
00669 AllocMdl:
00670         /* check if alloc mdl flag is passed */
00671         if (!(ProbeFlags & KSPROBE_ALLOCATEMDL))
00672         {
00673             /* nothing more to do */
00674             return STATUS_SUCCESS;
00675         }
00676         if (Irp->MdlAddress)
00677         {
00678 ProbeMdl:
00679             if (ProbeFlags & KSPROBE_PROBEANDLOCK)
00680             {
00681                 if (Irp->MdlAddress->MdlFlags & (MDL_PAGES_LOCKED | MDL_SOURCE_IS_NONPAGED_POOL))
00682                 {
00683                     if (ProbeFlags & KSPROBE_SYSTEMADDRESS)
00684                     {
00685                         _SEH2_TRY
00686                         {
00687                             /* loop through all mdls and probe them */
00688                             Mdl = Irp->MdlAddress;
00689                             do
00690                             {
00691                                 /* the mapping can fail */
00692                                 Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
00693 
00694                                 if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL))
00695                                 {
00696                                     /* no need to probe these pages */
00697                                     Buffer = Mdl->MappedSystemVa;
00698                                 }
00699                                 else
00700                                 {
00701                                     /* probe that mdl */
00702                                     Buffer = MmMapLockedPages(Mdl, KernelMode);
00703                                 }
00704 
00705                                 /* check if the mapping succeeded */
00706                                 if (!Buffer)
00707                                 {
00708                                     /* raise exception we'll catch */
00709                                     ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
00710                                 }
00711 
00712                                 /* iterate to next mdl */
00713                                 Mdl = Mdl->Next;
00714 
00715                             }while(Mdl);
00716                         }
00717                         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00718                         {
00719                             /* Exception, get the error code */
00720                             Status = _SEH2_GetExceptionCode();
00721                         } _SEH2_END;
00722                     }
00723                 }
00724                 else
00725                 {
00726                     _SEH2_TRY
00727                     {
00728                         /* loop through all mdls and probe them */
00729                         Mdl = Irp->MdlAddress;
00730 
00731                         /* determine operation */
00732                         if (!(ProbeFlags & KSPROBE_STREAMWRITE) || (ProbeFlags & KSPROBE_MODIFY))
00733                         {
00734                             /* operation is read / modify stream, need write access */
00735                             Operation = IoWriteAccess;
00736                         }
00737                         else
00738                         {
00739                             /* operation is write to device, so we need read access */
00740                             Operation = IoReadAccess;
00741                         }
00742 
00743                         do
00744                         {
00745                             /* probe the pages */
00746                             MmProbeAndLockPages(Mdl, Irp->RequestorMode, Operation);
00747 
00748                             if (ProbeFlags & KSPROBE_SYSTEMADDRESS)
00749                             {
00750                                 /* the mapping can fail */
00751                                 Mdl->MdlFlags |= MDL_MAPPING_CAN_FAIL;
00752 
00753                                 if (Mdl->MdlFlags & (MDL_MAPPED_TO_SYSTEM_VA | MDL_SOURCE_IS_NONPAGED_POOL))
00754                                 {
00755                                     /* no need to probe these pages */
00756                                     Buffer = Mdl->MappedSystemVa;
00757                                 }
00758                                 else
00759                                 {
00760                                     /* probe that mdl */
00761                                     Buffer = MmMapLockedPages(Mdl, KernelMode);
00762                                 }
00763 
00764                                 /* check if the mapping succeeded */
00765                                 if (!Buffer)
00766                                 {
00767                                     /* raise exception we'll catch */
00768                                     ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
00769                                 }
00770                             }
00771 
00772                             /* iterate to next mdl */
00773                             Mdl = Mdl->Next;
00774 
00775                         }while(Mdl);
00776                     }
00777                     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00778                     {
00779                         /* Exception, get the error code */
00780                         Status = _SEH2_GetExceptionCode();
00781                     } _SEH2_END;
00782                 }
00783             }
00784             return Status;
00785         }
00786 
00787         /* check all stream headers */
00788         StreamHeader = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
00789         ASSERT(StreamHeader);
00790         _SEH2_TRY
00791         {
00792             do
00793             {
00794                 if (HeaderSize)
00795                 {
00796                     /* does the supplied header size match stream header size and no type changed */
00797                     if (StreamHeader->Size != HeaderSize && !(StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED))
00798                     {
00799                         /* invalid stream header */
00800                         ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
00801                     }
00802                 }
00803                 else
00804                 {
00805                     /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */
00806                     if (StreamHeader->Size < sizeof(KSSTREAM_HEADER) || (StreamHeader->Size & 7))
00807                     {
00808                         /* invalid stream header */
00809                         ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
00810                     }
00811                 }
00812 
00813                 if (Length < StreamHeader->Size)
00814                 {
00815                     /* length is too short */
00816                     ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
00817                 }
00818 
00819                 if (ProbeFlags & KSPROBE_STREAMWRITE)
00820                 {
00821                     if (StreamHeader->DataUsed > StreamHeader->FrameExtent)
00822                     {
00823                         /* frame extend can never be smaller */
00824                         ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
00825                     }
00826 
00827                     /* is this stream change packet */
00828                     if (StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED)
00829                     {
00830                         if (Length != sizeof(KSSTREAM_HEADER) || (PVOID)StreamHeader != Irp->AssociatedIrp.SystemBuffer)
00831                         {
00832                             /* stream changed - must be send in a single packet */
00833                             ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
00834                         }
00835 
00836                         if (!(ProbeFlags & KSPROBE_ALLOWFORMATCHANGE))
00837                         {
00838                             /* caller does not permit format changes */
00839                             ExRaiseStatus(STATUS_INVALID_PARAMETER);
00840                         }
00841 
00842                         if (StreamHeader->FrameExtent)
00843                         {
00844                             /* allocate an mdl */
00845                             Mdl = IoAllocateMdl(StreamHeader->Data, StreamHeader->FrameExtent, FALSE, TRUE, Irp);
00846 
00847                             if (!Mdl)
00848                             {
00849                                 /* not enough memory */
00850                                 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
00851                             }
00852 
00853                             /* break-out to probe for the irp */
00854                             break;
00855                         }
00856                     }
00857                 }
00858                 else
00859                 {
00860                     if (StreamHeader->DataUsed)
00861                     {
00862                         /* DataUsed must be zero for stream read operation */
00863                         ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
00864                     }
00865 
00866                     if (StreamHeader->OptionsFlags)
00867                     {
00868                         /* no flags supported for reading */
00869                         ExRaiseStatus(STATUS_INVALID_PARAMETER);
00870                     }
00871                 }
00872 
00873                 if (StreamHeader->FrameExtent)
00874                 {
00875                     /* allocate an mdl */
00876                     ASSERT(Irp->MdlAddress == NULL);
00877                     Mdl = IoAllocateMdl(StreamHeader->Data, StreamHeader->FrameExtent, FALSE, TRUE, Irp);
00878                     if (!Mdl)
00879                     {
00880                         /* not enough memory */
00881                         ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
00882                     }
00883                 }
00884 
00885                 /* move to next stream header */
00886                 Length -= StreamHeader->Size;
00887                 StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size);
00888             }while(Length);
00889         }
00890         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00891         {
00892             /* Exception, get the error code */
00893             Status = _SEH2_GetExceptionCode();
00894         }_SEH2_END;
00895 
00896         /* now probe the allocated mdl's */
00897         if (!NT_SUCCESS(Status))
00898         {
00899             DPRINT("Status %x\n", Status);
00900             return Status;
00901         }
00902         else
00903             goto ProbeMdl;
00904     }
00905 
00906     /* probe user mode buffers */
00907     if (Length && ( (!HeaderSize) || (Length % HeaderSize == 0) || ((ProbeFlags & KSPROBE_ALLOWFORMATCHANGE) && (Length == sizeof(KSSTREAM_HEADER))) ) )
00908     {
00909         /* allocate stream header buffer */
00910         Irp->AssociatedIrp.SystemBuffer = AllocateItem(NonPagedPool, Length);
00911 
00912         if (!Irp->AssociatedIrp.SystemBuffer)
00913         {
00914             /* no memory */
00915             return STATUS_INSUFFICIENT_RESOURCES;
00916         }
00917 
00918         /* mark irp as buffered so that changes the stream headers are propagated back */
00919         Irp->Flags = IRP_DEALLOCATE_BUFFER | IRP_BUFFERED_IO;
00920 
00921         _SEH2_TRY
00922         {
00923             if (ProbeFlags & KSPROBE_STREAMWRITE)
00924             {
00925                 if (ProbeFlags & KSPROBE_MODIFY)
00926                     ProbeForWrite(Irp->UserBuffer, Length, sizeof(UCHAR));
00927                 else
00928                     ProbeForRead(Irp->UserBuffer, Length, sizeof(UCHAR));
00929             }
00930             else
00931             {
00932                 /* stream reads means writing */
00933                 ProbeForWrite(Irp->UserBuffer, Length, sizeof(UCHAR));
00934 
00935                 /* set input operation flags */
00936                 Irp->Flags |= IRP_INPUT_OPERATION;
00937             }
00938 
00939             /* copy stream buffer */
00940             RtlMoveMemory(Irp->AssociatedIrp.SystemBuffer, Irp->UserBuffer, Length);
00941         }
00942         _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
00943         {
00944             /* Exception, get the error code */
00945             Status = _SEH2_GetExceptionCode();
00946         }_SEH2_END;
00947 
00948         if (!NT_SUCCESS(Status))
00949         {
00950             /* failed */
00951             return Status;
00952         }
00953 
00954         if (ProbeFlags & KSPROBE_ALLOCATEMDL)
00955         {
00956             /* alloc mdls */
00957             goto AllocMdl;
00958         }
00959 
00960         /* check all stream headers */
00961         StreamHeader = (PKSSTREAM_HEADER)Irp->AssociatedIrp.SystemBuffer;
00962 
00963         _SEH2_TRY
00964         {
00965             do
00966             {
00967                 if (HeaderSize)
00968                 {
00969                     /* does the supplied header size match stream header size and no type changed */
00970                     if (StreamHeader->Size != HeaderSize && !(StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED))
00971                     {
00972                         /* invalid stream header */
00973                         ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
00974                     }
00975                 }
00976                 else
00977                 {
00978                     /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */
00979                     if (StreamHeader->Size < sizeof(KSSTREAM_HEADER) || (StreamHeader->Size & 7))
00980                     {
00981                         /* invalid stream header */
00982                         ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
00983                     }
00984                 }
00985 
00986                 if (Length < StreamHeader->Size)
00987                 {
00988                     /* length is too short */
00989                     ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
00990                 }
00991 
00992                 if (ProbeFlags & KSPROBE_STREAMWRITE)
00993                 {
00994                     if (StreamHeader->DataUsed > StreamHeader->FrameExtent)
00995                     {
00996                         /* frame extend can never be smaller */
00997                         ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
00998                     }
00999 
01000                     /* is this stream change packet */
01001                     if (StreamHeader->OptionsFlags & KSSTREAM_HEADER_OPTIONSF_TYPECHANGED)
01002                     {
01003                         if (Length != sizeof(KSSTREAM_HEADER) || (PVOID)StreamHeader != Irp->AssociatedIrp.SystemBuffer)
01004                         {
01005                             /* stream changed - must be send in a single packet */
01006                             ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
01007                         }
01008 
01009                         if (!(ProbeFlags & KSPROBE_ALLOWFORMATCHANGE))
01010                         {
01011                             /* caller does not permit format changes */
01012                             ExRaiseStatus(STATUS_INVALID_PARAMETER);
01013                         }
01014 
01015                         if (StreamHeader->FrameExtent)
01016                         {
01017                             /* allocate an mdl */
01018                             Mdl = IoAllocateMdl(StreamHeader->Data, StreamHeader->FrameExtent, FALSE, TRUE, Irp);
01019 
01020                             if (!Mdl)
01021                             {
01022                                 /* not enough memory */
01023                                 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES);
01024                             }
01025 
01026                             /* break out to probe for the irp */
01027                             //AllocateMdl = TRUE;
01028                             break;
01029                         }
01030                     }
01031                 }
01032                 else
01033                 {
01034                     if (StreamHeader->DataUsed)
01035                     {
01036                         /* DataUsed must be zero for stream read operation */
01037                         ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE);
01038                     }
01039 
01040                     if (StreamHeader->OptionsFlags)
01041                     {
01042                         /* no flags supported for reading */
01043                         ExRaiseStatus(STATUS_INVALID_PARAMETER);
01044                     }
01045                 }
01046 
01047                 /* move to next stream header */
01048                 Length -= StreamHeader->Size;
01049                 StreamHeader = (PKSSTREAM_HEADER)((ULONG_PTR)StreamHeader + StreamHeader->Size);
01050             }while(Length);
01051 
01052         }_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
01053         {
01054             /* Exception, get the error code */
01055             Status = _SEH2_GetExceptionCode();
01056         }_SEH2_END;
01057 
01058         /* now probe the allocated mdl's */
01059         if (NT_SUCCESS(Status))
01060             goto AllocMdl;
01061         else
01062             return Status;
01063     }
01064 
01065     return STATUS_INVALID_BUFFER_SIZE;
01066 }
01067 
01068 /*
01069     @implemented
01070 */
01071 KSDDKAPI
01072 NTSTATUS
01073 NTAPI
01074 KsAllocateExtraData(
01075     IN  PIRP Irp,
01076     IN  ULONG ExtraSize,
01077     OUT PVOID* ExtraBuffer)
01078 {
01079     PIO_STACK_LOCATION IoStack;
01080     ULONG Count, Index;
01081     PUCHAR Buffer, BufferOrg;
01082     PKSSTREAM_HEADER Header;
01083     NTSTATUS Status = STATUS_SUCCESS;
01084 
01085     /* get current irp stack */
01086     IoStack = IoGetCurrentIrpStackLocation(Irp);
01087 
01088     /* sanity check */
01089     ASSERT(IoStack->Parameters.DeviceIoControl.InputBufferLength >= sizeof(KSSTREAM_HEADER));
01090 
01091     /* get total length */
01092     Count = IoStack->Parameters.DeviceIoControl.InputBufferLength / sizeof(KSSTREAM_HEADER);
01093 
01094     /* allocate buffer */
01095     Buffer = BufferOrg = AllocateItem(NonPagedPool, Count * (sizeof(KSSTREAM_HEADER) + ExtraSize));
01096     if (!Buffer)
01097         return STATUS_INSUFFICIENT_RESOURCES;
01098 
01099     _SEH2_TRY
01100     {
01101         /* get input buffer */
01102         Header = (PKSSTREAM_HEADER)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
01103         for(Index = 0; Index < Count; Index++)
01104         {
01105             /* copy stream header */
01106             RtlMoveMemory(Buffer, Header, sizeof(KSSTREAM_HEADER));
01107 
01108             /* move to next header */
01109             Header++;
01110             /* increment output buffer offset */
01111             Buffer += sizeof(KSSTREAM_HEADER) + ExtraSize;
01112         }
01113     }
01114     _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
01115     {
01116         /* Exception, get the error code */
01117         Status = _SEH2_GetExceptionCode();
01118     }
01119     _SEH2_END;
01120 
01121     if (!NT_SUCCESS(Status))
01122     {
01123         /* free buffer on exception */
01124         FreeItem(Buffer);
01125         return Status;
01126     }
01127 
01128     /* store result */
01129     *ExtraBuffer = BufferOrg;
01130 
01131     /* done */
01132     return STATUS_SUCCESS;
01133 }
01134 
01135 /*
01136     @implemented
01137 */
01138 KSDDKAPI
01139 VOID
01140 NTAPI
01141 KsNullDriverUnload(
01142     IN  PDRIVER_OBJECT DriverObject)
01143 {
01144 }
01145 
01146 /*
01147     @implemented
01148 */
01149 KSDDKAPI
01150 NTSTATUS
01151 NTAPI
01152 KsDispatchInvalidDeviceRequest(
01153     IN  PDEVICE_OBJECT DeviceObject,
01154     IN  PIRP Irp)
01155 {
01156     Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
01157     CompleteRequest(Irp, IO_NO_INCREMENT);
01158 
01159     return STATUS_INVALID_DEVICE_REQUEST;
01160 }
01161 
01162 /*
01163     @implemented
01164 */
01165 KSDDKAPI
01166 NTSTATUS
01167 NTAPI
01168 KsDefaultDeviceIoCompletion(
01169     IN  PDEVICE_OBJECT DeviceObject,
01170     IN  PIRP Irp)
01171 {
01172     PIO_STACK_LOCATION IoStack;
01173     NTSTATUS Status;
01174 
01175     /* get current irp stack */
01176     IoStack = IoGetCurrentIrpStackLocation(Irp);
01177 
01178     if (IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY && 
01179         IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_METHOD &&
01180         IoStack->Parameters.DeviceIoControl.IoControlCode != IOCTL_KS_PROPERTY)
01181     {
01182         if (IoStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_KS_RESET_STATE)
01183         {
01184             /* fake success */
01185             Status = STATUS_SUCCESS;
01186         }
01187         else
01188         {
01189             /* request unsupported */
01190             Status = STATUS_INVALID_DEVICE_REQUEST;
01191         }
01192     }
01193     else
01194     {
01195         /* property / method / event not found */
01196         Status = STATUS_PROPSET_NOT_FOUND;
01197     }
01198 
01199     /* complete request */
01200     Irp->IoStatus.Status = Status;
01201     CompleteRequest(Irp, IO_NO_INCREMENT);
01202 
01203 
01204     return Status;
01205 }
01206 
01207 /*
01208     @implemented
01209 */
01210 KSDDKAPI
01211 BOOLEAN
01212 NTAPI
01213 KsDispatchFastIoDeviceControlFailure(
01214     IN  PFILE_OBJECT FileObject,
01215     IN  BOOLEAN Wait,
01216     IN  PVOID InputBuffer  OPTIONAL,
01217     IN  ULONG InputBufferLength,
01218     OUT PVOID OutputBuffer  OPTIONAL,
01219     IN  ULONG OutputBufferLength,
01220     IN  ULONG IoControlCode,
01221     OUT PIO_STATUS_BLOCK IoStatus,
01222     IN  PDEVICE_OBJECT DeviceObject)
01223 {
01224     return FALSE;
01225 }
01226 
01227 /*
01228     @implemented
01229 */
01230 KSDDKAPI
01231 BOOLEAN
01232 NTAPI
01233 KsDispatchFastReadFailure(
01234     IN  PFILE_OBJECT FileObject,
01235     IN  PLARGE_INTEGER FileOffset,
01236     IN  ULONG Length,
01237     IN  BOOLEAN Wait,
01238     IN  ULONG LockKey,
01239     OUT PVOID Buffer,
01240     OUT PIO_STATUS_BLOCK IoStatus,
01241     IN  PDEVICE_OBJECT DeviceObject)
01242 {
01243     return FALSE;
01244 }
01245 
01246 
01247 /*
01248     @implemented
01249 */
01250 KSDDKAPI
01251 VOID
01252 NTAPI
01253 KsCancelIo(
01254     IN  OUT PLIST_ENTRY QueueHead,
01255     IN  PKSPIN_LOCK SpinLock)
01256 {
01257     PDRIVER_CANCEL OldDriverCancel;
01258     PIO_STACK_LOCATION IoStack;
01259     PLIST_ENTRY Entry;
01260     PLIST_ENTRY NextEntry;
01261     PIRP Irp;
01262     KIRQL OldLevel;
01263 
01264     /* acquire spinlock */
01265     KeAcquireSpinLock(SpinLock, &OldLevel);
01266     /* point to first entry */
01267     Entry = QueueHead->Flink;
01268     /* loop all items */
01269     while(Entry != QueueHead)
01270     {
01271         /* get irp offset */
01272         Irp = (PIRP)CONTAINING_RECORD(Entry, IRP, Tail.Overlay.ListEntry);
01273 
01274         /* get next entry */
01275         NextEntry = Entry->Flink;
01276 
01277         /* set cancelled bit */
01278         Irp->Cancel = TRUE;
01279 
01280         /* now set the cancel routine */
01281         OldDriverCancel = IoSetCancelRoutine(Irp, NULL);
01282         if (OldDriverCancel)
01283         {
01284             /* this irp hasnt been yet used, so free to cancel */
01285             KeReleaseSpinLock(SpinLock, OldLevel);
01286 
01287             /* get current irp stack */
01288             IoStack = IoGetCurrentIrpStackLocation(Irp);
01289 
01290             /* acquire cancel spinlock */
01291             IoAcquireCancelSpinLock(&Irp->CancelIrql);
01292 
01293             /* call provided cancel routine */
01294             OldDriverCancel(IoStack->DeviceObject, Irp);
01295 
01296             /* re-acquire spinlock */
01297             KeAcquireSpinLock(SpinLock, &OldLevel);
01298         }
01299 
01300         /* move on to next entry */
01301         Entry = NextEntry;
01302     }
01303 
01304     /* the irp has already been canceled */
01305     KeReleaseSpinLock(SpinLock, OldLevel);
01306 
01307 }
01308 
01309 /*
01310     @implemented
01311 */
01312 KSDDKAPI
01313 VOID
01314 NTAPI
01315 KsReleaseIrpOnCancelableQueue(
01316     IN  PIRP Irp,
01317     IN  PDRIVER_CANCEL DriverCancel OPTIONAL)
01318 {
01319     PKSPIN_LOCK SpinLock;
01320     PDRIVER_CANCEL OldDriverCancel;
01321     PIO_STACK_LOCATION IoStack;
01322     KIRQL OldLevel;
01323 
01324     /* check for required parameters */
01325     if (!Irp)
01326         return;
01327 
01328     if (!DriverCancel)
01329     {
01330         /* default to KsCancelRoutine */
01331         DriverCancel = KsCancelRoutine;
01332     }
01333 
01334     /* get current irp stack */
01335     IoStack = IoGetCurrentIrpStackLocation(Irp);
01336 
01337     /* get internal queue lock */
01338     SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp);
01339 
01340     /* acquire spinlock */
01341     KeAcquireSpinLock(SpinLock, &OldLevel);
01342 
01343     /* now set the cancel routine */
01344     OldDriverCancel = IoSetCancelRoutine(Irp, DriverCancel);
01345 
01346     if (Irp->Cancel && OldDriverCancel == NULL)
01347     {
01348         /* the irp has already been canceled */
01349         KeReleaseSpinLock(SpinLock, OldLevel);
01350 
01351         /* cancel routine requires that cancel spinlock is held */
01352         IoAcquireCancelSpinLock(&Irp->CancelIrql);
01353 
01354         /* cancel irp */
01355         DriverCancel(IoStack->DeviceObject, Irp);
01356     }
01357     else
01358     {
01359         /* done */
01360         KeReleaseSpinLock(SpinLock, OldLevel);
01361     }
01362 }
01363 
01364 /*
01365     @implemented
01366 */
01367 KSDDKAPI
01368 PIRP
01369 NTAPI
01370 KsRemoveIrpFromCancelableQueue(
01371     IN  OUT PLIST_ENTRY QueueHead,
01372     IN  PKSPIN_LOCK SpinLock,
01373     IN  KSLIST_ENTRY_LOCATION ListLocation,
01374     IN  KSIRP_REMOVAL_OPERATION RemovalOperation)
01375 {
01376     PIRP Irp;
01377     PLIST_ENTRY CurEntry;
01378     KIRQL OldIrql;
01379 
01380     DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead, SpinLock, ListLocation, RemovalOperation);
01381 
01382     /* check parameters */
01383     if (!QueueHead || !SpinLock)
01384         return NULL;
01385 
01386     /* check if parameter ListLocation is valid */
01387     if (ListLocation != KsListEntryTail && ListLocation != KsListEntryHead)
01388         return NULL;
01389 
01390     /* acquire list lock */
01391     KeAcquireSpinLock(SpinLock, &OldIrql);
01392 
01393     /* point to queue head */
01394     CurEntry = QueueHead;
01395 
01396     do
01397     {
01398         /* reset irp to null */
01399         Irp = NULL;
01400 
01401         /* iterate to next entry */
01402         if (ListLocation == KsListEntryHead)
01403             CurEntry = CurEntry->Flink;
01404         else
01405             CurEntry = CurEntry->Blink;
01406 
01407         /* is the end of list reached */
01408         if (CurEntry == QueueHead)
01409         {
01410             /* reached end of list */
01411             break;
01412         }
01413 
01414         /* get irp offset */
01415         Irp = (PIRP)CONTAINING_RECORD(CurEntry, IRP, Tail.Overlay.ListEntry);
01416 
01417         if (Irp->Cancel)
01418         {
01419             /* irp has been canceled */
01420             break;
01421         }
01422 
01423         if (Irp->CancelRoutine)
01424         {
01425             /* remove cancel routine */
01426             Irp->CancelRoutine = NULL;
01427 
01428             if (RemovalOperation == KsAcquireAndRemove || RemovalOperation == KsAcquireAndRemoveOnlySingleItem)
01429             {
01430                 /* remove irp from list */
01431                 RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
01432             }
01433 
01434             if (RemovalOperation == KsAcquireAndRemoveOnlySingleItem || RemovalOperation == KsAcquireOnlySingleItem)
01435                 break;
01436         }
01437 
01438     }while(TRUE);
01439 
01440     /* release lock */
01441     KeReleaseSpinLock(SpinLock, OldIrql);
01442 
01443     if (!Irp || Irp->CancelRoutine == NULL)
01444     {
01445         /* either an irp has been acquired or nothing found */
01446         return Irp;
01447     }
01448 
01449     /* time to remove the canceled irp */
01450     IoAcquireCancelSpinLock(&OldIrql);
01451     /* acquire list lock */
01452     KeAcquireSpinLockAtDpcLevel(SpinLock);
01453 
01454     if (RemovalOperation == KsAcquireAndRemove || RemovalOperation == KsAcquireAndRemoveOnlySingleItem)
01455     {
01456         /* remove it */
01457         RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
01458     }
01459 
01460     /* release list lock */
01461     KeReleaseSpinLockFromDpcLevel(SpinLock);
01462 
01463     /* release cancel spinlock */
01464     IoReleaseCancelSpinLock(OldIrql);
01465     /* no non canceled irp has been found */
01466     return NULL;
01467 }
01468 
01469 /*
01470     @implemented
01471 */
01472 KSDDKAPI
01473 NTSTATUS
01474 NTAPI
01475 KsMoveIrpsOnCancelableQueue(
01476     IN  OUT PLIST_ENTRY SourceList,
01477     IN  PKSPIN_LOCK SourceLock,
01478     IN  OUT PLIST_ENTRY DestinationList,
01479     IN  PKSPIN_LOCK DestinationLock OPTIONAL,
01480     IN  KSLIST_ENTRY_LOCATION ListLocation,
01481     IN  PFNKSIRPLISTCALLBACK ListCallback,
01482     IN  PVOID Context)
01483 {
01484     KIRQL OldLevel;
01485     PLIST_ENTRY SrcEntry;
01486     PIRP Irp;
01487     NTSTATUS Status = STATUS_SUCCESS;
01488 
01489     if (!DestinationLock)
01490     {
01491         /* no destination lock just acquire the source lock */
01492         KeAcquireSpinLock(SourceLock, &OldLevel);
01493     }
01494     else
01495     {
01496         /* acquire cancel spinlock */
01497         IoAcquireCancelSpinLock(&OldLevel);
01498 
01499         /* now acquire source lock */
01500         KeAcquireSpinLockAtDpcLevel(SourceLock);
01501 
01502         /* now acquire destination lock */
01503         KeAcquireSpinLockAtDpcLevel(DestinationLock);
01504     }
01505 
01506     /* point to list head */
01507     SrcEntry = SourceList;
01508 
01509     /* now move all irps */
01510     while(TRUE)
01511     {
01512         if (ListLocation == KsListEntryTail)
01513         {
01514             /* move queue downwards */
01515             SrcEntry = SrcEntry->Flink;
01516         }
01517         else
01518         {
01519             /* move queue upwards */
01520             SrcEntry = SrcEntry->Blink;
01521         }
01522 
01523         if (SrcEntry == SourceList)
01524         {
01525             /* eof list reached */
01526             break;
01527         }
01528 
01529         /* get irp offset */
01530         Irp = (PIRP)CONTAINING_RECORD(SrcEntry, IRP, Tail.Overlay.ListEntry);
01531 
01532         /* now check if irp can be moved */
01533         Status = ListCallback(Irp, Context);
01534 
01535         /* check if irp can be moved */
01536         if (Status == STATUS_SUCCESS)
01537         {
01538             /* remove irp from src list */
01539             RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
01540 
01541             if (ListLocation == KsListEntryTail)
01542             {
01543                 /* insert irp end of list */
01544                 InsertTailList(DestinationList, &Irp->Tail.Overlay.ListEntry);
01545             }
01546             else
01547             {
01548                 /* insert irp head of list */
01549                 InsertHeadList(DestinationList, &Irp->Tail.Overlay.ListEntry);
01550             }
01551 
01552             /* do we need to update the irp lock */
01553             if (DestinationLock)
01554             {
01555                 /* update irp lock */
01556                 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) = DestinationLock;
01557             }
01558         }
01559         else
01560         {
01561             if (Status != STATUS_NO_MATCH)
01562             {
01563                 /* callback decided to stop enumeration */
01564                 break;
01565             }
01566 
01567             /* reset return value */
01568             Status = STATUS_SUCCESS;
01569         }
01570     }
01571 
01572     if (!DestinationLock)
01573     {
01574         /* release source lock */
01575         KeReleaseSpinLock(SourceLock, OldLevel);
01576     }
01577     else
01578     {
01579         /* now release destination lock */
01580         KeReleaseSpinLockFromDpcLevel(DestinationLock);
01581 
01582         /* now release source lock */
01583         KeReleaseSpinLockFromDpcLevel(SourceLock);
01584 
01585 
01586         /* now release cancel spinlock */
01587         IoReleaseCancelSpinLock(OldLevel);
01588     }
01589 
01590     /* done */
01591     return Status;
01592 }
01593 
01594 /*
01595     @implemented
01596 */
01597 KSDDKAPI
01598 VOID
01599 NTAPI
01600 KsRemoveSpecificIrpFromCancelableQueue(
01601     IN  PIRP Irp)
01602 {
01603     PKSPIN_LOCK SpinLock;
01604     KIRQL OldLevel;
01605 
01606     DPRINT("KsRemoveSpecificIrpFromCancelableQueue %p\n", Irp);
01607 
01608     /* get internal queue lock */
01609     SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp);
01610 
01611     /* acquire spinlock */
01612     KeAcquireSpinLock(SpinLock, &OldLevel);
01613 
01614     /* remove the irp from the list */
01615     RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
01616 
01617     /* release spinlock */
01618     KeReleaseSpinLock(SpinLock, OldLevel);
01619 }
01620 
01621 
01622 /*
01623     @implemented
01624 */
01625 KSDDKAPI
01626 VOID
01627 NTAPI
01628 KsAddIrpToCancelableQueue(
01629     IN  OUT PLIST_ENTRY QueueHead,
01630     IN  PKSPIN_LOCK SpinLock,
01631     IN  PIRP Irp,
01632     IN  KSLIST_ENTRY_LOCATION ListLocation,
01633     IN  PDRIVER_CANCEL DriverCancel OPTIONAL)
01634 {
01635     PDRIVER_CANCEL OldDriverCancel;
01636     PIO_STACK_LOCATION IoStack;
01637     KIRQL OldLevel;
01638 
01639     /* check for required parameters */
01640     if (!QueueHead || !SpinLock || !Irp)
01641         return;
01642 
01643     /* get current irp stack */
01644     IoStack = IoGetCurrentIrpStackLocation(Irp);
01645 
01646     DPRINT("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead, SpinLock, Irp, ListLocation, DriverCancel);
01647 
01648     // HACK for ms portcls
01649     if (IoStack->MajorFunction == IRP_MJ_CREATE)
01650     {
01651         // complete the request
01652         DPRINT1("MS HACK\n");
01653         Irp->IoStatus.Status = STATUS_SUCCESS;
01654         CompleteRequest(Irp, IO_NO_INCREMENT);
01655 
01656         return;
01657     }
01658 
01659 
01660     if (!DriverCancel)
01661     {
01662         /* default to KsCancelRoutine */
01663         DriverCancel = KsCancelRoutine;
01664     }
01665 
01666 
01667     /* acquire spinlock */
01668     KeAcquireSpinLock(SpinLock, &OldLevel);
01669 
01670     if (ListLocation == KsListEntryTail)
01671     {
01672         /* insert irp to tail of list */
01673         InsertTailList(QueueHead, &Irp->Tail.Overlay.ListEntry);
01674     }
01675     else
01676     {
01677         /* insert irp to head of list */
01678         InsertHeadList(QueueHead, &Irp->Tail.Overlay.ListEntry);
01679     }
01680 
01681     /* store internal queue lock */
01682     KSQUEUE_SPINLOCK_IRP_STORAGE(Irp) = SpinLock;
01683 
01684     /* now set the cancel routine */
01685     OldDriverCancel = IoSetCancelRoutine(Irp, DriverCancel);
01686 
01687     if (Irp->Cancel && OldDriverCancel == NULL)
01688     {
01689         /* the irp has already been canceled */
01690         KeReleaseSpinLock(SpinLock, OldLevel);
01691 
01692         /* cancel routine requires that cancel spinlock is held */
01693         IoAcquireCancelSpinLock(&Irp->CancelIrql);
01694 
01695         /* cancel irp */
01696         DriverCancel(IoStack->DeviceObject, Irp);
01697     }
01698     else
01699     {
01700         /* done */
01701         KeReleaseSpinLock(SpinLock, OldLevel);
01702     }
01703 }
01704 
01705 /*
01706     @implemented
01707 */
01708 KSDDKAPI
01709 VOID
01710 NTAPI
01711 KsCancelRoutine(
01712     IN  PDEVICE_OBJECT DeviceObject,
01713     IN  PIRP Irp)
01714 {
01715     PKSPIN_LOCK SpinLock;
01716 
01717     /* get internal queue lock */
01718     SpinLock = KSQUEUE_SPINLOCK_IRP_STORAGE(Irp);
01719 
01720     /* acquire spinlock */
01721     KeAcquireSpinLockAtDpcLevel(SpinLock);
01722 
01723     /* sanity check */
01724     ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
01725 
01726     /* release cancel spinlock */
01727     IoReleaseCancelSpinLock(Irp->CancelIrql);
01728 
01729     /* remove the irp from the list */
01730     RemoveEntryList(&Irp->Tail.Overlay.ListEntry);
01731 
01732     /* release spinlock */
01733     KeReleaseSpinLock(SpinLock, Irp->CancelIrql);
01734 
01735     /* has the irp already been canceled */
01736     if (Irp->IoStatus.Status != STATUS_CANCELLED)
01737     {
01738         /* let's complete it */
01739         Irp->IoStatus.Status = STATUS_CANCELLED;
01740         CompleteRequest(Irp, IO_NO_INCREMENT);
01741     }
01742 }
01743 
01744 NTSTATUS
01745 FindMatchingCreateItem(
01746     PLIST_ENTRY ListHead,
01747     ULONG BufferSize,
01748     LPWSTR Buffer,
01749     OUT PCREATE_ITEM_ENTRY *OutCreateItem)
01750 {
01751     PLIST_ENTRY Entry;
01752     PCREATE_ITEM_ENTRY CreateItemEntry;
01753     UNICODE_STRING RefString;
01754     LPWSTR pStr;
01755 
01756     /* get terminator */
01757     pStr = wcschr(Buffer, L'\\');
01758 
01759     /* sanity check */
01760     ASSERT(pStr != NULL);
01761 
01762     if (pStr == Buffer)
01763     {
01764         // skip slash
01765         RtlInitUnicodeString(&RefString, ++pStr);
01766     }
01767     else
01768     {
01769         // request is for pin / node / allocator
01770         RefString.Buffer = Buffer;
01771         RefString.Length = BufferSize = RefString.MaximumLength = ((ULONG_PTR)pStr - (ULONG_PTR)Buffer);
01772     }
01773 
01774     /* point to first entry */
01775     Entry = ListHead->Flink;
01776 
01777     /* loop all device items */
01778     while(Entry != ListHead)
01779     {
01780         /* get create item entry */
01781         CreateItemEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry);
01782 
01783         ASSERT(CreateItemEntry->CreateItem);
01784 
01785         if(CreateItemEntry->CreateItem->Flags & KSCREATE_ITEM_WILDCARD)
01786         {
01787             /* create item is default */
01788             *OutCreateItem = CreateItemEntry;
01789             return STATUS_SUCCESS;
01790         }
01791 
01792         if (!CreateItemEntry->CreateItem->Create)
01793         {
01794             /* skip free create item */
01795             Entry = Entry->Flink;
01796             continue;
01797         }
01798 
01799         DPRINT("CreateItem %S Length %u Request %wZ %u\n", CreateItemEntry->CreateItem->ObjectClass.Buffer,
01800                                                            CreateItemEntry->CreateItem->ObjectClass.Length,
01801                                                            &RefString,
01802                                                            RefString.Length);
01803 
01804         if (CreateItemEntry->CreateItem->ObjectClass.Length > RefString.Length)
01805         {
01806             /* create item doesnt match in length */
01807             Entry = Entry->Flink;
01808             continue;
01809         }
01810 
01811          /* now check if the object class is the same */
01812         if (!RtlCompareUnicodeString(&CreateItemEntry->CreateItem->ObjectClass, &RefString, TRUE))
01813         {
01814             /* found matching create item */
01815             *OutCreateItem = CreateItemEntry;
01816             return STATUS_SUCCESS;
01817         }
01818         /* iterate to next */
01819         Entry = Entry->Flink;
01820     }
01821 
01822     return STATUS_NOT_FOUND;
01823 }
01824 
01825 NTSTATUS
01826 NTAPI
01827 KspCreate(
01828     IN  PDEVICE_OBJECT DeviceObject,
01829     IN  PIRP Irp)
01830 {
01831     PCREATE_ITEM_ENTRY CreateItemEntry;
01832     PIO_STACK_LOCATION IoStack;
01833     PDEVICE_EXTENSION DeviceExtension;
01834     PKSIDEVICE_HEADER DeviceHeader;
01835     PKSIOBJECT_HEADER ObjectHeader;
01836     NTSTATUS Status;
01837 
01838     DPRINT("KS / CREATE\n");
01839 
01840     /* get current stack location */
01841     IoStack = IoGetCurrentIrpStackLocation(Irp);
01842     /* get device extension */
01843     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
01844     /* get device header */
01845     DeviceHeader = DeviceExtension->DeviceHeader;
01846 
01847 
01848     if (IoStack->FileObject->FileName.Buffer == NULL)
01849     {
01850         /* FIXME Pnp-Issue */
01851         DPRINT("Using reference string hack\n");
01852         Irp->IoStatus.Information = 0;
01853         /* set return status */
01854         Irp->IoStatus.Status = STATUS_SUCCESS;
01855         CompleteRequest(Irp, IO_NO_INCREMENT);
01856         return STATUS_SUCCESS;
01857     }
01858 
01859     if (IoStack->FileObject->RelatedFileObject != NULL)
01860     {
01861         /* request is to instantiate a pin / node / clock / allocator */
01862         ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->RelatedFileObject->FsContext2;
01863 
01864         /* sanity check */
01865         ASSERT(ObjectHeader);
01866 
01867         /* find a matching a create item */
01868         Status = FindMatchingCreateItem(&ObjectHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
01869     }
01870     else
01871     {
01872         /* request to create a filter */
01873         Status = FindMatchingCreateItem(&DeviceHeader->ItemList, IoStack->FileObject->FileName.Length, IoStack->FileObject->FileName.Buffer, &CreateItemEntry);
01874     }
01875 
01876     if (NT_SUCCESS(Status))
01877     {
01878         /* set object create item */
01879         KSCREATE_ITEM_IRP_STORAGE(Irp) = CreateItemEntry->CreateItem;
01880 
01881         /* call create function */
01882         Status = CreateItemEntry->CreateItem->Create(DeviceObject, Irp);
01883 
01884         if (NT_SUCCESS(Status))
01885         {
01886             /* increment create item reference count */
01887             InterlockedIncrement(&CreateItemEntry->ReferenceCount);
01888         }
01889         return Status;
01890     }
01891 
01892     Irp->IoStatus.Information = 0;
01893     /* set return status */
01894     Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
01895     CompleteRequest(Irp, IO_NO_INCREMENT);
01896     return STATUS_UNSUCCESSFUL;
01897 }
01898 
01899 NTSTATUS
01900 NTAPI
01901 KspDispatchIrp(
01902     IN  PDEVICE_OBJECT DeviceObject,
01903     IN  PIRP Irp)
01904 {
01905     PIO_STACK_LOCATION IoStack;
01906     //PDEVICE_EXTENSION DeviceExtension;
01907     PKSIOBJECT_HEADER ObjectHeader;
01908     //PKSIDEVICE_HEADER DeviceHeader;
01909     PDRIVER_DISPATCH Dispatch;
01910     NTSTATUS Status;
01911 
01912     /* get current stack location */
01913     IoStack = IoGetCurrentIrpStackLocation(Irp);
01914 
01915     /* get device extension */
01916     //DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
01917     /* get device header */
01918     //DeviceHeader = DeviceExtension->DeviceHeader;
01919 
01920     ASSERT(IoStack->FileObject);
01921 
01922     /* get object header */
01923     ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext2;
01924 
01925     if (!ObjectHeader)
01926     {
01927         /* FIXME Pnp-Issue*/
01928         Irp->IoStatus.Status = STATUS_SUCCESS;
01929         Irp->IoStatus.Information = 0;
01930         /* complete and forget */
01931         CompleteRequest(Irp, IO_NO_INCREMENT);
01932         return STATUS_SUCCESS;
01933     }
01934 
01935     /* sanity check */
01936     ASSERT(ObjectHeader);
01937     /* store create item */
01938     //KSCREATE_ITEM_IRP_STORAGE(Irp) = (PKSOBJECT_CREATE_ITEM)0x12345678; //ObjectHeader->CreateItem;
01939 
01940     /* retrieve matching dispatch function */
01941     switch(IoStack->MajorFunction)
01942     {
01943         case IRP_MJ_CLOSE:
01944             Dispatch = ObjectHeader->DispatchTable.Close;
01945             break;
01946         case IRP_MJ_DEVICE_CONTROL:
01947             Dispatch = ObjectHeader->DispatchTable.DeviceIoControl;
01948             break;
01949         case IRP_MJ_READ:
01950             Dispatch = ObjectHeader->DispatchTable.Read;
01951             break;
01952         case IRP_MJ_WRITE:
01953             Dispatch = ObjectHeader->DispatchTable.Write;
01954             break;
01955         case IRP_MJ_FLUSH_BUFFERS :
01956             Dispatch = ObjectHeader->DispatchTable.Flush;
01957             break;
01958         case IRP_MJ_QUERY_SECURITY:
01959             Dispatch = ObjectHeader->DispatchTable.QuerySecurity;
01960             break;
01961         case IRP_MJ_SET_SECURITY:
01962             Dispatch = ObjectHeader->DispatchTable.SetSecurity;
01963             break;
01964         case IRP_MJ_PNP:
01965             Dispatch = KsDefaultDispatchPnp;
01966             break;
01967         default:
01968             Dispatch = NULL;
01969     }
01970 
01971     /* is the request supported */
01972     if (Dispatch)
01973     {
01974         /* now call the dispatch function */
01975         Status = Dispatch(DeviceObject, Irp);
01976     }
01977     else
01978     {
01979         /* not supported request */
01980         Status = KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
01981     }
01982 
01983     /* done */
01984     return Status;
01985 }
01986 
01987 /*
01988     @implemented
01989 */
01990 KSDDKAPI
01991 NTSTATUS
01992 NTAPI
01993 KsSetMajorFunctionHandler(
01994     IN  PDRIVER_OBJECT DriverObject,
01995     IN  ULONG MajorFunction)
01996 {
01997     DPRINT("KsSetMajorFunctionHandler Function %x\n", MajorFunction);
01998 
01999     switch ( MajorFunction )
02000     {
02001         case IRP_MJ_CREATE:
02002             DriverObject->MajorFunction[MajorFunction] = KspCreate;
02003             break;
02004         case IRP_MJ_DEVICE_CONTROL:
02005         case IRP_MJ_CLOSE:
02006         case IRP_MJ_READ:
02007         case IRP_MJ_WRITE:
02008         case IRP_MJ_FLUSH_BUFFERS :
02009         case IRP_MJ_QUERY_SECURITY:
02010         case IRP_MJ_SET_SECURITY:
02011             DriverObject->MajorFunction[MajorFunction] = KspDispatchIrp;
02012             break;
02013         default:
02014             DPRINT1("NotSupported %x\n", MajorFunction);
02015             return STATUS_INVALID_PARAMETER;
02016     };
02017 
02018     return STATUS_SUCCESS;
02019 }
02020 
02021 /*
02022     @implemented
02023 */
02024 KSDDKAPI
02025 NTSTATUS
02026 NTAPI
02027 KsDispatchIrp(
02028     IN  PDEVICE_OBJECT DeviceObject,
02029     IN  PIRP Irp)
02030 {
02031     PIO_STACK_LOCATION IoStack;
02032     PKSIDEVICE_HEADER DeviceHeader;
02033     PDEVICE_EXTENSION DeviceExtension;
02034 
02035     DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject, Irp);
02036 
02037     /* get device extension */
02038     DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
02039 
02040     /* get device header */
02041     DeviceHeader = DeviceExtension->DeviceHeader;
02042 
02043 
02044     /* get current irp stack */
02045     IoStack = IoGetCurrentIrpStackLocation(Irp);
02046 
02047     if (IoStack->MajorFunction <= IRP_MJ_DEVICE_CONTROL)
02048     {
02049         if (IoStack->MajorFunction == IRP_MJ_CREATE)
02050         {
02051             /* check internal type */
02052             if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
02053             {
02054                 /* AVStream client */
02055                 return IKsDevice_Create(DeviceObject, Irp);
02056             }
02057             else
02058             {
02059                 /* external client (portcls) */
02060                 return KspCreate(DeviceObject, Irp);
02061             }
02062         }
02063 
02064         switch (IoStack->MajorFunction)
02065         {
02066             case IRP_MJ_CLOSE:
02067             case IRP_MJ_READ:
02068             case IRP_MJ_WRITE:
02069             case IRP_MJ_FLUSH_BUFFERS:
02070             case IRP_MJ_QUERY_SECURITY:
02071             case IRP_MJ_SET_SECURITY:
02072             case IRP_MJ_PNP:
02073             case IRP_MJ_DEVICE_CONTROL:
02074                 return KspDispatchIrp(DeviceObject, Irp);
02075             default:
02076                 return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
02077         }
02078     }
02079 
02080     /* dispatch power */
02081     if (IoStack->MajorFunction == IRP_MJ_POWER)
02082     {
02083         /* check internal type */
02084         if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
02085         {
02086             /* AVStream client */
02087             return IKsDevice_Power(DeviceObject, Irp);
02088         }
02089         else
02090         {
02091             /* external client (portcls) */
02092             return KsDefaultDispatchPower(DeviceObject, Irp);
02093         }
02094     }
02095     else if (IoStack->MajorFunction == IRP_MJ_PNP) /* dispatch pnp */
02096     {
02097         /* check internal type */
02098         if (DeviceHeader->BasicHeader.OuterUnknown) /* FIXME improve check */
02099         {
02100             /* AVStream client */
02101             return IKsDevice_Pnp(DeviceObject, Irp);
02102         }
02103         else
02104         {
02105             /* external client (portcls) */
02106             return KsDefaultDispatchPnp(DeviceObject, Irp);
02107         }
02108     }
02109     else if (IoStack->MajorFunction == IRP_MJ_SYSTEM_CONTROL)
02110     {
02111         /* forward irp */
02112         return KsDefaultForwardIrp(DeviceObject, Irp);
02113     }
02114     else
02115     {
02116         /* not supported */
02117         return KsDispatchInvalidDeviceRequest(DeviceObject, Irp);
02118     }
02119 }
02120 
02121 /*
02122     @unimplemented
02123 */
02124 KSDDKAPI
02125 ULONG
02126 NTAPI
02127 KsGetNodeIdFromIrp(
02128     IN PIRP Irp)
02129 {
02130     UNIMPLEMENTED
02131     return KSFILTER_NODE;
02132 }
02133 

Generated on Sat May 26 2012 04:26: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.