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