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 DPRINT("KsReleaseDevice\n");
99 ExReleaseResourceLite(&Header
->SecurityLock
);
100 KeLeaveCriticalRegion();
109 KsDefaultDispatchPnp(
110 IN PDEVICE_OBJECT DeviceObject
,
113 PDEVICE_EXTENSION DeviceExtension
;
114 PKSIDEVICE_HEADER DeviceHeader
;
115 PIO_STACK_LOCATION IoStack
;
116 PDEVICE_OBJECT PnpDeviceObject
;
120 /* get current irp stack */
121 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
123 /* caller wants to add the target device */
124 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
126 /* get device header */
127 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
129 /* backup PnpBaseObject */
130 PnpDeviceObject
= DeviceHeader
->PnpDeviceObject
;
133 /* backup minor function code */
134 MinorFunction
= IoStack
->MinorFunction
;
136 if(MinorFunction
== IRP_MN_REMOVE_DEVICE
)
138 /* remove the device */
139 KsFreeDeviceHeader((KSDEVICE_HEADER
)DeviceHeader
);
142 /* skip current irp stack */
143 IoSkipCurrentIrpStackLocation(Irp
);
145 /* call attached pnp device object */
146 Status
= IoCallDriver(PnpDeviceObject
, Irp
);
148 if (MinorFunction
== IRP_MN_REMOVE_DEVICE
)
151 IoDetachDevice(PnpDeviceObject
);
153 IoDeleteDevice(DeviceObject
);
165 KsDefaultDispatchPower(
166 IN PDEVICE_OBJECT DeviceObject
,
169 PDEVICE_EXTENSION DeviceExtension
;
170 PKSIDEVICE_HEADER DeviceHeader
;
171 PKSIOBJECT_HEADER ObjectHeader
;
172 PIO_STACK_LOCATION IoStack
;
173 PLIST_ENTRY ListEntry
;
176 /* get current irp stack */
177 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
179 /* caller wants to add the target device */
180 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
182 /* get device header */
183 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
187 /* loop our power dispatch list and call registered notification functions */
188 ListEntry
= DeviceHeader
->PowerDispatchList
.Flink
;
190 while(ListEntry
!= &DeviceHeader
->PowerDispatchList
)
192 /* get object header */
193 ObjectHeader
= (PKSIOBJECT_HEADER
)CONTAINING_RECORD(ListEntry
, KSIOBJECT_HEADER
, PowerDispatchEntry
);
195 /* does it have still a cb */
196 if (ObjectHeader
->PowerDispatch
)
198 /* call the power cb */
199 Status
= ObjectHeader
->PowerDispatch(ObjectHeader
->PowerContext
, Irp
);
200 ASSERT(NT_SUCCESS(Status
));
203 /* iterate to next entry */
204 ListEntry
= ListEntry
->Flink
;
207 /* start next power irp */
208 PoStartNextPowerIrp(Irp
);
210 /* skip current irp stack location */
211 IoSkipCurrentIrpStackLocation(Irp
);
214 Status
= PoCallDriver(DeviceHeader
->PnpDeviceObject
, Irp
);
227 IN PDEVICE_OBJECT DeviceObject
,
230 PDEVICE_EXTENSION DeviceExtension
;
231 PKSIDEVICE_HEADER DeviceHeader
;
232 PIO_STACK_LOCATION IoStack
;
235 /* get current irp stack */
236 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
238 /* caller wants to add the target device */
239 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
241 /* get device header */
242 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
244 /* forward the request to the PDO */
245 Status
= IoCallDriver(DeviceHeader
->PnpDeviceObject
, Irp
);
256 KsSetDevicePnpAndBaseObject(
257 IN KSDEVICE_HEADER Header
,
258 IN PDEVICE_OBJECT PnpDeviceObject
,
259 IN PDEVICE_OBJECT BaseDevice
)
261 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
263 DeviceHeader
->PnpDeviceObject
= PnpDeviceObject
;
264 DeviceHeader
->BaseDevice
= BaseDevice
;
273 KsQueryDevicePnpObject(
274 IN KSDEVICE_HEADER Header
)
276 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
278 /* return PnpDeviceObject */
279 return DeviceHeader
->PnpDeviceObject
;
289 KsQueryObjectAccessMask(
290 IN KSOBJECT_HEADER Header
)
292 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
)Header
;
294 /* return access mask */
295 return ObjectHeader
->AccessMask
;
305 KsRecalculateStackDepth(
306 IN KSDEVICE_HEADER Header
,
307 IN BOOLEAN ReuseStackLocation
)
320 IN KSOBJECT_HEADER Header
,
321 IN KSTARGET_STATE TargetState
)
323 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)Header
;
325 /* set target state */
326 DeviceHeader
->TargetState
= TargetState
;
335 KsSetTargetDeviceObject(
336 IN KSOBJECT_HEADER Header
,
337 IN PDEVICE_OBJECT TargetDevice OPTIONAL
)
339 PDEVICE_EXTENSION DeviceExtension
;
340 PKSIDEVICE_HEADER DeviceHeader
;
341 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
)Header
;
343 if(ObjectHeader
->TargetDevice
)
345 /* there is already a target device set */
348 /* caller wants to remove the target device */
349 DeviceExtension
= (PDEVICE_EXTENSION
)ObjectHeader
->TargetDevice
->DeviceExtension
;
351 /* get device header */
352 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
355 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
, FALSE
);
358 RemoveEntryList(&ObjectHeader
->TargetDeviceListEntry
);
360 /* remove device pointer */
361 ObjectHeader
->TargetDevice
= NULL
;
364 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
);
369 /* no target device yet set */
372 /* caller wants to add the target device */
373 DeviceExtension
= (PDEVICE_EXTENSION
)TargetDevice
->DeviceExtension
;
375 /* get device header */
376 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
379 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
, FALSE
);
381 /* insert list entry */
382 InsertTailList(&DeviceHeader
->TargetDeviceList
, &ObjectHeader
->TargetDeviceListEntry
);
384 /* store target device */
385 ObjectHeader
->TargetDevice
= TargetDevice
;
388 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
);
401 IN KSOBJECT_HEADER Header
,
402 IN PFNKSCONTEXT_DISPATCH PowerDispatch OPTIONAL
,
403 IN PVOID PowerContext OPTIONAL
)
405 PDEVICE_EXTENSION DeviceExtension
;
406 PKSIDEVICE_HEADER DeviceHeader
;
407 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
)Header
;
409 /* caller wants to add the target device */
410 DeviceExtension
= (PDEVICE_EXTENSION
)ObjectHeader
->ParentDeviceObject
->DeviceExtension
;
412 /* get device header */
413 DeviceHeader
= (PKSIDEVICE_HEADER
)DeviceExtension
->DeviceHeader
;
416 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
, FALSE
);
420 /* add power dispatch entry */
421 InsertTailList(&DeviceHeader
->PowerDispatchList
, &ObjectHeader
->PowerDispatchEntry
);
423 /* store function and context */
424 ObjectHeader
->PowerDispatch
= PowerDispatch
;
425 ObjectHeader
->PowerContext
= PowerContext
;
429 /* remove power dispatch entry */
430 RemoveEntryList(&ObjectHeader
->PowerDispatchEntry
);
432 /* store function and context */
433 ObjectHeader
->PowerDispatch
= NULL
;
434 ObjectHeader
->PowerContext
= NULL
;
439 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER
)DeviceHeader
);
447 PKSOBJECT_CREATE_ITEM
449 KsQueryObjectCreateItem(
450 IN KSOBJECT_HEADER Header
)
452 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
)Header
;
453 return ObjectHeader
->OriginalCreateItem
;
457 KspAddCreateItemToList(
458 OUT PLIST_ENTRY ListHead
,
460 IN PKSOBJECT_CREATE_ITEM ItemsList
)
463 PCREATE_ITEM_ENTRY Entry
;
466 for(Index
= 0; Index
< ItemsCount
; Index
++)
469 Entry
= AllocateItem(NonPagedPool
, sizeof(CREATE_ITEM_ENTRY
));
473 return STATUS_INSUFFICIENT_RESOURCES
;
476 /* initialize entry */
477 InitializeListHead(&Entry
->ObjectItemList
);
478 Entry
->CreateItem
= &ItemsList
[Index
];
479 Entry
->ReferenceCount
= 0;
480 Entry
->ItemFreeCallback
= NULL
;
482 InsertTailList(ListHead
, &Entry
->Entry
);
484 return STATUS_SUCCESS
;
489 PLIST_ENTRY ListHead
)
491 PCREATE_ITEM_ENTRY Entry
;
493 while(!IsListEmpty(ListHead
))
495 /* remove create item from list */
496 Entry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(RemoveHeadList(ListHead
), CREATE_ITEM_ENTRY
, Entry
);
498 /* caller shouldnt have any references */
499 //ASSERT(Entry->ReferenceCount == 0);
500 //ASSERT(IsListEmpty(&Entry->ObjectItemList));
502 /* does the creator wish notification */
503 if (Entry
->ItemFreeCallback
)
506 Entry
->ItemFreeCallback(Entry
->CreateItem
);
509 /* free create item entry */
521 KsAllocateDeviceHeader(
522 OUT KSDEVICE_HEADER
* OutHeader
,
524 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL
)
526 NTSTATUS Status
= STATUS_SUCCESS
;
527 PKSIDEVICE_HEADER Header
;
530 return STATUS_INVALID_PARAMETER
;
532 /* allocate a device header */
533 Header
= ExAllocatePoolWithTag(PagedPool
, sizeof(KSIDEVICE_HEADER
), TAG_DEVICE_HEADER
);
535 /* check for success */
537 return STATUS_INSUFFICIENT_RESOURCES
;
539 /* clear all memory */
540 RtlZeroMemory(Header
, sizeof(KSIDEVICE_HEADER
));
542 /* initialize device mutex */
543 KeInitializeMutex(&Header
->DeviceMutex
, 0);
545 /* initialize target device list */
546 InitializeListHead(&Header
->TargetDeviceList
);
547 /* initialize power dispatch list */
548 InitializeListHead(&Header
->PowerDispatchList
);
549 /* initialize object bag lists */
550 InitializeListHead(&Header
->ObjectBags
);
552 /* initialize create item list */
553 InitializeListHead(&Header
->ItemList
);
555 /* initialize basic header */
556 Header
->BasicHeader
.Type
= KsObjectTypeDevice
;
557 Header
->BasicHeader
.KsDevice
= &Header
->KsDevice
;
558 Header
->BasicHeader
.Parent
.KsDevice
= &Header
->KsDevice
;
560 /* are there any create items provided */
561 if (ItemsCount
&& ItemsList
)
563 Status
= KspAddCreateItemToList(&Header
->ItemList
, ItemsCount
, ItemsList
);
565 if (NT_SUCCESS(Status
))
567 /* store item count */
568 Header
->ItemListCount
= ItemsCount
;
572 /* release create items */
573 KspFreeCreateItems(&Header
->ItemList
);
590 IN KSDEVICE_HEADER DevHeader
)
592 PKSIDEVICE_HEADER Header
;
594 Header
= (PKSIDEVICE_HEADER
)DevHeader
;
599 KspFreeCreateItems(&Header
->ItemList
);
600 ExFreePoolWithTag(Header
, TAG_DEVICE_HEADER
);
609 KsAllocateObjectHeader(
610 OUT KSOBJECT_HEADER
*Header
,
612 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL
,
614 IN KSDISPATCH_TABLE
* Table
)
616 PIO_STACK_LOCATION IoStack
;
617 PDEVICE_EXTENSION DeviceExtension
;
618 PKSIDEVICE_HEADER DeviceHeader
;
619 PKSIOBJECT_HEADER ObjectHeader
;
620 PKSOBJECT_CREATE_ITEM CreateItem
;
624 return STATUS_INVALID_PARAMETER_1
;
627 return STATUS_INVALID_PARAMETER_4
;
630 return STATUS_INVALID_PARAMETER_5
;
632 /* get current stack location */
633 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
634 /* get device extension */
635 DeviceExtension
= (PDEVICE_EXTENSION
)IoStack
->DeviceObject
->DeviceExtension
;
636 /* get device header */
637 DeviceHeader
= DeviceExtension
->DeviceHeader
;
640 ASSERT(IoStack
->FileObject
);
641 /* check for an file object */
643 /* allocate the object header */
644 ObjectHeader
= ExAllocatePoolWithTag(NonPagedPool
, sizeof(KSIOBJECT_HEADER
), TAG_DEVICE_HEADER
);
646 return STATUS_INSUFFICIENT_RESOURCES
;
648 /* initialize object header */
649 RtlZeroMemory(ObjectHeader
, sizeof(KSIOBJECT_HEADER
));
651 /* initialize create item list */
652 InitializeListHead(&ObjectHeader
->ItemList
);
654 /* get create item */
655 CreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
657 /* do we have a name */
658 if (IoStack
->FileObject
->FileName
.Buffer
)
660 /* copy object class */
661 ObjectHeader
->ObjectClass
.MaximumLength
= IoStack
->FileObject
->FileName
.MaximumLength
;
662 ObjectHeader
->ObjectClass
.Buffer
= ExAllocatePoolWithTag(NonPagedPool
, ObjectHeader
->ObjectClass
.MaximumLength
, TAG_DEVICE_HEADER
);
663 if (!ObjectHeader
->ObjectClass
.Buffer
)
665 ExFreePoolWithTag(ObjectHeader
, TAG_DEVICE_HEADER
);
666 return STATUS_INSUFFICIENT_RESOURCES
;
668 RtlCopyUnicodeString(&ObjectHeader
->ObjectClass
, &IoStack
->FileObject
->FileName
);
671 /* copy dispatch table */
672 RtlCopyMemory(&ObjectHeader
->DispatchTable
, Table
, sizeof(KSDISPATCH_TABLE
));
674 /* store create items */
675 if (ItemsCount
&& ItemsList
)
677 Status
= KspAddCreateItemToList(&ObjectHeader
->ItemList
, ItemsCount
, ItemsList
);
679 if (NT_SUCCESS(Status
))
681 /* store item count */
682 ObjectHeader
->ItemListCount
= ItemsCount
;
687 KsFreeObjectHeader(ObjectHeader
);
691 /* store the object in the file object */
692 IoStack
->FileObject
->FsContext2
= ObjectHeader
;
694 /* store parent device */
695 ObjectHeader
->ParentDeviceObject
= IoGetRelatedDeviceObject(IoStack
->FileObject
);
697 /* store originating create item */
698 ObjectHeader
->OriginalCreateItem
= KSCREATE_ITEM_IRP_STORAGE(Irp
);
700 /* FIXME store access mask see KsQueryObjectAccessMask */
701 ObjectHeader
->AccessMask
= IoStack
->Parameters
.Create
.SecurityContext
->DesiredAccess
;
705 *Header
= ObjectHeader
;
707 DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader
->ObjectClass
.Buffer
, IoStack
->FileObject
, ObjectHeader
);
709 return STATUS_SUCCESS
;
722 PKSIOBJECT_HEADER ObjectHeader
= (PKSIOBJECT_HEADER
) Header
;
724 DPRINT("KsFreeObjectHeader Header %p Class %wZ\n", Header
, &ObjectHeader
->ObjectClass
);
726 if (ObjectHeader
->ObjectClass
.Buffer
)
728 /* release object class buffer */
729 ExFreePoolWithTag(ObjectHeader
->ObjectClass
.Buffer
, TAG_DEVICE_HEADER
);
732 if (ObjectHeader
->Unknown
)
734 /* release associated object */
735 ObjectHeader
->Unknown
->lpVtbl
->Release(ObjectHeader
->Unknown
);
738 /* free create items */
739 KspFreeCreateItems(&ObjectHeader
->ItemList
);
741 /* free object header */
742 ExFreePoolWithTag(ObjectHeader
, TAG_DEVICE_HEADER
);
747 KspAddObjectCreateItemToList(
748 PLIST_ENTRY ListHead
,
749 IN PDRIVER_DISPATCH Create
,
751 IN PWCHAR ObjectClass
,
752 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
755 PCREATE_ITEM_ENTRY CreateEntry
;
757 /* point to first entry */
758 Entry
= ListHead
->Flink
;
760 while(Entry
!= ListHead
)
762 /* get create entry */
763 CreateEntry
= (PCREATE_ITEM_ENTRY
)CONTAINING_RECORD(Entry
, CREATE_ITEM_ENTRY
, Entry
);
764 /* if the create item has no create routine, then it is free to use */
765 if (CreateEntry
->CreateItem
->Create
== NULL
)
768 ASSERT(IsListEmpty(&CreateEntry
->ObjectItemList
));
769 ASSERT(CreateEntry
->ReferenceCount
== 0);
771 CreateEntry
->CreateItem
->Context
= Context
;
772 CreateEntry
->CreateItem
->Create
= Create
;
773 RtlInitUnicodeString(&CreateEntry
->CreateItem
->ObjectClass
, ObjectClass
);
774 CreateEntry
->CreateItem
->SecurityDescriptor
= SecurityDescriptor
;
776 return STATUS_SUCCESS
;
779 if (!wcsicmp(ObjectClass
, CreateEntry
->CreateItem
->ObjectClass
.Buffer
))
781 /* the same object class already exists */
782 return STATUS_OBJECT_NAME_COLLISION
;
785 /* iterate to next entry */
786 Entry
= Entry
->Flink
;
788 return STATUS_ALLOTTED_SPACE_EXCEEDED
;
797 KsAddObjectCreateItemToDeviceHeader(
798 IN KSDEVICE_HEADER DevHeader
,
799 IN PDRIVER_DISPATCH Create
,
801 IN PWCHAR ObjectClass
,
802 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
804 PKSIDEVICE_HEADER Header
;
807 Header
= (PKSIDEVICE_HEADER
)DevHeader
;
809 DPRINT("KsAddObjectCreateItemToDeviceHeader entered\n");
811 /* check if a device header has been provided */
813 return STATUS_INVALID_PARAMETER_1
;
815 /* check if a create item has been provided */
817 return STATUS_INVALID_PARAMETER_2
;
819 /* check if a object class has been provided */
821 return STATUS_INVALID_PARAMETER_4
;
823 /* let others do the work */
824 Status
= KspAddObjectCreateItemToList(&Header
->ItemList
, Create
, Context
, ObjectClass
, SecurityDescriptor
);
826 if (NT_SUCCESS(Status
))
828 /* increment create item count */
829 InterlockedIncrement(&Header
->ItemListCount
);
831 DPRINT("KsAddObjectCreateItemToDeviceHeader Status %x\n", Status
);
841 KsAddObjectCreateItemToObjectHeader(
842 IN KSOBJECT_HEADER ObjectHeader
,
843 IN PDRIVER_DISPATCH Create
,
845 IN PWCHAR ObjectClass
,
846 IN PSECURITY_DESCRIPTOR SecurityDescriptor
)
848 PKSIOBJECT_HEADER Header
;
851 Header
= (PKSIOBJECT_HEADER
)ObjectHeader
;
853 DPRINT("KsAddObjectCreateItemToDeviceHeader entered\n");
855 /* check if a device header has been provided */
857 return STATUS_INVALID_PARAMETER_1
;
859 /* check if a create item has been provided */
861 return STATUS_INVALID_PARAMETER_2
;
863 /* check if a object class has been provided */
865 return STATUS_INVALID_PARAMETER_4
;
868 Status
= KspAddObjectCreateItemToList(&Header
->ItemList
, Create
, Context
, ObjectClass
, SecurityDescriptor
);
870 if (NT_SUCCESS(Status
))
872 /* increment create item count */
873 InterlockedIncrement(&Header
->ItemListCount
);
885 KsAllocateObjectCreateItem(
886 IN KSDEVICE_HEADER DevHeader
,
887 IN PKSOBJECT_CREATE_ITEM CreateItem
,
888 IN BOOLEAN AllocateEntry
,
889 IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL
)
891 PCREATE_ITEM_ENTRY CreateEntry
;
892 PKSIDEVICE_HEADER Header
;
893 PKSOBJECT_CREATE_ITEM Item
;
895 Header
= (PKSIDEVICE_HEADER
)DevHeader
;
898 return STATUS_INVALID_PARAMETER_1
;
901 return STATUS_INVALID_PARAMETER_2
;
903 /* first allocate a create entry */
904 CreateEntry
= AllocateItem(NonPagedPool
, sizeof(CREATE_ITEM_ENTRY
));
906 /* check for allocation success */
909 /* not enough resources */
910 return STATUS_INSUFFICIENT_RESOURCES
;
916 /* allocate create item */
917 Item
= ExAllocatePool(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
));
921 ExFreePool(CreateEntry
);
922 return STATUS_INSUFFICIENT_RESOURCES
;
925 /* initialize descriptor */
926 Item
->Context
= CreateItem
->Context
;
927 Item
->Create
= CreateItem
->Create
;
928 Item
->Flags
= CreateItem
->Flags
;
929 Item
->SecurityDescriptor
= CreateItem
->SecurityDescriptor
;
930 Item
->ObjectClass
.Length
= 0;
931 Item
->ObjectClass
.MaximumLength
= CreateItem
->ObjectClass
.MaximumLength
;
933 /* copy object class */
934 Item
->ObjectClass
.Buffer
= ExAllocatePool(NonPagedPool
, Item
->ObjectClass
.MaximumLength
);
935 if (!Item
->ObjectClass
.Buffer
)
937 /* release resources */
939 FreeItem(CreateEntry
);
941 return STATUS_INSUFFICIENT_RESOURCES
;
943 RtlCopyUnicodeString(&Item
->ObjectClass
, &CreateItem
->ObjectClass
);
947 if (ItemFreeCallback
)
949 /* callback is only accepted when the create item is copied */
950 ItemFreeCallback
= NULL
;
952 /* use passed create item */
956 /* initialize create item entry */
957 InitializeListHead(&CreateEntry
->ObjectItemList
);
958 CreateEntry
->ItemFreeCallback
= ItemFreeCallback
;
959 CreateEntry
->CreateItem
= Item
;
960 CreateEntry
->ReferenceCount
= 0;
962 /* now insert the create item entry */
963 InsertTailList(&Header
->ItemList
, &CreateEntry
->Entry
);
965 /* increment item count */
966 InterlockedIncrement(&Header
->ItemListCount
);
968 return STATUS_SUCCESS
;
972 KspObjectFreeCreateItems(
973 IN KSDEVICE_HEADER Header
,
974 IN PKSOBJECT_CREATE_ITEM CreateItem
)
977 return STATUS_NOT_IMPLEMENTED
;
986 KsFreeObjectCreateItem(
987 IN KSDEVICE_HEADER Header
,
988 IN PUNICODE_STRING CreateItem
)
990 KSOBJECT_CREATE_ITEM Item
;
992 RtlZeroMemory(&Item
, sizeof(KSOBJECT_CREATE_ITEM
));
993 RtlInitUnicodeString(&Item
.ObjectClass
, CreateItem
->Buffer
);
995 return KspObjectFreeCreateItems(Header
, &Item
);
1005 KsFreeObjectCreateItemsByContext(
1006 IN KSDEVICE_HEADER Header
,
1009 KSOBJECT_CREATE_ITEM Item
;
1011 RtlZeroMemory(&Item
, sizeof(KSOBJECT_CREATE_ITEM
));
1013 Item
.Context
= Context
;
1015 return KspObjectFreeCreateItems(Header
, &Item
);
1024 KsCreateDefaultSecurity(
1025 IN PSECURITY_DESCRIPTOR ParentSecurity OPTIONAL
,
1026 OUT PSECURITY_DESCRIPTOR
* DefaultSecurity
)
1028 PGENERIC_MAPPING Mapping
;
1029 SECURITY_SUBJECT_CONTEXT SubjectContext
;
1032 /* start capturing security context of calling thread */
1033 SeCaptureSubjectContext(&SubjectContext
);
1034 /* get generic mapping */
1035 Mapping
= IoGetFileObjectGenericMapping();
1036 /* build new descriptor */
1037 Status
= SeAssignSecurity(ParentSecurity
, NULL
, DefaultSecurity
, FALSE
, &SubjectContext
, Mapping
, NonPagedPool
);
1038 /* release security descriptor */
1039 SeReleaseSubjectContext(&SubjectContext
);
1052 IN PFILE_OBJECT FileObject
,
1053 IN BOOLEAN ReuseStackLocation
)
1056 return STATUS_UNSUCCESSFUL
;
1066 KsForwardAndCatchIrp(
1067 IN PDEVICE_OBJECT DeviceObject
,
1069 IN PFILE_OBJECT FileObject
,
1070 IN KSSTACK_USE StackUse
)
1073 return STATUS_UNSUCCESSFUL
;
1079 KspSynchronousIoControlDeviceCompletion(
1080 IN PDEVICE_OBJECT DeviceObject
,
1084 PIO_STATUS_BLOCK IoStatusBlock
= (PIO_STATUS_BLOCK
)Context
;
1086 IoStatusBlock
->Information
= Irp
->IoStatus
.Information
;
1087 IoStatusBlock
->Status
= Irp
->IoStatus
.Status
;
1089 return STATUS_SUCCESS
;
1098 KsSynchronousIoControlDevice(
1099 IN PFILE_OBJECT FileObject
,
1100 IN KPROCESSOR_MODE RequestorMode
,
1104 OUT PVOID OutBuffer
,
1106 OUT PULONG BytesReturned
)
1108 PKSIOBJECT_HEADER ObjectHeader
;
1109 PDEVICE_OBJECT DeviceObject
;
1112 IO_STATUS_BLOCK IoStatusBlock
;
1113 PIO_STACK_LOCATION IoStack
;
1116 /* check for valid file object */
1118 return STATUS_INVALID_PARAMETER
;
1120 /* get device object to send the request to */
1121 DeviceObject
= IoGetRelatedDeviceObject(FileObject
);
1123 return STATUS_UNSUCCESSFUL
;
1126 /* get object header */
1127 ObjectHeader
= (PKSIOBJECT_HEADER
)FileObject
->FsContext2
;
1129 /* check if there is fast device io function */
1130 if (ObjectHeader
&& ObjectHeader
->DispatchTable
.FastDeviceIoControl
)
1132 IoStatusBlock
.Status
= STATUS_UNSUCCESSFUL
;
1133 IoStatusBlock
.Information
= 0;
1135 /* send the request */
1136 Status
= ObjectHeader
->DispatchTable
.FastDeviceIoControl(FileObject
, TRUE
, InBuffer
, InSize
, OutBuffer
, OutSize
, IoControl
, &IoStatusBlock
, DeviceObject
);
1137 /* check if the request was handled */
1138 //DPRINT("Handled %u Status %x Length %u\n", Status, IoStatusBlock.Status, IoStatusBlock.Information);
1141 /* store bytes returned */
1142 *BytesReturned
= IoStatusBlock
.Information
;
1144 return IoStatusBlock
.Status
;
1148 /* initialize the event */
1149 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1151 /* create the irp */
1152 Irp
= IoBuildDeviceIoControlRequest(IoControl
, DeviceObject
, InBuffer
, InSize
, OutBuffer
, OutSize
, FALSE
, &Event
, &IoStatusBlock
);
1156 /* no memory to allocate the irp */
1157 return STATUS_INSUFFICIENT_RESOURCES
;
1161 /* Store Fileobject */
1162 IoStack
= IoGetNextIrpStackLocation(Irp
);
1163 IoStack
->FileObject
= FileObject
;
1165 if (IoControl
== IOCTL_KS_WRITE_STREAM
)
1167 Irp
->AssociatedIrp
.SystemBuffer
= OutBuffer
;
1169 else if (IoControl
== IOCTL_KS_READ_STREAM
)
1171 Irp
->AssociatedIrp
.SystemBuffer
= InBuffer
;
1174 IoSetCompletionRoutine(Irp
, KspSynchronousIoControlDeviceCompletion
, (PVOID
)&IoStatusBlock
, TRUE
, TRUE
, TRUE
);
1176 Status
= IoCallDriver(DeviceObject
, Irp
);
1177 if (Status
== STATUS_PENDING
)
1179 KeWaitForSingleObject(&Event
, Executive
, RequestorMode
, FALSE
, NULL
);
1180 Status
= IoStatusBlock
.Status
;
1183 *BytesReturned
= IoStatusBlock
.Information
;
1193 KsUnserializeObjectPropertiesFromRegistry(
1194 IN PFILE_OBJECT FileObject
,
1195 IN HANDLE ParentKey OPTIONAL
,
1196 IN PUNICODE_STRING RegistryPath OPTIONAL
)
1199 return STATUS_NOT_IMPLEMENTED
;
1210 IN PUNICODE_STRING SymbolicLink
,
1211 IN PKSPIN_MEDIUM Medium
,
1212 IN ULONG PinDirection
)
1215 UNICODE_STRING Path
;
1216 UNICODE_STRING BasePath
= RTL_CONSTANT_STRING(L
"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Control\\MediumCache\\");
1217 UNICODE_STRING GuidString
;
1219 OBJECT_ATTRIBUTES ObjectAttributes
;
1220 BOOLEAN PathAdjusted
= FALSE
;
1223 /* first check if the medium is standard */
1224 if (IsEqualGUIDAligned(&KSMEDIUMSETID_Standard
, &Medium
->Set
) ||
1225 IsEqualGUIDAligned(&GUID_NULL
, &Medium
->Set
))
1227 /* no need to cache that */
1228 return STATUS_SUCCESS
;
1231 /* convert guid to string */
1232 Status
= RtlStringFromGUID(&Medium
->Set
, &GuidString
);
1233 if (!NT_SUCCESS(Status
))
1236 /* allocate path buffer */
1238 Path
.MaximumLength
= BasePath
.MaximumLength
+ GuidString
.MaximumLength
+ 10 * sizeof(WCHAR
);
1239 Path
.Buffer
= AllocateItem(PagedPool
, Path
.MaximumLength
);
1242 /* not enough resources */
1243 RtlFreeUnicodeString(&GuidString
);
1244 return STATUS_INSUFFICIENT_RESOURCES
;
1247 RtlAppendUnicodeStringToString(&Path
, &BasePath
);
1248 RtlAppendUnicodeStringToString(&Path
, &GuidString
);
1249 RtlAppendUnicodeToString(&Path
, L
"-");
1250 /* FIXME append real instance id */
1251 RtlAppendUnicodeToString(&Path
, L
"0");
1252 RtlAppendUnicodeToString(&Path
, L
"-");
1253 /* FIXME append real instance id */
1254 RtlAppendUnicodeToString(&Path
, L
"0");
1256 /* free guid string */
1257 RtlFreeUnicodeString(&GuidString
);
1259 /* initialize object attributes */
1260 InitializeObjectAttributes(&ObjectAttributes
, &Path
, OBJ_KERNEL_HANDLE
| OBJ_CASE_INSENSITIVE
, NULL
, NULL
);
1261 /* create the key */
1262 Status
= ZwCreateKey(&hKey
, GENERIC_WRITE
, &ObjectAttributes
, 0, NULL
, 0, NULL
);
1264 /* free path buffer */
1265 FreeItem(Path
.Buffer
);
1267 if (NT_SUCCESS(Status
))
1269 /* store symbolic link */
1270 if (SymbolicLink
->Buffer
[1] == L
'?' && SymbolicLink
->Buffer
[2] == L
'?')
1272 /* replace kernel path with user mode path */
1273 SymbolicLink
->Buffer
[1] = L
'\\';
1274 PathAdjusted
= TRUE
;
1278 Status
= ZwSetValueKey(hKey
, SymbolicLink
, 0, REG_DWORD
, &Value
, sizeof(ULONG
));
1282 /* restore kernel path */
1283 SymbolicLink
->Buffer
[1] = L
'?';
1299 PUNICODE_STRING RegistryPath
)
1301 return STATUS_SUCCESS
;
1308 IN PDEVICE_OBJECT DeviceObject
,
1311 PKO_OBJECT_HEADER Header
;
1312 PIO_STACK_LOCATION IoStack
;
1313 PDEVICE_EXTENSION DeviceExtension
;
1315 /* get current irp stack location */
1316 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1318 /* get ko object header */
1319 Header
= (PKO_OBJECT_HEADER
)IoStack
->FileObject
->FsContext2
;
1321 /* free ks object header */
1322 KsFreeObjectHeader(Header
->ObjectHeader
);
1324 /* free ko object header */
1327 /* get device extension */
1328 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1330 /* release bus object */
1331 KsDereferenceBusObject((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
);
1333 /* complete request */
1334 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1335 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1337 return STATUS_SUCCESS
;
1342 static KSDISPATCH_TABLE KoDispatchTable
=
1344 KsDispatchInvalidDeviceRequest
,
1345 KsDispatchInvalidDeviceRequest
,
1346 KsDispatchInvalidDeviceRequest
,
1347 KsDispatchInvalidDeviceRequest
,
1349 KsDispatchQuerySecurity
,
1350 KsDispatchSetSecurity
,
1351 KsDispatchFastIoDeviceControlFailure
,
1352 KsDispatchFastReadFailure
,
1353 KsDispatchFastReadFailure
,
1360 IN PDEVICE_OBJECT DeviceObject
,
1363 PKO_OBJECT_HEADER Header
= NULL
;
1364 PIO_STACK_LOCATION IoStack
;
1365 PKO_DRIVER_EXTENSION DriverObjectExtension
;
1368 /* get current irp stack location */
1369 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1371 if (!IoStack
->FileObject
)
1373 DPRINT1("FileObject not attached!\n");
1374 Status
= STATUS_UNSUCCESSFUL
;
1378 /* get driver object extension */
1379 DriverObjectExtension
= (PKO_DRIVER_EXTENSION
)IoGetDriverObjectExtension(DeviceObject
->DriverObject
, (PVOID
)KoDriverInitialize
);
1380 if (!DriverObjectExtension
)
1382 DPRINT1("No DriverObjectExtension!\n");
1383 Status
= STATUS_UNSUCCESSFUL
;
1387 /* allocate ko object header */
1388 Header
= (PKO_OBJECT_HEADER
)AllocateItem(NonPagedPool
, sizeof(KO_OBJECT_HEADER
));
1391 DPRINT1("failed to allocate KO_OBJECT_HEADER\n");
1392 Status
= STATUS_INSUFFICIENT_RESOURCES
;
1396 /* initialize create item */
1397 Header
->CreateItem
.Create
= KopDispatchCreate
;
1398 RtlInitUnicodeString(&Header
->CreateItem
.ObjectClass
, KOSTRING_CreateObject
);
1401 /* now allocate the object header */
1402 Status
= KsAllocateObjectHeader(&Header
->ObjectHeader
, 1, &Header
->CreateItem
, Irp
, &KoDispatchTable
);
1403 if (!NT_SUCCESS(Status
))
1410 * extract clsid and interface id from irp
1411 * call the standard create handler
1416 IoStack
->FileObject
->FsContext2
= (PVOID
)Header
;
1418 Irp
->IoStatus
.Status
= Status
;
1419 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1425 if (Header
&& Header
->ObjectHeader
)
1426 KsFreeObjectHeader(Header
->ObjectHeader
);
1431 Irp
->IoStatus
.Status
= Status
;
1432 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1441 IN PDRIVER_OBJECT DriverObject
,
1442 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1444 NTSTATUS Status
= STATUS_DEVICE_REMOVED
;
1445 PDEVICE_OBJECT FunctionalDeviceObject
= NULL
;
1446 PDEVICE_OBJECT NextDeviceObject
;
1447 PDEVICE_EXTENSION DeviceExtension
;
1448 PKSOBJECT_CREATE_ITEM CreateItem
;
1450 /* create the device object */
1451 Status
= IoCreateDevice(DriverObject
, sizeof(DEVICE_EXTENSION
), NULL
, FILE_DEVICE_KS
, FILE_DEVICE_SECURE_OPEN
, FALSE
, &FunctionalDeviceObject
);
1452 if (!NT_SUCCESS(Status
))
1455 /* allocate the create item */
1456 CreateItem
= AllocateItem(NonPagedPool
, sizeof(KSOBJECT_CREATE_ITEM
));
1460 /* not enough memory */
1461 IoDeleteDevice(FunctionalDeviceObject
);
1462 return STATUS_INSUFFICIENT_RESOURCES
;
1465 /* initialize create item */
1466 CreateItem
->Create
= KopDispatchCreate
;
1467 RtlInitUnicodeString(&CreateItem
->ObjectClass
, KOSTRING_CreateObject
);
1469 /* get device extension */
1470 DeviceExtension
= (PDEVICE_EXTENSION
)FunctionalDeviceObject
->DeviceExtension
;
1472 /* now allocate the device header */
1473 Status
= KsAllocateDeviceHeader((KSDEVICE_HEADER
*)&DeviceExtension
->DeviceHeader
, 1, CreateItem
);
1474 if (!NT_SUCCESS(Status
))
1477 IoDeleteDevice(FunctionalDeviceObject
);
1478 FreeItem(CreateItem
);
1482 /* now attach to device stack */
1483 NextDeviceObject
= IoAttachDeviceToDeviceStack(FunctionalDeviceObject
, PhysicalDeviceObject
);
1484 if (NextDeviceObject
)
1486 /* store pnp base object */
1487 KsSetDevicePnpAndBaseObject((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, NextDeviceObject
, FunctionalDeviceObject
);
1488 /* set device flags */
1489 FunctionalDeviceObject
->Flags
|= DO_DIRECT_IO
| DO_POWER_PAGABLE
;
1490 FunctionalDeviceObject
->Flags
&= ~ DO_DEVICE_INITIALIZING
;
1495 KsFreeDeviceHeader((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
);
1496 FreeItem(CreateItem
);
1497 IoDeleteDevice(FunctionalDeviceObject
);
1498 Status
= STATUS_DEVICE_REMOVED
;
1513 IN PDEVICE_OBJECT DeviceObject
)
1515 PDEVICE_EXTENSION DeviceExtension
;
1517 /* get device extension */
1518 DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1520 return KsAddObjectCreateItemToDeviceHeader((KSDEVICE_HEADER
)DeviceExtension
->DeviceHeader
, KopDispatchCreate
, NULL
, KOSTRING_CreateObject
, NULL
);
1530 IN PDRIVER_OBJECT DriverObject
,
1531 IN PUNICODE_STRING RegistryPathName
,
1532 IN KoCreateObjectHandler CreateObjectHandler
)
1534 PKO_DRIVER_EXTENSION DriverObjectExtension
;
1537 /* allocate driver object extension */
1538 Status
= IoAllocateDriverObjectExtension(DriverObject
, (PVOID
)KoDriverInitialize
, sizeof(KO_DRIVER_EXTENSION
), (PVOID
*)&DriverObjectExtension
);
1541 if (NT_SUCCESS(Status
))
1543 /* store create handler */
1544 DriverObjectExtension
->CreateObjectHandler
= CreateObjectHandler
;
1546 /* Setting our IRP handlers */
1547 DriverObject
->MajorFunction
[IRP_MJ_PNP
] = KsDefaultDispatchPnp
;
1548 DriverObject
->MajorFunction
[IRP_MJ_POWER
] = KsDefaultDispatchPower
;
1549 DriverObject
->MajorFunction
[IRP_MJ_SYSTEM_CONTROL
] = KsDefaultForwardIrp
;
1551 /* The driver unload routine */
1552 DriverObject
->DriverUnload
= KsNullDriverUnload
;
1554 /* The driver-supplied AddDevice */
1555 DriverObject
->DriverExtension
->AddDevice
= KopAddDevice
;
1557 /* KS handles these */
1558 DPRINT1("Setting KS function handlers\n");
1559 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_CREATE
);
1560 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_CLOSE
);
1561 KsSetMajorFunctionHandler(DriverObject
, IRP_MJ_DEVICE_CONTROL
);
1575 IN REFCLSID ClassId
)
1589 PKSBASIC_HEADER BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
1592 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
1594 KeWaitForSingleObject(BasicHeader
->ControlMutex
, Executive
, KernelMode
, FALSE
, NULL
);
1606 PKSBASIC_HEADER BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
1609 ASSERT(BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
1611 KeReleaseMutex(BasicHeader
->ControlMutex
, FALSE
);
1623 IN PKSDEVICE Device
)
1625 IKsDevice
*KsDevice
;
1626 PKSIDEVICE_HEADER DeviceHeader
;
1628 DPRINT("KsAcquireDevice\n");
1629 DeviceHeader
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(Device
, KSIDEVICE_HEADER
, KsDevice
);
1631 /* get device interface*/
1632 KsDevice
= (IKsDevice
*)&DeviceHeader
->BasicHeader
.OuterUnknown
;
1634 /* acquire device mutex */
1635 KsDevice
->lpVtbl
->AcquireDevice(KsDevice
);
1644 IN PKSDEVICE Device
)
1646 IKsDevice
*KsDevice
;
1647 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(Device
, KSIDEVICE_HEADER
, KsDevice
);
1649 /* get device interface*/
1650 KsDevice
= (IKsDevice
*)&DeviceHeader
->BasicHeader
.OuterUnknown
;
1652 /* release device mutex */
1653 KsDevice
->lpVtbl
->ReleaseDevice(KsDevice
);
1663 IN PDEVICE_OBJECT DeviceObject
)
1665 IKsDevice
*KsDevice
;
1666 PKSIDEVICE_HEADER DeviceHeader
;
1667 PDEVICE_EXTENSION DeviceExtension
= (PDEVICE_EXTENSION
)DeviceObject
->DeviceExtension
;
1669 /* get device header */
1670 DeviceHeader
= DeviceExtension
->DeviceHeader
;
1672 /* get device interface*/
1673 KsDevice
= (IKsDevice
*)&DeviceHeader
->BasicHeader
.OuterUnknown
;
1675 /* now free device header */
1676 KsFreeDeviceHeader((KSDEVICE_HEADER
)DeviceHeader
);
1678 /* release interface when available */
1681 /* delete IKsDevice interface */
1682 KsDevice
->lpVtbl
->Release(KsDevice
);
1692 KsCompletePendingRequest(
1695 PIO_STACK_LOCATION IoStack
;
1697 /* get current irp stack location */
1698 IoStack
= IoGetCurrentIrpStackLocation(Irp
);
1701 ASSERT(Irp
->IoStatus
.Status
!= STATUS_PENDING
);
1703 if (IoStack
->MajorFunction
!= IRP_MJ_CLOSE
)
1705 /* can be completed immediately */
1706 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1710 /* did close operation fail */
1711 if (!NT_SUCCESS(Irp
->IoStatus
.Status
))
1713 /* closing failed, complete irp */
1714 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1719 * delete object / device header
1720 * remove dead pin / filter instance
1732 KsCreateBusEnumObject(
1733 IN PWCHAR BusIdentifier
,
1734 IN PDEVICE_OBJECT BusDeviceObject
,
1735 IN PDEVICE_OBJECT PhysicalDeviceObject
,
1736 IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL
,
1737 IN REFGUID InterfaceGuid OPTIONAL
,
1738 IN PWCHAR ServiceRelativePath OPTIONAL
)
1741 NTSTATUS Status
= STATUS_SUCCESS
;
1742 UNICODE_STRING ServiceKeyPath
= RTL_CONSTANT_STRING(L
"\\REGISTRY\\MACHINE\\SYSTEM\\CurrentControlSet\\Services\\");
1743 PBUS_ENUM_DEVICE_EXTENSION BusDeviceExtension
;
1744 PDEVICE_EXTENSION DeviceExtension
;
1746 /* calculate sizeof bus enum device extension */
1747 Length
= wcslen(BusIdentifier
) * sizeof(WCHAR
);
1748 Length
+= sizeof(BUS_ENUM_DEVICE_EXTENSION
);
1750 BusDeviceExtension
= ExAllocatePool(NonPagedPool
, Length
);
1751 if (!BusDeviceExtension
)
1753 /* not enough memory */
1754 return STATUS_INSUFFICIENT_RESOURCES
;
1757 /* zero device extension */
1758 RtlZeroMemory(BusDeviceExtension
, sizeof(BUS_ENUM_DEVICE_EXTENSION
));
1760 /* initialize bus device extension */
1761 wcscpy(BusDeviceExtension
->BusIdentifier
, BusIdentifier
);
1763 /* allocate service path string */
1764 Length
= ServiceKeyPath
.MaximumLength
;
1765 Length
+= BusDeviceObject
->DriverObject
->DriverExtension
->ServiceKeyName
.MaximumLength
;
1767 if (ServiceRelativePath
)
1769 /* relative path for devices */
1770 Length
+= wcslen(ServiceRelativePath
) + 2 * sizeof(WCHAR
);
1773 BusDeviceExtension
->ServicePath
.Length
= 0;
1774 BusDeviceExtension
->ServicePath
.MaximumLength
= Length
;
1775 BusDeviceExtension
->ServicePath
.Buffer
= ExAllocatePool(NonPagedPool
, Length
);
1777 if (!BusDeviceExtension
->ServicePath
.Buffer
)
1779 /* not enough memory */
1780 ExFreePool(BusDeviceExtension
);
1781 return STATUS_INSUFFICIENT_RESOURCES
;
1784 RtlAppendUnicodeStringToString(&BusDeviceExtension
->ServicePath
, &ServiceKeyPath
);
1785 RtlAppendUnicodeStringToString(&BusDeviceExtension
->ServicePath
, &BusDeviceObject
->DriverObject
->DriverExtension
->ServiceKeyName
);
1787 if (ServiceRelativePath
)
1789 RtlAppendUnicodeToString(&BusDeviceExtension
->ServicePath
, L
"\\");
1790 RtlAppendUnicodeToString(&BusDeviceExtension
->ServicePath
, ServiceRelativePath
);
1795 /* register an device interface */
1796 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
, InterfaceGuid
, NULL
, &BusDeviceExtension
->SymbolicLinkName
);
1798 /* check for success */
1799 if (!NT_SUCCESS(Status
))
1801 ExFreePool(BusDeviceExtension
->ServicePath
.Buffer
);
1802 ExFreePool(BusDeviceExtension
);
1806 /* now enable device interface */
1807 Status
= IoSetDeviceInterfaceState(&BusDeviceExtension
->SymbolicLinkName
, TRUE
);
1809 if (!NT_SUCCESS(Status
))
1811 ExFreePool(BusDeviceExtension
->ServicePath
.Buffer
);
1812 ExFreePool(BusDeviceExtension
);
1816 /* set state enabled */
1817 BusDeviceExtension
->Enabled
= TRUE
;
1820 /* store device objects */
1821 BusDeviceExtension
->BusDeviceObject
= BusDeviceObject
;
1822 BusDeviceExtension
->PnpDeviceObject
= PnpDeviceObject
;
1823 BusDeviceExtension
->PhysicalDeviceObject
= PhysicalDeviceObject
;
1825 if (!PnpDeviceObject
)
1827 BusDeviceExtension
->PnpDeviceObject
= IoAttachDeviceToDeviceStack(BusDeviceObject
, PhysicalDeviceObject
);
1829 if (!BusDeviceExtension
->PnpDeviceObject
)
1831 /* failed to attach device */
1832 if (BusDeviceExtension
->Enabled
)
1834 IoSetDeviceInterfaceState(&BusDeviceExtension
->SymbolicLinkName
, FALSE
);
1835 RtlFreeUnicodeString(&BusDeviceExtension
->SymbolicLinkName
);
1838 /* free device extension */
1839 ExFreePool(BusDeviceExtension
->ServicePath
.Buffer
);
1840 ExFreePool(BusDeviceExtension
);
1842 return STATUS_DEVICE_REMOVED
;
1846 /* attach device extension */
1847 DeviceExtension
= (PDEVICE_EXTENSION
)BusDeviceObject
->DeviceExtension
;
1848 DeviceExtension
->DeviceHeader
= (PKSIDEVICE_HEADER
)BusDeviceExtension
;
1850 /* FIXME scan bus and invalidate device relations */
1856 KspSetGetBusDataCompletion(
1857 IN PDEVICE_OBJECT DeviceObject
,
1861 /* signal completion */
1862 KeSetEvent((PRKEVENT
)Context
, IO_NO_INCREMENT
, FALSE
);
1864 /* more work needs be done, so dont free the irp */
1865 return STATUS_MORE_PROCESSING_REQUIRED
;
1870 KspDeviceSetGetBusData(
1871 IN PDEVICE_OBJECT DeviceObject
,
1878 PIO_STACK_LOCATION IoStack
;
1883 /* allocate the irp */
1884 Irp
= IoAllocateIrp(1, /*FIXME */
1888 return STATUS_INSUFFICIENT_RESOURCES
;
1890 /* initialize the event */
1891 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1893 /* get next stack location */
1894 IoStack
= IoGetNextIrpStackLocation(Irp
);
1896 /* setup a completion routine */
1897 IoSetCompletionRoutine(Irp
, KspSetGetBusDataCompletion
, (PVOID
)&Event
, TRUE
, TRUE
, TRUE
);
1899 /* setup parameters */
1900 IoStack
->Parameters
.ReadWriteConfig
.Buffer
= Buffer
;
1901 IoStack
->Parameters
.ReadWriteConfig
.Length
= Length
;
1902 IoStack
->Parameters
.ReadWriteConfig
.Offset
= Offset
;
1903 IoStack
->Parameters
.ReadWriteConfig
.WhichSpace
= DataType
;
1904 /* setup function code */
1905 IoStack
->MajorFunction
= IRP_MJ_PNP
;
1906 IoStack
->MinorFunction
= (bGet
? IRP_MN_READ_CONFIG
: IRP_MN_WRITE_CONFIG
);
1908 /* lets call the driver */
1909 Status
= IoCallDriver(DeviceObject
, Irp
);
1911 /* is the request still pending */
1912 if (Status
== STATUS_PENDING
)
1915 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1917 Status
= Irp
->IoStatus
.Status
;
1933 IN PKSDEVICE Device
,
1939 return KspDeviceSetGetBusData(Device
->PhysicalDeviceObject
, /* is this right? */
1940 DataType
, Buffer
, Offset
, Length
, FALSE
);
1951 IN PKSDEVICE Device
,
1957 return KspDeviceSetGetBusData(Device
->PhysicalDeviceObject
, /* is this right? */
1958 DataType
, Buffer
, Offset
, Length
, TRUE
);
1968 KsDeviceRegisterAdapterObject(
1969 IN PKSDEVICE Device
,
1970 IN PADAPTER_OBJECT AdapterObject
,
1971 IN ULONG MaxMappingsByteCount
,
1972 IN ULONG MappingTableStride
)
1974 PKSIDEVICE_HEADER DeviceHeader
= (PKSIDEVICE_HEADER
)CONTAINING_RECORD(Device
, KSIDEVICE_HEADER
, KsDevice
);
1976 DeviceHeader
->AdapterObject
= AdapterObject
;
1977 DeviceHeader
->MaxMappingsByteCount
= MaxMappingsByteCount
;
1978 DeviceHeader
->MappingTableStride
= MappingTableStride
;
1988 KsGetBusEnumIdentifier(
1993 return STATUS_UNSUCCESSFUL
;
2002 KsGetBusEnumParentFDOFromChildPDO(
2003 IN PDEVICE_OBJECT DeviceObject
,
2004 OUT PDEVICE_OBJECT
*FunctionalDeviceObject
)
2007 return STATUS_UNSUCCESSFUL
;
2016 KsGetBusEnumPnpDeviceObject(
2017 IN PDEVICE_OBJECT DeviceObject
,
2018 IN PDEVICE_OBJECT
*PnpDeviceObject
)
2021 return STATUS_UNSUCCESSFUL
;
2033 PKSBASIC_HEADER BasicHeader
;
2035 /* get the basic header */
2036 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
2038 /* type has to be either a device or a filter factory */
2039 ASSERT(BasicHeader
->Type
== KsObjectTypeDevice
|| BasicHeader
->Type
== KsObjectTypeFilterFactory
);
2041 return (PVOID
)BasicHeader
->FirstChild
.Filter
;
2053 PKSBASIC_HEADER BasicHeader
;
2055 /* get the basic header */
2056 BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
2058 ASSERT(BasicHeader
->Type
== KsObjectTypeDevice
|| BasicHeader
->Type
== KsObjectTypeFilterFactory
||
2059 BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
2061 return (PVOID
)BasicHeader
->Next
.Pin
;
2070 KsInstallBusEnumInterface(
2074 return STATUS_UNSUCCESSFUL
;
2083 KsIsBusEnumChildDevice(
2084 IN PDEVICE_OBJECT DeviceObject
,
2085 OUT PBOOLEAN ChildDevice
)
2088 return STATUS_UNSUCCESSFUL
;
2093 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2094 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2096 ULONG Index
, SubIndex
, Count
;
2099 if (!AutomationTableA
)
2100 return AutomationTableB
->MethodSetsCount
;
2102 if (!AutomationTableB
)
2103 return AutomationTableA
->MethodSetsCount
;
2106 DPRINT("AutomationTableA MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableA
->MethodItemSize
, AutomationTableA
->MethodSetsCount
);
2107 DPRINT("AutomationTableB MethodItemSize %lu MethodSetsCount %lu\n", AutomationTableB
->MethodItemSize
, AutomationTableB
->MethodSetsCount
);
2109 if (AutomationTableA
->MethodItemSize
&& AutomationTableB
->MethodItemSize
)
2112 ASSERT(AutomationTableA
->MethodItemSize
== AutomationTableB
->MethodItemSize
);
2115 /* now iterate all property sets and compare their guids */
2116 Count
= AutomationTableA
->MethodSetsCount
;
2118 for(Index
= 0; Index
< AutomationTableB
->MethodSetsCount
; Index
++)
2120 /* set found to false */
2123 for(SubIndex
= 0; SubIndex
< AutomationTableA
->MethodSetsCount
; SubIndex
++)
2125 if (IsEqualGUIDAligned(AutomationTableB
->MethodSets
[Index
].Set
, AutomationTableA
->MethodSets
[SubIndex
].Set
))
2127 /* same property set found */
2142 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2143 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2145 ULONG Index
, SubIndex
, Count
;
2148 if (!AutomationTableA
)
2149 return AutomationTableB
->EventSetsCount
;
2151 if (!AutomationTableB
)
2152 return AutomationTableA
->EventSetsCount
;
2154 DPRINT("AutomationTableA EventItemSize %lu EventSetsCount %lu\n", AutomationTableA
->EventItemSize
, AutomationTableA
->EventSetsCount
);
2155 DPRINT("AutomationTableB EventItemSize %lu EventSetsCount %lu\n", AutomationTableB
->EventItemSize
, AutomationTableB
->EventSetsCount
);
2157 if (AutomationTableA
->EventItemSize
&& AutomationTableB
->EventItemSize
)
2160 ASSERT(AutomationTableA
->EventItemSize
== AutomationTableB
->EventItemSize
);
2163 /* now iterate all Event sets and compare their guids */
2164 Count
= AutomationTableA
->EventSetsCount
;
2166 for(Index
= 0; Index
< AutomationTableB
->EventSetsCount
; Index
++)
2168 /* set found to false */
2171 for(SubIndex
= 0; SubIndex
< AutomationTableA
->EventSetsCount
; SubIndex
++)
2173 if (IsEqualGUIDAligned(AutomationTableB
->EventSets
[Index
].Set
, AutomationTableA
->EventSets
[SubIndex
].Set
))
2175 /* same Event set found */
2190 KspCountPropertySets(
2191 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2192 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2194 ULONG Index
, SubIndex
, Count
;
2197 if (!AutomationTableA
)
2198 return AutomationTableB
->PropertySetsCount
;
2200 if (!AutomationTableB
)
2201 return AutomationTableA
->PropertySetsCount
;
2204 DPRINT("AutomationTableA PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableA
->PropertyItemSize
, AutomationTableA
->PropertySetsCount
);
2205 DPRINT("AutomationTableB PropertyItemSize %lu PropertySetsCount %lu\n", AutomationTableB
->PropertyItemSize
, AutomationTableB
->PropertySetsCount
);
2206 ASSERT(AutomationTableA
->PropertyItemSize
== AutomationTableB
->PropertyItemSize
);
2208 /* now iterate all property sets and compare their guids */
2209 Count
= AutomationTableA
->PropertySetsCount
;
2211 for(Index
= 0; Index
< AutomationTableB
->PropertySetsCount
; Index
++)
2213 /* set found to false */
2216 for(SubIndex
= 0; SubIndex
< AutomationTableA
->PropertySetsCount
; SubIndex
++)
2218 if (IsEqualGUIDAligned(AutomationTableB
->PropertySets
[Index
].Set
, AutomationTableA
->PropertySets
[SubIndex
].Set
))
2220 /* same property set found */
2235 OUT PKSAUTOMATION_TABLE Table
,
2236 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2237 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2239 ULONG Index
, SubIndex
, Count
;
2242 if (!AutomationTableA
)
2244 /* copy of property set */
2245 RtlMoveMemory((PVOID
)Table
->MethodSets
, AutomationTableB
->MethodSets
, sizeof(KSMETHOD_SET
) * AutomationTableB
->MethodSetsCount
);
2246 return STATUS_SUCCESS
;
2248 else if (!AutomationTableB
)
2250 /* copy of property set */
2251 RtlMoveMemory((PVOID
)Table
->MethodSets
, AutomationTableA
->MethodSets
, sizeof(KSMETHOD_SET
) * AutomationTableA
->MethodSetsCount
);
2252 return STATUS_SUCCESS
;
2255 /* first copy all property items from dominant table */
2256 RtlMoveMemory((PVOID
)Table
->MethodSets
, AutomationTableA
->MethodSets
, sizeof(KSMETHOD_SET
) * AutomationTableA
->MethodSetsCount
);
2258 Count
= AutomationTableA
->MethodSetsCount
;
2260 /* now copy entries which arent available in the dominant table */
2261 for(Index
= 0; Index
< AutomationTableB
->MethodSetsCount
; Index
++)
2263 /* set found to false */
2266 for(SubIndex
= 0; SubIndex
< AutomationTableA
->MethodSetsCount
; SubIndex
++)
2268 if (IsEqualGUIDAligned(AutomationTableB
->MethodSets
[Index
].Set
, AutomationTableA
->MethodSets
[SubIndex
].Set
))
2270 /* same property set found */
2278 /* copy new property item set */
2279 RtlMoveMemory((PVOID
)&Table
->MethodSets
[Count
], &AutomationTableB
->MethodSets
[Index
], sizeof(KSMETHOD_SET
));
2284 return STATUS_SUCCESS
;
2289 KspCopyPropertySets(
2290 OUT PKSAUTOMATION_TABLE Table
,
2291 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2292 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2294 ULONG Index
, SubIndex
, Count
;
2297 if (!AutomationTableA
)
2299 /* copy of property set */
2300 RtlMoveMemory((PVOID
)Table
->PropertySets
, AutomationTableB
->PropertySets
, sizeof(KSPROPERTY_SET
) * AutomationTableB
->PropertySetsCount
);
2301 return STATUS_SUCCESS
;
2303 else if (!AutomationTableB
)
2305 /* copy of property set */
2306 RtlMoveMemory((PVOID
)Table
->PropertySets
, AutomationTableA
->PropertySets
, sizeof(KSPROPERTY_SET
) * AutomationTableA
->PropertySetsCount
);
2307 return STATUS_SUCCESS
;
2310 /* first copy all property items from dominant table */
2311 RtlMoveMemory((PVOID
)Table
->PropertySets
, AutomationTableA
->PropertySets
, sizeof(KSPROPERTY_SET
) * AutomationTableA
->PropertySetsCount
);
2313 Count
= AutomationTableA
->PropertySetsCount
;
2315 /* now copy entries which arent available in the dominant table */
2316 for(Index
= 0; Index
< AutomationTableB
->PropertySetsCount
; Index
++)
2318 /* set found to false */
2321 for(SubIndex
= 0; SubIndex
< AutomationTableA
->PropertySetsCount
; SubIndex
++)
2323 if (IsEqualGUIDAligned(AutomationTableB
->PropertySets
[Index
].Set
, AutomationTableA
->PropertySets
[SubIndex
].Set
))
2325 /* same property set found */
2333 /* copy new property item set */
2334 RtlMoveMemory((PVOID
)&Table
->PropertySets
[Count
], &AutomationTableB
->PropertySets
[Index
], sizeof(KSPROPERTY_SET
));
2339 return STATUS_SUCCESS
;
2344 OUT PKSAUTOMATION_TABLE Table
,
2345 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2346 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
)
2348 ULONG Index
, SubIndex
, Count
;
2351 if (!AutomationTableA
)
2353 /* copy of Event set */
2354 RtlMoveMemory((PVOID
)Table
->EventSets
, AutomationTableB
->EventSets
, sizeof(KSEVENT_SET
) * AutomationTableB
->EventSetsCount
);
2355 return STATUS_SUCCESS
;
2357 else if (!AutomationTableB
)
2359 /* copy of Event set */
2360 RtlMoveMemory((PVOID
)Table
->EventSets
, AutomationTableA
->EventSets
, sizeof(KSEVENT_SET
) * AutomationTableA
->EventSetsCount
);
2361 return STATUS_SUCCESS
;
2364 /* first copy all Event items from dominant table */
2365 RtlMoveMemory((PVOID
)Table
->EventSets
, AutomationTableA
->EventSets
, sizeof(KSEVENT_SET
) * AutomationTableA
->EventSetsCount
);
2367 Count
= AutomationTableA
->EventSetsCount
;
2369 /* now copy entries which arent available in the dominant table */
2370 for(Index
= 0; Index
< AutomationTableB
->EventSetsCount
; Index
++)
2372 /* set found to false */
2375 for(SubIndex
= 0; SubIndex
< AutomationTableA
->EventSetsCount
; SubIndex
++)
2377 if (IsEqualGUIDAligned(AutomationTableB
->EventSets
[Index
].Set
, AutomationTableA
->EventSets
[SubIndex
].Set
))
2379 /* same Event set found */
2387 /* copy new Event item set */
2388 RtlMoveMemory((PVOID
)&Table
->EventSets
[Count
], &AutomationTableB
->EventSets
[Index
], sizeof(KSEVENT_SET
));
2393 return STATUS_SUCCESS
;
2402 KsMergeAutomationTables(
2403 OUT PKSAUTOMATION_TABLE
*AutomationTableAB
,
2404 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL
,
2405 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL
,
2406 IN KSOBJECT_BAG Bag OPTIONAL
)
2408 PKSAUTOMATION_TABLE Table
;
2409 NTSTATUS Status
= STATUS_SUCCESS
;
2411 if (!AutomationTableA
&& !AutomationTableB
)
2413 /* nothing to merge */
2414 return STATUS_SUCCESS
;
2417 /* allocate an automation table */
2418 Table
= AllocateItem(NonPagedPool
, sizeof(KSAUTOMATION_TABLE
));
2420 return STATUS_INSUFFICIENT_RESOURCES
;
2424 /* add table to object bag */
2425 Status
= KsAddItemToObjectBag(Bag
, Table
, NULL
);
2426 /* check for success */
2427 if (!NT_SUCCESS(Status
))
2435 /* count property sets */
2436 Table
->PropertySetsCount
= KspCountPropertySets(AutomationTableA
, AutomationTableB
);
2438 if (Table
->PropertySetsCount
)
2440 if (AutomationTableA
)
2442 /* use item size from dominant automation table */
2443 Table
->PropertyItemSize
= AutomationTableA
->PropertyItemSize
;
2447 /* use item size from 2nd automation table */
2448 Table
->PropertyItemSize
= AutomationTableB
->PropertyItemSize
;
2451 /* now allocate the property sets */
2452 Table
->PropertySets
= AllocateItem(NonPagedPool
, sizeof(KSPROPERTY_SET
) * Table
->PropertySetsCount
);
2454 if (!Table
->PropertySets
)
2456 /* not enough memory */
2462 /* add set to property bag */
2463 Status
= KsAddItemToObjectBag(Bag
, (PVOID
)Table
->PropertySets
, NULL
);
2464 /* check for success */
2465 if (!NT_SUCCESS(Status
))
2471 /* now copy the property sets */
2472 Status
= KspCopyPropertySets(Table
, AutomationTableA
, AutomationTableB
);
2473 if(!NT_SUCCESS(Status
))
2478 /* now count the method sets */
2479 Table
->MethodSetsCount
= KspCountMethodSets(AutomationTableA
, AutomationTableB
);
2481 if (Table
->MethodSetsCount
)
2483 if (AutomationTableA
)
2485 /* use item size from dominant automation table */
2486 Table
->MethodItemSize
= AutomationTableA
->MethodItemSize
;
2490 /* use item size from 2nd automation table */
2491 Table
->MethodItemSize
= AutomationTableB
->MethodItemSize
;
2494 /* now allocate the property sets */
2495 Table
->MethodSets
= AllocateItem(NonPagedPool
, sizeof(KSMETHOD_SET
) * Table
->MethodSetsCount
);
2497 if (!Table
->MethodSets
)
2499 /* not enough memory */
2505 /* add set to property bag */
2506 Status
= KsAddItemToObjectBag(Bag
, (PVOID
)Table
->MethodSets
, NULL
);
2507 /* check for success */
2508 if (!NT_SUCCESS(Status
))
2514 /* now copy the property sets */
2515 Status
= KspCopyMethodSets(Table
, AutomationTableA
, AutomationTableB
);
2516 if(!NT_SUCCESS(Status
))
2521 /* now count the event sets */
2522 Table
->EventSetsCount
= KspCountEventSets(AutomationTableA
, AutomationTableB
);
2524 if (Table
->EventSetsCount
)
2526 if (AutomationTableA
)
2528 /* use item size from dominant automation table */
2529 Table
->EventItemSize
= AutomationTableA
->EventItemSize
;
2533 /* use item size from 2nd automation table */
2534 Table
->EventItemSize
= AutomationTableB
->EventItemSize
;
2537 /* now allocate the property sets */
2538 Table
->EventSets
= AllocateItem(NonPagedPool
, sizeof(KSEVENT_SET
) * Table
->EventSetsCount
);
2540 if (!Table
->EventSets
)
2542 /* not enough memory */
2548 /* add set to property bag */
2549 Status
= KsAddItemToObjectBag(Bag
, (PVOID
)Table
->EventSets
, NULL
);
2550 /* check for success */
2551 if (!NT_SUCCESS(Status
))
2557 /* now copy the property sets */
2558 Status
= KspCopyEventSets(Table
, AutomationTableA
, AutomationTableB
);
2559 if(!NT_SUCCESS(Status
))
2564 *AutomationTableAB
= Table
;
2573 if (Table
->PropertySets
)
2575 /* clean property sets */
2576 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, (PVOID
)Table
->PropertySets
, TRUE
)))
2577 FreeItem((PVOID
)Table
->PropertySets
);
2580 if (Table
->MethodSets
)
2582 /* clean property sets */
2583 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, (PVOID
)Table
->MethodSets
, TRUE
)))
2584 FreeItem((PVOID
)Table
->MethodSets
);
2587 if (Table
->EventSets
)
2589 /* clean property sets */
2590 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, (PVOID
)Table
->EventSets
, TRUE
)))
2591 FreeItem((PVOID
)Table
->EventSets
);
2594 if (!Bag
|| !NT_SUCCESS(KsRemoveItemFromObjectBag(Bag
, Table
, TRUE
)))
2598 return STATUS_INSUFFICIENT_RESOURCES
;
2607 KsServiceBusEnumCreateRequest(
2608 IN PDEVICE_OBJECT DeviceObject
,
2612 return STATUS_UNSUCCESSFUL
;
2622 KsServiceBusEnumPnpRequest(
2623 IN PDEVICE_OBJECT DeviceObject
,
2627 return STATUS_UNSUCCESSFUL
;
2632 KspRemoveBusInterface(
2635 PKSREMOVE_BUS_INTERFACE_CTX Context
=(PKSREMOVE_BUS_INTERFACE_CTX
)Ctx
;
2638 * get SWENUM_INSTALL_INTERFACE struct
2639 * open device key and delete the keys
2645 Context
->Irp
->IoStatus
.Status
= STATUS_NOT_IMPLEMENTED
;
2648 /* signal completion */
2649 KeSetEvent(&Context
->Event
, IO_NO_INCREMENT
, FALSE
);
2658 KsRemoveBusEnumInterface(
2661 KPROCESSOR_MODE Mode
;
2663 KSREMOVE_BUS_INTERFACE_CTX Ctx
;
2664 WORK_QUEUE_ITEM WorkItem
;
2666 /* get previous mode */
2667 Mode
= ExGetPreviousMode();
2669 /* convert to luid */
2670 luid
= RtlConvertUlongToLuid(SE_LOAD_DRIVER_PRIVILEGE
);
2672 /* perform access check */
2673 if (!SeSinglePrivilegeCheck(luid
, Mode
))
2675 /* insufficient privileges */
2676 return STATUS_PRIVILEGE_NOT_HELD
;
2678 /* initialize event */
2679 KeInitializeEvent(&Ctx
.Event
, NotificationEvent
, FALSE
);
2681 /* store irp in ctx */
2684 /* initialize work item */
2685 ExInitializeWorkItem(&WorkItem
, KspRemoveBusInterface
, (PVOID
)&Ctx
);
2687 /* now queue the work item */
2688 ExQueueWorkItem(&WorkItem
, DelayedWorkQueue
);
2690 /* wait for completion */
2691 KeWaitForSingleObject(&Ctx
.Event
, Executive
, KernelMode
, FALSE
, NULL
);
2694 return Ctx
.Irp
->IoStatus
.Status
;
2705 KsRegisterAggregatedClientUnknown(
2707 IN PUNKNOWN ClientUnknown
)
2709 PKSBASIC_HEADER BasicHeader
= (PKSBASIC_HEADER
)((ULONG_PTR
)Object
- sizeof(KSBASIC_HEADER
));
2712 ASSERT(BasicHeader
->Type
== KsObjectTypeDevice
|| BasicHeader
->Type
== KsObjectTypeFilterFactory
||
2713 BasicHeader
->Type
== KsObjectTypeFilter
|| BasicHeader
->Type
== KsObjectTypePin
);
2715 if (BasicHeader
->ClientAggregate
)
2717 /* release existing aggregate */
2718 BasicHeader
->ClientAggregate
->lpVtbl
->Release(BasicHeader
->ClientAggregate
);
2721 /* increment reference count */
2722 ClientUnknown
->lpVtbl
->AddRef(ClientUnknown
);
2724 /* store client aggregate */
2725 BasicHeader
->ClientAggregate
= ClientUnknown
;
2727 /* return objects outer unknown */
2728 return BasicHeader
->OuterUnknown
;
2736 KsRegisterFilterWithNoKSPins(
2737 IN PDEVICE_OBJECT DeviceObject
,
2738 IN
const GUID
* InterfaceClassGUID
,
2740 IN BOOL
* PinDirection
,
2741 IN KSPIN_MEDIUM
* MediumList
,
2742 IN GUID
* CategoryList OPTIONAL
)
2746 PWSTR SymbolicLinkList
;
2749 UNICODE_STRING InterfaceString
;
2750 //UNICODE_STRING FilterData = RTL_CONSTANT_STRING(L"FilterData");
2752 if (!InterfaceClassGUID
|| !PinCount
|| !PinDirection
|| !MediumList
)
2754 /* all these parameters are required */
2755 return STATUS_INVALID_PARAMETER
;
2758 /* calculate filter data value size */
2759 Size
= PinCount
* sizeof(KSPIN_MEDIUM
);
2762 /* add category list */
2763 Size
+= PinCount
* sizeof(GUID
);
2766 /* FIXME generate filter data blob */
2769 /* get symbolic link list */
2770 Status
= IoGetDeviceInterfaces(InterfaceClassGUID
, DeviceObject
, DEVICE_INTERFACE_INCLUDE_NONACTIVE
, &SymbolicLinkList
);
2771 if (NT_SUCCESS(Status
))
2773 /* initialize first symbolic link */
2774 RtlInitUnicodeString(&InterfaceString
, SymbolicLinkList
);
2776 /* open first device interface registry key */
2777 Status
= IoOpenDeviceInterfaceRegistryKey(&InterfaceString
, GENERIC_WRITE
, &hKey
);
2779 if (NT_SUCCESS(Status
))
2781 /* write filter data */
2782 //Status = ZwSetValueKey(hKey, &FilterData, 0, REG_BINARY, Buffer, Size);
2790 /* update medium cache */
2791 for(Index
= 0; Index
< PinCount
; Index
++)
2793 KsCacheMedium(&InterfaceString
, &MediumList
[Index
], PinDirection
[Index
]);
2797 /* free the symbolic link list */
2798 ExFreePool(SymbolicLinkList
);