- Implement KsAddIrpToCancelableQueue and KsRemoveIrpFromCancelableQueue
[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], &ItemsList[Index], sizeof(KSOBJECT_CREATE_ITEM));
192 }
193 Header->MaxItems = ItemsCount;
194 }
195
196 /* store result */
197 *OutHeader = Header;
198
199 return STATUS_SUCCESS;
200 }
201
202 /*
203 @unimplemented
204
205 http://www.osronline.com/DDKx/stream/ksfunc_3sc3.htm
206 */
207 KSDDKAPI
208 NTSTATUS
209 NTAPI
210 KsAllocateObjectCreateItem(
211 IN KSDEVICE_HEADER DevHeader,
212 IN PKSOBJECT_CREATE_ITEM CreateItem,
213 IN BOOLEAN AllocateEntry,
214 IN PFNKSITEMFREECALLBACK ItemFreeCallback OPTIONAL)
215 {
216 PKSIDEVICE_HEADER Header;
217
218 Header = (PKSIDEVICE_HEADER)DevHeader;
219
220 if (!DevHeader)
221 return STATUS_INVALID_PARAMETER_1;
222
223 if (!CreateItem)
224 return STATUS_INVALID_PARAMETER_2;
225
226 //FIXME
227 //handle ItemFreeCallback
228 //
229 if (AllocateEntry && ItemFreeCallback)
230 DPRINT1("Ignoring ItemFreeCallback\n");
231
232 return KsAddObjectCreateItemToDeviceHeader(DevHeader, CreateItem->Create, CreateItem->Context, CreateItem->ObjectClass.Buffer, CreateItem->SecurityDescriptor);
233 }
234
235
236 /*
237 @implemented
238 */
239 KSDDKAPI
240 VOID
241 NTAPI
242 KsFreeDeviceHeader(
243 IN KSDEVICE_HEADER DevHeader)
244 {
245 PKSIDEVICE_HEADER Header;
246
247 Header = (PKSIDEVICE_HEADER)DevHeader;
248
249 if (!DevHeader)
250 return;
251
252 ExFreePoolWithTag(Header->ItemList, TAG_DEVICE_HEADER);
253 ExFreePoolWithTag(Header, TAG_DEVICE_HEADER);
254 }
255
256 /*
257 @unimplemented
258 */
259 KSDDKAPI NTSTATUS NTAPI
260 KsAllocateExtraData(
261 IN PIRP Irp,
262 IN ULONG ExtraSize,
263 OUT PVOID* ExtraBuffer)
264 {
265 UNIMPLEMENTED;
266 return STATUS_UNSUCCESSFUL;
267 }
268
269 /*
270 @unimplemented
271
272 Initialize the required file context header.
273 Allocates KSOBJECT_HEADER structure.
274 Irp is an IRP_MJ_CREATE structure.
275 Driver must allocate KSDISPATCH_TABLE and initialize it first.
276
277 http://www.osronline.com/DDKx/stream/ksfunc_0u2b.htm
278 */
279 KSDDKAPI
280 NTSTATUS
281 NTAPI
282 KsAllocateObjectHeader(
283 OUT KSOBJECT_HEADER *Header,
284 IN ULONG ItemsCount,
285 IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL,
286 IN PIRP Irp,
287 IN KSDISPATCH_TABLE* Table)
288 {
289 PIO_STACK_LOCATION IoStack;
290 PDEVICE_EXTENSION DeviceExtension;
291 PKSIDEVICE_HEADER DeviceHeader;
292 PKSIOBJECT_HEADER ObjectHeader;
293 WCHAR ObjectClass[50];
294
295 if (!Header)
296 return STATUS_INVALID_PARAMETER_1;
297
298 if (!Irp)
299 return STATUS_INVALID_PARAMETER_4;
300
301 if (!Table)
302 return STATUS_INVALID_PARAMETER_5;
303
304 /* get current stack location */
305 IoStack = IoGetCurrentIrpStackLocation(Irp);
306 /* get device extension */
307 DeviceExtension = (PDEVICE_EXTENSION)IoStack->DeviceObject->DeviceExtension;
308 /* get device header */
309 DeviceHeader = DeviceExtension->DeviceHeader;
310
311 ObjectClass[0] = L'\0';
312 /* check for an file object */
313 if (IoStack->FileObject != NULL)
314 {
315 /* validate the file name */
316 if (IoStack->FileObject->FileName.Length >= 38)
317 {
318 RtlMoveMemory(ObjectClass, IoStack->FileObject->FileName.Buffer, 38 * sizeof(WCHAR));
319 ObjectClass[38] = L'\0';
320 DPRINT1("ObjectClass %S\n", ObjectClass);
321 }
322 }
323 /* allocate the object header */
324 ObjectHeader = ExAllocatePoolWithTag(NonPagedPool, sizeof(KSIOBJECT_HEADER), TAG_DEVICE_HEADER);
325 if (!ObjectHeader)
326 return STATUS_INSUFFICIENT_RESOURCES;
327
328 /* initialize object header */
329 RtlZeroMemory(ObjectHeader, sizeof(KSIOBJECT_HEADER));
330
331 /* do we have a name */
332 if (ObjectClass[0])
333 {
334 ObjectHeader->ObjectClass = ExAllocatePoolWithTag(NonPagedPool, 40 * sizeof(WCHAR), TAG_DEVICE_HEADER);
335 if (ObjectHeader->ObjectClass)
336 {
337 wcscpy(ObjectHeader->ObjectClass, ObjectClass);
338 }
339 }
340
341 /* copy dispatch table */
342 RtlCopyMemory(&ObjectHeader->DispatchTable, Table, sizeof(KSDISPATCH_TABLE));
343 /* store create items */
344 if (ItemsCount && ItemsList)
345 {
346 ObjectHeader->ItemCount = ItemsCount;
347 ObjectHeader->CreateItem = ItemsList;
348 }
349
350 /* was the request for a pin/clock/node */
351 if (IoStack->FileObject)
352 {
353 /* store the object in the file object */
354 ASSERT(IoStack->FileObject->FsContext == NULL);
355 IoStack->FileObject->FsContext = ObjectHeader;
356 }
357 else
358 {
359 /* the object header is for device */
360 ASSERT(DeviceHeader->DeviceIndex < DeviceHeader->MaxItems);
361 DeviceHeader->ItemList[DeviceHeader->DeviceIndex].ObjectHeader = ObjectHeader;
362 }
363
364 /* store result */
365 *Header = ObjectHeader;
366
367
368 DPRINT1("KsAllocateObjectHeader ObjectClass %S FileObject %p, ObjectHeader %p\n", ObjectClass, IoStack->FileObject, ObjectHeader);
369
370 return STATUS_SUCCESS;
371
372 }
373
374 /*
375 @unimplemented
376 */
377 KSDDKAPI
378 VOID
379 NTAPI
380 KsFreeObjectHeader(
381 IN PVOID Header)
382 {
383
384
385 }
386
387 /*
388 @unimplemented
389 */
390 KSDDKAPI VOID NTAPI
391 KsCancelIo(
392 IN OUT PLIST_ENTRY QueueHead,
393 IN PKSPIN_LOCK SpinLock)
394 {
395 UNIMPLEMENTED;
396 }
397
398 /*
399 @unimplemented
400 */
401 KSDDKAPI VOID NTAPI
402 KsCancelRoutine(
403 IN PDEVICE_OBJECT DeviceObject,
404 IN PIRP Irp)
405 {
406 UNIMPLEMENTED;
407 }
408
409 /*
410 @unimplemented
411 */
412 KSDDKAPI NTSTATUS NTAPI
413 KsDefaultDeviceIoCompletion(
414 IN PDEVICE_OBJECT DeviceObject,
415 IN PIRP Irp)
416 {
417 UNIMPLEMENTED;
418 return STATUS_UNSUCCESSFUL;
419 }
420
421 /*
422 @unimplemented
423 */
424 KSDDKAPI BOOLEAN NTAPI
425 KsDispatchFastIoDeviceControlFailure(
426 IN PFILE_OBJECT FileObject,
427 IN BOOLEAN Wait,
428 IN PVOID InputBuffer OPTIONAL,
429 IN ULONG InputBufferLength,
430 OUT PVOID OutputBuffer OPTIONAL,
431 IN ULONG OutputBufferLength,
432 IN ULONG IoControlCode,
433 OUT PIO_STATUS_BLOCK IoStatus,
434 IN PDEVICE_OBJECT DeviceObject) /* always return false */
435 {
436 return FALSE;
437 }
438
439 /*
440 @unimplemented
441 */
442 KSDDKAPI BOOLEAN NTAPI
443 KsDispatchFastReadFailure(
444 IN PFILE_OBJECT FileObject,
445 IN PLARGE_INTEGER FileOffset,
446 IN ULONG Length,
447 IN BOOLEAN Wait,
448 IN ULONG LockKey,
449 OUT PVOID Buffer,
450 OUT PIO_STATUS_BLOCK IoStatus,
451 IN PDEVICE_OBJECT DeviceObject) /* always return false */
452 {
453 return FALSE;
454 }
455
456 /*
457 Used in dispatch table entries that aren't handled and need to return
458 STATUS_INVALID_DEVICE_REQUEST.
459 */
460 KSDDKAPI NTSTATUS NTAPI
461 KsDispatchInvalidDeviceRequest(
462 IN PDEVICE_OBJECT DeviceObject,
463 IN PIRP Irp)
464 {
465 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
466 IoCompleteRequest(Irp, IO_NO_INCREMENT);
467
468 return STATUS_INVALID_DEVICE_REQUEST;
469 }
470
471 /*
472 @unimplemented
473 */
474 KSDDKAPI NTSTATUS NTAPI
475 KsDispatchSpecificMethod(
476 IN PIRP Irp,
477 IN PFNKSHANDLER Handler)
478 {
479 UNIMPLEMENTED;
480 return STATUS_UNSUCCESSFUL;
481 }
482
483 /*
484 @unimplemented
485 */
486 KSDDKAPI NTSTATUS NTAPI
487 KsDispatchSpecificProperty(
488 IN PIRP Irp,
489 IN PFNKSHANDLER Handler)
490 {
491 UNIMPLEMENTED;
492 return STATUS_UNSUCCESSFUL;
493 }
494
495 /*
496 @unimplemented
497 */
498 KSDDKAPI NTSTATUS NTAPI
499 KsForwardAndCatchIrp(
500 IN PDEVICE_OBJECT DeviceObject,
501 IN PIRP Irp,
502 IN PFILE_OBJECT FileObject,
503 IN KSSTACK_USE StackUse)
504 {
505 UNIMPLEMENTED;
506 return STATUS_UNSUCCESSFUL;
507 }
508
509 /*
510 @unimplemented
511 */
512 KSDDKAPI NTSTATUS NTAPI
513 KsForwardIrp(
514 IN PIRP Irp,
515 IN PFILE_OBJECT FileObject,
516 IN BOOLEAN ReuseStackLocation)
517 {
518 UNIMPLEMENTED;
519 return STATUS_UNSUCCESSFUL;
520 }
521
522 /*
523 @unimplemented
524 */
525 KSDDKAPI NTSTATUS NTAPI
526 KsGetChildCreateParameter(
527 IN PIRP Irp,
528 OUT PVOID* CreateParameter)
529 {
530 UNIMPLEMENTED;
531 return STATUS_UNSUCCESSFUL;
532 }
533
534 /*
535 @unimplemented
536 */
537 KSDDKAPI NTSTATUS NTAPI
538 KsMoveIrpsOnCancelableQueue(
539 IN OUT PLIST_ENTRY SourceList,
540 IN PKSPIN_LOCK SourceLock,
541 IN OUT PLIST_ENTRY DestinationList,
542 IN PKSPIN_LOCK DestinationLock OPTIONAL,
543 IN KSLIST_ENTRY_LOCATION ListLocation,
544 IN PFNKSIRPLISTCALLBACK ListCallback,
545 IN PVOID Context)
546 {
547 UNIMPLEMENTED;
548 return STATUS_UNSUCCESSFUL;
549 }
550
551 /*
552 @unimplemented
553 */
554 KSDDKAPI NTSTATUS NTAPI
555 KsProbeStreamIrp(
556 IN PIRP Irp,
557 IN ULONG ProbeFlags,
558 IN ULONG HeaderSize)
559 {
560 UNIMPLEMENTED;
561 return STATUS_UNSUCCESSFUL;
562 }
563
564 /*
565 @unimplemented
566 */
567 KSDDKAPI NTSTATUS NTAPI
568 KsQueryInformationFile(
569 IN PFILE_OBJECT FileObject,
570 OUT PVOID FileInformation,
571 IN ULONG Length,
572 IN FILE_INFORMATION_CLASS FileInformationClass)
573 {
574 UNIMPLEMENTED;
575 return STATUS_UNSUCCESSFUL;
576 }
577
578 /*
579 @unimplemented
580 */
581 KSDDKAPI ACCESS_MASK NTAPI
582 KsQueryObjectAccessMask(
583 IN KSOBJECT_HEADER Header)
584 {
585 UNIMPLEMENTED;
586 return STATUS_UNSUCCESSFUL;
587 }
588
589 /*
590 @unimplemented
591 */
592 KSDDKAPI PKSOBJECT_CREATE_ITEM NTAPI
593 KsQueryObjectCreateItem(
594 IN KSOBJECT_HEADER Header)
595 {
596 UNIMPLEMENTED;
597 /* return STATUS_UNSUCCESSFUL; */
598 return NULL;
599 }
600
601 /*
602 @unimplemented
603 */
604 KSDDKAPI NTSTATUS NTAPI
605 KsReadFile(
606 IN PFILE_OBJECT FileObject,
607 IN PKEVENT Event OPTIONAL,
608 IN PVOID PortContext OPTIONAL,
609 OUT PIO_STATUS_BLOCK IoStatusBlock,
610 OUT PVOID Buffer,
611 IN ULONG Length,
612 IN ULONG Key OPTIONAL,
613 IN KPROCESSOR_MODE RequestorMode)
614 {
615 UNIMPLEMENTED;
616 return STATUS_UNSUCCESSFUL;
617 }
618
619 /*
620 @unimplemented
621 */
622 KSDDKAPI VOID NTAPI
623 KsReleaseIrpOnCancelableQueue(
624 IN PIRP Irp,
625 IN PDRIVER_CANCEL DriverCancel OPTIONAL)
626 {
627 UNIMPLEMENTED;
628 }
629
630 /*
631 @implemented
632 */
633 KSDDKAPI
634 PIRP
635 NTAPI
636 KsRemoveIrpFromCancelableQueue(
637 IN OUT PLIST_ENTRY QueueHead,
638 IN PKSPIN_LOCK SpinLock,
639 IN KSLIST_ENTRY_LOCATION ListLocation,
640 IN KSIRP_REMOVAL_OPERATION RemovalOperation)
641 {
642 PQUEUE_ENTRY Entry = NULL;
643 PIRP Irp;
644 KIRQL OldIrql;
645
646 if (!QueueHead || !SpinLock)
647 return NULL;
648
649 if (ListLocation != KsListEntryTail && ListLocation != KsListEntryHead)
650 return NULL;
651
652 if (RemovalOperation != KsAcquireOnly && RemovalOperation != KsAcquireAndRemove)
653 return NULL;
654
655 KeAcquireSpinLock(SpinLock, &OldIrql);
656
657 if (!IsListEmpty(QueueHead))
658 {
659 if (RemovalOperation == KsAcquireOnly)
660 {
661 if (ListLocation == KsListEntryHead)
662 Entry = (PQUEUE_ENTRY)QueueHead->Flink;
663 else
664 Entry = (PQUEUE_ENTRY)QueueHead->Blink;
665 }
666 else if (RemovalOperation == KsAcquireAndRemove)
667 {
668 if (ListLocation == KsListEntryTail)
669 Entry = (PQUEUE_ENTRY)RemoveTailList(QueueHead);
670 else
671 Entry = (PQUEUE_ENTRY)RemoveHeadList(QueueHead);
672 }
673 }
674 KeReleaseSpinLock(SpinLock, OldIrql);
675
676 if (!Entry)
677 return NULL;
678
679 Irp = Entry->Irp;
680
681 if (RemovalOperation == KsAcquireAndRemove)
682 ExFreePool(Entry);
683
684 return Irp;
685 }
686
687 /*
688 @unimplemented
689 */
690 KSDDKAPI VOID NTAPI
691 KsRemoveSpecificIrpFromCancelableQueue(
692 IN PIRP Irp)
693 {
694 UNIMPLEMENTED;
695 }
696
697 /*
698 @unimplemented
699 */
700 KSDDKAPI NTSTATUS NTAPI
701 KsSetInformationFile(
702 IN PFILE_OBJECT FileObject,
703 IN PVOID FileInformation,
704 IN ULONG Length,
705 IN FILE_INFORMATION_CLASS FileInformationClass)
706 {
707 UNIMPLEMENTED;
708 return STATUS_UNSUCCESSFUL;
709 }
710
711
712
713 NTAPI
714 NTSTATUS
715 KsCreate(
716 IN PDEVICE_OBJECT DeviceObject,
717 IN PIRP Irp)
718 {
719 PIO_STACK_LOCATION IoStack;
720 PDEVICE_EXTENSION DeviceExtension;
721 PKSIDEVICE_HEADER DeviceHeader;
722 ULONG Index;
723 NTSTATUS Status = STATUS_SUCCESS;
724 KIRQL OldLevel;
725
726 DPRINT1("KS / CREATE\n");
727 /* get current stack location */
728 IoStack = IoGetCurrentIrpStackLocation(Irp);
729 /* get device extension */
730 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
731 /* get device header */
732 DeviceHeader = DeviceExtension->DeviceHeader;
733
734 /* acquire list lock */
735 KeAcquireSpinLock(&DeviceHeader->ItemListLock, &OldLevel);
736 /* loop all device items */
737 for(Index = 0; Index < DeviceHeader->MaxItems; Index++)
738 {
739 if (DeviceHeader->ItemList[Index].bCreated && DeviceHeader->ItemList[Index].ObjectHeader == NULL)
740 {
741 DeviceHeader->DeviceIndex = Index;
742 /* set object create item */
743 KSCREATE_ITEM_IRP_STORAGE(Irp) = &DeviceHeader->ItemList[Index].CreateItem;
744 Status = DeviceHeader->ItemList[Index].CreateItem.Create(DeviceObject, Irp);
745 }
746 }
747
748 /* release lock */
749 KeReleaseSpinLock(&DeviceHeader->ItemListLock, OldLevel);
750 return Status;
751 }
752
753 static NTAPI
754 NTSTATUS
755 KsClose(
756 IN PDEVICE_OBJECT DeviceObject,
757 IN PIRP Irp)
758 {
759 PIO_STACK_LOCATION IoStack;
760 PKSIOBJECT_HEADER ObjectHeader;
761
762 /* get current stack location */
763 IoStack = IoGetCurrentIrpStackLocation(Irp);
764
765 DPRINT1("KS / CLOSE\n");
766
767 if (IoStack->FileObject && IoStack->FileObject->FsContext)
768 {
769 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
770
771 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
772 return ObjectHeader->DispatchTable.Close(DeviceObject, Irp);
773 }
774 else
775 {
776 DPRINT1("Expected Object Header\n");
777 return STATUS_SUCCESS;
778 }
779 }
780
781 static NTAPI
782 NTSTATUS
783 KsDeviceControl(
784 IN PDEVICE_OBJECT DeviceObject,
785 IN PIRP Irp)
786 {
787 PIO_STACK_LOCATION IoStack;
788 PKSIOBJECT_HEADER ObjectHeader;
789
790 /* get current stack location */
791 IoStack = IoGetCurrentIrpStackLocation(Irp);
792
793 DPRINT1("KS / DeviceControl\n");
794 if (IoStack->FileObject && IoStack->FileObject->FsContext)
795 {
796 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
797
798 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
799 return ObjectHeader->DispatchTable.DeviceIoControl(DeviceObject, Irp);
800 }
801 else
802 {
803 DPRINT1("Expected Object Header\n");
804 KeBugCheckEx(0, 0, 0, 0, 0);
805 return STATUS_SUCCESS;
806 }
807 }
808
809 static NTAPI
810 NTSTATUS
811 KsRead(
812 IN PDEVICE_OBJECT DeviceObject,
813 IN PIRP Irp)
814 {
815 PIO_STACK_LOCATION IoStack;
816 PKSIOBJECT_HEADER ObjectHeader;
817
818 /* get current stack location */
819 IoStack = IoGetCurrentIrpStackLocation(Irp);
820
821 DPRINT1("KS / Read\n");
822 if (IoStack->FileObject && IoStack->FileObject->FsContext)
823 {
824 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
825
826 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
827 return ObjectHeader->DispatchTable.Read(DeviceObject, Irp);
828 }
829 else
830 {
831 DPRINT1("Expected Object Header\n");
832 KeBugCheckEx(0, 0, 0, 0, 0);
833 return STATUS_SUCCESS;
834 }
835 }
836
837 static NTAPI
838 NTSTATUS
839 KsWrite(
840 IN PDEVICE_OBJECT DeviceObject,
841 IN PIRP Irp)
842 {
843 PIO_STACK_LOCATION IoStack;
844 PKSIOBJECT_HEADER ObjectHeader;
845
846 /* get current stack location */
847 IoStack = IoGetCurrentIrpStackLocation(Irp);
848
849 DPRINT1("KS / Write\n");
850 if (IoStack->FileObject && IoStack->FileObject->FsContext)
851 {
852 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
853
854 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
855 return ObjectHeader->DispatchTable.Write(DeviceObject, Irp);
856 }
857 else
858 {
859 DPRINT1("Expected Object Header\n");
860 KeBugCheckEx(0, 0, 0, 0, 0);
861 return STATUS_SUCCESS;
862 }
863 }
864
865 static NTAPI
866 NTSTATUS
867 KsFlushBuffers(
868 IN PDEVICE_OBJECT DeviceObject,
869 IN PIRP Irp)
870 {
871 PIO_STACK_LOCATION IoStack;
872 PKSIOBJECT_HEADER ObjectHeader;
873
874 /* get current stack location */
875 IoStack = IoGetCurrentIrpStackLocation(Irp);
876
877 DPRINT1("KS / FlushBuffers\n");
878 if (IoStack->FileObject && IoStack->FileObject->FsContext)
879 {
880 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
881
882 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
883 return ObjectHeader->DispatchTable.Flush(DeviceObject, Irp);
884 }
885 else
886 {
887 DPRINT1("Expected Object Header\n");
888 KeBugCheckEx(0, 0, 0, 0, 0);
889 return STATUS_SUCCESS;
890 }
891 }
892
893 static NTAPI
894 NTSTATUS
895 KsQuerySecurity(
896 IN PDEVICE_OBJECT DeviceObject,
897 IN PIRP Irp)
898 {
899 PIO_STACK_LOCATION IoStack;
900 PKSIOBJECT_HEADER ObjectHeader;
901
902 /* get current stack location */
903 IoStack = IoGetCurrentIrpStackLocation(Irp);
904
905 DPRINT1("KS / QuerySecurity\n");
906 if (IoStack->FileObject && IoStack->FileObject->FsContext)
907 {
908 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
909
910 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
911 return ObjectHeader->DispatchTable.QuerySecurity(DeviceObject, Irp);
912 }
913 else
914 {
915 DPRINT1("Expected Object Header\n");
916 KeBugCheckEx(0, 0, 0, 0, 0);
917 return STATUS_SUCCESS;
918 }
919 }
920
921 static NTAPI
922 NTSTATUS
923 KsSetSecurity(
924 IN PDEVICE_OBJECT DeviceObject,
925 IN PIRP Irp)
926 {
927 PIO_STACK_LOCATION IoStack;
928 PKSIOBJECT_HEADER ObjectHeader;
929
930 /* get current stack location */
931 IoStack = IoGetCurrentIrpStackLocation(Irp);
932
933 DPRINT1("KS / SetSecurity\n");
934 if (IoStack->FileObject && IoStack->FileObject->FsContext)
935 {
936 ObjectHeader = (PKSIOBJECT_HEADER) IoStack->FileObject->FsContext;
937
938 KSCREATE_ITEM_IRP_STORAGE(Irp) = ObjectHeader->CreateItem;
939 return ObjectHeader->DispatchTable.SetSecurity(DeviceObject, Irp);
940 }
941 else
942 {
943 DPRINT1("Expected Object Header\n");
944 KeBugCheckEx(0, 0, 0, 0, 0);
945 return STATUS_SUCCESS;
946 }
947 }
948
949 /*
950 @implemented
951 */
952 KSDDKAPI NTSTATUS NTAPI
953 KsSetMajorFunctionHandler(
954 IN PDRIVER_OBJECT DriverObject,
955 IN ULONG MajorFunction)
956 {
957 /*
958 Sets a DriverObject's major function handler to point to an internal
959 function we implement.
960
961 TODO: Deal with KSDISPATCH_FASTIO
962 */
963
964 switch ( MajorFunction )
965 {
966 case IRP_MJ_CREATE:
967 DriverObject->MajorFunction[MajorFunction] = KsCreate;
968 break;
969 case IRP_MJ_CLOSE:
970 DriverObject->MajorFunction[MajorFunction] = KsClose;
971 break;
972 case IRP_MJ_DEVICE_CONTROL:
973 DriverObject->MajorFunction[MajorFunction] = KsDeviceControl;
974 break;
975 case IRP_MJ_READ:
976 DriverObject->MajorFunction[MajorFunction] = KsRead;
977 break;
978 case IRP_MJ_WRITE:
979 DriverObject->MajorFunction[MajorFunction] = KsWrite;
980 break;
981 case IRP_MJ_FLUSH_BUFFERS :
982 DriverObject->MajorFunction[MajorFunction] = KsFlushBuffers;
983 break;
984 case IRP_MJ_QUERY_SECURITY:
985 DriverObject->MajorFunction[MajorFunction] = KsQuerySecurity;
986 break;
987 case IRP_MJ_SET_SECURITY:
988 DriverObject->MajorFunction[MajorFunction] = KsSetSecurity;
989 break;
990
991 default:
992 return STATUS_INVALID_PARAMETER; /* is this right? */
993 };
994
995 return STATUS_SUCCESS;
996 }
997
998 /*
999 @implemented
1000 */
1001 KSDDKAPI
1002 NTSTATUS
1003 NTAPI
1004 KsDispatchIrp(
1005 IN PDEVICE_OBJECT DeviceObject,
1006 IN PIRP Irp)
1007 {
1008 PIO_STACK_LOCATION IoStack;
1009
1010 /* Calls a dispatch routine corresponding to the function code of the IRP */
1011 /*
1012 First we need to get the dispatch table. An opaque header is pointed to by
1013 FsContext. The first element points to this table. This table is the key
1014 to dispatching the IRP correctly.
1015 */
1016
1017 IoStack = IoGetCurrentIrpStackLocation(Irp);
1018 DPRINT1("KsDispatchIrp %x\n", IoStack->MajorFunction);
1019
1020 switch (IoStack->MajorFunction)
1021 {
1022 case IRP_MJ_CREATE:
1023 return KsCreate(DeviceObject, Irp);
1024 case IRP_MJ_CLOSE:
1025 return KsClose(DeviceObject, Irp);
1026 break;
1027 case IRP_MJ_DEVICE_CONTROL:
1028 return KsDeviceControl(DeviceObject, Irp);
1029 break;
1030 case IRP_MJ_READ:
1031 return KsRead(DeviceObject, Irp);
1032 break;
1033 case IRP_MJ_WRITE:
1034 return KsWrite(DeviceObject, Irp);
1035 break;
1036 case IRP_MJ_FLUSH_BUFFERS:
1037 return KsFlushBuffers(DeviceObject, Irp);
1038 break;
1039 case IRP_MJ_QUERY_SECURITY:
1040 return KsQuerySecurity(DeviceObject, Irp);
1041 break;
1042 case IRP_MJ_SET_SECURITY:
1043 return KsSetSecurity(DeviceObject, Irp);
1044 break;
1045 default:
1046 return STATUS_INVALID_PARAMETER; /* is this right? */
1047 };
1048 }
1049
1050
1051 /*
1052 @unimplemented
1053 */
1054 KSDDKAPI NTSTATUS NTAPI
1055 KsStreamIo(
1056 IN PFILE_OBJECT FileObject,
1057 IN PKEVENT Event OPTIONAL,
1058 IN PVOID PortContext OPTIONAL,
1059 IN PIO_COMPLETION_ROUTINE CompletionRoutine OPTIONAL,
1060 IN PVOID CompletionContext OPTIONAL,
1061 IN KSCOMPLETION_INVOCATION CompletionInvocationFlags OPTIONAL,
1062 OUT PIO_STATUS_BLOCK IoStatusBlock,
1063 IN OUT PVOID StreamHeaders,
1064 IN ULONG Length,
1065 IN ULONG Flags,
1066 IN KPROCESSOR_MODE RequestorMode)
1067 {
1068 UNIMPLEMENTED;
1069 return STATUS_UNSUCCESSFUL;
1070 }
1071
1072 /*
1073 @unimplemented
1074 */
1075 KSDDKAPI NTSTATUS NTAPI
1076 KsWriteFile(
1077 IN PFILE_OBJECT FileObject,
1078 IN PKEVENT Event OPTIONAL,
1079 IN PVOID PortContext OPTIONAL,
1080 OUT PIO_STATUS_BLOCK IoStatusBlock,
1081 IN PVOID Buffer,
1082 IN ULONG Length,
1083 IN ULONG Key OPTIONAL,
1084 IN KPROCESSOR_MODE RequestorMode)
1085 {
1086 UNIMPLEMENTED;
1087 return STATUS_UNSUCCESSFUL;
1088 }
1089
1090 /*
1091 @unimplemented
1092 */
1093 KSDDKAPI NTSTATUS NTAPI
1094 KsDefaultForwardIrp(
1095 IN PDEVICE_OBJECT DeviceObject,
1096 IN PIRP Irp)
1097 {
1098 UNIMPLEMENTED;
1099 return STATUS_UNSUCCESSFUL;
1100 }
1101