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