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
20 KsDispatchQuerySecurity(
21 IN PDEVICE_OBJECT DeviceObject
,
24 PKSOBJECT_CREATE_ITEM CreateItem
;
25 PIO_STACK_LOCATION IoStack
;
29 /* get current irp stack */
30 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
33 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
35 if (!CreateItem
|| !CreateItem
->SecurityDescriptor
)
38 Irp
->IoStatus
.Status
= STATUS_NO_SECURITY_ON_OBJECT
;
39 CompleteRequest(Irp
, IO_NO_INCREMENT
);
40 return STATUS_NO_SECURITY_ON_OBJECT
;
44 /* get input length */
45 Length
= IoStack
->Parameters
.QuerySecurity
.Length
;
47 /* clone the security descriptor */
48 Status
= SeQuerySecurityDescriptorInfo(&IoStack
->Parameters
.QuerySecurity
.SecurityInformation
, (PSECURITY_DESCRIPTOR
)Irp
->UserBuffer
, &Length
, &CreateItem
->SecurityDescriptor
);
50 DPRINT("SeQuerySecurityDescriptorInfo Status %x\n", Status
);
52 Irp
->IoStatus
.Status
= Status
;
53 Irp
->IoStatus
.Information
= Length
;
55 CompleteRequest(Irp
, IO_NO_INCREMENT
);
65 KsDispatchSetSecurity(
66 IN PDEVICE_OBJECT DeviceObject
,
69 PKSOBJECT_CREATE_ITEM CreateItem
;
70 PIO_STACK_LOCATION IoStack
;
71 PGENERIC_MAPPING Mapping
;
72 PSECURITY_DESCRIPTOR Descriptor
;
75 /* get current irp stack */
76 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
79 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
81 if (!CreateItem
|| !CreateItem
->SecurityDescriptor
)
84 Irp
->IoStatus
.Status
= STATUS_NO_SECURITY_ON_OBJECT
;
85 CompleteRequest(Irp
, IO_NO_INCREMENT
);
86 return STATUS_NO_SECURITY_ON_OBJECT
;
89 /* backup old descriptor */
90 Descriptor
= CreateItem
->SecurityDescriptor
;
92 /* get generic mapping */
93 Mapping
= IoGetFileObjectGenericMapping();
95 /* change security descriptor */
96 Status
= SeSetSecurityDescriptorInfo(NULL
, /*FIXME */
97 &IoStack
->Parameters
.SetSecurity
.SecurityInformation
,
98 IoStack
->Parameters
.SetSecurity
.SecurityDescriptor
,
99 &CreateItem
->SecurityDescriptor
,
103 if (NT_SUCCESS(Status
))
105 /* free old descriptor */
106 FreeItem(Descriptor
);
108 /* mark create item as changed */
109 CreateItem
->Flags
|= KSCREATE_ITEM_SECURITYCHANGED
;
113 Irp
->IoStatus
.Status
= Status
;
114 CompleteRequest(Irp
, IO_NO_INCREMENT
);
125 KsDispatchSpecificMethod(
127 IN PFNKSHANDLER Handler
)
130 return STATUS_UNSUCCESSFUL
;
141 IN PFILE_OBJECT FileObject
,
142 IN PKEVENT Event OPTIONAL
,
143 IN PVOID PortContext OPTIONAL
,
144 OUT PIO_STATUS_BLOCK IoStatusBlock
,
147 IN ULONG Key OPTIONAL
,
148 IN KPROCESSOR_MODE RequestorMode
)
150 PDEVICE_OBJECT DeviceObject
;
158 /* make sure event is reset */
162 if (RequestorMode
== UserMode
)
164 /* probe the user buffer */
167 ProbeForWrite(Buffer
, Length
, sizeof(UCHAR
));
168 Status
= STATUS_SUCCESS
;
170 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
172 /* Exception, get the error code */
173 Status
= _SEH2_GetExceptionCode();
177 if (!NT_SUCCESS(Status
))
179 DPRINT1("Invalid user buffer provided\n");
184 /* get corresponding device object */
185 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
187 /* fast-io read is only available for kernel mode clients */
188 if (RequestorMode
== KernelMode
&& ExGetPreviousMode() == KernelMode
&&
189 DeviceObject
->DriverObject
->FastIoDispatch
->FastIoRead
)
191 /* call fast io write */
192 Result
= DeviceObject
->DriverObject
->FastIoDispatch
->FastIoRead(FileObject
, &FileObject
->CurrentByteOffset
, Length
, TRUE
, Key
, Buffer
, IoStatusBlock
, DeviceObject
);
194 if (Result
&& NT_SUCCESS(IoStatusBlock
->Status
))
196 /* request was handeled and succeeded */
197 return STATUS_SUCCESS
;
201 /* do the slow way */
204 /* initialize temp event */
205 KeInitializeEvent(&LocalEvent
, NotificationEvent
, FALSE
);
209 /* build the irp packet */
210 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
, DeviceObject
, Buffer
, Length
, &FileObject
->CurrentByteOffset
, Event
, IoStatusBlock
);
213 /* not enough resources */
214 return STATUS_INSUFFICIENT_RESOURCES
;
217 /* send the packet */
218 Status
= IoCallDriver(DeviceObject
, Irp
);
220 if (Status
== STATUS_PENDING
)
222 /* operation is pending, is sync file object */
223 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
226 KeWaitForSingleObject(Event
, Executive
, RequestorMode
, FALSE
, NULL
);
227 Status
= IoStatusBlock
->Status
;
241 IN PFILE_OBJECT FileObject
,
242 IN PKEVENT Event OPTIONAL
,
243 IN PVOID PortContext OPTIONAL
,
244 OUT PIO_STATUS_BLOCK IoStatusBlock
,
247 IN ULONG Key OPTIONAL
,
248 IN KPROCESSOR_MODE RequestorMode
)
250 PDEVICE_OBJECT DeviceObject
;
258 /* make sure event is reset */
262 if (RequestorMode
== UserMode
)
264 /* probe the user buffer */
267 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
268 Status
= STATUS_SUCCESS
;
270 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
272 /* Exception, get the error code */
273 Status
= _SEH2_GetExceptionCode();
277 if (!NT_SUCCESS(Status
))
279 DPRINT1("Invalid user buffer provided\n");
284 /* get corresponding device object */
285 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
287 /* fast-io write is only available for kernel mode clients */
288 if (RequestorMode
== KernelMode
&& ExGetPreviousMode() == KernelMode
&&
289 DeviceObject
->DriverObject
->FastIoDispatch
->FastIoWrite
)
291 /* call fast io write */
292 Result
= DeviceObject
->DriverObject
->FastIoDispatch
->FastIoWrite(FileObject
, &FileObject
->CurrentByteOffset
, Length
, TRUE
, Key
, Buffer
, IoStatusBlock
, DeviceObject
);
294 if (Result
&& NT_SUCCESS(IoStatusBlock
->Status
))
296 /* request was handeled and succeeded */
297 return STATUS_SUCCESS
;
301 /* do the slow way */
304 /* initialize temp event */
305 KeInitializeEvent(&LocalEvent
, NotificationEvent
, FALSE
);
309 /* build the irp packet */
310 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
, DeviceObject
, Buffer
, Length
, &FileObject
->CurrentByteOffset
, Event
, IoStatusBlock
);
313 /* not enough resources */
314 return STATUS_INSUFFICIENT_RESOURCES
;
317 /* send the packet */
318 Status
= IoCallDriver(DeviceObject
, Irp
);
320 if (Status
== STATUS_PENDING
)
322 /* operation is pending, is sync file object */
323 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
326 KeWaitForSingleObject(Event
, Executive
, RequestorMode
, FALSE
, NULL
);
327 Status
= IoStatusBlock
->Status
;
340 KsQueryInformationFile(
341 IN PFILE_OBJECT FileObject
,
342 OUT PVOID FileInformation
,
344 IN FILE_INFORMATION_CLASS FileInformationClass
)
346 PDEVICE_OBJECT DeviceObject
;
347 PFAST_IO_DISPATCH FastIoDispatch
;
349 PIO_STACK_LOCATION IoStack
;
350 IO_STATUS_BLOCK IoStatus
;
352 LARGE_INTEGER Offset
;
353 IO_STATUS_BLOCK StatusBlock
;
356 /* get related file object */
357 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
359 /* get fast i/o table */
360 FastIoDispatch
= DeviceObject
->DriverObject
->FastIoDispatch
;
362 /* is there a fast table */
365 /* check the class */
366 if (FileInformationClass
== FileBasicInformation
)
368 /* use FastIoQueryBasicInfo routine */
369 if (FastIoDispatch
->FastIoQueryBasicInfo
)
371 return FastIoDispatch
->FastIoQueryBasicInfo(FileObject
, TRUE
, (PFILE_BASIC_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
374 else if (FileInformationClass
== FileStandardInformation
)
376 /* use FastIoQueryBasicInfo routine */
377 if (FastIoDispatch
->FastIoQueryBasicInfo
)
379 return FastIoDispatch
->FastIoQueryStandardInfo(FileObject
, TRUE
, (PFILE_STANDARD_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
384 KeClearEvent(&FileObject
->Event
);
386 /* initialize event */
387 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
389 /* set offset to zero */
390 Offset
.QuadPart
= 0L;
392 /* build the request */
393 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_INFORMATION
, IoGetRelatedDeviceObject(FileObject
), NULL
, 0, &Offset
, &Event
, &StatusBlock
);
396 return STATUS_INSUFFICIENT_RESOURCES
;
398 /* get next stack location */
399 IoStack
= IoGetNextIrpStackLocation(Irp
);
401 /* setup parameters */
402 IoStack
->Parameters
.QueryFile
.FileInformationClass
= FileInformationClass
;
403 IoStack
->Parameters
.QueryFile
.Length
= Length
;
404 Irp
->AssociatedIrp
.SystemBuffer
= FileInformation
;
407 /* call the driver */
408 Status
= IoCallDriver(IoGetRelatedDeviceObject(FileObject
), Irp
);
410 if (Status
== STATUS_PENDING
)
412 /* wait for the operation to complete */
413 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
416 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
417 Status
= FileObject
->FinalStatus
;
419 Status
= StatusBlock
.Status
;
432 KsSetInformationFile(
433 IN PFILE_OBJECT FileObject
,
434 IN PVOID FileInformation
,
436 IN FILE_INFORMATION_CLASS FileInformationClass
)
438 PIO_STACK_LOCATION IoStack
;
439 PDEVICE_OBJECT DeviceObject
;
443 LARGE_INTEGER Offset
;
444 IO_STATUS_BLOCK IoStatus
;
447 /* get related device object */
448 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
450 /* copy file information */
451 Buffer
= AllocateItem(NonPagedPool
, Length
);
453 return STATUS_INSUFFICIENT_RESOURCES
;
457 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
458 RtlMoveMemory(Buffer
, FileInformation
, Length
);
459 Status
= STATUS_SUCCESS
;
461 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
463 /* Exception, get the error code */
464 Status
= _SEH2_GetExceptionCode();
468 if (!NT_SUCCESS(Status
))
470 /* invalid user buffer */
475 /* initialize the event */
476 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
479 Offset
.QuadPart
= 0LL;
482 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_SET_INFORMATION
, DeviceObject
, NULL
, 0, &Offset
, &Event
, &IoStatus
);
486 /* failed to allocate irp */
488 return STATUS_INSUFFICIENT_RESOURCES
;
491 /* get next stack location */
492 IoStack
= IoGetNextIrpStackLocation(Irp
);
494 /* set irp parameters */
495 IoStack
->Parameters
.SetFile
.FileInformationClass
= FileInformationClass
;
496 IoStack
->Parameters
.SetFile
.Length
= Length
;
497 IoStack
->Parameters
.SetFile
.FileObject
= FileObject
;
498 Irp
->AssociatedIrp
.SystemBuffer
= Buffer
;
499 Irp
->UserBuffer
= FileInformation
;
501 /* dispatch the irp */
502 Status
= IoCallDriver(DeviceObject
, Irp
);
504 if (Status
== STATUS_PENDING
)
506 /* wait untill the operation has completed */
507 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
508 /* is a sync file object */
509 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
510 Status
= FileObject
->FinalStatus
;
512 Status
= IoStatus
.Status
;
525 IN PFILE_OBJECT FileObject
,
526 IN PKEVENT Event OPTIONAL
,
527 IN PVOID PortContext OPTIONAL
,
528 IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL
,
529 IN PVOID CompletionContext OPTIONAL
,
530 IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL
,
531 OUT PIO_STATUS_BLOCK IoStatusBlock
,
532 IN OUT PVOID StreamHeaders
,
535 IN KPROCESSOR_MODE RequestorMode
)
538 PIO_STACK_LOCATION IoStack
;
539 PDEVICE_OBJECT DeviceObject
;
541 LARGE_INTEGER Offset
;
542 PKSIOBJECT_HEADER ObjectHeader
;
545 /* get related device object */
546 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
548 ASSERT(DeviceObject
!= NULL
);
550 /* is there a event provided */
557 if (RequestorMode
|| ExGetPreviousMode() == KernelMode
)
559 /* requestor is from kernel land */
560 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext2
;
564 /* there is a object header */
565 if (Flags
== KSSTREAM_READ
)
567 /* is fast read supported */
568 if (ObjectHeader
->DispatchTable
.FastRead
)
570 /* call fast read dispatch routine */
571 Ret
= ObjectHeader
->DispatchTable
.FastRead(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
);
575 /* the request was handeled */
576 return IoStatusBlock
->Status
;
580 else if (Flags
== KSSTREAM_WRITE
)
582 /* is fast write supported */
583 if (ObjectHeader
->DispatchTable
.FastWrite
)
585 /* call fast write dispatch routine */
586 Ret
= ObjectHeader
->DispatchTable
.FastWrite(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
);
590 /* the request was handeled */
591 return IoStatusBlock
->Status
;
598 /* clear file object event */
599 KeClearEvent(&FileObject
->Event
);
601 /* set the offset to zero */
602 Offset
.QuadPart
= 0LL;
604 /* now build the irp */
605 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL
,
606 DeviceObject
, (PVOID
)StreamHeaders
, Length
, &Offset
, Event
, IoStatusBlock
);
609 /* not enough memory */
610 return STATUS_INSUFFICIENT_RESOURCES
;
613 /* setup irp parameters */
614 Irp
->RequestorMode
= RequestorMode
;
615 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= PortContext
;
616 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
617 Irp
->UserBuffer
= StreamHeaders
;
619 /* get next irp stack location */
620 IoStack
= IoGetNextIrpStackLocation(Irp
);
621 /* setup stack parameters */
622 IoStack
->FileObject
= FileObject
;
623 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= Length
;
624 IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
= StreamHeaders
;
625 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= (Flags
== KSSTREAM_READ
? IOCTL_KS_READ_STREAM
: IOCTL_KS_WRITE_STREAM
);
627 if (CompletionRoutine
)
629 /* setup completion routine for async processing */
630 IoSetCompletionRoutine(Irp
, CompletionRoutine
, CompletionContext
, (CompletionInvocationFlags
& KsInvokeOnSuccess
), (CompletionInvocationFlags
& KsInvokeOnError
), (CompletionInvocationFlags
& KsInvokeOnCancel
));
633 /* now call the driver */
634 Status
= IoCallDriver(DeviceObject
, Irp
);
652 LOCK_OPERATION Operation
;
653 NTSTATUS Status
= STATUS_SUCCESS
;
654 PKSSTREAM_HEADER StreamHeader
;
655 PIO_STACK_LOCATION IoStack
;
657 //BOOLEAN AllocateMdl = FALSE;
659 /* get current irp stack */
660 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
662 Length
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
664 if (Irp
->RequestorMode
== KernelMode
|| Irp
->AssociatedIrp
.SystemBuffer
)
666 if (Irp
->RequestorMode
== KernelMode
)
668 /* no need to allocate stream header */
669 Irp
->AssociatedIrp
.SystemBuffer
= Irp
->UserBuffer
;
672 /* check if alloc mdl flag is passed */
673 if (!(ProbeFlags
& KSPROBE_ALLOCATEMDL
))
675 /* nothing more to do */
676 return STATUS_SUCCESS
;
681 if (ProbeFlags
& KSPROBE_PROBEANDLOCK
)
683 if (Irp
->MdlAddress
->MdlFlags
& (MDL_PAGES_LOCKED
| MDL_SOURCE_IS_NONPAGED_POOL
))
685 if (ProbeFlags
& KSPROBE_SYSTEMADDRESS
)
689 /* loop through all mdls and probe them */
690 Mdl
= Irp
->MdlAddress
;
693 /* the mapping can fail */
694 Mdl
->MdlFlags
|= MDL_MAPPING_CAN_FAIL
;
696 if (Mdl
->MdlFlags
& (MDL_MAPPED_TO_SYSTEM_VA
| MDL_SOURCE_IS_NONPAGED_POOL
))
698 /* no need to probe these pages */
699 Buffer
= Mdl
->MappedSystemVa
;
704 Buffer
= MmMapLockedPages(Mdl
, KernelMode
);
707 /* check if the mapping succeeded */
710 /* raise exception we'll catch */
711 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
714 /* iterate to next mdl */
719 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
721 /* Exception, get the error code */
722 Status
= _SEH2_GetExceptionCode();
730 /* loop through all mdls and probe them */
731 Mdl
= Irp
->MdlAddress
;
733 /* determine operation */
734 if (!(ProbeFlags
& KSPROBE_STREAMWRITE
) || (ProbeFlags
& KSPROBE_MODIFY
))
736 /* operation is read / modify stream, need write access */
737 Operation
= IoWriteAccess
;
741 /* operation is write to device, so we need read access */
742 Operation
= IoReadAccess
;
747 /* probe the pages */
748 MmProbeAndLockPages(Mdl
, Irp
->RequestorMode
, Operation
);
750 if (ProbeFlags
& KSPROBE_SYSTEMADDRESS
)
752 /* the mapping can fail */
753 Mdl
->MdlFlags
|= MDL_MAPPING_CAN_FAIL
;
755 if (Mdl
->MdlFlags
& (MDL_MAPPED_TO_SYSTEM_VA
| MDL_SOURCE_IS_NONPAGED_POOL
))
757 /* no need to probe these pages */
758 Buffer
= Mdl
->MappedSystemVa
;
763 Buffer
= MmMapLockedPages(Mdl
, KernelMode
);
766 /* check if the mapping succeeded */
769 /* raise exception we'll catch */
770 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
774 /* iterate to next mdl */
779 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
781 /* Exception, get the error code */
782 Status
= _SEH2_GetExceptionCode();
789 /* check all stream headers */
790 StreamHeader
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
791 ASSERT(StreamHeader
);
798 /* does the supplied header size match stream header size and no type changed */
799 if (StreamHeader
->Size
!= HeaderSize
&& !(StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
))
801 /* invalid stream header */
802 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
807 /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */
808 if (StreamHeader
->Size
< sizeof(KSSTREAM_HEADER
) || (StreamHeader
->Size
& 7))
810 /* invalid stream header */
811 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
815 if (Length
< StreamHeader
->Size
)
817 /* length is too short */
818 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
821 if (ProbeFlags
& KSPROBE_STREAMWRITE
)
823 if (StreamHeader
->DataUsed
> StreamHeader
->FrameExtent
)
825 /* frame extend can never be smaller */
826 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
829 /* is this stream change packet */
830 if (StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
)
832 if (Length
!= sizeof(KSSTREAM_HEADER
) || (PVOID
)StreamHeader
!= Irp
->AssociatedIrp
.SystemBuffer
)
834 /* stream changed - must be send in a single packet */
835 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
838 if (!(ProbeFlags
& KSPROBE_ALLOWFORMATCHANGE
))
840 /* caller does not permit format changes */
841 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
844 if (StreamHeader
->FrameExtent
)
846 /* allocate an mdl */
847 Mdl
= IoAllocateMdl(StreamHeader
->Data
, StreamHeader
->FrameExtent
, FALSE
, TRUE
, Irp
);
851 /* not enough memory */
852 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
855 /* break-out to probe for the irp */
862 if (StreamHeader
->DataUsed
)
864 /* DataUsed must be zero for stream read operation */
865 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
868 if (StreamHeader
->OptionsFlags
)
870 /* no flags supported for reading */
871 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
875 if (StreamHeader
->FrameExtent
)
877 /* allocate an mdl */
878 ASSERT(Irp
->MdlAddress
== NULL
);
879 Mdl
= IoAllocateMdl(StreamHeader
->Data
, StreamHeader
->FrameExtent
, FALSE
, TRUE
, Irp
);
882 /* not enough memory */
883 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
887 /* move to next stream header */
888 Length
-= StreamHeader
->Size
;
889 StreamHeader
= (PKSSTREAM_HEADER
)((ULONG_PTR
)StreamHeader
+ StreamHeader
->Size
);
892 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
894 /* Exception, get the error code */
895 Status
= _SEH2_GetExceptionCode();
898 /* now probe the allocated mdl's */
899 if (!NT_SUCCESS(Status
))
901 DPRINT("Status %x\n", Status
);
908 /* probe user mode buffers */
909 if (Length
&& ( (!HeaderSize
) || (Length
% HeaderSize
== 0) || ((ProbeFlags
& KSPROBE_ALLOWFORMATCHANGE
) && (Length
== sizeof(KSSTREAM_HEADER
))) ) )
911 /* allocate stream header buffer */
912 Irp
->AssociatedIrp
.SystemBuffer
= AllocateItem(NonPagedPool
, Length
);
914 if (!Irp
->AssociatedIrp
.SystemBuffer
)
917 return STATUS_INSUFFICIENT_RESOURCES
;
920 /* mark irp as buffered so that changes the stream headers are propagated back */
921 Irp
->Flags
= IRP_DEALLOCATE_BUFFER
| IRP_BUFFERED_IO
;
925 if (ProbeFlags
& KSPROBE_STREAMWRITE
)
927 if (ProbeFlags
& KSPROBE_MODIFY
)
928 ProbeForWrite(Irp
->UserBuffer
, Length
, sizeof(UCHAR
));
930 ProbeForRead(Irp
->UserBuffer
, Length
, sizeof(UCHAR
));
934 /* stream reads means writing */
935 ProbeForWrite(Irp
->UserBuffer
, Length
, sizeof(UCHAR
));
937 /* set input operation flags */
938 Irp
->Flags
|= IRP_INPUT_OPERATION
;
941 /* copy stream buffer */
942 RtlMoveMemory(Irp
->AssociatedIrp
.SystemBuffer
, Irp
->UserBuffer
, Length
);
944 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
946 /* Exception, get the error code */
947 Status
= _SEH2_GetExceptionCode();
950 if (!NT_SUCCESS(Status
))
956 if (ProbeFlags
& KSPROBE_ALLOCATEMDL
)
962 /* check all stream headers */
963 StreamHeader
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
971 /* does the supplied header size match stream header size and no type changed */
972 if (StreamHeader
->Size
!= HeaderSize
&& !(StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
))
974 /* invalid stream header */
975 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
980 /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */
981 if (StreamHeader
->Size
< sizeof(KSSTREAM_HEADER
) || (StreamHeader
->Size
& 7))
983 /* invalid stream header */
984 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
988 if (Length
< StreamHeader
->Size
)
990 /* length is too short */
991 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
994 if (ProbeFlags
& KSPROBE_STREAMWRITE
)
996 if (StreamHeader
->DataUsed
> StreamHeader
->FrameExtent
)
998 /* frame extend can never be smaller */
999 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
1002 /* is this stream change packet */
1003 if (StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
)
1005 if (Length
!= sizeof(KSSTREAM_HEADER
) || (PVOID
)StreamHeader
!= Irp
->AssociatedIrp
.SystemBuffer
)
1007 /* stream changed - must be send in a single packet */
1008 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
1011 if (!(ProbeFlags
& KSPROBE_ALLOWFORMATCHANGE
))
1013 /* caller does not permit format changes */
1014 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
1017 if (StreamHeader
->FrameExtent
)
1019 /* allocate an mdl */
1020 Mdl
= IoAllocateMdl(StreamHeader
->Data
, StreamHeader
->FrameExtent
, FALSE
, TRUE
, Irp
);
1024 /* not enough memory */
1025 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
1028 /* break out to probe for the irp */
1029 //AllocateMdl = TRUE;
1036 if (StreamHeader
->DataUsed
)
1038 /* DataUsed must be zero for stream read operation */
1039 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
1042 if (StreamHeader
->OptionsFlags
)
1044 /* no flags supported for reading */
1045 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
1049 /* move to next stream header */
1050 Length
-= StreamHeader
->Size
;
1051 StreamHeader
= (PKSSTREAM_HEADER
)((ULONG_PTR
)StreamHeader
+ StreamHeader
->Size
);
1054 }_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1056 /* Exception, get the error code */
1057 Status
= _SEH2_GetExceptionCode();
1060 /* now probe the allocated mdl's */
1061 if (NT_SUCCESS(Status
))
1067 return STATUS_INVALID_BUFFER_SIZE
;
1076 KsAllocateExtraData(
1079 OUT PVOID
* ExtraBuffer
)
1081 PIO_STACK_LOCATION IoStack
;
1083 PUCHAR Buffer
, BufferOrg
;
1084 PKSSTREAM_HEADER Header
;
1085 NTSTATUS Status
= STATUS_SUCCESS
;
1087 /* get current irp stack */
1088 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1091 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSSTREAM_HEADER
));
1093 /* get total length */
1094 Count
= IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
/ sizeof(KSSTREAM_HEADER
);
1096 /* allocate buffer */
1097 Buffer
= BufferOrg
= AllocateItem(NonPagedPool
, Count
* (sizeof(KSSTREAM_HEADER
) + ExtraSize
));
1099 return STATUS_INSUFFICIENT_RESOURCES
;
1103 /* get input buffer */
1104 Header
= (PKSSTREAM_HEADER
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1105 for(Index
= 0; Index
< Count
; Index
++)
1107 /* copy stream header */
1108 RtlMoveMemory(Buffer
, Header
, sizeof(KSSTREAM_HEADER
));
1110 /* move to next header */
1112 /* increment output buffer offset */
1113 Buffer
+= sizeof(KSSTREAM_HEADER
) + ExtraSize
;
1116 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1118 /* Exception, get the error code */
1119 Status
= _SEH2_GetExceptionCode();
1123 if (!NT_SUCCESS(Status
))
1125 /* free buffer on exception */
1131 *ExtraBuffer
= BufferOrg
;
1134 return STATUS_SUCCESS
;
1144 IN PDRIVER_OBJECT DriverObject
)
1154 KsDispatchInvalidDeviceRequest(
1155 IN PDEVICE_OBJECT DeviceObject
,
1158 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
1159 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1161 return STATUS_INVALID_DEVICE_REQUEST
;
1170 KsDefaultDeviceIoCompletion(
1171 IN PDEVICE_OBJECT DeviceObject
,
1174 PIO_STACK_LOCATION IoStack
;
1177 /* get current irp stack */
1178 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1180 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
&&
1181 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_METHOD
&&
1182 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_ENABLE_EVENT
&&
1183 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_DISABLE_EVENT
)
1185 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_RESET_STATE
)
1188 Status
= STATUS_SUCCESS
;
1192 /* request unsupported */
1193 Status
= STATUS_INVALID_DEVICE_REQUEST
;
1198 /* property / method / event not found */
1199 Status
= STATUS_PROPSET_NOT_FOUND
;
1202 /* complete request */
1203 Irp
->IoStatus
.Status
= Status
;
1204 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1216 KsDispatchFastIoDeviceControlFailure(
1217 IN PFILE_OBJECT FileObject
,
1219 IN PVOID InputBuffer OPTIONAL
,
1220 IN ULONG InputBufferLength
,
1221 OUT PVOID OutputBuffer OPTIONAL
,
1222 IN ULONG OutputBufferLength
,
1223 IN ULONG IoControlCode
,
1224 OUT PIO_STATUS_BLOCK IoStatus
,
1225 IN PDEVICE_OBJECT DeviceObject
)
1236 KsDispatchFastReadFailure(
1237 IN PFILE_OBJECT FileObject
,
1238 IN PLARGE_INTEGER FileOffset
,
1243 OUT PIO_STATUS_BLOCK IoStatus
,
1244 IN PDEVICE_OBJECT DeviceObject
)
1257 IN OUT PLIST_ENTRY QueueHead
,
1258 IN PKSPIN_LOCK SpinLock
)
1260 PDRIVER_CANCEL OldDriverCancel
;
1261 PIO_STACK_LOCATION IoStack
;
1263 PLIST_ENTRY NextEntry
;
1267 /* acquire spinlock */
1268 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1269 /* point to first entry */
1270 Entry
= QueueHead
->Flink
;
1271 /* loop all items */
1272 while(Entry
!= QueueHead
)
1274 /* get irp offset */
1275 Irp
= (PIRP
)CONTAINING_RECORD(Entry
, IRP
, Tail
.Overlay
.ListEntry
);
1277 /* get next entry */
1278 NextEntry
= Entry
->Flink
;
1280 /* set cancelled bit */
1283 /* now set the cancel routine */
1284 OldDriverCancel
= IoSetCancelRoutine(Irp
, NULL
);
1285 if (OldDriverCancel
)
1287 /* this irp hasnt been yet used, so free to cancel */
1288 KeReleaseSpinLock(SpinLock
, OldLevel
);
1290 /* get current irp stack */
1291 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1293 /* acquire cancel spinlock */
1294 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1296 /* call provided cancel routine */
1297 OldDriverCancel(IoStack
->DeviceObject
, Irp
);
1299 /* re-acquire spinlock */
1300 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1303 /* move on to next entry */
1307 /* the irp has already been canceled */
1308 KeReleaseSpinLock(SpinLock
, OldLevel
);
1318 KsReleaseIrpOnCancelableQueue(
1320 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
1322 PKSPIN_LOCK SpinLock
;
1323 PDRIVER_CANCEL OldDriverCancel
;
1324 PIO_STACK_LOCATION IoStack
;
1327 /* check for required parameters */
1333 /* default to KsCancelRoutine */
1334 DriverCancel
= KsCancelRoutine
;
1337 /* get current irp stack */
1338 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1340 /* get internal queue lock */
1341 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1343 /* acquire spinlock */
1344 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1346 /* now set the cancel routine */
1347 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
1349 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
1351 /* the irp has already been canceled */
1352 KeReleaseSpinLock(SpinLock
, OldLevel
);
1354 /* cancel routine requires that cancel spinlock is held */
1355 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1358 DriverCancel(IoStack
->DeviceObject
, Irp
);
1363 KeReleaseSpinLock(SpinLock
, OldLevel
);
1373 KsRemoveIrpFromCancelableQueue(
1374 IN OUT PLIST_ENTRY QueueHead
,
1375 IN PKSPIN_LOCK SpinLock
,
1376 IN KSLIST_ENTRY_LOCATION ListLocation
,
1377 IN KSIRP_REMOVAL_OPERATION RemovalOperation
)
1380 PLIST_ENTRY CurEntry
;
1383 DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead
, SpinLock
, ListLocation
, RemovalOperation
);
1385 /* check parameters */
1386 if (!QueueHead
|| !SpinLock
)
1389 /* check if parameter ListLocation is valid */
1390 if (ListLocation
!= KsListEntryTail
&& ListLocation
!= KsListEntryHead
)
1393 /* acquire list lock */
1394 KeAcquireSpinLock(SpinLock
, &OldIrql
);
1396 /* point to queue head */
1397 CurEntry
= QueueHead
;
1401 /* reset irp to null */
1404 /* iterate to next entry */
1405 if (ListLocation
== KsListEntryHead
)
1406 CurEntry
= CurEntry
->Flink
;
1408 CurEntry
= CurEntry
->Blink
;
1410 /* is the end of list reached */
1411 if (CurEntry
== QueueHead
)
1413 /* reached end of list */
1417 /* get irp offset */
1418 Irp
= (PIRP
)CONTAINING_RECORD(CurEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1422 /* irp has been canceled */
1426 if (Irp
->CancelRoutine
)
1428 /* remove cancel routine */
1429 Irp
->CancelRoutine
= NULL
;
1431 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
1433 /* remove irp from list */
1434 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1437 if (RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
|| RemovalOperation
== KsAcquireOnlySingleItem
)
1444 KeReleaseSpinLock(SpinLock
, OldIrql
);
1446 if (!Irp
|| Irp
->CancelRoutine
== NULL
)
1448 /* either an irp has been acquired or nothing found */
1452 /* time to remove the canceled irp */
1453 IoAcquireCancelSpinLock(&OldIrql
);
1454 /* acquire list lock */
1455 KeAcquireSpinLockAtDpcLevel(SpinLock
);
1457 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
1460 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1463 /* release list lock */
1464 KeReleaseSpinLockFromDpcLevel(SpinLock
);
1466 /* release cancel spinlock */
1467 IoReleaseCancelSpinLock(OldIrql
);
1468 /* no non canceled irp has been found */
1478 KsMoveIrpsOnCancelableQueue(
1479 IN OUT PLIST_ENTRY SourceList
,
1480 IN PKSPIN_LOCK SourceLock
,
1481 IN OUT PLIST_ENTRY DestinationList
,
1482 IN PKSPIN_LOCK DestinationLock OPTIONAL
,
1483 IN KSLIST_ENTRY_LOCATION ListLocation
,
1484 IN PFNKSIRPLISTCALLBACK ListCallback
,
1488 PLIST_ENTRY SrcEntry
;
1490 NTSTATUS Status
= STATUS_SUCCESS
;
1492 if (!DestinationLock
)
1494 /* no destination lock just acquire the source lock */
1495 KeAcquireSpinLock(SourceLock
, &OldLevel
);
1499 /* acquire cancel spinlock */
1500 IoAcquireCancelSpinLock(&OldLevel
);
1502 /* now acquire source lock */
1503 KeAcquireSpinLockAtDpcLevel(SourceLock
);
1505 /* now acquire destination lock */
1506 KeAcquireSpinLockAtDpcLevel(DestinationLock
);
1509 /* point to list head */
1510 SrcEntry
= SourceList
;
1512 /* now move all irps */
1515 if (ListLocation
== KsListEntryTail
)
1517 /* move queue downwards */
1518 SrcEntry
= SrcEntry
->Flink
;
1522 /* move queue upwards */
1523 SrcEntry
= SrcEntry
->Blink
;
1526 if (SrcEntry
== SourceList
)
1528 /* eof list reached */
1532 /* get irp offset */
1533 Irp
= (PIRP
)CONTAINING_RECORD(SrcEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1535 /* now check if irp can be moved */
1536 Status
= ListCallback(Irp
, Context
);
1538 /* check if irp can be moved */
1539 if (Status
== STATUS_SUCCESS
)
1541 /* remove irp from src list */
1542 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1544 if (ListLocation
== KsListEntryTail
)
1546 /* insert irp end of list */
1547 InsertTailList(DestinationList
, &Irp
->Tail
.Overlay
.ListEntry
);
1551 /* insert irp head of list */
1552 InsertHeadList(DestinationList
, &Irp
->Tail
.Overlay
.ListEntry
);
1555 /* do we need to update the irp lock */
1556 if (DestinationLock
)
1558 /* update irp lock */
1559 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
) = DestinationLock
;
1564 if (Status
!= STATUS_NO_MATCH
)
1566 /* callback decided to stop enumeration */
1570 /* reset return value */
1571 Status
= STATUS_SUCCESS
;
1575 if (!DestinationLock
)
1577 /* release source lock */
1578 KeReleaseSpinLock(SourceLock
, OldLevel
);
1582 /* now release destination lock */
1583 KeReleaseSpinLockFromDpcLevel(DestinationLock
);
1585 /* now release source lock */
1586 KeReleaseSpinLockFromDpcLevel(SourceLock
);
1589 /* now release cancel spinlock */
1590 IoReleaseCancelSpinLock(OldLevel
);
1603 KsRemoveSpecificIrpFromCancelableQueue(
1606 PKSPIN_LOCK SpinLock
;
1609 DPRINT("KsRemoveSpecificIrpFromCancelableQueue %p\n", Irp
);
1611 /* get internal queue lock */
1612 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1614 /* acquire spinlock */
1615 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1617 /* remove the irp from the list */
1618 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1620 /* release spinlock */
1621 KeReleaseSpinLock(SpinLock
, OldLevel
);
1631 KsAddIrpToCancelableQueue(
1632 IN OUT PLIST_ENTRY QueueHead
,
1633 IN PKSPIN_LOCK SpinLock
,
1635 IN KSLIST_ENTRY_LOCATION ListLocation
,
1636 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
1638 PDRIVER_CANCEL OldDriverCancel
;
1639 PIO_STACK_LOCATION IoStack
;
1642 /* check for required parameters */
1643 if (!QueueHead
|| !SpinLock
|| !Irp
)
1646 /* get current irp stack */
1647 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1649 DPRINT("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead
, SpinLock
, Irp
, ListLocation
, DriverCancel
);
1651 // HACK for ms portcls
1652 if (IoStack
->MajorFunction
== IRP_MJ_CREATE
)
1654 // complete the request
1655 DPRINT1("MS HACK\n");
1656 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1657 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1665 /* default to KsCancelRoutine */
1666 DriverCancel
= KsCancelRoutine
;
1670 /* acquire spinlock */
1671 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1673 if (ListLocation
== KsListEntryTail
)
1675 /* insert irp to tail of list */
1676 InsertTailList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1680 /* insert irp to head of list */
1681 InsertHeadList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1684 /* store internal queue lock */
1685 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
) = SpinLock
;
1687 /* now set the cancel routine */
1688 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
1690 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
1692 /* the irp has already been canceled */
1693 KeReleaseSpinLock(SpinLock
, OldLevel
);
1695 /* cancel routine requires that cancel spinlock is held */
1696 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1699 DriverCancel(IoStack
->DeviceObject
, Irp
);
1704 KeReleaseSpinLock(SpinLock
, OldLevel
);
1715 IN PDEVICE_OBJECT DeviceObject
,
1718 PKSPIN_LOCK SpinLock
;
1720 /* get internal queue lock */
1721 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1723 /* acquire spinlock */
1724 KeAcquireSpinLockAtDpcLevel(SpinLock
);
1727 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1729 /* release cancel spinlock */
1730 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
1732 /* remove the irp from the list */
1733 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1735 /* release spinlock */
1736 KeReleaseSpinLock(SpinLock
, Irp
->CancelIrql
);
1738 /* has the irp already been canceled */
1739 if (Irp
->IoStatus
.Status
!= STATUS_CANCELLED
)
1741 /* let's complete it */
1742 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
1743 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1748 FindMatchingCreateItem(
1749 PLIST_ENTRY ListHead
,
1750 PUNICODE_STRING String
,
1751 OUT PCREATE_ITEM_ENTRY
*OutCreateItem
)
1754 PCREATE_ITEM_ENTRY CreateItemEntry
;
1755 UNICODE_STRING RefString
;
1759 /* Copy the input string */
1760 RefString
= *String
;
1762 /* Check if the string starts with a backslash */
1763 if (String
->Buffer
[0] == L
'\\')
1765 /* Skip backslash */
1767 RefString
.Length
-= sizeof(WCHAR
);
1771 /* get terminator */
1772 pStr
= String
->Buffer
;
1773 Count
= String
->Length
/ sizeof(WCHAR
);
1774 while ((Count
> 0) && (*pStr
!= L
'\\'))
1783 // request is for pin / node / allocator
1784 RefString
.Length
= (USHORT
)((PCHAR
)pStr
- (PCHAR
)String
->Buffer
);
1787 /* point to first entry */
1788 Entry
= ListHead
->Flink
;
1790 /* loop all device items */
1791 while (Entry
!= ListHead
)
1793 /* get create item entry */
1794 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
,
1798 ASSERT(CreateItemEntry
->CreateItem
);
1800 if(CreateItemEntry
->CreateItem
->Flags
& KSCREATE_ITEM_WILDCARD
)
1802 /* create item is default */
1803 *OutCreateItem
= CreateItemEntry
;
1804 return STATUS_SUCCESS
;
1807 if (!CreateItemEntry
->CreateItem
->Create
)
1809 /* skip free create item */
1810 Entry
= Entry
->Flink
;
1814 DPRINT("CreateItem %S Length %u Request %wZ %u\n",
1815 CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
,
1816 CreateItemEntry
->CreateItem
->ObjectClass
.Length
,
1820 if (CreateItemEntry
->CreateItem
->ObjectClass
.Length
> RefString
.Length
)
1822 /* create item doesnt match in length */
1823 Entry
= Entry
->Flink
;
1827 /* now check if the object class is the same */
1828 if (!RtlCompareUnicodeString(&CreateItemEntry
->CreateItem
->ObjectClass
,
1832 /* found matching create item */
1833 *OutCreateItem
= CreateItemEntry
;
1834 return STATUS_SUCCESS
;
1836 /* iterate to next */
1837 Entry
= Entry
->Flink
;
1840 return STATUS_NOT_FOUND
;
1846 IN PDEVICE_OBJECT DeviceObject
,
1849 PCREATE_ITEM_ENTRY CreateItemEntry
;
1850 PIO_STACK_LOCATION IoStack
;
1851 PDEVICE_EXTENSION DeviceExtension
;
1852 PKSIDEVICE_HEADER DeviceHeader
;
1853 PKSIOBJECT_HEADER ObjectHeader
;
1856 DPRINT("KS / CREATE\n");
1858 /* get current stack location */
1859 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1860 /* get device extension */
1861 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1862 /* get device header */
1863 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1866 if (IoStack
->FileObject
->FileName
.Buffer
== NULL
)
1868 /* FIXME Pnp-Issue */
1869 DPRINT("Using reference string hack\n");
1870 Irp
->IoStatus
.Information
= 0;
1871 /* set return status */
1872 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1873 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1874 return STATUS_SUCCESS
;
1877 if (IoStack
->FileObject
->RelatedFileObject
!= NULL
)
1879 /* request is to instantiate a pin / node / clock / allocator */
1880 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->RelatedFileObject
->FsContext2
;
1883 ASSERT(ObjectHeader
);
1885 /* find a matching a create item */
1886 Status
= FindMatchingCreateItem(&ObjectHeader
->ItemList
,
1887 &IoStack
->FileObject
->FileName
,
1892 /* request to create a filter */
1893 Status
= FindMatchingCreateItem(&DeviceHeader
->ItemList
,
1894 &IoStack
->FileObject
->FileName
,
1898 if (NT_SUCCESS(Status
))
1900 /* set object create item */
1901 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
1903 /* call create function */
1904 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
1906 if (NT_SUCCESS(Status
))
1908 /* increment create item reference count */
1909 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
1914 Irp
->IoStatus
.Information
= 0;
1915 /* set return status */
1916 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1917 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1918 return STATUS_UNSUCCESSFUL
;
1924 IN PDEVICE_OBJECT DeviceObject
,
1927 PIO_STACK_LOCATION IoStack
;
1928 //PDEVICE_EXTENSION DeviceExtension;
1929 PKSIOBJECT_HEADER ObjectHeader
;
1930 //PKSIDEVICE_HEADER DeviceHeader;
1931 PDRIVER_DISPATCH Dispatch
;
1934 /* get current stack location */
1935 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1937 /* get device extension */
1938 //DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
1939 /* get device header */
1940 //DeviceHeader = DeviceExtension->DeviceHeader;
1942 ASSERT(IoStack
->FileObject
);
1944 /* get object header */
1945 ObjectHeader
= (PKSIOBJECT_HEADER
) IoStack
->FileObject
->FsContext2
;
1949 /* FIXME Pnp-Issue*/
1950 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1951 Irp
->IoStatus
.Information
= 0;
1952 /* complete and forget */
1953 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1954 return STATUS_SUCCESS
;
1958 ASSERT(ObjectHeader
);
1959 /* store create item */
1960 //KSCREATE_ITEM_IRP_STORAGE(Irp) = (PKSOBJECT_CREATE_ITEM)0x12345678; //ObjectHeader->CreateItem;
1962 /* retrieve matching dispatch function */
1963 switch(IoStack
->MajorFunction
)
1966 Dispatch
= ObjectHeader
->DispatchTable
.Close
;
1968 case IRP_MJ_DEVICE_CONTROL
:
1969 Dispatch
= ObjectHeader
->DispatchTable
.DeviceIoControl
;
1972 Dispatch
= ObjectHeader
->DispatchTable
.Read
;
1975 Dispatch
= ObjectHeader
->DispatchTable
.Write
;
1977 case IRP_MJ_FLUSH_BUFFERS
:
1978 Dispatch
= ObjectHeader
->DispatchTable
.Flush
;
1980 case IRP_MJ_QUERY_SECURITY
:
1981 Dispatch
= ObjectHeader
->DispatchTable
.QuerySecurity
;
1983 case IRP_MJ_SET_SECURITY
:
1984 Dispatch
= ObjectHeader
->DispatchTable
.SetSecurity
;
1987 Dispatch
= KsDefaultDispatchPnp
;
1993 /* is the request supported */
1996 /* now call the dispatch function */
1997 Status
= Dispatch(DeviceObject
, Irp
);
2001 /* not supported request */
2002 Status
= KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
2015 KsSetMajorFunctionHandler(
2016 IN PDRIVER_OBJECT DriverObject
,
2017 IN ULONG MajorFunction
)
2019 DPRINT("KsSetMajorFunctionHandler Function %x\n", MajorFunction
);
2021 switch ( MajorFunction
)
2024 DriverObject
->MajorFunction
[MajorFunction
] = KspCreate
;
2026 case IRP_MJ_DEVICE_CONTROL
:
2030 case IRP_MJ_FLUSH_BUFFERS
:
2031 case IRP_MJ_QUERY_SECURITY
:
2032 case IRP_MJ_SET_SECURITY
:
2033 DriverObject
->MajorFunction
[MajorFunction
] = KspDispatchIrp
;
2036 DPRINT1("NotSupported %x\n", MajorFunction
);
2037 return STATUS_INVALID_PARAMETER
;
2040 return STATUS_SUCCESS
;
2050 IN PDEVICE_OBJECT DeviceObject
,
2053 PIO_STACK_LOCATION IoStack
;
2054 PKSIDEVICE_HEADER DeviceHeader
;
2055 PDEVICE_EXTENSION DeviceExtension
;
2057 DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject
, Irp
);
2059 /* get device extension */
2060 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
2062 /* get device header */
2063 DeviceHeader
= DeviceExtension
->DeviceHeader
;
2066 /* get current irp stack */
2067 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2069 if (IoStack
->MajorFunction
<= IRP_MJ_DEVICE_CONTROL
)
2071 if (IoStack
->MajorFunction
== IRP_MJ_CREATE
)
2073 /* check internal type */
2074 if (DeviceHeader
->BasicHeader
.OuterUnknown
) /* FIXME improve check */
2076 /* AVStream client */
2077 return IKsDevice_Create(DeviceObject
, Irp
);
2081 /* external client (portcls) */
2082 return KspCreate(DeviceObject
, Irp
);
2086 switch (IoStack
->MajorFunction
)
2091 case IRP_MJ_FLUSH_BUFFERS
:
2092 case IRP_MJ_QUERY_SECURITY
:
2093 case IRP_MJ_SET_SECURITY
:
2095 case IRP_MJ_DEVICE_CONTROL
:
2096 return KspDispatchIrp(DeviceObject
, Irp
);
2098 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
2102 /* dispatch power */
2103 if (IoStack
->MajorFunction
== IRP_MJ_POWER
)
2105 /* check internal type */
2106 if (DeviceHeader
->BasicHeader
.OuterUnknown
) /* FIXME improve check */
2108 /* AVStream client */
2109 return IKsDevice_Power(DeviceObject
, Irp
);
2113 /* external client (portcls) */
2114 return KsDefaultDispatchPower(DeviceObject
, Irp
);
2117 else if (IoStack
->MajorFunction
== IRP_MJ_PNP
) /* dispatch pnp */
2119 /* check internal type */
2120 if (DeviceHeader
->BasicHeader
.OuterUnknown
) /* FIXME improve check */
2122 /* AVStream client */
2123 return IKsDevice_Pnp(DeviceObject
, Irp
);
2127 /* external client (portcls) */
2128 return KsDefaultDispatchPnp(DeviceObject
, Irp
);
2131 else if (IoStack
->MajorFunction
== IRP_MJ_SYSTEM_CONTROL
)
2134 return KsDefaultForwardIrp(DeviceObject
, Irp
);
2139 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
2153 return KSFILTER_NODE
;