ReactOS 0.4.15-dev-5874-gc762234
adapter.cpp
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS Kernel Streaming
4 * FILE: drivers/wdm/audio/backpln/portcls/api.cpp
5 * PURPOSE: Port Class driver / DriverEntry and IRP handlers
6 * PROGRAMMER: Andrew Greenwood
7 * Johannes Anderwald
8 * HISTORY:
9 * 27 Jan 07 Created
10 */
11
12#include "private.hpp"
13
14#ifndef YDEBUG
15#define NDEBUG
16#endif
17
18#include <debug.h>
19
20//
21// This is called from DriverEntry so that PortCls can take care of some
22// IRPs and map some others to the main KS driver. In most cases this will
23// be the first function called by an audio driver.
24//
25// First 2 parameters are from DriverEntry.
26//
27// The AddDevice parameter is a driver-supplied pointer to a function which
28// typically then calls PcAddAdapterDevice (see below.)
29//
34 IN PUNICODE_STRING RegistryPathName,
36{
37 DPRINT("PcInitializeAdapterDriver\n");
39
40 // Our IRP handlers
41 DPRINT("Setting IRP handlers\n");
43 DriverObject->MajorFunction[IRP_MJ_PNP] = PcDispatchIrp;
44 DriverObject->MajorFunction[IRP_MJ_POWER] = PcDispatchIrp;
47
48 // The driver-supplied AddDevice
49 DriverObject->DriverExtension->AddDevice = AddDevice;
50
51 // KS handles these
52 DPRINT("Setting KS function handlers\n");
60
61 DPRINT("PortCls has finished initializing the adapter driver\n");
62
63 return STATUS_SUCCESS;
64}
65
66//
67// Typically called by a driver's AddDevice function, which is set when
68// calling PcInitializeAdapterDriver. This performs some common driver
69// operations, such as creating a device extension.
70//
71// The StartDevice parameter is a driver-supplied function which gets
72// called in response to IRP_MJ_PNP / IRP_MN_START_DEVICE.
73//
80 IN ULONG MaxObjects,
81 IN ULONG DeviceExtensionSize)
82{
85 PDEVICE_OBJECT PrevDeviceObject;
86 PPCLASS_DEVICE_EXTENSION portcls_ext = NULL;
87
88 DPRINT("PcAddAdapterDevice called\n");
90
92 {
94 }
95
96 // check if the DeviceExtensionSize is provided
97 if ( DeviceExtensionSize < PORT_CLASS_DEVICE_EXTENSION_SIZE )
98 {
99 // driver does not need a device extension
100 if ( DeviceExtensionSize != 0 )
101 {
102 // DeviceExtensionSize must be zero
104 }
105 // set size to our extension size
106 DeviceExtensionSize = PORT_CLASS_DEVICE_EXTENSION_SIZE;
107 }
108
109 // create the device
111 DeviceExtensionSize,
112 NULL,
115 FALSE,
116 &fdo);
117
118 if (!NT_SUCCESS(status))
119 {
120 DPRINT("IoCreateDevice() failed with status 0x%08lx\n", status);
121 return status;
122 }
123
124 // Obtain the new device extension
125 portcls_ext = (PPCLASS_DEVICE_EXTENSION) fdo->DeviceExtension;
126 // initialize the device extension
127 RtlZeroMemory(portcls_ext, DeviceExtensionSize);
128 // allocate create item
129 portcls_ext->CreateItems = (PKSOBJECT_CREATE_ITEM)AllocateItem(NonPagedPool, MaxObjects * sizeof(KSOBJECT_CREATE_ITEM), TAG_PORTCLASS);
130
131 if (!portcls_ext->CreateItems)
132 {
133 // not enough resources
135 goto cleanup;
136 }
137
138 // store max subdevice count
139 portcls_ext->MaxSubDevices = MaxObjects;
140 // store the physical device object
142 // set up the start device function
143 portcls_ext->StartDevice = StartDevice;
144 // initialize timer lock
145 KeInitializeSpinLock(&portcls_ext->TimerListLock);
146 // initialize timer list
147 InitializeListHead(&portcls_ext->TimerList);
148 // initialize io timer
150 // start the io timer
151 IoStartTimer(fdo);
152
153 // set io flags
155 // clear initializing flag
156 fdo->Flags &= ~ DO_DEVICE_INITIALIZING;
157
158 // allocate the device header
159 status = KsAllocateDeviceHeader(&portcls_ext->KsDeviceHeader, MaxObjects, portcls_ext->CreateItems);
160 // did we succeed
161 if (!NT_SUCCESS(status))
162 {
163 goto cleanup;
164 }
165
166 // attach device to device stack
167 PrevDeviceObject = IoAttachDeviceToDeviceStack(fdo, PhysicalDeviceObject);
168 // did we succeed
169 if (PrevDeviceObject)
170 {
171 // store the device object in the device header
172 //KsSetDevicePnpBaseObject(portcls_ext->KsDeviceHeader, fdo, PrevDeviceObject);
173 portcls_ext->PrevDeviceObject = PrevDeviceObject;
174 }
175 else
176 {
177 // return error code
179 goto cleanup;
180 }
181
182 // register shutdown notification
184
185 return status;
186
187cleanup:
188
189 if (portcls_ext->KsDeviceHeader)
190 {
191 // free the device header
193 }
194
195 if (portcls_ext->CreateItems)
196 {
197 // free previously allocated create items
198 FreeItem(portcls_ext->CreateItems, TAG_PORTCLASS);
199 }
200
201 // delete created fdo
202 IoDeleteDevice(fdo);
203
204
205 return status;
206}
207
209NTAPI
212 IN PWCHAR Name,
214{
215 PPCLASS_DEVICE_EXTENSION DeviceExt;
217 ISubdevice *SubDevice;
219 PSUBDEVICE_DESCRIPTOR SubDeviceDescriptor;
220 ULONG Index;
221 UNICODE_STRING RefName;
222 PSYMBOLICLINK_ENTRY SymEntry;
223
224 DPRINT("PcRegisterSubdevice DeviceObject %p Name %S Unknown %p\n", DeviceObject, Name, Unknown);
225
227
228 // check if all parameters are valid
229 if (!DeviceObject || !Name || !Unknown)
230 {
231 DPRINT("PcRegisterSubdevice invalid parameter\n");
233 }
234
235 // get device extension
236 DeviceExt = (PPCLASS_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
237
238 if (!DeviceExt)
239 {
240 // should not happen
242 return STATUS_UNSUCCESSFUL;
243 }
244
245 // look up our undocumented interface
246 Status = Unknown->QueryInterface(IID_ISubdevice, (LPVOID*)&SubDevice);
247 if (!NT_SUCCESS(Status))
248 {
249 DPRINT("No ISubdevice interface\n");
250 // the provided port driver doesnt support ISubdevice
252 }
253
254 // get the subdevice descriptor
255 Status = SubDevice->GetDescriptor(&SubDeviceDescriptor);
256 if (!NT_SUCCESS(Status))
257 {
258 DPRINT("Failed to get subdevice descriptor %x\n", Status);
259 SubDevice->Release();
260 return STATUS_UNSUCCESSFUL;
261 }
262
263 // add an create item to the device header
265 if (!NT_SUCCESS(Status))
266 {
267 // failed to attach
268 SubDevice->Release();
269 DPRINT("KsAddObjectCreateItemToDeviceHeader failed with %x\n", Status);
270 return Status;
271 }
272
273 // initialize reference string
274 RtlInitUnicodeString(&RefName, Name);
275 RtlInitUnicodeString(&SubDeviceDescriptor->RefString, Name);
276
277 for(Index = 0; Index < SubDeviceDescriptor->InterfaceCount; Index++)
278 {
279 // FIXME
280 // check if reference string with that name already exists
281
283 &SubDeviceDescriptor->Interfaces[Index],
284 &RefName,
286
287 if (NT_SUCCESS(Status))
288 {
289 // activate device interface
291 // allocate symbolic link entry
293 if (SymEntry)
294 {
295 // initialize symbolic link item
297 // store item
298 InsertTailList(&SubDeviceDescriptor->SymbolicLinkList, &SymEntry->Entry);
299 }
300 else
301 {
302 // allocating failed
304 }
305 }
306 }
307
308 // release SubDevice reference
309 SubDevice->Release();
310
311 return STATUS_SUCCESS;
312}
NTSTATUS NTAPI PcAddAdapterDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PCPFNSTARTDEVICE StartDevice, IN ULONG MaxObjects, IN ULONG DeviceExtensionSize)
Definition: adapter.cpp:76
NTSTATUS NTAPI PcInitializeAdapterDriver(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPathName, IN PDRIVER_ADD_DEVICE AddDevice)
Definition: adapter.cpp:32
NTSTATUS NTAPI PcRegisterSubdevice(IN PDEVICE_OBJECT DeviceObject, IN PWCHAR Name, IN PUNKNOWN Unknown)
Definition: adapter.cpp:210
struct SYMBOLICLINK_ENTRY * PSYMBOLICLINK_ENTRY
LONG NTSTATUS
Definition: precomp.h:26
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
static void cleanup(void)
Definition: main.c:1335
KSDDKAPI NTSTATUS NTAPI KsAllocateDeviceHeader(OUT KSDEVICE_HEADER *OutHeader, IN ULONG ItemsCount, IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL)
Definition: api.c:522
KSDDKAPI NTSTATUS NTAPI KsAddObjectCreateItemToDeviceHeader(IN KSDEVICE_HEADER DevHeader, IN PDRIVER_DISPATCH Create, IN PVOID Context, IN PWCHAR ObjectClass, IN PSECURITY_DESCRIPTOR SecurityDescriptor)
Definition: api.c:798
KSDDKAPI VOID NTAPI KsFreeDeviceHeader(IN KSDEVICE_HEADER DevHeader)
Definition: api.c:590
KSDDKAPI NTSTATUS NTAPI KsSetMajorFunctionHandler(IN PDRIVER_OBJECT DriverObject, IN ULONG MajorFunction)
Definition: irp.c:2029
VOID NTAPI PcIoTimerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: api.cpp:49
#define InsertTailList(ListHead, Entry)
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
#define NonPagedPool
Definition: env_spec_w32.h:307
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
#define KeInitializeSpinLock(sl)
Definition: env_spec_w32.h:604
Status
Definition: gdiplustypes.h:25
@ Unknown
Definition: i8042prt.h:114
NTSYSAPI void WINAPI DbgBreakPoint(void)
NTSTATUS NTAPI IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context)
Definition: iotimer.c:92
VOID NTAPI IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:133
NTSTATUS NTAPI PcDispatchIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:416
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
if(dx< 0)
Definition: linetemp.h:194
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
static BOOL StartDevice(IN HDEVINFO DeviceInfoSet, IN PSP_DEVINFO_DATA DevInfoData OPTIONAL, IN BOOL bEnable, IN DWORD HardwareProfile OPTIONAL, OUT BOOL *bNeedReboot OPTIONAL)
Definition: wizard.c:173
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
NTSTATUS NTAPI IoCreateDevice(IN PDRIVER_OBJECT DriverObject, IN ULONG DeviceExtensionSize, IN PUNICODE_STRING DeviceName, IN DEVICE_TYPE DeviceType, IN ULONG DeviceCharacteristics, IN BOOLEAN Exclusive, OUT PDEVICE_OBJECT *DeviceObject)
Definition: device.c:1031
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1694
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
DRIVER_ADD_DEVICE AddDevice
Definition: parport.h:72
NTSTATUS NTAPI PcCreateItemDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
#define PORT_CLASS_DEVICE_EXTENSION_SIZE
Definition: portcls.h:160
NTSTATUS(NTAPI * PCPFNSTARTDEVICE)(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PRESOURCELIST ResourceList)
Definition: portcls.h:2304
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
struct PCLASS_DEVICE_EXTENSION * PPCLASS_DEVICE_EXTENSION
#define TAG_PORTCLASS
Definition: private.hpp:24
#define FILE_DEVICE_KS
Definition: winioctl.h:153
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
#define IRP_MJ_READ
Definition: rdpdr.c:46
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_SUCCESS
Definition: shellext.h:65
#define DPRINT
Definition: sndvol32.h:71
KSDEVICE_HEADER KsDeviceHeader
Definition: private.hpp:401
PDEVICE_OBJECT PhysicalDeviceObject
Definition: private.hpp:402
PDEVICE_OBJECT PrevDeviceObject
Definition: private.hpp:403
KSOBJECT_CREATE_ITEM * CreateItems
Definition: private.hpp:408
PCPFNSTARTDEVICE StartDevice
Definition: private.hpp:404
KSPIN_LOCK TimerListLock
Definition: private.hpp:413
UNICODE_STRING RefString
Definition: interfaces.hpp:221
LIST_ENTRY SymbolicLinkList
Definition: interfaces.hpp:219
Definition: interfaces.hpp:174
LIST_ENTRY Entry
Definition: interfaces.hpp:175
UNICODE_STRING SymbolicLink
Definition: interfaces.hpp:176
PVOID DeviceExtension
Definition: env_spec_w32.h:418
Definition: ps.c:97
#define NTAPI
Definition: typedefs.h:36
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:262
#define IN
Definition: typedefs.h:39
uint16_t * PWCHAR
Definition: typedefs.h:56
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
_In_ WDFCOLLECTION _In_ ULONG Index
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFDEVICE _In_ PCUNICODE_STRING SymbolicLinkName
Definition: wdfdevice.h:3739
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
DRIVER_ADD_DEVICE * PDRIVER_ADD_DEVICE
Definition: iotypes.h:2216
#define IRP_MJ_QUERY_SECURITY
#define DO_POWER_PAGABLE
#define IRP_MJ_SYSTEM_CONTROL
#define IRP_MJ_FLUSH_BUFFERS
#define IRP_MJ_SHUTDOWN
#define IRP_MJ_POWER
#define IRP_MJ_SET_SECURITY