2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/api.c
5 * PURPOSE: KS API functions
6 * PROGRAMMER: Johannes Anderwald
12 const GUID GUID_NULL
= {0x00000000L
, 0x0000, 0x0000, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
13 const GUID KSMEDIUMSETID_Standard
= {0x4747B320L
, 0x62CE, 0x11CF, {0xA5, 0xD6, 0x28, 0xDB, 0x04, 0xC1, 0x00, 0x00}};
23 OUT KSRESET
* ResetValue
)
25 PIO_STACK_LOCATION IoStack
;
27 NTSTATUS Status
= STATUS_SUCCESS
;
29 /* get current irp stack */
30 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
32 /* check if there is reset value provided */
33 if (IoStack
->Parameters
.DeviceIoControl
.InputBufferLength
< sizeof(KSRESET
))
34 return STATUS_INVALID_PARAMETER
;
36 if (Irp
->RequestorMode
== UserMode
)
38 /* need to probe the buffer */
41 ProbeForRead(IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
, sizeof(KSRESET
), sizeof(UCHAR
));
42 Value
= (KSRESET
*)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
45 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER
)
47 /* Exception, get the error code */
48 Status
= _SEH2_GetExceptionCode();
54 Value
= (KSRESET
*)IoStack
->Parameters
.DeviceIoControl
.Type3InputBuffer
;
67 KsAcquireDeviceSecurityLock(
68 IN KSDEVICE_HEADER DevHeader
,
72 PKSIDEVICE_HEADER Header
= (PKSIDEVICE_HEADER
)DevHeader
;
74 KeEnterCriticalRegion();
78 Status
= ExAcquireResourceExclusiveLite(&Header
->SecurityLock
, TRUE
);
82 Status
= ExAcquireResourceSharedLite(&Header
->SecurityLock
, TRUE
);
92 KsReleaseDeviceSecurityLock(
93 IN KSDEVICE_HEADER DevHeader
)
95 PKSIDEVICE_HEADER Header
= (PKSIDEVICE_HEADER
)DevHeader
;
97 ExReleaseResourceLite(&Header
->SecurityLock
);
98 KeLeaveCriticalRegion();
107 KsDefaultDispatchPnp(
108 IN PDEVICE_OBJECT DeviceObject
,
111 PDEVICE_EXTENSION DeviceExtension
;
112 PKSIDEVICE_HEADER DeviceHeader
;
113 PIO_STACK_LOCATION IoStack
;
114 PDEVICE_OBJECT PnpDeviceObject
;
118 /* get current irp stack */
119 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
121 /* caller wants to add the target device */
122 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
124 /* get device header */
125 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
127 /* backup PnpBaseObject */
128 PnpDeviceObject
= DeviceHeader
->PnpDeviceObject
;
131 /* backup minor function code */
132 MinorFunction
= IoStack
->MinorFunction
;
134 if(MinorFunction
== IRP_MN_REMOVE_DEVICE
)
136 /* remove the device */
137 KsFreeDeviceHeader((KSDEVICE_HEADER
)DeviceHeader
);
140 /* skip current irp stack */
141 IoSkipCurrentIrpStackLocation(Irp
);
143 /* call attached pnp device object */
144 Status
= IoCallDriver(PnpDeviceObject
, Irp
);
146 if (MinorFunction
== IRP_MN_REMOVE_DEVICE
)
149 IoDetachDevice(PnpDeviceObject
);
151 IoDeleteDevice(DeviceObject
);
163 KsDefaultDispatchPower(
164 IN PDEVICE_OBJECT DeviceObject
,
167 PDEVICE_EXTENSION DeviceExtension
;
168 PKSIDEVICE_HEADER DeviceHeader
;
169 PKSIOBJECT_HEADER ObjectHeader
;
170 PIO_STACK_LOCATION IoStack
;
171 PLIST_ENTRY ListEntry
;
174 /* get current irp stack */
175 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
177 /* caller wants to add the target device */
178 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
180 /* get device header */
181 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
185 /* loop our power dispatch list and call registered notification functions */
186 ListEntry
= DeviceHeader
->PowerDispatchList
.Flink
;
188 while(ListEntry
!= &DeviceHeader
->PowerDispatchList
)
190 /* get object header */
191 ObjectHeader
= (PKSIOBJECT_HEADER
)CONTAINING_RECORD(ListEntry
, KSIOBJECT_HEADER
, PowerDispatchEntry
);
193 /* does it have still a cb */
194 if (ObjectHeader
->PowerDispatch
)
196 /* call the power cb */
197 Status
= ObjectHeader
->PowerDispatch(ObjectHeader
->PowerContext
, Irp
);
198 ASSERT(NT_SUCCESS(Status
));
201 /* iterate to next entry */
202 ListEntry
= ListEntry
->Flink
;
205 /* start next power irp */
206 PoStartNextPowerIrp(Irp
);
208 /* skip current irp stack location */
209 IoSkipCurrentIrpStackLocation(Irp
);
212 Status
= PoCallDriver(DeviceHeader
->PnpDeviceObject
, Irp
);
225 IN PDEVICE_OBJECT DeviceObject
,
228 PDEVICE_EXTENSION DeviceExtension
;
229 PKSIDEVICE_HEADER DeviceHeader
;
230 PIO_STACK_LOCATION IoStack
;
233 /* get current irp stack */
234 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
236 /* caller wants to add the target device */
237 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
239 /* get device header */
240 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
242 /* forward the request to the PDO */
243 Status
= IoCallDriver(DeviceHeader
->PnpDeviceObject
, Irp
);
254 KsSetDevicePnpAndBaseObject(
255 IN KSDEVICE_HEADER Header
,
256 IN PDEVICE_OBJECT PnpDeviceObject
,
257 IN PDEVICE_OBJECT BaseDevice
)
259 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
261 DeviceHeader
->PnpDeviceObject
= PnpDeviceObject
;
262 DeviceHeader
->BaseDevice
= BaseDevice
;
271 KsQueryDevicePnpObject(
272 IN KSDEVICE_HEADER Header
)
274 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
276 /* return PnpDeviceObject */
277 return DeviceHeader
->PnpDeviceObject
;
287 KsQueryObjectAccessMask(
288 IN KSOBJECT_HEADER Header
)
290 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
)Header
;
292 /* return access mask */
293 return ObjectHeader
->AccessMask
;
303 KsRecalculateStackDepth(
304 IN KSDEVICE_HEADER Header
,
305 IN BOOLEAN ReuseStackLocation
)
318 IN KSOBJECT_HEADER Header
,
319 IN KSTARGET_STATE TargetState
)
321 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
323 /* set target state */
324 DeviceHeader
->TargetState
= TargetState
;
333 KsSetTargetDeviceObject(
334 IN KSOBJECT_HEADER Header
,
335 IN PDEVICE_OBJECT TargetDevice OPTIONAL
)
337 PDEVICE_EXTENSION DeviceExtension
;
338 PKSIDEVICE_HEADER DeviceHeader
;
339 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
)Header
;
341 if(ObjectHeader
->TargetDevice
)
343 /* there is already a target device set */
346 /* caller wants to remove the target device */
347 DeviceExtension
= (PDEVICE_EXTENSION
)ObjectHeader
->TargetDevice
->DeviceExtension
;
349 /* get device header */
350 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
353 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
, FALSE
);
356 RemoveEntryList(&ObjectHeader
->TargetDeviceListEntry
);
358 /* remove device pointer */
359 ObjectHeader
->TargetDevice
= NULL
;
362 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
);
367 /* no target device yet set */
370 /* caller wants to add the target device */
371 DeviceExtension
= (PDEVICE_EXTENSION
)TargetDevice
->DeviceExtension
;
373 /* get device header */
374 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
377 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
, FALSE
);
379 /* insert list entry */
380 InsertTailList(&DeviceHeader
->TargetDeviceList
, &ObjectHeader
->TargetDeviceListEntry
);
382 /* store target device */
383 ObjectHeader
->TargetDevice
= TargetDevice
;
386 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
);
399 IN KSOBJECT_HEADER Header
,
400 IN PFNKSCONTEXT_DISPATCH PowerDispatch OPTIONAL
,
401 IN PVOID PowerContext OPTIONAL
)
403 PDEVICE_EXTENSION DeviceExtension
;
404 PKSIDEVICE_HEADER DeviceHeader
;
405 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
)Header
;
407 /* caller wants to add the target device */
408 DeviceExtension
= (PDEVICE_EXTENSION
)ObjectHeader
->ParentDeviceObject
->DeviceExtension
;
410 /* get device header */
411 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
414 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
, FALSE
);
418 /* add power dispatch entry */
419 InsertTailList(&DeviceHeader
->PowerDispatchList
, &ObjectHeader
->PowerDispatchEntry
);
421 /* store function and context */
422 ObjectHeader
->PowerDispatch
= PowerDispatch
;
423 ObjectHeader
->PowerContext
= PowerContext
;
427 /* remove power dispatch entry */
428 RemoveEntryList(&ObjectHeader
->PowerDispatchEntry
);
430 /* store function and context */
431 ObjectHeader
->PowerDispatch
= NULL
;
432 ObjectHeader
->PowerContext
= NULL
;
437 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
);
445 PKSOBJECT_CREATE_ITEM
447 KsQueryObjectCreateItem(
448 IN KSOBJECT_HEADER Header
)
450 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
)Header
;
451 return ObjectHeader
->OriginalCreateItem
;
455 KspAddCreateItemToList(
456 OUT PLIST_ENTRY ListHead
,
458 IN PKSOBJECT_CREATE_ITEM ItemsList
)
461 PCREATE_ITEM_ENTRY Entry
;
464 for(Index
= 0; Index
< ItemsCount
; Index
++)
467 Entry
= AllocateItem(NonPagedPool
, sizeof(CREATE_ITEM_ENTRY
));
471 return STATUS_INSUFFICIENT_RESOURCES
;
474 /* initialize entry */
475 InitializeListHead(&Entry
->ObjectItemList
);
476 Entry
->CreateItem
= &ItemsList
[Index
];
477 Entry
->ReferenceCount
= 0;
478 Entry
->ItemFreeCallback
= NULL
;
480 InsertTailList(ListHead
, &Entry
->Entry
);
482 return STATUS_SUCCESS
;
487 PLIST_ENTRY ListHead
)
489 PCREATE_ITEM_ENTRY Entry
;
491 while(!IsListEmpty(ListHead
))
493 /* remove create item from list */
494 Entry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(RemoveHeadList(ListHead
), CREATE_ITEM_ENTRY
, Entry
);
496 /* caller shouldnt have any references */
497 ASSERT(Entry
->ReferenceCount
== 0);
498 ASSERT(IsListEmpty(&Entry
->ObjectItemList
));
500 /* does the creator wish notification */
501 if (Entry
->ItemFreeCallback
)
504 Entry
->ItemFreeCallback(Entry
->CreateItem
);
507 /* free create item entry */
519 KsAllocateDeviceHeader(
520 OUT KSDEVICE_HEADER
* OutHeader
,
522 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL
)
524 NTSTATUS Status
= STATUS_SUCCESS
;
525 PKSIDEVICE_HEADER Header
;
528 return STATUS_INVALID_PARAMETER
;
530 /* allocate a device header */
531 Header
= ExAllocatePoolWithTag(PagedPool
, sizeof(KSIDEVICE_HEADER
), TAG_DEVICE_HEADER
);
533 /* check for success */
535 return STATUS_INSUFFICIENT_RESOURCES
;
537 /* clear all memory */
538 RtlZeroMemory(Header
, sizeof(KSIDEVICE_HEADER
));
540 /* initialize device mutex */
541 KeInitializeMutex(&Header
->DeviceMutex
, 0);
543 /* initialize target device list */
544 InitializeListHead(&Header
->TargetDeviceList
);
545 /* initialize power dispatch list */
546 InitializeListHead(&Header
->PowerDispatchList
);
547 /* initialize object bag lists */
548 InitializeListHead(&Header
->ObjectBags
);
550 /* initialize create item list */
551 InitializeListHead(&Header
->ItemList
);
553 /* initialize basic header */
554 Header
->BasicHeader
.Type
= KsObjectTypeDevice
;
555 Header
->BasicHeader
.KsDevice
= &Header
->KsDevice
;
556 Header
->BasicHeader
.Parent
.KsDevice
= &Header
->KsDevice
;
558 /* are there any create items provided */
559 if (ItemsCount
&& ItemsList
)
561 Status
= KspAddCreateItemToList(&Header
->ItemList
, ItemsCount
, ItemsList
);
563 if (NT_SUCCESS(Status
))
565 /* store item count */
566 Header
->ItemListCount
= ItemsCount
;
570 /* release create items */
571 KspFreeCreateItems(&Header
->ItemList
);
588 IN KSDEVICE_HEADER DevHeader
)
590 PKSIDEVICE_HEADER Header
;
592 Header
= (PKSIDEVICE_HEADER
)DevHeader
;
597 KspFreeCreateItems(&Header
->ItemList
);
598 ExFreePoolWithTag(Header
, TAG_DEVICE_HEADER
);
607 KsAllocateObjectHeader(
608 OUT KSOBJECT_HEADER
*Header
,
610 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL
,
612 IN KSDISPATCH_TABLE
* Table
)
614 PIO_STACK_LOCATION IoStack
;
615 PDEVICE_EXTENSION DeviceExtension
;
616 PKSIDEVICE_HEADER DeviceHeader
;
617 PKSIOBJECT_HEADER ObjectHeader
;
618 PKSOBJECT_CREATE_ITEM CreateItem
;
622 return STATUS_INVALID_PARAMETER_1
;
625 return STATUS_INVALID_PARAMETER_4
;
628 return STATUS_INVALID_PARAMETER_5
;
630 /* get current stack location */
631 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
632 /* get device extension */
633 DeviceExtension
= (PDEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
634 /* get device header */
635 DeviceHeader
= DeviceExtension
->DeviceHeader
;
638 ASSERT(IoStack
->FileObject
);
639 /* check for an file object */
641 /* allocate the object header */
642 ObjectHeader
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(KSIOBJECT_HEADER
), TAG_DEVICE_HEADER
);
644 return STATUS_INSUFFICIENT_RESOURCES
;
646 /* initialize object header */
647 RtlZeroMemory(ObjectHeader
, sizeof(KSIOBJECT_HEADER
));
649 /* initialize create item list */
650 InitializeListHead(&ObjectHeader
->ItemList
);
652 /* get create item */
653 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
655 /* do we have a name */
656 if (IoStack
->FileObject
->FileName
.Buffer
)
658 /* copy object class */
659 ObjectHeader
->ObjectClass
.MaximumLength
= IoStack
->FileObject
->FileName
.MaximumLength
;
660 ObjectHeader
->ObjectClass
.Buffer
= ExAllocatePoolWithTag(NonPagedPool
, ObjectHeader
->ObjectClass
.MaximumLength
, TAG_DEVICE_HEADER
);
661 if (!ObjectHeader
->ObjectClass
.Buffer
)
663 ExFreePoolWithTag(ObjectHeader
, TAG_DEVICE_HEADER
);
664 return STATUS_INSUFFICIENT_RESOURCES
;
666 RtlCopyUnicodeString(&ObjectHeader
->ObjectClass
, &IoStack
->FileObject
->FileName
);
669 /* copy dispatch table */
670 RtlCopyMemory(&ObjectHeader
->DispatchTable
, Table
, sizeof(KSDISPATCH_TABLE
));
672 /* store create items */
673 if (ItemsCount
&& ItemsList
)
675 Status
= KspAddCreateItemToList(&ObjectHeader
->ItemList
, ItemsCount
, ItemsList
);
677 if (NT_SUCCESS(Status
))
679 /* store item count */
680 ObjectHeader
->ItemListCount
= ItemsCount
;
685 KsFreeObjectHeader(ObjectHeader
);
689 /* store the object in the file object */
690 ASSERT(IoStack
->FileObject
->FsContext
== NULL
);
691 IoStack
->FileObject
->FsContext
= ObjectHeader
;
693 /* store parent device */
694 ObjectHeader
->ParentDeviceObject
= IoGetRelatedDeviceObject(IoStack
->FileObject
);
696 /* store originating create item */
697 ObjectHeader
->OriginalCreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
699 /* FIXME store access mask see KsQueryObjectAccessMask */
700 ObjectHeader
->AccessMask
= IoStack
->Parameters
.Create
.SecurityContext
->DesiredAccess
;
704 *Header
= ObjectHeader
;
706 DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader
->ObjectClass
.Buffer
, IoStack
->FileObject
, ObjectHeader
);
708 return STATUS_SUCCESS
;
721 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
) Header
;
723 if (ObjectHeader
->ObjectClass
.Buffer
)
725 /* release object class buffer */
726 ExFreePoolWithTag(ObjectHeader
->ObjectClass
.Buffer
, TAG_DEVICE_HEADER
);
729 if (ObjectHeader
->Unknown
)
731 /* release associated object */
732 ObjectHeader
->Unknown
->lpVtbl
->Release(ObjectHeader
->Unknown
);
735 /* free create items */
736 KspFreeCreateItems(&ObjectHeader
->ItemList
);
738 /* free object header */
739 ExFreePoolWithTag(ObjectHeader
, TAG_DEVICE_HEADER
);
744 KspAddObjectCreateItemToList(
745 PLIST_ENTRY ListHead
,
746 IN PDRIVER_DISPATCH Create
,
748 IN PWCHAR ObjectClass
,
749 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
752 PCREATE_ITEM_ENTRY CreateEntry
;
754 /* point to first entry */
755 Entry
= ListHead
->Flink
;
757 while(Entry
!= ListHead
)
759 /* get create entry */
760 CreateEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
761 /* if the create item has no create routine, then it is free to use */
762 if (CreateEntry
->CreateItem
->Create
== NULL
)
765 ASSERT(IsListEmpty(&CreateEntry
->ObjectItemList
));
766 ASSERT(CreateEntry
->ReferenceCount
== 0);
768 CreateEntry
->CreateItem
->Context
= Context
;
769 CreateEntry
->CreateItem
->Create
= Create
;
770 RtlInitUnicodeString(&CreateEntry
->CreateItem
->ObjectClass
, ObjectClass
);
771 CreateEntry
->CreateItem
->SecurityDescriptor
= SecurityDescriptor
;
773 return STATUS_SUCCESS
;
776 if (!wcsicmp(ObjectClass
, CreateEntry
->CreateItem
->ObjectClass
.Buffer
))
778 /* the same object class already exists */
779 return STATUS_OBJECT_NAME_COLLISION
;
782 /* iterate to next entry */
783 Entry
= Entry
->Flink
;
785 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
794 KsAddObjectCreateItemToDeviceHeader(
795 IN KSDEVICE_HEADER DevHeader
,
796 IN PDRIVER_DISPATCH Create
,
798 IN PWCHAR ObjectClass
,
799 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
801 PKSIDEVICE_HEADER Header
;
804 Header
= (PKSIDEVICE_HEADER
)DevHeader
;
806 DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n");
808 /* check if a device header has been provided */
810 return STATUS_INVALID_PARAMETER_1
;
812 /* check if a create item has been provided */
814 return STATUS_INVALID_PARAMETER_2
;
816 /* check if a object class has been provided */
818 return STATUS_INVALID_PARAMETER_4
;
820 /* let others do the work */
821 Status
= KspAddObjectCreateItemToList(&Header
->ItemList
, Create
, Context
, ObjectClass
, SecurityDescriptor
);
823 if (NT_SUCCESS(Status
))
825 /* increment create item count */
826 InterlockedIncrement(&Header
->ItemListCount
);
838 KsAddObjectCreateItemToObjectHeader(
839 IN KSOBJECT_HEADER ObjectHeader
,
840 IN PDRIVER_DISPATCH Create
,
842 IN PWCHAR ObjectClass
,
843 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
845 PKSIOBJECT_HEADER Header
;
848 Header
= (PKSIOBJECT_HEADER
)ObjectHeader
;
850 DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n");
852 /* check if a device header has been provided */
854 return STATUS_INVALID_PARAMETER_1
;
856 /* check if a create item has been provided */
858 return STATUS_INVALID_PARAMETER_2
;
860 /* check if a object class has been provided */
862 return STATUS_INVALID_PARAMETER_4
;
865 Status
= KspAddObjectCreateItemToList(&Header
->ItemList
, Create
, Context
, ObjectClass
, SecurityDescriptor
);
867 if (NT_SUCCESS(Status
))
869 /* increment create item count */
870 InterlockedIncrement(&Header
->ItemListCount
);
882 KsAllocateObjectCreateItem(
883 IN KSDEVICE_HEADER DevHeader
,
884 IN PKSOBJECT_CREATE_ITEM CreateItem
,
885 IN BOOLEAN AllocateEntry
,
886 IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL
)
888 PCREATE_ITEM_ENTRY CreateEntry
;
889 PKSIDEVICE_HEADER Header
;
890 PKSOBJECT_CREATE_ITEM Item
;
892 Header
= (PKSIDEVICE_HEADER
)DevHeader
;
895 return STATUS_INVALID_PARAMETER_1
;
898 return STATUS_INVALID_PARAMETER_2
;
900 /* first allocate a create entry */
901 CreateEntry
= AllocateItem(NonPagedPool
, sizeof(PCREATE_ITEM_ENTRY
));
903 /* check for allocation success */
906 /* not enough resources */
907 return STATUS_INSUFFICIENT_RESOURCES
;
913 /* allocate create item */
914 Item
= ExAllocatePool(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
));
918 ExFreePool(CreateEntry
);
919 return STATUS_INSUFFICIENT_RESOURCES
;
922 /* initialize descriptor */
923 Item
->Context
= CreateItem
->Context
;
924 Item
->Create
= CreateItem
->Create
;
925 Item
->Flags
= CreateItem
->Flags
;
926 Item
->SecurityDescriptor
= CreateItem
->SecurityDescriptor
;
927 Item
->ObjectClass
.Length
= 0;
928 Item
->ObjectClass
.MaximumLength
= CreateItem
->ObjectClass
.MaximumLength
;
930 /* copy object class */
931 Item
->ObjectClass
.Buffer
= ExAllocatePool(NonPagedPool
, Item
->ObjectClass
.MaximumLength
);
932 if (!Item
->ObjectClass
.Buffer
)
934 /* release resources */
936 FreeItem(CreateEntry
);
938 return STATUS_INSUFFICIENT_RESOURCES
;
940 RtlCopyUnicodeString(&Item
->ObjectClass
, &CreateItem
->ObjectClass
);
944 if (ItemFreeCallback
)
946 /* callback is only accepted when the create item is copied */
947 ItemFreeCallback
= NULL
;
949 /* use passed create item */
953 /* initialize create item entry */
954 InitializeListHead(&CreateEntry
->ObjectItemList
);
955 CreateEntry
->ItemFreeCallback
= ItemFreeCallback
;
956 CreateEntry
->CreateItem
= Item
;
957 CreateEntry
->ReferenceCount
= 0;
959 /* now insert the create item entry */
960 InsertTailList(&Header
->ItemList
, &CreateEntry
->Entry
);
962 /* increment item count */
963 InterlockedIncrement(&Header
->ItemListCount
);
965 return STATUS_SUCCESS
;
969 KspObjectFreeCreateItems(
970 IN KSDEVICE_HEADER Header
,
971 IN PKSOBJECT_CREATE_ITEM CreateItem
)
974 return STATUS_NOT_IMPLEMENTED
;
983 KsFreeObjectCreateItem(
984 IN KSDEVICE_HEADER Header
,
985 IN PUNICODE_STRING CreateItem
)
987 KSOBJECT_CREATE_ITEM Item
;
989 RtlZeroMemory(&Item
, sizeof(KSOBJECT_CREATE_ITEM
));
990 RtlInitUnicodeString(&Item
.ObjectClass
, CreateItem
->Buffer
);
992 return KspObjectFreeCreateItems(Header
, &Item
);
1002 KsFreeObjectCreateItemsByContext(
1003 IN KSDEVICE_HEADER Header
,
1006 KSOBJECT_CREATE_ITEM Item
;
1008 RtlZeroMemory(&Item
, sizeof(KSOBJECT_CREATE_ITEM
));
1010 Item
.Context
= Context
;
1012 return KspObjectFreeCreateItems(Header
, &Item
);
1021 KsCreateDefaultSecurity(
1022 IN PSECURITY_DESCRIPTOR ParentSecurity OPTIONAL
,
1023 OUT PSECURITY_DESCRIPTOR
* DefaultSecurity
)
1025 PGENERIC_MAPPING Mapping
;
1026 SECURITY_SUBJECT_CONTEXT SubjectContext
;
1029 /* start capturing security context of calling thread */
1030 SeCaptureSubjectContext(&SubjectContext
);
1031 /* get generic mapping */
1032 Mapping
= IoGetFileObjectGenericMapping();
1033 /* build new descriptor */
1034 Status
= SeAssignSecurity(ParentSecurity
, NULL
, DefaultSecurity
, FALSE
, &SubjectContext
, Mapping
, NonPagedPool
);
1035 /* release security descriptor */
1036 SeReleaseSubjectContext(&SubjectContext
);
1049 IN PFILE_OBJECT FileObject
,
1050 IN BOOLEAN ReuseStackLocation
)
1053 return STATUS_UNSUCCESSFUL
;
1063 KsForwardAndCatchIrp(
1064 IN PDEVICE_OBJECT DeviceObject
,
1066 IN PFILE_OBJECT FileObject
,
1067 IN KSSTACK_USE StackUse
)
1070 return STATUS_UNSUCCESSFUL
;
1076 KspSynchronousIoControlDeviceCompletion(
1077 IN PDEVICE_OBJECT DeviceObject
,
1081 PIO_STATUS_BLOCK IoStatusBlock
= (PIO_STATUS_BLOCK
)Context
;
1083 IoStatusBlock
->Information
= Irp
->IoStatus
.Information
;
1084 IoStatusBlock
->Status
= Irp
->IoStatus
.Status
;
1086 return STATUS_SUCCESS
;
1095 KsSynchronousIoControlDevice(
1096 IN PFILE_OBJECT FileObject
,
1097 IN KPROCESSOR_MODE RequestorMode
,
1101 OUT PVOID OutBuffer
,
1103 OUT PULONG BytesReturned
)
1105 PKSIOBJECT_HEADER ObjectHeader
;
1106 PDEVICE_OBJECT DeviceObject
;
1109 IO_STATUS_BLOCK IoStatusBlock
;
1110 PIO_STACK_LOCATION IoStack
;
1113 /* check for valid file object */
1115 return STATUS_INVALID_PARAMETER
;
1117 /* get device object to send the request to */
1118 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
1120 return STATUS_UNSUCCESSFUL
;
1123 /* get object header */
1124 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext
;
1126 /* check if there is fast device io function */
1127 if (ObjectHeader
&& ObjectHeader
->DispatchTable
.FastDeviceIoControl
)
1129 IoStatusBlock
.Status
= STATUS_UNSUCCESSFUL
;
1130 IoStatusBlock
.Information
= 0;
1132 /* it is send the request */
1133 Status
= ObjectHeader
->DispatchTable
.FastDeviceIoControl(FileObject
, TRUE
, InBuffer
, InSize
, OutBuffer
, OutSize
, IoControl
, &IoStatusBlock
, DeviceObject
);
1134 /* check if the request was handled */
1135 //DPRINT("Handled %u Status %x Length %u\n", Status, IoStatusBlock.Status, IoStatusBlock.Information);
1138 /* store bytes returned */
1139 *BytesReturned
= IoStatusBlock
.Information
;
1141 return IoStatusBlock
.Status
;
1145 /* initialize the event */
1146 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1148 /* create the irp */
1149 Irp
= IoBuildDeviceIoControlRequest(IoControl
, DeviceObject
, InBuffer
, InSize
, OutBuffer
, OutSize
, FALSE
, &Event
, &IoStatusBlock
);
1152 IoStack
= IoGetNextIrpStackLocation(Irp
);
1153 IoStack
->FileObject
= FileObject
;
1155 IoSetCompletionRoutine(Irp
, KspSynchronousIoControlDeviceCompletion
, (PVOID
)&IoStatusBlock
, TRUE
, TRUE
, TRUE
);
1157 Status
= IoCallDriver(DeviceObject
, Irp
);
1158 if (Status
== STATUS_PENDING
)
1160 KeWaitForSingleObject(&Event
, Executive
, RequestorMode
, FALSE
, NULL
);
1161 Status
= IoStatusBlock
.Status
;
1164 *BytesReturned
= IoStatusBlock
.Information
;
1174 KsUnserializeObjectPropertiesFromRegistry(
1175 IN PFILE_OBJECT FileObject
,
1176 IN HANDLE ParentKey OPTIONAL
,
1177 IN PUNICODE_STRING RegistryPath OPTIONAL
)
1180 return STATUS_NOT_IMPLEMENTED
;
1191 IN PUNICODE_STRING SymbolicLink
,
1192 IN PKSPIN_MEDIUM Medium
,
1193 IN ULONG PinDirection
)
1196 UNICODE_STRING Path
;
1197 UNICODE_STRING BasePath
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediumCache\\");
1198 UNICODE_STRING GuidString
;
1200 OBJECT_ATTRIBUTES ObjectAttributes
;
1201 BOOLEAN PathAdjusted
= FALSE
;
1204 /* first check if the medium is standard */
1205 if (IsEqualGUIDAligned(&KSMEDIUMSETID_Standard
, &Medium
->Set
) ||
1206 IsEqualGUIDAligned(&GUID_NULL
, &Medium
->Set
))
1208 /* no need to cache that */
1209 return STATUS_SUCCESS
;
1212 /* convert guid to string */
1213 Status
= RtlStringFromGUID(&Medium
->Set
, &GuidString
);
1214 if (!NT_SUCCESS(Status
))
1217 /* allocate path buffer */
1219 Path
.MaximumLength
= BasePath
.MaximumLength
+ GuidString
.MaximumLength
+ 10 * sizeof(WCHAR
);
1220 Path
.Buffer
= AllocateItem(PagedPool
, Path
.MaximumLength
);
1223 /* not enough resources */
1224 RtlFreeUnicodeString(&GuidString
);
1225 return STATUS_INSUFFICIENT_RESOURCES
;
1228 RtlAppendUnicodeStringToString(&Path
, &BasePath
);
1229 RtlAppendUnicodeStringToString(&Path
, &GuidString
);
1230 RtlAppendUnicodeToString(&Path
, L
"-");
1231 /* FIXME append real instance id */
1232 RtlAppendUnicodeToString(&Path
, L
"0");
1233 RtlAppendUnicodeToString(&Path
, L
"-");
1234 /* FIXME append real instance id */
1235 RtlAppendUnicodeToString(&Path
, L
"0");
1237 /* free guid string */
1238 RtlFreeUnicodeString(&GuidString
);
1240 /* initialize object attributes */
1241 InitializeObjectAttributes(&ObjectAttributes
, &Path
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1242 /* create the key */
1243 Status
= ZwCreateKey(&hKey
, GENERIC_WRITE
, &ObjectAttributes
, 0, NULL
, 0, NULL
);
1245 /* free path buffer */
1246 FreeItem(Path
.Buffer
);
1248 if (NT_SUCCESS(Status
))
1250 /* store symbolic link */
1251 if (SymbolicLink
->Buffer
[1] == L
'?' && SymbolicLink
->Buffer
[2] == L
'?')
1253 /* replace kernel path with user mode path */
1254 SymbolicLink
->Buffer
[1] = L
'\\';
1255 PathAdjusted
= TRUE
;
1259 Status
= ZwSetValueKey(hKey
, SymbolicLink
, 0, REG_DWORD
, &Value
, sizeof(ULONG
));
1263 /* restore kernel path */
1264 SymbolicLink
->Buffer
[1] = L
'?';
1280 PUNICODE_STRING RegistryPath
)
1282 return STATUS_SUCCESS
;
1289 IN PDEVICE_OBJECT DeviceObject
,
1292 PKO_OBJECT_HEADER Header
;
1293 PIO_STACK_LOCATION IoStack
;
1294 PDEVICE_EXTENSION DeviceExtension
;
1296 /* get current irp stack location */
1297 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1299 /* get ko object header */
1300 Header
= (PKO_OBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1302 /* free ks object header */
1303 KsFreeObjectHeader(Header
->ObjectHeader
);
1305 /* free ko object header */
1308 /* get device extension */
1309 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1311 /* release bus object */
1312 KsDereferenceBusObject((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
);
1314 /* complete request */
1315 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1316 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1318 return STATUS_SUCCESS
;
1323 static KSDISPATCH_TABLE KoDispatchTable
=
1325 KsDispatchInvalidDeviceRequest
,
1326 KsDispatchInvalidDeviceRequest
,
1327 KsDispatchInvalidDeviceRequest
,
1328 KsDispatchInvalidDeviceRequest
,
1330 KsDispatchQuerySecurity
,
1331 KsDispatchSetSecurity
,
1332 KsDispatchFastIoDeviceControlFailure
,
1333 KsDispatchFastReadFailure
,
1334 KsDispatchFastReadFailure
,
1341 IN PDEVICE_OBJECT DeviceObject
,
1344 PKO_OBJECT_HEADER Header
= NULL
;
1345 PIO_STACK_LOCATION IoStack
;
1346 PKO_DRIVER_EXTENSION DriverObjectExtension
;
1349 /* get current irp stack location */
1350 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1352 if (!IoStack
->FileObject
)
1354 DPRINT1("FileObject not attached!\n");
1355 Status
= STATUS_UNSUCCESSFUL
;
1359 /* get driver object extension */
1360 DriverObjectExtension
= (PKO_DRIVER_EXTENSION
)IoGetDriverObjectExtension(DeviceObject
->DriverObject
, (PVOID
)KoDriverInitialize
);
1361 if (!DriverObjectExtension
)
1363 DPRINT1("FileObject not attached!\n");
1364 Status
= STATUS_UNSUCCESSFUL
;
1368 /* allocate ko object header */
1369 Header
= (PKO_OBJECT_HEADER
)AllocateItem(NonPagedPool
, sizeof(KO_OBJECT_HEADER
));
1372 DPRINT1("failed to allocate KO_OBJECT_HEADER\n");
1373 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1377 /* initialize create item */
1378 Header
->CreateItem
.Create
= KopDispatchCreate
;
1379 RtlInitUnicodeString(&Header
->CreateItem
.ObjectClass
, KOSTRING_CreateObject
);
1382 /* now allocate the object header */
1383 Status
= KsAllocateObjectHeader(&Header
->ObjectHeader
, 1, &Header
->CreateItem
, Irp
, &KoDispatchTable
);
1384 if (!NT_SUCCESS(Status
))
1391 * extract clsid and interface id from irp
1392 * call the standard create handler
1397 IoStack
->FileObject
->FsContext2
= (PVOID
)Header
;
1399 Irp
->IoStatus
.Status
= Status
;
1400 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1406 if (Header
&& Header
->ObjectHeader
)
1407 KsFreeObjectHeader(Header
->ObjectHeader
);
1412 Irp
->IoStatus
.Status
= Status
;
1413 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1422 IN PDRIVER_OBJECT DriverObject
,
1423 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1425 NTSTATUS Status
= STATUS_DEVICE_REMOVED
;
1426 PDEVICE_OBJECT FunctionalDeviceObject
= NULL
;
1427 PDEVICE_OBJECT NextDeviceObject
;
1428 PDEVICE_EXTENSION DeviceExtension
;
1429 PKSOBJECT_CREATE_ITEM CreateItem
;
1431 /* create the device object */
1432 Status
= IoCreateDevice(DriverObject
, sizeof(DEVICE_EXTENSION
), NULL
, FILE_DEVICE_KS
, FILE_DEVICE_SECURE_OPEN
, FALSE
, &FunctionalDeviceObject
);
1433 if (!NT_SUCCESS(Status
))
1436 /* allocate the create item */
1437 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
));
1441 /* not enough memory */
1442 IoDeleteDevice(FunctionalDeviceObject
);
1443 return STATUS_INSUFFICIENT_RESOURCES
;
1446 /* initialize create item */
1447 CreateItem
->Create
= KopDispatchCreate
;
1448 RtlInitUnicodeString(&CreateItem
->ObjectClass
, KOSTRING_CreateObject
);
1450 /* get device extension */
1451 DeviceExtension
= (PDEVICE_EXTENSION
)FunctionalDeviceObject
->DeviceExtension
;
1453 /* now allocate the device header */
1454 Status
= KsAllocateDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
, 1, CreateItem
);
1455 if (!NT_SUCCESS(Status
))
1458 IoDeleteDevice(FunctionalDeviceObject
);
1459 FreeItem(CreateItem
);
1463 /* now attach to device stack */
1464 NextDeviceObject
= IoAttachDeviceToDeviceStack(FunctionalDeviceObject
, PhysicalDeviceObject
);
1465 if (NextDeviceObject
)
1467 /* store pnp base object */
1468 KsSetDevicePnpAndBaseObject((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, NextDeviceObject
, FunctionalDeviceObject
);
1469 /* set device flags */
1470 FunctionalDeviceObject
->Flags
|= DO_DIRECT_IO
| DO_POWER_PAGABLE
;
1471 FunctionalDeviceObject
->Flags
&= ~ DO_DEVICE_INITIALIZING
;
1476 KsFreeDeviceHeader((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
);
1477 FreeItem(CreateItem
);
1478 IoDeleteDevice(FunctionalDeviceObject
);
1479 Status
= STATUS_DEVICE_REMOVED
;
1494 IN PDEVICE_OBJECT DeviceObject
)
1496 PDEVICE_EXTENSION DeviceExtension
;
1498 /* get device extension */
1499 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1501 return KsAddObjectCreateItemToDeviceHeader((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, KopDispatchCreate
, NULL
, KOSTRING_CreateObject
, NULL
);
1511 IN PDRIVER_OBJECT DriverObject
,
1512 IN PUNICODE_STRING RegistryPathName
,
1513 IN KoCreateObjectHandler CreateObjectHandler
)
1515 PKO_DRIVER_EXTENSION DriverObjectExtension
;
1518 /* allocate driver object extension */
1519 Status
= IoAllocateDriverObjectExtension(DriverObject
, (PVOID
)KoDriverInitialize
, sizeof(KO_DRIVER_EXTENSION
), (PVOID
*)&DriverObjectExtension
);
1522 if (NT_SUCCESS(Status
))
1524 /* store create handler */
1525 DriverObjectExtension
->CreateObjectHandler
= CreateObjectHandler
;
1527 /* Setting our IRP handlers */
1528 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = KsDefaultDispatchPnp
;
1529 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = KsDefaultDispatchPower
;
1530 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = KsDefaultForwardIrp
;
1532 /* The driver unload routine */
1533 DriverObject
->DriverUnload
= KsNullDriverUnload
;
1535 /* The driver-supplied AddDevice */
1536 DriverObject
->DriverExtension
->AddDevice
= KopAddDevice
;
1538 /* KS handles these */
1539 DPRINT1("Setting KS function handlers\n");
1540 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_CREATE
);
1541 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_CLOSE
);
1542 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_DEVICE_CONTROL
);
1556 IN REFCLSID ClassId
)
1570 PKSBASIC_HEADER BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
1573 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
1575 KeWaitForSingleObject(&BasicHeader
->ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1587 PKSBASIC_HEADER BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
1590 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
1592 KeReleaseMutex(&BasicHeader
->ControlMutex
, FALSE
);
1604 IN PKSDEVICE Device
)
1606 IKsDevice
*KsDevice
;
1607 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(Device
, KSIDEVICE_HEADER
, KsDevice
);
1609 /* get device interface*/
1610 KsDevice
= (IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
;
1612 /* acquire device mutex */
1613 KsDevice
->lpVtbl
->AcquireDevice(KsDevice
);
1622 IN PKSDEVICE Device
)
1624 IKsDevice
*KsDevice
;
1625 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(Device
, KSIDEVICE_HEADER
, KsDevice
);
1627 /* get device interface*/
1628 KsDevice
= (IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
;
1630 /* release device mutex */
1631 KsDevice
->lpVtbl
->ReleaseDevice(KsDevice
);
1641 IN PDEVICE_OBJECT DeviceObject
)
1643 IKsDevice
*KsDevice
;
1644 PKSIDEVICE_HEADER DeviceHeader
;
1645 PDEVICE_EXTENSION DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1647 /* get device header */
1648 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1650 /* get device interface*/
1651 KsDevice
= (IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
;
1653 /* now free device header */
1654 KsFreeDeviceHeader((KSDEVICE_HEADER
)DeviceHeader
);
1656 /* release interface when available */
1659 /* delete IKsDevice interface */
1660 KsDevice
->lpVtbl
->Release(KsDevice
);
1670 KsCompletePendingRequest(
1673 PIO_STACK_LOCATION IoStack
;
1675 /* get current irp stack location */
1676 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1679 ASSERT(Irp
->IoStatus
.Status
!= STATUS_PENDING
);
1681 if (IoStack
->MajorFunction
!= IRP_MJ_CLOSE
)
1683 /* can be completed immediately */
1684 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1688 /* did close operation fail */
1689 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
1691 /* closing failed, complete irp */
1692 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1697 * delete object / device header
1698 * remove dead pin / filter instance
1710 KsCreateBusEnumObject(
1711 IN PWCHAR BusIdentifier
,
1712 IN PDEVICE_OBJECT BusDeviceObject
,
1713 IN PDEVICE_OBJECT PhysicalDeviceObject
,
1714 IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL
,
1715 IN REFGUID InterfaceGuid OPTIONAL
,
1716 IN PWCHAR ServiceRelativePath OPTIONAL
)
1719 return STATUS_UNSUCCESSFUL
;
1724 KspSetGetBusDataCompletion(
1725 IN PDEVICE_OBJECT DeviceObject
,
1729 /* signal completion */
1730 KeSetEvent((PRKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
1732 /* more work needs be done, so dont free the irp */
1733 return STATUS_MORE_PROCESSING_REQUIRED
;
1738 KspDeviceSetGetBusData(
1739 IN PDEVICE_OBJECT DeviceObject
,
1746 PIO_STACK_LOCATION IoStack
;
1751 /* allocate the irp */
1752 Irp
= IoAllocateIrp(1, /*FIXME */
1756 return STATUS_INSUFFICIENT_RESOURCES
;
1758 /* initialize the event */
1759 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1761 /* get next stack location */
1762 IoStack
= IoGetNextIrpStackLocation(Irp
);
1764 /* setup a completion routine */
1765 IoSetCompletionRoutine(Irp
, KspSetGetBusDataCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
1767 /* setup parameters */
1768 IoStack
->Parameters
.ReadWriteConfig
.Buffer
= Buffer
;
1769 IoStack
->Parameters
.ReadWriteConfig
.Length
= Length
;
1770 IoStack
->Parameters
.ReadWriteConfig
.Offset
= Offset
;
1771 IoStack
->Parameters
.ReadWriteConfig
.WhichSpace
= DataType
;
1772 /* setup function code */
1773 IoStack
->MajorFunction
= IRP_MJ_PNP
;
1774 IoStack
->MinorFunction
= (bGet
? IRP_MN_READ_CONFIG
: IRP_MN_WRITE_CONFIG
);
1776 /* lets call the driver */
1777 Status
= IoCallDriver(DeviceObject
, Irp
);
1779 /* is the request still pending */
1780 if (Status
== STATUS_PENDING
)
1783 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1785 Status
= Irp
->IoStatus
.Status
;
1801 IN PKSDEVICE Device
,
1807 return KspDeviceSetGetBusData(Device
->PhysicalDeviceObject
, /* is this right? */
1808 DataType
, Buffer
, Offset
, Length
, FALSE
);
1819 IN PKSDEVICE Device
,
1825 return KspDeviceSetGetBusData(Device
->PhysicalDeviceObject
, /* is this right? */
1826 DataType
, Buffer
, Offset
, Length
, TRUE
);
1836 KsDeviceRegisterAdapterObject(
1837 IN PKSDEVICE Device
,
1838 IN PADAPTER_OBJECT AdapterObject
,
1839 IN ULONG MaxMappingsByteCount
,
1840 IN ULONG MappingTableStride
)
1851 KsGetBusEnumIdentifier(
1855 return STATUS_UNSUCCESSFUL
;
1864 KsGetBusEnumParentFDOFromChildPDO(
1865 IN PDEVICE_OBJECT DeviceObject
,
1866 OUT PDEVICE_OBJECT
*FunctionalDeviceObject
)
1869 return STATUS_UNSUCCESSFUL
;
1878 KsGetBusEnumPnpDeviceObject(
1879 IN PDEVICE_OBJECT DeviceObject
,
1880 IN PDEVICE_OBJECT
*PnpDeviceObject
)
1883 return STATUS_UNSUCCESSFUL
;
1918 KsInstallBusEnumInterface(
1922 return STATUS_UNSUCCESSFUL
;
1931 KsIsBusEnumChildDevice(
1932 IN PDEVICE_OBJECT DeviceObject
,
1933 OUT PBOOLEAN ChildDevice
)
1936 return STATUS_UNSUCCESSFUL
;
1944 KsMergeAutomationTables(
1945 OUT PKSAUTOMATION_TABLE
*AutomationTableAB
,
1946 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
1947 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
,
1948 IN KSOBJECT_BAG Bag OPTIONAL
)
1951 return STATUS_UNSUCCESSFUL
;
1960 KsServiceBusEnumCreateRequest(
1961 IN PDEVICE_OBJECT DeviceObject
,
1965 return STATUS_UNSUCCESSFUL
;
1975 KsServiceBusEnumPnpRequest(
1976 IN PDEVICE_OBJECT DeviceObject
,
1980 return STATUS_UNSUCCESSFUL
;
1985 KspRemoveBusInterface(
1988 PKSREMOVE_BUS_INTERFACE_CTX Context
=(PKSREMOVE_BUS_INTERFACE_CTX
)Ctx
;
1991 * get SWENUM_INSTALL_INTERFACE struct
1992 * open device key and delete the keys
1998 Context
->Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2001 /* signal completion */
2002 KeSetEvent(&Context
->Event
, IO_NO_INCREMENT
, FALSE
);
2011 KsRemoveBusEnumInterface(
2014 KPROCESSOR_MODE Mode
;
2016 KSREMOVE_BUS_INTERFACE_CTX Ctx
;
2017 WORK_QUEUE_ITEM WorkItem
;
2019 /* get previous mode */
2020 Mode
= ExGetPreviousMode();
2022 /* convert to luid */
2023 luid
= RtlConvertUlongToLuid(SE_LOAD_DRIVER_PRIVILEGE
);
2025 /* perform access check */
2026 if (!SeSinglePrivilegeCheck(luid
, Mode
))
2028 /* insufficient privileges */
2029 return STATUS_PRIVILEGE_NOT_HELD
;
2031 /* initialize event */
2032 KeInitializeEvent(&Ctx
.Event
, NotificationEvent
, FALSE
);
2034 /* store irp in ctx */
2037 /* initialize work item */
2038 ExInitializeWorkItem(&WorkItem
, KspRemoveBusInterface
, (PVOID
)&Ctx
);
2040 /* now queue the work item */
2041 ExQueueWorkItem(&WorkItem
, DelayedWorkQueue
);
2043 /* wait for completion */
2044 KeWaitForSingleObject(&Ctx
.Event
, Executive
, KernelMode
, FALSE
, NULL
);
2047 return Ctx
.Irp
->IoStatus
.Status
;
2058 KsRegisterAggregatedClientUnknown(
2060 IN PUNKNOWN ClientUnknown
)
2071 KsRegisterFilterWithNoKSPins(
2072 IN PDEVICE_OBJECT DeviceObject
,
2073 IN
const GUID
* InterfaceClassGUID
,
2075 IN BOOL
* PinDirection
,
2076 IN KSPIN_MEDIUM
* MediumList
,
2077 IN GUID
* CategoryList OPTIONAL
)
2081 PWSTR SymbolicLinkList
;
2084 UNICODE_STRING InterfaceString
;
2085 //UNICODE_STRING FilterData = RTL_CONSTANT_STRING(L"FilterData");
2087 if (!InterfaceClassGUID
|| !PinCount
|| !PinDirection
|| !MediumList
)
2089 /* all these parameters are required */
2090 return STATUS_INVALID_PARAMETER
;
2093 /* calculate filter data value size */
2094 Size
= PinCount
* sizeof(KSPIN_MEDIUM
);
2097 /* add category list */
2098 Size
+= PinCount
* sizeof(GUID
);
2101 /* FIXME generate filter data blob */
2104 /* get symbolic link list */
2105 Status
= IoGetDeviceInterfaces(InterfaceClassGUID
, DeviceObject
, DEVICE_INTERFACE_INCLUDE_NONACTIVE
, &SymbolicLinkList
);
2106 if (NT_SUCCESS(Status
))
2108 /* initialize first symbolic link */
2109 RtlInitUnicodeString(&InterfaceString
, SymbolicLinkList
);
2111 /* open first device interface registry key */
2112 Status
= IoOpenDeviceInterfaceRegistryKey(&InterfaceString
, GENERIC_WRITE
, &hKey
);
2114 if (NT_SUCCESS(Status
))
2116 /* write filter data */
2117 //Status = ZwSetValueKey(hKey, &FilterData, 0, REG_BINARY, Buffer, Size);
2125 /* update medium cache */
2126 for(Index
= 0; Index
< PinCount
; Index
++)
2128 KsCacheMedium(&InterfaceString
, &MediumList
[Index
], PinDirection
[Index
]);
2132 /* free the symbolic link list */
2133 ExFreePool(SymbolicLinkList
);