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
);
1153 /* no memory to allocate the irp */
1154 return STATUS_INSUFFICIENT_RESOURCES
;
1158 /* Store Fileobject */
1159 IoStack
= IoGetNextIrpStackLocation(Irp
);
1160 IoStack
->FileObject
= FileObject
;
1162 if (IoControl
== IOCTL_KS_WRITE_STREAM
)
1164 Irp
->AssociatedIrp
.SystemBuffer
= OutBuffer
;
1166 else if (IoControl
== IOCTL_KS_READ_STREAM
)
1168 Irp
->AssociatedIrp
.SystemBuffer
= InBuffer
;
1171 IoSetCompletionRoutine(Irp
, KspSynchronousIoControlDeviceCompletion
, (PVOID
)&IoStatusBlock
, TRUE
, TRUE
, TRUE
);
1173 Status
= IoCallDriver(DeviceObject
, Irp
);
1174 if (Status
== STATUS_PENDING
)
1176 KeWaitForSingleObject(&Event
, Executive
, RequestorMode
, FALSE
, NULL
);
1177 Status
= IoStatusBlock
.Status
;
1180 *BytesReturned
= IoStatusBlock
.Information
;
1190 KsUnserializeObjectPropertiesFromRegistry(
1191 IN PFILE_OBJECT FileObject
,
1192 IN HANDLE ParentKey OPTIONAL
,
1193 IN PUNICODE_STRING RegistryPath OPTIONAL
)
1196 return STATUS_NOT_IMPLEMENTED
;
1207 IN PUNICODE_STRING SymbolicLink
,
1208 IN PKSPIN_MEDIUM Medium
,
1209 IN ULONG PinDirection
)
1212 UNICODE_STRING Path
;
1213 UNICODE_STRING BasePath
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediumCache\\");
1214 UNICODE_STRING GuidString
;
1216 OBJECT_ATTRIBUTES ObjectAttributes
;
1217 BOOLEAN PathAdjusted
= FALSE
;
1220 /* first check if the medium is standard */
1221 if (IsEqualGUIDAligned(&KSMEDIUMSETID_Standard
, &Medium
->Set
) ||
1222 IsEqualGUIDAligned(&GUID_NULL
, &Medium
->Set
))
1224 /* no need to cache that */
1225 return STATUS_SUCCESS
;
1228 /* convert guid to string */
1229 Status
= RtlStringFromGUID(&Medium
->Set
, &GuidString
);
1230 if (!NT_SUCCESS(Status
))
1233 /* allocate path buffer */
1235 Path
.MaximumLength
= BasePath
.MaximumLength
+ GuidString
.MaximumLength
+ 10 * sizeof(WCHAR
);
1236 Path
.Buffer
= AllocateItem(PagedPool
, Path
.MaximumLength
);
1239 /* not enough resources */
1240 RtlFreeUnicodeString(&GuidString
);
1241 return STATUS_INSUFFICIENT_RESOURCES
;
1244 RtlAppendUnicodeStringToString(&Path
, &BasePath
);
1245 RtlAppendUnicodeStringToString(&Path
, &GuidString
);
1246 RtlAppendUnicodeToString(&Path
, L
"-");
1247 /* FIXME append real instance id */
1248 RtlAppendUnicodeToString(&Path
, L
"0");
1249 RtlAppendUnicodeToString(&Path
, L
"-");
1250 /* FIXME append real instance id */
1251 RtlAppendUnicodeToString(&Path
, L
"0");
1253 /* free guid string */
1254 RtlFreeUnicodeString(&GuidString
);
1256 /* initialize object attributes */
1257 InitializeObjectAttributes(&ObjectAttributes
, &Path
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1258 /* create the key */
1259 Status
= ZwCreateKey(&hKey
, GENERIC_WRITE
, &ObjectAttributes
, 0, NULL
, 0, NULL
);
1261 /* free path buffer */
1262 FreeItem(Path
.Buffer
);
1264 if (NT_SUCCESS(Status
))
1266 /* store symbolic link */
1267 if (SymbolicLink
->Buffer
[1] == L
'?' && SymbolicLink
->Buffer
[2] == L
'?')
1269 /* replace kernel path with user mode path */
1270 SymbolicLink
->Buffer
[1] = L
'\\';
1271 PathAdjusted
= TRUE
;
1275 Status
= ZwSetValueKey(hKey
, SymbolicLink
, 0, REG_DWORD
, &Value
, sizeof(ULONG
));
1279 /* restore kernel path */
1280 SymbolicLink
->Buffer
[1] = L
'?';
1296 PUNICODE_STRING RegistryPath
)
1298 return STATUS_SUCCESS
;
1305 IN PDEVICE_OBJECT DeviceObject
,
1308 PKO_OBJECT_HEADER Header
;
1309 PIO_STACK_LOCATION IoStack
;
1310 PDEVICE_EXTENSION DeviceExtension
;
1312 /* get current irp stack location */
1313 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1315 /* get ko object header */
1316 Header
= (PKO_OBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1318 /* free ks object header */
1319 KsFreeObjectHeader(Header
->ObjectHeader
);
1321 /* free ko object header */
1324 /* get device extension */
1325 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1327 /* release bus object */
1328 KsDereferenceBusObject((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
);
1330 /* complete request */
1331 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1332 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1334 return STATUS_SUCCESS
;
1339 static KSDISPATCH_TABLE KoDispatchTable
=
1341 KsDispatchInvalidDeviceRequest
,
1342 KsDispatchInvalidDeviceRequest
,
1343 KsDispatchInvalidDeviceRequest
,
1344 KsDispatchInvalidDeviceRequest
,
1346 KsDispatchQuerySecurity
,
1347 KsDispatchSetSecurity
,
1348 KsDispatchFastIoDeviceControlFailure
,
1349 KsDispatchFastReadFailure
,
1350 KsDispatchFastReadFailure
,
1357 IN PDEVICE_OBJECT DeviceObject
,
1360 PKO_OBJECT_HEADER Header
= NULL
;
1361 PIO_STACK_LOCATION IoStack
;
1362 PKO_DRIVER_EXTENSION DriverObjectExtension
;
1365 /* get current irp stack location */
1366 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1368 if (!IoStack
->FileObject
)
1370 DPRINT1("FileObject not attached!\n");
1371 Status
= STATUS_UNSUCCESSFUL
;
1375 /* get driver object extension */
1376 DriverObjectExtension
= (PKO_DRIVER_EXTENSION
)IoGetDriverObjectExtension(DeviceObject
->DriverObject
, (PVOID
)KoDriverInitialize
);
1377 if (!DriverObjectExtension
)
1379 DPRINT1("FileObject not attached!\n");
1380 Status
= STATUS_UNSUCCESSFUL
;
1384 /* allocate ko object header */
1385 Header
= (PKO_OBJECT_HEADER
)AllocateItem(NonPagedPool
, sizeof(KO_OBJECT_HEADER
));
1388 DPRINT1("failed to allocate KO_OBJECT_HEADER\n");
1389 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1393 /* initialize create item */
1394 Header
->CreateItem
.Create
= KopDispatchCreate
;
1395 RtlInitUnicodeString(&Header
->CreateItem
.ObjectClass
, KOSTRING_CreateObject
);
1398 /* now allocate the object header */
1399 Status
= KsAllocateObjectHeader(&Header
->ObjectHeader
, 1, &Header
->CreateItem
, Irp
, &KoDispatchTable
);
1400 if (!NT_SUCCESS(Status
))
1407 * extract clsid and interface id from irp
1408 * call the standard create handler
1413 IoStack
->FileObject
->FsContext2
= (PVOID
)Header
;
1415 Irp
->IoStatus
.Status
= Status
;
1416 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1422 if (Header
&& Header
->ObjectHeader
)
1423 KsFreeObjectHeader(Header
->ObjectHeader
);
1428 Irp
->IoStatus
.Status
= Status
;
1429 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1438 IN PDRIVER_OBJECT DriverObject
,
1439 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1441 NTSTATUS Status
= STATUS_DEVICE_REMOVED
;
1442 PDEVICE_OBJECT FunctionalDeviceObject
= NULL
;
1443 PDEVICE_OBJECT NextDeviceObject
;
1444 PDEVICE_EXTENSION DeviceExtension
;
1445 PKSOBJECT_CREATE_ITEM CreateItem
;
1447 /* create the device object */
1448 Status
= IoCreateDevice(DriverObject
, sizeof(DEVICE_EXTENSION
), NULL
, FILE_DEVICE_KS
, FILE_DEVICE_SECURE_OPEN
, FALSE
, &FunctionalDeviceObject
);
1449 if (!NT_SUCCESS(Status
))
1452 /* allocate the create item */
1453 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
));
1457 /* not enough memory */
1458 IoDeleteDevice(FunctionalDeviceObject
);
1459 return STATUS_INSUFFICIENT_RESOURCES
;
1462 /* initialize create item */
1463 CreateItem
->Create
= KopDispatchCreate
;
1464 RtlInitUnicodeString(&CreateItem
->ObjectClass
, KOSTRING_CreateObject
);
1466 /* get device extension */
1467 DeviceExtension
= (PDEVICE_EXTENSION
)FunctionalDeviceObject
->DeviceExtension
;
1469 /* now allocate the device header */
1470 Status
= KsAllocateDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
, 1, CreateItem
);
1471 if (!NT_SUCCESS(Status
))
1474 IoDeleteDevice(FunctionalDeviceObject
);
1475 FreeItem(CreateItem
);
1479 /* now attach to device stack */
1480 NextDeviceObject
= IoAttachDeviceToDeviceStack(FunctionalDeviceObject
, PhysicalDeviceObject
);
1481 if (NextDeviceObject
)
1483 /* store pnp base object */
1484 KsSetDevicePnpAndBaseObject((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, NextDeviceObject
, FunctionalDeviceObject
);
1485 /* set device flags */
1486 FunctionalDeviceObject
->Flags
|= DO_DIRECT_IO
| DO_POWER_PAGABLE
;
1487 FunctionalDeviceObject
->Flags
&= ~ DO_DEVICE_INITIALIZING
;
1492 KsFreeDeviceHeader((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
);
1493 FreeItem(CreateItem
);
1494 IoDeleteDevice(FunctionalDeviceObject
);
1495 Status
= STATUS_DEVICE_REMOVED
;
1510 IN PDEVICE_OBJECT DeviceObject
)
1512 PDEVICE_EXTENSION DeviceExtension
;
1514 /* get device extension */
1515 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1517 return KsAddObjectCreateItemToDeviceHeader((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, KopDispatchCreate
, NULL
, KOSTRING_CreateObject
, NULL
);
1527 IN PDRIVER_OBJECT DriverObject
,
1528 IN PUNICODE_STRING RegistryPathName
,
1529 IN KoCreateObjectHandler CreateObjectHandler
)
1531 PKO_DRIVER_EXTENSION DriverObjectExtension
;
1534 /* allocate driver object extension */
1535 Status
= IoAllocateDriverObjectExtension(DriverObject
, (PVOID
)KoDriverInitialize
, sizeof(KO_DRIVER_EXTENSION
), (PVOID
*)&DriverObjectExtension
);
1538 if (NT_SUCCESS(Status
))
1540 /* store create handler */
1541 DriverObjectExtension
->CreateObjectHandler
= CreateObjectHandler
;
1543 /* Setting our IRP handlers */
1544 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = KsDefaultDispatchPnp
;
1545 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = KsDefaultDispatchPower
;
1546 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = KsDefaultForwardIrp
;
1548 /* The driver unload routine */
1549 DriverObject
->DriverUnload
= KsNullDriverUnload
;
1551 /* The driver-supplied AddDevice */
1552 DriverObject
->DriverExtension
->AddDevice
= KopAddDevice
;
1554 /* KS handles these */
1555 DPRINT1("Setting KS function handlers\n");
1556 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_CREATE
);
1557 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_CLOSE
);
1558 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_DEVICE_CONTROL
);
1572 IN REFCLSID ClassId
)
1586 PKSBASIC_HEADER BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
1589 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
1591 KeWaitForSingleObject(&BasicHeader
->ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1603 PKSBASIC_HEADER BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
1606 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
1608 KeReleaseMutex(&BasicHeader
->ControlMutex
, FALSE
);
1620 IN PKSDEVICE Device
)
1622 IKsDevice
*KsDevice
;
1623 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(Device
, KSIDEVICE_HEADER
, KsDevice
);
1625 /* get device interface*/
1626 KsDevice
= (IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
;
1628 /* acquire device mutex */
1629 KsDevice
->lpVtbl
->AcquireDevice(KsDevice
);
1638 IN PKSDEVICE Device
)
1640 IKsDevice
*KsDevice
;
1641 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(Device
, KSIDEVICE_HEADER
, KsDevice
);
1643 /* get device interface*/
1644 KsDevice
= (IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
;
1646 /* release device mutex */
1647 KsDevice
->lpVtbl
->ReleaseDevice(KsDevice
);
1657 IN PDEVICE_OBJECT DeviceObject
)
1659 IKsDevice
*KsDevice
;
1660 PKSIDEVICE_HEADER DeviceHeader
;
1661 PDEVICE_EXTENSION DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1663 /* get device header */
1664 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1666 /* get device interface*/
1667 KsDevice
= (IKsDevice
*)&DeviceHeader
->lpVtblIKsDevice
;
1669 /* now free device header */
1670 KsFreeDeviceHeader((KSDEVICE_HEADER
)DeviceHeader
);
1672 /* release interface when available */
1675 /* delete IKsDevice interface */
1676 KsDevice
->lpVtbl
->Release(KsDevice
);
1686 KsCompletePendingRequest(
1689 PIO_STACK_LOCATION IoStack
;
1691 /* get current irp stack location */
1692 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1695 ASSERT(Irp
->IoStatus
.Status
!= STATUS_PENDING
);
1697 if (IoStack
->MajorFunction
!= IRP_MJ_CLOSE
)
1699 /* can be completed immediately */
1700 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1704 /* did close operation fail */
1705 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
1707 /* closing failed, complete irp */
1708 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1713 * delete object / device header
1714 * remove dead pin / filter instance
1726 KsCreateBusEnumObject(
1727 IN PWCHAR BusIdentifier
,
1728 IN PDEVICE_OBJECT BusDeviceObject
,
1729 IN PDEVICE_OBJECT PhysicalDeviceObject
,
1730 IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL
,
1731 IN REFGUID InterfaceGuid OPTIONAL
,
1732 IN PWCHAR ServiceRelativePath OPTIONAL
)
1735 NTSTATUS Status
= STATUS_SUCCESS
;
1736 UNICODE_STRING ServiceKeyPath
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
1737 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension
;
1738 PDEVICE_EXTENSION DeviceExtension
;
1740 /* calculate sizeof bus enum device extension */
1741 Length
= wcslen(BusIdentifier
) * sizeof(WCHAR
);
1742 Length
+= sizeof(BUS_ENUM_DEVICE_EXTENSION
);
1744 BusDeviceExtension
= ExAllocatePool(NonPagedPool
, Length
);
1745 if (!BusDeviceExtension
)
1747 /* not enough memory */
1748 return STATUS_INSUFFICIENT_RESOURCES
;
1751 /* zero device extension */
1752 RtlZeroMemory(BusDeviceExtension
, sizeof(BUS_ENUM_DEVICE_EXTENSION
));
1754 /* initialize bus device extension */
1755 wcscpy(BusDeviceExtension
->BusIdentifier
, BusIdentifier
);
1757 /* allocate service path string */
1758 Length
= ServiceKeyPath
.MaximumLength
;
1759 Length
+= BusDeviceObject
->DriverObject
->DriverExtension
->ServiceKeyName
.MaximumLength
;
1761 if (ServiceRelativePath
)
1763 /* relative path for devices */
1764 Length
+= wcslen(ServiceRelativePath
) + 2 * sizeof(WCHAR
);
1767 BusDeviceExtension
->ServicePath
.Length
= 0;
1768 BusDeviceExtension
->ServicePath
.MaximumLength
= Length
;
1769 BusDeviceExtension
->ServicePath
.Buffer
= ExAllocatePool(NonPagedPool
, Length
);
1771 if (!BusDeviceExtension
->ServicePath
.Buffer
)
1773 /* not enough memory */
1774 ExFreePool(BusDeviceExtension
);
1775 return STATUS_INSUFFICIENT_RESOURCES
;
1778 RtlAppendUnicodeStringToString(&BusDeviceExtension
->ServicePath
, &ServiceKeyPath
);
1779 RtlAppendUnicodeStringToString(&BusDeviceExtension
->ServicePath
, &BusDeviceObject
->DriverObject
->DriverExtension
->ServiceKeyName
);
1781 if (ServiceRelativePath
)
1783 RtlAppendUnicodeToString(&BusDeviceExtension
->ServicePath
, L
"\\");
1784 RtlAppendUnicodeToString(&BusDeviceExtension
->ServicePath
, ServiceRelativePath
);
1789 /* register an device interface */
1790 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
, InterfaceGuid
, NULL
, &BusDeviceExtension
->SymbolicLinkName
);
1792 /* check for success */
1793 if (!NT_SUCCESS(Status
))
1795 ExFreePool(BusDeviceExtension
->ServicePath
.Buffer
);
1796 ExFreePool(BusDeviceExtension
);
1800 /* now enable device interface */
1801 Status
= IoSetDeviceInterfaceState(&BusDeviceExtension
->SymbolicLinkName
, TRUE
);
1803 if (!NT_SUCCESS(Status
))
1805 ExFreePool(BusDeviceExtension
->ServicePath
.Buffer
);
1806 ExFreePool(BusDeviceExtension
);
1810 /* set state enabled */
1811 BusDeviceExtension
->Enabled
= TRUE
;
1814 /* store device objects */
1815 BusDeviceExtension
->BusDeviceObject
= BusDeviceObject
;
1816 BusDeviceExtension
->PnpDeviceObject
= PnpDeviceObject
;
1817 BusDeviceExtension
->PhysicalDeviceObject
= PhysicalDeviceObject
;
1819 if (!PnpDeviceObject
)
1821 BusDeviceExtension
->PnpDeviceObject
= IoAttachDeviceToDeviceStack(BusDeviceObject
, PhysicalDeviceObject
);
1823 if (!BusDeviceExtension
->PnpDeviceObject
)
1825 /* failed to attach device */
1826 if (BusDeviceExtension
->Enabled
)
1828 IoSetDeviceInterfaceState(&BusDeviceExtension
->SymbolicLinkName
, FALSE
);
1829 RtlFreeUnicodeString(&BusDeviceExtension
->SymbolicLinkName
);
1832 /* free device extension */
1833 ExFreePool(BusDeviceExtension
->ServicePath
.Buffer
);
1834 ExFreePool(BusDeviceExtension
);
1836 return STATUS_DEVICE_REMOVED
;
1840 /* attach device extension */
1841 DeviceExtension
= (PDEVICE_EXTENSION
)BusDeviceObject
->DeviceExtension
;
1842 DeviceExtension
->DeviceHeader
= (PKSIDEVICE_HEADER
)BusDeviceExtension
;
1844 /* FIXME scan bus and invalidate device relations */
1850 KspSetGetBusDataCompletion(
1851 IN PDEVICE_OBJECT DeviceObject
,
1855 /* signal completion */
1856 KeSetEvent((PRKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
1858 /* more work needs be done, so dont free the irp */
1859 return STATUS_MORE_PROCESSING_REQUIRED
;
1864 KspDeviceSetGetBusData(
1865 IN PDEVICE_OBJECT DeviceObject
,
1872 PIO_STACK_LOCATION IoStack
;
1877 /* allocate the irp */
1878 Irp
= IoAllocateIrp(1, /*FIXME */
1882 return STATUS_INSUFFICIENT_RESOURCES
;
1884 /* initialize the event */
1885 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1887 /* get next stack location */
1888 IoStack
= IoGetNextIrpStackLocation(Irp
);
1890 /* setup a completion routine */
1891 IoSetCompletionRoutine(Irp
, KspSetGetBusDataCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
1893 /* setup parameters */
1894 IoStack
->Parameters
.ReadWriteConfig
.Buffer
= Buffer
;
1895 IoStack
->Parameters
.ReadWriteConfig
.Length
= Length
;
1896 IoStack
->Parameters
.ReadWriteConfig
.Offset
= Offset
;
1897 IoStack
->Parameters
.ReadWriteConfig
.WhichSpace
= DataType
;
1898 /* setup function code */
1899 IoStack
->MajorFunction
= IRP_MJ_PNP
;
1900 IoStack
->MinorFunction
= (bGet
? IRP_MN_READ_CONFIG
: IRP_MN_WRITE_CONFIG
);
1902 /* lets call the driver */
1903 Status
= IoCallDriver(DeviceObject
, Irp
);
1905 /* is the request still pending */
1906 if (Status
== STATUS_PENDING
)
1909 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1911 Status
= Irp
->IoStatus
.Status
;
1927 IN PKSDEVICE Device
,
1933 return KspDeviceSetGetBusData(Device
->PhysicalDeviceObject
, /* is this right? */
1934 DataType
, Buffer
, Offset
, Length
, FALSE
);
1945 IN PKSDEVICE Device
,
1951 return KspDeviceSetGetBusData(Device
->PhysicalDeviceObject
, /* is this right? */
1952 DataType
, Buffer
, Offset
, Length
, TRUE
);
1962 KsDeviceRegisterAdapterObject(
1963 IN PKSDEVICE Device
,
1964 IN PADAPTER_OBJECT AdapterObject
,
1965 IN ULONG MaxMappingsByteCount
,
1966 IN ULONG MappingTableStride
)
1977 KsGetBusEnumIdentifier(
1981 return STATUS_UNSUCCESSFUL
;
1990 KsGetBusEnumParentFDOFromChildPDO(
1991 IN PDEVICE_OBJECT DeviceObject
,
1992 OUT PDEVICE_OBJECT
*FunctionalDeviceObject
)
1995 return STATUS_UNSUCCESSFUL
;
2004 KsGetBusEnumPnpDeviceObject(
2005 IN PDEVICE_OBJECT DeviceObject
,
2006 IN PDEVICE_OBJECT
*PnpDeviceObject
)
2009 return STATUS_UNSUCCESSFUL
;
2021 PKSBASIC_HEADER BasicHeader
;
2023 /* get the basic header */
2024 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
2026 /* type has to be either a device or a filter factory */
2027 ASSERT(BasicHeader
->Type
== KsObjectTypeDevice
|| BasicHeader
->Type
== KsObjectTypeFilterFactory
);
2029 return (PVOID
)BasicHeader
->FirstChild
.Filter
;
2041 PKSBASIC_HEADER BasicHeader
;
2043 /* get the basic header */
2044 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
2046 ASSERT(BasicHeader
->Type
== KsObjectTypeDevice
|| BasicHeader
->Type
== KsObjectTypeFilterFactory
||
2047 BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
2049 return (PVOID
)BasicHeader
->Next
.Pin
;
2058 KsInstallBusEnumInterface(
2062 return STATUS_UNSUCCESSFUL
;
2071 KsIsBusEnumChildDevice(
2072 IN PDEVICE_OBJECT DeviceObject
,
2073 OUT PBOOLEAN ChildDevice
)
2076 return STATUS_UNSUCCESSFUL
;
2081 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2082 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2084 ULONG Index
, SubIndex
, Count
;
2087 if (!AutomationTableA
)
2088 return AutomationTableB
->MethodSetsCount
;
2090 if (!AutomationTableB
)
2091 return AutomationTableA
->MethodSetsCount
;
2094 ASSERT(AutomationTableA
->MethodItemSize
== AutomationTableB
->MethodItemSize
);
2096 /* now iterate all property sets and compare their guids */
2097 Count
= AutomationTableA
->MethodSetsCount
;
2099 for(Index
= 0; Index
< AutomationTableB
->MethodSetsCount
; Index
++)
2101 /* set found to false */
2104 for(SubIndex
= 0; SubIndex
< AutomationTableA
->MethodSetsCount
; SubIndex
++)
2106 if (IsEqualGUIDAligned(AutomationTableB
->MethodSets
[Index
].Set
, AutomationTableA
->MethodSets
[SubIndex
].Set
))
2108 /* same property set found */
2123 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2124 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2126 ULONG Index
, SubIndex
, Count
;
2129 if (!AutomationTableA
)
2130 return AutomationTableB
->EventSetsCount
;
2132 if (!AutomationTableB
)
2133 return AutomationTableA
->EventSetsCount
;
2136 ASSERT(AutomationTableA
->EventItemSize
== AutomationTableB
->EventItemSize
);
2138 /* now iterate all Event sets and compare their guids */
2139 Count
= AutomationTableA
->EventSetsCount
;
2141 for(Index
= 0; Index
< AutomationTableB
->EventSetsCount
; Index
++)
2143 /* set found to false */
2146 for(SubIndex
= 0; SubIndex
< AutomationTableA
->EventSetsCount
; SubIndex
++)
2148 if (IsEqualGUIDAligned(AutomationTableB
->EventSets
[Index
].Set
, AutomationTableA
->EventSets
[SubIndex
].Set
))
2150 /* same Event set found */
2165 KspCountPropertySets(
2166 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2167 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2169 ULONG Index
, SubIndex
, Count
;
2172 if (!AutomationTableA
)
2173 return AutomationTableB
->PropertySetsCount
;
2175 if (!AutomationTableB
)
2176 return AutomationTableA
->PropertySetsCount
;
2179 ASSERT(AutomationTableA
->PropertyItemSize
== AutomationTableB
->PropertyItemSize
);
2181 /* now iterate all property sets and compare their guids */
2182 Count
= AutomationTableA
->PropertySetsCount
;
2184 for(Index
= 0; Index
< AutomationTableB
->PropertySetsCount
; Index
++)
2186 /* set found to false */
2189 for(SubIndex
= 0; SubIndex
< AutomationTableA
->PropertySetsCount
; SubIndex
++)
2191 if (IsEqualGUIDAligned(AutomationTableB
->PropertySets
[Index
].Set
, AutomationTableA
->PropertySets
[SubIndex
].Set
))
2193 /* same property set found */
2208 OUT PKSAUTOMATION_TABLE Table
,
2209 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2210 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2212 ULONG Index
, SubIndex
, Count
;
2215 if (!AutomationTableA
)
2217 /* copy of property set */
2218 RtlMoveMemory((PVOID
)Table
->MethodSets
, AutomationTableB
->MethodSets
, Table
->MethodItemSize
* AutomationTableB
->MethodSetsCount
);
2219 return STATUS_SUCCESS
;
2221 else if (!AutomationTableB
)
2223 /* copy of property set */
2224 RtlMoveMemory((PVOID
)Table
->MethodSets
, AutomationTableA
->MethodSets
, Table
->MethodItemSize
* AutomationTableA
->MethodSetsCount
);
2225 return STATUS_SUCCESS
;
2228 /* first copy all property items from dominant table */
2229 RtlMoveMemory((PVOID
)Table
->MethodSets
, AutomationTableA
->MethodSets
, Table
->MethodItemSize
* AutomationTableA
->MethodSetsCount
);
2231 Count
= AutomationTableA
->MethodSetsCount
;
2233 /* now copy entries which arent available in the dominant table */
2234 for(Index
= 0; Index
< AutomationTableB
->MethodSetsCount
; Index
++)
2236 /* set found to false */
2239 for(SubIndex
= 0; SubIndex
< AutomationTableA
->MethodSetsCount
; SubIndex
++)
2241 if (IsEqualGUIDAligned(AutomationTableB
->MethodSets
[Index
].Set
, AutomationTableA
->MethodSets
[SubIndex
].Set
))
2243 /* same property set found */
2251 /* copy new property item set */
2252 RtlMoveMemory((PVOID
)&Table
->MethodSets
[Count
], &AutomationTableB
->MethodSets
[Index
], Table
->MethodItemSize
);
2257 return STATUS_SUCCESS
;
2262 KspCopyPropertySets(
2263 OUT PKSAUTOMATION_TABLE Table
,
2264 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2265 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2267 ULONG Index
, SubIndex
, Count
;
2270 if (!AutomationTableA
)
2272 /* copy of property set */
2273 RtlMoveMemory((PVOID
)Table
->PropertySets
, AutomationTableB
->PropertySets
, Table
->PropertyItemSize
* AutomationTableB
->PropertySetsCount
);
2274 return STATUS_SUCCESS
;
2276 else if (!AutomationTableB
)
2278 /* copy of property set */
2279 RtlMoveMemory((PVOID
)Table
->PropertySets
, AutomationTableA
->PropertySets
, Table
->PropertyItemSize
* AutomationTableA
->PropertySetsCount
);
2280 return STATUS_SUCCESS
;
2283 /* first copy all property items from dominant table */
2284 RtlMoveMemory((PVOID
)Table
->PropertySets
, AutomationTableA
->PropertySets
, Table
->PropertyItemSize
* AutomationTableA
->PropertySetsCount
);
2286 Count
= AutomationTableA
->PropertySetsCount
;
2288 /* now copy entries which arent available in the dominant table */
2289 for(Index
= 0; Index
< AutomationTableB
->PropertySetsCount
; Index
++)
2291 /* set found to false */
2294 for(SubIndex
= 0; SubIndex
< AutomationTableA
->PropertySetsCount
; SubIndex
++)
2296 if (IsEqualGUIDAligned(AutomationTableB
->PropertySets
[Index
].Set
, AutomationTableA
->PropertySets
[SubIndex
].Set
))
2298 /* same property set found */
2306 /* copy new property item set */
2307 RtlMoveMemory((PVOID
)&Table
->PropertySets
[Count
], &AutomationTableB
->PropertySets
[Index
], Table
->PropertyItemSize
);
2312 return STATUS_SUCCESS
;
2317 OUT PKSAUTOMATION_TABLE Table
,
2318 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2319 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2321 ULONG Index
, SubIndex
, Count
;
2324 if (!AutomationTableA
)
2326 /* copy of Event set */
2327 RtlMoveMemory((PVOID
)Table
->EventSets
, AutomationTableB
->EventSets
, Table
->EventItemSize
* AutomationTableB
->EventSetsCount
);
2328 return STATUS_SUCCESS
;
2330 else if (!AutomationTableB
)
2332 /* copy of Event set */
2333 RtlMoveMemory((PVOID
)Table
->EventSets
, AutomationTableA
->EventSets
, Table
->EventItemSize
* AutomationTableA
->EventSetsCount
);
2334 return STATUS_SUCCESS
;
2337 /* first copy all Event items from dominant table */
2338 RtlMoveMemory((PVOID
)Table
->EventSets
, AutomationTableA
->EventSets
, Table
->EventItemSize
* AutomationTableA
->EventSetsCount
);
2340 Count
= AutomationTableA
->EventSetsCount
;
2342 /* now copy entries which arent available in the dominant table */
2343 for(Index
= 0; Index
< AutomationTableB
->EventSetsCount
; Index
++)
2345 /* set found to false */
2348 for(SubIndex
= 0; SubIndex
< AutomationTableA
->EventSetsCount
; SubIndex
++)
2350 if (IsEqualGUIDAligned(AutomationTableB
->EventSets
[Index
].Set
, AutomationTableA
->EventSets
[SubIndex
].Set
))
2352 /* same Event set found */
2360 /* copy new Event item set */
2361 RtlMoveMemory((PVOID
)&Table
->EventSets
[Count
], &AutomationTableB
->EventSets
[Index
], Table
->EventItemSize
);
2366 return STATUS_SUCCESS
;
2375 KsMergeAutomationTables(
2376 OUT PKSAUTOMATION_TABLE
*AutomationTableAB
,
2377 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2378 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
,
2379 IN KSOBJECT_BAG Bag OPTIONAL
)
2381 PKSAUTOMATION_TABLE Table
;
2382 NTSTATUS Status
= STATUS_SUCCESS
;
2384 if (!AutomationTableA
&& !AutomationTableB
)
2386 /* nothing to merge */
2387 return STATUS_SUCCESS
;
2390 /* allocate an automation table */
2391 Table
= AllocateItem(NonPagedPool
, sizeof(KSAUTOMATION_TABLE
));
2393 return STATUS_INSUFFICIENT_RESOURCES
;
2397 /* add table to object bag */
2398 Status
= KsAddItemToObjectBag(Bag
, Table
, NULL
);
2399 /* check for success */
2400 if (!NT_SUCCESS(Status
))
2408 /* count property sets */
2409 Table
->PropertySetsCount
= KspCountPropertySets(AutomationTableA
, AutomationTableB
);
2411 if (Table
->PropertySetsCount
)
2413 if (AutomationTableA
)
2415 /* use item size from dominant automation table */
2416 Table
->PropertyItemSize
= AutomationTableA
->PropertyItemSize
;
2420 /* use item size from 2nd automation table */
2421 Table
->PropertyItemSize
= AutomationTableB
->PropertyItemSize
;
2424 /* now allocate the property sets */
2425 Table
->PropertySets
= AllocateItem(NonPagedPool
, Table
->PropertyItemSize
* Table
->PropertySetsCount
);
2427 if (!Table
->PropertySets
)
2429 /* not enough memory */
2435 /* add set to property bag */
2436 Status
= KsAddItemToObjectBag(Bag
, (PVOID
)Table
->PropertySets
, NULL
);
2437 /* check for success */
2438 if (!NT_SUCCESS(Status
))
2444 /* now copy the property sets */
2445 Status
= KspCopyPropertySets(Table
, AutomationTableA
, AutomationTableB
);
2446 if(!NT_SUCCESS(Status
))
2451 /* now count the method sets */
2452 Table
->MethodSetsCount
= KspCountMethodSets(AutomationTableA
, AutomationTableB
);
2454 if (Table
->MethodSetsCount
)
2456 if (AutomationTableA
)
2458 /* use item size from dominant automation table */
2459 Table
->MethodItemSize
= AutomationTableA
->MethodItemSize
;
2463 /* use item size from 2nd automation table */
2464 Table
->MethodItemSize
= AutomationTableB
->MethodItemSize
;
2467 /* now allocate the property sets */
2468 Table
->MethodSets
= AllocateItem(NonPagedPool
, Table
->MethodItemSize
* Table
->MethodSetsCount
);
2470 if (!Table
->MethodSets
)
2472 /* not enough memory */
2478 /* add set to property bag */
2479 Status
= KsAddItemToObjectBag(Bag
, (PVOID
)Table
->MethodSets
, NULL
);
2480 /* check for success */
2481 if (!NT_SUCCESS(Status
))
2487 /* now copy the property sets */
2488 Status
= KspCopyMethodSets(Table
, AutomationTableA
, AutomationTableB
);
2489 if(!NT_SUCCESS(Status
))
2494 /* now count the event sets */
2495 Table
->EventSetsCount
= KspCountEventSets(AutomationTableA
, AutomationTableB
);
2497 if (Table
->EventSetsCount
)
2499 if (AutomationTableA
)
2501 /* use item size from dominant automation table */
2502 Table
->EventItemSize
= AutomationTableA
->EventItemSize
;
2506 /* use item size from 2nd automation table */
2507 Table
->EventItemSize
= AutomationTableB
->EventItemSize
;
2510 /* now allocate the property sets */
2511 Table
->EventSets
= AllocateItem(NonPagedPool
, Table
->EventItemSize
* Table
->EventSetsCount
);
2513 if (!Table
->EventSets
)
2515 /* not enough memory */
2521 /* add set to property bag */
2522 Status
= KsAddItemToObjectBag(Bag
, (PVOID
)Table
->EventSets
, NULL
);
2523 /* check for success */
2524 if (!NT_SUCCESS(Status
))
2530 /* now copy the property sets */
2531 Status
= KspCopyEventSets(Table
, AutomationTableA
, AutomationTableB
);
2532 if(!NT_SUCCESS(Status
))
2537 *AutomationTableAB
= Table
;
2546 if (Table
->PropertySets
)
2548 /* clean property sets */
2549 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, (PVOID
)Table
->PropertySets
, TRUE
)))
2550 FreeItem((PVOID
)Table
->PropertySets
);
2553 if (Table
->MethodSets
)
2555 /* clean property sets */
2556 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, (PVOID
)Table
->MethodSets
, TRUE
)))
2557 FreeItem((PVOID
)Table
->MethodSets
);
2560 if (Table
->EventSets
)
2562 /* clean property sets */
2563 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, (PVOID
)Table
->EventSets
, TRUE
)))
2564 FreeItem((PVOID
)Table
->EventSets
);
2567 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, Table
, TRUE
)))
2571 return STATUS_INSUFFICIENT_RESOURCES
;
2580 KsServiceBusEnumCreateRequest(
2581 IN PDEVICE_OBJECT DeviceObject
,
2585 return STATUS_UNSUCCESSFUL
;
2595 KsServiceBusEnumPnpRequest(
2596 IN PDEVICE_OBJECT DeviceObject
,
2600 return STATUS_UNSUCCESSFUL
;
2605 KspRemoveBusInterface(
2608 PKSREMOVE_BUS_INTERFACE_CTX Context
=(PKSREMOVE_BUS_INTERFACE_CTX
)Ctx
;
2611 * get SWENUM_INSTALL_INTERFACE struct
2612 * open device key and delete the keys
2618 Context
->Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2621 /* signal completion */
2622 KeSetEvent(&Context
->Event
, IO_NO_INCREMENT
, FALSE
);
2631 KsRemoveBusEnumInterface(
2634 KPROCESSOR_MODE Mode
;
2636 KSREMOVE_BUS_INTERFACE_CTX Ctx
;
2637 WORK_QUEUE_ITEM WorkItem
;
2639 /* get previous mode */
2640 Mode
= ExGetPreviousMode();
2642 /* convert to luid */
2643 luid
= RtlConvertUlongToLuid(SE_LOAD_DRIVER_PRIVILEGE
);
2645 /* perform access check */
2646 if (!SeSinglePrivilegeCheck(luid
, Mode
))
2648 /* insufficient privileges */
2649 return STATUS_PRIVILEGE_NOT_HELD
;
2651 /* initialize event */
2652 KeInitializeEvent(&Ctx
.Event
, NotificationEvent
, FALSE
);
2654 /* store irp in ctx */
2657 /* initialize work item */
2658 ExInitializeWorkItem(&WorkItem
, KspRemoveBusInterface
, (PVOID
)&Ctx
);
2660 /* now queue the work item */
2661 ExQueueWorkItem(&WorkItem
, DelayedWorkQueue
);
2663 /* wait for completion */
2664 KeWaitForSingleObject(&Ctx
.Event
, Executive
, KernelMode
, FALSE
, NULL
);
2667 return Ctx
.Irp
->IoStatus
.Status
;
2678 KsRegisterAggregatedClientUnknown(
2680 IN PUNKNOWN ClientUnknown
)
2691 KsRegisterFilterWithNoKSPins(
2692 IN PDEVICE_OBJECT DeviceObject
,
2693 IN
const GUID
* InterfaceClassGUID
,
2695 IN BOOL
* PinDirection
,
2696 IN KSPIN_MEDIUM
* MediumList
,
2697 IN GUID
* CategoryList OPTIONAL
)
2701 PWSTR SymbolicLinkList
;
2704 UNICODE_STRING InterfaceString
;
2705 //UNICODE_STRING FilterData = RTL_CONSTANT_STRING(L"FilterData");
2707 if (!InterfaceClassGUID
|| !PinCount
|| !PinDirection
|| !MediumList
)
2709 /* all these parameters are required */
2710 return STATUS_INVALID_PARAMETER
;
2713 /* calculate filter data value size */
2714 Size
= PinCount
* sizeof(KSPIN_MEDIUM
);
2717 /* add category list */
2718 Size
+= PinCount
* sizeof(GUID
);
2721 /* FIXME generate filter data blob */
2724 /* get symbolic link list */
2725 Status
= IoGetDeviceInterfaces(InterfaceClassGUID
, DeviceObject
, DEVICE_INTERFACE_INCLUDE_NONACTIVE
, &SymbolicLinkList
);
2726 if (NT_SUCCESS(Status
))
2728 /* initialize first symbolic link */
2729 RtlInitUnicodeString(&InterfaceString
, SymbolicLinkList
);
2731 /* open first device interface registry key */
2732 Status
= IoOpenDeviceInterfaceRegistryKey(&InterfaceString
, GENERIC_WRITE
, &hKey
);
2734 if (NT_SUCCESS(Status
))
2736 /* write filter data */
2737 //Status = ZwSetValueKey(hKey, &FilterData, 0, REG_BINARY, Buffer, Size);
2745 /* update medium cache */
2746 for(Index
= 0; Index
< PinCount
; Index
++)
2748 KsCacheMedium(&InterfaceString
, &MediumList
[Index
], PinDirection
[Index
]);
2752 /* free the symbolic link list */
2753 ExFreePool(SymbolicLinkList
);