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 IoStack
->FileObject
->FsContext2
= ObjectHeader
;
692 /* store parent device */
693 ObjectHeader
->ParentDeviceObject
= IoGetRelatedDeviceObject(IoStack
->FileObject
);
695 /* store originating create item */
696 ObjectHeader
->OriginalCreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
698 /* FIXME store access mask see KsQueryObjectAccessMask */
699 ObjectHeader
->AccessMask
= IoStack
->Parameters
.Create
.SecurityContext
->DesiredAccess
;
703 *Header
= ObjectHeader
;
705 DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader
->ObjectClass
.Buffer
, IoStack
->FileObject
, ObjectHeader
);
707 return STATUS_SUCCESS
;
720 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
) Header
;
722 DPRINT1("KsFreeObjectHeader Header %p Class %wZ\n", Header
, &ObjectHeader
->ObjectClass
);
724 if (ObjectHeader
->ObjectClass
.Buffer
)
726 /* release object class buffer */
727 ExFreePoolWithTag(ObjectHeader
->ObjectClass
.Buffer
, TAG_DEVICE_HEADER
);
730 if (ObjectHeader
->Unknown
)
732 /* release associated object */
733 ObjectHeader
->Unknown
->lpVtbl
->Release(ObjectHeader
->Unknown
);
736 /* free create items */
737 KspFreeCreateItems(&ObjectHeader
->ItemList
);
739 /* free object header */
740 ExFreePoolWithTag(ObjectHeader
, TAG_DEVICE_HEADER
);
745 KspAddObjectCreateItemToList(
746 PLIST_ENTRY ListHead
,
747 IN PDRIVER_DISPATCH Create
,
749 IN PWCHAR ObjectClass
,
750 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
753 PCREATE_ITEM_ENTRY CreateEntry
;
755 /* point to first entry */
756 Entry
= ListHead
->Flink
;
758 while(Entry
!= ListHead
)
760 /* get create entry */
761 CreateEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
762 /* if the create item has no create routine, then it is free to use */
763 if (CreateEntry
->CreateItem
->Create
== NULL
)
766 ASSERT(IsListEmpty(&CreateEntry
->ObjectItemList
));
767 ASSERT(CreateEntry
->ReferenceCount
== 0);
769 CreateEntry
->CreateItem
->Context
= Context
;
770 CreateEntry
->CreateItem
->Create
= Create
;
771 RtlInitUnicodeString(&CreateEntry
->CreateItem
->ObjectClass
, ObjectClass
);
772 CreateEntry
->CreateItem
->SecurityDescriptor
= SecurityDescriptor
;
774 return STATUS_SUCCESS
;
777 if (!wcsicmp(ObjectClass
, CreateEntry
->CreateItem
->ObjectClass
.Buffer
))
779 /* the same object class already exists */
780 return STATUS_OBJECT_NAME_COLLISION
;
783 /* iterate to next entry */
784 Entry
= Entry
->Flink
;
786 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
795 KsAddObjectCreateItemToDeviceHeader(
796 IN KSDEVICE_HEADER DevHeader
,
797 IN PDRIVER_DISPATCH Create
,
799 IN PWCHAR ObjectClass
,
800 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
802 PKSIDEVICE_HEADER Header
;
805 Header
= (PKSIDEVICE_HEADER
)DevHeader
;
807 DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n");
809 /* check if a device header has been provided */
811 return STATUS_INVALID_PARAMETER_1
;
813 /* check if a create item has been provided */
815 return STATUS_INVALID_PARAMETER_2
;
817 /* check if a object class has been provided */
819 return STATUS_INVALID_PARAMETER_4
;
821 /* let others do the work */
822 Status
= KspAddObjectCreateItemToList(&Header
->ItemList
, Create
, Context
, ObjectClass
, SecurityDescriptor
);
824 if (NT_SUCCESS(Status
))
826 /* increment create item count */
827 InterlockedIncrement(&Header
->ItemListCount
);
829 DPRINT("KsAddObjectCreateItemToDeviceHeader Status %x\n", Status
);
839 KsAddObjectCreateItemToObjectHeader(
840 IN KSOBJECT_HEADER ObjectHeader
,
841 IN PDRIVER_DISPATCH Create
,
843 IN PWCHAR ObjectClass
,
844 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
846 PKSIOBJECT_HEADER Header
;
849 Header
= (PKSIOBJECT_HEADER
)ObjectHeader
;
851 DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n");
853 /* check if a device header has been provided */
855 return STATUS_INVALID_PARAMETER_1
;
857 /* check if a create item has been provided */
859 return STATUS_INVALID_PARAMETER_2
;
861 /* check if a object class has been provided */
863 return STATUS_INVALID_PARAMETER_4
;
866 Status
= KspAddObjectCreateItemToList(&Header
->ItemList
, Create
, Context
, ObjectClass
, SecurityDescriptor
);
868 if (NT_SUCCESS(Status
))
870 /* increment create item count */
871 InterlockedIncrement(&Header
->ItemListCount
);
883 KsAllocateObjectCreateItem(
884 IN KSDEVICE_HEADER DevHeader
,
885 IN PKSOBJECT_CREATE_ITEM CreateItem
,
886 IN BOOLEAN AllocateEntry
,
887 IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL
)
889 PCREATE_ITEM_ENTRY CreateEntry
;
890 PKSIDEVICE_HEADER Header
;
891 PKSOBJECT_CREATE_ITEM Item
;
893 Header
= (PKSIDEVICE_HEADER
)DevHeader
;
896 return STATUS_INVALID_PARAMETER_1
;
899 return STATUS_INVALID_PARAMETER_2
;
901 /* first allocate a create entry */
902 CreateEntry
= AllocateItem(NonPagedPool
, sizeof(CREATE_ITEM_ENTRY
));
904 /* check for allocation success */
907 /* not enough resources */
908 return STATUS_INSUFFICIENT_RESOURCES
;
914 /* allocate create item */
915 Item
= ExAllocatePool(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
));
919 ExFreePool(CreateEntry
);
920 return STATUS_INSUFFICIENT_RESOURCES
;
923 /* initialize descriptor */
924 Item
->Context
= CreateItem
->Context
;
925 Item
->Create
= CreateItem
->Create
;
926 Item
->Flags
= CreateItem
->Flags
;
927 Item
->SecurityDescriptor
= CreateItem
->SecurityDescriptor
;
928 Item
->ObjectClass
.Length
= 0;
929 Item
->ObjectClass
.MaximumLength
= CreateItem
->ObjectClass
.MaximumLength
;
931 /* copy object class */
932 Item
->ObjectClass
.Buffer
= ExAllocatePool(NonPagedPool
, Item
->ObjectClass
.MaximumLength
);
933 if (!Item
->ObjectClass
.Buffer
)
935 /* release resources */
937 FreeItem(CreateEntry
);
939 return STATUS_INSUFFICIENT_RESOURCES
;
941 RtlCopyUnicodeString(&Item
->ObjectClass
, &CreateItem
->ObjectClass
);
945 if (ItemFreeCallback
)
947 /* callback is only accepted when the create item is copied */
948 ItemFreeCallback
= NULL
;
950 /* use passed create item */
954 /* initialize create item entry */
955 InitializeListHead(&CreateEntry
->ObjectItemList
);
956 CreateEntry
->ItemFreeCallback
= ItemFreeCallback
;
957 CreateEntry
->CreateItem
= Item
;
958 CreateEntry
->ReferenceCount
= 0;
960 /* now insert the create item entry */
961 InsertTailList(&Header
->ItemList
, &CreateEntry
->Entry
);
963 /* increment item count */
964 InterlockedIncrement(&Header
->ItemListCount
);
966 return STATUS_SUCCESS
;
970 KspObjectFreeCreateItems(
971 IN KSDEVICE_HEADER Header
,
972 IN PKSOBJECT_CREATE_ITEM CreateItem
)
975 return STATUS_NOT_IMPLEMENTED
;
984 KsFreeObjectCreateItem(
985 IN KSDEVICE_HEADER Header
,
986 IN PUNICODE_STRING CreateItem
)
988 KSOBJECT_CREATE_ITEM Item
;
990 RtlZeroMemory(&Item
, sizeof(KSOBJECT_CREATE_ITEM
));
991 RtlInitUnicodeString(&Item
.ObjectClass
, CreateItem
->Buffer
);
993 return KspObjectFreeCreateItems(Header
, &Item
);
1003 KsFreeObjectCreateItemsByContext(
1004 IN KSDEVICE_HEADER Header
,
1007 KSOBJECT_CREATE_ITEM Item
;
1009 RtlZeroMemory(&Item
, sizeof(KSOBJECT_CREATE_ITEM
));
1011 Item
.Context
= Context
;
1013 return KspObjectFreeCreateItems(Header
, &Item
);
1022 KsCreateDefaultSecurity(
1023 IN PSECURITY_DESCRIPTOR ParentSecurity OPTIONAL
,
1024 OUT PSECURITY_DESCRIPTOR
* DefaultSecurity
)
1026 PGENERIC_MAPPING Mapping
;
1027 SECURITY_SUBJECT_CONTEXT SubjectContext
;
1030 /* start capturing security context of calling thread */
1031 SeCaptureSubjectContext(&SubjectContext
);
1032 /* get generic mapping */
1033 Mapping
= IoGetFileObjectGenericMapping();
1034 /* build new descriptor */
1035 Status
= SeAssignSecurity(ParentSecurity
, NULL
, DefaultSecurity
, FALSE
, &SubjectContext
, Mapping
, NonPagedPool
);
1036 /* release security descriptor */
1037 SeReleaseSubjectContext(&SubjectContext
);
1050 IN PFILE_OBJECT FileObject
,
1051 IN BOOLEAN ReuseStackLocation
)
1054 return STATUS_UNSUCCESSFUL
;
1064 KsForwardAndCatchIrp(
1065 IN PDEVICE_OBJECT DeviceObject
,
1067 IN PFILE_OBJECT FileObject
,
1068 IN KSSTACK_USE StackUse
)
1071 return STATUS_UNSUCCESSFUL
;
1077 KspSynchronousIoControlDeviceCompletion(
1078 IN PDEVICE_OBJECT DeviceObject
,
1082 PIO_STATUS_BLOCK IoStatusBlock
= (PIO_STATUS_BLOCK
)Context
;
1084 IoStatusBlock
->Information
= Irp
->IoStatus
.Information
;
1085 IoStatusBlock
->Status
= Irp
->IoStatus
.Status
;
1087 return STATUS_SUCCESS
;
1096 KsSynchronousIoControlDevice(
1097 IN PFILE_OBJECT FileObject
,
1098 IN KPROCESSOR_MODE RequestorMode
,
1102 OUT PVOID OutBuffer
,
1104 OUT PULONG BytesReturned
)
1106 PKSIOBJECT_HEADER ObjectHeader
;
1107 PDEVICE_OBJECT DeviceObject
;
1110 IO_STATUS_BLOCK IoStatusBlock
;
1111 PIO_STACK_LOCATION IoStack
;
1114 /* check for valid file object */
1116 return STATUS_INVALID_PARAMETER
;
1118 /* get device object to send the request to */
1119 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
1121 return STATUS_UNSUCCESSFUL
;
1124 /* get object header */
1125 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext2
;
1127 /* check if there is fast device io function */
1128 if (ObjectHeader
&& ObjectHeader
->DispatchTable
.FastDeviceIoControl
)
1130 IoStatusBlock
.Status
= STATUS_UNSUCCESSFUL
;
1131 IoStatusBlock
.Information
= 0;
1133 /* send the request */
1134 Status
= ObjectHeader
->DispatchTable
.FastDeviceIoControl(FileObject
, TRUE
, InBuffer
, InSize
, OutBuffer
, OutSize
, IoControl
, &IoStatusBlock
, DeviceObject
);
1135 /* check if the request was handled */
1136 //DPRINT("Handled %u Status %x Length %u\n", Status, IoStatusBlock.Status, IoStatusBlock.Information);
1139 /* store bytes returned */
1140 *BytesReturned
= IoStatusBlock
.Information
;
1142 return IoStatusBlock
.Status
;
1146 /* initialize the event */
1147 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1149 /* create the irp */
1150 Irp
= IoBuildDeviceIoControlRequest(IoControl
, DeviceObject
, InBuffer
, InSize
, OutBuffer
, OutSize
, FALSE
, &Event
, &IoStatusBlock
);
1154 /* no memory to allocate the irp */
1155 return STATUS_INSUFFICIENT_RESOURCES
;
1159 /* Store Fileobject */
1160 IoStack
= IoGetNextIrpStackLocation(Irp
);
1161 IoStack
->FileObject
= FileObject
;
1163 if (IoControl
== IOCTL_KS_WRITE_STREAM
)
1165 Irp
->AssociatedIrp
.SystemBuffer
= OutBuffer
;
1167 else if (IoControl
== IOCTL_KS_READ_STREAM
)
1169 Irp
->AssociatedIrp
.SystemBuffer
= InBuffer
;
1172 IoSetCompletionRoutine(Irp
, KspSynchronousIoControlDeviceCompletion
, (PVOID
)&IoStatusBlock
, TRUE
, TRUE
, TRUE
);
1174 Status
= IoCallDriver(DeviceObject
, Irp
);
1175 if (Status
== STATUS_PENDING
)
1177 KeWaitForSingleObject(&Event
, Executive
, RequestorMode
, FALSE
, NULL
);
1178 Status
= IoStatusBlock
.Status
;
1181 *BytesReturned
= IoStatusBlock
.Information
;
1191 KsUnserializeObjectPropertiesFromRegistry(
1192 IN PFILE_OBJECT FileObject
,
1193 IN HANDLE ParentKey OPTIONAL
,
1194 IN PUNICODE_STRING RegistryPath OPTIONAL
)
1197 return STATUS_NOT_IMPLEMENTED
;
1208 IN PUNICODE_STRING SymbolicLink
,
1209 IN PKSPIN_MEDIUM Medium
,
1210 IN ULONG PinDirection
)
1213 UNICODE_STRING Path
;
1214 UNICODE_STRING BasePath
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediumCache\\");
1215 UNICODE_STRING GuidString
;
1217 OBJECT_ATTRIBUTES ObjectAttributes
;
1218 BOOLEAN PathAdjusted
= FALSE
;
1221 /* first check if the medium is standard */
1222 if (IsEqualGUIDAligned(&KSMEDIUMSETID_Standard
, &Medium
->Set
) ||
1223 IsEqualGUIDAligned(&GUID_NULL
, &Medium
->Set
))
1225 /* no need to cache that */
1226 return STATUS_SUCCESS
;
1229 /* convert guid to string */
1230 Status
= RtlStringFromGUID(&Medium
->Set
, &GuidString
);
1231 if (!NT_SUCCESS(Status
))
1234 /* allocate path buffer */
1236 Path
.MaximumLength
= BasePath
.MaximumLength
+ GuidString
.MaximumLength
+ 10 * sizeof(WCHAR
);
1237 Path
.Buffer
= AllocateItem(PagedPool
, Path
.MaximumLength
);
1240 /* not enough resources */
1241 RtlFreeUnicodeString(&GuidString
);
1242 return STATUS_INSUFFICIENT_RESOURCES
;
1245 RtlAppendUnicodeStringToString(&Path
, &BasePath
);
1246 RtlAppendUnicodeStringToString(&Path
, &GuidString
);
1247 RtlAppendUnicodeToString(&Path
, L
"-");
1248 /* FIXME append real instance id */
1249 RtlAppendUnicodeToString(&Path
, L
"0");
1250 RtlAppendUnicodeToString(&Path
, L
"-");
1251 /* FIXME append real instance id */
1252 RtlAppendUnicodeToString(&Path
, L
"0");
1254 /* free guid string */
1255 RtlFreeUnicodeString(&GuidString
);
1257 /* initialize object attributes */
1258 InitializeObjectAttributes(&ObjectAttributes
, &Path
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1259 /* create the key */
1260 Status
= ZwCreateKey(&hKey
, GENERIC_WRITE
, &ObjectAttributes
, 0, NULL
, 0, NULL
);
1262 /* free path buffer */
1263 FreeItem(Path
.Buffer
);
1265 if (NT_SUCCESS(Status
))
1267 /* store symbolic link */
1268 if (SymbolicLink
->Buffer
[1] == L
'?' && SymbolicLink
->Buffer
[2] == L
'?')
1270 /* replace kernel path with user mode path */
1271 SymbolicLink
->Buffer
[1] = L
'\\';
1272 PathAdjusted
= TRUE
;
1276 Status
= ZwSetValueKey(hKey
, SymbolicLink
, 0, REG_DWORD
, &Value
, sizeof(ULONG
));
1280 /* restore kernel path */
1281 SymbolicLink
->Buffer
[1] = L
'?';
1297 PUNICODE_STRING RegistryPath
)
1299 return STATUS_SUCCESS
;
1306 IN PDEVICE_OBJECT DeviceObject
,
1309 PKO_OBJECT_HEADER Header
;
1310 PIO_STACK_LOCATION IoStack
;
1311 PDEVICE_EXTENSION DeviceExtension
;
1313 /* get current irp stack location */
1314 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1316 /* get ko object header */
1317 Header
= (PKO_OBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1319 /* free ks object header */
1320 KsFreeObjectHeader(Header
->ObjectHeader
);
1322 /* free ko object header */
1325 /* get device extension */
1326 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1328 /* release bus object */
1329 KsDereferenceBusObject((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
);
1331 /* complete request */
1332 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1333 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1335 return STATUS_SUCCESS
;
1340 static KSDISPATCH_TABLE KoDispatchTable
=
1342 KsDispatchInvalidDeviceRequest
,
1343 KsDispatchInvalidDeviceRequest
,
1344 KsDispatchInvalidDeviceRequest
,
1345 KsDispatchInvalidDeviceRequest
,
1347 KsDispatchQuerySecurity
,
1348 KsDispatchSetSecurity
,
1349 KsDispatchFastIoDeviceControlFailure
,
1350 KsDispatchFastReadFailure
,
1351 KsDispatchFastReadFailure
,
1358 IN PDEVICE_OBJECT DeviceObject
,
1361 PKO_OBJECT_HEADER Header
= NULL
;
1362 PIO_STACK_LOCATION IoStack
;
1363 PKO_DRIVER_EXTENSION DriverObjectExtension
;
1366 /* get current irp stack location */
1367 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1369 if (!IoStack
->FileObject
)
1371 DPRINT1("FileObject not attached!\n");
1372 Status
= STATUS_UNSUCCESSFUL
;
1376 /* get driver object extension */
1377 DriverObjectExtension
= (PKO_DRIVER_EXTENSION
)IoGetDriverObjectExtension(DeviceObject
->DriverObject
, (PVOID
)KoDriverInitialize
);
1378 if (!DriverObjectExtension
)
1380 DPRINT1("FileObject not attached!\n");
1381 Status
= STATUS_UNSUCCESSFUL
;
1385 /* allocate ko object header */
1386 Header
= (PKO_OBJECT_HEADER
)AllocateItem(NonPagedPool
, sizeof(KO_OBJECT_HEADER
));
1389 DPRINT1("failed to allocate KO_OBJECT_HEADER\n");
1390 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1394 /* initialize create item */
1395 Header
->CreateItem
.Create
= KopDispatchCreate
;
1396 RtlInitUnicodeString(&Header
->CreateItem
.ObjectClass
, KOSTRING_CreateObject
);
1399 /* now allocate the object header */
1400 Status
= KsAllocateObjectHeader(&Header
->ObjectHeader
, 1, &Header
->CreateItem
, Irp
, &KoDispatchTable
);
1401 if (!NT_SUCCESS(Status
))
1408 * extract clsid and interface id from irp
1409 * call the standard create handler
1414 IoStack
->FileObject
->FsContext2
= (PVOID
)Header
;
1416 Irp
->IoStatus
.Status
= Status
;
1417 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1423 if (Header
&& Header
->ObjectHeader
)
1424 KsFreeObjectHeader(Header
->ObjectHeader
);
1429 Irp
->IoStatus
.Status
= Status
;
1430 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1439 IN PDRIVER_OBJECT DriverObject
,
1440 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1442 NTSTATUS Status
= STATUS_DEVICE_REMOVED
;
1443 PDEVICE_OBJECT FunctionalDeviceObject
= NULL
;
1444 PDEVICE_OBJECT NextDeviceObject
;
1445 PDEVICE_EXTENSION DeviceExtension
;
1446 PKSOBJECT_CREATE_ITEM CreateItem
;
1448 /* create the device object */
1449 Status
= IoCreateDevice(DriverObject
, sizeof(DEVICE_EXTENSION
), NULL
, FILE_DEVICE_KS
, FILE_DEVICE_SECURE_OPEN
, FALSE
, &FunctionalDeviceObject
);
1450 if (!NT_SUCCESS(Status
))
1453 /* allocate the create item */
1454 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
));
1458 /* not enough memory */
1459 IoDeleteDevice(FunctionalDeviceObject
);
1460 return STATUS_INSUFFICIENT_RESOURCES
;
1463 /* initialize create item */
1464 CreateItem
->Create
= KopDispatchCreate
;
1465 RtlInitUnicodeString(&CreateItem
->ObjectClass
, KOSTRING_CreateObject
);
1467 /* get device extension */
1468 DeviceExtension
= (PDEVICE_EXTENSION
)FunctionalDeviceObject
->DeviceExtension
;
1470 /* now allocate the device header */
1471 Status
= KsAllocateDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
, 1, CreateItem
);
1472 if (!NT_SUCCESS(Status
))
1475 IoDeleteDevice(FunctionalDeviceObject
);
1476 FreeItem(CreateItem
);
1480 /* now attach to device stack */
1481 NextDeviceObject
= IoAttachDeviceToDeviceStack(FunctionalDeviceObject
, PhysicalDeviceObject
);
1482 if (NextDeviceObject
)
1484 /* store pnp base object */
1485 KsSetDevicePnpAndBaseObject((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, NextDeviceObject
, FunctionalDeviceObject
);
1486 /* set device flags */
1487 FunctionalDeviceObject
->Flags
|= DO_DIRECT_IO
| DO_POWER_PAGABLE
;
1488 FunctionalDeviceObject
->Flags
&= ~ DO_DEVICE_INITIALIZING
;
1493 KsFreeDeviceHeader((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
);
1494 FreeItem(CreateItem
);
1495 IoDeleteDevice(FunctionalDeviceObject
);
1496 Status
= STATUS_DEVICE_REMOVED
;
1511 IN PDEVICE_OBJECT DeviceObject
)
1513 PDEVICE_EXTENSION DeviceExtension
;
1515 /* get device extension */
1516 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1518 return KsAddObjectCreateItemToDeviceHeader((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, KopDispatchCreate
, NULL
, KOSTRING_CreateObject
, NULL
);
1528 IN PDRIVER_OBJECT DriverObject
,
1529 IN PUNICODE_STRING RegistryPathName
,
1530 IN KoCreateObjectHandler CreateObjectHandler
)
1532 PKO_DRIVER_EXTENSION DriverObjectExtension
;
1535 /* allocate driver object extension */
1536 Status
= IoAllocateDriverObjectExtension(DriverObject
, (PVOID
)KoDriverInitialize
, sizeof(KO_DRIVER_EXTENSION
), (PVOID
*)&DriverObjectExtension
);
1539 if (NT_SUCCESS(Status
))
1541 /* store create handler */
1542 DriverObjectExtension
->CreateObjectHandler
= CreateObjectHandler
;
1544 /* Setting our IRP handlers */
1545 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = KsDefaultDispatchPnp
;
1546 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = KsDefaultDispatchPower
;
1547 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = KsDefaultForwardIrp
;
1549 /* The driver unload routine */
1550 DriverObject
->DriverUnload
= KsNullDriverUnload
;
1552 /* The driver-supplied AddDevice */
1553 DriverObject
->DriverExtension
->AddDevice
= KopAddDevice
;
1555 /* KS handles these */
1556 DPRINT1("Setting KS function handlers\n");
1557 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_CREATE
);
1558 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_CLOSE
);
1559 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_DEVICE_CONTROL
);
1573 IN REFCLSID ClassId
)
1587 PKSBASIC_HEADER BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
1590 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
1592 KeWaitForSingleObject(&BasicHeader
->ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1604 PKSBASIC_HEADER BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
1607 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
1609 KeReleaseMutex(&BasicHeader
->ControlMutex
, FALSE
);
1621 IN PKSDEVICE Device
)
1623 IKsDevice
*KsDevice
;
1624 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(Device
, KSIDEVICE_HEADER
, KsDevice
);
1626 /* get device interface*/
1627 KsDevice
= (IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
;
1629 /* acquire device mutex */
1630 KsDevice
->lpVtbl
->AcquireDevice(KsDevice
);
1639 IN PKSDEVICE Device
)
1641 IKsDevice
*KsDevice
;
1642 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(Device
, KSIDEVICE_HEADER
, KsDevice
);
1644 /* get device interface*/
1645 KsDevice
= (IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
;
1647 /* release device mutex */
1648 KsDevice
->lpVtbl
->ReleaseDevice(KsDevice
);
1658 IN PDEVICE_OBJECT DeviceObject
)
1660 IKsDevice
*KsDevice
;
1661 PKSIDEVICE_HEADER DeviceHeader
;
1662 PDEVICE_EXTENSION DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1664 /* get device header */
1665 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1667 /* get device interface*/
1668 KsDevice
= (IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
;
1670 /* now free device header */
1671 KsFreeDeviceHeader((KSDEVICE_HEADER
)DeviceHeader
);
1673 /* release interface when available */
1676 /* delete IKsDevice interface */
1677 KsDevice
->lpVtbl
->Release(KsDevice
);
1687 KsCompletePendingRequest(
1690 PIO_STACK_LOCATION IoStack
;
1692 /* get current irp stack location */
1693 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1696 ASSERT(Irp
->IoStatus
.Status
!= STATUS_PENDING
);
1698 if (IoStack
->MajorFunction
!= IRP_MJ_CLOSE
)
1700 /* can be completed immediately */
1701 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1705 /* did close operation fail */
1706 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
1708 /* closing failed, complete irp */
1709 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1714 * delete object / device header
1715 * remove dead pin / filter instance
1727 KsCreateBusEnumObject(
1728 IN PWCHAR BusIdentifier
,
1729 IN PDEVICE_OBJECT BusDeviceObject
,
1730 IN PDEVICE_OBJECT PhysicalDeviceObject
,
1731 IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL
,
1732 IN REFGUID InterfaceGuid OPTIONAL
,
1733 IN PWCHAR ServiceRelativePath OPTIONAL
)
1736 NTSTATUS Status
= STATUS_SUCCESS
;
1737 UNICODE_STRING ServiceKeyPath
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
1738 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension
;
1739 PDEVICE_EXTENSION DeviceExtension
;
1741 /* calculate sizeof bus enum device extension */
1742 Length
= wcslen(BusIdentifier
) * sizeof(WCHAR
);
1743 Length
+= sizeof(BUS_ENUM_DEVICE_EXTENSION
);
1745 BusDeviceExtension
= ExAllocatePool(NonPagedPool
, Length
);
1746 if (!BusDeviceExtension
)
1748 /* not enough memory */
1749 return STATUS_INSUFFICIENT_RESOURCES
;
1752 /* zero device extension */
1753 RtlZeroMemory(BusDeviceExtension
, sizeof(BUS_ENUM_DEVICE_EXTENSION
));
1755 /* initialize bus device extension */
1756 wcscpy(BusDeviceExtension
->BusIdentifier
, BusIdentifier
);
1758 /* allocate service path string */
1759 Length
= ServiceKeyPath
.MaximumLength
;
1760 Length
+= BusDeviceObject
->DriverObject
->DriverExtension
->ServiceKeyName
.MaximumLength
;
1762 if (ServiceRelativePath
)
1764 /* relative path for devices */
1765 Length
+= wcslen(ServiceRelativePath
) + 2 * sizeof(WCHAR
);
1768 BusDeviceExtension
->ServicePath
.Length
= 0;
1769 BusDeviceExtension
->ServicePath
.MaximumLength
= Length
;
1770 BusDeviceExtension
->ServicePath
.Buffer
= ExAllocatePool(NonPagedPool
, Length
);
1772 if (!BusDeviceExtension
->ServicePath
.Buffer
)
1774 /* not enough memory */
1775 ExFreePool(BusDeviceExtension
);
1776 return STATUS_INSUFFICIENT_RESOURCES
;
1779 RtlAppendUnicodeStringToString(&BusDeviceExtension
->ServicePath
, &ServiceKeyPath
);
1780 RtlAppendUnicodeStringToString(&BusDeviceExtension
->ServicePath
, &BusDeviceObject
->DriverObject
->DriverExtension
->ServiceKeyName
);
1782 if (ServiceRelativePath
)
1784 RtlAppendUnicodeToString(&BusDeviceExtension
->ServicePath
, L
"\\");
1785 RtlAppendUnicodeToString(&BusDeviceExtension
->ServicePath
, ServiceRelativePath
);
1790 /* register an device interface */
1791 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
, InterfaceGuid
, NULL
, &BusDeviceExtension
->SymbolicLinkName
);
1793 /* check for success */
1794 if (!NT_SUCCESS(Status
))
1796 ExFreePool(BusDeviceExtension
->ServicePath
.Buffer
);
1797 ExFreePool(BusDeviceExtension
);
1801 /* now enable device interface */
1802 Status
= IoSetDeviceInterfaceState(&BusDeviceExtension
->SymbolicLinkName
, TRUE
);
1804 if (!NT_SUCCESS(Status
))
1806 ExFreePool(BusDeviceExtension
->ServicePath
.Buffer
);
1807 ExFreePool(BusDeviceExtension
);
1811 /* set state enabled */
1812 BusDeviceExtension
->Enabled
= TRUE
;
1815 /* store device objects */
1816 BusDeviceExtension
->BusDeviceObject
= BusDeviceObject
;
1817 BusDeviceExtension
->PnpDeviceObject
= PnpDeviceObject
;
1818 BusDeviceExtension
->PhysicalDeviceObject
= PhysicalDeviceObject
;
1820 if (!PnpDeviceObject
)
1822 BusDeviceExtension
->PnpDeviceObject
= IoAttachDeviceToDeviceStack(BusDeviceObject
, PhysicalDeviceObject
);
1824 if (!BusDeviceExtension
->PnpDeviceObject
)
1826 /* failed to attach device */
1827 if (BusDeviceExtension
->Enabled
)
1829 IoSetDeviceInterfaceState(&BusDeviceExtension
->SymbolicLinkName
, FALSE
);
1830 RtlFreeUnicodeString(&BusDeviceExtension
->SymbolicLinkName
);
1833 /* free device extension */
1834 ExFreePool(BusDeviceExtension
->ServicePath
.Buffer
);
1835 ExFreePool(BusDeviceExtension
);
1837 return STATUS_DEVICE_REMOVED
;
1841 /* attach device extension */
1842 DeviceExtension
= (PDEVICE_EXTENSION
)BusDeviceObject
->DeviceExtension
;
1843 DeviceExtension
->DeviceHeader
= (PKSIDEVICE_HEADER
)BusDeviceExtension
;
1845 /* FIXME scan bus and invalidate device relations */
1851 KspSetGetBusDataCompletion(
1852 IN PDEVICE_OBJECT DeviceObject
,
1856 /* signal completion */
1857 KeSetEvent((PRKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
1859 /* more work needs be done, so dont free the irp */
1860 return STATUS_MORE_PROCESSING_REQUIRED
;
1865 KspDeviceSetGetBusData(
1866 IN PDEVICE_OBJECT DeviceObject
,
1873 PIO_STACK_LOCATION IoStack
;
1878 /* allocate the irp */
1879 Irp
= IoAllocateIrp(1, /*FIXME */
1883 return STATUS_INSUFFICIENT_RESOURCES
;
1885 /* initialize the event */
1886 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1888 /* get next stack location */
1889 IoStack
= IoGetNextIrpStackLocation(Irp
);
1891 /* setup a completion routine */
1892 IoSetCompletionRoutine(Irp
, KspSetGetBusDataCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
1894 /* setup parameters */
1895 IoStack
->Parameters
.ReadWriteConfig
.Buffer
= Buffer
;
1896 IoStack
->Parameters
.ReadWriteConfig
.Length
= Length
;
1897 IoStack
->Parameters
.ReadWriteConfig
.Offset
= Offset
;
1898 IoStack
->Parameters
.ReadWriteConfig
.WhichSpace
= DataType
;
1899 /* setup function code */
1900 IoStack
->MajorFunction
= IRP_MJ_PNP
;
1901 IoStack
->MinorFunction
= (bGet
? IRP_MN_READ_CONFIG
: IRP_MN_WRITE_CONFIG
);
1903 /* lets call the driver */
1904 Status
= IoCallDriver(DeviceObject
, Irp
);
1906 /* is the request still pending */
1907 if (Status
== STATUS_PENDING
)
1910 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1912 Status
= Irp
->IoStatus
.Status
;
1928 IN PKSDEVICE Device
,
1934 return KspDeviceSetGetBusData(Device
->PhysicalDeviceObject
, /* is this right? */
1935 DataType
, Buffer
, Offset
, Length
, FALSE
);
1946 IN PKSDEVICE Device
,
1952 return KspDeviceSetGetBusData(Device
->PhysicalDeviceObject
, /* is this right? */
1953 DataType
, Buffer
, Offset
, Length
, TRUE
);
1963 KsDeviceRegisterAdapterObject(
1964 IN PKSDEVICE Device
,
1965 IN PADAPTER_OBJECT AdapterObject
,
1966 IN ULONG MaxMappingsByteCount
,
1967 IN ULONG MappingTableStride
)
1978 KsGetBusEnumIdentifier(
1982 return STATUS_UNSUCCESSFUL
;
1991 KsGetBusEnumParentFDOFromChildPDO(
1992 IN PDEVICE_OBJECT DeviceObject
,
1993 OUT PDEVICE_OBJECT
*FunctionalDeviceObject
)
1996 return STATUS_UNSUCCESSFUL
;
2005 KsGetBusEnumPnpDeviceObject(
2006 IN PDEVICE_OBJECT DeviceObject
,
2007 IN PDEVICE_OBJECT
*PnpDeviceObject
)
2010 return STATUS_UNSUCCESSFUL
;
2022 PKSBASIC_HEADER BasicHeader
;
2024 /* get the basic header */
2025 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
2027 /* type has to be either a device or a filter factory */
2028 ASSERT(BasicHeader
->Type
== KsObjectTypeDevice
|| BasicHeader
->Type
== KsObjectTypeFilterFactory
);
2030 return (PVOID
)BasicHeader
->FirstChild
.Filter
;
2042 PKSBASIC_HEADER BasicHeader
;
2044 /* get the basic header */
2045 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
2047 ASSERT(BasicHeader
->Type
== KsObjectTypeDevice
|| BasicHeader
->Type
== KsObjectTypeFilterFactory
||
2048 BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
2050 return (PVOID
)BasicHeader
->Next
.Pin
;
2059 KsInstallBusEnumInterface(
2063 return STATUS_UNSUCCESSFUL
;
2072 KsIsBusEnumChildDevice(
2073 IN PDEVICE_OBJECT DeviceObject
,
2074 OUT PBOOLEAN ChildDevice
)
2077 return STATUS_UNSUCCESSFUL
;
2082 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2083 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2085 ULONG Index
, SubIndex
, Count
;
2088 if (!AutomationTableA
)
2089 return AutomationTableB
->MethodSetsCount
;
2091 if (!AutomationTableB
)
2092 return AutomationTableA
->MethodSetsCount
;
2095 ASSERT(AutomationTableA
->MethodItemSize
== AutomationTableB
->MethodItemSize
);
2097 /* now iterate all property sets and compare their guids */
2098 Count
= AutomationTableA
->MethodSetsCount
;
2100 for(Index
= 0; Index
< AutomationTableB
->MethodSetsCount
; Index
++)
2102 /* set found to false */
2105 for(SubIndex
= 0; SubIndex
< AutomationTableA
->MethodSetsCount
; SubIndex
++)
2107 if (IsEqualGUIDAligned(AutomationTableB
->MethodSets
[Index
].Set
, AutomationTableA
->MethodSets
[SubIndex
].Set
))
2109 /* same property set found */
2124 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2125 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2127 ULONG Index
, SubIndex
, Count
;
2130 if (!AutomationTableA
)
2131 return AutomationTableB
->EventSetsCount
;
2133 if (!AutomationTableB
)
2134 return AutomationTableA
->EventSetsCount
;
2137 ASSERT(AutomationTableA
->EventItemSize
== AutomationTableB
->EventItemSize
);
2139 /* now iterate all Event sets and compare their guids */
2140 Count
= AutomationTableA
->EventSetsCount
;
2142 for(Index
= 0; Index
< AutomationTableB
->EventSetsCount
; Index
++)
2144 /* set found to false */
2147 for(SubIndex
= 0; SubIndex
< AutomationTableA
->EventSetsCount
; SubIndex
++)
2149 if (IsEqualGUIDAligned(AutomationTableB
->EventSets
[Index
].Set
, AutomationTableA
->EventSets
[SubIndex
].Set
))
2151 /* same Event set found */
2166 KspCountPropertySets(
2167 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2168 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2170 ULONG Index
, SubIndex
, Count
;
2173 if (!AutomationTableA
)
2174 return AutomationTableB
->PropertySetsCount
;
2176 if (!AutomationTableB
)
2177 return AutomationTableA
->PropertySetsCount
;
2180 ASSERT(AutomationTableA
->PropertyItemSize
== AutomationTableB
->PropertyItemSize
);
2182 /* now iterate all property sets and compare their guids */
2183 Count
= AutomationTableA
->PropertySetsCount
;
2185 for(Index
= 0; Index
< AutomationTableB
->PropertySetsCount
; Index
++)
2187 /* set found to false */
2190 for(SubIndex
= 0; SubIndex
< AutomationTableA
->PropertySetsCount
; SubIndex
++)
2192 if (IsEqualGUIDAligned(AutomationTableB
->PropertySets
[Index
].Set
, AutomationTableA
->PropertySets
[SubIndex
].Set
))
2194 /* same property set found */
2209 OUT PKSAUTOMATION_TABLE Table
,
2210 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2211 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2213 ULONG Index
, SubIndex
, Count
;
2216 if (!AutomationTableA
)
2218 /* copy of property set */
2219 RtlMoveMemory((PVOID
)Table
->MethodSets
, AutomationTableB
->MethodSets
, Table
->MethodItemSize
* AutomationTableB
->MethodSetsCount
);
2220 return STATUS_SUCCESS
;
2222 else if (!AutomationTableB
)
2224 /* copy of property set */
2225 RtlMoveMemory((PVOID
)Table
->MethodSets
, AutomationTableA
->MethodSets
, Table
->MethodItemSize
* AutomationTableA
->MethodSetsCount
);
2226 return STATUS_SUCCESS
;
2229 /* first copy all property items from dominant table */
2230 RtlMoveMemory((PVOID
)Table
->MethodSets
, AutomationTableA
->MethodSets
, Table
->MethodItemSize
* AutomationTableA
->MethodSetsCount
);
2232 Count
= AutomationTableA
->MethodSetsCount
;
2234 /* now copy entries which arent available in the dominant table */
2235 for(Index
= 0; Index
< AutomationTableB
->MethodSetsCount
; Index
++)
2237 /* set found to false */
2240 for(SubIndex
= 0; SubIndex
< AutomationTableA
->MethodSetsCount
; SubIndex
++)
2242 if (IsEqualGUIDAligned(AutomationTableB
->MethodSets
[Index
].Set
, AutomationTableA
->MethodSets
[SubIndex
].Set
))
2244 /* same property set found */
2252 /* copy new property item set */
2253 RtlMoveMemory((PVOID
)&Table
->MethodSets
[Count
], &AutomationTableB
->MethodSets
[Index
], Table
->MethodItemSize
);
2258 return STATUS_SUCCESS
;
2263 KspCopyPropertySets(
2264 OUT PKSAUTOMATION_TABLE Table
,
2265 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2266 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2268 ULONG Index
, SubIndex
, Count
;
2271 if (!AutomationTableA
)
2273 /* copy of property set */
2274 RtlMoveMemory((PVOID
)Table
->PropertySets
, AutomationTableB
->PropertySets
, Table
->PropertyItemSize
* AutomationTableB
->PropertySetsCount
);
2275 return STATUS_SUCCESS
;
2277 else if (!AutomationTableB
)
2279 /* copy of property set */
2280 RtlMoveMemory((PVOID
)Table
->PropertySets
, AutomationTableA
->PropertySets
, Table
->PropertyItemSize
* AutomationTableA
->PropertySetsCount
);
2281 return STATUS_SUCCESS
;
2284 /* first copy all property items from dominant table */
2285 RtlMoveMemory((PVOID
)Table
->PropertySets
, AutomationTableA
->PropertySets
, Table
->PropertyItemSize
* AutomationTableA
->PropertySetsCount
);
2287 Count
= AutomationTableA
->PropertySetsCount
;
2289 /* now copy entries which arent available in the dominant table */
2290 for(Index
= 0; Index
< AutomationTableB
->PropertySetsCount
; Index
++)
2292 /* set found to false */
2295 for(SubIndex
= 0; SubIndex
< AutomationTableA
->PropertySetsCount
; SubIndex
++)
2297 if (IsEqualGUIDAligned(AutomationTableB
->PropertySets
[Index
].Set
, AutomationTableA
->PropertySets
[SubIndex
].Set
))
2299 /* same property set found */
2307 /* copy new property item set */
2308 RtlMoveMemory((PVOID
)&Table
->PropertySets
[Count
], &AutomationTableB
->PropertySets
[Index
], Table
->PropertyItemSize
);
2313 return STATUS_SUCCESS
;
2318 OUT PKSAUTOMATION_TABLE Table
,
2319 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2320 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2322 ULONG Index
, SubIndex
, Count
;
2325 if (!AutomationTableA
)
2327 /* copy of Event set */
2328 RtlMoveMemory((PVOID
)Table
->EventSets
, AutomationTableB
->EventSets
, Table
->EventItemSize
* AutomationTableB
->EventSetsCount
);
2329 return STATUS_SUCCESS
;
2331 else if (!AutomationTableB
)
2333 /* copy of Event set */
2334 RtlMoveMemory((PVOID
)Table
->EventSets
, AutomationTableA
->EventSets
, Table
->EventItemSize
* AutomationTableA
->EventSetsCount
);
2335 return STATUS_SUCCESS
;
2338 /* first copy all Event items from dominant table */
2339 RtlMoveMemory((PVOID
)Table
->EventSets
, AutomationTableA
->EventSets
, Table
->EventItemSize
* AutomationTableA
->EventSetsCount
);
2341 Count
= AutomationTableA
->EventSetsCount
;
2343 /* now copy entries which arent available in the dominant table */
2344 for(Index
= 0; Index
< AutomationTableB
->EventSetsCount
; Index
++)
2346 /* set found to false */
2349 for(SubIndex
= 0; SubIndex
< AutomationTableA
->EventSetsCount
; SubIndex
++)
2351 if (IsEqualGUIDAligned(AutomationTableB
->EventSets
[Index
].Set
, AutomationTableA
->EventSets
[SubIndex
].Set
))
2353 /* same Event set found */
2361 /* copy new Event item set */
2362 RtlMoveMemory((PVOID
)&Table
->EventSets
[Count
], &AutomationTableB
->EventSets
[Index
], Table
->EventItemSize
);
2367 return STATUS_SUCCESS
;
2376 KsMergeAutomationTables(
2377 OUT PKSAUTOMATION_TABLE
*AutomationTableAB
,
2378 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2379 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
,
2380 IN KSOBJECT_BAG Bag OPTIONAL
)
2382 PKSAUTOMATION_TABLE Table
;
2383 NTSTATUS Status
= STATUS_SUCCESS
;
2385 if (!AutomationTableA
&& !AutomationTableB
)
2387 /* nothing to merge */
2388 return STATUS_SUCCESS
;
2391 /* allocate an automation table */
2392 Table
= AllocateItem(NonPagedPool
, sizeof(KSAUTOMATION_TABLE
));
2394 return STATUS_INSUFFICIENT_RESOURCES
;
2398 /* add table to object bag */
2399 Status
= KsAddItemToObjectBag(Bag
, Table
, NULL
);
2400 /* check for success */
2401 if (!NT_SUCCESS(Status
))
2409 /* count property sets */
2410 Table
->PropertySetsCount
= KspCountPropertySets(AutomationTableA
, AutomationTableB
);
2412 if (Table
->PropertySetsCount
)
2414 if (AutomationTableA
)
2416 /* use item size from dominant automation table */
2417 Table
->PropertyItemSize
= AutomationTableA
->PropertyItemSize
;
2421 /* use item size from 2nd automation table */
2422 Table
->PropertyItemSize
= AutomationTableB
->PropertyItemSize
;
2425 /* now allocate the property sets */
2426 Table
->PropertySets
= AllocateItem(NonPagedPool
, Table
->PropertyItemSize
* Table
->PropertySetsCount
);
2428 if (!Table
->PropertySets
)
2430 /* not enough memory */
2436 /* add set to property bag */
2437 Status
= KsAddItemToObjectBag(Bag
, (PVOID
)Table
->PropertySets
, NULL
);
2438 /* check for success */
2439 if (!NT_SUCCESS(Status
))
2445 /* now copy the property sets */
2446 Status
= KspCopyPropertySets(Table
, AutomationTableA
, AutomationTableB
);
2447 if(!NT_SUCCESS(Status
))
2452 /* now count the method sets */
2453 Table
->MethodSetsCount
= KspCountMethodSets(AutomationTableA
, AutomationTableB
);
2455 if (Table
->MethodSetsCount
)
2457 if (AutomationTableA
)
2459 /* use item size from dominant automation table */
2460 Table
->MethodItemSize
= AutomationTableA
->MethodItemSize
;
2464 /* use item size from 2nd automation table */
2465 Table
->MethodItemSize
= AutomationTableB
->MethodItemSize
;
2468 /* now allocate the property sets */
2469 Table
->MethodSets
= AllocateItem(NonPagedPool
, Table
->MethodItemSize
* Table
->MethodSetsCount
);
2471 if (!Table
->MethodSets
)
2473 /* not enough memory */
2479 /* add set to property bag */
2480 Status
= KsAddItemToObjectBag(Bag
, (PVOID
)Table
->MethodSets
, NULL
);
2481 /* check for success */
2482 if (!NT_SUCCESS(Status
))
2488 /* now copy the property sets */
2489 Status
= KspCopyMethodSets(Table
, AutomationTableA
, AutomationTableB
);
2490 if(!NT_SUCCESS(Status
))
2495 /* now count the event sets */
2496 Table
->EventSetsCount
= KspCountEventSets(AutomationTableA
, AutomationTableB
);
2498 if (Table
->EventSetsCount
)
2500 if (AutomationTableA
)
2502 /* use item size from dominant automation table */
2503 Table
->EventItemSize
= AutomationTableA
->EventItemSize
;
2507 /* use item size from 2nd automation table */
2508 Table
->EventItemSize
= AutomationTableB
->EventItemSize
;
2511 /* now allocate the property sets */
2512 Table
->EventSets
= AllocateItem(NonPagedPool
, Table
->EventItemSize
* Table
->EventSetsCount
);
2514 if (!Table
->EventSets
)
2516 /* not enough memory */
2522 /* add set to property bag */
2523 Status
= KsAddItemToObjectBag(Bag
, (PVOID
)Table
->EventSets
, NULL
);
2524 /* check for success */
2525 if (!NT_SUCCESS(Status
))
2531 /* now copy the property sets */
2532 Status
= KspCopyEventSets(Table
, AutomationTableA
, AutomationTableB
);
2533 if(!NT_SUCCESS(Status
))
2538 *AutomationTableAB
= Table
;
2547 if (Table
->PropertySets
)
2549 /* clean property sets */
2550 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, (PVOID
)Table
->PropertySets
, TRUE
)))
2551 FreeItem((PVOID
)Table
->PropertySets
);
2554 if (Table
->MethodSets
)
2556 /* clean property sets */
2557 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, (PVOID
)Table
->MethodSets
, TRUE
)))
2558 FreeItem((PVOID
)Table
->MethodSets
);
2561 if (Table
->EventSets
)
2563 /* clean property sets */
2564 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, (PVOID
)Table
->EventSets
, TRUE
)))
2565 FreeItem((PVOID
)Table
->EventSets
);
2568 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, Table
, TRUE
)))
2572 return STATUS_INSUFFICIENT_RESOURCES
;
2581 KsServiceBusEnumCreateRequest(
2582 IN PDEVICE_OBJECT DeviceObject
,
2586 return STATUS_UNSUCCESSFUL
;
2596 KsServiceBusEnumPnpRequest(
2597 IN PDEVICE_OBJECT DeviceObject
,
2601 return STATUS_UNSUCCESSFUL
;
2606 KspRemoveBusInterface(
2609 PKSREMOVE_BUS_INTERFACE_CTX Context
=(PKSREMOVE_BUS_INTERFACE_CTX
)Ctx
;
2612 * get SWENUM_INSTALL_INTERFACE struct
2613 * open device key and delete the keys
2619 Context
->Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2622 /* signal completion */
2623 KeSetEvent(&Context
->Event
, IO_NO_INCREMENT
, FALSE
);
2632 KsRemoveBusEnumInterface(
2635 KPROCESSOR_MODE Mode
;
2637 KSREMOVE_BUS_INTERFACE_CTX Ctx
;
2638 WORK_QUEUE_ITEM WorkItem
;
2640 /* get previous mode */
2641 Mode
= ExGetPreviousMode();
2643 /* convert to luid */
2644 luid
= RtlConvertUlongToLuid(SE_LOAD_DRIVER_PRIVILEGE
);
2646 /* perform access check */
2647 if (!SeSinglePrivilegeCheck(luid
, Mode
))
2649 /* insufficient privileges */
2650 return STATUS_PRIVILEGE_NOT_HELD
;
2652 /* initialize event */
2653 KeInitializeEvent(&Ctx
.Event
, NotificationEvent
, FALSE
);
2655 /* store irp in ctx */
2658 /* initialize work item */
2659 ExInitializeWorkItem(&WorkItem
, KspRemoveBusInterface
, (PVOID
)&Ctx
);
2661 /* now queue the work item */
2662 ExQueueWorkItem(&WorkItem
, DelayedWorkQueue
);
2664 /* wait for completion */
2665 KeWaitForSingleObject(&Ctx
.Event
, Executive
, KernelMode
, FALSE
, NULL
);
2668 return Ctx
.Irp
->IoStatus
.Status
;
2679 KsRegisterAggregatedClientUnknown(
2681 IN PUNKNOWN ClientUnknown
)
2692 KsRegisterFilterWithNoKSPins(
2693 IN PDEVICE_OBJECT DeviceObject
,
2694 IN
const GUID
* InterfaceClassGUID
,
2696 IN BOOL
* PinDirection
,
2697 IN KSPIN_MEDIUM
* MediumList
,
2698 IN GUID
* CategoryList OPTIONAL
)
2702 PWSTR SymbolicLinkList
;
2705 UNICODE_STRING InterfaceString
;
2706 //UNICODE_STRING FilterData = RTL_CONSTANT_STRING(L"FilterData");
2708 if (!InterfaceClassGUID
|| !PinCount
|| !PinDirection
|| !MediumList
)
2710 /* all these parameters are required */
2711 return STATUS_INVALID_PARAMETER
;
2714 /* calculate filter data value size */
2715 Size
= PinCount
* sizeof(KSPIN_MEDIUM
);
2718 /* add category list */
2719 Size
+= PinCount
* sizeof(GUID
);
2722 /* FIXME generate filter data blob */
2725 /* get symbolic link list */
2726 Status
= IoGetDeviceInterfaces(InterfaceClassGUID
, DeviceObject
, DEVICE_INTERFACE_INCLUDE_NONACTIVE
, &SymbolicLinkList
);
2727 if (NT_SUCCESS(Status
))
2729 /* initialize first symbolic link */
2730 RtlInitUnicodeString(&InterfaceString
, SymbolicLinkList
);
2732 /* open first device interface registry key */
2733 Status
= IoOpenDeviceInterfaceRegistryKey(&InterfaceString
, GENERIC_WRITE
, &hKey
);
2735 if (NT_SUCCESS(Status
))
2737 /* write filter data */
2738 //Status = ZwSetValueKey(hKey, &FilterData, 0, REG_BINARY, Buffer, Size);
2746 /* update medium cache */
2747 for(Index
= 0; Index
< PinCount
; Index
++)
2749 KsCacheMedium(&InterfaceString
, &MediumList
[Index
], PinDirection
[Index
]);
2753 /* free the symbolic link list */
2754 ExFreePool(SymbolicLinkList
);