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
;
360 IO_STATUS_BLOCK IoStatus
;
362 /* get related file object */
363 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
365 /* get fast i/o table */
366 FastIoDispatch
= DeviceObject
->DriverObject
->FastIoDispatch
;
368 /* is there a fast table */
371 /* check the class */
372 if (FileInformationClass
== FileBasicInformation
)
374 /* use FastIoQueryBasicInfo routine */
375 if (FastIoDispatch
->FastIoQueryBasicInfo
)
377 return FastIoDispatch
->FastIoQueryBasicInfo(FileObject
, TRUE
, (PFILE_BASIC_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
380 else if (FileInformationClass
== FileStandardInformation
)
382 /* use FastIoQueryBasicInfo routine */
383 if (FastIoDispatch
->FastIoQueryBasicInfo
)
385 return FastIoDispatch
->FastIoQueryStandardInfo(FileObject
, TRUE
, (PFILE_STANDARD_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
392 return STATUS_UNSUCCESSFUL
;
401 KsSetInformationFile(
402 IN PFILE_OBJECT FileObject
,
403 IN PVOID FileInformation
,
405 IN FILE_INFORMATION_CLASS FileInformationClass
)
407 PIO_STACK_LOCATION IoStack
;
408 PDEVICE_OBJECT DeviceObject
;
412 LARGE_INTEGER Offset
;
413 IO_STATUS_BLOCK IoStatus
;
416 /* get related device object */
417 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
419 /* copy file information */
420 Buffer
= AllocateItem(NonPagedPool
, Length
);
422 return STATUS_INSUFFICIENT_RESOURCES
;
426 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
427 RtlMoveMemory(Buffer
, FileInformation
, Length
);
428 Status
= STATUS_SUCCESS
;
430 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
432 /* Exception, get the error code */
433 Status
= _SEH2_GetExceptionCode();
437 if (!NT_SUCCESS(Status
))
439 /* invalid user buffer */
444 /* initialize the event */
445 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
448 Offset
.QuadPart
= 0LL;
451 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_SET_INFORMATION
, DeviceObject
, NULL
, 0, &Offset
, &Event
, &IoStatus
);
455 /* failed to allocate irp */
457 return STATUS_INSUFFICIENT_RESOURCES
;
460 /* get next stack location */
461 IoStack
= IoGetNextIrpStackLocation(Irp
);
463 /* set irp parameters */
464 IoStack
->Parameters
.SetFile
.FileInformationClass
= FileInformationClass
;
465 IoStack
->Parameters
.SetFile
.Length
= Length
;
466 IoStack
->Parameters
.SetFile
.FileObject
= FileObject
;
467 Irp
->AssociatedIrp
.SystemBuffer
= Buffer
;
468 Irp
->UserBuffer
= FileInformation
;
470 /* dispatch the irp */
471 Status
= IoCallDriver(DeviceObject
, Irp
);
473 if (Status
== STATUS_PENDING
)
475 /* wait untill the operation has completed */
476 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
477 /* is a sync file object */
478 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
479 Status
= FileObject
->FinalStatus
;
481 Status
= IoStatus
.Status
;
494 IN PFILE_OBJECT FileObject
,
495 IN PKEVENT Event OPTIONAL
,
496 IN PVOID PortContext OPTIONAL
,
497 IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL
,
498 IN PVOID CompletionContext OPTIONAL
,
499 IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL
,
500 OUT PIO_STATUS_BLOCK IoStatusBlock
,
501 IN OUT PVOID StreamHeaders
,
504 IN KPROCESSOR_MODE RequestorMode
)
507 PIO_STACK_LOCATION IoStack
;
508 PDEVICE_OBJECT DeviceObject
;
511 LARGE_INTEGER Offset
;
512 PKSIOBJECT_HEADER ObjectHeader
;
515 if (Flags
== KSSTREAM_READ
)
517 else if (Flags
== KSSTREAM_WRITE
)
520 return STATUS_INVALID_PARAMETER
;
522 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
524 return STATUS_INVALID_PARAMETER
;
531 //ASSERT(DeviceObject->DeviceType == FILE_DEVICE_KS);
532 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext
;
533 ASSERT(ObjectHeader
);
534 if (Code
== IRP_MJ_READ
)
536 if (ObjectHeader
->DispatchTable
.FastRead
)
538 if (ObjectHeader
->DispatchTable
.FastRead(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
))
540 return STATUS_SUCCESS
;
546 if (ObjectHeader
->DispatchTable
.FastWrite
)
548 if (ObjectHeader
->DispatchTable
.FastWrite(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
))
550 return STATUS_SUCCESS
;
555 Offset
.QuadPart
= 0LL;
556 Irp
= IoBuildSynchronousFsdRequest(Code
, DeviceObject
, (PVOID
)StreamHeaders
, Length
, &Offset
, Event
, IoStatusBlock
);
559 return STATUS_UNSUCCESSFUL
;
563 if (CompletionRoutine
)
565 IoSetCompletionRoutine(Irp
,
568 (CompletionInvocationFlags
& KsInvokeOnSuccess
),
569 (CompletionInvocationFlags
& KsInvokeOnError
),
570 (CompletionInvocationFlags
& KsInvokeOnCancel
));
573 IoStack
= IoGetNextIrpStackLocation(Irp
);
574 IoStack
->FileObject
= FileObject
;
576 Status
= IoCallDriver(DeviceObject
, Irp
);
593 return STATUS_UNSUCCESSFUL
;
605 OUT PVOID
* ExtraBuffer
)
607 PIO_STACK_LOCATION IoStack
;
609 PUCHAR Buffer
, BufferOrg
;
610 PKSSTREAM_HEADER Header
;
611 NTSTATUS Status
= STATUS_SUCCESS
;
613 /* get current irp stack */
614 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
617 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSSTREAM_HEADER
));
619 /* get total length */
620 Count
= IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
/ sizeof(KSSTREAM_HEADER
);
622 /* allocate buffer */
623 Buffer
= BufferOrg
= AllocateItem(NonPagedPool
, Count
* (sizeof(KSSTREAM_HEADER
) + ExtraSize
));
625 return STATUS_INSUFFICIENT_RESOURCES
;
629 /* get input buffer */
630 Header
= (PKSSTREAM_HEADER
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
631 for(Index
= 0; Index
< Count
; Index
++)
633 /* copy stream header */
634 RtlMoveMemory(Buffer
, Header
, sizeof(KSSTREAM_HEADER
));
636 /* move to next header */
638 /* increment output buffer offset */
639 Buffer
+= sizeof(KSSTREAM_HEADER
) + ExtraSize
;
642 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
644 /* Exception, get the error code */
645 Status
= _SEH2_GetExceptionCode();
649 if (!NT_SUCCESS(Status
))
651 /* free buffer on exception */
657 *ExtraBuffer
= BufferOrg
;
660 return STATUS_SUCCESS
;
670 IN PDRIVER_OBJECT DriverObject
)
680 KsDispatchInvalidDeviceRequest(
681 IN PDEVICE_OBJECT DeviceObject
,
684 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
685 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
687 return STATUS_INVALID_DEVICE_REQUEST
;
696 KsDefaultDeviceIoCompletion(
697 IN PDEVICE_OBJECT DeviceObject
,
700 PIO_STACK_LOCATION IoStack
;
703 /* get current irp stack */
704 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
706 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
&&
707 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_METHOD
&&
708 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
710 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_RESET_STATE
)
713 Status
= STATUS_SUCCESS
;
717 /* request unsupported */
718 Status
= STATUS_INVALID_DEVICE_REQUEST
;
723 /* property / method / event not found */
724 Status
= STATUS_PROPSET_NOT_FOUND
;
727 /* complete request */
728 Irp
->IoStatus
.Status
= Status
;
729 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
741 KsDispatchFastIoDeviceControlFailure(
742 IN PFILE_OBJECT FileObject
,
744 IN PVOID InputBuffer OPTIONAL
,
745 IN ULONG InputBufferLength
,
746 OUT PVOID OutputBuffer OPTIONAL
,
747 IN ULONG OutputBufferLength
,
748 IN ULONG IoControlCode
,
749 OUT PIO_STATUS_BLOCK IoStatus
,
750 IN PDEVICE_OBJECT DeviceObject
)
761 KsDispatchFastReadFailure(
762 IN PFILE_OBJECT FileObject
,
763 IN PLARGE_INTEGER FileOffset
,
768 OUT PIO_STATUS_BLOCK IoStatus
,
769 IN PDEVICE_OBJECT DeviceObject
)
782 IN OUT PLIST_ENTRY QueueHead
,
783 IN PKSPIN_LOCK SpinLock
)
785 PDRIVER_CANCEL OldDriverCancel
;
786 PIO_STACK_LOCATION IoStack
;
791 /* acquire spinlock */
792 KeAcquireSpinLock(SpinLock
, &OldLevel
);
793 /* point to first entry */
794 Entry
= QueueHead
->Flink
;
796 while(Entry
!= QueueHead
)
799 Irp
= (PIRP
)CONTAINING_RECORD(Entry
, IRP
, Tail
.Overlay
.ListEntry
);
801 /* set cancelled bit */
804 /* now set the cancel routine */
805 OldDriverCancel
= IoSetCancelRoutine(Irp
, NULL
);
808 /* this irp hasnt been yet used, so free to cancel */
809 KeReleaseSpinLock(SpinLock
, OldLevel
);
811 /* get current irp stack */
812 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
814 /* acquire cancel spinlock */
815 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
817 /* call provided cancel routine */
818 OldDriverCancel(IoStack
->DeviceObject
, Irp
);
820 /* re-acquire spinlock */
821 KeAcquireSpinLock(SpinLock
, &OldLevel
);
823 /* move on to next entry */
824 Entry
= Entry
->Flink
;
827 /* the irp has already been canceled */
828 KeReleaseSpinLock(SpinLock
, OldLevel
);
838 KsReleaseIrpOnCancelableQueue(
840 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
842 PKSPIN_LOCK SpinLock
;
843 PDRIVER_CANCEL OldDriverCancel
;
844 PIO_STACK_LOCATION IoStack
;
847 /* check for required parameters */
853 /* default to KsCancelRoutine */
854 DriverCancel
= KsCancelRoutine
;
857 /* get current irp stack */
858 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
860 /* get internal queue lock */
861 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
863 /* acquire spinlock */
864 KeAcquireSpinLock(SpinLock
, &OldLevel
);
866 /* now set the cancel routine */
867 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
869 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
871 /* the irp has already been canceled */
872 KeReleaseSpinLock(SpinLock
, OldLevel
);
874 /* cancel routine requires that cancel spinlock is held */
875 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
878 DriverCancel(IoStack
->DeviceObject
, Irp
);
883 KeReleaseSpinLock(SpinLock
, OldLevel
);
893 KsRemoveIrpFromCancelableQueue(
894 IN OUT PLIST_ENTRY QueueHead
,
895 IN PKSPIN_LOCK SpinLock
,
896 IN KSLIST_ENTRY_LOCATION ListLocation
,
897 IN KSIRP_REMOVAL_OPERATION RemovalOperation
)
900 PLIST_ENTRY CurEntry
;
903 /* check parameters */
904 if (!QueueHead
|| !SpinLock
)
907 /* check if parameter ListLocation is valid */
908 if (ListLocation
!= KsListEntryTail
&& ListLocation
!= KsListEntryHead
)
911 /* acquire list lock */
912 KeAcquireSpinLock(SpinLock
, &OldIrql
);
914 /* point to queue head */
915 CurEntry
= QueueHead
;
919 /* reset irp to null */
922 /* iterate to next entry */
923 if (ListLocation
== KsListEntryHead
)
924 CurEntry
= CurEntry
->Flink
;
926 CurEntry
= CurEntry
->Blink
;
928 /* is the end of list reached */
929 if (CurEntry
== QueueHead
)
931 /* reached end of list */
936 Irp
= (PIRP
)CONTAINING_RECORD(Irp
, IRP
, Tail
.Overlay
.ListEntry
);
940 /* irp has been canceled */
944 if (Irp
->CancelRoutine
)
946 /* remove cancel routine */
947 Irp
->CancelRoutine
= NULL
;
949 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
951 /* remove irp from list */
952 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
955 if (RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
|| RemovalOperation
== KsAcquireOnlySingleItem
)
962 KeReleaseSpinLock(SpinLock
, OldIrql
);
964 if (!Irp
|| Irp
->CancelRoutine
== NULL
)
966 /* either an irp has been acquired or nothing found */
970 /* time to remove the canceled irp */
971 IoAcquireCancelSpinLock(&OldIrql
);
972 /* acquire list lock */
973 KeAcquireSpinLockAtDpcLevel(SpinLock
);
975 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
978 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
981 /* release list lock */
982 KeReleaseSpinLockFromDpcLevel(SpinLock
);
984 /* release cancel spinlock */
985 IoReleaseCancelSpinLock(OldIrql
);
986 /* no non canceled irp has been found */
996 KsMoveIrpsOnCancelableQueue(
997 IN OUT PLIST_ENTRY SourceList
,
998 IN PKSPIN_LOCK SourceLock
,
999 IN OUT PLIST_ENTRY DestinationList
,
1000 IN PKSPIN_LOCK DestinationLock OPTIONAL
,
1001 IN KSLIST_ENTRY_LOCATION ListLocation
,
1002 IN PFNKSIRPLISTCALLBACK ListCallback
,
1006 return STATUS_UNSUCCESSFUL
;
1015 KsRemoveSpecificIrpFromCancelableQueue(
1018 PKSPIN_LOCK SpinLock
;
1021 /* get internal queue lock */
1022 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1024 /* acquire spinlock */
1025 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1027 /* remove the irp from the list */
1028 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1030 /* release spinlock */
1031 KeReleaseSpinLock(SpinLock
, OldLevel
);
1041 KsAddIrpToCancelableQueue(
1042 IN OUT PLIST_ENTRY QueueHead
,
1043 IN PKSPIN_LOCK SpinLock
,
1045 IN KSLIST_ENTRY_LOCATION ListLocation
,
1046 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
1048 PDRIVER_CANCEL OldDriverCancel
;
1049 PIO_STACK_LOCATION IoStack
;
1052 /* check for required parameters */
1053 if (!QueueHead
|| !SpinLock
|| !Irp
)
1058 /* default to KsCancelRoutine */
1059 DriverCancel
= KsCancelRoutine
;
1062 /* get current irp stack */
1063 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1065 /* acquire spinlock */
1066 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1068 if (ListLocation
== KsListEntryTail
)
1070 /* insert irp to tail of list */
1071 InsertTailList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1075 /* insert irp to head of list */
1076 InsertHeadList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1079 /* store internal queue lock */
1080 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
) = SpinLock
;
1082 /* now set the cancel routine */
1083 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
1085 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
1087 /* the irp has already been canceled */
1088 KeReleaseSpinLock(SpinLock
, OldLevel
);
1090 /* cancel routine requires that cancel spinlock is held */
1091 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1094 DriverCancel(IoStack
->DeviceObject
, Irp
);
1099 KeReleaseSpinLock(SpinLock
, OldLevel
);
1110 IN PDEVICE_OBJECT DeviceObject
,
1113 PKSPIN_LOCK SpinLock
;
1116 /* get internal queue lock */
1117 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1119 /* acquire spinlock */
1120 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1123 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1125 /* release cancel spinlock */
1126 IoReleaseCancelSpinLock(DISPATCH_LEVEL
);
1128 /* remove the irp from the list */
1129 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1131 /* release spinlock */
1132 KeReleaseSpinLock(SpinLock
, OldLevel
);
1134 /* has the irp already been canceled */
1135 if (Irp
->IoStatus
.Status
!= STATUS_CANCELLED
)
1137 /* let's complete it */
1138 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
1139 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1144 FindMatchingCreateItem(
1145 PLIST_ENTRY ListHead
,
1148 OUT PCREATE_ITEM_ENTRY
*OutCreateItem
)
1151 PCREATE_ITEM_ENTRY CreateItemEntry
;
1153 /* remove '\' slash */
1155 BufferSize
-= sizeof(WCHAR
);
1157 /* point to first entry */
1158 Entry
= ListHead
->Flink
;
1160 /* loop all device items */
1161 while(Entry
!= ListHead
)
1163 /* get create item entry */
1164 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1166 ASSERT(CreateItemEntry
->CreateItem
);
1168 if(CreateItemEntry
->CreateItem
->Flags
& KSCREATE_ITEM_WILDCARD
)
1170 /* create item is default */
1171 *OutCreateItem
= CreateItemEntry
;
1172 return STATUS_SUCCESS
;
1175 if (!CreateItemEntry
->CreateItem
->Create
)
1177 /* skip free create item */
1178 Entry
= Entry
->Flink
;
1182 ASSERT(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
);
1184 DPRINT1("CreateItem %S Length %u Request %S %u\n", CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
,
1185 CreateItemEntry
->CreateItem
->ObjectClass
.Length
,
1189 if (CreateItemEntry
->CreateItem
->ObjectClass
.Length
> BufferSize
)
1191 /* create item doesnt match in length */
1192 Entry
= Entry
->Flink
;
1196 /* now check if the object class is the same */
1197 if (RtlCompareMemory(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
, Buffer
, CreateItemEntry
->CreateItem
->ObjectClass
.Length
) == CreateItemEntry
->CreateItem
->ObjectClass
.Length
)
1199 /* found matching create item */
1200 *OutCreateItem
= CreateItemEntry
;
1201 return STATUS_SUCCESS
;
1203 /* iterate to next */
1204 Entry
= Entry
->Flink
;
1207 return STATUS_NOT_FOUND
;
1213 IN PDEVICE_OBJECT DeviceObject
,
1216 PCREATE_ITEM_ENTRY CreateItemEntry
;
1217 PIO_STACK_LOCATION IoStack
;
1218 PDEVICE_EXTENSION DeviceExtension
;
1219 PKSIDEVICE_HEADER DeviceHeader
;
1220 PKSIOBJECT_HEADER ObjectHeader
;
1223 DPRINT("KS / CREATE\n");
1224 /* get current stack location */
1225 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1226 /* get device extension */
1227 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1228 /* get device header */
1229 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1231 if (IoStack
->FileObject
->FileName
.Buffer
== NULL
&& DeviceHeader
->ItemListCount
== 1)
1233 /* hack for bug 4566 */
1234 ASSERT(!IsListEmpty(&DeviceHeader
->ItemList
));
1235 /* get create item entry */
1236 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(DeviceHeader
->ItemList
.Flink
, CREATE_ITEM_ENTRY
, Entry
);
1238 ASSERT(CreateItemEntry
->CreateItem
);
1240 if (!CreateItemEntry
->CreateItem
->Create
)
1242 /* no valid create item */
1243 Irp
->IoStatus
.Information
= 0;
1244 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1245 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1247 return STATUS_UNSUCCESSFUL
;
1250 /* set object create item */
1251 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
1253 /* call create function */
1254 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
1256 if (NT_SUCCESS(Status
))
1258 /* increment create item reference count */
1259 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
1266 /* hack for bug 4566 */
1267 if (IoStack
->FileObject
->FileName
.Buffer
== NULL
)
1269 DPRINT("Using reference string hack\n");
1270 Irp
->IoStatus
.Information
= 0;
1271 /* set return status */
1272 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1273 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1274 return STATUS_SUCCESS
;
1278 if (IoStack
->FileObject
->RelatedFileObject
!= NULL
)
1280 /* request is to instantiate a pin / node / clock / allocator */
1281 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->RelatedFileObject
->FsContext
;
1284 ASSERT(ObjectHeader
);
1286 /* find a matching a create item */
1287 Status
= FindMatchingCreateItem(&ObjectHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
1291 /* request to create a filter */
1292 Status
= FindMatchingCreateItem(&DeviceHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
1295 if (NT_SUCCESS(Status
))
1297 /* set object create item */
1298 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
1300 /* call create function */
1301 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
1303 if (NT_SUCCESS(Status
))
1305 /* increment create item reference count */
1306 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
1312 Irp
->IoStatus
.Information
= 0;
1313 /* set return status */
1314 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1315 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1316 return STATUS_UNSUCCESSFUL
;
1320 RosDeviceInterfaceReferenceStringHack(
1321 IN PDEVICE_OBJECT DeviceObject
,
1324 PIO_STACK_LOCATION IoStack
;
1325 PKSIDEVICE_HEADER DeviceHeader
;
1326 PDEVICE_EXTENSION DeviceExtension
;
1327 PCREATE_ITEM_ENTRY CreateItemEntry
;
1332 /* get current stack location */
1333 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1335 /* get device extension */
1336 DeviceExtension
= (PDEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
1337 /* get device header */
1338 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1340 /* retrieve all available reference strings registered */
1342 Entry
= DeviceHeader
->ItemList
.Flink
;
1343 while(Entry
!= &DeviceHeader
->ItemList
)
1345 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1347 ASSERT(CreateItemEntry
->CreateItem
);
1348 if (CreateItemEntry
->CreateItem
->Create
&& CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
)
1349 Length
+= wcslen(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
) + 1;
1351 Entry
= Entry
->Flink
;
1354 /* add extra zero */
1357 /* allocate the buffer */
1358 Buffer
= ExAllocatePool(NonPagedPool
, Length
* sizeof(WCHAR
));
1361 Irp
->IoStatus
.Information
= 0;
1362 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1363 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1364 return STATUS_INSUFFICIENT_RESOURCES
;
1368 *((LPWSTR
*)Irp
->UserBuffer
) = Buffer
;
1369 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1370 Irp
->IoStatus
.Information
= sizeof(LPWSTR
);
1372 Entry
= DeviceHeader
->ItemList
.Flink
;
1373 while(Entry
!= &DeviceHeader
->ItemList
)
1375 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1377 ASSERT(CreateItemEntry
->CreateItem
);
1378 if (CreateItemEntry
->CreateItem
->Create
&& CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
)
1380 wcscpy(Buffer
, CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
);
1381 Buffer
+= wcslen(Buffer
) + 1;
1383 Entry
= Entry
->Flink
;
1389 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1390 return STATUS_SUCCESS
;
1397 IN PDEVICE_OBJECT DeviceObject
,
1400 PIO_STACK_LOCATION IoStack
;
1401 PKSIOBJECT_HEADER ObjectHeader
;
1402 PKSIDEVICE_HEADER DeviceHeader
;
1403 PDEVICE_EXTENSION DeviceExtension
;
1407 /* get current stack location */
1408 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1410 /* get device extension */
1411 DeviceExtension
= (PDEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
1412 /* get device header */
1413 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1415 if (IoStack
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
&& IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_OBJECT_CLASS
)
1417 /* hack for bug 4566 */
1418 return RosDeviceInterfaceReferenceStringHack(DeviceObject
, Irp
);
1421 ObjectHeader
= (PKSIOBJECT_HEADER
) IoStack
->FileObject
->FsContext
;
1423 ASSERT(ObjectHeader
);
1424 //KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
1426 return ObjectHeader
->DispatchTable
.DeviceIoControl(DeviceObject
, Irp
);
1432 IN PDEVICE_OBJECT DeviceObject
,
1435 PIO_STACK_LOCATION IoStack
;
1436 PDEVICE_EXTENSION DeviceExtension
;
1437 PKSIOBJECT_HEADER ObjectHeader
;
1438 PKSIDEVICE_HEADER DeviceHeader
;
1439 PDRIVER_DISPATCH Dispatch
;
1442 /* get current stack location */
1443 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1445 /* get device extension */
1446 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1447 /* get device header */
1448 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1450 /* get object header */
1451 ObjectHeader
= (PKSIOBJECT_HEADER
) IoStack
->FileObject
->FsContext
;
1455 /* hack for bug 4566 */
1456 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1457 Irp
->IoStatus
.Information
= 0;
1458 /* complete and forget */
1459 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1460 return STATUS_SUCCESS
;
1464 ASSERT(ObjectHeader
);
1465 /* store create item */
1466 //KSCREATE_ITEM_IRP_STORAGE(Irp) = (PKSOBJECT_CREATE_ITEM)0x12345678; //ObjectHeader->CreateItem;
1468 /* retrieve matching dispatch function */
1469 switch(IoStack
->MajorFunction
)
1472 Dispatch
= ObjectHeader
->DispatchTable
.Close
;
1474 case IRP_MJ_DEVICE_CONTROL
:
1475 Dispatch
= ObjectHeader
->DispatchTable
.DeviceIoControl
;
1478 Dispatch
= ObjectHeader
->DispatchTable
.Read
;
1481 Dispatch
= ObjectHeader
->DispatchTable
.Write
;
1483 case IRP_MJ_FLUSH_BUFFERS
:
1484 Dispatch
= ObjectHeader
->DispatchTable
.Flush
;
1486 case IRP_MJ_QUERY_SECURITY
:
1487 Dispatch
= ObjectHeader
->DispatchTable
.QuerySecurity
;
1489 case IRP_MJ_SET_SECURITY
:
1490 Dispatch
= ObjectHeader
->DispatchTable
.SetSecurity
;
1493 Dispatch
= KsDefaultDispatchPnp
;
1498 /* is the request supported */
1501 /* now call the dispatch function */
1502 Status
= Dispatch(DeviceObject
, Irp
);
1506 /* not supported request */
1507 Status
= KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
1520 KsSetMajorFunctionHandler(
1521 IN PDRIVER_OBJECT DriverObject
,
1522 IN ULONG MajorFunction
)
1524 switch ( MajorFunction
)
1527 DriverObject
->MajorFunction
[MajorFunction
] = KspCreate
;
1530 case IRP_MJ_DEVICE_CONTROL
:
1531 DriverObject
->MajorFunction
[MajorFunction
] = KspDeviceControl
;
1536 case IRP_MJ_FLUSH_BUFFERS
:
1537 case IRP_MJ_QUERY_SECURITY
:
1538 case IRP_MJ_SET_SECURITY
:
1539 DriverObject
->MajorFunction
[MajorFunction
] = KspDispatchIrp
;
1542 return STATUS_INVALID_PARAMETER
;
1545 return STATUS_SUCCESS
;
1555 IN PDEVICE_OBJECT DeviceObject
,
1558 PIO_STACK_LOCATION IoStack
;
1559 PKSIDEVICE_HEADER DeviceHeader
;
1560 PDEVICE_EXTENSION DeviceExtension
;
1562 /* get device extension */
1563 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1564 /* get device header */
1565 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1568 /* get current irp stack */
1569 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1571 if (IoStack
->MajorFunction
<= IRP_MJ_DEVICE_CONTROL
)
1573 if (IoStack
->MajorFunction
== IRP_MJ_CREATE
)
1575 /* check internal type */
1576 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
1578 /* AVStream client */
1579 return IKsDevice_Create(DeviceObject
, Irp
);
1583 /* external client (portcls) */
1584 return KspCreate(DeviceObject
, Irp
);
1588 if (IoStack
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
1590 /* handle device requests */
1591 return KspDeviceControl(DeviceObject
, Irp
);
1594 switch (IoStack
->MajorFunction
)
1599 case IRP_MJ_FLUSH_BUFFERS
:
1600 case IRP_MJ_QUERY_SECURITY
:
1601 case IRP_MJ_SET_SECURITY
:
1603 return KspDispatchIrp(DeviceObject
, Irp
);
1605 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
1609 /* dispatch power */
1610 if (IoStack
->MajorFunction
== IRP_MJ_POWER
)
1612 /* check internal type */
1613 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
1615 /* AVStream client */
1616 return IKsDevice_Power(DeviceObject
, Irp
);
1620 /* external client (portcls) */
1621 return KsDefaultDispatchPower(DeviceObject
, Irp
);
1624 else if (IoStack
->MajorFunction
== IRP_MJ_PNP
) /* dispatch pnp */
1626 /* check internal type */
1627 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
1629 /* AVStream client */
1630 return IKsDevice_Pnp(DeviceObject
, Irp
);
1634 /* external client (portcls) */
1635 return KsDefaultDispatchPnp(DeviceObject
, Irp
);
1638 else if (IoStack
->MajorFunction
== IRP_MJ_SYSTEM_CONTROL
)
1641 return KsDefaultForwardIrp(DeviceObject
, Irp
);
1646 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);