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