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