- Implement KsAcquireResetValue, KsCompletePendingRequest, KsAllocateExtraData
[reactos.git] / reactos / drivers / ksfilter / ks / api.c
1 /*
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
7 */
8
9
10 #include "priv.h"
11
12 /*
13 @implemented
14 */
15 KSDDKAPI
16 NTSTATUS
17 NTAPI
18 KsAcquireResetValue(
19 IN PIRP Irp,
20 OUT KSRESET* ResetValue)
21 {
22 PIO_STACK_LOCATION IoStack;
23 KSRESET* Value;
24 NTSTATUS Status = STATUS_SUCCESS;
25
26 /* get current irp stack */
27 IoStack = IoGetCurrentIrpStackLocation(Irp);
28
29 /* check if there is reset value provided */
30 if (IoStack->Parameters.DeviceIoControl.InputBufferLength < sizeof(KSRESET))
31 return STATUS_INVALID_PARAMETER;
32
33 if (Irp->RequestorMode == UserMode)
34 {
35 /* need to probe the buffer */
36 _SEH2_TRY
37 {
38 ProbeForRead(IoStack->Parameters.DeviceIoControl.Type3InputBuffer, sizeof(KSRESET), sizeof(UCHAR));
39 Value = (KSRESET*)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
40 *ResetValue = *Value;
41 }
42 _SEH2_EXCEPT(EXCEPTION_EXECUTE_HANDLER)
43 {
44 /* Exception, get the error code */
45 Status = _SEH2_GetExceptionCode();
46 }
47 _SEH2_END;
48 }
49 else
50 {
51 Value = (KSRESET*)IoStack->Parameters.DeviceIoControl.Type3InputBuffer;
52 *ResetValue = *Value;
53 }
54
55 return Status;
56 }
57
58 /*
59 @implemented
60 */
61 KSDDKAPI
62 VOID
63 NTAPI
64 KsAcquireDeviceSecurityLock(
65 IN KSDEVICE_HEADER DevHeader,
66 IN BOOLEAN Exclusive)
67 {
68 NTSTATUS Status;
69 PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader;
70
71 KeEnterCriticalRegion();
72
73 if (Exclusive)
74 {
75 Status = ExAcquireResourceExclusiveLite(&Header->SecurityLock, TRUE);
76 }
77 else
78 {
79 Status = ExAcquireResourceSharedLite(&Header->SecurityLock, TRUE);
80 }
81 }
82
83 /*
84 @implemented
85 */
86 KSDDKAPI
87 VOID
88 NTAPI
89 KsReleaseDeviceSecurityLock(
90 IN KSDEVICE_HEADER DevHeader)
91 {
92 PKSIDEVICE_HEADER Header = (PKSIDEVICE_HEADER)DevHeader;
93
94 ExReleaseResourceLite(&Header->SecurityLock);
95 KeLeaveCriticalRegion();
96 }
97
98 /*
99 @implemented
100 */
101 KSDDKAPI
102 NTSTATUS
103 NTAPI
104 KsDefaultDispatchPnp(
105 IN PDEVICE_OBJECT DeviceObject,
106 IN PIRP Irp)
107 {
108 PDEVICE_EXTENSION DeviceExtension;
109 PKSIDEVICE_HEADER DeviceHeader;
110 PIO_STACK_LOCATION IoStack;
111 PDEVICE_OBJECT PnpDeviceObject;
112 NTSTATUS Status;
113 ULONG MinorFunction;
114
115 /* get current irp stack */
116 IoStack = IoGetCurrentIrpStackLocation(Irp);
117
118 /* caller wants to add the target device */
119 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
120
121 /* get device header */
122 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
123
124 /* backup PnpBaseObject */
125 PnpDeviceObject = DeviceHeader->PnpDeviceObject;
126
127
128 /* backup minor function code */
129 MinorFunction = IoStack->MinorFunction;
130
131 if(MinorFunction == IRP_MN_REMOVE_DEVICE)
132 {
133 /* remove the device */
134 KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader);
135 }
136
137 /* skip current irp stack */
138 IoSkipCurrentIrpStackLocation(Irp);
139
140 /* call attached pnp device object */
141 Status = IoCallDriver(PnpDeviceObject, Irp);
142
143 if (MinorFunction == IRP_MN_REMOVE_DEVICE)
144 {
145 /* time is over */
146 IoDetachDevice(PnpDeviceObject);
147 /* delete device */
148 IoDeleteDevice(DeviceObject);
149 }
150 /* done */
151 return Status;
152 }
153
154 /*
155 @implemented
156 */
157 KSDDKAPI
158 NTSTATUS
159 NTAPI
160 KsDefaultDispatchPower(
161 IN PDEVICE_OBJECT DeviceObject,
162 IN PIRP Irp)
163 {
164 PDEVICE_EXTENSION DeviceExtension;
165 PKSIDEVICE_HEADER DeviceHeader;
166 PKSIOBJECT_HEADER ObjectHeader;
167 PIO_STACK_LOCATION IoStack;
168 PLIST_ENTRY ListEntry;
169 NTSTATUS Status;
170
171 /* get current irp stack */
172 IoStack = IoGetCurrentIrpStackLocation(Irp);
173
174 /* caller wants to add the target device */
175 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
176
177 /* get device header */
178 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
179
180 /* FIXME locks */
181
182 /* loop our power dispatch list and call registered notification functions */
183 ListEntry = DeviceHeader->PowerDispatchList.Flink;
184 /* let's go */
185 while(ListEntry != &DeviceHeader->PowerDispatchList)
186 {
187 /* get object header */
188 ObjectHeader = (PKSIOBJECT_HEADER)CONTAINING_RECORD(ListEntry, KSIOBJECT_HEADER, PowerDispatchEntry);
189
190 /* does it have still a cb */
191 if (ObjectHeader->PowerDispatch)
192 {
193 /* call the power cb */
194 Status = ObjectHeader->PowerDispatch(ObjectHeader->PowerContext, Irp);
195 ASSERT(NT_SUCCESS(Status));
196 }
197
198 /* iterate to next entry */
199 ListEntry = ListEntry->Flink;
200 }
201
202 /* start next power irp */
203 PoStartNextPowerIrp(Irp);
204
205 /* skip current irp stack location */
206 IoSkipCurrentIrpStackLocation(Irp);
207
208 /* let's roll */
209 Status = PoCallDriver(DeviceHeader->PnpDeviceObject, Irp);
210
211 /* done */
212 return Status;
213 }
214
215 /*
216 @implemented
217 */
218 KSDDKAPI
219 NTSTATUS
220 NTAPI
221 KsDefaultForwardIrp(
222 IN PDEVICE_OBJECT DeviceObject,
223 IN PIRP Irp)
224 {
225 PDEVICE_EXTENSION DeviceExtension;
226 PKSIDEVICE_HEADER DeviceHeader;
227 PIO_STACK_LOCATION IoStack;
228 NTSTATUS Status;
229
230 /* get current irp stack */
231 IoStack = IoGetCurrentIrpStackLocation(Irp);
232
233 /* caller wants to add the target device */
234 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
235
236 /* get device header */
237 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
238
239 /* forward the request to the PDO */
240 Status = IoCallDriver(DeviceHeader->PnpDeviceObject, Irp);
241
242 return Status;
243 }
244
245 /*
246 @implemented
247 */
248 KSDDKAPI
249 VOID
250 NTAPI
251 KsSetDevicePnpAndBaseObject(
252 IN KSDEVICE_HEADER Header,
253 IN PDEVICE_OBJECT PnpDeviceObject,
254 IN PDEVICE_OBJECT BaseDevice)
255 {
256 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
257
258 DeviceHeader->PnpDeviceObject = PnpDeviceObject;
259 DeviceHeader->BaseDevice = BaseDevice;
260 }
261
262 /*
263 @implemented
264 */
265 KSDDKAPI
266 PDEVICE_OBJECT
267 NTAPI
268 KsQueryDevicePnpObject(
269 IN KSDEVICE_HEADER Header)
270 {
271 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
272
273 /* return PnpDeviceObject */
274 return DeviceHeader->PnpDeviceObject;
275
276 }
277
278 /*
279 @implemented
280 */
281 KSDDKAPI
282 ACCESS_MASK
283 NTAPI
284 KsQueryObjectAccessMask(
285 IN KSOBJECT_HEADER Header)
286 {
287 PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header;
288
289 /* return access mask */
290 return ObjectHeader->AccessMask;
291
292 }
293
294 /*
295 @unimplemented
296 */
297 KSDDKAPI
298 VOID
299 NTAPI
300 KsRecalculateStackDepth(
301 IN KSDEVICE_HEADER Header,
302 IN BOOLEAN ReuseStackLocation)
303 {
304 UNIMPLEMENTED;
305 }
306
307
308 /*
309 @implemented
310 */
311 KSDDKAPI
312 VOID
313 NTAPI
314 KsSetTargetState(
315 IN KSOBJECT_HEADER Header,
316 IN KSTARGET_STATE TargetState)
317 {
318 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)Header;
319
320 /* set target state */
321 DeviceHeader->TargetState = TargetState;
322 }
323
324 /*
325 @implemented
326 */
327 KSDDKAPI
328 VOID
329 NTAPI
330 KsSetTargetDeviceObject(
331 IN KSOBJECT_HEADER Header,
332 IN PDEVICE_OBJECT TargetDevice OPTIONAL)
333 {
334 PDEVICE_EXTENSION DeviceExtension;
335 PKSIDEVICE_HEADER DeviceHeader;
336 PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header;
337
338 if(ObjectHeader->TargetDevice)
339 {
340 /* there is already a target device set */
341 if (!TargetDevice)
342 {
343 /* caller wants to remove the target device */
344 DeviceExtension = (PDEVICE_EXTENSION)ObjectHeader->TargetDevice->DeviceExtension;
345
346 /* get device header */
347 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
348
349 /* acquire lock */
350 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE);
351
352 /* remove entry */
353 RemoveEntryList(&ObjectHeader->TargetDeviceListEntry);
354
355 /* remove device pointer */
356 ObjectHeader->TargetDevice = NULL;
357
358 /* release lock */
359 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader);
360 }
361 }
362 else
363 {
364 /* no target device yet set */
365 if (TargetDevice)
366 {
367 /* caller wants to add the target device */
368 DeviceExtension = (PDEVICE_EXTENSION)TargetDevice->DeviceExtension;
369
370 /* get device header */
371 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
372
373 /* acquire lock */
374 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE);
375
376 /* insert list entry */
377 InsertTailList(&DeviceHeader->TargetDeviceList, &ObjectHeader->TargetDeviceListEntry);
378
379 /* store target device */
380 ObjectHeader->TargetDevice = TargetDevice;
381
382 /* release lock */
383 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader);
384 }
385 }
386
387 }
388
389 /*
390 @implemented
391 */
392 KSDDKAPI
393 VOID
394 NTAPI
395 KsSetPowerDispatch(
396 IN KSOBJECT_HEADER Header,
397 IN PFNKSCONTEXT_DISPATCH PowerDispatch OPTIONAL,
398 IN PVOID PowerContext OPTIONAL)
399 {
400 PDEVICE_EXTENSION DeviceExtension;
401 PKSIDEVICE_HEADER DeviceHeader;
402 PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header;
403
404 /* caller wants to add the target device */
405 DeviceExtension = (PDEVICE_EXTENSION)ObjectHeader->ParentDeviceObject->DeviceExtension;
406
407 /* get device header */
408 DeviceHeader = (PKSIDEVICE_HEADER)DeviceExtension->DeviceHeader;
409
410 /* acquire lock */
411 KsAcquireDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader, FALSE);
412
413 if (PowerDispatch)
414 {
415 /* add power dispatch entry */
416 InsertTailList(&DeviceHeader->PowerDispatchList, &ObjectHeader->PowerDispatchEntry);
417
418 /* store function and context */
419 ObjectHeader->PowerDispatch = PowerDispatch;
420 ObjectHeader->PowerContext = PowerContext;
421 }
422 else
423 {
424 /* remove power dispatch entry */
425 RemoveEntryList(&ObjectHeader->PowerDispatchEntry);
426
427 /* store function and context */
428 ObjectHeader->PowerDispatch = NULL;
429 ObjectHeader->PowerContext = NULL;
430
431 }
432
433 /* release lock */
434 KsReleaseDeviceSecurityLock((KSDEVICE_HEADER)DeviceHeader);
435 }
436
437
438 /*
439 @implemented
440 */
441 KSDDKAPI
442 PKSOBJECT_CREATE_ITEM
443 NTAPI
444 KsQueryObjectCreateItem(
445 IN KSOBJECT_HEADER Header)
446 {
447 PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER)Header;
448 return ObjectHeader->OriginalCreateItem;
449 }
450
451 NTSTATUS
452 KspAddCreateItemToList(
453 OUT PLIST_ENTRY ListHead,
454 IN ULONG ItemsCount,
455 IN PKSOBJECT_CREATE_ITEM ItemsList)
456 {
457 ULONG Index;
458 PCREATE_ITEM_ENTRY Entry;
459
460 /* add the items */
461 for(Index = 0; Index < ItemsCount; Index++)
462 {
463 /* allocate item */
464 Entry = AllocateItem(NonPagedPool, sizeof(CREATE_ITEM_ENTRY));
465 if (!Entry)
466 {
467 /* no memory */
468 return STATUS_INSUFFICIENT_RESOURCES;
469 }
470
471 /* initialize entry */
472 InitializeListHead(&Entry->ObjectItemList);
473 Entry->CreateItem = &ItemsList[Index];
474 Entry->ReferenceCount = 0;
475 Entry->ItemFreeCallback = NULL;
476
477 InsertTailList(ListHead, &Entry->Entry);
478 }
479 return STATUS_SUCCESS;
480 }
481
482 VOID
483 KspFreeCreateItems(
484 PLIST_ENTRY ListHead)
485 {
486 PCREATE_ITEM_ENTRY Entry;
487
488 while(!IsListEmpty(ListHead))
489 {
490 /* remove create item from list */
491 Entry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(RemoveHeadList(ListHead), CREATE_ITEM_ENTRY, Entry);
492
493 /* caller shouldnt have any references */
494 ASSERT(Entry->ReferenceCount == 0);
495 ASSERT(IsListEmpty(&Entry->ObjectItemList));
496
497 /* does the creator wish notification */
498 if (Entry->ItemFreeCallback)
499 {
500 /* notify creator */
501 Entry->ItemFreeCallback(Entry->CreateItem);
502 }
503
504 /* free create item entry */
505 FreeItem(Entry);
506 }
507
508 }
509
510 /*
511 @implemented
512 */
513 KSDDKAPI
514 NTSTATUS
515 NTAPI
516 KsAllocateDeviceHeader(
517 OUT KSDEVICE_HEADER* OutHeader,
518 IN ULONG ItemsCount,
519 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL)
520 {
521 NTSTATUS Status = STATUS_SUCCESS;
522 PKSIDEVICE_HEADER Header;
523
524 if (!OutHeader)
525 return STATUS_INVALID_PARAMETER;
526
527 /* allocate a device header */
528 Header = ExAllocatePoolWithTag(PagedPool, sizeof(KSIDEVICE_HEADER), TAG_DEVICE_HEADER);
529
530 /* check for success */
531 if (!Header)
532 return STATUS_INSUFFICIENT_RESOURCES;
533
534 /* clear all memory */
535 RtlZeroMemory(Header, sizeof(KSIDEVICE_HEADER));
536
537 /* initialize device mutex */
538 KeInitializeMutex(&Header->DeviceMutex, 0);
539
540 /* initialize target device list */
541 InitializeListHead(&Header->TargetDeviceList);
542 /* initialize power dispatch list */
543 InitializeListHead(&Header->PowerDispatchList);
544 /* initialize object bag lists */
545 InitializeListHead(&Header->ObjectBags);
546
547 /* initialize create item list */
548 InitializeListHead(&Header->ItemList);
549
550 /* initialize basic header */
551 Header->BasicHeader.Type = KsObjectTypeDevice;
552 Header->BasicHeader.KsDevice = &Header->KsDevice;
553 Header->BasicHeader.Parent.KsDevice = &Header->KsDevice;
554
555 /* are there any create items provided */
556 if (ItemsCount && ItemsList)
557 {
558 Status = KspAddCreateItemToList(&Header->ItemList, ItemsCount, ItemsList);
559
560 if (NT_SUCCESS(Status))
561 {
562 /* store item count */
563 Header->ItemListCount = ItemsCount;
564 }
565 else
566 {
567 /* release create items */
568 KspFreeCreateItems(&Header->ItemList);
569 }
570 }
571
572 /* store result */
573 *OutHeader = Header;
574
575 return Status;
576 }
577
578 /*
579 @implemented
580 */
581 KSDDKAPI
582 VOID
583 NTAPI
584 KsFreeDeviceHeader(
585 IN KSDEVICE_HEADER DevHeader)
586 {
587 PKSIDEVICE_HEADER Header;
588
589 Header = (PKSIDEVICE_HEADER)DevHeader;
590
591 if (!DevHeader)
592 return;
593
594 KspFreeCreateItems(&Header->ItemList);
595 ExFreePoolWithTag(Header, TAG_DEVICE_HEADER);
596 }
597
598 /*
599 @implemented
600 */
601 KSDDKAPI
602 NTSTATUS
603 NTAPI
604 KsAllocateObjectHeader(
605 OUT KSOBJECT_HEADER *Header,
606 IN ULONG ItemsCount,
607 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL,
608 IN PIRP Irp,
609 IN KSDISPATCH_TABLE* Table)
610 {
611 PIO_STACK_LOCATION IoStack;
612 PDEVICE_EXTENSION DeviceExtension;
613 PKSIDEVICE_HEADER DeviceHeader;
614 PKSIOBJECT_HEADER ObjectHeader;
615 PKSOBJECT_CREATE_ITEM CreateItem;
616 NTSTATUS Status;
617
618 if (!Header)
619 return STATUS_INVALID_PARAMETER_1;
620
621 if (!Irp)
622 return STATUS_INVALID_PARAMETER_4;
623
624 if (!Table)
625 return STATUS_INVALID_PARAMETER_5;
626
627 /* get current stack location */
628 IoStack = IoGetCurrentIrpStackLocation(Irp);
629 /* get device extension */
630 DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
631 /* get device header */
632 DeviceHeader = DeviceExtension->DeviceHeader;
633
634 /* sanity check */
635 ASSERT(IoStack->FileObject);
636 /* check for an file object */
637
638 /* allocate the object header */
639 ObjectHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(KSIOBJECT_HEADER), TAG_DEVICE_HEADER);
640 if (!ObjectHeader)
641 return STATUS_INSUFFICIENT_RESOURCES;
642
643 /* initialize object header */
644 RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER));
645
646 /* initialize create item list */
647 InitializeListHead(&ObjectHeader->ItemList);
648
649 /* get create item */
650 CreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
651
652 /* do we have a name */
653 if (IoStack->FileObject->FileName.Buffer)
654 {
655 /* copy object class */
656 ObjectHeader->ObjectClass.MaximumLength = IoStack->FileObject->FileName.MaximumLength;
657 ObjectHeader->ObjectClass.Buffer = ExAllocatePoolWithTag(NonPagedPool, ObjectHeader->ObjectClass.MaximumLength, TAG_DEVICE_HEADER);
658 if (!ObjectHeader->ObjectClass.Buffer)
659 {
660 ExFreePoolWithTag(ObjectHeader, TAG_DEVICE_HEADER);
661 return STATUS_INSUFFICIENT_RESOURCES;
662 }
663 RtlCopyUnicodeString(&ObjectHeader->ObjectClass, &IoStack->FileObject->FileName);
664 }
665
666 /* copy dispatch table */
667 RtlCopyMemory(&ObjectHeader->DispatchTable, Table, sizeof(KSDISPATCH_TABLE));
668
669 /* store create items */
670 if (ItemsCount && ItemsList)
671 {
672 Status = KspAddCreateItemToList(&ObjectHeader->ItemList, ItemsCount, ItemsList);
673
674 if (NT_SUCCESS(Status))
675 {
676 /* store item count */
677 ObjectHeader->ItemListCount = ItemsCount;
678 }
679 else
680 {
681 /* destroy header*/
682 KsFreeObjectHeader(ObjectHeader);
683 return Status;
684 }
685 }
686 /* store the object in the file object */
687 ASSERT(IoStack->FileObject->FsContext == NULL);
688 IoStack->FileObject->FsContext = ObjectHeader;
689
690 /* store parent device */
691 ObjectHeader->ParentDeviceObject = IoGetRelatedDeviceObject(IoStack->FileObject);
692
693 /* store originating create item */
694 ObjectHeader->OriginalCreateItem = KSCREATE_ITEM_IRP_STORAGE(Irp);
695
696 /* FIXME store access mask see KsQueryObjectAccessMask */
697 ObjectHeader->AccessMask = IoStack->Parameters.Create.SecurityContext->DesiredAccess;
698
699
700 /* store result */
701 *Header = ObjectHeader;
702
703 DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectHeader->ObjectClass.Buffer, IoStack->FileObject, ObjectHeader);
704
705 return STATUS_SUCCESS;
706
707 }
708
709 /*
710 @implemented
711 */
712 KSDDKAPI
713 VOID
714 NTAPI
715 KsFreeObjectHeader(
716 IN PVOID Header)
717 {
718 PKSIOBJECT_HEADER ObjectHeader = (PKSIOBJECT_HEADER) Header;
719
720 if (ObjectHeader->ObjectClass.Buffer)
721 {
722 /* release object class buffer */
723 ExFreePoolWithTag(ObjectHeader->ObjectClass.Buffer, TAG_DEVICE_HEADER);
724 }
725
726 if (ObjectHeader->Unknown)
727 {
728 /* release associated object */
729 ObjectHeader->Unknown->lpVtbl->Release(ObjectHeader->Unknown);
730 }
731
732 /* free create items */
733 KspFreeCreateItems(&ObjectHeader->ItemList);
734
735 /* free object header */
736 ExFreePoolWithTag(ObjectHeader, TAG_DEVICE_HEADER);
737
738 }
739
740 NTSTATUS
741 KspAddObjectCreateItemToList(
742 PLIST_ENTRY ListHead,
743 IN PDRIVER_DISPATCH Create,
744 IN PVOID Context,
745 IN PWCHAR ObjectClass,
746 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
747 {
748 PLIST_ENTRY Entry;
749 PCREATE_ITEM_ENTRY CreateEntry;
750
751 /* point to first entry */
752 Entry = ListHead->Flink;
753
754 while(Entry != ListHead)
755 {
756 /* get create entry */
757 CreateEntry = (PCREATE_ITEM_ENTRY)CONTAINING_RECORD(Entry, CREATE_ITEM_ENTRY, Entry);
758 /* if the create item has no create routine, then it is free to use */
759 if (CreateEntry->CreateItem->Create == NULL)
760 {
761 /* sanity check */
762 ASSERT(IsListEmpty(&CreateEntry->ObjectItemList));
763 ASSERT(CreateEntry->ReferenceCount == 0);
764 /* use free entry */
765 CreateEntry->CreateItem->Context = Context;
766 CreateEntry->CreateItem->Create = Create;
767 RtlInitUnicodeString(&CreateEntry->CreateItem->ObjectClass, ObjectClass);
768 CreateEntry->CreateItem->SecurityDescriptor = SecurityDescriptor;
769
770 return STATUS_SUCCESS;
771 }
772
773 if (!wcsicmp(ObjectClass, CreateEntry->CreateItem->ObjectClass.Buffer))
774 {
775 /* the same object class already exists */
776 return STATUS_OBJECT_NAME_COLLISION;
777 }
778
779 /* iterate to next entry */
780 Entry = Entry->Flink;
781 }
782 return STATUS_ALLOTTED_SPACE_EXCEEDED;
783 }
784
785 /*
786 @implemented
787 */
788 KSDDKAPI
789 NTSTATUS
790 NTAPI
791 KsAddObjectCreateItemToDeviceHeader(
792 IN KSDEVICE_HEADER DevHeader,
793 IN PDRIVER_DISPATCH Create,
794 IN PVOID Context,
795 IN PWCHAR ObjectClass,
796 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
797 {
798 PKSIDEVICE_HEADER Header;
799 NTSTATUS Status;
800
801 Header = (PKSIDEVICE_HEADER)DevHeader;
802
803 DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n");
804
805 /* check if a device header has been provided */
806 if (!DevHeader)
807 return STATUS_INVALID_PARAMETER_1;
808
809 /* check if a create item has been provided */
810 if (!Create)
811 return STATUS_INVALID_PARAMETER_2;
812
813 /* check if a object class has been provided */
814 if (!ObjectClass)
815 return STATUS_INVALID_PARAMETER_4;
816
817 /* let others do the work */
818 Status = KspAddObjectCreateItemToList(&Header->ItemList, Create, Context, ObjectClass, SecurityDescriptor);
819
820 if (NT_SUCCESS(Status))
821 {
822 /* increment create item count */
823 InterlockedIncrement(&Header->ItemListCount);
824 }
825
826 return Status;
827 }
828
829 /*
830 @implemented
831 */
832 KSDDKAPI
833 NTSTATUS
834 NTAPI
835 KsAddObjectCreateItemToObjectHeader(
836 IN KSOBJECT_HEADER ObjectHeader,
837 IN PDRIVER_DISPATCH Create,
838 IN PVOID Context,
839 IN PWCHAR ObjectClass,
840 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
841 {
842 PKSIOBJECT_HEADER Header;
843 NTSTATUS Status;
844
845 Header = (PKSIOBJECT_HEADER)ObjectHeader;
846
847 DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n");
848
849 /* check if a device header has been provided */
850 if (!Header)
851 return STATUS_INVALID_PARAMETER_1;
852
853 /* check if a create item has been provided */
854 if (!Create)
855 return STATUS_INVALID_PARAMETER_2;
856
857 /* check if a object class has been provided */
858 if (!ObjectClass)
859 return STATUS_INVALID_PARAMETER_4;
860
861 /* let's work */
862 Status = KspAddObjectCreateItemToList(&Header->ItemList, Create, Context, ObjectClass, SecurityDescriptor);
863
864 if (NT_SUCCESS(Status))
865 {
866 /* increment create item count */
867 InterlockedIncrement(&Header->ItemListCount);
868 }
869
870 return Status;
871 }
872
873 /*
874 @implemented
875 */
876 KSDDKAPI
877 NTSTATUS
878 NTAPI
879 KsAllocateObjectCreateItem(
880 IN KSDEVICE_HEADER DevHeader,
881 IN PKSOBJECT_CREATE_ITEM CreateItem,
882 IN BOOLEAN AllocateEntry,
883 IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL)
884 {
885 PCREATE_ITEM_ENTRY CreateEntry;
886 PKSIDEVICE_HEADER Header;
887 PKSOBJECT_CREATE_ITEM Item;
888
889 Header = (PKSIDEVICE_HEADER)DevHeader;
890
891 if (!DevHeader)
892 return STATUS_INVALID_PARAMETER_1;
893
894 if (!CreateItem)
895 return STATUS_INVALID_PARAMETER_2;
896
897 /* first allocate a create entry */
898 CreateEntry = AllocateItem(NonPagedPool, sizeof(PCREATE_ITEM_ENTRY));
899
900 /* check for allocation success */
901 if (!CreateEntry)
902 {
903 /* not enough resources */
904 return STATUS_INSUFFICIENT_RESOURCES;
905 }
906
907
908 if (AllocateEntry)
909 {
910 /* allocate create item */
911 Item = ExAllocatePool(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
912 if (!Item)
913 {
914 /* no memory */
915 ExFreePool(CreateEntry);
916 return STATUS_INSUFFICIENT_RESOURCES;
917 }
918
919 /* initialize descriptor */
920 Item->Context = CreateItem->Context;
921 Item->Create = CreateItem->Create;
922 Item->Flags = CreateItem->Flags;
923 Item->SecurityDescriptor = CreateItem->SecurityDescriptor;
924 Item->ObjectClass.Length = 0;
925 Item->ObjectClass.MaximumLength = CreateItem->ObjectClass.MaximumLength;
926
927 /* copy object class */
928 Item->ObjectClass.Buffer = ExAllocatePool(NonPagedPool, Item->ObjectClass.MaximumLength);
929 if (!Item->ObjectClass.Buffer)
930 {
931 /* release resources */
932 FreeItem(Item);
933 FreeItem(CreateEntry);
934
935 return STATUS_INSUFFICIENT_RESOURCES;
936 }
937 RtlCopyUnicodeString(&Item->ObjectClass, &CreateItem->ObjectClass);
938 }
939 else
940 {
941 if (ItemFreeCallback)
942 {
943 /* callback is only accepted when the create item is copied */
944 ItemFreeCallback = NULL;
945 }
946 /* use passed create item */
947 Item = CreateItem;
948 }
949
950 /* initialize create item entry */
951 InitializeListHead(&CreateEntry->ObjectItemList);
952 CreateEntry->ItemFreeCallback = ItemFreeCallback;
953 CreateEntry->CreateItem = Item;
954 CreateEntry->ReferenceCount = 0;
955
956 /* now insert the create item entry */
957 InsertTailList(&Header->ItemList, &CreateEntry->Entry);
958
959 /* increment item count */
960 InterlockedIncrement(&Header->ItemListCount);
961
962 return STATUS_SUCCESS;
963 }
964
965 NTSTATUS
966 KspObjectFreeCreateItems(
967 IN KSDEVICE_HEADER Header,
968 IN PKSOBJECT_CREATE_ITEM CreateItem)
969 {
970 UNIMPLEMENTED
971 return STATUS_NOT_IMPLEMENTED;
972 }
973
974 /*
975 @implemented
976 */
977 KSDDKAPI
978 NTSTATUS
979 NTAPI
980 KsFreeObjectCreateItem(
981 IN KSDEVICE_HEADER Header,
982 IN PUNICODE_STRING CreateItem)
983 {
984 KSOBJECT_CREATE_ITEM Item;
985
986 RtlZeroMemory(&Item, sizeof(KSOBJECT_CREATE_ITEM));
987 RtlInitUnicodeString(&Item.ObjectClass, CreateItem->Buffer);
988
989 return KspObjectFreeCreateItems(Header, &Item);
990 }
991
992
993 /*
994 @implemented
995 */
996 KSDDKAPI
997 NTSTATUS
998 NTAPI
999 KsFreeObjectCreateItemsByContext(
1000 IN KSDEVICE_HEADER Header,
1001 IN PVOID Context)
1002 {
1003 KSOBJECT_CREATE_ITEM Item;
1004
1005 RtlZeroMemory(&Item, sizeof(KSOBJECT_CREATE_ITEM));
1006
1007 Item.Context = Context;
1008
1009 return KspObjectFreeCreateItems(Header, &Item);
1010 }
1011
1012 /*
1013 @implemented
1014 */
1015 KSDDKAPI
1016 NTSTATUS
1017 NTAPI
1018 KsCreateDefaultSecurity(
1019 IN PSECURITY_DESCRIPTOR ParentSecurity OPTIONAL,
1020 OUT PSECURITY_DESCRIPTOR* DefaultSecurity)
1021 {
1022 PGENERIC_MAPPING Mapping;
1023 SECURITY_SUBJECT_CONTEXT SubjectContext;
1024 NTSTATUS Status;
1025
1026 /* start capturing security context of calling thread */
1027 SeCaptureSubjectContext(&SubjectContext);
1028 /* get generic mapping */
1029 Mapping = IoGetFileObjectGenericMapping();
1030 /* build new descriptor */
1031 Status = SeAssignSecurity(ParentSecurity, NULL, DefaultSecurity, FALSE, &SubjectContext, Mapping, NonPagedPool);
1032 /* release security descriptor */
1033 SeReleaseSubjectContext(&SubjectContext);
1034 /* done */
1035 return Status;
1036 }
1037
1038 /*
1039 @unimplemented
1040 */
1041 KSDDKAPI
1042 NTSTATUS
1043 NTAPI
1044 KsForwardIrp(
1045 IN PIRP Irp,
1046 IN PFILE_OBJECT FileObject,
1047 IN BOOLEAN ReuseStackLocation)
1048 {
1049 UNIMPLEMENTED;
1050 return STATUS_UNSUCCESSFUL;
1051 }
1052
1053
1054 /*
1055 @unimplemented
1056 */
1057 KSDDKAPI
1058 NTSTATUS
1059 NTAPI
1060 KsForwardAndCatchIrp(
1061 IN PDEVICE_OBJECT DeviceObject,
1062 IN PIRP Irp,
1063 IN PFILE_OBJECT FileObject,
1064 IN KSSTACK_USE StackUse)
1065 {
1066 UNIMPLEMENTED;
1067 return STATUS_UNSUCCESSFUL;
1068 }
1069
1070
1071 NTSTATUS
1072 NTAPI
1073 KspSynchronousIoControlDeviceCompletion(
1074 IN PDEVICE_OBJECT DeviceObject,
1075 IN PIRP Irp,
1076 IN PVOID Context)
1077 {
1078 PIO_STATUS_BLOCK IoStatusBlock = (PIO_STATUS_BLOCK)Context;
1079
1080 IoStatusBlock->Information = Irp->IoStatus.Information;
1081 IoStatusBlock->Status = Irp->IoStatus.Status;
1082
1083 return STATUS_SUCCESS;
1084 }
1085
1086 /*
1087 @implemented
1088 */
1089 KSDDKAPI
1090 NTSTATUS
1091 NTAPI
1092 KsSynchronousIoControlDevice(
1093 IN PFILE_OBJECT FileObject,
1094 IN KPROCESSOR_MODE RequestorMode,
1095 IN ULONG IoControl,
1096 IN PVOID InBuffer,
1097 IN ULONG InSize,
1098 OUT PVOID OutBuffer,
1099 IN ULONG OutSize,
1100 OUT PULONG BytesReturned)
1101 {
1102 PKSIOBJECT_HEADER ObjectHeader;
1103 PDEVICE_OBJECT DeviceObject;
1104 KEVENT Event;
1105 PIRP Irp;
1106 IO_STATUS_BLOCK IoStatusBlock;
1107 PIO_STACK_LOCATION IoStack;
1108 NTSTATUS Status;
1109
1110 /* check for valid file object */
1111 if (!FileObject)
1112 return STATUS_INVALID_PARAMETER;
1113
1114 /* get device object to send the request to */
1115 DeviceObject = IoGetRelatedDeviceObject(FileObject);
1116 if (!DeviceObject)
1117 return STATUS_UNSUCCESSFUL;
1118
1119
1120 /* get object header */
1121 ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext;
1122
1123 /* check if there is fast device io function */
1124 if (ObjectHeader && ObjectHeader->DispatchTable.FastDeviceIoControl)
1125 {
1126 IoStatusBlock.Status = STATUS_UNSUCCESSFUL;
1127 IoStatusBlock.Information = 0;
1128
1129 /* it is send the request */
1130 Status = ObjectHeader->DispatchTable.FastDeviceIoControl(FileObject, TRUE, InBuffer, InSize, OutBuffer, OutSize, IoControl, &IoStatusBlock, DeviceObject);
1131 /* check if the request was handled */
1132 //DPRINT("Handled %u Status %x Length %u\n", Status, IoStatusBlock.Status, IoStatusBlock.Information);
1133 if (Status)
1134 {
1135 /* store bytes returned */
1136 *BytesReturned = IoStatusBlock.Information;
1137 /* return status */
1138 return IoStatusBlock.Status;
1139 }
1140 }
1141
1142 /* initialize the event */
1143 KeInitializeEvent(&Event, NotificationEvent, FALSE);
1144
1145 /* create the irp */
1146 Irp = IoBuildDeviceIoControlRequest(IoControl, DeviceObject, InBuffer, InSize, OutBuffer, OutSize, FALSE, &Event, &IoStatusBlock);
1147
1148 /* HACK */
1149 IoStack = IoGetNextIrpStackLocation(Irp);
1150 IoStack->FileObject = FileObject;
1151
1152 IoSetCompletionRoutine(Irp, KspSynchronousIoControlDeviceCompletion, (PVOID)&IoStatusBlock, TRUE, TRUE, TRUE);
1153
1154 Status = IoCallDriver(DeviceObject, Irp);
1155 if (Status == STATUS_PENDING)
1156 {
1157 KeWaitForSingleObject(&Event, Executive, RequestorMode, FALSE, NULL);
1158 Status = IoStatusBlock.Status;
1159 }
1160
1161 *BytesReturned = IoStatusBlock.Information;
1162 return Status;
1163 }
1164
1165 /*
1166 @implemented
1167 */
1168 KSDDKAPI
1169 NTSTATUS
1170 NTAPI
1171 KsUnserializeObjectPropertiesFromRegistry(
1172 IN PFILE_OBJECT FileObject,
1173 IN HANDLE ParentKey OPTIONAL,
1174 IN PUNICODE_STRING RegistryPath OPTIONAL)
1175 {
1176 UNIMPLEMENTED
1177 return STATUS_NOT_IMPLEMENTED;
1178 }
1179
1180
1181 /*
1182 @unimplemented
1183 */
1184 KSDDKAPI
1185 NTSTATUS
1186 NTAPI
1187 KsCacheMedium(
1188 IN PUNICODE_STRING SymbolicLink,
1189 IN PKSPIN_MEDIUM Medium,
1190 IN ULONG PinDirection)
1191 {
1192 UNIMPLEMENTED;
1193 return STATUS_UNSUCCESSFUL;
1194 }
1195
1196 /*
1197 @implemented
1198 */
1199 NTSTATUS
1200 NTAPI
1201 DllInitialize(
1202 PUNICODE_STRING RegistryPath)
1203 {
1204 return STATUS_SUCCESS;
1205 }
1206
1207
1208 NTSTATUS
1209 NTAPI
1210 KopDispatchClose(
1211 IN PDEVICE_OBJECT DeviceObject,
1212 IN PIRP Irp)
1213 {
1214 PKO_OBJECT_HEADER Header;
1215 PIO_STACK_LOCATION IoStack;
1216 PDEVICE_EXTENSION DeviceExtension;
1217
1218 /* get current irp stack location */
1219 IoStack = IoGetCurrentIrpStackLocation(Irp);
1220
1221 /* get ko object header */
1222 Header = (PKO_OBJECT_HEADER)IoStack->FileObject->FsContext2;
1223
1224 /* free ks object header */
1225 KsFreeObjectHeader(Header->ObjectHeader);
1226
1227 /* free ko object header */
1228 FreeItem(Header);
1229
1230 /* get device extension */
1231 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
1232
1233 /* release bus object */
1234 KsDereferenceBusObject((KSDEVICE_HEADER)DeviceExtension->DeviceHeader);
1235
1236 /* complete request */
1237 Irp->IoStatus.Status = STATUS_SUCCESS;
1238 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1239
1240 return STATUS_SUCCESS;
1241 }
1242
1243
1244
1245 static KSDISPATCH_TABLE KoDispatchTable =
1246 {
1247 KsDispatchInvalidDeviceRequest,
1248 KsDispatchInvalidDeviceRequest,
1249 KsDispatchInvalidDeviceRequest,
1250 KsDispatchInvalidDeviceRequest,
1251 KopDispatchClose,
1252 KsDispatchQuerySecurity,
1253 KsDispatchSetSecurity,
1254 KsDispatchFastIoDeviceControlFailure,
1255 KsDispatchFastReadFailure,
1256 KsDispatchFastReadFailure,
1257 };
1258
1259
1260 NTSTATUS
1261 NTAPI
1262 KopDispatchCreate(
1263 IN PDEVICE_OBJECT DeviceObject,
1264 IN PIRP Irp)
1265 {
1266 PKO_OBJECT_HEADER Header = NULL;
1267 PIO_STACK_LOCATION IoStack;
1268 PKO_DRIVER_EXTENSION DriverObjectExtension;
1269 NTSTATUS Status;
1270
1271 /* get current irp stack location */
1272 IoStack = IoGetCurrentIrpStackLocation(Irp);
1273
1274 if (!IoStack->FileObject)
1275 {
1276 DPRINT1("FileObject not attached!\n");
1277 Status = STATUS_UNSUCCESSFUL;
1278 goto cleanup;
1279 }
1280
1281 /* get driver object extension */
1282 DriverObjectExtension = (PKO_DRIVER_EXTENSION)IoGetDriverObjectExtension(DeviceObject->DriverObject, (PVOID)KoDriverInitialize);
1283 if (!DriverObjectExtension)
1284 {
1285 DPRINT1("FileObject not attached!\n");
1286 Status = STATUS_UNSUCCESSFUL;
1287 goto cleanup;
1288 }
1289
1290 /* allocate ko object header */
1291 Header = (PKO_OBJECT_HEADER)AllocateItem(NonPagedPool, sizeof(KO_OBJECT_HEADER));
1292 if (!Header)
1293 {
1294 DPRINT1("failed to allocate KO_OBJECT_HEADER\n");
1295 Status = STATUS_INSUFFICIENT_RESOURCES;
1296 goto cleanup;
1297 }
1298
1299 /* initialize create item */
1300 Header->CreateItem.Create = KopDispatchCreate;
1301 RtlInitUnicodeString(&Header->CreateItem.ObjectClass, KOSTRING_CreateObject);
1302
1303
1304 /* now allocate the object header */
1305 Status = KsAllocateObjectHeader(&Header->ObjectHeader, 1, &Header->CreateItem, Irp, &KoDispatchTable);
1306 if (!NT_SUCCESS(Status))
1307 {
1308 /* failed */
1309 goto cleanup;
1310 }
1311
1312 /* FIXME
1313 * extract clsid and interface id from irp
1314 * call the standard create handler
1315 */
1316
1317 UNIMPLEMENTED
1318
1319 IoStack->FileObject->FsContext2 = (PVOID)Header;
1320
1321 Irp->IoStatus.Status = Status;
1322 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1323
1324 return Status;
1325
1326 cleanup:
1327
1328 if (Header && Header->ObjectHeader)
1329 KsFreeObjectHeader(Header->ObjectHeader);
1330
1331 if (Header)
1332 FreeItem(Header);
1333
1334 Irp->IoStatus.Status = Status;
1335 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1336 return Status;
1337 }
1338
1339
1340
1341 NTSTATUS
1342 NTAPI
1343 KopAddDevice(
1344 IN PDRIVER_OBJECT DriverObject,
1345 IN PDEVICE_OBJECT PhysicalDeviceObject)
1346 {
1347 NTSTATUS Status = STATUS_DEVICE_REMOVED;
1348 PDEVICE_OBJECT FunctionalDeviceObject= NULL;
1349 PDEVICE_OBJECT NextDeviceObject;
1350 PDEVICE_EXTENSION DeviceExtension;
1351 PKSOBJECT_CREATE_ITEM CreateItem;
1352
1353 /* create the device object */
1354 Status = IoCreateDevice(DriverObject, sizeof(DEVICE_EXTENSION), NULL, FILE_DEVICE_KS, FILE_DEVICE_SECURE_OPEN, FALSE, &FunctionalDeviceObject);
1355 if (!NT_SUCCESS(Status))
1356 return Status;
1357
1358 /* allocate the create item */
1359 CreateItem = AllocateItem(NonPagedPool, sizeof(KSOBJECT_CREATE_ITEM));
1360
1361 if (!CreateItem)
1362 {
1363 /* not enough memory */
1364 IoDeleteDevice(FunctionalDeviceObject);
1365 return STATUS_INSUFFICIENT_RESOURCES;
1366 }
1367
1368 /* initialize create item */
1369 CreateItem->Create = KopDispatchCreate;
1370 RtlInitUnicodeString(&CreateItem->ObjectClass, KOSTRING_CreateObject);
1371
1372 /* get device extension */
1373 DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension;
1374
1375 /* now allocate the device header */
1376 Status = KsAllocateDeviceHeader((KSDEVICE_HEADER*)&DeviceExtension->DeviceHeader, 1, CreateItem);
1377 if (!NT_SUCCESS(Status))
1378 {
1379 /* failed */
1380 IoDeleteDevice(FunctionalDeviceObject);
1381 FreeItem(CreateItem);
1382 return Status;
1383 }
1384
1385 /* now attach to device stack */
1386 NextDeviceObject = IoAttachDeviceToDeviceStack(FunctionalDeviceObject, PhysicalDeviceObject);
1387 if (NextDeviceObject)
1388 {
1389 /* store pnp base object */
1390 KsSetDevicePnpAndBaseObject((KSDEVICE_HEADER)DeviceExtension->DeviceHeader, NextDeviceObject, FunctionalDeviceObject);
1391 /* set device flags */
1392 FunctionalDeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
1393 FunctionalDeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
1394 }
1395 else
1396 {
1397 /* failed */
1398 KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceExtension->DeviceHeader);
1399 FreeItem(CreateItem);
1400 IoDeleteDevice(FunctionalDeviceObject);
1401 Status = STATUS_DEVICE_REMOVED;
1402 }
1403
1404 /* return result */
1405 return Status;
1406 }
1407
1408
1409 /*
1410 @implemented
1411 */
1412 COMDDKAPI
1413 NTSTATUS
1414 NTAPI
1415 KoDeviceInitialize(
1416 IN PDEVICE_OBJECT DeviceObject)
1417 {
1418 PDEVICE_EXTENSION DeviceExtension;
1419
1420 /* get device extension */
1421 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
1422
1423 return KsAddObjectCreateItemToDeviceHeader((KSDEVICE_HEADER)DeviceExtension->DeviceHeader, KopDispatchCreate, NULL, KOSTRING_CreateObject, NULL);
1424 }
1425
1426 /*
1427 @implemented
1428 */
1429 COMDDKAPI
1430 NTSTATUS
1431 NTAPI
1432 KoDriverInitialize(
1433 IN PDRIVER_OBJECT DriverObject,
1434 IN PUNICODE_STRING RegistryPathName,
1435 IN KoCreateObjectHandler CreateObjectHandler)
1436 {
1437 PKO_DRIVER_EXTENSION DriverObjectExtension;
1438 NTSTATUS Status;
1439
1440 /* allocate driver object extension */
1441 Status = IoAllocateDriverObjectExtension(DriverObject, (PVOID)KoDriverInitialize, sizeof(KO_DRIVER_EXTENSION), (PVOID*)&DriverObjectExtension);
1442
1443 /* did it work */
1444 if (NT_SUCCESS(Status))
1445 {
1446 /* store create handler */
1447 DriverObjectExtension->CreateObjectHandler = CreateObjectHandler;
1448
1449 /* Setting our IRP handlers */
1450 DriverObject->MajorFunction[IRP_MJ_PNP] = KsDefaultDispatchPnp;
1451 DriverObject->MajorFunction[IRP_MJ_POWER] = KsDefaultDispatchPower;
1452 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
1453
1454 /* The driver unload routine */
1455 DriverObject->DriverUnload = KsNullDriverUnload;
1456
1457 /* The driver-supplied AddDevice */
1458 DriverObject->DriverExtension->AddDevice = KopAddDevice;
1459
1460 /* KS handles these */
1461 DPRINT1("Setting KS function handlers\n");
1462 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CREATE);
1463 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
1464 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
1465
1466 }
1467
1468 return Status;
1469 }
1470
1471 /*
1472 @unimplemented
1473 */
1474 COMDDKAPI
1475 VOID
1476 NTAPI
1477 KoRelease(
1478 IN REFCLSID ClassId)
1479 {
1480
1481 }
1482
1483 /*
1484 @implemented
1485 */
1486 KSDDKAPI
1487 VOID
1488 NTAPI
1489 KsAcquireControl(
1490 IN PVOID Object)
1491 {
1492 PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
1493
1494 /* sanity check */
1495 ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
1496
1497 KeWaitForSingleObject(&BasicHeader->ControlMutex, Executive, KernelMode, FALSE, NULL);
1498
1499 }
1500
1501 /*
1502 @implemented
1503 */
1504 VOID
1505 NTAPI
1506 KsReleaseControl(
1507 IN PVOID Object)
1508 {
1509 PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
1510
1511 /* sanity check */
1512 ASSERT(BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
1513
1514 KeReleaseMutex(&BasicHeader->ControlMutex, FALSE);
1515 }
1516
1517
1518
1519 /*
1520 @implemented
1521 */
1522 KSDDKAPI
1523 VOID
1524 NTAPI
1525 KsAcquireDevice(
1526 IN PKSDEVICE Device)
1527 {
1528 IKsDevice *KsDevice;
1529 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
1530
1531 /* get device interface*/
1532 KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
1533
1534 /* acquire device mutex */
1535 KsDevice->lpVtbl->AcquireDevice(KsDevice);
1536 }
1537
1538 /*
1539 @implemented
1540 */
1541 VOID
1542 NTAPI
1543 KsReleaseDevice(
1544 IN PKSDEVICE Device)
1545 {
1546 IKsDevice *KsDevice;
1547 PKSIDEVICE_HEADER DeviceHeader = (PKSIDEVICE_HEADER)CONTAINING_RECORD(Device, KSIDEVICE_HEADER, KsDevice);
1548
1549 /* get device interface*/
1550 KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
1551
1552 /* release device mutex */
1553 KsDevice->lpVtbl->ReleaseDevice(KsDevice);
1554 }
1555
1556 /*
1557 @implemented
1558 */
1559 KSDDKAPI
1560 VOID
1561 NTAPI
1562 KsTerminateDevice(
1563 IN PDEVICE_OBJECT DeviceObject)
1564 {
1565 IKsDevice *KsDevice;
1566 PKSIDEVICE_HEADER DeviceHeader;
1567 PDEVICE_EXTENSION DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
1568
1569 /* get device header */
1570 DeviceHeader = DeviceExtension->DeviceHeader;
1571
1572 /* get device interface*/
1573 KsDevice = (IKsDevice*)&DeviceHeader->lpVtblIKsDevice;
1574
1575 /* now free device header */
1576 KsFreeDeviceHeader((KSDEVICE_HEADER)DeviceHeader);
1577
1578 /* release interface when available */
1579 if (KsDevice)
1580 {
1581 /* delete IKsDevice interface */
1582 KsDevice->lpVtbl->Release(KsDevice);
1583 }
1584 }
1585
1586 /*
1587 @implemented
1588 */
1589 KSDDKAPI
1590 VOID
1591 NTAPI
1592 KsCompletePendingRequest(
1593 IN PIRP Irp)
1594 {
1595 PIO_STACK_LOCATION IoStack;
1596
1597 /* get current irp stack location */
1598 IoStack = IoGetCurrentIrpStackLocation(Irp);
1599
1600 /* sanity check */
1601 ASSERT(Irp->IoStatus.Status != STATUS_PENDING);
1602
1603 if (IoStack->MajorFunction != IRP_MJ_CLOSE)
1604 {
1605 /* can be completed immediately */
1606 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1607 return;
1608 }
1609
1610 /* did close operation fail */
1611 if (!NT_SUCCESS(Irp->IoStatus.Status))
1612 {
1613 /* closing failed, complete irp */
1614 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1615 return;
1616 }
1617
1618 /* FIXME
1619 * delete object / device header
1620 * remove dead pin / filter instance
1621 */
1622 UNIMPLEMENTED
1623
1624 }
1625
1626 /*
1627 @unimplemented
1628 */
1629 KSDDKAPI
1630 NTSTATUS
1631 NTAPI
1632 KsCreateBusEnumObject(
1633 IN PWCHAR BusIdentifier,
1634 IN PDEVICE_OBJECT BusDeviceObject,
1635 IN PDEVICE_OBJECT PhysicalDeviceObject,
1636 IN PDEVICE_OBJECT PnpDeviceObject OPTIONAL,
1637 IN REFGUID InterfaceGuid OPTIONAL,
1638 IN PWCHAR ServiceRelativePath OPTIONAL)
1639 {
1640 UNIMPLEMENTED
1641 return STATUS_UNSUCCESSFUL;
1642 }
1643
1644 NTSTATUS
1645 NTAPI
1646 KspSetGetBusDataCompletion(
1647 IN PDEVICE_OBJECT DeviceObject,
1648 IN PIRP Irp,
1649 IN PVOID Context)
1650 {
1651 /* signal completion */
1652 KeSetEvent((PRKEVENT)Context, IO_NO_INCREMENT, FALSE);
1653
1654 /* more work needs be done, so dont free the irp */
1655 return STATUS_MORE_PROCESSING_REQUIRED;
1656
1657 }
1658
1659 NTSTATUS
1660 KspDeviceSetGetBusData(
1661 IN PDEVICE_OBJECT DeviceObject,
1662 IN ULONG DataType,
1663 IN PVOID Buffer,
1664 IN ULONG Offset,
1665 IN ULONG Length,
1666 IN BOOL bGet)
1667 {
1668 PIO_STACK_LOCATION IoStack;
1669 PIRP Irp;
1670 NTSTATUS Status;
1671 KEVENT Event;
1672
1673 /* allocate the irp */
1674 Irp = IoAllocateIrp(1, /*FIXME */
1675 FALSE);
1676
1677 if (!Irp)
1678 return STATUS_INSUFFICIENT_RESOURCES;
1679
1680 /* initialize the event */
1681 KeInitializeEvent(&Event, NotificationEvent, FALSE);
1682
1683 /* get next stack location */
1684 IoStack = IoGetNextIrpStackLocation(Irp);
1685
1686 /* setup a completion routine */
1687 IoSetCompletionRoutine(Irp, KspSetGetBusDataCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
1688
1689 /* setup parameters */
1690 IoStack->Parameters.ReadWriteConfig.Buffer = Buffer;
1691 IoStack->Parameters.ReadWriteConfig.Length = Length;
1692 IoStack->Parameters.ReadWriteConfig.Offset = Offset;
1693 IoStack->Parameters.ReadWriteConfig.WhichSpace = DataType;
1694 /* setup function code */
1695 IoStack->MajorFunction = IRP_MJ_PNP;
1696 IoStack->MinorFunction = (bGet ? IRP_MN_READ_CONFIG : IRP_MN_WRITE_CONFIG);
1697
1698 /* lets call the driver */
1699 Status = IoCallDriver(DeviceObject, Irp);
1700
1701 /* is the request still pending */
1702 if (Status == STATUS_PENDING)
1703 {
1704 /* have a nap */
1705 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
1706 /* update status */
1707 Status = Irp->IoStatus.Status;
1708 }
1709
1710 /* free the irp */
1711 IoFreeIrp(Irp);
1712 /* done */
1713 return Status;
1714 }
1715
1716 /*
1717 @implemented
1718 */
1719 KSDDKAPI
1720 ULONG
1721 NTAPI
1722 KsDeviceSetBusData(
1723 IN PKSDEVICE Device,
1724 IN ULONG DataType,
1725 IN PVOID Buffer,
1726 IN ULONG Offset,
1727 IN ULONG Length)
1728 {
1729 return KspDeviceSetGetBusData(Device->PhysicalDeviceObject, /* is this right? */
1730 DataType, Buffer, Offset, Length, FALSE);
1731 }
1732
1733
1734 /*
1735 @implemented
1736 */
1737 KSDDKAPI
1738 ULONG
1739 NTAPI
1740 KsDeviceGetBusData(
1741 IN PKSDEVICE Device,
1742 IN ULONG DataType,
1743 IN PVOID Buffer,
1744 IN ULONG Offset,
1745 IN ULONG Length)
1746 {
1747 return KspDeviceSetGetBusData(Device->PhysicalDeviceObject, /* is this right? */
1748 DataType, Buffer, Offset, Length, TRUE);
1749
1750 }
1751
1752 /*
1753 @unimplemented
1754 */
1755 KSDDKAPI
1756 void
1757 NTAPI
1758 KsDeviceRegisterAdapterObject(
1759 IN PKSDEVICE Device,
1760 IN PADAPTER_OBJECT AdapterObject,
1761 IN ULONG MaxMappingsByteCount,
1762 IN ULONG MappingTableStride)
1763 {
1764 UNIMPLEMENTED
1765 }
1766
1767 /*
1768 @unimplemented
1769 */
1770 KSDDKAPI
1771 NTSTATUS
1772 NTAPI
1773 _KsEdit(
1774 IN KSOBJECT_BAG ObjectBag,
1775 IN OUT PVOID* PointerToPointerToItem,
1776 IN ULONG NewSize,
1777 IN ULONG OldSize,
1778 IN ULONG Tag)
1779 {
1780 UNIMPLEMENTED
1781 return STATUS_UNSUCCESSFUL;
1782 }
1783
1784 /*
1785 @unimplemented
1786 */
1787 KSDDKAPI
1788 NTSTATUS
1789 NTAPI
1790 KsGetBusEnumIdentifier(
1791 IN PIRP Irp)
1792 {
1793 UNIMPLEMENTED
1794 return STATUS_UNSUCCESSFUL;
1795 }
1796
1797 /*
1798 @unimplemented
1799 */
1800 KSDDKAPI
1801 NTSTATUS
1802 NTAPI
1803 KsGetBusEnumParentFDOFromChildPDO(
1804 IN PDEVICE_OBJECT DeviceObject,
1805 OUT PDEVICE_OBJECT *FunctionalDeviceObject)
1806 {
1807 UNIMPLEMENTED
1808 return STATUS_UNSUCCESSFUL;
1809 }
1810
1811 /*
1812 @unimplemented
1813 */
1814 KSDDKAPI
1815 NTSTATUS
1816 NTAPI
1817 KsGetBusEnumPnpDeviceObject(
1818 IN PDEVICE_OBJECT DeviceObject,
1819 IN PDEVICE_OBJECT *PnpDeviceObject)
1820 {
1821 UNIMPLEMENTED
1822 return STATUS_UNSUCCESSFUL;
1823 }
1824
1825 /*
1826 @unimplemented
1827 */
1828 KSDDKAPI
1829 PVOID
1830 NTAPI
1831 KsGetFirstChild(
1832 IN PVOID Object)
1833 {
1834 UNIMPLEMENTED
1835 return NULL;
1836 }
1837
1838 /*
1839 @unimplemented
1840 */
1841 KSDDKAPI
1842 PVOID
1843 NTAPI
1844 KsGetNextSibling(
1845 IN PVOID Object)
1846 {
1847 UNIMPLEMENTED
1848 return NULL;
1849 }
1850
1851 /*
1852 @unimplemented
1853 */
1854 KSDDKAPI
1855 NTSTATUS
1856 NTAPI
1857 KsInstallBusEnumInterface(
1858 PIRP Irp)
1859 {
1860 UNIMPLEMENTED
1861 return STATUS_UNSUCCESSFUL;
1862 }
1863
1864 /*
1865 @unimplemented
1866 */
1867 KSDDKAPI
1868 NTSTATUS
1869 NTAPI
1870 KsIsBusEnumChildDevice(
1871 IN PDEVICE_OBJECT DeviceObject,
1872 OUT PBOOLEAN ChildDevice)
1873 {
1874 UNIMPLEMENTED
1875 return STATUS_UNSUCCESSFUL;
1876 }
1877
1878 /*
1879 @unimplemented
1880 */
1881 NTSTATUS
1882 NTAPI
1883 KsMergeAutomationTables(
1884 OUT PKSAUTOMATION_TABLE *AutomationTableAB,
1885 IN PKSAUTOMATION_TABLE AutomationTableA OPTIONAL,
1886 IN PKSAUTOMATION_TABLE AutomationTableB OPTIONAL,
1887 IN KSOBJECT_BAG Bag OPTIONAL)
1888 {
1889 UNIMPLEMENTED
1890 return STATUS_UNSUCCESSFUL;
1891 }
1892
1893 /*
1894 @unimplemented
1895 */
1896 KSDDKAPI
1897 NTSTATUS
1898 NTAPI
1899 KsServiceBusEnumCreateRequest(
1900 IN PDEVICE_OBJECT DeviceObject,
1901 IN OUT PIRP Irp)
1902 {
1903 UNIMPLEMENTED
1904 return STATUS_UNSUCCESSFUL;
1905 }
1906
1907
1908 /*
1909 @unimplemented
1910 */
1911 KSDDKAPI
1912 NTSTATUS
1913 NTAPI
1914 KsServiceBusEnumPnpRequest(
1915 IN PDEVICE_OBJECT DeviceObject,
1916 IN OUT PIRP Irp)
1917 {
1918 UNIMPLEMENTED
1919 return STATUS_UNSUCCESSFUL;
1920 }
1921
1922 VOID
1923 NTAPI
1924 KspRemoveBusInterface(
1925 PVOID Ctx)
1926 {
1927 PKSREMOVE_BUS_INTERFACE_CTX Context =(PKSREMOVE_BUS_INTERFACE_CTX)Ctx;
1928
1929 /* TODO
1930 * get SWENUM_INSTALL_INTERFACE struct
1931 * open device key and delete the keys
1932 */
1933
1934 UNIMPLEMENTED
1935
1936 /* set status */
1937 Context->Irp->IoStatus.Status = STATUS_NOT_IMPLEMENTED;
1938
1939
1940 /* signal completion */
1941 KeSetEvent(&Context->Event, IO_NO_INCREMENT, FALSE);
1942 }
1943
1944 /*
1945 @unimplemented
1946 */
1947 KSDDKAPI
1948 NTSTATUS
1949 NTAPI
1950 KsRemoveBusEnumInterface(
1951 IN PIRP Irp)
1952 {
1953 KPROCESSOR_MODE Mode;
1954 LUID luid;
1955 KSREMOVE_BUS_INTERFACE_CTX Ctx;
1956 WORK_QUEUE_ITEM WorkItem;
1957
1958 /* get previous mode */
1959 Mode = ExGetPreviousMode();
1960
1961 /* convert to luid */
1962 luid = RtlConvertUlongToLuid(SE_LOAD_DRIVER_PRIVILEGE);
1963
1964 /* perform access check */
1965 if (!SeSinglePrivilegeCheck(luid, Mode))
1966 {
1967 /* insufficient privileges */
1968 return STATUS_PRIVILEGE_NOT_HELD;
1969 }
1970 /* initialize event */
1971 KeInitializeEvent(&Ctx.Event, NotificationEvent, FALSE);
1972
1973 /* store irp in ctx */
1974 Ctx.Irp = Irp;
1975
1976 /* initialize work item */
1977 ExInitializeWorkItem(&WorkItem, KspRemoveBusInterface, (PVOID)&Ctx);
1978
1979 /* now queue the work item */
1980 ExQueueWorkItem(&WorkItem, DelayedWorkQueue);
1981
1982 /* wait for completion */
1983 KeWaitForSingleObject(&Ctx.Event, Executive, KernelMode, FALSE, NULL);
1984
1985 /* return result */
1986 return Ctx.Irp->IoStatus.Status;
1987
1988 }
1989
1990
1991 /*
1992 @unimplemented
1993 */
1994 KSDDKAPI
1995 PUNKNOWN
1996 NTAPI
1997 KsRegisterAggregatedClientUnknown(
1998 IN PVOID Object,
1999 IN PUNKNOWN ClientUnknown)
2000 {
2001 UNIMPLEMENTED
2002 return NULL;
2003 }
2004
2005 /*
2006 @unimplemented
2007 */
2008 NTSTATUS
2009 NTAPI
2010 KsRegisterFilterWithNoKSPins(
2011 IN PDEVICE_OBJECT DeviceObject,
2012 IN const GUID* InterfaceClassGUID,
2013 IN ULONG PinCount,
2014 IN BOOL* PinDirection,
2015 IN KSPIN_MEDIUM* MediumList,
2016 IN GUID* CategoryList OPTIONAL)
2017 {
2018 UNIMPLEMENTED
2019 return STATUS_UNSUCCESSFUL;
2020 }