Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1971 lines
52 KiB

  1. /****************************************************************************
  2. *
  3. * wdmsys.h
  4. *
  5. * Function declarations, etc. for WDMAUD.SYS
  6. *
  7. * Copyright (C) Microsoft Corporation, 1997 - 1999 All Rights Reserved.
  8. *
  9. * History
  10. * 5-19-97 - Noel Cross (NoelC)
  11. *
  12. ***************************************************************************/
  13. #ifndef _WDMSYS_H_INCLUDED_
  14. #define _WDMSYS_H_INCLUDED_
  15. #ifdef UNDER_NT
  16. #if DBG
  17. #define DEBUG
  18. #endif
  19. #endif
  20. #include <ntddk.h>
  21. #include <windef.h>
  22. #include <winerror.h>
  23. #include <memory.h>
  24. #include <stddef.h>
  25. #include <stdio.h>
  26. #include <limits.h>
  27. #include <stdlib.h>
  28. #include <tchar.h>
  29. #include <conio.h>
  30. #include <math.h>
  31. // Make sure we will get correct multimedia structures from mmsystem.
  32. #ifdef UNDER_NT
  33. #ifndef _WIN32
  34. #pragma message( "WARNING: _WIN32 not defined. Build not valid for NT." )
  35. #endif
  36. #ifndef UNICODE
  37. #pragma message( "WARNING: UNICODE not defined. Build not valid for NT." )
  38. #endif
  39. #else
  40. #pragma message( "WARNING: UNDER_NT not defined. Build not valid for NT." )
  41. #endif
  42. #define NOBITMAP
  43. #include <mmsystem.h>
  44. #include <mmreg.h>
  45. #include <mmddk.h>
  46. #undef NOBITMAP
  47. #include <ks.h>
  48. #include <ksmedia.h>
  49. #include <swenum.h>
  50. #include <ksdebug.h>
  51. #include <midi.h>
  52. #include <wdmaud.h>
  53. #include "mixer.h"
  54. #include "robust.h"
  55. #define INIT_CODE code_seg("INIT", "CODE")
  56. #define INIT_DATA data_seg("INIT", "DATA")
  57. #define LOCKED_CODE code_seg(".text", "CODE")
  58. #define LOCKED_DATA data_seg(".data", "DATA")
  59. #define PAGEABLE_CODE code_seg("PAGE", "CODE")
  60. #define PAGEABLE_DATA data_seg("PAGEDATA", "DATA")
  61. #pragma PAGEABLE_CODE
  62. #pragma PAGEABLE_DATA
  63. /***************************************************************************
  64. Constants
  65. ***************************************************************************/
  66. #define PROFILE // turn on to help with debugging
  67. #define WAVE_CONTROL_VOLUME 0
  68. #define WAVE_CONTROL_RATE 1
  69. #define WAVE_CONTROL_QUALITY 2
  70. #define MAX_WAVE_CONTROLS 3
  71. #define MIDI_CONTROL_VOLUME 0
  72. #define MAX_MIDI_CONTROLS 1
  73. #define WILD_CARD 0xfffffffe
  74. #define INVALID_NODE 0xffffffff
  75. #define MAXNUMDEVS 32
  76. #define MAXDEVNODES 100
  77. #define STR_MODULENAME "wdmaud.sys: "
  78. #define STR_DEVICENAME TEXT("\\Device\\wdmaud")
  79. #define STR_LINKNAME TEXT("\\DosDevices\\wdmaud")
  80. #define STR_PNAME TEXT("%s (%d)")
  81. #ifdef DEBUG
  82. #define CONTEXT_SIGNATURE 'XNOC' // CONteXt structure
  83. #define MIXERDEVICE_SIGNATURE 'DXIM' // MIXerDevice structure
  84. #define MIXEROBJECT_SIGNATURE 'OXIM' // MIXerObject structure
  85. #define HWLINK_SIGNATURE 'KLWH' //HWLINK signature
  86. #endif
  87. #define LIVE_CONTROL ((PMXLCONTROL)(-1))
  88. #define INCREASE TRUE
  89. #define DECREASE FALSE
  90. /***************************************************************************
  91. structure definitions
  92. ***************************************************************************/
  93. typedef struct _WDMAPENDINGIRP_QUEUE {
  94. LIST_ENTRY WdmaPendingIrpListHead;
  95. KSPIN_LOCK WdmaPendingIrpListSpinLock;
  96. IO_CSQ Csq;
  97. } WDMAPENDINGIRP_QUEUE, *PWDMAPENDINGIRP_QUEUE;
  98. extern WDMAPENDINGIRP_QUEUE wdmaPendingIrpQueue;
  99. typedef struct _WDMAPENDINGIRP_CONTEXT {
  100. IO_CSQ_IRP_CONTEXT IrpContext;
  101. ULONG IrpDeviceType;
  102. struct tag_WDMACONTEXT *pContext;
  103. } WDMAPENDINGIRP_CONTEXT, *PWDMAPENDINGIRP_CONTEXT;
  104. typedef struct tag_ALLOCATED_MDL_LIST_ITEM
  105. {
  106. LIST_ENTRY Next;
  107. PMDL pMdl;
  108. struct tag_WDMACONTEXT *pContext;
  109. } ALLOCATED_MDL_LIST_ITEM , *PALLOCATED_MDL_LIST_ITEM;
  110. //typedef struct tag_IOCTL_HISTORY_LIST_ITEM
  111. //{
  112. // LIST_ENTRY Next;
  113. // PIRP pIrp;
  114. // ULONG IoCode;
  115. // NTSTATUS IoStatus;
  116. // struct tag_WDMACONTEXT *pContext;
  117. //} IOCTL_HISTORY_LIST_ITEM , *PIOCTL_HISTORY_LIST_ITEM;
  118. typedef struct device_instance
  119. {
  120. PVOID pDeviceHeader;
  121. } DEVICE_INSTANCE, *PDEVICE_INSTANCE;
  122. typedef struct _CONTROL_NODE
  123. {
  124. GUID Control;
  125. ULONG NodeId;
  126. ULONG Reserved;
  127. } CONTROL_NODE, *PCONTROL_NODE;
  128. typedef struct _CONTROLS_LIST
  129. {
  130. ULONG Count;
  131. ULONG Reserved;
  132. CONTROL_NODE Controls[1];
  133. } CONTROLS_LIST, *PCONTROLS_LIST;
  134. typedef struct _WAVEPOSITION {
  135. DWORD Operation; // Get / Set
  136. DWORD BytePos;
  137. } WAVEPOSITION, *PWAVEPOSITION, FAR *LPWAVEPOSITION;
  138. typedef struct _DEVICEVOLUME {
  139. DWORD Operation; // Get / Set
  140. DWORD Channel;
  141. DWORD Level;
  142. } DEVICEVOLUME, *PDEVICEVOLUME, FAR *LPDEVICEVOLUME;
  143. #define WAVE_PIN_INSTANCE_SIGNATURE ((ULONG)'SIPW') //WPIS
  144. //
  145. // This macro can be used with NT_SUCCESS to branch. Effectively returns an
  146. // NTSTATUS code.
  147. //
  148. #define IsValidWavePinInstance(pwpi) ((pwpi->dwSig == WAVE_PIN_INSTANCE_SIGNATURE) ? \
  149. STATUS_SUCCESS:STATUS_UNSUCCESSFUL)
  150. //
  151. // The Wave pin instance structure and the midi pin instance structure need to
  152. // use a common header so that the duplicate servicing functions can be
  153. // removed.
  154. //
  155. typedef struct _WAVEPININSTANCE
  156. {
  157. PFILE_OBJECT pFileObject;
  158. PDEVICE_OBJECT pDeviceObject;
  159. struct tag_WAVEDEVICE *pWaveDevice;
  160. KSPIN_LOCK WavePinSpinLock; // For State Changes
  161. BOOL fGraphRunning;
  162. KSSTATE PinState;
  163. KEVENT StopEvent;
  164. KEVENT PauseEvent;
  165. volatile ULONG NumPendingIos;
  166. volatile BOOL StoppingSource; // Flag which indicates
  167. // that the pin is in the
  168. // stopping process
  169. volatile BOOL PausingSource; // Flag which indicates
  170. // that the pin is in the
  171. // pausing process
  172. ULONG DeviceNumber;
  173. ULONG DataFlow;
  174. BOOL fWaveQueued;
  175. LPWAVEFORMATEX lpFormat;
  176. DWORD dwFlags;
  177. PCONTROLS_LIST pControlList;
  178. HANDLE32 WaveHandle;
  179. struct _WAVEPININSTANCE *Next;
  180. DWORD dwSig; //Used to validate structure.
  181. } WAVE_PIN_INSTANCE, *PWAVE_PIN_INSTANCE;
  182. typedef struct _midiinhdr
  183. {
  184. LIST_ENTRY Next;
  185. LPMIDIDATA pMidiData;
  186. PIRP pIrp;
  187. PMDL pMdl;
  188. PWDMAPENDINGIRP_CONTEXT pPendingIrpContext;
  189. } MIDIINHDR, *PMIDIINHDR;
  190. #define MIDI_PIN_INSTANCE_SIGNATURE ((ULONG)'SIPM') //MPIS
  191. //
  192. // This macro can be used with NT_SUCCESS to branch. Effectively returns a
  193. // NTSTATUS code.
  194. //
  195. #define IsValidMidiPinInstance(pmpi) ((pmpi->dwSig == MIDI_PIN_INSTANCE_SIGNATURE) ? \
  196. STATUS_SUCCESS:STATUS_UNSUCCESSFUL)
  197. typedef struct _MIDIPININSTANCE
  198. {
  199. PFILE_OBJECT pFileObject;
  200. PDEVICE_OBJECT pDeviceObject;
  201. struct tag_MIDIDEVICE *pMidiDevice;
  202. KSPIN_LOCK MidiPinSpinLock; // For state changes
  203. BOOL fGraphRunning;
  204. KSSTATE PinState;
  205. KEVENT StopEvent;
  206. ULONG NumPendingIos;
  207. volatile BOOL StoppingSource; // Flag which indicates
  208. // that the pin is in the
  209. // stopping process
  210. LIST_ENTRY MidiInQueueListHead; // for midihdrs
  211. KSPIN_LOCK MidiInQueueSpinLock;
  212. KSEVENT MidiInNotify; // for notification of new midiin data
  213. WORK_QUEUE_ITEM MidiInWorkItem;
  214. ULONG DeviceNumber;
  215. ULONG DataFlow;
  216. PCONTROLS_LIST pControlList;
  217. ULONG LastTimeMs;
  218. ULONGLONG LastTimeNs;
  219. BYTE bCurrentStatus;
  220. DWORD dwSig; // Used to validate structure
  221. } MIDI_PIN_INSTANCE, *PMIDI_PIN_INSTANCE;
  222. #define STREAM_HEADER_EX_SIGNATURE ((ULONG)'XEHS') //SHEX
  223. //
  224. // This macro can be used with NT_SUCCESS to branch. Effectively returns a
  225. // NTSTATUS code.
  226. //
  227. #define IsValidStreamHeaderEx(pshex) ((pshex->dwSig == STREAM_HEADER_EX_SIGNATURE) ? \
  228. STATUS_SUCCESS:STATUS_UNSUCCESSFUL)
  229. typedef struct _STREAM_HEADER_EX
  230. {
  231. KSSTREAM_HEADER Header;
  232. IO_STATUS_BLOCK IoStatus;
  233. union
  234. {
  235. PDWORD pdwBytesRecorded;
  236. PWAVEHDR pWaveHdr;
  237. PMIDIHDR pMidiHdr;
  238. };
  239. union
  240. {
  241. PWAVE_PIN_INSTANCE pWavePin;
  242. PMIDI_PIN_INSTANCE pMidiPin;
  243. };
  244. PIRP pIrp;
  245. PWAVEHDR pWaveHdrAligned;
  246. PMDL pHeaderMdl;
  247. PMDL pBufferMdl;
  248. PWDMAPENDINGIRP_CONTEXT pPendingIrpContext;
  249. DWORD dwSig; //Used To validate structure.
  250. } STREAM_HEADER_EX, *PSTREAM_HEADER_EX;
  251. //
  252. // make sure that this structure doesn't exceed the size of
  253. // the midihdr, otherwise the write_context defintion in
  254. // vxd.asm needs to be updated.
  255. //
  256. typedef struct _wavehdrex
  257. {
  258. WAVEHDR wh;
  259. PWAVE_PIN_INSTANCE pWaveInstance;
  260. } WAVEINSTANCEHDR, *PWAVEINSTANCEHDR;
  261. #define WRITE_CONTEXT_SIGNATURE ((ULONG)'GSCW') //WCSG
  262. //
  263. // This macro can be used with NT_SUCCESS to branch. Effectively returns a
  264. // NTSTATUS code.
  265. //
  266. #define IsValidWriteContext(pwc) ((pwc->dwSig == WRITE_CONTEXT_SIGNATURE) ? \
  267. STATUS_SUCCESS:STATUS_UNSUCCESSFUL)
  268. typedef struct write_context
  269. {
  270. union
  271. {
  272. WAVEINSTANCEHDR whInstance;
  273. MIDIHDR mh;
  274. };
  275. DWORD ClientContext;
  276. DWORD ClientContext2;
  277. WORD CallbackOffset;
  278. WORD CallbackSegment;
  279. DWORD ClientThread;
  280. union
  281. {
  282. LPWAVEHDR WaveHeaderLinearAddress;
  283. LPMIDIHDR MidiHeaderLinearAddress;
  284. };
  285. PVOID pCapturedWaveHdr;
  286. PMDL pBufferMdl;
  287. PWDMAPENDINGIRP_CONTEXT pPendingIrpContext;
  288. DWORD dwSig; // Used to validate structure.
  289. } WRITE_CONTEXT, *PWRITE_CONTEXT;
  290. typedef struct tag_IDENTIFIERS
  291. {
  292. KSMULTIPLE_ITEM;
  293. KSIDENTIFIER aIdentifiers[1]; // Array of identifiers
  294. } IDENTIFIERS, *PIDENTIFIERS;
  295. typedef struct tag_DATARANGES
  296. {
  297. KSMULTIPLE_ITEM;
  298. KSDATARANGE aDataRanges[1];
  299. } DATARANGES, *PDATARANGES;
  300. typedef struct tag_KSPROPERTYPLUS
  301. {
  302. KSPROPERTY Property;
  303. ULONG DeviceIndex;
  304. } KSPROPERTYPLUS, *PKSPROPERTYPLUS;
  305. //
  306. // COMMONDEVICE
  307. // DeviceInterface - the buffer for this string is allocated for all
  308. // classes except mixer. For mixer, it is a pointer to a buffer
  309. // allocated for one of the wave classes.
  310. //
  311. typedef struct tag_COMMONDEVICE
  312. {
  313. ULONG Device;
  314. ULONG PinId;
  315. PWSTR DeviceInterface;
  316. PWSTR pwstrName;
  317. ULONG PreferredDevice;
  318. struct tag_WDMACONTEXT *pWdmaContext;
  319. PKSCOMPONENTID ComponentId;
  320. } COMMONDEVICE, *PCOMMONDEVICE;
  321. typedef struct tag_WAVEDEVICE
  322. {
  323. COMMONDEVICE;
  324. PDATARANGES AudioDataRanges;
  325. PWAVE_PIN_INSTANCE pWavePin;
  326. DWORD LeftVolume; // only used for output
  327. DWORD RightVolume; // only used for output
  328. DWORD dwVolumeID; // only used for output
  329. DWORD cChannels; // only used for output
  330. PKTIMER pTimer; // only used for output
  331. PKDPC pDpc; // only used for output
  332. BOOL fNeedToSetVol; // only used for output
  333. } WAVEDEVICE, *PWAVEDEVICE;
  334. typedef struct tag_MIDIDEVICE
  335. {
  336. COMMONDEVICE;
  337. PDATARANGES MusicDataRanges;
  338. PMIDI_PIN_INSTANCE pMidiPin;
  339. DWORD dwVolumeID; // only used for output
  340. DWORD cChannels; // only used for output
  341. } MIDIDEVICE, *PMIDIDEVICE;
  342. typedef struct tag_MIXERDEVICE
  343. {
  344. COMMONDEVICE;
  345. ULONG cDestinations; // The no. of destinations on device
  346. LINELIST listLines; // The list of all lines on the dev.
  347. KSTOPOLOGY Topology; // The topology
  348. ULONG Mapping; // Mapping algorithm for this device
  349. PFILE_OBJECT pfo; // used for talking to SysAudio
  350. #ifdef DEBUG
  351. DWORD dwSig;
  352. #endif
  353. } MIXERDEVICE, *PMIXERDEVICE;
  354. typedef struct tag_AUXDEVICE
  355. {
  356. COMMONDEVICE;
  357. DWORD dwVolumeID;
  358. DWORD cChannels;
  359. } AUXDEVICE, *PAUXDEVICE;
  360. typedef struct tag_DEVNODE_LIST_ITEM
  361. {
  362. LIST_ENTRY Next;
  363. LONG cReference; // Number of device classes init'ed
  364. LPWSTR DeviceInterface;
  365. ULONG cDevices[MAX_DEVICE_CLASS]; // Count of devices for each class
  366. BOOLEAN fAdded[MAX_DEVICE_CLASS];
  367. } DEVNODE_LIST_ITEM, *PDEVNODE_LIST_ITEM;
  368. typedef struct tag_WORK_LIST_ITEM
  369. {
  370. LIST_ENTRY Next;
  371. VOID (*Function)(
  372. PVOID Reference1,
  373. PVOID Reference2
  374. );
  375. PVOID Reference1;
  376. PVOID Reference2;
  377. } WORK_LIST_ITEM, *PWORK_LIST_ITEM;
  378. extern KMUTEX wdmaMutex;
  379. typedef struct tag_WDMACONTEXT
  380. {
  381. LIST_ENTRY Next;
  382. BOOL fInList;
  383. BOOL fInitializeSysaudio;
  384. KEVENT InitializedSysaudioEvent;
  385. PFILE_OBJECT pFileObjectSysaudio;
  386. KSEVENTDATA EventData;
  387. ULONG VirtualWavePinId;
  388. ULONG VirtualMidiPinId;
  389. ULONG VirtualCDPinId;
  390. ULONG PreferredSysaudioWaveDevice;
  391. ULONG DevNodeListCount;
  392. LIST_ENTRY DevNodeListHead;
  393. PVOID NotificationEntry;
  394. WORK_QUEUE_ITEM WorkListWorkItem;
  395. LIST_ENTRY WorkListHead;
  396. KSPIN_LOCK WorkListSpinLock;
  397. LONG cPendingWorkList;
  398. WORK_QUEUE_ITEM SysaudioWorkItem;
  399. PKSWORKER WorkListWorkerObject;
  400. PKSWORKER SysaudioWorkerObject;
  401. WAVEDEVICE WaveOutDevs[MAXNUMDEVS];
  402. WAVEDEVICE WaveInDevs[MAXNUMDEVS];
  403. MIDIDEVICE MidiOutDevs[MAXNUMDEVS];
  404. MIDIDEVICE MidiInDevs[MAXNUMDEVS];
  405. MIXERDEVICE MixerDevs[MAXNUMDEVS];
  406. AUXDEVICE AuxDevs[MAXNUMDEVS];
  407. PCOMMONDEVICE apCommonDevice[MAX_DEVICE_CLASS][MAXNUMDEVS];
  408. #ifdef DEBUG
  409. DWORD dwSig;
  410. #endif
  411. } WDMACONTEXT, *PWDMACONTEXT;
  412. #ifdef WIN32
  413. #include <pshpack1.h>
  414. #else
  415. #ifndef RC_INVOKED
  416. #pragma pack(1)
  417. #endif
  418. #endif
  419. // This include needs to be here since it needs some of the declarations
  420. // above
  421. #include "kmxluser.h"
  422. typedef WORD VERSION; /* major (high byte), minor (low byte) */
  423. typedef struct waveoutcaps16_tag {
  424. WORD wMid; /* manufacturer ID */
  425. WORD wPid; /* product ID */
  426. WORD vDriverVersion; /* version of the driver */
  427. char szPname[MAXPNAMELEN]; /* product name (NULL terminated string) */
  428. DWORD dwFormats; /* formats supported */
  429. WORD wChannels; /* number of sources supported */
  430. DWORD dwSupport; /* functionality supported by driver */
  431. } WAVEOUTCAPS16, *PWAVEOUTCAPS16;
  432. typedef struct waveincaps16_tag {
  433. WORD wMid; /* manufacturer ID */
  434. WORD wPid; /* product ID */
  435. WORD vDriverVersion; /* version of the driver */
  436. char szPname[MAXPNAMELEN]; /* product name (NULL terminated string) */
  437. DWORD dwFormats; /* formats supported */
  438. WORD wChannels; /* number of channels supported */
  439. } WAVEINCAPS16, *PWAVEINCAPS16;
  440. typedef struct midioutcaps16_tag {
  441. WORD wMid; /* manufacturer ID */
  442. WORD wPid; /* product ID */
  443. WORD vDriverVersion; /* version of the driver */
  444. char szPname[MAXPNAMELEN]; /* product name (NULL terminated string) */
  445. WORD wTechnology; /* type of device */
  446. WORD wVoices; /* # of voices (internal synth only) */
  447. WORD wNotes; /* max # of notes (internal synth only) */
  448. WORD wChannelMask; /* channels used (internal synth only) */
  449. DWORD dwSupport; /* functionality supported by driver */
  450. } MIDIOUTCAPS16, *PMIDIOUTCAPS16;
  451. typedef struct midiincaps16_tag {
  452. WORD wMid; /* manufacturer ID */
  453. WORD wPid; /* product ID */
  454. WORD vDriverVersion; /* version of the driver */
  455. char szPname[MAXPNAMELEN]; /* product name (NULL terminated string) */
  456. #if (WINVER >= 0x0400)
  457. DWORD dwSupport; /* functionality supported by driver */
  458. #endif
  459. } MIDIINCAPS16, *PMIDIINCAPS16;
  460. typedef struct mixercaps16_tag {
  461. WORD wMid; /* manufacturer id */
  462. WORD wPid; /* product id */
  463. WORD vDriverVersion; /* version of the driver */
  464. char szPname[MAXPNAMELEN]; /* product name */
  465. DWORD fdwSupport; /* misc. support bits */
  466. DWORD cDestinations; /* count of destinations */
  467. } MIXERCAPS16, *PMIXERCAPS16;
  468. typedef struct auxcaps16_tag {
  469. WORD wMid; /* manufacturer ID */
  470. WORD wPid; /* product ID */
  471. WORD vDriverVersion; /* version of the driver */
  472. char szPname[MAXPNAMELEN]; /* product name (NULL terminated string) */
  473. WORD wTechnology; /* type of device */
  474. DWORD dwSupport; /* functionality supported by driver */
  475. } AUXCAPS16, *PAUXCAPS16;
  476. typedef struct wavehdr_tag32 {
  477. UINT32 lpData; /* pointer to locked data buffer */
  478. DWORD dwBufferLength; /* length of data buffer */
  479. DWORD dwBytesRecorded; /* used for input only */
  480. UINT32 dwUser; /* for client's use */
  481. DWORD dwFlags; /* assorted flags (see defines) */
  482. DWORD dwLoops; /* loop control counter */
  483. UINT32 lpNext; /* reserved for driver */
  484. UINT32 reserved; /* reserved for driver */
  485. } WAVEHDR32, *PWAVEHDR32, NEAR *NPWAVEHDR32, FAR *LPWAVEHDR32;
  486. /* MIDI data block header */
  487. typedef struct midihdr_tag32 {
  488. UINT32 lpData; /* pointer to locked data block */
  489. DWORD dwBufferLength; /* length of data in data block */
  490. DWORD dwBytesRecorded; /* used for input only */
  491. UINT32 dwUser; /* for client's use */
  492. DWORD dwFlags; /* assorted flags (see defines) */
  493. UINT32 lpNext; /* reserved for driver */
  494. UINT32 reserved; /* reserved for driver */
  495. #if (WINVER >= 0x0400)
  496. DWORD dwOffset; /* Callback offset into buffer */
  497. UINT32 dwReserved[8]; /* Reserved for MMSYSTEM */
  498. #endif
  499. } MIDIHDR32, *PMIDIHDR32, NEAR *NPMIDIHDR32, FAR *LPMIDIHDR32;
  500. typedef struct tagMIXERLINEA32 {
  501. DWORD cbStruct; /* size of MIXERLINE structure */
  502. DWORD dwDestination; /* zero based destination index */
  503. DWORD dwSource; /* zero based source index (if source) */
  504. DWORD dwLineID; /* unique line id for mixer device */
  505. DWORD fdwLine; /* state/information about line */
  506. UINT32 dwUser; /* driver specific information */
  507. DWORD dwComponentType; /* component type line connects to */
  508. DWORD cChannels; /* number of channels line supports */
  509. DWORD cConnections; /* number of connections [possible] */
  510. DWORD cControls; /* number of controls at this line */
  511. CHAR szShortName[MIXER_SHORT_NAME_CHARS];
  512. CHAR szName[MIXER_LONG_NAME_CHARS];
  513. struct {
  514. DWORD dwType; /* MIXERLINE_TARGETTYPE_xxxx */
  515. DWORD dwDeviceID; /* target device ID of device type */
  516. WORD wMid; /* of target device */
  517. WORD wPid; /* " */
  518. MMVERSION vDriverVersion; /* " */
  519. CHAR szPname[MAXPNAMELEN]; /* " */
  520. } Target;
  521. } MIXERLINEA32, *PMIXERLINEA32, *LPMIXERLINEA32;
  522. typedef struct tagMIXERLINEW32 {
  523. DWORD cbStruct; /* size of MIXERLINE structure */
  524. DWORD dwDestination; /* zero based destination index */
  525. DWORD dwSource; /* zero based source index (if source) */
  526. DWORD dwLineID; /* unique line id for mixer device */
  527. DWORD fdwLine; /* state/information about line */
  528. UINT32 dwUser; /* driver specific information */
  529. DWORD dwComponentType; /* component type line connects to */
  530. DWORD cChannels; /* number of channels line supports */
  531. DWORD cConnections; /* number of connections [possible] */
  532. DWORD cControls; /* number of controls at this line */
  533. WCHAR szShortName[MIXER_SHORT_NAME_CHARS];
  534. WCHAR szName[MIXER_LONG_NAME_CHARS];
  535. struct {
  536. DWORD dwType; /* MIXERLINE_TARGETTYPE_xxxx */
  537. DWORD dwDeviceID; /* target device ID of device type */
  538. WORD wMid; /* of target device */
  539. WORD wPid; /* " */
  540. MMVERSION vDriverVersion; /* " */
  541. WCHAR szPname[MAXPNAMELEN]; /* " */
  542. } Target;
  543. } MIXERLINEW32, *PMIXERLINEW32, *LPMIXERLINEW32;
  544. #ifdef UNICODE
  545. typedef MIXERLINEW32 MIXERLINE32;
  546. typedef PMIXERLINEW32 PMIXERLINE32;
  547. typedef LPMIXERLINEW32 LPMIXERLINE32;
  548. #else
  549. typedef MIXERLINEA32 MIXERLINE32;
  550. typedef PMIXERLINEA32 PMIXERLINE32;
  551. typedef LPMIXERLINEA32 LPMIXERLINE32;
  552. #endif // UNICODE
  553. typedef struct tagMIXERLINECONTROLSA32 {
  554. DWORD cbStruct; /* size in bytes of MIXERLINECONTROLS */
  555. DWORD dwLineID; /* line id (from MIXERLINE.dwLineID) */
  556. union {
  557. DWORD dwControlID; /* MIXER_GETLINECONTROLSF_ONEBYID */
  558. DWORD dwControlType; /* MIXER_GETLINECONTROLSF_ONEBYTYPE */
  559. };
  560. DWORD cControls; /* count of controls pmxctrl points to */
  561. DWORD cbmxctrl; /* size in bytes of _one_ MIXERCONTROL */
  562. UINT32 pamxctrl; /* pointer to first MIXERCONTROL array */
  563. } MIXERLINECONTROLSA32, *PMIXERLINECONTROLSA32, *LPMIXERLINECONTROLSA32;
  564. typedef struct tagMIXERLINECONTROLSW32 {
  565. DWORD cbStruct; /* size in bytes of MIXERLINECONTROLS */
  566. DWORD dwLineID; /* line id (from MIXERLINE.dwLineID) */
  567. union {
  568. DWORD dwControlID; /* MIXER_GETLINECONTROLSF_ONEBYID */
  569. DWORD dwControlType; /* MIXER_GETLINECONTROLSF_ONEBYTYPE */
  570. };
  571. DWORD cControls; /* count of controls pmxctrl points to */
  572. DWORD cbmxctrl; /* size in bytes of _one_ MIXERCONTROL */
  573. UINT32 pamxctrl; /* pointer to first MIXERCONTROL array */
  574. } MIXERLINECONTROLSW32, *PMIXERLINECONTROLSW32, *LPMIXERLINECONTROLSW32;
  575. #ifdef UNICODE
  576. typedef MIXERLINECONTROLSW32 MIXERLINECONTROLS32;
  577. typedef PMIXERLINECONTROLSW32 PMIXERLINECONTROLS32;
  578. typedef LPMIXERLINECONTROLSW32 LPMIXERLINECONTROLS32;
  579. #else
  580. typedef MIXERLINECONTROLSA32 MIXERLINECONTROLS32;
  581. typedef PMIXERLINECONTROLSA32 PMIXERLINECONTROLS32;
  582. typedef LPMIXERLINECONTROLSA32 LPMIXERLINECONTROLS32;
  583. #endif // UNICODE
  584. typedef struct tMIXERCONTROLDETAILS32 {
  585. DWORD cbStruct; /* size in bytes of MIXERCONTROLDETAILS */
  586. DWORD dwControlID; /* control id to get/set details on */
  587. DWORD cChannels; /* number of channels in paDetails array */
  588. union {
  589. UINT32 hwndOwner; /* for MIXER_SETCONTROLDETAILSF_CUSTOM */
  590. DWORD cMultipleItems; /* if _MULTIPLE, the number of items per channel */
  591. };
  592. DWORD cbDetails; /* size of _one_ details_XX struct */
  593. UINT32 paDetails; /* pointer to array of details_XX structs */
  594. } MIXERCONTROLDETAILS32, *PMIXERCONTROLDETAILS32, FAR *LPMIXERCONTROLDETAILS32;
  595. #ifdef WIN32
  596. #include <poppack.h>
  597. #else
  598. #ifndef RC_INVOKED
  599. #pragma pack()
  600. #endif
  601. #endif
  602. #ifndef _WIN64
  603. // WARNING WARNING WARNING!!!!
  604. // If the below lines do not compile for 32 bit x86, you MUST sync the
  605. // above wavehdr_tag32 structure up with the wavehdr_tag structure in
  606. // mmsystem.w! It doesn't compile because someone changed mmsystem.w
  607. // without changing the above structure.
  608. // Make SURE when you sync it up that you use UINT32 for all elements
  609. // that are normally 64bits on win64.
  610. // You MUST also update all places that thunk the above structure!
  611. // Look for all occurances of any of the wavehdr_tag32 typedefs in the
  612. // wdmaud.sys directory.
  613. struct wave_header_structures_are_in_sync {
  614. char x[(sizeof (WAVEHDR32) == sizeof (WAVEHDR)) ? 1 : -1];
  615. };
  616. // WARNING WARNING WARNING!!!
  617. // If above lines do not compile, see comment above and FIX!
  618. // DO NOT COMMENT OUT THE LINES THAT DON'T COMPILE
  619. #endif
  620. #ifndef _WIN64
  621. // WARNING WARNING WARNING!!!!
  622. // If the below lines do not compile for 32 bit x86, you MUST sync the
  623. // above midihdr_tag32 structure up with the midihdr_tag structure in
  624. // mmsystem.w! It doesn't compile because someone changed mmsystem.w
  625. // without changing the above structure.
  626. // Make SURE when you sync it up that you use UINT32 for all elements
  627. // that are normally 64bits on win64.
  628. // You MUST also update all places that thunk the above structure!
  629. // Look for all occurances of any of the midihdr_tag32 typedefs in the
  630. // wdmaud.sys directory.
  631. struct midi_header_structures_are_in_sync {
  632. char x[(sizeof (MIDIHDR32) == sizeof (MIDIHDR)) ? 1 : -1];
  633. };
  634. // WARNING WARNING WARNING!!!
  635. // If above lines do not compile, see comment above and FIX!
  636. // DO NOT COMMENT OUT THE LINES THAT DON'T COMPILE
  637. #endif
  638. #ifndef _WIN64
  639. // WARNING WARNING WARNING!!!!
  640. // If the below lines do not compile for 32 bit x86, you MUST sync the
  641. // above two tagMIXERLINEX32 structures up with the tagMIXERLINEX structures in
  642. // mmsystem.w! It doesn't compile because someone changed mmsystem.w
  643. // without changing the above structure.
  644. // Make SURE when you sync it up that you use UINT32 for all elements
  645. // that are normally 64bits on win64.
  646. // You MUST also update all places that thunk the above structure!
  647. // Look for all occurances of any of the MIXERLINE32 typedefs in the
  648. // wdmaud.sys directory.
  649. struct mixer_line_structures_are_in_sync {
  650. char x[(sizeof (MIXERLINE32) == sizeof (MIXERLINE)) ? 1 : -1];
  651. };
  652. // WARNING WARNING WARNING!!!
  653. // If above lines do not compile, see comment above and FIX!
  654. // DO NOT COMMENT OUT THE LINES THAT DON'T COMPILE
  655. #endif
  656. #ifndef _WIN64
  657. // WARNING WARNING WARNING!!!!
  658. // If the below lines do not compile for 32 bit x86, you MUST sync the
  659. // above two tagMIXERLINECONTROLSX32 structures up with the tagMIXERLINECONTROLSX structures in
  660. // mmsystem.w! It doesn't compile because someone changed mmsystem.w
  661. // without changing the above structure.
  662. // Make SURE when you sync it up that you use UINT32 for all elements
  663. // that are normally 64bits on win64.
  664. // You MUST also update all places that thunk the above structure!
  665. // Look for all occurances of any of the MIXERLINECONTROLS32 typedefs in the
  666. // wdmaud.sys directory.
  667. struct mixer_line_control_structures_are_in_sync {
  668. char x[(sizeof (MIXERLINECONTROLS32) == sizeof (MIXERLINECONTROLS)) ? 1 : -1];
  669. };
  670. // WARNING WARNING WARNING!!!
  671. // If above lines do not compile, see comment above and FIX!
  672. // DO NOT COMMENT OUT THE LINES THAT DON'T COMPILE
  673. #endif
  674. #ifndef _WIN64
  675. // WARNING WARNING WARNING!!!!
  676. // If the below lines do not compile for 32 bit x86, you MUST sync the
  677. // above tMIXERCONTROLDETAILS32 structure up with the tMIXERCONTROLDETAILS32 structure in
  678. // mmsystem.w! It doesn't compile because someone changed mmsystem.w
  679. // without changing the above structure.
  680. // Make SURE when you sync it up that you use UINT32 for all elements
  681. // that are normally 64bits on win64.
  682. // You MUST also update all places that thunk the above structure!
  683. // Look for all occurances of any of the MIXERCONTROLDETAILS32 typedefs in the
  684. // wdmaud.sys directory.
  685. struct mixer_control_details_structures_are_in_sync {
  686. char x[(sizeof (MIXERCONTROLDETAILS32) == sizeof (MIXERCONTROLDETAILS)) ? 1 : -1];
  687. };
  688. // WARNING WARNING WARNING!!!
  689. // If above lines do not compile, see comment above and FIX!
  690. // DO NOT COMMENT OUT THE LINES THAT DON'T COMPILE
  691. #endif
  692. /***************************************************************************
  693. Local prototypes
  694. ***************************************************************************/
  695. //
  696. // Device.c
  697. //
  698. NTSTATUS
  699. DriverEntry(
  700. IN PDRIVER_OBJECT DriverObject,
  701. IN PUNICODE_STRING usRegistryPathName
  702. );
  703. NTSTATUS
  704. DispatchPnp(
  705. IN PDEVICE_OBJECT pDeviceObject,
  706. IN PIRP pIrp
  707. );
  708. NTSTATUS
  709. PnpAddDevice(
  710. IN PDRIVER_OBJECT DriverObject,
  711. IN PDEVICE_OBJECT PhysicalDeviceObject
  712. );
  713. VOID
  714. PnpDriverUnload(
  715. IN PDRIVER_OBJECT DriverObject
  716. );
  717. //
  718. // Ioctl.c
  719. //
  720. #ifdef PROFILE
  721. VOID WdmaInitProfile();
  722. VOID WdmaCleanupProfile();
  723. NTSTATUS
  724. AddMdlToList(
  725. PMDL pMdl,
  726. PWDMACONTEXT pWdmaContext
  727. );
  728. NTSTATUS
  729. RemoveMdlFromList(
  730. PMDL pMdl
  731. );
  732. #else
  733. #define WdmaInitProfile()
  734. #define AddMdlToList(pMdl,pWdmaContext)
  735. #define RemoveMdlFromList(pMdl)
  736. #endif
  737. extern LIST_ENTRY WdmaPendingIrpListHead;
  738. extern KSPIN_LOCK WdmaPendingIrpListSpinLock;
  739. VOID
  740. WdmaCsqInsertIrp(
  741. IN struct _IO_CSQ *pCsq,
  742. IN PIRP Irp
  743. );
  744. VOID
  745. WdmaCsqRemoveIrp(
  746. IN PIO_CSQ Csq,
  747. IN PIRP Irp
  748. );
  749. PIRP
  750. WdmaCsqPeekNextIrp(
  751. IN PIO_CSQ Csq,
  752. IN PIRP Irp,
  753. IN PVOID PeekContext
  754. );
  755. VOID
  756. WdmaCsqAcquireLock(
  757. IN PIO_CSQ Csq,
  758. OUT PKIRQL Irql
  759. );
  760. VOID
  761. WdmaCsqReleaseLock(
  762. IN PIO_CSQ Csq,
  763. IN KIRQL Irql
  764. );
  765. VOID
  766. WdmaCsqCompleteCanceledIrp(
  767. IN PIO_CSQ pCsq,
  768. IN PIRP Irp
  769. );
  770. NTSTATUS
  771. AddIrpToPendingList(
  772. PIRP pIrp,
  773. ULONG IrpDeviceType,
  774. PWDMACONTEXT pWdmaContext,
  775. PWDMAPENDINGIRP_CONTEXT *ppPendingIrpContext
  776. );
  777. NTSTATUS
  778. RemoveIrpFromPendingList(
  779. PWDMAPENDINGIRP_CONTEXT pPendingIrpContext
  780. );
  781. VOID
  782. wdmaudMapBuffer(
  783. PIRP pIrp,
  784. PVOID DataBuffer,
  785. DWORD DataBufferSize,
  786. PVOID *pMappedBuffer,
  787. PMDL *ppMdl,
  788. PWDMACONTEXT pContext,
  789. BOOL bWrite
  790. );
  791. VOID
  792. wdmaudUnmapBuffer(
  793. PMDL pMdl
  794. );
  795. NTSTATUS
  796. CaptureBufferToLocalPool(
  797. PVOID DataBuffer,
  798. DWORD DataBufferSize,
  799. PVOID *ppMappedBuffer
  800. #ifdef _WIN64
  801. ,DWORD ThunkBufferSize
  802. #endif
  803. );
  804. NTSTATUS
  805. CopyAndFreeCapturedBuffer(
  806. PVOID DataBuffer,
  807. DWORD DataBufferSize,
  808. PVOID *ppMappedBuffer
  809. );
  810. NTSTATUS
  811. SoundDispatchCreate(
  812. IN PDEVICE_OBJECT pDO,
  813. IN PIRP pIrp
  814. );
  815. NTSTATUS
  816. SoundDispatchClose(
  817. IN PDEVICE_OBJECT pDO,
  818. IN PIRP pIrp
  819. );
  820. NTSTATUS
  821. SoundDispatch(
  822. IN PDEVICE_OBJECT pDO,
  823. IN PIRP pIrp
  824. );
  825. NTSTATUS
  826. SoundDispatchCleanup(
  827. IN PDEVICE_OBJECT pDO,
  828. IN PIRP pIrp
  829. );
  830. //
  831. // wave.c
  832. //
  833. NTSTATUS
  834. OpenWavePin(
  835. PWDMACONTEXT pWdmaContext,
  836. ULONG DeviceNumber,
  837. LPWAVEFORMATEX lpFormat,
  838. HANDLE32 DeviceHandle,
  839. DWORD dwFlags,
  840. ULONG DataFlow // DataFlow is either in or out.
  841. );
  842. VOID
  843. CloseTheWavePin(
  844. PWAVEDEVICE pWaveDev,
  845. HANDLE32 DeviceHandle
  846. );
  847. VOID
  848. CloseWavePin(
  849. PWAVE_PIN_INSTANCE pWavePin
  850. );
  851. NTSTATUS
  852. wqWriteWaveCallBack(
  853. PDEVICE_OBJECT pDeviceObject,
  854. PIRP pIrp,
  855. IN PWAVEHDR pWriteData
  856. );
  857. NTSTATUS
  858. ssWriteWaveCallBack(
  859. PDEVICE_OBJECT pDeviceObject,
  860. PIRP pIrp,
  861. IN PSTREAM_HEADER_EX pStreamHeaderEx
  862. );
  863. NTSTATUS
  864. WriteWaveOutPin(
  865. PWAVEDEVICE pWaveOutDevice,
  866. HANDLE32 DeviceHandle,
  867. LPWAVEHDR pWriteData,
  868. PSTREAM_HEADER_EX pStreamHeader,
  869. PIRP pUserIrp,
  870. PWDMACONTEXT pContext,
  871. BOOL *pCompletedIrp
  872. );
  873. NTSTATUS
  874. IoWavePin(
  875. PWAVE_PIN_INSTANCE pWavePin,
  876. ULONG Operation,
  877. PWRITE_CONTEXT pWriteContext,
  878. ULONG Size,
  879. PVOID RefData,
  880. PVOID CallBack
  881. );
  882. NTSTATUS
  883. PosWavePin(
  884. PWAVEDEVICE pWaveDevice,
  885. HANDLE32 DeviceHandle,
  886. PWAVEPOSITION pWavePos
  887. );
  888. NTSTATUS
  889. BreakLoopWaveOutPin(
  890. PWAVEDEVICE pWaveOutDevice,
  891. HANDLE32 DeviceHandle
  892. );
  893. NTSTATUS
  894. VolumeWaveOutPin(
  895. ULONG DeviceNumber,
  896. HANDLE32 DeviceHandle,
  897. PDEVICEVOLUME pWaveVolume
  898. );
  899. NTSTATUS
  900. VolumeWaveInPin(
  901. ULONG DeviceNumber,
  902. PDEVICEVOLUME pWaveVolume
  903. );
  904. NTSTATUS
  905. VolumeWavePin(
  906. PWAVE_PIN_INSTANCE pWavePin,
  907. PDEVICEVOLUME pWaveVolume
  908. );
  909. NTSTATUS
  910. ResetWaveOutPin(
  911. PWAVEDEVICE pWaveOutDevice,
  912. HANDLE32 DeviceHandle
  913. );
  914. NTSTATUS
  915. ResetWavePin(
  916. PWAVE_PIN_INSTANCE pWavePin,
  917. KSRESET *pResetValue
  918. );
  919. NTSTATUS
  920. StateWavePin(
  921. PWAVEDEVICE pWaveInDevice,
  922. HANDLE32 DeviceHandle,
  923. KSSTATE State
  924. );
  925. NTSTATUS
  926. ReadWaveCallBack(
  927. PDEVICE_OBJECT pDeviceObject,
  928. PIRP pIrp,
  929. IN PSTREAM_HEADER_EX pStreamHeader
  930. );
  931. NTSTATUS
  932. ReadWaveInPin(
  933. PWAVEDEVICE pWaveInDevice,
  934. HANDLE32 DeviceHandle,
  935. PSTREAM_HEADER_EX pStreamHeader,
  936. PIRP pUserIrp,
  937. PWDMACONTEXT pContext,
  938. BOOL *pCompletedIrp
  939. );
  940. ULONG
  941. FindMixerForDevNode(
  942. IN PMIXERDEVICE paMixerDevice,
  943. IN PCWSTR DeviceInterface
  944. );
  945. NTSTATUS
  946. FindVolumeControl(
  947. IN PWDMACONTEXT pWdmaContext,
  948. IN PCWSTR DeviceInterface,
  949. IN DWORD DeviceType
  950. );
  951. NTSTATUS
  952. IsVolumeControl(
  953. IN PWDMACONTEXT pWdmaContext,
  954. IN PCWSTR DeviceInterface,
  955. IN DWORD dwComponentType,
  956. IN PDWORD pdwControlID,
  957. IN PDWORD pcChannels
  958. );
  959. NTSTATUS
  960. SetVolume(
  961. IN PWDMACONTEXT pWdmaContext,
  962. IN DWORD DeviceNumber,
  963. IN DWORD DeviceType,
  964. IN DWORD LeftChannel,
  965. IN DWORD RightChannel
  966. );
  967. NTSTATUS
  968. GetVolume(
  969. IN PWDMACONTEXT pWdmaContext,
  970. IN DWORD DeviceNumber,
  971. IN DWORD DeviceType,
  972. OUT PDWORD LeftChannel,
  973. OUT PDWORD RightChannel
  974. );
  975. VOID
  976. CleanupWavePins(
  977. IN PWAVEDEVICE pWaveDevice
  978. );
  979. VOID
  980. CleanupWaveDevices(
  981. PWDMACONTEXT pWdmaContext
  982. );
  983. NTSTATUS
  984. wdmaudPrepareIrp(
  985. PIRP pIrp,
  986. ULONG IrpDeviceType,
  987. PWDMACONTEXT pWdmaContext,
  988. PWDMAPENDINGIRP_CONTEXT *ppPendingIrpContext
  989. );
  990. NTSTATUS
  991. wdmaudUnprepareIrp(
  992. PIRP pIrp,
  993. NTSTATUS IrpStatus,
  994. ULONG_PTR Information,
  995. PWDMAPENDINGIRP_CONTEXT pPendingIrpContext
  996. );
  997. //
  998. // midi.c
  999. //
  1000. NTSTATUS
  1001. OpenMidiPin(
  1002. PWDMACONTEXT pWdmaContext,
  1003. ULONG DeviceNumber,
  1004. ULONG DataFlow //DataFlow is either in or out.
  1005. );
  1006. VOID
  1007. CloseMidiDevicePin(
  1008. PMIDIDEVICE pMidiDevice
  1009. );
  1010. VOID
  1011. CloseMidiPin(
  1012. PMIDI_PIN_INSTANCE pMidiPin
  1013. );
  1014. NTSTATUS
  1015. WriteMidiEventCallBack(
  1016. PDEVICE_OBJECT pDeviceObject,
  1017. PIRP pIrp,
  1018. IN PSTREAM_HEADER_EX pStreamHeader
  1019. );
  1020. NTSTATUS
  1021. WriteMidiEventPin(
  1022. PMIDIDEVICE pMidiOutDevice,
  1023. ULONG ulEvent
  1024. );
  1025. NTSTATUS
  1026. WriteMidiCallBack(
  1027. PDEVICE_OBJECT pDeviceObject,
  1028. PIRP pIrp,
  1029. IN PSTREAM_HEADER_EX pStreamHeader
  1030. );
  1031. NTSTATUS
  1032. WriteMidiOutPin(
  1033. LPMIDIHDR pMidiHdr,
  1034. PSTREAM_HEADER_EX pStreamHeader,
  1035. BOOL *pCompletedIrp
  1036. );
  1037. ULONGLONG
  1038. GetCurrentMidiTime(
  1039. VOID
  1040. );
  1041. NTSTATUS
  1042. ResetMidiInPin(
  1043. PMIDI_PIN_INSTANCE pMidiPin
  1044. );
  1045. NTSTATUS
  1046. StateMidiOutPin(
  1047. PMIDI_PIN_INSTANCE pMidiPin,
  1048. KSSTATE State
  1049. );
  1050. NTSTATUS
  1051. StateMidiInPin(
  1052. PMIDI_PIN_INSTANCE pMidiPin,
  1053. KSSTATE State
  1054. );
  1055. NTSTATUS
  1056. ReadMidiCallBack(
  1057. PDEVICE_OBJECT pDeviceObject,
  1058. PIRP pIrp,
  1059. IN PSTREAM_HEADER_EX pStreamHeader
  1060. );
  1061. VOID
  1062. ReadMidiEventWorkItem(
  1063. PSTREAM_HEADER_EX pStreamHeader,
  1064. PVOID NotUsed
  1065. );
  1066. NTSTATUS
  1067. ReadMidiPin(
  1068. PMIDI_PIN_INSTANCE pMidiPin
  1069. );
  1070. NTSTATUS
  1071. AddBufferToMidiInQueue(
  1072. PMIDI_PIN_INSTANCE pMidiPin,
  1073. PMIDIINHDR pNewMidiInHdr
  1074. );
  1075. VOID
  1076. CleanupMidiDevices(
  1077. PWDMACONTEXT pWdmaContext
  1078. );
  1079. // from NTKERN
  1080. NTSYSAPI NTSTATUS NTAPI NtClose
  1081. (
  1082. IN HANDLE Handle
  1083. );
  1084. //
  1085. // sysaudio.c
  1086. //
  1087. /*
  1088. NTSTATUS
  1089. AllocMem(
  1090. POOL_TYPE PoolType,
  1091. PVOID *pp,
  1092. ULONG size,
  1093. ULONG ultag
  1094. );
  1095. VOID
  1096. FreeMem(
  1097. PVOID *pp
  1098. );
  1099. */
  1100. NTSTATUS
  1101. OpenSysAudioPin(
  1102. ULONG Device,
  1103. ULONG PinId,
  1104. KSPIN_DATAFLOW DataFlowRequested,
  1105. PKSPIN_CONNECT pPinConnect,
  1106. PFILE_OBJECT *ppFileObjectPin,
  1107. PDEVICE_OBJECT *ppDeviceObjectPin,
  1108. PCONTROLS_LIST pControlList
  1109. );
  1110. VOID
  1111. CloseSysAudio(
  1112. PWDMACONTEXT pWdmaContext,
  1113. PFILE_OBJECT pFileObjectPin
  1114. );
  1115. NTSTATUS
  1116. OpenSysAudio(
  1117. PHANDLE pHandle,
  1118. PFILE_OBJECT *ppFileObject
  1119. );
  1120. NTSTATUS
  1121. OpenDevice(
  1122. IN PWSTR pwstrDevice,
  1123. OUT PHANDLE pHandle
  1124. );
  1125. NTSTATUS
  1126. GetPinProperty(
  1127. PFILE_OBJECT pFileObject,
  1128. ULONG PropertyId,
  1129. ULONG PinId,
  1130. ULONG cbProperty,
  1131. PVOID pProperty
  1132. );
  1133. NTSTATUS
  1134. GetPinPropertyEx(
  1135. PFILE_OBJECT pFileObject,
  1136. ULONG PropertyId,
  1137. ULONG PinId,
  1138. PVOID *ppProperty
  1139. );
  1140. VOID
  1141. GetControlNodes(
  1142. PFILE_OBJECT pDeviceFileObject,
  1143. PFILE_OBJECT pPinFileObject,
  1144. ULONG PinId,
  1145. PCONTROLS_LIST pControlList
  1146. );
  1147. ULONG
  1148. ControlNodeFromGuid(
  1149. PFILE_OBJECT pDeviceFileObject,
  1150. PFILE_OBJECT pPinFileObject,
  1151. ULONG PinId,
  1152. GUID* NodeType
  1153. );
  1154. PVOID
  1155. GetTopologyProperty(
  1156. PFILE_OBJECT pDeviceFileObject,
  1157. ULONG PropertyId
  1158. );
  1159. PKSTOPOLOGY_CONNECTION
  1160. FindConnection(
  1161. PKSTOPOLOGY_CONNECTION pConnections,
  1162. ULONG NumConnections,
  1163. ULONG FromNode,
  1164. ULONG FromPin,
  1165. ULONG ToNode,
  1166. ULONG ToPin
  1167. );
  1168. ULONG
  1169. GetFirstConnectionIndex(
  1170. PFILE_OBJECT pPinFileObject
  1171. );
  1172. VOID
  1173. UpdatePreferredDevice(
  1174. PWDMACONTEXT pWdmaContext
  1175. );
  1176. NTSTATUS
  1177. SetPreferredDevice(
  1178. PWDMACONTEXT pContext,
  1179. LPDEVICEINFO pDeviceInfo
  1180. );
  1181. NTSTATUS
  1182. GetSysAudioProperty(
  1183. PFILE_OBJECT pFileObject,
  1184. ULONG PropertyId,
  1185. ULONG DeviceIndex,
  1186. ULONG cbProperty,
  1187. PVOID pProperty
  1188. );
  1189. NTSTATUS
  1190. SetSysAudioProperty(
  1191. PFILE_OBJECT pFileObject,
  1192. ULONG PropertyId,
  1193. ULONG cbProperty,
  1194. PVOID pProperty
  1195. );
  1196. WORD
  1197. GetMidiTechnology(
  1198. PKSDATARANGE_MUSIC MusicDataRange
  1199. );
  1200. DWORD
  1201. GetFormats(
  1202. PKSDATARANGE_AUDIO AudioDataRange
  1203. );
  1204. NTSTATUS
  1205. wdmaudGetDevCaps(
  1206. PWDMACONTEXT pWdmaContext,
  1207. DWORD DeviceType,
  1208. DWORD DeviceNumber,
  1209. LPBYTE lpCaps,
  1210. DWORD dwSize
  1211. );
  1212. NTSTATUS
  1213. wdmaudGetNumDevs(
  1214. PWDMACONTEXT pWdmaContext,
  1215. DWORD DeviceType,
  1216. LPCTSTR DeviceInterface,
  1217. LPDWORD lpNumberOfDevices
  1218. );
  1219. BOOL
  1220. IsEqualInterface(
  1221. PKSPIN_INTERFACE pInterface1,
  1222. PKSPIN_INTERFACE pInterface2
  1223. );
  1224. DWORD
  1225. wdmaudTranslateDeviceNumber(
  1226. PWDMACONTEXT pWdmaContext,
  1227. DWORD DeviceType,
  1228. PCWSTR DeviceInterface,
  1229. DWORD DeviceNumber
  1230. );
  1231. NTSTATUS
  1232. AddDevice(
  1233. PWDMACONTEXT pWdmaContext,
  1234. ULONG Device,
  1235. DWORD DeviceType,
  1236. PCWSTR DeviceInterface,
  1237. ULONG PinId,
  1238. PWSTR pwstrName,
  1239. BOOL fUsePreferred,
  1240. PDATARANGES pDataRange,
  1241. PKSCOMPONENTID ComponentId
  1242. );
  1243. NTSTATUS
  1244. PinProperty(
  1245. PFILE_OBJECT pFileObject,
  1246. const GUID *pPropertySet,
  1247. ULONG ulPropertyId,
  1248. ULONG ulFlags,
  1249. ULONG cbProperty,
  1250. PVOID pProperty
  1251. );
  1252. NTSTATUS
  1253. PinMethod(
  1254. PFILE_OBJECT pFileObject,
  1255. const GUID *pMethodSet,
  1256. ULONG ulMethodId,
  1257. ULONG ulFlags,
  1258. ULONG cbMethod,
  1259. PVOID pMethod
  1260. );
  1261. VOID
  1262. CopyAnsiStringtoUnicodeString(
  1263. LPWSTR lpwstr,
  1264. LPCSTR lpstr,
  1265. int len
  1266. );
  1267. VOID
  1268. CopyUnicodeStringtoAnsiString(
  1269. LPSTR lpstr,
  1270. LPCWSTR lpwstr,
  1271. int len
  1272. );
  1273. NTSTATUS
  1274. AttachVirtualSource(
  1275. PFILE_OBJECT pFileObject,
  1276. ULONG ulPinId
  1277. );
  1278. NTSTATUS
  1279. SysAudioPnPNotification(
  1280. IN PVOID NotificationStructure,
  1281. IN PVOID Context
  1282. );
  1283. NTSTATUS
  1284. InitializeSysaudio(
  1285. PVOID Reference1,
  1286. PVOID Reference2
  1287. );
  1288. VOID
  1289. UninitializeSysaudio(
  1290. );
  1291. NTSTATUS
  1292. AddDevNode(
  1293. PWDMACONTEXT pWdmaContext,
  1294. PCWSTR DeviceInterface,
  1295. UINT DeviceType
  1296. );
  1297. VOID
  1298. RemoveDevNode(
  1299. PWDMACONTEXT pWdmaContext,
  1300. PCWSTR DeviceInterface,
  1301. UINT DeviceType
  1302. );
  1303. NTSTATUS
  1304. ProcessDevNodeListItem(
  1305. PWDMACONTEXT pWdmaContext,
  1306. PDEVNODE_LIST_ITEM pDevNodeListItem,
  1307. ULONG DeviceType
  1308. );
  1309. VOID
  1310. SysaudioAddRemove(
  1311. PWDMACONTEXT pWdmaContext
  1312. );
  1313. NTSTATUS
  1314. QueueWorkList(
  1315. PWDMACONTEXT pWdmaContext,
  1316. VOID (*Function)(
  1317. PVOID Reference1,
  1318. PVOID Reference2
  1319. ),
  1320. PVOID Reference1,
  1321. PVOID Reference2
  1322. );
  1323. VOID
  1324. WorkListWorker(
  1325. PVOID pReference
  1326. );
  1327. NTSTATUS
  1328. AddFsContextToList(
  1329. PWDMACONTEXT pWdmaContext
  1330. );
  1331. NTSTATUS
  1332. RemoveFsContextFromList(
  1333. PWDMACONTEXT pWdmaContext
  1334. );
  1335. typedef NTSTATUS (FNCONTEXTCALLBACK)(PWDMACONTEXT pContext,PVOID pvoidRefData,PVOID pvoidRefData2);
  1336. NTSTATUS
  1337. HasMixerBeenInitialized(
  1338. PWDMACONTEXT pContext,
  1339. PVOID pvoidRefData,
  1340. PVOID pvoidRefData2
  1341. );
  1342. NTSTATUS
  1343. EnumFsContext(
  1344. FNCONTEXTCALLBACK fnCallback,
  1345. PVOID pvoidRefData,
  1346. PVOID pvoidRefData2
  1347. );
  1348. VOID
  1349. WdmaContextCleanup(
  1350. PWDMACONTEXT pWdmaContext
  1351. );
  1352. VOID
  1353. WdmaGrabMutex(
  1354. PWDMACONTEXT pWdmaContext
  1355. );
  1356. VOID
  1357. WdmaReleaseMutex(
  1358. PWDMACONTEXT pWdmaContext
  1359. );
  1360. int
  1361. MyWcsicmp(
  1362. const wchar_t *,
  1363. const wchar_t *
  1364. );
  1365. void
  1366. LockedWaveIoCount(
  1367. PWAVE_PIN_INSTANCE pCurWavePin,
  1368. BOOL bIncrease
  1369. );
  1370. void
  1371. LockedMidiIoCount(
  1372. PMIDI_PIN_INSTANCE pCurMidiPin,
  1373. BOOL bIncrease
  1374. );
  1375. void
  1376. MidiCompleteIo(
  1377. PMIDI_PIN_INSTANCE pMidiPin,
  1378. BOOL Yield
  1379. );
  1380. NTSTATUS
  1381. StatePin(
  1382. IN PFILE_OBJECT pFileObject,
  1383. IN KSSTATE State,
  1384. OUT PKSSTATE pResultingState
  1385. );
  1386. //==========================================================================
  1387. //
  1388. // In order to better track memory allocations, if you include the following
  1389. // all memory allocations will be tagged.
  1390. //
  1391. //==========================================================================
  1392. //
  1393. // For memory allocation routines we need some memory tags. Well, here they
  1394. // are.
  1395. //
  1396. #define TAG_AudD_DEVICEINFO ((ULONG)'DduA')
  1397. #define TAG_AudC_CONTROL ((ULONG)'CduA')
  1398. #define TAG_AudE_EVENT ((ULONG)'EduA')
  1399. #define TAG_AuDF_HARDWAREEVENT ((ULONG)'FDuA')
  1400. #define TAG_AudL_LINE ((ULONG)'LduA')
  1401. #define TAG_AuDA_CHANNEL ((ULONG)'ADuA')
  1402. #define TAG_AuDB_CHANNEL ((ULONG)'BDuA')
  1403. #define TAG_AuDC_CHANNEL ((ULONG)'CDuA')
  1404. #define TAG_AuDD_CHANNEL ((ULONG)'DDuA')
  1405. #define TAG_AuDE_CHANNEL ((ULONG)'EDuA')
  1406. #define TAG_AudS_SUPERMIX ((ULONG)'SduA')
  1407. #define TAG_Audl_MIXLEVEL ((ULONG)'lduA')
  1408. #define TAG_AudN_NODE ((ULONG)'NduA')
  1409. #define TAG_Audn_PEERNODE ((ULONG)'nduA')
  1410. //#define TAG_AudP_PROPERTY ((ULONG)'PduA')
  1411. #define TAG_AudQ_PROPERTY ((ULONG)'QduA')
  1412. #define TAG_Audq_PROPERTY ((ULONG)'qduA')
  1413. #define TAG_AudV_PROPERTY ((ULONG)'VduA')
  1414. #define TAG_Audv_PROPERTY ((ULONG)'vduA')
  1415. #define TAG_AudU_PROPERTY ((ULONG)'UduA')
  1416. #define TAG_Audu_PROPERTY ((ULONG)'uduA')
  1417. #define TAG_Auda_PROPERTY ((ULONG)'aduA')
  1418. #define TAG_AudA_PROPERTY ((ULONG)'AduA')
  1419. #define TAG_Audp_NAME ((ULONG)'pduA')
  1420. #define TAG_AudG_GETMUXLINE ((ULONG)'GduA')
  1421. #define TAG_AudI_INSTANCE ((ULONG)'IduA')
  1422. #define TAG_Audd_DETAILS ((ULONG)'dduA')
  1423. #define TAG_Audi_PIN ((ULONG)'iduA')
  1424. #define TAG_Audt_CONNECT ((ULONG)'tduA')
  1425. #define TAG_Audh_STREAMHEADER ((ULONG)'hduA')
  1426. #define TAG_Audm_MUSIC ((ULONG)'mduA')
  1427. #define TAG_Audx_CONTEXT ((ULONG)'xduA')
  1428. #define TAG_AudT_TIMER ((ULONG)'TduA')
  1429. #define TAG_AudF_FORMAT ((ULONG)'FduA')
  1430. #define TAG_AudM_MDL ((ULONG)'MduA')
  1431. #define TAG_AudR_IRP ((ULONG)'RduA')
  1432. #define TAG_AudB_BUFFER ((ULONG)'BduA')
  1433. #define TAG_Aude_MIDIHEADER ((ULONG)'eduA')
  1434. #define TAG_AuDN_NOTIFICATION ((ULONG)'NDuA')
  1435. #define TAG_AuDL_LINK ((ULONG)'LDuA')
  1436. /***************************************************************************
  1437. DEBUGGING SUPPORT
  1438. ***************************************************************************/
  1439. #ifdef DEBUG
  1440. //-----------------------------------------------------------------------------
  1441. //
  1442. // Debug support for wdmaud.sys on NT is found here.
  1443. //
  1444. // To start with, There will be four different levels or debugging information.
  1445. // With each level, there will be functional area. Thus, you can turn on
  1446. // debug output for just driver calls, api tracing or whatnot.
  1447. //
  1448. //-----------------------------------------------------------------------------
  1449. //
  1450. // 8 bits reserved for debug leves.
  1451. //
  1452. #define DL_ERROR 0x00000000
  1453. #define DL_WARNING 0x00000001
  1454. #define DL_TRACE 0x00000002
  1455. #define DL_MAX 0x00000004
  1456. #define DL_PATHTRAP 0x00000080
  1457. #define DL_MASK 0x000000FF
  1458. //
  1459. // 20 bits reserved for functional areas. If we find that this bit is set
  1460. // in the DebugLevel variable, we will display every message of this type.
  1461. //
  1462. #define FA_HARDWAREEVENT 0x80000000
  1463. #define FA_MIXER 0x40000000
  1464. #define FA_IOCTL 0x20000000
  1465. #define FA_SYSAUDIO 0x10000000
  1466. #define FA_PERSIST 0x08000000
  1467. #define FA_PROPERTY 0x04000000
  1468. #define FA_USER 0x02000000
  1469. #define FA_WAVE 0x01000000
  1470. #define FA_MIDI 0x00800000
  1471. #define FA_INSTANCE 0x00400000
  1472. #define FA_NOTE 0x00200000
  1473. #define FA_KS 0x00100000
  1474. #define FA_MASK 0xFFFFF000
  1475. #define FA_ASSERT 0x00002000
  1476. #define FA_ALL 0x00001000
  1477. //
  1478. // 4 bits reserved for return codes. The 3 lower bits map directly to status
  1479. // codes shifted right 22 bits. One bit represents that fact that we have a
  1480. // return statement.
  1481. //
  1482. #define RT_ERROR 0x00000300 // 0xCxxxxxxx >> 22 == 0x0000003xx
  1483. #define RT_WARNING 0x00000200 // 0x8xxxxxxx >> 22 == 0x0000002xx
  1484. #define RT_INFO 0x00000100 // 0x4xxxxxxx >> 22 == 0x0000001xx
  1485. #define RT_MASK 0x00000300
  1486. #define RT_RETURN 0x00000800
  1487. //-----------------------------------------------------------------------------
  1488. // Macro might look like this.
  1489. //
  1490. // Take the string that we want to output and add "WDMAUD.SYS" and ("Error" or
  1491. // "warning" or whatever) to the front of the string. Next, follow that with
  1492. // the function name and line number in the file that the function is found in.
  1493. // Then display the error message and then close the message with a breakpoint
  1494. // statement.
  1495. //
  1496. // The logic goes like this. If the user wants to see these messages ok. Else
  1497. // bail. If so, wdmaudDbgPreCheckLevel will return TRUE and it will have
  1498. // formated the start of the string. It will look like:
  1499. //
  1500. // WDMAUD.SYS Erorr OurFooFunction(456)
  1501. //
  1502. // Next, the message string with the variable arguements will be displayed, like:
  1503. //
  1504. // WDMAUD.SYS Warning OurFooFunction(456) Invalid Data Queue returning C0000109
  1505. //
  1506. // Then, wdmaudDbgPostCheckLevel will be called to post format the message and
  1507. // see if the user wanted to trap on this output.
  1508. //
  1509. // WDMAUD.SYS Warning OutFooFunction(456) Invalid Data Queue returning C0000109 &DL=ff680123
  1510. //
  1511. // The internal version will append "See \\debugtips\wdmaud.sys\wdmaud.htm" to
  1512. // the end
  1513. //
  1514. // if( wdmaudDbgPreCheckLevel(TypeOfMessageInCode) )
  1515. // {
  1516. // DbgPrintF( _x_ ); // output the actual string here.
  1517. // if( wdmaudDbgPostCheckLevel(Variable) )
  1518. // DbgBreakPoint();
  1519. // }
  1520. //
  1521. // DPF( DL_WARNING|DL_ALL, ("Invalid queue %X",Queue) );
  1522. //
  1523. //-----------------------------------------------------------------------------
  1524. extern VOID
  1525. wdmaudDbgBreakPoint(
  1526. );
  1527. extern UINT
  1528. wdmaudDbgPreCheckLevel(
  1529. UINT uiMsgLevel,
  1530. char *pFunction,
  1531. int iLine
  1532. );
  1533. extern UINT
  1534. wdmaudDbgPostCheckLevel(
  1535. UINT uiMsgLevel
  1536. );
  1537. extern char *
  1538. wdmaudReturnString(
  1539. ULONG ulMsg
  1540. );
  1541. extern char szReturningErrorStr[];
  1542. extern UINT uiDebugLevel;
  1543. #define DPF(_x_,_y_) {if( wdmaudDbgPreCheckLevel(_x_,__FUNCTION__,__LINE__) ) { DbgPrint _y_; \
  1544. wdmaudDbgPostCheckLevel( _x_ ); }}
  1545. //
  1546. // Writing macros are easy, it's figuring out when they are useful that is more
  1547. // difficult! In this code, The RETURN macro replaces the return keyword in the
  1548. // debug builds when returning an NTSTATUS code. Then, when tracking debug output
  1549. // the return debug line will be displayed based on the type of error the status
  1550. // value represents.
  1551. //
  1552. // Notice that the error code is shifted 22 bits and ORed with RT_RETURN. Thus
  1553. // a value of "0xCxxxxxxx" will be seen as an error message, "0x8xxxxxxx" will
  1554. // be seen as a warning and "0x4xxxxxxx" will be seen as a message.
  1555. //
  1556. // Key, if uiDebugLevel is DL_ERROR or DL_WARNING all NTSTATUS Error message will be displayed
  1557. // if uiDebugLevel is DL_TRACE, all warning return codes and error return codes
  1558. // will be displayed and if uiDebugLevel is set to DL_MAX all return messages will
  1559. // displayed including success codes.
  1560. //
  1561. // RETURN(Status);
  1562. //
  1563. // WARNING: Do not rap functions in this macro! Notice that _status_ is used more
  1564. // then once! Thus, the function will get called more then once! Don't do it.
  1565. #define RETURN(_status_) {DPF((RT_RETURN|DL_WARNING|((unsigned long)_status_>>22)),("%X:%s",_status_,wdmaudReturnString(_status_))); return (_status_);}
  1566. //
  1567. // _list_ is parameters for wdmaudExclusionList. Like (_status_,STATUS_INVALID_PARAMETER,STATUS_NOT_FOUND,...).
  1568. // wdmaudExclusionList takes a variable number of parameters. If the status value is
  1569. // found in the list of error codes supplied, the function returns TRUE.
  1570. //
  1571. extern int __cdecl
  1572. wdmaudExclusionList(
  1573. int count,
  1574. unsigned long status,
  1575. ...
  1576. );
  1577. //
  1578. // Thus, this macro reads: We have a return code that we're going to return. Is
  1579. // it a special return code that we don't need to display? NO - show the debug
  1580. // spew. YES - just return it.
  1581. //
  1582. // _status_ = The status in question
  1583. // _y_ = Parameters to wdmaudExclusionList "( the status in question, exclution values, .... )"
  1584. //
  1585. #define DPFRETURN( _status_,_y_ ) {if( !wdmaudExclusionList _y_ ) { \
  1586. if( wdmaudDbgPreCheckLevel((RT_RETURN|DL_WARNING|(_status_>>22)),__FUNCTION__,__LINE__) ) { \
  1587. DbgPrint ("%X:%s",_status_,wdmaudReturnString(_status_) ); \
  1588. wdmaudDbgPostCheckLevel( (RT_RETURN|DL_WARNING|(_status_>>22)) ); \
  1589. } } return (_status_);}
  1590. //
  1591. // It's bad form to put more then one expression in an assert macro. Why? because
  1592. // you will not know exactly what expression failed the assert!
  1593. //
  1594. #define DPFASSERT(_exp_) {if( !(_exp_) ) {DPF(DL_ERROR|FA_ASSERT,("'%s'",#_exp_) );}}
  1595. #ifdef WANT_TRAPS
  1596. //
  1597. // Branch trap. This macro is used when testing code to make sure that you've
  1598. // hit all branches in the new code. Every time you hit one validate that the
  1599. // code does the correct thing and then remove it from the source. We should
  1600. // ship with none of these lines left in the code!!!!!!
  1601. //
  1602. #define DPFBTRAP() DPF(DL_PATHTRAP,("Please report") )
  1603. #else
  1604. #define DPFBTRAP()
  1605. #endif
  1606. //
  1607. // There are a number of new routines in the checked build that validate structure
  1608. // types for us now. These should be used inside the DPFASSERT() macro. Thus,
  1609. // Under retail they don't have to be defined.
  1610. //
  1611. BOOL
  1612. IsValidDeviceInfo(
  1613. IN LPDEVICEINFO pDeviceInfo
  1614. );
  1615. BOOL
  1616. IsValidMixerObject(
  1617. IN PMIXEROBJECT pmxobj
  1618. );
  1619. BOOL
  1620. IsValidMixerDevice(
  1621. IN PMIXERDEVICE pmxd
  1622. );
  1623. BOOL
  1624. IsValidControl(
  1625. IN PMXLCONTROL pControl
  1626. );
  1627. BOOL
  1628. IsValidWdmaContext(
  1629. IN PWDMACONTEXT pWdmaContext
  1630. );
  1631. BOOL
  1632. IsValidLine(
  1633. IN PMXLLINE pLine
  1634. );
  1635. VOID
  1636. GetuiDebugLevel(
  1637. );
  1638. #else
  1639. #define DPF(_x_,_y_)
  1640. #define RETURN( _status_ ) return (_status_)
  1641. #define DPFRETURN( _status_,_y_ ) return (_status_)
  1642. #define DPFASSERT(_exp_)
  1643. #define DPFBTRAP()
  1644. #endif
  1645. VOID
  1646. kmxlFindAddressInNoteList(
  1647. IN PMXLCONTROL pControl
  1648. );
  1649. VOID
  1650. kmxlCleanupNoteList(
  1651. );
  1652. NTSTATUS
  1653. kmxlDisableControlChangeNotifications(
  1654. IN PMXLCONTROL pControl
  1655. );
  1656. VOID
  1657. kmxlRemoveContextFromNoteList(
  1658. PWDMACONTEXT pContext
  1659. );
  1660. VOID
  1661. kmxlPersistHWControlWorker(
  1662. PVOID pReference
  1663. );
  1664. #endif // _WDMSYS_H_INCLUDED_