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
19 IN KSDEVICE_HEADER Header
)
22 return STATUS_UNSUCCESSFUL
;
31 KsDereferenceBusObject(
32 IN KSDEVICE_HEADER Header
)
43 KsDereferenceSoftwareBusObject(
44 IN KSDEVICE_HEADER Header
)
55 KsDispatchQuerySecurity(
56 IN PDEVICE_OBJECT DeviceObject
,
59 PKSOBJECT_CREATE_ITEM CreateItem
;
60 PIO_STACK_LOCATION IoStack
;
64 /* get current irp stack */
65 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
68 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
70 if (!CreateItem
|| !CreateItem
->SecurityDescriptor
)
73 Irp
->IoStatus
.Status
= STATUS_NO_SECURITY_ON_OBJECT
;
74 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
75 return STATUS_NO_SECURITY_ON_OBJECT
;
79 /* get input length */
80 Length
= IoStack
->Parameters
.QuerySecurity
.Length
;
82 /* clone the security descriptor */
83 Status
= SeQuerySecurityDescriptorInfo(&IoStack
->Parameters
.QuerySecurity
.SecurityInformation
, (PSECURITY_DESCRIPTOR
)Irp
->UserBuffer
, &Length
, &CreateItem
->SecurityDescriptor
);
85 DPRINT("SeQuerySecurityDescriptorInfo Status %x\n", Status
);
87 Irp
->IoStatus
.Status
= Status
;
88 Irp
->IoStatus
.Information
= Length
;
90 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
100 KsDispatchSetSecurity(
101 IN PDEVICE_OBJECT DeviceObject
,
104 PKSOBJECT_CREATE_ITEM CreateItem
;
105 PIO_STACK_LOCATION IoStack
;
106 PGENERIC_MAPPING Mapping
;
107 PSECURITY_DESCRIPTOR Descriptor
;
110 /* get current irp stack */
111 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
113 /* get create item */
114 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
116 if (!CreateItem
|| !CreateItem
->SecurityDescriptor
)
119 Irp
->IoStatus
.Status
= STATUS_NO_SECURITY_ON_OBJECT
;
120 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
121 return STATUS_NO_SECURITY_ON_OBJECT
;
124 /* backup old descriptor */
125 Descriptor
= CreateItem
->SecurityDescriptor
;
127 /* get generic mapping */
128 Mapping
= IoGetFileObjectGenericMapping();
130 /* change security descriptor */
131 Status
= SeSetSecurityDescriptorInfo(NULL
, /*FIXME */
132 &IoStack
->Parameters
.SetSecurity
.SecurityInformation
,
133 IoStack
->Parameters
.SetSecurity
.SecurityDescriptor
,
134 &CreateItem
->SecurityDescriptor
,
138 if (NT_SUCCESS(Status
))
140 /* free old descriptor */
141 ExFreePool(Descriptor
);
143 /* mark create item as changed */
144 CreateItem
->Flags
|= KSCREATE_ITEM_SECURITYCHANGED
;
148 Irp
->IoStatus
.Status
= Status
;
149 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
160 KsDispatchSpecificProperty(
162 IN PFNKSHANDLER Handler
)
165 return STATUS_UNSUCCESSFUL
;
174 KsDispatchSpecificMethod(
176 IN PFNKSHANDLER Handler
)
179 return STATUS_UNSUCCESSFUL
;
190 IN PFILE_OBJECT FileObject
,
191 IN PKEVENT Event OPTIONAL
,
192 IN PVOID PortContext OPTIONAL
,
193 OUT PIO_STATUS_BLOCK IoStatusBlock
,
196 IN ULONG Key OPTIONAL
,
197 IN KPROCESSOR_MODE RequestorMode
)
199 PDEVICE_OBJECT DeviceObject
;
207 /* make sure event is reset */
211 if (RequestorMode
== UserMode
)
213 /* probe the user buffer */
216 ProbeForWrite(Buffer
, Length
, sizeof(UCHAR
));
217 Status
= STATUS_SUCCESS
;
219 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
221 /* Exception, get the error code */
222 Status
= _SEH2_GetExceptionCode();
226 if (!NT_SUCCESS(Status
))
228 DPRINT1("Invalid user buffer provided\n");
233 /* get corresponding device object */
234 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
236 /* fast-io read is only available for kernel mode clients */
237 if (RequestorMode
== KernelMode
&& ExGetPreviousMode() == KernelMode
&&
238 DeviceObject
->DriverObject
->FastIoDispatch
->FastIoRead
)
240 /* call fast io write */
241 Result
= DeviceObject
->DriverObject
->FastIoDispatch
->FastIoRead(FileObject
, &FileObject
->CurrentByteOffset
, Length
, TRUE
, Key
, Buffer
, IoStatusBlock
, DeviceObject
);
243 if (Result
&& NT_SUCCESS(IoStatusBlock
->Status
))
245 /* request was handeled and succeeded */
246 return STATUS_SUCCESS
;
250 /* do the slow way */
253 /* initialize temp event */
254 KeInitializeEvent(&LocalEvent
, NotificationEvent
, FALSE
);
258 /* build the irp packet */
259 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
, DeviceObject
, Buffer
, Length
, &FileObject
->CurrentByteOffset
, Event
, IoStatusBlock
);
262 /* not enough resources */
263 return STATUS_INSUFFICIENT_RESOURCES
;
266 /* send the packet */
267 Status
= IoCallDriver(DeviceObject
, Irp
);
269 if (Status
== STATUS_PENDING
)
271 /* operation is pending, is sync file object */
272 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
275 KeWaitForSingleObject(Event
, Executive
, RequestorMode
, FALSE
, NULL
);
276 Status
= IoStatusBlock
->Status
;
290 IN PFILE_OBJECT FileObject
,
291 IN PKEVENT Event OPTIONAL
,
292 IN PVOID PortContext OPTIONAL
,
293 OUT PIO_STATUS_BLOCK IoStatusBlock
,
296 IN ULONG Key OPTIONAL
,
297 IN KPROCESSOR_MODE RequestorMode
)
299 PDEVICE_OBJECT DeviceObject
;
307 /* make sure event is reset */
311 if (RequestorMode
== UserMode
)
313 /* probe the user buffer */
316 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
317 Status
= STATUS_SUCCESS
;
319 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
321 /* Exception, get the error code */
322 Status
= _SEH2_GetExceptionCode();
326 if (!NT_SUCCESS(Status
))
328 DPRINT1("Invalid user buffer provided\n");
333 /* get corresponding device object */
334 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
336 /* fast-io write is only available for kernel mode clients */
337 if (RequestorMode
== KernelMode
&& ExGetPreviousMode() == KernelMode
&&
338 DeviceObject
->DriverObject
->FastIoDispatch
->FastIoWrite
)
340 /* call fast io write */
341 Result
= DeviceObject
->DriverObject
->FastIoDispatch
->FastIoWrite(FileObject
, &FileObject
->CurrentByteOffset
, Length
, TRUE
, Key
, Buffer
, IoStatusBlock
, DeviceObject
);
343 if (Result
&& NT_SUCCESS(IoStatusBlock
->Status
))
345 /* request was handeled and succeeded */
346 return STATUS_SUCCESS
;
350 /* do the slow way */
353 /* initialize temp event */
354 KeInitializeEvent(&LocalEvent
, NotificationEvent
, FALSE
);
358 /* build the irp packet */
359 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
, DeviceObject
, Buffer
, Length
, &FileObject
->CurrentByteOffset
, Event
, IoStatusBlock
);
362 /* not enough resources */
363 return STATUS_INSUFFICIENT_RESOURCES
;
366 /* send the packet */
367 Status
= IoCallDriver(DeviceObject
, Irp
);
369 if (Status
== STATUS_PENDING
)
371 /* operation is pending, is sync file object */
372 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
375 KeWaitForSingleObject(Event
, Executive
, RequestorMode
, FALSE
, NULL
);
376 Status
= IoStatusBlock
->Status
;
389 KsQueryInformationFile(
390 IN PFILE_OBJECT FileObject
,
391 OUT PVOID FileInformation
,
393 IN FILE_INFORMATION_CLASS FileInformationClass
)
395 PDEVICE_OBJECT DeviceObject
;
396 PFAST_IO_DISPATCH FastIoDispatch
;
397 IO_STATUS_BLOCK IoStatus
;
399 /* get related file object */
400 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
402 /* get fast i/o table */
403 FastIoDispatch
= DeviceObject
->DriverObject
->FastIoDispatch
;
405 /* is there a fast table */
408 /* check the class */
409 if (FileInformationClass
== FileBasicInformation
)
411 /* use FastIoQueryBasicInfo routine */
412 if (FastIoDispatch
->FastIoQueryBasicInfo
)
414 return FastIoDispatch
->FastIoQueryBasicInfo(FileObject
, TRUE
, (PFILE_BASIC_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
417 else if (FileInformationClass
== FileStandardInformation
)
419 /* use FastIoQueryBasicInfo routine */
420 if (FastIoDispatch
->FastIoQueryBasicInfo
)
422 return FastIoDispatch
->FastIoQueryStandardInfo(FileObject
, TRUE
, (PFILE_STANDARD_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
429 return STATUS_UNSUCCESSFUL
;
438 KsSetInformationFile(
439 IN PFILE_OBJECT FileObject
,
440 IN PVOID FileInformation
,
442 IN FILE_INFORMATION_CLASS FileInformationClass
)
444 PIO_STACK_LOCATION IoStack
;
445 PDEVICE_OBJECT DeviceObject
;
449 LARGE_INTEGER Offset
;
450 IO_STATUS_BLOCK IoStatus
;
453 /* get related device object */
454 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
456 /* copy file information */
457 Buffer
= AllocateItem(NonPagedPool
, Length
);
459 return STATUS_INSUFFICIENT_RESOURCES
;
463 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
464 RtlMoveMemory(Buffer
, FileInformation
, Length
);
465 Status
= STATUS_SUCCESS
;
467 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
469 /* Exception, get the error code */
470 Status
= _SEH2_GetExceptionCode();
474 if (!NT_SUCCESS(Status
))
476 /* invalid user buffer */
481 /* initialize the event */
482 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
485 Offset
.QuadPart
= 0LL;
488 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_SET_INFORMATION
, DeviceObject
, NULL
, 0, &Offset
, &Event
, &IoStatus
);
492 /* failed to allocate irp */
494 return STATUS_INSUFFICIENT_RESOURCES
;
497 /* get next stack location */
498 IoStack
= IoGetNextIrpStackLocation(Irp
);
500 /* set irp parameters */
501 IoStack
->Parameters
.SetFile
.FileInformationClass
= FileInformationClass
;
502 IoStack
->Parameters
.SetFile
.Length
= Length
;
503 IoStack
->Parameters
.SetFile
.FileObject
= FileObject
;
504 Irp
->AssociatedIrp
.SystemBuffer
= Buffer
;
505 Irp
->UserBuffer
= FileInformation
;
507 /* dispatch the irp */
508 Status
= IoCallDriver(DeviceObject
, Irp
);
510 if (Status
== STATUS_PENDING
)
512 /* wait untill the operation has completed */
513 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
514 /* is a sync file object */
515 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
516 Status
= FileObject
->FinalStatus
;
518 Status
= IoStatus
.Status
;
531 IN PFILE_OBJECT FileObject
,
532 IN PKEVENT Event OPTIONAL
,
533 IN PVOID PortContext OPTIONAL
,
534 IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL
,
535 IN PVOID CompletionContext OPTIONAL
,
536 IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL
,
537 OUT PIO_STATUS_BLOCK IoStatusBlock
,
538 IN OUT PVOID StreamHeaders
,
541 IN KPROCESSOR_MODE RequestorMode
)
544 PIO_STACK_LOCATION IoStack
;
545 PDEVICE_OBJECT DeviceObject
;
548 LARGE_INTEGER Offset
;
549 PKSIOBJECT_HEADER ObjectHeader
;
552 if (Flags
== KSSTREAM_READ
)
554 else if (Flags
== KSSTREAM_WRITE
)
557 return STATUS_INVALID_PARAMETER
;
559 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
561 return STATUS_INVALID_PARAMETER
;
568 //ASSERT(DeviceObject->DeviceType == FILE_DEVICE_KS);
569 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext
;
570 ASSERT(ObjectHeader
);
571 if (Code
== IRP_MJ_READ
)
573 if (ObjectHeader
->DispatchTable
.FastRead
)
575 if (ObjectHeader
->DispatchTable
.FastRead(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
))
577 return STATUS_SUCCESS
;
583 if (ObjectHeader
->DispatchTable
.FastWrite
)
585 if (ObjectHeader
->DispatchTable
.FastWrite(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
))
587 return STATUS_SUCCESS
;
592 Offset
.QuadPart
= 0LL;
593 Irp
= IoBuildSynchronousFsdRequest(Code
, DeviceObject
, (PVOID
)StreamHeaders
, Length
, &Offset
, Event
, IoStatusBlock
);
596 return STATUS_UNSUCCESSFUL
;
600 if (CompletionRoutine
)
602 IoSetCompletionRoutine(Irp
,
605 (CompletionInvocationFlags
& KsInvokeOnSuccess
),
606 (CompletionInvocationFlags
& KsInvokeOnError
),
607 (CompletionInvocationFlags
& KsInvokeOnCancel
));
610 IoStack
= IoGetNextIrpStackLocation(Irp
);
611 IoStack
->FileObject
= FileObject
;
613 Status
= IoCallDriver(DeviceObject
, Irp
);
630 return STATUS_UNSUCCESSFUL
;
642 OUT PVOID
* ExtraBuffer
)
645 return STATUS_UNSUCCESSFUL
;
655 IN PDRIVER_OBJECT DriverObject
)
665 KsDispatchInvalidDeviceRequest(
666 IN PDEVICE_OBJECT DeviceObject
,
669 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
670 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
672 return STATUS_INVALID_DEVICE_REQUEST
;
681 KsDefaultDeviceIoCompletion(
682 IN PDEVICE_OBJECT DeviceObject
,
685 PIO_STACK_LOCATION IoStack
;
688 /* get current irp stack */
689 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
691 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
&&
692 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_METHOD
&&
693 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
695 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_RESET_STATE
)
698 Status
= STATUS_SUCCESS
;
702 /* request unsupported */
703 Status
= STATUS_INVALID_DEVICE_REQUEST
;
708 /* property / method / event not found */
709 Status
= STATUS_PROPSET_NOT_FOUND
;
712 /* complete request */
713 Irp
->IoStatus
.Status
= Status
;
714 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
726 KsDispatchFastIoDeviceControlFailure(
727 IN PFILE_OBJECT FileObject
,
729 IN PVOID InputBuffer OPTIONAL
,
730 IN ULONG InputBufferLength
,
731 OUT PVOID OutputBuffer OPTIONAL
,
732 IN ULONG OutputBufferLength
,
733 IN ULONG IoControlCode
,
734 OUT PIO_STATUS_BLOCK IoStatus
,
735 IN PDEVICE_OBJECT DeviceObject
)
746 KsDispatchFastReadFailure(
747 IN PFILE_OBJECT FileObject
,
748 IN PLARGE_INTEGER FileOffset
,
753 OUT PIO_STATUS_BLOCK IoStatus
,
754 IN PDEVICE_OBJECT DeviceObject
)
767 IN OUT PLIST_ENTRY QueueHead
,
768 IN PKSPIN_LOCK SpinLock
)
770 PDRIVER_CANCEL OldDriverCancel
;
771 PIO_STACK_LOCATION IoStack
;
776 /* acquire spinlock */
777 KeAcquireSpinLock(SpinLock
, &OldLevel
);
778 /* point to first entry */
779 Entry
= QueueHead
->Flink
;
781 while(Entry
!= QueueHead
)
784 Irp
= (PIRP
)CONTAINING_RECORD(Entry
, IRP
, Tail
.Overlay
.ListEntry
);
786 /* set cancelled bit */
789 /* now set the cancel routine */
790 OldDriverCancel
= IoSetCancelRoutine(Irp
, NULL
);
793 /* this irp hasnt been yet used, so free to cancel */
794 KeReleaseSpinLock(SpinLock
, OldLevel
);
796 /* get current irp stack */
797 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
799 /* acquire cancel spinlock */
800 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
802 /* call provided cancel routine */
803 OldDriverCancel(IoStack
->DeviceObject
, Irp
);
805 /* re-acquire spinlock */
806 KeAcquireSpinLock(SpinLock
, &OldLevel
);
808 /* move on to next entry */
809 Entry
= Entry
->Flink
;
812 /* the irp has already been canceled */
813 KeReleaseSpinLock(SpinLock
, OldLevel
);
823 KsReleaseIrpOnCancelableQueue(
825 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
827 PKSPIN_LOCK SpinLock
;
828 PDRIVER_CANCEL OldDriverCancel
;
829 PIO_STACK_LOCATION IoStack
;
832 /* check for required parameters */
838 /* default to KsCancelRoutine */
839 DriverCancel
= KsCancelRoutine
;
842 /* get current irp stack */
843 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
845 /* get internal queue lock */
846 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
848 /* acquire spinlock */
849 KeAcquireSpinLock(SpinLock
, &OldLevel
);
851 /* now set the cancel routine */
852 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
854 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
856 /* the irp has already been canceled */
857 KeReleaseSpinLock(SpinLock
, OldLevel
);
859 /* cancel routine requires that cancel spinlock is held */
860 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
863 DriverCancel(IoStack
->DeviceObject
, Irp
);
868 KeReleaseSpinLock(SpinLock
, OldLevel
);
878 KsRemoveIrpFromCancelableQueue(
879 IN OUT PLIST_ENTRY QueueHead
,
880 IN PKSPIN_LOCK SpinLock
,
881 IN KSLIST_ENTRY_LOCATION ListLocation
,
882 IN KSIRP_REMOVAL_OPERATION RemovalOperation
)
885 PLIST_ENTRY CurEntry
;
888 /* check parameters */
889 if (!QueueHead
|| !SpinLock
)
892 /* check if parameter ListLocation is valid */
893 if (ListLocation
!= KsListEntryTail
&& ListLocation
!= KsListEntryHead
)
896 /* acquire list lock */
897 KeAcquireSpinLock(SpinLock
, &OldIrql
);
899 /* point to queue head */
900 CurEntry
= QueueHead
;
904 /* reset irp to null */
907 /* iterate to next entry */
908 if (ListLocation
== KsListEntryHead
)
909 CurEntry
= CurEntry
->Flink
;
911 CurEntry
= CurEntry
->Blink
;
913 /* is the end of list reached */
914 if (CurEntry
== QueueHead
)
916 /* reached end of list */
921 Irp
= (PIRP
)CONTAINING_RECORD(Irp
, IRP
, Tail
.Overlay
.ListEntry
);
925 /* irp has been canceled */
929 if (Irp
->CancelRoutine
)
931 /* remove cancel routine */
932 Irp
->CancelRoutine
= NULL
;
934 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
936 /* remove irp from list */
937 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
940 if (RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
|| RemovalOperation
== KsAcquireOnlySingleItem
)
947 KeReleaseSpinLock(SpinLock
, OldIrql
);
949 if (!Irp
|| Irp
->CancelRoutine
== NULL
)
951 /* either an irp has been acquired or nothing found */
955 /* time to remove the canceled irp */
956 IoAcquireCancelSpinLock(&OldIrql
);
957 /* acquire list lock */
958 KeAcquireSpinLockAtDpcLevel(SpinLock
);
960 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
963 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
966 /* release list lock */
967 KeReleaseSpinLockFromDpcLevel(SpinLock
);
969 /* release cancel spinlock */
970 IoReleaseCancelSpinLock(OldIrql
);
971 /* no non canceled irp has been found */
981 KsMoveIrpsOnCancelableQueue(
982 IN OUT PLIST_ENTRY SourceList
,
983 IN PKSPIN_LOCK SourceLock
,
984 IN OUT PLIST_ENTRY DestinationList
,
985 IN PKSPIN_LOCK DestinationLock OPTIONAL
,
986 IN KSLIST_ENTRY_LOCATION ListLocation
,
987 IN PFNKSIRPLISTCALLBACK ListCallback
,
991 return STATUS_UNSUCCESSFUL
;
1000 KsRemoveSpecificIrpFromCancelableQueue(
1003 PKSPIN_LOCK SpinLock
;
1006 /* get internal queue lock */
1007 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1009 /* acquire spinlock */
1010 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1012 /* remove the irp from the list */
1013 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1015 /* release spinlock */
1016 KeReleaseSpinLock(SpinLock
, OldLevel
);
1026 KsAddIrpToCancelableQueue(
1027 IN OUT PLIST_ENTRY QueueHead
,
1028 IN PKSPIN_LOCK SpinLock
,
1030 IN KSLIST_ENTRY_LOCATION ListLocation
,
1031 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
1033 PDRIVER_CANCEL OldDriverCancel
;
1034 PIO_STACK_LOCATION IoStack
;
1037 /* check for required parameters */
1038 if (!QueueHead
|| !SpinLock
|| !Irp
)
1043 /* default to KsCancelRoutine */
1044 DriverCancel
= KsCancelRoutine
;
1047 /* get current irp stack */
1048 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1050 /* acquire spinlock */
1051 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1053 if (ListLocation
== KsListEntryTail
)
1055 /* insert irp to tail of list */
1056 InsertTailList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1060 /* insert irp to head of list */
1061 InsertHeadList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1064 /* store internal queue lock */
1065 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
) = SpinLock
;
1067 /* now set the cancel routine */
1068 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
1070 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
1072 /* the irp has already been canceled */
1073 KeReleaseSpinLock(SpinLock
, OldLevel
);
1075 /* cancel routine requires that cancel spinlock is held */
1076 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1079 DriverCancel(IoStack
->DeviceObject
, Irp
);
1084 KeReleaseSpinLock(SpinLock
, OldLevel
);
1095 IN PDEVICE_OBJECT DeviceObject
,
1098 PKSPIN_LOCK SpinLock
;
1101 /* get internal queue lock */
1102 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1104 /* acquire spinlock */
1105 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1108 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1110 /* release cancel spinlock */
1111 IoReleaseCancelSpinLock(DISPATCH_LEVEL
);
1113 /* remove the irp from the list */
1114 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1116 /* release spinlock */
1117 KeReleaseSpinLock(SpinLock
, OldLevel
);
1119 /* has the irp already been canceled */
1120 if (Irp
->IoStatus
.Status
!= STATUS_CANCELLED
)
1122 /* let's complete it */
1123 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
1124 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1134 KsGetChildCreateParameter(
1136 OUT PVOID
* CreateParameter
)
1139 return STATUS_UNSUCCESSFUL
;
1143 FindMatchingCreateItem(
1144 PLIST_ENTRY ListHead
,
1147 OUT PCREATE_ITEM_ENTRY
*OutCreateItem
)
1150 PCREATE_ITEM_ENTRY CreateItemEntry
;
1152 /* remove '\' slash */
1154 BufferSize
-= sizeof(WCHAR
);
1156 /* point to first entry */
1157 Entry
= ListHead
->Flink
;
1159 /* loop all device items */
1160 while(Entry
!= ListHead
)
1162 /* get create item entry */
1163 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1165 ASSERT(CreateItemEntry
->CreateItem
);
1167 if(CreateItemEntry
->CreateItem
->Flags
& KSCREATE_ITEM_WILDCARD
)
1169 /* create item is default */
1170 *OutCreateItem
= CreateItemEntry
;
1171 return STATUS_SUCCESS
;
1174 if (!CreateItemEntry
->CreateItem
->Create
)
1176 /* skip free create item */
1177 Entry
= Entry
->Flink
;
1181 ASSERT(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
);
1183 DPRINT1("CreateItem %S Length %u Request %S %u\n", CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
,
1184 CreateItemEntry
->CreateItem
->ObjectClass
.Length
,
1188 if (CreateItemEntry
->CreateItem
->ObjectClass
.Length
> BufferSize
)
1190 /* create item doesnt match in length */
1191 Entry
= Entry
->Flink
;
1195 /* now check if the object class is the same */
1196 if (RtlCompareMemory(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
, Buffer
, CreateItemEntry
->CreateItem
->ObjectClass
.Length
) == CreateItemEntry
->CreateItem
->ObjectClass
.Length
)
1198 /* found matching create item */
1199 *OutCreateItem
= CreateItemEntry
;
1200 return STATUS_SUCCESS
;
1202 /* iterate to next */
1203 Entry
= Entry
->Flink
;
1206 return STATUS_NOT_FOUND
;
1212 IN PDEVICE_OBJECT DeviceObject
,
1215 PCREATE_ITEM_ENTRY CreateItemEntry
;
1216 PIO_STACK_LOCATION IoStack
;
1217 PDEVICE_EXTENSION DeviceExtension
;
1218 PKSIDEVICE_HEADER DeviceHeader
;
1219 PKSIOBJECT_HEADER ObjectHeader
;
1222 DPRINT("KS / CREATE\n");
1223 /* get current stack location */
1224 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1225 /* get device extension */
1226 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1227 /* get device header */
1228 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1230 if (IoStack
->FileObject
->FileName
.Buffer
== NULL
&& DeviceHeader
->ItemListCount
== 1)
1232 /* hack for bug 4566 */
1233 ASSERT(!IsListEmpty(&DeviceHeader
->ItemList
));
1234 /* get create item entry */
1235 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(DeviceHeader
->ItemList
.Flink
, CREATE_ITEM_ENTRY
, Entry
);
1237 ASSERT(CreateItemEntry
->CreateItem
);
1239 if (!CreateItemEntry
->CreateItem
->Create
)
1241 /* no valid create item */
1242 Irp
->IoStatus
.Information
= 0;
1243 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1244 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1246 return STATUS_UNSUCCESSFUL
;
1249 /* set object create item */
1250 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
1252 /* call create function */
1253 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
1255 if (NT_SUCCESS(Status
))
1257 /* increment create item reference count */
1258 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
1265 /* hack for bug 4566 */
1266 if (IoStack
->FileObject
->FileName
.Buffer
== NULL
)
1268 DPRINT("Using reference string hack\n");
1269 Irp
->IoStatus
.Information
= 0;
1270 /* set return status */
1271 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1272 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1273 return STATUS_SUCCESS
;
1277 if (IoStack
->FileObject
->RelatedFileObject
!= NULL
)
1279 /* request is to instantiate a pin / node / clock / allocator */
1280 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->RelatedFileObject
->FsContext
;
1283 ASSERT(ObjectHeader
);
1285 /* find a matching a create item */
1286 Status
= FindMatchingCreateItem(&ObjectHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
1290 /* request to create a filter */
1291 Status
= FindMatchingCreateItem(&DeviceHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
1294 if (NT_SUCCESS(Status
))
1296 /* set object create item */
1297 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
1299 /* call create function */
1300 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
1302 if (NT_SUCCESS(Status
))
1304 /* increment create item reference count */
1305 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
1311 Irp
->IoStatus
.Information
= 0;
1312 /* set return status */
1313 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1314 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1315 return STATUS_UNSUCCESSFUL
;
1319 RosDeviceInterfaceReferenceStringHack(
1320 IN PDEVICE_OBJECT DeviceObject
,
1323 PIO_STACK_LOCATION IoStack
;
1324 PKSIDEVICE_HEADER DeviceHeader
;
1325 PDEVICE_EXTENSION DeviceExtension
;
1326 PCREATE_ITEM_ENTRY CreateItemEntry
;
1331 /* get current stack location */
1332 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1334 /* get device extension */
1335 DeviceExtension
= (PDEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
1336 /* get device header */
1337 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1339 /* retrieve all available reference strings registered */
1341 Entry
= DeviceHeader
->ItemList
.Flink
;
1342 while(Entry
!= &DeviceHeader
->ItemList
)
1344 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1346 ASSERT(CreateItemEntry
->CreateItem
);
1347 if (CreateItemEntry
->CreateItem
->Create
&& CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
)
1348 Length
+= wcslen(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
) + 1;
1350 Entry
= Entry
->Flink
;
1353 /* add extra zero */
1356 /* allocate the buffer */
1357 Buffer
= ExAllocatePool(NonPagedPool
, Length
* sizeof(WCHAR
));
1360 Irp
->IoStatus
.Information
= 0;
1361 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1362 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1363 return STATUS_INSUFFICIENT_RESOURCES
;
1367 *((LPWSTR
*)Irp
->UserBuffer
) = Buffer
;
1368 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1369 Irp
->IoStatus
.Information
= sizeof(LPWSTR
);
1371 Entry
= DeviceHeader
->ItemList
.Flink
;
1372 while(Entry
!= &DeviceHeader
->ItemList
)
1374 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1376 ASSERT(CreateItemEntry
->CreateItem
);
1377 if (CreateItemEntry
->CreateItem
->Create
&& CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
)
1379 wcscpy(Buffer
, CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
);
1380 Buffer
+= wcslen(Buffer
) + 1;
1382 Entry
= Entry
->Flink
;
1388 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1389 return STATUS_SUCCESS
;
1396 IN PDEVICE_OBJECT DeviceObject
,
1399 PIO_STACK_LOCATION IoStack
;
1400 PKSIOBJECT_HEADER ObjectHeader
;
1401 PKSIDEVICE_HEADER DeviceHeader
;
1402 PDEVICE_EXTENSION DeviceExtension
;
1406 /* get current stack location */
1407 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1409 /* get device extension */
1410 DeviceExtension
= (PDEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
1411 /* get device header */
1412 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1414 if (IoStack
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
&& IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_OBJECT_CLASS
)
1416 /* hack for bug 4566 */
1417 return RosDeviceInterfaceReferenceStringHack(DeviceObject
, Irp
);
1420 ObjectHeader
= (PKSIOBJECT_HEADER
) IoStack
->FileObject
->FsContext
;
1422 ASSERT(ObjectHeader
);
1423 //KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
1425 return ObjectHeader
->DispatchTable
.DeviceIoControl(DeviceObject
, Irp
);
1431 IN PDEVICE_OBJECT DeviceObject
,
1434 PIO_STACK_LOCATION IoStack
;
1435 PDEVICE_EXTENSION DeviceExtension
;
1436 PKSIOBJECT_HEADER ObjectHeader
;
1437 PKSIDEVICE_HEADER DeviceHeader
;
1438 PDRIVER_DISPATCH Dispatch
;
1441 /* get current stack location */
1442 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1444 /* get device extension */
1445 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1446 /* get device header */
1447 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1449 /* get object header */
1450 ObjectHeader
= (PKSIOBJECT_HEADER
) IoStack
->FileObject
->FsContext
;
1454 /* hack for bug 4566 */
1455 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1456 Irp
->IoStatus
.Information
= 0;
1457 /* complete and forget */
1458 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1459 return STATUS_SUCCESS
;
1463 ASSERT(ObjectHeader
);
1464 /* store create item */
1465 //KSCREATE_ITEM_IRP_STORAGE(Irp) = (PKSOBJECT_CREATE_ITEM)0x12345678; //ObjectHeader->CreateItem;
1467 /* retrieve matching dispatch function */
1468 switch(IoStack
->MajorFunction
)
1471 Dispatch
= ObjectHeader
->DispatchTable
.Close
;
1473 case IRP_MJ_DEVICE_CONTROL
:
1474 Dispatch
= ObjectHeader
->DispatchTable
.DeviceIoControl
;
1477 Dispatch
= ObjectHeader
->DispatchTable
.Read
;
1480 Dispatch
= ObjectHeader
->DispatchTable
.Write
;
1482 case IRP_MJ_FLUSH_BUFFERS
:
1483 Dispatch
= ObjectHeader
->DispatchTable
.Flush
;
1485 case IRP_MJ_QUERY_SECURITY
:
1486 Dispatch
= ObjectHeader
->DispatchTable
.QuerySecurity
;
1488 case IRP_MJ_SET_SECURITY
:
1489 Dispatch
= ObjectHeader
->DispatchTable
.SetSecurity
;
1492 Dispatch
= KsDefaultDispatchPnp
;
1497 /* is the request supported */
1500 /* now call the dispatch function */
1501 Status
= Dispatch(DeviceObject
, Irp
);
1505 /* not supported request */
1506 Status
= KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
1519 KsSetMajorFunctionHandler(
1520 IN PDRIVER_OBJECT DriverObject
,
1521 IN ULONG MajorFunction
)
1523 switch ( MajorFunction
)
1526 DriverObject
->MajorFunction
[MajorFunction
] = KspCreate
;
1529 case IRP_MJ_DEVICE_CONTROL
:
1530 DriverObject
->MajorFunction
[MajorFunction
] = KspDeviceControl
;
1535 case IRP_MJ_FLUSH_BUFFERS
:
1536 case IRP_MJ_QUERY_SECURITY
:
1537 case IRP_MJ_SET_SECURITY
:
1538 DriverObject
->MajorFunction
[MajorFunction
] = KspDispatchIrp
;
1541 return STATUS_INVALID_PARAMETER
;
1544 return STATUS_SUCCESS
;
1554 IN PDEVICE_OBJECT DeviceObject
,
1557 PIO_STACK_LOCATION IoStack
;
1558 PKSIDEVICE_HEADER DeviceHeader
;
1559 PDEVICE_EXTENSION DeviceExtension
;
1561 /* get device extension */
1562 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1563 /* get device header */
1564 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1567 /* get current irp stack */
1568 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1570 if (IoStack
->MajorFunction
<= IRP_MJ_DEVICE_CONTROL
)
1572 if (IoStack
->MajorFunction
== IRP_MJ_CREATE
)
1574 /* check internal type */
1575 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
1577 /* AVStream client */
1578 return IKsDevice_Create(DeviceObject
, Irp
);
1582 /* external client (portcls) */
1583 return KspCreate(DeviceObject
, Irp
);
1587 if (IoStack
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
1589 /* handle device requests */
1590 return KspDeviceControl(DeviceObject
, Irp
);
1593 switch (IoStack
->MajorFunction
)
1598 case IRP_MJ_FLUSH_BUFFERS
:
1599 case IRP_MJ_QUERY_SECURITY
:
1600 case IRP_MJ_SET_SECURITY
:
1602 return KspDispatchIrp(DeviceObject
, Irp
);
1604 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
1608 /* dispatch power */
1609 if (IoStack
->MajorFunction
== IRP_MJ_POWER
)
1611 /* check internal type */
1612 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
1614 /* AVStream client */
1615 return IKsDevice_Power(DeviceObject
, Irp
);
1619 /* external client (portcls) */
1620 return KsDefaultDispatchPower(DeviceObject
, Irp
);
1623 else if (IoStack
->MajorFunction
== IRP_MJ_PNP
) /* dispatch pnp */
1625 /* check internal type */
1626 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
1628 /* AVStream client */
1629 return IKsDevice_Pnp(DeviceObject
, Irp
);
1633 /* external client (portcls) */
1634 return KsDefaultDispatchPnp(DeviceObject
, Irp
);
1637 else if (IoStack
->MajorFunction
== IRP_MJ_SYSTEM_CONTROL
)
1640 return KsDefaultForwardIrp(DeviceObject
, Irp
);
1645 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);