xref: /reactos/drivers/ksfilter/ks/driver.c (revision 50cf16b3)
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 "precomp.h"
10 
11 #define NDEBUG
12 #include <debug.h>
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 }
201