ReactOS 0.4.15-dev-7704-gc07eb9f
adapter.cpp File Reference
#include "adapter.h"
Include dependency graph for adapter.cpp:

Go to the source code of this file.

Macros

#define STR_MODULENAME   "AC97 Adapter: "
 
#define PUT_GUIDS_HERE
 
#define DEFINE_DEBUG_VARS
 

Functions

NTSTATUS InstallSubdevice (_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PWSTR Name, _In_ REFGUID PortClassId, _In_ REFGUID MiniportClassId, _In_opt_ PFNCREATEMINIPORT MiniportCreate, _In_opt_ PUNKNOWN UnknownAdapter, _In_opt_ PRESOURCELIST ResourceList, _In_opt_ REFGUID PortInterfaceId, _Out_opt_ PMINIPORT *OutMiniport, _Out_opt_ PUNKNOWN *OutPortUnknown)
 
NTSTATUS ValidateResources (IN PRESOURCELIST ResourceList)
 
NTSTATUS GZCALL StartDevice (IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PRESOURCELIST ResourceList)
 
NTSTATUS GZCALL AddDevice (IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject)
 
NTSTATUS GZCALL DriverEntry (IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPathName)
 

Variables

DRIVER_ADD_DEVICE AddDevice
 
DRIVER_INITIALIZE DriverEntry
 

Macro Definition Documentation

◆ DEFINE_DEBUG_VARS

#define DEFINE_DEBUG_VARS

Definition at line 23 of file adapter.cpp.

◆ PUT_GUIDS_HERE

#define PUT_GUIDS_HERE

Definition at line 18 of file adapter.cpp.

◆ STR_MODULENAME

#define STR_MODULENAME   "AC97 Adapter: "

Definition at line 13 of file adapter.cpp.

Function Documentation

◆ AddDevice()

NTSTATUS GZCALL AddDevice ( IN PDRIVER_OBJECT  DriverObject,
IN PDEVICE_OBJECT  PhysicalDeviceObject 
)

Definition at line 533 of file adapter.cpp.

538{
539 PAGED_CODE ();
540
541 DOUT (DBG_PRINT, ("[AddDevice]"));
542
543
544 //
545 // Tell portcls (the class driver) to add the device.
546 //
551 0);
552}
#define PAGED_CODE()
NTSTATUS NTAPI PcAddAdapterDevice(IN PDRIVER_OBJECT DriverObject, IN PDEVICE_OBJECT PhysicalDeviceObject, IN PCPFNSTARTDEVICE StartDevice, IN ULONG MaxObjects, IN ULONG DeviceExtensionSize)
Definition: adapter.cpp:73
PDEVICE_OBJECT PhysicalDeviceObject
Definition: btrfs_drv.h:1157
#define MAX_MINIPORTS
Definition: adapter.cpp:13
#define DOUT(lvl, strings)
Definition: debug.h:82
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
NTSTATUS(NTAPI * PCPFNSTARTDEVICE)(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PRESOURCELIST ResourceList)
Definition: portcls.h:2304
_Must_inspect_result_ _In_ PDRIVER_OBJECT DriverObject
Definition: wdfdriver.h:213
#define DBG_PRINT(ppi, ch, level)
Definition: win32kdebug.h:168

◆ DriverEntry()

NTSTATUS GZCALL DriverEntry ( IN PDRIVER_OBJECT  DriverObject,
IN PUNICODE_STRING  RegistryPathName 
)

Definition at line 561 of file adapter.cpp.

566{
567 PAGED_CODE ();
568
569 DOUT (DBG_PRINT, ("[DriverEntry]"));
570
571 //
572 // Tell the class driver to initialize the driver.
573 //
575 RegistryPathName,
577
578
579 return RetValue;
580}
NTSTATUS NTAPI PcInitializeAdapterDriver(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPathName, IN PDRIVER_ADD_DEVICE AddDevice)
Definition: adapter.cpp:29
LONG NTSTATUS
Definition: precomp.h:26
DRIVER_ADD_DEVICE AddDevice
Definition: parport.h:72
DRIVER_ADD_DEVICE * PDRIVER_ADD_DEVICE
Definition: iotypes.h:2216

◆ InstallSubdevice()

NTSTATUS InstallSubdevice ( _In_ PDEVICE_OBJECT  DeviceObject,
_In_ PIRP  Irp,
_In_ PWSTR  Name,
_In_ REFGUID  PortClassId,
_In_ REFGUID  MiniportClassId,
_In_opt_ PFNCREATEMINIPORT  MiniportCreate,
_In_opt_ PUNKNOWN  UnknownAdapter,
_In_opt_ PRESOURCELIST  ResourceList,
_In_opt_ REFGUID  PortInterfaceId,
_Out_opt_ PMINIPORT OutMiniport,
_Out_opt_ PUNKNOWN OutPortUnknown 
)

