949e1285c5464dd5b10f82ee5f16bf7f8cdb0101
[reactos.git] / reactos / drivers / ksfilter / ks / driver.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/ksfilter/ks/driver.c
5 * PURPOSE: KS Driver functions
6 * PROGRAMMER: Johannes Anderwald
7 */
8
9 #include "priv.h"
10
11 #include "ksfunc.h"
12
13
14 /*
15 @implemented
16 */
17 KSDDKAPI
18 PKSDEVICE
19 NTAPI
20 KsGetDeviceForDeviceObject(
21 IN PDEVICE_OBJECT FunctionalDeviceObject)
22 {
23 PDEVICE_EXTENSION DeviceExtension;
24
25 /* get device extension */
26 DeviceExtension = (PDEVICE_EXTENSION)FunctionalDeviceObject->DeviceExtension;
27
28 return &DeviceExtension->DeviceHeader->KsDevice;
29 }
30
31 /*
32 @implemented
33 */
34 KSDDKAPI
35 PKSDEVICE
36 NTAPI
37 KsGetDevice(
38 IN PVOID Object)
39 {
40 PKSBASIC_HEADER BasicHeader = (PKSBASIC_HEADER)((ULONG_PTR)Object - sizeof(KSBASIC_HEADER));
41
42 ASSERT(BasicHeader->Type == KsObjectTypeFilterFactory || BasicHeader->Type == KsObjectTypeFilter || BasicHeader->Type == KsObjectTypePin);
43 ASSERT(BasicHeader->KsDevice);
44 ASSERT(BasicHeader->KsDevice->Started);
45 ASSERT(BasicHeader->KsDevice->PhysicalDeviceObject);
46
47 return BasicHeader->KsDevice;
48 }
49
50 /*
51 @implemented
52 */
53 KSDDKAPI
54 NTSTATUS
55 NTAPI
56 KsCreateDevice(
57 IN PDRIVER_OBJECT DriverObject,
58 IN PDEVICE_OBJECT PhysicalDeviceObject,
59 IN const KSDEVICE_DESCRIPTOR* Descriptor OPTIONAL,
60 IN ULONG ExtensionSize OPTIONAL,
61 OUT PKSDEVICE* Device OPTIONAL)
62 {
63 NTSTATUS Status = STATUS_DEVICE_REMOVED;
64 PDEVICE_OBJECT FunctionalDeviceObject= NULL;
65 PDEVICE_OBJECT OldHighestDeviceObject;
66 if (!ExtensionSize)
67 ExtensionSize = sizeof(KSDEVICE_HEADER);
68
69 DPRINT("KsCreateDevice Descriptor %p ExtensionSize %lu\n", Descriptor, ExtensionSize);
70
71 Status = IoCreateDevice(DriverObject, ExtensionSize, NULL, FILE_DEVICE_KS, FILE_DEVICE_SECURE_OPEN, FALSE, &FunctionalDeviceObject);
72 if (!NT_SUCCESS(Status))
73 return Status;
74
75 OldHighestDeviceObject = IoAttachDeviceToDeviceStack(FunctionalDeviceObject, PhysicalDeviceObject);
76 if (OldHighestDeviceObject)
77 {
78 Status = KsInitializeDevice(FunctionalDeviceObject, PhysicalDeviceObject, OldHighestDeviceObject, Descriptor);
79 }
80 else
81 {
82 Status = STATUS_DEVICE_REMOVED;
83 }
84
85 /* check if all succeeded */
86 if (!NT_SUCCESS(Status))
87 {
88 if (OldHighestDeviceObject)
89 IoDetachDevice(OldHighestDeviceObject);
90
91 IoDeleteDevice(FunctionalDeviceObject);
92 return Status;
93 }
94
95 /* set device flags */
96 FunctionalDeviceObject->Flags |= DO_DIRECT_IO | DO_POWER_PAGABLE;
97 FunctionalDeviceObject->Flags &= ~ DO_DEVICE_INITIALIZING;
98
99 if (Device)
100 {
101 /* get PKSDEVICE struct */
102 *Device = KsGetDeviceForDeviceObject(FunctionalDeviceObject);
103
104 if (ExtensionSize > sizeof(KSDEVICE_HEADER))
105 {
106 /* caller needs a device extension */
107 (*Device)->Context = (PVOID)((ULONG_PTR)FunctionalDeviceObject->DeviceExtension + sizeof(KSDEVICE_HEADER));
108 }
109 }
110
111 return Status;
112 }
113
114 /*
115 @implemented
116 */
117 KSDDKAPI
118 NTSTATUS
119 NTAPI
120 KsAddDevice(
121 IN PDRIVER_OBJECT DriverObject,
122 IN PDEVICE_OBJECT PhysicalDeviceObject)
123 {
124 PKS_DRIVER_EXTENSION DriverObjectExtension;
125 const KSDEVICE_DESCRIPTOR *Descriptor = NULL;
126
127 /* get stored driver object extension */
128
129 DriverObjectExtension = IoGetDriverObjectExtension(DriverObject, (PVOID)KsInitializeDriver);
130
131 if (DriverObjectExtension)
132 {
133 /* get the stored descriptor see KsInitializeDriver */
134 Descriptor = DriverObjectExtension->Descriptor;
135 }
136
137 return KsCreateDevice(DriverObject, PhysicalDeviceObject, Descriptor, 0, NULL);
138 }
139
140 /*
141 @implemented
142 */
143 KSDDKAPI
144 NTSTATUS
145 NTAPI
146 KsInitializeDriver(
147 IN PDRIVER_OBJECT DriverObject,
148 IN PUNICODE_STRING RegistryPath,
149 IN const KSDEVICE_DESCRIPTOR *Descriptor OPTIONAL
150 )
151 {
152 PKS_DRIVER_EXTENSION DriverObjectExtension;
153 NTSTATUS Status = STATUS_SUCCESS;
154
155 if (Descriptor)
156 {
157 Status = IoAllocateDriverObjectExtension(DriverObject, (PVOID)KsInitializeDriver, sizeof(KS_DRIVER_EXTENSION), (PVOID*)&DriverObjectExtension);
158 if (NT_SUCCESS(Status))
159 {
160 DriverObjectExtension->Descriptor = Descriptor;
161 }
162 }
163
164 /* sanity check */
165 ASSERT(Status == STATUS_SUCCESS);
166
167 if (!NT_SUCCESS(Status))
168 return Status;
169
170 /* Setting our IRP handlers */
171 DriverObject->MajorFunction[IRP_MJ_CREATE] = IKsDevice_Create;
172 DriverObject->MajorFunction[IRP_MJ_PNP] = IKsDevice_Pnp;
173 DriverObject->MajorFunction[IRP_MJ_POWER] = IKsDevice_Power;
174 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = KsDefaultForwardIrp;
175
176 /* The driver unload routine */
177 DriverObject->DriverUnload = KsNullDriverUnload;
178
179 /* The driver-supplied AddDevice */
180 DriverObject->DriverExtension->AddDevice = KsAddDevice;
181
182 /* KS handles these */
183 DPRINT1("KsInitializeDriver Setting KS function handlers\n");
184 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
185 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
186
187
188 return STATUS_SUCCESS;
189 }