- Silence tons of debug messages
[reactos.git] / reactos / drivers / ksfilter / ks / irp.c
1 /*
2 ReactOS Kernel Streaming
3 IRP Helpers
4 */
5
6 #include "priv.h"
7
8 /*
9 @unimplemented
10 */
11 KSDDKAPI NTSTATUS NTAPI
12 KsAcquireResetValue(
13 IN PIRP Irp,
14 OUT KSRESET* ResetValue)
15 {
16 UNIMPLEMENTED;
17 return STATUS_UNSUCCESSFUL;
18 }
19
20 /*
21 @implemented
22 */
23 KSDDKAPI
24 VOID
25 NTAPI
26 KsAddIrpToCancelableQueue(
27 IN OUT PLIST_ENTRY QueueHead,
28 IN PKSPIN_LOCK SpinLock,
29 IN PIRP Irp,
30 IN KSLIST_ENTRY_LOCATION ListLocation,
31 IN PDRIVER_CANCEL DriverCancel OPTIONAL)
32 {
33 PQUEUE_ENTRY Entry;
34
35 if (!QueueHead || !SpinLock || !Irp)
36 return;
37
38 Entry = ExAllocatePool(NonPagedPool, sizeof(QUEUE_ENTRY));
39 if (!Entry)
40 return;
41
42 ///FIXME
43 // setup cancel routine
44 //
45
46 Entry->Irp = Irp;
47
48 if (ListLocation == KsListEntryTail)
49 ExInterlockedInsertTailList(QueueHead, &Entry->Entry, SpinLock);
50 else
51 ExInterlockedInsertHeadList(QueueHead, &Entry->Entry, SpinLock);
52
53 }
54
55 /*
56 @unimplemented
57 */
58 KSDDKAPI NTSTATUS NTAPI
59 KsAddObjectCreateItemToObjectHeader(
60 IN KSOBJECT_HEADER Header,
61 IN PDRIVER_DISPATCH Create,
62 IN PVOID Context,
63 IN PWCHAR ObjectClass,
64 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
65 {
66 UNIMPLEMENTED;
67 return STATUS_UNSUCCESSFUL;
68 }
69
70
71 /*
72 @implemented
73 */
74 KSDDKAPI
75 NTSTATUS
76 NTAPI
77 KsAddObjectCreateItemToDeviceHeader(
78 IN KSDEVICE_HEADER DevHeader,
79 IN PDRIVER_DISPATCH Create,
80 IN PVOID Context,
81 IN PWCHAR ObjectClass,
82 IN PSECURITY_DESCRIPTOR SecurityDescriptor)
83 {
84 PKSIDEVICE_HEADER Header;
85 ULONG FreeIndex, Index;
86
87 Header = (PKSIDEVICE_HEADER)DevHeader;
88
89 DPRINT1("KsAddObjectCreateItemToDeviceHeader entered\n");
90
91 /* check if a device header has been provided */
92 if (!DevHeader)
93 return STATUS_INVALID_PARAMETER_1;
94
95 /* check if a create item has been provided */
96 if (!Create)
97 return STATUS_INVALID_PARAMETER_2;
98
99 /* check if a object class has been provided */
100 if (!ObjectClass)
101 return STATUS_INVALID_PARAMETER_4;
102
103 FreeIndex = (ULONG)-1;
104 /* now scan the list and check for a free item */
105 for(Index = 0; Index < Header->MaxItems; Index++)
106 {
107 if (!Header->ItemList[Index].bCreated)
108 {
109 if (FreeIndex == (ULONG)-1)
110 FreeIndex = Index;
111
112 continue;
113 }
114 else if (!wcsicmp(ObjectClass, Header->ItemList[Index].CreateItem.ObjectClass.Buffer))
115 {
116 /* the same object class already exists */
117 return STATUS_OBJECT_NAME_COLLISION;
118 }
119 }
120 /* found a free index */
121 if (FreeIndex == (ULONG)-1)
122 {
123 /* allocate a new device entry */
124 PDEVICE_ITEM Item = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_ITEM) * (Header->MaxItems + 1), TAG_DEVICE_HEADER);
125 if (!Item)
126 return STATUS_INSUFFICIENT_RESOURCES;
127
128 RtlMoveMemory(Item, Header->ItemList, Header->MaxItems * sizeof(DEVICE_ITEM));
129 ExFreePoolWithTag(Header->ItemList, TAG_DEVICE_HEADER);
130
131 Header->ItemList = Item;
132 FreeIndex = Header->MaxItems;
133 Header->MaxItems++;
134 }
135
136 /* store the new item */
137 Header->ItemList[FreeIndex].bCreated = TRUE;
138 Header->ItemList[FreeIndex].CreateItem.Create = Create;
139 Header->ItemList[FreeIndex].CreateItem.Context = Context;
140 RtlInitUnicodeString(&Header->ItemList[FreeIndex].CreateItem.ObjectClass, ObjectClass);
141 Header->ItemList[FreeIndex].CreateItem.SecurityDescriptor = SecurityDescriptor;
142 Header->ItemList[FreeIndex].CreateItem.Flags = 0;
143 return STATUS_SUCCESS;
144 }
145
146 /*
147 @implemented
148 */
149 KSDDKAPI
150 NTSTATUS
151 NTAPI
152 KsAllocateDeviceHeader(
153 OUT KSDEVICE_HEADER* OutHeader,
154 IN ULONG ItemsCount,
155 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL)
156 {
157 ULONG Index = 0;
158 PKSIDEVICE_HEADER Header;
159
160 if (!OutHeader)
161 return STATUS_INVALID_PARAMETER;
162
163 /* allocate a device header */
164 Header = ExAllocatePoolWithTag(PagedPool, sizeof(KSIDEVICE_HEADER), TAG_DEVICE_HEADER);
165
166 /* check for success */
167 if (!Header)
168 return STATUS_INSUFFICIENT_RESOURCES;
169
170 /* clear all memory */
171 RtlZeroMemory(Header, sizeof(KSIDEVICE_HEADER));
172
173 /* initialize spin lock */
174 KeInitializeSpinLock(&Header->ItemListLock);
175
176 /* are there any create items provided */
177 if (ItemsCount && ItemsList)
178 {
179 /* allocate space for device item list */
180 Header->ItemList = ExAllocatePoolWithTag(NonPagedPool, sizeof(DEVICE_ITEM) * ItemsCount, TAG_DEVICE_HEADER);
181 if (!Header->ItemList)
182 {
183 ExFreePoolWithTag(Header, TAG_DEVICE_HEADER);
184 return STATUS_INSUFFICIENT_RESOURCES;
185 }
186 RtlZeroMemory(Header->ItemList, sizeof(DEVICE_ITEM) * ItemsCount);
187
188 for(Index = 0; Index < ItemsCount; Index++)
189 {
190 /* copy provided create items */
191 RtlMoveMemory(&Header->ItemList[Index].CreateItem, &ItemsList[Index], sizeof(KSOBJECT_CREATE_ITEM));
192 if (ItemsList[Index].Create!= NULL)
193 {
194 Header->ItemList[Index].bCreated = TRUE;
195 }
196 }
197 Header->MaxItems = ItemsCount;
198 }
199
200 /* store result */
201 *OutHeader = Header;
202
203 return STATUS_SUCCESS;
204 }
205
206 /*
207 @unimplemented
208
209 http://www.osronline.com/DDKx/stream/ksfunc_3sc3.htm
210 */
211 KSDDKAPI
212 NTSTATUS
213 NTAPI
214 KsAllocateObjectCreateItem(
215 IN KSDEVICE_HEADER DevHeader,
216 IN PKSOBJECT_CREATE_ITEM CreateItem,
217 IN BOOLEAN AllocateEntry,
218 IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL)
219 {
220 PKSIDEVICE_HEADER Header;
221
222 Header = (PKSIDEVICE_HEADER)DevHeader;
223
224 if (!DevHeader)
225 return STATUS_INVALID_PARAMETER_1;
226
227 if (!CreateItem)
228 return STATUS_INVALID_PARAMETER_2;
229
230 //FIXME
231 //handle ItemFreeCallback
232 //
233 if (AllocateEntry && ItemFreeCallback)
234 DPRINT1("Ignoring ItemFreeCallback\n");
235
236 return KsAddObjectCreateItemToDeviceHeader(DevHeader, CreateItem->Create, CreateItem->Context, CreateItem->ObjectClass.Buffer, CreateItem->SecurityDescriptor);
237 }
238
239
240 /*
241 @implemented
242 */
243 KSDDKAPI
244 VOID
245 NTAPI
246 KsFreeDeviceHeader(
247 IN KSDEVICE_HEADER DevHeader)
248 {
249 PKSIDEVICE_HEADER Header;
250
251 Header = (PKSIDEVICE_HEADER)DevHeader;
252
253 if (!DevHeader)
254 return;
255
256 ExFreePoolWithTag(Header->ItemList, TAG_DEVICE_HEADER);
257 ExFreePoolWithTag(Header, TAG_DEVICE_HEADER);
258 }
259
260 /*
261 @unimplemented
262 */
263 KSDDKAPI NTSTATUS NTAPI
264 KsAllocateExtraData(
265 IN PIRP Irp,
266 IN ULONG ExtraSize,
267 OUT PVOID* ExtraBuffer)
268 {
269 UNIMPLEMENTED;
270 return STATUS_UNSUCCESSFUL;
271 }
272
273 /*
274 @unimplemented
275
276 Initialize the required file context header.
277 Allocates KSOBJECT_HEADER structure.
278 Irp is an IRP_MJ_CREATE structure.
279 Driver must allocate KSDISPATCH_TABLE and initialize it first.
280
281 http://www.osronline.com/DDKx/stream/ksfunc_0u2b.htm
282 */
283 KSDDKAPI
284 NTSTATUS
285 NTAPI
286 KsAllocateObjectHeader(
287 OUT KSOBJECT_HEADER *Header,
288 IN ULONG ItemsCount,
289 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL,
290 IN PIRP Irp,
291 IN KSDISPATCH_TABLE* Table)
292 {
293 PIO_STACK_LOCATION IoStack;
294 PDEVICE_EXTENSION DeviceExtension;
295 PKSIDEVICE_HEADER DeviceHeader;
296 PKSIOBJECT_HEADER ObjectHeader;
297 WCHAR ObjectClass[50];
298
299 if (!Header)
300 return STATUS_INVALID_PARAMETER_1;
301
302 if (!Irp)
303 return STATUS_INVALID_PARAMETER_4;
304
305 if (!Table)
306 return STATUS_INVALID_PARAMETER_5;
307
308 /* get current stack location */
309 IoStack = IoGetCurrentIrpStackLocation(Irp);
310 /* get device extension */
311 DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
312 /* get device header */
313 DeviceHeader = DeviceExtension->DeviceHeader;
314
315 ObjectClass[0] = L'\0';
316 /* check for an file object */
317 if (IoStack->FileObject != NULL)
318 {
319 /* validate the file name */
320 if (IoStack->FileObject->FileName.Length >= 38)
321 {
322 RtlMoveMemory(ObjectClass, IoStack->FileObject->FileName.Buffer, 38 * sizeof(WCHAR));
323 ObjectClass[38] = L'\0';
324 DPRINT("ObjectClass %S\n", ObjectClass);
325 }
326 }
327 /* allocate the object header */
328 ObjectHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(KSIOBJECT_HEADER), TAG_DEVICE_HEADER);
329 if (!ObjectHeader)
330 return STATUS_INSUFFICIENT_RESOURCES;
331
332 /* initialize object header */
333 RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER));
334
335 /* do we have a name */
336 if (ObjectClass[0])
337 {
338 ObjectHeader->ObjectClass = ExAllocatePoolWithTag(NonPagedPool, 40 * sizeof(WCHAR), TAG_DEVICE_HEADER);
339 if (ObjectHeader->ObjectClass)
340 {
341 wcscpy(ObjectHeader->ObjectClass, ObjectClass);
342 }
343 }
344
345 /* copy dispatch table */
346 RtlCopyMemory(&ObjectHeader->DispatchTable, Table, sizeof(KSDISPATCH_TABLE));
347 /* store create items */
348 if (ItemsCount && ItemsList)
349 {
350 ObjectHeader->ItemCount = ItemsCount;
351 ObjectHeader->CreateItem = ItemsList;
352 }
353
354 /* was the request for a pin/clock/node */
355 if (IoStack->FileObject)
356 {
357 /* store the object in the file object */
358 ASSERT(IoStack->FileObject->FsContext == NULL);
359 IoStack->FileObject->FsContext = ObjectHeader;
360 }
361 else
362 {
363 /* the object header is for device */
364 ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems);
365 DeviceHeader->ItemList[DeviceHeader->DeviceIndex].ObjectHeader = ObjectHeader;
366 }
367
368 /* store result */
369 *Header = ObjectHeader;
370
371
372 DPRINT("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectClass, IoStack->FileObject, ObjectHeader);
373
374 return STATUS_SUCCESS;
375
376 }
377
378 /*
379 @unimplemented
380 */
381 KSDDKAPI
382 VOID
383 NTAPI
384 KsFreeObjectHeader(
385 IN PVOID Header)
386 {
387
388
389 }
390
391 /*
392 @unimplemented
393 */
394 KSDDKAPI VOID NTAPI
395 KsCancelIo(
396 IN OUT PLIST_ENTRY QueueHead,
397 IN PKSPIN_LOCK SpinLock)
398 {
399 UNIMPLEMENTED;
400 }
401
402 /*
403 @unimplemented
404 */
405 KSDDKAPI VOID NTAPI
406 KsCancelRoutine(
407 IN PDEVICE_OBJECT DeviceObject,
408 IN PIRP Irp)
409 {
410 UNIMPLEMENTED;
411 }
412
413 /*
414 @unimplemented
415 */
416 KSDDKAPI NTSTATUS NTAPI
417 KsDefaultDeviceIoCompletion(
418 IN PDEVICE_OBJECT DeviceObject,
419 IN PIRP Irp)
420 {
421 UNIMPLEMENTED;
422 return STATUS_UNSUCCESSFUL;
423 }
424
425 /*
426 @unimplemented
427 */
428 KSDDKAPI BOOLEAN NTAPI
429 KsDispatchFastIoDeviceControlFailure(
430 IN PFILE_OBJECT FileObject,
431 IN BOOLEAN Wait,
432 IN PVOID InputBuffer OPTIONAL,
433 IN ULONG InputBufferLength,
434 OUT PVOID OutputBuffer OPTIONAL,
435 IN ULONG OutputBufferLength,
436 IN ULONG IoControlCode,
437 OUT PIO_STATUS_BLOCK IoStatus,
438 IN PDEVICE_OBJECT DeviceObject) /* always return false */
439 {
440 return FALSE;
441 }
442
443 /*
444 @unimplemented
445 */
446 KSDDKAPI BOOLEAN NTAPI
447 KsDispatchFastReadFailure(
448 IN PFILE_OBJECT FileObject,
449 IN PLARGE_INTEGER FileOffset,
450 IN ULONG Length,
451 IN BOOLEAN Wait,
452 IN ULONG LockKey,
453 OUT PVOID Buffer,
454 OUT PIO_STATUS_BLOCK IoStatus,
455 IN PDEVICE_OBJECT DeviceObject) /* always return false */
456 {
457 return FALSE;
458 }
459
460 /*
461 Used in dispatch table entries that aren't handled and need to return
462 STATUS_INVALID_DEVICE_REQUEST.
463 */
464 KSDDKAPI NTSTATUS NTAPI
465 KsDispatchInvalidDeviceRequest(
466 IN PDEVICE_OBJECT DeviceObject,
467 IN PIRP Irp)
468 {
469 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
470 IoCompleteRequest(Irp, IO_NO_INCREMENT);
471
472 return STATUS_INVALID_DEVICE_REQUEST;
473 }
474
475 /*
476 @unimplemented
477 */
478 KSDDKAPI NTSTATUS NTAPI
479 KsDispatchSpecificMethod(
480 IN PIRP Irp,
481 IN PFNKSHANDLER Handler)
482 {
483 UNIMPLEMENTED;
484 return STATUS_UNSUCCESSFUL;
485 }
486
487 /*
488 @unimplemented
489 */
490 KSDDKAPI NTSTATUS NTAPI
491 KsDispatchSpecificProperty(
492 IN PIRP Irp,
493 IN PFNKSHANDLER Handler)
494 {
495 UNIMPLEMENTED;
496 return STATUS_UNSUCCESSFUL;
497 }
498
499 /*
500 @unimplemented
501 */
502 KSDDKAPI NTSTATUS NTAPI
503 KsForwardAndCatchIrp(
504 IN PDEVICE_OBJECT DeviceObject,
505 IN PIRP Irp,
506 IN PFILE_OBJECT FileObject,
507 IN KSSTACK_USE StackUse)
508 {
509 UNIMPLEMENTED;
510 return STATUS_UNSUCCESSFUL;
511 }
512
513 /*
514 @unimplemented
515 */
516 KSDDKAPI NTSTATUS NTAPI
517 KsForwardIrp(
518 IN PIRP Irp,
519 IN PFILE_OBJECT FileObject,
520 IN BOOLEAN ReuseStackLocation)
521 {
522 UNIMPLEMENTED;
523 return STATUS_UNSUCCESSFUL;
524 }
525
526 /*
527 @unimplemented
528 */
529 KSDDKAPI NTSTATUS NTAPI
530 KsGetChildCreateParameter(
531 IN PIRP Irp,
532 OUT PVOID* CreateParameter)
533 {
534 UNIMPLEMENTED;
535 return STATUS_UNSUCCESSFUL;
536 }
537
538 /*
539 @unimplemented
540 */
541 KSDDKAPI NTSTATUS NTAPI
542 KsMoveIrpsOnCancelableQueue(
543 IN OUT PLIST_ENTRY SourceList,
544 IN PKSPIN_LOCK SourceLock,
545 IN OUT PLIST_ENTRY DestinationList,
546 IN PKSPIN_LOCK DestinationLock OPTIONAL,
547 IN KSLIST_ENTRY_LOCATION ListLocation,
548 IN PFNKSIRPLISTCALLBACK ListCallback,
549 IN PVOID Context)
550 {
551 UNIMPLEMENTED;
552 return STATUS_UNSUCCESSFUL;
553 }
554
555 /*
556 @unimplemented
557 */
558 KSDDKAPI NTSTATUS NTAPI
559 KsProbeStreamIrp(
560 IN PIRP Irp,
561 IN ULONG ProbeFlags,
562 IN ULONG HeaderSize)
563 {
564 UNIMPLEMENTED;
565 return STATUS_UNSUCCESSFUL;
566 }
567
568 /*
569 @unimplemented
570 */
571 KSDDKAPI NTSTATUS NTAPI
572 KsQueryInformationFile(
573 IN PFILE_OBJECT FileObject,
574 OUT PVOID FileInformation,
575 IN ULONG Length,
576 IN FILE_INFORMATION_CLASS FileInformationClass)
577 {
578 UNIMPLEMENTED;
579 return STATUS_UNSUCCESSFUL;
580 }
581
582 /*
583 @unimplemented
584 */
585 KSDDKAPI ACCESS_MASK NTAPI
586 KsQueryObjectAccessMask(
587 IN KSOBJECT_HEADER Header)
588 {
589 UNIMPLEMENTED;
590 return STATUS_UNSUCCESSFUL;
591 }
592
593 /*
594 @unimplemented
595 */
596 KSDDKAPI PKSOBJECT_CREATE_ITEM NTAPI
597 KsQueryObjectCreateItem(
598 IN KSOBJECT_HEADER Header)
599 {
600 UNIMPLEMENTED;
601 /* return STATUS_UNSUCCESSFUL; */
602 return NULL;
603 }
604
605 /*
606 @unimplemented
607 */
608 KSDDKAPI NTSTATUS NTAPI
609 KsReadFile(
610 IN PFILE_OBJECT FileObject,
611 IN PKEVENT Event OPTIONAL,
612 IN PVOID PortContext OPTIONAL,
613 OUT PIO_STATUS_BLOCK IoStatusBlock,
614 OUT PVOID Buffer,
615 IN ULONG Length,
616 IN ULONG Key OPTIONAL,
617 IN KPROCESSOR_MODE RequestorMode)
618 {
619 UNIMPLEMENTED;
620 return STATUS_UNSUCCESSFUL;
621 }
622
623 /*
624 @unimplemented
625 */
626 KSDDKAPI VOID NTAPI
627 KsReleaseIrpOnCancelableQueue(
628 IN PIRP Irp,
629 IN PDRIVER_CANCEL DriverCancel OPTIONAL)
630 {
631 UNIMPLEMENTED;
632 }
633
634 /*
635 @implemented
636 */
637 KSDDKAPI
638 PIRP
639 NTAPI
640 KsRemoveIrpFromCancelableQueue(
641 IN OUT PLIST_ENTRY QueueHead,
642 IN PKSPIN_LOCK SpinLock,
643 IN KSLIST_ENTRY_LOCATION ListLocation,
644 IN KSIRP_REMOVAL_OPERATION RemovalOperation)
645 {
646 PQUEUE_ENTRY Entry = NULL;
647 PIRP Irp;
648 KIRQL OldIrql;
649
650 if (!QueueHead || !SpinLock)
651 return NULL;
652
653 if (ListLocation != KsListEntryTail && ListLocation != KsListEntryHead)
654 return NULL;
655
656 if (RemovalOperation != KsAcquireOnly && RemovalOperation != KsAcquireAndRemove)
657 return NULL;
658
659 KeAcquireSpinLock(SpinLock, &OldIrql);
660
661 if (!IsListEmpty(QueueHead))
662 {
663 if (RemovalOperation == KsAcquireOnly)
664 {
665 if (ListLocation == KsListEntryHead)
666 Entry = (PQUEUE_ENTRY)QueueHead->Flink;
667 else
668 Entry = (PQUEUE_ENTRY)QueueHead->Blink;
669 }
670 else if (RemovalOperation == KsAcquireAndRemove)
671 {
672 if (ListLocation == KsListEntryTail)
673 Entry = (PQUEUE_ENTRY)RemoveTailList(QueueHead);
674 else
675 Entry = (PQUEUE_ENTRY)RemoveHeadList(QueueHead);
676 }
677 }
678 KeReleaseSpinLock(SpinLock, OldIrql);
679
680 if (!Entry)
681 return NULL;
682
683 Irp = Entry->Irp;
684
685 if (RemovalOperation == KsAcquireAndRemove)
686 ExFreePool(Entry);
687
688 return Irp;
689 }
690
691 /*
692 @unimplemented
693 */
694 KSDDKAPI VOID NTAPI
695 KsRemoveSpecificIrpFromCancelableQueue(
696 IN PIRP Irp)
697 {
698 UNIMPLEMENTED;
699 }
700
701 /*
702 @unimplemented
703 */
704 KSDDKAPI NTSTATUS NTAPI
705 KsSetInformationFile(
706 IN PFILE_OBJECT FileObject,
707 IN PVOID FileInformation,
708 IN ULONG Length,
709 IN FILE_INFORMATION_CLASS FileInformationClass)
710 {
711 UNIMPLEMENTED;
712 return STATUS_UNSUCCESSFUL;
713 }
714
715
716
717 NTAPI
718 NTSTATUS
719 KsCreate(
720 IN PDEVICE_OBJECT DeviceObject,
721 IN PIRP Irp)
722 {
723 //PIO_STACK_LOCATION IoStack;
724 PDEVICE_EXTENSION DeviceExtension;
725 PKSIDEVICE_HEADER DeviceHeader;
726 ULONG Index;
727 NTSTATUS Status = STATUS_SUCCESS;
728 KIRQL OldLevel;
729
730 DPRINT("KS / CREATE\n");
731 /* get current stack location */
732 //IoStack = IoGetCurrentIrpStackLocation(Irp);
733 /* get device extension */
734 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
735 /* get device header */
736 DeviceHeader = DeviceExtension->DeviceHeader;
737
738 /* acquire list lock */
739 KeAcquireSpinLock(&DeviceHeader->ItemListLock, &OldLevel);
740 /* loop all device items */
741 for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
742 {
743 if (DeviceHeader->ItemList[Index].bCreated && DeviceHeader->ItemList[Index].ObjectHeader == NULL)
744 {
745 DeviceHeader->DeviceIndex = Index;
746 /* set object create item */
747 KSCREATE_ITEM_IRP_STORAGE(Irp) = &DeviceHeader->ItemList[Index].CreateItem;
748 Status = DeviceHeader->ItemList[Index].CreateItem.Create(DeviceObject, Irp);
749 }
750 }
751
752 /* release lock */
753 KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
754 return Status;
755 }
756
757 static NTAPI
758 NTSTATUS
759 KsClose(
760 IN PDEVICE_OBJECT DeviceObject,
761 IN PIRP Irp)
762 {
763 PIO_STACK_LOCATION IoStack;
764 PKSIOBJECT_HEADER ObjectHeader;
765
766 /* get current stack location */
767 IoStack = IoGetCurrentIrpStackLocation(Irp);
768
769 DPRINT("KS / CLOSE\n");
770
771 if (IoStack->FileObject && IoStack->FileObject->FsContext)
772 {
773 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
774
775 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
776 return ObjectHeader->DispatchTable.Close(DeviceObject, Irp);
777 }
778 else
779 {
780 DPRINT1("Expected Object Header\n");
781 return STATUS_SUCCESS;
782 }
783 }
784
785 static NTAPI
786 NTSTATUS
787 KsDeviceControl(
788 IN PDEVICE_OBJECT DeviceObject,
789 IN PIRP Irp)
790 {
791 PIO_STACK_LOCATION IoStack;
792 PKSIOBJECT_HEADER ObjectHeader;
793
794 /* get current stack location */
795 IoStack = IoGetCurrentIrpStackLocation(Irp);
796
797 DPRINT("KS / DeviceControl\n");
798 if (IoStack->FileObject && IoStack->FileObject->FsContext)
799 {
800 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
801
802 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
803 return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp);
804 }
805 else
806 {
807 DPRINT1("Expected Object Header\n");
808 KeBugCheckEx(0, 0, 0, 0, 0);
809 return STATUS_SUCCESS;
810 }
811 }
812
813 static NTAPI
814 NTSTATUS
815 KsRead(
816 IN PDEVICE_OBJECT DeviceObject,
817 IN PIRP Irp)
818 {
819 PIO_STACK_LOCATION IoStack;
820 PKSIOBJECT_HEADER ObjectHeader;
821
822 /* get current stack location */
823 IoStack = IoGetCurrentIrpStackLocation(Irp);
824
825 DPRINT("KS / Read\n");
826 if (IoStack->FileObject && IoStack->FileObject->FsContext)
827 {
828 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
829
830 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
831 return ObjectHeader->DispatchTable.Read(DeviceObject, Irp);
832 }
833 else
834 {
835 DPRINT1("Expected Object Header\n");
836 KeBugCheckEx(0, 0, 0, 0, 0);
837 return STATUS_SUCCESS;
838 }
839 }
840
841 static NTAPI
842 NTSTATUS
843 KsWrite(
844 IN PDEVICE_OBJECT DeviceObject,
845 IN PIRP Irp)
846 {
847 PIO_STACK_LOCATION IoStack;
848 PKSIOBJECT_HEADER ObjectHeader;
849
850 /* get current stack location */
851 IoStack = IoGetCurrentIrpStackLocation(Irp);
852
853 DPRINT("KS / Write\n");
854 if (IoStack->FileObject && IoStack->FileObject->FsContext)
855 {
856 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
857
858 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
859 return ObjectHeader->DispatchTable.Write(DeviceObject, Irp);
860 }
861 else
862 {
863 DPRINT1("Expected Object Header %p\n", IoStack->FileObject);
864 KeBugCheckEx(0, 0, 0, 0, 0);
865 return STATUS_SUCCESS;
866 }
867 }
868
869 static NTAPI
870 NTSTATUS
871 KsFlushBuffers(
872 IN PDEVICE_OBJECT DeviceObject,
873 IN PIRP Irp)
874 {
875 PIO_STACK_LOCATION IoStack;
876 PKSIOBJECT_HEADER ObjectHeader;
877
878 /* get current stack location */
879 IoStack = IoGetCurrentIrpStackLocation(Irp);
880
881 DPRINT("KS / FlushBuffers\n");
882 if (IoStack->FileObject && IoStack->FileObject->FsContext)
883 {
884 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
885
886 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
887 return ObjectHeader->DispatchTable.Flush(DeviceObject, Irp);
888 }
889 else
890 {
891 DPRINT1("Expected Object Header\n");
892 KeBugCheckEx(0, 0, 0, 0, 0);
893 return STATUS_SUCCESS;
894 }
895 }
896
897 static NTAPI
898 NTSTATUS
899 KsQuerySecurity(
900 IN PDEVICE_OBJECT DeviceObject,
901 IN PIRP Irp)
902 {
903 PIO_STACK_LOCATION IoStack;
904 PKSIOBJECT_HEADER ObjectHeader;
905
906 /* get current stack location */
907 IoStack = IoGetCurrentIrpStackLocation(Irp);
908
909 DPRINT("KS / QuerySecurity\n");
910 if (IoStack->FileObject && IoStack->FileObject->FsContext)
911 {
912 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
913
914 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
915 return ObjectHeader->DispatchTable.QuerySecurity(DeviceObject, Irp);
916 }
917 else
918 {
919 DPRINT1("Expected Object Header\n");
920 KeBugCheckEx(0, 0, 0, 0, 0);
921 return STATUS_SUCCESS;
922 }
923 }
924
925 static NTAPI
926 NTSTATUS
927 KsSetSecurity(
928 IN PDEVICE_OBJECT DeviceObject,
929 IN PIRP Irp)
930 {
931 PIO_STACK_LOCATION IoStack;
932 PKSIOBJECT_HEADER ObjectHeader;
933
934 /* get current stack location */
935 IoStack = IoGetCurrentIrpStackLocation(Irp);
936
937 DPRINT("KS / SetSecurity\n");
938 if (IoStack->FileObject && IoStack->FileObject->FsContext)
939 {
940 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
941
942 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
943 return ObjectHeader->DispatchTable.SetSecurity(DeviceObject, Irp);
944 }
945 else
946 {
947 DPRINT1("Expected Object Header\n");
948 KeBugCheckEx(0, 0, 0, 0, 0);
949 return STATUS_SUCCESS;
950 }
951 }
952
953 /*
954 @implemented
955 */
956 KSDDKAPI NTSTATUS NTAPI
957 KsSetMajorFunctionHandler(
958 IN PDRIVER_OBJECT DriverObject,
959 IN ULONG MajorFunction)
960 {
961 /*
962 Sets a DriverObject's major function handler to point to an internal
963 function we implement.
964
965 TODO: Deal with KSDISPATCH_FASTIO
966 */
967
968 switch ( MajorFunction )
969 {
970 case IRP_MJ_CREATE:
971 DriverObject->MajorFunction[MajorFunction] = KsCreate;
972 break;
973 case IRP_MJ_CLOSE:
974 DriverObject->MajorFunction[MajorFunction] = KsClose;
975 break;
976 case IRP_MJ_DEVICE_CONTROL:
977 DriverObject->MajorFunction[MajorFunction] = KsDeviceControl;
978 break;
979 case IRP_MJ_READ:
980 DriverObject->MajorFunction[MajorFunction] = KsRead;
981 break;
982 case IRP_MJ_WRITE:
983 DriverObject->MajorFunction[MajorFunction] = KsWrite;
984 break;
985 case IRP_MJ_FLUSH_BUFFERS :
986 DriverObject->MajorFunction[MajorFunction] = KsFlushBuffers;
987 break;
988 case IRP_MJ_QUERY_SECURITY:
989 DriverObject->MajorFunction[MajorFunction] = KsQuerySecurity;
990 break;
991 case IRP_MJ_SET_SECURITY:
992 DriverObject->MajorFunction[MajorFunction] = KsSetSecurity;
993 break;
994
995 default:
996 return STATUS_INVALID_PARAMETER; /* is this right? */
997 };
998
999 return STATUS_SUCCESS;
1000 }
1001
1002 /*
1003 @implemented
1004 */
1005 KSDDKAPI
1006 NTSTATUS
1007 NTAPI
1008 KsDispatchIrp(
1009 IN PDEVICE_OBJECT DeviceObject,
1010 IN PIRP Irp)
1011 {
1012 PIO_STACK_LOCATION IoStack;
1013
1014 /* Calls a dispatch routine corresponding to the function code of the IRP */
1015 /*
1016 First we need to get the dispatch table. An opaque header is pointed to by
1017 FsContext. The first element points to this table. This table is the key
1018 to dispatching the IRP correctly.
1019 */
1020
1021 IoStack = IoGetCurrentIrpStackLocation(Irp);
1022 DPRINT("KsDispatchIrp %x\n", IoStack->MajorFunction);
1023
1024 switch (IoStack->MajorFunction)
1025 {
1026 case IRP_MJ_CREATE:
1027 return KsCreate(DeviceObject, Irp);
1028 case IRP_MJ_CLOSE:
1029 return KsClose(DeviceObject, Irp);
1030 break;
1031 case IRP_MJ_DEVICE_CONTROL:
1032 return KsDeviceControl(DeviceObject, Irp);
1033 break;
1034 case IRP_MJ_READ:
1035 return KsRead(DeviceObject, Irp);
1036 break;
1037 case IRP_MJ_WRITE:
1038 return KsWrite(DeviceObject, Irp);
1039 break;
1040 case IRP_MJ_FLUSH_BUFFERS:
1041 return KsFlushBuffers(DeviceObject, Irp);
1042 break;
1043 case IRP_MJ_QUERY_SECURITY:
1044 return KsQuerySecurity(DeviceObject, Irp);
1045 break;
1046 case IRP_MJ_SET_SECURITY:
1047 return KsSetSecurity(DeviceObject, Irp);
1048 break;
1049 default:
1050 return STATUS_INVALID_PARAMETER; /* is this right? */
1051 };
1052 }
1053
1054
1055 /*
1056 @implemented
1057 */
1058 KSDDKAPI
1059 NTSTATUS
1060 NTAPI
1061 KsStreamIo(
1062 IN PFILE_OBJECT FileObject,
1063 IN PKEVENT Event OPTIONAL,
1064 IN PVOID PortContext OPTIONAL,
1065 IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
1066 IN PVOID CompletionContext OPTIONAL,
1067 IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL,
1068 OUT PIO_STATUS_BLOCK IoStatusBlock,
1069 IN OUT PVOID StreamHeaders,
1070 IN ULONG Length,
1071 IN ULONG Flags,
1072 IN KPROCESSOR_MODE RequestorMode)
1073 {
1074 PIRP Irp;
1075 PIO_STACK_LOCATION IoStack;
1076 PDEVICE_OBJECT DeviceObject;
1077 ULONG Code;
1078 NTSTATUS Status;
1079 LARGE_INTEGER Offset;
1080 PKSIOBJECT_HEADER ObjectHeader;
1081
1082
1083 if (Flags == KSSTREAM_READ)
1084 Code = IRP_MJ_READ;
1085 else if (Flags == KSSTREAM_WRITE)
1086 Code = IRP_MJ_WRITE;
1087 else
1088 return STATUS_INVALID_PARAMETER;
1089
1090 DeviceObject = IoGetRelatedDeviceObject(FileObject);
1091 if (!DeviceObject)
1092 return STATUS_INVALID_PARAMETER;
1093
1094 if (Event)
1095 {
1096 KeResetEvent(Event);
1097 }
1098
1099 //ASSERT(DeviceObject->DeviceType == FILE_DEVICE_KS);
1100 ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext;
1101 ASSERT(ObjectHeader);
1102 if (Code == IRP_MJ_READ)
1103 {
1104 if (ObjectHeader->DispatchTable.FastRead)
1105 {
1106 if (ObjectHeader->DispatchTable.FastRead(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject))
1107 {
1108 return STATUS_SUCCESS;
1109 }
1110 }
1111 }
1112 else
1113 {
1114 if (ObjectHeader->DispatchTable.FastWrite)
1115 {
1116 if (ObjectHeader->DispatchTable.FastWrite(FileObject, NULL, Length, FALSE, 0, StreamHeaders, IoStatusBlock, DeviceObject))
1117 {
1118 return STATUS_SUCCESS;
1119 }
1120 }
1121 }
1122
1123 Offset.QuadPart = 0LL;
1124 Irp = IoBuildSynchronousFsdRequest(Code, DeviceObject, (PVOID)StreamHeaders, Length, &Offset, Event, IoStatusBlock);
1125 if (!Irp)
1126 {
1127 return STATUS_UNSUCCESSFUL;
1128 }
1129
1130
1131 if (CompletionRoutine)
1132 {
1133 IoSetCompletionRoutine(Irp,
1134 CompletionRoutine,
1135 CompletionContext,
1136 (CompletionInvocationFlags & KsInvokeOnSuccess),
1137 (CompletionInvocationFlags & KsInvokeOnError),
1138 (CompletionInvocationFlags & KsInvokeOnCancel));
1139 }
1140
1141 IoStack = IoGetNextIrpStackLocation(Irp);
1142 IoStack->FileObject = FileObject;
1143
1144 Status = IoCallDriver(DeviceObject, Irp);
1145 return Status;
1146 }
1147
1148 /*
1149 @unimplemented
1150 */
1151 KSDDKAPI NTSTATUS NTAPI
1152 KsWriteFile(
1153 IN PFILE_OBJECT FileObject,
1154 IN PKEVENT Event OPTIONAL,
1155 IN PVOID PortContext OPTIONAL,
1156 OUT PIO_STATUS_BLOCK IoStatusBlock,
1157 IN PVOID Buffer,
1158 IN ULONG Length,
1159 IN ULONG Key OPTIONAL,
1160 IN KPROCESSOR_MODE RequestorMode)
1161 {
1162 UNIMPLEMENTED;
1163 return STATUS_UNSUCCESSFUL;
1164 }
1165
1166 /*
1167 @unimplemented
1168 */
1169 KSDDKAPI NTSTATUS NTAPI
1170 KsDefaultForwardIrp(
1171 IN PDEVICE_OBJECT DeviceObject,
1172 IN PIRP Irp)
1173 {
1174 UNIMPLEMENTED;
1175 Irp->IoStatus.Information = 0;
1176 Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
1177 IoCompleteRequest(Irp, IO_NO_INCREMENT);
1178 return STATUS_UNSUCCESSFUL;
1179 }
1180