ReactOS  0.4.14-dev-599-g2d4d3f5
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 //
31 NTAPI
34  IN PUNICODE_STRING RegistryPathName,
36 {
37  DPRINT("PcInitializeAdapterDriver\n");
39 
40  // Our IRP handlers
41  DPRINT("Setting IRP handlers\n");
47 
48  // The driver-supplied 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 //
75 NTAPI
80  IN ULONG MaxObjects,
81  IN ULONG DeviceExtensionSize)
82 {
84  PDEVICE_OBJECT fdo;
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
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 
187 cleanup:
188 
189  if (portcls_ext->KsDeviceHeader)
190  {
191  // free the device header
192  KsFreeDeviceHeader(portcls_ext->KsDeviceHeader);
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 
208 NTSTATUS
209 NTAPI
212  IN PWCHAR Name,
214 {
215  PPCLASS_DEVICE_EXTENSION DeviceExt;
217  ISubdevice *SubDevice;
218  UNICODE_STRING SymbolicLinkName;
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
237 
238  if (!DeviceExt)
239  {
240  // should not happen
241  DbgBreakPoint();
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,
285  &SymbolicLinkName);
286 
287  if (NT_SUCCESS(Status))
288  {
289  // activate device interface
290  IoSetDeviceInterfaceState(&SymbolicLinkName, TRUE);
291  // allocate symbolic link entry
293  if (SymEntry)
294  {
295  // initialize symbolic link item
296  RtlInitUnicodeString(&SymEntry->SymbolicLink, SymbolicLinkName.Buffer);
297  // store item
298  InsertTailList(&SubDeviceDescriptor->SymbolicLinkList, &SymEntry->Entry);
299  }
300  else
301  {
302  // allocating failed
303  RtlFreeUnicodeString(&SymbolicLinkName);
304  }
305  }
306  }
307 
308  // release SubDevice reference
309  SubDevice->Release();
310 
311  return STATUS_SUCCESS;
312 }
#define DO_DEVICE_INITIALIZING
Definition: env_spec_w32.h:399
PDEVICE_OBJECT PrevDeviceObject
Definition: private.hpp:403
#define DO_POWER_PAGABLE
#define IN
Definition: typedefs.h:38
#define TRUE
Definition: types.h:120
#define IRP_MJ_CREATE
Definition: rdpdr.c:44
#define STATUS_INSUFFICIENT_RESOURCES
Definition: udferr_usr.h:158
VOID NTAPI PcIoTimerRoutine(IN PDEVICE_OBJECT DeviceObject, IN PVOID Context)
Definition: api.cpp:49
#define IRP_MJ_QUERY_SECURITY
#define IRP_MJ_FLUSH_BUFFERS
VOID NTAPI IoStartTimer(IN PDEVICE_OBJECT DeviceObject)
Definition: iotimer.c:133
KSDDKAPI NTSTATUS NTAPI KsAllocateDeviceHeader(OUT KSDEVICE_HEADER *OutHeader, IN ULONG ItemsCount, IN PKSOBJECT_CREATE_ITEM ItemsList OPTIONAL)
Definition: api.c:522
#define IRP_MJ_SHUTDOWN
struct PCLASS_DEVICE_EXTENSION * PPCLASS_DEVICE_EXTENSION
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
#define TAG_PORTCLASS
Definition: private.hpp:24
#define IRP_MJ_SET_SECURITY
#define IRP_MJ_PNP
Definition: cdrw_usr.h:52
PVOID AllocateItem(IN POOL_TYPE PoolType, IN SIZE_T NumberOfBytes)
Definition: misc.c:30
LONG NTSTATUS
Definition: precomp.h:26
uint16_t * PWCHAR
Definition: typedefs.h:54
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1122
#define InsertTailList(ListHead, Entry)
PCPFNSTARTDEVICE StartDevice
Definition: private.hpp:404
void DbgBreakPoint()
Definition: mach.c:553
struct SYMBOLICLINK_ENTRY * PSYMBOLICLINK_ENTRY
Definition: interfaces.hpp:173
#define DO_DIRECT_IO
Definition: env_spec_w32.h:396
KSDDKAPI NTSTATUS NTAPI KsSetMajorFunctionHandler(IN PDRIVER_OBJECT DriverObject, IN ULONG MajorFunction)
Definition: irp.c:2017
#define PORT_CLASS_DEVICE_EXTENSION_SIZE
Definition: portcls.h:160
VOID FreeItem(IN PVOID Item)
Definition: misc.c:43
NTSTATUS(* NTAPI)(IN PFILE_FULL_EA_INFORMATION EaBuffer, IN ULONG EaLength, OUT PULONG ErrorOffset)
Definition: IoEaTest.cpp:117
PDEVICE_OBJECT NTAPI IoAttachDeviceToDeviceStack(IN PDEVICE_OBJECT SourceDevice, IN PDEVICE_OBJECT TargetDevice)
Definition: device.c:966
PDRIVER_EXTENSION DriverExtension
Definition: iotypes.h:2174
FORCEINLINE VOID KeInitializeSpinLock(_Out_ PKSPIN_LOCK SpinLock)
Definition: kefuncs.h:251
PVOID DeviceExtension
Definition: env_spec_w32.h:418
NTSTATUS NTAPI PcAddAdapterDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PCPFNSTARTDEVICE StartDevice, IN ULONG MaxObjects, IN ULONG DeviceExtensionSize)
Definition: adapter.cpp:76
smooth NULL
Definition: ftsmooth.c:416
static PDRIVER_OBJECT DriverObject
Definition: template.c:42
void DPRINT(...)
Definition: polytest.cpp:61
KSPIN_LOCK TimerListLock
Definition: private.hpp:413
NTSTATUS NTAPI IoSetDeviceInterfaceState(IN PUNICODE_STRING SymbolicLinkName, IN BOOLEAN Enable)
Definition: deviface.c:1311
#define FILE_AUTOGENERATED_DEVICE_NAME
Definition: iotypes.h:138
NTSTATUS(NTAPI * PCPFNSTARTDEVICE)(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PRESOURCELIST ResourceList)
Definition: portcls.h:2231
KSDEVICE_HEADER KsDeviceHeader
Definition: private.hpp:401
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
PDEVICE_OBJECT PhysicalDeviceObject
Definition: private.hpp:402
NTSTATUS NTAPI IoInitializeTimer(IN PDEVICE_OBJECT DeviceObject, IN PIO_TIMER_ROUTINE TimerRoutine, IN PVOID Context)
Definition: iotimer.c:92
static const UCHAR Index[8]
Definition: usbohci.c:18
nsrefcnt Release()
NTSYSAPI VOID NTAPI RtlFreeUnicodeString(PUNICODE_STRING UnicodeString)
#define PC_ASSERT_IRQL_EQUAL(x)
Definition: private.hpp:31
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132
#define IRP_MJ_POWER
#define IRP_MJ_CLOSE
Definition: rdpdr.c:45
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
NTSTATUS NTAPI PcInitializeAdapterDriver(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPathName, IN PDRIVER_ADD_DEVICE AddDevice)
Definition: adapter.cpp:32
#define PASSIVE_LEVEL
Definition: env_spec_w32.h:693
#define IRP_MJ_SYSTEM_CONTROL
Status
Definition: gdiplustypes.h:24
KSOBJECT_CREATE_ITEM * CreateItems
Definition: private.hpp:408
UNICODE_STRING RefString
Definition: interfaces.hpp:221
IN PDEVICE_OBJECT DeviceObject
Definition: fatprocs.h:1560
VOID NTAPI IoDeleteDevice(IN PDEVICE_OBJECT DeviceObject)
Definition: device.c:1251
PDRIVER_ADD_DEVICE AddDevice
Definition: iotypes.h:2112
NTSTATUS NTAPI PcCreateItemDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
NTSTATUS NTAPI IoRegisterDeviceInterface(IN PDEVICE_OBJECT PhysicalDeviceObject, IN CONST GUID *InterfaceClassGuid, IN PUNICODE_STRING ReferenceString OPTIONAL, OUT PUNICODE_STRING SymbolicLinkName)
Definition: deviface.c:955
#define FILE_DEVICE_KS
Definition: winioctl.h:152
#define InitializeListHead(ListHead)
Definition: env_spec_w32.h:944
LIST_ENTRY Entry
Definition: interfaces.hpp:175
DRIVER_ADD_DEVICE * PDRIVER_ADD_DEVICE
Definition: iotypes.h:2108
#define IRP_MJ_READ
Definition: rdpdr.c:46
NTSTATUS NTAPI IoRegisterShutdownNotification(PDEVICE_OBJECT DeviceObject)
Definition: device.c:1694
UNICODE_STRING SymbolicLink
Definition: interfaces.hpp:176
PDRIVER_DISPATCH MajorFunction[IRP_MJ_MAXIMUM_FUNCTION+1]
Definition: iotypes.h:2181
unsigned int ULONG
Definition: retypes.h:1
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
NTSYSAPI VOID NTAPI RtlInitUnicodeString(PUNICODE_STRING DestinationString, PCWSTR SourceString)
#define RtlZeroMemory(Destination, Length)
Definition: typedefs.h:261
char * cleanup(char *str)
Definition: wpickclick.c:99
#define IRP_MJ_WRITE
Definition: rdpdr.c:47
#define FILE_DEVICE_SECURE_OPEN
Definition: cdrw_usr.h:46
NTSTATUS NTAPI PcDispatchIrp(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
Definition: irp.cpp:433
return STATUS_SUCCESS
Definition: btrfs.c:2938
static SERVICE_STATUS status
Definition: service.c:31
NTSTATUS NTAPI StartDevice(PDEVICE_OBJECT DeviceObject, PIRP Irp, PRESOURCELIST ResourceList)
Definition: adapter.cpp:115
NTSTATUS NTAPI AddDevice(PDRIVER_OBJECT DriverObject, PDEVICE_OBJECT PhysicalDeviceObject)
Definition: adapter.cpp:259
NTSTATUS NTAPI PcRegisterSubdevice(IN PDEVICE_OBJECT DeviceObject, IN PWCHAR Name, IN PUNKNOWN Unknown)
Definition: adapter.cpp:210
#define IRP_MJ_DEVICE_CONTROL
Definition: rdpdr.c:52
LIST_ENTRY SymbolicLinkList
Definition: interfaces.hpp:219
Definition: ps.c:97