Sync to trunk head(r38096)
[reactos.git] / reactos / drivers / wdm / audio / backpln / portcls / adapter.c
1 /*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/multimedia/portcls/adapter.c
5 * PURPOSE: Port Class driver / DriverEntry and IRP handlers
6 * PROGRAMMER: Andrew Greenwood
7 *
8 * HISTORY:
9 * 27 Jan 07 Created
10 */
11
12 #include "private.h"
13 #include <initguid.h>
14 /*
15 This is called from DriverEntry so that PortCls can take care of some
16 IRPs and map some others to the main KS driver. In most cases this will
17 be the first function called by an audio driver.
18
19 First 2 parameters are from DriverEntry.
20
21 The AddDevice parameter is a driver-supplied pointer to a function which
22 typically then calls PcAddAdapterDevice (see below.)
23 */
24 NTSTATUS NTAPI
25 PcInitializeAdapterDriver(
26 IN PDRIVER_OBJECT DriverObject,
27 IN PUNICODE_STRING RegistryPathName,
28 IN PDRIVER_ADD_DEVICE AddDevice)
29 {
30 /*
31 (* = implement here, otherwise KS default)
32 IRP_MJ_CLOSE
33 * IRP_MJ_CREATE
34 IRP_MJ_DEVICE_CONTROL
35 IRP_MJ_FLUSH_BUFFERS
36 * IRP_MJ_PNP
37 * IRP_MJ_POWER
38 IRP_MJ_QUERY_SECURITY
39 IRP_MJ_READ
40 IRP_MJ_SET_SECURITY
41 * IRP_MJ_SYSTEM_CONTROL
42 IRP_MJ_WRITE
43 */
44
45 //NTSTATUS status;
46 //ULONG i;
47
48 DPRINT("PcInitializeAdapterDriver\n");
49
50 #if 0
51 /* Set default stub - is this a good idea? */
52 DPRINT1("Setting IRP stub\n");
53 for ( i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i ++ )
54 {
55 DriverObject->MajorFunction[i] = IrpStub;
56 }
57 #endif
58
59 /* Our IRP handlers */
60 DPRINT1("Setting IRP handlers\n");
61 DriverObject->MajorFunction[IRP_MJ_CREATE] = PcDispatchIrp;
62 DriverObject->MajorFunction[IRP_MJ_PNP] = PcDispatchIrp;
63 DriverObject->MajorFunction[IRP_MJ_POWER] = PcDispatchIrp;
64 DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL] = PcDispatchIrp;
65
66 /* The driver-supplied AddDevice */
67 DriverObject->DriverExtension->AddDevice = AddDevice;
68
69 /* KS handles these */
70 DPRINT1("Setting KS function handlers\n");
71 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_CLOSE);
72 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_DEVICE_CONTROL);
73 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_FLUSH_BUFFERS);
74 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_QUERY_SECURITY);
75 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_READ);
76 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_SET_SECURITY);
77 KsSetMajorFunctionHandler(DriverObject, IRP_MJ_WRITE);
78
79 DPRINT1("PortCls has finished initializing the adapter driver\n");
80
81 return STATUS_SUCCESS;
82 }
83
84 /*
85 Typically called by a driver's AddDevice function, which is set when
86 calling PcInitializeAdapterDriver. This performs some common driver
87 operations, such as creating a device extension.
88
89 The StartDevice parameter is a driver-supplied function which gets
90 called in response to IRP_MJ_PNP / IRP_MN_START_DEVICE.
91 */
92 NTSTATUS NTAPI
93 PcAddAdapterDevice(
94 IN PDRIVER_OBJECT DriverObject,
95 IN PDEVICE_OBJECT PhysicalDeviceObject,
96 IN PCPFNSTARTDEVICE StartDevice,
97 IN ULONG MaxObjects,
98 IN ULONG DeviceExtensionSize)
99 {
100 /*
101 Note - after this has been called, we can
102 handle IRP_MN_START_DEVICE by calling StartDevice
103
104 TODO:
105 Validate DeviceExtensionSize!! (et al...)
106 */
107
108 NTSTATUS status = STATUS_UNSUCCESSFUL;
109 PDEVICE_OBJECT fdo = NULL;
110 PCExtension* portcls_ext;
111
112 DPRINT1("PcAddAdapterDevice called\n");
113
114 if ( ! DriverObject)
115 {
116 DPRINT("DriverObject is NULL!\n");
117 return STATUS_INVALID_PARAMETER;
118 }
119
120 if ( ! PhysicalDeviceObject )
121 {
122 DPRINT("PhysicalDeviceObject is NULL!\n");
123 return STATUS_INVALID_PARAMETER;
124 }
125
126 if ( ! StartDevice )
127 {
128 DPRINT("No StartDevice parameter!\n");
129 return STATUS_INVALID_PARAMETER;
130 }
131
132 /* TODO: Make sure this is right */
133 if ( DeviceExtensionSize < PORT_CLASS_DEVICE_EXTENSION_SIZE )
134 {
135 if ( DeviceExtensionSize != 0 )
136 {
137 /* TODO: Error */
138 DPRINT("DeviceExtensionSize is invalid\n");
139 return STATUS_INVALID_PARAMETER;
140 }
141 }
142
143 DPRINT("portcls is creating a device\n");
144 status = IoCreateDevice(DriverObject,
145 DeviceExtensionSize,
146 NULL,
147 FILE_DEVICE_KS,
148 PhysicalDeviceObject->Characteristics, /* TODO: Check */
149 FALSE,
150 &fdo);
151
152 if ( ! NT_SUCCESS(status) )
153 {
154 DPRINT("IoCreateDevice() failed with status 0x%08lx\n", status);
155 return status;
156 }
157
158 /* Obtain the new device extension */
159 portcls_ext = (PCExtension*) fdo->DeviceExtension;
160
161 ASSERT(portcls_ext);
162
163 /* Initialize */
164 RtlZeroMemory(portcls_ext, sizeof(PCExtension));
165 portcls_ext->StartDevice = StartDevice;
166
167 status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, 0, NULL);
168 if (!NT_SUCCESS(status))
169 {
170 IoDeleteDevice(fdo);
171 return status;
172 }
173
174 DPRINT("PcAddAdapterDriver succeeded\n");
175
176 return status;
177 }
178
179 NTSTATUS
180 NTAPI
181 PciDriverDispatch(
182 IN PDEVICE_OBJECT DeviceObject,
183 IN PIRP Irp)
184 {
185 DPRINT1("PortClsSysControl called\n");
186
187 /* TODO */
188
189 Irp->IoStatus.Status = STATUS_SUCCESS;
190 Irp->IoStatus.Information = 0;
191 IoCompleteRequest(Irp, IO_NO_INCREMENT);
192
193 return STATUS_SUCCESS;
194 }
195
196 NTSTATUS NTAPI
197 PcRegisterSubdevice(
198 IN PDEVICE_OBJECT DeviceObject,
199 IN PWCHAR Name,
200 IN PUNKNOWN Unknown)
201 {
202 PCExtension* DeviceExt;
203 NTSTATUS Status;
204
205 if (!DeviceObject || !Name || !Unknown)
206 return STATUS_INVALID_PARAMETER;
207
208 DeviceExt = (PCExtension*)DeviceObject->DeviceExtension;
209 if (!DeviceExt)
210 return STATUS_UNSUCCESSFUL;
211
212 Status = KsAddObjectCreateItemToDeviceHeader(DeviceExt->KsDeviceHeader, PciDriverDispatch, (PVOID)Unknown, Name, NULL);
213
214
215 return STATUS_UNSUCCESSFUL;
216 }