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