2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/factory.c
5 * PURPOSE: KS Allocator functions
6 * PROGRAMMER: Johannes Anderwald
18 KsDispatchQuerySecurity(
19 IN PDEVICE_OBJECT DeviceObject
,
22 PKSOBJECT_CREATE_ITEM CreateItem
;
23 PIO_STACK_LOCATION IoStack
;
27 /* get current irp stack */
28 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
31 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
33 if (!CreateItem
|| !CreateItem
->SecurityDescriptor
)
36 Irp
->IoStatus
.Status
= STATUS_NO_SECURITY_ON_OBJECT
;
37 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
38 return STATUS_NO_SECURITY_ON_OBJECT
;
42 /* get input length */
43 Length
= IoStack
->Parameters
.QuerySecurity
.Length
;
45 /* clone the security descriptor */
46 Status
= SeQuerySecurityDescriptorInfo(&IoStack
->Parameters
.QuerySecurity
.SecurityInformation
, (PSECURITY_DESCRIPTOR
)Irp
->UserBuffer
, &Length
, &CreateItem
->SecurityDescriptor
);
48 DPRINT("SeQuerySecurityDescriptorInfo Status %x\n", Status
);
50 Irp
->IoStatus
.Status
= Status
;
51 Irp
->IoStatus
.Information
= Length
;
53 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
63 KsDispatchSetSecurity(
64 IN PDEVICE_OBJECT DeviceObject
,
67 PKSOBJECT_CREATE_ITEM CreateItem
;
68 PIO_STACK_LOCATION IoStack
;
69 PGENERIC_MAPPING Mapping
;
70 PSECURITY_DESCRIPTOR Descriptor
;
73 /* get current irp stack */
74 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
77 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
79 if (!CreateItem
|| !CreateItem
->SecurityDescriptor
)
82 Irp
->IoStatus
.Status
= STATUS_NO_SECURITY_ON_OBJECT
;
83 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
84 return STATUS_NO_SECURITY_ON_OBJECT
;
87 /* backup old descriptor */
88 Descriptor
= CreateItem
->SecurityDescriptor
;
90 /* get generic mapping */
91 Mapping
= IoGetFileObjectGenericMapping();
93 /* change security descriptor */
94 Status
= SeSetSecurityDescriptorInfo(NULL
, /*FIXME */
95 &IoStack
->Parameters
.SetSecurity
.SecurityInformation
,
96 IoStack
->Parameters
.SetSecurity
.SecurityDescriptor
,
97 &CreateItem
->SecurityDescriptor
,
101 if (NT_SUCCESS(Status
))
103 /* free old descriptor */
104 ExFreePool(Descriptor
);
106 /* mark create item as changed */
107 CreateItem
->Flags
|= KSCREATE_ITEM_SECURITYCHANGED
;
111 Irp
->IoStatus
.Status
= Status
;
112 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
123 KsDispatchSpecificMethod(
125 IN PFNKSHANDLER Handler
)
128 return STATUS_UNSUCCESSFUL
;
139 IN PFILE_OBJECT FileObject
,
140 IN PKEVENT Event OPTIONAL
,
141 IN PVOID PortContext OPTIONAL
,
142 OUT PIO_STATUS_BLOCK IoStatusBlock
,
145 IN ULONG Key OPTIONAL
,
146 IN KPROCESSOR_MODE RequestorMode
)
148 PDEVICE_OBJECT DeviceObject
;
156 /* make sure event is reset */
160 if (RequestorMode
== UserMode
)
162 /* probe the user buffer */
165 ProbeForWrite(Buffer
, Length
, sizeof(UCHAR
));
166 Status
= STATUS_SUCCESS
;
168 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
170 /* Exception, get the error code */
171 Status
= _SEH2_GetExceptionCode();
175 if (!NT_SUCCESS(Status
))
177 DPRINT1("Invalid user buffer provided\n");
182 /* get corresponding device object */
183 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
185 /* fast-io read is only available for kernel mode clients */
186 if (RequestorMode
== KernelMode
&& ExGetPreviousMode() == KernelMode
&&
187 DeviceObject
->DriverObject
->FastIoDispatch
->FastIoRead
)
189 /* call fast io write */
190 Result
= DeviceObject
->DriverObject
->FastIoDispatch
->FastIoRead(FileObject
, &FileObject
->CurrentByteOffset
, Length
, TRUE
, Key
, Buffer
, IoStatusBlock
, DeviceObject
);
192 if (Result
&& NT_SUCCESS(IoStatusBlock
->Status
))
194 /* request was handeled and succeeded */
195 return STATUS_SUCCESS
;
199 /* do the slow way */
202 /* initialize temp event */
203 KeInitializeEvent(&LocalEvent
, NotificationEvent
, FALSE
);
207 /* build the irp packet */
208 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_READ
, DeviceObject
, Buffer
, Length
, &FileObject
->CurrentByteOffset
, Event
, IoStatusBlock
);
211 /* not enough resources */
212 return STATUS_INSUFFICIENT_RESOURCES
;
215 /* send the packet */
216 Status
= IoCallDriver(DeviceObject
, Irp
);
218 if (Status
== STATUS_PENDING
)
220 /* operation is pending, is sync file object */
221 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
224 KeWaitForSingleObject(Event
, Executive
, RequestorMode
, FALSE
, NULL
);
225 Status
= IoStatusBlock
->Status
;
239 IN PFILE_OBJECT FileObject
,
240 IN PKEVENT Event OPTIONAL
,
241 IN PVOID PortContext OPTIONAL
,
242 OUT PIO_STATUS_BLOCK IoStatusBlock
,
245 IN ULONG Key OPTIONAL
,
246 IN KPROCESSOR_MODE RequestorMode
)
248 PDEVICE_OBJECT DeviceObject
;
256 /* make sure event is reset */
260 if (RequestorMode
== UserMode
)
262 /* probe the user buffer */
265 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
266 Status
= STATUS_SUCCESS
;
268 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
270 /* Exception, get the error code */
271 Status
= _SEH2_GetExceptionCode();
275 if (!NT_SUCCESS(Status
))
277 DPRINT1("Invalid user buffer provided\n");
282 /* get corresponding device object */
283 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
285 /* fast-io write is only available for kernel mode clients */
286 if (RequestorMode
== KernelMode
&& ExGetPreviousMode() == KernelMode
&&
287 DeviceObject
->DriverObject
->FastIoDispatch
->FastIoWrite
)
289 /* call fast io write */
290 Result
= DeviceObject
->DriverObject
->FastIoDispatch
->FastIoWrite(FileObject
, &FileObject
->CurrentByteOffset
, Length
, TRUE
, Key
, Buffer
, IoStatusBlock
, DeviceObject
);
292 if (Result
&& NT_SUCCESS(IoStatusBlock
->Status
))
294 /* request was handeled and succeeded */
295 return STATUS_SUCCESS
;
299 /* do the slow way */
302 /* initialize temp event */
303 KeInitializeEvent(&LocalEvent
, NotificationEvent
, FALSE
);
307 /* build the irp packet */
308 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_WRITE
, DeviceObject
, Buffer
, Length
, &FileObject
->CurrentByteOffset
, Event
, IoStatusBlock
);
311 /* not enough resources */
312 return STATUS_INSUFFICIENT_RESOURCES
;
315 /* send the packet */
316 Status
= IoCallDriver(DeviceObject
, Irp
);
318 if (Status
== STATUS_PENDING
)
320 /* operation is pending, is sync file object */
321 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
324 KeWaitForSingleObject(Event
, Executive
, RequestorMode
, FALSE
, NULL
);
325 Status
= IoStatusBlock
->Status
;
338 KsQueryInformationFile(
339 IN PFILE_OBJECT FileObject
,
340 OUT PVOID FileInformation
,
342 IN FILE_INFORMATION_CLASS FileInformationClass
)
344 PDEVICE_OBJECT DeviceObject
;
345 PFAST_IO_DISPATCH FastIoDispatch
;
347 PIO_STACK_LOCATION IoStack
;
348 IO_STATUS_BLOCK IoStatus
;
350 LARGE_INTEGER Offset
;
351 IO_STATUS_BLOCK StatusBlock
;
354 /* get related file object */
355 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
357 /* get fast i/o table */
358 FastIoDispatch
= DeviceObject
->DriverObject
->FastIoDispatch
;
360 /* is there a fast table */
363 /* check the class */
364 if (FileInformationClass
== FileBasicInformation
)
366 /* use FastIoQueryBasicInfo routine */
367 if (FastIoDispatch
->FastIoQueryBasicInfo
)
369 return FastIoDispatch
->FastIoQueryBasicInfo(FileObject
, TRUE
, (PFILE_BASIC_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
372 else if (FileInformationClass
== FileStandardInformation
)
374 /* use FastIoQueryBasicInfo routine */
375 if (FastIoDispatch
->FastIoQueryBasicInfo
)
377 return FastIoDispatch
->FastIoQueryStandardInfo(FileObject
, TRUE
, (PFILE_STANDARD_INFORMATION
)FileInformation
, &IoStatus
, DeviceObject
);
382 KeClearEvent(&FileObject
->Event
);
384 /* initialize event */
385 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
387 /* set offset to zero */
388 Offset
.QuadPart
= 0L;
390 /* build the request */
391 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_QUERY_INFORMATION
, IoGetRelatedDeviceObject(FileObject
), NULL
, 0, &Offset
, &Event
, &StatusBlock
);
394 return STATUS_INSUFFICIENT_RESOURCES
;
396 /* get next stack location */
397 IoStack
= IoGetNextIrpStackLocation(Irp
);
399 /* setup parameters */
400 IoStack
->Parameters
.QueryFile
.FileInformationClass
= FileInformationClass
;
401 IoStack
->Parameters
.QueryFile
.Length
= Length
;
402 Irp
->AssociatedIrp
.SystemBuffer
= FileInformation
;
405 /* call the driver */
406 Status
= IoCallDriver(IoGetRelatedDeviceObject(FileObject
), Irp
);
408 if (Status
== STATUS_PENDING
)
410 /* wait for the operation to complete */
411 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
414 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
415 Status
= FileObject
->FinalStatus
;
417 Status
= StatusBlock
.Status
;
430 KsSetInformationFile(
431 IN PFILE_OBJECT FileObject
,
432 IN PVOID FileInformation
,
434 IN FILE_INFORMATION_CLASS FileInformationClass
)
436 PIO_STACK_LOCATION IoStack
;
437 PDEVICE_OBJECT DeviceObject
;
441 LARGE_INTEGER Offset
;
442 IO_STATUS_BLOCK IoStatus
;
445 /* get related device object */
446 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
448 /* copy file information */
449 Buffer
= AllocateItem(NonPagedPool
, Length
);
451 return STATUS_INSUFFICIENT_RESOURCES
;
455 ProbeForRead(Buffer
, Length
, sizeof(UCHAR
));
456 RtlMoveMemory(Buffer
, FileInformation
, Length
);
457 Status
= STATUS_SUCCESS
;
459 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
461 /* Exception, get the error code */
462 Status
= _SEH2_GetExceptionCode();
466 if (!NT_SUCCESS(Status
))
468 /* invalid user buffer */
473 /* initialize the event */
474 KeInitializeEvent(&Event
, SynchronizationEvent
, FALSE
);
477 Offset
.QuadPart
= 0LL;
480 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_SET_INFORMATION
, DeviceObject
, NULL
, 0, &Offset
, &Event
, &IoStatus
);
484 /* failed to allocate irp */
486 return STATUS_INSUFFICIENT_RESOURCES
;
489 /* get next stack location */
490 IoStack
= IoGetNextIrpStackLocation(Irp
);
492 /* set irp parameters */
493 IoStack
->Parameters
.SetFile
.FileInformationClass
= FileInformationClass
;
494 IoStack
->Parameters
.SetFile
.Length
= Length
;
495 IoStack
->Parameters
.SetFile
.FileObject
= FileObject
;
496 Irp
->AssociatedIrp
.SystemBuffer
= Buffer
;
497 Irp
->UserBuffer
= FileInformation
;
499 /* dispatch the irp */
500 Status
= IoCallDriver(DeviceObject
, Irp
);
502 if (Status
== STATUS_PENDING
)
504 /* wait untill the operation has completed */
505 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
506 /* is a sync file object */
507 if (FileObject
->Flags
& FO_SYNCHRONOUS_IO
)
508 Status
= FileObject
->FinalStatus
;
510 Status
= IoStatus
.Status
;
523 IN PFILE_OBJECT FileObject
,
524 IN PKEVENT Event OPTIONAL
,
525 IN PVOID PortContext OPTIONAL
,
526 IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL
,
527 IN PVOID CompletionContext OPTIONAL
,
528 IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL
,
529 OUT PIO_STATUS_BLOCK IoStatusBlock
,
530 IN OUT PVOID StreamHeaders
,
533 IN KPROCESSOR_MODE RequestorMode
)
536 PIO_STACK_LOCATION IoStack
;
537 PDEVICE_OBJECT DeviceObject
;
539 LARGE_INTEGER Offset
;
540 PKSIOBJECT_HEADER ObjectHeader
;
543 /* get related device object */
544 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
546 ASSERT(DeviceObject
!= NULL
);
548 /* is there a event provided */
555 if (RequestorMode
|| ExGetPreviousMode() == KernelMode
)
557 /* requestor is from kernel land */
558 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext
;
562 /* there is a object header */
563 if (Flags
== KSSTREAM_READ
)
565 /* is fast read supported */
566 if (ObjectHeader
->DispatchTable
.FastRead
)
568 /* call fast read dispatch routine */
569 Ret
= ObjectHeader
->DispatchTable
.FastRead(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
);
573 /* the request was handeled */
574 return IoStatusBlock
->Status
;
578 else if (Flags
== KSSTREAM_WRITE
)
580 /* is fast write supported */
581 if (ObjectHeader
->DispatchTable
.FastWrite
)
583 /* call fast write dispatch routine */
584 Ret
= ObjectHeader
->DispatchTable
.FastWrite(FileObject
, NULL
, Length
, FALSE
, 0, StreamHeaders
, IoStatusBlock
, DeviceObject
);
588 /* the request was handeled */
589 return IoStatusBlock
->Status
;
596 /* clear file object event */
597 KeClearEvent(&FileObject
->Event
);
599 /* set the offset to zero */
600 Offset
.QuadPart
= 0LL;
602 /* now build the irp */
603 Irp
= IoBuildSynchronousFsdRequest(IRP_MJ_DEVICE_CONTROL
,
604 DeviceObject
, (PVOID
)StreamHeaders
, Length
, &Offset
, Event
, IoStatusBlock
);
607 /* not enough memory */
608 return STATUS_INSUFFICIENT_RESOURCES
;
611 /* setup irp parameters */
612 Irp
->RequestorMode
= RequestorMode
;
613 Irp
->Overlay
.AsynchronousParameters
.UserApcContext
= PortContext
;
614 Irp
->Tail
.Overlay
.OriginalFileObject
= FileObject
;
615 Irp
->UserBuffer
= StreamHeaders
;
617 /* get next irp stack location */
618 IoStack
= IoGetNextIrpStackLocation(Irp
);
619 /* setup stack parameters */
620 IoStack
->FileObject
= FileObject
;
621 IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
= Length
;
622 IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
= StreamHeaders
;
623 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
= (Flags
== KSSTREAM_READ
? IOCTL_KS_READ_STREAM
: IOCTL_KS_WRITE_STREAM
);
625 if (CompletionRoutine
)
627 /* setup completion routine for async processing */
628 IoSetCompletionRoutine(Irp
, CompletionRoutine
, CompletionContext
, (CompletionInvocationFlags
& KsInvokeOnSuccess
), (CompletionInvocationFlags
& KsInvokeOnError
), (CompletionInvocationFlags
& KsInvokeOnCancel
));
631 /* now call the driver */
632 Status
= IoCallDriver(DeviceObject
, Irp
);
651 LOCK_OPERATION Operation
;
652 NTSTATUS Status
= STATUS_SUCCESS
;
653 PKSSTREAM_HEADER StreamHeader
;
654 PIO_STACK_LOCATION IoStack
;
656 BOOLEAN AllocateMdl
= FALSE
;
658 /* get current irp stack */
659 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
661 Length
= IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
;
663 if (Irp
->RequestorMode
== KernelMode
|| Irp
->AssociatedIrp
.SystemBuffer
)
666 /* check if alloc mdl flag is passed */
667 if (!(ProbeFlags
& KSPROBE_ALLOCATEMDL
))
669 /* nothing more to do */
670 return STATUS_SUCCESS
;
675 if (ProbeFlags
& KSPROBE_PROBEANDLOCK
)
677 if (Irp
->MdlAddress
->MdlFlags
& (MDL_PAGES_LOCKED
| MDL_SOURCE_IS_NONPAGED_POOL
))
679 if (ProbeFlags
& KSPROBE_SYSTEMADDRESS
)
683 /* loop through all mdls and probe them */
684 Mdl
= Irp
->MdlAddress
;
687 /* the mapping can fail */
688 Mdl
->MdlFlags
|= MDL_MAPPING_CAN_FAIL
;
690 if (Mdl
->MdlFlags
& (MDL_MAPPED_TO_SYSTEM_VA
| MDL_SOURCE_IS_NONPAGED_POOL
))
692 /* no need to probe these pages */
693 Buffer
= Mdl
->MappedSystemVa
;
698 Buffer
= MmMapLockedPages(Mdl
, KernelMode
);
701 /* check if the mapping succeeded */
704 /* raise exception we'll catch */
705 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
708 /* iterate to next mdl */
713 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
715 /* Exception, get the error code */
716 Status
= _SEH2_GetExceptionCode();
724 /* loop through all mdls and probe them */
725 Mdl
= Irp
->MdlAddress
;
727 /* determine operation */
728 Operation
= (ProbeFlags
& KSPROBE_STREAMWRITE
) ? IoWriteAccess
: IoReadAccess
;
732 /* probe the pages */
733 MmProbeAndLockPages(Mdl
, Irp
->RequestorMode
, Operation
);
735 if (ProbeFlags
& KSPROBE_SYSTEMADDRESS
)
737 /* the mapping can fail */
738 Mdl
->MdlFlags
|= MDL_MAPPING_CAN_FAIL
;
740 if (Mdl
->MdlFlags
& (MDL_MAPPED_TO_SYSTEM_VA
| MDL_SOURCE_IS_NONPAGED_POOL
))
742 /* no need to probe these pages */
743 Buffer
= Mdl
->MappedSystemVa
;
748 Buffer
= MmMapLockedPages(Mdl
, KernelMode
);
751 /* check if the mapping succeeded */
754 /* raise exception we'll catch */
755 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
759 /* iterate to next mdl */
764 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
766 /* Exception, get the error code */
767 Status
= _SEH2_GetExceptionCode();
774 /* check all stream headers */
775 StreamHeader
= (PKSSTREAM_HEADER
)Irp
->AssociatedIrp
.SystemBuffer
;
783 /* does the supplied header size match stream header size and no type changed */
784 if (StreamHeader
->Size
!= HeaderSize
&& !(StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
))
786 /* invalid stream header */
787 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
792 /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */
793 if (StreamHeader
->Size
< sizeof(KSSTREAM_HEADER
) || (StreamHeader
->Size
& 7))
795 /* invalid stream header */
796 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
800 if (Length
< StreamHeader
->Size
)
802 /* length is too short */
803 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
806 if (ProbeFlags
& KSPROBE_STREAMWRITE
)
808 if (StreamHeader
->DataUsed
> StreamHeader
->FrameExtent
)
810 /* frame extend can never be smaller */
811 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
814 /* is this stream change packet */
815 if (StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
)
817 if (Length
!= sizeof(KSSTREAM_HEADER
) || (PVOID
)StreamHeader
!= Irp
->AssociatedIrp
.SystemBuffer
)
819 /* stream changed - must be send in a single packet */
820 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
823 if (!(ProbeFlags
& KSPROBE_ALLOWFORMATCHANGE
))
825 /* caller does not permit format changes */
826 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
829 if (StreamHeader
->FrameExtend
)
831 /* allocate an mdl */
832 Mdl
= IoAllocateMdl(StreamHeader
->Data
, StreamHeader
->FrameExtend
, FALSE
, TRUE
, Irp
);
836 /* not enough memory */
837 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
840 /* break-out to probe for the irp */
847 if (StreamHeader
->DataUsed
)
849 /* DataUsed must be zero for stream read operation */
850 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
853 if (StreamHeader
->OptionsFlags
)
855 /* no flags supported for reading */
856 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
860 if (StreamHeader
->FrameExtend
)
862 /* allocate an mdl */
863 Mdl
= IoAllocateMdl(StreamHeader
->Data
, StreamHeader
->FrameExtend
, Irp
->MdlAddress
!= NULL
, TRUE
, Irp
);
866 /* not enough memory */
867 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
871 /* move to next stream header */
872 Length
-= StreamHeader
->Size
;
873 StreamHeader
= (PKSSTREAM_HEADER
)((ULONG_PTR
)StreamHeader
+ StreamHeader
->Size
);
876 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
878 /* Exception, get the error code */
879 Status
= _SEH2_GetExceptionCode();
882 /* now probe the allocated mdl's */
883 if (!NT_SUCCESS(Status
))
889 /* probe user mode buffers */
890 if (Length
&& ( (!HeaderSize
) || (Length
% HeaderSize
== 0) || ((ProbeFlags
& KSPROBE_ALLOWFORMATCHANGE
) && (Length
== sizeof(KSSTREAM_HEADER
))) ) )
892 /* allocate stream header buffer */
893 Irp
->AssociatedIrp
.SystemBuffer
= ExAllocatePool(NonPagedPool
, Length
);
895 if (!Irp
->AssociatedIrp
.SystemBuffer
)
898 return STATUS_INSUFFICIENT_RESOURCES
;
903 if (ProbeFlags
& KSPROBE_STREAMWRITE
)
905 if (ProbeFlags
& KSPROBE_MODIFY
)
906 ProbeForWrite(Irp
->UserBuffer
, Length
, sizeof(UCHAR
));
908 ProbeForRead(Irp
->UserBuffer
, Length
, sizeof(UCHAR
));
912 /* stream reads means writing */
913 ProbeForWrite(Irp
->UserBuffer
, Length
, sizeof(UCHAR
));
916 /* copy stream buffer */
917 RtlMoveMemory(Irp
->AssociatedIrp
.SystemBuffer
, Irp
->UserBuffer
, Length
);
919 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
921 /* Exception, get the error code */
922 Status
= _SEH2_GetExceptionCode();
925 if (!NT_SUCCESS(Status
))
931 if (ProbeFlags
& KSPROBE_ALLOCATEMDL
)
943 /* does the supplied header size match stream header size and no type changed */
944 if (StreamHeader
->Size
!= HeaderSize
&& !(StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
))
946 /* invalid stream header */
947 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
952 /* stream must be at least of size KSSTREAM_HEADER and size must be 8-byte block aligned */
953 if (StreamHeader
->Size
< sizeof(KSSTREAM_HEADER
) || (StreamHeader
->Size
& 7))
955 /* invalid stream header */
956 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
960 if (Length
< StreamHeader
->Size
)
962 /* length is too short */
963 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
966 if (ProbeFlags
& KSPROBE_STREAMWRITE
)
968 if (StreamHeader
->DataUsed
> StreamHeader
->FrameExtend
)
970 /* frame extend can never be smaller */
971 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
974 /* is this stream change packet */
975 if (StreamHeader
->OptionsFlags
& KSSTREAM_HEADER_OPTIONSF_TYPECHANGED
)
977 if (Length
!= sizeof(KSSTREAM_HEADER
) || (PVOID
)StreamHeader
!= Irp
->AssociatedIrp
.SystemBuffer
)
979 /* stream changed - must be send in a single packet */
980 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
983 if (!(ProbeFlags
& KSPROBE_ALLOWFORMATCHANGE
))
985 /* caller does not permit format changes */
986 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
989 if (StreamHeader
->FrameExtend
)
991 /* allocate an mdl */
992 Mdl
= IoAllocateMdl(StreamHeader
->Data
, StreamHeader
->FrameExtend
, FALSE
, TRUE
, Irp
);
996 /* not enough memory */
997 ExRaiseStatus(STATUS_INSUFFICIENT_RESOURCES
);
1000 /* break out to probe for the irp */
1008 if (StreamHeader
->DataUsed
)
1010 /* DataUsed must be zero for stream read operation */
1011 ExRaiseStatus(STATUS_INVALID_BUFFER_SIZE
);
1014 if (StreamHeader
->OptionsFlags
)
1016 /* no flags supported for reading */
1017 ExRaiseStatus(STATUS_INVALID_PARAMETER
);
1021 /* move to next stream header */
1022 Length
-= StreamHeader
->Size
;
1023 StreamHeader
= (PKSSTREAM_HEADER
)((ULONG_PTR
)StreamHeader
+ StreamHeader
->Size
);
1026 }_SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1028 /* Exception, get the error code */
1029 Status
= _SEH2_GetExceptionCode();
1032 /* now probe the allocated mdl's */
1033 if (NT_SUCCESS(Status
))
1039 return STATUS_INVALID_BUFFER_SIZE
;
1042 return STATUS_NOT_IMPLEMENTED
;
1052 KsAllocateExtraData(
1055 OUT PVOID
* ExtraBuffer
)
1057 PIO_STACK_LOCATION IoStack
;
1059 PUCHAR Buffer
, BufferOrg
;
1060 PKSSTREAM_HEADER Header
;
1061 NTSTATUS Status
= STATUS_SUCCESS
;
1063 /* get current irp stack */
1064 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1067 ASSERT(IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
>= sizeof(KSSTREAM_HEADER
));
1069 /* get total length */
1070 Count
= IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
/ sizeof(KSSTREAM_HEADER
);
1072 /* allocate buffer */
1073 Buffer
= BufferOrg
= AllocateItem(NonPagedPool
, Count
* (sizeof(KSSTREAM_HEADER
) + ExtraSize
));
1075 return STATUS_INSUFFICIENT_RESOURCES
;
1079 /* get input buffer */
1080 Header
= (PKSSTREAM_HEADER
)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
1081 for(Index
= 0; Index
< Count
; Index
++)
1083 /* copy stream header */
1084 RtlMoveMemory(Buffer
, Header
, sizeof(KSSTREAM_HEADER
));
1086 /* move to next header */
1088 /* increment output buffer offset */
1089 Buffer
+= sizeof(KSSTREAM_HEADER
) + ExtraSize
;
1092 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
1094 /* Exception, get the error code */
1095 Status
= _SEH2_GetExceptionCode();
1099 if (!NT_SUCCESS(Status
))
1101 /* free buffer on exception */
1107 *ExtraBuffer
= BufferOrg
;
1110 return STATUS_SUCCESS
;
1120 IN PDRIVER_OBJECT DriverObject
)
1130 KsDispatchInvalidDeviceRequest(
1131 IN PDEVICE_OBJECT DeviceObject
,
1134 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
1135 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1137 return STATUS_INVALID_DEVICE_REQUEST
;
1146 KsDefaultDeviceIoCompletion(
1147 IN PDEVICE_OBJECT DeviceObject
,
1150 PIO_STACK_LOCATION IoStack
;
1153 /* get current irp stack */
1154 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1156 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
&&
1157 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_METHOD
&&
1158 IoStack
->Parameters
.DeviceIoControl
.IoControlCode
!= IOCTL_KS_PROPERTY
)
1160 if (IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_RESET_STATE
)
1163 Status
= STATUS_SUCCESS
;
1167 /* request unsupported */
1168 Status
= STATUS_INVALID_DEVICE_REQUEST
;
1173 /* property / method / event not found */
1174 Status
= STATUS_PROPSET_NOT_FOUND
;
1177 /* complete request */
1178 Irp
->IoStatus
.Status
= Status
;
1179 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1191 KsDispatchFastIoDeviceControlFailure(
1192 IN PFILE_OBJECT FileObject
,
1194 IN PVOID InputBuffer OPTIONAL
,
1195 IN ULONG InputBufferLength
,
1196 OUT PVOID OutputBuffer OPTIONAL
,
1197 IN ULONG OutputBufferLength
,
1198 IN ULONG IoControlCode
,
1199 OUT PIO_STATUS_BLOCK IoStatus
,
1200 IN PDEVICE_OBJECT DeviceObject
)
1211 KsDispatchFastReadFailure(
1212 IN PFILE_OBJECT FileObject
,
1213 IN PLARGE_INTEGER FileOffset
,
1218 OUT PIO_STATUS_BLOCK IoStatus
,
1219 IN PDEVICE_OBJECT DeviceObject
)
1232 IN OUT PLIST_ENTRY QueueHead
,
1233 IN PKSPIN_LOCK SpinLock
)
1235 PDRIVER_CANCEL OldDriverCancel
;
1236 PIO_STACK_LOCATION IoStack
;
1241 /* acquire spinlock */
1242 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1243 /* point to first entry */
1244 Entry
= QueueHead
->Flink
;
1245 /* loop all items */
1246 while(Entry
!= QueueHead
)
1248 /* get irp offset */
1249 Irp
= (PIRP
)CONTAINING_RECORD(Entry
, IRP
, Tail
.Overlay
.ListEntry
);
1251 /* set cancelled bit */
1254 /* now set the cancel routine */
1255 OldDriverCancel
= IoSetCancelRoutine(Irp
, NULL
);
1256 if (OldDriverCancel
)
1258 /* this irp hasnt been yet used, so free to cancel */
1259 KeReleaseSpinLock(SpinLock
, OldLevel
);
1261 /* get current irp stack */
1262 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1264 /* acquire cancel spinlock */
1265 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1267 /* call provided cancel routine */
1268 OldDriverCancel(IoStack
->DeviceObject
, Irp
);
1270 /* re-acquire spinlock */
1271 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1273 /* move on to next entry */
1274 Entry
= Entry
->Flink
;
1277 /* the irp has already been canceled */
1278 KeReleaseSpinLock(SpinLock
, OldLevel
);
1288 KsReleaseIrpOnCancelableQueue(
1290 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
1292 PKSPIN_LOCK SpinLock
;
1293 PDRIVER_CANCEL OldDriverCancel
;
1294 PIO_STACK_LOCATION IoStack
;
1297 /* check for required parameters */
1303 /* default to KsCancelRoutine */
1304 DriverCancel
= KsCancelRoutine
;
1307 /* get current irp stack */
1308 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1310 /* get internal queue lock */
1311 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1313 /* acquire spinlock */
1314 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1316 /* now set the cancel routine */
1317 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
1319 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
1321 /* the irp has already been canceled */
1322 KeReleaseSpinLock(SpinLock
, OldLevel
);
1324 /* cancel routine requires that cancel spinlock is held */
1325 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1328 DriverCancel(IoStack
->DeviceObject
, Irp
);
1333 KeReleaseSpinLock(SpinLock
, OldLevel
);
1343 KsRemoveIrpFromCancelableQueue(
1344 IN OUT PLIST_ENTRY QueueHead
,
1345 IN PKSPIN_LOCK SpinLock
,
1346 IN KSLIST_ENTRY_LOCATION ListLocation
,
1347 IN KSIRP_REMOVAL_OPERATION RemovalOperation
)
1350 PLIST_ENTRY CurEntry
;
1353 /* check parameters */
1354 if (!QueueHead
|| !SpinLock
)
1357 /* check if parameter ListLocation is valid */
1358 if (ListLocation
!= KsListEntryTail
&& ListLocation
!= KsListEntryHead
)
1361 /* acquire list lock */
1362 KeAcquireSpinLock(SpinLock
, &OldIrql
);
1364 /* point to queue head */
1365 CurEntry
= QueueHead
;
1369 /* reset irp to null */
1372 /* iterate to next entry */
1373 if (ListLocation
== KsListEntryHead
)
1374 CurEntry
= CurEntry
->Flink
;
1376 CurEntry
= CurEntry
->Blink
;
1378 /* is the end of list reached */
1379 if (CurEntry
== QueueHead
)
1381 /* reached end of list */
1385 /* get irp offset */
1386 Irp
= (PIRP
)CONTAINING_RECORD(CurEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1390 /* irp has been canceled */
1394 if (Irp
->CancelRoutine
)
1396 /* remove cancel routine */
1397 Irp
->CancelRoutine
= NULL
;
1399 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
1401 /* remove irp from list */
1402 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1405 if (RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
|| RemovalOperation
== KsAcquireOnlySingleItem
)
1412 KeReleaseSpinLock(SpinLock
, OldIrql
);
1414 if (!Irp
|| Irp
->CancelRoutine
== NULL
)
1416 /* either an irp has been acquired or nothing found */
1420 /* time to remove the canceled irp */
1421 IoAcquireCancelSpinLock(&OldIrql
);
1422 /* acquire list lock */
1423 KeAcquireSpinLockAtDpcLevel(SpinLock
);
1425 if (RemovalOperation
== KsAcquireAndRemove
|| RemovalOperation
== KsAcquireAndRemoveOnlySingleItem
)
1428 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1431 /* release list lock */
1432 KeReleaseSpinLockFromDpcLevel(SpinLock
);
1434 /* release cancel spinlock */
1435 IoReleaseCancelSpinLock(OldIrql
);
1436 /* no non canceled irp has been found */
1446 KsMoveIrpsOnCancelableQueue(
1447 IN OUT PLIST_ENTRY SourceList
,
1448 IN PKSPIN_LOCK SourceLock
,
1449 IN OUT PLIST_ENTRY DestinationList
,
1450 IN PKSPIN_LOCK DestinationLock OPTIONAL
,
1451 IN KSLIST_ENTRY_LOCATION ListLocation
,
1452 IN PFNKSIRPLISTCALLBACK ListCallback
,
1456 PLIST_ENTRY SrcEntry
;
1458 NTSTATUS Status
= STATUS_SUCCESS
;
1460 if (!DestinationLock
)
1462 /* no destination lock just acquire the source lock */
1463 KeAcquireSpinLock(SourceLock
, &OldLevel
);
1467 /* acquire cancel spinlock */
1468 IoAcquireCancelSpinLock(&OldLevel
);
1470 /* now acquire source lock */
1471 KeAcquireSpinLockAtDpcLevel(SourceLock
);
1473 /* now acquire destination lock */
1474 KeAcquireSpinLockAtDpcLevel(DestinationLock
);
1477 /* point to list head */
1478 SrcEntry
= SourceList
;
1480 /* now move all irps */
1483 if (ListLocation
== KsListEntryTail
)
1485 /* move queue downwards */
1486 SrcEntry
= SrcEntry
->Flink
;
1490 /* move queue upwards */
1491 SrcEntry
= SrcEntry
->Blink
;
1494 if (SrcEntry
== SourceList
)
1496 /* eof list reached */
1500 /* get irp offset */
1501 Irp
= (PIRP
)CONTAINING_RECORD(SrcEntry
, IRP
, Tail
.Overlay
.ListEntry
);
1503 /* now check if irp can be moved */
1504 Status
= ListCallback(Irp
, Context
);
1506 /* check if irp can be moved */
1507 if (Status
== STATUS_SUCCESS
)
1509 /* remove irp from src list */
1510 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1512 if (ListLocation
== KsListEntryTail
)
1514 /* insert irp end of list */
1515 InsertTailList(DestinationList
, &Irp
->Tail
.Overlay
.ListEntry
);
1519 /* insert irp head of list */
1520 InsertHeadList(DestinationList
, &Irp
->Tail
.Overlay
.ListEntry
);
1523 /* do we need to update the irp lock */
1524 if (DestinationLock
)
1526 /* update irp lock */
1527 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
) = DestinationLock
;
1532 if (Status
!= STATUS_NO_MATCH
)
1534 /* callback decided to stop enumeration */
1538 /* reset return value */
1539 Status
= STATUS_SUCCESS
;
1543 if (!DestinationLock
)
1545 /* release source lock */
1546 KeReleaseSpinLock(SourceLock
, OldLevel
);
1550 /* now release destination lock */
1551 KeReleaseSpinLockFromDpcLevel(DestinationLock
);
1553 /* now release source lock */
1554 KeReleaseSpinLockFromDpcLevel(SourceLock
);
1557 /* now release cancel spinlock */
1558 IoReleaseCancelSpinLock(OldLevel
);
1571 KsRemoveSpecificIrpFromCancelableQueue(
1574 PKSPIN_LOCK SpinLock
;
1577 /* get internal queue lock */
1578 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1580 /* acquire spinlock */
1581 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1583 /* remove the irp from the list */
1584 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1586 /* release spinlock */
1587 KeReleaseSpinLock(SpinLock
, OldLevel
);
1597 KsAddIrpToCancelableQueue(
1598 IN OUT PLIST_ENTRY QueueHead
,
1599 IN PKSPIN_LOCK SpinLock
,
1601 IN KSLIST_ENTRY_LOCATION ListLocation
,
1602 IN PDRIVER_CANCEL DriverCancel OPTIONAL
)
1604 PDRIVER_CANCEL OldDriverCancel
;
1605 PIO_STACK_LOCATION IoStack
;
1608 /* check for required parameters */
1609 if (!QueueHead
|| !SpinLock
|| !Irp
)
1614 /* default to KsCancelRoutine */
1615 DriverCancel
= KsCancelRoutine
;
1618 /* get current irp stack */
1619 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1621 /* acquire spinlock */
1622 KeAcquireSpinLock(SpinLock
, &OldLevel
);
1624 if (ListLocation
== KsListEntryTail
)
1626 /* insert irp to tail of list */
1627 InsertTailList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1631 /* insert irp to head of list */
1632 InsertHeadList(QueueHead
, &Irp
->Tail
.Overlay
.ListEntry
);
1635 /* store internal queue lock */
1636 KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
) = SpinLock
;
1638 /* now set the cancel routine */
1639 OldDriverCancel
= IoSetCancelRoutine(Irp
, DriverCancel
);
1641 if (Irp
->Cancel
&& OldDriverCancel
== NULL
)
1643 /* the irp has already been canceled */
1644 KeReleaseSpinLock(SpinLock
, OldLevel
);
1646 /* cancel routine requires that cancel spinlock is held */
1647 IoAcquireCancelSpinLock(&Irp
->CancelIrql
);
1650 DriverCancel(IoStack
->DeviceObject
, Irp
);
1655 KeReleaseSpinLock(SpinLock
, OldLevel
);
1666 IN PDEVICE_OBJECT DeviceObject
,
1669 PKSPIN_LOCK SpinLock
;
1671 /* get internal queue lock */
1672 SpinLock
= KSQUEUE_SPINLOCK_IRP_STORAGE(Irp
);
1674 /* acquire spinlock */
1675 KeAcquireSpinLockAtDpcLevel(SpinLock
);
1678 ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL
);
1680 /* release cancel spinlock */
1681 IoReleaseCancelSpinLock(Irp
->CancelIrql
);
1683 /* remove the irp from the list */
1684 RemoveEntryList(&Irp
->Tail
.Overlay
.ListEntry
);
1686 /* release spinlock */
1687 KeReleaseSpinLockFromDpcLevel(SpinLock
);
1689 /* has the irp already been canceled */
1690 if (Irp
->IoStatus
.Status
!= STATUS_CANCELLED
)
1692 /* let's complete it */
1693 Irp
->IoStatus
.Status
= STATUS_CANCELLED
;
1694 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1699 FindMatchingCreateItem(
1700 PLIST_ENTRY ListHead
,
1703 OUT PCREATE_ITEM_ENTRY
*OutCreateItem
)
1706 PCREATE_ITEM_ENTRY CreateItemEntry
;
1708 /* remove '\' slash */
1710 BufferSize
-= sizeof(WCHAR
);
1712 /* point to first entry */
1713 Entry
= ListHead
->Flink
;
1715 /* loop all device items */
1716 while(Entry
!= ListHead
)
1718 /* get create item entry */
1719 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1721 ASSERT(CreateItemEntry
->CreateItem
);
1723 if(CreateItemEntry
->CreateItem
->Flags
& KSCREATE_ITEM_WILDCARD
)
1725 /* create item is default */
1726 *OutCreateItem
= CreateItemEntry
;
1727 return STATUS_SUCCESS
;
1730 if (!CreateItemEntry
->CreateItem
->Create
)
1732 /* skip free create item */
1733 Entry
= Entry
->Flink
;
1737 ASSERT(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
);
1739 DPRINT1("CreateItem %S Length %u Request %S %u\n", CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
,
1740 CreateItemEntry
->CreateItem
->ObjectClass
.Length
,
1744 if (CreateItemEntry
->CreateItem
->ObjectClass
.Length
> BufferSize
)
1746 /* create item doesnt match in length */
1747 Entry
= Entry
->Flink
;
1751 /* now check if the object class is the same */
1752 if (RtlCompareMemory(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
, Buffer
, CreateItemEntry
->CreateItem
->ObjectClass
.Length
) == CreateItemEntry
->CreateItem
->ObjectClass
.Length
)
1754 /* found matching create item */
1755 *OutCreateItem
= CreateItemEntry
;
1756 return STATUS_SUCCESS
;
1758 /* iterate to next */
1759 Entry
= Entry
->Flink
;
1762 return STATUS_NOT_FOUND
;
1768 IN PDEVICE_OBJECT DeviceObject
,
1771 PCREATE_ITEM_ENTRY CreateItemEntry
;
1772 PIO_STACK_LOCATION IoStack
;
1773 PDEVICE_EXTENSION DeviceExtension
;
1774 PKSIDEVICE_HEADER DeviceHeader
;
1775 PKSIOBJECT_HEADER ObjectHeader
;
1778 DPRINT("KS / CREATE\n");
1779 /* get current stack location */
1780 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1781 /* get device extension */
1782 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1783 /* get device header */
1784 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1786 /* hack for bug 4566 */
1787 if (IoStack
->FileObject
->FileName
.Buffer
== NULL
)
1789 DPRINT("Using reference string hack\n");
1790 Irp
->IoStatus
.Information
= 0;
1791 /* set return status */
1792 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1793 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1794 return STATUS_SUCCESS
;
1797 if (IoStack
->FileObject
->RelatedFileObject
!= NULL
)
1799 /* request is to instantiate a pin / node / clock / allocator */
1800 ObjectHeader
= (PKSIOBJECT_HEADER
)IoStack
->FileObject
->RelatedFileObject
->FsContext
;
1803 ASSERT(ObjectHeader
);
1805 /* find a matching a create item */
1806 Status
= FindMatchingCreateItem(&ObjectHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
1810 /* request to create a filter */
1811 Status
= FindMatchingCreateItem(&DeviceHeader
->ItemList
, IoStack
->FileObject
->FileName
.Length
, IoStack
->FileObject
->FileName
.Buffer
, &CreateItemEntry
);
1814 if (NT_SUCCESS(Status
))
1816 /* set object create item */
1817 KSCREATE_ITEM_IRP_STORAGE(Irp
) = CreateItemEntry
->CreateItem
;
1819 /* call create function */
1820 Status
= CreateItemEntry
->CreateItem
->Create(DeviceObject
, Irp
);
1822 if (NT_SUCCESS(Status
))
1824 /* increment create item reference count */
1825 InterlockedIncrement(&CreateItemEntry
->ReferenceCount
);
1831 Irp
->IoStatus
.Information
= 0;
1832 /* set return status */
1833 Irp
->IoStatus
.Status
= STATUS_UNSUCCESSFUL
;
1834 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1835 return STATUS_UNSUCCESSFUL
;
1839 RosDeviceInterfaceReferenceStringHack(
1840 IN PDEVICE_OBJECT DeviceObject
,
1843 PIO_STACK_LOCATION IoStack
;
1844 PKSIDEVICE_HEADER DeviceHeader
;
1845 PDEVICE_EXTENSION DeviceExtension
;
1846 PCREATE_ITEM_ENTRY CreateItemEntry
;
1851 /* get current stack location */
1852 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1854 /* get device extension */
1855 DeviceExtension
= (PDEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
1856 /* get device header */
1857 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1859 /* retrieve all available reference strings registered */
1861 Entry
= DeviceHeader
->ItemList
.Flink
;
1862 while(Entry
!= &DeviceHeader
->ItemList
)
1864 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1866 ASSERT(CreateItemEntry
->CreateItem
);
1867 if (CreateItemEntry
->CreateItem
->Create
&& CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
)
1868 Length
+= wcslen(CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
) + 1;
1870 Entry
= Entry
->Flink
;
1873 /* add extra zero */
1876 /* allocate the buffer */
1877 Buffer
= ExAllocatePool(NonPagedPool
, Length
* sizeof(WCHAR
));
1880 Irp
->IoStatus
.Information
= 0;
1881 Irp
->IoStatus
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1882 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1883 return STATUS_INSUFFICIENT_RESOURCES
;
1887 *((LPWSTR
*)Irp
->UserBuffer
) = Buffer
;
1888 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1889 Irp
->IoStatus
.Information
= sizeof(LPWSTR
);
1891 Entry
= DeviceHeader
->ItemList
.Flink
;
1892 while(Entry
!= &DeviceHeader
->ItemList
)
1894 CreateItemEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
1896 ASSERT(CreateItemEntry
->CreateItem
);
1897 if (CreateItemEntry
->CreateItem
->Create
&& CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
)
1899 wcscpy(Buffer
, CreateItemEntry
->CreateItem
->ObjectClass
.Buffer
);
1900 Buffer
+= wcslen(Buffer
) + 1;
1902 Entry
= Entry
->Flink
;
1908 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1909 return STATUS_SUCCESS
;
1916 IN PDEVICE_OBJECT DeviceObject
,
1919 PIO_STACK_LOCATION IoStack
;
1920 PKSIOBJECT_HEADER ObjectHeader
;
1921 PKSIDEVICE_HEADER DeviceHeader
;
1922 PDEVICE_EXTENSION DeviceExtension
;
1926 /* get current stack location */
1927 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1929 /* get device extension */
1930 DeviceExtension
= (PDEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
1931 /* get device header */
1932 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1934 if (IoStack
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
&& IoStack
->Parameters
.DeviceIoControl
.IoControlCode
== IOCTL_KS_OBJECT_CLASS
)
1936 /* hack for bug 4566 */
1937 return RosDeviceInterfaceReferenceStringHack(DeviceObject
, Irp
);
1940 ObjectHeader
= (PKSIOBJECT_HEADER
) IoStack
->FileObject
->FsContext
;
1942 ASSERT(ObjectHeader
);
1943 //KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
1945 return ObjectHeader
->DispatchTable
.DeviceIoControl(DeviceObject
, Irp
);
1951 IN PDEVICE_OBJECT DeviceObject
,
1954 PIO_STACK_LOCATION IoStack
;
1955 PDEVICE_EXTENSION DeviceExtension
;
1956 PKSIOBJECT_HEADER ObjectHeader
;
1957 PKSIDEVICE_HEADER DeviceHeader
;
1958 PDRIVER_DISPATCH Dispatch
;
1961 /* get current stack location */
1962 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1964 /* get device extension */
1965 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1966 /* get device header */
1967 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1969 /* get object header */
1970 ObjectHeader
= (PKSIOBJECT_HEADER
) IoStack
->FileObject
->FsContext
;
1974 /* hack for bug 4566 */
1975 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1976 Irp
->IoStatus
.Information
= 0;
1977 /* complete and forget */
1978 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1979 return STATUS_SUCCESS
;
1983 ASSERT(ObjectHeader
);
1984 /* store create item */
1985 //KSCREATE_ITEM_IRP_STORAGE(Irp) = (PKSOBJECT_CREATE_ITEM)0x12345678; //ObjectHeader->CreateItem;
1987 /* retrieve matching dispatch function */
1988 switch(IoStack
->MajorFunction
)
1991 Dispatch
= ObjectHeader
->DispatchTable
.Close
;
1993 case IRP_MJ_DEVICE_CONTROL
:
1994 Dispatch
= ObjectHeader
->DispatchTable
.DeviceIoControl
;
1997 Dispatch
= ObjectHeader
->DispatchTable
.Read
;
2000 Dispatch
= ObjectHeader
->DispatchTable
.Write
;
2002 case IRP_MJ_FLUSH_BUFFERS
:
2003 Dispatch
= ObjectHeader
->DispatchTable
.Flush
;
2005 case IRP_MJ_QUERY_SECURITY
:
2006 Dispatch
= ObjectHeader
->DispatchTable
.QuerySecurity
;
2008 case IRP_MJ_SET_SECURITY
:
2009 Dispatch
= ObjectHeader
->DispatchTable
.SetSecurity
;
2012 Dispatch
= KsDefaultDispatchPnp
;
2017 /* is the request supported */
2020 /* now call the dispatch function */
2021 Status
= Dispatch(DeviceObject
, Irp
);
2025 /* not supported request */
2026 Status
= KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
2039 KsSetMajorFunctionHandler(
2040 IN PDRIVER_OBJECT DriverObject
,
2041 IN ULONG MajorFunction
)
2043 switch ( MajorFunction
)
2046 DriverObject
->MajorFunction
[MajorFunction
] = KspCreate
;
2049 case IRP_MJ_DEVICE_CONTROL
:
2050 DriverObject
->MajorFunction
[MajorFunction
] = KspDeviceControl
;
2055 case IRP_MJ_FLUSH_BUFFERS
:
2056 case IRP_MJ_QUERY_SECURITY
:
2057 case IRP_MJ_SET_SECURITY
:
2058 DriverObject
->MajorFunction
[MajorFunction
] = KspDispatchIrp
;
2061 return STATUS_INVALID_PARAMETER
;
2064 return STATUS_SUCCESS
;
2074 IN PDEVICE_OBJECT DeviceObject
,
2077 PIO_STACK_LOCATION IoStack
;
2078 PKSIDEVICE_HEADER DeviceHeader
;
2079 PDEVICE_EXTENSION DeviceExtension
;
2081 /* get device extension */
2082 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
2083 /* get device header */
2084 DeviceHeader
= DeviceExtension
->DeviceHeader
;
2087 /* get current irp stack */
2088 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
2090 if (IoStack
->MajorFunction
<= IRP_MJ_DEVICE_CONTROL
)
2092 if (IoStack
->MajorFunction
== IRP_MJ_CREATE
)
2094 /* check internal type */
2095 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
2097 /* AVStream client */
2098 return IKsDevice_Create(DeviceObject
, Irp
);
2102 /* external client (portcls) */
2103 return KspCreate(DeviceObject
, Irp
);
2107 if (IoStack
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
2109 /* handle device requests */
2110 return KspDeviceControl(DeviceObject
, Irp
);
2113 switch (IoStack
->MajorFunction
)
2118 case IRP_MJ_FLUSH_BUFFERS
:
2119 case IRP_MJ_QUERY_SECURITY
:
2120 case IRP_MJ_SET_SECURITY
:
2122 return KspDispatchIrp(DeviceObject
, Irp
);
2124 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);
2128 /* dispatch power */
2129 if (IoStack
->MajorFunction
== IRP_MJ_POWER
)
2131 /* check internal type */
2132 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
2134 /* AVStream client */
2135 return IKsDevice_Power(DeviceObject
, Irp
);
2139 /* external client (portcls) */
2140 return KsDefaultDispatchPower(DeviceObject
, Irp
);
2143 else if (IoStack
->MajorFunction
== IRP_MJ_PNP
) /* dispatch pnp */
2145 /* check internal type */
2146 if (DeviceHeader
->lpVtblIKsDevice
) /* FIXME improve check */
2148 /* AVStream client */
2149 return IKsDevice_Pnp(DeviceObject
, Irp
);
2153 /* external client (portcls) */
2154 return KsDefaultDispatchPnp(DeviceObject
, Irp
);
2157 else if (IoStack
->MajorFunction
== IRP_MJ_SYSTEM_CONTROL
)
2160 return KsDefaultForwardIrp(DeviceObject
, Irp
);
2165 return KsDispatchInvalidDeviceRequest(DeviceObject
, Irp
);