Definition at line 47 of file adapter.cpp.

61{
62 PAGED_CODE ();
63
64 NTSTATUS ntStatus;
65 PPORT port;
66 PMINIPORT miniport;
67
68 DOUT (DBG_PRINT, ("[InstallSubdevice]"));
69
70#ifndef __REACTOS__
71 UNREFERENCED_PARAMETER(PortInterfaceId);
72#endif
73
74 //
75 // Create the port driver object
76 //
77 ntStatus = PcNewPort (&port,PortClassId);
78
79 //
80 // return immediately in case of an error
81 //
82 if (!NT_SUCCESS (ntStatus))
83 return ntStatus;
84
85 //
86 // Create the miniport object
87 //
88 if (MiniportCreate)
89 {
90 ntStatus = MiniportCreate ((PUNKNOWN*)&miniport, MiniportClassId,
92 }
93 else
94 {
95 ntStatus = PcNewMiniport (&miniport,MiniportClassId);
96 }
97
98 //
99 // return immediately in case of an error
100 //
101 if (!NT_SUCCESS (ntStatus))
102 {
103 port->Release ();
104 return ntStatus;
105 }
106
107 //
108 // Init the port driver and miniport in one go.
109 //
110#ifdef _MSC_VER
111#pragma warning(push)
112#endif
113 // IPort::Init's annotation on ResourceList requires it to be non-NULL. However,
114 // for dynamic devices, we may no longer have the resource list and this should
115 // still succeed.
116 //
117#ifdef _MSC_VER
118#pragma warning(disable:6387)
119#endif
120 ntStatus = port->Init (DeviceObject, Irp, miniport, UnknownAdapter,
122#ifdef _MSC_VER
123#pragma warning(pop)
124#endif
125
126 if (NT_SUCCESS (ntStatus))
127 {
128 //
129 // Register the subdevice (port/miniport combination).
130 //
132
133 //
134 // Deposit the port as an unknown if it's needed.
135 //
136 if (OutPortUnknown && NT_SUCCESS (ntStatus))
137 {
138 ntStatus = port->QueryInterface (IID_IUnknown,
139 (PVOID *)OutPortUnknown);
140 }
141
142 //
143 // Deposit the miniport as an IMiniport if it's needed.
144 //
145 if ( OutMiniport && NT_SUCCESS (ntStatus) )
146 {
147 ntStatus = miniport->QueryInterface (IID_IMiniport,
148 (PVOID *)OutMiniport);
149 }
150 }
151
152 //
153 // Release the reference for the port and miniport. This is the right
154 // thing to do, regardless of the outcome.
155 //
156 miniport->Release ();
157 port->Release ();
158
159
160 return ntStatus;
161}
NTSTATUS NTAPI PcRegisterSubdevice(IN PDEVICE_OBJECT DeviceObject, IN PWCHAR Name, IN PUNKNOWN Unknown)
Definition: adapter.cpp:206
NTSTATUS NTAPI PcNewMiniport(OUT PMINIPORT *OutMiniport, IN REFCLSID ClassId)
Definition: miniport.cpp:45
const GUID IID_IUnknown
_In_ PIRP Irp
Definition: csq.h:116
#define NULL
Definition: types.h:112
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:32
USHORT port
Definition: uri.c:228
#define NonPagedPool
Definition: env_spec_w32.h:307
#define UNREFERENCED_PARAMETER(P)
Definition: ntbasedef.h:317
NTSTATUS NTAPI PcNewPort(OUT PPORT *OutPort, IN REFCLSID ClassId)
Definition: port.cpp:17
IPort * PPORT
Definition: portcls.h:1105
_In_ PDEVICE_OBJECT DeviceObject
Definition: wdfdevice.h:2055
_Must_inspect_result_ _In_ WDFIORESREQLIST _In_opt_ PWDF_OBJECT_ATTRIBUTES _Out_ WDFIORESLIST * ResourceList
Definition: wdfresource.h:309

Referenced by StartDevice().

◆ StartDevice()

NTSTATUS GZCALL StartDevice ( IN PDEVICE_OBJECT  DeviceObject,
IN PIRP  Irp,
IN PRESOURCELIST  ResourceList 
)

Definition at line 210 of file adapter.cpp.

216{
217 PAGED_CODE ();
218
220 ASSERT (Irp);
222
223 NTSTATUS ntStatus;
224
225 DOUT (DBG_PRINT, ("[StartDevice]"));
226
227 //
228 // Determine which version of the OS we are running under. We don't want
229 // to run under Win98G.
230 //
231
232 // create a wave cyclic port
233 PPORT pPort = 0;
234 ntStatus = PcNewPort (&pPort,CLSID_PortWaveCyclic);
235
236 // check error code
237 if (NT_SUCCESS (ntStatus))
238 {
239 // query for the event interface which is not supported in Win98 gold.
240 PPORTEVENTS pPortEvents = 0;
241 ntStatus = pPort->QueryInterface (IID_IPortEvents,
242 (PVOID *)&pPortEvents);
243 if (!NT_SUCCESS (ntStatus))
244 {
245 DOUT (DBG_ERROR, ("This driver is not for Win98 Gold!"));
246 ntStatus = STATUS_UNSUCCESSFUL; // change error code.
247 }
248 else
249 {
250 pPortEvents->Release ();
251 }
252 pPort->Release ();
253 }
254
255 // now return in case it was Win98 Gold.
256 if (!NT_SUCCESS (ntStatus))
257 return ntStatus;
258
259 //
260 // Validate the resources.
261 // We don't have to split the resources into several resource lists cause
262 // the topology miniport doesn't need a resource list, the wave pci miniport
263 // needs all resources like the adapter common object.
264 //
265 ntStatus = ValidateResources (ResourceList);
266
267 //
268 // return immediately in case of an error
269 //
270 if (!NT_SUCCESS (ntStatus))
271 return ntStatus;
272
273 //
274 // If the adapter has the right resources...
275 //
276 PADAPTERCOMMON pAdapterCommon = NULL;
277 PUNKNOWN pUnknownCommon;
278
279 // create a new adapter common object
280 ntStatus = NewAdapterCommon (&pUnknownCommon, IID_IAC97AdapterCommon,
282
283 if (NT_SUCCESS (ntStatus))
284 {
285 // query for the IAC97AdapterCommon interface
286 ntStatus = pUnknownCommon->QueryInterface (IID_IAC97AdapterCommon,
287 (PVOID *)&pAdapterCommon);
288 if (NT_SUCCESS (ntStatus))
289 {
290 // Initialize the object
291 ntStatus = pAdapterCommon->Init (ResourceList, DeviceObject);
292
293 if (NT_SUCCESS (ntStatus))
294 {
295 // register with PortCls for power-management services
296 ntStatus = PcRegisterAdapterPowerManagement ((PUNKNOWN)pAdapterCommon,
298 }
299 }
300
301 // release the IID_IAC97AdapterCommon on adapter common
302 pUnknownCommon->Release ();
303 }
304
305 // print error message.
306 if (!NT_SUCCESS (ntStatus))
307 {
308 DOUT (DBG_ERROR, ("Could not create or query AdapterCommon."));
309 }
310
311 //
312 // These are the port driver pointers we are keeping around for registering
313 // physical connections.
314 //
315 PMINIPORT miniTopology = NULL;
316 PUNKNOWN unknownWave = NULL;
317 PUNKNOWN unknownTopology = NULL;
318 PAC97MINIPORTTOPOLOGY pMiniportTopology = NULL;
319
320 //
321 // Start the topology miniport.
322 //
323 if (NT_SUCCESS (ntStatus))
324 {
325 ntStatus = InstallSubdevice (DeviceObject,
326 Irp,
327 L"Topology",
328 CLSID_PortTopology,
329 CLSID_PortTopology, // not used
331 pAdapterCommon,
332 NULL,
333 GUID_NULL,
334 &miniTopology,
335 &unknownTopology);
336
337 if (NT_SUCCESS (ntStatus))
338 {
339 // query for the IAC97MiniportTopology interface
340 ntStatus = miniTopology->QueryInterface (IID_IAC97MiniportTopology,
341 (PVOID *)&pMiniportTopology);
342 miniTopology->Release ();
343 miniTopology = NULL;
344 }
345
346 // print error message.
347 if (!NT_SUCCESS (ntStatus))
348 {
349 DOUT (DBG_ERROR, ("Could not create or query TopologyICH"));
350 }
351 }
352
353 //
354 // Start the wave miniport.
355 //
356 if (NT_SUCCESS (ntStatus))
357 {
358#if (NTDDI_VERSION >= NTDDI_VISTA)
359 ntStatus = InstallSubdevice (DeviceObject,
360 Irp,
361 L"Wave",
362 CLSID_PortWaveRT,
363 CLSID_PortWaveRT, // not used
365 pAdapterCommon,
367 IID_IPortWaveRT,
368 NULL,
369 &unknownWave);
370
371 if (!NT_SUCCESS (ntStatus))
372 {
373#endif
374 //
375 // If creation of the RT port failed we can fall back to the WavePCI
376 // or WaveCyc port of portcls. In this case, we try the WavePCI port.
377 //
378#if 1
379 ntStatus = InstallSubdevice (DeviceObject,
380 Irp,
381 L"Wave",
382 CLSID_PortWaveCyclic,
383 CLSID_PortWaveCyclic, // not used
385 pAdapterCommon,
387 IID_IPortWaveCyclic,
388 NULL,
389 &unknownWave);
390#else
391 ntStatus = InstallSubdevice (DeviceObject,
392 Irp,
393 L"Wave",
394 CLSID_PortWavePci,
395 CLSID_PortWavePci, // not used
397 pAdapterCommon,
399 IID_IPortWavePci,
400 NULL,
401 &unknownWave);
402#endif
403
404
405#if (NTDDI_VERSION >= NTDDI_VISTA)
406 }
407#endif
408 // print error message.
409 if (!NT_SUCCESS (ntStatus))
410 {
411 DOUT (DBG_ERROR, ("WaveRT and WavePCI miniport installation failed!"));
412 }
413 }
414
415 //
416 // Establish physical connections between filters as shown.
417 //
418 // +------+ +------+
419 // | Wave | | Topo |
420 // Capture <---|2 3|<===|x |<--- CD
421 // | | | |
422 // Render --->|0 1|===>|y |<--- Line In
423 // | | | |
424 // Mic <---|4 5|<===|z |<--- Mic
425 // +------+ | |
426 // | |---> Line Out
427 // +------+
428 //
429 // Note that the pin numbers for the nodes to be connected
430 // vary depending on the hardware/codec configuration.
431 // Also, the mic input may or may not be present.
432 //
433 // So,
434 // Do a QI on unknownTopology to get an interface to call
435 // a method on to get the topology miniport pin IDs.
436
437 if (NT_SUCCESS (ntStatus))
438 {
439 ULONG ulWaveOut, ulWaveIn, ulMicIn;
440
441 // get the pin numbers.
442 DOUT (DBG_PRINT, ("Connecting topo and wave."));
443 ntStatus = pMiniportTopology->GetPhysicalConnectionPins (&ulWaveOut,
444 &ulWaveIn, &ulMicIn);
445
446 // register wave render connection
447 if (NT_SUCCESS (ntStatus))
448 {
450 unknownWave,
452 unknownTopology,
453 ulWaveOut);
454 // print error message.
455 if (!NT_SUCCESS (ntStatus))
456 {
457 DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport"
458 " (render)!"));
459 }
460 }
461
462
463 if (NT_SUCCESS (ntStatus))
464 {
465 // register wave capture connection
467 unknownTopology,
468 ulWaveIn,
469 unknownWave,
471 // print error message.
472 if (!NT_SUCCESS (ntStatus))
473 {
474 DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport"
475 " (capture)!"));
476 }
477 }
478
479 if (NT_SUCCESS (ntStatus))
480 {
481 // register mic capture connection
482 if (pAdapterCommon->GetPinConfig (PINC_MICIN_PRESENT))
483 {
485 unknownTopology,
486 ulMicIn,
487 unknownWave,
489 // print error message.
490 if (!NT_SUCCESS (ntStatus))
491 {
492 DOUT (DBG_ERROR, ("Cannot connect topology and wave miniport"
493 " (MIC)!"));
494 }
495 }
496 }
497 }
498
499 //
500 // Release the adapter common object. It either has other references,
501 // or we need to delete it anyway.
502 //
503 if (pAdapterCommon)
504 pAdapterCommon->Release ();
505
506 //
507 // Release the unknowns.
508 //
509 if (unknownTopology)
510 unknownTopology->Release ();
511 if (unknownWave)
512 unknownWave->Release ();
513
514 // and the AC97 miniport.
515 if (pMiniportTopology)
516 pMiniportTopology->Release ();
517
518
519 return ntStatus; // whatever this is ...
520}
NTSTATUS NewAdapterCommon(OUT PUNKNOWN *Unknown, IN REFCLSID, IN PUNKNOWN UnknownOuter OPTIONAL, _When_((PoolType &NonPagedPoolMustSucceed) !=0, __drv_reportError("Must succeed pool allocations are forbidden. " "Allocation failures cause a system crash")) IN POOL_TYPE PoolType)
Definition: common.cpp:117
NTSTATUS NTAPI PcRegisterPhysicalConnection(IN PDEVICE_OBJECT DeviceObject, IN PUNKNOWN FromUnknown, IN ULONG FromPin, IN PUNKNOWN ToUnknown, IN ULONG ToPin)
Definition: connection.cpp:259
NTSTATUS InstallSubdevice(_In_ PDEVICE_OBJECT DeviceObject, _In_ PIRP Irp, _In_ PWSTR Name, _In_ REFGUID PortClassId, _In_ REFGUID MiniportClassId, _In_opt_ PFNCREATEMINIPORT MiniportCreate, _In_opt_ PUNKNOWN UnknownAdapter, _In_opt_ PRESOURCELIST ResourceList, _In_opt_ REFGUID PortInterfaceId, _Out_opt_ PMINIPORT *OutMiniport, _Out_opt_ PUNKNOWN *OutPortUnknown)
Definition: adapter.cpp:48
NTSTATUS ValidateResources(IN PRESOURCELIST ResourceList)
Definition: adapter.cpp:173
NTSTATUS NTAPI PcRegisterAdapterPowerManagement(IN PUNKNOWN pUnknown, IN PVOID pvContext)
Definition: power.cpp:16
NTSTATUS CreateAC97MiniportTopology(OUT PUNKNOWN *Unknown, IN REFCLSID, IN PUNKNOWN UnknownOuter OPTIONAL, IN POOL_TYPE PoolType)
NTSTATUS CreateAC97MiniportWaveCyclic(OUT PUNKNOWN *Unknown, IN REFCLSID, IN PUNKNOWN UnknownOuter OPTIONAL, IN POOL_TYPE PoolType)
NTSTATUS CreateAC97MiniportWaveRT(OUT PUNKNOWN *Unknown, IN REFCLSID, IN PUNKNOWN UnknownOuter OPTIONAL, IN POOL_TYPE PoolType)
NTSTATUS CreateAC97MiniportWavePCI(OUT PUNKNOWN *Unknown, IN REFCLSID, IN PUNKNOWN UnknownOuter OPTIONAL, IN POOL_TYPE PoolType)
@ PIN_WAVEOUT_BRIDGE
Definition: shared.h:319
@ PIN_WAVEIN_BRIDGE
Definition: shared.h:321
@ PIN_MICIN_BRIDGE
Definition: shared.h:323
@ PINC_MICIN_PRESENT
Definition: shared.h:70
IAC97MiniportTopology * PAC97MINIPORTTOPOLOGY
Definition: shared.h:380
IAC97AdapterCommon * PADAPTERCOMMON
Definition: shared.h:488
HRESULT QueryInterface([in] REFIID riid, [out, iid_is(riid)] void **ppvObject)
ULONG Release()
nsrefcnt Release()
#define GUID_NULL
Definition: ks.h:106
#define ASSERT(a)
Definition: mode.c:44
#define DBG_ERROR
Definition: nfs41_debug.h:78
#define L(x)
Definition: ntvdm.h:50
IPortEvents * PPORTEVENTS
Definition: portcls.h:2121
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_UNSUCCESSFUL
Definition: udferr_usr.h:132

