2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/factory.c
5 * PURPOSE: KS Allocator functions
6 * PROGRAMMER: Johannes Anderwald
18 KsDispatchQuerySecurity(
19 IN PDEVICE_OBJECT DeviceObject
,
22 PKSOBJECT_CREATE_ITEM CreateItem
;
23 PIO_STACK_LOCATION IoStack
;
27 /* get current irp stack */
28 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
31 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
33 if (!CreateItem
|| !CreateItem
->SecurityDescriptor
)
36 Irp
->IoStatus
.Status
= STATUS_NO_SECURITY_ON_OBJECT
;
37 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
38 return STATUS_NO_SECURITY_ON_OBJECT
;
42 /* get input length */
43 Length
= IoStack
->Parameters
.QuerySecurity
.Length
;
45 /* clone the security descriptor */
46 Status
= SeQuerySecurityDescriptorInfo(&IoStack
->Parameters
.QuerySecurity
.SecurityInformation
, (PSECURITY_DESCRIPTOR
)Irp
->UserBuffer
, &Length
, &CreateItem
->SecurityDescriptor
);
48 DPRINT("SeQuerySecurityDescriptorInfo Status %x\n", Status
);
50 Irp
->IoStatus
.Status
= Status
;
51 Irp
->IoStatus
.Information
= Length
;
53 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
63 KsDispatchSetSecurity(
64 IN PDEVICE_OBJECT DeviceObject
,
67 PKSOBJECT_CREATE_ITEM CreateItem
;
68 PIO_STACK_LOCATION IoStack
;
69 PGENERIC_MAPPING Mapping
;
70 PSECURITY_DESCRIPTOR Descriptor
;
73 /* get current irp stack */
74 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
77 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
79 if (!CreateItem
|| !CreateItem
->SecurityDescriptor
)
82 Irp
->IoStatus
.Status
= STATUS_NO_SECURITY_ON_OBJECT
;
83 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
84 return STATUS_NO_SECURITY_ON_OBJECT
;
87 /* backup old descriptor */
88 Descriptor
= CreateItem
->SecurityDescriptor
;
90 /* get generic mapping */
91 Mapping
= IoGetFileObjectGenericMapping();
93 /* change security descriptor */
94 Status
= SeSetSecurityDescriptorInfo(NULL
, /*FIXME */
95 &IoStack
->Parameters
.SetSecurity
.SecurityInformation
,
96 IoStack
->Parameters
.SetSecurity
.SecurityDescriptor
,
97 &CreateItem
->SecurityDescriptor
,
101 if (NT_SUCCESS(Status
))
103 /* free old descriptor */
104 ExFreePool(Descriptor
);
106 /* mark create item as changed */
107 CreateItem
->Flags
|= KSCREATE_ITEM_SECURITYCHANGED
;
111 Irp
->IoStatus
.Status
= Status
;
112 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
123 KsDispatchSpecificProperty(
125 IN PFNKSHANDLER Handler
)
128 return STATUS_UNSUCCESSFUL
;
137 KsDispatchSpecificMethod(
139 IN PFNKSHANDLER Handler
)
142 return STATUS_UNSUCCESSFUL
;
153 IN PFILE_OBJECT FileObject
,
154 IN PKEVENT Event OPTIONAL
,
155 IN PVOID PortContext OPTIONAL
,
156 OUT PIO_STATUS_BLOCK IoStatusBlock
,
159 IN ULONG Key OPTIONAL
,
160 IN KPROCESSOR_MODE RequestorMode
)
162 PDEVICE_OBJECT DeviceObject
;
170 /* make sure event is reset */
174 if (RequestorMode
== UserMode
)
176 /* probe the user buffer */
179 ProbeForWrite(Buffer
, Length
, sizeof(UCHAR
));
180 Status
= STATUS_SUCCESS
;
182 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
184 /* Exception, get the error code */
185 Status
= _SEH2_GetExceptionCode();
189 if (!NT_SUCCESS(Status
))
191 DPRINT1("Invalid user buffer provided\n");
196 /* get corresponding device object */
197 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
199 /* fast-io read is only available for kernel mode clients */
200 if (RequestorMode
== KernelMode
&& ExGetPreviousMode() == KernelMode
&&
201 DeviceObject
->DriverObject
->FastIoDispatch
->FastIoRead
)
203 /* call fast io write */
204 Result
= DeviceObject
->DriverObject
->FastIoDispatch
->FastIoRead(FileObject
, &FileObject
->CurrentByteOffset
, Length
, TRUE
, Key
, Buffer
, IoStatusBlock
, DeviceObject
);
206 if (Result
&& NT_SUCCESS(IoStatusBlock
->Status
))
208 /* request was handeled and succeeded */
209 return STATUS_SUCCESS
;
213 /* do the slow way */
216 /* initialize temp event */
217 KeInitializeEvent(&LocalEvent
, NotificationEvent
, FALSE
);
221 /* build the irp packet */
222 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
, DeviceObject
, Buffer
, Length
, &FileObject
->CurrentByteOffset
, Event
, IoStatusBlock
);
225 /* not enough resources */
226 return STATUS_INSUFFICIENT_RESOURCES
;
229 /* send the packet */
230 Status
= IoCallDriver(DeviceObject
, Irp
);
232 if (Status
== STATUS_PENDING
)
234 /* operation is pending, is sync file object */
235 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
238 KeWaitForSingleObject(Event
, Executive
, RequestorMode
, FALSE
, NULL
);
239 Status
= IoStatusBlock
->Status
;
253 IN PFILE_OBJECT FileObject
,
254 IN PKEVENT Event OPTIONAL
,
255 IN PVOID PortContext OPTIONAL
,
256 OUT PIO_STATUS_BLOCK IoStatusBlock
,
259 IN ULONG Key OPTIONAL
,
260 IN KPROCESSOR_MODE RequestorMode
)
262 PDEVICE_OBJECT DeviceObject
;
270 /* make sure event is reset */
274 if (RequestorMode
== UserMode
)
276 /* probe the user buffer */
279 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
280 Status
= STATUS_SUCCESS
;
282 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
284 /* Exception, get the error code */
285 Status
= _SEH2_GetExceptionCode();
289 if (!NT_SUCCESS(Status
))
291 DPRINT1("Invalid user buffer provided\n");
296 /* get corresponding device object */
297 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
299 /* fast-io write is only available for kernel mode clients */
300 if (RequestorMode
== KernelMode
&& ExGetPreviousMode() == KernelMode
&&
301 DeviceObject
->DriverObject
->FastIoDispatch
->FastIoWrite
)
303 /* call fast io write */
304 Result
= DeviceObject
->DriverObject
->FastIoDispatch
->FastIoWrite(FileObject
, &FileObject
->CurrentByteOffset
, Length
, TRUE
, Key
, Buffer
, IoStatusBlock
, DeviceObject
);
306 if (Result
&& NT_SUCCESS(IoStatusBlock
->Status
))
308 /* request was handeled and succeeded */
309 return STATUS_SUCCESS
;
313 /* do the slow way */
316 /* initialize temp event */
317 KeInitializeEvent(&LocalEvent
, NotificationEvent
, FALSE
);
321 /* build the irp packet */
322 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
, DeviceObject
, Buffer
, Length
, &FileObject
->CurrentByteOffset
, Event
, IoStatusBlock
);
325 /* not enough resources */
326 return STATUS_INSUFFICIENT_RESOURCES
;
329 /* send the packet */
330 Status
= IoCallDriver(DeviceObject
, Irp
);
332 if (Status
== STATUS_PENDING
)
334 /* operation is pending, is sync file object */
335 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
338 KeWaitForSingleObject(Event
, Executive
, RequestorMode
, FALSE
, NULL
);
339 Status
= IoStatusBlock
->Status
;
352 KsQueryInformationFile(
353 IN PFILE_OBJECT FileObject
,
354 OUT PVOID FileInformation
,
356 IN FILE_INFORMATION_CLASS FileInformationClass
)
358 PDEVICE_OBJECT DeviceObject
;
359 PFAST_IO_DISPATCH FastIoDispatch
;
361 PIO_STACK_LOCATION IoStack
;
362 IO_STATUS_BLOCK IoStatus
;
364 LARGE_INTEGER Offset
;
365 IO_STATUS_BLOCK StatusBlock
;
368 /* get related file object */
369 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
371 /* get fast i/o table */
372 FastIoDispatch
= DeviceObject
->DriverObject
->FastIoDispatch
;
374 /* is there a fast table */
377 /* check the class */
378 if (FileInformationClass
== FileBasicInformation
)
380 /* use FastIoQueryBasicInfo routine */
381 if (FastIoDispatch
->FastIoQueryBasicInfo
)
383 return FastIoDispatch
->FastIoQueryBasicInfo(FileObject
, TRUE
, (PFILE_BASIC_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
386 else if (FileInformationClass
== FileStandardInformation
)
388 /* use FastIoQueryBasicInfo routine */
389 if (FastIoDispatch
->FastIoQueryBasicInfo
)
391 return FastIoDispatch
->FastIoQueryStandardInfo(FileObject
, TRUE
, (PFILE_STANDARD_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
396 KeClearEvent(&FileObject
->Event
);
398 /* initialize event */
399 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
401 /* set offset to zero */
402 Offset
.QuadPart
= 0L;
404 /* build the request */
405 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_INFORMATION
, IoGetRelatedDeviceObject(FileObject
), NULL
, 0, &Offset
, &Event
, &StatusBlock
);
408 return STATUS_INSUFFICIENT_RESOURCES
;
410 /* get next stack location */
411 IoStack
= IoGetNextIrpStackLocation(Irp
);
413 /* setup parameters */
414 IoStack
->Parameters
.QueryFile
.FileInformationClass
= FileInformationClass
;
415 IoStack
->Parameters
.QueryFile
.Length
= Length
;
416 Irp
->AssociatedIrp
.SystemBuffer
= FileInformation
;
419 /* call the driver */
420 Status
= IoCallDriver(IoGetRelatedDeviceObject(FileObject
), Irp
);
422 if (Status
== STATUS_PENDING
)
424 /* wait for the operation to complete */
425 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
428 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
429 Status
= FileObject
->FinalStatus
;
431 Status
= StatusBlock
.Status
;
444 KsSetInformationFile(
445 IN PFILE_OBJECT FileObject
,
446 IN PVOID FileInformation
,
448 IN FILE_INFORMATION_CLASS FileInformationClass
)
450 PIO_STACK_LOCATION IoStack
;
451 PDEVICE_OBJECT DeviceObject
;
455 LARGE_INTEGER Offset
;
456 IO_STATUS_BLOCK IoStatus
;
459 /* get related device object */
460 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
462 /* copy file information */
463 Buffer
= AllocateItem(NonPagedPool
, Length
);
465 return STATUS_INSUFFICIENT_RESOURCES
;
469 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
470 RtlMoveMemory(Buffer
, FileInformation
, Length
);
471 Status
= STATUS_SUCCESS
;
473 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
475 /* Exception, get the error code */
476 Status
= _SEH2_GetExceptionCode();
480 if (!NT_SUCCESS(Status
))
482 /* invalid user buffer */
487 /* initialize the event */
488 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
491 Offset
.QuadPart
= 0LL;
494 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_SET_INFORMATION
, DeviceObject
, NULL
, 0, &Offset
, &Event
, &IoStatus
);
498 /* failed to allocate irp */
500 return STATUS_INSUFFICIENT_RESOURCES
;
503 /* get next stack location */
504 IoStack
= IoGetNextIrpStackLocation(Irp
);
506 /* set irp parameters */
507 IoStack
->Parameters
.SetFile
.FileInformationClass
= FileInformationClass
;
508 IoStack
->Parameters
.SetFile
.Length
= Length
;
509 IoStack
->Parameters
.SetFile
.FileObject
= FileObject
;
510 Irp
->AssociatedIrp
.SystemBuffer
= Buffer
;
511 Irp
->UserBuffer
= FileInformation
;
513 /* dispatch the irp */
514 Status
= IoCallDriver(DeviceObject
, Irp
);
516 if (Status
== STATUS_PENDING
)
518 /* wait untill the operation has completed */
519 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
520 /* is a sync file object */
521 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
522 Status
= FileObject
->FinalStatus
;
524 Status
= IoStatus
.Status
;
537 IN PFILE_OBJECT FileObject
,
538 IN PKEVENT Event OPTIONAL
,
539 IN PVOID PortContext OPTIONAL
,
540 IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL
,
541 IN PVOID CompletionContext OPTIONAL
,
542 IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL
,
543 OUT PIO_STATUS_BLOCK IoStatusBlock
,
544 IN OUT PVOID StreamHeaders
,
547 IN KPROCESSOR_MODE RequestorMode
)
550 PIO_STACK_LOCATION IoStack
;
551 PDEVICE_OBJECT DeviceObject
;
553 LARGE_INTEGER Offset
;
554 PKSIOBJECT_HEADER ObjectHeader
;
557 /* get related device object */
558 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
560 ASSERT(DeviceObject
!= NULL
);
562 /* is there a event provided */
569 if (RequestorMode
|| ExGetPreviousMode() == KernelMode
)
571 /* requestor is from kernel land */
572 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext
;
576 /* there is a object header */
577 if (Flags
== KSSTREAM_READ
)
579 /* is fast read supported */
580 if (ObjectHeader
->DispatchTable
.FastRead
)
582 /* call fast read dispatch routine */
583 Ret
= ObjectHeader
->DispatchTable
.FastRead(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
);
587 /* the request was handeled */
588 return IoStatusBlock
->Status
;
592 else if (Flags
== KSSTREAM_WRITE
)
594 /* is fast write supported */
595 if (ObjectHeader
->DispatchTable
.FastWrite
)
597 /* call fast write dispatch routine */
598 Ret
= ObjectHeader
->DispatchTable
.FastWrite(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
);
602 /* the request was handeled */
603 return IoStatusBlock
->Status
;
610 /* clear file object event */
611 KeClearEvent(&FileObject
->Event
);
613 /* set the offset to zero */
614 Offset
.QuadPart
= 0LL;
616 /* now build the irp */
617 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL
,
618 DeviceObject
, (PVOID
)StreamHeaders
, Length
, &Offset
, Event
, IoStatusBlock
);
621 /* not enough memory */
622 return STATUS_INSUFFICIENT_RESOURCES
;
625 /* setup irp parameters */
626 Irp
->RequestorMode
= RequestorMode
;
627 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= PortContext
;
628 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
629 Irp
->UserBuffer
= StreamHeaders
;
631 /* get next irp stack location */
632 IoStack
= IoGetNextIrpStackLocation(Irp
);
633 /* setup stack parameters */
634 IoStack
->FileObject
= FileObject
;
635 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= Length
;
636 IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
= StreamHeaders
;
637 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= (Flags
== KSSTREAM_READ
? IOCTL_KS_READ_STREAM
: IOCTL_KS_WRITE_STREAM
);
639 if (CompletionRoutine
)
641 /* setup completion routine for async processing */
642 IoSetCompletionRoutine(Irp
, CompletionRoutine
, CompletionContext
, (CompletionInvocationFlags
& KsInvokeOnSuccess
), (CompletionInvocationFlags
& KsInvokeOnError
), (CompletionInvocationFlags
& KsInvokeOnCancel
));
645 /* now call the driver */
646 Status
= IoCallDriver(DeviceObject
, Irp
);
663 return STATUS_UNSUCCESSFUL
;
675 OUT PVOID
* ExtraBuffer
)
677 PIO_STACK_LOCATION IoStack
;
679 PUCHAR Buffer
, BufferOrg
;
680 PKSSTREAM_HEADER Header
;
681 NTSTATUS Status
= STATUS_SUCCESS
;
683 /* get current irp stack */
684 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
687 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSSTREAM_HEADER
));
689 /* get total length */
690 Count
= IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
/ sizeof(KSSTREAM_HEADER
);
692 /* allocate buffer */
693 Buffer
= BufferOrg
= AllocateItem(NonPagedPool
, Count
* (sizeof(KSSTREAM_HEADER
) + ExtraSize
));
695 return STATUS_INSUFFICIENT_RESOURCES
;
699 /* get input buffer */
700 Header
= (PKSSTREAM_HEADER
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
701 for(Index
= 0; Index
< Count
; Index
++)
703 /* copy stream header */
704 RtlMoveMemory(Buffer
, Header
, sizeof(KSSTREAM_HEADER
));
706 /* move to next header */
708 /* increment output buffer offset */
709 Buffer
+= sizeof(KSSTREAM_HEADER
) + ExtraSize
;
712 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
714 /* Exception, get the error code */
715 Status
= _SEH2_GetExceptionCode();
719 if (!NT_SUCCESS(Status
))
721 /* free buffer on exception */
727 *ExtraBuffer
= BufferOrg
;
730 return STATUS_SUCCESS
;
740 IN PDRIVER_OBJECT DriverObject
)
750 KsDispatchInvalidDeviceRequest(
751 IN PDEVICE_OBJECT DeviceObject
,
754 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
755 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
757 return STATUS_INVALID_DEVICE_REQUEST
;
766 KsDefaultDeviceIoCompletion(
767 IN PDEVICE_OBJECT DeviceObject
,
770 PIO_STACK_LOCATION IoStack
;
773 /* get current irp stack */
774 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
776 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
&&
777 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_METHOD
&&
778 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
780 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_RESET_STATE
)
783 Status
= STATUS_SUCCESS
;
787 /* request unsupported */
788 Status
= STATUS_INVALID_DEVICE_REQUEST
;
793 /* property / method / event not found */
794 Status
= STATUS_PROPSET_NOT_FOUND
;
797 /* complete request */
798 Irp
->IoStatus
.Status
= Status
;
799 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
811 KsDispatchFastIoDeviceControlFailure(
812 IN PFILE_OBJECT FileObject
,
814 IN PVOID InputBuffer OPTIONAL
,
815 IN ULONG InputBufferLength
,
816 OUT PVOID OutputBuffer OPTIONAL
,
817 IN ULONG OutputBufferLength
,
818 IN ULONG IoControlCode
,
819 OUT PIO_STATUS_BLOCK IoStatus
,
820 IN PDEVICE_OBJECT DeviceObject
)
831 KsDispatchFastReadFailure(
832 IN PFILE_OBJECT FileObject
,
833 IN PLARGE_INTEGER FileOffset
,
838 OUT PIO_STATUS_BLOCK IoStatus
,
839 IN PDEVICE_OBJECT DeviceObject
)
852 IN OUT PLIST_ENTRY QueueHead
,
853 IN PKSPIN_LOCK SpinLock
)
855 PDRIVER_CANCEL OldDriverCancel
;
856 PIO_STACK_LOCATION IoStack
;
861 /* acquire spinlock */
862 KeAcquireSpinLock(SpinLock
, &OldLevel
);
863 /* point to first entry */
864 Entry
= QueueHead
->Flink
;
866 while(Entry
!= QueueHead
)
869 Irp
= (PIRP
)CONTAINING_RECORD(Entry
, IRP
, Tail
.Overlay
.ListEntry
);
871 /* set cancelled bit */
874 /* now set the cancel routine */
875 OldDriverCancel
= IoSetCancelRoutine(Irp
, NULL
);
878 /* this irp hasnt been yet used, so free to cancel */
879 KeReleaseSpinLock(SpinLock
, OldLevel
);
881 /* get current irp stack */
882 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
884 /* acquire cancel spinlock */
885 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
887 /* call provided cancel routine */
888 OldDriverCancel(IoStack
->DeviceObject
, Irp
);
890 /* re-acquire spinlock */
891 KeAcquireSpinLock(SpinLock
, &OldLevel
);
893 /* move on to next entry */
894 Entry
= Entry
->Flink
;
897 /* the irp has already been canceled */
898 KeReleaseSpinLock(SpinLock
, OldLevel
);
908 KsReleaseIrpOnCancelableQueue(
910 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
912 PKSPIN_LOCK SpinLock
;
913 PDRIVER_CANCEL OldDriverCancel
;
914 PIO_STACK_LOCATION IoStack
;
917 /* check for required parameters */
923 /* default to KsCancelRoutine */
924 DriverCancel
= KsCancelRoutine
;
927 /* get current irp stack */
928 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
930 /* get internal queue lock */
931 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
933 /* acquire spinlock */
934 KeAcquireSpinLock(SpinLock
, &OldLevel
);
936 /* now set the cancel routine */
937 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
939 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
941 /* the irp has already been canceled */
942 KeReleaseSpinLock(SpinLock
, OldLevel
);
944 /* cancel routine requires that cancel spinlock is held */
945 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
948 DriverCancel(IoStack
->DeviceObject
, Irp
);
953 KeReleaseSpinLock(SpinLock
, OldLevel
);
963 KsRemoveIrpFromCancelableQueue(
964 IN OUT PLIST_ENTRY QueueHead
,
965 IN PKSPIN_LOCK SpinLock
,
966 IN KSLIST_ENTRY_LOCATION ListLocation
,
967 IN KSIRP_REMOVAL_OPERATION RemovalOperation
)
970 PLIST_ENTRY CurEntry
;
973 /* check parameters */
974 if (!QueueHead
|| !SpinLock
)
977 /* check if parameter ListLocation is valid */
978 if (ListLocation
!= KsListEntryTail
&& ListLocation
!= KsListEntryHead
)
981 /* acquire list lock */
982 KeAcquireSpinLock(SpinLock
, &OldIrql
);
984 /* point to queue head */
985 CurEntry
= QueueHead
;
989 /* reset irp to null */
992 /* iterate to next entry */
993 if (ListLocation
== KsListEntryHead
)
994 CurEntry
= CurEntry
->Flink
;
996 CurEntry
= CurEntry
->Blink
;
998 /* is the end of list reached */
999 if (CurEntry
== QueueHead
)
1001 /* reached end of list */
1005 /* get irp offset */
1006 Irp
= (PIRP
)CONTAINING_RECORD(CurEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1010 /* irp has been canceled */
1014 if (Irp
->CancelRoutine
)
1016 /* remove cancel routine */
1017 Irp
->CancelRoutine
= NULL
;
1019 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
1021 /* remove irp from list */
1022 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1025 if (RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
|| RemovalOperation
== KsAcquireOnlySingleItem
)
1032 KeReleaseSpinLock(SpinLock
, OldIrql
);
1034 if (!Irp
|| Irp
->CancelRoutine
== NULL
)
1036 /* either an irp has been acquired or nothing found */
1040 /* time to remove the canceled irp */
1041 IoAcquireCancelSpinLock(&OldIrql
);
1042 /* acquire list lock */
1043 KeAcquireSpinLockAtDpcLevel(SpinLock
);
1045 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
1048 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1051 /* release list lock */
1052 KeReleaseSpinLockFromDpcLevel(SpinLock
);
1054 /* release cancel spinlock */
1055 IoReleaseCancelSpinLock(OldIrql
);
1056 /* no non canceled irp has been found */
1066 KsMoveIrpsOnCancelableQueue(
1067 IN OUT PLIST_ENTRY SourceList
,
1068 IN PKSPIN_LOCK SourceLock
,
1069 IN OUT PLIST_ENTRY DestinationList
,
1070 IN PKSPIN_LOCK DestinationLock OPTIONAL
,
1071 IN KSLIST_ENTRY_LOCATION ListLocation
,
1072 IN PFNKSIRPLISTCALLBACK ListCallback
,
1076 PLIST_ENTRY SrcEntry
;
1080 if (!DestinationLock
)
1082 /* no destination lock just acquire the source lock */
1083 KeAcquireSpinLock(SourceLock
, &OldLevel
);
1087 /* acquire cancel spinlock */
1088 IoAcquireCancelSpinLock(&OldLevel
);
1090 /* now acquire source lock */
1091 KeAcquireSpinLockAtDpcLevel(SourceLock
);
1093 /* now acquire destination lock */
1094 KeAcquireSpinLockAtDpcLevel(DestinationLock
);
1097 /* point to list head */
1098 SrcEntry
= SourceList
;
1100 /* now move all irps */
1103 if (ListLocation
== KsListEntryTail
)
1105 /* move queue downwards */
1106 SrcEntry
= SrcEntry
->Flink
;
1110 /* move queue upwards */
1111 SrcEntry
= SrcEntry
->Blink
;
1114 if (SrcEntry
== DestinationList
)
1116 /* eof list reached */
1120 /* get irp offset */
1121 Irp
= (PIRP
)CONTAINING_RECORD(SrcEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1123 /* now check if irp can be moved */
1124 Status
= ListCallback(Irp
, Context
);
1126 /* check if irp can be moved */
1127 if (Status
== STATUS_SUCCESS
)
1129 /* remove irp from src list */
1130 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1132 if (ListLocation
== KsListEntryTail
)
1134 /* insert irp end of list */
1135 InsertTailList(DestinationList
, &Irp
->Tail
.Overlay
.ListEntry
);
1139 /* insert irp head of list */
1140 InsertHeadList(DestinationList
, &Irp
->Tail
.Overlay
.ListEntry
);
1143 /* do we need to update the irp lock */
1144 if (DestinationLock
)
1146 /* update irp lock */
1147 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
) = DestinationLock
;
1152 if (Status
!= STATUS_NO_MATCH
)
1154 /* callback decided to stop enumeration */
1158 /* reset return value */
1159 Status
= STATUS_SUCCESS
;
1163 if (!DestinationLock
)
1165 /* release source lock */
1166 KeReleaseSpinLock(SourceLock
, OldLevel
);
1170 /* now release destination lock */
1171 KeReleaseSpinLockFromDpcLevel(DestinationLock
);
1173 /* now release source lock */
1174 KeReleaseSpinLockFromDpcLevel(SourceLock
);
1177 /* now release cancel spinlock */
1178 IoReleaseCancelSpinLock(OldLevel
);
1191 KsRemoveSpecificIrpFromCancelableQueue(
1194 PKSPIN_LOCK SpinLock
;
1197 /* get internal queue lock */
1198 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1200 /* acquire spinlock */
1201 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1203 /* remove the irp from the list */
1204 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1206 /* release spinlock */
1207 KeReleaseSpinLock(SpinLock
, OldLevel
);
1217 KsAddIrpToCancelableQueue(
1218 IN OUT PLIST_ENTRY QueueHead
,
1219 IN PKSPIN_LOCK SpinLock
,
1221 IN KSLIST_ENTRY_LOCATION ListLocation
,
1222 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
1224 PDRIVER_CANCEL OldDriverCancel
;
1225 PIO_STACK_LOCATION IoStack
;
1228 /* check for required parameters */
1229 if (!QueueHead
|| !SpinLock
|| !Irp
)
1234 /* default to KsCancelRoutine */
1235 DriverCancel
= KsCancelRoutine
;
1238 /* get current irp stack */
1239 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1241 /* acquire spinlock */
1242 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1244 if (ListLocation
== KsListEntryTail
)
1246 /* insert irp to tail of list */
1247 InsertTailList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1251 /* insert irp to head of list */
1252 InsertHeadList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1255 /* store internal queue lock */
1256 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
) = SpinLock
;
1258 /* now set the cancel routine */
1259 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
1261 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
1263 /* the irp has already been canceled */
1264 KeReleaseSpinLock(SpinLock
, OldLevel
);
1266 /* cancel routine requires that cancel spinlock is held */
1267 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1270 DriverCancel(IoStack
->DeviceObject
, Irp
);
1275 KeReleaseSpinLock(SpinLock
, OldLevel
);
1286 IN PDEVICE_OBJECT DeviceObject
,
1289 PKSPIN_LOCK SpinLock
;
1291 /* get internal queue lock */
1292 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1294 /* acquire spinlock */
1295 KeAcquireSpinLockAtDpcLevel(SpinLock
);
1298 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1300 /* release cancel spinlock */
1301 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
1303 /* remove the irp from the list */
1304 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1306 /* release spinlock */
1307 KeReleaseSpinLockFromDpcLevel(SpinLock
);
1309 /* has the irp already been canceled */
1310 if (Irp
->IoStatus
.Status
!= STATUS_CANCELLED
)
1312 /* let's complete it */
1313 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
1314 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1319 FindMatchingCreateItem(
1320 PLIST_ENTRY ListHead
,
1323 OUT PCREATE_ITEM_ENTRY
*OutCreateItem
)
1326 PCREATE_ITEM_ENTRY CreateItemEntry
;
1328 /* remove '\' slash */
1330 BufferSize
-= sizeof(WCHAR
);
1332 /* point to first entry */
1333 Entry
= ListHead
->Flink
;
1335 /* loop all device items */
1336 while(Entry
!= ListHead
)
1338 /* get create item entry */
1339 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1341 ASSERT(CreateItemEntry
->CreateItem
);
1343 if(CreateItemEntry
->CreateItem
->Flags
& KSCREATE_ITEM_WILDCARD
)
1345 /* create item is default */
1346 *OutCreateItem
= CreateItemEntry
;
1347 return STATUS_SUCCESS
;
1350 if (!CreateItemEntry
->CreateItem
->Create
)
1352 /* skip free create item */
1353 Entry
= Entry
->Flink
;
1357 ASSERT(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
);
1359 DPRINT1("CreateItem %S Length %u Request %S %u\n", CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
,
1360 CreateItemEntry
->CreateItem
->ObjectClass
.Length
,
1364 if (CreateItemEntry
->CreateItem
->ObjectClass
.Length
> BufferSize
)
1366 /* create item doesnt match in length */
1367 Entry
= Entry
->Flink
;
1371 /* now check if the object class is the same */
1372 if (RtlCompareMemory(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
, Buffer
, CreateItemEntry
->CreateItem
->ObjectClass
.Length
) == CreateItemEntry
->CreateItem
->ObjectClass
.Length
)
1374 /* found matching create item */
1375 *OutCreateItem
= CreateItemEntry
;
1376 return STATUS_SUCCESS
;
1378 /* iterate to next */
1379 Entry
= Entry
->Flink
;
1382 return STATUS_NOT_FOUND
;
1388 IN PDEVICE_OBJECT DeviceObject
,
1391 PCREATE_ITEM_ENTRY CreateItemEntry
;
1392 PIO_STACK_LOCATION IoStack
;
1393 PDEVICE_EXTENSION DeviceExtension
;
1394 PKSIDEVICE_HEADER DeviceHeader
;
1395 PKSIOBJECT_HEADER ObjectHeader
;
1398 DPRINT("KS / CREATE\n");
1399 /* get current stack location */
1400 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1401 /* get device extension */
1402 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1403 /* get device header */
1404 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1406 if (IoStack
->FileObject
->FileName
.Buffer
== NULL
&& DeviceHeader
->ItemListCount
== 1)
1408 /* hack for bug 4566 */
1409 ASSERT(!IsListEmpty(&DeviceHeader
->ItemList
));
1410 /* get create item entry */
1411 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(DeviceHeader
->ItemList
.Flink
, CREATE_ITEM_ENTRY
, Entry
);
1413 ASSERT(CreateItemEntry
->CreateItem
);
1415 if (!CreateItemEntry
->CreateItem
->Create
)
1417 /* no valid create item */
1418 Irp
->IoStatus
.Information
= 0;
1419 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1420 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1422 return STATUS_UNSUCCESSFUL
;
1425 /* set object create item */
1426 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
1428 /* call create function */
1429 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
1431 if (NT_SUCCESS(Status
))
1433 /* increment create item reference count */
1434 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
1441 /* hack for bug 4566 */
1442 if (IoStack
->FileObject
->FileName
.Buffer
== NULL
)
1444 DPRINT("Using reference string hack\n");
1445 Irp
->IoStatus
.Information
= 0;
1446 /* set return status */
1447 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1448 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1449 return STATUS_SUCCESS
;
1453 if (IoStack
->FileObject
->RelatedFileObject
!= NULL
)
1455 /* request is to instantiate a pin / node / clock / allocator */
1456 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->RelatedFileObject
->FsContext
;
1459 ASSERT(ObjectHeader
);
1461 /* find a matching a create item */
1462 Status
= FindMatchingCreateItem(&ObjectHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
1466 /* request to create a filter */
1467 Status
= FindMatchingCreateItem(&DeviceHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
1470 if (NT_SUCCESS(Status
))
1472 /* set object create item */
1473 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
1475 /* call create function */
1476 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
1478 if (NT_SUCCESS(Status
))
1480 /* increment create item reference count */
1481 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
1487 Irp
->IoStatus
.Information
= 0;
1488 /* set return status */
1489 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1490 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1491 return STATUS_UNSUCCESSFUL
;
1495 RosDeviceInterfaceReferenceStringHack(
1496 IN PDEVICE_OBJECT DeviceObject
,
1499 PIO_STACK_LOCATION IoStack
;
1500 PKSIDEVICE_HEADER DeviceHeader
;
1501 PDEVICE_EXTENSION DeviceExtension
;
1502 PCREATE_ITEM_ENTRY CreateItemEntry
;
1507 /* get current stack location */
1508 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1510 /* get device extension */
1511 DeviceExtension
= (PDEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
1512 /* get device header */
1513 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1515 /* retrieve all available reference strings registered */
1517 Entry
= DeviceHeader
->ItemList
.Flink
;
1518 while(Entry
!= &DeviceHeader
->ItemList
)
1520 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1522 ASSERT(CreateItemEntry
->CreateItem
);
1523 if (CreateItemEntry
->CreateItem
->Create
&& CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
)
1524 Length
+= wcslen(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
) + 1;
1526 Entry
= Entry
->Flink
;
1529 /* add extra zero */
1532 /* allocate the buffer */
1533 Buffer
= ExAllocatePool(NonPagedPool
, Length
* sizeof(WCHAR
));
1536 Irp
->IoStatus
.Information
= 0;
1537 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1538 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1539 return STATUS_INSUFFICIENT_RESOURCES
;
1543 *((LPWSTR
*)Irp
->UserBuffer
) = Buffer
;
1544 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1545 Irp
->IoStatus
.Information
= sizeof(LPWSTR
);
1547 Entry
= DeviceHeader
->ItemList
.Flink
;
1548 while(Entry
!= &DeviceHeader
->ItemList
)
1550 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1552 ASSERT(CreateItemEntry
->CreateItem
);
1553 if (CreateItemEntry
->CreateItem
->Create
&& CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
)
1555 wcscpy(Buffer
, CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
);
1556 Buffer
+= wcslen(Buffer
) + 1;
1558 Entry
= Entry
->Flink
;
1564 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1565 return STATUS_SUCCESS
;
1572 IN PDEVICE_OBJECT DeviceObject
,
1575 PIO_STACK_LOCATION IoStack
;
1576 PKSIOBJECT_HEADER ObjectHeader
;
1577 PKSIDEVICE_HEADER DeviceHeader
;
1578 PDEVICE_EXTENSION DeviceExtension
;
1582 /* get current stack location */
1583 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1585 /* get device extension */
1586 DeviceExtension
= (PDEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
1587 /* get device header */
1588 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1590 if (IoStack
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
&& IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_OBJECT_CLASS
)
1592 /* hack for bug 4566 */
1593 return RosDeviceInterfaceReferenceStringHack(DeviceObject
, Irp
);
1596 ObjectHeader
= (PKSIOBJECT_HEADER
) IoStack
->FileObject
->FsContext
;
1598 ASSERT(ObjectHeader
);
1599 //KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
1601 return ObjectHeader
->DispatchTable
.DeviceIoControl(DeviceObject
, Irp
);
1607 IN PDEVICE_OBJECT DeviceObject
,
1610 PIO_STACK_LOCATION IoStack
;
1611 PDEVICE_EXTENSION DeviceExtension
;
1612 PKSIOBJECT_HEADER ObjectHeader
;
1613 PKSIDEVICE_HEADER DeviceHeader
;
1614 PDRIVER_DISPATCH Dispatch
;
1617 /* get current stack location */
1618 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1620 /* get device extension */
1621 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1622 /* get device header */
1623 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1625 /* get object header */
1626 ObjectHeader
= (PKSIOBJECT_HEADER
) IoStack
->FileObject
->FsContext
;
1630 /* hack for bug 4566 */
1631 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1632 Irp
->IoStatus
.Information
= 0;
1633 /* complete and forget */
1634 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1635 return STATUS_SUCCESS
;
1639 ASSERT(ObjectHeader
);
1640 /* store create item */
1641 //KSCREATE_ITEM_IRP_STORAGE(Irp) = (PKSOBJECT_CREATE_ITEM)0x12345678; //ObjectHeader->CreateItem;
1643 /* retrieve matching dispatch function */
1644 switch(IoStack
->MajorFunction
)
1647 Dispatch
= ObjectHeader
->DispatchTable
.Close
;
1649 case IRP_MJ_DEVICE_CONTROL
:
1650 Dispatch
= ObjectHeader
->DispatchTable
.DeviceIoControl
;
1653 Dispatch
= ObjectHeader
->DispatchTable
.Read
;
1656 Dispatch
= ObjectHeader
->DispatchTable
.Write
;
1658 case IRP_MJ_FLUSH_BUFFERS
:
1659 Dispatch
= ObjectHeader
->DispatchTable
.Flush
;
1661 case IRP_MJ_QUERY_SECURITY
:
1662 Dispatch
= ObjectHeader
->DispatchTable
.QuerySecurity
;
1664 case IRP_MJ_SET_SECURITY
:
1665 Dispatch
= ObjectHeader
->DispatchTable
.SetSecurity
;
1668 Dispatch
= KsDefaultDispatchPnp
;
1673 /* is the request supported */
1676 /* now call the dispatch function */
1677 Status
= Dispatch(DeviceObject
, Irp
);
1681 /* not supported request */
1682 Status
= KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
1695 KsSetMajorFunctionHandler(
1696 IN PDRIVER_OBJECT DriverObject
,
1697 IN ULONG MajorFunction
)
1699 switch ( MajorFunction
)
1702 DriverObject
->MajorFunction
[MajorFunction
] = KspCreate
;
1705 case IRP_MJ_DEVICE_CONTROL
:
1706 DriverObject
->MajorFunction
[MajorFunction
] = KspDeviceControl
;
1711 case IRP_MJ_FLUSH_BUFFERS
:
1712 case IRP_MJ_QUERY_SECURITY
:
1713 case IRP_MJ_SET_SECURITY
:
1714 DriverObject
->MajorFunction
[MajorFunction
] = KspDispatchIrp
;
1717 return STATUS_INVALID_PARAMETER
;
1720 return STATUS_SUCCESS
;
1730 IN PDEVICE_OBJECT DeviceObject
,
1733 PIO_STACK_LOCATION IoStack
;
1734 PKSIDEVICE_HEADER DeviceHeader
;
1735 PDEVICE_EXTENSION DeviceExtension
;
1737 /* get device extension */
1738 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1739 /* get device header */
1740 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1743 /* get current irp stack */
1744 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1746 if (IoStack
->MajorFunction
<= IRP_MJ_DEVICE_CONTROL
)
1748 if (IoStack
->MajorFunction
== IRP_MJ_CREATE
)
1750 /* check internal type */
1751 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
1753 /* AVStream client */
1754 return IKsDevice_Create(DeviceObject
, Irp
);
1758 /* external client (portcls) */
1759 return KspCreate(DeviceObject
, Irp
);
1763 if (IoStack
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
1765 /* handle device requests */
1766 return KspDeviceControl(DeviceObject
, Irp
);
1769 switch (IoStack
->MajorFunction
)
1774 case IRP_MJ_FLUSH_BUFFERS
:
1775 case IRP_MJ_QUERY_SECURITY
:
1776 case IRP_MJ_SET_SECURITY
:
1778 return KspDispatchIrp(DeviceObject
, Irp
);
1780 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
1784 /* dispatch power */
1785 if (IoStack
->MajorFunction
== IRP_MJ_POWER
)
1787 /* check internal type */
1788 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
1790 /* AVStream client */
1791 return IKsDevice_Power(DeviceObject
, Irp
);
1795 /* external client (portcls) */
1796 return KsDefaultDispatchPower(DeviceObject
, Irp
);
1799 else if (IoStack
->MajorFunction
== IRP_MJ_PNP
) /* dispatch pnp */
1801 /* check internal type */
1802 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
1804 /* AVStream client */
1805 return IKsDevice_Pnp(DeviceObject
, Irp
);
1809 /* external client (portcls) */
1810 return KsDefaultDispatchPnp(DeviceObject
, Irp
);
1813 else if (IoStack
->MajorFunction
== IRP_MJ_SYSTEM_CONTROL
)
1816 return KsDefaultForwardIrp(DeviceObject
, Irp
);
1821 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);