[KS]
[reactos.git] / reactos / drivers / ksfilter / ks / misc.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/misc.c
5 * PURPOSE: KS Allocator functions
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9 #include "priv.h"
10
11 #define NDEBUG
12 #include <debug.h>
13
14 VOID
15 CompleteRequest(
16 PIRP Irp,
17 CCHAR PriorityBoost)
18 {
19 DPRINT("Completing IRP %p Status %x\n", Irp, Irp->IoStatus.Status);
20
21 ASSERT(Irp->IoStatus.Status != STATUS_PENDING);
22
23
24 IoCompleteRequest(Irp, PriorityBoost);
25 }
26
27 PVOID
28 AllocateItem(
29 IN POOL_TYPE PoolType,
30 IN SIZE_T NumberOfBytes)
31 {
32 PVOID Item = ExAllocatePool(PoolType, NumberOfBytes);
33 if (!Item)
34 return Item;
35
36 RtlZeroMemory(Item, NumberOfBytes);
37 return Item;
38 }
39
40 VOID
41 FreeItem(
42 IN PVOID Item)
43 {
44 ExFreePool(Item);
45 }
46
47 NTSTATUS
48 NTAPI
49 KspForwardIrpSynchronousCompletion(
50 IN PDEVICE_OBJECT DeviceObject,
51 IN PIRP Irp,
52 IN PVOID Context)
53 {
54 if (Irp->PendingReturned == TRUE)
55 {
56 KeSetEvent ((PKEVENT) Context, IO_NO_INCREMENT, FALSE);
57 }
58 return STATUS_MORE_PROCESSING_REQUIRED;
59 }
60
61
62 NTSTATUS
63 KspForwardIrpSynchronous(
64 IN PDEVICE_OBJECT DeviceObject,
65 IN PIRP Irp)
66 {
67 KEVENT Event;
68 NTSTATUS Status;
69 PDEVICE_EXTENSION DeviceExtension;
70 PKSIDEVICE_HEADER DeviceHeader;
71
72 ASSERT_IRQL_EQUAL(PASSIVE_LEVEL);
73
74 /* get device extension */
75 DeviceExtension = (PDEVICE_EXTENSION)DeviceObject->DeviceExtension;
76 /* get device header */
77 DeviceHeader = DeviceExtension->DeviceHeader;
78
79 /* initialize the notification event */
80 KeInitializeEvent(&Event, NotificationEvent, FALSE);
81
82 IoCopyCurrentIrpStackLocationToNext(Irp);
83
84 IoSetCompletionRoutine(Irp, KspForwardIrpSynchronousCompletion, (PVOID)&Event, TRUE, TRUE, TRUE);
85
86 /* now call the driver */
87 Status = IoCallDriver(DeviceHeader->KsDevice.NextDeviceObject, Irp);
88 /* did the request complete yet */
89 if (Status == STATUS_PENDING)
90 {
91 /* not yet, lets wait a bit */
92 KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL);
93 Status = Irp->IoStatus.Status;
94 }
95 return Status;
96 }
97
98 NTSTATUS
99 KspCopyCreateRequest(
100 IN PIRP Irp,
101 IN LPWSTR ObjectClass,
102 IN OUT PULONG Size,
103 OUT PVOID * Result)
104 {
105 PIO_STACK_LOCATION IoStack;
106 ULONG ObjectLength, ParametersLength;
107 PVOID Buffer;
108
109 /* get current irp stack */
110 IoStack = IoGetCurrentIrpStackLocation(Irp);
111
112 /* get object class length */
113 ObjectLength = (wcslen(ObjectClass) + 1) * sizeof(WCHAR);
114
115 /* check for minium length requirement */
116 if (ObjectLength + *Size > IoStack->FileObject->FileName.MaximumLength)
117 return STATUS_UNSUCCESSFUL;
118
119 /* extract parameters length */
120 ParametersLength = IoStack->FileObject->FileName.MaximumLength - ObjectLength;
121
122 /* allocate buffer */
123 Buffer = AllocateItem(NonPagedPool, ParametersLength);
124 if (!Buffer)
125 return STATUS_INSUFFICIENT_RESOURCES;
126
127 /* copy parameters */
128 RtlMoveMemory(Buffer, &IoStack->FileObject->FileName.Buffer[ObjectLength / sizeof(WCHAR)], ParametersLength);
129
130 /* store result */
131 *Result = Buffer;
132 *Size = ParametersLength;
133
134 return STATUS_SUCCESS;
135 }
136
137 /*
138 @implemented
139 */
140 KSDDKAPI
141 PVOID
142 NTAPI
143 KsGetObjectFromFileObject(
144 IN PFILE_OBJECT FileObject)
145 {
146 PKSIOBJECT_HEADER ObjectHeader;
147
148 /* get object header */
149 ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext2;
150
151 /* return associated object */
152 return ObjectHeader->ObjectType;
153 }
154
155 /*
156 @implemented
157 */
158 KSDDKAPI
159 KSOBJECTTYPE
160 NTAPI
161 KsGetObjectTypeFromFileObject(
162 IN PFILE_OBJECT FileObject)
163 {
164 PKSIOBJECT_HEADER ObjectHeader;
165
166 /* get object header */
167 ObjectHeader = (PKSIOBJECT_HEADER)FileObject->FsContext2;
168 /* return type */
169 return ObjectHeader->Type;
170 }
171
172 /*
173 @implemented
174 */
175 KSOBJECTTYPE
176 NTAPI
177 KsGetObjectTypeFromIrp(
178 IN PIRP Irp)
179 {
180 PKSIOBJECT_HEADER ObjectHeader;
181 PIO_STACK_LOCATION IoStack;
182
183 /* get current irp stack */
184 IoStack = IoGetCurrentIrpStackLocation(Irp);
185 /* get object header */
186 ObjectHeader = (PKSIOBJECT_HEADER)IoStack->FileObject->FsContext2;
187 /* return type */
188 return ObjectHeader->Type;
189 }
190
191 /*
192 @implemented
193 */
194 PUNKNOWN
195 NTAPI
196 KsGetOuterUnknown(
197 IN PVOID Object)
198 {
199 PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
200
201 /* sanity check */
202 ASSERT(BasicHeader->Type == KsObjectTypeDevice || BasicHeader->Type == KsObjectTypeFilterFactory ||
203 BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
204
205 /* return objects outer unknown */
206 return BasicHeader->OuterUnknown;
207 }
208
209 /*
210 @implemented
211 */
212 KSDDKAPI
213 PVOID
214 NTAPI
215 KsGetParent(
216 IN PVOID Object)
217 {
218 PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
219 /* sanity check */
220 ASSERT(BasicHeader->Parent.KsDevice != NULL);
221 /* return object type */
222 return (PVOID)BasicHeader->Parent.KsDevice;
223 }
224
225