◆ ValidateResources()

NTSTATUS ValidateResources ( IN PRESOURCELIST  ResourceList)

Definition at line 172 of file adapter.cpp.

176{
177 PAGED_CODE ();
178
179 DOUT (DBG_PRINT, ("[ValidateResources]"));
180
181 //
182 // Get counts for the types of resources.
183 //
184 ULONG countIO = ResourceList->NumberOfPorts ();
185 ULONG countIRQ = ResourceList->NumberOfInterrupts ();
186 ULONG countDMA = ResourceList->NumberOfDmas ();
187
188 // validate resources
189 if ((countIO != 2) || (countIRQ != 1) || (countDMA != 0))
190 {
191 DOUT (DBG_ERROR, ("Unknown configuration:\n"
192 " IO count: %d\n"
193 " IRQ count: %d\n"
194 " DMA count: %d",
195 countIO, countIRQ, countDMA));
197 }
198
199 return STATUS_SUCCESS;
200}
#define STATUS_DEVICE_CONFIGURATION_ERROR
Definition: ntstatus.h:619
#define STATUS_SUCCESS
Definition: shellext.h:65

Referenced by StartDevice().

Variable Documentation

◆ AddDevice

DRIVER_ADD_DEVICE AddDevice

Definition at line 31 of file adapter.cpp.

◆ DriverEntry

DRIVER_INITIALIZE DriverEntry

Definition at line 560 of file adapter.cpp.