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
22 KsDispatchQuerySecurity(
23 IN PDEVICE_OBJECT DeviceObject
,
26 PKSOBJECT_CREATE_ITEM CreateItem
;
27 PIO_STACK_LOCATION IoStack
;
31 /* get current irp stack */
32 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
35 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
37 if (!CreateItem
|| !CreateItem
->SecurityDescriptor
)
40 Irp
->IoStatus
.Status
= STATUS_NO_SECURITY_ON_OBJECT
;
41 CompleteRequest(Irp
, IO_NO_INCREMENT
);
42 return STATUS_NO_SECURITY_ON_OBJECT
;
46 /* get input length */
47 Length
= IoStack
->Parameters
.QuerySecurity
.Length
;
49 /* clone the security descriptor */
50 Status
= SeQuerySecurityDescriptorInfo(&IoStack
->Parameters
.QuerySecurity
.SecurityInformation
, (PSECURITY_DESCRIPTOR
)Irp
->UserBuffer
, &Length
, &CreateItem
->SecurityDescriptor
);
52 DPRINT("SeQuerySecurityDescriptorInfo Status %x\n", Status
);
54 Irp
->IoStatus
.Status
= Status
;
55 Irp
->IoStatus
.Information
= Length
;
57 CompleteRequest(Irp
, IO_NO_INCREMENT
);
67 KsDispatchSetSecurity(
68 IN PDEVICE_OBJECT DeviceObject
,
71 PKSOBJECT_CREATE_ITEM CreateItem
;
72 PIO_STACK_LOCATION IoStack
;
73 PGENERIC_MAPPING Mapping
;
74 PSECURITY_DESCRIPTOR Descriptor
;
77 /* get current irp stack */
78 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
81 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
83 if (!CreateItem
|| !CreateItem
->SecurityDescriptor
)
86 Irp
->IoStatus
.Status
= STATUS_NO_SECURITY_ON_OBJECT
;
87 CompleteRequest(Irp
, IO_NO_INCREMENT
);
88 return STATUS_NO_SECURITY_ON_OBJECT
;
91 /* backup old descriptor */
92 Descriptor
= CreateItem
->SecurityDescriptor
;
94 /* get generic mapping */
95 Mapping
= IoGetFileObjectGenericMapping();
97 /* change security descriptor */
98 Status
= SeSetSecurityDescriptorInfo(NULL
, /*FIXME */
99 &IoStack
->Parameters
.SetSecurity
.SecurityInformation
,
100 IoStack
->Parameters
.SetSecurity
.SecurityDescriptor
,
101 &CreateItem
->SecurityDescriptor
,
105 if (NT_SUCCESS(Status
))
107 /* free old descriptor */
108 FreeItem(Descriptor
);
110 /* mark create item as changed */
111 CreateItem
->Flags
|= KSCREATE_ITEM_SECURITYCHANGED
;
115 Irp
->IoStatus
.Status
= Status
;
116 CompleteRequest(Irp
, IO_NO_INCREMENT
);
127 KsDispatchSpecificMethod(
129 IN PFNKSHANDLER Handler
)
132 return STATUS_UNSUCCESSFUL
;
143 IN PFILE_OBJECT FileObject
,
144 IN PKEVENT Event OPTIONAL
,
145 IN PVOID PortContext OPTIONAL
,
146 OUT PIO_STATUS_BLOCK IoStatusBlock
,
149 IN ULONG Key OPTIONAL
,
150 IN KPROCESSOR_MODE RequestorMode
)
152 PDEVICE_OBJECT DeviceObject
;
160 /* make sure event is reset */
164 if (RequestorMode
== UserMode
)
166 /* probe the user buffer */
169 ProbeForWrite(Buffer
, Length
, sizeof(UCHAR
));
170 Status
= STATUS_SUCCESS
;
172 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
174 /* Exception, get the error code */
175 Status
= _SEH2_GetExceptionCode();
179 if (!NT_SUCCESS(Status
))
181 DPRINT1("Invalid user buffer provided\n");
186 /* get corresponding device object */
187 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
189 /* fast-io read is only available for kernel mode clients */
190 if (RequestorMode
== KernelMode
&& ExGetPreviousMode() == KernelMode
&&
191 DeviceObject
->DriverObject
->FastIoDispatch
->FastIoRead
)
193 /* call fast io write */
194 Result
= DeviceObject
->DriverObject
->FastIoDispatch
->FastIoRead(FileObject
, &FileObject
->CurrentByteOffset
, Length
, TRUE
, Key
, Buffer
, IoStatusBlock
, DeviceObject
);
196 if (Result
&& NT_SUCCESS(IoStatusBlock
->Status
))
198 /* request was handled and succeeded */
199 return STATUS_SUCCESS
;
203 /* do the slow way */
206 /* initialize temp event */
207 KeInitializeEvent(&LocalEvent
, NotificationEvent
, FALSE
);
211 /* build the irp packet */
212 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
, DeviceObject
, Buffer
, Length
, &FileObject
->CurrentByteOffset
, Event
, IoStatusBlock
);
215 /* not enough resources */
216 return STATUS_INSUFFICIENT_RESOURCES
;
219 /* send the packet */
220 Status
= IoCallDriver(DeviceObject
, Irp
);
222 if (Status
== STATUS_PENDING
)
224 /* operation is pending, is sync file object */
225 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
228 KeWaitForSingleObject(Event
, Executive
, RequestorMode
, FALSE
, NULL
);
229 Status
= IoStatusBlock
->Status
;
243 IN PFILE_OBJECT FileObject
,
244 IN PKEVENT Event OPTIONAL
,
245 IN PVOID PortContext OPTIONAL
,
246 OUT PIO_STATUS_BLOCK IoStatusBlock
,
249 IN ULONG Key OPTIONAL
,
250 IN KPROCESSOR_MODE RequestorMode
)
252 PDEVICE_OBJECT DeviceObject
;
260 /* make sure event is reset */
264 if (RequestorMode
== UserMode
)
266 /* probe the user buffer */
269 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
270 Status
= STATUS_SUCCESS
;
272 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
274 /* Exception, get the error code */
275 Status
= _SEH2_GetExceptionCode();
279 if (!NT_SUCCESS(Status
))
281 DPRINT1("Invalid user buffer provided\n");
286 /* get corresponding device object */
287 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
289 /* fast-io write is only available for kernel mode clients */
290 if (RequestorMode
== KernelMode
&& ExGetPreviousMode() == KernelMode
&&
291 DeviceObject
->DriverObject
->FastIoDispatch
->FastIoWrite
)
293 /* call fast io write */
294 Result
= DeviceObject
->DriverObject
->FastIoDispatch
->FastIoWrite(FileObject
, &FileObject
->CurrentByteOffset
, Length
, TRUE
, Key
, Buffer
, IoStatusBlock
, DeviceObject
);
296 if (Result
&& NT_SUCCESS(IoStatusBlock
->Status
))
298 /* request was handled and succeeded */
299 return STATUS_SUCCESS
;
303 /* do the slow way */
306 /* initialize temp event */
307 KeInitializeEvent(&LocalEvent
, NotificationEvent
, FALSE
);
311 /* build the irp packet */
312 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
, DeviceObject
, Buffer
, Length
, &FileObject
->CurrentByteOffset
, Event
, IoStatusBlock
);
315 /* not enough resources */
316 return STATUS_INSUFFICIENT_RESOURCES
;
319 /* send the packet */
320 Status
= IoCallDriver(DeviceObject
, Irp
);
322 if (Status
== STATUS_PENDING
)
324 /* operation is pending, is sync file object */
325 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
328 KeWaitForSingleObject(Event
, Executive
, RequestorMode
, FALSE
, NULL
);
329 Status
= IoStatusBlock
->Status
;
342 KsQueryInformationFile(
343 IN PFILE_OBJECT FileObject
,
344 OUT PVOID FileInformation
,
346 IN FILE_INFORMATION_CLASS FileInformationClass
)
348 PDEVICE_OBJECT DeviceObject
;
349 PFAST_IO_DISPATCH FastIoDispatch
;
351 PIO_STACK_LOCATION IoStack
;
352 IO_STATUS_BLOCK IoStatus
;
354 LARGE_INTEGER Offset
;
355 IO_STATUS_BLOCK StatusBlock
;
358 /* get related file object */
359 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
361 /* get fast i/o table */
362 FastIoDispatch
= DeviceObject
->DriverObject
->FastIoDispatch
;
364 /* is there a fast table */
367 /* check the class */
368 if (FileInformationClass
== FileBasicInformation
)
370 /* use FastIoQueryBasicInfo routine */
371 if (FastIoDispatch
->FastIoQueryBasicInfo
)
373 return FastIoDispatch
->FastIoQueryBasicInfo(FileObject
, TRUE
, (PFILE_BASIC_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
376 else if (FileInformationClass
== FileStandardInformation
)
378 /* use FastIoQueryBasicInfo routine */
379 if (FastIoDispatch
->FastIoQueryBasicInfo
)
381 return FastIoDispatch
->FastIoQueryStandardInfo(FileObject
, TRUE
, (PFILE_STANDARD_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
386 KeClearEvent(&FileObject
->Event
);
388 /* initialize event */
389 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
391 /* set offset to zero */
392 Offset
.QuadPart
= 0L;
394 /* build the request */
395 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_INFORMATION
, IoGetRelatedDeviceObject(FileObject
), NULL
, 0, &Offset
, &Event
, &StatusBlock
);
398 return STATUS_INSUFFICIENT_RESOURCES
;
400 /* get next stack location */
401 IoStack
= IoGetNextIrpStackLocation(Irp
);
403 /* setup parameters */
404 IoStack
->Parameters
.QueryFile
.FileInformationClass
= FileInformationClass
;
405 IoStack
->Parameters
.QueryFile
.Length
= Length
;
406 Irp
->AssociatedIrp
.SystemBuffer
= FileInformation
;
409 /* call the driver */
410 Status
= IoCallDriver(IoGetRelatedDeviceObject(FileObject
), Irp
);
412 if (Status
== STATUS_PENDING
)
414 /* wait for the operation to complete */
415 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
418 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
419 Status
= FileObject
->FinalStatus
;
421 Status
= StatusBlock
.Status
;
434 KsSetInformationFile(
435 IN PFILE_OBJECT FileObject
,
436 IN PVOID FileInformation
,
438 IN FILE_INFORMATION_CLASS FileInformationClass
)
440 PIO_STACK_LOCATION IoStack
;
441 PDEVICE_OBJECT DeviceObject
;
445 LARGE_INTEGER Offset
;
446 IO_STATUS_BLOCK IoStatus
;
449 /* get related device object */
450 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
452 /* copy file information */
453 Buffer
= AllocateItem(NonPagedPool
, Length
);
455 return STATUS_INSUFFICIENT_RESOURCES
;
459 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
460 RtlMoveMemory(Buffer
, FileInformation
, Length
);
461 Status
= STATUS_SUCCESS
;
463 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
465 /* Exception, get the error code */
466 Status
= _SEH2_GetExceptionCode();
470 if (!NT_SUCCESS(Status
))
472 /* invalid user buffer */
477 /* initialize the event */
478 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
481 Offset
.QuadPart
= 0LL;
484 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_SET_INFORMATION
, DeviceObject
, NULL
, 0, &Offset
, &Event
, &IoStatus
);
488 /* failed to allocate irp */
490 return STATUS_INSUFFICIENT_RESOURCES
;
493 /* get next stack location */
494 IoStack
= IoGetNextIrpStackLocation(Irp
);
496 /* set irp parameters */
497 IoStack
->Parameters
.SetFile
.FileInformationClass
= FileInformationClass
;
498 IoStack
->Parameters
.SetFile
.Length
= Length
;
499 IoStack
->Parameters
.SetFile
.FileObject
= FileObject
;
500 Irp
->AssociatedIrp
.SystemBuffer
= Buffer
;
501 Irp
->UserBuffer
= FileInformation
;
503 /* dispatch the irp */
504 Status
= IoCallDriver(DeviceObject
, Irp
);
506 if (Status
== STATUS_PENDING
)
508 /* wait untill the operation has completed */
509 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
510 /* is a sync file object */
511 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
512 Status
= FileObject
->FinalStatus
;
514 Status
= IoStatus
.Status
;
527 IN PFILE_OBJECT FileObject
,
528 IN PKEVENT Event OPTIONAL
,
529 IN PVOID PortContext OPTIONAL
,
530 IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL
,
531 IN PVOID CompletionContext OPTIONAL
,
532 IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL
,
533 OUT PIO_STATUS_BLOCK IoStatusBlock
,
534 IN OUT PVOID StreamHeaders
,
537 IN KPROCESSOR_MODE RequestorMode
)
540 PIO_STACK_LOCATION IoStack
;
541 PDEVICE_OBJECT DeviceObject
;
543 LARGE_INTEGER Offset
;
544 PKSIOBJECT_HEADER ObjectHeader
;
547 /* get related device object */
548 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
550 ASSERT(DeviceObject
!= NULL
);
552 /* is there a event provided */
559 if (RequestorMode
|| ExGetPreviousMode() == KernelMode
)
561 /* requestor is from kernel land */
562 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext2
;
566 /* there is a object header */
567 if (Flags
== KSSTREAM_READ
)
569 /* is fast read supported */
570 if (ObjectHeader
->DispatchTable
.FastRead
)
572 /* call fast read dispatch routine */
573 Ret
= ObjectHeader
->DispatchTable
.FastRead(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
);
577 /* the request was handled */
578 return IoStatusBlock
->Status
;
582 else if (Flags
== KSSTREAM_WRITE
)
584 /* is fast write supported */
585 if (ObjectHeader
->DispatchTable
.FastWrite
)
587 /* call fast write dispatch routine */
588 Ret
= ObjectHeader
->DispatchTable
.FastWrite(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
);
592 /* the request was handled */
593 return IoStatusBlock
->Status
;
600 /* clear file object event */
601 KeClearEvent(&FileObject
->Event
);
603 /* set the offset to zero */
604 Offset
.QuadPart
= 0LL;
606 /* now build the irp */
607 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL
,
608 DeviceObject
, (PVOID
)StreamHeaders
, Length
, &Offset
, Event
, IoStatusBlock
);
611 /* not enough memory */
612 return STATUS_INSUFFICIENT_RESOURCES
;
615 /* setup irp parameters */
616 Irp
->RequestorMode
= RequestorMode
;
617 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= PortContext
;
618 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
619 Irp
->UserBuffer
= StreamHeaders
;
621 /* get next irp stack location */
622 IoStack
= IoGetNextIrpStackLocation(Irp
);
623 /* setup stack parameters */
624 IoStack
->FileObject
= FileObject
;
625 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= Length
;
626 IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
= StreamHeaders
;
627 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= (Flags
== KSSTREAM_READ
? IOCTL_KS_READ_STREAM
: IOCTL_KS_WRITE_STREAM
);
629 if (CompletionRoutine
)
631 /* setup completion routine for async processing */
632 IoSetCompletionRoutine(Irp
, CompletionRoutine
, CompletionContext
, (CompletionInvocationFlags
& KsInvokeOnSuccess
), (CompletionInvocationFlags
& KsInvokeOnError
), (CompletionInvocationFlags
& KsInvokeOnCancel
));
635 /* now call the driver */
636 Status
= IoCallDriver(DeviceObject
, Irp
);
654 LOCK_OPERATION Operation
;
655 NTSTATUS Status
= STATUS_SUCCESS
;
656 PKSSTREAM_HEADER StreamHeader
;
657 PIO_STACK_LOCATION IoStack
;
659 //BOOLEAN AllocateMdl = FALSE;
661 /* get current irp stack */
662 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
664 Length
= IoStack
->Parameters
.DeviceIoControl
.OutputBufferLength
;
666 if (Irp
->RequestorMode
== KernelMode
|| Irp
->AssociatedIrp
.SystemBuffer
)
668 if (Irp
->RequestorMode
== KernelMode
)
670 /* no need to allocate stream header */
671 Irp
->AssociatedIrp
.SystemBuffer
= Irp
->UserBuffer
;
674 /* check if alloc mdl flag is passed */
675 if (!(ProbeFlags
& KSPROBE_ALLOCATEMDL
))
677 /* nothing more to do */
678 return STATUS_SUCCESS
;
683 if (ProbeFlags
& KSPROBE_PROBEANDLOCK
)
685 if (Irp
->MdlAddress
->MdlFlags
& (MDL_PAGES_LOCKED
| MDL_SOURCE_IS_NONPAGED_POOL
))
687 if (ProbeFlags
& KSPROBE_SYSTEMADDRESS
)
691 /* loop through all mdls and probe them */
692 Mdl
= Irp
->MdlAddress
;
695 /* the mapping can fail */
696 Mdl
->MdlFlags
|= MDL_MAPPING_CAN_FAIL
;
698 if (Mdl
->MdlFlags
& (MDL_MAPPED_TO_SYSTEM_VA
| MDL_SOURCE_IS_NONPAGED_POOL
))
700 /* no need to probe these pages */
701 Buffer
= Mdl
->MappedSystemVa
;
706 Buffer
= MmMapLockedPages(Mdl
, KernelMode
);
709 /* check if the mapping succeeded */
712 /* raise exception we'll catch */
713 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
716 /* iterate to next mdl */
721 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
723 /* Exception, get the error code */
724 Status
= _SEH2_GetExceptionCode();
732 /* loop through all mdls and probe them */
733 Mdl
= Irp
->MdlAddress
;
735 /* determine operation */
736 if (!(ProbeFlags
& KSPROBE_STREAMWRITE
) || (ProbeFlags
& KSPROBE_MODIFY
))
738 /* operation is read / modify stream, need write access */
739 Operation
= IoWriteAccess
;
743 /* operation is write to device, so we need read access */
744 Operation
= IoReadAccess
;
749 /* probe the pages */
750 MmProbeAndLockPages(Mdl
, Irp
->RequestorMode
, Operation
);
752 if (ProbeFlags
& KSPROBE_SYSTEMADDRESS
)
754 /* the mapping can fail */
755 Mdl
->MdlFlags
|= MDL_MAPPING_CAN_FAIL
;
757 if (Mdl
->MdlFlags
& (MDL_MAPPED_TO_SYSTEM_VA
| MDL_SOURCE_IS_NONPAGED_POOL
))
759 /* no need to probe these pages */
760 Buffer
= Mdl
->MappedSystemVa
;
765 Buffer
= MmMapLockedPages(Mdl
, KernelMode
);
768 /* check if the mapping succeeded */
771 /* raise exception we'll catch */
772 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
776 /* iterate to next mdl */
781 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
783 /* Exception, get the error code */
784 Status
= _SEH2_GetExceptionCode();
791 /* check all stream headers */
792 StreamHeader
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
793 ASSERT(StreamHeader
);
800 /* does the supplied header size match stream header size and no type changed */
801 if (StreamHeader
->Size
!= HeaderSize
&& !(StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
))
803 /* invalid stream header */
804 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
809 /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */
810 if (StreamHeader
->Size
< sizeof(KSSTREAM_HEADER
) || (StreamHeader
->Size
& 7))
812 /* invalid stream header */
813 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
817 if (Length
< StreamHeader
->Size
)
819 /* length is too short */
820 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
823 if (ProbeFlags
& KSPROBE_STREAMWRITE
)
825 if (StreamHeader
->DataUsed
> StreamHeader
->FrameExtent
)
827 /* frame extend can never be smaller */
828 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
831 /* is this stream change packet */
832 if (StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
)
834 if (Length
!= sizeof(KSSTREAM_HEADER
) || (PVOID
)StreamHeader
!= Irp
->AssociatedIrp
.SystemBuffer
)
836 /* stream changed - must be send in a single packet */
837 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
840 if (!(ProbeFlags
& KSPROBE_ALLOWFORMATCHANGE
))
842 /* caller does not permit format changes */
843 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
846 if (StreamHeader
->FrameExtent
)
848 /* allocate an mdl */
849 Mdl
= IoAllocateMdl(StreamHeader
->Data
, StreamHeader
->FrameExtent
, FALSE
, TRUE
, Irp
);
853 /* not enough memory */
854 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
857 /* break-out to probe for the irp */
864 if (StreamHeader
->DataUsed
)
866 /* DataUsed must be zero for stream read operation */
867 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
870 if (StreamHeader
->OptionsFlags
)
872 /* no flags supported for reading */
873 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
877 if (StreamHeader
->FrameExtent
)
879 /* allocate an mdl */
880 ASSERT(Irp
->MdlAddress
== NULL
);
881 Mdl
= IoAllocateMdl(StreamHeader
->Data
, StreamHeader
->FrameExtent
, FALSE
, TRUE
, Irp
);
884 /* not enough memory */
885 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
889 /* move to next stream header */
890 Length
-= StreamHeader
->Size
;
891 StreamHeader
= (PKSSTREAM_HEADER
)((ULONG_PTR
)StreamHeader
+ StreamHeader
->Size
);
894 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
896 /* Exception, get the error code */
897 Status
= _SEH2_GetExceptionCode();
900 /* now probe the allocated mdl's */
901 if (!NT_SUCCESS(Status
))
903 DPRINT("Status %x\n", Status
);
910 /* probe user mode buffers */
911 if (Length
&& ( (!HeaderSize
) || (Length
% HeaderSize
== 0) || ((ProbeFlags
& KSPROBE_ALLOWFORMATCHANGE
) && (Length
== sizeof(KSSTREAM_HEADER
))) ) )
913 /* allocate stream header buffer */
914 Irp
->AssociatedIrp
.SystemBuffer
= AllocateItem(NonPagedPool
, Length
);
916 if (!Irp
->AssociatedIrp
.SystemBuffer
)
919 return STATUS_INSUFFICIENT_RESOURCES
;
922 /* mark irp as buffered so that changes the stream headers are propagated back */
923 Irp
->Flags
= IRP_DEALLOCATE_BUFFER
| IRP_BUFFERED_IO
;
927 if (ProbeFlags
& KSPROBE_STREAMWRITE
)
929 if (ProbeFlags
& KSPROBE_MODIFY
)
930 ProbeForWrite(Irp
->UserBuffer
, Length
, sizeof(UCHAR
));
932 ProbeForRead(Irp
->UserBuffer
, Length
, sizeof(UCHAR
));
936 /* stream reads means writing */
937 ProbeForWrite(Irp
->UserBuffer
, Length
, sizeof(UCHAR
));
939 /* set input operation flags */
940 Irp
->Flags
|= IRP_INPUT_OPERATION
;
943 /* copy stream buffer */
944 RtlMoveMemory(Irp
->AssociatedIrp
.SystemBuffer
, Irp
->UserBuffer
, Length
);
946 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
948 /* Exception, get the error code */
949 Status
= _SEH2_GetExceptionCode();
952 if (!NT_SUCCESS(Status
))
958 if (ProbeFlags
& KSPROBE_ALLOCATEMDL
)
964 /* check all stream headers */
965 StreamHeader
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
973 /* does the supplied header size match stream header size and no type changed */
974 if (StreamHeader
->Size
!= HeaderSize
&& !(StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
))
976 /* invalid stream header */
977 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
982 /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */
983 if (StreamHeader
->Size
< sizeof(KSSTREAM_HEADER
) || (StreamHeader
->Size
& 7))
985 /* invalid stream header */
986 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
990 if (Length
< StreamHeader
->Size
)
992 /* length is too short */
993 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
996 if (ProbeFlags
& KSPROBE_STREAMWRITE
)
998 if (StreamHeader
->DataUsed
> StreamHeader
->FrameExtent
)
1000 /* frame extend can never be smaller */
1001 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
1004 /* is this stream change packet */
1005 if (StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
)
1007 if (Length
!= sizeof(KSSTREAM_HEADER
) || (PVOID
)StreamHeader
!= Irp
->AssociatedIrp
.SystemBuffer
)
1009 /* stream changed - must be send in a single packet */
1010 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
1013 if (!(ProbeFlags
& KSPROBE_ALLOWFORMATCHANGE
))
1015 /* caller does not permit format changes */
1016 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
1019 if (StreamHeader
->FrameExtent
)
1021 /* allocate an mdl */
1022 Mdl
= IoAllocateMdl(StreamHeader
->Data
, StreamHeader
->FrameExtent
, FALSE
, TRUE
, Irp
);
1026 /* not enough memory */
1027 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
1030 /* break out to probe for the irp */
1031 //AllocateMdl = TRUE;
1038 if (StreamHeader
->DataUsed
)
1040 /* DataUsed must be zero for stream read operation */
1041 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
1044 if (StreamHeader
->OptionsFlags
)
1046 /* no flags supported for reading */
1047 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
1051 /* move to next stream header */
1052 Length
-= StreamHeader
->Size
;
1053 StreamHeader
= (PKSSTREAM_HEADER
)((ULONG_PTR
)StreamHeader
+ StreamHeader
->Size
);
1056 }_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1058 /* Exception, get the error code */
1059 Status
= _SEH2_GetExceptionCode();
1062 /* now probe the allocated mdl's */
1063 if (NT_SUCCESS(Status
))
1069 return STATUS_INVALID_BUFFER_SIZE
;
1078 KsAllocateExtraData(
1081 OUT PVOID
* ExtraBuffer
)
1083 PIO_STACK_LOCATION IoStack
;
1085 PUCHAR Buffer
, BufferOrg
;
1086 PKSSTREAM_HEADER Header
;
1087 NTSTATUS Status
= STATUS_SUCCESS
;
1089 /* get current irp stack */
1090 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1093 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSSTREAM_HEADER
));
1095 /* get total length */
1096 Count
= IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
/ sizeof(KSSTREAM_HEADER
);
1098 /* allocate buffer */
1099 Buffer
= BufferOrg
= AllocateItem(NonPagedPool
, Count
* (sizeof(KSSTREAM_HEADER
) + ExtraSize
));
1101 return STATUS_INSUFFICIENT_RESOURCES
;
1105 /* get input buffer */
1106 Header
= (PKSSTREAM_HEADER
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1107 for(Index
= 0; Index
< Count
; Index
++)
1109 /* copy stream header */
1110 RtlMoveMemory(Buffer
, Header
, sizeof(KSSTREAM_HEADER
));
1112 /* move to next header */
1114 /* increment output buffer offset */
1115 Buffer
+= sizeof(KSSTREAM_HEADER
) + ExtraSize
;
1118 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1120 /* Exception, get the error code */
1121 Status
= _SEH2_GetExceptionCode();
1125 if (!NT_SUCCESS(Status
))
1127 /* free buffer on exception */
1133 *ExtraBuffer
= BufferOrg
;
1136 return STATUS_SUCCESS
;
1146 IN PDRIVER_OBJECT DriverObject
)
1156 KsDispatchInvalidDeviceRequest(
1157 IN PDEVICE_OBJECT DeviceObject
,
1160 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
1161 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1163 return STATUS_INVALID_DEVICE_REQUEST
;
1172 KsDefaultDeviceIoCompletion(
1173 IN PDEVICE_OBJECT DeviceObject
,
1176 PIO_STACK_LOCATION IoStack
;
1179 /* get current irp stack */
1180 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1182 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
&&
1183 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_METHOD
&&
1184 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_ENABLE_EVENT
&&
1185 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_DISABLE_EVENT
)
1187 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_RESET_STATE
)
1190 Status
= STATUS_SUCCESS
;
1194 /* request unsupported */
1195 Status
= STATUS_INVALID_DEVICE_REQUEST
;
1200 /* property / method / event not found */
1201 Status
= STATUS_PROPSET_NOT_FOUND
;
1204 /* complete request */
1205 Irp
->IoStatus
.Status
= Status
;
1206 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1218 KsDispatchFastIoDeviceControlFailure(
1219 IN PFILE_OBJECT FileObject
,
1221 IN PVOID InputBuffer OPTIONAL
,
1222 IN ULONG InputBufferLength
,
1223 OUT PVOID OutputBuffer OPTIONAL
,
1224 IN ULONG OutputBufferLength
,
1225 IN ULONG IoControlCode
,
1226 OUT PIO_STATUS_BLOCK IoStatus
,
1227 IN PDEVICE_OBJECT DeviceObject
)
1238 KsDispatchFastReadFailure(
1239 IN PFILE_OBJECT FileObject
,
1240 IN PLARGE_INTEGER FileOffset
,
1245 OUT PIO_STATUS_BLOCK IoStatus
,
1246 IN PDEVICE_OBJECT DeviceObject
)
1259 IN OUT PLIST_ENTRY QueueHead
,
1260 IN PKSPIN_LOCK SpinLock
)
1262 PDRIVER_CANCEL OldDriverCancel
;
1263 PIO_STACK_LOCATION IoStack
;
1265 PLIST_ENTRY NextEntry
;
1269 /* acquire spinlock */
1270 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1271 /* point to first entry */
1272 Entry
= QueueHead
->Flink
;
1273 /* loop all items */
1274 while(Entry
!= QueueHead
)
1276 /* get irp offset */
1277 Irp
= (PIRP
)CONTAINING_RECORD(Entry
, IRP
, Tail
.Overlay
.ListEntry
);
1279 /* get next entry */
1280 NextEntry
= Entry
->Flink
;
1282 /* set cancelled bit */
1285 /* now set the cancel routine */
1286 OldDriverCancel
= IoSetCancelRoutine(Irp
, NULL
);
1287 if (OldDriverCancel
)
1289 /* this irp hasnt been yet used, so free to cancel */
1290 KeReleaseSpinLock(SpinLock
, OldLevel
);
1292 /* get current irp stack */
1293 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1295 /* acquire cancel spinlock */
1296 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1298 /* call provided cancel routine */
1299 OldDriverCancel(IoStack
->DeviceObject
, Irp
);
1301 /* re-acquire spinlock */
1302 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1305 /* move on to next entry */
1309 /* the irp has already been canceled */
1310 KeReleaseSpinLock(SpinLock
, OldLevel
);
1320 KsReleaseIrpOnCancelableQueue(
1322 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
1324 PKSPIN_LOCK SpinLock
;
1325 PDRIVER_CANCEL OldDriverCancel
;
1326 PIO_STACK_LOCATION IoStack
;
1329 /* check for required parameters */
1335 /* default to KsCancelRoutine */
1336 DriverCancel
= KsCancelRoutine
;
1339 /* get current irp stack */
1340 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1342 /* get internal queue lock */
1343 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1345 /* acquire spinlock */
1346 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1348 /* now set the cancel routine */
1349 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
1351 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
1353 /* the irp has already been canceled */
1354 KeReleaseSpinLock(SpinLock
, OldLevel
);
1356 /* cancel routine requires that cancel spinlock is held */
1357 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1360 DriverCancel(IoStack
->DeviceObject
, Irp
);
1365 KeReleaseSpinLock(SpinLock
, OldLevel
);
1375 KsRemoveIrpFromCancelableQueue(
1376 IN OUT PLIST_ENTRY QueueHead
,
1377 IN PKSPIN_LOCK SpinLock
,
1378 IN KSLIST_ENTRY_LOCATION ListLocation
,
1379 IN KSIRP_REMOVAL_OPERATION RemovalOperation
)
1382 PLIST_ENTRY CurEntry
;
1385 DPRINT("KsRemoveIrpFromCancelableQueue ListHead %p SpinLock %p ListLocation %x RemovalOperation %x\n", QueueHead
, SpinLock
, ListLocation
, RemovalOperation
);
1387 /* check parameters */
1388 if (!QueueHead
|| !SpinLock
)
1391 /* check if parameter ListLocation is valid */
1392 if (ListLocation
!= KsListEntryTail
&& ListLocation
!= KsListEntryHead
)
1395 /* acquire list lock */
1396 KeAcquireSpinLock(SpinLock
, &OldIrql
);
1398 /* point to queue head */
1399 CurEntry
= QueueHead
;
1403 /* reset irp to null */
1406 /* iterate to next entry */
1407 if (ListLocation
== KsListEntryHead
)
1408 CurEntry
= CurEntry
->Flink
;
1410 CurEntry
= CurEntry
->Blink
;
1412 /* is the end of list reached */
1413 if (CurEntry
== QueueHead
)
1415 /* reached end of list */
1419 /* get irp offset */
1420 Irp
= (PIRP
)CONTAINING_RECORD(CurEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1424 /* irp has been canceled */
1428 if (Irp
->CancelRoutine
)
1430 /* remove cancel routine */
1431 Irp
->CancelRoutine
= NULL
;
1433 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
1435 /* remove irp from list */
1436 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1439 if (RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
|| RemovalOperation
== KsAcquireOnlySingleItem
)
1446 KeReleaseSpinLock(SpinLock
, OldIrql
);
1448 if (!Irp
|| Irp
->CancelRoutine
== NULL
)
1450 /* either an irp has been acquired or nothing found */
1454 /* time to remove the canceled irp */
1455 IoAcquireCancelSpinLock(&OldIrql
);
1456 /* acquire list lock */
1457 KeAcquireSpinLockAtDpcLevel(SpinLock
);
1459 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
1462 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1465 /* release list lock */
1466 KeReleaseSpinLockFromDpcLevel(SpinLock
);
1468 /* release cancel spinlock */
1469 IoReleaseCancelSpinLock(OldIrql
);
1470 /* no non canceled irp has been found */
1480 KsMoveIrpsOnCancelableQueue(
1481 IN OUT PLIST_ENTRY SourceList
,
1482 IN PKSPIN_LOCK SourceLock
,
1483 IN OUT PLIST_ENTRY DestinationList
,
1484 IN PKSPIN_LOCK DestinationLock OPTIONAL
,
1485 IN KSLIST_ENTRY_LOCATION ListLocation
,
1486 IN PFNKSIRPLISTCALLBACK ListCallback
,
1490 PLIST_ENTRY SrcEntry
;
1492 NTSTATUS Status
= STATUS_SUCCESS
;
1494 if (!DestinationLock
)
1496 /* no destination lock just acquire the source lock */
1497 KeAcquireSpinLock(SourceLock
, &OldLevel
);
1501 /* acquire cancel spinlock */
1502 IoAcquireCancelSpinLock(&OldLevel
);
1504 /* now acquire source lock */
1505 KeAcquireSpinLockAtDpcLevel(SourceLock
);
1507 /* now acquire destination lock */
1508 KeAcquireSpinLockAtDpcLevel(DestinationLock
);
1511 /* point to list head */
1512 SrcEntry
= SourceList
;
1514 /* now move all irps */
1517 if (ListLocation
== KsListEntryTail
)
1519 /* move queue downwards */
1520 SrcEntry
= SrcEntry
->Flink
;
1524 /* move queue upwards */
1525 SrcEntry
= SrcEntry
->Blink
;
1528 if (SrcEntry
== SourceList
)
1530 /* eof list reached */
1534 /* get irp offset */
1535 Irp
= (PIRP
)CONTAINING_RECORD(SrcEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1537 /* now check if irp can be moved */
1538 Status
= ListCallback(Irp
, Context
);
1540 /* check if irp can be moved */
1541 if (Status
== STATUS_SUCCESS
)
1543 /* remove irp from src list */
1544 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1546 if (ListLocation
== KsListEntryTail
)
1548 /* insert irp end of list */
1549 InsertTailList(DestinationList
, &Irp
->Tail
.Overlay
.ListEntry
);
1553 /* insert irp head of list */
1554 InsertHeadList(DestinationList
, &Irp
->Tail
.Overlay
.ListEntry
);
1557 /* do we need to update the irp lock */
1558 if (DestinationLock
)
1560 /* update irp lock */
1561 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
) = DestinationLock
;
1566 if (Status
!= STATUS_NO_MATCH
)
1568 /* callback decided to stop enumeration */
1572 /* reset return value */
1573 Status
= STATUS_SUCCESS
;
1577 if (!DestinationLock
)
1579 /* release source lock */
1580 KeReleaseSpinLock(SourceLock
, OldLevel
);
1584 /* now release destination lock */
1585 KeReleaseSpinLockFromDpcLevel(DestinationLock
);
1587 /* now release source lock */
1588 KeReleaseSpinLockFromDpcLevel(SourceLock
);
1591 /* now release cancel spinlock */
1592 IoReleaseCancelSpinLock(OldLevel
);
1605 KsRemoveSpecificIrpFromCancelableQueue(
1608 PKSPIN_LOCK SpinLock
;
1611 DPRINT("KsRemoveSpecificIrpFromCancelableQueue %p\n", Irp
);
1613 /* get internal queue lock */
1614 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1616 /* acquire spinlock */
1617 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1619 /* remove the irp from the list */
1620 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1622 /* release spinlock */
1623 KeReleaseSpinLock(SpinLock
, OldLevel
);
1633 KsAddIrpToCancelableQueue(
1634 IN OUT PLIST_ENTRY QueueHead
,
1635 IN PKSPIN_LOCK SpinLock
,
1637 IN KSLIST_ENTRY_LOCATION ListLocation
,
1638 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
1640 PDRIVER_CANCEL OldDriverCancel
;
1641 PIO_STACK_LOCATION IoStack
;
1644 /* check for required parameters */
1645 if (!QueueHead
|| !SpinLock
|| !Irp
)
1648 /* get current irp stack */
1649 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1651 DPRINT("KsAddIrpToCancelableQueue QueueHead %p SpinLock %p Irp %p ListLocation %x DriverCancel %p\n", QueueHead
, SpinLock
, Irp
, ListLocation
, DriverCancel
);
1653 // HACK for ms portcls
1654 if (IoStack
->MajorFunction
== IRP_MJ_CREATE
)
1656 // complete the request
1657 DPRINT1("MS HACK\n");
1658 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1659 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1667 /* default to KsCancelRoutine */
1668 DriverCancel
= KsCancelRoutine
;
1672 /* acquire spinlock */
1673 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1675 if (ListLocation
== KsListEntryTail
)
1677 /* insert irp to tail of list */
1678 InsertTailList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1682 /* insert irp to head of list */
1683 InsertHeadList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1686 /* store internal queue lock */
1687 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
) = SpinLock
;
1689 /* now set the cancel routine */
1690 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
1692 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
1694 /* the irp has already been canceled */
1695 KeReleaseSpinLock(SpinLock
, OldLevel
);
1697 /* cancel routine requires that cancel spinlock is held */
1698 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1701 DriverCancel(IoStack
->DeviceObject
, Irp
);
1706 KeReleaseSpinLock(SpinLock
, OldLevel
);
1717 IN PDEVICE_OBJECT DeviceObject
,
1720 PKSPIN_LOCK SpinLock
;
1722 /* get internal queue lock */
1723 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1725 /* acquire spinlock */
1726 KeAcquireSpinLockAtDpcLevel(SpinLock
);
1729 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1731 /* release cancel spinlock */
1732 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
1734 /* remove the irp from the list */
1735 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1737 /* release spinlock */
1738 KeReleaseSpinLock(SpinLock
, Irp
->CancelIrql
);
1740 /* has the irp already been canceled */
1741 if (Irp
->IoStatus
.Status
!= STATUS_CANCELLED
)
1743 /* let's complete it */
1744 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
1745 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1750 FindMatchingCreateItem(
1751 PLIST_ENTRY ListHead
,
1752 PUNICODE_STRING String
,
1753 OUT PCREATE_ITEM_ENTRY
*OutCreateItem
)
1756 PCREATE_ITEM_ENTRY CreateItemEntry
;
1757 UNICODE_STRING RefString
;
1761 /* Copy the input string */
1762 RefString
= *String
;
1764 /* Check if the string starts with a backslash */
1765 if (String
->Buffer
[0] == L
'\\')
1767 /* Skip backslash */
1769 RefString
.Length
-= sizeof(WCHAR
);
1773 /* get terminator */
1774 pStr
= String
->Buffer
;
1775 Count
= String
->Length
/ sizeof(WCHAR
);
1776 while ((Count
> 0) && (*pStr
!= L
'\\'))
1785 // request is for pin / node / allocator
1786 RefString
.Length
= (USHORT
)((PCHAR
)pStr
- (PCHAR
)String
->Buffer
);
1789 /* point to first entry */
1790 Entry
= ListHead
->Flink
;
1792 /* loop all device items */
1793 while (Entry
!= ListHead
)
1795 /* get create item entry */
1796 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
,
1800 ASSERT(CreateItemEntry
->CreateItem
);
1802 if(CreateItemEntry
->CreateItem
->Flags
& KSCREATE_ITEM_WILDCARD
)
1804 /* create item is default */
1805 *OutCreateItem
= CreateItemEntry
;
1806 return STATUS_SUCCESS
;
1809 if (!CreateItemEntry
->CreateItem
->Create
)
1811 /* skip free create item */
1812 Entry
= Entry
->Flink
;
1816 DPRINT("CreateItem %S Length %u Request %wZ %u\n",
1817 CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
,
1818 CreateItemEntry
->CreateItem
->ObjectClass
.Length
,
1822 if (CreateItemEntry
->CreateItem
->ObjectClass
.Length
> RefString
.Length
)
1824 /* create item doesnt match in length */
1825 Entry
= Entry
->Flink
;
1829 /* now check if the object class is the same */
1830 if (!RtlCompareUnicodeString(&CreateItemEntry
->CreateItem
->ObjectClass
,
1834 /* found matching create item */
1835 *OutCreateItem
= CreateItemEntry
;
1836 return STATUS_SUCCESS
;
1838 /* iterate to next */
1839 Entry
= Entry
->Flink
;
1842 return STATUS_NOT_FOUND
;
1848 IN PDEVICE_OBJECT DeviceObject
,
1851 PCREATE_ITEM_ENTRY CreateItemEntry
;
1852 PIO_STACK_LOCATION IoStack
;
1853 PDEVICE_EXTENSION DeviceExtension
;
1854 PKSIDEVICE_HEADER DeviceHeader
;
1855 PKSIOBJECT_HEADER ObjectHeader
;
1858 DPRINT("KS / CREATE\n");
1860 /* get current stack location */
1861 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1862 /* get device extension */
1863 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1864 /* get device header */
1865 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1868 if (IoStack
->FileObject
->FileName
.Buffer
== NULL
)
1870 /* FIXME Pnp-Issue */
1871 DPRINT("Using reference string hack\n");
1872 Irp
->IoStatus
.Information
= 0;
1873 /* set return status */
1874 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1875 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1876 return STATUS_SUCCESS
;
1879 if (IoStack
->FileObject
->RelatedFileObject
!= NULL
)
1881 /* request is to instantiate a pin / node / clock / allocator */
1882 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->RelatedFileObject
->FsContext2
;
1885 ASSERT(ObjectHeader
);
1887 /* find a matching a create item */
1888 Status
= FindMatchingCreateItem(&ObjectHeader
->ItemList
,
1889 &IoStack
->FileObject
->FileName
,
1894 /* request to create a filter */
1895 Status
= FindMatchingCreateItem(&DeviceHeader
->ItemList
,
1896 &IoStack
->FileObject
->FileName
,
1900 if (NT_SUCCESS(Status
))
1902 /* set object create item */
1903 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
1905 /* call create function */
1906 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
1908 if (NT_SUCCESS(Status
))
1910 /* increment create item reference count */
1911 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
1916 Irp
->IoStatus
.Information
= 0;
1917 /* set return status */
1918 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1919 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1920 return STATUS_UNSUCCESSFUL
;
1926 IN PDEVICE_OBJECT DeviceObject
,
1929 PIO_STACK_LOCATION IoStack
;
1930 //PDEVICE_EXTENSION DeviceExtension;
1931 PKSIOBJECT_HEADER ObjectHeader
;
1932 //PKSIDEVICE_HEADER DeviceHeader;
1933 PDRIVER_DISPATCH Dispatch
;
1936 /* get current stack location */
1937 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1939 /* get device extension */
1940 //DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
1941 /* get device header */
1942 //DeviceHeader = DeviceExtension->DeviceHeader;
1944 ASSERT(IoStack
->FileObject
);
1946 /* get object header */
1947 ObjectHeader
= (PKSIOBJECT_HEADER
) IoStack
->FileObject
->FsContext2
;
1951 /* FIXME Pnp-Issue*/
1952 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1953 Irp
->IoStatus
.Information
= 0;
1954 /* complete and forget */
1955 CompleteRequest(Irp
, IO_NO_INCREMENT
);
1956 return STATUS_SUCCESS
;
1960 ASSERT(ObjectHeader
);
1961 /* store create item */
1962 //KSCREATE_ITEM_IRP_STORAGE(Irp) = (PKSOBJECT_CREATE_ITEM)0x12345678; //ObjectHeader->CreateItem;
1964 /* retrieve matching dispatch function */
1965 switch(IoStack
->MajorFunction
)
1968 Dispatch
= ObjectHeader
->DispatchTable
.Close
;
1970 case IRP_MJ_DEVICE_CONTROL
:
1971 Dispatch
= ObjectHeader
->DispatchTable
.DeviceIoControl
;
1974 Dispatch
= ObjectHeader
->DispatchTable
.Read
;
1977 Dispatch
= ObjectHeader
->DispatchTable
.Write
;
1979 case IRP_MJ_FLUSH_BUFFERS
:
1980 Dispatch
= ObjectHeader
->DispatchTable
.Flush
;
1982 case IRP_MJ_QUERY_SECURITY
:
1983 Dispatch
= ObjectHeader
->DispatchTable
.QuerySecurity
;
1985 case IRP_MJ_SET_SECURITY
:
1986 Dispatch
= ObjectHeader
->DispatchTable
.SetSecurity
;
1989 Dispatch
= KsDefaultDispatchPnp
;
1995 /* is the request supported */
1998 /* now call the dispatch function */
1999 Status
= Dispatch(DeviceObject
, Irp
);
2003 /* not supported request */
2004 Status
= KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
2017 KsSetMajorFunctionHandler(
2018 IN PDRIVER_OBJECT DriverObject
,
2019 IN ULONG MajorFunction
)
2021 DPRINT("KsSetMajorFunctionHandler Function %x\n", MajorFunction
);
2023 switch ( MajorFunction
)
2026 DriverObject
->MajorFunction
[MajorFunction
] = KspCreate
;
2028 case IRP_MJ_DEVICE_CONTROL
:
2032 case IRP_MJ_FLUSH_BUFFERS
:
2033 case IRP_MJ_QUERY_SECURITY
:
2034 case IRP_MJ_SET_SECURITY
:
2035 DriverObject
->MajorFunction
[MajorFunction
] = KspDispatchIrp
;
2038 DPRINT1("NotSupported %x\n", MajorFunction
);
2039 return STATUS_INVALID_PARAMETER
;
2042 return STATUS_SUCCESS
;
2052 IN PDEVICE_OBJECT DeviceObject
,
2055 PIO_STACK_LOCATION IoStack
;
2056 PKSIDEVICE_HEADER DeviceHeader
;
2057 PDEVICE_EXTENSION DeviceExtension
;
2059 DPRINT("KsDispatchIrp DeviceObject %p Irp %p\n", DeviceObject
, Irp
);
2061 /* get device extension */
2062 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
2064 /* get device header */
2065 DeviceHeader
= DeviceExtension
->DeviceHeader
;
2068 /* get current irp stack */
2069 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2071 if (IoStack
->MajorFunction
<= IRP_MJ_DEVICE_CONTROL
)
2073 if (IoStack
->MajorFunction
== IRP_MJ_CREATE
)
2075 /* check internal type */
2076 if (DeviceHeader
->BasicHeader
.OuterUnknown
) /* FIXME improve check */
2078 /* AVStream client */
2079 return IKsDevice_Create(DeviceObject
, Irp
);
2083 /* external client (portcls) */
2084 return KspCreate(DeviceObject
, Irp
);
2088 switch (IoStack
->MajorFunction
)
2093 case IRP_MJ_FLUSH_BUFFERS
:
2094 case IRP_MJ_QUERY_SECURITY
:
2095 case IRP_MJ_SET_SECURITY
:
2097 case IRP_MJ_DEVICE_CONTROL
:
2098 return KspDispatchIrp(DeviceObject
, Irp
);
2100 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
2104 /* dispatch power */
2105 if (IoStack
->MajorFunction
== IRP_MJ_POWER
)
2107 /* check internal type */
2108 if (DeviceHeader
->BasicHeader
.OuterUnknown
) /* FIXME improve check */
2110 /* AVStream client */
2111 return IKsDevice_Power(DeviceObject
, Irp
);
2115 /* external client (portcls) */
2116 return KsDefaultDispatchPower(DeviceObject
, Irp
);
2119 else if (IoStack
->MajorFunction
== IRP_MJ_PNP
) /* dispatch pnp */
2121 /* check internal type */
2122 if (DeviceHeader
->BasicHeader
.OuterUnknown
) /* FIXME improve check */
2124 /* AVStream client */
2125 return IKsDevice_Pnp(DeviceObject
, Irp
);
2129 /* external client (portcls) */
2130 return KsDefaultDispatchPnp(DeviceObject
, Irp
);
2133 else if (IoStack
->MajorFunction
== IRP_MJ_SYSTEM_CONTROL
)
2136 return KsDefaultForwardIrp(DeviceObject
, Irp
);
2141 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
2155 return KSFILTER_NODE
;